summaryrefslogtreecommitdiff
path: root/test/mkmf/test_constant.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/mkmf/test_constant.rb')
0 files changed, 0 insertions, 0 deletions
raph'>
-rw-r--r--.editorconfig24
-rw-r--r--.gdbinit1307
-rw-r--r--.gitattributes6
-rw-r--r--.gitignore197
-rw-r--r--.indent.pro21
-rw-r--r--.travis.yml109
-rw-r--r--BSDL22
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--COPYING366
-rw-r--r--COPYING.ja51
-rw-r--r--ChangeLog2632
-rw-r--r--GPL339
-rw-r--r--KNOWNBUGS.rb7
-rw-r--r--LEGAL850
-rw-r--r--MANIFEST237
-rw-r--r--Makefile.in708
-rw-r--r--NEWS577
-rw-r--r--README132
-rw-r--r--README.EXT1061
-rw-r--r--README.EXT.ja1
-rw-r--r--README.EXT.jp1147
-rw-r--r--README.ja.md171
-rw-r--r--README.jp171
-rw-r--r--README.md175
-rw-r--r--ToDo4
-rw-r--r--acinclude.m446
-rw-r--r--aclocal.m415
-rw-r--r--addr2line.c1234
-rw-r--r--addr2line.h21
-rw-r--r--appveyor.yml55
-rw-r--r--array.c6609
-rwxr-xr-xbasictest/runner.rb33
-rwxr-xr-xbasictest/test.rb2367
-rw-r--r--benchmark/bm_app_answer.rb15
-rw-r--r--benchmark/bm_app_aobench.rb291
-rw-r--r--benchmark/bm_app_erb.rb26
-rw-r--r--benchmark/bm_app_factorial.rb11
-rw-r--r--benchmark/bm_app_fib.rb10
-rw-r--r--benchmark/bm_app_lc_fizzbuzz.rb52
-rw-r--r--benchmark/bm_app_mandelbrot.rb23
-rw-r--r--benchmark/bm_app_pentomino.rb259
-rw-r--r--benchmark/bm_app_raise.rb8
-rw-r--r--benchmark/bm_app_strconcat.rb5
-rw-r--r--benchmark/bm_app_tak.rb13
-rw-r--r--benchmark/bm_app_tarai.rb10
-rw-r--r--benchmark/bm_app_uri.rb8
-rw-r--r--benchmark/bm_array_sample_100k_10.rb2
-rw-r--r--benchmark/bm_array_sample_100k_11.rb2
-rw-r--r--benchmark/bm_array_sample_100k__100.rb2
-rw-r--r--benchmark/bm_array_sample_100k__1k.rb2
-rw-r--r--benchmark/bm_array_sample_100k__6k.rb2
-rw-r--r--benchmark/bm_array_sample_100k___10k.rb2
-rw-r--r--benchmark/bm_array_sample_100k___50k.rb2
-rw-r--r--benchmark/bm_array_shift.rb14
-rw-r--r--benchmark/bm_array_small_and.rb17
-rw-r--r--benchmark/bm_array_small_diff.rb17
-rw-r--r--benchmark/bm_array_small_or.rb17
-rw-r--r--benchmark/bm_array_sort_block.rb2
-rw-r--r--benchmark/bm_array_sort_float.rb2
-rw-r--r--benchmark/bm_bighash.rb1
-rw-r--r--benchmark/bm_dir_empty_p.rb5
-rw-r--r--benchmark/bm_erb_render.rb26
-rw-r--r--benchmark/bm_file_chmod.rb9
-rw-r--r--benchmark/bm_file_rename.rb11
-rw-r--r--benchmark/bm_hash_aref_dsym.rb4
-rw-r--r--benchmark/bm_hash_aref_dsym_long.rb21
-rw-r--r--benchmark/bm_hash_aref_fix.rb4
-rw-r--r--benchmark/bm_hash_aref_flo.rb4
-rw-r--r--benchmark/bm_hash_aref_miss.rb5
-rw-r--r--benchmark/bm_hash_aref_str.rb4
-rw-r--r--benchmark/bm_hash_aref_sym.rb9
-rw-r--r--benchmark/bm_hash_aref_sym_long.rb13
-rw-r--r--benchmark/bm_hash_flatten.rb9
-rw-r--r--benchmark/bm_hash_ident_flo.rb4
-rw-r--r--benchmark/bm_hash_ident_num.rb4
-rw-r--r--benchmark/bm_hash_ident_obj.rb4
-rw-r--r--benchmark/bm_hash_ident_str.rb4
-rw-r--r--benchmark/bm_hash_ident_sym.rb4
-rw-r--r--benchmark/bm_hash_keys.rb9
-rw-r--r--benchmark/bm_hash_long.rb4
-rw-r--r--benchmark/bm_hash_shift.rb10
-rw-r--r--benchmark/bm_hash_shift_u16.rb10
-rw-r--r--benchmark/bm_hash_shift_u24.rb10
-rw-r--r--benchmark/bm_hash_shift_u32.rb10
-rw-r--r--benchmark/bm_hash_small2.rb1
-rw-r--r--benchmark/bm_hash_small4.rb1
-rw-r--r--benchmark/bm_hash_small8.rb1
-rw-r--r--benchmark/bm_hash_to_proc.rb9
-rw-r--r--benchmark/bm_hash_values.rb9
-rw-r--r--benchmark/bm_int_quo.rb1
-rw-r--r--benchmark/bm_io_copy_stream_write.rb24
-rw-r--r--benchmark/bm_io_copy_stream_write_socket.rb35
-rw-r--r--benchmark/bm_io_file_create.rb13
-rw-r--r--benchmark/bm_io_file_read.rb15
-rw-r--r--benchmark/bm_io_file_write.rb14
-rw-r--r--benchmark/bm_io_nonblock_noex.rb22
-rw-r--r--benchmark/bm_io_nonblock_noex2.rb21
-rw-r--r--benchmark/bm_io_pipe_rw.rb13
-rw-r--r--benchmark/bm_io_select.rb9
-rw-r--r--benchmark/bm_io_select2.rb22
-rw-r--r--benchmark/bm_io_select3.rb21
-rw-r--r--benchmark/bm_loop_for.rb3
-rw-r--r--benchmark/bm_loop_generator.rb14
-rw-r--r--benchmark/bm_loop_times.rb1
-rw-r--r--benchmark/bm_loop_whileloop.rb4
-rw-r--r--benchmark/bm_loop_whileloop2.rb4
-rw-r--r--benchmark/bm_marshal_dump_flo.rb2
-rw-r--r--benchmark/bm_marshal_dump_load_geniv.rb10
-rw-r--r--benchmark/bm_marshal_dump_load_time.rb1
-rw-r--r--benchmark/bm_require.rb7
-rw-r--r--benchmark/bm_require_thread.rb15
-rw-r--r--benchmark/bm_securerandom.rb5
-rw-r--r--benchmark/bm_so_ackermann.rb19
-rw-r--r--benchmark/bm_so_array.rb23
-rw-r--r--benchmark/bm_so_binary_trees.rb62
-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_fannkuch.rb45
-rw-r--r--benchmark/bm_so_fasta.rb81
-rw-r--r--benchmark/bm_so_k_nucleotide.rb48
-rw-r--r--benchmark/bm_so_lists.rb47
-rw-r--r--benchmark/bm_so_mandelbrot.rb57
-rw-r--r--benchmark/bm_so_matrix.rb48
-rwxr-xr-xbenchmark/bm_so_meteor_contest.rb563
-rw-r--r--benchmark/bm_so_nbody.rb148
-rw-r--r--benchmark/bm_so_nested_loop.rb24
-rw-r--r--benchmark/bm_so_nsieve.rb35
-rw-r--r--benchmark/bm_so_nsieve_bits.rb43
-rw-r--r--benchmark/bm_so_object.rb56
-rw-r--r--benchmark/bm_so_partial_sums.rb31
-rw-r--r--benchmark/bm_so_pidigits.rb92
-rw-r--r--benchmark/bm_so_random.rb20
-rw-r--r--benchmark/bm_so_reverse_complement.rb30
-rw-r--r--benchmark/bm_so_sieve.rb24
-rw-r--r--benchmark/bm_so_spectralnorm.rb50
-rw-r--r--benchmark/bm_string_index.rb3
-rw-r--r--benchmark/bm_string_scan_re.rb2
-rw-r--r--benchmark/bm_string_scan_str.rb2
-rw-r--r--benchmark/bm_time_subsec.rb2
-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
-rwxr-xr-xbenchmark/bm_vm1_blockparam.rb9
-rwxr-xr-xbenchmark/bm_vm1_blockparam_call.rb9
-rwxr-xr-xbenchmark/bm_vm1_blockparam_pass.rb13
-rwxr-xr-xbenchmark/bm_vm1_blockparam_yield.rb9
-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_vm3_backtrace.rb22
-rw-r--r--benchmark/bm_vm3_clearmethodcache.rb8
-rw-r--r--benchmark/bm_vm3_gc.rb6
-rw-r--r--benchmark/bm_vm3_gc_old_full.rb4
-rw-r--r--benchmark/bm_vm3_gc_old_immediate.rb4
-rw-r--r--benchmark/bm_vm3_gc_old_lazy.rb4
-rw-r--r--benchmark/bm_vm_symbol_block_pass.rb13
-rw-r--r--benchmark/bm_vm_thread_alive_check1.rb6
-rw-r--r--benchmark/bm_vm_thread_close.rb6
-rw-r--r--benchmark/bm_vm_thread_condvar1.rb28
-rw-r--r--benchmark/bm_vm_thread_condvar2.rb35
-rw-r--r--benchmark/bm_vm_thread_create_join.rb6
-rw-r--r--benchmark/bm_vm_thread_mutex1.rb21
-rw-r--r--benchmark/bm_vm_thread_mutex2.rb21
-rw-r--r--benchmark/bm_vm_thread_mutex3.rb20
-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_pipe.rb17
-rw-r--r--benchmark/bm_vm_thread_queue.rb18
-rw-r--r--benchmark/bm_vm_thread_sized_queue.rb20
-rw-r--r--benchmark/bm_vm_thread_sized_queue2.rb23
-rw-r--r--benchmark/bm_vm_thread_sized_queue3.rb22
-rw-r--r--benchmark/bm_vm_thread_sized_queue4.rb26
-rwxr-xr-xbenchmark/driver.rb441
-rw-r--r--benchmark/gc/aobench.rb1
-rw-r--r--benchmark/gc/binary_trees.rb1
-rw-r--r--benchmark/gc/gcbench.rb56
-rw-r--r--benchmark/gc/hash1.rb11
-rw-r--r--benchmark/gc/hash2.rb7
-rw-r--r--benchmark/gc/null.rb1
-rw-r--r--benchmark/gc/pentomino.rb1
-rw-r--r--benchmark/gc/rdoc.rb13
-rw-r--r--benchmark/gc/redblack.rb366
-rw-r--r--benchmark/gc/ring.rb29
-rw-r--r--benchmark/make_fasta_output.rb19
-rw-r--r--benchmark/memory_wrapper.rb16
-rw-r--r--benchmark/other-lang/ack.pl11
-rw-r--r--benchmark/other-lang/ack.py16
-rw-r--r--benchmark/other-lang/ack.rb12
-rw-r--r--benchmark/other-lang/ack.scm7
-rw-r--r--benchmark/other-lang/eval.rb66
-rw-r--r--benchmark/other-lang/fact.pl13
-rw-r--r--benchmark/other-lang/fact.py18
-rw-r--r--benchmark/other-lang/fact.rb13
-rw-r--r--benchmark/other-lang/fact.scm8
-rw-r--r--benchmark/other-lang/fib.pl11
-rw-r--r--benchmark/other-lang/fib.py7
-rw-r--r--benchmark/other-lang/fib.rb9
-rw-r--r--benchmark/other-lang/fib.scm7
-rw-r--r--benchmark/other-lang/loop.pl3
-rw-r--r--benchmark/other-lang/loop.py2
-rw-r--r--benchmark/other-lang/loop.rb4
-rw-r--r--benchmark/other-lang/loop.scm1
-rw-r--r--benchmark/other-lang/loop2.rb1
-rw-r--r--benchmark/other-lang/tak.pl11
-rw-r--r--benchmark/other-lang/tak.py8
-rw-r--r--benchmark/other-lang/tak.rb13
-rw-r--r--benchmark/other-lang/tak.scm10
-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/report.rb79
-rw-r--r--benchmark/run.rb127
-rw-r--r--benchmark/runc.rb27
-rw-r--r--benchmark/wc.input.base25
-rw-r--r--beos/ruby.def.in353
-rw-r--r--bignum.c7573
-rwxr-xr-xbin/erb171
-rwxr-xr-xbin/gem25
-rwxr-xr-xbin/irb11
-rwxr-xr-xbin/rdoc44
-rwxr-xr-xbin/ri12
-rw-r--r--bootstraptest/pending.rb39
-rwxr-xr-xbootstraptest/runner.rb505
-rw-r--r--bootstraptest/test_attr.rb36
-rw-r--r--bootstraptest/test_autoload.rb70
-rw-r--r--bootstraptest/test_block.rb613
-rw-r--r--bootstraptest/test_class.rb169
-rw-r--r--bootstraptest/test_env.rb12
-rw-r--r--bootstraptest/test_eval.rb324
-rw-r--r--bootstraptest/test_exception.rb432
-rw-r--r--bootstraptest/test_finalizer.rb8
-rw-r--r--bootstraptest/test_flip.rb1
-rw-r--r--bootstraptest/test_flow.rb601
-rw-r--r--bootstraptest/test_fork.rb75
-rw-r--r--bootstraptest/test_gc.rb34
-rw-r--r--bootstraptest/test_insns.rb389
-rw-r--r--bootstraptest/test_io.rb112
-rw-r--r--bootstraptest/test_jump.rb308
-rw-r--r--bootstraptest/test_literal.rb247
-rw-r--r--bootstraptest/test_literal_suffix.rb54
-rw-r--r--bootstraptest/test_load.rb27
-rw-r--r--bootstraptest/test_marshal.rb5
-rw-r--r--bootstraptest/test_massign.rb183
-rw-r--r--bootstraptest/test_method.rb1192
-rw-r--r--bootstraptest/test_objectspace.rb46
-rw-r--r--bootstraptest/test_proc.rb483
-rw-r--r--bootstraptest/test_string.rb3
-rw-r--r--bootstraptest/test_struct.rb5
-rw-r--r--bootstraptest/test_syntax.rb904
-rw-r--r--bootstraptest/test_thread.rb484
-rw-r--r--ccan/build_assert/build_assert.h40
-rw-r--r--ccan/check_type/check_type.h63
-rw-r--r--ccan/container_of/container_of.h142
-rw-r--r--ccan/licenses/BSD-MIT17
-rw-r--r--ccan/licenses/CC028
-rw-r--r--ccan/list/list.h773
-rw-r--r--ccan/str/str.h16
-rw-r--r--class.c2134
-rw-r--r--common.mk2933
-rw-r--r--compar.c278
-rw-r--r--compile.c9599
-rw-r--r--complex.c2352
-rw-r--r--config.guess885
-rw-r--r--config.sub966
-rw-r--r--config_h.dj64
-rw-r--r--config_s.dj49
-rw-r--r--configure4273
-rw-r--r--configure.ac4591
-rw-r--r--configure.bat6
-rw-r--r--configure.in631
-rw-r--r--constant.h51
-rw-r--r--cont.c2009
-rw-r--r--coverage/README17
-rw-r--r--cygwin/GNUmakefile.in106
-rw-r--r--debug.c226
-rw-r--r--debug_counter.c41
-rw-r--r--debug_counter.h109
-rw-r--r--defines.h56
-rw-r--r--defs/gmake.mk146
-rw-r--r--defs/id.def181
-rw-r--r--defs/keywords53
-rw-r--r--defs/known_errors.def148
-rw-r--r--defs/lex.c.src53
-rw-r--r--defs/opt_insn_unif.def27
-rw-r--r--defs/opt_operand.def22
-rw-r--r--defs/separated_version.mk38
-rw-r--r--dir.c3316
-rw-r--r--dln.c952
-rw-r--r--dln.h43
-rw-r--r--dln_find.c290
-rw-r--r--dmydln.c10
-rw-r--r--dmyenc.c10
-rw-r--r--dmyext.c2
-rw-r--r--doc/.document3
-rw-r--r--doc/ChangeLog-0.06_to_0.521147
-rw-r--r--doc/ChangeLog-0.50_to_0.60462
-rw-r--r--doc/ChangeLog-0.60_to_1.13955
-rw-r--r--doc/ChangeLog-1.8.024350
-rw-r--r--doc/ChangeLog-1.9.392772
-rw-r--r--doc/ChangeLog-2.0.024015
-rw-r--r--doc/ChangeLog-2.1.018060
-rw-r--r--doc/ChangeLog-2.2.012157
-rw-r--r--doc/ChangeLog-2.3.012187
-rw-r--r--doc/ChangeLog-2.4.09492
-rw-r--r--doc/ChangeLog-20166
-rw-r--r--doc/ChangeLog-YARV6917
-rw-r--r--doc/NEWS-1.8.7669
-rw-r--r--doc/NEWS-1.9.1429
-rw-r--r--doc/NEWS-1.9.2509
-rw-r--r--doc/NEWS-1.9.3341
-rw-r--r--doc/NEWS-2.0.0531
-rw-r--r--doc/NEWS-2.1.0376
-rw-r--r--doc/NEWS-2.2.0361
-rw-r--r--doc/NEWS-2.3.0404
-rw-r--r--doc/NEWS-2.4.0397
-rw-r--r--doc/contributing.rdoc460
-rw-r--r--doc/contributors.rdoc793
-rw-r--r--doc/dtrace_probes.rdoc178
-rw-r--r--doc/etc.rd.ja75
-rw-r--r--doc/extension.ja.rdoc1833
-rw-r--r--doc/extension.rdoc1959
-rw-r--r--doc/forwardable.rd.ja80
-rw-r--r--doc/globals.rdoc70
-rw-r--r--doc/images/boottime-classes.pngbin0 -> 28677 bytes-rw-r--r--doc/irb/irb-tools.rd.ja184
-rw-r--r--doc/irb/irb.rd.ja407
-rw-r--r--doc/keywords.rdoc158
-rw-r--r--doc/maintainers.rdoc293
-rw-r--r--doc/marshal.rdoc313
-rw-r--r--doc/pty/README.expect.ja21
-rw-r--r--doc/pty/README.ja76
-rw-r--r--doc/regexp.rdoc704
-rw-r--r--doc/security.rdoc152
-rw-r--r--doc/shell.rd.ja335
-rw-r--r--doc/standard_library.rdoc131
-rw-r--r--doc/syntax.rdoc34
-rw-r--r--doc/syntax/assignment.rdoc454
-rw-r--r--doc/syntax/calling_methods.rdoc352
-rw-r--r--doc/syntax/control_expressions.rdoc499
-rw-r--r--doc/syntax/exceptions.rdoc95
-rw-r--r--doc/syntax/literals.rdoc368
-rw-r--r--doc/syntax/methods.rdoc459
-rw-r--r--doc/syntax/miscellaneous.rdoc106
-rw-r--r--doc/syntax/modules_and_classes.rdoc344
-rw-r--r--doc/syntax/precedence.rdoc60
-rw-r--r--doc/syntax/refinements.rdoc286
-rw-r--r--enc/Makefile.in84
-rw-r--r--enc/ascii.c104
-rw-r--r--enc/big5.c376
-rw-r--r--enc/cp949.c222
-rw-r--r--enc/depend754
-rw-r--r--enc/ebcdic.h11
-rw-r--r--enc/emacs_mule.c342
-rw-r--r--enc/encdb.c26
-rw-r--r--enc/encinit.c.erb37
-rw-r--r--enc/euc_jp.c616
-rw-r--r--enc/euc_kr.c220
-rw-r--r--enc/euc_tw.c228
-rw-r--r--enc/gb18030.c603
-rw-r--r--enc/gb2312.c13
-rw-r--r--enc/gbk.c225
-rw-r--r--enc/iso_2022_jp.h47
-rw-r--r--enc/iso_8859.h1
-rw-r--r--enc/iso_8859_1.c322
-rw-r--r--enc/iso_8859_10.c294
-rw-r--r--enc/iso_8859_11.c114
-rw-r--r--enc/iso_8859_13.c289
-rw-r--r--enc/iso_8859_14.c305
-rw-r--r--enc/iso_8859_15.c296
-rw-r--r--enc/iso_8859_16.c300
-rw-r--r--enc/iso_8859_2.c291
-rw-r--r--enc/iso_8859_3.c301
-rw-r--r--enc/iso_8859_4.c297
-rw-r--r--enc/iso_8859_5.c265
-rw-r--r--enc/iso_8859_6.c110
-rw-r--r--enc/iso_8859_7.c284
-rw-r--r--enc/iso_8859_8.c110
-rw-r--r--enc/iso_8859_9.c290
-rw-r--r--enc/jis/props.h.blt217
-rw-r--r--enc/jis/props.kwd52
-rw-r--r--enc/jis/props.src52
-rw-r--r--enc/koi8_r.c221
-rw-r--r--enc/koi8_u.c224
-rwxr-xr-xenc/make_encmake.rb151
-rw-r--r--enc/mktable.c1184
-rw-r--r--enc/shift_jis.c67
-rw-r--r--enc/shift_jis.h546
-rw-r--r--enc/trans/CP/CP932UDA%UCS.src1912
-rw-r--r--enc/trans/CP/CP932VDC@IBM%UCS.src420
-rw-r--r--enc/trans/CP/CP932VDC@NEC_IBM%UCS.src406
-rw-r--r--enc/trans/CP/UCS%CP932UDA.src1912
-rw-r--r--enc/trans/CP/UCS%CP932VDC@IBM.src420
-rw-r--r--enc/trans/CP/UCS%CP932VDC@NEC_IBM.src406
-rw-r--r--enc/trans/EMOJI/EMOJI_ISO-2022-JP-KDDI%UCS.src658
-rw-r--r--enc/trans/EMOJI/EMOJI_SHIFT_JIS-DOCOMO%UCS.src293
-rw-r--r--enc/trans/EMOJI/EMOJI_SHIFT_JIS-KDDI%UCS.src658
-rw-r--r--enc/trans/EMOJI/EMOJI_SHIFT_JIS-KDDI-UNDOC%UCS.src658
-rw-r--r--enc/trans/EMOJI/EMOJI_SHIFT_JIS-SOFTBANK%UCS.src496
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_ISO-2022-JP-KDDI-UNDOC.src658
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_ISO-2022-JP-KDDI.src658
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_SHIFT_JIS-DOCOMO.src293
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_SHIFT_JIS-KDDI-UNDOC.src658
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_SHIFT_JIS-KDDI.src658
-rw-r--r--enc/trans/EMOJI/UCS%EMOJI_SHIFT_JIS-SOFTBANK.src496
-rw-r--r--enc/trans/GB/GB12345%UCS.src7567
-rw-r--r--enc/trans/GB/GB2312%UCS.src7470
-rw-r--r--enc/trans/GB/UCS%GB12345.src7569
-rw-r--r--enc/trans/GB/UCS%GB2312.src7466
-rw-r--r--enc/trans/JIS/JISX0201-KANA%UCS.src124
-rw-r--r--enc/trans/JIS/JISX0208@1990%UCS.src6964
-rw-r--r--enc/trans/JIS/JISX0208@MS%UCS.src6893
-rw-r--r--enc/trans/JIS/JISX0208UDC%UCS.src954
-rw-r--r--enc/trans/JIS/JISX0208VDC@NEC%UCS.src97
-rw-r--r--enc/trans/JIS/JISX0212%UCS.src6159
-rw-r--r--enc/trans/JIS/JISX0212@MS%UCS.src6081
-rw-r--r--enc/trans/JIS/JISX0212UDC%UCS.src954
-rw-r--r--enc/trans/JIS/JISX0212VDC@IBM%UCS.src120
-rw-r--r--enc/trans/JIS/JISX0213-1%UCS@BMP.src1926
-rw-r--r--enc/trans/JIS/JISX0213-1%UCS@SIP.src60
-rw-r--r--enc/trans/JIS/JISX0213-2%UCS@BMP.src2193
-rw-r--r--enc/trans/JIS/JISX0213-2%UCS@SIP.src311
-rw-r--r--enc/trans/JIS/UCS%JISX0201-KANA.src125
-rw-r--r--enc/trans/JIS/UCS%JISX0208@1990.src6965
-rw-r--r--enc/trans/JIS/UCS%JISX0208@MS.src6894
-rw-r--r--enc/trans/JIS/UCS%JISX0208UDC.src955
-rw-r--r--enc/trans/JIS/UCS%JISX0208VDC@NEC.src98
-rw-r--r--enc/trans/JIS/UCS%JISX0212.src6163
-rw-r--r--enc/trans/JIS/UCS%JISX0212@MS.src6082
-rw-r--r--enc/trans/JIS/UCS%JISX0212UDC.src955
-rw-r--r--enc/trans/JIS/UCS%JISX0212VDC@IBM.src121
-rw-r--r--enc/trans/JIS/UCS@BMP%JISX0213-1.src1922
-rw-r--r--enc/trans/JIS/UCS@BMP%JISX0213-2.src2189
-rw-r--r--enc/trans/JIS/UCS@SIP%JISX0213-1.src56
-rw-r--r--enc/trans/JIS/UCS@SIP%JISX0213-2.src307
-rw-r--r--enc/trans/big5-hkscs-tbl.rb37302
-rw-r--r--enc/trans/big5-uao-tbl.rb19784
-rw-r--r--enc/trans/big5.trans32
-rw-r--r--enc/trans/chinese.trans31
-rw-r--r--enc/trans/cp850-tbl.rb130
-rw-r--r--enc/trans/cp852-tbl.rb130
-rw-r--r--enc/trans/cp855-tbl.rb130
-rw-r--r--enc/trans/cp949-tbl.rb8831
-rw-r--r--enc/trans/ebcdic.trans278
-rw-r--r--enc/trans/emoji-exchange-tbl.rb8407
-rw-r--r--enc/trans/emoji.trans36
-rw-r--r--enc/trans/emoji_iso2022_kddi.trans216
-rw-r--r--enc/trans/emoji_sjis_docomo.trans32
-rw-r--r--enc/trans/emoji_sjis_kddi.trans33
-rw-r--r--enc/trans/emoji_sjis_softbank.trans32
-rw-r--r--enc/trans/escape.trans93
-rw-r--r--enc/trans/euckr-tbl.rb8230
-rw-r--r--enc/trans/gb18030-tbl.rb63362
-rw-r--r--enc/trans/gb18030.trans183
-rw-r--r--enc/trans/gbk-tbl.rb21794
-rw-r--r--enc/trans/gbk.trans15
-rw-r--r--enc/trans/ibm437-tbl.rb130
-rw-r--r--enc/trans/ibm737-tbl.rb130
-rw-r--r--enc/trans/ibm775-tbl.rb130
-rw-r--r--enc/trans/ibm852-tbl.rb130
-rw-r--r--enc/trans/ibm855-tbl.rb130
-rw-r--r--enc/trans/ibm857-tbl.rb127
-rw-r--r--enc/trans/ibm860-tbl.rb130
-rw-r--r--enc/trans/ibm861-tbl.rb130
-rw-r--r--enc/trans/ibm862-tbl.rb130
-rw-r--r--enc/trans/ibm863-tbl.rb130
-rw-r--r--enc/trans/ibm865-tbl.rb130
-rw-r--r--enc/trans/ibm866-tbl.rb130
-rw-r--r--enc/trans/ibm869-tbl.rb121
-rw-r--r--enc/trans/iso-8859-1-tbl.rb98
-rw-r--r--enc/trans/iso-8859-10-tbl.rb98
-rw-r--r--enc/trans/iso-8859-11-tbl.rb90
-rw-r--r--enc/trans/iso-8859-13-tbl.rb98
-rw-r--r--enc/trans/iso-8859-14-tbl.rb98
-rw-r--r--enc/trans/iso-8859-15-tbl.rb98
-rw-r--r--enc/trans/iso-8859-16-tbl.rb98
-rw-r--r--enc/trans/iso-8859-2-tbl.rb98
-rw-r--r--enc/trans/iso-8859-3-tbl.rb91
-rw-r--r--enc/trans/iso-8859-4-tbl.rb98
-rw-r--r--enc/trans/iso-8859-5-tbl.rb98
-rw-r--r--enc/trans/iso-8859-6-tbl.rb53
-rw-r--r--enc/trans/iso-8859-7-tbl.rb95
-rw-r--r--enc/trans/iso-8859-8-tbl.rb62
-rw-r--r--enc/trans/iso-8859-9-tbl.rb98
-rw-r--r--enc/trans/iso2022.trans567
-rw-r--r--enc/trans/japanese.trans97
-rw-r--r--enc/trans/japanese_euc.trans57
-rw-r--r--enc/trans/japanese_sjis.trans33
-rw-r--r--enc/trans/koi8-r-tbl.rb130
-rw-r--r--enc/trans/koi8-u-tbl.rb130
-rw-r--r--enc/trans/korean.trans18
-rw-r--r--enc/trans/maccroatian-tbl.rb129
-rw-r--r--enc/trans/maccyrillic-tbl.rb130
-rw-r--r--enc/trans/macgreek-tbl.rb129
-rw-r--r--enc/trans/maciceland-tbl.rb129
-rw-r--r--enc/trans/macroman-tbl.rb129
-rw-r--r--enc/trans/macromania-tbl.rb129
-rw-r--r--enc/trans/macturkish-tbl.rb128
-rw-r--r--enc/trans/macukraine-tbl.rb130
-rw-r--r--enc/trans/newline.trans135
-rw-r--r--enc/trans/single_byte.trans88
-rw-r--r--enc/trans/tis-620-tbl.rb89
-rw-r--r--enc/trans/transdb.c18
-rw-r--r--enc/trans/ucm/glibc-BIG5-2.3.3.ucm14087
-rw-r--r--enc/trans/ucm/glibc-BIG5HKSCS-2.3.3.ucm18332
-rw-r--r--enc/trans/ucm/windows-950-2000.ucm20379
-rw-r--r--enc/trans/ucm/windows-950_hkscs-2001.ucm23446
-rw-r--r--enc/trans/utf8_mac-tbl.rb23154
-rw-r--r--enc/trans/utf8_mac.trans256
-rw-r--r--enc/trans/utf_16_32.trans556
-rw-r--r--enc/trans/windows-1250-tbl.rb125
-rw-r--r--enc/trans/windows-1251-tbl.rb129
-rw-r--r--enc/trans/windows-1252-tbl.rb125
-rw-r--r--enc/trans/windows-1253-tbl.rb113
-rw-r--r--enc/trans/windows-1254-tbl.rb123
-rw-r--r--enc/trans/windows-1255-tbl.rb142
-rw-r--r--enc/trans/windows-1256-tbl.rb130
-rw-r--r--enc/trans/windows-1257-tbl.rb118
-rw-r--r--enc/trans/windows-874-tbl.rb99
-rw-r--r--enc/unicode.c803
-rw-r--r--enc/unicode/10.0.0/casefold.h7044
-rw-r--r--enc/unicode/10.0.0/name2ctype.h38381
-rwxr-xr-xenc/unicode/case-folding.rb419
-rw-r--r--enc/us_ascii.c41
-rw-r--r--enc/utf_16_32.h5
-rw-r--r--enc/utf_16be.c256
-rw-r--r--enc/utf_16le.c248
-rw-r--r--enc/utf_32be.c206
-rw-r--r--enc/utf_32le.c206
-rw-r--r--enc/utf_7.h5
-rw-r--r--enc/utf_8.c449
-rw-r--r--enc/windows_1250.c271
-rw-r--r--enc/windows_1251.c253
-rw-r--r--enc/windows_1252.c260
-rw-r--r--enc/windows_1253.c297
-rw-r--r--enc/windows_1254.c302
-rw-r--r--enc/windows_1257.c304
-rw-r--r--enc/windows_31j.c81
-rw-r--r--enc/x_emoji.h26
-rw-r--r--encindex.h69
-rw-r--r--encoding.c1978
-rw-r--r--enum.c4093
-rw-r--r--enumerator.c2444
-rw-r--r--env.h52
-rw-r--r--error.c3493
-rw-r--r--eval.c7651
-rw-r--r--eval_error.c386
-rw-r--r--eval_intern.h334
-rw-r--r--eval_jump.c144
-rw-r--r--ext/-test-/array/resize/depend12
-rw-r--r--ext/-test-/array/resize/extconf.rb2
-rw-r--r--ext/-test-/array/resize/resize.c14
-rw-r--r--ext/-test-/auto_ext.rb10
-rw-r--r--ext/-test-/bignum/big2str.c53
-rw-r--r--ext/-test-/bignum/bigzero.c26
-rw-r--r--ext/-test-/bignum/depend115
-rw-r--r--ext/-test-/bignum/div.c35
-rw-r--r--ext/-test-/bignum/extconf.rb3
-rw-r--r--ext/-test-/bignum/init.c11
-rw-r--r--ext/-test-/bignum/intpack.c87
-rw-r--r--ext/-test-/bignum/mul.c65
-rw-r--r--ext/-test-/bignum/str2big.c38
-rw-r--r--ext/-test-/bug-3571/bug.c23
-rw-r--r--ext/-test-/bug-3571/extconf.rb2
-rw-r--r--ext/-test-/bug-5832/bug.c14
-rw-r--r--ext/-test-/bug-5832/extconf.rb2
-rw-r--r--ext/-test-/bug_reporter/bug_reporter.c24
-rw-r--r--ext/-test-/bug_reporter/extconf.rb2
-rw-r--r--ext/-test-/class/class2name.c14
-rw-r--r--ext/-test-/class/depend23
-rw-r--r--ext/-test-/class/extconf.rb3
-rw-r--r--ext/-test-/class/init.c11
-rw-r--r--ext/-test-/debug/depend35
-rw-r--r--ext/-test-/debug/extconf.rb3
-rw-r--r--ext/-test-/debug/init.c11
-rw-r--r--ext/-test-/debug/inspector.c32
-rw-r--r--ext/-test-/debug/profile_frames.c43
-rw-r--r--ext/-test-/dln/empty/depend3
-rw-r--r--ext/-test-/dln/empty/empty.c4
-rw-r--r--ext/-test-/dln/empty/extconf.rb2
-rw-r--r--ext/-test-/exception/dataerror.c31
-rw-r--r--ext/-test-/exception/depend48
-rw-r--r--ext/-test-/exception/enc_raise.c15
-rw-r--r--ext/-test-/exception/ensured.c39
-rw-r--r--ext/-test-/exception/extconf.rb3
-rw-r--r--ext/-test-/exception/init.c11
-rw-r--r--ext/-test-/fatal/extconf.rb2
-rw-r--r--ext/-test-/fatal/rb_fatal.c19
-rw-r--r--ext/-test-/file/depend41
-rw-r--r--ext/-test-/file/extconf.rb18
-rw-r--r--ext/-test-/file/fs.c111
-rw-r--r--ext/-test-/file/init.c11
-rw-r--r--ext/-test-/file/stat.c27
-rw-r--r--ext/-test-/float/depend3
-rw-r--r--ext/-test-/float/extconf.rb3
-rw-r--r--ext/-test-/float/init.c11
-rw-r--r--ext/-test-/float/nextafter.c36
-rw-r--r--ext/-test-/funcall/extconf.rb3
-rw-r--r--ext/-test-/funcall/funcall.c44
-rw-r--r--ext/-test-/gvl/call_without_gvl/call_without_gvl.c34
-rw-r--r--ext/-test-/gvl/call_without_gvl/depend13
-rw-r--r--ext/-test-/gvl/call_without_gvl/extconf.rb2
-rw-r--r--ext/-test-/hash/delete.c16
-rw-r--r--ext/-test-/hash/extconf.rb3
-rw-r--r--ext/-test-/hash/init.c11
-rw-r--r--ext/-test-/integer/core_ext.c36
-rw-r--r--ext/-test-/integer/depend40
-rw-r--r--ext/-test-/integer/extconf.rb3
-rw-r--r--ext/-test-/integer/init.c11
-rw-r--r--ext/-test-/integer/my_integer.c16
-rw-r--r--ext/-test-/iseq_load/extconf.rb2
-rw-r--r--ext/-test-/iseq_load/iseq_load.c21
-rw-r--r--ext/-test-/iter/break.c25
-rw-r--r--ext/-test-/iter/extconf.rb3
-rw-r--r--ext/-test-/iter/init.c11
-rw-r--r--ext/-test-/iter/yield.c16
-rw-r--r--ext/-test-/load/dot.dot/depend3
-rw-r--r--ext/-test-/load/dot.dot/dot.dot.c1
-rw-r--r--ext/-test-/load/dot.dot/extconf.rb2
-rw-r--r--ext/-test-/load/protect/extconf.rb1
-rw-r--r--ext/-test-/load/protect/protect.c19
-rw-r--r--ext/-test-/marshal/compat/extconf.rb2
-rw-r--r--ext/-test-/marshal/compat/usrcompat.c32
-rw-r--r--ext/-test-/marshal/internal_ivar/extconf.rb2
-rw-r--r--ext/-test-/marshal/internal_ivar/internal_ivar.c39
-rw-r--r--ext/-test-/marshal/usr/extconf.rb2
-rw-r--r--ext/-test-/marshal/usr/usrmarshal.c50
-rw-r--r--ext/-test-/memory_status/extconf.rb12
-rw-r--r--ext/-test-/memory_status/memory_status.c65
-rw-r--r--ext/-test-/method/arity.c22
-rw-r--r--ext/-test-/method/extconf.rb3
-rw-r--r--ext/-test-/method/init.c11
-rw-r--r--ext/-test-/notimplement/bug.c16
-rw-r--r--ext/-test-/notimplement/extconf.rb2
-rw-r--r--ext/-test-/num2int/extconf.rb2
-rw-r--r--ext/-test-/num2int/num2int.c136
-rw-r--r--ext/-test-/path_to_class/extconf.rb7
-rw-r--r--ext/-test-/path_to_class/path_to_class.c15
-rw-r--r--ext/-test-/popen_deadlock/extconf.rb5
-rw-r--r--ext/-test-/popen_deadlock/infinite_loop_dlsym.c50
-rw-r--r--ext/-test-/postponed_job/depend1
-rw-r--r--ext/-test-/postponed_job/extconf.rb2
-rw-r--r--ext/-test-/postponed_job/postponed_job.c53
-rw-r--r--ext/-test-/printf/depend3
-rw-r--r--ext/-test-/printf/extconf.rb2
-rw-r--r--ext/-test-/printf/printf.c109
-rw-r--r--ext/-test-/proc/extconf.rb3
-rw-r--r--ext/-test-/proc/init.c11
-rw-r--r--ext/-test-/proc/receiver.c21
-rw-r--r--ext/-test-/proc/super.c27
-rw-r--r--ext/-test-/rational/depend22
-rw-r--r--ext/-test-/rational/extconf.rb8
-rw-r--r--ext/-test-/rational/rat.c37
-rw-r--r--ext/-test-/recursion/extconf.rb3
-rw-r--r--ext/-test-/recursion/recursion.c28
-rw-r--r--ext/-test-/regexp/extconf.rb3
-rw-r--r--ext/-test-/regexp/init.c11
-rw-r--r--ext/-test-/regexp/parse_depth_limit.c23
-rwxr-xr-xext/-test-/scan_args/extconf.rb1
-rw-r--r--ext/-test-/scan_args/scan_args.c286
-rw-r--r--ext/-test-/st/foreach/extconf.rb2
-rw-r--r--ext/-test-/st/foreach/foreach.c175
-rw-r--r--ext/-test-/st/numhash/extconf.rb2
-rw-r--r--ext/-test-/st/numhash/numhash.c138
-rw-r--r--ext/-test-/st/update/extconf.rb2
-rw-r--r--ext/-test-/st/update/update.c34
-rw-r--r--ext/-test-/string/capacity.c17
-rw-r--r--ext/-test-/string/coderange.c47
-rw-r--r--ext/-test-/string/cstr.c146
-rw-r--r--ext/-test-/string/depend198
-rw-r--r--ext/-test-/string/ellipsize.c13
-rw-r--r--ext/-test-/string/enc_associate.c22
-rw-r--r--ext/-test-/string/enc_str_buf_cat.c14
-rw-r--r--ext/-test-/string/extconf.rb3
-rw-r--r--ext/-test-/string/fstring.c15
-rw-r--r--ext/-test-/string/init.c11
-rw-r--r--ext/-test-/string/modify.c22
-rw-r--r--ext/-test-/string/new.c21
-rw-r--r--ext/-test-/string/nofree.c13
-rw-r--r--ext/-test-/string/normalize.c17
-rw-r--r--ext/-test-/string/qsort.c61
-rw-r--r--ext/-test-/string/rb_str_dup.c35
-rw-r--r--ext/-test-/string/set_len.c14
-rw-r--r--ext/-test-/struct/depend46
-rw-r--r--ext/-test-/struct/duplicate.c24
-rw-r--r--ext/-test-/struct/extconf.rb3
-rw-r--r--ext/-test-/struct/init.c11
-rw-r--r--ext/-test-/struct/len.c13
-rw-r--r--ext/-test-/struct/member.c18
-rw-r--r--ext/-test-/symbol/extconf.rb4
-rw-r--r--ext/-test-/symbol/init.c31
-rw-r--r--ext/-test-/symbol/type.c78
-rw-r--r--ext/-test-/thread_fd_close/depend16
-rw-r--r--ext/-test-/thread_fd_close/extconf.rb2
-rw-r--r--ext/-test-/thread_fd_close/thread_fd_close.c14
-rw-r--r--ext/-test-/time/extconf.rb3
-rw-r--r--ext/-test-/time/init.c11
-rw-r--r--ext/-test-/time/new.c34
-rw-r--r--ext/-test-/tracepoint/depend24
-rw-r--r--ext/-test-/tracepoint/extconf.rb2
-rw-r--r--ext/-test-/tracepoint/gc_hook.c80
-rw-r--r--ext/-test-/tracepoint/tracepoint.c96
-rw-r--r--ext/-test-/typeddata/extconf.rb2
-rw-r--r--ext/-test-/typeddata/typeddata.c44
-rw-r--r--ext/-test-/vm/at_exit.c44
-rw-r--r--ext/-test-/vm/depend13
-rw-r--r--ext/-test-/vm/extconf.rb1
-rw-r--r--ext/-test-/wait_for_single_fd/depend16
-rw-r--r--ext/-test-/wait_for_single_fd/extconf.rb2
-rw-r--r--ext/-test-/wait_for_single_fd/wait_for_single_fd.c30
-rw-r--r--ext/-test-/win32/console/attribute.c64
-rw-r--r--ext/-test-/win32/console/depend1
-rw-r--r--ext/-test-/win32/console/extconf.rb5
-rw-r--r--ext/-test-/win32/console/init.c11
-rw-r--r--ext/-test-/win32/dln/depend9
-rw-r--r--ext/-test-/win32/dln/dlntest.c17
-rw-r--r--ext/-test-/win32/dln/extconf.rb33
-rw-r--r--ext/-test-/win32/dln/libdlntest.c4
-rw-r--r--ext/-test-/win32/dln/libdlntest.def2
-rw-r--r--ext/-test-/win32/fd_setsize/depend1
-rw-r--r--ext/-test-/win32/fd_setsize/extconf.rb4
-rw-r--r--ext/-test-/win32/fd_setsize/fd_setsize.c55
-rw-r--r--ext/.document91
-rw-r--r--ext/Setup44
-rw-r--r--ext/Setup.atheos29
-rw-r--r--ext/Setup.dj12
-rw-r--r--ext/Setup.nt34
-rw-r--r--ext/Setup.x6812
-rw-r--r--ext/Win32API/MANIFEST7
-rw-r--r--ext/Win32API/Win32API.c223
-rw-r--r--ext/Win32API/extconf.rb7
-rw-r--r--ext/Win32API/getch.rb5
-rw-r--r--ext/Win32API/point.rb18
-rw-r--r--ext/aix_ld.rb73
-rw-r--r--ext/bigdecimal/bigdecimal.c6449
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec39
-rw-r--r--ext/bigdecimal/bigdecimal.h394
-rw-r--r--ext/bigdecimal/depend13
-rw-r--r--ext/bigdecimal/extconf.rb35
-rw-r--r--ext/bigdecimal/lib/bigdecimal/jacobian.rb88
-rw-r--r--ext/bigdecimal/lib/bigdecimal/ludcmp.rb89
-rw-r--r--ext/bigdecimal/lib/bigdecimal/math.rb232
-rw-r--r--ext/bigdecimal/lib/bigdecimal/newton.rb80
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb134
-rw-r--r--ext/bigdecimal/sample/linear.rb73
-rw-r--r--ext/bigdecimal/sample/nlsolve.rb40
-rw-r--r--ext/bigdecimal/sample/pi.rb21
-rw-r--r--ext/cgi/escape/depend16
-rw-r--r--ext/cgi/escape/escape.c422
-rw-r--r--ext/cgi/escape/extconf.rb3
-rw-r--r--ext/continuation/continuation.c13
-rw-r--r--ext/continuation/depend12
-rw-r--r--ext/continuation/extconf.rb4
-rw-r--r--ext/coverage/coverage.c304
-rw-r--r--ext/coverage/depend44
-rw-r--r--ext/coverage/extconf.rb5
-rw-r--r--ext/curses/MANIFEST6
-rw-r--r--ext/curses/curses.c826
-rw-r--r--ext/curses/extconf.rb22
-rw-r--r--ext/curses/hello.rb30
-rw-r--r--ext/curses/rain.rb76
-rw-r--r--ext/curses/view.rb91
-rw-r--r--ext/cygwin32_ld.rb90
-rw-r--r--ext/date/date.gemspec24
-rw-r--r--ext/date/date_core.c9671
-rw-r--r--ext/date/date_parse.c2998
-rw-r--r--ext/date/date_strftime.c638
-rw-r--r--ext/date/date_strptime.c703
-rw-r--r--ext/date/date_tmx.h56
-rw-r--r--ext/date/depend63
-rw-r--r--ext/date/extconf.rb9
-rw-r--r--ext/date/lib/date.rb61
-rw-r--r--ext/date/prereq.mk8
-rw-r--r--ext/date/zonetab.h895
-rw-r--r--ext/date/zonetab.list181
-rw-r--r--ext/dbm/MANIFEST4
-rw-r--r--ext/dbm/dbm.c1076
-rw-r--r--ext/dbm/dbm.gemspec21
-rw-r--r--ext/dbm/depend14
-rw-r--r--ext/dbm/extconf.rb293
-rw-r--r--ext/digest/bubblebabble/bubblebabble.c146
-rw-r--r--ext/digest/bubblebabble/depend14
-rw-r--r--ext/digest/bubblebabble/extconf.rb6
-rw-r--r--ext/digest/defs.h19
-rw-r--r--ext/digest/depend14
-rw-r--r--ext/digest/digest.c798
-rw-r--r--ext/digest/digest.h51
-rw-r--r--ext/digest/digest_conf.rb84
-rw-r--r--ext/digest/extconf.rb11
-rw-r--r--ext/digest/lib/digest.rb109
-rw-r--r--ext/digest/md5/depend18
-rw-r--r--ext/digest/md5/extconf.rb19
-rw-r--r--ext/digest/md5/md5.c424
-rw-r--r--ext/digest/md5/md5.h80
-rw-r--r--ext/digest/md5/md5cc.h12
-rw-r--r--ext/digest/md5/md5init.c68
-rw-r--r--ext/digest/md5/md5ossl.h15
-rw-r--r--ext/digest/rmd160/depend18
-rw-r--r--ext/digest/rmd160/extconf.rb19
-rw-r--r--ext/digest/rmd160/rmd160.c463
-rw-r--r--ext/digest/rmd160/rmd160.h56
-rw-r--r--ext/digest/rmd160/rmd160init.c66
-rw-r--r--ext/digest/rmd160/rmd160ossl.h20
-rw-r--r--ext/digest/sha1/depend18
-rw-r--r--ext/digest/sha1/extconf.rb19
-rw-r--r--ext/digest/sha1/sha1.c271
-rw-r--r--ext/digest/sha1/sha1.h39
-rw-r--r--ext/digest/sha1/sha1cc.h14
-rw-r--r--ext/digest/sha1/sha1init.c70
-rw-r--r--ext/digest/sha1/sha1ossl.h22
-rw-r--r--ext/digest/sha2/depend18
-rw-r--r--ext/digest/sha2/extconf.rb21
-rw-r--r--ext/digest/sha2/lib/sha2.rb142
-rw-r--r--ext/digest/sha2/sha2.c1081
-rw-r--r--ext/digest/sha2/sha2.h225
-rw-r--r--ext/digest/sha2/sha2cc.h31
-rw-r--r--ext/digest/sha2/sha2init.c61
-rw-r--r--ext/digest/sha2/sha2ossl.h27
-rw-r--r--ext/digest/test.sh30
-rw-r--r--ext/etc/MANIFEST5
-rw-r--r--ext/etc/depend23
-rw-r--r--ext/etc/etc.c1171
-rw-r--r--ext/etc/etc.doc73
-rw-r--r--ext/etc/etc.gemspec42
-rw-r--r--ext/etc/extconf.rb65
-rw-r--r--ext/etc/mkconstants.rb332
-rwxr-xr-xext/extmk.rb760
-rw-r--r--ext/extmk.rb.in556
-rw-r--r--ext/extmk.rb.nt501
-rw-r--r--ext/fcntl/MANIFEST3
-rw-r--r--ext/fcntl/depend14
-rw-r--r--ext/fcntl/extconf.rb3
-rw-r--r--ext/fcntl/fcntl.c157
-rw-r--r--ext/fcntl/fcntl.gemspec26
-rw-r--r--ext/fiber/depend1
-rw-r--r--ext/fiber/extconf.rb4
-rw-r--r--ext/fiber/fiber.c8
-rw-r--r--ext/fiddle/closure.c345
-rw-r--r--ext/fiddle/closure.h8
-rw-r--r--ext/fiddle/conversions.c141
-rw-r--r--ext/fiddle/conversions.h44
-rw-r--r--ext/fiddle/depend156
-rw-r--r--ext/fiddle/extconf.rb183
-rw-r--r--ext/fiddle/extlibs5
-rw-r--r--ext/fiddle/fiddle.c454
-rw-r--r--ext/fiddle/fiddle.gemspec23
-rw-r--r--ext/fiddle/fiddle.h138
-rw-r--r--ext/fiddle/function.c315
-rw-r--r--ext/fiddle/function.h8
-rw-r--r--ext/fiddle/handle.c479
-rw-r--r--ext/fiddle/lib/fiddle.rb56
-rw-r--r--ext/fiddle/lib/fiddle/closure.rb49
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb197
-rw-r--r--ext/fiddle/lib/fiddle/function.rb18
-rw-r--r--ext/fiddle/lib/fiddle/import.rb318
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb129
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb244
-rw-r--r--ext/fiddle/lib/fiddle/types.rb72
-rw-r--r--ext/fiddle/lib/fiddle/value.rb113
-rw-r--r--ext/fiddle/pointer.c721
-rwxr-xr-xext/fiddle/win32/fficonfig.h29
-rw-r--r--ext/fiddle/win32/libffi-3.2.1-mswin.patch191
-rwxr-xr-xext/fiddle/win32/libffi-config.rb48
-rwxr-xr-xext/fiddle/win32/libffi.mk.tmpl96
-rw-r--r--ext/gdbm/README1
-rw-r--r--ext/gdbm/depend13
-rw-r--r--ext/gdbm/extconf.rb19
-rw-r--r--ext/gdbm/gdbm.c1305
-rw-r--r--ext/gdbm/gdbm.gemspec27
-rwxr-xr-xext/io/console/buildgem.sh5
-rw-r--r--ext/io/console/console.c1012
-rw-r--r--ext/io/console/depend37
-rw-r--r--ext/io/console/extconf.rb29
-rw-r--r--ext/io/console/io-console.gemspec24
-rw-r--r--ext/io/console/lib/console/size.rb23
-rw-r--r--ext/io/console/win32_vk.chksum1
-rw-r--r--ext/io/console/win32_vk.inc1391
-rw-r--r--ext/io/console/win32_vk.list166
-rw-r--r--ext/io/nonblock/depend17
-rw-r--r--ext/io/nonblock/extconf.rb9
-rw-r--r--ext/io/nonblock/nonblock.c140
-rw-r--r--ext/io/wait/depend17
-rw-r--r--ext/io/wait/extconf.rb19
-rw-r--r--ext/io/wait/wait.c254
-rw-r--r--ext/json/extconf.rb2
-rw-r--r--ext/json/fbuffer/fbuffer.h187
-rw-r--r--ext/json/generator/depend23
-rw-r--r--ext/json/generator/extconf.rb4
-rw-r--r--ext/json/generator/generator.c1443
-rw-r--r--ext/json/generator/generator.h171
-rw-r--r--ext/json/json.gemspecbin0 -> 5474 bytes-rw-r--r--ext/json/lib/json.rb63
-rw-r--r--ext/json/lib/json/add/bigdecimal.rb29
-rw-r--r--ext/json/lib/json/add/complex.rb29
-rw-r--r--ext/json/lib/json/add/core.rb12
-rw-r--r--ext/json/lib/json/add/date.rb34
-rw-r--r--ext/json/lib/json/add/date_time.rb50
-rw-r--r--ext/json/lib/json/add/exception.rb31
-rw-r--r--ext/json/lib/json/add/ostruct.rb31
-rw-r--r--ext/json/lib/json/add/range.rb29
-rw-r--r--ext/json/lib/json/add/rational.rb28
-rw-r--r--ext/json/lib/json/add/regexp.rb30
-rw-r--r--ext/json/lib/json/add/struct.rb30
-rw-r--r--ext/json/lib/json/add/symbol.rb25
-rw-r--r--ext/json/lib/json/add/time.rb38
-rw-r--r--ext/json/lib/json/common.rb456
-rw-r--r--ext/json/lib/json/ext.rb15
-rw-r--r--ext/json/lib/json/generic_object.rb71
-rw-r--r--ext/json/lib/json/version.rb9
-rw-r--r--ext/json/parser/depend22
-rw-r--r--ext/json/parser/extconf.rb6
-rw-r--r--ext/json/parser/parser.c2109
-rw-r--r--ext/json/parser/parser.h91
-rw-r--r--ext/json/parser/parser.rl869
-rw-r--r--ext/json/parser/prereq.mk10
-rw-r--r--ext/kconv/MANIFEST3
-rw-r--r--ext/kconv/depend1
-rw-r--r--ext/kconv/kconv.c2016
-rw-r--r--ext/md5/MANIFEST6
-rw-r--r--ext/md5/depend2
-rw-r--r--ext/md5/md5.doc36
-rw-r--r--ext/md5/md5.h86
-rw-r--r--ext/md5/md5c.c337
-rw-r--r--ext/md5/md5init.c94
-rw-r--r--ext/nkf/depend24
-rw-r--r--ext/nkf/extconf.rb3
-rw-r--r--ext/nkf/lib/kconv.rb283
-rw-r--r--ext/nkf/nkf-utf8/config.h51
-rw-r--r--ext/nkf/nkf-utf8/nkf.c7192
-rw-r--r--ext/nkf/nkf-utf8/nkf.h189
-rw-r--r--ext/nkf/nkf-utf8/utf8tbl.c14628
-rw-r--r--ext/nkf/nkf-utf8/utf8tbl.h72
-rw-r--r--ext/nkf/nkf.c504
-rw-r--r--ext/objspace/depend75
-rw-r--r--ext/objspace/extconf.rb4
-rw-r--r--ext/objspace/object_tracing.c492
-rw-r--r--ext/objspace/objspace.c975
-rw-r--r--ext/objspace/objspace.h20
-rw-r--r--ext/objspace/objspace_dump.c516
-rw-r--r--ext/openssl/History.md339
-rw-r--r--ext/openssl/depend1154
-rw-r--r--ext/openssl/deprecation.rb23
-rw-r--r--ext/openssl/extconf.rb173
-rw-r--r--ext/openssl/lib/openssl.rb22
-rw-r--r--ext/openssl/lib/openssl/bn.rb40
-rw-r--r--ext/openssl/lib/openssl/buffering.rb462
-rw-r--r--ext/openssl/lib/openssl/cipher.rb67
-rw-r--r--ext/openssl/lib/openssl/config.rb474
-rw-r--r--ext/openssl/lib/openssl/digest.rb75
-rw-r--r--ext/openssl/lib/openssl/pkcs5.rb22
-rw-r--r--ext/openssl/lib/openssl/pkey.rb25
-rw-r--r--ext/openssl/lib/openssl/ssl.rb503
-rw-r--r--ext/openssl/lib/openssl/x509.rb215
-rw-r--r--ext/openssl/openssl.gemspec46
-rw-r--r--ext/openssl/openssl_missing.c106
-rw-r--r--ext/openssl/openssl_missing.h222
-rw-r--r--ext/openssl/ossl.c1249
-rw-r--r--ext/openssl/ossl.h178
-rw-r--r--ext/openssl/ossl_asn1.c1854
-rw-r--r--ext/openssl/ossl_asn1.h62
-rw-r--r--ext/openssl/ossl_bio.c42
-rw-r--r--ext/openssl/ossl_bio.h16
-rw-r--r--ext/openssl/ossl_bn.c1202
-rw-r--r--ext/openssl/ossl_bn.h25
-rw-r--r--ext/openssl/ossl_cipher.c1066
-rw-r--r--ext/openssl/ossl_cipher.h20
-rw-r--r--ext/openssl/ossl_config.c89
-rw-r--r--ext/openssl/ossl_config.h19
-rw-r--r--ext/openssl/ossl_digest.c456
-rw-r--r--ext/openssl/ossl_digest.h20
-rw-r--r--ext/openssl/ossl_engine.c577
-rw-r--r--ext/openssl/ossl_engine.h19
-rw-r--r--ext/openssl/ossl_hmac.c395
-rw-r--r--ext/openssl/ossl_hmac.h18
-rw-r--r--ext/openssl/ossl_kdf.c319
-rw-r--r--ext/openssl/ossl_kdf.h6
-rw-r--r--ext/openssl/ossl_ns_spki.c405
-rw-r--r--ext/openssl/ossl_ns_spki.h19
-rw-r--r--ext/openssl/ossl_ocsp.c2018
-rw-r--r--ext/openssl/ossl_ocsp.h23
-rw-r--r--ext/openssl/ossl_pkcs12.c257
-rw-r--r--ext/openssl/ossl_pkcs12.h13
-rw-r--r--ext/openssl/ossl_pkcs7.c1114
-rw-r--r--ext/openssl/ossl_pkcs7.h20
-rw-r--r--ext/openssl/ossl_pkey.c507
-rw-r--r--ext/openssl/ossl_pkey.h241
-rw-r--r--ext/openssl/ossl_pkey_dh.c650
-rw-r--r--ext/openssl/ossl_pkey_dsa.c664
-rw-r--r--ext/openssl/ossl_pkey_ec.c1798
-rw-r--r--ext/openssl/ossl_pkey_rsa.c958
-rw-r--r--ext/openssl/ossl_rand.c238
-rw-r--r--ext/openssl/ossl_rand.h18
-rw-r--r--ext/openssl/ossl_ssl.c2950
-rw-r--r--ext/openssl/ossl_ssl.h36
-rw-r--r--ext/openssl/ossl_ssl_session.c332
-rw-r--r--ext/openssl/ossl_version.h15
-rw-r--r--ext/openssl/ossl_x509.c171
-rw-r--r--ext/openssl/ossl_x509.h115
-rw-r--r--ext/openssl/ossl_x509attr.c324
-rw-r--r--ext/openssl/ossl_x509cert.c846
-rw-r--r--ext/openssl/ossl_x509crl.c542
-rw-r--r--ext/openssl/ossl_x509ext.c477
-rw-r--r--ext/openssl/ossl_x509name.c586
-rw-r--r--ext/openssl/ossl_x509req.c441
-rw-r--r--ext/openssl/ossl_x509revoked.c300
-rw-r--r--ext/openssl/ossl_x509store.c885
-rw-r--r--ext/openssl/ruby_missing.h24
-rw-r--r--ext/pathname/depend16
-rw-r--r--ext/pathname/extconf.rb4
-rw-r--r--ext/pathname/lib/pathname.rb593
-rw-r--r--ext/pathname/pathname.c1675
-rw-r--r--ext/psych/.gitignore11
-rw-r--r--ext/psych/depend97
-rw-r--r--ext/psych/extconf.rb39
-rw-r--r--ext/psych/lib/psych.rb546
-rw-r--r--ext/psych/lib/psych/class_loader.rb102
-rw-r--r--ext/psych/lib/psych/coder.rb95
-rw-r--r--ext/psych/lib/psych/core_ext.rb19
-rw-r--r--ext/psych/lib/psych/exception.rb14
-rw-r--r--ext/psych/lib/psych/handler.rb255
-rw-r--r--ext/psych/lib/psych/handlers/document_stream.rb23
-rw-r--r--ext/psych/lib/psych/handlers/recorder.rb40
-rw-r--r--ext/psych/lib/psych/json/ruby_events.rb20
-rw-r--r--ext/psych/lib/psych/json/stream.rb17
-rw-r--r--ext/psych/lib/psych/json/tree_builder.rb13
-rw-r--r--ext/psych/lib/psych/json/yaml_events.rb30
-rw-r--r--ext/psych/lib/psych/nodes.rb78
-rw-r--r--ext/psych/lib/psych/nodes/alias.rb19
-rw-r--r--ext/psych/lib/psych/nodes/document.rb61
-rw-r--r--ext/psych/lib/psych/nodes/mapping.rb57
-rw-r--r--ext/psych/lib/psych/nodes/node.rb68
-rw-r--r--ext/psych/lib/psych/nodes/scalar.rb68
-rw-r--r--ext/psych/lib/psych/nodes/sequence.rb82
-rw-r--r--ext/psych/lib/psych/nodes/stream.rb38
-rw-r--r--ext/psych/lib/psych/omap.rb5
-rw-r--r--ext/psych/lib/psych/parser.rb52
-rw-r--r--ext/psych/lib/psych/scalar_scanner.rb149
-rw-r--r--ext/psych/lib/psych/set.rb5
-rw-r--r--ext/psych/lib/psych/stream.rb38
-rw-r--r--ext/psych/lib/psych/streaming.rb28
-rw-r--r--ext/psych/lib/psych/syntax_error.rb22
-rw-r--r--ext/psych/lib/psych/tree_builder.rb137
-rw-r--r--ext/psych/lib/psych/versions.rb9
-rw-r--r--ext/psych/lib/psych/visitors.rb7
-rw-r--r--ext/psych/lib/psych/visitors/depth_first.rb27
-rw-r--r--ext/psych/lib/psych/visitors/emitter.rb52
-rw-r--r--ext/psych/lib/psych/visitors/json_tree.rb25
-rw-r--r--ext/psych/lib/psych/visitors/to_ruby.rb401
-rw-r--r--ext/psych/lib/psych/visitors/visitor.rb20
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb551
-rw-r--r--ext/psych/lib/psych/y.rb10
-rw-r--r--ext/psych/psych.c34
-rw-r--r--ext/psych/psych.gemspec64
-rw-r--r--ext/psych/psych.h17
-rw-r--r--ext/psych/psych_emitter.c554
-rw-r--r--ext/psych/psych_emitter.h8
-rw-r--r--ext/psych/psych_parser.c591
-rw-r--r--ext/psych/psych_parser.h6
-rw-r--r--ext/psych/psych_to_ruby.c39
-rw-r--r--ext/psych/psych_to_ruby.h8
-rw-r--r--ext/psych/psych_yaml_tree.c24
-rw-r--r--ext/psych/psych_yaml_tree.h8
-rw-r--r--ext/psych/yaml/api.c1392
-rw-r--r--ext/psych/yaml/config.h10
-rw-r--r--ext/psych/yaml/dumper.c394
-rw-r--r--ext/psych/yaml/emitter.c2329
-rw-r--r--ext/psych/yaml/loader.c444
-rw-r--r--ext/psych/yaml/parser.c1370
-rw-r--r--ext/psych/yaml/reader.c469
-rw-r--r--ext/psych/yaml/scanner.c3574
-rw-r--r--ext/psych/yaml/writer.c141
-rw-r--r--ext/psych/yaml/yaml.h1971
-rw-r--r--ext/psych/yaml/yaml_private.h662
-rw-r--r--ext/pty/depend19
-rw-r--r--ext/pty/extconf.rb21
-rw-r--r--ext/pty/lib/expect.rb71
-rw-r--r--ext/pty/pty.c750
-rw-r--r--ext/racc/cparse/README11
-rw-r--r--ext/racc/cparse/cparse.c857
-rw-r--r--ext/racc/cparse/depend12
-rw-r--r--ext/racc/cparse/extconf.rb6
-rw-r--r--ext/rbconfig/sizeof/depend37
-rw-r--r--ext/rbconfig/sizeof/extconf.rb36
-rw-r--r--ext/readline/README10
-rw-r--r--ext/readline/README.ja386
-rw-r--r--ext/readline/depend18
-rw-r--r--ext/readline/extconf.rb112
-rw-r--r--ext/readline/readline.c2101
-rw-r--r--ext/ripper/README30
-rw-r--r--ext/ripper/depend81
-rw-r--r--ext/ripper/eventids2.c306
-rw-r--r--ext/ripper/extconf.rb22
-rw-r--r--ext/ripper/lib/ripper.rb74
-rw-r--r--ext/ripper/lib/ripper/core.rb72
-rw-r--r--ext/ripper/lib/ripper/filter.rb86
-rw-r--r--ext/ripper/lib/ripper/lexer.rb251
-rw-r--r--ext/ripper/lib/ripper/sexp.rb158
-rwxr-xr-xext/ripper/tools/generate-param-macros.rb15
-rwxr-xr-xext/ripper/tools/generate.rb162
-rwxr-xr-xext/ripper/tools/preproc.rb106
-rwxr-xr-xext/ripper/tools/strip.rb12
-rw-r--r--ext/rubyvm/extconf.rb1
-rw-r--r--ext/rubyvm/lib/forwardable/impl.rb19
-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.c1065
-rw-r--r--ext/sdbm/sdbm.gemspec22
-rw-r--r--ext/sdbm/sdbm.h86
-rw-r--r--ext/socket/.document17
-rw-r--r--ext/socket/MANIFEST4
-rw-r--r--ext/socket/addrinfo.h189
-rw-r--r--ext/socket/ancdata.c1734
-rw-r--r--ext/socket/basicsocket.c757
-rw-r--r--ext/socket/constants.c145
-rw-r--r--ext/socket/depend330
-rw-r--r--ext/socket/extconf.rb694
-rw-r--r--ext/socket/getaddrinfo.c675
-rw-r--r--ext/socket/getnameinfo.c243
-rw-r--r--ext/socket/ifaddr.c477
-rw-r--r--ext/socket/init.c806
-rw-r--r--ext/socket/ipsocket.c381
-rw-r--r--ext/socket/lib/socket.rb1356
-rw-r--r--ext/socket/mkconstants.rb805
-rw-r--r--ext/socket/option.c1477
-rw-r--r--ext/socket/raddrinfo.c2627
-rw-r--r--ext/socket/rubysocket.h444
-rw-r--r--ext/socket/socket.c3182
-rw-r--r--ext/socket/sockport.h116
-rw-r--r--ext/socket/sockssocket.c68
-rw-r--r--ext/socket/tcpserver.c146
-rw-r--r--ext/socket/tcpsocket.c91
-rw-r--r--ext/socket/udpsocket.c244
-rw-r--r--ext/socket/unixserver.c128
-rw-r--r--ext/socket/unixsocket.c570
-rw-r--r--ext/stringio/README.md10
-rw-r--r--ext/stringio/depend17
-rw-r--r--ext/stringio/extconf.rb3
-rw-r--r--ext/stringio/stringio.c1730
-rw-r--r--ext/stringio/stringio.gemspec27
-rw-r--r--ext/strscan/depend19
-rw-r--r--ext/strscan/extconf.rb4
-rw-r--r--ext/strscan/strscan.c1490
-rw-r--r--ext/strscan/strscan.gemspec20
-rw-r--r--ext/syslog/depend13
-rw-r--r--ext/syslog/extconf.rb11
-rw-r--r--ext/syslog/lib/syslog/logger.rb209
-rw-r--r--ext/syslog/syslog.c592
-rw-r--r--ext/syslog/syslog.txt124
-rw-r--r--ext/tcltklib/MANIFEST15
-rw-r--r--ext/tcltklib/MANUAL.euc124
-rw-r--r--ext/tcltklib/README.euc133
-rw-r--r--ext/tcltklib/demo/lines0.tcl42
-rw-r--r--ext/tcltklib/demo/lines1.rb54
-rw-r--r--ext/tcltklib/demo/lines2.rb50
-rw-r--r--ext/tcltklib/depend1
-rw-r--r--ext/tcltklib/extconf.rb85
-rw-r--r--ext/tcltklib/lib/tcltk.rb388
-rw-r--r--ext/tcltklib/sample/batsu.gifbin538 -> 0 bytes-rw-r--r--ext/tcltklib/sample/maru.gifbin481 -> 0 bytes-rw-r--r--ext/tcltklib/sample/sample0.rb39
-rw-r--r--ext/tcltklib/sample/sample1.rb634
-rw-r--r--ext/tcltklib/sample/sample2.rb449
-rw-r--r--ext/tcltklib/tcltklib.c441
-rw-r--r--ext/tkutil/MANIFEST3
-rw-r--r--ext/tkutil/depend1
-rw-r--r--ext/tkutil/tkutil.c45
-rw-r--r--ext/win32/extconf.rb4
-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.rb913
-rw-r--r--ext/win32/lib/win32/resolv.rb149
-rw-r--r--ext/win32/lib/win32/resolv9x.rb253
-rw-r--r--ext/win32/lib/win32/sspi.rb331
-rw-r--r--ext/win32/resolv/extconf.rb3
-rw-r--r--ext/win32/resolv/resolv.c65
-rw-r--r--ext/win32ole/depend12
-rw-r--r--ext/win32ole/extconf.rb45
-rw-r--r--ext/win32ole/lib/win32ole.rb33
-rw-r--r--ext/win32ole/lib/win32ole/property.rb17
-rw-r--r--ext/win32ole/sample/excel1.rb37
-rw-r--r--ext/win32ole/sample/excel2.rb31
-rw-r--r--ext/win32ole/sample/excel3.rb21
-rw-r--r--ext/win32ole/sample/ie.rb12
-rw-r--r--ext/win32ole/sample/ieconst.rb33
-rw-r--r--ext/win32ole/sample/ienavi.rb41
-rw-r--r--ext/win32ole/sample/ienavi2.rb41
-rw-r--r--ext/win32ole/sample/oledirs.rb24
-rw-r--r--ext/win32ole/sample/olegen.rb348
-rw-r--r--ext/win32ole/sample/xml.rb7307
-rw-r--r--ext/win32ole/win32ole.c4151
-rw-r--r--ext/win32ole/win32ole.h155
-rw-r--r--ext/win32ole/win32ole_error.c84
-rw-r--r--ext/win32ole/win32ole_error.h9
-rw-r--r--ext/win32ole/win32ole_event.c1280
-rw-r--r--ext/win32ole/win32ole_event.h6
-rw-r--r--ext/win32ole/win32ole_method.c950
-rw-r--r--ext/win32ole/win32ole_method.h16
-rw-r--r--ext/win32ole/win32ole_param.c438
-rw-r--r--ext/win32ole/win32ole_param.h8
-rw-r--r--ext/win32ole/win32ole_record.c604
-rw-r--r--ext/win32ole/win32ole_record.h10
-rw-r--r--ext/win32ole/win32ole_type.c915
-rw-r--r--ext/win32ole/win32ole_type.h8
-rw-r--r--ext/win32ole/win32ole_typelib.c844
-rw-r--r--ext/win32ole/win32ole_typelib.h11
-rw-r--r--ext/win32ole/win32ole_variable.c380
-rw-r--r--ext/win32ole/win32ole_variable.h8
-rw-r--r--ext/win32ole/win32ole_variant.c732
-rw-r--r--ext/win32ole/win32ole_variant.h9
-rw-r--r--ext/win32ole/win32ole_variant_m.c149
-rw-r--r--ext/win32ole/win32ole_variant_m.h7
-rw-r--r--ext/zlib/depend18
-rw-r--r--ext/zlib/extconf.rb132
-rw-r--r--ext/zlib/zlib.c4848
-rw-r--r--ext/zlib/zlib.gemspec25
-rw-r--r--file.c6616
-rw-r--r--fnmatch.c243
-rw-r--r--fnmatch.h36
-rw-r--r--gc.c10088
-rw-r--r--gc.h116
-rw-r--r--gem_prelude.rb8
-rw-r--r--gems/bundled_gems7
-rw-r--r--glob.c591
-rw-r--r--golf_prelude.rb123
-rw-r--r--goruby.c66
-rw-r--r--hash.c4907
-rw-r--r--ia64.s42
-rw-r--r--id_table.c303
-rw-r--r--id_table.h31
-rw-r--r--include/ruby.h35
-rw-r--r--include/ruby/backward.h72
-rw-r--r--include/ruby/backward/classext.h18
-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.h111
-rw-r--r--include/ruby/defines.h388
-rw-r--r--include/ruby/encoding.h423
-rw-r--r--include/ruby/intern.h960
-rw-r--r--include/ruby/io.h177
-rw-r--r--include/ruby/missing.h268
-rw-r--r--include/ruby/onigmo.h935
-rw-r--r--include/ruby/oniguruma.h8
-rw-r--r--include/ruby/re.h72
-rw-r--r--include/ruby/regex.h46
-rw-r--r--include/ruby/ruby.h2561
-rw-r--r--include/ruby/st.h155
-rw-r--r--include/ruby/subst.h19
-rw-r--r--include/ruby/thread.h45
-rw-r--r--include/ruby/thread_native.h56
-rw-r--r--include/ruby/util.h89
-rw-r--r--include/ruby/version.h74
-rw-r--r--include/ruby/vm.h64
-rw-r--r--include/ruby/win32.h824
-rw-r--r--inits.c120
-rw-r--r--insns.def1699
-rw-r--r--install-sh238
-rw-r--r--instruby.rb51
-rw-r--r--intern.h304
-rw-r--r--internal.h2036
-rw-r--r--io.c13829
-rw-r--r--iseq.c2754
-rw-r--r--iseq.h308
-rw-r--r--keywords42
-rw-r--r--lex.c119
-rw-r--r--lex.c.blt303
-rw-r--r--lib/.document24
-rw-r--r--lib/English.rb162
-rw-r--r--lib/Env.rb31
-rw-r--r--lib/README61
-rw-r--r--lib/abbrev.rb132
-rw-r--r--lib/base64.rb126
-rw-r--r--lib/benchmark.rb562
-rw-r--r--lib/cgi-lib.rb96
-rw-r--r--lib/cgi.rb296
-rw-r--r--lib/cgi/cookie.rb188
-rw-r--r--lib/cgi/core.rb888
-rw-r--r--lib/cgi/html.rb1035
-rw-r--r--lib/cgi/session.rb534
-rw-r--r--lib/cgi/session/pstore.rb101
-rw-r--r--lib/cgi/util.rb223
-rw-r--r--lib/cmath.gemspec24
-rw-r--r--lib/cmath.rb435
-rw-r--r--lib/complex.rb496
-rw-r--r--lib/csv.gemspec21
-rw-r--r--lib/csv.rb2355
-rw-r--r--lib/date.rb258
-rw-r--r--lib/date2.rb219
-rw-r--r--lib/debug.rb1313
-rw-r--r--lib/delegate.rb460
-rw-r--r--lib/drb.rb3
-rw-r--r--lib/drb/acl.rb239
-rw-r--r--lib/drb/drb.rb1879
-rw-r--r--lib/drb/eq.rb15
-rw-r--r--lib/drb/extserv.rb44
-rw-r--r--lib/drb/extservm.rb93
-rw-r--r--lib/drb/gw.rb161
-rw-r--r--lib/drb/invokemethod.rb35
-rw-r--r--lib/drb/observer.rb26
-rw-r--r--lib/drb/ssl.rb346
-rw-r--r--lib/drb/timeridconv.rb97
-rw-r--r--lib/drb/unix.rb118
-rw-r--r--lib/e2mmap.rb268
-rw-r--r--lib/erb.rb1051
-rw-r--r--lib/eregex.rb36
-rw-r--r--lib/fileutils.gemspec25
-rw-r--r--lib/fileutils.rb1640
-rw-r--r--lib/final.rb41
-rw-r--r--lib/finalize.rb201
-rw-r--r--lib/find.rb103
-rw-r--r--lib/forwardable.rb308
-rw-r--r--lib/forwardable/impl.rb24
-rw-r--r--lib/ftools.rb163
-rw-r--r--lib/ftplib.rb574
-rw-r--r--lib/getoptlong.rb613
-rw-r--r--lib/getopts.rb141
-rw-r--r--lib/importenv.rb32
-rw-r--r--lib/ipaddr.gemspec26
-rw-r--r--lib/ipaddr.rb748
-rw-r--r--lib/irb.rb718
-rw-r--r--lib/irb/cmd/chws.rb34
-rw-r--r--lib/irb/cmd/fork.rb39
-rw-r--r--lib/irb/cmd/help.rb42
-rw-r--r--lib/irb/cmd/load.rb67
-rw-r--r--lib/irb/cmd/nop.rb39
-rw-r--r--lib/irb/cmd/pushws.rb41
-rw-r--r--lib/irb/cmd/subirb.rb43
-rw-r--r--lib/irb/completion.rb228
-rw-r--r--lib/irb/context.rb420
-rw-r--r--lib/irb/ext/change-ws.rb46
-rw-r--r--lib/irb/ext/history.rb119
-rw-r--r--lib/irb/ext/loader.rb129
-rw-r--r--lib/irb/ext/multi-irb.rb265
-rw-r--r--lib/irb/ext/save-history.rb105
-rw-r--r--lib/irb/ext/tracer.rb72
-rw-r--r--lib/irb/ext/use-loader.rb74
-rw-r--r--lib/irb/ext/workspaces.rb67
-rw-r--r--lib/irb/extend-command.rb306
-rw-r--r--lib/irb/frame.rb81
-rw-r--r--lib/irb/help.rb37
-rw-r--r--lib/irb/init.rb302
-rw-r--r--lib/irb/input-method.rb192
-rw-r--r--lib/irb/inspector.rb132
-rw-r--r--lib/irb/lc/.document4
-rw-r--r--lib/irb/lc/error.rb32
-rw-r--r--lib/irb/lc/help-message49
-rw-r--r--lib/irb/lc/ja/encoding_aliases.rb11
-rw-r--r--lib/irb/lc/ja/error.rb31
-rw-r--r--lib/irb/lc/ja/help-message52
-rw-r--r--lib/irb/locale.rb182
-rw-r--r--lib/irb/magic-file.rb38
-rw-r--r--lib/irb/notifier.rb232
-rw-r--r--lib/irb/output-method.rb92
-rw-r--r--lib/irb/ruby-lex.rb1180
-rw-r--r--lib/irb/ruby-token.rb267
-rw-r--r--lib/irb/slex.rb282
-rw-r--r--lib/irb/src_encoding.rb7
-rw-r--r--lib/irb/version.rb16
-rw-r--r--lib/irb/workspace.rb135
-rw-r--r--lib/irb/ws-for-case-2.rb15
-rw-r--r--lib/irb/xmp.rb170
-rw-r--r--lib/jcode.rb208
-rw-r--r--lib/logger.rb855
-rw-r--r--lib/mailread.rb48
-rw-r--r--lib/mathn.rb309
-rw-r--r--lib/matrix.rb2528
-rw-r--r--lib/matrix/eigenvalue_decomposition.rb883
-rw-r--r--lib/matrix/lup_decomposition.rb219
-rw-r--r--lib/mkmf.rb2947
-rw-r--r--lib/monitor.rb555
-rw-r--r--lib/mutex_m.rb266
-rw-r--r--lib/net/ftp.rb1493
-rw-r--r--lib/net/http.rb1646
-rw-r--r--lib/net/http/backward.rb26
-rw-r--r--lib/net/http/exceptions.rb26
-rw-r--r--lib/net/http/generic_request.rb338
-rw-r--r--lib/net/http/header.rb494
-rw-r--r--lib/net/http/proxy_delta.rb17
-rw-r--r--lib/net/http/request.rb21
-rw-r--r--lib/net/http/requests.rb123
-rw-r--r--lib/net/http/response.rb419
-rw-r--r--lib/net/http/responses.rb299
-rw-r--r--lib/net/http/status.rb83
-rw-r--r--lib/net/https.rb23
-rw-r--r--lib/net/imap.rb3725
-rw-r--r--lib/net/pop.rb1022
-rw-r--r--lib/net/protocol.rb442
-rw-r--r--lib/net/smtp.rb1078
-rw-r--r--lib/observer.rb200
-rw-r--r--lib/open-uri.rb820
-rw-r--r--lib/open3.rb712
-rw-r--r--lib/optionparser.rb2
-rw-r--r--lib/optparse.rb2161
-rw-r--r--lib/optparse/ac.rb51
-rw-r--r--lib/optparse/date.rb18
-rw-r--r--lib/optparse/kwargs.rb17
-rw-r--r--lib/optparse/shellwords.rb7
-rw-r--r--lib/optparse/time.rb11
-rw-r--r--lib/optparse/uri.rb7
-rw-r--r--lib/optparse/version.rb71
-rw-r--r--lib/ostruct.rb377
-rw-r--r--lib/parsearg.rb83
-rw-r--r--lib/parsedate.rb71
-rw-r--r--lib/ping.rb58
-rw-r--r--lib/pp.rb559
-rw-r--r--lib/prettyprint.rb556
-rw-r--r--lib/prime.rb467
-rw-r--r--lib/profile.rb62
-rw-r--r--lib/profiler.rb149
-rw-r--r--lib/pstore.rb491
-rw-r--r--lib/racc/parser.rb623
-rw-r--r--lib/racc/rdoc/grammar.en.rdoc219
-rw-r--r--lib/rational.rb366
-rw-r--r--lib/rdoc.rb186
-rw-r--r--lib/rdoc/.document1
-rw-r--r--lib/rdoc/alias.rb112
-rw-r--r--lib/rdoc/anon_class.rb11
-rw-r--r--lib/rdoc/any_method.rb316
-rw-r--r--lib/rdoc/attr.rb176
-rw-r--r--lib/rdoc/class_module.rb802
-rw-r--r--lib/rdoc/code_object.rb421
-rw-r--r--lib/rdoc/code_objects.rb6
-rw-r--r--lib/rdoc/comment.rb239
-rw-r--r--lib/rdoc/constant.rb187
-rw-r--r--lib/rdoc/context.rb1235
-rw-r--r--lib/rdoc/context/section.rb245
-rw-r--r--lib/rdoc/cross_reference.rb184
-rw-r--r--lib/rdoc/encoding.rb130
-rw-r--r--lib/rdoc/erb_partial.rb19
-rw-r--r--lib/rdoc/erbio.rb38
-rw-r--r--lib/rdoc/extend.rb10
-rw-r--r--lib/rdoc/generator.rb51
-rw-r--r--lib/rdoc/generator/darkfish.rb786
-rw-r--r--lib/rdoc/generator/json_index.rb297
-rw-r--r--lib/rdoc/generator/markup.rb170
-rw-r--r--lib/rdoc/generator/pot.rb98
-rw-r--r--lib/rdoc/generator/pot/message_extractor.rb68
-rw-r--r--lib/rdoc/generator/pot/po.rb84
-rw-r--r--lib/rdoc/generator/pot/po_entry.rb141
-rw-r--r--lib/rdoc/generator/ri.rb31
-rw-r--r--lib/rdoc/generator/template/darkfish/.document0
-rw-r--r--lib/rdoc/generator/template/darkfish/_footer.rhtml5
-rw-r--r--lib/rdoc/generator/template/darkfish/_head.rhtml23
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml19
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml9
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml15
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml9
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml15
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml15
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml12
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml11
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml12
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml11
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml14
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml11
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml18
-rw-r--r--lib/rdoc/generator/template/darkfish/class.rhtml172
-rw-r--r--lib/rdoc/generator/template/darkfish/css/fonts.css167
-rw-r--r--lib/rdoc/generator/template/darkfish/css/rdoc.css611
-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttfbin0 -> 94668 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttfbin0 -> 94196 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttfbin0 -> 96184 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttfbin0 -> 95316 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttfbin0 -> 71200 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttfbin0 -> 71692 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/add.pngbin0 -> 733 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/arrow_up.pngbin0 -> 372 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/brick.pngbin0 -> 452 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/brick_link.pngbin0 -> 764 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/bug.pngbin0 -> 774 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/bullet_black.pngbin0 -> 211 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.pngbin0 -> 207 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.pngbin0 -> 209 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/date.pngbin0 -> 626 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/delete.pngbin0 -> 715 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/find.pngbin0 -> 659 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/loadingAnimation.gifbin0 -> 5886 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/macFFBgHack.pngbin0 -> 207 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/package.pngbin0 -> 853 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/page_green.pngbin0 -> 621 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/page_white_text.pngbin0 -> 342 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/page_white_width.pngbin0 -> 309 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/plugin.pngbin0 -> 591 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/ruby.pngbin0 -> 592 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/tag_blue.pngbin0 -> 1880 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/tag_green.pngbin0 -> 613 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/transparent.pngbin0 -> 97 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/wrench.pngbin0 -> 610 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/wrench_orange.pngbin0 -> 584 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/images/zoom.pngbin0 -> 692 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/index.rhtml23
-rw-r--r--lib/rdoc/generator/template/darkfish/js/darkfish.js84
-rw-r--r--lib/rdoc/generator/template/darkfish/js/search.js110
-rw-r--r--lib/rdoc/generator/template/darkfish/page.rhtml18
-rw-r--r--lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml18
-rw-r--r--lib/rdoc/generator/template/darkfish/servlet_root.rhtml63
-rw-r--r--lib/rdoc/generator/template/darkfish/table_of_contents.rhtml58
-rw-r--r--lib/rdoc/generator/template/json_index/.document1
-rw-r--r--lib/rdoc/generator/template/json_index/js/navigation.js106
-rw-r--r--lib/rdoc/generator/template/json_index/js/searcher.js229
-rw-r--r--lib/rdoc/ghost_method.rb7
-rw-r--r--lib/rdoc/i18n.rb10
-rw-r--r--lib/rdoc/i18n/locale.rb102
-rw-r--r--lib/rdoc/i18n/text.rb126
-rw-r--r--lib/rdoc/include.rb10
-rw-r--r--lib/rdoc/known_classes.rb73
-rw-r--r--lib/rdoc/markdown.rb16286
-rw-r--r--lib/rdoc/markdown/entities.rb2132
-rw-r--r--lib/rdoc/markdown/literals.rb416
-rw-r--r--lib/rdoc/markup.rb870
-rw-r--r--lib/rdoc/markup/attr_changer.rb23
-rw-r--r--lib/rdoc/markup/attr_span.rb30
-rw-r--r--lib/rdoc/markup/attribute_manager.rb344
-rw-r--r--lib/rdoc/markup/attributes.rb71
-rw-r--r--lib/rdoc/markup/blank_line.rb28
-rw-r--r--lib/rdoc/markup/block_quote.rb15
-rw-r--r--lib/rdoc/markup/document.rb165
-rw-r--r--lib/rdoc/markup/formatter.rb265
-rw-r--r--lib/rdoc/markup/formatter_test_case.rb764
-rw-r--r--lib/rdoc/markup/hard_break.rb32
-rw-r--r--lib/rdoc/markup/heading.rb79
-rw-r--r--lib/rdoc/markup/include.rb43
-rw-r--r--lib/rdoc/markup/indented_paragraph.rb48
-rw-r--r--lib/rdoc/markup/inline.rb2
-rw-r--r--lib/rdoc/markup/list.rb102
-rw-r--r--lib/rdoc/markup/list_item.rb100
-rw-r--r--lib/rdoc/markup/paragraph.rb29
-rw-r--r--lib/rdoc/markup/parser.rb543
-rw-r--r--lib/rdoc/markup/pre_process.rb295
-rw-r--r--lib/rdoc/markup/raw.rb70
-rw-r--r--lib/rdoc/markup/rule.rb21
-rw-r--r--lib/rdoc/markup/special.rb41
-rw-r--r--lib/rdoc/markup/text_formatter_test_case.rb115
-rw-r--r--lib/rdoc/markup/to_ansi.rb94
-rw-r--r--lib/rdoc/markup/to_bs.rb77
-rw-r--r--lib/rdoc/markup/to_html.rb404
-rw-r--r--lib/rdoc/markup/to_html_crossref.rb161
-rw-r--r--lib/rdoc/markup/to_html_snippet.rb285
-rw-r--r--lib/rdoc/markup/to_joined_paragraph.rb46
-rw-r--r--lib/rdoc/markup/to_label.rb75
-rw-r--r--lib/rdoc/markup/to_markdown.rb192
-rw-r--r--lib/rdoc/markup/to_rdoc.rb334
-rw-r--r--lib/rdoc/markup/to_table_of_contents.rb88
-rw-r--r--lib/rdoc/markup/to_test.rb70
-rw-r--r--lib/rdoc/markup/to_tt_only.rb121
-rw-r--r--lib/rdoc/markup/verbatim.rb84
-rw-r--r--lib/rdoc/meta_method.rb7
-rw-r--r--lib/rdoc/method_attr.rb419
-rw-r--r--lib/rdoc/mixin.rb121
-rw-r--r--lib/rdoc/normal_class.rb93
-rw-r--r--lib/rdoc/normal_module.rb74
-rw-r--r--lib/rdoc/options.rb1227
-rw-r--r--lib/rdoc/parser.rb277
-rw-r--r--lib/rdoc/parser/c.rb1268
-rw-r--r--lib/rdoc/parser/changelog.rb204
-rw-r--r--lib/rdoc/parser/markdown.rb24
-rw-r--r--lib/rdoc/parser/rd.rb23
-rw-r--r--lib/rdoc/parser/ripper_state_lex.rb605
-rw-r--r--lib/rdoc/parser/ruby.rb2232
-rw-r--r--lib/rdoc/parser/ruby_tools.rb159
-rw-r--r--lib/rdoc/parser/simple.rb61
-rw-r--r--lib/rdoc/parser/text.rb12
-rw-r--r--lib/rdoc/rd.rb100
-rw-r--r--lib/rdoc/rd/block_parser.rb1055
-rw-r--r--lib/rdoc/rd/inline.rb72
-rw-r--r--lib/rdoc/rd/inline_parser.rb1207
-rw-r--r--lib/rdoc/rdoc.gemspec63
-rw-r--r--lib/rdoc/rdoc.rb571
-rw-r--r--lib/rdoc/require.rb52
-rw-r--r--lib/rdoc/ri.rb21
-rw-r--r--lib/rdoc/ri/driver.rb1547
-rw-r--r--lib/rdoc/ri/formatter.rb6
-rw-r--r--lib/rdoc/ri/paths.rb185
-rw-r--r--lib/rdoc/ri/store.rb7
-rw-r--r--lib/rdoc/ri/task.rb71
-rw-r--r--lib/rdoc/rubygems_hook.rb246
-rw-r--r--lib/rdoc/servlet.rb442
-rw-r--r--lib/rdoc/single_class.rb26
-rw-r--r--lib/rdoc/stats.rb462
-rw-r--r--lib/rdoc/stats/normal.rb58
-rw-r--r--lib/rdoc/stats/quiet.rb60
-rw-r--r--lib/rdoc/stats/verbose.rb46
-rw-r--r--lib/rdoc/store.rb968
-rw-r--r--lib/rdoc/task.rb329
-rw-r--r--lib/rdoc/test_case.rb203
-rw-r--r--lib/rdoc/text.rb298
-rw-r--r--lib/rdoc/token_stream.rb114
-rw-r--r--lib/rdoc/tom_doc.rb258
-rw-r--r--lib/rdoc/top_level.rb283
-rw-r--r--lib/readbytes.rb36
-rw-r--r--lib/resolv-replace.rb76
-rw-r--r--lib/resolv.rb2892
-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.rb171
-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.rb327
-rw-r--r--lib/rinda/ring.rb484
-rw-r--r--lib/rinda/tuplespace.rb641
-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.rb1346
-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.rb1405
-rw-r--r--lib/rubygems/available_set.rb165
-rw-r--r--lib/rubygems/basic_specification.rb332
-rw-r--r--lib/rubygems/bundler_version_finder.rb96
-rw-r--r--lib/rubygems/command.rb602
-rw-r--r--lib/rubygems/command_manager.rb223
-rw-r--r--lib/rubygems/commands/build_command.rb65
-rw-r--r--lib/rubygems/commands/cert_command.rb302
-rw-r--r--lib/rubygems/commands/check_command.rb94
-rw-r--r--lib/rubygems/commands/cleanup_command.rb178
-rw-r--r--lib/rubygems/commands/contents_command.rb191
-rw-r--r--lib/rubygems/commands/dependency_command.rb218
-rw-r--r--lib/rubygems/commands/environment_command.rb160
-rw-r--r--lib/rubygems/commands/fetch_command.rb78
-rw-r--r--lib/rubygems/commands/generate_index_command.rb85
-rw-r--r--lib/rubygems/commands/help_command.rb375
-rw-r--r--lib/rubygems/commands/install_command.rb303
-rw-r--r--lib/rubygems/commands/list_command.rb41
-rw-r--r--lib/rubygems/commands/lock_command.rb111
-rw-r--r--lib/rubygems/commands/mirror_command.rb26
-rw-r--r--lib/rubygems/commands/open_command.rb81
-rw-r--r--lib/rubygems/commands/outdated_command.rb33
-rw-r--r--lib/rubygems/commands/owner_command.rb104
-rw-r--r--lib/rubygems/commands/pristine_command.rb179
-rw-r--r--lib/rubygems/commands/push_command.rb104
-rw-r--r--lib/rubygems/commands/query_command.rb359
-rw-r--r--lib/rubygems/commands/rdoc_command.rb97
-rw-r--r--lib/rubygems/commands/search_command.rb41
-rw-r--r--lib/rubygems/commands/server_command.rb87
-rw-r--r--lib/rubygems/commands/setup_command.rb589
-rw-r--r--lib/rubygems/commands/signin_command.rb33
-rw-r--r--lib/rubygems/commands/signout_command.rb33
-rw-r--r--lib/rubygems/commands/sources_command.rb211
-rw-r--r--lib/rubygems/commands/specification_command.rb146
-rw-r--r--lib/rubygems/commands/stale_command.rb39
-rw-r--r--lib/rubygems/commands/uninstall_command.rb166
-rw-r--r--lib/rubygems/commands/unpack_command.rb195
-rw-r--r--lib/rubygems/commands/update_command.rb279
-rw-r--r--lib/rubygems/commands/which_command.rb91
-rw-r--r--lib/rubygems/commands/yank_command.rb96
-rw-r--r--lib/rubygems/compatibility.rb60
-rw-r--r--lib/rubygems/config_file.rb487
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb74
-rwxr-xr-xlib/rubygems/core_ext/kernel_require.rb142
-rw-r--r--lib/rubygems/defaults.rb196
-rw-r--r--lib/rubygems/dependency.rb335
-rw-r--r--lib/rubygems/dependency_installer.rb495
-rw-r--r--lib/rubygems/dependency_list.rb244
-rw-r--r--lib/rubygems/deprecate.rb71
-rw-r--r--lib/rubygems/doctor.rb132
-rw-r--r--lib/rubygems/errors.rb185
-rw-r--r--lib/rubygems/exceptions.rb276
-rw-r--r--lib/rubygems/ext.rb19
-rw-r--r--lib/rubygems/ext/build_error.rb7
-rw-r--r--lib/rubygems/ext/builder.rb221
-rw-r--r--lib/rubygems/ext/cmake_builder.rb17
-rw-r--r--lib/rubygems/ext/configure_builder.rb24
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb94
-rw-r--r--lib/rubygems/ext/rake_builder.rb37
-rw-r--r--lib/rubygems/gem_runner.rb86
-rw-r--r--lib/rubygems/gemcutter_utilities.rb171
-rw-r--r--lib/rubygems/indexer.rb435
-rw-r--r--lib/rubygems/install_default_message.rb13
-rw-r--r--lib/rubygems/install_message.rb13
-rw-r--r--lib/rubygems/install_update_options.rb216
-rw-r--r--lib/rubygems/installer.rb905
-rw-r--r--lib/rubygems/installer_test_case.rb199
-rw-r--r--lib/rubygems/local_remote_options.rb149
-rw-r--r--lib/rubygems/mock_gem_ui.rb89
-rw-r--r--lib/rubygems/name_tuple.rb124
-rw-r--r--lib/rubygems/package.rb668
-rw-r--r--lib/rubygems/package/digest_io.rb65
-rw-r--r--lib/rubygems/package/file_source.rb34
-rw-r--r--lib/rubygems/package/io_source.rb46
-rw-r--r--lib/rubygems/package/old.rb178
-rw-r--r--lib/rubygems/package/source.rb4
-rw-r--r--lib/rubygems/package/tar_header.rb234
-rw-r--r--lib/rubygems/package/tar_reader.rb123
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb154
-rw-r--r--lib/rubygems/package/tar_test_case.rb147
-rw-r--r--lib/rubygems/package/tar_writer.rb341
-rw-r--r--lib/rubygems/package_task.rb129
-rw-r--r--lib/rubygems/path_support.rb80
-rw-r--r--lib/rubygems/platform.rb206
-rw-r--r--lib/rubygems/psych_additions.rb10
-rw-r--r--lib/rubygems/psych_tree.rb32
-rw-r--r--lib/rubygems/rdoc.rb335
-rw-r--r--lib/rubygems/remote_fetcher.rb419
-rw-r--r--lib/rubygems/request.rb294
-rw-r--r--lib/rubygems/request/connection_pools.rb88
-rw-r--r--lib/rubygems/request/http_pool.rb48
-rw-r--r--lib/rubygems/request/https_pool.rb11
-rw-r--r--lib/rubygems/request_set.rb441
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb849
-rw-r--r--lib/rubygems/request_set/lockfile.rb238
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb354
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb112
-rw-r--r--lib/rubygems/requirement.rb289
-rw-r--r--lib/rubygems/resolver.rb348
-rw-r--r--lib/rubygems/resolver/activation_request.rb186
-rw-r--r--lib/rubygems/resolver/api_set.rb126
-rw-r--r--lib/rubygems/resolver/api_specification.rb86
-rw-r--r--lib/rubygems/resolver/best_set.rb79
-rw-r--r--lib/rubygems/resolver/composed_set.rb67
-rw-r--r--lib/rubygems/resolver/conflict.rb160
-rw-r--r--lib/rubygems/resolver/current_set.rb14
-rw-r--r--lib/rubygems/resolver/dependency_request.rb120
-rw-r--r--lib/rubygems/resolver/git_set.rb123
-rw-r--r--lib/rubygems/resolver/git_specification.rb59
-rw-r--r--lib/rubygems/resolver/index_set.rb81
-rw-r--r--lib/rubygems/resolver/index_specification.rb70
-rw-r--r--lib/rubygems/resolver/installed_specification.rb59
-rw-r--r--lib/rubygems/resolver/installer_set.rb227
-rw-r--r--lib/rubygems/resolver/local_specification.rb42
-rw-r--r--lib/rubygems/resolver/lock_set.rb83
-rw-r--r--lib/rubygems/resolver/lock_specification.rb88
-rw-r--r--lib/rubygems/resolver/molinillo.rb2
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo.rb10
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb50
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb80
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb222
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb35
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb65
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb61
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb62
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb60
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb125
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb45
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb35
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb125
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb75
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb5
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb100
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb65
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb494
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb45
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/state.rb54
-rw-r--r--lib/rubygems/resolver/requirement_list.rb82
-rw-r--r--lib/rubygems/resolver/set.rb57
-rw-r--r--lib/rubygems/resolver/source_set.rb48
-rw-r--r--lib/rubygems/resolver/spec_specification.rb57
-rw-r--r--lib/rubygems/resolver/specification.rb111
-rw-r--r--lib/rubygems/resolver/stats.rb45
-rw-r--r--lib/rubygems/resolver/vendor_set.rb88
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb25
-rw-r--r--lib/rubygems/safe_yaml.rb51
-rw-r--r--lib/rubygems/security.rb603
-rw-r--r--lib/rubygems/security/policies.rb116
-rw-r--r--lib/rubygems/security/policy.rb295
-rw-r--r--lib/rubygems/security/signer.rb157
-rw-r--r--lib/rubygems/security/trust_dir.rb119
-rw-r--r--lib/rubygems/security_option.rb43
-rw-r--r--lib/rubygems/server.rb878
-rw-r--r--lib/rubygems/source.rb238
-rw-r--r--lib/rubygems/source/git.rb242
-rw-r--r--lib/rubygems/source/installed.rb41
-rw-r--r--lib/rubygems/source/local.rb133
-rw-r--r--lib/rubygems/source/lock.rb52
-rw-r--r--lib/rubygems/source/specific_file.rb73
-rw-r--r--lib/rubygems/source/vendor.rb28
-rw-r--r--lib/rubygems/source_list.rb150
-rw-r--r--lib/rubygems/source_local.rb8
-rw-r--r--lib/rubygems/source_specific_file.rb6
-rw-r--r--lib/rubygems/spec_fetcher.rb274
-rw-r--r--lib/rubygems/specification.rb3090
-rw-r--r--lib/rubygems/ssl_certs/.document1
-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/stub_specification.rb218
-rw-r--r--lib/rubygems/syck_hack.rb77
-rw-r--r--lib/rubygems/test_case.rb1538
-rw-r--r--lib/rubygems/test_utilities.rb384
-rw-r--r--lib/rubygems/text.rb86
-rw-r--r--lib/rubygems/uninstaller.rb346
-rw-r--r--lib/rubygems/uri_formatter.rb50
-rw-r--r--lib/rubygems/user_interaction.rb705
-rw-r--r--lib/rubygems/util.rb125
-rw-r--r--lib/rubygems/util/licenses.rb380
-rw-r--r--lib/rubygems/util/list.rb37
-rw-r--r--lib/rubygems/validator.rb166
-rw-r--r--lib/rubygems/version.rb392
-rw-r--r--lib/rubygems/version_option.rb77
-rw-r--r--lib/scanf.gemspec25
-rw-r--r--lib/scanf.rb776
-rw-r--r--lib/securerandom.rb297
-rw-r--r--lib/set.rb908
-rw-r--r--lib/shell.rb904
-rw-r--r--lib/shell/builtin-command.rb147
-rw-r--r--lib/shell/command-processor.rb671
-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.rb255
-rw-r--r--lib/singleton.rb195
-rw-r--r--lib/sync.rb530
-rw-r--r--lib/telnet.rb439
-rw-r--r--lib/tempfile.rb397
-rw-r--r--lib/thread.rb201
-rw-r--r--lib/thwait.rb173
-rw-r--r--lib/time.rb688
-rw-r--r--lib/timeout.rb146
-rw-r--r--lib/tk.rb2499
-rw-r--r--lib/tkafter.rb296
-rw-r--r--lib/tkbgerror.rb17
-rw-r--r--lib/tkcanvas.rb829
-rw-r--r--lib/tkclass.rb38
-rw-r--r--lib/tkdialog.rb141
-rw-r--r--lib/tkentry.rb73
-rw-r--r--lib/tkfont.rb939
-rw-r--r--lib/tkmenubar.rb137
-rw-r--r--lib/tkmngfocus.rb27
-rw-r--r--lib/tkpalette.rb48
-rw-r--r--lib/tkscrollbox.rb27
-rw-r--r--lib/tktext.rb797
-rw-r--r--lib/tkvirtevent.rb66
-rw-r--r--lib/tmpdir.rb145
-rw-r--r--lib/tracer.rb290
-rw-r--r--lib/tsort.rb452
-rw-r--r--lib/un.rb391
-rw-r--r--lib/unicode_normalize/normalize.rb175
-rw-r--r--lib/unicode_normalize/tables.rb1170
-rw-r--r--lib/uri.rb112
-rw-r--r--lib/uri/common.rb750
-rw-r--r--lib/uri/ftp.rb267
-rw-r--r--lib/uri/generic.rb1563
-rw-r--r--lib/uri/http.rb88
-rw-r--r--lib/uri/https.rb23
-rw-r--r--lib/uri/ldap.rb261
-rw-r--r--lib/uri/ldaps.rb21
-rw-r--r--lib/uri/mailto.rb294
-rw-r--r--lib/uri/rfc2396_parser.rb544
-rw-r--r--lib/uri/rfc3986_parser.rb125
-rw-r--r--lib/weakref.rb95
-rw-r--r--lib/webrick.rb227
-rw-r--r--lib/webrick/.document6
-rw-r--r--lib/webrick/accesslog.rb159
-rw-r--r--lib/webrick/cgi.rb313
-rw-r--r--lib/webrick/compat.rb36
-rw-r--r--lib/webrick/config.rb158
-rw-r--r--lib/webrick/cookie.rb172
-rw-r--r--lib/webrick/htmlutils.rb30
-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.rb395
-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/httpauth/userdb.rb53
-rw-r--r--lib/webrick/httpproxy.rb338
-rw-r--r--lib/webrick/httprequest.rb598
-rw-r--r--lib/webrick/httpresponse.rb517
-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.rb120
-rw-r--r--lib/webrick/httpservlet/erbhandler.rb88
-rw-r--r--lib/webrick/httpservlet/filehandler.rb541
-rw-r--r--lib/webrick/httpservlet/prochandler.rb47
-rw-r--r--lib/webrick/httpstatus.rb194
-rw-r--r--lib/webrick/httputils.rb513
-rw-r--r--lib/webrick/httpversion.rb76
-rw-r--r--lib/webrick/log.rb156
-rw-r--r--lib/webrick/server.rb378
-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.gemspec29
-rw-r--r--lib/yaml.rb60
-rw-r--r--lib/yaml/dbm.rb280
-rw-r--r--lib/yaml/store.rb86
-rw-r--r--load.c1208
-rw-r--r--loadpath.c92
-rw-r--r--localeinit.c136
-rw-r--r--main.c45
-rw-r--r--man/erb.1161
-rw-r--r--man/goruby.139
-rw-r--r--man/irb.1172
-rw-r--r--man/ri.1247
-rw-r--r--man/ruby.1661
-rw-r--r--marshal.c2305
-rw-r--r--math.c1021
-rw-r--r--method.h218
-rw-r--r--miniinit.c49
-rw-r--r--misc/README12
-rw-r--r--misc/inf-ruby.el418
-rwxr-xr-xmisc/lldb_cruby.py177
-rw-r--r--misc/rb_optparse.bash20
-rwxr-xr-xmisc/rb_optparse.zsh38
-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.el81
-rw-r--r--misc/rubydb2x.el (renamed from sample/rubydb2x.el)0
-rw-r--r--misc/rubydb3x.el115
-rw-r--r--misc/test_lldb_cruby.rb36
-rw-r--r--missing/acosh.c93
-rw-r--r--missing/alloca.c18
-rw-r--r--missing/cbrt.c11
-rw-r--r--missing/close.c72
-rw-r--r--missing/crt_externs.h8
-rw-r--r--missing/crypt.c1159
-rw-r--r--missing/crypt.h248
-rw-r--r--missing/des_tables.c1616
-rw-r--r--missing/dir.h63
-rw-r--r--missing/dup2.c68
-rw-r--r--missing/erf.c89
-rw-r--r--missing/explicit_bzero.c88
-rw-r--r--missing/ffs.c49
-rw-r--r--missing/file.h33
-rw-r--r--missing/fileblocks.c1
-rw-r--r--missing/finite.c9
-rw-r--r--missing/flock.c84
-rw-r--r--missing/hypot.c17
-rw-r--r--missing/isinf.c69
-rw-r--r--missing/isnan.c32
-rw-r--r--missing/langinfo.c148
-rw-r--r--missing/lgamma_r.c80
-rw-r--r--missing/memcmp.c15
-rw-r--r--missing/memmove.c38
-rw-r--r--missing/mkdir.c104
-rw-r--r--missing/nextafter.c77
-rw-r--r--missing/nt.c2194
-rw-r--r--missing/nt.h358
-rw-r--r--missing/setenv.c149
-rw-r--r--missing/setproctitle.c176
-rw-r--r--missing/signbit.c19
-rw-r--r--missing/stdbool.h20
-rw-r--r--missing/strcasecmp.c13
-rw-r--r--missing/strchr.c57
-rw-r--r--missing/strdup.c25
-rw-r--r--missing/strerror.c13
-rw-r--r--missing/strftime.c889
-rw-r--r--missing/strlcat.c56
-rw-r--r--missing/strlcpy.c51
-rw-r--r--missing/strstr.c82
-rw-r--r--missing/strtol.c84
-rw-r--r--missing/strtoul.c184
-rw-r--r--missing/tgamma.c97
-rw-r--r--missing/vsnprintf.c1150
-rw-r--r--missing/x68.c36
-rw-r--r--missing/x86_64-chkstk.s10
-rw-r--r--mkconfig.rb77
-rw-r--r--node.c1186
-rw-r--r--node.h530
-rw-r--r--numeric.c5897
-rw-r--r--object.c4395
-rw-r--r--pack.c2090
-rw-r--r--parse.y13460
-rw-r--r--prelude.rb155
-rw-r--r--probes.d234
-rw-r--r--probes_helper.h43
-rw-r--r--proc.c3228
-rw-r--r--process.c8370
-rw-r--r--random.c1683
-rw-r--r--range.c1361
-rw-r--r--rational.c2794
-rw-r--r--re.c4226
-rw-r--r--re.h37
-rw-r--r--regcomp.c6740
-rw-r--r--regenc.c1012
-rw-r--r--regenc.h254
-rw-r--r--regerror.c386
-rw-r--r--regex.c4321
-rw-r--r--regex.h286
-rw-r--r--regexec.c4620
-rw-r--r--regint.h938
-rw-r--r--regparse.c7052
-rw-r--r--regparse.h370
-rw-r--r--regsyntax.c388
-rw-r--r--ruby-runner.c77
-rw-r--r--ruby.1329
-rw-r--r--ruby.c2530
-rw-r--r--ruby.h550
-rw-r--r--ruby_assert.h54
-rw-r--r--ruby_atomic.h233
-rw-r--r--rubyio.h58
-rw-r--r--rubysig.h54
-rw-r--r--rubystub.c60
-rw-r--r--rubytest.rb16
-rw-r--r--safe.c139
-rw-r--r--sample/README27
-rw-r--r--sample/benchmark.rb19
-rw-r--r--sample/biorhythm.rb154
-rw-r--r--sample/cal.rb262
-rw-r--r--sample/cbreak.rb12
-rw-r--r--sample/cgi-session-pstore.rb11
-rw-r--r--sample/clnt.rb12
-rw-r--r--sample/coverage.rb62
-rw-r--r--sample/dbmtest.rb14
-rw-r--r--sample/delegate.rb31
-rw-r--r--sample/dir.rb6
-rw-r--r--sample/drb/README.ja.rdoc59
-rw-r--r--sample/drb/README.rdoc56
-rw-r--r--sample/drb/acl.rb15
-rw-r--r--sample/drb/darray.rb12
-rw-r--r--sample/drb/darrayc.rb47
-rw-r--r--sample/drb/dbiff.rb51
-rw-r--r--sample/drb/dcdbiff.rb43
-rw-r--r--sample/drb/dchatc.rb41
-rw-r--r--sample/drb/dchats.rb69
-rw-r--r--sample/drb/dhasen.rb41
-rw-r--r--sample/drb/dhasenc.rb14
-rw-r--r--sample/drb/dlogc.rb16
-rw-r--r--sample/drb/dlogd.rb38
-rw-r--r--sample/drb/dqin.rb13
-rw-r--r--sample/drb/dqlib.rb14
-rw-r--r--sample/drb/dqout.rb14
-rw-r--r--sample/drb/dqueue.rb11
-rw-r--r--sample/drb/drbc.rb45
-rw-r--r--sample/drb/drbch.rb48
-rw-r--r--sample/drb/drbm.rb60
-rw-r--r--sample/drb/drbmc.rb22
-rw-r--r--sample/drb/drbs-acl.rb51
-rw-r--r--sample/drb/drbs.rb64
-rw-r--r--sample/drb/drbssl_c.rb19
-rw-r--r--sample/drb/drbssl_s.rb31
-rw-r--r--sample/drb/extserv_test.rb80
-rw-r--r--sample/drb/gw_ct.rb29
-rw-r--r--sample/drb/gw_cu.rb28
-rw-r--r--sample/drb/gw_s.rb10
-rw-r--r--sample/drb/holderc.rb22
-rw-r--r--sample/drb/holders.rb63
-rw-r--r--sample/drb/http0.rb77
-rw-r--r--sample/drb/http0serv.rb118
-rw-r--r--sample/drb/name.rb116
-rw-r--r--sample/drb/namec.rb36
-rw-r--r--sample/drb/old_tuplespace.rb212
-rw-r--r--sample/drb/rinda_ts.rb7
-rw-r--r--sample/drb/rindac.rb17
-rw-r--r--sample/drb/rindas.rb18
-rw-r--r--sample/drb/ring_echo.rb29
-rw-r--r--sample/drb/ring_inspect.rb30
-rw-r--r--sample/drb/ring_place.rb25
-rw-r--r--sample/drb/simpletuple.rb89
-rw-r--r--sample/drb/speedc.rb21
-rw-r--r--sample/drb/speeds.rb31
-rw-r--r--sample/dualstack-fetch.rb48
-rw-r--r--sample/dualstack-httpd.rb54
-rw-r--r--sample/eval.rb21
-rw-r--r--sample/export.rb2
-rw-r--r--sample/exyacc.rb34
-rw-r--r--sample/fact.rb5
-rw-r--r--sample/fib.awk8
-rw-r--r--sample/fib.pl19
-rw-r--r--sample/fib.scm6
-rw-r--r--sample/freq.rb15
-rw-r--r--sample/from.rb160
-rw-r--r--sample/fullpath.rb16
-rw-r--r--sample/getopts.test36
-rw-r--r--sample/goodfriday.rb48
-rw-r--r--sample/inf-ruby.el310
-rw-r--r--sample/iseq_loader.rb243
-rw-r--r--sample/list.rb17
-rw-r--r--sample/list2.rb2
-rw-r--r--sample/list3.rb2
-rw-r--r--sample/logger/app.rb46
-rw-r--r--sample/logger/log.rb27
-rw-r--r--sample/logger/shifting.rb26
-rwxr-xr-xsample/mine.rb176
-rw-r--r--sample/mkproto.rb30
-rw-r--r--sample/mpart.rb2
-rw-r--r--sample/mrshtest.rb14
-rw-r--r--sample/net-imap.rb167
-rw-r--r--sample/observ.rb9
-rw-r--r--sample/occur.pl8
-rw-r--r--sample/occur.rb14
-rw-r--r--sample/occur2.rb13
-rw-r--r--sample/open3.rb12
-rw-r--r--sample/openssl/c_rehash.rb174
-rw-r--r--sample/openssl/cert2text.rb23
-rw-r--r--sample/openssl/certstore.rb161
-rw-r--r--sample/openssl/cipher.rb54
-rw-r--r--sample/openssl/crlstore.rb122
-rw-r--r--sample/openssl/echo_cli.rb44
-rw-r--r--sample/openssl/echo_svr.rb65
-rw-r--r--sample/openssl/gen_csr.rb51
-rw-r--r--sample/openssl/smime_read.rb23
-rw-r--r--sample/openssl/smime_write.rb23
-rw-r--r--sample/openssl/wget.rb34
-rwxr-xr-xsample/optparse/opttest.rb125
-rwxr-xr-xsample/optparse/subcommand.rb19
-rw-r--r--sample/philos.rb9
-rw-r--r--sample/pi.rb2
-rw-r--r--sample/pstore.rb19
-rw-r--r--sample/pty/expect_sample.rb58
-rw-r--r--sample/pty/script.rb37
-rw-r--r--sample/pty/shl.rb93
-rw-r--r--sample/rbc.rb1015
-rw-r--r--sample/rcs.awk54
-rw-r--r--sample/rcs.rb30
-rw-r--r--sample/rdoc/markup/rdoc2latex.rb15
-rw-r--r--sample/rdoc/markup/sample.rb40
-rw-r--r--sample/regx.rb23
-rw-r--r--sample/rinda-ring.rb22
-rw-r--r--sample/ripper/ruby2html.rb112
-rw-r--r--sample/ripper/strip-comment.rb19
-rwxr-xr-xsample/rss/blend.rb79
-rwxr-xr-xsample/rss/convert.rb69
-rwxr-xr-xsample/rss/list_description.rb91
-rwxr-xr-xsample/rss/re_read.rb64
-rwxr-xr-xsample/rss/rss_recent.rb85
-rw-r--r--sample/ruby-mode.el677
-rw-r--r--sample/rubydb3x.el104
-rw-r--r--sample/sieve.rb22
-rw-r--r--sample/simple-bench.rb140
-rw-r--r--sample/svr.rb14
-rw-r--r--sample/tempfile.rb8
-rwxr-xr-x[-rw-r--r--]sample/test.rb1066
-rw-r--r--sample/testunit/adder.rb13
-rw-r--r--sample/testunit/subtracter.rb12
-rw-r--r--sample/testunit/tc_adder.rb18
-rw-r--r--sample/testunit/tc_subtracter.rb18
-rw-r--r--sample/testunit/ts_examples.rb7
-rw-r--r--sample/time.rb16
-rw-r--r--sample/timeout.rb42
-rw-r--r--sample/tkbiff.rb149
-rw-r--r--sample/tkbrowse.rb79
-rw-r--r--sample/tkdialog.rb62
-rw-r--r--sample/tkfrom.rb132
-rw-r--r--sample/tkhello.rb10
-rw-r--r--sample/tkline.rb45
-rw-r--r--sample/tktimer.rb50
-rw-r--r--sample/trick2013/README.md15
-rw-r--r--sample/trick2013/kinaba/authors.markdown3
-rw-r--r--sample/trick2013/kinaba/entry.rb1
-rw-r--r--sample/trick2013/kinaba/remarks.markdown37
-rw-r--r--sample/trick2013/mame/authors.markdown3
-rw-r--r--sample/trick2013/mame/entry.rb97
-rw-r--r--sample/trick2013/mame/music-box.mp4bin0 -> 580724 bytes-rw-r--r--sample/trick2013/mame/remarks.markdown47
-rw-r--r--sample/trick2013/shinh/authors.markdown2
-rw-r--r--sample/trick2013/shinh/entry.rb10
-rw-r--r--sample/trick2013/shinh/remarks.markdown4
-rw-r--r--sample/trick2013/yhara/authors.markdown3
-rw-r--r--sample/trick2013/yhara/entry.rb28
-rw-r--r--sample/trick2013/yhara/remarks.en.markdown23
-rw-r--r--sample/trick2013/yhara/remarks.markdown24
-rw-r--r--sample/trick2015/README.md16
-rw-r--r--sample/trick2015/eregon/authors.markdown3
-rw-r--r--sample/trick2015/eregon/entry.rb16
-rw-r--r--sample/trick2015/eregon/remarks.markdown70
-rw-r--r--sample/trick2015/kinaba/authors.markdown4
-rw-r--r--sample/trick2015/kinaba/entry.rb150
-rw-r--r--sample/trick2015/kinaba/remarks.markdown85
-rw-r--r--sample/trick2015/ksk_1/authors.markdown3
-rw-r--r--sample/trick2015/ksk_1/entry.rb1
-rw-r--r--sample/trick2015/ksk_1/remarks.markdown120
-rw-r--r--sample/trick2015/ksk_2/abnormal.cnf6
-rw-r--r--sample/trick2015/ksk_2/authors.markdown3
-rw-r--r--sample/trick2015/ksk_2/entry.rb1
-rw-r--r--sample/trick2015/ksk_2/quinn.cnf21
-rw-r--r--sample/trick2015/ksk_2/remarks.markdown204
-rw-r--r--sample/trick2015/ksk_2/sample.cnf9
-rw-r--r--sample/trick2015/ksk_2/uf20-01.cnf99
-rw-r--r--sample/trick2015/ksk_2/unsat.cnf11
-rw-r--r--sample/trick2015/monae/authors.markdown1
-rw-r--r--sample/trick2015/monae/entry.rb26
-rw-r--r--sample/trick2015/monae/remarks.markdown25
-rw-r--r--sample/trojan.rb7
-rw-r--r--sample/tsvr.rb17
-rw-r--r--sample/uumerge.rb16
-rw-r--r--sample/weakref.rb9
-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--signal.c1621
-rw-r--r--siphash.c482
-rw-r--r--siphash.h48
-rw-r--r--sparc.c40
-rw-r--r--spec/README.md79
-rw-r--r--spec/default.mspec67
-rw-r--r--spec/mspec/.gitignore26
-rw-r--r--spec/mspec/.travis.yml18
-rw-r--r--spec/mspec/Gemfile4
-rw-r--r--spec/mspec/Gemfile.lock24
-rw-r--r--spec/mspec/LICENSE22
-rw-r--r--spec/mspec/README.md91
-rw-r--r--spec/mspec/Rakefile7
-rwxr-xr-xspec/mspec/bin/mkspec7
-rwxr-xr-xspec/mspec/bin/mkspec.bat1
-rwxr-xr-xspec/mspec/bin/mspec7
-rwxr-xr-xspec/mspec/bin/mspec-ci7
-rwxr-xr-xspec/mspec/bin/mspec-ci.bat1
-rwxr-xr-xspec/mspec/bin/mspec-run7
-rwxr-xr-xspec/mspec/bin/mspec-run.bat1
-rwxr-xr-xspec/mspec/bin/mspec-tag7
-rwxr-xr-xspec/mspec/bin/mspec-tag.bat1
-rwxr-xr-xspec/mspec/bin/mspec.bat1
-rw-r--r--spec/mspec/lib/mspec.rb20
-rwxr-xr-xspec/mspec/lib/mspec/commands/mkspec.rb155
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-ci.rb78
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-run.rb86
-rw-r--r--spec/mspec/lib/mspec/commands/mspec-tag.rb132
-rwxr-xr-xspec/mspec/lib/mspec/commands/mspec.rb178
-rw-r--r--spec/mspec/lib/mspec/expectations.rb2
-rw-r--r--spec/mspec/lib/mspec/expectations/expectations.rb21
-rw-r--r--spec/mspec/lib/mspec/expectations/should.rb29
-rw-r--r--spec/mspec/lib/mspec/guards.rb11
-rw-r--r--spec/mspec/lib/mspec/guards/block_device.rb16
-rw-r--r--spec/mspec/lib/mspec/guards/bug.rb28
-rw-r--r--spec/mspec/lib/mspec/guards/conflict.rb17
-rw-r--r--spec/mspec/lib/mspec/guards/endian.rb25
-rw-r--r--spec/mspec/lib/mspec/guards/feature.rb41
-rw-r--r--spec/mspec/lib/mspec/guards/guard.rb141
-rw-r--r--spec/mspec/lib/mspec/guards/platform.rb76
-rw-r--r--spec/mspec/lib/mspec/guards/quarantine.rb11
-rw-r--r--spec/mspec/lib/mspec/guards/superuser.rb15
-rw-r--r--spec/mspec/lib/mspec/guards/support.rb14
-rw-r--r--spec/mspec/lib/mspec/guards/version.rb37
-rw-r--r--spec/mspec/lib/mspec/helpers.rb14
-rw-r--r--spec/mspec/lib/mspec/helpers/argf.rb35
-rw-r--r--spec/mspec/lib/mspec/helpers/argv.rb44
-rw-r--r--spec/mspec/lib/mspec/helpers/datetime.rb47
-rw-r--r--spec/mspec/lib/mspec/helpers/fixture.rb24
-rw-r--r--spec/mspec/lib/mspec/helpers/flunk.rb3
-rw-r--r--spec/mspec/lib/mspec/helpers/frozen_error_class.rb17
-rw-r--r--spec/mspec/lib/mspec/helpers/fs.rb70
-rw-r--r--spec/mspec/lib/mspec/helpers/io.rb111
-rw-r--r--spec/mspec/lib/mspec/helpers/mock_to_path.rb6
-rw-r--r--spec/mspec/lib/mspec/helpers/numeric.rb70
-rw-r--r--spec/mspec/lib/mspec/helpers/ruby_exe.rb186
-rw-r--r--spec/mspec/lib/mspec/helpers/scratch.rb17
-rw-r--r--spec/mspec/lib/mspec/helpers/tmp.rb43
-rw-r--r--spec/mspec/lib/mspec/helpers/warning.rb7
-rw-r--r--spec/mspec/lib/mspec/matchers.rb35
-rw-r--r--spec/mspec/lib/mspec/matchers/base.rb107
-rw-r--r--spec/mspec/lib/mspec/matchers/be_an_instance_of.rb26
-rw-r--r--spec/mspec/lib/mspec/matchers/be_ancestor_of.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/be_close.rb27
-rw-r--r--spec/mspec/lib/mspec/matchers/be_computed_by.rb37
-rw-r--r--spec/mspec/lib/mspec/matchers/be_empty.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/be_false.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/be_kind_of.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/be_nan.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/be_nil.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/be_true.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/be_true_or_false.rb20
-rw-r--r--spec/mspec/lib/mspec/matchers/block_caller.rb35
-rw-r--r--spec/mspec/lib/mspec/matchers/complain.rb60
-rw-r--r--spec/mspec/lib/mspec/matchers/eql.rb26
-rw-r--r--spec/mspec/lib/mspec/matchers/equal.rb26
-rw-r--r--spec/mspec/lib/mspec/matchers/equal_element.rb78
-rw-r--r--spec/mspec/lib/mspec/matchers/have_class_variable.rb12
-rw-r--r--spec/mspec/lib/mspec/matchers/have_constant.rb12
-rw-r--r--spec/mspec/lib/mspec/matchers/have_instance_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_instance_variable.rb12
-rw-r--r--spec/mspec/lib/mspec/matchers/have_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_private_instance_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_private_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_protected_instance_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_public_instance_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/have_singleton_method.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/include.rb31
-rw-r--r--spec/mspec/lib/mspec/matchers/infinity.rb28
-rw-r--r--spec/mspec/lib/mspec/matchers/match_yaml.rb46
-rw-r--r--spec/mspec/lib/mspec/matchers/method.rb10
-rw-r--r--spec/mspec/lib/mspec/matchers/output.rb67
-rw-r--r--spec/mspec/lib/mspec/matchers/output_to_fd.rb71
-rw-r--r--spec/mspec/lib/mspec/matchers/raise_error.rb87
-rw-r--r--spec/mspec/lib/mspec/matchers/respond_to.rb24
-rw-r--r--spec/mspec/lib/mspec/matchers/signed_zero.rb28
-rw-r--r--spec/mspec/lib/mspec/matchers/variable.rb24
-rw-r--r--spec/mspec/lib/mspec/mocks.rb3
-rw-r--r--spec/mspec/lib/mspec/mocks/mock.rb198
-rw-r--r--spec/mspec/lib/mspec/mocks/object.rb28
-rw-r--r--spec/mspec/lib/mspec/mocks/proxy.rb186
-rw-r--r--spec/mspec/lib/mspec/runner.rb12
-rw-r--r--spec/mspec/lib/mspec/runner/actions.rb6
-rw-r--r--spec/mspec/lib/mspec/runner/actions/filter.rb40
-rw-r--r--spec/mspec/lib/mspec/runner/actions/leakchecker.rb301
-rw-r--r--spec/mspec/lib/mspec/runner/actions/tag.rb133
-rw-r--r--spec/mspec/lib/mspec/runner/actions/taglist.rb56
-rw-r--r--spec/mspec/lib/mspec/runner/actions/tagpurge.rb56
-rw-r--r--spec/mspec/lib/mspec/runner/actions/tally.rb133
-rw-r--r--spec/mspec/lib/mspec/runner/actions/timer.rb22
-rw-r--r--spec/mspec/lib/mspec/runner/context.rb239
-rw-r--r--spec/mspec/lib/mspec/runner/evaluate.rb54
-rw-r--r--spec/mspec/lib/mspec/runner/example.rb34
-rw-r--r--spec/mspec/lib/mspec/runner/exception.rb43
-rw-r--r--spec/mspec/lib/mspec/runner/filters.rb4
-rw-r--r--spec/mspec/lib/mspec/runner/filters/match.rb18
-rw-r--r--spec/mspec/lib/mspec/runner/filters/profile.rb54
-rw-r--r--spec/mspec/lib/mspec/runner/filters/regexp.rb7
-rw-r--r--spec/mspec/lib/mspec/runner/filters/tag.rb29
-rw-r--r--spec/mspec/lib/mspec/runner/formatters.rb12
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/describe.rb24
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/dotted.rb117
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/file.rb19
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/html.rb81
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/junit.rb88
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/method.rb93
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/multi.rb37
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/profile.rb70
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/specdoc.rb41
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/spinner.rb117
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/summary.rb11
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/unit.rb21
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/yaml.rb42
-rw-r--r--spec/mspec/lib/mspec/runner/mspec.rb408
-rw-r--r--spec/mspec/lib/mspec/runner/object.rb26
-rw-r--r--spec/mspec/lib/mspec/runner/shared.rb10
-rw-r--r--spec/mspec/lib/mspec/runner/tag.rb38
-rw-r--r--spec/mspec/lib/mspec/utils/deprecate.rb6
-rw-r--r--spec/mspec/lib/mspec/utils/name_map.rb128
-rw-r--r--spec/mspec/lib/mspec/utils/options.rb481
-rw-r--r--spec/mspec/lib/mspec/utils/script.rb274
-rw-r--r--spec/mspec/lib/mspec/utils/version.rb52
-rw-r--r--spec/mspec/lib/mspec/utils/warnings.rb61
-rw-r--r--spec/mspec/lib/mspec/version.rb5
-rw-r--r--spec/mspec/spec/commands/fixtures/four.txt0
-rw-r--r--spec/mspec/spec/commands/fixtures/level2/three_spec.rb1
-rw-r--r--spec/mspec/spec/commands/fixtures/one_spec.rb1
-rw-r--r--spec/mspec/spec/commands/fixtures/three.rb1
-rw-r--r--spec/mspec/spec/commands/fixtures/two_spec.rb1
-rw-r--r--spec/mspec/spec/commands/mkspec_spec.rb363
-rw-r--r--spec/mspec/spec/commands/mspec_ci_spec.rb150
-rw-r--r--spec/mspec/spec/commands/mspec_run_spec.rb173
-rw-r--r--spec/mspec/spec/commands/mspec_spec.rb207
-rw-r--r--spec/mspec/spec/commands/mspec_tag_spec.rb414
-rw-r--r--spec/mspec/spec/expectations/expectations_spec.rb29
-rw-r--r--spec/mspec/spec/expectations/should.rb73
-rw-r--r--spec/mspec/spec/expectations/should_spec.rb61
-rw-r--r--spec/mspec/spec/fixtures/a_spec.rb15
-rw-r--r--spec/mspec/spec/fixtures/b_spec.rb7
-rw-r--r--spec/mspec/spec/fixtures/config.mspec10
-rwxr-xr-xspec/mspec/spec/fixtures/my_ruby4
-rw-r--r--spec/mspec/spec/fixtures/object_methods_spec.rb8
-rw-r--r--spec/mspec/spec/fixtures/print_interpreter_spec.rb4
-rw-r--r--spec/mspec/spec/fixtures/tagging_spec.rb16
-rw-r--r--spec/mspec/spec/guards/block_device_spec.rb46
-rw-r--r--spec/mspec/spec/guards/bug_spec.rb151
-rw-r--r--spec/mspec/spec/guards/conflict_spec.rb51
-rw-r--r--spec/mspec/spec/guards/endian_spec.rb55
-rw-r--r--spec/mspec/spec/guards/feature_spec.rb80
-rw-r--r--spec/mspec/spec/guards/guard_spec.rb421
-rw-r--r--spec/mspec/spec/guards/platform_spec.rb328
-rw-r--r--spec/mspec/spec/guards/quarantine_spec.rb35
-rw-r--r--spec/mspec/spec/guards/superuser_spec.rb35
-rw-r--r--spec/mspec/spec/guards/support_spec.rb54
-rw-r--r--spec/mspec/spec/guards/user_spec.rb20
-rw-r--r--spec/mspec/spec/guards/version_spec.rb90
-rw-r--r--spec/mspec/spec/helpers/argf_spec.rb37
-rw-r--r--spec/mspec/spec/helpers/argv_spec.rb27
-rw-r--r--spec/mspec/spec/helpers/datetime_spec.rb44
-rw-r--r--spec/mspec/spec/helpers/fixture_spec.rb25
-rw-r--r--spec/mspec/spec/helpers/flunk_spec.rb20
-rw-r--r--spec/mspec/spec/helpers/fs_spec.rb195
-rw-r--r--spec/mspec/spec/helpers/io_spec.rb174
-rw-r--r--spec/mspec/spec/helpers/mock_to_path_spec.rb17
-rw-r--r--spec/mspec/spec/helpers/numeric_spec.rb25
-rw-r--r--spec/mspec/spec/helpers/ruby_exe_spec.rb197
-rw-r--r--spec/mspec/spec/helpers/scratch_spec.rb24
-rw-r--r--spec/mspec/spec/helpers/suppress_warning_spec.rb19
-rw-r--r--spec/mspec/spec/helpers/tmp_spec.rb27
-rw-r--r--spec/mspec/spec/integration/interpreter_spec.rb18
-rw-r--r--spec/mspec/spec/integration/object_methods_spec.rb18
-rw-r--r--spec/mspec/spec/integration/run_spec.rb52
-rw-r--r--spec/mspec/spec/integration/tag_spec.rb63
-rw-r--r--spec/mspec/spec/matchers/base_spec.rb225
-rw-r--r--spec/mspec/spec/matchers/be_an_instance_of_spec.rb50
-rw-r--r--spec/mspec/spec/matchers/be_ancestor_of_spec.rb28
-rw-r--r--spec/mspec/spec/matchers/be_close_spec.rb46
-rw-r--r--spec/mspec/spec/matchers/be_computed_by_spec.rb42
-rw-r--r--spec/mspec/spec/matchers/be_empty_spec.rb26
-rw-r--r--spec/mspec/spec/matchers/be_false_spec.rb28
-rw-r--r--spec/mspec/spec/matchers/be_kind_of_spec.rb31
-rw-r--r--spec/mspec/spec/matchers/be_nan_spec.rb28
-rw-r--r--spec/mspec/spec/matchers/be_nil_spec.rb27
-rw-r--r--spec/mspec/spec/matchers/be_true_or_false_spec.rb19
-rw-r--r--spec/mspec/spec/matchers/be_true_spec.rb28
-rw-r--r--spec/mspec/spec/matchers/block_caller_spec.rb13
-rw-r--r--spec/mspec/spec/matchers/complain_spec.rb52
-rw-r--r--spec/mspec/spec/matchers/eql_spec.rb33
-rw-r--r--spec/mspec/spec/matchers/equal_element_spec.rb75
-rw-r--r--spec/mspec/spec/matchers/equal_spec.rb32
-rw-r--r--spec/mspec/spec/matchers/have_class_variable_spec.rb49
-rw-r--r--spec/mspec/spec/matchers/have_constant_spec.rb37
-rw-r--r--spec/mspec/spec/matchers/have_instance_method_spec.rb53
-rw-r--r--spec/mspec/spec/matchers/have_instance_variable_spec.rb50
-rw-r--r--spec/mspec/spec/matchers/have_method_spec.rb55
-rw-r--r--spec/mspec/spec/matchers/have_private_instance_method_spec.rb57
-rw-r--r--spec/mspec/spec/matchers/have_private_method_spec.rb44
-rw-r--r--spec/mspec/spec/matchers/have_protected_instance_method_spec.rb57
-rw-r--r--spec/mspec/spec/matchers/have_public_instance_method_spec.rb53
-rw-r--r--spec/mspec/spec/matchers/have_singleton_method_spec.rb45
-rw-r--r--spec/mspec/spec/matchers/include_spec.rb37
-rw-r--r--spec/mspec/spec/matchers/infinity_spec.rb34
-rw-r--r--spec/mspec/spec/matchers/match_yaml_spec.rb39
-rw-r--r--spec/mspec/spec/matchers/output_spec.rb74
-rw-r--r--spec/mspec/spec/matchers/output_to_fd_spec.rb44
-rw-r--r--spec/mspec/spec/matchers/raise_error_spec.rb120
-rw-r--r--spec/mspec/spec/matchers/respond_to_spec.rb33
-rw-r--r--spec/mspec/spec/matchers/signed_zero_spec.rb32
-rw-r--r--spec/mspec/spec/mocks/mock_spec.rb467
-rw-r--r--spec/mspec/spec/mocks/proxy_spec.rb405
-rw-r--r--spec/mspec/spec/runner/actions/filter_spec.rb84
-rw-r--r--spec/mspec/spec/runner/actions/tag_spec.rb315
-rw-r--r--spec/mspec/spec/runner/actions/taglist_spec.rb152
-rw-r--r--spec/mspec/spec/runner/actions/tagpurge_spec.rb154
-rw-r--r--spec/mspec/spec/runner/actions/tally_spec.rb352
-rw-r--r--spec/mspec/spec/runner/actions/timer_spec.rb44
-rw-r--r--spec/mspec/spec/runner/context_spec.rb1041
-rw-r--r--spec/mspec/spec/runner/example_spec.rb117
-rw-r--r--spec/mspec/spec/runner/exception_spec.rb146
-rw-r--r--spec/mspec/spec/runner/filters/a.yaml4
-rw-r--r--spec/mspec/spec/runner/filters/b.yaml11
-rw-r--r--spec/mspec/spec/runner/filters/match_spec.rb34
-rw-r--r--spec/mspec/spec/runner/filters/profile_spec.rb117
-rw-r--r--spec/mspec/spec/runner/filters/regexp_spec.rb13
-rw-r--r--spec/mspec/spec/runner/filters/tag_spec.rb92
-rw-r--r--spec/mspec/spec/runner/formatters/describe_spec.rb67
-rw-r--r--spec/mspec/spec/runner/formatters/dotted_spec.rb285
-rw-r--r--spec/mspec/spec/runner/formatters/file_spec.rb84
-rw-r--r--spec/mspec/spec/runner/formatters/html_spec.rb216
-rw-r--r--spec/mspec/spec/runner/formatters/junit_spec.rb147
-rw-r--r--spec/mspec/spec/runner/formatters/method_spec.rb178
-rw-r--r--spec/mspec/spec/runner/formatters/multi_spec.rb68
-rw-r--r--spec/mspec/spec/runner/formatters/specdoc_spec.rb106
-rw-r--r--spec/mspec/spec/runner/formatters/spinner_spec.rb83
-rw-r--r--spec/mspec/spec/runner/formatters/summary_spec.rb26
-rw-r--r--spec/mspec/spec/runner/formatters/unit_spec.rb74
-rw-r--r--spec/mspec/spec/runner/formatters/yaml_spec.rb125
-rw-r--r--spec/mspec/spec/runner/mspec_spec.rb595
-rw-r--r--spec/mspec/spec/runner/shared_spec.rb90
-rw-r--r--spec/mspec/spec/runner/tag_spec.rb123
-rw-r--r--spec/mspec/spec/runner/tags.txt4
-rw-r--r--spec/mspec/spec/spec_helper.rb55
-rw-r--r--spec/mspec/spec/utils/deprecate_spec.rb17
-rw-r--r--spec/mspec/spec/utils/name_map_spec.rb175
-rw-r--r--spec/mspec/spec/utils/options_spec.rb1285
-rw-r--r--spec/mspec/spec/utils/script_spec.rb475
-rw-r--r--spec/mspec/spec/utils/version_spec.rb45
-rwxr-xr-xspec/mspec/tool/find.rb10
-rw-r--r--spec/mspec/tool/remove_old_guards.rb41
-rw-r--r--spec/mspec/tool/sync/.gitignore4
-rw-r--r--spec/mspec/tool/sync/sync-rubyspec.rb240
-rw-r--r--spec/ruby/.gitignore5
-rw-r--r--spec/ruby/.rubocop.yml60
-rw-r--r--spec/ruby/.rubocop_todo.yml207
-rw-r--r--spec/ruby/.travis.yml36
-rw-r--r--spec/ruby/CHANGES.before-2008-05-1017796
-rw-r--r--spec/ruby/CONTRIBUTING.md171
-rw-r--r--spec/ruby/LICENSE22
-rw-r--r--spec/ruby/README.md97
-rw-r--r--spec/ruby/TODO8
-rw-r--r--spec/ruby/appveyor.yml30
-rw-r--r--spec/ruby/command_line/dash_a_spec.rb17
-rw-r--r--spec/ruby/command_line/dash_c_spec.rb13
-rw-r--r--spec/ruby/command_line/dash_d_spec.rb22
-rw-r--r--spec/ruby/command_line/dash_e_spec.rb41
-rw-r--r--spec/ruby/command_line/dash_n_spec.rb34
-rw-r--r--spec/ruby/command_line/dash_p_spec.rb17
-rw-r--r--spec/ruby/command_line/dash_r_spec.rb13
-rw-r--r--spec/ruby/command_line/dash_s_spec.rb52
-rw-r--r--spec/ruby/command_line/dash_upper_c_spec.rb18
-rw-r--r--spec/ruby/command_line/dash_upper_e_spec.rb7
-rw-r--r--spec/ruby/command_line/dash_upper_f_spec.rb11
-rw-r--r--spec/ruby/command_line/dash_upper_i_spec.rb11
-rw-r--r--spec/ruby/command_line/dash_upper_k_spec.rb33
-rw-r--r--spec/ruby/command_line/dash_upper_s_spec.rb29
-rw-r--r--spec/ruby/command_line/dash_upper_u_spec.rb41
-rw-r--r--spec/ruby/command_line/dash_upper_w_spec.rb20
-rw-r--r--spec/ruby/command_line/dash_v_spec.rb12
-rw-r--r--spec/ruby/command_line/dash_w_spec.rb6
-rw-r--r--spec/ruby/command_line/dash_x_spec.rb21
-rw-r--r--spec/ruby/command_line/error_message_spec.rb11
-rw-r--r--spec/ruby/command_line/fixtures/bad_syntax.rb1
-rw-r--r--spec/ruby/command_line/fixtures/bin/bad_embedded_ruby.txt3
-rw-r--r--spec/ruby/command_line/fixtures/bin/dash_s_fail1
-rw-r--r--spec/ruby/command_line/fixtures/bin/embedded_ruby.txt3
-rw-r--r--spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh4
-rw-r--r--spec/ruby/command_line/fixtures/bin/launcher.rb2
-rw-r--r--spec/ruby/command_line/fixtures/conditional_range.txt5
-rw-r--r--spec/ruby/command_line/fixtures/dash_s_script.rb12
-rw-r--r--spec/ruby/command_line/fixtures/dash_upper_c_script.rb1
-rw-r--r--spec/ruby/command_line/fixtures/debug.rb10
-rw-r--r--spec/ruby/command_line/fixtures/debug_info.rb11
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_across_files.rb3
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_across_files_diff_enc.rb3
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_one_literal.rb2
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_required.rb1
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_required_diff_enc.rbbin0 -> 121 bytes-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_two_literals.rb1
-rw-r--r--spec/ruby/command_line/fixtures/full_names.txt3
-rw-r--r--spec/ruby/command_line/fixtures/loadpath.rb1
-rw-r--r--spec/ruby/command_line/fixtures/names.txt3
-rw-r--r--spec/ruby/command_line/fixtures/passwd_file.txt3
-rw-r--r--spec/ruby/command_line/fixtures/require.rb1
-rw-r--r--spec/ruby/command_line/fixtures/rubyopt.rb1
-rw-r--r--spec/ruby/command_line/fixtures/test_file.rb1
-rw-r--r--spec/ruby/command_line/fixtures/verbose.rb1
-rw-r--r--spec/ruby/command_line/frozen_strings_spec.rb30
-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb165
-rw-r--r--spec/ruby/command_line/shared/verbose.rb9
-rw-r--r--spec/ruby/command_line/syntax_error_spec.rb13
-rw-r--r--spec/ruby/core/argf/argf_spec.rb11
-rw-r--r--spec/ruby/core/argf/argv_spec.rb19
-rw-r--r--spec/ruby/core/argf/binmode_spec.rb43
-rw-r--r--spec/ruby/core/argf/bytes_spec.rb6
-rw-r--r--spec/ruby/core/argf/chars_spec.rb6
-rw-r--r--spec/ruby/core/argf/close_spec.rb46
-rw-r--r--spec/ruby/core/argf/closed_spec.rb18
-rw-r--r--spec/ruby/core/argf/codepoints_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_byte_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_char_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_codepoint_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_line_spec.rb6
-rw-r--r--spec/ruby/core/argf/each_spec.rb6
-rw-r--r--spec/ruby/core/argf/eof_spec.rb10
-rw-r--r--spec/ruby/core/argf/file_spec.rb21
-rw-r--r--spec/ruby/core/argf/filename_spec.rb6
-rw-r--r--spec/ruby/core/argf/fileno_spec.rb6
-rw-r--r--spec/ruby/core/argf/fixtures/bin_file.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/file1.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/file2.txt2
-rw-r--r--spec/ruby/core/argf/fixtures/filename.rb3
-rw-r--r--spec/ruby/core/argf/fixtures/lineno.rb5
-rw-r--r--spec/ruby/core/argf/fixtures/rewind.rb5
-rw-r--r--spec/ruby/core/argf/fixtures/stdin.txt2
-rw-r--r--spec/ruby/core/argf/getc_spec.rb20
-rw-r--r--spec/ruby/core/argf/gets_spec.rb51
-rw-r--r--spec/ruby/core/argf/lineno_spec.rb30
-rw-r--r--spec/ruby/core/argf/lines_spec.rb6
-rw-r--r--spec/ruby/core/argf/path_spec.rb6
-rw-r--r--spec/ruby/core/argf/pos_spec.rb38
-rw-r--r--spec/ruby/core/argf/read_nonblock_spec.rb82
-rw-r--r--spec/ruby/core/argf/read_spec.rb87
-rw-r--r--spec/ruby/core/argf/readchar_spec.rb19
-rw-r--r--spec/ruby/core/argf/readline_spec.rb23
-rw-r--r--spec/ruby/core/argf/readlines_spec.rb6
-rw-r--r--spec/ruby/core/argf/readpartial_spec.rb77
-rw-r--r--spec/ruby/core/argf/rewind_spec.rb39
-rw-r--r--spec/ruby/core/argf/seek_spec.rb63
-rw-r--r--spec/ruby/core/argf/set_encoding_spec.rb41
-rw-r--r--spec/ruby/core/argf/shared/each_byte.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_char.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_codepoint.rb58
-rw-r--r--spec/ruby/core/argf/shared/each_line.rb62
-rw-r--r--spec/ruby/core/argf/shared/eof.rb24
-rw-r--r--spec/ruby/core/argf/shared/filename.rb28
-rw-r--r--spec/ruby/core/argf/shared/fileno.rb24
-rw-r--r--spec/ruby/core/argf/shared/getc.rb17
-rw-r--r--spec/ruby/core/argf/shared/gets.rb99
-rw-r--r--spec/ruby/core/argf/shared/pos.rb31
-rw-r--r--spec/ruby/core/argf/shared/read.rb58
-rw-r--r--spec/ruby/core/argf/shared/readlines.rb22
-rw-r--r--spec/ruby/core/argf/skip_spec.rb42
-rw-r--r--spec/ruby/core/argf/tell_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_a_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_i_spec.rb6
-rw-r--r--spec/ruby/core/argf/to_io_spec.rb23
-rw-r--r--spec/ruby/core/argf/to_s_spec.rb14
-rw-r--r--spec/ruby/core/array/allocate_spec.rb19
-rw-r--r--spec/ruby/core/array/any_spec.rb37
-rw-r--r--spec/ruby/core/array/append_spec.rb42
-rw-r--r--spec/ruby/core/array/array_spec.rb7
-rw-r--r--spec/ruby/core/array/assoc_spec.rb40
-rw-r--r--spec/ruby/core/array/at_spec.rb56
-rw-r--r--spec/ruby/core/array/bsearch_index_spec.rb87
-rw-r--r--spec/ruby/core/array/bsearch_spec.rb84
-rw-r--r--spec/ruby/core/array/clear_spec.rb49
-rw-r--r--spec/ruby/core/array/clone_spec.rb31
-rw-r--r--spec/ruby/core/array/collect_spec.rb11
-rw-r--r--spec/ruby/core/array/combination_spec.rb74
-rw-r--r--spec/ruby/core/array/compact_spec.rb77
-rw-r--r--spec/ruby/core/array/comparison_spec.rb97
-rw-r--r--spec/ruby/core/array/concat_spec.rb132
-rw-r--r--spec/ruby/core/array/constructor_spec.rb24
-rw-r--r--spec/ruby/core/array/count_spec.rb15
-rw-r--r--spec/ruby/core/array/cycle_spec.rb101
-rw-r--r--spec/ruby/core/array/delete_at_spec.rb61
-rw-r--r--spec/ruby/core/array/delete_if_spec.rb66
-rw-r--r--spec/ruby/core/array/delete_spec.rb66
-rw-r--r--spec/ruby/core/array/dig_spec.rb54
-rw-r--r--spec/ruby/core/array/drop_spec.rb33
-rw-r--r--spec/ruby/core/array/drop_while_spec.rb15
-rw-r--r--spec/ruby/core/array/dup_spec.rb31
-rw-r--r--spec/ruby/core/array/each_index_spec.rb42
-rw-r--r--spec/ruby/core/array/each_spec.rb32
-rw-r--r--spec/ruby/core/array/element_reference_spec.rb50
-rw-r--r--spec/ruby/core/array/element_set_spec.rb417
-rw-r--r--spec/ruby/core/array/empty_spec.rb10
-rw-r--r--spec/ruby/core/array/eql_spec.rb19
-rw-r--r--spec/ruby/core/array/equal_value_spec.rb51
-rw-r--r--spec/ruby/core/array/fetch_spec.rb55
-rw-r--r--spec/ruby/core/array/fill_spec.rb317
-rw-r--r--spec/ruby/core/array/find_index_spec.rb6
-rw-r--r--spec/ruby/core/array/first_spec.rb93
-rw-r--r--spec/ruby/core/array/fixtures/classes.rb525
-rw-r--r--spec/ruby/core/array/fixtures/encoded_strings.rb69
-rw-r--r--spec/ruby/core/array/flatten_spec.rb286
-rw-r--r--spec/ruby/core/array/frozen_spec.rb16
-rw-r--r--spec/ruby/core/array/hash_spec.rb83
-rw-r--r--spec/ruby/core/array/include_spec.rb33
-rw-r--r--spec/ruby/core/array/index_spec.rb6
-rw-r--r--spec/ruby/core/array/initialize_spec.rb156
-rw-r--r--spec/ruby/core/array/insert_spec.rb78
-rw-r--r--spec/ruby/core/array/inspect_spec.rb7
-rw-r--r--spec/ruby/core/array/intersection_spec.rb87
-rw-r--r--spec/ruby/core/array/join_spec.rb48
-rw-r--r--spec/ruby/core/array/keep_if_spec.rb10
-rw-r--r--spec/ruby/core/array/last_spec.rb87
-rw-r--r--spec/ruby/core/array/length_spec.rb7
-rw-r--r--spec/ruby/core/array/map_spec.rb11
-rw-r--r--spec/ruby/core/array/max_spec.rb118
-rw-r--r--spec/ruby/core/array/min_spec.rb123
-rw-r--r--spec/ruby/core/array/minus_spec.rb87
-rw-r--r--spec/ruby/core/array/multiply_spec.rb132
-rw-r--r--spec/ruby/core/array/new_spec.rb122
-rw-r--r--spec/ruby/core/array/pack/a_spec.rb59
-rw-r--r--spec/ruby/core/array/pack/at_spec.rb30
-rw-r--r--spec/ruby/core/array/pack/b_spec.rb105
-rw-r--r--spec/ruby/core/array/pack/buffer_spec.rb52
-rw-r--r--spec/ruby/core/array/pack/c_spec.rb75
-rw-r--r--spec/ruby/core/array/pack/comment_spec.rb25
-rw-r--r--spec/ruby/core/array/pack/d_spec.rb39
-rw-r--r--spec/ruby/core/array/pack/e_spec.rb25
-rw-r--r--spec/ruby/core/array/pack/empty_spec.rb11
-rw-r--r--spec/ruby/core/array/pack/f_spec.rb39
-rw-r--r--spec/ruby/core/array/pack/g_spec.rb25
-rw-r--r--spec/ruby/core/array/pack/h_spec.rb197
-rw-r--r--spec/ruby/core/array/pack/i_spec.rb133
-rw-r--r--spec/ruby/core/array/pack/j_spec.rb222
-rw-r--r--spec/ruby/core/array/pack/l_spec.rb221
-rw-r--r--spec/ruby/core/array/pack/m_spec.rb306
-rw-r--r--spec/ruby/core/array/pack/n_spec.rb25
-rw-r--r--spec/ruby/core/array/pack/p_spec.rb11
-rw-r--r--spec/ruby/core/array/pack/percent_spec.rb7
-rw-r--r--spec/ruby/core/array/pack/q_spec.rb61
-rw-r--r--spec/ruby/core/array/pack/s_spec.rb133
-rw-r--r--spec/ruby/core/array/pack/shared/basic.rb65
-rw-r--r--spec/ruby/core/array/pack/shared/encodings.rb16
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb249
-rw-r--r--spec/ruby/core/array/pack/shared/integer.rb381
-rw-r--r--spec/ruby/core/array/pack/shared/numeric_basic.rb44
-rw-r--r--spec/ruby/core/array/pack/shared/string.rb80
-rw-r--r--spec/ruby/core/array/pack/shared/unicode.rb94
-rw-r--r--spec/ruby/core/array/pack/u_spec.rb128
-rw-r--r--spec/ruby/core/array/pack/v_spec.rb25
-rw-r--r--spec/ruby/core/array/pack/w_spec.rb42
-rw-r--r--spec/ruby/core/array/pack/x_spec.rb64
-rw-r--r--spec/ruby/core/array/pack/z_spec.rb32
-rw-r--r--spec/ruby/core/array/partition_spec.rb43
-rw-r--r--spec/ruby/core/array/permutation_spec.rb138
-rw-r--r--spec/ruby/core/array/plus_spec.rb57
-rw-r--r--spec/ruby/core/array/pop_spec.rb168
-rw-r--r--spec/ruby/core/array/prepend_spec.rb9
-rw-r--r--spec/ruby/core/array/product_spec.rb68
-rw-r--r--spec/ruby/core/array/push_spec.rb7
-rw-r--r--spec/ruby/core/array/rassoc_spec.rb38
-rw-r--r--spec/ruby/core/array/reject_spec.rb117
-rw-r--r--spec/ruby/core/array/repeated_combination_spec.rb84
-rw-r--r--spec/ruby/core/array/repeated_permutation_spec.rb94
-rw-r--r--spec/ruby/core/array/replace_spec.rb7
-rw-r--r--spec/ruby/core/array/reverse_each_spec.rb43
-rw-r--r--spec/ruby/core/array/reverse_spec.rb42
-rw-r--r--spec/ruby/core/array/rindex_spec.rb80
-rw-r--r--spec/ruby/core/array/rotate_spec.rb129
-rw-r--r--spec/ruby/core/array/sample_spec.rb155
-rw-r--r--spec/ruby/core/array/select_spec.rb36
-rw-r--r--spec/ruby/core/array/shared/clone.rb42
-rw-r--r--spec/ruby/core/array/shared/collect.rb136
-rw-r--r--spec/ruby/core/array/shared/delete_if.rb27
-rw-r--r--spec/ruby/core/array/shared/enumeratorize.rb5
-rw-r--r--spec/ruby/core/array/shared/eql.rb92
-rw-r--r--spec/ruby/core/array/shared/index.rb37
-rw-r--r--spec/ruby/core/array/shared/inspect.rb144
-rw-r--r--spec/ruby/core/array/shared/join.rb161
-rw-r--r--spec/ruby/core/array/shared/keep_if.rb60
-rw-r--r--spec/ruby/core/array/shared/length.rb11
-rw-r--r--spec/ruby/core/array/shared/push.rb33
-rw-r--r--spec/ruby/core/array/shared/replace.rb60
-rw-r--r--spec/ruby/core/array/shared/slice.rb459
-rw-r--r--spec/ruby/core/array/shared/unshift.rb46
-rw-r--r--spec/ruby/core/array/shift_spec.rb134
-rw-r--r--spec/ruby/core/array/shuffle_spec.rb102
-rw-r--r--spec/ruby/core/array/size_spec.rb7
-rw-r--r--spec/ruby/core/array/slice_spec.rb160
-rw-r--r--spec/ruby/core/array/sort_by_spec.rb52
-rw-r--r--spec/ruby/core/array/sort_spec.rb252
-rw-r--r--spec/ruby/core/array/sum_spec.rb44
-rw-r--r--spec/ruby/core/array/take_spec.rb27
-rw-r--r--spec/ruby/core/array/take_while_spec.rb15
-rw-r--r--spec/ruby/core/array/to_a_spec.rb24
-rw-r--r--spec/ruby/core/array/to_ary_spec.rb20
-rw-r--r--spec/ruby/core/array/to_h_spec.rb37
-rw-r--r--spec/ruby/core/array/to_s_spec.rb8
-rw-r--r--spec/ruby/core/array/transpose_spec.rb53
-rw-r--r--spec/ruby/core/array/try_convert_spec.rb50
-rw-r--r--spec/ruby/core/array/union_spec.rb82
-rw-r--r--spec/ruby/core/array/uniq_spec.rb221
-rw-r--r--spec/ruby/core/array/unshift_spec.rb7
-rw-r--r--spec/ruby/core/array/values_at_spec.rb63
-rw-r--r--spec/ruby/core/array/zip_spec.rb65
-rw-r--r--spec/ruby/core/basicobject/__id__spec.rb6
-rw-r--r--spec/ruby/core/basicobject/__send___spec.rb10
-rw-r--r--spec/ruby/core/basicobject/basicobject_spec.rb87
-rw-r--r--spec/ruby/core/basicobject/equal_spec.rb52
-rw-r--r--spec/ruby/core/basicobject/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/basicobject/fixtures/classes.rb33
-rw-r--r--spec/ruby/core/basicobject/fixtures/common.rb9
-rw-r--r--spec/ruby/core/basicobject/fixtures/remove_method_missing.rb9
-rw-r--r--spec/ruby/core/basicobject/fixtures/singleton_method.rb10
-rw-r--r--spec/ruby/core/basicobject/initialize_spec.rb13
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb180
-rw-r--r--spec/ruby/core/basicobject/instance_exec_spec.rb107
-rw-r--r--spec/ruby/core/basicobject/method_missing_spec.rb39
-rw-r--r--spec/ruby/core/basicobject/not_equal_spec.rb53
-rw-r--r--spec/ruby/core/basicobject/not_spec.rb11
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb86
-rw-r--r--spec/ruby/core/basicobject/singleton_method_removed_spec.rb24
-rw-r--r--spec/ruby/core/basicobject/singleton_method_undefined_spec.rb24
-rw-r--r--spec/ruby/core/bignum/abs_spec.rb7
-rw-r--r--spec/ruby/core/bignum/bignum_spec.rb31
-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.rb7
-rw-r--r--spec/ruby/core/binding/dup_spec.rb7
-rw-r--r--spec/ruby/core/binding/eval_spec.rb37
-rw-r--r--spec/ruby/core/binding/fixtures/classes.rb40
-rw-r--r--spec/ruby/core/binding/local_variable_defined_spec.rb46
-rw-r--r--spec/ruby/core/binding/local_variable_get_spec.rb56
-rw-r--r--spec/ruby/core/binding/local_variable_set_spec.rb71
-rw-r--r--spec/ruby/core/binding/local_variables_spec.rb35
-rw-r--r--spec/ruby/core/binding/location_spec.rb46
-rw-r--r--spec/ruby/core/binding/receiver_spec.rb11
-rw-r--r--spec/ruby/core/binding/shared/clone.rb34
-rw-r--r--spec/ruby/core/builtin_constants/builtin_constants_spec.rb49
-rw-r--r--spec/ruby/core/class/allocate_spec.rb41
-rw-r--r--spec/ruby/core/class/dup_spec.rb64
-rw-r--r--spec/ruby/core/class/fixtures/classes.rb47
-rw-r--r--spec/ruby/core/class/inherited_spec.rb102
-rw-r--r--spec/ruby/core/class/initialize_spec.rb34
-rw-r--r--spec/ruby/core/class/new_spec.rb154
-rw-r--r--spec/ruby/core/class/superclass_spec.rb27
-rw-r--r--spec/ruby/core/class/to_s_spec.rb23
-rw-r--r--spec/ruby/core/comparable/between_spec.rb25
-rw-r--r--spec/ruby/core/comparable/clamp_spec.rb50
-rw-r--r--spec/ruby/core/comparable/equal_value_spec.rb139
-rw-r--r--spec/ruby/core/comparable/fixtures/classes.rb36
-rw-r--r--spec/ruby/core/comparable/gt_spec.rb43
-rw-r--r--spec/ruby/core/comparable/gte_spec.rb47
-rw-r--r--spec/ruby/core/comparable/lt_spec.rb43
-rw-r--r--spec/ruby/core/comparable/lte_spec.rb46
-rw-r--r--spec/ruby/core/complex/abs2_spec.rb5
-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.rb5
-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.rb5
-rw-r--r--spec/ruby/core/complex/denominator_spec.rb5
-rw-r--r--spec/ruby/core/complex/divide_spec.rb5
-rw-r--r--spec/ruby/core/complex/eql_spec.rb31
-rw-r--r--spec/ruby/core/complex/equal_value_spec.rb5
-rw-r--r--spec/ruby/core/complex/exponent_spec.rb5
-rw-r--r--spec/ruby/core/complex/fdiv_spec.rb129
-rw-r--r--spec/ruby/core/complex/finite_spec.rb36
-rw-r--r--spec/ruby/core/complex/hash_spec.rb6
-rw-r--r--spec/ruby/core/complex/imag_spec.rb5
-rw-r--r--spec/ruby/core/complex/imaginary_spec.rb5
-rw-r--r--spec/ruby/core/complex/infinite_spec.rb34
-rw-r--r--spec/ruby/core/complex/inspect_spec.rb5
-rw-r--r--spec/ruby/core/complex/integer_spec.rb9
-rw-r--r--spec/ruby/core/complex/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/complex/marshal_dump_spec.rb11
-rw-r--r--spec/ruby/core/complex/minus_spec.rb5
-rw-r--r--spec/ruby/core/complex/multiply_spec.rb5
-rw-r--r--spec/ruby/core/complex/negative_spec.rb11
-rw-r--r--spec/ruby/core/complex/numerator_spec.rb5
-rw-r--r--spec/ruby/core/complex/phase_spec.rb6
-rw-r--r--spec/ruby/core/complex/plus_spec.rb5
-rw-r--r--spec/ruby/core/complex/polar_spec.rb14
-rw-r--r--spec/ruby/core/complex/positive_spec.rb11
-rw-r--r--spec/ruby/core/complex/quo_spec.rb5
-rw-r--r--spec/ruby/core/complex/rationalize_spec.rb29
-rw-r--r--spec/ruby/core/complex/real_spec.rb23
-rw-r--r--spec/ruby/core/complex/rect_spec.rb9
-rw-r--r--spec/ruby/core/complex/rectangular_spec.rb9
-rw-r--r--spec/ruby/core/complex/to_f_spec.rb41
-rw-r--r--spec/ruby/core/complex/to_i_spec.rb41
-rw-r--r--spec/ruby/core/complex/to_r_spec.rb41
-rw-r--r--spec/ruby/core/complex/to_s_spec.rb5
-rw-r--r--spec/ruby/core/complex/uminus_spec.rb11
-rw-r--r--spec/ruby/core/dir/chdir_spec.rb124
-rw-r--r--spec/ruby/core/dir/children_spec.rb72
-rw-r--r--spec/ruby/core/dir/chroot_spec.rb47
-rw-r--r--spec/ruby/core/dir/close_spec.rb29
-rw-r--r--spec/ruby/core/dir/delete_spec.rb15
-rw-r--r--spec/ruby/core/dir/dir_spec.rb7
-rw-r--r--spec/ruby/core/dir/each_child_spec.rb53
-rw-r--r--spec/ruby/core/dir/each_spec.rb64
-rw-r--r--spec/ruby/core/dir/element_reference_spec.rb33
-rw-r--r--spec/ruby/core/dir/empty_spec.rb33
-rw-r--r--spec/ruby/core/dir/entries_spec.rb70
-rw-r--r--spec/ruby/core/dir/exist_spec.rb15
-rw-r--r--spec/ruby/core/dir/exists_spec.rb15
-rw-r--r--spec/ruby/core/dir/fileno_spec.rb37
-rw-r--r--spec/ruby/core/dir/fixtures/common.rb169
-rw-r--r--spec/ruby/core/dir/foreach_spec.rb56
-rw-r--r--spec/ruby/core/dir/getwd_spec.rb15
-rw-r--r--spec/ruby/core/dir/glob_spec.rb156
-rw-r--r--spec/ruby/core/dir/home_spec.rb26
-rw-r--r--spec/ruby/core/dir/initialize_spec.rb23
-rw-r--r--spec/ruby/core/dir/inspect_spec.rb24
-rw-r--r--spec/ruby/core/dir/mkdir_spec.rb85
-rw-r--r--spec/ruby/core/dir/open_spec.rb15
-rw-r--r--spec/ruby/core/dir/path_spec.rb15
-rw-r--r--spec/ruby/core/dir/pos_spec.rb40
-rw-r--r--spec/ruby/core/dir/pwd_spec.rb39
-rw-r--r--spec/ruby/core/dir/read_spec.rb43
-rw-r--r--spec/ruby/core/dir/rewind_spec.rb36
-rw-r--r--spec/ruby/core/dir/rmdir_spec.rb15
-rw-r--r--spec/ruby/core/dir/seek_spec.rb19
-rw-r--r--spec/ruby/core/dir/shared/chroot.rb41
-rw-r--r--spec/ruby/core/dir/shared/closed.rb9
-rw-r--r--spec/ruby/core/dir/shared/delete.rb61
-rw-r--r--spec/ruby/core/dir/shared/exist.rb56
-rw-r--r--spec/ruby/core/dir/shared/glob.rb328
-rw-r--r--spec/ruby/core/dir/shared/open.rb63
-rw-r--r--spec/ruby/core/dir/shared/path.rb32
-rw-r--r--spec/ruby/core/dir/shared/pos.rb51
-rw-r--r--spec/ruby/core/dir/shared/pwd.rb49
-rw-r--r--spec/ruby/core/dir/tell_spec.rb18
-rw-r--r--spec/ruby/core/dir/to_path_spec.rb15
-rw-r--r--spec/ruby/core/dir/unlink_spec.rb15
-rw-r--r--spec/ruby/core/encoding/_dump_spec.rb5
-rw-r--r--spec/ruby/core/encoding/_load_spec.rb5
-rw-r--r--spec/ruby/core/encoding/aliases_spec.rb45
-rw-r--r--spec/ruby/core/encoding/ascii_compatible_spec.rb13
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb381
-rw-r--r--spec/ruby/core/encoding/converter/asciicompat_encoding_spec.rb39
-rw-r--r--spec/ruby/core/encoding/converter/constants_spec.rb133
-rw-r--r--spec/ruby/core/encoding/converter/convert_spec.rb47
-rw-r--r--spec/ruby/core/encoding/converter/convpath_spec.rb65
-rw-r--r--spec/ruby/core/encoding/converter/destination_encoding_spec.rb13
-rw-r--r--spec/ruby/core/encoding/converter/finish_spec.rb38
-rw-r--r--spec/ruby/core/encoding/converter/insert_output_spec.rb5
-rw-r--r--spec/ruby/core/encoding/converter/inspect_spec.rb13
-rw-r--r--spec/ruby/core/encoding/converter/last_error_spec.rb85
-rw-r--r--spec/ruby/core/encoding/converter/new_spec.rb121
-rw-r--r--spec/ruby/core/encoding/converter/primitive_convert_spec.rb213
-rw-r--r--spec/ruby/core/encoding/converter/primitive_errinfo_spec.rb70
-rw-r--r--spec/ruby/core/encoding/converter/putback_spec.rb49
-rw-r--r--spec/ruby/core/encoding/converter/replacement_spec.rb74
-rw-r--r--spec/ruby/core/encoding/converter/search_convpath_spec.rb73
-rw-r--r--spec/ruby/core/encoding/converter/source_encoding_spec.rb13
-rw-r--r--spec/ruby/core/encoding/default_external_spec.rb74
-rw-r--r--spec/ruby/core/encoding/default_internal_spec.rb93
-rw-r--r--spec/ruby/core/encoding/dummy_spec.rb16
-rw-r--r--spec/ruby/core/encoding/find_spec.rb84
-rw-r--r--spec/ruby/core/encoding/fixtures/classes.rb49
-rw-r--r--spec/ruby/core/encoding/inspect_spec.rb21
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_name_spec.rb20
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/destination_encoding_spec.rb20
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/error_bytes_spec.rb32
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/incomplete_input_spec.rb31
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/readagain_bytes_spec.rb32
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_name_spec.rb30
-rw-r--r--spec/ruby/core/encoding/invalid_byte_sequence_error/source_encoding_spec.rb35
-rw-r--r--spec/ruby/core/encoding/list_spec.rb43
-rw-r--r--spec/ruby/core/encoding/locale_charmap_spec.rb47
-rw-r--r--spec/ruby/core/encoding/name_list_spec.rb25
-rw-r--r--spec/ruby/core/encoding/name_spec.rb7
-rw-r--r--spec/ruby/core/encoding/names_spec.rb37
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb48
-rw-r--r--spec/ruby/core/encoding/shared/name.rb15
-rw-r--r--spec/ruby/core/encoding/to_s_spec.rb7
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_name_spec.rb17
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/destination_encoding_spec.rb17
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/error_char_spec.rb29
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_name_spec.rb30
-rw-r--r--spec/ruby/core/encoding/undefined_conversion_error/source_encoding_spec.rb31
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb130
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb225
-rw-r--r--spec/ruby/core/enumerable/chunk_spec.rb100
-rw-r--r--spec/ruby/core/enumerable/chunk_while_spec.rb44
-rw-r--r--spec/ruby/core/enumerable/collect_concat_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/collect_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/count_spec.rb59
-rw-r--r--spec/ruby/core/enumerable/cycle_spec.rb104
-rw-r--r--spec/ruby/core/enumerable/detect_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/drop_spec.rb43
-rw-r--r--spec/ruby/core/enumerable/drop_while_spec.rb50
-rw-r--r--spec/ruby/core/enumerable/each_cons_spec.rb99
-rw-r--r--spec/ruby/core/enumerable/each_entry_spec.rb41
-rw-r--r--spec/ruby/core/enumerable/each_slice_spec.rb101
-rw-r--r--spec/ruby/core/enumerable/each_with_index_spec.rb53
-rw-r--r--spec/ruby/core/enumerable/each_with_object_spec.rb41
-rw-r--r--spec/ruby/core/enumerable/entries_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/find_all_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/find_index_spec.rb89
-rw-r--r--spec/ruby/core/enumerable/find_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/first_spec.rb28
-rw-r--r--spec/ruby/core/enumerable/fixtures/classes.rb331
-rw-r--r--spec/ruby/core/enumerable/flat_map_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb52
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb43
-rw-r--r--spec/ruby/core/enumerable/group_by_spec.rb45
-rw-r--r--spec/ruby/core/enumerable/include_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/inject_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/lazy_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/map_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/max_by_spec.rb81
-rw-r--r--spec/ruby/core/enumerable/max_spec.rb119
-rw-r--r--spec/ruby/core/enumerable/member_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/min_by_spec.rb81
-rw-r--r--spec/ruby/core/enumerable/min_spec.rb123
-rw-r--r--spec/ruby/core/enumerable/minmax_by_spec.rb44
-rw-r--r--spec/ruby/core/enumerable/minmax_spec.rb44
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb68
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb60
-rw-r--r--spec/ruby/core/enumerable/partition_spec.rb20
-rw-r--r--spec/ruby/core/enumerable/reduce_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/reject_spec.rb25
-rw-r--r--spec/ruby/core/enumerable/reverse_each_spec.rb26
-rw-r--r--spec/ruby/core/enumerable/select_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/shared/collect.rb32
-rw-r--r--spec/ruby/core/enumerable/shared/collect_concat.rb54
-rw-r--r--spec/ruby/core/enumerable/shared/entries.rb24
-rw-r--r--spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb33
-rw-r--r--spec/ruby/core/enumerable/shared/enumeratorized.rb42
-rw-r--r--spec/ruby/core/enumerable/shared/find.rb73
-rw-r--r--spec/ruby/core/enumerable/shared/find_all.rb31
-rw-r--r--spec/ruby/core/enumerable/shared/include.rb34
-rw-r--r--spec/ruby/core/enumerable/shared/inject.rb69
-rw-r--r--spec/ruby/core/enumerable/shared/take.rb63
-rw-r--r--spec/ruby/core/enumerable/slice_after_spec.rb61
-rw-r--r--spec/ruby/core/enumerable/slice_before_spec.rb87
-rw-r--r--spec/ruby/core/enumerable/slice_when_spec.rb54
-rw-r--r--spec/ruby/core/enumerable/sort_by_spec.rb36
-rw-r--r--spec/ruby/core/enumerable/sort_spec.rb54
-rw-r--r--spec/ruby/core/enumerable/sum_spec.rb30
-rw-r--r--spec/ruby/core/enumerable/take_spec.rb13
-rw-r--r--spec/ruby/core/enumerable/take_while_spec.rb51
-rw-r--r--spec/ruby/core/enumerable/to_a_spec.rb7
-rw-r--r--spec/ruby/core/enumerable/to_h_spec.rb46
-rw-r--r--spec/ruby/core/enumerable/uniq_spec.rb94
-rw-r--r--spec/ruby/core/enumerable/zip_spec.rb42
-rw-r--r--spec/ruby/core/enumerator/each_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/each_with_index_spec.rb38
-rw-r--r--spec/ruby/core/enumerator/each_with_object_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/enum_for_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/enumerator_spec.rb7
-rw-r--r--spec/ruby/core/enumerator/feed_spec.rb52
-rw-r--r--spec/ruby/core/enumerator/first_spec.rb7
-rw-r--r--spec/ruby/core/enumerator/fixtures/common.rb9
-rw-r--r--spec/ruby/core/enumerator/generator/each_spec.rb40
-rw-r--r--spec/ruby/core/enumerator/generator/initialize_spec.rb26
-rw-r--r--spec/ruby/core/enumerator/initialize_spec.rb61
-rw-r--r--spec/ruby/core/enumerator/inject_spec.rb15
-rw-r--r--spec/ruby/core/enumerator/inspect_spec.rb17
-rw-r--r--spec/ruby/core/enumerator/lazy/collect_concat_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/collect_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/drop_spec.rb52
-rw-r--r--spec/ruby/core/enumerator/lazy/drop_while_spec.rb60
-rw-r--r--spec/ruby/core/enumerator/lazy/enum_for_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/find_all_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/fixtures/classes.rb54
-rw-r--r--spec/ruby/core/enumerator/lazy/flat_map_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/force_spec.rb30
-rw-r--r--spec/ruby/core/enumerator/lazy/grep_spec.rb82
-rw-r--r--spec/ruby/core/enumerator/lazy/grep_v_spec.rb86
-rw-r--r--spec/ruby/core/enumerator/lazy/initialize_spec.rb63
-rw-r--r--spec/ruby/core/enumerator/lazy/lazy_spec.rb16
-rw-r--r--spec/ruby/core/enumerator/lazy/map_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/reject_spec.rb60
-rw-r--r--spec/ruby/core/enumerator/lazy/select_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/collect.rb56
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/collect_concat.rb72
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/select.rb60
-rw-r--r--spec/ruby/core/enumerator/lazy/shared/to_enum.rb50
-rw-r--r--spec/ruby/core/enumerator/lazy/take_spec.rb66
-rw-r--r--spec/ruby/core/enumerator/lazy/take_while_spec.rb60
-rw-r--r--spec/ruby/core/enumerator/lazy/to_enum_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/lazy/uniq_spec.rb70
-rw-r--r--spec/ruby/core/enumerator/lazy/zip_spec.rb74
-rw-r--r--spec/ruby/core/enumerator/new_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/next_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/next_values_spec.rb55
-rw-r--r--spec/ruby/core/enumerator/peek_spec.rb36
-rw-r--r--spec/ruby/core/enumerator/peek_values_spec.rb57
-rw-r--r--spec/ruby/core/enumerator/rewind_spec.rb38
-rw-r--r--spec/ruby/core/enumerator/size_spec.rb26
-rw-r--r--spec/ruby/core/enumerator/to_enum_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/with_index_spec.rb72
-rw-r--r--spec/ruby/core/enumerator/with_object_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/yielder/append_spec.rb35
-rw-r--r--spec/ruby/core/enumerator/yielder/initialize_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/yielder/yield_spec.rb16
-rw-r--r--spec/ruby/core/env/assoc_spec.rb23
-rw-r--r--spec/ruby/core/env/clear_spec.rb20
-rw-r--r--spec/ruby/core/env/delete_if_spec.rb27
-rw-r--r--spec/ruby/core/env/delete_spec.rb24
-rw-r--r--spec/ruby/core/env/each_key_spec.rb32
-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.rb32
-rw-r--r--spec/ruby/core/env/element_reference_spec.rb66
-rw-r--r--spec/ruby/core/env/element_set_spec.rb6
-rw-r--r--spec/ruby/core/env/empty_spec.rb23
-rw-r--r--spec/ruby/core/env/fetch_spec.rb35
-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.rb6
-rw-r--r--spec/ruby/core/env/indexes_spec.rb1
-rw-r--r--spec/ruby/core/env/indices_spec.rb1
-rw-r--r--spec/ruby/core/env/inspect_spec.rb11
-rw-r--r--spec/ruby/core/env/invert_spec.rb16
-rw-r--r--spec/ruby/core/env/keep_if_spec.rb33
-rw-r--r--spec/ruby/core/env/key_spec.rb11
-rw-r--r--spec/ruby/core/env/keys_spec.rb14
-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/rassoc_spec.rb23
-rw-r--r--spec/ruby/core/env/rehash_spec.rb1
-rw-r--r--spec/ruby/core/env/reject_spec.rb77
-rw-r--r--spec/ruby/core/env/replace_spec.rb15
-rw-r--r--spec/ruby/core/env/select_spec.rb39
-rw-r--r--spec/ruby/core/env/shared/each.rb65
-rw-r--r--spec/ruby/core/env/shared/include.rb11
-rw-r--r--spec/ruby/core/env/shared/key.rb15
-rw-r--r--spec/ruby/core/env/shared/length.rb13
-rw-r--r--spec/ruby/core/env/shared/store.rb56
-rw-r--r--spec/ruby/core/env/shared/to_hash.rb22
-rw-r--r--spec/ruby/core/env/shared/value.rb11
-rw-r--r--spec/ruby/core/env/shift_spec.rb59
-rw-r--r--spec/ruby/core/env/size_spec.rb6
-rw-r--r--spec/ruby/core/env/store_spec.rb6
-rw-r--r--spec/ruby/core/env/to_a_spec.rb19
-rw-r--r--spec/ruby/core/env/to_h_spec.rb6
-rw-r--r--spec/ruby/core/env/to_hash_spec.rb6
-rw-r--r--spec/ruby/core/env/to_s_spec.rb7
-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.rb17
-rw-r--r--spec/ruby/core/env/values_spec.rb21
-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_spec.rb68
-rw-r--r--spec/ruby/core/exception/case_compare_spec.rb5
-rw-r--r--spec/ruby/core/exception/cause_spec.rb19
-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/equal_value_spec.rb68
-rw-r--r--spec/ruby/core/exception/errno_spec.rb48
-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.rb83
-rw-r--r--spec/ruby/core/exception/exit_value_spec.rb5
-rw-r--r--spec/ruby/core/exception/fixtures/common.rb64
-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.rb20
-rw-r--r--spec/ruby/core/exception/interrupt_spec.rb41
-rw-r--r--spec/ruby/core/exception/io_error_spec.rb51
-rw-r--r--spec/ruby/core/exception/load_error_spec.rb21
-rw-r--r--spec/ruby/core/exception/message_spec.rb27
-rw-r--r--spec/ruby/core/exception/name_error_spec.rb13
-rw-r--r--spec/ruby/core/exception/name_spec.rb61
-rw-r--r--spec/ruby/core/exception/new_spec.rb7
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb59
-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.rb5
-rw-r--r--spec/ruby/core/exception/receiver_spec.rb62
-rw-r--r--spec/ruby/core/exception/result_spec.rb29
-rw-r--r--spec/ruby/core/exception/script_error_spec.rb15
-rw-r--r--spec/ruby/core/exception/set_backtrace_spec.rb56
-rw-r--r--spec/ruby/core/exception/shared/new.rb18
-rw-r--r--spec/ruby/core/exception/signal_exception_spec.rb74
-rw-r--r--spec/ruby/core/exception/signm_spec.rb5
-rw-r--r--spec/ruby/core/exception/signo_spec.rb5
-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.rb50
-rw-r--r--spec/ruby/core/exception/status_spec.rb5
-rw-r--r--spec/ruby/core/exception/success_spec.rb5
-rw-r--r--spec/ruby/core/exception/system_call_error_spec.rb89
-rw-r--r--spec/ruby/core/exception/system_stack_error_spec.rb7
-rw-r--r--spec/ruby/core/exception/to_s_spec.rb23
-rw-r--r--spec/ruby/core/exception/uncaught_throw_error_spec.rb19
-rw-r--r--spec/ruby/core/false/and_spec.rb11
-rw-r--r--spec/ruby/core/false/dup_spec.rb9
-rw-r--r--spec/ruby/core/false/falseclass_spec.rb15
-rw-r--r--spec/ruby/core/false/inspect_spec.rb7
-rw-r--r--spec/ruby/core/false/or_spec.rb11
-rw-r--r--spec/ruby/core/false/to_s_spec.rb7
-rw-r--r--spec/ruby/core/false/xor_spec.rb11
-rw-r--r--spec/ruby/core/fiber/new_spec.rb41
-rw-r--r--spec/ruby/core/fiber/resume_spec.rb54
-rw-r--r--spec/ruby/core/fiber/yield_spec.rb51
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb37
-rw-r--r--spec/ruby/core/file/atime_spec.rb55
-rw-r--r--spec/ruby/core/file/basename_spec.rb170
-rw-r--r--spec/ruby/core/file/birthtime_spec.rb56
-rw-r--r--spec/ruby/core/file/blockdev_spec.rb6
-rw-r--r--spec/ruby/core/file/chardev_spec.rb6
-rw-r--r--spec/ruby/core/file/chmod_spec.rb239
-rw-r--r--spec/ruby/core/file/chown_spec.rb152
-rw-r--r--spec/ruby/core/file/constants/constants_spec.rb31
-rw-r--r--spec/ruby/core/file/constants_spec.rb141
-rw-r--r--spec/ruby/core/file/ctime_spec.rb51
-rw-r--r--spec/ruby/core/file/delete_spec.rb6
-rw-r--r--spec/ruby/core/file/directory_spec.rb10
-rw-r--r--spec/ruby/core/file/dirname_spec.rb108
-rw-r--r--spec/ruby/core/file/empty_spec.rb15
-rw-r--r--spec/ruby/core/file/executable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/executable_spec.rb7
-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.rb242
-rw-r--r--spec/ruby/core/file/extname_spec.rb54
-rw-r--r--spec/ruby/core/file/file_spec.rb16
-rw-r--r--spec/ruby/core/file/fixtures/common.rb22
-rw-r--r--spec/ruby/core/file/fixtures/do_not_remove1
-rw-r--r--spec/ruby/core/file/fixtures/file_types.rb64
-rw-r--r--spec/ruby/core/file/flock_spec.rb106
-rw-r--r--spec/ruby/core/file/fnmatch_spec.rb10
-rw-r--r--spec/ruby/core/file/ftype_spec.rb73
-rw-r--r--spec/ruby/core/file/grpowned_spec.rb10
-rw-r--r--spec/ruby/core/file/identical_spec.rb6
-rw-r--r--spec/ruby/core/file/initialize_spec.rb23
-rw-r--r--spec/ruby/core/file/inspect_spec.rb17
-rw-r--r--spec/ruby/core/file/join_spec.rb139
-rw-r--r--spec/ruby/core/file/lchmod_spec.rb42
-rw-r--r--spec/ruby/core/file/lchown_spec.rb63
-rw-r--r--spec/ruby/core/file/link_spec.rb39
-rw-r--r--spec/ruby/core/file/lstat_spec.rb33
-rw-r--r--spec/ruby/core/file/mkfifo_spec.rb53
-rw-r--r--spec/ruby/core/file/mtime_spec.rb51
-rw-r--r--spec/ruby/core/file/new_spec.rb162
-rw-r--r--spec/ruby/core/file/null_spec.rb15
-rw-r--r--spec/ruby/core/file/open_spec.rb678
-rw-r--r--spec/ruby/core/file/owned_spec.rb33
-rw-r--r--spec/ruby/core/file/path_spec.rb29
-rw-r--r--spec/ruby/core/file/pipe_spec.rb32
-rw-r--r--spec/ruby/core/file/printf_spec.rb18
-rw-r--r--spec/ruby/core/file/read_spec.rb6
-rw-r--r--spec/ruby/core/file/readable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/readable_spec.rb7
-rw-r--r--spec/ruby/core/file/readlink_spec.rb86
-rw-r--r--spec/ruby/core/file/realdirpath_spec.rb104
-rw-r--r--spec/ruby/core/file/realpath_spec.rb88
-rw-r--r--spec/ruby/core/file/rename_spec.rb37
-rw-r--r--spec/ruby/core/file/reopen_spec.rb32
-rw-r--r--spec/ruby/core/file/setgid_spec.rb36
-rw-r--r--spec/ruby/core/file/setuid_spec.rb38
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb241
-rw-r--r--spec/ruby/core/file/shared/open.rb12
-rw-r--r--spec/ruby/core/file/shared/read.rb15
-rw-r--r--spec/ruby/core/file/shared/stat.rb32
-rw-r--r--spec/ruby/core/file/shared/unlink.rb63
-rw-r--r--spec/ruby/core/file/size_spec.rb119
-rw-r--r--spec/ruby/core/file/socket_spec.rb42
-rw-r--r--spec/ruby/core/file/split_spec.rb63
-rw-r--r--spec/ruby/core/file/stat/atime_spec.rb18
-rw-r--r--spec/ruby/core/file/stat/birthtime_spec.rb27
-rw-r--r--spec/ruby/core/file/stat/blksize_spec.rb27
-rw-r--r--spec/ruby/core/file/stat/blockdev_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/blocks_spec.rb27
-rw-r--r--spec/ruby/core/file/stat/chardev_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/comparison_spec.rb66
-rw-r--r--spec/ruby/core/file/stat/ctime_spec.rb18
-rw-r--r--spec/ruby/core/file/stat/dev_major_spec.rb23
-rw-r--r--spec/ruby/core/file/stat/dev_minor_spec.rb23
-rw-r--r--spec/ruby/core/file/stat/dev_spec.rb15
-rw-r--r--spec/ruby/core/file/stat/directory_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/executable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/executable_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/file_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/fixtures/classes.rb5
-rw-r--r--spec/ruby/core/file/stat/ftype_spec.rb68
-rw-r--r--spec/ruby/core/file/stat/gid_spec.rb19
-rw-r--r--spec/ruby/core/file/stat/grpowned_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/ino_spec.rb38
-rw-r--r--spec/ruby/core/file/stat/inspect_spec.rb26
-rw-r--r--spec/ruby/core/file/stat/mode_spec.rb19
-rw-r--r--spec/ruby/core/file/stat/mtime_spec.rb18
-rw-r--r--spec/ruby/core/file/stat/new_spec.rb32
-rw-r--r--spec/ruby/core/file/stat/nlink_spec.rb21
-rw-r--r--spec/ruby/core/file/stat/owned_spec.rb31
-rw-r--r--spec/ruby/core/file/stat/pipe_spec.rb32
-rw-r--r--spec/ruby/core/file/stat/rdev_major_spec.rb31
-rw-r--r--spec/ruby/core/file/stat/rdev_minor_spec.rb31
-rw-r--r--spec/ruby/core/file/stat/rdev_spec.rb15
-rw-r--r--spec/ruby/core/file/stat/readable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/readable_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/setgid_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/setuid_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/size_spec.rb21
-rw-r--r--spec/ruby/core/file/stat/socket_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/sticky_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/symlink_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/uid_spec.rb18
-rw-r--r--spec/ruby/core/file/stat/world_readable_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/world_writable_spec.rb11
-rw-r--r--spec/ruby/core/file/stat/writable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/writable_spec.rb7
-rw-r--r--spec/ruby/core/file/stat/zero_spec.rb7
-rw-r--r--spec/ruby/core/file/stat_spec.rb45
-rw-r--r--spec/ruby/core/file/sticky_spec.rb50
-rw-r--r--spec/ruby/core/file/symlink_spec.rb57
-rw-r--r--spec/ruby/core/file/to_path_spec.rb49
-rw-r--r--spec/ruby/core/file/truncate_spec.rb177
-rw-r--r--spec/ruby/core/file/umask_spec.rb60
-rw-r--r--spec/ruby/core/file/unlink_spec.rb6
-rw-r--r--spec/ruby/core/file/utime_spec.rb47
-rw-r--r--spec/ruby/core/file/world_readable_spec.rb12
-rw-r--r--spec/ruby/core/file/world_writable_spec.rb12
-rw-r--r--spec/ruby/core/file/writable_real_spec.rb7
-rw-r--r--spec/ruby/core/file/writable_spec.rb7
-rw-r--r--spec/ruby/core/file/zero_spec.rb13
-rw-r--r--spec/ruby/core/filetest/blockdev_spec.rb6
-rw-r--r--spec/ruby/core/filetest/chardev_spec.rb6
-rw-r--r--spec/ruby/core/filetest/directory_spec.rb10
-rw-r--r--spec/ruby/core/filetest/executable_real_spec.rb7
-rw-r--r--spec/ruby/core/filetest/executable_spec.rb7
-rw-r--r--spec/ruby/core/filetest/exist_spec.rb6
-rw-r--r--spec/ruby/core/filetest/exists_spec.rb6
-rw-r--r--spec/ruby/core/filetest/file_spec.rb10
-rw-r--r--spec/ruby/core/filetest/grpowned_spec.rb10
-rw-r--r--spec/ruby/core/filetest/identical_spec.rb6
-rw-r--r--spec/ruby/core/filetest/owned_spec.rb10
-rw-r--r--spec/ruby/core/filetest/pipe_spec.rb10
-rw-r--r--spec/ruby/core/filetest/readable_real_spec.rb7
-rw-r--r--spec/ruby/core/filetest/readable_spec.rb7
-rw-r--r--spec/ruby/core/filetest/setgid_spec.rb10
-rw-r--r--spec/ruby/core/filetest/setuid_spec.rb10
-rw-r--r--spec/ruby/core/filetest/size_spec.rb34
-rw-r--r--spec/ruby/core/filetest/socket_spec.rb10
-rw-r--r--spec/ruby/core/filetest/sticky_spec.rb7
-rw-r--r--spec/ruby/core/filetest/symlink_spec.rb10
-rw-r--r--spec/ruby/core/filetest/world_readable_spec.rb5
-rw-r--r--spec/ruby/core/filetest/world_writable_spec.rb5
-rw-r--r--spec/ruby/core/filetest/writable_real_spec.rb7
-rw-r--r--spec/ruby/core/filetest/writable_spec.rb7
-rw-r--r--spec/ruby/core/filetest/zero_spec.rb13
-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.rb31
-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.rb5
-rw-r--r--spec/ruby/core/float/arg_spec.rb5
-rw-r--r--spec/ruby/core/float/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/float/ceil_spec.rb23
-rw-r--r--spec/ruby/core/float/coerce_spec.rb18
-rw-r--r--spec/ruby/core/float/comparison_spec.rb36
-rw-r--r--spec/ruby/core/float/constants_spec.rb55
-rw-r--r--spec/ruby/core/float/denominator_spec.rb29
-rw-r--r--spec/ruby/core/float/divide_spec.rb36
-rw-r--r--spec/ruby/core/float/divmod_spec.rb43
-rw-r--r--spec/ruby/core/float/dup_spec.rb10
-rw-r--r--spec/ruby/core/float/eql_spec.rb16
-rw-r--r--spec/ruby/core/float/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/float/exponent_spec.rb15
-rw-r--r--spec/ruby/core/float/fdiv_spec.rb6
-rw-r--r--spec/ruby/core/float/finite_spec.rb19
-rw-r--r--spec/ruby/core/float/fixtures/coerce.rb15
-rw-r--r--spec/ruby/core/float/float_spec.rb19
-rw-r--r--spec/ruby/core/float/floor_spec.rb23
-rw-r--r--spec/ruby/core/float/gt_spec.rb14
-rw-r--r--spec/ruby/core/float/gte_spec.rb14
-rw-r--r--spec/ruby/core/float/hash_spec.rb11
-rw-r--r--spec/ruby/core/float/infinite_spec.rb19
-rw-r--r--spec/ruby/core/float/lt_spec.rb14
-rw-r--r--spec/ruby/core/float/lte_spec.rb15
-rw-r--r--spec/ruby/core/float/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/float/minus_spec.rb9
-rw-r--r--spec/ruby/core/float/modulo_spec.rb10
-rw-r--r--spec/ruby/core/float/multiply_spec.rb14
-rw-r--r--spec/ruby/core/float/nan_spec.rb9
-rw-r--r--spec/ruby/core/float/next_float_spec.rb49
-rw-r--r--spec/ruby/core/float/numerator_spec.rb39
-rw-r--r--spec/ruby/core/float/phase_spec.rb5
-rw-r--r--spec/ruby/core/float/plus_spec.rb9
-rw-r--r--spec/ruby/core/float/prev_float_spec.rb49
-rw-r--r--spec/ruby/core/float/quo_spec.rb6
-rw-r--r--spec/ruby/core/float/rationalize_spec.rb43
-rw-r--r--spec/ruby/core/float/round_spec.rb101
-rw-r--r--spec/ruby/core/float/shared/abs.rb21
-rw-r--r--spec/ruby/core/float/shared/equal.rb17
-rw-r--r--spec/ruby/core/float/shared/modulo.rb48
-rw-r--r--spec/ruby/core/float/shared/quo.rb59
-rw-r--r--spec/ruby/core/float/shared/to_i.rb10
-rw-r--r--spec/ruby/core/float/to_f_spec.rb9
-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.rb5
-rw-r--r--spec/ruby/core/float/to_s_spec.rb120
-rw-r--r--spec/ruby/core/float/truncate_spec.rb16
-rw-r--r--spec/ruby/core/float/uminus_spec.rb28
-rw-r--r--spec/ruby/core/float/uplus_spec.rb9
-rw-r--r--spec/ruby/core/float/zero_spec.rb9
-rw-r--r--spec/ruby/core/gc/count_spec.rb7
-rw-r--r--spec/ruby/core/gc/disable_spec.rb18
-rw-r--r--spec/ruby/core/gc/enable_spec.rb13
-rw-r--r--spec/ruby/core/gc/garbage_collect_spec.rb15
-rw-r--r--spec/ruby/core/gc/profiler/clear_spec.rb5
-rw-r--r--spec/ruby/core/gc/profiler/disable_spec.rb16
-rw-r--r--spec/ruby/core/gc/profiler/enable_spec.rb17
-rw-r--r--spec/ruby/core/gc/profiler/enabled_spec.rb21
-rw-r--r--spec/ruby/core/gc/profiler/report_spec.rb5
-rw-r--r--spec/ruby/core/gc/profiler/result_spec.rb7
-rw-r--r--spec/ruby/core/gc/profiler/total_time_spec.rb7
-rw-r--r--spec/ruby/core/gc/start_spec.rb8
-rw-r--r--spec/ruby/core/gc/stress_spec.rb27
-rw-r--r--spec/ruby/core/hash/allocate_spec.rb15
-rw-r--r--spec/ruby/core/hash/any_spec.rb30
-rw-r--r--spec/ruby/core/hash/assoc_spec.rb50
-rw-r--r--spec/ruby/core/hash/clear_spec.rb32
-rw-r--r--spec/ruby/core/hash/clone_spec.rb13
-rw-r--r--spec/ruby/core/hash/compact_spec.rb61
-rw-r--r--spec/ruby/core/hash/compare_by_identity_spec.rb140
-rw-r--r--spec/ruby/core/hash/constructor_spec.rb110
-rw-r--r--spec/ruby/core/hash/default_proc_spec.rb80
-rw-r--r--spec/ruby/core/hash/default_spec.rb46
-rw-r--r--spec/ruby/core/hash/delete_if_spec.rb44
-rw-r--r--spec/ruby/core/hash/delete_spec.rb44
-rw-r--r--spec/ruby/core/hash/dig_spec.rb68
-rw-r--r--spec/ruby/core/hash/each_key_spec.rb23
-rw-r--r--spec/ruby/core/hash/each_pair_spec.rb11
-rw-r--r--spec/ruby/core/hash/each_spec.rb11
-rw-r--r--spec/ruby/core/hash/each_value_spec.rb23
-rw-r--r--spec/ruby/core/hash/element_reference_spec.rb120
-rw-r--r--spec/ruby/core/hash/element_set_spec.rb7
-rw-r--r--spec/ruby/core/hash/empty_spec.rb15
-rw-r--r--spec/ruby/core/hash/eql_spec.rb9
-rw-r--r--spec/ruby/core/hash/equal_value_spec.rb18
-rw-r--r--spec/ruby/core/hash/fetch_spec.rb36
-rw-r--r--spec/ruby/core/hash/fetch_values_spec.rb35
-rw-r--r--spec/ruby/core/hash/fixtures/classes.rb68
-rw-r--r--spec/ruby/core/hash/flatten_spec.rb62
-rw-r--r--spec/ruby/core/hash/gt_spec.rb44
-rw-r--r--spec/ruby/core/hash/gte_spec.rb44
-rw-r--r--spec/ruby/core/hash/has_key_spec.rb8
-rw-r--r--spec/ruby/core/hash/has_value_spec.rb8
-rw-r--r--spec/ruby/core/hash/hash_spec.rb36
-rw-r--r--spec/ruby/core/hash/include_spec.rb7
-rw-r--r--spec/ruby/core/hash/index_spec.rb7
-rw-r--r--spec/ruby/core/hash/initialize_spec.rb40
-rw-r--r--spec/ruby/core/hash/inspect_spec.rb7
-rw-r--r--spec/ruby/core/hash/invert_spec.rb27
-rw-r--r--spec/ruby/core/hash/keep_if_spec.rb37
-rw-r--r--spec/ruby/core/hash/key_spec.rb12
-rw-r--r--spec/ruby/core/hash/keys_spec.rb23
-rw-r--r--spec/ruby/core/hash/length_spec.rb7
-rw-r--r--spec/ruby/core/hash/lt_spec.rb44
-rw-r--r--spec/ruby/core/hash/lte_spec.rb44
-rw-r--r--spec/ruby/core/hash/member_spec.rb7
-rw-r--r--spec/ruby/core/hash/merge_spec.rb77
-rw-r--r--spec/ruby/core/hash/new_spec.rb36
-rw-r--r--spec/ruby/core/hash/rassoc_spec.rb42
-rw-r--r--spec/ruby/core/hash/rehash_spec.rb42
-rw-r--r--spec/ruby/core/hash/reject_spec.rb100
-rw-r--r--spec/ruby/core/hash/replace_spec.rb7
-rw-r--r--spec/ruby/core/hash/select_spec.rb83
-rw-r--r--spec/ruby/core/hash/shared/comparison.rb15
-rw-r--r--spec/ruby/core/hash/shared/each.rb68
-rw-r--r--spec/ruby/core/hash/shared/eql.rb216
-rw-r--r--spec/ruby/core/hash/shared/equal.rb90
-rw-r--r--spec/ruby/core/hash/shared/greater_than.rb23
-rw-r--r--spec/ruby/core/hash/shared/index.rb27
-rw-r--r--spec/ruby/core/hash/shared/iteration.rb19
-rw-r--r--spec/ruby/core/hash/shared/key.rb38
-rw-r--r--spec/ruby/core/hash/shared/length.rb12
-rw-r--r--spec/ruby/core/hash/shared/less_than.rb23
-rw-r--r--spec/ruby/core/hash/shared/replace.rb51
-rw-r--r--spec/ruby/core/hash/shared/store.rb98
-rw-r--r--spec/ruby/core/hash/shared/to_s.rb109
-rw-r--r--spec/ruby/core/hash/shared/update.rb59
-rw-r--r--spec/ruby/core/hash/shared/value.rb14
-rw-r--r--spec/ruby/core/hash/shared/values_at.rb9
-rw-r--r--spec/ruby/core/hash/shift_spec.rb64
-rw-r--r--spec/ruby/core/hash/size_spec.rb7
-rw-r--r--spec/ruby/core/hash/slice_spec.rb36
-rw-r--r--spec/ruby/core/hash/sort_spec.rb17
-rw-r--r--spec/ruby/core/hash/store_spec.rb7
-rw-r--r--spec/ruby/core/hash/to_a_spec.rb37
-rw-r--r--spec/ruby/core/hash/to_h_spec.rb34
-rw-r--r--spec/ruby/core/hash/to_hash_spec.rb14
-rw-r--r--spec/ruby/core/hash/to_proc_spec.rb89
-rw-r--r--spec/ruby/core/hash/to_s_spec.rb7
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb110
-rw-r--r--spec/ruby/core/hash/transform_values_spec.rb99
-rw-r--r--spec/ruby/core/hash/try_convert_spec.rb50
-rw-r--r--spec/ruby/core/hash/update_spec.rb7
-rw-r--r--spec/ruby/core/hash/value_spec.rb8
-rw-r--r--spec/ruby/core/hash/values_at_spec.rb7
-rw-r--r--spec/ruby/core/hash/values_spec.rb10
-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/ceil_spec.rb21
-rw-r--r--spec/ruby/core/integer/chr_spec.rb239
-rw-r--r--spec/ruby/core/integer/denominator_spec.rb20
-rw-r--r--spec/ruby/core/integer/digits_spec.rb34
-rw-r--r--spec/ruby/core/integer/downto_spec.rb69
-rw-r--r--spec/ruby/core/integer/dup_spec.rb10
-rw-r--r--spec/ruby/core/integer/even_spec.rb20
-rw-r--r--spec/ruby/core/integer/floor_spec.rb21
-rw-r--r--spec/ruby/core/integer/gcd_spec.rb58
-rw-r--r--spec/ruby/core/integer/gcdlcm_spec.rb53
-rw-r--r--spec/ruby/core/integer/integer_spec.rb22
-rw-r--r--spec/ruby/core/integer/lcm_spec.rb58
-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.rb18
-rw-r--r--spec/ruby/core/integer/odd_spec.rb18
-rw-r--r--spec/ruby/core/integer/ord_spec.rb17
-rw-r--r--spec/ruby/core/integer/pred_spec.rb11
-rw-r--r--spec/ruby/core/integer/rationalize_spec.rb39
-rw-r--r--spec/ruby/core/integer/round_spec.rb95
-rw-r--r--spec/ruby/core/integer/shared/integer_rounding.rb31
-rw-r--r--spec/ruby/core/integer/shared/next.rb25
-rw-r--r--spec/ruby/core/integer/shared/to_i.rb8
-rw-r--r--spec/ruby/core/integer/sqrt_spec.rb33
-rw-r--r--spec/ruby/core/integer/succ_spec.rb6
-rw-r--r--spec/ruby/core/integer/times_spec.rb79
-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.rb26
-rw-r--r--spec/ruby/core/integer/truncate_spec.rb21
-rw-r--r--spec/ruby/core/integer/upto_spec.rb69
-rw-r--r--spec/ruby/core/io/advise_spec.rb97
-rw-r--r--spec/ruby/core/io/binmode_spec.rb60
-rw-r--r--spec/ruby/core/io/binread_spec.rb49
-rw-r--r--spec/ruby/core/io/binwrite_spec.rb8
-rw-r--r--spec/ruby/core/io/bytes_spec.rb43
-rw-r--r--spec/ruby/core/io/chars_spec.rb12
-rw-r--r--spec/ruby/core/io/close_on_exec_spec.rb100
-rw-r--r--spec/ruby/core/io/close_read_spec.rb80
-rw-r--r--spec/ruby/core/io/close_spec.rb82
-rw-r--r--spec/ruby/core/io/close_write_spec.rb84
-rw-r--r--spec/ruby/core/io/closed_spec.rb20
-rw-r--r--spec/ruby/core/io/codepoints_spec.rb25
-rw-r--r--spec/ruby/core/io/constants_spec.rb19
-rw-r--r--spec/ruby/core/io/copy_stream_spec.rb282
-rw-r--r--spec/ruby/core/io/dup_spec.rb69
-rw-r--r--spec/ruby/core/io/each_byte_spec.rb57
-rw-r--r--spec/ruby/core/io/each_char_spec.rb12
-rw-r--r--spec/ruby/core/io/each_codepoint_spec.rb45
-rw-r--r--spec/ruby/core/io/each_line_spec.rb11
-rw-r--r--spec/ruby/core/io/each_spec.rb11
-rw-r--r--spec/ruby/core/io/eof_spec.rb107
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb218
-rw-r--r--spec/ruby/core/io/fcntl_spec.rb8
-rw-r--r--spec/ruby/core/io/fdatasync_spec.rb5
-rw-r--r--spec/ruby/core/io/fileno_spec.rb12
-rw-r--r--spec/ruby/core/io/fixtures/bom_UTF-16BE.txtbin0 -> 20 bytes-rw-r--r--spec/ruby/core/io/fixtures/bom_UTF-16LE.txtbin0 -> 20 bytes-rw-r--r--spec/ruby/core/io/fixtures/bom_UTF-32BE.txtbin0 -> 40 bytes-rw-r--r--spec/ruby/core/io/fixtures/bom_UTF-32LE.txtbin0 -> 40 bytes-rw-r--r--spec/ruby/core/io/fixtures/bom_UTF-8.txt1
-rw-r--r--spec/ruby/core/io/fixtures/classes.rb189
-rw-r--r--spec/ruby/core/io/fixtures/copy_stream.txt6
-rw-r--r--spec/ruby/core/io/fixtures/empty.txt0
-rw-r--r--spec/ruby/core/io/fixtures/incomplete.txt1
-rw-r--r--spec/ruby/core/io/fixtures/lines.txt9
-rw-r--r--spec/ruby/core/io/fixtures/no_bom_UTF-8.txt1
-rw-r--r--spec/ruby/core/io/fixtures/numbered_lines.txt5
-rw-r--r--spec/ruby/core/io/fixtures/one_byte.txt1
-rw-r--r--spec/ruby/core/io/fixtures/read_binary.txt1
-rw-r--r--spec/ruby/core/io/fixtures/read_euc_jp.txt1
-rw-r--r--spec/ruby/core/io/fixtures/read_text.txt1
-rw-r--r--spec/ruby/core/io/fixtures/reopen_stdout.rb3
-rw-r--r--spec/ruby/core/io/flush_spec.rb8
-rw-r--r--spec/ruby/core/io/for_fd_spec.rb10
-rw-r--r--spec/ruby/core/io/foreach_spec.rb81
-rw-r--r--spec/ruby/core/io/fsync_spec.rb24
-rw-r--r--spec/ruby/core/io/getbyte_spec.rb42
-rw-r--r--spec/ruby/core/io/getc_spec.rb42
-rw-r--r--spec/ruby/core/io/gets_spec.rb321
-rw-r--r--spec/ruby/core/io/initialize_spec.rb53
-rw-r--r--spec/ruby/core/io/inspect_spec.rb23
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb140
-rw-r--r--spec/ruby/core/io/io_spec.rb11
-rw-r--r--spec/ruby/core/io/ioctl_spec.rb32
-rw-r--r--spec/ruby/core/io/isatty_spec.rb6
-rw-r--r--spec/ruby/core/io/lineno_spec.rb95
-rw-r--r--spec/ruby/core/io/lines_spec.rb42
-rw-r--r--spec/ruby/core/io/new_spec.rb10
-rw-r--r--spec/ruby/core/io/open_spec.rb86
-rw-r--r--spec/ruby/core/io/output_spec.rb27
-rw-r--r--spec/ruby/core/io/pid_spec.rb35
-rw-r--r--spec/ruby/core/io/pipe_spec.rb214
-rw-r--r--spec/ruby/core/io/popen_spec.rb286
-rw-r--r--spec/ruby/core/io/pos_spec.rb12
-rw-r--r--spec/ruby/core/io/print_spec.rb54
-rw-r--r--spec/ruby/core/io/printf_spec.rb32
-rw-r--r--spec/ruby/core/io/putc_spec.rb11
-rw-r--r--spec/ruby/core/io/puts_spec.rb141
-rw-r--r--spec/ruby/core/io/read_nonblock_spec.rb95
-rw-r--r--spec/ruby/core/io/read_spec.rb616
-rw-r--r--spec/ruby/core/io/readbyte_spec.rb26
-rw-r--r--spec/ruby/core/io/readchar_spec.rb44
-rw-r--r--spec/ruby/core/io/readline_spec.rb53
-rw-r--r--spec/ruby/core/io/readlines_spec.rb210
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb96
-rw-r--r--spec/ruby/core/io/reopen_spec.rb302
-rw-r--r--spec/ruby/core/io/rewind_spec.rb38
-rw-r--r--spec/ruby/core/io/seek_spec.rb79
-rw-r--r--spec/ruby/core/io/select_spec.rb116
-rw-r--r--spec/ruby/core/io/set_encoding_spec.rb193
-rw-r--r--spec/ruby/core/io/shared/binwrite.rb78
-rw-r--r--spec/ruby/core/io/shared/chars.rb73
-rw-r--r--spec/ruby/core/io/shared/codepoints.rb54
-rw-r--r--spec/ruby/core/io/shared/each.rb185
-rw-r--r--spec/ruby/core/io/shared/gets_ascii.rb19
-rw-r--r--spec/ruby/core/io/shared/new.rb378
-rw-r--r--spec/ruby/core/io/shared/pos.rb72
-rw-r--r--spec/ruby/core/io/shared/readlines.rb211
-rw-r--r--spec/ruby/core/io/shared/tty.rb25
-rw-r--r--spec/ruby/core/io/shared/write.rb72
-rw-r--r--spec/ruby/core/io/stat_spec.rb24
-rw-r--r--spec/ruby/core/io/sync_spec.rb64
-rw-r--r--spec/ruby/core/io/sysopen_spec.rb50
-rw-r--r--spec/ruby/core/io/sysread_spec.rb98
-rw-r--r--spec/ruby/core/io/sysseek_spec.rb44
-rw-r--r--spec/ruby/core/io/syswrite_spec.rb54
-rw-r--r--spec/ruby/core/io/tell_spec.rb7
-rw-r--r--spec/ruby/core/io/to_i_spec.rb12
-rw-r--r--spec/ruby/core/io/to_io_spec.rb21
-rw-r--r--spec/ruby/core/io/try_convert_spec.rb49
-rw-r--r--spec/ruby/core/io/tty_spec.rb6
-rw-r--r--spec/ruby/core/io/ungetbyte_spec.rb48
-rw-r--r--spec/ruby/core/io/ungetc_spec.rb119
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb86
-rw-r--r--spec/ruby/core/io/write_spec.rb157
-rw-r--r--spec/ruby/core/kernel/Array_spec.rb97
-rw-r--r--spec/ruby/core/kernel/Complex_spec.rb6
-rw-r--r--spec/ruby/core/kernel/Float_spec.rb316
-rw-r--r--spec/ruby/core/kernel/Hash_spec.rb57
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb697
-rw-r--r--spec/ruby/core/kernel/Rational_spec.rb6
-rw-r--r--spec/ruby/core/kernel/String_spec.rb106
-rw-r--r--spec/ruby/core/kernel/__callee___spec.rb48
-rw-r--r--spec/ruby/core/kernel/__dir___spec.rb13
-rw-r--r--spec/ruby/core/kernel/__method___spec.rb40
-rw-r--r--spec/ruby/core/kernel/abort_spec.rb15
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb44
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb121
-rw-r--r--spec/ruby/core/kernel/backtick_spec.rb80
-rw-r--r--spec/ruby/core/kernel/binding_spec.rb51
-rw-r--r--spec/ruby/core/kernel/block_given_spec.rb38
-rw-r--r--spec/ruby/core/kernel/caller_locations_spec.rb32
-rw-r--r--spec/ruby/core/kernel/caller_spec.rb37
-rw-r--r--spec/ruby/core/kernel/case_compare_spec.rb135
-rw-r--r--spec/ruby/core/kernel/catch_spec.rb127
-rw-r--r--spec/ruby/core/kernel/chomp_spec.rb67
-rw-r--r--spec/ruby/core/kernel/chop_spec.rb55
-rw-r--r--spec/ruby/core/kernel/class_spec.rb26
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb118
-rw-r--r--spec/ruby/core/kernel/comparison_spec.rb31
-rw-r--r--spec/ruby/core/kernel/define_singleton_method_spec.rb101
-rw-r--r--spec/ruby/core/kernel/display_spec.rb6
-rw-r--r--spec/ruby/core/kernel/dup_spec.rb67
-rw-r--r--spec/ruby/core/kernel/enum_for_spec.rb5
-rw-r--r--spec/ruby/core/kernel/eql_spec.rb11
-rw-r--r--spec/ruby/core/kernel/equal_value_spec.rb15
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb216
-rw-r--r--spec/ruby/core/kernel/exec_spec.rb18
-rw-r--r--spec/ruby/core/kernel/exit_spec.rb27
-rw-r--r--spec/ruby/core/kernel/extend_spec.rb79
-rw-r--r--spec/ruby/core/kernel/fail_spec.rb43
-rw-r--r--spec/ruby/core/kernel/fixtures/__callee__.rb34
-rw-r--r--spec/ruby/core/kernel/fixtures/__method__.rb34
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_b.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_c.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_d.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_frozen.rb7
-rw-r--r--spec/ruby/core/kernel/fixtures/caller.rb7
-rw-r--r--spec/ruby/core/kernel/fixtures/caller_locations.rb7
-rw-r--r--spec/ruby/core/kernel/fixtures/chomp.rb4
-rw-r--r--spec/ruby/core/kernel/fixtures/chomp_f.rb4
-rw-r--r--spec/ruby/core/kernel/fixtures/chop.rb4
-rw-r--r--spec/ruby/core/kernel/fixtures/chop_f.rb4
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb419
-rw-r--r--spec/ruby/core/kernel/fixtures/eval_locals.rb6
-rw-r--r--spec/ruby/core/kernel/fixtures/eval_return_with_lambda.rb12
-rw-r--r--spec/ruby/core/kernel/fixtures/eval_return_without_lambda.rb14
-rw-r--r--spec/ruby/core/kernel/fixtures/test.rb362
-rw-r--r--spec/ruby/core/kernel/fork_spec.rb15
-rw-r--r--spec/ruby/core/kernel/format_spec.rb14
-rw-r--r--spec/ruby/core/kernel/freeze_spec.rb85
-rw-r--r--spec/ruby/core/kernel/frozen_spec.rb78
-rw-r--r--spec/ruby/core/kernel/gets_spec.rb17
-rw-r--r--spec/ruby/core/kernel/global_variables_spec.rb26
-rw-r--r--spec/ruby/core/kernel/gsub_spec.rb96
-rw-r--r--spec/ruby/core/kernel/inspect_spec.rb31
-rw-r--r--spec/ruby/core/kernel/instance_of_spec.rb40
-rw-r--r--spec/ruby/core/kernel/instance_variable_defined_spec.rb41
-rw-r--r--spec/ruby/core/kernel/instance_variable_get_spec.rb105
-rw-r--r--spec/ruby/core/kernel/instance_variable_set_spec.rb93
-rw-r--r--spec/ruby/core/kernel/instance_variables_spec.rb27
-rw-r--r--spec/ruby/core/kernel/is_a_spec.rb6
-rw-r--r--spec/ruby/core/kernel/iterator_spec.rb12
-rw-r--r--spec/ruby/core/kernel/itself_spec.rb9
-rw-r--r--spec/ruby/core/kernel/kind_of_spec.rb6
-rw-r--r--spec/ruby/core/kernel/lambda_spec.rb86
-rw-r--r--spec/ruby/core/kernel/load_spec.rb40
-rw-r--r--spec/ruby/core/kernel/local_variables_spec.rb37
-rw-r--r--spec/ruby/core/kernel/loop_spec.rb81
-rw-r--r--spec/ruby/core/kernel/match_spec.rb14
-rw-r--r--spec/ruby/core/kernel/method_spec.rb37
-rw-r--r--spec/ruby/core/kernel/methods_spec.rb101
-rw-r--r--spec/ruby/core/kernel/nil_spec.rb6
-rw-r--r--spec/ruby/core/kernel/not_match_spec.rb21
-rw-r--r--spec/ruby/core/kernel/object_id_spec.rb6
-rw-r--r--spec/ruby/core/kernel/open_spec.rb142
-rw-r--r--spec/ruby/core/kernel/p_spec.rb79
-rw-r--r--spec/ruby/core/kernel/print_spec.rb12
-rw-r--r--spec/ruby/core/kernel/printf_spec.rb61
-rw-r--r--spec/ruby/core/kernel/private_methods_spec.rb69
-rw-r--r--spec/ruby/core/kernel/proc_spec.rb50
-rw-r--r--spec/ruby/core/kernel/protected_methods_spec.rb69
-rw-r--r--spec/ruby/core/kernel/public_method_spec.rb32
-rw-r--r--spec/ruby/core/kernel/public_methods_spec.rb76
-rw-r--r--spec/ruby/core/kernel/public_send_spec.rb108
-rw-r--r--spec/ruby/core/kernel/putc_spec.rb39
-rw-r--r--spec/ruby/core/kernel/puts_spec.rb29
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb17
-rw-r--r--spec/ruby/core/kernel/rand_spec.rb139
-rw-r--r--spec/ruby/core/kernel/readline_spec.rb12
-rw-r--r--spec/ruby/core/kernel/readlines_spec.rb12
-rw-r--r--spec/ruby/core/kernel/remove_instance_variable_spec.rb59
-rw-r--r--spec/ruby/core/kernel/require_relative_spec.rb349
-rw-r--r--spec/ruby/core/kernel/require_spec.rb36
-rw-r--r--spec/ruby/core/kernel/respond_to_missing_spec.rb100
-rw-r--r--spec/ruby/core/kernel/respond_to_spec.rb73
-rw-r--r--spec/ruby/core/kernel/select_spec.rb20
-rw-r--r--spec/ruby/core/kernel/send_spec.rb68
-rw-r--r--spec/ruby/core/kernel/set_trace_func_spec.rb12
-rw-r--r--spec/ruby/core/kernel/shared/dup_clone.rb149
-rw-r--r--spec/ruby/core/kernel/shared/kind_of.rb44
-rw-r--r--spec/ruby/core/kernel/shared/lambda.rb9
-rw-r--r--spec/ruby/core/kernel/shared/load.rb139
-rw-r--r--spec/ruby/core/kernel/shared/method.rb50
-rw-r--r--spec/ruby/core/kernel/shared/require.rb703
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb871
-rw-r--r--spec/ruby/core/kernel/shared/sprintf_encoding.rb28
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb27
-rw-r--r--spec/ruby/core/kernel/singleton_method_spec.rb41
-rw-r--r--spec/ruby/core/kernel/singleton_methods_spec.rb180
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb52
-rw-r--r--spec/ruby/core/kernel/spawn_spec.rb25
-rw-r--r--spec/ruby/core/kernel/sprintf_spec.rb24
-rw-r--r--spec/ruby/core/kernel/srand_spec.rb61
-rw-r--r--spec/ruby/core/kernel/sub_spec.rb26
-rw-r--r--spec/ruby/core/kernel/syscall_spec.rb12
-rw-r--r--spec/ruby/core/kernel/system_spec.rb107
-rw-r--r--spec/ruby/core/kernel/taint_spec.rb45
-rw-r--r--spec/ruby/core/kernel/tainted_spec.rb12
-rw-r--r--spec/ruby/core/kernel/tap_spec.rb13
-rw-r--r--spec/ruby/core/kernel/test_spec.rb109
-rw-r--r--spec/ruby/core/kernel/throw_spec.rb80
-rw-r--r--spec/ruby/core/kernel/to_enum_spec.rb5
-rw-r--r--spec/ruby/core/kernel/to_s_spec.rb16
-rw-r--r--spec/ruby/core/kernel/trace_var_spec.rb54
-rw-r--r--spec/ruby/core/kernel/trap_spec.rb12
-rw-r--r--spec/ruby/core/kernel/trust_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untaint_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untrace_var_spec.rb12
-rw-r--r--spec/ruby/core/kernel/untrust_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untrusted_spec.rb28
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb79
-rw-r--r--spec/ruby/core/kernel/yield_self_spec.rb26
-rw-r--r--spec/ruby/core/main/define_method_spec.rb28
-rw-r--r--spec/ruby/core/main/fixtures/classes.rb18
-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/fixtures/wrapped_include.rb1
-rw-r--r--spec/ruby/core/main/include_spec.rb16
-rw-r--r--spec/ruby/core/main/private_spec.rb23
-rw-r--r--spec/ruby/core/main/public_spec.rb23
-rw-r--r--spec/ruby/core/main/to_s_spec.rb7
-rw-r--r--spec/ruby/core/main/using_spec.rb135
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb582
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb420
-rw-r--r--spec/ruby/core/marshal/fixtures/random.dumpbin0 -> 2520 bytes-rw-r--r--spec/ruby/core/marshal/float_spec.rb77
-rw-r--r--spec/ruby/core/marshal/load_spec.rb6
-rw-r--r--spec/ruby/core/marshal/major_version_spec.rb7
-rw-r--r--spec/ruby/core/marshal/minor_version_spec.rb7
-rw-r--r--spec/ruby/core/marshal/restore_spec.rb6
-rw-r--r--spec/ruby/core/marshal/shared/load.rb830
-rw-r--r--spec/ruby/core/matchdata/begin_spec.rb30
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb87
-rw-r--r--spec/ruby/core/matchdata/end_spec.rb30
-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.rb5
-rw-r--r--spec/ruby/core/matchdata/inspect_spec.rb17
-rw-r--r--spec/ruby/core/matchdata/length_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/named_captures_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/names_spec.rb33
-rw-r--r--spec/ruby/core/matchdata/offset_spec.rb30
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb36
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb36
-rw-r--r--spec/ruby/core/matchdata/regexp_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/shared/eql.rb26
-rw-r--r--spec/ruby/core/matchdata/shared/length.rb5
-rw-r--r--spec/ruby/core/matchdata/size_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/string_spec.rb14
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb23
-rw-r--r--spec/ruby/core/math/acos_spec.rb58
-rw-r--r--spec/ruby/core/math/acosh_spec.rb43
-rw-r--r--spec/ruby/core/math/asin_spec.rb50
-rw-r--r--spec/ruby/core/math/asinh_spec.rb42
-rw-r--r--spec/ruby/core/math/atan2_spec.rb54
-rw-r--r--spec/ruby/core/math/atan_spec.rb40
-rw-r--r--spec/ruby/core/math/atanh_spec.rb14
-rw-r--r--spec/ruby/core/math/cbrt_spec.rb27
-rw-r--r--spec/ruby/core/math/constants_spec.rb22
-rw-r--r--spec/ruby/core/math/cos_spec.rb42
-rw-r--r--spec/ruby/core/math/cosh_spec.rb37
-rw-r--r--spec/ruby/core/math/erf_spec.rb44
-rw-r--r--spec/ruby/core/math/erfc_spec.rb43
-rw-r--r--spec/ruby/core/math/exp_spec.rb37
-rw-r--r--spec/ruby/core/math/fixtures/classes.rb28
-rw-r--r--spec/ruby/core/math/frexp_spec.rb37
-rw-r--r--spec/ruby/core/math/gamma_spec.rb69
-rw-r--r--spec/ruby/core/math/hypot_spec.rb41
-rw-r--r--spec/ruby/core/math/ldexp_spec.rb54
-rw-r--r--spec/ruby/core/math/lgamma_spec.rb56
-rw-r--r--spec/ruby/core/math/log10_spec.rb45
-rw-r--r--spec/ruby/core/math/log2_spec.rb41
-rw-r--r--spec/ruby/core/math/log_spec.rb59
-rw-r--r--spec/ruby/core/math/sin_spec.rb39
-rw-r--r--spec/ruby/core/math/sinh_spec.rb37
-rw-r--r--spec/ruby/core/math/sqrt_spec.rb36
-rw-r--r--spec/ruby/core/math/tan_spec.rb42
-rw-r--r--spec/ruby/core/math/tanh_spec.rb39
-rw-r--r--spec/ruby/core/method/arity_spec.rb222
-rw-r--r--spec/ruby/core/method/call_spec.rb7
-rw-r--r--spec/ruby/core/method/clone_spec.rb14
-rw-r--r--spec/ruby/core/method/curry_spec.rb36
-rw-r--r--spec/ruby/core/method/element_reference_spec.rb7
-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.rb184
-rw-r--r--spec/ruby/core/method/hash_spec.rb17
-rw-r--r--spec/ruby/core/method/inspect_spec.rb6
-rw-r--r--spec/ruby/core/method/name_spec.rb22
-rw-r--r--spec/ruby/core/method/owner_spec.rb26
-rw-r--r--spec/ruby/core/method/parameters_spec.rb244
-rw-r--r--spec/ruby/core/method/receiver_spec.rb22
-rw-r--r--spec/ruby/core/method/shared/call.rb51
-rw-r--r--spec/ruby/core/method/shared/eql.rb94
-rw-r--r--spec/ruby/core/method/shared/to_s.rb34
-rw-r--r--spec/ruby/core/method/source_location_spec.rb95
-rw-r--r--spec/ruby/core/method/super_method_spec.rb45
-rw-r--r--spec/ruby/core/method/to_proc_spec.rb89
-rw-r--r--spec/ruby/core/method/to_s_spec.rb6
-rw-r--r--spec/ruby/core/method/unbind_spec.rb37
-rw-r--r--spec/ruby/core/module/alias_method_spec.rb157
-rw-r--r--spec/ruby/core/module/allocate_spec.rb14
-rw-r--r--spec/ruby/core/module/ancestors_spec.rb70
-rw-r--r--spec/ruby/core/module/append_features_spec.rb73
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb97
-rw-r--r--spec/ruby/core/module/attr_reader_spec.rb71
-rw-r--r--spec/ruby/core/module/attr_spec.rb156
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb71
-rw-r--r--spec/ruby/core/module/autoload_spec.rb508
-rw-r--r--spec/ruby/core/module/case_compare_spec.rb31
-rw-r--r--spec/ruby/core/module/class_eval_spec.rb7
-rw-r--r--spec/ruby/core/module/class_exec_spec.rb7
-rw-r--r--spec/ruby/core/module/class_variable_defined_spec.rb72
-rw-r--r--spec/ruby/core/module/class_variable_get_spec.rb76
-rw-r--r--spec/ruby/core/module/class_variable_set_spec.rb62
-rw-r--r--spec/ruby/core/module/class_variables_spec.rb26
-rw-r--r--spec/ruby/core/module/comparison_spec.rb36
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb144
-rw-r--r--spec/ruby/core/module/const_get_spec.rb208
-rw-r--r--spec/ruby/core/module/const_missing_spec.rb27
-rw-r--r--spec/ruby/core/module/const_set_spec.rb86
-rw-r--r--spec/ruby/core/module/constants_spec.rb91
-rw-r--r--spec/ruby/core/module/define_method_spec.rb633
-rw-r--r--spec/ruby/core/module/define_singleton_method_spec.rb17
-rw-r--r--spec/ruby/core/module/deprecate_constant_spec.rb52
-rw-r--r--spec/ruby/core/module/eql_spec.rb7
-rw-r--r--spec/ruby/core/module/equal_spec.rb7
-rw-r--r--spec/ruby/core/module/equal_value_spec.rb7
-rw-r--r--spec/ruby/core/module/extend_object_spec.rb68
-rw-r--r--spec/ruby/core/module/extended_spec.rb44
-rw-r--r--spec/ruby/core/module/fixtures/autoload.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_abc.rb11
-rw-r--r--spec/ruby/core/module/fixtures/autoload_c.rb11
-rw-r--r--spec/ruby/core/module/fixtures/autoload_concur.rb9
-rw-r--r--spec/ruby/core/module/fixtures/autoload_d.rb11
-rw-r--r--spec/ruby/core/module/fixtures/autoload_e.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_empty.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_ex1.rb16
-rw-r--r--spec/ruby/core/module/fixtures/autoload_f.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_g.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_h.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_i.rb5
-rw-r--r--spec/ruby/core/module/fixtures/autoload_j.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_k.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_lm.rb4
-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_r.rb4
-rw-r--r--spec/ruby/core/module/fixtures/autoload_s.rb5
-rw-r--r--spec/ruby/core/module/fixtures/autoload_scope.rb8
-rw-r--r--spec/ruby/core/module/fixtures/autoload_subclass.rb11
-rw-r--r--spec/ruby/core/module/fixtures/autoload_t.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_v.rb7
-rw-r--r--spec/ruby/core/module/fixtures/autoload_w.rb2
-rw-r--r--spec/ruby/core/module/fixtures/autoload_w2.rb1
-rw-r--r--spec/ruby/core/module/fixtures/autoload_x.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_z.rb5
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb605
-rw-r--r--spec/ruby/core/module/fixtures/constant_unicode.rb5
-rw-r--r--spec/ruby/core/module/fixtures/module.rb4
-rw-r--r--spec/ruby/core/module/fixtures/name.rb10
-rw-r--r--spec/ruby/core/module/fixtures/path1/load_path.rb9
-rw-r--r--spec/ruby/core/module/fixtures/path2/load_path.rb1
-rw-r--r--spec/ruby/core/module/fixtures/refine.rb13
-rw-r--r--spec/ruby/core/module/fixtures/repeated_concurrent_autoload.rb8
-rw-r--r--spec/ruby/core/module/freeze_spec.rb6
-rw-r--r--spec/ruby/core/module/gt_spec.rb36
-rw-r--r--spec/ruby/core/module/gte_spec.rb33
-rw-r--r--spec/ruby/core/module/include_spec.rb270
-rw-r--r--spec/ruby/core/module/included_modules_spec.rb12
-rw-r--r--spec/ruby/core/module/included_spec.rb44
-rw-r--r--spec/ruby/core/module/initialize_copy_spec.rb10
-rw-r--r--spec/ruby/core/module/initialize_spec.rb18
-rw-r--r--spec/ruby/core/module/instance_method_spec.rb85
-rw-r--r--spec/ruby/core/module/instance_methods_spec.rb61
-rw-r--r--spec/ruby/core/module/lt_spec.rb36
-rw-r--r--spec/ruby/core/module/lte_spec.rb33
-rw-r--r--spec/ruby/core/module/method_added_spec.rb62
-rw-r--r--spec/ruby/core/module/method_defined_spec.rb49
-rw-r--r--spec/ruby/core/module/method_removed_spec.rb33
-rw-r--r--spec/ruby/core/module/method_undefined_spec.rb33
-rw-r--r--spec/ruby/core/module/module_eval_spec.rb7
-rw-r--r--spec/ruby/core/module/module_exec_spec.rb7
-rw-r--r--spec/ruby/core/module/module_function_spec.rb269
-rw-r--r--spec/ruby/core/module/name_spec.rb68
-rw-r--r--spec/ruby/core/module/nesting_spec.rb31
-rw-r--r--spec/ruby/core/module/new_spec.rb31
-rw-r--r--spec/ruby/core/module/prepend_features_spec.rb76
-rw-r--r--spec/ruby/core/module/prepend_spec.rb361
-rw-r--r--spec/ruby/core/module/prepended_spec.rb25
-rw-r--r--spec/ruby/core/module/private_class_method_spec.rb81
-rw-r--r--spec/ruby/core/module/private_constant_spec.rb32
-rw-r--r--spec/ruby/core/module/private_instance_methods_spec.rb54
-rw-r--r--spec/ruby/core/module/private_method_defined_spec.rb72
-rw-r--r--spec/ruby/core/module/private_spec.rb93
-rw-r--r--spec/ruby/core/module/protected_instance_methods_spec.rb57
-rw-r--r--spec/ruby/core/module/protected_method_defined_spec.rb72
-rw-r--r--spec/ruby/core/module/protected_spec.rb56
-rw-r--r--spec/ruby/core/module/public_class_method_spec.rb80
-rw-r--r--spec/ruby/core/module/public_constant_spec.rb38
-rw-r--r--spec/ruby/core/module/public_instance_method_spec.rb65
-rw-r--r--spec/ruby/core/module/public_instance_methods_spec.rb61
-rw-r--r--spec/ruby/core/module/public_method_defined_spec.rb72
-rw-r--r--spec/ruby/core/module/public_spec.rb44
-rw-r--r--spec/ruby/core/module/refine_spec.rb657
-rw-r--r--spec/ruby/core/module/remove_class_variable_spec.rb44
-rw-r--r--spec/ruby/core/module/remove_const_spec.rb84
-rw-r--r--spec/ruby/core/module/remove_method_spec.rb116
-rw-r--r--spec/ruby/core/module/shared/class_eval.rb115
-rw-r--r--spec/ruby/core/module/shared/class_exec.rb29
-rw-r--r--spec/ruby/core/module/shared/equal_value.rb14
-rw-r--r--spec/ruby/core/module/shared/set_visibility.rb135
-rw-r--r--spec/ruby/core/module/singleton_class_spec.rb27
-rw-r--r--spec/ruby/core/module/to_s_spec.rb18
-rw-r--r--spec/ruby/core/module/undef_method_spec.rb159
-rw-r--r--spec/ruby/core/module/using_spec.rb287
-rw-r--r--spec/ruby/core/mutex/lock_spec.rb41
-rw-r--r--spec/ruby/core/mutex/locked_spec.rb36
-rw-r--r--spec/ruby/core/mutex/owned_spec.rb43
-rw-r--r--spec/ruby/core/mutex/sleep_spec.rb95
-rw-r--r--spec/ruby/core/mutex/synchronize_spec.rb27
-rw-r--r--spec/ruby/core/mutex/try_lock_spec.rb32
-rw-r--r--spec/ruby/core/mutex/unlock_spec.rb38
-rw-r--r--spec/ruby/core/nil/and_spec.rb11
-rw-r--r--spec/ruby/core/nil/dup_spec.rb9
-rw-r--r--spec/ruby/core/nil/inspect_spec.rb7
-rw-r--r--spec/ruby/core/nil/nil_spec.rb7
-rw-r--r--spec/ruby/core/nil/nilclass_spec.rb15
-rw-r--r--spec/ruby/core/nil/or_spec.rb11
-rw-r--r--spec/ruby/core/nil/rationalize_spec.rb16
-rw-r--r--spec/ruby/core/nil/to_a_spec.rb7
-rw-r--r--spec/ruby/core/nil/to_c_spec.rb7
-rw-r--r--spec/ruby/core/nil/to_f_spec.rb11
-rw-r--r--spec/ruby/core/nil/to_h_spec.rb8
-rw-r--r--spec/ruby/core/nil/to_i_spec.rb11
-rw-r--r--spec/ruby/core/nil/to_r_spec.rb7
-rw-r--r--spec/ruby/core/nil/to_s_spec.rb7
-rw-r--r--spec/ruby/core/nil/xor_spec.rb11
-rw-r--r--spec/ruby/core/numeric/abs2_spec.rb34
-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.rb15
-rw-r--r--spec/ruby/core/numeric/coerce_spec.rb76
-rw-r--r--spec/ruby/core/numeric/comparison_spec.rb48
-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.rb24
-rw-r--r--spec/ruby/core/numeric/div_spec.rb22
-rw-r--r--spec/ruby/core/numeric/divmod_spec.rb15
-rw-r--r--spec/ruby/core/numeric/eql_spec.rb22
-rw-r--r--spec/ruby/core/numeric/fdiv_spec.rb32
-rw-r--r--spec/ruby/core/numeric/finite_spec.rb10
-rw-r--r--spec/ruby/core/numeric/fixtures/classes.rb17
-rw-r--r--spec/ruby/core/numeric/floor_spec.rb14
-rw-r--r--spec/ruby/core/numeric/i_spec.rb15
-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.rb10
-rw-r--r--spec/ruby/core/numeric/integer_spec.rb8
-rw-r--r--spec/ruby/core/numeric/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/numeric/modulo_spec.rb24
-rw-r--r--spec/ruby/core/numeric/negative_spec.rb43
-rw-r--r--spec/ruby/core/numeric/nonzero_spec.rb18
-rw-r--r--spec/ruby/core/numeric/numerator_spec.rb33
-rw-r--r--spec/ruby/core/numeric/numeric_spec.rb7
-rw-r--r--spec/ruby/core/numeric/phase_spec.rb6
-rw-r--r--spec/ruby/core/numeric/polar_spec.rb6
-rw-r--r--spec/ruby/core/numeric/positive_spec.rb43
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb55
-rw-r--r--spec/ruby/core/numeric/real_spec.rb13
-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.rb67
-rw-r--r--spec/ruby/core/numeric/round_spec.rb14
-rw-r--r--spec/ruby/core/numeric/shared/abs.rb19
-rw-r--r--spec/ruby/core/numeric/shared/quo.rb7
-rw-r--r--spec/ruby/core/numeric/shared/rect.rb48
-rw-r--r--spec/ruby/core/numeric/shared/step.rb425
-rw-r--r--spec/ruby/core/numeric/singleton_method_added_spec.rb41
-rw-r--r--spec/ruby/core/numeric/step_spec.rb163
-rw-r--r--spec/ruby/core/numeric/to_c_spec.rb45
-rw-r--r--spec/ruby/core/numeric/to_int_spec.rb10
-rw-r--r--spec/ruby/core/numeric/truncate_spec.rb14
-rw-r--r--spec/ruby/core/numeric/uminus_spec.rb31
-rw-r--r--spec/ruby/core/numeric/uplus_spec.rb9
-rw-r--r--spec/ruby/core/numeric/zero_spec.rb18
-rw-r--r--spec/ruby/core/objectspace/_id2ref_spec.rb25
-rw-r--r--spec/ruby/core/objectspace/add_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/call_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/count_objects_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb101
-rw-r--r--spec/ruby/core/objectspace/each_object_spec.rb225
-rw-r--r--spec/ruby/core/objectspace/finalizers_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/fixtures/classes.rb64
-rw-r--r--spec/ruby/core/objectspace/garbage_collect_spec.rb22
-rw-r--r--spec/ruby/core/objectspace/remove_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/undefine_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/proc/allocate_spec.rb9
-rw-r--r--spec/ruby/core/proc/arity_spec.rb640
-rw-r--r--spec/ruby/core/proc/binding_spec.rb21
-rw-r--r--spec/ruby/core/proc/block_pass_spec.rb41
-rw-r--r--spec/ruby/core/proc/call_spec.rb16
-rw-r--r--spec/ruby/core/proc/case_compare_spec.rb16
-rw-r--r--spec/ruby/core/proc/clone_spec.rb6
-rw-r--r--spec/ruby/core/proc/curry_spec.rb180
-rw-r--r--spec/ruby/core/proc/dup_spec.rb6
-rw-r--r--spec/ruby/core/proc/element_reference_spec.rb16
-rw-r--r--spec/ruby/core/proc/eql_spec.rb6
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/proc/fixtures/common.rb51
-rw-r--r--spec/ruby/core/proc/fixtures/source_location.rb55
-rw-r--r--spec/ruby/core/proc/hash_spec.rb17
-rw-r--r--spec/ruby/core/proc/inspect_spec.rb6
-rw-r--r--spec/ruby/core/proc/lambda_spec.rb60
-rw-r--r--spec/ruby/core/proc/new_spec.rb190
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb95
-rw-r--r--spec/ruby/core/proc/shared/call.rb96
-rw-r--r--spec/ruby/core/proc/shared/call_arguments.rb7
-rw-r--r--spec/ruby/core/proc/shared/dup.rb10
-rw-r--r--spec/ruby/core/proc/shared/equal.rb100
-rw-r--r--spec/ruby/core/proc/shared/to_s.rb27
-rw-r--r--spec/ruby/core/proc/source_location_spec.rb72
-rw-r--r--spec/ruby/core/proc/to_proc_spec.rb9
-rw-r--r--spec/ruby/core/proc/to_s_spec.rb6
-rw-r--r--spec/ruby/core/proc/yield_spec.rb16
-rw-r--r--spec/ruby/core/process/abort_spec.rb6
-rw-r--r--spec/ruby/core/process/constants_spec.rb63
-rw-r--r--spec/ruby/core/process/daemon_spec.rb123
-rw-r--r--spec/ruby/core/process/detach_spec.rb46
-rw-r--r--spec/ruby/core/process/egid_spec.rb19
-rw-r--r--spec/ruby/core/process/euid_spec.rb59
-rw-r--r--spec/ruby/core/process/exec_spec.rb218
-rw-r--r--spec/ruby/core/process/exit_spec.rb10
-rw-r--r--spec/ruby/core/process/fixtures/common.rb84
-rw-r--r--spec/ruby/core/process/fixtures/daemon.rb111
-rw-r--r--spec/ruby/core/process/fixtures/kill.rb45
-rw-r--r--spec/ruby/core/process/fixtures/map_fd.rb8
-rw-r--r--spec/ruby/core/process/fixtures/setpriority.rb12
-rw-r--r--spec/ruby/core/process/fork_spec.rb6
-rw-r--r--spec/ruby/core/process/getpgid_spec.rb17
-rw-r--r--spec/ruby/core/process/getpgrp_spec.rb7
-rw-r--r--spec/ruby/core/process/getpriority_spec.rb23
-rw-r--r--spec/ruby/core/process/getrlimit_spec.rb91
-rw-r--r--spec/ruby/core/process/gid/change_privilege_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/eid_spec.rb9
-rw-r--r--spec/ruby/core/process/gid/grant_privilege_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/re_exchange_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/re_exchangeable_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/rid_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/sid_available_spec.rb5
-rw-r--r--spec/ruby/core/process/gid/switch_spec.rb5
-rw-r--r--spec/ruby/core/process/gid_spec.rb22
-rw-r--r--spec/ruby/core/process/groups_spec.rb64
-rw-r--r--spec/ruby/core/process/initgroups_spec.rb20
-rw-r--r--spec/ruby/core/process/kill_spec.rb128
-rw-r--r--spec/ruby/core/process/maxgroups_spec.rb19
-rw-r--r--spec/ruby/core/process/pid_spec.rb9
-rw-r--r--spec/ruby/core/process/ppid_spec.rb23
-rw-r--r--spec/ruby/core/process/set_proctitle_spec.rb23
-rw-r--r--spec/ruby/core/process/setpgid_spec.rb28
-rw-r--r--spec/ruby/core/process/setpgrp_spec.rb37
-rw-r--r--spec/ruby/core/process/setpriority_spec.rb41
-rw-r--r--spec/ruby/core/process/setrlimit_spec.rb232
-rw-r--r--spec/ruby/core/process/setsid_spec.rb37
-rw-r--r--spec/ruby/core/process/spawn_spec.rb636
-rw-r--r--spec/ruby/core/process/status/bit_and_spec.rb5
-rw-r--r--spec/ruby/core/process/status/coredump_spec.rb5
-rw-r--r--spec/ruby/core/process/status/equal_value_spec.rb5
-rw-r--r--spec/ruby/core/process/status/exited_spec.rb37
-rw-r--r--spec/ruby/core/process/status/exitstatus_spec.rb13
-rw-r--r--spec/ruby/core/process/status/inspect_spec.rb5
-rw-r--r--spec/ruby/core/process/status/pid_spec.rb15
-rw-r--r--spec/ruby/core/process/status/right_shift_spec.rb5
-rw-r--r--spec/ruby/core/process/status/signaled_spec.rb35
-rw-r--r--spec/ruby/core/process/status/stopped_spec.rb5
-rw-r--r--spec/ruby/core/process/status/stopsig_spec.rb5
-rw-r--r--spec/ruby/core/process/status/success_spec.rb51
-rw-r--r--spec/ruby/core/process/status/termsig_spec.rb39
-rw-r--r--spec/ruby/core/process/status/to_i_spec.rb5
-rw-r--r--spec/ruby/core/process/status/to_int_spec.rb5
-rw-r--r--spec/ruby/core/process/status/to_s_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/getegid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/geteuid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/getgid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/getuid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/issetugid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setegid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/seteuid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setgid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setregid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setresgid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setresuid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setreuid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setrgid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setruid_spec.rb5
-rw-r--r--spec/ruby/core/process/sys/setuid_spec.rb5
-rw-r--r--spec/ruby/core/process/times_spec.rb27
-rw-r--r--spec/ruby/core/process/uid/change_privilege_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/eid_spec.rb9
-rw-r--r--spec/ruby/core/process/uid/grant_privilege_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/re_exchange_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/re_exchangeable_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/rid_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/sid_available_spec.rb5
-rw-r--r--spec/ruby/core/process/uid/switch_spec.rb5
-rw-r--r--spec/ruby/core/process/uid_spec.rb84
-rw-r--r--spec/ruby/core/process/wait2_spec.rb32
-rw-r--r--spec/ruby/core/process/wait_spec.rb90
-rw-r--r--spec/ruby/core/process/waitall_spec.rb48
-rw-r--r--spec/ruby/core/process/waitpid2_spec.rb5
-rw-r--r--spec/ruby/core/process/waitpid_spec.rb15
-rw-r--r--spec/ruby/core/random/bytes_spec.rb39
-rw-r--r--spec/ruby/core/random/default_spec.rb7
-rw-r--r--spec/ruby/core/random/equal_value_spec.rb37
-rw-r--r--spec/ruby/core/random/new_seed_spec.rb24
-rw-r--r--spec/ruby/core/random/new_spec.rb37
-rw-r--r--spec/ruby/core/random/rand_spec.rb216
-rw-r--r--spec/ruby/core/random/raw_seed_spec.rb9
-rw-r--r--spec/ruby/core/random/seed_spec.rb29
-rw-r--r--spec/ruby/core/random/shared/urandom.rb23
-rw-r--r--spec/ruby/core/random/srand_spec.rb39
-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.rb137
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb11
-rw-r--r--spec/ruby/core/range/cover_spec.rb9
-rw-r--r--spec/ruby/core/range/dup_spec.rb15
-rw-r--r--spec/ruby/core/range/each_spec.rb66
-rw-r--r--spec/ruby/core/range/end_spec.rb6
-rw-r--r--spec/ruby/core/range/eql_spec.rb10
-rw-r--r--spec/ruby/core/range/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/range/exclude_end_spec.rb19
-rw-r--r--spec/ruby/core/range/first_spec.rb49
-rw-r--r--spec/ruby/core/range/fixtures/classes.rb65
-rw-r--r--spec/ruby/core/range/hash_spec.rb24
-rw-r--r--spec/ruby/core/range/include_spec.rb10
-rw-r--r--spec/ruby/core/range/initialize_spec.rb41
-rw-r--r--spec/ruby/core/range/inspect_spec.rb26
-rw-r--r--spec/ruby/core/range/last_spec.rb49
-rw-r--r--spec/ruby/core/range/max_spec.rb82
-rw-r--r--spec/ruby/core/range/member_spec.rb10
-rw-r--r--spec/ruby/core/range/min_spec.rb75
-rw-r--r--spec/ruby/core/range/new_spec.rb34
-rw-r--r--spec/ruby/core/range/range_spec.rb7
-rw-r--r--spec/ruby/core/range/shared/begin.rb10
-rw-r--r--spec/ruby/core/range/shared/cover.rb93
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb66
-rw-r--r--spec/ruby/core/range/shared/end.rb10
-rw-r--r--spec/ruby/core/range/shared/equal_value.rb45
-rw-r--r--spec/ruby/core/range/shared/include.rb91
-rw-r--r--spec/ruby/core/range/size_spec.rb31
-rw-r--r--spec/ruby/core/range/step_spec.rb347
-rw-r--r--spec/ruby/core/range/to_a_spec.rb22
-rw-r--r--spec/ruby/core/range/to_s_spec.rb25
-rw-r--r--spec/ruby/core/rational/abs_spec.rb5
-rw-r--r--spec/ruby/core/rational/ceil_spec.rb5
-rw-r--r--spec/ruby/core/rational/coerce_spec.rb5
-rw-r--r--spec/ruby/core/rational/comparison_spec.rb21
-rw-r--r--spec/ruby/core/rational/denominator_spec.rb5
-rw-r--r--spec/ruby/core/rational/div_spec.rb17
-rw-r--r--spec/ruby/core/rational/divide_spec.rb17
-rw-r--r--spec/ruby/core/rational/divmod_spec.rb13
-rw-r--r--spec/ruby/core/rational/equal_value_spec.rb17
-rw-r--r--spec/ruby/core/rational/exponent_spec.rb5
-rw-r--r--spec/ruby/core/rational/fdiv_spec.rb5
-rw-r--r--spec/ruby/core/rational/floor_spec.rb5
-rw-r--r--spec/ruby/core/rational/hash_spec.rb5
-rw-r--r--spec/ruby/core/rational/inspect_spec.rb5
-rw-r--r--spec/ruby/core/rational/integer_spec.rb9
-rw-r--r--spec/ruby/core/rational/magnitude_spec.rb5
-rw-r--r--spec/ruby/core/rational/marshal_dump_spec.rb11
-rw-r--r--spec/ruby/core/rational/minus_spec.rb5
-rw-r--r--spec/ruby/core/rational/modulo_spec.rb5
-rw-r--r--spec/ruby/core/rational/multiply_spec.rb17
-rw-r--r--spec/ruby/core/rational/numerator_spec.rb5
-rw-r--r--spec/ruby/core/rational/plus_spec.rb16
-rw-r--r--spec/ruby/core/rational/quo_spec.rb5
-rw-r--r--spec/ruby/core/rational/rational_spec.rb7
-rw-r--r--spec/ruby/core/rational/rationalize_spec.rb36
-rw-r--r--spec/ruby/core/rational/remainder_spec.rb5
-rw-r--r--spec/ruby/core/rational/round_spec.rb5
-rw-r--r--spec/ruby/core/rational/to_f_spec.rb5
-rw-r--r--spec/ruby/core/rational/to_i_spec.rb5
-rw-r--r--spec/ruby/core/rational/to_r_spec.rb20
-rw-r--r--spec/ruby/core/rational/to_s_spec.rb5
-rw-r--r--spec/ruby/core/rational/truncate_spec.rb5
-rw-r--r--spec/ruby/core/rational/zero_spec.rb13
-rw-r--r--spec/ruby/core/regexp/case_compare_spec.rb25
-rw-r--r--spec/ruby/core/regexp/casefold_spec.rb8
-rw-r--r--spec/ruby/core/regexp/compile_spec.rb18
-rw-r--r--spec/ruby/core/regexp/encoding_spec.rb58
-rw-r--r--spec/ruby/core/regexp/eql_spec.rb6
-rw-r--r--spec/ruby/core/regexp/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/regexp/escape_spec.rb6
-rw-r--r--spec/ruby/core/regexp/fixed_encoding_spec.rb36
-rw-r--r--spec/ruby/core/regexp/hash_spec.rb20
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb15
-rw-r--r--spec/ruby/core/regexp/inspect_spec.rb44
-rw-r--r--spec/ruby/core/regexp/last_match_spec.rb14
-rw-r--r--spec/ruby/core/regexp/match_spec.rb148
-rw-r--r--spec/ruby/core/regexp/named_captures_spec.rb35
-rw-r--r--spec/ruby/core/regexp/names_spec.rb29
-rw-r--r--spec/ruby/core/regexp/new_spec.rb30
-rw-r--r--spec/ruby/core/regexp/options_spec.rb54
-rw-r--r--spec/ruby/core/regexp/quote_spec.rb6
-rw-r--r--spec/ruby/core/regexp/shared/equal_value.rb31
-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.rb31
-rw-r--r--spec/ruby/core/regexp/source_spec.rb29
-rw-r--r--spec/ruby/core/regexp/to_s_spec.rb62
-rw-r--r--spec/ruby/core/regexp/try_convert_spec.rb21
-rw-r--r--spec/ruby/core/regexp/union_spec.rb149
-rw-r--r--spec/ruby/core/signal/list_spec.rb64
-rw-r--r--spec/ruby/core/signal/signame_spec.rb23
-rw-r--r--spec/ruby/core/signal/trap_spec.rb135
-rw-r--r--spec/ruby/core/string/allocate_spec.rb19
-rw-r--r--spec/ruby/core/string/append_spec.rb8
-rw-r--r--spec/ruby/core/string/ascii_only_spec.rb85
-rw-r--r--spec/ruby/core/string/b_spec.rb24
-rw-r--r--spec/ruby/core/string/bytes_spec.rb57
-rw-r--r--spec/ruby/core/string/bytesize_spec.rb37
-rw-r--r--spec/ruby/core/string/byteslice_spec.rb29
-rw-r--r--spec/ruby/core/string/capitalize_spec.rb70
-rw-r--r--spec/ruby/core/string/case_compare_spec.rb8
-rw-r--r--spec/ruby/core/string/casecmp_spec.rb184
-rw-r--r--spec/ruby/core/string/center_spec.rb133
-rw-r--r--spec/ruby/core/string/chars_spec.rb11
-rw-r--r--spec/ruby/core/string/chomp_spec.rb387
-rw-r--r--spec/ruby/core/string/chop_spec.rb128
-rw-r--r--spec/ruby/core/string/chr_spec.rb44
-rw-r--r--spec/ruby/core/string/clear_spec.rb39
-rw-r--r--spec/ruby/core/string/clone_spec.rb58
-rw-r--r--spec/ruby/core/string/codepoints_spec.rb20
-rw-r--r--spec/ruby/core/string/comparison_spec.rb108
-rw-r--r--spec/ruby/core/string/concat_spec.rb28
-rw-r--r--spec/ruby/core/string/count_spec.rb105
-rw-r--r--spec/ruby/core/string/crypt_spec.rb75
-rw-r--r--spec/ruby/core/string/delete_prefix_spec.rb81
-rw-r--r--spec/ruby/core/string/delete_spec.rb119
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb81
-rw-r--r--spec/ruby/core/string/downcase_spec.rb73
-rw-r--r--spec/ruby/core/string/dump_spec.rb424
-rw-r--r--spec/ruby/core/string/dup_spec.rb52
-rw-r--r--spec/ruby/core/string/each_byte_spec.rb61
-rw-r--r--spec/ruby/core/string/each_char_spec.rb7
-rw-r--r--spec/ruby/core/string/each_codepoint_spec.rb10
-rw-r--r--spec/ruby/core/string/each_line_spec.rb9
-rw-r--r--spec/ruby/core/string/element_reference_spec.rb35
-rw-r--r--spec/ruby/core/string/element_set_spec.rb612
-rw-r--r--spec/ruby/core/string/empty_spec.rb12
-rw-r--r--spec/ruby/core/string/encode_spec.rb159
-rw-r--r--spec/ruby/core/string/encoding_spec.rb189
-rw-r--r--spec/ruby/core/string/end_with_spec.rb50
-rw-r--r--spec/ruby/core/string/eql_spec.rb21
-rw-r--r--spec/ruby/core/string/equal_value_spec.rb8
-rw-r--r--spec/ruby/core/string/fixtures/classes.rb49
-rw-r--r--spec/ruby/core/string/fixtures/freeze_magic_comment.rb3
-rw-r--r--spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb9
-rw-r--r--spec/ruby/core/string/fixtures/utf-8-encoding.rb7
-rw-r--r--spec/ruby/core/string/force_encoding_spec.rb53
-rw-r--r--spec/ruby/core/string/freeze_spec.rb18
-rw-r--r--spec/ruby/core/string/getbyte_spec.rb69
-rw-r--r--spec/ruby/core/string/gsub_spec.rb696
-rw-r--r--spec/ruby/core/string/hash_spec.rb9
-rw-r--r--spec/ruby/core/string/hex_spec.rb49
-rw-r--r--spec/ruby/core/string/include_spec.rb35
-rw-r--r--spec/ruby/core/string/index_spec.rb316
-rw-r--r--spec/ruby/core/string/initialize_spec.rb26
-rw-r--r--spec/ruby/core/string/insert_spec.rb84
-rw-r--r--spec/ruby/core/string/inspect_spec.rb492
-rw-r--r--spec/ruby/core/string/intern_spec.rb7
-rw-r--r--spec/ruby/core/string/length_spec.rb7
-rw-r--r--spec/ruby/core/string/lines_spec.rb22
-rw-r--r--spec/ruby/core/string/ljust_spec.rb116
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb50
-rw-r--r--spec/ruby/core/string/match_spec.rb175
-rw-r--r--spec/ruby/core/string/modulo_spec.rb789
-rw-r--r--spec/ruby/core/string/multiply_spec.rb7
-rw-r--r--spec/ruby/core/string/new_spec.rb65
-rw-r--r--spec/ruby/core/string/next_spec.rb11
-rw-r--r--spec/ruby/core/string/oct_spec.rb88
-rw-r--r--spec/ruby/core/string/ord_spec.rb30
-rw-r--r--spec/ruby/core/string/partition_spec.rb38
-rw-r--r--spec/ruby/core/string/percent_spec.rb14
-rw-r--r--spec/ruby/core/string/plus_spec.rb47
-rw-r--r--spec/ruby/core/string/prepend_spec.rb64
-rw-r--r--spec/ruby/core/string/replace_spec.rb7
-rw-r--r--spec/ruby/core/string/reverse_spec.rb52
-rw-r--r--spec/ruby/core/string/rindex_spec.rb368
-rw-r--r--spec/ruby/core/string/rjust_spec.rb116
-rw-r--r--spec/ruby/core/string/rpartition_spec.rb33
-rw-r--r--spec/ruby/core/string/rstrip_spec.rb52
-rw-r--r--spec/ruby/core/string/scan_spec.rb192
-rw-r--r--spec/ruby/core/string/scrub_spec.rb101
-rw-r--r--spec/ruby/core/string/setbyte_spec.rb105
-rw-r--r--spec/ruby/core/string/shared/chars.rb80
-rw-r--r--spec/ruby/core/string/shared/codepoints.rb56
-rw-r--r--spec/ruby/core/string/shared/concat.rb160
-rw-r--r--spec/ruby/core/string/shared/each_char_without_block.rb26
-rw-r--r--spec/ruby/core/string/shared/each_codepoint_without_block.rb33
-rw-r--r--spec/ruby/core/string/shared/each_line.rb150
-rw-r--r--spec/ruby/core/string/shared/each_line_without_block.rb17
-rw-r--r--spec/ruby/core/string/shared/encode.rb247
-rw-r--r--spec/ruby/core/string/shared/eql.rb34
-rw-r--r--spec/ruby/core/string/shared/equal_value.rb29
-rw-r--r--spec/ruby/core/string/shared/length.rb28
-rw-r--r--spec/ruby/core/string/shared/replace.rb75
-rw-r--r--spec/ruby/core/string/shared/slice.rb557
-rw-r--r--spec/ruby/core/string/shared/succ.rb88
-rw-r--r--spec/ruby/core/string/shared/to_a.rb9
-rw-r--r--spec/ruby/core/string/shared/to_s.rb18
-rw-r--r--spec/ruby/core/string/shared/to_sym.rb63
-rw-r--r--spec/ruby/core/string/size_spec.rb7
-rw-r--r--spec/ruby/core/string/slice_spec.rb476
-rw-r--r--spec/ruby/core/string/split_spec.rb405
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb113
-rw-r--r--spec/ruby/core/string/start_with_spec.rb45
-rw-r--r--spec/ruby/core/string/string_spec.rb7
-rw-r--r--spec/ruby/core/string/strip_spec.rb60
-rw-r--r--spec/ruby/core/string/sub_spec.rb571
-rw-r--r--spec/ruby/core/string/succ_spec.rb11
-rw-r--r--spec/ruby/core/string/sum_spec.rb22
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb66
-rw-r--r--spec/ruby/core/string/to_c_spec.rb99
-rw-r--r--spec/ruby/core/string/to_f_spec.rb69
-rw-r--r--spec/ruby/core/string/to_i_spec.rb337
-rw-r--r--spec/ruby/core/string/to_r_spec.rb58
-rw-r--r--spec/ruby/core/string/to_s_spec.rb7
-rw-r--r--spec/ruby/core/string/to_str_spec.rb7
-rw-r--r--spec/ruby/core/string/to_sym_spec.rb7
-rw-r--r--spec/ruby/core/string/tr_s_spec.rb136
-rw-r--r--spec/ruby/core/string/tr_spec.rb131
-rw-r--r--spec/ruby/core/string/try_convert_spec.rb50
-rw-r--r--spec/ruby/core/string/uminus_spec.rb21
-rw-r--r--spec/ruby/core/string/unicode_normalize_spec.rb115
-rw-r--r--spec/ruby/core/string/unicode_normalized_spec.rb74
-rw-r--r--spec/ruby/core/string/unpack/a_spec.rb63
-rw-r--r--spec/ruby/core/string/unpack/at_spec.rb29
-rw-r--r--spec/ruby/core/string/unpack/b_spec.rb190
-rw-r--r--spec/ruby/core/string/unpack/c_spec.rb63
-rw-r--r--spec/ruby/core/string/unpack/comment_spec.rb25
-rw-r--r--spec/ruby/core/string/unpack/d_spec.rb28
-rw-r--r--spec/ruby/core/string/unpack/e_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/f_spec.rb28
-rw-r--r--spec/ruby/core/string/unpack/g_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/h_spec.rb124
-rw-r--r--spec/ruby/core/string/unpack/i_spec.rb152
-rw-r--r--spec/ruby/core/string/unpack/j_spec.rb277
-rw-r--r--spec/ruby/core/string/unpack/l_spec.rb265
-rw-r--r--spec/ruby/core/string/unpack/m_spec.rb170
-rw-r--r--spec/ruby/core/string/unpack/n_spec.rb18
-rw-r--r--spec/ruby/core/string/unpack/p_spec.rb21
-rw-r--r--spec/ruby/core/string/unpack/percent_spec.rb7
-rw-r--r--spec/ruby/core/string/unpack/q_spec.rb64
-rw-r--r--spec/ruby/core/string/unpack/s_spec.rb152
-rw-r--r--spec/ruby/core/string/unpack/shared/basic.rb29
-rw-r--r--spec/ruby/core/string/unpack/shared/float.rb271
-rw-r--r--spec/ruby/core/string/unpack/shared/integer.rb339
-rw-r--r--spec/ruby/core/string/unpack/shared/string.rb51
-rw-r--r--spec/ruby/core/string/unpack/shared/unicode.rb60
-rw-r--r--spec/ruby/core/string/unpack/u_spec.rb94
-rw-r--r--spec/ruby/core/string/unpack/v_spec.rb18
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb25
-rw-r--r--spec/ruby/core/string/unpack/x_spec.rb62
-rw-r--r--spec/ruby/core/string/unpack/z_spec.rb21
-rw-r--r--spec/ruby/core/string/unpack1_spec.rb12
-rw-r--r--spec/ruby/core/string/upcase_spec.rb68
-rw-r--r--spec/ruby/core/string/uplus_spec.rb24
-rw-r--r--spec/ruby/core/string/upto_spec.rb98
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb129
-rw-r--r--spec/ruby/core/struct/dig_spec.rb44
-rw-r--r--spec/ruby/core/struct/dup_spec.rb20
-rw-r--r--spec/ruby/core/struct/each_pair_spec.rb33
-rw-r--r--spec/ruby/core/struct/each_spec.rb27
-rw-r--r--spec/ruby/core/struct/element_reference_spec.rb52
-rw-r--r--spec/ruby/core/struct/element_set_spec.rb29
-rw-r--r--spec/ruby/core/struct/eql_spec.rb13
-rw-r--r--spec/ruby/core/struct/equal_value_spec.rb7
-rw-r--r--spec/ruby/core/struct/fixtures/classes.rb26
-rw-r--r--spec/ruby/core/struct/hash_spec.rb46
-rw-r--r--spec/ruby/core/struct/initialize_spec.rb43
-rw-r--r--spec/ruby/core/struct/inspect_spec.rb15
-rw-r--r--spec/ruby/core/struct/instance_variables_spec.rb16
-rw-r--r--spec/ruby/core/struct/length_spec.rb12
-rw-r--r--spec/ruby/core/struct/members_spec.rb13
-rw-r--r--spec/ruby/core/struct/new_spec.rb134
-rw-r--r--spec/ruby/core/struct/select_spec.rb30
-rw-r--r--spec/ruby/core/struct/shared/accessor.rb7
-rw-r--r--spec/ruby/core/struct/shared/equal_value.rb30
-rw-r--r--spec/ruby/core/struct/shared/inspect.rb5
-rw-r--r--spec/ruby/core/struct/size_spec.rb11
-rw-r--r--spec/ruby/core/struct/struct_spec.rb43
-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.rb12
-rw-r--r--spec/ruby/core/struct/to_h_spec.rb15
-rw-r--r--spec/ruby/core/struct/to_s_spec.rb12
-rw-r--r--spec/ruby/core/struct/values_at_spec.rb16
-rw-r--r--spec/ruby/core/struct/values_spec.rb11
-rw-r--r--spec/ruby/core/symbol/all_symbols_spec.rb14
-rw-r--r--spec/ruby/core/symbol/capitalize_spec.rb56
-rw-r--r--spec/ruby/core/symbol/case_compare_spec.rb11
-rw-r--r--spec/ruby/core/symbol/casecmp_spec.rb146
-rw-r--r--spec/ruby/core/symbol/comparison_spec.rb51
-rw-r--r--spec/ruby/core/symbol/downcase_spec.rb33
-rw-r--r--spec/ruby/core/symbol/dup_spec.rb9
-rw-r--r--spec/ruby/core/symbol/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/symbol/empty_spec.rb11
-rw-r--r--spec/ruby/core/symbol/encoding_spec.rb23
-rw-r--r--spec/ruby/core/symbol/equal_value_spec.rb14
-rw-r--r--spec/ruby/core/symbol/fixtures/classes.rb3
-rw-r--r--spec/ruby/core/symbol/id2name_spec.rb6
-rw-r--r--spec/ruby/core/symbol/inspect_spec.rb105
-rw-r--r--spec/ruby/core/symbol/intern_spec.rb11
-rw-r--r--spec/ruby/core/symbol/length_spec.rb6
-rw-r--r--spec/ruby/core/symbol/match_spec.rb70
-rw-r--r--spec/ruby/core/symbol/next_spec.rb6
-rw-r--r--spec/ruby/core/symbol/shared/id2name.rb9
-rw-r--r--spec/ruby/core/symbol/shared/length.rb23
-rw-r--r--spec/ruby/core/symbol/shared/slice.rb278
-rw-r--r--spec/ruby/core/symbol/shared/succ.rb18
-rw-r--r--spec/ruby/core/symbol/size_spec.rb6
-rw-r--r--spec/ruby/core/symbol/slice_spec.rb6
-rw-r--r--spec/ruby/core/symbol/succ_spec.rb6
-rw-r--r--spec/ruby/core/symbol/swapcase_spec.rb41
-rw-r--r--spec/ruby/core/symbol/symbol_spec.rb19
-rw-r--r--spec/ruby/core/symbol/to_proc_spec.rb41
-rw-r--r--spec/ruby/core/symbol/to_s_spec.rb6
-rw-r--r--spec/ruby/core/symbol/to_sym_spec.rb9
-rw-r--r--spec/ruby/core/symbol/upcase_spec.rb29
-rw-r--r--spec/ruby/core/systemexit/initialize_spec.rb27
-rw-r--r--spec/ruby/core/systemexit/success_spec.rb13
-rw-r--r--spec/ruby/core/thread/abort_on_exception_spec.rb106
-rw-r--r--spec/ruby/core/thread/add_trace_func_spec.rb5
-rw-r--r--spec/ruby/core/thread/alive_spec.rb58
-rw-r--r--spec/ruby/core/thread/allocate_spec.rb9
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb12
-rw-r--r--spec/ruby/core/thread/backtrace/location/base_label_spec.rb12
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/classes.rb17
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/main.rb5
-rw-r--r--spec/ruby/core/thread/backtrace/location/inspect_spec.rb13
-rw-r--r--spec/ruby/core/thread/backtrace/location/label_spec.rb20
-rw-r--r--spec/ruby/core/thread/backtrace/location/lineno_spec.rb13
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb91
-rw-r--r--spec/ruby/core/thread/backtrace/location/to_s_spec.rb13
-rw-r--r--spec/ruby/core/thread/backtrace_spec.rb27
-rw-r--r--spec/ruby/core/thread/current_spec.rb15
-rw-r--r--spec/ruby/core/thread/element_reference_spec.rb44
-rw-r--r--spec/ruby/core/thread/element_set_spec.rb51
-rw-r--r--spec/ruby/core/thread/exclusive_spec.rb18
-rw-r--r--spec/ruby/core/thread/exit_spec.rb15
-rw-r--r--spec/ruby/core/thread/fixtures/classes.rb303
-rw-r--r--spec/ruby/core/thread/fork_spec.rb9
-rw-r--r--spec/ruby/core/thread/group_spec.rb5
-rw-r--r--spec/ruby/core/thread/initialize_spec.rb27
-rw-r--r--spec/ruby/core/thread/inspect_spec.rb44
-rw-r--r--spec/ruby/core/thread/join_spec.rb65
-rw-r--r--spec/ruby/core/thread/key_spec.rb53
-rw-r--r--spec/ruby/core/thread/keys_spec.rb44
-rw-r--r--spec/ruby/core/thread/kill_spec.rb21
-rw-r--r--spec/ruby/core/thread/list_spec.rb42
-rw-r--r--spec/ruby/core/thread/main_spec.rb10
-rw-r--r--spec/ruby/core/thread/name_spec.rb56
-rw-r--r--spec/ruby/core/thread/new_spec.rb56
-rw-r--r--spec/ruby/core/thread/pass_spec.rb8
-rw-r--r--spec/ruby/core/thread/priority_spec.rb68
-rw-r--r--spec/ruby/core/thread/raise_spec.rb181
-rw-r--r--spec/ruby/core/thread/report_on_exception_spec.rb120
-rw-r--r--spec/ruby/core/thread/run_spec.rb9
-rw-r--r--spec/ruby/core/thread/set_trace_func_spec.rb5
-rw-r--r--spec/ruby/core/thread/shared/exit.rb176
-rw-r--r--spec/ruby/core/thread/shared/start.rb41
-rw-r--r--spec/ruby/core/thread/shared/wakeup.rb61
-rw-r--r--spec/ruby/core/thread/start_spec.rb9
-rw-r--r--spec/ruby/core/thread/status_spec.rb60
-rw-r--r--spec/ruby/core/thread/stop_spec.rb54
-rw-r--r--spec/ruby/core/thread/terminate_spec.rb7
-rw-r--r--spec/ruby/core/thread/thread_variable_get_spec.rb25
-rw-r--r--spec/ruby/core/thread/thread_variable_set_spec.rb26
-rw-r--r--spec/ruby/core/thread/thread_variable_spec.rb21
-rw-r--r--spec/ruby/core/thread/thread_variables_spec.rb29
-rw-r--r--spec/ruby/core/thread/value_spec.rb21
-rw-r--r--spec/ruby/core/thread/wakeup_spec.rb7
-rw-r--r--spec/ruby/core/threadgroup/add_spec.rb36
-rw-r--r--spec/ruby/core/threadgroup/default_spec.rb11
-rw-r--r--spec/ruby/core/threadgroup/enclose_spec.rb25
-rw-r--r--spec/ruby/core/threadgroup/enclosed_spec.rb14
-rw-r--r--spec/ruby/core/threadgroup/fixtures/classes.rb6
-rw-r--r--spec/ruby/core/threadgroup/list_spec.rb24
-rw-r--r--spec/ruby/core/time/_dump_spec.rb56
-rw-r--r--spec/ruby/core/time/_load_spec.rb54
-rw-r--r--spec/ruby/core/time/asctime_spec.rb6
-rw-r--r--spec/ruby/core/time/at_spec.rb201
-rw-r--r--spec/ruby/core/time/comparison_spec.rb94
-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.rb46
-rw-r--r--spec/ruby/core/time/eql_spec.rb29
-rw-r--r--spec/ruby/core/time/fixtures/classes.rb12
-rw-r--r--spec/ruby/core/time/friday_spec.rb11
-rw-r--r--spec/ruby/core/time/getgm_spec.rb6
-rw-r--r--spec/ruby/core/time/getlocal_spec.rb98
-rw-r--r--spec/ruby/core/time/getutc_spec.rb6
-rw-r--r--spec/ruby/core/time/gm_spec.rb10
-rw-r--r--spec/ruby/core/time/gmt_offset_spec.rb6
-rw-r--r--spec/ruby/core/time/gmt_spec.rb8
-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.rb11
-rw-r--r--spec/ruby/core/time/hour_spec.rb17
-rw-r--r--spec/ruby/core/time/inspect_spec.rb6
-rw-r--r--spec/ruby/core/time/isdst_spec.rb6
-rw-r--r--spec/ruby/core/time/local_spec.rb11
-rw-r--r--spec/ruby/core/time/localtime_spec.rb140
-rw-r--r--spec/ruby/core/time/mday_spec.rb6
-rw-r--r--spec/ruby/core/time/min_spec.rb17
-rw-r--r--spec/ruby/core/time/minus_spec.rb103
-rw-r--r--spec/ruby/core/time/mktime_spec.rb11
-rw-r--r--spec/ruby/core/time/mon_spec.rb6
-rw-r--r--spec/ruby/core/time/monday_spec.rb11
-rw-r--r--spec/ruby/core/time/month_spec.rb6
-rw-r--r--spec/ruby/core/time/new_spec.rb99
-rw-r--r--spec/ruby/core/time/now_spec.rb6
-rw-r--r--spec/ruby/core/time/nsec_spec.rb27
-rw-r--r--spec/ruby/core/time/plus_spec.rb100
-rw-r--r--spec/ruby/core/time/round_spec.rb35
-rw-r--r--spec/ruby/core/time/saturday_spec.rb11
-rw-r--r--spec/ruby/core/time/sec_spec.rb7
-rw-r--r--spec/ruby/core/time/shared/asctime.rb6
-rw-r--r--spec/ruby/core/time/shared/day.rb15
-rw-r--r--spec/ruby/core/time/shared/getgm.rb9
-rw-r--r--spec/ruby/core/time/shared/gm.rb29
-rw-r--r--spec/ruby/core/time/shared/gmt_offset.rb53
-rw-r--r--spec/ruby/core/time/shared/gmtime.rb33
-rw-r--r--spec/ruby/core/time/shared/inspect.rb23
-rw-r--r--spec/ruby/core/time/shared/isdst.rb8
-rw-r--r--spec/ruby/core/time/shared/local.rb45
-rw-r--r--spec/ruby/core/time/shared/month.rb15
-rw-r--r--spec/ruby/core/time/shared/now.rb20
-rw-r--r--spec/ruby/core/time/shared/time_params.rb258
-rw-r--r--spec/ruby/core/time/shared/to_i.rb9
-rw-r--r--spec/ruby/core/time/strftime_spec.rb52
-rw-r--r--spec/ruby/core/time/subsec_spec.rb27
-rw-r--r--spec/ruby/core/time/succ_spec.rb19
-rw-r--r--spec/ruby/core/time/sunday_spec.rb11
-rw-r--r--spec/ruby/core/time/thursday_spec.rb11
-rw-r--r--spec/ruby/core/time/time_spec.rb7
-rw-r--r--spec/ruby/core/time/to_a_spec.rb12
-rw-r--r--spec/ruby/core/time/to_f_spec.rb7
-rw-r--r--spec/ruby/core/time/to_i_spec.rb6
-rw-r--r--spec/ruby/core/time/to_r_spec.rb11
-rw-r--r--spec/ruby/core/time/to_s_spec.rb6
-rw-r--r--spec/ruby/core/time/tuesday_spec.rb11
-rw-r--r--spec/ruby/core/time/tv_nsec_spec.rb5
-rw-r--r--spec/ruby/core/time/tv_sec_spec.rb6
-rw-r--r--spec/ruby/core/time/tv_usec_spec.rb5
-rw-r--r--spec/ruby/core/time/usec_spec.rb39
-rw-r--r--spec/ruby/core/time/utc_offset_spec.rb6
-rw-r--r--spec/ruby/core/time/utc_spec.rb21
-rw-r--r--spec/ruby/core/time/wday_spec.rb9
-rw-r--r--spec/ruby/core/time/wednesday_spec.rb11
-rw-r--r--spec/ruby/core/time/yday_spec.rb21
-rw-r--r--spec/ruby/core/time/year_spec.rb17
-rw-r--r--spec/ruby/core/time/zone_spec.rb90
-rw-r--r--spec/ruby/core/tracepoint/binding_spec.rb19
-rw-r--r--spec/ruby/core/tracepoint/callee_id_spec.rb20
-rw-r--r--spec/ruby/core/tracepoint/defined_class_spec.rb26
-rw-r--r--spec/ruby/core/tracepoint/disable_spec.rb73
-rw-r--r--spec/ruby/core/tracepoint/enable_spec.rb102
-rw-r--r--spec/ruby/core/tracepoint/enabled_spec.rb14
-rw-r--r--spec/ruby/core/tracepoint/event_spec.rb21
-rw-r--r--spec/ruby/core/tracepoint/fixtures/classes.rb34
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb8
-rw-r--r--spec/ruby/core/tracepoint/lineno_spec.rb10
-rw-r--r--spec/ruby/core/tracepoint/method_id_spec.rb13
-rw-r--r--spec/ruby/core/tracepoint/new_spec.rb68
-rw-r--r--spec/ruby/core/tracepoint/path_spec.rb18
-rw-r--r--spec/ruby/core/tracepoint/raised_exception_spec.rb16
-rw-r--r--spec/ruby/core/tracepoint/return_value_spec.rb13
-rw-r--r--spec/ruby/core/tracepoint/self_spec.rb10
-rw-r--r--spec/ruby/core/tracepoint/trace_spec.rb9
-rw-r--r--spec/ruby/core/true/and_spec.rb11
-rw-r--r--spec/ruby/core/true/dup_spec.rb9
-rw-r--r--spec/ruby/core/true/inspect_spec.rb7
-rw-r--r--spec/ruby/core/true/or_spec.rb11
-rw-r--r--spec/ruby/core/true/to_s_spec.rb7
-rw-r--r--spec/ruby/core/true/trueclass_spec.rb15
-rw-r--r--spec/ruby/core/true/xor_spec.rb11
-rw-r--r--spec/ruby/core/unboundmethod/arity_spec.rb207
-rw-r--r--spec/ruby/core/unboundmethod/bind_spec.rb51
-rw-r--r--spec/ruby/core/unboundmethod/clone_spec.rb12
-rw-r--r--spec/ruby/core/unboundmethod/eql_spec.rb5
-rw-r--r--spec/ruby/core/unboundmethod/equal_value_spec.rb101
-rw-r--r--spec/ruby/core/unboundmethod/fixtures/classes.rb86
-rw-r--r--spec/ruby/core/unboundmethod/hash_spec.rb17
-rw-r--r--spec/ruby/core/unboundmethod/inspect_spec.rb7
-rw-r--r--spec/ruby/core/unboundmethod/name_spec.rb15
-rw-r--r--spec/ruby/core/unboundmethod/owner_spec.rb26
-rw-r--r--spec/ruby/core/unboundmethod/parameters_spec.rb5
-rw-r--r--spec/ruby/core/unboundmethod/shared/to_s.rb25
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb52
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb28
-rw-r--r--spec/ruby/core/unboundmethod/to_s_spec.rb7
-rw-r--r--spec/ruby/core/warning/warn_spec.rb60
-rw-r--r--spec/ruby/default.mspec52
-rw-r--r--spec/ruby/fixtures/basicobject/method_missing.rb55
-rw-r--r--spec/ruby/fixtures/class.rb136
-rw-r--r--spec/ruby/fixtures/class_variables.rb58
-rw-r--r--spec/ruby/fixtures/code/a/load_fixture.bundle1
-rw-r--r--spec/ruby/fixtures/code/a/load_fixture.dll1
-rw-r--r--spec/ruby/fixtures/code/a/load_fixture.so1
-rw-r--r--spec/ruby/fixtures/code/b/load_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/concurrent.rb12
-rw-r--r--spec/ruby/fixtures/code/concurrent2.rb8
-rw-r--r--spec/ruby/fixtures/code/concurrent3.rb2
-rw-r--r--spec/ruby/fixtures/code/file_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/gem/load_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/line_fixture.rb5
-rw-r--r--spec/ruby/fixtures/code/load_ext_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/load_fixture1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.bundle1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.dll1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext.bundle1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext.dll1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext.rb1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext.so1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.so1
-rw-r--r--spec/ruby/fixtures/code/load_wrap_method_fixture.rb9
-rw-r--r--spec/ruby/fixtures/code/methods_fixture.rb364
-rw-r--r--spec/ruby/fixtures/code/raise_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/recursive_load_fixture.rb5
-rw-r--r--spec/ruby/fixtures/code/recursive_require_fixture.rb3
-rw-r--r--spec/ruby/fixtures/code/symlink/symlink1.rb1
-rw-r--r--spec/ruby/fixtures/code/symlink/symlink2/symlink2.rb1
-rw-r--r--spec/ruby/fixtures/code/wrap_fixture.rb3
-rw-r--r--spec/ruby/fixtures/code_loading.rb26
-rw-r--r--spec/ruby/fixtures/constants.rb288
-rw-r--r--spec/ruby/fixtures/enumerator/classes.rb15
-rw-r--r--spec/ruby/fixtures/math/common.rb3
-rw-r--r--spec/ruby/fixtures/rational.rb11
-rw-r--r--spec/ruby/fixtures/reflection.rb352
-rw-r--r--spec/ruby/language/BEGIN_spec.rb36
-rw-r--r--spec/ruby/language/README30
-rw-r--r--spec/ruby/language/alias_spec.rb246
-rw-r--r--spec/ruby/language/and_spec.rb80
-rw-r--r--spec/ruby/language/array_spec.rb155
-rw-r--r--spec/ruby/language/block_spec.rb865
-rw-r--r--spec/ruby/language/break_spec.rb365
-rw-r--r--spec/ruby/language/case_spec.rb389
-rw-r--r--spec/ruby/language/class_spec.rb330
-rw-r--r--spec/ruby/language/class_variable_spec.rb84
-rw-r--r--spec/ruby/language/constants_spec.rb668
-rw-r--r--spec/ruby/language/def_spec.rb714
-rw-r--r--spec/ruby/language/defined_spec.rb1140
-rw-r--r--spec/ruby/language/encoding_spec.rb36
-rw-r--r--spec/ruby/language/ensure_spec.rb293
-rw-r--r--spec/ruby/language/execution_spec.rb15
-rw-r--r--spec/ruby/language/file_spec.rb29
-rw-r--r--spec/ruby/language/fixtures/argv_encoding.rb1
-rw-r--r--spec/ruby/language/fixtures/array.rb11
-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.rb57
-rw-r--r--spec/ruby/language/fixtures/break.rb291
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel.rb9
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel_block.rb23
-rw-r--r--spec/ruby/language/fixtures/break_lambda_toplevel_method.rb17
-rw-r--r--spec/ruby/language/fixtures/classes.rb31
-rw-r--r--spec/ruby/language/fixtures/coding_us_ascii.rb11
-rw-r--r--spec/ruby/language/fixtures/coding_utf_8.rb11
-rw-r--r--spec/ruby/language/fixtures/constant_visibility.rb98
-rw-r--r--spec/ruby/language/fixtures/constants_sclass.rb54
-rw-r--r--spec/ruby/language/fixtures/def.rb8
-rw-r--r--spec/ruby/language/fixtures/defined.rb298
-rw-r--r--spec/ruby/language/fixtures/dollar_zero.rb6
-rw-r--r--spec/ruby/language/fixtures/ensure.rb77
-rw-r--r--spec/ruby/language/fixtures/file.rb1
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb5
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb5
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb5
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb4
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_required.rb3
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rbbin0 -> 181 bytes-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb1
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb3
-rw-r--r--spec/ruby/language/fixtures/hash_strings_ascii8bit.rb7
-rw-r--r--spec/ruby/language/fixtures/hash_strings_usascii.rb7
-rw-r--r--spec/ruby/language/fixtures/hash_strings_utf8.rb7
-rw-r--r--spec/ruby/language/fixtures/match_operators.rb9
-rw-r--r--spec/ruby/language/fixtures/metaclass.rb34
-rw-r--r--spec/ruby/language/fixtures/module.rb24
-rw-r--r--spec/ruby/language/fixtures/next.rb134
-rw-r--r--spec/ruby/language/fixtures/precedence.rb16
-rw-r--r--spec/ruby/language/fixtures/private.rb59
-rw-r--r--spec/ruby/language/fixtures/rescue.rb63
-rw-r--r--spec/ruby/language/fixtures/return.rb139
-rw-r--r--spec/ruby/language/fixtures/send.rb140
-rw-r--r--spec/ruby/language/fixtures/squiggly_heredoc.rb39
-rw-r--r--spec/ruby/language/fixtures/super.rb664
-rw-r--r--spec/ruby/language/fixtures/variables.rb85
-rw-r--r--spec/ruby/language/fixtures/yield.rb37
-rw-r--r--spec/ruby/language/for_spec.rb177
-rw-r--r--spec/ruby/language/hash_spec.rb154
-rw-r--r--spec/ruby/language/heredoc_spec.rb87
-rw-r--r--spec/ruby/language/if_spec.rb373
-rw-r--r--spec/ruby/language/lambda_spec.rb573
-rw-r--r--spec/ruby/language/line_spec.rb45
-rw-r--r--spec/ruby/language/loop_spec.rb67
-rw-r--r--spec/ruby/language/magic_comment_spec.rb62
-rw-r--r--spec/ruby/language/match_spec.rb74
-rw-r--r--spec/ruby/language/metaclass_spec.rb143
-rw-r--r--spec/ruby/language/method_spec.rb1296
-rw-r--r--spec/ruby/language/module_spec.rb91
-rw-r--r--spec/ruby/language/next_spec.rb410
-rw-r--r--spec/ruby/language/not_spec.rb51
-rw-r--r--spec/ruby/language/numbers_spec.rb97
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb226
-rw-r--r--spec/ruby/language/or_spec.rb90
-rw-r--r--spec/ruby/language/order_spec.rb75
-rw-r--r--spec/ruby/language/precedence_spec.rb448
-rw-r--r--spec/ruby/language/predefined/data_spec.rb29
-rw-r--r--spec/ruby/language/predefined/fixtures/data1.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/data2.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/data3.rb7
-rw-r--r--spec/ruby/language/predefined/fixtures/data4.rb4
-rw-r--r--spec/ruby/language/predefined/fixtures/data5.rb5
-rw-r--r--spec/ruby/language/predefined/fixtures/data_only.rb2
-rw-r--r--spec/ruby/language/predefined/fixtures/print_data.rb3
-rw-r--r--spec/ruby/language/predefined_spec.rb1240
-rw-r--r--spec/ruby/language/private_spec.rb67
-rw-r--r--spec/ruby/language/proc_spec.rb220
-rw-r--r--spec/ruby/language/redo_spec.rb66
-rw-r--r--spec/ruby/language/regexp/anchors_spec.rb179
-rw-r--r--spec/ruby/language/regexp/back-references_spec.rb48
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb633
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb103
-rw-r--r--spec/ruby/language/regexp/escapes_spec.rb81
-rw-r--r--spec/ruby/language/regexp/grouping_spec.rb23
-rw-r--r--spec/ruby/language/regexp/interpolation_spec.rb58
-rw-r--r--spec/ruby/language/regexp/modifiers_spec.rb117
-rw-r--r--spec/ruby/language/regexp/repetition_spec.rb57
-rw-r--r--spec/ruby/language/regexp_spec.rb150
-rw-r--r--spec/ruby/language/rescue_spec.rb452
-rw-r--r--spec/ruby/language/retry_spec.rb52
-rw-r--r--spec/ruby/language/return_spec.rb483
-rw-r--r--spec/ruby/language/safe_navigator_spec.rb101
-rw-r--r--spec/ruby/language/send_spec.rb521
-rw-r--r--spec/ruby/language/shared/__FILE__.rb23
-rw-r--r--spec/ruby/language/shared/__LINE__.rb15
-rw-r--r--spec/ruby/language/singleton_class_spec.rb293
-rw-r--r--spec/ruby/language/string_spec.rb282
-rw-r--r--spec/ruby/language/super_spec.rb359
-rw-r--r--spec/ruby/language/symbol_spec.rb106
-rw-r--r--spec/ruby/language/throw_spec.rb81
-rw-r--r--spec/ruby/language/undef_spec.rb72
-rw-r--r--spec/ruby/language/unless_spec.rb43
-rw-r--r--spec/ruby/language/until_spec.rb234
-rw-r--r--spec/ruby/language/variables_spec.rb760
-rw-r--r--spec/ruby/language/while_spec.rb344
-rw-r--r--spec/ruby/language/yield_spec.rb179
-rw-r--r--spec/ruby/library/English/English_spec.rb171
-rw-r--r--spec/ruby/library/abbrev/abbrev_spec.rb31
-rw-r--r--spec/ruby/library/base64/decode64_spec.rb9
-rw-r--r--spec/ruby/library/base64/encode64_spec.rb14
-rw-r--r--spec/ruby/library/base64/urlsafe_decode64_spec.rb27
-rw-r--r--spec/ruby/library/base64/urlsafe_encode64_spec.rb22
-rw-r--r--spec/ruby/library/bigdecimal/abs_spec.rb50
-rw-r--r--spec/ruby/library/bigdecimal/add_spec.rb179
-rw-r--r--spec/ruby/library/bigdecimal/case_compare_spec.rb7
-rw-r--r--spec/ruby/library/bigdecimal/ceil_spec.rb104
-rw-r--r--spec/ruby/library/bigdecimal/coerce_spec.rb26
-rw-r--r--spec/ruby/library/bigdecimal/comparison_spec.rb81
-rw-r--r--spec/ruby/library/bigdecimal/div_spec.rb102
-rw-r--r--spec/ruby/library/bigdecimal/divide_spec.rb7
-rw-r--r--spec/ruby/library/bigdecimal/divmod_spec.rb180
-rw-r--r--spec/ruby/library/bigdecimal/double_fig_spec.rb9
-rw-r--r--spec/ruby/library/bigdecimal/eql_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/equal_value_spec.rb7
-rw-r--r--spec/ruby/library/bigdecimal/exponent_spec.rb38
-rw-r--r--spec/ruby/library/bigdecimal/finite_spec.rb35
-rw-r--r--spec/ruby/library/bigdecimal/fix_spec.rb57
-rw-r--r--spec/ruby/library/bigdecimal/fixtures/classes.rb17
-rw-r--r--spec/ruby/library/bigdecimal/floor_spec.rb100
-rw-r--r--spec/ruby/library/bigdecimal/frac_spec.rb48
-rw-r--r--spec/ruby/library/bigdecimal/gt_spec.rb98
-rw-r--r--spec/ruby/library/bigdecimal/gte_spec.rb102
-rw-r--r--spec/ruby/library/bigdecimal/infinite_spec.rb32
-rw-r--r--spec/ruby/library/bigdecimal/inspect_spec.rb47
-rw-r--r--spec/ruby/library/bigdecimal/limit_spec.rb45
-rw-r--r--spec/ruby/library/bigdecimal/lt_spec.rb96
-rw-r--r--spec/ruby/library/bigdecimal/lte_spec.rb102
-rw-r--r--spec/ruby/library/bigdecimal/minus_spec.rb58
-rw-r--r--spec/ruby/library/bigdecimal/mode_spec.rb36
-rw-r--r--spec/ruby/library/bigdecimal/modulo_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/mult_spec.rb24
-rw-r--r--spec/ruby/library/bigdecimal/multiply_spec.rb26
-rw-r--r--spec/ruby/library/bigdecimal/nan_spec.rb23
-rw-r--r--spec/ruby/library/bigdecimal/new_spec.rb109
-rw-r--r--spec/ruby/library/bigdecimal/nonzero_spec.rb29
-rw-r--r--spec/ruby/library/bigdecimal/plus_spec.rb47
-rw-r--r--spec/ruby/library/bigdecimal/power_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/precs_spec.rb49
-rw-r--r--spec/ruby/library/bigdecimal/quo_spec.rb13
-rw-r--r--spec/ruby/library/bigdecimal/remainder_spec.rb84
-rw-r--r--spec/ruby/library/bigdecimal/round_spec.rb202
-rw-r--r--spec/ruby/library/bigdecimal/shared/eql.rb61
-rw-r--r--spec/ruby/library/bigdecimal/shared/modulo.rb116
-rw-r--r--spec/ruby/library/bigdecimal/shared/mult.rb97
-rw-r--r--spec/ruby/library/bigdecimal/shared/power.rb72
-rw-r--r--spec/ruby/library/bigdecimal/shared/quo.rb59
-rw-r--r--spec/ruby/library/bigdecimal/shared/to_int.rb16
-rw-r--r--spec/ruby/library/bigdecimal/sign_spec.rb47
-rw-r--r--spec/ruby/library/bigdecimal/split_spec.rb88
-rw-r--r--spec/ruby/library/bigdecimal/sqrt_spec.rb112
-rw-r--r--spec/ruby/library/bigdecimal/sub_spec.rb53
-rw-r--r--spec/ruby/library/bigdecimal/to_f_spec.rb55
-rw-r--r--spec/ruby/library/bigdecimal/to_i_spec.rb7
-rw-r--r--spec/ruby/library/bigdecimal/to_int_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/to_r_spec.rb16
-rw-r--r--spec/ruby/library/bigdecimal/to_s_spec.rb73
-rw-r--r--spec/ruby/library/bigdecimal/truncate_spec.rb81
-rw-r--r--spec/ruby/library/bigdecimal/uminus_spec.rb58
-rw-r--r--spec/ruby/library/bigdecimal/uplus_spec.rb20
-rw-r--r--spec/ruby/library/bigdecimal/ver_spec.rb11
-rw-r--r--spec/ruby/library/bigdecimal/zero_spec.rb28
-rw-r--r--spec/ruby/library/bigmath/log_spec.rb10
-rw-r--r--spec/ruby/library/cgi/cookie/domain_spec.rb23
-rw-r--r--spec/ruby/library/cgi/cookie/expires_spec.rb23
-rw-r--r--spec/ruby/library/cgi/cookie/initialize_spec.rb147
-rw-r--r--spec/ruby/library/cgi/cookie/name_spec.rb23
-rw-r--r--spec/ruby/library/cgi/cookie/parse_spec.rb39
-rw-r--r--spec/ruby/library/cgi/cookie/path_spec.rb23
-rw-r--r--spec/ruby/library/cgi/cookie/secure_spec.rb70
-rw-r--r--spec/ruby/library/cgi/cookie/to_s_spec.rb42
-rw-r--r--spec/ruby/library/cgi/cookie/value_spec.rb76
-rw-r--r--spec/ruby/library/cgi/escapeElement_spec.rb20
-rw-r--r--spec/ruby/library/cgi/escapeHTML_spec.rb13
-rw-r--r--spec/ruby/library/cgi/escape_spec.rb26
-rw-r--r--spec/ruby/library/cgi/htmlextension/a_spec.rb49
-rw-r--r--spec/ruby/library/cgi/htmlextension/base_spec.rb33
-rw-r--r--spec/ruby/library/cgi/htmlextension/blockquote_spec.rb33
-rw-r--r--spec/ruby/library/cgi/htmlextension/br_spec.rb22
-rw-r--r--spec/ruby/library/cgi/htmlextension/caption_spec.rb33
-rw-r--r--spec/ruby/library/cgi/htmlextension/checkbox_group_spec.rb76
-rw-r--r--spec/ruby/library/cgi/htmlextension/checkbox_spec.rb77
-rw-r--r--spec/ruby/library/cgi/htmlextension/doctype_spec.rb27
-rw-r--r--spec/ruby/library/cgi/htmlextension/file_field_spec.rb72
-rw-r--r--spec/ruby/library/cgi/htmlextension/fixtures/common.rb15
-rw-r--r--spec/ruby/library/cgi/htmlextension/form_spec.rb58
-rw-r--r--spec/ruby/library/cgi/htmlextension/frame_spec.rb14
-rw-r--r--spec/ruby/library/cgi/htmlextension/frameset_spec.rb14
-rw-r--r--spec/ruby/library/cgi/htmlextension/hidden_spec.rb59
-rw-r--r--spec/ruby/library/cgi/htmlextension/html_spec.rb66
-rw-r--r--spec/ruby/library/cgi/htmlextension/image_button_spec.rb69
-rw-r--r--spec/ruby/library/cgi/htmlextension/img_spec.rb83
-rw-r--r--spec/ruby/library/cgi/htmlextension/multipart_form_spec.rb64
-rw-r--r--spec/ruby/library/cgi/htmlextension/password_field_spec.rb84
-rw-r--r--spec/ruby/library/cgi/htmlextension/popup_menu_spec.rb8
-rw-r--r--spec/ruby/library/cgi/htmlextension/radio_button_spec.rb77
-rw-r--r--spec/ruby/library/cgi/htmlextension/radio_group_spec.rb77
-rw-r--r--spec/ruby/library/cgi/htmlextension/reset_spec.rb57
-rw-r--r--spec/ruby/library/cgi/htmlextension/scrolling_list_spec.rb8
-rw-r--r--spec/ruby/library/cgi/htmlextension/shared/popup_menu.rb94
-rw-r--r--spec/ruby/library/cgi/htmlextension/submit_spec.rb57
-rw-r--r--spec/ruby/library/cgi/htmlextension/text_field_spec.rb84
-rw-r--r--spec/ruby/library/cgi/htmlextension/textarea_spec.rb73
-rw-r--r--spec/ruby/library/cgi/http_header_spec.rb8
-rw-r--r--spec/ruby/library/cgi/initialize_spec.rb133
-rw-r--r--spec/ruby/library/cgi/out_spec.rb51
-rw-r--r--spec/ruby/library/cgi/parse_spec.rb24
-rw-r--r--spec/ruby/library/cgi/pretty_spec.rb24
-rw-r--r--spec/ruby/library/cgi/print_spec.rb26
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_charset_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_encoding_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_language_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/accept_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/auth_type_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/cache_control_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/content_length_spec.rb26
-rw-r--r--spec/ruby/library/cgi/queryextension/content_type_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/cookies_spec.rb10
-rw-r--r--spec/ruby/library/cgi/queryextension/element_reference_spec.rb27
-rw-r--r--spec/ruby/library/cgi/queryextension/from_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/gateway_interface_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/has_key_spec.rb7
-rw-r--r--spec/ruby/library/cgi/queryextension/host_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/include_spec.rb7
-rw-r--r--spec/ruby/library/cgi/queryextension/key_spec.rb7
-rw-r--r--spec/ruby/library/cgi/queryextension/keys_spec.rb20
-rw-r--r--spec/ruby/library/cgi/queryextension/multipart_spec.rb40
-rw-r--r--spec/ruby/library/cgi/queryextension/negotiate_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/params_spec.rb37
-rw-r--r--spec/ruby/library/cgi/queryextension/path_info_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/path_translated_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/pragma_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/query_string_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/raw_cookie2_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/raw_cookie_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/referer_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_addr_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_host_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_ident_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/remote_user_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/request_method_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/script_name_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/server_name_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/server_port_spec.rb26
-rw-r--r--spec/ruby/library/cgi/queryextension/server_protocol_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/server_software_spec.rb22
-rw-r--r--spec/ruby/library/cgi/queryextension/shared/has_key.rb19
-rw-r--r--spec/ruby/library/cgi/queryextension/user_agent_spec.rb22
-rw-r--r--spec/ruby/library/cgi/rfc1123_date_spec.rb10
-rw-r--r--spec/ruby/library/cgi/shared/http_header.rb112
-rw-r--r--spec/ruby/library/cgi/unescapeElement_spec.rb20
-rw-r--r--spec/ruby/library/cgi/unescapeHTML_spec.rb39
-rw-r--r--spec/ruby/library/cgi/unescape_spec.rb15
-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/fixtures/classes.rb4
-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.rb67
-rw-r--r--spec/ruby/library/conditionvariable/marshal_dump_spec.rb9
-rw-r--r--spec/ruby/library/conditionvariable/signal_spec.rb69
-rw-r--r--spec/ruby/library/conditionvariable/wait_spec.rb25
-rw-r--r--spec/ruby/library/coverage/fixtures/second_class.rb5
-rw-r--r--spec/ruby/library/coverage/fixtures/some_class.rb16
-rw-r--r--spec/ruby/library/coverage/fixtures/spec_helper.rb11
-rw-r--r--spec/ruby/library/coverage/fixtures/start_coverage.rb3
-rw-r--r--spec/ruby/library/coverage/peek_result_spec.rb67
-rw-r--r--spec/ruby/library/coverage/result_spec.rb78
-rw-r--r--spec/ruby/library/coverage/start_spec.rb6
-rw-r--r--spec/ruby/library/csv/basicwriter/close_on_terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/basicwriter/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/basicwriter/terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/cell/data_spec.rb6
-rw-r--r--spec/ruby/library/csv/cell/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/fixtures/one_line.csv1
-rw-r--r--spec/ruby/library/csv/foreach_spec.rb6
-rw-r--r--spec/ruby/library/csv/generate_line_spec.rb30
-rw-r--r--spec/ruby/library/csv/generate_row_spec.rb6
-rw-r--r--spec/ruby/library/csv/generate_spec.rb32
-rw-r--r--spec/ruby/library/csv/iobuf/close_spec.rb6
-rw-r--r--spec/ruby/library/csv/iobuf/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/iobuf/read_spec.rb6
-rw-r--r--spec/ruby/library/csv/iobuf/terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/ioreader/close_on_terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/ioreader/get_row_spec.rb6
-rw-r--r--spec/ruby/library/csv/ioreader/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/ioreader/terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/liberal_parsing_spec.rb21
-rw-r--r--spec/ruby/library/csv/open_spec.rb6
-rw-r--r--spec/ruby/library/csv/parse_spec.rb95
-rw-r--r--spec/ruby/library/csv/read_spec.rb6
-rw-r--r--spec/ruby/library/csv/readlines_spec.rb37
-rw-r--r--spec/ruby/library/csv/streambuf/add_buf_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/buf_size_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/drop_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/element_reference_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/get_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/idx_is_eos_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/is_eos_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/read_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/rel_buf_spec.rb6
-rw-r--r--spec/ruby/library/csv/streambuf/terminate_spec.rb6
-rw-r--r--spec/ruby/library/csv/stringreader/get_row_spec.rb6
-rw-r--r--spec/ruby/library/csv/stringreader/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/add_row_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/append_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/close_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/create_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/generate_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/initialize_spec.rb6
-rw-r--r--spec/ruby/library/csv/writer/terminate_spec.rb6
-rw-r--r--spec/ruby/library/date/accessor_spec.rb91
-rw-r--r--spec/ruby/library/date/add_month_spec.rb38
-rw-r--r--spec/ruby/library/date/add_spec.rb30
-rw-r--r--spec/ruby/library/date/ajd_spec.rb6
-rw-r--r--spec/ruby/library/date/ajd_to_amjd_spec.rb6
-rw-r--r--spec/ruby/library/date/ajd_to_jd_spec.rb6
-rw-r--r--spec/ruby/library/date/amjd_spec.rb6
-rw-r--r--spec/ruby/library/date/amjd_to_ajd_spec.rb6
-rw-r--r--spec/ruby/library/date/append_spec.rb6
-rw-r--r--spec/ruby/library/date/asctime_spec.rb6
-rw-r--r--spec/ruby/library/date/boat_spec.rb24
-rw-r--r--spec/ruby/library/date/case_compare_spec.rb6
-rw-r--r--spec/ruby/library/date/civil_spec.rb12
-rw-r--r--spec/ruby/library/date/commercial_spec.rb18
-rw-r--r--spec/ruby/library/date/commercial_to_jd_spec.rb6
-rw-r--r--spec/ruby/library/date/comparison_spec.rb6
-rw-r--r--spec/ruby/library/date/constants_spec.rb48
-rw-r--r--spec/ruby/library/date/conversions_spec.rb43
-rw-r--r--spec/ruby/library/date/ctime_spec.rb6
-rw-r--r--spec/ruby/library/date/cwday_spec.rb6
-rw-r--r--spec/ruby/library/date/cweek_spec.rb6
-rw-r--r--spec/ruby/library/date/cwyear_spec.rb6
-rw-r--r--spec/ruby/library/date/day_fraction_spec.rb6
-rw-r--r--spec/ruby/library/date/day_fraction_to_time_spec.rb6
-rw-r--r--spec/ruby/library/date/day_spec.rb9
-rw-r--r--spec/ruby/library/date/downto_spec.rb18
-rw-r--r--spec/ruby/library/date/england_spec.rb6
-rw-r--r--spec/ruby/library/date/eql_spec.rb12
-rw-r--r--spec/ruby/library/date/format/bag/method_missing_spec.rb6
-rw-r--r--spec/ruby/library/date/format/bag/to_hash_spec.rb6
-rw-r--r--spec/ruby/library/date/friday_spec.rb12
-rw-r--r--spec/ruby/library/date/gregorian_leap_spec.rb16
-rw-r--r--spec/ruby/library/date/gregorian_spec.rb16
-rw-r--r--spec/ruby/library/date/hash_spec.rb8
-rw-r--r--spec/ruby/library/date/infinity/abs_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/coerce_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/comparison_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/d_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/finite_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/infinite_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/nan_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/uminus_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/uplus_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity/zero_spec.rb6
-rw-r--r--spec/ruby/library/date/infinity_spec.rb67
-rw-r--r--spec/ruby/library/date/inspect_spec.rb6
-rw-r--r--spec/ruby/library/date/italy_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_spec.rb15
-rw-r--r--spec/ruby/library/date/jd_to_ajd_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_civil_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_commercial_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_ld_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_mjd_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_ordinal_spec.rb6
-rw-r--r--spec/ruby/library/date/jd_to_wday_spec.rb6
-rw-r--r--spec/ruby/library/date/julian_leap_spec.rb15
-rw-r--r--spec/ruby/library/date/julian_spec.rb16
-rw-r--r--spec/ruby/library/date/ld_spec.rb6
-rw-r--r--spec/ruby/library/date/ld_to_jd_spec.rb6
-rw-r--r--spec/ruby/library/date/leap_spec.rb10
-rw-r--r--spec/ruby/library/date/mday_spec.rb6
-rw-r--r--spec/ruby/library/date/minus_month_spec.rb25
-rw-r--r--spec/ruby/library/date/minus_spec.rb30
-rw-r--r--spec/ruby/library/date/mjd_spec.rb6
-rw-r--r--spec/ruby/library/date/mjd_to_jd_spec.rb6
-rw-r--r--spec/ruby/library/date/mon_spec.rb6
-rw-r--r--spec/ruby/library/date/monday_spec.rb8
-rw-r--r--spec/ruby/library/date/month_spec.rb9
-rw-r--r--spec/ruby/library/date/new_spec.rb8
-rw-r--r--spec/ruby/library/date/new_start_spec.rb6
-rw-r--r--spec/ruby/library/date/next_day_spec.rb14
-rw-r--r--spec/ruby/library/date/next_month_spec.rb29
-rw-r--r--spec/ruby/library/date/next_spec.rb6
-rw-r--r--spec/ruby/library/date/next_year_spec.rb12
-rw-r--r--spec/ruby/library/date/ordinal_spec.rb8
-rw-r--r--spec/ruby/library/date/ordinal_to_jd_spec.rb6
-rw-r--r--spec/ruby/library/date/parse_spec.rb137
-rw-r--r--spec/ruby/library/date/plus_spec.rb20
-rw-r--r--spec/ruby/library/date/prev_day_spec.rb14
-rw-r--r--spec/ruby/library/date/prev_month_spec.rb29
-rw-r--r--spec/ruby/library/date/prev_year_spec.rb12
-rw-r--r--spec/ruby/library/date/relationship_spec.rb20
-rw-r--r--spec/ruby/library/date/right_shift_spec.rb6
-rw-r--r--spec/ruby/library/date/saturday_spec.rb8
-rw-r--r--spec/ruby/library/date/shared/civil.rb57
-rw-r--r--spec/ruby/library/date/shared/commercial.rb39
-rw-r--r--spec/ruby/library/date/shared/jd.rb14
-rw-r--r--spec/ruby/library/date/shared/new_bang.rb14
-rw-r--r--spec/ruby/library/date/shared/ordinal.rb22
-rw-r--r--spec/ruby/library/date/shared/parse.rb54
-rw-r--r--spec/ruby/library/date/shared/parse_eu.rb37
-rw-r--r--spec/ruby/library/date/shared/parse_us.rb36
-rw-r--r--spec/ruby/library/date/shared/valid_civil.rb36
-rw-r--r--spec/ruby/library/date/shared/valid_commercial.rb34
-rw-r--r--spec/ruby/library/date/shared/valid_jd.rb15
-rw-r--r--spec/ruby/library/date/shared/valid_ordinal.rb26
-rw-r--r--spec/ruby/library/date/start_spec.rb6
-rw-r--r--spec/ruby/library/date/step_spec.rb56
-rw-r--r--spec/ruby/library/date/strftime_spec.rb40
-rw-r--r--spec/ruby/library/date/strptime_spec.rb149
-rw-r--r--spec/ruby/library/date/succ_spec.rb6
-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.rb6
-rw-r--r--spec/ruby/library/date/to_s_spec.rb6
-rw-r--r--spec/ruby/library/date/today_spec.rb14
-rw-r--r--spec/ruby/library/date/tuesday_spec.rb8
-rw-r--r--spec/ruby/library/date/upto_spec.rb16
-rw-r--r--spec/ruby/library/date/valid_civil_spec.rb10
-rw-r--r--spec/ruby/library/date/valid_commercial_spec.rb10
-rw-r--r--spec/ruby/library/date/valid_date_spec.rb7
-rw-r--r--spec/ruby/library/date/valid_jd_spec.rb10
-rw-r--r--spec/ruby/library/date/valid_ordinal_spec.rb10
-rw-r--r--spec/ruby/library/date/valid_time_spec.rb6
-rw-r--r--spec/ruby/library/date/wday_spec.rb9
-rw-r--r--spec/ruby/library/date/wednesday_spec.rb8
-rw-r--r--spec/ruby/library/date/yday_spec.rb6
-rw-r--r--spec/ruby/library/date/year_spec.rb9
-rw-r--r--spec/ruby/library/date/zone_to_diff_spec.rb6
-rw-r--r--spec/ruby/library/datetime/_strptime_spec.rb6
-rw-r--r--spec/ruby/library/datetime/civil_spec.rb6
-rw-r--r--spec/ruby/library/datetime/commercial_spec.rb6
-rw-r--r--spec/ruby/library/datetime/hour_spec.rb47
-rw-r--r--spec/ruby/library/datetime/httpdate_spec.rb6
-rw-r--r--spec/ruby/library/datetime/iso8601_spec.rb10
-rw-r--r--spec/ruby/library/datetime/jd_spec.rb6
-rw-r--r--spec/ruby/library/datetime/jisx0301_spec.rb10
-rw-r--r--spec/ruby/library/datetime/min_spec.rb6
-rw-r--r--spec/ruby/library/datetime/minute_spec.rb6
-rw-r--r--spec/ruby/library/datetime/new_offset_spec.rb6
-rw-r--r--spec/ruby/library/datetime/new_spec.rb52
-rw-r--r--spec/ruby/library/datetime/now_spec.rb25
-rw-r--r--spec/ruby/library/datetime/offset_spec.rb6
-rw-r--r--spec/ruby/library/datetime/ordinal_spec.rb6
-rw-r--r--spec/ruby/library/datetime/parse_spec.rb127
-rw-r--r--spec/ruby/library/datetime/rfc2822_spec.rb6
-rw-r--r--spec/ruby/library/datetime/rfc3339_spec.rb10
-rw-r--r--spec/ruby/library/datetime/rfc822_spec.rb6
-rw-r--r--spec/ruby/library/datetime/sec_fraction_spec.rb6
-rw-r--r--spec/ruby/library/datetime/sec_spec.rb6
-rw-r--r--spec/ruby/library/datetime/second_fraction_spec.rb6
-rw-r--r--spec/ruby/library/datetime/second_spec.rb6
-rw-r--r--spec/ruby/library/datetime/shared/min.rb40
-rw-r--r--spec/ruby/library/datetime/shared/sec.rb45
-rw-r--r--spec/ruby/library/datetime/strftime_spec.rb51
-rw-r--r--spec/ruby/library/datetime/strptime_spec.rb6
-rw-r--r--spec/ruby/library/datetime/to_date_spec.rb37
-rw-r--r--spec/ruby/library/datetime/to_datetime_spec.rb9
-rw-r--r--spec/ruby/library/datetime/to_s_spec.rb17
-rw-r--r--spec/ruby/library/datetime/to_time_spec.rb38
-rw-r--r--spec/ruby/library/datetime/xmlschema_spec.rb10
-rw-r--r--spec/ruby/library/datetime/zone_spec.rb6
-rw-r--r--spec/ruby/library/delegate/delegate_class/instance_method_spec.rb52
-rw-r--r--spec/ruby/library/delegate/delegate_class/instance_methods_spec.rb26
-rw-r--r--spec/ruby/library/delegate/delegate_class/private_instance_methods_spec.rb23
-rw-r--r--spec/ruby/library/delegate/delegate_class/protected_instance_methods_spec.rb29
-rw-r--r--spec/ruby/library/delegate/delegate_class/public_instance_methods_spec.rb25
-rw-r--r--spec/ruby/library/delegate/delegate_class/respond_to_missing_spec.rb23
-rw-r--r--spec/ruby/library/delegate/delegator/case_compare_spec.rb11
-rw-r--r--spec/ruby/library/delegate/delegator/compare_spec.rb11
-rw-r--r--spec/ruby/library/delegate/delegator/complement_spec.rb11
-rw-r--r--spec/ruby/library/delegate/delegator/eql_spec.rb46
-rw-r--r--spec/ruby/library/delegate/delegator/equal_spec.rb13
-rw-r--r--spec/ruby/library/delegate/delegator/equal_value_spec.rb24
-rw-r--r--spec/ruby/library/delegate/delegator/frozen_spec.rb39
-rw-r--r--spec/ruby/library/delegate/delegator/hash_spec.rb11
-rw-r--r--spec/ruby/library/delegate/delegator/marshal_spec.rb21
-rw-r--r--spec/ruby/library/delegate/delegator/method_spec.rb69
-rw-r--r--spec/ruby/library/delegate/delegator/methods_spec.rb37
-rw-r--r--spec/ruby/library/delegate/delegator/not_equal_spec.rb24
-rw-r--r--spec/ruby/library/delegate/delegator/not_spec.rb11
-rw-r--r--spec/ruby/library/delegate/delegator/private_methods_spec.rb20
-rw-r--r--spec/ruby/library/delegate/delegator/protected_methods_spec.rb18
-rw-r--r--spec/ruby/library/delegate/delegator/public_methods_spec.rb18
-rw-r--r--spec/ruby/library/delegate/delegator/send_spec.rb26
-rw-r--r--spec/ruby/library/delegate/delegator/taint_spec.rb23
-rw-r--r--spec/ruby/library/delegate/delegator/tap_spec.rb16
-rw-r--r--spec/ruby/library/delegate/delegator/trust_spec.rb22
-rw-r--r--spec/ruby/library/delegate/delegator/untaint_spec.rb24
-rw-r--r--spec/ruby/library/delegate/delegator/untrust_spec.rb23
-rw-r--r--spec/ruby/library/delegate/fixtures/classes.rb60
-rw-r--r--spec/ruby/library/digest/bubblebabble_spec.rb29
-rw-r--r--spec/ruby/library/digest/hexencode_spec.rb31
-rw-r--r--spec/ruby/library/digest/md5/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/md5/block_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/md5/digest_bang_spec.rb13
-rw-r--r--spec/ruby/library/digest/md5/digest_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/md5/digest_spec.rb32
-rw-r--r--spec/ruby/library/digest/md5/equal_spec.rb38
-rw-r--r--spec/ruby/library/digest/md5/file_spec.rb43
-rw-r--r--spec/ruby/library/digest/md5/hexdigest_bang_spec.rb14
-rw-r--r--spec/ruby/library/digest/md5/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/md5/inspect_spec.rb12
-rw-r--r--spec/ruby/library/digest/md5/length_spec.rb8
-rw-r--r--spec/ruby/library/digest/md5/reset_spec.rb15
-rw-r--r--spec/ruby/library/digest/md5/shared/constants.rb16
-rw-r--r--spec/ruby/library/digest/md5/shared/length.rb8
-rw-r--r--spec/ruby/library/digest/md5/shared/sample.rb17
-rw-r--r--spec/ruby/library/digest/md5/shared/update.rb7
-rw-r--r--spec/ruby/library/digest/md5/size_spec.rb8
-rw-r--r--spec/ruby/library/digest/md5/to_s_spec.rb24
-rw-r--r--spec/ruby/library/digest/md5/update_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha1/digest_spec.rb20
-rw-r--r--spec/ruby/library/digest/sha1/file_spec.rb43
-rw-r--r--spec/ruby/library/digest/sha1/shared/constants.rb17
-rw-r--r--spec/ruby/library/digest/sha256/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha256/block_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha256/digest_bang_spec.rb13
-rw-r--r--spec/ruby/library/digest/sha256/digest_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha256/digest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha256/equal_spec.rb37
-rw-r--r--spec/ruby/library/digest/sha256/file_spec.rb43
-rw-r--r--spec/ruby/library/digest/sha256/hexdigest_bang_spec.rb14
-rw-r--r--spec/ruby/library/digest/sha256/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha256/inspect_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha256/length_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha256/reset_spec.rb15
-rw-r--r--spec/ruby/library/digest/sha256/shared/constants.rb17
-rw-r--r--spec/ruby/library/digest/sha256/shared/length.rb8
-rw-r--r--spec/ruby/library/digest/sha256/shared/update.rb7
-rw-r--r--spec/ruby/library/digest/sha256/size_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha256/to_s_spec.rb21
-rw-r--r--spec/ruby/library/digest/sha256/update_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha384/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha384/block_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha384/digest_bang_spec.rb13
-rw-r--r--spec/ruby/library/digest/sha384/digest_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha384/digest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha384/equal_spec.rb37
-rw-r--r--spec/ruby/library/digest/sha384/file_spec.rb43
-rw-r--r--spec/ruby/library/digest/sha384/hexdigest_bang_spec.rb14
-rw-r--r--spec/ruby/library/digest/sha384/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha384/inspect_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha384/length_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha384/reset_spec.rb15
-rw-r--r--spec/ruby/library/digest/sha384/shared/constants.rb18
-rw-r--r--spec/ruby/library/digest/sha384/shared/length.rb8
-rw-r--r--spec/ruby/library/digest/sha384/shared/update.rb7
-rw-r--r--spec/ruby/library/digest/sha384/size_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha384/to_s_spec.rb21
-rw-r--r--spec/ruby/library/digest/sha384/update_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha512/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha512/block_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha512/digest_bang_spec.rb13
-rw-r--r--spec/ruby/library/digest/sha512/digest_length_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha512/digest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha512/equal_spec.rb37
-rw-r--r--spec/ruby/library/digest/sha512/file_spec.rb43
-rw-r--r--spec/ruby/library/digest/sha512/hexdigest_bang_spec.rb14
-rw-r--r--spec/ruby/library/digest/sha512/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha512/inspect_spec.rb12
-rw-r--r--spec/ruby/library/digest/sha512/length_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha512/reset_spec.rb15
-rw-r--r--spec/ruby/library/digest/sha512/shared/constants.rb17
-rw-r--r--spec/ruby/library/digest/sha512/shared/length.rb8
-rw-r--r--spec/ruby/library/digest/sha512/shared/update.rb7
-rw-r--r--spec/ruby/library/digest/sha512/size_spec.rb8
-rw-r--r--spec/ruby/library/digest/sha512/to_s_spec.rb21
-rw-r--r--spec/ruby/library/digest/sha512/update_spec.rb7
-rw-r--r--spec/ruby/library/drb/fixtures/test_server.rb8
-rw-r--r--spec/ruby/library/drb/start_service_spec.rb28
-rw-r--r--spec/ruby/library/erb/def_class_spec.rb29
-rw-r--r--spec/ruby/library/erb/def_method_spec.rb26
-rw-r--r--spec/ruby/library/erb/def_module_spec.rb27
-rw-r--r--spec/ruby/library/erb/defmethod/def_erb_method_spec.rb63
-rw-r--r--spec/ruby/library/erb/filename_spec.rb40
-rw-r--r--spec/ruby/library/erb/new_spec.rb134
-rw-r--r--spec/ruby/library/erb/result_spec.rb86
-rw-r--r--spec/ruby/library/erb/run_spec.rb97
-rw-r--r--spec/ruby/library/erb/src_spec.rb33
-rw-r--r--spec/ruby/library/erb/util/h_spec.rb7
-rw-r--r--spec/ruby/library/erb/util/html_escape_spec.rb8
-rw-r--r--spec/ruby/library/erb/util/shared/html_escape.rb42
-rw-r--r--spec/ruby/library/erb/util/shared/url_encode.rb50
-rw-r--r--spec/ruby/library/erb/util/u_spec.rb8
-rw-r--r--spec/ruby/library/erb/util/url_encode_spec.rb7
-rw-r--r--spec/ruby/library/etc/endgrent_spec.rb7
-rw-r--r--spec/ruby/library/etc/endpwent_spec.rb7
-rw-r--r--spec/ruby/library/etc/getgrent_spec.rb7
-rw-r--r--spec/ruby/library/etc/getgrgid_spec.rb70
-rw-r--r--spec/ruby/library/etc/getgrnam_spec.rb30
-rw-r--r--spec/ruby/library/etc/getlogin_spec.rb38
-rw-r--r--spec/ruby/library/etc/getpwent_spec.rb7
-rw-r--r--spec/ruby/library/etc/getpwnam_spec.rb28
-rw-r--r--spec/ruby/library/etc/getpwuid_spec.rb36
-rw-r--r--spec/ruby/library/etc/group_spec.rb18
-rw-r--r--spec/ruby/library/etc/nprocessors_spec.rb9
-rw-r--r--spec/ruby/library/etc/shared/windows.rb7
-rw-r--r--spec/ruby/library/etc/struct_group_spec.rb31
-rw-r--r--spec/ruby/library/etc/struct_passwd_spec.rb43
-rw-r--r--spec/ruby/library/expect/expect_spec.rb62
-rw-r--r--spec/ruby/library/fiber/alive_spec.rb48
-rw-r--r--spec/ruby/library/fiber/current_spec.rb53
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb14
-rw-r--r--spec/ruby/library/fiber/transfer_spec.rb51
-rw-r--r--spec/ruby/library/find/find_spec.rb30
-rw-r--r--spec/ruby/library/find/fixtures/common.rb174
-rw-r--r--spec/ruby/library/find/prune_spec.rb12
-rw-r--r--spec/ruby/library/getoptlong/each_option_spec.rb7
-rw-r--r--spec/ruby/library/getoptlong/each_spec.rb7
-rw-r--r--spec/ruby/library/getoptlong/error_message_spec.rb23
-rw-r--r--spec/ruby/library/getoptlong/get_option_spec.rb7
-rw-r--r--spec/ruby/library/getoptlong/get_spec.rb7
-rw-r--r--spec/ruby/library/getoptlong/initialize_spec.rb28
-rw-r--r--spec/ruby/library/getoptlong/ordering_spec.rb38
-rw-r--r--spec/ruby/library/getoptlong/set_options_spec.rb98
-rw-r--r--spec/ruby/library/getoptlong/shared/each.rb18
-rw-r--r--spec/ruby/library/getoptlong/shared/get.rb64
-rw-r--r--spec/ruby/library/getoptlong/terminate_spec.rb30
-rw-r--r--spec/ruby/library/getoptlong/terminated_spec.rb17
-rw-r--r--spec/ruby/library/ipaddr/hton_spec.rb30
-rw-r--r--spec/ruby/library/ipaddr/ipv4_conversion_spec.rb46
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb93
-rw-r--r--spec/ruby/library/ipaddr/operator_spec.rb87
-rw-r--r--spec/ruby/library/ipaddr/reverse_spec.rb27
-rw-r--r--spec/ruby/library/ipaddr/to_s_spec.rb20
-rw-r--r--spec/ruby/library/logger/device/close_spec.rb22
-rw-r--r--spec/ruby/library/logger/device/new_spec.rb47
-rw-r--r--spec/ruby/library/logger/device/write_spec.rb42
-rw-r--r--spec/ruby/library/logger/fixtures/common.rb9
-rw-r--r--spec/ruby/library/logger/logger/add_spec.rb81
-rw-r--r--spec/ruby/library/logger/logger/close_spec.rb20
-rw-r--r--spec/ruby/library/logger/logger/datetime_format_spec.rb60
-rw-r--r--spec/ruby/library/logger/logger/debug_spec.rb52
-rw-r--r--spec/ruby/library/logger/logger/error_spec.rb53
-rw-r--r--spec/ruby/library/logger/logger/fatal_spec.rb53
-rw-r--r--spec/ruby/library/logger/logger/info_spec.rb53
-rw-r--r--spec/ruby/library/logger/logger/new_spec.rb120
-rw-r--r--spec/ruby/library/logger/logger/unknown_spec.rb36
-rw-r--r--spec/ruby/library/logger/logger/warn_spec.rb53
-rw-r--r--spec/ruby/library/logger/severity_spec.rb13
-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/build_spec.rb73
-rw-r--r--spec/ruby/library/matrix/clone_spec.rb25
-rw-r--r--spec/ruby/library/matrix/coerce_spec.rb10
-rw-r--r--spec/ruby/library/matrix/collect_spec.rb6
-rw-r--r--spec/ruby/library/matrix/column_size_spec.rb13
-rw-r--r--spec/ruby/library/matrix/column_spec.rb35
-rw-r--r--spec/ruby/library/matrix/column_vector_spec.rb25
-rw-r--r--spec/ruby/library/matrix/column_vectors_spec.rb26
-rw-r--r--spec/ruby/library/matrix/columns_spec.rb42
-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.rb65
-rw-r--r--spec/ruby/library/matrix/det_spec.rb7
-rw-r--r--spec/ruby/library/matrix/determinant_spec.rb7
-rw-r--r--spec/ruby/library/matrix/diagonal_spec.rb72
-rw-r--r--spec/ruby/library/matrix/divide_spec.rb55
-rw-r--r--spec/ruby/library/matrix/each_spec.rb74
-rw-r--r--spec/ruby/library/matrix/each_with_index_spec.rb81
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalue_matrix_spec.rb9
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalues_spec.rb22
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvector_matrix_spec.rb20
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvectors_spec.rb22
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/initialize_spec.rb24
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/to_a_spec.rb18
-rw-r--r--spec/ruby/library/matrix/element_reference_spec.rb23
-rw-r--r--spec/ruby/library/matrix/empty_spec.rb68
-rw-r--r--spec/ruby/library/matrix/eql_spec.rb11
-rw-r--r--spec/ruby/library/matrix/equal_value_spec.rb11
-rw-r--r--spec/ruby/library/matrix/exponent_spec.rb51
-rw-r--r--spec/ruby/library/matrix/find_index_spec.rb146
-rw-r--r--spec/ruby/library/matrix/fixtures/classes.rb7
-rw-r--r--spec/ruby/library/matrix/hash_spec.rb15
-rw-r--r--spec/ruby/library/matrix/hermitian_spec.rb34
-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.rb27
-rw-r--r--spec/ruby/library/matrix/inv_spec.rb7
-rw-r--r--spec/ruby/library/matrix/inverse_from_spec.rb6
-rw-r--r--spec/ruby/library/matrix/inverse_spec.rb7
-rw-r--r--spec/ruby/library/matrix/lower_triangular_spec.rb24
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/determinant_spec.rb21
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/initialize_spec.rb13
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/l_spec.rb18
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/p_spec.rb18
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/solve_spec.rb53
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/to_a_spec.rb33
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/u_spec.rb18
-rw-r--r--spec/ruby/library/matrix/map_spec.rb6
-rw-r--r--spec/ruby/library/matrix/minor_spec.rb85
-rw-r--r--spec/ruby/library/matrix/minus_spec.rb42
-rw-r--r--spec/ruby/library/matrix/multiply_spec.rb68
-rw-r--r--spec/ruby/library/matrix/new_spec.rb8
-rw-r--r--spec/ruby/library/matrix/normal_spec.rb26
-rw-r--r--spec/ruby/library/matrix/orthogonal_spec.rb26
-rw-r--r--spec/ruby/library/matrix/permutation_spec.rb32
-rw-r--r--spec/ruby/library/matrix/plus_spec.rb42
-rw-r--r--spec/ruby/library/matrix/rank_spec.rb19
-rw-r--r--spec/ruby/library/matrix/real_spec.rb42
-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.rb31
-rw-r--r--spec/ruby/library/matrix/round_spec.rb21
-rw-r--r--spec/ruby/library/matrix/row_size_spec.rb13
-rw-r--r--spec/ruby/library/matrix/row_spec.rb36
-rw-r--r--spec/ruby/library/matrix/row_vector_spec.rb24
-rw-r--r--spec/ruby/library/matrix/row_vectors_spec.rb26
-rw-r--r--spec/ruby/library/matrix/rows_spec.rb41
-rw-r--r--spec/ruby/library/matrix/scalar/Fail_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/Raise_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/divide_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/exponent_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/included_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/initialize_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/minus_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/multiply_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar/plus_spec.rb6
-rw-r--r--spec/ruby/library/matrix/scalar_spec.rb67
-rw-r--r--spec/ruby/library/matrix/shared/collect.rb26
-rw-r--r--spec/ruby/library/matrix/shared/conjugate.rb20
-rw-r--r--spec/ruby/library/matrix/shared/determinant.rb38
-rw-r--r--spec/ruby/library/matrix/shared/equal_value.rb33
-rw-r--r--spec/ruby/library/matrix/shared/identity.rb19
-rw-r--r--spec/ruby/library/matrix/shared/imaginary.rb20
-rw-r--r--spec/ruby/library/matrix/shared/inverse.rb38
-rw-r--r--spec/ruby/library/matrix/shared/rectangular.rb18
-rw-r--r--spec/ruby/library/matrix/shared/trace.rb12
-rw-r--r--spec/ruby/library/matrix/shared/transpose.rb19
-rw-r--r--spec/ruby/library/matrix/singular_spec.rb31
-rw-r--r--spec/ruby/library/matrix/spec_helper.rb35
-rw-r--r--spec/ruby/library/matrix/square_spec.rb28
-rw-r--r--spec/ruby/library/matrix/symmetric_spec.rb29
-rw-r--r--spec/ruby/library/matrix/t_spec.rb6
-rw-r--r--spec/ruby/library/matrix/to_a_spec.rb11
-rw-r--r--spec/ruby/library/matrix/to_s_spec.rb6
-rw-r--r--spec/ruby/library/matrix/tr_spec.rb7
-rw-r--r--spec/ruby/library/matrix/trace_spec.rb7
-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.rb28
-rw-r--r--spec/ruby/library/matrix/upper_triangular_spec.rb24
-rw-r--r--spec/ruby/library/matrix/vector/cross_product_spec.rb14
-rw-r--r--spec/ruby/library/matrix/vector/each2_spec.rb49
-rw-r--r--spec/ruby/library/matrix/vector/eql_spec.rb16
-rw-r--r--spec/ruby/library/matrix/vector/inner_product_spec.rb22
-rw-r--r--spec/ruby/library/matrix/vector/normalize_spec.rb18
-rw-r--r--spec/ruby/library/matrix/zero_spec.rb52
-rw-r--r--spec/ruby/library/net/FTPError_spec.rb8
-rw-r--r--spec/ruby/library/net/FTPPermError_spec.rb12
-rw-r--r--spec/ruby/library/net/FTPProtoError_spec.rb12
-rw-r--r--spec/ruby/library/net/FTPReplyError_spec.rb12
-rw-r--r--spec/ruby/library/net/FTPTempError_spec.rb12
-rw-r--r--spec/ruby/library/net/ftp/abort_spec.rb62
-rw-r--r--spec/ruby/library/net/ftp/acct_spec.rb58
-rw-r--r--spec/ruby/library/net/ftp/binary_spec.rb24
-rw-r--r--spec/ruby/library/net/ftp/chdir_spec.rb99
-rw-r--r--spec/ruby/library/net/ftp/close_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/closed_spec.rb21
-rw-r--r--spec/ruby/library/net/ftp/connect_spec.rb49
-rw-r--r--spec/ruby/library/net/ftp/debug_mode_spec.rb23
-rw-r--r--spec/ruby/library/net/ftp/default_passive_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/delete_spec.rb59
-rw-r--r--spec/ruby/library/net/ftp/dir_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/fixtures/default_passive.rb3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/passive.rb2
-rw-r--r--spec/ruby/library/net/ftp/fixtures/putbinaryfile3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/puttextfile3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/server.rb277
-rw-r--r--spec/ruby/library/net/ftp/get_spec.rb21
-rw-r--r--spec/ruby/library/net/ftp/getbinaryfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/getdir_spec.rb7
-rw-r--r--spec/ruby/library/net/ftp/gettextfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/help_spec.rb66
-rw-r--r--spec/ruby/library/net/ftp/initialize_spec.rb91
-rw-r--r--spec/ruby/library/net/ftp/last_response_code_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/last_response_spec.rb25
-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.rb195
-rw-r--r--spec/ruby/library/net/ftp/ls_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/mdtm_spec.rb38
-rw-r--r--spec/ruby/library/net/ftp/mkdir_spec.rb61
-rw-r--r--spec/ruby/library/net/ftp/mtime_spec.rb50
-rw-r--r--spec/ruby/library/net/ftp/nlst_spec.rb92
-rw-r--r--spec/ruby/library/net/ftp/noop_spec.rb38
-rw-r--r--spec/ruby/library/net/ftp/open_spec.rb55
-rw-r--r--spec/ruby/library/net/ftp/passive_spec.rb36
-rw-r--r--spec/ruby/library/net/ftp/put_spec.rb21
-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.rb53
-rw-r--r--spec/ruby/library/net/ftp/quit_spec.rb33
-rw-r--r--spec/ruby/library/net/ftp/rename_spec.rb94
-rw-r--r--spec/ruby/library/net/ftp/resume_spec.rb23
-rw-r--r--spec/ruby/library/net/ftp/retrbinary_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/retrlines_spec.rb34
-rw-r--r--spec/ruby/library/net/ftp/return_code_spec.rb24
-rw-r--r--spec/ruby/library/net/ftp/rmdir_spec.rb58
-rw-r--r--spec/ruby/library/net/ftp/sendcmd_spec.rb54
-rw-r--r--spec/ruby/library/net/ftp/set_socket_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/shared/getbinaryfile.rb150
-rw-r--r--spec/ruby/library/net/ftp/shared/gettextfile.rb100
-rw-r--r--spec/ruby/library/net/ftp/shared/last_response_code.rb25
-rw-r--r--spec/ruby/library/net/ftp/shared/list.rb104
-rw-r--r--spec/ruby/library/net/ftp/shared/putbinaryfile.rb167
-rw-r--r--spec/ruby/library/net/ftp/shared/puttextfile.rb120
-rw-r--r--spec/ruby/library/net/ftp/shared/pwd.rb3
-rw-r--r--spec/ruby/library/net/ftp/site_spec.rb53
-rw-r--r--spec/ruby/library/net/ftp/size_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/spec_helper.rb5
-rw-r--r--spec/ruby/library/net/ftp/status_spec.rb69
-rw-r--r--spec/ruby/library/net/ftp/storbinary_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/storlines_spec.rb43
-rw-r--r--spec/ruby/library/net/ftp/system_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/voidcmd_spec.rb54
-rw-r--r--spec/ruby/library/net/ftp/welcome_spec.rb25
-rw-r--r--spec/ruby/library/net/http/HTTPBadResponse_spec.rb8
-rw-r--r--spec/ruby/library/net/http/HTTPError_spec.rb12
-rw-r--r--spec/ruby/library/net/http/HTTPFatalError_spec.rb12
-rw-r--r--spec/ruby/library/net/http/HTTPHeaderSyntaxError_spec.rb8
-rw-r--r--spec/ruby/library/net/http/HTTPRetriableError_spec.rb12
-rw-r--r--spec/ruby/library/net/http/HTTPServerException_spec.rb12
-rw-r--r--spec/ruby/library/net/http/http/Proxy_spec.rb35
-rw-r--r--spec/ruby/library/net/http/http/active_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/address_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/close_on_empty_response_spec.rb10
-rw-r--r--spec/ruby/library/net/http/http/copy_spec.rb21
-rw-r--r--spec/ruby/library/net/http/http/default_port_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/delete_spec.rb21
-rw-r--r--spec/ruby/library/net/http/http/finish_spec.rb29
-rw-r--r--spec/ruby/library/net/http/http/fixtures/http_server.rb105
-rw-r--r--spec/ruby/library/net/http/http/get2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/get_print_spec.rb30
-rw-r--r--spec/ruby/library/net/http/http/get_response_spec.rb30
-rw-r--r--spec/ruby/library/net/http/http/get_spec.rb26
-rw-r--r--spec/ruby/library/net/http/http/head2_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/head_spec.rb25
-rw-r--r--spec/ruby/library/net/http/http/http_default_port_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/https_default_port_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/initialize_spec.rb46
-rw-r--r--spec/ruby/library/net/http/http/inspect_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/is_version_1_1_spec.rb7
-rw-r--r--spec/ruby/library/net/http/http/is_version_1_2_spec.rb7
-rw-r--r--spec/ruby/library/net/http/http/lock_spec.rb21
-rw-r--r--spec/ruby/library/net/http/http/mkcol_spec.rb21
-rw-r--r--spec/ruby/library/net/http/http/move_spec.rb25
-rw-r--r--spec/ruby/library/net/http/http/new_spec.rb86
-rw-r--r--spec/ruby/library/net/http/http/newobj_spec.rb48
-rw-r--r--spec/ruby/library/net/http/http/open_timeout_spec.rb35
-rw-r--r--spec/ruby/library/net/http/http/options_spec.rb25
-rw-r--r--spec/ruby/library/net/http/http/port_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/post2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/post_form_spec.rb22
-rw-r--r--spec/ruby/library/net/http/http/post_spec.rb77
-rw-r--r--spec/ruby/library/net/http/http/propfind_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/proppatch_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/proxy_address_spec.rb31
-rw-r--r--spec/ruby/library/net/http/http/proxy_class_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/proxy_pass_spec.rb39
-rw-r--r--spec/ruby/library/net/http/http/proxy_port_spec.rb39
-rw-r--r--spec/ruby/library/net/http/http/proxy_user_spec.rb39
-rw-r--r--spec/ruby/library/net/http/http/put2_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/put_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/read_timeout_spec.rb24
-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.rb109
-rw-r--r--spec/ruby/library/net/http/http/request_types_spec.rb254
-rw-r--r--spec/ruby/library/net/http/http/send_request_spec.rb61
-rw-r--r--spec/ruby/library/net/http/http/set_debug_output_spec.rb33
-rw-r--r--spec/ruby/library/net/http/http/shared/request_get.rb41
-rw-r--r--spec/ruby/library/net/http/http/shared/request_head.rb41
-rw-r--r--spec/ruby/library/net/http/http/shared/request_post.rb41
-rw-r--r--spec/ruby/library/net/http/http/shared/request_put.rb41
-rw-r--r--spec/ruby/library/net/http/http/shared/started.rb26
-rw-r--r--spec/ruby/library/net/http/http/shared/version_1_1.rb6
-rw-r--r--spec/ruby/library/net/http/http/shared/version_1_2.rb6
-rw-r--r--spec/ruby/library/net/http/http/socket_type_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/start_spec.rb111
-rw-r--r--spec/ruby/library/net/http/http/started_spec.rb8
-rw-r--r--spec/ruby/library/net/http/http/trace_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/unlock_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/use_ssl_spec.rb9
-rw-r--r--spec/ruby/library/net/http/http/version_1_1_spec.rb7
-rw-r--r--spec/ruby/library/net/http/http/version_1_2_spec.rb20
-rw-r--r--spec/ruby/library/net/http/httpexceptions/fixtures/classes.rb5
-rw-r--r--spec/ruby/library/net/http/httpexceptions/initialize_spec.rb17
-rw-r--r--spec/ruby/library/net/http/httpexceptions/response_spec.rb10
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_exist_spec.rb22
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_spec.rb30
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/body_stream_spec.rb32
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/exec_spec.rb131
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/inspect_spec.rb25
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/method_spec.rb15
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/path_spec.rb12
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/request_body_permitted_spec.rb12
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/response_body_permitted_spec.rb12
-rw-r--r--spec/ruby/library/net/http/httpgenericrequest/set_body_internal_spec.rb21
-rw-r--r--spec/ruby/library/net/http/httpheader/add_field_spec.rb31
-rw-r--r--spec/ruby/library/net/http/httpheader/basic_auth_spec.rb14
-rw-r--r--spec/ruby/library/net/http/httpheader/canonical_each_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/chunked_spec.rb22
-rw-r--r--spec/ruby/library/net/http/httpheader/content_length_spec.rb54
-rw-r--r--spec/ruby/library/net/http/httpheader/content_range_spec.rb32
-rw-r--r--spec/ruby/library/net/http/httpheader/content_type_spec.rb26
-rw-r--r--spec/ruby/library/net/http/httpheader/delete_spec.rb30
-rw-r--r--spec/ruby/library/net/http/httpheader/each_capitalized_name_spec.rb35
-rw-r--r--spec/ruby/library/net/http/httpheader/each_capitalized_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpheader/each_header_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/each_key_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/each_name_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/each_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/each_value_spec.rb35
-rw-r--r--spec/ruby/library/net/http/httpheader/element_reference_spec.rb39
-rw-r--r--spec/ruby/library/net/http/httpheader/element_set_spec.rb41
-rw-r--r--spec/ruby/library/net/http/httpheader/fetch_spec.rb68
-rw-r--r--spec/ruby/library/net/http/httpheader/fixtures/classes.rb11
-rw-r--r--spec/ruby/library/net/http/httpheader/form_data_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/get_fields_spec.rb39
-rw-r--r--spec/ruby/library/net/http/httpheader/initialize_http_header_spec.rb22
-rw-r--r--spec/ruby/library/net/http/httpheader/key_spec.rb21
-rw-r--r--spec/ruby/library/net/http/httpheader/length_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/main_type_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httpheader/proxy_basic_auth_spec.rb14
-rw-r--r--spec/ruby/library/net/http/httpheader/range_length_spec.rb32
-rw-r--r--spec/ruby/library/net/http/httpheader/range_spec.rb48
-rw-r--r--spec/ruby/library/net/http/httpheader/set_content_type_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/set_form_data_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/set_range_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/each_capitalized.rb31
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/each_header.rb31
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/each_name.rb31
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/set_content_type.rb18
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/set_form_data.rb27
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/set_range.rb89
-rw-r--r--spec/ruby/library/net/http/httpheader/shared/size.rb18
-rw-r--r--spec/ruby/library/net/http/httpheader/size_spec.rb8
-rw-r--r--spec/ruby/library/net/http/httpheader/sub_type_spec.rb32
-rw-r--r--spec/ruby/library/net/http/httpheader/to_hash_spec.rb25
-rw-r--r--spec/ruby/library/net/http/httpheader/type_params_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httprequest/initialize_spec.rb45
-rw-r--r--spec/ruby/library/net/http/httpresponse/body_permitted_spec.rb13
-rw-r--r--spec/ruby/library/net/http/httpresponse/body_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpresponse/code_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httpresponse/code_type_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httpresponse/entity_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_type_spec.rb24
-rw-r--r--spec/ruby/library/net/http/httpresponse/exception_type_spec.rb13
-rw-r--r--spec/ruby/library/net/http/httpresponse/header_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/http_version_spec.rb12
-rw-r--r--spec/ruby/library/net/http/httpresponse/initialize_spec.rb11
-rw-r--r--spec/ruby/library/net/http/httpresponse/inspect_spec.rb15
-rw-r--r--spec/ruby/library/net/http/httpresponse/message_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/msg_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_body_spec.rb86
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_header_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_new_spec.rb22
-rw-r--r--spec/ruby/library/net/http/httpresponse/reading_body_spec.rb58
-rw-r--r--spec/ruby/library/net/http/httpresponse/response_spec.rb9
-rw-r--r--spec/ruby/library/net/http/httpresponse/shared/body.rb18
-rw-r--r--spec/ruby/library/net/http/httpresponse/value_spec.rb24
-rw-r--r--spec/ruby/library/observer/add_observer_spec.rb23
-rw-r--r--spec/ruby/library/observer/count_observers_spec.rb23
-rw-r--r--spec/ruby/library/observer/delete_observer_spec.rb19
-rw-r--r--spec/ruby/library/observer/delete_observers_spec.rb19
-rw-r--r--spec/ruby/library/observer/fixtures/classes.rb17
-rw-r--r--spec/ruby/library/observer/notify_observers_spec.rb31
-rw-r--r--spec/ruby/library/open3/capture2_spec.rb6
-rw-r--r--spec/ruby/library/open3/capture2e_spec.rb6
-rw-r--r--spec/ruby/library/open3/capture3_spec.rb6
-rw-r--r--spec/ruby/library/open3/pipeline_r_spec.rb6
-rw-r--r--spec/ruby/library/open3/pipeline_rw_spec.rb6
-rw-r--r--spec/ruby/library/open3/pipeline_spec.rb6
-rw-r--r--spec/ruby/library/open3/pipeline_start_spec.rb6
-rw-r--r--spec/ruby/library/open3/pipeline_w_spec.rb6
-rw-r--r--spec/ruby/library/open3/popen2_spec.rb6
-rw-r--r--spec/ruby/library/open3/popen2e_spec.rb6
-rw-r--r--spec/ruby/library/open3/popen3_spec.rb43
-rw-r--r--spec/ruby/library/openssl/cipher_spec.rb9
-rw-r--r--spec/ruby/library/openssl/config/freeze_spec.rb20
-rw-r--r--spec/ruby/library/openssl/hmac/digest_spec.rb16
-rw-r--r--spec/ruby/library/openssl/hmac/hexdigest_spec.rb16
-rw-r--r--spec/ruby/library/openssl/random/pseudo_bytes_spec.rb8
-rw-r--r--spec/ruby/library/openssl/random/random_bytes_spec.rb6
-rw-r--r--spec/ruby/library/openssl/random/shared/random_bytes.rb29
-rw-r--r--spec/ruby/library/openssl/shared/constants.rb11
-rw-r--r--spec/ruby/library/openssl/x509/name/parse_spec.rb48
-rw-r--r--spec/ruby/library/openstruct/delete_field_spec.rb19
-rw-r--r--spec/ruby/library/openstruct/element_reference_spec.rb13
-rw-r--r--spec/ruby/library/openstruct/element_set_spec.rb13
-rw-r--r--spec/ruby/library/openstruct/equal_value_spec.rb28
-rw-r--r--spec/ruby/library/openstruct/fixtures/classes.rb4
-rw-r--r--spec/ruby/library/openstruct/frozen_spec.rb38
-rw-r--r--spec/ruby/library/openstruct/initialize_spec.rb8
-rw-r--r--spec/ruby/library/openstruct/inspect_spec.rb8
-rw-r--r--spec/ruby/library/openstruct/marshal_dump_spec.rb9
-rw-r--r--spec/ruby/library/openstruct/marshal_load_spec.rb12
-rw-r--r--spec/ruby/library/openstruct/method_missing_spec.rb47
-rw-r--r--spec/ruby/library/openstruct/new_spec.rb20
-rw-r--r--spec/ruby/library/openstruct/shared/inspect.rb20
-rw-r--r--spec/ruby/library/openstruct/to_h_spec.rb29
-rw-r--r--spec/ruby/library/openstruct/to_s_spec.rb8
-rw-r--r--spec/ruby/library/optionparser/order_spec.rb32
-rw-r--r--spec/ruby/library/optionparser/parse_spec.rb32
-rw-r--r--spec/ruby/library/pathname/absolute_spec.rb23
-rw-r--r--spec/ruby/library/pathname/empty_spec.rb34
-rw-r--r--spec/ruby/library/pathname/equal_value_spec.rb15
-rw-r--r--spec/ruby/library/pathname/hash_spec.rb15
-rw-r--r--spec/ruby/library/pathname/join_spec.rb40
-rw-r--r--spec/ruby/library/pathname/new_spec.rb28
-rw-r--r--spec/ruby/library/pathname/parent_spec.rb19
-rw-r--r--spec/ruby/library/pathname/realdirpath_spec.rb10
-rw-r--r--spec/ruby/library/pathname/realpath_spec.rb10
-rw-r--r--spec/ruby/library/pathname/relative_path_from_spec.rb51
-rw-r--r--spec/ruby/library/pathname/relative_spec.rb23
-rw-r--r--spec/ruby/library/pathname/root_spec.rb27
-rw-r--r--spec/ruby/library/pathname/sub_spec.rb16
-rw-r--r--spec/ruby/library/pp/pp_spec.rb25
-rw-r--r--spec/ruby/library/prime/each_spec.rb167
-rw-r--r--spec/ruby/library/prime/instance_spec.rb21
-rw-r--r--spec/ruby/library/prime/int_from_prime_division_spec.rb13
-rw-r--r--spec/ruby/library/prime/integer/each_prime_spec.rb13
-rw-r--r--spec/ruby/library/prime/integer/from_prime_division_spec.rb13
-rw-r--r--spec/ruby/library/prime/integer/prime_division_spec.rb19
-rw-r--r--spec/ruby/library/prime/integer/prime_spec.rb17
-rw-r--r--spec/ruby/library/prime/next_spec.rb7
-rw-r--r--spec/ruby/library/prime/prime_division_spec.rb25
-rw-r--r--spec/ruby/library/prime/prime_spec.rb17
-rw-r--r--spec/ruby/library/prime/shared/next.rb8
-rw-r--r--spec/ruby/library/prime/succ_spec.rb7
-rw-r--r--spec/ruby/library/readline/basic_quote_characters_spec.rb18
-rw-r--r--spec/ruby/library/readline/basic_word_break_characters_spec.rb16
-rw-r--r--spec/ruby/library/readline/completer_quote_characters_spec.rb16
-rw-r--r--spec/ruby/library/readline/completer_word_break_characters_spec.rb16
-rw-r--r--spec/ruby/library/readline/completion_append_character_spec.rb16
-rw-r--r--spec/ruby/library/readline/completion_case_fold_spec.rb18
-rw-r--r--spec/ruby/library/readline/completion_proc_spec.rb22
-rw-r--r--spec/ruby/library/readline/constants_spec.rb18
-rw-r--r--spec/ruby/library/readline/emacs_editing_mode_spec.rb11
-rw-r--r--spec/ruby/library/readline/filename_quote_characters_spec.rb18
-rw-r--r--spec/ruby/library/readline/history/append_spec.rb28
-rw-r--r--spec/ruby/library/readline/history/delete_at_spec.rb45
-rw-r--r--spec/ruby/library/readline/history/each_spec.rb29
-rw-r--r--spec/ruby/library/readline/history/element_reference_spec.rb40
-rw-r--r--spec/ruby/library/readline/history/element_set_spec.rb35
-rw-r--r--spec/ruby/library/readline/history/empty_spec.rb13
-rw-r--r--spec/ruby/library/readline/history/history_spec.rb9
-rw-r--r--spec/ruby/library/readline/history/length_spec.rb9
-rw-r--r--spec/ruby/library/readline/history/pop_spec.rb30
-rw-r--r--spec/ruby/library/readline/history/push_spec.rb26
-rw-r--r--spec/ruby/library/readline/history/shared/size.rb14
-rw-r--r--spec/ruby/library/readline/history/shift_spec.rb30
-rw-r--r--spec/ruby/library/readline/history/size_spec.rb9
-rw-r--r--spec/ruby/library/readline/history/to_s_spec.rb9
-rw-r--r--spec/ruby/library/readline/readline_spec.rb31
-rw-r--r--spec/ruby/library/readline/spec_helper.rb11
-rw-r--r--spec/ruby/library/readline/vi_editing_mode_spec.rb11
-rw-r--r--spec/ruby/library/resolv/get_address_spec.rb21
-rw-r--r--spec/ruby/library/resolv/get_addresses_spec.rb14
-rw-r--r--spec/ruby/library/resolv/get_name_spec.rb19
-rw-r--r--spec/ruby/library/resolv/get_names_spec.rb14
-rw-r--r--spec/ruby/library/rexml/attribute/clone_spec.rb11
-rw-r--r--spec/ruby/library/rexml/attribute/element_spec.rb23
-rw-r--r--spec/ruby/library/rexml/attribute/equal_value_spec.rb18
-rw-r--r--spec/ruby/library/rexml/attribute/hash_spec.rb13
-rw-r--r--spec/ruby/library/rexml/attribute/initialize_spec.rb29
-rw-r--r--spec/ruby/library/rexml/attribute/inspect_spec.rb20
-rw-r--r--spec/ruby/library/rexml/attribute/namespace_spec.rb24
-rw-r--r--spec/ruby/library/rexml/attribute/node_type_spec.rb10
-rw-r--r--spec/ruby/library/rexml/attribute/prefix_spec.rb18
-rw-r--r--spec/ruby/library/rexml/attribute/remove_spec.rb20
-rw-r--r--spec/ruby/library/rexml/attribute/to_s_spec.rb14
-rw-r--r--spec/ruby/library/rexml/attribute/to_string_spec.rb15
-rw-r--r--spec/ruby/library/rexml/attribute/value_spec.rb15
-rw-r--r--spec/ruby/library/rexml/attribute/write_spec.rb23
-rw-r--r--spec/ruby/library/rexml/attribute/xpath_spec.rb20
-rw-r--r--spec/ruby/library/rexml/attributes/add_spec.rb7
-rw-r--r--spec/ruby/library/rexml/attributes/append_spec.rb7
-rw-r--r--spec/ruby/library/rexml/attributes/delete_all_spec.rb31
-rw-r--r--spec/ruby/library/rexml/attributes/delete_spec.rb27
-rw-r--r--spec/ruby/library/rexml/attributes/each_attribute_spec.rb25
-rw-r--r--spec/ruby/library/rexml/attributes/each_spec.rb25
-rw-r--r--spec/ruby/library/rexml/attributes/element_reference_spec.rb19
-rw-r--r--spec/ruby/library/rexml/attributes/element_set_spec.rb26
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb14
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_spec.rb29
-rw-r--r--spec/ruby/library/rexml/attributes/initialize_spec.rb18
-rw-r--r--spec/ruby/library/rexml/attributes/length_spec.rb7
-rw-r--r--spec/ruby/library/rexml/attributes/namespaces_spec.rb6
-rw-r--r--spec/ruby/library/rexml/attributes/prefixes_spec.rb24
-rw-r--r--spec/ruby/library/rexml/attributes/shared/add.rb17
-rw-r--r--spec/ruby/library/rexml/attributes/shared/length.rb13
-rw-r--r--spec/ruby/library/rexml/attributes/size_spec.rb7
-rw-r--r--spec/ruby/library/rexml/attributes/to_a_spec.rb20
-rw-r--r--spec/ruby/library/rexml/cdata/clone_spec.rb10
-rw-r--r--spec/ruby/library/rexml/cdata/initialize_spec.rb24
-rw-r--r--spec/ruby/library/rexml/cdata/shared/to_s.rb11
-rw-r--r--spec/ruby/library/rexml/cdata/to_s_spec.rb7
-rw-r--r--spec/ruby/library/rexml/cdata/value_spec.rb7
-rw-r--r--spec/ruby/library/rexml/document/add_element_spec.rb31
-rw-r--r--spec/ruby/library/rexml/document/add_spec.rb57
-rw-r--r--spec/ruby/library/rexml/document/clone_spec.rb20
-rw-r--r--spec/ruby/library/rexml/document/doctype_spec.rb15
-rw-r--r--spec/ruby/library/rexml/document/encoding_spec.rb22
-rw-r--r--spec/ruby/library/rexml/document/expanded_name_spec.rb16
-rw-r--r--spec/ruby/library/rexml/document/new_spec.rb36
-rw-r--r--spec/ruby/library/rexml/document/node_type_spec.rb8
-rw-r--r--spec/ruby/library/rexml/document/root_spec.rb12
-rw-r--r--spec/ruby/library/rexml/document/stand_alone_spec.rb19
-rw-r--r--spec/ruby/library/rexml/document/version_spec.rb14
-rw-r--r--spec/ruby/library/rexml/document/write_spec.rb35
-rw-r--r--spec/ruby/library/rexml/document/xml_decl_spec.rb15
-rw-r--r--spec/ruby/library/rexml/element/add_attribute_spec.rb41
-rw-r--r--spec/ruby/library/rexml/element/add_attributes_spec.rb22
-rw-r--r--spec/ruby/library/rexml/element/add_element_spec.rb39
-rw-r--r--spec/ruby/library/rexml/element/add_namespace_spec.rb24
-rw-r--r--spec/ruby/library/rexml/element/add_text_spec.rb24
-rw-r--r--spec/ruby/library/rexml/element/attribute_spec.rb17
-rw-r--r--spec/ruby/library/rexml/element/attributes_spec.rb19
-rw-r--r--spec/ruby/library/rexml/element/cdatas_spec.rb24
-rw-r--r--spec/ruby/library/rexml/element/clone_spec.rb29
-rw-r--r--spec/ruby/library/rexml/element/comments_spec.rb20
-rw-r--r--spec/ruby/library/rexml/element/delete_attribute_spec.rb39
-rw-r--r--spec/ruby/library/rexml/element/delete_element_spec.rb49
-rw-r--r--spec/ruby/library/rexml/element/delete_namespace_spec.rb25
-rw-r--r--spec/ruby/library/rexml/element/document_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb35
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb31
-rw-r--r--spec/ruby/library/rexml/element/element_reference_spec.rb22
-rw-r--r--spec/ruby/library/rexml/element/get_text_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/has_attributes_spec.rb17
-rw-r--r--spec/ruby/library/rexml/element/has_elements_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb16
-rw-r--r--spec/ruby/library/rexml/element/inspect_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/instructions_spec.rb21
-rw-r--r--spec/ruby/library/rexml/element/namespace_spec.rb27
-rw-r--r--spec/ruby/library/rexml/element/namespaces_spec.rb32
-rw-r--r--spec/ruby/library/rexml/element/new_spec.rb35
-rw-r--r--spec/ruby/library/rexml/element/next_element_spec.rb19
-rw-r--r--spec/ruby/library/rexml/element/node_type_spec.rb8
-rw-r--r--spec/ruby/library/rexml/element/prefixes_spec.rb23
-rw-r--r--spec/ruby/library/rexml/element/previous_element_spec.rb20
-rw-r--r--spec/ruby/library/rexml/element/raw_spec.rb24
-rw-r--r--spec/ruby/library/rexml/element/root_spec.rb28
-rw-r--r--spec/ruby/library/rexml/element/text_spec.rb46
-rw-r--r--spec/ruby/library/rexml/element/texts_spec.rb16
-rw-r--r--spec/ruby/library/rexml/element/whitespace_spec.rb23
-rw-r--r--spec/ruby/library/rexml/node/each_recursive_spec.rb21
-rw-r--r--spec/ruby/library/rexml/node/find_first_recursive_spec.rb25
-rw-r--r--spec/ruby/library/rexml/node/index_in_parent_spec.rb15
-rw-r--r--spec/ruby/library/rexml/node/next_sibling_node_spec.rb21
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb21
-rw-r--r--spec/ruby/library/rexml/node/previous_sibling_node_spec.rb21
-rw-r--r--spec/ruby/library/rexml/shared/each_element.rb36
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb34
-rw-r--r--spec/ruby/library/rexml/text/append_spec.rb10
-rw-r--r--spec/ruby/library/rexml/text/clone_spec.rb10
-rw-r--r--spec/ruby/library/rexml/text/comparison_spec.rb25
-rw-r--r--spec/ruby/library/rexml/text/empty_spec.rb12
-rw-r--r--spec/ruby/library/rexml/text/indent_text_spec.rb24
-rw-r--r--spec/ruby/library/rexml/text/inspect_spec.rb8
-rw-r--r--spec/ruby/library/rexml/text/new_spec.rb49
-rw-r--r--spec/ruby/library/rexml/text/node_type_spec.rb8
-rw-r--r--spec/ruby/library/rexml/text/normalize_spec.rb8
-rw-r--r--spec/ruby/library/rexml/text/read_with_substitution_spec.rb13
-rw-r--r--spec/ruby/library/rexml/text/to_s_spec.rb18
-rw-r--r--spec/ruby/library/rexml/text/unnormalize_spec.rb8
-rw-r--r--spec/ruby/library/rexml/text/value_spec.rb37
-rw-r--r--spec/ruby/library/rexml/text/wrap_spec.rb21
-rw-r--r--spec/ruby/library/rexml/text/write_with_substitution_spec.rb33
-rw-r--r--spec/ruby/library/scanf/io/block_scanf_spec.rb7
-rw-r--r--spec/ruby/library/scanf/io/fixtures/date.txt4
-rw-r--r--spec/ruby/library/scanf/io/fixtures/helloworld.txt1
-rw-r--r--spec/ruby/library/scanf/io/scanf_spec.rb35
-rw-r--r--spec/ruby/library/scanf/io/shared/block_scanf.rb28
-rw-r--r--spec/ruby/library/scanf/string/block_scanf_spec.rb7
-rw-r--r--spec/ruby/library/scanf/string/scanf_spec.rb53
-rw-r--r--spec/ruby/library/scanf/string/shared/block_scanf.rb25
-rw-r--r--spec/ruby/library/securerandom/base64_spec.rb55
-rw-r--r--spec/ruby/library/securerandom/hex_spec.rb54
-rw-r--r--spec/ruby/library/securerandom/random_bytes_spec.rb50
-rw-r--r--spec/ruby/library/securerandom/random_number_spec.rb95
-rw-r--r--spec/ruby/library/set/add_spec.rb27
-rw-r--r--spec/ruby/library/set/append_spec.rb7
-rw-r--r--spec/ruby/library/set/case_compare_spec.rb15
-rw-r--r--spec/ruby/library/set/case_equality_spec.rb9
-rw-r--r--spec/ruby/library/set/classify_spec.rb27
-rw-r--r--spec/ruby/library/set/clear_spec.rb17
-rw-r--r--spec/ruby/library/set/collect_spec.rb7
-rw-r--r--spec/ruby/library/set/compare_by_identity_spec.rb147
-rw-r--r--spec/ruby/library/set/constructor_spec.rb15
-rw-r--r--spec/ruby/library/set/delete_if_spec.rb38
-rw-r--r--spec/ruby/library/set/delete_spec.rb37
-rw-r--r--spec/ruby/library/set/difference_spec.rb7
-rw-r--r--spec/ruby/library/set/divide_spec.rb34
-rw-r--r--spec/ruby/library/set/each_spec.rb26
-rw-r--r--spec/ruby/library/set/empty_spec.rb10
-rw-r--r--spec/ruby/library/set/enumerable/to_set_spec.rb19
-rw-r--r--spec/ruby/library/set/eql_spec.rb15
-rw-r--r--spec/ruby/library/set/equal_value_spec.rb26
-rw-r--r--spec/ruby/library/set/exclusion_spec.rb18
-rw-r--r--spec/ruby/library/set/flatten_merge_spec.rb23
-rw-r--r--spec/ruby/library/set/flatten_spec.rb40
-rw-r--r--spec/ruby/library/set/hash_spec.rb13
-rw-r--r--spec/ruby/library/set/include_spec.rb7
-rw-r--r--spec/ruby/library/set/initialize_spec.rb24
-rw-r--r--spec/ruby/library/set/inspect_spec.rb7
-rw-r--r--spec/ruby/library/set/intersection_spec.rb11
-rw-r--r--spec/ruby/library/set/keep_if_spec.rb38
-rw-r--r--spec/ruby/library/set/length_spec.rb7
-rw-r--r--spec/ruby/library/set/map_spec.rb7
-rw-r--r--spec/ruby/library/set/member_spec.rb7
-rw-r--r--spec/ruby/library/set/merge_spec.rb19
-rw-r--r--spec/ruby/library/set/minus_spec.rb7
-rw-r--r--spec/ruby/library/set/plus_spec.rb7
-rw-r--r--spec/ruby/library/set/pretty_print_cycle_spec.rb10
-rw-r--r--spec/ruby/library/set/pretty_print_spec.rb17
-rw-r--r--spec/ruby/library/set/proper_subset_spec.rb34
-rw-r--r--spec/ruby/library/set/proper_superset_spec.rb34
-rw-r--r--spec/ruby/library/set/reject_spec.rb42
-rw-r--r--spec/ruby/library/set/replace_spec.rb17
-rw-r--r--spec/ruby/library/set/select_spec.rb42
-rw-r--r--spec/ruby/library/set/shared/add.rb14
-rw-r--r--spec/ruby/library/set/shared/collect.rb20
-rw-r--r--spec/ruby/library/set/shared/difference.rb15
-rw-r--r--spec/ruby/library/set/shared/include.rb29
-rw-r--r--spec/ruby/library/set/shared/inspect.rb15
-rw-r--r--spec/ruby/library/set/shared/intersection.rb15
-rw-r--r--spec/ruby/library/set/shared/length.rb6
-rw-r--r--spec/ruby/library/set/shared/union.rb15
-rw-r--r--spec/ruby/library/set/size_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/add_spec.rb39
-rw-r--r--spec/ruby/library/set/sortedset/append_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/case_equality_spec.rb9
-rw-r--r--spec/ruby/library/set/sortedset/classify_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/clear_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/collect_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/constructor_spec.rb15
-rw-r--r--spec/ruby/library/set/sortedset/delete_if_spec.rb38
-rw-r--r--spec/ruby/library/set/sortedset/delete_spec.rb37
-rw-r--r--spec/ruby/library/set/sortedset/difference_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/divide_spec.rb34
-rw-r--r--spec/ruby/library/set/sortedset/each_spec.rb26
-rw-r--r--spec/ruby/library/set/sortedset/empty_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/eql_spec.rb16
-rw-r--r--spec/ruby/library/set/sortedset/equal_value_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/exclusion_spec.rb18
-rw-r--r--spec/ruby/library/set/sortedset/flatten_merge_spec.rb8
-rw-r--r--spec/ruby/library/set/sortedset/flatten_spec.rb44
-rw-r--r--spec/ruby/library/set/sortedset/hash_spec.rb13
-rw-r--r--spec/ruby/library/set/sortedset/include_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/initialize_spec.rb30
-rw-r--r--spec/ruby/library/set/sortedset/inspect_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/intersection_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/keep_if_spec.rb31
-rw-r--r--spec/ruby/library/set/sortedset/length_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/map_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/member_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/merge_spec.rb19
-rw-r--r--spec/ruby/library/set/sortedset/minus_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/plus_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb10
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/proper_subset_spec.rb33
-rw-r--r--spec/ruby/library/set/sortedset/proper_superset_spec.rb33
-rw-r--r--spec/ruby/library/set/sortedset/reject_spec.rb42
-rw-r--r--spec/ruby/library/set/sortedset/replace_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/select_spec.rb35
-rw-r--r--spec/ruby/library/set/sortedset/shared/add.rb14
-rw-r--r--spec/ruby/library/set/sortedset/shared/collect.rb20
-rw-r--r--spec/ruby/library/set/sortedset/shared/difference.rb15
-rw-r--r--spec/ruby/library/set/sortedset/shared/include.rb7
-rw-r--r--spec/ruby/library/set/sortedset/shared/intersection.rb15
-rw-r--r--spec/ruby/library/set/sortedset/shared/length.rb6
-rw-r--r--spec/ruby/library/set/sortedset/shared/union.rb15
-rw-r--r--spec/ruby/library/set/sortedset/size_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/subset_spec.rb33
-rw-r--r--spec/ruby/library/set/sortedset/subtract_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/superset_spec.rb33
-rw-r--r--spec/ruby/library/set/sortedset/to_a_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/union_spec.rb11
-rw-r--r--spec/ruby/library/set/subset_spec.rb34
-rw-r--r--spec/ruby/library/set/subtract_spec.rb17
-rw-r--r--spec/ruby/library/set/superset_spec.rb34
-rw-r--r--spec/ruby/library/set/to_a_spec.rb8
-rw-r--r--spec/ruby/library/set/to_s_spec.rb13
-rw-r--r--spec/ruby/library/set/union_spec.rb11
-rw-r--r--spec/ruby/library/shellwords/shellwords_spec.rb36
-rw-r--r--spec/ruby/library/singleton/allocate_spec.rb8
-rw-r--r--spec/ruby/library/singleton/clone_spec.rb8
-rw-r--r--spec/ruby/library/singleton/dump_spec.rb14
-rw-r--r--spec/ruby/library/singleton/dup_spec.rb8
-rw-r--r--spec/ruby/library/singleton/fixtures/classes.rb18
-rw-r--r--spec/ruby/library/singleton/instance_spec.rb30
-rw-r--r--spec/ruby/library/singleton/load_spec.rb21
-rw-r--r--spec/ruby/library/singleton/new_spec.rb8
-rw-r--r--spec/ruby/library/socket/addrinfo/afamily_spec.rb38
-rw-r--r--spec/ruby/library/socket/addrinfo/bind_spec.rb29
-rw-r--r--spec/ruby/library/socket/addrinfo/canonname_spec.rb19
-rw-r--r--spec/ruby/library/socket/addrinfo/initialize_spec.rb253
-rw-r--r--spec/ruby/library/socket/addrinfo/inspect_sockaddr_spec.rb25
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_address_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_port_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ip_unpack_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_loopback_spec.rb46
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_multicast_spec.rb46
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_private_spec.rb41
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_loopback_spec.rb46
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_multicast_spec.rb46
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_spec.rb36
-rw-r--r--spec/ruby/library/socket/addrinfo/pfamily_spec.rb38
-rw-r--r--spec/ruby/library/socket/addrinfo/protocol_spec.rb38
-rw-r--r--spec/ruby/library/socket/addrinfo/shared/to_sockaddr.rb35
-rw-r--r--spec/ruby/library/socket/addrinfo/socktype_spec.rb38
-rw-r--r--spec/ruby/library/socket/addrinfo/tcp_spec.rb20
-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.rb20
-rw-r--r--spec/ruby/library/socket/addrinfo/unix_path_spec.rb40
-rw-r--r--spec/ruby/library/socket/addrinfo/unix_spec.rb54
-rw-r--r--spec/ruby/library/socket/basicsocket/close_read_spec.rb43
-rw-r--r--spec/ruby/library/socket/basicsocket/close_write_spec.rb48
-rw-r--r--spec/ruby/library/socket/basicsocket/do_not_reverse_lookup_spec.rb39
-rw-r--r--spec/ruby/library/socket/basicsocket/for_fd_spec.rb21
-rw-r--r--spec/ruby/library/socket/basicsocket/getpeername_spec.rb26
-rw-r--r--spec/ruby/library/socket/basicsocket/getsockname_spec.rb28
-rw-r--r--spec/ruby/library/socket/basicsocket/getsockopt_spec.rb46
-rw-r--r--spec/ruby/library/socket/basicsocket/ioctl_spec.rb43
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb7
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_spec.rb96
-rw-r--r--spec/ruby/library/socket/basicsocket/send_spec.rb85
-rw-r--r--spec/ruby/library/socket/basicsocket/setsockopt_spec.rb213
-rw-r--r--spec/ruby/library/socket/basicsocket/shutdown_spec.rb6
-rw-r--r--spec/ruby/library/socket/constants/constants_spec.rb90
-rw-r--r--spec/ruby/library/socket/fixtures/classes.rb93
-rw-r--r--spec/ruby/library/socket/fixtures/send_io.txt1
-rw-r--r--spec/ruby/library/socket/ipsocket/addr_spec.rb42
-rw-r--r--spec/ruby/library/socket/ipsocket/getaddress_spec.rb27
-rw-r--r--spec/ruby/library/socket/ipsocket/peeraddr_spec.rb51
-rw-r--r--spec/ruby/library/socket/ipsocket/recvfrom_spec.rb72
-rw-r--r--spec/ruby/library/socket/option/bool_spec.rb25
-rw-r--r--spec/ruby/library/socket/option/inspect_spec.rb20
-rw-r--r--spec/ruby/library/socket/option/int_spec.rb28
-rw-r--r--spec/ruby/library/socket/option/linger_spec.rb62
-rw-r--r--spec/ruby/library/socket/option/new_spec.rb35
-rw-r--r--spec/ruby/library/socket/shared/pack_sockaddr.rb50
-rw-r--r--spec/ruby/library/socket/shared/partially_closable_sockets.rb13
-rw-r--r--spec/ruby/library/socket/shared/recv_nonblock.rb54
-rw-r--r--spec/ruby/library/socket/shared/socketpair.rb23
-rw-r--r--spec/ruby/library/socket/socket/accept_nonblock_spec.rb37
-rw-r--r--spec/ruby/library/socket/socket/accept_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/bind_spec.rb81
-rw-r--r--spec/ruby/library/socket/socket/connect_nonblock_spec.rb73
-rw-r--r--spec/ruby/library/socket/socket/connect_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/for_fd_spec.rb31
-rw-r--r--spec/ruby/library/socket/socket/getaddrinfo_spec.rb112
-rw-r--r--spec/ruby/library/socket/socket/gethostbyaddr_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/gethostbyname_spec.rb17
-rw-r--r--spec/ruby/library/socket/socket/gethostname_spec.rb8
-rw-r--r--spec/ruby/library/socket/socket/getnameinfo_spec.rb66
-rw-r--r--spec/ruby/library/socket/socket/getservbyname_spec.rb24
-rw-r--r--spec/ruby/library/socket/socket/listen_spec.rb22
-rw-r--r--spec/ruby/library/socket/socket/new_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/pack_sockaddr_in_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/pack_sockaddr_un_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/pair_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/recvfrom_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/sockaddr_in_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/sockaddr_un_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/socket_spec.rb38
-rw-r--r--spec/ruby/library/socket/socket/socketpair_spec.rb7
-rw-r--r--spec/ruby/library/socket/socket/sysaccept_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_in_spec.rb29
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb26
-rw-r--r--spec/ruby/library/socket/tcpserver/accept_nonblock_spec.rb50
-rw-r--r--spec/ruby/library/socket/tcpserver/accept_spec.rb66
-rw-r--r--spec/ruby/library/socket/tcpserver/gets_spec.rb16
-rw-r--r--spec/ruby/library/socket/tcpserver/listen_spec.rb18
-rw-r--r--spec/ruby/library/socket/tcpserver/new_spec.rb96
-rw-r--r--spec/ruby/library/socket/tcpserver/sysaccept_spec.rb32
-rw-r--r--spec/ruby/library/socket/tcpsocket/gethostbyname_spec.rb51
-rw-r--r--spec/ruby/library/socket/tcpsocket/new_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/open_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/partially_closable_spec.rb21
-rw-r--r--spec/ruby/library/socket/tcpsocket/recv_nonblock_spec.rb36
-rw-r--r--spec/ruby/library/socket/tcpsocket/setsockopt_spec.rb45
-rw-r--r--spec/ruby/library/socket/tcpsocket/shared/new.rb79
-rw-r--r--spec/ruby/library/socket/udpsocket/bind_spec.rb42
-rw-r--r--spec/ruby/library/socket/udpsocket/new_spec.rb34
-rw-r--r--spec/ruby/library/socket/udpsocket/open_spec.rb13
-rw-r--r--spec/ruby/library/socket/udpsocket/send_spec.rb78
-rw-r--r--spec/ruby/library/socket/udpsocket/write_spec.rb21
-rw-r--r--spec/ruby/library/socket/unixserver/accept_nonblock_spec.rb38
-rw-r--r--spec/ruby/library/socket/unixserver/accept_spec.rb61
-rw-r--r--spec/ruby/library/socket/unixserver/for_fd_spec.rb23
-rw-r--r--spec/ruby/library/socket/unixserver/new_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixserver/open_spec.rb25
-rw-r--r--spec/ruby/library/socket/unixserver/shared/new.rb23
-rw-r--r--spec/ruby/library/socket/unixsocket/addr_spec.rb36
-rw-r--r--spec/ruby/library/socket/unixsocket/inspect_spec.rb17
-rw-r--r--spec/ruby/library/socket/unixsocket/new_spec.rb6
-rw-r--r--spec/ruby/library/socket/unixsocket/open_spec.rb27
-rw-r--r--spec/ruby/library/socket/unixsocket/pair_spec.rb39
-rw-r--r--spec/ruby/library/socket/unixsocket/partially_closable_spec.rb25
-rw-r--r--spec/ruby/library/socket/unixsocket/path_spec.rb28
-rw-r--r--spec/ruby/library/socket/unixsocket/peeraddr_spec.rb30
-rw-r--r--spec/ruby/library/socket/unixsocket/recv_io_spec.rb44
-rw-r--r--spec/ruby/library/socket/unixsocket/recvfrom_spec.rb47
-rw-r--r--spec/ruby/library/socket/unixsocket/send_io_spec.rb35
-rw-r--r--spec/ruby/library/socket/unixsocket/shared/new.rb24
-rw-r--r--spec/ruby/library/stringio/append_spec.rb84
-rw-r--r--spec/ruby/library/stringio/binmode_spec.rb9
-rw-r--r--spec/ruby/library/stringio/bytes_spec.rb11
-rw-r--r--spec/ruby/library/stringio/chars_spec.rb11
-rw-r--r--spec/ruby/library/stringio/close_read_spec.rb36
-rw-r--r--spec/ruby/library/stringio/close_spec.rb32
-rw-r--r--spec/ruby/library/stringio/close_write_spec.rb36
-rw-r--r--spec/ruby/library/stringio/closed_read_spec.rb12
-rw-r--r--spec/ruby/library/stringio/closed_spec.rb16
-rw-r--r--spec/ruby/library/stringio/closed_write_spec.rb12
-rw-r--r--spec/ruby/library/stringio/codepoints_spec.rb9
-rw-r--r--spec/ruby/library/stringio/each_byte_spec.rb11
-rw-r--r--spec/ruby/library/stringio/each_char_spec.rb11
-rw-r--r--spec/ruby/library/stringio/each_codepoint_spec.rb10
-rw-r--r--spec/ruby/library/stringio/each_line_spec.rb21
-rw-r--r--spec/ruby/library/stringio/each_spec.rb21
-rw-r--r--spec/ruby/library/stringio/eof_spec.rb11
-rw-r--r--spec/ruby/library/stringio/external_encoding_spec.rb21
-rw-r--r--spec/ruby/library/stringio/fcntl_spec.rb8
-rw-r--r--spec/ruby/library/stringio/fileno_spec.rb9
-rw-r--r--spec/ruby/library/stringio/fixtures/classes.rb15
-rw-r--r--spec/ruby/library/stringio/flush_spec.rb9
-rw-r--r--spec/ruby/library/stringio/fsync_spec.rb9
-rw-r--r--spec/ruby/library/stringio/getbyte_spec.rb19
-rw-r--r--spec/ruby/library/stringio/getc_spec.rb19
-rw-r--r--spec/ruby/library/stringio/getch_spec.rb46
-rw-r--r--spec/ruby/library/stringio/gets_spec.rb247
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb185
-rw-r--r--spec/ruby/library/stringio/internal_encoding_spec.rb10
-rw-r--r--spec/ruby/library/stringio/isatty_spec.rb7
-rw-r--r--spec/ruby/library/stringio/length_spec.rb7
-rw-r--r--spec/ruby/library/stringio/lineno_spec.rb30
-rw-r--r--spec/ruby/library/stringio/lines_spec.rb21
-rw-r--r--spec/ruby/library/stringio/open_spec.rb208
-rw-r--r--spec/ruby/library/stringio/path_spec.rb8
-rw-r--r--spec/ruby/library/stringio/pid_spec.rb8
-rw-r--r--spec/ruby/library/stringio/pos_spec.rb28
-rw-r--r--spec/ruby/library/stringio/print_spec.rb100
-rw-r--r--spec/ruby/library/stringio/printf_spec.rb71
-rw-r--r--spec/ruby/library/stringio/putc_spec.rb88
-rw-r--r--spec/ruby/library/stringio/puts_spec.rb159
-rw-r--r--spec/ruby/library/stringio/read_nonblock_spec.rb20
-rw-r--r--spec/ruby/library/stringio/read_spec.rb62
-rw-r--r--spec/ruby/library/stringio/readbyte_spec.rb20
-rw-r--r--spec/ruby/library/stringio/readchar_spec.rb20
-rw-r--r--spec/ruby/library/stringio/readline_spec.rb131
-rw-r--r--spec/ruby/library/stringio/readlines_spec.rb101
-rw-r--r--spec/ruby/library/stringio/readpartial_spec.rb80
-rw-r--r--spec/ruby/library/stringio/reopen_spec.rb288
-rw-r--r--spec/ruby/library/stringio/rewind_spec.rb24
-rw-r--r--spec/ruby/library/stringio/seek_spec.rb67
-rw-r--r--spec/ruby/library/stringio/set_encoding_spec.rb10
-rw-r--r--spec/ruby/library/stringio/shared/codepoints.rb45
-rw-r--r--spec/ruby/library/stringio/shared/each.rb114
-rw-r--r--spec/ruby/library/stringio/shared/each_byte.rb48
-rw-r--r--spec/ruby/library/stringio/shared/each_char.rb36
-rw-r--r--spec/ruby/library/stringio/shared/eof.rb24
-rw-r--r--spec/ruby/library/stringio/shared/getc.rb43
-rw-r--r--spec/ruby/library/stringio/shared/isatty.rb5
-rw-r--r--spec/ruby/library/stringio/shared/length.rb5
-rw-r--r--spec/ruby/library/stringio/shared/read.rb121
-rw-r--r--spec/ruby/library/stringio/shared/readchar.rb29
-rw-r--r--spec/ruby/library/stringio/shared/sysread.rb15
-rw-r--r--spec/ruby/library/stringio/shared/tell.rb12
-rw-r--r--spec/ruby/library/stringio/shared/write.rb87
-rw-r--r--spec/ruby/library/stringio/size_spec.rb7
-rw-r--r--spec/ruby/library/stringio/string_spec.rb50
-rw-r--r--spec/ruby/library/stringio/stringio_spec.rb9
-rw-r--r--spec/ruby/library/stringio/sync_spec.rb19
-rw-r--r--spec/ruby/library/stringio/sysread_spec.rb48
-rw-r--r--spec/ruby/library/stringio/syswrite_spec.rb19
-rw-r--r--spec/ruby/library/stringio/tell_spec.rb7
-rw-r--r--spec/ruby/library/stringio/truncate_spec.rb70
-rw-r--r--spec/ruby/library/stringio/tty_spec.rb7
-rw-r--r--spec/ruby/library/stringio/ungetbyte_spec.rb6
-rw-r--r--spec/ruby/library/stringio/ungetc_spec.rb72
-rw-r--r--spec/ruby/library/stringio/write_nonblock_spec.rb19
-rw-r--r--spec/ruby/library/stringio/write_spec.rb19
-rw-r--r--spec/ruby/library/stringscanner/append_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/beginning_of_line_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/bol_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/check_spec.rb16
-rw-r--r--spec/ruby/library/stringscanner/check_until_spec.rb15
-rw-r--r--spec/ruby/library/stringscanner/clear_spec.rb20
-rw-r--r--spec/ruby/library/stringscanner/concat_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/dup_spec.rb39
-rw-r--r--spec/ruby/library/stringscanner/element_reference_spec.rb61
-rw-r--r--spec/ruby/library/stringscanner/empty_spec.rb20
-rw-r--r--spec/ruby/library/stringscanner/eos_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/exist_spec.rb24
-rw-r--r--spec/ruby/library/stringscanner/get_byte_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/getbyte_spec.rb23
-rw-r--r--spec/ruby/library/stringscanner/getch_spec.rb35
-rw-r--r--spec/ruby/library/stringscanner/initialize_spec.rb28
-rw-r--r--spec/ruby/library/stringscanner/inspect_spec.rb20
-rw-r--r--spec/ruby/library/stringscanner/match_spec.rb28
-rw-r--r--spec/ruby/library/stringscanner/matched_size_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/matched_spec.rb41
-rw-r--r--spec/ruby/library/stringscanner/must_C_version_spec.rb8
-rw-r--r--spec/ruby/library/stringscanner/peek_spec.rb8
-rw-r--r--spec/ruby/library/stringscanner/peep_spec.rb20
-rw-r--r--spec/ruby/library/stringscanner/pointer_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/pos_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/post_match_spec.rb28
-rw-r--r--spec/ruby/library/stringscanner/pre_match_spec.rb41
-rw-r--r--spec/ruby/library/stringscanner/reset_spec.rb15
-rw-r--r--spec/ruby/library/stringscanner/rest_size_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/rest_spec.rb48
-rw-r--r--spec/ruby/library/stringscanner/restsize_spec.rb20
-rw-r--r--spec/ruby/library/stringscanner/scan_full_spec.rb30
-rw-r--r--spec/ruby/library/stringscanner/scan_spec.rb43
-rw-r--r--spec/ruby/library/stringscanner/scan_until_spec.rb23
-rw-r--r--spec/ruby/library/stringscanner/search_full_spec.rb30
-rw-r--r--spec/ruby/library/stringscanner/shared/bol.rb25
-rw-r--r--spec/ruby/library/stringscanner/shared/concat.rb30
-rw-r--r--spec/ruby/library/stringscanner/shared/eos.rb17
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range.rb22
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range_matched.rb22
-rw-r--r--spec/ruby/library/stringscanner/shared/get_byte.rb29
-rw-r--r--spec/ruby/library/stringscanner/shared/matched_size.rb21
-rw-r--r--spec/ruby/library/stringscanner/shared/peek.rb47
-rw-r--r--spec/ruby/library/stringscanner/shared/pos.rb52
-rw-r--r--spec/ruby/library/stringscanner/shared/rest_size.rb18
-rw-r--r--spec/ruby/library/stringscanner/shared/terminate.rb8
-rw-r--r--spec/ruby/library/stringscanner/skip_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/skip_until_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/string_spec.rb40
-rw-r--r--spec/ruby/library/stringscanner/terminate_spec.rb7
-rw-r--r--spec/ruby/library/stringscanner/unscan_spec.rb28
-rw-r--r--spec/ruby/library/syslog/alert_spec.rb10
-rw-r--r--spec/ruby/library/syslog/close_spec.rb58
-rw-r--r--spec/ruby/library/syslog/constants_spec.rb41
-rw-r--r--spec/ruby/library/syslog/crit_spec.rb10
-rw-r--r--spec/ruby/library/syslog/debug_spec.rb10
-rw-r--r--spec/ruby/library/syslog/emerg_spec.rb16
-rw-r--r--spec/ruby/library/syslog/err_spec.rb10
-rw-r--r--spec/ruby/library/syslog/facility_spec.rb48
-rw-r--r--spec/ruby/library/syslog/ident_spec.rb35
-rw-r--r--spec/ruby/library/syslog/info_spec.rb10
-rw-r--r--spec/ruby/library/syslog/inspect_spec.rb39
-rw-r--r--spec/ruby/library/syslog/instance_spec.rb13
-rw-r--r--spec/ruby/library/syslog/log_spec.rb56
-rw-r--r--spec/ruby/library/syslog/mask_spec.rb113
-rw-r--r--spec/ruby/library/syslog/notice_spec.rb10
-rw-r--r--spec/ruby/library/syslog/open_spec.rb92
-rw-r--r--spec/ruby/library/syslog/opened_spec.rb39
-rw-r--r--spec/ruby/library/syslog/options_spec.rb48
-rw-r--r--spec/ruby/library/syslog/reopen_spec.rb10
-rw-r--r--spec/ruby/library/syslog/shared/log.rb40
-rw-r--r--spec/ruby/library/syslog/shared/reopen.rb40
-rw-r--r--spec/ruby/library/syslog/warning_spec.rb10
-rw-r--r--spec/ruby/library/tempfile/_close_spec.rb21
-rw-r--r--spec/ruby/library/tempfile/callback_spec.rb6
-rw-r--r--spec/ruby/library/tempfile/close_spec.rb57
-rw-r--r--spec/ruby/library/tempfile/delete_spec.rb7
-rw-r--r--spec/ruby/library/tempfile/initialize_spec.rb41
-rw-r--r--spec/ruby/library/tempfile/length_spec.rb7
-rw-r--r--spec/ruby/library/tempfile/open_spec.rb82
-rw-r--r--spec/ruby/library/tempfile/path_spec.rb26
-rw-r--r--spec/ruby/library/tempfile/shared/length.rb21
-rw-r--r--spec/ruby/library/tempfile/shared/unlink.rb12
-rw-r--r--spec/ruby/library/tempfile/size_spec.rb7
-rw-r--r--spec/ruby/library/tempfile/unlink_spec.rb7
-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/shared/queue/clear.rb10
-rw-r--r--spec/ruby/library/thread/shared/queue/close.rb26
-rw-r--r--spec/ruby/library/thread/shared/queue/closed.rb12
-rw-r--r--spec/ruby/library/thread/shared/queue/deque.rb37
-rw-r--r--spec/ruby/library/thread/shared/queue/empty.rb12
-rw-r--r--spec/ruby/library/thread/shared/queue/enque.rb10
-rw-r--r--spec/ruby/library/thread/shared/queue/length.rb9
-rw-r--r--spec/ruby/library/thread/shared/queue/num_waiting.rb16
-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/time/httpdate_spec.rb21
-rw-r--r--spec/ruby/library/time/iso8601_spec.rb7
-rw-r--r--spec/ruby/library/time/rfc2822_spec.rb7
-rw-r--r--spec/ruby/library/time/rfc822_spec.rb7
-rw-r--r--spec/ruby/library/time/shared/rfc2822.rb65
-rw-r--r--spec/ruby/library/time/shared/xmlschema.rb53
-rw-r--r--spec/ruby/library/time/to_date_spec.rb42
-rw-r--r--spec/ruby/library/time/to_datetime_spec.rb27
-rw-r--r--spec/ruby/library/time/to_time_spec.rb17
-rw-r--r--spec/ruby/library/time/xmlschema_spec.rb7
-rw-r--r--spec/ruby/library/timeout/error_spec.rb8
-rw-r--r--spec/ruby/library/timeout/timeout_spec.rb37
-rw-r--r--spec/ruby/library/tmpdir/dir/mktmpdir_spec.rb117
-rw-r--r--spec/ruby/library/tmpdir/dir/tmpdir_spec.rb10
-rw-r--r--spec/ruby/library/uri/decode_www_form_component_spec.rb6
-rw-r--r--spec/ruby/library/uri/decode_www_form_spec.rb6
-rw-r--r--spec/ruby/library/uri/encode_www_form_component_spec.rb6
-rw-r--r--spec/ruby/library/uri/encode_www_form_spec.rb6
-rw-r--r--spec/ruby/library/uri/eql_spec.rb10
-rw-r--r--spec/ruby/library/uri/equality_spec.rb46
-rw-r--r--spec/ruby/library/uri/escape/decode_spec.rb6
-rw-r--r--spec/ruby/library/uri/escape/encode_spec.rb6
-rw-r--r--spec/ruby/library/uri/escape/escape_spec.rb6
-rw-r--r--spec/ruby/library/uri/escape/unescape_spec.rb6
-rw-r--r--spec/ruby/library/uri/extract_spec.rb86
-rw-r--r--spec/ruby/library/uri/fixtures/classes.rb11
-rw-r--r--spec/ruby/library/uri/fixtures/normalization.rb54
-rw-r--r--spec/ruby/library/uri/ftp/build_spec.rb6
-rw-r--r--spec/ruby/library/uri/ftp/merge_spec.rb6
-rw-r--r--spec/ruby/library/uri/ftp/new2_spec.rb6
-rw-r--r--spec/ruby/library/uri/ftp/path_spec.rb26
-rw-r--r--spec/ruby/library/uri/ftp/set_typecode_spec.rb6
-rw-r--r--spec/ruby/library/uri/ftp/to_s_spec.rb15
-rw-r--r--spec/ruby/library/uri/ftp/typecode_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/absolute_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/build2_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/build_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/coerce_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/component_ary_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/component_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/default_port_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/eql_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/equal_value_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/fragment_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/hash_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/hierarchical_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/host_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/inspect_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/merge_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/minus_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/normalize_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/opaque_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/password_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/path_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/plus_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/port_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/query_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/registry_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/relative_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/route_from_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/route_to_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/scheme_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/select_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_fragment_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_host_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_opaque_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_password_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_path_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_port_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_query_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_registry_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_scheme_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_user_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/set_userinfo_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/to_s_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/use_registry_spec.rb6
-rw-r--r--spec/ruby/library/uri/generic/user_spec.rb10
-rw-r--r--spec/ruby/library/uri/generic/userinfo_spec.rb10
-rw-r--r--spec/ruby/library/uri/http/build_spec.rb6
-rw-r--r--spec/ruby/library/uri/http/request_uri_spec.rb16
-rw-r--r--spec/ruby/library/uri/join_spec.rb59
-rw-r--r--spec/ruby/library/uri/ldap/attributes_spec.rb10
-rw-r--r--spec/ruby/library/uri/ldap/build_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/dn_spec.rb10
-rw-r--r--spec/ruby/library/uri/ldap/extensions_spec.rb10
-rw-r--r--spec/ruby/library/uri/ldap/filter_spec.rb10
-rw-r--r--spec/ruby/library/uri/ldap/hierarchical_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/scope_spec.rb10
-rw-r--r--spec/ruby/library/uri/ldap/set_attributes_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/set_dn_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/set_extensions_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/set_filter_spec.rb6
-rw-r--r--spec/ruby/library/uri/ldap/set_scope_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/build_spec.rb98
-rw-r--r--spec/ruby/library/uri/mailto/headers_spec.rb10
-rw-r--r--spec/ruby/library/uri/mailto/set_headers_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/set_to_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/to_mailtext_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/to_rfc822text_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/to_s_spec.rb6
-rw-r--r--spec/ruby/library/uri/mailto/to_spec.rb10
-rw-r--r--spec/ruby/library/uri/merge_spec.rb20
-rw-r--r--spec/ruby/library/uri/normalize_spec.rb35
-rw-r--r--spec/ruby/library/uri/parse_spec.rb203
-rw-r--r--spec/ruby/library/uri/parser/escape_spec.rb6
-rw-r--r--spec/ruby/library/uri/parser/extract_spec.rb7
-rw-r--r--spec/ruby/library/uri/parser/inspect_spec.rb6
-rw-r--r--spec/ruby/library/uri/parser/join_spec.rb7
-rw-r--r--spec/ruby/library/uri/parser/make_regexp_spec.rb6
-rw-r--r--spec/ruby/library/uri/parser/parse_spec.rb7
-rw-r--r--spec/ruby/library/uri/parser/split_spec.rb6
-rw-r--r--spec/ruby/library/uri/parser/unescape_spec.rb6
-rw-r--r--spec/ruby/library/uri/plus_spec.rb459
-rw-r--r--spec/ruby/library/uri/regexp_spec.rb18
-rw-r--r--spec/ruby/library/uri/route_from_spec.rb23
-rw-r--r--spec/ruby/library/uri/route_to_spec.rb26
-rw-r--r--spec/ruby/library/uri/select_spec.rb31
-rw-r--r--spec/ruby/library/uri/set_component_spec.rb47
-rw-r--r--spec/ruby/library/uri/shared/eql.rb17
-rw-r--r--spec/ruby/library/uri/shared/extract.rb83
-rw-r--r--spec/ruby/library/uri/shared/join.rb56
-rw-r--r--spec/ruby/library/uri/shared/parse.rb199
-rw-r--r--spec/ruby/library/uri/split_spec.rb6
-rw-r--r--spec/ruby/library/uri/uri_spec.rb29
-rw-r--r--spec/ruby/library/uri/util/make_components_hash_spec.rb6
-rw-r--r--spec/ruby/library/weakref/__getobj___spec.rb17
-rw-r--r--spec/ruby/library/weakref/fixtures/classes.rb24
-rw-r--r--spec/ruby/library/weakref/send_spec.rb37
-rw-r--r--spec/ruby/library/weakref/weakref_alive_spec.rb15
-rw-r--r--spec/ruby/library/win32ole/fixtures/classes.rb14
-rw-r--r--spec/ruby/library/win32ole/win32ole/_getproperty_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole/_invoke_spec.rb23
-rw-r--r--spec/ruby/library/win32ole/win32ole/codepage_spec.rb15
-rw-r--r--spec/ruby/library/win32ole/win32ole/connect_spec.rb17
-rw-r--r--spec/ruby/library/win32ole/win32ole/const_load_spec.rb34
-rw-r--r--spec/ruby/library/win32ole/win32ole/constants_spec.rb44
-rw-r--r--spec/ruby/library/win32ole/win32ole/create_guid_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole/invoke_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole/locale_spec.rb31
-rw-r--r--spec/ruby/library/win32ole/win32ole/new_spec.rb27
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_func_methods_spec.rb27
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_get_methods_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_help_spec.rb12
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_method_spec.rb12
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_methods_spec.rb27
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_obj_help_spec.rb23
-rw-r--r--spec/ruby/library/win32ole/win32ole/ole_put_methods_spec.rb27
-rw-r--r--spec/ruby/library/win32ole/win32ole/setproperty_spec.rb12
-rw-r--r--spec/ruby/library/win32ole/win32ole/shared/ole_method.rb25
-rw-r--r--spec/ruby/library/win32ole/win32ole/shared/setproperty.rb25
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/new_spec.rb33
-rw-r--r--spec/ruby/library/win32ole/win32ole_event/on_event_spec.rb62
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/dispid_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_interface_spec.rb26
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/event_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpcontext_spec.rb26
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpfile_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/helpstring_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invkind_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/invoke_kind_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/name_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/new_spec.rb33
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/offset_vtbl_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/params_spec.rb28
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_detail_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_type_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/return_vtype_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/shared/name.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_opt_params_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/size_params_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/to_s_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_method/visible_spec.rb20
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/default_spec.rb31
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/input_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/name_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_detail_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/ole_type_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/optional_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/retval_spec.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/shared/name.rb21
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/to_s_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/guid_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpcontext_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpfile_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/helpstring_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/major_version_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/minor_version_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/name_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/new_spec.rb37
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_classes_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_methods_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/ole_type_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/progid_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/progids_spec.rb14
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/shared/name.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/src_type_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/to_s_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/typekind_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/typelibs_spec.rb22
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/variables_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_type/visible_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/name_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/ole_type_detail_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/ole_type_spec.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/shared/name.rb18
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/to_s_spec.rb11
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/value_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/variable_kind_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/varkind_spec.rb19
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/visible_spec.rb18
-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.rb51
-rw-r--r--spec/ruby/library/yaml/dump_stream_spec.rb8
-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/common.rb10
-rw-r--r--spec/ruby/library/yaml/fixtures/example_class.rb5
-rw-r--r--spec/ruby/library/yaml/fixtures/strings.rb36
-rw-r--r--spec/ruby/library/yaml/fixtures/test_yaml.yml2
-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.rb13
-rw-r--r--spec/ruby/library/yaml/load_spec.rb137
-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.rb22
-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.rb18
-rw-r--r--spec/ruby/library/yaml/tagurize_spec.rb11
-rw-r--r--spec/ruby/library/yaml/to_yaml_spec.rb99
-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.rb46
-rw-r--r--spec/ruby/library/zlib/crc32_spec.rb52
-rw-r--r--spec/ruby/library/zlib/crc_table_spec.rb75
-rw-r--r--spec/ruby/library/zlib/deflate/append_spec.rb1
-rw-r--r--spec/ruby/library/zlib/deflate/deflate_spec.rb128
-rw-r--r--spec/ruby/library/zlib/deflate/flush_spec.rb1
-rw-r--r--spec/ruby/library/zlib/deflate/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/deflate/params_spec.rb17
-rw-r--r--spec/ruby/library/zlib/deflate/set_dictionary_spec.rb15
-rw-r--r--spec/ruby/library/zlib/gzipfile/close_spec.rb22
-rw-r--r--spec/ruby/library/zlib/gzipfile/closed_spec.rb17
-rw-r--r--spec/ruby/library/zlib/gzipfile/comment_spec.rb27
-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.rb27
-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.rb51
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_line_spec.rb5
-rw-r--r--spec/ruby/library/zlib/gzipreader/each_spec.rb5
-rw-r--r--spec/ruby/library/zlib/gzipreader/eof_spec.rb56
-rw-r--r--spec/ruby/library/zlib/gzipreader/getc_spec.rb41
-rw-r--r--spec/ruby/library/zlib/gzipreader/gets_spec.rb22
-rw-r--r--spec/ruby/library/zlib/gzipreader/lineno_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/open_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/pos_spec.rb27
-rw-r--r--spec/ruby/library/zlib/gzipreader/read_spec.rb68
-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.rb17
-rw-r--r--spec/ruby/library/zlib/gzipreader/rewind_spec.rb48
-rw-r--r--spec/ruby/library/zlib/gzipreader/shared/each.rb51
-rw-r--r--spec/ruby/library/zlib/gzipreader/tell_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipreader/ungetbyte_spec.rb122
-rw-r--r--spec/ruby/library/zlib/gzipreader/ungetc_spec.rb292
-rw-r--r--spec/ruby/library/zlib/gzipreader/unused_spec.rb1
-rw-r--r--spec/ruby/library/zlib/gzipwriter/append_spec.rb17
-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.rb38
-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.rb36
-rw-r--r--spec/ruby/library/zlib/inflate/append_spec.rb60
-rw-r--r--spec/ruby/library/zlib/inflate/finish_spec.rb28
-rw-r--r--spec/ruby/library/zlib/inflate/inflate_spec.rb152
-rw-r--r--spec/ruby/library/zlib/inflate/new_spec.rb1
-rw-r--r--spec/ruby/library/zlib/inflate/set_dictionary_spec.rb21
-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/zlib_version_spec.rb1
-rw-r--r--spec/ruby/library/zlib/zstream/adler_spec.rb11
-rw-r--r--spec/ruby/library/zlib/zstream/avail_in_spec.rb9
-rw-r--r--spec/ruby/library/zlib/zstream/avail_out_spec.rb9
-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.rb9
-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.rb16
-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/README16
-rw-r--r--spec/ruby/optional/capi/array_spec.rb463
-rw-r--r--spec/ruby/optional/capi/bignum_spec.rb214
-rw-r--r--spec/ruby/optional/capi/boolean_spec.rb33
-rw-r--r--spec/ruby/optional/capi/class_spec.rb386
-rw-r--r--spec/ruby/optional/capi/complex_spec.rb45
-rw-r--r--spec/ruby/optional/capi/constants_spec.rb270
-rw-r--r--spec/ruby/optional/capi/data_spec.rb46
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb485
-rw-r--r--spec/ruby/optional/capi/enumerator_spec.rb39
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb58
-rw-r--r--spec/ruby/optional/capi/ext/.gitignore9
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c452
-rw-r--r--spec/ruby/optional/capi/ext/bignum_spec.c149
-rw-r--r--spec/ruby/optional/capi/ext/boolean_spec.c34
-rw-r--r--spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c261
-rw-r--r--spec/ruby/optional/capi/ext/class_under_autoload_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/complex_spec.c76
-rw-r--r--spec/ruby/optional/capi/ext/constants_spec.c646
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c97
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c424
-rw-r--r--spec/ruby/optional/capi/ext/enumerator_spec.c27
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c72
-rw-r--r--spec/ruby/optional/capi/ext/file_spec.c44
-rw-r--r--spec/ruby/optional/capi/ext/fixnum_spec.c52
-rw-r--r--spec/ruby/optional/capi/ext/float_spec.c54
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c72
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c199
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c218
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c40
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c303
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c450
-rw-r--r--spec/ruby/optional/capi/ext/marshal_spec.c36
-rw-r--r--spec/ruby/optional/capi/ext/module_spec.c262
-rw-r--r--spec/ruby/optional/capi/ext/module_under_autoload_spec.c7
-rw-r--r--spec/ruby/optional/capi/ext/mutex_spec.c91
-rw-r--r--spec/ruby/optional/capi/ext/numeric_spec.c176
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c646
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c85
-rw-r--r--spec/ruby/optional/capi/ext/range_spec.c66
-rw-r--r--spec/ruby/optional/capi/ext/rational_spec.c95
-rw-r--r--spec/ruby/optional/capi/ext/regexp_spec.c84
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h613
-rw-r--r--spec/ruby/optional/capi/ext/st_spec.c93
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c698
-rw-r--r--spec/ruby/optional/capi/ext/struct_spec.c131
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c138
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c188
-rw-r--r--spec/ruby/optional/capi/ext/time_spec.c127
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c177
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c95
-rw-r--r--spec/ruby/optional/capi/file_spec.rb89
-rw-r--r--spec/ruby/optional/capi/fixnum_spec.rb124
-rw-r--r--spec/ruby/optional/capi/fixtures/class.rb82
-rw-r--r--spec/ruby/optional/capi/fixtures/const_get.rb5
-rw-r--r--spec/ruby/optional/capi/fixtures/const_get_at.rb5
-rw-r--r--spec/ruby/optional/capi/fixtures/const_get_from.rb5
-rw-r--r--spec/ruby/optional/capi/fixtures/const_get_object.rb3
-rw-r--r--spec/ruby/optional/capi/fixtures/encoding.rb3
-rw-r--r--spec/ruby/optional/capi/fixtures/foo.rb1
-rw-r--r--spec/ruby/optional/capi/fixtures/module.rb35
-rw-r--r--spec/ruby/optional/capi/fixtures/module_autoload.rb4
-rw-r--r--spec/ruby/optional/capi/fixtures/path_to_class.rb6
-rw-r--r--spec/ruby/optional/capi/fixtures/proc.rb20
-rw-r--r--spec/ruby/optional/capi/float_spec.rb30
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb54
-rw-r--r--spec/ruby/optional/capi/globals_spec.rb224
-rw-r--r--spec/ruby/optional/capi/hash_spec.rb245
-rw-r--r--spec/ruby/optional/capi/integer_spec.rb275
-rw-r--r--spec/ruby/optional/capi/io_spec.rb344
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb532
-rw-r--r--spec/ruby/optional/capi/marshal_spec.rb46
-rw-r--r--spec/ruby/optional/capi/module_spec.rb349
-rw-r--r--spec/ruby/optional/capi/mutex_spec.rb88
-rw-r--r--spec/ruby/optional/capi/numeric_spec.rb447
-rw-r--r--spec/ruby/optional/capi/object_spec.rb835
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb112
-rw-r--r--spec/ruby/optional/capi/rake_helper.rb23
-rw-r--r--spec/ruby/optional/capi/range_spec.rb95
-rw-r--r--spec/ruby/optional/capi/rational_spec.rb57
-rw-r--r--spec/ruby/optional/capi/regexp_spec.rb71
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb116
-rw-r--r--spec/ruby/optional/capi/st_spec.rb41
-rw-r--r--spec/ruby/optional/capi/string_spec.rb812
-rw-r--r--spec/ruby/optional/capi/struct_spec.rb209
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb133
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb127
-rw-r--r--spec/ruby/optional/capi/time_spec.rb302
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb56
-rw-r--r--spec/ruby/optional/capi/util_spec.rb201
-rw-r--r--spec/ruby/security/cve_2011_4815_spec.rb41
-rw-r--r--spec/ruby/security/cve_2013_4164_spec.rb19
-rw-r--r--spec/ruby/security/cve_2014_8080_spec.rb32
-rw-r--r--spec/ruby/shared/basicobject/method_missing.rb126
-rw-r--r--spec/ruby/shared/basicobject/send.rb110
-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/arg.rb9
-rw-r--r--spec/ruby/shared/complex/coerce.rb70
-rw-r--r--spec/ruby/shared/complex/conjugate.rb8
-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/enumerator/each.rb89
-rw-r--r--spec/ruby/shared/enumerator/enum_cons.rb12
-rw-r--r--spec/ruby/shared/enumerator/enum_for.rb50
-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.rb32
-rw-r--r--spec/ruby/shared/enumerator/with_object.rb42
-rw-r--r--spec/ruby/shared/fiber/resume.rb82
-rw-r--r--spec/ruby/shared/file/blockdev.rb9
-rw-r--r--spec/ruby/shared/file/chardev.rb9
-rw-r--r--spec/ruby/shared/file/directory.rb66
-rw-r--r--spec/ruby/shared/file/executable.rb48
-rw-r--r--spec/ruby/shared/file/executable_real.rb46
-rw-r--r--spec/ruby/shared/file/exist.rb24
-rw-r--r--spec/ruby/shared/file/file.rb45
-rw-r--r--spec/ruby/shared/file/grpowned.rb40
-rw-r--r--spec/ruby/shared/file/identical.rb47
-rw-r--r--spec/ruby/shared/file/owned.rb3
-rw-r--r--spec/ruby/shared/file/pipe.rb3
-rw-r--r--spec/ruby/shared/file/readable.rb30
-rw-r--r--spec/ruby/shared/file/readable_real.rb23
-rw-r--r--spec/ruby/shared/file/setgid.rb2
-rw-r--r--spec/ruby/shared/file/setuid.rb2
-rw-r--r--spec/ruby/shared/file/size.rb124
-rw-r--r--spec/ruby/shared/file/socket.rb3
-rw-r--r--spec/ruby/shared/file/sticky.rb29
-rw-r--r--spec/ruby/shared/file/symlink.rb46
-rw-r--r--spec/ruby/shared/file/world_readable.rb49
-rw-r--r--spec/ruby/shared/file/world_writable.rb49
-rw-r--r--spec/ruby/shared/file/writable.rb26
-rw-r--r--spec/ruby/shared/file/writable_real.rb33
-rw-r--r--spec/ruby/shared/file/zero.rb68
-rw-r--r--spec/ruby/shared/io/putc.rb57
-rw-r--r--spec/ruby/shared/kernel/equal.rb54
-rw-r--r--spec/ruby/shared/kernel/object_id.rb80
-rw-r--r--spec/ruby/shared/kernel/raise.rb68
-rw-r--r--spec/ruby/shared/math/atanh.rb44
-rw-r--r--spec/ruby/shared/process/abort.rb36
-rw-r--r--spec/ruby/shared/process/exit.rb94
-rw-r--r--spec/ruby/shared/process/fork.rb90
-rw-r--r--spec/ruby/shared/rational/Rational.rb103
-rw-r--r--spec/ruby/shared/rational/abs.rb11
-rw-r--r--spec/ruby/shared/rational/ceil.rb45
-rw-r--r--spec/ruby/shared/rational/coerce.rb21
-rw-r--r--spec/ruby/shared/rational/comparison.rb85
-rw-r--r--spec/ruby/shared/rational/denominator.rb14
-rw-r--r--spec/ruby/shared/rational/div.rb54
-rw-r--r--spec/ruby/shared/rational/divide.rb71
-rw-r--r--spec/ruby/shared/rational/divmod.rb42
-rw-r--r--spec/ruby/shared/rational/equal_value.rb39
-rw-r--r--spec/ruby/shared/rational/exponent.rb176
-rw-r--r--spec/ruby/shared/rational/fdiv.rb5
-rw-r--r--spec/ruby/shared/rational/floor.rb45
-rw-r--r--spec/ruby/shared/rational/hash.rb9
-rw-r--r--spec/ruby/shared/rational/inspect.rb12
-rw-r--r--spec/ruby/shared/rational/marshal_dump.rb5
-rw-r--r--spec/ruby/shared/rational/marshal_load.rb5
-rw-r--r--spec/ruby/shared/rational/minus.rb48
-rw-r--r--spec/ruby/shared/rational/modulo.rb43
-rw-r--r--spec/ruby/shared/rational/multiply.rb62
-rw-r--r--spec/ruby/shared/rational/numerator.rb10
-rw-r--r--spec/ruby/shared/rational/plus.rb48
-rw-r--r--spec/ruby/shared/rational/quo.rb5
-rw-r--r--spec/ruby/shared/rational/remainder.rb5
-rw-r--r--spec/ruby/shared/rational/round.rb96
-rw-r--r--spec/ruby/shared/rational/to_f.rb10
-rw-r--r--spec/ruby/shared/rational/to_i.rb12
-rw-r--r--spec/ruby/shared/rational/to_r.rb13
-rw-r--r--spec/ruby/shared/rational/to_s.rb11
-rw-r--r--spec/ruby/shared/rational/truncate.rb45
-rw-r--r--spec/ruby/shared/string/times.rb64
-rw-r--r--spec/ruby/shared/time/strftime_for_date.rb275
-rw-r--r--spec/ruby/shared/time/strftime_for_time.rb173
-rw-r--r--spec/ruby/spec_helper.rb32
-rw-r--r--sprintf.c1656
-rw-r--r--st.c2483
-rw-r--r--st.h52
-rw-r--r--strftime.c1267
-rw-r--r--string.c11673
-rw-r--r--struct.c1470
-rw-r--r--symbol.c1157
-rw-r--r--symbol.h112
-rw-r--r--template/Doxyfile.tmpl265
-rw-r--r--template/GNUmakefile.in5
-rw-r--r--template/configure-ext.mk.tmpl44
-rw-r--r--template/encdb.h.tmpl92
-rw-r--r--template/extinit.c.tmpl17
-rw-r--r--template/exts.mk.tmpl148
-rw-r--r--template/fake.rb.in40
-rw-r--r--template/id.c.tmpl43
-rw-r--r--template/id.h.tmpl97
-rw-r--r--template/insns.inc.tmpl24
-rw-r--r--template/insns_info.inc.tmpl109
-rw-r--r--template/known_errors.inc.tmpl14
-rw-r--r--template/limits.c.tmpl97
-rw-r--r--template/minsns.inc.tmpl14
-rw-r--r--template/opt_sc.inc.tmpl35
-rw-r--r--template/optinsn.inc.tmpl78
-rw-r--r--template/optunifs.inc.tmpl67
-rw-r--r--template/prelude.c.tmpl238
-rw-r--r--template/ruby-runner.h.in7
-rw-r--r--template/ruby.pc.in58
-rw-r--r--template/sizes.c.tmpl54
-rw-r--r--template/transdb.h.tmpl59
-rw-r--r--template/unicode_norm_gen.tmpl220
-rw-r--r--template/verconf.h.tmpl63
-rw-r--r--template/vm.inc.tmpl33
-rw-r--r--template/vmtc.inc.tmpl21
-rw-r--r--template/yarvarch.en7
-rw-r--r--template/yarvarch.ja454
-rw-r--r--template/yasmdata.rb.tmpl20
-rw-r--r--test/-ext-/array/test_resize.rb30
-rw-r--r--test/-ext-/bignum/test_big2str.rb30
-rw-r--r--test/-ext-/bignum/test_bigzero.rb20
-rw-r--r--test/-ext-/bignum/test_div.rb29
-rw-r--r--test/-ext-/bignum/test_mul.rb138
-rw-r--r--test/-ext-/bignum/test_pack.rb399
-rw-r--r--test/-ext-/bignum/test_str2big.rb38
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb24
-rw-r--r--test/-ext-/class/test_class2name.rb19
-rw-r--r--test/-ext-/debug/test_debug.rb75
-rw-r--r--test/-ext-/debug/test_profile_frames.rb122
-rw-r--r--test/-ext-/exception/test_data_error.rb14
-rw-r--r--test/-ext-/exception/test_enc_raise.rb16
-rw-r--r--test/-ext-/exception/test_ensured.rb32
-rw-r--r--test/-ext-/exception/test_exception_at_throwing.rb18
-rw-r--r--test/-ext-/file/test_stat.rb15
-rw-r--r--test/-ext-/float/test_nextafter.rb65
-rw-r--r--test/-ext-/funcall/test_funcall.rb11
-rw-r--r--test/-ext-/funcall/test_passing_block.rb23
-rw-r--r--test/-ext-/gvl/test_last_thread.rb23
-rw-r--r--test/-ext-/hash/test_delete.rb20
-rw-r--r--test/-ext-/integer/test_integer.rb26
-rw-r--r--test/-ext-/integer/test_my_integer.rb48
-rw-r--r--test/-ext-/iseq_load/test_iseq_load.rb117
-rw-r--r--test/-ext-/iter/test_iter_break.rb16
-rw-r--r--test/-ext-/iter/test_yield_block.rb34
-rw-r--r--test/-ext-/load/script.rb2
-rw-r--r--test/-ext-/load/test_dot_dot.rb11
-rw-r--r--test/-ext-/load/test_protect.rb14
-rw-r--r--test/-ext-/marshal/test_internal_ivar.rb20
-rw-r--r--test/-ext-/marshal/test_usrmarshal.rb33
-rw-r--r--test/-ext-/method/test_arity.rb38
-rw-r--r--test/-ext-/num2int/test_num2int.rb265
-rw-r--r--test/-ext-/path_to_class/test_path_to_class.rb13
-rw-r--r--test/-ext-/popen_deadlock/test_popen_deadlock.rb36
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb28
-rw-r--r--test/-ext-/proc/test_bmethod.rb38
-rw-r--r--test/-ext-/rational/test_rat.rb32
-rw-r--r--test/-ext-/st/test_foreach.rb16
-rw-r--r--test/-ext-/st/test_numhash.rb50
-rw-r--r--test/-ext-/st/test_update.rb51
-rw-r--r--test/-ext-/string/test_capacity.rb40
-rw-r--r--test/-ext-/string/test_coderange.rb60
-rw-r--r--test/-ext-/string/test_cstr.rb164
-rw-r--r--test/-ext-/string/test_ellipsize.rb47
-rw-r--r--test/-ext-/string/test_enc_associate.rb24
-rw-r--r--test/-ext-/string/test_enc_str_buf_cat.rb16
-rw-r--r--test/-ext-/string/test_external_new.rb17
-rw-r--r--test/-ext-/string/test_fstring.rb74
-rw-r--r--test/-ext-/string/test_modify_expand.rb27
-rw-r--r--test/-ext-/string/test_nofree.rb13
-rw-r--r--test/-ext-/string/test_normalize.rb110
-rw-r--r--test/-ext-/string/test_qsort.rb20
-rw-r--r--test/-ext-/string/test_rb_str_dup.rb16
-rw-r--r--test/-ext-/string/test_set_len.rb35
-rw-r--r--test/-ext-/struct/test_duplicate.rb22
-rw-r--r--test/-ext-/struct/test_len.rb10
-rw-r--r--test/-ext-/struct/test_member.rb14
-rw-r--r--test/-ext-/symbol/noninterned_name.rb15
-rw-r--r--test/-ext-/symbol/test_inadvertent_creation.rb494
-rw-r--r--test/-ext-/symbol/test_type.rb139
-rw-r--r--test/-ext-/test_bug-3571.rb21
-rw-r--r--test/-ext-/test_bug-5832.rb22
-rw-r--r--test/-ext-/test_notimplement.rb15
-rw-r--r--test/-ext-/test_printf.rb191
-rw-r--r--test/-ext-/test_recursion.rb36
-rw-r--r--test/-ext-/test_scan_args.rb231
-rw-r--r--test/-ext-/thread_fd_close/test_thread_fd_close.rb25
-rw-r--r--test/-ext-/time/test_new.rb44
-rw-r--r--test/-ext-/tracepoint/test_tracepoint.rb80
-rw-r--r--test/-ext-/typeddata/test_typeddata.rb29
-rw-r--r--test/-ext-/vm/test_at_exit.rb19
-rw-r--r--test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb53
-rw-r--r--test/-ext-/win32/test_console_attr.rb44
-rw-r--r--test/-ext-/win32/test_dln.rb39
-rw-r--r--test/-ext-/win32/test_fd_setsize.rb25
-rw-r--r--test/base64/test_base64.rb115
-rw-r--r--test/benchmark/test_benchmark.rb162
-rw-r--r--test/bigdecimal/test_bigdecimal.rb1842
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb60
-rw-r--r--test/bigdecimal/test_bigmath.rb81
-rw-r--r--test/bigdecimal/testbase.rb28
-rw-r--r--test/cgi/test_cgi_cookie.rb121
-rw-r--r--test/cgi/test_cgi_core.rb303
-rw-r--r--test/cgi/test_cgi_header.rb184
-rw-r--r--test/cgi/test_cgi_modruby.rb149
-rw-r--r--test/cgi/test_cgi_multipart.rb386
-rw-r--r--test/cgi/test_cgi_session.rb169
-rw-r--r--test/cgi/test_cgi_tag_helper.rb355
-rw-r--r--test/cgi/test_cgi_util.rb200
-rw-r--r--test/cgi/testdata/file1.html10
-rw-r--r--test/cgi/testdata/large.pngbin0 -> 156414 bytes-rw-r--r--test/cgi/testdata/small.pngbin0 -> 82 bytes-rw-r--r--test/cgi/update_env.rb9
-rw-r--r--test/colors3
-rw-r--r--test/coverage/test_coverage.rb495
-rw-r--r--test/csv/base.rb9
-rw-r--r--test/csv/line_endings.gzbin0 -> 59 bytes-rwxr-xr-xtest/csv/test_csv_parsing.rb244
-rwxr-xr-xtest/csv/test_csv_writing.rb98
-rwxr-xr-xtest/csv/test_data_converters.rb273
-rwxr-xr-xtest/csv/test_encodings.rb338
-rwxr-xr-xtest/csv/test_features.rb380
-rwxr-xr-xtest/csv/test_headers.rb305
-rwxr-xr-xtest/csv/test_interface.rb393
-rwxr-xr-xtest/csv/test_row.rb380
-rwxr-xr-xtest/csv/test_table.rb497
-rw-r--r--test/csv/ts_all.rb21
-rw-r--r--test/date/test_date.rb153
-rw-r--r--test/date/test_date_arith.rb278
-rw-r--r--test/date/test_date_attr.rb103
-rw-r--r--test/date/test_date_base.rb435
-rw-r--r--test/date/test_date_compat.rb22
-rw-r--r--test/date/test_date_conv.rb153
-rw-r--r--test/date/test_date_marshal.rb42
-rw-r--r--test/date/test_date_new.rb270
-rw-r--r--test/date/test_date_parse.rb1125
-rw-r--r--test/date/test_date_strftime.rb431
-rw-r--r--test/date/test_date_strptime.rb513
-rw-r--r--test/date/test_switch_hitter.rb664
-rw-r--r--test/dbm/test_dbm.rb634
-rw-r--r--test/digest/digest/foo.rb11
-rw-r--r--test/digest/test_digest.rb280
-rw-r--r--test/digest/test_digest_extend.rb159
-rw-r--r--test/drb/drbtest.rb362
-rw-r--r--test/drb/ignore_test_drb.rb14
-rw-r--r--test/drb/test_acl.rb207
-rw-r--r--test/drb/test_drb.rb351
-rw-r--r--test/drb/test_drbssl.rb77
-rw-r--r--test/drb/test_drbunix.rb60
-rw-r--r--test/drb/ut_array.rb17
-rw-r--r--test/drb/ut_array_drbssl.rb39
-rw-r--r--test/drb/ut_array_drbunix.rb17
-rw-r--r--test/drb/ut_drb.rb168
-rw-r--r--test/drb/ut_drb_drbssl.rb40
-rw-r--r--test/drb/ut_drb_drbunix.rb18
-rw-r--r--test/drb/ut_eq.rb37
-rw-r--r--test/drb/ut_large.rb62
-rw-r--r--test/drb/ut_port.rb16
-rw-r--r--test/drb/ut_safe1.rb17
-rw-r--r--test/drb/ut_timerholder.rb74
-rw-r--r--test/dtrace/dummy.rb2
-rw-r--r--test/dtrace/helper.rb83
-rw-r--r--test/dtrace/test_array_create.rb36
-rw-r--r--test/dtrace/test_cmethod.rb50
-rw-r--r--test/dtrace/test_function_entry.rb88
-rw-r--r--test/dtrace/test_gc.rb27
-rw-r--r--test/dtrace/test_hash_create.rb53
-rw-r--r--test/dtrace/test_load.rb53
-rw-r--r--test/dtrace/test_method_cache.rb29
-rw-r--r--test/dtrace/test_object_create_start.rb36
-rw-r--r--test/dtrace/test_raise.rb30
-rw-r--r--test/dtrace/test_require.rb35
-rw-r--r--test/dtrace/test_singleton_function.rb56
-rw-r--r--test/dtrace/test_string.rb28
-rw-r--r--test/erb/hello.erb4
-rw-r--r--test/erb/test_erb.rb645
-rw-r--r--test/erb/test_erb_command.rb18
-rw-r--r--test/erb/test_erb_m17n.rb124
-rw-r--r--test/etc/test_etc.rb172
-rw-r--r--test/excludes/TestException.rb8
-rw-r--r--test/excludes/TestIO_Console.rb2
-rw-r--r--test/excludes/TestISeq.rb1
-rw-r--r--test/excludes/TestThread.rb2
-rw-r--r--test/fiddle/helper.rb123
-rw-r--r--test/fiddle/test_c_struct_entry.rb77
-rw-r--r--test/fiddle/test_c_union_entity.rb35
-rw-r--r--test/fiddle/test_closure.rb85
-rw-r--r--test/fiddle/test_cparser.rb211
-rw-r--r--test/fiddle/test_fiddle.rb17
-rw-r--r--test/fiddle/test_func.rb93
-rw-r--r--test/fiddle/test_function.rb100
-rw-r--r--test/fiddle/test_handle.rb194
-rw-r--r--test/fiddle/test_import.rb151
-rw-r--r--test/fiddle/test_pointer.rb236
-rw-r--r--test/fileutils/clobber.rb92
-rw-r--r--test/fileutils/fileasserts.rb112
-rw-r--r--test/fileutils/test_dryrun.rb18
-rw-r--r--test/fileutils/test_fileutils.rb1699
-rw-r--r--test/fileutils/test_nowrite.rb18
-rw-r--r--test/fileutils/test_verbose.rb18
-rw-r--r--test/fileutils/visibility_tests.rb42
-rw-r--r--test/gdbm/test_gdbm.rb733
-rw-r--r--test/io/console/test_io_console.rb420
-rw-r--r--test/io/nonblock/test_flush.rb72
-rw-r--r--test/io/wait/test_io_wait.rb167
-rw-r--r--test/irb/test_completion.rb22
-rw-r--r--test/irb/test_init.rb31
-rw-r--r--test/irb/test_option.rb12
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb14
-rw-r--r--test/irb/test_ruby-lex.rb108
-rw-r--r--test/irb/test_workspace.rb94
-rw-r--r--test/json/fixtures/fail10.json1
-rw-r--r--test/json/fixtures/fail11.json1
-rw-r--r--test/json/fixtures/fail12.json1
-rw-r--r--test/json/fixtures/fail13.json1
-rw-r--r--test/json/fixtures/fail14.json1
-rw-r--r--test/json/fixtures/fail18.json1
-rw-r--r--test/json/fixtures/fail19.json1
-rw-r--r--test/json/fixtures/fail2.json1
-rw-r--r--test/json/fixtures/fail20.json1
-rw-r--r--test/json/fixtures/fail21.json1
-rw-r--r--test/json/fixtures/fail22.json1
-rw-r--r--test/json/fixtures/fail23.json1
-rw-r--r--test/json/fixtures/fail24.json1
-rw-r--r--test/json/fixtures/fail25.json1
-rw-r--r--test/json/fixtures/fail27.json2
-rw-r--r--test/json/fixtures/fail28.json2
-rw-r--r--test/json/fixtures/fail3.json1
-rw-r--r--test/json/fixtures/fail4.json1
-rw-r--r--test/json/fixtures/fail5.json1
-rw-r--r--test/json/fixtures/fail6.json1
-rw-r--r--test/json/fixtures/fail7.json1
-rw-r--r--test/json/fixtures/fail8.json1
-rw-r--r--test/json/fixtures/fail9.json1
-rw-r--r--test/json/fixtures/obsolete_fail1.json1
-rw-r--r--test/json/fixtures/pass1.json56
-rw-r--r--test/json/fixtures/pass15.json1
-rw-r--r--test/json/fixtures/pass16.json1
-rw-r--r--test/json/fixtures/pass17.json1
-rw-r--r--test/json/fixtures/pass2.json1
-rw-r--r--test/json/fixtures/pass26.json1
-rw-r--r--test/json/fixtures/pass3.json6
-rw-r--r--test/json/json_addition_test.rb193
-rw-r--r--test/json/json_common_interface_test.rb126
-rw-r--r--test/json/json_encoding_test.rb107
-rw-r--r--test/json/json_ext_parser_test.rb15
-rw-r--r--test/json/json_fixtures_test.rb32
-rw-r--r--test/json/json_generator_test.rb377
-rw-r--r--test/json/json_generic_object_test.rb82
-rw-r--r--test/json/json_parser_test.rb472
-rw-r--r--test/json/json_string_matching_test.rb38
-rw-r--r--test/json/test_helper.rb21
-rw-r--r--test/lib/-test-/integer.rb14
-rw-r--r--test/lib/envutil.rb298
-rw-r--r--test/lib/find_executable.rb22
-rw-r--r--test/lib/iseq_loader_checker.rb75
-rw-r--r--test/lib/leakchecker.rb229
-rw-r--r--test/lib/memory_status.rb149
-rw-r--r--test/lib/minitest/README.txt457
-rw-r--r--test/lib/minitest/autorun.rb14
-rw-r--r--test/lib/minitest/benchmark.rb418
-rw-r--r--test/lib/minitest/mock.rb196
-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.rb943
-rw-r--r--test/lib/test/unit/parallel.rb208
-rw-r--r--test/lib/test/unit/testcase.rb36
-rw-r--r--test/lib/tracepointchecker.rb126
-rw-r--r--test/lib/with_different_ofs.rb18
-rw-r--r--test/lib/zombie_hunter.rb9
-rw-r--r--test/logger/test_logdevice.rb838
-rw-r--r--test/logger/test_logger.rb344
-rw-r--r--test/logger/test_severity.rb16
-rw-r--r--test/matrix/test_matrix.rb651
-rw-r--r--test/matrix/test_vector.rb231
-rw-r--r--test/minitest/metametameta.rb71
-rw-r--r--test/minitest/test_minitest_benchmark.rb131
-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.rb145
-rw-r--r--test/mkmf/test_config.rb17
-rw-r--r--test/mkmf/test_constant.rb38
-rw-r--r--test/mkmf/test_convertible.rb35
-rw-r--r--test/mkmf/test_find_executable.rb58
-rw-r--r--test/mkmf/test_flags.rb57
-rw-r--r--test/mkmf/test_framework.rb49
-rw-r--r--test/mkmf/test_have_func.rb17
-rw-r--r--test/mkmf/test_have_library.rb56
-rw-r--r--test/mkmf/test_have_macro.rb36
-rw-r--r--test/mkmf/test_libs.rb87
-rw-r--r--test/mkmf/test_signedness.rb30
-rw-r--r--test/mkmf/test_sizeof.rb48
-rw-r--r--test/monitor/test_monitor.rb272
-rw-r--r--test/net/fixtures/cacert.pem24
-rw-r--r--test/net/fixtures/dhparams.pem29
-rw-r--r--test/net/fixtures/server.crt82
-rw-r--r--test/net/fixtures/server.key28
-rw-r--r--test/net/ftp/test_buffered_socket.rb48
-rw-r--r--test/net/ftp/test_ftp.rb2471
-rw-r--r--test/net/ftp/test_mlsx_entry.rb98
-rw-r--r--test/net/http/test_buffered_io.rb18
-rw-r--r--test/net/http/test_http.rb1186
-rw-r--r--test/net/http/test_http_request.rb80
-rw-r--r--test/net/http/test_httpheader.rb427
-rw-r--r--test/net/http/test_httpresponse.rb437
-rw-r--r--test/net/http/test_httpresponses.rb25
-rw-r--r--test/net/http/test_https.rb215
-rw-r--r--test/net/http/test_https_proxy.rb47
-rw-r--r--test/net/http/utils.rb110
-rw-r--r--test/net/imap/Makefile15
-rw-r--r--test/net/imap/test_imap.rb770
-rw-r--r--test/net/imap/test_imap_response_parser.rb322
-rw-r--r--test/net/pop/test_pop.rb166
-rw-r--r--test/net/protocol/test_protocol.rb29
-rw-r--r--test/net/smtp/test_response.rb100
-rw-r--r--test/net/smtp/test_smtp.rb200
-rw-r--r--test/net/smtp/test_ssl_socket.rb97
-rw-r--r--test/nkf/test_kconv.rb82
-rw-r--r--test/nkf/test_nkf.rb23
-rw-r--r--test/objspace/test_objspace.rb446
-rw-r--r--test/open-uri/test_open-uri.rb900
-rw-r--r--test/open-uri/test_ssl.rb420
-rw-r--r--test/openssl/fixtures/pkey/dh1024.pem5
-rw-r--r--test/openssl/fixtures/pkey/dsa1024.pem12
-rw-r--r--test/openssl/fixtures/pkey/dsa256.pem8
-rw-r--r--test/openssl/fixtures/pkey/dsa512.pem8
-rw-r--r--test/openssl/fixtures/pkey/p256.pem5
-rw-r--r--test/openssl/fixtures/pkey/rsa1024.pem15
-rw-r--r--test/openssl/fixtures/pkey/rsa2048.pem27
-rw-r--r--test/openssl/test_asn1.rb694
-rw-r--r--test/openssl/test_bn.rb277
-rw-r--r--test/openssl/test_buffering.rb90
-rw-r--r--test/openssl/test_cipher.rb325
-rw-r--r--test/openssl/test_config.rb304
-rw-r--r--test/openssl/test_digest.rb121
-rw-r--r--test/openssl/test_engine.rb97
-rw-r--r--test/openssl/test_fips.rb30
-rw-r--r--test/openssl/test_hmac.rb44
-rw-r--r--test/openssl/test_kdf.rb183
-rw-r--r--test/openssl/test_ns_spki.rb53
-rw-r--r--test/openssl/test_ocsp.rb310
-rw-r--r--test/openssl/test_pair.rb530
-rw-r--r--test/openssl/test_pkcs12.rb313
-rw-r--r--test/openssl/test_pkcs7.rb285
-rw-r--r--test/openssl/test_pkey_dh.rb103
-rw-r--r--test/openssl/test_pkey_dsa.rb200
-rw-r--r--test/openssl/test_pkey_ec.rb347
-rw-r--r--test/openssl/test_pkey_rsa.rb312
-rw-r--r--test/openssl/test_random.rb19
-rw-r--r--test/openssl/test_ssl.rb1582
-rw-r--r--test/openssl/test_ssl_session.rb400
-rw-r--r--test/openssl/test_x509attr.rb84
-rw-r--r--test/openssl/test_x509cert.rb201
-rw-r--r--test/openssl/test_x509crl.rb261
-rw-r--r--test/openssl/test_x509ext.rb91
-rw-r--r--test/openssl/test_x509name.rb456
-rw-r--r--test/openssl/test_x509req.rb163
-rw-r--r--test/openssl/test_x509store.rb241
-rw-r--r--test/openssl/ut_eof.rb133
-rw-r--r--test/openssl/utils.rb320
-rw-r--r--test/optparse/test_acceptable.rb199
-rw-r--r--test/optparse/test_autoconf.rb64
-rw-r--r--test/optparse/test_bash_completion.rb48
-rw-r--r--test/optparse/test_cclass.rb18
-rw-r--r--test/optparse/test_getopts.rb35
-rw-r--r--test/optparse/test_kwargs.rb40
-rw-r--r--test/optparse/test_noarg.rb79
-rw-r--r--test/optparse/test_optarg.rb60
-rw-r--r--test/optparse/test_optparse.rb78
-rw-r--r--test/optparse/test_placearg.rb70
-rw-r--r--test/optparse/test_reqarg.rb95
-rw-r--r--test/optparse/test_summary.rb47
-rw-r--r--test/optparse/test_zsh_completion.rb23
-rw-r--r--test/ostruct/test_ostruct.rb221
-rw-r--r--test/pathname/test_pathname.rb1429
-rw-r--r--test/psych/handlers/test_recorder.rb26
-rw-r--r--test/psych/helper.rb128
-rw-r--r--test/psych/json/test_stream.rb110
-rw-r--r--test/psych/nodes/test_enumerable.rb44
-rw-r--r--test/psych/test_alias_and_anchor.rb97
-rw-r--r--test/psych/test_array.rb64
-rw-r--r--test/psych/test_boolean.rb37
-rw-r--r--test/psych/test_class.rb37
-rw-r--r--test/psych/test_coder.rb207
-rw-r--r--test/psych/test_date_time.rb70
-rw-r--r--test/psych/test_deprecated.rb91
-rw-r--r--test/psych/test_document.rb47
-rw-r--r--test/psych/test_emitter.rb112
-rw-r--r--test/psych/test_encoding.rb281
-rw-r--r--test/psych/test_exception.rb145
-rw-r--r--test/psych/test_hash.rb95
-rw-r--r--test/psych/test_json_tree.rb66
-rw-r--r--test/psych/test_marshalable.rb55
-rw-r--r--test/psych/test_merge_keys.rb181
-rw-r--r--test/psych/test_nil.rb19
-rw-r--r--test/psych/test_null.rb20
-rw-r--r--test/psych/test_numeric.rb46
-rw-r--r--test/psych/test_object.rb45
-rw-r--r--test/psych/test_object_references.rb72
-rw-r--r--test/psych/test_omap.rb76
-rw-r--r--test/psych/test_parser.rb392
-rw-r--r--test/psych/test_psych.rb203
-rw-r--r--test/psych/test_safe_load.rb98
-rw-r--r--test/psych/test_scalar.rb17
-rw-r--r--test/psych/test_scalar_scanner.rb117
-rw-r--r--test/psych/test_serialize_subclasses.rb39
-rw-r--r--test/psych/test_set.rb50
-rw-r--r--test/psych/test_stream.rb94
-rw-r--r--test/psych/test_string.rb231
-rw-r--r--test/psych/test_struct.rb50
-rw-r--r--test/psych/test_symbol.rb26
-rw-r--r--test/psych/test_tainted.rb131
-rw-r--r--test/psych/test_tree_builder.rb94
-rw-r--r--test/psych/test_yaml.rb1293
-rw-r--r--test/psych/test_yamldbm.rb193
-rw-r--r--test/psych/test_yamlstore.rb86
-rw-r--r--test/psych/visitors/test_depth_first.rb50
-rw-r--r--test/psych/visitors/test_emitter.rb145
-rw-r--r--test/psych/visitors/test_to_ruby.rb332
-rw-r--r--test/psych/visitors/test_yaml_tree.rb197
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Amps and angle encoding.text21
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Auto links.text13
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Backslash escapes.text120
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Blockquotes with code blocks.text11
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Code Blocks.text14
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Code Spans.text6
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text8
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Horizontal rules.text67
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML (Advanced).text15
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML (Simple).text69
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML comments.text13
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, inline style.text12
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, reference style.text71
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, shortcut references.text20
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Literal quotes in titles.text7
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text306
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text888
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Nested blockquotes.text5
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Ordered and unordered lists.text131
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Strong and em together.text7
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Tabs.text21
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Tidyness.text5
-rw-r--r--test/rdoc/README1
-rw-r--r--test/rdoc/binary.datbin0 -> 1024 bytes-rw-r--r--test/rdoc/hidden.zip.txt1
-rw-r--r--test/rdoc/test.ja.largedoc3
-rw-r--r--test/rdoc/test.ja.rdoc10
-rw-r--r--test/rdoc/test.ja.txt8
-rw-r--r--test/rdoc/test.txt1
-rw-r--r--test/rdoc/test_rdoc_alias.rb14
-rw-r--r--test/rdoc/test_rdoc_any_method.rb470
-rw-r--r--test/rdoc/test_rdoc_attr.rb191
-rw-r--r--test/rdoc/test_rdoc_class_module.rb1494
-rw-r--r--test/rdoc/test_rdoc_code_object.rb440
-rw-r--r--test/rdoc/test_rdoc_comment.rb496
-rw-r--r--test/rdoc/test_rdoc_constant.rb182
-rw-r--r--test/rdoc/test_rdoc_context.rb955
-rw-r--r--test/rdoc/test_rdoc_context_section.rb155
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb193
-rw-r--r--test/rdoc/test_rdoc_encoding.rb234
-rw-r--r--test/rdoc/test_rdoc_extend.rb95
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb246
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb322
-rw-r--r--test/rdoc/test_rdoc_generator_markup.rb60
-rw-r--r--test/rdoc/test_rdoc_generator_pot.rb92
-rw-r--r--test/rdoc/test_rdoc_generator_pot_po.rb52
-rw-r--r--test/rdoc/test_rdoc_generator_pot_po_entry.rb140
-rw-r--r--test/rdoc/test_rdoc_generator_ri.rb76
-rw-r--r--test/rdoc/test_rdoc_i18n_locale.rb74
-rw-r--r--test/rdoc/test_rdoc_i18n_text.rb124
-rw-r--r--test/rdoc/test_rdoc_include.rb109
-rw-r--r--test/rdoc/test_rdoc_markdown.rb1018
-rw-r--r--test/rdoc/test_rdoc_markdown_test.rb1883
-rw-r--r--test/rdoc/test_rdoc_markup.rb96
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb373
-rw-r--r--test/rdoc/test_rdoc_markup_attributes.rb40
-rw-r--r--test/rdoc/test_rdoc_markup_document.rb208
-rw-r--r--test/rdoc/test_rdoc_markup_formatter.rb176
-rw-r--r--test/rdoc/test_rdoc_markup_hard_break.rb32
-rw-r--r--test/rdoc/test_rdoc_markup_heading.rb30
-rw-r--r--test/rdoc/test_rdoc_markup_include.rb20
-rw-r--r--test/rdoc/test_rdoc_markup_indented_paragraph.rb54
-rw-r--r--test/rdoc/test_rdoc_markup_paragraph.rb33
-rw-r--r--test/rdoc/test_rdoc_markup_parser.rb1668
-rw-r--r--test/rdoc/test_rdoc_markup_pre_process.rb467
-rw-r--r--test/rdoc/test_rdoc_markup_raw.rb23
-rw-r--r--test/rdoc/test_rdoc_markup_to_ansi.rb370
-rw-r--r--test/rdoc/test_rdoc_markup_to_bs.rb352
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb809
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb232
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_snippet.rb711
-rw-r--r--test/rdoc/test_rdoc_markup_to_joined_paragraph.rb33
-rw-r--r--test/rdoc/test_rdoc_markup_to_label.rb113
-rw-r--r--test/rdoc/test_rdoc_markup_to_markdown.rb390
-rw-r--r--test/rdoc/test_rdoc_markup_to_rdoc.rb378
-rw-r--r--test/rdoc/test_rdoc_markup_to_table_of_contents.rb127
-rw-r--r--test/rdoc/test_rdoc_markup_to_tt_only.rb247
-rw-r--r--test/rdoc/test_rdoc_markup_verbatim.rb30
-rw-r--r--test/rdoc/test_rdoc_method_attr.rb194
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb48
-rw-r--r--test/rdoc/test_rdoc_normal_module.rb43
-rw-r--r--test/rdoc/test_rdoc_options.rb760
-rw-r--r--test/rdoc/test_rdoc_parser.rb323
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb1960
-rw-r--r--test/rdoc/test_rdoc_parser_changelog.rb316
-rw-r--r--test/rdoc/test_rdoc_parser_markdown.rb62
-rw-r--r--test/rdoc/test_rdoc_parser_rd.rb56
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb3845
-rw-r--r--test/rdoc/test_rdoc_parser_simple.rb116
-rw-r--r--test/rdoc/test_rdoc_rd.rb31
-rw-r--r--test/rdoc/test_rdoc_rd_block_parser.rb536
-rw-r--r--test/rdoc/test_rdoc_rd_inline.rb64
-rw-r--r--test/rdoc/test_rdoc_rd_inline_parser.rb178
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb486
-rw-r--r--test/rdoc/test_rdoc_require.rb26
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb1489
-rw-r--r--test/rdoc/test_rdoc_ri_paths.rb156
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb248
-rw-r--r--test/rdoc/test_rdoc_servlet.rb538
-rw-r--r--test/rdoc/test_rdoc_single_class.rb21
-rw-r--r--test/rdoc/test_rdoc_stats.rb723
-rw-r--r--test/rdoc/test_rdoc_store.rb991
-rw-r--r--test/rdoc/test_rdoc_task.rb174
-rw-r--r--test/rdoc/test_rdoc_text.rb540
-rw-r--r--test/rdoc/test_rdoc_token_stream.rb43
-rw-r--r--test/rdoc/test_rdoc_tom_doc.rb521
-rw-r--r--test/rdoc/test_rdoc_top_level.rb288
-rw-r--r--test/rdoc/xref_data.rb114
-rw-r--r--test/rdoc/xref_test_case.rb70
-rw-r--r--test/readline/test_readline.rb620
-rw-r--r--test/readline/test_readline_history.rb293
-rw-r--r--test/resolv/test_addr.rb41
-rw-r--r--test/resolv/test_dns.rb268
-rw-r--r--test/resolv/test_mdns.rb22
-rw-r--r--test/resolv/test_resource.rb26
-rw-r--r--test/rexml/data/LostineRiver.kml.gzbin0 -> 50154 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.xmlbin0 -> 161690 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.xmlbin0 -> 207464 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.rb848
-rw-r--r--test/rinda/test_tuplebag.rb173
-rw-r--r--test/ripper/dummyparser.rb284
-rw-r--r--test/ripper/test_files.rb50
-rw-r--r--test/ripper/test_filter.rb95
-rw-r--r--test/ripper/test_lexer.rb93
-rw-r--r--test/ripper/test_parser_events.rb1505
-rw-r--r--test/ripper/test_ripper.rb142
-rw-r--r--test/ripper/test_scanner_events.rb940
-rw-r--r--test/ripper/test_sexp.rb143
-rw-r--r--test/rss/dot.pngbin0 -> 111 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.rb352
-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.rb480
-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/allpairs.rb103
-rw-r--r--test/ruby/beginmainend.rb79
-rw-r--r--test/ruby/bug-11928.rb14
-rw-r--r--test/ruby/bug-13526.rb22
-rw-r--r--test/ruby/enc/test_big5.rb29
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb303
-rw-r--r--test/ruby/enc/test_case_mapping.rb198
-rw-r--r--test/ruby/enc/test_case_options.rb81
-rw-r--r--test/ruby/enc/test_cp949.rb29
-rw-r--r--test/ruby/enc/test_emoji.rb443
-rw-r--r--test/ruby/enc/test_euc_jp.rb25
-rw-r--r--test/ruby/enc/test_euc_kr.rb37
-rw-r--r--test/ruby/enc/test_euc_tw.rb29
-rw-r--r--test/ruby/enc/test_gb18030.rb127
-rw-r--r--test/ruby/enc/test_gbk.rb29
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb92
-rw-r--r--test/ruby/enc/test_iso_8859.rb166
-rw-r--r--test/ruby/enc/test_koi8.rb23
-rw-r--r--test/ruby/enc/test_regex_casefold.rb120
-rw-r--r--test/ruby/enc/test_shift_jis.rb28
-rw-r--r--test/ruby/enc/test_utf16.rb397
-rw-r--r--test/ruby/enc/test_utf32.rb162
-rw-r--r--test/ruby/enc/test_windows_1251.rb17
-rw-r--r--test/ruby/enc/test_windows_1252.rb26
-rw-r--r--test/ruby/lbtest.rb49
-rw-r--r--test/ruby/marshaltestlib.rb437
-rw-r--r--test/ruby/sentence.rb669
-rw-r--r--test/ruby/test_alias.rb236
-rw-r--r--test/ruby/test_argf.rb1057
-rw-r--r--test/ruby/test_arity.rb70
-rw-r--r--test/ruby/test_array.rb3052
-rw-r--r--test/ruby/test_assignment.rb784
-rw-r--r--test/ruby/test_autoload.rb323
-rw-r--r--test/ruby/test_backtrace.rb300
-rw-r--r--test/ruby/test_basicinstructions.rb723
-rw-r--r--test/ruby/test_beginendblock.rb179
-rw-r--r--test/ruby/test_bignum.rb798
-rw-r--r--test/ruby/test_call.rb102
-rw-r--r--test/ruby/test_case.rb146
-rw-r--r--test/ruby/test_class.rb628
-rw-r--r--test/ruby/test_clone.rb29
-rw-r--r--test/ruby/test_comparable.rb115
-rw-r--r--test/ruby/test_complex.rb961
-rw-r--r--test/ruby/test_complex2.rb736
-rw-r--r--test/ruby/test_complexrational.rb408
-rw-r--r--test/ruby/test_condition.rb17
-rw-r--r--test/ruby/test_const.rb72
-rw-r--r--test/ruby/test_continuation.rb136
-rw-r--r--test/ruby/test_defined.rb260
-rw-r--r--test/ruby/test_dir.rb424
-rw-r--r--test/ruby/test_dir_m17n.rb449
-rw-r--r--test/ruby/test_econv.rb924
-rw-r--r--test/ruby/test_encoding.rb128
-rw-r--r--test/ruby/test_enum.rb1032
-rw-r--r--test/ruby/test_enumerator.rb665
-rw-r--r--test/ruby/test_env.rb533
-rw-r--r--test/ruby/test_eval.rb546
-rw-r--r--test/ruby/test_exception.rb1187
-rw-r--r--test/ruby/test_fiber.rb395
-rw-r--r--test/ruby/test_file.rb518
-rw-r--r--test/ruby/test_file_exhaustive.rb1694
-rw-r--r--test/ruby/test_fixnum.rb352
-rw-r--r--test/ruby/test_flip.rb74
-rw-r--r--test/ruby/test_float.rb926
-rw-r--r--test/ruby/test_fnmatch.rb138
-rw-r--r--test/ruby/test_gc.rb454
-rw-r--r--test/ruby/test_hash.rb1626
-rw-r--r--test/ruby/test_ifunless.rb15
-rw-r--r--test/ruby/test_integer.rb528
-rw-r--r--test/ruby/test_integer_comb.rb634
-rw-r--r--test/ruby/test_io.rb3775
-rw-r--r--test/ruby/test_io_m17n.rb2704
-rw-r--r--test/ruby/test_iseq.rb434
-rw-r--r--test/ruby/test_iterator.rb502
-rw-r--r--test/ruby/test_keyword.rb685
-rw-r--r--test/ruby/test_lambda.rb183
-rw-r--r--test/ruby/test_lazy_enumerator.rb581
-rw-r--r--test/ruby/test_literal.rb570
-rw-r--r--test/ruby/test_m17n.rb1700
-rw-r--r--test/ruby/test_m17n_comb.rb1644
-rw-r--r--test/ruby/test_marshal.rb814
-rw-r--r--test/ruby/test_math.rb342
-rw-r--r--test/ruby/test_metaclass.rb168
-rw-r--r--test/ruby/test_method.rb1049
-rw-r--r--test/ruby/test_mixed_unicode_escapes.rb30
-rw-r--r--test/ruby/test_module.rb2323
-rw-r--r--test/ruby/test_not.rb13
-rw-r--r--test/ruby/test_notimp.rb85
-rw-r--r--test/ruby/test_numeric.rb410
-rw-r--r--test/ruby/test_object.rb948
-rw-r--r--test/ruby/test_objectspace.rb206
-rw-r--r--test/ruby/test_optimization.rb787
-rw-r--r--test/ruby/test_pack.rb879
-rw-r--r--test/ruby/test_parse.rb1113
-rw-r--r--test/ruby/test_path.rb263
-rw-r--r--test/ruby/test_pipe.rb30
-rw-r--r--test/ruby/test_primitive.rb424
-rw-r--r--test/ruby/test_proc.rb1379
-rw-r--r--test/ruby/test_process.rb2376
-rw-r--r--test/ruby/test_rand.rb587
-rw-r--r--test/ruby/test_range.rb662
-rw-r--r--test/ruby/test_rational.rb996
-rw-r--r--test/ruby/test_rational2.rb1387
-rw-r--r--test/ruby/test_readpartial.rb73
-rw-r--r--test/ruby/test_refinement.rb2114
-rw-r--r--test/ruby/test_regexp.rb1281
-rw-r--r--test/ruby/test_require.rb898
-rw-r--r--test/ruby/test_rubyoptions.rb996
-rw-r--r--test/ruby/test_rubyvm.rb18
-rw-r--r--test/ruby/test_settracefunc.rb1861
-rw-r--r--test/ruby/test_signal.rb324
-rw-r--r--test/ruby/test_sleep.rb17
-rw-r--r--test/ruby/test_sprintf.rb535
-rw-r--r--test/ruby/test_sprintf_comb.rb554
-rw-r--r--test/ruby/test_string.rb3150
-rw-r--r--test/ruby/test_stringchar.rb182
-rw-r--r--test/ruby/test_struct.rb418
-rw-r--r--test/ruby/test_super.rb563
-rw-r--r--test/ruby/test_symbol.rb530
-rw-r--r--test/ruby/test_syntax.rb1235
-rw-r--r--test/ruby/test_system.rb163
-rw-r--r--test/ruby/test_thread.rb1317
-rw-r--r--test/ruby/test_threadgroup.rb57
-rw-r--r--test/ruby/test_time.rb1166
-rw-r--r--test/ruby/test_time_tz.rb463
-rw-r--r--test/ruby/test_trace.rb62
-rw-r--r--test/ruby/test_transcode.rb2231
-rw-r--r--test/ruby/test_undef.rb38
-rw-r--r--test/ruby/test_unicode_escape.rb272
-rw-r--r--test/ruby/test_variable.rb163
-rw-r--r--test/ruby/test_vm_dump.rb21
-rw-r--r--test/ruby/test_weakmap.rb135
-rw-r--r--test/ruby/test_whileuntil.rb83
-rw-r--r--test/ruby/test_yield.rb425
-rw-r--r--test/ruby/ut_eof.rb129
-rw-r--r--test/rubygems/alternate_cert.pem19
-rw-r--r--test/rubygems/alternate_cert_32.pem19
-rw-r--r--test/rubygems/alternate_key.pem27
-rw-r--r--test/rubygems/bad_rake.rb2
-rw-r--r--test/rubygems/bogussources.rb9
-rw-r--r--test/rubygems/ca_cert.pem77
-rw-r--r--test/rubygems/child_cert.pem20
-rw-r--r--test/rubygems/child_cert_32.pem20
-rw-r--r--test/rubygems/child_key.pem27
-rw-r--r--test/rubygems/client.pem107
-rw-r--r--test/rubygems/data/gem-private_key.pem27
-rw-r--r--test/rubygems/data/gem-public_cert.pem20
-rw-r--r--test/rubygems/data/null-type.gemspec.rzbin0 -> 554 bytes-rw-r--r--test/rubygems/encrypted_private_key.pem30
-rw-r--r--test/rubygems/expired_cert.pem19
-rw-r--r--test/rubygems/fake_certlib/openssl.rb8
-rw-r--r--test/rubygems/fix_openssl_warnings.rb13
-rw-r--r--test/rubygems/foo/discover.rb1
-rw-r--r--test/rubygems/future_cert.pem19
-rw-r--r--test/rubygems/future_cert_32.pem19
-rw-r--r--test/rubygems/good_rake.rb2
-rw-r--r--test/rubygems/grandchild_cert.pem20
-rw-r--r--test/rubygems/grandchild_cert_32.pem20
-rw-r--r--test/rubygems/grandchild_key.pem27
-rw-r--r--test/rubygems/invalid_client.pem49
-rw-r--r--test/rubygems/invalid_issuer_cert.pem20
-rw-r--r--test/rubygems/invalid_issuer_cert_32.pem20
-rw-r--r--test/rubygems/invalid_key.pem27
-rw-r--r--test/rubygems/invalid_signer_cert.pem19
-rw-r--r--test/rubygems/invalid_signer_cert_32.pem19
-rw-r--r--test/rubygems/invalidchild_cert.pem20
-rw-r--r--test/rubygems/invalidchild_cert_32.pem20
-rw-r--r--test/rubygems/invalidchild_key.pem27
-rw-r--r--test/rubygems/plugin/exception/rubygems_plugin.rb3
-rw-r--r--test/rubygems/plugin/load/rubygems_plugin.rb4
-rw-r--r--test/rubygems/plugin/standarderror/rubygems_plugin.rb3
-rw-r--r--test/rubygems/private3072_key.pem40
-rw-r--r--test/rubygems/private_key.pem27
-rw-r--r--test/rubygems/public3072_cert.pem25
-rw-r--r--test/rubygems/public_cert.pem20
-rw-r--r--test/rubygems/public_cert_32.pem19
-rw-r--r--test/rubygems/public_key.pem9
-rw-r--r--test/rubygems/rubygems/commands/crash_command.rb6
-rw-r--r--test/rubygems/rubygems_plugin.rb26
-rw-r--r--test/rubygems/sff/discover.rb1
-rw-r--r--test/rubygems/simple_gem.rb67
-rw-r--r--test/rubygems/specifications/bar-0.0.2.gemspec9
-rw-r--r--test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspecbin0 -> 269 bytes-rw-r--r--test/rubygems/ssl_cert.pem80
-rw-r--r--test/rubygems/ssl_key.pem27
-rw-r--r--test/rubygems/test_bundled_ca.rb63
-rw-r--r--test/rubygems/test_config.rb24
-rw-r--r--test/rubygems/test_deprecate.rb77
-rw-r--r--test/rubygems/test_gem.rb1904
-rw-r--r--test/rubygems/test_gem_available_set.rb130
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb126
-rw-r--r--test/rubygems/test_gem_command.rb254
-rw-r--r--test/rubygems/test_gem_command_manager.rb264
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb147
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb735
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb69
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb240
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb240
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb230
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb154
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb127
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb51
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb75
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb1041
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb34
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb69
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb20
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb71
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb33
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb237
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb491
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb330
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb830
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb18
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb60
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb266
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb98
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb37
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb301
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb251
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb43
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb295
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb209
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb508
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb87
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb100
-rw-r--r--test/rubygems/test_gem_config_file.rb490
-rw-r--r--test/rubygems/test_gem_dependency.rb390
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb1235
-rw-r--r--test/rubygems/test_gem_dependency_list.rb260
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb29
-rw-r--r--test/rubygems/test_gem_doctor.rb169
-rw-r--r--test/rubygems/test_gem_ext_builder.rb341
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb87
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb87
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb234
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb82
-rw-r--r--test/rubygems/test_gem_gem_runner.rb101
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb235
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb62
-rw-r--r--test/rubygems/test_gem_indexer.rb366
-rw-r--r--test/rubygems/test_gem_install_update_options.rb200
-rw-r--r--test/rubygems/test_gem_installer.rb1907
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb134
-rw-r--r--test/rubygems/test_gem_name_tuple.rb45
-rw-r--r--test/rubygems/test_gem_package.rb990
-rw-r--r--test/rubygems/test_gem_package_old.rb90
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb167
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb90
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb142
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb288
-rw-r--r--test/rubygems/test_gem_package_task.rb84
-rw-r--r--test/rubygems/test_gem_path_support.rb121
-rw-r--r--test/rubygems/test_gem_platform.rb308
-rw-r--r--test/rubygems/test_gem_rdoc.rb272
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb1070
-rw-r--r--test/rubygems/test_gem_request.rb495
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb129
-rw-r--r--test/rubygems/test_gem_request_set.rb595
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb831
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb470
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb549
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb306
-rw-r--r--test/rubygems/test_gem_requirement.rb393
-rw-r--r--test/rubygems/test_gem_resolver.rb753
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb74
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb209
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb145
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb138
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb46
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb88
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb85
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb190
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb114
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb90
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb90
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb50
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb258
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb46
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb64
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb100
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb21
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb65
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb84
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb84
-rw-r--r--test/rubygems/test_gem_security.rb312
-rw-r--r--test/rubygems/test_gem_security_policy.rb541
-rw-r--r--test/rubygems/test_gem_security_signer.rb217
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb101
-rw-r--r--test/rubygems/test_gem_server.rb607
-rw-r--r--test/rubygems/test_gem_silent_ui.rb117
-rw-r--r--test/rubygems/test_gem_source.rb251
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb28
-rw-r--r--test/rubygems/test_gem_source_git.rb309
-rw-r--r--test/rubygems/test_gem_source_installed.rb37
-rw-r--r--test/rubygems/test_gem_source_list.rb118
-rw-r--r--test/rubygems/test_gem_source_local.rb107
-rw-r--r--test/rubygems/test_gem_source_lock.rb115
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb76
-rw-r--r--test/rubygems/test_gem_source_vendor.rb32
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb331
-rw-r--r--test/rubygems/test_gem_specification.rb3658
-rw-r--r--test/rubygems/test_gem_stream_ui.rb239
-rw-r--r--test/rubygems/test_gem_stub_specification.rb296
-rw-r--r--test/rubygems/test_gem_text.rb93
-rw-r--r--test/rubygems/test_gem_uninstaller.rb485
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb33
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb29
-rw-r--r--test/rubygems/test_gem_util.rb66
-rw-r--r--test/rubygems/test_gem_validator.rb46
-rw-r--r--test/rubygems/test_gem_version.rb260
-rw-r--r--test/rubygems/test_gem_version_option.rb167
-rw-r--r--test/rubygems/test_kernel.rb123
-rw-r--r--test/rubygems/test_remote_fetch_error.rb21
-rw-r--r--test/rubygems/test_require.rb424
-rw-r--r--test/rubygems/wrong_key_cert.pem19
-rw-r--r--test/rubygems/wrong_key_cert_32.pem19
-rw-r--r--test/runner.rb38
-rw-r--r--test/scanf/data.txt6
-rw-r--r--test/scanf/test_scanf.rb305
-rw-r--r--test/scanf/test_scanfblocks.rb82
-rw-r--r--test/scanf/test_scanfio.rb28
-rw-r--r--test/sdbm/test_sdbm.rb544
-rw-r--r--test/shell/test_command_processor.rb100
-rw-r--r--test/socket/test_addrinfo.rb684
-rw-r--r--test/socket/test_ancdata.rb68
-rw-r--r--test/socket/test_basicsocket.rb229
-rw-r--r--test/socket/test_nonblock.rb397
-rw-r--r--test/socket/test_socket.rb730
-rw-r--r--test/socket/test_sockopt.rb80
-rw-r--r--test/socket/test_tcp.rb98
-rw-r--r--test/socket/test_udp.rb112
-rw-r--r--test/socket/test_unix.rb711
-rw-r--r--test/stringio/test_stringio.rb784
-rw-r--r--test/strscan/test_stringscanner.rb753
-rw-r--r--test/syslog/test_syslog_logger.rb573
-rw-r--r--test/test_abbrev.rb55
-rw-r--r--test/test_cmath.rb76
-rw-r--r--test/test_delegate.rb261
-rw-r--r--test/test_extlibs.rb83
-rw-r--r--test/test_find.rb334
-rw-r--r--test/test_forwardable.rb339
-rw-r--r--test/test_ipaddr.rb385
-rw-r--r--test/test_mutex_m.rb26
-rw-r--r--test/test_observer.rb66
-rw-r--r--test/test_open3.rb318
-rw-r--r--test/test_pp.rb197
-rw-r--r--test/test_prettyprint.rb521
-rw-r--r--test/test_prime.rb198
-rw-r--r--test/test_pstore.rb150
-rw-r--r--test/test_pty.rb242
-rw-r--r--test/test_rbconfig.rb63
-rw-r--r--test/test_securerandom.rb194
-rw-r--r--test/test_set.rb909
-rw-r--r--test/test_shellwords.rb126
-rw-r--r--test/test_singleton.rb104
-rw-r--r--test/test_syslog.rb190
-rw-r--r--test/test_tempfile.rb419
-rw-r--r--test/test_time.rb516
-rw-r--r--test/test_timeout.rb110
-rw-r--r--test/test_tmpdir.rb82
-rw-r--r--test/test_tracer.rb56
-rw-r--r--test/test_tsort.rb115
-rw-r--r--test/test_unicode_normalize.rb198
-rw-r--r--test/test_weakref.rb72
-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.rb29
-rw-r--r--test/testunit/test_hideskip.rb17
-rw-r--r--test/testunit/test_parallel.rb200
-rw-r--r--test/testunit/test_redefinition.rb16
-rw-r--r--test/testunit/test_sorting.rb18
-rw-r--r--test/testunit/tests_for_parallel/ptest_first.rb8
-rw-r--r--test/testunit/tests_for_parallel/ptest_forth.rb30
-rw-r--r--test/testunit/tests_for_parallel/ptest_second.rb12
-rw-r--r--test/testunit/tests_for_parallel/ptest_third.rb11
-rw-r--r--test/testunit/tests_for_parallel/runner.rb14
-rw-r--r--test/thread/test_cv.rb239
-rw-r--r--test/thread/test_queue.rb616
-rw-r--r--test/thread/test_sync.rb68
-rw-r--r--test/uri/test_common.rb175
-rw-r--r--test/uri/test_ftp.rb67
-rw-r--r--test/uri/test_generic.rb1022
-rw-r--r--test/uri/test_http.rb70
-rw-r--r--test/uri/test_ldap.rb101
-rw-r--r--test/uri/test_mailto.rb191
-rw-r--r--test/uri/test_parser.rb48
-rw-r--r--test/webrick/.htaccess1
-rw-r--r--test/webrick/test_cgi.rb170
-rw-r--r--test/webrick/test_config.rb17
-rw-r--r--test/webrick/test_cookie.rb141
-rw-r--r--test/webrick/test_do_not_reverse_lookup.rb71
-rw-r--r--test/webrick/test_filehandler.rb351
-rw-r--r--test/webrick/test_htmlutils.rb21
-rw-r--r--test/webrick/test_httpauth.rb348
-rw-r--r--test/webrick/test_httpproxy.rb328
-rw-r--r--test/webrick/test_httprequest.rb417
-rw-r--r--test/webrick/test_httpresponse.rb247
-rw-r--r--test/webrick/test_https.rb112
-rw-r--r--test/webrick/test_httpserver.rb510
-rw-r--r--test/webrick/test_httputils.rb101
-rw-r--r--test/webrick/test_httpversion.rb41
-rw-r--r--test/webrick/test_server.rb162
-rw-r--r--test/webrick/test_ssl_server.rb67
-rw-r--r--test/webrick/test_utils.rb110
-rw-r--r--test/webrick/utils.rb74
-rw-r--r--test/webrick/webrick.cgi38
-rw-r--r--test/webrick/webrick.rhtml4
-rw-r--r--test/webrick/webrick_long_filename.cgi36
-rw-r--r--test/win32ole/err_in_callback.rb10
-rw-r--r--test/win32ole/orig_data.csv5
-rw-r--r--test/win32ole/test_err_in_callback.rb56
-rw-r--r--test/win32ole/test_folderitem2_invokeverb.rb66
-rw-r--r--test/win32ole/test_nil2vtempty.rb37
-rw-r--r--test/win32ole/test_ole_methods.rb35
-rw-r--r--test/win32ole/test_propertyputref.rb31
-rw-r--r--test/win32ole/test_thread.rb34
-rw-r--r--test/win32ole/test_win32ole.rb577
-rw-r--r--test/win32ole/test_win32ole_event.rb401
-rw-r--r--test/win32ole/test_win32ole_method.rb147
-rw-r--r--test/win32ole/test_win32ole_param.rb107
-rw-r--r--test/win32ole/test_win32ole_record.rb213
-rw-r--r--test/win32ole/test_win32ole_type.rb250
-rw-r--r--test/win32ole/test_win32ole_typelib.rb117
-rw-r--r--test/win32ole/test_win32ole_variable.rb62
-rw-r--r--test/win32ole/test_win32ole_variant.rb722
-rw-r--r--test/win32ole/test_win32ole_variant_m.rb36
-rw-r--r--test/win32ole/test_win32ole_variant_outarg.rb69
-rw-r--r--test/win32ole/test_word.rb73
-rw-r--r--test/yaml/test_store.rb180
-rw-r--r--test/zlib/test_zlib.rb1216
-rw-r--r--thread.c5276
-rw-r--r--thread_pthread.c1791
-rw-r--r--thread_pthread.h54
-rw-r--r--thread_sync.c1532
-rw-r--r--thread_win32.c780
-rw-r--r--thread_win32.h36
-rw-r--r--time.c5173
-rw-r--r--timev.h42
-rw-r--r--tool/asm_parse.rb53
-rwxr-xr-xtool/bisect.sh45
-rwxr-xr-xtool/build-transcode16
-rwxr-xr-xtool/change_maker.rb47
-rwxr-xr-xtool/checksum.rb72
-rw-r--r--tool/colorize.rb41
-rw-r--r--tool/downloader.rb331
-rw-r--r--tool/enc-emoji-citrus-gen.rb131
-rw-r--r--tool/enc-emoji4unicode.rb133
-rwxr-xr-xtool/enc-unicode.rb556
-rw-r--r--tool/eval.rb160
-rwxr-xr-xtool/expand-config.rb35
-rwxr-xr-xtool/extlibs.rb186
-rw-r--r--tool/fake.rb70
-rwxr-xr-xtool/fetch-bundled_gems.rb27
-rwxr-xr-xtool/file2lastrev.rb98
-rwxr-xr-xtool/gem-unpack.rb18
-rwxr-xr-xtool/gen_dummy_probes.rb32
-rwxr-xr-xtool/gen_ruby_tapset.rb106
-rw-r--r--tool/generate-backport-changelog.rb99
-rw-r--r--tool/generic_erb.rb58
-rwxr-xr-xtool/git-refresh43
-rw-r--r--tool/gperf.sed22
-rwxr-xr-xtool/id2token.rb27
-rwxr-xr-xtool/ifchange87
-rwxr-xr-xtool/insns2vm.rb18
-rw-r--r--tool/install-sh17
-rwxr-xr-xtool/instruction.rb1249
-rw-r--r--tool/jisx0208.rb86
-rwxr-xr-xtool/make-snapshot467
-rw-r--r--tool/make_hgraph.rb95
-rwxr-xr-xtool/mdoc2man.rb505
-rwxr-xr-xtool/merger.rb312
-rw-r--r--tool/mk_call_iseq_optimized.rb73
-rwxr-xr-xtool/mkconfig.rb325
-rwxr-xr-xtool/mkrunnable.rb137
-rwxr-xr-xtool/node_name.rb10
-rw-r--r--tool/parse.rb16
-rw-r--r--tool/prereq.status43
-rw-r--r--tool/probes_to_wiki.rb16
-rwxr-xr-xtool/pull-latest-mspec-spec18
-rwxr-xr-xtool/rbinstall.rb920
-rwxr-xr-xtool/rbuninstall.rb71
-rwxr-xr-xtool/redmine-backporter.rb608
-rwxr-xr-xtool/release.sh38
-rwxr-xr-xtool/rmdirs14
-rw-r--r--tool/run-gcov.rb54
-rw-r--r--tool/run-lcov.rb164
-rwxr-xr-xtool/runruby.rb159
-rwxr-xr-xtool/strip-rdoc.rb26
-rw-r--r--tool/sync_default_gems.rb198
-rw-r--r--tool/test-coverage.rb103
-rw-r--r--tool/test/test_jisx0208.rb40
-rw-r--r--tool/transcode-tblgen.rb1114
-rwxr-xr-xtool/update-deps625
-rw-r--r--tool/vcs.rb495
-rw-r--r--tool/vpath.rb87
-rw-r--r--tool/vtlh.rb17
-rwxr-xr-xtool/ytab.sed61
-rw-r--r--top.sed58
-rw-r--r--transcode.c4579
-rw-r--r--transcode_data.h139
-rw-r--r--util.c4468
-rw-r--r--util.h18
-rw-r--r--variable.c3295
-rw-r--r--version.c97
-rw-r--r--version.h75
-rw-r--r--vm.c3387
-rw-r--r--vm_args.c884
-rw-r--r--vm_backtrace.c1463
-rw-r--r--vm_core.h1768
-rw-r--r--vm_debug.h37
-rw-r--r--vm_dump.c1090
-rw-r--r--vm_eval.c2202
-rw-r--r--vm_exec.c167
-rw-r--r--vm_exec.h192
-rw-r--r--vm_insnhelper.c3849
-rw-r--r--vm_insnhelper.h255
-rw-r--r--vm_method.c2143
-rw-r--r--vm_opts.h56
-rw-r--r--vm_trace.c1637
-rw-r--r--vsnprintf.c1313
-rw-r--r--win32/Makefile241
-rw-r--r--win32/Makefile.sub1208
-rw-r--r--win32/README.win32141
-rw-r--r--win32/config.h67
-rwxr-xr-xwin32/configure.bat256
-rw-r--r--win32/dir.h45
-rw-r--r--win32/enc-setup.mak10
-rw-r--r--win32/file.c716
-rw-r--r--win32/file.h48
-rwxr-xr-xwin32/ifchange.bat75
-rwxr-xr-xwin32/makedirs.bat3
-rwxr-xr-xwin32/mkexports.rb175
-rwxr-xr-xwin32/ntsetup.bat10
-rwxr-xr-xwin32/resource.rb96
-rwxr-xr-xwin32/rm.bat18
-rwxr-xr-xwin32/rmdirs.bat30
-rw-r--r--win32/rtname.cmd35
-rw-r--r--win32/ruby.def431
-rw-r--r--win32/sdbm.c981
-rw-r--r--win32/sdbm.h84
-rw-r--r--win32/setup.mak242
-rw-r--r--win32/win32.c8084
-rw-r--r--win32/winmain.c10
-rw-r--r--x68/_dtos18.c250
-rw-r--r--x68/_round.c45
-rw-r--r--x68/fconvert.c81
-rw-r--r--x68/select.c167
8312 files changed, 1852196 insertions, 82820 deletions
diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index 2474526e2a..0000000000
--- a/.cvsignore
+++ /dev/null
@@ -1,18 +0,0 @@
-Makefile
-parse.c
-newver.rb
-ruby
-miniruby
-README.fat-patch
-config.cache
-config.h
-config.log
-config.status
-Makefile
-ppack
-archive
-*.orig
-*.rej
-*.bak
-*.sav
-*~
diff --git a/.document b/.document
new file mode 100644
index 0000000000..eeb565b08b
--- /dev/null
+++ b/.document
@@ -0,0 +1,27 @@
+# This file determines which files in the
+# Ruby hierarchy will be processed by the RDoc
+# tool when it is given the top-level directory
+# as an argument
+
+# Process all the C source files
+*.c
+*.y
+
+# prelude
+prelude.rb
+
+rbconfig.rb
+
+# the lib/ directory (which has its own .document file)
+lib
+
+# and some of the ext/ directory (which has its own .document file)
+ext
+
+# rdoc files
+NEWS
+
+README.md
+README.ja.md
+
+doc
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..49cc692091
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,24 @@
+root = true
+
+[*]
+end_of_line = lf
+indent_size = 4
+indent_style = tab
+insert_final_newline = true
+tab_width = 8
+trim_trailing_whitespace = true
+
+[*.bat]
+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
diff --git a/.gdbinit b/.gdbinit
new file mode 100644
index 0000000000..a188ffa172
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,1307 @@
+define hook-run
+ set $color_type = 0
+ set $color_highlite = 0
+ set $color_end = 0
+end
+
+define ruby_gdb_init
+ if !$color_type
+ set $color_type = "\033[31m"
+ end
+ if !$color_highlite
+ set $color_highlite = "\033[36m"
+ end
+ if !$color_end
+ set $color_end = "\033[m"
+ end
+ if ruby_dummy_gdb_enums.special_consts
+ end
+end
+
+# set prompt \033[36m(gdb)\033[m\040
+
+define rp
+ ruby_gdb_init
+ if (VALUE)($arg0) & RUBY_FIXNUM_FLAG
+ printf "FIXNUM: %ld\n", (long)($arg0) >> 1
+ else
+ if ((VALUE)($arg0) & ~(~(VALUE)0<<RUBY_SPECIAL_SHIFT)) == RUBY_SYMBOL_FLAG
+ set $id = (($arg0) >> RUBY_SPECIAL_SHIFT)
+ printf "%sSYMBOL%s: ", $color_type, $color_end
+ rp_id $id
+ else
+ if ($arg0) == RUBY_Qfalse
+ echo false\n
+ else
+ if ($arg0) == RUBY_Qtrue
+ echo true\n
+ else
+ if ($arg0) == RUBY_Qnil
+ echo nil\n
+ else
+ if ($arg0) == RUBY_Qundef
+ echo undef\n
+ else
+ if (VALUE)($arg0) & RUBY_IMMEDIATE_MASK
+ if ((VALUE)($arg0) & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
+ printf "%sFLONUM%s: %g\n", $color_type, $color_end, (double)rb_float_value($arg0)
+ else
+ echo immediate\n
+ end
+ else
+ set $flags = ((struct RBasic*)($arg0))->flags
+ if ($flags & RUBY_FL_PROMOTED) == RUBY_FL_PROMOTED
+ printf "[PROMOTED] "
+ end
+ if ($flags & RUBY_T_MASK) == RUBY_T_NONE
+ printf "%sT_NONE%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_NIL
+ printf "%sT_NIL%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_OBJECT
+ printf "%sT_OBJECT%s: ", $color_type, $color_end
+ print ((struct RObject *)($arg0))->basic
+ if ($flags & ROBJECT_EMBED)
+ print/x *((VALUE*)((struct RObject*)($arg0))->as.ary) @ (ROBJECT_EMBED_LEN_MAX+0)
+ else
+ print (((struct RObject *)($arg0))->as.heap)
+ if (((struct RObject*)($arg0))->as.heap.numiv) > 0
+ print/x *(((struct RObject*)($arg0))->as.heap.ivptr) @ (((struct RObject*)($arg0))->as.heap.numiv)
+ end
+ end
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_CLASS
+ printf "%sT_CLASS%s%s: ", $color_type, ($flags & RUBY_FL_SINGLETON) ? "*" : "", $color_end
+ rp_class $arg0
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_ICLASS
+ printf "%sT_ICLASS%s: ", $color_type, $color_end
+ rp_class $arg0
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_MODULE
+ printf "%sT_MODULE%s: ", $color_type, $color_end
+ rp_class $arg0
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_FLOAT
+ printf "%sT_FLOAT%s: %.16g ", $color_type, $color_end, (((struct RFloat*)($arg0))->float_value)
+ print (struct RFloat *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_STRING
+ printf "%sT_STRING%s: ", $color_type, $color_end
+ rp_string $arg0 $flags
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_REGEXP
+ set $regsrc = ((struct RRegexp*)($arg0))->src
+ set $rsflags = ((struct RBasic*)$regsrc)->flags
+ printf "%sT_REGEXP%s: ", $color_type, $color_end
+ set $len = ($rsflags & RUBY_FL_USER1) ? \
+ ((struct RString*)$regsrc)->as.heap.len : \
+ (($rsflags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
+ set print address off
+ output *(char *)(($rsflags & RUBY_FL_USER1) ? \
+ ((struct RString*)$regsrc)->as.heap.ptr : \
+ ((struct RString*)$regsrc)->as.ary) @ $len
+ set print address on
+ printf " len:%ld ", $len
+ if $flags & RUBY_FL_USER6
+ printf "(none) "
+ end
+ if $flags & RUBY_FL_USER5
+ printf "(literal) "
+ end
+ if $flags & RUBY_FL_USER4
+ printf "(fixed) "
+ end
+ printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
+ print (struct RRegexp *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
+ if ($flags & RUBY_FL_USER1)
+ set $len = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
+ printf "(embed) "
+ if ($len == 0)
+ printf "{(empty)} "
+ else
+ print/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len
+ printf " "
+ end
+ else
+ set $len = ((struct RArray*)($arg0))->as.heap.len
+ 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
+ printf " "
+ else
+ printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
+ end
+ if ($len == 0)
+ printf "{(empty)} "
+ else
+ print/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len
+ printf " "
+ end
+ end
+ print (struct RArray *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_FIXNUM
+ printf "%sT_FIXNUM%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ 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
+ end
+ print (struct RHash *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_STRUCT
+ set $len = (($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
+ ($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) >> (RUBY_FL_USHIFT+1) : \
+ ((struct RStruct *)($arg0))->as.heap.len)
+ printf "%sT_STRUCT%s: len=%ld ", $color_type, $color_end, $len
+ print (struct RStruct *)($arg0)
+ output/x *(($flags & (RUBY_FL_USER1|RUBY_FL_USER2)) ? \
+ ((struct RStruct *)($arg0))->as.ary : \
+ ((struct RStruct *)($arg0))->as.heap.ptr) @ $len
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_BIGNUM
+ rp_bignum $arg0
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_RATIONAL
+ printf "%sT_RATIONAL%s: ", $color_type, $color_end
+ print (struct RRational *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_COMPLEX
+ printf "%sT_COMPLEX%s: ", $color_type, $color_end
+ print (struct RComplex *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_FILE
+ printf "%sT_FILE%s: ", $color_type, $color_end
+ print (struct RFile *)($arg0)
+ output *((struct RFile *)($arg0))->fptr
+ printf "\n"
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_TRUE
+ printf "%sT_TRUE%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_FALSE
+ printf "%sT_FALSE%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_DATA
+ if ((struct RTypedData *)($arg0))->typed_flag == 1
+ printf "%sT_DATA%s(%s): ", $color_type, $color_end, ((struct RTypedData *)($arg0))->type->wrap_struct_name
+ print (struct RTypedData *)($arg0)
+ else
+ printf "%sT_DATA%s: ", $color_type, $color_end
+ print (struct RData *)($arg0)
+ end
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_MATCH
+ printf "%sT_MATCH%s: ", $color_type, $color_end
+ print (struct RMatch *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_SYMBOL
+ printf "%sT_SYMBOL%s: ", $color_type, $color_end
+ print (struct RSymbol *)($arg0)
+ set $id_type = ((struct RSymbol *)($arg0))->id & RUBY_ID_SCOPE_MASK
+ if $id_type == RUBY_ID_LOCAL
+ printf "l"
+ else
+ if $id_type == RUBY_ID_INSTANCE
+ printf "i"
+ else
+ if $id_type == RUBY_ID_GLOBAL
+ printf "G"
+ else
+ if $id_type == RUBY_ID_ATTRSET
+ printf "a"
+ else
+ if $id_type == RUBY_ID_CONST
+ printf "C"
+ else
+ if $id_type == RUBY_ID_CLASS
+ printf "c"
+ else
+ printf "j"
+ end
+ end
+ end
+ end
+ end
+ end
+ set $id_fstr = ((struct RSymbol *)($arg0))->fstr
+ rp_string $id_fstr
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_UNDEF
+ printf "%sT_UNDEF%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ 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)&RUBY_IMEMO_MASK)
+ printf "): "
+ rp_imemo $arg0
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_NODE
+ printf "%sT_NODE%s(", $color_type, $color_end
+ output (enum node_type)(($flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
+ printf "): "
+ print *(NODE *)($arg0)
+ else
+ if ($flags & RUBY_T_MASK) == RUBY_T_ZOMBIE
+ printf "%sT_ZOMBIE%s: ", $color_type, $color_end
+ print (struct RData *)($arg0)
+ else
+ printf "%sunknown%s: ", $color_type, $color_end
+ print (struct RBasic *)($arg0)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+document rp
+ Print a Ruby's VALUE.
+end
+
+define rp_id
+ set $id = (ID)$arg0
+ if $id == '!' || $id == '+' || $id == '-' || $id == '*' || $id == '/' || $id == '%' || $id == '<' || $id == '>' || $id == '`'
+ printf "(:%c)\n", $id
+ else
+ if $id == idDot2
+ printf "(:..)\n"
+ else
+ if $id == idDot3
+ printf "(:...)\n"
+ else
+ if $id == idUPlus
+ printf "(:+@)\n"
+ else
+ if $id == idUMinus
+ printf "(:-@)\n"
+ else
+ if $id == idPow
+ printf "(:**)\n"
+ else
+ if $id == idCmp
+ printf "(:<=>)\n"
+ else
+ if $id == idLTLT
+ printf "(:<<)\n"
+ else
+ if $id == idGTGT
+ printf "(:>>)\n"
+ else
+ if $id == idLE
+ printf "(:<=)\n"
+ else
+ if $id == idGE
+ printf "(:>=)\n"
+ else
+ if $id == idEq
+ printf "(:==)\n"
+ else
+ if $id == idEqq
+ printf "(:===)\n"
+ else
+ if $id == idNeq
+ printf "(:!=)\n"
+ else
+ if $id == idEqTilde
+ printf "(:=~)\n"
+ else
+ if $id == idNeqTilde
+ printf "(:!~)\n"
+ else
+ if $id == idAREF
+ printf "(:[])\n"
+ else
+ if $id == idASET
+ printf "(:[]=)\n"
+ else
+ if $id == idCOLON2
+ printf "(:'::')\n"
+ else
+ if $id == idANDOP
+ printf "(:&&)\n"
+ else
+ if $id == idOROP
+ printf "(:||)\n"
+ else
+ if $id == idANDDOT
+ printf "(:&.)\n"
+ else
+ if $id <= tLAST_OP_ID
+ printf "O"
+ else
+ set $id_type = $id & RUBY_ID_SCOPE_MASK
+ if $id_type == RUBY_ID_LOCAL
+ printf "l"
+ else
+ if $id_type == RUBY_ID_INSTANCE
+ printf "i"
+ else
+ if $id_type == RUBY_ID_GLOBAL
+ printf "G"
+ else
+ if $id_type == RUBY_ID_ATTRSET
+ printf "a"
+ else
+ if $id_type == RUBY_ID_CONST
+ printf "C"
+ else
+ if $id_type == RUBY_ID_CLASS
+ printf "c"
+ else
+ printf "j"
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ printf "(%ld): ", $id
+ print_id $id
+ echo \n
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+document rp_id
+ Print an ID.
+end
+
+define output_string
+ set $flags = ((struct RBasic*)($arg0))->flags
+ set $len = ($flags & RUBY_FL_USER1) ? \
+ ((struct RString*)($arg0))->as.heap.len : \
+ (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
+ if $len > 0
+ output *(char *)(($flags & RUBY_FL_USER1) ? \
+ ((struct RString*)($arg0))->as.heap.ptr : \
+ ((struct RString*)($arg0))->as.ary) @ $len
+ else
+ output ""
+ end
+end
+
+define print_string
+ set $flags = ((struct RBasic*)($arg0))->flags
+ set $len = ($flags & RUBY_FL_USER1) ? \
+ ((struct RString*)($arg0))->as.heap.len : \
+ (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2)
+ if $len > 0
+ printf "%s", *(char *)(($flags & RUBY_FL_USER1) ? \
+ ((struct RString*)($arg0))->as.heap.ptr : \
+ ((struct RString*)($arg0))->as.ary) @ $len
+ end
+end
+
+define rp_string
+ output_string $arg0
+ printf " bytesize:%ld ", $len
+ if !($flags & RUBY_FL_USER1)
+ printf "(embed) "
+ else
+ if ($flags & RUBY_FL_USER2)
+ printf "(shared) "
+ end
+ if ($flags & RUBY_FL_USER3)
+ printf "(assoc) "
+ end
+ end
+ printf "encoding:%d ", ($flags & RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == 0
+ printf "coderange:unknown "
+ else
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_7BIT
+ printf "coderange:7bit "
+ else
+ if ($flags & RUBY_ENC_CODERANGE_MASK) == RUBY_ENC_CODERANGE_VALID
+ printf "coderange:valid "
+ else
+ printf "coderange:broken "
+ end
+ end
+ end
+ print (struct RString *)($arg0)
+end
+document rp_string
+ Print the content of a String.
+end
+
+define rp_bignum
+ set $flags = ((struct RBignum*)($arg0))->basic.flags
+ set $len = (($flags & RUBY_FL_USER2) ? \
+ ($flags & (RUBY_FL_USER5|RUBY_FL_USER4|RUBY_FL_USER3)) >> (RUBY_FL_USHIFT+3) : \
+ ((struct RBignum*)($arg0))->as.heap.len)
+ printf "%sT_BIGNUM%s: sign=%d len=%ld ", $color_type, $color_end, \
+ (($flags & RUBY_FL_USER1) != 0), $len
+ if $flags & RUBY_FL_USER2
+ printf "(embed) "
+ end
+ print (struct RBignum *)($arg0)
+ set $ptr = (($flags & RUBY_FL_USER2) ? \
+ ((struct RBignum*)($arg0))->as.ary : \
+ ((struct RBignum*)($arg0))->as.heap.digits)
+ set $len = $len-1
+ printf "0x%x", $ptr[$len]
+ while $len > 0
+ set $len = $len-1
+ set $val = $ptr[$len]
+ set $w = sizeof($ptr[0])
+ printf "_"
+ if $w > 8
+ printf "%.32x", $val
+ else
+ if $w > 4
+ printf "%.16x", $val
+ else
+ if $w > 2
+ printf "%.8x", $val
+ else
+ if $w > 1
+ printf "%.4x", $val
+ else
+ printf "%.2x", $val
+ end
+ end
+ end
+ end
+ end
+ printf "\n"
+end
+document rp_bignum
+ Print the content of a Bignum.
+end
+
+define rp_class
+ printf "(struct RClass *) %p", (void*)$arg0
+ if ((struct RClass *)($arg0))->ptr.origin_ != $arg0
+ printf " -> %p", ((struct RClass *)($arg0))->ptr.origin_
+ end
+ printf "\n"
+ rb_classname $arg0
+ print/x *(struct RClass *)($arg0)
+ print *((struct RClass *)($arg0))->ptr
+end
+document rp_class
+ Print the content of a Class/Module.
+end
+
+define rp_imemo
+ 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
+ else
+ if $flags == imemo_svar
+ printf "(struct vm_svar *) %p\n", (void*)$arg0
+ print *(struct vm_svar *)$arg0
+ else
+ if $flags == imemo_throw_data
+ printf "(struct vm_throw_data *) %p\n", (void*)$arg0
+ print *(struct vm_throw_data *)$arg0
+ else
+ if $flags == imemo_ifunc
+ printf "(struct vm_ifunc *) %p\n", (void*)$arg0
+ print *(struct vm_ifunc *)$arg0
+ else
+ if $flags == imemo_memo
+ printf "(struct MEMO *) %p\n", (void*)$arg0
+ print *(struct MEMO *)$arg0
+ else
+ if $flags == imemo_ment
+ printf "(rb_method_entry_t *) %p\n", (void*)$arg0
+ print *(rb_method_entry_t *)$arg0
+ else
+ if $flags == imemo_iseq
+ printf "(rb_iseq_t *) %p\n", (void*)$arg0
+ print *(rb_iseq_t *)$arg0
+ else
+ printf "(struct RIMemo *) %p\n", (void*)$arg0
+ print *(struct RIMemo *)$arg0
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+document rp_imemo
+ Print the content of a memo
+end
+
+define nd_type
+ print (enum node_type)((((NODE*)($arg0))->flags&RUBY_NODE_TYPEMASK)>>RUBY_NODE_TYPESHIFT)
+end
+document nd_type
+ Print a Ruby' node type.
+end
+
+define nd_file
+ print ((NODE*)($arg0))->nd_file
+end
+document nd_file
+ Print the source file name of a node.
+end
+
+define nd_line
+ print ((unsigned int)((((NODE*)($arg0))->flags>>RUBY_NODE_LSHIFT)&RUBY_NODE_LMASK))
+end
+document nd_line
+ Print the source line number of a node.
+end
+
+# Print members of ruby node.
+
+define nd_head
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_alen
+ printf "%su2.argc%s: ", $color_highlite, $color_end
+ p ($arg0).u2.argc
+end
+
+define nd_next
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.node
+end
+
+
+define nd_cond
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_body
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+define nd_else
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.node
+end
+
+
+define nd_orig
+ printf "%su3.value%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.value
+end
+
+
+define nd_resq
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+define nd_ensr
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.node
+end
+
+
+define nd_1st
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_2nd
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+
+define nd_stts
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+
+define nd_entry
+ printf "%su3.entry%s: ", $color_highlite, $color_end
+ p ($arg0).u3.entry
+end
+
+define nd_vid
+ printf "%su1.id%s: ", $color_highlite, $color_end
+ p ($arg0).u1.id
+end
+
+define nd_cflag
+ printf "%su2.id%s: ", $color_highlite, $color_end
+ p ($arg0).u2.id
+end
+
+define nd_cval
+ printf "%su3.value%s: ", $color_highlite, $color_end
+ 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
+end
+
+
+define nd_var
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_ibdy
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+define nd_iter
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.node
+end
+
+
+define nd_value
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+define nd_aid
+ printf "%su3.id%s: ", $color_highlite, $color_end
+ p ($arg0).u3.id
+end
+
+
+define nd_lit
+ printf "%su1.value%s: ", $color_highlite, $color_end
+ 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
+end
+
+define nd_opt
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+
+define nd_recv
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_mid
+ printf "%su2.id%s: ", $color_highlite, $color_end
+ p ($arg0).u2.id
+end
+
+define nd_args
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ 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
+end
+
+
+define nd_old
+ printf "%su1.id%s: ", $color_highlite, $color_end
+ p ($arg0).u1.id
+end
+
+define nd_new
+ printf "%su2.id%s: ", $color_highlite, $color_end
+ p ($arg0).u2.id
+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
+end
+
+define nd_super
+ printf "%su3.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u3.node
+end
+
+
+define nd_modl
+ printf "%su1.id%s: ", $color_highlite, $color_end
+ p ($arg0).u1.id
+end
+
+define nd_clss
+ printf "%su1.value%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.value
+end
+
+
+define nd_beg
+ printf "%su1.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u1.node
+end
+
+define nd_end
+ printf "%su2.node%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.node
+end
+
+define nd_state
+ printf "%su3.state%s: ", $color_highlite, $color_end
+ p ($arg0).u3.state
+end
+
+define nd_rval
+ printf "%su2.value%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.value
+end
+
+
+define nd_nth
+ printf "%su2.argc%s: ", $color_highlite, $color_end
+ p ($arg0).u2.argc
+end
+
+
+define nd_tag
+ printf "%su1.id%s: ", $color_highlite, $color_end
+ p ($arg0).u1.id
+end
+
+define nd_tval
+ printf "%su2.value%s: ", $color_highlite, $color_end
+ rp ($arg0).u2.value
+end
+
+define nd_tree
+ set $buf = (struct RString *)rb_str_buf_new(0)
+ call dump_node((VALUE)($buf), rb_str_tmp_new(0), 0, ($arg0))
+ printf "%s\n", $buf->as.heap.ptr
+end
+
+define rb_p
+ call rb_p($arg0)
+end
+
+define rb_numtable_entry
+ set $rb_numtable_tbl = $arg0
+ set $rb_numtable_id = (st_data_t)$arg1
+ set $rb_numtable_key = 0
+ set $rb_numtable_rec = 0
+ if $rb_numtable_tbl->entries_packed
+ set $rb_numtable_p = $rb_numtable_tbl->as.packed.bins
+ while $rb_numtable_p && $rb_numtable_p < $rb_numtable_tbl->as.packed.bins+$rb_numtable_tbl->num_entries
+ if $rb_numtable_p.k == $rb_numtable_id
+ set $rb_numtable_key = $rb_numtable_p.k
+ set $rb_numtable_rec = $rb_numtable_p.v
+ set $rb_numtable_p = 0
+ else
+ set $rb_numtable_p = $rb_numtable_p + 1
+ end
+ end
+ else
+ set $rb_numtable_p = $rb_numtable_tbl->as.big.bins[st_numhash($rb_numtable_id) % $rb_numtable_tbl->num_bins]
+ while $rb_numtable_p
+ if $rb_numtable_p->key == $rb_numtable_id
+ set $rb_numtable_key = $rb_numtable_p->key
+ set $rb_numtable_rec = $rb_numtable_p->record
+ set $rb_numtable_p = 0
+ else
+ set $rb_numtable_p = $rb_numtable_p->next
+ end
+ end
+ end
+end
+
+define rb_id2name
+ ruby_gdb_init
+ printf "%sID%s: ", $color_type, $color_end
+ rp_id $arg0
+end
+document rb_id2name
+ Print the name of id
+end
+
+define rb_method_entry
+ set $rb_method_entry_klass = (struct RClass *)$arg0
+ set $rb_method_entry_id = (ID)$arg1
+ set $rb_method_entry_me = (rb_method_entry_t *)0
+ while !$rb_method_entry_me && $rb_method_entry_klass
+ rb_numtable_entry $rb_method_entry_klass->m_tbl_wrapper->tbl $rb_method_entry_id
+ set $rb_method_entry_me = (rb_method_entry_t *)$rb_numtable_rec
+ if !$rb_method_entry_me
+ set $rb_method_entry_klass = (struct RClass *)RCLASS_SUPER($rb_method_entry_klass)
+ end
+ end
+ if $rb_method_entry_me
+ print *$rb_method_entry_klass
+ print *$rb_method_entry_me
+ else
+ echo method not found\n
+ end
+end
+document rb_method_entry
+ Search method entry by class and id
+end
+
+define rb_classname
+ # up to 128bit int
+ set $rb_classname = rb_mod_name($arg0)
+ if $rb_classname != RUBY_Qnil
+ rp $rb_classname
+ else
+ echo anonymous class/module\n
+ end
+end
+
+define rb_ancestors
+ set $rb_ancestors_module = $arg0
+ while $rb_ancestors_module
+ rp_class $rb_ancestors_module
+ set $rb_ancestors_module = RCLASS_SUPER($rb_ancestors_module)
+ end
+end
+document rb_ancestors
+ Print ancestors.
+end
+
+define rb_backtrace
+ call rb_backtrace()
+end
+
+define iseq
+ if ruby_dummy_gdb_enums.special_consts
+ end
+ if ($arg0)->type == ISEQ_ELEMENT_NONE
+ echo [none]\n
+ end
+ if ($arg0)->type == ISEQ_ELEMENT_LABEL
+ print *(LABEL*)($arg0)
+ end
+ if ($arg0)->type == ISEQ_ELEMENT_INSN
+ print *(INSN*)($arg0)
+ if ((INSN*)($arg0))->insn_id != YARVINSN_jump
+ set $i = 0
+ set $operand_size = ((INSN*)($arg0))->operand_size
+ set $operands = ((INSN*)($arg0))->operands
+ while $i < $operand_size
+ rp $operands[$i++]
+ end
+ end
+ end
+ if ($arg0)->type == ISEQ_ELEMENT_ADJUST
+ print *(ADJUST*)($arg0)
+ end
+end
+
+define rb_ps
+ rb_ps_vm ruby_current_vm_ptr
+end
+document rb_ps
+Dump all threads and their callstacks
+end
+
+define rb_ps_vm
+ print $ps_vm = (rb_vm_t*)$arg0
+ set $ps_thread_ln = $ps_vm->living_threads.n.next
+ set $ps_thread_ln_last = $ps_vm->living_threads.n.prev
+ while 1
+ set $ps_thread_th = (rb_thread_t *)$ps_thread_ln
+ set $ps_thread = (VALUE)($ps_thread_th->self)
+ rb_ps_thread $ps_thread
+ if $ps_thread_ln == $ps_thread_ln_last
+ loop_break
+ end
+ set $ps_thread_ln = $ps_thread_ln->next
+ end
+end
+document rb_ps_vm
+Dump all threads in a (rb_vm_t*) and their callstacks
+end
+
+define print_lineno
+ set $cfp = $arg0
+ set $iseq = $cfp->iseq
+ set $pos = $cfp->pc - $iseq->body->iseq_encoded
+ if $pos != 0
+ set $pos = $pos - 1
+ end
+
+ set $i = 0
+ set $size = $iseq->body->insns_info_size
+ set $table = $iseq->body->insns_info
+ #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
+ end
+ set $i = $i + 1
+ if $table[$i].position == $pos
+ loop_break
+ end
+ end
+ printf "%d", $table[$i-1].line_no
+ end
+end
+
+define check_method_entry
+ set $imemo = (struct RBasic *)$arg0
+ if $imemo != RUBY_Qfalse
+ set $type = ($imemo->flags >> 12) & 0x07
+ if $type == imemo_ment
+ set $me = (rb_callable_method_entry_t *)$imemo
+ else
+ if $type == imemo_svar
+ set $imemo = ((struct vm_svar *)$imemo)->cref_or_me
+ check_method_entry $imemo
+ end
+ end
+ end
+end
+
+define print_id
+ set $id = $arg0
+ # rb_id_to_serial
+ if $id > tLAST_OP_ID
+ set $serial = (rb_id_serial_t)($id >> RUBY_ID_SCOPE_SHIFT)
+ else
+ set $serial = (rb_id_serial_t)$id
+ end
+ if $serial && $serial <= global_symbols.last_id
+ set $idx = $serial / ID_ENTRY_UNIT
+ set $ids = (struct RArray *)global_symbols.ids
+ set $flags = $ids->basic.flags
+ if ($flags & RUBY_FL_USER1)
+ set $idsptr = $ids->as.ary
+ set $idslen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ else
+ set $idsptr = $ids->as.heap.ptr
+ set $idslen = $ids->as.heap.len
+ end
+ if $idx < $idslen
+ set $t = 0
+ set $ary = (struct RArray *)$idsptr[$idx]
+ if $ary != RUBY_Qnil
+ set $flags = $ary->basic.flags
+ if ($flags & RUBY_FL_USER1)
+ set $aryptr = $ary->as.ary
+ set $arylen = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
+ else
+ set $aryptr = $ary->as.heap.ptr
+ set $arylen = $ary->as.heap.len
+ end
+ set $result = $aryptr[($serial % ID_ENTRY_UNIT) * ID_ENTRY_SIZE + $t]
+ if $result != RUBY_Qnil
+ print_string $result
+ else
+ echo undef
+ end
+ end
+ end
+ end
+end
+
+define print_pathobj
+ set $flags = ((struct RBasic*)($arg0))->flags
+ if ($flags & RUBY_T_MASK) == RUBY_T_STRING
+ print_string $arg0
+ end
+ if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
+ if $flags & RUBY_FL_USER1
+ set $str = ((struct RArray*)($arg0))->as.ary[0]
+ else
+ set $str = ((struct RArray*)($arg0))->as.heap.ptr[0]
+ end
+ print_string $str
+ end
+end
+
+define rb_ps_thread
+ set $ps_thread = (struct RTypedData*)$arg0
+ 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
+ while $cfp < $cfpend
+ if $cfp->iseq
+ 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
+ set print symbol-filename off
+ printf "\n"
+ else
+ if $cfp->pc
+ set $location = $cfp->iseq->body->location
+ printf "%d:", $cfpend-$cfp
+ print_pathobj $location.pathobj
+ printf ":"
+ print_lineno $cfp
+ printf ":in `"
+ print_string $location.label
+ printf "'\n"
+ else
+ printf "%d: ???.rb:???:in `???'\n", $cfpend-$cfp
+ end
+ end
+ else
+ # if VM_FRAME_TYPE($cfp->flag) == VM_FRAME_MAGIC_CFUNC
+ set $ep = $cfp->ep
+ if ($ep[0] & 0xffff0001) == 0x55550001
+ #define VM_ENV_FLAG_LOCAL 0x02
+ #define VM_ENV_PREV_EP(ep) GC_GUARDED_PTR_REF(ep[VM_ENV_DATA_INDEX_SPECVAL])
+ set $me = 0
+ set $env_specval = $ep[-1]
+ set $env_me_cref = $ep[-2]
+ while ($env_specval & 0x02) != 0
+ check_method_entry $env_me_cref
+ if $me != 0
+ loop_break
+ end
+ set $ep = $ep[0]
+ set $env_specval = $ep[-1]
+ set $env_me_cref = $ep[-2]
+ end
+ if $me == 0
+ check_method_entry $env_me_cref
+ end
+ printf "%d:", $cfpend-$cfp
+ set print symbol-filename on
+ output/a $me->def->body.cfunc.func
+ set print symbol-filename off
+ set $mid = $me->def->original_id
+ printf ":in `"
+ print_id $mid
+ printf "'\n"
+ else
+ printf "%d:unknown_frame:???:in `???'\n", $cfpend-$cfp
+ end
+ end
+ set $cfp = $cfp + 1
+ end
+end
+
+define rb_count_objects
+ set $objspace = ruby_current_vm_ptr->objspace
+ set $counts_00 = 0
+ set $counts_01 = 0
+ set $counts_02 = 0
+ set $counts_03 = 0
+ set $counts_04 = 0
+ set $counts_05 = 0
+ set $counts_06 = 0
+ set $counts_07 = 0
+ set $counts_08 = 0
+ set $counts_09 = 0
+ set $counts_0a = 0
+ set $counts_0b = 0
+ set $counts_0c = 0
+ set $counts_0d = 0
+ set $counts_0e = 0
+ set $counts_0f = 0
+ set $counts_10 = 0
+ set $counts_11 = 0
+ set $counts_12 = 0
+ set $counts_13 = 0
+ set $counts_14 = 0
+ set $counts_15 = 0
+ set $counts_16 = 0
+ set $counts_17 = 0
+ set $counts_18 = 0
+ set $counts_19 = 0
+ set $counts_1a = 0
+ set $counts_1b = 0
+ set $counts_1c = 0
+ set $counts_1d = 0
+ set $counts_1e = 0
+ set $counts_1f = 0
+ set $total = 0
+ set $i = 0
+ while $i < $objspace->heap_pages.allocated_pages
+ printf "\rcounting... %d/%d", $i, $objspace->heap_pages.allocated_pages
+ set $page = $objspace->heap_pages.sorted[$i]
+ set $p = $page->start
+ set $pend = $p + $page->total_slots
+ while $p < $pend
+ set $flags = $p->as.basic.flags & 0x1f
+ eval "set $counts_%02x = $counts_%02x + 1", $flags, $flags
+ set $p = $p + 1
+ end
+ set $total = $total + $page->total_slots
+ set $i = $i + 1
+ end
+ printf "\rTOTAL: %d, FREE: %d\n", $total, $counts_00
+ printf "T_OBJECT: %d\n", $counts_01
+ printf "T_CLASS: %d\n", $counts_02
+ printf "T_MODULE: %d\n", $counts_03
+ printf "T_FLOAT: %d\n", $counts_04
+ printf "T_STRING: %d\n", $counts_05
+ printf "T_REGEXP: %d\n", $counts_06
+ printf "T_ARRAY: %d\n", $counts_07
+ printf "T_HASH: %d\n", $counts_08
+ printf "T_STRUCT: %d\n", $counts_09
+ printf "T_BIGNUM: %d\n", $counts_0a
+ printf "T_FILE: %d\n", $counts_0b
+ printf "T_DATA: %d\n", $counts_0c
+ printf "T_MATCH: %d\n", $counts_0d
+ printf "T_COMPLEX: %d\n", $counts_0e
+ printf "T_RATIONAL: %d\n", $counts_0f
+ #printf "UNKNOWN_10: %d\n", $counts_10
+ printf "T_NIL: %d\n", $counts_11
+ printf "T_TRUE: %d\n", $counts_12
+ printf "T_FALSE: %d\n", $counts_13
+ printf "T_SYMBOL: %d\n", $counts_14
+ printf "T_FIXNUM: %d\n", $counts_15
+ printf "T_UNDEF: %d\n", $counts_16
+ #printf "UNKNOWN_17: %d\n", $counts_17
+ #printf "UNKNOWN_18: %d\n", $counts_18
+ #printf "UNKNOWN_19: %d\n", $counts_19
+ printf "T_IMEMO: %d\n", $counts_1a
+ printf "T_NODE: %d\n", $counts_1b
+ printf "T_ICLASS: %d\n", $counts_1c
+ printf "T_ZOMBIE: %d\n", $counts_1d
+ #printf "UNKNOWN_1E: %d\n", $counts_1e
+ printf "T_MASK: %d\n", $counts_1f
+end
+document rb_count_objects
+ Counts all objects grouped by type.
+end
+
+# Details: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/MachineInstructionsTraceWithGDB
+define trace_machine_instructions
+ set logging on
+ set height 0
+ set width 0
+ display/i $pc
+ while !$exit_code
+ info line *$pc
+ si
+ end
+end
+
+define SDR
+ call rb_vmdebug_stack_dump_raw_current()
+end
+
+define rbi
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_LABEL
+ p *(LABEL*)$arg0
+ else
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_INSN
+ p *(INSN*)$arg0
+ else
+ if ((LINK_ELEMENT*)$arg0)->type == ISEQ_ELEMENT_ADJUST
+ p *(ADJUST*)$arg0
+ else
+ print *$arg0
+ end
+ end
+ end
+end
+
+define dump_node
+ set $str = rb_parser_dump_tree($arg0, 0)
+ set $flags = ((struct RBasic*)($str))->flags
+ printf "%s", (char *)(($flags & RUBY_FL_USER1) ? \
+ ((struct RString*)$str)->as.heap.ptr : \
+ ((struct RString*)$str)->as.ary)
+end
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..6ca2f89462
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+*.gemspec diff=ruby
+*.rb diff=ruby
+bin svn-properties=svn:ignore=ruby
+bin/* diff=ruby
+tool/update-deps diff=ruby
+tool/make-snapshot diff=ruby
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..efc7fd5864
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,197 @@
+*-*-*.def
+*-*-*.exp
+*-*-*.lib
+*.a
+*.bak
+*.bc
+*.dSYM
+*.dmyh
+*.dylib
+*.elc
+*.i
+*.inc
+*.log
+*.o
+*.obj
+*.old
+*.orig
+*.pdb
+*.rej
+*.s
+*.sav
+*.swp
+*.yarb
+*~
+.*-*
+.*.list
+.*.time
+.DS_Store
+.bundle
+.ccmalloc
+.ext
+.pc
+.ppack
+.svn
+Makefile
+cygruby*.def
+extconf.h
+y.output
+y.tab.c
+*.gcda
+*.gcno
+*.gcov
+lcov*.info
+
+# /
+/*-fake.rb
+/*.dll
+/*.exe
+/*.res
+/*.pc
+/*.rc
+/*_prelude.c
+/COPYING.LIB
+/Doxyfile
+/GNUmakefile
+/README.atheos
+/README.fat-patch
+/README.v6
+/TAGS
+/archive
+/autom4te*.cache
+/automake
+/beos
+/bmlog-*
+/breakpoints.gdb
+/config.cache
+/config.h
+/config.h.in
+/config.status
+/config.status.lineno
+/configure
+/coverage/simplecov
+/coverage/simplecov-html
+/coverage/doclie
+/coverage/.last_run.json
+/coverage/.resultset.json*
+/coverage/assets
+/coverage/index.html
+/doc/capi
+/enc.mk
+/encdb.h
+/exts.mk
+/goruby
+/id.[ch]
+/largefile.h
+/lcov-c-out
+/lcov-rb-out
+/lcov-out
+/lex.c
+/libruby*.*
+/miniprelude.c
+/miniruby
+/newdate.rb
+/newline.c
+/newver.rb
+/parse.c
+/parse.h
+/patches
+/patches-master
+/pitest.rb
+/ppack
+/prelude.c
+/preview
+/probes.dmyh
+/probes.h
+/rbconfig.rb
+/rename2.h
+/repack
+/revision.h
+/riscos
+/rubicon
+/ruby
+/ruby-runner
+/ruby-runner.h
+/ruby-man.rd.gz
+/run.gdb
+/sizes.c
+/test.rb
+/test-coverage.dat
+/tmp
+/transdb.h
+/uncommon.mk
+/verconf.h
+/verconf.mk
+/web
+/yasmdata.rb
+
+# /benchmark/
+/benchmark/bm_require.data
+/benchmark/bmx_*.rb
+/benchmark/fasta.output.*
+/benchmark/wc.input
+
+/enc/*.def
+/enc/*.exp
+/enc/*.lib
+/enc/jis/props.h
+/enc/unicode/data
+
+# /enc/trans/
+/enc/trans/*.c
+/enc/trans/*.def
+/enc/trans/*.exp
+/enc/trans/*.lib
+/enc/trans/.time
+
+# /exe/
+/exe/ruby
+/exe/.time
+
+# /ext/
+/ext/extinit.c
+/ext/configure-ext.mk
+/ext/*/exts.mk
+
+# /ext/-test-/win32/dln/
+/ext/-test-/win32/dln/dlntest.dll
+/ext/-test-/win32/dln/dlntest.exp
+/ext/-test-/win32/dln/dlntest.lib
+
+# /ext/etc/
+/ext/etc/constdefs.h
+
+# /ext/fiddle/
+/ext/fiddle/libffi-*
+
+# /ext/rbconfig/
+/ext/rbconfig/sizeof/sizes.c
+/ext/rbconfig/sizeof/limits.c
+
+# /ext/ripper/
+/ext/ripper/eventids1.c
+/ext/ripper/eventids2table.c
+/ext/ripper/ripper.*
+/ext/ripper/ids1
+/ext/ripper/ids2
+
+# /ext/socket/
+/ext/socket/constants.h
+/ext/socket/constdefs.h
+/ext/socket/constdefs.c
+
+# /gems
+/gems/*.gem
+/gems/src
+/gems/*-*
+
+# /spec/bundler
+/.rspec_status
+
+# /tool/
+/tool/config.guess
+/tool/config.sub
+
+# /win32/
+/win32/*.ico
+/win32/.time
diff --git a/.indent.pro b/.indent.pro
new file mode 100644
index 0000000000..6a207a0554
--- /dev/null
+++ b/.indent.pro
@@ -0,0 +1,21 @@
+-bap
+-nbbb
+-nbc
+-br
+-nbs
+-ncdb
+-ce
+-cli0.5
+-ndj
+-ei
+-nfc1
+-i4
+-l120
+-lp
+-npcs
+-psl
+-sc
+-sob
+
+-TID
+-TVALUE
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..a9117d190f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,109 @@
+# Copyright (C) 2011 Urabe, Shyouhei. All rights reserved.
+#
+# This file is a part of the programming language Ruby. Permission is hereby
+# granted, to either redistribute or modify this file, provided that the
+# conditions mentioned in the file COPYING are met. Consult the file for
+# details.
+
+# This is a Travis-CI build configuration file. The list of configurations
+# available is located in
+#
+# http://about.travis-ci.org/docs/user/build-configuration/
+#
+# and as Ruby itself is a project written in C language,
+#
+# http://about.travis-ci.org/docs/user/languages/c/
+#
+# is also a good place to look at.
+
+language: c
+dist: trusty
+
+# temporary workaround for https://github.com/travis-ci/travis-ci/issues/8892
+sudo: required
+group: deprecated-2017Q4
+
+compiler:
+ - gcc
+
+os:
+ - linux
+
+before_install:
+ - "CONFIG_FLAG="
+ - "JOBS=-j`nproc`"
+
+before_script:
+ - "echo JOBS=$JOBS"
+ - "uname -a"
+ - "uname -r"
+ - "rm -fr .ext autom4te.cache"
+ - "echo $TERM"
+ - "> 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"
+
+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"
+
+# Branch matrix. Not all branches are Travis-ready so we limit branches here.
+branches:
+ only:
+ - trunk
+ - ruby_2_2
+ - ruby_2_3
+ - ruby_2_4
+ - ruby_2_5
+ - /^feature\//
+ - /^bug\//
+
+# 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:
+ rooms:
+ - secure: i1GLETSKye85ea6dGNA3MxI/5myChmMFiZtBd5C69xK+s1sBFqEgOSbaSf9KHc0CYrHVyNhQMaZRruieV7xS+6Pfs0Zvxf1DO6QQTWC2KhkqwFDLvZncAzjoyASdR90hbr+iRPOngQ+HJuE94zemALAwEqNAinzA74PMiJXktqY= # ruby:<token>#commits
+ - secure: ah7UEHBvncXT7bM5mvYIQAO+tIyV/wl7nXLb7wQD16dO2v8Gragy0mWjB79Q09hrrMGmp6H9bCDpdGS80boIA5EHaHoG4QaP0i9bsSt8U2AMWgZtfyIgQKJ4H2kXkGlrjO+AXTgnIkP7LNjdgAVUUTGQPb26T3QmoN2Splt+fIQ= # ruby:<token>#alerts
+ on_pull_requests: false
+ on_success: change
+ 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
new file mode 100644
index 0000000000..a009caefea
--- /dev/null
+++ b/BSDL
@@ -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/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..ffdf2dd4b8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,4 @@
+Please see the [official issue tracker] and wiki [HowToContribute].
+
+[official issue tracker]: https://bugs.ruby-lang.org
+[HowToContribute]: https://bugs.ruby-lang.org/projects/ruby/wiki/HowToContribute
diff --git a/COPYING b/COPYING
index eeb586b392..f06056fb45 100644
--- a/COPYING
+++ b/COPYING
@@ -1,340 +1,56 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+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:
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+ 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.
- Preamble
+ 2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
+ 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.
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
+ b) use the modified software only within your corporation or
+ organization.
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
+ c) give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
+ d) make other distribution arrangements with the author.
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
+ 3. You may distribute the software in object code or binary form,
+ provided that you do at least ONE of the following:
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
+ 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.
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
+ b) accompany the distribution with the machine-readable source of
+ the software.
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ c) give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
+ d) make other distribution arrangements with the author.
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
+ 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.
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
+ For the list of those files and their copying conditions, see the
+ file LEGAL.
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
+ 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.
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- 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 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+ 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
new file mode 100644
index 0000000000..e50d01c8d1
--- /dev/null
+++ b/COPYING.ja
@@ -0,0 +1,51 @@
+本プログラムã¯ãƒ•リーソフトウェアã§ã™ï¼Ž2-clause BSDL
+ã¾ãŸã¯ä»¥ä¸‹ã«ç¤ºã™æ¡ä»¶ã§æœ¬ãƒ—ログラムをå†é…布ã§ãã¾ã™
+2-clause BSDLã«ã¤ã„ã¦ã¯BSDLファイルをå‚ç…§ã—ã¦ä¸‹ã•ã„.
+
+ 1. 複製ã¯åˆ¶é™ãªã自由ã§ã™ï¼Ž
+
+ 2. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムã®ã‚½ãƒ¼ã‚¹ã‚’
+ 自由ã«å¤‰æ›´ã§ãã¾ã™ï¼Ž
+
+ (a) ãƒãƒƒãƒˆãƒ‹ãƒ¥ãƒ¼ã‚ºã«ãƒã‚¹ãƒˆã—ãŸã‚Šï¼Œä½œè€…ã«å¤‰æ›´ã‚’é€ä»˜ã™ã‚‹
+ ãªã©ã®æ–¹æ³•ã§ï¼Œå¤‰æ›´ã‚’公開ã™ã‚‹ï¼Ž
+
+ (b) 変更ã—ãŸæœ¬ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã‚’è‡ªåˆ†ã®æ‰€å±žã™ã‚‹çµ„織内部ã ã‘ã§
+ 使ã†ï¼Ž
+
+ (c) 変更点を明示ã—ãŸã†ãˆï¼Œã‚½ãƒ•トウェアã®åå‰ã‚’変更ã™ã‚‹ï¼Ž
+ ãã®ã‚½ãƒ•トウェアをé…布ã™ã‚‹æ™‚ã«ã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラ
+ ãƒ ã‚‚åŒæ™‚ã«é…布ã™ã‚‹ï¼Žã¾ãŸã¯å¤‰æ›´å‰ã®æœ¬ãƒ—ログラムã®ã‚½ãƒ¼
+ スã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+
+ (d) ãã®ä»–ã®å¤‰æ›´æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
+
+ 3. ä»¥ä¸‹ã®æ¡ä»¶ã®ã„ãšã‚Œã‹ã‚’満ãŸã™æ™‚ã«æœ¬ãƒ—ログラムをコンパイ
+ ルã—ãŸã‚ªãƒ–ジェクトコードや実行形å¼ã§ã‚‚é…布ã§ãã¾ã™ï¼Ž
+
+ (a) ãƒã‚¤ãƒŠãƒªã‚’å—ã‘å–ã£ãŸäººãŒã‚½ãƒ¼ã‚¹ã‚’入手ã§ãるよã†ã«ï¼Œ
+ ソースã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+
+ (b) 機械å¯èª­ãªã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’添付ã™ã‚‹ï¼Ž
+
+ (c) 変更を行ã£ãŸãƒã‚¤ãƒŠãƒªã¯åå‰ã‚’変更ã—ãŸã†ãˆï¼Œã‚ªãƒªã‚¸ãƒŠ
+ ルã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®å…¥æ‰‹æ³•を明示ã™ã‚‹ï¼Ž
+
+ (d) ãã®ä»–ã®é…布æ¡ä»¶ã‚’作者ã¨åˆæ„ã™ã‚‹ï¼Ž
+
+ 4. ä»–ã®ãƒ—ログラムã¸ã®å¼•用ã¯ã„ã‹ãªã‚‹ç›®çš„ã§ã‚れ自由ã§ã™ï¼ŽãŸ
+ ã ã—,本プログラムã«å«ã¾ã‚Œã‚‹ä»–ã®ä½œè€…ã«ã‚ˆã‚‹ã‚³ãƒ¼ãƒ‰ã¯ï¼Œã
+ れãžã‚Œã®ä½œè€…ã®æ„å‘ã«ã‚ˆã‚‹åˆ¶é™ãŒåŠ ãˆã‚‰ã‚Œã‚‹å ´åˆãŒã‚りã¾ã™ï¼Ž
+
+ ãれらファイルã®ä¸€è¦§ã¨ãれãžã‚Œã®é…布æ¡ä»¶ãªã©ã«ä»˜ã„ã¦ã¯
+ LEGALファイルをå‚ç…§ã—ã¦ãã ã•ã„.
+
+ 5. 本プログラムã¸ã®å…¥åŠ›ã¨ãªã‚‹ã‚¹ã‚¯ãƒªãƒ—トãŠã‚ˆã³ï¼Œæœ¬ãƒ—ログラ
+ ムã‹ã‚‰ã®å‡ºåŠ›ã®æ¨©åˆ©ã¯æœ¬ãƒ—ログラムã®ä½œè€…ã§ã¯ãªã,ãれãž
+ れã®å…¥å‡ºåŠ›ã‚’ç”Ÿæˆã—ãŸäººã«å±žã—ã¾ã™ï¼Žã¾ãŸï¼Œæœ¬ãƒ—ログラムã«
+ 組ã¿è¾¼ã¾ã‚Œã‚‹ãŸã‚ã®æ‹¡å¼µãƒ©ã‚¤ãƒ–ラリã«ã¤ã„ã¦ã‚‚åŒæ§˜ã§ã™ï¼Ž
+
+ 6. 本プログラムã¯ç„¡ä¿è¨¼ã§ã™ï¼Žä½œè€…ã¯æœ¬ãƒ—ログラムをサãƒãƒ¼ãƒˆ
+ ã™ã‚‹æ„å¿—ã¯ã‚りã¾ã™ãŒï¼Œãƒ—ログラム自身ã®ãƒã‚°ã‚ã‚‹ã„ã¯æœ¬ãƒ—
+ ログラムã®å®Ÿè¡Œãªã©ã‹ã‚‰ç™ºç”Ÿã™ã‚‹ã„ã‹ãªã‚‹æå®³ã«å¯¾ã—ã¦ã‚‚責
+ 任をæŒã¡ã¾ã›ã‚“.
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 14bc362df3..0000000000
--- a/ChangeLog
+++ /dev/null
@@ -1,2632 +0,0 @@
-Mon Nov 9 17:55:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c7 released.
-
-Fri Nov 6 19:25:27 1998 Takao KAWAMURA <kawamura@ike.tottori-u.ac.jp>
-
- * sample/ruby-mode.el: font-lock patch.
-
-Thu Nov 5 15:42:22 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/README, lib/README: simple description for each file.
-
-Wed Nov 4 18:14:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (assign): attribute assignment should be called as public.
-
-Mon Nov 2 18:24:33 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_create): was accessing modified status.
-
-Sun Nov 1 01:18:52 1998 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
-
- * gc.c (xrealloc): size 0 needs round up to 1.
-
-Sat Oct 31 23:18:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (rb_str_split_method): negative LIMIT means number of
- splitted fields are unlimited, as in perl.
-
- * string.c (rb_str_split_method): if LIMIT is unspecified,
- trailing null fields are stripped.
-
-Sat Oct 31 04:16:14 1998 Inaba Hiroto <inaba@st.rim.or.jp>
-
- * string.c (str_aref): regexp index SEGVed.
-
-Fri Oct 30 14:33:47 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_match): returns nil for unmatch.
-
- * dir.c (dir_entries): new method.
-
- * eval.c (block_pass): do not push block, substitute it.
-
-Wed Oct 28 11:37:42 1998 TAMITO <tommy@valley.ne.jp>
-
- * io.c (f_select): fd number comparison bug.
-
-Sun Oct 25 22:59:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (set_list_bits): was using wrong offset.
-
-Mon Oct 19 11:50:00 1998 Motoyuki Kasahara <m-kasahr@sra.co.jp>
-
- * ext/extmk.rb: Load '@top_srcdir@/lib/find.rb', not
- '../lib/find.rb'.
- * ext/extmk.rb: Distinguish between `top_srcdir' and `topdir'.
- * Makefile.in (CFLAGS): Add `-I.'.
- * Makefile.in (lex.c): Give `@srcdir@/keywords' to gperf, not
- `keywords'.
- * instruby.rb: Use `CONFIG["bindir"]', instead of `prefix + "/bin"'.
- * instruby.rb: Use `CONFIG["libdir"]', instead of `prefix + "/lib"'.
- * instruby.rb Use `CONFIG["mandir"]', instead of `prefix + "/man"'.
- * instruby.rb (wdir): Add the variable to preserve the current
- working directory.
- * instruby.rb: Chdir to wdir before install `config.h' and
- `rbconfig.rb'.
-
-Mon Oct 19 10:07:01 1998 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
-
- * eval.c (rb_eval): reduce recursive calls to rb_eval().
-
-Thu Oct 15 13:54:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (arg): local variabls can be accessed within right side
- expression in assignment, notably in blocks.
-
-Mon Oct 12 13:27:15 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_call0): check stack depth more frequently.
-
-Fri Oct 9 17:01:14 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (read_all): read() returns "" at immediate EOF.
-
- * io.c (io_read): read(nil) read all until EOF.
-
-Thu Oct 8 13:32:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c (time_dump): marshal can dump Time object now.
-
- * marshal.c (Init_marshal): rename marshal methods `_dump_to' to
- `_dump', `_load_from' to `_load'.
-
- * parse.y (rb_intern): "+=".intern generates proper symbol.
-
-Mon Oct 5 18:31:53 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c6 released.
-
-Fri Oct 2 14:22:33 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_search): `/\s*(--)$/ =~ "- --"' did not match,
- because of wrong optimize condition.
-
-Mon Oct 1 01:55:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (rb_intern): should not raise exceptions.
-
- * parse.y (yylex): symbol like `:foo?=' should not be allowed.
-
- * ext/extmk.rb.in: makes *.a for static link modules.
-
-Fri Sep 25 12:01:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): `@foo!' should be an error.
-
-Thu Sep 24 14:55:06 1998 WATANABE Tetsuya <tetsu@jpn.hp.com>
-
- * ext/etc/etc.c (Init_etc): wrong field definition.
-
-Thu Sep 17 17:09:05 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_reopen): was creating FILE* for wrong fd.
-
-Tue Sep 15 05:28:11 1998 Koji Arai <JCA02266@nifty.ne.jp>
-
- * regex.c (re_compile_pattern): forgot to fixup for the pattern
- like (?=(A)|(B)).
-
-Mon Sep 14 14:42:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_match): beginning and end of the string, do not
- automatically match `\b'.
-
- * string.c (scan_once): comsume at leaset on character.
-
- * regex.c (re_search): wrong behavior for negative range.
-
-Sat Sep 12 21:21:26 1998 Koji Arai <JCA02266@nifty.ne.jp>
-
- * regex.c (re_search): range value should be maintained.
-
-Thu Sep 10 10:55:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (backref_error): yyerror does not understand formats.
-
-Tue Sep 8 18:05:33 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c5 released.
-
-Tue Sep 8 10:03:39 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_each_line): wrong line splitting with newline at
- top of the string.
-
- * string.c: non bang methods return copied string.
-
- * eval.c (f_END): needed to initialize frame->argc;
-
-Fri Sep 4 11:27:40 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (bigadd): proper sign combination.
-
- * regex.c (re_search): wrong return value for \A.
-
-Thu Sep 3 14:08:14 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c4 released.
-
-Tue Sep 1 10:47:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (slow_search): do not compare llen and blen. llen may
- be longer than blen, if little contains 0xff.
-
- * regex.c (mbctab_euc): set 0x8e as multibyte character.
-
- * string.c (str_inspect): mask character for octal output.
-
-Mon Aug 31 15:32:41 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_search): use calculated offset if exactn is the
- first opcode in the compiled regexp.
-
- * regex.c (bm_search): use Boyer-Moore search for simple search.
-
- * regex.c (must_instr): wrong length check if pattern includes
- byte escape by 0xff.
-
- * regex.c (re_compile_pattern): need not to check current_mbctype.
-
-Sat Aug 29 16:31:40 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_check_safe_str): avoid calling rb_id2name() in normal
- cases to speed-up.
-
- * eval.c (thread_raise): do not save context of terminated thread.
-
- * regex.c (re_compile_pattern): mask \nnn over 256.
-
-Sat Aug 29 02:09:46 1998 1998 Koji Arai <JCA02266@nifty.ne.jp>
-
- * sprintf.c (f_sprintf): wrong buffer size check.
-
-Fri Aug 28 01:57:04 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): accepts (?ix-ix) and (?ix-ix:...).
-
-Fri Aug 28 12:25:33 1998 Hiroshi Igarashi <igarashi@ueda.info.waseda.ac.jp>
-
- * ruby.c (ruby_require_modules): load modules in appearing order.
-
-Thu Aug 27 12:54:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c3 released.
-
-Wed Aug 26 11:47:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_match): pop non-greedy stack elements on success.
-
-Wed Aug 26 09:25:35 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ruby.h: add #define environ for cygwin32.
-
-Mon Aug 24 18:46:44 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * dln.c (dln_find_1): path check was too strict.
-
-Mon Aug 24 15:28:11 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (f_arglist): opt_nl added after f_args.
-
-Wed Aug 19 00:31:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_ctl): forgot to place TRAP_END at right position.
-
-Fri Aug 14 11:01:47 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (call_trace_func): save __FILE__, __LINE__ before
- executing trace_func, since trace function should not corrupt
- line number information.
-
-Thu Aug 13 15:09:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_s_new): was marking unallocated region on GC.
-
-Tue Aug 11 11:57:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c2 released.
-
-Mon Aug 10 14:05:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * process.c (f_system): removed fflush(stdin).
-
-Fri Aug 7 17:44:44 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * error.c (err_snprintf): replace sprintf for fixed sized buffer,
- with snprintf to avoid buffer over-run. For systems which does
- dot provide snprintf, missing/snprintf.c added.
-
-Tue Jul 28 13:03:25 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_s_new): argument to specify initial value is added.
-
- * array.c (ary_s_new): specifies size, not capacity.
-
-Mon Jul 27 12:39:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_replace): zero fill for expansion gap.
-
- * regex.c (mbctab_euc): set flags on for 0xA1-0xFE. suggested by
- <inaba@st.rim.or.jp>.
-
- * string.c (str_inspect): consider current_mbctype.
-
-Sun Jul 26 15:37:11 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * array.c (ary_s_new): Array.new(1<<30) dumps core.
-
-Fri Jul 24 13:40:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c1 released.
-
-Fri Jul 24 02:10:22 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * marshal.c (r_bytes2): allocated buffer size was too short.
-
- * marshal.c (w_object): saves all options, not only casefold flag.
-
- * re.c (reg_clone): now copies options properly.
-
- * re.c (reg_get_kcode): code number was wrong.
-
-Thu Jul 23 13:11:32 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_attr): argument should be symbol or string.
-
-Wed Jul 22 11:59:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (calculate_must_string): wrong offset added.
-
-Wed Jul 22 11:59:59 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * st.c (rehash): still had a GC problem. fixed.
-
-Tue Jul 21 13:19:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (gc_mark_threads): crashed on GC before thread allocation.
-
- * st.c (rehash): GC during rehash caused SEGV.
-
-Tue Jul 21 01:25:10 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sprintf.c (f_sprintf): integer formatter totally re-written.
-
- * sprintf.c (remove_sign_bits): support uppercase hexadecimal.
-
-Sat Jul 18 00:14:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sprintf.c (f_sprintf): proper sign position for %X and %O.
-
-Fri Jul 17 14:10:20 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1c0 released.
-
-Fri Jul 17 08:01:49 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * process.c (f_exec): Check_SafeStr() added.
-
- * process.c (f_system): Check_SafeStr() moved before fork().
-
-Thu Jul 16 22:58:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (scan_once): substrings to the block should not be
- tainted. use reg_nth_match(), not str_substr().
-
- * string.c (str_substr): needed to transfer taint.
-
-Thu Jul 16 16:15:57 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * gc.c (xmalloc): object allocation count added to GC trigger.
-
- * eval.c (thread_save_context): avoid marking uninitialized stack
- in thread_mark. GC may be triggered by REALLOC_N().
-
-Wed Jul 15 15:11:57 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_31.
-
-Wed Jul 15 15:05:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_create): exit() and abort() in threads now
- forwarded to main_thread.
-
-Tue Jul 14 14:03:47 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (obj_instance_variables): list names that is not
- instance variables.
-
- * gc.c (GC_MALLOC_LIMIT): choose smaller limit value.
-
-Mon Jul 13 12:39:38 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (str2cstr): should not return NULL.
-
-Fri Jul 10 11:51:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (gettable): needed to add dyna_in_block() check.
-
-Thu Jul 9 17:38:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_30.
-
-Thu Jul 9 16:01:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sprintf.c (fmt_setup): format specifier for long needed.
-
- * sprintf.c (f_sprintf): ditto.
-
- * numeric.c (fix2str): ditto.
-
- * eval.c (thread_create): no more ITIMER_REAL.
-
- * eval.c (thread_create): thread finalization needed before
- aborting thread if thread_abort is set.
-
-Wed Jul 8 18:17:33 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (big_pow): abandon power by bignum (too big).
-
-Tue Jul 7 13:58:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_catch): add C level catch/throw feature.
-
-Mon Jul 6 15:18:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (arg): proper return values for `||=' and `&&='.
-
-Fri Jul 3 16:05:11 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_29.
-
-Fri Jul 3 11:20:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * marshal.c (r_byte): byte should not extend sign bit.
-
- * numeric.c (fix_mul): use FIX2LONG() instead of FIX2INT() for
- 64bit architectures.
-
- * marshal.c (r_bytes): remove weird casting bwetween pointer and int.
-
- * process.c (proc_setsid): new method Process#setsid().
-
-Thu Jul 2 12:49:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * marshal.c (w_object): remove `write_bignum' label for 64bit
- architectures.
-
- * marshal.c (r_bytes): needs int, not long.
-
-Wed Jul 1 14:21:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * numeric.c (flo_plus): should not allow addition with strings.
-
-Wed Jul 1 13:09:01 1998 Keiju ISHITSUKA <keiju@rational.com>
-
- * numeric.c (num_uminus): wrong coerce direction.
-
-Tue Jun 30 10:13:44 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (f_p): accepts arbitrary number of arguments.
-
- * eval.c (rb_yield_0): there's some case that iterator_p() returns
- true even if the_block was not set. check added.
-
-Tue Jun 30 01:05:20 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (BEGIN_CALLARGS): adjust the_block before evaluating the
- receiver's value and the arguments.
-
-Fri Jun 26 18:02:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_28.
-
-Fri Jun 26 11:01:26 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_aset_method): needed to convert to string.
-
-Thu Jun 25 02:05:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_search): optimize for `.*' at beginning of the
- pattern.
-
- * regex.c (re_search): optimize for character class repeat at
- beginning of the pattern.
-
- * regex.c (re_compile_pattern): detect optimization potential for
- the compiled patterns.
-
-Thu Jun 25 00:02:26 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * re.c (reg_s_new): flag value was wrong.
-
-Wed Jun 24 23:45:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_search): wrong anchor handling for reverse search.
-
-Wed Jun 24 02:18:57 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (mlhs): `((a,b)),c = [[1,2]],3' assigns a=1,b=2,c=3.
-
-Tue Jun 23 11:46:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): `&&=' and `||=' added.
-
-Sat Jun 20 02:53:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (assignable): nesting local variables should have higher
- priority than normal local variables for assignment too.
-
-Fri Jun 19 18:28:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_27.
-
-Fri Jun 19 14:34:49 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (assign): support hack for nested multiple assignment.
-
- * parse.y (mlhs): nested multiple assignment.
-
- * eval.c (rb_eval): in-block variables now honors static scope.
-
- * configure.in: RSHIFT check moved to configure.
-
-Thu Jun 18 16:46:04 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_26.
-
-Thu Jun 18 13:37:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * file.c (file_s_ftype): uses lstat(2) instead of stat(2).
-
- * dir.c (dir_s_glob): there can be buffer overrun, check added.
-
- * eval.c (f_binding): handles in-block variables declared after
- binding's generation.
-
- * numeric.c (flo_floor): floor, ceil, round added to Float.
-
-Wed Jun 17 11:20:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (gettable): nesting local variables should have higher
- priority than normal local variables.
-
-Tue Jun 16 12:30:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (str2inum): handles `+ddd'.
-
- * struct.c (make_struct): name parameter can be nil for unnamed
- structures.
-
-Mon Jun 15 16:30:10 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (class_s_inherited): prohibiting to make subclass of
- class Class.
-
- * object.c (module_s_new): support for making subclass of Module.
-
- * parse.y (yycompile): clear eval_tree before compiling.
-
-Fri Jun 12 17:58:18 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (eval): write back the_dyna_var into the block.
-
-Thu Jun 11 18:19:18 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_25.
-
- * eval.c (dvar_add_compiling): register dyna_var at compile time.
-
- * regex.c (re_compile_pattern): RE_DUP_MAX iteration is too big.
-
-Wed Jun 10 15:12:04 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_eof): do not block other threads.
-
- * signal.c (trap): reserve SIGALRM for thread.
-
- * eval.c (thread_create): use ITIMER_REAL also to avoid system
- call blocking.
-
- * io.c (f_syscall): add TRAP_BEG, TRAP_END around system calls.
-
- * io.c (io_ctl): add TRAP_BEG, TRAP_END around system calls.
-
- * enum.c (enum_collect): did not collect false values.
-
- * array.c (ary_new2): forgot to initialize capa field.
-
-Tue Jun 9 18:36:15 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_split_method): split dumped core for "\xff".
-
-Tue Jun 9 16:22:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_24.
-
-Tue Jun 9 16:04:07 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/kconv/kconv.c (kconv_guess): more precise decision for EUC,
- using jless algorithm (3 sequential EUC hiragana characters).
-
-Tue Jun 9 15:12:44 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/kconv/kconv.c (kconv_guess): wrong guess for EUC as SJIS in
- some cases (0xe0 - 0xef).
-
- * gc.c (xmalloc): insert size check for big (negative in signed)
- allocation size.
-
-Tue Jun 9 02:54:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * lib/parsedate.rb: wday moved to the last in the return values.
-
-Mon Jun 8 10:40:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_split_method): split dumped core for "\0".
-
-Sat Jun 6 22:50:52 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (calculate_must_string): wrong condition for
- {start,stop}_nowidth.
-
- * regex.c (re_match): various features imported from GNU regex.c
- 0.12, such as nested grouping, avoiding infinite loop with empty
- match, etc.
-
- * regex.c (register_info_type): now use union.
-
- * regex.c (re_search): more precise anchor(^) check.
-
-Wed Jun 3 18:07:54 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_raise): check rb_in_compile, not rb_in_eval.
-
-Mon Jun 1 05:26:06 1998 WATANABE Tetsuya <tetsu@jpn.hp.com>
-
- * string.c (trnext): casting to signed char* needed.
-
-Tue Jun 2 16:00:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/socket/socket.c (udp_addrsetup): error check enhanced.
-
- * ext/socket/socket.c (sock_s_getservbyaname): use strtoul(), if
- possible.
-
-Sat May 30 07:10:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_prepare_re): no more needless regular expression
- recompile on casefold conditions.
-
-Thu May 28 18:02:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (nil_plus): no more `+' method for nil.
-
-Wed May 27 17:33:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * hash.c (hash_fetch): new method.
-
- * regex.c (re_search): check whether translate table is set.
-
-Tue May 26 11:39:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_23.
-
- * parse.y (yylex): no UPLUS/UMINUS for 1st argument if
- parenthesises are omitted.
-
-Tue May 26 01:09:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): (?XI) for turns off the
- corresponding option.
-
-Mon May 25 12:38:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): inline i option (?i).
-
- * regex.c (re_compile_pattern): inline x option (?x).
-
- * regex.c (re_compile_pattern): x option for regexp.
-
- * dir.c (dir_s_open): returns block's evaluated value.
-
- * io.c (f_open): returns block's evaluated value.
-
- * ext/curses/curses.c (curses_addstr): nil argument caused SEGV.
-
-Fri May 22 11:52:45 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): push mark on (?:), so that
- laststart check for {a,b} can be done.
-
-Thu May 21 17:31:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_match): wrong match (too non-greedy) for `{a,b}?'.
-
- * io.c (io_lineno): new method IO#lineno, IO#lineno=.
-
-Wed May 20 06:04:43 1998 MAEDA shugo <shugo@aianet.ne.jp>
-
- * BeOS patch.
-
-Wed May 20 16:32:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (BIGDN): use RSHIFT(), instead of mere `>>'.
-
-Tue May 19 16:36:26 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_22.
-
-Tue May 19 16:31:57 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (assignable): specification changed for in-block
- variable definition.
-
- * eval.c (dyna_var_asgn): error in in-block variables' compile
- time definition.
-
- * parse.y (str_extend): wrong nesting detection.
-
-Tue May 19 09:47:55 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * numeric.c (num2int): re-defined (extensions may use this).
-
-Mon May 18 16:40:50 1998 MAEDA shugo <shugo@aianet.ne.jp>
-
- * error.c (get_syserr): BeOS support.
-
- * configure.in: modified for BeOS.
-
- * string.c (str_dump): do not call isascii().
-
- * sprintf.c (remove_sign_bits): forgot to initialize end pointer.
-
- * glob.c: #include <alloca.h> added.
-
-Mon May 18 14:52:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_21.
-
-Mon May 18 03:27:57 1998 MAEDA shugo <shugo@aianet.ne.jp>
-
- * file.c (file_s_expand_path): optional second argument
- `default_directory' added.
-
-Sat May 16 22:06:52 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * error.c (RAISE_ERROR): wrong error message
-
-Fri May 15 14:43:25 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_20.
-
-Thu May 14 14:44:21 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * sun4 cc patches for intern.h and regex.h.
-
-Thu May 14 14:03:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * random.c (RANDOM_MAX): guessing proper maximum value for random
- numbers.
-
- * random.c (f_rand): use drand48 if possible.
-
-Wed May 13 19:05:20 1998 1998 MAEDA shugo <shugo@aianet.ne.jp>
-
- * BeOS patches for io.c, error.c and config.guess.
-
-Wed May 13 14:56:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_19.
-
- * most of the Mac and BeOS patches merged, except path separators.
-
- * error.c (err_append): generated SyntaxError was String.
-
- * ruby.h: xxx2INT, xxx2UINT checks values as int, not long.
-
- * ruby.h: remove typedef's. INT, UINT, UCHAR, USHORT.
-
-Tue May 12 17:38:00 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_18.
-
-Tue May 12 11:38:08 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * error.c (syserr_errno): returns errno of the SystemCallError.
-
- * error.c (rb_sys_fail): saves errno in the Exception.
-
- * error.c (set_syserr): no need to protect syserr_list.
-
- * error.c (rb_sys_fail): no more bufsize limit.
-
- * error.c (set_syserr): integer value of errno can be accessed by
- Errno::EXXX::Errno.
-
-Sun May 10 03:10:33 1998 WATANABE Tetsuya <tetsu@jpn.hp.com>
-
- * io.c (io_tell etc.): moved from File class to IO class.
-
-Fri May 8 12:26:37 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * pack.c (pack_unpack): should be unsigned int (was signed int).
-
-Thu May 7 16:34:10 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * pack.c (pack_pack): `V', `N' uses newly created NUM2UINT().
-
- * ruby.h (NUM2UINT): new macro.
-
- * bignum.c (big2uint): try to convert bignum into UINT.
-
- * re.c (reg_match): needed to return false for match with nil.
-
- * gc.c (obj_free): wrong condition to free string.
-
-Wed May 6 21:08:08 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ruby.c (ruby_process_options): modified for DJGPP.
-
-Wed May 6 15:48:03 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_17.
-
-Wed May 6 01:37:39 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c: remove global variable `errat'.
-
- * eval.c (rb_longjmp): embed error position information in the
- exception object.
-
-Sat May 2 12:20:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_search): supports reverse search.
-
- * string.c (str_index_method): does update $~ etc.
-
- * eval.c (f_load): needed to clear the_dyna_vars.
-
- * eval.c (dyna_var_asgn): do not push dyna_var, which is id == 0.
-
- * error.c (Init_Exception): NotImplementError is no longer
- StandardError, which is not handled by default rescue.
-
-Fri May 1 00:35:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (proc_options): `-d' turns on verbose flag too.
-
- * error.c (exception): last argument may be the superclass of the
- defining exception(s).
-
- * io.c (Init_IO): EOFError is now subclass of the IOError.
-
- * io.c (Init_IO): forgot to define IOError.
-
- * error.c (Init_Exception): old Exception class renamed to
- StandardError. Exception now replaces old GlobalExit.
-
- * error.c (Init_Exception): Exception is now the root of the
- Global Exits. There's no longer GlobalExit class.
-
- * util.c (ruby_mktemp): check TMP, TMPDIR first.
-
-Thu Apr 30 01:08:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * lib/tk.rb: call 'unknown', if proc not defined.
-
- * eval.c (handle_rescue): default rescue handles `Exceptional' not
- only the instance of the `Exception's.
-
- * eval.c (f_raise): exception can be any object.
-
- * time.c (time_gm_or_local): call time_gmtime or time_localtime.
-
- * eval.c (f_raise): raises TypeError if the class which is not a
- subclass of String is specified (checked in exc_new()).
-
- * error.c (exc_new): need to check whether invalid class (not a
- subclass of String) is specified.
-
-Wed Apr 29 21:05:44 1998 WATANABE Hirofumi <eban@os.rim.or.jp>
-
- * ruby.c (proc_options): option '-e' via tempfile.
-
-Tue Apr 28 15:27:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_16.
-
-Tue Apr 28 00:07:38 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (obj_is_proc): type check predicate.
-
- * eval.c (obj_is_block): ditto.
-
-Mon Apr 27 16:59:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/gtk/gtk.c (Init_gtk): use timeout, not idle to avoid
- comsuming CPU too much.
-
- * lib/tk.rb: use tcltklib#_invoke instead of `_eval'.
-
-Mon Apr 27 16:59:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_sort): use dup, not clone.
-
-Mon Apr 27 13:46:27 1998 Tadahiro Maebashi <maebashi@iij.ad.jp>
-
- * ext/tcltklib/tcltklib.c (ip_invoke): invoke tcl command
- directly. need not worry about escaping tcl characters.
-
-Mon Apr 27 12:04:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * random.c (f_rand): do not call srand() implicitly.
-
-Fri Apr 24 14:35:45 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_15.
-
- * parse.y (assignable): dyna_var_asgn actually defines nested
- local variables in outer context.
-
- * random.c (f_rand): call srand(), if it has not called yet.
-
- * random.c (f_srand): use tv_usec as the default seed.
-
- * eval.c (rb_eval): values of nested local variables should be
- independent.
-
- * eval.c (rb_yield_0): local variables wrong nested conditions.
-
-Wed Apr 22 23:27:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (select_get_io): get IO object by `to_io'.
-
- * io.c (io_to_io): method to retrieve IO object, from delegating
- object for example.
-
-Wed Apr 22 16:52:37 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_14.
-
- * string.c (str_modify): check for embedded pointer reference.
-
- * gc.c (obj_free): ditto.
-
- * pack.c (pack_pack): p/P template to embed pointers.
-
-Wed Apr 22 00:07:10 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * array.c (ary_rindex): embarrassing typo.
-
-Tue Apr 21 12:31:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_13.
-
- * configure.in (RUBY_LIB): supports --program-{prefix,suffix}.
-
- * array.c (ary_rindex): new method.
-
- * io.c (io_binmode): should return self.
-
-Tue Apr 21 08:23:04 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * parse.y (here_document): calling parse_string with wrong
- arguments.
-
- * struct.c (struct_aset): problem member assignment with name.
-
-Mon Apr 20 14:47:49 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_12.
-
- * time.c (time_arg): args may be string (support for reduced
- implicit type conversion).
-
- * lib/base64.rb: changed to use pack/unpack with `m' template.
-
-Mon Apr 20 06:23:20 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (mod_remove_const): new method.
-
-Sat Apr 18 03:53:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * hash.c (hash_each_with_index): removed. use Enumerable's
- each_with_index instead.
-
- * class.c (rb_include_module): check for super modules, since
- module's included modules may be changed.
-
-Fri Apr 17 21:50:47 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * marshal.c (r_long): r_byte() may return signed byte.
-
-Fri Apr 17 11:58:30 1998 NAGAI Hidetoshi <nagai@dumbo.ai.kyutech.ac.jp>
-
- * ext/tcltklib/tcltklib.c (lib_mainloop): thread and interrupt check.
-
-Fri Apr 17 11:06:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (find_file): try to fopen() to check whether file exists.
-
- * ruby.c (load_file): ditto.
-
- * struct.c (struct_aset): struct member can be set by member name.
-
-Fri Apr 17 00:47:19 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/extmk.rb.in: added m68k-human support
-
- * file.c (LOCK_SH): defines moved.
-
- * array.c (ary_flatten_bang): simplified loop.
-
-Thu Apr 16 16:52:01 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_11.
-
- * lib/tk.rb: thread support (experimental - maybe slow).
-
- * eval.c (rb_longjmp): trace event on exception in raising
- context, just before raising exception.
-
- * struct.c (struct_s_members): forgot to check singletons.
-
- * struct.c (struct_aref): members can be accessed by names too.
-
- * array.c (ary_flatten): new method.
-
- * eval.c (rb_longjmp): prints exception information with `-d'.
-
- * object.c (any_to_s): remove class name restriction.
-
-Thu Apr 16 01:38:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * file.c (thread_flock): do not block other threads.
-
- * eval.c (thread_trap_eval): signals are now delivered to the
- current thread again. In case that the current thread is dead,
- signals are forwarded to the main thread.
-
- * string.c (str_new4): need not to duplicate frozen strings.
-
-Wed Apr 15 08:33:47 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * struct.c (struct_inspect): remove restriction for struct names.
-
-Wed Apr 15 02:55:02 1998 Kazuya 'Sharl' Masuda <sharl@www.ufo.co.jp>
-
- * x68 patches to config.sub, ext/extmk.rb.in
-
-Wed Apr 15 01:22:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_dup_frozen): do not duplicate frozen strings.
-
- * parse.y (yylex): allow nested parenthesises.
-
- * io.c (obj_displayln): prints newline after `display'ing the
- receiver.
-
- * io.c (io_puts): avoid generating "\n" each time. use RS_default
- instead.
-
- * io.c (f_p): ditto.
-
-Tue Apr 14 22:18:17 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * struct.c (struct_aref): should not subtract negative index.
-
-Tue Apr 14 11:34:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_10.
-
- * parse.y: token names prefixed by `t'.
-
- * struct.c (struct_s_def): supports subclassing of Struct.
-
- * io.c (io_s_new): supports subclassing of IO.
-
-Mon Apr 13 11:07:39 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (f_binding): need to restore method name.
-
- * eval.c (rb_call0): raises SystemStackError, not Fatal.
-
- * io.c (obj_display): same as `print self'.
-
- * io.c (f_p): can now be called in the method form.
-
- * re.c (reg_regsub): needed to be mbchar aware.
-
-Mon Apr 13 13:18:32 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_trap_eval): all signals delivered to main_thread.
-
-Mon Apr 13 12:47:03 1998 TAKAHASHI Masayoshi <maki@inac.co.jp>
-
- * re.c (kcode_set_option): did not set SJIS on SJIS condition.
-
-Sun Apr 12 22:14:07 1998 Kazunori NISHI <kazunori@swlab.csce.kyushu-u.ac.jp>
-
- * array.c (ary_uniq_bang): should be `==', not `='. embarrassing.
-
-Sat Apr 11 02:13:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_subseq): SEGVed for `[][1,1]'.
-
-Fri Apr 10 21:29:06 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * array.c (ary_subseq): add check for beg larger than array length.
-
-Wed Apr 8 17:24:11 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * dir.c (dir_s_open): can be called with block (like IO#open).
-
- * dir.c (dir_s_chdir): print directory path on error.
-
- * dir.c (dir_s_chroot): ditto
-
- * dir.c (Init_Dir): needed to override `new'.
-
-Thu Apr 9 18:24:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_09.
-
- * string.c (str_cmp): do not depend on sentinel at the end of the
- strings.
-
- * string.c (str_chomp_bang): forgot to set the sentinel.
-
-Wed Apr 8 00:59:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (big2int): converted int may be too big to fit in
- signed int.
-
- * parse.y (arg): `foo += 1' should not cause an error.
-
- * variable.c (rb_const_defined): returned false even if the
- constant is defined at the top level.
-
- * eval.c (f_local_variables): dyna_var->id may be null. should
- have checked before calling str_new2().
-
-Tue Apr 7 01:15:15 1998 Kaneko Naoshi <wbs01621@mail.wbs.or.jp>
-
- * re.c (reg_regsub): need to check string boundary.
-
-Tue Apr 7 19:19:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_cmp): returns either 1, 0, -1.
-
- * array.c (ary_cmp): should check array length, too
-
-Tue Apr 7 18:50:16 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_08.
-
-Tue Apr 7 18:31:27 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * instruby.rb (mandir): dll installation for cygwin32
-
-Tue Apr 7 01:16:45 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * config.sub (maybe_os): TOWNS support?
-
- * config.guess: too strict check for libc versions on linuxes.
-
- * experimental release 1.1b9_07.
-
- * array.c (ary_cmp): compare each element using `<=>'.
-
- * hash.c (hash_each_with_index): yields [value, key] pair.
-
- * class.c (class_protected_instance_methods): list protected
- method names.
-
- * class.c (ins_methods_i): exclude protected methods.
-
- * eval.c (PUSH_BLOCK): dynamic variables can be accessed from
- eval() with bindings.
-
-Mon Apr 6 14:49:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_yield): must return evaluated value.
-
-Fri Apr 3 13:07:29 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_schedule): context switch bypassed on wrong
- conditions.
-
- * variable.c (rb_name_class): set classname by id before String
- class is initialized (1.0 behavior restored).
-
-Fri Apr 3 11:25:45 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * numeric.c (num2int): no implicit conversion from string.
-
- * numeric.c (num2int): check whether `to_i' returns an Integer.
-
- * numeric.c (num_zero_p): new method.
-
- * numeric.c (num_nonzero_p): new method. returns the receiver if
- it's not zero.
-
- * eval.c (obj_instance_eval): the_class should be the object's
- singleton class.
-
- * error.c (exc_s_new): message is converted into a string.
-
-Thu Apr 2 18:31:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (obj_call_init): every object call `initialize'.
-
-Wed Apr 1 08:51:53 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * parse.y (stmt): UNTIL_MOD should be for stmt, not only for expr.
-
-Wed Apr 1 01:20:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (true_and): boolean operators &, | and ^.
-
-Tue Mar 31 13:23:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_compact_bang): returns nil, if it does not modify
- the array like String's bang methods.
-
- * array.c (ary_uniq_bang): new method to remove duplicate items.
-
- * eval.c (bind_s_new): new method.
-
- * numeric.c (num2int): raise exception if Fixnums too big to
- convert into `int' in case that sizeof(int) < sizeof(INT).
-
- * string.c (str_center): SEGV on negative width.
-
- * eval.c (eval): forgot to set sourcefile.
-
-Mon Mar 30 11:12:29 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * file.c (f_test): raises exception for unkown command.
-
- * eval.c (Init_eval): `class_eval': alias to the module_eval.
-
-Mon Mar 30 18:50:42 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * string.c (str_capitalize_bang): did not check string modification.
-
- * string.c (str_delete_bang): wrong conversion.
-
- * string.c (str_intern): typo in error message.
-
-Mon Mar 30 01:44:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (obj_instance_eval): accepts block as evaluation body.
- No compilation needed each time.
-
- * eval.c (mod_module_eval): ditto
-
- * file.c (file_s_umask): umask did not return old values, if no
- argument given.
-
-Sun Mar 29 00:54:23 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (f_throw): nil returned always.
-
-Sat Mar 28 20:40:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_06.
-
-Sat Mar 28 16:07:11 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_closed): should not cause exception fot closed IO.
-
- * string.c (str_tr): returned nil for success.
-
-Sat Mar 28 00:47:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (f_local_variables): new method to return an array of
- local variable names.
-
- * variable.c (obj_instance_variables): now returns an array of
- variable names, as described in the reference.
-
- * eval.c (rb_attr): honors default method visibility of the
- current scope.
-
-Fri Mar 27 13:49:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_05.
-
- * ruby.c (ruby_prog_init): `site_ruby' added to load_path.
-
- * ruby.c (ruby_prog_init): load-path order changed. Paths in
- the RUBYLIB environment variable comes first in non-tainted
- mode.
-
-Thu Mar 26 11:51:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_call): new feature: `protected' methods.
-
- * string.c (str_dump): new method.
-
- * eval.c (block_pass): block argument can be nil, which means no
- block is supplied for the method.
-
-Wed Mar 25 21:20:13 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * string.c (str_reverse_bang): string copied to wrong place.
-
-Wed Mar 25 08:12:07 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * numeric.c (flo_modulo): caused SEGV if left operand is not a
- float value.
-
- * eval.c (f_eval): optional third and fourth argument to specify
- file-name and line-number.
-
- * eval.c (eval): file-name and line-number set properly.
-
- * parse.y (assign_in_cond): literal assignment is now warning, not
- compile error.
-
- * error.c (Warn): Warn() always print message, OTOH Waring()
- prints when verbose flag is set.
-
-Tue Mar 24 12:50:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (ruby_prog_init): `.' should come last in the load-path.
-
- * eval.c (Init_eval): `__send__', alias for `send'.
-
-Mon Mar 23 12:44:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_chomp_bang): now takes `rs' as an argument.
-
- * eval.c (thread_free): main_thread should not be freed.
-
-Fri Mar 20 16:40:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_chomp_bang): chomp! (and other ! methods) returns
- nil if it does not modify the string.
-
- * string.c (str_sub_iter_s): should check last pattern since it
- may be matched to null.
-
-Thu Mar 19 13:48:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_04.
-
- * parse.y (yylex): `10e0.9' should cause syntax error.
-
-Wed Mar 18 17:46:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (load_file): new file object constant DATA. Only
- available for the script from the file.
-
- * regex.c (re_match): forwading failure point popped too much.
-
-Tue Mar 17 18:23:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * math.c (math_frexp): newly added.
-
- * math.c (math_ldexp): ditto.
-
- * bignum.c (bigdivmod): calculates modulo.
-
- * numeric.c (fix_remainder): returns reminder, formerly introduced
- as modulo.
-
- * numeric.c (fix_modulo): calculates proper `modulo'.
-
- * bignum.c (bigdivmod): wrong sign for reminder.
-
-Mon Mar 16 17:07:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_03.
-
-Mon Mar 16 16:33:53 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (pipe_finalize): needed to add pipe_finalize to pipes on
- cygwin32.
-
-Mon Mar 16 14:11:06 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (ins_methods_i): needed to consider NOEX_UNDEF.
-
-Mon Mar 16 13:23:53 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_check_closed): check for `fptr->f2 == NULL'.
-
- * io.c (io_fptr_close): ditto.
-
-Mon Mar 16 11:49:25 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (pipe_atexit): free()ing referencing pipe_list.
-
- * range.c (range_length): returns zero, if the first is greater
- than the last.
-
- * signal.c (trap_restore_mask): restore signal mask before raising
- exceptions and throws.
-
-Fri Mar 13 13:49:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_02.
-
- * object.c (mod_clone): need to dups constants and instance
- variables.
-
- * eval.c (rb_eval): forgot to initialize body for NODE_DEFS.
-
- * eval.c (rb_eval): retrieve self from calling frame, since self
- changes sometimes.
-
- * env.h (FRAME): need to save self in the calling frame.
-
- * io.c (f_gets_method): rs should be initialized by RS.
-
-Thu Mar 12 15:33:57 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * experimental release 1.1b9_01.
-
- * range.c (range_s_new): check values by `first <= last'.
-
- * parse.y (lastline_set): fixed offset for $_ and $~ in the local
- variable space.
-
-Wed Mar 11 02:14:17 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_gets): handle normal case specially for speed.
-
- * eval.c (rb_disable_super): function to disable superclass's
- method explicitly.
-
- * eval.c (rb_eval): inherits previous method definition's
- NOEX_UNDEF-ness, if exists.
-
- * class.c (rb_define_method): disables superclass's overriding
- method by default.
-
-Wed Mar 11 01:40:48 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * numeric.c (flo_gt,etc.): do not depend on `<=>', to handle NaN.
-
-Tue Mar 10 00:03:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (load_file): understands multiple options in #! line.
-
- * regex.c (re_compile_pattern): support for [:alpha:] etc.
-
-Mon Mar 9 16:53:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.h (GetOpenFile): embed io_check_closed in GetOpenFile.
-
- * sprintf.c (f_sprintf): zero padding failed for negative
- integers.
-
- * sprintf.c (remove_sign_bits): failed to remove some bits.
-
-Sat Mar 7 21:51:46 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * class.c (ins_methods_i): body may be NULL for some case.
-
-Fri Mar 6 17:23:07 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (mbcinit): table driven mbchar detection.
-
- * object.c (obj_alloc): check for allocating instance for the
- primitive classes (mostly perfect).
-
- * ext/curses/curses.c (curses_finalize): restore original state at
- interpreter temination.
-
- * ext/curses/curses.c (curses_addstr): forgot to check argument
- type (caused SEGV). now uses STR2CSTR() macro.
-
-Thu Mar 5 13:47:39 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (block_pass): accepts method object as block args.
-
- * eval.c (f_missing): use any_to_s() for stringify.
-
-Wed Mar 4 01:39:52 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (block_arg): new syntax - block argument in the
- calling arglist.
-
- * eval.c (rb_call): no module search. simplified a lot.
-
- * eval.c (rb_eval): block arg support.
-
- * parse.y (f_block_arg): new syntax - block argument in the
- formal arglist.
-
-Tue Mar 3 14:20:15 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (obj_method): returns bound method object.
-
- * eval.c (rb_call): argument check for empty methods.
-
- * ruby.h (NUM2CHR): new macro, originally from curses module.
-
-Tue Mar 3 13:03:35 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * io.c (io_putc): new method.
-
-Tue Mar 3 11:21:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_inspect): more strict charcode detection.
-
- * eval.c (thread_stop): stopping only thread raises ThreadError
- exception.
-
-Tue Mar 3 08:04:56 1998 Tadayoshi Funaba <tadf@kt.rim.or.jp>
-
- * struct.c (struct_alloc): imcomplete struct initialization made
- GC to access unallocated addresses.
-
-Mon Mar 2 16:28:27 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (thread_stop_method): remove Thread#stop.
-
-Fri Feb 27 18:16:26 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b9 released.
-
-Fri Feb 27 09:36:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * hash.c (hash_delete_nil): needed to compare value to nil, since
- nil is the valid key for hashes.
-
- * hash.c (hash_foreach_iter): rehashing causes IndexError.
-
- * hash.c (hash_foreach_iter): rehash check by pointer comparison.
-
-Thu Feb 26 17:22:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (fname): convert reswords into symbols.
-
- * parse.y (reswords): reserved words are now embedded in the
- syntax (sigh).
-
- * parse.y: now reserved words can be method names safely.
-
-Wed Feb 25 15:50:07 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (mod_module_eval): clear the_scope's PRIVATE flag before
- calling eval().
-
- * gc.c (gc_call_finalizer_at_exit): run finalizers before any data
- object being freed.
-
- * eval.c (rb_eval): needed to keep prot_tag->retval before
- evaluating the ensure clause.
-
-Tue Feb 24 11:16:32 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): reserved words can be appear as method names at
- right after 'def' and `.'(dot), like foo.next.
-
- * eval.c (return_check): checks for return out of thread (formerly
- done in return_value).
-
- * eval.c (POP_TAG): copy retval to outer level.
-
- * eval.c (return_value): just set retval, no check, no unwinding.
-
- * parse.y (nextc): line continuation by backslash at end of line.
-
- * regex.c (re_compile_pattern): forgot to clear pending_exact on
- closing parentheses.
-
- * parse.y (assignable): should not assign dyna_var to true, if it
- is already defined.
-
-Mon Feb 23 14:35:03 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (obj_is_kind_of): no longer accepts true/false/nil.
-
- * object.c ({true,false,nil}_to_i): can be converted into integers.
-
-Mon Feb 23 12:11:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_s_quote): needed to be mbchar aware.
-
- * eval.c (proc_s_new): wrong iter mark.
-
-Sat Feb 21 22:59:30 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * io.c (f_syscall): no argument check.
-
-Fri Feb 20 10:17:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b8 released.
-
- * ext/kconv/kconv.c (kconv_kconv): default output code now be
- determined according to the value of $KCODE.
-
- * re.c (rb_get_kcode): can retrieve $KCODE from C code.
-
- * parse.y (stmt): if/unless modifiers returns nil, if condition is
- not established.
-
-Thu Feb 19 11:06:47 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/kconv/kconv.c (kconv_kconv): charcode can be specified by
- code name (JIS, SJIS, EUC like value of $KCODE).
-
- * regex.c (re_compile_pattern): forgot to fixup_jump for (?:..).
-
- * regex.c (re_compile_pattern): needed to clear pending_exact on
- non-registering grouping (?:...).
-
-Wed Feb 18 19:54:21 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (here_document): needed to set lex_state to EXPR_END.
-
-Wed Feb 18 18:45:10 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * patches for cygwin32 applied.
-
-Wed Feb 18 00:41:31 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_sub_s): needed to be mbchar aware to increment one
- character.
-
- * regex.c (re_match): \Z matches newline just before the end of
- the string.
-
-Tue Feb 17 00:04:32 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c (time_arg): Time.gm and Time.local now understands
- Time#to_a format.
-
- * string.c (str_sub_s): replace happened twice for null pattern.
-
- * regex.c (re_search): null pattern should not match after newline
- at the end of string.
-
- * time.c (time_isdst): now returns boolean value.
-
- * error.c (rb_check_type): treat special constants in messages.
-
- * parse.y (yylex): new form `::Const' to see toplevel constants.
-
- * parse.y (cond): SEGV on `if ()'.
-
- * gc.c (obj_free): some data needed explicit free().
-
-Mon Feb 16 23:55:40 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (blk_free): release duplicated block informations.
-
- * eval.c (blk_copy_prev): duplicate outer block information into
- the heap, when proc/binding created.
-
-Mon Feb 16 14:38:25 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c (time_mon): now 1 for January and so on.
-
- * time.c (time_year): year in 19xx (no + 1900 needed anymore).
-
-Mon Feb 16 13:28:33 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): need to fetch mbchar's second byte
- without translation.
-
-Mon Feb 16 12:29:27 1998 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * eval.c (f_pass_block): pass iterator block to other method.
-
-Fri Feb 13 08:16:11 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (parse_regx): handle \s before read_escape().
-
- * parse.y (read_escape): `\s' in strings as space.
-
-Tue Feb 10 17:29:08 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b7 released.
-
- * string.c (str_aset): string insertion by `str[n] = str2'.
-
- * string.c (str_oct): does recognize `0x'.
-
- * sprintf.c (f_sprintf): use baes 10 for conversion from string to
- integer.
-
-Mon Feb 9 14:51:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * numeric.c (do_coerce): proper error message.
-
- * string.c (str_sum): bug - masked by wrong value. (sigh..)
-
-Sat Feb 7 15:11:14 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_empty): new method
-
-Fri Feb 6 01:42:15 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c (time_asctime): use asctime(3), not strftime(3).
-
-Thu Feb 5 18:58:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_fptr_close): do not free path on close().
-
- * array.c (ary_filter): new method.
-
- * enum.c (enum_each_with_index): new method.
-
-Thu Feb 5 14:10:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (primary): singleton class def can be appeared inside
- method bodies.
-
- * hash.c (hash_replace): replace content.
-
- * string.c (str_replace_method): replace content.
-
- * array.c (ary_replace_method): replace elements.
-
- * string.c (str_succ_bang): String#succ!
-
-Thu Feb 5 18:20:30 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_upcase_bang): multi byte character support.
-
-Wed Feb 4 13:55:26 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_reverse): SEGV on empty array reverse.
-
-Tue Feb 3 12:24:07 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (match_to_a): non matching element should be nil.
-
- * ruby.c (ruby_load_script): load script after all initialization.
-
- * bignum.c (str2inum): need to interpret prefix `0' of `0x'.
-
-Tue Feb 3 10:00:18 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * numeric.c (fix_rshift): use `sizeof(INT)*8' instead of 32.
-
-Mon Feb 2 14:09:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (set_arg0): grab environment region too.
-
-Thu Jan 29 18:36:25 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * process.c (rb_proc_exec): check `sh' to be exist.
-
-Thu Jan 29 18:18:19 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_stdio_set): assignment to $stdin or $stdout does
- reopen() as well as $stderr.
-
-Thu Jan 29 14:18:40 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (mod_ancestors): should not include singleton classes.
-
- * object.c (obj_type): should not return internal class.
-
- * io.c (io_reopen): unwillingly closes stdio streams.
-
-Thu Jan 29 11:50:35 1998 Toshihiko SHIMOKAWA <toshi@csce.kyushu-u.ac.jp>
-
- * ext/socket/socket.c (udp_addrsetup): forgot to use htons().
-
-Tue Jan 27 23:15:24 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * keywords: __FILE__, __LINE__ are available again.
-
-Fri Jan 23 14:19:28 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b6 released.
-
- * object.c (mod_to_s): need to duplicate classpath.
-
- * error.c (exc_inspect): need to duplicate classpath.
-
-Thu Jan 22 00:37:47 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.h (STR2CSTR): new macro to retrieve char*.
-
- * class.c (rb_define_method): `initialize' should always be
- private, even if it defined by C extensions.
-
- * eval.c (rb_eval): `initialize' should always be private.
-
-Thu Jan 22 16:21:08 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_eval): some singleton class def cause SEGV.
-
- * eval.c (TMP_ALLOC): replace ALLOCA_N, where thread context
- switch may happen.
-
-Wed Jan 21 01:43:42 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (PUSH_FRAME): do not use ALLOCA_N(). crash on some
- platforms that use missing/alloca.c.
-
- * regex.c (re_compile_pattern): too many pops for non register
- subexpr.
-
- * parse.y (yylex): open parentheses after identifiers are argument
- list, even if whitespaces have seen.
-
-Tue Jan 20 15:19:59 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (terms): quoted word list by %w(a b c).
-
- * ext/tcltklib/extconf.rb: more accurate check for tcl/tk libs.
-
- * file.c (rb_stat): most of the FileTest methods (and function
- `test') accept File objects as the argument.
-
-Tue Jan 19 18:19:24 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/extmk.rb.in (install): there should be no newline after install:
-
- * re.c (MIN): renamed from min(). there's a local variable named
- min in the file, so that some cpp will raise an error.
-
-Mon Jan 19 16:30:05 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b5 released.
-
- * process.c (rb_syswait): no exception raised.
-
-Fri Jan 16 00:43:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.h (CLONESETUP): copies its singleton classes too.
-
- * class.c (singleton_class_attached): saves binded object in the
- singleton classes.
-
- * eval.c (rb_eval): calls singleton_method_added even in the
- singleton class clauses.
-
-Fri Jan 15 23:22:43 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ruby.c (proc_options): -S does not recognize PATH.
-
-Thu Jan 15 02:03:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_clear_cache_by_id): clear only affected cache
- entries.
-
-Wed Jan 14 02:14:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/socket/socket.c: new UDP/IP socket classes.
-
-Tue Jan 13 10:00:18 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_cmp): ignorecase($=) works wrong.
-
-Fri Jan 9 13:19:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b4 released.
-
- * eval.c (f_missing): class name omitted from the error message.
-
- * error.c (exc_inspect): description changed.
-
- * string.c (Init_String): GlobalExit's superclass did not filled,
- since GlobalExit created earlier than String.
-
-Thu Jan 8 12:10:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (aryset): expr in the brackets can be null.
-
-Wed Jan 7 21:13:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_reopen): keep stderr unclosed.
-
- * io.c (io_errset): keep stderr unclosed.
-
-Tue Jan 6 00:27:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y: syntax modified for `while expr do .. end' etc.
-
- * process.c (f_exec,f_system): can supply arbitrary name for the
- new process.
-
-Mon Jan 5 16:59:13 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * file.c (file_s_basename): removes any extention by ".*".
-
-Sun Jan 4 19:36:22 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (yylex): needed to update lex_p (reading point).
-
-Sat Jan 3 19:14:14 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * class.c,object.c: duplicate defines mKernel and cFinxnum.
-
-Fri Jan 2 20:38:59 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/curses/curses.c (NUM2CHAR): uses the first character for
- string arguments.
-
- * array.c (ary_fill): did not extend array for ranges.
-
- * array.c (beg_len): did not return end pos bigger than size.
-
-Fri Jan 2 02:09:16 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * dir.c (dir_s_chdir): bug in nil check.
-
- * array.c (ary_fill): bug in nil check.
-
-Tue Dec 30 11:46:23 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * hash.c (env_path_tainted): checks directories in PATH
- environment variable are not world writable.
-
- * ruby.c (load_file): invoke specified interpreter if the #! line
- does not contain the word `ruby'.
-
-Fri Dec 26 03:26:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (uscore_get): type information included in the error
- message.
-
- * variable.c (f_untrace_var): does not free trace-data within
- trace procedure.
-
-Thu Dec 25 02:50:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b3 released.
-
- * ruby.h: inlining some functions on gcc 2.x
-
-Tue Dec 23 02:47:33 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_eval): public/private information kept in the current
- scope, to remove undesired state from the class/module.
-
- * time.c (time_strftime): remove hidden limit of 100 bytes of
- result string, using malloc'ed buffer.
-
- * hash.c (hash_update): merges the contents of another hash,
- overriding existing keys.
-
- * regex.c (must_instr): totally re-written.
-
- * io.c (read_all): try to allocate proper sized buffer using
- fstat(2) for speedup.
-
-Sat Dec 20 00:27:28 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (must_instr): need to skip 2 bytes for mbchars.
-
-Fri Dec 19 01:18:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b2 released.
-
- * eval.c (check_errat): check and convert (if necessary) traceback
- information before assigning to the variable $@.
-
- * eval.c (f_raise): optional third argument to specify traceback
- information.
-
- * io.c (f_open): prevent infinite recursive call.
-
-Thu Dec 18 19:33:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_rindex): now accepts regexp as index.
-
-Thu Dec 18 18:42:50 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/socket/extconf.rb: modified to detect win32 socket lib.
-
-Thu Dec 18 00:25:03 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (reg_equal): checks for source and casefold and kcode matching.
-
- * marshal.c: became built-in module.
-
- * ext/marshal/marshal.c (r_object): displays struct name for
- non-compatible struct.
-
- * string.c (str_index_method): now searches character (fixnum) in
- the string.
-
- * string.c (str_include): redefine `include?'.
-
- * regex.c (re_match): start_nowidth saves current stack position
- to stop_nowidth.
-
- * regex.c (re_compile_pattern): add space to stop_nowidth to save
- runtime stack position.
-
-Tue Dec 16 14:57:43 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (scan_once): wrong exception for regexp that match with
- null string (use substr instead of subseq).
-
-Sat Dec 13 00:13:32 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (expr): remove bare assocs from expr rule.
-
- * rbconfig.rb: renamed from config.rb (it was too generic name).
-
-Fri Dec 12 00:50:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (expr): warns if BEGIN or END appear in the method
- bodies.
-
- * string.c (str_match): calls y =~ x if y is neither String nor
- Regexp so that eregex.rb works.
-
- * eval.c (f_at_exit): to register end proc.
-
- * class.c (rb_define_module_function): define 'function' method
- for the Module, not private method.
-
- * class.c (rb_define_function): function to define `function' method.
-
- * eval.c (rb_eval): inherit visibility from superclass's method
- except when it is set to `function'
-
- * eval.c (rb_eval): new visibility status `function'.
-
- * parse.y (yycompile): do not clear eval_tree. thus enable multipe
- command line script by optn `-e'.
-
- * eval.c (rb_eval): END execute just once.
-
- * parse.y (expr): BEGIN/END built in the syntax.
-
-Thu Dec 11 13:14:35 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (mod_le): Module (or Class) comparison.
-
- * eval.c (rb_remove_method): raises NameError if named method does
- not exist.
-
- * ext/curses/curses.c: remove CHECK macro for BSD curses.
-
-Thu Dec 11 12:44:01 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * pack.c: sun4 cc patch
-
-Wed Dec 10 15:21:36 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/marshal/marshal.c (marshal_load): can supply evolution proc
- object as optional second argument.
-
- * re.c (reg_source): get source string of the regular expression.
-
-Tue Dec 9 10:05:17 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b1 released.
-
- * parse.y (tokadd): token buffer overrun.
-
- * ruby.c (ruby_prog_init): forgot to protect rb_argv0 from gc.
-
- * eval.c (ruby_run): call finalizers at process termination.
-
- * gc.c (gc_call_finalizer_at_exit): call free proc for every Data
- Wrapper, and finalizer for specified objects at termination.
-
- * version.c (show_version): version format changed.
-
- * regex.c (re_match): wrong match with non-greedy if they appear
- more than once in regular expressions.
-
- * sample/ruby-mode.el (ruby-expr-beg): forgot to handle modifiers.
-
-Mon Dec 8 19:00:15 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_puts): just put a newline if no argument given.
-
- * ext/tcltklib/tcltklib.c (lib_mainloop): thread-aware tk handle
- when $tk_thread_safe is set.
-
- * ext/tcltklib/tcltklib.c (lib_mainloop): use Tcl_DoOneEvent()
- instead of Tk_MainLoop().
-
-Mon Dec 6 07:11:16 1997 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * io.c (io_puts): core dumped without any argument.
-
-Fri Dec 5 18:17:17 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (mod_remove_method): remove (not undef) a method from the
- class/module.
-
- * variable.c (obj_remove_instance_variable): method to remove
- instance variables.
-
-Thu Dec 4 13:50:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1b0 released.
-
- * string.c (str_aref): called str_index for regexp.
-
-Mon Dec 1 15:24:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * compar.c (cmp_between): wrong comparison made.
-
-Wed Nov 26 18:18:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * lib/mkmf.rb: generate Makefile for extention modules out of ruby
- source tree. use like `ruby -r mkmf extconf.rb'.
-
- * numeric.c (fix2str): enlarge buffer to prevent overflow on some
- machines.
-
- * parse.y (here_document): wrong line number generated after here-doc.
-
-Fri Nov 21 13:17:12 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): skip multibyte characters in comments.
-
-Wed Nov 19 17:19:20 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (nil_to_a): nil.to_a => [].
-
- * parse.y (call_args): wrong node generation.
-
-Tue Nov 18 10:13:08 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (Init_Array): Array#=== works as Array#include?
-
- * regex.c (re_compile_pattern): insert initialize code for jump_n,
- before entering loops.
-
- * re.c (reg_search): does not save registers unless $& etc appear
- in the script.
-
-Mon Nov 17 13:01:43 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (is_defined): add defined? check for receivers and
- arguments for calls.
-
- * re.c (reg_search): cache last match object.
-
- * re.c (match_aref): $[0] etc. are available.
-
-Sat Nov 15 00:11:36 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_s_popen): "rb" detection
-
-Fri Nov 14 18:28:40 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (scan_once): returns whole match if the pattern does
- not contain any parentheses.
-
-Thu Nov 13 14:39:06 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (str_sub): returns copy of the receiver string, even if
- any substitution occurred.
-
- * regex.c (re_compile_pattern): no-width match by (?=..), (?!..).
-
-Wed Nov 12 13:44:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c: remove coerce from Time class.
-
- * regex.c (re_match): non-greedy match by ??, *? +?, {n,m}?.
-
-Mon Nov 10 11:24:51 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): non-resitering parens (?:..).
-
- * regex.c (re_compile_pattern): new meta character \< (wordbeg)
- and \> (wordend).
-
- * regex.c (re_compile_pattern): embedded comment for regular
- expression by (?#...).
-
-Fri Nov 7 16:58:24 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): perl5 regxp \A and \Z available.
-
- * regex.c (re_compile_pattern): can expand compile stack dynamically.
-
- * regex.c (PUSH_FAILURE_POINT): wrong compare condition.
-
-Wed Nov 2 16:00:00 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_sub_s): "".sub! "", "" => "\000"
-
-Fri Oct 31 15:52:10 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (assoc): keyword assoc like {fg->"black"}.
-
-Thu Oct 30 17:33:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_println): print with newline, which is not affected by
- the values of $/ and $\.
-
-Thu Oct 30 16:54:01 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_chop_bang): "".chop caused SEGV.
-
- * string.c (str_chomp_bang): method to chop out last newline.
-
-Mon Oct 27 13:49:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/extmk.rb.in: library may have pathname contains `.'
-
- * eval.c (rb_rescue): should not protect SystemError.
-
-Fri Oct 24 10:58:53 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_s_with_open_stream): ensures to close stream.
-
-Thu Oct 23 11:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_errset): value of $stderr can be changed (to any IO
- object).
-
- * io.c (next_argv): $< can be anything that responds to `write'.
-
- * file.c (file_s_with_open_file): ensures to close file.
-
- * error.c (exception): create error under the current class/module.
-
- * range.c (range_eqq): fixnum check for last needed too.
-
-Wed Oct 22 12:52:30 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/socket/socket.c: Socket::Constants added.
-
- * file.c: File::Constants added for inclusion.
-
- * array.c (ary_join): call ary_join() recursively for the 1st
- array element.
-
-Mon Oct 20 12:18:29 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ruby.c (load_file): wrong condition for #! check with -x.
-
- * file.c (file_s_dirname): did return "" for "/a".
-
-Fri Oct 17 14:29:09 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c: now works on alpha-linux.
-
- * bignum.c (bigadd): some undefined side effect order assumed.
-
-Wed Oct 15 17:49:24 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * intern.h: function prototypes added.
-
-Mon Oct 13 16:54:18 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (rb_define_class_id): call superclass's `inherited'
- method when making subclasses.
-
- * parse.y (nextc): clear lex_lastline at the end of file.
-
- * object.c (Init_Object): need to undef Class#append_features.
-
- * eval.c (rb_eval): no warning on extending classes or modules.
-
-Thu Oct 9 11:17:50 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (error_print): the exception name follows after the error
- message.
-
- * eval.c (compile_error): error message slightly changed.
-
- * parse.y (nextc): script parsing will be terminated by __END__ at
- beginning of line.
-
- * eval.c (compile_error): `__END__' is no longer a keyword.
-
- * parse.y (nextc): protect lastline read from script stream.
-
-Tue Oct 7 14:06:06 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha9 released.
-
- * eval.c (mod_append_features): renamed from extend_class.
-
- * eval.c (rb_eval): defining method calls `method_added'.
-
- * eval.c (ruby_options): exception while processing options must
- terminate the interpreter.
-
- * error.c (Init_Exception): wrong method configuration. `new'
- should have been a singleton method.
-
-Mon Oct 6 18:55:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/kconv/kconv.c (kconv_guess): code to guess character code
- from string.
-
-Mon Oct 6 18:38:17 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * pack.c: now encode/decode base64 by `m' template.
-
-Fri Oct 3 10:51:10 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * MANIFEST: needed to include lex.c in the distribution.
-
- * eval.c (ruby_options): f_require() called too early.
-
- * eval.c (rb_provide): module extentions should always be `.o'.
-
-Thu Oct 2 11:38:31 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha8 released.
-
- * ext/marshal/marshal.c (r_object): remove temporal regist for
- structs. (caused problem if structs form cycles.)
-
- * parse.y (match_gen): static binding for match(=~) calls
- with regexp literals.
-
-Wed Oct 1 15:26:55 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c: protect retval in struct tag from GC for C_ALLOCA.
-
- * eval.c: no more pointer value from setjmp/longjmp.
-
-Wed Oct 1 14:01:49 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/marshal/marshal.c (w_byte): argument must be char.
-
-Wed Oct 1 10:30:22 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (mod_const_at): global constants now belongs to the
- class Object.
-
- * object.c (Init_Object): new global constant NIL.
-
- * ext/marshal/marshal.c (marshal_dump): try to set binmode.
-
- * ext/marshal/marshal.c (r_object): forgot to re-regist structs in
- the object table.
-
- * eval.c (ruby_options): call Init_ext() before any require()
- calls by `-r'.
-
-Fri Sep 30 14:29:22 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/marshal/marshal.c (w_object): marshal dumped core.
-
-Tue Sep 30 10:27:39 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/test.rb: bignum test suits added.
-
- * eval.c (rb_eval): new pseudo variable `true' and `false'.
-
- * parse.y: new keywords `true' and `false' added.
-
-Mon Sep 29 13:37:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (forbid_setid): forbid some options in suid mode.
-
- * ruby.h (NUM2DBL): new macro to convert into doubles.
-
-Mon Sep 27 09:53:48 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-
- * bignum.c: modified for speeding.
-
-Fri Sep 26 18:27:59 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * sample/from.rb: some extensions.
-
-Mon Sep 29 13:15:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (lhs): no more syntax error on `obj.CONSTANT = value'.
-
-Fri Sep 26 14:41:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (ruby_run): deferred calling Init_ext() just before eval_node.
-
-Fri Sep 26 13:27:24 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_isatty): forgot to return TRUE value.
-
-Fri Sep 25 11:10:58 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-
- * eval.c: use _setjmp/_longjmp instead of setjmp/longjmp on some
- platforms.
-
-Wed Sep 24 17:43:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (Init_String): String#taint and String#taint? added.
-
- * class.c (mod_ancestors): ancestors include the class itself.
-
-Wed Sep 24 00:57:00 1997 Katsuyuki Okabe <HGC02147@niftyserve.or.jp>
-
- * X68000 patch.
-
-Tue Sep 23 20:42:30 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-
- * parse.y (node_newnode): SEGV on null node setup.
-
-Mon Sep 22 11:22:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (ruby_prog_init): wrong safe condition check.
-
-Sun Sep 21 14:46:02 1997 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * error.c (exc_inspect): garbage added to classpath.
-
-Fri Sep 19 11:49:23 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (newtok): forgot to adjust buffer size when shrinking
- the token buffer.
-
- * enum.c (enum_find): rb_eval_cmd() does not return value.
-
- * io.c (pipe_open): close fds on pipe exec. fcntl(fd, F_SETFD, 1)
- no longer used.
-
-Tue Sep 16 17:54:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * file.c (f_test): problem if wrong command specified.
-
- * ruby.c (ruby_prog_init): close stdaux and stdprn for MSDOS.
-
- * ruby.c (ruby_prog_init): should not add path from environment
- variable, if ruby is running under seuid.
-
- * process.c (init_ids): check suid check for setuid/seteuid etc.
-
-Mon Sep 15 00:42:04 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * regex.c (re_compile_pattern): \w{3} and \W{3} did not work.
-
-Thu Sep 11 10:31:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha7 released.
-
- * ext/socket/socket.c (sock_new): no setbuf() for NT.
-
- * io.c (rb_fopen,rb_fdopen): set close-on-exec for every fd.
-
-Wed Sep 10 15:55:31 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/marshal/marshal.c (r_bytes0): extra big length check.
-
-Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (pipe_fptr_atexit): clean up popen()'ed fptr.
-
- * error.c (set_syserr): some system has error code that is bigger
- than sys_nerr. grrr.
-
-Mon Sep 8 18:33:33 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_s_new): dereferenced nil for optional mode.
-
-Fri Sep 5 10:26:03 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (class_instance_methods): do not include methods which
- are changed to private in subclasses.
-
-Thu Sep 4 12:38:53 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (f_global_variables): list name of the global
- variables.
-
- * object.c (obj_id): returns unique integer.
-
-Wed Sep 3 14:05:16 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha6 released.
-
- * eval.c (mod_s_constants): context sensitive constant list.
-
- * variable.c (mod_constants): no more `all' option.
-
- * variable.c (mod_const_of): the values for autoload classes are
- their name strings.
-
- * class.c (class_instance_methods): no special treatment for
- singleton classes.
-
- * object.c (obj_singleton_methods): returns list of singleton
- method names.
-
- * parse.y (yylex): no here document after `class' keyword.
-
- * eval.c (f_load): expand path if fname begins with `~'.
-
-Tue Sep 2 13:19:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (ins_methods_i): do not list undef'ed methods.
-
-Mon Sep 1 13:42:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha5 released.
-
- * object.c (mod_attr_reader): create methods to define attribute
- reader/write/accessor.
-
- * class.c (rb_define_attr): always defines accessors.
-
- * eval.c (rb_call): alias occured in the module body caused SEGV.
-
- * parse.y: did not generate here document strings properly.
-
-Mon Sep 1 11:43:57 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (yylex): heredoc dropped an extra character.
-
-Fri Aug 29 11:10:21 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * class.c (class_instance_methods): same method names should not
- appear more than twice.
-
- * parse.y (yylex): spaces can follow =begin/=end.
-
- * variable.c (find_class_path): look for class_tbl also for
- unnamed fundamental classes, such as Object, String, etc.
-
- * variable.c (rb_name_class): can't name class before String class
- is initilialized.
-
- * inits.c (rb_call_inits): unrecognized dependency from GC to
- Array.
-
- * variable.c (find_class_path): could not find class if Object's
- iv_tbl is NULL.
-
-Thu Aug 28 13:12:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha4 released.
-
- * variable.c (mod_constants): wrong condition for singleton
- class.
-
- * parse.y (yylex): revised `=begin' skip code.
-
- * parse.y (here_document): forgot to free(eos).
-
- * parse.y (yylex): spaces after `<<' prohibited for here
- documents to avoid confusing with operator `<<'.
-
- * eval.c (is_defined): separated from rb_eval().
-
-Wed Aug 27 11:32:42 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha3 released.
-
- * variable.c (mod_name): returns name of the class/module.
-
- * parse.y (here_document): finally here document available now.
-
- * variable.c (fc_i): some classes/modules does not have iv_tbl.
-
- * variable.c (find_class_path): avoid inifinite loop.
-
-Tue Aug 26 13:43:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_eval): undef'ing non-existing method will raise
- NameError exception.
-
- * object.c (class_s_new): needed to create metaclass too.
-
- * eval.c (error_print): no class name print for anonymous class.
-
- * eval.c (rb_longjmp): proper exception raised if raise() called
- without arguments, with $! or $@ set.
-
- * object.c (Init_Object): superclass()'s method argument setting
- was wrong again.
-
- * class.c (mod_anscestors): list superclasses and included modules
- in priority order.
-
-Mon Aug 25 11:53:11 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha2 released.
-
- * sample/ruby-mode.el (ruby-parse-region): auto-indent now
- supports "\\" in the strings.
-
- * struct.c (struct_getmember): new API to get member value from C
- language side.
-
-Sat Aug 23 21:39:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (asignable): remove unnecessary local variable
- initialize by nil.
-
-Fri Aug 22 14:26:40 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (error_print): modified exception print format.
-
-Thu Aug 21 16:10:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/ruby-mode.el (ruby-calculate-indent): wrong indent level
- calculated with keyword operators.
-
-Thu Aug 21 11:36:58 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (arg): ary[0] += 1 cause SEGV
-
-Wed Aug 20 17:28:50 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (ruby_process_options): require() all modules after
- processing all options
-
- * process.c (rb_proc_exec): more security checks added.
-
- * process.c (rb_proc_exec): insecure path on exec.
-
- * hash.c (f_getenv): PATH modification security check.
-
-Tue Aug 19 00:15:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha1 released.
-
- * eval.c (mod_eval): work as normal eval() if second binding
- argument given.
-
- * eval.c (rb_call): did not raise ArgumentError if too many
- arguments more than optional arguments (without rest arg).
-
- * eval.c (rb_eval): did not work well for op_asgn2 (attribute
- self assignment).
-
- * eval.c (Init_Thread): returns main thread.
-
-Mon Aug 18 09:25:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (inspect_i): did not display T_DATA instance variables.
-
- * parse.y: provides more accurate line number information.
-
- * eval.c (thread_value): include value's backtrace information in
- the variable `$@'.
-
- * eval.c (f_abort): print backtrace and exit.
-
-Sat Aug 16 00:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (class_new_instance): do not make instance from virtual
- classes.
-
- * object.c (class_s_new): do not make subclass of singleton class.
-
-Fri Aug 15 15:49:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (call_trace_func): block context switch in the trace
- function.
-
- * eval.c (rb_eval): clear method cache at class extention.
-
- * object.c (obj_type): returns object's class even if it defines
- singleton methods.
-
-Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/socket/socket.c (Init_socket): small typo caused SEGV.
-
-Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.1 alpha0 released.
-
diff --git a/GPL b/GPL
new file mode 100644
index 0000000000..d159169d10
--- /dev/null
+++ b/GPL
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/KNOWNBUGS.rb b/KNOWNBUGS.rb
new file mode 100644
index 0000000000..35a8e75876
--- /dev/null
+++ b/KNOWNBUGS.rb
@@ -0,0 +1,7 @@
+#
+# IMPORTANT: Always keep the first 7 lines (comments),
+# even if this file is otherwise empty.
+#
+# This test file includes tests which point out known bugs.
+# So all tests will cause failure.
+#
diff --git a/LEGAL b/LEGAL
new file mode 100644
index 0000000000..0479751691
--- /dev/null
+++ b/LEGAL
@@ -0,0 +1,850 @@
+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
+
+ These files are licensed under the CC0.
+
+ https://creativecommons.org/choose/zero/
+
+ccan/list/list.h
+
+ This file is licensed under the MIT License.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+include/ruby/onigmo.h:
+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
+
+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/trans/GB/GB12345%UCS.src:
+enc/trans/GB/UCS%GB12345.src:
+enc/trans/GB/GB2312%UCS.src:
+enc/trans/GB/UCS%GB2312.src:
+
+ 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.
+ Please note that Unicode, Inc. never made any claims as to fitness of these
+ 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:
+
+ © 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:
+
+ 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:
+
+ 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:
+
+ This file is free software.
+
+ Copyright (C) 1992, 93, 94, 95, 96 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:
+
+ 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.
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ As a special exception to the GNU General Public License, if you
+ distribute this file as part of a program that contains a
+ configuration script generated by Autoconf, you may include it under
+ the same distribution terms that you use for the rest of that program.
+
+parse.c:
+
+ This file is licensed under the GPL, but is 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.
+
+ 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 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. */
+
+ /* 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. */
+
+util.c (partly):
+
+ 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.
+
+win32/win32.[ch]:
+
+ You can apply the Artistic License to these files. (or GPL,
+ alternatively)
+
+ 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
+
+ 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.
+ 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.
+
+ 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
+
+ The Wayback Machine url: http://web.archive.org/web/19990429082237/http://www.math.keio.ac.jp/matumoto/emt.html
+
+vm_dump.c:procstat_vm
+
+ This file is under the new-style BSD license.
+
+ 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
+ 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.
+
+ $FreeBSD: head/usr.bin/procstat/procstat_vm.c 261780 2014-02-11 21:57:37Z jhb $
+
+vsnprintf.c:
+
+ This file is under the old-style BSD license. Note that the
+ paragraph 3 below is now null and void.
+
+ 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:
+
+ These files are all under public domain.
+
+missing/crypt.c:
+
+ This file is under the old-style BSD license. Note that the
+ paragraph 3 below is now null and void.
+
+ 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
+
+ This file is under the old-style BSD license. Note that the
+ paragraph 3 below is now null and void.
+
+ 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
+
+ These files are under an ISC-style license.
+
+ 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
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+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.
+
+ext/digest/md5/md5.[ch]:
+
+ These files are under the following license. Ruby uses modified
+ versions of them.
+
+ 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ext/digest/rmd160/rmd160.[ch]:
+
+ 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
+ (Arranged for libc by Todd C. Miller)
+ DATE: 1 March 1996
+
+ Copyright (c) Katholieke Universiteit Leuven
+ 1996, All Rights Reserved
+
+ext/digest/sha2/sha2.[ch]:
+
+ These files are under the new-style BSD license.
+
+ 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
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holder nor the names of contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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(S) OR CONTRIBUTOR(S) 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.
+
+ext/json/generator/generator.c:
+
+ Copyright 2001-2004 Unicode, Inc.
+
+ 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.
+
+ 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.
+
+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:
+
+ These files are under the new-style BSD license.
+
+ Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ 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 project 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 PROJECT 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 PROJECT 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.
+
+ext/win32ole/win32ole.c:
+
+ You can apply the Artistic License to this file. (or GPL,
+ alternatively)
+
+ (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
+ <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.
+
+ The Wayback Machine url: http://web.archive.org/web/19970607104352/http://www.activeware.com:80/
+
+lib/rdoc/generator/template/darkfish/css/fonts.css:
+
+ This file is licensed under the SIL Open Font License.
+
+ http://scripts.sil.org/OFL
+
+spec/mspec:
+spec/ruby:
+
+ 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
+ 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.
+
+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:
+
+ 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.
diff --git a/MANIFEST b/MANIFEST
deleted file mode 100644
index 95dc640c53..0000000000
--- a/MANIFEST
+++ /dev/null
@@ -1,237 +0,0 @@
-COPYING
-ChangeLog
-MANIFEST
-Makefile.in
-README
-README.jp
-README.EXT
-README.EXT.jp
-ToDo
-array.c
-bignum.c
-class.c
-compar.c
-configure
-configure.bat
-configure.in
-config_h.dj
-config_s.dj
-config.guess
-config.sub
-defines.h
-dir.c
-dln.c
-dln.h
-dmyext.c
-enum.c
-env.h
-error.c
-eval.c
-file.c
-fnmatch.c
-fnmatch.h
-gc.c
-glob.c
-hash.c
-inits.c
-install-sh
-instruby.rb
-intern.h
-io.c
-keywords
-lex.c
-main.c
-marshal.c
-math.c
-mkconfig.rb
-node.h
-numeric.c
-object.c
-pack.c
-parse.c
-parse.y
-process.c
-random.c
-range.c
-re.c
-re.h
-regex.c
-regex.h
-ruby.1
-ruby.c
-ruby.h
-rubyio.h
-rubysig.h
-rubytest.rb
-signal.c
-sprintf.c
-st.c
-st.h
-string.c
-struct.c
-time.c
-top.sed
-util.h
-util.c
-variable.c
-version.c
-version.h
-beos/ruby.def.in
-ext/Setup
-ext/Setup.dj
-ext/Setup.nt
-ext/Setup.x68
-ext/aix_ld.rb
-ext/cygwin32_ld.rb
-ext/extmk.rb.in
-ext/extmk.rb.nt
-lib/English.rb
-lib/Env.rb
-lib/README
-lib/base64.rb
-lib/cgi-lib.rb
-lib/complex.rb
-lib/date.rb
-lib/date2.rb
-lib/debug.rb
-lib/delegate.rb
-lib/e2mmap.rb
-lib/eregex.rb
-lib/find.rb
-lib/final.rb
-lib/finalize.rb
-lib/ftplib.rb
-lib/ftools.rb
-lib/getopts.rb
-lib/importenv.rb
-lib/jcode.rb
-lib/mailread.rb
-lib/mathn.rb
-lib/matrix.rb
-lib/mkmf.rb
-lib/monitor.rb
-lib/mutex_m.rb
-lib/observer.rb
-lib/open3.rb
-lib/ostruct.rb
-lib/parsearg.rb
-lib/parsedate.rb
-lib/ping.rb
-lib/pstore.rb
-lib/rational.rb
-lib/readbytes.rb
-lib/shell.rb
-lib/shellwords.rb
-lib/singleton.rb
-lib/sync.rb
-lib/telnet.rb
-lib/tempfile.rb
-lib/thread.rb
-lib/thwait.rb
-lib/timeout.rb
-lib/tk.rb
-lib/tkafter.rb
-lib/tkbgerror.rb
-lib/tkcanvas.rb
-lib/tkclass.rb
-lib/tkdialog.rb
-lib/tkentry.rb
-lib/tkfont.rb
-lib/tkmenubar.rb
-lib/tkmngfocus.rb
-lib/tkpalette.rb
-lib/tkscrollbox.rb
-lib/tktext.rb
-lib/tkvirtevent.rb
-lib/tracer.rb
-lib/weakref.rb
-missing/alloca.c
-missing/crypt.c
-missing/dir.h
-missing/dup2.c
-missing/file.h
-missing/flock.c
-missing/memcmp.c
-missing/memmove.c
-missing/mkdir.c
-missing/nt.c
-missing/nt.h
-missing/setenv.c
-missing/strcasecmp.c
-missing/strchr.c
-missing/strdup.c
-missing/strerror.c
-missing/strftime.c
-missing/strstr.c
-missing/strtol.c
-missing/strtoul.c
-missing/vsnprintf.c
-missing/x68.c
-sample/README
-sample/biorhythm.rb
-sample/cal.rb
-sample/cbreak.rb
-sample/clnt.rb
-sample/dbmtest.rb
-sample/dir.rb
-sample/eval.rb
-sample/export.rb
-sample/exyacc.rb
-sample/fact.rb
-sample/fib.awk
-sample/fib.pl
-sample/fib.py
-sample/fib.rb
-sample/fib.scm
-sample/freq.rb
-sample/from.rb
-sample/fullpath.rb
-sample/getopts.test
-sample/goodfriday.rb
-sample/inf-ruby.el
-sample/less.rb
-sample/list.rb
-sample/list2.rb
-sample/list3.rb
-sample/mine.rb
-sample/mkproto.rb
-sample/mpart.rb
-sample/mrshtest.rb
-sample/observ.rb
-sample/occur.pl
-sample/occur.rb
-sample/occur2.rb
-sample/philos.rb
-sample/pi.rb
-sample/rbc.rb
-sample/rcs.awk
-sample/rcs.dat
-sample/rcs.rb
-sample/regx.rb
-sample/ruby-mode.el
-sample/rubydb2x.el
-sample/rubydb3x.el
-sample/sieve.rb
-sample/svr.rb
-sample/test.rb
-sample/time.rb
-sample/tkbiff.rb
-sample/tkbrowse.rb
-sample/tkdialog.rb
-sample/tkfrom.rb
-sample/tkhello.rb
-sample/tkline.rb
-sample/tktimer.rb
-sample/trojan.rb
-sample/tsvr.rb
-sample/uumerge.rb
-win32/Makefile
-win32/config.h
-win32/ntsetup.bat
-win32/ruby.def
-win32/sdbm.c
-win32/sdbm.h
-x68/fconvert.c
-x68/select.c
-x68/_dtos18.c
-x68/_round.c
diff --git a/Makefile.in b/Makefile.in
index f3ac3dd890..25075f5900 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,225 +1,531 @@
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@
-VPATH = @srcdir@:@srcdir@/missing
+top_srcdir = $(srcdir)
+hdrdir = $(srcdir)/include
+PLATFORM_DIR = @PLATFORM_DIR@
CC = @CC@
-YACC = @YACC@
+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@
-CFLAGS = @CFLAGS@ -I. -I@srcdir@ -I@includedir@
+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@
-EXTLIBS =
+EXTLDFLAGS = @EXTLDFLAGS@
+XLDFLAGS = @XLDFLAGS@ $(EXTLDFLAGS)
+EXTLIBS =
LIBS = @LIBS@ $(EXTLIBS)
MISSING = @LIBOBJS@ @ALLOCA@
-LDSHARED = @LDSHARED@
-DLDFLAGS = @DLDFLAGS@
+ENABLE_SHARED = @ENABLE_SHARED@
+LDSHARED = @LIBRUBY_LDSHARED@
+DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(XLDFLAGS) $(ARCH_FLAG)
SOLIBS = @SOLIBS@
-
-binsuffix = @binsuffix@
+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_SONAME= @LIBRUBY_SONAME@
+LIBRUBY_ALIASES= @LIBRUBY_ALIASES@
LIBRUBY = @LIBRUBY@
LIBRUBYARG = @LIBRUBYARG@
-
-EXTOBJS =
-
-MAINOBJ = main.o
-
-OBJS = array.o \
- bignum.o \
- class.o \
- compar.o \
- dir.o \
- dln.o \
- enum.o \
- error.o \
- eval.o \
- file.o \
- fnmatch.o \
- gc.o \
- glob.o \
- hash.o \
- inits.o \
- io.o \
- marshal.o \
- math.o \
- numeric.o \
- object.o \
- pack.o \
- parse.o \
- process.o \
- random.o \
- range.o \
- re.o \
- regex.o \
- ruby.o \
- signal.o \
- sprintf.o \
- st.o \
- string.o \
- struct.o \
- time.o \
- util.o \
- variable.o \
- version.o \
- $(MISSING)
-
-all: miniruby$(binsuffix) rbconfig.rb
- @./miniruby$(binsuffix) -Xext extmk.rb @EXTSTATIC@
-
-miniruby$(binsuffix): $(OBJS) $(MAINOBJ) dmyext.o
- @rm -f $@
- $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) dmyext.o $(LIBS) -o $@
-
-ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS)
- @rm -f $@
- $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
-
-libruby.a: $(OBJS) dmyext.o
- @AR@ rcu $@ $(OBJS) dmyext.o
- @-@RANLIB@ $@ 2> /dev/null || true
-
-libruby.so: $(OBJS) dmyext.o
- $(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.o -o $@
-
-install: rbconfig.rb
- ./miniruby$(binsuffix) $(srcdir)/instruby.rb
-
-clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb
- @rm -f ext/extinit.c ext/extinit.o dmyext.o
- @if test -f ./miniruby$(binsuffix); then \
- ./miniruby$(binsuffix) -Xext extmk.rb clean; \
- fi
-
-distclean: clean
- @rm -f Makefile ext/extmk.rb config.h
- @rm -f ext/config.cache config.cache config.log config.status
- @rm -f parse.c *~ core *.core gmon.out y.tab.c y.output
- @rm -f ruby$(binsuffix) miniruby$(binsuffix)
-
-realclean: distclean
- @rm -f lex.c
-
-test: miniruby$(binsuffix)
- @./miniruby$(binsuffix) $(srcdir)/rubytest.rb
-
-rbconfig.rb: config.status miniruby$(binsuffix)
- @./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb
-
-.c.o:
- $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
-
-lex.c: keywords
- gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ @srcdir@/keywords > lex.c
-
-parse.c: parse.y
- $(YACC) $<
- mv -f y.tab.c parse.c
-
-alloca.o: @srcdir@/missing/alloca.c
- $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/alloca.c
-
-crypt.o: @srcdir@/missing/crypt.c
- $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/crypt.c
-
-dup2.o: @srcdir@/missing/dup2.c
- $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/dup2.c
-
-flock.o: @srcdir@/missing/flock.c
- $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c
-
-memcmp.o: @srcdir@/missing/memcmp.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memcmp.c
-
-memmove.o: @srcdir@/missing/memmove.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memmove.c
-
-mkdir.o: @srcdir@/missing/mkdir.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/mkdir.c
-
-setenv.o: @srcdir@/missing/setenv.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/setenv.c
-
-vsnprintf.o: @srcdir@/missing/vsnprintf.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/vsnprintf.c
-
-strcasecmp.o: @srcdir@/missing/strcasecmp.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strcasecmp.c
-
-strchr.o: @srcdir@/missing/strchr.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strchr.c
-
-strdup.o: @srcdir@/missing/strdup.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strdup.c
-
-strerror.o: @srcdir@/missing/strerror.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strerror.c
-
-strftime.o: @srcdir@/missing/strftime.c
- $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strftime.c
-
-strstr.o: @srcdir@/missing/strstr.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strstr.c
-
-strtol.o: @srcdir@/missing/strtol.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strtol.c
-
-strtoul.o: @srcdir@/missing/strtoul.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strtoul.c
-
-nt.o: @srcdir@/missing/nt.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/nt.c
-
-x68.o: @srcdir@/missing/x68.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/x68.c
+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
+SOEXT = @SOEXT@
+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:
-###
-parse.o: parse.y ruby.h config.h defines.h intern.h env.h node.h st.h regex.h util.h lex.c
-###
-array.o: array.c ruby.h config.h defines.h intern.h
-bignum.o: bignum.c ruby.h config.h defines.h intern.h
-class.o: class.c ruby.h config.h defines.h intern.h node.h st.h
-compar.o: compar.c ruby.h config.h defines.h intern.h
-dir.o: dir.c ruby.h config.h defines.h intern.h
-dln.o: dln.c config.h defines.h dln.h
-dmyext.o: dmyext.c
-enum.o: enum.c ruby.h config.h defines.h intern.h
-error.o: error.c ruby.h config.h defines.h intern.h env.h
-eval.o: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dln.h
-file.o: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
-fnmatch.o: fnmatch.c config.h fnmatch.h
-gc.o: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
-glob.o: config.h glob.c fnmatch.h
-hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h
-inits.o: inits.c ruby.h config.h defines.h intern.h
-io.o: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
-main.o: main.c ruby.h config.h defines.h intern.h
-marshal.o: marshal.c ruby.h config.h defines.h intern.h rubyio.h st.h
-math.o: math.c ruby.h config.h defines.h intern.h
-numeric.o: numeric.c ruby.h config.h defines.h intern.h
-object.o: object.c ruby.h config.h defines.h intern.h st.h
-pack.o: pack.c ruby.h config.h defines.h intern.h
-process.o: process.c ruby.h config.h defines.h intern.h rubysig.h st.h
-random.o: random.c ruby.h config.h defines.h intern.h
-range.o: range.c ruby.h config.h defines.h intern.h
-re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h
-regex.o: regex.c config.h regex.h util.h
-ruby.o: ruby.c ruby.h config.h defines.h intern.h dln.h
-signal.o: signal.c ruby.h config.h defines.h intern.h rubysig.h
-sprintf.o: sprintf.c ruby.h config.h defines.h intern.h
-st.o: st.c config.h st.h
-string.o: string.c ruby.h config.h defines.h intern.h re.h regex.h
-struct.o: struct.c ruby.h config.h defines.h intern.h
-time.o: time.c ruby.h config.h defines.h intern.h
-util.o: util.c ruby.h config.h defines.h intern.h util.h
-variable.o: variable.c ruby.h config.h defines.h intern.h env.h node.h st.h
-version.o: version.c ruby.h config.h defines.h intern.h version.h
+
+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_*' -L '$(SYMBOL_PREFIX)*_ec_*' $@
+ $(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 -f $(srcdir)/tool/gperf.sed \
+ > $@.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 -f $(srcdir)/tool/gperf.sed > $@ && \
+ $(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-bundled-gems-run:
+ $(Q) set -e; while read gem _; do \
+ echo testing $$gem gem && \
+ $(XRUBY) -C $(srcdir)/gems/src/$$gem -Ilib ../../../.bundle/bin/rake; \
+ done < $(srcdir)/gems/bundled_gems
+
+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
new file mode 100644
index 0000000000..e1b91f38b7
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,577 @@
+# -*- 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?,all?,none?,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 rb_stat()-using methods release GVL
+ [Bug #13941]
+ * File.rename releases GVL [Feature #13951]
+ * File::Stat#{atime,mtime,ctime} support fractional second timestamps on
+ Windows 8 and later [Feature #13726]
+ * File::Stat#ino and File.indentical? 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]
+
+* Exception
+
+ * Exception#full_message takes :highlight and :order options [Bug #14324]
+
+* 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#step no longer hides errors from coerce method when
+ given a step value which cannot be compared with #> to 0.
+ [Feature #7688]
+ * Integer#{round,floor,ceil,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,attr_accessor,attr_reader,attr_writer} become public [Feature #14132]
+ * Module#{define_method,alias_method,undef_method,remove_method} become public [Feature #14133]
+
+* Numeric
+
+ * 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
+
+ * 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?} 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,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,entrywise_product}
+
+* Net::HTTP
+
+ * Net::HTTP.new supports no_proxy parameter [Feature #11195]
+ * Net::HTTP#{min_version,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,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.
+
+=== C API updates
+
+=== 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 which runs 2 times faster than 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/README b/README
deleted file mode 100644
index 47012a3cb2..0000000000
--- a/README
+++ /dev/null
@@ -1,132 +0,0 @@
-* 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.
-
-* Features of Ruby
-
- + Simple Syntax
- + *Normal* Object-Oriented features(ex. class, method calls)
- + *Advanced* Object-Oriented features(ex. Mix-in, Singleton-method)
- + Operator Overloading
- + Exception Handling
- + Iterators and Closures
- + Garbage Collection
- + Dynamic Loading of Object files(on some architecture)
- + Highly Portable(works on many UNIX machines)
-
-* How to get Ruby
-
-The Ruby distribution can be found on
-
- ftp://ftp.netlab.co.jp/pub/lang/ruby/
-
-* How to compile and install
-
-This is what you need to do to compile and install Ruby:
-
- 1. Run ./configure, which will generate config.h and Makefile.
-
- 2. Edit defines.h if you need. Probably this step will not need.
-
- 3. Remove comment mark(#) before the module names from ext/Setup (or
- add module names if not present), if you want to link modules
- statically.
-
- If you don't want to compile non static extension modules
- (probably on architectures which does not allow dynamic loading),
- remove comment mark from the line "#option nodynamic" in
- ext/Setup.
-
- 4. Run make.
-
- 5. Optionally, run 'make test' to check whether the compiled Ruby
- interpreter works well. If you see the message "test succeeded",
- your ruby works as it should (hopefully).
-
- 6. Run 'make install'
-
- 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 error log and machine/OS type, to help others.
-
-* Copying
-
-Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
-You can redistribute it and/or modify it under either the terms of the GPL
-(see COPYING file), 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) rename any non-standard executables so the names do not conflict
- with standard executables, which must also be provided.
-
- 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). But some files in the distribution
- are not written by the author, so that they are not under this terms.
- They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
- glob.c, st.[ch] and some files under the ./missing directory. See
- each file for the copying condition.
-
- 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- PURPOSE.
-
-* Ruby home-page
-
-The URL of the Ruby home-page is:
-
- http://www.netlab.co.jp/ruby/
-
-* The Author
-
-Feel free to send comments and bug reports to the author. Here is the
-author's latest mail address:
-
- matz@netlab.co.jp
-
--------------------------------------------------------
-created at: Thu Aug 3 11:57:36 JST 1995
-Local variables:
-mode: indented-text
-end:
diff --git a/README.EXT b/README.EXT
index fb041bca9b..48b8d964c4 100644
--- a/README.EXT
+++ b/README.EXT
@@ -1,1060 +1 @@
-.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
-
-This document explains how to make extention modules for Ruby.
-
-1¡¥Basic knowledge
-
-In C, variables have types and data do not have types. In contrast,
-Ruby variables do not have static type and data themselves have
-types. So, data need to be converted across the languages.
-
-Data in Ruby represented C type `VALUE'. Each VALUE data have its
-data-type.
-
-To retrieve an C data from the VALUE, you need to:
-
- (1) Identify VALUE's data type
- (2) Convert VALUE into C data
-
-Converting to wrong data type may cause serious promblems.
-
-
-1.1 Data-types
-
-Ruby interpreter has data-types as below:
-
- T_NIL nil
- T_OBJECT ordinaly object
- T_CLASS class
- T_MODULE module
- T_FLOAT floating point number
- T_STRING string
- T_REGEXP regular expression
- T_ARRAY array
- T_FIXNUM Fixnum(31bit integer)
- T_HASH assosiative array
- T_STRUCT (Ruby) structure
- T_BIGNUM multi precision integer
- T_TRUE true
- T_FALSE false
- T_DATA data
-
-Otherwise, there are several other types used internally:
-
- T_ICLASS
- T_MATCH
- T_VARMAP
- T_SCOPE
- T_NODE
-
-Most of the types are represented by C structures.
-
-1.2 Check Data Type of the VALUE
-
-The macro TYPE() defined in ruby.h shows data-type of the VALUE.
-TYPE() returns the constant number T_XXXX described above. To handle
-data-types, the code will be like:
-
- switch (TYPE(obj)) {
- case T_FIXNUM:
- /* process Fixnum */
- break;
- case T_STRING:
- /* process String */
- break;
- case T_ARRAY:
- /* process Array */
- break;
- default:
- /* raise exception */
- Fail("not valid value");
- break;
- }
-
-There is the data-type check function.
-
- void Check_Type(VALUE value, int type)
-
-It raises an exception, if the VALUE does not have the type specified.
-
-There are faster check-macros for fixnums and nil.
-
- FIXNUM_P(obj)
- NIL_P(obj)
-
-1.3 Convert VALUE into C data
-
-¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_NIL, T_FALSE, T_TRUE¤Ç¤¢¤ë»þ¡¤¥Ç¡¼¥¿¤Ï¤½¤ì¤¾
-¤ìnil, false, true¤Ç¤¹¡¥¤³¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ï¤Ò¤È
-¤Ä¤º¤Ä¤·¤«Â¸ºß¤·¤Þ¤»¤ó¡¥
-
-¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_FIXNUM¤Î»þ¡¤¤³¤ì¤Ï31bit¤Î¥µ¥¤¥º¤ò»ý¤ÄÀ°¿ô¤Ç
-¤¹¡¥FIXNUM¤òC¤ÎÀ°¿ô¤ËÊÑ´¹¤¹¤ë¤¿¤á¤Ë¤Ï¥Þ¥¯¥í¡ÖFIX2INT()¡×¤ò»È
-¤¤¤Þ¤¹¡¥¤½¤ì¤«¤é¡¤FIXNUM¤Ë¸Â¤é¤ºRuby¤Î¥Ç¡¼¥¿¤òÀ°¿ô¤ËÊÑ´¹¤¹¤ë
-¡ÖNUM2INT()¡×¤È¤¤¤¦¥Þ¥¯¥í¤¬¤¢¤ê¤Þ¤¹¡¥¤³¤Î¥Þ¥¯¥í¤Ï¥Ç¡¼¥¿¥¿¥¤
-¥×¤Î¥Á¥§¥Ã¥¯Ìµ¤·¤Ç»È¤¨¤Þ¤¹(À°¿ô¤ËÊÑ´¹¤Ç¤­¤Ê¤¤¾ì¹ç¤Ë¤ÏÎã³°¤¬
-ȯÀ¸¤¹¤ë)¡¥
-
-¤½¤ì°Ê³°¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ÏÂбþ¤¹¤ëC¤Î¹½Â¤ÂΤ¬¤¢¤ê¤Þ¤¹¡¥Âбþ¤¹
-¤ë¹½Â¤ÂΤΤ¢¤ëVALUE¤Ï¤½¤Î¤Þ¤Þ¥­¥ã¥¹¥È(·¿ÊÑ´¹)¤¹¤ì¤Ð¹½Â¤ÂΤÎ
-¥Ý¥¤¥ó¥¿¤ËÊÑ´¹¤Ç¤­¤Þ¤¹¡¥
-
-¹½Â¤ÂΤϡÖstruct RXxxxx¡×¤È¤¤¤¦Ì¾Á°¤Çruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ
-¤¹¡¥Î㤨¤Ðʸ»úÎó¤Ï¡Östruct RString¡×¤Ç¤¹¡¥¼ÂºÝ¤Ë»È¤¦²ÄǽÀ­¤¬
-¤¢¤ë¤Î¤Ïʸ»úÎó¤ÈÇÛÎ󤯤餤¤À¤È»×¤¤¤Þ¤¹¡¥
-
-ruby.h¤Ç¤Ï¹½Â¤ÂΤإ­¥ã¥¹¥È¤¹¤ë¥Þ¥¯¥í¤â¡ÖRXXXXX()¡×(Á´ÉôÂçʸ
-»ú¤Ë¤·¤¿¤â¤Î)¤È¤¤¤¦Ì¾Á°¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹(Îã: RSTRING())¡¥
-
-Î㤨¤Ð¡¤Ê¸»úÎóstr¤ÎŤµ¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->len¡×¤È
-¤·¡¤Ê¸»úÎóstr¤òchar*¤È¤·¤ÆÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->ptr¡×
-¤È¤·¤Þ¤¹¡¥ÇÛÎó¤Î¾ì¹ç¤Ë¤Ï¡¤¤½¤ì¤¾¤ì¡ÖRARRAT(str)->len¡×¡¤
-¡ÖRARRAT(str)->ptr¡×¤È¤Ê¤ê¤Þ¤¹¡¥
-
-Ruby¤Î¹½Â¤ÂΤòľÀÜ¥¢¥¯¥»¥¹¤¹¤ë»þ¤Ëµ¤¤ò¤Ä¤±¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³
-¤È¤Ï¡¤ÇÛÎó¤äʸ»úÎó¤Î¹½Â¤ÂΤÎÃæ¿È¤Ï»²¾È¤¹¤ë¤À¤±¤Ç¡¤Ä¾ÀÜÊѹ¹¤·
-¤Ê¤¤¤³¤È¤Ç¤¹¡¥Ä¾ÀÜÊѹ¹¤·¤¿¾ì¹ç¡¤¥ª¥Ö¥¸¥§¥¯¥È¤ÎÆâÍÆ¤ÎÀ°¹çÀ­¤¬
-¤È¤ì¤Ê¤¯¤Ê¤Ã¤Æ¡¤»×¤ï¤Ì¥Ð¥°¤Î¸¶°ø¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-1.4 Convert C data into VALUE
-
-VALUE¤Î¼ÂºÝ¤Î¹½Â¤¤Ï
-
- * FIXNUM¤Î¾ì¹ç
-
- 1bit±¦¥·¥Õ¥È¤·¤Æ¡¤LSB¤òΩ¤Æ¤ë¡¥
-
- * ¤½¤Î¾¤Î¥Ý¥¤¥ó¥¿¤Î¾ì¹ç
-
- ¤½¤Î¤Þ¤ÞVALUE¤Ë¥­¥ã¥¹¥È¤¹¤ë¡¥
-
-¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥¤è¤Ã¤Æ¡¤LSB¤ò¥Á¥§¥Ã¥¯¤¹¤ì¤ÐVALUE¤¬FIXNUM¤«¤É
-¤¦¤«¤ï¤«¤ë¤ï¤±¤Ç¤¹(¥Ý¥¤¥ó¥¿¤ÎLSB¤¬Î©¤Ã¤Æ¤¤¤Ê¤¤¤³¤È¤ò²¾Äꤷ¤Æ
-¤¤¤ë)¡¥
-
-¤Ç¤¹¤«¤é¡¤FIXNUM°Ê³°¤ÎRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î¹½Â¤ÂΤÏñ¤ËVALUE
-¤Ë¥­¥ã¥¹¥È¤¹¤ë¤À¤±¤ÇVALUE¤ËÊÑ´¹½ÐÍè¤Þ¤¹¡¥¤¿¤À¤·¡¤Ç¤°Õ¤Î¹½Â¤
-ÂΤ¬VALUE¤Ë¥­¥ã¥¹¥È½ÐÍè¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥¥­¥ã¥¹¥È¤¹¤ë¤Î
-¤ÏRuby¤ÎÃΤäƤ¤¤ë¹½Â¤ÂÎ(ruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëstruct RXxxx
-¤Î¤â¤Î)¤À¤±¤Ë¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡¥
-
-FIXNUM¤Ë´Ø¤·¤Æ¤ÏÊÑ´¹¥Þ¥¯¥í¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥C¤ÎÀ°¿ô
-¤«¤éVALUE¤ËÊÑ´¹¤¹¤ë¥Þ¥¯¥í¤Ï°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡¥É¬Íפ˱þ¤¸
-¤Æ»È¤¤Ê¬¤±¤Æ¤¯¤À¤µ¤¤¡¥
-
- INT2FIX() ¤â¤È¤ÎÀ°¿ô¤¬31bit°ÊÆâ¤Ë¼ý¤Þ¤ë»þ
- INT2NUM() Ǥ°Õ¤ÎÀ°¿ô¤«¤éVALUE¤Ø
-
-INT2NUM()¤ÏÀ°¿ô¤¬FIXNUM¤ÎÈϰϤ˼ý¤Þ¤é¤Ê¤¤¾ì¹ç¡¤Bignum¤ËÊÑ´¹
-¤·¤Æ¤¯¤ì¤Þ¤¹(¤¬¡¤¾¯¤·ÃÙ¤¤)¡¥
-
-1.5 Manipulate Ruby data
-
-ÀèÄø¤â½Ò¤Ù¤¿Ä̤ꡤRuby¤Î¹½Â¤ÂΤò¥¢¥¯¥»¥¹¤¹¤ë»þ¤ËÆâÍÆ¤Î¹¹¿·¤ò
-¹Ô¤¦¤³¤È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥¤Ç¡¤Ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë»þ¤Ë¤Ï
-Ruby¤¬ÍѰդ·¤Æ¤¤¤ë´Ø¿ô¤òÍѤ¤¤Æ¤¯¤À¤µ¤¤¡¥
-
-¤³¤³¤Ç¤Ï¤â¤Ã¤È¤â»È¤ï¤ì¤ë¤Ç¤¢¤í¤¦Ê¸»úÎó¤ÈÇÛÎó¤ÎÀ¸À®/Áàºî¤ò¹Ô
-¤¤´Ø¿ô¤ò¤¢¤²¤Þ¤¹(Á´Éô¤Ç¤Ï¤Ê¤¤¤Ç¤¹)¡¥
-
- String funtions
-
- str_new(char *ptr, int len)
-
- Creates a new Ruby string.
-
- str_new2(char *ptr)
-
- Creates a new Ruby string from C string. This is equivalent to
- str_new(ptr, strlen(ptr)).
-
- str_cat(VALUE str, char *ptr, int len)
-
- Appends len bytes data from ptr to the Ruby string.
-
- Array functions
-
- ary_new()
-
- Creates an array with no element.
-
- ary_new2(int len)
-
- Creates an array with no element, with allocating internal buffer
- for len elements.
-
- ary_new3(int n, ...)
-
- Creates an n-elements array from arguments.
-
- ary_new4(int n, VALUE *elts)
-
- Creates an n-elements array from C array.
-
- ary_push(VALUE ary, VALUE val)
- ary_pop(VALUE ary)
- ary_shift(VALUE ary)
- ary_unshift(VALUE ary, VALUE val)
- ary_entry(VALUE ary, int idx)
-
- Array operations. The first argument to each functions must be an
- array. They may dump core if other types given.
-
-2. Extend Ruby with C
-
-¸¶ÍýŪ¤ËRuby¤Ç½ñ¤±¤ë¤³¤È¤ÏC¤Ç¤â½ñ¤±¤Þ¤¹¡¥Ruby¤½¤Î¤â¤Î¤¬C¤Çµ­
-½Ò¤µ¤ì¤Æ¤¤¤ë¤ó¤Ç¤¹¤«¤é¡¤ÅöÁ³¤È¤¤¤¨¤ÐÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¥¤³¤³¤Ç
-¤ÏRuby¤Î³ÈÄ¥¤Ë»È¤¦¤³¤È¤¬Â¿¤¤¤À¤í¤¦¤Èͽ¬¤µ¤ì¤ëµ¡Ç½¤òÃæ¿´¤Ë¾Ò
-²ð¤·¤Þ¤¹¡¥
-
-2.1 Add new features to Ruby
-
-Ruby¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤¨¤ÐRuby¥¤¥ó¥¿¥×¥ê¥¿¤Ë¿·¤·¤¤µ¡Ç½
-¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡¥Ruby¤Ç¤Ï°Ê²¼¤Îµ¡Ç½¤òÄɲä¹¤ë´Ø¿ô¤¬
-Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- * ¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë
- * ¥á¥½¥Ã¥É¡¤ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É
- * Äê¿ô
-
-¤Ç¤Ï½ç¤Ë¾Ò²ð¤·¤Þ¤¹¡¥
-
-2.1.1 Class/module definition
-
-¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- VALUE rb_define_class(char *name, VALUE super)
- VALUE rb_define_module(char *name)
-
-¤³¤ì¤é¤Î´Ø¿ô¤Ï¿·¤·¤¯ÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÊÖ¤·¤Þ¤¹¡¥
-¥á¥½¥Ã¥É¤äÄê¿ô¤ÎÄêµÁ¤Ë¤³¤ì¤é¤ÎÃͤ¬É¬ÍפʤΤǡ¤¤Û¤È¤ó¤É¤Î¾ì¹ç
-¤ÏÌá¤êÃͤòÊÑ¿ô¤Ë³ÊǼ¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡¥
-
-2.1.2 Method/singleton method definition
-
-¥á¥½¥Ã¥É¤äÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- void rb_define_method(VALUE class, char *name,
- VALUE (*func)(), int argc)
-
- void rb_define_singleton_method(VALUE object, char *name,
- VALUE (*func)(), int argc)
-
-
-ǰ¤Î¤¿¤áÀâÌÀ¤¹¤ë¤È¡ÖÆÃ°Û¥á¥½¥Ã¥É¡×¤È¤Ï¡¤¤½¤ÎÆÃÄê¤Î¥ª¥Ö¥¸¥§¥¯
-¥È¤ËÂФ·¤Æ¤À¤±Í­¸ú¤Ê¥á¥½¥Ã¥É¤Ç¤¹¡¥Ruby¤Ç¤Ï¤è¤¯Smalltalk¤Ë¤ª
-¤±¤ë¥¯¥é¥¹¥á¥½¥Ã¥É¤È¤·¤Æ¡¤¥¯¥é¥¹¤ËÂФ¹¤ëÆÃ°Û¥á¥½¥Ã¥É¤¬»È¤ï¤ì
-¤Þ¤¹¡¥
-
-¤³¤ì¤é¤Î´Ø¿ô¤Î argc¤È¤¤¤¦°ú¿ô¤ÏC¤Î´Ø¿ô¤ØÅϤµ¤ì¤ë°ú¿ô¤Î¿ô(¤È
-·Á¼°)¤ò·è¤á¤Þ¤¹¡¥argc¤¬Àµ¤Î»þ¤Ï´Ø¿ô¤Ë°ú¤­ÅϤ¹°ú¿ô¤Î¿ô¤ò°ÕÌ£
-¤·¤Þ¤¹¡¥16¸Ä°Ê¾å¤Î°ú¿ô¤Ï»È¤¨¤Þ¤»¤ó(¤¬¡¤Íפê¤Þ¤»¤ó¤è¤Í¡¤¤½¤ó
-¤Ê¤Ë)¡¥
-
-argc¤¬Éé¤Î»þ¤Ï°ú¿ô¤Î¿ô¤Ç¤Ï¤Ê¤¯¡¤·Á¼°¤ò»ØÄꤷ¤¿¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-argc¤¬-1¤Î»þ¤Ï°ú¿ô¤òÇÛÎó¤ËÆþ¤ì¤ÆÅϤµ¤ì¤Þ¤¹¡¥argc¤¬-2¤Î»þ¤Ï°ú
-¿ô¤ÏRuby¤ÎÇÛÎó¤È¤·¤ÆÅϤµ¤ì¤Þ¤¹¡¥
-
-¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï¤â¤¦Æó¤Ä¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ïprivate¥á
-¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ç¡¤°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¤Ç¤¹¡¥
-
- void rb_define_private_method(VALUE class, char *name,
- VALUE (*func)(), int argc)
-
-private¥á¥½¥Ã¥É¤È¤Ï´Ø¿ô·Á¼°¤Ç¤·¤«¸Æ¤Ó½Ð¤¹¤³¤È¤Î½ÐÍè¤Ê¤¤¥á¥½¥Ã
-¥É¤Ç¤¹¡¥
-
-¤â¤¦¤Ò¤È¤Ä¤Ï¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô
-¤È¤Ï¥â¥¸¥å¡¼¥ë¤ÎÆÃ°Û¥á¥½¥Ã¥É¤Ç¤¢¤ê¡¤Æ±»þ¤Ëprivate¥á¥½¥Ã¥É¤Ç
-¤â¤¢¤ë¤â¤Î¤Ç¤¹¡¥Îã¤ò¤¢¤²¤ë¤ÈMath¥â¥¸¥å¡¼¥ë¤Îsqrt()¤Ê¤É¤¬¤¢¤²
-¤é¤ì¤Þ¤¹¡¥¤³¤Î¥á¥½¥Ã¥É¤Ï
-
- Math.sqrt(4)
-
-¤È¤¤¤¦·Á¼°¤Ç¤â
-
- include Math
- sqrt(4)
-
-¤È¤¤¤¦·Á¼°¤Ç¤â»È¤¨¤Þ¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤Î
-Ä̤ê¤Ç¤¹¡¥
-
- void rb_define_module_function(VALUE module, char *name,
- VALUE (*func)(), int argc)
-
-´Ø¿ôŪ¥á¥½¥Ã¥É(Kernel¥â¥¸¥å¡¼¥ë¤Îprivaet method)¤òÄêµÁ¤¹¤ë¤¿
-¤á¤Î´Ø¿ô¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¹¡¥
-
- void rb_define_global_function(char *name, VALUE (*func)(), int argc)
-
-
-2.1.3 Constant definition
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ë¤¬É¬ÍפÊÄê¿ô¤Ï¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤
-¤Ç¤·¤ç¤¦¡¥Äê¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_const(VALUE class, char *name, VALUE val)
- void rb_define_global_const(char *name, VALUE val)
-
-Á°¼Ô¤ÏÆÃÄê¤Î¥¯¥é¥¹/¥â¥¸¥å¡¼¥ë¤Ë°¤¹¤ëÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¡¤¸å
-¼Ô¤Ï¥°¥í¡¼¥Ð¥ë¤ÊÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥
-
-2.2 Use Ruby features from C
-
-´û¤Ë¡Ø1.5 Ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë¡Ù¤Ç°ìÉô¾Ò²ð¤·¤¿¤è¤¦¤Ê´Ø¿ô¤ò
-»È¤¨¤Ð¡¤Ruby¤Îµ¡Ç½¤ò¼Â¸½¤·¤Æ¤¤¤ë´Ø¿ô¤òľÀܸƤӽФ¹¤³¤È¤¬½ÐÍè
-¤Þ¤¹¡¥
-
-# ¤³¤Î¤è¤¦¤Ê´Ø¿ô¤Î°ìÍ÷ɽ¤Ï¤¤¤Þ¤Î¤È¤³¤í¤¢¤ê¤Þ¤»¤ó¡¥¥½¡¼¥¹¤ò¸«
-# ¤ë¤·¤«¤Ê¤¤¤Ç¤¹¤Í¡¥
-
-¤½¤ì°Ê³°¤Ë¤âRuby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹ÊýË¡¤Ï¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡¥
-
-2.2.1 Ruby¤Î¥×¥í¥°¥é¥à¤òeval¤¹¤ë
-
-C¤«¤éRuby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤È¤·¤Æ¡¤Ê¸»úÎó¤Ç
-Í¿¤¨¤é¤ì¤¿Ruby¤Î¥×¥í¥°¥é¥à¤òɾ²Á¤¹¤ë´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
-
- VALUE rb_eval_string(char *str)
-
-¤³¤Îɾ²Á¤Ï¸½ºß¤Î´Ä¶­¤Ç¹Ô¤ï¤ì¤Þ¤¹¡¥¤Ä¤Þ¤ê¡¤¸½ºß¤Î¥í¡¼¥«¥ëÊÑ¿ô
-¤Ê¤É¤ò¼õ¤±·Ñ¤®¤Þ¤¹¡¥
-
-2.2.2 ID or Symbol
-
-C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤ËRuby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤â¤Ç¤­¤Þ
-¤¹¡¥¤½¤ÎÁ°¤Ë¡¤Ruby¥¤¥ó¥¿¥×¥ê¥¿Æâ¤Ç¥á¥½¥Ã¥É¤äÊÑ¿ô̾¤ò»ØÄꤹ¤ë
-»þ¤Ë»È¤ï¤ì¤Æ¤¤¤ëID¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤ª¤­¤Þ¤·¤ç¤¦¡¥
-
-ID¤È¤ÏÊÑ¿ô̾¡¤¥á¥½¥Ã¥É̾¤òɽ¤¹À°¿ô¤Ç¤¹¡¥Ruby¤ÎÃæ¤Ç¤Ï
-
- :¼±ÊÌ»Ò
-
-¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹¡¥C¤«¤é¤³¤ÎÀ°¿ô¤òÆÀ¤ë¤¿¤á¤Ë¤Ï´Ø¿ô
-
- rb_intern(char *name)
-
-¤ò»È¤¤¤Þ¤¹¡¥¤Þ¤¿°ìʸ»ú¤Î±é»»»Ò¤Ï¤½¤Îʸ»ú¥³¡¼¥É¤¬¤½¤Î¤Þ¤Þ¥·¥ó
-¥Ü¥ë¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
-2.2.3 Invoke Ruby method from C
-
-C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤ËRuby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤¿¤á¤Ë¤Ï°Ê²¼
-¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
-
-¤³¤Î´Ø¿ô¤Ï¥ª¥Ö¥¸¥§¥¯¥Èrecv¤Îmid¤Ç»ØÄꤵ¤ì¤ë¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð
-¤·¤Þ¤¹¡¥
-
-2.2.4 ÊÑ¿ô/Äê¿ô¤ò»²¾È/¹¹¿·¤¹¤ë
-
-C¤«¤é´Ø¿ô¤ò»È¤Ã¤Æ»²¾È¡¦¹¹¿·¤Ç¤­¤ë¤Î¤Ï¡¤¥¯¥é¥¹Äê¿ô¡¤¥¤¥ó¥¹¥¿
-¥ó¥¹ÊÑ¿ô¤Ç¤¹¡¥Âç°èÊÑ¿ô¤Ï°ìÉô¤Î¤â¤Î¤ÏC¤ÎÂç°èÊÑ¿ô¤È¤·¤Æ¥¢¥¯¥»
-¥¹¤Ç¤­¤Þ¤¹¡¥¥í¡¼¥«¥ëÊÑ¿ô¤ò»²¾È¤¹¤ëÊýË¡¤Ï¸ø³«¤·¤Æ¤¤¤Þ¤»¤ó¡¥
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¡¦¹¹¿·¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤ÎÄÌ
-¤ê¤Ç¤¹¡¥
-
- VALUE rb_ivar_get(VALUE obj, ID id)
- VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
-
-id¤Ïrb_intern()¤ÇÆÀ¤é¤ì¤ë¤â¤Î¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
-¥¯¥é¥¹Äê¿ô¤ò»²¾È¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
- VALUE rb_const_get(VALUE obj, ID id)
-
-¥¯¥é¥¹Äê¿ô¤ò¿·¤·¤¯ÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡Ø2.1.3 Äê¿ôÄêµÁ¡Ù¤Ç¾Ò²ð¤µ
-¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
-3. Informatin sharing between Ruby and C
-
-C¸À¸ì¤ÈRuby¤Î´Ö¤Ç¾ðÊó¤ò¶¦Í­¤¹¤ëÊýË¡¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Þ¤¹¡¥
-
-3.1 Ruby constant that C¤«¤é»²¾È¤Ç¤­¤ëRuby¤ÎÄê¿ô
-
-Following Ruby constants can be referred from C.
-
- TRUE
- FALSE
-
-Boolean values. FALSE is false in the C also (i.e. 0).
-
- Qnil
-
-Ruby nil in C scope.
-
-3.2 Global variables shared between C and Ruby
-
-C¤ÈRuby¤ÇÂç°èÊÑ¿ô¤ò»È¤Ã¤Æ¾ðÊó¤ò¶¦Í­¤Ç¤­¤Þ¤¹¡¥¶¦Í­¤Ç¤­¤ëÂç°è
-ÊÑ¿ô¤Ë¤Ï¤¤¤¯¤Ä¤«¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡¥¤½¤Î¤Ê¤«¤Ç¤â¤Ã¤È¤âÎɤ¯»È¤ï
-¤ì¤ë¤È»×¤ï¤ì¤ë¤Î¤Ïrb_define_variable()¤Ç¤¹¡¥
-
- void rb_define_variable(char *name, VALUE *var)
-
-¤³¤Î´Ø¿ô¤ÏRuby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëÂç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ¤¹¡¥ÊÑ¿ô̾¤¬
-`$'¤Ç»Ï¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤòÊÑ
-¹¹¤¹¤ë¤È¼«Æ°Åª¤ËRuby¤ÎÂбþ¤¹¤ëÊÑ¿ô¤ÎÃͤâÊѤï¤ê¤Þ¤¹¡¥
-
-¤Þ¤¿Ruby¦¤«¤é¤Ï¹¹¿·¤Ç¤­¤Ê¤¤ÊÑ¿ô¤â¤¢¤ê¤Þ¤¹¡¥¤³¤Îread only¤Î
-ÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ÇÄêµÁ¤·¤Þ¤¹¡¥
-
- void rb_define_readonly_variable(char *name, VALUE *var)
-
-¤³¤ì¤éÊÑ¿ô¤Î¾¤Ëhook¤ò¤Ä¤±¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤Ç¤­¤Þ¤¹¡¥hookÉÕ¤­
-¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤òÍѤ¤¤ÆÄêµÁ¤·¤Þ¤¹¡¥hookÉÕ¤­Âç°èÊÑ¿ô¤Î
-Ãͤλ²¾È¤äÀßÄê¤Ïhook¤Ç¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_hooked_variable(char *name, VALUE *var,
- VALUE (*getter)(), VALUE (*setter)())
-
-¤³¤Î´Ø¿ô¤ÏC¤Î´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ
-¤¹¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï´Ø¿ôgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì
-¤¿»þ¤Ë¤Ï´Ø¿ôsetter¤¬¸Æ¤Ð¤ì¤ë¡¥hook¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ïgetter¤ä
-setter¤Ë0¤ò»ØÄꤷ¤Þ¤¹¡¥
-
-# getter¤âsetter¤â0¤Ê¤é¤Ðrb_define_variable()¤ÈƱ¤¸¤Ë¤Ê¤ë¡¥
-
-¤½¤ì¤«¤é¡¤C¤Î´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRuby¤ÎÂç°èÊÑ¿ô¤òÄêµÁ¤¹¤ë
-´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_virtual_variable(char *name,
- VALUE (*getter)(), VALUE (*setter)())
-
-¤³¤Î´Ø¿ô¤Ë¤è¤Ã¤ÆÄêµÁ¤µ¤ì¤¿Ruby¤ÎÂç°èÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï
-getter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤Þ¤¹¡¥
-
-The prototypes of the getter and setter functions are as following:
-
- (*getter)(ID id, void *data, struct global_entry* entry);
- (*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
-
-3.3 Encapsulate C data into Ruby object
-
-C¤ÎÀ¤³¦¤ÇÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿(¹½Â¤ÂÎ)¤òRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ
-¼è¤ê°·¤¤¤¿¤¤¾ì¹ç¤¬¤¢¤ê¤¨¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤Data¤È¤¤¤¦
-Ruby¥ª¥Ö¥¸¥§¥¯¥È¤ËC¤Î¹½Â¤ÂÎ(¤Ø¤Î¥Ý¥¤¥ó¥¿)¤ò¤¯¤ë¤à¤³¤È¤ÇRuby
-¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ¼è¤ê°·¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Æ¹½Â¤ÂΤòRuby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥«¥×¥»¥ë
-²½¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤¤¤Þ¤¹¡¥
-
- Data_Wrap_Struct(class,mark,free,ptr)
-
-¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
-
-class¤Ï¤³¤ÎData¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¤Ç¤¹¡¥ptr¤Ï¥«¥×¥»¥ë²½¤¹¤ë
-C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤Ç¤¹¡¥mark¤Ï¤³¤Î¹½Â¤ÂΤ¬Ruby¤Î¥ª¥Ö¥¸¥§
-¥¯¥È¤Ø¤Î»²¾È¤¬¤¢¤ë»þ¤Ë»È¤¦´Ø¿ô¤Ç¤¹¡¥¤½¤Î¤è¤¦¤Ê»²¾È¤ò´Þ¤Þ¤Ê¤¤
-»þ¤Ë¤Ï0¤ò»ØÄꤷ¤Þ¤¹¡¥
-
-# ¤½¤Î¤è¤¦¤Ê»²¾È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥
-
-free¤Ï¤³¤Î¹½Â¤ÂΤ¬¤â¤¦ÉÔÍפˤʤä¿»þ¤Ë¸Æ¤Ð¤ì¤ë´Ø¿ô¤Ç¤¹¡¥¤³¤Î
-´Ø¿ô¤¬¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿¤«¤é¸Æ¤Ð¤ì¤Þ¤¹¡¥
-
-C¤Î¹½Â¤ÂΤγäÅö¤ÈData¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤òƱ»þ¤Ë¹Ô¤¦¥Þ¥¯¥í¤È
-¤·¤Æ°Ê²¼¤Î¤â¤Î¤¬Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- Data_Make_Struct(class, type, mark, free, sval)
-
-¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
-
-class, mark, free¤ÏData_Wrap_Struct¤ÈƱ¤¸Æ¯¤­¤ò¤·¤Þ¤¹¡¥type
-¤Ï³ä¤êÅö¤Æ¤ëC¹½Â¤ÂΤη¿¤Ç¤¹¡¥³ä¤êÅö¤Æ¤é¤ì¤¿¹½Â¤ÂΤÏÊÑ¿ôsval
-¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤Î·¿¤Ï (type*) ¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤é¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤Î¤Ï°Ê²¼¤Î¥Þ¥¯¥í¤òÍѤ¤
-¤Þ¤¹¡¥
-
- Data_Get_Struct(obj, type, sval)
-
-C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤ÏÊÑ¿ôsval¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥
-
-¤³¤ì¤é¤ÎData¤Î»È¤¤Êý¤Ï¤Á¤ç¤Ã¤Èʬ¤«¤ê¤Ë¤¯¤¤¤Î¤Ç¡¤¸å¤ÇÀâÌÀ¤¹¤ë
-ÎãÂê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-4¡¥Example - Create dbm module
-
-¤³¤³¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤È¤ê¤¢¤¨¤º³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ïºî¤ì¤ë¤Ï¤º¤Ç¤¹¡¥
-Ruby¤Îext¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¹¤Ç¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ëdbm¥â¥¸¥å¡¼¥ë¤òÎã¤Ë
-¤·¤ÆÃʳ¬Åª¤ËÀâÌÀ¤·¤Þ¤¹¡¥
-
-(1) make the directory
-
- % mkdir ext/dbm
-
-Ruby¤òŸ³«¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¡¤ext¥Ç¥£¥ì¥¯¥È¥ê¤ÎÃæ¤Ë³ÈÄ¥¥â
-¥¸¥å¡¼¥ëÍѤΥǥ£¥ì¥¯¥È¥ê¤òºî¤ê¤Þ¤¹¡¥Ì¾Á°¤ÏŬÅö¤ËÁª¤ó¤Ç¹½¤¤¤Þ
-¤»¤ó¡¥
-
-(2) create MANIFEST file
-
- % cd ext/dbm
- % touch MANIFEST
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤ÏMANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬
-ɬÍפʤΤǡ¤¤È¤ê¤¢¤¨¤º¶õ¤Î¥Õ¥¡¥¤¥ë¤òºî¤Ã¤Æ¤ª¤­¤Þ¤¹¡¥¸å¤Ç¤³¤Î
-¥Õ¥¡¥¤¥ë¤Ë¤ÏɬÍפʥե¡¥¤¥ë°ìÍ÷¤¬Æþ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-MANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤Ï¡¤make¤Î»þ¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤¬³ÈÄ¥¥â¥¸¥å¡¼
-¥ë¤ò´Þ¤ó¤Ç¤¤¤ë¤«¤É¤¦¤«È½Äꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ì¤Æ¤¤¤Þ¤¹¡¥
-
-(3) design the library
-
-¤Þ¤¢¡¤ÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¤¤É¤¦¤¤¤¦µ¡Ç½¤ò¼Â¸½¤¹¤ë¤«¤É¤¦¤«¤Þ¤ºÀß
-·×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¤É¤ó¤Ê¥¯¥é¥¹¤ò¤Ä¤¯¤ë¤«¡¤¤½¤Î¥¯¥é¥¹¤Ë¤Ï
-¤É¤ó¤Ê¥á¥½¥Ã¥É¤¬¤¢¤ë¤«¡¤¥¯¥é¥¹¤¬Ä󶡤¹¤ëÄê¿ô¤Ê¤É¤Ë¤Ä¤¤¤ÆÀß·×
-¤·¤Þ¤¹¡¥dbm¥¯¥é¥¹¤Ë¤Ä¤¤¤Æ¤Ïext/dbm.doc¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-(4) write C code.
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ëËÜÂΤȤʤëC¸À¸ì¤Î¥½¡¼¥¹¤ò½ñ¤­¤Þ¤¹¡¥C¸À¸ì¤Î¥½¡¼
-¥¹¤¬¤Ò¤È¤Ä¤Î»þ¤Ë¤Ï¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤òÁª¤Ö¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡¥C
-¸À¸ì¤Î¥½¡¼¥¹¤¬Ê£¿ô¤Î¾ì¹ç¤Ë¤ÏµÕ¤Ë¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤È¤¤¤¦¥Õ¥¡
-¥¤¥ë̾¤ÏÈò¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤È¥â¥¸¥å¡¼
-¥ëÀ¸À®»þ¤ËÃæ´ÖŪ¤ËÀ¸À®¤µ¤ì¤ë¡Ö¥â¥¸¥å¡¼¥ë̾.o¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë
-¤È¤¬¾×ÆÍ¤¹¤ë¤«¤é¤Ç¤¹¡¥
-
-Ruby¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë»þ¤Ë¡ÖInit_¥â¥¸¥å¡¼¥ë̾¡×¤È
-¤¤¤¦´Ø¿ô¤ò¼«Æ°Åª¤Ë¼Â¹Ô¤·¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤Î¾ì¹ç¡ÖInit_dbm¡×
-¤Ç¤¹¡¥¤³¤Î´Ø¿ô¤ÎÃæ¤Ç¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë¡¤¥á¥½¥Ã¥É¡¤Äê¿ô¤Ê¤É¤Î
-ÄêµÁ¤ò¹Ô¤¤¤Þ¤¹¡¥dbm.c¤«¤é°ìÉô°úÍѤ·¤Þ¤¹¡¥
-
---
-Init_dbm()
-{
- /* DBM¥¯¥é¥¹¤òÄêµÁ¤¹¤ë */
- cDBM = rb_define_class("DBM", cObject);
- /* DBM¤ÏEnumerate¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë */
- rb_include_module(cDBM, mEnumerable);
-
- /* DBM¥¯¥é¥¹¤Î¥¯¥é¥¹¥á¥½¥Ã¥Éopen(): °ú¿ô¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë */
- rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
-
- /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥Éclose(): °ú¿ô¤Ï¤Ê¤· */
- rb_define_method(cDBM, "close", fdbm_close, 0);
- /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥É[]: °ú¿ô¤Ï1¸Ä */
- rb_define_method(cDBM, "[]", fdbm_fetch, 1);
- :
-
- /* DBM¥Ç¡¼¥¿¤ò³ÊǼ¤¹¤ë¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô̾¤Î¤¿¤á¤ÎID */
- id_dbm = rb_intern("dbm");
-}
---
-
-DBM¥â¥¸¥å¡¼¥ë¤Ïdbm¤Î¥Ç¡¼¥¿¤ÈÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤ë¤Ï¤º¤Ç
-¤¹¤«¤é¡¤C¤ÎÀ¤³¦¤Îdbm¤òRuby¤ÎÀ¤³¦¤Ë¼è¤ê¹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
-
-
-dbm.c¤Ç¤ÏData_Make_Struct¤ò°Ê²¼¤Î¤è¤¦¤Ë»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-struct dbmdata {
- int di_size;
- DBM *di_dbm;
-};
-
-
-obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
---
-
-¤³¤³¤Ç¤Ïdbmstruct¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤òData¤Ë¥«¥×¥»¥ë²½¤·¤Æ¤¤
-¤Þ¤¹¡¥DBM*¤òľÀÜ¥«¥×¥»¥ë²½¤·¤Ê¤¤¤Î¤Ïclose()¤·¤¿»þ¤Î½èÍý¤ò¹Í
-¤¨¤Æ¤Î¤³¤È¤Ç¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤édbmstruct¹½Â¤ÂΤΥݥ¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á
-¤Ë°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-#define GetDBM(obj, dbmp) {\
- Data_Get_Struct(obj, struct dbmdata, dbmp);\
- if (dbmp->di_dbm == 0) closed_dbm();\
-}
---
-
-¤Á¤ç¤Ã¤ÈÊ£»¨¤Ê¥Þ¥¯¥í¤Ç¤¹¤¬¡¤Íפ¹¤ë¤Ëdbmdata¹½Â¤ÂΤΥݥ¤¥ó¥¿
-¤Î¼è¤ê½Ð¤·¤È¡¤close¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤ò¤Þ¤È¤á¤Æ¤¤
-¤ë¤À¤±¤Ç¤¹¡¥
-
-DBM¥¯¥é¥¹¤Ë¤Ï¤¿¤¯¤µ¤ó¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¤¬¡¤Ê¬Îह¤ë¤È3¼ïÎà¤Î
-°ú¿ô¤Î¼õ¤±Êý¤¬¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ï°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¤â¤Î¤Ç¡¤Îã¤È
-¤·¤Æ¤Ïdelete¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¡¥delete¥á¥½¥Ã¥É¤ò¼ÂÁõ¤·¤Æ¤¤¤ë
-fdbm_delete()¤Ï¤³¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-static VALUE
-fdbm_delete(obj, keystr)
- VALUE obj, keystr;
-{
- :
-}
---
-
-°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¥¿¥¤¥×¤ÏÂè1°ú¿ô¤¬self¡¤Âè2°ú¿ô°Ê¹ß¤¬¥á¥½¥Ã¥É
-¤Î°ú¿ô¤È¤Ê¤ê¤Þ¤¹¡¥
-
-°ú¿ô¤Î¿ô¤¬ÉÔÄê¤Î¤â¤Î¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î¤ÈRuby¤ÎÇÛÎó¤Ç¼õ¤±
-¤ë¤â¤Î¤È¤¬¤¢¤ê¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Ç¡¤C¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î
-¤ÏDBM¤Î¥¯¥é¥¹¥á¥½¥Ã¥É¤Ç¤¢¤ëopen()¤Ç¤¹¡¥¤³¤ì¤ò¼ÂÁõ¤·¤Æ¤¤¤ë´Ø
-¿ôfdbm_s_open()¤Ï¤³¤¦¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-static VALUE
-fdbm_s_open(argc, argv, class)
- int argc;
- VALUE *argv;
- VALUE class;
-{
- :
- if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
- mode = 0666; /* default value */
- }
- :
-}
---
-
-¤³¤Î¥¿¥¤¥×¤Î´Ø¿ô¤ÏÂè1°ú¿ô¤¬Í¿¤¨¤é¤ì¤¿°ú¿ô¤Î¿ô¡¤Âè2°ú¿ô¤¬Í¿¤¨
-¤é¤ì¤¿°ú¿ô¤ÎÆþ¤Ã¤Æ¤¤¤ëÇÛÎó¤Ë¤Ê¤ê¤Þ¤¹¡¥self¤ÏÂè3°ú¿ô¤È¤·¤ÆÍ¿
-¤¨¤é¤ì¤Þ¤¹¡¥
-
-¤³¤ÎÇÛÎó¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤ò²òÀϤ¹¤ë¤¿¤á¤Î´Ø¿ô¤¬open()¤Ç¤â»È¤ï
-¤ì¤Æ¤¤¤ërb_scan_args()¤Ç¤¹¡¥Âè3°ú¿ô¤Ë»ØÄꤷ¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë
-½¾¤¤¡¤Âè4ÊÑ¿ô°Ê¹ß¤Ë»ØÄꤷ¤¿ÊÑ¿ô¤ËÃͤòÂåÆþ¤·¤Æ¤¯¤ì¤Þ¤¹¡¥¤³¤Î
-¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¡¤Âè1ʸ»úÌܤ¬¾Êά¤Ç¤­¤Ê¤¤°ú¿ô¤Î¿ô¡¤Âè2ʸ»úÌܤ¬
-¾Êά¤Ç¤­¤ë°ú¿ô¤Î¿ô¡¤Âè3ʸ»úÌܤ¬Âбþ¤¹¤ëÁê¼ê¤¬Ìµ¤¤¤¢¤Þ¤ê¤Î°ú
-¿ô¤¬¤¢¤ë¤«¤É¤¦¤«¤ò¼¨¤¹"*"¤Ç¤¹¡¥2ʸ»úÌܤÈ3ʸ»úÌܤϾÊά¤Ç¤­¤Þ
-¤¹¡¥dbm.c¤ÎÎã¤Ç¤Ï¡¤¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï"11"¤Ç¤¹¤«¤é¡¤°ú¿ô¤ÏºÇÄã1¤Ä
-¤Ç¡¤2¤Ä¤Þ¤Çµö¤µ¤ì¤ë¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡¥¾Êά¤µ¤ì¤Æ¤¤¤ë»þ¤Î
-ÊÑ¿ô¤ÎÃͤÏnil(C¸À¸ì¤Î¥ì¥Ù¥ë¤Ç¤ÏQnil)¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-Ruby¤ÎÇÛÎó¤Ç°ú¿ô¤ò¼õ¤±¼è¤ë¤â¤Î¤Ïindexes¤¬¤¢¤ê¤Þ¤¹¡¥¼ÂÁõ¤Ï¤³
-¤¦¤Ç¤¹¡¥
-
---
-static VALUE
-fdbm_indexes(obj, args)
- VALUE obj;
- struct RArray *args;
-{
- :
-}
---
-
-Âè1°ú¿ô¤Ïself¡¤Âè2°ú¿ô¤ÏRuby¤ÎÇÛÎó¤Ç¤¹¡¥¤³¤³¤Ç¤Ï¥­¥ã¥¹¥È¤ò¸º
-¤é¤¹¤¿¤á struct RArray* ¤Ç¼õ¤±¤Æ¤¤¤Þ¤¹¤¬¡¤VALUE¤Ç¤âƱ¤¸¤³¤È
-¤Ç¤¹¡¥
-
-** Ãí°Õ»ö¹à
-
-Ruby¤È¶¦Í­¤Ï¤·¤Ê¤¤¤¬Ruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤¹¤ë²ÄǽÀ­¤Î¤¢¤ë
-C¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤ÆRuby¥¤¥ó¥¿¥×¥ê¥¿¤ËÊÑ¿ô¤Î¸ºß
-¤ò¶µ¤¨¤Æ¤¢¤²¤Æ¤¯¤À¤µ¤¤¡¥¤Ç¤Ê¤¤¤ÈGC¤Ç¥È¥é¥Ö¥ë¤òµ¯¤³¤·¤Þ¤¹¡¥
-
- void rb_global_variable(VALUE *var)
-
-(5) prepare extconf.rb
-
-¤â¤·¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡Öextconf.rb¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
-make»þ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¡¥¤Ê¤±¤ì¤ÐŬÅö¤ËMakefile¤¬À¸À®¤µ¤ì¤Þ¤¹¡¥
-
-extconf.rb¤Ï¥â¥¸¥å¡¼¥ë¤Î¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʾò·ï¤Î¥Á¥§¥Ã¥¯¤Ê¤É
-¤ò¹Ô¤¦¤³¤È¤¬ÌÜŪ¤Ç¤¹¡¥extconf.rb¤ÎÃæ¤Ç¤Ï°Ê²¼¤ÎRuby´Ø¿ô¤ò»È¤¦
-¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥
-
- have_library(lib, func): ¥é¥¤¥Ö¥é¥ê¤Î¸ºß¥Á¥§¥Ã¥¯
- have_func(func): ´Ø¿ô¤Î¸ºß¥Á¥§¥Ã¥¯
- have_header(header): ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¥Á¥§¥Ã¥¯
- create_makefile(target): Makefile¤ÎÀ¸À®
-
-°Ê²¼¤ÎÊÑ¿ô¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥
-
- $CFLAGS: ¥³¥ó¥Ñ¥¤¥ë»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-I¤Ê¤É)
- $LDFLAGS: ¥ê¥ó¥¯»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-L¤Ê¤É)
-
-¥â¥¸¥å¡¼¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ò·ï¤¬Â·¤ï¤Ê¤º¡¤¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³
-¥ó¥Ñ¥¤¥ë¤·¤Ê¤¤»þ¤Ë¤Ïcreate_makefile¤ò¸Æ¤Ð¤Ê¤±¤ì¤ÐMakefile¤Ï
-À¸À®¤µ¤ì¤º¡¤¥³¥ó¥Ñ¥¤¥ë¤â¹Ô¤ï¤ì¤Þ¤»¤ó¡¥
-
-(6) prepare depend (optional)
-
-¤â¤·¡¤¥Ç¥£¥ì¥¯¥È¥ê¤Ëdepend¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
-Makefile¤¬°Í¸´Ø·¸¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤ì¤Þ¤¹¡¥
-
- % gcc -MM *.c > depend
-
-¤Ê¤É¤Çºî¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤¢¤Ã¤ÆÂ»¤Ï̵¤¤¤Ç¤·¤ç¤¦¡¥
-
-(7) MANIFEST¥Õ¥¡¥¤¥ë¤Ë¥Õ¥¡¥¤¥ë̾¤òÆþ¤ì¤ë
-
- % ls > MANIFEST
- % vi MANIFEST
-
-*.o, *~¤Ê¤ÉÉÔɬÍפʥե¡¥¤¥ë°Ê³°¤ÏMANIFEST¤ËÄɲ䷤Ƥª¤­¤Þ¤¹¡¥
-make»þ¤Ë¤ÏMANIFEST¤ÎÆâÍÆ¤Ï»²¾È¤·¤Þ¤»¤ó¤Î¤Ç¡¤¶õ¤Î¤Þ¤Þ¤Ç¤âÌäÂê
-¤Ïµ¯¤­¤Þ¤»¤ó¤¬¡¤¥Ñ¥Ã¥±¡¼¥¸¥ó¥°¤Î»þ¤Ë»²¾È¤¹¤ë¤³¤È¤¬¤¢¤ë¤Î¤È¡¤
-ɬÍפʥե¡¥¤¥ë¤ò¶èÊ̤Ǥ­¤ë¤Î¤Ç¡¤ÍѰդ·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç
-¤¦¡¥
-
-(8) make
-
-Ruby¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤ò¼Â¹Ô¤¹¤ë¤ÈMakefile¤òÀ¸À®¤«¤émake¡¤
-ɬÍפˤè¤Ã¤Æ¤Ï¤½¤Î¥â¥¸¥å¡¼¥ë¤ÎRuby¤Ø¤Î¥ê¥ó¥¯¤Þ¤Ç¼«Æ°Åª¤Ë¼Â¹Ô
-¤·¤Æ¤¯¤ì¤Þ¤¹¡¥extconf.rb¤ò½ñ¤­´¹¤¨¤ë¤Ê¤É¤·¤ÆMakefile¤ÎºÆÀ¸À®
-¤¬É¬Íפʻþ¤Ï¤Þ¤¿Ruby¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-(9) debug
-
-You may need to debug the module. The modules can be linked
-statically by adding directory name in the ext/Setup file,
-so that you can inspect the module by the debugger.
-
-(10) done, now you have the extension module
-
-¸å¤Ï¤³¤Ã¤½¤ê»È¤¦¤Ê¤ê¡¤¹­¤¯¸ø³«¤¹¤ë¤Ê¤ê¡¤Çä¤ë¤Ê¤ê¡¤¤´¼«Í³¤Ë¤ª
-»È¤¤¤¯¤À¤µ¤¤¡¥Ruby¤Îºî¼Ô¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò
-¼çÄ¥¤·¤Þ¤»¤ó¡¥
-
-Appendix A. Ruby¤Î¥½¡¼¥¹¥³¡¼¥É¤ÎʬÎà
-
-Ruby¤Î¥½¡¼¥¹¤Ï¤¤¤¯¤Ä¤«¤ËʬÎह¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤³¤Î¤¦¤Á¥¯¥é
-¥¹¥é¥¤¥Ö¥é¥ê¤ÎÉôʬ¤Ï´ðËÜŪ¤Ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ÈƱ¤¸ºî¤êÊý¤Ë¤Ê¤Ã
-¤Æ¤¤¤Þ¤¹¡¥¤³¤ì¤é¤Î¥½¡¼¥¹¤Ïº£¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤Û¤È¤ó¤ÉÍý²ò¤Ç¤­¤ë¤È
-»×¤¤¤Þ¤¹¡¥
-
-ruby language core
-
- class.c
- error.c
- eval.c
- gc.c
- object.c
- parse.y
- variable.c
-
-utility functions
-
- dln.c
- fnmatch.c
- glob.c
- regex.c
- st.c
- util.c
-
-ruby interpreter implementation
-
- dmyext.c
- inits.c
- main.c
- ruby.c
- version.c
-
-class library
-
- array.c
- bignum.c
- compar.c
- dir.c
- enum.c
- file.c
- hash.c
- io.c
- math.c
- numeric.c
- pack.c
- process.c
- random.c
- range.c
- re.c
- signal.c
- sprintf.c
- string.c
- struct.c
- time.c
-
-Appendix B. ³ÈÄ¥ÍÑ´Ø¿ô¥ê¥Õ¥¡¥ì¥ó¥¹
-
-C¸À¸ì¤«¤éRuby¤Îµ¡Ç½¤òÍøÍѤ¹¤ëAPI¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-** ·¿
-
- VALUE
-
-Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¸½¤¹¤ë·¿¡¥É¬Íפ˱þ¤¸¤Æ¥­¥ã¥¹¥È¤·¤ÆÍѤ¤¤ë¡¥
-ÁȤ߹þ¤ß·¿¤òɽ¸½¤¹¤ëC¤Î·¿¤Ïruby.h¤Ëµ­½Ò¤·¤Æ¤¢¤ëR¤Ç»Ï¤Þ¤ë¹½Â¤
-ÂΤǤ¢¤ë¡¥VALUE·¿¤ò¤³¤ì¤é¤Ë¥­¥ã¥¹¥È¤¹¤ë¤¿¤á¤ËR¤Ç»Ï¤Þ¤ë¹½Â¤ÂÎ
-̾¤òÁ´¤ÆÂçʸ»ú¤Ë¤·¤¿Ì¾Á°¤Î¥Þ¥¯¥í¤¬ÍѰդµ¤ì¤Æ¤¤¤ë¡¥
-
-** Variables and constants
-
- Qnil
-
-const: nil object
-
- TRUE
-
-const: TRUE object(default true value)
-
- FALSE
-
-const: FALSE object
-
-** C¥Ç¡¼¥¿¤Î¥«¥×¥»¥ë²½
-
- Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
-
-C¤ÎǤ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò¥«¥×¥»¥ë²½¤·¤¿Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¤³
-¤Î¥Ý¥¤¥ó¥¿¤¬Ruby¤«¤é¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¯¤Ê¤Ã¤¿»þ¡¤free¤Ç»ØÄꤷ¤¿
-´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¡¥¤Þ¤¿¡¤¤³¤Î¥Ý¥¤¥ó¥¿¤Î»Ø¤¹¥Ç¡¼¥¿¤¬Â¾¤ÎRuby¥ª¥Ö
-¥¸¥§¥¯¥È¤ò»Ø¤·¤Æ¤¤¤ë¾ì¹ç¡¤mark¤Ë»ØÄꤹ¤ë´Ø¿ô¤Ç¥Þ¡¼¥¯¤¹¤ëɬÍ×
-¤¬¤¢¤ë¡¥
-
- Data_Make_Struct(class, type, mark, free, sval)
-
-type·¿¤Î¥á¥â¥ê¤òmalloc¤·¡¤ÊÑ¿ôsval¤ËÂåÆþ¤·¤¿¸å¡¤¤½¤ì¤ò¥«¥×¥»
-¥ë²½¤·¤¿¥Ç¡¼¥¿¤òÊÖ¤¹¥Þ¥¯¥í¡¥
-
- Data_Get_Struct(data, type, sval)
-
-data¤«¤étype·¿¤Î¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤·ÊÑ¿ôsval¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
-
-** ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
-
- VALUE rb_define_class(char *name, VALUE super)
-
-super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
-
-super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤·¡¤module¤ÎÄê
-¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_module(char *name)
-
-¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
-
-¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤·¡¤module¤ÎÄê¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
-
- void rb_include_module(VALUE class, VALUE module)
-
-¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥class¤¬¤¹¤Ç¤Ëmodule¤ò¥¤¥ó¥¯¥ë¡¼
-¥É¤·¤Æ¤¤¤ë»þ¤Ë¤Ï²¿¤â¤·¤Ê¤¤(¿½Å¥¤¥ó¥¯¥ë¡¼¥É¤Î¶Ø»ß)¡¥
-
- void rb_extend_object(VALUE object, VALUE module)
-
-¥ª¥Ö¥¸¥§¥¯¥È¤ò¥â¥¸¥å¡¼¥ë(¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É)¤Ç³ÈÄ¥¤¹¤ë¡¥
-
-** Âç°èÊÑ¿ôÄêµÁ
-
- void rb_define_variable(char *name, VALUE *var)
-
-Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ë¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô̾¤¬`$'¤Ç»Ï
-¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤ë¡¥name¤È¤·¤ÆRuby¤Î¼±Ê̻ҤȤ·
-¤Æµö¤µ¤ì¤Ê¤¤Ê¸»ú(Î㤨¤Ð` ')¤ò´Þ¤à¾ì¹ç¤Ë¤ÏRuby¥×¥í¥°¥é¥à¤«¤é
-¤Ï¸«¤¨¤Ê¤¯¤Ê¤ë¡¥
-
- void rb_define_readonly_variable(char *name, VALUE *var)
-
-Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëread only¤Î¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥read
-only¤Ç¤¢¤ë¤³¤È°Ê³°¤Ïrb_define_variable()¤ÈƱ¤¸¡¥
-
- void rb_define_virtual_variable(char *name,
- VALUE (*getter)(), VALUE (*setter)())
-
-´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRubyÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ
-¤Ë¤Ïgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤ë¡¥
-
- void rb_define_hooked_variable(char *name, VALUE *var,
- VALUE (*getter)(), VALUE (*setter)())
-
-´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬
-»²¾È¤µ¤ì¤¿»þ¤Ë¤Ïgetter¤¬¡¤´Ø¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter
-¤¬¸Æ¤Ð¤ì¤ë¡¥getter¤äsetter¤Ë0¤ò»ØÄꤷ¤¿»þ¤Ë¤Ïhook¤ò»ØÄꤷ¤Ê
-¤¤¤Î¤ÈƱ¤¸»ö¤Ë¤Ê¤ë¡¥
-
- void rb_global_variable(VALUE *var)
-
-GC¤Î¤¿¤á¡¤Ruby¥×¥í¥°¥é¥à¤«¤é¤Ï¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¤¤¬, Ruby¥ª¥Ö¥¸¥§
-¥¯¥È¤ò´Þ¤àÂç°èÊÑ¿ô¤ò¥Þ¡¼¥¯¤¹¤ë¡¥
-
-** ¥¯¥é¥¹Äê¿ô
-
- void rb_define_const(VALUE class, char *name, VALUE val)
-
-¥¯¥é¥¹Äê¿ô¤òÄêµÁ¤¹¤ë¡¥
-
- void rb_define_global_const(char *name, VALUE val)
-
-Âç°èÄê¿ô¤òÄêµÁ¤¹¤ë¡¥
-
- rb_define_const(cKernal, name, val)
-
-¤ÈƱ¤¸°ÕÌ£¡¥
-
-** ¥á¥½¥Ã¥ÉÄêµÁ
-
- rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥argc¤Ïself¤ò½ü¤¯°ú¿ô¤Î¿ô¡¥argc¤¬-1¤Î»þ,
-´Ø¿ô¤Ë¤Ï°ú¿ô¤Î¿ô(self¤ò´Þ¤Þ¤Ê¤¤)¤òÂè1°ú¿ô, °ú¿ô¤ÎÇÛÎó¤òÂè2°ú
-¿ô¤È¤¹¤ë·Á¼°¤ÇÍ¿¤¨¤é¤ì¤ë(Âè3°ú¿ô¤Ïself)¡¥argc¤¬-2¤Î»þ, Âè1°ú
-¿ô¤¬self, Âè2°ú¿ô¤¬args(args¤Ï°ú¿ô¤ò´Þ¤àRuby¤ÎÇÛÎó)¤È¤¤¤¦·Á
-¼°¤ÇÍ¿¤¨¤é¤ì¤ë¡¥
-
- rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-private¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
-
- rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-ÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
-
- rb_scan_args(int atgc, VALUE *argv, char *fmt, ...)
-
-argc,argv·Á¼°¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤òʬ²ò¤¹¤ë¡¥fmt¤Ïɬ¿Ü°ú¿ô¤Î¿ô,
-Éղðú¿ô¤Î¿ô, »Ä¤ê¤Î°ú¿ô¤¬¤¢¤ë¤«¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç, "¿ô»ú¿ô
-»ú*"¤È¤¤¤¦·Á¼°¤Ç¤¢¤ë¡¥ 2 ÈÖÌܤοô»ú¤È"*"¤Ï¤½¤ì¤¾¤ì¾Êά²Äǽ¤Ç
-¤¢¤ë¡¥É¬¿Ü°ú¿ô¤¬°ì¤Ä¤â¤Ê¤¤¾ì¹ç¤Ï0¤ò»ØÄꤹ¤ë¡¥Âè3°ú¿ô°Ê¹ß¤ÏÊÑ
-¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç, ³ºÅö¤¹¤ëÍ×ÁǤ¬¤½¤ÎÊÑ¿ô¤Ë³ÊǼ¤µ¤ì¤ë¡¥Éղðú
-¿ô¤ËÂбþ¤¹¤ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤ÏÊÑ¿ô¤ËQnil¤¬ÂåÆþ¤µ¤ì
-¤ë¡¥
-
-** Ruby¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
-
- VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥Ê¸»úÎ󤫤émid¤òÆÀ¤ë¤¿¤á¤Ë¤Ïrb_intern()¤ò»È¤¦¡¥
-
- VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥°ú¿ô¤òargc,argv·Á¼°¤ÇÅϤ¹¡¥
-
- VALUE rb_eval_string(char *str)
-
-ʸ»úÎó¤òRuby¤È¥¹¥¯¥ê¥×¥È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¡¦¼Â¹Ô¤¹¤ë¡¥
-
- ID rb_intern(char *name)
-
-ʸ»úÎó¤ËÂбþ¤¹¤ëID¤òÊÖ¤¹¡¥
-
- char *rb_id2name(ID id)
-
-ID¤ËÂбþ¤¹¤ëʸ»úÎó¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥
-
- char *rb_class2name(VALUE class)
-
-class¤Î̾Á°¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥class¤¬Ì¾Á°¤ò»ý¤¿¤Ê¤¤»þ¤Ë¤Ï,
-ÁÄÀè¤òÁ̤äÆÌ¾Á°¤ò»ý¤Ä¥¯¥é¥¹¤Î̾Á°¤òÊÖ¤¹¡¥
-
-** ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô
-
- VALUE rb_iv_get(VALUE obj, char *name)
-
-obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ÎÃͤòÆÀ¤ë¡¥`@'¤Ç»Ï¤Þ¤é¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹
-ÊÑ¿ô¤Ï Ruby¥×¥í¥°¥é¥à¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¡Ö±£¤ì¤¿¡×¥¤¥ó¥¹¥¿
-¥ó¥¹ÊÑ¿ô¤Ë¤Ê¤ë¡¥
-
- VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
-
-obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤òval¤Ë¥»¥Ã¥È¤¹¤ë¡¥
-
-** À©¸æ¹½Â¤
-
- VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
-
-func2¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ, func1¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ö¡¥
-func1¤Ë¤Ï arg1¤¬°ú¿ô¤È¤·¤ÆÅϤµ¤ì, func2¤Ë¤ÏÂè1°ú¿ô¤Ë¥¤¥Æ¥ì¡¼
-¥¿¤«¤éÍ¿¤¨¤é¤ì¤¿ÃÍ, Âè2°ú¿ô¤Ëarg2¤¬ÅϤµ¤ì¤ë¡¥
-
- VALUE rb_yield(VALUE val)
-
-val¤òÃͤȤ·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¸Æ¤Ó½Ð¤¹¡¥
-
- VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
-
-´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤Ë¸Æ¤Ó½Ð¤¹¡¥func1¤Î¼Â¹ÔÃæ¤ËÎã³°¤¬È¯À¸¤·
-¤¿»þ¤Ë¤Ï func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ö¡¥Ìá¤êÃͤÏÎã³°¤¬È¯À¸¤·¤Ê
-¤«¤Ã¤¿»þ¤Ïfunc1¤ÎÌá¤êÃÍ, Îã³°¤¬È¯À¸¤·¤¿»þ¤Ë¤Ïfunc2¤ÎÌá¤êÃͤÇ
-¤¢¤ë¡¥
-
- VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2)
-
-´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤·, ¼Â¹Ô½ªÎ»¸å(¤¿¤È¤¨Îã³°¤¬È¯
-À¸¤·¤Æ¤â) func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡¥Ìá¤êÃͤÏfunc1¤ÎÌá
-¤êÃͤǤ¢¤ë(Îã³°¤¬È¯À¸¤·¤¿»þ¤ÏÌá¤é¤Ê¤¤)¡¥
-
-** Îã³°¡¦¥¨¥é¡¼
-
- void Warning(char *fmt, ...)
-
-verbose»þ¤Ëɸ½à¥¨¥é¡¼½ÐÎϤ˷ٹð¾ðÊó¤òɽ¼¨¤¹¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
-
- void Fail(char *fmt, ...)
-
-Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
-
- void Fatal(char *fmt, ...)
-
-Ã×̿ŪÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥Ä̾ï¤ÎÎã³°½èÍý¤Ï¹Ô¤Ê¤ï¤ì¤º, ¥¤¥ó¥¿¡¼
-¥×¥ê¥¿¤¬½ªÎ»¤¹¤ë(¤¿¤À¤·ensure¤Ç»ØÄꤵ¤ì¤¿¥³¡¼¥É¤Ï½ªÎ»Á°¤Ë¼Â
-¹Ô¤µ¤ì¤ë)¡¥
-
- void Bug(char *fmt, ...)
-
-¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ê¤É¥×¥í¥°¥é¥à¤Î¥Ð¥°¤Ç¤·¤«È¯À¸¤¹¤ë¤Ï¤º¤Î¤Ê¤¤¾õ
-¶·¤Î»þ¸Æ¤Ö¡¥¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ï¥³¥¢¥À¥ó¥×¤·Ä¾¤Á¤Ë½ªÎ»¤¹¤ë¡¥Îã³°
-½èÍý¤Ï°ìÀڹԤʤï¤ì¤Ê¤¤¡¥
-
-** Ruby¤Î½é´ü²½¡¦¼Â¹Ô
-
-Ruby¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ËËä¤á¹þ¤à¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹
-¤ò»È¤¦¡¥Ä̾ï¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤ÏɬÍפʤ¤¡¥
-
- void ruby_init(int argc, char **argv, char **envp)
-
-Ruby¥¤¥ó¥¿¥×¥ê¥¿¤Î½é´ü²½¤ò¹Ô¤Ê¤¦¡¥
-
- void ruby_run()
-
-Ruby¥¤¥ó¥¿¥×¥ê¥¿¤ò¼Â¹Ô¤¹¤ë¡¥
-
- void ruby_script(char *name)
-
-Ruby¤Î¥¹¥¯¥ê¥×¥È̾($0)¤òÀßÄꤹ¤ë¡¥
-
-
-Appendix B. extconf.rb¤Ç»È¤¨¤ë´Ø¿ô¤¿¤Á
-
-extconf.rb¤ÎÃæ¤Ç¤ÏÍøÍѲÄǽ¤Ê¥³¥ó¥Ñ¥¤¥ë¾ò·ï¥Á¥§¥Ã¥¯¤Î´Ø¿ô¤Ï°Ê
-²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
- have_library(lib, func)
-
-´Ø¿ôfunc¤òÄêµÁ¤·¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥êlib¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥é
-¥¤¥Ö¥é¥ê¤¬Â¸ºß¤¹¤ë»þ¡¤TRUE¤òÊÖ¤¹¡¥
-
- have_func(func)
-
-´Ø¿ôfunc¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥func¤¬É¸½à¤Ç¤Ï¥ê¥ó¥¯¤µ¤ì¤Ê¤¤¥é
-¥¤¥Ö¥é¥êÆâ¤Î¤â¤Î¤Ç¤¢¤ë»þ¤Ë¤ÏÀè¤Ëhave_library¤Ç¤½¤Î¥é¥¤¥Ö¥é¥ê
-¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤ª¤¯»ö¡¥´Ø¿ô¤¬Â¸ºß¤¹¤ë»þTRUE¤òÊÖ¤¹¡¥
-
- have_header(header)
-
-¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë
-»þTRUE¤òÊÖ¤¹¡¥
-
- create_makefile(target)
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤÎMakefile¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤ò¸Æ¤Ð¤Ê¤±¤ì¤Ð
-¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤¡¥target¤Ï¥â¥¸¥å¡¼¥ë̾¤òɽ
-¤¹¡¥
-
-/*
- * Local variables:
- * fill-column: 60
- * end:
- */
+Moved to doc/extension.rdoc
diff --git a/README.EXT.ja b/README.EXT.ja
new file mode 100644
index 0000000000..f884ecbb0e
--- /dev/null
+++ b/README.EXT.ja
@@ -0,0 +1 @@
+doc/extension.ja.rdocã«ç§»å‹•ã—ã¾ã—ãŸ
diff --git a/README.EXT.jp b/README.EXT.jp
deleted file mode 100644
index 09983b5ee0..0000000000
--- a/README.EXT.jp
+++ /dev/null
@@ -1,1147 +0,0 @@
-.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
-
-Ruby¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Îºî¤êÊý¤òÀâÌÀ¤·¤Þ¤¹¡¥
-
-1¡¥´ðÁÃÃμ±
-
-C¤ÎÊÑ¿ô¤Ë¤Ï·¿¤¬¤¢¤ê¡¤¥Ç¡¼¥¿¤Ë¤Ï·¿¤¬¤¢¤ê¤Þ¤»¤ó¡¥¤Ç¤¹¤«¤é¡¤¤¿
-¤È¤¨¤Ð¥Ý¥¤¥ó¥¿¤òint¤ÎÊÑ¿ô¤ËÂåÆþ¤¹¤ë¤È¡¤¤½¤ÎÃͤÏÀ°¿ô¤È¤·¤Æ¼è
-¤ê°·¤ï¤ì¤Þ¤¹¡¥µÕ¤ËRuby¤ÎÊÑ¿ô¤Ë¤Ï·¿¤¬¤Ê¤¯¡¤¥Ç¡¼¥¿¤Ë·¿¤¬¤¢¤ê¤Þ
-¤¹¡¥¤³¤Î°ã¤¤¤Î¤¿¤á¡¤C¤ÈRuby¤ÏÁê¸ß¤ËÊÑ´¹¤·¤Ê¤±¤ì¤Ð¡¤¤ª¸ß¤¤¤Î
-¥Ç¡¼¥¿¤ò¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó¡¥
-
-Ruby¤Î¥Ç¡¼¥¿¤ÏVALUE¤È¤¤¤¦C¤Î·¿¤Çɽ¸½¤µ¤ì¤Þ¤¹¡¥VALUE·¿¤Î¥Ç¡¼
-¥¿¤Ï¤½¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ò¼«Ê¬¤ÇÃΤäƤ¤¤Þ¤¹¡¥¤³¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤È
-¤¤¤¦¤Î¤Ï¥Ç¡¼¥¿(¥ª¥Ö¥¸¥§¥¯¥È)¤Î¼ÂºÝ¤Î¹½Â¤¤ò°ÕÌ£¤·¤Æ¤¤¤Æ¡¤Ruby
-¤Î¥¯¥é¥¹¤È¤Ï¤Þ¤¿°ã¤Ã¤¿¤â¤Î¤Ç¤¹¡¥
-
-VALUE¤«¤éC¤Ë¤È¤Ã¤Æ°ÕÌ£¤Î¤¢¤ë¥Ç¡¼¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á¤Ë¤Ï
-
- (1) VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤òÃΤë
- (2) VALUE¤òC¤Î¥Ç¡¼¥¿¤ËÊÑ´¹¤¹¤ë
-
-¤ÎξÊý¤¬É¬ÍפǤ¹¡¥(1)¤ò˺¤ì¤ë¤È´Ö°ã¤Ã¤¿¥Ç¡¼¥¿¤ÎÊÑ´¹¤¬¹Ô¤ï¤ì
-¤Æ¡¤ºÇ°­¥×¥í¥°¥é¥à¤¬core dump¤·¤Þ¤¹¡¥
-
-1.1 ¥Ç¡¼¥¿¥¿¥¤¥×
-
-Ruby¤Ë¤Ï¥æ¡¼¥¶¤¬»È¤¦²ÄǽÀ­¤Î¤¢¤ë°Ê²¼¤Î¥¿¥¤¥×¤¬¤¢¤ê¤Þ¤¹¡¥
-
- T_NIL nil
- T_OBJECT Ä̾ï¤Î¥ª¥Ö¥¸¥§¥¯¥È
- T_CLASS ¥¯¥é¥¹
- T_MODULE ¥â¥¸¥å¡¼¥ë
- T_FLOAT ÉâÆ°¾®¿ôÅÀ¿ô
- T_STRING ʸ»úÎó
- T_REGEXP Àµµ¬É½¸½
- T_ARRAY ÇÛÎó
- T_FIXNUM Fixnum(31bitĹÀ°¿ô)
- T_HASH Ï¢ÁÛÇÛÎó
- T_STRUCT (Ruby¤Î)¹½Â¤ÂÎ
- T_BIGNUM ¿ÇÜĹÀ°¿ô
- T_FILE Æþ½ÐÎÏ
- T_TRUE ¿¿
- T_FALSE µ¶
- T_DATA ¥Ç¡¼¥¿
-
-¤½¤Î¾¤ËÆâÉô¤ÇÍøÍѤµ¤ì¤Æ¤¤¤ë°Ê²¼¤Î¥¿¥¤¥×¤¬¤¢¤ê¤Þ¤¹¡¥
-
- T_ICLASS
- T_MATCH
- T_VARMAP
- T_SCOPE
- T_NODE
-
-¤Û¤È¤ó¤É¤Î¥¿¥¤¥×¤ÏC¤Î¹½Â¤ÂΤǼÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
-1.2 VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ò¥Á¥§¥Ã¥¯¤¹¤ë
-
-ruby.h¤Ç¤ÏTYPE()¤È¤¤¤¦¥Þ¥¯¥í¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Æ¡¤VALUE¤Î¥Ç¡¼¥¿
-¥¿¥¤¥×¤òÃΤ뤳¤È¤¬½ÐÍè¤Þ¤¹¡¥TYPE()¥Þ¥¯¥í¤Ï¾å¤Ç¾Ò²ð¤·¤¿T_XXXX
-¤Î·Á¼°¤ÎÄê¿ô¤òÊÖ¤·¤Þ¤¹¡¥VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤Ë±þ¤¸¤Æ½èÍý¤¹¤ë
-¾ì¹ç¤Ë¤Ï¡¤TYPE()¤ÎÃͤÇʬ´ô¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
- switch (TYPE(obj)) {
- case T_FIXNUM:
- /* FIXNUM¤Î½èÍý */
- break;
- case T_STRING:
- /* ʸ»úÎó¤Î½èÍý */
- break;
- case T_ARRAY:
- /* ÇÛÎó¤Î½èÍý */
- break;
- default:
- /* Îã³°¤òȯÀ¸¤µ¤»¤ë */
- TypeError("not valid value");
- break;
- }
-
-¤½¤ì¤È¥Ç¡¼¥¿¥¿¥¤¥×¤ò¥Á¥§¥Ã¥¯¤·¤Æ¡¤Àµ¤·¤¯¤Ê¤±¤ì¤ÐÎã³°¤òȯÀ¸¤¹
-¤ë´Ø¿ô¤¬ÍѰդµ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- void Check_Type(VALUE value, int type)
-
-¤³¤Î´Ø¿ô¤Ïvalue¤¬type¤Ç̵¤±¤ì¤Ð¡¤Îã³°¤òȯÀ¸¤µ¤»¤Þ¤¹¡¥°ú¿ô¤È
-¤·¤ÆÍ¿¤¨¤é¤ì¤¿VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤¬Àµ¤·¤¤¤«¤É¤¦¤«¥Á¥§¥Ã¥¯¤¹
-¤ë¤¿¤á¤Ë¤Ï¡¤¤³¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
-FIXNUM¤ÈNIL¤Ë´Ø¤·¤Æ¤Ï¤è¤ê¹â®¤ÊȽÊÌ¥Þ¥¯¥í¤¬ÍѰդµ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- FIXNUM_P(obj)
- NIL_P(obj)
-
-1.3 VALUE¤òC¤Î¥Ç¡¼¥¿¤ËÊÑ´¹¤¹¤ë
-
-¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_NIL, T_FALSE, T_TRUE¤Ç¤¢¤ë»þ¡¤¥Ç¡¼¥¿¤Ï¤½¤ì¤¾
-¤ìnil, false, true¤Ç¤¹¡¥¤³¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ï¤Ò¤È
-¤Ä¤º¤Ä¤·¤«Â¸ºß¤·¤Þ¤»¤ó¡¥
-
-¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_FIXNUM¤Î»þ¡¤¤³¤ì¤Ï31bit¤Î¥µ¥¤¥º¤ò»ý¤ÄÀ°¿ô¤Ç
-¤¹¡¥FIXNUM¤òC¤ÎÀ°¿ô¤ËÊÑ´¹¤¹¤ë¤¿¤á¤Ë¤Ï¥Þ¥¯¥í¡ÖFIX2INT()¡×¤ò»È
-¤¤¤Þ¤¹¡¥¤½¤ì¤«¤é¡¤FIXNUM¤Ë¸Â¤é¤ºRuby¤Î¥Ç¡¼¥¿¤òÀ°¿ô¤ËÊÑ´¹¤¹¤ë
-¡ÖNUM2INT()¡×¤È¤¤¤¦¥Þ¥¯¥í¤¬¤¢¤ê¤Þ¤¹¡¥¤³¤Î¥Þ¥¯¥í¤Ï¥Ç¡¼¥¿¥¿¥¤
-¥×¤Î¥Á¥§¥Ã¥¯Ìµ¤·¤Ç»È¤¨¤Þ¤¹(À°¿ô¤ËÊÑ´¹¤Ç¤­¤Ê¤¤¾ì¹ç¤Ë¤ÏÎã³°¤¬
-ȯÀ¸¤¹¤ë)¡¥
-
-ƱÍͤ˥Á¥§¥Ã¥¯Ìµ¤·¤Ç»È¤¨¤ëÊÑ´¹¥Þ¥¯¥í¤Ïdouble¤ò¼è¤ê½Ð¤¹
-¡ÖNUM2DBL()¡×¤Èchar*¤ò¼è¤ê½Ð¤¹¡ÖSTR2CSTR()¡×¤¬¤¢¤ê¤Þ¤¹¡¥
-
-¤½¤ì°Ê³°¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ÏÂбþ¤¹¤ëC¤Î¹½Â¤ÂΤ¬¤¢¤ê¤Þ¤¹¡¥Âбþ¤¹
-¤ë¹½Â¤ÂΤΤ¢¤ëVALUE¤Ï¤½¤Î¤Þ¤Þ¥­¥ã¥¹¥È(·¿ÊÑ´¹)¤¹¤ì¤Ð¹½Â¤ÂΤÎ
-¥Ý¥¤¥ó¥¿¤ËÊÑ´¹¤Ç¤­¤Þ¤¹¡¥
-
-¹½Â¤ÂΤϡÖstruct RXxxxx¡×¤È¤¤¤¦Ì¾Á°¤Çruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ
-¤¹¡¥Î㤨¤Ðʸ»úÎó¤Ï¡Östruct RString¡×¤Ç¤¹¡¥¼ÂºÝ¤Ë»È¤¦²ÄǽÀ­¤¬
-¤¢¤ë¤Î¤Ïʸ»úÎó¤ÈÇÛÎ󤯤餤¤À¤È»×¤¤¤Þ¤¹¡¥
-
-ruby.h¤Ç¤Ï¹½Â¤ÂΤإ­¥ã¥¹¥È¤¹¤ë¥Þ¥¯¥í¤â¡ÖRXXXXX()¡×(Á´ÉôÂçʸ
-»ú¤Ë¤·¤¿¤â¤Î)¤È¤¤¤¦Ì¾Á°¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹(Îã: RSTRING())¡¥
-
-Î㤨¤Ð¡¤Ê¸»úÎóstr¤ÎŤµ¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->len¡×¤È
-¤·¡¤Ê¸»úÎóstr¤òchar*¤È¤·¤ÆÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->ptr¡×
-¤È¤·¤Þ¤¹¡¥ÇÛÎó¤Î¾ì¹ç¤Ë¤Ï¡¤¤½¤ì¤¾¤ì¡ÖRARRAY(str)->len¡×¡¤
-¡ÖRARRAY(str)->ptr¡×¤È¤Ê¤ê¤Þ¤¹¡¥
-
-Ruby¤Î¹½Â¤ÂΤòľÀÜ¥¢¥¯¥»¥¹¤¹¤ë»þ¤Ëµ¤¤ò¤Ä¤±¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³
-¤È¤Ï¡¤ÇÛÎó¤äʸ»úÎó¤Î¹½Â¤ÂΤÎÃæ¿È¤Ï»²¾È¤¹¤ë¤À¤±¤Ç¡¤Ä¾ÀÜÊѹ¹¤·
-¤Ê¤¤¤³¤È¤Ç¤¹¡¥Ä¾ÀÜÊѹ¹¤·¤¿¾ì¹ç¡¤¥ª¥Ö¥¸¥§¥¯¥È¤ÎÆâÍÆ¤ÎÀ°¹çÀ­¤¬
-¤È¤ì¤Ê¤¯¤Ê¤Ã¤Æ¡¤»×¤ï¤Ì¥Ð¥°¤Î¸¶°ø¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-1.4 C¤Î¥Ç¡¼¥¿¤òVALUE¤ËÊÑ´¹¤¹¤ë
-
-VALUE¤Î¼ÂºÝ¤Î¹½Â¤¤Ï
-
- * FIXNUM¤Î¾ì¹ç
-
- 1bit±¦¥·¥Õ¥È¤·¤Æ¡¤LSB¤òΩ¤Æ¤ë¡¥
-
- * ¤½¤Î¾¤Î¥Ý¥¤¥ó¥¿¤Î¾ì¹ç
-
- ¤½¤Î¤Þ¤ÞVALUE¤Ë¥­¥ã¥¹¥È¤¹¤ë¡¥
-
-¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥¤è¤Ã¤Æ¡¤LSB¤ò¥Á¥§¥Ã¥¯¤¹¤ì¤ÐVALUE¤¬FIXNUM¤«¤É
-¤¦¤«¤ï¤«¤ë¤ï¤±¤Ç¤¹(¥Ý¥¤¥ó¥¿¤ÎLSB¤¬Î©¤Ã¤Æ¤¤¤Ê¤¤¤³¤È¤ò²¾Äꤷ¤Æ
-¤¤¤ë)¡¥
-
-¤Ç¤¹¤«¤é¡¤FIXNUM°Ê³°¤ÎRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î¹½Â¤ÂΤÏñ¤ËVALUE
-¤Ë¥­¥ã¥¹¥È¤¹¤ë¤À¤±¤ÇVALUE¤ËÊÑ´¹½ÐÍè¤Þ¤¹¡¥¤¿¤À¤·¡¤Ç¤°Õ¤Î¹½Â¤
-ÂΤ¬VALUE¤Ë¥­¥ã¥¹¥È½ÐÍè¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥¥­¥ã¥¹¥È¤¹¤ë¤Î
-¤ÏRuby¤ÎÃΤäƤ¤¤ë¹½Â¤ÂÎ(ruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëstruct RXxxx
-¤Î¤â¤Î)¤À¤±¤Ç¤¹¡¥
-
-FIXNUM¤Ë´Ø¤·¤Æ¤ÏÊÑ´¹¥Þ¥¯¥í¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥C¤ÎÀ°¿ô
-¤«¤éVALUE¤ËÊÑ´¹¤¹¤ë¥Þ¥¯¥í¤Ï°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡¥É¬Íפ˱þ¤¸
-¤Æ»È¤¤Ê¬¤±¤Æ¤¯¤À¤µ¤¤¡¥
-
- INT2FIX() ¤â¤È¤ÎÀ°¿ô¤¬31bit°ÊÆâ¤Ë¼ý¤Þ¤ë¼«¿®¤¬¤¢¤ë»þ
- INT2NUM() Ǥ°Õ¤ÎÀ°¿ô¤«¤éVALUE¤Ø
-
-INT2NUM()¤ÏÀ°¿ô¤¬FIXNUM¤ÎÈϰϤ˼ý¤Þ¤é¤Ê¤¤¾ì¹ç¡¤Bignum¤ËÊÑ´¹
-¤·¤Æ¤¯¤ì¤Þ¤¹(¤¬¡¤¾¯¤·ÃÙ¤¤)¡¥
-
-1.5 Ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë
-
-ÀèÄø¤â½Ò¤Ù¤¿Ä̤ꡤRuby¤Î¹½Â¤ÂΤò¥¢¥¯¥»¥¹¤¹¤ë»þ¤ËÆâÍÆ¤Î¹¹¿·¤ò
-¹Ô¤¦¤³¤È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥¤Ç¡¤Ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë»þ¤Ë¤Ï
-Ruby¤¬ÍѰդ·¤Æ¤¤¤ë´Ø¿ô¤òÍѤ¤¤Æ¤¯¤À¤µ¤¤¡¥
-
-¤³¤³¤Ç¤Ï¤â¤Ã¤È¤â»È¤ï¤ì¤ë¤Ç¤¢¤í¤¦Ê¸»úÎó¤ÈÇÛÎó¤ÎÀ¸À®/Áàºî¤ò¹Ô
-¤¤´Ø¿ô¤ò¤¢¤²¤Þ¤¹(Á´Éô¤Ç¤Ï¤Ê¤¤¤Ç¤¹)¡¥
-
- ʸ»úÎó¤ËÂФ¹¤ë´Ø¿ô
-
- str_new(char *ptr, int len)
-
- ¿·¤·¤¤Ruby¤Îʸ»úÎó¤òÀ¸À®¤¹¤ë¡¥
-
- str_new2(char *ptr)
-
- C¤Îʸ»úÎ󤫤éRuby¤Îʸ»úÎó¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤Îµ¡Ç½¤Ï
- str_new(ptr, strlen(ptr))¤ÈƱÅù¤Ç¤¢¤ë¡¥
-
- str_cat(VALUE str, char *ptr, int len)
-
- Ruby¤Îʸ»úÎóstr¤Ëlen¥Ð¥¤¥È¤Îʸ»úÎóptr¤òÄɲ乤롥
-
- ÇÛÎó¤ËÂФ¹¤ë´Ø¿ô
-
- ary_new()
-
- Í×ÁǤ¬0¤ÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
-
- ary_new2(int len)
-
- Í×ÁǤ¬0¤ÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥lenÍ×ÁÇʬ¤ÎÎΰè¤ò¤¢¤é¤«¤¸¤á³ä¤ê
- Åö¤Æ¤Æ¤ª¤¯¡¥
-
- ary_new3(int n, ...)
-
- °ú¿ô¤Ç»ØÄꤷ¤¿nÍ×ÁǤò´Þ¤àÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
-
- ary_new4(int n, VALUE *elts)
-
- ÇÛÎó¤ÇÍ¿¤¨¤¿nÍ×ÁǤÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
-
- ary_push(VALUE ary, VALUE val)
- ary_pop(VALUE ary)
- ary_shift(VALUE ary)
- ary_unshift(VALUE ary, VALUE val)
- ary_entry(VALUE ary, int idx)
-
- Array¤ÎƱ̾¤Î¥á¥½¥Ã¥É¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë´Ø¿ô¡¥Âè1°ú¿ô¤Ïɬ¤º
- ÇÛÎó¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-
-2¡¥Ruby¤Îµ¡Ç½¤ò»È¤¦
-
-¸¶ÍýŪ¤ËRuby¤Ç½ñ¤±¤ë¤³¤È¤ÏC¤Ç¤â½ñ¤±¤Þ¤¹¡¥Ruby¤½¤Î¤â¤Î¤¬C¤Çµ­
-½Ò¤µ¤ì¤Æ¤¤¤ë¤ó¤Ç¤¹¤«¤é¡¤ÅöÁ³¤È¤¤¤¨¤ÐÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¥¤³¤³¤Ç
-¤ÏRuby¤Î³ÈÄ¥¤Ë»È¤¦¤³¤È¤¬Â¿¤¤¤À¤í¤¦¤Èͽ¬¤µ¤ì¤ëµ¡Ç½¤òÃæ¿´¤Ë¾Ò
-²ð¤·¤Þ¤¹¡¥
-
-2.1 Ruby¤Ëµ¡Ç½¤òÄɲ乤ë
-
-Ruby¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤¨¤ÐRuby¥¤¥ó¥¿¥×¥ê¥¿¤Ë¿·¤·¤¤µ¡Ç½
-¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡¥Ruby¤Ç¤Ï°Ê²¼¤Îµ¡Ç½¤òÄɲä¹¤ë´Ø¿ô¤¬
-Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- * ¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë
- * ¥á¥½¥Ã¥É¡¤ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É
- * Äê¿ô
-
-¤Ç¤Ï½ç¤Ë¾Ò²ð¤·¤Þ¤¹¡¥
-
-2.1.1 ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
-
-¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- VALUE rb_define_class(char *name, VALUE super)
- VALUE rb_define_module(char *name)
-
-¤³¤ì¤é¤Î´Ø¿ô¤Ï¿·¤·¤¯ÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÊÖ¤·¤Þ¤¹¡¥
-¥á¥½¥Ã¥É¤äÄê¿ô¤ÎÄêµÁ¤Ë¤³¤ì¤é¤ÎÃͤ¬É¬ÍפʤΤǡ¤¤Û¤È¤ó¤É¤Î¾ì¹ç
-¤ÏÌá¤êÃͤòÊÑ¿ô¤Ë³ÊǼ¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡¥
-
-¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤ò¾¤Î¥¯¥é¥¹¤ÎÆâÉô¤Ë¥Í¥¹¥È¤·¤ÆÄêµÁ¤¹¤ë»þ¤Ë
-¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- VALUE rb_define_class(VALUE outer, char *name, VALUE super)
- VALUE rb_define_module(VALUE outer, char *name)
-
-2.1.2 ¥á¥½¥Ã¥É/ÆÃ°Û¥á¥½¥Ã¥ÉÄêµÁ
-
-¥á¥½¥Ã¥É¤äÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- void rb_define_method(VALUE class, char *name,
- VALUE (*func)(), int argc)
-
- void rb_define_singleton_method(VALUE object, char *name,
- VALUE (*func)(), int argc)
-
-
-ǰ¤Î¤¿¤áÀâÌÀ¤¹¤ë¤È¡ÖÆÃ°Û¥á¥½¥Ã¥É¡×¤È¤Ï¡¤¤½¤ÎÆÃÄê¤Î¥ª¥Ö¥¸¥§¥¯
-¥È¤ËÂФ·¤Æ¤À¤±Í­¸ú¤Ê¥á¥½¥Ã¥É¤Ç¤¹¡¥Ruby¤Ç¤Ï¤è¤¯Smalltalk¤Ë¤ª
-¤±¤ë¥¯¥é¥¹¥á¥½¥Ã¥É¤È¤·¤Æ¡¤¥¯¥é¥¹¤ËÂФ¹¤ëÆÃ°Û¥á¥½¥Ã¥É¤¬»È¤ï¤ì
-¤Þ¤¹¡¥
-
-¤³¤ì¤é¤Î´Ø¿ô¤Î argc¤È¤¤¤¦°ú¿ô¤ÏC¤Î´Ø¿ô¤ØÅϤµ¤ì¤ë°ú¿ô¤Î¿ô(¤È
-·Á¼°)¤ò·è¤á¤Þ¤¹¡¥argc¤¬Àµ¤Î»þ¤Ï´Ø¿ô¤Ë°ú¤­ÅϤ¹°ú¿ô¤Î¿ô¤ò°ÕÌ£
-¤·¤Þ¤¹¡¥16¸Ä°Ê¾å¤Î°ú¿ô¤Ï»È¤¨¤Þ¤»¤ó(¤¬¡¤Íפê¤Þ¤»¤ó¤è¤Í¡¤¤½¤ó
-¤Ê¤Ë)¡¥¼ÂºÝ¤Î´Ø¿ô¤Ë¤ÏÀèÆ¬¤Î°ú¿ô¤È¤·¤Æself¤¬Í¿¤¨¤é¤ì¤Þ¤¹¤Î¤Ç¡¤
-»ØÄꤷ¤¿¿ô¤è¤ê1¿¤¤°ú¿ô¤ò»ý¤Ä¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-argc¤¬Éé¤Î»þ¤Ï°ú¿ô¤Î¿ô¤Ç¤Ï¤Ê¤¯¡¤·Á¼°¤ò»ØÄꤷ¤¿¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-argc¤¬-1¤Î»þ¤Ï°ú¿ô¤òÇÛÎó¤ËÆþ¤ì¤ÆÅϤµ¤ì¤Þ¤¹¡¥argc¤¬-2¤Î»þ¤Ï°ú
-¿ô¤ÏRuby¤ÎÇÛÎó¤È¤·¤ÆÅϤµ¤ì¤Þ¤¹¡¥
-
-¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï¤â¤¦Æó¤Ä¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ïprivate¥á
-¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ç¡¤°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¤Ç¤¹¡¥
-
- void rb_define_private_method(VALUE class, char *name,
- VALUE (*func)(), int argc)
-
-private¥á¥½¥Ã¥É¤È¤Ï´Ø¿ô·Á¼°¤Ç¤·¤«¸Æ¤Ó½Ð¤¹¤³¤È¤Î½ÐÍè¤Ê¤¤¥á¥½¥Ã
-¥É¤Ç¤¹¡¥
-
-¤â¤¦¤Ò¤È¤Ä¤Ï¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô
-¤È¤Ï¥â¥¸¥å¡¼¥ë¤ÎÆÃ°Û¥á¥½¥Ã¥É¤Ç¤¢¤ê¡¤Æ±»þ¤Ëprivate¥á¥½¥Ã¥É¤Ç
-¤â¤¢¤ë¤â¤Î¤Ç¤¹¡¥Îã¤ò¤¢¤²¤ë¤ÈMath¥â¥¸¥å¡¼¥ë¤Îsqrt()¤Ê¤É¤¬¤¢¤²
-¤é¤ì¤Þ¤¹¡¥¤³¤Î¥á¥½¥Ã¥É¤Ï
-
- Math.sqrt(4)
-
-¤È¤¤¤¦·Á¼°¤Ç¤â
-
- include Math
- sqrt(4)
-
-¤È¤¤¤¦·Á¼°¤Ç¤â»È¤¨¤Þ¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤Î
-Ä̤ê¤Ç¤¹¡¥
-
- void rb_define_module_function(VALUE module, char *name,
- VALUE (*func)(), int argc)
-
-´Ø¿ôŪ¥á¥½¥Ã¥É(Kernel¥â¥¸¥å¡¼¥ë¤Îprivate method)¤òÄêµÁ¤¹¤ë¤¿
-¤á¤Î´Ø¿ô¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¹¡¥
-
- void rb_define_global_function(char *name, VALUE (*func)(), int argc)
-
-
-2.1.3 Äê¿ôÄêµÁ
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ë¤¬É¬ÍפÊÄê¿ô¤Ï¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤
-¤Ç¤·¤ç¤¦¡¥Äê¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_const(VALUE class, char *name, VALUE val)
- void rb_define_global_const(char *name, VALUE val)
-
-Á°¼Ô¤ÏÆÃÄê¤Î¥¯¥é¥¹/¥â¥¸¥å¡¼¥ë¤Ë°¤¹¤ëÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¡¤¸å
-¼Ô¤Ï¥°¥í¡¼¥Ð¥ë¤ÊÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥
-
-2.2 Ruby¤Îµ¡Ç½¤òC¤«¤é¸Æ¤Ó½Ð¤¹
-
-´û¤Ë¡Ø1.5 Ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë¡Ù¤Ç°ìÉô¾Ò²ð¤·¤¿¤è¤¦¤Ê´Ø¿ô¤ò
-»È¤¨¤Ð¡¤Ruby¤Îµ¡Ç½¤ò¼Â¸½¤·¤Æ¤¤¤ë´Ø¿ô¤òľÀܸƤӽФ¹¤³¤È¤¬½ÐÍè
-¤Þ¤¹¡¥
-
-# ¤³¤Î¤è¤¦¤Ê´Ø¿ô¤Î°ìÍ÷ɽ¤Ï¤¤¤Þ¤Î¤È¤³¤í¤¢¤ê¤Þ¤»¤ó¡¥¥½¡¼¥¹¤ò¸«
-# ¤ë¤·¤«¤Ê¤¤¤Ç¤¹¤Í¡¥
-
-¤½¤ì°Ê³°¤Ë¤âRuby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹ÊýË¡¤Ï¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡¥
-
-2.2.1 Ruby¤Î¥×¥í¥°¥é¥à¤òeval¤¹¤ë
-
-C¤«¤éRuby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤È¤·¤Æ¡¤Ê¸»úÎó¤Ç
-Í¿¤¨¤é¤ì¤¿Ruby¤Î¥×¥í¥°¥é¥à¤òɾ²Á¤¹¤ë´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
-
- VALUE rb_eval_string(char *str)
-
-¤³¤Îɾ²Á¤Ï¸½ºß¤Î´Ä¶­¤Ç¹Ô¤ï¤ì¤Þ¤¹¡¥¤Ä¤Þ¤ê¡¤¸½ºß¤Î¥í¡¼¥«¥ëÊÑ¿ô
-¤Ê¤É¤ò¼õ¤±·Ñ¤®¤Þ¤¹¡¥
-
-2.2.2 ID¤Þ¤¿¤Ï¥·¥ó¥Ü¥ë
-
-C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤ËRuby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤â¤Ç¤­¤Þ
-¤¹¡¥¤½¤ÎÁ°¤Ë¡¤Ruby¥¤¥ó¥¿¥×¥ê¥¿Æâ¤Ç¥á¥½¥Ã¥É¤äÊÑ¿ô̾¤ò»ØÄꤹ¤ë
-»þ¤Ë»È¤ï¤ì¤Æ¤¤¤ëID¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤ª¤­¤Þ¤·¤ç¤¦¡¥
-
-ID¤È¤ÏÊÑ¿ô̾¡¤¥á¥½¥Ã¥É̾¤òɽ¤¹À°¿ô¤Ç¤¹¡¥Ruby¤ÎÃæ¤Ç¤Ï
-
- :¼±ÊÌ»Ò
-
-¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹¡¥C¤«¤é¤³¤ÎÀ°¿ô¤òÆÀ¤ë¤¿¤á¤Ë¤Ï´Ø¿ô
-
- rb_intern(char *name)
-
-¤ò»È¤¤¤Þ¤¹¡¥¤Þ¤¿°ìʸ»ú¤Î±é»»»Ò¤Ï¤½¤Îʸ»ú¥³¡¼¥É¤¬¤½¤Î¤Þ¤Þ¥·¥ó
-¥Ü¥ë¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥Ruby¤«¤é°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿¥·¥ó¥Ü¥ë(¤Þ
-¤¿¤Ïʸ»úÎó)¤òID¤ËÊÑ´¹¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- rb_to_id(VALUE symbol)
-
-2.2.3 C¤«¤éRuby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹
-
-C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤ËRuby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤¿¤á¤Ë¤Ï°Ê²¼
-¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
-
- VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
-
-¤³¤Î´Ø¿ô¤Ï¥ª¥Ö¥¸¥§¥¯¥Èrecv¤Îmid¤Ç»ØÄꤵ¤ì¤ë¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð
-¤·¤Þ¤¹¡¥¤½¤Î¾¤Ë°ú¿ô¤Î»ØÄê¤Î»ÅÊý¤¬°ã¤¦°Ê²¼¤Î´Ø¿ô¤â¤¢¤ê¤Þ¤¹¡¥
-
- VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
- VALUE rb_apply(VALUE recv, ID mid, VALUE args)
-
-apply¤Ë¤Ï°ú¿ô¤È¤·¤ÆRuby¤ÎÇÛÎó¤òÍ¿¤¨¤Þ¤¹¡¥
-
-2.2.4 ÊÑ¿ô/Äê¿ô¤ò»²¾È/¹¹¿·¤¹¤ë
-
-C¤«¤é´Ø¿ô¤ò»È¤Ã¤Æ»²¾È¡¦¹¹¿·¤Ç¤­¤ë¤Î¤Ï¡¤¥¯¥é¥¹Äê¿ô¡¤¥¤¥ó¥¹¥¿
-¥ó¥¹ÊÑ¿ô¤Ç¤¹¡¥Âç°èÊÑ¿ô¤Ï°ìÉô¤Î¤â¤Î¤ÏC¤ÎÂç°èÊÑ¿ô¤È¤·¤Æ¥¢¥¯¥»
-¥¹¤Ç¤­¤Þ¤¹¡¥¥í¡¼¥«¥ëÊÑ¿ô¤ò»²¾È¤¹¤ëÊýË¡¤Ï¸ø³«¤·¤Æ¤¤¤Þ¤»¤ó¡¥
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¡¦¹¹¿·¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤ÎÄÌ
-¤ê¤Ç¤¹¡¥
-
- VALUE rb_ivar_get(VALUE obj, ID id)
- VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
-
-id¤Ïrb_intern()¤ÇÆÀ¤é¤ì¤ë¤â¤Î¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
-¥¯¥é¥¹Äê¿ô¤ò»²¾È¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
- VALUE rb_const_get(VALUE obj, ID id)
-
-¥¯¥é¥¹Äê¿ô¤ò¿·¤·¤¯ÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡Ø2.1.3 Äê¿ôÄêµÁ¡Ù¤Ç¾Ò²ð¤µ
-¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
-3¡¥Ruby¤ÈC¤È¤Î¾ðÊó¶¦Í­
-
-C¸À¸ì¤ÈRuby¤Î´Ö¤Ç¾ðÊó¤ò¶¦Í­¤¹¤ëÊýË¡¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Þ¤¹¡¥
-
-3.1 C¤«¤é»²¾È¤Ç¤­¤ëRuby¤ÎÄê¿ô
-
-°Ê²¼¤ÎRuby¤ÎÄê¿ô¤ÏC¤Î¥ì¥Ù¥ë¤«¤é»²¾È¤Ç¤­¤ë¡¥
-
- TRUE
- FALSE
-
-¿¿µ¶ÃÍ¡¥FALSE¤ÏC¸À¸ì¤Ç¤âµ¶¤È¤ß¤Ê¤µ¤ì¤ë(¤Ä¤Þ¤ê0)¡¥
-
- Qnil
-
-C¸À¸ì¤«¤é¸«¤¿¡Önil¡×¡¥
-
-3.2 C¤ÈRuby¤Ç¶¦Í­¤µ¤ì¤ëÂç°èÊÑ¿ô
-
-C¤ÈRuby¤ÇÂç°èÊÑ¿ô¤ò»È¤Ã¤Æ¾ðÊó¤ò¶¦Í­¤Ç¤­¤Þ¤¹¡¥¶¦Í­¤Ç¤­¤ëÂç°è
-ÊÑ¿ô¤Ë¤Ï¤¤¤¯¤Ä¤«¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡¥¤½¤Î¤Ê¤«¤Ç¤â¤Ã¤È¤âÎɤ¯»È¤ï
-¤ì¤ë¤È»×¤ï¤ì¤ë¤Î¤Ïrb_define_variable()¤Ç¤¹¡¥
-
- void rb_define_variable(char *name, VALUE *var)
-
-¤³¤Î´Ø¿ô¤ÏRuby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëÂç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ¤¹¡¥ÊÑ¿ô̾¤¬
-`$'¤Ç»Ï¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤòÊÑ
-¹¹¤¹¤ë¤È¼«Æ°Åª¤ËRuby¤ÎÂбþ¤¹¤ëÊÑ¿ô¤ÎÃͤâÊѤï¤ê¤Þ¤¹¡¥
-
-¤Þ¤¿Ruby¦¤«¤é¤Ï¹¹¿·¤Ç¤­¤Ê¤¤ÊÑ¿ô¤â¤¢¤ê¤Þ¤¹¡¥¤³¤Îread only¤Î
-ÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ÇÄêµÁ¤·¤Þ¤¹¡¥
-
- void rb_define_readonly_variable(char *name, VALUE *var)
-
-¤³¤ì¤éÊÑ¿ô¤Î¾¤Ëhook¤ò¤Ä¤±¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤Ç¤­¤Þ¤¹¡¥hookÉÕ¤­
-¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤òÍѤ¤¤ÆÄêµÁ¤·¤Þ¤¹¡¥hookÉÕ¤­Âç°èÊÑ¿ô¤Î
-Ãͤλ²¾È¤äÀßÄê¤Ïhook¤Ç¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_hooked_variable(char *name, VALUE *var,
- VALUE (*getter)(), VALUE (*setter)())
-
-¤³¤Î´Ø¿ô¤ÏC¤Î´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ
-¤¹¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï´Ø¿ôgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì
-¤¿»þ¤Ë¤Ï´Ø¿ôsetter¤¬¸Æ¤Ð¤ì¤ë¡¥hook¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ïgetter¤ä
-setter¤Ë0¤ò»ØÄꤷ¤Þ¤¹¡¥
-
-# getter¤âsetter¤â0¤Ê¤é¤Ðrb_define_variable()¤ÈƱ¤¸¤Ë¤Ê¤ë¡¥
-
-¤½¤ì¤«¤é¡¤C¤Î´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRuby¤ÎÂç°èÊÑ¿ô¤òÄêµÁ¤¹¤ë
-´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
-
- void rb_define_virtual_variable(char *name,
- VALUE (*getter)(), VALUE (*setter)())
-
-¤³¤Î´Ø¿ô¤Ë¤è¤Ã¤ÆÄêµÁ¤µ¤ì¤¿Ruby¤ÎÂç°èÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï
-getter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤Þ¤¹¡¥
-
-getter¤Èsetter¤Î»ÅÍͤϰʲ¼¤ÎÄ̤ê¤Ç¤¹¡¥
-
- (*getter)(ID id, void *data, struct global_entry* entry);
- (*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
-
-3.3 C¤Î¥Ç¡¼¥¿¤òRuby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤¹¤ë
-
-C¤ÎÀ¤³¦¤ÇÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿(¹½Â¤ÂÎ)¤òRuby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ
-¼è¤ê°·¤¤¤¿¤¤¾ì¹ç¤¬¤¢¤ê¤¨¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤Data¤È¤¤¤¦
-Ruby¥ª¥Ö¥¸¥§¥¯¥È¤ËC¤Î¹½Â¤ÂÎ(¤Ø¤Î¥Ý¥¤¥ó¥¿)¤ò¤¯¤ë¤à¤³¤È¤ÇRuby
-¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ¼è¤ê°·¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Æ¹½Â¤ÂΤòRuby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥«¥×¥»¥ë
-²½¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤¤¤Þ¤¹¡¥
-
- Data_Wrap_Struct(class,mark,free,ptr)
-
-¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
-
-class¤Ï¤³¤ÎData¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¤Ç¤¹¡¥ptr¤Ï¥«¥×¥»¥ë²½¤¹¤ë
-C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤Ç¤¹¡¥mark¤Ï¤³¤Î¹½Â¤ÂΤ¬Ruby¤Î¥ª¥Ö¥¸¥§
-¥¯¥È¤Ø¤Î»²¾È¤¬¤¢¤ë»þ¤Ë»È¤¦´Ø¿ô¤Ç¤¹¡¥¤½¤Î¤è¤¦¤Ê»²¾È¤ò´Þ¤Þ¤Ê¤¤
-»þ¤Ë¤Ï0¤ò»ØÄꤷ¤Þ¤¹¡¥
-
-# ¤½¤Î¤è¤¦¤Ê»²¾È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥
-
-free¤Ï¤³¤Î¹½Â¤ÂΤ¬¤â¤¦ÉÔÍפˤʤä¿»þ¤Ë¸Æ¤Ð¤ì¤ë´Ø¿ô¤Ç¤¹¡¥¤³¤Î
-´Ø¿ô¤¬¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿¤«¤é¸Æ¤Ð¤ì¤Þ¤¹¡¥
-
-C¤Î¹½Â¤ÂΤγäÅö¤ÈData¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤òƱ»þ¤Ë¹Ô¤¦¥Þ¥¯¥í¤È
-¤·¤Æ°Ê²¼¤Î¤â¤Î¤¬Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
-
- Data_Make_Struct(class, type, mark, free, sval)
-
-¤³¤Î¥Þ¥¯¥í¤ÎÌá¤êÃͤÏÀ¸À®¤µ¤ì¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡¥
-
-class, mark, free¤ÏData_Wrap_Struct¤ÈƱ¤¸Æ¯¤­¤ò¤·¤Þ¤¹¡¥type
-¤Ï³ä¤êÅö¤Æ¤ëC¹½Â¤ÂΤη¿¤Ç¤¹¡¥³ä¤êÅö¤Æ¤é¤ì¤¿¹½Â¤ÂΤÏÊÑ¿ôsval
-¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤Î·¿¤Ï (type*) ¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤é¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤Î¤Ï°Ê²¼¤Î¥Þ¥¯¥í¤òÍѤ¤
-¤Þ¤¹¡¥
-
- Data_Get_Struct(obj, type, sval)
-
-C¤Î¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤ÏÊÑ¿ôsval¤ËÂåÆþ¤µ¤ì¤Þ¤¹¡¥
-
-¤³¤ì¤é¤ÎData¤Î»È¤¤Êý¤Ï¤Á¤ç¤Ã¤Èʬ¤«¤ê¤Ë¤¯¤¤¤Î¤Ç¡¤¸å¤ÇÀâÌÀ¤¹¤ë
-ÎãÂê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-4¡¥ÎãÂê - dbm¥Ñ¥Ã¥±¡¼¥¸¤òºî¤ë
-
-¤³¤³¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤È¤ê¤¢¤¨¤º³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ïºî¤ì¤ë¤Ï¤º¤Ç¤¹¡¥
-Ruby¤Îext¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¹¤Ç¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ëdbm¥â¥¸¥å¡¼¥ë¤òÎã¤Ë
-¤·¤ÆÃʳ¬Åª¤ËÀâÌÀ¤·¤Þ¤¹¡¥
-
-(1) ¥Ç¥£¥ì¥¯¥È¥ê¤òºî¤ë
-
- % mkdir ext/dbm
-
-Ruby 1.1¤«¤é¤ÏǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¥À¥¤¥Ê¥ß¥Ã¥¯¥é¥¤¥Ö¥é¥ê¤òºî
-¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡¥Ruby¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë¾ì¹ç¤Ë
-¤ÏRuby¤òŸ³«¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¡¤ext¥Ç¥£¥ì¥¯¥È¥ê¤ÎÃæ¤Ë³ÈÄ¥
-¥â¥¸¥å¡¼¥ëÍѤΥǥ£¥ì¥¯¥È¥ê¤òºî¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥Ì¾Á°¤ÏŬÅö¤Ë
-Áª¤ó¤Ç¹½¤¤¤Þ¤»¤ó¡¥
-
-(2) MANIFEST¥Õ¥¡¥¤¥ë¤òºî¤ë
-
- % cd ext/dbm
- % touch MANIFEST
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤ÏMANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬
-ɬÍפʤΤǡ¤¤È¤ê¤¢¤¨¤º¶õ¤Î¥Õ¥¡¥¤¥ë¤òºî¤Ã¤Æ¤ª¤­¤Þ¤¹¡¥¸å¤Ç¤³¤Î
-¥Õ¥¡¥¤¥ë¤Ë¤ÏɬÍפʥե¡¥¤¥ë°ìÍ÷¤¬Æþ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-MANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤Ï¡¤ÀÅŪ¥ê¥ó¥¯¤Îmake¤Î»þ¤Ë¥Ç¥£¥ì¥¯¥È¥ê
-¤¬³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò´Þ¤ó¤Ç¤¤¤ë¤«¤É¤¦¤«È½Äꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ì¤Æ
-¤¤¤Þ¤¹¡¥¥À¥¤¥Ê¥ß¥Ã¥¯¥é¥¤¥Ö¥é¥ê¤òºî¤ë¾ì¹ç¤Ë¤Ïɬ¤º¤·¤âɬÍפǤÏ
-¤¢¤ê¤Þ¤»¤ó¡¥
-
-(3) À߷פ¹¤ë
-
-¤Þ¤¢¡¤ÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¤¤É¤¦¤¤¤¦µ¡Ç½¤ò¼Â¸½¤¹¤ë¤«¤É¤¦¤«¤Þ¤ºÀß
-·×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¤É¤ó¤Ê¥¯¥é¥¹¤ò¤Ä¤¯¤ë¤«¡¤¤½¤Î¥¯¥é¥¹¤Ë¤Ï
-¤É¤ó¤Ê¥á¥½¥Ã¥É¤¬¤¢¤ë¤«¡¤¥¯¥é¥¹¤¬Ä󶡤¹¤ëÄê¿ô¤Ê¤É¤Ë¤Ä¤¤¤ÆÀß·×
-¤·¤Þ¤¹¡¥dbm¥¯¥é¥¹¤Ë¤Ä¤¤¤Æ¤Ïext/dbm.doc¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-(4) C¥³¡¼¥É¤ò½ñ¤¯
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ëËÜÂΤȤʤëC¸À¸ì¤Î¥½¡¼¥¹¤ò½ñ¤­¤Þ¤¹¡¥C¸À¸ì¤Î¥½¡¼
-¥¹¤¬¤Ò¤È¤Ä¤Î»þ¤Ë¤Ï¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤òÁª¤Ö¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡¥C
-¸À¸ì¤Î¥½¡¼¥¹¤¬Ê£¿ô¤Î¾ì¹ç¤Ë¤ÏµÕ¤Ë¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤È¤¤¤¦¥Õ¥¡
-¥¤¥ë̾¤ÏÈò¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤È¥â¥¸¥å¡¼
-¥ëÀ¸À®»þ¤ËÃæ´ÖŪ¤ËÀ¸À®¤µ¤ì¤ë¡Ö¥â¥¸¥å¡¼¥ë̾.o¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë
-¤È¤¬¾×ÆÍ¤¹¤ë¤«¤é¤Ç¤¹¡¥
-
-Ruby¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë»þ¤Ë¡ÖInit_¥â¥¸¥å¡¼¥ë̾¡×¤È
-¤¤¤¦´Ø¿ô¤ò¼«Æ°Åª¤Ë¼Â¹Ô¤·¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤Î¾ì¹ç¡ÖInit_dbm¡×
-¤Ç¤¹¡¥¤³¤Î´Ø¿ô¤ÎÃæ¤Ç¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë¡¤¥á¥½¥Ã¥É¡¤Äê¿ô¤Ê¤É¤Î
-ÄêµÁ¤ò¹Ô¤¤¤Þ¤¹¡¥dbm.c¤«¤é°ìÉô°úÍѤ·¤Þ¤¹¡¥
-
---
-Init_dbm()
-{
- /* DBM¥¯¥é¥¹¤òÄêµÁ¤¹¤ë */
- cDBM = rb_define_class("DBM", cObject);
- /* DBM¤ÏEnumerate¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë */
- rb_include_module(cDBM, mEnumerable);
-
- /* DBM¥¯¥é¥¹¤Î¥¯¥é¥¹¥á¥½¥Ã¥Éopen(): °ú¿ô¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë */
- rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
-
- /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥Éclose(): °ú¿ô¤Ï¤Ê¤· */
- rb_define_method(cDBM, "close", fdbm_close, 0);
- /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥É[]: °ú¿ô¤Ï1¸Ä */
- rb_define_method(cDBM, "[]", fdbm_fetch, 1);
- :
-
- /* DBM¥Ç¡¼¥¿¤ò³ÊǼ¤¹¤ë¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô̾¤Î¤¿¤á¤ÎID */
- id_dbm = rb_intern("dbm");
-}
---
-
-DBM¥â¥¸¥å¡¼¥ë¤Ïdbm¤Î¥Ç¡¼¥¿¤ÈÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤ë¤Ï¤º¤Ç
-¤¹¤«¤é¡¤C¤ÎÀ¤³¦¤Îdbm¤òRuby¤ÎÀ¤³¦¤Ë¼è¤ê¹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
-
-
-dbm.c¤Ç¤ÏData_Make_Struct¤ò°Ê²¼¤Î¤è¤¦¤Ë»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-struct dbmdata {
- int di_size;
- DBM *di_dbm;
-};
-
-
-obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp);
---
-
-¤³¤³¤Ç¤Ïdbmstruct¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤òData¤Ë¥«¥×¥»¥ë²½¤·¤Æ¤¤
-¤Þ¤¹¡¥DBM*¤òľÀÜ¥«¥×¥»¥ë²½¤·¤Ê¤¤¤Î¤Ïclose()¤·¤¿»þ¤Î½èÍý¤ò¹Í
-¤¨¤Æ¤Î¤³¤È¤Ç¤¹¡¥
-
-Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤édbmstruct¹½Â¤ÂΤΥݥ¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á
-¤Ë°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-#define GetDBM(obj, dbmp) {\
- Data_Get_Struct(obj, struct dbmdata, dbmp);\
- if (dbmp->di_dbm == 0) closed_dbm();\
-}
---
-
-¤Á¤ç¤Ã¤ÈÊ£»¨¤Ê¥Þ¥¯¥í¤Ç¤¹¤¬¡¤Íפ¹¤ë¤Ëdbmdata¹½Â¤ÂΤΥݥ¤¥ó¥¿
-¤Î¼è¤ê½Ð¤·¤È¡¤close¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤ò¤Þ¤È¤á¤Æ¤¤
-¤ë¤À¤±¤Ç¤¹¡¥
-
-DBM¥¯¥é¥¹¤Ë¤Ï¤¿¤¯¤µ¤ó¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¤¬¡¤Ê¬Îह¤ë¤È3¼ïÎà¤Î
-°ú¿ô¤Î¼õ¤±Êý¤¬¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ï°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¤â¤Î¤Ç¡¤Îã¤È
-¤·¤Æ¤Ïdelete¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¡¥delete¥á¥½¥Ã¥É¤ò¼ÂÁõ¤·¤Æ¤¤¤ë
-fdbm_delete()¤Ï¤³¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-static VALUE
-fdbm_delete(obj, keystr)
- VALUE obj, keystr;
-{
- :
-}
---
-
-°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¥¿¥¤¥×¤ÏÂè1°ú¿ô¤¬self¡¤Âè2°ú¿ô°Ê¹ß¤¬¥á¥½¥Ã¥É
-¤Î°ú¿ô¤È¤Ê¤ê¤Þ¤¹¡¥
-
-°ú¿ô¤Î¿ô¤¬ÉÔÄê¤Î¤â¤Î¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î¤ÈRuby¤ÎÇÛÎó¤Ç¼õ¤±
-¤ë¤â¤Î¤È¤¬¤¢¤ê¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Ç¡¤C¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î
-¤ÏDBM¤Î¥¯¥é¥¹¥á¥½¥Ã¥É¤Ç¤¢¤ëopen()¤Ç¤¹¡¥¤³¤ì¤ò¼ÂÁõ¤·¤Æ¤¤¤ë´Ø
-¿ôfdbm_s_open()¤Ï¤³¤¦¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
-
---
-static VALUE
-fdbm_s_open(argc, argv, class)
- int argc;
- VALUE *argv;
- VALUE class;
-{
- :
- if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
- mode = 0666; /* default value */
- }
- :
-}
---
-
-¤³¤Î¥¿¥¤¥×¤Î´Ø¿ô¤ÏÂè1°ú¿ô¤¬Í¿¤¨¤é¤ì¤¿°ú¿ô¤Î¿ô¡¤Âè2°ú¿ô¤¬Í¿¤¨
-¤é¤ì¤¿°ú¿ô¤ÎÆþ¤Ã¤Æ¤¤¤ëÇÛÎó¤Ë¤Ê¤ê¤Þ¤¹¡¥self¤ÏÂè3°ú¿ô¤È¤·¤ÆÍ¿
-¤¨¤é¤ì¤Þ¤¹¡¥
-
-¤³¤ÎÇÛÎó¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤ò²òÀϤ¹¤ë¤¿¤á¤Î´Ø¿ô¤¬open()¤Ç¤â»È¤ï
-¤ì¤Æ¤¤¤ërb_scan_args()¤Ç¤¹¡¥Âè3°ú¿ô¤Ë»ØÄꤷ¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë
-½¾¤¤¡¤Âè4ÊÑ¿ô°Ê¹ß¤Ë»ØÄꤷ¤¿ÊÑ¿ô¤ËÃͤòÂåÆþ¤·¤Æ¤¯¤ì¤Þ¤¹¡¥¤³¤Î
-¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¡¤Âè1ʸ»úÌܤ¬¾Êά¤Ç¤­¤Ê¤¤°ú¿ô¤Î¿ô¡¤Âè2ʸ»úÌܤ¬
-¾Êά¤Ç¤­¤ë°ú¿ô¤Î¿ô¡¤Âè3ʸ»úÌܤ¬Âбþ¤¹¤ëÁê¼ê¤¬Ìµ¤¤¤¢¤Þ¤ê¤Î°ú
-¿ô¤¬¤¢¤ë¤«¤É¤¦¤«¤ò¼¨¤¹"*"¤Ç¤¹¡¥2ʸ»úÌܤÈ3ʸ»úÌܤϾÊά¤Ç¤­¤Þ
-¤¹¡¥dbm.c¤ÎÎã¤Ç¤Ï¡¤¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï"11"¤Ç¤¹¤«¤é¡¤°ú¿ô¤ÏºÇÄã1¤Ä
-¤Ç¡¤2¤Ä¤Þ¤Çµö¤µ¤ì¤ë¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡¥¾Êά¤µ¤ì¤Æ¤¤¤ë»þ¤Î
-ÊÑ¿ô¤ÎÃͤÏnil(C¸À¸ì¤Î¥ì¥Ù¥ë¤Ç¤ÏQnil)¤Ë¤Ê¤ê¤Þ¤¹¡¥
-
-Ruby¤ÎÇÛÎó¤Ç°ú¿ô¤ò¼õ¤±¼è¤ë¤â¤Î¤Ïindexes¤¬¤¢¤ê¤Þ¤¹¡¥¼ÂÁõ¤Ï¤³
-¤¦¤Ç¤¹¡¥
-
---
-static VALUE
-fdbm_indexes(obj, args)
- VALUE obj;
- struct RArray *args;
-{
- :
-}
---
-
-Âè1°ú¿ô¤Ïself¡¤Âè2°ú¿ô¤ÏRuby¤ÎÇÛÎó¤Ç¤¹¡¥¤³¤³¤Ç¤Ï¥­¥ã¥¹¥È¤ò¸º
-¤é¤¹¤¿¤á struct RArray* ¤Ç¼õ¤±¤Æ¤¤¤Þ¤¹¤¬¡¤VALUE¤Ç¤âƱ¤¸¤³¤È
-¤Ç¤¹¡¥
-
-** Ãí°Õ»ö¹à
-
-Ruby¤È¶¦Í­¤Ï¤·¤Ê¤¤¤¬Ruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤¹¤ë²ÄǽÀ­¤Î¤¢¤ë
-C¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤ÆRuby¥¤¥ó¥¿¥×¥ê¥¿¤ËÊÑ¿ô¤Î¸ºß
-¤ò¶µ¤¨¤Æ¤¢¤²¤Æ¤¯¤À¤µ¤¤¡¥¤Ç¤Ê¤¤¤ÈGC¤Ç¥È¥é¥Ö¥ë¤òµ¯¤³¤·¤Þ¤¹¡¥
-
- void rb_global_variable(VALUE *var)
-
-(5) extconf.rb¤òÍѰդ¹¤ë
-
-Makefile¤òºî¤ë¾ì¹ç¤Î¿÷·¿¤Ë¤Ê¤ëextconf.rb¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤òºî¤ê
-¤Þ¤¹¡¥extconf.rb¤Ï¥â¥¸¥å¡¼¥ë¤Î¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʾò·ï¤Î¥Á¥§¥Ã
-¥¯¤Ê¤É¤ò¹Ô¤¦¤³¤È¤¬ÌÜŪ¤Ç¤¹¡¥extconf.rb¤ÎÃæ¤Ç¤Ï°Ê²¼¤ÎRuby´Ø¿ô
-¤ò»È¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥
-
- have_library(lib, func): ¥é¥¤¥Ö¥é¥ê¤Î¸ºß¥Á¥§¥Ã¥¯
- have_func(func): ´Ø¿ô¤Î¸ºß¥Á¥§¥Ã¥¯
- have_header(header): ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¥Á¥§¥Ã¥¯
- create_makefile(target): Makefile¤ÎÀ¸À®
-
-°Ê²¼¤ÎÊÑ¿ô¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥
-
- $CFLAGS: ¥³¥ó¥Ñ¥¤¥ë»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-I¤Ê¤É)
- $LDFLAGS: ¥ê¥ó¥¯»þ¤ËÄɲÃŪ¤Ë»ØÄꤹ¤ë¥Õ¥é¥°(-L¤Ê¤É)
-
-¥â¥¸¥å¡¼¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ò·ï¤¬Â·¤ï¤Ê¤º¡¤¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³
-¥ó¥Ñ¥¤¥ë¤·¤Ê¤¤»þ¤Ë¤Ïcreate_makefile¤ò¸Æ¤Ð¤Ê¤±¤ì¤ÐMakefile¤Ï
-À¸À®¤µ¤ì¤º¡¤¥³¥ó¥Ñ¥¤¥ë¤â¹Ô¤ï¤ì¤Þ¤»¤ó¡¥
-
-¥â¥¸¥å¡¼¥ë¤¬Ruby 1.1ÀìÍѤǤ¢¤ë¾ì¹ç¤Ë¤Ï
-
- require 'mkmf'
-
-¤òextconf.rb¤ÎÀèÆ¬¤ËÃÖ¤¯¤ÈÊØÍø¤Ç¤·¤ç¤¦¡¥
-
-(6) depend¤òÍѰդ¹¤ë
-
-¤â¤·¡¤¥Ç¥£¥ì¥¯¥È¥ê¤Ëdepend¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
-Makefile¤¬°Í¸´Ø·¸¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤ì¤Þ¤¹¡¥
-
- % gcc -MM *.c > depend
-
-¤Ê¤É¤Çºî¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤¢¤Ã¤ÆÂ»¤Ï̵¤¤¤Ç¤·¤ç¤¦¡¥
-
-(7) MANIFEST¥Õ¥¡¥¤¥ë¤Ë¥Õ¥¡¥¤¥ë̾¤òÆþ¤ì¤ë
-
- % ls > MANIFEST
- % vi MANIFEST
-
-*.o, *~¤Ê¤ÉÉÔɬÍפʥե¡¥¤¥ë°Ê³°¤ÏMANIFEST¤ËÄɲ䷤Ƥª¤­¤Þ¤¹¡¥
-make»þ¤Ë¤ÏMANIFEST¤ÎÆâÍÆ¤Ï»²¾È¤·¤Þ¤»¤ó¤Î¤Ç¡¤¶õ¤Î¤Þ¤Þ¤Ç¤âÌäÂê
-¤Ïµ¯¤­¤Þ¤»¤ó¤¬¡¤¥Ñ¥Ã¥±¡¼¥¸¥ó¥°¤Î»þ¤Ë»²¾È¤¹¤ë¤³¤È¤¬¤¢¤ë¤Î¤È¡¤
-ɬÍפʥե¡¥¤¥ë¤ò¶èÊ̤Ǥ­¤ë¤Î¤Ç¡¤ÍѰդ·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç
-¤¦¡¥
-
-(8) Makefile¤òÀ¸À®¤¹¤ë
-
-Makefile¤ò¼ÂºÝ¤ËÀ¸À®¤¹¤ë¤¿¤á¤Ë¤Ï
-
- ruby extconf.rb
-
-¤È¤·¤Þ¤¹¡¥extconf.rb¤Ë require 'mkmf' ¤Î¹Ô¤¬¤Ê¤¤¾ì¹ç¤Ë¤Ï¥¨¥é¡¼
-¤Ë¤Ê¤ê¤Þ¤¹¤Î¤Ç¡¤°ú¿ô¤òÄɲä·¤Æ
-
- ruby -r mkmf extconf.rb
-
-¤È¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-¥Ç¥£¥ì¥¯¥È¥ê¤òext°Ê²¼¤ËÍѰդ·¤¿¾ì¹ç¤Ë¤ÏRubyÁ´ÂΤÎmake¤Î»þ¤Ë
-¼«Æ°Åª¤ËMakefile¤¬À¸À®¤µ¤ì¤Þ¤¹¤Î¤Ç¡¤¤³¤Î¥¹¥Æ¥Ã¥×¤ÏÉÔÍפǤ¹¡¥
-
-(9) make¤¹¤ë
-
-ưŪ¥ê¥ó¥¯¥é¥¤¥Ö¥é¥ê¤òÀ¸À®¤¹¤ë¾ì¹ç¤Ë¤Ï¤½¤Î¾ì¤Çmake¤·¤Æ¤¯¤À¤µ
-¤¤¡¥É¬ÍפǤ¢¤ì¤Ð make install ¤Ç¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Þ¤¹¡¥
-
-ext°Ê²¼¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤òÍѰդ·¤¿¾ì¹ç¤Ï¡¤Ruby¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç
-make¤ò¼Â¹Ô¤¹¤ë¤ÈMakefile¤òÀ¸À®¤«¤émake¡¤É¬Íפˤè¤Ã¤Æ¤Ï¤½¤Î¥â
-¥¸¥å¡¼¥ë¤ÎRuby¤Ø¤Î¥ê¥ó¥¯¤Þ¤Ç¼«Æ°Åª¤Ë¼Â¹Ô¤·¤Æ¤¯¤ì¤Þ¤¹¡¥
-extconf.rb¤ò½ñ¤­´¹¤¨¤ë¤Ê¤É¤·¤ÆMakefile¤ÎºÆÀ¸À®¤¬É¬Íפʻþ¤Ï¤Þ
-¤¿Ruby¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤·¤Æ¤¯¤À¤µ¤¤¡¥
-
-ưŪ¥ê¥ó¥¯¥é¥¤¥Ö¥é¥ê¤Ïmake install¤ÇRuby¥é¥¤¥Ö¥é¥ê¤Î¥Ç¥£¥ì¥¯
-¥È¥ê¤Î²¼¤Ë¥³¥Ô¡¼¤µ¤ì¤Þ¤¹¡¥¤â¤·¥â¥¸¥å¡¼¥ë¤È¶¨Ä´¤·¤Æ»È¤¦Ruby¤Ç
-µ­½Ò¤µ¤ì¤¿¥×¥í¥°¥é¥à¤¬¤¢¤ê¡¤Ruby¥é¥¤¥Ö¥é¥ê¤ËÃÖ¤­¤¿¤¤¾ì¹ç¤Ë¤Ï¡¤
-³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤΥǥ£¥ì¥¯¥È¥ê¤Î²¼¤Ë lib ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê
-¤òºî¤ê¡¤¤½¤³¤Ë ³ÈÄ¥»Ò .rb ¤Î¥Õ¥¡¥¤¥ë¤òÃÖ¤¤¤Æ¤ª¤±¤ÐƱ»þ¤Ë¥¤¥ó
-¥¹¥È¡¼¥ë¤µ¤ì¤Þ¤¹¡¥
-
-(10) ¥Ç¥Ð¥Ã¥°
-
-¤Þ¤¢¡¤¥Ç¥Ð¥Ã¥°¤·¤Ê¤¤¤Èư¤«¤Ê¤¤¤Ç¤·¤ç¤¦¤Í¡¥ext/Setup¤Ë¥Ç¥£¥ì
-¥¯¥È¥ê̾¤ò½ñ¤¯¤ÈÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë¤Î¤Ç¥Ç¥Ð¥Ã¥¬¤¬»È¤¨¤ë¤è¤¦¤Ë¤Ê
-¤ê¤Þ¤¹¡¥¤½¤Îʬ¥³¥ó¥Ñ¥¤¥ë¤¬ÃÙ¤¯¤Ê¤ê¤Þ¤¹¤±¤É¡¥
-
-(11) ¤Ç¤­¤¢¤¬¤ê
-
-¸å¤Ï¤³¤Ã¤½¤ê»È¤¦¤Ê¤ê¡¤¹­¤¯¸ø³«¤¹¤ë¤Ê¤ê¡¤Çä¤ë¤Ê¤ê¡¤¤´¼«Í³¤Ë¤ª
-»È¤¤¤¯¤À¤µ¤¤¡¥Ruby¤Îºî¼Ô¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò
-¼çÄ¥¤·¤Þ¤»¤ó¡¥
-
-Appendix A. Ruby¤Î¥½¡¼¥¹¥³¡¼¥É¤ÎʬÎà
-
-Ruby¤Î¥½¡¼¥¹¤Ï¤¤¤¯¤Ä¤«¤ËʬÎह¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤³¤Î¤¦¤Á¥¯¥é
-¥¹¥é¥¤¥Ö¥é¥ê¤ÎÉôʬ¤Ï´ðËÜŪ¤Ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ÈƱ¤¸ºî¤êÊý¤Ë¤Ê¤Ã
-¤Æ¤¤¤Þ¤¹¡¥¤³¤ì¤é¤Î¥½¡¼¥¹¤Ïº£¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤Û¤È¤ó¤ÉÍý²ò¤Ç¤­¤ë¤È
-»×¤¤¤Þ¤¹¡¥
-
-Ruby¸À¸ì¤Î¥³¥¢
-
- class.c
- error.c
- eval.c
- gc.c
- object.c
- parse.y
- variable.c
-
-¥æ¡¼¥Æ¥£¥ê¥Æ¥£´Ø¿ô
-
- dln.c
- fnmatch.c
- glob.c
- regex.c
- st.c
- util.c
-
-Ruby¥³¥Þ¥ó¥É¤Î¼ÂÁõ
-
- dmyext.c
- inits.c
- main.c
- ruby.c
- version.c
-
-¥¯¥é¥¹¥é¥¤¥Ö¥é¥ê
-
- array.c
- bignum.c
- compar.c
- dir.c
- enum.c
- file.c
- hash.c
- io.c
- marshal.c
- math.c
- numeric.c
- pack.c
- process.c
- random.c
- range.c
- re.c
- signal.c
- sprintf.c
- string.c
- struct.c
- time.c
-
-Appendix B. ³ÈÄ¥ÍÑ´Ø¿ô¥ê¥Õ¥¡¥ì¥ó¥¹
-
-C¸À¸ì¤«¤éRuby¤Îµ¡Ç½¤òÍøÍѤ¹¤ëAPI¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-** ·¿
-
- VALUE
-
-Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¸½¤¹¤ë·¿¡¥É¬Íפ˱þ¤¸¤Æ¥­¥ã¥¹¥È¤·¤ÆÍѤ¤¤ë¡¥
-ÁȤ߹þ¤ß·¿¤òɽ¸½¤¹¤ëC¤Î·¿¤Ïruby.h¤Ëµ­½Ò¤·¤Æ¤¢¤ëR¤Ç»Ï¤Þ¤ë¹½Â¤
-ÂΤǤ¢¤ë¡¥VALUE·¿¤ò¤³¤ì¤é¤Ë¥­¥ã¥¹¥È¤¹¤ë¤¿¤á¤ËR¤Ç»Ï¤Þ¤ë¹½Â¤ÂÎ
-̾¤òÁ´¤ÆÂçʸ»ú¤Ë¤·¤¿Ì¾Á°¤Î¥Þ¥¯¥í¤¬ÍѰդµ¤ì¤Æ¤¤¤ë¡¥
-
-** ÊÑ¿ô¡¦Äê¿ô
-
- Qnil
-
-Äê¿ô: nil¥ª¥Ö¥¸¥§¥¯¥È
-
- TRUE
-
-Äê¿ô: true¥ª¥Ö¥¸¥§¥¯¥È(¿¿¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ)
-
- FALSE
-
-Äê¿ô: false¥ª¥Ö¥¸¥§¥¯¥È
-
-** C¥Ç¡¼¥¿¤Î¥«¥×¥»¥ë²½
-
- Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
-
-C¤ÎǤ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò¥«¥×¥»¥ë²½¤·¤¿Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¤³
-¤Î¥Ý¥¤¥ó¥¿¤¬Ruby¤«¤é¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¯¤Ê¤Ã¤¿»þ¡¤free¤Ç»ØÄꤷ¤¿
-´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¡¥¤Þ¤¿¡¤¤³¤Î¥Ý¥¤¥ó¥¿¤Î»Ø¤¹¥Ç¡¼¥¿¤¬Â¾¤ÎRuby¥ª¥Ö
-¥¸¥§¥¯¥È¤ò»Ø¤·¤Æ¤¤¤ë¾ì¹ç¡¤mark¤Ë»ØÄꤹ¤ë´Ø¿ô¤Ç¥Þ¡¼¥¯¤¹¤ëɬÍ×
-¤¬¤¢¤ë¡¥
-
- Data_Make_Struct(class, type, mark, free, sval)
-
-type·¿¤Î¥á¥â¥ê¤òmalloc¤·¡¤ÊÑ¿ôsval¤ËÂåÆþ¤·¤¿¸å¡¤¤½¤ì¤ò¥«¥×¥»
-¥ë²½¤·¤¿¥Ç¡¼¥¿¤òÊÖ¤¹¥Þ¥¯¥í¡¥
-
- Data_Get_Struct(data, type, sval)
-
-data¤«¤étype·¿¤Î¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤·ÊÑ¿ôsval¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
-
-** ·¿¥Á¥§¥Ã¥¯
-
- TYPE(value)
- FIXNUM_P(value)
- NIL_P(value)
- void Check_Type(VALUE value, int type)
- void Check_SafeStr(VALUE value)
-
-** ·¿ÊÑ´¹
-
- FIX2INT(value)
- INT2FIX(i)
- NUM2INT(value)
- INT2NUM(i)
- NUM2DBL(value)
- float_new(f)
- STR2CSTR(value)
- str_new2(s)
-
-** ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
-
- VALUE rb_define_class(char *name, VALUE super)
-
-super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
-
-super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤·¡¤module¤ÎÄê
-¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_module(char *name)
-
-¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¡¥
-
- VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
-
-¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤·¡¤module¤ÎÄê¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
-
- void rb_include_module(VALUE class, VALUE module)
-
-¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥class¤¬¤¹¤Ç¤Ëmodule¤ò¥¤¥ó¥¯¥ë¡¼
-¥É¤·¤Æ¤¤¤ë»þ¤Ë¤Ï²¿¤â¤·¤Ê¤¤(¿½Å¥¤¥ó¥¯¥ë¡¼¥É¤Î¶Ø»ß)¡¥
-
- void rb_extend_object(VALUE object, VALUE module)
-
-¥ª¥Ö¥¸¥§¥¯¥È¤ò¥â¥¸¥å¡¼¥ë(¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É)¤Ç³ÈÄ¥¤¹¤ë¡¥
-
-** Âç°èÊÑ¿ôÄêµÁ
-
- void rb_define_variable(char *name, VALUE *var)
-
-Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ë¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô̾¤¬`$'¤Ç»Ï
-¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤ë¡¥name¤È¤·¤ÆRuby¤Î¼±Ê̻ҤȤ·
-¤Æµö¤µ¤ì¤Ê¤¤Ê¸»ú(Î㤨¤Ð` ')¤ò´Þ¤à¾ì¹ç¤Ë¤ÏRuby¥×¥í¥°¥é¥à¤«¤é
-¤Ï¸«¤¨¤Ê¤¯¤Ê¤ë¡¥
-
- void rb_define_readonly_variable(char *name, VALUE *var)
-
-Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëread only¤Î¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥read
-only¤Ç¤¢¤ë¤³¤È°Ê³°¤Ïrb_define_variable()¤ÈƱ¤¸¡¥
-
- void rb_define_virtual_variable(char *name,
- VALUE (*getter)(), VALUE (*setter)())
-
-´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRubyÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ
-¤Ë¤Ïgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤ë¡¥
-
- void rb_define_hooked_variable(char *name, VALUE *var,
- VALUE (*getter)(), VALUE (*setter)())
-
-´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬
-»²¾È¤µ¤ì¤¿»þ¤Ë¤Ïgetter¤¬¡¤´Ø¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter
-¤¬¸Æ¤Ð¤ì¤ë¡¥getter¤äsetter¤Ë0¤ò»ØÄꤷ¤¿»þ¤Ë¤Ïhook¤ò»ØÄꤷ¤Ê
-¤¤¤Î¤ÈƱ¤¸»ö¤Ë¤Ê¤ë¡¥
-
- void rb_global_variable(VALUE *var)
-
-GC¤Î¤¿¤á¡¤Ruby¥×¥í¥°¥é¥à¤«¤é¤Ï¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¤¤¬, Ruby¥ª¥Ö¥¸¥§
-¥¯¥È¤ò´Þ¤àÂç°èÊÑ¿ô¤ò¥Þ¡¼¥¯¤¹¤ë¡¥
-
-** ¥¯¥é¥¹Äê¿ô
-
- void rb_define_const(VALUE class, char *name, VALUE val)
-
-¥¯¥é¥¹Äê¿ô¤òÄêµÁ¤¹¤ë¡¥
-
- void rb_define_global_const(char *name, VALUE val)
-
-Âç°èÄê¿ô¤òÄêµÁ¤¹¤ë¡¥
-
- rb_define_const(cKernal, name, val)
-
-¤ÈƱ¤¸°ÕÌ£¡¥
-
-** ¥á¥½¥Ã¥ÉÄêµÁ
-
- rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥argc¤Ïself¤ò½ü¤¯°ú¿ô¤Î¿ô¡¥argc¤¬-1¤Î»þ,
-´Ø¿ô¤Ë¤Ï°ú¿ô¤Î¿ô(self¤ò´Þ¤Þ¤Ê¤¤)¤òÂè1°ú¿ô, °ú¿ô¤ÎÇÛÎó¤òÂè2°ú
-¿ô¤È¤¹¤ë·Á¼°¤ÇÍ¿¤¨¤é¤ì¤ë(Âè3°ú¿ô¤Ïself)¡¥argc¤¬-2¤Î»þ, Âè1°ú
-¿ô¤¬self, Âè2°ú¿ô¤¬args(args¤Ï°ú¿ô¤ò´Þ¤àRuby¤ÎÇÛÎó)¤È¤¤¤¦·Á
-¼°¤ÇÍ¿¤¨¤é¤ì¤ë¡¥
-
- rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-private¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
-
- rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc)
-
-ÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
-
- rb_scan_args(int atgc, VALUE *argv, char *fmt, ...)
-
-argc,argv·Á¼°¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤òʬ²ò¤¹¤ë¡¥fmt¤Ïɬ¿Ü°ú¿ô¤Î¿ô,
-Éղðú¿ô¤Î¿ô, »Ä¤ê¤Î°ú¿ô¤¬¤¢¤ë¤«¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç, "¿ô»ú¿ô
-»ú*"¤È¤¤¤¦·Á¼°¤Ç¤¢¤ë¡¥ 2 ÈÖÌܤοô»ú¤È"*"¤Ï¤½¤ì¤¾¤ì¾Êά²Äǽ¤Ç
-¤¢¤ë¡¥É¬¿Ü°ú¿ô¤¬°ì¤Ä¤â¤Ê¤¤¾ì¹ç¤Ï0¤ò»ØÄꤹ¤ë¡¥Âè3°ú¿ô°Ê¹ß¤ÏÊÑ
-¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç, ³ºÅö¤¹¤ëÍ×ÁǤ¬¤½¤ÎÊÑ¿ô¤Ë³ÊǼ¤µ¤ì¤ë¡¥Éղðú
-¿ô¤ËÂбþ¤¹¤ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤ÏÊÑ¿ô¤ËQnil¤¬ÂåÆþ¤µ¤ì
-¤ë¡¥
-
-** Ruby¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
-
- VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥Ê¸»úÎ󤫤émid¤òÆÀ¤ë¤¿¤á¤Ë¤Ïrb_intern()¤ò»È¤¦¡¥
-
- VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥°ú¿ô¤òargc,argv·Á¼°¤ÇÅϤ¹¡¥
-
- VALUE rb_eval_string(char *str)
-
-ʸ»úÎó¤òRuby¤È¥¹¥¯¥ê¥×¥È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¡¦¼Â¹Ô¤¹¤ë¡¥
-
- ID rb_intern(char *name)
-
-ʸ»úÎó¤ËÂбþ¤¹¤ëID¤òÊÖ¤¹¡¥
-
- char *rb_id2name(ID id)
-
-ID¤ËÂбþ¤¹¤ëʸ»úÎó¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥
-
- char *rb_class2name(VALUE class)
-
-class¤Î̾Á°¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥class¤¬Ì¾Á°¤ò»ý¤¿¤Ê¤¤»þ¤Ë¤Ï,
-ÁÄÀè¤òÁ̤äÆÌ¾Á°¤ò»ý¤Ä¥¯¥é¥¹¤Î̾Á°¤òÊÖ¤¹¡¥
-
-** ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô
-
- VALUE rb_iv_get(VALUE obj, char *name)
-
-obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ÎÃͤòÆÀ¤ë¡¥`@'¤Ç»Ï¤Þ¤é¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹
-ÊÑ¿ô¤Ï Ruby¥×¥í¥°¥é¥à¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¡Ö±£¤ì¤¿¡×¥¤¥ó¥¹¥¿
-¥ó¥¹ÊÑ¿ô¤Ë¤Ê¤ë¡¥Äê¿ô¤ÏÂçʸ»ú¤Î̾Á°¤ò»ý¤Ä¥¯¥é¥¹(¤Þ¤¿¤Ï¥â¥¸¥å¡¼
-¥ë)¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤È¤·¤Æ¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¡¥
-
- VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
-
-obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤òval¤Ë¥»¥Ã¥È¤¹¤ë¡¥
-
-** À©¸æ¹½Â¤
-
- VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
-
-func2¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ, func1¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ö¡¥
-func1¤Ë¤Ï arg1¤¬°ú¿ô¤È¤·¤ÆÅϤµ¤ì, func2¤Ë¤ÏÂè1°ú¿ô¤Ë¥¤¥Æ¥ì¡¼
-¥¿¤«¤éÍ¿¤¨¤é¤ì¤¿ÃÍ, Âè2°ú¿ô¤Ëarg2¤¬ÅϤµ¤ì¤ë¡¥
-
- VALUE rb_yield(VALUE val)
-
-val¤òÃͤȤ·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¸Æ¤Ó½Ð¤¹¡¥
-
- VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
-
-´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤Ë¸Æ¤Ó½Ð¤¹¡¥func1¤Î¼Â¹ÔÃæ¤ËÎã³°¤¬È¯À¸¤·
-¤¿»þ¤Ë¤Ï func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ö¡¥Ìá¤êÃͤÏÎã³°¤¬È¯À¸¤·¤Ê
-¤«¤Ã¤¿»þ¤Ïfunc1¤ÎÌá¤êÃÍ, Îã³°¤¬È¯À¸¤·¤¿»þ¤Ë¤Ïfunc2¤ÎÌá¤êÃͤÇ
-¤¢¤ë¡¥
-
- VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2)
-
-´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤·, ¼Â¹Ô½ªÎ»¸å(¤¿¤È¤¨Îã³°¤¬È¯
-À¸¤·¤Æ¤â) func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡¥Ìá¤êÃͤÏfunc1¤ÎÌá
-¤êÃͤǤ¢¤ë(Îã³°¤¬È¯À¸¤·¤¿»þ¤ÏÌá¤é¤Ê¤¤)¡¥
-
-** Îã³°¡¦¥¨¥é¡¼
-
- void Warning(char *fmt, ...)
-
-verbose»þ¤Ëɸ½à¥¨¥é¡¼½ÐÎϤ˷ٹð¾ðÊó¤òɽ¼¨¤¹¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
-
- void Fail(char *fmt, ...)
-
-RuntimeErrorÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
-
- void Raise(VALUE exception, char *fmt, ...)
-
-exception¤Ç»ØÄꤷ¤¿Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥fmt°Ê²¼¤Î°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
-
- void Fatal(char *fmt, ...)
-
-Ã×̿ŪÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥Ä̾ï¤ÎÎã³°½èÍý¤Ï¹Ô¤Ê¤ï¤ì¤º, ¥¤¥ó¥¿¡¼
-¥×¥ê¥¿¤¬½ªÎ»¤¹¤ë(¤¿¤À¤·ensure¤Ç»ØÄꤵ¤ì¤¿¥³¡¼¥É¤Ï½ªÎ»Á°¤Ë¼Â
-¹Ô¤µ¤ì¤ë)¡¥
-
- void Bug(char *fmt, ...)
-
-¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ê¤É¥×¥í¥°¥é¥à¤Î¥Ð¥°¤Ç¤·¤«È¯À¸¤¹¤ë¤Ï¤º¤Î¤Ê¤¤¾õ
-¶·¤Î»þ¸Æ¤Ö¡¥¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ï¥³¥¢¥À¥ó¥×¤·Ä¾¤Á¤Ë½ªÎ»¤¹¤ë¡¥Îã³°
-½èÍý¤Ï°ìÀڹԤʤï¤ì¤Ê¤¤¡¥
-
-** Ruby¤Î½é´ü²½¡¦¼Â¹Ô
-
-Ruby¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ËËä¤á¹þ¤à¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹
-¤ò»È¤¦¡¥Ä̾ï¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤ÏɬÍפʤ¤¡¥
-
- void ruby_init(int argc, char **argv, char **envp)
-
-Ruby¥¤¥ó¥¿¥×¥ê¥¿¤Î½é´ü²½¤ò¹Ô¤Ê¤¦¡¥
-
- void ruby_run()
-
-Ruby¥¤¥ó¥¿¥×¥ê¥¿¤ò¼Â¹Ô¤¹¤ë¡¥
-
- void ruby_script(char *name)
-
-Ruby¤Î¥¹¥¯¥ê¥×¥È̾($0)¤òÀßÄꤹ¤ë¡¥
-
-
-Appendix B. extconf.rb¤Ç»È¤¨¤ë´Ø¿ô¤¿¤Á
-
-extconf.rb¤ÎÃæ¤Ç¤ÏÍøÍѲÄǽ¤Ê¥³¥ó¥Ñ¥¤¥ë¾ò·ï¥Á¥§¥Ã¥¯¤Î´Ø¿ô¤Ï°Ê
-²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
- have_library(lib, func)
-
-´Ø¿ôfunc¤òÄêµÁ¤·¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥êlib¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥é
-¥¤¥Ö¥é¥ê¤¬Â¸ºß¤¹¤ë»þ¡¤TRUE¤òÊÖ¤¹¡¥
-
- have_func(func)
-
-´Ø¿ôfunc¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥func¤¬É¸½à¤Ç¤Ï¥ê¥ó¥¯¤µ¤ì¤Ê¤¤¥é
-¥¤¥Ö¥é¥êÆâ¤Î¤â¤Î¤Ç¤¢¤ë»þ¤Ë¤ÏÀè¤Ëhave_library¤Ç¤½¤Î¥é¥¤¥Ö¥é¥ê
-¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤ª¤¯»ö¡¥´Ø¿ô¤¬Â¸ºß¤¹¤ë»þTRUE¤òÊÖ¤¹¡¥
-
- have_header(header)
-
-¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë
-»þTRUE¤òÊÖ¤¹¡¥
-
- create_makefile(target)
-
-³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤÎMakefile¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤ò¸Æ¤Ð¤Ê¤±¤ì¤Ð
-¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤¡¥target¤Ï¥â¥¸¥å¡¼¥ë̾¤òɽ
-¤¹¡¥
-
-/*
- * Local variables:
- * fill-column: 60
- * end:
- */
diff --git a/README.ja.md b/README.ja.md
new file mode 100644
index 0000000000..2902216f99
--- /dev/null
+++ b/README.ja.md
@@ -0,0 +1,171 @@
+# Rubyã¨ã¯
+
+Rubyã¯ã‚·ãƒ³ãƒ—ルã‹ã¤å¼·åŠ›ãªã‚ªãƒ–ジェクト指å‘スクリプト言語ã§ã™ï¼Ž Rubyã¯ç´”粋ãªã‚ªãƒ–ジェクト指å‘言語ã¨ã—ã¦è¨­è¨ˆã•れã¦ã„ã‚‹ã®ã§ï¼Œ
+オブジェクト指å‘プログラミングを手軽ã«è¡Œã†äº‹ãŒå‡ºæ¥ã¾ã™ï¼Žã‚‚ã¡ã‚ã‚“æ™®é€šã®æ‰‹ç¶šãåž‹ã®ãƒ—ログラミングもå¯èƒ½ã§ã™ï¼Ž
+
+Rubyã¯ãƒ†ã‚­ã‚¹ãƒˆå‡¦ç†é–¢ä¿‚ã®èƒ½åŠ›ãªã©ã«å„ªã‚Œï¼ŒPerlã¨åŒã˜ãらã„強力ã§ã™ï¼Žã•らã«ã‚·ãƒ³ãƒ—ãƒ«ãªæ–‡æ³•ã¨ï¼Œ
+例外処ç†ã‚„イテレータãªã©ã®æ©Ÿæ§‹ã«ã‚ˆã£ã¦ï¼Œã‚ˆã‚Šåˆ†ã‹ã‚Šã‚„ã™ã„プログラミングãŒå‡ºæ¥ã¾ã™ï¼Ž
+
+## Rubyã®ç‰¹é•·
+
+* ã‚·ãƒ³ãƒ—ãƒ«ãªæ–‡æ³•
+* 普通ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæŒ‡å‘æ©Ÿèƒ½(クラス,メソッドコールãªã©)
+* 特殊ãªã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæŒ‡å‘æ©Ÿèƒ½(Mixin, 特異メソッドãªã©)
+* 演算å­ã‚ªãƒ¼ãƒãƒ¼ãƒ­ãƒ¼ãƒ‰
+* ä¾‹å¤–å‡¦ç†æ©Ÿèƒ½
+* イテレータã¨ã‚¯ãƒ­ãƒ¼ã‚¸ãƒ£
+* ガーベージコレクタ
+* ダイナミックローディング (アーキテクãƒãƒ£ã«ã‚ˆã‚‹)
+* ç§»æ¤æ€§ãŒé«˜ã„.多ãã®Unix-like/POSIX互æ›ãƒ—ラットフォーム上ã§å‹•ãã ã‘ã§ãªã,Windows, Mac OS
+ X,Haikuãªã©ã®ä¸Šã§ã‚‚å‹•ã cf.
+ https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/SupportedPlatformsJa
+
+
+## 入手法
+
+### FTPã§
+
+以下ã®å ´æ‰€ã«ãŠã„ã¦ã‚りã¾ã™ï¼Ž
+
+ftp://ftp.ruby-lang.org/pub/ruby/
+
+### Subversionã§
+
+開発先端ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§å–å¾—ã§ãã¾ã™ï¼Ž
+
+ $ svn co https://svn.ruby-lang.org/repos/ruby/trunk/ ruby
+
+ä»–ã«é–‹ç™ºä¸­ã®ãƒ–ランãƒã®ä¸€è¦§ã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã§è¦‹ã‚‰ã‚Œã¾ã™ï¼Ž
+
+ $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+
+### Gitã§
+
+Subversionã®ãƒŸãƒ©ãƒ¼ã‚’GitHubã«å…¬é–‹ã—ã¦ã„ã¾ã™ï¼Ž 以下ã®ã‚³ãƒžãƒ³ãƒ‰ã§ãƒªãƒã‚¸ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã™ï¼Ž
+
+ $ git clone git://github.com/ruby/ruby.git
+
+## ホームページ
+
+Rubyã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã®URLã¯
+
+https://www.ruby-lang.org/
+
+ã§ã™ï¼Ž
+
+## メーリングリスト
+
+Rubyã®ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãŒã‚りã¾ã™ï¼Žå‚åŠ å¸Œæœ›ã®æ–¹ã¯
+
+mailto:ruby-list-request@ruby-lang.org
+
+ã¾ã§æœ¬æ–‡ã«
+
+ subscribe
+
+ã¨æ›¸ã„ã¦é€ã£ã¦ä¸‹ã•ã„.
+
+Ruby開発者å‘ã‘メーリングリストもã‚りã¾ã™ï¼Žã“ã¡ã‚‰ã§ã¯rubyã®ãƒã‚°ï¼Œå°†æ¥ã®ä»•様拡張ãªã©å®Ÿè£…上ã®å•題ã«ã¤ã„ã¦è­°è«–ã•れã¦ã„ã¾ã™ï¼Ž å‚åŠ å¸Œæœ›ã®æ–¹ã¯
+
+mailto:ruby-dev-request@ruby-lang.org
+
+ã¾ã§ruby-listã¨åŒæ§˜ã®æ–¹æ³•ã§ãƒ¡ãƒ¼ãƒ«ã—ã¦ãã ã•ã„.
+
+Ruby拡張モジュールã«ã¤ã„ã¦è©±ã—åˆã†ruby-extãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆã¨æ•°å­¦é–¢ä¿‚ã®è©±é¡Œã«ã¤ã„ã¦è©±ã—åˆã†ruby-mathメーリングリストã¨
+英語ã§rubyã«ã¤ã„ã¦è©±ã—åˆã†ruby-talkメーリングリストもã‚りã¾ã™ï¼Žå‚加方法ã¯ã©ã‚Œã‚‚åŒã˜ã§ã™ï¼Ž
+
+## コンパイル・インストール
+
+ä»¥ä¸‹ã®æ‰‹é †ã§è¡Œã£ã¦ãã ã•ã„.
+
+1. ã‚‚ã— `configure` ファイルãŒè¦‹ã¤ã‹ã‚‰ãªã„,もã—ã㯠`configure.ac` よりå¤ã„よã†ãªã‚‰ï¼Œ `autoconf` を実行ã—ã¦
+ æ–°ã—ã `configure` を生æˆã™ã‚‹
+
+2. `configure` を実行ã—㦠`Makefile` ãªã©ã‚’生æˆã™ã‚‹
+
+ 環境ã«ã‚ˆã£ã¦ã¯ãƒ‡ãƒ•ォルトã®Cコンパイラ用オプションãŒä»˜ãã¾ã™ï¼Ž `configure` オプション㧠`optflags=..`
+ `warnflags=..` ç­‰ã§ä¸Šæ›¸ãã§ãã¾ã™ï¼Ž
+
+3. (å¿…è¦ãªã‚‰ã°)`defines.h` を編集ã™ã‚‹
+
+ 多分,必è¦ç„¡ã„ã¨æ€ã„ã¾ã™ï¼Ž
+
+4. (å¿…è¦ãªã‚‰ã°)`ext/Setup` ã«é™çš„ã«ãƒªãƒ³ã‚¯ã™ã‚‹æ‹¡å¼µãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’指定ã™ã‚‹
+
+ `ext/Setup` ã«è¨˜è¿°ã—ãŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯é™çš„ã«ãƒªãƒ³ã‚¯ã•れã¾ã™ï¼Ž
+
+ ダイナミックローディングをサãƒãƒ¼ãƒˆã—ã¦ã„ãªã„アーキテクãƒãƒ£ã§ã¯ `Setup` ã®1行目ã®ã€Œ`option nodynamic`ã€ã¨ã„ã†è¡Œã®ã‚³
+ メントを外ã™å¿…è¦ãŒã‚りã¾ã™ï¼Žã¾ãŸï¼Œã“ã®ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ã§æ‹¡å¼µãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’利用ã™ã‚‹ãŸã‚ã«ã¯ï¼Œã‚らã‹ã˜ã‚é™çš„ã«ãƒªãƒ³ã‚¯ã‚’ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ï¼Ž
+
+5. `make` を実行ã—ã¦ã‚³ãƒ³ãƒ‘イルã™ã‚‹
+
+6. `make check`ã§ãƒ†ã‚¹ãƒˆã‚’行ã†ï¼Ž
+
+ 「`check succeeded`ã€ã¨è¡¨ç¤ºã•ã‚Œã‚Œã°æˆåŠŸã§ã™ï¼ŽãŸã ã—ãƒ†ã‚¹ãƒˆã«æˆåŠŸã—ã¦ã‚‚完璧ã ã¨ä¿è¨¼ã•れã¦ã„る訳ã§ã¯ã‚りã¾ã›ã‚“.
+
+7. `make install`
+
+ 以下ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’作ã£ã¦ï¼Œãã“ã«ãƒ•ァイルをインストー ルã—ã¾ã™ï¼Ž
+
+ * `${DESTDIR}${prefix}/bin`
+ * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib`
+ * `${DESTDIR}${prefix}/lib/ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/gems/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/share/man/man1`
+ * `${DESTDIR}${prefix}/share/ri/${MAJOR}.${MINOR}.${TEENY}/system`
+
+
+ Rubyã®APIãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒ'*x.y.z*'ã§ã‚れã°ï¼Œ`${MAJOR}`ã¯
+ '*x*'ã§ï¼Œ`${MINOR}`ã¯'*y*',`${TEENY}`ã¯'*z*'ã§ã™ï¼Ž
+
+ **注æ„**: APIãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® `teeny` ã¯ï¼ŒRubyプログラムã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ã¯ç•°ãªã‚‹ã“ã¨ãŒã‚りã¾ã™ï¼Ž
+
+ `root` ã§ä½œæ¥­ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“.
+
+
+ã‚‚ã—,コンパイル時ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå ´åˆã«ã¯ã‚¨ãƒ©ãƒ¼ã®ãƒ­ã‚°ã¨ãƒžã‚·ãƒ³ï¼ŒOSã®ç¨®é¡žã‚’å«ã‚€ã§ãã‚‹ã ã‘詳ã—ã„レãƒãƒ¼ãƒˆã‚’作者ã«é€ã£ã¦ä¸‹ã•ã‚‹ã¨ä»–ã®æ–¹ã®ãŸã‚ã«ã‚‚ãªã‚Šã¾ã™ï¼Ž
+
+## ç§»æ¤
+
+UNIXã§ã‚れ㰠`configure` ãŒã»ã¨ã‚“ã©ã®å·®ç•°ã‚’å¸åŽã—ã¦ãれるã¯ãšã§ã™ãŒï¼Œæ€ã‚ã¬è¦‹è½ã¨ã—ãŒã‚ã£ãŸå ´åˆ(ã‚る事ãŒå¤šã„),作者ã«ãã®
+ã“ã¨ã‚’報告ã™ã‚Œã°ï¼Œè§£æ±ºã§ãã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ï¼Ž
+
+アーキテクãƒãƒ£ã«ã‚‚ã£ã¨ã‚‚ä¾å­˜ã™ã‚‹ã®ã¯GC部ã§ã™ï¼ŽRubyã®GCã¯å¯¾è±¡
+ã®ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ãŒ`setjmp()`ã¾ãŸã¯`getcontext()`ã«ã‚ˆã£ã¦å…¨ã¦ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’ `jmp_buf` ã‚„ `ucontext_t`
+ã«æ ¼ç´ã™ã‚‹ã“ã¨ã¨ï¼Œ `jmp_buf` ã‚„ `ucontext_t` ã¨ã‚¹ã‚¿ãƒƒã‚¯ãŒ32bitアラインメントã•れã¦ã„ã‚‹ã“ã¨ã‚’仮定
+ã—ã¦ã„ã¾ã™ï¼Žç‰¹ã«å‰è€…ãŒæˆç«‹ã—ãªã„å ´åˆã®å¯¾å¿œã¯éžå¸¸ã«å›°é›£ã§ã—ょã†ï¼Ž 後者ã®è§£æ±ºã¯æ¯”較的簡å˜ã§ï¼Œ `gc.c` ã§ã‚¹ã‚¿ãƒƒã‚¯ã‚’マークã—ã¦ã„ã‚‹
+部分ã«ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆã®ãƒã‚¤ãƒˆæ•°ã ã‘ãšã‚‰ã—ã¦ãƒžãƒ¼ã‚¯ã™ã‚‹ã‚³ãƒ¼ãƒ‰ã‚’追加ã™ã‚‹ã ã‘ã§æ¸ˆã¿ã¾ã™ï¼Ž`defined(__mc68000__)`ã§æ‹¬ã‚‰ã‚Œã¦ã„
+る部分をå‚考ã«ã—ã¦ãã ã•ã„.
+
+レジスタウィンドウをæŒã¤CPUã§ã¯ï¼Œãƒ¬ã‚¸ã‚¹ã‚¿ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’スタックã«ãƒ•ラッシュã™ã‚‹ã‚¢ã‚»ãƒ³ãƒ–ラコードを追加ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“.
+
+## é…布æ¡ä»¶
+
+[COPYING.ja](COPYING.ja) ファイルをå‚ç…§ã—ã¦ãã ã•ã„.
+
+## フィードãƒãƒƒã‚¯
+
+Rubyã«é–¢ã™ã‚‹è³ªå•㯠Ruby-Talk(英語)や Ruby-List(日本語) (https://www.ruby-lang.org/ja/community/mailing-lists) や,
+stackoverflow (https://ja.stackoverflow.com/) ãªã©ã®Webã‚µã‚¤ãƒˆã«æŠ•ç¨¿ã—ã¦ãã ã•ã„.
+
+ãƒã‚°å ±å‘Šã¯ https://bugs.ruby-lang.org ã§å—ã‘付ã‘ã¦ã„ã¾ã™ï¼Ž
+
+
+## 著者
+
+Rubyã®ã‚ªãƒªã‚¸ãƒŠãƒ«ç‰ˆã¯ï¼Œ1995å¹´ã«ã¾ã¤ã‚‚ã¨ã‚†ãã²ã‚æ°ã«ã‚ˆã£ã¦è¨­è¨ˆãƒ»é–‹ç™ºã•れã¾ã—ãŸï¼Ž
+
+<mailto:matz@ruby-lang.org>
+
+---
+created at: Thu Aug 3 11:57:36 JST 1995
diff --git a/README.jp b/README.jp
deleted file mode 100644
index 0ef0065925..0000000000
--- a/README.jp
+++ /dev/null
@@ -1,171 +0,0 @@
-* Ruby¤È¤Ï
-
-Ruby¤Ï¥·¥ó¥×¥ë¤«¤Ä¶¯ÎϤʥª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥¹¥¯¥ê¥×¥È¸À¸ì¤Ç¤¹¡¥
-Ruby¤ÏºÇ½é¤«¤é½ã¿è¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¸À¸ì¤È¤·¤ÆÀ߷פµ¤ì¤Æ¤¤¤Þ
-¤¹¤«¤é¡¤¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤ò¼ê·Ú¤Ë¹Ô¤¦»ö¤¬½ÐÍè¤Þ
-¤¹¡¥¤â¤Á¤í¤óÄ̾ï¤Î¼ê³¤­·¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¤â²Äǽ¤Ç¤¹¡¥
-
-Ruby¤Ï¥Æ¥­¥¹¥È½èÍý´Ø·¸¤ÎǽÎϤʤɤËÍ¥¤ì¡¤Perl¤ÈƱ¤¸¤¯¤é¤¤¶¯ÎÏ
-¤Ç¤¹¡¥¤µ¤é¤Ë¥·¥ó¥×¥ë¤Êʸˡ¤È¡¤Îã³°½èÍý¤ä¥¤¥Æ¥ì¡¼¥¿¤Ê¤É¤Îµ¡¹½
-¤Ë¤è¤Ã¤Æ¡¤¤è¤êʬ¤«¤ê¤ä¤¹¤¤¥×¥í¥°¥é¥ß¥ó¥°¤¬½ÐÍè¤Þ¤¹¡¥
-
-
-* Ruby¤ÎÆÃĹ¡¥
-
- + ¥·¥ó¥×¥ë¤Êʸˡ
- + ÉáÄ̤Υª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(¥¯¥é¥¹¡¤¥á¥½¥Ã¥É¥³¡¼¥ë¤Ê¤É)
- + ÆÃ¼ì¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(Mixin, ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É)
- + ±é»»»Ò¥ª¡¼¥Ð¡¼¥í¡¼¥É
- + Îã³°½èÍýµ¡Ç½
- + ¥¤¥Æ¥ì¡¼¥¿¤È¥¯¥í¡¼¥¸¥ã
- + ¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿
- + ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥° (¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ë¤è¤ë)
- + °Ü¿¢À­¤¬¹â¤¤¡¥Â¿¤¯¤ÎUNIX¾å¤Çư¤¯
-
-
-* Æþ¼êË¡
-
-** ftp¤Ç
-
-°Ê²¼¤Î¾ì½ê¤Ë¤ª¤¤¤Æ¤¢¤ê¤Þ¤¹¡¥
-
- ftp://ftp.netlab.co.jp/pub/lang/ruby/
-
-
-* ¥Û¡¼¥à¥Ú¡¼¥¸
-
- Ruby¤Î¥Û¡¼¥à¥Ú¡¼¥¸¤ÎURL¤Ï
-
- http://www.netlab.co.jp/ruby/jp/
-
- ¤Ç¤¹¡¥
-
-
-* ¥á¥¤¥ê¥ó¥°¥ê¥¹¥È
-
- Ruby¤Ë´Ø¤ï¤ëÏÃÂê¤Î¤¿¤á¤Î¥á¥¤¥ê¥ó¥°¥ê¥¹¥È¤ò³«Àߤ·¤Þ¤·¤¿¡¥¥¢
- ¥É¥ì¥¹¤Ï
-
- ruby-list@netlab.co.jp
-
- ¤Ç¤¹¡¥¤³¤Î¥¢¥É¥ì¥¹¤Ë¥á¥¤¥ë¤òÁ÷¤ì¤Ð¡¤¼«Æ°Åª¤ËÅÐÏ¿¤µ¤ì¤Þ¤¹¡¥
-
-
-* ¥³¥ó¥Ñ¥¤¥ë¡¦¥¤¥ó¥¹¥È¡¼¥ë
-
-°Ê²¼¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
- 1. configure¤ò¼Â¹Ô¤·¤ÆMakefile¤Ê¤É¤òÀ¸À®¤¹¤ë
-
- 2. (ɬÍפʤé¤Ð)defines.h¤òÊÔ½¸¤¹¤ë
-
- ¿ʬ¡¤É¬Í×̵¤¤¤È»×¤¤¤Þ¤¹¡¥
-
- 3. (ɬÍפʤé¤Ð)ext/Setup¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò
- »ØÄꤹ¤ë
-
- ext/Setup¤Ëµ­½Ò¤·¤¿¥â¥¸¥å¡¼¥ë¤ÏÀÅŪ¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡¥
-
- ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥°¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥¢¡¼¥­¥Æ¥¯
- ¥Á¥ã¤Ç¤ÏSetup¤Î1¹ÔÌܤΡÖoption nodynamic¡×¤È¤¤¤¦¹Ô¤Î¥³
- ¥á¥ó¥È¤ò³°¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥¤Þ¤¿¡¤¤³¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç
- ³ÈÄ¥¥â¥¸¥å¡¼¥ë¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¤¤¢¤é¤«¤¸¤áÀÅŪ¤Ë¥ê¥ó
- ¥¯¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
-
- 4. make¤ò¼Â¹Ô¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
-
- 5. make test¤Ç¥Æ¥¹¥È¤ò¹Ô¤¦¡¥
-
- ¡Ötest succeeded¡×¤Èɽ¼¨¤µ¤ì¤ì¤ÐÀ®¸ù¤Ç¤¹¡¥¤¿¤À¤·¥Æ¥¹¥È
- ¤ËÀ®¸ù¤·¤Æ¤â´°àú¤À¤ÈÊݾڤµ¤ì¤Æ¤¤¤ëÌõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥
-
- 6. make install
-
- root¤Çºî¶È¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡¥
-
-¤â¤·¡¤¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿¾ì¹ç¤Ë¤Ï¥¨¥é¡¼¤Î¥í¥°¤È¥Þ
-¥·¥ó¡¤OS¤Î¼ïÎà¤ò´Þ¤à¤Ç¤­¤ë¤À¤±¾Ü¤·¤¤¥ì¥Ý¡¼¥È¤òºî¼Ô¤ËÁ÷¤Ã¤Æ¤¯
-¤À¤µ¤ë¤È¾¤ÎÊý¤Î¤¿¤á¤Ë¤â¤Ê¤ê¤Þ¤¹¡¥
-
-
-* °Ü¿¢
-
-UNIX¤Ç¤¢¤ì¤Ðconfigure¤¬¤Û¤È¤ó¤É¤Îº¹°Û¤òµÛ¼ý¤·¤Æ¤¯¤ì¤ë¤Ï¤º¤Ç
-¤¹¤¬¡¤»×¤ï¤Ì¸«Íî¤È¤·¤¬¤¢¤Ã¤¿¾ì¹ç(¤¢¤ë¤Ë°ã¤¤¤Ê¤¤)¡¤ºî¼Ô¤Ë¤½¤Î
-¤³¤È¤ò¥ì¥Ý¡¼¥È¤¹¤ì¤Ð¡¤²ò·è¤Ç¤­¤ë¤«¤âÃΤì¤Þ¤»¤ó¡¥
-
-¥¢¡¼¥¯¥Æ¥¯¥Á¥ã¤Ë¤â¤Ã¤È¤â°Í¸¤¹¤ë¤Î¤ÏGCÉô¤Ç¤¹¡¥Ruby¤ÎGC¤ÏÂоÝ
-¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤¬setjmp()¤Ë¤è¤Ã¤ÆÁ´¤Æ¤Î¥ì¥¸¥¹¥¿¤ò jmp_buf¤Ë
-³ÊǼ¤¹¤ë¤³¤È¤È¡¤jmp_buf¤È¥¹¥¿¥Ã¥¯¤¬32bit¥¢¥é¥¤¥ó¥á¥ó¥È¤µ¤ì¤Æ
-¤¤¤ë¤³¤È¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡¥ÆÃ¤ËÁ°¼Ô¤¬À®Î©¤·¤Ê¤¤¾ì¹ç¤ÎÂбþ¤ÏÈó
-¾ï¤Ëº¤Æñ¤Ç¤·¤ç¤¦¡¥¸å¼Ô¤Î²ò·è¤ÏÈæ³ÓŪ´Êñ¤Ç¡¤gc.c¤Ç¥¹¥¿¥Ã¥¯¤ò
-¥Þ¡¼¥¯¤·¤Æ¤¤¤ëÉôʬ¤Ë¥¢¥é¥¤¥ó¥á¥ó¥È¤Î¥Ð¥¤¥È¿ô¤À¤±¤º¤é¤·¤Æ¥Þ¡¼
-¥¯¤¹¤ë¥³¡¼¥É¤òÄɲ乤ë¤À¤±¤ÇºÑ¤ß¤Þ¤¹¡¥¡Ödefined(THINK_C)¡×¤Ç
-³ç¤é¤ì¤Æ¤¤¤ëÉôʬ¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤
-
-# ¼ÂºÝ¤Ë¤ÏRuby¤ÏThink C¤Ç¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤Þ¤»¤ó¡¥
-
-¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É¥¦¤ò»ý¤ÄCPU¤Ç¤Ï¡¤¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É¥¦¤ò¥¹¥¿¥Ã
-¥¯¤Ë¥Õ¥é¥Ã¥·¥å¤¹¤ë¥¢¥»¥ó¥Ö¥é¥³¡¼¥É¤òÄɲ乤ëɬÍפ¬¤¢¤ë¤«¤âÃÎ
-¤ì¤Þ¤»¤ó¡¥
-
-
-* ÇÛÉÛ¾ò·ï
-
-RUby¤Ï¥Õ¥ê¡¼¥½¥Õ¥È¥¦¥§¥¢¤Ç¤¹¡¥GPL(the GNU General Public
-Licence)¤Þ¤¿¤Ï°Ê²¼¤Ë¼¨¤¹¾ò·ï¤ÇRuby¤òºÆÇÛÉۤǤ­¤Þ¤¹¡¥GPL¤Ë¤Ä
-¤¤¤Æ¤ÏCOPYING¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡¥
-
- 1. Ê£À½¤ÏÀ©¸Â¤Ê¤¯¼«Í³¤Ç¤¹¡¥
-
- 2. °Ê²¼¤Î¾ò·ï¤Î¤¤¤º¤ì¤«¤òËþ¤¿¤¹»þ¤Ë¼ê¸µ¤ÎRuby¤Î¥½¡¼¥¹¤ò¼«
- ͳ¤ËÊѹ¹¤Ç¤­¤Þ¤¹¡¥
-
- (a) ¥Í¥Ã¥È¥Ë¥å¡¼¥º¤Ë¥Ý¥¹¥È¤·¤¿¤ê¡¤ºî¼Ô¤ËÊѹ¹¤òÁ÷ÉÕ¤¹¤ë
- ¤Ê¤É¤ÎÊýË¡¤Ç¡¤Êѹ¹¤ò¸ø³«¤¹¤ë
-
- (b) Êѹ¹¤·¤¿Ruby¤ò¼«Ê¬¤Î½ê°¤¹¤ëÁÈ¿¥ÆâÉô¤À¤±¤Ç»È¤¦
-
- (c) Êѹ¹ÅÀ¤òÌÀ¼¨¤·¤¿¤¦¤¨¡¤¥½¥Õ¥È¥¦¥§¥¢¤Î̾Á°¤òÊѹ¹¤¹¤ë¡¥
- ¤½¤Î¥½¥Õ¥È¥¦¥§¥¢¤òÇÛÉÛ¤¹¤ë»þ¤Ë¤Ï¤â¤È¤ÎRuby¤âƱ»þ¤Ë
- ÇÛÉÛ¤¹¤ë
-
- (d) ¤½¤Î¾¤ÎÊѹ¹¾ò·ï¤òºî¼Ô¤È¹ç°Õ¤¹¤ë
-
- 3. °Ê²¼¤Î¾ò·ï¤Î¤¤¤º¤ì¤«¤òËþ¤¿¤¹»þ¤ËRuby¤ò¥ª¥Ö¥¸¥§¥¯¥È¥³¡¼
- ¥É¤ä¼Â¹Ô·Á¼°¤Ç¤âÇÛÉۤǤ­¤Þ¤¹¡¥
-
- (a) ¥Ð¥¤¥Ê¥ê¤ò¼õ¤±¼è¤Ã¤¿¿Í¤¬¥½¡¼¥¹¤òÆþ¼ê¤Ç¤­¤ë¤è¤¦¤Ë¥½¡¼
- ¥¹¤ÎÆþ¼êË¡¤òÌÀ¼¨¤¹¤ë
-
- (b) µ¡³£²ÄÆÉ¤Ê¥½¡¼¥¹¥³¡¼¥É¤òźÉÕ¤¹¤ë
-
- (c) Êѹ¹¤ò¹Ô¤Ã¤¿¥Ð¥¤¥Ê¥ê¤Ï̾Á°¤òÊѹ¹¤·¤¿¤¦¤¨¡¤¥½¡¼¥¹¤Î
- Æþ¼êË¡¤òÌÀ¼¨¤¹¤ë
-
- (d) ¤½¤Î¾¤ÎÇÛÉÛ¾ò·ï¤òºî¼Ô¤È¹ç°Õ¤¹¤ë
-
- 4. ¾¤Î¥×¥í¥°¥é¥à¤Ø¤Î°úÍѤϤ¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤ì¼«Í³¤Ç¤¹¡¥¤¿
- ¤À¤·¡¤Ruby¤Ë´Þ¤Þ¤ì¤ë¾¤Îºî¼Ô¤Ë¤è¤ë¥³¡¼¥É¤Ï¡¤¤½¤ì¤¾¤ì¤Î
- ºî¼Ô¤Î°Õ¸þ¤Ë¤è¤ëÀ©¸Â¤¬²Ã¤¨¤é¤ì¤Þ¤¹¡¥¶ñÂÎŪ¤Ë¤Ïgc.c(°ìÉô)¡¤
- util.c(°ìÉô)¡¤st.[ch]¡¤regex.[ch], fnmatch.[ch], glob.c
- ¤ª¤è¤Ó./missing¥Ç¥£¥ì¥¯¥È¥ê²¼¤Î¥Õ¥¡¥¤¥ë·²¤¬³ºÅö¤·¤Þ¤¹¡¥
-
- 5. Ruby¤Ø¤ÎÆþÎϤȤʤ륹¥¯¥ê¥×¥È¤ª¤è¤Ó¡¤Ruby¤«¤é¤Î½ÐÎϤθ¢
- Íø¤ÏRuby¤Îºî¼Ô¤Ç¤Ï¤Ê¤¯¡¤¤½¤ì¤¾¤ì¤ÎÆþ½ÐÎϤòÀ¸À®¤·¤¿¿Í¤Ë
- °¤·¤Þ¤¹¡¥¤Þ¤¿¡¤Ruby¤ËÁȤ߹þ¤à¤¿¤á¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤Ä
- ¤¤¤Æ¤âƱÍͤǤ¹¡¥
-
- 6. Ruby¤Ï̵ÊݾڤǤ¹¡¥ºî¼Ô¤ÏRuby¤ò¥µ¥Ý¡¼¥È¤¹¤ë°Õ»Ö¤Ï¤¢¤ê¤Þ
- ¤¹¤¬¡¤Ruby¼«¿È¤Î¥Ð¥°¤¢¤ë¤¤¤ÏRuby¥¹¥¯¥ê¥×¥È¤Î¥Ð¥°¤Ê¤É¤«
- ¤éȯÀ¸¤¹¤ë¤¤¤«¤Ê¤ë»³²¤ËÂФ·¤Æ¤âÀÕǤ¤ò»ý¤Á¤Þ¤»¤ó¡¥
-
-
-* Ãø¼Ô
-
-¥³¥á¥ó¥È¡¤¥Ð¥°¥ì¥Ý¡¼¥È¤½¤Î¾¤Ï matz@netlab.co.jp ¤Þ¤Ç¡¥
--------------------------------------------------------
-created at: Thu Aug 3 11:57:36 JST 1995
-Local variables:
-mode: indented-text
-end:
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..7a24329fe8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,175 @@
+[![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)
+
+# 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.
+
+## Features of Ruby
+
+* Simple Syntax
+* **Normal** Object-oriented Features (e.g. class, method calls)
+* **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, macOS, Haiku, etc.) cf.
+ https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/SupportedPlatforms
+
+
+## How to get Ruby
+
+For a complete list of ways to install Ruby, including using third-party tools
+like rvm, see:
+
+https://www.ruby-lang.org/en/downloads/
+
+The Ruby distribution files can be found on the following FTP site:
+
+ftp://ftp.ruby-lang.org/pub/ruby/
+
+The trunk of the Ruby source tree can be checked out with the following
+command:
+
+ $ svn co https://svn.ruby-lang.org/repos/ruby/trunk/ ruby
+
+Or if you are using git then use the following command:
+
+ $ git clone https://github.com/ruby/ruby.git
+
+There are some other branches under development. Try the following command
+to see the list of branches:
+
+ $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+
+Or if you are using git then use the following command:
+
+ $ git ls-remote git://github.com/ruby/ruby.git
+
+## Ruby home page
+
+The URL of the Ruby home page is:
+
+https://www.ruby-lang.org/
+
+## Mailing list
+
+There is a mailing list to talk about 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>.
+
+## How to compile and install
+
+This is what you need to do to compile and install Ruby:
+
+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.
+
+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
+ override them.
+
+4. Edit `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.
+
+ If you don't want to compile non static extension modules (probably on
+ architectures which do not allow dynamic loading), remove comment mark
+ from the line "`#option nodynamic`" in `ext/Setup`.
+
+ Usually this step will not be needed.
+
+6. Run `make`.
+
+ * On Mac, set RUBY\_CODESIGN environment variable with a signing identity.
+ It uses the identity to sign `ruby` binary. See also codesign(1).
+
+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`.
+
+ If you want to install bundled gems, run `make update-gems` and
+ `make extract-gems` before running `make install`.
+
+9. Run '`make install`'.
+
+ This command will create the following directories and install files into
+ them.
+
+ * `${DESTDIR}${prefix}/bin`
+ * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib`
+ * `${DESTDIR}${prefix}/lib/ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
+ * `${DESTDIR}${prefix}/lib/ruby/gems/${MAJOR}.${MINOR}.${TEENY}`
+ * `${DESTDIR}${prefix}/share/man/man1`
+ * `${DESTDIR}${prefix}/share/ri/${MAJOR}.${MINOR}.${TEENY}/system`
+
+
+ If Ruby's API version is '*x.y.z*', the `${MAJOR}` is '*x*', the
+ `${MINOR}` is '*y*', and the `${TEENY}` is '*z*'.
+
+ **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.
+
+
+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
+external libraries and/or headers, then you will need to run '`make distclean-ext`'
+to remove old configuration after installing them in such case.
+
+## Copying
+
+See the file [COPYING](COPYING).
+
+## Feedback
+
+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.
+
+[HowToReport]: https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport
+
+## Contributing
+
+See the file [CONTRIBUTING.md](CONTRIBUTING.md)
+
+
+## The Author
+
+Ruby was originally designed and developed by Yukihiro Matsumoto (Matz) in
+1995.
+
+<mailto:matz@ruby-lang.org>
diff --git a/ToDo b/ToDo
deleted file mode 100644
index 462bc47adb..0000000000
--- a/ToDo
+++ /dev/null
@@ -1,4 +0,0 @@
-* remove Enumerable#reverse at 1.2
-* non-blocking open/write for thread
-* package or access control for global variables
-* format
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000000..99b24e6d93
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,46 @@
+# -*- 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
new file mode 100644
index 0000000000..18ba297b05
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,15 @@
+# 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
new file mode 100644
index 0000000000..09fcc3c225
--- /dev/null
+++ b/addr2line.c
@@ -0,0 +1,1234 @@
+/**********************************************************************
+
+ addr2line.c -
+
+ $Author$
+
+ Copyright (C) 2010 Shinichiro Hamaji
+
+**********************************************************************/
+
+#include "ruby/config.h"
+#include "ruby/missing.h"
+#include "addr2line.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+#include "missing/stdbool.h"
+#endif
+
+#ifdef USE_ELF
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#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
+# 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__ */
+
+#ifdef HAVE_DLADDR
+# 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 */
+
+/* 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 */
+
+#ifndef ElfW
+# if SIZEOF_VOIDP == 8
+# define ElfW(x) Elf64##_##x
+# else
+# define ElfW(x) Elf32##_##x
+# endif
+#endif
+#ifndef ELF_ST_TYPE
+# if SIZEOF_VOIDP == 8
+# define ELF_ST_TYPE ELF64_ST_TYPE
+# else
+# define ELF_ST_TYPE ELF32_ST_TYPE
+# endif
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#ifndef SHF_COMPRESSED /* compatibility with glibc < 2.22 */
+#define SHF_COMPRESSED 0
+#endif
+
+int kprintf(const char *fmt, ...);
+
+typedef struct {
+ const char *dirname;
+ const char *filename;
+ const char *path; /* object path */
+ int line;
+
+ uintptr_t base_addr;
+ uintptr_t saddr;
+ const char *sname; /* function name */
+} line_info_t;
+typedef struct obj_info obj_info_t;
+struct obj_info {
+ const char *path; /* object path */
+ int fd;
+ void *mapped;
+ size_t mapped_size;
+ uintptr_t base_addr;
+ obj_info_t *next;
+};
+
+/* Avoid consuming stack as this module may be used from signal handler */
+static char binary_filename[PATH_MAX];
+
+static unsigned long
+uleb128(char **p)
+{
+ unsigned long r = 0;
+ int s = 0;
+ for (;;) {
+ unsigned char b = *(unsigned char *)(*p)++;
+ if (b < 0x80) {
+ r += (unsigned long)b << s;
+ break;
+ }
+ r += (b & 0x7f) << s;
+ s += 7;
+ }
+ return r;
+}
+
+static long
+sleb128(char **p)
+{
+ long r = 0;
+ int s = 0;
+ for (;;) {
+ unsigned char b = *(unsigned char *)(*p)++;
+ if (b < 0x80) {
+ if (b & 0x40) {
+ r -= (0x80 - b) << s;
+ }
+ else {
+ r += (b & 0x3f) << s;
+ }
+ break;
+ }
+ r += (b & 0x7f) << s;
+ s += 7;
+ }
+ return r;
+}
+
+static const char *
+get_nth_dirname(unsigned long dir, char *p)
+{
+ if (!dir--) {
+ return "";
+ }
+ while (dir--) {
+ while (*p) p++;
+ p++;
+ if (!*p) {
+ kprintf("Unexpected directory number %lu in %s\n",
+ dir, binary_filename);
+ return "";
+ }
+ }
+ return p;
+}
+
+static void
+fill_filename(int file, char *include_directories, char *filenames,
+ line_info_t *line)
+{
+ int i;
+ char *p = filenames;
+ char *filename;
+ unsigned long dir;
+ for (i = 1; i <= file; i++) {
+ filename = p;
+ if (!*p) {
+ /* Need to output binary file name? */
+ kprintf("Unexpected file number %d in %s\n",
+ file, binary_filename);
+ return;
+ }
+ while (*p) p++;
+ p++;
+ dir = uleb128(&p);
+ /* last modified. */
+ uleb128(&p);
+ /* size of the file. */
+ uleb128(&p);
+
+ if (i == file) {
+ line->filename = filename;
+ line->dirname = get_nth_dirname(dir, include_directories);
+ }
+ }
+}
+
+static void
+fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
+ char *include_directories, char *filenames,
+ obj_info_t *obj, line_info_t *lines, int offset)
+{
+ int i;
+ addr += obj->base_addr;
+ 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]);
+ lines[i].line = line;
+ }
+ }
+}
+
+static int
+parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
+ obj_info_t *obj, line_info_t *lines, int offset)
+{
+ 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);
+ }
+
+ 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;
+
+ minimum_instruction_length = *(unsigned char *)p;
+ p++;
+
+ is_stmt = default_is_stmt = *(unsigned char *)p;
+ p++;
+
+ line_base = *(signed char *)p;
+ p++;
+
+ line_range = *(unsigned char *)p;
+ p++;
+
+ opcode_base = *(unsigned char *)p;
+ p++;
+
+ /* standard_opcode_lengths = (unsigned char *)p - 1; */
+ p += opcode_base - 1;
+
+ include_directories = p;
+
+ /* temporary measure for compress-debug-sections */
+ if (p >= cu_end) return -1;
+
+ /* skip include directories */
+ while (*p) {
+ p = memchr(p, '\0', cu_end - p);
+ if (!p) return -1;
+ p++;
+ }
+ p++;
+
+ filenames = p;
+
+ p = cu_start;
+
+#define FILL_LINE() \
+ do { \
+ fill_line(num_traces, traces, addr, file, line, \
+ include_directories, filenames, \
+ obj, lines, offset); \
+ /*basic_block = prologue_end = epilogue_begin = 0;*/ \
+ } while (0)
+
+ while (p < cu_end) {
+ unsigned long a;
+ unsigned char op = *p++;
+ switch (op) {
+ case DW_LNS_copy:
+ FILL_LINE();
+ break;
+ case DW_LNS_advance_pc:
+ a = uleb128(&p);
+ addr += a;
+ break;
+ case DW_LNS_advance_line: {
+ long a = sleb128(&p);
+ line += a;
+ break;
+ }
+ case DW_LNS_set_file:
+ file = (unsigned int)uleb128(&p);
+ break;
+ case DW_LNS_set_column:
+ /*column = (unsigned int)*/(void)uleb128(&p);
+ break;
+ case DW_LNS_negate_stmt:
+ is_stmt = !is_stmt;
+ break;
+ case DW_LNS_set_basic_block:
+ /*basic_block = 1; */
+ break;
+ case DW_LNS_const_add_pc:
+ a = ((255 - opcode_base) / line_range) *
+ minimum_instruction_length;
+ addr += a;
+ break;
+ case DW_LNS_fixed_advance_pc:
+ a = *(unsigned char *)p++;
+ addr += a;
+ break;
+ case DW_LNS_set_prologue_end:
+ /* prologue_end = 1; */
+ break;
+ case DW_LNS_set_epilogue_begin:
+ /* epilogue_begin = 1; */
+ break;
+ case DW_LNS_set_isa:
+ /* isa = (unsigned int)*/(void)uleb128(&p);
+ break;
+ case 0:
+ a = *(unsigned char *)p++;
+ op = *p++;
+ switch (op) {
+ case DW_LNE_end_sequence:
+ /* end_sequence = 1; */
+ FILL_LINE();
+ addr = 0;
+ file = 1;
+ line = 1;
+ /* column = 0; */
+ is_stmt = default_is_stmt;
+ /* end_sequence = 0; */
+ /* isa = 0; */
+ break;
+ case DW_LNE_set_address:
+ addr = *(unsigned long *)p;
+ p += sizeof(unsigned long);
+ break;
+ case DW_LNE_define_file:
+ kprintf("Unsupported operation in %s\n",
+ binary_filename);
+ break;
+ case DW_LNE_set_discriminator:
+ /* TODO:currently ignore */
+ uleb128(&p);
+ break;
+ default:
+ kprintf("Unknown extended opcode: %d in %s\n",
+ op, binary_filename);
+ }
+ 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;
+ FILL_LINE();
+ }
+ }
+ }
+ *debug_line = p;
+ return 0;
+}
+
+static int
+parse_debug_line(int num_traces, void **traces,
+ char *debug_line, unsigned long size,
+ obj_info_t *obj, line_info_t *lines, int offset)
+{
+ char *debug_line_end = debug_line + size;
+ while (debug_line < debug_line_end) {
+ if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
+ return -1;
+ }
+ if (debug_line != debug_line_end) {
+ kprintf("Unexpected size of .debug_line in %s\n",
+ binary_filename);
+ }
+ return 0;
+}
+
+/* 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);
+
+static void
+append_obj(obj_info_t **objp)
+{
+ obj_info_t *newobj = calloc(1, sizeof(obj_info_t));
+ if (*objp) (*objp)->next = newobj;
+ *objp = newobj;
+}
+
+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;
+ obj_info_t *o1 = *objp, *o2;
+ size_t len;
+
+ p = strrchr(binary_filename, '/');
+ if (!p) {
+ return;
+ }
+ p[1] = '\0';
+
+ len = strlen(binary_filename);
+ if (len >= PATH_MAX - global_debug_dir_len)
+ len = PATH_MAX - global_debug_dir_len - 1;
+ memmove(binary_filename + global_debug_dir_len, binary_filename, len);
+ memcpy(binary_filename, global_debug_dir, global_debug_dir_len);
+ len += global_debug_dir_len;
+ strlcpy(binary_filename + len, debuglink, PATH_MAX - len);
+
+ append_obj(objp);
+ o2 = *objp;
+ o2->base_addr = o1->base_addr;
+ o2->path = o1->path;
+ fill_lines(num_traces, traces, 0, objp, lines, offset);
+}
+
+/* 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)
+{
+ 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;
+ int fd;
+ off_t filesize;
+ char *file;
+ ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
+ ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
+ obj_info_t *obj = *objp;
+ uintptr_t dladdr_fbase = 0;
+ bool compressed_p = false;
+
+ 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;
+ }
+
+ ehdr = (ElfW(Ehdr) *)file;
+ if (memcmp(ehdr->e_ident, "\177ELF", 4) != 0) {
+ /*
+ * 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;
+
+ shdr = (ElfW(Shdr) *)(file + ehdr->e_shoff);
+
+ shstr_shdr = shdr + ehdr->e_shstrndx;
+ shstr = file + shstr_shdr->sh_offset;
+
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ section_name = shstr + shdr[i].sh_name;
+ switch (shdr[i].sh_type) {
+ case SHT_STRTAB:
+ if (!strcmp(section_name, ".strtab")) {
+ strtab_shdr = shdr + i;
+ }
+ else if (!strcmp(section_name, ".dynstr")) {
+ dynstr_shdr = shdr + i;
+ }
+ break;
+ case SHT_SYMTAB:
+ /* if (!strcmp(section_name, ".symtab")) */
+ symtab_shdr = shdr + i;
+ break;
+ case SHT_DYNSYM:
+ /* if (!strcmp(section_name, ".dynsym")) */
+ dynsym_shdr = shdr + i;
+ break;
+ case SHT_PROGBITS:
+ if (!strcmp(section_name, ".debug_line")) {
+ if (shdr[i].sh_flags & SHF_COMPRESSED) {
+ compressed_p = true;
+ }
+ debug_line_shdr = shdr + i;
+ }
+ else if (!strcmp(section_name, ".gnu_debuglink")) {
+ gnu_debuglink_shdr = shdr + i;
+ }
+ break;
+ }
+ }
+
+ if (offset == -1) {
+ /* main executable */
+ offset = 0;
+ if (dynsym_shdr && dynstr_shdr) {
+ 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;
+ }
+ }
+ if (ehdr->e_type == ET_EXEC) {
+ obj->base_addr = 0;
+ }
+ else {
+ /* PIE (position-independent executable) */
+ obj->base_addr = dladdr_fbase;
+ }
+ }
+ }
+
+ 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 (!debug_line_shdr) {
+ /* This file doesn't have .debug_line section,
+ let's check .gnu_debuglink section instead. */
+ if (gnu_debuglink_shdr && check_debuglink) {
+ follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
+ num_traces, traces,
+ objp, lines, offset);
+ }
+ goto finish;
+ }
+
+ if (!compressed_p &&
+ parse_debug_line(num_traces, traces,
+ file + debug_line_shdr->sh_offset,
+ debug_line_shdr->sh_size,
+ obj, lines, offset))
+ goto fail;
+finish:
+ return dladdr_fbase;
+fail:
+ return (uintptr_t)-1;
+}
+
+#define HAVE_MAIN_EXE_PATH
+#if defined(__FreeBSD__)
+# include <sys/sysctl.h>
+#endif
+/* ssize_t main_exe_path(void)
+ *
+ * store the path of the main executable to `binary_filename`,
+ * and returns strlen(binary_filename).
+ * it is NUL terminated.
+ */
+#if defined(__linux__)
+static ssize_t
+main_exe_path(void)
+{
+# define PROC_SELF_EXE "/proc/self/exe"
+ ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
+ binary_filename[len] = 0;
+ return len;
+}
+#elif defined(__FreeBSD__)
+static ssize_t
+main_exe_path(void)
+{
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+ size_t len = PATH_MAX;
+ int err = sysctl(mib, 4, binary_filename, &len, NULL, 0);
+ if (err) {
+ kprintf("Can't get the path of ruby");
+ return -1;
+ }
+ len--; /* sysctl sets strlen+1 */
+ return len;
+}
+#else
+#undef HAVE_MAIN_EXE_PATH
+#endif
+
+void
+rb_dump_backtrace_with_lines(int num_traces, void **traces)
+{
+ int i;
+ /* async-signal unsafe */
+ line_info_t *lines = (line_info_t *)calloc(num_traces, sizeof(line_info_t));
+ obj_info_t *obj = NULL;
+ /* 2 is NULL + main executable */
+ void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
+#ifdef HAVE_MAIN_EXE_PATH
+ char *main_path = NULL; /* used on printing backtrace */
+ ssize_t len;
+ if ((len = main_exe_path()) > 0) {
+ main_path = (char *)alloca(len + 1);
+ if (main_path) {
+ uintptr_t addr;
+ memcpy(main_path, binary_filename, len+1);
+ append_obj(&obj);
+ obj->path = main_path;
+ addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
+ if (addr != (uintptr_t)-1) {
+ dladdr_fbases[0] = (void *)addr;
+ }
+ }
+ }
+#endif
+
+ /* fill source lines by reading dwarf */
+ for (i = 0; i < num_traces; i++) {
+ Dl_info info;
+ if (lines[i].line) continue;
+ if (dladdr(traces[i], &info)) {
+ const char *path;
+ void **p;
+
+ /* skip symbols which is in already checked objects */
+ /* if the binary is strip-ed, this may effect */
+ for (p=dladdr_fbases; *p; p++) {
+ if (*p == info.dli_fbase) {
+ lines[i].path = info.dli_fname;
+ lines[i].sname = info.dli_sname;
+ goto next_line;
+ }
+ }
+ *p = info.dli_fbase;
+
+ append_obj(&obj);
+ obj->base_addr = (uintptr_t)info.dli_fbase;
+ path = info.dli_fname;
+ obj->path = path;
+ lines[i].path = path;
+ strlcpy(binary_filename, path, PATH_MAX);
+ if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
+ break;
+ }
+next_line:
+ continue;
+ }
+
+ /* 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) [0x%lx]\n", line->path, addr-line->base_addr, 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);
+ }
+ /* FreeBSD's backtrace may show _start and so on */
+ if (line->sname && strcmp("main", line->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);
+ }
+ free(o);
+ }
+ free(lines);
+ free(dladdr_fbases);
+}
+
+/* From FreeBSD's lib/libstand/printf.c */
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ */
+
+#include <stdarg.h>
+#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 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);
+
+static void putce(int c)
+{
+ char s[1];
+ ssize_t ret;
+
+ s[0] = (char)c;
+ ret = write(2, s, 1);
+ (void)ret;
+}
+
+int
+kprintf(const char *fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ va_start(ap, fmt);
+ retval = kvprintf(fmt, putce, NULL, 10, ap);
+ va_end(ap);
+ return retval;
+}
+
+/*
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
+ */
+static char *
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
+{
+ char *p, c;
+
+ p = nbuf;
+ *p = '\0';
+ do {
+ c = hex2ascii(num % base);
+ *++p = upper ? toupper(c) : c;
+ } while (num /= base);
+ if (lenp)
+ *lenp = (int)(p - nbuf);
+ return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ *
+ * XXX: %D -- Hexdump, takes pointer and separator string:
+ * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
+ * ("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+static int
+kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
+ char nbuf[MAXNBUF];
+ char *d;
+ const char *p, *percent, *q;
+ unsigned char *up;
+ int ch, n;
+ uintmax_t num;
+ int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int cflag, hflag, jflag, tflag, zflag;
+ int dwidth, upper;
+ char padc;
+ int stop = 0, retval = 0;
+
+ num = 0;
+ if (!func)
+ d = (char *) arg;
+ else
+ d = NULL;
+
+ if (fmt == NULL)
+ fmt = "(fmt null)\n";
+
+ if (radix < 2 || radix > 36)
+ radix = 10;
+
+ for (;;) {
+ padc = ' ';
+ width = 0;
+ while ((ch = (unsigned char)*fmt++) != '%' || stop) {
+ if (ch == '\0')
+ return (retval);
+ PCHAR(ch);
+ }
+ percent = fmt - 1;
+ qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ sign = 0; dot = 0; dwidth = 0; upper = 0;
+ cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
+reswitch: switch (ch = (unsigned char)*fmt++) {
+ case '.':
+ dot = 1;
+ goto reswitch;
+ case '#':
+ sharpflag = 1;
+ goto reswitch;
+ case '+':
+ sign = 1;
+ goto reswitch;
+ case '-':
+ ladjust = 1;
+ goto reswitch;
+ case '%':
+ PCHAR(ch);
+ break;
+ case '*':
+ if (!dot) {
+ width = va_arg(ap, int);
+ if (width < 0) {
+ ladjust = !ladjust;
+ width = -width;
+ }
+ } else {
+ dwidth = va_arg(ap, int);
+ }
+ goto reswitch;
+ case '0':
+ if (!dot) {
+ padc = '0';
+ goto reswitch;
+ }
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ for (n = 0;; ++fmt) {
+ n = n * 10 + ch - '0';
+ ch = *fmt;
+ if (ch < '0' || ch > '9')
+ break;
+ }
+ if (dot)
+ dwidth = n;
+ else
+ width = n;
+ goto reswitch;
+ case 'b':
+ num = (unsigned int)va_arg(ap, int);
+ p = va_arg(ap, char *);
+ for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
+ PCHAR(*q--);
+
+ if (num == 0)
+ break;
+
+ for (tmp = 0; *p;) {
+ n = *p++;
+ if (num & (1 << (n - 1))) {
+ PCHAR(tmp ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ PCHAR(n);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ PCHAR('>');
+ break;
+ case 'c':
+ PCHAR(va_arg(ap, int));
+ break;
+ case 'D':
+ up = va_arg(ap, unsigned char *);
+ p = va_arg(ap, char *);
+ if (!width)
+ width = 16;
+ while(width--) {
+ PCHAR(hex2ascii(*up >> 4));
+ PCHAR(hex2ascii(*up & 0x0f));
+ up++;
+ if (width)
+ for (q=p;*q;q++)
+ PCHAR(*q);
+ }
+ break;
+ case 'd':
+ case 'i':
+ base = 10;
+ sign = 1;
+ goto handle_sign;
+ case 'h':
+ if (hflag) {
+ hflag = 0;
+ cflag = 1;
+ } else
+ hflag = 1;
+ goto reswitch;
+ case 'j':
+ jflag = 1;
+ goto reswitch;
+ case 'l':
+ if (lflag) {
+ lflag = 0;
+ qflag = 1;
+ } else
+ lflag = 1;
+ goto reswitch;
+ case 'n':
+ if (jflag)
+ *(va_arg(ap, intmax_t *)) = retval;
+ else if (qflag)
+ *(va_arg(ap, int64_t *)) = retval;
+ else if (lflag)
+ *(va_arg(ap, long *)) = retval;
+ else if (zflag)
+ *(va_arg(ap, size_t *)) = retval;
+ else if (hflag)
+ *(va_arg(ap, short *)) = retval;
+ else if (cflag)
+ *(va_arg(ap, char *)) = retval;
+ else
+ *(va_arg(ap, int *)) = retval;
+ break;
+ case 'o':
+ base = 8;
+ goto handle_nosign;
+ case 'p':
+ base = 16;
+ sharpflag = (width == 0);
+ sign = 0;
+ num = (uintptr_t)va_arg(ap, void *);
+ goto number;
+ case 'q':
+ qflag = 1;
+ goto reswitch;
+ case 'r':
+ base = radix;
+ if (sign)
+ goto handle_sign;
+ goto handle_nosign;
+ case 's':
+ p = va_arg(ap, char *);
+ if (p == NULL)
+ p = "(null)";
+ if (!dot)
+ n = (int)strlen (p);
+ else
+ for (n = 0; n < dwidth && p[n]; n++)
+ continue;
+
+ width -= n;
+
+ if (!ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ while (n--)
+ PCHAR(*p++);
+ if (ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ break;
+ case 't':
+ tflag = 1;
+ goto reswitch;
+ case 'u':
+ base = 10;
+ goto handle_nosign;
+ case 'X':
+ upper = 1;
+ case 'x':
+ base = 16;
+ goto handle_nosign;
+ case 'y':
+ base = 16;
+ sign = 1;
+ goto handle_sign;
+ case 'z':
+ zflag = 1;
+ goto reswitch;
+handle_nosign:
+ sign = 0;
+ if (jflag)
+ num = va_arg(ap, uintmax_t);
+ else if (qflag)
+ num = va_arg(ap, uint64_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, unsigned long);
+ else if (zflag)
+ num = va_arg(ap, size_t);
+ else if (hflag)
+ num = (unsigned short)va_arg(ap, int);
+ else if (cflag)
+ num = (unsigned char)va_arg(ap, int);
+ else
+ num = va_arg(ap, unsigned int);
+ goto number;
+handle_sign:
+ if (jflag)
+ num = va_arg(ap, intmax_t);
+ else if (qflag)
+ num = va_arg(ap, int64_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, long);
+ else if (zflag)
+ num = va_arg(ap, ssize_t);
+ else if (hflag)
+ num = (short)va_arg(ap, int);
+ else if (cflag)
+ num = (char)va_arg(ap, int);
+ else
+ num = va_arg(ap, int);
+number:
+ if (sign && (intmax_t)num < 0) {
+ neg = 1;
+ num = -(intmax_t)num;
+ }
+ p = ksprintn(nbuf, num, base, &n, upper);
+ tmp = 0;
+ if (sharpflag && num != 0) {
+ if (base == 8)
+ tmp++;
+ else if (base == 16)
+ tmp += 2;
+ }
+ if (neg)
+ tmp++;
+
+ if (!ladjust && padc == '0')
+ dwidth = width - tmp;
+ width -= tmp + imax(dwidth, n);
+ dwidth -= n;
+ if (!ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+ if (neg)
+ PCHAR('-');
+ if (sharpflag && num != 0) {
+ if (base == 8) {
+ PCHAR('0');
+ } else if (base == 16) {
+ PCHAR('0');
+ PCHAR('x');
+ }
+ }
+ while (dwidth-- > 0)
+ PCHAR('0');
+
+ while (*p)
+ PCHAR(*p--);
+
+ if (ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+
+ break;
+ default:
+ while (percent < fmt)
+ PCHAR(*percent++);
+ /*
+ * Since we ignore an formatting argument it is no
+ * longer safe to obey the remaining formatting
+ * arguments as the arguments will no longer match
+ * the format specs.
+ */
+ stop = 1;
+ break;
+ }
+ }
+#undef PCHAR
+}
+#else /* defined(USE_ELF) */
+#error not supported
+#endif
diff --git a/addr2line.h b/addr2line.h
new file mode 100644
index 0000000000..d99f010934
--- /dev/null
+++ b/addr2line.h
@@ -0,0 +1,21 @@
+/**********************************************************************
+
+ addr2line.h -
+
+ $Author$
+
+ Copyright (C) 2010 Shinichiro Hamaji
+
+**********************************************************************/
+
+#ifndef RUBY_ADDR2LINE_H
+#define RUBY_ADDR2LINE_H
+
+#ifdef USE_ELF
+
+void
+rb_dump_backtrace_with_lines(int num_traces, void **traces);
+
+#endif /* USE_ELF */
+
+#endif /* RUBY_ADDR2LINE_H */
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000000..22c7bdce6a
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,55 @@
+---
+shallow_clone: true
+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
diff --git a/array.c b/array.c
index 10d554ba2c..1600e484fe 100644
--- a/array.c
+++ b/array.c
@@ -1,26 +1,141 @@
-/************************************************
+/**********************************************************************
array.c -
$Author$
- $Date$
created at: Fri Aug 6 09:46:12 JST 1993
- Copyright (C) 1993-1998 Yukihiro Matsumoto
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
+ Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ Copyright (C) 2000 Information-technology Promotion Agency, Japan
-************************************************/
+**********************************************************************/
-#include "ruby.h"
+#include "internal.h"
+#include "ruby/util.h"
+#include "ruby/st.h"
+#include "probes.h"
+#include "id.h"
+#include "debug_counter.h"
+#ifndef ARRAY_DEBUG
+# define NDEBUG
+#endif
+#include "ruby_assert.h"
+
+VALUE rb_cArray;
-VALUE cArray;
+/* for OPTIMIZED_CMP: */
+#define id_cmp idCmp
#define ARY_DEFAULT_SIZE 16
+#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)
+
+#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_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_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); \
+} 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)); \
+ FL_SET((ary), ELTS_SHARED); \
+} while (0)
+#define FL_UNSET_SHARED(ary) FL_UNSET((ary), ELTS_SHARED)
+
+#define ARY_SET_PTR(ary, p) do { \
+ assert(!ARY_EMBED_P(ary)); \
+ assert(!OBJ_FROZEN(ary)); \
+ RARRAY(ary)->as.heap.ptr = (p); \
+} while (0)
+#define ARY_SET_EMBED_LEN(ary, n) do { \
+ long tmp_n = (n); \
+ assert(ARY_EMBED_P(ary)); \
+ assert(!OBJ_FROZEN(ary)); \
+ RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
+ RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
+} while (0)
+#define ARY_SET_HEAP_LEN(ary, n) do { \
+ assert(!ARY_EMBED_P(ary)); \
+ RARRAY(ary)->as.heap.len = (n); \
+} while (0)
+#define ARY_SET_LEN(ary, n) do { \
+ if (ARY_EMBED_P(ary)) { \
+ ARY_SET_EMBED_LEN((ary), (n)); \
+ } \
+ else { \
+ ARY_SET_HEAP_LEN((ary), (n)); \
+ } \
+ assert(RARRAY_LEN(ary) == (n)); \
+} while (0)
+#define ARY_INCREASE_PTR(ary, n) do { \
+ assert(!ARY_EMBED_P(ary)); \
+ assert(!OBJ_FROZEN(ary)); \
+ RARRAY(ary)->as.heap.ptr += (n); \
+} while (0)
+#define ARY_INCREASE_LEN(ary, n) do { \
+ assert(!OBJ_FROZEN(ary)); \
+ if (ARY_EMBED_P(ary)) { \
+ ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
+ } \
+ else { \
+ RARRAY(ary)->as.heap.len += (n); \
+ } \
+} 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)
+#define ARY_SET_CAPA(ary, n) do { \
+ assert(!ARY_EMBED_P(ary)); \
+ assert(!ARY_SHARED_P(ary)); \
+ assert(!OBJ_FROZEN(ary)); \
+ 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_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_); \
+} 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) \
+ (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 { \
+ 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)); \
+ 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))
void
-memclear(mem, size)
- register VALUE *mem;
- register int size;
+rb_mem_clear(register VALUE *mem, register long size)
{
while (size--) {
*mem++ = Qnil;
@@ -28,1363 +143,6217 @@ memclear(mem, size)
}
static void
-memfill(mem, size, val)
- register VALUE *mem;
- register int size;
- register VALUE val;
+ary_mem_clear(VALUE ary, long beg, long size)
+{
+ RARRAY_PTR_USE(ary, ptr, {
+ rb_mem_clear(ptr + beg, size);
+ });
+}
+
+static inline void
+memfill(register VALUE *mem, register long size, register VALUE val)
{
while (size--) {
*mem++ = val;
}
}
-#define ARY_FREEZE FL_USER1
+static void
+ary_memfill(VALUE ary, long beg, long size, VALUE val)
+{
+ RARRAY_PTR_USE(ary, ptr, {
+ memfill(ptr + beg, size, val);
+ RB_OBJ_WRITTEN(ary, Qundef, val);
+ });
+}
static void
-ary_modify(ary)
- VALUE ary;
+ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_ary)
{
- rb_secure(5);
- if (FL_TEST(ary, ARY_FREEZE)) {
- TypeError("can't modify frozen array");
+#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);
+ });
+ }
+ 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]);
+ }
+ });
}
+#else
+ /* giveup write barrier (traditional way) */
+ RARRAY_PTR(buff_owner_ary);
+ MEMCPY(RARRAY_PTR(ary)+beg, argv, VALUE, argc);
+#endif
}
-VALUE
-ary_freeze(ary)
- VALUE ary;
+static void
+ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
{
- FL_SET(ary, ARY_FREEZE);
+ ary_memcpy0(ary, beg, argc, argv, ary);
+}
+
+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));
+ 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_SET_CAPA(ary, (capacity));
+ }
+ else {
+ if (!ARY_EMBED_P(ary)) {
+ long len = RARRAY_LEN(ary);
+ const VALUE *ptr = RARRAY_CONST_PTR(ary);
+
+ if (len > capacity) len = capacity;
+ MEMCPY((VALUE *)RARRAY(ary)->as.ary, ptr, VALUE, len);
+ FL_SET_EMBED(ary);
+ ARY_SET_LEN(ary, len);
+ ruby_xfree((VALUE *)ptr);
+ }
+ }
+}
+
+static inline void
+ary_shrink_capa(VALUE ary)
+{
+ long capacity = ARY_HEAP_LEN(ary);
+ long old_capa = RARRAY(ary)->as.heap.aux.capa;
+ assert(!ARY_SHARED_P(ary));
+ assert(old_capa >= capacity);
+ if (old_capa > capacity)
+ REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, capacity);
+}
+
+static void
+ary_double_capa(VALUE ary, long min)
+{
+ long new_capa = ARY_CAPA(ary) / 2;
+
+ if (new_capa < ARY_DEFAULT_SIZE) {
+ new_capa = ARY_DEFAULT_SIZE;
+ }
+ if (new_capa >= ARY_MAX_SIZE - min) {
+ new_capa = (ARY_MAX_SIZE - min) / 2;
+ }
+ new_capa += min;
+ ary_resize_capa(ary, new_capa);
+}
+
+static void
+rb_ary_decrement_share(VALUE shared)
+{
+ if (shared) {
+ long num = ARY_SHARED_NUM(shared) - 1;
+ if (num == 0) {
+ rb_ary_free(shared);
+ rb_gc_force_recycle(shared);
+ }
+ else if (num > 0) {
+ ARY_SET_SHARED_NUM(shared, num);
+ }
+ }
+}
+
+static void
+rb_ary_unshare(VALUE ary)
+{
+ VALUE shared = RARRAY(ary)->as.heap.aux.shared;
+ rb_ary_decrement_share(shared);
+ FL_UNSET_SHARED(ary);
+}
+
+static inline void
+rb_ary_unshare_safe(VALUE ary)
+{
+ if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
+ rb_ary_unshare(ary);
+ }
+}
+
+static VALUE
+rb_ary_increment_share(VALUE shared)
+{
+ long num = ARY_SHARED_NUM(shared);
+ if (num >= 0) {
+ ARY_SET_SHARED_NUM(shared, num + 1);
+ }
+ return shared;
+}
+
+static void
+rb_ary_set_shared(VALUE ary, VALUE shared)
+{
+ rb_ary_increment_share(shared);
+ FL_SET_SHARED(ary);
+ ARY_SET_SHARED(ary, shared);
+}
+
+static inline void
+rb_ary_modify_check(VALUE ary)
+{
+ rb_check_frozen(ary);
+}
+
+void
+rb_ary_modify(VALUE ary)
+{
+ rb_ary_modify_check(ary);
+ if (ARY_SHARED_P(ary)) {
+ long shared_len, len = RARRAY_LEN(ary);
+ VALUE shared = ARY_SHARED(ary);
+ if (len <= RARRAY_EMBED_LEN_MAX) {
+ 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);
+ 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 {
+ VALUE *ptr = ALLOC_N(VALUE, len);
+ MEMCPY(ptr, RARRAY_CONST_PTR(ary), VALUE, len);
+ rb_ary_unshare(ary);
+ ARY_SET_CAPA(ary, len);
+ ARY_SET_PTR(ary, ptr);
+ }
+
+ rb_gc_writebarrier_remember(ary);
+ }
+}
+
+static VALUE
+ary_ensure_room_for_push(VALUE ary, long add_len)
+{
+ long old_len = RARRAY_LEN(ary);
+ long new_len = old_len + add_len;
+ long capa;
+
+ if (old_len > ARY_MAX_SIZE - add_len) {
+ rb_raise(rb_eIndexError, "index %ld too big", new_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)) {
+ rb_ary_modify_check(ary);
+ return shared;
+ }
+ else {
+ /* if array is shared, then it is likely it participate in push/shift pattern */
+ rb_ary_modify(ary);
+ capa = ARY_CAPA(ary);
+ if (new_len > capa - (capa >> 6)) {
+ ary_double_capa(ary, new_len);
+ }
+ return ary;
+ }
+ }
+ }
+ rb_ary_modify(ary);
+ }
+ else {
+ rb_ary_modify_check(ary);
+ }
+ capa = ARY_CAPA(ary);
+ if (new_len > capa) {
+ ary_double_capa(ary, new_len);
+ }
+
return ary;
}
+/*
+ * call-seq:
+ * ary.freeze -> ary
+ *
+ * Calls Object#freeze on +ary+ to prevent any further
+ * modification. A RuntimeError will be raised if a modification
+ * attempt is made.
+ *
+ */
+
+VALUE
+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
-ary_frozen_p(ary)
- VALUE ary;
+rb_ary_frozen_p(VALUE ary)
{
- if (FL_TEST(ary, ARY_FREEZE))
- return TRUE;
- return FALSE;
+ 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
+ something does modify the array it will pay the cost of copying
+ it. If Array#pop or Array#shift has been called, the array will
+ be still shared with the snapshot, but the array length will
+ differ. */
VALUE
-ary_new2(len)
- int len;
+rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
{
- NEWOBJ(ary, struct RArray);
- OBJSETUP(ary, cArray, T_ARRAY);
+ 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.len == RARRAY(ary2)->as.heap.len) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
- if (len < 0) {
- ArgError("negative array size (or size too big)");
+static VALUE
+ary_alloc(VALUE klass)
+{
+ NEWOBJ_OF(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
+empty_ary_alloc(VALUE klass)
+{
+ RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
+ return ary_alloc(klass);
+}
+
+static VALUE
+ary_new(VALUE klass, long capa)
+{
+ VALUE ary,*ptr;
+
+ if (capa < 0) {
+ rb_raise(rb_eArgError, "negative array size (or size too big)");
}
- if (len > 0 && len*sizeof(VALUE) <= 0) {
- ArgError("array size too big");
+ if (capa > ARY_MAX_SIZE) {
+ rb_raise(rb_eArgError, "array size too big");
}
- ary->len = 0;
- ary->capa = len;
- ary->ptr = 0;
- ary->ptr = ALLOC_N(VALUE, len);
- memclear(ary->ptr, len);
- return (VALUE)ary;
+ RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
+
+ ary = ary_alloc(klass);
+ if (capa > RARRAY_EMBED_LEN_MAX) {
+ ptr = ALLOC_N(VALUE, capa);
+ FL_UNSET_EMBED(ary);
+ ARY_SET_PTR(ary, ptr);
+ ARY_SET_CAPA(ary, capa);
+ ARY_SET_HEAP_LEN(ary, 0);
+ }
+
+ return ary;
}
VALUE
-ary_new()
+rb_ary_new_capa(long capa)
{
- return ary_new2(ARY_DEFAULT_SIZE);
+ return ary_new(rb_cArray, capa);
}
-#ifdef HAVE_STDARG_PROTOTYPES
-#include <stdarg.h>
-#define va_init_list(a,b) va_start(a,b)
-#else
-#include <varargs.h>
-#define va_init_list(a,b) va_start(a)
-#endif
+VALUE
+rb_ary_new(void)
+{
+ return rb_ary_new2(RARRAY_EMBED_LEN_MAX);
+}
VALUE
-#ifdef HAVE_STDARG_PROTOTYPES
-ary_new3(int n, ...)
-#else
-ary_new3(n, va_alist)
- int n;
- va_dcl
-#endif
+(rb_ary_new_from_args)(long n, ...)
{
va_list ar;
VALUE ary;
- int i;
+ long i;
- if (n < 0) {
- IndexError("Negative number of items(%d)", n);
- }
- ary = ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n);
+ ary = rb_ary_new2(n);
- va_init_list(ar, n);
+ va_start(ar, n);
for (i=0; i<n; i++) {
- RARRAY(ary)->ptr[i] = va_arg(ar, VALUE);
+ ARY_SET(ary, i, va_arg(ar, VALUE));
}
va_end(ar);
- RARRAY(ary)->len = n;
+ ARY_SET_LEN(ary, n);
return ary;
}
VALUE
-ary_new4(n, elts)
- int n;
- VALUE *elts;
+rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
{
VALUE ary;
- ary = ary_new2(n);
- if (elts) {
- MEMCPY(RARRAY(ary)->ptr, elts, VALUE, n);
+ ary = ary_new(klass, n);
+ if (n > 0 && elts) {
+ ary_memcpy(ary, 0, n, elts);
+ ARY_SET_LEN(ary, n);
}
- RARRAY(ary)->len = n;
return ary;
}
VALUE
-assoc_new(car, cdr)
- VALUE car, cdr;
+rb_ary_new_from_values(long n, const VALUE *elts)
{
- VALUE ary;
+ return rb_ary_tmp_new_from_values(rb_cArray, n, elts);
+}
- ary = ary_new2(2);
- RARRAY(ary)->ptr[0] = car;
- RARRAY(ary)->ptr[1] = cdr;
- RARRAY(ary)->len = 2;
+VALUE
+rb_ary_tmp_new(long capa)
+{
+ return ary_new(0, capa);
+}
+VALUE
+rb_ary_tmp_new_fill(long capa)
+{
+ VALUE ary = ary_new(0, capa);
+ ary_memfill(ary, 0, capa, Qnil);
+ ARY_SET_LEN(ary, capa);
return ary;
}
-static VALUE
-ary_s_new(argc, argv, klass)
- int argc;
- VALUE *argv;
- VALUE klass;
+void
+rb_ary_free(VALUE ary)
{
- int len = 0;
- VALUE size, val;
- NEWOBJ(ary, struct RArray);
- OBJSETUP(ary, klass, T_ARRAY);
+ 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));
+ }
+ else {
+ RB_DEBUG_COUNTER_INC(obj_ary_embed);
+ }
+}
- ary->len = 0;
- ary->ptr = 0;
- if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
- ary->capa = ARY_DEFAULT_SIZE;
+RUBY_FUNC_EXPORTED size_t
+rb_ary_memsize(VALUE ary)
+{
+ if (ARY_OWNS_HEAP_P(ary)) {
+ return ARY_CAPA(ary) * sizeof(VALUE);
}
else {
- int capa = NUM2INT(size);
+ return 0;
+ }
+}
- if (capa < 0) {
- ArgError("negative array size");
- }
- if (capa > 0 && capa*sizeof(VALUE) <= 0) {
- ArgError("array size too big");
- }
- ary->capa = capa;
- len = capa;
+static inline void
+ary_discard(VALUE ary)
+{
+ rb_ary_free(ary);
+ RBASIC(ary)->flags |= RARRAY_EMBED_FLAG;
+ RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK;
+}
+
+static VALUE
+ary_make_shared(VALUE ary)
+{
+ assert(!ARY_EMBED_P(ary));
+ if (ARY_SHARED_P(ary)) {
+ return ARY_SHARED(ary);
}
- ary->ptr = ALLOC_N(VALUE, ary->capa);
- memfill(ary->ptr, len, val);
- ary->len = len;
- obj_call_init((VALUE)ary);
+ else if (ARY_SHARED_ROOT_P(ary)) {
+ return ary;
+ }
+ else if (OBJ_FROZEN(ary)) {
+ ary_shrink_capa(ary);
+ FL_SET_SHARED_ROOT(ary);
+ ARY_SET_SHARED_NUM(ary, 1);
+ return ary;
+ }
+ else {
+ long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary);
+ NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
+ FL_UNSET_EMBED(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);
+ FL_SET_SHARED(ary);
+ ARY_SET_SHARED(ary, (VALUE)shared);
+ OBJ_FREEZE(shared);
+ return (VALUE)shared;
+ }
+}
- return (VALUE)ary;
+static VALUE
+ary_make_substitution(VALUE ary)
+{
+ long len = RARRAY_LEN(ary);
+
+ if (len <= RARRAY_EMBED_LEN_MAX) {
+ VALUE subst = rb_ary_new2(len);
+ ary_memcpy(subst, 0, len, RARRAY_CONST_PTR(ary));
+ ARY_SET_EMBED_LEN(subst, len);
+ return subst;
+ }
+ else {
+ return rb_ary_increment_share(ary_make_shared(ary));
+ }
+}
+
+VALUE
+rb_assoc_new(VALUE car, VALUE cdr)
+{
+ return rb_ary_new3(2, car, cdr);
+}
+
+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)
+{
+ return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
+}
+
+/*
+ * call-seq:
+ * Array.try_convert(obj) -> 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.
+ *
+ * Array.try_convert([1]) #=> [1]
+ * Array.try_convert("1") #=> nil
+ *
+ * if tmp = Array.try_convert(arg)
+ * # the argument is an array
+ * elsif tmp = String.try_convert(arg)
+ * # the argument is a string
+ * end
+ *
+ */
static VALUE
-ary_s_create(argc, argv, klass)
- int argc;
- VALUE *argv;
- VALUE klass;
+rb_ary_s_try_convert(VALUE dummy, VALUE ary)
+{
+ return rb_check_array_type(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"}, {}]
+ *
+ */
+
+static VALUE
+rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
{
- NEWOBJ(ary, struct RArray);
- OBJSETUP(ary, klass, T_ARRAY);
+ long len;
+ VALUE size, val;
- ary->len = argc;
- ary->capa = argc;
+ rb_ary_modify(ary);
if (argc == 0) {
- ary->ptr = 0;
+ if (ARY_OWNS_HEAP_P(ary) && RARRAY_CONST_PTR(ary) != 0) {
+ ruby_sized_xfree((void *)RARRAY_CONST_PTR(ary), ARY_HEAP_SIZE(ary));
+ }
+ rb_ary_unshare_safe(ary);
+ FL_SET_EMBED(ary);
+ ARY_SET_EMBED_LEN(ary, 0);
+ if (rb_block_given_p()) {
+ rb_warning("given block not used");
+ }
+ return ary;
+ }
+ rb_scan_args(argc, argv, "02", &size, &val);
+ if (argc == 1 && !FIXNUM_P(size)) {
+ val = rb_check_array_type(size);
+ if (!NIL_P(val)) {
+ rb_ary_replace(ary, val);
+ return ary;
+ }
+ }
+
+ len = NUM2LONG(size);
+ /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
+ if (len < 0) {
+ rb_raise(rb_eArgError, "negative array size");
+ }
+ if (len > ARY_MAX_SIZE) {
+ rb_raise(rb_eArgError, "array size too big");
+ }
+ /* recheck after argument conversion */
+ rb_ary_modify(ary);
+ ary_resize_capa(ary, len);
+ if (rb_block_given_p()) {
+ long i;
+
+ if (argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
+ for (i=0; i<len; i++) {
+ rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
+ ARY_SET_LEN(ary, i + 1);
+ }
}
else {
- ary->ptr = ALLOC_N(VALUE, argc);
- MEMCPY(ary->ptr, argv, VALUE, argc);
+ ary_memfill(ary, 0, len, val);
+ ARY_SET_LEN(ary, len);
}
+ return ary;
+}
- return (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/]
+ * [ 1, 'a', /^A/ ] # => [1, "a", /^A/]
+ */
+
+static VALUE
+rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE ary = ary_new(klass, argc);
+ if (argc > 0 && argv) {
+ ary_memcpy(ary, 0, argc, argv);
+ ARY_SET_LEN(ary, argc);
+ }
+
+ return ary;
}
void
-ary_store(ary, idx, val)
- VALUE ary;
- int idx;
- VALUE val;
+rb_ary_store(VALUE ary, long idx, VALUE val)
{
- ary_modify(ary);
+ long len = RARRAY_LEN(ary);
+
if (idx < 0) {
- IndexError("negative index for array");
+ idx += len;
+ if (idx < 0) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ idx - len, -len);
+ }
+ }
+ else if (idx >= ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
}
- if (idx >= RARRAY(ary)->capa) {
- RARRAY(ary)->capa = idx + ARY_DEFAULT_SIZE;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+ rb_ary_modify(ary);
+ if (idx >= ARY_CAPA(ary)) {
+ ary_double_capa(ary, idx);
}
- if (idx > RARRAY(ary)->len) {
- memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, idx-RARRAY(ary)->len+1);
+ if (idx > len) {
+ ary_mem_clear(ary, len, idx - len + 1);
}
- if (idx >= RARRAY(ary)->len) {
- RARRAY(ary)->len = idx + 1;
+ if (idx >= len) {
+ ARY_SET_LEN(ary, idx + 1);
}
- RARRAY(ary)->ptr[idx] = val;
+ ARY_SET(ary, idx, val);
}
-VALUE
-ary_push(ary, item)
- VALUE ary;
- VALUE item;
+static VALUE
+ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
{
- ary_store(ary, RARRAY(ary)->len, item);
- return ary;
+ assert(offset >= 0);
+ assert(len >= 0);
+ assert(offset+len <= RARRAY_LEN(ary));
+
+ if (len <= RARRAY_EMBED_LEN_MAX) {
+ VALUE result = ary_alloc(klass);
+ ary_memcpy(result, 0, len, RARRAY_CONST_PTR(ary) + offset);
+ ARY_SET_EMBED_LEN(result, len);
+ return result;
+ }
+ else {
+ VALUE shared, result = ary_alloc(klass);
+ FL_UNSET_EMBED(result);
+
+ shared = ary_make_shared(ary);
+ ARY_SET_PTR(result, RARRAY_CONST_PTR(ary));
+ ARY_SET_LEN(result, RARRAY_LEN(ary));
+ rb_ary_set_shared(result, shared);
+
+ ARY_INCREASE_PTR(result, offset);
+ ARY_SET_LEN(result, len);
+ return result;
+ }
}
static VALUE
-ary_push_method(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+ary_make_shared_copy(VALUE ary)
+{
+ return ary_make_partial(ary, rb_obj_class(ary), 0, RARRAY_LEN(ary));
+}
+
+enum ary_take_pos_flags
{
- while (argc--) {
- ary_store(ary, RARRAY(ary)->len, *argv++);
+ ARY_TAKE_FIRST = 0,
+ ARY_TAKE_LAST = 1
+};
+
+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);
+ len = RARRAY_LEN(ary);
+ if (n > len) {
+ n = len;
+ }
+ else if (n < 0) {
+ rb_raise(rb_eArgError, "negative array size");
+ }
+ if (last) {
+ offset = len - n;
}
+ return ary_make_partial(ary, rb_cArray, offset, n);
+}
+
+/*
+ * 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.
+ *
+ * a = [ 1, 2 ]
+ * a << "c" << "d" << [ 3, 4 ]
+ * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
+ * a
+ * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
+ *
+ */
+
+VALUE
+rb_ary_push(VALUE ary, VALUE item)
+{
+ long idx = RARRAY_LEN(ary);
+ VALUE target_ary = ary_ensure_room_for_push(ary, 1);
+ RARRAY_PTR_USE(ary, ptr, {
+ RB_OBJ_WRITE(target_ary, &ptr[idx], item);
+ });
+ ARY_SET_LEN(ary, idx + 1);
return ary;
}
VALUE
-ary_pop(ary)
- VALUE ary;
+rb_ary_cat(VALUE ary, const VALUE *argv, long len)
{
- if (RARRAY(ary)->len == 0) return Qnil;
- if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
- RARRAY(ary)->capa = RARRAY(ary)->len * 2;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
- }
- return RARRAY(ary)->ptr[--RARRAY(ary)->len];
+ long oldlen = RARRAY_LEN(ary);
+ VALUE target_ary = ary_ensure_room_for_push(ary, len);
+ ary_memcpy0(ary, oldlen, len, argv, target_ary);
+ ARY_SET_LEN(ary, oldlen + len);
+ return ary;
+}
+
+/*
+ * 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]
+ */
+
+static VALUE
+rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
+{
+ return rb_ary_cat(ary, argv, argc);
}
VALUE
-ary_shift(ary)
- VALUE ary;
+rb_ary_pop(VALUE ary)
{
- VALUE top;
+ long n;
+ rb_ary_modify_check(ary);
+ n = RARRAY_LEN(ary);
+ if (n == 0) return Qnil;
+ if (ARY_OWNS_HEAP_P(ary) &&
+ n * 3 < ARY_CAPA(ary) &&
+ ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
+ {
+ ary_resize_capa(ary, n * 2);
+ }
+ --n;
+ ARY_SET_LEN(ary, n);
+ return RARRAY_AREF(ary, n);
+}
- if (RARRAY(ary)->len == 0) return Qnil;
+/*
+ * call-seq:
+ * ary.pop -> obj or nil
+ * ary.pop(n) -> new_ary
+ *
+ * Removes the last element from +self+ and returns it, or
+ * +nil+ if the array is empty.
+ *
+ * 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.
+ *
+ * a = [ "a", "b", "c", "d" ]
+ * a.pop #=> "d"
+ * a.pop(2) #=> ["b", "c"]
+ * a #=> ["a"]
+ */
- top = RARRAY(ary)->ptr[0];
- RARRAY(ary)->len--;
+static VALUE
+rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
+{
+ VALUE result;
- /* sliding items */
- MEMMOVE(RARRAY(ary)->ptr, RARRAY(ary)->ptr+1, VALUE, RARRAY(ary)->len);
- if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
- RARRAY(ary)->capa = RARRAY(ary)->len * 2;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+ if (argc == 0) {
+ return rb_ary_pop(ary);
}
- return top;
+ rb_ary_modify_check(ary);
+ result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
+ ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
+ return result;
}
VALUE
-ary_unshift(ary, item)
- VALUE ary, item;
+rb_ary_shift(VALUE ary)
{
- ary_modify(ary);
- if (RARRAY(ary)->len >= RARRAY(ary)->capa) {
- RARRAY(ary)->capa+=ARY_DEFAULT_SIZE;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
- }
+ VALUE top;
+ long len = RARRAY_LEN(ary);
+
+ rb_ary_modify_check(ary);
+ if (len == 0) return Qnil;
+ top = RARRAY_AREF(ary, 0);
+ if (!ARY_SHARED_P(ary)) {
+ if (len < ARY_DEFAULT_SIZE) {
+ RARRAY_PTR_USE(ary, ptr, {
+ MEMMOVE(ptr, ptr+1, VALUE, len-1);
+ }); /* WB: no new reference */
+ ARY_INCREASE_LEN(ary, -1);
+ return top;
+ }
+ assert(!ARY_EMBED_P(ary)); /* ARY_EMBED_LEN_MAX < ARY_DEFAULT_SIZE */
- /* sliding items */
- MEMMOVE(RARRAY(ary)->ptr+1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
+ 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);
+ }
+ ARY_INCREASE_PTR(ary, 1); /* shift ptr */
+ ARY_INCREASE_LEN(ary, -1);
- RARRAY(ary)->len++;
- return RARRAY(ary)->ptr[0] = item;
+ return top;
}
-VALUE
-ary_entry(ary, offset)
- VALUE ary;
- int offset;
+/*
+ * call-seq:
+ * ary.shift -> obj or nil
+ * ary.shift(n) -> new_ary
+ *
+ * Removes the first element of +self+ and returns it (shifting all
+ * other elements down by one). Returns +nil+ if the array
+ * 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.
+ *
+ * args = [ "-m", "-q", "filename" ]
+ * args.shift #=> "-m"
+ * args #=> ["-q", "filename"]
+ *
+ * args = [ "-m", "-q", "filename" ]
+ * args.shift(2) #=> ["-m", "-q"]
+ * args #=> ["filename"]
+ */
+
+static VALUE
+rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
{
- if (RARRAY(ary)->len == 0) return Qnil;
+ VALUE result;
+ long n;
- if (offset < 0) {
- offset = RARRAY(ary)->len + offset;
+ if (argc == 0) {
+ return rb_ary_shift(ary);
}
- if (offset < 0 || RARRAY(ary)->len <= offset) {
- return Qnil;
+
+ 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);
+ }
+ 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;
+ }
}
+ ARY_INCREASE_LEN(ary, -n);
- return RARRAY(ary)->ptr[offset];
+ return result;
}
static VALUE
-ary_subseq(ary, beg, len)
- VALUE ary;
- int beg, len;
+ary_ensure_room_for_unshift(VALUE ary, int argc)
{
- VALUE ary2;
+ long len = RARRAY_LEN(ary);
+ long new_len = len + argc;
+ long capa;
+ const VALUE *head, *sharedp;
- if (beg < 0) {
- beg = RARRAY(ary)->len + beg;
- if (beg < 0) beg = 0;
+ if (len > ARY_MAX_SIZE - argc) {
+ rb_raise(rb_eIndexError, "index %ld too big", new_len);
}
- if (len < 0) {
- IndexError("negative length %d", RARRAY(ary)->len);
+
+ rb_ary_modify(ary);
+
+ 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;
+ }
}
- if (len == 0) {
- return ary_new2(0);
+
+ capa = ARY_CAPA(ary);
+ if (capa - (capa >> 6) <= new_len) {
+ ary_double_capa(ary, new_len);
}
- if (beg + len > RARRAY(ary)->len) {
- len = RARRAY(ary)->len - beg;
+
+ /* use shared array for big "queues" */
+ if (new_len > ARY_DEFAULT_SIZE * 4) {
+ /* 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);
}
- if (len < 0) {
- len = 0;
+ else {
+ /* sliding items */
+ RARRAY_PTR_USE(ary, ptr, {
+ MEMMOVE(ptr + argc, ptr, VALUE, len);
+ });
+
+ return ary;
}
+}
- ary2 = ary_new2(len);
- MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len);
- RARRAY(ary2)->len = len;
+/*
+ * call-seq:
+ * ary.unshift(obj, ...) -> ary
+ *
+ * Prepends objects to the front of +self+, moving other elements upwards.
+ * See also Array#shift for the opposite effect.
+ *
+ * a = [ "b", "c", "d" ]
+ * a.unshift("a") #=> ["a", "b", "c", "d"]
+ * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
+ */
- return ary2;
+static VALUE
+rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
+{
+ long len = RARRAY_LEN(ary);
+ VALUE target_ary;
+
+ if (argc == 0) {
+ rb_ary_modify_check(ary);
+ return ary;
+ }
+
+ target_ary = ary_ensure_room_for_unshift(ary, argc);
+ ary_memcpy0(ary, 0, argc, argv, target_ary);
+ ARY_SET_LEN(ary, len + argc);
+ return ary;
}
-static VALUE
-beg_len(range, begp, lenp, len)
- VALUE range;
- int *begp, *lenp;
- int len;
+VALUE
+rb_ary_unshift(VALUE ary, VALUE item)
{
- int beg, end;
- int b, e;
+ return rb_ary_unshift_m(1,&item,ary);
+}
- if (!range_beg_end(range, &beg, &end)) return FALSE;
- b = beg; e = end;
+/* faster version - use this if you don't need to treat negative offset */
+static inline VALUE
+rb_ary_elt(VALUE ary, long offset)
+{
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ if (offset < 0 || len <= offset) {
+ return Qnil;
+ }
+ return RARRAY_AREF(ary, offset);
+}
- if (beg < 0) {
- beg = len + beg;
- if (beg < 0) beg = 0;
+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;
}
- if (end < 0) {
- end = len + end;
- if (end < 0) end = -1;
+ else if (len <= offset) {
+ return Qnil;
}
- if (beg > end) {
- IndexError("end smaller than beg [%d..%d]", b, e);
+ return ptr[offset];
+}
+
+VALUE
+rb_ary_subseq(VALUE ary, long beg, long len)
+{
+ VALUE klass;
+ long alen = RARRAY_LEN(ary);
+
+ if (beg > alen) return Qnil;
+ if (beg < 0 || len < 0) return Qnil;
+
+ if (alen < len || alen < beg + len) {
+ len = alen - beg;
}
+ klass = rb_obj_class(ary);
+ if (len == 0) return ary_new(klass, 0);
+
+ return ary_make_partial(ary, klass, beg, len);
+}
+
+/*
+ * 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] #=> []
+ *
+ */
- *begp = beg;
- if (beg > len) {
- *lenp = 0;
+VALUE
+rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
+{
+ rb_check_arity(argc, 1, 2);
+ if (argc == 2) {
+ return rb_ary_aref2(ary, argv[0], argv[1]);
}
- else {
- *lenp = end - beg +1;
+ return rb_ary_aref1(ary, argv[0]);
+}
+
+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);
}
- return TRUE;
+ return rb_ary_subseq(ary, beg, len);
}
VALUE
-ary_aref(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+rb_ary_aref1(VALUE ary, VALUE arg)
{
- VALUE arg1, arg2;
- int beg, len;
+ long beg, len;
- if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
- beg = NUM2INT(arg1);
- len = NUM2INT(arg2);
- if (len <= 0) {
- return ary_new();
- }
- return ary_subseq(ary, beg, len);
+ /* 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)) {
+ case Qfalse:
+ break;
+ case Qnil:
+ return Qnil;
+ default:
+ return rb_ary_subseq(ary, beg, len);
}
+ return rb_ary_entry(ary, NUM2LONG(arg));
+}
- /* special case - speeding up */
- if (FIXNUM_P(arg1)) {
- return ary_entry(ary, FIX2INT(arg1));
+/*
+ * 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#[].
+ *
+ * a = [ "a", "b", "c", "d", "e" ]
+ * a.at(0) #=> "a"
+ * a.at(-1) #=> "e"
+ */
+
+VALUE
+rb_ary_at(VALUE ary, VALUE pos)
+{
+ return rb_ary_entry(ary, NUM2LONG(pos));
+}
+
+/*
+ * call-seq:
+ * ary.first -> obj or nil
+ * ary.first(n) -> new_ary
+ *
+ * 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.
+ *
+ * a = [ "q", "r", "s", "t" ]
+ * a.first #=> "q"
+ * a.first(2) #=> ["q", "r"]
+ */
+
+static VALUE
+rb_ary_first(int argc, VALUE *argv, VALUE ary)
+{
+ if (argc == 0) {
+ if (RARRAY_LEN(ary) == 0) return Qnil;
+ return RARRAY_AREF(ary, 0);
}
- else if (TYPE(arg1) == T_BIGNUM) {
- IndexError("index too big");
+ else {
+ return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
- else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
- /* check if idx is Range */
- return ary_subseq(ary, beg, len);
+}
+
+/*
+ * call-seq:
+ * ary.last -> obj or nil
+ * ary.last(n) -> new_ary
+ *
+ * Returns the last element(s) of +self+. If the array is empty,
+ * the first form returns +nil+.
+ *
+ * See also Array#first for the opposite effect.
+ *
+ * a = [ "w", "x", "y", "z" ]
+ * a.last #=> "z"
+ * a.last(2) #=> ["y", "z"]
+ */
+
+VALUE
+rb_ary_last(int argc, const VALUE *argv, VALUE ary)
+{
+ if (argc == 0) {
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ return RARRAY_AREF(ary, len-1);
+ }
+ else {
+ return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
}
- return ary_entry(ary, NUM2INT(arg1));
}
+/*
+ * 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"
+ */
+
static VALUE
-ary_index(ary, val)
- VALUE ary;
- VALUE val;
+rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
{
- int i;
+ VALUE pos, ifnone;
+ long block_given;
+ long idx;
+
+ rb_scan_args(argc, argv, "11", &pos, &ifnone);
+ block_given = rb_block_given_p();
+ if (block_given && argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
+ idx = NUM2LONG(pos);
- for (i=0; i<RARRAY(ary)->len; i++) {
- if (rb_equal(RARRAY(ary)->ptr[i], val))
- return INT2FIX(i);
+ if (idx < 0) {
+ idx += RARRAY_LEN(ary);
}
- return Qnil;
+ if (idx < 0 || RARRAY_LEN(ary) <= idx) {
+ if (block_given) return rb_yield(pos);
+ if (argc == 1) {
+ rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
+ idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
+ }
+ return ifnone;
+ }
+ return RARRAY_AREF(ary, idx);
}
+/*
+ * 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
+ *
+ * Returns the _index_ of the first object in +ary+ such that the object is
+ * <code>==</code> to +obj+.
+ *
+ * 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.
+ *
+ * See also Array#rindex.
+ *
+ * An Enumerator is returned if neither a block nor argument is given.
+ *
+ * a = [ "a", "b", "c" ]
+ * a.index("b") #=> 1
+ * a.index("z") #=> nil
+ * a.index { |x| x == "b" } #=> 1
+ */
+
static VALUE
-ary_rindex(ary, val)
- VALUE ary;
- VALUE val;
+rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
- int i = RARRAY(ary)->len;
+ VALUE val;
+ long i;
- while (i--) {
- if (rb_equal(RARRAY(ary)->ptr[i], val))
- return INT2FIX(i);
+ if (argc == 0) {
+ RETURN_ENUMERATOR(ary, 0, 0);
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+ return LONG2NUM(i);
+ }
+ }
+ return Qnil;
+ }
+ rb_check_arity(argc, 0, 1);
+ val = argv[0];
+ if (rb_block_given_p())
+ rb_warn("given block not used");
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ VALUE e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, val)) {
+ return LONG2NUM(i);
+ }
}
return Qnil;
}
+/*
+ * call-seq:
+ * ary.rindex(obj) -> int or nil
+ * ary.rindex { |item| block } -> int or nil
+ * ary.rindex -> Enumerator
+ *
+ * Returns the _index_ of the last object in +self+ <code>==</code> to +obj+.
+ *
+ * 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.
+ *
+ * Returns +nil+ if no match is found.
+ *
+ * See also Array#index.
+ *
+ * If neither block nor argument is given, an Enumerator is returned instead.
+ *
+ * a = [ "a", "b", "b", "b", "c" ]
+ * a.rindex("b") #=> 3
+ * a.rindex("z") #=> nil
+ * a.rindex { |x| x == "b" } #=> 3
+ */
+
static VALUE
-ary_indexes(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
{
- VALUE new_ary;
- int i;
+ VALUE val;
+ long i = RARRAY_LEN(ary), len;
- new_ary = ary_new2(argc);
- for (i=0; i<argc; i++) {
- ary_store(new_ary, i, ary_entry(ary, NUM2INT(argv[i])));
+ if (argc == 0) {
+ RETURN_ENUMERATOR(ary, 0, 0);
+ while (i--) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
+ return LONG2NUM(i);
+ if (i > (len = RARRAY_LEN(ary))) {
+ i = len;
+ }
+ }
+ return Qnil;
}
+ rb_check_arity(argc, 0, 1);
+ val = argv[0];
+ if (rb_block_given_p())
+ rb_warn("given block not used");
+ while (i--) {
+ VALUE e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, val)) {
+ return LONG2NUM(i);
+ }
+ }
+ return Qnil;
+}
- return new_ary;
+VALUE
+rb_ary_to_ary(VALUE obj)
+{
+ VALUE tmp = rb_check_array_type(obj);
+
+ if (!NIL_P(tmp)) return tmp;
+ return rb_ary_new3(1, obj);
}
static void
-ary_replace(ary, beg, len, rpl)
- VALUE ary, rpl;
- int beg, len;
+rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
{
- ary_modify(ary);
- if (TYPE(rpl) != T_ARRAY) {
- rpl = rb_Array(rpl);
- }
+ long olen;
+ long rofs;
+
+ if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
+ olen = RARRAY_LEN(ary);
if (beg < 0) {
- beg = RARRAY(ary)->len + beg;
- if (beg < 0) beg = 0;
+ beg += olen;
+ if (beg < 0) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ beg - olen, -olen);
+ }
+ }
+ if (olen < len || olen < beg + len) {
+ len = olen - beg;
+ }
+
+ {
+ const VALUE *optr = RARRAY_CONST_PTR(ary);
+ rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
}
- if (beg >= RARRAY(ary)->len) {
- len = beg + RARRAY(rpl)->len;
- if (len >= RARRAY(ary)->capa) {
- RARRAY(ary)->capa=len;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+
+ if (beg >= olen) {
+ VALUE target_ary;
+ if (beg > ARY_MAX_SIZE - rlen) {
+ rb_raise(rb_eIndexError, "index %ld too big", beg);
+ }
+ target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
+ len = beg + rlen;
+ ary_mem_clear(ary, olen, beg - olen);
+ if (rlen > 0) {
+ if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs;
+ ary_memcpy0(ary, beg, rlen, rptr, target_ary);
}
- memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len);
- MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, RARRAY(rpl)->len);
- RARRAY(ary)->len = len;
+ ARY_SET_LEN(ary, len);
}
else {
- int alen;
+ long alen;
- if (beg + len > RARRAY(ary)->len) {
- len = RARRAY(ary)->len - beg;
+ if (olen - len > ARY_MAX_SIZE - rlen) {
+ rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
}
- if (len < 0) {
- IndexError("negative length %d", RARRAY(ary)->len);
+ rb_ary_modify(ary);
+ alen = olen + rlen - len;
+ if (alen >= ARY_CAPA(ary)) {
+ ary_double_capa(ary, alen);
}
- alen = RARRAY(ary)->len + RARRAY(rpl)->len - len;
- if (alen >= RARRAY(ary)->capa) {
- RARRAY(ary)->capa=alen;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+ if (len != rlen) {
+ RARRAY_PTR_USE(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);
+ }
+ }
+}
+
+void
+rb_ary_set_len(VALUE ary, long len)
+{
+ long capa;
+
+ rb_ary_modify_check(ary);
+ if (ARY_SHARED_P(ary)) {
+ rb_raise(rb_eRuntimeError, "can't set length of shared ");
+ }
+ if (len > (capa = (long)ARY_CAPA(ary))) {
+ rb_bug("probable buffer overflow: %ld for %ld", len, capa);
+ }
+ ARY_SET_LEN(ary, len);
+}
+
+/*!
+ * expands or shrinks \a ary to \a len elements.
+ * expanded region will be filled with Qnil.
+ * \param ary an array
+ * \param len new size
+ * \return \a ary
+ * \post the size of \a ary is \a len.
+ */
+VALUE
+rb_ary_resize(VALUE ary, long len)
+{
+ long olen;
- if (len != RARRAY(rpl)->len) {
- MEMMOVE(RARRAY(ary)->ptr+beg+RARRAY(rpl)->len, RARRAY(ary)->ptr+beg+len,
- VALUE, RARRAY(ary)->len-(beg+len));
- RARRAY(ary)->len = alen;
+ rb_ary_modify(ary);
+ olen = RARRAY_LEN(ary);
+ if (len == olen) return ary;
+ if (len > ARY_MAX_SIZE) {
+ rb_raise(rb_eIndexError, "index %ld too big", len);
+ }
+ if (len > olen) {
+ if (len >= ARY_CAPA(ary)) {
+ ary_double_capa(ary, len);
+ }
+ ary_mem_clear(ary, olen, len - olen);
+ ARY_SET_LEN(ary, len);
+ }
+ else if (ARY_EMBED_P(ary)) {
+ ARY_SET_EMBED_LEN(ary, len);
+ }
+ else if (len <= RARRAY_EMBED_LEN_MAX) {
+ VALUE tmp[RARRAY_EMBED_LEN_MAX];
+ MEMCPY(tmp, ARY_HEAP_PTR(ary), VALUE, len);
+ ary_discard(ary);
+ MEMCPY((VALUE *)ARY_EMBED_PTR(ary), tmp, VALUE, len); /* WB: no new reference */
+ ARY_SET_EMBED_LEN(ary, 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_SET_CAPA(ary, len);
}
- MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, RARRAY(rpl)->len);
+ ARY_SET_HEAP_LEN(ary, len);
}
+ return ary;
}
+/*
+ * 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"]
+ */
+
static VALUE
-ary_aset(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
- VALUE arg1, arg2, arg3;
- int offset;
- int beg, len;
-
- if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) {
- beg = NUM2INT(arg1);
- len = NUM2INT(arg2);
- ary_replace(ary, beg, len, arg3);
- return arg3;
+ long offset, beg, len;
+ VALUE rpl;
+
+ if (argc == 3) {
+ rb_ary_modify_check(ary);
+ beg = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
+ goto range;
}
- else if (FIXNUM_P(arg1)) {
- offset = FIX2INT(arg1);
+ rb_check_arity(argc, 2, 2);
+ rb_ary_modify_check(ary);
+ if (FIXNUM_P(argv[0])) {
+ offset = FIX2LONG(argv[0]);
goto fixnum;
}
- else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
+ if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
/* check if idx is Range */
- ary_replace(ary, beg, len, arg2);
- return arg2;
- }
- if (TYPE(arg1) == T_BIGNUM) {
- IndexError("index too big");
+ 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];
}
- offset = NUM2INT(arg1);
- fixnum:
- if (offset < 0) {
- offset = RARRAY(ary)->len + offset;
+ offset = NUM2LONG(argv[0]);
+fixnum:
+ rb_ary_store(ary, offset, argv[1]);
+ return argv[1];
+}
+
+/*
+ * call-seq:
+ * ary.insert(index, obj...) -> ary
+ *
+ * Inserts the given values before the element with the given +index+.
+ *
+ * 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.
+ *
+ * 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"]
+ */
+
+static VALUE
+rb_ary_insert(int argc, VALUE *argv, VALUE ary)
+{
+ long pos;
+
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+ rb_ary_modify_check(ary);
+ pos = NUM2LONG(argv[0]);
+ if (argc == 1) return ary;
+ if (pos == -1) {
+ pos = RARRAY_LEN(ary);
+ }
+ else if (pos < 0) {
+ long minpos = -RARRAY_LEN(ary) - 1;
+ if (pos < minpos) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ pos, minpos);
+ }
+ pos++;
}
- ary_store(ary, offset, arg2);
- return arg2;
+ rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
+ return ary;
+}
+
+static VALUE
+rb_ary_length(VALUE ary);
+
+static VALUE
+ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
+{
+ return rb_ary_length(ary);
}
+/*
+ * call-seq:
+ * ary.each { |item| block } -> ary
+ * ary.each -> Enumerator
+ *
+ * Calls the given block once for each element in +self+, passing that element
+ * as a parameter. Returns the array itself.
+ *
+ * If no block is given, an Enumerator is returned.
+ *
+ * a = [ "a", "b", "c" ]
+ * a.each {|x| print x, " -- " }
+ *
+ * produces:
+ *
+ * a -- b -- c --
+ */
+
VALUE
-ary_each(ary)
- VALUE ary;
+rb_ary_each(VALUE ary)
{
- int i;
+ long i;
- for (i=0; i<RARRAY(ary)->len; i++) {
- rb_yield(RARRAY(ary)->ptr[i]);
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ rb_yield(RARRAY_AREF(ary, i));
}
- return Qnil;
+ return ary;
}
+/*
+ * call-seq:
+ * ary.each_index { |index| block } -> ary
+ * ary.each_index -> Enumerator
+ *
+ * Same as Array#each, but passes the +index+ of the element instead of the
+ * element itself.
+ *
+ * An Enumerator is returned if no block is given.
+ *
+ * a = [ "a", "b", "c" ]
+ * a.each_index {|x| print x, " -- " }
+ *
+ * produces:
+ *
+ * 0 -- 1 -- 2 --
+ */
+
static VALUE
-ary_each_index(ary)
- VALUE ary;
+rb_ary_each_index(VALUE ary)
{
- int i;
+ long i;
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
- for (i=0; i<RARRAY(ary)->len; i++) {
- rb_yield(INT2FIX(i));
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ rb_yield(LONG2NUM(i));
}
- return Qnil;
+ return 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
+ */
+
static VALUE
-ary_reverse_each(ary)
- VALUE ary;
+rb_ary_reverse_each(VALUE ary)
{
- int len = RARRAY(ary)->len;
+ long len;
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ len = RARRAY_LEN(ary);
while (len--) {
- rb_yield(RARRAY(ary)->ptr[len]);
+ long nlen;
+ rb_yield(RARRAY_AREF(ary, len));
+ nlen = RARRAY_LEN(ary);
+ if (nlen < len) {
+ len = nlen;
+ }
}
- return Qnil;
+ return ary;
}
+/*
+ * call-seq:
+ * ary.length -> int
+ *
+ * Returns the number of elements in +self+. May be zero.
+ *
+ * [ 1, 2, 3, 4, 5 ].length #=> 5
+ * [].length #=> 0
+ */
+
static VALUE
-ary_length(ary)
- VALUE ary;
+rb_ary_length(VALUE ary)
{
- return INT2FIX(RARRAY(ary)->len);
+ long len = RARRAY_LEN(ary);
+ return LONG2NUM(len);
}
+/*
+ * call-seq:
+ * ary.empty? -> true or false
+ *
+ * Returns +true+ if +self+ contains no elements.
+ *
+ * [].empty? #=> true
+ */
+
static VALUE
-ary_empty_p(ary)
- VALUE ary;
+rb_ary_empty_p(VALUE ary)
{
- if (RARRAY(ary)->len == 0)
- return TRUE;
- return FALSE;
+ if (RARRAY_LEN(ary) == 0)
+ return Qtrue;
+ return Qfalse;
}
-static VALUE
-ary_clone(ary)
- VALUE ary;
+VALUE
+rb_ary_dup(VALUE ary)
{
- VALUE ary2 = ary_new2(RARRAY(ary)->len);
+ long len = RARRAY_LEN(ary);
+ VALUE dup = rb_ary_new2(len);
+ ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary));
+ ARY_SET_LEN(dup, len);
+ return dup;
+}
- CLONESETUP(ary2, ary);
- MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
- RARRAY(ary2)->len = RARRAY(ary)->len;
- return ary2;
+VALUE
+rb_ary_resurrect(VALUE ary)
+{
+ return rb_ary_new4(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
}
+extern VALUE rb_output_fs;
+
+static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
+
static VALUE
-ary_dup(ary)
- VALUE ary;
+recursive_join(VALUE obj, VALUE argp, int recur)
{
- return ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
+ VALUE *arg = (VALUE *)argp;
+ VALUE ary = arg[0];
+ VALUE sep = arg[1];
+ VALUE result = arg[2];
+ int *first = (int *)arg[3];
+
+ if (recur) {
+ rb_raise(rb_eArgError, "recursive array join");
+ }
+ else {
+ ary_join_1(obj, ary, sep, 0, result, first);
+ }
+ return Qnil;
}
-static VALUE
-to_ary(ary)
- VALUE ary;
+static void
+ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
{
- return rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
+ long i;
+ VALUE val;
+
+ if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
+ for (i=0; i<max; i++) {
+ val = RARRAY_AREF(ary, i);
+ 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);
+ }
}
-extern VALUE OFS;
+static void
+ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
+{
+ VALUE val, tmp;
+
+ for (; i<RARRAY_LEN(ary); i++) {
+ if (i > 0 && !NIL_P(sep))
+ rb_str_buf_append(result, sep);
+
+ 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;
+ }
+ }
+ 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);
+ }
+ }
+ 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;
+ }
+ }
+}
VALUE
-ary_join(ary, sep)
- VALUE ary;
- VALUE sep;
+rb_ary_join(VALUE ary, VALUE sep)
{
- int i;
- VALUE result, tmp;
- if (RARRAY(ary)->len == 0) return str_new(0, 0);
+ long len = 1, i;
+ int taint = FALSE;
+ VALUE val, tmp, result;
- switch (TYPE(RARRAY(ary)->ptr[0])) {
- case T_STRING:
- result = str_dup(RARRAY(ary)->ptr[0]);
- break;
- case T_ARRAY:
- result = ary_join(RARRAY(ary)->ptr[0], sep);
- break;
- default:
- result = obj_as_string(RARRAY(ary)->ptr[0]);
- break;
- }
+ if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
+ if (OBJ_TAINTED(ary)) taint = TRUE;
- for (i=1; i<RARRAY(ary)->len; i++) {
- tmp = RARRAY(ary)->ptr[i];
- switch (TYPE(tmp)) {
- case T_STRING:
- break;
- case T_ARRAY:
- tmp = ary_join(tmp, sep);
- break;
- default:
- tmp = obj_as_string(tmp);
+ if (!NIL_P(sep)) {
+ StringValue(sep);
+ len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
+ }
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ val = RARRAY_AREF(ary, i);
+ tmp = rb_check_string_type(val);
+
+ if (NIL_P(tmp) || tmp != val) {
+ int first;
+ result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
+ rb_enc_associate(result, rb_usascii_encoding());
+ if (taint) OBJ_TAINT(result);
+ ary_join_0(ary, sep, i, result);
+ first = i == 0;
+ ary_join_1(ary, ary, sep, i, result, &first);
+ return result;
}
- if (!NIL_P(sep)) str_concat(result, sep);
- str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
- if (str_tainted(tmp)) str_taint(result);
+
+ len += RSTRING_LEN(tmp);
}
+ result = rb_str_buf_new(len);
+ if (taint) OBJ_TAINT(result);
+ ary_join_0(ary, sep, RARRAY_LEN(ary), result);
+
return result;
}
+/*
+ * 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"
+ */
+
static VALUE
-ary_join_method(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
{
VALUE sep;
rb_scan_args(argc, argv, "01", &sep);
- if (NIL_P(sep)) sep = OFS;
+ if (NIL_P(sep)) sep = rb_output_fs;
- return ary_join(ary, sep);
+ return rb_ary_join(ary, sep);
}
-VALUE
-ary_to_s(ary)
- VALUE ary;
+static VALUE
+inspect_ary(VALUE ary, VALUE dummy, int recur)
{
- VALUE str = ary_join(ary, OFS);
- if (NIL_P(str)) return str_new(0, 0);
+ int tainted = OBJ_TAINTED(ary);
+ long i;
+ VALUE s, str;
+
+ if (recur) return rb_usascii_str_new_cstr("[...]");
+ 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
+ *
+ * Creates a string representation of +self+.
+ *
+ * [ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
+ */
+
static VALUE
-ary_inspect(ary)
- VALUE ary;
+rb_ary_inspect(VALUE ary)
{
- int i, len;
- VALUE s, str;
+ if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
+ return rb_exec_recursive(inspect_ary, ary, 0);
+}
+
+VALUE
+rb_ary_to_s(VALUE ary)
+{
+ return rb_ary_inspect(ary);
+}
- if (RARRAY(ary)->len == 0) return str_new2("[]");
- str = str_new2("[");
- len = 1;
+/*
+ * call-seq:
+ * ary.to_a -> ary
+ *
+ * Returns +self+.
+ *
+ * If called on a subclass of Array, converts the receiver to an Array object.
+ */
- for (i=0; i<RARRAY(ary)->len; i++) {
- s = rb_inspect(RARRAY(ary)->ptr[i]);
- if (i > 0) str_cat(str, ", ", 2);
- str_cat(str, RSTRING(s)->ptr, RSTRING(s)->len);
- len += RSTRING(s)->len + 2;
+static VALUE
+rb_ary_to_a(VALUE ary)
+{
+ if (rb_obj_class(ary) != rb_cArray) {
+ VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
+ rb_ary_replace(dup, ary);
+ return dup;
}
- str_cat(str, "]", 1);
+ return ary;
+}
- return str;
+/*
+ * 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}
+ */
+
+static VALUE
+rb_ary_to_h(VALUE ary)
+{
+ long i;
+ VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ const VALUE elt = rb_ary_elt(ary, i);
+ 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)",
+ rb_obj_class(elt), i);
+ }
+ if (RARRAY_LEN(key_value_pair) != 2) {
+ rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
+ i, RARRAY_LEN(key_value_pair));
+ }
+ rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
+ }
+ return hash;
}
+/*
+ * call-seq:
+ * ary.to_ary -> ary
+ *
+ * Returns +self+.
+ */
+
static VALUE
-ary_to_a(ary)
- VALUE ary;
+rb_ary_to_ary_m(VALUE ary)
{
return ary;
}
+static void
+ary_reverse(VALUE *p1, VALUE *p2)
+{
+ while (p1 < p2) {
+ VALUE tmp = *p1;
+ *p1++ = *p2;
+ *p2-- = tmp;
+ }
+}
+
VALUE
-ary_reverse(ary)
- VALUE ary;
+rb_ary_reverse(VALUE ary)
{
- VALUE *p1, *p2;
- VALUE tmp;
+ VALUE *p2;
+ long len = RARRAY_LEN(ary);
+
+ rb_ary_modify(ary);
+ if (len > 1) {
+ RARRAY_PTR_USE(ary, p1, {
+ p2 = p1 + len - 1; /* points last item */
+ ary_reverse(p1, p2);
+ }); /* WB: no new reference */
+ }
+ return ary;
+}
+
+/*
+ * call-seq:
+ * ary.reverse! -> ary
+ *
+ * Reverses +self+ in place.
+ *
+ * a = [ "a", "b", "c" ]
+ * a.reverse! #=> ["c", "b", "a"]
+ * a #=> ["c", "b", "a"]
+ */
- if (RARRAY(ary)->len == 0) return ary;
+static VALUE
+rb_ary_reverse_bang(VALUE ary)
+{
+ return rb_ary_reverse(ary);
+}
- p1 = RARRAY(ary)->ptr;
- p2 = p1 + RARRAY(ary)->len - 1; /* points last item */
+/*
+ * call-seq:
+ * ary.reverse -> new_ary
+ *
+ * Returns a new array containing +self+'s elements in reverse order.
+ *
+ * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
+ * [ 1 ].reverse #=> [1]
+ */
- while (p1 < p2) {
- tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- p1++; p2--;
+static VALUE
+rb_ary_reverse_m(VALUE ary)
+{
+ long len = RARRAY_LEN(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;
+ do *p2-- = *p1++; while (--len > 0);
+ }
+ ARY_SET_LEN(dup, RARRAY_LEN(ary));
+ return dup;
+}
+
+static inline long
+rotate_count(long cnt, long len)
+{
+ return (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % 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;
+ }
}
+ 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"]
+ */
+
+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);
+ }
+ 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"]
+ */
+
static VALUE
-ary_reverse_method(ary)
- VALUE ary;
+rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
{
- return ary_reverse(ary_dup(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);
+ }
+
+ len = RARRAY_LEN(ary);
+ rotated = rb_ary_new2(len);
+ if (len > 0) {
+ cnt = rotate_count(cnt, len);
+ ptr = RARRAY_CONST_PTR(ary);
+ len -= cnt;
+ ary_memcpy(rotated, 0, len, ptr + cnt);
+ ary_memcpy(rotated, len, cnt, ptr);
+ }
+ ARY_SET_LEN(rotated, RARRAY_LEN(ary));
+ return rotated;
}
-static ID cmp;
+struct ary_sort_data {
+ VALUE ary;
+ struct cmp_opt_data cmp_opt;
+};
+
+static VALUE
+sort_reentered(VALUE ary)
+{
+ if (RBASIC(ary)->klass) {
+ rb_raise(rb_eRuntimeError, "sort reentered");
+ }
+ return Qnil;
+}
static int
-sort_1(a, b)
- VALUE *a, *b;
+sort_1(const void *ap, const void *bp, void *dummy)
{
- VALUE retval = rb_yield(assoc_new(*a, *b));
- return NUM2INT(retval);
+ struct ary_sort_data *data = dummy;
+ VALUE retval = sort_reentered(data->ary);
+ VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
+ VALUE args[2];
+ int n;
+
+ args[0] = a;
+ args[1] = b;
+ retval = rb_yield_values2(2, args);
+ n = rb_cmpint(retval, a, b);
+ sort_reentered(data->ary);
+ return n;
}
static int
-sort_2(a, b)
- VALUE *a, *b;
+sort_2(const void *ap, const void *bp, void *dummy)
{
- VALUE retval;
+ struct ary_sort_data *data = dummy;
+ VALUE retval = sort_reentered(data->ary);
+ VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
+ int n;
- if (FIXNUM_P(*a)) {
- if (FIXNUM_P(*b)) return *a - *b;
+ if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, Fixnum)) {
+ if ((long)a > (long)b) return 1;
+ if ((long)a < (long)b) return -1;
+ return 0;
+ }
+ if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, String)) {
+ return rb_str_cmp(a, b);
}
- else if (TYPE(*a) == T_STRING) {
- if (TYPE(*b) == T_STRING) return str_cmp(*a, *b);
+ if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(data->cmp_opt, Float)) {
+ return rb_float_cmp(a, b);
}
- retval = rb_funcall(*a, cmp, 1, *b);
- return NUM2INT(retval);
+ retval = rb_funcallv(a, id_cmp, 1, &b);
+ n = rb_cmpint(retval, a, b);
+ sort_reentered(data->ary);
+
+ return n;
}
+/*
+ * 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.
+ */
+
VALUE
-ary_sort_bang(ary)
- VALUE ary;
+rb_ary_sort_bang(VALUE ary)
+{
+ rb_ary_modify(ary);
+ assert(!ARY_SHARED_P(ary));
+ if (RARRAY_LEN(ary) > 1) {
+ 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);
+ }); /* WB: no new reference */
+ rb_ary_modify(ary);
+ if (ARY_EMBED_P(tmp)) {
+ if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
+ rb_ary_unshare(ary);
+ FL_SET_EMBED(ary);
+ }
+ ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
+ ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
+ }
+ else {
+ if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
+ FL_UNSET_SHARED(ary);
+ ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
+ }
+ else {
+ assert(!ARY_SHARED_P(tmp));
+ if (ARY_EMBED_P(ary)) {
+ FL_UNSET_EMBED(ary);
+ }
+ else if (ARY_SHARED_P(ary)) {
+ /* ary might be destructively operated in the given block */
+ rb_ary_unshare(ary);
+ }
+ else {
+ ruby_sized_xfree((void *)ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
+ }
+ ARY_SET_PTR(ary, RARRAY_CONST_PTR(tmp));
+ ARY_SET_HEAP_LEN(ary, len);
+ ARY_SET_CAPA(ary, RARRAY_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 */
+ }
+ 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.
+ */
+
+VALUE
+rb_ary_sort(VALUE ary)
+{
+ ary = rb_ary_dup(ary);
+ rb_ary_sort_bang(ary);
+ return ary;
+}
+
+static VALUE rb_ary_bsearch_index(VALUE ary);
+
+/*
+ * call-seq:
+ * ary.bsearch {|x| block } -> elem
+ *
+ * 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.
+ */
+
+static VALUE
+rb_ary_bsearch(VALUE ary)
+{
+ VALUE index_result = rb_ary_bsearch_index(ary);
+
+ if (FIXNUM_P(index_result)) {
+ return rb_ary_entry(ary, FIX2LONG(index_result));
+ }
+ return index_result;
+}
+
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+static VALUE
+rb_ary_bsearch_index(VALUE ary)
+{
+ long low = 0, high = RARRAY_LEN(ary), mid;
+ int smaller = 0, satisfied = 0;
+ VALUE v, val;
+
+ RETURN_ENUMERATOR(ary, 0, 0);
+ while (low < high) {
+ mid = low + ((high - low) / 2);
+ val = rb_ary_entry(ary, mid);
+ v = rb_yield(val);
+ if (FIXNUM_P(v)) {
+ if (v == INT2FIX(0)) return INT2FIX(mid);
+ smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
+ }
+ else if (v == Qtrue) {
+ satisfied = 1;
+ smaller = 1;
+ }
+ else if (v == Qfalse || v == Qnil) {
+ smaller = 0;
+ }
+ else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
+ const VALUE zero = INT2FIX(0);
+ switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
+ case 0: return INT2FIX(mid);
+ case 1: smaller = 1; break;
+ case -1: smaller = 0;
+ }
+ }
+ else {
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
+ " (must be numeric, true, false or nil)",
+ rb_obj_class(v));
+ }
+ if (smaller) {
+ high = mid;
+ }
+ else {
+ low = mid + 1;
+ }
+ }
+ if (!satisfied) return Qnil;
+ return INT2FIX(low);
+}
+
+
+static VALUE
+sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
+{
+ return rb_yield(i);
+}
+
+/*
+ * call-seq:
+ * ary.sort_by! { |obj| block } -> ary
+ * ary.sort_by! -> Enumerator
+ *
+ * Sorts +self+ in place using a set of keys generated by mapping the
+ * values in +self+ through the given block.
+ *
+ * The result is not guaranteed to be stable. When two keys are equal,
+ * the order of the corresponding elements is unpredictable.
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ * See also Enumerable#sort_by.
+ */
+
+static VALUE
+rb_ary_sort_by_bang(VALUE ary)
+{
+ VALUE sorted;
+
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rb_ary_modify(ary);
+ sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
+ rb_ary_replace(ary, sorted);
+ return 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+.
+ *
+ * Creates a new array containing the values returned by the block.
+ *
+ * See also Enumerable#collect.
+ *
+ * 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"]
+ */
+
+static VALUE
+rb_ary_collect(VALUE ary)
+{
+ long i;
+ VALUE collect;
+
+ 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_force_blockarg(RARRAY_AREF(ary, i)));
+ }
+ return collect;
+}
+
+
+/*
+ * 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.
+ *
+ * See also Enumerable#collect.
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ * 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!"]
+ */
+
+static VALUE
+rb_ary_collect_bang(VALUE ary)
{
- if (RARRAY(ary)->len == 0) return ary;
+ long i;
- ary_modify(ary);
- qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
- iterator_p()?sort_1:sort_2);
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rb_ary_modify(ary);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
+ }
return ary;
}
VALUE
-ary_sort(ary)
+rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func) (VALUE, long))
+{
+ VALUE result = rb_ary_new2(argc);
+ long beg, len, i, j;
+
+ for (i=0; i<argc; i++) {
+ if (FIXNUM_P(argv[i])) {
+ rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
+ continue;
+ }
+ /* check if idx is Range */
+ if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
+ long end = olen < beg+len ? olen : beg+len;
+ for (j = beg; j < end; j++) {
+ rb_ary_push(result, (*func)(obj, j));
+ }
+ if (beg + len > j)
+ rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
+ continue;
+ }
+ rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
+ }
+ return result;
+}
+
+/*
+ * call-seq:
+ * ary.values_at(selector, ...) -> new_ary
+ *
+ * Returns an array containing the elements in +self+ corresponding to the
+ * given +selector+(s).
+ *
+ * The selectors may be either integer indices or ranges.
+ *
+ * See also Array#select.
+ *
+ * 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"]
+ */
+
+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);
+}
+
+
+/*
+ * call-seq:
+ * ary.select { |item| block } -> new_ary
+ * ary.select -> Enumerator
+ *
+ * Returns a new array containing all elements of +ary+
+ * for which the given +block+ returns a true value.
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ * [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.
+ */
+
+static VALUE
+rb_ary_select(VALUE ary)
+{
+ VALUE result;
+ long i;
+
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ result = rb_ary_new2(RARRAY_LEN(ary));
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+ rb_ary_push(result, rb_ary_elt(ary, i));
+ }
+ }
+ return result;
+}
+
+struct select_bang_arg {
VALUE ary;
+ long len[2];
+};
+
+static VALUE
+select_bang_i(VALUE a)
{
- if (RARRAY(ary)->len == 0) return ary;
- return ary_sort_bang(ary_dup(ary));
+ volatile struct select_bang_arg *arg = (void *)a;
+ VALUE ary = arg->ary;
+ long i1, i2;
+
+ for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
+ VALUE v = RARRAY_AREF(ary, i1);
+ if (!RTEST(rb_yield(v))) continue;
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, v);
+ }
+ arg->len[1] = ++i2;
+ }
+ return (i1 == i2) ? Qnil : ary;
}
+static VALUE
+select_bang_ensure(VALUE a)
+{
+ volatile struct select_bang_arg *arg = (void *)a;
+ VALUE ary = arg->ary;
+ long len = RARRAY_LEN(ary);
+ long i1 = arg->len[0], i2 = arg->len[1];
+
+ if (i2 < len && i2 < i1) {
+ long tail = 0;
+ if (i1 < len) {
+ tail = len - i1;
+ RARRAY_PTR_USE(ary, ptr, {
+ MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
+ });
+ }
+ ARY_SET_LEN(ary, i2 + tail);
+ }
+ return ary;
+}
+
+/*
+ * call-seq:
+ * ary.select! {|item| block } -> ary or nil
+ * ary.select! -> Enumerator
+ *
+ * Invokes the given block passing in successive elements from +self+,
+ * deleting elements for which the block returns a +false+ value.
+ *
+ * The array may not be changed instantly every time the block is called.
+ *
+ * If changes were made, it will return +self+, otherwise it returns +nil+.
+ *
+ * See also Array#keep_if
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ */
+
+static VALUE
+rb_ary_select_bang(VALUE ary)
+{
+ struct select_bang_arg args;
+
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rb_ary_modify(ary);
+
+ args.ary = ary;
+ args.len[0] = args.len[1] = 0;
+ return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
+}
+
+/*
+ * 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+.
+ *
+ * See also Array#select!
+ *
+ * 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"]
+ */
+
+static VALUE
+rb_ary_keep_if(VALUE ary)
+{
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rb_ary_select_bang(ary);
+ return ary;
+}
+
+static void
+ary_resize_smaller(VALUE ary, long len)
+{
+ rb_ary_modify(ary);
+ if (RARRAY_LEN(ary) > len) {
+ ARY_SET_LEN(ary, len);
+ if (len * 2 < ARY_CAPA(ary) &&
+ ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
+ ary_resize_capa(ary, len * 2);
+ }
+ }
+}
+
+/*
+ * 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"
+ */
+
VALUE
-ary_delete(ary, item)
- VALUE ary;
- VALUE item;
+rb_ary_delete(VALUE ary, VALUE item)
{
- int i1, i2;
+ VALUE v = item;
+ long i1, i2;
- ary_modify(ary);
- for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
- if (rb_equal(RARRAY(ary)->ptr[i1], item)) continue;
+ for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
+ VALUE e = RARRAY_AREF(ary, i1);
+
+ if (rb_equal(e, item)) {
+ v = e;
+ continue;
+ }
if (i1 != i2) {
- RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
+ rb_ary_store(ary, i2, e);
}
i2++;
}
- if (RARRAY(ary)->len == i2) {
- if (iterator_p()) {
+ if (RARRAY_LEN(ary) == i2) {
+ if (rb_block_given_p()) {
return rb_yield(item);
}
return Qnil;
}
- else {
- RARRAY(ary)->len = i2;
- }
- return item;
+ ary_resize_smaller(ary, i2);
+
+ return v;
}
-VALUE
-ary_delete_at(ary, at)
- VALUE ary;
- VALUE at;
+void
+rb_ary_delete_same(VALUE ary, VALUE item)
{
- int i1, i2, pos;
- VALUE del = Qnil;
+ long i1, i2;
- ary_modify(ary);
- pos = NUM2INT(at);
- for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
- if (i1 == pos) {
- del = RARRAY(ary)->ptr[i1];
+ for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
+ VALUE e = RARRAY_AREF(ary, i1);
+
+ if (e == item) {
continue;
}
if (i1 != i2) {
- RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
+ rb_ary_store(ary, i2, e);
}
i2++;
}
- RARRAY(ary)->len = i2;
+ if (RARRAY_LEN(ary) == i2) {
+ return;
+ }
+
+ ary_resize_smaller(ary, i2);
+}
+
+VALUE
+rb_ary_delete_at(VALUE ary, long pos)
+{
+ long len = RARRAY_LEN(ary);
+ VALUE del;
+
+ if (pos >= len) return Qnil;
+ if (pos < 0) {
+ pos += len;
+ if (pos < 0) return Qnil;
+ }
+
+ rb_ary_modify(ary);
+ del = RARRAY_AREF(ary, pos);
+ RARRAY_PTR_USE(ary, ptr, {
+ MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
+ });
+ ARY_INCREASE_LEN(ary, -1);
return del;
}
+/*
+ * call-seq:
+ * ary.delete_at(index) -> obj or nil
+ *
+ * Deletes the element at the specified +index+, returning that element, or
+ * +nil+ if the +index+ is out of range.
+ *
+ * See also Array#slice!
+ *
+ * a = ["ant", "bat", "cat", "dog"]
+ * a.delete_at(2) #=> "cat"
+ * a #=> ["ant", "bat", "dog"]
+ * a.delete_at(99) #=> nil
+ */
+
static VALUE
-ary_delete_if(ary)
- VALUE ary;
+rb_ary_delete_at_m(VALUE ary, VALUE pos)
{
- int i1, i2;
+ return rb_ary_delete_at(ary, NUM2LONG(pos));
+}
- ary_modify(ary);
- for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
- if (rb_yield(RARRAY(ary)->ptr[i1])) continue;
- if (i1 != i2) {
- RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
+/*
+ * 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"]
+ */
+
+static VALUE
+rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
+{
+ VALUE arg1, arg2;
+ long pos, len, orig_len;
+
+ rb_ary_modify_check(ary);
+ 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;
}
- i2++;
+ 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;
}
- RARRAY(ary)->len = i2;
- return ary;
+ if (argc != 1) {
+ /* error report */
+ rb_scan_args(argc, argv, "11", NULL, NULL);
+ }
+ 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;
+ case Qnil:
+ /* invalid range */
+ return Qnil;
+ default:
+ /* not a range */
+ break;
+ }
+ }
+
+ return rb_ary_delete_at(ary, NUM2LONG(arg1));
}
static VALUE
-ary_filter(ary)
- VALUE ary;
+ary_reject(VALUE orig, VALUE result)
{
- int i;
+ long i;
- ary_modify(ary);
- for (i = 0; i < RARRAY(ary)->len; i++) {
- RARRAY(ary)->ptr[i] = rb_yield(RARRAY(ary)->ptr[i]);
+ for (i = 0; i < RARRAY_LEN(orig); i++) {
+ VALUE v = RARRAY_AREF(orig, i);
+ if (!RTEST(rb_yield(v))) {
+ rb_ary_push(result, v);
+ }
}
- return ary;
+ return result;
}
static VALUE
-ary_replace_method(ary, ary2)
- VALUE ary, ary2;
+reject_bang_i(VALUE a)
{
- ary2 = to_ary(ary2);
- ary_replace(ary, 0, RARRAY(ary2)->len, ary2);
+ volatile struct select_bang_arg *arg = (void *)a;
+ VALUE ary = arg->ary;
+ long i1, i2;
+
+ for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
+ VALUE v = RARRAY_AREF(ary, i1);
+ if (RTEST(rb_yield(v))) continue;
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, v);
+ }
+ arg->len[1] = ++i2;
+ }
+ return (i1 == i2) ? Qnil : ary;
+}
+
+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;
+ return rb_ensure(reject_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
+}
+
+/*
+ * call-seq:
+ * ary.reject! { |item| block } -> ary or nil
+ * ary.reject! -> Enumerator
+ *
+ * Deletes every element of +self+ for which the block evaluates to +true+,
+ * if no changes were made returns +nil+.
+ *
+ * The array may not be changed instantly every time the block is called.
+ *
+ * See also Enumerable#reject and Array#delete_if.
+ *
+ * If no block is given, an Enumerator is returned instead.
+ */
+
+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.
+ */
+
+static VALUE
+rb_ary_reject(VALUE ary)
+{
+ VALUE rejected_ary;
+
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ rejected_ary = rb_ary_new();
+ ary_reject(ary, rejected_ary);
+ return rejected_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!
+ *
+ * If no block is given, an Enumerator is returned instead.
+ *
+ * scores = [ 97, 42, 75 ]
+ * scores.delete_if {|score| score < 80 } #=> [97]
+ */
+
+static VALUE
+rb_ary_delete_if(VALUE ary)
+{
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+ ary_reject_bang(ary);
return ary;
}
static VALUE
-ary_clear(ary)
- VALUE ary;
+take_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, cbarg))
+{
+ VALUE *args = (VALUE *)cbarg;
+ if (args[1]-- == 0) rb_iter_break();
+ if (argc > 1) val = rb_ary_new4(argc, argv);
+ rb_ary_push(args[0], val);
+ return Qnil;
+}
+
+static VALUE
+take_items(VALUE obj, long n)
+{
+ VALUE result = rb_check_array_type(obj);
+ VALUE args[2];
+
+ if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
+ result = rb_ary_new2(n);
+ args[0] = result; args[1] = (VALUE)n;
+ if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
+ rb_obj_class(obj));
+ return result;
+}
+
+
+/*
+ * 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]]
+ */
+
+static VALUE
+rb_ary_zip(int argc, VALUE *argv, VALUE ary)
+{
+ int i, j;
+ long len = RARRAY_LEN(ary);
+ VALUE result = Qnil;
+
+ for (i=0; i<argc; i++) {
+ argv[i] = take_items(argv[i], len);
+ }
+
+ if (rb_block_given_p()) {
+ int arity = rb_block_arity();
+
+ if (arity > 1) {
+ VALUE work, *tmp;
+
+ tmp = ALLOCV_N(VALUE, work, argc+1);
+
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ tmp[0] = RARRAY_AREF(ary, i);
+ for (j=0; j<argc; j++) {
+ tmp[j+1] = rb_ary_elt(argv[j], i);
+ }
+ rb_yield_values2(argc+1, tmp);
+ }
+
+ if (work) ALLOCV_END(work);
+ }
+ else {
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ VALUE tmp = rb_ary_new2(argc+1);
+
+ rb_ary_push(tmp, RARRAY_AREF(ary, i));
+ for (j=0; j<argc; j++) {
+ rb_ary_push(tmp, rb_ary_elt(argv[j], i));
+ }
+ rb_yield(tmp);
+ }
+ }
+ }
+ else {
+ result = rb_ary_new_capa(len);
+
+ for (i=0; i<len; i++) {
+ VALUE tmp = rb_ary_new_capa(argc+1);
+
+ rb_ary_push(tmp, RARRAY_AREF(ary, i));
+ for (j=0; j<argc; j++) {
+ rb_ary_push(tmp, rb_ary_elt(argv[j], i));
+ }
+ rb_ary_push(result, tmp);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * call-seq:
+ * ary.transpose -> new_ary
+ *
+ * Assumes that +self+ is an array of arrays and transposes the rows and
+ * columns.
+ *
+ * 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.
+ */
+
+static VALUE
+rb_ary_transpose(VALUE ary)
+{
+ long elen = -1, alen, i, j;
+ VALUE tmp, result = 0;
+
+ alen = RARRAY_LEN(ary);
+ if (alen == 0) return rb_ary_dup(ary);
+ for (i=0; i<alen; i++) {
+ tmp = to_ary(rb_ary_elt(ary, i));
+ if (elen < 0) { /* first element */
+ elen = RARRAY_LEN(tmp);
+ result = rb_ary_new2(elen);
+ for (j=0; j<elen; j++) {
+ rb_ary_store(result, j, rb_ary_new2(alen));
+ }
+ }
+ else if (elen != RARRAY_LEN(tmp)) {
+ rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
+ RARRAY_LEN(tmp), elen);
+ }
+ for (j=0; j<elen; j++) {
+ rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
+ }
+ }
+ return result;
+}
+
+/*
+ * 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.
+ *
+ * a = [ "a", "b", "c", "d", "e" ]
+ * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
+ * a #=> ["x", "y", "z"]
+ */
+
+VALUE
+rb_ary_replace(VALUE copy, VALUE orig)
+{
+ rb_ary_modify_check(copy);
+ orig = to_ary(orig);
+ if (copy == orig) return copy;
+
+ if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
+ VALUE shared = 0;
+
+ if (ARY_OWNS_HEAP_P(copy)) {
+ RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(copy)));
+ }
+ else if (ARY_SHARED_P(copy)) {
+ shared = ARY_SHARED(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_SET_LEN(copy, RARRAY_LEN(orig));
+ }
+ else {
+ VALUE shared = ary_make_shared(orig);
+ if (ARY_OWNS_HEAP_P(copy)) {
+ RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(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);
+ }
+ return copy;
+}
+
+/*
+ * call-seq:
+ * ary.clear -> ary
+ *
+ * Removes all elements from +self+.
+ *
+ * a = [ "a", "b", "c", "d", "e" ]
+ * a.clear #=> [ ]
+ */
+
+VALUE
+rb_ary_clear(VALUE ary)
{
- RARRAY(ary)->len = 0;
- if (ARY_DEFAULT_SIZE*3 < RARRAY(ary)->capa) {
- RARRAY(ary)->capa = ARY_DEFAULT_SIZE * 2;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+ 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);
+ }
+ }
+ else if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
+ ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
}
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]
+ */
+
static VALUE
-ary_fill(argc, argv, ary)
- int argc;
- VALUE *argv;
- VALUE ary;
+rb_ary_fill(int argc, VALUE *argv, VALUE ary)
{
- VALUE item, arg1, arg2;
- int beg, len, end;
- VALUE *p, *pend;
+ VALUE item = Qundef, arg1, arg2;
+ long beg = 0, end = 0, len = 0;
- if (rb_scan_args(argc, argv, "12", &item, &arg1, &arg2) == 2 &&
- beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
- /* beg and len set already */
+ if (rb_block_given_p()) {
+ rb_scan_args(argc, argv, "02", &arg1, &arg2);
+ argc += 1; /* hackish */
}
else {
- beg = NIL_P(arg1)?0:NUM2INT(arg1);
+ rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
+ }
+ switch (argc) {
+ case 1:
+ beg = 0;
+ len = RARRAY_LEN(ary);
+ break;
+ case 2:
+ if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
+ break;
+ }
+ /* fall through */
+ case 3:
+ beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
if (beg < 0) {
- beg = RARRAY(ary)->len + beg;
+ beg = RARRAY_LEN(ary) + beg;
if (beg < 0) beg = 0;
}
- len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2INT(arg2);
+ len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
+ break;
+ }
+ rb_ary_modify(ary);
+ if (len < 0) {
+ return ary;
+ }
+ if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
+ rb_raise(rb_eArgError, "argument too big");
}
end = beg + len;
- if (end > RARRAY(ary)->len) {
- if (end >= RARRAY(ary)->capa) {
- RARRAY(ary)->capa=end;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
+ if (RARRAY_LEN(ary) < end) {
+ if (end >= ARY_CAPA(ary)) {
+ ary_resize_capa(ary, end);
}
- if (beg > RARRAY(ary)->len) {
- memclear(RARRAY(ary)->ptr+RARRAY(ary)->len,end-RARRAY(ary)->len);
- }
- RARRAY(ary)->len = end;
+ ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
+ ARY_SET_LEN(ary, end);
}
- p = RARRAY(ary)->ptr + beg; pend = p + len;
- while (p < pend) {
- *p++ = item;
+ if (item == Qundef) {
+ VALUE v;
+ long i;
+
+ for (i=beg; i<end; i++) {
+ v = rb_yield(LONG2NUM(i));
+ if (i>=RARRAY_LEN(ary)) break;
+ ARY_SET(ary, i, v);
+ }
+ }
+ else {
+ ary_memfill(ary, beg, len, item);
}
return 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" ]
+ *
+ * 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.
+ *
+ * See also Array#concat.
+ */
+
VALUE
-ary_plus(x, y)
- VALUE x, y;
+rb_ary_plus(VALUE x, VALUE y)
{
VALUE z;
+ long len, xlen, ylen;
- if (TYPE(y) != T_ARRAY) {
- return ary_plus(x, rb_Array(y));
- }
+ y = to_ary(y);
+ xlen = RARRAY_LEN(x);
+ ylen = RARRAY_LEN(y);
+ len = xlen + ylen;
+ z = rb_ary_new2(len);
- z = ary_new2(RARRAY(x)->len + RARRAY(y)->len);
- MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len);
- MEMCPY(RARRAY(z)->ptr+RARRAY(x)->len, RARRAY(y)->ptr, VALUE, RARRAY(y)->len);
- RARRAY(z)->len = RARRAY(x)->len + RARRAY(y)->len;
+ ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
+ ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
+ ARY_SET_LEN(z, len);
return z;
}
-VALUE
-ary_concat(x, y)
- VALUE x, y;
+static VALUE
+ary_append(VALUE x, VALUE y)
{
- VALUE *p, *pend;
-
- if (TYPE(y) != T_ARRAY) {
- return ary_concat(x, rb_Array(y));
+ long n = RARRAY_LEN(y);
+ if (n > 0) {
+ rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR(y), n);
}
+ return x;
+}
+
+/*
+ * call-seq:
+ * ary.concat(other_ary1, other_ary2,...) -> ary
+ *
+ * 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#+.
+ */
+
+static VALUE
+rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
+{
+ rb_ary_modify_check(ary);
- p = RARRAY(y)->ptr;
- pend = p + RARRAY(y)->len;
- while (p < pend) {
- ary_store(x, RARRAY(x)->len, *p);
- p++;
+ if (argc == 1) {
+ rb_ary_concat(ary, argv[0]);
}
- return x;
+ else if (argc > 1) {
+ int i;
+ VALUE args = rb_ary_tmp_new(argc);
+ for (i = 0; i < argc; i++) {
+ rb_ary_concat(args, argv[i]);
+ }
+ ary_append(ary, args);
+ }
+
+ return ary;
+}
+
+VALUE
+rb_ary_concat(VALUE x, VALUE y)
+{
+ return ary_append(x, to_ary(y));
}
+/*
+ * call-seq:
+ * ary * int -> new_ary
+ * ary * str -> 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"
+ *
+ */
+
static VALUE
-ary_times(ary, times)
- VALUE ary;
- VALUE times;
+rb_ary_times(VALUE ary, VALUE times)
{
- VALUE ary2;
- int i, len;
+ VALUE ary2, tmp;
+ const VALUE *ptr;
+ long t, len;
- if (TYPE(times) == T_STRING) {
- return ary_join(ary, times);
+ tmp = rb_check_string_type(times);
+ if (!NIL_P(tmp)) {
+ return rb_ary_join(ary, tmp);
}
- len = NUM2INT(times);
+ len = NUM2LONG(times);
+ if (len == 0) {
+ ary2 = ary_new(rb_obj_class(ary), 0);
+ goto out;
+ }
if (len < 0) {
- ArgError("negative argument");
+ rb_raise(rb_eArgError, "negative argument");
}
- len *= RARRAY(ary)->len;
-
- ary2 = ary_new2(len);
- RARRAY(ary2)->len = len;
-
- for (i=0; i<len; i+=RARRAY(ary)->len) {
- MEMCPY(RARRAY(ary2)->ptr+i, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
+ if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
+ rb_raise(rb_eArgError, "argument too big");
+ }
+ len *= RARRAY_LEN(ary);
+
+ ary2 = ary_new(rb_obj_class(ary), len);
+ ARY_SET_LEN(ary2, len);
+
+ ptr = RARRAY_CONST_PTR(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));
+ t *= 2;
+ }
+ if (t < len) {
+ ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
+ }
}
+ out:
+ OBJ_INFECT(ary2, ary);
return ary2;
}
+/*
+ * call-seq:
+ * ary.assoc(obj) -> element_ary 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 contained array that matches (that is, the first
+ * associated array), or +nil+ if no match 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
+ */
+
VALUE
-ary_assoc(ary, key)
- VALUE ary;
- VALUE key;
+rb_ary_assoc(VALUE ary, VALUE key)
{
- VALUE *p, *pend;
+ long i;
+ VALUE v;
- p = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
- while (p < pend) {
- if (TYPE(*p) == T_ARRAY
- && RARRAY(*p)->len > 1
- && rb_equal(RARRAY(*p)->ptr[0], key))
- return *p;
- p++;
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ v = rb_check_array_type(RARRAY_AREF(ary, i));
+ if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
+ rb_equal(RARRAY_AREF(v, 0), key))
+ return v;
}
return Qnil;
}
+/*
+ * 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>.
+ *
+ * Returns the first contained array that matches +obj+.
+ *
+ * See also Array#assoc.
+ *
+ * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
+ * a.rassoc("two") #=> [2, "two"]
+ * a.rassoc("four") #=> nil
+ */
+
VALUE
-ary_rassoc(ary, value)
- VALUE ary;
- VALUE value;
+rb_ary_rassoc(VALUE ary, VALUE value)
{
- VALUE *p, *pend;
+ long i;
+ VALUE v;
- p = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
- while (p < pend) {
- if (TYPE(*p) == T_ARRAY
- && RARRAY(*p)->len > 1
- && rb_equal(RARRAY(*p)->ptr[1], value))
- return *p;
- p++;
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ v = RARRAY_AREF(ary, i);
+ if (RB_TYPE_P(v, T_ARRAY) &&
+ RARRAY_LEN(v) > 1 &&
+ rb_equal(RARRAY_AREF(v, 1), value))
+ return v;
}
return Qnil;
}
static VALUE
-ary_equal(ary1, ary2)
- VALUE ary1, ary2;
+recursive_equal(VALUE ary1, VALUE ary2, int recur)
{
- int i;
+ long i, len1;
+ const VALUE *p1, *p2;
+
+ if (recur) return Qtrue; /* Subtle! */
+
+ p1 = RARRAY_CONST_PTR(ary1);
+ p2 = RARRAY_CONST_PTR(ary2);
+ len1 = RARRAY_LEN(ary1);
+
+ for (i = 0; i < len1; i++) {
+ if (*p1 != *p2) {
+ if (rb_equal(*p1, *p2)) {
+ len1 = RARRAY_LEN(ary1);
+ if (len1 != RARRAY_LEN(ary2))
+ return Qfalse;
+ if (len1 < i)
+ return Qtrue;
+ p1 = RARRAY_CONST_PTR(ary1) + i;
+ p2 = RARRAY_CONST_PTR(ary2) + i;
+ }
+ else {
+ return Qfalse;
+ }
+ }
+ p1++;
+ p2++;
+ }
+ return Qtrue;
+}
- if (TYPE(ary2) != T_ARRAY) return FALSE;
- if (RARRAY(ary1)->len != RARRAY(ary2)->len) return FALSE;
- for (i=0; i<RARRAY(ary1)->len; i++) {
- if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
- return FALSE;
+/*
+ * call-seq:
+ * ary == other_ary -> bool
+ *
+ * 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+.
+ *
+ * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
+ * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
+ * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
+ *
+ */
+
+static VALUE
+rb_ary_equal(VALUE ary1, VALUE ary2)
+{
+ if (ary1 == ary2) return Qtrue;
+ if (!RB_TYPE_P(ary2, T_ARRAY)) {
+ if (!rb_respond_to(ary2, idTo_ary)) {
+ return Qfalse;
+ }
+ return rb_equal(ary2, ary1);
}
- return TRUE;
+ if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
+ if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
+ return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}
static VALUE
-ary_eql(ary1, ary2)
- VALUE ary1, ary2;
+recursive_eql(VALUE ary1, VALUE ary2, int recur)
{
- int i;
+ long i;
- if (TYPE(ary2) != T_ARRAY) return FALSE;
- if (RARRAY(ary1)->len != RARRAY(ary2)->len)
- return FALSE;
- for (i=0; i<RARRAY(ary1)->len; i++) {
- if (!rb_eql(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
- return FALSE;
+ if (recur) return Qtrue; /* Subtle! */
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+ return Qfalse;
}
- return TRUE;
+ return Qtrue;
}
+/*
+ * call-seq:
+ * ary.eql?(other) -> true or false
+ *
+ * Returns +true+ if +self+ and +other+ are the same object,
+ * or are both arrays with the same content (according to Object#eql?).
+ */
+
static VALUE
-ary_hash(ary)
- VALUE ary;
+rb_ary_eql(VALUE ary1, VALUE ary2)
{
- int h, i;
+ 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;
+ return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
+}
- h = RARRAY(ary)->len;
- for (i=0; i<RARRAY(ary)->len; i++) {
- h ^= rb_hash(RARRAY(ary)->ptr[i]);
+/*
+ * call-seq:
+ * ary.hash -> integer
+ *
+ * Compute a hash-code for this array.
+ *
+ * Two arrays with the same content will have the same hash code (and will
+ * compare using #eql?).
+ *
+ * See also Object#hash.
+ */
+
+static VALUE
+rb_ary_hash(VALUE ary)
+{
+ long i;
+ st_index_t h;
+ VALUE n;
+
+ h = rb_hash_start(RARRAY_LEN(ary));
+ h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ n = rb_hash(RARRAY_AREF(ary, i));
+ h = rb_hash_uint(h, NUM2LONG(n));
}
- return INT2FIX(h);
+ h = rb_hash_end(h);
+ return ST2FIX(h);
}
+/*
+ * 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+.
+ *
+ * a = [ "a", "b", "c" ]
+ * a.include?("b") #=> true
+ * a.include?("z") #=> false
+ */
+
VALUE
-ary_includes(ary, item)
- VALUE ary;
- VALUE item;
+rb_ary_includes(VALUE ary, VALUE item)
{
- int i;
- for (i=0; i<RARRAY(ary)->len; i++) {
- if (rb_equal(RARRAY(ary)->ptr[i], item)) {
- return TRUE;
+ long i;
+ VALUE e;
+
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, item)) {
+ return Qtrue;
}
}
- return FALSE;
+ return Qfalse;
}
-VALUE
-ary_cmp(ary, ary2)
- VALUE ary;
- VALUE ary2;
+static VALUE
+rb_ary_includes_by_eql(VALUE ary, VALUE item)
{
- int i, len;
+ long i;
+ VALUE e;
- ary2 = to_ary(ary2);
- len = RARRAY(ary)->len;
- if (len > RARRAY(ary2)->len) {
- len = RARRAY(ary2)->len;
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ e = RARRAY_AREF(ary, i);
+ if (rb_eql(item, e)) {
+ return Qtrue;
+ }
+ }
+ return Qfalse;
+}
+
+static VALUE
+recursive_cmp(VALUE ary1, VALUE ary2, int recur)
+{
+ long i, len;
+
+ if (recur) return Qundef; /* Subtle! */
+ len = RARRAY_LEN(ary1);
+ if (len > RARRAY_LEN(ary2)) {
+ len = RARRAY_LEN(ary2);
}
for (i=0; i<len; i++) {
- VALUE v = rb_funcall(RARRAY(ary)->ptr[i],cmp,1,RARRAY(ary2)->ptr[i]);
+ VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
+ VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
if (v != INT2FIX(0)) {
return v;
}
}
- len = RARRAY(ary)->len - RARRAY(ary2)->len;
+ return Qundef;
+}
+
+/*
+ * 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).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * +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
+ *
+ */
+
+VALUE
+rb_ary_cmp(VALUE ary1, VALUE ary2)
+{
+ long len;
+ VALUE v;
+
+ ary2 = rb_check_array_type(ary2);
+ if (NIL_P(ary2)) return Qnil;
+ if (ary1 == ary2) return INT2FIX(0);
+ v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
+ if (v != Qundef) return v;
+ len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
if (len == 0) return INT2FIX(0);
if (len > 0) return INT2FIX(1);
return INT2FIX(-1);
}
static VALUE
-ary_diff(ary1, ary2)
- VALUE ary1, ary2;
+ary_add_hash(VALUE hash, VALUE ary)
+{
+ long i;
+
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ VALUE elt = RARRAY_AREF(ary, i);
+ rb_hash_add_new_element(hash, elt, elt);
+ }
+ return hash;
+}
+
+static inline VALUE
+ary_tmp_hash_new(VALUE ary)
+{
+ long size = RARRAY_LEN(ary);
+ VALUE hash = rb_hash_new_with_size(size);
+
+ RBASIC_CLEAR_CLASS(hash);
+ return hash;
+}
+
+static VALUE
+ary_make_hash(VALUE ary)
+{
+ VALUE hash = ary_tmp_hash_new(ary);
+ return ary_add_hash(hash, ary);
+}
+
+static VALUE
+ary_add_hash_by(VALUE hash, VALUE ary)
+{
+ long i;
+
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
+ rb_hash_add_new_element(hash, k, v);
+ }
+ return hash;
+}
+
+static VALUE
+ary_make_hash_by(VALUE ary)
+{
+ VALUE hash = ary_tmp_hash_new(ary);
+ return ary_add_hash_by(hash, ary);
+}
+
+static inline void
+ary_recycle_hash(VALUE hash)
+{
+ assert(RBASIC_CLASS(hash) == 0);
+ if (RHASH(hash)->ntbl) {
+ st_table *tbl = RHASH(hash)->ntbl;
+ st_free_table(tbl);
+ }
+ 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.
+ *
+ * It compares elements using their #hash and #eql? methods for efficiency.
+ *
+ * [ 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.
+ */
+
+static VALUE
+rb_ary_diff(VALUE ary1, VALUE ary2)
{
VALUE ary3;
- int i;
+ VALUE hash;
+ long i;
ary2 = to_ary(ary2);
- ary3 = ary_new();
- for (i=0; i<RARRAY(ary1)->len; i++) {
- if (ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue;
- if (ary_includes(ary3, RARRAY(ary1)->ptr[i])) continue;
- ary_push(ary3, RARRAY(ary1)->ptr[i]);
+ ary3 = rb_ary_new();
+
+ 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;
+ rb_ary_push(ary3, elt);
+ }
+ return ary3;
}
+
+ 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;
+ rb_ary_push(ary3, rb_ary_elt(ary1, i));
+ }
+ ary_recycle_hash(hash);
return ary3;
}
+/*
+ * call-seq:
+ * ary & other_ary -> new_ary
+ *
+ * Set Intersection --- Returns a new array containing unique elements common to the
+ * two arrays. The order is preserved from the original array.
+ *
+ * It compares elements using their #hash and #eql? methods for efficiency.
+ *
+ * [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
+ * [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
+ *
+ * See also Array#uniq.
+ */
+
+
static VALUE
-ary_and(ary1, ary2)
- VALUE ary1, ary2;
+rb_ary_and(VALUE ary1, VALUE ary2)
{
- VALUE ary3;
- int i;
+ VALUE hash, ary3, v;
+ st_table *table;
+ st_data_t vv;
+ long i;
ary2 = to_ary(ary2);
- ary3 = ary_new();
- for (i=0; i<RARRAY(ary1)->len; i++) {
- if (ary_includes(ary2, RARRAY(ary1)->ptr[i])
- && !ary_includes(ary3, RARRAY(ary1)->ptr[i])) {
- ary_push(ary3, RARRAY(ary1)->ptr[i]);
+ ary3 = rb_ary_new();
+ if (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++) {
+ v = RARRAY_AREF(ary1, i);
+ if (!rb_ary_includes_by_eql(ary2, v)) continue;
+ if (rb_ary_includes_by_eql(ary3, v)) continue;
+ rb_ary_push(ary3, v);
}
+ return ary3;
}
+
+ 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)) {
+ rb_ary_push(ary3, v);
+ }
+ }
+ ary_recycle_hash(hash);
+
return ary3;
}
+static int
+ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
+{
+ if (existing) return ST_STOP;
+ *key = *value = (VALUE)arg;
+ return ST_CONTINUE;
+}
+
+/*
+ * call-seq:
+ * ary | other_ary -> new_ary
+ *
+ * Set Union --- Returns a new array by joining +ary+ with +other_ary+,
+ * excluding any duplicates and preserving the order from the given arrays.
+ *
+ * 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.
+ */
+
static VALUE
-ary_or(ary1, ary2)
- VALUE ary1, ary2;
+rb_ary_or(VALUE ary1, VALUE ary2)
{
- VALUE ary3;
- int i;
+ VALUE hash, ary3;
+ long i;
- if (TYPE(ary2) != T_ARRAY) {
- if (ary_includes(ary1, ary2)) return ary1;
- else return ary_plus(ary1, ary2);
+ 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);
+ }
+ return ary3;
}
- ary3 = ary_new();
- for (i=0; i<RARRAY(ary1)->len; i++) {
- if (!ary_includes(ary3, RARRAY(ary1)->ptr[i]))
- ary_push(ary3, RARRAY(ary1)->ptr[i]);
- }
- for (i=0; i<RARRAY(ary2)->len; i++) {
- if (!ary_includes(ary3, RARRAY(ary2)->ptr[i]))
- ary_push(ary3, RARRAY(ary2)->ptr[i]);
+ 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);
+ }
}
+ ary3 = rb_hash_values(hash);
+ ary_recycle_hash(hash);
return ary3;
}
+/*
+ * call-seq:
+ * ary.max -> obj
+ * ary.max { |a, b| block } -> obj
+ * ary.max(n) -> array
+ * ary.max(n) { |a, b| block } -> array
+ *
+ * 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>.
+ *
+ * ary = %w(albatross dog horse)
+ * ary.max #=> "horse"
+ * ary.max { |a, b| a.length <=> b.length } #=> "albatross"
+ *
+ * If the +n+ argument is given, maximum +n+ elements are returned
+ * as an array.
+ *
+ * ary = %w[albatross dog horse]
+ * ary.max(2) #=> ["horse", "dog"]
+ * ary.max(2) {|a, b| a.length <=> b.length } #=> ["albatross", "horse"]
+ */
static VALUE
-ary_uniq_bang(ary)
- VALUE ary;
+rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
- VALUE *p, *q, *t, *end;
- VALUE v;
-
- ary_modify(ary);
- p = RARRAY(ary)->ptr;
- end = p + RARRAY(ary)->len;
+ struct cmp_opt_data cmp_opt = { 0, 0 };
+ VALUE result = Qundef, v;
+ VALUE num;
+ long i;
+
+ rb_scan_args(argc, argv, "01", &num);
+
+ if (!NIL_P(num))
+ return rb_nmin_run(ary, num, 0, 1, 1);
+
+ if (rb_block_given_p()) {
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
+ result = v;
+ }
+ }
+ }
+ 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;
+ }
+ }
+ }
+ if (result == Qundef) return Qnil;
+ return result;
+}
- while (p < end) {
- v = *p++;
- q = t = p;
- while (q < end) {
- if (rb_equal(*q, v)) q++;
- else *t++ = *q++;
+/*
+ * call-seq:
+ * ary.min -> obj
+ * ary.min {| a,b | block } -> obj
+ * ary.min(n) -> array
+ * ary.min(n) {| a,b | block } -> array
+ *
+ * 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>.
+ *
+ * ary = %w(albatross dog horse)
+ * ary.min #=> "albatross"
+ * ary.min { |a, b| a.length <=> b.length } #=> "dog"
+ *
+ * If the +n+ argument is given, minimum +n+ elements are returned
+ * as an array.
+ *
+ * ary = %w[albatross dog horse]
+ * ary.min(2) #=> ["albatross", "dog"]
+ * ary.min(2) {|a, b| a.length <=> b.length } #=> ["dog", "horse"]
+ */
+static VALUE
+rb_ary_min(int argc, VALUE *argv, VALUE ary)
+{
+ struct cmp_opt_data cmp_opt = { 0, 0 };
+ VALUE result = Qundef, v;
+ VALUE num;
+ long i;
+
+ rb_scan_args(argc, argv, "01", &num);
+
+ if (!NIL_P(num))
+ return rb_nmin_run(ary, num, 0, 0, 1);
+
+ if (rb_block_given_p()) {
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
+ result = v;
+ }
}
- end = t;
}
- if (RARRAY(ary)->len == (end - RARRAY(ary)->ptr)) {
- return Qnil;
+ 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;
+ }
+ }
}
+ if (result == Qundef) return Qnil;
+ return result;
+}
+
+static int
+push_value(st_data_t key, st_data_t val, st_data_t ary)
+{
+ rb_ary_push((VALUE)ary, (VALUE)val);
+ return ST_CONTINUE;
+}
+
+/*
+ * call-seq:
+ * ary.uniq! -> ary or nil
+ * ary.uniq! { |item| ... } -> ary or nil
+ *
+ * Removes duplicate elements from +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.
+ *
+ * Returns +nil+ if no changes are made (that is, no duplicates are found).
+ *
+ * a = [ "a", "a", "b", "b", "c" ]
+ * a.uniq! # => ["a", "b", "c"]
+ *
+ * b = [ "a", "b", "c" ]
+ * b.uniq! # => nil
+ *
+ * c = [["student","sam"], ["student","george"], ["teacher","matz"]]
+ * c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
+ *
+ */
- RARRAY(ary)->len = (end - RARRAY(ary)->ptr);
+static VALUE
+rb_ary_uniq_bang(VALUE ary)
+{
+ VALUE hash;
+ long hash_size;
+
+ rb_ary_modify_check(ary);
+ if (RARRAY_LEN(ary) <= 1)
+ return Qnil;
+ if (rb_block_given_p())
+ hash = ary_make_hash_by(ary);
+ else
+ hash = ary_make_hash(ary);
+
+ hash_size = RHASH_SIZE(hash);
+ if (RARRAY_LEN(ary) == hash_size) {
+ return Qnil;
+ }
+ rb_ary_modify_check(ary);
+ ARY_SET_LEN(ary, 0);
+ if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
+ rb_ary_unshare(ary);
+ FL_SET_EMBED(ary);
+ }
+ ary_resize_capa(ary, hash_size);
+ st_foreach(rb_hash_tbl_raw(hash), push_value, ary);
+ ary_recycle_hash(hash);
return 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"]]
+ *
+ */
+
static VALUE
-ary_uniq(ary)
- VALUE ary;
+rb_ary_uniq(VALUE ary)
{
- VALUE v = ary_uniq_bang(ary_dup(ary));
+ VALUE hash, uniq;
- if (NIL_P(v)) return ary;
- return v;
+ if (RARRAY_LEN(ary) <= 1)
+ return rb_ary_dup(ary);
+ if (rb_block_given_p()) {
+ hash = ary_make_hash_by(ary);
+ uniq = rb_hash_values(hash);
+ }
+ else {
+ hash = ary_make_hash(ary);
+ uniq = rb_hash_values(hash);
+ }
+ RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
+ ary_recycle_hash(hash);
+
+ return uniq;
}
+/*
+ * call-seq:
+ * ary.compact! -> ary or nil
+ *
+ * Removes +nil+ elements from the array.
+ *
+ * Returns +nil+ if no changes were made, otherwise returns the array.
+ *
+ * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
+ * [ "a", "b", "c" ].compact! #=> nil
+ */
+
static VALUE
-ary_compact_bang(ary)
- VALUE ary;
+rb_ary_compact_bang(VALUE ary)
{
VALUE *p, *t, *end;
+ long n;
+
+ rb_ary_modify(ary);
+ p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
+ end = p + RARRAY_LEN(ary);
- ary_modify(ary);
- p = t = RARRAY(ary)->ptr;
- end = p + RARRAY(ary)->len;
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
- if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) {
+ n = p - RARRAY_CONST_PTR(ary);
+ if (RARRAY_LEN(ary) == n) {
return Qnil;
}
- RARRAY(ary)->len = RARRAY(ary)->capa = (p - RARRAY(ary)->ptr);
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
+ ary_resize_smaller(ary, n);
return ary;
}
+/*
+ * call-seq:
+ * ary.compact -> new_ary
+ *
+ * Returns a copy of +self+ with all +nil+ elements removed.
+ *
+ * [ "a", nil, "b", nil, "c", nil ].compact
+ * #=> [ "a", "b", "c" ]
+ */
+
static VALUE
-ary_compact(ary)
- VALUE ary;
+rb_ary_compact(VALUE ary)
{
- VALUE v = ary_compact_bang(ary_dup(ary));
+ ary = rb_ary_dup(ary);
+ rb_ary_compact_bang(ary);
+ return ary;
+}
- if (NIL_P(v)) return ary;
- return v;
+/*
+ * call-seq:
+ * ary.count -> int
+ * ary.count(obj) -> int
+ * ary.count { |item| block } -> int
+ *
+ * Returns the number of elements.
+ *
+ * If an argument is given, counts the number of elements which equal +obj+
+ * using <code>==</code>.
+ *
+ * If a block is given, counts the number of elements for which the block
+ * returns a true value.
+ *
+ * ary = [1, 2, 4, 2]
+ * ary.count #=> 4
+ * ary.count(2) #=> 2
+ * ary.count { |x| x%2 == 0 } #=> 3
+ *
+ */
+
+static VALUE
+rb_ary_count(int argc, VALUE *argv, VALUE ary)
+{
+ long i, n = 0;
+
+ if (argc == 0) {
+ VALUE v;
+
+ if (!rb_block_given_p())
+ return LONG2NUM(RARRAY_LEN(ary));
+
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (RTEST(rb_yield(v))) n++;
+ }
+ }
+ else {
+ VALUE obj;
+
+ rb_scan_args(argc, argv, "1", &obj);
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
+ }
+ }
+
+ return LONG2NUM(n);
}
static VALUE
-ary_nitems(ary)
- VALUE ary;
+flatten(VALUE ary, int level, int *modified)
{
- int n = 0;
- VALUE *p, *pend;
+ long i = 0;
+ VALUE stack, result, tmp, elt;
+ st_table *memo;
+ st_data_t id;
+
+ stack = ary_new(0, ARY_DEFAULT_SIZE);
+ result = ary_new(0, RARRAY_LEN(ary));
+ memo = st_init_numtable();
+ st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
+ *modified = 0;
+
+ while (1) {
+ while (i < RARRAY_LEN(ary)) {
+ elt = RARRAY_AREF(ary, i++);
+ if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
+ rb_ary_push(result, elt);
+ continue;
+ }
+ tmp = rb_check_array_type(elt);
+ if (RBASIC(result)->klass) {
+ 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");
+ }
+ st_insert(memo, id, (st_data_t)Qtrue);
+ rb_ary_push(stack, ary);
+ rb_ary_push(stack, LONG2NUM(i));
+ ary = tmp;
+ i = 0;
+ }
+ }
+ if (RARRAY_LEN(stack) == 0) {
+ break;
+ }
+ 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);
- p = RARRAY(ary)->ptr;
- pend = p + RARRAY(ary)->len;
- while (p < pend) {
- if (!NIL_P(*p)) n++;
- p++;
+ RBASIC_SET_CLASS(result, rb_obj_class(ary));
+ 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]]
+ */
+
+static VALUE
+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);
+ 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);
+ return Qnil;
}
- return INT2FIX(n);
+ if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
+ rb_ary_replace(ary, result);
+ if (mod) ARY_SET_EMBED_LEN(result, 0);
+
+ return 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]]
+ */
+
+static VALUE
+rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
+{
+ int mod = 0, level = -1;
+ VALUE result, lv;
+
+ rb_scan_args(argc, argv, "01", &lv);
+ if (!NIL_P(lv)) level = NUM2INT(lv);
+ if (level == 0) return ary_make_shared_copy(ary);
+
+ result = flatten(ary, level, &mod);
+ OBJ_INFECT(result, 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
-ary_flatten_bang(ary)
- VALUE ary;
+rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary)
{
- int i;
- int mod = 0;
+ VALUE opts, randgen = rb_cRandom;
+ long i, len;
- ary_modify(ary);
- for (i=0; i<RARRAY(ary)->len; i++) {
- VALUE ary2 = RARRAY(ary)->ptr[i];
- if (TYPE(ary2) == T_ARRAY) {
- ary_replace(ary, i--, 1, ary2);
- mod = 1;
+ 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;
}
}
- if (mod == 0) return Qnil;
+ 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");
+ }
+ tmp = ptr[--i];
+ ptr[i] = ptr[j];
+ ptr[j] = tmp;
+ }
+ }); /* WB: no new reference */
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
-ary_flatten(ary)
- VALUE ary;
+rb_ary_shuffle(int argc, VALUE *argv, VALUE ary)
+{
+ ary = rb_ary_dup(ary);
+ rb_ary_shuffle_bang(argc, argv, ary);
+ 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)
{
- VALUE v = ary_flatten_bang(ary_dup(ary));
+ VALUE nv, result;
+ VALUE opts, randgen = rb_cRandom;
+ 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 (len < 2)
+ i = 0;
+ else
+ i = RAND_UPTO(len);
- if (NIL_P(v)) return 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;
+ if (n <= numberof(idx)) {
+ for (i = 0; i < n; ++i) {
+ rnds[i] = RAND_UPTO(len - i);
+ }
+ }
+ k = len;
+ len = RARRAY_LEN(ary);
+ if (len < k && n <= numberof(idx)) {
+ for (i = 0; i < n; ++i) {
+ if (rnds[i] >= len) return rb_ary_new_capa(0);
+ }
+ }
+ if (n > len) n = len;
+ switch (n) {
+ case 0:
+ return rb_ary_new_capa(0);
+ case 1:
+ i = rnds[0];
+ return rb_ary_new_from_values(1, &RARRAY_AREF(ary, i));
+ case 2:
+ i = rnds[0];
+ j = rnds[1];
+ if (j >= i) j++;
+ return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
+ case 3:
+ i = rnds[0];
+ j = rnds[1];
+ k = rnds[2];
+ {
+ long l = j, g = i;
+ if (j >= i) l = i, g = ++j;
+ if (k >= l && (++k >= g)) ++k;
+ }
+ return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
+ }
+ memo_threshold =
+ len < 2560 ? len / 128 :
+ len < 5120 ? len / 64 :
+ len < 10240 ? len / 32 :
+ len / 16;
+ if (n <= numberof(idx)) {
+ long sorted[numberof(idx)];
+ sorted[0] = idx[0] = rnds[0];
+ for (i=1; i<n; i++) {
+ k = rnds[i];
+ for (j = 0; j < i; ++j) {
+ if (k < sorted[j]) break;
+ ++k;
+ }
+ memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
+ sorted[j] = idx[i] = k;
+ }
+ result = rb_ary_new_capa(n);
+ RARRAY_PTR_USE(result, ptr_result, {
+ for (i=0; i<n; i++) {
+ ptr_result[i] = RARRAY_AREF(ary, idx[i]);
+ }
+ });
+ }
+ else if (n <= memo_threshold / 2) {
+ long max_idx = 0;
+#undef RUBY_UNTYPED_DATA_WARNING
+#define RUBY_UNTYPED_DATA_WARNING 0
+ 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);
+ RARRAY_PTR_USE(result, ptr_result, {
+ for (i=0; i<n; i++) {
+ long r = RAND_UPTO(len-i) + i;
+ ptr_result[i] = r;
+ if (r > max_idx) max_idx = r;
+ }
+ len = RARRAY_LEN(ary);
+ if (len <= max_idx) n = 0;
+ else if (n > len) n = len;
+ RARRAY_PTR_USE(ary, ptr_ary, {
+ for (i=0; i<n; i++) {
+ long j2 = j = ptr_result[i];
+ long i2 = i;
+ st_data_t value;
+ if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
+ if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
+ st_insert(memo, (st_data_t)j, (st_data_t)i2);
+ ptr_result[i] = ptr_ary[j2];
+ }
+ });
+ });
+ DATA_PTR(vmemo) = 0;
+ st_free_table(memo);
+ }
+ else {
+ result = rb_ary_dup(ary);
+ RBASIC_CLEAR_CLASS(result);
+ RB_GC_GUARD(ary);
+ RARRAY_PTR_USE(result, ptr_result, {
+ for (i=0; i<n; i++) {
+ j = RAND_UPTO(len-i) + i;
+ nv = ptr_result[j];
+ ptr_result[j] = ptr_result[i];
+ ptr_result[i] = nv;
+ }
+ });
+ RBASIC_SET_CLASS_RAW(result, rb_cArray);
+ }
+ ARY_SET_LEN(result, n);
+
+ return result;
+}
+
+static VALUE
+rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
+{
+ long mul;
+ VALUE n = Qnil;
+ if (args && (RARRAY_LEN(args) > 0)) {
+ n = RARRAY_AREF(args, 0);
+ }
+ if (RARRAY_LEN(self) == 0) return INT2FIX(0);
+ if (n == Qnil) return DBL2NUM(INFINITY);
+ mul = NUM2LONG(n);
+ if (mul <= 0) return INT2FIX(0);
+ n = LONG2FIX(mul);
+ return rb_fix_mul_fix(rb_ary_length(self), n);
+}
+
+/*
+ * 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.
+ *
+ */
+
+static VALUE
+rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
+{
+ long n, i;
+ VALUE nv = Qnil;
+
+ rb_scan_args(argc, argv, "01", &nv);
+
+ RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
+ if (NIL_P(nv)) {
+ n = -1;
+ }
+ else {
+ n = NUM2LONG(nv);
+ if (n <= 0) return Qnil;
+ }
+
+ while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ rb_yield(RARRAY_AREF(ary, i));
+ }
+ }
+ 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))
+
+/*
+ * Build a ruby array of the corresponding values and yield it to the
+ * associated block.
+ * Return the class of +values+ for reentry check.
+ */
+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]];
+ ARY_SET_LEN(result, r);
+ rb_yield(result);
+ return !RBASIC(values)->klass;
+}
+
+/*
+ * Compute permutations of +r+ elements of the set <code>[0..n-1]</code>.
+ *
+ * When we have a complete permutation of array indices, copy the values
+ * at those indices into a new array and yield that array.
+ *
+ * n: the size of the set
+ * r: the number of elements in each permutation
+ * p: the array (of size r) that we're filling in
+ * used: an array of booleans: whether a given index is already used
+ * values: the Ruby array that holds the actual values to permute
+ */
+static void
+permute0(const long n, const long r, long *const p, char *const used, const VALUE values)
+{
+ long i = 0, index = 0;
+
+ for (;;) {
+ const char *const unused = memchr(&used[i], 0, n-i);
+ if (!unused) {
+ if (!index) break;
+ i = p[--index]; /* pop index */
+ used[i++] = 0; /* index unused */
+ }
+ else {
+ i = unused - used;
+ p[index] = i;
+ used[i] = 1; /* mark index used */
+ ++index;
+ if (index < r-1) { /* if not done yet */
+ p[index] = i = 0;
+ continue;
+ }
+ for (i = 0; i < n; ++i) {
+ if (used[i]) continue;
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "permute reentered");
+ }
+ }
+ i = p[--index]; /* pop index */
+ used[i] = 0; /* index unused */
+ p[index] = ++i;
+ }
+ }
+}
+
+/*
+ * Returns the product of from, from-1, ..., from - how_many + 1.
+ * http://en.wikipedia.org/wiki/Pochhammer_symbol
+ */
+static VALUE
+descending_factorial(long from, long how_many)
+{
+ VALUE cnt;
+ if (how_many > 0) {
+ cnt = LONG2FIX(from);
+ while (--how_many > 0) {
+ long v = --from;
+ cnt = rb_int_mul(cnt, LONG2FIX(v));
+ }
+ }
+ else {
+ cnt = LONG2FIX(how_many == 0);
+ }
+ return cnt;
+}
+
+static VALUE
+binomial_coefficient(long comb, long size)
+{
+ VALUE r;
+ long i;
+ if (comb > size-comb) {
+ comb = size-comb;
+ }
+ if (comb < 0) {
+ return LONG2FIX(0);
+ }
+ else if (comb == 0) {
+ return LONG2FIX(1);
+ }
+ r = LONG2FIX(size);
+ for (i = 1; i < comb; ++i) {
+ r = rb_int_mul(r, LONG2FIX(size - i));
+ r = rb_int_idiv(r, LONG2FIX(i + 1));
+ }
+ return r;
+}
+
+static VALUE
+rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
+{
+ long n = RARRAY_LEN(ary);
+ long k = (args && (RARRAY_LEN(args) > 0)) ? NUM2LONG(RARRAY_AREF(args, 0)) : n;
+
+ return descending_factorial(n, k);
+}
+
+/*
+ * 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
+ */
+
+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 */
+
+ if (r < 0 || n < r) {
+ /* no permutations: yield nothing */
+ }
+ else if (r == 0) { /* exactly one permutation: the zero-length array */
+ rb_yield(rb_ary_new2(0));
+ }
+ else if (r == 1) { /* this is a special, easy case */
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
+ }
+ else { /* this is the general case */
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
+ char *used = (char*)(p + r);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
+
+ MEMZERO(used, char, n); /* initialize array */
+
+ permute0(n, r, p, used, ary0); /* compute and yield permutations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ }
+ return ary;
+}
+
+static void
+combinate0(const long len, const long n, long *const stack, const VALUE values)
+{
+ long lev = 0;
+
+ MEMZERO(stack+1, long, n);
+ stack[0] = -1;
+ for (;;) {
+ for (lev++; lev < n; lev++) {
+ stack[lev+1] = stack[lev]+1;
+ }
+ if (!yield_indexed_values(values, n, stack+1)) {
+ rb_raise(rb_eRuntimeError, "combination reentered");
+ }
+ do {
+ if (lev == 0) return;
+ stack[lev--]++;
+ } while (stack[lev+1]+n == len+lev+1);
+ }
+}
+
+static VALUE
+rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
+{
+ long n = RARRAY_LEN(ary);
+ long k = NUM2LONG(RARRAY_AREF(args, 0));
+
+ return binomial_coefficient(k, n);
+}
+
+/*
+ * 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
+ *
+ */
+
+static VALUE
+rb_ary_combination(VALUE ary, VALUE num)
+{
+ long i, n, len;
+
+ n = NUM2LONG(num);
+ RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
+ len = RARRAY_LEN(ary);
+ if (n < 0 || len < n) {
+ /* yield nothing */
+ }
+ else if (n == 0) {
+ rb_yield(rb_ary_new2(0));
+ }
+ else if (n == 1) {
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
+ }
+ else {
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ volatile VALUE t0;
+ long *stack = ALLOCV_N(long, t0, n+1);
+
+ RBASIC_CLEAR_CLASS(ary0);
+ combinate0(len, n, stack, ary0);
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ }
+ return ary;
+}
+
+/*
+ * Compute repeated permutations of +r+ elements of the set
+ * <code>[0..n-1]</code>.
+ *
+ * When we have a complete repeated permutation of array indices, copy the
+ * values at those indices into a new array and yield that array.
+ *
+ * n: the size of the set
+ * r: the number of elements in each permutation
+ * p: the array (of size r) that we're filling in
+ * values: the Ruby array that holds the actual values to permute
+ */
+static void
+rpermute0(const long n, const long r, long *const p, const VALUE values)
+{
+ long i = 0, index = 0;
+
+ p[index] = i;
+ for (;;) {
+ if (++index < r-1) {
+ p[index] = i = 0;
+ continue;
+ }
+ for (i = 0; i < n; ++i) {
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "repeated permute reentered");
+ }
+ }
+ do {
+ if (index <= 0) return;
+ } while ((i = ++p[--index]) >= n);
+ }
+}
+
+static VALUE
+rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
+{
+ long n = RARRAY_LEN(ary);
+ long k = NUM2LONG(RARRAY_AREF(args, 0));
+
+ if (k < 0) {
+ return LONG2FIX(0);
+ }
+ if (n <= 0) {
+ return LONG2FIX(!k);
+ }
+ return rb_int_positive_pow(n, (unsigned long)k);
+}
+
+/*
+ * 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
+ */
+
+static VALUE
+rb_ary_repeated_permutation(VALUE ary, VALUE num)
+{
+ long r, n, i;
+
+ n = RARRAY_LEN(ary); /* Array length */
+ RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
+ r = NUM2LONG(num); /* Permutation size from argument */
+
+ if (r < 0) {
+ /* no permutations: yield nothing */
+ }
+ else if (r == 0) { /* exactly one permutation: the zero-length array */
+ rb_yield(rb_ary_new2(0));
+ }
+ else if (r == 1) { /* this is a special, easy case */
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
+ }
+ else { /* this is the general case */
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, r);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
+
+ rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ }
+ return ary;
+}
+
+static void
+rcombinate0(const long n, const long r, long *const p, const long rest, const VALUE values)
+{
+ long i = 0, index = 0;
+
+ p[index] = i;
+ for (;;) {
+ if (++index < r-1) {
+ p[index] = i;
+ continue;
+ }
+ for (; i < n; ++i) {
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "repeated combination reentered");
+ }
+ }
+ do {
+ if (index <= 0) return;
+ } while ((i = ++p[--index]) >= n);
+ }
+}
+
+static VALUE
+rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
+{
+ long n = RARRAY_LEN(ary);
+ long k = NUM2LONG(RARRAY_AREF(args, 0));
+ if (k == 0) {
+ return LONG2FIX(1);
+ }
+ return binomial_coefficient(k, n + k - 1);
+}
+
+/*
+ * 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
+ *
+ */
+
+static VALUE
+rb_ary_repeated_combination(VALUE ary, VALUE num)
+{
+ long n, i, len;
+
+ n = NUM2LONG(num); /* Combination size from argument */
+ RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
+ len = RARRAY_LEN(ary);
+ if (n < 0) {
+ /* yield nothing */
+ }
+ else if (n == 0) {
+ rb_yield(rb_ary_new2(0));
+ }
+ else if (n == 1) {
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
+ }
+ else if (len == 0) {
+ /* yield nothing */
+ }
+ else {
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, n);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
+
+ rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ }
+ return ary;
+}
+
+/*
+ * 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([]) #=> []
+ */
+
+static VALUE
+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));
+ 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 */
+ 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);
+ arrays[0] = ary;
+ for (i = 1; i < n; i++) arrays[i] = Qnil;
+ for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
+
+ /* initialize the counters for the arrays */
+ for (i = 0; i < n; i++) counters[i] = 0;
+
+ /* Otherwise, allocate and fill in an array of results */
+ if (rb_block_given_p()) {
+ /* Make defensive copies of arrays; exit if any is empty */
+ for (i = 0; i < n; i++) {
+ if (RARRAY_LEN(arrays[i]) == 0) goto done;
+ arrays[i] = ary_make_shared_copy(arrays[i]);
+ }
+ }
+ else {
+ /* Compute the length of the result array; return [] if any is empty */
+ for (i = 0; i < n; i++) {
+ long k = RARRAY_LEN(arrays[i]);
+ if (k == 0) {
+ result = rb_ary_new2(0);
+ goto done;
+ }
+ if (MUL_OVERFLOW_LONG_P(resultlen, k))
+ rb_raise(rb_eRangeError, "too big to product");
+ resultlen *= k;
+ }
+ result = rb_ary_new2(resultlen);
+ }
+ for (;;) {
+ int m;
+ /* fill in one subarray */
+ VALUE subarray = rb_ary_new2(n);
+ for (j = 0; j < n; j++) {
+ rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
+ }
+
+ /* put it on the result array */
+ if (NIL_P(result)) {
+ FL_SET(t0, FL_USER5);
+ rb_yield(subarray);
+ if (! FL_TEST(t0, FL_USER5)) {
+ rb_raise(rb_eRuntimeError, "product reentered");
+ }
+ else {
+ FL_UNSET(t0, FL_USER5);
+ }
+ }
+ else {
+ rb_ary_push(result, subarray);
+ }
+
+ /*
+ * Increment the last counter. If it overflows, reset to 0
+ * and increment the one before it.
+ */
+ m = n-1;
+ counters[m]++;
+ while (counters[m] == RARRAY_LEN(arrays[m])) {
+ counters[m] = 0;
+ /* If the first counter overflows, we are done */
+ if (--m < 0) goto done;
+ counters[m]++;
+ }
+ }
+done:
+ tmpary_discard(t0);
+ tmpbuf_discard(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]
+ *
+ */
+
+static VALUE
+rb_ary_take(VALUE obj, VALUE n)
+{
+ long len = NUM2LONG(n);
+ if (len < 0) {
+ rb_raise(rb_eArgError, "attempt to take negative size");
+ }
+ return rb_ary_subseq(obj, 0, len);
+}
+
+/*
+ * 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]
+ *
+ */
+
+static VALUE
+rb_ary_take_while(VALUE ary)
+{
+ long i;
+
+ RETURN_ENUMERATOR(ary, 0, 0);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
+ }
+ return rb_ary_take(ary, LONG2FIX(i));
+}
+
+/*
+ * call-seq:
+ * ary.drop(n) -> new_ary
+ *
+ * Drops first +n+ elements from +ary+ and returns the rest of the elements in
+ * an 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]
+ *
+ */
+
+static VALUE
+rb_ary_drop(VALUE ary, VALUE n)
+{
+ VALUE result;
+ long pos = NUM2LONG(n);
+ if (pos < 0) {
+ rb_raise(rb_eArgError, "attempt to drop negative size");
+ }
+
+ result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
+ if (result == Qnil) result = rb_ary_new();
+ return result;
+}
+
+/*
+ * 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
+ *
+ * a = [1, 2, 3, 4, 5, 0]
+ * a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
+ *
+ */
+
+static VALUE
+rb_ary_drop_while(VALUE ary)
+{
+ long i;
+
+ RETURN_ENUMERATOR(ary, 0, 0);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
+ }
+ return rb_ary_drop(ary, LONG2FIX(i));
+}
+
+/*
+ * call-seq:
+ * ary.any? [{ |obj| block }] -> true or false
+ *
+ * See also Enumerable#any?
+ */
+
+static VALUE
+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 (argc) {
+ 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(ptr[i])) return Qtrue;
+ }
+ else {
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
+ }
+ }
+ return Qfalse;
+}
+
+/*
+ * 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
+ */
+
+VALUE
+rb_ary_dig(int argc, VALUE *argv, VALUE self)
+{
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+ self = rb_ary_at(self, *argv);
+ if (!--argc) return self;
+ ++argv;
+ return rb_obj_dig(argc, argv, self, Qnil);
+}
+
+static inline VALUE
+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);
+ }
+ else if (!n && z) {
+ v = rb_fix_plus(LONG2FIX(0), v);
+ }
+ return v;
+}
+
+/*
+ * 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#+.
+ *
+ */
+
+static VALUE
+rb_ary_sum(int argc, VALUE *argv, VALUE ary)
+{
+ VALUE e, v, r;
+ long i, n;
+ int block_given;
+
+ if (rb_scan_args(argc, argv, "01", &v) == 0)
+ v = LONG2FIX(0);
+
+ block_given = rb_block_given_p();
+
+ if (RARRAY_LEN(ary) == 0)
+ return v;
+
+ n = 0;
+ r = Qundef;
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ e = RARRAY_AREF(ary, i);
+ if (block_given)
+ e = rb_yield(e);
+ if (FIXNUM_P(e)) {
+ n += FIX2LONG(e); /* should not overflow long type */
+ if (!FIXABLE(n)) {
+ v = rb_big_plus(LONG2NUM(n), v);
+ n = 0;
+ }
+ }
+ else if (RB_TYPE_P(e, T_BIGNUM))
+ v = rb_big_plus(e, v);
+ else if (RB_TYPE_P(e, T_RATIONAL)) {
+ if (r == Qundef)
+ r = e;
+ else
+ r = rb_rational_plus(r, e);
+ }
+ else
+ goto not_exact;
+ }
+ v = finish_exact_sum(n, r, v, argc!=0);
+ return v;
+
+ not_exact:
+ v = finish_exact_sum(n, r, v, i!=0);
+
+ if (RB_FLOAT_TYPE_P(e)) {
+ /*
+ * Kahan-Babuska balancing compensated summation algorithm
+ * See http://link.springer.com/article/10.1007/s00607-005-0139-x
+ */
+ double f, c;
+
+ 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);
+ if (RB_FLOAT_TYPE_P(e))
+ has_float_value:
+ x = RFLOAT_VALUE(e);
+ else if (FIXNUM_P(e))
+ x = FIX2LONG(e);
+ else if (RB_TYPE_P(e, T_BIGNUM))
+ x = rb_big2dbl(e);
+ else if (RB_TYPE_P(e, T_RATIONAL))
+ x = rb_num2dbl(e);
+ 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);
+ else
+ c += ((x - t) + f);
+ f = t;
+ }
+ f += c;
+ return DBL2NUM(f);
+
+ not_float:
+ v = DBL2NUM(f);
+ }
+
+ goto has_some_value;
+ for (; i < RARRAY_LEN(ary); i++) {
+ e = RARRAY_AREF(ary, i);
+ if (block_given)
+ e = rb_yield(e);
+ has_some_value:
+ v = rb_funcall(v, idPLUS, 1, e);
+ }
return v;
}
+/*
+ * Arrays are ordered, integer-indexed collections of any object.
+ *
+ * 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.
+ *
+ * == Creating Arrays
+ *
+ * A new array can be created by using the literal constructor
+ * <code>[]</code>. Arrays can contain different types of objects. For
+ * example, the array below contains an Integer, a String and a Float:
+ *
+ * ary = [1, "two", 3.0] #=> [1, "two", 3.0]
+ *
+ * An array can also be created by explicitly calling Array.new with zero, one
+ * (the initial size of the Array) or two arguments (the initial size and a
+ * default object).
+ *
+ * ary = Array.new #=> []
+ * Array.new(3) #=> [nil, nil, nil]
+ * Array.new(3, true) #=> [true, true, true]
+ *
+ * Note that the second argument populates the array with references to the
+ * same object. Therefore, it is only recommended in cases when you need to
+ * instantiate arrays with natively immutable objects such as Symbols,
+ * numbers, true or false.
+ *
+ * To create an array with separate objects a block can be passed instead.
+ * This method is safe to use with mutable objects such as hashes, strings or
+ * other arrays:
+ *
+ * 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) }
+ * #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
+ *
+ * An array can also be created by using the Array() method, provided by
+ * Kernel, which tries to call #to_ary, then #to_a on its argument.
+ *
+ * Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
+ *
+ * == Example Usage
+ *
+ * In addition to the methods it mixes in through the Enumerable module, the
+ * Array class has proprietary methods for accessing, searching and otherwise
+ * manipulating arrays.
+ *
+ * Some of the more common ones are illustrated below.
+ *
+ * == Accessing Elements
+ *
+ * Elements in an array can be retrieved using the Array#[] method. It can
+ * take a single integer argument (a numeric index), a pair of arguments
+ * (start and length) or a range. Negative indices start counting from the end,
+ * with -1 being the last element.
+ *
+ * arr = [1, 2, 3, 4, 5, 6]
+ * arr[2] #=> 3
+ * arr[100] #=> nil
+ * arr[-3] #=> 4
+ * arr[2, 3] #=> [3, 4, 5]
+ * arr[1..4] #=> [2, 3, 4, 5]
+ * arr[1..-3] #=> [2, 3, 4]
+ *
+ * Another way to access a particular array element is by using the #at method
+ *
+ * arr.at(0) #=> 1
+ *
+ * The #slice method works in an identical manner to Array#[].
+ *
+ * To raise an error for indices outside of the array bounds or else to
+ * provide a default value when that happens, you can use #fetch.
+ *
+ * arr = ['a', 'b', 'c', 'd', 'e', 'f']
+ * arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
+ * arr.fetch(100, "oops") #=> "oops"
+ *
+ * The special methods #first and #last will return the first and last
+ * elements of an array, respectively.
+ *
+ * arr.first #=> 1
+ * arr.last #=> 6
+ *
+ * To return the first +n+ elements of an array, use #take
+ *
+ * arr.take(3) #=> [1, 2, 3]
+ *
+ * #drop does the opposite of #take, by returning the elements after +n+
+ * elements have been dropped:
+ *
+ * arr.drop(3) #=> [4, 5, 6]
+ *
+ * == Obtaining Information about an Array
+ *
+ * Arrays keep track of their own length at all times. To query an array
+ * about the number of elements it contains, use #length, #count or #size.
+ *
+ * browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
+ * browsers.length #=> 5
+ * browsers.count #=> 5
+ *
+ * To check whether an array contains any elements at all
+ *
+ * browsers.empty? #=> false
+ *
+ * To check whether a particular item is included in the array
+ *
+ * browsers.include?('Konqueror') #=> false
+ *
+ * == Adding Items to Arrays
+ *
+ * Items can be added to the end of an array by using either #push or #<<
+ *
+ * arr = [1, 2, 3, 4]
+ * arr.push(5) #=> [1, 2, 3, 4, 5]
+ * arr << 6 #=> [1, 2, 3, 4, 5, 6]
+ *
+ * #unshift will add a new item to the beginning of an array.
+ *
+ * arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
+ *
+ * With #insert you can add a new element to an array at any position.
+ *
+ * arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
+ *
+ * Using the #insert method, you can also insert multiple values at once:
+ *
+ * arr.insert(3, 'orange', 'pear', 'grapefruit')
+ * #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
+ *
+ * == Removing Items from an Array
+ *
+ * The method #pop removes the last element in an array and returns it:
+ *
+ * arr = [1, 2, 3, 4, 5, 6]
+ * arr.pop #=> 6
+ * arr #=> [1, 2, 3, 4, 5]
+ *
+ * To retrieve and at the same time remove the first item, use #shift:
+ *
+ * arr.shift #=> 1
+ * arr #=> [2, 3, 4, 5]
+ *
+ * To delete an element at a particular index:
+ *
+ * arr.delete_at(2) #=> 4
+ * arr #=> [2, 3, 5]
+ *
+ * To delete a particular element anywhere in an array, use #delete:
+ *
+ * arr = [1, 2, 2, 3]
+ * arr.delete(2) #=> 2
+ * arr #=> [1,3]
+ *
+ * A useful method if you need to remove +nil+ values from an array is
+ * #compact:
+ *
+ * arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
+ * arr.compact #=> ['foo', 0, 'bar', 7, 'baz']
+ * arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
+ * arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
+ * arr #=> ['foo', 0, 'bar', 7, 'baz']
+ *
+ * Another common need is to remove duplicate elements from an array.
+ *
+ * It has the non-destructive #uniq, and destructive method #uniq!
+ *
+ * arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
+ * arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
+ *
+ * == Iterating over Arrays
+ *
+ * Like all classes that include the Enumerable module, Array has an each
+ * method, which defines what elements should be iterated over and how. In
+ * case of Array's #each, all elements in the Array instance are yielded to
+ * the supplied block in sequence.
+ *
+ * Note that this operation leaves the array unchanged.
+ *
+ * arr = [1, 2, 3, 4, 5]
+ * arr.each { |a| print a -= 10, " " }
+ * # prints: -9 -8 -7 -6 -5
+ * #=> [1, 2, 3, 4, 5]
+ *
+ * Another sometimes useful iterator is #reverse_each which will iterate over
+ * the elements in the array in reverse order.
+ *
+ * words = %w[first second third fourth fifth sixth]
+ * str = ""
+ * 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 #=> [1, 2, 3, 4, 5]
+ * arr.map! { |a| a**2 } #=> [1, 4, 9, 16, 25]
+ * arr #=> [1, 4, 9, 16, 25]
+ *
+ * == Selecting Items from an Array
+ *
+ * Elements can be selected from an array according to criteria defined in a
+ * block. The selection can happen in a destructive or a non-destructive
+ * manner. While the destructive operations will modify the array they were
+ * called on, the non-destructive methods usually return a new array with the
+ * selected elements, but leave the original array unchanged.
+ *
+ * === 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 #=> [1, 2, 3, 4, 5, 6]
+ *
+ * === Destructive Selection
+ *
+ * #select! and #reject! are the corresponding destructive methods to #select
+ * and #reject
+ *
+ * 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 #=> [4, 5, 6]
+ *
+ * arr = [1, 2, 3, 4, 5, 6]
+ * arr.keep_if { |a| a < 4 } #=> [1, 2, 3]
+ * arr #=> [1, 2, 3]
+ *
+ */
+
void
-Init_Array()
-{
- cArray = rb_define_class("Array", cObject);
- rb_include_module(cArray, mEnumerable);
-
- rb_define_singleton_method(cArray, "new", ary_s_new, -1);
- rb_define_singleton_method(cArray, "[]", ary_s_create, -1);
- rb_define_method(cArray, "to_s", ary_to_s, 0);
- rb_define_method(cArray, "inspect", ary_inspect, 0);
- rb_define_method(cArray, "to_a", ary_to_a, 0);
- rb_define_method(cArray, "to_ary", ary_to_a, 0);
-
- rb_define_method(cArray, "freeze", ary_freeze, 0);
- rb_define_method(cArray, "frozen?", ary_frozen_p, 0);
-
- rb_define_method(cArray, "==", ary_equal, 1);
- rb_define_method(cArray, "eql?", ary_eql, 1);
- rb_define_method(cArray, "hash", ary_hash, 0);
-
- rb_define_method(cArray, "[]", ary_aref, -1);
- rb_define_method(cArray, "[]=", ary_aset, -1);
- rb_define_method(cArray, "concat", ary_concat, 1);
- rb_define_method(cArray, "<<", ary_push, 1);
- rb_define_method(cArray, "push", ary_push_method, -1);
- rb_define_method(cArray, "pop", ary_pop, 0);
- rb_define_method(cArray, "shift", ary_shift, 0);
- rb_define_method(cArray, "unshift", ary_unshift, 1);
- rb_define_method(cArray, "each", ary_each, 0);
- rb_define_method(cArray, "each_index", ary_each_index, 0);
- rb_define_method(cArray, "reverse_each", ary_reverse_each, 0);
- rb_define_method(cArray, "length", ary_length, 0);
- rb_define_alias(cArray, "size", "length");
- rb_define_method(cArray, "empty?", ary_empty_p, 0);
- rb_define_method(cArray, "index", ary_index, 1);
- rb_define_method(cArray, "rindex", ary_rindex, 1);
- rb_define_method(cArray, "indexes", ary_indexes, -1);
- rb_define_method(cArray, "indices", ary_indexes, -1);
- rb_define_method(cArray, "clone", ary_clone, 0);
- rb_define_method(cArray, "dup", ary_dup, 0);
- rb_define_method(cArray, "join", ary_join_method, -1);
- rb_define_method(cArray, "reverse", ary_reverse_method, 0);
- rb_define_method(cArray, "reverse!", ary_reverse, 0);
- rb_define_method(cArray, "sort", ary_sort, 0);
- rb_define_method(cArray, "sort!", ary_sort_bang, 0);
- rb_define_method(cArray, "delete", ary_delete, 1);
- rb_define_method(cArray, "delete_at", ary_delete_at, 1);
- rb_define_method(cArray, "delete_if", ary_delete_if, 0);
- rb_define_method(cArray, "filter", ary_filter, 0);
- rb_define_method(cArray, "replace", ary_replace_method, 1);
- rb_define_method(cArray, "clear", ary_clear, 0);
- rb_define_method(cArray, "fill", ary_fill, -1);
- rb_define_method(cArray, "include?", ary_includes, 1);
- rb_define_method(cArray, "===", ary_includes, 1);
- rb_define_method(cArray, "<=>", ary_cmp, 1);
-
- rb_define_method(cArray, "assoc", ary_assoc, 1);
- rb_define_method(cArray, "rassoc", ary_rassoc, 1);
-
- rb_define_method(cArray, "+", ary_plus, 1);
- rb_define_method(cArray, "*", ary_times, 1);
-
- rb_define_method(cArray, "-", ary_diff, 1);
- rb_define_method(cArray, "&", ary_and, 1);
- rb_define_method(cArray, "|", ary_or, 1);
-
- rb_define_method(cArray, "uniq", ary_uniq, 0);
- rb_define_method(cArray, "uniq!", ary_uniq_bang, 0);
- rb_define_method(cArray, "compact", ary_compact, 0);
- rb_define_method(cArray, "compact!", ary_compact_bang, 0);
- rb_define_method(cArray, "flatten", ary_flatten, 0);
- rb_define_method(cArray, "flatten!", ary_flatten_bang, 0);
- rb_define_method(cArray, "nitems", ary_nitems, 0);
-
- cmp = rb_intern("<=>");
+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);
+
+ rb_define_alloc_func(rb_cArray, empty_ary_alloc);
+ rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1);
+ rb_define_singleton_method(rb_cArray, "try_convert", rb_ary_s_try_convert, 1);
+ rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
+ rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
+
+ rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
+ rb_define_alias(rb_cArray, "to_s", "inspect");
+ 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);
+ rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
+
+ rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
+ rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
+ rb_define_method(rb_cArray, "at", rb_ary_at, 1);
+ rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
+ 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, "<<", rb_ary_push, 1);
+ rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
+ rb_define_alias(rb_cArray, "append", "push");
+ rb_define_method(rb_cArray, "pop", rb_ary_pop_m, -1);
+ rb_define_method(rb_cArray, "shift", rb_ary_shift_m, -1);
+ rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
+ rb_define_alias(rb_cArray, "prepend", "unshift");
+ rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
+ rb_define_method(rb_cArray, "each", rb_ary_each, 0);
+ 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, "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);
+ rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
+ rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
+ rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
+ rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);
+ rb_define_method(rb_cArray, "rotate", rb_ary_rotate_m, -1);
+ rb_define_method(rb_cArray, "rotate!", rb_ary_rotate_bang, -1);
+ rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
+ rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0);
+ rb_define_method(rb_cArray, "sort_by!", rb_ary_sort_by_bang, 0);
+ rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
+ rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
+ rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
+ 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, "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);
+ rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
+ rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
+ rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
+ rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);
+ rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);
+ rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);
+ rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
+ rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
+ rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
+ rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
+ rb_define_method(rb_cArray, "<=>", rb_ary_cmp, 1);
+
+ rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
+ rb_define_method(rb_cArray, "slice!", rb_ary_slice_bang, -1);
+
+ rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
+ rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
+
+ rb_define_method(rb_cArray, "+", rb_ary_plus, 1);
+ rb_define_method(rb_cArray, "*", rb_ary_times, 1);
+
+ rb_define_method(rb_cArray, "-", rb_ary_diff, 1);
+ rb_define_method(rb_cArray, "&", rb_ary_and, 1);
+ rb_define_method(rb_cArray, "|", rb_ary_or, 1);
+
+ 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, "uniq", rb_ary_uniq, 0);
+ rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
+ rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
+ rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0);
+ 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);
+ rb_define_method(rb_cArray, "repeated_permutation", rb_ary_repeated_permutation, 1);
+ rb_define_method(rb_cArray, "repeated_combination", rb_ary_repeated_combination, 1);
+ rb_define_method(rb_cArray, "product", rb_ary_product, -1);
+
+ rb_define_method(rb_cArray, "take", rb_ary_take, 1);
+ rb_define_method(rb_cArray, "take_while", rb_ary_take_while, 0);
+ rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
+ 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, -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");
}
diff --git a/basictest/runner.rb b/basictest/runner.rb
new file mode 100755
index 0000000000..0f398e7acc
--- /dev/null
+++ b/basictest/runner.rb
@@ -0,0 +1,33 @@
+#! ./miniruby
+
+exit if defined?(CROSS_COMPILING) and CROSS_COMPILING
+ruby = ENV["RUBY"]
+unless ruby
+ load './rbconfig.rb'
+ ruby = "./#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}"
+end
+unless File.exist? ruby
+ print "#{ruby} is not found.\n"
+ print "Try `make' first, then `make test', please.\n"
+ exit false
+end
+ARGV[0] and opt = ARGV[0][/\A--run-opt=(.*)/, 1] and ARGV.shift
+
+$stderr.reopen($stdout)
+error = ''
+
+srcdir = File.expand_path('..', File.dirname(__FILE__))
+if env = ENV["RUBYOPT"]
+ ENV["RUBYOPT"] = env + " -W1"
+end
+`#{ruby} #{opt} -W1 #{srcdir}/basictest/test.rb #{ARGV.join(' ')}`.each_line do |line|
+ if line =~ /^end of test/
+ print "\ntest succeeded\n"
+ exit true
+ end
+ error << line if %r:^(basictest/test.rb|not): =~ line
+end
+puts
+print error
+print "test failed\n"
+exit false
diff --git a/basictest/test.rb b/basictest/test.rb
new file mode 100755
index 0000000000..25d52ca1ef
--- /dev/null
+++ b/basictest/test.rb
@@ -0,0 +1,2367 @@
+#! /usr/bin/env ruby
+# -*- coding: us-ascii -*-
+
+$testnum=0
+$ntest=0
+$failed = 0
+class Progress
+ def initialize
+ @color = nil
+ @tty = nil
+ @quiet = nil
+ @verbose = nil
+ ARGV.each do |arg|
+ case arg
+ when /\A--color(?:=(?:always|(auto)|(never)|(.*)))?\z/
+ warn "unknown --color argument: #$3" if $3
+ @color = $1 ? nil : !$2
+ when /\A--tty(=(?:yes|(no)|(.*)))?\z/
+ warn "unknown --tty argument: #$3" if $3
+ @tty = !$1 || !$2
+ true
+ when /\A-(q|-quiet)\z/
+ @quiet = true
+ when /\A-(v|-verbose)\z/
+ @verbose = true
+ end
+ end
+ @tty = STDERR.tty? && !STDOUT.tty? && /dumb/ !~ ENV["TERM"] if @tty.nil?
+ @eol = @tty && !@verbose ? "\r\e[K\r" : "\n"
+ case @color
+ when nil
+ @color = @tty
+ end
+ if @color
+ # 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|
+ colors[n] ||= c
+ end
+ rescue
+ end
+ @passed = "\e[;#{colors["pass"] || "32"}m"
+ @failed = "\e[;#{colors["fail"] || "31"}m"
+ @reset = "\e[m"
+ else
+ @passed = @failed = @reset = ""
+ end
+ extend(Rotator) if @tty
+ end
+
+ def passed_string
+ "."
+ end
+ def failed_string
+ "#{@failed}F#{@reset}"
+ end
+ def init_string
+ end
+ def finish_string
+ if @quiet
+ @eol
+ else
+ "#{@passed}#{@ok ? 'OK' : ''} #{$testnum}#{@reset}#{@eol}"
+ end
+ end
+ def pass
+ STDERR.print passed_string
+ end
+ def fail
+ @ok = false
+ STDERR.print failed_string
+ end
+ def init
+ @ok = true
+ STDERR.print init_string
+ end
+ def finish
+ STDERR.print finish_string
+ end
+
+ module Rotator
+ ROTATOR = %w[- \\ | /]
+ BS = "\b" * ROTATOR[0].size
+ def passed_string
+ "#{BS}#{ROTATOR[(@count += 1) % ROTATOR.size]}"
+ end
+ def failed_string
+ "#{BS}#{super}#{ROTATOR[@count % ROTATOR.size]}"
+ end
+ def init_string
+ @count = 0
+ " "
+ end
+ def finish_string
+ s = "#{BS}#{' ' * BS.size}#{BS}#{super}"
+ s.gsub!(/\n/, "\r\e[2K\r") if @quiet
+ s
+ end
+ end
+end
+PROGRESS = Progress.new
+
+def test_check(what)
+ unless $ntest.zero?
+ PROGRESS.finish
+ end
+ STDERR.print "#{$0}:#{what} "
+ PROGRESS.init
+ $what = what
+ $testnum = 0
+end
+
+def test_ok(cond,n=1)
+ $testnum+=1
+ $ntest+=1
+ where = (st = caller(n)) ? st[0] : "caller error! (n=#{n}, trace=#{caller(0).join(', ')}"
+ if cond
+ PROGRESS.pass
+ printf "ok %d (%s)\n", $testnum, where
+ else
+ PROGRESS.fail
+ printf "not ok %s %d -- %s\n", $what, $testnum, where
+ $failed+=1
+ end
+ STDOUT.flush
+ STDERR.flush
+end
+
+# make sure conditional operators work
+
+test_check "assignment"
+
+a=[]; a[0] ||= "bar";
+test_ok(a[0] == "bar")
+h={}; h["foo"] ||= "bar";
+test_ok(h["foo"] == "bar")
+
+aa = 5
+aa ||= 25
+test_ok(aa == 5)
+bb ||= 25
+test_ok(bb == 25)
+cc &&=33
+test_ok(cc == nil)
+cc = 5
+cc &&=44
+test_ok(cc == 44)
+
+a = nil; test_ok(a == nil)
+a = 1; test_ok(a == 1)
+a = []; test_ok(a == [])
+a = [1]; test_ok(a == [1])
+a = [nil]; test_ok(a == [nil])
+a = [[]]; test_ok(a == [[]])
+a = [1,2]; test_ok(a == [1,2])
+a = [*[]]; test_ok(a == [])
+a = [*[1]]; test_ok(a == [1])
+a = [*[1,2]]; test_ok(a == [1,2])
+
+a = *[]; test_ok(a == [])
+a = *[1]; test_ok(a == [1])
+a = *[nil]; test_ok(a == [nil])
+a = *[[]]; test_ok(a == [[]])
+a = *[1,2]; test_ok(a == [1,2])
+a = *[*[]]; test_ok(a == [])
+a = *[*[1]]; test_ok(a == [1])
+a = *[*[1,2]]; test_ok(a == [1,2])
+
+a, = nil; test_ok(a == nil)
+a, = 1; test_ok(a == 1)
+a, = []; test_ok(a == nil)
+a, = [1]; test_ok(a == 1)
+a, = [nil]; test_ok(a == nil)
+a, = [[]]; test_ok(a == [])
+a, = 1,2; test_ok(a == 1)
+a, = [1,2]; test_ok(a == 1)
+a, = [*[]]; test_ok(a == nil)
+a, = [*[1]]; test_ok(a == 1)
+a, = *[1,2]; test_ok(a == 1)
+a, = [*[1,2]]; test_ok(a == 1)
+
+a, = *[]; test_ok(a == nil)
+a, = *[1]; test_ok(a == 1)
+a, = *[nil]; test_ok(a == nil)
+a, = *[[]]; test_ok(a == [])
+a, = *[1,2]; test_ok(a == 1)
+a, = *[*[]]; test_ok(a == nil)
+a, = *[*[1]]; test_ok(a == 1)
+a, = *[*[1,2]]; test_ok(a == 1)
+
+*a = nil; test_ok(a == [nil])
+*a = 1; test_ok(a == [1])
+*a = []; test_ok(a == [])
+*a = [1]; test_ok(a == [1])
+*a = [nil]; test_ok(a == [nil])
+*a = [[]]; test_ok(a == [[]])
+*a = [1,2]; test_ok(a == [1,2])
+*a = [*[]]; test_ok(a == [])
+*a = [*[1]]; test_ok(a == [1])
+*a = [*[1,2]]; test_ok(a == [1,2])
+
+*a = *[]; test_ok(a == [])
+*a = *[1]; test_ok(a == [1])
+*a = *[nil]; test_ok(a == [nil])
+*a = *[[]]; test_ok(a == [[]])
+*a = *[1,2]; test_ok(a == [1,2])
+*a = *[*[]]; test_ok(a == [])
+*a = *[*[1]]; test_ok(a == [1])
+*a = *[*[1,2]]; test_ok(a == [1,2])
+
+a,b,*c = nil; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = 1; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = []; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [1]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = [nil]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [[]]; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = [1,2]; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = [*[]]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = [*[1]]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = [*[1,2]]; test_ok([a,b,c] == [1,2,[]])
+
+a,b,*c = *[]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[1]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = *[nil]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[[]]; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = *[1,2]; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = *[*[]]; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = *[*[1]]; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = *[*[1,2]]; test_ok([a,b,c] == [1,2,[]])
+
+def f; yield nil; end; f {|a| test_ok(a == nil)}
+def f; yield 1; end; f {|a| test_ok(a == 1)}
+def f; yield []; end; f {|a| test_ok(a == [])}
+def f; yield [1]; end; f {|a| test_ok(a == [1])}
+def f; yield [nil]; end; f {|a| test_ok(a == [nil])}
+def f; yield [[]]; end; f {|a| test_ok(a == [[]])}
+def f; yield [*[]]; end; f {|a| test_ok(a == [])}
+def f; yield [*[1]]; end; f {|a| test_ok(a == [1])}
+def f; yield [*[1,2]]; end; f {|a| test_ok(a == [1,2])}
+def f; yield *[]; end; f {|a| test_ok(a == nil)}
+def f; yield *[1]; end; f {|a| test_ok(a == 1)}
+def f; yield *[nil]; end; f {|a| test_ok(a == nil)}
+def f; yield *[[]]; end; f {|a| test_ok(a == [])}
+def f; yield *[*[]]; end; f {|a| test_ok(a == nil)}
+def f; yield *[*[1]]; end; f {|a| test_ok(a == 1)}
+def f; yield *[*[1,2]]; end; f {|a| test_ok(a == 1)}
+
+def f; yield; end; f {|a,| test_ok(a == nil)}
+def f; yield nil; end; f {|a,| test_ok(a == nil)}
+def f; yield 1; end; f {|a,| test_ok(a == 1)}
+def f; yield []; end; f {|a,| test_ok(a == nil)}
+def f; yield [1]; end; f {|a,| test_ok(a == 1)}
+def f; yield [nil]; end; f {|a,| test_ok(a == nil)}
+def f; yield [[]]; end; f {|a,| test_ok(a == [])}
+def f; yield [*[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield [*[1]]; end; f {|a,| test_ok(a == 1)}
+def f; yield [*[1,2]]; end; f {|a,| test_ok(a == 1)}
+
+def f; yield *[]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[1]; end; f {|a,| test_ok(a == 1)}
+def f; yield *[nil]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[*[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield *[*[1]]; end; f {|a,| test_ok(a == 1)}
+def f; yield *[*[1,2]]; end; f {|a,| test_ok(a == 1)}
+
+def f; yield; end; f {|*a| test_ok(a == [])}
+def f; yield nil; end; f {|*a| test_ok(a == [nil])}
+def f; yield 1; end; f {|*a| test_ok(a == [1])}
+def f; yield []; end; f {|*a| test_ok(a == [[]])}
+def f; yield [1]; end; f {|*a| test_ok(a == [[1]])}
+def f; yield [nil]; end; f {|*a| test_ok(a == [[nil]])}
+def f; yield [[]]; end; f {|*a| test_ok(a == [[[]]])}
+def f; yield [1,2]; end; f {|*a| test_ok(a == [[1,2]])}
+def f; yield [*[]]; end; f {|*a| test_ok(a == [[]])}
+def f; yield [*[1]]; end; f {|*a| test_ok(a == [[1]])}
+def f; yield [*[1,2]]; end; f {|*a| test_ok(a == [[1,2]])}
+
+def f; yield *[]; end; f {|*a| test_ok(a == [])}
+def f; yield *[1]; end; f {|*a| test_ok(a == [1])}
+def f; yield *[nil]; end; f {|*a| test_ok(a == [nil])}
+def f; yield *[[]]; end; f {|*a| test_ok(a == [[]])}
+def f; yield *[*[]]; end; f {|*a| test_ok(a == [])}
+def f; yield *[*[1]]; end; f {|*a| test_ok(a == [1])}
+def f; yield *[*[1,2]]; end; f {|*a| test_ok(a == [1,2])}
+
+def f; yield; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield 1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
+def f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
+
+def f; yield *[]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield *[nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield *[*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield *[*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
+
+def r; return; end; a = r(); test_ok(a == nil)
+def r; return nil; end; a = r(); test_ok(a == nil)
+def r; return 1; end; a = r(); test_ok(a == 1)
+def r; return []; end; a = r(); test_ok(a == [])
+def r; return [1]; end; a = r(); test_ok(a == [1])
+def r; return [nil]; end; a = r(); test_ok(a == [nil])
+def r; return [[]]; end; a = r(); test_ok(a == [[]])
+def r; return [*[]]; end; a = r(); test_ok(a == [])
+def r; return [*[1]]; end; a = r(); test_ok(a == [1])
+def r; return [*[1,2]]; end; a = r(); test_ok(a == [1,2])
+
+def r; return *[]; end; a = r(); test_ok(a == [])
+def r; return *[1]; end; a = r(); test_ok(a == [1])
+def r; return *[nil]; end; a = r(); test_ok(a == [nil])
+def r; return *[[]]; end; a = r(); test_ok(a == [[]])
+def r; return *[*[]]; end; a = r(); test_ok(a == [])
+def r; return *[*[1]]; end; a = r(); test_ok(a == [1])
+def r; return *[*[1,2]]; end; a = r(); test_ok(a == [1,2])
+
+def r; return *[[]]; end; a = *r(); test_ok(a == [[]])
+def r; return *[*[1,2]]; end; a = *r(); test_ok(a == [1,2])
+
+def r; return; end; *a = r(); test_ok(a == [nil])
+def r; return nil; end; *a = r(); test_ok(a == [nil])
+def r; return 1; end; *a = r(); test_ok(a == [1])
+def r; return []; end; *a = r(); test_ok(a == [])
+def r; return [1]; end; *a = r(); test_ok(a == [1])
+def r; return [nil]; end; *a = r(); test_ok(a == [nil])
+def r; return [[]]; end; *a = r(); test_ok(a == [[]])
+def r; return [1,2]; end; *a = r(); test_ok(a == [1,2])
+def r; return [*[]]; end; *a = r(); test_ok(a == [])
+def r; return [*[1]]; end; *a = r(); test_ok(a == [1])
+def r; return [*[1,2]]; end; *a = r(); test_ok(a == [1,2])
+
+def r; return *[]; end; *a = r(); test_ok(a == [])
+def r; return *[1]; end; *a = r(); test_ok(a == [1])
+def r; return *[nil]; end; *a = r(); test_ok(a == [nil])
+def r; return *[[]]; end; *a = r(); test_ok(a == [[]])
+def r; return *[1,2]; end; *a = r(); test_ok(a == [1,2])
+def r; return *[*[]]; end; *a = r(); test_ok(a == [])
+def r; return *[*[1]]; end; *a = r(); test_ok(a == [1])
+def r; return *[*[1,2]]; end; *a = r(); test_ok(a == [1,2])
+
+def r; return *[[]]; end; *a = *r(); test_ok(a == [[]])
+def r; return *[1,2]; end; *a = *r(); test_ok(a == [1,2])
+def r; return *[*[1,2]]; end; *a = *r(); test_ok(a == [1,2])
+
+def r; return; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return nil; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return 1; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return []; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return [nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]])
+def r; return [1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+def r; return [*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return [*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return [*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+
+def r; return *[]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return *[nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]])
+def r; return *[1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+def r; return *[*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])
+def r; return *[*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])
+def r; return *[*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])
+
+f = lambda {|r,| test_ok([] == r)}
+f.call([], *[])
+
+f = lambda {|r,*l| test_ok([] == r); test_ok([1] == l)}
+f.call([], *[1])
+
+f = lambda{|x| x}
+test_ok(f.call(42) == 42)
+test_ok(f.call([42]) == [42])
+test_ok(f.call([[42]]) == [[42]])
+test_ok(f.call([42,55]) == [42,55])
+
+f = lambda{|x,| x}
+test_ok(f.call(42) == 42)
+test_ok(f.call([42]) == [42])
+test_ok(f.call([[42]]) == [[42]])
+test_ok(f.call([42,55]) == [42,55])
+
+f = lambda{|*x| x}
+test_ok(f.call(42) == [42])
+test_ok(f.call([42]) == [[42]])
+test_ok(f.call([[42]]) == [[[42]]])
+test_ok(f.call([42,55]) == [[42,55]])
+test_ok(f.call(42,55) == [42,55])
+
+f = lambda { |a, b=42, *c| [a,b,c] }
+test_ok(f.call(1 ) == [1,42,[ ]] )
+test_ok(f.call(1,43 ) == [1,43,[ ]] )
+test_ok(f.call(1,43,44) == [1,43,[44]] )
+
+f = lambda { |a, b=(a|16), *c, &block| [a,b,c,block&&block[]] }
+test_ok(f.call(8 ) == [8,24,[ ],nil] )
+test_ok(f.call(8,43 ) == [8,43,[ ],nil] )
+test_ok(f.call(8,43,44) == [8,43,[44],nil] )
+test_ok(f.call(8 ){45} == [8,24,[ ],45 ] )
+test_ok(f.call(8,43 ){45} == [8,43,[ ],45 ] )
+test_ok(f.call(8,43,44){45} == [8,43,[44],45 ] )
+
+f = lambda { |a, b=42, *c, d| [a,b,c,d] }
+test_ok(f.call(1 ,99) == [1,42,[ ],99] )
+test_ok(f.call(1,43 ,99) == [1,43,[ ],99] )
+test_ok(f.call(1,43,44,99) == [1,43,[44],99] )
+
+f = lambda { |a, b=(a|16), &block| [a,b,block&&block[]] }
+test_ok(f.call(8 ) == [8,24,nil] )
+test_ok(f.call(8,43) == [8,43,nil] )
+test_ok(f.call(8,43) == [8,43,nil] )
+test_ok(f.call(8 ){45} == [8,24,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+
+f = lambda { |a, b=42, d| [a,b,d] }
+test_ok(f.call(1 ,99) == [1,42,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+
+f = lambda { |b=42, *c, &block| [b,c,block&&block[]] }
+test_ok(f.call( ) == [42,[ ],nil] )
+test_ok(f.call(43 ) == [43,[ ],nil] )
+test_ok(f.call(43,44) == [43,[44],nil] )
+test_ok(f.call( ){45} == [42,[ ],45 ] )
+test_ok(f.call(43 ){45} == [43,[ ],45 ] )
+test_ok(f.call(43,44){45} == [43,[44],45 ] )
+
+f = lambda { |b=42, *c, d| [b,c,d] }
+test_ok(f.call( 99) == [42,[ ],99] )
+test_ok(f.call(43 ,99) == [43,[ ],99] )
+test_ok(f.call(43,44,99) == [43,[44],99] )
+
+f = lambda { |b=42, &block| [b,block&&block[]] }
+test_ok(f.call( ) == [42,nil] )
+test_ok(f.call(43) == [43,nil] )
+test_ok(f.call(43) == [43,nil] )
+test_ok(f.call( ){45} == [42,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+
+f = lambda { |b=42, d| [b,d] }
+test_ok(f.call( 99) == [42,99] )
+test_ok(f.call(43,99) == [43,99] )
+test_ok(f.call(43,99) == [43,99] )
+
+
+a,=*[1]
+test_ok(a == 1)
+a,=*[[1]]
+test_ok(a == [1])
+a,=*[[[1]]]
+test_ok(a == [[1]])
+
+x, (y, z) = 1, 2, 3
+test_ok([1,2,nil] == [x,y,z])
+x, (y, z) = 1, [2,3]
+test_ok([1,2,3] == [x,y,z])
+x, (y, z) = 1, [2]
+test_ok([1,2,nil] == [x,y,z])
+
+a = loop do break; end; test_ok(a == nil)
+a = loop do break nil; end; test_ok(a == nil)
+a = loop do break 1; end; test_ok(a == 1)
+a = loop do break []; end; test_ok(a == [])
+a = loop do break [1]; end; test_ok(a == [1])
+a = loop do break [nil]; end; test_ok(a == [nil])
+a = loop do break [[]]; end; test_ok(a == [[]])
+a = loop do break [*[]]; end; test_ok(a == [])
+a = loop do break [*[1]]; end; test_ok(a == [1])
+a = loop do break [*[1,2]]; end; test_ok(a == [1,2])
+
+a = loop do break *[]; end; test_ok(a == [])
+a = loop do break *[1]; end; test_ok(a == [1])
+a = loop do break *[nil]; end; test_ok(a == [nil])
+a = loop do break *[[]]; end; test_ok(a == [[]])
+a = loop do break *[*[]]; end; test_ok(a == [])
+a = loop do break *[*[1]]; end; test_ok(a == [1])
+a = loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+*a = loop do break; end; test_ok(a == [nil])
+*a = loop do break nil; end; test_ok(a == [nil])
+*a = loop do break 1; end; test_ok(a == [1])
+*a = loop do break []; end; test_ok(a == [])
+*a = loop do break [1]; end; test_ok(a == [1])
+*a = loop do break [nil]; end; test_ok(a == [nil])
+*a = loop do break [[]]; end; test_ok(a == [[]])
+*a = loop do break [1,2]; end; test_ok(a == [1,2])
+*a = loop do break [*[]]; end; test_ok(a == [])
+*a = loop do break [*[1]]; end; test_ok(a == [1])
+*a = loop do break [*[1,2]]; end; test_ok(a == [1,2])
+
+*a = loop do break *[]; end; test_ok(a == [])
+*a = loop do break *[1]; end; test_ok(a == [1])
+*a = loop do break *[nil]; end; test_ok(a == [nil])
+*a = loop do break *[[]]; end; test_ok(a == [[]])
+*a = loop do break *[1,2]; end; test_ok(a == [1,2])
+*a = loop do break *[*[]]; end; test_ok(a == [])
+*a = loop do break *[*[1]]; end; test_ok(a == [1])
+*a = loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+*a = *loop do break *[[]]; end; test_ok(a == [[]])
+*a = *loop do break *[1,2]; end; test_ok(a == [1,2])
+*a = *loop do break *[*[1,2]]; end; test_ok(a == [1,2])
+
+a,b,*c = loop do break; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break nil; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break 1; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break []; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [1]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break [nil]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [[]]; end; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = loop do break [1,2]; end; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = loop do break [*[]]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break [*[1]]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break [*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])
+
+a,b,*c = loop do break *[]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[1]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break *[nil]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[[]]; end; test_ok([a,b,c] == [[],nil,[]])
+a,b,*c = loop do break *[1,2]; end; test_ok([a,b,c] == [1,2,[]])
+a,b,*c = loop do break *[*[]]; end; test_ok([a,b,c] == [nil,nil,[]])
+a,b,*c = loop do break *[*[1]]; end; test_ok([a,b,c] == [1,nil,[]])
+a,b,*c = loop do break *[*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])
+
+def r(val); a = yield(); test_ok(a == val, 2); end
+r(nil){next}
+r(nil){next nil}
+r(1){next 1}
+r([]){next []}
+r([1]){next [1]}
+r([nil]){next [nil]}
+r([[]]){next [[]]}
+r([]){next [*[]]}
+r([1]){next [*[1]]}
+r([1,2]){next [*[1,2]]}
+
+r([]){next *[]}
+r([1]){next *[1]}
+r([nil]){next *[nil]}
+r([[]]){next *[[]]}
+r([]){next *[*[]]}
+r([1]){next *[*[1]]}
+r([1,2]){next *[*[1,2]]}
+
+def r(val); *a = yield(); test_ok(a == val, 2); end
+r([nil]){next}
+r([nil]){next nil}
+r([1]){next 1}
+r([]){next []}
+r([1]){next [1]}
+r([nil]){next [nil]}
+r([[]]){next [[]]}
+r([1,2]){next [1,2]}
+r([]){next [*[]]}
+r([1]){next [*[1]]}
+r([1,2]){next [*[1,2]]}
+
+def r(val); *a = *yield(); test_ok(a == val, 2); end
+r([[]]){next *[[]]}
+r([1,2]){next *[1,2]}
+r([1,2]){next *[*[1,2]]}
+
+def r(val); a,b,*c = yield(); test_ok([a,b,c] == val, 2); end
+r([nil,nil,[]]){next}
+r([nil,nil,[]]){next nil}
+r([1,nil,[]]){next 1}
+r([nil,nil,[]]){next []}
+r([1,nil,[]]){next [1]}
+r([nil,nil,[]]){next [nil]}
+r([[],nil,[]]){next [[]]}
+r([1,2,[]]){next [1,2]}
+r([nil,nil,[]]){next [*[]]}
+r([1,nil,[]]){next [*[1]]}
+r([1,2,[]]){next [*[1,2]]}
+
+def r(val); a,b,*c = *yield(); test_ok([a,b,c] == val, 2); end
+r([[],nil,[]]){next *[[]]}
+r([1,2,[]]){next *[1,2]}
+r([1,2,[]]){next *[*[1,2]]}
+
+test_check "condition"
+
+$x = '0';
+
+$x == $x && test_ok(true)
+$x != $x && test_ok(false)
+$x == $x || test_ok(false)
+$x != $x || test_ok(true)
+
+# first test to see if we can run the tests.
+
+test_check "if/unless";
+
+$x = 'test';
+test_ok(if $x == $x then true else false end)
+$bad = false
+unless $x == $x
+ $bad = true
+end
+test_ok(!$bad)
+test_ok(unless $x != $x then true else false end)
+
+test_check "case"
+
+case 5
+when 1, 2, 3, 4, 6, 7, 8
+ test_ok(false)
+when 5
+ test_ok(true)
+end
+
+case 5
+when 5
+ test_ok(true)
+when 1..10
+ test_ok(false)
+end
+
+case 5
+when 1..10
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+case 5
+when 5
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+case "foobar"
+when /^f.*r$/
+ test_ok(true)
+else
+ test_ok(false)
+end
+
+test_check "while/until";
+
+while_tmp = "while_tmp.#{$$}"
+tmp = open(while_tmp, "w")
+tmp.print "tvi925\n";
+tmp.print "tvi920\n";
+tmp.print "vt100\n";
+tmp.print "Amiga\n";
+tmp.print "paper\n";
+tmp.close
+
+# test break
+
+tmp = open(while_tmp, "r")
+test_ok(tmp.kind_of?(File))
+
+while line = tmp.gets()
+ break if /vt100/ =~ line
+end
+
+test_ok(!tmp.eof? && /vt100/ =~ line)
+tmp.close
+
+# test next
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ next if /vt100/ =~ line
+ $bad = 1 if /vt100/ =~ line
+end
+test_ok(!(!tmp.eof? || /vt100/ =~ line || $bad))
+tmp.close
+
+# test redo
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ lastline = line
+ line = line.gsub(/vt100/, 'VT100')
+ if lastline != line
+ line.gsub!('VT100', 'Vt100')
+ redo
+ end
+ $bad = 1 if /vt100/ =~ line
+ $bad = 1 if /VT100/ =~ line
+end
+test_ok(tmp.eof? && !$bad)
+tmp.close
+
+sum=0
+for i in 1..10
+ sum += i
+ i -= 1
+ if i > 0
+ redo
+ end
+end
+test_ok(sum == 220)
+
+# test interval
+$bad = false
+tmp = open(while_tmp, "r")
+while line = tmp.gets()
+ break if 3
+ case line
+ when /vt100/, /Amiga/, /paper/
+ $bad = true
+ end
+end
+test_ok(!$bad)
+tmp.close
+
+File.unlink while_tmp or `/bin/rm -f "#{while_tmp}"`
+test_ok(!File.exist?(while_tmp))
+
+i = 0
+until i>4
+ i+=1
+end
+test_ok(i>4)
+
+
+# exception handling
+test_check "exception";
+
+begin
+ raise "this must be handled"
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+$bad = true
+begin
+ raise "this must be handled no.2"
+rescue
+ if $bad
+ $bad = false
+ retry
+ test_ok(false)
+ end
+end
+test_ok(true)
+
+# exception in rescue clause
+$string = "this must be handled no.3"
+begin
+ begin
+ raise "exception in rescue clause"
+ rescue
+ raise $string
+ end
+ test_ok(false)
+rescue => e
+ test_ok($! == e)
+ test_ok(e.message == $string)
+ test_ok(e != $string)
+end
+
+# exception in ensure clause
+begin
+ begin
+ raise "this must be handled no.4"
+ ensure
+ raise "exception in ensure clause"
+ end
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+$bad = true
+begin
+ begin
+ raise "this must be handled no.5"
+ ensure
+ $bad = false
+ end
+rescue
+end
+test_ok(!$bad)
+
+$bad = true
+begin
+ begin
+ raise "this must be handled no.6"
+ ensure
+ $bad = false
+ end
+rescue
+end
+test_ok(!$bad)
+
+$bad = true
+while true
+ begin
+ break
+ ensure
+ $bad = false
+ end
+end
+test_ok(!$bad)
+
+test_ok(catch(:foo) {
+ loop do
+ loop do
+ throw :foo, true
+ break
+ end
+ break
+ test_ok(false) # should not reach here
+ end
+ false
+ })
+
+test_check "array"
+test_ok([1, 2] + [3, 4] == [1, 2, 3, 4])
+test_ok([1, 2] * 2 == [1, 2, 1, 2])
+test_ok([1, 2] * ":" == "1:2")
+
+test_ok([1, 2].hash == [1, 2].hash)
+
+test_ok([1,2,3] & [2,3,4] == [2,3])
+test_ok([1,2,3] | [2,3,4] == [1,2,3,4])
+test_ok([1,2,3] - [2,3] == [1])
+
+$x = [0, 1, 2, 3, 4, 5]
+test_ok($x[2] == 2)
+test_ok($x[1..3] == [1, 2, 3])
+test_ok($x[1,3] == [1, 2, 3])
+
+$x[0, 2] = 10
+test_ok($x[0] == 10 && $x[1] == 2)
+
+$x[0, 0] = -1
+test_ok($x[0] == -1 && $x[1] == 10)
+
+$x[-1, 1] = 20
+test_ok($x[-1] == 20 && $x.pop == 20)
+
+# array and/or
+test_ok(([1,2,3]&[2,4,6]) == [2])
+test_ok(([1,2,3]|[2,4,6]) == [1,2,3,4,6])
+
+# compact
+$x = [nil, 1, nil, nil, 5, nil, nil]
+$x.compact!
+test_ok($x == [1, 5])
+
+# uniq
+$x = [1, 1, 4, 2, 5, 4, 5, 1, 2]
+$x.uniq!
+test_ok($x == [1, 4, 2, 5])
+
+# empty?
+test_ok(!$x.empty?)
+$x = []
+test_ok($x.empty?)
+
+# sort
+$x = ["it", "came", "to", "pass", "that", "..."]
+$x = $x.sort.join(" ")
+test_ok($x == "... came it pass that to")
+$x = [2,5,3,1,7]
+$x.sort!{|a,b| a<=>b} # sort with condition
+test_ok($x == [1,2,3,5,7])
+$x.sort!{|a,b| b-a} # reverse sort
+test_ok($x == [7,5,3,2,1])
+
+# split test
+$x = "The Book of Mormon"
+test_ok($x.split(//).reverse!.join == $x.reverse)
+test_ok($x.reverse == $x.reverse!)
+test_ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1")
+$x = "a b c d"
+test_ok($x.split == ['a', 'b', 'c', 'd'])
+test_ok($x.split(' ') == ['a', 'b', 'c', 'd'])
+test_ok(defined? "a".chomp)
+test_ok("abc".scan(/./) == ["a", "b", "c"])
+test_ok("1a2b3c".scan(/(\d.)/) == [["1a"], ["2b"], ["3c"]])
+# non-greedy match
+test_ok("a=12;b=22".scan(/(.*?)=(\d*);?/) == [["a", "12"], ["b", "22"]])
+
+$x = [1]
+test_ok(($x * 5).join(":") == '1:1:1:1:1')
+test_ok(($x * 1).join(":") == '1')
+test_ok(($x * 0).join(":") == '')
+
+*$x = *(1..7).to_a
+test_ok($x.size == 7)
+test_ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+$x = [1,2,3]
+$x[1,0] = $x
+test_ok($x == [1,1,2,3,2,3])
+
+$x = [1,2,3]
+$x[-1,0] = $x
+test_ok($x == [1,2,1,2,3,3])
+
+$x = [1,2,3]
+$x.concat($x)
+test_ok($x == [1,2,3,1,2,3])
+
+test_check "hash"
+$x = {1=>2, 2=>4, 3=>6}
+
+test_ok($x[1] == 2)
+
+test_ok(begin
+ for k,v in $x
+ raise if k*2 != v
+ end
+ true
+ rescue
+ false
+ end)
+
+test_ok($x.length == 3)
+test_ok($x.has_key?(1))
+test_ok($x.has_value?(4))
+test_ok($x.values_at(2,3) == [4,6])
+test_ok($x == {1=>2, 2=>4, 3=>6})
+
+$z = $x.keys.sort.join(":")
+test_ok($z == "1:2:3")
+
+$z = $x.values.sort.join(":")
+test_ok($z == "2:4:6")
+test_ok($x == $x)
+
+$x.shift
+test_ok($x.length == 2)
+
+$z = [1,2]
+$x[$z] = 256
+test_ok($x[$z] == 256)
+
+$x = Hash.new(0)
+$x[1] = 1
+test_ok($x[1] == 1)
+test_ok($x[2] == 0)
+
+$x = Hash.new([])
+test_ok($x[22] == [])
+test_ok($x[22].equal?($x[22]))
+
+$x = Hash.new{[]}
+test_ok($x[22] == [])
+test_ok(!$x[22].equal?($x[22]))
+
+$x = Hash.new{|h,k| $z = k; h[k] = k*2}
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 22)
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 0)
+$x.default = 5
+test_ok($x[23] == 5)
+
+$x = Hash.new
+def $x.default(k)
+ $z = k
+ self[k] = k*2
+end
+$z = 0
+test_ok($x[22] == 44)
+test_ok($z == 22)
+$z = 0
+test_ok($x[22] == 44)
+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))
+
+$x = [1, 2, 3, 4]
+$y = []
+
+# iterator over array
+for i in $x
+ $y.push i
+end
+test_ok($x == $y)
+
+# nested iterator
+def tt
+ 1.upto(10) {|i|
+ yield i
+ }
+end
+
+i=0
+tt{|i| break if i == 5}
+test_ok(i == 0)
+
+def tt2(dummy)
+ yield 1
+end
+
+def tt3(&block)
+ tt2(raise(ArgumentError,""),&block)
+end
+
+$x = false
+begin
+ tt3{}
+rescue ArgumentError
+ $x = true
+rescue Exception
+end
+test_ok($x)
+
+def tt4 &block
+ tt2(raise(ArgumentError,""),&block)
+end
+$x = false
+begin
+ tt4{}
+rescue ArgumentError
+ $x = true
+rescue Exception
+end
+test_ok($x)
+
+# iterator break/redo/next/retry
+done = true
+loop{
+ break
+ done = false # should not reach here
+}
+test_ok(done)
+
+done = false
+$bad = false
+loop {
+ break if done
+ done = true
+ next
+ $bad = true # should not reach here
+}
+test_ok(!$bad)
+
+done = false
+$bad = false
+loop {
+ break if done
+ done = true
+ redo
+ $bad = true # should not reach here
+}
+test_ok(!$bad)
+
+$x = []
+for i in 1 .. 7
+ $x.push i
+end
+test_ok($x.size == 7)
+test_ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+# append method to built-in class
+class Array
+ def iter_test1
+ collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
+ end
+ def iter_test2
+ a = collect{|e| [e, yield(e)]}
+ a.sort{|a,b|a[1]<=>b[1]}
+ end
+end
+$x = [[1,2],[3,4],[5,6]]
+test_ok($x.iter_test1{|x|x} == $x.iter_test2{|x|x})
+
+class IterTest
+ def initialize(e); @body = e; end
+
+ def each0(&block); @body.each(&block); end
+ def each1(&block); @body.each {|*x| block.call(*x) } end
+ def each2(&block); @body.each {|*x| block.call(x) } end
+ def each3(&block); @body.each {|x| block.call(*x) } end
+ def each4(&block); @body.each {|x| block.call(x) } end
+ def each5; @body.each {|*x| yield(*x) } end
+ def each6; @body.each {|*x| yield(x) } end
+ def each7; @body.each {|x| yield(*x) } end
+ def each8; @body.each {|x| yield(x) } end
+
+ def f(a)
+ a
+ end
+end
+test_ok(IterTest.new(nil).method(:f).to_proc.call([1]) == [1])
+m = /\w+/.match("abc")
+test_ok(IterTest.new(nil).method(:f).to_proc.call([m]) == [m])
+
+IterTest.new([0]).each0 {|x| test_ok(x == 0)}
+IterTest.new([1]).each1 {|x| test_ok(x == 1)}
+IterTest.new([2]).each2 {|x| test_ok(x == [2])}
+#IterTest.new([3]).each3 {|x| test_ok(x == 3)}
+IterTest.new([4]).each4 {|x| test_ok(x == 4)}
+IterTest.new([5]).each5 {|x| test_ok(x == 5)}
+IterTest.new([6]).each6 {|x| test_ok(x == [6])}
+#IterTest.new([7]).each7 {|x| test_ok(x == 7)}
+IterTest.new([8]).each8 {|x| test_ok(x == 8)}
+
+IterTest.new([[0]]).each0 {|x| test_ok(x == [0])}
+IterTest.new([[1]]).each1 {|x| test_ok(x == [1])}
+IterTest.new([[2]]).each2 {|x| test_ok(x == [[2]])}
+IterTest.new([[3]]).each3 {|x| test_ok(x == 3)}
+IterTest.new([[4]]).each4 {|x| test_ok(x == [4])}
+IterTest.new([[5]]).each5 {|x| test_ok(x == [5])}
+IterTest.new([[6]]).each6 {|x| test_ok(x == [[6]])}
+IterTest.new([[7]]).each7 {|x| test_ok(x == 7)}
+IterTest.new([[8]]).each8 {|x| test_ok(x == [8])}
+
+IterTest.new([[0,0]]).each0 {|*x| test_ok(x == [[0,0]])}
+IterTest.new([[8,8]]).each8 {|*x| test_ok(x == [[8,8]])}
+
+def m0(v)
+ v
+end
+
+def m1
+ m0(block_given?)
+end
+test_ok(m1{p 'test'})
+test_ok(!m1)
+
+def m
+ m0(block_given?,&Proc.new{})
+end
+test_ok(m1{p 'test'})
+test_ok(!m1)
+
+class C
+ include Enumerable
+ def initialize
+ @a = [1,2,3]
+ end
+ def each(&block)
+ @a.each(&block)
+ end
+end
+
+test_ok(C.new.collect{|n| n} == [1,2,3])
+
+test_ok(Proc == lambda{}.class)
+test_ok(Proc == Proc.new{}.class)
+lambda{|a|test_ok(a==1)}.call(1)
+def block_test(klass, &block)
+ test_ok(klass === block)
+end
+
+block_test(NilClass)
+block_test(Proc){}
+
+def call_argument_test(state, proc, *args)
+ x = state
+ begin
+ proc.call(*args)
+ rescue ArgumentError
+ x = !x
+ end
+ test_ok(x,2)
+end
+
+call_argument_test(true, lambda{||})
+call_argument_test(false, lambda{||}, 1)
+call_argument_test(true, lambda{|a,|}, 1)
+call_argument_test(false, lambda{|a,|})
+call_argument_test(false, lambda{|a,|}, 1,2)
+
+call_argument_test(true, Proc.new{||})
+call_argument_test(true, Proc.new{||}, 1)
+call_argument_test(true, Proc.new{|a,|}, 1)
+call_argument_test(true, Proc.new{|a,|})
+call_argument_test(true, Proc.new{|a,|}, 1,2)
+
+def block_get(&block)
+ block
+end
+
+test_ok(Proc == block_get{}.class)
+call_argument_test(true, block_get{||})
+call_argument_test(true, block_get{||}, 1)
+call_argument_test(true, block_get{|a,|}, 1)
+call_argument_test(true, block_get{|a,|})
+call_argument_test(true, block_get{|a,|}, 1,2)
+
+call_argument_test(true, block_get(&lambda{||}))
+call_argument_test(false, block_get(&lambda{||}),1)
+call_argument_test(true, block_get(&lambda{|a,|}),1)
+call_argument_test(false, block_get(&lambda{|a,|}),1,2)
+
+blk = block_get{11}
+test_ok(blk.class == Proc)
+test_ok(blk.to_proc.class == Proc)
+test_ok(blk.clone.call == 11)
+test_ok(block_get(&blk).class == Proc)
+
+lmd = lambda{44}
+test_ok(lmd.class == Proc)
+test_ok(lmd.to_proc.class == Proc)
+test_ok(lmd.clone.call == 44)
+test_ok(block_get(&lmd).class == Proc)
+
+test_ok(Proc.new{|a,| a}.yield(1,2,3) == 1)
+call_argument_test(true, Proc.new{|a,|}, 1,2)
+
+test_ok(Proc.new{|&b| b.call(10)}.call {|x| x} == 10)
+test_ok(Proc.new{|a,&b| b.call(a)}.call(12) {|x| x} == 12)
+
+def test_return1
+ Proc.new {
+ return 55
+ }.yield + 5
+end
+test_ok(test_return1() == 55)
+def test_return2
+ lambda {
+ return 55
+ }.call + 5
+end
+test_ok(test_return2() == 60)
+
+def proc_call(&b)
+ b.call
+end
+def proc_yield()
+ yield
+end
+def proc_return1
+ lambda{return 42}.call+1
+end
+test_ok(proc_return1() == 43)
+def proc_return2
+ ->{return 42}.call+1
+end
+test_ok(proc_return2() == 43)
+def proc_return3
+ proc_call{return 42}+1
+end
+test_ok(proc_return3() == 42)
+def proc_return4
+ proc_yield{return 42}+1
+end
+test_ok(proc_return4() == 42)
+
+def ljump_test(state, proc, *args)
+ x = state
+ begin
+ proc.call(*args)
+ rescue LocalJumpError
+ x = !x
+ end
+ test_ok(x,2)
+end
+
+ljump_test(false, block_get{break})
+ljump_test(true, lambda{break})
+
+def exit_value_test(&block)
+ block.call
+rescue LocalJumpError
+ $!.exit_value
+end
+
+test_ok(45 == exit_value_test{break 45})
+
+test_ok(55 == begin
+ block_get{break 55}.call
+ rescue LocalJumpError
+ $!.exit_value
+ end)
+
+def block_call(&block)
+ block.call
+end
+
+def test_b1
+ block_call{break 11}
+end
+test_ok(test_b1() == 11)
+
+def ljump_rescue(r)
+ begin
+ yield
+ rescue LocalJumpError => e
+ r if /from proc-closure/ =~ e.message
+ end
+end
+
+def test_b2
+ ljump_rescue(22) do
+ block_get{break 21}.call
+ end
+end
+test_ok(test_b2() == 22)
+
+def test_b3
+ ljump_rescue(33) do
+ Proc.new{break 31}.yield
+ end
+end
+test_ok(test_b3() == 33)
+
+def test_b4
+ lambda{break 44}.call
+end
+test_ok(test_b4() == 44)
+
+def test_b5
+ ljump_rescue(55) do
+ b = block_get{break 54}
+ block_call(&b)
+ end
+end
+test_ok(test_b5() == 55)
+
+def test_b6
+ b = lambda{break 67}
+ block_call(&b)
+ 66
+end
+test_ok(test_b6() == 66)
+
+def util_r7
+ block_get{break 78}
+end
+
+def test_b7
+ b = util_r7()
+ ljump_rescue(77) do
+ block_call(&b)
+ end
+end
+test_ok(test_b7() == 77)
+
+def util_b8(&block)
+ block_call(&block)
+end
+
+def test_b8
+ util_b8{break 88}
+end
+test_ok(test_b8() == 88)
+
+def util_b9(&block)
+ lambda{block.call; 98}.call
+end
+
+def test_b9
+ util_b9{break 99}
+end
+test_ok(test_b9() == 99)
+
+def util_b10
+ util_b9{break 100}
+end
+
+def test_b10
+ util_b10()
+end
+test_ok(test_b10() == 100)
+
+def test_b11
+ ljump_rescue(111) do
+ loop do
+ Proc.new{break 110}.yield
+ break 112
+ end
+ end
+end
+test_ok(test_b11() == 111)
+
+def test_b12
+ loop do
+ break lambda{break 122}.call
+ break 121
+ end
+end
+test_ok(test_b12() == 122)
+
+def test_b13
+ ljump_rescue(133) do
+ while true
+ Proc.new{break 130}.yield
+ break 131
+ end
+ end
+end
+test_ok(test_b13() == 133)
+
+def test_b14
+ while true
+ break lambda{break 144}.call
+ break 143
+ end
+end
+test_ok(test_b14() == 144)
+
+def test_b15
+ [0].each {|c| yield 1 }
+ 156
+end
+test_ok(test_b15{|e| break 155 } == 155)
+
+def marity_test(m)
+ method = method(m)
+ test_ok(method.arity == method.to_proc.arity, 2)
+end
+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?
+ end
+end
+
+class ITER_TEST2 < ITER_TEST1
+ def a
+ test_ok(super)
+ super
+ end
+end
+test_ok(ITER_TEST2.new.a {})
+
+class ITER_TEST3
+ def foo x
+ return yield if block_given?
+ x
+ end
+end
+
+class ITER_TEST4 < ITER_TEST3
+ def foo x
+ test_ok(super == yield)
+ test_ok(super(x, &nil) == x)
+ end
+end
+
+ITER_TEST4.new.foo(44){55}
+
+class ITER_TEST5
+ def tt(aa)
+ aa
+ end
+
+ def uu(a)
+ class << self
+ define_method(:tt) do |sym|
+ super(sym)
+ end
+ end
+ end
+
+ def xx(*x)
+ x.size
+ end
+end
+
+a = ITER_TEST5.new
+a.uu(12)
+test_ok(a.tt(1) == 1)
+
+class ITER_TEST6 < ITER_TEST5
+ def xx(*a)
+ a << 12
+ super
+ end
+end
+
+test_ok(ITER_TEST6.new.xx([24]) == 2)
+
+test_check "float"
+test_ok(2.6.floor == 2)
+test_ok((-2.6).floor == -3)
+test_ok(2.6.ceil == 3)
+test_ok((-2.6).ceil == -2)
+test_ok(2.6.truncate == 2)
+test_ok((-2.6).truncate == -2)
+test_ok(2.6.round == 3)
+test_ok((-2.4).truncate == -2)
+test_ok((13.4 % 1 - 0.4).abs < 0.0001)
+nan = 0.0/0
+def nan_test(x,y)
+ test_ok(x != y)
+ test_ok((x < y) == false)
+ test_ok((x > y) == false)
+ test_ok((x <= y) == false)
+ test_ok((x >= y) == false)
+end
+nan_test(nan, nan)
+nan_test(nan, 0)
+nan_test(nan, 1)
+nan_test(nan, -1)
+nan_test(nan, 1000)
+nan_test(nan, -1000)
+nan_test(nan, 1_000_000_000_000)
+nan_test(nan, -1_000_000_000_000)
+nan_test(nan, 100.0);
+nan_test(nan, -100.0);
+nan_test(nan, 0.001);
+nan_test(nan, -0.001);
+nan_test(nan, 1.0/0);
+nan_test(nan, -1.0/0);
+
+#s = "3.7517675036461267e+17"
+#test_ok(s == sprintf("%.16e", s.to_f))
+f = 3.7517675036461267e+17
+test_ok(f == sprintf("%.16e", f).to_f)
+
+
+test_check "bignum"
+def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+end
+$x = fact(40)
+test_ok($x == $x)
+test_ok($x == fact(40))
+test_ok($x < $x+2)
+test_ok($x > $x-2)
+test_ok($x == 815915283247897734345611269596115894272000000000)
+test_ok($x != 815915283247897734345611269596115894272000000001)
+test_ok($x+1 == 815915283247897734345611269596115894272000000001)
+test_ok($x/fact(20) == 335367096786357081410764800000)
+$x = -$x
+test_ok($x == -815915283247897734345611269596115894272000000000)
+test_ok(2-(2**32) == -(2**32-2))
+test_ok(2**32 - 5 == (2**32-3)-2)
+
+$good = true;
+for i in 1000..1014
+ $good = false if ((1 << i) != (2**i))
+end
+test_ok($good)
+
+$good = true;
+n1= 1 << 1000
+for i in 1000..1014
+ $good = false if ((1 << i) != n1)
+ n1 *= 2
+end
+test_ok($good)
+
+$good = true;
+n2=n1
+for i in 1..10
+ n1 = n1 / 2
+ n2 = n2 >> 1
+ $good = false if (n1 != n2)
+end
+test_ok($good)
+
+$good = true;
+for i in 4000..4096
+ n1 = 1 << i;
+ if (n1**2-1) / (n1+1) != (n1-1)
+ $good = false
+ end
+end
+test_ok($good)
+
+b = 10**80
+a = b * 9 + 7
+test_ok(7 == a.modulo(b))
+test_ok(-b + 7 == a.modulo(-b))
+test_ok(b + -7 == (-a).modulo(b))
+test_ok(-7 == (-a).modulo(-b))
+test_ok(7 == a.remainder(b))
+test_ok(7 == a.remainder(-b))
+test_ok(-7 == (-a).remainder(b))
+test_ok(-7 == (-a).remainder(-b))
+
+test_ok(10**40+10**20 == 10000000000000000000100000000000000000000)
+test_ok(10**40/10**20 == 100000000000000000000)
+
+a = 677330545177305025495135714080
+b = 14269972710765292560
+test_ok(a % b == 0)
+test_ok(-a % b == 0)
+
+def shift_test(a)
+ b = a / (2 ** 32)
+ c = a >> 32
+ test_ok(b == c)
+
+ b = a * (2 ** 32)
+ c = a << 32
+ test_ok(b == c)
+end
+
+shift_test(-4518325415524767873)
+shift_test(-0xfffffffffffffffff)
+
+test_check "string & char"
+
+test_ok("abcd" == "abcd")
+test_ok("abcd" =~ /abcd/)
+test_ok("abcd" === "abcd")
+# compile time string concatenation
+test_ok("ab" "cd" == "abcd")
+test_ok("#{22}aa" "cd#{44}" == "22aacd44")
+test_ok("#{22}aa" "cd#{44}" "55" "#{66}" == "22aacd445566")
+test_ok("abc" !~ /^$/)
+test_ok("abc\n" !~ /^$/)
+test_ok("abc" !~ /^d*$/)
+test_ok(("abc" =~ /d*$/) == 3)
+test_ok("" =~ /^$/)
+test_ok("\n" =~ /^$/)
+test_ok("a\n\n" =~ /^$/)
+test_ok("abcabc" =~ /.*a/ && $& == "abca")
+test_ok("abcabc" =~ /.*c/ && $& == "abcabc")
+test_ok("abcabc" =~ /.*?a/ && $& == "a")
+test_ok("abcabc" =~ /.*?c/ && $& == "abc")
+test_ok(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n" && $& == "a\nb")
+
+test_ok(/^(ab+)+b/ =~ "ababb" && $& == "ababb")
+test_ok(/^(?:ab+)+b/ =~ "ababb" && $& == "ababb")
+test_ok(/^(ab+)+/ =~ "ababb" && $& == "ababb")
+test_ok(/^(?:ab+)+/ =~ "ababb" && $& == "ababb")
+
+test_ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
+test_ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2")
+
+$x = <<END;
+ABCD
+ABCD
+END
+$x.gsub!(/((.|\n)*?)B((.|\n)*?)D/, '\1\3')
+test_ok($x == "AC\nAC\n")
+
+test_ok("foobar" =~ /foo(?=(bar)|(baz))/)
+test_ok("foobaz" =~ /foo(?=(bar)|(baz))/)
+
+$foo = "abc"
+test_ok("#$foo = abc" == "abc = abc")
+test_ok("#{$foo} = abc" == "abc = abc")
+
+foo = "abc"
+test_ok("#{foo} = abc" == "abc = abc")
+
+test_ok('-' * 5 == '-----')
+test_ok('-' * 1 == '-')
+test_ok('-' * 0 == '')
+
+foo = '-'
+test_ok(foo * 5 == '-----')
+test_ok(foo * 1 == '-')
+test_ok(foo * 0 == '')
+
+$x = "a.gif"
+test_ok($x.sub(/.*\.([^\.]+)$/, '\1') == "gif")
+test_ok($x.sub(/.*\.([^\.]+)$/, 'b.\1') == "b.gif")
+test_ok($x.sub(/.*\.([^\.]+)$/, '\2') == "")
+test_ok($x.sub(/.*\.([^\.]+)$/, 'a\2b') == "ab")
+test_ok($x.sub(/.*\.([^\.]+)$/, '<\&>') == "<a.gif>")
+
+# character constants(assumes ASCII)
+test_ok("a"[0] == ?a)
+test_ok(?a == ?a)
+test_ok(?\C-a == "\1")
+test_ok(?\M-a == "\341")
+test_ok(?\M-\C-a == "\201")
+test_ok("a".upcase![0] == ?A)
+test_ok("A".downcase![0] == ?a)
+test_ok("abc".tr!("a-z", "A-Z") == "ABC")
+test_ok("aabbcccc".tr_s!("a-z", "A-Z") == "ABC")
+test_ok("abcc".squeeze!("a-z") == "abc")
+test_ok("abcd".delete!("bc") == "ad")
+
+$x = "abcdef"
+$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
+$bad = false
+$x.each_byte {|i|
+ if i.chr != $y.shift
+ $bad = true
+ break
+ end
+}
+test_ok(!$bad)
+
+s = "a string"
+s[0..s.size]="another string"
+test_ok(s == "another string")
+
+s = <<EOS
+#{
+[1,2,3].join(",")
+}
+EOS
+test_ok(s == "1,2,3\n")
+test_ok("Just".to_i(36) == 926381)
+test_ok("-another".to_i(36) == -23200231779)
+test_ok(1299022.to_s(36) == "ruby")
+test_ok(-1045307475.to_s(36) == "-hacker")
+test_ok("Just_another_Ruby_hacker".to_i(36) == 265419172580680477752431643787347)
+test_ok(-265419172580680477752431643787347.to_s(36) == "-justanotherrubyhacker")
+
+a = []
+(0..255).each {|n|
+ ch = [n].pack("C")
+ a.push ch if /a#{Regexp.quote ch}b/x =~ "ab"
+}
+test_ok(a.size == 0)
+
+test_check "assignment"
+a = nil
+test_ok(defined?(a))
+test_ok(a == nil)
+
+# multiple asignment
+a, b = 1, 2
+test_ok(a == 1 && b == 2)
+
+a, b = b, a
+test_ok(a == 2 && b == 1)
+
+a, = 1,2
+test_ok(a == 1)
+
+a, *b = 1, 2, 3
+test_ok(a == 1 && b == [2, 3])
+
+a, (b, c), d = 1, [2, 3], 4
+test_ok(a == 1 && b == 2 && c == 3 && d == 4)
+
+*a = 1, 2, 3
+test_ok(a == [1, 2, 3])
+
+*a = 4
+test_ok(a == [4])
+
+*a = nil
+test_ok(a == [nil])
+
+test_check "call"
+def aaa(a, b=100, *rest)
+ res = [a, b]
+ res += rest if rest
+ return res
+end
+
+# not enough argument
+begin
+ aaa() # need at least 1 arg
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+begin
+ aaa # no arg given (exception raised)
+ test_ok(false)
+rescue
+ test_ok(true)
+end
+
+test_ok(aaa(1) == [1, 100])
+test_ok(aaa(1, 2) == [1, 2])
+test_ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])
+test_ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])
+
+test_check "proc"
+$proc = Proc.new{|i| i}
+test_ok($proc.call(2) == 2)
+test_ok($proc.call(3) == 3)
+
+$proc = Proc.new{|i| i*2}
+test_ok($proc.call(2) == 4)
+test_ok($proc.call(3) == 6)
+
+Proc.new{
+ iii=5 # nested local variable
+ $proc = Proc.new{|i|
+ iii = i
+ }
+ $proc2 = Proc.new {
+ $x = iii # nested variables shared by procs
+ }
+ # scope of nested variables
+ test_ok(defined?(iii))
+}.call
+test_ok(!defined?(iii)) # out of scope
+
+loop{iii=5; test_ok(eval("defined? iii")); break}
+loop {
+ iii = 10
+ def dyna_var_check
+ loop {
+ test_ok(!defined?(iii))
+ break
+ }
+ end
+ dyna_var_check
+ break
+}
+$x=0
+$proc.call(5)
+$proc2.call
+test_ok($x == 5)
+
+if defined? Process.kill
+ test_check "signal"
+
+ $x = 0
+ trap "SIGINT", Proc.new{|sig| $x = 2}
+ Process.kill "SIGINT", $$
+ 100.times {
+ sleep 0.1
+ break if $x != 0
+ }
+ test_ok($x == 2)
+
+ trap "SIGINT", Proc.new{raise "Interrupt"}
+
+ x = false
+ begin
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ rescue
+ x = $!
+ end
+ test_ok(x && /Interrupt/ =~ x.message)
+end
+
+test_check "eval"
+test_ok(eval("") == nil)
+$bad=false
+eval 'while false; $bad = true; print "foo\n" end'
+test_ok(!$bad)
+
+test_ok(eval('Object'))
+test_ok(eval('true'))
+test_ok(!eval('nil'))
+test_ok(!eval('false'))
+
+$foo = 'test_ok(true)'
+begin
+ eval $foo
+rescue
+ test_ok(false)
+end
+
+test_ok(eval("$foo") == 'test_ok(true)')
+test_ok(eval("true") == true)
+i = 5
+test_ok(eval("i == 5"))
+test_ok(eval("i") == 5)
+test_ok(eval("defined? i"))
+
+# eval with binding
+def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
+end
+
+$x = test_ev
+test_ok(eval("local1", $x) == "local1") # normal local var
+test_ok(eval("local2", $x) == "local2") # nested local var
+$bad = true
+begin
+ p eval("local1")
+rescue NameError # must raise error
+ $bad = false
+end
+test_ok(!$bad)
+
+module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+end
+test_ok(eval("EVTEST1", $x) == 25) # constant in module
+test_ok(eval("evtest2", $x) == 125) # local var in module
+$bad = true
+begin
+ eval("EVTEST1")
+rescue NameError # must raise error
+ $bad = false
+end
+test_ok(!$bad)
+
+x = binding #! YARV Limitation: Proc.new{}
+eval "i4 = 1", x
+test_ok(eval("i4", x) == 1)
+x = Proc.new{binding}.call #! YARV Limitation: Proc.new{Proc.new{}}.call
+eval "i4 = 22", x
+test_ok(eval("i4", x) == 22)
+$x = []
+x = Proc.new{binding}.call #! YARV Limitation: Proc.new{Proc.new{}}.call
+eval "(0..9).each{|i5| $x[i5] = Proc.new{i5*2}}", x
+test_ok($x[4].call == 8)
+
+x = binding
+eval "i = 1", x
+test_ok(eval("i", x) == 1)
+x = Proc.new{binding}.call
+eval "i = 22", x
+test_ok(eval("i", x) == 22)
+$x = []
+x = Proc.new{binding}.call
+eval "(0..9).each{|i5| $x[i5] = Proc.new{i5*2}}", x
+test_ok($x[4].call == 8)
+x = Proc.new{binding}.call
+eval "for i6 in 1..1; j6=i6; end", x
+test_ok(eval("defined? i6", x))
+test_ok(eval("defined? j6", x))
+
+Proc.new {
+ p = binding
+ eval "foo11 = 1", p
+ foo22 = 5
+ Proc.new{foo11=22}.call
+ Proc.new{foo22=55}.call
+ test_ok(eval("foo11", p) == eval("foo11"))
+ test_ok(eval("foo11") == 1)
+ test_ok(eval("foo22", p) == eval("foo22"))
+ test_ok(eval("foo22") == 55)
+}.call if false #! YARV Limitation
+
+#! YARV Limitation: p1 = Proc.new{i7 = 0; Proc.new{i7}}.call
+p1 = Proc.new{i7 = 0; binding}.call
+#! YARV Limitation: test_ok(p1.call == 0)
+eval "i7=5", p1
+#! YARV Limitation: test_ok(p1.call == 5)
+test_ok(!defined?(i7))
+
+if false #! YARV Limitation
+p1 = Proc.new{i7 = 0; Proc.new{i7}}.call
+i7 = nil
+test_ok(p1.call == 0)
+eval "i7=1", p1
+test_ok(p1.call == 1)
+eval "i7=5", p1
+test_ok(p1.call == 5)
+test_ok(i7 == nil)
+end
+
+test_check "system"
+test_ok(`echo foobar` == "foobar\n")
+test_ok(`./miniruby -e 'print "foobar"'` == 'foobar')
+
+script_tmp = "script_tmp.#{$$}"
+tmp = open(script_tmp, "w")
+tmp.print "print $zzz\n";
+tmp.close
+
+test_ok(`./miniruby -s #{script_tmp} -zzz` == 'true')
+test_ok(`./miniruby -s #{script_tmp} -zzz=555` == '555')
+
+tmp = open(script_tmp, "w")
+tmp.print "#! /usr/local/bin/ruby -s\n";
+tmp.print "print $zzz\n";
+tmp.close
+
+test_ok(`./miniruby #{script_tmp} -zzz=678` == '678')
+
+tmp = open(script_tmp, "w")
+tmp.print "this is a leading junk\n";
+tmp.print "#! /usr/local/bin/ruby -s\n";
+tmp.print "print $zzz\n";
+tmp.print "__END__\n";
+tmp.print "this is a trailing junk\n";
+tmp.close
+
+test_ok(`./miniruby -x #{script_tmp}` == '')
+test_ok(`./miniruby -x #{script_tmp} -zzz=555` == '555')
+
+tmp = open(script_tmp, "w")
+for i in 1..5
+ tmp.print i, "\n"
+end
+tmp.close
+
+`./miniruby -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' #{script_tmp}`
+done = true
+tmp = open(script_tmp, "r")
+while tmp.gets
+ if $_.to_i % 5 != 0
+ done = false
+ break
+ end
+end
+tmp.close
+test_ok(done)
+
+File.unlink script_tmp or `/bin/rm -f "#{script_tmp}"`
+File.unlink "#{script_tmp}.bak" or `/bin/rm -f "#{script_tmp}.bak"`
+
+test_check "const"
+TEST1 = 1
+TEST2 = 2
+
+module Const
+ TEST3 = 3
+ TEST4 = 4
+end
+
+module Const2
+ TEST3 = 6
+ TEST4 = 8
+end
+
+include Const
+
+test_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,3,4])
+
+include Const2
+STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+test_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])
+
+
+test_ok((String <=> Object) == -1)
+test_ok((Object <=> String) == 1)
+test_ok((Array <=> String) == nil)
+
+test_check "clone"
+foo = Object.new
+def foo.test
+ "test"
+end
+bar = foo.clone
+def bar.test2
+ "test2"
+end
+
+test_ok(bar.test2 == "test2")
+test_ok(bar.test == "test")
+test_ok(foo.test == "test")
+
+begin
+ foo.test2
+ test_ok false
+rescue NoMethodError
+ test_ok true
+end
+
+module M001; end
+module M002; end
+module M003; include M002; end
+module M002; include M001; end
+module M003; include M002; end
+
+test_ok(M003.ancestors == [M003, M002, M001])
+
+test_check "marshal"
+$x = [1,2,3,[4,5,"foo"],{1=>"bar"},2.5,fact(30)]
+$y = Marshal.dump($x)
+test_ok($x == Marshal.load($y))
+
+StrClone=String.clone;
+test_ok(Marshal.load(Marshal.dump(StrClone.new("abc"))).class == StrClone)
+
+[[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|
+ a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))
+ ma = Marshal.dump(a)
+ b = Marshal.load(ma)
+ test_ok(a == b)
+}
+
+test_check "pack"
+
+$format = "c2x5CCxsdils_l_a6";
+# Need the expression in here to force ary[5] to be numeric. This avoids
+# test2 failing because ary2 goes str->numeric->str and ary does not.
+ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"]
+$x = ary.pack($format)
+ary2 = $x.unpack($format)
+
+test_ok(ary.length == ary2.length)
+test_ok(ary.join(':') == ary2.join(':'))
+test_ok($x =~ /def/)
+
+$x = [-1073741825]
+test_ok($x.pack("q").unpack("q") == $x)
+
+test_check "math"
+test_ok(Math.sqrt(4) == 2)
+
+include Math
+test_ok(sqrt(4) == 2)
+
+test_check "struct"
+struct_test = Struct.new("Test", :foo, :bar)
+test_ok(struct_test == Struct::Test)
+
+test = struct_test.new(1, 2)
+test_ok(test.foo == 1 && test.bar == 2)
+test_ok(test[0] == 1 && test[1] == 2)
+
+a, b = test.to_a
+test_ok(a == 1 && b == 2)
+
+test[0] = 22
+test_ok(test.foo == 22)
+
+test.bar = 47
+test_ok(test.bar == 47)
+
+test_check "variable"
+test_ok($$.instance_of?(Integer))
+
+# read-only variable
+begin
+ $$ = 5
+ test_ok false
+rescue NameError
+ test_ok true
+end
+
+foobar = "foobar"
+$_ = foobar
+test_ok($_ == foobar)
+
+class Gods
+ @@rule = "Uranus" # private to Gods
+ def ruler0
+ @@rule
+ end
+
+ def self.ruler1 # <= per method definition style
+ @@rule
+ end
+ class << self # <= multiple method definition style
+ def ruler2
+ @@rule
+ end
+ end
+end
+
+module Olympians
+ @@rule ="Zeus"
+ def ruler3
+ @@rule
+ end
+end
+
+class Titans < Gods
+ @@rule = "Cronus" # do not affect @@rule in Gods
+ include Olympians
+ def ruler4
+ @@rule
+ end
+end
+
+test_ok(Gods.new.ruler0 == "Cronus")
+test_ok(Gods.ruler1 == "Cronus")
+test_ok(Gods.ruler2 == "Cronus")
+test_ok(Titans.ruler1 == "Cronus")
+test_ok(Titans.ruler2 == "Cronus")
+atlas = Titans.new
+test_ok(atlas.ruler0 == "Cronus")
+test_ok(atlas.ruler3 == "Zeus")
+test_ok(atlas.ruler4 == "Cronus")
+
+test_check "trace"
+$x = 1234
+$y = 0
+trace_var :$x, Proc.new{$y = $x}
+$x = 40414
+test_ok($y == $x)
+
+untrace_var :$x
+$x = 19660208
+test_ok($y != $x)
+
+trace_var :$x, Proc.new{$x *= 2}
+$x = 5
+test_ok($x == 10)
+
+untrace_var :$x
+
+test_check "defined?"
+
+test_ok(defined?($x)) # global variable
+test_ok(defined?($x) == 'global-variable')# returns description
+
+foo=5
+test_ok(defined?(foo)) # local variable
+
+test_ok(defined?(Array)) # constant
+test_ok(defined?(Object.new)) # method
+test_ok(!defined?(Object.print))# private method
+test_ok(defined?(1 == 2)) # operator expression
+
+class Foo
+ def foo
+ p :foo
+ end
+ protected :foo
+ def bar(f)
+ test_ok(defined?(self.foo))
+ test_ok(defined?(f.foo))
+ end
+end
+f = Foo.new
+test_ok(defined?(f.foo) == nil)
+f.bar(f)
+
+def defined_test
+ return !defined?(yield)
+end
+
+test_ok(defined_test) # not iterator
+test_ok(!defined_test{}) # called as iterator
+
+test_check "alias"
+class Alias0
+ def foo; "foo" end
+end
+class Alias1 < Alias0
+ alias bar foo
+ def foo; "foo+" + super end
+end
+class Alias2 < Alias1
+ alias baz foo
+ undef foo
+end
+
+x = Alias2.new
+test_ok(x.bar == "foo")
+test_ok(x.baz == "foo+foo")
+
+# test_check for cache
+test_ok(x.baz == "foo+foo")
+
+class Alias3 < Alias2
+ def foo
+ defined? super
+ end
+ def bar
+ defined? super
+ end
+ def quux
+ defined? super
+ end
+end
+x = Alias3.new
+test_ok(!x.foo)
+test_ok(x.bar)
+test_ok(!x.quux)
+
+test_check "path"
+test_ok(File.basename("a") == "a")
+test_ok(File.basename("a/b") == "b")
+test_ok(File.basename("a/b/") == "b")
+test_ok(File.basename("/") == "/")
+test_ok(File.basename("//") == "/")
+test_ok(File.basename("///") == "/")
+test_ok(File.basename("a/b////") == "b")
+test_ok(File.basename("a.rb", ".rb") == "a")
+test_ok(File.basename("a.rb///", ".rb") == "a")
+test_ok(File.basename("a.rb///", ".*") == "a")
+test_ok(File.basename("a.rb///", ".c") == "a.rb")
+test_ok(File.dirname("a") == ".")
+test_ok(File.dirname("/") == "/")
+test_ok(File.dirname("/a") == "/")
+test_ok(File.dirname("a/b") == "a")
+test_ok(File.dirname("a/b/c") == "a/b")
+test_ok(File.dirname("/a/b/c") == "/a/b")
+test_ok(File.dirname("/a/b/") == "/a")
+test_ok(File.dirname("/a/b///") == "/a")
+case Dir.pwd
+when %r'\A\w:'
+ test_ok(/\A\w:\/\z/ =~ File.expand_path(".", "/"))
+ test_ok(/\A\w:\/a\z/ =~ File.expand_path("a", "/"))
+ dosish = true
+when %r'\A//'
+ test_ok(%r'\A//[^/]+/[^/]+\z' =~ File.expand_path(".", "/"))
+ test_ok(%r'\A//[^/]+/[^/]+/a\z' =~ File.expand_path(".", "/"))
+ dosish = true
+else
+ test_ok(File.expand_path(".", "/") == "/")
+ test_ok(File.expand_path("sub", "/") == "/sub")
+end
+if dosish
+ test_ok(File.expand_path("/", "//machine/share/sub") == "//machine/share")
+ test_ok(File.expand_path("/dir", "//machine/share/sub") == "//machine/share/dir")
+ test_ok(File.expand_path("/", "z:/sub") == "z:/")
+ test_ok(File.expand_path("/dir", "z:/sub") == "z:/dir")
+end
+test_ok(File.expand_path(".", "//") == "//")
+test_ok(File.expand_path("sub", "//") == "//sub")
+
+# test_check "Proc#binding"
+ObjectSpace.each_object(Proc){|o|
+ begin
+ b = o.binding
+ eval 'self', b
+ rescue ArgumentError
+ end
+}
+
+test_check "gc"
+begin
+ 1.upto(10000) {
+ tmp = [0,1,2,3,4,5,6,7,8,9]
+ }
+ tmp = nil
+ test_ok true
+rescue
+ test_ok false
+end
+class S
+ def initialize(a)
+ @a = a
+ end
+end
+l=nil
+100000.times {
+ l = S.new(l)
+}
+GC.start
+test_ok true # reach here or dumps core
+l = []
+100000.times {
+ l.push([l])
+}
+GC.start
+test_ok true # reach here or dumps core
+
+ObjectSpace.each_object{|o|
+ o.class.name
+}
+
+test_ok true # reach here or dumps core
+
+PROGRESS.finish
+if $failed > 0
+ printf "not ok/test: %d failed %d\n", $ntest, $failed
+else
+ printf "end of test(test: %d)\n", $ntest
+end
diff --git a/benchmark/bm_app_answer.rb b/benchmark/bm_app_answer.rb
new file mode 100644
index 0000000000..3cd8a8fd37
--- /dev/null
+++ b/benchmark/bm_app_answer.rb
@@ -0,0 +1,15 @@
+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
+
+def the_answer_to_life_the_universe_and_everything
+ (ack(3,7).to_s.split(//).inject(0){|s,x| s+x.to_i}.to_s + "2" ).to_i
+end
+
+answer = the_answer_to_life_the_universe_and_everything
diff --git a/benchmark/bm_app_aobench.rb b/benchmark/bm_app_aobench.rb
new file mode 100644
index 0000000000..2bd6acfaf8
--- /dev/null
+++ b/benchmark/bm_app_aobench.rb
@@ -0,0 +1,291 @@
+# 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
new file mode 100644
index 0000000000..77c66a7949
--- /dev/null
+++ b/benchmark/bm_app_erb.rb
@@ -0,0 +1,26 @@
+#
+# 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_factorial.rb b/benchmark/bm_app_factorial.rb
new file mode 100644
index 0000000000..45f471dfdb
--- /dev/null
+++ b/benchmark/bm_app_factorial.rb
@@ -0,0 +1,11 @@
+def fact(n)
+ if(n > 1)
+ n * fact(n-1)
+ else
+ 1
+ end
+end
+
+100.times {
+ fact(5000)
+}
diff --git a/benchmark/bm_app_fib.rb b/benchmark/bm_app_fib.rb
new file mode 100644
index 0000000000..34a7b2e725
--- /dev/null
+++ b/benchmark/bm_app_fib.rb
@@ -0,0 +1,10 @@
+def fib n
+ if n < 3
+ 1
+ else
+ fib(n-1) + fib(n-2)
+ end
+end
+
+fib(34)
+
diff --git a/benchmark/bm_app_lc_fizzbuzz.rb b/benchmark/bm_app_lc_fizzbuzz.rb
new file mode 100644
index 0000000000..f09574bbeb
--- /dev/null
+++ b/benchmark/bm_app_lc_fizzbuzz.rb
@@ -0,0 +1,52 @@
+#
+# FizzBuzz program using only lambda calculus
+#
+# This program is quoted from
+# "Understanding Computation" by Tom Stuart
+# http://computationbook.com/
+#
+# You can understand why this program works fine by reading this book.
+#
+
+solution = -> k { -> f { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][k][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> l { -> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[l][f[x]] } }] } }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[m][n]][-> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[f[-> n { -> p { -> x { p[n[p][x]] } } }[m]][n]][m][x] }][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]] } } }][-> p { -> x { p[x] } }][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } }]][-> n { -> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[x]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> n { -> l { -> x { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][l][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][x]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }] } }[-> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> x { f[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { -> n { -> p { -> x { p[n[p][x]] } } }[f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n]][x] }][-> p { -> x { x } }] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][x] }]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]] } }][n]]]] }]
+
+FIRST = -> l { LEFT[RIGHT[l]] }
+IF = -> b { b }
+LEFT = -> p { p[-> x { -> y { x } } ] }
+RIGHT = -> p { p[-> x { -> y { y } } ] }
+IS_EMPTY = LEFT
+REST = -> l { RIGHT[RIGHT[l]] }
+
+def to_integer(proc)
+ proc[-> n { n + 1 }][0]
+end
+
+def to_boolean(proc)
+ IF[proc][true][false]
+end
+
+def to_array(proc)
+ array = []
+
+ until to_boolean(IS_EMPTY[proc])
+ array.push(FIRST[proc])
+ proc = REST[proc]
+ end
+
+ array
+end
+
+def to_char(c)
+ '0123456789BFiuz'.slice(to_integer(c))
+end
+
+def to_string(s)
+ to_array(s).map { |c| to_char(c) }.join
+end
+
+answer = to_array(solution).map do |p|
+ to_string(p)
+end
+
+answer_ary = answer.to_a
+# puts answer_ary
diff --git a/benchmark/bm_app_mandelbrot.rb b/benchmark/bm_app_mandelbrot.rb
new file mode 100644
index 0000000000..801b75e8e2
--- /dev/null
+++ b/benchmark/bm_app_mandelbrot.rb
@@ -0,0 +1,23 @@
+require 'complex'
+
+def mandelbrot? z
+ i = 0
+ while i<100
+ i += 1
+ z = z * z
+ return false if z.abs > 2
+ end
+ true
+end
+
+ary = []
+
+(0..1000).each{|dx|
+ (0..1000).each{|dy|
+ x = dx / 50.0
+ y = dy / 50.0
+ c = Complex(x, y)
+ ary << c if mandelbrot?(c)
+ }
+}
+
diff --git a/benchmark/bm_app_pentomino.rb b/benchmark/bm_app_pentomino.rb
new file mode 100644
index 0000000000..59c63f358e
--- /dev/null
+++ b/benchmark/bm_app_pentomino.rb
@@ -0,0 +1,259 @@
+#!/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_app_raise.rb b/benchmark/bm_app_raise.rb
new file mode 100644
index 0000000000..5db8f95d50
--- /dev/null
+++ b/benchmark/bm_app_raise.rb
@@ -0,0 +1,8 @@
+i = 0
+while i<300000
+ i += 1
+ begin
+ raise
+ rescue
+ end
+end
diff --git a/benchmark/bm_app_strconcat.rb b/benchmark/bm_app_strconcat.rb
new file mode 100644
index 0000000000..7eed7c1aed
--- /dev/null
+++ b/benchmark/bm_app_strconcat.rb
@@ -0,0 +1,5 @@
+i = 0
+while i<2_000_000
+ "#{1+1} #{1+1} #{1+1}"
+ i += 1
+end
diff --git a/benchmark/bm_app_tak.rb b/benchmark/bm_app_tak.rb
new file mode 100644
index 0000000000..efe5380f4e
--- /dev/null
+++ b/benchmark/bm_app_tak.rb
@@ -0,0 +1,13 @@
+
+def tak x, y, z
+ unless y < x
+ z
+ else
+ tak( tak(x-1, y, z),
+ tak(y-1, z, x),
+ tak(z-1, x, y))
+ end
+end
+
+tak(18, 9, 0)
+
diff --git a/benchmark/bm_app_tarai.rb b/benchmark/bm_app_tarai.rb
new file mode 100644
index 0000000000..4c146f5ccf
--- /dev/null
+++ b/benchmark/bm_app_tarai.rb
@@ -0,0 +1,10 @@
+def tarai( x, y, z )
+ if x <= y
+ then y
+ else tarai(tarai(x-1, y, z),
+ tarai(y-1, z, x),
+ tarai(z-1, x, y))
+ end
+end
+
+tarai(12, 6, 0)
diff --git a/benchmark/bm_app_uri.rb b/benchmark/bm_app_uri.rb
new file mode 100644
index 0000000000..586edfd5dc
--- /dev/null
+++ b/benchmark/bm_app_uri.rb
@@ -0,0 +1,8 @@
+require 'uri'
+
+100_000.times{
+ uri = URI.parse('http://www.ruby-lang.org')
+ uri.scheme
+ uri.host
+ uri.port
+}
diff --git a/benchmark/bm_array_sample_100k_10.rb b/benchmark/bm_array_sample_100k_10.rb
new file mode 100644
index 0000000000..5f41ecc32b
--- /dev/null
+++ b/benchmark/bm_array_sample_100k_10.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 10}
diff --git a/benchmark/bm_array_sample_100k_11.rb b/benchmark/bm_array_sample_100k_11.rb
new file mode 100644
index 0000000000..18b1715319
--- /dev/null
+++ b/benchmark/bm_array_sample_100k_11.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 11}
diff --git a/benchmark/bm_array_sample_100k__100.rb b/benchmark/bm_array_sample_100k__100.rb
new file mode 100644
index 0000000000..22863afe89
--- /dev/null
+++ b/benchmark/bm_array_sample_100k__100.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 100}
diff --git a/benchmark/bm_array_sample_100k__1k.rb b/benchmark/bm_array_sample_100k__1k.rb
new file mode 100644
index 0000000000..4cd79e6c67
--- /dev/null
+++ b/benchmark/bm_array_sample_100k__1k.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 1000}
diff --git a/benchmark/bm_array_sample_100k__6k.rb b/benchmark/bm_array_sample_100k__6k.rb
new file mode 100644
index 0000000000..b3d264249e
--- /dev/null
+++ b/benchmark/bm_array_sample_100k__6k.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 6000}
diff --git a/benchmark/bm_array_sample_100k___10k.rb b/benchmark/bm_array_sample_100k___10k.rb
new file mode 100644
index 0000000000..5dd55ec058
--- /dev/null
+++ b/benchmark/bm_array_sample_100k___10k.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 10_000}
diff --git a/benchmark/bm_array_sample_100k___50k.rb b/benchmark/bm_array_sample_100k___50k.rb
new file mode 100644
index 0000000000..1506732c3c
--- /dev/null
+++ b/benchmark/bm_array_sample_100k___50k.rb
@@ -0,0 +1,2 @@
+arr = [*0...100000]
+10_000.times {arr.sample 50_000}
diff --git a/benchmark/bm_array_shift.rb b/benchmark/bm_array_shift.rb
new file mode 100644
index 0000000000..798bb9e3f4
--- /dev/null
+++ b/benchmark/bm_array_shift.rb
@@ -0,0 +1,14 @@
+require 'benchmark'
+
+Benchmark.bm do |x|
+ [10_000,1_000_000,100_000_000].each do |n|
+ ary = Array.new(n,0)
+ GC.start
+ x.report("#{n}:shift"){ ary.shift }
+ (0..4).each do |i|
+ ary = Array.new(n,0)
+ GC.start
+ x.report("#{n}:shift(#{i})"){ ary.shift(i) }
+ end
+ end
+end
diff --git a/benchmark/bm_array_small_and.rb b/benchmark/bm_array_small_and.rb
new file mode 100644
index 0000000000..e53a6edae6
--- /dev/null
+++ b/benchmark/bm_array_small_and.rb
@@ -0,0 +1,17 @@
+MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
+MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
+ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
+
+ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
+ (MIN_SIZE..MAX_SIZE).map do |size2|
+ [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
+ end
+end
+
+ITERATIONS.times do
+ ARRAYS.each do |group|
+ group.each do |arr1, arr2|
+ arr1 & arr2
+ end
+ end
+end
diff --git a/benchmark/bm_array_small_diff.rb b/benchmark/bm_array_small_diff.rb
new file mode 100644
index 0000000000..9661ee48db
--- /dev/null
+++ b/benchmark/bm_array_small_diff.rb
@@ -0,0 +1,17 @@
+MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
+MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
+ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
+
+ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
+ (MIN_SIZE..MAX_SIZE).map do |size2|
+ [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
+ end
+end
+
+ITERATIONS.times do
+ ARRAYS.each do |group|
+ group.each do |arr1, arr2|
+ arr1 - arr2
+ end
+ end
+end
diff --git a/benchmark/bm_array_small_or.rb b/benchmark/bm_array_small_or.rb
new file mode 100644
index 0000000000..c58b5fd1ff
--- /dev/null
+++ b/benchmark/bm_array_small_or.rb
@@ -0,0 +1,17 @@
+MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
+MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
+ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
+
+ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
+ (MIN_SIZE..MAX_SIZE).map do |size2|
+ [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
+ end
+end
+
+ITERATIONS.times do
+ ARRAYS.each do |group|
+ group.each do |arr1, arr2|
+ arr1 | arr2
+ end
+ end
+end
diff --git a/benchmark/bm_array_sort_block.rb b/benchmark/bm_array_sort_block.rb
new file mode 100644
index 0000000000..3579786056
--- /dev/null
+++ b/benchmark/bm_array_sort_block.rb
@@ -0,0 +1,2 @@
+ary = Array.new(1000) { rand(1000) }
+10000.times { ary.sort { |a, b| a <=> b } }
diff --git a/benchmark/bm_array_sort_float.rb b/benchmark/bm_array_sort_float.rb
new file mode 100644
index 0000000000..9a6e2f8bd2
--- /dev/null
+++ b/benchmark/bm_array_sort_float.rb
@@ -0,0 +1,2 @@
+arr = Array.new(1000) { rand }
+10000.times { arr.sort }
diff --git a/benchmark/bm_bighash.rb b/benchmark/bm_bighash.rb
new file mode 100644
index 0000000000..e2ad5a5c94
--- /dev/null
+++ b/benchmark/bm_bighash.rb
@@ -0,0 +1 @@
+h = {}; 5000000.times {|n| h[n] = n }
diff --git a/benchmark/bm_dir_empty_p.rb b/benchmark/bm_dir_empty_p.rb
new file mode 100644
index 0000000000..8329c757cf
--- /dev/null
+++ b/benchmark/bm_dir_empty_p.rb
@@ -0,0 +1,5 @@
+require 'tmpdir'
+max = 100_000
+Dir.mktmpdir('bm_dir_empty_p') do |dir|
+ max.times { Dir.empty?(dir) }
+end
diff --git a/benchmark/bm_erb_render.rb b/benchmark/bm_erb_render.rb
new file mode 100644
index 0000000000..d2929b0553
--- /dev/null
+++ b/benchmark/bm_erb_render.rb
@@ -0,0 +1,26 @@
+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_chmod.rb b/benchmark/bm_file_chmod.rb
new file mode 100644
index 0000000000..1cd4760c9d
--- /dev/null
+++ b/benchmark/bm_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/bm_file_rename.rb b/benchmark/bm_file_rename.rb
new file mode 100644
index 0000000000..3bf6a5ef35
--- /dev/null
+++ b/benchmark/bm_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 }
+max.times do
+ File.rename(a, b)
+ File.rename(b, a)
+end
+tmp.each { |t| t.close! }
diff --git a/benchmark/bm_hash_aref_dsym.rb b/benchmark/bm_hash_aref_dsym.rb
new file mode 100644
index 0000000000..af4f8c36d4
--- /dev/null
+++ b/benchmark/bm_hash_aref_dsym.rb
@@ -0,0 +1,4 @@
+h = {}
+syms = ('a'..'z').map { |s| s.to_sym }
+syms.each { |s| h[s] = 1 }
+200_000.times { syms.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_dsym_long.rb b/benchmark/bm_hash_aref_dsym_long.rb
new file mode 100644
index 0000000000..9d7759379e
--- /dev/null
+++ b/benchmark/bm_hash_aref_dsym_long.rb
@@ -0,0 +1,21 @@
+# [ruby-core:70129] [Bug #11396]
+collection_size = 200000
+sample_size = 10000
+
+values = (1..collection_size).to_a.map do |x|
+ "THIS IS A LONGER STRING THAT IS ALSO UNIQUE #{x}"
+end
+
+symbol_hash = {}
+
+values.each do |x|
+ symbol_hash[x.to_sym] = 1
+end
+
+# use the same samples each time to minimize deviations
+rng = Random.new(0)
+symbol_sample_array = values.sample(sample_size, random: rng).map(&:to_sym)
+
+3000.times do
+ symbol_sample_array.each { |x| symbol_hash[x] }
+end
diff --git a/benchmark/bm_hash_aref_fix.rb b/benchmark/bm_hash_aref_fix.rb
new file mode 100644
index 0000000000..1346890582
--- /dev/null
+++ b/benchmark/bm_hash_aref_fix.rb
@@ -0,0 +1,4 @@
+h = {}
+nums = (1..26).to_a
+nums.each { |i| h[i] = i }
+200_000.times { nums.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_flo.rb b/benchmark/bm_hash_aref_flo.rb
new file mode 100644
index 0000000000..2217274c82
--- /dev/null
+++ b/benchmark/bm_hash_aref_flo.rb
@@ -0,0 +1,4 @@
+h = {}
+strs = [*1..10000].map! {|i| i.fdiv(10)}
+strs.each { |s| h[s] = s }
+50.times { strs.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_miss.rb b/benchmark/bm_hash_aref_miss.rb
new file mode 100644
index 0000000000..b0913dd4bb
--- /dev/null
+++ b/benchmark/bm_hash_aref_miss.rb
@@ -0,0 +1,5 @@
+h = {}
+strs = ('a'..'z').to_a.map!(&:freeze)
+strs.each { |s| h[s] = s }
+strs = ('A'..'Z').to_a
+200_000.times { strs.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_str.rb b/benchmark/bm_hash_aref_str.rb
new file mode 100644
index 0000000000..19439b061b
--- /dev/null
+++ b/benchmark/bm_hash_aref_str.rb
@@ -0,0 +1,4 @@
+h = {}
+strs = ('a'..'z').to_a.map!(&:freeze)
+strs.each { |s| h[s] = s }
+200_000.times { strs.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_sym.rb b/benchmark/bm_hash_aref_sym.rb
new file mode 100644
index 0000000000..f75d163fe6
--- /dev/null
+++ b/benchmark/bm_hash_aref_sym.rb
@@ -0,0 +1,9 @@
+h = {}
+syms = ('a'..'z').to_a
+begin
+ syms = eval("%i[#{syms.join(' ')}]")
+rescue SyntaxError # <= 1.9.3
+ syms.map!(&:to_sym)
+end
+syms.each { |s| h[s] = s }
+200_000.times { syms.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_aref_sym_long.rb b/benchmark/bm_hash_aref_sym_long.rb
new file mode 100644
index 0000000000..9dab8df7be
--- /dev/null
+++ b/benchmark/bm_hash_aref_sym_long.rb
@@ -0,0 +1,13 @@
+h = {}
+syms = %w[puts warn syswrite write stat bacon lettuce tomato
+some symbols in this array may already be interned others should not be
+hash browns make good breakfast but not cooked using prime numbers
+shift for division entries delete_if keys exist?
+]
+begin
+ syms = eval("%i[#{syms.join(' ')}]")
+rescue SyntaxError # <= 1.9.3
+ syms.map!(&:to_sym)
+end
+syms.each { |s| h[s] = s }
+200_000.times { syms.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_flatten.rb b/benchmark/bm_hash_flatten.rb
new file mode 100644
index 0000000000..e944aae9f2
--- /dev/null
+++ b/benchmark/bm_hash_flatten.rb
@@ -0,0 +1,9 @@
+h = {}
+
+10000.times do |i|
+ h[i] = nil
+end
+
+1000.times do
+ h.flatten
+end
diff --git a/benchmark/bm_hash_ident_flo.rb b/benchmark/bm_hash_ident_flo.rb
new file mode 100644
index 0000000000..0c7edfed3e
--- /dev/null
+++ b/benchmark/bm_hash_ident_flo.rb
@@ -0,0 +1,4 @@
+h = {}.compare_by_identity
+strs = (1..10000).to_a.map!(&:to_f)
+strs.each { |s| h[s] = s }
+50.times { strs.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_ident_num.rb b/benchmark/bm_hash_ident_num.rb
new file mode 100644
index 0000000000..b226736c6f
--- /dev/null
+++ b/benchmark/bm_hash_ident_num.rb
@@ -0,0 +1,4 @@
+h = {}.compare_by_identity
+nums = (1..26).to_a
+nums.each { |n| h[n] = n }
+200_000.times { nums.each { |n| h[n] } }
diff --git a/benchmark/bm_hash_ident_obj.rb b/benchmark/bm_hash_ident_obj.rb
new file mode 100644
index 0000000000..4b3b58edec
--- /dev/null
+++ b/benchmark/bm_hash_ident_obj.rb
@@ -0,0 +1,4 @@
+h = {}.compare_by_identity
+objs = 26.times.map { Object.new }
+objs.each { |o| h[o] = o }
+200_000.times { objs.each { |o| h[o] } }
diff --git a/benchmark/bm_hash_ident_str.rb b/benchmark/bm_hash_ident_str.rb
new file mode 100644
index 0000000000..8582b38e31
--- /dev/null
+++ b/benchmark/bm_hash_ident_str.rb
@@ -0,0 +1,4 @@
+h = {}.compare_by_identity
+strs = ('a'..'z').to_a
+strs.each { |s| h[s] = s }
+200_000.times { strs.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_ident_sym.rb b/benchmark/bm_hash_ident_sym.rb
new file mode 100644
index 0000000000..4c81e3d28e
--- /dev/null
+++ b/benchmark/bm_hash_ident_sym.rb
@@ -0,0 +1,4 @@
+h = {}.compare_by_identity
+syms = ('a'..'z').to_a.map(&:to_sym)
+syms.each { |s| h[s] = s }
+200_000.times { syms.each { |s| h[s] } }
diff --git a/benchmark/bm_hash_keys.rb b/benchmark/bm_hash_keys.rb
new file mode 100644
index 0000000000..6863cd01f9
--- /dev/null
+++ b/benchmark/bm_hash_keys.rb
@@ -0,0 +1,9 @@
+h = {}
+
+10000.times do |i|
+ h[i] = nil
+end
+
+5000.times do
+ h.keys
+end
diff --git a/benchmark/bm_hash_long.rb b/benchmark/bm_hash_long.rb
new file mode 100644
index 0000000000..03d9109602
--- /dev/null
+++ b/benchmark/bm_hash_long.rb
@@ -0,0 +1,4 @@
+k1 = "Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong";
+k2 = "Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping";
+h = {k1 => 0, k2 => 0};
+3000000.times{|i| k = i % 2 ? k2 : k1; h [k] = h[k] + 1}
diff --git a/benchmark/bm_hash_shift.rb b/benchmark/bm_hash_shift.rb
new file mode 100644
index 0000000000..a645671a5b
--- /dev/null
+++ b/benchmark/bm_hash_shift.rb
@@ -0,0 +1,10 @@
+h = {}
+
+10000.times do |i|
+ h[i] = nil
+end
+
+50000.times do
+ k, v = h.shift
+ h[k] = v
+end
diff --git a/benchmark/bm_hash_shift_u16.rb b/benchmark/bm_hash_shift_u16.rb
new file mode 100644
index 0000000000..ec800d0342
--- /dev/null
+++ b/benchmark/bm_hash_shift_u16.rb
@@ -0,0 +1,10 @@
+h = {}
+
+(16384..65536).each do |i|
+ h[i] = nil
+end
+
+300000.times do
+ k, v = h.shift
+ h[k] = v
+end
diff --git a/benchmark/bm_hash_shift_u24.rb b/benchmark/bm_hash_shift_u24.rb
new file mode 100644
index 0000000000..de4e0fa696
--- /dev/null
+++ b/benchmark/bm_hash_shift_u24.rb
@@ -0,0 +1,10 @@
+h = {}
+
+(0xff4000..0xffffff).each do |i|
+ h[i] = nil
+end
+
+300000.times do
+ k, v = h.shift
+ h[k] = v
+end
diff --git a/benchmark/bm_hash_shift_u32.rb b/benchmark/bm_hash_shift_u32.rb
new file mode 100644
index 0000000000..656aa55583
--- /dev/null
+++ b/benchmark/bm_hash_shift_u32.rb
@@ -0,0 +1,10 @@
+h = {}
+
+(0xffff4000..0xffffffff).each do |i|
+ h[i] = nil
+end
+
+300000.times do
+ k, v = h.shift
+ h[k] = v
+end
diff --git a/benchmark/bm_hash_small2.rb b/benchmark/bm_hash_small2.rb
new file mode 100644
index 0000000000..45485d9c71
--- /dev/null
+++ b/benchmark/bm_hash_small2.rb
@@ -0,0 +1 @@
+1000000.times.map{|i| a={}; 2.times{|j| a[j]=j}; a}
diff --git a/benchmark/bm_hash_small4.rb b/benchmark/bm_hash_small4.rb
new file mode 100644
index 0000000000..acd4084334
--- /dev/null
+++ b/benchmark/bm_hash_small4.rb
@@ -0,0 +1 @@
+1000000.times.map{|i| a={}; 4.times{|j| a[j]=j}; a}
diff --git a/benchmark/bm_hash_small8.rb b/benchmark/bm_hash_small8.rb
new file mode 100644
index 0000000000..9cffcc91b6
--- /dev/null
+++ b/benchmark/bm_hash_small8.rb
@@ -0,0 +1 @@
+1000000.times.map{|i| a={}; 8.times{|j| a[j]=j}; a}
diff --git a/benchmark/bm_hash_to_proc.rb b/benchmark/bm_hash_to_proc.rb
new file mode 100644
index 0000000000..2b675bf509
--- /dev/null
+++ b/benchmark/bm_hash_to_proc.rb
@@ -0,0 +1,9 @@
+h = {}
+
+10000.times do |i|
+ h[i] = nil
+end
+
+5000.times do |i|
+ [i].map(&h)
+end
diff --git a/benchmark/bm_hash_values.rb b/benchmark/bm_hash_values.rb
new file mode 100644
index 0000000000..069441302f
--- /dev/null
+++ b/benchmark/bm_hash_values.rb
@@ -0,0 +1,9 @@
+h = {}
+
+10000.times do |i|
+ h[i] = nil
+end
+
+5000.times do
+ h.values
+end
diff --git a/benchmark/bm_int_quo.rb b/benchmark/bm_int_quo.rb
new file mode 100644
index 0000000000..e22a3f8c30
--- /dev/null
+++ b/benchmark/bm_int_quo.rb
@@ -0,0 +1 @@
+5000000.times { 42.quo(3) }
diff --git a/benchmark/bm_io_copy_stream_write.rb b/benchmark/bm_io_copy_stream_write.rb
new file mode 100644
index 0000000000..3fd87250a4
--- /dev/null
+++ b/benchmark/bm_io_copy_stream_write.rb
@@ -0,0 +1,24 @@
+# The goal of this is to use a synthetic (non-IO) reader
+# to trigger the read/write loop of IO.copy_stream,
+# bypassing in-kernel mechanisms like sendfile for zero copy,
+# so we wrap the /dev/zero IO object:
+
+class Zero
+ def initialize
+ @n = 100000
+ @in = File.open('/dev/zero', 'rb')
+ end
+
+ def read(len, buf)
+ return if (@n -= 1) == 0
+ @in.read(len, buf)
+ end
+end
+
+begin
+ src = Zero.new
+ dst = File.open(IO::NULL, 'wb')
+ n = IO.copy_stream(src, dst)
+rescue Errno::ENOENT
+ # not *nix
+end if IO.respond_to?(:copy_stream) && IO.const_defined?(:NULL)
diff --git a/benchmark/bm_io_copy_stream_write_socket.rb b/benchmark/bm_io_copy_stream_write_socket.rb
new file mode 100644
index 0000000000..11f369bd0d
--- /dev/null
+++ b/benchmark/bm_io_copy_stream_write_socket.rb
@@ -0,0 +1,35 @@
+# The goal of this is to use a synthetic (non-IO) reader
+# to trigger the read/write loop of IO.copy_stream,
+# bypassing in-kernel mechanisms like sendfile for zero copy,
+# so we wrap the /dev/zero IO object:
+class Zero
+ def initialize
+ @n = 100000
+ @in = File.open('/dev/zero', 'rb')
+ end
+
+ def read(len, buf)
+ return if (@n -= 1) == 0
+ @in.read(len, buf)
+ end
+end
+
+begin
+ require 'socket'
+ src = Zero.new
+ rd, wr = UNIXSocket.pair
+ pid = fork do
+ wr.close
+ buf = String.new
+ while rd.read(16384, buf)
+ end
+ end
+ rd.close
+ IO.copy_stream(src, wr)
+rescue Errno::ENOENT, NotImplementedError, NameError
+ # not *nix: missing /dev/zero, fork, or UNIXSocket
+rescue LoadError # no socket?
+ensure
+ wr.close if wr
+ Process.waitpid(pid) if pid
+end if IO.respond_to?(:copy_stream)
diff --git a/benchmark/bm_io_file_create.rb b/benchmark/bm_io_file_create.rb
new file mode 100644
index 0000000000..2f205c1333
--- /dev/null
+++ b/benchmark/bm_io_file_create.rb
@@ -0,0 +1,13 @@
+#
+# Create files
+#
+
+max = 200_000
+file = './tmpfile_of_bm_io_file_create'
+
+max.times{
+ f = open(file, 'w')
+ f.close#(true)
+}
+File.unlink(file)
+
diff --git a/benchmark/bm_io_file_read.rb b/benchmark/bm_io_file_read.rb
new file mode 100644
index 0000000000..b9e796ed30
--- /dev/null
+++ b/benchmark/bm_io_file_read.rb
@@ -0,0 +1,15 @@
+#
+# Seek and Read file.
+#
+
+require 'tempfile'
+
+max = 200_000
+str = "Hello world! " * 1000
+f = Tempfile.new('yarv-benchmark')
+f.write str
+
+max.times{
+ f.seek 0
+ f.read
+}
diff --git a/benchmark/bm_io_file_write.rb b/benchmark/bm_io_file_write.rb
new file mode 100644
index 0000000000..aa1be0e5fe
--- /dev/null
+++ b/benchmark/bm_io_file_write.rb
@@ -0,0 +1,14 @@
+#
+# Seek and Write file.
+#
+
+require 'tempfile'
+
+max = 200_000
+str = "Hello world! " * 1000
+f = Tempfile.new('yarv-benchmark')
+
+max.times{
+ f.seek 0
+ f.write str
+}
diff --git a/benchmark/bm_io_nonblock_noex.rb b/benchmark/bm_io_nonblock_noex.rb
new file mode 100644
index 0000000000..da9357fdc6
--- /dev/null
+++ b/benchmark/bm_io_nonblock_noex.rb
@@ -0,0 +1,22 @@
+nr = 1_000_000
+i = 0
+msg = '.'
+buf = '.'
+noex = { exception: false }
+begin
+ r, w = IO.pipe
+ while i < nr
+ i += 1
+ w.write_nonblock(msg, noex)
+ r.read_nonblock(1, buf, noex)
+ end
+rescue ArgumentError # old Rubies
+ while i < nr
+ i += 1
+ w.write_nonblock(msg)
+ r.read_nonblock(1, buf)
+ end
+ensure
+ r.close
+ w.close
+end
diff --git a/benchmark/bm_io_nonblock_noex2.rb b/benchmark/bm_io_nonblock_noex2.rb
new file mode 100644
index 0000000000..56819d049b
--- /dev/null
+++ b/benchmark/bm_io_nonblock_noex2.rb
@@ -0,0 +1,21 @@
+nr = 1_000_000
+i = 0
+msg = '.'
+buf = '.'
+begin
+ r, w = IO.pipe
+ while i < nr
+ i += 1
+ w.write_nonblock(msg, exception: false)
+ r.read_nonblock(1, buf, exception: false)
+ end
+rescue ArgumentError # old Rubies
+ while i < nr
+ i += 1
+ w.write_nonblock(msg)
+ r.read_nonblock(1, buf)
+ end
+ensure
+ r.close
+ w.close
+end
diff --git a/benchmark/bm_io_pipe_rw.rb b/benchmark/bm_io_pipe_rw.rb
new file mode 100644
index 0000000000..6862a8ae61
--- /dev/null
+++ b/benchmark/bm_io_pipe_rw.rb
@@ -0,0 +1,13 @@
+# Measure uncontended GVL performance via read/write with 1:1 threading
+# If we switch to M:N threading, this will benchmark something else...
+r, w = IO.pipe
+src = '0'.freeze
+dst = String.new
+i = 0
+while i < 1_000_000
+ i += 1
+ w.write(src)
+ r.read(1, dst)
+end
+w.close
+r.close
diff --git a/benchmark/bm_io_select.rb b/benchmark/bm_io_select.rb
new file mode 100644
index 0000000000..19248daeb1
--- /dev/null
+++ b/benchmark/bm_io_select.rb
@@ -0,0 +1,9 @@
+# IO.select performance
+
+w = [ IO.pipe[1] ];
+
+nr = 1000000
+nr.times {
+ IO.select nil, w
+}
+
diff --git a/benchmark/bm_io_select2.rb b/benchmark/bm_io_select2.rb
new file mode 100644
index 0000000000..10e37d71b2
--- /dev/null
+++ b/benchmark/bm_io_select2.rb
@@ -0,0 +1,22 @@
+# IO.select performance. worst case of single fd.
+
+ios = []
+nr = 1000000
+if defined?(Process::RLIMIT_NOFILE)
+ max = Process.getrlimit(Process::RLIMIT_NOFILE)[0]
+else
+ max = 64
+end
+puts "max fd: #{max} (results not apparent with <= 1024 max fd)"
+
+((max / 2) - 10).times do
+ ios.concat IO.pipe
+end
+
+last = [ ios[-1] ]
+puts "last IO: #{last[0].inspect}"
+
+nr.times do
+ IO.select nil, last
+end
+
diff --git a/benchmark/bm_io_select3.rb b/benchmark/bm_io_select3.rb
new file mode 100644
index 0000000000..7d0ba1f092
--- /dev/null
+++ b/benchmark/bm_io_select3.rb
@@ -0,0 +1,21 @@
+# IO.select performance. a lot of fd
+
+ios = []
+nr = 100
+if defined?(Process::RLIMIT_NOFILE)
+ max = Process.getrlimit(Process::RLIMIT_NOFILE)[0]
+else
+ max = 64
+end
+puts "max fd: #{max} (results not apparent with <= 1024 max fd)"
+
+(max - 10).times do
+ r, w = IO.pipe
+ r.close
+ ios.push w
+end
+
+nr.times do
+ IO.select nil, ios
+end
+
diff --git a/benchmark/bm_loop_for.rb b/benchmark/bm_loop_for.rb
new file mode 100644
index 0000000000..0fc4cc1511
--- /dev/null
+++ b/benchmark/bm_loop_for.rb
@@ -0,0 +1,3 @@
+for i in 1..30_000_000
+ #
+end
diff --git a/benchmark/bm_loop_generator.rb b/benchmark/bm_loop_generator.rb
new file mode 100644
index 0000000000..d3375c744c
--- /dev/null
+++ b/benchmark/bm_loop_generator.rb
@@ -0,0 +1,14 @@
+max = 600000
+
+if defined? Fiber
+ gen = (1..max).each
+ loop do
+ gen.next
+ end
+else
+ require 'generator'
+ gen = Generator.new((0..max))
+ while gen.next?
+ gen.next
+ end
+end
diff --git a/benchmark/bm_loop_times.rb b/benchmark/bm_loop_times.rb
new file mode 100644
index 0000000000..521f72ad1a
--- /dev/null
+++ b/benchmark/bm_loop_times.rb
@@ -0,0 +1 @@
+30_000_000.times{|e|}
diff --git a/benchmark/bm_loop_whileloop.rb b/benchmark/bm_loop_whileloop.rb
new file mode 100644
index 0000000000..0072822c06
--- /dev/null
+++ b/benchmark/bm_loop_whileloop.rb
@@ -0,0 +1,4 @@
+i = 0
+while i<30_000_000 # benchmark loop 1
+ i += 1
+end
diff --git a/benchmark/bm_loop_whileloop2.rb b/benchmark/bm_loop_whileloop2.rb
new file mode 100644
index 0000000000..47d02dffc4
--- /dev/null
+++ b/benchmark/bm_loop_whileloop2.rb
@@ -0,0 +1,4 @@
+i = 0
+while i< 6_000_000 # benchmark loop 2
+ i += 1
+end
diff --git a/benchmark/bm_marshal_dump_flo.rb b/benchmark/bm_marshal_dump_flo.rb
new file mode 100644
index 0000000000..9b8d0c6afb
--- /dev/null
+++ b/benchmark/bm_marshal_dump_flo.rb
@@ -0,0 +1,2 @@
+bug10761 = 10000.times.map { |x| x.to_f }
+100.times { Marshal.dump(bug10761) }
diff --git a/benchmark/bm_marshal_dump_load_geniv.rb b/benchmark/bm_marshal_dump_load_geniv.rb
new file mode 100644
index 0000000000..8252ad90fa
--- /dev/null
+++ b/benchmark/bm_marshal_dump_load_geniv.rb
@@ -0,0 +1,10 @@
+a = ''
+a.instance_eval do
+ @a = :a
+ @b = :b
+ @c = :c
+end
+100000.times do
+ a = Marshal.load(Marshal.dump(a))
+end
+#p(a.instance_eval { @a == :a && @b == :b && @c == :c })
diff --git a/benchmark/bm_marshal_dump_load_time.rb b/benchmark/bm_marshal_dump_load_time.rb
new file mode 100644
index 0000000000..e29743b791
--- /dev/null
+++ b/benchmark/bm_marshal_dump_load_time.rb
@@ -0,0 +1 @@
+100000.times { Marshal.load(Marshal.dump(Time.now)) }
diff --git a/benchmark/bm_require.rb b/benchmark/bm_require.rb
new file mode 100644
index 0000000000..b8abc88f41
--- /dev/null
+++ b/benchmark/bm_require.rb
@@ -0,0 +1,7 @@
+$:.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
new file mode 100644
index 0000000000..e54db6c6e5
--- /dev/null
+++ b/benchmark/bm_require_thread.rb
@@ -0,0 +1,15 @@
+$:.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_securerandom.rb b/benchmark/bm_securerandom.rb
new file mode 100644
index 0000000000..a082ea6d5b
--- /dev/null
+++ b/benchmark/bm_securerandom.rb
@@ -0,0 +1,5 @@
+require "securerandom"
+
+20_0000.times do
+ SecureRandom.random_number(100)
+end
diff --git a/benchmark/bm_so_ackermann.rb b/benchmark/bm_so_ackermann.rb
new file mode 100644
index 0000000000..7db5be9050
--- /dev/null
+++ b/benchmark/bm_so_ackermann.rb
@@ -0,0 +1,19 @@
+#!/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
new file mode 100644
index 0000000000..2b8fce8f99
--- /dev/null
+++ b/benchmark/bm_so_array.rb
@@ -0,0 +1,23 @@
+#!/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_binary_trees.rb b/benchmark/bm_so_binary_trees.rb
new file mode 100644
index 0000000000..b1693e4109
--- /dev/null
+++ b/benchmark/bm_so_binary_trees.rb
@@ -0,0 +1,62 @@
+# The Computer Language Shootout Benchmarks
+# http://shootout.alioth.debian.org
+#
+# contributed by Jesse Millikan
+
+# disable output
+alias puts_orig puts
+def puts str
+ # disable puts
+end
+
+def item_check(tree)
+ if tree[0] == nil
+ tree[1]
+ else
+ tree[1] + item_check(tree[0]) - item_check(tree[2])
+ end
+end
+
+def bottom_up_tree(item, depth)
+ if depth > 0
+ item_item = 2 * item
+ depth -= 1
+ [bottom_up_tree(item_item - 1, depth), item, bottom_up_tree(item_item, depth)]
+ else
+ [nil, item, nil]
+ end
+end
+
+max_depth = 16 # ARGV[0].to_i
+min_depth = 4
+
+max_depth = min_depth + 2 if min_depth + 2 > max_depth
+
+stretch_depth = max_depth + 1
+stretch_tree = bottom_up_tree(0, stretch_depth)
+
+puts "stretch tree of depth #{stretch_depth}\t check: #{item_check(stretch_tree)}"
+stretch_tree = nil
+
+long_lived_tree = bottom_up_tree(0, max_depth)
+
+min_depth.step(max_depth + 1, 2) do |depth|
+ iterations = 2**(max_depth - depth + min_depth)
+
+ check = 0
+
+ for i in 1..iterations
+ temp_tree = bottom_up_tree(i, depth)
+ check += item_check(temp_tree)
+
+ temp_tree = bottom_up_tree(-i, depth)
+ check += item_check(temp_tree)
+ end
+
+ puts "#{iterations * 2}\t trees of depth #{depth}\t check: #{check}"
+end
+
+puts "long lived tree of depth #{max_depth}\t check: #{item_check(long_lived_tree)}"
+
+undef puts
+alias puts puts_orig
diff --git a/benchmark/bm_so_concatenate.rb b/benchmark/bm_so_concatenate.rb
new file mode 100644
index 0000000000..873214de7c
--- /dev/null
+++ b/benchmark/bm_so_concatenate.rb
@@ -0,0 +1,18 @@
+#!/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
new file mode 100644
index 0000000000..65f6337a4a
--- /dev/null
+++ b/benchmark/bm_so_count_words.rb
@@ -0,0 +1,19 @@
+#!/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
new file mode 100644
index 0000000000..deb003a594
--- /dev/null
+++ b/benchmark/bm_so_exception.rb
@@ -0,0 +1,61 @@
+#!/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_fannkuch.rb b/benchmark/bm_so_fannkuch.rb
new file mode 100644
index 0000000000..bac5ecd44c
--- /dev/null
+++ b/benchmark/bm_so_fannkuch.rb
@@ -0,0 +1,45 @@
+# The Computer Language Shootout
+# http://shootout.alioth.debian.org/
+# Contributed by Sokolov Yura
+# Modified by Ryan Williams
+
+def fannkuch(n)
+ maxFlips, m, r, check = 0, n-1, n, 0
+ count = (1..n).to_a
+ perm = (1..n).to_a
+
+ while true
+ if check < 30
+ puts "#{perm}"
+ check += 1
+ end
+
+ while r != 1
+ count[r-1] = r
+ r -= 1
+ end
+
+ if perm[0] != 1 and perm[m] != n
+ perml = perm.clone #.dup
+ flips = 0
+ while (k = perml.first ) != 1
+ perml = perml.slice!(0, k).reverse + perml
+ flips += 1
+ end
+ maxFlips = flips if flips > maxFlips
+ end
+ while true
+ if r==n then return maxFlips end
+ perm.insert r,perm.shift
+ break if (count[r] -= 1) > 0
+ r += 1
+ end
+ end
+end
+
+def puts *args
+end
+
+N = 9 # (ARGV[0] || 1).to_i
+puts "Pfannkuchen(#{N}) = #{fannkuch(N)}"
+
diff --git a/benchmark/bm_so_fasta.rb b/benchmark/bm_so_fasta.rb
new file mode 100644
index 0000000000..dcc6b39507
--- /dev/null
+++ b/benchmark/bm_so_fasta.rb
@@ -0,0 +1,81 @@
+# 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)
+
diff --git a/benchmark/bm_so_k_nucleotide.rb b/benchmark/bm_so_k_nucleotide.rb
new file mode 100644
index 0000000000..dadab3e79c
--- /dev/null
+++ b/benchmark/bm_so_k_nucleotide.rb
@@ -0,0 +1,48 @@
+# 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_lists.rb b/benchmark/bm_so_lists.rb
new file mode 100644
index 0000000000..e8f4a2a5f7
--- /dev/null
+++ b/benchmark/bm_so_lists.rb
@@ -0,0 +1,47 @@
+#from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby
+
+NUM = 300
+SIZE = 10000
+
+def test_lists()
+ # create a list of integers (Li1) from 1 to SIZE
+ li1 = (1..SIZE).to_a
+ # copy the list to li2 (not by individual items)
+ li2 = li1.dup
+ # remove each individual item from left side of li2 and
+ # append to right side of li3 (preserving order)
+ li3 = Array.new
+ while (not li2.empty?)
+ li3.push(li2.shift)
+ end
+ # li2 must now be empty
+ # remove each individual item from right side of li3 and
+ # append to right side of li2 (reversing list)
+ while (not li3.empty?)
+ li2.push(li3.pop)
+ end
+ # li3 must now be empty
+ # reverse li1 in place
+ li1.reverse!
+ # check that first item is now SIZE
+ if li1[0] != SIZE then
+ p "not SIZE"
+ 0
+ else
+ # compare li1 and li2 for equality
+ if li1 != li2 then
+ return(0)
+ else
+ # return the length of the list
+ li1.length
+ end
+ end
+end
+
+i = 0
+while i<NUM
+ i += 1
+ result = test_lists()
+end
+
+result
diff --git a/benchmark/bm_so_mandelbrot.rb b/benchmark/bm_so_mandelbrot.rb
new file mode 100644
index 0000000000..76331c64b8
--- /dev/null
+++ b/benchmark/bm_so_mandelbrot.rb
@@ -0,0 +1,57 @@
+# The Computer Language Benchmarks Game
+# http://shootout.alioth.debian.org/
+#
+# contributed by Karl von Laudermann
+# modified by Jeremy Echols
+
+size = 600 # ARGV[0].to_i
+
+puts "P4\n#{size} #{size}"
+
+ITER = 49 # Iterations - 1 for easy for..in looping
+LIMIT_SQUARED = 4.0 # Presquared limit
+
+byte_acc = 0
+bit_num = 0
+
+count_size = size - 1 # Precomputed size for easy for..in looping
+
+# For..in loops are faster than .upto, .downto, .times, etc.
+for y in 0..count_size
+ for x in 0..count_size
+ zr = 0.0
+ zi = 0.0
+ cr = (2.0*x/size)-1.5
+ ci = (2.0*y/size)-1.0
+ escape = false
+
+ # To make use of the for..in code, we use a dummy variable,
+ # like one would in C
+ for dummy in 0..ITER
+ tr = zr*zr - zi*zi + cr
+ ti = 2*zr*zi + ci
+ zr, zi = tr, ti
+
+ if (zr*zr+zi*zi) > LIMIT_SQUARED
+ escape = true
+ break
+ end
+ end
+
+ byte_acc = (byte_acc << 1) | (escape ? 0b0 : 0b1)
+ bit_num += 1
+
+ # Code is very similar for these cases, but using separate blocks
+ # ensures we skip the shifting when it's unnecessary, which is most cases.
+ if (bit_num == 8)
+ print byte_acc.chr
+ byte_acc = 0
+ bit_num = 0
+ elsif (x == count_size)
+ byte_acc <<= (8 - bit_num)
+ print byte_acc.chr
+ byte_acc = 0
+ bit_num = 0
+ end
+ end
+end
diff --git a/benchmark/bm_so_matrix.rb b/benchmark/bm_so_matrix.rb
new file mode 100644
index 0000000000..e2c5c8e559
--- /dev/null
+++ b/benchmark/bm_so_matrix.rb
@@ -0,0 +1,48 @@
+#!/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_meteor_contest.rb b/benchmark/bm_so_meteor_contest.rb
new file mode 100755
index 0000000000..8c136baa6c
--- /dev/null
+++ b/benchmark/bm_so_meteor_contest.rb
@@ -0,0 +1,563 @@
+#!/usr/bin/env ruby
+#
+# The Computer Language Shootout
+# http://shootout.alioth.debian.org
+# contributed by Kevin Barnes (Ruby novice)
+
+# PROGRAM: the main body is at the bottom.
+# 1) read about the problem here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/
+# 2) see how I represent a board as a bitmask by reading the blank_board comments
+# 3) read as your mental paths take you
+
+def print *args
+end
+
+# class to represent all information about a particular rotation of a particular piece
+class Rotation
+ # an array (by location) containing a bit mask for how the piece maps at the given location.
+ # if the rotation is invalid at that location the mask will contain false
+ attr_reader :start_masks
+
+ # maps a direction to a relative location. these differ depending on whether it is an even or
+ # odd row being mapped from
+ @@rotation_even_adder = { :west => -1, :east => 1, :nw => -7, :ne => -6, :sw => 5, :se => 6 }
+ @@rotation_odd_adder = { :west => -1, :east => 1, :nw => -6, :ne => -5, :sw => 6, :se => 7 }
+
+ def initialize( directions )
+ @even_offsets, @odd_offsets = normalize_offsets( get_values( directions ))
+
+ @even_mask = mask_for_offsets( @even_offsets)
+ @odd_mask = mask_for_offsets( @odd_offsets)
+
+ @start_masks = Array.new(60)
+
+ # create the rotational masks by placing the base mask at the location and seeing if
+ # 1) it overlaps the boundaries and 2) it produces a prunable board. if either of these
+ # is true the piece cannot be placed
+ 0.upto(59) do | offset |
+ mask = is_even(offset) ? (@even_mask << offset) : (@odd_mask << offset)
+ if (blank_board & mask == 0 && !prunable(blank_board | mask, 0, true)) then
+ imask = compute_required( mask, offset)
+ @start_masks[offset] = [ mask, imask, imask | mask ]
+ else
+ @start_masks[offset] = false
+ end
+ end
+ end
+
+ def compute_required( mask, offset )
+ board = blank_board
+ 0.upto(offset) { | i | board |= 1 << i }
+ board |= mask
+ return 0 if (!prunable(board | mask, offset))
+ board = flood_fill(board,58)
+ count = 0
+ imask = 0
+ 0.upto(59) do | i |
+ if (board[i] == 0) then
+ imask |= (1 << i)
+ count += 1
+ end
+ end
+ (count > 0 && count < 5) ? imask : 0
+ end
+
+ def flood_fill( board, location)
+ return board if (board[location] == 1)
+ board |= 1 << location
+ row, col = location.divmod(6)
+ board = flood_fill( board, location - 1) if (col > 0)
+ board = flood_fill( board, location + 1) if (col < 4)
+ if (row % 2 == 0) then
+ board = flood_fill( board, location - 7) if (col > 0 && row > 0)
+ board = flood_fill( board, location - 6) if (row > 0)
+ board = flood_fill( board, location + 6) if (row < 9)
+ board = flood_fill( board, location + 5) if (col > 0 && row < 9)
+ else
+ board = flood_fill( board, location - 5) if (col < 4 && row > 0)
+ board = flood_fill( board, location - 6) if (row > 0)
+ board = flood_fill( board, location + 6) if (row < 9)
+ board = flood_fill( board, location + 7) if (col < 4 && row < 9)
+ end
+ board
+ end
+
+ # given a location, produces a list of relative locations covered by the piece at this rotation
+ def offsets( location)
+ if is_even( location) then
+ @even_offsets.collect { | value | value + location }
+ else
+ @odd_offsets.collect { | value | value + location }
+ end
+ end
+
+ # returns a set of offsets relative to the top-left most piece of the rotation (by even or odd rows)
+ # this is hard to explain. imagine we have this partial board:
+ # 0 0 0 0 0 x [positions 0-5]
+ # 0 0 1 1 0 x [positions 6-11]
+ # 0 0 1 0 0 x [positions 12-17]
+ # 0 1 0 0 0 x [positions 18-23]
+ # 0 1 0 0 0 x [positions 24-29]
+ # 0 0 0 0 0 x [positions 30-35]
+ # ...
+ # The top-left of the piece is at position 8, the
+ # board would be passed as a set of positions (values array) containing [8,9,14,19,25] not necessarily in that
+ # sorted order. Since that array starts on an odd row, the offsets for an odd row are: [0,1,6,11,17] obtained
+ # by subtracting 8 from everything. Now imagine the piece shifted up and to the right so it's on an even row:
+ # 0 0 0 1 1 x [positions 0-5]
+ # 0 0 1 0 0 x [positions 6-11]
+ # 0 0 1 0 0 x [positions 12-17]
+ # 0 1 0 0 0 x [positions 18-23]
+ # 0 0 0 0 0 x [positions 24-29]
+ # 0 0 0 0 0 x [positions 30-35]
+ # ...
+ # Now the positions are [3,4,8,14,19] which after subtracting the lowest value (3) gives [0,1,5,11,16] thus, the
+ # offsets for this particular piece are (in even, odd order) [0,1,5,11,16],[0,1,6,11,17] which is what
+ # this function would return
+ def normalize_offsets( values)
+ min = values.min
+ even_min = is_even(min)
+ other_min = even_min ? min + 6 : min + 7
+ other_values = values.collect do | value |
+ if is_even(value) then
+ value + 6 - other_min
+ else
+ value + 7 - other_min
+ end
+ end
+ values.collect! { | value | value - min }
+
+ if even_min then
+ [values, other_values]
+ else
+ [other_values, values]
+ end
+ end
+
+ # produce a bitmask representation of an array of offset locations
+ def mask_for_offsets( offsets )
+ mask = 0
+ offsets.each { | value | mask = mask + ( 1 << value ) }
+ mask
+ end
+
+ # finds a "safe" position that a position as described by a list of directions can be placed
+ # without falling off any edge of the board. the values returned a location to place the first piece
+ # at so it will fit after making the described moves
+ def start_adjust( directions )
+ south = east = 0;
+ directions.each do | direction |
+ east += 1 if ( direction == :sw || direction == :nw || direction == :west )
+ south += 1 if ( direction == :nw || direction == :ne )
+ end
+ south * 6 + east
+ end
+
+ # given a set of directions places the piece (as defined by a set of directions) on the board at
+ # a location that will not take it off the edge
+ def get_values( directions )
+ start = start_adjust(directions)
+ values = [ start ]
+ directions.each do | direction |
+ if (start % 12 >= 6) then
+ start += @@rotation_odd_adder[direction]
+ else
+ start += @@rotation_even_adder[direction]
+ end
+ values += [ start ]
+ end
+
+ # some moves take you back to an existing location, we'll strip duplicates
+ values.uniq
+ end
+end
+
+# describes a piece and caches information about its rotations to as to be efficient for iteration
+# ATTRIBUTES:
+# rotations -- all the rotations of the piece
+# type -- a numeic "name" of the piece
+# masks -- an array by location of all legal rotational masks (a n inner array) for that location
+# placed -- the mask that this piece was last placed at (not a location, but the actual mask used)
+class Piece
+ attr_reader :rotations, :type, :masks
+ attr_accessor :placed
+
+ # transform hashes that change one direction into another when you either flip or rotate a set of directions
+ @@flip_converter = { :west => :west, :east => :east, :nw => :sw, :ne => :se, :sw => :nw, :se => :ne }
+ @@rotate_converter = { :west => :nw, :east => :se, :nw => :ne, :ne => :east, :sw => :west, :se => :sw }
+
+ def initialize( directions, type )
+ @type = type
+ @rotations = Array.new();
+ @map = {}
+
+ generate_rotations( directions )
+ directions.collect! { | value | @@flip_converter[value] }
+ generate_rotations( directions )
+
+ # creates the masks AND a map that returns [location, rotation] for any given mask
+ # this is used when a board is found and we want to draw it, otherwise the map is unused
+ @masks = Array.new();
+ 0.upto(59) do | i |
+ even = true
+ @masks[i] = @rotations.collect do | rotation |
+ mask = rotation.start_masks[i]
+ @map[mask[0]] = [ i, rotation ] if (mask)
+ mask || nil
+ end
+ @masks[i].compact!
+ end
+ end
+
+ # rotates a set of directions through all six angles and adds a Rotation to the list for each one
+ def generate_rotations( directions )
+ 6.times do
+ rotations.push( Rotation.new(directions))
+ directions.collect! { | value | @@rotate_converter[value] }
+ end
+ end
+
+ # given a board string, adds this piece to the board at whatever location/rotation
+ # important: the outbound board string is 5 wide, the normal location notation is six wide (padded)
+ def fill_string( board_string)
+ location, rotation = @map[@placed]
+ rotation.offsets(location).each do | offset |
+ row, col = offset.divmod(6)
+ board_string[ row*5 + col, 1 ] = @type.to_s
+ end
+ end
+end
+
+# a blank bit board having this form:
+#
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 0 0 0 0 0 1
+# 1 1 1 1 1 1
+#
+# where left lest significant bit is the top left and the most significant is the lower right
+# the actual board only consists of the 0 places, the 1 places are blockers to keep things from running
+# off the edges or bottom
+def blank_board
+ 0b111111100000100000100000100000100000100000100000100000100000100000
+end
+
+def full_board
+ 0b111111111111111111111111111111111111111111111111111111111111111111
+end
+
+# determines if a location (bit position) is in an even row
+def is_even( location)
+ (location % 12) < 6
+end
+
+# support function that create three utility maps:
+# $converter -- for each row an array that maps a five bit row (via array mapping)
+# to the a five bit representation of the bits below it
+# $bit_count -- maps a five bit row (via array mapping) to the number of 1s in the row
+# @@new_regions -- maps a five bit row (via array mapping) to an array of "region" arrays
+# a region array has three values the first is a mask of bits in the region,
+# the second is the count of those bits and the third is identical to the first
+# examples:
+# 0b10010 => [ 0b01100, 2, 0b01100 ], [ 0b00001, 1, 0b00001]
+# 0b01010 => [ 0b10000, 1, 0b10000 ], [ 0b00100, 1, 0b00100 ], [ 0b00001, 1, 0b00001]
+# 0b10001 => [ 0b01110, 3, 0b01110 ]
+def create_collector_support
+ odd_map = [0b11, 0b110, 0b1100, 0b11000, 0b10000]
+ even_map = [0b1, 0b11, 0b110, 0b1100, 0b11000]
+
+ all_odds = Array.new(0b100000)
+ all_evens = Array.new(0b100000)
+ bit_counts = Array.new(0b100000)
+ new_regions = Array.new(0b100000)
+ 0.upto(0b11111) do | i |
+ bit_count = odd = even = 0
+ 0.upto(4) do | bit |
+ if (i[bit] == 1) then
+ bit_count += 1
+ odd |= odd_map[bit]
+ even |= even_map[bit]
+ end
+ end
+ all_odds[i] = odd
+ all_evens[i] = even
+ bit_counts[i] = bit_count
+ new_regions[i] = create_regions( i)
+ end
+
+ $converter = []
+ 10.times { | row | $converter.push((row % 2 == 0) ? all_evens : all_odds) }
+ $bit_counts = bit_counts
+ $regions = new_regions.collect { | set | set.collect { | value | [ value, bit_counts[value], value] } }
+end
+
+# determines if a board is punable, meaning that there is no possibility that it
+# can be filled up with pieces. A board is prunable if there is a grouping of unfilled spaces
+# that are not a multiple of five. The following board is an example of a prunable board:
+# 0 0 1 0 0
+# 0 1 0 0 0
+# 1 1 0 0 0
+# 0 1 0 0 0
+# 0 0 0 0 0
+# ...
+#
+# This board is prunable because the top left corner is only 3 bits in area, no piece will ever fit it
+# parameters:
+# board -- an initial bit board (6 bit padded rows, see blank_board for format)
+# location -- starting location, everything above and to the left is already full
+# slotting -- set to true only when testing initial pieces, when filling normally
+# additional assumptions are possible
+#
+# Algorithm:
+# The algorithm starts at the top row (as determined by location) and iterates a row at a time
+# maintainng counts of active open areas (kept in the collector array) each collector contains
+# three values at the start of an iteration:
+# 0: mask of bits that would be adjacent to the collector in this row
+# 1: the number of bits collected so far
+# 2: a scratch space starting as zero, but used during the computation to represent
+# the empty bits in the new row that are adjacent (position 0)
+# The exact procedure is described in-code
+def prunable( board, location, slotting = false)
+ collectors = []
+ # loop across the rows
+ (location / 6).to_i.upto(9) do | row_on |
+ # obtain a set of regions representing the bits of the current row.
+ regions = $regions[(board >> (row_on * 6)) & 0b11111]
+ converter = $converter[row_on]
+
+ # track the number of collectors at the start of the cycle so that
+ # we don't compute against newly created collectors, only existing collectors
+ initial_collector_count = collectors.length
+
+ # loop against the regions. For each region of the row
+ # we will see if it connects to one or more existing collectors.
+ # if it connects to 1 collector, the bits from the region are added to the
+ # bits of the collector and the mask is placed in collector[2]
+ # If the region overlaps more than one collector then all the collectors
+ # it overlaps with are merged into the first one (the others are set to nil in the array)
+ # if NO collectors are found then the region is copied as a new collector
+ regions.each do | region |
+ collector_found = nil
+ region_mask = region[2]
+ initial_collector_count.times do | collector_num |
+ collector = collectors[collector_num]
+ if (collector) then
+ collector_mask = collector[0]
+ if (collector_mask & region_mask != 0) then
+ if (collector_found) then
+ collector_found[0] |= collector_mask
+ collector_found[1] += collector[1]
+ collector_found[2] |= collector[2]
+ collectors[collector_num] = nil
+ else
+ collector_found = collector
+ collector[1] += region[1]
+ collector[2] |= region_mask
+ end
+ end
+ end
+ end
+ if (collector_found == nil) then
+ collectors.push(Array.new(region))
+ end
+ end
+
+ # check the existing collectors, if any collector overlapped no bits in the region its [2] value will
+ # be zero. The size of any such reaason is tested if it is not a multiple of five true is returned since
+ # the board is prunable. if it is a multiple of five it is removed.
+ # Collector that are still active have a new adjacent value [0] set based n the matched bits
+ # and have [2] cleared out for the next cycle.
+ collectors.length.times do | collector_num |
+ collector = collectors[collector_num]
+ if (collector) then
+ if (collector[2] == 0) then
+ return true if (collector[1] % 5 != 0)
+ collectors[collector_num] = nil
+ else
+ # if a collector matches all bits in the row then we can return unprunable early for the
+ # following reasons:
+ # 1) there can be no more unavailable bits bince we fill from the top left downward
+ # 2) all previous regions have been closed or joined so only this region can fail
+ # 3) this region must be good since there can never be only 1 region that is nuot
+ # a multiple of five
+ # this rule only applies when filling normally, so we ignore the rule if we are "slotting"
+ # in pieces to see what configurations work for them (the only other time this algorithm is used).
+ return false if (collector[2] == 0b11111 && !slotting)
+ collector[0] = converter[collector[2]]
+ collector[2] = 0
+ end
+ end
+ end
+
+ # get rid of all the empty converters for the next round
+ collectors.compact!
+ end
+ return false if (collectors.length <= 1) # 1 collector or less and the region is fine
+ collectors.any? { | collector | (collector[1] % 5) != 0 } # more than 1 and we test them all for bad size
+end
+
+# creates a region given a row mask. see prunable for what a "region" is
+def create_regions( value )
+ regions = []
+ cur_region = 0
+ 5.times do | bit |
+ if (value[bit] == 0) then
+ cur_region |= 1 << bit
+ else
+ if (cur_region != 0 ) then
+ regions.push( cur_region)
+ cur_region = 0;
+ end
+ end
+ end
+ regions.push(cur_region) if (cur_region != 0)
+ regions
+end
+
+# find up to the counted number of solutions (or all solutions) and prints the final result
+def find_all
+ find_top( 1)
+ find_top( 0)
+ print_results
+end
+
+# show the board
+def print_results
+ print "#{@boards_found} solutions found\n\n"
+ print_full_board( @min_board)
+ print "\n"
+ print_full_board( @max_board)
+ print "\n"
+end
+
+# finds solutions. This special version of the main function is only used for the top level
+# the reason for it is basically to force a particular ordering on how the rotations are tested for
+# the first piece. It is called twice, first looking for placements of the odd rotations and then
+# looking for placements of the even locations.
+#
+# WHY?
+# Since any found solution has an inverse we want to maximize finding solutions that are not already found
+# as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away
+# (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier
+# in the cycle. We still need to keep checking all the permutations, but our probability of finding one will
+# diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces
+# this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the
+# maximum number
+def find_top( rotation_skip)
+ board = blank_board
+ (@pieces.length-1).times do
+ piece = @pieces.shift
+ piece.masks[0].each do | mask, imask, cmask |
+ if ((rotation_skip += 1) % 2 == 0) then
+ piece.placed = mask
+ find( 1, 1, board | mask)
+ end
+ end
+ @pieces.push(piece)
+ end
+ piece = @pieces.shift
+ @pieces.push(piece)
+end
+
+# the normail find routine, iterates through the available pieces, checks all rotations at the current location
+# and adds any boards found. depth is achieved via recursion. the overall approach is described
+# here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/
+# parameters:
+# start_location -- where to start looking for place for the next piece at
+# placed -- number of pieces placed
+# board -- current state of the board
+#
+# see in-code comments
+def find( start_location, placed, board)
+ # find the next location to place a piece by looking for an empty bit
+ while board[start_location] == 1
+ start_location += 1
+ end
+
+ @pieces.length.times do
+ piece = @pieces.shift
+ piece.masks[start_location].each do | mask, imask, cmask |
+ if ( board & cmask == imask) then
+ piece.placed = mask
+ if (placed == 9) then
+ add_board
+ else
+ find( start_location + 1, placed + 1, board | mask)
+ end
+ end
+ end
+ @pieces.push(piece)
+ end
+end
+
+# print the board
+def print_full_board( board_string)
+ 10.times do | row |
+ print " " if (row % 2 == 1)
+ 5.times do | col |
+ print "#{board_string[row*5 + col,1]} "
+ end
+ print "\n"
+ end
+end
+
+# when a board is found we "draw it" into a string and then flip that string, adding both to
+# the list (hash) of solutions if they are unique.
+def add_board
+ board_string = "99999999999999999999999999999999999999999999999999"
+ @all_pieces.each { | piece | piece.fill_string( board_string ) }
+ save( board_string)
+ save( board_string.reverse)
+end
+
+# adds a board string to the list (if new) and updates the current best/worst board
+def save( board_string)
+ if (@all_boards[board_string] == nil) then
+ @min_board = board_string if (board_string < @min_board)
+ @max_board = board_string if (board_string > @max_board)
+ @all_boards.store(board_string,true)
+ @boards_found += 1
+
+ # the exit motif is a time saver. Ideally the function should return, but those tests
+ # take noticeable time (performance).
+ if (@boards_found == @stop_count) then
+ print_results
+ exit(0)
+ end
+ end
+end
+
+
+##
+## MAIN BODY :)
+##
+create_collector_support
+@pieces = [
+ Piece.new( [ :nw, :ne, :east, :east ], 2),
+ Piece.new( [ :ne, :se, :east, :ne ], 7),
+ Piece.new( [ :ne, :east, :ne, :nw ], 1),
+ Piece.new( [ :east, :sw, :sw, :se ], 6),
+ Piece.new( [ :east, :ne, :se, :ne ], 5),
+ Piece.new( [ :east, :east, :east, :se ], 0),
+ Piece.new( [ :ne, :nw, :se, :east, :se ], 4),
+ Piece.new( [ :se, :se, :se, :west ], 9),
+ Piece.new( [ :se, :se, :east, :se ], 8),
+ Piece.new( [ :east, :east, :sw, :se ], 3)
+ ];
+
+@all_pieces = Array.new( @pieces)
+
+@min_board = "99999999999999999999999999999999999999999999999999"
+@max_board = "00000000000000000000000000000000000000000000000000"
+@stop_count = ARGV[0].to_i || 2089
+@all_boards = {}
+@boards_found = 0
+
+find_all ######## DO IT!!!
diff --git a/benchmark/bm_so_nbody.rb b/benchmark/bm_so_nbody.rb
new file mode 100644
index 0000000000..d6c5bb9e61
--- /dev/null
+++ b/benchmark/bm_so_nbody.rb
@@ -0,0 +1,148 @@
+# The Computer Language Shootout
+# http://shootout.alioth.debian.org
+#
+# Optimized for Ruby by Jesse Millikan
+# From version ported by Michael Neumann from the C gcc version,
+# which was written by Christoph Bauer.
+
+SOLAR_MASS = 4 * Math::PI**2
+DAYS_PER_YEAR = 365.24
+
+def _puts *args
+end
+
+class Planet
+ attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass
+
+ def initialize(x, y, z, vx, vy, vz, mass)
+ @x, @y, @z = x, y, z
+ @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR
+ @mass = mass * SOLAR_MASS
+ end
+
+ def move_from_i(bodies, nbodies, dt, i)
+ while i < nbodies
+ b2 = bodies[i]
+ dx = @x - b2.x
+ dy = @y - b2.y
+ dz = @z - b2.z
+
+ distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
+ mag = dt / (distance * distance * distance)
+ b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag
+
+ @vx -= dx * b2_mass_mag
+ @vy -= dy * b2_mass_mag
+ @vz -= dz * b2_mass_mag
+ b2.vx += dx * b_mass_mag
+ b2.vy += dy * b_mass_mag
+ b2.vz += dz * b_mass_mag
+ i += 1
+ end
+
+ @x += dt * @vx
+ @y += dt * @vy
+ @z += dt * @vz
+ end
+end
+
+def energy(bodies)
+ e = 0.0
+ nbodies = bodies.size
+
+ for i in 0 ... nbodies
+ b = bodies[i]
+ e += 0.5 * b.mass * (b.vx * b.vx + b.vy * b.vy + b.vz * b.vz)
+ for j in (i + 1) ... nbodies
+ b2 = bodies[j]
+ dx = b.x - b2.x
+ dy = b.y - b2.y
+ dz = b.z - b2.z
+ distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
+ e -= (b.mass * b2.mass) / distance
+ end
+ end
+ e
+end
+
+def offset_momentum(bodies)
+ px, py, pz = 0.0, 0.0, 0.0
+
+ for b in bodies
+ m = b.mass
+ px += b.vx * m
+ py += b.vy * m
+ pz += b.vz * m
+ end
+
+ b = bodies[0]
+ b.vx = - px / SOLAR_MASS
+ b.vy = - py / SOLAR_MASS
+ b.vz = - pz / SOLAR_MASS
+end
+
+BODIES = [
+ # sun
+ Planet.new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0),
+
+ # jupiter
+ Planet.new(
+ 4.84143144246472090e+00,
+ -1.16032004402742839e+00,
+ -1.03622044471123109e-01,
+ 1.66007664274403694e-03,
+ 7.69901118419740425e-03,
+ -6.90460016972063023e-05,
+ 9.54791938424326609e-04),
+
+ # saturn
+ Planet.new(
+ 8.34336671824457987e+00,
+ 4.12479856412430479e+00,
+ -4.03523417114321381e-01,
+ -2.76742510726862411e-03,
+ 4.99852801234917238e-03,
+ 2.30417297573763929e-05,
+ 2.85885980666130812e-04),
+
+ # uranus
+ Planet.new(
+ 1.28943695621391310e+01,
+ -1.51111514016986312e+01,
+ -2.23307578892655734e-01,
+ 2.96460137564761618e-03,
+ 2.37847173959480950e-03,
+ -2.96589568540237556e-05,
+ 4.36624404335156298e-05),
+
+ # neptune
+ Planet.new(
+ 1.53796971148509165e+01,
+ -2.59193146099879641e+01,
+ 1.79258772950371181e-01,
+ 2.68067772490389322e-03,
+ 1.62824170038242295e-03,
+ -9.51592254519715870e-05,
+ 5.15138902046611451e-05)
+]
+
+init = 200_000 # ARGV[0]
+n = Integer(init)
+
+offset_momentum(BODIES)
+
+puts "%.9f" % energy(BODIES)
+
+nbodies = BODIES.size
+dt = 0.01
+
+n.times do
+ i = 0
+ while i < nbodies
+ b = BODIES[i]
+ b.move_from_i(BODIES, nbodies, dt, i + 1)
+ i += 1
+ end
+end
+
+puts "%.9f" % energy(BODIES)
diff --git a/benchmark/bm_so_nested_loop.rb b/benchmark/bm_so_nested_loop.rb
new file mode 100644
index 0000000000..a0513f8c47
--- /dev/null
+++ b/benchmark/bm_so_nested_loop.rb
@@ -0,0 +1,24 @@
+#!/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_nsieve.rb b/benchmark/bm_so_nsieve.rb
new file mode 100644
index 0000000000..a65cc78233
--- /dev/null
+++ b/benchmark/bm_so_nsieve.rb
@@ -0,0 +1,35 @@
+# The Computer Language Shootout
+# http://shootout.alioth.debian.org/
+#
+# contributed by Glenn Parker, March 2005
+# modified by Evan Phoenix, Sept 2006
+
+def sieve(m)
+ flags = Flags.dup[0,m]
+ count = 0
+ pmax = m - 1
+ p = 2
+ while p <= pmax
+ unless flags[p].zero?
+ count += 1
+ mult = p
+ while mult <= pmax
+ flags[mult] = 0
+ mult += p
+ end
+ end
+ p += 1
+ end
+ count
+end
+
+n = 9 # (ARGV[0] || 2).to_i
+Flags = ("\x1" * ( 2 ** n * 10_000)).unpack("c*")
+
+n.downto(n-2) do |exponent|
+ break if exponent < 0
+ m = (1 << exponent) * 10_000
+ # m = (2 ** exponent) * 10_000
+ count = sieve(m)
+ printf "Primes up to %8d %8d\n", m, count
+end
diff --git a/benchmark/bm_so_nsieve_bits.rb b/benchmark/bm_so_nsieve_bits.rb
new file mode 100644
index 0000000000..6f958ee44e
--- /dev/null
+++ b/benchmark/bm_so_nsieve_bits.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/ruby
+#coding: us-ascii
+#
+# The Great Computer Language Shootout
+# http://shootout.alioth.debian.org/
+#
+# nsieve-bits in Ruby
+# Contributed by Glenn Parker, March 2005
+
+CharExponent = 3
+BitsPerChar = 1 << CharExponent
+LowMask = BitsPerChar - 1
+
+def sieve(m)
+ items = "\xFF" * ((m / BitsPerChar) + 1)
+ masks = ""
+ BitsPerChar.times do |b|
+ masks << (1 << b).chr
+ end
+
+ count = 0
+ pmax = m - 1
+ 2.step(pmax, 1) do |p|
+ if items[p >> CharExponent][p & LowMask] == 1
+ count += 1
+ p.step(pmax, p) do |mult|
+ a = mult >> CharExponent
+ b = mult & LowMask
+ items[a] -= masks[b] if items[a][b] != 0
+ end
+ end
+ end
+ count
+end
+
+n = 9 # (ARGV[0] || 2).to_i
+n.step(n - 2, -1) do |exponent|
+ break if exponent < 0
+ m = 2 ** exponent * 10_000
+ count = sieve(m)
+ printf "Primes up to %8d %8d\n", m, count
+end
+
diff --git a/benchmark/bm_so_object.rb b/benchmark/bm_so_object.rb
new file mode 100644
index 0000000000..e8607c7199
--- /dev/null
+++ b/benchmark/bm_so_object.rb
@@ -0,0 +1,56 @@
+#!/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_partial_sums.rb b/benchmark/bm_so_partial_sums.rb
new file mode 100644
index 0000000000..630b45cb8d
--- /dev/null
+++ b/benchmark/bm_so_partial_sums.rb
@@ -0,0 +1,31 @@
+n = 2_500_000 # (ARGV.shift || 1).to_i
+
+alt = 1.0 ; s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = 0.0
+
+1.upto(n) do |d|
+ d = d.to_f ; d2 = d * d ; d3 = d2 * d ; ds = Math.sin(d) ; dc = Math.cos(d)
+
+ s0 += (2.0 / 3.0) ** (d - 1.0)
+ s1 += 1.0 / Math.sqrt(d)
+ s2 += 1.0 / (d * (d + 1.0))
+ s3 += 1.0 / (d3 * ds * ds)
+ s4 += 1.0 / (d3 * dc * dc)
+ s5 += 1.0 / d
+ s6 += 1.0 / d2
+ s7 += alt / d
+ s8 += alt / (2.0 * d - 1.0)
+
+ alt = -alt
+end
+
+if false
+ printf("%.9f\t(2/3)^k\n", s0)
+ printf("%.9f\tk^-0.5\n", s1)
+ printf("%.9f\t1/k(k+1)\n", s2)
+ printf("%.9f\tFlint Hills\n", s3)
+ printf("%.9f\tCookson Hills\n", s4)
+ printf("%.9f\tHarmonic\n", s5)
+ printf("%.9f\tRiemann Zeta\n", s6)
+ printf("%.9f\tAlternating Harmonic\n", s7)
+ printf("%.9f\tGregory\n", s8)
+end
diff --git a/benchmark/bm_so_pidigits.rb b/benchmark/bm_so_pidigits.rb
new file mode 100644
index 0000000000..9a537b2d1c
--- /dev/null
+++ b/benchmark/bm_so_pidigits.rb
@@ -0,0 +1,92 @@
+# The Great Computer Language Shootout
+# http://shootout.alioth.debian.org/
+#
+# contributed by Gabriele Renzi
+
+class PiDigitSpigot
+
+ def initialize()
+ @z = Transformation.new 1,0,0,1
+ @x = Transformation.new 0,0,0,0
+ @inverse = Transformation.new 0,0,0,0
+ end
+
+ def next!
+ @y = @z.extract(3)
+ if safe? @y
+ @z = produce(@y)
+ @y
+ else
+ @z = consume @x.next!()
+ next!()
+ end
+ end
+
+ def safe?(digit)
+ digit == @z.extract(4)
+ end
+
+ def produce(i)
+ @inverse.qrst(10,-10*i,0,1).compose(@z)
+ end
+
+ def consume(a)
+ @z.compose(a)
+ end
+end
+
+
+class Transformation
+ attr_reader :q, :r, :s, :t
+ def initialize(q, r, s, t)
+ @q,@r,@s,@t,@k = q,r,s,t,0
+ end
+
+ def next!()
+ @q = @k = @k + 1
+ @r = 4 * @k + 2
+ @s = 0
+ @t = 2 * @k + 1
+ self
+ end
+
+ def extract(j)
+ (@q * j + @r) / (@s * j + @t)
+ end
+
+ def compose(a)
+ self.class.new( @q * a.q,
+ @q * a.r + r * a.t,
+ @s * a.q + t * a.s,
+ @s * a.r + t * a.t
+ )
+ end
+
+ def qrst *args
+ initialize *args
+ self
+ end
+
+
+end
+
+
+WIDTH = 10
+n = 2_500 # Integer(ARGV[0])
+j = 0
+
+digits = PiDigitSpigot.new
+
+while n > 0
+ if n >= WIDTH
+ WIDTH.times {print digits.next!}
+ j += WIDTH
+ else
+ n.times {print digits.next!}
+ (WIDTH-n).times {print " "}
+ j += n
+ end
+ puts "\t:"+j.to_s
+ n -= WIDTH
+end
+
diff --git a/benchmark/bm_so_random.rb b/benchmark/bm_so_random.rb
new file mode 100644
index 0000000000..a66b9e8e63
--- /dev/null
+++ b/benchmark/bm_so_random.rb
@@ -0,0 +1,20 @@
+# from http://www.bagley.org/~doug/shootout/bench/random/random.ruby
+
+IM = 139968.0
+IA = 3877.0
+IC = 29573.0
+
+$last = 42.0
+
+def gen_random(max)
+ (max * ($last = ($last * IA + IC) % IM)) / IM
+end
+
+N = 3_000_000
+
+i = 0
+while i<N
+ i +=1
+ gen_random(100.0)
+end
+# "%.9f" % gen_random(100.0)
diff --git a/benchmark/bm_so_reverse_complement.rb b/benchmark/bm_so_reverse_complement.rb
new file mode 100644
index 0000000000..82ea666994
--- /dev/null
+++ b/benchmark/bm_so_reverse_complement.rb
@@ -0,0 +1,30 @@
+#!/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_so_sieve.rb b/benchmark/bm_so_sieve.rb
new file mode 100644
index 0000000000..43dc302648
--- /dev/null
+++ b/benchmark/bm_so_sieve.rb
@@ -0,0 +1,24 @@
+# from http://www.bagley.org/~doug/shootout/bench/sieve/sieve.ruby
+num = 500
+count = i = j = 0
+flags0 = Array.new(8192,1)
+k = 0
+while k < num
+ k += 1
+ count = 0
+ flags = flags0.dup
+ i = 2
+ while i<8192
+ i += 1
+ if flags[i]
+ # remove all multiples of prime: i
+ j = i*i
+ while j < 8192
+ j += i
+ flags[j] = nil
+ end
+ count += 1
+ end
+ end
+end
+count
diff --git a/benchmark/bm_so_spectralnorm.rb b/benchmark/bm_so_spectralnorm.rb
new file mode 100644
index 0000000000..6b97206689
--- /dev/null
+++ b/benchmark/bm_so_spectralnorm.rb
@@ -0,0 +1,50 @@
+# The Computer Language Shootout
+# http://shootout.alioth.debian.org/
+# Contributed by Sokolov Yura
+
+def eval_A(i,j)
+ return 1.0/((i+j)*(i+j+1)/2+i+1)
+end
+
+def eval_A_times_u(u)
+ v, i = nil, nil
+ (0..u.length-1).collect { |i|
+ v = 0
+ for j in 0..u.length-1
+ v += eval_A(i,j)*u[j]
+ end
+ v
+ }
+end
+
+def eval_At_times_u(u)
+ v, i = nil, nil
+ (0..u.length-1).collect{|i|
+ v = 0
+ for j in 0..u.length-1
+ v += eval_A(j,i)*u[j]
+ end
+ v
+ }
+end
+
+def eval_AtA_times_u(u)
+ return eval_At_times_u(eval_A_times_u(u))
+end
+
+n = 500 # ARGV[0].to_i
+
+u=[1]*n
+for i in 1..10
+ v=eval_AtA_times_u(u)
+ u=eval_AtA_times_u(v)
+end
+vBv=0
+vv=0
+for i in 0..n-1
+ vBv += u[i]*v[i]
+ vv += v[i]*v[i]
+end
+
+str = "%0.9f" % (Math.sqrt(vBv/vv)), "\n"
+# print str
diff --git a/benchmark/bm_string_index.rb b/benchmark/bm_string_index.rb
new file mode 100644
index 0000000000..7783111082
--- /dev/null
+++ b/benchmark/bm_string_index.rb
@@ -0,0 +1,3 @@
+str1 = "ã‚" * 1024 + "ã„" # not single byte optimizable
+str2 = "ã„"
+100_000.times { str1.index(str2) }
diff --git a/benchmark/bm_string_scan_re.rb b/benchmark/bm_string_scan_re.rb
new file mode 100644
index 0000000000..b0d60201a9
--- /dev/null
+++ b/benchmark/bm_string_scan_re.rb
@@ -0,0 +1,2 @@
+str = Array.new(1_000, 'abc').join(',')
+1_000.times { str.scan(/abc/) }
diff --git a/benchmark/bm_string_scan_str.rb b/benchmark/bm_string_scan_str.rb
new file mode 100644
index 0000000000..42440bd948
--- /dev/null
+++ b/benchmark/bm_string_scan_str.rb
@@ -0,0 +1,2 @@
+str = Array.new(1_000, 'abc').join(',')
+1_000.times { str.scan('abc') }
diff --git a/benchmark/bm_time_subsec.rb b/benchmark/bm_time_subsec.rb
new file mode 100644
index 0000000000..505021c701
--- /dev/null
+++ b/benchmark/bm_time_subsec.rb
@@ -0,0 +1,2 @@
+t = Time.now
+4000000.times { t.subsec }
diff --git a/benchmark/bm_vm1_attr_ivar.rb b/benchmark/bm_vm1_attr_ivar.rb
new file mode 100644
index 0000000000..16906f3605
--- /dev/null
+++ b/benchmark/bm_vm1_attr_ivar.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..7e7a6b48c0
--- /dev/null
+++ b/benchmark/bm_vm1_attr_ivar_set.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..a9f56b15ea
--- /dev/null
+++ b/benchmark/bm_vm1_block.rb
@@ -0,0 +1,10 @@
+def m
+ yield
+end
+
+i = 0
+while i<30_000_000 # while loop 1
+ i += 1
+ m{
+ }
+end
diff --git a/benchmark/bm_vm1_blockparam.rb b/benchmark/bm_vm1_blockparam.rb
new file mode 100755
index 0000000000..11680a2e61
--- /dev/null
+++ b/benchmark/bm_vm1_blockparam.rb
@@ -0,0 +1,9 @@
+def m &b
+end
+
+i = 0
+while i<30_000_000 # while loop 1
+ i += 1
+ m{}
+end
+
diff --git a/benchmark/bm_vm1_blockparam_call.rb b/benchmark/bm_vm1_blockparam_call.rb
new file mode 100755
index 0000000000..f6102a2b5a
--- /dev/null
+++ b/benchmark/bm_vm1_blockparam_call.rb
@@ -0,0 +1,9 @@
+def m &b
+ b.call
+end
+
+i = 0
+while i<30_000_000 # while loop 1
+ i += 1
+ m{}
+end
diff --git a/benchmark/bm_vm1_blockparam_pass.rb b/benchmark/bm_vm1_blockparam_pass.rb
new file mode 100755
index 0000000000..10029a257a
--- /dev/null
+++ b/benchmark/bm_vm1_blockparam_pass.rb
@@ -0,0 +1,13 @@
+def bp_yield
+ yield
+end
+
+def bp_pass &b
+ bp_yield &b
+end
+
+i = 0
+while i<30_000_000 # while loop 1
+ i += 1
+ bp_pass{}
+end
diff --git a/benchmark/bm_vm1_blockparam_yield.rb b/benchmark/bm_vm1_blockparam_yield.rb
new file mode 100755
index 0000000000..6dc01ced7c
--- /dev/null
+++ b/benchmark/bm_vm1_blockparam_yield.rb
@@ -0,0 +1,9 @@
+def bp_yield &b
+ yield
+end
+
+i = 0
+while i<30_000_000 # while loop 1
+ i += 1
+ bp_yield{}
+end
diff --git a/benchmark/bm_vm1_const.rb b/benchmark/bm_vm1_const.rb
new file mode 100644
index 0000000000..ac59ebccf1
--- /dev/null
+++ b/benchmark/bm_vm1_const.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000000..a1596145f2
--- /dev/null
+++ b/benchmark/bm_vm1_ensure.rb
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 0000000000..d4581439ff
--- /dev/null
+++ b/benchmark/bm_vm1_float_simple.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..e78bca5668
--- /dev/null
+++ b/benchmark/bm_vm1_gc_short_lived.rb
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 0000000000..b66052dee0
--- /dev/null
+++ b/benchmark/bm_vm1_gc_short_with_complex_long.rb
@@ -0,0 +1,27 @@
+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
new file mode 100644
index 0000000000..298dbc845b
--- /dev/null
+++ b/benchmark/bm_vm1_gc_short_with_long.rb
@@ -0,0 +1,13 @@
+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
new file mode 100644
index 0000000000..6b15c1b7bf
--- /dev/null
+++ b/benchmark/bm_vm1_gc_short_with_symbol.rb
@@ -0,0 +1,15 @@
+# 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
new file mode 100644
index 0000000000..1b030386cf
--- /dev/null
+++ b/benchmark/bm_vm1_gc_wb_ary.rb
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 0000000000..ebc369a60f
--- /dev/null
+++ b/benchmark/bm_vm1_gc_wb_ary_promoted.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..96f4261915
--- /dev/null
+++ b/benchmark/bm_vm1_gc_wb_obj.rb
@@ -0,0 +1,15 @@
+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
new file mode 100644
index 0000000000..674c413992
--- /dev/null
+++ b/benchmark/bm_vm1_gc_wb_obj_promoted.rb
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 0000000000..68a73cf92f
--- /dev/null
+++ b/benchmark/bm_vm1_ivar.rb
@@ -0,0 +1,8 @@
+@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
new file mode 100644
index 0000000000..bd81b06c34
--- /dev/null
+++ b/benchmark/bm_vm1_ivar_set.rb
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000000..353de3ab0e
--- /dev/null
+++ b/benchmark/bm_vm1_length.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..36f2068811
--- /dev/null
+++ b/benchmark/bm_vm1_lvar_init.rb
@@ -0,0 +1,18 @@
+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
new file mode 100644
index 0000000000..222e864134
--- /dev/null
+++ b/benchmark/bm_vm1_lvar_set.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..bbb4ae07a4
--- /dev/null
+++ b/benchmark/bm_vm1_neq.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000000..b09ecdcc21
--- /dev/null
+++ b/benchmark/bm_vm1_not.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..b0d3e2bdfa
--- /dev/null
+++ b/benchmark/bm_vm1_rescue.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..63f9f21675
--- /dev/null
+++ b/benchmark/bm_vm1_simplereturn.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..918f8b2112
--- /dev/null
+++ b/benchmark/bm_vm1_swap.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000000..775597cea6
--- /dev/null
+++ b/benchmark/bm_vm1_yield.rb
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 0000000000..df9037c83c
--- /dev/null
+++ b/benchmark/bm_vm2_array.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..b02509d6a2
--- /dev/null
+++ b/benchmark/bm_vm2_bigarray.rb
@@ -0,0 +1,106 @@
+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
new file mode 100644
index 0000000000..5e3f437bb8
--- /dev/null
+++ b/benchmark/bm_vm2_bighash.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..adc6e4df0a
--- /dev/null
+++ b/benchmark/bm_vm2_case.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..c62b294e0e
--- /dev/null
+++ b/benchmark/bm_vm2_case_lit.rb
@@ -0,0 +1,19 @@
+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
new file mode 100644
index 0000000000..053ed6c912
--- /dev/null
+++ b/benchmark/bm_vm2_defined_method.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..58c0f7bbc3
--- /dev/null
+++ b/benchmark/bm_vm2_dstr.rb
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000000..307cfc28ef
--- /dev/null
+++ b/benchmark/bm_vm2_eval.rb
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000000..c6f615d71d
--- /dev/null
+++ b/benchmark/bm_vm2_fiber_switch.rb
@@ -0,0 +1,9 @@
+# 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
new file mode 100644
index 0000000000..a8ccff7138
--- /dev/null
+++ b/benchmark/bm_vm2_method.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..2badc73101
--- /dev/null
+++ b/benchmark/bm_vm2_method_missing.rb
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 0000000000..b4efb4f520
--- /dev/null
+++ b/benchmark/bm_vm2_method_with_block.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..12ccfd2ff3
--- /dev/null
+++ b/benchmark/bm_vm2_module_ann_const_set.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..f4d4c1b2e7
--- /dev/null
+++ b/benchmark/bm_vm2_module_const_set.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000000..5d16480c6b
--- /dev/null
+++ b/benchmark/bm_vm2_mutex.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..6422c9b0d0
--- /dev/null
+++ b/benchmark/bm_vm2_newlambda.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..c82c0e4bce
--- /dev/null
+++ b/benchmark/bm_vm2_poly_method.rb
@@ -0,0 +1,20 @@
+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
new file mode 100644
index 0000000000..aa5fd1dd38
--- /dev/null
+++ b/benchmark/bm_vm2_poly_method_ov.rb
@@ -0,0 +1,20 @@
+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
new file mode 100644
index 0000000000..0dba4320c4
--- /dev/null
+++ b/benchmark/bm_vm2_poly_singleton.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..65e5217371
--- /dev/null
+++ b/benchmark/bm_vm2_proc.rb
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..aa5387987f
--- /dev/null
+++ b/benchmark/bm_vm2_raise1.rb
@@ -0,0 +1,18 @@
+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
new file mode 100644
index 0000000000..1f61c63157
--- /dev/null
+++ b/benchmark/bm_vm2_raise2.rb
@@ -0,0 +1,18 @@
+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
new file mode 100644
index 0000000000..55f9e957a3
--- /dev/null
+++ b/benchmark/bm_vm2_regexp.rb
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000000..6a3ab6fdab
--- /dev/null
+++ b/benchmark/bm_vm2_send.rb
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 0000000000..1d73036849
--- /dev/null
+++ b/benchmark/bm_vm2_string_literal.rb
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000000..22cb26b0a5
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_aref_hi.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..5e61a7087e
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_aref_lo.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..5a1c3d16f3
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_aset.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..fff940a80a
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_href_hi.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..5e4085d59d
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_href_lo.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..9c0cee4141
--- /dev/null
+++ b/benchmark/bm_vm2_struct_big_hset.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..8eaa555b41
--- /dev/null
+++ b/benchmark/bm_vm2_struct_small_aref.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..ecd0f95669
--- /dev/null
+++ b/benchmark/bm_vm2_struct_small_aset.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..2c88fee6bf
--- /dev/null
+++ b/benchmark/bm_vm2_struct_small_href.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..33c36d20f1
--- /dev/null
+++ b/benchmark/bm_vm2_struct_small_hset.rb
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000000..afd8579e7b
--- /dev/null
+++ b/benchmark/bm_vm2_super.rb
@@ -0,0 +1,20 @@
+
+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
new file mode 100644
index 0000000000..1774625942
--- /dev/null
+++ b/benchmark/bm_vm2_unif1.rb
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000000..2a43e62217
--- /dev/null
+++ b/benchmark/bm_vm2_zsuper.rb
@@ -0,0 +1,20 @@
+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_vm3_backtrace.rb b/benchmark/bm_vm3_backtrace.rb
new file mode 100644
index 0000000000..0fbf73e1ca
--- /dev/null
+++ b/benchmark/bm_vm3_backtrace.rb
@@ -0,0 +1,22 @@
+# get last backtrace
+
+begin
+ caller(0, 0)
+rescue ArgumentError
+ alias caller_orig caller
+ def caller lev, n
+ caller_orig(lev)[0..n]
+ end
+end
+
+def rec n
+ if n < 0
+ 100_000.times{
+ caller(0, 1)
+ }
+ else
+ rec(n-1)
+ end
+end
+
+rec 50
diff --git a/benchmark/bm_vm3_clearmethodcache.rb b/benchmark/bm_vm3_clearmethodcache.rb
new file mode 100644
index 0000000000..9661323cd2
--- /dev/null
+++ b/benchmark/bm_vm3_clearmethodcache.rb
@@ -0,0 +1,8 @@
+i = 0
+while i<200_000
+ i += 1
+
+ Class.new{
+ def m; end
+ }
+end
diff --git a/benchmark/bm_vm3_gc.rb b/benchmark/bm_vm3_gc.rb
new file mode 100644
index 0000000000..e668026915
--- /dev/null
+++ b/benchmark/bm_vm3_gc.rb
@@ -0,0 +1,6 @@
+5000.times do
+ 100.times do
+ {"xxxx"=>"yyyy"}
+ end
+ GC.start
+end
diff --git a/benchmark/bm_vm3_gc_old_full.rb b/benchmark/bm_vm3_gc_old_full.rb
new file mode 100644
index 0000000000..cfdfc8c5a5
--- /dev/null
+++ b/benchmark/bm_vm3_gc_old_full.rb
@@ -0,0 +1,4 @@
+old_object = Array.new(1_000_000){''}
+100.times do
+ GC.start
+end
diff --git a/benchmark/bm_vm3_gc_old_immediate.rb b/benchmark/bm_vm3_gc_old_immediate.rb
new file mode 100644
index 0000000000..ad22feb655
--- /dev/null
+++ b/benchmark/bm_vm3_gc_old_immediate.rb
@@ -0,0 +1,4 @@
+old_object = Array.new(1_000_000){''}
+30_000.times do
+ GC.start(full_mark: false, immediate_sweep: true)
+end
diff --git a/benchmark/bm_vm3_gc_old_lazy.rb b/benchmark/bm_vm3_gc_old_lazy.rb
new file mode 100644
index 0000000000..b74d44baf1
--- /dev/null
+++ b/benchmark/bm_vm3_gc_old_lazy.rb
@@ -0,0 +1,4 @@
+old_object = Array.new(1_000_000){''}
+30_000.times do
+ GC.start(full_mark: false, immediate_sweep: false)
+end
diff --git a/benchmark/bm_vm_symbol_block_pass.rb b/benchmark/bm_vm_symbol_block_pass.rb
new file mode 100644
index 0000000000..1d433353e1
--- /dev/null
+++ b/benchmark/bm_vm_symbol_block_pass.rb
@@ -0,0 +1,13 @@
+class C
+ 1000.times {|i|
+ eval("def i#{i};end")
+ }
+end
+
+c = C.new
+m = C.instance_methods(false)
+5_000.times do
+ m.each do |n|
+ c.tap(&n)
+ end
+end
diff --git a/benchmark/bm_vm_thread_alive_check1.rb b/benchmark/bm_vm_thread_alive_check1.rb
new file mode 100644
index 0000000000..c993accdda
--- /dev/null
+++ b/benchmark/bm_vm_thread_alive_check1.rb
@@ -0,0 +1,6 @@
+5_000.times{
+ t = Thread.new{}
+ while t.alive?
+ Thread.pass
+ end
+}
diff --git a/benchmark/bm_vm_thread_close.rb b/benchmark/bm_vm_thread_close.rb
new file mode 100644
index 0000000000..3e9a265ce8
--- /dev/null
+++ b/benchmark/bm_vm_thread_close.rb
@@ -0,0 +1,6 @@
+1000.times { Thread.new { sleep } }
+i = 0
+while i<100_000 # benchmark loop 3
+ i += 1
+ IO.pipe.each(&:close)
+end
diff --git a/benchmark/bm_vm_thread_condvar1.rb b/benchmark/bm_vm_thread_condvar1.rb
new file mode 100644
index 0000000000..cf5706b23e
--- /dev/null
+++ b/benchmark/bm_vm_thread_condvar1.rb
@@ -0,0 +1,28 @@
+# two threads, two mutex, two condvar ping-pong
+require 'thread'
+m1 = Mutex.new
+m2 = Mutex.new
+cv1 = ConditionVariable.new
+cv2 = ConditionVariable.new
+max = 100000
+i = 0
+wait = nil
+m2.synchronize do
+ wait = Thread.new do
+ m1.synchronize do
+ m2.synchronize { cv2.signal }
+ while (i += 1) < max
+ cv1.wait(m1)
+ cv2.signal
+ end
+ end
+ end
+ cv2.wait(m2)
+end
+m1.synchronize do
+ while i < max
+ cv1.signal
+ cv2.wait(m1)
+ end
+end
+wait.join
diff --git a/benchmark/bm_vm_thread_condvar2.rb b/benchmark/bm_vm_thread_condvar2.rb
new file mode 100644
index 0000000000..7c8dc19481
--- /dev/null
+++ b/benchmark/bm_vm_thread_condvar2.rb
@@ -0,0 +1,35 @@
+# many threads, one mutex, many condvars
+require 'thread'
+m = Mutex.new
+cv1 = ConditionVariable.new
+cv2 = ConditionVariable.new
+max = 1000
+n = 100
+waiting = 0
+scvs = []
+waiters = n.times.map do |i|
+ start_cv = ConditionVariable.new
+ scvs << start_cv
+ start_mtx = Mutex.new
+ start_mtx.synchronize do
+ th = Thread.new(start_mtx, start_cv) do |sm, scv|
+ m.synchronize do
+ sm.synchronize { scv.signal }
+ max.times do
+ cv2.signal if (waiting += 1) == n
+ cv1.wait(m)
+ end
+ end
+ end
+ start_cv.wait(start_mtx)
+ th
+ end
+end
+m.synchronize do
+ max.times do
+ cv2.wait(m) until waiting == n
+ waiting = 0
+ cv1.broadcast
+ end
+end
+waiters.each(&:join)
diff --git a/benchmark/bm_vm_thread_create_join.rb b/benchmark/bm_vm_thread_create_join.rb
new file mode 100644
index 0000000000..393cd45df9
--- /dev/null
+++ b/benchmark/bm_vm_thread_create_join.rb
@@ -0,0 +1,6 @@
+i = 0
+while i<100_000 # benchmark loop 3
+ i += 1
+ Thread.new{
+ }.join
+end
diff --git a/benchmark/bm_vm_thread_mutex1.rb b/benchmark/bm_vm_thread_mutex1.rb
new file mode 100644
index 0000000000..66e42c85e1
--- /dev/null
+++ b/benchmark/bm_vm_thread_mutex1.rb
@@ -0,0 +1,21 @@
+# one thread, one mutex (no contention)
+
+require 'thread'
+m = Thread::Mutex.new
+r = 0
+max = 2000
+lmax = max * max
+(1..1).map{
+ Thread.new{
+ i = 0
+ while i<lmax
+ i += 1
+ m.synchronize{
+ r += 1
+ }
+ end
+ }
+}.each{|e|
+ e.join
+}
+raise r.to_s if r != max * max
diff --git a/benchmark/bm_vm_thread_mutex2.rb b/benchmark/bm_vm_thread_mutex2.rb
new file mode 100644
index 0000000000..6e6c804c31
--- /dev/null
+++ b/benchmark/bm_vm_thread_mutex2.rb
@@ -0,0 +1,21 @@
+# two threads, one mutex
+
+require 'thread'
+m = Thread::Mutex.new
+r = 0
+max = 2000
+lmax = (max * max)/2
+(1..2).map{
+ Thread.new{
+ i = 0
+ while i<lmax
+ i += 1
+ m.synchronize{
+ r += 1
+ }
+ end
+ }
+}.each{|e|
+ e.join
+}
+raise r.to_s if r != max * max
diff --git a/benchmark/bm_vm_thread_mutex3.rb b/benchmark/bm_vm_thread_mutex3.rb
new file mode 100644
index 0000000000..c750dc542a
--- /dev/null
+++ b/benchmark/bm_vm_thread_mutex3.rb
@@ -0,0 +1,20 @@
+# 1000 threads, one mutex
+
+require 'thread'
+m = Thread::Mutex.new
+r = 0
+max = 2000
+(1..max).map{
+ Thread.new{
+ i = 0
+ while i<max
+ i += 1
+ m.synchronize{
+ r += 1
+ }
+ end
+ }
+}.each{|e|
+ e.join
+}
+raise r.to_s if r != max * max
diff --git a/benchmark/bm_vm_thread_pass.rb b/benchmark/bm_vm_thread_pass.rb
new file mode 100644
index 0000000000..b5b3c0bc85
--- /dev/null
+++ b/benchmark/bm_vm_thread_pass.rb
@@ -0,0 +1,15 @@
+# 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
new file mode 100644
index 0000000000..a660aafc18
--- /dev/null
+++ b/benchmark/bm_vm_thread_pass_flood.rb
@@ -0,0 +1,10 @@
+# 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_pipe.rb b/benchmark/bm_vm_thread_pipe.rb
new file mode 100644
index 0000000000..112a621905
--- /dev/null
+++ b/benchmark/bm_vm_thread_pipe.rb
@@ -0,0 +1,17 @@
+# Measure small and plenty pipe read/write.
+# A performance may depend on GVL implementation.
+
+lmax = 100_000
+r, w = IO.pipe
+[Thread.new{
+ lmax.times{
+ w.write('a')
+ }
+ p "w:exit"
+}, Thread.new{
+ lmax.times{
+ r.read(1)
+ }
+ p "r:exit"
+}].each{|t| t.join}
+
diff --git a/benchmark/bm_vm_thread_queue.rb b/benchmark/bm_vm_thread_queue.rb
new file mode 100644
index 0000000000..274ceda366
--- /dev/null
+++ b/benchmark/bm_vm_thread_queue.rb
@@ -0,0 +1,18 @@
+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/bm_vm_thread_sized_queue.rb b/benchmark/bm_vm_thread_sized_queue.rb
new file mode 100644
index 0000000000..7b9af5482b
--- /dev/null
+++ b/benchmark/bm_vm_thread_sized_queue.rb
@@ -0,0 +1,20 @@
+require 'thread'
+# on producer, one consumer
+
+n = 1_000_000
+q = Thread::SizedQueue.new(100)
+consumer = Thread.new{
+ while q.pop
+ # consuming
+ end
+}
+
+producer = Thread.new{
+ while n > 0
+ q.push true
+ n -= 1
+ end
+ q.push nil
+}
+
+consumer.join
diff --git a/benchmark/bm_vm_thread_sized_queue2.rb b/benchmark/bm_vm_thread_sized_queue2.rb
new file mode 100644
index 0000000000..de9f55e978
--- /dev/null
+++ b/benchmark/bm_vm_thread_sized_queue2.rb
@@ -0,0 +1,23 @@
+require 'thread'
+# one producer, many consumers
+n = 1_000_000
+m = 10
+q = Thread::SizedQueue.new(100)
+consumers = m.times.map do
+ Thread.new do
+ while q.pop
+ # consuming
+ end
+ end
+end
+
+producer = Thread.new do
+ while n > 0
+ q.push true
+ n -= 1
+ end
+ m.times { q.push nil }
+end
+
+producer.join
+consumers.each(&:join)
diff --git a/benchmark/bm_vm_thread_sized_queue3.rb b/benchmark/bm_vm_thread_sized_queue3.rb
new file mode 100644
index 0000000000..ce5f1796d8
--- /dev/null
+++ b/benchmark/bm_vm_thread_sized_queue3.rb
@@ -0,0 +1,22 @@
+require 'thread'
+# many producers, one consumer
+n = 1_000_000
+m = 10
+q = Thread::SizedQueue.new(100)
+consumer = Thread.new do
+ while q.pop
+ # consuming
+ end
+end
+
+producers = m.times.map do
+ Thread.new do
+ while n > 0
+ q.push true
+ n -= 1
+ end
+ end
+end
+producers.each(&:join)
+q.push nil
+consumer.join
diff --git a/benchmark/bm_vm_thread_sized_queue4.rb b/benchmark/bm_vm_thread_sized_queue4.rb
new file mode 100644
index 0000000000..a9b7d80ec0
--- /dev/null
+++ b/benchmark/bm_vm_thread_sized_queue4.rb
@@ -0,0 +1,26 @@
+require 'thread'
+# many producers, many consumers
+nr = 1_000_000
+n = 10
+m = 10
+q = Thread::SizedQueue.new(100)
+consumers = n.times.map do
+ Thread.new do
+ while q.pop
+ # consuming
+ end
+ end
+end
+
+producers = m.times.map do
+ Thread.new do
+ while nr > 0
+ q.push true
+ nr -= 1
+ end
+ end
+end
+
+producers.each(&:join)
+n.times { q.push nil }
+consumers.each(&:join)
diff --git a/benchmark/driver.rb b/benchmark/driver.rb
new file mode 100755
index 0000000000..469fc99f40
--- /dev/null
+++ b/benchmark/driver.rb
@@ -0,0 +1,441 @@
+#!/usr/bin/env ruby
+#
+# 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('--rbenv [VERSIONS]', 'Specify benchmark targets with rbenv version (vX.X.X;vX.X.X;...)'){|v|
+ v.split(/;/).each{|version|
+ opt[:execs] << "#{version}::#{`RBENV_VERSION='#{version}' rbenv which ruby`.rstrip}"
+ }
+ }
+ 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/gc/aobench.rb b/benchmark/gc/aobench.rb
new file mode 100644
index 0000000000..2eed7abc83
--- /dev/null
+++ b/benchmark/gc/aobench.rb
@@ -0,0 +1 @@
+require_relative '../bm_app_aobench.rb'
diff --git a/benchmark/gc/binary_trees.rb b/benchmark/gc/binary_trees.rb
new file mode 100644
index 0000000000..af8ea722aa
--- /dev/null
+++ b/benchmark/gc/binary_trees.rb
@@ -0,0 +1 @@
+require_relative '../bm_so_binary_trees.rb'
diff --git a/benchmark/gc/gcbench.rb b/benchmark/gc/gcbench.rb
new file mode 100644
index 0000000000..09a404466a
--- /dev/null
+++ b/benchmark/gc/gcbench.rb
@@ -0,0 +1,56 @@
+require 'benchmark'
+require 'pp'
+require 'optparse'
+
+$list = true
+$gcprof = true
+
+opt = OptionParser.new
+opt.on('-q'){$list = false}
+opt.on('-d'){$gcprof = false}
+opt.parse!(ARGV)
+
+script = File.join(File.dirname(__FILE__), ARGV.shift)
+script += '.rb' unless FileTest.exist?(script)
+raise "#{script} not found" unless FileTest.exist?(script)
+
+puts "Script: #{script}"
+
+if $gcprof
+ GC::Profiler.enable
+end
+
+tms = Benchmark.measure{|x|
+ load script
+}
+
+gc_time = 0
+
+if $gcprof
+ gc_time = GC::Profiler.total_time
+ GC::Profiler.report if $list and RUBY_VERSION >= '2.0.0' # before 1.9.3, report() may run infinite loop
+ GC::Profiler.disable
+end
+
+pp GC.stat
+
+puts "#{RUBY_DESCRIPTION} #{GC::OPTS.inspect}" if defined?(GC::OPTS)
+
+desc = "#{RUBY_VERSION}#{RUBY_PATCHLEVEL >= 0 ? "p#{RUBY_PATCHLEVEL}" : "dev"}"
+name = File.basename(script, '.rb')
+
+puts
+puts script
+puts Benchmark::CAPTION
+puts tms
+puts "GC total time (sec): #{gc_time}"
+
+# show High-Water Mark on Linux
+if File.exist?('/proc/self/status') && /VmHWM:\s*(\d+.+)/ =~ File.read('/proc/self/status')
+ puts
+ puts "VmHWM: #{$1.chomp}"
+end
+
+puts
+puts "Summary of #{name} on #{desc}\t#{tms.real}\t#{gc_time}\t#{GC.count}"
+puts " (real time in sec, GC time in sec, GC count)"
diff --git a/benchmark/gc/hash1.rb b/benchmark/gc/hash1.rb
new file mode 100644
index 0000000000..cb030d458d
--- /dev/null
+++ b/benchmark/gc/hash1.rb
@@ -0,0 +1,11 @@
+value = 0.01
+h = {}
+n = 50_000
+
+1.upto(n){|i|
+ h["%020d" % i] = "v-#{i}"
+}
+
+(n * 1_000).times{
+ ''
+}
diff --git a/benchmark/gc/hash2.rb b/benchmark/gc/hash2.rb
new file mode 100644
index 0000000000..e8c943fb21
--- /dev/null
+++ b/benchmark/gc/hash2.rb
@@ -0,0 +1,7 @@
+value = 0.01
+h = {}
+n = 4*(10**6)
+
+1.upto(n){|i|
+ h["%020d" % i] = value * i
+}
diff --git a/benchmark/gc/null.rb b/benchmark/gc/null.rb
new file mode 100644
index 0000000000..c05a79f561
--- /dev/null
+++ b/benchmark/gc/null.rb
@@ -0,0 +1 @@
+# null
diff --git a/benchmark/gc/pentomino.rb b/benchmark/gc/pentomino.rb
new file mode 100644
index 0000000000..94ba74be89
--- /dev/null
+++ b/benchmark/gc/pentomino.rb
@@ -0,0 +1 @@
+require_relative '../bm_app_pentomino.rb'
diff --git a/benchmark/gc/rdoc.rb b/benchmark/gc/rdoc.rb
new file mode 100644
index 0000000000..14c89f5611
--- /dev/null
+++ b/benchmark/gc/rdoc.rb
@@ -0,0 +1,13 @@
+require 'rdoc/rdoc'
+require 'tmpdir'
+
+srcdir = File.expand_path('../..', __dir__)
+
+Dir.mktmpdir('rdocbench-'){|d|
+ dir = File.join(d, 'rdocbench')
+ args = %W(--root #{srcdir} --page-dir #{srcdir}/doc --encoding=UTF-8 --no-force-update --all --ri --debug --quiet #{srcdir})
+ args << '--op' << dir
+
+ r = RDoc::RDoc.new
+ r.document args
+}
diff --git a/benchmark/gc/redblack.rb b/benchmark/gc/redblack.rb
new file mode 100644
index 0000000000..c66290140a
--- /dev/null
+++ b/benchmark/gc/redblack.rb
@@ -0,0 +1,366 @@
+# This benchmark is imported from https://github.com/jruby/rubybench/blob/master/time/bench_red_black.rb
+# License is License is Apache-2
+
+require 'benchmark'
+
+# Algorithm based on "Introduction to Algorithms" by Cormen and others
+class RedBlackTree
+ class Node
+ attr_accessor :color
+ attr_accessor :key
+ attr_accessor :left
+ attr_accessor :right
+ attr_accessor :parent
+
+ RED = :red
+ BLACK = :black
+ COLORS = [RED, BLACK].freeze
+
+ def initialize(key, color = RED)
+ raise ArgumentError, "Bad value for color parameter" unless COLORS.include?(color)
+ @color = color
+ @key = key
+ @left = @right = @parent = NilNode.instance
+ end
+
+ def black?
+ return color == BLACK
+ end
+
+ def red?
+ return color == RED
+ end
+ end
+
+ class NilNode < Node
+ class << self
+ private :new
+
+ # it's not thread safe
+ def instance
+ @instance ||= begin
+ def instance
+ return @instance
+ end
+
+ new
+ end
+ end
+ end
+
+ def initialize
+ self.color = BLACK
+ self.key = 0
+ self.left = nil
+ self.right = nil
+ self.parent = nil
+ end
+
+ def nil?
+ return true
+ end
+ end
+
+ include Enumerable
+
+ attr_accessor :root
+ attr_accessor :size
+
+ def initialize
+ self.root = NilNode.instance
+ self.size = 0
+ end
+
+ def add(key)
+ insert(Node.new(key))
+ end
+
+ def insert(x)
+ insert_helper(x)
+
+ x.color = Node::RED
+ while x != root && x.parent.color == Node::RED
+ if x.parent == x.parent.parent.left
+ y = x.parent.parent.right
+ if !y.nil? && y.color == Node::RED
+ x.parent.color = Node::BLACK
+ y.color = Node::BLACK
+ x.parent.parent.color = Node::RED
+ x = x.parent.parent
+ else
+ if x == x.parent.right
+ x = x.parent
+ left_rotate(x)
+ end
+ x.parent.color = Node::BLACK
+ x.parent.parent.color = Node::RED
+ right_rotate(x.parent.parent)
+ end
+ else
+ y = x.parent.parent.left
+ if !y.nil? && y.color == Node::RED
+ x.parent.color = Node::BLACK
+ y.color = Node::BLACK
+ x.parent.parent.color = Node::RED
+ x = x.parent.parent
+ else
+ if x == x.parent.left
+ x = x.parent
+ right_rotate(x)
+ end
+ x.parent.color = Node::BLACK
+ x.parent.parent.color = Node::RED
+ left_rotate(x.parent.parent)
+ end
+ end
+ end
+ root.color = Node::BLACK
+ end
+
+ alias << insert
+
+ def delete(z)
+ y = (z.left.nil? || z.right.nil?) ? z : successor(z)
+ x = y.left.nil? ? y.right : y.left
+ x.parent = y.parent
+
+ if y.parent.nil?
+ self.root = x
+ else
+ if y == y.parent.left
+ y.parent.left = x
+ else
+ y.parent.right = x
+ end
+ end
+
+ z.key = y.key if y != z
+
+ if y.color == Node::BLACK
+ delete_fixup(x)
+ end
+
+ self.size -= 1
+ return y
+ end
+
+ def minimum(x = root)
+ while !x.left.nil?
+ x = x.left
+ end
+ return x
+ end
+
+ def maximum(x = root)
+ while !x.right.nil?
+ x = x.right
+ end
+ return x
+ end
+
+ def successor(x)
+ if !x.right.nil?
+ return minimum(x.right)
+ end
+ y = x.parent
+ while !y.nil? && x == y.right
+ x = y
+ y = y.parent
+ end
+ return y
+ end
+
+ def predecessor(x)
+ if !x.left.nil?
+ return maximum(x.left)
+ end
+ y = x.parent
+ while !y.nil? && x == y.left
+ x = y
+ y = y.parent
+ end
+ return y
+ end
+
+ def inorder_walk(x = root)
+ x = self.minimum
+ while !x.nil?
+ yield x.key
+ x = successor(x)
+ end
+ end
+
+ alias each inorder_walk
+
+ def reverse_inorder_walk(x = root)
+ x = self.maximum
+ while !x.nil?
+ yield x.key
+ x = predecessor(x)
+ end
+ end
+
+ alias reverse_each reverse_inorder_walk
+
+ def search(key, x = root)
+ while !x.nil? && x.key != key
+ key < x.key ? x = x.left : x = x.right
+ end
+ return x
+ end
+
+ def empty?
+ return self.root.nil?
+ end
+
+ def black_height(x = root)
+ height = 0
+ while !x.nil?
+ x = x.left
+ height +=1 if x.nil? || x.black?
+ end
+ return height
+ end
+
+private
+
+ def left_rotate(x)
+ raise "x.right is nil!" if x.right.nil?
+ y = x.right
+ x.right = y.left
+ y.left.parent = x if !y.left.nil?
+ y.parent = x.parent
+ if x.parent.nil?
+ self.root = y
+ else
+ if x == x.parent.left
+ x.parent.left = y
+ else
+ x.parent.right = y
+ end
+ end
+ y.left = x
+ x.parent = y
+ end
+
+ def right_rotate(x)
+ raise "x.left is nil!" if x.left.nil?
+ y = x.left
+ x.left = y.right
+ y.right.parent = x if !y.right.nil?
+ y.parent = x.parent
+ if x.parent.nil?
+ self.root = y
+ else
+ if x == x.parent.left
+ x.parent.left = y
+ else
+ x.parent.right = y
+ end
+ end
+ y.right = x
+ x.parent = y
+ end
+
+ def insert_helper(z)
+ y = NilNode.instance
+ x = root
+ while !x.nil?
+ y = x
+ z.key < x.key ? x = x.left : x = x.right
+ end
+ z.parent = y
+ if y.nil?
+ self.root = z
+ else
+ z.key < y.key ? y.left = z : y.right = z
+ end
+ self.size += 1
+ end
+
+ def delete_fixup(x)
+ while x != root && x.color == Node::BLACK
+ if x == x.parent.left
+ w = x.parent.right
+ if w.color == Node::RED
+ w.color = Node::BLACK
+ x.parent.color = Node::RED
+ left_rotate(x.parent)
+ w = x.parent.right
+ end
+ if w.left.color == Node::BLACK && w.right.color == Node::BLACK
+ w.color = Node::RED
+ x = x.parent
+ else
+ if w.right.color == Node::BLACK
+ w.left.color = Node::BLACK
+ w.color = Node::RED
+ right_rotate(w)
+ w = x.parent.right
+ end
+ w.color = x.parent.color
+ x.parent.color = Node::BLACK
+ w.right.color = Node::BLACK
+ left_rotate(x.parent)
+ x = root
+ end
+ else
+ w = x.parent.left
+ if w.color == Node::RED
+ w.color = Node::BLACK
+ x.parent.color = Node::RED
+ right_rotate(x.parent)
+ w = x.parent.left
+ end
+ if w.right.color == Node::BLACK && w.left.color == Node::BLACK
+ w.color = Node::RED
+ x = x.parent
+ else
+ if w.left.color == Node::BLACK
+ w.right.color = Node::BLACK
+ w.color = Node::RED
+ left_rotate(w)
+ w = x.parent.left
+ end
+ w.color = x.parent.color
+ x.parent.color = Node::BLACK
+ w.left.color = Node::BLACK
+ right_rotate(x.parent)
+ x = root
+ end
+ end
+ end
+ x.color = Node::BLACK
+ end
+end
+
+def rbt_bm
+ n = 100_000
+ a1 = []; n.times { a1 << rand(999_999) }
+ a2 = []; n.times { a2 << rand(999_999) }
+
+ start = Time.now
+
+ tree = RedBlackTree.new
+
+ n.times {|i| tree.add(i) }
+ n.times { tree.delete(tree.root) }
+
+ tree = RedBlackTree.new
+ a1.each {|e| tree.add(e) }
+ a2.each {|e| tree.search(e) }
+ tree.inorder_walk {|key| key + 1 }
+ tree.reverse_inorder_walk {|key| key + 1 }
+ n.times { tree.minimum }
+ n.times { tree.maximum }
+
+ return Time.now - start
+end
+
+N = (ARGV[0] || 10).to_i
+
+N.times do
+ # puts rbt_bm.to_f
+ rbt_bm.to_f
+ # puts "GC.count = #{GC.count}" if GC.respond_to?(:count)
+end
diff --git a/benchmark/gc/ring.rb b/benchmark/gc/ring.rb
new file mode 100644
index 0000000000..be2c7b7250
--- /dev/null
+++ b/benchmark/gc/ring.rb
@@ -0,0 +1,29 @@
+# create many old objects
+
+max = 30_000_000
+
+class Ring
+ attr_reader :next_ring
+ def initialize n = nil
+ @next_ring = n
+ end
+
+
+ def size
+ s = 1
+ ring = self
+ while ring.next_ring
+ s += 1
+ ring = ring.next_ring
+ end
+ s
+ end
+end
+
+ring = Ring.new
+
+max.times{
+ ring = Ring.new(ring)
+}
+
+# p ring.size
diff --git a/benchmark/make_fasta_output.rb b/benchmark/make_fasta_output.rb
new file mode 100644
index 0000000000..b6d787ae27
--- /dev/null
+++ b/benchmark/make_fasta_output.rb
@@ -0,0 +1,19 @@
+# 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/memory_wrapper.rb b/benchmark/memory_wrapper.rb
new file mode 100644
index 0000000000..3f4451a037
--- /dev/null
+++ b/benchmark/memory_wrapper.rb
@@ -0,0 +1,16 @@
+
+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/other-lang/ack.pl b/benchmark/other-lang/ack.pl
new file mode 100644
index 0000000000..201e22ddfa
--- /dev/null
+++ b/benchmark/other-lang/ack.pl
@@ -0,0 +1,11 @@
+use integer;
+
+sub Ack {
+ return $_[0] ? ($_[1] ? Ack($_[0]-1, Ack($_[0], $_[1]-1))
+ : Ack($_[0]-1, 1))
+ : $_[1]+1;
+}
+
+my $NUM = 9;
+$NUM = 1 if ($NUM < 1);
+my $ack = Ack(3, $NUM);
diff --git a/benchmark/other-lang/ack.py b/benchmark/other-lang/ack.py
new file mode 100644
index 0000000000..9968e7cfcf
--- /dev/null
+++ b/benchmark/other-lang/ack.py
@@ -0,0 +1,16 @@
+import sys
+sys.setrecursionlimit(5000000)
+
+def Ack(M, N):
+ if (not M):
+ return( N + 1 )
+ if (not N):
+ return( Ack(M-1, 1) )
+ return( Ack(M-1, Ack(M, N-1)) )
+
+def main():
+ NUM = 9
+ sys.setrecursionlimit(10000)
+ Ack(3, NUM)
+
+main()
diff --git a/benchmark/other-lang/ack.rb b/benchmark/other-lang/ack.rb
new file mode 100644
index 0000000000..7451bed6c4
--- /dev/null
+++ b/benchmark/other-lang/ack.rb
@@ -0,0 +1,12 @@
+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/other-lang/ack.scm b/benchmark/other-lang/ack.scm
new file mode 100644
index 0000000000..a80b73ba55
--- /dev/null
+++ b/benchmark/other-lang/ack.scm
@@ -0,0 +1,7 @@
+(define (ack m n)
+ (cond ((zero? m) (+ n 1))
+ ((zero? n) (ack (- m 1) 1))
+ (else (ack (- m 1) (ack m (- n 1))))))
+
+(ack 3 9)
+
diff --git a/benchmark/other-lang/eval.rb b/benchmark/other-lang/eval.rb
new file mode 100644
index 0000000000..48a2cea019
--- /dev/null
+++ b/benchmark/other-lang/eval.rb
@@ -0,0 +1,66 @@
+
+Bench = %w(
+ loop
+ ack
+ fib
+ tak
+ fact
+)
+
+Lang = <<EOP.map{|l| l.strip}
+ ruby-cyg
+ ../../../test6/miniruby
+ perl
+ python
+ gosh
+EOP
+
+Bench.replace ['loop2']
+Lang.replace ['ruby-cyg']
+
+Ext = %w(
+ .rb
+ .rb
+ .pl
+ .py
+ .scm
+)
+
+p Bench
+p Lang
+
+require 'benchmark'
+
+def bench cmd
+ m = Benchmark.measure{
+ #p cmd
+ system(cmd)
+ }
+ [m.utime, m.real]
+end
+
+Result = []
+Bench.each{|b|
+ r = []
+ Lang.each_with_index{|l, idx|
+ cmd = "#{l} #{b}#{Ext[idx]}"
+ r << bench(cmd)
+ }
+ Result << r
+}
+
+require 'pp'
+# utime
+puts Lang.join("\t")
+Bench.each_with_index{|b, bi|
+ print b, "\t"
+ puts Result[bi].map{|e| e[0]}.join("\t")
+}
+
+# rtime
+puts Lang.join("\t")
+Bench.each_with_index{|b, bi|
+ print b, "\t"
+ puts Result[bi].map{|e| e[1]}.join("\t")
+}
+
diff --git a/benchmark/other-lang/fact.pl b/benchmark/other-lang/fact.pl
new file mode 100644
index 0000000000..a9b0b69cdf
--- /dev/null
+++ b/benchmark/other-lang/fact.pl
@@ -0,0 +1,13 @@
+sub fact{
+ my $n = @_[0];
+ if($n < 2){
+ return 1;
+ }
+ else{
+ return $n * fact($n-1);
+ }
+}
+
+for($i=0; $i<10000; $i++){
+ &fact(100);
+}
diff --git a/benchmark/other-lang/fact.py b/benchmark/other-lang/fact.py
new file mode 100644
index 0000000000..01593965d9
--- /dev/null
+++ b/benchmark/other-lang/fact.py
@@ -0,0 +1,18 @@
+#import sys
+#sys.setrecursionlimit(1000)
+
+def factL(n):
+ r = 1
+ for x in range(2, n):
+ r *= x
+ return r
+
+def factR(n):
+ if n < 2:
+ return 1
+ else:
+ return n * factR(n-1)
+
+for i in range(10000):
+ factR(100)
+
diff --git a/benchmark/other-lang/fact.rb b/benchmark/other-lang/fact.rb
new file mode 100644
index 0000000000..6cedc752cd
--- /dev/null
+++ b/benchmark/other-lang/fact.rb
@@ -0,0 +1,13 @@
+def fact(n)
+ if n < 2
+ 1
+ else
+ n * fact(n-1)
+ end
+end
+
+i = 0
+while i<10000
+ i += 1
+ fact(100)
+end
diff --git a/benchmark/other-lang/fact.scm b/benchmark/other-lang/fact.scm
new file mode 100644
index 0000000000..c98a7fedd3
--- /dev/null
+++ b/benchmark/other-lang/fact.scm
@@ -0,0 +1,8 @@
+(define (fact n)
+ (if (< n 2)
+ 1
+ (* n (fact (- n 1)))))
+
+(dotimes (i 10000)
+ (fact 100))
+
diff --git a/benchmark/other-lang/fib.pl b/benchmark/other-lang/fib.pl
new file mode 100644
index 0000000000..a46f666d1e
--- /dev/null
+++ b/benchmark/other-lang/fib.pl
@@ -0,0 +1,11 @@
+sub fib{
+ my $n = $_[0];
+ if($n < 3){
+ return 1;
+ }
+ else{
+ return fib($n-1) + fib($n-2);
+ }
+};
+
+&fib(34);
diff --git a/benchmark/other-lang/fib.py b/benchmark/other-lang/fib.py
new file mode 100644
index 0000000000..45f2bceb8d
--- /dev/null
+++ b/benchmark/other-lang/fib.py
@@ -0,0 +1,7 @@
+def fib(n):
+ if n < 3:
+ return 1
+ else:
+ return fib(n-1) + fib(n-2)
+
+fib(34)
diff --git a/benchmark/other-lang/fib.rb b/benchmark/other-lang/fib.rb
new file mode 100644
index 0000000000..ec587eabe0
--- /dev/null
+++ b/benchmark/other-lang/fib.rb
@@ -0,0 +1,9 @@
+def fib n
+ if n < 3
+ 1
+ else
+ fib(n-1) + fib(n-2)
+ end
+end
+
+fib(34)
diff --git a/benchmark/other-lang/fib.scm b/benchmark/other-lang/fib.scm
new file mode 100644
index 0000000000..2fc4e225bd
--- /dev/null
+++ b/benchmark/other-lang/fib.scm
@@ -0,0 +1,7 @@
+(define (fib n)
+ (if (< n 3)
+ 1
+ (+ (fib (- n 1)) (fib (- n 2)))))
+
+(fib 34)
+
diff --git a/benchmark/other-lang/loop.pl b/benchmark/other-lang/loop.pl
new file mode 100644
index 0000000000..2777490aaa
--- /dev/null
+++ b/benchmark/other-lang/loop.pl
@@ -0,0 +1,3 @@
+for($i=0; $i<30000000; $i++){
+}
+
diff --git a/benchmark/other-lang/loop.py b/benchmark/other-lang/loop.py
new file mode 100644
index 0000000000..003749bf3a
--- /dev/null
+++ b/benchmark/other-lang/loop.py
@@ -0,0 +1,2 @@
+for i in xrange(30000000):
+ pass
diff --git a/benchmark/other-lang/loop.rb b/benchmark/other-lang/loop.rb
new file mode 100644
index 0000000000..b367b9dbf3
--- /dev/null
+++ b/benchmark/other-lang/loop.rb
@@ -0,0 +1,4 @@
+i = 0
+while i<30000000
+ i += 1
+end
diff --git a/benchmark/other-lang/loop.scm b/benchmark/other-lang/loop.scm
new file mode 100644
index 0000000000..3364f7e679
--- /dev/null
+++ b/benchmark/other-lang/loop.scm
@@ -0,0 +1 @@
+(dotimes (x 30000000))
diff --git a/benchmark/other-lang/loop2.rb b/benchmark/other-lang/loop2.rb
new file mode 100644
index 0000000000..df8fffc1ff
--- /dev/null
+++ b/benchmark/other-lang/loop2.rb
@@ -0,0 +1 @@
+30000000.times{}
diff --git a/benchmark/other-lang/tak.pl b/benchmark/other-lang/tak.pl
new file mode 100644
index 0000000000..7e748a67c6
--- /dev/null
+++ b/benchmark/other-lang/tak.pl
@@ -0,0 +1,11 @@
+sub tak {
+ local($x, $y, $z) = @_;
+ if (!($y < $x)) {
+ return $z;
+ } else {
+ return &tak(&tak($x - 1, $y, $z),
+ &tak($y - 1, $z, $x),
+ &tak($z - 1, $x, $y));
+ }
+}
+&tak(18, 9, 0);
diff --git a/benchmark/other-lang/tak.py b/benchmark/other-lang/tak.py
new file mode 100644
index 0000000000..04f3f6829c
--- /dev/null
+++ b/benchmark/other-lang/tak.py
@@ -0,0 +1,8 @@
+def tak(x, y, z):
+ if not(y<x):
+ return z
+ else:
+ return tak(tak(x-1, y, z),
+ tak(y-1, z, x),
+ tak(z-1, x, y))
+tak(18, 9, 0)
diff --git a/benchmark/other-lang/tak.rb b/benchmark/other-lang/tak.rb
new file mode 100644
index 0000000000..efe5380f4e
--- /dev/null
+++ b/benchmark/other-lang/tak.rb
@@ -0,0 +1,13 @@
+
+def tak x, y, z
+ unless y < x
+ z
+ else
+ tak( tak(x-1, y, z),
+ tak(y-1, z, x),
+ tak(z-1, x, y))
+ end
+end
+
+tak(18, 9, 0)
+
diff --git a/benchmark/other-lang/tak.scm b/benchmark/other-lang/tak.scm
new file mode 100644
index 0000000000..52a7629ee5
--- /dev/null
+++ b/benchmark/other-lang/tak.scm
@@ -0,0 +1,10 @@
+(define (tak x y z)
+ (if (not (< y x))
+ z
+ (tak (tak (- x 1) y z)
+ (tak (- y 1) z x)
+ (tak (- z 1) x y))))
+
+(tak 18 9 0)
+
+
diff --git a/benchmark/prepare_require.rb b/benchmark/prepare_require.rb
new file mode 100644
index 0000000000..c4786f04ad
--- /dev/null
+++ b/benchmark/prepare_require.rb
@@ -0,0 +1,25 @@
+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
new file mode 100644
index 0000000000..339ecb8b39
--- /dev/null
+++ b/benchmark/prepare_require_thread.rb
@@ -0,0 +1,2 @@
+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
new file mode 100644
index 0000000000..ee2138cdb2
--- /dev/null
+++ b/benchmark/prepare_so_count_words.rb
@@ -0,0 +1,15 @@
+# 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
new file mode 100644
index 0000000000..d83aeb7a7e
--- /dev/null
+++ b/benchmark/prepare_so_k_nucleotide.rb
@@ -0,0 +1,2 @@
+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
new file mode 100644
index 0000000000..da3ec2df14
--- /dev/null
+++ b/benchmark/prepare_so_reverse_complement.rb
@@ -0,0 +1,2 @@
+require_relative 'make_fasta_output'
+prepare_fasta_output(2_500_000)
diff --git a/benchmark/report.rb b/benchmark/report.rb
new file mode 100644
index 0000000000..d2dc56b1e1
--- /dev/null
+++ b/benchmark/report.rb
@@ -0,0 +1,79 @@
+#
+# 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/run.rb b/benchmark/run.rb
new file mode 100644
index 0000000000..0cd2363849
--- /dev/null
+++ b/benchmark/run.rb
@@ -0,0 +1,127 @@
+#
+# 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
new file mode 100644
index 0000000000..97c5cef045
--- /dev/null
+++ b/benchmark/runc.rb
@@ -0,0 +1,27 @@
+#
+#
+#
+
+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/wc.input.base b/benchmark/wc.input.base
new file mode 100644
index 0000000000..41143fbac0
--- /dev/null
+++ b/benchmark/wc.input.base
@@ -0,0 +1,25 @@
+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/beos/ruby.def.in b/beos/ruby.def.in
deleted file mode 100644
index 04de159208..0000000000
--- a/beos/ruby.def.in
+++ /dev/null
@@ -1,353 +0,0 @@
-ArgError
-Bug
-Error
-Error_Append
-Fail
-Fatal
-IndexError
-LoadError
-NameError
-Raise
-TypeError
-Warning
-any_to_s
-ary_assoc
-ary_concat
-ary_delete
-ary_delete_at
-ary_each
-ary_entry
-ary_freeze
-ary_includes
-ary_join
-ary_new
-ary_new2
-ary_new3
-ary_new4
-ary_plus
-ary_pop
-ary_push
-ary_rassoc
-ary_reverse
-ary_shift
-ary_sort
-ary_sort_bang
-ary_store
-ary_to_s
-ary_unshift
-assoc_new
-backref_get
-backref_set
-big2dbl
-big2str
-big_2comp
-big_and
-big_clone
-big_lshift
-big_minus
-big_mul
-big_norm
-big_or
-big_plus
-big_pow
-big_rand
-big_to_f
-big_to_i
-big_xor
-cArray
-cBignum
-cClass
-cData
-cFile
-cFixnum
-cFixnum
-cFloat
-cHash
-cIO
-cInteger
-cModule
-cNumeric
-cObject
-cProc
-cRegexp
-cString
-cStruct
-class_new
-class_new_instance
-data_object_alloc
-dbl2big
-dln_find_exe
-dln_find_file
-dln_load
-dyna_var_asgn
-dyna_var_defined
-dyna_var_ref
-eaccess
-enum_length
-eof_error
-exc_new
-exc_new2
-exc_new3
-f_autoload
-f_gets
-f_lambda
-f_load
-f_require
-file_open
-file_s_expand_path
-fix2str
-fix_to_s
-fix_upto
-flo_pow
-float_new
-gc_force_recycle
-gc_gc
-gc_mark
-gc_mark_frame
-gc_mark_global_tbl
-gc_mark_locations
-gc_mark_maybe
-gc_mark_threads
-gc_mark_trap_list
-gc_s_disable
-gc_s_enable
-hash_aref
-hash_aset
-hash_new
-id_attrset
-int2big
-int2inum
-io_binmode
-io_check_closed
-io_close
-io_fptr_finalize
-io_getc
-io_gets
-io_gets_method
-io_mode_flags
-io_readable
-io_reopen
-io_unbuffered
-io_ungetc
-io_writable
-io_write
-iterator_p
-lastline_get
-lastline_set
-local_var_append
-memclear
-mod_constants
-module_new
-new_idhash
-nodeline
-nodetype
-num2fix
-num2int
-num2long
-num_coerce_bin
-num_upto
-num_zerodiv
-obj_alloc
-obj_as_string
-obj_call_init
-obj_equal
-obj_is_instance_of
-obj_is_kind_of
-range_beg_end
-range_new
-rb_Array
-rb_Float
-rb_Integer
-rb_String
-rb_add_method
-rb_alias
-rb_alias_variable
-rb_apply
-rb_autoload
-rb_autoload_defined
-rb_backtrace
-rb_call_inits
-rb_check_safe_str
-rb_check_type
-rb_class2name
-rb_class_of
-rb_class_path
-rb_clear_cache
-rb_const_defined
-rb_const_defined_at
-rb_const_get
-rb_const_get_at
-rb_const_set
-rb_define_alias
-rb_define_attr
-rb_define_class
-rb_define_class_id
-rb_define_class_under
-rb_define_const
-rb_define_global_const
-rb_define_global_function
-rb_define_hooked_variable
-rb_define_method
-rb_define_method_id
-rb_define_module
-rb_define_module_function
-rb_define_module_id
-rb_define_module_under
-rb_define_private_method
-rb_define_readonly_variable
-rb_define_singleton_method
-rb_define_variable
-rb_define_virtual_variable
-rb_each
-rb_ensure
-rb_eql
-rb_equal
-rb_eval_cmd
-rb_eval_string
-rb_exit
-rb_extend_object
-rb_fatal
-rb_fdopen
-rb_fopen
-rb_frame_last_func
-rb_funcall
-rb_funcall2
-rb_get_kcode
-rb_global_entry
-rb_global_variable
-rb_gvar_defined
-rb_gvar_get
-rb_gvar_set
-rb_gvar_set2
-rb_hash
-rb_id2name
-rb_include_module
-rb_inspect
-rb_intern
-rb_interrupt
-rb_is_const_id
-rb_is_instance_id
-rb_iterate
-rb_iv_get
-rb_iv_set
-rb_ivar_defined
-rb_ivar_get
-rb_ivar_set
-rb_load_file
-rb_method_boundp
-rb_name_class
-rb_newobj
-rb_notimplement
-rb_path2class
-rb_proc_exec
-rb_provide
-rb_raise
-rb_rescue
-rb_respond_to
-rb_safe_level
-rb_scan_args
-rb_secure
-rb_set_class_path
-rb_set_kcode
-rb_set_safe_level
-rb_singleton_class
-rb_special_const_p
-rb_str_setter
-rb_sys_fail
-rb_syswait
-rb_test_false_or_nil
-rb_to_id
-rb_trap_eval
-rb_trap_exec
-rb_trap_exit
-rb_type
-rb_undef_method
-rb_yield
-rb_yield_0
-reg_free
-reg_last_match
-reg_match
-reg_match2
-reg_match_last
-reg_match_post
-reg_match_pre
-reg_new
-reg_nth_defined
-reg_nth_match
-reg_regcomp
-reg_regsub
-reg_search
-ruby_init
-ruby_options
-ruby_process_options
-ruby_prog_init
-ruby_run
-ruby_script
-ruby_set_argv
-scan_hex
-scan_oct
-show_copyright
-show_version
-singleton_class_clone
-singleton_class_new
-st_add_direct
-st_copy
-st_delete
-st_delete_safe
-st_find_or_add
-st_foreach
-st_free_table
-st_init_numtable
-st_init_strtable
-st_init_table
-st_init_table_with_size
-st_insert
-st_lookup
-str2inum
-str2cstr
-str_cat
-str_cicmp
-str_cmp
-str_dup
-str_freeze
-str_hash
-str_inspect
-str_modify
-str_new
-str_new2
-str_new3
-str_new4
-str_plus
-str_resize
-str_split
-str_substr
-str_taint
-str_tainted
-str_times
-str_upto
-struct_alloc
-struct_aref
-struct_aset
-struct_define
-struct_getmember
-struct_new
-thread_alone
-thread_create
-thread_fd_writable
-thread_interrupt
-thread_schedule
-thread_select
-thread_sleep
-thread_sleep_forever
-thread_wait_fd
-thread_wait_for
-time_new
-time_timeval
-uint2big
-uint2inum
-xcalloc
-xmalloc
-xrealloc
-eException
-eStandardError
-trap_immediate
diff --git a/bignum.c b/bignum.c
index c1f0692d6d..7ffb798e5e 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1,401 +1,5200 @@
-/************************************************
+/**********************************************************************
bignum.c -
$Author$
- $Date$
created at: Fri Jun 10 00:48:55 JST 1994
-************************************************/
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
-#include "ruby.h"
+**********************************************************************/
+
+#include "internal.h"
+#include "ruby/thread.h"
+#include "ruby/util.h"
+#include "id.h"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
#include <math.h>
+#include <float.h>
#include <ctype.h>
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+#include "ruby_assert.h"
-VALUE cBignum;
-typedef unsigned short USHORT;
+#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
+#define USE_GMP
+#include <gmp.h>
+#endif
-#define BDIGITS(x) RBIGNUM(x)->digits
-#define BITSPERDIG (sizeof(short)*CHAR_BIT)
-#define BIGRAD (1L << BITSPERDIG)
-#define DIGSPERINT ((unsigned int)(sizeof(long)/sizeof(short)))
-#define BIGUP(x) ((unsigned long)(x) << BITSPERDIG)
-#define BIGDN(x) (((x)<0) ? ~((~(x))>>BITSPERDIG) : (x)>>BITSPERDIG)
-#define BIGLO(x) ((x) & (BIGRAD-1))
+#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
-static VALUE
-bignew_1(klass, len, sign)
- VALUE klass;
- unsigned int len;
- char sign;
+#ifndef RUBY_INTEGER_UNIFICATION
+VALUE rb_cBignum;
+#endif
+const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+#ifndef SIZEOF_BDIGIT_DBL
+# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
+# define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
+# else
+# define SIZEOF_BDIGIT_DBL SIZEOF_LONG
+# endif
+#endif
+
+STATIC_ASSERT(sizeof_bdigit_dbl, sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
+STATIC_ASSERT(sizeof_bdigit_dbl_signed, sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
+STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <= sizeof(BDIGIT));
+STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
+STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
+STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
+STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
+STATIC_ASSERT(rbignum_embed_len_max, BIGNUM_EMBED_LEN_MAX <= (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT));
+
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
+#else
+STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define HOST_BIGENDIAN_P 1
+#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))))
+#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
+#define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
+#define POW2_P(x) (((x)&((x)-1))==0)
+
+#define BDIGITS(x) (BIGNUM_DIGITS(x))
+#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
+#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
+#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
+#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
+#define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
+#define BIGDN(x) RSHIFT((x),BITSPERDIG)
+#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
+#define BDIGMAX ((BDIGIT)(BIGRAD-1))
+#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
+
+#if SIZEOF_BDIGIT == 2
+# define swap_bdigit(x) swap16(x)
+#elif SIZEOF_BDIGIT == 4
+# define swap_bdigit(x) swap32(x)
+#elif SIZEOF_BDIGIT == 8
+# define swap_bdigit(x) swap64(x)
+#endif
+
+#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
+ (BDIGITS(x)[0] == 0 && \
+ (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
+#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
+ BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
+ (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
+ rb_absint_size(x, NULL))
+
+#define BIGDIVREM_EXTRA_WORDS 1
+#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
+#define BARY_ARGS(ary) ary, numberof(ary)
+
+#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
+#define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
+#define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
+#define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
+#define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
+
+#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
+#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
+
+#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
+
+#define BDIGITS_ZERO(ptr, n) do { \
+ BDIGIT *bdigitz_zero_ptr = (ptr); \
+ size_t bdigitz_zero_n = (n); \
+ while (bdigitz_zero_n) { \
+ *bdigitz_zero_ptr++ = 0; \
+ bdigitz_zero_n--; \
+ } \
+} while (0)
+
+#define BARY_TRUNC(ds, n) do { \
+ while (0 < (n) && (ds)[(n)-1] == 0) \
+ (n)--; \
+ } while (0)
+
+#define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
+#define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
+
+#define GMP_MUL_DIGITS 20
+#define KARATSUBA_MUL_DIGITS 70
+#define TOOM3_MUL_DIGITS 150
+
+#define GMP_DIV_DIGITS 20
+#define GMP_BIG2STR_DIGITS 20
+#define GMP_STR2BIG_DIGITS 20
+#ifdef USE_GMP
+# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
+#else
+# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
+#endif
+
+typedef void (mulfunc_t)(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn);
+
+static mulfunc_t bary_mul_toom3_start;
+static mulfunc_t bary_mul_karatsuba_start;
+static BDIGIT bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y);
+static void bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn);
+
+static VALUE bigmul0(VALUE x, VALUE y);
+static void bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn);
+static VALUE bignew_1(VALUE klass, size_t len, int sign);
+static inline VALUE bigtrunc(VALUE x);
+
+static VALUE bigsq(VALUE x);
+static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
+static inline VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret);
+
+#if SIZEOF_BDIGIT <= SIZEOF_INT
+static int nlz(BDIGIT x) { return nlz_int((unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
+#elif SIZEOF_BDIGIT <= SIZEOF_LONG
+static int nlz(BDIGIT x) { return nlz_long((unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
+#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
+static int nlz(BDIGIT x) { return nlz_long_long((unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
+#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
+static int nlz(BDIGIT x) { return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
+#endif
+
+#define U16(a) ((uint16_t)(a))
+#define U32(a) ((uint32_t)(a))
+#ifdef HAVE_UINT64_T
+#define U64(a,b) (((uint64_t)(a) << 32) | (b))
+#endif
+#ifdef HAVE_UINT128_T
+#define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
+#endif
+
+/* The following script, maxpow.rb, generates the tables follows.
+
+def big(n, bits)
+ ns = []
+ ((bits+31)/32).times {
+ ns << sprintf("0x%08x", n & 0xffff_ffff)
+ n >>= 32
+ }
+ "U#{bits}(" + ns.reverse.join(",") + ")"
+end
+def values(ary, width, indent)
+ lines = [""]
+ ary.each {|e|
+ lines << "" if !ary.last.empty? && width < (lines.last + e + ", ").length
+ lines.last << e + ", "
+ }
+ lines.map {|line| " " * indent + line.chomp(" ") + "\n" }.join
+end
+[16,32,64,128].each {|bits|
+ max = 2**bits-1
+ exps = []
+ nums = []
+ 2.upto(36) {|base|
+ exp = 0
+ n = 1
+ while n * base <= max
+ exp += 1
+ n *= base
+ end
+ exps << exp.to_s
+ nums << big(n, bits)
+ }
+ puts "#ifdef HAVE_UINT#{bits}_T"
+ puts "static const int maxpow#{bits}_exp[35] = {"
+ print values(exps, 70, 4)
+ puts "};"
+ puts "static const uint#{bits}_t maxpow#{bits}_num[35] = {"
+ print values(nums, 70, 4)
+ puts "};"
+ puts "#endif"
+}
+
+ */
+
+#if SIZEOF_BDIGIT_DBL == 2
+static const int maxpow16_exp[35] = {
+ 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+};
+static const uint16_t maxpow16_num[35] = {
+ U16(0x00008000), U16(0x0000e6a9), U16(0x00004000), U16(0x00003d09),
+ U16(0x0000b640), U16(0x000041a7), U16(0x00008000), U16(0x0000e6a9),
+ U16(0x00002710), U16(0x00003931), U16(0x00005100), U16(0x00006f91),
+ U16(0x00009610), U16(0x0000c5c1), U16(0x00001000), U16(0x00001331),
+ U16(0x000016c8), U16(0x00001acb), U16(0x00001f40), U16(0x0000242d),
+ U16(0x00002998), U16(0x00002f87), U16(0x00003600), U16(0x00003d09),
+ U16(0x000044a8), U16(0x00004ce3), U16(0x000055c0), U16(0x00005f45),
+ U16(0x00006978), U16(0x0000745f), U16(0x00008000), U16(0x00008c61),
+ U16(0x00009988), U16(0x0000a77b), U16(0x0000b640),
+};
+#elif SIZEOF_BDIGIT_DBL == 4
+static const int maxpow32_exp[35] = {
+ 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
+ 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+};
+static const uint32_t maxpow32_num[35] = {
+ U32(0x80000000), U32(0xcfd41b91), U32(0x40000000), U32(0x48c27395),
+ U32(0x81bf1000), U32(0x75db9c97), U32(0x40000000), U32(0xcfd41b91),
+ U32(0x3b9aca00), U32(0x8c8b6d2b), U32(0x19a10000), U32(0x309f1021),
+ U32(0x57f6c100), U32(0x98c29b81), U32(0x10000000), U32(0x18754571),
+ U32(0x247dbc80), U32(0x3547667b), U32(0x4c4b4000), U32(0x6b5a6e1d),
+ U32(0x94ace180), U32(0xcaf18367), U32(0x0b640000), U32(0x0e8d4a51),
+ U32(0x1269ae40), U32(0x17179149), U32(0x1cb91000), U32(0x23744899),
+ U32(0x2b73a840), U32(0x34e63b41), U32(0x40000000), U32(0x4cfa3cc1),
+ U32(0x5c13d840), U32(0x6d91b519), U32(0x81bf1000),
+};
+#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
+static const int maxpow64_exp[35] = {
+ 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
+ 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
+ 12,
+};
+static const uint64_t maxpow64_num[35] = {
+ U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
+ U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
+ U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
+ U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
+ U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
+ U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
+ U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
+ U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
+ U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
+ U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
+ U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
+ U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
+ U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
+ U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
+ U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
+ U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
+ U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
+ U64(0x41c21cb8,0xe1000000),
+};
+#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
+static const int maxpow128_exp[35] = {
+ 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
+ 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
+ 24,
+};
+static const uint128_t maxpow128_num[35] = {
+ U128(0x80000000,0x00000000,0x00000000,0x00000000),
+ U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
+ U128(0x40000000,0x00000000,0x00000000,0x00000000),
+ U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
+ U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
+ U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
+ U128(0x40000000,0x00000000,0x00000000,0x00000000),
+ U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
+ U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
+ U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
+ U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
+ U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
+ U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
+ U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
+ U128(0x10000000,0x00000000,0x00000000,0x00000000),
+ U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
+ U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
+ U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
+ U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
+ U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
+ U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
+ U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
+ U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
+ U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
+ U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
+ U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
+ U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
+ U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
+ U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
+ U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
+ U128(0x20000000,0x00000000,0x00000000,0x00000000),
+ U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
+ U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
+ U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
+ U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
+};
+#endif
+
+static BDIGIT_DBL
+maxpow_in_bdigit_dbl(int base, int *exp_ret)
{
- NEWOBJ(big, struct RBignum);
- OBJSETUP(big, klass, T_BIGNUM);
- big->sign = sign;
- big->len = len;
- BDIGITS(big) = ALLOC_N(USHORT, len);
+ BDIGIT_DBL maxpow;
+ int exponent;
+
+ assert(2 <= base && base <= 36);
+
+ {
+#if SIZEOF_BDIGIT_DBL == 2
+ maxpow = maxpow16_num[base-2];
+ exponent = maxpow16_exp[base-2];
+#elif SIZEOF_BDIGIT_DBL == 4
+ maxpow = maxpow32_num[base-2];
+ exponent = maxpow32_exp[base-2];
+#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
+ maxpow = maxpow64_num[base-2];
+ exponent = maxpow64_exp[base-2];
+#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
+ maxpow = maxpow128_num[base-2];
+ exponent = maxpow128_exp[base-2];
+#else
+ maxpow = base;
+ exponent = 1;
+ while (maxpow <= BDIGIT_DBL_MAX / base) {
+ maxpow *= base;
+ exponent++;
+ }
+#endif
+ }
- return (VALUE)big;
+ *exp_ret = exponent;
+ return maxpow;
+}
+
+static inline BDIGIT_DBL
+bary2bdigitdbl(const BDIGIT *ds, size_t n)
+{
+ assert(n <= 2);
+
+ if (n == 2)
+ return ds[0] | BIGUP(ds[1]);
+ if (n == 1)
+ return ds[0];
+ return 0;
+}
+
+static inline void
+bdigitdbl2bary(BDIGIT *ds, size_t n, BDIGIT_DBL num)
+{
+ assert(n == 2);
+
+ ds[0] = BIGLO(num);
+ ds[1] = (BDIGIT)BIGDN(num);
+}
+
+static int
+bary_cmp(const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ BARY_TRUNC(xds, xn);
+ BARY_TRUNC(yds, yn);
+
+ if (xn < yn)
+ return -1;
+ if (xn > yn)
+ return 1;
+
+ while (xn-- && xds[xn] == yds[xn])
+ ;
+ if (xn == (size_t)-1)
+ return 0;
+ return xds[xn] < yds[xn] ? -1 : 1;
+}
+
+static BDIGIT
+bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift)
+{
+ size_t i;
+ BDIGIT_DBL num = 0;
+ assert(0 <= shift && shift < BITSPERDIG);
+
+ for (i=0; i<n; i++) {
+ num = num | (BDIGIT_DBL)*xds++ << shift;
+ *zds++ = BIGLO(num);
+ num = BIGDN(num);
+ }
+ return BIGLO(num);
+}
+
+static void
+bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT higher_bdigit)
+{
+ BDIGIT_DBL num = 0;
+
+ assert(0 <= shift && shift < BITSPERDIG);
+
+ num = BIGUP(higher_bdigit);
+ while (n--) {
+ BDIGIT x = xds[n];
+ num = (num | x) >> shift;
+ zds[n] = BIGLO(num);
+ num = BIGUP(x);
+ }
+}
+
+static int
+bary_zero_p(const BDIGIT *xds, size_t xn)
+{
+ if (xn == 0)
+ return 1;
+ do {
+ if (xds[--xn]) return 0;
+ } while (xn);
+ return 1;
+}
+
+static void
+bary_neg(BDIGIT *ds, size_t n)
+{
+ while (n--)
+ ds[n] = BIGLO(~ds[n]);
+}
+
+static int
+bary_2comp(BDIGIT *ds, size_t n)
+{
+ size_t i;
+ i = 0;
+ for (i = 0; i < n; i++) {
+ if (ds[i] != 0) {
+ goto non_zero;
+ }
+ }
+ return 1;
+
+ non_zero:
+ ds[i] = BIGLO(~ds[i] + 1);
+ i++;
+ for (; i < n; i++) {
+ ds[i] = BIGLO(~ds[i]);
+ }
+ return 0;
+}
+
+static void
+bary_swap(BDIGIT *ds, size_t num_bdigits)
+{
+ BDIGIT *p1 = ds;
+ BDIGIT *p2 = ds + num_bdigits - 1;
+ for (; p1 < p2; p1++, p2--) {
+ BDIGIT tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ }
+}
+
+#define INTEGER_PACK_WORDORDER_MASK \
+ (INTEGER_PACK_MSWORD_FIRST | \
+ INTEGER_PACK_LSWORD_FIRST)
+#define INTEGER_PACK_BYTEORDER_MASK \
+ (INTEGER_PACK_MSBYTE_FIRST | \
+ INTEGER_PACK_LSBYTE_FIRST | \
+ INTEGER_PACK_NATIVE_BYTE_ORDER)
+
+static void
+validate_integer_pack_format(size_t numwords, size_t wordsize, size_t nails, int flags, int supported_flags)
+{
+ int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
+ int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
+
+ if (flags & ~supported_flags) {
+ rb_raise(rb_eArgError, "unsupported flags specified");
+ }
+ if (wordorder_bits == 0) {
+ if (1 < numwords)
+ rb_raise(rb_eArgError, "word order not specified");
+ }
+ else if (wordorder_bits != INTEGER_PACK_MSWORD_FIRST &&
+ wordorder_bits != INTEGER_PACK_LSWORD_FIRST)
+ rb_raise(rb_eArgError, "unexpected word order");
+ if (byteorder_bits == 0) {
+ rb_raise(rb_eArgError, "byte order not specified");
+ }
+ else if (byteorder_bits != INTEGER_PACK_MSBYTE_FIRST &&
+ byteorder_bits != INTEGER_PACK_LSBYTE_FIRST &&
+ byteorder_bits != INTEGER_PACK_NATIVE_BYTE_ORDER)
+ rb_raise(rb_eArgError, "unexpected byte order");
+ if (wordsize == 0)
+ rb_raise(rb_eArgError, "invalid wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
+ if (SSIZE_MAX < wordsize)
+ rb_raise(rb_eArgError, "too big wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
+ if (wordsize <= nails / CHAR_BIT)
+ rb_raise(rb_eArgError, "too big nails: %"PRI_SIZE_PREFIX"u", nails);
+ if (SIZE_MAX / wordsize < numwords)
+ rb_raise(rb_eArgError, "too big numwords * wordsize: %"PRI_SIZE_PREFIX"u * %"PRI_SIZE_PREFIX"u", numwords, wordsize);
+}
+
+static void
+integer_pack_loop_setup(
+ size_t numwords, size_t wordsize, size_t nails, int flags,
+ size_t *word_num_fullbytes_ret,
+ int *word_num_partialbits_ret,
+ size_t *word_start_ret,
+ ssize_t *word_step_ret,
+ size_t *word_last_ret,
+ size_t *byte_start_ret,
+ int *byte_step_ret)
+{
+ int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
+ int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
+ size_t word_num_fullbytes;
+ int word_num_partialbits;
+ size_t word_start;
+ ssize_t word_step;
+ size_t word_last;
+ size_t byte_start;
+ int byte_step;
+
+ word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
+ if (word_num_partialbits == CHAR_BIT)
+ word_num_partialbits = 0;
+ word_num_fullbytes = wordsize - (nails / CHAR_BIT);
+ if (word_num_partialbits != 0) {
+ word_num_fullbytes--;
+ }
+
+ if (wordorder_bits == INTEGER_PACK_MSWORD_FIRST) {
+ word_start = wordsize*(numwords-1);
+ word_step = -(ssize_t)wordsize;
+ word_last = 0;
+ }
+ else {
+ word_start = 0;
+ word_step = wordsize;
+ word_last = wordsize*(numwords-1);
+ }
+
+ if (byteorder_bits == INTEGER_PACK_NATIVE_BYTE_ORDER) {
+#ifdef WORDS_BIGENDIAN
+ byteorder_bits = INTEGER_PACK_MSBYTE_FIRST;
+#else
+ byteorder_bits = INTEGER_PACK_LSBYTE_FIRST;
+#endif
+ }
+ if (byteorder_bits == INTEGER_PACK_MSBYTE_FIRST) {
+ byte_start = wordsize-1;
+ byte_step = -1;
+ }
+ else {
+ byte_start = 0;
+ byte_step = 1;
+ }
+
+ *word_num_partialbits_ret = word_num_partialbits;
+ *word_num_fullbytes_ret = word_num_fullbytes;
+ *word_start_ret = word_start;
+ *word_step_ret = word_step;
+ *word_last_ret = word_last;
+ *byte_start_ret = byte_start;
+ *byte_step_ret = byte_step;
+}
+
+static inline void
+integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
+{
+ if (*dpp < *dep && BITSPERDIG <= (int)sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
+ *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
+ *numbits_in_dd_p += BITSPERDIG;
+ }
+ else if (*dpp == *dep) {
+ /* higher bits are infinity zeros */
+ *numbits_in_dd_p = (int)sizeof(*ddp) * CHAR_BIT;
+ }
+}
+
+static inline BDIGIT_DBL
+integer_pack_take_lowbits(int n, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
+{
+ BDIGIT_DBL ret;
+ ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
+ *ddp >>= n;
+ *numbits_in_dd_p -= n;
+ return ret;
+}
+
+#if !defined(WORDS_BIGENDIAN)
+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++) {
+ buf[i]++;
+ if (buf[i] != 0)
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+static int
+bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
+{
+ BDIGIT *dp, *de;
+ unsigned char *buf, *bufend;
+
+ dp = ds;
+ de = ds + num_bdigits;
+
+ validate_integer_pack_format(numwords, wordsize, nails, flags,
+ INTEGER_PACK_MSWORD_FIRST|
+ INTEGER_PACK_LSWORD_FIRST|
+ INTEGER_PACK_MSBYTE_FIRST|
+ INTEGER_PACK_LSBYTE_FIRST|
+ INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP|
+ INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION);
+
+ while (dp < de && de[-1] == 0)
+ de--;
+ if (dp == de) {
+ sign = 0;
+ }
+
+ if (!(flags & INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION)) {
+ if (sign == 0) {
+ MEMZERO(words, unsigned char, numwords * wordsize);
+ return 0;
+ }
+ if (nails == 0 && numwords == 1) {
+ int need_swap = wordsize != 1 &&
+ (flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_NATIVE_BYTE_ORDER &&
+ ((flags & INTEGER_PACK_MSBYTE_FIRST) ? !HOST_BIGENDIAN_P : HOST_BIGENDIAN_P);
+ if (0 < sign || !(flags & INTEGER_PACK_2COMP)) {
+ BDIGIT d;
+ if (wordsize == 1) {
+ *((unsigned char *)words) = (unsigned char)(d = dp[0]);
+ 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) {
+ uint16_t u = (uint16_t)(d = dp[0]);
+ if (need_swap) u = swap16(u);
+ *((uint16_t *)words) = u;
+ return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
+ }
+#endif
+#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
+ if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
+ uint32_t u = (uint32_t)(d = dp[0]);
+ if (need_swap) u = swap32(u);
+ *((uint32_t *)words) = u;
+ return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
+ }
+#endif
+#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
+ if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
+ uint64_t u = (uint64_t)(d = dp[0]);
+ if (need_swap) u = swap64(u);
+ *((uint64_t *)words) = u;
+ return ((1 < de - dp || CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
+ }
+#endif
+ }
+ else { /* sign < 0 && (flags & INTEGER_PACK_2COMP) */
+ BDIGIT_DBL_SIGNED d;
+ if (wordsize == 1) {
+ *((unsigned char *)words) = (unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
+ 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) {
+ uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
+ if (need_swap) u = swap16(u);
+ *((uint16_t *)words) = u;
+ return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
+ (1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
+ }
+#endif
+#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
+ if (wordsize == 4 && (uintptr_t)words % 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;
+ return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
+ (1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
+ }
+#endif
+#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
+ if (wordsize == 8 && (uintptr_t)words % 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;
+ return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
+ (1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
+ }
+#endif
+ }
+ }
+#if !defined(WORDS_BIGENDIAN)
+ if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
+ (flags & INTEGER_PACK_WORDORDER_MASK) == INTEGER_PACK_LSWORD_FIRST &&
+ (flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_MSBYTE_FIRST) {
+ size_t src_size = (de - dp) * SIZEOF_BDIGIT;
+ size_t dst_size = numwords * wordsize;
+ int overflow = 0;
+ while (0 < src_size && ((unsigned char *)ds)[src_size-1] == 0)
+ src_size--;
+ if (src_size <= dst_size) {
+ MEMCPY(words, dp, char, src_size);
+ MEMZERO((char*)words + src_size, char, dst_size - src_size);
+ }
+ else {
+ MEMCPY(words, dp, char, dst_size);
+ overflow = 1;
+ }
+ if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
+ int zero_p = bytes_2comp(words, dst_size);
+ if (zero_p && overflow) {
+ unsigned char *p = (unsigned char *)dp;
+ if (dst_size == src_size-1 &&
+ p[dst_size] == 1) {
+ overflow = 0;
+ }
+ }
+ }
+ if (overflow)
+ sign *= 2;
+ return sign;
+ }
+#endif
+ if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
+ wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words % 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;
+ int overflow = 0;
+ int mswordfirst_p = (flags & INTEGER_PACK_MSWORD_FIRST) != 0;
+ int msbytefirst_p = (flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ? HOST_BIGENDIAN_P :
+ (flags & INTEGER_PACK_MSBYTE_FIRST) != 0;
+ if (src_num_bdigits <= dst_num_bdigits) {
+ MEMCPY(words, dp, BDIGIT, src_num_bdigits);
+ BDIGITS_ZERO((BDIGIT*)words + src_num_bdigits, dst_num_bdigits - src_num_bdigits);
+ }
+ else {
+ MEMCPY(words, dp, BDIGIT, dst_num_bdigits);
+ overflow = 1;
+ }
+ if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
+ int zero_p = bary_2comp(words, dst_num_bdigits);
+ if (zero_p && overflow &&
+ dst_num_bdigits == src_num_bdigits-1 &&
+ dp[dst_num_bdigits] == 1)
+ overflow = 0;
+ }
+ if (msbytefirst_p != HOST_BIGENDIAN_P) {
+ size_t i;
+ for (i = 0; i < dst_num_bdigits; i++) {
+ BDIGIT d = ((BDIGIT*)words)[i];
+ ((BDIGIT*)words)[i] = swap_bdigit(d);
+ }
+ }
+ if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
+ size_t i;
+ BDIGIT *p = words;
+ for (i = 0; i < numwords; i++) {
+ bary_swap(p, bdigits_per_word);
+ p += bdigits_per_word;
+ }
+ }
+ if (mswordfirst_p) {
+ bary_swap(words, dst_num_bdigits);
+ }
+ if (overflow)
+ sign *= 2;
+ return sign;
+ }
+ }
+
+ buf = words;
+ bufend = buf + numwords * wordsize;
+
+ if (buf == bufend) {
+ /* overflow if non-zero*/
+ if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
+ sign *= 2;
+ else {
+ if (de - dp == 1 && dp[0] == 1)
+ sign = -1; /* val == -1 == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
+ else
+ sign = -2; /* val < -1 == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
+ }
+ }
+ else if (dp == de) {
+ memset(buf, '\0', bufend - buf);
+ }
+ else if (dp < de && buf < bufend) {
+ int word_num_partialbits;
+ size_t word_num_fullbytes;
+
+ ssize_t word_step;
+ size_t byte_start;
+ int byte_step;
+
+ size_t word_start, word_last;
+ unsigned char *wordp, *last_wordp;
+ BDIGIT_DBL dd;
+ int numbits_in_dd;
+
+ integer_pack_loop_setup(numwords, wordsize, nails, flags,
+ &word_num_fullbytes, &word_num_partialbits,
+ &word_start, &word_step, &word_last, &byte_start, &byte_step);
+
+ wordp = buf + word_start;
+ last_wordp = buf + word_last;
+
+ dd = 0;
+ numbits_in_dd = 0;
+
+#define FILL_DD \
+ integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
+#define TAKE_LOWBITS(n) \
+ integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
+
+ while (1) {
+ size_t index_in_word = 0;
+ unsigned char *bytep = wordp + byte_start;
+ while (index_in_word < word_num_fullbytes) {
+ FILL_DD;
+ *bytep = TAKE_LOWBITS(CHAR_BIT);
+ bytep += byte_step;
+ index_in_word++;
+ }
+ if (word_num_partialbits) {
+ FILL_DD;
+ *bytep = TAKE_LOWBITS(word_num_partialbits);
+ bytep += byte_step;
+ index_in_word++;
+ }
+ while (index_in_word < wordsize) {
+ *bytep = 0;
+ bytep += byte_step;
+ index_in_word++;
+ }
+
+ if (wordp == last_wordp)
+ break;
+
+ wordp += word_step;
+ }
+ FILL_DD;
+ /* overflow tests */
+ if (dp != de || 1 < dd) {
+ /* 2**(numwords*(wordsize*CHAR_BIT-nails)+1) <= abs(val) */
+ sign *= 2;
+ }
+ else if (dd == 1) {
+ /* 2**(numwords*(wordsize*CHAR_BIT-nails)) <= abs(val) < 2**(numwords*(wordsize*CHAR_BIT-nails)+1) */
+ if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
+ sign *= 2;
+ else { /* overflow_2comp && sign == -1 */
+ /* test lower bits are all zero. */
+ dp = ds;
+ while (dp < de && *dp == 0)
+ dp++;
+ if (de - dp == 1 && /* only one non-zero word. */
+ POW2_P(*dp)) /* *dp contains only one bit set. */
+ sign = -1; /* val == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
+ else
+ sign = -2; /* val < -2**(numwords*(wordsize*CHAR_BIT-nails)) */
+ }
+ }
+ }
+
+ if ((flags & INTEGER_PACK_2COMP) && (sign < 0 && numwords != 0)) {
+ int word_num_partialbits;
+ size_t word_num_fullbytes;
+
+ ssize_t word_step;
+ size_t byte_start;
+ int byte_step;
+
+ size_t word_start, word_last;
+ unsigned char *wordp, *last_wordp;
+
+ unsigned int partialbits_mask;
+ int carry;
+
+ integer_pack_loop_setup(numwords, wordsize, nails, flags,
+ &word_num_fullbytes, &word_num_partialbits,
+ &word_start, &word_step, &word_last, &byte_start, &byte_step);
+
+ partialbits_mask = (1 << word_num_partialbits) - 1;
+
+ buf = words;
+ wordp = buf + word_start;
+ last_wordp = buf + word_last;
+
+ carry = 1;
+ while (1) {
+ size_t index_in_word = 0;
+ unsigned char *bytep = wordp + byte_start;
+ while (index_in_word < word_num_fullbytes) {
+ carry += (unsigned char)~*bytep;
+ *bytep = (unsigned char)carry;
+ carry >>= CHAR_BIT;
+ bytep += byte_step;
+ index_in_word++;
+ }
+ if (word_num_partialbits) {
+ carry += (*bytep & partialbits_mask) ^ partialbits_mask;
+ *bytep = carry & partialbits_mask;
+ carry >>= word_num_partialbits;
+ bytep += byte_step;
+ index_in_word++;
+ }
+
+ if (wordp == last_wordp)
+ break;
+
+ wordp += word_step;
+ }
+ }
+
+ return sign;
+#undef FILL_DD
+#undef TAKE_LOWBITS
+}
+
+static size_t
+integer_unpack_num_bdigits_small(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
+{
+ /* nlp_bits stands for number of leading padding bits */
+ size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
+ size_t num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG;
+ *nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
+ return num_bdigits;
+}
+
+static size_t
+integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
+{
+ /* BITSPERDIG = SIZEOF_BDIGIT * CHAR_BIT */
+ /* num_bits = (wordsize * CHAR_BIT - nails) * numwords */
+ /* num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG */
+
+ /* num_bits = CHAR_BIT * (wordsize * numwords) - nails * numwords = CHAR_BIT * num_bytes1 - nails * numwords */
+ size_t num_bytes1 = wordsize * numwords;
+
+ /* q1 * CHAR_BIT + r1 = numwords */
+ size_t q1 = numwords / CHAR_BIT;
+ size_t r1 = numwords % CHAR_BIT;
+
+ /* num_bits = CHAR_BIT * num_bytes1 - nails * (q1 * CHAR_BIT + r1) = CHAR_BIT * num_bytes2 - nails * r1 */
+ size_t num_bytes2 = num_bytes1 - nails * q1;
+
+ /* q2 * CHAR_BIT + r2 = nails */
+ size_t q2 = nails / CHAR_BIT;
+ size_t r2 = nails % CHAR_BIT;
+
+ /* num_bits = CHAR_BIT * num_bytes2 - (q2 * CHAR_BIT + r2) * r1 = CHAR_BIT * num_bytes3 - r1 * r2 */
+ size_t num_bytes3 = num_bytes2 - q2 * r1;
+
+ /* q3 * BITSPERDIG + r3 = num_bytes3 */
+ size_t q3 = num_bytes3 / BITSPERDIG;
+ size_t r3 = num_bytes3 % BITSPERDIG;
+
+ /* num_bits = CHAR_BIT * (q3 * BITSPERDIG + r3) - r1 * r2 = BITSPERDIG * num_digits1 + CHAR_BIT * r3 - r1 * r2 */
+ size_t num_digits1 = CHAR_BIT * q3;
+
+ /*
+ * if CHAR_BIT * r3 >= r1 * r2
+ * CHAR_BIT * r3 - r1 * r2 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2))
+ * q4 * BITSPERDIG + r4 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2)
+ * num_bits = BITSPERDIG * num_digits1 + CHAR_BIT * BITSPERDIG - (q4 * BITSPERDIG + r4) = BITSPERDIG * num_digits2 - r4
+ * else
+ * q4 * BITSPERDIG + r4 = -(CHAR_BIT * r3 - r1 * r2)
+ * num_bits = BITSPERDIG * num_digits1 - (q4 * BITSPERDIG + r4) = BITSPERDIG * num_digits2 - r4
+ * end
+ */
+
+ if (CHAR_BIT * r3 >= r1 * r2) {
+ size_t tmp1 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2);
+ size_t q4 = tmp1 / BITSPERDIG;
+ int r4 = (int)(tmp1 % BITSPERDIG);
+ size_t num_digits2 = num_digits1 + CHAR_BIT - q4;
+ *nlp_bits_ret = r4;
+ return num_digits2;
+ }
+ else {
+ size_t tmp1 = r1 * r2 - CHAR_BIT * r3;
+ size_t q4 = tmp1 / BITSPERDIG;
+ int r4 = (int)(tmp1 % BITSPERDIG);
+ size_t num_digits2 = num_digits1 - q4;
+ *nlp_bits_ret = r4;
+ return num_digits2;
+ }
+}
+
+static size_t
+integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
+{
+ size_t num_bdigits;
+
+ if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
+ num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
+#ifdef DEBUG_INTEGER_PACK
+ {
+ int nlp_bits1;
+ size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
+ assert(num_bdigits == num_bdigits1);
+ assert(*nlp_bits_ret == nlp_bits1);
+ }
+#endif
+ }
+ else {
+ num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
+ }
+ return num_bdigits;
+}
+
+static inline void
+integer_unpack_push_bits(int data, int numbits, BDIGIT_DBL *ddp, int *numbits_in_dd_p, BDIGIT **dpp)
+{
+ (*ddp) |= ((BDIGIT_DBL)data) << (*numbits_in_dd_p);
+ *numbits_in_dd_p += numbits;
+ while (BITSPERDIG <= *numbits_in_dd_p) {
+ *(*dpp)++ = BIGLO(*ddp);
+ *ddp = BIGDN(*ddp);
+ *numbits_in_dd_p -= BITSPERDIG;
+ }
+}
+
+static int
+integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp)
+{
+ int sign;
+ if (flags & INTEGER_PACK_2COMP) {
+ sign = (flags & INTEGER_PACK_NEGATIVE) ?
+ ((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
+ ((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
+ if (sign < 0) {
+ u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
+ u = BIGLO(1 + ~u);
+ }
+ }
+ else
+ sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
+ *dp = u;
+ return sign;
+}
+
+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)
+{
+ int sign;
+ const unsigned char *buf = words;
+ BDIGIT *dp;
+ BDIGIT *de;
+
+ dp = bdigits;
+ de = dp + num_bdigits;
+
+ if (!(flags & INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION)) {
+ if (nails == 0 && numwords == 1) {
+ int need_swap = wordsize != 1 &&
+ (flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_NATIVE_BYTE_ORDER &&
+ ((flags & INTEGER_PACK_MSBYTE_FIRST) ? !HOST_BIGENDIAN_P : HOST_BIGENDIAN_P);
+ if (wordsize == 1) {
+ 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;
+ 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;
+ 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;
+ return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
+ }
+#endif
+ }
+#if !defined(WORDS_BIGENDIAN)
+ if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
+ (flags & INTEGER_PACK_WORDORDER_MASK) == INTEGER_PACK_LSWORD_FIRST &&
+ (flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_MSBYTE_FIRST) {
+ size_t src_size = numwords * wordsize;
+ size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
+ MEMCPY(dp, words, char, src_size);
+ if (flags & INTEGER_PACK_2COMP) {
+ if (flags & INTEGER_PACK_NEGATIVE) {
+ int zero_p;
+ memset((char*)dp + src_size, 0xff, dst_size - src_size);
+ zero_p = bary_2comp(dp, num_bdigits);
+ sign = zero_p ? -2 : -1;
+ }
+ else if (buf[src_size-1] >> (CHAR_BIT-1)) {
+ memset((char*)dp + src_size, 0xff, dst_size - src_size);
+ bary_2comp(dp, num_bdigits);
+ sign = -1;
+ }
+ else {
+ MEMZERO((char*)dp + src_size, char, dst_size - src_size);
+ sign = 1;
+ }
+ }
+ else {
+ MEMZERO((char*)dp + src_size, char, dst_size - src_size);
+ sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
+ }
+ return sign;
+ }
+#endif
+ if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
+ wordsize % SIZEOF_BDIGIT == 0) {
+ size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
+ int mswordfirst_p = (flags & INTEGER_PACK_MSWORD_FIRST) != 0;
+ int msbytefirst_p = (flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ? HOST_BIGENDIAN_P :
+ (flags & INTEGER_PACK_MSBYTE_FIRST) != 0;
+ MEMCPY(dp, words, BDIGIT, numwords*bdigits_per_word);
+ if (mswordfirst_p) {
+ bary_swap(dp, num_bdigits);
+ }
+ if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
+ size_t i;
+ BDIGIT *p = dp;
+ for (i = 0; i < numwords; i++) {
+ bary_swap(p, bdigits_per_word);
+ p += bdigits_per_word;
+ }
+ }
+ if (msbytefirst_p != HOST_BIGENDIAN_P) {
+ BDIGIT *p;
+ for (p = dp; p < de; p++) {
+ BDIGIT d = *p;
+ *p = swap_bdigit(d);
+ }
+ }
+ if (flags & INTEGER_PACK_2COMP) {
+ if (flags & INTEGER_PACK_NEGATIVE) {
+ int zero_p = bary_2comp(dp, num_bdigits);
+ sign = zero_p ? -2 : -1;
+ }
+ else if (BDIGIT_MSB(de[-1])) {
+ bary_2comp(dp, num_bdigits);
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ }
+ else {
+ sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
+ }
+ return sign;
+ }
+ }
+
+ if (num_bdigits != 0) {
+ int word_num_partialbits;
+ size_t word_num_fullbytes;
+
+ ssize_t word_step;
+ size_t byte_start;
+ int byte_step;
+
+ size_t word_start, word_last;
+ const unsigned char *wordp, *last_wordp;
+ BDIGIT_DBL dd;
+ int numbits_in_dd;
+
+ integer_pack_loop_setup(numwords, wordsize, nails, flags,
+ &word_num_fullbytes, &word_num_partialbits,
+ &word_start, &word_step, &word_last, &byte_start, &byte_step);
+
+ wordp = buf + word_start;
+ last_wordp = buf + word_last;
+
+ dd = 0;
+ numbits_in_dd = 0;
+
+#define PUSH_BITS(data, numbits) \
+ integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
+
+ while (1) {
+ size_t index_in_word = 0;
+ const unsigned char *bytep = wordp + byte_start;
+ while (index_in_word < word_num_fullbytes) {
+ PUSH_BITS(*bytep, CHAR_BIT);
+ bytep += byte_step;
+ index_in_word++;
+ }
+ if (word_num_partialbits) {
+ PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
+ bytep += byte_step;
+ index_in_word++;
+ }
+
+ if (wordp == last_wordp)
+ break;
+
+ wordp += word_step;
+ }
+ if (dd)
+ *dp++ = (BDIGIT)dd;
+ assert(dp <= de);
+ while (dp < de)
+ *dp++ = 0;
+#undef PUSH_BITS
+ }
+
+ if (!(flags & INTEGER_PACK_2COMP)) {
+ sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
+ }
+ else {
+ if (nlp_bits) {
+ if ((flags & INTEGER_PACK_NEGATIVE) ||
+ (bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1))) {
+ bdigits[num_bdigits-1] |= BIGLO(BDIGMAX << (BITSPERDIG - nlp_bits));
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ }
+ else {
+ if (flags & INTEGER_PACK_NEGATIVE) {
+ sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
+ }
+ else {
+ if (num_bdigits != 0 && BDIGIT_MSB(bdigits[num_bdigits-1]))
+ sign = -1;
+ else
+ sign = 1;
+ }
+ }
+ if (sign == -1 && num_bdigits != 0) {
+ bary_2comp(bdigits, num_bdigits);
+ }
+ }
+
+ return sign;
+}
+
+static void
+bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
+{
+ size_t num_bdigits0;
+ int nlp_bits;
+ int sign;
+
+ validate_integer_pack_format(numwords, wordsize, nails, flags,
+ INTEGER_PACK_MSWORD_FIRST|
+ INTEGER_PACK_LSWORD_FIRST|
+ INTEGER_PACK_MSBYTE_FIRST|
+ INTEGER_PACK_LSBYTE_FIRST|
+ INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP|
+ INTEGER_PACK_FORCE_BIGNUM|
+ INTEGER_PACK_NEGATIVE|
+ INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION);
+
+ num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
+
+ assert(num_bdigits0 <= num_bdigits);
+
+ sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
+
+ if (num_bdigits0 < num_bdigits) {
+ BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
+ if (sign == -2) {
+ bdigits[num_bdigits0] = 1;
+ }
+ }
+}
+
+static int
+bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int borrow)
+{
+ BDIGIT_DBL_SIGNED num;
+ size_t i;
+ size_t sn;
+
+ assert(xn <= zn);
+ assert(yn <= zn);
+
+ sn = xn < yn ? xn : yn;
+
+ num = borrow ? -1 : 0;
+ for (i = 0; i < sn; i++) {
+ num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ if (yn <= xn) {
+ for (; i < xn; i++) {
+ if (num == 0) goto num_is_zero;
+ num += xds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ }
+ else {
+ for (; i < yn; i++) {
+ num -= yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ }
+ if (num == 0) goto num_is_zero;
+ for (; i < zn; i++) {
+ zds[i] = BDIGMAX;
+ }
+ return 1;
+
+ num_is_zero:
+ if (xds == zds && xn == zn)
+ return 0;
+ for (; i < xn; i++) {
+ zds[i] = xds[i];
+ }
+ for (; i < zn; i++) {
+ zds[i] = 0;
+ }
+ return 0;
+}
+
+static int
+bary_sub(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ return bary_subb(zds, zn, xds, xn, yds, yn, 0);
+}
+
+static int
+bary_sub_one(BDIGIT *zds, size_t zn)
+{
+ return bary_subb(zds, zn, zds, zn, NULL, 0, 1);
+}
+
+static int
+bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int carry)
+{
+ BDIGIT_DBL num;
+ size_t i;
+
+ assert(xn <= zn);
+ assert(yn <= zn);
+
+ if (xn > yn) {
+ const BDIGIT *tds;
+ tds = xds; xds = yds; yds = tds;
+ i = xn; xn = yn; yn = i;
+ }
+
+ num = carry ? 1 : 0;
+ for (i = 0; i < xn; i++) {
+ num += (BDIGIT_DBL)xds[i] + yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ for (; i < yn; i++) {
+ if (num == 0) goto num_is_zero;
+ num += yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ for (; i < zn; i++) {
+ if (num == 0) goto num_is_zero;
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ return num != 0;
+
+ num_is_zero:
+ if (yds == zds && yn == zn)
+ return 0;
+ for (; i < yn; i++) {
+ zds[i] = yds[i];
+ }
+ for (; i < zn; i++) {
+ zds[i] = 0;
+ }
+ return 0;
+}
+
+static int
+bary_add(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ return bary_addc(zds, zn, xds, xn, yds, yn, 0);
+}
+
+static int
+bary_add_one(BDIGIT *ds, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++) {
+ ds[i] = BIGLO(ds[i]+1);
+ if (ds[i] != 0)
+ return 0;
+ }
+ return 1;
+}
+
+static void
+bary_mul_single(BDIGIT *zds, size_t zn, BDIGIT x, BDIGIT y)
+{
+ BDIGIT_DBL n;
+
+ assert(2 <= zn);
+
+ n = (BDIGIT_DBL)x * y;
+ bdigitdbl2bary(zds, 2, n);
+ BDIGITS_ZERO(zds + 2, zn - 2);
+}
+
+static int
+bary_muladd_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
+{
+ BDIGIT_DBL n;
+ BDIGIT_DBL dd;
+ size_t j;
+
+ assert(zn > yn);
+
+ if (x == 0)
+ return 0;
+ dd = x;
+ n = 0;
+ for (j = 0; j < yn; j++) {
+ BDIGIT_DBL ee = n + dd * yds[j];
+ if (ee) {
+ n = zds[j] + ee;
+ zds[j] = BIGLO(n);
+ n = BIGDN(n);
+ }
+ else {
+ n = 0;
+ }
+
+ }
+ for (; j < zn; j++) {
+ if (n == 0)
+ break;
+ n += zds[j];
+ zds[j] = BIGLO(n);
+ n = BIGDN(n);
+ }
+ return n != 0;
+}
+
+static BDIGIT_DBL_SIGNED
+bigdivrem_mulsub(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
+{
+ size_t i;
+ BDIGIT_DBL t2;
+ BDIGIT_DBL_SIGNED num;
+
+ assert(zn == yn + 1);
+
+ num = 0;
+ t2 = 0;
+ i = 0;
+
+ do {
+ BDIGIT_DBL ee;
+ t2 += (BDIGIT_DBL)yds[i] * x;
+ ee = num - BIGLO(t2);
+ num = (BDIGIT_DBL)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 */
+ return num;
}
-#define bignew(len,sign) bignew_1(cBignum,len,sign)
+static int
+bary_mulsub_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
+{
+ BDIGIT_DBL_SIGNED num;
+
+ assert(zn == yn + 1);
+
+ num = bigdivrem_mulsub(zds, zn, x, yds, yn);
+ zds[yn] = BIGLO(num);
+ if (BIGDN(num))
+ return 1;
+ return 0;
+}
+
+static void
+bary_mul_normal(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ size_t i;
+
+ assert(xn + yn <= zn);
+
+ BDIGITS_ZERO(zds, zn);
+ for (i = 0; i < xn; i++) {
+ bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
+ }
+}
VALUE
-big_clone(x)
- VALUE x;
+rb_big_mul_normal(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
+ VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ bary_mul_normal(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+
+/* efficient squaring (2 times faster than normal multiplication)
+ * ref: Handbook of Applied Cryptography, Algorithm 14.16
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ */
+static void
+bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn)
{
- VALUE z = bignew_1(CLASS_OF(x), RBIGNUM(x)->len, RBIGNUM(x)->sign);
+ size_t i, j;
+ BDIGIT_DBL c, v, w;
+ BDIGIT vl;
+ int vh;
+
+ assert(xn * 2 <= zn);
+
+ BDIGITS_ZERO(zds, zn);
+
+ if (xn == 0)
+ return;
+
+ for (i = 0; i < xn-1; i++) {
+ v = (BDIGIT_DBL)xds[i];
+ if (!v)
+ continue;
+ c = (BDIGIT_DBL)zds[i + i] + v * v;
+ zds[i + i] = BIGLO(c);
+ c = BIGDN(c);
+ v *= 2;
+ vl = BIGLO(v);
+ vh = (int)BIGDN(v);
+ for (j = i + 1; j < xn; j++) {
+ w = (BDIGIT_DBL)xds[j];
+ c += (BDIGIT_DBL)zds[i + j] + vl * w;
+ zds[i + j] = BIGLO(c);
+ c = BIGDN(c);
+ if (vh)
+ c += w;
+ }
+ if (c) {
+ c += (BDIGIT_DBL)zds[i + xn];
+ zds[i + xn] = BIGLO(c);
+ c = BIGDN(c);
+ if (c)
+ zds[i + xn + 1] += (BDIGIT)c;
+ }
+ }
+
+ /* i == xn-1 */
+ v = (BDIGIT_DBL)xds[i];
+ if (!v)
+ return;
+ c = (BDIGIT_DBL)zds[i + i] + v * v;
+ zds[i + i] = BIGLO(c);
+ c = BIGDN(c);
+ if (c) {
+ zds[i + xn] += BIGLO(c);
+ }
+}
- MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, RBIGNUM(x)->len);
+VALUE
+rb_big_sq_fast(VALUE x)
+{
+ size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
+ VALUE z = bignew(zn, 1);
+ bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
+ RB_GC_GUARD(x);
return z;
}
-void
-big_2comp(x) /* get 2's complement */
- VALUE x;
+/* balancing multiplication by slicing larger argument */
+static void
+bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn, mulfunc_t *mulfunc)
+{
+ VALUE work = 0;
+ size_t yn0 = yn;
+ size_t r, n;
+
+ assert(xn + yn <= zn);
+ assert(xn <= yn);
+ assert(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn));
+
+ BDIGITS_ZERO(zds, xn);
+
+ n = 0;
+ while (yn > 0) {
+ BDIGIT *tds;
+ size_t tn;
+ r = xn > yn ? yn : xn;
+ tn = xn + r;
+ if (2 * (xn + r) <= zn - n) {
+ tds = zds + n + xn + r;
+ mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
+ BDIGITS_ZERO(zds + n + xn, r);
+ bary_add(zds + n, tn,
+ zds + n, tn,
+ tds, tn);
+ }
+ else {
+ if (wn < xn) {
+ wn = xn;
+ wds = ALLOCV_N(BDIGIT, work, wn);
+ }
+ tds = zds + n;
+ MEMCPY(wds, zds + n, BDIGIT, xn);
+ mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
+ bary_add(zds + n, tn,
+ zds + n, tn,
+ wds, xn);
+ }
+ yn -= r;
+ n += r;
+ }
+ BDIGITS_ZERO(zds+xn+yn0, zn - (xn+yn0));
+
+ if (work)
+ ALLOCV_END(work);
+}
+
+VALUE
+rb_big_mul_balance(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
+ VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ bary_mul_balance_with_mulfunc(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0, bary_mul_toom3_start);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+
+/* multiplication by karatsuba method */
+static void
+bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
+{
+ VALUE work = 0;
+
+ size_t n;
+ int sub_p, borrow, carry1, carry2, carry3;
+
+ int odd_y = 0;
+ int odd_xy = 0;
+ int sq;
+
+ const BDIGIT *xds0, *xds1, *yds0, *yds1;
+ BDIGIT *zds0, *zds1, *zds2, *zds3;
+
+ assert(xn + yn <= zn);
+ assert(xn <= yn);
+ assert(yn < 2 * xn);
+
+ sq = xds == yds && xn == yn;
+
+ if (yn & 1) {
+ odd_y = 1;
+ yn--;
+ if (yn < xn) {
+ odd_xy = 1;
+ xn--;
+ }
+ }
+
+ n = yn / 2;
+
+ assert(n < xn);
+
+ if (wn < n) {
+ /* This function itself needs only n BDIGITs for work area.
+ * However this function calls bary_mul_karatsuba and
+ * bary_mul_balance recursively.
+ * 2n BDIGITs are enough to avoid allocations in
+ * the recursively called functions.
+ */
+ wn = 2*n;
+ wds = ALLOCV_N(BDIGIT, work, wn);
+ }
+
+ /* Karatsuba algorithm:
+ *
+ * x = x0 + r*x1
+ * y = y0 + r*y1
+ * z = x*y
+ * = (x0 + r*x1) * (y0 + r*y1)
+ * = x0*y0 + r*(x1*y0 + x0*y1) + r*r*x1*y1
+ * = x0*y0 + r*(x0*y0 + x1*y1 - (x1-x0)*(y1-y0)) + r*r*x1*y1
+ * = x0*y0 + r*(x0*y0 + x1*y1 - (x0-x1)*(y0-y1)) + r*r*x1*y1
+ */
+
+ xds0 = xds;
+ xds1 = xds + n;
+ yds0 = yds;
+ yds1 = yds + n;
+ zds0 = zds;
+ zds1 = zds + n;
+ zds2 = zds + 2*n;
+ zds3 = zds + 3*n;
+
+ sub_p = 1;
+
+ /* zds0:? zds1:? zds2:? zds3:? wds:? */
+
+ if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
+ bary_2comp(zds0, n);
+ sub_p = !sub_p;
+ }
+
+ /* zds0:|x1-x0| zds1:? zds2:? zds3:? wds:? */
+
+ if (sq) {
+ sub_p = 1;
+ bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
+ }
+ else {
+ if (bary_sub(wds, n, yds, n, yds+n, n)) {
+ bary_2comp(wds, n);
+ sub_p = !sub_p;
+ }
+
+ /* zds0:|x1-x0| zds1:? zds2:? zds3:? wds:|y1-y0| */
+
+ bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
+ }
+
+ /* zds0:|x1-x0| zds1,zds2:|x1-x0|*|y1-y0| zds3:? wds:|y1-y0| */
+
+ borrow = 0;
+ if (sub_p) {
+ borrow = !bary_2comp(zds1, 2*n);
+ }
+ /* zds0:|x1-x0| zds1,zds2:-?|x1-x0|*|y1-y0| zds3:? wds:|y1-y0| */
+
+ MEMCPY(wds, zds1, BDIGIT, n);
+
+ /* zds0:|x1-x0| zds1,zds2:-?|x1-x0|*|y1-y0| zds3:? wds:lo(-?|x1-x0|*|y1-y0|) */
+
+ bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
+
+ /* zds0,zds1:x0*y0 zds2:hi(-?|x1-x0|*|y1-y0|) zds3:? wds:lo(-?|x1-x0|*|y1-y0|) */
+
+ carry1 = bary_add(wds, n, wds, n, zds0, n);
+ carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
+
+ /* zds0,zds1:x0*y0 zds2:hi(x0*y0-?|x1-x0|*|y1-y0|) zds3:? wds:lo(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ carry2 = bary_add(zds1, n, zds1, n, wds, n);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2:hi(x0*y0-?|x1-x0|*|y1-y0|) zds3:? wds:lo(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ MEMCPY(wds, zds2, BDIGIT, n);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2:_ zds3:? wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2,zds3:x1*y1 wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ carry3 = bary_add(zds1, n, zds1, n, zds2, n);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1 wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1+hi(x1*y1) wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
+
+ bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
+
+ /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1+hi(x1*y1)+hi(x0*y0-?|x1-x0|*|y1-y0|) wds:_ */
+
+ if (carry2)
+ bary_add_one(zds2, zn-2*n);
+
+ if (carry1 + carry3 - borrow < 0)
+ bary_sub_one(zds3, zn-3*n);
+ else if (carry1 + carry3 - borrow > 0) {
+ BDIGIT c = carry1 + carry3 - borrow;
+ bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
+ }
+
+ /*
+ if (SIZEOF_BDIGIT * zn <= 16) {
+ uint128_t z, x, y;
+ ssize_t i;
+ for (x = 0, i = xn-1; 0 <= i; i--) { x <<= SIZEOF_BDIGIT*CHAR_BIT; x |= xds[i]; }
+ for (y = 0, i = yn-1; 0 <= i; i--) { y <<= SIZEOF_BDIGIT*CHAR_BIT; y |= yds[i]; }
+ for (z = 0, i = zn-1; 0 <= i; i--) { z <<= SIZEOF_BDIGIT*CHAR_BIT; z |= zds[i]; }
+ assert(z == x * y);
+ }
+ */
+
+ if (odd_xy) {
+ bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
+ bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
+ }
+ else if (odd_y) {
+ bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
+ }
+
+ if (work)
+ ALLOCV_END(work);
+}
+
+VALUE
+rb_big_mul_karatsuba(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
+ VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ if (!((xn <= yn && yn < 2) || KARATSUBA_BALANCED(xn, yn)))
+ rb_raise(rb_eArgError, "unexpected bignum length for karatsuba");
+ bary_mul_karatsuba(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+
+static void
+bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
{
- unsigned int i = RBIGNUM(x)->len;
- USHORT *ds = BDIGITS(x);
- long num;
+ size_t n;
+ size_t wnc;
+ VALUE work = 0;
+
+ /* "p" stands for "positive". Actually it means "non-negative", though. */
+ size_t x0n; const BDIGIT *x0ds;
+ size_t x1n; const BDIGIT *x1ds;
+ size_t x2n; const BDIGIT *x2ds;
+ size_t y0n; const BDIGIT *y0ds;
+ size_t y1n; const BDIGIT *y1ds;
+ size_t y2n; const BDIGIT *y2ds;
+
+ size_t u1n; BDIGIT *u1ds; int u1p;
+ size_t u2n; BDIGIT *u2ds; int u2p;
+ size_t u3n; BDIGIT *u3ds; int u3p;
+
+ size_t v1n; BDIGIT *v1ds; int v1p;
+ size_t v2n; BDIGIT *v2ds; int v2p;
+ size_t v3n; BDIGIT *v3ds; int v3p;
+
+ size_t t0n; BDIGIT *t0ds; int t0p;
+ size_t t1n; BDIGIT *t1ds; int t1p;
+ size_t t2n; BDIGIT *t2ds; int t2p;
+ size_t t3n; BDIGIT *t3ds; int t3p;
+ size_t t4n; BDIGIT *t4ds; int t4p;
+
+ size_t z0n; BDIGIT *z0ds;
+ size_t z1n; BDIGIT *z1ds; int z1p;
+ size_t z2n; BDIGIT *z2ds; int z2p;
+ size_t z3n; BDIGIT *z3ds; int z3p;
+ size_t z4n; BDIGIT *z4ds;
+
+ size_t zzn; BDIGIT *zzds;
+
+ int sq = xds == yds && xn == yn;
+
+ assert(xn <= yn); /* assume y >= x */
+ assert(xn + yn <= zn);
+
+ n = (yn + 2) / 3;
+ assert(2*n < xn);
+
+ wnc = 0;
+
+ wnc += (u1n = n+1); /* BITSPERDIG*n+2 bits */
+ wnc += (u2n = n+1); /* BITSPERDIG*n+1 bits */
+ wnc += (u3n = n+1); /* BITSPERDIG*n+3 bits */
+ wnc += (v1n = n+1); /* BITSPERDIG*n+2 bits */
+ wnc += (v2n = n+1); /* BITSPERDIG*n+1 bits */
+ wnc += (v3n = n+1); /* BITSPERDIG*n+3 bits */
+
+ wnc += (t0n = 2*n); /* BITSPERDIG*2*n bits */
+ wnc += (t1n = 2*n+2); /* BITSPERDIG*2*n+4 bits but bary_mul needs u1n+v1n */
+ wnc += (t2n = 2*n+2); /* BITSPERDIG*2*n+2 bits but bary_mul needs u2n+v2n */
+ wnc += (t3n = 2*n+2); /* BITSPERDIG*2*n+6 bits but bary_mul needs u3n+v3n */
+ wnc += (t4n = 2*n); /* BITSPERDIG*2*n bits */
+
+ wnc += (z1n = 2*n+1); /* BITSPERDIG*2*n+5 bits */
+ wnc += (z2n = 2*n+1); /* BITSPERDIG*2*n+6 bits */
+ wnc += (z3n = 2*n+1); /* BITSPERDIG*2*n+8 bits */
+
+ if (wn < wnc) {
+ wn = wnc * 3 / 2; /* Allocate working memory for whole recursion at once. */
+ wds = ALLOCV_N(BDIGIT, work, wn);
+ }
+
+ u1ds = wds; wds += u1n;
+ u2ds = wds; wds += u2n;
+ u3ds = wds; wds += u3n;
+
+ v1ds = wds; wds += v1n;
+ v2ds = wds; wds += v2n;
+ v3ds = wds; wds += v3n;
+
+ t0ds = wds; wds += t0n;
+ t1ds = wds; wds += t1n;
+ t2ds = wds; wds += t2n;
+ t3ds = wds; wds += t3n;
+ t4ds = wds; wds += t4n;
+
+ z1ds = wds; wds += z1n;
+ z2ds = wds; wds += z2n;
+ z3ds = wds; wds += z3n;
+
+ wn -= wnc;
+
+ zzds = u1ds;
+ zzn = 6*n+1;
+
+ x0n = n;
+ x1n = n;
+ x2n = xn - 2*n;
+ x0ds = xds;
+ x1ds = xds + n;
+ x2ds = xds + 2*n;
+
+ if (sq) {
+ y0n = x0n;
+ y1n = x1n;
+ y2n = x2n;
+ y0ds = x0ds;
+ y1ds = x1ds;
+ y2ds = x2ds;
+ }
+ else {
+ y0n = n;
+ y1n = n;
+ y2n = yn - 2*n;
+ y0ds = yds;
+ y1ds = yds + n;
+ y2ds = yds + 2*n;
+ }
+
+ /*
+ * ref. http://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
+ *
+ * z(b) = x(b) * y(b)
+ * z(b) = z0 * b^0 + z1 * b^1 + z2 * b^2 + z3 * b^3 + z4 * b^4
+ * where:
+ * z0 = x0 * y0
+ * z1 = x0 * y1 + x1 * y0
+ * z2 = x0 * y2 + x1 * y1 + x2 * y0
+ * z3 = x1 * y2 + x2 * y1
+ * z4 = x2 * y2
+ *
+ * Toom3 method (a.k.a. Toom-Cook method):
+ * (Step1) calculating 5 points z(b0), z(b1), z(b2), z(b3), z(b4),
+ * where:
+ * b0 = 0, b1 = 1, b2 = -1, b3 = -2, b4 = inf,
+ * z(0) = x(0) * y(0) = x0 * y0
+ * z(1) = x(1) * y(1) = (x0 + x1 + x2) * (y0 + y1 + y2)
+ * z(-1) = x(-1) * y(-1) = (x0 - x1 + x2) * (y0 - y1 + y2)
+ * z(-2) = x(-2) * y(-2) = (x0 - 2 * (x1 - 2 * x2)) * (y0 - 2 * (y1 - 2 * y2))
+ * z(inf) = x(inf) * y(inf) = x2 * y2
+ *
+ * (Step2) interpolating z0, z1, z2, z3 and z4.
+ *
+ * (Step3) Substituting base value into b of the polynomial z(b),
+ */
+
+ /*
+ * [Step1] calculating 5 points z(b0), z(b1), z(b2), z(b3), z(b4)
+ */
+
+ /* u1 <- x0 + x2 */
+ bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
+ u1p = 1;
+
+ /* x(-1) : u2 <- u1 - x1 = x0 - x1 + x2 */
+ if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
+ bary_2comp(u2ds, u2n);
+ u2p = 0;
+ }
+ else {
+ u2p = 1;
+ }
+
+ /* x(1) : u1 <- u1 + x1 = x0 + x1 + x2 */
+ bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
+
+ /* x(-2) : u3 <- 2 * (u2 + x2) - x0 = x0 - 2 * (x1 - 2 * x2) */
+ u3p = 1;
+ if (u2p) {
+ bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
+ }
+ else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
+ bary_2comp(u3ds, u3n);
+ u3p = 0;
+ }
+ bary_small_lshift(u3ds, u3ds, u3n, 1);
+ if (!u3p) {
+ bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
+ }
+ else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
+ bary_2comp(u3ds, u3n);
+ u3p = 0;
+ }
+
+ if (sq) {
+ v1n = u1n; v1ds = u1ds; v1p = u1p;
+ v2n = u2n; v2ds = u2ds; v2p = u2p;
+ v3n = u3n; v3ds = u3ds; v3p = u3p;
+ }
+ else {
+ /* v1 <- y0 + y2 */
+ bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
+ v1p = 1;
+
+ /* y(-1) : v2 <- v1 - y1 = y0 - y1 + y2 */
+ v2p = 1;
+ if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
+ bary_2comp(v2ds, v2n);
+ v2p = 0;
+ }
+
+ /* y(1) : v1 <- v1 + y1 = y0 + y1 + y2 */
+ bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
+
+ /* y(-2) : v3 <- 2 * (v2 + y2) - y0 = y0 - 2 * (y1 - 2 * y2) */
+ v3p = 1;
+ if (v2p) {
+ bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
+ }
+ else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
+ bary_2comp(v3ds, v3n);
+ v3p = 0;
+ }
+ bary_small_lshift(v3ds, v3ds, v3n, 1);
+ if (!v3p) {
+ bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
+ }
+ else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
+ bary_2comp(v3ds, v3n);
+ v3p = 0;
+ }
+ }
+
+ /* z(0) : t0 <- x0 * y0 */
+ bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
+ t0p = 1;
+
+ /* z(1) : t1 <- u1 * v1 */
+ bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
+ t1p = u1p == v1p;
+ assert(t1ds[t1n-1] == 0);
+ t1n--;
+
+ /* z(-1) : t2 <- u2 * v2 */
+ bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
+ t2p = u2p == v2p;
+ assert(t2ds[t2n-1] == 0);
+ t2n--;
+
+ /* z(-2) : t3 <- u3 * v3 */
+ bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
+ t3p = u3p == v3p;
+ assert(t3ds[t3n-1] == 0);
+ t3n--;
+
+ /* z(inf) : t4 <- x2 * y2 */
+ bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
+ t4p = 1;
+
+ /*
+ * [Step2] interpolating z0, z1, z2, z3 and z4.
+ */
+
+ /* z0 <- z(0) == t0 */
+ z0n = t0n; z0ds = t0ds;
+
+ /* z4 <- z(inf) == t4 */
+ z4n = t4n; z4ds = t4ds;
+
+ /* z3 <- (z(-2) - z(1)) / 3 == (t3 - t1) / 3 */
+ if (t3p == t1p) {
+ z3p = t3p;
+ if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
+ bary_2comp(z3ds, z3n);
+ z3p = !z3p;
+ }
+ }
+ else {
+ z3p = t3p;
+ bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
+ }
+ bigdivrem_single(z3ds, z3ds, z3n, 3);
+
+ /* z1 <- (z(1) - z(-1)) / 2 == (t1 - t2) / 2 */
+ if (t1p == t2p) {
+ z1p = t1p;
+ if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
+ bary_2comp(z1ds, z1n);
+ z1p = !z1p;
+ }
+ }
+ else {
+ z1p = t1p;
+ bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
+ }
+ bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
+
+ /* z2 <- z(-1) - z(0) == t2 - t0 */
+ if (t2p == t0p) {
+ z2p = t2p;
+ if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
+ bary_2comp(z2ds, z2n);
+ z2p = !z2p;
+ }
+ }
+ else {
+ z2p = t2p;
+ bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
+ }
+
+ /* z3 <- (z2 - z3) / 2 + 2 * z(inf) == (z2 - z3) / 2 + 2 * t4 */
+ if (z2p == z3p) {
+ z3p = z2p;
+ if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
+ bary_2comp(z3ds, z3n);
+ z3p = !z3p;
+ }
+ }
+ else {
+ z3p = z2p;
+ bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
+ }
+ bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
+ if (z3p == t4p) {
+ bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
+ }
+ else {
+ if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
+ bary_2comp(z3ds, z3n);
+ z3p = !z3p;
+ }
+ }
+
+ /* z2 <- z2 + z1 - z(inf) == z2 + z1 - t4 */
+ if (z2p == z1p) {
+ bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
+ }
+ else {
+ if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
+ bary_2comp(z2ds, z2n);
+ z2p = !z2p;
+ }
+ }
+
+ if (z2p == t4p) {
+ if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
+ bary_2comp(z2ds, z2n);
+ z2p = !z2p;
+ }
+ }
+ else {
+ bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
+ }
+
+ /* z1 <- z1 - z3 */
+ if (z1p == z3p) {
+ if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
+ bary_2comp(z1ds, z1n);
+ z1p = !z1p;
+ }
+ }
+ else {
+ bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
+ }
+
+ /*
+ * [Step3] Substituting base value into b of the polynomial z(b),
+ */
+
+ MEMCPY(zzds, z0ds, BDIGIT, z0n);
+ BDIGITS_ZERO(zzds + z0n, 4*n - z0n);
+ MEMCPY(zzds + 4*n, z4ds, BDIGIT, z4n);
+ BDIGITS_ZERO(zzds + 4*n + z4n, zzn - (4*n + z4n));
+ if (z1p)
+ bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
+ else
+ bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
+ if (z2p)
+ bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
+ else
+ bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
+ if (z3p)
+ bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
+ else
+ bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
+
+ BARY_TRUNC(zzds, zzn);
+ MEMCPY(zds, zzds, BDIGIT, zzn);
+ BDIGITS_ZERO(zds + zzn, zn - zzn);
+
+ if (work)
+ ALLOCV_END(work);
+}
+
+VALUE
+rb_big_mul_toom3(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
+ VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ if (xn > yn || yn < 3 || !TOOM3_BALANCED(xn,yn))
+ rb_raise(rb_eArgError, "unexpected bignum length for toom3");
+ bary_mul_toom3(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+
+#ifdef USE_GMP
+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;
+
+ assert(xn + yn <= zn);
+
+ mpz_init(x);
+ mpz_init(y);
+ mpz_init(z);
+ mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+ if (xds == yds && xn == yn) {
+ mpz_mul(z, x, x);
+ }
+ else {
+ mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
+ mpz_mul(z, x, y);
+ }
+ mpz_export(zds, &count, -1, sizeof(BDIGIT), 0, nails, z);
+ BDIGITS_ZERO(zds+count, zn-count);
+ mpz_clear(x);
+ mpz_clear(y);
+ mpz_clear(z);
+}
+
+VALUE
+rb_big_mul_gmp(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
+ VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ bary_mul_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+#endif
+
+static void
+bary_short_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ assert(xn + yn <= zn);
+
+ if (xn == 1 && yn == 1) {
+ bary_mul_single(zds, zn, xds[0], yds[0]);
+ }
+ else {
+ bary_mul_normal(zds, zn, xds, xn, yds, yn);
+ rb_thread_check_ints();
+ }
+}
+
+/* determine whether a bignum is sparse or not by random sampling */
+static inline int
+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++;
+
+ return (c <= 1) ? 1 : 0;
+}
+
+static int
+bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp, const BDIGIT **ydsp, size_t *ynp)
+{
+ size_t nlsz; /* number of least significant zero BDIGITs */
+
+ BDIGIT *zds = *zdsp;
+ size_t zn = *znp;
+ const BDIGIT *xds = *xdsp;
+ size_t xn = *xnp;
+ const BDIGIT *yds = *ydsp;
+ size_t yn = *ynp;
+
+ assert(xn + yn <= zn);
+
+ nlsz = 0;
+
+ while (0 < xn) {
+ if (xds[xn-1] == 0) {
+ xn--;
+ }
+ else {
+ do {
+ if (xds[0] != 0)
+ break;
+ xds++;
+ xn--;
+ nlsz++;
+ } while (0 < xn);
+ break;
+ }
+ }
+
+ while (0 < yn) {
+ if (yds[yn-1] == 0) {
+ yn--;
+ }
+ else {
+ do {
+ if (yds[0] != 0)
+ break;
+ yds++;
+ yn--;
+ nlsz++;
+ } while (0 < yn);
+ break;
+ }
+ }
+
+ if (nlsz) {
+ BDIGITS_ZERO(zds, nlsz);
+ zds += nlsz;
+ zn -= nlsz;
+ }
+
+ /* make sure that y is longer than x */
+ if (xn > yn) {
+ const BDIGIT *tds;
+ size_t tn;
+ tds = xds; xds = yds; yds = tds;
+ tn = xn; xn = yn; yn = tn;
+ }
+ assert(xn <= yn);
+
+ if (xn <= 1) {
+ if (xn == 0) {
+ BDIGITS_ZERO(zds, zn);
+ return 1;
+ }
+
+ if (xds[0] == 1) {
+ MEMCPY(zds, yds, BDIGIT, yn);
+ BDIGITS_ZERO(zds+yn, zn-yn);
+ return 1;
+ }
+ if (POW2_P(xds[0])) {
+ zds[yn] = bary_small_lshift(zds, yds, yn, bit_length(xds[0])-1);
+ BDIGITS_ZERO(zds+yn+1, zn-yn-1);
+ return 1;
+ }
+ if (yn == 1 && yds[0] == 1) {
+ zds[0] = xds[0];
+ BDIGITS_ZERO(zds+1, zn-1);
+ return 1;
+ }
+ bary_mul_normal(zds, zn, xds, xn, yds, yn);
+ return 1;
+ }
+
+ *zdsp = zds;
+ *znp = zn;
+ *xdsp = xds;
+ *xnp = xn;
+ *ydsp = yds;
+ *ynp = yn;
+
+ return 0;
+}
+
+static void
+bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
+{
+ /* 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;
+ }
+
+ /* normal multiplication when x or y is a sparse bignum */
+ if (bary_sparse_p(xds, xn)) goto normal;
+ if (bary_sparse_p(yds, yn)) {
+ bary_short_mul(zds, zn, yds, yn, xds, xn);
+ return;
+ }
+
+ /* balance multiplication by slicing y when x is much smaller than y */
+ if (!KARATSUBA_BALANCED(xn, yn)) {
+ bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
+ return;
+ }
+
+ /* multiplication by karatsuba method */
+ bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
+}
+
+static void
+bary_mul_karatsuba_start(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
+{
+ if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
+ return;
+
+ bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
+}
+
+static void
+bary_mul_toom3_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
+{
+ if (xn < TOOM3_MUL_DIGITS) {
+ bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
+ return;
+ }
+
+ if (!TOOM3_BALANCED(xn, yn)) {
+ bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
+ return;
+ }
+
+ bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
+}
+
+static void
+bary_mul_toom3_start(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
+{
+ if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
+ return;
+
+ bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
+}
+
+static void
+bary_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ if (xn <= yn) {
+ if (xn < NAIVE_MUL_DIGITS) {
+ if (xds == yds && xn == yn)
+ bary_sq_fast(zds, zn, xds, xn);
+ else
+ bary_short_mul(zds, zn, xds, xn, yds, yn);
+ return;
+ }
+ }
+ else {
+ if (yn < NAIVE_MUL_DIGITS) {
+ bary_short_mul(zds, zn, yds, yn, xds, xn);
+ return;
+ }
+ }
+
+#ifdef USE_GMP
+ bary_mul_gmp(zds, zn, xds, xn, yds, yn);
+#else
+ bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
+#endif
+}
+
+struct big_div_struct {
+ size_t yn, zn;
+ BDIGIT *yds, *zds;
+ volatile VALUE stop;
+};
+
+static void *
+bigdivrem1(void *ptr)
+{
+ struct big_div_struct *bds = (struct big_div_struct*)ptr;
+ size_t yn = bds->yn;
+ size_t zn = bds->zn;
+ BDIGIT *yds = bds->yds, *zds = bds->zds;
+ BDIGIT_DBL_SIGNED num;
+ BDIGIT q;
- while (i--) ds[i] = ~ds[i];
- i = 0; num = 1;
do {
- num += ds[i];
- ds[i++] = BIGLO(num);
- num = BIGDN(num);
- } while (i < RBIGNUM(x)->len);
- if (ds[0] == 1 || ds[0] == 0) {
- for (i=1;i<RBIGNUM(x)->len;i++) {
- if (ds[i] != 0) return;
+ if (bds->stop) {
+ bds->zn = zn;
+ return 0;
+ }
+ if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
+ else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
+ if (q) {
+ num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
+ q,
+ yds, yn);
+ while (num) { /* "add back" required */
+ q--;
+ num = bary_add(zds+zn-(yn+1), yn,
+ zds+zn-(yn+1), yn,
+ yds, yn);
+ num--;
+ }
}
- REALLOC_N(BDIGITS(x), USHORT, RBIGNUM(x)->len++);
- ds = BDIGITS(x);
- ds[RBIGNUM(x)->len-1] = 1;
+ zn--;
+ zds[zn] = q;
+ } while (zn > yn);
+ return 0;
+}
+
+static void
+rb_big_stop(void *ptr)
+{
+ struct big_div_struct *bds = ptr;
+ bds->stop = Qtrue;
+}
+
+static BDIGIT
+bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
+{
+ assert(0 < xn);
+ assert(x_higher_bdigit < y);
+ if (POW2_P(y)) {
+ BDIGIT r;
+ r = xds[0] & (y-1);
+ bary_small_rshift(qds, xds, xn, bit_length(y)-1, x_higher_bdigit);
+ return r;
+ }
+ else {
+ size_t i;
+ BDIGIT_DBL t2;
+ t2 = x_higher_bdigit;
+ i = xn;
+ while (i--) {
+ t2 = BIGUP(t2) + xds[i];
+ qds[i] = (BDIGIT)(t2 / y);
+ t2 %= y;
+ }
+ return (BDIGIT)t2;
+ }
+}
+
+static BDIGIT
+bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
+{
+ return bigdivrem_single1(qds, xds, xn, 0, y);
+}
+
+static void
+bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
+{
+ struct big_div_struct bds;
+ size_t ynzero;
+
+ assert(yn < zn);
+ assert(BDIGIT_MSB(yds[yn-1]));
+ assert(zds[zn-1] < yds[yn-1]);
+
+ for (ynzero = 0; !yds[ynzero]; ynzero++);
+
+ if (ynzero+1 == yn) {
+ BDIGIT r;
+ r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
+ zds[ynzero] = r;
+ return;
+ }
+
+ bds.yn = yn - ynzero;
+ bds.zds = zds + ynzero;
+ bds.yds = yds + ynzero;
+ bds.stop = Qfalse;
+ bds.zn = zn - ynzero;
+ if (bds.zn > 10000 || bds.yn > 10000) {
+ retry:
+ bds.stop = Qfalse;
+ rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
+
+ if (bds.stop == Qtrue) {
+ /* execute trap handler, but exception was not raised. */
+ goto retry;
+ }
+ }
+ else {
+ bigdivrem1(&bds);
+ }
+}
+
+static void
+bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ int shift;
+ BDIGIT *zds, *yyds;
+ size_t zn;
+ VALUE tmpyz = 0;
+
+ assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
+ assert(qds ? (xn - yn + 1) <= qn : 1);
+ assert(rds ? yn <= rn : 1);
+
+ zn = xn + BIGDIVREM_EXTRA_WORDS;
+
+ shift = nlz(yds[yn-1]);
+ if (shift) {
+ int alloc_y = !rds;
+ int alloc_z = !qds || qn < zn;
+ if (alloc_y && alloc_z) {
+ yyds = ALLOCV_N(BDIGIT, tmpyz, yn+zn);
+ zds = yyds + yn;
+ }
+ else {
+ yyds = alloc_y ? ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
+ zds = alloc_z ? ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
+ }
+ zds[xn] = bary_small_lshift(zds, xds, xn, shift);
+ bary_small_lshift(yyds, yds, yn, shift);
+ }
+ else {
+ if (qds && zn <= qn)
+ zds = qds;
+ else
+ zds = ALLOCV_N(BDIGIT, tmpyz, zn);
+ MEMCPY(zds, xds, BDIGIT, xn);
+ zds[xn] = 0;
+ /* bigdivrem_restoring will not modify y.
+ * So use yds directly. */
+ yyds = (BDIGIT *)yds;
+ }
+
+ bigdivrem_restoring(zds, zn, yyds, yn);
+
+ if (rds) {
+ if (shift)
+ bary_small_rshift(rds, zds, yn, shift, 0);
+ else
+ MEMCPY(rds, zds, BDIGIT, yn);
+ BDIGITS_ZERO(rds+yn, rn-yn);
+ }
+
+ if (qds) {
+ size_t j = zn - yn;
+ MEMMOVE(qds, zds+yn, BDIGIT, j);
+ BDIGITS_ZERO(qds+j, qn-j);
+ }
+
+ if (tmpyz)
+ ALLOCV_END(tmpyz);
+}
+
+VALUE
+rb_big_divrem_normal(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
+ BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
+ VALUE q, r;
+
+ BARY_TRUNC(yds, yn);
+ if (yn == 0)
+ rb_num_zerodiv();
+ BARY_TRUNC(xds, xn);
+
+ if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
+ return rb_assoc_new(LONG2FIX(0), x);
+
+ qn = xn + BIGDIVREM_EXTRA_WORDS;
+ q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ qds = BDIGITS(q);
+
+ rn = yn;
+ r = bignew(rn, BIGNUM_SIGN(x));
+ rds = BDIGITS(r);
+
+ bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
+
+ bigtrunc(q);
+ bigtrunc(r);
+
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+
+ return rb_assoc_new(q, r);
+}
+
+#ifdef USE_GMP
+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;
+
+ assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
+ assert(qds ? (xn - yn + 1) <= qn : 1);
+ assert(rds ? yn <= rn : 1);
+ assert(qds || rds);
+
+ mpz_init(x);
+ mpz_init(y);
+ 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);
+
+ if (!rds) {
+ mpz_fdiv_q(q, x, y);
+ }
+ else if (!qds) {
+ mpz_fdiv_r(r, x, y);
+ }
+ else {
+ mpz_fdiv_qr(q, r, x, y);
+ }
+
+ mpz_clear(x);
+ mpz_clear(y);
+
+ if (qds) {
+ mpz_export(qds, &count, -1, sizeof(BDIGIT), 0, nails, q);
+ BDIGITS_ZERO(qds+count, qn-count);
+ mpz_clear(q);
+ }
+
+ if (rds) {
+ mpz_export(rds, &count, -1, sizeof(BDIGIT), 0, nails, r);
+ BDIGITS_ZERO(rds+count, rn-count);
+ mpz_clear(r);
+ }
+}
+
+VALUE
+rb_big_divrem_gmp(VALUE x, VALUE y)
+{
+ size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
+ BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
+ VALUE q, r;
+
+ BARY_TRUNC(yds, yn);
+ if (yn == 0)
+ rb_num_zerodiv();
+ BARY_TRUNC(xds, xn);
+
+ if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
+ return rb_assoc_new(LONG2FIX(0), x);
+
+ qn = xn - yn + 1;
+ q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ qds = BDIGITS(q);
+
+ rn = yn;
+ r = bignew(rn, BIGNUM_SIGN(x));
+ rds = BDIGITS(r);
+
+ bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
+
+ bigtrunc(q);
+ bigtrunc(r);
+
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+
+ return rb_assoc_new(q, r);
+}
+#endif
+
+static void
+bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+#ifdef USE_GMP
+ if (GMP_DIV_DIGITS < xn) {
+ bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
+ return;
+ }
+#endif
+ bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
+}
+
+static void
+bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
+{
+ assert(xn <= qn);
+ assert(yn <= rn);
+
+ BARY_TRUNC(yds, yn);
+ if (yn == 0)
+ rb_num_zerodiv();
+
+ BARY_TRUNC(xds, xn);
+ if (xn == 0) {
+ BDIGITS_ZERO(qds, qn);
+ BDIGITS_ZERO(rds, rn);
+ return;
+ }
+
+ if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
+ MEMCPY(rds, xds, BDIGIT, xn);
+ BDIGITS_ZERO(rds+xn, rn-xn);
+ BDIGITS_ZERO(qds, qn);
+ }
+ else if (yn == 1) {
+ MEMCPY(qds, xds, BDIGIT, xn);
+ BDIGITS_ZERO(qds+xn, qn-xn);
+ rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
+ BDIGITS_ZERO(rds+1, rn-1);
+ }
+ else if (xn == 2 && yn == 2) {
+ BDIGIT_DBL x = bary2bdigitdbl(xds, 2);
+ BDIGIT_DBL y = bary2bdigitdbl(yds, 2);
+ BDIGIT_DBL q = x / y;
+ BDIGIT_DBL r = x % y;
+ qds[0] = BIGLO(q);
+ qds[1] = BIGLO(BIGDN(q));
+ BDIGITS_ZERO(qds+2, qn-2);
+ rds[0] = BIGLO(r);
+ rds[1] = BIGLO(BIGDN(r));
+ BDIGITS_ZERO(rds+2, rn-2);
+ }
+ else {
+ bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
}
}
+
+#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
-bignorm(x)
- VALUE x;
+rb_big_dump(VALUE x)
+{
+ dump_bignum(x);
+ return x;
+}
+#else
+#define ON_DEBUG(x)
+#endif
+
+static int
+bigzero_p(VALUE x)
+{
+ return bary_zero_p(BDIGITS(x), BIGNUM_LEN(x));
+}
+
+int
+rb_bigzero_p(VALUE x)
{
- unsigned int len = RBIGNUM(x)->len;
- USHORT *ds = BDIGITS(x);
+ return BIGZEROP(x);
+}
+
+int
+rb_cmpint(VALUE val, VALUE a, VALUE b)
+{
+ if (NIL_P(val)) {
+ rb_cmperr(a, b);
+ }
+ if (FIXNUM_P(val)) {
+ long l = FIX2LONG(val);
+ if (l > 0) return 1;
+ if (l < 0) return -1;
+ return 0;
+ }
+ if (RB_BIGNUM_TYPE_P(val)) {
+ if (BIGZEROP(val)) return 0;
+ if (BIGNUM_SIGN(val)) return 1;
+ return -1;
+ }
+ if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
+ if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
+ return 0;
+}
- while (len-- && !ds[len]) ;
- RBIGNUM(x)->len = ++len;
+#define BIGNUM_SET_LEN(b,l) \
+ ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
+ (void)(RBASIC(b)->flags = \
+ (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
+ ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
+ (void)(RBIGNUM(b)->as.heap.len = (l)))
- if (len*sizeof(USHORT) <= sizeof(VALUE)) {
- long num = 0;
- while (len--) {
- num = BIGUP(num) + ds[len];
+static void
+rb_big_realloc(VALUE big, size_t len)
+{
+ BDIGIT *ds;
+ if (RBASIC(big)->flags & BIGNUM_EMBED_FLAG) {
+ 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;
}
- if (num >= 0) {
- if (RBIGNUM(x)->sign) {
- if (POSFIXABLE(num)) return INT2FIX(num);
+ }
+ else {
+ if (len <= BIGNUM_EMBED_LEN_MAX) {
+ ds = RBIGNUM(big)->as.heap.digits;
+ 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));
+ if (ds) {
+ MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
+ xfree(ds);
}
- else if (NEGFIXABLE(-num)) return INT2FIX(-num);
}
+ else {
+ if (BIGNUM_LEN(big) == 0) {
+ RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
+ }
+ else {
+ REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT, len);
+ }
+ }
+ }
+}
+
+void
+rb_big_resize(VALUE big, size_t len)
+{
+ rb_big_realloc(big, len);
+ BIGNUM_SET_LEN(big, len);
+}
+
+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);
+ 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));
+ }
+ else {
+ RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
+ RBIGNUM(big)->as.heap.len = len;
+ }
+ OBJ_FREEZE(big);
+ return (VALUE)big;
+}
+
+VALUE
+rb_big_new(size_t len, int sign)
+{
+ return bignew(len, sign != 0);
+}
+
+VALUE
+rb_big_clone(VALUE x)
+{
+ size_t len = BIGNUM_LEN(x);
+ VALUE z = bignew_1(CLASS_OF(x), len, BIGNUM_SIGN(x));
+
+ MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, len);
+ return z;
+}
+
+static void
+big_extend_carry(VALUE x)
+{
+ rb_big_resize(x, BIGNUM_LEN(x)+1);
+ BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
+}
+
+/* modify a bignum by 2's complement */
+static void
+get2comp(VALUE x)
+{
+ long i = BIGNUM_LEN(x);
+ BDIGIT *ds = BDIGITS(x);
+
+ if (bary_2comp(ds, i)) {
+ big_extend_carry(x);
+ }
+}
+
+void
+rb_big_2comp(VALUE x) /* get 2's complement */
+{
+ get2comp(x);
+}
+
+static BDIGIT
+abs2twocomp(VALUE *xp, long *n_ret)
+{
+ VALUE x = *xp;
+ long n = BIGNUM_LEN(x);
+ BDIGIT *ds = BDIGITS(x);
+ BDIGIT hibits = 0;
+
+ BARY_TRUNC(ds, n);
+
+ if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
+ VALUE z = bignew_1(CLASS_OF(x), n, 0);
+ MEMCPY(BDIGITS(z), ds, BDIGIT, n);
+ bary_2comp(BDIGITS(z), n);
+ hibits = BDIGMAX;
+ *xp = z;
+ }
+ *n_ret = n;
+ return hibits;
+}
+
+static void
+twocomp2abs_bang(VALUE x, int hibits)
+{
+ BIGNUM_SET_SIGN(x, !hibits);
+ if (hibits) {
+ get2comp(x);
+ }
+}
+
+static inline VALUE
+bigtrunc(VALUE x)
+{
+ size_t len = BIGNUM_LEN(x);
+ BDIGIT *ds = BDIGITS(x);
+
+ if (len == 0) return x;
+ while (--len && !ds[len]);
+ if (BIGNUM_LEN(x) > len+1) {
+ rb_big_resize(x, len+1);
+ }
+ return x;
+}
+
+static inline VALUE
+bigfixize(VALUE x)
+{
+ size_t n = BIGNUM_LEN(x);
+ BDIGIT *ds = BDIGITS(x);
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ unsigned long u;
+#else
+ BDIGIT u;
+#endif
+
+ BARY_TRUNC(ds, n);
+
+ if (n == 0) return INT2FIX(0);
+
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (sizeof(long)/SIZEOF_BDIGIT < n)
+ goto return_big;
+ else {
+ int i = (int)n;
+ u = 0;
+ while (i--) {
+ u = (unsigned long)(BIGUP(u) + ds[i]);
+ }
+ }
+#else /* SIZEOF_BDIGIT >= SIZEOF_LONG */
+ if (1 < n)
+ goto return_big;
+ else
+ u = ds[0];
+#endif
+
+ if (BIGNUM_POSITIVE_P(x)) {
+ if (POSFIXABLE(u)) return LONG2FIX((long)u);
+ }
+ else {
+ if (u <= -FIXNUM_MIN) return LONG2FIX(-(long)u);
+ }
+
+ return_big:
+ rb_big_resize(x, n);
+ return x;
+}
+
+static VALUE
+bignorm(VALUE x)
+{
+ if (RB_BIGNUM_TYPE_P(x)) {
+ x = bigfixize(x);
}
return x;
}
VALUE
-big_norm(x)
- VALUE x;
+rb_big_norm(VALUE x)
{
- return bignorm(RBIGNUM(x));
+ return bignorm(x);
}
VALUE
-uint2big(n)
- unsigned long n;
+rb_uint2big(VALUE n)
{
- unsigned int i = 0;
- USHORT *digits;
- VALUE big;
+ long i;
+ VALUE big = bignew(bdigit_roomof(SIZEOF_VALUE), 1);
+ BDIGIT *digits = BDIGITS(big);
- i = 0;
- big = bignew(DIGSPERINT, 1);
- digits = BDIGITS(big);
- while (i < DIGSPERINT) {
- digits[i++] = BIGLO(n);
+#if SIZEOF_BDIGIT >= SIZEOF_VALUE
+ digits[0] = n;
+#else
+ for (i = 0; i < bdigit_roomof(SIZEOF_VALUE); i++) {
+ digits[i] = BIGLO(n);
n = BIGDN(n);
}
+#endif
- i = DIGSPERINT;
- while (i-- && !digits[i]) ;
- RBIGNUM(big)->len = i+1;
+ i = bdigit_roomof(SIZEOF_VALUE);
+ while (--i && !digits[i]) ;
+ BIGNUM_SET_LEN(big, i+1);
return big;
}
VALUE
-int2big(n)
- long n;
+rb_int2big(SIGNED_VALUE n)
{
long neg = 0;
+ VALUE u;
VALUE big;
if (n < 0) {
- n = -n;
+ u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */
neg = 1;
}
- big = uint2big(n);
+ else {
+ u = n;
+ }
+ big = rb_uint2big(u);
if (neg) {
- RBIGNUM(big)->sign = 0;
+ BIGNUM_SET_NEGATIVE_SIGN(big);
}
return big;
}
VALUE
-uint2inum(n)
- unsigned long n;
+rb_uint2inum(VALUE n)
{
- if (POSFIXABLE(n)) return INT2FIX(n);
- return uint2big(n);
+ if (POSFIXABLE(n)) return LONG2FIX(n);
+ return rb_uint2big(n);
}
VALUE
-int2inum(n)
- long n;
+rb_int2inum(SIGNED_VALUE n)
+{
+ if (FIXABLE(n)) return LONG2FIX(n);
+ return rb_int2big(n);
+}
+
+void
+rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
{
- if (FIXABLE(n)) return INT2FIX(n);
- return int2big(n);
+ rb_integer_pack(val, buf, num_longs, sizeof(long), 0,
+ INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP);
}
VALUE
-str2inum(str, base)
- char *str;
- int base;
+rb_big_unpack(unsigned long *buf, long num_longs)
{
- char sign = 1, c;
- unsigned long num;
- unsigned int len, blen = 1, i;
- VALUE z;
- USHORT *zds;
+ return rb_integer_unpack(buf, num_longs, sizeof(long), 0,
+ INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP);
+}
+
+/*
+ * Calculate the number of bytes to be required to represent
+ * the absolute value of the integer given as _val_.
+ *
+ * [val] an integer.
+ * [nlz_bits_ret] number of leading zero bits in the most significant byte is returned if not NULL.
+ *
+ * This function returns ((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)
+ * where val_numbits is the number of bits of abs(val).
+ * This function should not overflow.
+ *
+ * If nlz_bits_ret is not NULL,
+ * (return_value * CHAR_BIT - val_numbits) is stored in *nlz_bits_ret.
+ * In this case, 0 <= *nlz_bits_ret < CHAR_BIT.
+ *
+ */
+size_t
+rb_absint_size(VALUE val, int *nlz_bits_ret)
+{
+ BDIGIT *dp;
+ BDIGIT *de;
+ BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
+
+ int num_leading_zeros;
- while (ISSPACE(*str)) str++;
+ val = rb_to_int(val);
- if (*str == '+') {
- str++;
+ if (FIXNUM_P(val)) {
+ long v = FIX2LONG(val);
+ if (v < 0) {
+ v = -v;
+ }
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ fixbuf[0] = v;
+#else
+ {
+ int i;
+ for (i = 0; i < numberof(fixbuf); i++) {
+ fixbuf[i] = BIGLO(v);
+ v = BIGDN(v);
+ }
+ }
+#endif
+ dp = fixbuf;
+ de = fixbuf + numberof(fixbuf);
+ }
+ else {
+ dp = BDIGITS(val);
+ de = dp + BIGNUM_LEN(val);
+ }
+ while (dp < de && de[-1] == 0)
+ de--;
+ if (dp == de) {
+ if (nlz_bits_ret)
+ *nlz_bits_ret = 0;
+ return 0;
}
- else if (*str == '-') {
- str++;
- sign = 0;
+ num_leading_zeros = nlz(de[-1]);
+ if (nlz_bits_ret)
+ *nlz_bits_ret = num_leading_zeros % CHAR_BIT;
+ return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
+}
+
+static size_t
+absint_numwords_small(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
+{
+ size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
+ size_t div = val_numbits / word_numbits;
+ size_t mod = val_numbits % word_numbits;
+ size_t numwords;
+ size_t nlz_bits;
+ numwords = mod == 0 ? div : div + 1;
+ nlz_bits = mod == 0 ? 0 : word_numbits - mod;
+ *nlz_bits_ret = nlz_bits;
+ return numwords;
+}
+
+static size_t
+absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
+{
+ static const BDIGIT char_bit[1] = { CHAR_BIT };
+ BDIGIT numbytes_bary[bdigit_roomof(sizeof(numbytes))];
+ BDIGIT val_numbits_bary[bdigit_roomof(sizeof(numbytes) + 1)];
+ BDIGIT nlz_bits_in_msbyte_bary[1];
+ BDIGIT word_numbits_bary[bdigit_roomof(sizeof(word_numbits))];
+ BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
+ BDIGIT mod_bary[numberof(word_numbits_bary)];
+ BDIGIT one[1] = { 1 };
+ size_t nlz_bits;
+ size_t mod;
+ int sign;
+ size_t numwords;
+
+ nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
+
+ /*
+ * val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte
+ * div, mod = val_numbits.divmod(word_numbits)
+ * numwords = mod == 0 ? div : div + 1
+ * nlz_bits = mod == 0 ? 0 : word_numbits - mod
+ */
+
+ bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
+ INTEGER_PACK_NATIVE_BYTE_ORDER);
+ BARY_SHORT_MUL(val_numbits_bary, numbytes_bary, char_bit);
+ if (nlz_bits_in_msbyte)
+ BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
+ bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1, sizeof(word_numbits), 0,
+ INTEGER_PACK_NATIVE_BYTE_ORDER);
+ BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
+ if (BARY_ZERO_P(mod_bary)) {
+ nlz_bits = 0;
}
- if (base == 0) {
- if (*str == '0') {
+ else {
+ BARY_ADD(div_bary, div_bary, one);
+ bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1, sizeof(mod), 0,
+ INTEGER_PACK_NATIVE_BYTE_ORDER);
+ nlz_bits = word_numbits - mod;
+ }
+ sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1, sizeof(numwords), 0,
+ INTEGER_PACK_NATIVE_BYTE_ORDER);
+
+ if (sign == 2) {
+#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
+ *nlz_bits_ret = 0;
+#endif
+ return (size_t)-1;
+ }
+ *nlz_bits_ret = nlz_bits;
+ return numwords;
+}
+
+/*
+ * Calculate the number of words to be required to represent
+ * the absolute value of the integer given as _val_.
+ *
+ * [val] an integer.
+ * [word_numbits] number of bits in a word.
+ * [nlz_bits_ret] number of leading zero bits in the most significant word is returned if not NULL.
+ *
+ * This function returns ((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)
+ * where val_numbits is the number of bits of abs(val).
+ *
+ * This function can overflow.
+ * When overflow occur, (size_t)-1 is returned.
+ *
+ * If nlz_bits_ret is not NULL and overflow is not occur,
+ * (return_value * word_numbits - val_numbits) is stored in *nlz_bits_ret.
+ * In this case, 0 <= *nlz_bits_ret < word_numbits.
+ *
+ */
+size_t
+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;
+
+ if (word_numbits == 0)
+ return (size_t)-1;
+
+ numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
+
+ if (numbytes <= SIZE_MAX / CHAR_BIT) {
+ numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
+#ifdef DEBUG_INTEGER_PACK
+ {
+ size_t numwords0, nlz_bits0;
+ numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
+ assert(numwords0 == numwords);
+ assert(nlz_bits0 == nlz_bits);
+ }
+#endif
+ }
+ else {
+ numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
+ }
+ if (numwords == (size_t)-1)
+ return numwords;
+
+ if (nlz_bits_ret)
+ *nlz_bits_ret = nlz_bits;
+
+ return numwords;
+}
+
+/* Test abs(val) consists only a bit or not.
+ *
+ * Returns 1 if abs(val) == 1 << n for some n >= 0.
+ * Returns 0 otherwise.
+ *
+ * rb_absint_singlebit_p can be used to determine required buffer size
+ * for rb_integer_pack used with INTEGER_PACK_2COMP (two's complement).
+ *
+ * Following example calculates number of bits required to
+ * represent val in two's complement number, without sign bit.
+ *
+ * size_t size;
+ * int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
+ * size = rb_absint_numwords(val, 1, NULL)
+ * if (size == (size_t)-1) ...overflow...
+ * if (neg && rb_absint_singlebit_p(val))
+ * size--;
+ *
+ * Following example calculates number of bytes required to
+ * represent val in two's complement number, with sign bit.
+ *
+ * size_t size;
+ * int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
+ * int nlz_bits;
+ * size = rb_absint_size(val, &nlz_bits);
+ * if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
+ * size++;
+ */
+int
+rb_absint_singlebit_p(VALUE val)
+{
+ BDIGIT *dp;
+ BDIGIT *de;
+ BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
+ BDIGIT d;
+
+ val = rb_to_int(val);
+
+ if (FIXNUM_P(val)) {
+ long v = FIX2LONG(val);
+ if (v < 0) {
+ v = -v;
+ }
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ fixbuf[0] = v;
+#else
+ {
+ int i;
+ for (i = 0; i < numberof(fixbuf); i++) {
+ fixbuf[i] = BIGLO(v);
+ v = BIGDN(v);
+ }
+ }
+#endif
+ dp = fixbuf;
+ de = fixbuf + numberof(fixbuf);
+ }
+ else {
+ dp = BDIGITS(val);
+ de = dp + BIGNUM_LEN(val);
+ }
+ while (dp < de && de[-1] == 0)
+ de--;
+ while (dp < de && dp[0] == 0)
+ dp++;
+ if (dp == de) /* no bit set. */
+ return 0;
+ if (dp != de-1) /* two non-zero words. two bits set, at least. */
+ return 0;
+ d = *dp;
+ return POW2_P(d);
+}
+
+
+/*
+ * Export an integer into a buffer.
+ *
+ * This function fills the buffer specified by _words_ and _numwords_ as
+ * val in the format specified by _wordsize_, _nails_ and _flags_.
+ *
+ * [val] Fixnum, Bignum or another integer like object which has to_int method.
+ * [words] buffer to export abs(val).
+ * [numwords] the size of given buffer as number of words.
+ * [wordsize] the size of word as number of bytes.
+ * [nails] number of padding bits in a word.
+ * Most significant nails bits of each word are filled by zero.
+ * [flags] bitwise or of constants which name starts "INTEGER_PACK_".
+ *
+ * flags:
+ * [INTEGER_PACK_MSWORD_FIRST] Store the most significant word as the first word.
+ * [INTEGER_PACK_LSWORD_FIRST] Store the least significant word as the first word.
+ * [INTEGER_PACK_MSBYTE_FIRST] Store the most significant byte in a word as the first byte in the word.
+ * [INTEGER_PACK_LSBYTE_FIRST] Store the least significant byte in a word as the first byte in the word.
+ * [INTEGER_PACK_NATIVE_BYTE_ORDER] INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST corresponding to the host's endian.
+ * [INTEGER_PACK_2COMP] Use 2's complement representation.
+ * [INTEGER_PACK_LITTLE_ENDIAN] Same as INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
+ * [INTEGER_PACK_BIG_ENDIAN] Same as INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
+ * [INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION] Use generic implementation (for test and debug).
+ *
+ * This function fills the buffer specified by _words_
+ * as abs(val) if INTEGER_PACK_2COMP is not specified in _flags_.
+ * If INTEGER_PACK_2COMP is specified, 2's complement representation of val is
+ * filled in the buffer.
+ *
+ * This function returns the signedness and overflow condition.
+ * The overflow condition depends on INTEGER_PACK_2COMP.
+ *
+ * INTEGER_PACK_2COMP is not specified:
+ * -2 : negative overflow. val <= -2**(numwords*(wordsize*CHAR_BIT-nails))
+ * -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0
+ * 0 : zero. val == 0
+ * 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
+ * 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
+ *
+ * INTEGER_PACK_2COMP is specified:
+ * -2 : negative overflow. val < -2**(numwords*(wordsize*CHAR_BIT-nails))
+ * -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0
+ * 0 : zero. val == 0
+ * 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
+ * 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
+ *
+ * The value, -2**(numwords*(wordsize*CHAR_BIT-nails)), is representable
+ * in 2's complement representation but not representable in absolute value.
+ * So -1 is returned for the value if INTEGER_PACK_2COMP is specified
+ * but returns -2 if INTEGER_PACK_2COMP is not specified.
+ *
+ * The least significant words are filled in the buffer when overflow occur.
+ */
+
+int
+rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
+{
+ int sign;
+ BDIGIT *ds;
+ size_t num_bdigits;
+ BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
+
+ RB_GC_GUARD(val) = rb_to_int(val);
+
+ if (FIXNUM_P(val)) {
+ long v = FIX2LONG(val);
+ if (v < 0) {
+ sign = -1;
+ v = -v;
+ }
+ else {
+ sign = 1;
+ }
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ fixbuf[0] = v;
+#else
+ {
+ int i;
+ for (i = 0; i < numberof(fixbuf); i++) {
+ fixbuf[i] = BIGLO(v);
+ v = BIGDN(v);
+ }
+ }
+#endif
+ ds = fixbuf;
+ num_bdigits = numberof(fixbuf);
+ }
+ else {
+ sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
+ ds = BDIGITS(val);
+ num_bdigits = BIGNUM_LEN(val);
+ }
+
+ return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
+}
+
+/*
+ * Import an integer into a buffer.
+ *
+ * [words] buffer to import.
+ * [numwords] the size of given buffer as number of words.
+ * [wordsize] the size of word as number of bytes.
+ * [nails] number of padding bits in a word.
+ * Most significant nails bits of each word are ignored.
+ * [flags] bitwise or of constants which name starts "INTEGER_PACK_".
+ *
+ * flags:
+ * [INTEGER_PACK_MSWORD_FIRST] Interpret the first word as the most significant word.
+ * [INTEGER_PACK_LSWORD_FIRST] Interpret the first word as the least significant word.
+ * [INTEGER_PACK_MSBYTE_FIRST] Interpret the first byte in a word as the most significant byte in the word.
+ * [INTEGER_PACK_LSBYTE_FIRST] Interpret the first byte in a word as the least significant byte in the word.
+ * [INTEGER_PACK_NATIVE_BYTE_ORDER] INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST corresponding to the host's endian.
+ * [INTEGER_PACK_2COMP] Use 2's complement representation.
+ * [INTEGER_PACK_LITTLE_ENDIAN] Same as INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
+ * [INTEGER_PACK_BIG_ENDIAN] Same as INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
+ * [INTEGER_PACK_FORCE_BIGNUM] the result will be a Bignum
+ * even if it is representable as a Fixnum.
+ * [INTEGER_PACK_NEGATIVE] Returns non-positive value.
+ * (Returns non-negative value if not specified.)
+ * [INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION] Use generic implementation (for test and debug).
+ *
+ * This function returns the imported integer as Fixnum or Bignum.
+ *
+ * The range of the result value depends on INTEGER_PACK_2COMP and INTEGER_PACK_NEGATIVE.
+ *
+ * INTEGER_PACK_2COMP is not set:
+ * 0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails)) if !INTEGER_PACK_NEGATIVE
+ * -2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0 if INTEGER_PACK_NEGATIVE
+ *
+ * INTEGER_PACK_2COMP is set:
+ * -2**(numwords*(wordsize*CHAR_BIT-nails)-1) <= val <= 2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1 if !INTEGER_PACK_NEGATIVE
+ * -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1 if INTEGER_PACK_NEGATIVE
+ *
+ * INTEGER_PACK_2COMP without INTEGER_PACK_NEGATIVE means sign extension.
+ * INTEGER_PACK_2COMP with INTEGER_PACK_NEGATIVE mean assuming the higher bits are 1.
+ *
+ * Note that this function returns 0 when numwords is zero and
+ * INTEGER_PACK_2COMP is set but INTEGER_PACK_NEGATIVE is not set.
+ */
+
+VALUE
+rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
+{
+ VALUE val;
+ size_t num_bdigits;
+ int sign;
+ int nlp_bits;
+ BDIGIT *ds;
+ BDIGIT fixbuf[2] = { 0, 0 };
+
+ validate_integer_pack_format(numwords, wordsize, nails, flags,
+ INTEGER_PACK_MSWORD_FIRST|
+ INTEGER_PACK_LSWORD_FIRST|
+ INTEGER_PACK_MSBYTE_FIRST|
+ INTEGER_PACK_LSBYTE_FIRST|
+ INTEGER_PACK_NATIVE_BYTE_ORDER|
+ INTEGER_PACK_2COMP|
+ INTEGER_PACK_FORCE_BIGNUM|
+ INTEGER_PACK_NEGATIVE|
+ INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION);
+
+ num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
+
+ if (LONG_MAX-1 < num_bdigits)
+ rb_raise(rb_eArgError, "too big to unpack as an integer");
+ if (num_bdigits <= numberof(fixbuf) && !(flags & INTEGER_PACK_FORCE_BIGNUM)) {
+ val = Qfalse;
+ ds = fixbuf;
+ }
+ else {
+ val = bignew((long)num_bdigits, 0);
+ ds = BDIGITS(val);
+ }
+ sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
+
+ if (sign == -2) {
+ if (val) {
+ big_extend_carry(val);
+ }
+ else if (num_bdigits == numberof(fixbuf)) {
+ val = bignew((long)num_bdigits+1, 0);
+ MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
+ BDIGITS(val)[num_bdigits++] = 1;
+ }
+ else {
+ ds[num_bdigits++] = 1;
+ }
+ }
+
+ if (!val) {
+ BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
+ if (u == 0)
+ return LONG2FIX(0);
+ if (0 < sign && POSFIXABLE(u))
+ return LONG2FIX(u);
+ if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
+ NEGFIXABLE(-(BDIGIT_DBL_SIGNED)u))
+ return LONG2FIX(-(BDIGIT_DBL_SIGNED)u);
+ val = bignew((long)num_bdigits, 0 <= sign);
+ MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
+ }
+
+ if ((flags & INTEGER_PACK_FORCE_BIGNUM) && sign != 0 &&
+ bary_zero_p(BDIGITS(val), BIGNUM_LEN(val)))
+ sign = 0;
+ BIGNUM_SET_SIGN(val, 0 <= sign);
+
+ if (flags & INTEGER_PACK_FORCE_BIGNUM)
+ return bigtrunc(val);
+ return bignorm(val);
+}
+
+#define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
+
+NORETURN(static inline void invalid_radix(int base));
+NORETURN(static inline void invalid_integer(VALUE s));
+
+static inline int
+valid_radix_p(int base)
+{
+ return (1 < base && base <= 36);
+}
+
+static inline void
+invalid_radix(int base)
+{
+ rb_raise(rb_eArgError, "invalid radix %d", base);
+}
+
+static inline void
+invalid_integer(VALUE s)
+{
+ rb_raise(rb_eArgError, "invalid value for Integer(): %+"PRIsVALUE, s);
+}
+
+static int
+str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size_t *num_digits_p, ssize_t *len_p)
+{
+ char nondigit = 0;
+ size_t num_digits = 0;
+ const char *digits_start = str;
+ const char *digits_end = str;
+ ssize_t len = *len_p;
+
+ int c;
+
+ if (!len) {
+ *num_digits_p = 0;
+ *len_p = 0;
+ return TRUE;
+ }
+
+ if (badcheck && *str == '_') goto bad;
+
+ while ((c = *str++) != 0) {
+ if (c == '_') {
+ if (nondigit) {
+ if (badcheck) goto bad;
+ break;
+ }
+ nondigit = (char) c;
+ }
+ else if ((c = conv_digit(c)) < 0 || c >= base) {
+ break;
+ }
+ else {
+ nondigit = 0;
+ num_digits++;
+ digits_end = str;
+ }
+ if (len > 0 && !--len) break;
+ }
+ if (badcheck && nondigit) goto bad;
+ if (badcheck && len) {
+ str--;
+ while (*str && ISSPACE(*str)) {
str++;
- if (*str == 'x' || *str == 'X') {
- str++;
+ if (len > 0 && !--len) break;
+ }
+ if (len && *str) {
+ bad:
+ return FALSE;
+ }
+ }
+ *num_digits_p = num_digits;
+ *len_p = digits_end - digits_start;
+ return TRUE;
+}
+
+static VALUE
+str2big_poweroftwo(
+ int sign,
+ const char *digits_start,
+ const char *digits_end,
+ size_t num_digits,
+ int bits_per_digit)
+{
+ BDIGIT *dp;
+ BDIGIT_DBL dd;
+ int numbits;
+
+ size_t num_bdigits;
+ const char *p;
+ int c;
+ VALUE z;
+
+ num_bdigits = (num_digits / BITSPERDIG) * bits_per_digit + roomof((num_digits % BITSPERDIG) * bits_per_digit, BITSPERDIG);
+ z = bignew(num_bdigits, sign);
+ dp = BDIGITS(z);
+ dd = 0;
+ numbits = 0;
+ for (p = digits_end; digits_start < p; p--) {
+ if ((c = conv_digit(p[-1])) < 0)
+ continue;
+ dd |= (BDIGIT_DBL)c << numbits;
+ numbits += bits_per_digit;
+ if (BITSPERDIG <= numbits) {
+ *dp++ = BIGLO(dd);
+ dd = BIGDN(dd);
+ numbits -= BITSPERDIG;
+ }
+ }
+ if (numbits) {
+ *dp++ = BIGLO(dd);
+ }
+ assert((size_t)(dp - BDIGITS(z)) == num_bdigits);
+
+ return z;
+}
+
+static VALUE
+str2big_normal(
+ int sign,
+ const char *digits_start,
+ const char *digits_end,
+ size_t num_bdigits,
+ int base)
+{
+ size_t blen = 1;
+ BDIGIT *zds;
+ BDIGIT_DBL num;
+
+ size_t i;
+ const char *p;
+ int c;
+ VALUE z;
+
+ z = bignew(num_bdigits, sign);
+ zds = BDIGITS(z);
+ BDIGITS_ZERO(zds, num_bdigits);
+
+ for (p = digits_start; p < digits_end; p++) {
+ if ((c = conv_digit(*p)) < 0)
+ continue;
+ num = c;
+ i = 0;
+ for (;;) {
+ while (i<blen) {
+ num += (BDIGIT_DBL)zds[i]*base;
+ zds[i++] = BIGLO(num);
+ num = BIGDN(num);
+ }
+ if (num) {
+ blen++;
+ continue;
+ }
+ break;
+ }
+ assert(blen <= num_bdigits);
+ }
+
+ return z;
+}
+
+static VALUE
+str2big_karatsuba(
+ int sign,
+ const char *digits_start,
+ const char *digits_end,
+ size_t num_digits,
+ size_t num_bdigits,
+ int digits_per_bdigits_dbl,
+ int base)
+{
+ VALUE powerv;
+ size_t unit;
+ VALUE tmpuv = 0;
+ BDIGIT *uds, *vds, *tds;
+ BDIGIT_DBL dd;
+ BDIGIT_DBL current_base;
+ int m;
+ int power_level = 0;
+
+ size_t i;
+ const char *p;
+ int c;
+ VALUE z;
+
+ uds = ALLOCV_N(BDIGIT, tmpuv, 2*num_bdigits);
+ vds = uds + num_bdigits;
+
+ powerv = power_cache_get_power(base, power_level, NULL);
+
+ i = 0;
+ dd = 0;
+ current_base = 1;
+ m = digits_per_bdigits_dbl;
+ if (num_digits < (size_t)m)
+ m = (int)num_digits;
+ for (p = digits_end; digits_start < p; p--) {
+ if ((c = conv_digit(p[-1])) < 0)
+ continue;
+ dd = dd + c * current_base;
+ current_base *= base;
+ num_digits--;
+ m--;
+ if (m == 0) {
+ uds[i++] = BIGLO(dd);
+ uds[i++] = (BDIGIT)BIGDN(dd);
+ dd = 0;
+ m = digits_per_bdigits_dbl;
+ if (num_digits < (size_t)m)
+ m = (int)num_digits;
+ current_base = 1;
+ }
+ }
+ assert(i == num_bdigits);
+ for (unit = 2; unit < num_bdigits; unit *= 2) {
+ for (i = 0; i < num_bdigits; i += unit*2) {
+ if (2*unit <= num_bdigits - i) {
+ bary_mul(vds+i, unit*2, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
+ bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
+ }
+ else if (unit <= num_bdigits - i) {
+ bary_mul(vds+i, num_bdigits-i, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
+ bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
+ }
+ else {
+ MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
+ }
+ }
+ power_level++;
+ powerv = power_cache_get_power(base, power_level, NULL);
+ tds = vds;
+ vds = uds;
+ uds = tds;
+ }
+ BARY_TRUNC(uds, num_bdigits);
+ z = bignew(num_bdigits, sign);
+ MEMCPY(BDIGITS(z), uds, BDIGIT, num_bdigits);
+
+ if (tmpuv)
+ ALLOCV_END(tmpuv);
+
+ return z;
+}
+
+#ifdef USE_GMP
+static VALUE
+str2big_gmp(
+ int sign,
+ const char *digits_start,
+ const char *digits_end,
+ size_t num_digits,
+ size_t num_bdigits,
+ int base)
+{
+ const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
+ char *buf, *p;
+ const char *q;
+ VALUE tmps;
+ mpz_t mz;
+ VALUE z;
+ BDIGIT *zds;
+ size_t zn, count;
+
+ buf = ALLOCV_N(char, tmps, num_digits+1);
+ p = buf;
+ for (q = digits_start; q < digits_end; q++) {
+ if (conv_digit(*q) < 0)
+ continue;
+ *p++ = *q;
+ }
+ *p = '\0';
+
+ mpz_init(mz);
+ mpz_set_str(mz, buf, base);
+ zn = num_bdigits;
+ z = bignew(zn, sign);
+ zds = BDIGITS(z);
+ mpz_export(BDIGITS(z), &count, -1, sizeof(BDIGIT), 0, nails, mz);
+ BDIGITS_ZERO(zds+count, zn-count);
+ mpz_clear(mz);
+
+ if (tmps)
+ ALLOCV_END(tmps);
+
+ return z;
+}
+#endif
+
+/*
+ * Parse +str+ as Ruby Integer, i.e., underscores, 0d and 0b prefixes.
+ *
+ * str: pointer to the string to be parsed.
+ * should be NUL-terminated.
+ * base: base of conversion, must be 2..36, or -36..0.
+ * if +base+ > 0, the conversion is done according to the +base+
+ * and unmatched prefix is parsed as a part of the result if
+ * present.
+ * if +base+ <= 0, the conversion is done according to the
+ * prefix if present, in base <code>-base</code> if +base+ < -1,
+ * or in base 10.
+ * badcheck: if non-zero, +ArgumentError+ is raised when +str+ is not
+ * valid as an Integer. if zero, Fixnum 0 is returned in
+ * that case.
+ */
+VALUE
+rb_cstr_to_inum(const char *str, int base, int badcheck)
+{
+ char *end;
+ VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
+ if (NIL_P(ret)) {
+ if (badcheck) rb_invalid_str(str, "Integer()");
+ ret = INT2FIX(0);
+ }
+ return ret;
+}
+
+/*
+ * Parse +str+ as Ruby Integer, i.e., underscores, 0d and 0b prefixes.
+ *
+ * str: pointer to the string to be parsed.
+ * should be NUL-terminated if +len+ is negative.
+ * len: length of +str+ if >= 0. if +len+ is negative, +str+ should
+ * be NUL-terminated.
+ * endp: if non-NULL, the address after parsed part is stored. if
+ * NULL, Qnil is returned when +str+ is not valid as an Integer.
+ * ndigits: if non-NULL, the number of parsed digits is stored.
+ * base: see +rb_cstr_to_inum+
+ * flags: bitwise OR of below flags:
+ * RB_INT_PARSE_SIGN: allow preceding spaces and +/- sign
+ * RB_INT_PARSE_UNDERSCORE: allow an underscore between digits
+ * RB_INT_PARSE_PREFIX: allow preceding prefix
+ */
+
+VALUE
+rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
+ int base, int flags)
+{
+ const char *const s = str;
+ char sign = 1;
+ int c;
+ VALUE z = Qnil;
+
+ unsigned long val;
+ int ov;
+
+ const char *digits_start, *digits_end;
+ size_t num_digits = 0;
+ size_t num_bdigits;
+ const ssize_t len0 = len;
+ const int badcheck = !endp;
+
+#define ADV(n) do {\
+ if (len > 0 && len <= (n)) goto bad; \
+ str += (n); \
+ len -= (n); \
+ } while (0)
+#define ASSERT_LEN() do {\
+ assert(len != 0); \
+ if (len0 >= 0) assert(s + len0 == str + len); \
+ } while (0)
+
+ if (!str) {
+ bad:
+ if (endp) *endp = (char *)str;
+ if (ndigits) *ndigits = num_digits;
+ return z;
+ }
+ if (len && (flags & RB_INT_PARSE_SIGN)) {
+ while (ISSPACE(*str)) ADV(1);
+
+ if (str[0] == '+') {
+ ADV(1);
+ }
+ else if (str[0] == '-') {
+ ADV(1);
+ sign = 0;
+ }
+ ASSERT_LEN();
+ }
+ if (base <= 0) {
+ if (str[0] == '0' && len > 1) {
+ switch (str[1]) {
+ case 'x': case 'X':
base = 16;
- }
- else {
+ ADV(2);
+ break;
+ case 'b': case 'B':
+ base = 2;
+ ADV(2);
+ break;
+ case 'o': case 'O':
+ base = 8;
+ ADV(2);
+ break;
+ case 'd': case 'D':
+ base = 10;
+ ADV(2);
+ break;
+ default:
base = 8;
}
- if (*str == '\0') return INT2FIX(0);
+ }
+ else if (base < -1) {
+ base = -base;
}
else {
base = 10;
}
}
- if (base == 8) {
- while (str[0] == '0') str++;
- len = 3*strlen(str)*sizeof(char);
+ else if (len == 1 || !(flags & RB_INT_PARSE_PREFIX)) {
+ /* no prefix */
+ }
+ else if (base == 2) {
+ if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
+ ADV(2);
+ }
+ }
+ else if (base == 8) {
+ if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
+ ADV(2);
+ }
}
- else { /* base == 10 or 16 */
- if (base == 16 && str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
- str += 2;
+ else if (base == 10) {
+ if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
+ ADV(2);
+ }
+ }
+ else if (base == 16) {
+ if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
+ ADV(2);
}
- while (str[0] == '0') str++;
- len = 4*strlen(str)*sizeof(char);
+ }
+ if (!valid_radix_p(base)) {
+ invalid_radix(base);
+ }
+ if (!len) goto bad;
+ num_digits = str - s;
+ if (*str == '0' && len != 1) { /* squeeze preceding 0s */
+ int us = 0;
+ const char *end = len < 0 ? NULL : str + len;
+ ++num_digits;
+ while ((c = *++str) == '0' ||
+ ((flags & RB_INT_PARSE_UNDERSCORE) && c == '_')) {
+ if (c == '_') {
+ if (++us >= 2)
+ break;
+ }
+ else {
+ ++num_digits;
+ us = 0;
+ }
+ if (str == end) break;
+ }
+ if (!c || ISSPACE(c)) --str;
+ if (end) len = end - str;
+ ASSERT_LEN();
+ }
+ c = *str;
+ c = conv_digit(c);
+ if (c < 0 || c >= base) {
+ if (!badcheck && num_digits) z = INT2FIX(0);
+ goto bad;
}
- if (len <= (sizeof(VALUE)*CHAR_BIT)) {
- unsigned int val = strtoul((char*)str, 0, base);
+ if (ndigits) *ndigits = num_digits;
+ val = ruby_scan_digits(str, len, base, &num_digits, &ov);
+ if (!ov) {
+ const char *end = &str[num_digits];
+ if (num_digits > 0 && *end == '_' && (flags & RB_INT_PARSE_UNDERSCORE))
+ goto bigparse;
+ if (endp) *endp = (char *)end;
+ if (ndigits) *ndigits += num_digits;
+ if (badcheck) {
+ if (num_digits == 0) return Qnil; /* no number */
+ while (len < 0 ? *end : end < str + len) {
+ if (!ISSPACE(*end)) return Qnil; /* trailing garbage */
+ end++;
+ }
+ }
if (POSFIXABLE(val)) {
- if (sign) return INT2FIX(val);
+ if (sign) return LONG2FIX(val);
else {
long result = -(long)val;
- return INT2FIX(result);
+ return LONG2FIX(result);
}
}
else {
- VALUE big = uint2big(val);
- RBIGNUM(big)->sign = sign;
- return big;
+ VALUE big = rb_uint2big(val);
+ BIGNUM_SET_SIGN(big, sign);
+ return bignorm(big);
}
}
- len = (len/BITSPERDIG)+1;
- z = bignew(len, sign);
- zds = BDIGITS(z);
- for (i=len;i--;) zds[i]=0;
- while (c = *str++) {
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- c = c - '0';
- break;
- case 'a': case 'b': case 'c':
- case 'd': case 'e': case 'f':
- c = c - 'a' + 10;
- break;
- case 'A': case 'B': case 'C':
- case 'D': case 'E': case 'F':
- c = c - 'A' + 10;
- break;
- default:
- c = base;
- break;
- }
- if (c >= base) break;
- i = 0;
- num = c;
- for (;;) {
- while (i<blen) {
- num += zds[i]*base;
- zds[i++] = BIGLO(num);
- num = BIGDN(num);
- }
- if (num) {
- blen++;
- continue;
- }
- break;
- }
+ bigparse:
+ digits_start = str;
+ if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
+ goto bad;
+ if (endp) *endp = (char *)(str + len);
+ if (ndigits) *ndigits += num_digits;
+ digits_end = digits_start + len;
+
+ if (POW2_P(base)) {
+ z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
+ bit_length(base-1));
}
+ else {
+ int digits_per_bdigits_dbl;
+ maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
+ num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
+
+#ifdef USE_GMP
+ if (GMP_STR2BIG_DIGITS < num_bdigits) {
+ z = str2big_gmp(sign, digits_start, digits_end, num_digits,
+ num_bdigits, base);
+ }
+ else
+#endif
+ if (num_bdigits < KARATSUBA_MUL_DIGITS) {
+ z = str2big_normal(sign, digits_start, digits_end,
+ num_bdigits, base);
+ }
+ else {
+ z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
+ num_bdigits, digits_per_bdigits_dbl, base);
+ }
+ }
+
return bignorm(z);
}
-static char hexmap[] = "0123456789abcdef";
VALUE
-big2str(x, base)
- VALUE x;
- int base;
+rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
{
- VALUE t;
- USHORT *ds;
- unsigned int i, j, hbase;
- VALUE ss;
- char *s, c;
+ return rb_int_parse_cstr(str, len, endp, NULL, base,
+ RB_INT_PARSE_DEFAULT);
+}
- if (FIXNUM_P(x)) {
- return fix2str(x, base);
+VALUE
+rb_str_to_inum(VALUE str, int base, int badcheck)
+{
+ VALUE ret;
+ const char *s;
+ long len;
+ char *end;
+
+ StringValue(str);
+ rb_must_asciicompat(str);
+ 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);
}
- i = RBIGNUM(x)->len;
- if (i == 0) return str_new2("0");
- if (base == 10) {
- j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i*241L)/800+2;
- hbase = 10000;
+ return ret;
+}
+
+VALUE
+rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
+{
+ int positive_p = 1;
+ const char *s, *str;
+ const char *digits_start, *digits_end;
+ size_t num_digits;
+ ssize_t len;
+ VALUE z;
+
+ if (!valid_radix_p(base) || !POW2_P(base)) {
+ invalid_radix(base);
}
- else if (base == 16) {
- j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i)/4+2;
- hbase = 0x10000;
+
+ rb_must_asciicompat(arg);
+ s = str = StringValueCStr(arg);
+ len = RSTRING_LEN(arg);
+ if (*str == '-') {
+ len--;
+ str++;
+ positive_p = 0;
}
- else if (base == 8) {
- j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i)+2;
- hbase = 010000;
+
+ digits_start = str;
+ if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
+ invalid_integer(arg);
+ digits_end = digits_start + len;
+
+ z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
+ bit_length(base-1));
+
+ RB_GC_GUARD(arg);
+
+ return bignorm(z);
+}
+
+VALUE
+rb_str2big_normal(VALUE arg, int base, int badcheck)
+{
+ int positive_p = 1;
+ const char *s, *str;
+ const char *digits_start, *digits_end;
+ size_t num_digits;
+ ssize_t len;
+ VALUE z;
+
+ int digits_per_bdigits_dbl;
+ size_t num_bdigits;
+
+ if (!valid_radix_p(base)) {
+ invalid_radix(base);
}
- else if (base == 2) {
- j = (sizeof(USHORT)*CHAR_BIT*i)+2;
- hbase = 020;
+
+ rb_must_asciicompat(arg);
+ s = str = StringValuePtr(arg);
+ len = RSTRING_LEN(arg);
+ if (len > 0 && *str == '-') {
+ len--;
+ str++;
+ positive_p = 0;
+ }
+
+ digits_start = str;
+ if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
+ invalid_integer(arg);
+ digits_end = digits_start + len;
+
+ maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
+ num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
+
+ z = str2big_normal(positive_p, digits_start, digits_end,
+ num_bdigits, base);
+
+ RB_GC_GUARD(arg);
+
+ return bignorm(z);
+}
+
+VALUE
+rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
+{
+ int positive_p = 1;
+ const char *s, *str;
+ const char *digits_start, *digits_end;
+ size_t num_digits;
+ ssize_t len;
+ VALUE z;
+
+ int digits_per_bdigits_dbl;
+ size_t num_bdigits;
+
+ if (!valid_radix_p(base)) {
+ invalid_radix(base);
+ }
+
+ rb_must_asciicompat(arg);
+ s = str = StringValuePtr(arg);
+ len = RSTRING_LEN(arg);
+ if (len > 0 && *str == '-') {
+ len--;
+ str++;
+ positive_p = 0;
+ }
+
+ digits_start = str;
+ if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
+ invalid_integer(arg);
+ digits_end = digits_start + len;
+
+ maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
+ num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
+
+ z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
+ num_bdigits, digits_per_bdigits_dbl, base);
+
+ RB_GC_GUARD(arg);
+
+ return bignorm(z);
+}
+
+#ifdef USE_GMP
+VALUE
+rb_str2big_gmp(VALUE arg, int base, int badcheck)
+{
+ int positive_p = 1;
+ const char *s, *str;
+ const char *digits_start, *digits_end;
+ size_t num_digits;
+ ssize_t len;
+ VALUE z;
+
+ int digits_per_bdigits_dbl;
+ size_t num_bdigits;
+
+ if (!valid_radix_p(base)) {
+ invalid_radix(base);
+ }
+
+ rb_must_asciicompat(arg);
+ s = str = StringValuePtr(arg);
+ len = RSTRING_LEN(arg);
+ if (len > 0 && *str == '-') {
+ len--;
+ str++;
+ positive_p = 0;
+ }
+
+ digits_start = str;
+ if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
+ invalid_integer(arg);
+ digits_end = digits_start + len;
+
+ maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
+ num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
+
+ z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
+
+ RB_GC_GUARD(arg);
+
+ return bignorm(z);
+}
+#endif
+
+#if HAVE_LONG_LONG
+
+static VALUE
+rb_ull2big(unsigned LONG_LONG n)
+{
+ long i;
+ VALUE big = bignew(bdigit_roomof(SIZEOF_LONG_LONG), 1);
+ BDIGIT *digits = BDIGITS(big);
+
+#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
+ digits[0] = n;
+#else
+ for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
+ digits[i] = BIGLO(n);
+ n = BIGDN(n);
+ }
+#endif
+
+ i = bdigit_roomof(SIZEOF_LONG_LONG);
+ while (i-- && !digits[i]) ;
+ BIGNUM_SET_LEN(big, i+1);
+ return big;
+}
+
+static VALUE
+rb_ll2big(LONG_LONG n)
+{
+ long neg = 0;
+ unsigned LONG_LONG u;
+ VALUE big;
+
+ if (n < 0) {
+ u = 1 + (unsigned LONG_LONG)(-(n + 1)); /* u = -n avoiding overflow */
+ neg = 1;
+ }
+ else {
+ u = n;
+ }
+ big = rb_ull2big(u);
+ if (neg) {
+ BIGNUM_SET_NEGATIVE_SIGN(big);
+ }
+ return big;
+}
+
+VALUE
+rb_ull2inum(unsigned LONG_LONG n)
+{
+ if (POSFIXABLE(n)) return LONG2FIX(n);
+ return rb_ull2big(n);
+}
+
+VALUE
+rb_ll2inum(LONG_LONG n)
+{
+ if (FIXABLE(n)) return LONG2FIX(n);
+ return rb_ll2big(n);
+}
+
+#endif /* HAVE_LONG_LONG */
+
+#ifdef HAVE_INT128_T
+static VALUE
+rb_uint128t2big(uint128_t n)
+{
+ long i;
+ VALUE big = bignew(bdigit_roomof(SIZEOF_INT128_T), 1);
+ BDIGIT *digits = BDIGITS(big);
+
+ for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
+ digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
+ }
+
+ i = bdigit_roomof(SIZEOF_INT128_T);
+ while (i-- && !digits[i]) ;
+ BIGNUM_SET_LEN(big, i+1);
+ return big;
+}
+
+VALUE
+rb_int128t2big(int128_t n)
+{
+ int neg = 0;
+ uint128_t u;
+ VALUE big;
+
+ if (n < 0) {
+ u = 1 + (uint128_t)(-(n + 1)); /* u = -n avoiding overflow */
+ neg = 1;
+ }
+ else {
+ u = n;
+ }
+ big = rb_uint128t2big(u);
+ if (neg) {
+ BIGNUM_SET_NEGATIVE_SIGN(big);
+ }
+ return big;
+}
+#endif
+
+VALUE
+rb_cstr2inum(const char *str, int base)
+{
+ return rb_cstr_to_inum(str, base, base==0);
+}
+
+VALUE
+rb_str2inum(VALUE str, int base)
+{
+ return rb_str_to_inum(str, base, base==0);
+}
+
+static VALUE
+big_shift3(VALUE x, int lshift_p, size_t shift_numdigits, int shift_numbits)
+{
+ BDIGIT *xds, *zds;
+ long s1;
+ int s2;
+ VALUE z;
+ long xn;
+
+ if (lshift_p) {
+ if (LONG_MAX < shift_numdigits) {
+ rb_raise(rb_eArgError, "too big number");
+ }
+ s1 = shift_numdigits;
+ s2 = shift_numbits;
+ xn = BIGNUM_LEN(x);
+ z = bignew(xn+s1+1, BIGNUM_SIGN(x));
+ zds = BDIGITS(z);
+ BDIGITS_ZERO(zds, s1);
+ xds = BDIGITS(x);
+ zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
+ }
+ else {
+ long zn;
+ BDIGIT hibitsx;
+ if (LONG_MAX < shift_numdigits || (size_t)BIGNUM_LEN(x) <= shift_numdigits) {
+ if (BIGNUM_POSITIVE_P(x) ||
+ bary_zero_p(BDIGITS(x), BIGNUM_LEN(x)))
+ return INT2FIX(0);
+ else
+ return INT2FIX(-1);
+ }
+ s1 = shift_numdigits;
+ s2 = shift_numbits;
+ hibitsx = abs2twocomp(&x, &xn);
+ xds = BDIGITS(x);
+ if (xn <= s1) {
+ return hibitsx ? INT2FIX(-1) : INT2FIX(0);
+ }
+ zn = xn - s1;
+ z = bignew(zn, 0);
+ zds = BDIGITS(z);
+ bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ? BDIGMAX : 0);
+ twocomp2abs_bang(z, hibitsx != 0);
+ }
+ RB_GC_GUARD(x);
+ return z;
+}
+
+static VALUE
+big_shift2(VALUE x, int lshift_p, VALUE y)
+{
+ int sign;
+ size_t lens[2];
+ size_t shift_numdigits;
+ int shift_numbits;
+
+ assert(POW2_P(CHAR_BIT));
+ assert(POW2_P(BITSPERDIG));
+
+ if (BIGZEROP(x))
+ return INT2FIX(0);
+ sign = rb_integer_pack(y, lens, numberof(lens), sizeof(size_t), 0,
+ INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
+ if (sign < 0) {
+ lshift_p = !lshift_p;
+ sign = -sign;
+ }
+ if (lshift_p) {
+ if (1 < sign || CHAR_BIT <= lens[1])
+ rb_raise(rb_eRangeError, "shift width too big");
}
else {
- j = 0;
- hbase = 0;
- Fail("bignum cannot treat base %d", base);
+ if (1 < sign || CHAR_BIT <= lens[1])
+ return BIGNUM_POSITIVE_P(x) ? INT2FIX(0) : INT2FIX(-1);
}
+ shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
+ shift_numdigits = (lens[0] >> bit_length(BITSPERDIG-1)) |
+ (lens[1] << (CHAR_BIT*SIZEOF_SIZE_T - bit_length(BITSPERDIG-1)));
+ return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
+}
- t = big_clone(x);
- ds = BDIGITS(t);
- ss = str_new(0, j);
- s = RSTRING(ss)->ptr;
+static VALUE
+big_lshift(VALUE x, unsigned long shift)
+{
+ long s1 = shift/BITSPERDIG;
+ int s2 = (int)(shift%BITSPERDIG);
+ return big_shift3(x, 1, s1, s2);
+}
- s[0] = RBIGNUM(x)->sign ? '+' : '-';
- while (i && j) {
- int k = i;
- unsigned long num = 0;
- while (k--) {
- num = BIGUP(num) + ds[k];
- ds[k] = num / hbase;
- num %= hbase;
+static VALUE
+big_rshift(VALUE x, unsigned long shift)
+{
+ long s1 = shift/BITSPERDIG;
+ int s2 = (int)(shift%BITSPERDIG);
+ return big_shift3(x, 0, s1, s2);
+}
+
+#define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
+
+static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
+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;
}
- if (ds[i-1] == 0) i--;
- k = 4;
- while (k--) {
- c = num % base;
- s[--j] = hexmap[(int)c];
- num /= base;
- if (i == 0 && num == 0) break;
+ }
+}
+
+static inline VALUE
+power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
+{
+ /*
+ * MAX_BASE36_POWER_TABLE_ENTRIES is big enough to that
+ * base36_power_cache[base][MAX_BASE36_POWER_TABLE_ENTRIES-1] fills whole memory.
+ * So MAX_BASE36_POWER_TABLE_ENTRIES <= power_level is not possible to calculate.
+ *
+ * number-of-bytes =
+ * log256(base36_power_cache[base][MAX_BASE36_POWER_TABLE_ENTRIES-1]) =
+ * log256(maxpow_in_bdigit_dbl(base)**(2**(MAX_BASE36_POWER_TABLE_ENTRIES-1))) =
+ * log256(maxpow_in_bdigit_dbl(base)**(2**(SIZEOF_SIZE_T*CHAR_BIT))) =
+ * (2**(SIZEOF_SIZE_T*CHAR_BIT))*log256(maxpow_in_bdigit_dbl(base)) =
+ * (256**SIZEOF_SIZE_T)*log256(maxpow_in_bdigit_dbl(base)) >
+ * (256**SIZEOF_SIZE_T)*(sizeof(BDIGIT_DBL)-1) >
+ * 256**SIZEOF_SIZE_T
+ */
+ 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;
+ size_t numdigits;
+ if (power_level == 0) {
+ int numdigits0;
+ BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
+ power = bignew(2, 1);
+ bdigitdbl2bary(BDIGITS(power), 2, dd);
+ numdigits = numdigits0;
+ }
+ else {
+ power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
+ numdigits *= 2;
+ }
+ rb_obj_hide(power);
+ base36_power_cache[base - 2][power_level] = power;
+ base36_numdigits_cache[base - 2][power_level] = numdigits;
+ rb_gc_register_mark_object(power);
+ }
+ if (numdigits_ret)
+ *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
+ return base36_power_cache[base - 2][power_level];
+}
+
+struct big2str_struct {
+ int negative;
+ int base;
+ BDIGIT_DBL hbase2;
+ int hbase2_numdigits;
+ VALUE result;
+ char *ptr;
+};
+
+static void
+big2str_alloc(struct big2str_struct *b2s, size_t len)
+{
+ if (LONG_MAX-1 < len)
+ rb_raise(rb_eArgError, "too big number");
+ b2s->result = rb_usascii_str_new(0, (long)(len + 1)); /* plus one for sign */
+ b2s->ptr = RSTRING_PTR(b2s->result);
+ if (b2s->negative)
+ *b2s->ptr++ = '-';
+}
+
+static void
+big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t taillen)
+{
+ size_t j;
+ BDIGIT_DBL num;
+ char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
+ int beginning = !b2s->ptr;
+ size_t len = 0;
+
+ assert(xn <= 2);
+ num = bary2bdigitdbl(xds, xn);
+
+ if (beginning) {
+ if (num == 0)
+ return;
+ p = buf;
+ j = sizeof(buf);
+ do {
+ BDIGIT_DBL idx = num % b2s->base;
+ num /= b2s->base;
+ p[--j] = ruby_digitmap[idx];
+ } while (num);
+ len = sizeof(buf) - j;
+ big2str_alloc(b2s, len + taillen);
+ MEMCPY(b2s->ptr, buf + j, char, len);
+ }
+ else {
+ p = b2s->ptr;
+ j = b2s->hbase2_numdigits;
+ do {
+ BDIGIT_DBL idx = num % b2s->base;
+ num /= b2s->base;
+ p[--j] = ruby_digitmap[idx];
+ } while (j);
+ len = b2s->hbase2_numdigits;
+ }
+ b2s->ptr += len;
+}
+
+static void
+big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn,
+ int power_level, size_t taillen)
+{
+ VALUE b;
+ size_t half_numdigits, lower_numdigits;
+ int lower_power_level;
+ size_t bn;
+ const BDIGIT *bds;
+ size_t len;
+
+ /*
+ * Precondition:
+ * abs(x) < maxpow**(2**power_level)
+ * where
+ * maxpow = maxpow_in_bdigit_dbl(base, &numdigits)
+ *
+ * This function generates sequence of zeros, and then stringized abs(x) into b2s->ptr.
+ *
+ * b2s->ptr can be NULL.
+ * It is allocated when the first character is generated via big2str_alloc.
+ *
+ * The prefix zeros should be generated if and only if b2s->ptr is not NULL.
+ * When the zeros are generated, the zeros and abs(x) consists
+ * numdigits*(2**power_level) characters at total.
+ *
+ * Note:
+ * power_cache_get_power(base, power_level, &len) may not be cached yet. It should not be called.
+ * power_cache_get_power(base, power_level-1, &len) should be cached already if 0 <= power_level-1.
+ */
+
+ if (xn == 0 || bary_zero_p(xds, xn)) {
+ if (b2s->ptr) {
+ /* When x is zero, power_cache_get_power(base, power_level) should be cached already. */
+ power_cache_get_power(b2s->base, power_level, &len);
+ memset(b2s->ptr, '0', len);
+ b2s->ptr += len;
}
+ return;
+ }
+
+ if (power_level == 0) {
+ big2str_2bdigits(b2s, xds, xn, taillen);
+ return;
+ }
+
+ lower_power_level = power_level-1;
+ b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
+ bn = BIGNUM_LEN(b);
+ bds = BDIGITS(b);
+
+ half_numdigits = lower_numdigits;
+
+ while (0 < lower_power_level &&
+ (xn < bn ||
+ (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
+ lower_power_level--;
+ b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
+ bn = BIGNUM_LEN(b);
+ bds = BDIGITS(b);
}
- while (s[j] == '0') j++;
- RSTRING(ss)->len -= RBIGNUM(x)->sign?j:j-1;
- memmove(RBIGNUM(x)->sign?s:s+1, s+j, RSTRING(ss)->len);
- s[RSTRING(ss)->len] = '\0';
- return ss;
+ if (lower_power_level == 0 &&
+ (xn < bn ||
+ (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
+ if (b2s->ptr) {
+ len = half_numdigits * 2 - lower_numdigits;
+ memset(b2s->ptr, '0', len);
+ b2s->ptr += len;
+ }
+ big2str_2bdigits(b2s, xds, xn, taillen);
+ }
+ else {
+ BDIGIT *qds, *rds;
+ size_t qn, rn;
+ BDIGIT *tds;
+ int shift;
+
+ if (lower_power_level != power_level-1 && b2s->ptr) {
+ len = (half_numdigits - lower_numdigits) * 2;
+ memset(b2s->ptr, '0', len);
+ b2s->ptr += len;
+ }
+
+ shift = nlz(bds[bn-1]);
+
+ qn = xn + BIGDIVREM_EXTRA_WORDS;
+
+ if (shift == 0) {
+ /* bigdivrem_restoring will not modify y.
+ * So use bds directly. */
+ tds = (BDIGIT *)bds;
+ xds[xn] = 0;
+ }
+ else {
+ /* bigdivrem_restoring will modify y.
+ * So use temporary buffer. */
+ tds = xds + qn;
+ assert(qn + bn <= xn + wn);
+ bary_small_lshift(tds, bds, bn, shift);
+ xds[xn] = bary_small_lshift(xds, xds, xn, shift);
+ }
+
+ bigdivrem_restoring(xds, qn, tds, bn);
+
+ rds = xds;
+ rn = bn;
+
+ qds = xds + bn;
+ qn = qn - bn;
+
+ if (shift) {
+ bary_small_rshift(rds, rds, rn, shift, 0);
+ }
+
+ BARY_TRUNC(qds, qn);
+ assert(qn <= bn);
+ big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
+ BARY_TRUNC(rds, rn);
+ big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
+ }
}
static VALUE
-big_to_s(x)
- VALUE x;
+big2str_base_poweroftwo(VALUE x, int base)
{
- return big2str(x, 10);
+ int word_numbits = ffs(base) - 1;
+ size_t numwords;
+ VALUE result;
+ char *ptr;
+ numwords = rb_absint_numwords(x, word_numbits, NULL);
+ if (BIGNUM_NEGATIVE_P(x)) {
+ if (LONG_MAX-1 < numwords)
+ rb_raise(rb_eArgError, "too big number");
+ result = rb_usascii_str_new(0, 1+numwords);
+ ptr = RSTRING_PTR(result);
+ *ptr++ = BIGNUM_POSITIVE_P(x) ? '+' : '-';
+ }
+ else {
+ if (LONG_MAX < numwords)
+ rb_raise(rb_eArgError, "too big number");
+ result = rb_usascii_str_new(0, numwords);
+ ptr = RSTRING_PTR(result);
+ }
+ rb_integer_pack(x, ptr, numwords, 1, CHAR_BIT-word_numbits,
+ INTEGER_PACK_BIG_ENDIAN);
+ while (0 < numwords) {
+ *ptr = ruby_digitmap[*(unsigned char *)ptr];
+ ptr++;
+ numwords--;
+ }
+ return result;
}
-unsigned long
-big2ulong(x)
- VALUE x;
+VALUE
+rb_big2str_poweroftwo(VALUE x, int base)
{
+ return big2str_base_poweroftwo(x, base);
+}
+
+static VALUE
+big2str_generic(VALUE x, int base)
+{
+ BDIGIT *xds;
+ size_t xn;
+ struct big2str_struct b2s_data;
+ int power_level;
+ VALUE power;
+
+ xds = BDIGITS(x);
+ xn = BIGNUM_LEN(x);
+ BARY_TRUNC(xds, xn);
+
+ if (xn == 0) {
+ return rb_usascii_str_new2("0");
+ }
+
+ if (!valid_radix_p(base))
+ invalid_radix(base);
+
+ if (xn >= LONG_MAX/BITSPERDIG) {
+ rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
+ }
+
+ power_level = 0;
+ power = power_cache_get_power(base, power_level, NULL);
+ while (power_level < MAX_BASE36_POWER_TABLE_ENTRIES &&
+ (size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
+ power_level++;
+ power = power_cache_get_power(base, power_level, NULL);
+ }
+ assert(power_level != MAX_BASE36_POWER_TABLE_ENTRIES);
+
+ if ((size_t)BIGNUM_LEN(power) <= xn) {
+ /*
+ * This increment guarantees x < power_cache_get_power(base, power_level)
+ * without invoking it actually.
+ * (power_cache_get_power(base, power_level) can be slow and not used
+ * in big2str_karatsuba.)
+ *
+ * Although it is possible that x < power_cache_get_power(base, power_level-1),
+ * it is no problem because big2str_karatsuba checks it and
+ * doesn't affect the result when b2s_data.ptr is NULL.
+ */
+ power_level++;
+ }
+
+ b2s_data.negative = BIGNUM_NEGATIVE_P(x);
+ b2s_data.base = base;
+ b2s_data.hbase2 = maxpow_in_bdigit_dbl(base, &b2s_data.hbase2_numdigits);
+
+ b2s_data.result = Qnil;
+ b2s_data.ptr = NULL;
+
+ if (power_level == 0) {
+ big2str_2bdigits(&b2s_data, xds, xn, 0);
+ }
+ else {
+ VALUE tmpw = 0;
+ BDIGIT *wds;
+ size_t wn;
+ wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
+ wds = ALLOCV_N(BDIGIT, tmpw, xn + wn);
+ MEMCPY(wds, xds, BDIGIT, xn);
+ big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
+ if (tmpw)
+ ALLOCV_END(tmpw);
+ }
+ RB_GC_GUARD(x);
+
+ *b2s_data.ptr = '\0';
+ rb_str_resize(b2s_data.result, (long)(b2s_data.ptr - RSTRING_PTR(b2s_data.result)));
+
+ RB_GC_GUARD(x);
+ return b2s_data.result;
+}
+
+VALUE
+rb_big2str_generic(VALUE x, int base)
+{
+ return big2str_generic(x, base);
+}
+
+#ifdef USE_GMP
+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;
+ BDIGIT *xds = BDIGITS(x);
+ size_t xn = BIGNUM_LEN(x);
+
+ mpz_init(mx);
+ mpz_import(mx, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+
+ size = mpz_sizeinbase(mx, base);
+
+ if (BIGNUM_NEGATIVE_P(x)) {
+ mpz_neg(mx, mx);
+ str = rb_usascii_str_new(0, size+1);
+ }
+ else {
+ str = rb_usascii_str_new(0, size);
+ }
+ mpz_get_str(RSTRING_PTR(str), base, mx);
+ mpz_clear(mx);
+
+ if (RSTRING_PTR(str)[RSTRING_LEN(str)-1] == '\0') {
+ rb_str_set_len(str, RSTRING_LEN(str)-1);
+ }
+
+ RB_GC_GUARD(x);
+ return str;
+}
+
+VALUE
+rb_big2str_gmp(VALUE x, int base)
+{
+ return big2str_gmp(x, base);
+}
+#endif
+
+static VALUE
+rb_big2str1(VALUE x, int base)
+{
+ BDIGIT *xds;
+ size_t xn;
+
+ if (FIXNUM_P(x)) {
+ return rb_fix2str(x, base);
+ }
+
+ bigtrunc(x);
+ xds = BDIGITS(x);
+ xn = BIGNUM_LEN(x);
+ BARY_TRUNC(xds, xn);
+
+ if (xn == 0) {
+ return rb_usascii_str_new2("0");
+ }
+
+ if (!valid_radix_p(base))
+ invalid_radix(base);
+
+ if (xn >= LONG_MAX/BITSPERDIG) {
+ rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
+ }
+
+ if (POW2_P(base)) {
+ /* base == 2 || base == 4 || base == 8 || base == 16 || base == 32 */
+ return big2str_base_poweroftwo(x, base);
+ }
+
+#ifdef USE_GMP
+ if (GMP_BIG2STR_DIGITS < xn) {
+ return big2str_gmp(x, base);
+ }
+#endif
+
+ return big2str_generic(x, base);
+}
+
+VALUE
+rb_big2str(VALUE x, int base)
+{
+ return rb_big2str1(x, base);
+}
+
+static unsigned long
+big2ulong(VALUE x, const char *type)
+{
+ size_t len = BIGNUM_LEN(x);
unsigned long num;
- unsigned int len = RBIGNUM(x)->len;
- USHORT *ds;
+ BDIGIT *ds;
- if (len > sizeof(long)/sizeof(USHORT))
- ArgError("bignum too big to convert into `uint'");
+ if (len == 0)
+ return 0;
+ if (BIGSIZE(x) > sizeof(long)) {
+ rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
+ }
ds = BDIGITS(x);
+#if SIZEOF_LONG <= SIZEOF_BDIGIT
+ num = (unsigned long)ds[0];
+#else
num = 0;
while (len--) {
- num = BIGUP(num);
- num += ds[len];
+ num <<= BITSPERDIG;
+ num += (unsigned long)ds[len]; /* overflow is already checked */
}
+#endif
return num;
}
+unsigned long
+rb_big2ulong(VALUE x)
+{
+ unsigned long num = big2ulong(x, "unsigned long");
+
+ if (BIGNUM_POSITIVE_P(x)) {
+ return num;
+ }
+ else {
+ if (num <= 1+(unsigned long)(-(LONG_MIN+1)))
+ return -(long)(num-1)-1;
+ }
+ rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
+}
+
long
-big2long(x)
- VALUE x;
+rb_big2long(VALUE x)
{
- unsigned long num = big2ulong(x);
+ unsigned long num = big2ulong(x, "long");
- if ((long)num < 0) {
- ArgError("bignum too big to convert into `int'");
+ if (BIGNUM_POSITIVE_P(x)) {
+ if (num <= LONG_MAX)
+ return num;
}
- if (!RBIGNUM(x)->sign) return -num;
+ else {
+ if (num <= 1+(unsigned long)(-(LONG_MIN+1)))
+ return -(long)(num-1)-1;
+ }
+ rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
+}
+
+#if HAVE_LONG_LONG
+
+static unsigned LONG_LONG
+big2ull(VALUE x, const char *type)
+{
+ size_t len = BIGNUM_LEN(x);
+ unsigned LONG_LONG num;
+ BDIGIT *ds = BDIGITS(x);
+
+ if (len == 0)
+ return 0;
+ if (BIGSIZE(x) > SIZEOF_LONG_LONG)
+ rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
+#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
+ num = (unsigned LONG_LONG)ds[0];
+#else
+ num = 0;
+ while (len--) {
+ num = BIGUP(num);
+ num += ds[len];
+ }
+#endif
return num;
}
-VALUE
-big_to_i(x)
- VALUE x;
+unsigned LONG_LONG
+rb_big2ull(VALUE x)
{
- return bignorm(x);
+ unsigned LONG_LONG num = big2ull(x, "unsigned long long");
+
+ if (BIGNUM_POSITIVE_P(x)) {
+ return num;
+ }
+ else {
+ if (num <= 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
+ return -(LONG_LONG)(num-1)-1;
+ }
+ rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
}
-VALUE
-dbl2big(d)
- double d;
+LONG_LONG
+rb_big2ll(VALUE x)
{
- unsigned int i = 0;
- long c;
- USHORT *digits;
+ unsigned LONG_LONG num = big2ull(x, "long long");
+
+ if (BIGNUM_POSITIVE_P(x)) {
+ if (num <= LLONG_MAX)
+ return num;
+ }
+ else {
+ if (num <= 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
+ return -(LONG_LONG)(num-1)-1;
+ }
+ rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
+}
+
+#endif /* HAVE_LONG_LONG */
+
+static VALUE
+dbl2big(double d)
+{
+ long i = 0;
+ BDIGIT c;
+ BDIGIT *digits;
VALUE z;
double u = (d < 0)?-d:d;
- while (0 != (long)u) {
+ if (isinf(d)) {
+ rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
+ }
+ if (isnan(d)) {
+ rb_raise(rb_eFloatDomainError, "NaN");
+ }
+
+ while (1.0 <= u) {
u /= (double)(BIGRAD);
i++;
}
@@ -403,903 +5202,1921 @@ dbl2big(d)
digits = BDIGITS(z);
while (i--) {
u *= BIGRAD;
- c = (long)u;
+ c = (BDIGIT)u;
u -= c;
digits[i] = c;
}
- return bignorm(z);
+ return z;
}
-double
-big2dbl(x)
- VALUE x;
+VALUE
+rb_dbl2big(double d)
+{
+ return bignorm(dbl2big(d));
+}
+
+static double
+big2dbl(VALUE x)
{
double d = 0.0;
- unsigned int i = RBIGNUM(x)->len;
- USHORT *ds = BDIGITS(x);
+ long i = (bigtrunc(x), BIGNUM_LEN(x)), lo = 0, bits;
+ BDIGIT *ds = BDIGITS(x), dl;
- while (i--) {
- d = ds[i] + BIGRAD*d;
+ if (i) {
+ bits = i * BITSPERDIG - nlz(ds[i-1]);
+ if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
+ d = HUGE_VAL;
+ }
+ else {
+ if (bits > DBL_MANT_DIG+1)
+ lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
+ else
+ bits = 0;
+ while (--i > lo) {
+ d = ds[i] + BIGRAD*d;
+ }
+ dl = ds[i];
+ if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
+ int carry = (dl & ~(BDIGMAX << bits)) != 0;
+ if (!carry) {
+ while (i-- > 0) {
+ carry = ds[i] != 0;
+ if (carry) break;
+ }
+ }
+ if (carry) {
+ dl &= BDIGMAX << bits;
+ dl = BIGLO(dl + ((BDIGIT)1 << bits));
+ if (!dl) d += 1;
+ }
+ }
+ d = dl + BIGRAD*d;
+ if (lo) {
+ if (lo > INT_MAX / BITSPERDIG)
+ d = HUGE_VAL;
+ else if (lo < INT_MIN / BITSPERDIG)
+ d = 0.0;
+ else
+ d = ldexp(d, (int)(lo * BITSPERDIG));
+ }
+ }
+ }
+ if (BIGNUM_NEGATIVE_P(x)) d = -d;
+ return d;
+}
+
+double
+rb_big2dbl(VALUE x)
+{
+ double d = big2dbl(x);
+
+ if (isinf(d)) {
+ rb_warning("Bignum out of Float range");
+ if (d < 0.0)
+ d = -HUGE_VAL;
+ else
+ d = HUGE_VAL;
}
- if (!RBIGNUM(x)->sign) d = -d;
return d;
}
VALUE
-big_to_f(x)
- VALUE x;
+rb_integer_float_cmp(VALUE x, VALUE y)
{
- return float_new(big2dbl(x));
+ double yd = RFLOAT_VALUE(y);
+ double yi, yf;
+ VALUE rel;
+
+ if (isnan(yd))
+ return Qnil;
+ if (isinf(yd)) {
+ if (yd > 0.0) return INT2FIX(-1);
+ else return INT2FIX(1);
+ }
+ yf = modf(yd, &yi);
+ if (FIXNUM_P(x)) {
+#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
+ double xd = (double)FIX2LONG(x);
+ if (xd < yd)
+ return INT2FIX(-1);
+ if (xd > yd)
+ return INT2FIX(1);
+ return INT2FIX(0);
+#else
+ long xn, yn;
+ if (yi < FIXNUM_MIN)
+ return INT2FIX(1);
+ if (FIXNUM_MAX+1 <= yi)
+ return INT2FIX(-1);
+ xn = FIX2LONG(x);
+ yn = (long)yi;
+ if (xn < yn)
+ return INT2FIX(-1);
+ if (xn > yn)
+ return INT2FIX(1);
+ if (yf < 0.0)
+ return INT2FIX(1);
+ if (0.0 < yf)
+ return INT2FIX(-1);
+ return INT2FIX(0);
+#endif
+ }
+ y = rb_dbl2big(yi);
+ rel = rb_big_cmp(x, y);
+ if (yf == 0.0 || rel != INT2FIX(0))
+ return rel;
+ if (yf < 0.0)
+ return INT2FIX(1);
+ return INT2FIX(-1);
+}
+
+VALUE
+rb_integer_float_eq(VALUE x, VALUE y)
+{
+ double yd = RFLOAT_VALUE(y);
+ double yi, yf;
+
+ if (isnan(yd) || isinf(yd))
+ return Qfalse;
+ yf = modf(yd, &yi);
+ if (yf != 0)
+ return Qfalse;
+ if (FIXNUM_P(x)) {
+#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
+ double xd = (double)FIX2LONG(x);
+ if (xd != yd)
+ return Qfalse;
+ return Qtrue;
+#else
+ long xn, yn;
+ if (yi < LONG_MIN || LONG_MAX < yi)
+ return Qfalse;
+ xn = FIX2LONG(x);
+ yn = (long)yi;
+ if (xn != yn)
+ return Qfalse;
+ return Qtrue;
+#endif
+ }
+ y = rb_dbl2big(yi);
+ return rb_big_eq(x, y);
}
+VALUE
+rb_big_cmp(VALUE x, VALUE y)
+{
+ if (FIXNUM_P(y)) {
+ x = bigfixize(x);
+ if (FIXNUM_P(x)) {
+ /* SIGNED_VALUE and Fixnum have same sign-bits, same
+ * order */
+ SIGNED_VALUE sx = (SIGNED_VALUE)x, sy = (SIGNED_VALUE)y;
+ if (sx < sy) return INT2FIX(-1);
+ return INT2FIX(sx > sy);
+ }
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
+ int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
+ return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
+ }
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ return rb_integer_float_cmp(x, y);
+ }
+ else {
+ return rb_num_coerce_cmp(x, y, idCmp);
+ }
+ return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
+}
+
+enum big_op_t {
+ big_op_gt,
+ big_op_ge,
+ big_op_lt,
+ big_op_le
+};
+
static VALUE
-big_cmp(x, y)
- VALUE x, y;
+big_op(VALUE x, VALUE y, enum big_op_t op)
{
- int xlen = RBIGNUM(x)->len;
+ VALUE rel;
+ int n;
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- break;
+ if (RB_INTEGER_TYPE_P(y)) {
+ rel = rb_big_cmp(x, y);
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ rel = rb_integer_float_cmp(x, y);
+ }
+ else {
+ ID id = 0;
+ switch (op) {
+ case big_op_gt: id = '>'; break;
+ case big_op_ge: id = idGE; break;
+ case big_op_lt: id = '<'; break;
+ case big_op_le: id = idLE; break;
+ }
+ return rb_num_coerce_relop(x, y, id);
+ }
- case T_BIGNUM:
- break;
+ if (NIL_P(rel)) return Qfalse;
+ n = FIX2INT(rel);
- default:
- return num_coerce_bin(x, y);
+ switch (op) {
+ case big_op_gt: return n > 0 ? Qtrue : Qfalse;
+ case big_op_ge: return n >= 0 ? Qtrue : Qfalse;
+ case big_op_lt: return n < 0 ? Qtrue : Qfalse;
+ case big_op_le: return n <= 0 ? Qtrue : Qfalse;
}
+ return Qundef;
+}
- if (RBIGNUM(x)->sign > RBIGNUM(y)->sign) return INT2FIX(1);
- if (RBIGNUM(x)->sign < RBIGNUM(y)->sign) return INT2FIX(-1);
- if (xlen < RBIGNUM(y)->len)
- return (RBIGNUM(x)->sign) ? INT2FIX(-1) : INT2FIX(1);
- if (xlen > RBIGNUM(y)->len)
- return (RBIGNUM(x)->sign) ? INT2FIX(1) : INT2FIX(-1);
+VALUE
+rb_big_gt(VALUE x, VALUE y)
+{
+ return big_op(x, y, big_op_gt);
+}
- while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
- if (-1 == xlen) return INT2FIX(0);
- return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
- (RBIGNUM(x)->sign ? INT2FIX(1) : INT2FIX(-1)) :
- (RBIGNUM(x)->sign ? INT2FIX(-1) : INT2FIX(1));
+VALUE
+rb_big_ge(VALUE x, VALUE y)
+{
+ return big_op(x, y, big_op_ge);
}
-static VALUE
-big_eq(x, y)
- VALUE x, y;
+VALUE
+rb_big_lt(VALUE x, VALUE y)
{
- if (big_cmp(x, y) == INT2FIX(0)) return TRUE;
- return FALSE;
+ return big_op(x, y, big_op_lt);
}
-static VALUE
-big_uminus(x)
- VALUE x;
+VALUE
+rb_big_le(VALUE x, VALUE y)
+{
+ return big_op(x, y, big_op_le);
+}
+
+/*
+ * call-seq:
+ * 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>.
+ *
+ * 68719476736 == 68719476736.0 #=> true
+ */
+
+VALUE
+rb_big_eq(VALUE x, VALUE y)
{
- VALUE z = big_clone(x);
+ if (FIXNUM_P(y)) {
+ return bignorm(x) == y ? Qtrue : Qfalse;
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ return rb_integer_float_eq(x, y);
+ }
+ else {
+ return rb_equal(y, x);
+ }
+ if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
+ if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
+ if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
+ return Qtrue;
+}
- RBIGNUM(z)->sign = !RBIGNUM(x)->sign;
+VALUE
+rb_big_eql(VALUE x, VALUE y)
+{
+ if (!RB_BIGNUM_TYPE_P(y)) return Qfalse;
+ if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
+ if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
+ if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
+ return Qtrue;
+}
+
+VALUE
+rb_big_uminus(VALUE x)
+{
+ VALUE z = rb_big_clone(x);
+
+ BIGNUM_NEGATE(z);
return bignorm(z);
}
-static VALUE
-big_neg(x)
- VALUE x;
+VALUE
+rb_big_comp(VALUE x)
{
- VALUE z = big_clone(x);
- unsigned int i = RBIGNUM(x)->len;
- USHORT *ds = BDIGITS(z);
+ VALUE z = rb_big_clone(x);
+ BDIGIT *ds = BDIGITS(z);
+ long n = BIGNUM_LEN(z);
+
+ if (!n) return INT2FIX(-1);
- if (!RBIGNUM(x)->sign) big_2comp(z);
- while (i--) ds[i] = ~ds[i];
- if (RBIGNUM(x)->sign) big_2comp(z);
- RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
+ if (BIGNUM_POSITIVE_P(z)) {
+ if (bary_add_one(ds, n)) {
+ big_extend_carry(z);
+ }
+ BIGNUM_SET_NEGATIVE_SIGN(z);
+ }
+ else {
+ bary_neg(ds, n);
+ if (bary_add_one(ds, n))
+ return INT2FIX(-1);
+ bary_neg(ds, n);
+ BIGNUM_SET_POSITIVE_SIGN(z);
+ }
return bignorm(z);
}
static VALUE
-bigsub(x, y)
- VALUE x, y;
-{
- VALUE z = 0;
- USHORT *zds;
- long num;
- unsigned int i;
-
- i = RBIGNUM(x)->len;
- /* if x is larger than y, swap */
- if (RBIGNUM(x)->len < RBIGNUM(y)->len) {
- z = x; x = y; y = z; /* swap x y */
- }
- else if (RBIGNUM(x)->len == RBIGNUM(y)->len) {
- while (i > 0) {
- i--;
- if (BDIGITS(x)[i] > BDIGITS(y)[i]) {
- break;
- }
- if (BDIGITS(x)[i] < BDIGITS(y)[i]) {
- z = x; x = y; y = z; /* swap x y */
- break;
- }
- }
+bigsub(VALUE x, VALUE y)
+{
+ VALUE z;
+ BDIGIT *xds, *yds, *zds;
+ long xn, yn, zn;
+
+ xn = BIGNUM_LEN(x);
+ yn = BIGNUM_LEN(y);
+ zn = xn < yn ? yn : xn;
+
+ z = bignew(zn, 1);
+
+ xds = BDIGITS(x);
+ yds = BDIGITS(y);
+ zds = BDIGITS(z);
+
+ if (bary_sub(zds, zn, xds, xn, yds, yn)) {
+ bary_2comp(zds, zn);
+ BIGNUM_SET_NEGATIVE_SIGN(z);
}
- z = bignew(RBIGNUM(x)->len, (z == 0)?1:0);
+ return z;
+}
+
+static VALUE bigadd_int(VALUE x, long y);
+
+static VALUE
+bigsub_int(VALUE x, long y0)
+{
+ VALUE z;
+ BDIGIT *xds, *zds;
+ long xn, zn;
+ BDIGIT_DBL_SIGNED num;
+ long i, y;
+
+ y = y0;
+ xds = BDIGITS(x);
+ xn = BIGNUM_LEN(x);
+
+ if (xn == 0)
+ return LONG2NUM(-y0);
+
+ zn = xn;
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (zn < bdigit_roomof(SIZEOF_LONG))
+ zn = bdigit_roomof(SIZEOF_LONG);
+#endif
+ z = bignew(zn, BIGNUM_SIGN(x));
zds = BDIGITS(z);
- for (i = 0, num = 0; i < RBIGNUM(y)->len; i++) {
- num += (long)BDIGITS(x)[i] - BDIGITS(y)[i];
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ assert(xn == zn);
+ num = (BDIGIT_DBL_SIGNED)xds[0] - y;
+ if (xn == 1 && num < 0) {
+ BIGNUM_NEGATE(z);
+ zds[0] = (BDIGIT)-num;
+ RB_GC_GUARD(x);
+ return bignorm(z);
+ }
+ zds[0] = BIGLO(num);
+ num = BIGDN(num);
+ i = 1;
+ if (i < xn)
+ goto y_is_zero_x;
+ goto finish;
+#else
+ num = 0;
+ for (i=0; i < xn; i++) {
+ if (y == 0) goto y_is_zero_x;
+ num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
zds[i] = BIGLO(num);
num = BIGDN(num);
- }
- while (num && i < RBIGNUM(x)->len) {
- num += BDIGITS(x)[i];
- zds[i++] = BIGLO(num);
+ y = BIGDN(y);
+ }
+ for (; i < zn; i++) {
+ if (y == 0) goto y_is_zero_z;
+ num -= BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
+ }
+ goto finish;
+#endif
+
+ for (; i < xn; i++) {
+ y_is_zero_x:
+ if (num == 0) goto num_is_zero_x;
+ num += xds[i];
+ zds[i] = BIGLO(num);
num = BIGDN(num);
}
- while (i < RBIGNUM(x)->len) {
- zds[i] = BDIGITS(x)[i];
- i++;
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ for (; i < zn; i++) {
+ y_is_zero_z:
+ if (num == 0) goto num_is_zero_z;
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ }
+#endif
+ goto finish;
+
+ for (; i < xn; i++) {
+ num_is_zero_x:
+ zds[i] = xds[i];
}
-
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ for (; i < zn; i++) {
+ num_is_zero_z:
+ zds[i] = 0;
+ }
+#endif
+ goto finish;
+
+ finish:
+ assert(num == 0 || num == -1);
+ if (num < 0) {
+ get2comp(z);
+ BIGNUM_NEGATE(z);
+ }
+ RB_GC_GUARD(x);
return bignorm(z);
}
static VALUE
-bigadd(x, y, sign)
- VALUE x, y;
- char sign;
+bigadd_int(VALUE x, long y)
{
VALUE z;
- long num;
- unsigned int i, len;
+ BDIGIT *xds, *zds;
+ long xn, zn;
+ BDIGIT_DBL num;
+ long i;
- sign = (sign == RBIGNUM(y)->sign);
- if (RBIGNUM(x)->sign != sign) {
- if (sign) return bigsub(y, x);
- return bigsub(x, y);
- }
+ xds = BDIGITS(x);
+ xn = BIGNUM_LEN(x);
+
+ if (xn == 0)
+ return LONG2NUM(y);
+
+ zn = xn;
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (zn < bdigit_roomof(SIZEOF_LONG))
+ zn = bdigit_roomof(SIZEOF_LONG);
+#endif
+ zn++;
- if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
- len = RBIGNUM(x)->len + 1;
- z = x; x = y; y = z;
+ z = bignew(zn, BIGNUM_SIGN(x));
+ zds = BDIGITS(z);
+
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ num = (BDIGIT_DBL)xds[0] + y;
+ zds[0] = BIGLO(num);
+ num = BIGDN(num);
+ i = 1;
+ if (i < xn)
+ goto y_is_zero_x;
+ goto y_is_zero_z;
+#else
+ num = 0;
+ for (i=0; i < xn; i++) {
+ if (y == 0) goto y_is_zero_x;
+ num += (BDIGIT_DBL)xds[i] + BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
}
- else {
- len = RBIGNUM(y)->len + 1;
+ for (; i < zn; i++) {
+ if (y == 0) goto y_is_zero_z;
+ num += BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
}
- z = bignew(len, sign);
+ goto finish;
- len = RBIGNUM(x)->len;
- for (i = 0, num = 0; i < len; i++) {
- num += BDIGITS(x)[i] + BDIGITS(y)[i];
- BDIGITS(z)[i] = BIGLO(num);
+#endif
+
+ for (;i < xn; i++) {
+ y_is_zero_x:
+ if (num == 0) goto num_is_zero_x;
+ num += (BDIGIT_DBL)xds[i];
+ zds[i] = BIGLO(num);
num = BIGDN(num);
}
- len = RBIGNUM(y)->len;
- while (num && i < len) {
- num += BDIGITS(y)[i];
- BDIGITS(z)[i++] = BIGLO(num);
+ for (; i < zn; i++) {
+ y_is_zero_z:
+ if (num == 0) goto num_is_zero_z;
+ zds[i] = BIGLO(num);
num = BIGDN(num);
}
- while (i < len) {
- BDIGITS(z)[i] = BDIGITS(y)[i];
- i++;
+ goto finish;
+
+ for (;i < xn; i++) {
+ num_is_zero_x:
+ zds[i] = xds[i];
+ }
+ for (; i < zn; i++) {
+ num_is_zero_z:
+ zds[i] = 0;
}
- BDIGITS(z)[i] = num;
+ goto finish;
+ finish:
+ RB_GC_GUARD(x);
return bignorm(z);
}
-VALUE
-big_plus(x, y)
- VALUE x, y;
+static VALUE
+bigadd(VALUE x, VALUE y, int sign)
{
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- /* fall through */
- case T_BIGNUM:
- return bigadd(x, y, 1);
+ VALUE z;
+ size_t len;
- case T_FLOAT:
- return float_new(big2dbl(x) + RFLOAT(y)->value);
+ sign = (sign == BIGNUM_SIGN(y));
+ if (BIGNUM_SIGN(x) != sign) {
+ if (sign) return bigsub(y, x);
+ return bigsub(x, y);
+ }
- default:
- return num_coerce_bin(x, y);
+ if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
+ len = BIGNUM_LEN(x) + 1;
}
+ else {
+ len = BIGNUM_LEN(y) + 1;
+ }
+ z = bignew(len, sign);
+
+ bary_add(BDIGITS(z), BIGNUM_LEN(z),
+ BDIGITS(x), BIGNUM_LEN(x),
+ BDIGITS(y), BIGNUM_LEN(y));
+
+ return z;
}
VALUE
-big_minus(x, y)
- VALUE x, y;
+rb_big_plus(VALUE x, VALUE y)
{
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- /* fall through */
- case T_BIGNUM:
- return bigadd(x, y, 0);
-
- case T_FLOAT:
- return float_new(big2dbl(x) - RFLOAT(y)->value);
+ long n;
- default:
- return num_coerce_bin(x, y);
+ if (FIXNUM_P(y)) {
+ n = FIX2LONG(y);
+ if ((n > 0) != BIGNUM_SIGN(x)) {
+ if (n < 0) {
+ n = -n;
+ }
+ return bigsub_int(x, n);
+ }
+ if (n < 0) {
+ n = -n;
+ }
+ return bigadd_int(x, n);
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ return bignorm(bigadd(x, y, 1));
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
+ }
+ else {
+ return rb_num_coerce_bin(x, y, '+');
}
}
VALUE
-big_mul(x, y)
- VALUE x, y;
+rb_big_minus(VALUE x, VALUE y)
{
- unsigned int i = 0, j;
- unsigned long n = 0;
+ long n;
+
+ if (FIXNUM_P(y)) {
+ n = FIX2LONG(y);
+ if ((n > 0) != BIGNUM_SIGN(x)) {
+ if (n < 0) {
+ n = -n;
+ }
+ return bigadd_int(x, n);
+ }
+ if (n < 0) {
+ n = -n;
+ }
+ return bigsub_int(x, n);
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ return bignorm(bigadd(x, y, 0));
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
+ }
+ else {
+ return rb_num_coerce_bin(x, y, '-');
+ }
+}
+
+static VALUE
+bigsq(VALUE x)
+{
+ long xn, zn;
VALUE z;
- USHORT *zds;
+ BDIGIT *xds, *zds;
- if (FIXNUM_P(x)) x = int2big(FIX2LONG(x));
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- break;
+ xn = BIGNUM_LEN(x);
+ zn = 2 * xn;
- case T_BIGNUM:
- break;
+ z = bignew(zn, 1);
- case T_FLOAT:
- return float_new(big2dbl(x) * RFLOAT(y)->value);
+ xds = BDIGITS(x);
+ zds = BDIGITS(z);
- default:
- return num_coerce_bin(x, y);
- }
+ if (xn < NAIVE_MUL_DIGITS)
+ bary_sq_fast(zds, zn, xds, xn);
+ else
+ bary_mul(zds, zn, xds, xn, xds, xn);
+
+ RB_GC_GUARD(x);
+ return z;
+}
+
+static VALUE
+bigmul0(VALUE x, VALUE y)
+{
+ long xn, yn, zn;
+ VALUE z;
+ BDIGIT *xds, *yds, *zds;
+
+ if (x == y)
+ return bigsq(x);
+
+ xn = BIGNUM_LEN(x);
+ yn = BIGNUM_LEN(y);
+ zn = xn + yn;
- j = RBIGNUM(x)->len + RBIGNUM(y)->len + 1;
- z = bignew(j, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
+ z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+
+ xds = BDIGITS(x);
+ yds = BDIGITS(y);
zds = BDIGITS(z);
- while (j--) zds[j] = 0;
- for (i = 0; i < RBIGNUM(x)->len; i++) {
- unsigned long dd = BDIGITS(x)[i];
- if (dd == 0) continue;
- n = 0;
- for (j = 0; j < RBIGNUM(y)->len; j++) {
- int ee = n + dd * BDIGITS(y)[j];
- n = zds[i + j] + ee;
- if (ee) zds[i + j] = BIGLO(n);
- n = BIGDN(n);
- }
- if (n) {
- zds[i + j] = n;
- }
+
+ bary_mul(zds, zn, xds, xn, yds, yn);
+
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
+ return z;
+}
+
+VALUE
+rb_big_mul(VALUE x, VALUE y)
+{
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
+ }
+ else {
+ return rb_num_coerce_bin(x, y, '*');
}
- return bignorm(z);
+ return bignorm(bigmul0(x, y));
}
-static void
-bigdivmod(x, y, div, mod, modulo)
- VALUE x, y;
- VALUE *div, *mod;
- int modulo;
-{
- unsigned int nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len, i, j;
- VALUE yy, z;
- USHORT *xds, *yds, *zds, *tds;
- unsigned long t2;
- long num;
- USHORT dd, q;
+static VALUE
+bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
+{
+ long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
+ VALUE z;
+ BDIGIT *xds, *yds, *zds;
+ BDIGIT dd;
+
+ VALUE q = Qnil, r = Qnil;
+ BDIGIT *qds, *rds;
+ long qn, rn;
yds = BDIGITS(y);
- if (ny == 0 && yds[0] == 0) num_zerodiv();
- if (nx < ny || nx == ny && BDIGITS(x)[nx - 1] < BDIGITS(y)[ny - 1]) {
- if (div) *div = INT2FIX(0);
- if (mod) *mod = bignorm(x);
- return;
- }
+ BARY_TRUNC(yds, yn);
+ if (yn == 0)
+ rb_num_zerodiv();
+
xds = BDIGITS(x);
- if (ny == 1) {
+ BARY_TRUNC(xds, xn);
+
+ if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
+ if (divp) *divp = rb_int2big(0);
+ if (modp) *modp = x;
+ return Qnil;
+ }
+ if (yn == 1) {
dd = yds[0];
- z = big_clone(x);
+ z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
zds = BDIGITS(z);
- t2 = 0; i = nx;
- while (i--) {
- t2 = BIGUP(t2) + zds[i];
- zds[i] = t2 / dd;
- t2 %= dd;
+ dd = bigdivrem_single(zds, xds, xn, dd);
+ if (modp) {
+ *modp = rb_uint2big((VALUE)dd);
+ BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
}
- if (div) *div = bignorm(z);
- if (mod) {
- if (!RBIGNUM(y)->sign) t2 = -t2;
- *mod = INT2FIX(t2);
- }
- return;
+ if (divp) *divp = z;
+ return Qnil;
}
- z = bignew(nx==ny?nx+2:nx+1, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
- zds = BDIGITS(z);
- if (nx==ny) zds[nx+1] = 0;
- while (!yds[ny-1]) ny--;
- if ((dd = BIGRAD/(int)(yds[ny-1]+1)) != 1) {
- yy = big_clone(y);
- tds = BDIGITS(yy);
- j = 0;
- num = 0;
- while (j<ny) {
- num += (long)yds[j]*dd;
- tds[j++] = BIGLO(num);
- num = BIGDN(num);
- }
- yds = tds;
- j = 0;
- num = 0;
- while (j<nx) {
- num += (long)xds[j]*dd;
- zds[j++] = BIGLO(num);
- num = BIGDN(num);
- }
- zds[j] = num;
+ if (xn == 2 && yn == 2) {
+ BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
+ BDIGIT_DBL y0 = bary2bdigitdbl(yds, 2);
+ BDIGIT_DBL q0 = x0 / y0;
+ BDIGIT_DBL r0 = x0 % y0;
+ if (divp) {
+ z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ zds = BDIGITS(z);
+ zds[0] = BIGLO(q0);
+ zds[1] = BIGLO(BIGDN(q0));
+ *divp = z;
+ }
+ if (modp) {
+ z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x));
+ zds = BDIGITS(z);
+ zds[0] = BIGLO(r0);
+ zds[1] = BIGLO(BIGDN(r0));
+ *modp = z;
+ }
+ return Qnil;
+ }
+
+ if (divp) {
+ qn = xn + BIGDIVREM_EXTRA_WORDS;
+ q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ qds = BDIGITS(q);
}
else {
- zds[nx] = 0;
- j = nx;
- while (j--) zds[j] = xds[j];
+ qn = 0;
+ qds = NULL;
}
- j = nx==ny?nx+1:nx;
- do {
- if (zds[j] == yds[ny-1]) q = BIGRAD-1;
- else q = (BIGUP(zds[j]) + zds[j-1])/yds[ny-1];
- if (q) {
- i = 0; num = 0; t2 = 0;
- do { /* multiply and subtract */
- int ee;
- t2 += (long)yds[i] * q;
- ee = num - BIGLO(t2);
- num = zds[j - ny + i] + ee;
- if (ee) zds[j - ny + i] = BIGLO(num);
- num = BIGDN(num);
- t2 = BIGDN(t2);
- } while (++i < ny);
- num += zds[j - ny + i] - t2; /* borrow from high digit; don't update */
- while (num) { /* "add back" required */
- i = 0; num = 0; q--;
- do {
- int ee = num + yds[i];
- num = (long) zds[j - ny + i] + ee;
- if (ee) zds[j - ny + i] = BIGLO(num);
- num = BIGDN(num);
- } while (++i < ny);
- num--;
- }
- }
- zds[j] = q;
- } while (--j >= ny);
- if (div) { /* move quotient down in z */
- *div = big_clone(z);
- zds = BDIGITS(*div);
- j = (nx==ny ? nx+2 : nx+1) - ny;
- for (i = 0;i < j;i++) zds[i] = zds[i+ny];
- RBIGNUM(*div)->len = i;
- *div = bignorm(*div);
- }
- if (mod) { /* just normalize remainder */
- *mod = big_clone(z);
- if (dd) {
- zds = BDIGITS(*mod);
- t2 = 0; i = ny;
- while(i--) {
- t2 = BIGUP(t2) + zds[i];
- zds[i] = t2 / dd;
- t2 %= dd;
- }
- }
- RBIGNUM(*mod)->len = ny;
- RBIGNUM(*mod)->sign = RBIGNUM(x)->sign;
- if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) {
- int len = ny;
- zds = BDIGITS(*mod);
- while (len-- && !zds[len]);
- if (len > 0) {
- *mod = bigadd(*mod, y, 1);
- return;
- }
- }
- *mod = bignorm(*mod);
+
+ if (modp) {
+ rn = yn;
+ r = bignew(rn, BIGNUM_SIGN(x));
+ rds = BDIGITS(r);
+ }
+ else {
+ rn = 0;
+ rds = NULL;
+ }
+
+ bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
+
+ if (divp) {
+ bigtrunc(q);
+ *divp = q;
+ }
+ if (modp) {
+ bigtrunc(r);
+ *modp = r;
}
+
+ return Qnil;
}
-static VALUE
-big_div(x, y)
- VALUE x, y;
+static void
+bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
{
- VALUE z;
+ VALUE mod;
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- break;
+ bigdivrem(x, y, divp, &mod);
+ if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
+ if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
+ if (modp) *modp = bigadd(mod, y, 1);
+ }
+ else if (modp) {
+ *modp = mod;
+ }
+}
- case T_BIGNUM:
- break;
- case T_FLOAT:
- return float_new(big2dbl(x) / RFLOAT(y)->value);
+static VALUE
+rb_big_divide(VALUE x, VALUE y, ID op)
+{
+ VALUE z;
- default:
- return num_coerce_bin(x, y);
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ }
+ else if (RB_FLOAT_TYPE_P(y)) {
+ if (op == '/') {
+ return DBL2NUM(rb_big2dbl(x) / RFLOAT_VALUE(y));
+ }
+ else {
+ double dy = RFLOAT_VALUE(y);
+ if (dy == 0.0) rb_num_zerodiv();
+ return rb_dbl2big(rb_big2dbl(x) / dy);
+ }
+ }
+ else {
+ return rb_num_coerce_bin(x, y, op);
}
- bigdivmod(x, y, &z, 0, 0);
+ bigdivmod(x, y, &z, 0);
- return z;
+ return bignorm(z);
}
+VALUE
+rb_big_div(VALUE x, VALUE y)
+{
+ return rb_big_divide(x, y, '/');
+}
-static VALUE
-big_modulo(x, y, modulo)
- VALUE x, y;
- int modulo;
+VALUE
+rb_big_idiv(VALUE x, VALUE y)
+{
+ return rb_big_divide(x, y, rb_intern("div"));
+}
+
+VALUE
+rb_big_modulo(VALUE x, VALUE y)
{
VALUE z;
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- break;
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ else if (!RB_BIGNUM_TYPE_P(y)) {
+ return rb_num_coerce_bin(x, y, '%');
+ }
+ bigdivmod(x, y, 0, &z);
- case T_BIGNUM:
- break;
+ return bignorm(z);
+}
- case T_FLOAT:
- y = dbl2big(RFLOAT(y)->value);
- break;
+VALUE
+rb_big_remainder(VALUE x, VALUE y)
+{
+ VALUE z;
- default:
- return num_coerce_bin(x, y);
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ else if (!RB_BIGNUM_TYPE_P(y)) {
+ return rb_num_coerce_bin(x, y, rb_intern("remainder"));
}
- bigdivmod(x, y, 0, &z, modulo);
+ bigdivrem(x, y, 0, &z);
- return z;
+ return bignorm(z);
}
-static VALUE
-big_mod(x, y)
- VALUE x, y;
+VALUE
+rb_big_divmod(VALUE x, VALUE y)
{
- return big_modulo(x, y, 1);
+ VALUE div, mod;
+
+ if (FIXNUM_P(y)) {
+ y = rb_int2big(FIX2LONG(y));
+ }
+ else if (!RB_BIGNUM_TYPE_P(y)) {
+ return rb_num_coerce_bin(x, y, rb_intern("divmod"));
+ }
+ bigdivmod(x, y, &div, &mod);
+
+ return rb_assoc_new(bignorm(div), bignorm(mod));
}
static VALUE
-big_remainder(x, y)
- VALUE x, y;
+big_shift(VALUE x, long n)
{
- return big_modulo(x, y, 0);
+ if (n < 0)
+ return big_lshift(x, 1+(unsigned long)(-(n+1)));
+ else if (n > 0)
+ return big_rshift(x, (unsigned long)n);
+ return x;
}
-static VALUE
-big_divmod(x, y)
- VALUE x, y;
+enum {DBL_BIGDIG = ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)};
+
+static double
+big_fdiv(VALUE x, VALUE y, long ey)
{
- VALUE div, mod;
+ VALUE z;
+ long l, ex;
+
+ bigtrunc(x);
+ l = BIGNUM_LEN(x);
+ ex = l * BITSPERDIG - nlz(BDIGITS(x)[l-1]);
+ ex -= 2 * DBL_BIGDIG * BITSPERDIG;
+ if (ex > BITSPERDIG) ex -= BITSPERDIG;
+ else if (ex > 0) ex = 0;
+ if (ex) x = big_shift(x, ex);
+
+ bigdivrem(x, y, &z, 0);
+ l = ex - ey;
+#if SIZEOF_LONG > SIZEOF_INT
+ {
+ /* Visual C++ can't be here */
+ if (l > INT_MAX) return INFINITY;
+ if (l < INT_MIN) return 0.0;
+ }
+#endif
+ return ldexp(big2dbl(z), (int)l);
+}
- switch (TYPE(y)) {
- case T_FIXNUM:
- y = int2big(FIX2LONG(y));
- break;
+static double
+big_fdiv_int(VALUE x, VALUE y)
+{
+ long l, ey;
+ bigtrunc(y);
+ l = BIGNUM_LEN(y);
+ ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
+ ey -= DBL_BIGDIG * BITSPERDIG;
+ if (ey) y = big_shift(y, ey);
+ return big_fdiv(x, y, ey);
+}
- case T_FLOAT:
- y = dbl2big(RFLOAT(y)->value);
- break;
+static double
+big_fdiv_float(VALUE x, VALUE y)
+{
+ int i;
+ y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
+ return big_fdiv(x, y, i - DBL_MANT_DIG);
+}
- case T_BIGNUM:
- break;
+double
+rb_big_fdiv_double(VALUE x, VALUE y)
+{
+ double dx, dy;
- default:
- return num_coerce_bin(x, y);
+ dx = big2dbl(x);
+ if (FIXNUM_P(y)) {
+ dy = (double)FIX2LONG(y);
+ if (isinf(dx))
+ 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);
}
- bigdivmod(x, y, &div, &mod, 1);
+ else if (RB_FLOAT_TYPE_P(y)) {
+ dy = RFLOAT_VALUE(y);
+ if (isnan(dy))
+ return dy;
+ if (isinf(dx))
+ return big_fdiv_float(x, y);
+ }
+ else {
+ return NUM2DBL(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
+ }
+ return dx / dy;
+}
- return assoc_new(div, mod);;
+VALUE
+rb_big_fdiv(VALUE x, VALUE y)
+{
+ return DBL2NUM(rb_big_fdiv_double(x, y));
}
VALUE
-big_pow(x, y)
- VALUE x, y;
+rb_big_pow(VALUE x, VALUE y)
{
double d;
- long yy;
-
+ SIGNED_VALUE yy;
+
+ again:
if (y == INT2FIX(0)) return INT2FIX(1);
- switch (TYPE(y)) {
- case T_FLOAT:
- d = RFLOAT(y)->value;
- break;
-
- case T_BIGNUM:
- Warn("in a**b, b may be too big");
- d = big2dbl(y);
- break;
-
- case T_FIXNUM:
- yy = NUM2LONG(y);
- if (yy > 0) {
- VALUE z;
-
- z = x;
- for (;;) {
- yy = yy - 1;
- if (yy == 0) break;
- while (yy % 2 == 0) {
- yy = yy / 2;
- x = big_mul(x, 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);
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ y = bignorm(y);
+ if (FIXNUM_P(y))
+ goto again;
+ rb_warn("in a**b, b may be too big");
+ d = rb_big2dbl(y);
+ }
+ else if (FIXNUM_P(y)) {
+ yy = FIX2LONG(y);
+
+ if (yy < 0)
+ return rb_funcall(rb_rational_raw1(x), idPow, 1, y);
+ else {
+ VALUE z = 0;
+ SIGNED_VALUE mask;
+ const size_t xbits = rb_absint_numwords(x, 1, NULL);
+ const size_t BIGLEN_LIMIT = 32*1024*1024;
+
+ if (xbits == (size_t)-1 ||
+ (xbits > BIGLEN_LIMIT) ||
+ (xbits * yy > BIGLEN_LIMIT)) {
+ rb_warn("in a**b, b may be too big");
+ d = (double)yy;
+ }
+ else {
+ for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
+ if (z) z = bigsq(z);
+ if (yy & mask) {
+ z = z ? bigtrunc(bigmul0(z, x)) : x;
+ }
}
- z = big_mul(z, x);
+ return bignorm(z);
}
- return z;
}
- d = (double)yy;
- break;
-
- default:
- return num_coerce_bin(x, y);
}
- return float_new(pow(big2dbl(x), d));
+ else {
+ return rb_num_coerce_bin(x, y, idPow);
+ }
+ return DBL2NUM(pow(rb_big2dbl(x), d));
}
-VALUE
-big_and(x, y)
- VALUE x, y;
+static VALUE
+bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
{
VALUE z;
- USHORT *ds1, *ds2, *zds;
- unsigned int i, l1, l2;
- char sign;
+ BDIGIT *xds, *zds;
+ long zn;
+ long i;
+ BDIGIT hibitsy;
+
+ if (y == 0) return INT2FIX(0);
+ if (xn == 0) return hibitsx ? LONG2NUM(y) : 0;
+ hibitsy = 0 <= y ? 0 : BDIGMAX;
+ xds = BDIGITS(x);
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ if (!hibitsy) {
+ y &= xds[0];
+ return LONG2NUM(y);
+ }
+#endif
- if (FIXNUM_P(y)) {
- y = int2big(FIX2LONG(y));
+ zn = xn;
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
+ zn = bdigit_roomof(SIZEOF_LONG);
+#endif
+
+ z = bignew(zn, 0);
+ zds = BDIGITS(z);
+
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ i = 1;
+ zds[0] = xds[0] & BIGLO(y);
+#else
+ for (i=0; i < xn; i++) {
+ if (y == 0 || y == -1) break;
+ zds[i] = xds[i] & BIGLO(y);
+ y = BIGDN(y);
}
- else {
- Check_Type(y, T_BIGNUM);
+ for (; i < zn; i++) {
+ if (y == 0 || y == -1) break;
+ zds[i] = hibitsx & BIGLO(y);
+ y = BIGDN(y);
}
-
- if (!RBIGNUM(y)->sign) {
- y = big_clone(y);
- big_2comp(y);
+#endif
+ for (;i < xn; i++) {
+ zds[i] = xds[i] & hibitsy;
}
- if (!RBIGNUM(x)->sign) {
- x = big_clone(x);
- big_2comp(x);
+ for (;i < zn; i++) {
+ zds[i] = hibitsx & hibitsy;
}
- if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
- l1 = RBIGNUM(y)->len;
- l2 = RBIGNUM(x)->len;
- ds1 = BDIGITS(y);
- ds2 = BDIGITS(x);
- sign = RBIGNUM(y)->sign;
+ twocomp2abs_bang(z, hibitsx && hibitsy);
+ RB_GC_GUARD(x);
+ return bignorm(z);
+}
+
+VALUE
+rb_big_and(VALUE x, VALUE y)
+{
+ VALUE z;
+ BDIGIT *ds1, *ds2, *zds;
+ long i, xn, yn, n1, n2;
+ BDIGIT hibitsx, hibitsy;
+ BDIGIT hibits1, hibits2;
+ VALUE tmpv;
+ BDIGIT tmph;
+ long tmpn;
+
+ if (!RB_INTEGER_TYPE_P(y)) {
+ return rb_num_coerce_bit(x, y, '&');
}
- else {
- l1 = RBIGNUM(x)->len;
- l2 = RBIGNUM(y)->len;
- ds1 = BDIGITS(x);
- ds2 = BDIGITS(y);
- sign = RBIGNUM(x)->sign;
+
+ hibitsx = abs2twocomp(&x, &xn);
+ if (FIXNUM_P(y)) {
+ return bigand_int(x, xn, hibitsx, FIX2LONG(y));
+ }
+ hibitsy = abs2twocomp(&y, &yn);
+ if (xn > yn) {
+ tmpv = x; x = y; y = tmpv;
+ tmpn = xn; xn = yn; yn = tmpn;
+ tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
- z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign);
+ n1 = xn;
+ n2 = yn;
+ ds1 = BDIGITS(x);
+ ds2 = BDIGITS(y);
+ hibits1 = hibitsx;
+ hibits2 = hibitsy;
+
+ if (!hibits1)
+ n2 = n1;
+
+ z = bignew(n2, 0);
zds = BDIGITS(z);
- for (i=0; i<l1; i++) {
+ for (i=0; i<n1; i++) {
zds[i] = ds1[i] & ds2[i];
}
- for (; i<l2; i++) {
- zds[i] = sign?0:ds2[i];
+ for (; i<n2; i++) {
+ zds[i] = hibits1 & ds2[i];
}
- if (!RBIGNUM(z)->sign) big_2comp(z);
+ twocomp2abs_bang(z, hibits1 && hibits2);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
return bignorm(z);
}
-VALUE
-big_or(x, y)
- VALUE x, y;
+static VALUE
+bigor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
{
VALUE z;
- USHORT *ds1, *ds2, *zds;
- unsigned int i, l1, l2;
- char sign;
+ BDIGIT *xds, *zds;
+ long zn;
+ long i;
+ BDIGIT hibitsy;
+
+ if (y == -1) return INT2FIX(-1);
+ if (xn == 0) return hibitsx ? INT2FIX(-1) : LONG2FIX(y);
+ hibitsy = 0 <= y ? 0 : BDIGMAX;
+ xds = BDIGITS(x);
- if (FIXNUM_P(y)) {
- y = int2big(FIX2LONG(y));
- }
- else {
- Check_Type(y, T_BIGNUM);
- }
+ zn = BIGNUM_LEN(x);
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (zn < bdigit_roomof(SIZEOF_LONG))
+ zn = bdigit_roomof(SIZEOF_LONG);
+#endif
+ z = bignew(zn, 0);
+ zds = BDIGITS(z);
- if (!RBIGNUM(y)->sign) {
- y = big_clone(y);
- big_2comp(y);
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ i = 1;
+ zds[0] = xds[0] | BIGLO(y);
+ if (i < zn)
+ goto y_is_fixed_point;
+ goto finish;
+#else
+ for (i=0; i < xn; i++) {
+ if (y == 0 || y == -1) goto y_is_fixed_point;
+ zds[i] = xds[i] | BIGLO(y);
+ y = BIGDN(y);
}
- if (!RBIGNUM(x)->sign) {
- x = big_clone(x);
- big_2comp(x);
+ if (hibitsx)
+ goto fill_hibits;
+ for (; i < zn; i++) {
+ if (y == 0 || y == -1) goto y_is_fixed_point;
+ zds[i] = BIGLO(y);
+ y = BIGDN(y);
}
- if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
- l1 = RBIGNUM(y)->len;
- l2 = RBIGNUM(x)->len;
- ds1 = BDIGITS(y);
- ds2 = BDIGITS(x);
- sign = RBIGNUM(y)->sign;
+ goto finish;
+#endif
+
+ y_is_fixed_point:
+ if (hibitsy)
+ goto fill_hibits;
+ for (; i < xn; i++) {
+ zds[i] = xds[i];
}
- else {
- l1 = RBIGNUM(x)->len;
- l2 = RBIGNUM(y)->len;
- ds1 = BDIGITS(x);
- ds2 = BDIGITS(y);
- sign = RBIGNUM(x)->sign;
+ if (hibitsx)
+ goto fill_hibits;
+ for (; i < zn; i++) {
+ zds[i] = 0;
}
- z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign);
- zds = BDIGITS(z);
+ goto finish;
- for (i=0; i<l1; i++) {
- zds[i] = ds1[i] | ds2[i];
- }
- for (; i<l2; i++) {
- zds[i] = sign?ds2[i]:(BIGRAD-1);
+ fill_hibits:
+ for (; i < zn; i++) {
+ zds[i] = BDIGMAX;
}
- if (!RBIGNUM(z)->sign) big_2comp(z);
+ finish:
+ twocomp2abs_bang(z, hibitsx || hibitsy);
+ RB_GC_GUARD(x);
return bignorm(z);
}
VALUE
-big_xor(x, y)
- VALUE x, y;
+rb_big_or(VALUE x, VALUE y)
{
VALUE z;
- USHORT *ds1, *ds2, *zds;
- unsigned int i, l1, l2;
- char sign;
+ BDIGIT *ds1, *ds2, *zds;
+ long i, xn, yn, n1, n2;
+ BDIGIT hibitsx, hibitsy;
+ BDIGIT hibits1, hibits2;
+ VALUE tmpv;
+ BDIGIT tmph;
+ long tmpn;
+
+ if (!RB_INTEGER_TYPE_P(y)) {
+ return rb_num_coerce_bit(x, y, '|');
+ }
+ hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
- y = int2big(FIX2LONG(y));
+ return bigor_int(x, xn, hibitsx, FIX2LONG(y));
}
- else {
- Check_Type(y, T_BIGNUM);
+ hibitsy = abs2twocomp(&y, &yn);
+ if (xn > yn) {
+ tmpv = x; x = y; y = tmpv;
+ tmpn = xn; xn = yn; yn = tmpn;
+ tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
+ n1 = xn;
+ n2 = yn;
+ ds1 = BDIGITS(x);
+ ds2 = BDIGITS(y);
+ hibits1 = hibitsx;
+ hibits2 = hibitsy;
- if (!RBIGNUM(y)->sign) {
- y = big_clone(y);
- big_2comp(y);
- }
- if (!RBIGNUM(x)->sign) {
- x = big_clone(x);
- big_2comp(x);
- }
- if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
- l1 = RBIGNUM(y)->len;
- l2 = RBIGNUM(x)->len;
- ds1 = BDIGITS(y);
- ds2 = BDIGITS(x);
- sign = RBIGNUM(y)->sign;
- }
- else {
- l1 = RBIGNUM(x)->len;
- l2 = RBIGNUM(y)->len;
- ds1 = BDIGITS(x);
- ds2 = BDIGITS(y);
- sign = RBIGNUM(x)->sign;
- }
- RBIGNUM(x)->sign = RBIGNUM(x)->sign?1:0;
- RBIGNUM(y)->sign = RBIGNUM(y)->sign?1:0;
- z = bignew(l2, !(RBIGNUM(x)->sign ^ RBIGNUM(y)->sign));
+ if (hibits1)
+ n2 = n1;
+
+ z = bignew(n2, 0);
zds = BDIGITS(z);
- for (i=0; i<l1; i++) {
- zds[i] = ds1[i] ^ ds2[i];
+ for (i=0; i<n1; i++) {
+ zds[i] = ds1[i] | ds2[i];
}
- for (; i<l2; i++) {
- zds[i] = sign?ds2[i]:~ds2[i];
+ for (; i<n2; i++) {
+ zds[i] = hibits1 | ds2[i];
}
- if (!RBIGNUM(z)->sign) big_2comp(z);
-
+ twocomp2abs_bang(z, hibits1 || hibits2);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
return bignorm(z);
}
-static VALUE big_rshift _((VALUE,VALUE));
-
-VALUE
-big_lshift(x, y)
- VALUE x, y;
+static VALUE
+bigxor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
{
- USHORT *xds, *zds;
- int shift = NUM2INT(y);
- unsigned int s1 = shift/BITSPERDIG;
- unsigned int s2 = shift%BITSPERDIG;
VALUE z;
- unsigned long num = 0;
- unsigned int len, i;
+ BDIGIT *xds, *zds;
+ long zn;
+ long i;
+ BDIGIT hibitsy;
- if (shift < 0) return big_rshift(x, INT2FIX(-shift));
+ hibitsy = 0 <= y ? 0 : BDIGMAX;
xds = BDIGITS(x);
- len = RBIGNUM(x)->len;
- z = bignew(len+s1+1, RBIGNUM(x)->sign);
+ zn = BIGNUM_LEN(x);
+#if SIZEOF_BDIGIT < SIZEOF_LONG
+ if (zn < bdigit_roomof(SIZEOF_LONG))
+ zn = bdigit_roomof(SIZEOF_LONG);
+#endif
+ z = bignew(zn, 0);
zds = BDIGITS(z);
- for (i=0; i<s1; i++) {
- *zds++ = 0;
+
+#if SIZEOF_BDIGIT >= SIZEOF_LONG
+ i = 1;
+ zds[0] = xds[0] ^ BIGLO(y);
+#else
+ for (i = 0; i < xn; i++) {
+ zds[i] = xds[i] ^ BIGLO(y);
+ y = BIGDN(y);
}
- for (i=0; i<len; i++) {
- num = num | *xds++<<s2;
- *zds++ = BIGLO(num);
- num = BIGDN(num);
+ for (; i < zn; i++) {
+ zds[i] = hibitsx ^ BIGLO(y);
+ y = BIGDN(y);
+ }
+#endif
+ for (; i < xn; i++) {
+ zds[i] = xds[i] ^ hibitsy;
+ }
+ for (; i < zn; i++) {
+ zds[i] = hibitsx ^ hibitsy;
}
- *zds = BIGLO(num);
+ twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
+ RB_GC_GUARD(x);
return bignorm(z);
}
-static VALUE
-big_rshift(x, y)
- VALUE x, y;
+VALUE
+rb_big_xor(VALUE x, VALUE y)
{
- USHORT *xds, *zds;
- int shift = NUM2INT(y);
- unsigned int s1 = shift/BITSPERDIG;
- unsigned int s2 = shift%BITSPERDIG;
VALUE z;
- unsigned long num = 0;
- unsigned int i = RBIGNUM(x)->len;
- unsigned int j;
+ BDIGIT *ds1, *ds2, *zds;
+ long i, xn, yn, n1, n2;
+ BDIGIT hibitsx, hibitsy;
+ BDIGIT hibits1, hibits2;
+ VALUE tmpv;
+ BDIGIT tmph;
+ long tmpn;
+
+ if (!RB_INTEGER_TYPE_P(y)) {
+ return rb_num_coerce_bit(x, y, '^');
+ }
- if (shift < 0) return big_lshift(x, INT2FIX(-shift));
- if (s1 > RBIGNUM(x)->len) {
- if (RBIGNUM(x)->sign)
- return INT2FIX(0);
- else
- return INT2FIX(-1);
+ hibitsx = abs2twocomp(&x, &xn);
+ if (FIXNUM_P(y)) {
+ return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
}
- xds = BDIGITS(x);
- i = RBIGNUM(x)->len; j = i - s1;
- z = bignew(j, RBIGNUM(x)->sign);
+ hibitsy = abs2twocomp(&y, &yn);
+ if (xn > yn) {
+ tmpv = x; x = y; y = tmpv;
+ tmpn = xn; xn = yn; yn = tmpn;
+ tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
+ }
+ n1 = xn;
+ n2 = yn;
+ ds1 = BDIGITS(x);
+ ds2 = BDIGITS(y);
+ hibits1 = hibitsx;
+ hibits2 = hibitsy;
+
+ z = bignew(n2, 0);
zds = BDIGITS(z);
- while (i--, j--) {
- num = (num | xds[i]) >> s2;
- zds[j] = BIGLO(num);
- num = BIGUP(xds[i]);
+
+ for (i=0; i<n1; i++) {
+ zds[i] = ds1[i] ^ ds2[i];
+ }
+ for (; i<n2; i++) {
+ zds[i] = hibitsx ^ ds2[i];
}
+ twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
+ RB_GC_GUARD(x);
+ RB_GC_GUARD(y);
return bignorm(z);
}
-static VALUE
-big_aref(x, y)
- VALUE x, y;
+VALUE
+rb_big_lshift(VALUE x, VALUE y)
{
- USHORT *xds;
- int shift = NUM2INT(y);
- unsigned int s1, s2;
+ int lshift_p;
+ size_t shift_numdigits;
+ int shift_numbits;
+
+ for (;;) {
+ if (FIXNUM_P(y)) {
+ long l = FIX2LONG(y);
+ unsigned long shift;
+ if (0 <= l) {
+ lshift_p = 1;
+ shift = l;
+ }
+ else {
+ lshift_p = 0;
+ shift = 1+(unsigned long)(-(l+1));
+ }
+ shift_numbits = (int)(shift & (BITSPERDIG-1));
+ shift_numdigits = shift >> bit_length(BITSPERDIG-1);
+ return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ return bignorm(big_shift2(x, 1, y));
+ }
+ y = rb_to_int(y);
+ }
+}
- if (shift < 0) return INT2FIX(0);
- s1 = shift/BITSPERDIG;
- s2 = shift%BITSPERDIG;
+VALUE
+rb_big_rshift(VALUE x, VALUE y)
+{
+ int lshift_p;
+ size_t shift_numdigits;
+ int shift_numbits;
+
+ for (;;) {
+ if (FIXNUM_P(y)) {
+ long l = FIX2LONG(y);
+ unsigned long shift;
+ if (0 <= l) {
+ lshift_p = 0;
+ shift = l;
+ }
+ else {
+ lshift_p = 1;
+ shift = 1+(unsigned long)(-(l+1));
+ }
+ shift_numbits = (int)(shift & (BITSPERDIG-1));
+ shift_numdigits = shift >> bit_length(BITSPERDIG-1);
+ return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
+ return bignorm(big_shift2(x, 0, y));
+ }
+ y = rb_to_int(y);
+ }
+}
- if (!RBIGNUM(x)->sign) {
- if (s1 >= RBIGNUM(x)->len) return INT2FIX(1);
- x = big_clone(x);
- big_2comp(x);
+VALUE
+rb_big_aref(VALUE x, VALUE y)
+{
+ BDIGIT *xds;
+ size_t shift;
+ size_t i, s1, s2;
+ long l;
+ BDIGIT bit;
+
+ if (RB_BIGNUM_TYPE_P(y)) {
+ if (BIGNUM_NEGATIVE_P(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
+ shift = big2ulong(y, "long");
+#else
+ shift = big2ull(y, "long long");
+#endif
}
else {
- if (s1 >= RBIGNUM(x)->len) return INT2FIX(0);
+ l = NUM2LONG(y);
+ if (l < 0) return INT2FIX(0);
+ shift = (size_t)l;
}
+ s1 = shift/BITSPERDIG;
+ s2 = shift%BITSPERDIG;
+ bit = (BDIGIT)1 << s2;
+
+ if (s1 >= BIGNUM_LEN(x)) goto out_of_range;
+
xds = BDIGITS(x);
- if (xds[s1] & (1<<s2))
- return INT2FIX(1);
- return INT2FIX(0);
+ if (BIGNUM_POSITIVE_P(x))
+ return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
+ if (xds[s1] & (bit-1))
+ return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
+ for (i = 0; i < s1; i++)
+ if (xds[i])
+ return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
+ return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
}
-static VALUE
-big_hash(x)
- VALUE x;
+VALUE
+rb_big_hash(VALUE x)
{
- int i, len, key;
- USHORT *digits;
+ st_index_t hash;
- key = 0; digits = BDIGITS(x);
- for (i=0,len=RBIGNUM(x)->len; i<RBIGNUM(x)->len; i++) {
- key ^= *digits++;
- }
- return INT2FIX(key);
+ hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
+ return ST2FIX(hash);
}
+/*
+ * call-seq:
+ * big.coerce(numeric) -> array
+ *
+ * Returns an array with both a +numeric+ and a +big+ represented as Bignum
+ * objects.
+ *
+ * This is achieved by converting +numeric+ to a Bignum.
+ *
+ * A TypeError is raised if the +numeric+ is not a Fixnum or Bignum type.
+ *
+ * (0x3FFFFFFFFFFFFFFF+1).coerce(42) #=> [42, 4611686018427387904]
+ */
+
static VALUE
-big_coerce(x, y)
- VALUE x, y;
+rb_int_coerce(VALUE x, VALUE y)
{
- if (FIXNUM_P(y)) {
- return assoc_new(int2big(FIX2LONG(y)), x);
+ if (RB_INTEGER_TYPE_P(y)) {
+ return rb_assoc_new(y, x);
}
else {
- TypeError("can't coerce %s to Bignum", rb_class2name(CLASS_OF(y)));
+ x = rb_Float(x);
+ y = rb_Float(y);
+ return rb_assoc_new(y, x);
}
- /* not reached */
}
-static VALUE
-big_abs(x)
- VALUE x;
+VALUE
+rb_big_abs(VALUE x)
{
- if (!RBIGNUM(x)->sign) {
- x = big_clone(x);
- RBIGNUM(x)->sign = 1;
+ if (BIGNUM_NEGATIVE_P(x)) {
+ x = rb_big_clone(x);
+ BIGNUM_SET_POSITIVE_SIGN(x);
}
return x;
}
-/* !!!warnig!!!!
- this is not really a random number!!
-*/
+int
+rb_big_sign(VALUE x)
+{
+ return BIGNUM_SIGN(x);
+}
+
+size_t
+rb_big_size(VALUE big)
+{
+ return BIGSIZE(big);
+}
VALUE
-big_rand(max)
- VALUE max;
+rb_big_size_m(VALUE big)
{
- struct RBignum *v;
- int len;
+ return SIZET2NUM(rb_big_size(big));
+}
- len = RBIGNUM(max)->len;
- v = RBIGNUM(bignew(len,1));
- while (len--) {
-#ifdef HAVE_RANDOM
- BDIGITS(v)[len] = random();
+VALUE
+rb_big_bit_length(VALUE big)
+{
+ int nlz_bits;
+ size_t numbytes;
+
+ static const BDIGIT char_bit[1] = { CHAR_BIT };
+ BDIGIT numbytes_bary[bdigit_roomof(sizeof(size_t))];
+ BDIGIT nlz_bary[1];
+ BDIGIT result_bary[bdigit_roomof(sizeof(size_t)+1)];
+
+ numbytes = rb_absint_size(big, &nlz_bits);
+
+ if (numbytes == 0)
+ return LONG2FIX(0);
+
+ if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
+ if (nlz_bits != CHAR_BIT-1) {
+ nlz_bits++;
+ }
+ else {
+ nlz_bits = 0;
+ numbytes--;
+ }
+ }
+
+ if (numbytes <= SIZE_MAX / CHAR_BIT) {
+ return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
+ }
+
+ nlz_bary[0] = nlz_bits;
+
+ bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
+ INTEGER_PACK_NATIVE_BYTE_ORDER);
+ BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
+ BARY_SUB(result_bary, result_bary, nlz_bary);
+
+ return rb_integer_unpack(result_bary, numberof(result_bary), sizeof(BDIGIT), 0,
+ INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
+}
+
+VALUE
+rb_big_odd_p(VALUE num)
+{
+ if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+VALUE
+rb_big_even_p(VALUE num)
+{
+ if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
+ return Qfalse;
+ }
+ return Qtrue;
+}
+
+unsigned long rb_ulong_isqrt(unsigned long);
+#if SIZEOF_BDIGIT*2 > SIZEOF_LONG
+BDIGIT rb_bdigit_dbl_isqrt(BDIGIT_DBL);
+# ifdef ULL_TO_DOUBLE
+# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
+# endif
#else
- BDIGITS(v)[len] = rand();
+# define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
+#endif
+#ifndef BDIGIT_DBL_TO_DOUBLE
+# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
+#endif
+
+static BDIGIT *
+estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len)
+{
+ enum {dbl_per_bdig = roomof(DBL_MANT_DIG,BITSPERDIG)};
+ const int zbits = nlz(nds[len-1]);
+ VALUE x = *xp = bignew_1(0, xn, 1); /* division may release the GVL */
+ BDIGIT *xds = BDIGITS(x);
+ BDIGIT_DBL d = bary2bdigitdbl(nds+len-dbl_per_bdig, dbl_per_bdig);
+ BDIGIT lowbits = 1;
+ int rshift = (int)((BITSPERDIG*2-zbits+(len&BITSPERDIG&1) - DBL_MANT_DIG + 1) & ~1);
+ double f;
+
+ if (rshift > 0) {
+ lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
+ d >>= rshift;
+ }
+ else if (rshift < 0) {
+ d <<= -rshift;
+ d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
+ }
+ f = sqrt(BDIGIT_DBL_TO_DOUBLE(d));
+ d = (BDIGIT_DBL)ceil(f);
+ if (BDIGIT_DBL_TO_DOUBLE(d) == f) {
+ if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
+ ++d;
+ }
+ else {
+ lowbits = 1;
+ }
+ rshift /= 2;
+ rshift += (2-(len&1))*BITSPERDIG/2;
+ if (rshift >= 0) {
+ d <<= rshift;
+ }
+ BDIGITS_ZERO(xds, xn-2);
+ bdigitdbl2bary(&xds[xn-2], 2, d);
+
+ if (!lowbits) return NULL; /* special case, exact result */
+ return xds;
+}
+
+VALUE
+rb_big_isqrt(VALUE n)
+{
+ BDIGIT *nds = BDIGITS(n);
+ size_t len = BIGNUM_LEN(n);
+ size_t xn = (len+1) / 2;
+ VALUE x;
+ BDIGIT *xds;
+
+ if (len <= 2) {
+ BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len));
+#if SIZEOF_BDIGIT > SIZEOF_LONG
+ return ULL2NUM(sq);
+#else
+ return ULONG2NUM(sq);
+#endif
+ }
+ else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) {
+ size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
+ VALUE t = bignew_1(0, tn, 1);
+ BDIGIT *tds = BDIGITS(t);
+ tn = BIGNUM_LEN(t);
+
+ /* t = n/x */
+ while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn),
+ bary_cmp(tds, tn, xds, xn) < 0) {
+ int carry;
+ BARY_TRUNC(tds, tn);
+ /* x = (x+t)/2 */
+ carry = bary_add(xds, xn, xds, xn, tds, tn);
+ bary_small_rshift(xds, xds, xn, 1, carry);
+ tn = BIGNUM_LEN(t);
+ }
+ rb_big_realloc(t, 0);
+ rb_gc_force_recycle(t);
+ }
+ RBASIC_SET_CLASS_RAW(x, rb_cInteger);
+ 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)
+{
+ const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
+ mpz_t z, x, y, m;
+ size_t count;
+ mpz_init(x);
+ mpz_init(y);
+ mpz_init(m);
+ mpz_init(z);
+ mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
+ mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
+ mpz_import(m, mn, -1, sizeof(BDIGIT), 0, nails, mds);
+ mpz_powm(z, x, y, m);
+ mpz_export(zds, &count, -1, sizeof(BDIGIT), 0, nails, z);
+ 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_funcall(z, '-', 1, 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;
- return big_mod(v, max);
+ for (/*NOP*/; ! FIXNUM_P(y); y = rb_funcall(y, rb_intern(">>"), 1, LONG2FIX(1L))) {
+ if (RTEST(rb_funcall(y, rb_intern("odd?"), 0))) {
+ tmp = rb_funcall(tmp, '*', 1, x);
+ tmp = rb_int_modulo(tmp, m);
+ }
+ x = rb_funcall(x, '*', 1, x);
+ x = rb_int_modulo(x, m);
+ }
+ for (yy = FIX2LONG(y); yy; yy >>= 1L) {
+ if (yy & 1L) {
+ tmp = rb_funcall(tmp, '*', 1, x);
+ tmp = rb_int_modulo(tmp, m);
+ }
+ x = rb_funcall(x, '*', 1, x);
+ x = rb_int_modulo(x, m);
+ }
+
+ if (nega_flg && RTEST(rb_funcall(tmp, rb_intern("positive?"), 0))) {
+ tmp = rb_funcall(tmp, '-', 1, m);
+ }
+ return tmp;
+#endif
}
+/*
+ * Integer#pow
+ */
+
static VALUE
-big_size(big)
- VALUE big;
+int_pow_tmp1(VALUE x, VALUE y, long mm, int nega_flg)
{
- return INT2FIX(RBIGNUM(big)->len*sizeof(USHORT));
+ long xx = FIX2LONG(x);
+ long tmp = 1L;
+ long yy;
+
+ for (/*NOP*/; ! FIXNUM_P(y); y = rb_funcall(y, idGTGT, 1, 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
-big_zero_p(big)
- VALUE big;
+int_pow_tmp2(VALUE x, VALUE y, long mm, int nega_flg)
{
- return FALSE;
+ 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_funcall(y, idGTGT, 1, 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_funcall(num, rb_intern("**"), 1, 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_num_negative_int_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_num_negative_int_p(m)) {
+ m = rb_funcall(m, idUMinus, 0);
+ nega_flg = 1;
+ }
+
+ if (!rb_num_positive_int_p(m)) {
+ rb_num_zerodiv();
+ }
+ if (FIXNUM_P(m)) {
+ long const half_val = (long)HALF_LONG_MSB;
+ long const mm = FIX2LONG(m);
+ 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_TYPE_P(m, T_BIGNUM)) {
+ return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
+ }
+ }
+ UNREACHABLE;
+}
+
+/*
+ * Bignum objects hold integers outside the range of
+ * Fixnum. Bignum objects are created
+ * automatically when integer calculations would otherwise overflow a
+ * Fixnum. When a calculation involving
+ * Bignum objects returns a result that will fit in a
+ * Fixnum, the result is automatically converted.
+ *
+ * For the purposes of the bitwise operations and <code>[]</code>, a
+ * Bignum is treated as if it were an infinite-length
+ * bitstring with 2's complement representation.
+ *
+ * While Fixnum values are immediate, Bignum
+ * objects are not---assignment and parameter passing work with
+ * references to objects, not the objects themselves.
+ *
+ */
+
void
-Init_Bignum()
-{
- cBignum = rb_define_class("Bignum", cInteger);
-
- rb_undef_method(CLASS_OF(cBignum), "new");
-
- rb_define_method(cBignum, "to_s", big_to_s, 0);
- rb_define_method(cBignum, "coerce", big_coerce, 1);
- rb_define_method(cBignum, "-@", big_uminus, 0);
- rb_define_method(cBignum, "+", big_plus, 1);
- rb_define_method(cBignum, "-", big_minus, 1);
- rb_define_method(cBignum, "*", big_mul, 1);
- rb_define_method(cBignum, "/", big_div, 1);
- rb_define_method(cBignum, "%", big_mod, 1);
- rb_define_method(cBignum, "divmod", big_divmod, 1);
- rb_define_method(cBignum, "remainder", big_remainder, 1);
- rb_define_method(cBignum, "**", big_pow, 1);
- rb_define_method(cBignum, "&", big_and, 1);
- rb_define_method(cBignum, "|", big_or, 1);
- rb_define_method(cBignum, "^", big_xor, 1);
- rb_define_method(cBignum, "~", big_neg, 0);
- rb_define_method(cBignum, "<<", big_lshift, 1);
- rb_define_method(cBignum, ">>", big_rshift, 1);
- rb_define_method(cBignum, "[]", big_aref, 1);
-
- rb_define_method(cBignum, "<=>", big_cmp, 1);
- rb_define_method(cBignum, "==", big_eq, 1);
- rb_define_method(cBignum, "eql?", big_eq, 1);
- rb_define_method(cBignum, "hash", big_hash, 0);
- rb_define_method(cBignum, "to_i", big_to_i, 0);
- rb_define_method(cBignum, "to_f", big_to_f, 0);
- rb_define_method(cBignum, "abs", big_abs, 0);
- rb_define_method(cBignum, "size", big_size, 0);
- rb_define_method(cBignum, "zero?", big_zero_p, 0);
+Init_Bignum(void)
+{
+#ifndef RUBY_INTEGER_UNIFICATION
+ rb_cBignum = rb_cInteger;
+#endif
+ rb_define_const(rb_cObject, "Bignum", rb_cInteger);
+ rb_deprecate_constant(rb_cObject, "Bignum");
+
+ rb_define_method(rb_cInteger, "coerce", rb_int_coerce, 1);
+
+#ifdef USE_GMP
+ /* The version of loaded GMP. */
+ rb_define_const(rb_cInteger, "GMP_VERSION", rb_sprintf("GMP %s", gmp_version));
+#endif
+
+ power_cache_init();
}
diff --git a/bin/erb b/bin/erb
new file mode 100755
index 0000000000..86f7042fae
--- /dev/null
+++ b/bin/erb
@@ -0,0 +1,171 @@
+#!/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::UTF_8, 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
+ end
+end
+
+if __FILE__ == $0
+ ERB::Main.run
+end
diff --git a/bin/gem b/bin/gem
new file mode 100755
index 0000000000..a4ec754abb
--- /dev/null
+++ b/bin/gem
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+require 'rubygems'
+require 'rubygems/gem_runner'
+require 'rubygems/exceptions'
+
+required_version = Gem::Requirement.new ">= 1.8.7"
+
+unless required_version.satisfied_by? Gem.ruby_version then
+ abort "Expected Ruby Version #{required_version}, is #{Gem.ruby_version}"
+end
+
+args = ARGV.clone
+
+begin
+ Gem::GemRunner.new.run args
+rescue Gem::SystemExitException => e
+ exit e.exit_code
+end
+
diff --git a/bin/irb b/bin/irb
new file mode 100755
index 0000000000..c64ee85fbd
--- /dev/null
+++ b/bin/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/bin/rdoc b/bin/rdoc
new file mode 100755
index 0000000000..aaa23292df
--- /dev/null
+++ b/bin/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/bin/ri b/bin/ri
new file mode 100755
index 0000000000..7fbed0c099
--- /dev/null
+++ b/bin/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/bootstraptest/pending.rb b/bootstraptest/pending.rb
new file mode 100644
index 0000000000..744c0adac1
--- /dev/null
+++ b/bootstraptest/pending.rb
@@ -0,0 +1,39 @@
+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{
+ proc{
+ return :ng1
+ }
+ }.call.call
+ :ng2
+ end
+
+ begin
+ m()
+ rescue LocalJumpError
+ :ok
+ end
+}
+
+assert_normal_exit %q{
+ r = Range.allocate
+ def r.<=>(o) true end
+ r.instance_eval { initialize r, r }
+ r.inspect
+}
diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb
new file mode 100755
index 0000000000..e807ce5b62
--- /dev/null
+++ b/bootstraptest/runner.rb
@@ -0,0 +1,505 @@
+"exec" "${RUBY-ruby}" "-x" "$0" "$@" || true # -*- mode: ruby; coding: utf-8 -*-
+#!./ruby
+# $Id$
+
+# NOTE:
+# Never use optparse in this file.
+# Never use test/unit in this file.
+# Never use Ruby extensions in this file.
+
+begin
+ require 'fileutils'
+ require 'tmpdir'
+rescue LoadError
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
+ retry
+end
+
+if !Dir.respond_to?(:mktmpdir)
+ # copied from lib/tmpdir.rb
+ def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
+ case prefix_suffix
+ when nil
+ prefix = "d"
+ suffix = ""
+ when String
+ prefix = prefix_suffix
+ suffix = ""
+ when Array
+ prefix = prefix_suffix[0]
+ suffix = prefix_suffix[1]
+ else
+ raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
+ end
+ tmpdir ||= Dir.tmpdir
+ t = Time.now.strftime("%Y%m%d")
+ n = nil
+ begin
+ path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
+ path << "-#{n}" if n
+ path << suffix
+ Dir.mkdir(path, 0700)
+ rescue Errno::EEXIST
+ n ||= 0
+ n += 1
+ retry
+ end
+
+ if block_given?
+ begin
+ yield path
+ ensure
+ FileUtils.remove_entry_secure path
+ end
+ else
+ path
+ end
+ end
+end
+
+def main
+ @ruby = File.expand_path('miniruby')
+ @verbose = false
+ $VERBOSE = false
+ $stress = false
+ @color = nil
+ @tty = nil
+ @quiet = false
+ dir = nil
+ quiet = false
+ tests = nil
+ ARGV.delete_if {|arg|
+ case arg
+ when /\A--ruby=(.*)/
+ @ruby = $1
+ @ruby.gsub!(/^([^ ]*)/){File.expand_path($1)}
+ @ruby.gsub!(/(\s+-I\s*)((?!(?:\.\/)*-(?:\s|\z))\S+)/){$1+File.expand_path($2)}
+ @ruby.gsub!(/(\s+-r\s*)(\.\.?\/\S+)/){$1+File.expand_path($2)}
+ true
+ when /\A--sets=(.*)/
+ tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb").sort
+ puts tests.map {|path| File.basename(path) }.inspect
+ true
+ when /\A--dir=(.*)/
+ dir = $1
+ true
+ when /\A(--stress|-s)/
+ $stress = true
+ when /\A--color(?:=(?:always|(auto)|(never)|(.*)))?\z/
+ warn "unknown --color argument: #$3" if $3
+ @color = $1 ? nil : !$2
+ true
+ when /\A--tty(=(?:yes|(no)|(.*)))?\z/
+ warn "unknown --tty argument: #$3" if $3
+ @tty = !$1 || !$2
+ true
+ when /\A(-q|--q(uiet))\z/
+ quiet = true
+ @quiet = true
+ true
+ when /\A(-v|--v(erbose))\z/
+ @verbose = true
+ when /\A(-h|--h(elp)?)\z/
+ puts(<<-End)
+Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...]
+ --sets=NAME,NAME,... Name of test sets.
+ --dir=DIRECTORY Working directory.
+ default: /tmp/bootstraptestXXXXX.tmpwd
+ --color[=WHEN] Colorize the output. WHEN defaults to 'always'
+ or can be 'never' or 'auto'.
+ -s, --stress stress test.
+ -v, --verbose Output test name before exec.
+ -q, --quiet Don\'t print header message.
+ -h, --help Print this message and quit.
+End
+ exit true
+ when /\A-j/
+ true
+ else
+ false
+ end
+ }
+ if tests and not ARGV.empty?
+ $stderr.puts "--tests and arguments are exclusive"
+ exit false
+ end
+ tests ||= ARGV
+ tests = Dir.glob("#{File.dirname($0)}/test_*.rb").sort if tests.empty?
+ pathes = tests.map {|path| File.expand_path(path) }
+
+ @progress = %w[- \\ | /]
+ @progress_bs = "\b" * @progress[0].size
+ @tty = $stderr.tty? if @tty.nil?
+ case @color
+ when nil
+ @color = @tty && /dumb/ !~ ENV["TERM"]
+ end
+ @tty &&= !@verbose
+ if @color
+ # 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|
+ colors[n] ||= c
+ end
+ rescue
+ end
+ @passed = "\e[;#{colors["pass"] || "32"}m"
+ @failed = "\e[;#{colors["fail"] || "31"}m"
+ @reset = "\e[m"
+ else
+ @passed = @failed = @reset = ""
+ end
+ unless quiet
+ puts Time.now
+ if defined?(RUBY_DESCRIPTION)
+ puts "Driver is #{RUBY_DESCRIPTION}"
+ elsif defined?(RUBY_PATCHLEVEL)
+ puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}#{RUBY_PLATFORM}) [#{RUBY_PLATFORM}]"
+ else
+ puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
+ end
+ puts "Target is #{`#{@ruby} -v`.chomp}"
+ puts
+ $stdout.flush
+ end
+
+ in_temporary_working_directory(dir) {
+ exec_test pathes
+ }
+end
+
+def erase(e = true)
+ if e and @columns > 0 and !@verbose
+ "\r#{" "*@columns}\r"
+ else
+ ""
+ end
+end
+
+def exec_test(pathes)
+ @count = 0
+ @error = 0
+ @errbuf = []
+ @location = nil
+ @columns = 0
+ @width = pathes.map {|path| File.basename(path).size}.max + 2
+ pathes.each do |path|
+ @basename = File.basename(path)
+ $stderr.printf("%s%-*s ", erase(@quiet), @width, @basename)
+ $stderr.flush
+ @columns = @width + 1
+ $stderr.puts if @verbose
+ count = @count
+ error = @error
+ load File.expand_path(path)
+ if @tty
+ if @error == error
+ msg = "PASS #{@count-count}"
+ @columns += msg.size - 1
+ $stderr.print "#{@progress_bs}#{@passed}#{msg}#{@reset}"
+ else
+ msg = "FAIL #{@error-error}/#{@count-count}"
+ $stderr.print "#{@progress_bs}#{@failed}#{msg}#{@reset}"
+ @columns = 0
+ end
+ end
+ $stderr.puts unless @quiet and @tty and @error == error
+ end
+ $stderr.print(erase) if @quiet
+ if @error == 0
+ if @count == 0
+ $stderr.puts "No tests, no problem"
+ else
+ $stderr.puts "#{@passed}PASS#{@reset} all #{@count} tests"
+ end
+ exit true
+ else
+ @errbuf.each do |msg|
+ $stderr.puts msg
+ end
+ $stderr.puts "#{@failed}FAIL#{@reset} #{@error}/#{@count} tests failed"
+ exit false
+ end
+end
+
+def show_progress(message = '')
+ if @verbose
+ $stderr.print "\##{@count} #{@location} "
+ elsif @tty
+ $stderr.print "#{@progress_bs}#{@progress[@count % @progress.size]}"
+ end
+ t = Time.now if @verbose
+ faildesc, errout = with_stderr {yield}
+ t = Time.now - t if @verbose
+ if !faildesc
+ if @tty
+ $stderr.print "#{@progress_bs}#{@progress[@count % @progress.size]}"
+ elsif @verbose
+ $stderr.printf(". %.3f\n", t)
+ else
+ $stderr.print '.'
+ end
+ else
+ $stderr.print "#{@failed}F"
+ $stderr.printf(" %.3f", t) if @verbose
+ $stderr.print "#{@reset}"
+ $stderr.puts if @verbose
+ error faildesc, message
+ unless errout.empty?
+ $stderr.print "#{@failed}stderr output is not empty#{@reset}\n", adjust_indent(errout)
+ end
+ if @tty and !@verbose
+ $stderr.printf("%-*s%s", @width, @basename, @progress[@count % @progress.size])
+ end
+ end
+rescue Interrupt
+ $stderr.puts "\##{@count} #{@location}"
+ raise Interrupt
+rescue Exception => err
+ $stderr.print 'E'
+ $stderr.puts if @verbose
+ error err.message, message
+end
+
+def assert_check(testsrc, message = '', opt = '', **argh)
+ show_progress(message) {
+ result = get_result_string(testsrc, opt, **argh)
+ check_coredump
+ yield(result)
+ }
+end
+
+def assert_equal(expected, testsrc, message = '', opt = '', **argh)
+ newtest
+ assert_check(testsrc, message, opt, **argh) {|result|
+ if expected == result
+ nil
+ else
+ desc = "#{result.inspect} (expected #{expected.inspect})"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_match(expected_pattern, testsrc, message = '')
+ newtest
+ assert_check(testsrc, message) {|result|
+ if expected_pattern =~ result
+ nil
+ else
+ desc = "#{expected_pattern.inspect} expected to be =~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_not_match(unexpected_pattern, testsrc, message = '')
+ newtest
+ assert_check(testsrc, message) {|result|
+ if unexpected_pattern !~ result
+ nil
+ else
+ desc = "#{unexpected_pattern.inspect} expected to be !~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_valid_syntax(testsrc, message = '')
+ newtest
+ assert_check(testsrc, message, '-c') {|result|
+ result if /Syntax OK/ !~ result
+ }
+end
+
+def assert_normal_exit(testsrc, *rest, timeout: nil, **opt)
+ newtest
+ message, ignore_signals = rest
+ message ||= ''
+ show_progress(message) {
+ faildesc = nil
+ filename = make_srcfile(testsrc)
+ old_stderr = $stderr.dup
+ timeout_signaled = false
+ begin
+ $stderr.reopen("assert_normal_exit.log", "w")
+ io = IO.popen("#{@ruby} -W0 #{filename}")
+ pid = io.pid
+ th = Thread.new {
+ io.read
+ io.close
+ $?
+ }
+ if !th.join(timeout)
+ Process.kill :KILL, pid
+ timeout_signaled = true
+ end
+ status = th.value
+ ensure
+ $stderr.reopen(old_stderr)
+ old_stderr.close
+ end
+ if status && status.signaled?
+ signo = status.termsig
+ signame = Signal.list.invert[signo]
+ unless ignore_signals and ignore_signals.include?(signame)
+ sigdesc = "signal #{signo}"
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if timeout_signaled
+ sigdesc << " (timeout)"
+ end
+ faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
+ stderr_log = File.read("assert_normal_exit.log")
+ if !stderr_log.empty?
+ faildesc << "\n" if /\n\z/ !~ faildesc
+ stderr_log << "\n" if /\n\z/ !~ stderr_log
+ stderr_log.gsub!(/^.*\n/) { '| ' + $& }
+ faildesc << stderr_log
+ end
+ end
+ end
+ faildesc
+ }
+end
+
+def assert_finish(timeout_seconds, testsrc, message = '')
+ newtest
+ show_progress(message) {
+ faildesc = nil
+ filename = make_srcfile(testsrc)
+ io = IO.popen("#{@ruby} -W0 #{filename}")
+ pid = io.pid
+ waited = false
+ tlimit = Time.now + timeout_seconds
+ while Time.now < tlimit
+ if Process.waitpid pid, Process::WNOHANG
+ waited = true
+ break
+ end
+ sleep 0.1
+ end
+ if !waited
+ Process.kill(:KILL, pid)
+ Process.waitpid pid
+ faildesc = pretty(testsrc, "not finished in #{timeout_seconds} seconds", nil)
+ end
+ io.close
+ faildesc
+ }
+end
+
+def flunk(message = '')
+ newtest
+ show_progress('') { message }
+end
+
+def pretty(src, desc, result)
+ src = src.sub(/\A\s*\n/, '')
+ (/\n/ =~ src ? "\n#{adjust_indent(src)}" : src) + " #=> #{desc}"
+end
+
+INDENT = 27
+
+def adjust_indent(src)
+ untabify(src).gsub(/^ {#{INDENT}}/o, '').gsub(/^/, ' ').sub(/\s*\z/, "\n")
+end
+
+def untabify(str)
+ str.gsub(/^\t+/) {' ' * (8 * $&.size) }
+end
+
+def make_srcfile(src, frozen_string_literal: nil)
+ filename = 'bootstraptest.tmp.rb'
+ File.open(filename, 'w') {|f|
+ f.puts "#frozen_string_literal:true" if frozen_string_literal
+ f.puts "GC.stress = true" if $stress
+ f.puts "print(begin; #{src}; end)"
+ }
+ filename
+end
+
+def get_result_string(src, opt = '', **argh)
+ if @ruby
+ filename = make_srcfile(src, **argh)
+ begin
+ `#{@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
+ end
+end
+
+def with_stderr
+ out = err = nil
+ begin
+ r, w = IO.pipe
+ stderr = $stderr.dup
+ $stderr.reopen(w)
+ w.close
+ reader = Thread.start {r.read}
+ begin
+ out = yield
+ ensure
+ $stderr.reopen(stderr)
+ err = reader.value
+ end
+ ensure
+ w.close rescue nil
+ r.close rescue nil
+ end
+ return out, err
+end
+
+def newtest
+ @location = File.basename(caller(2).first)
+ @count += 1
+ cleanup_coredump
+end
+
+def error(msg, additional_message)
+ msg = "#{@failed}\##{@count} #{@location}#{@reset}: #{msg} #{additional_message}"
+ if @tty
+ $stderr.puts "#{erase}#{msg}"
+ else
+ @errbuf.push msg
+ end
+ @error += 1
+end
+
+def in_temporary_working_directory(dir)
+ if dir
+ Dir.mkdir dir
+ Dir.chdir(dir) {
+ yield
+ }
+ else
+ Dir.mktmpdir(["bootstraptest", ".tmpwd"]) {|d|
+ Dir.chdir(d) {
+ yield
+ }
+ }
+ end
+end
+
+def cleanup_coredump
+ FileUtils.rm_f 'core'
+ FileUtils.rm_f Dir.glob('core.*')
+ FileUtils.rm_f @ruby+'.stackdump' if @ruby
+end
+
+class CoreDumpError < StandardError; end
+
+def check_coredump
+ if File.file?('core') or not Dir.glob('core.*').empty? or
+ (@ruby and File.exist?(@ruby+'.stackdump'))
+ raise CoreDumpError, "core dumped"
+ end
+end
+
+main
diff --git a/bootstraptest/test_attr.rb b/bootstraptest/test_attr.rb
new file mode 100644
index 0000000000..721a847145
--- /dev/null
+++ b/bootstraptest/test_attr.rb
@@ -0,0 +1,36 @@
+assert_equal 'ok', %q{
+ module M
+ class A
+ class << self
+ attr_accessor :at
+ def workflow_rule
+ yield self
+ end
+
+ def eval_str(str)
+ eval(str)
+ end
+ end
+ end
+ end
+ begin
+ M::A.eval_str(<<-END)
+ workflow_rule do |r|
+ r.at 1
+ end
+ END
+ rescue ArgumentError => e
+ print "ok"
+ end
+}, '[ruby-core:14641]'
+
+assert_equal %{ok}, %{
+ class A
+ attr :m
+ end
+ begin
+ A.new.m(3)
+ rescue ArgumentError => e
+ print "ok"
+ end
+}, '[ruby-core:15120]'
diff --git a/bootstraptest/test_autoload.rb b/bootstraptest/test_autoload.rb
new file mode 100644
index 0000000000..a9f8e6dacd
--- /dev/null
+++ b/bootstraptest/test_autoload.rb
@@ -0,0 +1,70 @@
+assert_equal 'ok', %q{
+ File.unlink('zzz.rb') if File.file?('zzz.rb')
+ instance_eval do
+ autoload :ZZZ, './zzz.rb'
+ begin
+ ZZZ
+ rescue LoadError
+ :ok
+ end
+ end
+}, '[ruby-dev:43816]'
+
+assert_equal 'ok', %q{
+ open('zzz.rb', 'w') {|f| f.puts '' }
+ instance_eval do
+ autoload :ZZZ, './zzz.rb'
+ begin
+ ZZZ
+ rescue NameError
+ :ok
+ end
+ end
+}, '[ruby-dev:43816]'
+
+assert_equal 'ok', %q{
+ open('zzz.rb', 'w') {|f| f.puts 'class ZZZ; def self.ok;:ok;end;end'}
+ instance_eval do
+ autoload :ZZZ, './zzz.rb'
+ ZZZ.ok
+ end
+}, '[ruby-dev:43816]'
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ ZZZ.ok
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ require "./zzz.rb"
+ ZZZ.ok
+}
+
+assert_equal 'okok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ t1 = Thread.new {ZZZ.ok}
+ t2 = Thread.new {ZZZ.ok}
+ [t1.value, t2.value].join
+}
+
+assert_finish 5, %q{
+ autoload :ZZZ, File.expand_path(__FILE__)
+ begin
+ ZZZ
+ rescue NameError
+ end
+}, '[ruby-core:21696]'
+
+assert_equal 'A::C', %q{
+ open("zzz.rb", "w") {}
+ class A
+ autoload :C, "./zzz"
+ class C
+ end
+ C
+ end
+}
diff --git a/bootstraptest/test_block.rb b/bootstraptest/test_block.rb
new file mode 100644
index 0000000000..cdc5960a59
--- /dev/null
+++ b/bootstraptest/test_block.rb
@@ -0,0 +1,613 @@
+assert_equal %q{1}, %q{
+ 1.times{
+ begin
+ a = 1
+ ensure
+ foo = nil
+ end
+ }
+}
+assert_equal %q{2}, %q{
+ [1,2,3].find{|x| x == 2}
+}
+assert_equal %q{2}, %q{
+ class E
+ include Enumerable
+ def each(&block)
+ [1, 2, 3].each(&block)
+ end
+ end
+ E.new.find {|x| x == 2 }
+}
+assert_equal %q{6}, %q{
+ sum = 0
+ for x in [1, 2, 3]
+ sum += x
+ end
+ sum
+}
+assert_equal %q{15}, %q{
+ sum = 0
+ for x in (1..5)
+ sum += x
+ end
+ sum
+}
+assert_equal %q{0}, %q{
+ sum = 0
+ for x in []
+ sum += x
+ end
+ sum
+}
+assert_equal %q{1}, %q{
+ ans = []
+ 1.times{
+ for n in 1..3
+ a = n
+ ans << a
+ end
+ }
+}
+assert_equal %q{1..3}, %q{
+ ans = []
+ for m in 1..3
+ for n in 1..3
+ a = [m, n]
+ ans << a
+ end
+ end
+}
+assert_equal %q{[1, 2, 3]}, %q{
+ (1..3).to_a
+}
+assert_equal %q{[4, 8, 12]}, %q{
+ (1..3).map{|e|
+ e * 4
+ }
+}
+assert_equal %q{[1, 2, 3]}, %q{
+ class C
+ include Enumerable
+ def each
+ [1,2,3].each{|e|
+ yield e
+ }
+ end
+ end
+
+ C.new.to_a
+}
+assert_equal %q{[4, 5, 6]}, %q{
+ class C
+ include Enumerable
+ def each
+ [1,2,3].each{|e|
+ yield e
+ }
+ end
+ end
+
+ C.new.map{|e|
+ e + 3
+ }
+}
+assert_equal %q{100}, %q{
+ def m
+ yield
+ end
+ def n
+ yield
+ end
+
+ m{
+ n{
+ 100
+ }
+ }
+}
+assert_equal %q{20}, %q{
+ def m
+ yield 1
+ end
+
+ m{|ib|
+ m{|jb|
+ i = 20
+ }
+ }
+}
+assert_equal %q{2}, %q{
+ def m
+ yield 1
+ end
+
+ m{|ib|
+ m{|jb|
+ ib = 20
+ kb = 2
+ }
+ }
+}
+assert_equal %q{3}, %q{
+ def iter1
+ iter2{
+ yield
+ }
+ end
+
+ def iter2
+ yield
+ end
+
+ iter1{
+ jb = 2
+ iter1{
+ jb = 3
+ }
+ jb
+ }
+}
+assert_equal %q{2}, %q{
+ def iter1
+ iter2{
+ yield
+ }
+ end
+
+ def iter2
+ yield
+ end
+
+ iter1{
+ jb = 2
+ iter1{
+ jb
+ }
+ jb
+ }
+}
+assert_equal %q{2}, %q{
+ def m
+ yield 1
+ end
+ m{|ib|
+ ib*2
+ }
+}
+assert_equal %q{92580}, %q{
+ def m
+ yield 12345, 67890
+ end
+ m{|ib,jb|
+ ib*2+jb
+ }
+}
+assert_equal %q{[10, nil]}, %q{
+ def iter
+ yield 10
+ end
+
+ a = nil
+ [iter{|a|
+ a
+ }, a]
+}
+assert_equal %q{21}, %q{
+ def iter
+ yield 10
+ end
+
+ iter{|a|
+ iter{|a|
+ a + 1
+ } + a
+ }
+}
+assert_equal %q{[10, 20, 30, 40, nil, nil, nil, nil]}, %q{
+ def iter
+ yield 10, 20, 30, 40
+ end
+
+ a = b = c = d = nil
+ iter{|a, b, c, d|
+ [a, b, c, d]
+ } + [a, b, c, d]
+}
+assert_equal %q{[10, 20, 30, 40, nil, nil]}, %q{
+ def iter
+ yield 10, 20, 30, 40
+ end
+
+ a = b = nil
+ iter{|a, b, c, d|
+ [a, b, c, d]
+ } + [a, b]
+}
+assert_equal %q{[1]}, %q{
+ $a = []
+
+ def iter
+ yield 1
+ end
+
+ def m
+ x = iter{|x|
+ $a << x
+ y = 0
+ }
+ end
+ m
+ $a
+}
+assert_equal %q{[1, [2]]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, *b|
+ [a, b]
+ }
+}
+assert_equal %q{[[1, 2]]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|*a|
+ [a]
+ }
+}
+assert_equal %q{[1, 2, []]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, b, *c|
+ [a, b, c]
+ }
+}
+assert_equal %q{[1, 2, nil, []]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, b, c, *d|
+ [a, b, c, d]
+ }
+}
+assert_equal %q{1}, %q{
+ def m
+ yield
+ end
+ m{
+ 1
+ }
+}
+assert_equal %q{15129}, %q{
+ def m
+ yield 123
+ end
+ m{|ib|
+ m{|jb|
+ ib*jb
+ }
+ }
+}
+assert_equal %q{2}, %q{
+ def m a
+ yield a
+ end
+ m(1){|ib|
+ m(2){|jb|
+ ib*jb
+ }
+ }
+}
+assert_equal %q{9}, %q{
+ sum = 0
+ 3.times{|ib|
+ 2.times{|jb|
+ sum += ib + jb
+ }}
+ sum
+}
+assert_equal %q{10}, %q{
+ 3.times{|bl|
+ break 10
+ }
+}
+assert_equal %q{[1, 2]}, %q{
+ def iter
+ yield 1,2,3
+ end
+
+ iter{|i, j|
+ [i, j]
+ }
+}
+assert_equal %q{[1, nil]}, %q{
+ def iter
+ yield 1
+ end
+
+ iter{|i, j|
+ [i, j]
+ }
+}
+
+assert_equal '0', %q{
+def m()
+end
+m {|(v0,*,(*)),|}
+m {|(*v0,(*)),|}
+m {|(v0,*v1,(*)),|}
+m {|((v0,*v1,v2)),|}
+m {|(v0,*v1,v2),|}
+m {|(v0,*v1,(v2)),|}
+m {|((*),*v0,v1),|}
+m {|((v0),*v1,v2),|}
+m {|(v0,v1,*v2,v3),|}
+m {|v0,(v1,*v2,v3),|}
+m {|(v0,*v1,v2),v3,|}
+m {|(v0,*v1,v2)|}
+m {|(v0,*v1,v2),&v3|}
+m {|(v0,*v1,v2),*|}
+m {|(v0,*v1,v2),*,&v3|}
+m {|*,(v0,*v1,v2)|}
+m {|*,(v0,*v1,v2),&v3|}
+m {|v0,*,(v1,*v2,v3)|}
+m {|v0,*,(v1,*v2,v3),&v4|}
+m {|(v0,*v1,v2),*,v3|}
+m {|(v0,*v1,v2),*,v3,&v4|}
+m {|(v0, *v1, v2)|}
+m {|(*,v)|}
+0
+}, "block parameter (shouldn't SEGV: [ruby-dev:31143])"
+
+assert_equal 'nil', %q{
+ def m
+ yield
+ end
+ m{|&b| b}.inspect
+}, '[ruby-dev:31147]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|(v,(*))|}.inspect
+}, '[ruby-dev:31160]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|(*,a,b)|}.inspect
+}, '[ruby-dev:31153]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|((*))|}.inspect
+}
+
+assert_equal %q{[1, 1, [1, nil], [1, nil], [1, nil], [1, nil], [1, 1], 1, [1, nil], [1, nil], [1, nil], [1, nil], [[1, 1], [1, 1]], [1, 1], [1, 1], [1, 1], [1, nil], [1, nil], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [1, 1], [1, 1], [[[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]]}, %q{
+def m(ary = [])
+ yield(ary)
+end
+
+$ans = []
+o = 1
+5.times{
+ v,(*) = o; $ans << o
+ m(o){|(v,(*))| $ans << v}
+ ((x, y)) = o; $ans << [x, y]
+ m(o){|((x, y))| $ans << [x, y]}
+ (((x, y))) = o; $ans << [x, y]
+ m(o){|(((x, y)))| $ans << [x, y]}
+ o = [o, o]
+}; $ans
+}
+
+assert_equal '0', %q{
+ def m()
+ yield [0]
+ end
+ m {|*,v| v}.inspect
+}, '[ruby-dev:31437]'
+assert_equal '[0]', %q{
+ def m
+ yield [0]
+ end
+ m{|v, &b| v}.inspect
+}, '[ruby-dev:31440]'
+assert_equal 'ok', %q{
+ begin
+ lambda{|a|}.call(1, 2)
+ rescue ArgumentError
+ :ok
+ else
+ :ng
+ end
+}, '[ruby-dev:31464]'
+assert_equal 'ok', %q{
+ begin
+ lambda{|&b|}.call(3)
+ rescue ArgumentError
+ :ok
+ else
+ :ng
+ end
+}, '[ruby-dev:31472]'
+assert_equal 'ok', %q{
+ class C
+ def each
+ yield [1,2]
+ yield 1,2
+ end
+ end
+ vs1 = []
+ C.new.each {|*v| vs1 << v }
+ vs2 = []
+ C.new.to_enum.each {|*v| vs2 << v }
+ vs1 == vs2 ? :ok : :ng
+}, '[ruby-dev:32329]'
+
+assert_normal_exit %q{
+ e = [1,2,3].each
+ 10000.times {
+ e = [e].each
+ }
+ Thread.new { GC.start }.join
+}, '[ruby-dev:32604]'
+
+
+assert_equal '[nil, []]', %q{
+ def m() yield nil,[] end
+ l = lambda {|*v| v}
+ GC.stress=true
+ r = m(&l)
+ GC.stress=false
+ r.inspect
+}, '[ruby-dev:32567]'
+
+assert_equal NilClass.to_s, %q{
+ r = false; 1.times{|&b| r = b}; r.class
+}
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:foo) do |arg, &block|
+ if block then block.call else arg end
+ end
+ end
+ C.new.foo("ng") {"ok"}
+}, '[ruby-talk:266422]'
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:xyz) do |o, k, &block|
+ block.call(o, k)
+ end
+ end
+ C.new.xyz("o","k") {|o, k| o+k}
+}, '[ruby-core:20544]'
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:xyz) do |*args, &block|
+ block.call(*args)
+ end
+ end
+ C.new.xyz("o","k") {|*args| args.join("")}
+}, '[ruby-core:20544]'
+
+assert_equal 'ok', %q{
+ STDERR.reopen(STDOUT)
+ class C
+ define_method(:foo) do |&block|
+ block.call if block
+ end
+ result = "ng"
+ new.foo() {result = "ok"}
+ result
+ end
+}
+
+assert_equal "ok", %q{
+ class Bar
+ def bar; :ok; end
+ end
+ def foo
+ yield(Bar.new) if block_given?
+ end
+ foo(&:bar)
+}, '[ruby-core:14279]'
+
+assert_normal_exit %q{
+ class Controller
+ def respond_to(&block)
+ responder = Responder.new
+ block.call(responder)
+ responder.respond
+ end
+ def test_for_bug
+ respond_to{|format|
+ format.js{
+ puts "in test"
+ render{|obj|
+ puts obj
+ }
+ }
+ }
+ end
+ def render(&block)
+ puts "in render"
+ end
+ end
+
+ class Responder
+ def method_missing(symbol, &block)
+ puts "enter method_missing"
+ @response = Proc.new{
+ puts 'in method missing'
+ block.call
+ }
+ puts "leave method_missing"
+ end
+ def respond
+ @response.call
+ end
+ end
+ t = Controller.new
+ t.test_for_bug
+}, '[ruby-core:14395]'
+
+assert_equal 'true', %q{
+ class C0
+ def foo
+ block_given?
+ end
+ end
+
+ class C1 < C0
+ def foo
+ super
+ end
+ end
+
+ C1.new.foo{}
+}
+
+assert_equal 'true', %q{
+ class C0
+ def foo
+ block_given?
+ end
+ end
+
+ class C1 < C0
+ def foo
+ super()
+ end
+ end
+
+ C1.new.foo{}
+}
+
+assert_equal 'ok', %q{
+ 1.times do
+ begin
+ raise
+ rescue
+ begin
+ raise
+ rescue
+ break
+ end
+ end
+ end
+ 'ok'
+}
diff --git a/bootstraptest/test_class.rb b/bootstraptest/test_class.rb
new file mode 100644
index 0000000000..b7fe0a1acd
--- /dev/null
+++ b/bootstraptest/test_class.rb
@@ -0,0 +1,169 @@
+# class
+assert_equal 'true', %q( class C; end
+ Object.const_defined?(:C) )
+assert_equal 'Class', %q( class C; end
+ C.class )
+assert_equal 'C', %q( class C; end
+ C.name )
+assert_equal 'C', %q( class C; end
+ C.new.class )
+assert_equal 'C', %q( class C; end
+ C.new.class.name )
+assert_equal 'Class', %q( class C; end
+ C.new.class.class )
+assert_equal 'true', %q( Object.__send__(:remove_const, :TrueClass)
+ GC.start
+ true.inspect)
+assert_equal 'false', %q( Object.__send__(:remove_const, :FalseClass)
+ GC.start
+ false.inspect)
+assert_equal 'nil', %q( Object.__send__(:remove_const, :NilClass)
+ GC.start
+ nil.inspect)
+
+
+# inherited class
+assert_equal 'true', %q( class A; end
+ class C < A; end
+ Object.const_defined?(:C) )
+assert_equal 'Class', %q( class A; end
+ class C < A; end
+ C.class )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.name )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.new.class )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.new.class.name )
+assert_equal 'Class', %q( class A; end
+ class C < A; end
+ C.new.class.class )
+
+# module
+assert_equal 'true', %q( module M; end
+ Object.const_defined?(:M) )
+assert_equal 'Module', %q( module M; end
+ M.class )
+assert_equal 'M', %q( module M; end
+ M.name )
+assert_equal 'C', %q( module M; end
+ class C; include M; end
+ C.new.class )
+
+# nested class
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B )
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B.name )
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B.new.class )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ A::B.new.class.class )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.name )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.class )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.new.class )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.new.class.class )
+assert_equal 'A::B2', %q( class A; end
+ class A::B; end
+ class A::B2 < A::B; end
+ A::B2 )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B2 < A::B; end
+ A::B2.class )
+
+# reopen
+assert_equal 'true', %q( class C; end; c1 = ::C
+ class C; end; c2 = ::C
+ c1.equal?(c2) )
+assert_equal '1', %q( class C; end
+ class A; end
+ begin class C < A; end; rescue TypeError; 1 end )
+assert_equal '1', %q( class C; end
+ begin module C; end; rescue TypeError; 1 end )
+assert_equal '1', %q( C = 1 # [yarv-dev:782]
+ begin class C; end; rescue TypeError; 1 end )
+assert_equal '1', %q( C = 1 # [yarv-dev:800]
+ begin module C; end; rescue TypeError; 1 end )
+
+# colon2, colon3
+assert_equal '1', %q( class A; end; A::C = 1; A::C )
+assert_equal '1', %q( A = 7; begin A::C = 7; rescue TypeError; 1 end )
+assert_equal '1', %q( begin 7::C = 7; rescue TypeError; 1 end )
+assert_equal 'C', %q( class A; class ::C; end end; C )
+assert_equal 'Class', %q( class A; class ::C; end end; C.class )
+assert_equal 'OK', %q( class A; ::C = "OK"; end; C )
+assert_equal 'String', %q( class A; ::C = "OK"; end; C.class )
+
+# class/module dup
+assert_equal 'Class', %q( class C; end; C.dup.class )
+assert_equal 'Module', %q( module M; end; M.dup.class )
+
+
+assert_equal "ok", %q{
+ module Foo
+ end
+
+ begin
+ def foo(&b)
+ Foo.module_eval &b
+ end
+ foo{
+ def bar
+ end
+ }
+ bar()
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:14378]'
+
+assert_equal '3', %q{
+ $i = 0
+ class C
+ def self.const_missing *args
+ $i+=1
+ end
+ end
+
+ 3.times{
+ C::FOO
+ }
+ $i
+}
+
+assert_match /::C\z/, %q{
+ c = nil
+ Module.new{|m| c = class m::C; name; end}
+ c
+}, '[ruby-dev:38456]'
+
+assert_normal_exit %q{
+ s = Symbol.dup
+ class << s
+ end
+ s.allocate.to_s
+}, '[ruby-core:30843]'
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
new file mode 100644
index 0000000000..8e90ac2728
--- /dev/null
+++ b/bootstraptest/test_eval.rb
@@ -0,0 +1,324 @@
+assert_equal %q{ok}, %q{
+ def m
+ a = :ok
+ $b = binding
+ end
+ m
+ eval('a', $b)
+}
+assert_equal %q{[:ok, :ok2]}, %q{
+ def m
+ a = :ok
+ $b = binding
+ end
+ m
+ eval('b = :ok2', $b)
+ eval('[a, b]', $b)
+}
+assert_equal %q{[nil, 1]}, %q{
+ $ans = []
+ def m
+ $b = binding
+ end
+ m
+ $ans << eval(%q{
+ $ans << eval(%q{
+ a
+ }, $b)
+ a = 1
+ }, $b)
+ $ans
+}
+assert_equal %q{C}, %q{
+ Const = :top
+ class C
+ Const = :C
+ def m
+ binding
+ end
+ end
+ eval('Const', C.new.m)
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ a = 1
+ class C
+ Const = :C
+ def m
+ eval('Const', TOPLEVEL_BINDING)
+ end
+ end
+ C.new.m
+}
+assert_equal %q{:ok
+ok}, %q{
+ class C
+ $b = binding
+ end
+ eval %q{
+ def m
+ :ok
+ end
+ }, $b
+ p C.new.m
+}
+assert_equal %q{ok}, %q{
+ b = proc{
+ a = :ok
+ binding
+ }.call
+ a = :ng
+ eval("a", b)
+}
+assert_equal %q{C}, %q{
+ class C
+ def foo
+ binding
+ end
+ end
+ C.new.foo.eval("self.class.to_s")
+}
+assert_equal %q{1}, %q{
+ eval('1')
+}
+assert_equal %q{1}, %q{
+ eval('a=1; a')
+}
+assert_equal %q{1}, %q{
+ a = 1
+ eval('a')
+}
+assert_equal %q{ok}, %q{
+ __send__ :eval, %{
+ :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ 1.__send__ :instance_eval, %{
+ :ok
+ }
+}
+assert_equal %q{1}, %q{
+ 1.instance_eval{
+ self
+ }
+}
+assert_equal %q{foo}, %q{
+ 'foo'.instance_eval{
+ self
+ }
+}
+assert_equal %q{1}, %q{
+ class Integer
+ Const = 1
+ end
+ 1.instance_eval %{
+ Const
+ }
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.module_eval{
+ Const
+ }
+}
+assert_equal %q{C}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.class_eval %{
+ def m
+ Const
+ end
+ }
+ C.new.m
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.class_eval{
+ def m
+ Const
+ end
+ }
+ C.new.m
+}
+assert_equal %q{[:top, :C, :top, :C]}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ $nest = false
+ $ans = []
+ def m
+ $ans << Const
+ C.module_eval %{
+ $ans << Const
+ Boo = false unless defined? Boo
+ unless $nest
+ $nest = true
+ m
+ end
+ }
+ end
+ m
+ $ans
+}
+assert_equal %q{[10, main]}, %q{
+ $nested = false
+ $ans = []
+ $pr = proc{
+ $ans << self
+ unless $nested
+ $nested = true
+ $pr.call
+ end
+ }
+ class C
+ def initialize &b
+ 10.instance_eval(&b)
+ end
+ end
+ C.new(&$pr)
+ $ans
+}
+
+%w[break next redo].each do |keyword|
+ assert_match %r"Can't escape from eval with #{keyword}\z", %{
+ begin
+ eval "0 rescue #{keyword}"
+ rescue SyntaxError => e
+ e.message
+ end
+ }, '[ruby-dev:31372]'
+end
+
+assert_normal_exit %q{
+ STDERR.reopen(STDOUT)
+ class Foo
+ def self.add_method
+ class_eval("def some-bad-name; puts 'hello' unless @some_variable.some_function(''); end")
+ end
+ end
+ Foo.add_method
+}, '[ruby-core:14556] reported by Frederick Cheung'
+
+assert_equal 'ok', %q{
+ class Module
+ def my_module_eval(&block)
+ module_eval(&block)
+ end
+ end
+ class String
+ Integer.my_module_eval do
+ def hoge; end
+ end
+ end
+ if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
+ !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
+ :ok
+ else
+ :ng
+ end
+}, "[ruby-dev:34236]"
+
+assert_equal 'ok', %q{
+ begin
+ eval("class nil::Foo; end")
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ begin
+ 0.instance_eval { def m() :m end }
+ 1.m
+ :ng
+ rescue Exception
+ :ok
+ end
+}, '[ruby-dev:34579]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_eval { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_exec { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ nil.instance_eval {
+ def defd_using_instance_eval() :ok end
+ }
+ nil.defd_using_instance_eval
+}, '[ruby-core:28324]'
+
+assert_equal 'ok', %q{
+ nil.instance_exec {
+ def defd_using_instance_exec() :ok end
+ }
+ nil.defd_using_instance_exec
+}, '[ruby-core:28324]'
+
+assert_normal_exit %q{
+ eval("", method(:proc).call {}.binding)
+}
+
+assert_equal "", %q{
+ b = binding
+ 10.times{
+ eval('', b)
+ }
+ begin
+ eval('1.times{raise}', b)
+ rescue => e
+ e.message
+ end
+}, '[ruby-dev:35392]'
+
+assert_equal "[:x]", %q{
+ def kaboom!
+ yield.eval("local_variables")
+ end
+
+ for x in enum_for(:kaboom!)
+ binding
+ end
+}, '[ruby-core:25125]'
+
+assert_normal_exit %q{
+ hash = {}
+ ("aaaa".."matz").each_with_index do |s, i|
+ hash[s] = i
+ end
+ begin
+ eval "class C; @@h = #{hash.inspect}; end"
+ end
+}, '[ruby-core:25714]'
+
+assert_normal_exit %q{
+ begin
+ eval("# encoding:utf-16le\nfoo")
+ rescue Exception => e
+ p e
+ RubyVM::InstructionSequence.compile("p:hello")
+ end
+}, 'check escaping the internal value th->base_block'
+
diff --git a/bootstraptest/test_exception.rb b/bootstraptest/test_exception.rb
new file mode 100644
index 0000000000..35c8d25e37
--- /dev/null
+++ b/bootstraptest/test_exception.rb
@@ -0,0 +1,432 @@
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ ensure
+ 2+2
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ ensure
+ 3+3
+ end
+ ensure
+ 4+4
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ ensure
+ 3+3
+ end
+ ensure
+ 4+4
+ begin
+ 5+5
+ ensure
+ 6+6
+ end
+ end
+}
+assert_equal %q{NilClass}, %q{
+ a = nil
+ 1.times{|e|
+ begin
+ rescue => err
+ end
+ a = err.class
+ }
+ a
+}
+assert_equal %q{RuntimeError}, %q{
+ a = nil
+ 1.times{|e|
+ begin
+ raise
+ rescue => err
+ end
+ a = err.class
+ }
+ a
+}
+assert_equal %q{}, %q{
+ $!
+}
+assert_equal %q{FOO}, %q{
+ begin
+ raise "FOO"
+ rescue
+ $!
+ end
+}
+assert_equal %q{FOO}, %q{
+ def m
+ $!
+ end
+ begin
+ raise "FOO"
+ rescue
+ m()
+ end
+}
+assert_equal %q{[#<RuntimeError: BAR>, #<RuntimeError: FOO>]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+ begin
+ raise "FOO"
+ rescue
+ begin
+ raise "BAR"
+ rescue
+ $ans << m()
+ end
+ $ans << m()
+ end
+ $ans
+}
+assert_equal %q{[#<RuntimeError: FOO>, #<RuntimeError: FOO>]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+
+ begin
+ begin
+ raise "FOO"
+ ensure
+ $ans << m()
+ end
+ rescue
+ $ans << m()
+ end
+}
+assert_equal %q{[nil]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+ def m2
+ 1.times{
+ begin
+ return
+ ensure
+ $ans << m
+ end
+ }
+ end
+ m2
+ $ans
+}
+assert_equal %q{ok}, %q{
+ begin
+ raise
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ begin
+ raise
+ rescue
+ :ok
+ ensure
+ :ng
+ end
+}
+assert_equal %q{RuntimeError}, %q{
+ begin
+ raise
+ rescue => e
+ e.class
+ end
+}
+assert_equal %q{ng}, %q{
+ begin
+ raise
+ rescue StandardError
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+assert_equal %q{c}, %q{
+ begin
+ begin
+ raise "a"
+ rescue
+ raise "b"
+ ensure
+ raise "c"
+ end
+ rescue => e
+ e.message
+ end
+}
+assert_equal %q{33}, %q{
+ def m a, b
+ a + b
+ end
+ m(1, begin
+ raise
+ rescue
+ 2
+ end) +
+ m(10, begin
+ raise
+ rescue
+ 20
+ ensure
+ 30
+ end)
+}
+assert_equal %q{3}, %q{
+ def m a, b
+ a + b
+ end
+ m(begin
+ raise
+ rescue
+ 1
+ end,
+ begin
+ raise
+ rescue
+ 2
+ end)
+}
+assert_equal %q{ok3}, %q{
+ class E1 < Exception
+ end
+
+ def m
+ yield
+ end
+
+ begin
+ begin
+ begin
+ m{
+ raise
+ }
+ rescue E1
+ :ok2
+ ensure
+ end
+ rescue
+ :ok3
+ ensure
+ end
+ rescue E1
+ :ok
+ ensure
+ end
+}
+assert_equal %q{7}, %q{
+ $i = 0
+ def m
+ iter{
+ begin
+ $i += 1
+ begin
+ $i += 2
+ break
+ ensure
+
+ end
+ ensure
+ $i += 4
+ end
+ $i = 0
+ }
+ end
+
+ def iter
+ yield
+ end
+ m
+ $i
+}
+assert_equal %q{10}, %q{
+ $i = 0
+ def m
+ begin
+ $i += 1
+ begin
+ $i += 2
+ return
+ ensure
+ $i += 3
+ end
+ ensure
+ $i += 4
+ end
+ p :end
+ end
+ m
+ $i
+}
+assert_equal %q{1}, %q{
+ begin
+ 1
+ rescue
+ 2
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1
+ begin
+ 2
+ rescue
+ 3
+ end
+ 4
+ rescue
+ 5
+ end
+}
+assert_equal %q{3}, %q{
+ begin
+ 1
+ rescue
+ 2
+ else
+ 3
+ end
+}
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ ensure
+ 3+3
+ end
+ }
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ ensure
+ 3+3
+ end
+ }
+assert_equal %q{6}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ else
+ 3+3
+ ensure
+ 4+4
+ end
+ }
+assert_equal %q{12}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ rescue
+ 3+3
+ else
+ 4+4
+ end
+ rescue
+ 5+5
+ else
+ 6+6
+ ensure
+ 7+7
+ end
+ }
+assert_equal %q{ok}, %q{ #
+ proc{
+ begin
+ raise
+ break
+ rescue
+ :ok
+ end
+ }.call
+}
+assert_equal %q{}, %q{
+ proc do
+ begin
+ raise StandardError
+ redo
+ rescue StandardError
+ end
+ end.call
+}
+
+##
+assert_match /undefined method `foo\'/, %q{#`
+ STDERR.reopen(STDOUT)
+ class C
+ def inspect
+ bar {}
+ end
+
+ def bar
+ raise
+ ensure
+ end
+ end
+ C.new.foo
+}, "[ruby-dev:31407]"
+
+assert_equal 'nil', %q{
+ doit = false
+ exc = nil
+ t = Thread.new {
+ begin
+ doit = true
+ sleep 10
+ ensure
+ exc = $!
+ end
+ }
+ Thread.pass until doit
+ t.kill
+ t.join
+ exc.inspect
+}, '[ruby-dev:32608]'
+
+assert_equal 'exception class/object expected', %q{
+ class ZeroDivisionError
+ def self.new(message)
+ 42
+ end
+ end
+ begin
+ 1/0
+ rescue Exception => e
+ e.message
+ end
+}, '[ruby-core:24767]'
+
+assert_equal 'ok', %q{
+ class C
+ def ===(o)
+ true
+ end
+ end
+ begin
+ begin
+ raise
+ rescue C.new
+ end
+ rescue TypeError
+ :ok
+ end
+}
diff --git a/bootstraptest/test_finalizer.rb b/bootstraptest/test_finalizer.rb
new file mode 100644
index 0000000000..22a16b1220
--- /dev/null
+++ b/bootstraptest/test_finalizer.rb
@@ -0,0 +1,8 @@
+assert_normal_exit %q{
+a1,a2,b1,b2=Array.new(4){""}
+ObjectSpace.define_finalizer(b2,proc{})
+ObjectSpace.define_finalizer(b1,proc{b1.inspect})
+
+ObjectSpace.define_finalizer(a2,proc{a1.inspect})
+ObjectSpace.define_finalizer(a1,proc{})
+}, '[ruby-dev:35778]'
diff --git a/bootstraptest/test_flip.rb b/bootstraptest/test_flip.rb
new file mode 100644
index 0000000000..ff194868b2
--- /dev/null
+++ b/bootstraptest/test_flip.rb
@@ -0,0 +1 @@
+assert_equal %q{E}, %q{$_ = "E"; eval("nil if true..~/^E/",nil,"-e"); $_}
diff --git a/bootstraptest/test_flow.rb b/bootstraptest/test_flow.rb
new file mode 100644
index 0000000000..9da6d45cbd
--- /dev/null
+++ b/bootstraptest/test_flow.rb
@@ -0,0 +1,601 @@
+assert_equal %q{[1, 2, 4, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each{; $a << 2
+ break; $a << 3
+ }; $a << 4
+ begin; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ [1,2].each do; $a << 3
+ break; $a << 4
+ end; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{ok}, %q{
+ ["a"].inject("ng"){|x,y|
+ break :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ unless ''.respond_to? :lines
+ class String
+ def lines
+ self
+ end
+ end
+ end
+
+ ('a').lines.map{|e|
+ break :ok
+ }
+}
+assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1
+ ["a"].inject("ng"){|x,y|; $a << 2
+ break :ok; $a << 3
+ }; $a << 4
+; $a << 5
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1
+ ('a'..'b').map{|e|; $a << 2
+ break :ok; $a << 3
+ }; $a << 4
+; $a << 5
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 9, 10]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ ensure; $a << 6
+ break; $a << 7
+ end; $a << 8
+ end; $a << 9
+; $a << 10
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ raise; $a << 6
+ ensure; $a << 7
+ break; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ raise; $a << 6
+ rescue; $a << 7
+ break; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ raise StandardError; $a << 4
+ ensure; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ raise StandardError; $a << 4
+ rescue; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 6, 8, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ begin; $a << 4
+ break; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+ ensure; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ begin; $a << 8
+ raise; $a << 9
+ rescue; $a << 10
+ break; $a << 11
+ end; $a << 12
+ end; $a << 13
+ end; $a << 14
+; $a << 15
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ 1.times{; $a << 8
+ begin; $a << 9
+ raise; $a << 10
+ rescue; $a << 11
+ break; $a << 12
+ end; $a << 13
+ }; $a << 14
+ end; $a << 15
+ end; $a << 16
+; $a << 17
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ begin; $a << 8
+ raise; $a << 9
+ ensure; $a << 10
+ break; $a << 11
+ end; $a << 12
+ end; $a << 13
+ end; $a << 14
+; $a << 15
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ 1.times{; $a << 8
+ begin; $a << 9
+ raise; $a << 10
+ ensure; $a << 11
+ break; $a << 12
+ end; $a << 13
+ }; $a << 14
+ end; $a << 15
+ end; $a << 16
+; $a << 17
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 99]}, %q{
+$a = [];
+begin; ; $a << 1
+ while true; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ raise; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 6, 8, 9, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ [1,2].each do; $a << 3
+ begin; $a << 4
+ break; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+ end; $a << 8
+ ensure; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 4, 99]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ raise StandardError; $a << 3
+ ensure; $a << 4
+ end; $a << 5
+; $a << 6
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ ensure; $a << 3
+ end ; $a << 4
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ raise StandardError; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{3}, %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ while true
+ break 2
+ end
+ )
+}
+assert_equal %q{4}, %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ (i=0; while i<2
+ i+=1
+ class C
+ next 2
+ end
+ end; 3)
+ )
+}
+assert_equal %q{34}, %q{
+ def m a, b
+ a+b
+ end
+ m(1, 1.times{break 3}) +
+ m(10, (1.times{next 3}; 20))
+}
+assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ break; $a << 4
+ end; $a << 5
+ }; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class A; $a << 3
+ class B; $a << 4
+ break; $a << 5
+ end; $a << 6
+ end; $a << 7
+ }; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 2, 3, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ next; $a << 4
+ end; $a << 5
+ }; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ class D; $a << 4
+ next; $a << 5
+ end; $a << 6
+ end; $a << 7
+ }; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ class C; $a << 3
+ break; $a << 4
+ end; $a << 5
+ end; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ class C; $a << 3
+ class D; $a << 4
+ break; $a << 5
+ end; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ class C; $a << 5
+ next 10; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{1}, %q{
+ 1.times{
+ while true
+ class C
+ begin
+ break
+ ensure
+ break
+ end
+ end
+ end
+ }
+}
+assert_equal %q{[1, 2, 3, 5, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ next; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 6, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ o = "test"; $a << 2
+ def o.test(a); $a << 3
+ return a; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ o.test(123); $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 4, 7, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ def m1 *args; $a << 2
+ ; $a << 3
+ end; $a << 4
+ def m2; $a << 5
+ m1(:a, :b, (return 1; :c)); $a << 6
+ end; $a << 7
+ m2; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 8, 2, 3, 4, 5, 9, 10]}, %q{$a = []; begin; ; $a << 1
+ def m(); $a << 2
+ begin; $a << 3
+ 2; $a << 4
+ ensure; $a << 5
+ return 3; $a << 6
+ end; $a << 7
+ end; $a << 8
+ m; $a << 9
+; $a << 10
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 3, 11, 4, 5, 6, 7, 12, 13]}, %q{$a = []; begin; ; $a << 1
+ def m2; $a << 2
+ end; $a << 3
+ def m(); $a << 4
+ m2(begin; $a << 5
+ 2; $a << 6
+ ensure; $a << 7
+ return 3; $a << 8
+ end); $a << 9
+ 4; $a << 10
+ end; $a << 11
+ m(); $a << 12
+; $a << 13
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 16, 2, 3, 4, 5, 6, 7, 10, 11, 17, 18]}, %q{$a = []; begin; ; $a << 1
+ def m; $a << 2
+ 1; $a << 3
+ 1.times{; $a << 4
+ 2; $a << 5
+ begin; $a << 6
+ 3; $a << 7
+ return; $a << 8
+ 4; $a << 9
+ ensure; $a << 10
+ 5; $a << 11
+ end; $a << 12
+ 6; $a << 13
+ }; $a << 14
+ 7; $a << 15
+ end; $a << 16
+ m(); $a << 17
+; $a << 18
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ next
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ break
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ if i>0
+ break
+ end
+ i+=1
+ begin
+ begin
+ redo
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %Q{ENSURE\n}, %q{
+ def test
+ while true
+ return
+ end
+ ensure
+ puts("ENSURE")
+ end
+ test
+}, '[ruby-dev:37967]'
+
+[['[ruby-core:28129]', %q{
+ class Bug2728
+ include Enumerable
+ define_method(:dynamic_method) do
+ "dynamically defined method"
+ end
+ def each
+ begin
+ yield :foo
+ ensure
+ dynamic_method
+ end
+ end
+ end
+ e = Bug2728.new
+}],
+ ['[ruby-core:28132]', %q{
+ class Bug2729
+ include Enumerable
+ def each
+ begin
+ yield :foo
+ ensure
+ proc {}.call
+ end
+ end
+ end
+ e = Bug2729.new
+}],
+ ['[ruby-core:39125]', %q{
+ class Bug5234
+ include Enumerable
+ def each
+ begin
+ yield :foo
+ ensure
+ proc
+ end
+ end
+ end
+ e = Bug5234.new
+}],
+ ['[ruby-dev:45656]', %q{
+ class Bug6460
+ include Enumerable
+ def each
+ begin
+ yield :foo
+ ensure
+ 1.times { Proc.new }
+ end
+ end
+ end
+ e = Bug6460.new
+}]].each do |bug, src|
+ assert_equal "foo", src + %q{e.detect {true}}, bug
+ assert_equal "true", src + %q{e.any? {true}}, bug
+ assert_equal "false", src + %q{e.all? {false}}, bug
+ assert_equal "true", src + %q{e.include?(:foo)}, bug
+end
+
+assert_equal "foo", %q{
+ class Bug6460
+ def m1
+ m2 {|e|
+ return e
+ }
+ end
+
+ def m2
+ begin
+ yield :foo
+ ensure
+ begin
+ begin
+ yield :foo
+ ensure
+ Proc.new
+ raise ''
+ end
+ rescue
+ end
+ end
+ end
+ 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
new file mode 100644
index 0000000000..1cd9f7ac6c
--- /dev/null
+++ b/bootstraptest/test_fork.rb
@@ -0,0 +1,75 @@
+assert_equal '0', %q{
+ begin
+ GC.stress = true
+ pid = fork {}
+ Process.wait pid
+ $?.to_i
+ rescue NotImplementedError
+ 0
+ end
+}, '[ruby-dev:32404]'
+
+assert_finish 10, %q{
+ begin
+ children = (1..10).map{
+ Thread.start{fork{}}.value
+ }
+ while !children.empty? and pid = Process.wait
+ children.delete(pid)
+ end
+ rescue NotImplementedError
+ end
+}, '[ruby-core:22158]'
+
+assert_normal_exit(<<'End', '[ruby-dev:37934]')
+ main = Thread.current
+ Thread.new { sleep 0.01 until main.stop?; Thread.kill main }
+ Process.setrlimit(:NPROC, 1) if defined?(Process::RLIMIT_NPROC)
+ fork {}
+End
+
+assert_equal 'ok', %q{
+ begin
+ r, w = IO.pipe
+ if pid1 = fork
+ w.close
+ r.read(1)
+ Process.kill("USR1", pid1)
+ _, s = Process.wait2(pid1)
+ s.success? ? :ok : :ng
+ else
+ r.close
+ if pid2 = fork
+ trap("USR1") { Time.now.to_s; Process.kill("USR2", pid2) }
+ w.close
+ Process.wait2(pid2)
+ else
+ w.close
+ sleep 0.2
+ end
+ exit true
+ end
+ rescue NotImplementedError
+ :ok
+ end
+}, '[ruby-core:28924]'
+
+assert_equal '[1, 2]', %q{
+ a = []
+ main = Thread.current
+ trap(:INT) { a.push(1).size == 2 and main.wakeup }
+ trap(:TERM) { a.push(2).size == 2 and main.wakeup }
+ pid = $$
+ begin
+ pid = fork do
+ Process.kill(:INT, pid)
+ Process.kill(:TERM, pid)
+ end
+ Process.wait(pid)
+ 100.times {break if a.size > 1; sleep 0.001}
+ a.sort
+ rescue NotImplementedError
+ [1, 2]
+ end
+}, '[ruby-dev:44005] [Ruby 1.9 - Bug #4950]'
+
diff --git a/bootstraptest/test_gc.rb b/bootstraptest/test_gc.rb
new file mode 100644
index 0000000000..eb68c9845e
--- /dev/null
+++ b/bootstraptest/test_gc.rb
@@ -0,0 +1,34 @@
+assert_normal_exit %q{
+a = []
+ms = "a".."k"
+("A".."Z").each do |mod|
+ mod = eval("module #{mod}; self; end")
+ ms.each do |meth|
+ iseq = RubyVM::InstructionSequence.compile("module #{mod}; def #{meth}; end; end")
+ GC.stress = true
+ iseq.eval
+ GC.stress = false
+ end
+ o = Object.new.extend(mod)
+ ms.each do |meth|
+ o.send(meth)
+ end
+end
+}, '[ruby-dev:39453]'
+
+assert_normal_exit %q{
+a = []
+ms = "a".."k"
+("A".."Z").each do |mod|
+ mod = eval("module #{mod}; self; end")
+ ms.each do |meth|
+ GC.stress = true
+ mod.module_eval {define_method(meth) {}}
+ GC.stress = false
+ end
+ o = Object.new.extend(mod)
+ ms.each do |meth|
+ o.send(meth)
+ end
+end
+}, '[ruby-dev:39453]'
diff --git a/bootstraptest/test_insns.rb b/bootstraptest/test_insns.rb
new file mode 100644
index 0000000000..4dd888897a
--- /dev/null
+++ b/bootstraptest/test_insns.rb
@@ -0,0 +1,389 @@
+# C0 coverage of each instructions
+
+# :NOTE: This is for development purpose; never consider this file as
+# ISeq compilation specification.
+
+begin
+ # This library brings some additional coverage.
+ # Not mandatory.
+ require 'rbconfig/sizeof'
+rescue LoadError
+ # OK, just skip
+else
+ $FIXNUM_MAX = RbConfig::LIMITS["FIXNUM_MAX"]
+ $FIXNUM_MIN = RbConfig::LIMITS["FIXNUM_MIN"]
+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 }, ],
+ [ 'setlocal', %q{ x = nil; -> { -> { x = true }.() }.() }, ],
+ [ 'getlocal *, 0', %q{ x = true; x }, ],
+ [ 'getlocal *, 1', %q{ x = true; -> { x }.call }, ],
+ [ 'getlocal', %q{ x = true; -> { -> { x }.() }.() }, ],
+
+ [ 'setspecial', %q{ true if true..true }, ],
+ [ 'getspecial', %q{ $&.nil? }, ],
+ [ 'getspecial', %q{ $`.nil? }, ],
+ [ 'getspecial', %q{ $'.nil? }, ],
+ [ 'getspecial', %q{ $+.nil? }, ],
+ [ 'getspecial', %q{ $1.nil? }, ],
+ [ 'getspecial', %q{ $128.nil? }, ],
+
+ [ 'getglobal', %q{ String === $0 }, ],
+ [ 'getglobal', %q{ $_.nil? }, ],
+ [ 'setglobal', %q{ $0 = "true" }, ],
+
+ [ 'setinstancevariable', %q{ @x = true }, ],
+ [ 'getinstancevariable', %q{ @x = true; @x }, ],
+
+ [ 'setclassvariable', %q{ @@x = true }, ],
+ [ 'getclassvariable', %q{ @@x = true; @@x }, ],
+
+ [ 'setconstant', %q{ X = true }, ],
+ [ 'setconstant', %q{ Object::X = true }, ],
+ [ 'getconstant', %q{ X = true; X }, ],
+ [ 'getconstant', %q{ X = true; Object::X }, ],
+
+ [ 'getinlinecache / setinlinecache', %q{ def x; X; end; X = true; x; x; x }, ],
+
+ [ 'putnil', %q{ $~ == nil }, ],
+ [ 'putself', %q{ $~ != self }, ],
+ [ 'putobject INT2FIX(0)', %q{ $~ != 0 }, ],
+ [ 'putobject INT2FIX(1)', %q{ $~ != 1 }, ],
+ [ 'putobject', %q{ $~ != -1 }, ],
+ [ 'putobject', %q{ $~ != /x/ }, ],
+ [ 'putobject', %q{ $~ != :x }, ],
+ [ 'putobject', %q{ $~ != (1..2) }, ],
+ [ 'putobject', %q{ $~ != true }, ],
+ [ '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" && $~ }, ],
+
+ [ 'newarray', %q{ ["true"][0] }, ],
+ [ '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', <<~'},', ], # {
+ class X; def to_a; ['u']; end; end
+ ['t', 'r', *X.new, 'e'].join
+ },
+ [ 'concatarray', <<~'},', ], # {
+ r = false
+ t = [true, nil]
+ q, w, e = r, *t # here
+ w
+ },
+
+ [ 'newhash', %q{ x = {}; x[x] = true }, ],
+ [ 'newhash', %q{ x = true; { x => x }[x] }, ],
+ [ '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', <<~'},', ], # {
+ x = [[false, true]]
+ for i, j in x # here
+ ;
+ end
+ j
+ },
+
+ [ 'topn', %q{ x, y = [], 0; x[*y], = [true, false]; x[0] }, ],
+ [ 'setn', %q{ x, y = [], 0; x[*y] = true ; x[0] }, ],
+ [ 'adjuststack', %q{ x = [true]; x[0] ||= nil; x[0] }, ],
+
+ [ 'defined', %q{ !defined?(x) }, ],
+ [ 'checkkeyword', %q{ def x x:rand;x end; x x: true }, ],
+ [ 'checkmatch', <<~'},', ], # {
+ x = y = true
+ case x
+ when false
+ y = false
+ when true # here
+ y = nil
+ end
+ y == nil
+ },
+ [ 'checkmatch', <<~'},', ], # {
+ x, y = true, [false]
+ case x
+ when *y # here
+ z = false
+ else
+ z = true
+ end
+ z
+ },
+ [ 'checkmatch', <<~'},', ], # {
+ x = false
+ begin
+ raise
+ rescue # here
+ x = true
+ end
+ x
+ },
+
+ [ 'defineclass', %q{ module X; true end }, ],
+ [ 'defineclass', %q{ X = Module.new; module X; true end }, ],
+ [ 'defineclass', %q{ class X; true end }, ],
+ [ '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', <<~'},', ], # {
+ X = Class.new
+ Y = Class.new(X)
+ class Y < X
+ true
+ end
+ },
+
+ [ 'opt_send_without_block', %q{ true.to_s }, ],
+ [ 'send', %q{ true.tap {|i| i.to_s } }, ],
+ [ 'leave', %q{ def x; true; end; x }, ],
+ [ 'invokesuper', <<~'},', ], # {
+ class X < String
+ def empty?
+ super # here
+ end
+ end
+ X.new.empty?
+ },
+ [ 'invokeblock', <<~'},', ], # {
+ def x
+ return yield self # here
+ end
+ x do
+ true
+ end
+ },
+
+ [ 'opt_str_freeze', %q{ 'true'.freeze }, ],
+ [ 'opt_str_uminus', %q{ -'true' }, ],
+ [ 'opt_str_freeze', <<~'},', ], # {
+ class String
+ def freeze
+ true
+ end
+ end
+ 'true'.freeze
+ },
+
+ [ 'opt_newarray_max', %q{ [ ].max.nil? }, ],
+ [ 'opt_newarray_max', %q{ [1, x = 2, 3].max == 3 }, ],
+ [ 'opt_newarray_max', <<~'},', ], # {
+ class Array
+ def max
+ true
+ end
+ end
+ [1, x = 2, 3].max
+ },
+ [ 'opt_newarray_min', %q{ [ ].min.nil? }, ],
+ [ 'opt_newarray_min', %q{ [3, x = 2, 1].min == 1 }, ],
+ [ 'opt_newarray_min', <<~'},', ], # {
+ class Array
+ def min
+ true
+ end
+ end
+ [3, x = 2, 1].min
+ },
+
+ [ 'throw', %q{ false.tap { break true } }, ],
+ [ 'branchif', %q{ x = nil; x ||= true }, ],
+ [ 'branchif', %q{ x = true; x ||= nil; x }, ],
+ [ 'branchunless', %q{ x = 1; x &&= true }, ],
+ [ 'branchunless', %q{ x = nil; x &&= true; x.nil? }, ],
+ [ 'branchnil', %q{ x = true; x&.to_s }, ],
+ [ 'branchnil', %q{ x = nil; (x&.to_s).nil? }, ],
+ [ 'jump', <<~'},', ], # {
+ y = 1
+ x = if y == 0 then nil elsif y == 1 then true else nil end
+ x
+ },
+ [ 'jump', <<~'},', ], # {
+ # ultra complicated situation: this ||= assignment only generates
+ # 15 instructions, not including the class definition.
+ class X; attr_accessor :x; end
+ x = X.new
+ x&.x ||= true # here
+ },
+
+ [ 'once', %q{ /#{true}/o =~ "true" && $~ }, ],
+ [ 'once', <<~'},', ], # {
+ def once expr
+ return /#{expr}/o # here
+ end
+ x = once(true); x = once(false); x = once(nil);
+ x =~ "true" && $~
+ },
+ [ 'once', <<~'},', ], # {
+ # recursive once
+ def once n
+ return %r/#{
+ if n == 0
+ true
+ else
+ once(n-1) # here
+ end
+ }/ox
+ end
+ x = once(128); x = once(7); x = once(16);
+ x =~ "true" && $~
+ },
+ [ 'once', <<~'},', ], # {
+ # inter-thread lockup situation
+ def once n
+ return Thread.start n do |m|
+ Thread.pass
+ next %r/#{
+ sleep m # here
+ true
+ }/ox
+ end
+ end
+ x = once(1); y = once(0.1); z = y.value
+ z =~ "true" && $~
+ },
+
+ [ 'opt_case_dispatch', %q{ case 0 when 1.1 then false else true end }, ],
+ [ 'opt_case_dispatch', %q{ case 1.0 when 1.1 then false else true end }, ],
+
+ [ 'opt_plus', %q{ 1 + 1 == 2 }, ],
+ if defined? $FIXNUM_MAX then
+ [ 'opt_plus', %Q{ #{ $FIXNUM_MAX } + 1 == #{ $FIXNUM_MAX + 1 } }, ]
+ end,
+ [ 'opt_plus', %q{ 1.0 + 1.0 == 2.0 }, ],
+ [ 'opt_plus', %q{ x = +0.0.next_float; x + x >= x }, ],
+ [ 'opt_plus', %q{ 't' + 'rue' }, ],
+ [ 'opt_plus', %q{ ( ['t'] + ['r', ['u', ['e'], ], ] ).join }, ],
+ [ 'opt_plus', %q{ Time.at(1) + 1 == Time.at(2) }, ],
+ [ 'opt_minus', %q{ 1 - 1 == 0 }, ],
+ if defined? $FIXNUM_MIN then
+ [ 'opt_minus', %Q{ #{ $FIXNUM_MIN } - 1 == #{ $FIXNUM_MIN - 1 } }, ]
+ end,
+ [ 'opt_minus', %q{ 1.0 - 1.0 == 0.0 }, ],
+ [ 'opt_minus', %q{ x = -0.0.prev_float; x - x == 0.0 }, ],
+ [ 'opt_minus', %q{ ( [false, true] - [false] )[0] }, ],
+ [ 'opt_mult', %q{ 1 * 1 == 1 }, ],
+ [ 'opt_mult', %q{ 1.0 * 1.0 == 1.0 }, ],
+ [ 'opt_mult', %q{ x = +0.0.next_float; x * x <= x }, ],
+ [ 'opt_mult', %q{ ( "ruet" * 3 )[7,4] }, ],
+ [ 'opt_div', %q{ 1 / 1 == 1 }, ],
+ [ 'opt_div', %q{ 1.0 / 1.0 == 1.0 }, ],
+ [ 'opt_div', %q{ x = +0.0.next_float; x / x >= x }, ],
+ [ 'opt_div', %q{ x = 1/2r; x / x == 1 }, ],
+ [ 'opt_mod', %q{ 1 % 1 == 0 }, ],
+ [ 'opt_mod', %q{ 1.0 % 1.0 == 0.0 }, ],
+ [ 'opt_mod', %q{ x = +0.0.next_float; x % x == 0.0 }, ],
+ [ 'opt_mod', %q{ '%s' % [ true ] }, ],
+
+ [ 'opt_eq', %q{ 1 == 1 }, ],
+ [ 'opt_eq', <<~'},', ], # {
+ class X; def == other; true; end; end
+ X.new == true
+ },
+ [ 'opt_neq', %q{ 1 != 0 }, ],
+ [ 'opt_neq', <<~'},', ], # {
+ class X; def != other; true; end; end
+ X.new != true
+ },
+
+ [ 'opt_lt', %q{ -1 < 0 }, ],
+ [ 'opt_lt', %q{ -1.0 < 0.0 }, ],
+ [ 'opt_lt', %q{ -0.0.prev_float < 0.0 }, ],
+ [ 'opt_lt', %q{ ?a < ?z }, ],
+ [ 'opt_le', %q{ -1 <= 0 }, ],
+ [ 'opt_le', %q{ -1.0 <= 0.0 }, ],
+ [ 'opt_le', %q{ -0.0.prev_float <= 0.0 }, ],
+ [ 'opt_le', %q{ ?a <= ?z }, ],
+ [ 'opt_gt', %q{ 1 > 0 }, ],
+ [ 'opt_gt', %q{ 1.0 > 0.0 }, ],
+ [ 'opt_gt', %q{ +0.0.next_float > 0.0 }, ],
+ [ 'opt_gt', %q{ ?z > ?a }, ],
+ [ 'opt_ge', %q{ 1 >= 0 }, ],
+ [ 'opt_ge', %q{ 1.0 >= 0.0 }, ],
+ [ 'opt_ge', %q{ +0.0.next_float >= 0.0 }, ],
+ [ 'opt_ge', %q{ ?z >= ?a }, ],
+
+ [ 'opt_ltlt', %q{ '' << 'true' }, ],
+ [ 'opt_ltlt', %q{ ([] << 'true').join }, ],
+ [ 'opt_ltlt', %q{ (1 << 31) == 2147483648 }, ],
+
+ [ 'opt_aref', %q{ ['true'][0] }, ],
+ [ 'opt_aref', %q{ { 0 => 'true'}[0] }, ],
+ [ 'opt_aref', %q{ 'true'[0] == ?t }, ],
+ [ 'opt_aset', %q{ [][0] = true }, ],
+ [ 'opt_aset', %q{ {}[0] = true }, ],
+ [ 'opt_aset', %q{ x = 'frue'; x[0] = 't'; x }, ],
+ [ 'opt_aset', <<~'},', ], # {
+ # opt_aref / opt_aset mixup situation
+ class X; def x; {}; end; end
+ x = X.new
+ x&.x[true] ||= true # here
+ },
+
+ [ 'opt_aref_with', %q{ { 'true' => true }['true'] }, ],
+ [ 'opt_aref_with', %q{ Struct.new(:nil).new['nil'].nil? }, ],
+ [ 'opt_aset_with', %q{ {}['true'] = true }, ],
+ [ 'opt_aset_with', %q{ Struct.new(:true).new['true'] = true }, ],
+
+ [ 'opt_length', %q{ 'true' .length == 4 }, ],
+ [ 'opt_length', %q{ :true .length == 4 }, ],
+ [ 'opt_length', %q{ [ 'true' ] .length == 1 }, ],
+ [ 'opt_length', %q{ { 'true' => 1 }.length == 1 }, ],
+ [ 'opt_size', %q{ 'true' .size == 4 }, ],
+ [ 'opt_size', %q{ 1.size >= 4 }, ],
+ [ 'opt_size', %q{ [ 'true' ] .size == 1 }, ],
+ [ 'opt_size', %q{ { 'true' => 1 }.size == 1 }, ],
+ [ 'opt_empty_p', %q{ ''.empty? }, ],
+ [ 'opt_empty_p', %q{ [].empty? }, ],
+ [ 'opt_empty_p', %q{ {}.empty? }, ],
+ [ 'opt_empty_p', %q{ Queue.new.empty? }, ],
+
+ [ 'opt_succ', %q{ 1.succ == 2 }, ],
+ if defined? $FIXNUM_MAX then
+ [ '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', <<~'},', ], # {
+ class X; def !; true; end; end
+ ! X.new
+ },
+
+ [ 'opt_regexpmatch1', %q{ /true/ =~ 'true' && $~ }, ],
+ [ 'opt_regexpmatch1', <<~'},', ], # {
+ class Regexp; def =~ other; true; end; end
+ /true/ =~ 'true'
+ },
+ [ 'opt_regexpmatch2', %q{ 'true' =~ /true/ && $~ }, ],
+ [ 'opt_regexpmatch2', <<~'},', ], # {
+ class String; def =~ other; true; end; end
+ 'true' =~ /true/
+ },
+]
+
+tests.compact.each {|(insn, expr, *a)| assert_equal 'true', expr, insn, *a }
diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb
new file mode 100644
index 0000000000..89c00d0b88
--- /dev/null
+++ b/bootstraptest/test_io.rb
@@ -0,0 +1,112 @@
+assert_finish 5, %q{
+ r, w = IO.pipe
+ t1 = Thread.new { r.sysread(1) }
+ t2 = Thread.new { r.sysread(1) }
+ sleep 0.01 until t1.stop? and t2.stop?
+ w.write "a"
+ w.write "a"
+}, '[ruby-dev:31866]'
+
+assert_finish 10, %q{
+ begin
+ require "io/nonblock"
+ require "timeout"
+ timeout(3) do
+ r, w = IO.pipe
+ w.nonblock?
+ w.nonblock = true
+ w.write_nonblock("a" * 100000)
+ w.nonblock = false
+ t1 = Thread.new { w.write("b" * 4096) }
+ t2 = Thread.new { w.write("c" * 4096) }
+ sleep 0.5
+ r.sysread(4096).length
+ sleep 0.5
+ r.sysread(4096).length
+ t1.join
+ t2.join
+ end
+ rescue LoadError, Timeout::Error, NotImplementedError
+ end
+}, '[ruby-dev:32566]'
+
+assert_finish 1, %q{
+ r, w = IO.pipe
+ Thread.new {
+ w << "ab"
+ sleep 0.01
+ w << "ab"
+ }
+ r.gets("abab")
+}
+
+assert_equal 'ok', %q{
+ require 'tmpdir'
+ begin
+ tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}"
+ rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
+ rescue Errno::EEXIST
+ retry
+ end
+ save = STDIN.dup
+ STDIN.reopen(rw)
+ STDIN.reopen(save)
+ rw.close
+ File.unlink(tmpname)
+ :ok
+}
+
+assert_equal 'ok', %q{
+ require 'tmpdir'
+ begin
+ tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}"
+ rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
+ rescue Errno::EEXIST
+ retry
+ end
+ save = STDIN.dup
+ STDIN.reopen(rw)
+ STDIN.print "a"
+ STDIN.reopen(save)
+ rw.close
+ File.unlink(tmpname)
+ :ok
+}
+
+assert_equal 'ok', %q{
+ dup = STDIN.dup
+ dupfd = dup.fileno
+ dupfd == STDIN.dup.fileno ? :ng : :ok
+}, '[ruby-dev:46834]'
+
+assert_normal_exit %q{
+ ARGF.set_encoding "foo"
+}
+
+10.times do
+ assert_normal_exit %q{
+ at_exit { p :foo }
+
+ megacontent = "abc" * 12345678
+ #File.open("megasrc", "w") {|f| f << megacontent }
+
+ t0 = Thread.main
+ Thread.new { sleep 0.001 until t0.stop?; Process.kill(:INT, $$) }
+
+ r1, w1 = IO.pipe
+ r2, w2 = IO.pipe
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read; r2.close }
+ IO.copy_stream(r1, w2) rescue nil
+ w2.close
+ r1.close
+ t1.join
+ t2.join
+ }, 'megacontent-copy_stream', ["INT"], :timeout => 10 or break
+end
+
+assert_normal_exit %q{
+ r, w = IO.pipe
+ STDOUT.reopen(w)
+ STDOUT.reopen(__FILE__, "r")
+}, '[ruby-dev:38131]'
diff --git a/bootstraptest/test_jump.rb b/bootstraptest/test_jump.rb
new file mode 100644
index 0000000000..595aaa7c4b
--- /dev/null
+++ b/bootstraptest/test_jump.rb
@@ -0,0 +1,308 @@
+assert_equal %q{ok}, %q{
+ def m
+ :ng1
+ mm{
+ yield
+ }
+ :ng2
+ end
+
+ def mm
+ :ng3
+ yield
+ :ng4
+ end
+
+ m{
+ break :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ 3.times{
+ break :ok
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ throw :foo
+ }
+}
+assert_equal %q{false}, %q{
+ catch(:foo){
+ throw :foo, false
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ throw :foo, nil
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ throw :foo, :ok
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ 1.times{
+ throw :foo
+ }
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ 1.times{
+ throw :foo, :ok
+ }
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ catch(:bar){
+ throw :foo, :ok
+ }
+ :ng
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ catch(:bar){
+ 1.times{
+ throw :foo, :ok
+ }
+ }
+ :ng
+ }
+}
+assert_equal %q{2}, %q{
+ module Enumerable
+ def all_?
+ self.each{|e|
+ unless yield(e)
+ return false
+ end
+ }
+ true
+ end
+ end
+
+ xxx = 0
+ [1,2].each{|bi|
+ [3,4].each{|bj|
+ [true, nil, true].all_?{|be| be}
+ break
+ }
+ xxx += 1
+ }
+ xxx
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ end
+
+ m{
+ begin
+ ensure
+ break :ok
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ :ok
+ end
+ i=0
+ m{
+ if i>10
+ i*i
+ else
+ i+=1
+ next
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ end
+
+ m{
+ next :ok
+ }
+}
+assert_equal %q{131}, %q{
+ def m
+ yield + 10
+ end
+ i=0
+ m{
+ if i>10
+ i*i
+ else
+ i+=1
+ redo
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+begin
+ eval %q{
+ 1.times{
+ retry
+ }
+ }
+rescue SyntaxError
+ :ok
+end
+}
+assert_equal %q{3}, %q{
+ def m
+ return 3
+ end
+ m
+}
+assert_equal %q{ok}, %q{
+ def m
+ :ng1
+ mm{
+ return :ok
+ }
+ :ng2
+ end
+
+ def mm
+ :ng3
+ yield
+ :ng4
+ end
+ m
+}
+assert_equal %q{100}, %q{
+ $i = 0
+ def m
+ begin
+ iter{
+ return
+ }
+ ensure
+ $i = 100
+ end
+ end
+
+ def iter
+ yield
+ end
+ m
+ $i
+}
+assert_equal %q{ok}, %q{
+ def m
+ begin
+ raise
+ rescue
+ return :ok
+ end
+ :ng
+ end
+ m
+}
+assert_equal %q{1}, %q{
+ def m
+ begin
+ raise
+ rescue
+ return 1
+ end
+ end
+
+ m
+}
+assert_equal %q{1}, %q{
+ def m
+ begin
+ #
+ ensure
+ return 1
+ end
+ end
+
+ m
+}
+assert_equal 'ok', %q{
+ begin
+ catch {|t| throw t, :ok }
+ rescue ArgumentError
+ :ng
+ end
+}, '[ruby-dev:31609]'
+
+assert_equal "1", %q{
+ catch do |t|
+ begin
+ throw t, 1
+ 2
+ ensure
+ 3
+ end
+ end
+}, "[ruby-dev:31698]"
+
+assert_normal_exit %q{
+ f = 0
+ 1.times do
+ begin
+ f += 1
+ ensure
+ redo unless f > 2
+ end
+ end
+}
+
+assert_normal_exit %q{
+ -> do
+ 1.times do
+ begin
+ raise
+ rescue
+ return
+ end
+ end
+ end.call
+}
+
+assert_normal_exit %q{
+ while true
+ begin
+ raise
+ next
+ rescue
+ end
+ break
+ end
+}, '[ruby-core:28172]'
+
+assert_equal "true", %q{
+ class Object
+ def return_eigenclass
+ class << self
+ return self
+ end
+ end
+ end
+ s = "foo"
+ s.return_eigenclass == class << s; self; end
+}, '[ruby-core:21379]'
+
+assert_equal "true", %q{
+ class Object
+ def yield_eigenclass
+ class << self
+ yield self
+ end
+ end
+ end
+ s = "foo"
+ s.yield_eigenclass {|c| c == class << s; self; end }
+}, '[ruby-dev:40975]'
diff --git a/bootstraptest/test_literal.rb b/bootstraptest/test_literal.rb
new file mode 100644
index 0000000000..9b3c10d519
--- /dev/null
+++ b/bootstraptest/test_literal.rb
@@ -0,0 +1,247 @@
+# empty program
+assert_equal '', ''
+assert_equal '', ' '
+assert_equal '', "\n"
+
+# special const
+assert_equal 'true', 'true'
+assert_equal 'TrueClass', 'true.class'
+assert_equal 'false', 'false'
+assert_equal 'FalseClass', 'false.class'
+assert_equal '', 'nil'
+assert_equal 'nil', 'nil.inspect'
+assert_equal 'NilClass', 'nil.class'
+assert_equal 'sym', ':sym'
+assert_equal ':sym', ':sym.inspect'
+assert_equal 'Symbol', ':sym.class'
+assert_equal '1234', '1234'
+assert_equal 'Integer', '1234.class'
+assert_equal '1234', '1_2_3_4'
+assert_equal 'Integer', '1_2_3_4.class'
+assert_equal '18', '0x12'
+assert_equal 'Integer', '0x12.class'
+assert_equal '15', '0o17'
+assert_equal 'Integer', '0o17.class'
+assert_equal '5', '0b101'
+assert_equal 'Integer', '0b101.class'
+assert_equal '123456789012345678901234567890', '123456789012345678901234567890'
+assert_equal 'Integer', '123456789012345678901234567890.class'
+assert_equal '2.0', '2.0'
+assert_equal 'Float', '1.3.class'
+
+# self
+assert_equal 'main', 'self'
+assert_equal 'Object', 'self.class'
+
+# string literal
+assert_equal 'a', '?a'
+assert_equal 'String', '?a.class'
+assert_equal 'A', '?A'
+assert_equal 'String', '?A.class'
+assert_equal "\n", '?\n'
+assert_equal 'String', '?\n.class'
+assert_equal ' ', '?\ '
+assert_equal 'String', '?\ .class'
+assert_equal 'string', "'string'"
+assert_equal 'string', '"string"'
+assert_equal 'string', '%(string)'
+assert_equal 'string', '%q(string)'
+assert_equal 'string', '%Q(string)'
+assert_equal 'string string', '"string string"'
+assert_equal ' ', '" "'
+assert_equal "\0", '"\0"'
+assert_equal "\1", '"\1"'
+assert_equal "3", '"\x33"'
+assert_equal "\n", '"\n"'
+
+# dynamic string literal
+assert_equal '2', '"#{1 + 1}"'
+assert_equal '16', '"#{2 ** 4}"'
+assert_equal 'string', 's = "string"; "#{s}"'
+
+# dynamic symbol literal
+assert_equal 'a3c', ':"a#{1+2}c"'
+assert_equal ':a3c', ':"a#{1+2}c".inspect'
+assert_equal 'Symbol', ':"a#{1+2}c".class'
+
+# xstring
+assert_equal "foo\n", %q(`echo foo`)
+assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
+
+# regexp
+assert_equal '', '//.source'
+assert_equal 'Regexp', '//.class'
+assert_equal '0', '// =~ "a"'
+assert_equal '0', '// =~ ""'
+assert_equal 'a', '/a/.source'
+assert_equal 'Regexp', '/a/.class'
+assert_equal '0', '/a/ =~ "a"'
+assert_equal '0', '/test/ =~ "test"'
+assert_equal '', '/test/ =~ "tes"'
+assert_equal '0', 're = /test/; re =~ "test"'
+assert_equal '0', 'str = "test"; /test/ =~ str'
+assert_equal '0', 're = /test/; str = "test"; re =~ str'
+
+# dynamic regexp
+assert_equal 'regexp', %q(/re#{'ge'}xp/.source)
+assert_equal 'Regexp', %q(/re#{'ge'}xp/.class)
+
+# array
+assert_equal 'Array', '[].class'
+assert_equal '0', '[].size'
+assert_equal '0', '[].length'
+assert_equal '[]', '[].inspect'
+assert_equal 'Array', '[0].class'
+assert_equal '1', '[3].size'
+assert_equal '[3]', '[3].inspect'
+assert_equal '3', 'a = [3]; a[0]'
+assert_equal 'Array', '[1,2].class'
+assert_equal '2', '[1,2].size'
+assert_equal '[1, 2]', '[1,2].inspect'
+assert_equal 'Array', '[1,2,3,4,5].class'
+assert_equal '5', '[1,2,3,4,5].size'
+assert_equal '[1, 2, 3, 4, 5]', '[1,2,3,4,5].inspect'
+assert_equal '1', 'a = [1,2]; a[0]'
+assert_equal '2', 'a = [1,2]; a[1]'
+assert_equal 'Array', 'a = [1 + 2, 3 + 4, 5 + 6]; a.class'
+assert_equal '[3, 7, 11]', 'a = [1 + 2, 3 + 4, 5 + 6]; a.inspect'
+assert_equal '7', 'a = [1 + 2, 3 + 4, 5 + 6]; a[1]'
+assert_equal '1', '([0][0] += 1)'
+assert_equal '1', '([2][0] -= 1)'
+assert_equal 'Array', 'a = [obj = Object.new]; a.class'
+assert_equal '1', 'a = [obj = Object.new]; a.size'
+assert_equal 'true', 'a = [obj = Object.new]; a[0] == obj'
+assert_equal '5', 'a = [1,2,3]; a[1] = 5; a[1]'
+assert_equal 'bar', '[*:foo];:bar'
+assert_equal '[1, 2]', 'def nil.to_a; [2]; end; [1, *nil]'
+assert_equal '[1, 2]', 'def nil.to_a; [1, 2]; end; [*nil]'
+assert_equal '[0, 1, {2=>3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]"
+
+
+# hash
+assert_equal 'Hash', '{}.class'
+assert_equal '{}', '{}.inspect'
+assert_equal 'Hash', '{1=>2}.class'
+assert_equal '{1=>2}', '{1=>2}.inspect'
+assert_equal '2', 'h = {1 => 2}; h[1]'
+assert_equal '0', 'h = {1 => 2}; h.delete(1); h.size'
+assert_equal '', 'h = {1 => 2}; h.delete(1); h[1]'
+assert_equal '2', 'h = {"string" => "literal", "goto" => "hell"}; h.size'
+assert_equal 'literal', 'h = {"string"=>"literal", "goto"=>"hell"}; h["string"]'
+assert_equal 'hell', 'h = {"string"=>"literal", "goto"=>"hell"}; h["goto"]'
+
+# range
+assert_equal 'Range', '(1..2).class'
+assert_equal '1..2', '(1..2).inspect'
+assert_equal '1', '(1..2).begin'
+assert_equal '2', '(1..2).end'
+assert_equal 'false', '(1..2).exclude_end?'
+assert_equal 'Range', 'r = 1..2; r.class'
+assert_equal '1..2', 'r = 1..2; r.inspect'
+assert_equal '1', 'r = 1..2; r.begin'
+assert_equal '2', 'r = 1..2; r.end'
+assert_equal 'false', 'r = 1..2; r.exclude_end?'
+assert_equal 'Range', '(1...3).class'
+assert_equal '1...3', '(1...3).inspect'
+assert_equal '1', '(1...3).begin'
+assert_equal '3', '(1...3).end'
+assert_equal 'true', '(1...3).exclude_end?'
+assert_equal 'Range', 'r = (1...3); r.class'
+assert_equal '1...3', 'r = (1...3); r.inspect'
+assert_equal '1', 'r = (1...3); r.begin'
+assert_equal '3', 'r = (1...3); r.end'
+assert_equal 'true', 'r = (1...3); r.exclude_end?'
+assert_equal 'Range', 'r = (1+2 .. 3+4); r.class'
+assert_equal '3..7', 'r = (1+2 .. 3+4); r.inspect'
+assert_equal '3', 'r = (1+2 .. 3+4); r.begin'
+assert_equal '7', 'r = (1+2 .. 3+4); r.end'
+assert_equal 'false', 'r = (1+2 .. 3+4); r.exclude_end?'
+assert_equal 'Range', 'r = (1+2 ... 3+4); r.class'
+assert_equal '3...7', 'r = (1+2 ... 3+4); r.inspect'
+assert_equal '3', 'r = (1+2 ... 3+4); r.begin'
+assert_equal '7', 'r = (1+2 ... 3+4); r.end'
+assert_equal 'true', 'r = (1+2 ... 3+4); r.exclude_end?'
+assert_equal 'Range', 'r = ("a".."c"); r.class'
+assert_equal '"a".."c"', 'r = ("a".."c"); r.inspect'
+assert_equal 'a', 'r = ("a".."c"); r.begin'
+assert_equal 'c', 'r = ("a".."c"); r.end'
+
+assert_equal 'String', '__FILE__.class'
+assert_equal 'Integer', '__LINE__.class'
+
+###
+
+assert_equal 'ok', %q{
+ # this cause "called on terminated object".
+ ObjectSpace.each_object(Module) {|m| m.name.inspect }
+ :ok
+}
+
+assert_normal_exit %q{
+ begin
+ r = 0**-1
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34524]'
+
+assert_normal_exit %q{
+ begin
+ r = Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34536]'
+
+assert_equal 'ok', %q{
+ "#{}""#{}ok"
+}, '[ruby-dev:38968]'
+
+assert_equal 'ok', %q{
+ "#{}o""#{}k""#{}"
+}, '[ruby-core:25284]'
+
+assert_equal 'ok', %q{ # long array literal
+ x = nil
+ eval "a = [#{(1..10_000).map{'x'}.join(", ")}]"
+ :ok
+}
+
+assert_equal 'ok', %q{ # long array literal (optimized)
+ eval "a = [#{(1..10_000).to_a.join(", ")}]"
+ :ok
+}
+
+assert_equal 'ok', %q{ # long hash literal
+ x = nil
+ eval "a = {#{(1..10_000).map{|n| "#{n} => x"}.join(', ')}}"
+ :ok
+}
+
+assert_equal 'ok', %q{ # long hash literal (optimized)
+ eval "a = {#{(1..10_000).map{|n| "#{n} => #{n}"}.join(', ')}}"
+ :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
new file mode 100644
index 0000000000..4316c9e040
--- /dev/null
+++ b/bootstraptest/test_literal_suffix.rb
@@ -0,0 +1,54 @@
+# numbers with suffix
+assert_equal '0/1', '0r'
+assert_equal 'Rational', '0r.class'
+assert_equal '1/1', '1r'
+assert_equal 'Rational', '1r.class'
+assert_equal '-1/1', '-1r'
+assert_equal 'Rational', '(-1r).class'
+assert_equal '1/1', '0x1r'
+assert_equal 'Rational', '0x1r.class'
+assert_equal '1/1', '0b1r'
+assert_equal 'Rational', '0b1r.class'
+assert_equal '1/1', '0d1r'
+assert_equal 'Rational', '0d1r.class'
+assert_equal '1/1', '0o1r'
+assert_equal 'Rational', '0o1r.class'
+assert_equal '1/1', '01r'
+assert_equal 'Rational', '01r.class'
+assert_equal '6/5', '1.2r'
+assert_equal 'Rational', '1.2r.class'
+assert_equal '-6/5', '-1.2r'
+assert_equal 'Rational', '(-1.2r).class'
+assert_equal '0+0i', '0i'
+assert_equal 'Complex', '0i.class'
+assert_equal '0+1i', '1i'
+assert_equal 'Complex', '1i.class'
+assert_equal '0+1i', '0x1i'
+assert_equal 'Complex', '0x1i.class'
+assert_equal '0+1i', '0b1i'
+assert_equal 'Complex', '0b1i.class'
+assert_equal '0+1i', '0d1i'
+assert_equal 'Complex', '0d1i.class'
+assert_equal '0+1i', '0o1i'
+assert_equal 'Complex', '0o1i.class'
+assert_equal '0+1i', '01i'
+assert_equal 'Complex', '01i.class'
+assert_equal '0+1.2i', '1.2i'
+assert_equal 'Complex', '1.2i.class'
+assert_equal '0+1/1i', '1ri'
+assert_equal 'Complex', '1ri.class'
+assert_equal '0+6/5i', '1.2ri'
+assert_equal 'Complex', '1.2ri.class'
+assert_equal '0+10.0i', '1e1i'
+assert_equal 'Complex', '1e1i.class'
+assert_equal '1', '1if true'
+assert_equal '1', '1rescue nil'
+assert_equal '10000000000000000001/10000000000000000000',
+ '1.0000000000000000001r'
+
+assert_equal 'syntax error, unexpected tIDENTIFIER, 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',
+ %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',
+ %q{begin eval('1e1r', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end}
diff --git a/bootstraptest/test_load.rb b/bootstraptest/test_load.rb
new file mode 100644
index 0000000000..e63c93a8f4
--- /dev/null
+++ b/bootstraptest/test_load.rb
@@ -0,0 +1,27 @@
+assert_equal 'ok', %q{
+ open("require-lock-test.rb", "w") {|f|
+ f.puts "sleep 0.1"
+ f.puts "module M"
+ f.puts "end"
+ }
+ $:.unshift Dir.pwd
+ vs = (1..2).map {|i|
+ Thread.start {
+ require "require-lock-test"
+ M
+ }
+ }.map {|t| t.value }
+ vs[0] == M && vs[1] == M ? :ok : :ng
+}, '[ruby-dev:32048]'
+
+assert_equal 'ok', %q{
+ %w[a a/foo b].each {|d| Dir.mkdir(d)}
+ open("b/foo", "w") {|f| f.puts "$ok = :ok"}
+ $:.replace(%w[a b])
+ begin
+ load "foo"
+ $ok
+ rescue => e
+ e.message
+ end
+}, '[ruby-dev:38097]'
diff --git a/bootstraptest/test_marshal.rb b/bootstraptest/test_marshal.rb
new file mode 100644
index 0000000000..7e34176169
--- /dev/null
+++ b/bootstraptest/test_marshal.rb
@@ -0,0 +1,5 @@
+
+assert_normal_exit %q{
+ Marshal.load(Marshal.dump({"k"=>"v"}), lambda {|v| v})
+}
+
diff --git a/bootstraptest/test_massign.rb b/bootstraptest/test_massign.rb
new file mode 100644
index 0000000000..0f63dd424a
--- /dev/null
+++ b/bootstraptest/test_massign.rb
@@ -0,0 +1,183 @@
+assert_equal '[[1], 2, 3]', '*v1, (a, b) = [1,[2, 3]]; [v1, a, b]'
+assert_equal '[[1], 2, 3]', '*v1,(*), (a, b) = [1,:x,[2, 3]]; [v1, a, b]'
+
+assert_equal '[]', '*a = *nil; a'
+assert_equal '[nil]', '*a = nil; a'
+assert_equal '2', 'a, a = 1, 2; a', "[ruby-dev:31522]"
+assert_equal '[1, 2]', 'a, b = 1, 2'
+assert_equal '[1, 2]', %q{
+ ans = []
+ trace_var(:$a){|v| ans << v}
+ trace_var(:$b){|v| ans << v}
+ $a, $b = 1, 2
+ ans
+}
+
+assert_equal 'ok', %q{
+ r = :ok
+ :ng.tap {|(r)|}
+ r
+}, '[ruby-dev:31507]'
+
+=begin
+# generated by this script:
+
+3.times{|i|
+ 8.times{|e|
+ ary = (0...e).to_a
+ a,b,c,d,e,f = nil
+ vals = %w(a b c d e f)
+ vals[i] = '*' + vals[i]
+ program = "#{vals.join(", ")} = *ary"
+ eval(program)
+ ans = [a,b,c,d,e,f]
+ puts %Q{
+ assert_equal "#{ans.inspect}", %q{
+ ary = #{ary.inspect}
+ #{program}; [a, b, c, d, e, f]
+ }}
+ }
+}
+=end
+
+ assert_equal "[[], nil, nil, nil, nil, nil]", %q{
+ ary = []
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, nil, nil, nil, nil]", %q{
+ ary = [0]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, nil, nil, nil]", %q{
+ ary = [0, 1]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[0], 1, 2, 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[0, 1], 2, 3, 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[nil, [], nil, nil, nil, nil]", %q{
+ ary = []
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], nil, nil, nil, nil]", %q{
+ ary = [0]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, nil, nil, nil]", %q{
+ ary = [0, 1]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [1], 2, 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [1, 2], 3, 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[nil, nil, [], nil, nil, nil]", %q{
+ ary = []
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, nil, [], nil, nil, nil]", %q{
+ ary = [0]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], nil, nil, nil]", %q{
+ ary = [0, 1]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [2], 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [2, 3], 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+
+#
+assert_equal 'ok', %q{
+ a,s=[],"aaa"
+ 300.times { a<<s; s=s.succ }
+ eval <<-END__
+ GC.stress=true
+ Fiber.new do
+ #{ a.join(",") },*zzz=1
+ end.resume
+ END__
+ :ok
+}, '[ruby-dev:32581]'
+
+assert_equal 'ok', %q{
+ while true
+ *, z = 1
+ break
+ end
+ :ok
+}, '[ruby-dev:32892]'
diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb
new file mode 100644
index 0000000000..3462aa9434
--- /dev/null
+++ b/bootstraptest/test_method.rb
@@ -0,0 +1,1192 @@
+# regular argument
+assert_equal '1', 'def m() 1 end; m()'
+assert_equal '1', 'def m(a) a end; m(1)'
+assert_equal '[1, 2]', 'def m(a,b) [a, b] end; m(1,2)'
+assert_equal '[1, 2, 3]', 'def m(a,b,c) [a, b, c] end; m(1,2,3)'
+assert_match /\Awrong number of arguments \(.*\b1\b.* 0\)\z/, %q{
+ def m; end
+ begin
+ m(1)
+ rescue => e
+ e.message
+ end
+}
+
+assert_match /\Awrong number of arguments \(.*\b0\b.* 1\)\z/, %q{
+ def m a; end
+ begin
+ m
+ rescue => e
+ e.message
+ end
+}
+
+# default argument
+assert_equal '1', 'def m(x=1) x end; m()'
+assert_equal '1', 'def m(x=7) x end; m(1)'
+assert_equal '1', 'def m(a,x=1) x end; m(7)'
+assert_equal '1', 'def m(a,x=7) x end; m(7,1)'
+assert_equal '1', 'def m(a,b,x=1) x end; m(7,7)'
+assert_equal '1', 'def m(a,b,x=7) x end; m(7,7,1)'
+assert_equal '1', 'def m(a,x=1,y=1) x end; m(7)'
+assert_equal '1', 'def m(a,x=1,y=1) y end; m(7)'
+assert_equal '1', 'def m(a,x=7,y=1) x end; m(7,1)'
+assert_equal '1', 'def m(a,x=7,y=1) y end; m(7,1)'
+assert_equal '1', 'def m(a,x=7,y=7) x end; m(7,1,1)'
+assert_equal '1', 'def m(a,x=7,y=7) y end; m(7,1,1)'
+
+# rest argument
+assert_equal '[]', 'def m(*a) a end; m().inspect'
+assert_equal '[1]', 'def m(*a) a end; m(1).inspect'
+assert_equal '[1, 2]', 'def m(*a) a end; m(1,2).inspect'
+assert_equal '[]', 'def m(x,*a) a end; m(7).inspect'
+assert_equal '[1]', 'def m(x,*a) a end; m(7,1).inspect'
+assert_equal '[1, 2]', 'def m(x,*a) a end; m(7,1,2).inspect'
+assert_equal '[]', 'def m(x,y,*a) a end; m(7,7).inspect'
+assert_equal '[1]', 'def m(x,y,*a) a end; m(7,7,1).inspect'
+assert_equal '[1, 2]', 'def m(x,y,*a) a end; m(7,7,1,2).inspect'
+assert_equal '[]', 'def m(x,y=7,*a) a end; m(7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=7,*a) zz end; m(7,7,7,1).inspect'
+
+# block argument
+assert_equal 'Proc', 'def m(&block) block end; m{}.class'
+assert_equal 'nil', 'def m(&block) block end; m().inspect'
+assert_equal 'Proc', 'def m(a,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,&block) block end; m(7).inspect'
+assert_equal '1', 'def m(a,&block) a end; m(1){}'
+assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,b=nil,&block) block end; m(7).inspect'
+assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7,7){}.class'
+assert_equal '1', 'def m(a,b=nil,&block) b end; m(7,1){}'
+assert_equal 'Proc', 'def m(a,b=nil,*c,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,b=nil,*c,&block) block end; m(7).inspect'
+assert_equal '1', 'def m(a,b=nil,*c,&block) a end; m(1).inspect'
+assert_equal '1', 'def m(a,b=1,*c,&block) b end; m(7).inspect'
+assert_equal '1', 'def m(a,b=7,*c,&block) b end; m(7,1).inspect'
+assert_equal '[1]', 'def m(a,b=7,*c,&block) c end; m(7,7,1).inspect'
+
+# splat
+assert_equal '1', 'def m(a) a end; m(*[1])'
+assert_equal '1', 'def m(x,a) a end; m(7,*[1])'
+assert_equal '1', 'def m(x,y,a) a end; m(7,7,*[1])'
+assert_equal '1', 'def m(a,b) a end; m(*[1,7])'
+assert_equal '1', 'def m(a,b) b end; m(*[7,1])'
+assert_equal '1', 'def m(x,a,b) b end; m(7,*[7,1])'
+assert_equal '1', 'def m(x,y,a,b) b end; m(7,7,*[7,1])'
+assert_equal '1', 'def m(a,b,c) a end; m(*[1,7,7])'
+assert_equal '1', 'def m(a,b,c) b end; m(*[7,1,7])'
+assert_equal '1', 'def m(a,b,c) c end; m(*[7,7,1])'
+assert_equal '1', 'def m(x,a,b,c) a end; m(7,*[1,7,7])'
+assert_equal '1', 'def m(x,y,a,b,c) a end; m(7,7,*[1,7,7])'
+
+# hash argument
+assert_equal '1', 'def m(h) h end; m(7=>1)[7]'
+assert_equal '1', 'def m(h) h end; m(7=>1).size'
+assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7)[7]'
+assert_equal '2', 'def m(h) h end; m(7=>1, 8=>7).size'
+assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7, 9=>7)[7]'
+assert_equal '3', 'def m(h) h end; m(7=>1, 8=>7, 9=>7).size'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1)[7]'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7)[7]'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7, 9=>7)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7, 9=>7)[7]'
+
+# block argument
+assert_equal '1', %q(def m(&block) mm(&block) end
+ def mm() yield 1 end
+ m {|a| a })
+assert_equal '1', %q(def m(x,&block) mm(x,&block) end
+ def mm(x) yield 1 end
+ m(7) {|a| a })
+assert_equal '1', %q(def m(x,y,&block) mm(x,y,&block) end
+ def mm(x,y) yield 1 end
+ m(7,7) {|a| a })
+
+# recursive call
+assert_equal '1', %q(def m(n) n == 0 ? 1 : m(n-1) end; m(5))
+
+# instance method
+assert_equal '1', %q(class C; def m() 1 end end; C.new.m)
+assert_equal '1', %q(class C; def m(a) a end end; C.new.m(1))
+assert_equal '1', %q(class C; def m(a = 1) a end end; C.new.m)
+assert_equal '[1]', %q(class C; def m(*a) a end end; C.new.m(1).inspect)
+assert_equal '1', %q( class C
+ def m() mm() end
+ def mm() 1 end
+ end
+ C.new.m )
+
+# singleton method (const)
+assert_equal '1', %q(class C; def C.m() 1 end end; C.m)
+assert_equal '1', %q(class C; def C.m(a) a end end; C.m(1))
+assert_equal '1', %q(class C; def C.m(a = 1) a end end; C.m)
+assert_equal '[1]', %q(class C; def C.m(*a) a end end; C.m(1).inspect)
+assert_equal '1', %q(class C; end; def C.m() 1 end; C.m)
+assert_equal '1', %q(class C; end; def C.m(a) a end; C.m(1))
+assert_equal '1', %q(class C; end; def C.m(a = 1) a end; C.m)
+assert_equal '[1]', %q(class C; end; def C.m(*a) a end; C.m(1).inspect)
+assert_equal '1', %q(class C; def m() 7 end end; def C.m() 1 end; C.m)
+assert_equal '1', %q( class C
+ def C.m() mm() end
+ def C.mm() 1 end
+ end
+ C.m )
+
+# singleton method (lvar)
+assert_equal '1', %q(obj = Object.new; def obj.m() 1 end; obj.m)
+assert_equal '1', %q(obj = Object.new; def obj.m(a) a end; obj.m(1))
+assert_equal '1', %q(obj = Object.new; def obj.m(a=1) a end; obj.m)
+assert_equal '[1]', %q(obj = Object.new; def obj.m(*a) a end; obj.m(1))
+assert_equal '1', %q(class C; def m() 7 end; end
+ obj = C.new
+ def obj.m() 1 end
+ obj.m)
+
+# inheritance
+assert_equal '1', %q(class A; def m(a) a end end
+ class B < A; end
+ B.new.m(1))
+assert_equal '1', %q(class A; end
+ class B < A; def m(a) a end end
+ B.new.m(1))
+assert_equal '1', %q(class A; def m(a) a end end
+ class B < A; end
+ class C < B; end
+ C.new.m(1))
+
+# include
+assert_equal '1', %q(class A; def m(a) a end end
+ module M; end
+ class B < A; include M; end
+ B.new.m(1))
+assert_equal '1', %q(class A; end
+ module M; def m(a) a end end
+ class B < A; include M; end
+ B.new.m(1))
+
+# alias
+assert_equal '1', %q( def a() 1 end
+ alias m a
+ m() )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias :m a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m :a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias :m :a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m a
+ undef a
+ end
+ C.new.m )
+
+# undef
+assert_equal '1', %q( class C
+ def m() end
+ undef m
+ end
+ begin C.new.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A
+ def m() end
+ end
+ class C < A
+ def m() end
+ undef m
+ end
+ begin C.new.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A; def a() end end # [yarv-dev:999]
+ class B < A
+ def b() end
+ undef a, b
+ end
+ begin B.new.a; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A; def a() end end # [yarv-dev:999]
+ class B < A
+ def b() end
+ undef a, b
+ end
+ begin B.new.b; rescue NoMethodError; 1 end )
+
+assert_equal '3', %q{
+ def m1
+ 1
+ end
+ alias m2 m1
+ alias :"#{'m3'}" m1
+ m1 + m2 + m3
+}, '[ruby-dev:32308]'
+assert_equal '1', %q{
+ def foobar
+ end
+ undef :"foo#{:bar}"
+ 1
+}, '[ruby-dev:32308]'
+assert_equal '1', %q{
+ def foobar
+ 1
+ end
+ alias :"bar#{:baz}" :"foo#{:bar}"
+ barbaz
+}, '[ruby-dev:32308]'
+
+# private
+assert_equal '1', %q( class C
+ def m() mm() end
+ def mm() 1 end
+ private :mm
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def m() 7 end
+ private :m
+ end
+ begin C.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C
+ def C.m() mm() end
+ def C.mm() 1 end
+ private_class_method :mm
+ end
+ C.m )
+assert_equal '1', %q( class C
+ def C.m() 7 end
+ private_class_method :m
+ end
+ begin C.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C; def m() 1 end end
+ C.new.m # cache
+ class C
+ alias mm m; private :mm
+ end
+ C.new.m
+ begin C.new.mm; 7; rescue NoMethodError; 1 end )
+
+# nested method
+assert_equal '1', %q( class C
+ def m
+ def mm() 1 end
+ end
+ end
+ C.new.m
+ C.new.mm )
+assert_equal '1', %q( class C
+ def m
+ def mm() 1 end
+ end
+ end
+ instance_eval "C.new.m; C.new.mm" )
+
+# method_missing
+assert_equal ':m', %q( class C
+ def method_missing(mid, *args) mid end
+ end
+ C.new.m.inspect )
+assert_equal ':mm', %q( class C
+ def method_missing(mid, *args) mid end
+ end
+ C.new.mm.inspect )
+assert_equal '[1, 2]', %q( class C
+ def method_missing(mid, *args) args end
+ end
+ C.new.m(1,2).inspect )
+assert_equal '1', %q( class C
+ def method_missing(mid, *args) yield 1 end
+ end
+ C.new.m {|a| a })
+assert_equal 'nil', %q( class C
+ def method_missing(mid, *args, &block) block end
+ end
+ C.new.m.inspect )
+
+# send
+assert_equal '1', %q( class C; def m() 1 end end;
+ C.new.__send__(:m) )
+assert_equal '1', %q( class C; def m() 1 end end;
+ C.new.send(:m) )
+assert_equal '1', %q( class C; def m(a) a end end;
+ C.new.send(:m,1) )
+assert_equal '1', %q( class C; def m(a,b) a end end;
+ C.new.send(:m,1,7) )
+assert_equal '1', %q( class C; def m(x,a=1) a end end;
+ C.new.send(:m,7) )
+assert_equal '1', %q( class C; def m(x,a=7) a end end;
+ C.new.send(:m,7,1) )
+assert_equal '[1, 2]', %q( class C; def m(*a) a end end;
+ C.new.send(:m,1,2).inspect )
+assert_equal '1', %q( class C; def m() 7 end; private :m end
+ begin C.new.public_send(:m); rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C; def m() 1 end; private :m end
+ C.new.send(:m) )
+
+# with block
+assert_equal '[[:ok1, :foo], [:ok2, :foo, :bar]]',
+%q{
+ class C
+ def [](a)
+ $ary << [yield, a]
+ end
+ def []=(a, b)
+ $ary << [yield, a, b]
+ end
+ end
+
+ $ary = []
+ C.new[:foo, &lambda{:ok1}]
+ C.new[:foo, &lambda{:ok2}] = :bar
+ $ary
+}
+
+# with
+assert_equal '[:ok1, [:ok2, 11]]', %q{
+ class C
+ def []
+ $ary << :ok1
+ 10
+ end
+ def []=(a)
+ $ary << [:ok2, a]
+ end
+ end
+ $ary = []
+ C.new[]+=1
+ $ary
+}
+
+# splat and block arguments
+assert_equal %q{[[[:x, :y, :z], NilClass], [[1, :x, :y, :z], NilClass], [[1, 2, :x, :y, :z], NilClass], [[:obj], NilClass], [[1, :obj], NilClass], [[1, 2, :obj], NilClass], [[], Proc], [[1], Proc], [[1, 2], Proc], [[], Proc], [[1], Proc], [[1, 2], Proc], [[:x, :y, :z], Proc], [[1, :x, :y, :z], Proc], [[1, 2, :x, :y, :z], Proc]]}, %q{
+def m(*args, &b)
+ $result << [args, b.class]
+end
+$result = []
+ary = [:x, :y, :z]
+obj = :obj
+b = Proc.new{}
+
+m(*ary)
+m(1,*ary)
+m(1,2,*ary)
+m(*obj)
+m(1,*obj)
+m(1,2,*obj)
+m(){}
+m(1){}
+m(1,2){}
+m(&b)
+m(1,&b)
+m(1,2,&b)
+m(*ary,&b)
+m(1,*ary,&b)
+m(1,2,*ary,&b)
+$result
+}
+
+# aset and splat
+assert_equal '4', %q{class Foo;def []=(a,b,c,d);end;end;Foo.new[1,*a=[2,3]]=4}
+assert_equal '4', %q{class Foo;def []=(a,b,c,d);end;end;def m(&blk)Foo.new[1,*a=[2,3],&blk]=4;end;m{}}
+
+# post test
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4)}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5)}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6)}
+
+assert_equal %q{[1, 2, 3, 4, [5], 6, 7, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)}
+
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4){}}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5){}}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6){}}
+
+assert_equal %q{[1, 2, 3, 4, [5], 6, 7, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11){}}
+
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4)}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4, 5)}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4, 5, 6)}
+
+
+#
+# super
+#
+=begin
+# below programs are generated by this program:
+
+BASE = <<EOS__
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; <TEST>; super; end; end
+EOS__
+
+tests = {
+%q{
+ def m
+} => %q{
+ C1.new.m
+},
+#
+%q{
+ def m a
+} => %q{
+ C1.new.m 1
+},
+%q{
+ def m a
+ a = :a
+} => %q{
+ C1.new.m 1
+},
+#
+%q{
+ def m a, o=:o
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+%q{
+ def m a, o=:o
+ a = :a
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+%q{
+ def m a, o=:o
+ o = :x
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+#
+%q{
+ def m a, *r
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+},
+%q{
+ def m a, *r
+ r = [:x, :y]
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+},
+#
+%q{
+ def m a, o=:o, *r
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+ C1.new.m 1, 2, 3, 4
+},
+#
+%q{
+ def m a, o=:o, *r, &b
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+ C1.new.m 1, 2, 3, 4
+ C1.new.m(1){}
+ C1.new.m(1, 2){}
+ C1.new.m(1, 2, 3){}
+ C1.new.m(1, 2, 3, 4){}
+},
+#
+"def m(m1, m2, o1=:o1, o2=:o2, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+},
+#
+"def m(m1, m2, *r, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+C1.new.m(1,2,3,4,5,6,7)
+C1.new.m(1,2,3,4,5,6,7,8)
+},
+#
+"def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+C1.new.m(1,2,3,4,5,6,7)
+C1.new.m(1,2,3,4,5,6,7,8)
+C1.new.m(1,2,3,4,5,6,7,8,9)
+},
+
+###
+}
+
+
+tests.each{|setup, methods| setup = setup.dup; setup.strip!
+ setup = BASE.gsub(/<TEST>/){setup}
+ methods.split(/\n/).each{|m| m = m.dup; m.strip!
+ next if m.empty?
+ expr = "#{setup}; #{m}"
+ result = eval(expr)
+ puts "assert_equal %q{#{result.inspect}}, %q{\n#{expr}}"
+ puts
+ }
+}
+
+=end
+
+assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2, 3, 4}
+
+assert_equal %q{[:C0_m, [:a]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a
+ a = :a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8)}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2, 3, 4}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1){}}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2){}}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2, 3){}}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2, 3, 4){}}
+
+assert_equal %q{[:C0_m, [1, :x]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ o = :x; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ o = :x; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [:a, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ a = :a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [:a, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ a = :a; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8, 9]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8,9)}
+
+assert_equal %q{[:C0_m, [1]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, []]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m; super; end; end
+; C1.new.m}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal 'ok', %q{
+ class C
+ def x=(n)
+ end
+ def m
+ self.x = :ok
+ end
+ end
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ proc{
+ $SAFE = 1
+ class C
+ def m
+ :ok
+ end
+ end
+ }.call
+ C.new.m
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+ class B
+ def m() :fail end
+ end
+ class C < B
+ undef m
+ begin
+ remove_method :m
+ rescue NameError
+ end
+ end
+ begin
+ C.new.m
+ rescue NameError
+ :ok
+ end
+}, '[ruby-dev:31816], [ruby-dev:31817]'
+
+assert_normal_exit %q{
+ begin
+ Process.setrlimit(Process::RLIMIT_STACK, 4_206_592)
+ # FreeBSD SEGVs this less than 4M + 12K bytes.
+ rescue Exception
+ exit
+ end
+ class C
+ attr "a" * (10*1024*1024)
+ end
+}, '[ruby-dev:31818]'
+
+assert_equal 'ok', %q{
+ class Module
+ def define_method2(name, &block)
+ define_method(name, &block)
+ end
+ end
+ class C
+ define_method2(:m) {|x, y| :fail }
+ end
+ begin
+ C.new.m([1,2])
+ rescue ArgumentError
+ :ok
+ end
+}
+
+assert_not_match /method_missing/, %q{
+ STDERR.reopen(STDOUT)
+ variable_or_mehtod_not_exist
+}
+
+assert_equal '[false, false, false, false, true, true]', %q{
+ class C
+ define_method(:foo) {
+ block_given?
+ }
+ end
+
+ C.new.foo {}
+
+ class D
+ def foo
+ D.module_eval{
+ define_method(:m1){
+ block_given?
+ }
+ }
+ end
+ def bar
+ D.module_eval{
+ define_method(:m2){
+ block_given?
+ }
+ }
+ end
+ end
+
+ D.new.foo
+ D.new.bar{}
+ [C.new.foo, C.new.foo{}, D.new.m1, D.new.m1{}, D.new.m2, D.new.m2{}]
+}, '[ruby-core:14813]'
+
+assert_equal 'ok', %q{
+ class Foo
+ define_method(:foo) do |&b|
+ b.call
+ end
+ end
+ Foo.new.foo do
+ break :ok
+ end
+}, '[ruby-dev:36028]'
+
+assert_equal '[1, 2, [3, 4]]', %q{
+ def regular(a, b, *c)
+ [a, b, c]
+ end
+ regular(*[], 1, *[], *[2, 3], *[], 4)
+}, '[ruby-core:19413]'
+
+assert_equal '[1, [:foo, 3, 4, :foo]]', %q{
+ def regular(a, *b)
+ [a, b]
+ end
+ a = b = [:foo]
+ regular(1, *a, *[3, 4], *b)
+}
+
+assert_equal '["B", "A"]', %q{
+ class A
+ def m
+ 'A'
+ end
+ end
+
+ class B < A
+ define_method(:m) do
+ ['B', super()]
+ end
+ end
+
+ class C < B
+ end
+
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ module Foo
+ def foo
+ begin
+ super
+ rescue NoMethodError
+ :ok
+ end
+ end
+ module_function :foo
+ end
+ Foo.foo
+}, '[ruby-dev:37587]'
+
+assert_equal 'Object#foo', %q{
+ class Object
+ def self.foo
+ "Object.foo"
+ end
+ def foo
+ "Object#foo"
+ end
+ end
+
+ module Foo
+ def foo
+ begin
+ super
+ rescue NoMethodError
+ :ok
+ end
+ end
+ module_function :foo
+ end
+ Foo.foo
+}, '[ruby-dev:37587]'
+
+assert_normal_exit %q{
+ class BasicObject
+ remove_method :method_missing
+ end
+ begin
+ "a".lalala!
+ rescue NoMethodError => e
+ e.message == "undefined method `lalala!' for \"a\":String" ? :ok : :ng
+ end
+}, '[ruby-core:22298]'
+
+assert_equal 'ok', %q{
+ "hello"[0] ||= "H"
+ "ok"
+}
+
+assert_equal 'ok', %q{
+ "hello"[0, 1] ||= "H"
+ "ok"
+}
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:foo) do
+ C.class_eval { remove_method(:foo) }
+ super()
+ end
+ end
+ begin
+ C.new.foo
+ rescue NoMethodError
+ 'ok'
+ end
+}
+assert_equal 'ok', %q{
+ [0][0, &proc{}] += 21
+ 'ok'
+}, '[ruby-core:30534]'
+
+# should not cache when splat
+assert_equal 'ok', %q{
+ class C
+ attr_reader :a
+ def initialize
+ @a = 1
+ end
+ end
+
+ def m *args
+ C.new.a(*args)
+ end
+
+ m()
+ begin
+ m(1)
+ rescue ArgumentError
+ 'ok'
+ end
+}
+
+assert_equal 'DC', %q{
+ $result = []
+
+ class C
+ def foo *args
+ $result << 'C'
+ end
+ end
+ class D
+ def foo *args
+ $result << 'D'
+ end
+ end
+
+ o1 = $o1 = C.new
+ o2 = $o2 = D.new
+
+ args = Object.new
+ def args.to_a
+ test1 $o2, nil
+ []
+ end
+ def test1 o, args
+ o.foo(*args)
+ end
+ test1 o1, args
+ $result.join
+}
+
+assert_equal 'DC', %q{
+ $result = []
+
+ class C
+ def foo *args
+ $result << 'C'
+ end
+ end
+ class D
+ def foo *args
+ $result << 'D'
+ end
+ end
+
+ o1 = $o1 = C.new
+ o2 = $o2 = D.new
+
+ block = Object.new
+ def block.to_proc
+ test2 $o2, %w(a, b, c), nil
+ Proc.new{}
+ end
+ def test2 o, args, block
+ o.foo(*args, &block)
+ end
+ test2 o1, [], block
+ $result.join
+}
diff --git a/bootstraptest/test_objectspace.rb b/bootstraptest/test_objectspace.rb
new file mode 100644
index 0000000000..24a1a0ce2c
--- /dev/null
+++ b/bootstraptest/test_objectspace.rb
@@ -0,0 +1,46 @@
+assert_normal_exit %q{
+ eval("", TOPLEVEL_BINDING)
+ minobj = ObjectSpace.to_enum(:each_object).min_by {|a| a.object_id }
+ maxobj = ObjectSpace.to_enum(:each_object).max_by {|a| a.object_id }
+ (((minobj.object_id-100)..(minobj.object_id+100))+
+ ((maxobj.object_id-100)..(maxobj.object_id+100))).each {|id|
+ begin
+ o = ObjectSpace._id2ref(id)
+ rescue RangeError
+ next
+ end
+ o.inspect if defined?(o.inspect)
+ }
+}, '[ruby-dev:31911]'
+
+assert_normal_exit %q{
+ ary = (1..10).to_a
+ ary.permutation(2) {|x|
+ if x == [1,2]
+ ObjectSpace.each_object(String) {|s|
+ s.clear if !s.frozen? && (s.length == 40 || s.length == 80)
+ }
+ end
+ }
+}, '[ruby-dev:31982]'
+
+assert_normal_exit %q{
+ ary = (1..100).to_a
+ ary.permutation(2) {|x|
+ if x == [1,2]
+ ObjectSpace.each_object(Array) {|o| o.clear if o == ary && o.object_id != ary.object_id }
+ end
+ }
+}, '[ruby-dev:31985]'
+
+assert_normal_exit %q{
+ ObjectSpace.define_finalizer("") do
+ Thread::Mutex.new.lock
+ end
+}, '[ruby-dev:44049]'
+
+assert_normal_exit %q{
+ ObjectSpace.define_finalizer("") do
+ Thread.new {}
+ end
+}, '[ruby-core:37858]'
diff --git a/bootstraptest/test_proc.rb b/bootstraptest/test_proc.rb
new file mode 100644
index 0000000000..c23394e8d2
--- /dev/null
+++ b/bootstraptest/test_proc.rb
@@ -0,0 +1,483 @@
+assert_equal %q{[1, 2, 3]}, %q{
+ def getproc &b
+ b
+ end
+
+ def m
+ yield
+ end
+
+ m{
+ i = 1
+ m{
+ j = 2
+ m{
+ k = 3
+ getproc{
+ [i, j, k]
+ }
+ }
+ }
+ }.call
+}
+assert_equal %q{7}, %q{
+ def make_proc(&b)
+ b
+ end
+
+ def make_closure
+ a = 0
+ make_proc{
+ a+=1
+ }
+ end
+
+ cl = make_closure
+ cl.call + cl.call * cl.call
+}
+assert_equal %q{ok}, %q{
+ class C
+ def foo
+ :ok
+ end
+ end
+
+ def block
+ C.method(:new).to_proc
+ end
+ b = block()
+ b.call.foo
+}
+assert_equal %q{[0, 1, :last, 0, 2, :last]}, %q{
+ def proc &b
+ b
+ end
+
+ pr = []
+ proc{|i_b|
+ p3 = proc{|j_b|
+ pr << proc{|k_b|
+ [i_b, j_b, k_b]
+ }
+ }
+ p3.call(1)
+ p3.call(2)
+ }.call(0)
+
+ pr[0].call(:last).concat pr[1].call(:last)
+}
+assert_equal %q{12}, %q{
+ def iter
+ yield
+ end
+
+ def getproc &b
+ b
+ end
+
+ iter{
+ bvar = 3
+ getproc{
+ bvar2 = 4
+ bvar * bvar2
+ }
+ }.call
+}
+assert_equal %q{200}, %q{
+ def iter
+ yield
+ end
+
+ def getproc &b
+ b
+ end
+
+ loc1 = 0
+ pr1 = iter{
+ bl1 = 1
+ getproc{
+ loc1 += 1
+ bl1 += 1
+ loc1 + bl1
+ }
+ }
+
+ pr2 = iter{
+ bl1 = 1
+ getproc{
+ loc1 += 1
+ bl1 += 1
+ loc1 + bl1
+ }
+ }
+
+ pr1.call; pr2.call
+ pr1.call; pr2.call
+ pr1.call; pr2.call
+ (pr1.call + pr2.call) * loc1
+}
+assert_equal %q{[1, 2]}, %q{
+ def proc(&pr)
+ pr
+ end
+
+ def m
+ a = 1
+ m2{
+ a
+ }
+ end
+
+ def m2
+ b = 2
+ proc{
+ [yield, b]
+ }
+ end
+
+ pr = m
+ x = ['a', 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,]
+ pr.call
+}
+assert_equal %q{1}, %q{
+ def proc(&pr)
+ pr
+ end
+
+ def m
+ a = 1
+ m2{
+ a
+ }
+ end
+
+ def m2
+ b = 2
+ proc{
+ [yield, b]
+ }
+ 100000.times{|x|
+ "#{x}"
+ }
+ yield
+ end
+ m
+}
+assert_equal %q{[:C, :C]}, %q{
+ Const = :top
+ class C
+ Const = :C
+ $pr = proc{
+ (1..2).map{
+ Const
+ }
+ }
+ end
+ $pr.call
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ pr = proc{
+ Const
+ }
+ C.class_eval %q{
+ pr.call
+ }
+}
+assert_equal %q{1}, %q{
+ def m(&b)
+ b
+ end
+
+ m{|e_proctest| e_proctest}.call(1)
+}
+assert_equal %q{12}, %q{
+ def m(&b)
+ b
+ end
+
+ m{|e_proctest1, e_proctest2|
+ a = e_proctest1 * e_proctest2 * 2
+ a * 3
+ }.call(1, 2)
+}
+assert_equal %q{[[], [1], [1, 2], [1, 2, 3]]}, %q{
+ [
+ Proc.new{|*args| args}.call(),
+ Proc.new{|*args| args}.call(1),
+ Proc.new{|*args| args}.call(1, 2),
+ Proc.new{|*args| args}.call(1, 2, 3),
+ ]
+}
+assert_equal %q{[[nil, []], [1, []], [1, [2]], [1, [2, 3]]]}, %q{
+ [
+ Proc.new{|a, *b| [a, b]}.call(),
+ Proc.new{|a, *b| [a, b]}.call(1),
+ Proc.new{|a, *b| [a, b]}.call(1, 2),
+ 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
+ end
+ m{1}.call
+}
+assert_equal %q{3}, %q{
+ def m(&b)
+ b
+ end
+
+ m{
+ a = 1
+ a + 2
+ }.call
+}
+assert_equal %Q{ok\n}, %q{
+ class A; def get_block; proc {puts "ok"} end end
+ block = A.new.get_block
+ GC.start
+ block.call
+}, '[ruby-core:14885]'
+
+assert_equal 'ok', %q{
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end
+}, '[ruby-core:15551]'
+
+assert_equal 'ok', %q{
+ lambda {
+ break :ok
+ :ng
+ }.call
+}, '[ruby-dev:34646]'
+
+assert_equal %q{[:bar, :foo]}, %q{
+ def foo
+ klass = Class.new do
+ define_method(:bar) do
+ return :bar
+ end
+ end
+ [klass.new.bar, :foo]
+ end
+ foo
+}, "[ ruby-Bugs-19304 ]"
+
+assert_equal 'ok', %q{
+ $x = :ok
+ def def7(x, y)
+ x[y]
+ $x = :ng
+ end
+ def test_def7
+ def7(lambda {|x| x.call}, Proc.new {return})
+ $x = :ng
+ end
+ test_def7
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ lambda { a = lambda { return }; $x = :ng; a[]; $x = :ok }.call
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ lambda { a = lambda { break }; $x = :ng; a[]; $x = :ok }.call
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def8
+ $x = :ng
+ lambda { a = Proc.new { return }; a[]}.call
+ $x = :ok
+ end
+ def8
+ $x
+}, '[ruby-core:17164]'
+
+
+assert_equal 'ok', %q{
+ def def9
+ lambda {|a| $x = :ok; a[]; $x = :ng }.call(Proc.new { return })
+ $x = :ng
+ end
+ def9
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def10
+ $x = :ng
+ lambda { 1.times { return } }.call
+ $x = :ok
+ end
+ $x = :ok
+ def10
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def11
+ yield
+ end
+ begin
+ lambda { def11 { return } }.call
+ rescue LocalJumpError
+ :ng
+ else
+ :ok
+ end
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def12
+ b = Proc.new { $x = :ng; lambda { return }.call; $x = :ok }.call
+ end
+ def12
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def m
+ pr = proc{
+ proc{
+ return :ok
+ }
+ }.call
+ pr.call
+ :ng
+ end
+ m()
+}
+
+assert_equal 'ok', %q{
+ class Foo
+ def call_it
+ p = Proc.new
+ p.call
+ end
+ end
+
+ def give_it
+ proc { :ok }
+ end
+
+ f = Foo.new
+ a_proc = give_it
+ f.call_it(&give_it())
+}, '[ruby-core:15711]'
+
+assert_equal 'foo!', %q{
+ class FooProc < Proc
+ def initialize
+ @foo = "foo!"
+ end
+
+ def bar
+ @foo
+ end
+ end
+
+ def bar
+ FooProc.new &lambda{
+ p 1
+ }
+ end
+
+ fp = bar(&lambda{
+ p 2
+ })
+
+ fp.bar
+}, 'Subclass of Proc'
+
+assert_equal 'ok', %q{
+ o = Object.new
+ def o.write(s); end
+ $stderr = o
+ at_exit{
+ print $!.message
+ }
+ raise "ok"
+}
+
+assert_equal 'ok', %q{
+ lambda do
+ class A
+ class B
+ proc{return :ng}.call
+ end
+ end
+ end.call
+ :ok
+}
+
+assert_equal 'ok', %q{
+ $proc = proc{return}
+ begin
+ lambda do
+ class A
+ class B
+ $proc.call
+ end
+ end
+ end.call
+ :ng
+ rescue LocalJumpError
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ def x
+ binding
+ end
+ b = x{|a| a }
+ b.eval('yield("ok")')
+}, '[Bug #5634]'
+
+assert_equal 'ok', %q{
+ def x
+ binding
+ end
+ eval("x { 'ok' }").eval "yield"
+}, '[Bug #5634]'
+
+assert_equal 'ok', %q{
+ def x
+ binding
+ end
+ def m
+ x{ 'ok' }
+ end
+ eval('yield', m)
+}, '[Bug #5634]'
+
diff --git a/bootstraptest/test_string.rb b/bootstraptest/test_string.rb
new file mode 100644
index 0000000000..849dcd45b0
--- /dev/null
+++ b/bootstraptest/test_string.rb
@@ -0,0 +1,3 @@
+assert_normal_exit %q{
+ inspect.clear
+}, '[ruby-core:68110]'
diff --git a/bootstraptest/test_struct.rb b/bootstraptest/test_struct.rb
new file mode 100644
index 0000000000..a65964d5f9
--- /dev/null
+++ b/bootstraptest/test_struct.rb
@@ -0,0 +1,5 @@
+assert_equal 'Struct::Foo', %q{
+ Struct.instance_eval { const_set(:Foo, nil) }
+ Struct.new("Foo")
+ Struct::Foo
+}
diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb
new file mode 100644
index 0000000000..a111990a1f
--- /dev/null
+++ b/bootstraptest/test_syntax.rb
@@ -0,0 +1,904 @@
+assert_equal %q{4}, %q{1 && 2 && 3 && 4}
+assert_equal %q{}, %q{1 && nil && 3 && 4}
+assert_equal %q{}, %q{1 && 2 && 3 && nil}
+assert_equal %q{false}, %q{1 && 2 && 3 && false}
+assert_equal %q{4}, %q{1 and 2 and 3 and 4}
+assert_equal %q{}, %q{1 and nil and 3 and 4}
+assert_equal %q{}, %q{1 and 2 and 3 and nil}
+assert_equal %q{false}, %q{1 and 2 and 3 and false}
+assert_equal %q{}, %q{nil && true}
+assert_equal %q{false}, %q{false && true}
+assert_equal %q{}, %q{
+ case 1
+ when 2
+ :ng
+ end}
+assert_equal %q{ok}, %q{
+ case 1
+ when 10,20,30
+ :ng1
+ when 1,2,3
+ :ok
+ when 100,200,300
+ :ng2
+ else
+ :elseng
+ end}
+assert_equal %q{elseok}, %q{
+ case 123
+ when 10,20,30
+ :ng1
+ when 1,2,3
+ :ng2
+ when 100,200,300
+ :ng3
+ else
+ :elseok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when /testx/
+ :ng1
+ when /test/
+ :ok
+ when /tetxx/
+ :ng2
+ else
+ :ng_else
+ end
+}
+assert_equal %q{ok}, %q{
+ case Object.new
+ when Object
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case Object
+ when Object.new
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when 'te'
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when 'te'
+ :ng
+ when 'test'
+ :ok
+ end
+}
+assert_equal %q{ng}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when /te/
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when /test/
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{100}, %q{
+ def test(arg)
+ case 1
+ when 2
+ 3
+ end
+ return arg
+ end
+
+ test(100)
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 1
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 3
+ when *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 1
+ when :x, *ary
+ :ok
+ when :z
+ :ng1
+ else
+ :ng2
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 3
+ when :x, *ary
+ :ng1
+ when :z
+ :ng2
+ else
+ :ok
+ end
+}
+assert_equal %q{[:false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep]}, %q{
+
+ def make_perm ary, num
+ if num == 1
+ ary.map{|e| [e]}
+ else
+ base = make_perm(ary, num-1)
+ res = []
+ base.each{|b|
+ ary.each{|e|
+ res << [e] + b
+ }
+ }
+ res
+ end
+ end
+
+ def each_test
+ conds = make_perm(['fv', 'tv'], 3)
+ bangs = make_perm(['', '!'], 3)
+ exprs = make_perm(['and', 'or'], 3)
+ ['if', 'unless'].each{|syn|
+ conds.each{|cs|
+ bangs.each{|bs|
+ exprs.each{|es|
+ yield(syn, cs, bs, es)
+ }
+ }
+ }
+ }
+ end
+
+ fv = false
+ tv = true
+
+ $ans = []
+ each_test{|syn, conds, bangs, exprs|
+ c1, c2, c3 = conds
+ bang1, bang2, bang3 = bangs
+ e1, e2 = exprs
+ eval %Q{
+ #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+ $ans << :then
+ else
+ $ans << :false
+ end
+ }
+ }
+
+ each_test{|syn, conds, bangs, exprs|
+ c1, c2, c3 = conds
+ bang1, bang2, bang3 = bangs
+ e1, e2 = exprs
+ eval %Q{
+ #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+ $ans << :then
+ end
+ $ans << :sep
+ }
+ }
+ $ans
+}
+assert_equal %q{}, %q{
+ defined?(m)
+}
+assert_equal %q{method}, %q{
+ def m
+ end
+ defined?(m)
+}
+assert_equal %q{}, %q{
+ defined?(a.class)
+}
+assert_equal %q{method}, %q{
+ a = 1
+ defined?(a.class)
+}
+assert_equal %q{["method", "method", "method", "method", nil, nil, "method", "method", "method", nil]}, %q{
+ class C
+ def test
+ [defined?(m1()), defined?(self.m1), defined?(C.new.m1),
+ defined?(m2()), defined?(self.m2), defined?(C.new.m2),
+ defined?(m3()), defined?(self.m3), defined?(C.new.m3)]
+ end
+ def m1
+ end
+ private
+ def m2
+ end
+ protected
+ def m3
+ end
+ end
+ C.new.test + [defined?(C.new.m3)]
+}
+assert_equal %q{[nil, nil, nil, nil, "global-variable", "global-variable", nil, nil]}, %q{
+ $ans = [defined?($1), defined?($2), defined?($3), defined?($4)]
+ /(a)(b)/ =~ 'ab'
+ $ans + [defined?($1), defined?($2), defined?($3), defined?($4)]
+}
+assert_equal %q{nilselftruefalse}, %q{
+ defined?(nil) + defined?(self) +
+ defined?(true) + defined?(false)
+}
+assert_equal %q{}, %q{
+ defined?(@a)
+}
+assert_equal %q{instance-variable}, %q{
+ @a = 1
+ defined?(@a)
+}
+assert_equal %q{}, %q{
+ defined?(@@a)
+}
+assert_equal %q{class variable}, %q{
+ @@a = 1
+ defined?(@@a)
+}
+assert_equal %q{}, %q{
+ defined?($a)
+}
+assert_equal %q{global-variable}, %q{
+ $a = 1
+ defined?($a)
+}
+assert_equal %q{}, %q{
+ defined?(C_definedtest)
+}
+assert_equal %q{constant}, %q{
+ C_definedtest = 1
+ defined?(C_definedtest)
+}
+assert_equal %q{}, %q{
+ defined?(::C_definedtest)
+}
+assert_equal %q{constant}, %q{
+ C_definedtest = 1
+ defined?(::C_definedtest)
+}
+assert_equal %q{}, %q{
+ defined?(C_definedtestA::C_definedtestB::C_definedtestC)
+}
+assert_equal %q{constant}, %q{
+ class C_definedtestA
+ class C_definedtestB
+ C_definedtestC = 1
+ end
+ end
+ defined?(C_definedtestA::C_definedtestB::C_definedtestC)
+}
+assert_equal %q{30}, %q{
+ sum = 0
+ 30.times{|ib|
+ if ib % 10 == 0 .. true
+ sum += ib
+ end
+ }
+ sum
+}
+assert_equal %q{63}, %q{
+ sum = 0
+ 30.times{|ib|
+ if ib % 10 == 0 ... true
+ sum += ib
+ end
+ }
+ sum
+}
+assert_equal %q{[["NUM", "Type: NUM\n"], ["NUM", "123\n"], ["NUM", "456\n"], ["NUM", "Type: ARP\n"], ["NUM", "aaa\n"], ["NUM", "bbb\n"], ["NUM", "\f\n"], ["ARP", "Type: ARP\n"], ["ARP", "aaa\n"], ["ARP", "bbb\n"]]}, %q{
+ t = nil
+ unless ''.respond_to? :lines
+ class String
+ def lines
+ self
+ end
+ end
+ end
+ ary = []
+"this must not print
+Type: NUM
+123
+456
+Type: ARP
+aaa
+bbb
+\f
+this must not print
+hoge
+Type: ARP
+aaa
+bbb
+".lines.each{|l|
+ if (t = l[/^Type: (.*)/, 1])..(/^\f/ =~ l)
+ ary << [t, l]
+ end
+ }
+ ary
+}
+assert_equal %q{1}, %q{if true then 1 ; end}
+assert_equal %q{}, %q{if false then 1 ; end}
+assert_equal %q{1}, %q{if true then 1 ; else; 2; end}
+assert_equal %q{2}, %q{if false then 1 ; else; 2; end}
+assert_equal %q{}, %q{if true then ; elsif true then ; 1 ; end}
+assert_equal %q{1}, %q{if false then ; elsif true then ; 1 ; end}
+assert_equal %q{}, %q{unless true then 1 ; end}
+assert_equal %q{1}, %q{unless false then 1 ; end}
+assert_equal %q{2}, %q{unless true then 1 ; else; 2; end}
+assert_equal %q{1}, %q{unless false then 1 ; else; 2; end}
+assert_equal %q{1}, %q{1 if true}
+assert_equal %q{}, %q{1 if false}
+assert_equal %q{}, %q{1 if nil}
+assert_equal %q{}, %q{1 unless true}
+assert_equal %q{1}, %q{1 unless false}
+assert_equal %q{1}, %q{1 unless nil}
+assert_equal %q{1}, %q{1 || 2 || 3 || 4}
+assert_equal %q{1}, %q{1 || false || 3 || 4}
+assert_equal %q{2}, %q{nil || 2 || 3 || 4}
+assert_equal %q{2}, %q{false || 2 || 3 || 4}
+assert_equal %q{false}, %q{nil || false || nil || false}
+assert_equal %q{1}, %q{1 or 2 or 3 or 4}
+assert_equal %q{1}, %q{1 or false or 3 or 4}
+assert_equal %q{2}, %q{nil or 2 or 3 or 4}
+assert_equal %q{2}, %q{false or 2 or 3 or 4}
+assert_equal %q{1}, %q{if true && ""; then 1; end}
+assert_equal %q{1}, %q{if nil || true; then 1; end}
+assert_equal %q{false}, %q{nil or false or nil or false}
+assert_equal %q{elseng}, %q{
+ case
+ when 1==2, 2==3
+ :ng1
+ when false, 4==5
+ :ok
+ when false
+ :ng2
+ else
+ :elseng
+ end
+}
+assert_equal %q{ok}, %q{
+ case
+ when nil, nil
+ :ng1
+ when 1,2,3
+ :ok
+ when false, false
+ :ng2
+ else
+ :elseng
+ end
+}
+assert_equal %q{elseok}, %q{
+ case
+ when nil
+ :ng1
+ when false
+ :ng2
+ else
+ :elseok
+ end}
+assert_equal %q{}, %q{
+ case
+ when 1
+ end
+}
+assert_equal %q{ok}, %q{
+ r = nil
+ ary = []
+ case
+ when false
+ r = :ng1
+ when false, false
+ r = :ng2
+ when *ary
+ r = :ng3
+ when false, *ary
+ r = :ng4
+ when true, *ary
+ r = :ok
+ end
+ r
+}
+assert_equal %q{ok}, %q{
+ ary = []
+ case
+ when false, *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ng
+ when true
+ :ok
+ else
+ :ng2
+ end
+}
+assert_equal %q{ng}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, true]
+ case
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, true]
+ case
+ when false, false
+ when false, *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{}, %q{
+ i = 0
+ while i < 10
+ i+=1
+ end}
+assert_equal %q{10}, %q{
+ i = 0
+ while i < 10
+ i+=1
+ end; i}
+assert_equal %q{}, %q{
+ i = 0
+ until i > 10
+ i+=1
+ end}
+assert_equal %q{11}, %q{
+ i = 0
+ until i > 10
+ i+=1
+ end; i}
+assert_equal %q{1}, %q{
+ i = 0
+ begin
+ i+=1
+ end while false
+ i
+}
+assert_equal %q{1}, %q{
+ i = 0
+ begin
+ i+=1
+ end until true
+ i
+}
+def assert_syntax_error expected, code, message = ''
+ assert_equal "#{expected}",
+ "begin eval(%q{#{code}}, nil, '', 0)"'; rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end', message
+end
+assert_syntax_error "unterminated string meets end of file", '().."', '[ruby-dev:29732]'
+assert_equal %q{[]}, %q{$&;[]}, '[ruby-dev:31068]'
+assert_syntax_error "syntax error, unexpected *, expecting '}'", %q{{*0}}, '[ruby-dev:31072]'
+assert_syntax_error "`@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]'
+assert_syntax_error "identifier $00 is not valid to get", %q{$00..0}, '[ruby-dev:31100]'
+assert_syntax_error "identifier $00 is not valid to set", %q{0..$00=1}
+assert_equal %q{0}, %q{[*0];0}, '[ruby-dev:31102]'
+assert_syntax_error "syntax error, unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]'
+assert_equal %q{1}, %q{
+ class << (ary=[]); def []; 0; end; def []=(x); super(0,x);end;end; ary[]+=1
+}, '[ruby-dev:31110]'
+assert_syntax_error "Can't set variable $1", %q{0..$1=1}, '[ruby-dev:31118]'
+assert_valid_syntax %q{1.times{1+(1&&next)}}, '[ruby-dev:31119]'
+assert_valid_syntax %q{x=-1;loop{x+=1&&redo if (x+=1).zero?}}, '[ruby-dev:31119]'
+assert_syntax_error %q{syntax error, unexpected end-of-input}, %q{!}, '[ruby-dev:31243]'
+assert_equal %q{[nil]}, %q{[()]}, '[ruby-dev:31252]'
+assert_equal %q{true}, %q{!_=()}, '[ruby-dev:31263]'
+assert_equal 'ok', %q{while true; redo; end if 1 == 2; :ok}, '[ruby-dev:31360]'
+assert_equal 'ok', %q{
+ 1.times {
+ begin
+ ensure
+ next
+ end
+ }; :ok
+}, '[ruby-dev:31373]'
+assert_equal 'ok', %q{
+ flag = false
+ 1.times {
+ next if flag
+ flag = true
+ begin
+ ensure
+ redo
+ end
+ }; :ok
+}, '[ruby-dev:31373]'
+
+assert_equal 'ok', %q{
+ 1.times{
+ p(1, (next; 2))
+ }; :ok
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ next
+ end)
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ p(1, (next; 2))
+ end)
+}
+# redo
+assert_equal 'ok', %q{
+ i = 0
+ 1.times{
+ break if i>1
+ i+=1
+ p(1, (redo; 2))
+ }; :ok
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ redo
+ end)
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ p(1, (redo; 2))
+ end)
+}
+assert_equal '1', %q{
+ a = [0]
+ a[*a]+=1
+}
+assert_equal '2', %q{
+ ary = [0]
+ case 1
+ when *ary, 1
+ 1
+ end +
+ case
+ when *ary
+ 1
+ end
+}
+
+assert_match /invalid multibyte char/, %q{
+ STDERR.reopen(STDOUT)
+ eval("\"\xf0".force_encoding("utf-8"))
+}, '[ruby-dev:32429]'
+
+# method ! and !=
+assert_equal 'true', %q{!false}
+assert_equal 'true', %q{1 == 1}
+assert_equal 'true', %q{1 != 2}
+assert_equal 'true', %q{
+ class C; def !=(obj); true; end; end
+ C.new != 1
+}
+assert_equal 'true', %q{
+ class C; def !@; true; end; end
+ !C.new
+}
+assert_normal_exit %q{
+ eval "while true; return; end rescue p $!"
+}, '[ruby-dev:31663]'
+assert_equal '1', %q{
+ def bar
+ raise
+ end
+
+ def foo
+ 1.times{
+ begin
+ return bar
+ rescue
+ :ok
+ end
+ }
+ end
+
+ foo
+}
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ break
+ end
+ :ok
+}, '[ruby-core:14385]'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ break :ok
+ end # direct
+}, '[ruby-core:14385]'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ "#{next}"
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ redo
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ "#{ redo }"
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ begin
+ raise
+ rescue
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ retry
+ end
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ "#{ break }"
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ "#{ break }"
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ 1.times do
+ [
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ begin
+ false ? next : p
+ break while true
+ end
+ ]
+ end
+ :ok
+}, '[ruby-dev:32882]'
+
+assert_equal "1\n2\n", %q{
+ i = 0
+ while i<2
+ i += 1
+ next p(i)
+ end
+}
+
+assert_valid_syntax('1.times {|i|print (42),1;}', '[ruby-list:44479]')
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a(1).a)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a::B)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_normal_exit %q{
+ defined? C && 0
+}
+
+assert_normal_exit %q{
+ class C
+ def m
+ defined?(super())
+ end
+ end
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ class X < RuntimeError;end
+ x = [X]
+ begin
+ raise X
+ rescue *x
+ :ok
+ end
+}, '[ruby-core:14537]'
+
+assert_equal 'ok', %q{
+ a = [false]
+ (a[0] &&= true) == false ? :ok : :ng
+}, '[ruby-dev:34679]'
+
+assert_normal_exit %q{
+ a = []
+ 100.times {|i| a << i << nil << nil }
+ p a.compact!
+}
+
+assert_equal 'ok', %q{
+ "#{}""#{}ok"
+}, '[ruby-dev:38968]'
+
+
+assert_equal 'ok', %q{
+ "o" "#{}k"
+}, '[ruby-dev:38980]'
+
+bug2415 = '[ruby-core:26961]'
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a=1, b, *rest); nil end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x@; nil end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a = 0.times do
+ def y(a=1, b, *rest); nil; end
+ end)
+ nil
+ end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a = 0.times do
+ def x@; nil; end
+ end)
+ nil
+ end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ a {
+ b {|c.d| }
+ e
+ }
+}, '[ruby-dev:39861]'
+
+bug1240 = '[ruby-core:22637]'
+assert_valid_syntax('x y { "#{}".z { } }', bug1240)
+assert_valid_syntax('x y { "#{}".z do end }', bug1240)
+
+assert_valid_syntax('y "#{a 1}" do end', '[ruby-core:29579]')
+assert_normal_exit %q{
+ def foo(&block)
+ yield
+ end
+
+ foo do
+ s = defined?(raise + 1)
+ Class
+ end
+}, '[ruby-core:30293]'
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
new file mode 100644
index 0000000000..d16295de8b
--- /dev/null
+++ b/bootstraptest/test_thread.rb
@@ -0,0 +1,484 @@
+# Thread and Fiber
+
+assert_equal %q{ok}, %q{
+ Thread.new{
+ }.join
+ :ok
+}
+assert_equal %q{ok}, %q{
+ Thread.new{
+ :ok
+ }.value
+}
+assert_equal %q{ok}, %q{
+begin
+ v = 0
+ (1..200).map{|i|
+ Thread.new{
+ i
+ }
+ }.each{|t|
+ v += t.value
+ }
+ v == 20100 ? :ok : v
+rescue ThreadError => e
+ :ok if /can't create Thread/ =~ e.message
+end
+}
+assert_equal %q{ok}, %q{
+begin
+ :ok if 5000 == 5000.times{|e|
+ (1..2).map{
+ Thread.new{
+ }
+ }.each{|e|
+ e.join()
+ }
+ }
+rescue ThreadError => e
+ :ok if /can't create Thread/ =~ e.message
+end
+}
+assert_equal %q{ok}, %q{
+begin
+ :ok if 5000 == 5000.times{|e|
+ (1..2).map{
+ Thread.new{
+ }
+ }.each{|e|
+ e.join(1000000000)
+ }
+ }
+rescue ThreadError => e
+ :ok if /can't create Thread/ =~ e.message
+end
+}
+assert_equal %q{ok}, %q{
+begin
+ :ok if 5000 == 5000.times{
+ t = Thread.new{}
+ while t.alive?
+ Thread.pass
+ end
+ }
+rescue NoMemoryError
+ :ok
+end
+}
+assert_equal %q{100}, %q{
+ 100.times{
+ Thread.new{loop{Thread.pass}}
+ }
+}
+assert_equal %q{ok}, %q{
+ Thread.new{
+ :ok
+ }.join.value
+}
+assert_equal %q{ok}, %q{
+ begin
+ Thread.new{
+ raise "ok"
+ }.join
+ rescue => e
+ e
+ end
+}
+assert_equal %q{ok}, %q{
+ ans = nil
+ t = Thread.new{
+ begin
+ sleep 0.5
+ ensure
+ ans = :ok
+ end
+ }
+ Thread.pass until t.stop?
+ t.kill
+ t.join
+ ans
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ sleep
+ }
+ sleep 0.1
+ t.raise
+ begin
+ t.join
+ :ng
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ loop{}
+ }
+ Thread.pass
+ t.raise
+ begin
+ t.join
+ :ng
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ }
+ Thread.pass
+ t.join
+ t.raise # raise to exited thread
+ begin
+ t.join
+ :ok
+ rescue
+ :ng
+ end
+}
+assert_equal %q{run}, %q{
+ t = Thread.new{
+ loop{}
+ }
+ st = t.status
+ t.kill
+ st
+}
+assert_equal %q{sleep}, %q{
+ t = Thread.new{
+ sleep
+ }
+ sleep 0.1
+ st = t.status
+ t.kill
+ st
+}
+assert_equal %q{false}, %q{
+ t = Thread.new{
+ }
+ t.kill
+ sleep 0.1
+ t.status
+}
+assert_equal %q{[ThreadGroup, true]}, %q{
+ ptg = Thread.current.group
+ Thread.new{
+ ctg = Thread.current.group
+ [ctg.class, ctg == ptg]
+ }.value
+}
+assert_equal %q{[1, 1]}, %q{
+ thg = ThreadGroup.new
+
+ t = Thread.new{
+ thg.add Thread.current
+ sleep
+ }
+ sleep 0.1
+ [thg.list.size, ThreadGroup::Default.list.size]
+}
+assert_equal %q{true}, %q{
+ thg = ThreadGroup.new
+
+ t = Thread.new{sleep 5}
+ thg.add t
+ thg.list.include?(t)
+}
+assert_equal %q{[true, nil, true]}, %q{
+ /a/ =~ 'a'
+ $a = $~
+ Thread.new{
+ $b = $~
+ /b/ =~ 'b'
+ $c = $~
+ }.join
+ $d = $~
+ [$a == $d, $b, $c != $d]
+}
+assert_equal %q{11}, %q{
+ Thread.current[:a] = 1
+ Thread.new{
+ Thread.current[:a] = 10
+ Thread.pass
+ Thread.current[:a]
+ }.value + Thread.current[:a]
+}
+assert_normal_exit %q{
+ begin
+ 100.times do |i|
+ begin
+ th = Thread.start(Thread.current) {|u| u.raise }
+ raise
+ rescue
+ ensure
+ th.join
+ end
+ end
+ rescue
+ end
+}, '[ruby-dev:31371]'
+
+assert_equal 'true', %{
+ t = Thread.new { loop {} }
+ begin
+ pid = fork {
+ exit t.status != "run"
+ }
+ Process.wait pid
+ $?.success?
+ rescue NotImplementedError
+ true
+ end
+}
+
+assert_equal 'ok', %{
+ open("zzz.rb", "w") do |f|
+ f.puts <<-END
+ begin
+ Thread.new { fork { GC.start } }.join
+ pid, status = Process.wait2
+ $result = status.success? ? :ok : :ng
+ rescue NotImplementedError
+ $result = :ok
+ end
+ END
+ end
+ require "./zzz.rb"
+ $result
+}
+
+assert_finish 3, %{
+ th = Thread.new {sleep 0.2}
+ th.join(0.1)
+ th.join
+}
+
+assert_finish 3, %{
+ require 'timeout'
+ th = Thread.new {sleep 0.2}
+ begin
+ Timeout.timeout(0.1) {th.join}
+ rescue Timeout::Error
+ end
+ th.join
+}
+
+assert_normal_exit %q{
+ STDERR.reopen(STDOUT)
+ exec "/"
+}
+
+assert_normal_exit %q{
+ (0..10).map {
+ Thread.new {
+ 10000.times {
+ Object.new.to_s
+ }
+ }
+ }.each {|t|
+ t.join
+ }
+}
+
+assert_equal 'ok', %q{
+ def m
+ t = Thread.new { while true; // =~ "" end }
+ sleep 0.01
+ 10.times {
+ if /((ab)*(ab)*)*(b)/ =~ "ab"*7
+ return :ng if !$4
+ return :ng if $~.size != 5
+ end
+ }
+ :ok
+ ensure
+ Thread.kill t
+ end
+ m
+}, '[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]'
+
+assert_normal_exit %q{
+ g = enum_for(:block_given?)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = enum_for(:binding)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = "abc".enum_for(:scan, /./)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = Module.enum_for(:new)
+ loop { g.next }
+}, '[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]'
+
+assert_equal 'ok', %q{
+ begin
+ Thread.new { Thread.stop }
+ Thread.stop
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ begin
+ m1, m2 = Thread::Mutex.new, Thread::Mutex.new
+ f1 = f2 = false
+ Thread.new { m1.lock; f2 = true; sleep 0.001 until f1; m2.lock }
+ m2.lock; f1 = true; sleep 0.001 until f2; m1.lock
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ m = Thread::Mutex.new
+ Thread.new { m.lock }; sleep 0.1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Thread::Mutex.new
+ Thread.new { m.lock }; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Thread::Mutex.new
+ Thread.new { m.lock }.join; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Thread::Mutex.new
+ Thread.new { m.lock; sleep 0.2 }
+ sleep 0.1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Thread::Mutex.new
+ Thread.new { m.lock; sleep 0.2; m.unlock }
+ sleep 0.1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ t = Thread.new {`echo`}
+ t.join
+ $? ? :ng : :ok
+}, '[ruby-dev:35414]'
+
+assert_equal 'ok', %q{
+ begin
+ 100.times{
+ (1..100).map{ Thread.new(true) {|x| x == false } }.each{|th| th.join}
+ }
+ rescue NoMemoryError, StandardError
+ end
+ :ok
+}
+
+assert_equal 'ok', %{
+ open("zzz.rb", "w") do |f|
+ f.puts <<-'end;' # do
+ begin
+ m = Thread::Mutex.new
+ parent = Thread.current
+ th1 = Thread.new { m.lock; sleep }
+ sleep 0.01 until th1.stop?
+ Thread.new do
+ sleep 0.01 until parent.stop?
+ begin
+ fork { GC.start }
+ rescue Exception
+ parent.raise $!
+ end
+ th1.run
+ end
+ m.lock
+ pid, status = Process.wait2
+ $result = status.success? ? :ok : :ng
+ rescue NotImplementedError
+ $result = :ok
+ end
+ end;
+ end
+ require "./zzz.rb"
+ $result
+}
+
+assert_finish 3, %q{
+ require 'thread'
+
+ lock = Thread::Mutex.new
+ cond = Thread::ConditionVariable.new
+ t = Thread.new do
+ lock.synchronize do
+ cond.wait(lock)
+ end
+ end
+
+ begin
+ pid = fork do
+ # Child
+ STDOUT.write "This is the child process.\n"
+ STDOUT.write "Child process exiting.\n"
+ end
+ Process.waitpid(pid)
+ rescue NotImplementedError
+ end
+}, '[ruby-core:23572]'
+
+assert_equal 'ok', %q{
+ begin
+ Process.waitpid2(fork {})[1].success? ? 'ok' : 'ng'
+ rescue NotImplementedError
+ 'ok'
+ end
+}
+
+assert_equal 'foo', %q{
+ i = 0
+ Thread.start {sleep 1; exit!}
+ f = proc {|s, c| /#{c.call; s}/o }
+ th2 = Thread.new {
+ sleep 0.01 until i == 1
+ i = 2
+ f.call("bar", proc {sleep 2});
+ nil
+ }
+ th1 = Thread.new {
+ f.call("foo", proc {i = 1; sleep 0.01 until i == 2; sleep 0.01})
+ nil
+ }
+ [th1, th2].each {|t| t.join }
+ GC.start
+ f.call.source
+}
diff --git a/ccan/build_assert/build_assert.h b/ccan/build_assert/build_assert.h
new file mode 100644
index 0000000000..a04d1d4709
--- /dev/null
+++ b/ccan/build_assert/build_assert.h
@@ -0,0 +1,40 @@
+/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
+#ifndef CCAN_BUILD_ASSERT_H
+#define CCAN_BUILD_ASSERT_H
+
+/**
+ * BUILD_ASSERT - assert a build-time dependency.
+ * @cond: the compile-time condition which must be true.
+ *
+ * Your compile will fail if the condition isn't true, or can't be evaluated
+ * by the compiler. This can only be used within a function.
+ *
+ * Example:
+ * #include <stddef.h>
+ * ...
+ * static char *foo_to_char(struct foo *foo)
+ * {
+ * // This code needs string to be at start of foo.
+ * BUILD_ASSERT(offsetof(struct foo, string) == 0);
+ * return (char *)foo;
+ * }
+ */
+#define BUILD_ASSERT(cond) \
+ do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
+
+/**
+ * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
+ * @cond: the compile-time condition which must be true.
+ *
+ * Your compile will fail if the condition isn't true, or can't be evaluated
+ * by the compiler. This can be used in an expression: its value is "0".
+ *
+ * Example:
+ * #define foo_to_char(foo) \
+ * ((char *)(foo) \
+ * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
+ */
+#define BUILD_ASSERT_OR_ZERO(cond) \
+ (sizeof(char [1 - 2*!(cond)]) - 1)
+
+#endif /* CCAN_BUILD_ASSERT_H */
diff --git a/ccan/check_type/check_type.h b/ccan/check_type/check_type.h
new file mode 100644
index 0000000000..1f77a535e4
--- /dev/null
+++ b/ccan/check_type/check_type.h
@@ -0,0 +1,63 @@
+/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
+#ifndef CCAN_CHECK_TYPE_H
+#define CCAN_CHECK_TYPE_H
+
+/**
+ * check_type - issue a warning or build failure if type is not correct.
+ * @expr: the expression whose type we should check (not evaluated).
+ * @type: the exact type we expect the expression to be.
+ *
+ * This macro is usually used within other macros to try to ensure that a macro
+ * argument is of the expected type. No type promotion of the expression is
+ * done: an unsigned int is not the same as an int!
+ *
+ * check_type() always evaluates to 0.
+ *
+ * If your compiler does not support typeof, then the best we can do is fail
+ * to compile if the sizes of the types are unequal (a less complete check).
+ *
+ * Example:
+ * // They should always pass a 64-bit value to _set_some_value!
+ * #define set_some_value(expr) \
+ * _set_some_value((check_type((expr), uint64_t), (expr)))
+ */
+
+/**
+ * check_types_match - issue a warning or build failure if types are not same.
+ * @expr1: the first expression (not evaluated).
+ * @expr2: the second expression (not evaluated).
+ *
+ * This macro is usually used within other macros to try to ensure that
+ * arguments are of identical types. No type promotion of the expressions is
+ * done: an unsigned int is not the same as an int!
+ *
+ * check_types_match() always evaluates to 0.
+ *
+ * If your compiler does not support typeof, then the best we can do is fail
+ * to compile if the sizes of the types are unequal (a less complete check).
+ *
+ * Example:
+ * // Do subtraction to get to enclosing type, but make sure that
+ * // pointer is of correct type for that member.
+ * #define container_of(mbr_ptr, encl_type, mbr) \
+ * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \
+ * ((encl_type *) \
+ * ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))
+ */
+#if HAVE_TYPEOF
+#define check_type(expr, type) \
+ ((typeof(expr) *)0 != (type *)0)
+
+#define check_types_match(expr1, expr2) \
+ ((typeof(expr1) *)0 != (typeof(expr2) *)0)
+#else
+#include "ccan/build_assert/build_assert.h"
+/* Without typeof, we can only test the sizes. */
+#define check_type(expr, type) \
+ BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type))
+
+#define check_types_match(expr1, expr2) \
+ BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2))
+#endif /* HAVE_TYPEOF */
+
+#endif /* CCAN_CHECK_TYPE_H */
diff --git a/ccan/container_of/container_of.h b/ccan/container_of/container_of.h
new file mode 100644
index 0000000000..ae3e1fc81f
--- /dev/null
+++ b/ccan/container_of/container_of.h
@@ -0,0 +1,142 @@
+/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
+#ifndef CCAN_CONTAINER_OF_H
+#define CCAN_CONTAINER_OF_H
+#include "ccan/check_type/check_type.h"
+
+/**
+ * container_of - get pointer to enclosing structure
+ * @member_ptr: pointer to the structure member
+ * @containing_type: the type this member is within
+ * @member: the name of this member within the structure.
+ *
+ * Given a pointer to a member of a structure, this macro does pointer
+ * subtraction to return the pointer to the enclosing type.
+ *
+ * Example:
+ * struct foo {
+ * int fielda, fieldb;
+ * // ...
+ * };
+ * struct info {
+ * int some_other_field;
+ * struct foo my_foo;
+ * };
+ *
+ * static struct info *foo_to_info(struct foo *foo)
+ * {
+ * return container_of(foo, struct info, my_foo);
+ * }
+ */
+#define container_of(member_ptr, containing_type, member) \
+ ((containing_type *) \
+ ((char *)(member_ptr) \
+ - container_off(containing_type, member)) \
+ + check_types_match(*(member_ptr), ((containing_type *)0)->member))
+
+
+/**
+ * container_of_or_null - get pointer to enclosing structure, or NULL
+ * @member_ptr: pointer to the structure member
+ * @containing_type: the type this member is within
+ * @member: the name of this member within the structure.
+ *
+ * Given a pointer to a member of a structure, this macro does pointer
+ * subtraction to return the pointer to the enclosing type, unless it
+ * is given NULL, in which case it also returns NULL.
+ *
+ * Example:
+ * struct foo {
+ * int fielda, fieldb;
+ * // ...
+ * };
+ * struct info {
+ * int some_other_field;
+ * struct foo my_foo;
+ * };
+ *
+ * static struct info *foo_to_info_allowing_null(struct foo *foo)
+ * {
+ * return container_of_or_null(foo, struct info, my_foo);
+ * }
+ */
+static inline char *container_of_or_null_(void *member_ptr, size_t offset)
+{
+ return member_ptr ? (char *)member_ptr - offset : NULL;
+}
+#define container_of_or_null(member_ptr, containing_type, member) \
+ ((containing_type *) \
+ container_of_or_null_(member_ptr, \
+ container_off(containing_type, member)) \
+ + check_types_match(*(member_ptr), ((containing_type *)0)->member))
+
+/**
+ * container_off - get offset to enclosing structure
+ * @containing_type: the type this member is within
+ * @member: the name of this member within the structure.
+ *
+ * Given a pointer to a member of a structure, this macro does
+ * typechecking and figures out the offset to the enclosing type.
+ *
+ * Example:
+ * struct foo {
+ * int fielda, fieldb;
+ * // ...
+ * };
+ * struct info {
+ * int some_other_field;
+ * struct foo my_foo;
+ * };
+ *
+ * static struct info *foo_to_info(struct foo *foo)
+ * {
+ * size_t off = container_off(struct info, my_foo);
+ * return (void *)((char *)foo - off);
+ * }
+ */
+#define container_off(containing_type, member) \
+ offsetof(containing_type, member)
+
+/**
+ * container_of_var - get pointer to enclosing structure using a variable
+ * @member_ptr: pointer to the structure member
+ * @container_var: a pointer of same type as this member's container
+ * @member: the name of this member within the structure.
+ *
+ * Given a pointer to a member of a structure, this macro does pointer
+ * subtraction to return the pointer to the enclosing type.
+ *
+ * Example:
+ * static struct info *foo_to_i(struct foo *foo)
+ * {
+ * struct info *i = container_of_var(foo, i, my_foo);
+ * return i;
+ * }
+ */
+#if HAVE_TYPEOF
+#define container_of_var(member_ptr, container_var, member) \
+ container_of(member_ptr, typeof(*container_var), member)
+#else
+#define container_of_var(member_ptr, container_var, member) \
+ ((void *)((char *)(member_ptr) - \
+ container_off_var(container_var, member)))
+#endif
+
+/**
+ * container_off_var - get offset of a field in enclosing structure
+ * @container_var: a pointer to a container structure
+ * @member: the name of a member within the structure.
+ *
+ * Given (any) pointer to a structure and a its member name, this
+ * macro does pointer subtraction to return offset of member in a
+ * structure memory layout.
+ *
+ */
+#if HAVE_TYPEOF
+#define container_off_var(var, member) \
+ container_off(typeof(*var), member)
+#else
+#define container_off_var(var, member) \
+ ((const char *)&(var)->member - (const char *)(var))
+#endif
+
+#endif /* CCAN_CONTAINER_OF_H */
diff --git a/ccan/licenses/BSD-MIT b/ccan/licenses/BSD-MIT
new file mode 100644
index 0000000000..89de354795
--- /dev/null
+++ b/ccan/licenses/BSD-MIT
@@ -0,0 +1,17 @@
+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/ccan/licenses/CC0 b/ccan/licenses/CC0
new file mode 100644
index 0000000000..feb9b118e6
--- /dev/null
+++ b/ccan/licenses/CC0
@@ -0,0 +1,28 @@
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
+
+ the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
+ moral rights retained by the original author(s) and/or performer(s);
+ publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
+ rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
+ rights protecting the extraction, dissemination, use and reuse of data in a Work;
+ database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
+ other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
+ Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
+ Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
+ Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
diff --git a/ccan/list/list.h b/ccan/list/list.h
new file mode 100644
index 0000000000..ca9f9f1f7f
--- /dev/null
+++ b/ccan/list/list.h
@@ -0,0 +1,773 @@
+/* Licensed under BSD-MIT - see ccan/licenses/BSD-MIT file for details */
+#ifndef CCAN_LIST_H
+#define CCAN_LIST_H
+#include <assert.h>
+#include "ccan/str/str.h"
+#include "ccan/container_of/container_of.h"
+#include "ccan/check_type/check_type.h"
+
+/**
+ * struct list_node - an entry in a doubly-linked list
+ * @next: next entry (self if empty)
+ * @prev: previous entry (self if empty)
+ *
+ * This is used as an entry in a linked list.
+ * Example:
+ * struct child {
+ * const char *name;
+ * // Linked list of all us children.
+ * struct list_node list;
+ * };
+ */
+struct list_node
+{
+ struct list_node *next, *prev;
+};
+
+/**
+ * struct list_head - the head of a doubly-linked list
+ * @h: the list_head (containing next and prev pointers)
+ *
+ * This is used as the head of a linked list.
+ * Example:
+ * struct parent {
+ * const char *name;
+ * struct list_head children;
+ * unsigned int num_children;
+ * };
+ */
+struct list_head
+{
+ struct list_node n;
+};
+
+#define LIST_LOC __FILE__ ":" stringify(__LINE__)
+#define list_debug(h, loc) ((void)loc, h)
+#define list_debug_node(n, loc) ((void)loc, n)
+
+/**
+ * LIST_HEAD_INIT - initializer for an empty list_head
+ * @name: the name of the list.
+ *
+ * Explicit initializer for an empty list.
+ *
+ * See also:
+ * LIST_HEAD, list_head_init()
+ *
+ * Example:
+ * static struct list_head my_list = LIST_HEAD_INIT(my_list);
+ */
+#define LIST_HEAD_INIT(name) { { &name.n, &name.n } }
+
+/**
+ * LIST_HEAD - define and initialize an empty list_head
+ * @name: the name of the list.
+ *
+ * The LIST_HEAD macro defines a list_head and initializes it to an empty
+ * list. It can be prepended by "static" to define a static list_head.
+ *
+ * See also:
+ * LIST_HEAD_INIT, list_head_init()
+ *
+ * Example:
+ * static LIST_HEAD(my_global_list);
+ */
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+/**
+ * list_head_init - initialize a list_head
+ * @h: the list_head to set to the empty list
+ *
+ * Example:
+ * ...
+ * struct parent *parent = malloc(sizeof(*parent));
+ *
+ * list_head_init(&parent->children);
+ * parent->num_children = 0;
+ */
+static inline void list_head_init(struct list_head *h)
+{
+ h->n.next = h->n.prev = &h->n;
+}
+
+/**
+ * list_node_init - initialize a list_node
+ * @n: the list_node to link to itself.
+ *
+ * You don't need to use this normally! But it lets you list_del(@n)
+ * safely.
+ */
+static inline void list_node_init(struct list_node *n)
+{
+ n->next = n->prev = n;
+}
+
+/**
+ * list_add_after - add an entry after an existing node in a linked list
+ * @h: the list_head to add the node to (for debugging)
+ * @p: the existing list_node to add the node after
+ * @n: the new list_node to add to the list.
+ *
+ * The existing list_node must already be a member of the list.
+ * The new list_node does not need to be initialized; it will be overwritten.
+ *
+ * Example:
+ * struct child c1, c2, c3;
+ * LIST_HEAD(h);
+ *
+ * list_add_tail(&h, &c1.list);
+ * list_add_tail(&h, &c3.list);
+ * list_add_after(&h, &c1.list, &c2.list);
+ */
+#define list_add_after(h, p, n) list_add_after_(h, p, n, LIST_LOC)
+static inline void list_add_after_(struct list_head *h,
+ struct list_node *p,
+ struct list_node *n,
+ const char *abortstr)
+{
+ n->next = p->next;
+ n->prev = p;
+ p->next->prev = n;
+ p->next = n;
+ (void)list_debug(h, abortstr);
+}
+
+/**
+ * list_add - add an entry at the start of a linked list.
+ * @h: the list_head to add the node to
+ * @n: the list_node to add to the list.
+ *
+ * The list_node does not need to be initialized; it will be overwritten.
+ * Example:
+ * struct child *child = malloc(sizeof(*child));
+ *
+ * child->name = "marvin";
+ * list_add(&parent->children, &child->list);
+ * parent->num_children++;
+ */
+#define list_add(h, n) list_add_(h, n, LIST_LOC)
+static inline void list_add_(struct list_head *h,
+ struct list_node *n,
+ const char *abortstr)
+{
+ list_add_after_(h, &h->n, n, abortstr);
+}
+
+/**
+ * list_add_before - add an entry before an existing node in a linked list
+ * @h: the list_head to add the node to (for debugging)
+ * @p: the existing list_node to add the node before
+ * @n: the new list_node to add to the list.
+ *
+ * The existing list_node must already be a member of the list.
+ * The new list_node does not need to be initialized; it will be overwritten.
+ *
+ * Example:
+ * list_head_init(&h);
+ * list_add_tail(&h, &c1.list);
+ * list_add_tail(&h, &c3.list);
+ * list_add_before(&h, &c3.list, &c2.list);
+ */
+#define list_add_before(h, p, n) list_add_before_(h, p, n, LIST_LOC)
+static inline void list_add_before_(struct list_head *h,
+ struct list_node *p,
+ struct list_node *n,
+ const char *abortstr)
+{
+ n->next = p;
+ n->prev = p->prev;
+ p->prev->next = n;
+ p->prev = n;
+ (void)list_debug(h, abortstr);
+}
+
+/**
+ * list_add_tail - add an entry at the end of a linked list.
+ * @h: the list_head to add the node to
+ * @n: the list_node to add to the list.
+ *
+ * The list_node does not need to be initialized; it will be overwritten.
+ * Example:
+ * list_add_tail(&parent->children, &child->list);
+ * parent->num_children++;
+ */
+#define list_add_tail(h, n) list_add_tail_(h, n, LIST_LOC)
+static inline void list_add_tail_(struct list_head *h,
+ struct list_node *n,
+ const char *abortstr)
+{
+ list_add_before_(h, &h->n, n, abortstr);
+}
+
+/**
+ * list_empty - is a list empty?
+ * @h: the list_head
+ *
+ * If the list is empty, returns true.
+ *
+ * Example:
+ * assert(list_empty(&parent->children) == (parent->num_children == 0));
+ */
+#define list_empty(h) list_empty_(h, LIST_LOC)
+static inline int list_empty_(const struct list_head *h, const char* abortstr)
+{
+ (void)list_debug(h, abortstr);
+ return h->n.next == &h->n;
+}
+
+/**
+ * list_empty_nodebug - is a list empty (and don't perform debug checks)?
+ * @h: the list_head
+ *
+ * If the list is empty, returns true.
+ * This differs from list_empty() in that if CCAN_LIST_DEBUG is set it
+ * will NOT perform debug checks. Only use this function if you REALLY
+ * know what you're doing.
+ *
+ * Example:
+ * assert(list_empty_nodebug(&parent->children) == (parent->num_children == 0));
+ */
+#ifndef CCAN_LIST_DEBUG
+#define list_empty_nodebug(h) list_empty(h)
+#else
+static inline int list_empty_nodebug(const struct list_head *h)
+{
+ return h->n.next == &h->n;
+}
+#endif
+
+/**
+ * list_del - delete an entry from an (unknown) linked list.
+ * @n: the list_node to delete from the list.
+ *
+ * Note that this leaves @n in an undefined state; it can be added to
+ * another list, but not deleted again.
+ *
+ * See also:
+ * list_del_from(), list_del_init()
+ *
+ * Example:
+ * list_del(&child->list);
+ * parent->num_children--;
+ */
+#define list_del(n) list_del_(n, LIST_LOC)
+static inline void list_del_(struct list_node *n, const char* abortstr)
+{
+ (void)list_debug_node(n, abortstr);
+ n->next->prev = n->prev;
+ n->prev->next = n->next;
+#ifdef CCAN_LIST_DEBUG
+ /* Catch use-after-del. */
+ n->next = n->prev = NULL;
+#endif
+}
+
+/**
+ * list_del_init - delete a node, and reset it so it can be deleted again.
+ * @n: the list_node to be deleted.
+ *
+ * list_del(@n) or list_del_init() again after this will be safe,
+ * which can be useful in some cases.
+ *
+ * See also:
+ * list_del_from(), list_del()
+ *
+ * Example:
+ * list_del_init(&child->list);
+ * parent->num_children--;
+ */
+#define list_del_init(n) list_del_init_(n, LIST_LOC)
+static inline void list_del_init_(struct list_node *n, const char *abortstr)
+{
+ list_del_(n, abortstr);
+ list_node_init(n);
+}
+
+/**
+ * list_del_from - delete an entry from a known linked list.
+ * @h: the list_head the node is in.
+ * @n: the list_node to delete from the list.
+ *
+ * This explicitly indicates which list a node is expected to be in,
+ * which is better documentation and can catch more bugs.
+ *
+ * See also: list_del()
+ *
+ * Example:
+ * list_del_from(&parent->children, &child->list);
+ * parent->num_children--;
+ */
+static inline void list_del_from(struct list_head *h, struct list_node *n)
+{
+#ifdef CCAN_LIST_DEBUG
+ {
+ /* Thorough check: make sure it was in list! */
+ struct list_node *i;
+ for (i = h->n.next; i != n; i = i->next)
+ assert(i != &h->n);
+ }
+#endif /* CCAN_LIST_DEBUG */
+
+ /* Quick test that catches a surprising number of bugs. */
+ assert(!list_empty(h));
+ list_del(n);
+}
+
+/**
+ * list_swap - swap out an entry from an (unknown) linked list for a new one.
+ * @o: the list_node to replace from the list.
+ * @n: the list_node to insert in place of the old one.
+ *
+ * Note that this leaves @o in an undefined state; it can be added to
+ * another list, but not deleted/swapped again.
+ *
+ * See also:
+ * list_del()
+ *
+ * Example:
+ * struct child x1, x2;
+ * LIST_HEAD(xh);
+ *
+ * list_add(&xh, &x1.list);
+ * list_swap(&x1.list, &x2.list);
+ */
+#define list_swap(o, n) list_swap_(o, n, LIST_LOC)
+static inline void list_swap_(struct list_node *o,
+ struct list_node *n,
+ const char* abortstr)
+{
+ (void)list_debug_node(o, abortstr);
+ *n = *o;
+ n->next->prev = n;
+ n->prev->next = n;
+#ifdef CCAN_LIST_DEBUG
+ /* Catch use-after-del. */
+ o->next = o->prev = NULL;
+#endif
+}
+
+/**
+ * list_entry - convert a list_node back into the structure containing it.
+ * @n: the list_node
+ * @type: the type of the entry
+ * @member: the list_node member of the type
+ *
+ * Example:
+ * // First list entry is children.next; convert back to child.
+ * child = list_entry(parent->children.n.next, struct child, list);
+ *
+ * See Also:
+ * list_top(), list_for_each()
+ */
+#define list_entry(n, type, member) container_of(n, type, member)
+
+/**
+ * list_top - get the first entry in a list
+ * @h: the list_head
+ * @type: the type of the entry
+ * @member: the list_node member of the type
+ *
+ * If the list is empty, returns NULL.
+ *
+ * Example:
+ * struct child *first;
+ * first = list_top(&parent->children, struct child, list);
+ * if (!first)
+ * printf("Empty list!\n");
+ */
+#define list_top(h, type, member) \
+ ((type *)list_top_((h), list_off_(type, member)))
+
+static inline const void *list_top_(const struct list_head *h, size_t off)
+{
+ if (list_empty(h))
+ return NULL;
+ return (const char *)h->n.next - off;
+}
+
+/**
+ * list_pop - remove the first entry in a list
+ * @h: the list_head
+ * @type: the type of the entry
+ * @member: the list_node member of the type
+ *
+ * If the list is empty, returns NULL.
+ *
+ * Example:
+ * struct child *one;
+ * one = list_pop(&parent->children, struct child, list);
+ * if (!one)
+ * printf("Empty list!\n");
+ */
+#define list_pop(h, type, member) \
+ ((type *)list_pop_((h), list_off_(type, member)))
+
+static inline const void *list_pop_(const struct list_head *h, size_t off)
+{
+ struct list_node *n;
+
+ if (list_empty(h))
+ return NULL;
+ n = h->n.next;
+ list_del(n);
+ return (const char *)n - off;
+}
+
+/**
+ * list_tail - get the last entry in a list
+ * @h: the list_head
+ * @type: the type of the entry
+ * @member: the list_node member of the type
+ *
+ * If the list is empty, returns NULL.
+ *
+ * Example:
+ * struct child *last;
+ * last = list_tail(&parent->children, struct child, list);
+ * if (!last)
+ * printf("Empty list!\n");
+ */
+#define list_tail(h, type, member) \
+ ((type *)list_tail_((h), list_off_(type, member)))
+
+static inline const void *list_tail_(const struct list_head *h, size_t off)
+{
+ if (list_empty(h))
+ return NULL;
+ return (const char *)h->n.prev - off;
+}
+
+/**
+ * list_for_each - iterate through a list.
+ * @h: the list_head (warning: evaluated multiple times!)
+ * @i: the structure containing the list_node
+ * @member: the list_node member of the structure
+ *
+ * This is a convenient wrapper to iterate @i over the entire list. It's
+ * a for loop, so you can break and continue as normal.
+ *
+ * Example:
+ * list_for_each(&parent->children, child, list)
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each(h, i, member) \
+ list_for_each_off(h, i, list_off_var_(i, member))
+
+/**
+ * list_for_each_rev - iterate through a list backwards.
+ * @h: the list_head
+ * @i: the structure containing the list_node
+ * @member: the list_node member of the structure
+ *
+ * This is a convenient wrapper to iterate @i over the entire list. It's
+ * a for loop, so you can break and continue as normal.
+ *
+ * Example:
+ * list_for_each_rev(&parent->children, child, list)
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each_rev(h, i, member) \
+ list_for_each_rev_off(h, i, list_off_var_(i, member))
+
+/**
+ * list_for_each_rev_safe - iterate through a list backwards,
+ * maybe during deletion
+ * @h: the list_head
+ * @i: the structure containing the list_node
+ * @nxt: the structure containing the list_node
+ * @member: the list_node member of the structure
+ *
+ * This is a convenient wrapper to iterate @i over the entire list backwards.
+ * It's a for loop, so you can break and continue as normal. The extra
+ * variable * @nxt is used to hold the next element, so you can delete @i
+ * from the list.
+ *
+ * Example:
+ * struct child *next;
+ * list_for_each_rev_safe(&parent->children, child, next, list) {
+ * printf("Name: %s\n", child->name);
+ * }
+ */
+#define list_for_each_rev_safe(h, i, nxt, member) \
+ list_for_each_rev_safe_off(h, i, nxt, list_off_var_(i, member))
+
+/**
+ * list_for_each_safe - iterate through a list, maybe during deletion
+ * @h: the list_head
+ * @i: the structure containing the list_node
+ * @nxt: the structure containing the list_node
+ * @member: the list_node member of the structure
+ *
+ * This is a convenient wrapper to iterate @i over the entire list. It's
+ * a for loop, so you can break and continue as normal. The extra variable
+ * @nxt is used to hold the next element, so you can delete @i from the list.
+ *
+ * Example:
+ * list_for_each_safe(&parent->children, child, next, list) {
+ * list_del(&child->list);
+ * parent->num_children--;
+ * }
+ */
+#define list_for_each_safe(h, i, nxt, member) \
+ list_for_each_safe_off(h, i, nxt, list_off_var_(i, member))
+
+/**
+ * list_next - get the next entry in a list
+ * @h: the list_head
+ * @i: a pointer to an entry in the list.
+ * @member: the list_node member of the structure
+ *
+ * If @i was the last entry in the list, returns NULL.
+ *
+ * Example:
+ * struct child *second;
+ * second = list_next(&parent->children, first, list);
+ * if (!second)
+ * printf("No second child!\n");
+ */
+#define list_next(h, i, member) \
+ ((list_typeof(i))list_entry_or_null(list_debug(h, \
+ __FILE__ ":" stringify(__LINE__)), \
+ (i)->member.next, \
+ list_off_var_((i), member)))
+
+/**
+ * list_prev - get the previous entry in a list
+ * @h: the list_head
+ * @i: a pointer to an entry in the list.
+ * @member: the list_node member of the structure
+ *
+ * If @i was the first entry in the list, returns NULL.
+ *
+ * Example:
+ * first = list_prev(&parent->children, second, list);
+ * if (!first)
+ * printf("Can't go back to first child?!\n");
+ */
+#define list_prev(h, i, member) \
+ ((list_typeof(i))list_entry_or_null(list_debug(h, \
+ __FILE__ ":" stringify(__LINE__)), \
+ (i)->member.prev, \
+ list_off_var_((i), member)))
+
+/**
+ * list_append_list - empty one list onto the end of another.
+ * @to: the list to append into
+ * @from: the list to empty.
+ *
+ * This takes the entire contents of @from and moves it to the end of
+ * @to. After this @from will be empty.
+ *
+ * Example:
+ * struct list_head adopter;
+ *
+ * list_append_list(&adopter, &parent->children);
+ * assert(list_empty(&parent->children));
+ * parent->num_children = 0;
+ */
+#define list_append_list(t, f) list_append_list_(t, f, \
+ __FILE__ ":" stringify(__LINE__))
+static inline void list_append_list_(struct list_head *to,
+ struct list_head *from,
+ const char *abortstr)
+{
+ struct list_node *from_tail = list_debug(from, abortstr)->n.prev;
+ struct list_node *to_tail = list_debug(to, abortstr)->n.prev;
+
+ /* Sew in head and entire list. */
+ to->n.prev = from_tail;
+ from_tail->next = &to->n;
+ to_tail->next = &from->n;
+ from->n.prev = to_tail;
+
+ /* Now remove head. */
+ list_del(&from->n);
+ list_head_init(from);
+}
+
+/**
+ * list_prepend_list - empty one list into the start of another.
+ * @to: the list to prepend into
+ * @from: the list to empty.
+ *
+ * This takes the entire contents of @from and moves it to the start
+ * of @to. After this @from will be empty.
+ *
+ * Example:
+ * list_prepend_list(&adopter, &parent->children);
+ * assert(list_empty(&parent->children));
+ * parent->num_children = 0;
+ */
+#define list_prepend_list(t, f) list_prepend_list_(t, f, LIST_LOC)
+static inline void list_prepend_list_(struct list_head *to,
+ struct list_head *from,
+ const char *abortstr)
+{
+ struct list_node *from_tail = list_debug(from, abortstr)->n.prev;
+ struct list_node *to_head = list_debug(to, abortstr)->n.next;
+
+ /* Sew in head and entire list. */
+ to->n.next = &from->n;
+ from->n.prev = &to->n;
+ to_head->prev = from_tail;
+ from_tail->next = to_head;
+
+ /* Now remove head. */
+ list_del(&from->n);
+ list_head_init(from);
+}
+
+/* internal macros, do not use directly */
+#define list_for_each_off_dir_(h, i, off, dir) \
+ for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \
+ (off)); \
+ list_node_from_off_((void *)i, (off)) != &(h)->n; \
+ i = list_node_to_off_(list_node_from_off_((void *)i, (off))->dir, \
+ (off)))
+
+#define list_for_each_safe_off_dir_(h, i, nxt, off, dir) \
+ for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \
+ (off)), \
+ nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \
+ (off)); \
+ list_node_from_off_(i, (off)) != &(h)->n; \
+ i = nxt, \
+ nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \
+ (off)))
+
+/**
+ * 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.
+ * @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
+ * implement all oher, more high-level, for-each constructs. It's a for loop,
+ * 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
+ * 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
+ * remember that given the wrong pointer/offset couple this macro will
+ * happilly churn all you memory untill SEGFAULT stops it, in other words
+ * caveat emptor.
+ *
+ * It is worth mentioning that one of legitimate use-cases for that wrapper
+ * is operation on opaque types with known offset for `struct list_node'
+ * member(preferably 0), because it allows you not to disclose the type of
+ * @i.
+ *
+ * Example:
+ * list_for_each_off(&parent->children, child,
+ * offsetof(struct child, list))
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each_off(h, i, off) \
+ list_for_each_off_dir_((h),(i),(off),next)
+
+/**
+ * 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.
+ * @off: offset(relative to @i) at which list node data resides.
+ *
+ * See list_for_each_off for details
+ */
+#define list_for_each_rev_off(h, i, off) \
+ list_for_each_off_dir_((h),(i),(off),prev)
+
+/**
+ * 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.
+ * @nxt: the structure containing the list_node
+ * @off: offset(relative to @i) at which list node data resides.
+ *
+ * For details see `list_for_each_off' and `list_for_each_safe'
+ * descriptions.
+ *
+ * Example:
+ * list_for_each_safe_off(&parent->children, child,
+ * next, offsetof(struct child, list))
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each_safe_off(h, i, nxt, off) \
+ list_for_each_safe_off_dir_((h),(i),(nxt),(off),next)
+
+/**
+ * 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.
+ * @nxt: the structure containing the list_node
+ * @off: offset(relative to @i) at which list node data resides.
+ *
+ * For details see `list_for_each_rev_off' and `list_for_each_rev_safe'
+ * descriptions.
+ *
+ * Example:
+ * list_for_each_rev_safe_off(&parent->children, child,
+ * next, offsetof(struct child, list))
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each_rev_safe_off(h, i, nxt, off) \
+ list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev)
+
+/* Other -off variants. */
+#define list_entry_off(n, type, off) \
+ ((type *)list_node_from_off_((n), (off)))
+
+#define list_head_off(h, type, off) \
+ ((type *)list_head_off((h), (off)))
+
+#define list_tail_off(h, type, off) \
+ ((type *)list_tail_((h), (off)))
+
+#define list_add_off(h, n, off) \
+ list_add((h), list_node_from_off_((n), (off)))
+
+#define list_del_off(n, off) \
+ list_del(list_node_from_off_((n), (off)))
+
+#define list_del_from_off(h, n, off) \
+ list_del_from(h, list_node_from_off_((n), (off)))
+
+/* Offset helper functions so we only single-evaluate. */
+static inline void *list_node_to_off_(struct list_node *node, size_t off)
+{
+ return (void *)((char *)node - off);
+}
+static inline struct list_node *list_node_from_off_(void *ptr, size_t off)
+{
+ return (struct list_node *)((char *)ptr + off);
+}
+
+/* Get the offset of the member, but make sure it's a list_node. */
+#define list_off_(type, member) \
+ (container_off(type, member) + \
+ check_type(((type *)0)->member, struct list_node))
+
+#define list_off_var_(var, member) \
+ (container_off_var(var, member) + \
+ check_type(var->member, struct list_node))
+
+#if HAVE_TYPEOF
+#define list_typeof(var) typeof(var)
+#else
+#define list_typeof(var) void *
+#endif
+
+/* Returns member, or NULL if at end of list. */
+static inline void *list_entry_or_null(const struct list_head *h,
+ const struct list_node *n,
+ size_t off)
+{
+ if (n == &h->n)
+ return NULL;
+ return (char *)n - off;
+}
+#endif /* CCAN_LIST_H */
diff --git a/ccan/str/str.h b/ccan/str/str.h
new file mode 100644
index 0000000000..9a9da9cd3f
--- /dev/null
+++ b/ccan/str/str.h
@@ -0,0 +1,16 @@
+/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
+#ifndef CCAN_STR_H
+#define CCAN_STR_H
+/**
+ * stringify - Turn expression into a string literal
+ * @expr: any C expression
+ *
+ * Example:
+ * #define PRINT_COND_IF_FALSE(cond) \
+ * ((cond) || printf("%s is false!", stringify(cond)))
+ */
+#define stringify(expr) stringify_1(expr)
+/* Double-indirection required to stringify expansions */
+#define stringify_1(expr) #expr
+
+#endif /* CCAN_STR_H */
diff --git a/class.c b/class.c
index fefc99d65e..364f258333 100644
--- a/class.c
+++ b/class.c
@@ -1,647 +1,2047 @@
-/************************************************
+/**********************************************************************
class.c -
$Author$
- $Date$
created at: Tue Aug 10 15:05:44 JST 1993
- Copyright (C) 1993-1998 Yukihiro Matsumoto
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
+
+**********************************************************************/
+
+/*!
+ * \defgroup class Classes and their hierarchy.
+ * \par Terminology
+ * - class: same as in Ruby.
+ * - singleton class: class for a particular object
+ * - eigenclass: = singleton class
+ * - metaclass: class of a class. metaclass is a kind of singleton class.
+ * - metametaclass: class of a metaclass.
+ * - meta^(n)-class: class of a meta^(n-1)-class.
+ * - attached object: A singleton class knows its unique instance.
+ * The instance is called the attached object for the singleton class.
+ * \{
+ */
+
+#include "internal.h"
+#include "ruby/st.h"
+#include "constant.h"
+#include "vm_core.h"
+#include "id_table.h"
+#include <ctype.h>
-************************************************/
+#define id_attached id__attached__
-#include "ruby.h"
-#include "node.h"
-#include "st.h"
-#include <ctype.h>
+void
+rb_class_subclass_add(VALUE super, VALUE klass)
+{
+ rb_subclass_entry_t *entry, *head;
+
+ if (super && super != Qundef) {
+ entry = ALLOC(rb_subclass_entry_t);
+ entry->klass = klass;
+ entry->next = NULL;
+
+ head = RCLASS_EXT(super)->subclasses;
+ if (head) {
+ entry->next = head;
+ RCLASS_EXT(head->klass)->parent_subclasses = &entry->next;
+ }
+
+ RCLASS_EXT(super)->subclasses = entry;
+ RCLASS_EXT(klass)->parent_subclasses = &RCLASS_EXT(super)->subclasses;
+ }
+}
+
+static void
+rb_module_add_to_subclasses_list(VALUE module, VALUE iclass)
+{
+ rb_subclass_entry_t *entry, *head;
+
+ entry = ALLOC(rb_subclass_entry_t);
+ entry->klass = iclass;
+ entry->next = NULL;
+
+ head = RCLASS_EXT(module)->subclasses;
+ if (head) {
+ entry->next = head;
+ RCLASS_EXT(head->klass)->module_subclasses = &entry->next;
+ }
+
+ RCLASS_EXT(module)->subclasses = entry;
+ RCLASS_EXT(iclass)->module_subclasses = &RCLASS_EXT(module)->subclasses;
+}
+
+void
+rb_class_remove_from_super_subclasses(VALUE klass)
+{
+ rb_subclass_entry_t *entry;
+
+ if (RCLASS_EXT(klass)->parent_subclasses) {
+ entry = *RCLASS_EXT(klass)->parent_subclasses;
+
+ *RCLASS_EXT(klass)->parent_subclasses = entry->next;
+ if (entry->next) {
+ RCLASS_EXT(entry->next->klass)->parent_subclasses = RCLASS_EXT(klass)->parent_subclasses;
+ }
+ xfree(entry);
+ }
-#ifdef USE_CWGUSI
-#include <stdio.h>
-#endif
+ RCLASS_EXT(klass)->parent_subclasses = NULL;
+}
+
+void
+rb_class_remove_from_module_subclasses(VALUE klass)
+{
+ rb_subclass_entry_t *entry;
-extern st_table *rb_class_tbl;
+ if (RCLASS_EXT(klass)->module_subclasses) {
+ entry = *RCLASS_EXT(klass)->module_subclasses;
+ *RCLASS_EXT(klass)->module_subclasses = entry->next;
+
+ if (entry->next) {
+ RCLASS_EXT(entry->next->klass)->module_subclasses = RCLASS_EXT(klass)->module_subclasses;
+ }
+
+ xfree(entry);
+ }
+ RCLASS_EXT(klass)->module_subclasses = NULL;
+}
+
+void
+rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE arg)
+{
+ rb_subclass_entry_t *cur = RCLASS_EXT(klass)->subclasses;
+
+ /* do not be tempted to simplify this loop into a for loop, the order of
+ operations is important here if `f` modifies the linked list */
+ while (cur) {
+ VALUE curklass = cur->klass;
+ cur = cur->next;
+ f(curklass, arg);
+ }
+}
+
+static void
+class_detach_subclasses(VALUE klass, VALUE arg)
+{
+ rb_class_remove_from_super_subclasses(klass);
+}
+
+void
+rb_class_detach_subclasses(VALUE klass)
+{
+ rb_class_foreach_subclass(klass, class_detach_subclasses, Qnil);
+}
+
+static void
+class_detach_module_subclasses(VALUE klass, VALUE arg)
+{
+ rb_class_remove_from_module_subclasses(klass);
+}
+
+void
+rb_class_detach_module_subclasses(VALUE klass)
+{
+ rb_class_foreach_subclass(klass, class_detach_module_subclasses, Qnil);
+}
+
+/**
+ * Allocates a struct RClass for a new class.
+ *
+ * \param flags initial value for basic.flags of the returned class.
+ * \param klass the class of the returned class.
+ * \return an uninitialized Class object.
+ * \pre \p klass must refer \c Class class or an ancestor of Class.
+ * \pre \code (flags | T_CLASS) != 0 \endcode
+ * \post the returned class can safely be \c #initialize 'd.
+ *
+ * \note this function is not Class#allocate.
+ */
+static VALUE
+class_alloc(VALUE flags, VALUE klass)
+{
+ NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | FL_PROMOTED1 /* start from age == 2 */ | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0));
+ obj->ptr = ZALLOC(rb_classext_t);
+ /* ZALLOC
+ RCLASS_IV_TBL(obj) = 0;
+ RCLASS_CONST_TBL(obj) = 0;
+ RCLASS_M_TBL(obj) = 0;
+ RCLASS_IV_INDEX_TBL(obj) = 0;
+ RCLASS_SET_SUPER((VALUE)obj, 0);
+ RCLASS_EXT(obj)->subclasses = NULL;
+ RCLASS_EXT(obj)->parent_subclasses = NULL;
+ RCLASS_EXT(obj)->module_subclasses = NULL;
+ */
+ RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
+ RCLASS_SERIAL(obj) = rb_next_class_serial();
+ RCLASS_REFINED_CLASS(obj) = Qnil;
+ RCLASS_EXT(obj)->allocator = 0;
+
+ return (VALUE)obj;
+}
+
+static void
+RCLASS_M_TBL_INIT(VALUE c)
+{
+ RCLASS_M_TBL(c) = rb_id_table_create(0);
+}
+
+/*!
+ * A utility function that wraps class_alloc.
+ *
+ * allocates a class and initializes safely.
+ * \param super a class from which the new class derives.
+ * \return a class object.
+ * \pre \a super must be a class.
+ * \post the metaclass of the new class is Class.
+ */
VALUE
-class_new(super)
- VALUE super;
+rb_class_boot(VALUE super)
{
- NEWOBJ(klass, struct RClass);
- OBJSETUP(klass, cClass, T_CLASS);
+ VALUE klass = class_alloc(T_CLASS, rb_cClass);
- klass->super = super;
- klass->iv_tbl = 0;
- klass->m_tbl = 0; /* safe GC */
- klass->m_tbl = new_idhash();
+ RCLASS_SET_SUPER(klass, super);
+ RCLASS_M_TBL_INIT(klass);
+ OBJ_INFECT(klass, super);
return (VALUE)klass;
}
+
+/*!
+ * Ensures a class can be derived from super.
+ *
+ * \param super a reference to an object.
+ * \exception TypeError if \a super is not a Class or \a super is a singleton class.
+ */
+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_obj_class(super));
+ }
+ if (RBASIC(super)->flags & FL_SINGLETON) {
+ rb_raise(rb_eTypeError, "can't make subclass of singleton class");
+ }
+ if (super == rb_cClass) {
+ rb_raise(rb_eTypeError, "can't make subclass of Class");
+ }
+}
+
+
+/*!
+ * Creates a new class.
+ * \param super a class from which the new class derives.
+ * \exception TypeError \a super is not inheritable.
+ * \exception TypeError \a super is the Class class.
+ */
VALUE
-singleton_class_new(super)
- VALUE super;
+rb_class_new(VALUE super)
{
- VALUE klass = class_new(super);
+ Check_Type(super, T_CLASS);
+ rb_check_inheritable(super);
+ return rb_class_boot(super);
+}
- FL_SET(klass, FL_SINGLETON);
- return klass;
+static void
+clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *me)
+{
+ if (me->def->type == VM_METHOD_TYPE_ISEQ) {
+ rb_cref_t *new_cref;
+ rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &new_cref);
+ rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
+ }
+ else {
+ rb_method_entry_set(new_klass, mid, me, METHOD_ENTRY_VISI(me));
+ }
+}
+
+struct clone_method_arg {
+ VALUE new_klass;
+ VALUE old_klass;
+};
+
+static enum rb_id_table_iterator_result
+clone_method_i(ID key, VALUE value, void *data)
+{
+ const struct clone_method_arg *arg = (struct clone_method_arg *)data;
+ clone_method(arg->old_klass, arg->new_klass, key, (const rb_method_entry_t *)value);
+ return ID_TABLE_CONTINUE;
}
+struct clone_const_arg {
+ VALUE klass;
+ struct rb_id_table *tbl;
+};
+
static int
-clone_method(mid, body, tbl)
- ID mid;
- NODE *body;
- st_table *tbl;
+clone_const(ID key, const rb_const_entry_t *ce, struct clone_const_arg *arg)
{
- st_insert(tbl, mid, NEW_METHOD(body->nd_body, body->nd_noex));
- return ST_CONTINUE;
+ rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
+ MEMCPY(nce, ce, rb_const_entry_t, 1);
+ RB_OBJ_WRITTEN(arg->klass, Qundef, ce->value);
+ RB_OBJ_WRITTEN(arg->klass, Qundef, ce->file);
+
+ rb_id_table_insert(arg->tbl, key, (VALUE)nce);
+ return ID_TABLE_CONTINUE;
+}
+
+static enum rb_id_table_iterator_result
+clone_const_i(ID key, VALUE value, void *data)
+{
+ return clone_const(key, (const rb_const_entry_t *)value, data);
+}
+
+static void
+class_init_copy_check(VALUE clone, VALUE orig)
+{
+ if (orig == rb_cBasicObject) {
+ rb_raise(rb_eTypeError, "can't copy the root class");
+ }
+ if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
+ rb_raise(rb_eTypeError, "already initialized class");
+ }
+ if (FL_TEST(orig, FL_SINGLETON)) {
+ rb_raise(rb_eTypeError, "can't copy singleton class");
+ }
}
+/* :nodoc: */
VALUE
-singleton_class_clone(klass)
- VALUE klass;
+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;
+ 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;
+ }
+ if (RCLASS_CONST_TBL(clone)) {
+ rb_free_const_table(RCLASS_CONST_TBL(clone));
+ RCLASS_CONST_TBL(clone) = 0;
+ }
+ RCLASS_M_TBL(clone) = 0;
+ if (RCLASS_IV_TBL(orig)) {
+ st_data_t id;
+
+ RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
+ CONST_ID(id, "__tmp_classpath__");
+ st_delete(RCLASS_IV_TBL(clone), &id, 0);
+ CONST_ID(id, "__classpath__");
+ st_delete(RCLASS_IV_TBL(clone), &id, 0);
+ CONST_ID(id, "__classid__");
+ st_delete(RCLASS_IV_TBL(clone), &id, 0);
+ }
+ if (RCLASS_CONST_TBL(orig)) {
+ struct clone_const_arg arg;
+
+ arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
+ arg.klass = clone;
+ rb_id_table_foreach(RCLASS_CONST_TBL(orig), clone_const_i, &arg);
+ }
+ if (RCLASS_M_TBL(orig)) {
+ struct clone_method_arg arg;
+ arg.old_klass = orig;
+ arg.new_klass = clone;
+ RCLASS_M_TBL_INIT(clone);
+ rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
+ }
+
+ return clone;
+}
+
+VALUE
+rb_singleton_class_clone(VALUE obj)
{
+ return rb_singleton_class_clone_and_attach(obj, Qundef);
+}
+
+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;
else {
/* copy singleton(unnamed) class */
- NEWOBJ(clone, struct RClass);
- CLONESETUP(clone, klass);
-
- clone->super = RCLASS(klass)->super;
- clone->iv_tbl = 0;
- clone->m_tbl = 0;
- clone->m_tbl = new_idhash();
- st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
+ VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
+
+ if (BUILTIN_TYPE(obj) == T_CLASS) {
+ RBASIC_SET_CLASS(clone, clone);
+ }
+ else {
+ RBASIC_SET_CLASS(clone, rb_singleton_class_clone(klass));
+ }
+
+ 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));
+ }
+ if (RCLASS_CONST_TBL(klass)) {
+ struct clone_const_arg arg;
+ arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
+ arg.klass = clone;
+ rb_id_table_foreach(RCLASS_CONST_TBL(klass), clone_const_i, &arg);
+ }
+ if (attach != Qundef) {
+ rb_singleton_class_attached(clone, attach);
+ }
+ RCLASS_M_TBL_INIT(clone);
+ {
+ struct clone_method_arg arg;
+ arg.old_klass = klass;
+ arg.new_klass = clone;
+ rb_id_table_foreach(RCLASS_M_TBL(klass), clone_method_i, &arg);
+ }
+ rb_singleton_class_attached(RBASIC(clone)->klass, clone);
FL_SET(clone, FL_SINGLETON);
- return (VALUE)clone;
+
+ return clone;
}
}
+/*!
+ * Attach a object to a singleton class.
+ * @pre \a klass is the singleton class of \a obj.
+ */
void
-singleton_class_attached(klass, obj)
- VALUE klass, obj;
+rb_singleton_class_attached(VALUE klass, VALUE obj)
{
- if (FL_TEST(klass, FL_SINGLETON))
- rb_iv_set(klass, "__attached__", obj);
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ if (!RCLASS_IV_TBL(klass)) {
+ RCLASS_IV_TBL(klass) = st_init_numtable();
+ }
+ rb_class_ivar_set(klass, id_attached, obj);
+ }
}
-VALUE
-rb_define_class_id(id, super)
- ID id;
+
+
+#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)
+ * @retval 0 otherwise
+ */
+#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
+
+static int
+rb_singleton_class_has_metaclass_p(VALUE sklass)
+{
+ return rb_attr_get(METACLASS_OF(sklass), id_attached) == sklass;
+}
+
+int
+rb_singleton_class_internal_p(VALUE sklass)
+{
+ return (RB_TYPE_P(rb_attr_get(sklass, id_attached), T_CLASS) &&
+ !rb_singleton_class_has_metaclass_p(sklass));
+}
+
+/*!
+ * whether k has a metaclass
+ * @retval 1 if \a k has a metaclass
+ * @retval 0 otherwise
+ */
+#define HAVE_METACLASS_P(k) \
+ (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
+ rb_singleton_class_has_metaclass_p(k))
+
+/*!
+ * ensures \a klass belongs to its own eigenclass.
+ * @return the eigenclass of \a klass
+ * @post \a klass belongs to the returned eigenclass.
+ * i.e. the attached object of the eigenclass is \a klass.
+ * @note this macro creates a new eigenclass if necessary.
+ */
+#define ENSURE_EIGENCLASS(klass) \
+ (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
+
+
+/*!
+ * Creates a metaclass of \a klass
+ * \param klass a class
+ * \return created metaclass for the class
+ * \pre \a klass is a Class object
+ * \pre \a klass has no singleton class.
+ * \post the class of \a klass is the returned class.
+ * \post the returned class is meta^(n+1)-class when \a klass is a meta^(n)-klass for n >= 0
+ */
+static inline VALUE
+make_metaclass(VALUE klass)
+{
VALUE super;
+ VALUE metaclass = rb_class_boot(Qundef);
+
+ FL_SET(metaclass, FL_SINGLETON);
+ rb_singleton_class_attached(metaclass, klass);
+
+ if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
+ SET_METACLASS_OF(klass, metaclass);
+ SET_METACLASS_OF(metaclass, metaclass);
+ }
+ else {
+ VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
+ SET_METACLASS_OF(klass, metaclass);
+ SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp));
+ }
+
+ super = RCLASS_SUPER(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;
+}
+
+/*!
+ * Creates a singleton class for \a obj.
+ * \pre \a obj must not a immediate nor a special const.
+ * \pre \a obj must not a Class object.
+ * \pre \a obj has no singleton class.
+ */
+static inline VALUE
+make_singleton_class(VALUE obj)
+{
+ VALUE orig_class = RBASIC(obj)->klass;
+ VALUE klass = rb_class_boot(orig_class);
+
+ FL_SET(klass, FL_SINGLETON);
+ RBASIC_SET_CLASS(obj, klass);
+ rb_singleton_class_attached(klass, obj);
+
+ SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class)));
+ return klass;
+}
+
+
+static VALUE
+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);
+ return obj;
+}
+
+void
+Init_class_hierarchy(void)
+{
+ rb_cBasicObject = boot_defclass("BasicObject", 0);
+ rb_cObject = boot_defclass("Object", rb_cBasicObject);
+ rb_gc_register_mark_object(rb_cObject);
+
+ /* resolve class name ASAP for order-independence */
+ rb_class_name(rb_cObject);
+
+ rb_cModule = boot_defclass("Module", rb_cObject);
+ rb_cClass = boot_defclass("Class", rb_cModule);
+
+ rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
+ RBASIC_SET_CLASS(rb_cClass, rb_cClass);
+ RBASIC_SET_CLASS(rb_cModule, rb_cClass);
+ RBASIC_SET_CLASS(rb_cObject, rb_cClass);
+ RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
+}
+
+
+/*!
+ * \internal
+ * Creates a new *singleton class* for an object.
+ *
+ * \pre \a obj has no singleton class.
+ * \note DO NOT USE the function in an extension libraries. Use \ref rb_singleton_class.
+ * \param obj An object.
+ * \param unused ignored.
+ * \return The singleton class of the object.
+ */
+VALUE
+rb_make_metaclass(VALUE obj, VALUE unused)
+{
+ if (BUILTIN_TYPE(obj) == T_CLASS) {
+ return make_metaclass(obj);
+ }
+ else {
+ return make_singleton_class(obj);
+ }
+}
+
+
+/*!
+ * Defines a new class.
+ * \param id ignored
+ * \param super A class from which the new class will derive. NULL means \c Object class.
+ * \return the created class
+ * \throw TypeError if super is not a \c Class object.
+ *
+ * \note the returned class will not be associated with \a id.
+ * You must explicitly set a class name if necessary.
+ */
+VALUE
+rb_define_class_id(ID id, VALUE super)
{
VALUE klass;
- if (!super) super = cObject;
- klass = class_new(super);
- rb_name_class(klass, id);
- /* make metaclass */
- RBASIC(klass)->klass = singleton_class_new(RBASIC(super)->klass);
- singleton_class_attached(RBASIC(klass)->klass, klass);
- rb_funcall(super, rb_intern("inherited"), 1, klass);
+ if (!super) super = rb_cObject;
+ klass = rb_class_new(super);
+ rb_make_metaclass(klass, RBASIC(super)->klass);
return klass;
}
+
+/*!
+ * Calls Class#inherited.
+ * \param super A class which will be called #inherited.
+ * NULL means Object class.
+ * \param klass A Class object which derived from \a super
+ * \return the value \c Class#inherited's returns
+ * \pre Each of \a super and \a klass must be a \c Class object.
+ */
VALUE
-rb_define_class(name, super)
- char *name;
- VALUE super;
+rb_class_inherited(VALUE super, VALUE klass)
+{
+ ID inherited;
+ if (!super) super = rb_cObject;
+ CONST_ID(inherited, "inherited");
+ return rb_funcall(super, inherited, 1, klass);
+}
+
+
+
+/*!
+ * Defines a top-level class.
+ * \param name name of the class
+ * \param super a class from which the new class will derive.
+ * \return the created class
+ * \throw TypeError if the constant name \a name is already taken but
+ * the constant is not a \c Class.
+ * \throw TypeError if the class is already defined but the class can not
+ * be reopened because its superclass is not \a super.
+ * \throw ArgumentError if the \a super is NULL.
+ * \post top-level constant named \a name refers the returned class.
+ *
+ * \note if a class named \a name is already defined and its superclass is
+ * \a super, the function just returns the defined class.
+ */
+VALUE
+rb_define_class(const char *name, VALUE super)
{
VALUE klass;
ID id;
id = rb_intern(name);
+ if (rb_const_defined(rb_cObject, id)) {
+ klass = rb_const_get(rb_cObject, id);
+ if (!RB_TYPE_P(klass, T_CLASS)) {
+ rb_raise(rb_eTypeError, "%s is not a class (%"PRIsVALUE")",
+ name, rb_obj_class(klass));
+ }
+ if (rb_class_real(RCLASS_SUPER(klass)) != super) {
+ rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
+ }
+ return klass;
+ }
+ if (!super) {
+ rb_raise(rb_eArgError, "no super class for `%s'", name);
+ }
klass = rb_define_class_id(id, super);
- st_add_direct(rb_class_tbl, id, klass);
+ rb_vm_add_root_module(id, klass);
+ rb_name_class(klass, id);
+ rb_const_set(rb_cObject, id, klass);
+ rb_class_inherited(super, klass);
return klass;
}
+
+/*!
+ * Defines a class under the namespace of \a outer.
+ * \param outer a class which contains the new class.
+ * \param name name of the new class
+ * \param super a class from which the new class will derive.
+ * NULL means \c Object class.
+ * \return the created class
+ * \throw TypeError if the constant name \a name is already taken but
+ * the constant is not a \c Class.
+ * \throw TypeError if the class is already defined but the class can not
+ * be reopened because its superclass is not \a super.
+ * \post top-level constant named \a name refers the returned class.
+ *
+ * \note if a class named \a name is already defined and its superclass is
+ * \a super, the function just returns the defined class.
+ */
VALUE
-rb_define_class_under(outer, name, super)
- VALUE outer;
- char *name;
- VALUE super;
+rb_define_class_under(VALUE outer, const char *name, VALUE super)
+{
+ return rb_define_class_id_under(outer, rb_intern(name), super);
+}
+
+
+/*!
+ * Defines a class under the namespace of \a outer.
+ * \param outer a class which contains the new class.
+ * \param id name of the new class
+ * \param super a class from which the new class will derive.
+ * NULL means \c Object class.
+ * \return the created class
+ * \throw TypeError if the constant name \a name is already taken but
+ * the constant is not a \c Class.
+ * \throw TypeError if the class is already defined but the class can not
+ * be reopened because its superclass is not \a super.
+ * \post top-level constant named \a name refers the returned class.
+ *
+ * \note if a class named \a name is already defined and its superclass is
+ * \a super, the function just returns the defined class.
+ */
+VALUE
+rb_define_class_id_under(VALUE outer, ID id, VALUE super)
{
VALUE klass;
- ID id;
- id = rb_intern(name);
+ if (rb_const_defined_at(outer, id)) {
+ klass = rb_const_get_at(outer, id);
+ if (!RB_TYPE_P(klass, T_CLASS)) {
+ rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a class"
+ " (%"PRIsVALUE")",
+ outer, rb_id2str(id), rb_obj_class(klass));
+ }
+ if (rb_class_real(RCLASS_SUPER(klass)) != super) {
+ rb_raise(rb_eTypeError, "superclass mismatch for class "
+ "%"PRIsVALUE"::%"PRIsVALUE""
+ " (%"PRIsVALUE" is given but was %"PRIsVALUE")",
+ outer, rb_id2str(id), RCLASS_SUPER(klass), super);
+ }
+ return klass;
+ }
+ if (!super) {
+ rb_raise(rb_eArgError, "no super class for `%"PRIsVALUE"::%"PRIsVALUE"'",
+ rb_class_path(outer), rb_id2str(id));
+ }
klass = rb_define_class_id(id, super);
+ rb_set_class_path_string(klass, outer, rb_id2str(id));
rb_const_set(outer, id, klass);
- rb_set_class_path(klass, outer, name);
+ rb_class_inherited(super, klass);
+ rb_gc_register_mark_object(klass);
return klass;
}
VALUE
-module_new()
+rb_module_new(void)
{
- NEWOBJ(mdl, struct RClass);
- OBJSETUP(mdl, cModule, T_MODULE);
-
- mdl->super = 0;
- mdl->iv_tbl = 0;
- mdl->m_tbl = 0;
- mdl->m_tbl = new_idhash();
-
+ VALUE mdl = class_alloc(T_MODULE, rb_cModule);
+ RCLASS_M_TBL_INIT(mdl);
return (VALUE)mdl;
}
VALUE
-rb_define_module_id(id)
- ID id;
+rb_define_module_id(ID id)
{
- extern st_table *rb_class_tbl;
- VALUE mdl = module_new();
+ VALUE mdl;
+ mdl = rb_module_new();
rb_name_class(mdl, id);
return mdl;
}
VALUE
-rb_define_module(name)
- char *name;
+rb_define_module(const char *name)
{
VALUE module;
ID id;
id = rb_intern(name);
+ if (rb_const_defined(rb_cObject, id)) {
+ module = rb_const_get(rb_cObject, id);
+ if (!RB_TYPE_P(module, T_MODULE)) {
+ rb_raise(rb_eTypeError, "%s is not a module (%"PRIsVALUE")",
+ name, rb_obj_class(module));
+ }
+ return module;
+ }
module = rb_define_module_id(id);
- st_add_direct(rb_class_tbl, id, module);
+ rb_vm_add_root_module(id, module);
+ rb_const_set(rb_cObject, id, module);
return module;
}
VALUE
-rb_define_module_under(outer, name)
- VALUE outer;
- char *name;
+rb_define_module_under(VALUE outer, const char *name)
+{
+ return rb_define_module_id_under(outer, rb_intern(name));
+}
+
+VALUE
+rb_define_module_id_under(VALUE outer, ID id)
{
VALUE module;
- ID id;
- id = rb_intern(name);
+ if (rb_const_defined_at(outer, id)) {
+ module = rb_const_get_at(outer, id);
+ if (!RB_TYPE_P(module, T_MODULE)) {
+ rb_raise(rb_eTypeError, "%"PRIsVALUE"::%"PRIsVALUE" is not a module"
+ " (%"PRIsVALUE")",
+ outer, rb_id2str(id), rb_obj_class(module));
+ }
+ return module;
+ }
module = rb_define_module_id(id);
rb_const_set(outer, id, module);
- rb_set_class_path(module, outer, name);
+ rb_set_class_path_string(module, outer, rb_id2str(id));
+ rb_gc_register_mark_object(module);
return module;
}
-static VALUE
-include_class_new(module, super)
- VALUE module, super;
+VALUE
+rb_include_class_new(VALUE module, VALUE super)
{
- NEWOBJ(klass, struct RClass);
- OBJSETUP(klass, cClass, T_ICLASS);
+ VALUE klass = class_alloc(T_ICLASS, rb_cClass);
+
+ if (BUILTIN_TYPE(module) == T_ICLASS) {
+ module = RBASIC(module)->klass;
+ }
+ if (!RCLASS_IV_TBL(module)) {
+ RCLASS_IV_TBL(module) = st_init_numtable();
+ }
+ if (!RCLASS_CONST_TBL(module)) {
+ RCLASS_CONST_TBL(module) = rb_id_table_create(0);
+ }
+ RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
+ RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
- klass->m_tbl = RCLASS(module)->m_tbl;
- klass->iv_tbl = RCLASS(module)->iv_tbl;
- klass->super = super;
- if (TYPE(module) == T_ICLASS) {
- RBASIC(klass)->klass = RBASIC(module)->klass;
+ 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(klass)->klass = module;
+ RBASIC_SET_CLASS(klass, module);
}
+ OBJ_INFECT(klass, module);
+ OBJ_INFECT(klass, super);
return (VALUE)klass;
}
+static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
+
+static void
+ensure_includable(VALUE klass, VALUE module)
+{
+ rb_frozen_class_p(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
-rb_include_module(klass, module)
- VALUE klass, module;
+rb_include_module(VALUE klass, VALUE module)
{
- VALUE p;
+ int changed = 0;
- if (NIL_P(module)) return;
- if (klass == module) return;
+ ensure_includable(klass, module);
- switch (TYPE(module)) {
- case T_MODULE:
- case T_CLASS:
- case T_ICLASS:
- break;
- default:
- Check_Type(module, T_MODULE);
- }
+ changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
+ if (changed < 0)
+ rb_raise(rb_eArgError, "cyclic include detected");
+}
+
+static enum rb_id_table_iterator_result
+add_refined_method_entry_i(ID key, VALUE value, void *data)
+{
+ rb_add_refined_method_entry((VALUE)data, key);
+ 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;
+ struct rb_id_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
while (module) {
+ int superclass_seen = FALSE;
+ struct rb_id_table *tbl;
+
+ if (RCLASS_ORIGIN(module) != module)
+ goto skip;
+ if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
+ return -1;
/* ignore if the module included already in superclasses */
- for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
- if (BUILTIN_TYPE(p) == T_ICLASS &&
- RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
- if (RCLASS(module)->super) {
- rb_include_module(p, RCLASS(module)->super);
+ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
+ int type = BUILTIN_TYPE(p);
+ if (type == T_ICLASS) {
+ if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
+ if (!superclass_seen) {
+ c = p; /* move insertion point */
+ }
+ goto skip;
}
- return;
}
+ else if (type == T_CLASS) {
+ if (!search_super) break;
+ superclass_seen = TRUE;
+ }
+ }
+ iclass = rb_include_class_new(module, RCLASS_SUPER(c));
+ c = RCLASS_SET_SUPER(c, iclass);
+
+ {
+ VALUE m = module;
+ if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass;
+ 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);
+ 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);
+ 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;
+}
+
+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);
+
+ if (me->def->type == VM_METHOD_TYPE_REFINED) {
+ 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_entry_copy(me, orig_me);
+ return ID_TABLE_CONTINUE;
+ }
+ else {
+ rb_id_table_insert(tbl, key, (VALUE)me);
+ return ID_TABLE_DELETE;
}
- RCLASS(klass)->super =
- include_class_new(module, RCLASS(klass)->super);
- klass = RCLASS(klass)->super;
- module = RCLASS(module)->super;
}
- rb_clear_cache();
+ else {
+ return ID_TABLE_CONTINUE;
+ }
+}
+
+void
+rb_prepend_module(VALUE klass, VALUE module)
+{
+ VALUE origin;
+ int changed = 0;
+
+ ensure_includable(klass, module);
+
+ 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), move_refined_method, (void *)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);
+ }
}
+/*
+ * call-seq:
+ * mod.included_modules -> array
+ *
+ * Returns the list of modules included in <i>mod</i>.
+ *
+ * module Mixin
+ * end
+ *
+ * module Outer
+ * include Mixin
+ * end
+ *
+ * Mixin.included_modules #=> []
+ * Outer.included_modules #=> [Mixin]
+ */
+
VALUE
-mod_included_modules(mod)
- VALUE mod;
+rb_mod_included_modules(VALUE mod)
{
- VALUE ary = ary_new();
+ VALUE ary = rb_ary_new();
VALUE p;
+ VALUE origin = RCLASS_ORIGIN(mod);
- for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
- if (BUILTIN_TYPE(p) == T_ICLASS) {
- ary_push(ary, RBASIC(p)->klass);
+ for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
+ if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
+ VALUE m = RBASIC(p)->klass;
+ if (RB_TYPE_P(m, T_MODULE))
+ rb_ary_push(ary, m);
}
}
return ary;
}
+/*
+ * 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.
+ *
+ * module A
+ * end
+ * class B
+ * include A
+ * end
+ * class C < B
+ * end
+ * B.include?(A) #=> true
+ * C.include?(A) #=> true
+ * A.include?(A) #=> false
+ */
+
VALUE
-mod_ancestors(mod)
- VALUE mod;
+rb_mod_include_p(VALUE mod, VALUE mod2)
{
- VALUE ary = ary_new();
VALUE p;
- for (p = mod; p; p = RCLASS(p)->super) {
- if (FL_TEST(p, FL_SINGLETON))
- continue;
+ Check_Type(mod2, T_MODULE);
+ for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
- ary_push(ary, RBASIC(p)->klass);
- }
- else {
- ary_push(ary, p);
+ if (RBASIC(p)->klass == mod2) return Qtrue;
}
}
- return ary;
+ return Qfalse;
}
-static int
-ins_methods_i(key, body, ary)
- ID key;
- NODE *body;
- VALUE ary;
+/*
+ * call-seq:
+ * mod.ancestors -> array
+ *
+ * Returns a list of modules included/prepended in <i>mod</i>
+ * (including <i>mod</i> itself).
+ *
+ * module Mod
+ * include Math
+ * include Comparable
+ * prepend Enumerable
+ * end
+ *
+ * Mod.ancestors #=> [Enumerable, Mod, Comparable, Math]
+ * Math.ancestors #=> [Math]
+ * Enumerable.ancestors #=> [Enumerable]
+ */
+
+VALUE
+rb_mod_ancestors(VALUE mod)
{
- if ((body->nd_noex&(NOEX_PRIVATE|NOEX_PROTECTED)) == 0) {
- VALUE name = str_new2(rb_id2name(key));
+ VALUE p, ary = rb_ary_new();
- if (!ary_includes(ary, name)) {
- if (!body->nd_body) {
- ary_push(ary, Qnil);
- }
- ary_push(ary, name);
+ for (p = mod; p; p = RCLASS_SUPER(p)) {
+ if (BUILTIN_TYPE(p) == T_ICLASS) {
+ rb_ary_push(ary, RBASIC(p)->klass);
+ }
+ else if (p == RCLASS_ORIGIN(p)) {
+ rb_ary_push(ary, p);
}
}
- else if (body->nd_body && nd_type(body->nd_body) == NODE_ZSUPER) {
- ary_push(ary, Qnil);
- ary_push(ary, str_new2(rb_id2name(key)));
+ return ary;
+}
+
+static void
+ins_methods_push(st_data_t name, st_data_t ary)
+{
+ rb_ary_push((VALUE)ary, ID2SYM((ID)name));
+}
+
+static int
+ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
+{
+ switch ((rb_method_visibility_t)type) {
+ case METHOD_VISI_UNDEF:
+ case METHOD_VISI_PRIVATE:
+ break;
+ default: /* everything but private */
+ ins_methods_push(name, ary);
+ break;
}
return ST_CONTINUE;
}
static int
-ins_methods_prot_i(key, body, ary)
- ID key;
- NODE *body;
- VALUE ary;
+ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
{
- if (!body->nd_body) {
- ary_push(ary, Qnil);
- ary_push(ary, str_new2(rb_id2name(key)));
+ if ((rb_method_visibility_t)type == METHOD_VISI_PROTECTED) {
+ ins_methods_push(name, ary);
}
- else if (body->nd_noex & NOEX_PROTECTED) {
- VALUE name = str_new2(rb_id2name(key));
+ return ST_CONTINUE;
+}
- if (!ary_includes(ary, name)) {
- ary_push(ary, name);
- }
- }
- else if (nd_type(body->nd_body) == NODE_ZSUPER) {
- ary_push(ary, Qnil);
- ary_push(ary, str_new2(rb_id2name(key)));
+static int
+ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
+{
+ if ((rb_method_visibility_t)type == METHOD_VISI_PRIVATE) {
+ ins_methods_push(name, ary);
}
return ST_CONTINUE;
}
static int
-ins_methods_priv_i(key, body, ary)
- ID key;
- NODE *body;
- VALUE ary;
+ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
{
- if (!body->nd_body) {
- ary_push(ary, Qnil);
- ary_push(ary, str_new2(rb_id2name(key)));
+ if ((rb_method_visibility_t)type == METHOD_VISI_PUBLIC) {
+ ins_methods_push(name, ary);
}
- else if (body->nd_noex & NOEX_PRIVATE) {
- VALUE name = str_new2(rb_id2name(key));
+ return ST_CONTINUE;
+}
- if (!ary_includes(ary, name)) {
- ary_push(ary, name);
- }
+struct method_entry_arg {
+ st_table *list;
+ int recur;
+};
+
+static enum rb_id_table_iterator_result
+method_entry_i(ID key, VALUE value, void *data)
+{
+ const rb_method_entry_t *me = (const rb_method_entry_t *)value;
+ struct method_entry_arg *arg = (struct method_entry_arg *)data;
+ rb_method_visibility_t type;
+
+ if (me->def->type == VM_METHOD_TYPE_REFINED) {
+ VALUE owner = me->owner;
+ me = rb_resolve_refined_method(Qnil, me);
+ if (!me) return ID_TABLE_CONTINUE;
+ if (!arg->recur && me->owner != owner) return ID_TABLE_CONTINUE;
}
- else if (nd_type(body->nd_body) == NODE_ZSUPER) {
- ary_push(ary, Qnil);
- ary_push(ary, str_new2(rb_id2name(key)));
+ if (!st_lookup(arg->list, key, 0)) {
+ if (UNDEFINED_METHOD_ENTRY_P(me)) {
+ type = METHOD_VISI_UNDEF; /* none */
+ }
+ else {
+ type = METHOD_ENTRY_VISI(me);
+ }
+ st_add_direct(arg->list, key, (st_data_t)type);
}
- return ST_CONTINUE;
+ return ID_TABLE_CONTINUE;
}
static VALUE
-method_list(mod, option, func)
- VALUE mod;
- int option;
- int (*func)();
+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;
- VALUE klass;
- VALUE *p, *q, *pend;
+ int recur, prepended = 0;
+ struct method_entry_arg me_arg;
- ary = ary_new();
- for (klass = mod; klass; klass = RCLASS(klass)->super) {
- st_foreach(RCLASS(klass)->m_tbl, func, ary);
- if (!option) break;
+ if (argc == 0) {
+ recur = TRUE;
}
- p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
- while (p < pend) {
- if (*p == Qnil) {
- p+=2;
- continue;
- }
- *q++ = *p++;
+ else {
+ VALUE r;
+ rb_scan_args(argc, argv, "01", &r);
+ recur = RTEST(r);
+ }
+
+ if (!recur && RCLASS_ORIGIN(mod) != mod) {
+ mod = RCLASS_ORIGIN(mod);
+ 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);
+ if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
+ if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
+ if (!recur) break;
}
- RARRAY(ary)->len = q - RARRAY(ary)->ptr;
+ ary = rb_ary_new();
+ st_foreach(me_arg.list, func, ary);
+ st_free_table(me_arg.list);
+
return ary;
}
+/*
+ * call-seq:
+ * mod.instance_methods(include_super=true) -> array
+ *
+ * Returns an array containing the names of the public and protected instance
+ * methods in the receiver. For a module, these are the public and protected methods;
+ * for a class, they are the instance (not singleton) methods. If the optional
+ * parameter is <code>false</code>, the methods of any ancestors are not included.
+ *
+ * module A
+ * def method1() end
+ * end
+ * class B
+ * include A
+ * def method2() end
+ * end
+ * class C < B
+ * def method3() end
+ * end
+ *
+ * A.instance_methods(false) #=> [:method1]
+ * B.instance_methods(false) #=> [:method2]
+ * B.instance_methods(true).include?(:method1) #=> true
+ * C.instance_methods(false) #=> [:method3]
+ * C.instance_methods.include?(:method2) #=> true
+ */
+
+VALUE
+rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
+{
+ return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
+}
+
+/*
+ * call-seq:
+ * mod.protected_instance_methods(include_super=true) -> array
+ *
+ * Returns a list of the protected instance methods defined in
+ * <i>mod</i>. If the optional parameter is <code>false</code>, the
+ * methods of any ancestors are not included.
+ */
+
VALUE
-class_instance_methods(argc, argv, mod)
- int argc;
- VALUE *argv;
- VALUE mod;
+rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
- VALUE option;
+ return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
+}
+
+/*
+ * call-seq:
+ * mod.private_instance_methods(include_super=true) -> array
+ *
+ * Returns a list of the private instance methods defined in
+ * <i>mod</i>. If the optional parameter is <code>false</code>, the
+ * methods of any ancestors are not included.
+ *
+ * module Mod
+ * def method1() end
+ * private :method1
+ * def method2() end
+ * end
+ * Mod.instance_methods #=> [:method2]
+ * Mod.private_instance_methods #=> [:method1]
+ */
- rb_scan_args(argc, argv, "01", &option);
- return method_list(mod, RTEST(option), ins_methods_i);
+VALUE
+rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod)
+{
+ return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
}
+/*
+ * call-seq:
+ * mod.public_instance_methods(include_super=true) -> array
+ *
+ * Returns a list of the public instance methods defined in <i>mod</i>.
+ * If the optional parameter is <code>false</code>, the methods of
+ * any ancestors are not included.
+ */
+
VALUE
-class_protected_instance_methods(argc, argv, mod)
- int argc;
- VALUE *argv;
- VALUE mod;
+rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
- VALUE option;
+ return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
+}
- rb_scan_args(argc, argv, "01", &option);
- return method_list(mod, RTEST(option), ins_methods_prot_i);
+/*
+ * call-seq:
+ * obj.methods(regular=true) -> array
+ *
+ * Returns a list of the names of public and protected methods of
+ * <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,
+ * the array will not include methods in modules included in <i>obj</i>.
+ *
+ * class Klass
+ * def klass_method()
+ * end
+ * end
+ * k = Klass.new
+ * k.methods[0..9] #=> [:klass_method, :nil?, :===,
+ * # :==~, :!, :eql?
+ * # :hash, :<=>, :class, :singleton_class]
+ * k.methods.length #=> 56
+ *
+ * k.methods(false) #=> []
+ * def k.singleton_method; end
+ * k.methods(false) #=> [:singleton_method]
+ *
+ * module M123; def m123; end end
+ * k.extend M123
+ * k.methods(false) #=> [:singleton_method]
+ */
+
+VALUE
+rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
+{
+ rb_check_arity(argc, 0, 1);
+ if (argc > 0 && !RTEST(argv[0])) {
+ return rb_obj_singleton_methods(argc, argv, obj);
+ }
+ return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
}
+/*
+ * call-seq:
+ * obj.protected_methods(all=true) -> array
+ *
+ * Returns the list of protected methods accessible to <i>obj</i>. If
+ * the <i>all</i> parameter is set to <code>false</code>, only those methods
+ * in the receiver will be listed.
+ */
+
VALUE
-class_private_instance_methods(argc, argv, mod)
- int argc;
- VALUE *argv;
- VALUE mod;
+rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
{
- VALUE option;
+ return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
+}
- rb_scan_args(argc, argv, "01", &option);
- return method_list(mod, RTEST(option), ins_methods_priv_i);
+/*
+ * call-seq:
+ * obj.private_methods(all=true) -> array
+ *
+ * Returns the list of private methods accessible to <i>obj</i>. If
+ * the <i>all</i> parameter is set to <code>false</code>, only those methods
+ * in the receiver will be listed.
+ */
+
+VALUE
+rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
+{
+ return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
}
+/*
+ * call-seq:
+ * obj.public_methods(all=true) -> array
+ *
+ * Returns the list of public methods accessible to <i>obj</i>. If
+ * the <i>all</i> parameter is set to <code>false</code>, only those methods
+ * in the receiver will be listed.
+ */
+
VALUE
-obj_singleton_methods(obj)
- VALUE obj;
+rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
{
- VALUE ary;
- VALUE klass;
- VALUE *p, *q, *pend;
+ return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
+}
+
+/*
+ * call-seq:
+ * obj.singleton_methods(all=true) -> array
+ *
+ * Returns an array of the names of singleton methods for <i>obj</i>.
+ * If the optional <i>all</i> parameter is true, the list will include
+ * methods in modules included in <i>obj</i>.
+ * Only public and protected singleton methods are returned.
+ *
+ * module Other
+ * def three() end
+ * end
+ *
+ * class Single
+ * def Single.four() end
+ * end
+ *
+ * a = Single.new
+ *
+ * def a.one()
+ * end
+ *
+ * class << a
+ * include Other
+ * def two()
+ * end
+ * end
+ *
+ * Single.singleton_methods #=> [:four]
+ * a.singleton_methods(false) #=> [:two, :one]
+ * a.singleton_methods #=> [:two, :one, :three]
+ */
- ary = ary_new();
+VALUE
+rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
+{
+ VALUE recur, ary, klass, origin;
+ struct method_entry_arg me_arg;
+ struct rb_id_table *mtbl;
+
+ if (argc == 0) {
+ recur = Qtrue;
+ }
+ else {
+ rb_scan_args(argc, argv, "01", &recur);
+ }
klass = CLASS_OF(obj);
- while (klass && FL_TEST(klass, FL_SINGLETON)) {
- st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
- klass = RCLASS(klass)->super;
+ origin = RCLASS_ORIGIN(klass);
+ me_arg.list = st_init_numtable();
+ me_arg.recur = RTEST(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);
}
- p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
- while (p < pend) {
- if (*p == Qnil) {
- p+=2;
- continue;
+ if (RTEST(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);
}
- *q++ = *p++;
}
- RARRAY(ary)->len = q - RARRAY(ary)->ptr;
+ ary = rb_ary_new();
+ st_foreach(me_arg.list, ins_methods_i, ary);
+ st_free_table(me_arg.list);
return ary;
}
+/*!
+ * \}
+ */
+/*!
+ * \defgroup defmethod Defining methods
+ * There are some APIs to define a method from C.
+ * These API takes a C function as a method body.
+ *
+ * \par Method body functions
+ * Method body functions must return a VALUE and
+ * can be one of the following form:
+ * <dl>
+ * <dt>Fixed number of parameters</dt>
+ * <dd>
+ * This form is a normal C function, excepting it takes
+ * a receiver object as the first argument.
+ *
+ * \code
+ * static VALUE my_method(VALUE self, VALUE x, VALUE y);
+ * \endcode
+ * </dd>
+ * <dt>argc and argv style</dt>
+ * <dd>
+ * This form takes three parameters: \a argc, \a argv and \a self.
+ * \a self is the receiver. \a argc is the number of arguments.
+ * \a argv is a pointer to an array of the arguments.
+ *
+ * \code
+ * static VALUE my_method(int argc, VALUE *argv, VALUE self);
+ * \endcode
+ * </dd>
+ * <dt>Ruby array style</dt>
+ * <dd>
+ * This form takes two parameters: self and args.
+ * \a self is the receiver. \a args is an Array object which
+ * contains the arguments.
+ *
+ * \code
+ * static VALUE my_method(VALUE self, VALUE args);
+ * \endcode
+ * </dd>
+ *
+ * \par Number of parameters
+ * Method defining APIs takes the number of parameters which the
+ * method will takes. This number is called \a argc.
+ * \a argc can be:
+ * <dl>
+ * <dt>zero or positive number</dt>
+ * <dd>This means the method body function takes a fixed number of parameters</dd>
+ * <dt>-1</dt>
+ * <dd>This means the method body function is "argc and argv" style.</dd>
+ * <dt>-2</dt>
+ * <dd>This means the method body function is "self and args" style.</dd>
+ * </dl>
+ * \{
+ */
+
void
-rb_define_method_id(klass, name, func, argc)
- VALUE klass;
- ID name;
- VALUE (*func)();
- int argc;
+rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC|NOEX_CFUNC);
+ rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC);
}
void
-rb_define_method(klass, name, func, argc)
- VALUE klass;
- char *name;
- VALUE (*func)();
- int argc;
+rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
- ID id = rb_intern(name);
+ rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PUBLIC);
+}
- rb_add_method(klass, id, NEW_CFUNC(func, argc),
- ((name[0] == 'i' && id == rb_intern("initialize"))?
- NOEX_PRIVATE:NOEX_PUBLIC)|NOEX_CFUNC);
+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);
}
void
-rb_define_protected_method(klass, name, func, argc)
- VALUE klass;
- char *name;
- VALUE (*func)();
- int argc;
+rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
- NOEX_PROTECTED|NOEX_CFUNC);
+ rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PRIVATE);
}
void
-rb_define_private_method(klass, name, func, argc)
- VALUE klass;
- char *name;
- VALUE (*func)();
- int argc;
+rb_undef_method(VALUE klass, const char *name)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
- NOEX_PRIVATE|NOEX_CFUNC);
+ rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
+}
+
+static enum rb_id_table_iterator_result
+undef_method_i(ID name, VALUE value, void *data)
+{
+ VALUE klass = (VALUE)data;
+ rb_add_method(klass, name, VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF);
+ return ID_TABLE_CONTINUE;
}
void
-rb_undef_method(klass, name)
- VALUE klass;
- char *name;
+rb_undef_methods_from(VALUE klass, VALUE super)
+{
+ struct rb_id_table *mtbl = RCLASS_M_TBL(super);
+ if (mtbl) {
+ rb_id_table_foreach(mtbl, undef_method_i, (void *)klass);
+ }
+}
+
+/*!
+ * \}
+ */
+/*!
+ * \addtogroup class
+ * \{
+ */
+
+#define SPECIAL_SINGLETON(x,c) do {\
+ if (obj == (x)) {\
+ return (c);\
+ }\
+} while (0)
+
+static inline VALUE
+special_singleton_class_of(VALUE obj)
{
- rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
+ SPECIAL_SINGLETON(Qnil, rb_cNilClass);
+ SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
+ SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
+ return Qnil;
}
VALUE
-rb_singleton_class(obj)
- VALUE obj;
+rb_special_singleton_class(VALUE obj)
{
- if (rb_special_const_p(obj)) {
- TypeError("cannot define singleton");
+ return special_singleton_class_of(obj);
+}
+
+/*!
+ * \internal
+ * Returns the singleton class of \a obj. Creates it if necessary.
+ *
+ * \note DO NOT expose the returned singleton class to
+ * outside of class.c.
+ * Use \ref rb_singleton_class instead for
+ * consistency of the metaclass hierarchy.
+ */
+static VALUE
+singleton_class_of(VALUE obj)
+{
+ VALUE klass;
+
+ if (FIXNUM_P(obj) || FLONUM_P(obj) || STATIC_SYM_P(obj)) {
+ no_singleton:
+ rb_raise(rb_eTypeError, "can't define singleton");
}
- if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) {
- return RBASIC(obj)->klass;
+ if (SPECIAL_CONST_P(obj)) {
+ klass = special_singleton_class_of(obj);
+ if (NIL_P(klass))
+ rb_bug("unknown immediate %p", (void *)obj);
+ return klass;
}
- RBASIC(obj)->klass = singleton_class_new(RBASIC(obj)->klass);
- singleton_class_attached(RBASIC(obj)->klass, obj);
- return RBASIC(obj)->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;
+ }
+ }
+
+ klass = RBASIC(obj)->klass;
+ if (!(FL_TEST(klass, FL_SINGLETON) &&
+ rb_ivar_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;
}
void
-rb_define_singleton_method(obj, name, func, argc)
- VALUE obj;
- char *name;
- VALUE (*func)();
- int argc;
+rb_freeze_singleton_class(VALUE x)
+{
+ /* should not propagate to meta-meta-class, and so on */
+ if (!(RBASIC(x)->flags & FL_SINGLETON)) {
+ VALUE klass = RBASIC_CLASS(x);
+ if (klass && (klass = RCLASS_ORIGIN(klass)) != 0 &&
+ FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
+ OBJ_FREEZE_RAW(klass);
+ }
+ }
+}
+
+/*!
+ * Returns the singleton class of \a obj, or nil if obj is not a
+ * singleton object.
+ *
+ * \param obj an arbitrary object.
+ * \return the singleton class or nil.
+ */
+VALUE
+rb_singleton_class_get(VALUE obj)
{
- rb_define_method(rb_singleton_class(obj), name, func, argc);
+ VALUE klass;
+
+ if (SPECIAL_CONST_P(obj)) {
+ return rb_special_singleton_class(obj);
+ }
+ klass = RBASIC(obj)->klass;
+ if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
+ if (rb_ivar_get(klass, id_attached) != obj) return Qnil;
+ return klass;
+}
+
+/*!
+ * 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.
+ * \return the singleton class.
+ *
+ * \post \a obj has its own singleton class.
+ * \post if \a obj is a class,
+ * the returned singleton class also has its own
+ * singleton class in order to keep consistency of the
+ * inheritance structure of metaclasses.
+ * \note a new singleton class will be created
+ * if \a obj does not have it.
+ * \note the singleton classes for nil, true and false are:
+ * NilClass, TrueClass and FalseClass.
+ */
+VALUE
+rb_singleton_class(VALUE obj)
+{
+ VALUE klass = singleton_class_of(obj);
+
+ /* ensures an exposed class belongs to its own eigenclass */
+ if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass);
+
+ return klass;
}
+/*!
+ * \}
+ */
+
+/*!
+ * \addtogroup defmethod
+ * \{
+ */
+
+/*!
+ * Defines a singleton method for \a obj.
+ * \param obj an arbitrary object
+ * \param name name of the singleton method
+ * \param func the method body
+ * \param argc the number of parameters, or -1 or -2. see \ref defmethod.
+ */
void
-rb_define_module_function(module, name, func, argc)
- VALUE module;
- char *name;
- VALUE (*func)();
- int argc;
+rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
+{
+ rb_define_method(singleton_class_of(obj), name, func, argc);
+}
+
+
+
+/*!
+ * Defines a module function for \a module.
+ * \param module an module or a class.
+ * \param name name of the function
+ * \param func the method body
+ * \param argc the number of parameters, or -1 or -2. see \ref defmethod.
+ */
+void
+rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
{
rb_define_private_method(module, name, func, argc);
rb_define_singleton_method(module, name, func, argc);
}
+
+/*!
+ * Defines a global function
+ * \param name name of the function
+ * \param func the method body
+ * \param argc the number of parameters, or -1 or -2. see \ref defmethod.
+ */
void
-rb_define_global_function(name, func, argc)
- char *name;
- VALUE (*func)();
- int argc;
+rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
{
- rb_define_private_method(mKernel, name, func, argc);
+ rb_define_module_function(rb_mKernel, name, func, argc);
}
+
+/*!
+ * Defines an alias of a method.
+ * \param klass the class which the original method belongs to
+ * \param name1 a new name for the method
+ * \param name2 the original name of the method
+ */
void
-rb_define_alias(klass, name1, name2)
- VALUE klass;
- char *name1, *name2;
+rb_define_alias(VALUE klass, const char *name1, const char *name2)
{
rb_alias(klass, rb_intern(name1), rb_intern(name2));
}
+/*!
+ * Defines (a) public accessor method(s) for an attribute.
+ * \param klass the class which the attribute will belongs to
+ * \param name name of the attribute
+ * \param read a getter method for the attribute will be defined if \a read is non-zero.
+ * \param write a setter method for the attribute will be defined if \a write is non-zero.
+ */
void
-rb_define_attr(klass, name, read, write)
- VALUE klass;
- char *name;
- int read, write;
+rb_define_attr(VALUE klass, const char *name, int read, int write)
{
rb_attr(klass, rb_intern(name), read, write, FALSE);
}
-#ifdef HAVE_STDARG_PROTOTYPES
-#include <stdarg.h>
-#define va_init_list(a,b) va_start(a,b)
-#else
-#include <varargs.h>
-#define va_init_list(a,b) va_start(a)
-#endif
+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));
+ if (++i >= len) break;
+ rb_str_cat_cstr(error_message, ", ");
+ }
+ }
+
+ return rb_exc_new_str(rb_eArgError, error_message);
+}
+
+NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
+static void
+rb_keyword_error(const char *error, VALUE keys)
+{
+ rb_exc_raise(rb_keyword_error_new(error, keys));
+}
+
+NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
+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_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);
+ return ST_CONTINUE;
+}
+
+VALUE
+rb_extract_keywords(VALUE *orighash)
+{
+ VALUE parthash[2] = {0, 0};
+ VALUE hash = *orighash;
+
+ if (RHASH_EMPTY_P(hash)) {
+ *orighash = 0;
+ return hash;
+ }
+ st_foreach(rb_hash_tbl_raw(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));
+ }
+ return parthash[0];
+}
int
-#ifdef HAVE_STDARG_PROTOTYPES
-rb_scan_args(int argc, VALUE *argv, char *fmt, ...)
-#else
-rb_scan_args(argc, argv, fmt, va_alist)
- int argc;
- VALUE *argv;
- char *fmt;
- va_dcl
-#endif
-{
- int n, i;
- char *p = fmt;
- VALUE *var;
- va_list vargs;
+rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
+{
+ int i = 0, j;
+ int rest = 0;
+ VALUE missing = Qnil;
+ st_data_t key;
- va_init_list(vargs, fmt);
+#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)))
- if (*p == '*') {
- var = va_arg(vargs, VALUE*);
- *var = ary_new4(argc, argv);
- return argc;
+ if (NIL_P(keyword_hash)) keyword_hash = 0;
+
+ if (optional < 0) {
+ 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;
+ continue;
+ }
+ }
+ if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
+ rb_ary_push(missing, keyword);
+ }
+ if (!NIL_P(missing)) {
+ rb_keyword_error("missing", missing);
+ }
+ }
+ 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;
+ j++;
+ }
+ }
}
+ if (!rest && keyword_hash) {
+ if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : j)) {
+ unknown_keyword_error(keyword_hash, table, required+optional);
+ }
+ }
+ return j;
+#undef extract_kwarg
+}
+
+#undef rb_scan_args
+int
+rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
+{
+ 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;
if (ISDIGIT(*p)) {
- n = *p - '0';
- if (n > argc)
- ArgError("Wrong # of arguments (%d for %d)", argc, n);
- for (i=0; i<n; i++) {
- var = va_arg(vargs, VALUE*);
- *var = argv[i];
+ n_lead = *p - '0';
+ p++;
+ if (ISDIGIT(*p)) {
+ n_opt = *p - '0';
+ p++;
}
+ }
+ if (*p == '*') {
+ f_var = 1;
p++;
}
- else {
- goto error;
+ if (ISDIGIT(*p)) {
+ n_trail = *p - '0';
+ p++;
+ }
+ if (*p == ':') {
+ f_hash = 1;
+ p++;
+ }
+ if (*p == '&') {
+ f_block = 1;
+ p++;
+ }
+ if (*p != '\0') {
+ rb_fatal("bad scan arg format: %s", fmt);
}
+ n_mand = n_lead + n_trail;
- if (ISDIGIT(*p)) {
- n = i + *p - '0';
- for (; i<n; i++) {
- var = va_arg(vargs, VALUE*);
- if (argc > i) {
- *var = argv[i];
- }
- else {
- *var = Qnil;
+ if (argc < n_mand)
+ goto argc_error;
+
+ va_start(vargs, fmt);
+
+ /* capture an option hash - phase 1: pop */
+ if (f_hash && n_mand < argc) {
+ VALUE last = argv[argc - 1];
+
+ 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;
}
}
- p++;
}
-
- if(*p == '*') {
- var = va_arg(vargs, VALUE*);
- if (argc > i) {
- *var = ary_new4(argc-i, argv+i);
+ /* 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];
+ 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];
+ argi++;
}
else {
- *var = ary_new();
+ if (var) *var = Qnil;
}
}
- else if (*p == '\0') {
- if (argc > i) {
- ArgError("Wrong # of arguments(%d for %d)", argc, i);
+ /* capture variable length arguments */
+ if (f_var) {
+ int n_var = argc - argi - n_trail;
+
+ var = va_arg(vargs, VALUE *);
+ 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();
}
}
- else {
- goto error;
+ /* 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];
+ argi++;
+ }
+ /* capture an option hash - phase 2: assignment */
+ if (f_hash) {
+ var = va_arg(vargs, VALUE *);
+ if (var) *var = hash;
+ }
+ /* capture iterator block */
+ if (f_block) {
+ var = va_arg(vargs, VALUE *);
+ if (rb_block_given_p()) {
+ *var = rb_block_proc();
+ }
+ else {
+ *var = Qnil;
+ }
}
-
va_end(vargs);
+
+ if (argi < argc) {
+ argc_error:
+ rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
+ }
+
return argc;
+}
- error:
- Fatal("bad scan arg format: %s", fmt);
- return 0;
+int
+rb_class_has_methods(VALUE c)
+{
+ return rb_id_table_size(RCLASS_M_TBL(c)) == 0 ? FALSE : TRUE;
}
+
+/*!
+ * \}
+ */
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000000..2175f67eba
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,2933 @@
+bin: $(PROGRAM) $(WPROGRAM)
+lib: $(LIBRUBY)
+dll: $(LIBRUBY_SO)
+
+.SUFFIXES: .inc .h .c .y .i .$(DTRACE_EXT)
+
+# V=0 quiet, V=1 verbose. other values don't work.
+V = 0
+Q1 = $(V:1=)
+Q = $(Q1:0=@)
+ECHO0 = $(ECHO1:0=echo)
+ECHO = @$(ECHO0)
+
+mflags = $(MFLAGS)
+gnumake_recursive =
+enable_shared = $(ENABLE_SHARED:no=)
+
+UNICODE_VERSION = 10.0.0
+UNICODE_EMOJI_VERSION = 5.0
+
+### 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)/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 \
+ $(UNICODE_HDR_DIR)/name2ctype.h \
+ $(empty)
+
+RUBY_RELEASE_DATE = $(RUBY_RELEASE_YEAR)-$(RUBY_RELEASE_MONTH)-$(RUBY_RELEASE_DAY)
+RUBYLIB = $(PATH_SEPARATOR)
+RUBYOPT = -
+RUN_OPTS = --disable-gems
+
+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
+SIMPLECOV_HTML_GIT_REF = v0.10.2
+DOCLIE_GIT_URL = git://github.com/ms-ati/docile.git
+DOCLIE_GIT_REF = v1.1.5
+
+STATIC_RUBY = static-ruby
+
+TIMESTAMPDIR = $(EXTOUT)/.timestamp
+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
+RDOCOUT = $(EXTOUT)/rdoc
+HTMLOUT = $(EXTOUT)/html
+CAPIOUT = doc/capi
+
+INITOBJS = dmyext.$(OBJEXT) dmyenc.$(OBJEXT)
+NORMALMAINOBJ = main.$(OBJEXT)
+MAINOBJ = $(NORMALMAINOBJ)
+DLDOBJS = $(INITOBJS)
+EXTSOLIBS =
+MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) dmyext.$(OBJEXT) miniprelude.$(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) \
+ bignum.$(OBJEXT) \
+ class.$(OBJEXT) \
+ compar.$(OBJEXT) \
+ compile.$(OBJEXT) \
+ complex.$(OBJEXT) \
+ cont.$(OBJEXT) \
+ debug.$(OBJEXT) \
+ debug_counter.$(OBJEXT) \
+ dir.$(OBJEXT) \
+ dln_find.$(OBJEXT) \
+ encoding.$(OBJEXT) \
+ enum.$(OBJEXT) \
+ enumerator.$(OBJEXT) \
+ error.$(OBJEXT) \
+ eval.$(OBJEXT) \
+ file.$(OBJEXT) \
+ gc.$(OBJEXT) \
+ hash.$(OBJEXT) \
+ inits.$(OBJEXT) \
+ io.$(OBJEXT) \
+ iseq.$(OBJEXT) \
+ load.$(OBJEXT) \
+ marshal.$(OBJEXT) \
+ math.$(OBJEXT) \
+ node.$(OBJEXT) \
+ numeric.$(OBJEXT) \
+ object.$(OBJEXT) \
+ pack.$(OBJEXT) \
+ parse.$(OBJEXT) \
+ proc.$(OBJEXT) \
+ process.$(OBJEXT) \
+ random.$(OBJEXT) \
+ range.$(OBJEXT) \
+ rational.$(OBJEXT) \
+ re.$(OBJEXT) \
+ regcomp.$(OBJEXT) \
+ regenc.$(OBJEXT) \
+ regerror.$(OBJEXT) \
+ regexec.$(OBJEXT) \
+ regparse.$(OBJEXT) \
+ regsyntax.$(OBJEXT) \
+ ruby.$(OBJEXT) \
+ safe.$(OBJEXT) \
+ signal.$(OBJEXT) \
+ sprintf.$(OBJEXT) \
+ st.$(OBJEXT) \
+ strftime.$(OBJEXT) \
+ string.$(OBJEXT) \
+ struct.$(OBJEXT) \
+ symbol.$(OBJEXT) \
+ thread.$(OBJEXT) \
+ time.$(OBJEXT) \
+ transcode.$(OBJEXT) \
+ util.$(OBJEXT) \
+ variable.$(OBJEXT) \
+ version.$(OBJEXT) \
+ vm.$(OBJEXT) \
+ vm_backtrace.$(OBJEXT) \
+ vm_dump.$(OBJEXT) \
+ vm_trace.$(OBJEXT) \
+ $(DTRACE_OBJ) \
+ $(BUILTIN_ENCOBJS) \
+ $(BUILTIN_TRANSOBJS) \
+ $(MISSING)
+
+EXPORTOBJS = $(DLNOBJ) \
+ localeinit.$(OBJEXT) \
+ loadpath.$(OBJEXT) \
+ $(COMMONOBJS)
+
+OBJS = $(EXPORTOBJS) prelude.$(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
+GOLFPRELUDES = {$(srcdir)}golf_prelude.c
+
+SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
+ --extout="$(EXTOUT)" \
+ --mflags="$(MFLAGS)" \
+ --make-flags="$(MAKEFLAGS)"
+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_ARGS = $(SCRIPT_ARGS) \
+ --data-mode=$(INSTALL_DATA_MODE) \
+ --prog-mode=$(INSTALL_PROG_MODE) \
+ --installed-list $(INSTALLED_LIST) \
+ --mantype="$(MANTYPE)"
+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
+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
+
+SHOWFLAGS = showflags
+
+all: $(SHOWFLAGS) main docs
+
+main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs
+ @$(NULLCMD)
+
+.PHONY: showflags
+exts enc trans: $(SHOWFLAGS)
+showflags:
+ $(MESSAGE_BEGIN) \
+ " CC = $(CC)" \
+ " LD = $(LD)" \
+ " LDSHARED = $(LDSHARED)" \
+ " CFLAGS = $(CFLAGS)" \
+ " XCFLAGS = $(XCFLAGS)" \
+ " CPPFLAGS = $(CPPFLAGS)" \
+ " DLDFLAGS = $(DLDFLAGS)" \
+ " SOLIBS = $(SOLIBS)" \
+ " LANG = $(LANG)" \
+ " LC_ALL = $(LC_ALL)" \
+ " LC_CTYPE = $(LC_CTYPE)" \
+ $(MESSAGE_END)
+ -@$(CC_VERSION)
+
+.PHONY: showconfig
+showconfig:
+ @$(ECHO_BEGIN) \
+ $(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
+ $(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)
+
+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 \
+ $(srcdir)/template/$(@F).tmpl --srcdir="$(srcdir)" \
+ --miniruby="$(MINIRUBY)" --script-args='$(SCRIPT_ARGS)'
+
+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) $(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 \
+ $(srcdir)/template/extinit.c.tmpl $(EXTINITS)
+
+prog: program wprogram
+programs: $(PROGRAM) $(WPROGRAM)
+
+$(PREP): $(MKFILES)
+
+miniruby$(EXEEXT): config.status $(ALLOBJS) $(ARCHFILE)
+
+objs: $(ALLOBJS)
+
+GORUBY = go$(RUBY_INSTALL_NAME)
+golf: $(LIBRUBY) $(GOLFOBJS) PHONY
+ $(Q) $(MAKE) $(mflags) \
+ MAINOBJ=goruby.$(OBJEXT) \
+ EXTOBJS="golf_prelude.$(OBJEXT) $(EXTOBJS)" \
+ PROGRAM=$(GORUBY)$(EXEEXT) \
+ program
+capi: $(CAPIOUT)/.timestamp PHONY
+
+$(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)}' "$@"
+
+Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(srcdir)/tool/generic_erb.rb $(RBCONFIG)
+ $(ECHO) generating $@
+ $(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \
+ --srcdir="$(srcdir)" --miniruby="$(MINIRUBY)"
+
+program: $(SHOWFLAGS) $(PROGRAM)
+wprogram: $(SHOWFLAGS) $(WPROGRAM)
+mini: PHONY miniruby$(EXEEXT)
+
+$(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_EXTS):
+ @exit > $@
+
+$(STATIC_RUBY)$(EXEEXT): $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A)
+ $(Q)$(RM) $@
+ $(PURIFY) $(CC) $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(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_|rb_ec_\.)/{print $$1}' | \
+ sort -u -o $@
+
+install: install-$(INSTALLDOC)
+docs: $(DOCTARGETS)
+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
+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
+ @$(NULLCMD)
+
+install-nodoc: pre-install-nodoc do-install-nodoc post-install-nodoc
+pre-install-nodoc:: pre-install-local pre-install-ext
+do-install-nodoc: main pre-install-nodoc
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS)
+post-install-nodoc:: post-install-local post-install-ext
+
+install-local: pre-install-local do-install-local post-install-local
+pre-install-local:: pre-install-bin pre-install-lib pre-install-man
+do-install-local: $(PROGRAM) pre-install-local
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=local
+post-install-local:: post-install-bin post-install-lib post-install-man
+
+install-ext: pre-install-ext do-install-ext post-install-ext
+pre-install-ext:: pre-install-ext-arch pre-install-ext-comm
+do-install-ext: exts pre-install-ext
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext
+post-install-ext:: post-install-ext-arch post-install-ext-comm
+
+install-arch: pre-install-arch do-install-arch post-install-arch
+pre-install-arch:: pre-install-bin pre-install-ext-arch
+do-install-arch: main do-install-arch
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=arch
+post-install-arch:: post-install-bin post-install-ext-arch
+
+install-comm: pre-install-comm do-install-comm post-install-comm
+pre-install-comm:: pre-install-lib pre-install-ext-comm pre-install-man
+do-install-comm: $(PREP) pre-install-comm
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=lib --install=ext-comm --install=man
+post-install-comm:: post-install-lib post-install-ext-comm post-install-man
+
+install-bin: pre-install-bin do-install-bin post-install-bin
+pre-install-bin:: install-prereq
+do-install-bin: $(PROGRAM) pre-install-bin
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=bin
+post-install-bin::
+ @$(NULLCMD)
+
+install-lib: pre-install-lib do-install-lib post-install-lib
+pre-install-lib:: install-prereq
+do-install-lib: $(PREP) pre-install-lib
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=lib
+post-install-lib::
+ @$(NULLCMD)
+
+install-ext-comm: pre-install-ext-comm do-install-ext-comm post-install-ext-comm
+pre-install-ext-comm:: install-prereq
+do-install-ext-comm: exts pre-install-ext-comm
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext-comm
+post-install-ext-comm::
+ @$(NULLCMD)
+
+install-ext-arch: pre-install-ext-arch do-install-ext-arch post-install-ext-arch
+pre-install-ext-arch:: install-prereq
+do-install-ext-arch: exts pre-install-ext-arch
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext-arch
+post-install-ext-arch::
+ @$(NULLCMD)
+
+install-man: pre-install-man do-install-man post-install-man
+pre-install-man:: install-prereq
+do-install-man: $(PREP) pre-install-man
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=man
+post-install-man::
+ @$(NULLCMD)
+
+install-capi: capi pre-install-capi do-install-capi post-install-capi
+pre-install-capi:: install-prereq
+do-install-capi: $(PREP) pre-install-capi
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=capi
+post-install-capi::
+ @$(NULLCMD)
+
+what-where: no-install
+no-install: no-install-$(INSTALLDOC)
+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)"
+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)
+
+reinstall: all uninstall install
+
+what-where-nodoc: no-install-nodoc
+no-install-nodoc: pre-no-install-nodoc dont-install-nodoc post-no-install-nodoc
+pre-no-install-nodoc:: pre-no-install-local pre-no-install-ext
+dont-install-nodoc: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS)
+post-no-install-nodoc:: post-no-install-local post-no-install-ext
+
+what-where-local: no-install-local
+no-install-local: pre-no-install-local dont-install-local post-no-install-local
+pre-no-install-local:: pre-no-install-bin pre-no-install-lib pre-no-install-man
+dont-install-local: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=local
+post-no-install-local:: post-no-install-bin post-no-install-lib post-no-install-man
+
+what-where-ext: no-install-ext
+no-install-ext: pre-no-install-ext dont-install-ext post-no-install-ext
+pre-no-install-ext:: pre-no-install-ext-arch pre-no-install-ext-comm
+dont-install-ext: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext
+post-no-install-ext:: post-no-install-ext-arch post-no-install-ext-comm
+
+what-where-arch: no-install-arch
+no-install-arch: pre-no-install-arch dont-install-arch post-no-install-arch
+pre-no-install-arch:: pre-no-install-bin pre-no-install-ext-arch
+dont-install-arch: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=bin --install=ext-arch
+post-no-install-arch:: post-no-install-lib post-no-install-man post-no-install-ext-arch
+
+what-where-comm: no-install-comm
+no-install-comm: pre-no-install-comm dont-install-comm post-no-install-comm
+pre-no-install-comm:: pre-no-install-lib pre-no-install-ext-comm pre-no-install-man
+dont-install-comm: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=lib --install=ext-comm --install=man
+post-no-install-comm:: post-no-install-lib post-no-install-ext-comm post-no-install-man
+
+what-where-bin: no-install-bin
+no-install-bin: pre-no-install-bin dont-install-bin post-no-install-bin
+pre-no-install-bin:: install-prereq
+dont-install-bin: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=bin
+post-no-install-bin::
+ @$(NULLCMD)
+
+what-where-lib: no-install-lib
+no-install-lib: pre-no-install-lib dont-install-lib post-no-install-lib
+pre-no-install-lib:: install-prereq
+dont-install-lib: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=lib
+post-no-install-lib::
+ @$(NULLCMD)
+
+what-where-ext-comm: no-install-ext-comm
+no-install-ext-comm: pre-no-install-ext-comm dont-install-ext-comm post-no-install-ext-comm
+pre-no-install-ext-comm:: install-prereq
+dont-install-ext-comm: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext-comm
+post-no-install-ext-comm::
+ @$(NULLCMD)
+
+what-where-ext-arch: no-install-ext-arch
+no-install-ext-arch: pre-no-install-ext-arch dont-install-ext-arch post-no-install-ext-arch
+pre-no-install-ext-arch:: install-prereq
+dont-install-ext-arch: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=ext-arch
+post-no-install-ext-arch::
+ @$(NULLCMD)
+
+what-where-man: no-install-man
+no-install-man: pre-no-install-man dont-install-man post-no-install-man
+pre-no-install-man:: install-prereq
+dont-install-man: $(PREP)
+ $(INSTRUBY) -n --make="$(MAKE)" $(INSTRUBY_ARGS) --install=man
+post-no-install-man::
+ @$(NULLCMD)
+
+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)"
+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
+do-install-gem: $(PROGRAM) pre-install-gem
+ $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=gem
+post-install-gem::
+ @$(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)"
+
+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)"
+
+rdoc-coverage: PHONY main
+ @echo Generating RDoc coverage report
+ $(Q) $(XRUBY) "$(srcdir)/bin/rdoc" --root "$(srcdir)" --encoding=UTF-8 --all --quiet -C $(RDOCFLAGS) "$(srcdir)"
+
+RDOCBENCHOUT=/tmp/rdocbench
+
+GCBENCH_ITEM=null
+
+gcbench: PHONY
+ $(Q) $(XRUBY) "$(srcdir)/benchmark/gc/gcbench.rb" $(GCBENCH_ITEM)
+
+gcbench-rdoc: PHONY
+ $(Q) $(XRUBY) "$(srcdir)/benchmark/gc/gcbench.rb" rdoc
+
+nodoc: PHONY
+
+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)"
+post-no-install-doc::
+ @$(NULLCMD)
+
+CLEAR_INSTALLED_LIST = clear-installed-list
+
+install-prereq: $(CLEAR_INSTALLED_LIST) yes-fake sudo-precheck PHONY
+
+clear-installed-list: PHONY
+ @> $(INSTALLED_LIST) set MAKE="$(MAKE)"
+
+clean: clean-ext clean-enc clean-golf clean-docs clean-extout clean-local clean-platform clean-spec
+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
+clean-ext:: PHONY
+clean-golf: PHONY
+ $(Q)$(RM) $(GORUBY)$(EXEEXT) $(GOLFOBJS)
+clean-rdoc: PHONY
+clean-html: PHONY
+clean-capi: PHONY
+clean-platform: PHONY
+clean-extout: PHONY
+ -$(Q)$(RMDIR) $(EXTOUT)/$(arch) $(EXTOUT) 2> $(NULL) || exit 0
+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) config.cache config.status config.status.lineno
+ $(Q)$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)
+ -$(Q)$(RMALL) $(srcdir)/autom4te.cache
+distclean-ext:: PHONY
+distclean-golf: clean-golf
+distclean-rdoc: clean-rdoc
+distclean-html: clean-html
+distclean-capi: clean-capi
+distclean-docs: clean-docs
+distclean-extout: clean-extout
+distclean-platform: clean-platform
+distclean-spec: clean-spec
+distclean-rubyspec: distclean-spec
+
+realclean:: realclean-ext realclean-local realclean-enc realclean-golf realclean-extout
+realclean-local:: distclean-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
+realclean-ext:: PHONY
+realclean-golf: distclean-golf
+ $(Q)$(RM) $(GOLFPRELUDES)
+realclean-rdoc: distclean-rdoc
+realclean-html: distclean-html
+realclean-capi: distclean-capi
+realclean-docs: distclean-docs
+realclean-extout: distclean-extout
+realclean-platform: distclean-platform
+realclean-spec: distclean-spec
+realclean-rubyspec: realclean-spec
+
+clean-ext:: ext/clean gems/clean timestamp/clean
+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
+
+timestamp/clean:: ext/clean gems/clean
+timestamp/distclean:: ext/distclean gems/distclean
+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
+
+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
+
+clean-enc distclean-enc realclean-enc: PHONY
+
+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
+
+clean-rdoc distclean-rdoc realclean-rdoc:
+ @echo $(@:-rdoc=ing) rdoc
+ $(Q)$(RMALL) $(RDOCOUT)
+
+clean-html distclean-html realclean-html:
+ @echo $(@:-html=ing) HTML
+ $(Q)$(RMALL) $(HTMLOUT)
+
+clean-capi distclean-capi realclean-capi:
+ @echo $(@:-capi=ing) capi
+ $(Q)$(RMALL) $(CAPIOUT)
+
+clean-platform:
+ $(Q) $(RM) $(PLATFORM_D)
+ -$(Q) $(RMDIR) $(PLATFORM_DIR) 2> $(NULL) || exit 0
+
+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
+
+check: main test test-testframework test-almost
+ $(ECHO) check succeeded
+check-ruby: test test-ruby
+
+fake: $(CROSS_COMPILING)-fake
+yes-fake: $(arch)-fake.rb $(RBCONFIG) PHONY
+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)
+ $(ECHO) generating $@
+ $(Q) $(CPP) $(warnflags) $(XCFLAGS) $(CPPFLAGS) "$(srcdir)/version.c" | \
+ $(BOOTSTRAPRUBY) "$(srcdir)/tool/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)
+
+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)
+
+test-basic: $(TEST_RUNNABLE)-test-basic
+no-test-basic: PHONY
+yes-test-basic: prog PHONY
+ $(Q)$(exec) $(RUNRUBY) "$(srcdir)/basictest/runner.rb" --run-opt=$(RUN_OPTS) $(OPTS) $(TESTOPTS)
+
+test-knownbugs: test-knownbug
+test-knownbug: $(TEST_RUNNABLE)-test-knownbug
+no-test-knownbug: PHONY
+yes-test-knownbug: prog PHONY
+ -$(exec) $(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(srcdir)/KNOWNBUGS.rb
+
+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
+no-test-testframework: PHONY
+
+test-sample: test-basic # backward compatibility for mswin-build
+test: btest-ruby test-knownbug test-basic
+
+# $ 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)
+TESTS_BUILD = mkmf
+no-test-all: PHONY
+ $(gnumake_recursive)$(MINIRUBY) -I"$(srcdir)/lib" "$(srcdir)/test/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-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-
+
+extconf: $(PREP)
+ $(Q) $(MAKEDIRS) "$(EXTCONFDIR)"
+ $(RUNRUBY) -C "$(EXTCONFDIR)" $(EXTCONF) $(EXTCONFARGS)
+
+$(RBCONFIG): $(srcdir)/tool/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 \
+ -arch=$(arch) -version=$(RUBY_PROGRAM_VERSION) \
+ -install_name=$(RUBY_INSTALL_NAME) \
+ -so_name=$(RUBY_SO_NAME) \
+ -unicode_version=$(UNICODE_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: $(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)
+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)
+yes-runnable: PHONY
+
+encs: enc trans
+libencs: libenc libtrans
+encs enc trans libencs libenc libtrans: $(SHOWFLAGS) $(ENC_MK) $(LIBRUBY) $(PREP) PHONY
+ $(ECHO) making $@
+ $(Q) $(MAKE) $(MAKE_ENC) $@
+
+
+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) $(MINIRUBY) $(srcdir)/enc/make_encmake.rb --builtin-encs="$(BUILTIN_ENCOBJS)" --builtin-transes="$(BUILTIN_TRANSOBJS)" --module$(ENCSTATIC) $(ENCS) $@
+
+.PRECIOUS: $(MKFILES)
+
+.PHONY: PHONY all fake prereq incs srcs preludes help
+.PHONY: test install install-nodoc install-doc dist
+.PHONY: loadpath golf capi rdoc install-prereq clear-installed-list
+.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: 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.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)$(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)$(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 > $@
+
+exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time miniruby$(EXEEXT)
+ $(Q) $(PURIFY) $(CC) $(CFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(LDFLAGS) $(LIBS) $(OUTFLAG)$@ $<
+ $(Q) ./miniruby$(EXEEXT) \
+ -e 'prog, dest = ARGV; dest += "/ruby"' \
+ -e 'unless prog=="ruby"' \
+ -e ' begin File.unlink(dest); rescue Errno::ENOENT; end' \
+ -e ' File.symlink(prog, dest)' \
+ -e 'end' \
+ $(@F) $(@D)
+
+exe/.time:
+ $(Q) $(MAKEDIRS) exe $(@D)
+ @exit > $@
+
+$(BUILTIN_ENCOBJS) $(BUILTIN_TRANSOBJS): $(ENC_TRANS_D)
+
+$(ENC_TRANS_D):
+ $(Q) $(MAKEDIRS) enc/trans $(@D)
+ @exit > $@
+
+$(TIMESTAMPDIR)/$(arch)/.time:
+ $(Q)$(MAKEDIRS) $(@D) $(EXTOUT)/$(arch)
+ @exit > $@
+
+###
+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
+
+###
+
+acosh.$(OBJEXT): {$(VPATH)}acosh.c
+alloca.$(OBJEXT): {$(VPATH)}alloca.c {$(VPATH)}config.h
+crypt.$(OBJEXT): {$(VPATH)}crypt.c {$(VPATH)}crypt.h {$(VPATH)}missing/des_tables.c
+dup2.$(OBJEXT): {$(VPATH)}dup2.c
+erf.$(OBJEXT): {$(VPATH)}erf.c
+explicit_bzero.$(OBJEXT): {$(VPATH)}explicit_bzero.c
+finite.$(OBJEXT): {$(VPATH)}finite.c
+flock.$(OBJEXT): {$(VPATH)}flock.c
+memcmp.$(OBJEXT): {$(VPATH)}memcmp.c
+memmove.$(OBJEXT): {$(VPATH)}memmove.c
+mkdir.$(OBJEXT): {$(VPATH)}mkdir.c
+setproctitle.$(OBJEXT): {$(VPATH)}setproctitle.c
+strchr.$(OBJEXT): {$(VPATH)}strchr.c
+strdup.$(OBJEXT): {$(VPATH)}strdup.c
+strerror.$(OBJEXT): {$(VPATH)}strerror.c
+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 $<
+
+###
+
+# 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) \
+ {$(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
+ $(Q) $(MAKEDIRS) $(@D)
+ $(Q) $(BASERUBY) "$(srcdir)/tool/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
+ $(ECHO) creating $@
+ $(Q) $(BOOTSTRAPRUBY) "$(srcdir)/tool/generic_erb.rb" -o $@ $(srcdir)/template/verconf.h.tmpl
+
+ruby-glommed.$(OBJEXT): $(OBJS)
+
+$(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
+
+common-srcs: {$(VPATH)}parse.c {$(VPATH)}lex.c {$(VPATH)}enc/trans/newline.c {$(VPATH)}id.c \
+ srcs-lib srcs-ext incs
+
+missing-srcs: $(srcdir)/missing/des_tables.c
+
+srcs: common-srcs missing-srcs srcs-enc
+
+EXT_SRCS = $(srcdir)/ext/ripper/ripper.c \
+ $(srcdir)/ext/rbconfig/sizeof/sizes.c \
+ $(srcdir)/ext/rbconfig/sizeof/limits.c \
+ $(srcdir)/ext/socket/constdefs.c \
+ # EXT_SRCS
+
+srcs-ext: $(EXT_SRCS)
+
+srcs-extra: $(srcdir)/ext/json/parser/parser.c \
+ $(srcdir)/ext/date/zonetab.h \
+ $(empty)
+
+LIB_SRCS = $(srcdir)/lib/unicode_normalize/tables.rb
+
+srcs-lib: $(LIB_SRCS)
+
+srcs-enc: $(ENC_MK)
+ $(ECHO) making srcs under enc
+ $(Q) $(MAKE) $(MAKE_ENC) srcs
+
+all-incs: incs {$(VPATH)}encdb.h {$(VPATH)}transdb.h
+incs: $(INSNS) {$(VPATH)}node_name.inc {$(VPATH)}known_errors.inc \
+ {$(VPATH)}vm_call_iseq_optimized.inc $(srcdir)/revision.h \
+ $(REVISION_H) \
+ $(UNICODE_DATA_HEADERS) $(srcdir)/enc/jis/props.h \
+ {$(VPATH)}id.h {$(VPATH)}probes.dmyh
+
+insns: $(INSNS)
+
+id.h: $(srcdir)/tool/generic_erb.rb $(srcdir)/template/id.h.tmpl $(srcdir)/defs/id.def
+ $(ECHO) generating $@
+ $(Q) $(BASERUBY) $(srcdir)/tool/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
+ $(ECHO) generating $@
+ $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb --output=$@ \
+ $(srcdir)/template/id.c.tmpl
+
+node_name.inc: {$(VPATH)}node.h
+ $(ECHO) generating $@
+ $(Q) $(BASERUBY) -n $(srcdir)/tool/node_name.rb < $? > $@
+
+encdb.h: $(PREP) $(srcdir)/tool/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
+
+transdb.h: $(PREP) srcs-enc $(srcdir)/tool/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
+
+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
+
+vm_call_iseq_optimized.inc: $(srcdir)/tool/mk_call_iseq_optimized.rb
+ $(ECHO) generating $@
+ $(Q) $(BASERUBY) $(srcdir)/tool/mk_call_iseq_optimized.rb > $@
+
+$(MINIPRELUDE_C): $(COMPILE_PRELUDE)
+ $(ECHO) generating $@
+ $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -o $@ \
+ $(srcdir)/template/prelude.c.tmpl
+
+$(PRELUDE_C): $(COMPILE_PRELUDE) \
+ $(PRELUDE_SCRIPTS)
+ $(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 $@ \
+ $(srcdir)/template/prelude.c.tmpl golf_prelude.rb
+
+MAINCPPFLAGS = $(ENABLE_DEBUG_ENV:yes=-DRUBY_DEBUG_ENV=1)
+
+$(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
+
+probes.dmyh:
+ $(BASERUBY) $(srcdir)/tool/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)/revision.h:
+ @exit > $@
+
+$(REVISION_H): $(srcdir)/version.h $(srcdir)/tool/file2lastrev.rb $(REVISION_FORCE)
+ -$(Q) $(BASERUBY) $(srcdir)/tool/file2lastrev.rb -q --revision.h "$(srcdir)" > revision.tmp
+ $(Q)$(IFCHANGE) "--timestamp=$@" "$(srcdir)/revision.h" revision.tmp
+
+$(srcdir)/ext/ripper/ripper.c: $(srcdir)/parse.y id.h
+ $(ECHO) generating $@
+ $(Q) VPATH=$${PWD-`pwd`} && $(CHDIR) $(@D) && \
+ sed /AUTOGENERATED/q depend | \
+ $(exec) $(MAKE) -f - $(mflags) \
+ Q=$(Q) ECHO=$(ECHO) RM="$(RM)" top_srcdir=../.. srcdir=. VPATH="$${VPATH}" \
+ RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)"
+
+$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl
+ $(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
+ $(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
+ $(ECHO) generating $@
+ $(Q) $(CHDIR) $(@D) && \
+ sed '/AUTOGENERATED/q' depend | \
+ $(exec) $(MAKE) -f - $(mflags) \
+ 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
+ $(ECHO) generating $@
+ $(Q) $(CHDIR) $(@D) && \
+ sed '/AUTOGENERATED/q' depend | \
+ $(exec) $(MAKE) -f - $(mflags) \
+ Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. RUBY="$(BASERUBY)" $(@F)
+
+$(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/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)
+
+runruby: $(PROGRAM) PHONY
+ $(RUNRUBY) $(TESTRUN_SCRIPT)
+
+parse: fake miniruby$(EXEEXT) PHONY
+ $(BTESTRUBY) --dump=parsetree_with_comment,insns $(TESTRUN_SCRIPT)
+
+bisect: PHONY
+ $(srcdir)/tool/bisect.sh miniruby $(srcdir)
+
+bisect-ruby: PHONY
+ $(srcdir)/tool/bisect.sh ruby $(srcdir)
+
+COMPARE_RUBY = $(BASERUBY)
+ITEM =
+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)
+
+run.gdb:
+ echo set breakpoint pending on > run.gdb
+ echo b ruby_debug_breakpoint >> run.gdb
+ echo '# handle SIGINT nostop' >> run.gdb
+ echo '# handle SIGPIPE nostop' >> run.gdb
+ echo '# b rb_longjmp' >> run.gdb
+ echo source $(srcdir)/breakpoints.gdb >> run.gdb
+ echo source $(srcdir)/.gdbinit >> run.gdb
+ echo 'set $$_exitcode = -999' >> run.gdb
+ echo run >> run.gdb
+ echo 'if $$_exitcode != -999' >> run.gdb
+ echo ' quit' >> run.gdb
+ echo end >> run.gdb
+
+
+gdb: miniruby$(EXEEXT) run.gdb PHONY
+ gdb -x run.gdb --quiet --args $(MINIRUBY) $(TESTRUN_SCRIPT)
+
+gdb-ruby: $(PROGRAM) run.gdb PHONY
+ $(Q) $(RUNRUBY_COMMAND) $(RUNRUBY_DEBUGGER) -- $(TESTRUN_SCRIPT)
+
+LLDB_INIT = command script import -r $(srcdir)/misc/lldb_cruby.py
+
+lldb: miniruby$(EXEEXT) PHONY
+ lldb -o '$(LLDB_INIT)' miniruby$(EXEEXT) -- $(TESTRUN_SCRIPT)
+
+lldb-ruby: $(PROGRAM) PHONY
+ lldb $(enable_shared:yes=-o 'target modules add ${LIBRUBY_SO}') -o '$(LLDB_INIT)' $(PROGRAM) -- $(TESTRUN_SCRIPT)
+
+DISTPKGS = gzip,zip,all
+dist:
+ $(BASERUBY) $(srcdir)/tool/make-snapshot \
+ -srcdir=$(srcdir) -packages=$(DISTPKGS) \
+ -unicode-version=$(UNICODE_VERSION) \
+ tmp $(RELNAME)
+
+up:: update-remote
+
+up::
+ -$(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY "$(REVISION_H)"
+
+up::
+ -$(Q)$(MAKE) $(mflags) Q=$(Q) after-update
+
+after-update:: extract-extlibs
+
+update-remote:: update-src update-download
+update-download:: update-unicode update-gems download-extlibs
+
+update-mspec:
+update-rubyspec:
+
+update-config_files: PHONY
+ $(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool -e gnu \
+ config.guess config.sub
+
+update-gems: PHONY
+ $(ECHO) Downloading bundled gem files...
+ $(Q) $(BASERUBY) -C "$(srcdir)" \
+ -I./tool -rdownloader -answ \
+ -e 'gem, ver = *$$F' \
+ -e 'old = Dir.glob("gems/#{gem}-*.gem")' \
+ -e 'gem = "#{gem}-#{ver}.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")})' \
+ gems/bundled_gems
+
+extract-gems: PHONY
+ $(ECHO) Extracting bundled gem files...
+ $(Q) $(RUNRUBY) -C "$(srcdir)/gems" \
+ -I../tool -rgem-unpack -answ \
+ -e 'gem, ver = *$$F' \
+ -e 'Gem.unpack("#{gem}-#{ver}.gem")' \
+ bundled_gems
+
+update-bundled_gems: PHONY
+ $(Q) $(RUNRUBY) -rrubygems \
+ -pla \
+ -e '$$_=Gem::SpecFetcher.fetcher.detect(:latest) {'"|s|" \
+ -e 'if s.platform=="ruby"&&s.name==$$F[0]' \
+ -e 'break [s.name, s.version, *$$F[2..-1]].join(" ")' \
+ -e 'end' \
+ -e '}' \
+ "$(srcdir)/gems/bundled_gems" | \
+ "$(IFCHANGE)" "$(srcdir)/gems/bundled_gems" -
+
+test-bundled-gems-precheck: $(arch)-fake.rb programs
+
+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
+ $(XRUBY) -C "$(srcdir)" bin/gem install --no-ri --no-rdoc \
+ --install-dir .bundle --conservative "bundler" "minitest:~> 5" 'test-unit' 'rake' 'hoe' 'yard' 'pry' 'packnga'
+
+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:
+test-bundled-gems-run: $(PREPARE_BUNDLED_GEMS)
+
+UNICODE_FILES = $(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
+ $(UNICODE_SRC_DATA_DIR)/CompositionExclusions.txt \
+ $(UNICODE_SRC_DATA_DIR)/NormalizationTest.txt \
+ $(UNICODE_SRC_DATA_DIR)/CaseFolding.txt \
+ $(UNICODE_SRC_DATA_DIR)/SpecialCasing.txt \
+ $(empty)
+
+UNICODE_PROPERTY_FILES = \
+ $(UNICODE_SRC_DATA_DIR)/Blocks.txt \
+ $(UNICODE_SRC_DATA_DIR)/DerivedAge.txt \
+ $(UNICODE_SRC_DATA_DIR)/DerivedCoreProperties.txt \
+ $(UNICODE_SRC_DATA_DIR)/PropList.txt \
+ $(UNICODE_SRC_DATA_DIR)/PropertyAliases.txt \
+ $(UNICODE_SRC_DATA_DIR)/PropertyValueAliases.txt \
+ $(UNICODE_SRC_DATA_DIR)/Scripts.txt \
+ $(UNICODE_SRC_DATA_DIR)/auxiliary/GraphemeBreakProperty.txt \
+ $(empty)
+
+UNICODE_EMOJI_FILES = \
+ $(UNICODE_SRC_EMOJI_DATA_DIR)/emoji-data.txt \
+ $(empty)
+
+update-unicode: $(UNICODE_FILES)
+
+CACHE_DIR = $(srcdir)/.downloaded-cache
+UNICODE_DOWNLOAD = \
+ $(BASERUBY) $(srcdir)/tool/downloader.rb \
+ --cache-dir=$(CACHE_DIR) \
+ -d $(UNICODE_SRC_DATA_DIR) \
+ -p $(UNICODE_VERSION)/ucd \
+ -e $(ALWAYS_UPDATE_UNICODE:yes=-a) unicode
+UNICODE_EMOJI_DOWNLOAD = \
+ $(BASERUBY) $(srcdir)/tool/downloader.rb \
+ --cache-dir=$(CACHE_DIR) \
+ -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)
+ $(ECHO) Downloading Unicode emoji $(UNICODE_EMOJI_VERSION) files...
+ $(Q) $(MAKEDIRS) "$(UNICODE_SRC_EMOJI_DATA_DIR)"
+ $(Q) $(UNICODE_EMOJI_DOWNLOAD) $(UNICODE_EMOJI_FILES)
+
+$(UNICODE_FILES): update-unicode-files
+update-unicode-files:
+ $(ECHO) Downloading Unicode $(UNICODE_VERSION) data files...
+ $(Q) $(MAKEDIRS) "$(UNICODE_SRC_DATA_DIR)"
+ $(Q) $(UNICODE_DOWNLOAD) $(UNICODE_FILES)
+
+$(srcdir)/$(HAVE_BASERUBY:yes=lib/unicode_normalize/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)
+
+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 \
+ $(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 \
+ -I $(srcdir) \
+ $(srcdir)/template/unicode_norm_gen.tmpl \
+ $(UNICODE_DATA_DIR) lib/unicode_normalize
+
+$(UNICODE_SRC_DATA_DIR):
+ $(Q) $(exec) $(MAKEDIRS) $@ || exit && echo $(MAKE)
+
+$(UNICODE_HDR_DIR)/$(ALWAYS_UPDATE_UNICODE:yes=name2ctype.h): \
+ $(srcdir)/tool/enc-unicode.rb \
+ $(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
+ $(UNICODE_PROPERTY_FILES)
+
+$(UNICODE_HDR_DIR)/name2ctype.h:
+ $(MAKEDIRS) $(@D)
+ $(BOOTSTRAPRUBY) $(srcdir)/tool/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 \
+# but was changed to make sure CI works on systems that don't have gperf
+unicode-up: $(UNICODE_DATA_HEADERS)
+
+$(UNICODE_HDR_DIR)/$(ALWAYS_UPDATE_UNICODE:yes=casefold.h): \
+ $(srcdir)/enc/unicode/case-folding.rb \
+ $(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
+ $(UNICODE_SRC_DATA_DIR)/SpecialCasing.txt \
+ $(UNICODE_SRC_DATA_DIR)/CaseFolding.txt
+
+$(UNICODE_HDR_DIR)/casefold.h:
+ $(MAKEDIRS) $(@D)
+ $(Q) $(BASERUBY) $(srcdir)/enc/unicode/case-folding.rb \
+ --output-file=$@ \
+ --mapping-data-directory=$(UNICODE_SRC_DATA_DIR)
+
+download-extlibs:
+ $(Q) $(BASERUBY) -C $(srcdir) -w tool/extlibs.rb --download ext
+
+extract-extlibs:
+ $(Q) $(BASERUBY) -C $(srcdir) -w tool/extlibs.rb --all ext
+
+clean-extlibs:
+ $(Q) $(RMALL) $(srcdir)/.downloaded-cache
+
+clean-gems:
+ $(Q) $(RM) gems/*.gem
+
+CLEAN_CACHE = clean-extlibs
+
+info: info-program info-libruby_a info-libruby_so info-arch
+info-program: PHONY
+ @echo PROGRAM=$(PROGRAM)
+info-libruby_a: PHONY
+ @echo LIBRUBY_A=$(LIBRUBY_A)
+info-libruby_so: PHONY
+ @echo LIBRUBY_SO=$(LIBRUBY_SO)
+info-arch: PHONY
+ @echo arch=$(arch)
+
+change: PHONY
+ $(BASERUBY) -C "$(srcdir)" ./tool/change_maker.rb $(CHANGES) > change.log
+
+exam: check test-spec
+
+love: sudo-precheck up all test exam install
+ @echo love is all you need
+
+great: exam
+
+yes-test-all no-test-all: sudo-precheck
+
+sudo-precheck: PHONY
+ @$(SUDO) echo > $(NULL)
+
+update-man-date: PHONY
+ -$(Q) $(BASERUBY) -I"$(srcdir)/tool" -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
+
+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" \
+ " 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-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" \
+ " test-bundled-gems: run the test suite of bundled gems" \
+ " 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" \
+ "" \
+ "see DeveloperHowto for more detail: " \
+ " https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto" \
+ $(MESSAGE_END)
+
+# AUTOGENERATED DEPENDENCIES START
+addr2line.$(OBJEXT): {$(VPATH)}addr2line.c
+addr2line.$(OBJEXT): {$(VPATH)}addr2line.h
+addr2line.$(OBJEXT): {$(VPATH)}config.h
+addr2line.$(OBJEXT): {$(VPATH)}missing.h
+array.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+array.$(OBJEXT): $(top_srcdir)/include/ruby.h
+array.$(OBJEXT): {$(VPATH)}array.c
+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)}intern.h
+array.$(OBJEXT): {$(VPATH)}internal.h
+array.$(OBJEXT): {$(VPATH)}io.h
+array.$(OBJEXT): {$(VPATH)}missing.h
+array.$(OBJEXT): {$(VPATH)}onigmo.h
+array.$(OBJEXT): {$(VPATH)}oniguruma.h
+array.$(OBJEXT): {$(VPATH)}probes.dmyh
+array.$(OBJEXT): {$(VPATH)}probes.h
+array.$(OBJEXT): {$(VPATH)}ruby_assert.h
+array.$(OBJEXT): {$(VPATH)}st.h
+array.$(OBJEXT): {$(VPATH)}subst.h
+array.$(OBJEXT): {$(VPATH)}util.h
+bignum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+bignum.$(OBJEXT): $(top_srcdir)/include/ruby.h
+bignum.$(OBJEXT): {$(VPATH)}bignum.c
+bignum.$(OBJEXT): {$(VPATH)}config.h
+bignum.$(OBJEXT): {$(VPATH)}defines.h
+bignum.$(OBJEXT): {$(VPATH)}encoding.h
+bignum.$(OBJEXT): {$(VPATH)}id.h
+bignum.$(OBJEXT): {$(VPATH)}intern.h
+bignum.$(OBJEXT): {$(VPATH)}internal.h
+bignum.$(OBJEXT): {$(VPATH)}io.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
+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/ruby.h
+class.$(OBJEXT): $(top_srcdir)/include/ruby.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)}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)}method.h
+class.$(OBJEXT): {$(VPATH)}missing.h
+class.$(OBJEXT): {$(VPATH)}node.h
+class.$(OBJEXT): {$(VPATH)}onigmo.h
+class.$(OBJEXT): {$(VPATH)}oniguruma.h
+class.$(OBJEXT): {$(VPATH)}ruby_assert.h
+class.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+class.$(OBJEXT): {$(VPATH)}st.h
+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/ruby.h
+compar.$(OBJEXT): {$(VPATH)}compar.c
+compar.$(OBJEXT): {$(VPATH)}config.h
+compar.$(OBJEXT): {$(VPATH)}defines.h
+compar.$(OBJEXT): {$(VPATH)}id.h
+compar.$(OBJEXT): {$(VPATH)}intern.h
+compar.$(OBJEXT): {$(VPATH)}missing.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/ruby.h
+compile.$(OBJEXT): $(hdrdir)/ruby/version.h
+compile.$(OBJEXT): $(top_srcdir)/include/ruby.h
+compile.$(OBJEXT): {$(VPATH)}compile.c
+compile.$(OBJEXT): {$(VPATH)}config.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.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)}iseq.h
+compile.$(OBJEXT): {$(VPATH)}method.h
+compile.$(OBJEXT): {$(VPATH)}missing.h
+compile.$(OBJEXT): {$(VPATH)}node.h
+compile.$(OBJEXT): {$(VPATH)}onigmo.h
+compile.$(OBJEXT): {$(VPATH)}oniguruma.h
+compile.$(OBJEXT): {$(VPATH)}opt_sc.inc
+compile.$(OBJEXT): {$(VPATH)}optinsn.inc
+compile.$(OBJEXT): {$(VPATH)}optunifs.inc
+compile.$(OBJEXT): {$(VPATH)}re.h
+compile.$(OBJEXT): {$(VPATH)}regex.h
+compile.$(OBJEXT): {$(VPATH)}ruby_assert.h
+compile.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+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)}vm_core.h
+compile.$(OBJEXT): {$(VPATH)}vm_debug.h
+compile.$(OBJEXT): {$(VPATH)}vm_opts.h
+complex.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+complex.$(OBJEXT): $(top_srcdir)/include/ruby.h
+complex.$(OBJEXT): {$(VPATH)}complex.c
+complex.$(OBJEXT): {$(VPATH)}config.h
+complex.$(OBJEXT): {$(VPATH)}defines.h
+complex.$(OBJEXT): {$(VPATH)}encoding.h
+complex.$(OBJEXT): {$(VPATH)}intern.h
+complex.$(OBJEXT): {$(VPATH)}internal.h
+complex.$(OBJEXT): {$(VPATH)}io.h
+complex.$(OBJEXT): {$(VPATH)}missing.h
+complex.$(OBJEXT): {$(VPATH)}onigmo.h
+complex.$(OBJEXT): {$(VPATH)}oniguruma.h
+complex.$(OBJEXT): {$(VPATH)}ruby_assert.h
+complex.$(OBJEXT): {$(VPATH)}st.h
+complex.$(OBJEXT): {$(VPATH)}subst.h
+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/ruby.h
+cont.$(OBJEXT): $(top_srcdir)/include/ruby.h
+cont.$(OBJEXT): {$(VPATH)}config.h
+cont.$(OBJEXT): {$(VPATH)}cont.c
+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)}intern.h
+cont.$(OBJEXT): {$(VPATH)}internal.h
+cont.$(OBJEXT): {$(VPATH)}io.h
+cont.$(OBJEXT): {$(VPATH)}method.h
+cont.$(OBJEXT): {$(VPATH)}missing.h
+cont.$(OBJEXT): {$(VPATH)}node.h
+cont.$(OBJEXT): {$(VPATH)}onigmo.h
+cont.$(OBJEXT): {$(VPATH)}oniguruma.h
+cont.$(OBJEXT): {$(VPATH)}ruby_assert.h
+cont.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+cont.$(OBJEXT): {$(VPATH)}st.h
+cont.$(OBJEXT): {$(VPATH)}subst.h
+cont.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+cont.$(OBJEXT): {$(VPATH)}thread_native.h
+cont.$(OBJEXT): {$(VPATH)}vm_core.h
+cont.$(OBJEXT): {$(VPATH)}vm_debug.h
+cont.$(OBJEXT): {$(VPATH)}vm_opts.h
+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/ruby.h
+debug.$(OBJEXT): $(top_srcdir)/include/ruby.h
+debug.$(OBJEXT): {$(VPATH)}config.h
+debug.$(OBJEXT): {$(VPATH)}debug.c
+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)}intern.h
+debug.$(OBJEXT): {$(VPATH)}internal.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)}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_core.h
+debug.$(OBJEXT): {$(VPATH)}vm_debug.h
+debug.$(OBJEXT): {$(VPATH)}vm_opts.h
+debug_counter.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+debug_counter.$(OBJEXT): $(top_srcdir)/include/ruby.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)}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
+dir.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+dir.$(OBJEXT): $(top_srcdir)/include/ruby.h
+dir.$(OBJEXT): {$(VPATH)}config.h
+dir.$(OBJEXT): {$(VPATH)}defines.h
+dir.$(OBJEXT): {$(VPATH)}dir.c
+dir.$(OBJEXT): {$(VPATH)}encindex.h
+dir.$(OBJEXT): {$(VPATH)}encoding.h
+dir.$(OBJEXT): {$(VPATH)}intern.h
+dir.$(OBJEXT): {$(VPATH)}internal.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)}util.h
+dln.$(OBJEXT): $(hdrdir)/ruby/ruby.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)}missing.h
+dln.$(OBJEXT): {$(VPATH)}st.h
+dln.$(OBJEXT): {$(VPATH)}subst.h
+dln_find.$(OBJEXT): $(hdrdir)/ruby/ruby.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)}missing.h
+dln_find.$(OBJEXT): {$(VPATH)}st.h
+dln_find.$(OBJEXT): {$(VPATH)}subst.h
+dmydln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+dmydln.$(OBJEXT): {$(VPATH)}config.h
+dmydln.$(OBJEXT): {$(VPATH)}defines.h
+dmydln.$(OBJEXT): {$(VPATH)}dmydln.c
+dmydln.$(OBJEXT): {$(VPATH)}intern.h
+dmydln.$(OBJEXT): {$(VPATH)}missing.h
+dmydln.$(OBJEXT): {$(VPATH)}st.h
+dmydln.$(OBJEXT): {$(VPATH)}subst.h
+dmyenc.$(OBJEXT): {$(VPATH)}dmyenc.c
+dmyext.$(OBJEXT): {$(VPATH)}dmyext.c
+enc/ascii.$(OBJEXT): {$(VPATH)}config.h
+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
+enc/trans/newline.$(OBJEXT): {$(VPATH)}defines.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}enc/trans/newline.c
+enc/trans/newline.$(OBJEXT): {$(VPATH)}intern.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}missing.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}st.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}subst.h
+enc/trans/newline.$(OBJEXT): {$(VPATH)}transcode_data.h
+enc/unicode.$(OBJEXT): $(UNICODE_HDR_DIR)/casefold.h
+enc/unicode.$(OBJEXT): $(UNICODE_HDR_DIR)/name2ctype.h
+enc/unicode.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+enc/unicode.$(OBJEXT): {$(VPATH)}config.h
+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)}regenc.h
+enc/unicode.$(OBJEXT): {$(VPATH)}regint.h
+enc/unicode.$(OBJEXT): {$(VPATH)}st.h
+enc/unicode.$(OBJEXT): {$(VPATH)}subst.h
+enc/us_ascii.$(OBJEXT): {$(VPATH)}config.h
+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/ruby.h
+encoding.$(OBJEXT): $(top_srcdir)/include/ruby.h
+encoding.$(OBJEXT): {$(VPATH)}config.h
+encoding.$(OBJEXT): {$(VPATH)}defines.h
+encoding.$(OBJEXT): {$(VPATH)}encindex.h
+encoding.$(OBJEXT): {$(VPATH)}encoding.c
+encoding.$(OBJEXT): {$(VPATH)}encoding.h
+encoding.$(OBJEXT): {$(VPATH)}intern.h
+encoding.$(OBJEXT): {$(VPATH)}internal.h
+encoding.$(OBJEXT): {$(VPATH)}io.h
+encoding.$(OBJEXT): {$(VPATH)}missing.h
+encoding.$(OBJEXT): {$(VPATH)}onigmo.h
+encoding.$(OBJEXT): {$(VPATH)}oniguruma.h
+encoding.$(OBJEXT): {$(VPATH)}regenc.h
+encoding.$(OBJEXT): {$(VPATH)}ruby_assert.h
+encoding.$(OBJEXT): {$(VPATH)}st.h
+encoding.$(OBJEXT): {$(VPATH)}subst.h
+encoding.$(OBJEXT): {$(VPATH)}util.h
+enum.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+enum.$(OBJEXT): $(top_srcdir)/include/ruby.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)}intern.h
+enum.$(OBJEXT): {$(VPATH)}internal.h
+enum.$(OBJEXT): {$(VPATH)}io.h
+enum.$(OBJEXT): {$(VPATH)}missing.h
+enum.$(OBJEXT): {$(VPATH)}onigmo.h
+enum.$(OBJEXT): {$(VPATH)}oniguruma.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/ruby.h
+enumerator.$(OBJEXT): $(top_srcdir)/include/ruby.h
+enumerator.$(OBJEXT): {$(VPATH)}config.h
+enumerator.$(OBJEXT): {$(VPATH)}defines.h
+enumerator.$(OBJEXT): {$(VPATH)}encoding.h
+enumerator.$(OBJEXT): {$(VPATH)}enumerator.c
+enumerator.$(OBJEXT): {$(VPATH)}intern.h
+enumerator.$(OBJEXT): {$(VPATH)}internal.h
+enumerator.$(OBJEXT): {$(VPATH)}io.h
+enumerator.$(OBJEXT): {$(VPATH)}missing.h
+enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
+enumerator.$(OBJEXT): {$(VPATH)}oniguruma.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/ruby.h
+error.$(OBJEXT): $(top_srcdir)/include/ruby.h
+error.$(OBJEXT): {$(VPATH)}config.h
+error.$(OBJEXT): {$(VPATH)}defines.h
+error.$(OBJEXT): {$(VPATH)}encoding.h
+error.$(OBJEXT): {$(VPATH)}error.c
+error.$(OBJEXT): {$(VPATH)}id.h
+error.$(OBJEXT): {$(VPATH)}intern.h
+error.$(OBJEXT): {$(VPATH)}internal.h
+error.$(OBJEXT): {$(VPATH)}io.h
+error.$(OBJEXT): {$(VPATH)}known_errors.inc
+error.$(OBJEXT): {$(VPATH)}method.h
+error.$(OBJEXT): {$(VPATH)}missing.h
+error.$(OBJEXT): {$(VPATH)}node.h
+error.$(OBJEXT): {$(VPATH)}onigmo.h
+error.$(OBJEXT): {$(VPATH)}oniguruma.h
+error.$(OBJEXT): {$(VPATH)}ruby_assert.h
+error.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+error.$(OBJEXT): {$(VPATH)}st.h
+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
+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/ruby.h
+eval.$(OBJEXT): $(hdrdir)/ruby/version.h
+eval.$(OBJEXT): $(top_srcdir)/include/ruby.h
+eval.$(OBJEXT): {$(VPATH)}config.h
+eval.$(OBJEXT): {$(VPATH)}defines.h
+eval.$(OBJEXT): {$(VPATH)}encoding.h
+eval.$(OBJEXT): {$(VPATH)}eval.c
+eval.$(OBJEXT): {$(VPATH)}eval_error.c
+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)}intern.h
+eval.$(OBJEXT): {$(VPATH)}internal.h
+eval.$(OBJEXT): {$(VPATH)}io.h
+eval.$(OBJEXT): {$(VPATH)}iseq.h
+eval.$(OBJEXT): {$(VPATH)}method.h
+eval.$(OBJEXT): {$(VPATH)}missing.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)}ruby_assert.h
+eval.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+eval.$(OBJEXT): {$(VPATH)}st.h
+eval.$(OBJEXT): {$(VPATH)}subst.h
+eval.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+eval.$(OBJEXT): {$(VPATH)}thread_native.h
+eval.$(OBJEXT): {$(VPATH)}vm.h
+eval.$(OBJEXT): {$(VPATH)}vm_core.h
+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)}missing.h
+file.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+file.$(OBJEXT): $(top_srcdir)/include/ruby.h
+file.$(OBJEXT): {$(VPATH)}config.h
+file.$(OBJEXT): {$(VPATH)}defines.h
+file.$(OBJEXT): {$(VPATH)}dln.h
+file.$(OBJEXT): {$(VPATH)}encindex.h
+file.$(OBJEXT): {$(VPATH)}encoding.h
+file.$(OBJEXT): {$(VPATH)}file.c
+file.$(OBJEXT): {$(VPATH)}id.h
+file.$(OBJEXT): {$(VPATH)}intern.h
+file.$(OBJEXT): {$(VPATH)}internal.h
+file.$(OBJEXT): {$(VPATH)}io.h
+file.$(OBJEXT): {$(VPATH)}missing.h
+file.$(OBJEXT): {$(VPATH)}onigmo.h
+file.$(OBJEXT): {$(VPATH)}oniguruma.h
+file.$(OBJEXT): {$(VPATH)}st.h
+file.$(OBJEXT): {$(VPATH)}subst.h
+file.$(OBJEXT): {$(VPATH)}thread.h
+file.$(OBJEXT): {$(VPATH)}util.h
+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/ruby.h
+gc.$(OBJEXT): $(top_srcdir)/include/ruby.h
+gc.$(OBJEXT): {$(VPATH)}config.h
+gc.$(OBJEXT): {$(VPATH)}constant.h
+gc.$(OBJEXT): {$(VPATH)}debug.h
+gc.$(OBJEXT): {$(VPATH)}debug_counter.h
+gc.$(OBJEXT): {$(VPATH)}defines.h
+gc.$(OBJEXT): {$(VPATH)}encoding.h
+gc.$(OBJEXT): {$(VPATH)}eval_intern.h
+gc.$(OBJEXT): {$(VPATH)}gc.c
+gc.$(OBJEXT): {$(VPATH)}gc.h
+gc.$(OBJEXT): {$(VPATH)}id.h
+gc.$(OBJEXT): {$(VPATH)}id_table.h
+gc.$(OBJEXT): {$(VPATH)}intern.h
+gc.$(OBJEXT): {$(VPATH)}internal.h
+gc.$(OBJEXT): {$(VPATH)}io.h
+gc.$(OBJEXT): {$(VPATH)}method.h
+gc.$(OBJEXT): {$(VPATH)}missing.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)}re.h
+gc.$(OBJEXT): {$(VPATH)}regenc.h
+gc.$(OBJEXT): {$(VPATH)}regex.h
+gc.$(OBJEXT): {$(VPATH)}regint.h
+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)}thread.h
+gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+gc.$(OBJEXT): {$(VPATH)}thread_native.h
+gc.$(OBJEXT): {$(VPATH)}util.h
+gc.$(OBJEXT): {$(VPATH)}vm_core.h
+gc.$(OBJEXT): {$(VPATH)}vm_debug.h
+gc.$(OBJEXT): {$(VPATH)}vm_opts.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/ruby.h
+golf_prelude.$(OBJEXT): $(hdrdir)/ruby/version.h
+golf_prelude.$(OBJEXT): $(top_srcdir)/include/ruby.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)}id.h
+golf_prelude.$(OBJEXT): {$(VPATH)}intern.h
+golf_prelude.$(OBJEXT): {$(VPATH)}internal.h
+golf_prelude.$(OBJEXT): {$(VPATH)}io.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
+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/ruby.h
+goruby.$(OBJEXT): $(top_srcdir)/include/ruby.h
+goruby.$(OBJEXT): {$(VPATH)}backward.h
+goruby.$(OBJEXT): {$(VPATH)}config.h
+goruby.$(OBJEXT): {$(VPATH)}defines.h
+goruby.$(OBJEXT): {$(VPATH)}goruby.c
+goruby.$(OBJEXT): {$(VPATH)}intern.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/ruby.h
+hash.$(OBJEXT): $(top_srcdir)/include/ruby.h
+hash.$(OBJEXT): {$(VPATH)}config.h
+hash.$(OBJEXT): {$(VPATH)}defines.h
+hash.$(OBJEXT): {$(VPATH)}encoding.h
+hash.$(OBJEXT): {$(VPATH)}hash.c
+hash.$(OBJEXT): {$(VPATH)}id.h
+hash.$(OBJEXT): {$(VPATH)}intern.h
+hash.$(OBJEXT): {$(VPATH)}internal.h
+hash.$(OBJEXT): {$(VPATH)}io.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)}st.h
+hash.$(OBJEXT): {$(VPATH)}subst.h
+hash.$(OBJEXT): {$(VPATH)}symbol.h
+hash.$(OBJEXT): {$(VPATH)}util.h
+inits.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+inits.$(OBJEXT): $(top_srcdir)/include/ruby.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)}missing.h
+inits.$(OBJEXT): {$(VPATH)}onigmo.h
+inits.$(OBJEXT): {$(VPATH)}oniguruma.h
+inits.$(OBJEXT): {$(VPATH)}st.h
+inits.$(OBJEXT): {$(VPATH)}subst.h
+io.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+io.$(OBJEXT): $(top_srcdir)/include/ruby.h
+io.$(OBJEXT): {$(VPATH)}config.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)}intern.h
+io.$(OBJEXT): {$(VPATH)}internal.h
+io.$(OBJEXT): {$(VPATH)}io.c
+io.$(OBJEXT): {$(VPATH)}io.h
+io.$(OBJEXT): {$(VPATH)}missing.h
+io.$(OBJEXT): {$(VPATH)}onigmo.h
+io.$(OBJEXT): {$(VPATH)}oniguruma.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)}util.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/ruby.h
+iseq.$(OBJEXT): $(hdrdir)/ruby/version.h
+iseq.$(OBJEXT): $(top_srcdir)/include/ruby.h
+iseq.$(OBJEXT): {$(VPATH)}config.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.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)}iseq.c
+iseq.$(OBJEXT): {$(VPATH)}iseq.h
+iseq.$(OBJEXT): {$(VPATH)}method.h
+iseq.$(OBJEXT): {$(VPATH)}missing.h
+iseq.$(OBJEXT): {$(VPATH)}node.h
+iseq.$(OBJEXT): {$(VPATH)}node_name.inc
+iseq.$(OBJEXT): {$(VPATH)}onigmo.h
+iseq.$(OBJEXT): {$(VPATH)}oniguruma.h
+iseq.$(OBJEXT): {$(VPATH)}ruby_assert.h
+iseq.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+iseq.$(OBJEXT): {$(VPATH)}st.h
+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_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/ruby.h
+load.$(OBJEXT): $(top_srcdir)/include/ruby.h
+load.$(OBJEXT): {$(VPATH)}config.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)}intern.h
+load.$(OBJEXT): {$(VPATH)}internal.h
+load.$(OBJEXT): {$(VPATH)}io.h
+load.$(OBJEXT): {$(VPATH)}load.c
+load.$(OBJEXT): {$(VPATH)}method.h
+load.$(OBJEXT): {$(VPATH)}missing.h
+load.$(OBJEXT): {$(VPATH)}node.h
+load.$(OBJEXT): {$(VPATH)}onigmo.h
+load.$(OBJEXT): {$(VPATH)}oniguruma.h
+load.$(OBJEXT): {$(VPATH)}probes.dmyh
+load.$(OBJEXT): {$(VPATH)}probes.h
+load.$(OBJEXT): {$(VPATH)}ruby_assert.h
+load.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+load.$(OBJEXT): {$(VPATH)}st.h
+load.$(OBJEXT): {$(VPATH)}subst.h
+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)}config.h
+loadpath.$(OBJEXT): {$(VPATH)}defines.h
+loadpath.$(OBJEXT): {$(VPATH)}intern.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/ruby.h
+localeinit.$(OBJEXT): $(top_srcdir)/include/ruby.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)}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/ruby.h
+main.$(OBJEXT): $(top_srcdir)/include/ruby.h
+main.$(OBJEXT): {$(VPATH)}backward.h
+main.$(OBJEXT): {$(VPATH)}config.h
+main.$(OBJEXT): {$(VPATH)}defines.h
+main.$(OBJEXT): {$(VPATH)}intern.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/ruby.h
+marshal.$(OBJEXT): $(top_srcdir)/include/ruby.h
+marshal.$(OBJEXT): {$(VPATH)}config.h
+marshal.$(OBJEXT): {$(VPATH)}defines.h
+marshal.$(OBJEXT): {$(VPATH)}encindex.h
+marshal.$(OBJEXT): {$(VPATH)}encoding.h
+marshal.$(OBJEXT): {$(VPATH)}id_table.h
+marshal.$(OBJEXT): {$(VPATH)}intern.h
+marshal.$(OBJEXT): {$(VPATH)}internal.h
+marshal.$(OBJEXT): {$(VPATH)}io.h
+marshal.$(OBJEXT): {$(VPATH)}marshal.c
+marshal.$(OBJEXT): {$(VPATH)}missing.h
+marshal.$(OBJEXT): {$(VPATH)}onigmo.h
+marshal.$(OBJEXT): {$(VPATH)}oniguruma.h
+marshal.$(OBJEXT): {$(VPATH)}st.h
+marshal.$(OBJEXT): {$(VPATH)}subst.h
+marshal.$(OBJEXT): {$(VPATH)}util.h
+math.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+math.$(OBJEXT): $(top_srcdir)/include/ruby.h
+math.$(OBJEXT): {$(VPATH)}config.h
+math.$(OBJEXT): {$(VPATH)}defines.h
+math.$(OBJEXT): {$(VPATH)}encoding.h
+math.$(OBJEXT): {$(VPATH)}intern.h
+math.$(OBJEXT): {$(VPATH)}internal.h
+math.$(OBJEXT): {$(VPATH)}io.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
+miniinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+miniinit.$(OBJEXT): {$(VPATH)}config.h
+miniinit.$(OBJEXT): {$(VPATH)}defines.h
+miniinit.$(OBJEXT): {$(VPATH)}encoding.h
+miniinit.$(OBJEXT): {$(VPATH)}intern.h
+miniinit.$(OBJEXT): {$(VPATH)}miniinit.c
+miniinit.$(OBJEXT): {$(VPATH)}missing.h
+miniinit.$(OBJEXT): {$(VPATH)}onigmo.h
+miniinit.$(OBJEXT): {$(VPATH)}oniguruma.h
+miniinit.$(OBJEXT): {$(VPATH)}st.h
+miniinit.$(OBJEXT): {$(VPATH)}subst.h
+miniprelude.$(OBJEXT): $(hdrdir)/ruby/version.h
+miniprelude.$(OBJEXT): {$(VPATH)}iseq.h
+miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c
+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/ruby.h
+node.$(OBJEXT): $(top_srcdir)/include/ruby.h
+node.$(OBJEXT): {$(VPATH)}config.h
+node.$(OBJEXT): {$(VPATH)}defines.h
+node.$(OBJEXT): {$(VPATH)}encoding.h
+node.$(OBJEXT): {$(VPATH)}id.h
+node.$(OBJEXT): {$(VPATH)}intern.h
+node.$(OBJEXT): {$(VPATH)}internal.h
+node.$(OBJEXT): {$(VPATH)}io.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
+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/ruby.h
+numeric.$(OBJEXT): $(top_srcdir)/include/ruby.h
+numeric.$(OBJEXT): {$(VPATH)}config.h
+numeric.$(OBJEXT): {$(VPATH)}defines.h
+numeric.$(OBJEXT): {$(VPATH)}encoding.h
+numeric.$(OBJEXT): {$(VPATH)}id.h
+numeric.$(OBJEXT): {$(VPATH)}intern.h
+numeric.$(OBJEXT): {$(VPATH)}internal.h
+numeric.$(OBJEXT): {$(VPATH)}io.h
+numeric.$(OBJEXT): {$(VPATH)}missing.h
+numeric.$(OBJEXT): {$(VPATH)}numeric.c
+numeric.$(OBJEXT): {$(VPATH)}onigmo.h
+numeric.$(OBJEXT): {$(VPATH)}oniguruma.h
+numeric.$(OBJEXT): {$(VPATH)}st.h
+numeric.$(OBJEXT): {$(VPATH)}subst.h
+numeric.$(OBJEXT): {$(VPATH)}util.h
+object.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+object.$(OBJEXT): $(top_srcdir)/include/ruby.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)}intern.h
+object.$(OBJEXT): {$(VPATH)}internal.h
+object.$(OBJEXT): {$(VPATH)}io.h
+object.$(OBJEXT): {$(VPATH)}missing.h
+object.$(OBJEXT): {$(VPATH)}object.c
+object.$(OBJEXT): {$(VPATH)}onigmo.h
+object.$(OBJEXT): {$(VPATH)}oniguruma.h
+object.$(OBJEXT): {$(VPATH)}probes.dmyh
+object.$(OBJEXT): {$(VPATH)}probes.h
+object.$(OBJEXT): {$(VPATH)}st.h
+object.$(OBJEXT): {$(VPATH)}subst.h
+object.$(OBJEXT): {$(VPATH)}util.h
+pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+pack.$(OBJEXT): $(top_srcdir)/include/ruby.h
+pack.$(OBJEXT): {$(VPATH)}config.h
+pack.$(OBJEXT): {$(VPATH)}defines.h
+pack.$(OBJEXT): {$(VPATH)}encoding.h
+pack.$(OBJEXT): {$(VPATH)}intern.h
+pack.$(OBJEXT): {$(VPATH)}internal.h
+pack.$(OBJEXT): {$(VPATH)}io.h
+pack.$(OBJEXT): {$(VPATH)}missing.h
+pack.$(OBJEXT): {$(VPATH)}onigmo.h
+pack.$(OBJEXT): {$(VPATH)}oniguruma.h
+pack.$(OBJEXT): {$(VPATH)}pack.c
+pack.$(OBJEXT): {$(VPATH)}st.h
+pack.$(OBJEXT): {$(VPATH)}subst.h
+parse.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+parse.$(OBJEXT): $(top_srcdir)/include/ruby.h
+parse.$(OBJEXT): {$(VPATH)}config.h
+parse.$(OBJEXT): {$(VPATH)}defines.h
+parse.$(OBJEXT): {$(VPATH)}defs/keywords
+parse.$(OBJEXT): {$(VPATH)}encoding.h
+parse.$(OBJEXT): {$(VPATH)}id.h
+parse.$(OBJEXT): {$(VPATH)}intern.h
+parse.$(OBJEXT): {$(VPATH)}internal.h
+parse.$(OBJEXT): {$(VPATH)}io.h
+parse.$(OBJEXT): {$(VPATH)}lex.c
+parse.$(OBJEXT): {$(VPATH)}missing.h
+parse.$(OBJEXT): {$(VPATH)}node.h
+parse.$(OBJEXT): {$(VPATH)}onigmo.h
+parse.$(OBJEXT): {$(VPATH)}oniguruma.h
+parse.$(OBJEXT): {$(VPATH)}parse.c
+parse.$(OBJEXT): {$(VPATH)}parse.h
+parse.$(OBJEXT): {$(VPATH)}parse.y
+parse.$(OBJEXT): {$(VPATH)}probes.dmyh
+parse.$(OBJEXT): {$(VPATH)}probes.h
+parse.$(OBJEXT): {$(VPATH)}regenc.h
+parse.$(OBJEXT): {$(VPATH)}regex.h
+parse.$(OBJEXT): {$(VPATH)}st.h
+parse.$(OBJEXT): {$(VPATH)}subst.h
+parse.$(OBJEXT): {$(VPATH)}symbol.h
+parse.$(OBJEXT): {$(VPATH)}util.h
+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/ruby.h
+prelude.$(OBJEXT): $(hdrdir)/ruby/version.h
+prelude.$(OBJEXT): $(top_srcdir)/include/ruby.h
+prelude.$(OBJEXT): {$(VPATH)}config.h
+prelude.$(OBJEXT): {$(VPATH)}defines.h
+prelude.$(OBJEXT): {$(VPATH)}encoding.h
+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
+prelude.$(OBJEXT): {$(VPATH)}st.h
+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/ruby.h
+proc.$(OBJEXT): $(hdrdir)/ruby/version.h
+proc.$(OBJEXT): $(top_srcdir)/include/ruby.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)}intern.h
+proc.$(OBJEXT): {$(VPATH)}internal.h
+proc.$(OBJEXT): {$(VPATH)}io.h
+proc.$(OBJEXT): {$(VPATH)}iseq.h
+proc.$(OBJEXT): {$(VPATH)}method.h
+proc.$(OBJEXT): {$(VPATH)}missing.h
+proc.$(OBJEXT): {$(VPATH)}node.h
+proc.$(OBJEXT): {$(VPATH)}onigmo.h
+proc.$(OBJEXT): {$(VPATH)}oniguruma.h
+proc.$(OBJEXT): {$(VPATH)}proc.c
+proc.$(OBJEXT): {$(VPATH)}ruby_assert.h
+proc.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+proc.$(OBJEXT): {$(VPATH)}st.h
+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/ruby.h
+process.$(OBJEXT): $(top_srcdir)/include/ruby.h
+process.$(OBJEXT): {$(VPATH)}config.h
+process.$(OBJEXT): {$(VPATH)}defines.h
+process.$(OBJEXT): {$(VPATH)}dln.h
+process.$(OBJEXT): {$(VPATH)}encoding.h
+process.$(OBJEXT): {$(VPATH)}id.h
+process.$(OBJEXT): {$(VPATH)}intern.h
+process.$(OBJEXT): {$(VPATH)}internal.h
+process.$(OBJEXT): {$(VPATH)}io.h
+process.$(OBJEXT): {$(VPATH)}method.h
+process.$(OBJEXT): {$(VPATH)}missing.h
+process.$(OBJEXT): {$(VPATH)}node.h
+process.$(OBJEXT): {$(VPATH)}onigmo.h
+process.$(OBJEXT): {$(VPATH)}oniguruma.h
+process.$(OBJEXT): {$(VPATH)}process.c
+process.$(OBJEXT): {$(VPATH)}ruby_assert.h
+process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+process.$(OBJEXT): {$(VPATH)}st.h
+process.$(OBJEXT): {$(VPATH)}subst.h
+process.$(OBJEXT): {$(VPATH)}thread.h
+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
+random.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+random.$(OBJEXT): $(top_srcdir)/include/ruby.h
+random.$(OBJEXT): {$(VPATH)}config.h
+random.$(OBJEXT): {$(VPATH)}defines.h
+random.$(OBJEXT): {$(VPATH)}encoding.h
+random.$(OBJEXT): {$(VPATH)}intern.h
+random.$(OBJEXT): {$(VPATH)}internal.h
+random.$(OBJEXT): {$(VPATH)}io.h
+random.$(OBJEXT): {$(VPATH)}missing.h
+random.$(OBJEXT): {$(VPATH)}onigmo.h
+random.$(OBJEXT): {$(VPATH)}oniguruma.h
+random.$(OBJEXT): {$(VPATH)}random.c
+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/ruby.h
+range.$(OBJEXT): $(top_srcdir)/include/ruby.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)}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/ruby.h
+rational.$(OBJEXT): $(top_srcdir)/include/ruby.h
+rational.$(OBJEXT): {$(VPATH)}config.h
+rational.$(OBJEXT): {$(VPATH)}defines.h
+rational.$(OBJEXT): {$(VPATH)}encoding.h
+rational.$(OBJEXT): {$(VPATH)}id.h
+rational.$(OBJEXT): {$(VPATH)}intern.h
+rational.$(OBJEXT): {$(VPATH)}internal.h
+rational.$(OBJEXT): {$(VPATH)}io.h
+rational.$(OBJEXT): {$(VPATH)}missing.h
+rational.$(OBJEXT): {$(VPATH)}onigmo.h
+rational.$(OBJEXT): {$(VPATH)}oniguruma.h
+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/ruby.h
+re.$(OBJEXT): $(top_srcdir)/include/ruby.h
+re.$(OBJEXT): {$(VPATH)}config.h
+re.$(OBJEXT): {$(VPATH)}defines.h
+re.$(OBJEXT): {$(VPATH)}encindex.h
+re.$(OBJEXT): {$(VPATH)}encoding.h
+re.$(OBJEXT): {$(VPATH)}intern.h
+re.$(OBJEXT): {$(VPATH)}internal.h
+re.$(OBJEXT): {$(VPATH)}io.h
+re.$(OBJEXT): {$(VPATH)}missing.h
+re.$(OBJEXT): {$(VPATH)}onigmo.h
+re.$(OBJEXT): {$(VPATH)}oniguruma.h
+re.$(OBJEXT): {$(VPATH)}re.c
+re.$(OBJEXT): {$(VPATH)}re.h
+re.$(OBJEXT): {$(VPATH)}regenc.h
+re.$(OBJEXT): {$(VPATH)}regex.h
+re.$(OBJEXT): {$(VPATH)}regint.h
+re.$(OBJEXT): {$(VPATH)}st.h
+re.$(OBJEXT): {$(VPATH)}subst.h
+re.$(OBJEXT): {$(VPATH)}util.h
+regcomp.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regcomp.$(OBJEXT): {$(VPATH)}config.h
+regcomp.$(OBJEXT): {$(VPATH)}defines.h
+regcomp.$(OBJEXT): {$(VPATH)}intern.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
+regcomp.$(OBJEXT): {$(VPATH)}regparse.h
+regcomp.$(OBJEXT): {$(VPATH)}st.h
+regcomp.$(OBJEXT): {$(VPATH)}subst.h
+regenc.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regenc.$(OBJEXT): {$(VPATH)}config.h
+regenc.$(OBJEXT): {$(VPATH)}defines.h
+regenc.$(OBJEXT): {$(VPATH)}intern.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)}config.h
+regerror.$(OBJEXT): {$(VPATH)}defines.h
+regerror.$(OBJEXT): {$(VPATH)}intern.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)}config.h
+regexec.$(OBJEXT): {$(VPATH)}defines.h
+regexec.$(OBJEXT): {$(VPATH)}intern.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)}config.h
+regparse.$(OBJEXT): {$(VPATH)}defines.h
+regparse.$(OBJEXT): {$(VPATH)}intern.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
+regparse.$(OBJEXT): {$(VPATH)}regparse.h
+regparse.$(OBJEXT): {$(VPATH)}st.h
+regparse.$(OBJEXT): {$(VPATH)}subst.h
+regsyntax.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+regsyntax.$(OBJEXT): {$(VPATH)}config.h
+regsyntax.$(OBJEXT): {$(VPATH)}defines.h
+regsyntax.$(OBJEXT): {$(VPATH)}intern.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)}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/ruby.h
+ruby.$(OBJEXT): $(top_srcdir)/include/ruby.h
+ruby.$(OBJEXT): {$(VPATH)}config.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)}intern.h
+ruby.$(OBJEXT): {$(VPATH)}internal.h
+ruby.$(OBJEXT): {$(VPATH)}io.h
+ruby.$(OBJEXT): {$(VPATH)}method.h
+ruby.$(OBJEXT): {$(VPATH)}missing.h
+ruby.$(OBJEXT): {$(VPATH)}node.h
+ruby.$(OBJEXT): {$(VPATH)}onigmo.h
+ruby.$(OBJEXT): {$(VPATH)}oniguruma.h
+ruby.$(OBJEXT): {$(VPATH)}ruby.c
+ruby.$(OBJEXT): {$(VPATH)}ruby_assert.h
+ruby.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+ruby.$(OBJEXT): {$(VPATH)}st.h
+ruby.$(OBJEXT): {$(VPATH)}subst.h
+ruby.$(OBJEXT): {$(VPATH)}thread.h
+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
+setproctitle.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+setproctitle.$(OBJEXT): $(top_srcdir)/include/ruby.h
+setproctitle.$(OBJEXT): {$(VPATH)}config.h
+setproctitle.$(OBJEXT): {$(VPATH)}defines.h
+setproctitle.$(OBJEXT): {$(VPATH)}intern.h
+setproctitle.$(OBJEXT): {$(VPATH)}missing.h
+setproctitle.$(OBJEXT): {$(VPATH)}setproctitle.c
+setproctitle.$(OBJEXT): {$(VPATH)}st.h
+setproctitle.$(OBJEXT): {$(VPATH)}subst.h
+setproctitle.$(OBJEXT): {$(VPATH)}util.h
+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/ruby.h
+signal.$(OBJEXT): $(top_srcdir)/include/ruby.h
+signal.$(OBJEXT): {$(VPATH)}config.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)}intern.h
+signal.$(OBJEXT): {$(VPATH)}internal.h
+signal.$(OBJEXT): {$(VPATH)}io.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)}ruby_assert.h
+signal.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+signal.$(OBJEXT): {$(VPATH)}signal.c
+signal.$(OBJEXT): {$(VPATH)}st.h
+signal.$(OBJEXT): {$(VPATH)}subst.h
+signal.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+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/ruby.h
+sprintf.$(OBJEXT): $(top_srcdir)/include/ruby.h
+sprintf.$(OBJEXT): {$(VPATH)}config.h
+sprintf.$(OBJEXT): {$(VPATH)}defines.h
+sprintf.$(OBJEXT): {$(VPATH)}encoding.h
+sprintf.$(OBJEXT): {$(VPATH)}id.h
+sprintf.$(OBJEXT): {$(VPATH)}intern.h
+sprintf.$(OBJEXT): {$(VPATH)}internal.h
+sprintf.$(OBJEXT): {$(VPATH)}io.h
+sprintf.$(OBJEXT): {$(VPATH)}missing.h
+sprintf.$(OBJEXT): {$(VPATH)}onigmo.h
+sprintf.$(OBJEXT): {$(VPATH)}oniguruma.h
+sprintf.$(OBJEXT): {$(VPATH)}re.h
+sprintf.$(OBJEXT): {$(VPATH)}regex.h
+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/ruby.h
+st.$(OBJEXT): $(top_srcdir)/include/ruby.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)}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/ruby.h
+strftime.$(OBJEXT): $(top_srcdir)/include/ruby.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)}missing.h
+strftime.$(OBJEXT): {$(VPATH)}onigmo.h
+strftime.$(OBJEXT): {$(VPATH)}oniguruma.h
+strftime.$(OBJEXT): {$(VPATH)}st.h
+strftime.$(OBJEXT): {$(VPATH)}strftime.c
+strftime.$(OBJEXT): {$(VPATH)}subst.h
+strftime.$(OBJEXT): {$(VPATH)}timev.h
+string.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+string.$(OBJEXT): $(top_srcdir)/include/ruby.h
+string.$(OBJEXT): {$(VPATH)}config.h
+string.$(OBJEXT): {$(VPATH)}crypt.h
+string.$(OBJEXT): {$(VPATH)}debug_counter.h
+string.$(OBJEXT): {$(VPATH)}defines.h
+string.$(OBJEXT): {$(VPATH)}encindex.h
+string.$(OBJEXT): {$(VPATH)}encoding.h
+string.$(OBJEXT): {$(VPATH)}gc.h
+string.$(OBJEXT): {$(VPATH)}id.h
+string.$(OBJEXT): {$(VPATH)}intern.h
+string.$(OBJEXT): {$(VPATH)}internal.h
+string.$(OBJEXT): {$(VPATH)}io.h
+string.$(OBJEXT): {$(VPATH)}missing.h
+string.$(OBJEXT): {$(VPATH)}onigmo.h
+string.$(OBJEXT): {$(VPATH)}oniguruma.h
+string.$(OBJEXT): {$(VPATH)}probes.dmyh
+string.$(OBJEXT): {$(VPATH)}probes.h
+string.$(OBJEXT): {$(VPATH)}re.h
+string.$(OBJEXT): {$(VPATH)}regex.h
+string.$(OBJEXT): {$(VPATH)}ruby_assert.h
+string.$(OBJEXT): {$(VPATH)}st.h
+string.$(OBJEXT): {$(VPATH)}string.c
+string.$(OBJEXT): {$(VPATH)}subst.h
+strlcat.$(OBJEXT): {$(VPATH)}config.h
+strlcat.$(OBJEXT): {$(VPATH)}missing.h
+strlcat.$(OBJEXT): {$(VPATH)}strlcat.c
+strlcpy.$(OBJEXT): {$(VPATH)}config.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/ruby.h
+struct.$(OBJEXT): $(top_srcdir)/include/ruby.h
+struct.$(OBJEXT): {$(VPATH)}config.h
+struct.$(OBJEXT): {$(VPATH)}defines.h
+struct.$(OBJEXT): {$(VPATH)}encoding.h
+struct.$(OBJEXT): {$(VPATH)}id.h
+struct.$(OBJEXT): {$(VPATH)}intern.h
+struct.$(OBJEXT): {$(VPATH)}internal.h
+struct.$(OBJEXT): {$(VPATH)}io.h
+struct.$(OBJEXT): {$(VPATH)}method.h
+struct.$(OBJEXT): {$(VPATH)}missing.h
+struct.$(OBJEXT): {$(VPATH)}node.h
+struct.$(OBJEXT): {$(VPATH)}onigmo.h
+struct.$(OBJEXT): {$(VPATH)}oniguruma.h
+struct.$(OBJEXT): {$(VPATH)}ruby_assert.h
+struct.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+struct.$(OBJEXT): {$(VPATH)}st.h
+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)}vm_core.h
+struct.$(OBJEXT): {$(VPATH)}vm_debug.h
+struct.$(OBJEXT): {$(VPATH)}vm_opts.h
+symbol.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+symbol.$(OBJEXT): $(top_srcdir)/include/ruby.h
+symbol.$(OBJEXT): {$(VPATH)}config.h
+symbol.$(OBJEXT): {$(VPATH)}defines.h
+symbol.$(OBJEXT): {$(VPATH)}encoding.h
+symbol.$(OBJEXT): {$(VPATH)}gc.h
+symbol.$(OBJEXT): {$(VPATH)}id.c
+symbol.$(OBJEXT): {$(VPATH)}id.h
+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)}missing.h
+symbol.$(OBJEXT): {$(VPATH)}onigmo.h
+symbol.$(OBJEXT): {$(VPATH)}oniguruma.h
+symbol.$(OBJEXT): {$(VPATH)}probes.dmyh
+symbol.$(OBJEXT): {$(VPATH)}probes.h
+symbol.$(OBJEXT): {$(VPATH)}ruby_assert.h
+symbol.$(OBJEXT): {$(VPATH)}st.h
+symbol.$(OBJEXT): {$(VPATH)}subst.h
+symbol.$(OBJEXT): {$(VPATH)}symbol.c
+symbol.$(OBJEXT): {$(VPATH)}symbol.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/ruby.h
+thread.$(OBJEXT): $(top_srcdir)/include/ruby.h
+thread.$(OBJEXT): {$(VPATH)}config.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)}id.h
+thread.$(OBJEXT): {$(VPATH)}intern.h
+thread.$(OBJEXT): {$(VPATH)}internal.h
+thread.$(OBJEXT): {$(VPATH)}io.h
+thread.$(OBJEXT): {$(VPATH)}method.h
+thread.$(OBJEXT): {$(VPATH)}missing.h
+thread.$(OBJEXT): {$(VPATH)}node.h
+thread.$(OBJEXT): {$(VPATH)}onigmo.h
+thread.$(OBJEXT): {$(VPATH)}oniguruma.h
+thread.$(OBJEXT): {$(VPATH)}ruby_assert.h
+thread.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+thread.$(OBJEXT): {$(VPATH)}st.h
+thread.$(OBJEXT): {$(VPATH)}subst.h
+thread.$(OBJEXT): {$(VPATH)}thread.c
+thread.$(OBJEXT): {$(VPATH)}thread.h
+thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).c
+thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+thread.$(OBJEXT): {$(VPATH)}thread_native.h
+thread.$(OBJEXT): {$(VPATH)}thread_sync.c
+thread.$(OBJEXT): {$(VPATH)}timev.h
+thread.$(OBJEXT): {$(VPATH)}vm_core.h
+thread.$(OBJEXT): {$(VPATH)}vm_debug.h
+thread.$(OBJEXT): {$(VPATH)}vm_opts.h
+time.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+time.$(OBJEXT): $(top_srcdir)/include/ruby.h
+time.$(OBJEXT): {$(VPATH)}config.h
+time.$(OBJEXT): {$(VPATH)}defines.h
+time.$(OBJEXT): {$(VPATH)}encoding.h
+time.$(OBJEXT): {$(VPATH)}id.h
+time.$(OBJEXT): {$(VPATH)}intern.h
+time.$(OBJEXT): {$(VPATH)}internal.h
+time.$(OBJEXT): {$(VPATH)}io.h
+time.$(OBJEXT): {$(VPATH)}missing.h
+time.$(OBJEXT): {$(VPATH)}onigmo.h
+time.$(OBJEXT): {$(VPATH)}oniguruma.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/ruby.h
+transcode.$(OBJEXT): $(top_srcdir)/include/ruby.h
+transcode.$(OBJEXT): {$(VPATH)}config.h
+transcode.$(OBJEXT): {$(VPATH)}defines.h
+transcode.$(OBJEXT): {$(VPATH)}encoding.h
+transcode.$(OBJEXT): {$(VPATH)}intern.h
+transcode.$(OBJEXT): {$(VPATH)}internal.h
+transcode.$(OBJEXT): {$(VPATH)}io.h
+transcode.$(OBJEXT): {$(VPATH)}missing.h
+transcode.$(OBJEXT): {$(VPATH)}onigmo.h
+transcode.$(OBJEXT): {$(VPATH)}oniguruma.h
+transcode.$(OBJEXT): {$(VPATH)}st.h
+transcode.$(OBJEXT): {$(VPATH)}subst.h
+transcode.$(OBJEXT): {$(VPATH)}transcode.c
+transcode.$(OBJEXT): {$(VPATH)}transcode_data.h
+util.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+util.$(OBJEXT): $(top_srcdir)/include/ruby.h
+util.$(OBJEXT): {$(VPATH)}config.h
+util.$(OBJEXT): {$(VPATH)}defines.h
+util.$(OBJEXT): {$(VPATH)}encoding.h
+util.$(OBJEXT): {$(VPATH)}intern.h
+util.$(OBJEXT): {$(VPATH)}internal.h
+util.$(OBJEXT): {$(VPATH)}io.h
+util.$(OBJEXT): {$(VPATH)}missing.h
+util.$(OBJEXT): {$(VPATH)}onigmo.h
+util.$(OBJEXT): {$(VPATH)}oniguruma.h
+util.$(OBJEXT): {$(VPATH)}st.h
+util.$(OBJEXT): {$(VPATH)}subst.h
+util.$(OBJEXT): {$(VPATH)}util.c
+util.$(OBJEXT): {$(VPATH)}util.h
+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/ruby.h
+variable.$(OBJEXT): $(top_srcdir)/include/ruby.h
+variable.$(OBJEXT): {$(VPATH)}config.h
+variable.$(OBJEXT): {$(VPATH)}constant.h
+variable.$(OBJEXT): {$(VPATH)}debug_counter.h
+variable.$(OBJEXT): {$(VPATH)}defines.h
+variable.$(OBJEXT): {$(VPATH)}encoding.h
+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)}missing.h
+variable.$(OBJEXT): {$(VPATH)}onigmo.h
+variable.$(OBJEXT): {$(VPATH)}oniguruma.h
+variable.$(OBJEXT): {$(VPATH)}st.h
+variable.$(OBJEXT): {$(VPATH)}subst.h
+variable.$(OBJEXT): {$(VPATH)}util.h
+variable.$(OBJEXT): {$(VPATH)}variable.c
+version.$(OBJEXT): $(hdrdir)/ruby/ruby.h
+version.$(OBJEXT): $(hdrdir)/ruby/version.h
+version.$(OBJEXT): $(top_srcdir)/revision.h
+version.$(OBJEXT): $(top_srcdir)/version.h
+version.$(OBJEXT): {$(VPATH)}config.h
+version.$(OBJEXT): {$(VPATH)}defines.h
+version.$(OBJEXT): {$(VPATH)}intern.h
+version.$(OBJEXT): {$(VPATH)}missing.h
+version.$(OBJEXT): {$(VPATH)}st.h
+version.$(OBJEXT): {$(VPATH)}subst.h
+version.$(OBJEXT): {$(VPATH)}version.c
+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/ruby.h
+vm.$(OBJEXT): $(hdrdir)/ruby/version.h
+vm.$(OBJEXT): $(top_srcdir)/include/ruby.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)}encoding.h
+vm.$(OBJEXT): {$(VPATH)}eval_intern.h
+vm.$(OBJEXT): {$(VPATH)}gc.h
+vm.$(OBJEXT): {$(VPATH)}id.h
+vm.$(OBJEXT): {$(VPATH)}id_table.h
+vm.$(OBJEXT): {$(VPATH)}insns.def
+vm.$(OBJEXT): {$(VPATH)}insns.inc
+vm.$(OBJEXT): {$(VPATH)}intern.h
+vm.$(OBJEXT): {$(VPATH)}internal.h
+vm.$(OBJEXT): {$(VPATH)}io.h
+vm.$(OBJEXT): {$(VPATH)}iseq.h
+vm.$(OBJEXT): {$(VPATH)}method.h
+vm.$(OBJEXT): {$(VPATH)}missing.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)}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)}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_core.h
+vm.$(OBJEXT): {$(VPATH)}vm_debug.h
+vm.$(OBJEXT): {$(VPATH)}vm_eval.c
+vm.$(OBJEXT): {$(VPATH)}vm_exec.c
+vm.$(OBJEXT): {$(VPATH)}vm_exec.h
+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)}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/ruby.h
+vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/version.h
+vm_backtrace.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}config.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}debug.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}defines.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}encoding.h
+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)}iseq.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}method.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}missing.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}node.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}onigmo.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}oniguruma.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_assert.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}st.h
+vm_backtrace.$(OBJEXT): {$(VPATH)}subst.h
+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/ruby.h
+vm_dump.$(OBJEXT): $(hdrdir)/ruby/version.h
+vm_dump.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_dump.$(OBJEXT): {$(VPATH)}addr2line.h
+vm_dump.$(OBJEXT): {$(VPATH)}config.h
+vm_dump.$(OBJEXT): {$(VPATH)}defines.h
+vm_dump.$(OBJEXT): {$(VPATH)}encoding.h
+vm_dump.$(OBJEXT): {$(VPATH)}id.h
+vm_dump.$(OBJEXT): {$(VPATH)}intern.h
+vm_dump.$(OBJEXT): {$(VPATH)}internal.h
+vm_dump.$(OBJEXT): {$(VPATH)}io.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)}ruby_assert.h
+vm_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h
+vm_dump.$(OBJEXT): {$(VPATH)}st.h
+vm_dump.$(OBJEXT): {$(VPATH)}subst.h
+vm_dump.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+vm_dump.$(OBJEXT): {$(VPATH)}thread_native.h
+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_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/ruby.h
+vm_trace.$(OBJEXT): $(top_srcdir)/include/ruby.h
+vm_trace.$(OBJEXT): {$(VPATH)}config.h
+vm_trace.$(OBJEXT): {$(VPATH)}debug.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)}iseq.h
+vm_trace.$(OBJEXT): {$(VPATH)}method.h
+vm_trace.$(OBJEXT): {$(VPATH)}missing.h
+vm_trace.$(OBJEXT): {$(VPATH)}node.h
+vm_trace.$(OBJEXT): {$(VPATH)}onigmo.h
+vm_trace.$(OBJEXT): {$(VPATH)}oniguruma.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)}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 846364ef49..02529c9960 100644
--- a/compar.c
+++ b/compar.c
@@ -1,100 +1,262 @@
-/************************************************
+/**********************************************************************
compar.c -
$Author$
- $Date$
created at: Thu Aug 26 14:39:48 JST 1993
- Copyright (C) 1993-1998 Yukihiro Matsumoto
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
-************************************************/
+**********************************************************************/
-#include "ruby.h"
+#include "ruby/ruby.h"
+#include "id.h"
-VALUE mComparable;
-
-static ID cmp;
+VALUE rb_mComparable;
static VALUE
-cmp_eq(x, y)
- VALUE x, y;
+rb_cmp(VALUE x, VALUE y)
+{
+ return rb_funcallv(x, idCmp, 1, &y);
+}
+
+void
+rb_cmperr(VALUE x, VALUE y)
{
- VALUE c = rb_funcall(x, cmp, 1, y);
- int t = NUM2INT(c);
+ VALUE classname;
- if (t == 0) return TRUE;
- return FALSE;
+ if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) {
+ classname = rb_inspect(y);
+ }
+ else {
+ classname = rb_obj_class(y);
+ }
+ rb_raise(rb_eArgError, "comparison of %"PRIsVALUE" with %"PRIsVALUE" failed",
+ rb_obj_class(x), classname);
}
static VALUE
-cmp_gt(x, y)
- VALUE x, y;
+invcmp_recursive(VALUE x, VALUE y, int recursive)
{
- VALUE c = rb_funcall(x, cmp, 1, y);
- int t = NUM2INT(c);
+ if (recursive) return Qnil;
+ return rb_cmp(y, x);
+}
+
+VALUE
+rb_invcmp(VALUE x, VALUE y)
+{
+ VALUE invcmp = rb_exec_recursive(invcmp_recursive, x, y);
+ if (invcmp == Qundef || NIL_P(invcmp)) {
+ return Qnil;
+ }
+ else {
+ int result = -rb_cmpint(invcmp, x, y);
+ return INT2FIX(result);
+ }
+}
- if (t > 0) return TRUE;
- return FALSE;
+static VALUE
+cmp_eq_recursive(VALUE arg1, VALUE arg2, int recursive)
+{
+ if (recursive) return Qnil;
+ return rb_cmp(arg1, arg2);
}
+/*
+ * call-seq:
+ * obj == other -> true or false
+ *
+ * Compares two objects based on the receiver's <code><=></code>
+ * method, returning true if it returns 0. Also returns true if
+ * _obj_ and _other_ are the same object.
+ */
+
static VALUE
-cmp_ge(x, y)
- VALUE x, y;
+cmp_equal(VALUE x, VALUE y)
{
- VALUE c = rb_funcall(x, cmp, 1, y);
- int t = NUM2INT(c);
+ VALUE c;
+ if (x == y) return Qtrue;
+
+ c = rb_exec_recursive_paired_outer(cmp_eq_recursive, x, y, y);
+
+ if (NIL_P(c)) return Qfalse;
+ if (rb_cmpint(c, x, y) == 0) return Qtrue;
+ return Qfalse;
+}
+
+static int
+cmpint(VALUE x, VALUE y)
+{
+ return rb_cmpint(rb_cmp(x, y), x, y);
+}
- if (t >= 0) return TRUE;
- return FALSE;
+/*
+ * call-seq:
+ * obj > other -> true or false
+ *
+ * Compares two objects based on the receiver's <code><=></code>
+ * method, returning true if it returns 1.
+ */
+
+static VALUE
+cmp_gt(VALUE x, VALUE y)
+{
+ if (cmpint(x, y) > 0) return Qtrue;
+ return Qfalse;
}
+/*
+ * call-seq:
+ * obj >= other -> true or false
+ *
+ * Compares two objects based on the receiver's <code><=></code>
+ * method, returning true if it returns 0 or 1.
+ */
+
static VALUE
-cmp_lt(x, y)
- VALUE x, y;
+cmp_ge(VALUE x, VALUE y)
{
- VALUE c = rb_funcall(x, cmp, 1, y);
- int t = NUM2INT(c);
+ if (cmpint(x, y) >= 0) return Qtrue;
+ return Qfalse;
+}
- if (t < 0) return TRUE;
- return FALSE;
+/*
+ * call-seq:
+ * obj < other -> true or false
+ *
+ * Compares two objects based on the receiver's <code><=></code>
+ * method, returning true if it returns -1.
+ */
+
+static VALUE
+cmp_lt(VALUE x, VALUE y)
+{
+ if (cmpint(x, y) < 0) return Qtrue;
+ return Qfalse;
}
+/*
+ * call-seq:
+ * obj <= other -> true or false
+ *
+ * Compares two objects based on the receiver's <code><=></code>
+ * method, returning true if it returns -1 or 0.
+ */
+
static VALUE
-cmp_le(x, y)
- VALUE x, y;
+cmp_le(VALUE x, VALUE y)
{
- VALUE c = rb_funcall(x, cmp, 1, y);
- int t = NUM2INT(c);
+ if (cmpint(x, y) <= 0) return Qtrue;
+ return Qfalse;
+}
+
+/*
+ * 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.
+ *
+ * 3.between?(1, 5) #=> true
+ * 6.between?(1, 5) #=> false
+ * 'cat'.between?('ant', 'dog') #=> true
+ * 'gnu'.between?('ant', 'dog') #=> false
+ *
+ */
- if (t <= 0) return TRUE;
- return FALSE;
+static VALUE
+cmp_between(VALUE x, VALUE min, VALUE max)
+{
+ if (cmpint(x, min) < 0) return Qfalse;
+ if (cmpint(x, max) > 0) return Qfalse;
+ return Qtrue;
}
+/*
+ * call-seq:
+ * obj.clamp(min, max) -> 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.
+ *
+ * 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'
+ */
+
static VALUE
-cmp_between(x, min, max)
- VALUE x, min, max;
+cmp_clamp(VALUE x, VALUE min, VALUE max)
{
- VALUE c = rb_funcall(x, cmp, 1, min);
- long t = NUM2LONG(c);
- if (t < 0) return FALSE;
-
- c = rb_funcall(x, cmp, 1, max);
- t = NUM2LONG(c);
- if (t > 0) return FALSE;
- return TRUE;
+ int c;
+
+ if (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;
+ 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>.
+ *
+ * class SizeMatters
+ * include Comparable
+ * attr :str
+ * def <=>(other)
+ * str.size <=> other.str.size
+ * end
+ * def initialize(str)
+ * @str = str
+ * end
+ * def inspect
+ * @str
+ * end
+ * end
+ *
+ * s1 = SizeMatters.new("Z")
+ * s2 = SizeMatters.new("YY")
+ * s3 = SizeMatters.new("XXX")
+ * s4 = SizeMatters.new("WWWW")
+ * s5 = SizeMatters.new("VVVVV")
+ *
+ * s1 < s2 #=> true
+ * s4.between?(s1, s3) #=> false
+ * s4.between?(s3, s5) #=> true
+ * [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
+ *
+ */
+
void
-Init_Comparable()
+Init_Comparable(void)
{
- mComparable = rb_define_module("Comparable");
- rb_define_method(mComparable, "==", cmp_eq, 1);
- rb_define_method(mComparable, ">", cmp_gt, 1);
- rb_define_method(mComparable, ">=", cmp_ge, 1);
- rb_define_method(mComparable, "<", cmp_lt, 1);
- rb_define_method(mComparable, "<=", cmp_le, 1);
- rb_define_method(mComparable, "between?", cmp_between, 2);
-
- cmp = rb_intern("<=>");
+#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);
+ rb_define_method(rb_mComparable, ">=", cmp_ge, 1);
+ 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);
}
diff --git a/compile.c b/compile.c
new file mode 100644
index 0000000000..2c10d151f5
--- /dev/null
+++ b/compile.c
@@ -0,0 +1,9599 @@
+/**********************************************************************
+
+ compile.c - ruby node tree -> VM instruction sequence
+
+ $Author$
+ created at: 04/01/01 03:42:15 JST
+
+ Copyright (C) 2004-2007 Koichi Sasada
+
+**********************************************************************/
+
+#include "internal.h"
+#include "ruby/re.h"
+#include "encindex.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
+
+#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_LABEL,
+ ISEQ_ELEMENT_INSN,
+ ISEQ_ELEMENT_ADJUST,
+ ISEQ_ELEMENT_TRACE
+ } type;
+ struct iseq_link_element *next;
+ struct iseq_link_element *prev;
+} LINK_ELEMENT;
+
+typedef struct iseq_link_anchor {
+ LINK_ELEMENT anchor;
+ LINK_ELEMENT *last;
+} LINK_ANCHOR;
+
+typedef enum {
+ LABEL_RESCUE_NONE,
+ LABEL_RESCUE_BEG,
+ LABEL_RESCUE_END,
+ LABEL_RESCUE_TYPE_MAX
+} LABEL_RESCUE_TYPE;
+
+typedef struct iseq_label_data {
+ LINK_ELEMENT link;
+ int label_no;
+ int position;
+ int sc_state;
+ int sp;
+ int refcnt;
+ unsigned int set: 1;
+ unsigned int rescued: 2;
+ unsigned int unremovable: 1;
+} LABEL;
+
+typedef struct iseq_insn_data {
+ LINK_ELEMENT link;
+ enum ruby_vminsn_type insn_id;
+ 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 {
+ LINK_ELEMENT link;
+ LABEL *label;
+ int line_no;
+} ADJUST;
+
+typedef struct iseq_trace_data {
+ LINK_ELEMENT link;
+ rb_event_flag_t event;
+} TRACE;
+
+struct ensure_range {
+ LABEL *begin;
+ LABEL *end;
+ struct ensure_range *next;
+};
+
+struct iseq_compile_data_ensure_node_stack {
+ const NODE *ensure_node;
+ struct iseq_compile_data_ensure_node_stack *prev;
+ struct ensure_range *erange;
+};
+
+/**
+ * debug function(macro) interface depend on CPDEBUG
+ * if it is less than 0, runtime option is in effect.
+ *
+ * debug level:
+ * 0: no debug output
+ * 1: show node type
+ * 2: show node important parameters
+ * ...
+ * 5: show other parameters
+ * 10: show every AST array
+ */
+
+#ifndef CPDEBUG
+#define CPDEBUG 0
+#endif
+
+#if CPDEBUG >= 0
+#define compile_debug CPDEBUG
+#else
+#define compile_debug ISEQ_COMPILE_DATA(iseq)->option->debug_level
+#endif
+
+#if CPDEBUG
+
+#define compile_debug_print_indent(level) \
+ ruby_debug_print_indent((level), compile_debug, gl_node_level * 2)
+
+#define debugp(header, value) (void) \
+ (compile_debug_print_indent(1) && \
+ ruby_debug_print_value(1, compile_debug, (header), (value)))
+
+#define debugi(header, id) (void) \
+ (compile_debug_print_indent(1) && \
+ ruby_debug_print_id(1, compile_debug, (header), (id)))
+
+#define debugp_param(header, value) (void) \
+ (compile_debug_print_indent(1) && \
+ ruby_debug_print_value(1, compile_debug, (header), (value)))
+
+#define debugp_verbose(header, value) (void) \
+ (compile_debug_print_indent(2) && \
+ ruby_debug_print_value(2, compile_debug, (header), (value)))
+
+#define debugp_verbose_node(header, value) (void) \
+ (compile_debug_print_indent(10) && \
+ ruby_debug_print_value(10, compile_debug, (header), (value)))
+
+#define debug_node_start(node) ((void) \
+ (compile_debug_print_indent(1) && \
+ (ruby_debug_print_node(1, CPDEBUG, "", (const NODE *)(node)), gl_node_level)), \
+ gl_node_level++)
+
+#define debug_node_end() gl_node_level --
+
+#else
+
+#define debugi(header, id) ((void)0)
+#define debugp(header, value) ((void)0)
+#define debugp_verbose(header, value) ((void)0)
+#define debugp_verbose_node(header, value) ((void)0)
+#define debugp_param(header, value) ((void)0)
+#define debug_node_start(node) ((void)0)
+#define debug_node_end() ((void)0)
+#endif
+
+#if CPDEBUG > 1 || CPDEBUG < 0
+#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))
+#else
+#define debugs if(0)printf
+#define debug_compile(msg, v) (v)
+#endif
+
+#define LVAR_ERRINFO (1)
+
+/* create new label */
+#define NEW_LABEL(l) new_label_body(iseq, (l))
+#define LABEL_FORMAT "<L%03d>"
+
+#define NEW_ISEQ(node, name, type, line_no) \
+ new_child_iseq(iseq, (node), rb_fstring(name), 0, (type), (line_no))
+
+#define NEW_CHILD_ISEQ(node, name, type, line_no) \
+ new_child_iseq(iseq, (node), rb_fstring(name), iseq, (type), (line_no))
+
+/* add instructions */
+#define ADD_SEQ(seq1, seq2) \
+ APPEND_LIST((seq1), (seq2))
+
+/* add an instruction */
+#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) \
+ ELEM_INSERT_PREV(&(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) \
+ ELEM_INSERT_PREV(&(prev)->link, (LINK_ELEMENT *) \
+ new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
+
+#define LABEL_REF(label) ((label)->refcnt++)
+
+/* add an instruction with label operand (alias of ADD_INSN1) */
+#define ADD_INSNL(seq, line, insn, label) (ADD_INSN1(seq, line, insn, label), LABEL_REF(label))
+
+#define ADD_INSN2(seq, line, insn, op1, op2) \
+ ADD_ELEM((seq), (LINK_ELEMENT *) \
+ new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2)))
+
+#define ADD_INSN3(seq, line, insn, op1, op2, op3) \
+ ADD_ELEM((seq), (LINK_ELEMENT *) \
+ new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3)))
+
+/* Specific Insn factory */
+#define ADD_SEND(seq, line, id, argc) \
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL)
+
+#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag) \
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)(flag), NULL)
+
+#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block) \
+ ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(0), NULL)
+
+#define ADD_CALL_RECEIVER(seq, line) \
+ ADD_INSN((seq), (line), putself)
+
+#define ADD_CALL(seq, line, id, argc) \
+ ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
+
+#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
+ ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
+
+#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(seq, event) \
+ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event)))
+#define ADD_TRACE_LINE_COVERAGE(seq, line) \
+ do { \
+ if (ISEQ_COVERAGE(iseq) && \
+ ISEQ_LINE_COVERAGE(iseq) && \
+ (line) > 0) { \
+ RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \
+ ADD_INSN2((seq), (line), tracecoverage, INT2FIX(RUBY_EVENT_COVERAGE_LINE), INT2FIX(line)); \
+ } \
+ } while (0)
+
+
+#define DECL_BRANCH_BASE(branches, first_line, first_column, last_line, last_column, type) \
+ do { \
+ if (ISEQ_COVERAGE(iseq) && \
+ ISEQ_BRANCH_COVERAGE(iseq) && \
+ (first_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(first_line)); \
+ rb_ary_push(branches, INT2FIX(first_column)); \
+ rb_ary_push(branches, INT2FIX(last_line)); \
+ rb_ary_push(branches, INT2FIX(last_column)); \
+ } \
+ } while (0)
+#define ADD_TRACE_BRANCH_COVERAGE(seq, first_line, first_column, last_line, last_column, type, branches) \
+ do { \
+ if (ISEQ_COVERAGE(iseq) && \
+ ISEQ_BRANCH_COVERAGE(iseq) && \
+ (first_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(first_line)); \
+ rb_ary_push(branches, INT2FIX(first_column)); \
+ rb_ary_push(branches, INT2FIX(last_line)); \
+ rb_ary_push(branches, INT2FIX(last_column)); \
+ rb_ary_push(branches, INT2FIX(counter_idx)); \
+ ADD_INSN2((seq), (first_line), tracecoverage, INT2FIX(RUBY_EVENT_COVERAGE_BRANCH), INT2FIX(counter_idx)); \
+ } \
+ } while (0)
+
+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) \
+ ADD_ELEM((seq), (LINK_ELEMENT *) (label))
+
+#define APPEND_LABEL(seq, before, label) \
+ APPEND_ELEM((seq), (before), (LINK_ELEMENT *) (label))
+
+#define ADD_ADJUST(seq, line, label) \
+ ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (line)))
+
+#define ADD_ADJUST_RESTORE(seq, label) \
+ ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
+
+#define LABEL_UNREMOVABLE(label) \
+ ((label) ? (LABEL_REF(label), (label)->unremovable=1) : 0)
+#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) do { \
+ VALUE _e = rb_ary_new3(5, (type), \
+ (VALUE)(ls) | 1, (VALUE)(le) | 1, \
+ (VALUE)(iseqv), (VALUE)(lc) | 1); \
+ LABEL_UNREMOVABLE(ls); \
+ LABEL_REF(le); \
+ LABEL_REF(lc); \
+ rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \
+} while (0)
+
+/* compile node */
+#define COMPILE(anchor, desc, node) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, (anchor), (node), 0)))
+
+/* compile node, this node's value will be popped */
+#define COMPILE_POPPED(anchor, desc, node) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, (anchor), (node), 1)))
+
+/* compile node, which is popped when 'popped' is true */
+#define COMPILE_(anchor, desc, node, popped) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, (anchor), (node), (popped))))
+
+#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))
+
+#define OPERAND_AT(insn, idx) \
+ (((INSN*)(insn))->operands[(idx)])
+
+#define INSN_OF(insn) \
+ (((INSN*)(insn))->insn_id)
+
+#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, ...));
+#endif
+
+static void
+append_compile_error(rb_iseq_t *iseq, int line, const char *fmt, ...)
+{
+ VALUE err_info = ISEQ_COMPILE_DATA(iseq)->err_info;
+ VALUE file = rb_iseq_path(iseq);
+ VALUE err = err_info == Qtrue ? Qfalse : err_info;
+ va_list args;
+
+ va_start(args, fmt);
+ err = rb_syntax_error_append(err, file, line, -1, NULL, fmt, args);
+ va_end(args);
+ if (NIL_P(err_info)) {
+ RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->err_info, err);
+ rb_set_errinfo(err);
+ }
+ else if (!err_info) {
+ RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->err_info, Qtrue);
+ }
+ if (compile_debug) rb_exc_fatal(err);
+}
+
+#if 0
+static void
+compile_bug(rb_iseq_t *iseq, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ rb_report_bug_valist(rb_iseq_path(iseq), line, fmt, args);
+ va_end(args);
+ abort();
+}
+#endif
+
+#define COMPILE_ERROR append_compile_error
+
+#define ERROR_ARGS_AT(n) iseq, nd_line(n),
+#define ERROR_ARGS ERROR_ARGS_AT(node)
+
+#define EXPECT_NODE(prefix, node, ndtype, errval) \
+do { \
+ 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) \
+ prefix ": " #ndtype " is expected, but %s", \
+ ruby_node_name(error_type)); \
+ return errval; \
+ } \
+} while (0)
+
+#define EXPECT_NODE_NONULL(prefix, parent, ndtype, errval) \
+do { \
+ COMPILE_ERROR(ERROR_ARGS_AT(parent) \
+ prefix ": must be " #ndtype ", but 0"); \
+ return errval; \
+} while (0)
+
+#define UNKNOWN_NODE(prefix, node, errval) \
+do { \
+ 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; \
+} while (0)
+
+#define COMPILE_OK 1
+#define COMPILE_NG 0
+
+#define CHECK(sub) if (!(sub)) {BEFORE_RETURN;return COMPILE_NG;}
+#define BEFORE_RETURN
+
+/* leave name uninitialized so that compiler warn if INIT_ANCHOR is
+ * missing */
+#define DECL_ANCHOR(name) \
+ LINK_ANCHOR name[1] = {{{0,},}}
+#define INIT_ANCHOR(name) \
+ (name->last = &name->anchor)
+
+static inline VALUE
+freeze_hide_obj(VALUE obj)
+{
+ OBJ_FREEZE(obj);
+ RBASIC_CLEAR_CLASS(obj);
+ return obj;
+}
+
+#include "optinsn.inc"
+#if OPT_INSTRUCTIONS_UNIFICATION
+#include "optunifs.inc"
+#endif
+
+/* for debug */
+#if CPDEBUG < 0
+#define ISEQ_ARG iseq,
+#define ISEQ_ARG_DECLARE rb_iseq_t *iseq,
+#else
+#define ISEQ_ARG
+#define ISEQ_ARG_DECLARE
+#endif
+
+#if CPDEBUG
+#define gl_node_level ISEQ_COMPILE_DATA(iseq)->node_level
+#endif
+
+static void dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, const LABEL *dest);
+static void dump_disasm_list(const LINK_ELEMENT *elem);
+
+static int insn_data_length(INSN *iobj);
+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);
+
+
+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, 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, const NODE *const node, VALUE needstr);
+
+/*
+ * To make Array to LinkedList, use link_anchor
+ */
+
+static void
+verify_list(ISEQ_ARG_DECLARE const char *info, LINK_ANCHOR *const anchor)
+{
+#if CPDEBUG
+ int flag = 0;
+ LINK_ELEMENT *list, *plist;
+
+ if (!compile_debug) return;
+
+ list = anchor->anchor.next;
+ plist = &anchor->anchor;
+ while (list) {
+ if (plist != list->prev) {
+ flag += 1;
+ }
+ plist = list;
+ list = list->next;
+ }
+
+ if (anchor->last != plist && anchor->last != 0) {
+ flag |= 0x70000;
+ }
+
+ if (flag != 0) {
+ rb_bug("list verify error: %08x (%s)", flag, info);
+ }
+#endif
+}
+#if CPDEBUG < 0
+#define verify_list(info, anchor) verify_list(iseq, (info), (anchor))
+#endif
+
+/*
+ * elem1, elem2 => elem1, elem2, elem
+ */
+static void
+ADD_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor, LINK_ELEMENT *elem)
+{
+ elem->prev = anchor->last;
+ anchor->last->next = elem;
+ anchor->last = elem;
+ verify_list("add", anchor);
+}
+
+/*
+ * elem1, before, elem2 => elem1, before, elem, elem2
+ */
+static void
+APPEND_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor, LINK_ELEMENT *before, LINK_ELEMENT *elem)
+{
+ elem->prev = before;
+ elem->next = before->next;
+ elem->next->prev = elem;
+ before->next = elem;
+ if (before == anchor->last) anchor->last = elem;
+ verify_list("add", anchor);
+}
+#if CPDEBUG < 0
+#define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem))
+#define APPEND_ELEM(anchor, before, elem) APPEND_ELEM(iseq, (anchor), (before), (elem))
+#endif
+
+static int
+iseq_add_mark_object(const rb_iseq_t *iseq, VALUE v)
+{
+ if (!SPECIAL_CONST_P(v)) {
+ rb_iseq_add_mark_object(iseq, v);
+ }
+ return COMPILE_OK;
+}
+
+static int
+iseq_add_mark_object_compile_time(const rb_iseq_t *iseq, VALUE v)
+{
+ if (!SPECIAL_CONST_P(v)) {
+ rb_ary_push(ISEQ_COMPILE_DATA(iseq)->mark_ary, v);
+ }
+ return COMPILE_OK;
+}
+
+static inline VALUE
+freeze_literal(rb_iseq_t *iseq, VALUE lit)
+{
+ lit = rb_fstring(lit);
+ rb_ary_push(ISEQ_COMPILE_DATA(iseq)->mark_ary, lit);
+ return lit;
+}
+
+static int
+validate_label(st_data_t name, st_data_t label, st_data_t arg)
+{
+ rb_iseq_t *iseq = (rb_iseq_t *)arg;
+ LABEL *lobj = (LABEL *)label;
+ if (!lobj->link.next) {
+ do {
+ COMPILE_ERROR(iseq, lobj->position,
+ "%"PRIsVALUE": undefined label",
+ rb_sym2str((VALUE)name));
+ } while (0);
+ }
+ return ST_CONTINUE;
+}
+
+static void
+validate_labels(rb_iseq_t *iseq, st_table *labels_table)
+{
+ st_foreach(labels_table, validate_label, (st_data_t)iseq);
+ st_free_table(labels_table);
+}
+
+VALUE
+rb_iseq_compile_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *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 (node == 0) {
+ COMPILE(ret, "nil", node);
+ iseq_set_local_table(iseq, 0);
+ }
+ 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);
+ }
+ /* 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);
+ iseq_set_arguments(iseq, ret, node->nd_args);
+
+ switch (iseq->body->type) {
+ case ISEQ_TYPE_BLOCK:
+ {
+ LABEL *start = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(0);
+ LABEL *end = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(0);
+
+ start->rescued = LABEL_RESCUE_BEG;
+ end->rescued = LABEL_RESCUE_END;
+
+ 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, RUBY_EVENT_B_RETURN);
+ ISEQ_COMPILE_DATA(iseq)->last_line = iseq->body->location.code_range.last_loc.lineno;
+
+ /* wide range catch handler must put at last */
+ ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, NULL, start);
+ ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, NULL, end);
+ break;
+ }
+ case ISEQ_TYPE_CLASS:
+ {
+ ADD_TRACE(ret, RUBY_EVENT_CLASS);
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
+ ADD_TRACE(ret, RUBY_EVENT_END);
+ ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
+ break;
+ }
+ case ISEQ_TYPE_METHOD:
+ {
+ ADD_TRACE(ret, RUBY_EVENT_CALL);
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
+ ADD_TRACE(ret, RUBY_EVENT_RETURN);
+ ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node);
+ break;
+ }
+ default: {
+ CHECK(COMPILE(ret, "scoped node", node->nd_body));
+ break;
+ }
+ }
+ }
+ else {
+ const char *m;
+#define INVALID_ISEQ_TYPE(type) \
+ ISEQ_TYPE_##type: m = #type; goto invalid_iseq_type
+ switch (iseq->body->type) {
+ 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));
+ break;
+ case ISEQ_TYPE_ENSURE:
+ 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));
+ break;
+ default:
+ 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;
+ }
+ }
+
+ if (iseq->body->type == ISEQ_TYPE_RESCUE || iseq->body->type == ISEQ_TYPE_ENSURE) {
+ ADD_GETLOCAL(ret, 0, LVAR_ERRINFO, 0);
+ ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ );
+ }
+ else {
+ ADD_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, leave);
+ }
+
+#if 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
+rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
+{
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ const void * const *table = rb_vm_get_insns_address_table();
+ unsigned int i;
+ VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
+
+ for (i = 0; i < iseq->body->iseq_size; /* */ ) {
+ int insn = (int)iseq->body->iseq_encoded[i];
+ int len = insn_len(insn);
+ encoded[i] = (VALUE)table[insn];
+ i += len;
+ }
+#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 */
+{
+ VALUE *original_code;
+
+ if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq);
+ original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->body->iseq_size);
+ MEMCPY(original_code, iseq->body->iseq_encoded, VALUE, iseq->body->iseq_size);
+
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ {
+ unsigned int i;
+
+ for (i = 0; i < iseq->body->iseq_size; /* */ ) {
+ const void *addr = (const void *)original_code[i];
+ const int insn = rb_vm_insn_addr2insn(addr);
+
+ original_code[i] = insn;
+ i += insn_len(insn);
+ }
+ }
+#endif
+ return original_code;
+}
+
+/*********************************************/
+/* definition of data structure for compiler */
+/*********************************************/
+
+/*
+ * On 32-bit SPARC, GCC by default generates SPARC V7 code that may require
+ * 8-byte word alignment. On the other hand, Oracle Solaris Studio seems to
+ * generate SPARCV8PLUS code with unaligned memory access instructions.
+ * That is why the STRICT_ALIGNMENT is defined only with GCC.
+ */
+#if defined(__sparc) && SIZEOF_VOIDP == 4 && defined(__GNUC__)
+ #define STRICT_ALIGNMENT
+#endif
+
+#ifdef STRICT_ALIGNMENT
+ #if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE
+ #define ALIGNMENT_SIZE SIZEOF_LONG_LONG
+ #else
+ #define ALIGNMENT_SIZE SIZEOF_VALUE
+ #endif
+ #define PADDING_SIZE_MAX ((size_t)((ALIGNMENT_SIZE) - 1))
+ #define ALIGNMENT_SIZE_MASK PADDING_SIZE_MAX
+ /* Note: ALIGNMENT_SIZE == (2 ** N) is expected. */
+#else
+ #define PADDING_SIZE_MAX 0
+#endif /* STRICT_ALIGNMENT */
+
+#ifdef STRICT_ALIGNMENT
+/* calculate padding size for aligned memory access */
+static size_t
+calc_padding(void *ptr, size_t size)
+{
+ size_t mis;
+ size_t padding = 0;
+
+ mis = (size_t)ptr & ALIGNMENT_SIZE_MASK;
+ if (mis > 0) {
+ padding = ALIGNMENT_SIZE - mis;
+ }
+/*
+ * On 32-bit sparc or equivalents, when a single VALUE is requested
+ * and padding == sizeof(VALUE), it is clear that no padding is needed.
+ */
+#if ALIGNMENT_SIZE > SIZEOF_VALUE
+ if (size == sizeof(VALUE) && padding == sizeof(VALUE)) {
+ padding = 0;
+ }
+#endif
+
+ return padding;
+}
+#endif /* STRICT_ALIGNMENT */
+
+static void *
+compile_data_alloc(rb_iseq_t *iseq, size_t size)
+{
+ void *ptr = 0;
+ struct iseq_compile_data_storage *storage =
+ ISEQ_COMPILE_DATA(iseq)->storage_current;
+#ifdef STRICT_ALIGNMENT
+ size_t padding = calc_padding((void *)&storage->buff[storage->pos], size);
+#else
+ const size_t padding = 0; /* expected to be optimized by compiler */
+#endif /* STRICT_ALIGNMENT */
+
+ if (size >= INT_MAX - padding) rb_memerror();
+ if (storage->pos + size + padding > storage->size) {
+ unsigned int alloc_size = storage->size;
+
+ while (alloc_size < size + PADDING_SIZE_MAX) {
+ if (alloc_size >= INT_MAX / 2) rb_memerror();
+ 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;
+ storage->next = 0;
+ storage->pos = 0;
+ storage->size = alloc_size;
+#ifdef STRICT_ALIGNMENT
+ padding = calc_padding((void *)&storage->buff[storage->pos], size);
+#endif /* STRICT_ALIGNMENT */
+ }
+
+#ifdef STRICT_ALIGNMENT
+ storage->pos += (int)padding;
+#endif /* STRICT_ALIGNMENT */
+
+ ptr = (void *)&storage->buff[storage->pos];
+ storage->pos += (int)size;
+ return ptr;
+}
+
+static INSN *
+compile_data_alloc_insn(rb_iseq_t *iseq)
+{
+ return (INSN *)compile_data_alloc(iseq, sizeof(INSN));
+}
+
+static LABEL *
+compile_data_alloc_label(rb_iseq_t *iseq)
+{
+ return (LABEL *)compile_data_alloc(iseq, sizeof(LABEL));
+}
+
+static ADJUST *
+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
+ELEM_INSERT_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+{
+ elem2->next = elem1->next;
+ elem2->prev = elem1;
+ elem1->next = elem2;
+ if (elem2->next) {
+ elem2->next->prev = elem2;
+ }
+}
+
+/*
+ * elem1, elemX => elemX, elem2, elem1
+ */
+static void
+ELEM_INSERT_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+{
+ elem2->prev = elem1->prev;
+ elem2->next = elem1;
+ elem1->prev = elem2;
+ if (elem2->prev) {
+ elem2->prev->next = elem2;
+ }
+}
+
+/*
+ * elemX, elem1, elemY => elemX, elem2, elemY
+ */
+static void
+ELEM_REPLACE(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
+{
+ elem2->prev = elem1->prev;
+ elem2->next = elem1->next;
+ if (elem1->prev) {
+ elem1->prev->next = elem2;
+ }
+ if (elem1->next) {
+ elem1->next->prev = elem2;
+ }
+}
+
+static void
+ELEM_REMOVE(LINK_ELEMENT *elem)
+{
+ elem->prev->next = elem->next;
+ if (elem->next) {
+ elem->next->prev = elem->prev;
+ }
+}
+
+static LINK_ELEMENT *
+FIRST_ELEMENT(const LINK_ANCHOR *const anchor)
+{
+ return anchor->anchor.next;
+}
+
+static LINK_ELEMENT *
+LAST_ELEMENT(LINK_ANCHOR *const anchor)
+{
+ return anchor->last;
+}
+
+static LINK_ELEMENT *
+POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *const anchor)
+{
+ LINK_ELEMENT *elem = anchor->last;
+ anchor->last = anchor->last->prev;
+ anchor->last->next = 0;
+ verify_list("pop", anchor);
+ return elem;
+}
+#if CPDEBUG < 0
+#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_INSN_SIZE_ONE(const LINK_ANCHOR *const anchor)
+{
+ 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 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;
+ }
+}
+
+/*
+ * anc1: e1, e2, e3
+ * anc2: e4, e5
+ *#=>
+ * anc1: e1, e2, e3, e4, e5
+ * anc2: e4, e5 (broken)
+ */
+static void
+APPEND_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *const anc1, LINK_ANCHOR *const anc2)
+{
+ if (anc2->anchor.next) {
+ anc1->last->next = anc2->anchor.next;
+ anc2->anchor.next->prev = anc1->last;
+ anc1->last = anc2->last;
+ }
+ verify_list("append", anc1);
+}
+#if CPDEBUG < 0
+#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)
+{
+ LINK_ELEMENT *list = FIRST_ELEMENT(anchor);
+ printf("----\n");
+ printf("anch: %p, frst: %p, last: %p\n", &anchor->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 = list->next;
+ }
+ printf("----\n");
+
+ dump_disasm_list(anchor->anchor.next);
+ verify_list("debug list", anchor);
+}
+#if CPDEBUG < 0
+#define debug_list(anc) debug_list(iseq, (anc))
+#endif
+#else
+#define debug_list(anc) ((void)0)
+#endif
+
+static TRACE *
+new_trace_body(rb_iseq_t *iseq, rb_event_flag_t event)
+{
+ TRACE *trace = compile_data_alloc_trace(iseq);
+
+ trace->link.type = ISEQ_ELEMENT_TRACE;
+ trace->link.next = NULL;
+ trace->event = event;
+
+ return trace;
+}
+
+static LABEL *
+new_label_body(rb_iseq_t *iseq, long line)
+{
+ LABEL *labelobj = compile_data_alloc_label(iseq);
+
+ labelobj->link.type = ISEQ_ELEMENT_LABEL;
+ labelobj->link.next = 0;
+
+ labelobj->label_no = ISEQ_COMPILE_DATA(iseq)->label_no++;
+ labelobj->sc_state = 0;
+ labelobj->sp = -1;
+ labelobj->refcnt = 0;
+ labelobj->set = 0;
+ labelobj->rescued = LABEL_RESCUE_NONE;
+ labelobj->unremovable = 0;
+ return labelobj;
+}
+
+static ADJUST *
+new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
+{
+ ADJUST *adjust = compile_data_alloc_adjust(iseq);
+ adjust->link.type = ISEQ_ELEMENT_ADJUST;
+ adjust->link.next = 0;
+ adjust->label = label;
+ adjust->line_no = line;
+ LABEL_UNREMOVABLE(label);
+ return adjust;
+}
+
+static INSN *
+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->insn_info.line_no = line_no;
+ iobj->insn_info.events = 0;
+ iobj->operands = argv;
+ iobj->operand_size = argc;
+ iobj->sc_state = 0;
+ return iobj;
+}
+
+static INSN *
+new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int argc, ...)
+{
+ VALUE *operands = 0;
+ va_list argv;
+ if (argc > 0) {
+ int i;
+ va_init_list(argv, argc);
+ operands = (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ for (i = 0; i < argc; i++) {
+ VALUE v = va_arg(argv, VALUE);
+ operands[i] = v;
+ }
+ va_end(argv);
+ }
+ 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)
+{
+ 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;
+
+ ci->mid = mid;
+ ci->flag = flag;
+ ci->orig_argc = argc;
+
+ 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++;
+ }
+
+ 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;
+ }
+ 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)
+{
+ 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);
+}
+
+static rb_iseq_t *
+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;
+
+ debugs("[new_child_iseq]> ---------------------------------------\n");
+ ret_iseq = rb_iseq_new_with_opt(node, name,
+ rb_iseq_path(iseq), rb_iseq_realpath(iseq),
+ INT2FIX(line_no), parent, type, ISEQ_COMPILE_DATA(iseq)->option);
+ debugs("[new_child_iseq]< ---------------------------------------\n");
+ iseq_add_mark_object(iseq, (VALUE)ret_iseq);
+ return ret_iseq;
+}
+
+static void
+iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq)
+{
+ VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ unsigned int i, tlen = (unsigned int)RARRAY_LEN(catch_table_ary);
+ const VALUE *tptr = RARRAY_CONST_PTR(catch_table_ary);
+ for (i = 0; i < tlen; i++) {
+ const VALUE *ptr = RARRAY_CONST_PTR(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_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+ if (RTEST(ISEQ_COMPILE_DATA(iseq)->err_info))
+ return COMPILE_NG;
+
+ /* debugs("[compile step 2] (iseq_array_to_linkedlist)\n"); */
+
+ if (compile_debug > 5)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+
+ debugs("[compile step 3.1 (iseq_optimize)]\n");
+ iseq_optimize(iseq, anchor);
+
+ if (compile_debug > 5)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+
+ if (ISEQ_COMPILE_DATA(iseq)->option->instructions_unification) {
+ debugs("[compile step 3.2 (iseq_insns_unification)]\n");
+ iseq_insns_unification(iseq, anchor);
+ if (compile_debug > 5)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+ }
+
+ if (ISEQ_COMPILE_DATA(iseq)->option->stack_caching) {
+ debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
+ iseq_set_sequence_stackcaching(iseq, anchor);
+ if (compile_debug > 5)
+ 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);
+
+ 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)
+ dump_disasm_list(FIRST_ELEMENT(anchor));
+
+ debugs("[compile step 4.2 (iseq_set_exception_table)]\n");
+ if (!iseq_set_exception_table(iseq)) return COMPILE_NG;
+
+ debugs("[compile step 4.3 (set_optargs_table)] \n");
+ if (!iseq_set_optargs_table(iseq)) return COMPILE_NG;
+
+ debugs("[compile step 5 (iseq_translate_threaded_code)] \n");
+ if (!rb_iseq_translate_threaded_code(iseq)) return COMPILE_NG;
+
+ if (compile_debug > 1) {
+ VALUE str = rb_iseq_disasm(iseq);
+ printf("%s\n", StringValueCStr(str));
+ }
+ debugs("[compile step: finish]\n");
+
+ return COMPILE_OK;
+}
+
+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;
+ return COMPILE_OK;
+}
+
+static int
+get_lvar_level(const rb_iseq_t *iseq)
+{
+ int lev = 0;
+ while (iseq != iseq->body->local_iseq) {
+ lev++;
+ iseq = iseq->body->parent_iseq;
+ }
+ return lev;
+}
+
+static int
+get_dyna_var_idx_at_raw(const rb_iseq_t *iseq, ID id)
+{
+ unsigned int i;
+
+ for (i = 0; i < iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
+ return (int)i;
+ }
+ }
+ return -1;
+}
+
+static int
+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);
+ }
+
+ return idx;
+}
+
+static int
+get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
+{
+ int lv = 0, idx = -1;
+
+ while (iseq) {
+ idx = get_dyna_var_idx_at_raw(iseq, id);
+ if (idx >= 0) {
+ break;
+ }
+ iseq = iseq->body->parent_iseq;
+ lv++;
+ }
+
+ if (idx < 0) {
+ rb_bug("get_dyna_var_idx: -1");
+ }
+
+ *level = lv;
+ *ls = iseq->body->local_table_size;
+ return idx;
+}
+
+static int
+iseq_local_block_param_p(const rb_iseq_t *iseq, unsigned int idx, unsigned int level)
+{
+ while (level > 0) {
+ iseq = iseq->body->parent_iseq;
+ level--;
+ }
+ if (iseq->body->local_iseq == iseq && /* local variables */
+ iseq->body->param.flags.has_block &&
+ iseq->body->local_table_size - iseq->body->param.block_start == idx) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+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));
+ }
+}
+
+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));
+ }
+}
+
+
+
+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) {
+
+ if (iseq->body->param.flags.has_block) {
+ iseq->body->param.size = iseq->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 (iseq->body->param.flags.has_kw) {
+ iseq->body->param.size = iseq->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 (iseq->body->param.flags.has_rest) {
+ iseq->body->param.size = iseq->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 {
+ rb_bug("unreachable");
+ }
+ }
+ else {
+ iseq->body->param.size = iseq->body->param.lead_num;
+ }
+}
+
+static void
+iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
+ const struct rb_args_info *args)
+{
+ const NODE *node = args->kw_args;
+ 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);
+
+ while (node) {
+ const NODE *val_node = node->nd_body->nd_value;
+ VALUE dv;
+
+ if (val_node == (const NODE *)-1) {
+ ++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;
+ break;
+ case NODE_TRUE:
+ dv = Qtrue;
+ break;
+ case NODE_FALSE:
+ dv = Qfalse;
+ break;
+ default:
+ COMPILE_POPPED(optargs, "kwarg", node); /* nd_type(node) == NODE_KW_ARG */
+ dv = complex_mark;
+ }
+
+ keyword->num = ++di;
+ 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->required_num = rkw;
+ keyword->table = &iseq->body->local_table[keyword->bits_start - keyword->num];
+
+ {
+ VALUE *dvs = ALLOC_N(VALUE, RARRAY_LEN(default_values));
+
+ for (i = 0; i < RARRAY_LEN(default_values); i++) {
+ VALUE dv = RARRAY_AREF(default_values, i);
+ if (dv == complex_mark) dv = Qundef;
+ dvs[i] = dv;
+ }
+
+ keyword->default_values = dvs;
+ }
+}
+
+static int
+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_args_info *args = node_args->nd_ainfo;
+ ID rest_id = 0;
+ int last_comma = 0;
+ ID block_id = 0;
+
+ 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);
+
+ rest_id = args->rest_arg;
+ if (rest_id == 1) {
+ 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) {
+ const NODE *node = args->opt_args;
+ LABEL *label;
+ VALUE labels = rb_ary_tmp_new(1);
+ VALUE *opt_table;
+ int i = 0, j;
+
+ while (node) {
+ label = NEW_LABEL(nd_line(node));
+ rb_ary_push(labels, (VALUE)label | 1);
+ ADD_LABEL(optargs, label);
+ COMPILE_POPPED(optargs, "optarg", node->nd_body);
+ node = node->nd_next;
+ i += 1;
+ }
+
+ /* last label */
+ label = NEW_LABEL(nd_line(node_args));
+ rb_ary_push(labels, (VALUE)label | 1);
+ ADD_LABEL(optargs, label);
+
+ opt_table = ALLOC_N(VALUE, i+1);
+
+ MEMCPY(opt_table, RARRAY_CONST_PTR(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;
+ }
+
+ if (args->kw_args) {
+ iseq_set_arguments_keywords(iseq, optargs, args);
+ }
+ 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->pre_init) { /* m_init */
+ COMPILE_POPPED(optargs, "init arguments (m)", args->pre_init);
+ }
+ if (args->post_init) { /* p_init */
+ COMPILE_POPPED(optargs, "init arguments (p)", args->post_init);
+ }
+
+ 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;
+ }
+ }
+
+ if (block_id) {
+ iseq->body->param.block_start = get_dyna_var_idx_at_raw(iseq, block_id);
+ iseq->body->param.flags.has_block = TRUE;
+ }
+
+ iseq_calc_param_size(iseq);
+
+ 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 (iseq->body->param.lead_num == 1 && last_comma == 0) {
+ /* {|a|} */
+ iseq->body->param.flags.ambiguous_param0 = TRUE;
+ }
+ }
+ }
+ }
+
+ return COMPILE_OK;
+}
+
+static int
+iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
+{
+ unsigned int size;
+
+ if (tbl) {
+ size = (unsigned int)*tbl;
+ tbl++;
+ }
+ else {
+ size = 0;
+ }
+
+ if (size > 0) {
+ ID *ids = (ID *)ALLOC_N(ID, size);
+ MEMCPY(ids, tbl, ID, size);
+ iseq->body->local_table = ids;
+ }
+ iseq->body->local_table_size = size;
+
+ debugs("iseq_set_local_table: %u\n", iseq->body->local_table_size);
+ return COMPILE_OK;
+}
+
+static int
+cdhash_cmp(VALUE val, VALUE lit)
+{
+ if (val == lit) return 0;
+ if (SPECIAL_CONST_P(lit)) {
+ return val != lit;
+ }
+ if (SPECIAL_CONST_P(val) || BUILTIN_TYPE(val) != BUILTIN_TYPE(lit)) {
+ return -1;
+ }
+ if (BUILTIN_TYPE(lit) == T_STRING) {
+ return rb_str_hash_cmp(lit, val);
+ }
+ 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);
+ }
+}
+
+static const struct st_hash_type cdhash_type = {
+ cdhash_cmp,
+ cdhash_hash,
+};
+
+struct cdhash_set_label_struct {
+ VALUE hash;
+ int pos;
+ int len;
+};
+
+static int
+cdhash_set_label_i(VALUE key, VALUE val, void *ptr)
+{
+ struct cdhash_set_label_struct *data = (struct cdhash_set_label_struct *)ptr;
+ LABEL *lobj = (LABEL *)(val & ~1);
+ rb_hash_aset(data->hash, key, INT2FIX(lobj->position - (data->pos+data->len)));
+ return ST_CONTINUE;
+}
+
+
+static inline VALUE
+get_ivar_ic_value(rb_iseq_t *iseq,ID id)
+{
+ VALUE val;
+ struct rb_id_table *tbl = ISEQ_COMPILE_DATA(iseq)->ivar_cache_table;
+ if (tbl) {
+ if (rb_id_table_lookup(tbl,id,&val)) {
+ return val;
+ }
+ }
+ else {
+ tbl = rb_id_table_create(1);
+ ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = tbl;
+ }
+ val = INT2FIX(iseq->body->is_size++);
+ rb_id_table_insert(tbl,id,val);
+ return val;
+}
+
+#define BADINSN_DUMP(anchor, list, dest) \
+ dump_disasm_list_with_cursor(&anchor->anchor, list, dest)
+
+#define BADINSN_ERROR \
+ (xfree(generated_iseq), \
+ xfree(insns_info), \
+ BADINSN_DUMP(anchor, list, NULL), \
+ COMPILE_ERROR)
+
+static int
+fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+ int stack_max = 0, sp = 0, line = 0;
+ LINK_ELEMENT *list;
+
+ for (list = FIRST_ELEMENT(anchor); list; list = list->next) {
+ if (list->type == ISEQ_ELEMENT_LABEL) {
+ LABEL *lobj = (LABEL *)list;
+ lobj->set = TRUE;
+ }
+ }
+
+ for (list = FIRST_ELEMENT(anchor); list; list = list->next) {
+ switch (list->type) {
+ case ISEQ_ELEMENT_INSN:
+ {
+ int j, len, insn;
+ const char *types;
+ VALUE *operands;
+ INSN *iobj = (INSN *)list;
+
+ /* update sp */
+ sp = calc_sp_depth(sp, iobj);
+ if (sp < 0) {
+ BADINSN_DUMP(anchor, list, NULL);
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "argument stack underflow (%d)", sp);
+ return -1;
+ }
+ if (sp > stack_max) {
+ stack_max = sp;
+ }
+
+ 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;
+ types = insn_op_types(insn);
+ len = insn_len(insn);
+
+ /* operand check */
+ 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->insn_info.line_no,
+ "operand size miss! (%d for %d)",
+ iobj->operand_size, len - 1);
+ return -1;
+ }
+
+ for (j = 0; types[j]; j++) {
+ if (types[j] == TS_OFFSET) {
+ /* label(destination position) */
+ LABEL *lobj = (LABEL *)operands[j];
+ if (!lobj->set) {
+ BADINSN_DUMP(anchor, list, NULL);
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "unknown label: "LABEL_FORMAT, lobj->label_no);
+ return -1;
+ }
+ if (lobj->sp == -1) {
+ lobj->sp = sp;
+ }
+ }
+ }
+ break;
+ }
+ case ISEQ_ELEMENT_LABEL:
+ {
+ LABEL *lobj = (LABEL *)list;
+ if (lobj->sp == -1) {
+ lobj->sp = sp;
+ }
+ else {
+ sp = lobj->sp;
+ }
+ break;
+ }
+ case ISEQ_ELEMENT_TRACE:
+ {
+ /* ignore */
+ break;
+ }
+ case ISEQ_ELEMENT_ADJUST:
+ {
+ ADJUST *adjust = (ADJUST *)list;
+ int orig_sp = sp;
+
+ sp = adjust->label ? adjust->label->sp : 0;
+ if (adjust->line_no != -1 && orig_sp - sp < 0) {
+ BADINSN_DUMP(anchor, list, NULL);
+ COMPILE_ERROR(iseq, adjust->line_no,
+ "iseq_set_sequence: adjust bug %d < %d",
+ orig_sp, sp);
+ return -1;
+ }
+ break;
+ }
+ default:
+ BADINSN_DUMP(anchor, list, NULL);
+ COMPILE_ERROR(iseq, line, "unknown list type: %d", list->type);
+ return -1;
+ }
+ }
+ return stack_max;
+}
+
+static int
+add_insn_info(struct iseq_insn_info_entry *insns_info, int insns_info_index, int code_index, LINK_ELEMENT *list)
+{
+ if (list->type == ISEQ_ELEMENT_INSN) {
+ INSN *iobj = (INSN *)list;
+ 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].position = code_index;
+ insns_info[insns_info_index].line_no = iobj->insn_info.line_no;
+ insns_info[insns_info_index].events = iobj->insn_info.events;
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+ }
+ else if (list->type == ISEQ_ELEMENT_ADJUST) {
+ ADJUST *adjust = (ADJUST *)list;
+ if (insns_info_index > 0 ||
+ insns_info[insns_info_index-1].line_no != adjust->line_no) {
+ insns_info[insns_info_index].position = code_index;
+ insns_info[insns_info_index].line_no = adjust->line_no;
+ insns_info[insns_info_index].events = 0;
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+ }
+ else {
+ VM_UNREACHABLE(add_insn_info);
+ }
+}
+
+/**
+ ruby insn object list -> raw instruction sequence
+ */
+static int
+iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+ struct iseq_insn_info_entry *insns_info;
+ LINK_ELEMENT *list;
+ VALUE *generated_iseq;
+ rb_event_flag_t events = 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) {
+ 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++;
+ iobj->insn_info.events |= events;
+ events = 0;
+ break;
+ }
+ case ISEQ_ELEMENT_LABEL:
+ {
+ LABEL *lobj = (LABEL *)list;
+ lobj->position = code_index;
+ sp = lobj->sp;
+ break;
+ }
+ case ISEQ_ELEMENT_TRACE:
+ {
+ TRACE *trace = (TRACE *)list;
+ events |= trace->event;
+ break;
+ }
+ case ISEQ_ELEMENT_ADJUST:
+ {
+ ADJUST *adjust = (ADJUST *)list;
+ if (adjust->line_no != -1) {
+ int orig_sp = sp;
+ sp = adjust->label ? adjust->label->sp : 0;
+ if (orig_sp - sp > 0) {
+ if (orig_sp - sp > 1) code_index++; /* 1 operand */
+ code_index++; /* insn */
+ insn_num++;
+ }
+ }
+ break;
+ }
+ }
+ list = list->next;
+ }
+
+ /* make instruction sequence */
+ generated_iseq = ALLOC_N(VALUE, code_index);
+ insns_info = ALLOC_N(struct iseq_insn_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);
+ MEMZERO(iseq->body->ci_entries + iseq->body->ci_size, struct rb_call_info_with_kwarg, iseq->body->ci_kw_size); /* need to clear ci_kw entries */
+ 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;
+
+ list = FIRST_ELEMENT(anchor);
+ insns_info_index = code_index = sp = 0;
+
+ while (list) {
+ switch (list->type) {
+ case ISEQ_ELEMENT_INSN:
+ {
+ int j, len, insn;
+ const char *types;
+ VALUE *operands;
+ INSN *iobj = (INSN *)list;
+
+ /* update sp */
+ sp = calc_sp_depth(sp, iobj);
+ /* fprintf(stderr, "insn: %-16s, sp: %d\n", insn_name(iobj->insn_id), sp); */
+ operands = iobj->operands;
+ insn = iobj->insn_id;
+ generated_iseq[code_index] = insn;
+ types = insn_op_types(insn);
+ len = insn_len(insn);
+
+ for (j = 0; types[j]; j++) {
+ char type = types[j];
+ /* printf("--> [%c - (%d-%d)]\n", type, k, j); */
+ switch (type) {
+ case TS_OFFSET:
+ {
+ /* label(destination position) */
+ LABEL *lobj = (LABEL *)operands[j];
+ generated_iseq[code_index + 1 + j] = lobj->position - (code_index + len);
+ break;
+ }
+ case TS_CDHASH:
+ {
+ VALUE map = operands[j];
+ struct cdhash_set_label_struct data;
+ data.hash = map;
+ data.pos = code_index;
+ data.len = len;
+ rb_hash_foreach(map, cdhash_set_label_i, (VALUE)&data);
+
+ rb_hash_rehash(map);
+ freeze_hide_obj(map);
+ generated_iseq[code_index + 1 + j] = map;
+ 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 */
+ {
+ VALUE v = operands[j];
+ generated_iseq[code_index + 1 + j] = v;
+ /* to mark ruby object */
+ iseq_add_mark_object(iseq, v);
+ break;
+ }
+ case TS_IC: /* inline 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);
+ }
+ generated_iseq[code_index + 1 + j] = (VALUE)ic;
+ 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_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;
+ default:
+ BADINSN_ERROR(iseq, iobj->insn_info.line_no,
+ "unknown operand type: %c", type);
+ return COMPILE_NG;
+ }
+ }
+ if (add_insn_info(insns_info, insns_info_index, code_index, (LINK_ELEMENT *)iobj)) insns_info_index++;
+ code_index += len;
+ break;
+ }
+ case ISEQ_ELEMENT_LABEL:
+ {
+ LABEL *lobj = (LABEL *)list;
+ sp = lobj->sp;
+ break;
+ }
+ case ISEQ_ELEMENT_ADJUST:
+ {
+ ADJUST *adjust = (ADJUST *)list;
+ int orig_sp = sp;
+
+ if (adjust->label) {
+ sp = adjust->label->sp;
+ }
+ else {
+ sp = 0;
+ }
+
+ if (adjust->line_no != -1) {
+ const int diff = orig_sp - sp;
+ if (diff > 0) {
+ if (add_insn_info(insns_info, insns_info_index, code_index, (LINK_ELEMENT *)adjust)) insns_info_index++;
+ }
+ if (diff > 1) {
+ generated_iseq[code_index++] = BIN(adjuststack);
+ generated_iseq[code_index++] = orig_sp - sp;
+ }
+ else if (diff == 1) {
+ generated_iseq[code_index++] = BIN(pop);
+ }
+ else if (diff < 0) {
+ int label_no = adjust->label ? adjust->label->label_no : -1;
+ xfree(generated_iseq);
+ xfree(insns_info);
+ debug_list(anchor);
+ COMPILE_ERROR(iseq, adjust->line_no,
+ "iseq_set_sequence: adjust bug to %d %d < %d",
+ label_no, orig_sp, sp);
+ return COMPILE_NG;
+ }
+ }
+ break;
+ }
+ default:
+ /* ignore */
+ break;
+ }
+ list = list->next;
+ }
+
+ iseq->body->iseq_encoded = (void *)generated_iseq;
+ iseq->body->iseq_size = code_index;
+ iseq->body->stack_max = stack_max;
+
+ /* get rid of memory leak when REALLOC failed */
+ iseq->body->insns_info = insns_info;
+
+ REALLOC_N(insns_info, struct iseq_insn_info_entry, insns_info_index);
+ iseq->body->insns_info = insns_info;
+ iseq->body->insns_info_size = insns_info_index;
+
+ return COMPILE_OK;
+}
+
+static int
+label_get_position(LABEL *lobj)
+{
+ return lobj->position;
+}
+
+static int
+label_get_sp(LABEL *lobj)
+{
+ return lobj->sp;
+}
+
+static int
+iseq_set_exception_table(rb_iseq_t *iseq)
+{
+ const VALUE *tptr, *ptr;
+ unsigned int tlen, i;
+ struct iseq_catch_table_entry *entry;
+
+ tlen = (int)RARRAY_LEN(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
+ tptr = RARRAY_CONST_PTR(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];
+ 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);
+ }
+
+ /* stack depth */
+ if (ptr[4]) {
+ LABEL *lobj = (LABEL *)(ptr[4] & ~1);
+ entry->cont = label_get_position(lobj);
+ entry->sp = label_get_sp(lobj);
+
+ /* TODO: Dirty Hack! Fix me */
+ if (entry->type == CATCH_TYPE_RESCUE ||
+ entry->type == CATCH_TYPE_BREAK ||
+ entry->type == CATCH_TYPE_NEXT) {
+ entry->sp--;
+ }
+ }
+ else {
+ entry->cont = 0;
+ }
+ }
+ 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;
+}
+
+/*
+ * set optional argument table
+ * def foo(a, b=expr1, c=expr2)
+ * =>
+ * b:
+ * expr1
+ * c:
+ * expr2
+ */
+static int
+iseq_set_optargs_table(rb_iseq_t *iseq)
+{
+ int i;
+ VALUE *opt_table = (VALUE *)iseq->body->param.opt_table;
+
+ if (iseq->body->param.flags.has_opt) {
+ for (i = 0; i < iseq->body->param.opt_num + 1; i++) {
+ opt_table[i] = label_get_position((LABEL *)opt_table[i]);
+ }
+ }
+ return COMPILE_OK;
+}
+
+static LINK_ELEMENT *
+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) {
+ 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;
+ }
+ list = list->next;
+ }
+ found:
+ if (list && IS_INSN(list)) {
+ INSN *iobj = (INSN *)list;
+ iobj->insn_info.events |= events;
+ }
+ return list;
+}
+
+static LINK_ELEMENT *
+get_next_insn(INSN *iobj)
+{
+ LINK_ELEMENT *list = iobj->link.next;
+
+ while (list) {
+ if (IS_INSN(list) || IS_ADJUST(list)) {
+ return list;
+ }
+ list = list->next;
+ }
+ return 0;
+}
+
+static LINK_ELEMENT *
+get_prev_insn(INSN *iobj)
+{
+ LINK_ELEMENT *list = iobj->link.prev;
+
+ while (list) {
+ if (IS_INSN(list) || IS_ADJUST(list)) {
+ return list;
+ }
+ list = list->prev;
+ }
+ return 0;
+}
+
+static void
+unref_destination(INSN *iobj, int pos)
+{
+ LABEL *lobj = (LABEL *)OPERAND_AT(iobj, pos);
+ --lobj->refcnt;
+ if (!lobj->refcnt) ELEM_REMOVE(&lobj->link);
+}
+
+static void
+replace_destination(INSN *dobj, INSN *nobj)
+{
+ VALUE n = OPERAND_AT(nobj, 0);
+ LABEL *dl = (LABEL *)OPERAND_AT(dobj, 0);
+ LABEL *nl = (LABEL *)n;
+ --dl->refcnt;
+ ++nl->refcnt;
+ OPERAND_AT(dobj, 0) = n;
+ 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;
+ 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, 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)) {
+ lab = (LABEL *)i;
+ if (lab->unremovable) return 0;
+ if (lab->refcnt > unref_counts[lab->label_no]) {
+ if (i == first) return 0;
+ break;
+ }
+ continue;
+ }
+ 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)) {
+ struct rb_iseq_constant_body *body = iseq->body;
+ VALUE insn = INSN_OF(i);
+ int pos, len = insn_len(insn);
+ for (pos = 0; pos < len; ++pos) {
+ switch (insn_op_types(insn)[pos]) {
+ 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);
+ break;
+ }
+ }
+ }
+ ELEM_REMOVE(i);
+ } while ((i != end) && (i = i->next) != 0);
+ return 1;
+}
+
+static int
+iseq_pop_newarray(rb_iseq_t *iseq, INSN *iobj)
+{
+ switch (OPERAND_AT(iobj, 0)) {
+ case INT2FIX(0): /* empty array */
+ ELEM_REMOVE(&iobj->link);
+ return TRUE;
+ case INT2FIX(1): /* single element array */
+ ELEM_REMOVE(&iobj->link);
+ return FALSE;
+ default:
+ iobj->insn_id = BIN(adjuststack);
+ return TRUE;
+ }
+}
+
+static int
+same_debug_pos_p(LINK_ELEMENT *iobj1, LINK_ELEMENT *iobj2)
+{
+ VALUE debug1 = OPERAND_AT(iobj1, 0);
+ VALUE debug2 = OPERAND_AT(iobj2, 0);
+ if (debug1 == debug2) return TRUE;
+ if (!RB_TYPE_P(debug1, T_ARRAY)) return FALSE;
+ if (!RB_TYPE_P(debug2, T_ARRAY)) return FALSE;
+ if (RARRAY_LEN(debug1) != 2) return FALSE;
+ if (RARRAY_LEN(debug2) != 2) return FALSE;
+ if (RARRAY_AREF(debug1, 0) != RARRAY_AREF(debug2, 0)) return FALSE;
+ if (RARRAY_AREF(debug1, 1) != RARRAY_AREF(debug2, 1)) return FALSE;
+ return TRUE;
+}
+
+static int
+iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt)
+{
+ INSN *const iobj = (INSN *)list;
+ again:
+ if (IS_INSN_ID(iobj, jump)) {
+ INSN *niobj, *diobj, *piobj;
+ diobj = (INSN *)get_destination_insn(iobj);
+ niobj = (INSN *)get_next_insn(iobj);
+
+ if (diobj == niobj) {
+ /*
+ * jump LABEL
+ * LABEL:
+ * =>
+ * LABEL:
+ */
+ unref_destination(iobj, 0);
+ ELEM_REMOVE(&iobj->link);
+ return COMPILE_OK;
+ }
+ else if (iobj != diobj && IS_INSN_ID(diobj, jump) &&
+ OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) {
+ /*
+ * useless jump elimination:
+ * jump LABEL1
+ * ...
+ * LABEL1:
+ * jump LABEL2
+ *
+ * => in this case, first jump instruction should jump to
+ * LABEL2 directly
+ */
+ replace_destination(iobj, diobj);
+ remove_unreachable_chunk(iseq, iobj->link.next);
+ goto again;
+ }
+ else if (IS_INSN_ID(diobj, leave)) {
+ INSN *pop;
+ /*
+ * jump LABEL
+ * ...
+ * LABEL:
+ * leave
+ * =>
+ * leave
+ * pop
+ * ...
+ * LABEL:
+ * leave
+ */
+ /* replace */
+ unref_destination(iobj, 0);
+ iobj->insn_id = BIN(leave);
+ iobj->operand_size = 0;
+ iobj->insn_info = diobj->insn_info;
+ /* adjust stack depth */
+ pop = new_insn_body(iseq, diobj->insn_info.line_no, BIN(pop), 0);
+ ELEM_INSERT_NEXT(&iobj->link, &pop->link);
+ goto again;
+ }
+ 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
+ * jump L2
+ * L1:
+ * ...
+ * L2:
+ *
+ * ==>
+ * unless L2
+ * L1:
+ * ...
+ * L2:
+ */
+ piobj->insn_id = (IS_INSN_ID(piobj, branchif))
+ ? BIN(branchunless) : BIN(branchif);
+ replace_destination(piobj, iobj);
+ if (refcnt <= 1) {
+ ELEM_REMOVE(&iobj->link);
+ }
+ else {
+ /* TODO: replace other branch destinations too */
+ }
+ return COMPILE_OK;
+ }
+ else if (diobj == pdiobj) {
+ /*
+ * useless jump elimination (if/unless before jump):
+ * L1:
+ * ...
+ * if L1
+ * jump L1
+ *
+ * ==>
+ * L1:
+ * ...
+ * pop
+ * jump L1
+ */
+ INSN *popiobj = new_insn_core(iseq, iobj->insn_info.line_no,
+ BIN(pop), 0, 0);
+ ELEM_REPLACE(&piobj->link, &popiobj->link);
+ }
+ }
+ if (remove_unreachable_chunk(iseq, iobj->link.next)) {
+ goto again;
+ }
+ }
+
+ /*
+ * putstring "beg"
+ * putstring "end"
+ * newrange excl
+ *
+ * ==>
+ *
+ * putobject "beg".."end"
+ */
+ if (IS_INSN_ID(iobj, checkmatch)) {
+ INSN *range = (INSN *)get_prev_insn(iobj);
+ INSN *beg, *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);
+ 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);
+ ELEM_REMOVE(&beg->link);
+ ELEM_REMOVE(&end->link);
+ range->insn_id = BIN(putobject);
+ OPERAND_AT(range, 0) = lit_range;
+ }
+ }
+
+ if (IS_INSN_ID(iobj, leave)) {
+ remove_unreachable_chunk(iseq, iobj->link.next);
+ }
+
+ if (IS_INSN_ID(iobj, branchif) ||
+ IS_INSN_ID(iobj, branchnil) ||
+ IS_INSN_ID(iobj, branchunless)) {
+ /*
+ * if L1
+ * ...
+ * L1:
+ * jump L2
+ * =>
+ * 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)) {
+ 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)) {
+ /*
+ * putself / putnil / putobject obj / putstring "..."
+ * pop
+ * =>
+ * # do nothing
+ */
+ LINK_ELEMENT *prev = iobj->link.prev;
+ if (IS_INSN(prev)) {
+ enum ruby_vminsn_type previ = ((INSN *)prev)->insn_id;
+ if (previ == BIN(putobject) || previ == BIN(putnil) ||
+ previ == BIN(putself) || previ == BIN(putstring) ||
+ previ == BIN(duparray)) {
+ /* just push operand or static value and pop soon, no
+ * side effects */
+ ELEM_REMOVE(prev);
+ ELEM_REMOVE(&iobj->link);
+ }
+ else if (previ == BIN(newarray) && iseq_pop_newarray(iseq, (INSN*)prev)) {
+ ELEM_REMOVE(&iobj->link);
+ }
+ }
+ }
+
+ if (IS_INSN_ID(iobj, newarray) ||
+ IS_INSN_ID(iobj, duparray) ||
+ IS_INSN_ID(iobj, expandarray) ||
+ IS_INSN_ID(iobj, concatarray) ||
+ IS_INSN_ID(iobj, splatarray) ||
+ 0) {
+ /*
+ * newarray N
+ * splatarray
+ * =>
+ * newarray N
+ * newarray always puts an array
+ */
+ LINK_ELEMENT *next = iobj->link.next;
+ if (IS_INSN(next) && IS_INSN_ID(next, splatarray)) {
+ /* remove splatarray following always-array insn */
+ 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)) {
+ 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, *freeze = 0;
+ INSN *jump = 0;
+ if (IS_INSN(next) && IS_INSN_ID(next, freezestring))
+ next = (freeze = next)->next;
+ 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++;
+ if (freeze && IS_NEXT_INSN_ID(next, freezestring)) {
+ if (same_debug_pos_p(freeze, next->next)) {
+ ELEM_REMOVE(freeze);
+ }
+ else {
+ next = next->next;
+ }
+ }
+ ELEM_INSERT_NEXT(next, &label->link);
+ CHECK(iseq_peephole_optimize(iseq, get_next_insn(jump), do_tailcallopt));
+ }
+ else {
+ if (freeze) ELEM_REMOVE(freeze);
+ ELEM_REMOVE(next);
+ }
+ }
+ }
+
+ if (do_tailcallopt &&
+ (IS_INSN_ID(iobj, send) ||
+ IS_INSN_ID(iobj, opt_aref_with) ||
+ IS_INSN_ID(iobj, opt_aset_with) ||
+ IS_INSN_ID(iobj, invokesuper))) {
+ /*
+ * send ...
+ * leave
+ * =>
+ * send ..., ... | VM_CALL_TAILCALL, ...
+ * leave # unreachable
+ */
+ INSN *piobj = NULL;
+ if (iobj->link.next) {
+ LINK_ELEMENT *next = iobj->link.next;
+ do {
+ if (!IS_INSN(next)) {
+ next = next->next;
+ continue;
+ }
+ switch (INSN_OF(next)) {
+ case BIN(nop):
+ next = next->next;
+ break;
+ case BIN(jump):
+ /* if cond
+ * return tailcall
+ * end
+ */
+ next = get_destination_insn((INSN *)next);
+ break;
+ case BIN(leave):
+ piobj = iobj;
+ default:
+ next = NULL;
+ break;
+ }
+ } while (next);
+ }
+
+ 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;
+ }
+ }
+ else {
+ ci->flag |= VM_CALL_TAILCALL;
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+
+ return COMPILE_OK;
+}
+
+static int
+insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
+{
+ iobj->insn_id = insn_id;
+ iobj->operand_size = insn_len(insn_id) - 1;
+
+ 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 */
+ }
+
+ return COMPILE_OK;
+}
+
+static int
+iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
+{
+ if (IS_INSN_ID(iobj, newarray) && iobj->link.next &&
+ IS_INSN(iobj->link.next)) {
+ /*
+ * [a, b, ...].max/min -> a, b, c, opt_newarray_max/min
+ */
+ 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) {
+ case idMax:
+ iobj->insn_id = BIN(opt_newarray_max);
+ ELEM_REMOVE(&niobj->link);
+ return COMPILE_OK;
+ case idMin:
+ iobj->insn_id = BIN(opt_newarray_min);
+ ELEM_REMOVE(&niobj->link);
+ return COMPILE_OK;
+ }
+ }
+ }
+ }
+
+ 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);
+
+#define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
+ if (ci->flag & VM_CALL_ARGS_SIMPLE) {
+ switch (ci->orig_argc) {
+ case 0:
+ switch (ci->mid) {
+ 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 idSucc: SP_INSN(succ); return COMPILE_OK;
+ case idNot: SP_INSN(not); return COMPILE_OK;
+ }
+ break;
+ case 1:
+ switch (ci->mid) {
+ case idPLUS: SP_INSN(plus); return COMPILE_OK;
+ case idMINUS: SP_INSN(minus); return COMPILE_OK;
+ case idMULT: SP_INSN(mult); return COMPILE_OK;
+ case idDIV: SP_INSN(div); return COMPILE_OK;
+ 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 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;
+ }
+ break;
+ case 2:
+ switch (ci->mid) {
+ case idASET: SP_INSN(aset); return COMPILE_OK;
+ }
+ break;
+ }
+ }
+
+ if ((ci->flag & VM_CALL_ARGS_BLOCKARG) == 0 && blockiseq == NULL) {
+ iobj->insn_id = BIN(opt_send_without_block);
+ iobj->operand_size = insn_len(iobj->insn_id) - 1;
+ }
+ }
+#undef SP_INSN
+
+ return COMPILE_OK;
+}
+
+static inline int
+tailcallable_p(rb_iseq_t *iseq)
+{
+ switch (iseq->body->type) {
+ case ISEQ_TYPE_TOP:
+ case ISEQ_TYPE_EVAL:
+ case ISEQ_TYPE_MAIN:
+ /* not tail callable because cfp will be over popped */
+ case ISEQ_TYPE_RESCUE:
+ case ISEQ_TYPE_ENSURE:
+ /* rescue block can't tail call because of errinfo */
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+static int
+iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+ LINK_ELEMENT *list;
+ const int do_peepholeopt = ISEQ_COMPILE_DATA(iseq)->option->peephole_optimization;
+ const int do_tailcallopt = tailcallable_p(iseq) &&
+ ISEQ_COMPILE_DATA(iseq)->option->tailcall_optimization;
+ const int do_si = ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction;
+ const int do_ou = ISEQ_COMPILE_DATA(iseq)->option->operands_unification;
+ int rescue_level = 0;
+ int tailcallopt = do_tailcallopt;
+
+ list = FIRST_ELEMENT(anchor);
+
+ while (list) {
+ if (IS_INSN(list)) {
+ if (do_peepholeopt) {
+ iseq_peephole_optimize(iseq, list, tailcallopt);
+ }
+ if (do_si) {
+ iseq_specialized_instruction(iseq, (INSN *)list);
+ }
+ if (do_ou) {
+ insn_operands_unification((INSN *)list);
+ }
+ }
+ if (IS_LABEL(list)) {
+ switch (((LABEL *)list)->rescued) {
+ case LABEL_RESCUE_BEG:
+ rescue_level++;
+ tailcallopt = FALSE;
+ break;
+ case LABEL_RESCUE_END:
+ if (!--rescue_level) tailcallopt = do_tailcallopt;
+ break;
+ }
+ }
+ list = list->next;
+ }
+ return COMPILE_OK;
+}
+
+#if OPT_INSTRUCTIONS_UNIFICATION
+static INSN *
+new_unified_insn(rb_iseq_t *iseq,
+ int insn_id, int size, LINK_ELEMENT *seq_list)
+{
+ INSN *iobj = 0;
+ LINK_ELEMENT *list = seq_list;
+ int i, argc = 0;
+ VALUE *operands = 0, *ptr = 0;
+
+
+ /* count argc */
+ for (i = 0; i < size; i++) {
+ iobj = (INSN *)list;
+ argc += iobj->operand_size;
+ list = list->next;
+ }
+
+ if (argc > 0) {
+ ptr = operands =
+ (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ }
+
+ /* copy operands */
+ list = seq_list;
+ for (i = 0; i < size; i++) {
+ iobj = (INSN *)list;
+ MEMCPY(ptr, iobj->operands, VALUE, iobj->operand_size);
+ ptr += iobj->operand_size;
+ list = list->next;
+ }
+
+ return new_insn_core(iseq, iobj->insn_info.line_no, insn_id, argc, operands);
+}
+#endif
+
+/*
+ * This scheme can get more performance if do this optimize with
+ * label address resolving.
+ * It's future work (if compile time was bottle neck).
+ */
+static int
+iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+#if OPT_INSTRUCTIONS_UNIFICATION
+ LINK_ELEMENT *list;
+ INSN *iobj, *niobj;
+ int id, k;
+ intptr_t j;
+
+ list = FIRST_ELEMENT(anchor);
+ while (list) {
+ if (IS_INSN(list)) {
+ iobj = (INSN *)list;
+ id = iobj->insn_id;
+ if (unified_insns_data[id] != 0) {
+ const int *const *entry = unified_insns_data[id];
+ for (j = 1; j < (intptr_t)entry[0]; j++) {
+ const int *unified = entry[j];
+ LINK_ELEMENT *li = list->next;
+ for (k = 2; k < unified[1]; k++) {
+ if (!IS_INSN(li) ||
+ ((INSN *)li)->insn_id != unified[k]) {
+ goto miss;
+ }
+ li = li->next;
+ }
+ /* matched */
+ niobj =
+ new_unified_insn(iseq, unified[0], unified[1] - 1,
+ list);
+
+ /* insert to list */
+ niobj->link.prev = (LINK_ELEMENT *)iobj->link.prev;
+ niobj->link.next = li;
+ if (li) {
+ li->prev = (LINK_ELEMENT *)niobj;
+ }
+
+ list->prev->next = (LINK_ELEMENT *)niobj;
+ list = (LINK_ELEMENT *)niobj;
+ break;
+ miss:;
+ }
+ }
+ }
+ list = list->next;
+ }
+#endif
+ return COMPILE_OK;
+}
+
+#if OPT_STACK_CACHING
+
+#define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
+#define SC_NEXT(insn) sc_insn_next[(insn)]
+
+#include "opt_sc.inc"
+
+static int
+insn_set_sc_state(rb_iseq_t *iseq, const LINK_ELEMENT *anchor, INSN *iobj, int state)
+{
+ int nstate;
+ int insn_id;
+
+ insn_id = iobj->insn_id;
+ iobj->insn_id = SC_INSN(insn_id, state);
+ nstate = SC_NEXT(iobj->insn_id);
+
+ if (insn_id == BIN(jump) ||
+ insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
+ LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0);
+
+ if (lobj->sc_state != 0) {
+ if (lobj->sc_state != nstate) {
+ BADINSN_DUMP(anchor, iobj, lobj);
+ 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);
+ return COMPILE_NG;
+ }
+ }
+ else {
+ lobj->sc_state = nstate;
+ }
+ if (insn_id == BIN(jump)) {
+ nstate = SCS_XX;
+ }
+ }
+ else if (insn_id == BIN(leave)) {
+ nstate = SCS_XX;
+ }
+
+ return nstate;
+}
+
+static int
+label_set_sc_state(LABEL *lobj, int state)
+{
+ if (lobj->sc_state != 0) {
+ if (lobj->sc_state != state) {
+ state = lobj->sc_state;
+ }
+ }
+ else {
+ lobj->sc_state = state;
+ }
+
+ return state;
+}
+
+
+#endif
+
+static int
+iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
+{
+#if OPT_STACK_CACHING
+ LINK_ELEMENT *list;
+ int state, insn_id;
+
+ /* initialize */
+ state = SCS_XX;
+ list = FIRST_ELEMENT(anchor);
+ /* dump_disasm_list(list); */
+
+ /* for each list element */
+ while (list) {
+ redo_point:
+ switch (list->type) {
+ case ISEQ_ELEMENT_INSN:
+ {
+ INSN *iobj = (INSN *)list;
+ insn_id = iobj->insn_id;
+
+ /* dump_disasm_list(list); */
+
+ switch (insn_id) {
+ case BIN(nop):
+ {
+ /* exception merge point */
+ if (state != SCS_AX) {
+ INSN *rpobj =
+ new_insn_body(iseq, 0, BIN(reput), 0);
+
+ /* replace this insn */
+ ELEM_REPLACE(list, (LINK_ELEMENT *)rpobj);
+ list = (LINK_ELEMENT *)rpobj;
+ goto redo_point;
+ }
+ break;
+ }
+ case BIN(swap):
+ {
+ if (state == SCS_AB || state == SCS_BA) {
+ state = (state == SCS_AB ? SCS_BA : SCS_AB);
+
+ ELEM_REMOVE(list);
+ list = list->next;
+ goto redo_point;
+ }
+ break;
+ }
+ case BIN(pop):
+ {
+ switch (state) {
+ case SCS_AX:
+ case SCS_BX:
+ state = SCS_XX;
+ break;
+ case SCS_AB:
+ state = SCS_AX;
+ break;
+ case SCS_BA:
+ state = SCS_BX;
+ break;
+ case SCS_XX:
+ goto normal_insn;
+ default:
+ COMPILE_ERROR(iseq, iobj->insn_info.line_no,
+ "unreachable");
+ return COMPILE_NG;
+ }
+ /* remove useless pop */
+ ELEM_REMOVE(list);
+ list = list->next;
+ goto redo_point;
+ }
+ default:;
+ /* none */
+ } /* end of switch */
+ normal_insn:
+ state = insn_set_sc_state(iseq, anchor, iobj, state);
+ break;
+ }
+ case ISEQ_ELEMENT_LABEL:
+ {
+ LABEL *lobj;
+ lobj = (LABEL *)list;
+
+ state = label_set_sc_state(lobj, state);
+ }
+ default:
+ break;
+ }
+ list = list->next;
+ }
+#endif
+ return COMPILE_OK;
+}
+
+static int
+all_string_result_p(const NODE *node)
+{
+ 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;
+
+ debugp_param("nd_lit", lit);
+ if (!NIL_P(lit)) {
+ cnt++;
+ if (!RB_TYPE_P(lit, T_STRING)) {
+ COMPILE_ERROR(ERROR_ARGS "dstr: must be string: %s",
+ rb_builtin_type_name(TYPE(lit)));
+ return COMPILE_NG;
+ }
+ lit = freeze_literal(iseq, lit);
+ ADD_INSN1(ret, nd_line(node), putobject, lit);
+ if (RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret);
+ }
+
+ while (list) {
+ const NODE *const head = list->nd_head;
+ if (nd_type(head) == NODE_STR) {
+ lit = freeze_literal(iseq, head->nd_lit);
+ ADD_INSN1(ret, nd_line(head), putobject, lit);
+ lit = Qnil;
+ }
+ else {
+ CHECK(COMPILE(ret, "each string", head));
+ }
+ cnt++;
+ list = list->nd_next;
+ }
+ if (NIL_P(lit) && first_lit) {
+ ELEM_REMOVE(first_lit);
+ --cnt;
+ }
+ *cntp = cnt;
+
+ return COMPILE_OK;
+}
+
+static int
+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));
+ return COMPILE_OK;
+}
+
+static int
+compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
+{
+ int cnt;
+ CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
+ ADD_INSN2(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag), INT2FIX(cnt));
+ return COMPILE_OK;
+}
+
+static int
+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);
+ LABEL *lend = NEW_LABEL(line);
+ rb_num_t cnt = ISEQ_FLIP_CNT_INCREMENT(iseq->body->local_iseq)
+ + VM_SVAR_FLIPFLOP_START;
+ VALUE key = INT2FIX(cnt);
+
+ ADD_INSN2(ret, line, getspecial, key, INT2FIX(0));
+ ADD_INSNL(ret, line, branchif, lend);
+
+ /* *flip == 0 */
+ CHECK(COMPILE(ret, "flip2 beg", node->nd_beg));
+ ADD_INSNL(ret, line, branchunless, else_label);
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSN1(ret, line, setspecial, key);
+ if (!again) {
+ ADD_INSNL(ret, line, jump, then_label);
+ }
+
+ /* *flip == 1 */
+ ADD_LABEL(ret, lend);
+ CHECK(COMPILE(ret, "flip2 end", node->nd_end));
+ ADD_INSNL(ret, line, branchunless, then_label);
+ ADD_INSN1(ret, line, putobject, Qfalse);
+ ADD_INSN1(ret, line, setspecial, key);
+ ADD_INSNL(ret, line, jump, then_label);
+
+ return COMPILE_OK;
+}
+
+static int
+compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond,
+ LABEL *then_label, LABEL *else_label)
+{
+ again:
+ switch (nd_type(cond)) {
+ case NODE_AND:
+ {
+ LABEL *label = NEW_LABEL(nd_line(cond));
+ CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label,
+ else_label));
+ if (!label->refcnt) break;
+ ADD_LABEL(ret, label);
+ cond = cond->nd_2nd;
+ goto again;
+ }
+ case NODE_OR:
+ {
+ LABEL *label = NEW_LABEL(nd_line(cond));
+ CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label,
+ label));
+ if (!label->refcnt) break;
+ ADD_LABEL(ret, label);
+ cond = cond->nd_2nd;
+ goto again;
+ }
+ case NODE_LIT: /* NODE_LIT is always true */
+ case NODE_TRUE:
+ case NODE_STR:
+ case NODE_ZARRAY:
+ 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;
+ 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;
+ case NODE_FLIP2:
+ CHECK(compile_flip_flop(iseq, ret, cond, TRUE, then_label, else_label));
+ break;
+ case NODE_FLIP3:
+ CHECK(compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label));
+ break;
+ case NODE_DEFINED:
+ CHECK(compile_defined_expr(iseq, ret, cond, Qfalse));
+ goto branch;
+ 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;
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_array_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,
+ 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) {
+ const NODE *node = root_node->nd_head;
+
+ while (node) {
+ const NODE *key_node = node->nd_head;
+
+ 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)) {
+ /* can be keywords */
+ }
+ else {
+ return FALSE;
+ }
+ node = node->nd_next; /* skip value node */
+ node = node->nd_next;
+ }
+
+ /* may be keywords */
+ 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));
+ VALUE *keywords = kw_arg->keywords;
+ int i = 0;
+ kw_arg->keyword_len = len;
+
+ *kw_arg_ptr = kw_arg;
+
+ for (i=0; node != NULL; i++, node = node->nd_next->nd_next) {
+ 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);
+ }
+ assert(i == len);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+enum compile_array_type_t {
+ COMPILE_ARRAY_TYPE_ARRAY,
+ COMPILE_ARRAY_TYPE_HASH,
+ COMPILE_ARRAY_TYPE_ARGS
+};
+
+static inline int
+static_literal_node_p(const NODE *node)
+{
+ node = node->nd_head;
+ switch (nd_type(node)) {
+ case NODE_LIT:
+ case NODE_NIL:
+ case NODE_TRUE:
+ case NODE_FALSE:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static inline VALUE
+static_literal_value(const NODE *node)
+{
+ node = node->nd_head;
+ switch (nd_type(node)) {
+ case NODE_NIL:
+ return Qnil;
+ case NODE_TRUE:
+ return Qtrue;
+ case NODE_FALSE:
+ return Qfalse;
+ default:
+ return node->nd_lit;
+ }
+}
+
+static int
+compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_root,
+ enum compile_array_type_t type, struct rb_call_info_kw_arg **keywords_ptr,
+ unsigned int *flag, int popped)
+{
+ const NODE *node = node_root;
+ int line = (int)nd_line(node);
+ int len = 0;
+
+ if (nd_type(node) == NODE_ZARRAY) {
+ 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;
+ }
+ }
+ }
+ else {
+ int opt_p = 1;
+ int first = 1, i;
+
+ while (node) {
+ const NODE *start_node = node, *end_node;
+ const 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;
+ }
+
+ 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 (opt_p && type != COMPILE_ARRAY_TYPE_ARGS) {
+ if (!popped) {
+ VALUE ary = rb_ary_tmp_new(i);
+
+ end_node = node;
+ node = start_node;
+
+ 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++;
+ }
+
+ OBJ_FREEZE(ary);
+
+ iseq_add_mark_object_compile_time(iseq, ary);
+
+ 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 || kw) {
+ switch (type) {
+ case COMPILE_ARRAY_TYPE_ARRAY:
+ ADD_INSN1(anchor, line, newarray, INT2FIX(i));
+
+ if (first) {
+ first = 0;
+ }
+ else {
+ ADD_INSN(anchor, line, concatarray);
+ }
+
+ APPEND_LIST(ret, anchor);
+ break;
+ case COMPILE_ARRAY_TYPE_HASH:
+ if (i > 0) {
+ if (first) {
+ if (!popped) {
+ ADD_INSN1(anchor, line, newhash, INT2FIX(i));
+ }
+ APPEND_LIST(ret, anchor);
+ }
+ else {
+ if (!popped) {
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_INSN(ret, line, swap);
+ }
+ APPEND_LIST(ret, anchor);
+ if (!popped) {
+ ADD_SEND(ret, line, id_core_hash_merge_ptr, INT2FIX(i + 1));
+ }
+ }
+ }
+ if (kw) {
+ VALUE nhash = (i > 0 || !first) ? INT2FIX(2) : INT2FIX(1);
+ if (!popped) {
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ if (i > 0 || !first) ADD_INSN(ret, line, swap);
+ }
+ COMPILE(ret, "keyword splat", kw);
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ else {
+ 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);
+ }
+ }
+ }
+ }
+ return len;
+}
+
+static VALUE
+case_when_optimizable_literal(const NODE *const node)
+{
+ switch (nd_type(node)) {
+ case NODE_LIT: {
+ VALUE v = node->nd_lit;
+ double ival;
+ if (RB_TYPE_P(v, T_FLOAT) &&
+ modf(RFLOAT_VALUE(v), &ival) == 0.0) {
+ return FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival);
+ }
+ if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
+ return v;
+ }
+ break;
+ }
+ case NODE_NIL:
+ return Qnil;
+ case NODE_TRUE:
+ return Qtrue;
+ case NODE_FALSE:
+ return Qfalse;
+ case NODE_STR:
+ return rb_fstring(node->nd_lit);
+ }
+ return Qundef;
+}
+
+static int
+when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
+ LABEL *l1, int only_special_literals, VALUE literals)
+{
+ while (vals) {
+ const NODE *val = vals->nd_head;
+ VALUE lit = 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);
+ }
+ }
+
+ ADD_INSN(cond_seq, nd_line(val), dup); /* dup target */
+
+ if (nd_type(val) == NODE_STR) {
+ debugp_param("nd_lit", val->nd_lit);
+ lit = freeze_literal(iseq, val->nd_lit);
+ ADD_INSN1(cond_seq, nd_line(val), putobject, lit);
+ }
+ else {
+ COMPILE(cond_seq, "when cond", val);
+ }
+
+ ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
+ ADD_INSNL(cond_seq, nd_line(val), branchif, l1);
+ vals = vals->nd_next;
+ }
+ return only_special_literals;
+}
+
+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);
+
+ 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));
+ INSERT_BEFORE_INSN(iobj, line, concatarray);
+ }
+ ADD_INSN(ret, line, pop); /* result */
+ break;
+ }
+ case NODE_MASGN: {
+ DECL_ANCHOR(anchor);
+ INIT_ANCHOR(anchor);
+ CHECK(COMPILE_POPPED(anchor, "nest masgn lhs", node));
+ ELEM_REMOVE(FIRST_ELEMENT(anchor));
+ ADD_SEQ(ret, anchor);
+ break;
+ }
+ default: {
+ DECL_ANCHOR(anchor);
+ INIT_ANCHOR(anchor);
+ CHECK(COMPILE_POPPED(anchor, "masgn lhs", node));
+ ELEM_REMOVE(FIRST_ELEMENT(anchor));
+ ADD_SEQ(ret, anchor);
+ }
+ }
+
+ return COMPILE_OK;
+}
+
+static int
+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));
+ CHECK(compile_massign_lhs(iseq, ret, lhsn->nd_head));
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
+ 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;
+ const NODE *lhsn = orig_lhsn;
+
+#define MEMORY(v) { \
+ int i; \
+ if (memindex == memsize) return 0; \
+ for (i=0; i<memindex; i++) { \
+ if (mem[i] == (v)) return 0; \
+ } \
+ mem[memindex++] = (v); \
+}
+
+ if (rhsn == 0 || nd_type(rhsn) != NODE_ARRAY) {
+ return 0;
+ }
+
+ while (lhsn) {
+ const NODE *ln = lhsn->nd_head;
+ switch (nd_type(ln)) {
+ case NODE_LASGN:
+ MEMORY(ln->nd_vid);
+ break;
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:
+ case NODE_IASGN:
+ case NODE_CVASGN:
+ MEMORY(ln->nd_vid);
+ break;
+ default:
+ return 0;
+ }
+ lhsn = lhsn->nd_next;
+ llen++;
+ }
+
+ while (rhsn) {
+ if (llen <= rlen) {
+ COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head);
+ }
+ else {
+ COMPILE(ret, "masgn val", rhsn->nd_head);
+ }
+ rhsn = rhsn->nd_next;
+ rlen++;
+ }
+
+ if (llen > rlen) {
+ for (i=0; i<llen-rlen; i++) {
+ ADD_INSN(ret, nd_line(orig_lhsn), putnil);
+ }
+ }
+
+ compile_massign_opt_lhs(iseq, ret, orig_lhsn);
+ return 1;
+}
+
+static void
+adjust_stack(rb_iseq_t *iseq, LINK_ANCHOR *const ret, int line, int rlen, int llen)
+{
+ if (rlen < llen) {
+ do {ADD_INSN(ret, line, putnil);} while (++rlen < llen);
+ }
+ else if (rlen > llen) {
+ do {ADD_INSN(ret, line, pop);} while (--rlen > llen);
+ }
+}
+
+static int
+compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const NODE *rhsn = node->nd_value;
+ const NODE *splatn = node->nd_args;
+ const NODE *lhsn = node->nd_head;
+ int lhs_splat = (splatn && splatn != NODE_SPECIAL_NO_NAME_REST) ? 1 : 0;
+
+ if (!popped || splatn || !compile_massign_opt(iseq, ret, rhsn, lhsn)) {
+ int llen = 0;
+ int expand = 1;
+ DECL_ANCHOR(lhsseq);
+
+ INIT_ANCHOR(lhsseq);
+
+ while (lhsn) {
+ CHECK(compile_massign_lhs(iseq, lhsseq, lhsn->nd_head));
+ llen += 1;
+ lhsn = lhsn->nd_next;
+ }
+
+ COMPILE(ret, "normal masgn rhs", rhsn);
+
+ if (!popped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ else if (!lhs_splat) {
+ INSN *last = (INSN*)ret->last;
+ if (IS_INSN(&last->link) &&
+ IS_INSN_ID(last, newarray) &&
+ last->operand_size == 1) {
+ int rlen = FIX2INT(OPERAND_AT(last, 0));
+ /* special case: assign to aset or attrset */
+ if (llen == 2) {
+ POP_ELEMENT(ret);
+ adjust_stack(iseq, ret, nd_line(node), rlen, llen);
+ ADD_INSN(ret, nd_line(node), swap);
+ expand = 0;
+ }
+ else if (llen > 2 && llen != rlen) {
+ POP_ELEMENT(ret);
+ adjust_stack(iseq, ret, nd_line(node), rlen, llen);
+ ADD_INSN1(ret, nd_line(node), reverse, INT2FIX(llen));
+ expand = 0;
+ }
+ else if (llen > 2) {
+ last->insn_id = BIN(reverse);
+ expand = 0;
+ }
+ }
+ }
+ if (expand) {
+ ADD_INSN2(ret, nd_line(node), expandarray,
+ INT2FIX(llen), INT2FIX(lhs_splat));
+ }
+ ADD_SEQ(ret, lhsseq);
+
+ if (lhs_splat) {
+ if (nd_type(splatn) == NODE_POSTARG) {
+ /*a, b, *r, p1, p2 */
+ const NODE *postn = splatn->nd_2nd;
+ const NODE *restn = splatn->nd_1st;
+ int num = (int)postn->nd_alen;
+ int flag = 0x02 | ((restn == NODE_SPECIAL_NO_NAME_REST) ? 0x00 : 0x01);
+
+ ADD_INSN2(ret, nd_line(splatn), expandarray,
+ INT2FIX(num), INT2FIX(flag));
+
+ if (restn != NODE_SPECIAL_NO_NAME_REST) {
+ CHECK(compile_massign_lhs(iseq, ret, restn));
+ }
+ while (postn) {
+ CHECK(compile_massign_lhs(iseq, ret, postn->nd_head));
+ postn = postn->nd_next;
+ }
+ }
+ else {
+ /* a, b, *r */
+ CHECK(compile_massign_lhs(iseq, ret, splatn));
+ }
+ }
+ }
+ return COMPILE_OK;
+}
+
+static int
+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));
+ 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));
+ 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));
+ break;
+ default:
+ CHECK(COMPILE(pref, "const colon2 prefix", node));
+ break;
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath)
+{
+ if (nd_type(cpath) == NODE_COLON3) {
+ /* toplevel class ::Foo */
+ ADD_INSN1(ret, nd_line(cpath), putobject, rb_cObject);
+ return VM_DEFINECLASS_FLAG_SCOPED;
+ }
+ else if (cpath->nd_head) {
+ /* Bar::Foo */
+ COMPILE(ret, "nd_else->nd_head", cpath->nd_head);
+ return VM_DEFINECLASS_FLAG_SCOPED;
+ }
+ else {
+ /* class at cbase Foo */
+ ADD_INSN1(ret, nd_line(cpath), putspecialobject,
+ INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
+ return 0;
+ }
+}
+
+#define private_recv_p(node) (nd_type((node)->nd_recv) == NODE_SELF)
+static int
+defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
+ const NODE *const node, LABEL **lfinish, VALUE needstr);
+
+static int
+defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
+ const NODE *const node, LABEL **lfinish, VALUE needstr)
+{
+ enum defined_type expr_type = 0;
+ enum node_type type;
+
+ switch (type = nd_type(node)) {
+
+ /* easy literals */
+ case NODE_NIL:
+ expr_type = DEFINED_NIL;
+ break;
+ case NODE_SELF:
+ expr_type = DEFINED_SELF;
+ break;
+ case NODE_TRUE:
+ expr_type = DEFINED_TRUE;
+ break;
+ case NODE_FALSE:
+ expr_type = DEFINED_FALSE;
+ break;
+
+ case NODE_ARRAY:{
+ const NODE *vals = node;
+
+ do {
+ defined_expr0(iseq, ret, vals->nd_head, lfinish, Qfalse);
+
+ if (!lfinish[1]) {
+ lfinish[1] = NEW_LABEL(nd_line(node));
+ }
+ ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
+ } while ((vals = vals->nd_next) != NULL);
+ }
+ case NODE_STR:
+ case NODE_LIT:
+ case NODE_ZARRAY:
+ case NODE_AND:
+ case NODE_OR:
+ default:
+ expr_type = DEFINED_EXPR;
+ break;
+
+ /* variables */
+ case NODE_LVAR:
+ case NODE_DVAR:
+ expr_type = DEFINED_LVAR;
+ break;
+
+ case NODE_IVAR:
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_IVAR),
+ ID2SYM(node->nd_vid), needstr);
+ return 1;
+
+ 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;
+
+ case NODE_CVAR:
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CVAR),
+ ID2SYM(node->nd_vid), needstr);
+ return 1;
+
+ case NODE_CONST:
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CONST),
+ ID2SYM(node->nd_vid), needstr);
+ return 1;
+ case NODE_COLON2:
+ if (!lfinish[1]) {
+ lfinish[1] = NEW_LABEL(nd_line(node));
+ }
+ 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_INSN3(ret, nd_line(node), defined,
+ (rb_is_const_id(node->nd_mid) ?
+ INT2FIX(DEFINED_CONST) : INT2FIX(DEFINED_METHOD)),
+ ID2SYM(node->nd_mid), needstr);
+ return 1;
+ 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;
+
+ /* method dispatch */
+ case NODE_CALL:
+ case NODE_OPCALL:
+ case NODE_VCALL:
+ case NODE_FCALL:
+ case NODE_ATTRASGN:{
+ const int explicit_receiver =
+ (type == NODE_CALL || type == NODE_OPCALL ||
+ (type == NODE_ATTRASGN && !private_recv_p(node)));
+
+ if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
+ lfinish[1] = NEW_LABEL(nd_line(node));
+ }
+ if (node->nd_args) {
+ defined_expr0(iseq, ret, node->nd_args, lfinish, Qfalse);
+ ADD_INSNL(ret, nd_line(node), 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),
+ ID2SYM(node->nd_mid), needstr);
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), putself);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC),
+ ID2SYM(node->nd_mid), needstr);
+ }
+ return 1;
+ }
+
+ case NODE_YIELD:
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_YIELD), 0,
+ needstr);
+ return 1;
+
+ 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),
+ INT2FIX((node->nd_nth << 1) | (type == NODE_BACK_REF)),
+ needstr);
+ return 1;
+
+ case NODE_SUPER:
+ case NODE_ZSUPER:
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_ZSUPER), 0,
+ needstr);
+ return 1;
+
+ case NODE_OP_ASGN1:
+ case NODE_OP_ASGN2:
+ case NODE_OP_ASGN_OR:
+ case NODE_OP_ASGN_AND:
+ case NODE_MASGN:
+ case NODE_LASGN:
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:
+ case NODE_GASGN:
+ case NODE_IASGN:
+ case NODE_CDECL:
+ 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;
+ }
+ return 0;
+}
+
+static int
+defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
+ const NODE *const node, LABEL **lfinish, VALUE needstr)
+{
+ LINK_ELEMENT *lcur = ret->last;
+ int done = 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;
+ NODE tmp_node, *node = &tmp_node;
+ rb_node_init(node, NODE_NIL, 0, 0, 0);
+ rescue = NEW_CHILD_ISEQ(node,
+ rb_str_concat(rb_str_new2
+ ("defined guard in "),
+ iseq->body->location.label),
+ ISEQ_TYPE_DEFINED_GUARD, 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, const NODE *const node, VALUE needstr)
+{
+ const int line = nd_line(node);
+ if (!node->nd_head) {
+ VALUE str = rb_iseq_defined_string(DEFINED_NIL);
+ ADD_INSN1(ret, line, putobject, str);
+ }
+ else {
+ LABEL *lfinish[2];
+ LINK_ELEMENT *last = ret->last;
+ lfinish[0] = NEW_LABEL(line);
+ lfinish[1] = 0;
+ defined_expr(iseq, ret, node->nd_head, lfinish, needstr);
+ if (lfinish[1]) {
+ 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]);
+ }
+ ADD_LABEL(ret, lfinish[0]);
+ }
+ return COMPILE_OK;
+}
+
+static VALUE
+make_name_for_block(const rb_iseq_t *orig_iseq)
+{
+ int level = 1;
+ const rb_iseq_t *iseq = orig_iseq;
+
+ if (orig_iseq->body->parent_iseq != 0) {
+ while (orig_iseq->body->local_iseq != iseq) {
+ if (iseq->body->type == ISEQ_TYPE_BLOCK) {
+ level++;
+ }
+ iseq = iseq->body->parent_iseq;
+ }
+ }
+
+ if (level == 1) {
+ return rb_sprintf("block in %"PRIsVALUE, iseq->body->location.label);
+ }
+ else {
+ return rb_sprintf("block (%d levels) in %"PRIsVALUE, level, iseq->body->location.label);
+ }
+}
+
+static void
+push_ensure_entry(rb_iseq_t *iseq,
+ struct iseq_compile_data_ensure_node_stack *enl,
+ struct ensure_range *er, const NODE *const node)
+{
+ enl->ensure_node = node;
+ enl->prev = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack; /* prev */
+ enl->erange = er;
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enl;
+}
+
+static void
+add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange,
+ LABEL *lstart, LABEL *lend)
+{
+ struct ensure_range *ne =
+ compile_data_alloc(iseq, sizeof(struct ensure_range));
+
+ while (erange->next != 0) {
+ erange = erange->next;
+ }
+ ne->next = 0;
+ ne->begin = lend;
+ ne->end = erange->end;
+ erange->end = lstart;
+
+ erange->next = ne;
+}
+
+static void
+add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return)
+{
+ struct iseq_compile_data_ensure_node_stack *enlp =
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack;
+ struct iseq_compile_data_ensure_node_stack *prev_enlp = enlp;
+ DECL_ANCHOR(ensure);
+
+ INIT_ANCHOR(ensure);
+ while (enlp) {
+ if (enlp->erange != NULL) {
+ DECL_ANCHOR(ensure_part);
+ LABEL *lstart = NEW_LABEL(0);
+ LABEL *lend = NEW_LABEL(0);
+ INIT_ANCHOR(ensure_part);
+
+ add_ensure_range(iseq, enlp->erange, lstart, lend);
+
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enlp->prev;
+ ADD_LABEL(ensure_part, lstart);
+ COMPILE_POPPED(ensure_part, "ensure part", enlp->ensure_node);
+ ADD_LABEL(ensure_part, lend);
+ ADD_SEQ(ensure, ensure_part);
+ }
+ else {
+ if (!is_return) {
+ break;
+ }
+ }
+ enlp = enlp->prev;
+ }
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = prev_enlp;
+ ADD_SEQ(ret, ensure);
+}
+
+static VALUE
+setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
+ unsigned int *flag, struct rb_call_info_kw_arg **keywords)
+{
+ VALUE argc = INT2FIX(0);
+ int nsplat = 0;
+ DECL_ANCHOR(arg_block);
+ DECL_ANCHOR(args_splat);
+
+ 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;
+ }
+
+ 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 (nd_type(argn->nd_body) == NODE_HASH)
+ *flag |= VM_CALL_KW_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);
+ }
+ }
+ }
+
+ if (nsplat > 1) {
+ int i;
+ for (i=1; i<nsplat; i++) {
+ ADD_INSN(args_splat, nd_line(argn), concatarray);
+ }
+ }
+
+ if (!LIST_INSN_SIZE_ZERO(args_splat)) {
+ ADD_SEQ(args, args_splat);
+ }
+
+ if (*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(getlocal);
+ *flag |= VM_CALL_ARGS_BLOCKARG_BLOCKPARAM;
+ }
+ }
+ }
+ ADD_SEQ(args, arg_block);
+ }
+ return argc;
+}
+
+static VALUE
+build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *body)
+{
+ 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);
+ iseq_set_local_table(iseq, 0);
+ return Qnil;
+}
+
+static void
+compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
+{
+ 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));
+#else
+ ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */, INT2FIX(0));
+#endif
+ ADD_INSN(ret, line, dup);
+ ADD_INSNL(ret, line, branchunless, fail_label);
+
+ for (vars = node; vars; vars = vars->nd_next) {
+ INSN *cap;
+ if (vars->nd_next) {
+ ADD_INSN(ret, line, dup);
+ }
+ last = ret->last;
+ 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);
+ 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 */
+ DECL_ANCHOR(nom);
+
+ INIT_ANCHOR(nom);
+ ADD_INSNL(nom, line, jump, end_label);
+ ADD_LABEL(nom, fail_label);
+# if 0 /* $~ must be MatchData or nil */
+ ADD_INSN(nom, line, pop);
+ ADD_INSN(nom, line, putnil);
+# endif
+ ADD_LABEL(nom, end_label);
+ (nom->last->next = cap->link.next)->prev = nom->last;
+ (cap->link.next = nom->anchor.next)->prev = &cap->link;
+ return;
+ }
+#endif
+ }
+ ADD_INSNL(ret, line, jump, end_label);
+ ADD_LABEL(ret, fail_label);
+ ADD_INSN(ret, line, pop);
+ for (vars = node; vars; vars = vars->nd_next) {
+ last = ret->last;
+ COMPILE_POPPED(ret, "capture", vars->nd_head);
+ last = last->next; /* putobject :var */
+ ((INSN*)last)->insn_id = BIN(putnil);
+ ((INSN*)last)->operand_size = 0;
+ }
+ ADD_LABEL(ret, end_label);
+}
+
+static int
+number_literal_p(const NODE *n)
+{
+ return (n && nd_type(n) == NODE_LIT && RB_INTEGER_TYPE_P(n->nd_lit));
+}
+
+static int
+compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
+{
+ 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);
+ const int lineno = nd_first_lineno(node);
+ const int column = nd_first_column(node);
+ const int last_lineno = nd_last_lineno(node);
+ const int last_column = nd_last_column(node);
+ DECL_ANCHOR(cond_seq);
+ DECL_ANCHOR(then_seq);
+ DECL_ANCHOR(else_seq);
+ LABEL *then_label, *else_label, *end_label;
+ VALUE branches = 0;
+ int ci_size, ci_kw_size;
+
+ INIT_ANCHOR(cond_seq);
+ INIT_ANCHOR(then_seq);
+ INIT_ANCHOR(else_seq);
+ then_label = NEW_LABEL(line);
+ else_label = NEW_LABEL(line);
+ end_label = 0;
+
+ compile_branch_condition(iseq, cond_seq, node->nd_cond,
+ then_label, else_label);
+
+ ci_size = iseq->body->ci_size;
+ ci_kw_size = iseq->body->ci_kw_size;
+ CHECK(COMPILE_(then_seq, "then", node_body, popped));
+ if (!then_label->refcnt) {
+ iseq->body->ci_size = ci_size;
+ iseq->body->ci_kw_size = ci_kw_size;
+ }
+
+ ci_size = iseq->body->ci_size;
+ ci_kw_size = iseq->body->ci_kw_size;
+ CHECK(COMPILE_(else_seq, "else", node_else, popped));
+ if (!else_label->refcnt) {
+ iseq->body->ci_size = ci_size;
+ iseq->body->ci_kw_size = ci_kw_size;
+ }
+
+ ADD_SEQ(ret, cond_seq);
+
+ if (then_label->refcnt && else_label->refcnt) {
+ DECL_BRANCH_BASE(branches, lineno, column, last_lineno, last_column, 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_first_lineno(node_body) : lineno,
+ node_body ? nd_first_column(node_body) : column,
+ node_body ? nd_last_lineno(node_body) : last_lineno,
+ node_body ? nd_last_column(node_body) : last_column,
+ type == NODE_IF ? "then" : "else",
+ branches);
+ }
+ 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_first_lineno(node_else) : lineno,
+ node_else ? nd_first_column(node_else) : column,
+ node_else ? nd_last_lineno(node_else) : last_lineno,
+ node_else ? nd_last_column(node_else) : last_column,
+ type == NODE_IF ? "else" : "then",
+ branches);
+ }
+ ADD_SEQ(ret, else_seq);
+ }
+
+ if (end_label) {
+ ADD_LABEL(ret, end_label);
+ }
+
+ return COMPILE_OK;
+}
+
+static int
+compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
+{
+ const NODE *vals;
+ const NODE *node = orig_node;
+ LABEL *endlabel, *elselabel;
+ DECL_ANCHOR(head);
+ DECL_ANCHOR(body_seq);
+ DECL_ANCHOR(cond_seq);
+ int only_special_literals = 1;
+ VALUE literals = rb_hash_new();
+ int line, lineno, column, last_lineno, last_column;
+ enum node_type type;
+ VALUE branches = 0;
+
+ INIT_ANCHOR(head);
+ INIT_ANCHOR(body_seq);
+ INIT_ANCHOR(cond_seq);
+
+ rb_hash_tbl_raw(literals)->type = &cdhash_type;
+
+ CHECK(COMPILE(head, "case base", node->nd_head));
+
+ DECL_BRANCH_BASE(branches, nd_first_lineno(node), nd_first_column(node), nd_last_lineno(node), nd_last_column(node), "case");
+
+ node = node->nd_body;
+ type = nd_type(node);
+ line = nd_line(node);
+ lineno = nd_first_lineno(node);
+ column = nd_first_column(node);
+ last_lineno = nd_last_lineno(node);
+ last_column = nd_last_column(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);
+
+ ADD_SEQ(ret, head); /* case VAL */
+
+ while (type == NODE_WHEN) {
+ LABEL *l1;
+
+ 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_first_lineno(node->nd_body) : lineno,
+ node->nd_body ? nd_first_column(node->nd_body) : column,
+ node->nd_body ? nd_last_lineno(node->nd_body) : last_lineno,
+ node->nd_body ? nd_last_column(node->nd_body) : last_column,
+ "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:
+ only_special_literals = when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals);
+ 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);
+ break;
+ default:
+ UNKNOWN_NODE("NODE_CASE", vals, COMPILE_NG);
+ }
+ }
+ else {
+ EXPECT_NODE_NONULL("NODE_CASE", node, NODE_ARRAY, COMPILE_NG);
+ }
+
+ node = node->nd_next;
+ if (!node) {
+ break;
+ }
+ type = nd_type(node);
+ line = nd_line(node);
+ lineno = nd_first_lineno(node);
+ column = nd_first_column(node);
+ last_lineno = nd_last_lineno(node);
+ last_column = nd_last_column(node);
+ }
+ /* else */
+ if (node) {
+ ADD_LABEL(cond_seq, elselabel);
+ ADD_INSN(cond_seq, line, pop);
+ ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_first_lineno(node), nd_first_column(node), nd_last_lineno(node), nd_last_column(node), "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(orig_node), pop);
+ ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_first_lineno(orig_node), nd_first_column(orig_node), nd_last_lineno(orig_node), nd_last_column(orig_node), "else", branches);
+ if (!popped) {
+ ADD_INSN(cond_seq, nd_line(orig_node), putnil);
+ }
+ 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(orig_node), dup);
+ ADD_INSN2(ret, nd_line(orig_node), opt_case_dispatch, literals, elselabel);
+ LABEL_REF(elselabel);
+ }
+
+ ADD_SEQ(ret, cond_seq);
+ ADD_SEQ(ret, body_seq);
+ ADD_LABEL(ret, endlabel);
+ return COMPILE_OK;
+}
+
+static int
+compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
+{
+ const NODE *vals;
+ const NODE *val;
+ const NODE *node = orig_node->nd_body;
+ LABEL *endlabel;
+ DECL_ANCHOR(body_seq);
+ VALUE branches = 0;
+
+ DECL_BRANCH_BASE(branches, nd_first_lineno(orig_node), nd_first_column(orig_node), nd_last_lineno(orig_node), nd_last_column(orig_node), "case");
+
+ INIT_ANCHOR(body_seq);
+ endlabel = NEW_LABEL(nd_line(node));
+
+ while (node && nd_type(node) == NODE_WHEN) {
+ const int line = nd_line(node);
+ const int lineno = nd_first_lineno(node);
+ const int column = nd_first_column(node);
+ const int last_lineno = nd_last_lineno(node);
+ const int last_column = nd_last_column(node);
+ LABEL *l1 = NEW_LABEL(line);
+ ADD_LABEL(body_seq, l1);
+ ADD_TRACE_BRANCH_COVERAGE(
+ body_seq,
+ node->nd_body ? nd_first_lineno(node->nd_body) : lineno,
+ node->nd_body ? nd_first_column(node->nd_body) : column,
+ node->nd_body ? nd_last_lineno(node->nd_body) : last_lineno,
+ node->nd_body ? nd_last_column(node->nd_body) : last_column,
+ "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;
+ }
+ switch (nd_type(vals)) {
+ case NODE_ARRAY:
+ while (vals) {
+ val = vals->nd_head;
+ CHECK(COMPILE(ret, "when2", val));
+ ADD_INSNL(ret, nd_line(val), branchif, l1);
+ vals = vals->nd_next;
+ }
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH:
+ ADD_INSN(ret, nd_line(vals), putnil);
+ CHECK(COMPILE(ret, "when2/cond splat", vals));
+ ADD_INSN1(ret, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_WHEN | VM_CHECKMATCH_ARRAY));
+ ADD_INSNL(ret, nd_line(vals), branchif, l1);
+ break;
+ default:
+ UNKNOWN_NODE("NODE_WHEN", vals, COMPILE_NG);
+ }
+ node = node->nd_next;
+ }
+ /* else */
+ ADD_TRACE_BRANCH_COVERAGE(
+ ret,
+ node ? nd_first_lineno(node) : nd_first_lineno(orig_node),
+ node ? nd_first_column(node) : nd_first_column(orig_node),
+ node ? nd_last_lineno(node) : nd_last_lineno(orig_node),
+ node ? nd_last_column(node) : nd_last_column(orig_node),
+ "else",
+ branches);
+ CHECK(COMPILE_(ret, "else", node, popped));
+ ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
+
+ ADD_SEQ(ret, body_seq);
+ ADD_LABEL(ret, endlabel);
+ return COMPILE_OK;
+}
+
+static int
+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);
+ const int lineno = nd_first_lineno(node);
+ const int column = nd_first_column(node);
+ const int last_lineno = nd_last_lineno(node);
+ const int last_column = nd_last_column(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;
+
+ struct iseq_compile_data_ensure_node_stack enl;
+
+ LABEL *next_label = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(line); /* next */
+ LABEL *redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label = NEW_LABEL(line); /* redo */
+ LABEL *break_label = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(line); /* break */
+ LABEL *end_label = NEW_LABEL(line);
+ LABEL *adjust_label = NEW_LABEL(line);
+
+ LABEL *next_catch_label = NEW_LABEL(line);
+ LABEL *tmp_label = NULL;
+
+ ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0;
+ push_ensure_entry(iseq, &enl, NULL, NULL);
+
+ if (node->nd_state == 1) {
+ ADD_INSNL(ret, line, jump, next_label);
+ }
+ else {
+ tmp_label = NEW_LABEL(line);
+ ADD_INSNL(ret, line, jump, tmp_label);
+ }
+ ADD_LABEL(ret, adjust_label);
+ ADD_INSN(ret, line, putnil);
+ ADD_LABEL(ret, next_catch_label);
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, next_label);
+ if (tmp_label) ADD_LABEL(ret, tmp_label);
+
+ ADD_LABEL(ret, redo_label);
+ DECL_BRANCH_BASE(branches, lineno, column, last_lineno, last_column, type == NODE_WHILE ? "while" : "until");
+ ADD_TRACE_BRANCH_COVERAGE(
+ ret,
+ node->nd_body ? nd_first_lineno(node->nd_body) : lineno,
+ node->nd_body ? nd_first_column(node->nd_body) : column,
+ node->nd_body ? nd_last_lineno(node->nd_body) : last_lineno,
+ node->nd_body ? nd_last_column(node->nd_body) : last_column,
+ "body",
+ branches);
+ CHECK(COMPILE_POPPED(ret, "while body", node->nd_body));
+ ADD_LABEL(ret, next_label); /* next */
+
+ if (type == NODE_WHILE) {
+ compile_branch_condition(iseq, ret, node->nd_cond,
+ redo_label, end_label);
+ }
+ else {
+ /* until */
+ compile_branch_condition(iseq, ret, node->nd_cond,
+ end_label, redo_label);
+ }
+
+ ADD_LABEL(ret, end_label);
+ ADD_ADJUST_RESTORE(ret, adjust_label);
+
+ if (node->nd_state == Qundef) {
+ /* ADD_INSN(ret, line, putundef); */
+ COMPILE_ERROR(ERROR_ARGS "unsupported: putundef");
+ return COMPILE_NG;
+ }
+ else {
+ ADD_INSN(ret, line, putnil);
+ }
+
+ ADD_LABEL(ret, break_label); /* break */
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+
+ ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
+ break_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, NULL,
+ next_catch_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, NULL,
+ ISEQ_COMPILE_DATA(iseq)->redo_label);
+
+ ISEQ_COMPILE_DATA(iseq)->start_label = prev_start_label;
+ ISEQ_COMPILE_DATA(iseq)->end_label = prev_end_label;
+ ISEQ_COMPILE_DATA(iseq)->redo_label = prev_redo_label;
+ ISEQ_COMPILE_DATA(iseq)->loopval_popped = prev_loopval_popped;
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->prev;
+ return COMPILE_OK;
+}
+
+static int
+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(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+ if (node->nd_var) {
+ /* massign to var in "for"
+ * args.length == 1 && Array === (tmp = args[0]) ? tmp : args
+ */
+ 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_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);
+ return COMPILE_OK;
+ }
+ else {
+ return compile_iter(iseq, ret, node, popped);
+ }
+}
+
+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;
+
+ if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
+ /* while/until */
+ LABEL *splabel = NEW_LABEL(0);
+ ADD_LABEL(ret, splabel);
+ ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->redo_label);
+ CHECK(COMPILE_(ret, "break val (while/until)", node->nd_stts,
+ ISEQ_COMPILE_DATA(iseq)->loopval_popped));
+ add_ensure_iseq(ret, iseq, 0);
+ ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
+ ADD_ADJUST_RESTORE(ret, splabel);
+
+ if (!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;
+
+ while (ip) {
+ if (!ISEQ_COMPILE_DATA(ip)) {
+ ip = 0;
+ break;
+ }
+
+ level++;
+ if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
+ level = VM_THROW_NO_ESCAPE_FLAG;
+ goto break_by_insn;
+ }
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
+ level <<= VM_THROW_LEVEL_SHIFT;
+ goto break_by_insn;
+ }
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
+ goto break_in_eval;
+ }
+
+ ip = ip->body->parent_iseq;
+ }
+ COMPILE_ERROR(ERROR_ARGS "Invalid break");
+ return COMPILE_NG;
+ }
+ return COMPILE_OK;
+}
+
+static int
+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;
+
+ if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
+ LABEL *splabel = NEW_LABEL(0);
+ debugs("next in while loop\n");
+ ADD_LABEL(ret, splabel);
+ CHECK(COMPILE(ret, "next val/valid syntax?", node->nd_stts));
+ add_ensure_iseq(ret, iseq, 0);
+ ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->redo_label);
+ ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
+ ADD_ADJUST_RESTORE(ret, splabel);
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ }
+ }
+ else if (ISEQ_COMPILE_DATA(iseq)->end_label) {
+ LABEL *splabel = NEW_LABEL(0);
+ debugs("next in block\n");
+ ADD_LABEL(ret, splabel);
+ ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->start_label);
+ CHECK(COMPILE(ret, "next val", node->nd_stts));
+ 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;
+
+ while (ip) {
+ if (!ISEQ_COMPILE_DATA(ip)) {
+ ip = 0;
+ break;
+ }
+
+ level = VM_THROW_NO_ESCAPE_FLAG;
+ if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
+ /* while loop */
+ break;
+ }
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
+ break;
+ }
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
+ goto next_in_eval;
+ }
+
+ 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));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "Invalid next");
+ return COMPILE_NG;
+ }
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+
+ if (ISEQ_COMPILE_DATA(iseq)->redo_label) {
+ LABEL *splabel = NEW_LABEL(0);
+ debugs("redo in while");
+ ADD_LABEL(ret, splabel);
+ ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->redo_label);
+ add_ensure_iseq(ret, iseq, 0);
+ ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->redo_label);
+ ADD_ADJUST_RESTORE(ret, splabel);
+ if (!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) {
+ LABEL *splabel = NEW_LABEL(0);
+
+ debugs("redo in block");
+ ADD_LABEL(ret, splabel);
+ add_ensure_iseq(ret, iseq, 0);
+ ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->start_label);
+ ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
+ ADD_ADJUST_RESTORE(ret, splabel);
+
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ }
+ }
+ else {
+ const rb_iseq_t *ip = iseq;
+ const unsigned long level = VM_THROW_NO_ESCAPE_FLAG;
+
+ while (ip) {
+ if (!ISEQ_COMPILE_DATA(ip)) {
+ ip = 0;
+ break;
+ }
+
+ if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
+ break;
+ }
+ else if (ip->body->type == ISEQ_TYPE_BLOCK) {
+ break;
+ }
+ else if (ip->body->type == ISEQ_TYPE_EVAL) {
+ goto redo_in_eval;
+ }
+
+ ip = ip->body->parent_iseq;
+ }
+ if (ip != 0) {
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_REDO));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "Invalid redo");
+ return COMPILE_NG;
+ }
+ }
+ return COMPILE_OK;
+}
+
+static int
+compile_retry(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+
+ if (iseq->body->type == ISEQ_TYPE_RESCUE) {
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETRY));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ else {
+ COMPILE_ERROR(ERROR_ARGS "Invalid retry");
+ return COMPILE_NG;
+ }
+ return COMPILE_OK;
+}
+
+static int
+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);
+ LABEL *lend = NEW_LABEL(line);
+ LABEL *lcont = NEW_LABEL(line);
+ const rb_iseq_t *rescue = NEW_CHILD_ISEQ(node->nd_resq,
+ rb_str_concat(rb_str_new2("rescue in "), iseq->body->location.label),
+ ISEQ_TYPE_RESCUE, line);
+
+ lstart->rescued = LABEL_RESCUE_BEG;
+ lend->rescued = LABEL_RESCUE_END;
+ ADD_LABEL(ret, lstart);
+ CHECK(COMPILE(ret, "rescue head", node->nd_head));
+ ADD_LABEL(ret, lend);
+ if (node->nd_else) {
+ ADD_INSN(ret, line, pop);
+ CHECK(COMPILE(ret, "rescue else", node->nd_else));
+ }
+ ADD_INSN(ret, line, nop);
+ ADD_LABEL(ret, lcont);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+
+ /* register catch entry */
+ ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lcont);
+ ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, NULL, lstart);
+ return COMPILE_OK;
+}
+
+static int
+compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+{
+ const int line = nd_line(node);
+ const NODE *resq = node;
+ const NODE *narg;
+ LABEL *label_miss, *label_hit;
+
+ while (resq) {
+ label_miss = NEW_LABEL(line);
+ label_hit = NEW_LABEL(line);
+
+ narg = resq->nd_args;
+ if (narg) {
+ switch (nd_type(narg)) {
+ case NODE_ARRAY:
+ while (narg) {
+ ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
+ CHECK(COMPILE(ret, "rescue arg", narg->nd_head));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
+ ADD_INSNL(ret, line, branchif, label_hit);
+ narg = narg->nd_next;
+ }
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH:
+ ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
+ CHECK(COMPILE(ret, "rescue/cond splat", narg));
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE | VM_CHECKMATCH_ARRAY));
+ ADD_INSNL(ret, line, branchif, label_hit);
+ break;
+ default:
+ UNKNOWN_NODE("NODE_RESBODY", narg, COMPILE_NG);
+ }
+ }
+ else {
+ ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
+ ADD_INSN1(ret, line, putobject, rb_eStandardError);
+ ADD_INSN1(ret, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
+ ADD_INSNL(ret, line, branchif, label_hit);
+ }
+ ADD_INSNL(ret, line, jump, label_miss);
+ ADD_LABEL(ret, label_hit);
+ CHECK(COMPILE(ret, "resbody body", resq->nd_body));
+ if (ISEQ_COMPILE_DATA(iseq)->option->tailcall_optimization) {
+ ADD_INSN(ret, line, nop);
+ }
+ ADD_INSN(ret, line, leave);
+ ADD_LABEL(ret, label_miss);
+ resq = resq->nd_head;
+ }
+ return COMPILE_OK;
+}
+
+static int
+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);
+ const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr,
+ rb_str_concat(rb_str_new2 ("ensure in "), iseq->body->location.label),
+ ISEQ_TYPE_ENSURE, line);
+ LABEL *lstart = NEW_LABEL(line);
+ LABEL *lend = NEW_LABEL(line);
+ LABEL *lcont = NEW_LABEL(line);
+ LINK_ELEMENT *last;
+ int last_leave = 0;
+ struct ensure_range er;
+ struct iseq_compile_data_ensure_node_stack enl;
+ struct ensure_range *erange;
+
+ INIT_ANCHOR(ensr);
+ CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr));
+ last = ensr->last;
+ last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave);
+
+ er.begin = lstart;
+ er.end = lend;
+ er.next = 0;
+ push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
+
+ ADD_LABEL(ret, lstart);
+ CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave)));
+ ADD_LABEL(ret, lend);
+ 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);
+
+ erange = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->erange;
+ if (lstart->link.next != &lend->link) {
+ while (erange) {
+ ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end,
+ ensure, lcont);
+ erange = erange->next;
+ }
+ }
+
+ ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enl.prev;
+ return COMPILE_OK;
+}
+
+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 (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 iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped);
+/**
+ compile each node
+
+ self: InstructionSequence
+ node: Ruby compiled node
+ popped: This node will be popped
+ */
+static int
+iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *node, int popped)
+{
+ if (node == 0) {
+ 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
+iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped)
+{
+ const int line = (int)nd_line(node);
+ const enum node_type type = nd_type(node);
+
+ if (ISEQ_COMPILE_DATA(iseq)->last_line == line) {
+ /* ignore */
+ }
+ else {
+ if (node->flags & NODE_FL_NEWLINE) {
+ ISEQ_COMPILE_DATA(iseq)->last_line = line;
+ ADD_TRACE_LINE_COVERAGE(ret, line);
+ ADD_TRACE(ret, RUBY_EVENT_LINE);
+ }
+ }
+
+ debug_node_start(node);
+#undef BEFORE_RETURN
+#define BEFORE_RETURN debug_node_end()
+
+ switch (type) {
+ case NODE_BLOCK:{
+ while (node && nd_type(node) == NODE_BLOCK) {
+ CHECK(COMPILE_(ret, "BLOCK body", node->nd_head,
+ (node->nd_next ? 1 : popped)));
+ node = node->nd_next;
+ }
+ if (node) {
+ CHECK(COMPILE_(ret, "BLOCK next", node->nd_next, popped));
+ }
+ break;
+ }
+ case NODE_IF:
+ case NODE_UNLESS:
+ CHECK(compile_if(iseq, ret, node, popped, type));
+ break;
+ case NODE_CASE:
+ CHECK(compile_case(iseq, ret, node, popped));
+ break;
+ case NODE_CASE2:
+ CHECK(compile_case2(iseq, ret, node, popped));
+ break;
+ case NODE_WHILE:
+ case NODE_UNTIL:
+ CHECK(compile_loop(iseq, ret, node, popped, type));
+ break;
+ case NODE_FOR:
+ CHECK(compile_for(iseq, ret, node, popped));
+ break;
+ case NODE_ITER:
+ CHECK(compile_iter(iseq, ret, node, popped));
+ break;
+ case NODE_BREAK:
+ CHECK(compile_break(iseq, ret, node, popped));
+ break;
+ case NODE_NEXT:
+ CHECK(compile_next(iseq, ret, node, popped));
+ break;
+ case NODE_REDO:
+ CHECK(compile_redo(iseq, ret, node, popped));
+ break;
+ case NODE_RETRY:
+ CHECK(compile_retry(iseq, ret, node, popped));
+ break;
+ case NODE_BEGIN:{
+ CHECK(COMPILE_(ret, "NODE_BEGIN", node->nd_body, popped));
+ break;
+ }
+ case NODE_RESCUE:
+ CHECK(compile_rescue(iseq, ret, node, popped));
+ break;
+ case NODE_RESBODY:
+ CHECK(compile_resbody(iseq, ret, node, popped));
+ break;
+ case NODE_ENSURE:
+ CHECK(compile_ensure(iseq, ret, node, popped));
+ break;
+
+ case NODE_AND:
+ case NODE_OR:{
+ LABEL *end_label = NEW_LABEL(line);
+ CHECK(COMPILE(ret, "nd_1st", node->nd_1st));
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+ if (type == NODE_AND) {
+ ADD_INSNL(ret, line, branchunless, end_label);
+ }
+ else {
+ ADD_INSNL(ret, line, branchif, end_label);
+ }
+ if (!popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ CHECK(COMPILE_(ret, "nd_2nd", node->nd_2nd, popped));
+ ADD_LABEL(ret, end_label);
+ break;
+ }
+
+ case NODE_MASGN:{
+ compile_massign(iseq, ret, node, popped);
+ break;
+ }
+
+ case NODE_LASGN:{
+ ID id = node->nd_vid;
+ int idx = iseq->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));
+
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+ ADD_SETLOCAL(ret, line, idx, get_lvar_level(iseq));
+ break;
+ }
+ 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(id) ? id : '*');
+
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+
+ idx = get_dyna_var_idx(iseq, id, &lv, &ls);
+
+ if (idx < 0) {
+ COMPILE_ERROR(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%"PRIsVALUE")",
+ rb_id2str(id));
+ goto ng;
+ }
+ ADD_SETLOCAL(ret, line, ls - idx, lv);
+ break;
+ }
+ case NODE_GASGN:{
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
+
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+ ADD_INSN1(ret, line, setglobal,
+ ((VALUE)node->nd_entry | 1));
+ break;
+ }
+ case NODE_IASGN:{
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+ ADD_INSN2(ret, line, setinstancevariable,
+ ID2SYM(node->nd_vid),
+ get_ivar_ic_value(iseq,node->nd_vid));
+ break;
+ }
+ case NODE_CDECL:{
+ CHECK(COMPILE(ret, "lvalue", node->nd_value));
+
+ 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));
+ }
+ else {
+ compile_cpath(ret, iseq, node->nd_else);
+ ADD_INSN1(ret, line, setconstant, ID2SYM(node->nd_else->nd_mid));
+ }
+ break;
+ }
+ case NODE_CVASGN:{
+ CHECK(COMPILE(ret, "cvasgn val", node->nd_value));
+ if (!popped) {
+ ADD_INSN(ret, line, dup);
+ }
+ ADD_INSN1(ret, line, setclassvariable,
+ ID2SYM(node->nd_vid));
+ break;
+ }
+ case NODE_OP_ASGN1: {
+ DECL_ANCHOR(args);
+ VALUE argc;
+ unsigned int flag = 0;
+ unsigned int asgnflag = 0;
+ ID id = node->nd_mid;
+ int boff = 0;
+
+ /*
+ * a[x] (op)= y
+ *
+ * nil # nil
+ * eval a # nil a
+ * eval x # nil a x
+ * dupn 2 # nil a x a x
+ * send :[] # nil a x a[x]
+ * eval y # nil a x a[x] y
+ * send op # nil a x ret
+ * setn 3 # ret a x ret
+ * send []= # ret ?
+ * pop # ret
+ */
+
+ /*
+ * nd_recv[nd_args->nd_body] (nd_mid)= nd_args->nd_head;
+ * NODE_OP_ASGN nd_recv
+ * nd_args->nd_head
+ * nd_args->nd_body
+ * nd_mid
+ */
+
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ }
+ asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node);
+ switch (nd_type(node->nd_args->nd_head)) {
+ case NODE_ZARRAY:
+ argc = INT2FIX(0);
+ break;
+ case NODE_BLOCK_PASS:
+ boff = 1;
+ default:
+ INIT_ANCHOR(args);
+ argc = setup_args(iseq, args, 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));
+ ADD_SEND_WITH_FLAG(ret, line, idAREF, argc, INT2FIX(flag));
+ flag |= asgnflag;
+
+ if (id == 0 || id == 1) {
+ /* 0: or, 1: and
+ a[x] ||= y
+
+ unless/if a[x]
+ a[x]= y
+ else
+ nil
+ end
+ */
+ LABEL *label = NEW_LABEL(line);
+ LABEL *lfin = NEW_LABEL(line);
+
+ ADD_INSN(ret, line, dup);
+ if (id == 0) {
+ /* or */
+ ADD_INSNL(ret, line, branchif, label);
+ }
+ else {
+ /* and */
+ ADD_INSNL(ret, line, branchunless, label);
+ }
+ ADD_INSN(ret, line, pop);
+
+ CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
+ if (!popped) {
+ ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 2+boff));
+ }
+ if (flag & VM_CALL_ARGS_SPLAT) {
+ ADD_INSN1(ret, line, newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, line, dupn, INT2FIX(3));
+ ADD_INSN(ret, line, swap);
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_INSN(ret, line, concatarray);
+ if (boff > 0) {
+ ADD_INSN1(ret, line, setn, INT2FIX(3));
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_SEND_WITH_FLAG(ret, line, idASET, argc, INT2FIX(flag));
+ }
+ else {
+ if (boff > 0)
+ ADD_INSN(ret, line, swap);
+ ADD_SEND_WITH_FLAG(ret, line, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
+ }
+ ADD_INSN(ret, line, pop);
+ ADD_INSNL(ret, line, jump, lfin);
+ ADD_LABEL(ret, label);
+ if (!popped) {
+ ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 2+boff));
+ }
+ ADD_INSN1(ret, line, adjuststack, FIXNUM_INC(argc, 2+boff));
+ ADD_LABEL(ret, lfin);
+ }
+ else {
+ CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
+ ADD_SEND(ret, line, id, INT2FIX(1));
+ if (!popped) {
+ ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 2+boff));
+ }
+ if (flag & VM_CALL_ARGS_SPLAT) {
+ ADD_INSN1(ret, line, newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, line, dupn, INT2FIX(3));
+ ADD_INSN(ret, line, swap);
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_INSN(ret, line, concatarray);
+ if (boff > 0) {
+ ADD_INSN1(ret, line, setn, INT2FIX(3));
+ ADD_INSN(ret, line, pop);
+ ADD_INSN(ret, line, pop);
+ }
+ ADD_SEND_WITH_FLAG(ret, line, idASET, argc, INT2FIX(flag));
+ }
+ else {
+ if (boff > 0)
+ ADD_INSN(ret, line, swap);
+ ADD_SEND_WITH_FLAG(ret, line, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag));
+ }
+ ADD_INSN(ret, line, pop);
+ }
+
+ break;
+ }
+ 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;
+ LABEL *lfin = NEW_LABEL(line);
+ LABEL *lcfin = NEW_LABEL(line);
+ LABEL *lskip = 0;
+ /*
+ class C; attr_accessor :c; end
+ r = C.new
+ r.a &&= v # asgn2
+
+ eval r # r
+ dup # r r
+ eval r.a # r o
+
+ # or
+ dup # r o o
+ if lcfin # r o
+ pop # r
+ eval v # r v
+ swap # v r
+ topn 1 # v r v
+ send a= # v ?
+ jump lfin # v ?
+
+ lcfin: # r o
+ swap # o r
+
+ lfin: # o ?
+ pop # o
+
+ # and
+ dup # r o o
+ unless lcfin
+ pop # r
+ eval v # r v
+ swap # v r
+ topn 1 # v r v
+ send a= # v ?
+ jump lfin # v ?
+
+ # others
+ eval v # r o v
+ send ?? # r w
+ send a= # w
+
+ */
+
+ asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node);
+ 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));
+
+ if (atype == 0 || atype == 1) { /* 0: OR or 1: AND */
+ ADD_INSN(ret, line, dup);
+ if (atype == 0) {
+ ADD_INSNL(ret, line, branchif, lcfin);
+ }
+ else {
+ ADD_INSNL(ret, line, branchunless, lcfin);
+ }
+ ADD_INSN(ret, line, pop);
+ CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value));
+ ADD_INSN(ret, line, swap);
+ ADD_INSN1(ret, line, topn, INT2FIX(1));
+ ADD_SEND_WITH_FLAG(ret, line, aid, INT2FIX(1), INT2FIX(asgnflag));
+ ADD_INSNL(ret, line, jump, lfin);
+
+ ADD_LABEL(ret, lcfin);
+ ADD_INSN(ret, line, swap);
+
+ ADD_LABEL(ret, lfin);
+ ADD_INSN(ret, line, pop);
+ if (lskip) {
+ ADD_LABEL(ret, lskip);
+ }
+ if (popped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, line, pop);
+ }
+ }
+ else {
+ CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value));
+ ADD_SEND(ret, line, atype, INT2FIX(1));
+ if (!popped) {
+ ADD_INSN(ret, line, swap);
+ ADD_INSN1(ret, line, topn, INT2FIX(1));
+ }
+ ADD_SEND_WITH_FLAG(ret, line, aid, INT2FIX(1), INT2FIX(asgnflag));
+ if (lskip && popped) {
+ ADD_LABEL(ret, lskip);
+ }
+ ADD_INSN(ret, line, pop);
+ if (lskip && !popped) {
+ ADD_LABEL(ret, lskip);
+ }
+ }
+ break;
+ }
+ case NODE_OP_CDECL: {
+ LABEL *lfin = 0;
+ LABEL *lassign = 0;
+ ID mid;
+
+ switch (nd_type(node->nd_head)) {
+ case NODE_COLON3:
+ ADD_INSN1(ret, line, putobject, rb_cObject);
+ break;
+ case NODE_COLON2:
+ CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head));
+ break;
+ default:
+ COMPILE_ERROR(ERROR_ARGS "%s: invalid node in NODE_OP_CDECL",
+ ruby_node_name(nd_type(node->nd_head)));
+ goto ng;
+ }
+ mid = node->nd_head->nd_mid;
+ /* cref */
+ if (node->nd_aid == 0) {
+ lassign = NEW_LABEL(line);
+ ADD_INSN(ret, line, dup); /* cref cref */
+ ADD_INSN3(ret, line, defined, INT2FIX(DEFINED_CONST),
+ 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 */
+
+ if (node->nd_aid == 0 || node->nd_aid == 1) {
+ lfin = NEW_LABEL(line);
+ if (!popped) ADD_INSN(ret, line, dup); /* cref [obj] obj */
+ if (node->nd_aid == 0)
+ ADD_INSNL(ret, line, branchif, lfin);
+ else
+ ADD_INSNL(ret, line, branchunless, lfin);
+ /* cref [obj] */
+ if (!popped) ADD_INSN(ret, line, pop); /* cref */
+ if (lassign) ADD_LABEL(ret, lassign);
+ CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value));
+ /* cref value */
+ if (popped)
+ ADD_INSN1(ret, line, topn, INT2FIX(1)); /* cref value cref */
+ else {
+ ADD_INSN1(ret, line, dupn, INT2FIX(2)); /* cref value cref value */
+ ADD_INSN(ret, line, swap); /* cref value value cref */
+ }
+ ADD_INSN1(ret, line, setconstant, ID2SYM(mid)); /* cref [value] */
+ ADD_LABEL(ret, lfin); /* cref [value] */
+ if (!popped) ADD_INSN(ret, line, swap); /* [value] cref */
+ ADD_INSN(ret, line, pop); /* [value] */
+ }
+ else {
+ CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value));
+ /* cref obj value */
+ ADD_CALL(ret, line, node->nd_aid, INT2FIX(1));
+ /* cref value */
+ ADD_INSN(ret, line, swap); /* value cref */
+ if (!popped) {
+ ADD_INSN1(ret, line, topn, INT2FIX(1)); /* value cref value */
+ ADD_INSN(ret, line, swap); /* value value cref */
+ }
+ ADD_INSN1(ret, line, setconstant, ID2SYM(mid));
+ }
+ break;
+ }
+ case NODE_OP_ASGN_AND:
+ case NODE_OP_ASGN_OR:{
+ LABEL *lfin = NEW_LABEL(line);
+ LABEL *lassign;
+
+ if (nd_type(node) == NODE_OP_ASGN_OR) {
+ LABEL *lfinish[2];
+ lfinish[0] = lfin;
+ lfinish[1] = 0;
+ defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
+ lassign = lfinish[1];
+ if (!lassign) {
+ lassign = NEW_LABEL(line);
+ }
+ ADD_INSNL(ret, line, branchunless, lassign);
+ }
+ else {
+ lassign = NEW_LABEL(line);
+ }
+
+ CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
+ ADD_INSN(ret, line, dup);
+
+ if (nd_type(node) == NODE_OP_ASGN_AND) {
+ ADD_INSNL(ret, line, branchunless, lfin);
+ }
+ else {
+ ADD_INSNL(ret, line, branchif, lfin);
+ }
+
+ ADD_INSN(ret, line, pop);
+ ADD_LABEL(ret, lassign);
+ CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value));
+ ADD_LABEL(ret, lfin);
+
+ if (popped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, line, pop);
+ }
+ 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 = freeze_literal(iseq, node->nd_recv->nd_lit);
+ 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->frozen_string_literal &&
+ ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
+ VALUE str = freeze_literal(iseq, node->nd_args->nd_head->nd_lit);
+ 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_first_lineno(node), nd_first_column(node), nd_last_lineno(node), nd_last_column(node), "&.");
+ ADD_INSN(recv, line, dup);
+ ADD_INSNL(recv, line, branchnil, else_label);
+ ADD_TRACE_BRANCH_COVERAGE(recv, nd_first_lineno(node), nd_first_column(node), nd_last_lineno(node), nd_last_column(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_first_lineno(node), nd_first_column(node), nd_last_lineno(node), nd_last_column(node), "else", branches);
+ ADD_LABEL(ret, end_label);
+ }
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_SUPER:
+ case NODE_ZSUPER:{
+ DECL_ANCHOR(args);
+ int 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;
+
+ INIT_ANCHOR(args);
+ ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
+ if (type == NODE_SUPER) {
+ VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
+ CHECK(!NIL_P(vargc));
+ argc = FIX2INT(vargc);
+ }
+ else {
+ /* NODE_ZSUPER */
+ int i;
+ const rb_iseq_t *liseq = iseq->body->local_iseq;
+ int lvar_level = get_lvar_level(iseq);
+
+ argc = liseq->body->param.lead_num;
+
+ /* normal arguments */
+ for (i = 0; i < liseq->body->param.lead_num; i++) {
+ int idx = liseq->body->local_table_size - i;
+ ADD_GETLOCAL(args, line, idx, lvar_level);
+ }
+
+ if (liseq->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);
+ ADD_GETLOCAL(args, line, idx, lvar_level);
+ }
+ i += j;
+ argc = i;
+ }
+ if (liseq->body->param.flags.has_rest) {
+ /* rest argument */
+ int idx = liseq->body->local_table_size - liseq->body->param.rest_start;
+
+ ADD_GETLOCAL(args, line, idx, lvar_level);
+ ADD_INSN1(args, line, splatarray, Qfalse);
+
+ argc = liseq->body->param.rest_start + 1;
+ flag |= VM_CALL_ARGS_SPLAT;
+ }
+ if (liseq->body->param.flags.has_post) {
+ /* post arguments */
+ int post_len = liseq->body->param.post_num;
+ int post_start = liseq->body->param.post_start;
+
+ if (liseq->body->param.flags.has_rest) {
+ int j;
+ for (j=0; j<post_len; j++) {
+ int idx = liseq->body->local_table_size - (post_start + j);
+ ADD_GETLOCAL(args, line, idx, lvar_level);
+ }
+ ADD_INSN1(args, line, newarray, INT2FIX(j));
+ ADD_INSN (args, line, concatarray);
+ /* argc is settled at above */
+ }
+ else {
+ int j;
+ for (j=0; j<post_len; j++) {
+ int idx = liseq->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;
+ 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;
+ ADD_GETLOCAL(args, line, idx, lvar_level);
+ ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
+ }
+ else {
+ ADD_INSN1(args, line, newhash, INT2FIX(0));
+ }
+ for (i = 0; i < liseq->body->param.keyword->num; ++i) {
+ ID id = liseq->body->param.keyword->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) {
+ ADD_INSN1(args, line, newarray, INT2FIX(1));
+ ADD_INSN (args, line, concatarray);
+ --argc;
+ }
+ }
+ else if (liseq->body->param.flags.has_kwrest) {
+ int idx = liseq->body->local_table_size - liseq->body->param.keyword->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) {
+ ADD_INSN1(args, line, newarray, INT2FIX(1));
+ ADD_INSN (args, line, concatarray);
+ }
+ else {
+ argc++;
+ }
+ }
+ }
+
+ /* dummy receiver */
+ ADD_INSN1(ret, line, putobject, type == NODE_ZSUPER ? Qfalse : Qtrue);
+ 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 */
+ parent_block);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_ARRAY:{
+ CHECK(compile_array(iseq, ret, node, COMPILE_ARRAY_TYPE_ARRAY, NULL, NULL, popped) >= 0);
+ break;
+ }
+ case NODE_ZARRAY:{
+ if (!popped) {
+ ADD_INSN1(ret, line, newarray, INT2FIX(0));
+ }
+ break;
+ }
+ case NODE_VALUES:{
+ const NODE *n = node;
+ if (popped) {
+ COMPILE_ERROR(ERROR_ARGS "NODE_VALUES: must not be popped");
+ }
+ while (n) {
+ CHECK(COMPILE(ret, "values item", n->nd_head));
+ n = n->nd_next;
+ }
+ ADD_INSN1(ret, line, newarray, INT2FIX(node->nd_alen));
+ break;
+ }
+ case NODE_HASH:{
+ DECL_ANCHOR(list);
+ enum node_type 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:
+ 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;
+
+ INIT_ANCHOR(args);
+ if (iseq->body->type == ISEQ_TYPE_TOP ||
+ iseq->body->type == ISEQ_TYPE_MAIN) {
+ COMPILE_ERROR(ERROR_ARGS "Invalid yield");
+ goto ng;
+ }
+
+ if (node->nd_head) {
+ argc = setup_args(iseq, args, node->nd_head, &flag, &keywords);
+ CHECK(!NIL_P(argc));
+ }
+ else {
+ argc = INT2FIX(0);
+ }
+
+ ADD_SEQ(ret, args);
+ ADD_INSN1(ret, line, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, keywords, FALSE));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ 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);
+
+ debugs("id: %s idx: %d\n", rb_id2name(id), idx);
+ ADD_GETLOCAL(ret, line, idx, get_lvar_level(iseq));
+ }
+ break;
+ }
+ case NODE_DVAR:{
+ int lv, idx, ls;
+ debugi("nd_vid", node->nd_vid);
+ if (!popped) {
+ idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
+ if (idx < 0) {
+ COMPILE_ERROR(ERROR_ARGS "unknown dvar (%"PRIsVALUE")",
+ rb_id2str(node->nd_vid));
+ goto ng;
+ }
+ ADD_GETLOCAL(ret, line, ls - idx, lv);
+ }
+ break;
+ }
+ case NODE_GVAR:{
+ ADD_INSN1(ret, line, getglobal,
+ ((VALUE)node->nd_entry | 1));
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_IVAR:{
+ debugi("nd_vid", node->nd_vid);
+ if (!popped) {
+ ADD_INSN2(ret, line, getinstancevariable,
+ ID2SYM(node->nd_vid),
+ get_ivar_ic_value(iseq,node->nd_vid));
+ }
+ break;
+ }
+ case NODE_CONST:{
+ debugi("nd_vid", node->nd_vid);
+
+ if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
+ LABEL *lend = NEW_LABEL(line);
+ int ic_index = iseq->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_LABEL(ret, lend);
+ }
+ else {
+ ADD_INSN(ret, line, putnil);
+ ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
+ }
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_CVAR:{
+ if (!popped) {
+ ADD_INSN1(ret, line, getclassvariable,
+ ID2SYM(node->nd_vid));
+ }
+ break;
+ }
+ case NODE_NTH_REF:{
+ if (!popped) {
+ if (!node->nd_nth) {
+ ADD_INSN(ret, line, putnil);
+ break;
+ }
+ ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */,
+ INT2FIX(node->nd_nth << 1));
+ }
+ break;
+ }
+ case NODE_BACK_REF:{
+ if (!popped) {
+ ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */,
+ INT2FIX(0x01 | (node->nd_nth << 1)));
+ }
+ break;
+ }
+ case NODE_MATCH:
+ case NODE_MATCH2:
+ case NODE_MATCH3:{
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(val);
+
+ INIT_ANCHOR(recv);
+ INIT_ANCHOR(val);
+ switch (nd_type(node)) {
+ case NODE_MATCH:
+ ADD_INSN1(recv, line, putobject, node->nd_lit);
+ ADD_INSN2(val, line, getspecial, INT2FIX(0),
+ INT2FIX(0));
+ break;
+ case NODE_MATCH2:
+ CHECK(COMPILE(recv, "receiver", node->nd_recv));
+ CHECK(COMPILE(val, "value", node->nd_value));
+ break;
+ case NODE_MATCH3:
+ CHECK(COMPILE(recv, "receiver", node->nd_value));
+ CHECK(COMPILE(val, "value", node->nd_recv));
+ 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));
+ }
+
+ if (node->nd_args) {
+ compile_named_capture_assign(iseq, ret, node->nd_args);
+ }
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_LIT:{
+ debugp_param("lit", node->nd_lit);
+ if (!popped) {
+ ADD_INSN1(ret, line, putobject, node->nd_lit);
+ }
+ break;
+ }
+ case NODE_STR:{
+ debugp_param("nd_lit", node->nd_lit);
+ if (!popped) {
+ VALUE lit = node->nd_lit;
+ if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
+ lit = freeze_literal(iseq, lit);
+ ADD_INSN1(ret, line, putstring, 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));
+ lit = rb_str_dup(lit);
+ rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
+ lit = rb_str_freeze(lit);
+ }
+ else {
+ lit = rb_fstring(lit);
+ }
+ ADD_INSN1(ret, line, putobject, lit);
+ iseq_add_mark_object_compile_time(iseq, lit);
+ }
+ }
+ break;
+ }
+ case NODE_DSTR:{
+ compile_dstr(iseq, ret, node);
+
+ 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:{
+ ADD_CALL_RECEIVER(ret, line);
+ ADD_INSN1(ret, line, putobject, freeze_literal(iseq, node->nd_lit));
+ ADD_CALL(ret, line, idBackquote, INT2FIX(1));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_DXSTR:{
+ ADD_CALL_RECEIVER(ret, line);
+ compile_dstr(iseq, ret, node);
+ ADD_CALL(ret, line, idBackquote, INT2FIX(1));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_EVSTR:{
+ CHECK(COMPILE(ret, "nd_body", node->nd_body));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ else if (!all_string_result_p(node->nd_body)) {
+ 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);
+ }
+ break;
+ }
+ case NODE_DREGX:{
+ compile_dregx(iseq, ret, node);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_SCOPE:{
+ int ic_index = iseq->body->is_size++;
+ const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(node, make_name_for_block(iseq),
+ ISEQ_TYPE_ONCE_GUARD, line);
+
+ ADD_INSN2(ret, line, once, block_iseq, INT2FIX(ic_index));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_ARGSCAT:{
+ if (popped) {
+ CHECK(COMPILE(ret, "argscat head", node->nd_head));
+ ADD_INSN1(ret, line, splatarray, Qfalse);
+ ADD_INSN(ret, line, pop);
+ CHECK(COMPILE(ret, "argscat body", node->nd_body));
+ ADD_INSN1(ret, line, splatarray, Qfalse);
+ ADD_INSN(ret, line, pop);
+ }
+ else {
+ CHECK(COMPILE(ret, "argscat head", node->nd_head));
+ CHECK(COMPILE(ret, "argscat body", node->nd_body));
+ ADD_INSN(ret, line, concatarray);
+ }
+ break;
+ }
+ case NODE_ARGSPUSH:{
+ if (popped) {
+ CHECK(COMPILE(ret, "arsgpush head", node->nd_head));
+ ADD_INSN1(ret, line, splatarray, Qfalse);
+ ADD_INSN(ret, line, pop);
+ CHECK(COMPILE_(ret, "argspush body", node->nd_body, popped));
+ }
+ else {
+ CHECK(COMPILE(ret, "arsgpush head", node->nd_head));
+ CHECK(COMPILE_(ret, "argspush body", node->nd_body, popped));
+ ADD_INSN1(ret, line, newarray, INT2FIX(1));
+ ADD_INSN(ret, line, concatarray);
+ }
+ break;
+ }
+ case NODE_SPLAT:{
+ CHECK(COMPILE(ret, "splat", node->nd_head));
+ ADD_INSN1(ret, line, splatarray, Qtrue);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_DEFN:{
+ const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn,
+ rb_id2str(node->nd_mid),
+ ISEQ_TYPE_METHOD, line);
+
+ debugp_param("defn/iseq", rb_iseqw_new(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);
+ }
+
+ break;
+ }
+ case NODE_DEFS:{
+ const rb_iseq_t * singleton_method = NEW_ISEQ(node->nd_defn,
+ rb_id2str(node->nd_mid),
+ ISEQ_TYPE_METHOD, line);
+
+ debugp_param("defs/iseq", rb_iseqw_new(singleton_method));
+
+ 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);
+ }
+ 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->nd_1st));
+ CHECK(COMPILE(ret, "alias arg2", node->nd_2nd));
+ ADD_SEND(ret, line, id_core_set_method_alias, INT2FIX(3));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_VALIAS:{
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ 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) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ 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->nd_undef));
+ ADD_SEND(ret, line, id_core_undef_method, INT2FIX(2));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_CLASS:{
+ const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
+ ISEQ_TYPE_CLASS, line);
+ const int flags = VM_DEFINECLASS_TYPE_CLASS |
+ (node->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
+ compile_cpath(ret, iseq, node->nd_cpath);
+
+ CHECK(COMPILE(ret, "super", node->nd_super));
+ ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_MODULE:{
+ const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(node->nd_body,
+ rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid)),
+ ISEQ_TYPE_CLASS, line);
+ const int flags = VM_DEFINECLASS_TYPE_MODULE |
+ compile_cpath(ret, iseq, node->nd_cpath);
+
+ ADD_INSN (ret, line, putnil); /* dummy */
+ ADD_INSN3(ret, line, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_SCLASS:{
+ ID singletonclass;
+ const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_fstring_cstr("singleton class"),
+ ISEQ_TYPE_CLASS, line);
+
+ CHECK(COMPILE(ret, "sclass#recv", node->nd_recv));
+ ADD_INSN (ret, line, putnil);
+ CONST_ID(singletonclass, "singletonclass");
+ ADD_INSN3(ret, line, defineclass,
+ ID2SYM(singletonclass), singleton_class,
+ INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_COLON2:{
+ if (rb_is_const_id(node->nd_mid)) {
+ /* constant */
+ LABEL *lend = NEW_LABEL(line);
+ int ic_index = iseq->body->is_size++;
+
+ DECL_ANCHOR(pref);
+ DECL_ANCHOR(body);
+
+ INIT_ANCHOR(pref);
+ INIT_ANCHOR(body);
+ CHECK(compile_const_prefix(iseq, node, pref, body));
+ if (LIST_INSN_SIZE_ZERO(pref)) {
+ if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
+ ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
+ }
+ else {
+ ADD_INSN(ret, line, putnil);
+ }
+
+ ADD_SEQ(ret, body);
+
+ if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
+ ADD_INSN1(ret, line, setinlinecache, INT2FIX(ic_index));
+ ADD_LABEL(ret, lend);
+ }
+ }
+ else {
+ ADD_SEQ(ret, pref);
+ ADD_SEQ(ret, body);
+ }
+ }
+ else {
+ /* function call */
+ ADD_CALL_RECEIVER(ret, line);
+ CHECK(COMPILE(ret, "colon2#nd_head", node->nd_head));
+ ADD_CALL(ret, line, node->nd_mid, INT2FIX(1));
+ }
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_COLON3:{
+ LABEL *lend = NEW_LABEL(line);
+ int ic_index = iseq->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_INSN(ret, line, pop);
+ }
+
+ ADD_INSN1(ret, line, putobject, rb_cObject);
+ 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_LABEL(ret, lend);
+ }
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_DOT2:
+ case NODE_DOT3:{
+ int excl = type == NODE_DOT3;
+ VALUE flag = INT2FIX(excl);
+ const NODE *b = node->nd_beg;
+ const NODE *e = node->nd_end;
+ if (number_literal_p(b) && number_literal_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);
+ }
+ }
+ else {
+ CHECK(COMPILE_(ret, "min", b, popped));
+ CHECK(COMPILE_(ret, "max", e, popped));
+ if (!popped) {
+ ADD_INSN1(ret, line, newrange, flag);
+ }
+ }
+ break;
+ }
+ case NODE_FLIP2:
+ case NODE_FLIP3:{
+ LABEL *lend = NEW_LABEL(line);
+ LABEL *ltrue = NEW_LABEL(line);
+ LABEL *lfalse = NEW_LABEL(line);
+ CHECK(compile_flip_flop(iseq, ret, node, type == NODE_FLIP2,
+ ltrue, lfalse));
+ ADD_LABEL(ret, ltrue);
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ ADD_INSNL(ret, line, jump, lend);
+ ADD_LABEL(ret, lfalse);
+ ADD_INSN1(ret, line, putobject, Qfalse);
+ ADD_LABEL(ret, lend);
+ break;
+ }
+ case NODE_SELF:{
+ if (!popped) {
+ ADD_INSN(ret, line, putself);
+ }
+ break;
+ }
+ case NODE_NIL:{
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ }
+ break;
+ }
+ case NODE_TRUE:{
+ if (!popped) {
+ ADD_INSN1(ret, line, putobject, Qtrue);
+ }
+ break;
+ }
+ case NODE_FALSE:{
+ if (!popped) {
+ ADD_INSN1(ret, line, putobject, Qfalse);
+ }
+ break;
+ }
+ case NODE_ERRINFO:{
+ if (!popped) {
+ if (iseq->body->type == ISEQ_TYPE_RESCUE) {
+ ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
+ }
+ else {
+ const rb_iseq_t *ip = iseq;
+ int level = 0;
+ while (ip) {
+ if (ip->body->type == ISEQ_TYPE_RESCUE) {
+ break;
+ }
+ ip = ip->body->parent_iseq;
+ level++;
+ }
+ if (ip) {
+ ADD_GETLOCAL(ret, line, LVAR_ERRINFO, level);
+ }
+ else {
+ ADD_INSN(ret, line, putnil);
+ }
+ }
+ }
+ break;
+ }
+ case NODE_DEFINED:
+ if (!popped) {
+ CHECK(compile_defined_expr(iseq, ret, node, Qtrue));
+ }
+ break;
+ case NODE_POSTEXE:{
+ /* compiled to:
+ * ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } }
+ */
+ int is_index = iseq->body->is_size++;
+ const rb_iseq_t *once_iseq = NEW_CHILD_ISEQ((const NODE *)IFUNC_NEW(build_postexe_iseq, node->nd_body, 0),
+ make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+
+ ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index));
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_KW_ARG:
+ {
+ LABEL *end_label = NEW_LABEL(nd_line(node));
+ const NODE *default_value = node->nd_body->nd_value;
+
+ if (default_value == (const NODE *)-1) {
+ /* required argument. do nothing */
+ COMPILE_ERROR(ERROR_ARGS "unreachable");
+ goto ng;
+ }
+ else if (nd_type(default_value) == NODE_LIT ||
+ nd_type(default_value) == NODE_NIL ||
+ nd_type(default_value) == NODE_TRUE ||
+ nd_type(default_value) == NODE_FALSE) {
+ COMPILE_ERROR(ERROR_ARGS "unreachable");
+ goto ng;
+ }
+ else {
+ /* if keywordcheck(_kw_bits, nth_keyword)
+ * 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;
+
+ ADD_INSN2(ret, line, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(keyword_idx));
+ ADD_INSNL(ret, line, branchif, end_label);
+ CHECK(COMPILE_POPPED(ret, "keyword default argument", node->nd_body));
+ ADD_LABEL(ret, end_label);
+ }
+
+ break;
+ }
+ case NODE_DSYM:{
+ compile_dstr(iseq, ret, node);
+ if (!popped) {
+ ADD_INSN(ret, line, intern);
+ }
+ else {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ case NODE_ATTRASGN:{
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(args);
+ unsigned int flag = 0;
+ ID mid = node->nd_mid;
+ LABEL *lskip = 0;
+ VALUE argc;
+
+ /* 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->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 = freeze_literal(iseq, node->nd_args->nd_head->nd_lit);
+ 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_INSN(ret, line, pop);
+ break;
+ }
+
+ INIT_ANCHOR(recv);
+ INIT_ANCHOR(args);
+ argc = setup_args(iseq, args, node->nd_args, &flag, NULL);
+ CHECK(!NIL_P(argc));
+
+ flag |= COMPILE_RECV(recv, "recv", node);
+
+ debugp_param("argc", argc);
+ debugp_param("nd_mid", ID2SYM(mid));
+
+ 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);
+ }
+ if (!popped) {
+ ADD_INSN(ret, line, putnil);
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, args);
+
+ if (flag & VM_CALL_ARGS_BLOCKARG) {
+ 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_INSN1(ret, line, setn, FIXNUM_INC(argc, 3));
+ ADD_INSN (ret, line, pop);
+ }
+ 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_INSN1(ret, line, setn, FIXNUM_INC(argc, 2));
+ ADD_INSN (ret, line, pop);
+ }
+ else {
+ ADD_INSN1(ret, line, setn, FIXNUM_INC(argc, 1));
+ }
+ }
+ else {
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, args);
+ }
+ ADD_SEND_WITH_FLAG(ret, line, mid, argc, INT2FIX(flag));
+ if (lskip) ADD_LABEL(ret, lskip);
+ ADD_INSN(ret, line, pop);
+
+ break;
+ }
+ case NODE_PRELUDE:{
+ const rb_compile_option_t *orig_opt = ISEQ_COMPILE_DATA(iseq)->option;
+ rb_compile_option_t new_opt = *orig_opt;
+ if (node->nd_compile_option) {
+ rb_iseq_make_compile_option(&new_opt, node->nd_compile_option);
+ 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;
+ /* Do NOT restore ISEQ_COVERAGE!
+ * If ISEQ_COVERAGE is not false, finish_iseq_build function in iseq.c
+ * will initialize the counter array of line coverage.
+ * We keep ISEQ_COVERAGE as nil to disable this initialization.
+ * This is not harmful assuming that NODE_PRELUDE pragma does not occur
+ * in NODE tree except the root.
+ */
+ 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);
+ VALUE argc = INT2FIX(0);
+
+ ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ ADD_CALL_WITH_BLOCK(ret, line, idLambda, argc, block);
+
+ if (popped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
+ default:
+ UNKNOWN_NODE("iseq_compile_each", node, COMPILE_NG);
+ ng:
+ debug_node_end();
+ return COMPILE_NG;
+ }
+
+ /* remove tracecoverage instruction if there is no relevant instruction */
+ if (IS_TRACE(ret->last) && ((TRACE*) ret->last)->event == RUBY_EVENT_LINE) {
+ LINK_ELEMENT *insn = ret->last->prev;
+ if (IS_INSN(insn) &&
+ IS_INSN_ID(insn, tracecoverage) &&
+ FIX2LONG(OPERAND_AT(insn, 0)) == RUBY_EVENT_COVERAGE_LINE
+ ) {
+ ELEM_REMOVE(insn); /* remove tracecovearge */
+ RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line - 1, Qnil);
+ }
+ }
+
+ debug_node_end();
+ return COMPILE_OK;
+}
+
+/***************************/
+/* instruction information */
+/***************************/
+
+static int
+insn_data_length(INSN *iobj)
+{
+ return insn_len(iobj->insn_id);
+}
+
+static int
+calc_sp_depth(int depth, INSN *insn)
+{
+ return 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)) {
+ case T_STRING:
+ obj = rb_str_new_cstr(RSTRING_PTR(obj));
+ break;
+ case T_ARRAY:
+ obj = rb_ary_dup(obj);
+ break;
+ }
+ }
+ return rb_inspect(obj);
+}
+
+
+
+static VALUE
+insn_data_to_s_detail(INSN *iobj)
+{
+ VALUE str = rb_sprintf("%-20s ", insn_name(iobj->insn_id));
+
+ if (iobj->operands) {
+ const char *types = insn_op_types(iobj->insn_id);
+ int j;
+
+ for (j = 0; types[j]; j++) {
+ char type = types[j];
+
+ switch (type) {
+ case TS_OFFSET: /* label(destination position) */
+ {
+ LABEL *lobj = (LABEL *)OPERAND_AT(iobj, j);
+ rb_str_catf(str, LABEL_FORMAT, lobj->label_no);
+ break;
+ }
+ break;
+ case TS_ISEQ: /* iseq */
+ {
+ rb_iseq_t *iseq = (rb_iseq_t *)OPERAND_AT(iobj, j);
+ VALUE val = Qnil;
+ if (0 && iseq) { /* TODO: invalidate now */
+ val = (VALUE)iseq;
+ }
+ rb_str_concat(str, opobj_inspect(val));
+ }
+ break;
+ case TS_LINDEX:
+ case TS_NUM: /* ulong */
+ case TS_VALUE: /* VALUE */
+ {
+ VALUE v = OPERAND_AT(iobj, j);
+ 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 */
+ rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
+ break;
+ case TS_CALLINFO: /* call info */
+ {
+ 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>");
+ break;
+ }
+ case TS_CDHASH: /* case/when condition cache */
+ rb_str_cat2(str, "<ch>");
+ break;
+ case TS_FUNCPTR:
+ {
+ rb_insn_func_t func = (rb_insn_func_t)OPERAND_AT(iobj, j);
+#ifdef HAVE_DLADDR
+ Dl_info info;
+ if (dladdr(func, &info) && info.dli_sname) {
+ rb_str_cat2(str, info.dli_sname);
+ break;
+ }
+#endif
+ rb_str_catf(str, "<%p>", func);
+ }
+ break;
+ default:{
+ rb_raise(rb_eSyntaxError, "unknown operand type: %c", type);
+ }
+ }
+ if (types[j + 1]) {
+ rb_str_cat2(str, ", ");
+ }
+ }
+ }
+ return str;
+}
+
+static void
+dump_disasm_list(const LINK_ELEMENT *link)
+{
+ dump_disasm_list_with_cursor(link, NULL, NULL);
+}
+
+static void
+dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, const LABEL *dest)
+{
+ int pos = 0;
+ INSN *iobj;
+ LABEL *lobj;
+ VALUE str;
+
+ printf("-- raw disasm--------\n");
+
+ while (link) {
+ if (curr) printf(curr == link ? "*" : " ");
+ switch (link->type) {
+ case ISEQ_ELEMENT_INSN:
+ {
+ iobj = (INSN *)link;
+ str = insn_data_to_s_detail(iobj);
+ 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 ? " <---" : "");
+ break;
+ }
+ case ISEQ_ELEMENT_TRACE:
+ {
+ 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);
+ break;
+ }
+ default:
+ /* ignore */
+ rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type));
+ }
+ link = link->next;
+ }
+ printf("---------------------\n");
+ fflush(stdout);
+}
+
+const char *
+rb_insns_name(int i)
+{
+ return insn_name_info[i];
+}
+
+VALUE
+rb_insns_name_array(void)
+{
+ VALUE ary = rb_ary_new();
+ int i;
+ for (i = 0; i < VM_INSTRUCTION_SIZE; i++) {
+ rb_ary_push(ary, rb_fstring_cstr(insn_name_info[i]));
+ }
+ return rb_obj_freeze(ary);
+}
+
+static LABEL *
+register_label(rb_iseq_t *iseq, struct st_table *labels_table, VALUE obj)
+{
+ LABEL *label = 0;
+ st_data_t tmp;
+ obj = rb_to_symbol_type(obj);
+
+ if (st_lookup(labels_table, obj, &tmp) == 0) {
+ label = NEW_LABEL(0);
+ st_insert(labels_table, obj, (st_data_t)label);
+ }
+ else {
+ label = (LABEL *)tmp;
+ }
+ LABEL_REF(label);
+ return label;
+}
+
+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"));
+ }
+
+ if (sym == symRescue) return CATCH_TYPE_RESCUE;
+ if (sym == symEnsure) return CATCH_TYPE_ENSURE;
+ if (sym == symRetry) return CATCH_TYPE_RETRY;
+ if (sym == symBreak) return CATCH_TYPE_BREAK;
+ if (sym == symRedo) return CATCH_TYPE_REDO;
+ if (sym == symNext) return CATCH_TYPE_NEXT;
+ rb_raise(rb_eSyntaxError, "invalid exception symbol: %+"PRIsVALUE, sym);
+ return 0;
+}
+
+static int
+iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table,
+ VALUE exception)
+{
+ int i;
+
+ 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_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) {
+ eiseq = NULL;
+ }
+ else {
+ eiseq = rb_iseqw_to_iseq(rb_iseq_load(ptr[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]);
+
+ /* TODO: Dirty Hack! Fix me */
+ if (type == CATCH_TYPE_RESCUE ||
+ type == CATCH_TYPE_BREAK ||
+ type == CATCH_TYPE_NEXT) {
+ ++sp;
+ }
+
+ lcont->sp = sp;
+
+ ADD_CATCH_ENTRY(type, lstart, lend, eiseq, lcont);
+
+ RB_GC_GUARD(v);
+ }
+ return COMPILE_OK;
+}
+
+static struct st_table *
+insn_make_insn_table(void)
+{
+ struct st_table *table;
+ int i;
+ table = st_init_numtable();
+
+ for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
+ st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);
+ }
+
+ return table;
+}
+
+static const rb_iseq_t *
+iseq_build_load_iseq(const rb_iseq_t *iseq, VALUE op)
+{
+ VALUE iseqw;
+ const rb_iseq_t *loaded_iseq;
+
+ if (RB_TYPE_P(op, T_ARRAY)) {
+ iseqw = rb_iseq_load(op, (VALUE)iseq, Qnil);
+ }
+ else if (CLASS_OF(op) == rb_cISeq) {
+ iseqw = op;
+ }
+ else {
+ rb_raise(rb_eSyntaxError, "ISEQ is required");
+ }
+
+ loaded_iseq = rb_iseqw_to_iseq(iseqw);
+ iseq_add_mark_object(iseq, (VALUE)loaded_iseq);
+ return loaded_iseq;
+}
+
+static VALUE
+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;
+
+ 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")));
+
+ if (!NIL_P(vmid)) mid = SYM2ID(vmid);
+ if (!NIL_P(vflag)) flag = NUM2UINT(vflag);
+ if (!NIL_P(vorig_argc)) orig_argc = FIX2INT(vorig_argc);
+
+ if (!NIL_P(vkw_arg)) {
+ int i;
+ int len = RARRAY_LENINT(vkw_arg);
+ size_t n = rb_call_info_kw_arg_bytes(len);
+
+ kw_arg = xmalloc(n);
+ kw_arg->keyword_len = len;
+ for (i = 0; i < len; i++) {
+ VALUE kw = RARRAY_AREF(vkw_arg, i);
+ SYM2ID(kw); /* make immortal */
+ kw_arg->keywords[i] = kw;
+ }
+ }
+ }
+
+ return (VALUE)new_callinfo(iseq, mid, orig_argc, flag, kw_arg, (flag & VM_CALL_ARGS_SIMPLE) == 0);
+}
+
+static rb_event_flag_t
+event_name_to_flag(VALUE sym)
+{
+#define CHECK_EVENT(ev) if (sym == ID2SYM(rb_intern(#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
+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;
+ int line_no = 0;
+ int ret = COMPILE_OK;
+
+ /*
+ * index -> LABEL *label
+ */
+ static struct st_table *insn_table;
+
+ if (insn_table == 0) {
+ insn_table = insn_make_insn_table();
+ }
+
+ for (i=0; i<len; i++) {
+ VALUE obj = ptr[i];
+
+ if (SYMBOL_P(obj)) {
+ 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);
+ }
+ else if (RB_TYPE_P(obj, T_ARRAY)) {
+ VALUE *argv = 0;
+ int argc = RARRAY_LENINT(obj) - 1;
+ st_data_t insn_id;
+ VALUE insn;
+
+ insn = (argc < 0) ? Qnil : RARRAY_AREF(obj, 0);
+ if (st_lookup(insn_table, (st_data_t)insn, &insn_id) == 0) {
+ /* TODO: exception */
+ COMPILE_ERROR(iseq, line_no,
+ "unknown instruction: %+"PRIsVALUE, insn);
+ ret = COMPILE_NG;
+ break;
+ }
+
+ if (argc != insn_len((VALUE)insn_id)-1) {
+ COMPILE_ERROR(iseq, line_no,
+ "operand size mismatch");
+ ret = COMPILE_NG;
+ break;
+ }
+
+ if (argc > 0) {
+ argv = compile_data_alloc(iseq, sizeof(VALUE) * argc);
+ for (j=0; j<argc; j++) {
+ VALUE op = rb_ary_entry(obj, j+1);
+ switch (insn_op_type((VALUE)insn_id, j)) {
+ case TS_OFFSET: {
+ LABEL *label = register_label(iseq, labels_table, op);
+ argv[j] = (VALUE)label;
+ break;
+ }
+ case TS_LINDEX:
+ case TS_NUM:
+ (void)NUM2INT(op);
+ argv[j] = op;
+ break;
+ case TS_VALUE:
+ argv[j] = op;
+ iseq_add_mark_object(iseq, op);
+ break;
+ case TS_ISEQ:
+ {
+ if (op != Qnil) {
+ argv[j] = (VALUE)iseq_build_load_iseq(iseq, op);
+ }
+ else {
+ argv[j] = 0;
+ }
+ }
+ break;
+ case TS_GENTRY:
+ op = rb_to_symbol_type(op);
+ argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
+ break;
+ case TS_IC:
+ argv[j] = op;
+ if (NUM2UINT(op) >= iseq->body->is_size) {
+ iseq->body->is_size = NUM2INT(op) + 1;
+ }
+ break;
+ case TS_CALLINFO:
+ argv[j] = iseq_build_callinfo_from_hash(iseq, op);
+ break;
+ case TS_CALLCACHE:
+ argv[j] = Qfalse;
+ break;
+ case TS_ID:
+ 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_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);
+ LABEL *label =
+ register_label(iseq, labels_table, sym);
+ rb_hash_aset(map, key, (VALUE)label | 1);
+ }
+ RB_GC_GUARD(op);
+ argv[j] = map;
+ rb_iseq_add_mark_object(iseq, map);
+ }
+ break;
+ case TS_FUNCPTR:
+ {
+#if SIZEOF_VALUE <= SIZEOF_LONG
+ long funcptr = NUM2LONG(op);
+#else
+ LONG_LONG funcptr = NUM2LL(op);
+#endif
+ argv[j] = (VALUE)funcptr;
+ }
+ break;
+ default:
+ rb_raise(rb_eSyntaxError, "unknown operand: %c", insn_op_type((VALUE)insn_id, j));
+ }
+ }
+ }
+ ADD_ELEM(anchor,
+ (LINK_ELEMENT*)new_insn_core(iseq, line_no,
+ (enum ruby_vminsn_type)insn_id, argc, argv));
+ }
+ else {
+ rb_raise(rb_eTypeError, "unexpected object for instruction");
+ }
+ }
+ DATA_PTR(labels_wrapper) = 0;
+ validate_labels(iseq, labels_table);
+ if (!ret) return ret;
+ return iseq_setup(iseq, anchor);
+}
+
+#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)
+{
+ VALUE val = rb_hash_aref(param, sym);
+ if (FIXNUM_P(val)) {
+ *dst = FIX2INT(val);
+ return TRUE;
+ }
+ else if (!NIL_P(val)) {
+ rb_raise(rb_eTypeError, "invalid %+"PRIsVALUE" Fixnum: %+"PRIsVALUE,
+ sym, val);
+ }
+ return FALSE;
+}
+
+static const struct rb_iseq_param_keyword *
+iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
+{
+ int i, j;
+ int len = RARRAY_LENINT(keywords);
+ int default_len;
+ VALUE key, sym, default_val;
+ VALUE *dvs;
+ ID *ids;
+ struct rb_iseq_param_keyword *keyword = ZALLOC(struct rb_iseq_param_keyword);
+
+ iseq->body->param.flags.has_kw = TRUE;
+
+ keyword->num = len;
+#define SYM(s) ID2SYM(rb_intern(#s))
+ (void)int_param(&keyword->bits_start, params, SYM(kwbits));
+ i = keyword->bits_start - keyword->num;
+ ids = (ID *)&iseq->body->local_table[i];
+#undef SYM
+
+ /* required args */
+ for (i = 0; i < len; i++) {
+ VALUE val = RARRAY_AREF(keywords, i);
+
+ if (!SYMBOL_P(val)) {
+ goto default_values;
+ }
+ ids[i] = SYM2ID(val);
+ keyword->required_num++;
+ }
+
+ default_values: /* note: we intentionally preserve `i' from previous loop */
+ default_len = len - i;
+ if (default_len == 0) {
+ keyword->table = ids;
+ return keyword;
+ }
+
+ dvs = ALLOC_N(VALUE, (unsigned int)default_len);
+
+ for (j = 0; i < len; i++, j++) {
+ key = RARRAY_AREF(keywords, i);
+ CHECK_ARRAY(key);
+
+ switch (RARRAY_LEN(key)) {
+ case 1:
+ sym = RARRAY_AREF(key, 0);
+ default_val = Qundef;
+ break;
+ case 2:
+ sym = RARRAY_AREF(key, 0);
+ default_val = RARRAY_AREF(key, 1);
+ break;
+ default:
+ rb_raise(rb_eTypeError, "keyword default has unsupported len %+"PRIsVALUE, key);
+ }
+ ids[i] = SYM2ID(sym);
+ dvs[j] = default_val;
+ }
+
+ keyword->table = ids;
+ keyword->default_values = dvs;
+
+ return keyword;
+}
+
+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))
+ 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 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"));
+ DECL_ANCHOR(anchor);
+ INIT_ANCHOR(anchor);
+
+ len = RARRAY_LENINT(locals);
+ iseq->body->local_table_size = len;
+ iseq->body->local_table = tbl = len > 0 ? (ID *)ALLOC_N(ID, iseq->body->local_table_size) : NULL;
+
+ for (i = 0; i < len; i++) {
+ VALUE lv = RARRAY_AREF(locals, i);
+
+ if (sym_arg_rest == lv) {
+ tbl[i] = 0;
+ }
+ else {
+ tbl[i] = FIXNUM_P(lv) ? (ID)FIX2LONG(lv) : SYM2ID(CHECK_SYMBOL(lv));
+ }
+ }
+
+#define INT_PARAM(F) int_param(&iseq->body->param.F, params, SYM(F))
+ if (INT_PARAM(lead_num)) {
+ iseq->body->param.flags.has_lead = TRUE;
+ }
+ if (INT_PARAM(post_num)) iseq->body->param.flags.has_post = TRUE;
+ if (INT_PARAM(post_start)) iseq->body->param.flags.has_post = TRUE;
+ if (INT_PARAM(rest_start)) iseq->body->param.flags.has_rest = TRUE;
+ if (INT_PARAM(block_start)) iseq->body->param.flags.has_block = TRUE;
+#undef INT_PARAM
+ {
+#define INT_PARAM(F) F = (int_param(&x, misc, SYM(F)) ? (unsigned int)x : 0)
+ int x;
+ INT_PARAM(arg_size);
+ INT_PARAM(local_size);
+ INT_PARAM(stack_max);
+#undef INT_PARAM
+ }
+
+ if (RB_TYPE_P(arg_opt_labels, T_ARRAY)) {
+ len = RARRAY_LENINT(arg_opt_labels);
+ iseq->body->param.flags.has_opt = !!(len - 1 >= 0);
+
+ if (iseq->body->param.flags.has_opt) {
+ VALUE *opt_table = ALLOC_N(VALUE, len);
+
+ for (i = 0; i < len; i++) {
+ VALUE ent = RARRAY_AREF(arg_opt_labels, i);
+ LABEL *label = register_label(iseq, labels_table, ent);
+ opt_table[i] = (VALUE)label;
+ }
+
+ iseq->body->param.opt_num = len - 1;
+ iseq->body->param.opt_table = opt_table;
+ }
+ }
+ else if (!NIL_P(arg_opt_labels)) {
+ rb_raise(rb_eTypeError, ":opt param is not an array: %+"PRIsVALUE,
+ arg_opt_labels);
+ }
+
+ if (RB_TYPE_P(keywords, T_ARRAY)) {
+ iseq->body->param.keyword = iseq_build_kw(iseq, params, keywords);
+ }
+ else if (!NIL_P(keywords)) {
+ rb_raise(rb_eTypeError, ":keywords param is not an array: %+"PRIsVALUE,
+ keywords);
+ }
+
+ if (Qtrue == rb_hash_aref(params, SYM(ambiguous_param0))) {
+ iseq->body->param.flags.ambiguous_param0 = TRUE;
+ }
+
+ if (int_param(&i, params, SYM(kwrest))) {
+ struct rb_iseq_param_keyword *keyword = (struct rb_iseq_param_keyword *)iseq->body->param.keyword;
+ if (keyword == NULL) {
+ iseq->body->param.keyword = keyword = ZALLOC(struct rb_iseq_param_keyword);
+ }
+ keyword->rest_start = i;
+ iseq->body->param.flags.has_kwrest = TRUE;
+ }
+#undef SYM
+ iseq_calc_param_size(iseq);
+
+ /* exception */
+ iseq_build_from_ary_exception(iseq, labels_table, exception);
+
+ /* body */
+ iseq_build_from_ary_body(iseq, anchor, body, labels_wrapper);
+
+ iseq->body->param.size = arg_size;
+ iseq->body->local_table_size = local_size;
+ iseq->body->stack_max = stack_max;
+}
+
+/* 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
+ ) {
+ unsigned int i;
+
+ for (i = 0; i < iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
+ return 1;
+ }
+ }
+ iseq = iseq->body->parent_iseq;
+ }
+ }
+ return 0;
+}
+
+int
+rb_local_defined(ID id, const struct rb_block *base_block)
+{
+ const rb_iseq_t *iseq;
+
+ if (base_block && (iseq = vm_block_iseq(base_block)) != NULL) {
+ unsigned int i;
+ iseq = iseq->body->local_iseq;
+
+ for (i=0; i<iseq->body->local_table_size; i++) {
+ if (iseq->body->local_table[i] == id) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+caller_location(VALUE *path, VALUE *realpath)
+{
+ const rb_execution_context_t *ec = GET_EC();
+ const rb_control_frame_t *const cfp =
+ rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
+
+ if (cfp) {
+ int line = rb_vm_get_sourceline(cfp);
+ *path = rb_iseq_path(cfp->iseq);
+ *realpath = rb_iseq_realpath(cfp->iseq);
+ return line;
+ }
+ else {
+ *path = rb_fstring_cstr("<compiled>");
+ *realpath = *path;
+ return 1;
+ }
+}
+
+typedef struct {
+ VALUE arg;
+ rb_insn_func_t 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))
+{
+ VALUE path, realpath;
+ accessor_args acc;
+
+ acc.arg = arg;
+ acc.func = func;
+ acc.line = caller_location(&path, &realpath);
+ return rb_iseq_new_with_opt((const NODE *)IFUNC_NEW(build, (VALUE)&acc, 0),
+ 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)
+{
+ const accessor_args *const args = (void *)a;
+ const int line = args->line;
+
+ iseq_set_local_table(iseq, 0);
+ iseq->body->param.lead_num = 0;
+ iseq->body->param.size = 0;
+
+ ADD_INSN1(ret, line, putobject, args->arg);
+ ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
+ return Qnil;
+}
+
+static VALUE
+for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a)
+{
+ const accessor_args *const args = (void *)a;
+ const int line = args->line;
+ static const ID vars[] = {1, idUScore};
+
+ iseq_set_local_table(iseq, vars);
+ iseq->body->param.lead_num = 1;
+ iseq->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;
+}
+
+/*
+ * func (index) -> (value)
+ */
+const rb_iseq_t *
+rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
+{
+ return method_for_self(name, arg, func, for_self_aref);
+}
+
+/*
+ * func (index, value) -> (index, value)
+ */
+const rb_iseq_t *
+rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
+{
+ return method_for_self(name, arg, func, for_self_aset);
+}
+
+/* ISeq binary format */
+
+typedef unsigned int ibf_offset_t;
+#define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr))
+
+struct ibf_header {
+ char magic[4]; /* YARB */
+ unsigned int major_version;
+ unsigned int minor_version;
+ unsigned int size;
+ unsigned int extra_size;
+
+ unsigned int iseq_list_size;
+ unsigned int id_list_size;
+ unsigned int object_list_size;
+
+ ibf_offset_t iseq_list_offset;
+ ibf_offset_t id_list_offset;
+ ibf_offset_t 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 {
+ 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 */
+};
+
+rb_iseq_t * iseq_alloc(void);
+
+struct ibf_load {
+ const char *buff;
+ const struct ibf_header *header;
+ ID *id_list; /* [id0, ...] */
+ VALUE iseq_list; /* [iseq0, ...] */
+ VALUE obj_list; /* [obj0, ...] */
+ VALUE loader_obj;
+ VALUE str;
+ rb_iseq_t *iseq;
+};
+
+static ibf_offset_t
+ibf_dump_pos(struct ibf_dump *dump)
+{
+ return (unsigned int)rb_str_strlen(dump->str);
+}
+
+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);
+ /* TODO: overflow check */
+ return pos;
+}
+
+static void
+ibf_dump_overwrite(struct ibf_dump *dump, void *buff, unsigned int size, long offset)
+{
+ VALUE str = dump->str;
+ char *ptr = RSTRING_PTR(str);
+ if ((unsigned long)(size + offset) > (unsigned long)RSTRING_LEN(str))
+ rb_bug("ibf_dump_overwrite: overflow");
+ memcpy(ptr + offset, buff, size);
+}
+
+static void *
+ibf_load_alloc(const struct ibf_load *load, ibf_offset_t offset, int size)
+{
+ void *buff = ruby_xmalloc(size);
+ memcpy(buff, load->buff + offset, size);
+ return buff;
+}
+
+#define IBF_W(b, type, n) (type *)(VALUE)ibf_dump_write(dump, (b), sizeof(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))
+
+static int
+ibf_table_lookup(struct st_table *table, st_data_t key)
+{
+ st_data_t val;
+
+ if (st_lookup(table, key, &val)) {
+ return (int)val;
+ }
+ else {
+ return -1;
+ }
+}
+
+static int
+ibf_table_index(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);
+ }
+
+ return index;
+}
+
+/* dump/load generic */
+
+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 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;
+}
+
+static VALUE
+ibf_dump_id(struct ibf_dump *dump, ID id)
+{
+ return (VALUE)ibf_table_index(dump->id_table, (st_data_t)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 id;
+}
+
+/* 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 *
+ibf_dump_iseq(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ if (iseq == NULL) {
+ return (rb_iseq_t *)-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;
+ }
+}
+
+static VALUE
+ibf_dump_gentry(struct ibf_dump *dump, const struct rb_global_entry *entry)
+{
+ return (VALUE)ibf_dump_id(dump, entry->id);
+}
+
+static VALUE
+ibf_load_gentry(const struct ibf_load *load, const struct rb_global_entry *entry)
+{
+ ID gid = ibf_load_id(load, (ID)(VALUE)entry);
+ return (VALUE)rb_global_entry(gid);
+}
+
+static VALUE *
+ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ const int iseq_size = iseq->body->iseq_size;
+ int code_index;
+ VALUE *code;
+ const VALUE *orig_code = rb_iseq_original_iseq(iseq);
+
+ code = ALLOCA_N(VALUE, iseq_size);
+
+ 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);
+ }
+
+ return IBF_W(code, VALUE, iseq_size);
+}
+
+static VALUE *
+ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct rb_iseq_constant_body *body)
+{
+ const int iseq_size = body->iseq_size;
+ int code_index;
+ VALUE *code = IBF_R(body->iseq_encoded, VALUE, iseq_size);
+
+ 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;
+
+ 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];
+
+ 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");
+ }
+ }
+
+
+ return code;
+}
+
+static VALUE *
+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);
+ }
+ else {
+ return NULL;
+ }
+}
+
+static VALUE *
+ibf_load_param_opt_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+{
+ 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;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static struct rb_iseq_param_keyword *
+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;
+
+ 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);
+ }
+ else {
+ return NULL;
+ }
+}
+
+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;
+
+ 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;
+ }
+}
+
+static struct iseq_insn_info_entry *
+ibf_dump_insns_info(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ return IBF_W(iseq->body->insns_info, struct iseq_insn_info_entry, iseq->body->insns_info_size);
+}
+
+static struct iseq_insn_info_entry *
+ibf_load_insns_info(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+{
+ return IBF_R(body->insns_info, struct iseq_insn_info_entry, body->insns_info_size);
+}
+
+static ID *
+ibf_dump_local_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
+{
+ const int size = iseq->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]);
+ }
+
+ return IBF_W(table, ID, size);
+}
+
+static ID *
+ibf_load_local_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+{
+ const int size = body->local_table_size;
+
+ if (size > 0) {
+ ID *table = IBF_R(body->local_table, ID, size);
+ int i;
+
+ for (i=0; i<size; i++) {
+ table[i] = ibf_load_id(load, table[i]);
+ }
+ return table;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static struct iseq_catch_table *
+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);
+ }
+ else {
+ return NULL;
+ }
+}
+
+static struct iseq_catch_table *
+ibf_load_catch_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+{
+ 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;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static struct rb_call_info *
+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);
+ 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++) { /* conver ID for each ci */
+ dump_ci_entries[i].mid = ibf_dump_id(dump, dump_ci_entries[i].mid);
+ }
+ 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 (struct rb_call_info *)(VALUE)ibf_dump_write(dump, dump_ci_entries, byte_size);
+}
+
+static struct rb_call_info *
+ibf_load_ci_entries(const struct ibf_load *load, const struct rb_iseq_constant_body *body)
+{
+ 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);
+ }
+ 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);
+ }
+
+ return ci_entries;
+}
+
+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;
+
+ 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);
+
+ 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.insns_info = ibf_dump_insns_info(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);
+
+ return ibf_dump_write(dump, &dump_body, sizeof(dump_body));
+}
+
+static VALUE
+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);
+ }
+ return str;
+}
+
+static void
+ibf_load_iseq_each(const 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);
+
+ /* 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->insns_info_size = body->insns_info_size;
+
+ RB_OBJ_WRITE(iseq, &load_body->mark_ary, iseq_mark_ary_create((int)body->mark_ary));
+
+ {
+ 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 = 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, 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;
+ load_body->location.code_range = body->location.code_range;
+
+ 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->insns_info = ibf_load_insns_info(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);
+
+ rb_iseq_translate_threaded_code(iseq);
+}
+
+
+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;
+
+ for (i=0; i<size; i++) {
+ list[i] = (ibf_offset_t)NUM2LONG(rb_ary_entry(dump->iseq_list, i));
+ }
+
+ header->iseq_list_offset = ibf_dump_write(dump, list, sizeof(ibf_offset_t) * size);
+ header->iseq_list_size = (unsigned int)size;
+}
+
+struct ibf_dump_id_list_i_arg {
+ struct ibf_dump *dump;
+ long *list;
+ int current_i;
+};
+
+static int
+ibf_dump_id_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++;
+
+ if (rb_id2name(id)) {
+ arg->list[i] = (long)ibf_dump_object(arg->dump, rb_id2str(id));
+ }
+ else {
+ arg->list[i] = 0;
+ }
+
+ return ST_CONTINUE;
+}
+
+static void
+ibf_dump_id_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;
+
+ st_foreach(dump->id_table, ibf_dump_id_list_i, (st_data_t)&arg);
+
+ header->id_list_offset = ibf_dump_write(dump, arg.list, sizeof(long) * size);
+ header->id_list_size = (unsigned int)size;
+}
+
+#define IBF_OBJECT_INTERNAL FL_PROMOTED0
+
+/*
+ * Binary format
+ * - ibf_object_header
+ * - ibf_object_xxx (xxx is type)
+ */
+
+struct ibf_object_header {
+ unsigned int type: 5;
+ unsigned int special_const: 1;
+ unsigned int frozen: 1;
+ unsigned int internal: 1;
+};
+
+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];
+};
+
+struct ibf_object_regexp {
+ long srcstr;
+ char option;
+};
+
+struct ibf_object_array {
+ long len;
+ long ary[1];
+};
+
+struct ibf_object_hash {
+ long len;
+ long keyval[1];
+};
+
+struct ibf_object_struct_range {
+ long class_index;
+ long len;
+ long beg;
+ long end;
+ int excl;
+};
+
+struct ibf_object_bignum {
+ ssize_t slen;
+ BDIGIT digits[1];
+};
+
+enum ibf_object_data_type {
+ IBF_OBJECT_DATA_ENCODING
+};
+
+struct ibf_object_complex_rational {
+ long a, b;
+};
+
+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))
+
+static void
+ibf_dump_object_unsupported(struct ibf_dump *dump, VALUE obj)
+{
+ rb_obj_info_dump(obj);
+ rb_bug("ibf_dump_object_unsupported: unsupported");
+}
+
+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;
+}
+
+static void
+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;
+ }
+ else if (obj == rb_cArray) {
+ cindex = IBF_OBJECT_CLASS_ARRAY;
+ }
+ else if (obj == rb_eStandardError) {
+ cindex = IBF_OBJECT_CLASS_STANDARD_ERROR;
+ }
+ else {
+ rb_obj_info_dump(obj);
+ rb_p(obj);
+ rb_bug("unsupported class");
+ }
+ ibf_dump_write(dump, &cindex, sizeof(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;
+
+ switch (cindex) {
+ case IBF_OBJECT_CLASS_OBJECT:
+ return rb_cObject;
+ case IBF_OBJECT_CLASS_ARRAY:
+ return rb_cArray;
+ case IBF_OBJECT_CLASS_STANDARD_ERROR:
+ return rb_eStandardError;
+ }
+
+ rb_bug("ibf_load_object_class: unknown class (%d)", (int)cindex);
+}
+
+
+static void
+ibf_dump_object_float(struct ibf_dump *dump, VALUE obj)
+{
+ double dbl = RFLOAT_VALUE(obj);
+ ibf_dump_write(dump, &dbl, sizeof(dbl));
+}
+
+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);
+ return DBL2NUM(*dblp);
+}
+
+static void
+ibf_dump_object_string(struct ibf_dump *dump, VALUE obj)
+{
+ long encindex = (long)rb_enc_get_index(obj);
+ long len = RSTRING_LEN(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));
+ }
+
+ IBF_WV(encindex);
+ IBF_WV(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;
+
+ 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));
+ }
+ rb_enc_associate_index(str, encindex);
+
+ if (header->internal) rb_obj_hide(str);
+ if (header->frozen) str = rb_fstring(str);
+
+ return str;
+}
+
+static void
+ibf_dump_object_regexp(struct ibf_dump *dump, VALUE obj)
+{
+ struct ibf_object_regexp regexp;
+ VALUE srcstr = RREGEXP_SRC(obj);
+ regexp.option = (char)rb_reg_options(obj);
+ regexp.srcstr = (long)ibf_dump_object(dump, srcstr);
+ IBF_WV(regexp);
+}
+
+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);
+
+ if (header->internal) rb_obj_hide(reg);
+ if (header->frozen) rb_obj_freeze(reg);
+
+ return reg;
+}
+
+static void
+ibf_dump_object_array(struct ibf_dump *dump, VALUE obj)
+{
+ long i, len = (int)RARRAY_LEN(obj);
+ IBF_WV(len);
+ for (i=0; i<len; i++) {
+ long index = (long)ibf_dump_object(dump, RARRAY_AREF(obj, i));
+ IBF_WV(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);
+ int i;
+
+ for (i=0; i<array->len; i++) {
+ rb_ary_push(ary, ibf_load_object(load, array->ary[i]));
+ }
+
+ if (header->internal) rb_obj_hide(ary);
+ if (header->frozen) rb_obj_freeze(ary);
+
+ return ary;
+}
+
+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);
+ return ST_CONTINUE;
+}
+
+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);
+}
+
+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);
+ 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);
+ }
+ rb_hash_rehash(obj);
+
+ if (header->internal) rb_obj_hide(obj);
+ if (header->frozen) rb_obj_freeze(obj);
+
+ return obj;
+}
+
+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;
+
+ 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);
+ }
+ else {
+ rb_bug("ibf_dump_object_struct: unsupported class");
+ }
+}
+
+static VALUE
+ibf_load_object_struct(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
+{
+ const struct ibf_object_struct_range *range = IBF_OBJBODY(struct ibf_object_struct_range, offset);
+ VALUE beg = ibf_load_object(load, range->beg);
+ VALUE end = ibf_load_object(load, range->end);
+ VALUE obj = rb_range_new(beg, end, range->excl);
+ if (header->internal) rb_obj_hide(obj);
+ if (header->frozen) rb_obj_freeze(obj);
+ return obj;
+}
+
+static void
+ibf_dump_object_bignum(struct ibf_dump *dump, VALUE obj)
+{
+ ssize_t len = BIGNUM_LEN(obj);
+ ssize_t slen = BIGNUM_SIGN(obj) > 0 ? len : len * -1;
+ BDIGIT *d = BIGNUM_DIGITS(obj);
+
+ IBF_WV(slen);
+ IBF_WP(d, BDIGIT, len);
+}
+
+static VALUE
+ibf_load_object_bignum(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
+{
+ const struct ibf_object_bignum *bignum = IBF_OBJBODY(struct ibf_object_bignum, offset);
+ int sign = bignum->slen > 0;
+ ssize_t len = sign > 0 ? bignum->slen : -1 * bignum->slen;
+ VALUE obj = rb_integer_unpack(bignum->digits, len * 2, 2, 0,
+ INTEGER_PACK_LITTLE_ENDIAN | (sign == 0 ? INTEGER_PACK_NEGATIVE : 0));
+ if (header->internal) rb_obj_hide(obj);
+ if (header->frozen) rb_obj_freeze(obj);
+ return obj;
+}
+
+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);
+ }
+ else {
+ 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));
+
+ switch (*typep) {
+ case IBF_OBJECT_DATA_ENCODING:
+ {
+ VALUE encobj = rb_enc_from_encoding(rb_enc_find(data));
+ return encobj;
+ }
+ }
+
+ return ibf_load_object_unsupported(load, header, offset);
+}
+
+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);
+
+ IBF_WV(real);
+ IBF_WV(imag);
+}
+
+static VALUE
+ibf_load_object_complex_rational(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
+{
+ const struct ibf_object_complex_rational *nums = IBF_OBJBODY(struct ibf_object_complex_rational, offset);
+ VALUE a = ibf_load_object(load, nums->a);
+ VALUE b = ibf_load_object(load, nums->b);
+ VALUE obj = header->type == T_COMPLEX ?
+ rb_complex_new(a, b) : rb_rational_new(a, b);
+
+ if (header->internal) rb_obj_hide(obj);
+ if (header->frozen) rb_obj_freeze(obj);
+ return obj;
+}
+
+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);
+}
+
+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);
+ ID id = rb_intern_str(str);
+ return ID2SYM(id);
+}
+
+typedef void (*ibf_dump_object_function)(struct ibf_dump *dump, VALUE obj);
+static ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = {
+ ibf_dump_object_unsupported, /* T_NONE */
+ ibf_dump_object_unsupported, /* T_OBJECT */
+ ibf_dump_object_class, /* T_CLASS */
+ ibf_dump_object_unsupported, /* T_MODULE */
+ ibf_dump_object_float, /* T_FLOAT */
+ ibf_dump_object_string, /* T_STRING */
+ ibf_dump_object_regexp, /* T_REGEXP */
+ ibf_dump_object_array, /* T_ARRAY */
+ ibf_dump_object_hash, /* T_HASH */
+ ibf_dump_object_struct, /* T_STRUCT */
+ ibf_dump_object_bignum, /* T_BIGNUM */
+ ibf_dump_object_unsupported, /* T_FILE */
+ ibf_dump_object_data, /* T_DATA */
+ ibf_dump_object_unsupported, /* T_MATCH */
+ ibf_dump_object_complex_rational, /* T_COMPLEX */
+ ibf_dump_object_complex_rational, /* T_RATIONAL */
+ ibf_dump_object_unsupported, /* 0x10 */
+ ibf_dump_object_unsupported, /* 0x11 T_NIL */
+ ibf_dump_object_unsupported, /* 0x12 T_TRUE */
+ ibf_dump_object_unsupported, /* 0x13 T_FALSE */
+ ibf_dump_object_symbol, /* 0x14 T_SYMBOL */
+ ibf_dump_object_unsupported, /* T_FIXNUM */
+ ibf_dump_object_unsupported, /* T_UNDEF */
+ ibf_dump_object_unsupported, /* 0x17 */
+ ibf_dump_object_unsupported, /* 0x18 */
+ ibf_dump_object_unsupported, /* 0x19 */
+ ibf_dump_object_unsupported, /* T_IMEMO 0x1a */
+ ibf_dump_object_unsupported, /* T_NODE 0x1b */
+ ibf_dump_object_unsupported, /* T_ICLASS 0x1c */
+ ibf_dump_object_unsupported, /* T_ZOMBIE 0x1d */
+ ibf_dump_object_unsupported, /* 0x1e */
+ ibf_dump_object_unsupported /* 0x1f */
+};
+
+static ibf_offset_t
+lbf_dump_object_object(struct ibf_dump *dump, VALUE obj)
+{
+ struct ibf_object_header obj_header;
+ ibf_offset_t current_offset = ibf_dump_pos(dump);
+ 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);
+ }
+ 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);
+ }
+
+ return current_offset;
+}
+
+typedef VALUE (*ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t);
+static ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = {
+ ibf_load_object_unsupported, /* T_NONE */
+ ibf_load_object_unsupported, /* T_OBJECT */
+ ibf_load_object_class, /* T_CLASS */
+ ibf_load_object_unsupported, /* T_MODULE */
+ ibf_load_object_float, /* T_FLOAT */
+ ibf_load_object_string, /* T_STRING */
+ ibf_load_object_regexp, /* T_REGEXP */
+ ibf_load_object_array, /* T_ARRAY */
+ ibf_load_object_hash, /* T_HASH */
+ ibf_load_object_struct, /* T_STRUCT */
+ ibf_load_object_bignum, /* T_BIGNUM */
+ ibf_load_object_unsupported, /* T_FILE */
+ ibf_load_object_data, /* T_DATA */
+ ibf_load_object_unsupported, /* T_MATCH */
+ ibf_load_object_complex_rational, /* T_COMPLEX */
+ ibf_load_object_complex_rational, /* T_RATIONAL */
+ ibf_load_object_unsupported, /* 0x10 */
+ ibf_load_object_unsupported, /* T_NIL */
+ ibf_load_object_unsupported, /* T_TRUE */
+ ibf_load_object_unsupported, /* T_FALSE */
+ ibf_load_object_symbol,
+ ibf_load_object_unsupported, /* T_FIXNUM */
+ ibf_load_object_unsupported, /* T_UNDEF */
+ ibf_load_object_unsupported, /* 0x17 */
+ ibf_load_object_unsupported, /* 0x18 */
+ ibf_load_object_unsupported, /* 0x19 */
+ ibf_load_object_unsupported, /* T_IMEMO 0x1a */
+ ibf_load_object_unsupported, /* T_NODE 0x1b */
+ ibf_load_object_unsupported, /* T_ICLASS 0x1c */
+ ibf_load_object_unsupported, /* T_ZOMBIE 0x1d */
+ ibf_load_object_unsupported, /* 0x1e */
+ 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);
+ }
+ 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);
+
+ if (header->special_const) {
+ VALUE *vp = IBF_OBJBODY(VALUE, offset);
+ obj = *vp;
+ }
+ else {
+ obj = (*load_object_functions[header->type])(load, header, offset);
+ }
+
+ rb_ary_store(load->obj_list, (long)object_index, obj);
+ }
+ iseq_add_mark_object(load->iseq, obj);
+ return obj;
+ }
+}
+
+static void
+ibf_dump_object_list(struct ibf_dump *dump, struct ibf_header *header)
+{
+ VALUE list = rb_ary_tmp_new(RARRAY_LEN(dump->obj_list));
+ int i, size;
+
+ 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);
+
+ for (i=0; i<size; i++) {
+ ibf_offset_t offset = NUM2UINT(RARRAY_AREF(list, i));
+ IBF_WV(offset);
+ }
+
+ header->object_list_size = 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);
+}
+
+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->id_table) {
+ st_free_table(dump->id_table);
+ dump->id_table = 0;
+ }
+ ruby_xfree(dump);
+}
+
+static size_t
+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);
+ return size;
+}
+
+static const rb_data_type_t ibf_dump_type = {
+ "ibf_dump",
+ {ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,},
+ 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+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->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 */
+}
+
+VALUE
+rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
+{
+ struct ibf_dump *dump;
+ struct ibf_header header = {{0}};
+ VALUE dump_obj;
+ VALUE str;
+
+ if (iseq->body->parent_iseq != NULL ||
+ 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");
+ }
+
+ dump_obj = TypedData_Make_Struct(0, struct ibf_dump, &ibf_dump_type, dump);
+ ibf_dump_setup(dump, dump_obj);
+
+ ibf_dump_write(dump, &header, sizeof(header));
+ ibf_dump_write(dump, RUBY_PLATFORM, strlen(RUBY_PLATFORM) + 1);
+ ibf_dump_iseq(dump, iseq);
+
+ header.magic[0] = 'Y'; /* YARB */
+ header.magic[1] = 'A';
+ header.magic[2] = 'R';
+ header.magic[3] = 'B';
+ header.major_version = ISEQ_MAJOR_VERSION;
+ header.minor_version = ISEQ_MINOR_VERSION;
+ ibf_dump_iseq_list(dump, &header);
+ ibf_dump_id_list(dump, &header);
+ ibf_dump_object_list(dump, &header);
+ 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);
+ }
+ else {
+ header.extra_size = 0;
+ }
+
+ ibf_dump_overwrite(dump, &header, sizeof(header), 0);
+
+ str = dump->str;
+ ibf_dump_free(dump);
+ DATA_PTR(dump_obj) = NULL;
+ RB_GC_GUARD(dump_obj);
+ return str;
+}
+
+static const ibf_offset_t *
+ibf_iseq_list(const struct ibf_load *load)
+{
+ return (ibf_offset_t *)(load->buff + load->header->iseq_list_offset);
+}
+
+void
+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;
+ load->iseq = iseq;
+ ibf_load_iseq_each(load, iseq, ibf_iseq_list(load)[iseq->aux.loader.index]);
+ ISEQ_COMPILE_DATA_CLEAR(iseq);
+ FL_UNSET(iseq, ISEQ_NOT_LOADED_YET);
+ load->iseq = prev_src_iseq;
+}
+
+#if USE_LAZY_LOAD
+const rb_iseq_t *
+rb_iseq_complete(const rb_iseq_t *iseq)
+{
+ rb_ibf_load_iseq_complete((rb_iseq_t *)iseq);
+ return iseq;
+}
+#endif
+
+static rb_iseq_t *
+ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq)
+{
+ int iseq_index = (int)(VALUE)index_iseq;
+
+ if (iseq_index == -1) {
+ return NULL;
+ }
+ else {
+ VALUE iseqv = rb_ary_entry(load->iseq_list, iseq_index);
+
+ if (iseqv != Qnil) {
+ return (rb_iseq_t *)iseqv;
+ }
+ else {
+ rb_iseq_t *iseq = iseq_imemo_alloc();
+ FL_SET(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 !USE_LAZY_LOAD
+ rb_ibf_load_iseq_complete(iseq);
+#endif /* !USE_LAZY_LOAD */
+
+ if (load->iseq) {
+ iseq_add_mark_object(load->iseq, (VALUE)iseq);
+ }
+ return iseq;
+ }
+ }
+}
+
+static void
+ibf_load_setup(struct ibf_load *load, VALUE loader_obj, VALUE str)
+{
+ 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->iseq = NULL;
+
+ if (RSTRING_LENINT(str) < (int)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) {
+ 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);
+ }
+ if (strcmp(load->buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) {
+ rb_raise(rb_eRuntimeError, "unmatched platform");
+ }
+}
+
+static void
+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);
+}
+
+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);
+}
+
+static const rb_data_type_t ibf_load_type = {
+ "ibf_loader",
+ {ibf_loader_mark, ibf_loader_free, ibf_loader_memsize,},
+ 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+const rb_iseq_t *
+rb_iseq_ibf_load(VALUE str)
+{
+ 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(load, loader_obj, str);
+ iseq = ibf_load_iseq(load, 0);
+
+ rb_iseq_init_trace(iseq);
+
+ RB_GC_GUARD(loader_obj);
+ return iseq;
+}
+
+VALUE
+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);
+ RB_GC_GUARD(loader_obj);
+ return extra_str;
+}
diff --git a/complex.c b/complex.c
new file mode 100644
index 0000000000..e06faa813b
--- /dev/null
+++ b/complex.c
@@ -0,0 +1,2352 @@
+/*
+ complex.c: Coded by Tadayoshi Funaba 2008-2012
+
+ This implementation is based on Keiju Ishitsuka's Complex library
+ which is written in ruby.
+*/
+
+#include "ruby/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 <math.h>
+#include "internal.h"
+
+#define NDEBUG
+#include "ruby_assert.h"
+
+#define ZERO INT2FIX(0)
+#define ONE INT2FIX(1)
+#define TWO INT2FIX(2)
+#define RFLOAT_0 DBL2NUM(0)
+#if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun) && \
+ !defined(signbit)
+extern int signbit(double);
+#endif
+
+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_finite_p, id_infinite_p, id_rationalize,
+ id_PI;
+
+#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)\
+{\
+ return rb_funcall(x, id_##n, 0);\
+}
+
+#define fun2(n) \
+inline static VALUE \
+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
+ return rb_funcall(x, '+', 1, y);
+}
+
+inline static VALUE
+f_div(VALUE x, VALUE y)
+{
+ if (FIXNUM_P(y) && FIX2LONG(y) == 1)
+ return x;
+ return rb_funcall(x, '/', 1, y);
+}
+
+inline static int
+f_gt_p(VALUE x, VALUE y)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ if (FIXNUM_P(x) && FIXNUM_P(y))
+ return (SIGNED_VALUE)x > (SIGNED_VALUE)y;
+ return RTEST(rb_int_gt(x, y));
+ }
+ else if (RB_FLOAT_TYPE_P(x))
+ return RTEST(rb_float_gt(x, y));
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ int const cmp = rb_cmpint(rb_rational_cmp(x, y), x, y);
+ return cmp > 0;
+ }
+ return RTEST(rb_funcall(x, '>', 1, 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;
+ }
+#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))
+ return x;
+#endif
+ return rb_funcall(x, '-', 1, y);
+}
+
+fun1(abs)
+fun1(arg)
+fun1(denominator)
+
+static VALUE nucomp_negate(VALUE self);
+
+inline static VALUE
+f_negate(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return rb_int_uminus(x);
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return rb_float_uminus(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return rb_rational_uminus(x);
+ }
+ else if (RB_TYPE_P(x, T_COMPLEX)) {
+ return nucomp_negate(x);
+ }
+ return rb_funcall(x, id_negate, 0);
+}
+
+fun1(numerator)
+fun1(real_p)
+
+inline static VALUE
+f_to_i(VALUE x)
+{
+ if (RB_TYPE_P(x, T_STRING))
+ return rb_str_to_inum(x, 10, 0);
+ return rb_funcall(x, id_to_i, 0);
+}
+inline static VALUE
+f_to_f(VALUE x)
+{
+ if (RB_TYPE_P(x, T_STRING))
+ return DBL2NUM(rb_str_to_dbl(x, 0));
+ return rb_funcall(x, id_to_f, 0);
+}
+
+fun1(to_r)
+
+inline static int
+f_eqeq_p(VALUE x, VALUE y)
+{
+ if (FIXNUM_P(x) && FIXNUM_P(y))
+ return x == y;
+ else if (RB_FLOAT_TYPE_P(x) || RB_FLOAT_TYPE_P(y))
+ return NUM2DBL(x) == NUM2DBL(y);
+ return (int)rb_equal(x, y);
+}
+
+fun2(expt)
+fun2(fdiv)
+fun2(quo)
+
+inline static int
+f_negative_p(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x))
+ return INT_NEGATIVE_P(x);
+ else if (RB_FLOAT_TYPE_P(x))
+ return RFLOAT_VALUE(x) < 0.0;
+ else if (RB_TYPE_P(x, T_RATIONAL))
+ return INT_NEGATIVE_P(RRATIONAL(x)->num);
+ return rb_num_negative_p(x);
+}
+
+#define f_positive_p(x) (!f_negative_p(x))
+
+inline static int
+f_zero_p(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return FIXNUM_ZERO_P(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ const VALUE num = RRATIONAL(x)->num;
+ return FIXNUM_ZERO_P(num);
+ }
+ return (int)rb_equal(x, ZERO);
+}
+
+#define f_nonzero_p(x) (!f_zero_p(x))
+
+VALUE rb_flo_is_finite_p(VALUE num);
+inline static int
+f_finite_p(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return TRUE;
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return (int)rb_flo_is_finite_p(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return TRUE;
+ }
+ return RTEST(rb_funcallv(x, id_finite_p, 0, 0));
+}
+
+VALUE rb_flo_is_infinite_p(VALUE num);
+inline static VALUE
+f_infinite_p(VALUE x)
+{
+ if (RB_INTEGER_TYPE_P(x)) {
+ return Qnil;
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ return rb_flo_is_infinite_p(x);
+ }
+ else if (RB_TYPE_P(x, T_RATIONAL)) {
+ return Qnil;
+ }
+ return rb_funcallv(x, id_infinite_p, 0, 0);
+}
+
+inline static int
+f_kind_of_p(VALUE x, VALUE c)
+{
+ return (int)rb_obj_is_kind_of(x, c);
+}
+
+inline static int
+k_numeric_p(VALUE x)
+{
+ return f_kind_of_p(x, rb_cNumeric);
+}
+
+#define k_exact_p(x) (!RB_FLOAT_TYPE_P(x))
+
+#define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x))
+
+#define get_dat1(x) \
+ struct RComplex *dat = RCOMPLEX(x)
+
+#define get_dat2(x,y) \
+ struct RComplex *adat = RCOMPLEX(x), *bdat = RCOMPLEX(y)
+
+inline static VALUE
+nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
+{
+ NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0));
+
+ RCOMPLEX_SET_REAL(obj, real);
+ RCOMPLEX_SET_IMAG(obj, imag);
+ OBJ_FREEZE_RAW(obj);
+
+ return (VALUE)obj;
+}
+
+static VALUE
+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)
+{
+ assert(!RB_TYPE_P(x, T_COMPLEX));
+ return nucomp_s_new_internal(klass, x, ZERO);
+}
+
+inline static VALUE
+f_complex_new_bang2(VALUE klass, VALUE x, VALUE y)
+{
+ assert(!RB_TYPE_P(x, T_COMPLEX));
+ assert(!RB_TYPE_P(y, T_COMPLEX));
+ 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)
+{
+ if (!RB_INTEGER_TYPE_P(num) &&
+ !RB_FLOAT_TYPE_P(num) &&
+ !RB_TYPE_P(num, T_RATIONAL)) {
+ if (!k_numeric_p(num) || !f_real_p(num))
+ rb_raise(rb_eTypeError, "not a real");
+ }
+}
+
+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))
+ return nucomp_s_new_internal(klass, real, imag);
+ else if (f_real_p(real)) {
+ 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)) {
+ get_dat1(real);
+
+ return nucomp_s_new_internal(klass,
+ dat->real,
+ f_add(dat->imag, imag));
+ }
+ else {
+ get_dat2(real, imag);
+
+ return nucomp_s_new_internal(klass,
+ f_sub(adat->real, bdat->imag),
+ f_add(adat->imag, bdat->real));
+ }
+}
+
+/*
+ * call-seq:
+ * Complex.rect(real[, imag]) -> complex
+ * Complex.rectangular(real[, imag]) -> complex
+ *
+ * Returns a complex object which denotes the given rectangular form.
+ *
+ * Complex.rectangular(1, 2) #=> (1+2i)
+ */
+static VALUE
+nucomp_s_new(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE real, imag;
+
+ switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
+ case 1:
+ nucomp_real_check(real);
+ imag = ZERO;
+ break;
+ default:
+ nucomp_real_check(real);
+ nucomp_real_check(imag);
+ break;
+ }
+
+ return nucomp_s_canonicalize_internal(klass, real, imag);
+}
+
+inline static VALUE
+f_complex_new2(VALUE klass, VALUE x, VALUE y)
+{
+ assert(!RB_TYPE_P(x, T_COMPLEX));
+ return nucomp_s_canonicalize_internal(klass, x, y);
+}
+
+static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
+
+/*
+ * call-seq:
+ * Complex(x[, y]) -> numeric
+ *
+ * Returns x+i*y;
+ *
+ * Complex(1, 2) #=> (1+2i)
+ * Complex('1+2i') #=> (1+2i)
+ * Complex(nil) #=> TypeError
+ * Complex(1, nil) #=> TypeError
+ *
+ * Syntax of string form:
+ *
+ * string form = extra spaces , complex , extra spaces ;
+ * complex = real part | [ sign ] , imaginary part
+ * | real part , sign , imaginary part
+ * | rational , "@" , rational ;
+ * real part = rational ;
+ * imaginary part = imaginary unit | unsigned rational , imaginary unit ;
+ * rational = [ sign ] , unsigned rational ;
+ * unsigned rational = numerator | numerator , "/" , denominator ;
+ * numerator = integer part | fractional part | integer part , fractional part ;
+ * denominator = digits ;
+ * integer part = digits ;
+ * fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
+ * imaginary unit = "i" | "I" | "j" | "J" ;
+ * sign = "-" | "+" ;
+ * digits = digit , { digit | "_" , digit };
+ * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
+ * extra spaces = ? \s* ? ;
+ *
+ * See String#to_c.
+ */
+static VALUE
+nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
+{
+ return nucomp_s_convert(argc, argv, rb_cComplex);
+}
+
+#define imp1(n) \
+inline static VALUE \
+m_##n##_bang(VALUE x)\
+{\
+ return rb_math_##n(x);\
+}
+
+imp1(cos)
+imp1(cosh)
+imp1(exp)
+
+static VALUE
+m_log_bang(VALUE x)
+{
+ return rb_math_log(1, &x);
+}
+
+imp1(sin)
+imp1(sinh)
+
+static VALUE
+m_cos(VALUE x)
+{
+ if (f_real_p(x))
+ return m_cos_bang(x);
+ {
+ get_dat1(x);
+ return f_complex_new2(rb_cComplex,
+ f_mul(m_cos_bang(dat->real),
+ m_cosh_bang(dat->imag)),
+ f_mul(f_negate(m_sin_bang(dat->real)),
+ m_sinh_bang(dat->imag)));
+ }
+}
+
+static VALUE
+m_sin(VALUE x)
+{
+ if (f_real_p(x))
+ return m_sin_bang(x);
+ {
+ get_dat1(x);
+ return f_complex_new2(rb_cComplex,
+ f_mul(m_sin_bang(dat->real),
+ m_cosh_bang(dat->imag)),
+ f_mul(m_cos_bang(dat->real),
+ m_sinh_bang(dat->imag)));
+ }
+}
+
+#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) {
+ y = x;
+ x = RFLOAT_0;
+ }
+ else if (arg == M_PI_2+M_PI) {
+ y = f_negate(x);
+ x = RFLOAT_0;
+ }
+ else if (RB_FLOAT_TYPE_P(x)) {
+ 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;
+ }
+ return nucomp_s_new_internal(klass, x, y);
+ }
+ return nucomp_s_canonicalize_internal(klass,
+ f_mul(x, m_cos(y)),
+ f_mul(x, m_sin(y)));
+}
+
+/*
+ * call-seq:
+ * Complex.polar(abs[, arg]) -> complex
+ *
+ * Returns a complex object which denotes the given polar form.
+ *
+ * Complex.polar(3, 0) #=> (3.0+0.0i)
+ * Complex.polar(3, Math::PI/2) #=> (1.836909530733566e-16+3.0i)
+ * Complex.polar(3, Math::PI) #=> (-3.0+3.673819061467132e-16i)
+ * Complex.polar(3, -Math::PI/2) #=> (1.836909530733566e-16-3.0i)
+ */
+static VALUE
+nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE abs, arg;
+
+ 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;
+ }
+ return f_complex_polar(klass, abs, arg);
+}
+
+/*
+ * call-seq:
+ * cmp.real -> real
+ *
+ * Returns the real part.
+ *
+ * Complex(7).real #=> 7
+ * Complex(9, -4).real #=> 9
+ */
+static VALUE
+nucomp_real(VALUE self)
+{
+ get_dat1(self);
+ return dat->real;
+}
+
+/*
+ * call-seq:
+ * cmp.imag -> real
+ * cmp.imaginary -> real
+ *
+ * Returns the imaginary part.
+ *
+ * Complex(7).imaginary #=> 0
+ * Complex(9, -4).imaginary #=> -4
+ */
+static VALUE
+nucomp_imag(VALUE self)
+{
+ get_dat1(self);
+ return dat->imag;
+}
+
+/*
+ * call-seq:
+ * -cmp -> complex
+ *
+ * Returns negation of the value.
+ *
+ * -Complex(1, 2) #=> (-1-2i)
+ */
+static VALUE
+nucomp_negate(VALUE self)
+{
+ get_dat1(self);
+ return f_complex_new2(CLASS_OF(self),
+ f_negate(dat->real), f_negate(dat->imag));
+}
+
+/*
+ * call-seq:
+ * cmp + numeric -> complex
+ *
+ * Performs addition.
+ *
+ * Complex(2, 3) + Complex(2, 3) #=> (4+6i)
+ * Complex(900) + Complex(1) #=> (901+0i)
+ * Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i)
+ * Complex(9, 8) + 4 #=> (13+8i)
+ * Complex(20, 9) + 9.8 #=> (29.8+9i)
+ */
+VALUE
+rb_complex_plus(VALUE self, VALUE other)
+{
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ VALUE real, imag;
+
+ get_dat2(self, other);
+
+ real = f_add(adat->real, bdat->real);
+ imag = f_add(adat->imag, bdat->imag);
+
+ return f_complex_new2(CLASS_OF(self), real, imag);
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ get_dat1(self);
+
+ return f_complex_new2(CLASS_OF(self),
+ f_add(dat->real, other), dat->imag);
+ }
+ return rb_num_coerce_bin(self, other, '+');
+}
+
+/*
+ * call-seq:
+ * cmp - numeric -> complex
+ *
+ * Performs subtraction.
+ *
+ * Complex(2, 3) - Complex(2, 3) #=> (0+0i)
+ * Complex(900) - Complex(1) #=> (899+0i)
+ * Complex(-2, 9) - Complex(-9, 2) #=> (7+7i)
+ * Complex(9, 8) - 4 #=> (5+8i)
+ * Complex(20, 9) - 9.8 #=> (10.2+9i)
+ */
+static VALUE
+nucomp_sub(VALUE self, VALUE other)
+{
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ VALUE real, imag;
+
+ get_dat2(self, other);
+
+ real = f_sub(adat->real, bdat->real);
+ imag = f_sub(adat->imag, bdat->imag);
+
+ return f_complex_new2(CLASS_OF(self), real, imag);
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ get_dat1(self);
+
+ return f_complex_new2(CLASS_OF(self),
+ f_sub(dat->real, other), dat->imag);
+ }
+ return rb_num_coerce_bin(self, other, '-');
+}
+
+static VALUE
+safe_mul(VALUE a, VALUE b, int az, int bz)
+{
+ double v;
+ if (!az && bz && RB_FLOAT_TYPE_P(a) && (v = RFLOAT_VALUE(a), !isnan(v))) {
+ a = signbit(v) ? DBL2NUM(-1.0) : DBL2NUM(1.0);
+ }
+ if (!bz && az && RB_FLOAT_TYPE_P(b) && (v = RFLOAT_VALUE(b), !isnan(v))) {
+ b = signbit(v) ? DBL2NUM(-1.0) : DBL2NUM(1.0);
+ }
+ return f_mul(a, b);
+}
+
+/*
+ * call-seq:
+ * cmp * numeric -> complex
+ *
+ * Performs multiplication.
+ *
+ * Complex(2, 3) * Complex(2, 3) #=> (-5+12i)
+ * Complex(900) * Complex(1) #=> (900+0i)
+ * Complex(-2, 9) * Complex(-9, 2) #=> (0-85i)
+ * Complex(9, 8) * 4 #=> (36+32i)
+ * Complex(20, 9) * 9.8 #=> (196.0+88.2i)
+ */
+VALUE
+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));
+
+ return f_complex_new2(CLASS_OF(self), real, imag);
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ get_dat1(self);
+
+ return f_complex_new2(CLASS_OF(self),
+ f_mul(dat->real, other),
+ f_mul(dat->imag, 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)) {
+ int flo;
+ get_dat2(self, other);
+
+ flo = (RB_FLOAT_TYPE_P(adat->real) || RB_FLOAT_TYPE_P(adat->imag) ||
+ 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));
+ }
+ 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));
+ }
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ get_dat1(self);
+
+ return f_complex_new2(CLASS_OF(self),
+ (*func)(dat->real, other),
+ (*func)(dat->imag, other));
+ }
+ return rb_num_coerce_bin(self, other, id);
+}
+
+#define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
+
+/*
+ * call-seq:
+ * cmp / numeric -> complex
+ * cmp.quo(numeric) -> complex
+ *
+ * Performs division.
+ *
+ * Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i)
+ * Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i)
+ * Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i)
+ * 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)
+{
+ return f_divide(self, other, f_quo, id_quo);
+}
+
+#define nucomp_quo nucomp_div
+
+/*
+ * call-seq:
+ * cmp.fdiv(numeric) -> complex
+ *
+ * Performs division as each part is a float, never returns a float.
+ *
+ * Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i)
+ */
+static VALUE
+nucomp_fdiv(VALUE self, VALUE other)
+{
+ return f_divide(self, other, f_fdiv, id_fdiv);
+}
+
+inline static VALUE
+f_reciprocal(VALUE x)
+{
+ return f_quo(ONE, x);
+}
+
+/*
+ * call-seq:
+ * cmp ** numeric -> complex
+ *
+ * Performs exponentiation.
+ *
+ * Complex('i') ** 2 #=> (-1+0i)
+ * Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i)
+ */
+static VALUE
+nucomp_expt(VALUE self, VALUE other)
+{
+ if (k_numeric_p(other) && k_exact_zero_p(other))
+ return f_complex_new_bang1(CLASS_OF(self), ONE);
+
+ if (RB_TYPE_P(other, T_RATIONAL) && RRATIONAL(other)->den == LONG2FIX(1))
+ other = RRATIONAL(other)->num; /* c14n */
+
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ get_dat1(other);
+
+ if (k_exact_zero_p(dat->imag))
+ other = dat->real; /* c14n */
+ }
+
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ VALUE r, theta, nr, ntheta;
+
+ get_dat1(other);
+
+ r = f_abs(self);
+ theta = f_arg(self);
+
+ nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
+ f_mul(dat->imag, theta)));
+ ntheta = f_add(f_mul(theta, dat->real),
+ f_mul(dat->imag, m_log_bang(r)));
+ 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;
+ }
+ return f_expt(f_reciprocal(self), rb_int_uminus(other));
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ VALUE r, theta;
+
+ if (RB_TYPE_P(other, T_BIGNUM))
+ rb_warn("in a**b, b may be too big");
+
+ r = f_abs(self);
+ theta = f_arg(self);
+
+ return f_complex_polar(CLASS_OF(self), f_expt(r, other),
+ f_mul(theta, other));
+ }
+ return rb_num_coerce_bin(self, other, id_expt);
+}
+
+/*
+ * call-seq:
+ * cmp == object -> true or false
+ *
+ * Returns true if cmp equals object numerically.
+ *
+ * Complex(2, 3) == Complex(2, 3) #=> true
+ * Complex(5) == 5 #=> true
+ * Complex(0) == 0.0 #=> true
+ * Complex('1/3') == 0.33 #=> false
+ * Complex('1/2') == '1/2' #=> false
+ */
+static VALUE
+nucomp_eqeq_p(VALUE self, VALUE other)
+{
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ get_dat2(self, other);
+
+ return f_boolcast(f_eqeq_p(adat->real, bdat->real) &&
+ f_eqeq_p(adat->imag, bdat->imag));
+ }
+ if (k_numeric_p(other) && f_real_p(other)) {
+ get_dat1(self);
+
+ return f_boolcast(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
+ }
+ return f_boolcast(f_eqeq_p(other, self));
+}
+
+/* :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);
+
+ rb_raise(rb_eTypeError, "%"PRIsVALUE" can't be coerced into %"PRIsVALUE,
+ rb_obj_class(other), rb_obj_class(self));
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * cmp.abs -> real
+ * cmp.magnitude -> real
+ *
+ * Returns the absolute part of its polar form.
+ *
+ * Complex(-1).abs #=> 1
+ * Complex(3.0, -4.0).abs #=> 5.0
+ */
+static VALUE
+nucomp_abs(VALUE self)
+{
+ get_dat1(self);
+
+ if (f_zero_p(dat->real)) {
+ VALUE a = f_abs(dat->imag);
+ if (RB_FLOAT_TYPE_P(dat->real) && !RB_FLOAT_TYPE_P(dat->imag))
+ a = f_to_f(a);
+ return a;
+ }
+ if (f_zero_p(dat->imag)) {
+ VALUE a = f_abs(dat->real);
+ if (!RB_FLOAT_TYPE_P(dat->real) && RB_FLOAT_TYPE_P(dat->imag))
+ a = f_to_f(a);
+ return a;
+ }
+ return rb_math_hypot(dat->real, dat->imag);
+}
+
+/*
+ * call-seq:
+ * cmp.abs2 -> real
+ *
+ * Returns square of the absolute value.
+ *
+ * Complex(-1).abs2 #=> 1
+ * Complex(3.0, -4.0).abs2 #=> 25.0
+ */
+static VALUE
+nucomp_abs2(VALUE self)
+{
+ get_dat1(self);
+ return f_add(f_mul(dat->real, dat->real),
+ f_mul(dat->imag, dat->imag));
+}
+
+/*
+ * call-seq:
+ * cmp.arg -> float
+ * cmp.angle -> float
+ * cmp.phase -> float
+ *
+ * Returns the angle part of its polar form.
+ *
+ * Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
+ */
+static VALUE
+nucomp_arg(VALUE self)
+{
+ get_dat1(self);
+ return rb_math_atan2(dat->imag, dat->real);
+}
+
+/*
+ * call-seq:
+ * cmp.rect -> array
+ * cmp.rectangular -> array
+ *
+ * Returns an array; [cmp.real, cmp.imag].
+ *
+ * Complex(1, 2).rectangular #=> [1, 2]
+ */
+static VALUE
+nucomp_rect(VALUE self)
+{
+ get_dat1(self);
+ return rb_assoc_new(dat->real, dat->imag);
+}
+
+/*
+ * call-seq:
+ * cmp.polar -> array
+ *
+ * Returns an array; [cmp.abs, cmp.arg].
+ *
+ * Complex(1, 2).polar #=> [2.23606797749979, 1.1071487177940904]
+ */
+static VALUE
+nucomp_polar(VALUE self)
+{
+ return rb_assoc_new(f_abs(self), f_arg(self));
+}
+
+/*
+ * call-seq:
+ * cmp.conj -> complex
+ * cmp.conjugate -> complex
+ *
+ * Returns the complex conjugate.
+ *
+ * Complex(1, 2).conjugate #=> (1-2i)
+ */
+static VALUE
+nucomp_conj(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
+ *
+ * Returns false.
+ */
+static VALUE
+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
+ *
+ * Returns the denominator (lcm of both denominator - real and imag).
+ *
+ * See numerator.
+ */
+static VALUE
+nucomp_denominator(VALUE self)
+{
+ get_dat1(self);
+ return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
+}
+
+/*
+ * call-seq:
+ * cmp.numerator -> numeric
+ *
+ * Returns the numerator.
+ *
+ * 1 2 3+4i <- numerator
+ * - + -i -> ----
+ * 2 3 6 <- denominator
+ *
+ * c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i)
+ * n = c.numerator #=> (3+4i)
+ * d = c.denominator #=> 6
+ * n / d #=> ((1/2)+(2/3)*i)
+ * Complex(Rational(n.real, d), Rational(n.imag, d))
+ * #=> ((1/2)+(2/3)*i)
+ * See denominator.
+ */
+static VALUE
+nucomp_numerator(VALUE self)
+{
+ VALUE cd;
+
+ get_dat1(self);
+
+ cd = f_denominator(self);
+ return f_complex_new2(CLASS_OF(self),
+ f_mul(f_numerator(dat->real),
+ f_div(cd, f_denominator(dat->real))),
+ f_mul(f_numerator(dat->imag),
+ f_div(cd, f_denominator(dat->imag))));
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_hash(VALUE self)
+{
+ st_index_t v, h[2];
+ VALUE n;
+
+ get_dat1(self);
+ n = rb_hash(dat->real);
+ h[0] = NUM2LONG(n);
+ n = rb_hash(dat->imag);
+ h[1] = NUM2LONG(n);
+ v = rb_memhash(h, sizeof(h));
+ return ST2FIX(v);
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_eql_p(VALUE self, VALUE other)
+{
+ if (RB_TYPE_P(other, T_COMPLEX)) {
+ get_dat2(self, other);
+
+ return f_boolcast((CLASS_OF(adat->real) == CLASS_OF(bdat->real)) &&
+ (CLASS_OF(adat->imag) == CLASS_OF(bdat->imag)) &&
+ f_eqeq_p(self, other));
+
+ }
+ return Qfalse;
+}
+
+inline static int
+f_signbit(VALUE x)
+{
+ if (RB_FLOAT_TYPE_P(x)) {
+ double f = RFLOAT_VALUE(x);
+ return !isnan(f) && signbit(f);
+ }
+ return f_negative_p(x);
+}
+
+inline static int
+f_tpositive_p(VALUE x)
+{
+ return !f_signbit(x);
+}
+
+static VALUE
+f_format(VALUE self, VALUE (*func)(VALUE))
+{
+ VALUE s;
+ int impos;
+
+ get_dat1(self);
+
+ impos = f_tpositive_p(dat->imag);
+
+ s = (*func)(dat->real);
+ rb_str_cat2(s, !impos ? "-" : "+");
+
+ rb_str_concat(s, (*func)(f_abs(dat->imag)));
+ if (!rb_isdigit(RSTRING_PTR(s)[RSTRING_LEN(s) - 1]))
+ rb_str_cat2(s, "*");
+ rb_str_cat2(s, "i");
+
+ return s;
+}
+
+/*
+ * call-seq:
+ * cmp.to_s -> string
+ *
+ * Returns the value as a string.
+ *
+ * Complex(2).to_s #=> "2+0i"
+ * Complex('-8/6').to_s #=> "-4/3+0i"
+ * Complex('1/2i').to_s #=> "0+1/2i"
+ * Complex(0, Float::INFINITY).to_s #=> "0+Infinity*i"
+ * Complex(Float::NAN, Float::NAN).to_s #=> "NaN+NaN*i"
+ */
+static VALUE
+nucomp_to_s(VALUE self)
+{
+ return f_format(self, rb_String);
+}
+
+/*
+ * call-seq:
+ * cmp.inspect -> string
+ *
+ * Returns the value as a string for inspection.
+ *
+ * Complex(2).inspect #=> "(2+0i)"
+ * Complex('-8/6').inspect #=> "((-4/3)+0i)"
+ * Complex('1/2i').inspect #=> "(0+(1/2)*i)"
+ * Complex(0, Float::INFINITY).inspect #=> "(0+Infinity*i)"
+ * Complex(Float::NAN, Float::NAN).inspect #=> "(NaN+NaN*i)"
+ */
+static VALUE
+nucomp_inspect(VALUE self)
+{
+ VALUE s;
+
+ s = rb_usascii_str_new2("(");
+ rb_str_concat(s, f_format(self, rb_inspect));
+ rb_str_cat2(s, ")");
+
+ return s;
+}
+
+#define FINITE_TYPE_P(v) (RB_INTEGER_TYPE_P(v) || RB_TYPE_P(v, T_RATIONAL))
+
+/*
+ * call-seq:
+ * cmp.finite? -> true or false
+ *
+ * Returns +true+ if +cmp+'s magnitude is a finite number,
+ * otherwise returns +false+.
+ */
+static VALUE
+rb_complex_finite_p(VALUE self)
+{
+ get_dat1(self);
+
+ if (f_finite_p(dat->real) && f_finite_p(dat->imag)) {
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+/*
+ * call-seq:
+ * cmp.infinite? -> nil or 1
+ *
+ * Returns values corresponding to the value of +cmp+'s magnitude:
+ *
+ * +finite+:: +nil+
+ * ++Infinity+:: ++1+
+ *
+ * For example:
+ *
+ * (1+1i).infinite? #=> nil
+ * (Float::INFINITY + 1i).infinite? #=> 1
+ */
+static VALUE
+rb_complex_infinite_p(VALUE self)
+{
+ get_dat1(self);
+
+ if (NIL_P(f_infinite_p(dat->real)) && NIL_P(f_infinite_p(dat->imag))) {
+ return Qnil;
+ }
+ return ONE;
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_dumper(VALUE self)
+{
+ return self;
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_loader(VALUE self, VALUE a)
+{
+ get_dat1(self);
+
+ 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;
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_marshal_dump(VALUE self)
+{
+ VALUE a;
+ get_dat1(self);
+
+ a = rb_assoc_new(dat->real, dat->imag);
+ rb_copy_generic_ivar(a, self);
+ return a;
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_marshal_load(VALUE self, VALUE a)
+{
+ Check_Type(a, T_ARRAY);
+ if (RARRAY_LEN(a) != 2)
+ rb_raise(rb_eArgError, "marshaled complex must have an array whose length is 2 but %ld", RARRAY_LEN(a));
+ rb_ivar_set(self, id_i_real, RARRAY_AREF(a, 0));
+ rb_ivar_set(self, id_i_imag, RARRAY_AREF(a, 1));
+ return self;
+}
+
+/* --- */
+
+VALUE
+rb_complex_raw(VALUE x, VALUE y)
+{
+ return nucomp_s_new_internal(rb_cComplex, x, y);
+}
+
+VALUE
+rb_complex_new(VALUE x, VALUE y)
+{
+ return nucomp_s_canonicalize_internal(rb_cComplex, x, y);
+}
+
+VALUE
+rb_complex_polar(VALUE x, VALUE y)
+{
+ return f_complex_polar(rb_cComplex, x, y);
+}
+
+VALUE
+rb_Complex(VALUE x, VALUE y)
+{
+ VALUE a[2];
+ a[0] = x;
+ a[1] = y;
+ return nucomp_s_convert(2, a, rb_cComplex);
+}
+
+VALUE
+rb_complex_abs(VALUE cmp)
+{
+ return nucomp_abs(cmp);
+}
+
+/*
+ * call-seq:
+ * cmp.to_i -> integer
+ *
+ * Returns the value as an integer if possible (the imaginary part
+ * should be exactly zero).
+ *
+ * Complex(1, 0).to_i #=> 1
+ * Complex(1, 0.0).to_i # RangeError
+ * Complex(1, 2).to_i # RangeError
+ */
+static VALUE
+nucomp_to_i(VALUE self)
+{
+ get_dat1(self);
+
+ if (!k_exact_zero_p(dat->imag)) {
+ rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Integer",
+ self);
+ }
+ return f_to_i(dat->real);
+}
+
+/*
+ * call-seq:
+ * cmp.to_f -> float
+ *
+ * Returns the value as a float if possible (the imaginary part should
+ * be exactly zero).
+ *
+ * Complex(1, 0).to_f #=> 1.0
+ * Complex(1, 0.0).to_f # RangeError
+ * Complex(1, 2).to_f # RangeError
+ */
+static VALUE
+nucomp_to_f(VALUE self)
+{
+ get_dat1(self);
+
+ if (!k_exact_zero_p(dat->imag)) {
+ rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Float",
+ self);
+ }
+ return f_to_f(dat->real);
+}
+
+/*
+ * call-seq:
+ * cmp.to_r -> rational
+ *
+ * Returns the value as a rational if possible (the imaginary part
+ * should be exactly zero).
+ *
+ * Complex(1, 0).to_r #=> (1/1)
+ * Complex(1, 0.0).to_r # RangeError
+ * Complex(1, 2).to_r # RangeError
+ *
+ * See rationalize.
+ */
+static VALUE
+nucomp_to_r(VALUE self)
+{
+ get_dat1(self);
+
+ if (!k_exact_zero_p(dat->imag)) {
+ rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
+ self);
+ }
+ return f_to_r(dat->real);
+}
+
+/*
+ * call-seq:
+ * cmp.rationalize([eps]) -> rational
+ *
+ * Returns the value as a rational if possible (the imaginary part
+ * should be exactly zero).
+ *
+ * Complex(1.0/3, 0).rationalize #=> (1/3)
+ * Complex(1, 0.0).rationalize # RangeError
+ * Complex(1, 2).rationalize # RangeError
+ *
+ * See to_r.
+ */
+static VALUE
+nucomp_rationalize(int argc, VALUE *argv, VALUE self)
+{
+ get_dat1(self);
+
+ rb_scan_args(argc, argv, "01", NULL);
+
+ if (!k_exact_zero_p(dat->imag)) {
+ rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
+ self);
+ }
+ return rb_funcallv(dat->real, id_rationalize, argc, argv);
+}
+
+/*
+ * call-seq:
+ * complex.to_c -> self
+ *
+ * Returns self.
+ *
+ * Complex(2).to_c #=> (2+0i)
+ * Complex(-8, 6).to_c #=> (-8+6i)
+ */
+static VALUE
+nucomp_to_c(VALUE self)
+{
+ return self;
+}
+
+/*
+ * call-seq:
+ * nil.to_c -> (0+0i)
+ *
+ * Returns zero as a complex.
+ */
+static VALUE
+nilclass_to_c(VALUE self)
+{
+ return rb_complex_new1(INT2FIX(0));
+}
+
+/*
+ * call-seq:
+ * num.to_c -> complex
+ *
+ * Returns the value as a complex.
+ */
+static VALUE
+numeric_to_c(VALUE self)
+{
+ return rb_complex_new1(self);
+}
+
+#include <ctype.h>
+
+inline static int
+issign(int c)
+{
+ return (c == '-' || c == '+');
+}
+
+static int
+read_sign(const char **s,
+ char **b)
+{
+ int sign = '?';
+
+ if (issign(**s)) {
+ sign = **b = **s;
+ (*s)++;
+ (*b)++;
+ }
+ return sign;
+}
+
+inline static int
+isdecimal(int c)
+{
+ return isdigit((unsigned char)c);
+}
+
+static int
+read_digits(const char **s, int strict,
+ char **b)
+{
+ int us = 1;
+
+ if (!isdecimal(**s))
+ return 0;
+
+ while (isdecimal(**s) || **s == '_') {
+ if (**s == '_') {
+ if (strict) {
+ if (us)
+ return 0;
+ }
+ us = 1;
+ }
+ else {
+ **b = **s;
+ (*b)++;
+ us = 0;
+ }
+ (*s)++;
+ }
+ if (us)
+ do {
+ (*s)--;
+ } while (**s == '_');
+ return 1;
+}
+
+inline static int
+islettere(int c)
+{
+ return (c == 'e' || c == 'E');
+}
+
+static int
+read_num(const char **s, int strict,
+ char **b)
+{
+ if (**s != '.') {
+ if (!read_digits(s, strict, b))
+ return 0;
+ }
+
+ if (**s == '.') {
+ **b = **s;
+ (*s)++;
+ (*b)++;
+ if (!read_digits(s, strict, b)) {
+ (*b)--;
+ return 0;
+ }
+ }
+
+ if (islettere(**s)) {
+ **b = **s;
+ (*s)++;
+ (*b)++;
+ read_sign(s, b);
+ if (!read_digits(s, strict, b)) {
+ (*b)--;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+inline static int
+read_den(const char **s, int strict,
+ char **b)
+{
+ if (!read_digits(s, strict, b))
+ return 0;
+ return 1;
+}
+
+static int
+read_rat_nos(const char **s, int strict,
+ char **b)
+{
+ if (!read_num(s, strict, b))
+ return 0;
+ if (**s == '/') {
+ **b = **s;
+ (*s)++;
+ (*b)++;
+ if (!read_den(s, strict, b)) {
+ (*b)--;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+read_rat(const char **s, int strict,
+ char **b)
+{
+ read_sign(s, b);
+ if (!read_rat_nos(s, strict, b))
+ return 0;
+ return 1;
+}
+
+inline static int
+isimagunit(int c)
+{
+ return (c == 'i' || c == 'I' ||
+ c == 'j' || c == 'J');
+}
+
+static VALUE
+str2num(char *s)
+{
+ if (strchr(s, '/'))
+ return rb_cstr_to_rat(s, 0);
+ if (strpbrk(s, ".eE"))
+ return DBL2NUM(rb_cstr_to_dbl(s, 0));
+ return rb_cstr_to_inum(s, 10, 0);
+}
+
+static int
+read_comp(const char **s, int strict,
+ VALUE *ret, char **b)
+{
+ char *bb;
+ int sign;
+ VALUE num, num2;
+
+ bb = *b;
+
+ sign = read_sign(s, b);
+
+ if (isimagunit(**s)) {
+ (*s)++;
+ num = INT2FIX((sign == '-') ? -1 : + 1);
+ *ret = rb_complex_new2(ZERO, num);
+ return 1; /* e.g. "i" */
+ }
+
+ if (!read_rat_nos(s, strict, b)) {
+ **b = '\0';
+ num = str2num(bb);
+ *ret = rb_complex_new2(num, ZERO);
+ return 0; /* e.g. "-" */
+ }
+ **b = '\0';
+ num = str2num(bb);
+
+ if (isimagunit(**s)) {
+ (*s)++;
+ *ret = rb_complex_new2(ZERO, num);
+ return 1; /* e.g. "3i" */
+ }
+
+ if (**s == '@') {
+ int st;
+
+ (*s)++;
+ bb = *b;
+ st = read_rat(s, strict, b);
+ **b = '\0';
+ if (strlen(bb) < 1 ||
+ !isdecimal(*(bb + strlen(bb) - 1))) {
+ *ret = rb_complex_new2(num, ZERO);
+ return 0; /* e.g. "1@-" */
+ }
+ num2 = str2num(bb);
+ *ret = rb_complex_polar(num, num2);
+ if (!st)
+ return 0; /* e.g. "1@2." */
+ else
+ return 1; /* e.g. "1@2" */
+ }
+
+ if (issign(**s)) {
+ bb = *b;
+ sign = read_sign(s, b);
+ if (isimagunit(**s))
+ num2 = INT2FIX((sign == '-') ? -1 : + 1);
+ else {
+ if (!read_rat_nos(s, strict, b)) {
+ *ret = rb_complex_new2(num, ZERO);
+ return 0; /* e.g. "1+xi" */
+ }
+ **b = '\0';
+ num2 = str2num(bb);
+ }
+ if (!isimagunit(**s)) {
+ *ret = rb_complex_new2(num, ZERO);
+ return 0; /* e.g. "1+3x" */
+ }
+ (*s)++;
+ *ret = rb_complex_new2(num, num2);
+ return 1; /* e.g. "1+2i" */
+ }
+ /* !(@, - or +) */
+ {
+ *ret = rb_complex_new2(num, ZERO);
+ return 1; /* e.g. "3" */
+ }
+}
+
+inline static void
+skip_ws(const char **s)
+{
+ while (isspace((unsigned char)**s))
+ (*s)++;
+}
+
+static int
+parse_comp(const char *s, int strict,
+ VALUE *num)
+{
+ char *buf, *b;
+ VALUE tmp;
+ int ret = 1;
+
+ buf = ALLOCV_N(char, tmp, strlen(s) + 1);
+ b = buf;
+
+ skip_ws(&s);
+ if (!read_comp(&s, strict, num, &b)) {
+ ret = 0;
+ }
+ else {
+ skip_ws(&s);
+
+ if (strict)
+ if (*s != '\0')
+ ret = 0;
+ }
+ ALLOCV_END(tmp);
+
+ return ret;
+}
+
+static VALUE
+string_to_c_strict(VALUE self)
+{
+ char *s;
+ VALUE num;
+
+ rb_must_asciicompat(self);
+
+ s = RSTRING_PTR(self);
+
+ if (!s || memchr(s, '\0', RSTRING_LEN(self)))
+ rb_raise(rb_eArgError, "string contains null byte");
+
+ if (s && s[RSTRING_LEN(self)]) {
+ rb_str_modify(self);
+ s = RSTRING_PTR(self);
+ s[RSTRING_LEN(self)] = '\0';
+ }
+
+ if (!s)
+ s = (char *)"";
+
+ if (!parse_comp(s, 1, &num)) {
+ rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
+ self);
+ }
+
+ return num;
+}
+
+/*
+ * call-seq:
+ * str.to_c -> complex
+ *
+ * Returns a complex which denotes the string form. The parser
+ * ignores leading whitespaces and trailing garbage. Any digit
+ * sequences can be separated by an underscore. Returns zero for null
+ * or garbage string.
+ *
+ * '9'.to_c #=> (9+0i)
+ * '2.5'.to_c #=> (2.5+0i)
+ * '2.5/1'.to_c #=> ((5/2)+0i)
+ * '-3/2'.to_c #=> ((-3/2)+0i)
+ * '-i'.to_c #=> (0-1i)
+ * '45i'.to_c #=> (0+45i)
+ * '3-4i'.to_c #=> (3-4i)
+ * '-4e2-4e-2i'.to_c #=> (-400.0-0.04i)
+ * '-0.0-0.0i'.to_c #=> (-0.0-0.0i)
+ * '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i)
+ * 'ruby'.to_c #=> (0+0i)
+ *
+ * See Kernel.Complex.
+ */
+static VALUE
+string_to_c(VALUE self)
+{
+ char *s;
+ VALUE num;
+
+ rb_must_asciicompat(self);
+
+ s = RSTRING_PTR(self);
+
+ if (s && s[RSTRING_LEN(self)]) {
+ rb_str_modify(self);
+ s = RSTRING_PTR(self);
+ s[RSTRING_LEN(self)] = '\0';
+ }
+
+ if (!s)
+ s = (char *)"";
+
+ (void)parse_comp(s, 0, &num);
+
+ return num;
+}
+
+static VALUE
+nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE a1, a2, backref;
+
+ rb_scan_args(argc, argv, "11", &a1, &a2);
+
+ if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
+ 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);
+ }
+
+ if (RB_TYPE_P(a2, T_STRING)) {
+ a2 = string_to_c_strict(a2);
+ }
+
+ rb_backref_set(backref);
+
+ if (RB_TYPE_P(a1, T_COMPLEX)) {
+ {
+ get_dat1(a1);
+
+ if (k_exact_zero_p(dat->imag))
+ a1 = dat->real;
+ }
+ }
+
+ if (RB_TYPE_P(a2, T_COMPLEX)) {
+ {
+ get_dat1(a2);
+
+ if (k_exact_zero_p(dat->imag))
+ a2 = dat->real;
+ }
+ }
+
+ if (RB_TYPE_P(a1, T_COMPLEX)) {
+ if (argc == 1 || (k_exact_zero_p(a2)))
+ return a1;
+ }
+
+ if (argc == 1) {
+ 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");
+ }
+ else {
+ if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
+ (!f_real_p(a1) || !f_real_p(a2)))
+ return f_add(a1,
+ f_mul(a2,
+ f_complex_new_bang2(rb_cComplex, ZERO, ONE)));
+ }
+
+ {
+ VALUE argv2[2];
+ argv2[0] = a1;
+ argv2[1] = a2;
+ return nucomp_s_new(argc, argv2, klass);
+ }
+}
+
+/* --- */
+
+/*
+ * call-seq:
+ * num.real -> self
+ *
+ * Returns self.
+ */
+static VALUE
+numeric_real(VALUE self)
+{
+ return self;
+}
+
+/*
+ * call-seq:
+ * num.imag -> 0
+ * num.imaginary -> 0
+ *
+ * Returns zero.
+ */
+static VALUE
+numeric_imag(VALUE self)
+{
+ return INT2FIX(0);
+}
+
+/*
+ * call-seq:
+ * num.abs2 -> real
+ *
+ * Returns square of self.
+ */
+static VALUE
+numeric_abs2(VALUE self)
+{
+ return f_mul(self, self);
+}
+
+/*
+ * call-seq:
+ * num.arg -> 0 or float
+ * num.angle -> 0 or float
+ * num.phase -> 0 or float
+ *
+ * Returns 0 if the value is positive, pi otherwise.
+ */
+static VALUE
+numeric_arg(VALUE self)
+{
+ if (f_positive_p(self))
+ return INT2FIX(0);
+ return DBL2NUM(M_PI);
+}
+
+/*
+ * call-seq:
+ * num.rect -> array
+ * num.rectangular -> array
+ *
+ * Returns an array; [num, 0].
+ */
+static VALUE
+numeric_rect(VALUE self)
+{
+ return rb_assoc_new(self, INT2FIX(0));
+}
+
+static VALUE float_arg(VALUE self);
+
+/*
+ * call-seq:
+ * num.polar -> array
+ *
+ * Returns an array; [num.abs, num.arg].
+ */
+static VALUE
+numeric_polar(VALUE self)
+{
+ VALUE abs, arg;
+
+ if (RB_INTEGER_TYPE_P(self)) {
+ abs = rb_int_abs(self);
+ arg = numeric_arg(self);
+ }
+ else if (RB_FLOAT_TYPE_P(self)) {
+ abs = rb_float_abs(self);
+ arg = float_arg(self);
+ }
+ else if (RB_TYPE_P(self, T_RATIONAL)) {
+ abs = rb_rational_abs(self);
+ arg = numeric_arg(self);
+ }
+ else {
+ abs = f_abs(self);
+ arg = f_arg(self);
+ }
+ return rb_assoc_new(abs, arg);
+}
+
+/*
+ * call-seq:
+ * num.conj -> self
+ * num.conjugate -> self
+ *
+ * Returns self.
+ */
+static VALUE
+numeric_conj(VALUE self)
+{
+ return self;
+}
+
+/*
+ * call-seq:
+ * flo.arg -> 0 or float
+ * flo.angle -> 0 or float
+ * flo.phase -> 0 or float
+ *
+ * Returns 0 if the value is positive, pi otherwise.
+ */
+static VALUE
+float_arg(VALUE self)
+{
+ if (isnan(RFLOAT_VALUE(self)))
+ return self;
+ if (f_tpositive_p(self))
+ return INT2FIX(0);
+ return rb_const_get(rb_mMath, id_PI);
+}
+
+/*
+ * A complex number can be represented as a paired real number with
+ * imaginary unit; a+bi. Where a is real part, b is imaginary part
+ * and i is imaginary unit. Real a equals complex a+0i
+ * mathematically.
+ *
+ * Complex object can be created as literal, and also by using
+ * Kernel#Complex, Complex::rect, Complex::polar or to_c method.
+ *
+ * 2+1i #=> (2+1i)
+ * Complex(1) #=> (1+0i)
+ * Complex(2, 3) #=> (2+3i)
+ * Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i)
+ * 3.to_c #=> (3+0i)
+ *
+ * You can also create complex object from floating-point numbers or
+ * strings.
+ *
+ * Complex(0.3) #=> (0.3+0i)
+ * Complex('0.3-0.5i') #=> (0.3-0.5i)
+ * Complex('2/3+3/4i') #=> ((2/3)+(3/4)*i)
+ * Complex('1@2') #=> (-0.4161468365471424+0.9092974268256817i)
+ *
+ * 0.3.to_c #=> (0.3+0i)
+ * '0.3-0.5i'.to_c #=> (0.3-0.5i)
+ * '2/3+3/4i'.to_c #=> ((2/3)+(3/4)*i)
+ * '1@2'.to_c #=> (-0.4161468365471424+0.9092974268256817i)
+ *
+ * A complex object is either an exact or an inexact number.
+ *
+ * Complex(1, 1) / 2 #=> ((1/2)+(1/2)*i)
+ * Complex(1, 1) / 2.0 #=> (0.5+0.5i)
+ */
+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");
+
+ 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);
+ rb_define_singleton_method(rb_cComplex, "polar", nucomp_s_polar, -1);
+
+ rb_define_global_function("Complex", nucomp_f_complex, -1);
+
+ rb_undef_methods_from(rb_cComplex, 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");
+ rb_undef_method(rb_cComplex, "ceil");
+ rb_undef_method(rb_cComplex, "modulo");
+ rb_undef_method(rb_cComplex, "remainder");
+ rb_undef_method(rb_cComplex, "round");
+ rb_undef_method(rb_cComplex, "step");
+ 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, "-@", nucomp_negate, 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, "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, "==", nucomp_eqeq_p, 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, "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, "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, "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);
+
+ rb_define_method(rb_cComplex, "hash", nucomp_hash, 0);
+ rb_define_method(rb_cComplex, "eql?", nucomp_eql_p, 1);
+
+ rb_define_method(rb_cComplex, "to_s", nucomp_to_s, 0);
+ rb_define_method(rb_cComplex, "inspect", nucomp_inspect, 0);
+
+ rb_undef_method(rb_cComplex, "positive?");
+ rb_undef_method(rb_cComplex, "negative?");
+
+ rb_define_method(rb_cComplex, "finite?", rb_complex_finite_p, 0);
+ 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: */
+ rb_define_private_method(compat, "marshal_load", nucomp_marshal_load, 1);
+ rb_marshal_define_compat(rb_cComplex, compat, nucomp_dumper, nucomp_loader);
+
+ /* --- */
+
+ rb_define_method(rb_cComplex, "to_i", nucomp_to_i, 0);
+ rb_define_method(rb_cComplex, "to_f", nucomp_to_f, 0);
+ rb_define_method(rb_cComplex, "to_r", nucomp_to_r, 0);
+ rb_define_method(rb_cComplex, "rationalize", nucomp_rationalize, -1);
+ rb_define_method(rb_cComplex, "to_c", nucomp_to_c, 0);
+ rb_define_method(rb_cNilClass, "to_c", nilclass_to_c, 0);
+ rb_define_method(rb_cNumeric, "to_c", numeric_to_c, 0);
+
+ rb_define_method(rb_cString, "to_c", string_to_c, 0);
+
+ rb_define_private_method(CLASS_OF(rb_cComplex), "convert", nucomp_s_convert, -1);
+
+ /* --- */
+
+ rb_define_method(rb_cNumeric, "real", numeric_real, 0);
+ rb_define_method(rb_cNumeric, "imaginary", numeric_imag, 0);
+ rb_define_method(rb_cNumeric, "imag", numeric_imag, 0);
+ rb_define_method(rb_cNumeric, "abs2", numeric_abs2, 0);
+ rb_define_method(rb_cNumeric, "arg", numeric_arg, 0);
+ rb_define_method(rb_cNumeric, "angle", numeric_arg, 0);
+ rb_define_method(rb_cNumeric, "phase", numeric_arg, 0);
+ rb_define_method(rb_cNumeric, "rectangular", numeric_rect, 0);
+ rb_define_method(rb_cNumeric, "rect", numeric_rect, 0);
+ rb_define_method(rb_cNumeric, "polar", numeric_polar, 0);
+ rb_define_method(rb_cNumeric, "conjugate", numeric_conj, 0);
+ rb_define_method(rb_cNumeric, "conj", numeric_conj, 0);
+
+ rb_define_method(rb_cFloat, "arg", float_arg, 0);
+ rb_define_method(rb_cFloat, "angle", float_arg, 0);
+ rb_define_method(rb_cFloat, "phase", float_arg, 0);
+
+ /*
+ * The imaginary unit.
+ */
+ rb_define_const(rb_cComplex, "I",
+ f_complex_new_bang2(rb_cComplex, ZERO, ONE));
+
+ rb_provide("complex.so"); /* for backward compatibility */
+}
+
+/*
+Local variables:
+c-file-style: "ruby"
+End:
+*/
diff --git a/config.guess b/config.guess
deleted file mode 100644
index d62857905a..0000000000
--- a/config.guess
+++ /dev/null
@@ -1,885 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 93, 94, 95, 96, 1997 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
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Written by Per Bothner <bothner@cygnus.com>.
-# The master version of this file is at the FSF in /home/gd/gnu/lib.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit system type (host/target name).
-#
-# Only a few systems have been added to this list; please add others
-# (but try to keep the structure clean).
-#
-
-# Modified for Human68k by K.Okabe 1997.07.09
-# Last change: 1997.07.09
-
-case "$KSH_VERSION" in
-*X6*)
- echo m68k-sharp-human
- exit 0 ;;
-*)
- ;;
-esac
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- cat <<EOF >dummy.s
- .globl main
- .ent main
-main:
- .frame \$30,0,\$26,0
- .prologue 0
- .long 0x47e03d80 # implver $0
- lda \$2,259
- .long 0x47e20c21 # amask $2,$1
- srl \$1,8,\$2
- sll \$2,2,\$2
- sll \$0,3,\$0
- addl \$1,\$0,\$0
- addl \$2,\$0,\$0
- ret \$31,(\$26),1
- .end main
-EOF
- ${CC-cc} dummy.s -o dummy 2>/dev/null
- if test "$?" = 0 ; then
- ./dummy
- case "$?" in
- 7)
- UNAME_MACHINE="alpha"
- ;;
- 15)
- UNAME_MACHINE="alphaev5"
- ;;
- 14)
- UNAME_MACHINE="alphaev56"
- ;;
- 10)
- UNAME_MACHINE="alphapca56"
- ;;
- 16)
- UNAME_MACHINE="alphaev6"
- ;;
- esac
- fi
- rm -f dummy.s dummy
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
- exit 0 ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit 0 ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-cbm-sysv4
- exit 0;;
- amiga:NetBSD:*:*)
- echo m68k-cbm-netbsd${UNAME_RELEASE}
- exit 0 ;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc64:OpenBSD:*:*)
- echo mips64el-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hkmips:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- arm32:NetBSD:*:*)
- echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- SR2?01:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
- Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- NILE:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit 0 ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit 0 ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
- atari*:NetBSD:*:*)
- echo m68k-atari-netbsd${UNAME_RELEASE}
- exit 0 ;;
- atari*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3*:NetBSD:*:*)
- echo m68k-sun-netbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:NetBSD:*:*)
- echo m68k-apple-netbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- 2020:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- sed 's/^ //' << EOF >dummy.c
- int main (argc, argv) int argc; char **argv; {
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- ${CC-cc} dummy.c -o dummy \
- && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
- -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i?86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- sed 's/^ //' << EOF >dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:4)
- if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=4.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit 0 ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[3478]??:HP-UX:*:*)
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
- 9000/8?? ) HP_ARCH=hppa1.0 ;;
- esac
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- sed 's/^ //' << EOF >dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- i?86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit 0 ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:*:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE}
- exit 0 ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
- exit 0 ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE}
- exit 0 ;;
- CRAY-2:*:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
- F300:UNIX_System_V:*:*)
- FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- F301:UNIX_System_V:*:*)
- echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
- exit 0 ;;
- hp3[0-9][05]:NetBSD:*:*)
- echo m68k-hp-netbsd${UNAME_RELEASE}
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- i?86:BSD/386:*:* | *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:NetBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- *:*:*BOW*:*)
- echo i386-pc-bow
- exit 0 ;;
- i*:CYGWIN*:*)
- echo i386-pc-cygwin32
- exit 0 ;;
- i*:MINGW*:*)
- echo i386-pc-mingw32
- exit 0 ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin32
- exit 0 ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- *:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- *:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us.
- ld_help_string=`ld --help 2>&1`
- ld_supported_emulations=`echo $ld_help_string \
- | sed -ne '/supported emulations:/!d
- s/[ ][ ]*/ /g
- s/.*supported emulations: *//
- s/ .*//
- p'`
- case "$ld_supported_emulations" in
- i?86linux) echo "${UNAME_MACHINE}-pc-linux-aout" ; exit 0 ;;
- i?86coff) echo "${UNAME_MACHINE}-pc-linux-coff" ; exit 0 ;;
- sparclinux) echo "${UNAME_MACHINE}-unknown-linux-aout" ; exit 0 ;;
- m68klinux) echo "${UNAME_MACHINE}-unknown-linux-aout" ; exit 0 ;;
- elf32ppc) echo "powerpc-unknown-linux" ; exit 0 ;;
- esac
-
- if test "${UNAME_MACHINE}" = "alpha" ; then
- sed 's/^ //' <<EOF >dummy.s
- .globl main
- .ent main
- main:
- .frame \$30,0,\$26,0
- .prologue 0
- .long 0x47e03d80 # implver $0
- lda \$2,259
- .long 0x47e20c21 # amask $2,$1
- srl \$1,8,\$2
- sll \$2,2,\$2
- sll \$0,3,\$0
- addl \$1,\$0,\$0
- addl \$2,\$0,\$0
- ret \$31,(\$26),1
- .end main
-EOF
- LIBC=""
- ${CC-cc} dummy.s -o dummy 2>/dev/null
- if test "$?" = 0 ; then
- ./dummy
- case "$?" in
- 7)
- UNAME_MACHINE="alpha"
- ;;
- 15)
- UNAME_MACHINE="alphaev5"
- ;;
- 14)
- UNAME_MACHINE="alphaev56"
- ;;
- 10)
- UNAME_MACHINE="alphapca56"
- ;;
- 16)
- UNAME_MACHINE="alphaev6"
- ;;
- esac
-
- objdump --private-headers dummy | \
- grep ld.so.1 > /dev/null
- if test "$?" = 0 ; then
- LIBC="-libc1"
- fi
- fi
- rm -f dummy.s dummy
- echo ${UNAME_MACHINE}-unknown-linux${LIBC} ; exit 0
- elif test "${UNAME_MACHINE}" = "mips" ; then
- cat >dummy.c <<EOF
-main(argc, argv)
- int argc;
- char *argv[];
-{
-#ifdef __MIPSEB__
- printf ("%s-unknown-linux\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
- printf ("%sel-unknown-linux\n", argv[1]);
-#endif
- return 0;
-}
-EOF
- ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- else
- case "${UNAME_MACHINE}" in
- i?86)
- VENDOR=pc;
- ;;
- *)
- VENDOR=unknown;
- ;;
- esac
- echo ${UNAME_MACHINE}-${VENDOR}-linux
- exit 0
- fi ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
-# are messed up and put the nodename in both sysname and nodename.
- i?86:DYNIX/ptx:4*:*)
- echo i386-sequent-sysv4
- exit 0 ;;
- i?86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
- i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- i?86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit 0 ;;
- pc:*:*:*)
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit 0 ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- M68*:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m68*:LynxOS:2.*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- i?86:LynxOS:2.*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
- PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit 0 ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit 0 ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit 0 ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
- X680[02346]0:Human68k:*:*)
- echo m68k-sharp-human
- exit 0 ;;
- news*:NEWS-OS:*:6*)
- echo mips-sony-newsos6
- exit 0 ;;
- R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- DS/90*:*:*:V20*)
- echo sparc-fujitsu-uxpds
- exit 0 ;;
- BeBox:BeOS:*:*)
- echo powerpc-be-beos
- exit 0 ;;
- BeMac:BeOS:*:*)
- echo powerpc-apple-beos
- exit 0 ;;
- BePC:BeOS:*:*)
- echo i586-pc-beos
- exit 0 ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-cat >dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-#if !defined (ultrix)
- printf ("vax-dec-bsd\n"); exit (0);
-#else
- printf ("vax-dec-ultrix\n"); exit (0);
-#endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
-rm -f dummy.c dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-#echo '(Unable to guess system type)' 1>&2
-
-exit 1
diff --git a/config.sub b/config.sub
deleted file mode 100644
index 9775812226..0000000000
--- a/config.sub
+++ /dev/null
@@ -1,966 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-if [ x$1 = x ]
-then
- echo Configuration name missing. 1>&2
- echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
- echo "or $0 ALIAS" 1>&2
- echo where ALIAS is a recognized configuration type. 1>&2
- exit 1
-fi
-
-# First pass through any local machine types.
-case $1 in
- *local*)
- echo $1
- exit 0
- ;;
- *)
- ;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- linux-gnu*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple)
- os=
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco5)
- os=sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
- | arme[lb] | pyramid | mn10200 | mn10300 \
- | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
- | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
- | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
- | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
- | mipstx39 | mipstx39el \
- | sparc | sparclet | sparclite | sparc64 | v850)
- basic_machine=$basic_machine-unknown
- ;;
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i[3456]86)
- basic_machine=$basic_machine-pc
- ;;
- i[3456]86-TOWNS*)
- basic_machine=`echo $basic_machine | sed -e 's/-TOWNS.*/-TOWNS/'`
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
- | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
- | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
- | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
- | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
- | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
- | sparc64-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* \
- | mipstx39-* | mipstx39el-* \
- | f301-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-cbm
- ;;
- amigaos | amigados)
- basic_machine=m68k-cbm
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-cbm
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- [ctj]90-cray)
- basic_machine=c90-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- os=-mvs
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[3456]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i[3456]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i[3456]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i[3456]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium | p5)
- basic_machine=i586-intel
- ;;
- pentiumpro | p6)
- basic_machine=i686-intel
- ;;
- pentium-* | p5-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- k5)
- # We don't have specific support for AMD's K5 yet, so just call it a Pentium
- basic_machine=i586-amd
- ;;
- nexen)
- # We don't have specific support for Nexgen yet, so just call it a Pentium
- basic_machine=i586-nexgen
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=rs6000-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- mips)
- if [ x$os = x-linux ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sparc)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- human)
- basic_machine=m68k-sharp
- os=-human
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -cygwin32* | -pe* | -psos* | -moss* | -proelf* \
- | -linux* | -bow* | -rhapsody* | -openstep* )
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -xenix)
- os=-xenix
- ;;
- -uxpds)
- os=-uxpds
- ;;
- -human)
- ;;
- -beos)
- os=-beos
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-semi)
- os=-aout
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-ibm)
- os=-aix
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f301-fujitsu)
- os=-uxpv
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -hpux*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -vxsim* | -vxworks*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
diff --git a/config_h.dj b/config_h.dj
deleted file mode 100644
index 2a81c29594..0000000000
--- a/config_h.dj
+++ /dev/null
@@ -1,64 +0,0 @@
-#define THREAD 1
-#define SIZEOF_INT 4
-#define SIZEOF_LONG 4
-#define SIZEOF_VOIDP 4
-#define HAVE_PROTOTYPES 1
-#define HAVE_STDARG_PROTOTYPES 1
-#define HAVE_ATTR_NORETURN 1
-#define HAVE_DIRENT_H 1
-#define STDC_HEADERS 1
-#define HAVE_STDLIB_H 1
-#define HAVE_UNISTD_H 1
-#define HAVE_LIMITS_H 1
-#define HAVE_SYS_FILE_H 1
-#define HAVE_SYS_IOCTL_H 1
-#define HAVE_PWD_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_SYS_TIMES_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_WAIT_H 1
-#define HAVE_STRING_H 1
-#define HAVE_UTIME_H 1
-#define HAVE_MEMORY_H 1
-#define HAVE_DIRECT_H 1
-#define HAVE_ST_BLKSIZE 1
-#define HAVE_ST_RDEV 1
-#define GETGROUPS_T gid_t
-#define RETSIGTYPE void
-#define HAVE_ALLOCA 1
-#define vfork fork
-#define HAVE_DUP2 1
-#define HAVE_SETENV 1
-#define HAVE_MEMMOVE 1
-#define HAVE_MKDIR 1
-#define HAVE_STRCASECMP 1
-#define HAVE_STRERROR 1
-#define HAVE_STRFTIME 1
-#define HAVE_STRCHR 1
-#define HAVE_STRSTR 1
-#define HAVE_STRTOUL 1
-#define HAVE_STRDUP 1
-#define HAVE_FMOD 1
-#define HAVE_RANDOM 1
-#define HAVE_WAITPID 1
-#define HAVE_GETCWD 1
-#define HAVE_TRUNCATE 1
-#define HAVE_CHSIZE 1
-#define HAVE_TIMES 1
-#define HAVE_UTIMES 1
-#define HAVE_FCNTL 1
-/*#define HAVE_SETITIMER 1*/
-#define HAVE_GETGROUPS 1
-#define HAVE_SIGPROCMASK 1
-#define HAVE_SIGACTION 1
-#define HAVE_SETSID 1
-#define POSIX_SIGNAL 1
-#define BSD_SETPGRP setpgrp
-#define RSHIFT(x,y) ((x)>>y)
-#define FILE_COUNT _cnt
-#define DLEXT ".o"
-#define RUBY_LIB "/usr/local/lib/ruby"
-#define RUBY_SITE_LIB "/usr/local/lib/ruby/site_ruby"
-#define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-djgpp"
-#define RUBY_SITE_ARCHLIB "/usr/local/lib/ruby/site_ruby/i386-djgpp"
-#define RUBY_PLATFORM "i386-djgpp"
diff --git a/config_s.dj b/config_s.dj
deleted file mode 100644
index d6d3836613..0000000000
--- a/config_s.dj
+++ /dev/null
@@ -1,49 +0,0 @@
-s%@CFLAGS@%-g -O2%g
-s%@CPPFLAGS@%%g
-s%@CXXFLAGS@%%g
-s%@DEFS@% -DTHREAD=1 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_VOIDP=4 -DHAVE_PROTOTYPES=1 -DHAVE_STDARG_PROTOTYPES=1 -DHAVE_ATTR_NORETURN=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_PWD_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_STRING_H=1 -DHAVE_UTIME_H=1 -DHAVE_MEMORY_H=1 -DHAVE_DIRECT_H=1 -DHAVE_ST_BLKSIZE=1 -DHAVE_ST_RDEV=1 -DGETGROUPS_T=gid_t -DRETSIGTYPE=void -DHAVE_ALLOCA=1 -Dvfork=fork -DHAVE_DUP2=1 -DHAVE_SETENV=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRERROR=1 -DHAVE_STRFTIME=1 -DHAVE_STRCHR=1 -DHAVE_STRSTR=1 -DHAVE_STRTOUL=1 -DHAVE_STRDUP=1 -DHAVE_FMOD=1 -DHAVE_RANDOM=1 -DHAVE_WAITPID=1 -DHAVE_GETCWD=1 -DHAVE_TRUNCATE=1 -DHAVE_CHSIZE=1 -DHAVE_TIMES=1 -DHAVE_UTIMES=1 -DHAVE_FCNTL=1 -DHAVE_SETITIMER=1 -DHAVE_GETGROUPS=1 -DHAVE_SIGPROCMASK=1 -DHAVE_SIGACTION=1 -DHAVE_SETSID=1 -DPOSIX_SIGNAL=1 -DBSD_SETPGRP=setpgrp -DRSHIFT=\(x,y\)\ \(\(x\)\>\>y\) -DFILE_COUNT=_cnt -DDLEXT=\".so\" -DRUBY_LIB=\"/usr/local/lib/ruby\" -DRUBY_SITE_LIB=\"/usr/local/lib/ruby/site_ruby\" -DRUBY_ARCHLIB=\"/usr/local/lib/ruby/i386-djgpp\" -DRUBY_SITE_ARCHLIB=\"/usr/local/lib/ruby/site_ruby/i386-djgpp\" -DRUBY_PLATFORM=\"i386-djgpp\" %g
-s%@LDFLAGS@%%g
-s%@LIBS@%-lm %g
-s%@exec_prefix@%${prefix}%g
-s%@prefix@%/usr/local%g
-s%@program_transform_name@%s,x,x,%g
-s%@bindir@%${exec_prefix}/bin%g
-s%@sbindir@%${exec_prefix}/sbin%g
-s%@libexecdir@%${exec_prefix}/libexec%g
-s%@datadir@%${prefix}/share%g
-s%@sysconfdir@%${prefix}/etc%g
-s%@sharedstatedir@%${prefix}/com%g
-s%@localstatedir@%${prefix}/var%g
-s%@libdir@%${exec_prefix}/lib%g
-s%@includedir@%${prefix}/include%g
-s%@oldincludedir@%/usr/include%g
-s%@infodir@%${prefix}/info%g
-s%@mandir@%${prefix}/man%g
-s%@host@%i386-pc-djgpp%g
-s%@host_alias@%i386-djgpp%g
-s%@host_cpu@%i386%g
-s%@host_vendor@%pc%g
-s%@host_os@%djgpp%g
-s%@CC@%gcc%g
-s%@CPP@%gcc -E%g
-s%@YACC@%bison -y%g
-s%@RANLIB@%ranlib%g
-s%@AR@%ar%g
-s%@INSTALL_PROGRAM@%${INSTALL}%g
-s%@INSTALL_DATA@%${INSTALL} -m 644%g
-s%@SET_MAKE@%%g
-s%@LIBOBJS@% crypt.o flock.o snprintf.o%g
-s%@ALLOCA@%%g
-s%@DLDFLAGS@%%g
-s%@STATIC@%%g
-s%@CCDLFLAGS@%%g
-s%@LDSHARED@%ld%g
-s%@DLEXT@%o%g
-s%@STRIP@%strip%g
-s%@EXTSTATIC@%%g
-s%@binsuffix@%.exe%g
-s%@setup@%Setup%g
-s%@LIBRUBY@%libruby.a%g
-s%@LIBRUBYARG@%libruby.a%g
-s%@SOLIBS@%%g
-s%@arch@%i386-djgpp%g
diff --git a/configure b/configure
deleted file mode 100644
index b3e31db719..0000000000
--- a/configure
+++ /dev/null
@@ -1,4273 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.12
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
---without-gcc never use gcc"
-ac_help="$ac_help
---disable-thread never use user-level thread"
-ac_help="$ac_help
---enable-fat-binary build a NeXT/Apple Multi Architecture Binary. "
-ac_help="$ac_help
---with-dln-a-out use dln_a_out if possible"
-ac_help="$ac_help
---with-static-linked-ext link external modules statically"
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.12"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=ruby.h
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-
-# Check whether --with-gcc or --without-gcc was given.
-if test "${with_gcc+set}" = set; then
- withval="$with_gcc"
-
- case $withval in
- no) CC=cc
- without_gcc=yes;;
- yes) CC=gcc
- without_gcc=no;;
- *) CC=$withval
- without_gcc=$withval;;
- esac
-else
- without_gcc=no
-fi
-
-if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
-then
- { echo "configure: error: cached CC is different -- throw away $cache_file
-(it is also a good idea to do 'make clean' before compiling)" 1>&2; exit 1; }
-fi
-
-rb_thread=yes
-# Check whether --enable-thread or --disable-thread was given.
-if test "${enable_thread+set}" = set; then
- enableval="$enable_thread"
-
- rb_thread=$enableval
-
-fi
-
-if test $rb_thread = yes; then
- cat >> confdefs.h <<\EOF
-#define THREAD 1
-EOF
-
-fi
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:597: checking host system type" >&5
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`$ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-
-fat_binary=no
-# Check whether --enable-fat-binary or --disable-fat-binary was given.
-if test "${enable_fat_binary+set}" = set; then
- enableval="$enable_fat_binary"
- fat_binary=$enableval
-fi
-
- if test "$fat_binary" = yes ; then
-
- echo $ac_n "checking target architecture ""... $ac_c" 1>&6
-echo "configure:628: checking target architecture " >&5
-
- if test "$host_os" = "rhapsody" ; then
- echo -n "Rhapsody: "
- if test "$TARGET_ARCHS" = "" ; then
- TARGET_ARCHS="ppc i486"
- fi
- else
- echo -n "NeXTSTEP/OPENSTEP: "
- if test "$TARGET_ARCHS" = "" ; then
- if test `/usr/bin/arch` = "m68k" ; then
- TARGET_ARCHS="m68k i486"
- else
- TARGET_ARCHS="m68k `/usr/bin/arch`"
- fi
- fi
- fi
- # /usr/lib/arch_tool -archify_list $TARGET_ARCHS
- for archs in $TARGET_ARCHS
- do
- ARCH_FLAG="$ARCH_FLAG -arch $archs "
- echo -n " $archs"
- done
- cat >> confdefs.h <<\EOF
-#define NEXT_FAT_BINARY 1
-EOF
-
- echo "."
-fi
-
-if test "$program_transform_name" = s,x,x,; then
- program_transform_name=
-else
- # Double any \ or $. echo might interpret backslashes.
- cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
- program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
- rm -f conftestsed
-fi
-test "$program_prefix" != NONE &&
- program_transform_name="s,^,${program_prefix},; $program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
-
-# sed with no file args requires a program.
-test "$program_transform_name" = "" && program_transform_name="s,x,x,"
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:681: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:710: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- ac_prog_rejected=no
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:758: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext <<EOF
-#line 768 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-if { (eval echo configure:772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
- else
- ac_cv_prog_cc_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:792: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:797: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
- ac_test_CFLAGS="${CFLAGS+set}"
- ac_save_CFLAGS="$CFLAGS"
- CFLAGS=
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:821: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
-else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
- if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
- elif test $ac_cv_prog_cc_g = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-O2"
- fi
-else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:849: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 864 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:870: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 881 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:887: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:911: checking whether ${CC-cc} needs -traditional" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_pattern="Autoconf.*'x'"
- cat > conftest.$ac_ext <<EOF
-#line 917 "configure"
-#include "confdefs.h"
-#include <sgtty.h>
-Autoconf TIOCGETP
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "$ac_pattern" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_prog_gcc_traditional=yes
-else
- rm -rf conftest*
- ac_cv_prog_gcc_traditional=no
-fi
-rm -f conftest*
-
-
- if test $ac_cv_prog_gcc_traditional = no; then
- cat > conftest.$ac_ext <<EOF
-#line 935 "configure"
-#include "confdefs.h"
-#include <termio.h>
-Autoconf TCGETA
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "$ac_pattern" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_prog_gcc_traditional=yes
-fi
-rm -f conftest*
-
- fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
- if test $ac_cv_prog_gcc_traditional = yes; then
- CC="$CC -traditional"
- fi
-fi
-
-for ac_prog in 'bison -y' byacc
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:961: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$YACC"; then
- ac_cv_prog_YACC="$YACC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_YACC="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-YACC="$ac_cv_prog_YACC"
-if test -n "$YACC"; then
- echo "$ac_t""$YACC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$YACC" && break
-done
-test -n "$YACC" || YACC="yacc"
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:993: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-for ac_prog in ar aal
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1025: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_AR="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-AR="$ac_cv_prog_AR"
-if test -n "$AR"; then
- echo "$ac_t""$AR" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$AR" && break
-done
-test -n "$AR" || AR="ar"
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1065: checking for a BSD compatible install" >&5
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- # Account for people who put trailing slashes in PATH elements.
- case "$ac_dir/" in
- /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
- if test -f $ac_dir/$ac_prog; then
- if test $ac_prog = install &&
- grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
- :
- else
- ac_cv_path_install="$ac_dir/$ac_prog -c"
- break 2
- fi
- fi
- done
- ;;
- esac
- done
- IFS="$ac_save_IFS"
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL="$ac_cv_path_install"
- else
- # As a last resort, use the slow shell script. We don't cache a
- # path for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the path is relative.
- INSTALL="$ac_install_sh"
- fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1115: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftestmake <<\EOF
-all:
- @echo 'ac_maketemp="${MAKE}"'
-EOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
- eval ac_cv_prog_make_${ac_make}_set=yes
-else
- eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- SET_MAKE=
-else
- echo "$ac_t""no" 1>&6
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-# checks for UNIX variants that set C preprocessor variables
-ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
-echo "configure:1145: checking for minix/config.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1150 "configure"
-#include "confdefs.h"
-#include <minix/config.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- MINIX=yes
-else
- echo "$ac_t""no" 1>&6
-MINIX=
-fi
-
-if test "$MINIX" = yes; then
- cat >> confdefs.h <<\EOF
-#define _POSIX_SOURCE 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define _POSIX_1_SOURCE 2
-EOF
-
- cat >> confdefs.h <<\EOF
-#define _MINIX 1
-EOF
-
-fi
-
-
-echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:1194: checking size of int" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1202 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(int));
- exit(0);
-}
-EOF
-if { (eval echo configure:1213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_sizeof_int=`cat conftestval`
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_sizeof_int=0
-fi
-rm -fr conftest*
-fi
-
-fi
-echo "$ac_t""$ac_cv_sizeof_int" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-EOF
-
-
-echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:1233: checking size of long" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1241 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(long));
- exit(0);
-}
-EOF
-if { (eval echo configure:1252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_sizeof_long=`cat conftestval`
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_sizeof_long=0
-fi
-rm -fr conftest*
-fi
-
-fi
-echo "$ac_t""$ac_cv_sizeof_long" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-EOF
-
-
-echo $ac_n "checking size of void*""... $ac_c" 1>&6
-echo "configure:1272: checking size of void*" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_voidp'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1280 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
- FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
- fprintf(f, "%d\n", sizeof(void*));
- exit(0);
-}
-EOF
-if { (eval echo configure:1291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_sizeof_voidp=`cat conftestval`
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_sizeof_voidp=0
-fi
-rm -fr conftest*
-fi
-
-fi
-echo "$ac_t""$ac_cv_sizeof_voidp" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
-EOF
-
-
-
-echo $ac_n "checking for prototypes""... $ac_c" 1>&6
-echo "configure:1312: checking for prototypes" >&5
-if eval "test \"`echo '$''{'rb_cv_have_prototypes'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1317 "configure"
-#include "confdefs.h"
-int foo(int x) { return 0; }
-int main() {
-return foo(10);
-; return 0; }
-EOF
-if { (eval echo configure:1324: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_have_prototypes=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_have_prototypes=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$rb_cv_have_prototypes" 1>&6
-if test "$rb_cv_have_prototypes" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_PROTOTYPES 1
-EOF
-
-fi
-
-echo $ac_n "checking for variable length prototypes and stdarg.h""... $ac_c" 1>&6
-echo "configure:1345: checking for variable length prototypes and stdarg.h" >&5
-if eval "test \"`echo '$''{'rb_cv_stdarg'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1350 "configure"
-#include "confdefs.h"
-
-#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;
-}
-
-int main() {
-return foo(10, "", 3.14);
-; return 0; }
-EOF
-if { (eval echo configure:1367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_stdarg=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_stdarg=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$rb_cv_stdarg" 1>&6
-if test "$rb_cv_stdarg" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_STDARG_PROTOTYPES 1
-EOF
-
-fi
-
-echo $ac_n "checking for gcc attribute noreturn""... $ac_c" 1>&6
-echo "configure:1388: checking for gcc attribute noreturn" >&5
-if eval "test \"`echo '$''{'rb_cv_have_attr_noreturn'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1393 "configure"
-#include "confdefs.h"
-void exit(int x) __attribute__ ((noreturn));
-int main() {
-
-; return 0; }
-EOF
-if { (eval echo configure:1400: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_have_attr_noreturn=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_have_attr_noreturn=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$rb_cv_have_attr_noreturn" 1>&6
-if test "$rb_cv_have_attr_noreturn" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ATTR_NORETURN 1
-EOF
-
-fi
-
-case "$host_os" in
-nextstep*) ;;
-openstep*) ;;
-rhapsody*) ;;
-human*) ;;
-beos*) ;;
-*) LIBS="-lm $LIBS";;
-esac
-echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:1429: checking for crypt in -lcrypt" >&5
-ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lcrypt $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1437 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char crypt();
-
-int main() {
-crypt()
-; return 0; }
-EOF
-if { (eval echo configure:1448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo crypt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lcrypt $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:1476: checking for dlopen in -ldl" >&5
-ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldl $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1484 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen();
-
-int main() {
-dlopen()
-; return 0; }
-EOF
-if { (eval echo configure:1495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-ldl $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
- # Dynamic linking for SunOS/Solaris and SYSV
-echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
-echo "configure:1523: checking for shl_load in -ldld" >&5
-ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldld $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1531 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char shl_load();
-
-int main() {
-shl_load()
-; return 0; }
-EOF
-if { (eval echo configure:1542: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo dld | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-ldld $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
- # Dynamic linking for HP-UX
-echo $ac_n "checking for setlocale in -lxpg4""... $ac_c" 1>&6
-echo "configure:1570: checking for setlocale in -lxpg4" >&5
-ac_lib_var=`echo xpg4'_'setlocale | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lxpg4 $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1578 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char setlocale();
-
-int main() {
-setlocale()
-; return 0; }
-EOF
-if { (eval echo configure:1589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo xpg4 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lxpg4 $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
- # FreeBSD needs this
-
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1622: checking for $ac_hdr that defines DIR" >&5
-if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1627 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <$ac_hdr>
-int main() {
-DIR *dirp = 0;
-; return 0; }
-EOF
-if { (eval echo configure:1635: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
- ac_header_dirent=$ac_hdr; break
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
-echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1660: checking for opendir in -ldir" >&5
-ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldir $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1668 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
-
-int main() {
-opendir()
-; return 0; }
-EOF
-if { (eval echo configure:1679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -ldir"
-else
- echo "$ac_t""no" 1>&6
-fi
-
-else
-echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1701: checking for opendir in -lx" >&5
-ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lx $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1709 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
-
-int main() {
-opendir()
-; return 0; }
-EOF
-if { (eval echo configure:1720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -lx"
-else
- echo "$ac_t""no" 1>&6
-fi
-
-fi
-
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1743: checking for ANSI C header files" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1748 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1756: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1773 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1791 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
- cat > conftest.$ac_ext <<EOF
-#line 1812 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-if { (eval echo configure:1823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_header_stdc=no
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-for ac_hdr in stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \
- sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\
- syscall.h a.out.h string.h utime.h memory.h direct.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1852: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1857 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1862: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1890: checking for uid_t in sys/types.h" >&5
-if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1895 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "uid_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_uid_t=yes
-else
- rm -rf conftest*
- ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
-if test $ac_cv_type_uid_t = no; then
- cat >> confdefs.h <<\EOF
-#define uid_t int
-EOF
-
- cat >> confdefs.h <<\EOF
-#define gid_t int
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1924: checking for size_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1929 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
-echo "configure:1957: checking for st_blksize in struct stat" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1962 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-int main() {
-struct stat s; s.st_blksize;
-; return 0; }
-EOF
-if { (eval echo configure:1970: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_struct_st_blksize=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_st_blksize=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6
-if test $ac_cv_struct_st_blksize = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ST_BLKSIZE 1
-EOF
-
-fi
-
-save_LIBOJBS="$LIBOBJS"
-echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
-echo "configure:1992: checking for st_blocks in struct stat" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1997 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-int main() {
-struct stat s; s.st_blocks;
-; return 0; }
-EOF
-if { (eval echo configure:2005: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_struct_st_blocks=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_st_blocks=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_struct_st_blocks" 1>&6
-if test $ac_cv_struct_st_blocks = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ST_BLOCKS 1
-EOF
-
-else
- LIBOBJS="$LIBOBJS fileblocks.o"
-fi
-
-LIBOBJS="$save_LIBOBJS"
-echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:2029: checking for st_rdev in struct stat" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2034 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-int main() {
-struct stat s; s.st_rdev;
-; return 0; }
-EOF
-if { (eval echo configure:2042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_struct_st_rdev=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_st_rdev=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6
-if test $ac_cv_struct_st_rdev = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ST_RDEV 1
-EOF
-
-fi
-
-
-echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
-echo "configure:2064: checking type of array argument to getgroups" >&5
-if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_type_getgroups=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 2072 "configure"
-#include "confdefs.h"
-
-/* Thanks to Mike Rendell for this test. */
-#include <sys/types.h>
-#define NGID 256
-#undef MAX
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-main()
-{
- gid_t gidset[NGID];
- int i, n;
- union { gid_t gval; long lval; } val;
-
- val.lval = -1;
- for (i = 0; i < NGID; i++)
- gidset[i] = val.gval;
- n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
- gidset);
- /* Exit non-zero if getgroups seems to require an array of ints. This
- happens when gid_t is short but getgroups modifies an array of ints. */
- exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
-}
-
-EOF
-if { (eval echo configure:2097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_type_getgroups=gid_t
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_type_getgroups=int
-fi
-rm -fr conftest*
-fi
-
-if test $ac_cv_type_getgroups = cross; then
- cat > conftest.$ac_ext <<EOF
-#line 2111 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_getgroups=gid_t
-else
- rm -rf conftest*
- ac_cv_type_getgroups=int
-fi
-rm -f conftest*
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_type_getgroups" 1>&6
-cat >> confdefs.h <<EOF
-#define GETGROUPS_T $ac_cv_type_getgroups
-EOF
-
-
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2135: checking return type of signal handlers" >&5
-if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2140 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
-#endif
-
-int main() {
-int i;
-; return 0; }
-EOF
-if { (eval echo configure:2157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_type_signal=void
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_type_signal=int
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_type_signal" 1>&6
-cat >> confdefs.h <<EOF
-#define RETSIGTYPE $ac_cv_type_signal
-EOF
-
-
-# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-# for constant arguments. Useless!
-echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:2178: checking for working alloca.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2183 "configure"
-#include "confdefs.h"
-#include <alloca.h>
-int main() {
-char *p = alloca(2 * sizeof(int));
-; return 0; }
-EOF
-if { (eval echo configure:2190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_header_alloca_h=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_alloca_h=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
-if test $ac_cv_header_alloca_h = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA_H 1
-EOF
-
-fi
-
-echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:2211: checking for alloca" >&5
-if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2216 "configure"
-#include "confdefs.h"
-
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-#endif
-
-int main() {
-char *p = (char *) alloca(1);
-; return 0; }
-EOF
-if { (eval echo configure:2239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_func_alloca_works=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_func_alloca_works=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
-if test $ac_cv_func_alloca_works = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA 1
-EOF
-
-fi
-
-if test $ac_cv_func_alloca_works = no; then
- # The SVR3 libPW and SVR4 libucb both contain incompatible functions
- # that cause trouble. Some versions do not even contain alloca or
- # contain a buggy version. If you still want to use their alloca,
- # use ar to extract alloca.o from them instead of compiling alloca.c.
- ALLOCA=alloca.o
- cat >> confdefs.h <<\EOF
-#define C_ALLOCA 1
-EOF
-
-
-echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2271: checking whether alloca needs Cray hooks" >&5
-if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2276 "configure"
-#include "confdefs.h"
-#if defined(CRAY) && ! defined(CRAY2)
-webecray
-#else
-wenotbecray
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "webecray" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_os_cray=yes
-else
- rm -rf conftest*
- ac_cv_os_cray=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_os_cray" 1>&6
-if test $ac_cv_os_cray = yes; then
-for ac_func in _getb67 GETB67 getb67; do
- echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2301: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2306 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<EOF
-#define CRAY_STACKSEG_END $ac_func
-EOF
-
- break
-else
- echo "$ac_t""no" 1>&6
-fi
-
-done
-fi
-
-echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2356: checking stack direction for C alloca" >&5
-if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_stack_direction=0
-else
- cat > conftest.$ac_ext <<EOF
-#line 2364 "configure"
-#include "confdefs.h"
-find_stack_direction ()
-{
- static char *addr = 0;
- auto char dummy;
- if (addr == 0)
- {
- addr = &dummy;
- return find_stack_direction ();
- }
- else
- return (&dummy > addr) ? 1 : -1;
-}
-main ()
-{
- exit (find_stack_direction() < 0);
-}
-EOF
-if { (eval echo configure:2383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_c_stack_direction=1
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_c_stack_direction=-1
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
-cat >> confdefs.h <<EOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-EOF
-
-fi
-
-echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2405: checking for pid_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2410 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_pid_t=yes
-else
- rm -rf conftest*
- ac_cv_type_pid_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&6
-if test $ac_cv_type_pid_t = no; then
- cat >> confdefs.h <<\EOF
-#define pid_t int
-EOF
-
-fi
-
-ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2439: checking for vfork.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2444 "configure"
-#include "confdefs.h"
-#include <vfork.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define HAVE_VFORK_H 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2474: checking for working vfork" >&5
-if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2480: checking for vfork" >&5
-if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2485 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char vfork(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char vfork();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_vfork) || defined (__stub___vfork)
-choke me
-#else
-vfork();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_vfork=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_vfork=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- :
-else
- echo "$ac_t""no" 1>&6
-fi
-
-else
- cat > conftest.$ac_ext <<EOF
-#line 2529 "configure"
-#include "confdefs.h"
-/* Thanks to Paul Eggert for this test. */
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-/* On some sparc systems, changes by the child to local and incoming
- argument registers are propagated back to the parent.
- The compiler is told about this with #include <vfork.h>,
- but some compilers (e.g. gcc -O) don't grok <vfork.h>.
- Test for this by using a static variable whose address
- is put into a register that is clobbered by the vfork. */
-static
-#ifdef __cplusplus
-sparc_address_test (int arg)
-#else
-sparc_address_test (arg) int arg;
-#endif
-{
- static pid_t child;
- if (!child) {
- child = vfork ();
- if (child < 0) {
- perror ("vfork");
- _exit(2);
- }
- if (!child) {
- arg = getpid();
- write(-1, "", 0);
- _exit (arg);
- }
- }
-}
-main() {
- pid_t parent = getpid ();
- pid_t child;
-
- sparc_address_test ();
-
- child = vfork ();
-
- if (child == 0) {
- /* Here is another test for sparc vfork register problems.
- This test uses lots of local variables, at least
- as many local variables as main has allocated so far
- including compiler temporaries. 4 locals are enough for
- gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
- A buggy compiler should reuse the register of parent
- for one of the local variables, since it will think that
- parent can't possibly be used any more in this routine.
- Assigning to the local variable will thus munge parent
- in the parent process. */
- pid_t
- p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
- p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
- /* Convince the compiler that p..p7 are live; otherwise, it might
- use the same hardware register for all 8 local variables. */
- if (p != p1 || p != p2 || p != p3 || p != p4
- || p != p5 || p != p6 || p != p7)
- _exit(1);
-
- /* On some systems (e.g. IRIX 3.3),
- vfork doesn't separate parent from child file descriptors.
- If the child closes a descriptor before it execs or exits,
- this munges the parent's descriptor as well.
- Test for this by closing stdout in the child. */
- _exit(close(fileno(stdout)) != 0);
- } else {
- int status;
- struct stat st;
-
- while (wait(&status) != child)
- ;
- exit(
- /* Was there some problem with vforking? */
- child < 0
-
- /* Did the child fail? (This shouldn't happen.) */
- || status
-
- /* Did the vfork/compiler bug occur? */
- || parent != getpid()
-
- /* Did the file descriptor bug occur? */
- || fstat(fileno(stdout), &st) != 0
- );
- }
-}
-EOF
-if { (eval echo configure:2624: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_func_vfork_works=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_func_vfork_works=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
-if test $ac_cv_func_vfork_works = no; then
- cat >> confdefs.h <<\EOF
-#define vfork fork
-EOF
-
-fi
-
-echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:2647: checking for 8-bit clean memcmp" >&5
-if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_memcmp_clean=no
-else
- cat > conftest.$ac_ext <<EOF
-#line 2655 "configure"
-#include "confdefs.h"
-
-main()
-{
- char c0 = 0x40, c1 = 0x80, c2 = 0x81;
- exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
-}
-
-EOF
-if { (eval echo configure:2665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_func_memcmp_clean=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_func_memcmp_clean=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
-test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.o"
-
-for ac_func in dup2 setenv memmove mkdir strcasecmp strerror strftime\
- strchr strstr strtoul strdup crypt flock snprintf
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2686: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2691 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-LIBOBJS="$LIBOBJS ${ac_func}.o"
-fi
-done
-
-
-for ac_func in fmod killpg drand48 random wait4 waitpid syscall getcwd\
- truncate chsize times utimes fcntl lockf setitimer\
- setruid seteuid setreuid setrgid setegid setregid\
- setpgrp2 getpgid getgroups getpriority\
- dlopen sigprocmask sigaction _setjmp setpgrp setsid
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2747: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2752 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-if test "$ac_cv_func_strftime" = no; then
- echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:2801: checking whether struct tm is in sys/time.h or time.h" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2806 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <time.h>
-int main() {
-struct tm *tp; tp->tm_sec;
-; return 0; }
-EOF
-if { (eval echo configure:2814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_struct_tm=time.h
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_tm=sys/time.h
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_struct_tm" 1>&6
-if test $ac_cv_struct_tm = sys/time.h; then
- cat >> confdefs.h <<\EOF
-#define TM_IN_SYS_TIME 1
-EOF
-
-fi
-
-echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
-echo "configure:2835: checking for tm_zone in struct tm" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2840 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <$ac_cv_struct_tm>
-int main() {
-struct tm tm; tm.tm_zone;
-; return 0; }
-EOF
-if { (eval echo configure:2848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_struct_tm_zone=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_tm_zone=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6
-if test "$ac_cv_struct_tm_zone" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_TM_ZONE 1
-EOF
-
-else
- echo $ac_n "checking for tzname""... $ac_c" 1>&6
-echo "configure:2868: checking for tzname" >&5
-if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2873 "configure"
-#include "confdefs.h"
-#include <time.h>
-#ifndef tzname /* For SGI. */
-extern char *tzname[]; /* RS6000 and others reject char **tzname. */
-#endif
-int main() {
-atoi(*tzname);
-; return 0; }
-EOF
-if { (eval echo configure:2883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_var_tzname=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_var_tzname=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_var_tzname" 1>&6
- if test $ac_cv_var_tzname = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_TZNAME 1
-EOF
-
- fi
-fi
-
- cat > conftest.$ac_ext <<EOF
-#line 2905 "configure"
-#include "confdefs.h"
-
-int main() {
-extern int daylight; int i = daylight;
-; return 0; }
-EOF
-if { (eval echo configure:2912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- cat >> confdefs.h <<\EOF
-#define HAVE_DAYLIGHT 1
-EOF
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-fi
-
-if test "$ac_cv_func_sigprocmask" = yes && test "$ac_cv_func_sigaction" = yes; then
- cat >> confdefs.h <<\EOF
-#define POSIX_SIGNAL 1
-EOF
-
-else
- echo $ac_n "checking for BSD signal semantics""... $ac_c" 1>&6
-echo "configure:2932: checking for BSD signal semantics" >&5
- if eval "test \"`echo '$''{'rb_cv_bsd_signal'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 2940 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <signal.h>
-
-void
-sig_handler(dummy)
- int dummy;
-{
-}
-
-int
-main()
-{
- signal(SIGINT, sig_handler);
- kill(getpid(), SIGINT);
- kill(getpid(), SIGINT);
- return 0;
-}
-
-EOF
-if { (eval echo configure:2962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rb_cv_bsd_signal=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rb_cv_bsd_signal=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
- echo "$ac_t""$rb_cv_bsd_signal" 1>&6
- if test "$rb_cv_bsd_signal" = yes; then
- cat >> confdefs.h <<\EOF
-#define BSD_SIGNAL 1
-EOF
-
- fi
-fi
-
-if test "$ac_cv_func_setpgrp2" = yes; then
- cat >> confdefs.h <<\EOF
-#define BSD_GETPGRP getpgrp2
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BSD_SETPGRP setpgrp2
-EOF
-
-else
- echo $ac_n "checking whether getpgrp() has arg""... $ac_c" 1>&6
-echo "configure:2996: checking whether getpgrp() has arg" >&5
- if eval "test \"`echo '$''{'rb_cv_bsdgetpgrp'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3001 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-int main() {
-getpgrp(0);
-; return 0; }
-EOF
-if { (eval echo configure:3008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_bsdgetpgrp=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_bsdgetpgrp=no
-fi
-rm -f conftest*
-fi
-
- echo "$ac_t""$rb_cv_bsdgetpgrp" 1>&6
- if test "$rb_cv_bsdgetpgrp" = yes; then
- cat >> confdefs.h <<\EOF
-#define BSD_GETPGRP getpgrp
-EOF
-
- fi
-
- echo $ac_n "checking whether setpgrp() has args""... $ac_c" 1>&6
-echo "configure:3029: checking whether setpgrp() has args" >&5
- if eval "test \"`echo '$''{'rb_cv_bsdsetpgrp'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3034 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-int main() {
-setpgrp(1, 1);
-; return 0; }
-EOF
-if { (eval echo configure:3041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_bsdsetpgrp=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_bsdsetpgrp=no
-fi
-rm -f conftest*
-fi
-
- echo "$ac_t""$rb_cv_bsdsetpgrp" 1>&6
- if test "$rb_cv_bsdsetpgrp" = yes; then
- cat >> confdefs.h <<\EOF
-#define BSD_SETPGRP setpgrp
-EOF
-
- fi
-fi
-
-echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:3063: checking whether byte ordering is bigendian" >&5
-if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_cv_c_bigendian=unknown
-# See if sys/param.h defines the BYTE_ORDER macro.
-cat > conftest.$ac_ext <<EOF
-#line 3070 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/param.h>
-int main() {
-
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif
-; return 0; }
-EOF
-if { (eval echo configure:3081: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- # It does; now see whether it defined to BIG_ENDIAN or not.
-cat > conftest.$ac_ext <<EOF
-#line 3085 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/param.h>
-int main() {
-
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
-; return 0; }
-EOF
-if { (eval echo configure:3096: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_c_bigendian=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_c_bigendian=no
-fi
-rm -f conftest*
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-if test $ac_cv_c_bigendian = unknown; then
-if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 3116 "configure"
-#include "confdefs.h"
-main () {
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long l;
- char c[sizeof (long)];
- } u;
- u.l = 1;
- exit (u.c[sizeof (long) - 1] == 1);
-}
-EOF
-if { (eval echo configure:3129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_c_bigendian=no
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_c_bigendian=yes
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_c_bigendian" 1>&6
-if test $ac_cv_c_bigendian = yes; then
- cat >> confdefs.h <<\EOF
-#define WORDS_BIGENDIAN 1
-EOF
-
-fi
-
-echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-echo "configure:3153: checking whether char is unsigned" >&5
-if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$GCC" = yes; then
- # GCC predefines this symbol on systems where it applies.
-cat > conftest.$ac_ext <<EOF
-#line 3160 "configure"
-#include "confdefs.h"
-#ifdef __CHAR_UNSIGNED__
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_c_char_unsigned=yes
-else
- rm -rf conftest*
- ac_cv_c_char_unsigned=no
-fi
-rm -f conftest*
-
-else
-if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 3182 "configure"
-#include "confdefs.h"
-/* volatile prevents gcc2 from optimizing the test away on sparcs. */
-#if !defined(__STDC__) || __STDC__ != 1
-#define volatile
-#endif
-main() {
- volatile char c = 255; exit(c < 0);
-}
-EOF
-if { (eval echo configure:3192: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_c_char_unsigned=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_c_char_unsigned=no
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
-if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
- cat >> confdefs.h <<\EOF
-#define __CHAR_UNSIGNED__ 1
-EOF
-
-fi
-
-
-echo $ac_n "checking whether right shift preserve sign bit""... $ac_c" 1>&6
-echo "configure:3217: checking whether right shift preserve sign bit" >&5
-if eval "test \"`echo '$''{'rb_cv_rshift_sign'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 3225 "configure"
-#include "confdefs.h"
-
-int
-main()
-{
- if (-1==(-1>>1))
- return 0;
- return 1;
-}
-
-EOF
-if { (eval echo configure:3237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rb_cv_rshift_sign=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rb_cv_rshift_sign=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
- echo "$ac_t""$rb_cv_rshift_sign" 1>&6
-if test "$rb_cv_rshift_sign" = yes; then
- cat >> confdefs.h <<\EOF
-#define RSHIFT(x,y) ((x)>>y)
-EOF
-
-else
- cat >> confdefs.h <<\EOF
-#define RSHIFT(x,y) (((x)<0) ? ~((~(x))>>y) : (x)>>y)
-EOF
-
-fi
-
-echo $ac_n "checking count field in FILE structures""... $ac_c" 1>&6
-echo "configure:3265: checking count field in FILE structures" >&5
-if eval "test \"`echo '$''{'rb_cv_fcnt'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3270 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-FILE *f = stdin; f->_cnt = 0;
-; return 0; }
-EOF
-if { (eval echo configure:3277: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_fcnt="_cnt"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-if test "$rb_cv_fcnt" = ""; then
- cat > conftest.$ac_ext <<EOF
-#line 3287 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-FILE *f = stdin; f->__cnt = 0;
-; return 0; }
-EOF
-if { (eval echo configure:3294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_fcnt="__cnt"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-fi
-if test "$rb_cv_fcnt" = ""; then
- cat > conftest.$ac_ext <<EOF
-#line 3305 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-FILE *f = stdin; f->_r = 0;
-; return 0; }
-EOF
-if { (eval echo configure:3312: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_fcnt="_r"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-fi
-if test "$rb_cv_fcnt" = ""; then
- cat > conftest.$ac_ext <<EOF
-#line 3323 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-FILE *f = stdin; f->readCount = 0;
-; return 0; }
-EOF
-if { (eval echo configure:3330: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_fcnt="readCount"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_fcnt="not found"
-fi
-rm -f conftest*
-fi
-fi
-
-if test "$rb_cv_fcnt" = "not found"; then
- echo "$ac_t""not found(OK if using GNU libc)" 1>&6
-else
- echo "$ac_t""$rb_cv_fcnt" 1>&6
- cat >> confdefs.h <<EOF
-#define FILE_COUNT $rb_cv_fcnt
-EOF
-
-fi
-
-# Check whether --with-dln-a-out or --without-dln-a-out was given.
-if test "${with_dln_a_out+set}" = set; then
- withval="$with_dln_a_out"
-
- case $withval in
- yes) with_dln_a_out=yes;;
- *) with_dln_a_out=no;;
- esac
-else
- with_dln_a_out=no
-fi
-
-
-case "$host_os" in
- linux*)
- echo $ac_n "checking whether ELF binaries are produced""... $ac_c" 1>&6
-echo "configure:3369: checking whether ELF binaries are produced" >&5
- if eval "test \"`echo '$''{'rb_cv_linux_elf'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- :
-else
- cat > conftest.$ac_ext <<EOF
-#line 3377 "configure"
-#include "confdefs.h"
-
-/* Test for whether ELF binaries are produced */
-#include <fcntl.h>
-#include <stdlib.h>
-main() {
- char buffer[4];
- int i=open("conftest",O_RDONLY);
- if(i==-1)
- exit(1); /* fail */
- if(read(i,&buffer[0],4)<4)
- exit(1); /* fail */
- if(buffer[0] != 127 || buffer[1] != 'E' ||
- buffer[2] != 'L' || buffer[3] != 'F')
- exit(1); /* fail */
- exit(0); /* succeed (yes, it's ELF) */
-}
-
-EOF
-if { (eval echo configure:3397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rb_cv_linux_elf=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rb_cv_linux_elf=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
- echo "$ac_t""$rb_cv_linux_elf" 1>&6
- if test "$rb_cv_linux_elf" = no; then
- with_dln_a_out=yes
- host_os=linux-a.out
- else
- LDFLAGS="-rdynamic"
- fi;;
-esac
-
-
-
-STATIC=
-
-if test "$with_dln_a_out" != yes; then
- rb_cv_dlopen=unknown
- echo $ac_n "checking whether OS depend dynamic link works""... $ac_c" 1>&6
-echo "configure:3427: checking whether OS depend dynamic link works" >&5
- if test "$GCC" = yes; then
- case "$host_os" in
- nextstep*) ;;
- openstep*) ;;
- rhapsody*) ;;
- human*) ;;
- cygwin32*) CCDLFLAGS=-DDLLIMPORT;;
- *) CCDLFLAGS=-fpic;;
- esac
- else
- case "$host_os" in
- hpux*) CCDLFLAGS='+z';;
- solaris*|irix*) CCDLFLAGS='-K pic' ;;
- sunos*) CCDLFLAGS='-pic' ;;
- esix*|uxpds*) CCDLFLAGS='-Kpic' ;;
- *) CCDLFLAGS='' ;;
- esac
- fi
-
- case "$host_os" in
- hpux*) DLDFLAGS="-E"
- LDSHARED='ld -b'
- LDFLAGS="-Wl,-E"
- rb_cv_dlopen=yes;;
- solaris*) LDSHARED='ld -G'
- rb_cv_dlopen=yes;;
- sunos*) LDSHARED='ld -assert nodefinitions'
- rb_cv_dlopen=yes;;
- irix*) LDSHARED='ld -ignore_unresolved'
- rb_cv_dlopen=yes;;
- sysv4*) LDSHARED='ld -G'
- rb_cv_dlopen=yes;;
- esix*|uxpds*) LDSHARED="ld -G"
- rb_cv_dlopen=yes ;;
- linux*) LDSHARED="gcc -shared"
- rb_cv_dlopen=yes ;;
- freebsd*) LDSHARED="ld -Bshareable"
- rb_cv_dlopen=yes ;;
- netbsd*) LDSHARED="ld -Bshareable"
- rb_cv_dlopen=yes ;;
- openbsd*) LDSHARED="ld -Bshareable"
- rb_cv_dlopen=yes ;;
- nextstep*) LDSHARED='cc -r'
- LDFLAGS="-u libsys_s"
- DLDFLAGS="$ARCH_FLAG"
- rb_cv_dlopen=yes ;;
- openstep*) LDSHARED='cc -dynamic -bundle -undefined suppress'
- LDFLAGS=""
- DLDFLAGS="$ARCH_FLAG"
- rb_cv_dlopen=yes ;;
- rhapsody*) LDSHARED='cc -dynamic -bundle -undefined suppress'
- LDFLAGS=""
- DLDFLAGS="$ARCH_FLAG"
- rb_cv_dlopen=yes ;;
- aix*) LDSHARED='../../miniruby ../aix_ld.rb $(TARGET)'
- rb_cv_dlopen=yes ;;
- human*) DLDFLAGS=''
- LDSHARED=''
- LDFLAGS='' ;;
- beos*) LDSHARED="ld -xms"
- case "$host_cpu" in
- powerpc*)
- DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
- ;;
- *)
- DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
- ;;
- esac
- rb_cv_dlopen=yes ;;
- cygwin32*) LDSHARED='../../miniruby ../cygwin32_ld.rb' ;;
- *) LDSHARED='ld' ;;
- esac
- echo "$ac_t""$rb_cv_dlopen" 1>&6
-fi
-
-dln_a_out_works=no
-if test "$ac_cv_header_a_out_h" = yes; then
- if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then
- echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6
-echo "configure:3507: checking whether matz's dln works" >&5
- cat confdefs.h > config.h
- if eval "test \"`echo '$''{'rb_cv_dln_a_out'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3513 "configure"
-#include "confdefs.h"
-
-#define USE_DLN_A_OUT
-#include "dln.c"
-
-int main() {
-
-; return 0; }
-EOF
-if { (eval echo configure:3523: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rb_cv_dln_a_out=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rb_cv_dln_a_out=no
-fi
-rm -f conftest*
-fi
-
- echo "$ac_t""$rb_cv_dln_a_out" 1>&6
- if test "$rb_cv_dln_a_out" = yes; then
- dln_a_out_works=yes
- cat >> confdefs.h <<\EOF
-#define USE_DLN_A_OUT 1
-EOF
-
- fi
- fi
-fi
-
-if test "$dln_a_out_works" = yes; then
- if test "$GCC" = yes; then
- STATIC=-static
- else
- STATIC=-Bstatic
- fi
- DLEXT=o
- cat >> confdefs.h <<\EOF
-#define DLEXT ".o"
-EOF
-
- CCDLFLAGS=
-else
- case "$host_os" in
- hpux*) DLEXT=sl
- cat >> confdefs.h <<\EOF
-#define DLEXT ".sl"
-EOF
-;;
- nextstep*) DLEXT=o
- cat >> confdefs.h <<\EOF
-#define DLEXT ".o"
-EOF
-;;
- openstep*) DLEXT=bundle
- cat >> confdefs.h <<\EOF
-#define DLEXT ".bundle"
-EOF
-;;
- rhapsody*) DLEXT=bundle
- cat >> confdefs.h <<\EOF
-#define DLEXT ".bundle"
-EOF
-;;
- cygwin32*) DLEXT=dll
- cat >> confdefs.h <<\EOF
-#define DLEXT ".dll"
-EOF
-;;
- *) DLEXT=so
- cat >> confdefs.h <<\EOF
-#define DLEXT ".so"
-EOF
-;;
- esac
-fi
-
-if test "$with_dln_a_out" = yes; then
- STRIP=true
-else
- STRIP=strip
-fi
-
-case "$host_os" in
- linux*)
- STRIP='strip -S -x';;
- nextstep*)
- STRIP='strip -A -n';;
- openstep*)
- STRIP='strip -A -n';;
- rhapsody*)
- STRIP='strip -A -n';;
-esac
-
-EXTSTATIC=
-# Check whether --with-static-linked-ext or --without-static-linked-ext was given.
-if test "${with_static_linked_ext+set}" = set; then
- withval="$with_static_linked_ext"
- case $withval in
- yes) STATIC=
- EXTSTATIC=static;;
- *) ;;
- esac
-fi
-
-
-case "$host_os" in
- human*)
- echo $ac_n "checking for _harderr in -lsignal""... $ac_c" 1>&6
-echo "configure:3625: checking for _harderr in -lsignal" >&5
-ac_lib_var=`echo signal'_'_harderr | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lsignal $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3633 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char _harderr();
-
-int main() {
-_harderr()
-; return 0; }
-EOF
-if { (eval echo configure:3644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo signal | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lsignal $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
- echo $ac_n "checking for hmemset in -lhmem""... $ac_c" 1>&6
-echo "configure:3672: checking for hmemset in -lhmem" >&5
-ac_lib_var=`echo hmem'_'hmemset | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lhmem $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3680 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char hmemset();
-
-int main() {
-hmemset()
-; return 0; }
-EOF
-if { (eval echo configure:3691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo hmem | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lhmem $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
- for ac_func in select
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3721: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3726 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:3749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
- echo $ac_n "checking whether PD libc _dtos18 fail to convert big number""... $ac_c" 1>&6
-echo "configure:3774: checking whether PD libc _dtos18 fail to convert big number" >&5
- if eval "test \"`echo '$''{'rb_cv_missing__dtos18'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 3782 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-main ()
-{
- char buf[256];
- sprintf (buf, "%g", 1e+300);
- exit (strcmp (buf, "1e+300") ? 0 : 1);
-}
-
-EOF
-if { (eval echo configure:3794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rb_cv_missing__dtos18=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rb_cv_missing__dtos18=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
- echo "$ac_t""$rb_cv_missing__dtos18" 1>&6
- if test "$rb_cv_missing__dtos18" = yes; then
- cat >> confdefs.h <<\EOF
-#define MISSING__DTOS18 1
-EOF
-
- fi
- echo $ac_n "checking whether PD libc fconvert fail to round""... $ac_c" 1>&6
-echo "configure:3816: checking whether PD libc fconvert fail to round" >&5
- if eval "test \"`echo '$''{'rb_cv_missing_fconvert'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 3824 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <math.h>
-main ()
-{
- char buf[256];
- sprintf (buf, "%f", log(exp(1.0)));
- exit (strcmp (buf, "1.000000") ? 0 : 1);
-}
-
-EOF
-if { (eval echo configure:3837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rb_cv_missing_fconvert=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rb_cv_missing_fconvert=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
- echo "$ac_t""$rb_cv_missing_fconvert" 1>&6
- if test "$rb_cv_missing_fconvert" = yes; then
- cat >> confdefs.h <<\EOF
-#define MISSING_FCONVERT 1
-EOF
-
- fi
- LIBOBJS="$LIBOBJS x68.o"
- CFLAGS="$CFLAGS -fansi-only -cc1-stack=196608 -cpp-stack=2694144"
- binsuffix=.x
- setup=Setup.x68
- ;;
- cygwin32*)
- binsuffix=.exe
- setup=Setup
- ;;
- *)
- binsuffix=
- setup=Setup
- ;;
-esac
-
-
-
-
-
-
-if test "$prefix" = NONE; then
- prefix=$ac_default_prefix
-fi
-
-if test "$fat_binary" = yes ; then
- CFLAGS="$CFLAGS $ARCH_FLAG"
-fi
-
-LIBRUBY='libruby.a'
-LIBRUBYARG='libruby.a'
-SOLIBS=
-if test "$host_os" = "beos"; then
- CFLAGS="$CFLAGS -relax_pointers"
- LIBRUBY='libruby.so'
- LIBRUBYARG='-lruby'
- SOLIBS='-lnet'
- echo creating ruby.def
- case "$host_cpu" in
- powerpc*)
- cp beos/ruby.def.in ruby.exp
- ;;
- *)
- echo EXPORTS > ruby.def
- cat beos/ruby.def.in >> ruby.def
- ;;
- esac
-fi
-
-if test "$enable_shared" = 'yes'; then
- LIBRUBY='libruby.so'
- LIBRUBYARG='-L./ -lruby'
-fi
-
-case "$host_os" in
- nextstep*)
- CFLAGS="$CFLAGS -pipe"
- ;;
- openstep*)
- CFLAGS="$CFLAGS -pipe"
- ;;
- rhasody*)
- CFLAGS="$CFLAGS -pipe -no-precomp"
- ;;
- *)
- ;;
-esac
-
-
-
-
-
-
-ri_prefix=
-test "$program_prefix" != NONE &&
- ri_prefix=$program_prefix
-
-ri_suffix=
-test "$program_suffix" != NONE &&
- ri_suffix=$program_suffix
-
-RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
-cat >> confdefs.h <<EOF
-#define RUBY_LIB "${prefix}/lib/${RUBY_INSTALL_NAME}"
-EOF
-
-cat >> confdefs.h <<EOF
-#define RUBY_SITE_LIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby"
-EOF
-
-
-if test "$fat_binary" = yes ; then
- arch="fat-${host_os}"
-
- cat >> confdefs.h <<EOF
-#define RUBY_THIN_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}"
-EOF
-
-
- cat >> confdefs.h <<EOF
-#define RUBY_SITE_THIN_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}"
-EOF
-
-
- cat >> confdefs.h <<EOF
-#define RUBY_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}"
-EOF
-
- cat >> confdefs.h <<EOF
-#define RUBY_SITE_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}"
-EOF
-
- cat >> confdefs.h <<EOF
-#define RUBY_PLATFORM __ARCHITECTURE__ "-${host_os}"
-EOF
-
-else
- arch="${host_cpu}-${host_os}"
- cat >> confdefs.h <<EOF
-#define RUBY_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}"
-EOF
-
- cat >> confdefs.h <<EOF
-#define RUBY_SITE_ARCHLIB "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}"
-EOF
-
- cat >> confdefs.h <<EOF
-#define RUBY_PLATFORM "${arch}"
-EOF
-
-fi
-
-echo "creating config.h"
-cat confdefs.h > config.h
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
-
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.12"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile ext/extmk.rb" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@CC@%$CC%g
-s%@CPP@%$CPP%g
-s%@YACC@%$YACC%g
-s%@RANLIB@%$RANLIB%g
-s%@AR@%$AR%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@LIBOBJS@%$LIBOBJS%g
-s%@ALLOCA@%$ALLOCA%g
-s%@DLDFLAGS@%$DLDFLAGS%g
-s%@STATIC@%$STATIC%g
-s%@CCDLFLAGS@%$CCDLFLAGS%g
-s%@LDSHARED@%$LDSHARED%g
-s%@DLEXT@%$DLEXT%g
-s%@STRIP@%$STRIP%g
-s%@EXTSTATIC@%$EXTSTATIC%g
-s%@binsuffix@%$binsuffix%g
-s%@setup@%$setup%g
-s%@LIBRUBY@%$LIBRUBY%g
-s%@LIBRUBYARG@%$LIBRUBYARG%g
-s%@SOLIBS@%$SOLIBS%g
-s%@arch@%$arch%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
- else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
- fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
- else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
- fi
-done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile ext/extmk.rb"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- case "$ac_given_INSTALL" in
- [/$]*) INSTALL="$ac_given_INSTALL" ;;
- *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
- esac
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
-
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000000..8a7cee55b8
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,4591 @@
+dnl Process this file with autoconf to produce a configure script.
+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 "[$]@"
+}
+])])])
+
+{ # environment section
+
+HAVE_BASERUBY=yes
+AC_ARG_WITH(baseruby,
+ AS_HELP_STRING([--with-baseruby=RUBY], [use RUBY as baseruby; RUBY is the pathname of ruby]),
+ [AS_CASE(["$withval"],
+ [*ruby*],[BASERUBY=$withval],
+ [no],[HAVE_BASERUBY=no],
+ [AC_MSG_ERROR(need ruby)])
+ ],
+ [
+ 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
+], [
+ BASERUBY="echo executable host ruby is required. use --with-baseruby option.; false"
+ HAVE_BASERUBY=no
+])
+AC_SUBST(BASERUBY)
+AC_SUBST(HAVE_BASERUBY)
+
+: ${GIT=git}
+HAVE_GIT=yes
+AC_ARG_WITH(git,
+ AS_HELP_STRING([--without-git], [never use git]),
+ [AS_CASE([$withval],
+ [no], [GIT=never-use HAVE_GIT=no],
+ [yes], [],
+ [GIT=$withval])])
+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_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`
+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)
+dnl checks for alternative programs
+AC_CANONICAL_BUILD
+RUBY_RM_RECURSIVE
+AC_ARG_WITH(gcc,
+ AS_HELP_STRING([--without-gcc], [never use gcc]),
+ [
+ AS_CASE([$withval],
+ [no], [: ${CC=cc}],
+ [yes], [: ${CC=gcc}],
+ [CC=$withval])])
+dnl If the user switches compilers, we can't believe the cache
+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_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}')
+
+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.
+
+AC_ARG_WITH(os-version-style,
+ AS_HELP_STRING([--with-os-version-style=TYPE],
+ [OS version number for target and target_os [[full]]]
+ [(full|teeny|minor+0|minor|major+0|major|none)]),
+ [os_version_style=$withval],
+ [os_version_style=full
+ AS_CASE($target_os, [[*[0-9].*]],
+ [AS_CASE([`/usr/bin/ruby -e 'puts RUBY_PLATFORM' 2>/dev/null`],
+ [[*-*[0-9].*.0]], [os_version_style=minor+0],
+ [[*-*[0-9].*.*]], [os_version_style=full],
+ [[*-*[0-9].0] ], [os_version_style=major+0],
+ [[*-*[0-9].*] ], [os_version_style=minor],
+ [[*-*[0-9]] ], [os_version_style=major],
+ )])
+ ])
+os_version_style_transform=
+AS_CASE("${os_version_style}",
+ [full|teeny], [],
+ [minor+0], [os_version_style_transform=['s/\([0-9]\.[0-9][0-9]*\)\.[0-9][.0-9]*$/\1.0/']],
+ [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]*$//']],
+ [AC_MSG_ERROR(unknown --with-os-version-style: $withval)])
+AS_IF([test -z "$target_alias" -a -n "$os_version_style_transform"],
+ [
+ target=`echo ${target} | sed "$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);
+ ARCHS is a comma-delimited list of architectures for
+ which to build; if this option is disabled or omitted
+ entirely, then the package will be built only for the
+ 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
+
+dnl Checks for programs.
+
+cflagspat=
+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" ||
+ 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}'
+])
+
+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_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"
+
+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,
+ : ${optflags=-O3}
+ gcc_major=`echo =__GNUC__ | $CC -E -xc - | sed '/^=/!d;s///'`
+ 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
+ AS_CASE(["x$CC"], [xicc], [
+ icc_version=`echo =__ICC | $CC -E -xc - | sed '/^=/!d;s///'`
+ ])
+ test -n "$icc_version" || icc_version=0
+ # RUBY_APPEND_OPTIONS(XCFLAGS, ["-include ruby/config.h" "-include ruby/missing.h"])
+], [
+ linker_flag=
+])
+
+RUBY_PROG_GNU_LD
+RUBY_CPPOUTFILE
+
+: ${OUTFLAG='-o '}
+: ${COUTFLAG=${OUTFLAG}}
+: ${CSRCFLAG=''}
+AC_SUBST(OUTFLAG)
+AC_SUBST(COUTFLAG)
+AC_SUBST(CSRCFLAG)
+
+cc_version=
+for option in --version -v -V -qversion; do
+ cc_version_message=`$CC $option 2>&1`
+ cc_version_status=$?
+ AS_CASE($cc_version_status, [0], [:], [continue])
+ AS_CASE($cc_version_message, [*Warning*], [continue])
+ cc_version='$(CC) '$option
+ break
+done
+AC_SUBST(CC_VERSION, $cc_version)
+AC_SUBST(CC_VERSION_MESSAGE, $cc_version_message)
+
+RUBY_UNIVERSAL_ARCH
+AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "$universal_binary" = no], [
+ RUBY_DEFAULT_ARCH("$target_cpu")
+])
+
+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)
+ AC_CHECK_TOOL(DLLWRAP, dllwrap)
+ target=`echo $target | sed "s/^$target_cpu-/-/"`
+ target_alias=`echo $target_alias | sed "s/^$target_cpu-/-/"`
+ target_cpu=`echo $target_cpu | sed s/i.86/i386/`
+ AS_CASE(["$target"], [-*], [ target="$target_cpu${target}"])
+ AS_CASE(["$target_alias"], [-*], [ target_alias="$target_cpu${target_alias}"])
+ 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;],
+ [rb_cv_msvcrt=`$OBJDUMP -p conftest$ac_exeext |
+ tr A-Z a-z |
+ sed -n '/^[[ ]]*dll name: \(msvc.*\)\.dll$/{s//\1/p;q;}'`],
+ [rb_cv_msvcrt=msvcrt])
+ test "$rb_cv_msvcrt" = "" && rb_cv_msvcrt=msvcrt])
+ 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
+AC_PROG_INSTALL
+AC_PROG_MKDIR_P
+AS_IF([test "x$MKDIR_P" = "x -d"], [
+ AS_IF([test x"$as_mkdir_p" != xfalse], [
+ MKDIR_P='mkdir -p'
+ echo "use 'mkdir -p' as MKDIR_P"
+ ], [
+ AC_MSG_ERROR([mkdir -p is required])
+ ])
+])
+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])
+])
+
+AC_CHECK_PROGS(DOT, dot)
+AC_CHECK_PROGS(DOXYGEN, doxygen)
+
+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"`])
+
+# checks for UNIX variants that set C preprocessor variables
+AC_USE_SYSTEM_EXTENSIONS
+
+AC_SUBST(RM, ['rm -f'])
+AC_SUBST(CP, ['cp'])
+RMDIRS='$(top_srcdir)/tool/rmdirs'
+RMDIR=rmdir
+mkdir "rmdirs_$$_test" "rmdirs_$$_test/a"
+rmdir --ignore-fail-on-non-empty "rmdirs_$$_test" 2>/dev/null &&
+RMDIR='rmdir --ignore-fail-on-non-empty'
+$RMDIR -p "rmdirs_$$_test/a" 2>/dev/null &&
+{ test -d "rmdirs_$$_test" || RMDIRS="$RMDIR -p"; }
+rmdir "rmdirs_$$_test/a" "rmdirs_$$_test" 2>/dev/null
+AC_SUBST(RMDIR)
+AC_SUBST(RMDIRS)
+AC_SUBST(RMALL, ['rm -fr'])
+
+AC_MSG_CHECKING([for cd using physical directory])
+rm -fr conf$$.dir
+mkdir conf$$.dir &&
+(cd conf$$.dir && mkdir src build && cd src &&
+$as_ln_s ../build . > /dev/null 2>&1 && cd build &&
+for chdir in 'cd -P' 'PWD= cd'; do
+ /bin/sh -c "$chdir ../src && echo '$chdir' > cdcmd" 2> /dev/null && break
+done)
+AS_IF([test -f conf$$.dir/src/cdcmd], [
+ read CHDIR < conf$$.dir/src/cdcmd 2> /dev/null
+], [
+ CHDIR=cd
+])
+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
+])])
+
+RUBY_WERROR_FLAG([
+ AC_MSG_CHECKING([whether CFLAGS is valid])
+ AC_TRY_COMPILE([], [],
+ [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 &&
+ cd tmp.$$.try_link &&
+ cp ../confdefs.h . &&
+ 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_MSG_RESULT(yes)],
+ [
+ cd .. && rm -fr tmp.$$.try_link
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([something wrong with LDFLAGS="$LDFLAGS"])
+ ]
+ )
+ 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], [
+ AS_CASE(["$target_os"],
+ [hpux*], [AS_IF([test "$rb_cv_prog_gnu_ld" = no], [rpathflag='+b '])],
+ [aix*], [rpathflag='-blibpath:'],
+ [for rpathflag in -R "-rpath "; do
+ AS_CASE("$rpathflag",
+ [*" "], [AS_CASE(["${linker_flag}"],
+ [*,], [rpathflag=`echo "$rpathflag" | tr ' ' ,`])])
+ rpathflag="${linker_flag}${rpathflag}"
+ RUBY_TRY_LDFLAGS([${rpathflag}.], [], [rpathflag=])
+ AS_IF([test "x${rpathflag}" != x], [])
+ done])
+], [
+ rpathflag=`echo "$RPATHFLAG" | sed 's/%.*//'`
+])
+
+AS_CASE([$RUBY_PATCHLEVEL], [-*],
+ [RUBY_DEVEL=yes], [RUBY_DEVEL=no])
+particular_werror_flags=$RUBY_DEVEL
+AC_ARG_ENABLE(werror,
+ AS_HELP_STRING([--disable-werror],
+ [don't make warnings into errors
+ even if a compiler support -Werror feature
+ [[disabled by default unless development version]]]),
+ [particular_werror_flags=$enableval])
+
+rb_cv_warnflags="$warnflags"
+AS_IF([test "$GCC:${warnflags+set}:no" = yes::no], [
+ AS_IF([test $gcc_major -ge 4], [
+ extra_warning=-Werror=extra-tokens
+ ], [
+ extra_warning=
+ ])
+ AS_IF([test $gcc_major -ge 5 -a $gcc_major -le 6], [
+ extra_warning="$extra_warning -Wno-maybe-uninitialized"
+ ])
+ # ICC doesn't support -Werror=
+ AS_IF([test $icc_version -gt 0], [
+ particular_werror_flags=no
+ ])
+ for wflag in -Wno-unused-parameter -Wno-parentheses -Wno-long-long \
+ -diag-disable=175,188,2259 \
+ -Wno-missing-field-initializers \
+ -Wno-tautological-compare \
+ -Wno-parentheses-equality \
+ -Wno-constant-logical-operand \
+ -Wno-self-assign \
+ -Wunused-variable \
+ -Werror=implicit-int \
+ -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=misleading-indentation \
+ -Wno-packed-bitfield-compat \
+ -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=format \
+ -Wimplicit-fallthrough=0 \
+ -Werror=duplicated-cond \
+ -Werror=restrict \
+ $extra_warning \
+ ; do
+ AS_IF([test "$particular_werror_flags" != yes], [
+ wflag=`echo x$wflag | sed 's/^x-Werror=/-W/;s/^x//'`
+ ])
+ ok=no
+ RUBY_TRY_CFLAGS($wflag, [
+ RUBY_APPEND_OPTIONS(warnflags, $wflag)
+ ok=yes
+ ])
+ AS_CASE([$ok:$wflag], [no:-Werror=*], [
+ wflag=`echo x$wflag | sed 's/^x-Werror=/-W/'`
+ RUBY_TRY_CFLAGS($wflag, [
+ RUBY_APPEND_OPTIONS(warnflags, $wflag)
+ particular_werror_flags=no
+ ])
+ ])
+ done
+ AS_CASE([" $warnflags "],[*" -Wno-missing-field-initializers "*], [wflag="-Wall -Wextra"],
+ [wflag=-Wall])
+ RUBY_TRY_CFLAGS($wflag, [warnflags="$wflag${warnflags+ $warnflags}"])
+ # Disable warnflags while conftest. -Werror=* flags might make bad OS capability guess.
+ rb_cv_warnflags="$warnflags"
+ 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_ARG_WITH(compress-debug-sections,
+ AS_HELP_STRING([--with-compress-debug-sections=type],
+ [enable debug section compression]),
+ [compress_debug_sections=$withval], [compress_debug_sections=])
+
+AS_IF([test "$GCC" = yes], [
+ # -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)])
+
+ # -fstack-protector
+ AS_CASE(["$target_os"],
+ [mingw*], [
+ 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_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("${compress_debug_sections:-zlib}",
+ [none|no], [], [
+ RUBY_TRY_LDFLAGS(${linker_flag}--compress-debug-sections=${compress_debug_sections:-zlib},
+ [compress_debug_sections=${compress_debug_sections:-zlib}],
+ [compress_debug_sections=no])
+ ])
+ AS_IF([test "x$compress_debug_sections" != xno], [
+ RUBY_APPEND_OPTION(DLDFLAGS, ${linker_flag}--compress-debug-sections=$compress_debug_sections)
+ ])
+
+ AS_CASE(["$target_os"],[mingw*], [
+ # On Windows platforms, system provided headers are VC++
+ # optimized. That is, C++ habits are often contaminated into
+ # various headers. Most frequent situation is the use of //
+ # 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
+ # to be pure, the variables pointed by the second arguments are
+ # considered uninitialized unexpectedly.
+ AC_CACHE_CHECK([whether frexp and modf are broken],
+ rb_cv_mingw64_broken_frexp_modf,
+ [
+ save_CFLAGS="$CFLAGS"
+ AS_IF([test "$particular_werror_flags" = "yes"], [
+ CFLAGS="$CFLAGS -Werror=uninitialized"
+ ], [
+ CFLAGS="$CFLAGS -Werror -Wuninitialized"
+ ])
+ AC_TRY_COMPILE([@%:@include <math.h>
+ int foo(double x)
+ {
+ int exp;
+ frexp(x, &exp);
+ return exp;
+ }], [if (foo(0.0)) return 1;],
+ [rb_cv_mingw64_broken_frexp_modf=no],
+ [rb_cv_mingw64_broken_frexp_modf=yes])
+ CFLAGS="$save_CFLAGS"
+ ])
+ AS_IF([test "$rb_cv_mingw64_broken_frexp_modf" = yes], [
+ AC_DEFINE(RUBY_MINGW64_BROKEN_FREXP_MODF)
+ ])
+ ],
+ [cygwin*|darwin*|netbsd*], [
+ # need lgamma_r(), finite()
+ ],
+ [
+ # ANSI (no XCFLAGS because this is C only)
+ for ansi_options in -std=gnu99; do
+ RUBY_TRY_CFLAGS(${ansi_options}, [
+ RUBY_APPEND_OPTIONS(warnflags, ${ansi_options})
+ RUBY_APPEND_OPTIONS(strict_warnflags, ${ansi_options})
+ ], [ansi_options=])
+ test "x${ansi_options}" = x || break
+ done
+ ])
+
+ # suppress annoying -Wstrict-overflow warnings
+ RUBY_TRY_CFLAGS(-fno-strict-overflow, [RUBY_APPEND_OPTION(XCFLAGS, -fno-strict-overflow)])
+
+ test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb3, [debugflags=-ggdb3])}
+ test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb, [debugflags=-ggdb])}
+ test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-g3, [debugflags=-g3])}
+])
+test $ac_cv_prog_cc_g = yes && : ${debugflags=-g}
+AS_IF([test "x$RUBY_DEVEL" = xyes], [RUBY_APPEND_OPTION(XCFLAGS, -DRUBY_DEVEL=1)])
+
+AS_IF([test "$GCC" = ""], [
+ AS_CASE(["$target_os"],[aix*],[warnflags="$warnflags -qinfo=por" rb_cv_warnflags="$rb_cv_warnflags -qinfo=por"])
+])
+AS_IF([test "$GCC" = yes], [
+ AS_IF([test "$gcc_major" -ge 4], [
+ RUBY_TRY_CFLAGS(-fvisibility=hidden, [visibility_option=yes], [visibility_option=no])
+ ])
+ AC_SUBST(WERRORFLAG, "-Werror")
+ AS_IF([test "$visibility_option" = yes], [
+ RUBY_APPEND_OPTION(XCFLAGS, -fvisibility=hidden)
+ AC_DEFINE(RUBY_SYMBOL_EXPORT_BEGIN, [_Pragma("GCC visibility push(default)")])
+ AC_DEFINE(RUBY_SYMBOL_EXPORT_END, [_Pragma("GCC visibility pop")])
+ ], [
+ RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no])
+ ])
+ test "$visibility_option" = no || OBJCOPY=:
+])
+
+AS_IF([test "$GCC" = yes], [
+ # optflags
+
+ AS_CASE(["$target_os"], [mingw*], [
+ RUBY_TRY_CFLAGS(-fno-omit-frame-pointer, [optflags="${optflags+$optflags }-fno-omit-frame-pointer"])
+ RUBY_TRY_CFLAGS(-static-libgcc, [static_libgcc=yes], [static_libgcc=no])
+ AS_IF([test "$static_libgcc" = yes], [
+ RUBY_APPEND_OPTION(EXTLDFLAGS, -static-libgcc)
+ ])
+ ])
+
+ # disable fast-math
+ for oflag in -fno-fast-math; do
+ RUBY_TRY_CFLAGS($oflag, [RUBY_APPEND_OPTION(CFLAGS, $oflag)])
+ done
+ for oflag in -fexcess-precision=standard -fp-model\ precise; do
+ RUBY_TRY_CFLAGS($oflag, [RUBY_APPEND_OPTION(XCFLAGS, $oflag)])
+ done
+])
+
+AC_ARG_WITH(opt-dir,
+ AS_HELP_STRING([--with-opt-dir=DIR-LIST],
+ [add optional headers and libraries directories separated by $PATH_SEPARATOR]),
+ [
+ val=`echo "$PATH_SEPARATOR$withval" | sed "s|$PATH_SEPARATOR\([[^$PATH_SEPARATOR]*]\)| -I\1/include|g;s/^ //"`
+ CPPFLAGS="$CPPFLAGS $val"
+ val=`echo "$PATH_SEPARATOR$withval" | sed "s|$PATH_SEPARATOR\([[^$PATH_SEPARATOR]*]\)| -L\1/lib${rpathflag:+ $rpathflag\\\\1/lib}|g;s/^ //"`
+ LDFLAGS="$LDFLAGS $val"
+ LDFLAGS_OPTDIR="$val"
+ OPT_DIR="$withval"
+ ], [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_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_CASE(["$target_os"],
+[mingw*], [
+ RUBY_APPEND_OPTION(CPPFLAGS, -D_WIN32_WINNT=$with_winnt_ver)
+ RUBY_APPEND_OPTION(CPPFLAGS, -D__MINGW_USE_VC2005_COMPAT)
+])
+
+AS_CASE(["$target_os"],
+[freebsd*], [
+ AC_CACHE_CHECK([whether pthread should be enabled by default],
+ rb_cv_enable_pthread_default,
+ [AC_TRY_CPP([
+#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
+ ],
+[mingw*], [
+ enable_pthread=no
+ ],
+[
+ enable_pthread=yes
+ ])
+
+dnl Checks for libraries.
+AS_CASE(["$target_os"],[*bsd*|dragonfly*],[],[ac_cv_func_daemon=no])
+
+POSTLINK=:
+AC_SUBST(POSTLINK)
+AS_CASE(["$target_os"],
+[nextstep*], [ ],
+[openstep*], [ ],
+[rhapsody*], [ ],
+[darwin*], [ 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_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)
+ ])
+ 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"`
+ done
+ for d in $incs; do
+ test -d "$d" && RUBY_APPEND_OPTIONS(LDFLAGS, "-L$d")
+ done
+ ac_cv_type_getgroups=gid_t # getgroups() on Rosetta fills garbage
+ ac_cv_lib_crypt_crypt=no
+ ac_cv_func_fdatasync=no # Mac OS X wrongly reports it has fdatasync()
+ ac_cv_func_vfork=no
+ AS_IF([test $gcc_major -lt 4 -o \( $gcc_major -eq 4 -a $gcc_minor -lt 3 \)], [
+ ac_cv_func___builtin_setjmp=no
+ ])
+ AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt,
+ [AC_TRY_RUN([
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+void
+broken_crypt(const char *salt, const char *buf1, const char *buf2)
+{
+#if 0
+ printf("%.2x%.2x: %s -> %s\n", (unsigned char)salt[0], (unsigned char)salt[1],
+ buf1+2, buf2+2);
+#endif
+}
+
+int
+main()
+{
+ int i;
+ char salt[2], buf[256], *s;
+ for (i = 0; i < 128*128; i++) {
+ salt[0] = 0x80 | (i & 0x7f);
+ salt[1] = 0x80 | (i >> 7);
+ strcpy(buf, crypt("", salt));
+ if (strcmp(buf, s = crypt("", salt))) {
+ broken_crypt(salt, buf, s);
+ return 1;
+ }
+ }
+ salt[0] = salt[1] = ' ';
+ strcpy(buf, crypt("", salt));
+ salt[0] = salt[1] = 0x80 | ' ';
+ if (strcmp(buf, s = crypt("", salt))) {
+ broken_crypt(salt, buf, s);
+ return 1;
+ }
+ return 0;
+}
+],
+ rb_cv_broken_crypt=no,
+ rb_cv_broken_crypt=yes,
+ rb_cv_broken_crypt=yes)])
+ AS_IF([test "$rb_cv_broken_crypt" = yes], [
+ AC_DEFINE(BROKEN_CRYPT, 1)
+ ])
+ POSTLINK=""
+ AC_CHECK_PROGS(codesign, codesign)
+ AC_CHECK_PROGS(dsymutil, dsymutil)
+ AS_IF([test -n "$codesign"], [
+ POSTLINK="{ test -z '\$(RUBY_CODESIGN)' || $codesign -s '\$(RUBY_CODESIGN)' -f \$@; }${POSTLINK:+; $POSTLINK}"
+ ])
+ AS_IF([test -n "$dsymutil"], [
+ POSTLINK="$dsymutil \$@${POSTLINK:+; $POSTLINK}"
+ ])
+ AS_IF([test -n "${POSTLINK}"], [
+ LINK_SO="$LINK_SO
+\$(POSTLINK)"
+ ])
+ AC_CHECK_HEADERS(crt_externs.h, [], [], [
+ #include <crt_externs.h>
+ ])
+ ],
+[hpux*], [ LIBS="-lm $LIBS"
+ ac_cv_c_inline=no],
+[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_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
+ ])
+ # 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([
+ #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
+ ])
+ AC_MSG_RESULT($define_xopen_source)
+ AS_IF([test x"$define_xopen_source" != xno], [
+ RUBY_APPEND_OPTIONS(CPPFLAGS, -D_XOPEN_SOURCE=$define_xopen_source)
+ ])
+ ])
+ ],
+[haiku*], [
+ LIBS="$LIBS" # m lib is include in root
+ ],
+[cygwin*], [ ac_cv_header_langinfo_h=yes
+ RUBY_APPEND_OPTIONS(CPPFLAGS, -D_XOPEN_SOURCE -D_GNU_SOURCE)
+ AC_CHECK_FUNCS(cygwin_conv_path)
+ AC_LIBOBJ([langinfo])
+ ],
+[mingw*], [ LIBS="-lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi $LIBS"
+ ac_cv_header_a_out_h=no
+ ac_cv_header_pwd_h=no
+ ac_cv_header_utime_h=no
+ ac_cv_header_sys_ioctl_h=no
+ ac_cv_header_sys_param_h=no
+ ac_cv_header_sys_resource_h=no
+ ac_cv_header_sys_select_h=no
+ ac_cv_header_sys_time_h=no
+ ac_cv_header_sys_times_h=no
+ ac_cv_header_sys_socket_h=no
+ ac_cv_func_lstat=yes
+ ac_cv_func_times=yes
+ ac_cv_func_waitpid=yes
+ 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
+ ac_cv_func_symlink=yes
+ ac_cv_lib_crypt_crypt=no
+ ac_cv_func_getpgrp_void=no
+ ac_cv_func_memcmp_working=yes
+ ac_cv_lib_dl_dlopen=no
+ rb_cv_binary_elf=no
+ rb_cv_negative_time_t=no
+ ac_cv_func_fcntl=yes
+ ac_cv_func_flock=yes
+ ac_cv_func_gmtime_r=yes
+ rb_cv_large_fd_select=yes
+ ac_cv_type_struct_timeval=yes
+ ac_cv_func_clock_gettime=yes
+ ac_cv_func_clock_getres=yes
+ ac_cv_func_malloc_usable_size=no
+ AS_IF([test "$target_cpu" = x64], [
+ ac_cv_func___builtin_setjmp=no
+ ac_cv_func_round=no
+ ])
+ ac_cv_func_tgamma=no
+ rb_cv_negative_time_t=yes
+ AC_CHECK_TYPE([NET_LUID], [], [],
+ [@%:@include <winsock2.h>
+ @%:@include <iphlpapi.h>])
+ AS_IF([test x"$ac_cv_type_NET_LUID" = xyes], [
+ AC_DEFINE(HAVE_TYPE_NET_LUID, 1)
+ ])
+ AC_CHECK_FUNCS(_gmtime64_s)
+ AC_CHECK_FUNCS(_wfreopen_s)
+ AC_LIBOBJ([langinfo])
+ ],
+[bsdi*], [ LIBS="-lm $LIBS"
+ AC_DEFINE(BROKEN_SETREUID, 1)
+ AC_DEFINE(BROKEN_SETREGID, 1)
+ ac_cv_sizeof_rlim_t=8],
+[freebsd*], [ LIBS="-lm $LIBS"
+ ac_cv_func_getpeername=no
+ ac_cv_func_getsockname=no
+ ac_cv_func_shutdown=no
+ ac_cv_func_close=no
+ ],
+[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
+ ],
+[ LIBS="-lm $LIBS"])
+
+AC_CHECK_LIB(crypt, crypt) # glibc (GNU/Linux, GNU/Hurd, GNU/kFreeBSD)
+AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV
+AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX
+AC_CHECK_LIB(socket, shutdown) # SunOS/Solaris
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+dnl AC_HEADER_STDC has been checked in AC_USE_SYSTEM_EXTENSIONS
+AC_HEADER_STDBOOL
+AC_HEADER_SYS_WAIT
+
+AC_CHECK_HEADERS(a.out.h)
+AC_CHECK_HEADERS(atomic.h)
+AC_CHECK_HEADERS(direct.h)
+AC_CHECK_HEADERS(grp.h)
+AC_CHECK_HEADERS(fcntl.h)
+AC_CHECK_HEADERS(float.h)
+AC_CHECK_HEADERS(ieeefp.h)
+AC_CHECK_HEADERS(intrinsics.h)
+AC_CHECK_HEADERS(langinfo.h)
+AC_CHECK_HEADERS(limits.h)
+AC_CHECK_HEADERS(locale.h)
+AC_CHECK_HEADERS(malloc.h)
+AC_CHECK_HEADERS(malloc/malloc.h)
+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(setjmpex.h)
+AC_CHECK_HEADERS(sys/attr.h)
+AC_CHECK_HEADERS(sys/fcntl.h)
+AC_CHECK_HEADERS(sys/file.h)
+AC_CHECK_HEADERS(sys/id.h)
+AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/mkdev.h)
+AC_CHECK_HEADERS(sys/param.h)
+AC_CHECK_HEADERS(sys/prctl.h)
+AC_CHECK_HEADERS(sys/resource.h)
+AC_CHECK_HEADERS(sys/select.h)
+AC_CHECK_HEADERS(sys/sendfile.h)
+AC_CHECK_HEADERS(sys/socket.h)
+AC_CHECK_HEADERS(sys/syscall.h)
+AC_CHECK_HEADERS(sys/sysmacros.h)
+AC_CHECK_HEADERS(sys/time.h)
+AC_CHECK_HEADERS(sys/times.h)
+AC_CHECK_HEADERS(sys/uio.h)
+AC_CHECK_HEADERS(sys/utime.h)
+AC_CHECK_HEADERS(syscall.h)
+AC_CHECK_HEADERS(time.h)
+AC_CHECK_HEADERS(ucontext.h)
+AC_CHECK_HEADERS(utime.h)
+
+AC_ARG_WITH([gmp],
+ [AS_HELP_STRING([--without-gmp],
+ [disable GNU GMP to accelerate Bignum operations])],
+ [],
+ [with_gmp=yes])
+AS_IF([test "x$with_gmp" != xno],
+ [AC_CHECK_HEADERS(gmp.h)
+ AS_IF([test "x$ac_cv_header_gmp_h" != xno],
+ AC_SEARCH_LIBS([__gmpz_init], [gmp],
+ [AC_DEFINE(HAVE_LIBGMP, 1)]))])
+
+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],[
+ AC_SEARCH_LIBS([malloc_conf], [jemalloc],
+ [AC_DEFINE(HAVE_LIBJEMALLOC, 1)], [with_jemalloc=no])
+ AC_CHECK_HEADER(jemalloc/jemalloc.h, [
+ AC_DEFINE(RUBY_ALTERNATIVE_MALLOC_HEADER, [<jemalloc/jemalloc.h>])
+ ],
+ [test x$with_jemalloc = xyes && with_jemalloc=no])
+ AS_IF([test "x$with_jemalloc" = xno], [
+ 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
+ @%:@include RUBY_ALTERNATIVE_MALLOC_HEADER
+ @%:@else
+ @%:@include <jemalloc.h>
+ @%:@endif], [return !&malloc_conf])],
+ [rb_cv_jemalloc_demangle=yes],
+ [rb_cv_jemalloc_demangle=no])
+ ])
+ ])
+ AS_IF([test "x$rb_cv_jemalloc_demangle" = xyes], [
+ AC_DEFINE(JEMALLOC_MANGLE)
+ with_jemalloc=yes
+ ])
+ AS_IF([test "x$with_jemalloc" = xyes],
+ [
+ AC_DEFINE(HAVE_MALLOC_CONF)
+ ac_cv_func_malloc_usable_size=yes
+ ],
+ [AC_MSG_ERROR([jemalloc requested but not found])
+ ])
+])
+
+dnl check for large file stuff
+mv confdefs.h confdefs1.h
+: > confdefs.h
+AC_SYS_LARGEFILE
+# On 32-bit Solaris, it is safe to define _LARGEFILE_SOURCE
+# which is not added by AC_SYS_LARGEFILE.
+AS_IF([test x"$enable_largefile" != xno], [
+ AS_CASE(["$target_os"], [solaris*], [
+ AC_MSG_CHECKING([wheather _LARGEFILE_SOURCE should be defined])
+ AS_CASE(["${ac_cv_sys_file_offset_bits}:${ac_cv_sys_large_files}"],
+ ["64:"|"64:no"|"64:unknown"], [
+ # insert _LARGEFILE_SOURCE before _FILE_OFFSET_BITS line
+ # that is the same order as "getconf LFS_CFLAGS" output
+ mv confdefs.h largefile0.h
+ : > confdefs.h
+ AC_DEFINE(_LARGEFILE_SOURCE)
+ cat largefile0.h >> confdefs.h
+ rm largefile0.h
+ AC_MSG_RESULT([yes])
+ ], [AC_MSG_RESULT([no])])
+ ])
+])
+mv confdefs.h largefile.h
+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:*], [],
+ [*:no|*:unknown], [],
+ [
+ # AIX currently does not support a 32-bit call to posix_fadvise()
+ # if _LARGE_FILES is defined.
+ ac_cv_func_posix_fadvise=no
+ ])
+ ])
+
+AC_C_BIGENDIAN
+AC_C_CONST
+AC_C_CHAR_UNSIGNED
+AC_C_INLINE
+AC_C_VOLATILE
+AC_C_TYPEOF
+
+AS_CASE(":$ac_cv_c_const:$ac_cv_c_volatile:",
+ [*:no:*], [AC_MSG_ERROR(ANSI C-conforming const and volatile are mandatory)])
+
+AC_CHECK_TYPES([long long, off_t])
+
+AC_CACHE_CHECK([char bit], [rb_cv_char_bit],
+ [test "$universal_binary" = yes && cross_compiling=yes
+ AC_COMPUTE_INT([rb_cv_char_bit], [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])
+RUBY_CHECK_SIZEOF(long long)
+RUBY_CHECK_SIZEOF(__int64, [8], [ILP LP])
+RUBY_CHECK_SIZEOF(__int128, [16], [ILP LP])
+RUBY_CHECK_SIZEOF(off_t)
+RUBY_CHECK_SIZEOF(void*, [int long "long long"], [ILP LP LLP])
+RUBY_CHECK_SIZEOF(float)
+RUBY_CHECK_SIZEOF(double)
+RUBY_CHECK_SIZEOF(time_t, [long "long long"], [], [@%:@include <time.h>])
+RUBY_CHECK_SIZEOF(clock_t, [], [], [@%:@include <time.h>])
+
+AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct,
+ [rb_cv_packed_struct=no
+ for mac in \
+ "__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; });], [],
+ [rb_cv_packed_struct=$mac; break])
+ done])
+AS_IF([test "$rb_cv_packed_struct" != no], [
+ AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], [$rb_cv_packed_struct])
+ RUBY_TRY_CFLAGS(-Wno-address-of-packed-member, [AC_DEFINE(USE_UNALIGNED_MEMBER_ACCESS)])
+], [
+ 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(rlim_t, [int long "long long"], RLIM, [
+@%:@ifdef HAVE_SYS_TYPES_H
+@%:@include <sys/types.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_TYPES_H
+@%:@include <sys/time.h>
+@%:@endif
+@%:@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)
+])
+
+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);],
+ 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;}
+])
+])
+
+RUBY_FUNC_ATTRIBUTE(__const__, CONSTFUNC)
+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(__warn_unused_result__, WARN_UNUSED_RESULT)
+RUBY_FUNC_ATTRIBUTE(__unused__, MAYBE_UNUSED)
+RUBY_FUNC_ATTRIBUTE(__error__ mesg, ERRORFUNC(mesg,x), rb_cv_func___error__)
+RUBY_FUNC_ATTRIBUTE(__warning__ mesg, WARNINGFUNC(mesg,x), rb_cv_func___warning__)
+RUBY_FUNC_ATTRIBUTE(__weak__, WEAK, rb_cv_func_weak)
+AS_IF([test "$rb_cv_func_weak" != x], [
+ AC_DEFINE(HAVE_FUNC_WEAK)
+])
+
+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})
+RUBY_FUNC_ATTRIBUTE(__fastcall__, FUNC_FASTCALL, rb_cv_func_fastcall, ${if_i386})
+RUBY_FUNC_ATTRIBUTE(__optimize__("O0"), FUNC_UNOPTIMIZED, rb_cv_func_unoptimized)
+RUBY_FUNC_ATTRIBUTE(__optimize__("-Os","-fomit-frame-pointer"), FUNC_MINIMIZED, rb_cv_func_minimized)
+
+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()],
+ [rb_cv_gcc_function_alias=$a; break])
+ done])
+ AS_IF([test "$rb_cv_gcc_function_alias" != no], [
+ AC_DEFINE(HAVE_ATTRIBUTE_FUNCTION_ALIAS)
+ AC_DEFINE_UNQUOTED([RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args)],
+ [type prot __attribute__(($rb_cv_gcc_function_alias(@%:@name)));])
+ AC_DEFINE_UNQUOTED([RUBY_ALIAS_FUNCTION_VOID(prot, name, args)],
+ [RUBY_ALIAS_FUNCTION_TYPE(void, prot, name, args)])
+ ])
+
+ AC_CACHE_CHECK([for __atomic builtins], [rb_cv_gcc_atomic_builtins], [
+ AC_TRY_LINK([unsigned char 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], [
+ AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS)
+ ])
+
+ AC_CACHE_CHECK([for __sync builtins], [rb_cv_gcc_sync_builtins], [
+ AC_TRY_LINK([unsigned char 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();],
+ [rb_cv_func___builtin_unreachable=yes],
+ [rb_cv_func___builtin_unreachable=no])
+ ])
+ ])
+ 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);], [],
+ [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_APPEND_OPTION(XCFLAGS, -DRUBY_EXPORT)
+
+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_IF([test "$rb_cv_function_name_string" != no], [
+ AC_DEFINE_UNQUOTED(RUBY_FUNCTION_NAME_STRING, [$rb_cv_function_name_string])
+])
+
+AC_CACHE_CHECK(if enum over int is allowed, rb_cv_enum_over_int, [
+ rb_cv_enum_over_int=no
+ AS_IF([test "x$ac_cv_type_long_long" = xyes], [
+ type="unsigned long long" max="ULLONG_MAX"
+ ], [
+ type="unsigned long" max="ULONG_MAX"
+ ])
+ RUBY_WERROR_FLAG([
+ AC_COMPILE_IFELSE([
+ AC_LANG_BOOL_COMPILE_TRY([
+ @%:@include <limits.h>
+ enum {conftest_max = $max};
+ ], [
+ (conftest_max == $max) &&
+ (sizeof(conftest_max) == sizeof($type))
+ ]
+ )],
+ [rb_cv_enum_over_int=yes],
+ [rb_cv_enum_over_int=no]
+ )
+ ])
+])
+AS_IF([test $rb_cv_enum_over_int = yes], [
+ AC_DEFINE(ENUM_OVER_INT, 1)
+])
+
+dnl Check whether we need to define sys_nerr locally
+AC_CHECK_DECLS([sys_nerr], [], [], [$ac_includes_default
+@%:@include <errno.h>])
+
+AC_CHECK_DECLS([getenv])
+
+AS_CASE(["$target_cpu"],
+[alpha*|sh4|sh4el|sh4eb], [AS_CASE(["$target_os"::"$GCC"],
+ [*::yes], # gcc
+ [CFLAGS="-mieee $CFLAGS"],
+ [osf*], # ccc
+ [CFLAGS="-ieee $CFLAGS"],
+ )],
+[sparc*], [AC_LIBOBJ([sparc])])
+
+ac_cv_header_net_socket_h=${ac_cv_header_net_socket_h=no}
+AS_IF([test "$ac_cv_header_net_socket_h" = yes], [
+ ac_cv_header_sys_socket_h=${ac_cv_header_sys_socket_h=no}
+], [
+ ac_cv_header_sys_socket_h=${ac_cv_header_sys_socket_h=yes}
+])
+
+
+AC_TYPE_SIZE_T
+RUBY_CHECK_SIGNEDNESS(size_t, [AC_MSG_ERROR(size_t is signed)], [],
+ [@%:@include <sys/types.h>])
+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
+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>])
+])
+RUBY_CHECK_SIZEOF([struct stat.st_ino], [long "long long"], [], [@%:@include <sys/stat.h>])
+AC_CHECK_MEMBERS([struct stat.st_atim])
+AC_CHECK_MEMBERS([struct stat.st_atimespec])
+AC_CHECK_MEMBERS([struct stat.st_atimensec])
+AC_CHECK_MEMBERS([struct stat.st_mtim])
+AC_CHECK_MEMBERS([struct stat.st_mtimespec])
+AC_CHECK_MEMBERS([struct stat.st_mtimensec])
+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])
+
+AC_CHECK_TYPES([struct timeval], [], [], [@%:@ifdef HAVE_TIME_H
+@%:@include <time.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_TIME_H
+@%:@include <sys/time.h>
+@%:@endif])
+
+AS_IF([test "${ac_cv_type_struct_timeval}" = yes], [
+ RUBY_CHECK_SIZEOF([struct timeval.tv_sec], [time_t long "long long"], [],
+ [@%:@ifdef HAVE_TIME_H
+@%:@include <time.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_TIME_H
+@%:@include <sys/time.h>
+@%:@endif])
+ AS_CASE(${ac_cv_sizeof_struct_timeval_tv_sec},
+ [SIZEOF_INT], [t=int],
+ [SIZEOF_LONG], [t=long],
+ [SIZEOF_LONG_LONG], [t=LONG_LONG],
+ [t=])
+ AS_IF([test "${t}" != ""], [
+ AC_DEFINE_UNQUOTED(TYPEOF_TIMEVAL_TV_SEC, [$t])
+ ])
+])
+
+AC_CHECK_TYPES([struct timespec], [], [], [@%:@ifdef HAVE_TIME_H
+@%:@include <time.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_TIME_H
+@%:@include <sys/time.h>
+@%:@endif])
+
+AC_CHECK_TYPES([struct timezone], [], [], [@%:@ifdef HAVE_TIME_H
+@%:@ include <time.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_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], [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)
+RUBY_DEFINT(uint16_t, 2, unsigned)
+RUBY_DEFINT(int32_t, 4)
+RUBY_DEFINT(uint32_t, 4, unsigned)
+RUBY_DEFINT(int64_t, 8)
+RUBY_DEFINT(uint64_t, 8, unsigned)
+RUBY_DEFINT(int128_t, 16)
+RUBY_DEFINT(uint128_t, 16, unsigned)
+RUBY_DEFINT(intptr_t, void*)
+RUBY_DEFINT(uintptr_t, void*, unsigned)
+RUBY_DEFINT(ssize_t, size_t, [], [@%:@include <sys/types.h>]) dnl may differ from int, so not use AC_TYPE_SSIZE_T.
+
+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;],
+ [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)
+ AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.${ac_objext}])
+ AC_DEFINE(C_ALLOCA)
+ AC_DEFINE_UNQUOTED(alloca, alloca)
+ ],
+[universal-darwin*:*ppc*], [
+ AC_LIBSOURCES(alloca.c)
+ AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.${ac_objext}])
+ RUBY_DEFINE_IF([defined __powerpc__], C_ALLOCA, 1)
+ RUBY_DEFINE_IF([defined __powerpc__], alloca, alloca)
+ ],
+[
+ AC_FUNC_ALLOCA
+ ])
+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([
+ @%:@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;],
+ [rb_cv_dynamic_alloca=$chk; break])
+ done])
+ AS_IF([test "x$rb_cv_dynamic_alloca" = "x__chkstk"], [
+ AC_DEFINE_UNQUOTED(RUBY_ALLOCA_CHKSTK, _$rb_cv_dynamic_alloca)
+ AS_CASE("$target_cpu",
+ [x64|x86_64], [
+ AC_SUBST([ALLOCA], [\${LIBOBJDIR}x86_64-chkstk.${ac_objext}])
+ ],)
+ ])
+])
+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)
+ ])
+
+AC_REPLACE_FUNCS(acosh)
+AC_REPLACE_FUNCS(cbrt)
+AC_REPLACE_FUNCS(crypt)
+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(nextafter)
+AC_REPLACE_FUNCS(setproctitle)
+AC_REPLACE_FUNCS(strchr)
+AC_REPLACE_FUNCS(strerror)
+AC_REPLACE_FUNCS(strlcat)
+AC_REPLACE_FUNCS(strlcpy)
+AC_REPLACE_FUNCS(strstr)
+AC_REPLACE_FUNCS(tgamma)
+
+# for missing/setproctitle.c
+AS_CASE(["$target_os"],
+[aix* | k*bsd*-gnu | kopensolaris*-gnu | linux* | darwin*], [AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)],
+[hpux*], [AC_DEFINE(SPT_TYPE,SPT_PSTAT) ],
+[])
+AC_CHECK_HEADERS(sys/pstat.h)
+
+
+AC_CACHE_CHECK(for signbit, rb_cv_have_signbit,
+ [AC_TRY_LINK([
+#include <math.h>
+], [int v = signbit(-0.0);],
+ rb_cv_have_signbit=yes,
+ rb_cv_have_signbit=no)])
+AS_IF([test "$rb_cv_have_signbit" = yes], [
+ AC_DEFINE(HAVE_SIGNBIT)
+], [
+ 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)
+AC_CHECK_FUNCS(_longjmp) # used for AC_ARG_WITH(setjmp-type)
+# we don't use _setjmp if _longjmp doesn't exist.
+test x$ac_cv_func__longjmp = xno && ac_cv_func__setjmp=no
+AC_CHECK_FUNCS(arc4random_buf)
+AC_CHECK_FUNCS(atan2l atan2f)
+AC_CHECK_FUNCS(chroot)
+AC_CHECK_FUNCS(chsize)
+AC_CHECK_FUNCS(clock_gettime)
+AC_CHECK_FUNCS(cosh)
+AC_CHECK_FUNCS(crypt_r)
+AC_CHECK_FUNCS(daemon)
+AC_CHECK_FUNCS(dirfd)
+AC_CHECK_FUNCS(dl_iterate_phdr)
+AC_CHECK_FUNCS(dlopen)
+AC_CHECK_FUNCS(dladdr)
+AC_CHECK_FUNCS(dup)
+AC_CHECK_FUNCS(dup3)
+AC_CHECK_FUNCS(eaccess)
+AC_CHECK_FUNCS(endgrent)
+AC_CHECK_FUNCS(fchmod)
+AC_CHECK_FUNCS(fchown)
+AC_CHECK_FUNCS(fcntl)
+AC_CHECK_FUNCS(fdatasync)
+AC_CHECK_FUNCS(fdopendir)
+AC_CHECK_FUNCS(fgetattrlist)
+AC_CHECK_FUNCS(fmod)
+AC_CHECK_FUNCS(fstatat)
+AC_CHECK_FUNCS(fsync)
+AC_CHECK_FUNCS(ftruncate)
+AC_CHECK_FUNCS(ftruncate64) # used for Win32 platform
+AC_CHECK_FUNCS(getattrlist)
+AC_CHECK_FUNCS(getcwd)
+AC_CHECK_FUNCS(getgidx)
+AC_CHECK_FUNCS(getgrnam)
+AC_CHECK_FUNCS(getgrnam_r)
+AC_CHECK_FUNCS(getgroups)
+AC_CHECK_FUNCS(getpgid)
+AC_CHECK_FUNCS(getpgrp)
+AC_CHECK_FUNCS(getpriority)
+AC_CHECK_FUNCS(getpwnam_r)
+AC_CHECK_FUNCS(getresgid)
+AC_CHECK_FUNCS(getresuid)
+AC_CHECK_FUNCS(getrlimit)
+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(initgroups)
+AC_CHECK_FUNCS(ioctl)
+AC_CHECK_FUNCS(isfinite)
+AC_CHECK_FUNCS(issetugid)
+AC_CHECK_FUNCS(killpg)
+AC_CHECK_FUNCS(lchmod)
+AC_CHECK_FUNCS(lchown)
+AC_CHECK_FUNCS(link)
+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)
+AC_CHECK_FUNCS(memalign)
+AC_CHECK_FUNCS(memset_s)
+AC_CHECK_FUNCS(writev)
+AC_CHECK_FUNCS(memrchr)
+AC_CHECK_FUNCS(memmem)
+AC_CHECK_FUNCS(mkfifo)
+AC_CHECK_FUNCS(mknod)
+AC_CHECK_FUNCS(mktime)
+AC_CHECK_FUNCS(openat)
+AC_CHECK_FUNCS(pipe2)
+AC_CHECK_FUNCS(poll)
+AC_CHECK_FUNCS(posix_fadvise)
+AC_CHECK_FUNCS(posix_memalign)
+AC_CHECK_FUNCS(ppoll)
+AC_CHECK_FUNCS(pread)
+AC_CHECK_FUNCS(pwrite)
+AC_CHECK_FUNCS(qsort_r)
+AC_CHECK_FUNCS(qsort_s)
+AC_CHECK_FUNCS(readlink)
+AC_CHECK_FUNCS(round)
+AC_CHECK_FUNCS(sched_getaffinity)
+AC_CHECK_FUNCS(seekdir)
+AC_CHECK_FUNCS(select_large_fdset)
+AC_CHECK_FUNCS(sendfile)
+AC_CHECK_FUNCS(setegid)
+AC_CHECK_FUNCS(setenv)
+AC_CHECK_FUNCS(seteuid)
+AC_CHECK_FUNCS(setgid)
+AC_CHECK_FUNCS(setgroups)
+AC_CHECK_FUNCS(setpgid)
+AC_CHECK_FUNCS(setpgrp)
+AC_CHECK_FUNCS(setregid)
+AC_CHECK_FUNCS(setresgid)
+AC_CHECK_FUNCS(setresuid)
+AC_CHECK_FUNCS(setreuid)
+AC_CHECK_FUNCS(setrgid)
+AC_CHECK_FUNCS(setrlimit)
+AC_CHECK_FUNCS(setruid)
+AC_CHECK_FUNCS(setsid)
+AC_CHECK_FUNCS(setuid)
+AC_CHECK_FUNCS(shutdown)
+AC_CHECK_FUNCS(sigaction)
+AC_CHECK_FUNCS(sigaltstack)
+AC_CHECK_FUNCS(sigprocmask)
+AC_CHECK_FUNCS(sinh)
+AC_CHECK_FUNCS(spawnv)
+AC_CHECK_FUNCS(symlink)
+AC_CHECK_FUNCS(syscall)
+AC_CHECK_FUNCS(sysconf)
+AC_CHECK_FUNCS(tanh)
+AC_CHECK_FUNCS(telldir)
+AC_CHECK_FUNCS(timegm)
+AC_CHECK_FUNCS(times)
+AC_CHECK_FUNCS(truncate)
+AC_CHECK_FUNCS(truncate64) # used for Win32
+AC_CHECK_FUNCS(unsetenv)
+AC_CHECK_FUNCS(utimensat)
+AC_CHECK_FUNCS(utimes)
+AC_CHECK_FUNCS(wait4)
+AC_CHECK_FUNCS(waitpid)
+
+AS_IF([test "$ac_cv_func_memset_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([
+@%:@include <stddef.h>
+@%:@include <stdio.h>
+@%:@ifdef HAVE_UNISTD_H
+@%:@include <unistd.h>
+@%:@endif
+@%:@ifndef EXIT_SUCCESS
+@%:@define EXIT_SUCCESS 0
+@%:@endif
+@%:@ifndef EXIT_FAILURE
+@%:@define EXIT_FAILURE 1
+@%:@endif
+
+int
+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,
+ [linux*|darwin*|*bsd|cygwin*|mingw*|mswin*],
+ [rb_cv_getcwd_malloc=yes],
+ [rb_cv_getcwd_malloc=no]))])
+ AS_IF([test "$rb_cv_getcwd_malloc" = no], [AC_DEFINE(NO_GETCWD_MALLOC, 1)])
+])
+
+AS_IF([test "$ac_cv_func_crypt_r" = yes],
+ [AC_CHECK_HEADERS(crypt.h)])
+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_bswap16, [__builtin_bswap16(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap32, [__builtin_bswap32(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_bswap64, [__builtin_bswap64(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_popcount, [__builtin_popcount(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_popcountll, [__builtin_popcountll(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_clz, [__builtin_clz(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_clzl, [__builtin_clzl(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_clzll, [__builtin_clzll(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_ctz, [__builtin_ctz(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_ctzll, [__builtin_ctzll(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_add_overflow, [int x;__builtin_add_overflow(0,0,&x)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_sub_overflow, [int x;__builtin_sub_overflow(0,0,&x)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_mul_overflow, [int x;__builtin_mul_overflow(0,0,&x)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_mul_overflow_p, [__builtin_mul_overflow_p(0,0,(int)0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_constant_p, [__builtin_constant_p(0)])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_choose_expr, [
+ [int x[__extension__(__builtin_choose_expr(1, 1, -1))]];
+ [int y[__extension__(__builtin_choose_expr(0, -1, 1))]];
+ ])
+AS_IF([test x$rb_cv_builtin___builtin_choose_expr = xyes], [
+ RUBY_CHECK_BUILTIN_FUNC(__builtin_choose_expr_constant_p, [
+ [int x[__extension__(__builtin_choose_expr(__builtin_constant_p(1), 1, -1))]];
+ [int y[__extension__(__builtin_choose_expr(__builtin_constant_p(foo), -1, 1))]];
+ ])
+])
+RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatible_p(int, int)])
+
+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([
+@%:@include <stdlib.h>
+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([
+@%:@include <stdlib.h>
+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])
+ ])
+ AS_CASE("$rb_cv_gnu_qsort_r:$rb_cv_bsd_qsort_r",
+ [yes:no], [
+ AC_DEFINE(HAVE_GNU_QSORT_R, 1)
+ ],
+ [no:yes], [
+ AC_DEFINE(HAVE_BSD_QSORT_R, 1)
+ ])
+])
+
+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([
+@%:@include <math.h>
+@%:@ifdef HAVE_UNISTD_H
+@%:@include <unistd.h>
+@%:@endif
+@%:@ifndef EXIT_SUCCESS
+@%:@define EXIT_SUCCESS 0
+@%:@endif
+@%:@ifndef EXIT_FAILURE
+@%:@define EXIT_FAILURE 1
+@%:@endif
+
+int
+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])]
+ )
+ ], [rb_cv_atan2_inf_c99=no])
+])
+AS_IF([test "x$rb_cv_atan2_inf_c99" = xyes], [AC_DEFINE(ATAN2_INF_C99)])
+
+# Some platform need -lrt for clock_gettime, but the other don't.
+AS_IF([test x"$ac_cv_func_clock_gettime" != xyes], [
+ # glibc 2.17 moves clock_* functions from librt to the main C library.
+ # http://sourceware.org/ml/libc-announce/2012/msg00001.html
+ AC_CHECK_LIB(rt, clock_gettime)
+ AS_IF([test x"$ac_cv_lib_rt_clock_gettime" = xyes], [
+ AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
+ ])
+])
+AC_CHECK_FUNCS(clock_getres) # clock_getres should be tested after clock_gettime test including librt test.
+
+AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
+ [AC_TRY_COMPILE([
+#include <stdlib.h>
+], [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,
+ AS_HELP_STRING([--enable-setreuid], [use setreuid()/setregid() according to need even if obsolete]),
+ [use_setreuid=$enableval])
+AS_IF([test "$use_setreuid" = yes], [
+ AC_DEFINE(USE_SETREUID)
+ AC_DEFINE(USE_SETREGID)
+])
+AC_STRUCT_TIMEZONE
+AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
+ [AC_TRY_COMPILE([
+@%:@define _BSD_SOURCE
+@%:@define _DEFAULT_SOURCE
+@%:@include <time.h>
+ ],
+ [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;],
+ rb_cv_have_daylight=yes,
+ rb_cv_have_daylight=no)])
+AS_IF([test "$rb_cv_have_daylight" = yes], [
+ AC_DEFINE(HAVE_DAYLIGHT)
+])
+
+AC_CACHE_CHECK(for negative time_t for gmtime(3), rb_cv_negative_time_t,
+ [AC_TRY_RUN([
+#include <stdlib.h>
+#include <time.h>
+
+void
+check(tm, y, m, d, h, s)
+ struct tm *tm;
+ int y, m, d, h, s;
+{
+ if (!tm ||
+ tm->tm_year != y ||
+ tm->tm_mon != m-1 ||
+ tm->tm_mday != d ||
+ tm->tm_hour != h ||
+ tm->tm_sec != s) {
+ exit(1);
+ }
+}
+
+int
+main()
+{
+ time_t t = -1;
+ struct tm *tm;
+
+ check(gmtime(&t), 69, 12, 31, 23, 59);
+ t = ~(time_t)0 << 31;
+ 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)])
+AS_IF([test "$rb_cv_negative_time_t" = yes], [
+ AC_DEFINE(NEGATIVE_TIME_T)
+])
+
+# [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([
+#include <stdlib.h>
+#include <time.h>
+
+void
+check(time_t t1)
+{
+ struct tm *tm;
+ time_t t2;
+ tm = localtime(&t1);
+ if (!tm)
+ return; /* overflow detected. ok. */
+ t2 = mktime(tm);
+ if (t1 == t2)
+ return; /* round-trip. ok. */
+ exit(1);
+}
+
+int
+main()
+{
+ time_t t;
+ if (~(time_t)0 <= 0) {
+ t = (((time_t)1) << (sizeof(time_t) * 8 - 2));
+ t |= t - 1;
+ }
+ else {
+ t = ~(time_t)0;
+ }
+ check(t);
+ return 0;
+}
+],
+ rb_cv_localtime_overflow=yes,
+ rb_cv_localtime_overflow=no,
+ rb_cv_localtime_overflow=no)])
+AS_IF([test "$rb_cv_localtime_overflow" = no], [
+ AC_DEFINE(LOCALTIME_OVERFLOW_PROBLEM)
+])
+
+AS_IF([test "$ac_cv_func_sigprocmask" = yes && test "$ac_cv_func_sigaction" = yes], [
+ AC_DEFINE(POSIX_SIGNAL)
+], [
+ AC_CHECK_FUNCS(sigsetmask)
+ AC_CACHE_CHECK(for BSD signal semantics, rb_cv_bsd_signal,
+ [AC_TRY_RUN([
+#include <stdio.h>
+#include <signal.h>
+
+void
+sig_handler(dummy)
+ int dummy;
+{
+}
+
+int
+main()
+{
+ signal(SIGINT, sig_handler);
+ kill(getpid(), SIGINT);
+ kill(getpid(), SIGINT);
+ return 0;
+}
+],
+ rb_cv_bsd_signal=yes,
+ rb_cv_bsd_signal=no,
+ rb_cv_bsd_signal=$ac_cv_func_sigsetmask)])
+ AS_IF([test "$rb_cv_bsd_signal" = yes], [
+ AC_DEFINE(BSD_SIGNAL)
+ ])
+])
+
+AC_CHECK_TYPES([sig_t],[],[],[@%:@include <signal.h>])
+
+AS_IF([test "$ac_cv_func_getpgid" = no], [
+ # AC_FUNC_GETPGRP fails when cross-compiling with old autoconf.
+ # autoconf is changed between 2.52d and 2.52f?
+ # http://lists.gnu.org/archive/html/bug-gnu-utils/2001-09/msg00181.html
+ # "autoconf cleanup for AC_FUNC_GETPGRP and GETPGRP_VOID"
+AC_FUNC_GETPGRP
+])
+AS_IF([test "$ac_cv_func_setpgid:$ac_cv_func_setpgrp" = no:yes], [
+ # AC_FUNC_SETPGRP fails when cross-compiling. (until autoconf 2.69?)
+ # https://lists.gnu.org/archive/html/bug-autoconf/2013-02/msg00002.html
+ # "AC_FUNC_SETPGRP fails to work properly when cross-compiling"
+AC_FUNC_SETPGRP
+])
+
+AS_IF([test x"$ac_cv_func_dirfd" = xno], [
+ AS_CASE(["$target_os"],[solaris*],
+ [AC_CHECK_MEMBERS([DIR.d_fd, DIR.dd_fd],,,[
+#include <sys/types.h>
+#include <dirent.h>
+])])
+])
+
+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,
+ rb_cv_rshift_sign=no)])
+AS_IF([test "$rb_cv_rshift_sign" = yes], [
+ AC_DEFINE(RSHIFT(x,y), ((x)>>(int)(y)))
+], [
+ 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_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"'||'`
+ save_LDFLAGS="$LDFLAGS" new_ldflags=`echo "$LDFLAGS" | sed "s|$archflagpat"'||'`
+ stack_dir=
+ for archs in ${universal_archnames}; do
+ archs=`echo $archs | sed 's/=.*//'`
+ CFLAGS="$new_cflags -arch $archs"
+ LDFLAGS="$new_ldflags -arch $archs"
+ RUBY_STACK_GROW_DIRECTION($archs, dir)
+ AS_IF([test x$stack_dir = x], [
+ stack_dir=$dir
+ ], [test x$stack_dir != x$dir], [
+ stack_dir=no
+ ])
+ done
+ CFLAGS="$save_CFLAGS" LDFLAGS="$save_LDFLAGS"
+ AS_IF([test x$stack_dir = xno], [
+ for archs in ${universal_archnames}; do
+ archs=`echo $archs | sed 's/=.*//'`
+ eval dir=\$[rb_cv_stack_grow_dir_]AS_TR_SH([$archs])
+ RUBY_DEFINE_IF([defined __${archs}__], STACK_GROW_DIRECTION, $dir)
+ done
+ ], [
+ AC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $stack_dir)
+ ])
+], [
+ RUBY_STACK_GROW_DIRECTION($target_cpu, dir)
+ AC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $dir)
+])
+
+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,
+ rb_with_pthread=yes, rb_with_pthread=no)
+ AS_IF([test "$rb_with_pthread" = "yes"], [ break; fi
+ 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"])])
+ ], [
+ 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([
+ @%:@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])
+ ])
+ AS_IF([test x"$rb_cv_scalar_pthread_t" = xyes], [
+ : # RUBY_CHECK_SIZEOF(pthread_t, [void* int long], [], [@%:@include <pthread.h>])
+ ], [
+ AC_DEFINE(NON_SCALAR_THREAD_ID)
+ ])
+ AC_CHECK_FUNCS(sched_yield pthread_attr_setinheritsched \
+ pthread_attr_get_np pthread_attr_getstack pthread_attr_init \
+ 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_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)])
+ 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\")
+ # Darwin (name)
+ for mac in \
+ "(pthread_self(), name)" \
+ "(pthread_self(), name, \"%s\")" \
+ "(name)" \
+ ; do
+ AC_TRY_COMPILE([
+ @%:@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;],
+ [rb_cv_func_pthread_setname_np_arguments="${mac}"
+ break])
+ done
+ ]
+ )
+ AS_IF([test -n "${rb_cv_func_pthread_setname_np_arguments}"], [
+ set_current_thread_name="pthread_setname_np${rb_cv_func_pthread_setname_np_arguments}"
+ ])
+ ], [test "$ac_cv_func_pthread_set_name_np" = yes], [
+ set_current_thread_name="pthread_set_name_np(pthread_self(), name)"
+ ])
+ AS_IF([test -n "$set_current_thread_name"], [
+ AC_DEFINE_UNQUOTED(SET_CURRENT_THREAD_NAME(name), $set_current_thread_name)
+ AS_CASE([$set_current_thread_name],
+ [*'pthread_self()'*], [
+ set_another_thread_name=`echo "$set_current_thread_name" | sed 's/pthread_self()/thid/'`
+ AC_DEFINE_UNQUOTED(SET_ANOTHER_THREAD_NAME(thid,name), $set_another_thread_name)
+ ])
+ ])
+])
+
+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);],
+ [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)
+ ])
+])
+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([
+ @%:@include <signal.h>
+ @%:@ifdef HAVE_UCONTEXT_H
+ @%:@include <ucontext.h>
+ @%:@endif
+ mcontext_t test(mcontext_t mc) {return mc+1;}
+ ],
+ [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)
+ ], [
+ AC_DEFINE_UNQUOTED(DEFINE_MCONTEXT_PTR(mc, uc), mcontext_t *mc = &(uc)->uc_mcontext)
+ ])
+ AS_IF([test x"$rb_with_pthread" = xyes], [
+ AC_CHECK_FUNCS(getcontext setcontext)
+ ])
+])
+
+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([
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+void *
+thread_func(void *dmy)
+{
+ return dmy;
+}
+
+int
+use_threads(void)
+{
+ pthread_t tid;
+ if (pthread_create(&tid, 0, thread_func, 0) != 0) {
+ return -1;
+ }
+ if (pthread_join(tid, 0) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pid_t pid;
+ if (use_threads()) return EXIT_FAILURE;
+ pid = fork();
+
+ if (pid) {
+ int loc;
+ sleep(1);
+ if (waitpid(pid, &loc, WNOHANG) == 0) {
+ kill(pid, SIGKILL);
+ return EXIT_FAILURE;
+ }
+ if (!WIFEXITED(loc) || WEXITSTATUS(loc) != EXIT_SUCCESS)
+ return EXIT_FAILURE;
+ }
+ else {
+ if (use_threads()) return EXIT_FAILURE;
+ }
+
+ 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
+
+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]),
+ [
+ AS_CASE([$withval],
+ [yes], [
+ AS_IF([test "$enable_shared" = yes], [
+ AC_MSG_ERROR(dln_a_out can not make shared library)
+ ])
+ with_dln_a_out=yes],
+ [
+ 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([],[], [
+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)])
+
+AS_IF([test "$rb_cv_binary_elf" = yes], [
+ AC_DEFINE(USE_ELF)
+ AS_IF([test "$with_dln_a_out" = yes], [
+ AC_MSG_ERROR(dln_a_out does not work with ELF)
+ ])
+ 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])
+ ])
+])
+
+AS_CASE(["$target_os"],
+[linux* | gnu* | k*bsd*-gnu | bsdi* | kopensolaris*-gnu], [
+ AS_IF([test "$rb_cv_binary_elf" = no], [
+ with_dln_a_out=yes
+ ], [
+ LDFLAGS="$LDFLAGS -rdynamic"
+ ])])
+LIBEXT=a
+
+AC_SUBST(DLDFLAGS)dnl
+AC_SUBST(ARCH_FLAG)dnl
+
+AC_SUBST(STATIC)dnl
+AC_SUBST(CCDLFLAGS)dnl
+AC_SUBST(LDSHARED)dnl
+AC_SUBST(LDSHAREDXX)dnl
+AC_SUBST(DLEXT)dnl
+AC_SUBST(DLEXT2)dnl
+AC_SUBST(LIBEXT)dnl
+AC_SUBST(ASMEXT, S)dnl
+
+STATIC=
+
+AS_IF([test "$with_dln_a_out" != yes], [
+ rb_cv_dlopen=unknown
+ AC_MSG_CHECKING(whether OS depend dynamic link works)
+ AS_IF([test "$GCC" = yes], [
+ AS_CASE(["$target_os"],
+ [darwin*], [
+ # The -fno-common is needed if we wish to embed the Ruby interpreter
+ # into a plugin module of some project (as opposed to embedding it
+ # within the project's application). The -I/usr/local/include is
+ # needed because CPP as discovered by configure (cc -E -traditional)
+ # fails to consult /usr/local/include by default. This causes
+ # mkmf.rb's have_header() to fail if the desired resource happens to be
+ # installed in the /usr/local tree.
+ RUBY_APPEND_OPTION(CCDLFLAGS, -fno-common)],
+ [bsdi*|cygwin*|mingw*|aix*|interix*], [ ],
+ [
+ RUBY_APPEND_OPTION(CCDLFLAGS, -fPIC)])
+ ], [
+ AS_CASE(["$target_os"],
+ [hpux*], [CCDLFLAGS="$CCDLFLAGS +Z"],
+ [solaris*|irix*], [CCDLFLAGS="$CCDLFLAGS -KPIC"],
+ [sunos*], [CCDLFLAGS="$CCDLFLAGS -PIC"],
+ [esix*|uxpds*], [CCDLFLAGS="$CCDLFLAGS -KPIC"],
+ [: ${CCDLFLAGS=""}])
+ ])
+
+
+ AC_ARG_ENABLE(rpath,
+ AS_HELP_STRING([--enable-rpath], [embed run path into extension libraries.
+ enabled by default on ELF platforms]),
+ [enable_rpath=$enableval], [enable_rpath="$rb_cv_binary_elf"])
+
+ AS_CASE(["$target_os"],
+ [hpux*], [ DLDFLAGS="$DLDFLAGS -E"
+ : ${LDSHARED='$(LD) -b'}
+ XLDFLAGS="$XLDFLAGS -Wl,-E"
+ : ${LIBPATHENV=SHLIB_PATH}
+ rb_cv_dlopen=yes],
+ [solaris*], [ AS_IF([test "$GCC" = yes], [
+ : ${LDSHARED='$(CC) -shared'}
+ AS_IF([test "$rb_cv_prog_gnu_ld" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ ])
+ ], [
+ : ${LDSHARED='$(CC) -G'}
+ ])
+ AS_IF([test "$ac_cv_sizeof_voidp" = 8], [
+ : ${LIBPATHENV=LD_LIBRARY_PATH_64}
+ : ${PRELOADENV=LD_PRELOAD_64}
+ ], [
+ : ${LIBPATHENV=LD_LIBRARY_PATH_32}
+ : ${PRELOADENV=LD_PRELOAD_32}
+ ])
+ rb_cv_dlopen=yes],
+ [sunos*], [ : ${LDSHARED='$(LD) -assert nodefinitions'}
+ rb_cv_dlopen=yes],
+ [irix*], [ : ${LDSHARED='$(LD) -shared'}
+ rb_cv_dlopen=yes],
+ [sysv4*], [ : ${LDSHARED='$(LD) -G'}
+ rb_cv_dlopen=yes],
+ [nto-qnx*], [ : ${LDSHARED='$(CC) -shared'}
+ rb_cv_dlopen=yes],
+ [esix*|uxpds*], [ : ${LDSHARED='$(LD) -G'}
+ rb_cv_dlopen=yes],
+ [osf*], [ : ${LDSHARED='$(LD) -shared -expect_unresolved "*"'}
+ rb_cv_dlopen=yes],
+ [bsdi3*], [ AS_CASE(["$CC"],
+ [*shlicc*], [ : ${LDSHARED='$(CC) -r'}
+ rb_cv_dlopen=yes])],
+ [linux* | gnu* | k*bsd*-gnu | netbsd* | bsdi* | kopensolaris*-gnu | haiku*], [
+ : ${LDSHARED='$(CC) -shared'}
+ AS_IF([test "$rb_cv_binary_elf" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
+ ])
+ rb_cv_dlopen=yes],
+ [interix*], [ : ${LDSHARED='$(CC) -shared'}
+ XLDFLAGS="$XLDFLAGS -Wl,-E"
+ LIBPATHFLAG=" -L%1\$-s"
+ rb_cv_dlopen=yes],
+ [freebsd*|dragonfly*], [
+ : ${LDSHARED='$(CC) -shared'}
+ AS_IF([test "$rb_cv_binary_elf" = yes], [
+ LDFLAGS="$LDFLAGS -rdynamic"
+ DLDFLAGS="$DLDFLAGS "'-Wl,-soname,$@'
+ ], [
+ test "$GCC" = yes && test "$rb_cv_prog_gnu_ld" = yes || LDSHARED='$(LD) -Bshareable'
+ ])
+ rb_cv_dlopen=yes],
+ [openbsd*|mirbsd*], [ : ${LDSHARED='$(CC) -shared ${CCDLFLAGS}'}
+ AS_IF([test "$rb_cv_binary_elf" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ ])
+ rb_cv_dlopen=yes],
+ [darwin*], [ : ${LDSHARED='$(CC) -dynamic -bundle'}
+ : ${LDFLAGS=""}
+ : ${LIBPATHENV=DYLD_LIBRARY_PATH}
+ : ${PRELOADENV=DYLD_INSERT_LIBRARIES}
+ rb_cv_dlopen=yes],
+ [aix*], [ : ${LDSHARED='$(CC)'}
+ 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)'
+ : ${LIBPATHENV=LIBPATH}
+ rb_cv_dlopen=yes],
+ [nto-qnx*], [ DLDFLAGS="$DLDFLAGS -L/lib -L/usr/lib -L/usr/local/lib"
+ : ${LDSHARED='$(LD) -Bshareable -x'}
+ LDFLAGS="$LDFLAGS -L/lib -L/usr/lib -L/usr/local/lib"
+ rb_cv_dlopen=yes],
+ [cygwin*|mingw*], [
+ : ${LDSHARED='$(CC) -shared'}
+ XLDFLAGS="$XLDFLAGS -Wl,--stack,0x00200000,--enable-auto-import"
+ DLDFLAGS="${DLDFLAGS} -Wl,--enable-auto-image-base,--enable-auto-import"
+ : ${LIBPATHENV=PATH}
+ : ${PRELOADENV=""}
+ rb_cv_dlopen=yes],
+ [hiuxmpp], [ : ${LDSHARED='$(LD) -r'}],
+ [atheos*], [ : ${LDSHARED='$(CC) -shared'}
+ rb_cv_dlopen=yes],
+ [ : ${LDSHARED='$(LD)'}])
+ AC_MSG_RESULT($rb_cv_dlopen)
+
+ AS_IF([test "$rb_cv_dlopen" = yes], [
+ AS_CASE(["$target_os"],
+ [darwin*], [
+ for flag in \
+ "-undefined dynamic_lookup" \
+ "-multiply_defined suppress" \
+ ; 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])
+ ])
+ done
+ ])
+ ])
+
+ AS_IF([test "$enable_rpath:${RPATHFLAG}" = yes:], [
+ AS_IF([test "x$rpathflag" != x], [
+ RPATHFLAG=" ${rpathflag}%1\$-s"
+ ])
+ ])
+])
+AS_IF([test "${LDSHAREDXX}" = ""], [
+ AS_CASE(["${LDSHARED}"],
+ [*'$(CC)'*], [
+ LDSHAREDXX=`echo "${LDSHARED}" | sed 's/\$(CC)/$(CXX)/'`
+ ],
+ [*'${CC}'*], [
+ LDSHAREDXX=`echo "${LDSHARED}" | sed 's/\${CC}/${CXX}/'`
+ ],
+ [*$CC*], [
+ LDSHAREDXX=`echo "${LDSHARED}" | sed "s|$CC|$CXX|"`
+ ],
+ [ld" "*], [
+ ])
+])
+AS_CASE([${RPATHFLAG}],[*'%1$'*],[: ${LIBPATHFLAG=' -L%1$-s'}],[: ${LIBPATHFLAG=' -L%s'}])
+
+AC_SUBST(LINK_SO)
+AC_SUBST(LIBPATHFLAG)
+AC_SUBST(RPATHFLAG)
+AC_SUBST(LIBPATHENV, "${LIBPATHENV-LD_LIBRARY_PATH}")
+AC_SUBST(PRELOADENV, "${PRELOADENV-LD_PRELOAD}")
+AC_SUBST(TRY_LINK)
+
+AS_IF([test "x$OPT_DIR" != x], [
+ pat=`echo "${LDFLAGS_OPTDIR}" | sed ['s/[][\\.*|]/\\\\&/']`
+ LDFLAGS=`echo "${LDFLAGS}" | sed "s| ${pat}||"`
+ val=`IFS="$PATH_SEPARATOR"
+ for dir in $OPT_DIR; do
+ echo x ${LIBPATHFLAG} ${RPATHFLAG} |
+ sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${dir}/lib${IFS}g;s${IFS}%s${IFS}${dir}/lib${IFS}g"
+ done | tr '\012' ' ' | sed 's/ *$//'`
+ AS_IF([test x"$val" != x], [
+ test x"${LDFLAGS}" = x || LDFLAGS="$LDFLAGS "
+ LDFLAGS="$LDFLAGS$val"
+ test x"${DLDFLAGS}" = x || DLDFLAGS="$DLDFLAGS "
+ DLDFLAGS="$DLDFLAGS$val"
+ ])
+ LDFLAGS_OPTDIR="$val"
+])
+
+AS_CASE(["$target_os"],
+[freebsd*], [
+ AC_CHECK_LIB([procstat], [procstat_open_sysctl])
+ AS_IF([test "x$ac_cv_lib_procstat_procstat_open_sysctl" = xyes], [
+ AC_CHECK_FUNCS(procstat_getvmmap)
+ ])
+ ])
+AS_CASE(["$target_cpu-$target_os"],
+[*-darwin*], [
+ AC_CHECK_HEADERS([execinfo.h])
+ AS_IF([test "x$ac_cv_header_execinfo_h" = xyes], [
+ AC_CHECK_LIB([execinfo], [backtrace])
+ AC_CHECK_HEADERS([libunwind.h])
+ ])],
+[*-freebsd*|x86_64-netbsd*], [
+ AC_CHECK_HEADERS([execinfo.h])
+ AS_IF([test "x$ac_cv_header_execinfo_h" = xyes], [
+ AC_CHECK_LIB([execinfo], [backtrace])
+ AC_CHECK_LIB([unwind], [unw_backtrace])
+ ])])
+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([
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <signal.h>
+#include <execinfo.h>
+
+#define TRACE_SIZE 256
+
+void sigsegv(int signum, siginfo_t *info, void *ctx){
+ void *trace[TRACE_SIZE];
+ int n = backtrace(trace, TRACE_SIZE);
+ if (n > 0) {
+ /*fprintf(stdout, "backtrace:%d\n",n);*/
+ } else {
+ _exit(EXIT_FAILURE);
+ }
+ _exit(EXIT_SUCCESS);
+}
+int
+main(void)
+{
+ volatile int *a = NULL;
+ stack_t ss;
+ ss.ss_sp = malloc(SIGSTKSZ);
+ if (ss.ss_sp == NULL) {
+ fprintf(stderr, "cannot allocate memory for sigaltstack\n");
+ return EXIT_FAILURE;
+ }
+ ss.ss_size = SIGSTKSZ;
+ 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;
+ sa.sa_flags |= SA_SIGINFO;
+ sa.sa_flags |= SA_ONSTACK;
+ sigaction(SIGSEGV, &sa, NULL);
+ a[0] = 1;
+ return EXIT_SUCCESS;
+}
+],
+ rb_cv_broken_backtrace=no,
+ rb_cv_broken_backtrace=yes,
+ rb_cv_broken_backtrace=no)])
+ AS_IF([test "$rb_cv_broken_backtrace" = yes], [
+ AC_DEFINE(BROKEN_BACKTRACE, 1)
+ ])
+])
+
+AC_ARG_WITH(valgrind,
+ AS_HELP_STRING([--without-valgrind],[disable valgrind memcheck support]),
+ [], with_valgrind=yes)
+AS_IF([test x$with_valgrind != xno],
+ [AC_CHECK_HEADERS(valgrind/memcheck.h)])
+
+dln_a_out_works=no
+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([
+#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], [
+ dln_a_out_works=yes
+ AC_DEFINE(USE_DLN_A_OUT)
+ ])
+ ])
+])
+
+AS_IF([test "$dln_a_out_works" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ STATIC=-static
+ ], [
+ STATIC=-Bstatic
+ ])
+ DLEXT=so
+ CCDLFLAGS=
+], [
+ AS_CASE(["$target_os"],
+ [hpux*], [
+ DLEXT=sl],
+ [darwin*], [
+ 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
+ ])
+])
+AS_IF([test x"$LOAD_RELATIVE" = x1], [
+ load_relative=yes
+], [
+ unset load_relative
+])
+
+len=2 # .rb
+n=`expr "$DLEXT" : '.*'`; test "$n" -gt "$len" && len=$n
+n=`expr "$DLEXT2" : '.*'`; test "$n" -gt "$len" && len=$n
+AC_DEFINE_UNQUOTED(DLEXT_MAXLEN, `expr $len + 1`)
+test ".$DLEXT" = "." || AC_DEFINE_UNQUOTED(DLEXT, ".$DLEXT")
+test ".$DLEXT2" = "." || AC_DEFINE_UNQUOTED(DLEXT2, ".$DLEXT2")
+AC_SUBST(DLEXT)
+
+AS_IF([test "$with_dln_a_out" = yes], [
+ STRIP=true
+], [
+ AC_CHECK_TOOL(STRIP, strip, :)dnl
+])
+
+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],
+ [pass to --with-ext option of extmk.rb]))
+AC_ARG_WITH(out-ext,
+ AC_HELP_STRING([--with-out-ext=EXTS],
+ [pass to --without-ext option of extmk.rb]))
+EXTSTATIC=
+AC_SUBST(EXTSTATIC)dnl
+AC_ARG_WITH(static-linked-ext,
+ AS_HELP_STRING([--with-static-linked-ext], [link external modules statically]),
+ [AS_CASE([$withval],[yes],[STATIC=;EXTSTATIC=static],[no],[],[EXTSTATIC="$withval"])])
+AS_CASE([",$EXTSTATIC,"], [,static,|*,enc,*], [
+ ENCOBJS='enc/encinit.$(OBJEXT) enc/libenc.$(LIBEXT) enc/libtrans.$(LIBEXT)'
+ EXTOBJS='ext/extinit.$(OBJEXT)'
+ AC_DEFINE_UNQUOTED(EXTSTATIC, 1)
+ AC_SUBST(ENCSTATIC, static)
+], [
+ ENCOBJS='dmyenc.$(OBJEXT)'
+ EXTOBJS='dmyext.$(OBJEXT)'
+])
+AC_SUBST(ENCOBJS)
+AC_SUBST(EXTOBJS)
+
+AC_ARG_WITH(setup,
+ AS_HELP_STRING([--with-setup=SETUP], [use extension libraries setup]),
+ [setup=$withval])
+AS_IF([test -n "$setup"], [
+ AS_IF([! test -f "ext/$setup" -o -f "$srcdir/ext/$setup"], [
+ AC_MSG_ERROR(Setup file $setup not found under ext or $srcdir/ext)
+ ])
+], [test -f "$srcdir/ext/Setup.$target_os"], [
+ setup="Setup.$target_os"
+], [
+ setup=
+ for file in "$srcdir"/ext/Setup.*; do
+ AS_CASE(["$file"], [*~|*.bak|*.orig|*.rej|*.tmp], [continue])
+ setup=`basename "$file"`
+ AS_CASE(["$target_os"], [`expr "$setup" : 'Setup.\(.*\)'`*], [break])
+ platform=`sed '/^option *platform */!d;s///;s/|/*|/g;q' "$file"`
+ AS_IF([test "x$platform" != x], [
+ eval "AS_CASE([\"\$target_os\"], [$platform*], [break])"
+ ])
+ setup=
+ done
+ : ${setup:=Setup}
+])
+AC_SUBST(setup)
+
+rubylibprefix='${libdir}/${RUBY_BASE_NAME}'
+AC_ARG_WITH(rubylibprefix,
+ AS_HELP_STRING([--with-rubylibprefix=DIR], [prefix for ruby libraries [[LIBDIR/RUBY_BASE_NAME]]]),
+ [AS_IF([test "x$withval" = xno], [
+ AC_MSG_ERROR([No ruby, No libprefix])
+ ])
+ rubylibprefix="$withval"])
+AC_SUBST(rubylibprefix)
+
+AS_IF([test x"${exec_prefix}" != xNONE], [
+ RUBY_EXEC_PREFIX="$exec_prefix"
+], [test x"$prefix" != xNONE], [
+ RUBY_EXEC_PREFIX="$prefix"
+], [
+ RUBY_EXEC_PREFIX=$ac_default_prefix
+])
+pat=`echo "${RUBY_EXEC_PREFIX}" | tr -c '\012' .`'\(.*\)'
+for var in bindir libdir rubylibprefix; do
+ eval val='"$'$var'"'
+ AS_CASE(["$val"], ["${RUBY_EXEC_PREFIX}"*], [val='${exec_prefix}'"`expr \"$val\" : \"$pat\"`"])
+ eval $var='"$val"'
+done
+
+BTESTRUBY='$(MINIRUBY)'
+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"]']`
+ XRUBY_RUBYLIBDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["rubylibdir"]']`
+ XRUBY_RUBYHDRDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["rubyhdrdir"]']`
+ AC_SUBST(XRUBY_LIBDIR)
+ AC_SUBST(XRUBY_RUBYLIBDIR)
+ AC_SUBST(XRUBY_RUBYHDRDIR)
+ PREP='$(arch)-fake.rb'
+ RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
+ RUNRUBY='$(RUNRUBY_COMMAND)'
+ XRUBY='$(MINIRUBY)'
+ BOOTSTRAPRUBY='$(BASERUBY)'
+ TEST_RUNNABLE=no
+ CROSS_COMPILING=yes
+], [
+ 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='$(RUNRUBY_COMMAND) --'
+ XRUBY='$(RUNRUBY)'
+ BOOTSTRAPRUBY='$(MINIRUBY)'
+ TEST_RUNNABLE=yes
+ CROSS_COMPILING=no
+])
+AC_SUBST(TEST_RUNNABLE)
+AC_SUBST(CROSS_COMPILING)
+AC_SUBST(MINIRUBY)
+AC_SUBST(BTESTRUBY)
+AC_SUBST(PREP)
+AC_SUBST(RUNRUBY_COMMAND)
+AC_SUBST(RUNRUBY)
+AC_SUBST(XRUBY)
+AC_SUBST(BOOTSTRAPRUBY)
+AC_SUBST(EXTOUT, [${EXTOUT=.ext}])
+
+])RSTMAKEFILE=""
+LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'
+LIBRUBY='$(LIBRUBY_A)'
+LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static'
+LIBRUBYARG='$(LIBRUBYARG_STATIC)'
+SOLIBS=
+
+AS_CASE(["$target_os"],
+ [cygwin*|mingw*|haiku*|darwin*], [
+ : ${DLDLIBS=""}
+ ],
+ [
+ DLDLIBS="$DLDLIBS -lc"
+ ])
+
+AC_ARG_ENABLE(multiarch,
+ AS_HELP_STRING([--enable-multiarch], [enable multiarch compatible directories]),
+ [multiarch=], [unset multiarch])
+AS_IF([test ${multiarch+set}], [
+ AC_DEFINE(ENABLE_MULTIARCH)
+])
+
+archlibdir='${libdir}/${arch}'
+sitearchlibdir='${libdir}/${sitearch}'
+archincludedir='${includedir}/${arch}'
+sitearchincludedir='${includedir}/${sitearch}'
+
+AC_ARG_WITH(soname,
+ AS_HELP_STRING([--with-soname=SONAME], [base name of shared library]),
+ [RUBY_SO_NAME=$withval],
+ [
+ AS_CASE(["$target_os"],
+ [darwin*], [
+ RUBY_SO_NAME='$(RUBY_BASE_NAME).$(RUBY_PROGRAM_VERSION)'
+ ],
+ [cygwin*], [
+ RUBY_SO_NAME='$(RUBY_BASE_NAME)$(MAJOR)$(MINOR)0'
+ ],
+ [mingw*], [
+ RUBY_SO_NAME="${rb_cv_msvcrt}"'-$(RUBY_BASE_NAME)$(MAJOR)$(MINOR)0'
+ AS_IF([test x"${target_cpu}" != xi386], [
+ RUBY_SO_NAME="${target_cpu}-${RUBY_SO_NAME}"
+ ])
+ ],
+ [RUBY_SO_NAME='$(RUBY_BASE_NAME)'])
+ ])
+
+LIBRUBY_LDSHARED=$LDSHARED
+LIBRUBY_DLDFLAGS=$DLDFLAGS
+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,
+ AS_HELP_STRING([--enable-shared], [build a shared library for Ruby]),
+ [enable_shared=$enableval])
+libprefix=${multiarch+'$(archlibdir)'}${multiarch-'$(libdir)'}
+LIBRUBY_RELATIVE=${load_relative-no}
+AS_CASE("$enable_shared", [yes], [
+ LIBRUBY='$(LIBRUBY_SO)'
+ LIBRUBYARG_SHARED='-l$(RUBY_SO_NAME)'
+ LIBRUBYARG='$(LIBRUBYARG_SHARED)'
+ 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
+ AS_IF([test "$bindir" = '${exec_prefix}/bin'], [
+ AS_CASE(["$libdir"], ['${exec_prefix}/'*], [libdir_basename=`basename "$libdir"`])
+ ])
+ AC_DEFINE_UNQUOTED(LIBDIR_BASENAME, ["${libdir_basename}"])
+ libdir_basename="${libdir_basename}"${multiarch+'/${arch}'}
+
+ AS_CASE(["$target_os"],
+ [freebsd*|dragonfly*], [],
+ [
+ AS_IF([test "$GCC" = yes], [
+ RUBY_TRY_LDFLAGS([${linker_flag}--no-undefined], [no_undefined=yes], [no_undefined=no])
+ AS_IF([test "no_undefined" = yes], [
+ RUBY_APPEND_OPTION(EXTLDFLAGS, [${linker_flag}--no-undefined])
+ ])
+ ])
+ ])
+
+ AS_CASE(["$target_os"],
+ [sunos4*], [
+ 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,$(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}"
+ LIBRUBY_RELATIVE=yes
+ ])
+ ],
+ [freebsd*|dragonfly*], [
+ SOLIBS='$(LIBS)'
+ 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_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='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
+ ], [ # a.out platforms
+ LIBRUBY_ALIASES=""
+ ])
+ ],
+ [openbsd*|mirbsd*], [
+ SOLIBS='$(LIBS)'
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR).'`expr ${MINOR} \* 10 + ${TEENY}`
+ ],
+ [solaris*], [
+ SOLIBS='$(LIBS)'
+ 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)'
+ AS_IF([test "$GCC" = yes], [
+ LIBRUBY_DLDFLAGS="$DLDFLAGS "'-Wl,-h,$(@F)'
+ ], [
+ LIBRUBY_DLDFLAGS="$DLDFLAGS "'-h $(@F)'
+ ])
+ XLDFLAGS="$XLDFLAGS "'-R${libdir}'
+ ],
+ [hpux*], [
+ XLDFLAGS="$XLDFLAGS "'-Wl,+s,+b,$(libdir)'
+ 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'
+ ],
+ [darwin*], [
+ LIBRUBY_LDSHARED='$(CC) -dynamiclib'
+ AS_IF([test "$load_relative" = yes], [
+ libprefix="@executable_path/../${libdir_basename}"
+ LIBRUBY_RELATIVE=yes
+ ])
+ 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], [
+ LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-Wl,-unexported_symbol,_Init_*'
+ LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-Wl,-unexported_symbol,_ruby_static_id_*'
+ LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "'-Wl,-unexported_symbol,*_threadptr_*'
+ ])
+ LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS "' $(XLDFLAGS)'
+ LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT)'
+ LIBRUBY_SONAME='lib$(RUBY_BASE_NAME).$(RUBY_API_VERSION).$(SOEXT)'
+ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_INSTALL_NAME).$(SOEXT)'
+ SOLIBS='$(LIBS)'
+ ],
+ [interix*], [
+ LIBRUBYARG_SHARED='-L. -L${libdir} -l$(RUBY_SO_NAME)'
+ ],
+ [mingw*|cygwin*|mswin*], [
+ LIBRUBY_RELATIVE=yes
+ ])
+], [
+ LIBRUBYARG_SHARED=
+
+ # enable PIE if possible
+ AC_ARG_ENABLE(pie,
+ AS_HELP_STRING([--disable-pie], [disable PIE feature]),
+ [pie=$enableval], [pie=])
+ 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], [
+ # Use -fPIE when testing -pie. RUBY_TRY_LDFLAGS sets
+ # $save_CFLAGS internally, so set other name here.
+ save_CFLAGS_before_pie="$CFLAGS"
+ CFLAGS="$CFLAGS -fPIE"
+
+ # gcc need -pie but clang need -Wl,-pie.
+ for pie in -pie -Wl,-pie; do
+ RUBY_TRY_LDFLAGS([$pie], [], [pie=])
+ AS_IF([test "x$pie" != x], [
+ RUBY_APPEND_OPTION(XCFLAGS, -fPIE)
+ RUBY_APPEND_OPTION(XLDFLAGS, $pie)
+ break
+ ])
+ done
+ CFLAGS="$save_CFLAGS_before_pie"
+ ])
+ ])
+])
+AS_IF([test "$enable_rpath" = yes], [
+ test -z "$LIBRUBY_RPATHFLAGS" || LIBRUBY_RPATHFLAGS="$LIBRUBY_RPATHFLAGS "
+ rpathflag="${RPATHFLAG}"
+ AS_CASE(["${cross_compiling}${load_relative}"], [*yes*], [], [rpathflag="$RPATHFLAG$LIBPATHFLAG"])
+ rpathflag=`IFS="$PATH_SEPARATOR"
+ echo x "$rpathflag" |
+ sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${libprefix}${IFS}g;s${IFS}%s${IFS}${libprefix}${IFS}g"
+ `
+ LIBRUBY_RPATHFLAGS="$LIBRUBY_RPATHFLAGS${rpathflag}"
+ LIBRUBYARG_SHARED="$LIBRUBY_RPATHFLAGS $LIBRUBYARG_SHARED"
+ LIBRUBYARG_STATIC="$LIBRUBY_RPATHFLAGS $LIBRUBYARG_STATIC"
+])
+AC_SUBST(LIBRUBY_RELATIVE)
+
+LDFLAGS="-L. $LDFLAGS"
+AC_SUBST(ARCHFILE)
+
+AS_IF([test "$EXEEXT" = .exe], [
+ EXECUTABLE_EXTS='".exe",".com",".cmd",".bat"'
+ AC_DEFINE_UNQUOTED(EXECUTABLE_EXTS, $EXECUTABLE_EXTS)
+ EXECUTABLE_EXTS=`echo $EXECUTABLE_EXTS | tr -d '"' | tr , ' '`
+ AC_SUBST(EXECUTABLE_EXTS)
+])
+
+AS_CASE("$cross_compiling:${LIBPATHENV}", [yes:* | no:], [], [
+ AC_MSG_CHECKING(whether wrapper for $LIBPATHENV is needed)
+ AS_IF([env ${LIBPATHENV}=/lib /bin/sh -c ': ${'${LIBPATHENV}'?}' 2>/dev/null],
+ [AC_MSG_RESULT(no)],
+ [PREP="$PREP"' exe/$(PROGRAM)'
+ AC_MSG_RESULT(yes)]
+ )
+])
+
+AC_ARG_ENABLE(dtrace,
+ AS_HELP_STRING([--enable-dtrace],
+ [enable DTrace for tracing inside ruby. enabled by default on systems having dtrace]),
+ [enable_dtrace=$enableval], [enable_dtrace=auto])
+
+LIBRUBY_A_OBJS='$(OBJS)'
+DTRACE_REBUILD=
+AS_CASE(["${enable_dtrace}"],
+[yes|auto], [
+ RUBY_DTRACE_AVAILABLE()
+], [
+ 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])
+ ], [test "$cross_compiling" = yes], [dnl
+ AC_MSG_ERROR([--enable-dtrace, however, cross compiling])
+ ], [test "${rb_cv_dtrace_available}" = "no"], [dnl
+ AC_MSG_ERROR([--enable-dtrace, however, USDT is not available])
+ ])
+])
+AS_CASE([$rb_cv_dtrace_available],
+[yes*], [dnl
+ RUBY_DTRACE_POSTPROCESS()
+ AS_IF([test "$rb_cv_prog_dtrace_g" != no], [dnl
+ DTRACE_OBJ='probes.$(OBJEXT)'
+ ])
+ AS_IF([test "$rb_cv_prog_dtrace_g" = rebuild], [dnl
+ DTRACE_REBUILD=yes
+ LIBRUBY_A_OBJS='$(DTRACE_GLOMMED_OBJ)'
+ ])
+ AS_CASE("${target_os}", [freebsd*], [dnl
+ # FreeBSD's dtrace requires libelf
+ LIBS="-lelf $LIBS"
+ ])
+ DTRACE_EXT=d
+], [dnl
+ enable_dtrace=no
+ DTRACE_EXT=dmyh
+])
+AC_SUBST(DTRACE_EXT)
+AC_SUBST(DTRACE_OBJ)
+AC_SUBST(DTRACE_REBUILD)
+AC_SUBST(DTRACE_OPT)
+AC_SUBST(LIBRUBY_A_OBJS)
+
+AC_ARG_ENABLE(gcov,
+ AS_HELP_STRING([--enable-gcov], [enable coverage measurement by gcov]),
+ [gcov=yes])
+AS_IF([test x"$gcov" = xyes], [
+ CFLAGS="$CFLAGS -coverage"
+ LDFLAGS="$LDFLAGS -coverage"
+])
+
+RUBY_SETJMP_TYPE
+}
+{ # 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_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], [
+ RDOCTARGET="rdoc"
+ ], [
+ RDOCTARGET="nodoc"
+ ])
+ AS_IF([test "$install_capi" != no -a -n "$DOXYGEN"], [
+ CAPITARGET="capi"
+ ], [
+ CAPITARGET="nodoc"
+ ])
+], [
+ RDOCTARGET="nodoc"
+ CAPITARGET="nodoc"
+])
+
+AC_SUBST(RDOCTARGET)
+AC_SUBST(CAPITARGET)
+
+AS_CASE(["$RDOCTARGET:$CAPITARGET"],[nodoc:nodoc],[INSTALLDOC=nodoc],[INSTALLDOC=all])
+AC_SUBST(INSTALLDOC)
+
+AC_ARG_ENABLE(install-static-library,
+ AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]),
+ [INSTALL_STATIC_LIBRARY=$enableval],
+ AS_IF([test x"$enable_shared" = xyes],
+ [INSTALL_STATIC_LIBRARY=no],
+ [INSTALL_STATIC_LIBRARY=yes]))
+AC_SUBST(INSTALL_STATIC_LIBRARY)
+
+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) {}], [], [
+ rb_cv_symbol_prefix=`$NM conftest.$ac_objext |
+ sed -n ['/.*T[ ]\([^ ]*\)conftest_external.*/!d;s//\1/p;q']`
+ ],
+ [rb_cv_symbol_prefix=''])
+ test -n "$rb_cv_symbol_prefix" || rb_cv_symbol_prefix=NONE
+])
+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]),
+ [test "$enableval" = yes || DLNOBJ=dmydln.o])
+AC_SUBST(DLNOBJ)
+MINIDLNOBJ=dmydln.o
+
+AS_CASE(["$target_os"],
+ [linux*], [
+ ],
+ [netbsd*], [
+ RUBY_APPEND_OPTION(CFLAGS, -pipe)
+ ],
+ [darwin*], [
+ RUBY_APPEND_OPTION(CFLAGS, -pipe)
+ RUBY_APPEND_OPTION(XLDFLAGS, [-framework Foundation])
+ RUBY_APPEND_OPTION(LIBRUBYARG_STATIC, [-framework Foundation])
+ ],
+ [osf*], [
+ AS_IF([test "$GCC" != "yes" ], [
+ # compile something small: taint.c is fine for this.
+ # the main point is the '-v' flag of 'cc'.
+ AS_CASE(["`cc -v -I. -c main.c -o /tmp/main.o 2>&1`"],
+ [*/gemc_cc*], [ # we have the new DEC GEM CC
+ CFLAGS="$CFLAGS -oldc"
+ ],
+ [ # we have the old MIPS CC
+ ])
+ # cleanup
+ rm -f /tmp/main.o
+ CFLAGS="$CFLAGS -std"
+ ])
+ ],
+ [cygwin*|mingw*], [
+ LIBRUBY_DLDFLAGS="${DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)'
+ AS_CASE(["$target_os"],
+ [cygwin*], [
+ AS_IF([test x"$enable_shared" = xyes], [
+ LIBRUBY_SO='cyg$(RUBY_SO_NAME)'.dll
+ LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' $(RUBYDEF)'
+ ])
+ ],
+ [mingw*], [
+ AS_IF([test x"$enable_shared" = xyes], [
+ LIBRUBY_SO='$(RUBY_SO_NAME)'.dll
+ LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' $(RUBYDEF)'
+ ])
+ EXPORT_PREFIX=' '
+ DLDFLAGS="${DLDFLAGS}"' $(DEFFILE)'
+ AC_LIBOBJ([win32/win32])
+ AC_LIBOBJ([win32/file])
+ COMMON_LIBS=m
+# COMMON_MACROS="WIN32_LEAN_AND_MEAN="
+ COMMON_HEADERS="winsock2.h windows.h"
+ THREAD_MODEL=win32
+ PLATFORM_DIR=win32
+ ])
+ LIBRUBY_ALIASES=''
+ FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
+ SOLIBS='$(LIBS)'
+ AS_IF([test x"$enable_shared" = xyes], [
+ LIBRUBY='lib$(RUBY_SO_NAME).dll.a'
+ ], [
+ LIBRUBY_SO=dummy
+ LIBRUBY='lib$(RUBY_SO_NAME).a'
+ LIBRUBYARG='-l$(RUBY_SO_NAME)'
+ ])
+ ],
+ [hpux*], [
+ AS_CASE(["$YACC"],[*yacc*], [
+ XCFLAGS="$XCFLAGS -DYYMAXDEPTH=300"
+ YACC="$YACC -Nl40000 -Nm40000"
+ ])
+])
+
+MINIOBJS="$MINIDLNOBJ"
+
+AS_CASE(["$THREAD_MODEL"],
+[pthread], [AC_CHECK_HEADERS(pthread.h)],
+[win32], [],
+[""], [AC_MSG_ERROR(thread model is missing)],
+ [AC_MSG_ERROR(unknown thread model $THREAD_MODEL)])
+
+AC_ARG_ENABLE(debug-env,
+ AS_HELP_STRING([--enable-debug-env], [enable RUBY_DEBUG environment variable]),
+ [AC_SUBST(ENABLE_DEBUG_ENV, yes)])
+
+AS_CASE(["$FIRSTMAKEFILE"], [*GNUmakefile:*], [gnumake=yes], [
+ AC_MSG_CHECKING([if ${MAKE-make} is GNU make])
+ mkdir conftest.dir
+ echo "all:; @echo yes" > conftest.dir/GNUmakefile
+ echo "all:; @echo no" > conftest.dir/Makefile
+ gnumake=`(cd conftest.dir; ${MAKE-make})`
+ rm -fr conftest.dir
+ AS_CASE(["$gnumake"],
+ [*yes*], [
+ FIRSTMAKEFILE=GNUmakefile:template/GNUmakefile.in
+ gnumake=yes],
+ [
+ gnumake=no])
+ AC_MSG_RESULT($gnumake)
+])
+AS_IF([test "$gnumake" = yes], [ NULLCMD=: ], [
+ AC_MSG_CHECKING([for safe null command for ${MAKE-make}])
+ mkdir conftest.dir
+ NULLCMD=
+ for cmd in : true; do
+ echo 'A=1' > conftest.dir/Makefile
+ echo 'B=$(A:1=@'$cmd')' >> conftest.dir/Makefile
+ echo 'all:; $B 1 2 3 4 5 6 7 8 9' >> conftest.dir/Makefile
+ AS_IF([(cd conftest.dir; ${MAKE-make} >/dev/null 2>/dev/null)], [
+ NULLCMD=$cmd
+ break
+ ])
+ done
+ rm -fr conftest.dir
+ AS_IF([test -z "$NULLCMD"], [
+ AC_MSG_ERROR(no candidate for safe null command)
+ ])
+ AC_MSG_RESULT($NULLCMD)
+])
+AC_SUBST(NULLCMD)
+
+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} |
+ sed 's/=[^ ]*//g;s/ /__ || defined __/g'`__
+@%:@else
+@%:@error
+>>>>>><<<<<<
+@%:@endif], [],
+[
+ rb_cv_architecture_macros=yes
+ mv -f confdefs1.h confdefs.h
+], [
+ rb_cv_architecture_macros=no
+ archflagpat=`eval echo '"'"${ARCH_FLAG}"'"' | sed 's/[[][|.*]]/\\&/g'`
+ new_cflags=`echo "$CFLAGS" | sed "s|$archflagpat"'||'`
+ for archs in ${universal_archnames}; do
+ cpu=${archs@%:@*=}
+ archs=${archs%=*}
+ CFLAGS="$new_cflags -arch $archs"
+ archs="__${archs}__"
+ AC_MSG_CHECKING([for macro ${archs} on ${cpu}])
+ AC_TRY_COMPILE([@%:@ifndef ${archs}
+@%:@error
+@%:@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);],
+ [rb_cv_architecture_available=yes], [rb_cv_architecture_available=no]))
+])
+
+CPPFLAGS="$CPPFLAGS "'$(DEFS)'
+test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}'
+AS_IF([test -n "${cflags+set}"], [
+ cflagspat=`eval echo '"'"${cflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/^ *$/ /'`
+ CFLAGS=`echo " $CFLAGS " | sed "s|$cflagspat"'|${cflags}|;s/^ *//;s/ *$//'`
+])
+AS_IF([test -n "${cxxflags+set}"], [
+ cxxflagspat=`eval echo '"'"${cxxflags}"'"' | sed 's/[[][|.*]]/\\&/g;s/^ */ /;s/^ *$/ /'`
+ CXXFLAGS=`echo " $CXXFLAGS " | sed "s|$cxxflagspat"'|${cxxflags}|;s/^ *//;s/ *$//'`
+])
+AS_IF([test "${ARCH_FLAG}"], [
+ archflagpat=`eval echo '"'"${ARCH_FLAG}"'"' | sed 's/[[][|.*]]/\\&/g'`
+ CFLAGS=`echo "$CFLAGS" | sed "s| *$archflagpat"'||'`
+ CXXFLAGS=`echo "$CXXFLAGS" | sed "s| *$archflagpat"'||'`
+ LDFLAGS=`echo "$LDFLAGS" | sed "s| *$archflagpat"'||'`
+])
+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(optflags)dnl
+AC_SUBST(debugflags)dnl
+AC_SUBST(warnflags)dnl
+AC_SUBST(strict_warnflags)dnl
+AC_SUBST(XCFLAGS)dnl
+AC_SUBST(XLDFLAGS)dnl
+AC_SUBST(EXTLDFLAGS)dnl
+AC_SUBST(EXTDLDFLAGS)dnl
+AC_SUBST(LIBRUBY_LDSHARED)
+AC_SUBST(LIBRUBY_DLDFLAGS)
+AC_SUBST(RUBY_INSTALL_NAME)
+AC_SUBST(rubyw_install_name)
+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)
+AC_SUBST(LIBRUBYARG_STATIC)
+AC_SUBST(LIBRUBYARG_SHARED)
+AC_SUBST(SOLIBS)
+AC_SUBST(DLDLIBS)
+AC_SUBST(ENABLE_SHARED)
+AC_SUBST(MAINLIBS)
+AC_SUBST(COMMON_LIBS)
+AC_SUBST(COMMON_MACROS)
+AC_SUBST(COMMON_HEADERS)
+AC_SUBST(EXPORT_PREFIX)
+AC_SUBST(SYMBOL_PREFIX)
+AC_SUBST(MINIOBJS)
+AC_SUBST(THREAD_MODEL)
+AC_SUBST(PLATFORM_DIR)
+
+firstmf=`echo $FIRSTMAKEFILE | sed 's/:.*//'`
+firsttmpl=`echo $FIRSTMAKEFILE | sed 's/.*://'`
+MAKEFILES="Makefile $firstmf"
+MAKEFILES="`echo $MAKEFILES`"
+AC_SUBST(MAKEFILES)
+
+ri_prefix=
+test "$program_prefix" != NONE &&
+ ri_prefix=$program_prefix
+
+ri_suffix=
+test "$program_suffix" != NONE &&
+ ri_suffix=$program_suffix
+
+RUBY_INSTALL_NAME="${ri_prefix}"'$(RUBY_BASE_NAME)'"${ri_suffix}"
+AS_CASE(["$target_os"],
+ [cygwin*|mingw*], [
+ RUBYW_INSTALL_NAME="${ri_prefix}"'$(RUBYW_BASE_NAME)'"${ri_suffix}"
+ rubyw_install_name='$(RUBYW_INSTALL_NAME)'
+ ])
+
+rubylibdir='${rubylibprefix}/${ruby_version}'
+rubyarchdir=${multiarch+'${rubyarchprefix}/${ruby_version}'}${multiarch-'${rubylibdir}/${arch}'}
+
+rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'}
+AC_ARG_WITH(rubyarchprefix,
+ AS_HELP_STRING([--with-rubyarchprefix=DIR],
+ [prefix for architecture dependent ruby libraries [[RUBYLIBPREFIX/ARCH]]]),
+ [rubyarchprefix="$withval"])
+AC_SUBST(rubyarchprefix)
+
+rubysitearchprefix=${multiarch+'${sitearchlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${sitearch}'}
+AC_ARG_WITH(rubysitearchprefix,
+ AS_HELP_STRING([--with-rubysitearchprefix=DIR],
+ [prefix for architecture dependent site libraries [[RUBYLIBPREFIX/SITEARCH]]]),
+ [rubysitearchprefix="$withval"])
+AC_SUBST(rubysitearchprefix)
+
+RI_BASE_NAME=`echo ${RUBY_BASE_NAME} | sed 's/ruby/ri/'`
+ridir='${datarootdir}/${RI_BASE_NAME}'
+AC_ARG_WITH(ridir,
+ AS_HELP_STRING([--with-ridir=DIR], [ri documentation [[DATAROOTDIR/ri]]]),
+ [ridir=$withval])
+AC_SUBST(ridir)
+AC_SUBST(RI_BASE_NAME)
+
+AC_ARG_WITH(ruby-version,
+ AS_HELP_STRING([--with-ruby-version=STR], [ruby version string for version specific directories [[full]] (full|minor|STR)]),
+ [ruby_version=$withval],
+ [ruby_version=full])
+unset RUBY_LIB_VERSION
+unset RUBY_LIB_VERSION_STYLE
+AS_CASE(["$ruby_version"],
+ [full], [RUBY_LIB_VERSION_STYLE='3 /* full */'],
+ [minor], [RUBY_LIB_VERSION_STYLE='2 /* minor */'])
+AS_IF([test ${RUBY_LIB_VERSION_STYLE+set}], [
+ {
+ echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE"
+ echo '#define STRINGIZE(x) x'
+ test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0'
+ echo '#include "version.h"'
+ echo 'ruby_version=RUBY_LIB_VERSION'
+ } > conftest.c
+ ruby_version="`$CPP -I. -I"${srcdir}" -I"${srcdir}/include" conftest.c | sed '/^ruby_version=/!d;s/ //g'`"
+ eval $ruby_version
+], [test -z "${ruby_version}"], [
+ AC_MSG_ERROR([No ruby version, No place for bundled libraries])
+], [
+ RUBY_LIB_VERSION="${ruby_version}"
+])
+AC_SUBST(RUBY_LIB_VERSION_STYLE)
+AC_SUBST(RUBY_LIB_VERSION)
+
+AC_ARG_WITH(sitedir,
+ AS_HELP_STRING([--with-sitedir=DIR], [site libraries in DIR [[RUBY_LIB_PREFIX/site_ruby]], "no" to disable site directory]),
+ [sitedir=$withval],
+ [sitedir='${rubylibprefix}/site_ruby'])
+sitelibdir='${sitedir}/${ruby_version}'
+
+AC_ARG_WITH(sitearchdir,
+ AS_HELP_STRING([--with-sitearchdir=DIR],
+ [architecture dependent site libraries in DIR [[SITEDIR/SITEARCH]], "no" to disable site directory]),
+ [sitearchdir=$withval],
+ [sitearchdir=${multiarch+'${rubysitearchprefix}/site_ruby/${ruby_version}'}${multiarch-'${sitelibdir}/${sitearch}'}])
+
+AC_ARG_WITH(vendordir,
+ AS_HELP_STRING([--with-vendordir=DIR], [vendor libraries in DIR [[RUBY_LIB_PREFIX/vendor_ruby]], "no" to disable vendor directory]),
+ [vendordir=$withval],
+ [vendordir='${rubylibprefix}/vendor_ruby'])
+vendorlibdir='${vendordir}/${ruby_version}'
+
+AC_ARG_WITH(vendorarchdir,
+ AS_HELP_STRING([--with-vendorarchdir=DIR],
+ [architecture dependent vendor libraries in DIR [[VENDORDIR/SITEARCH]], "no" to disable vendor directory]),
+ [vendorarchdir=$withval],
+ [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby/${ruby_version}'}${multiarch-'${vendorlibdir}/${sitearch}'}])
+
+AS_IF([test "${LOAD_RELATIVE+set}"], [
+ AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE)
+ RUBY_EXEC_PREFIX=''
+])
+
+AC_SUBST(RUBY_EXEC_PREFIX)
+
+AC_SUBST(libdirname, ${multiarch+arch}libdir)
+AC_SUBST(archlibdir)dnl
+AC_SUBST(sitearchlibdir)dnl
+AC_SUBST(archincludedir)dnl
+AC_SUBST(sitearchincludedir)dnl
+AC_SUBST(arch)dnl
+AC_SUBST(sitearch)dnl
+AC_SUBST(ruby_version)dnl
+AC_SUBST(rubylibdir)dnl
+AC_SUBST(rubyarchdir)dnl
+AC_SUBST(sitedir)dnl
+AC_SUBST(sitelibdir)dnl
+AC_SUBST(sitearchdir)dnl
+AC_SUBST(vendordir)dnl
+AC_SUBST(vendorlibdir)dnl
+AC_SUBST(vendorarchdir)dnl
+
+AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl
+AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl
+
+AS_IF([test "${universal_binary-no}" = yes ], [
+ arch="universal-${target_os}"
+ AS_IF([test "${rb_cv_architecture_available}" = yes], [
+ AC_DEFINE_UNQUOTED(RUBY_PLATFORM_CPU, __ARCHITECTURE__)
+ ], [
+ 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}"])
+ done
+ ])
+ ints='long int short'
+ test "$ac_cv_type_long_long" = yes && ints="'long long' $ints"
+ 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)
+], [
+ arch="${target_cpu}-${target_os}"
+ AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch")
+])
+
+unset sitearch
+AS_CASE(["$target_os"],[mingw*],[sitearch="$target_cpu-$rb_cv_msvcrt"])
+: ${sitearch='${arch}'}
+
+AC_ARG_WITH(search-path,
+ AS_HELP_STRING([--with-search-path=DIR], [specify the additional search path]),
+ [search_path=$withval])
+AS_IF([test "$search_path" != ""], [
+ AC_SUBST(RUBY_SEARCH_PATH, $search_path)
+])
+
+AC_ARG_WITH(rubyhdrdir,
+ AS_HELP_STRING([--with-rubyhdrdir=DIR], [core headers in DIR [[INCLUDEDIR/RUBY_BASE_NAME-RUBY_VERSION]]]),
+ [rubyhdrdir=$withval],
+ [rubyhdrdir='${includedir}/${RUBY_VERSION_NAME}'])
+
+AC_ARG_WITH(rubyarchhdrdir,
+ AS_HELP_STRING([--with-rubyarchhdrdir=DIR],
+ [architecture dependent core headers in DIR [[$(rubyhdrdir)/$(arch)]]]),
+ [rubyarchhdrdir=$withval],
+ [rubyarchhdrdir=${multiarch+'${archincludedir}/${RUBY_VERSION_NAME}'}${multiarch-'${rubyhdrdir}/${arch}'}])
+
+AC_ARG_WITH(sitehdrdir,
+ AS_HELP_STRING([--with-sitehdrdir=DIR], [core site headers in DIR [[RUBYHDRDIR/site_ruby]]]),
+ [sitehdrdir=$withval],
+ [sitehdrdir='${rubyhdrdir}/site_ruby'])
+
+AC_ARG_WITH(sitearchhdrdir,
+ AS_HELP_STRING([--with-sitearchhdrdir=DIR],
+ [architecture dependent core site headers in DIR [[RUBYHDRDIR/site_ruby]]]),
+ [sitearchhdrdir=$withval],
+ [sitearchhdrdir=${multiarch+'${sitearchincludedir}/${RUBY_VERSION_NAME}/site_ruby'}${multiarch-'${sitehdrdir}/${sitearch}'}])
+
+AC_ARG_WITH(vendorhdrdir,
+ AS_HELP_STRING([--with-vendorhdrdir=DIR], [core vendor headers in DIR [[RUBYHDRDIR/vendor_ruby]]]),
+ [vendorhdrdir=$withval],
+ [vendorhdrdir='${rubyhdrdir}/vendor_ruby'])
+
+AC_ARG_WITH(vendorarchhdrdir,
+ AS_HELP_STRING([--with-vendorarchhdrdir=DIR],
+ [architecture dependent core vendor headers in DIR [[RUBYHDRDIR/vendor_ruby]]]),
+ [vendorarchhdrdir=$withval],
+ [vendorarchhdrdir=${multiarch+'${sitearchincludedir}/${RUBY_VERSION_NAME}/vendor_ruby'}${multiarch-'${vendorhdrdir}/${sitearch}'}])
+
+AC_SUBST(rubyhdrdir)dnl
+AC_SUBST(sitehdrdir)dnl
+AC_SUBST(vendorhdrdir)dnl
+AC_SUBST(rubyarchhdrdir)dnl
+AC_SUBST(sitearchhdrdir)dnl
+AC_SUBST(vendorarchhdrdir)dnl
+
+AC_ARG_WITH(mantype,
+ AS_HELP_STRING([--with-mantype=TYPE], [specify man page type; TYPE is one of man and doc]),
+ [
+ AS_CASE(["$withval"],
+ [man|man.gz|man.bz2|doc|doc.gz|doc.bz2], [MANTYPE=$withval],
+ [AC_MSG_ERROR(invalid man type: $withval)])
+ ])
+AS_IF([test -z "$MANTYPE"], [
+ dnl Looks for nroff with -mdoc support.
+ AC_CACHE_VAL([ac_cv_path_NROFF], [
+ AC_PATH_PROGS_FEATURE_CHECK([NROFF],
+ [nroff awf mandoc],
+ [$ac_path_NROFF -mdoc ${srcdir}/man/ruby.1 \
+ >/dev/null 2>&1 &&
+ ac_cv_path_NROFF=$ac_path_NROFF \
+ ac_path_NROFF_found=:],
+ [], ["/usr/bin:/usr/ucb"]
+ )
+ ])
+ AS_IF([test -n "$ac_cv_path_NROFF"], [
+ MANTYPE=doc
+ ], [
+ MANTYPE=man
+ ])
+])
+AC_SUBST(MANTYPE)
+
+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=YES
+])
+AC_SUBST(USE_RUBYGEMS)
+
+arch_hdrdir="${EXTOUT}/include/${arch}/ruby"
+AS_MKDIR_P("${arch_hdrdir}")
+config_h="${arch_hdrdir}/config.h"
+guard=INCLUDE_RUBY_CONFIG_H
+{
+ echo "#ifndef $guard"
+ echo "#define $guard 1"
+ grep -v "^#define PACKAGE_" confdefs.h
+ echo "#endif /* $guard */"
+} | 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}])
+tr -d '\015' < largefile.h > confdefs.h
+rm largefile.h
+
+BUILTIN_ENCS=["`sed -n -e '/^BUILTIN_ENCS[ ]*=/{' \
+ -e s/// -e :l -e '/\\\\$/N' -e 's/\\\\\\n/ /' -e 't l' -e p \
+ -e '}' "${srcdir}/enc/Makefile.in"`"]
+BUILTIN_ENCOBJS=
+for e in $BUILTIN_ENCS; do BUILTIN_ENCOBJS="$BUILTIN_ENCOBJS "`echo $e | sed 's/\.c$/.$(OBJEXT)/'`; done
+AC_SUBST(BUILTIN_ENCOBJS)
+
+BUILTIN_TRANSES=["`sed -n -e '/^BUILTIN_TRANSES[ ]*=/{' \
+ -e s/// -e :l -e '/\\\\$/N' -e 's/\\\\\\n/ /' -e 't l' -e p \
+ -e '}' "${srcdir}/enc/Makefile.in"`"]
+BUILTIN_TRANSSRCS=
+BUILTIN_TRANSOBJS=
+for e in $BUILTIN_TRANSES; do
+ BUILTIN_TRANSSRCS="$BUILTIN_TRANSSRCS "`echo $e | sed 's/\.trans$/.c/'`
+ BUILTIN_TRANSOBJS="$BUILTIN_TRANSOBJS "`echo $e | sed 's/\.trans$/.$(OBJEXT)/'`
+done
+AC_SUBST(BUILTIN_TRANSSRCS)
+AC_SUBST(BUILTIN_TRANSOBJS)
+
+PACKAGE=$RUBY_BASE_NAME
+AC_SUBST(PACKAGE)
+AS_MESSAGE([$PACKAGE library version = $ruby_version])
+
+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, [
+ 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='echo cannot'
+ ])
+ AS_CASE("$VCS",
+ [svn], [VCSUP='$(VCS) up $(SVNUPOPTIONS)'],
+ ['$(GIT) svn'], [VCSUP='$(VCS) rebase $(GITSVNREBASEOPTIONS)'],
+ ['$(GIT)'|git], [VCSUP='$(VCS) pull $(GITPULLOPTIONS)'],
+ [VCSUP='$(VCS)'])
+ sed -n \
+ -e '[/^@%:@define \(RUBY_RELEASE_[A-Z]*\) \([0-9][0-9]*\)/]{' \
+ -e 's//\1 = \2/' \
+ -e '[s/ \([0-9]\)$/ 0\1/]' \
+ -e p \
+ -e '}' "$srcdir/version.h"
+ sed '/^MISSING/s/\$U\././g;/^VCS *=/s#@VCS@#'"$VCS"'#;/^VCSUP *=/s#@VCSUP@#'"$VCSUP"'#' Makefile
+ echo; test x"$EXEEXT" = x || echo 'miniruby: miniruby$(EXEEXT)'
+ AS_IF([test "$gnumake" != yes], [
+ echo ['$(MKFILES): $(srcdir)/common.mk']
+ sed ['s/{\$([^(){}]*)[^{}]*}//g'] ${srcdir}/common.mk
+ ], [
+ echo 'distclean-local::; @$(RM) GNUmakefile uncommon.mk'
+ ])
+ } > $tmpmk && AS_IF([! grep '^ruby:' $tmpmk > /dev/null], [
+ AS_IF([test "${gnumake}" = yes], [
+ tmpgmk=confgmk$$.tmp
+ {
+ echo "include $tmpmk"
+ echo "-include uncommon.mk"
+ } > $tmpgmk
+ ], [
+ tmpgmk=$tmpmk
+ ]) &&
+ test -z "`${MAKE-make} -f $tmpgmk info-program | grep '^PROGRAM=ruby$'`" &&
+ echo 'ruby: $(PROGRAM);' >> $tmpmk
+ test "$tmpmk" = "$tmpgmk" || rm -f "$tmpgmk"
+ ]) && mv -f $tmpmk Makefile],
+[EXEEXT='$EXEEXT' gnumake='$gnumake' GIT='$GIT'])
+
+AC_ARG_WITH([ruby-pc],
+ AC_HELP_STRING([--with-ruby-pc=FILENAME], [pc file basename]),
+ [ruby_pc="$withval"],
+ [ruby_pc="${RUBY_BASE_NAME}-${MAJOR}.${MINOR}.pc"])
+AC_SUBST(ruby_pc)
+AC_SUBST(exec, [exec])
+
+AC_ARG_WITH(destdir,
+ AS_HELP_STRING([--with-destdir=DESTDIR], [specify default directory to install]),
+ [DESTDIR="$withval"])
+AC_SUBST(DESTDIR)
+
+AC_CONFIG_FILES($ruby_pc:template/ruby.pc.in,
+ [
+ AS_IF([sed ['s/\$(\([A-Za-z_][A-Za-z0-9_]*\))/${\1}/g;s/@[A-Za-z_][A-Za-z0-9_]*@//'] $ruby_pc > ruby.tmp.pc &&
+ {
+ test -z "$PKG_CONFIG" ||
+ PKG_CONFIG_PATH=. $PKG_CONFIG --print-errors ruby.tmp
+ }],
+ [
+ mv -f ruby.tmp.pc $ruby_pc
+ ], [
+ exit 1
+ ])
+ ],
+ [ruby_pc='$ruby_pc' PKG_CONFIG='$PKG_CONFIG'])
+
+AC_OUTPUT
+}
+}
+
+AS_IF([${FOLD+:} false], [], [
+AS_IF([test "`echo abcdefg hijklmno | fold -s -w10 | sed 1d`" = hijklmno], [FOLD="fold"], [FOLD=])
+])
+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 |
+ sed '1!s/^/ /;$!s/$/\\/'
+ ], [echo "$2"])
+ ])]
+)
+
+echo "---"
+echo "Configuration summary for $RUBY_BASE_NAME version $RUBY_PROGRAM_VERSION"
+echo ""
+config_summary "Installation prefix" "$prefix"
+config_summary "exec prefix" "$exec_prefix"
+config_summary "arch" "$arch"
+config_summary "site arch" "$sitearch"
+config_summary "RUBY_BASE_NAME" "$RUBY_BASE_NAME"
+config_summary "enable shared" "$enable_shared"
+config_summary "ruby lib prefix" "$rubylibprefix"
+config_summary "site libraries path" "$rubysitearchprefix"
+config_summary "vendor path" "$vendordir"
+config_summary "target OS" "$target_os"
+config_summary "compiler" "$CC"
+config_summary "with pthread" "$enable_pthread"
+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 "optflags" "$optflags"
+config_summary "debugflags" "$debugflags"
+config_summary "warnflags" "$warnflags"
+config_summary "strip command" "$STRIP"
+config_summary "install doc" "$install_doc"
+config_summary "man page type" "$MANTYPE"
+config_summary "search path" "$search_path"
+config_summary "static-linked-ext" ${EXTSTATIC:+"yes"}
+echo ""
+echo "---"
diff --git a/configure.bat b/configure.bat
deleted file mode 100644