diff options
Diffstat (limited to 'ext')
574 files changed, 36714 insertions, 105183 deletions
diff --git a/ext/-test-/RUBY_ALIGNOF/depend b/ext/-test-/RUBY_ALIGNOF/depend index 14dac0974c..103d20b33c 100644 --- a/ext/-test-/RUBY_ALIGNOF/depend +++ b/ext/-test-/RUBY_ALIGNOF/depend @@ -7,7 +7,6 @@ c.o: $(hdrdir)/ruby/backward.h c.o: $(hdrdir)/ruby/backward/2/assume.h c.o: $(hdrdir)/ruby/backward/2/attributes.h c.o: $(hdrdir)/ruby/backward/2/bool.h -c.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h c.o: $(hdrdir)/ruby/backward/2/inttypes.h c.o: $(hdrdir)/ruby/backward/2/limits.h c.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ c.o: $(hdrdir)/ruby/backward/2/stdalign.h c.o: $(hdrdir)/ruby/backward/2/stdarg.h c.o: $(hdrdir)/ruby/defines.h c.o: $(hdrdir)/ruby/intern.h +c.o: $(hdrdir)/ruby/internal/abi.h c.o: $(hdrdir)/ruby/internal/anyargs.h c.o: $(hdrdir)/ruby/internal/arithmetic.h c.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ c.o: $(hdrdir)/ruby/internal/attr/noexcept.h c.o: $(hdrdir)/ruby/internal/attr/noinline.h c.o: $(hdrdir)/ruby/internal/attr/nonnull.h c.o: $(hdrdir)/ruby/internal/attr/noreturn.h +c.o: $(hdrdir)/ruby/internal/attr/packed_struct.h c.o: $(hdrdir)/ruby/internal/attr/pure.h c.o: $(hdrdir)/ruby/internal/attr/restrict.h c.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -111,7 +112,6 @@ c.o: $(hdrdir)/ruby/internal/intern/enumerator.h c.o: $(hdrdir)/ruby/internal/intern/error.h c.o: $(hdrdir)/ruby/internal/intern/eval.h c.o: $(hdrdir)/ruby/internal/intern/file.h -c.o: $(hdrdir)/ruby/internal/intern/gc.h c.o: $(hdrdir)/ruby/internal/intern/hash.h c.o: $(hdrdir)/ruby/internal/intern/io.h c.o: $(hdrdir)/ruby/internal/intern/load.h @@ -128,6 +128,7 @@ c.o: $(hdrdir)/ruby/internal/intern/re.h c.o: $(hdrdir)/ruby/internal/intern/ruby.h c.o: $(hdrdir)/ruby/internal/intern/select.h c.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +c.o: $(hdrdir)/ruby/internal/intern/set.h c.o: $(hdrdir)/ruby/internal/intern/signal.h c.o: $(hdrdir)/ruby/internal/intern/sprintf.h c.o: $(hdrdir)/ruby/internal/intern/string.h @@ -142,12 +143,12 @@ c.o: $(hdrdir)/ruby/internal/memory.h c.o: $(hdrdir)/ruby/internal/method.h c.o: $(hdrdir)/ruby/internal/module.h c.o: $(hdrdir)/ruby/internal/newobj.h -c.o: $(hdrdir)/ruby/internal/rgengc.h c.o: $(hdrdir)/ruby/internal/scan_args.h c.o: $(hdrdir)/ruby/internal/special_consts.h c.o: $(hdrdir)/ruby/internal/static_assert.h c.o: $(hdrdir)/ruby/internal/stdalign.h c.o: $(hdrdir)/ruby/internal/stdbool.h +c.o: $(hdrdir)/ruby/internal/stdckdint.h c.o: $(hdrdir)/ruby/internal/symbol.h c.o: $(hdrdir)/ruby/internal/value.h c.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/abi/abi.c b/ext/-test-/abi/abi.c new file mode 100644 index 0000000000..923e0f67b8 --- /dev/null +++ b/ext/-test-/abi/abi.c @@ -0,0 +1,11 @@ +#include <limits.h> + +unsigned long long +ruby_abi_version(void) +{ + return ULONG_MAX; +} + +void +Init_abi(void) +{} diff --git a/ext/readline/depend-gem b/ext/-test-/abi/depend index df01bd2a86..716a7b1356 100644 --- a/ext/readline/depend-gem +++ b/ext/-test-/abi/depend @@ -1,4 +1,3 @@ # AUTOGENERATED DEPENDENCIES START -readline.o: $(RUBY_EXTCONF_H) -readline.o: readline.c +abi.o: abi.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/abi/extconf.rb b/ext/-test-/abi/extconf.rb new file mode 100644 index 0000000000..3b090b7553 --- /dev/null +++ b/ext/-test-/abi/extconf.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: false +return unless RUBY_PATCHLEVEL < 0 +require_relative "../auto_ext.rb" +auto_ext(inc: true) diff --git a/ext/-test-/arith_seq/beg_len_step/beg_len_step.c b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c new file mode 100644 index 0000000000..40c8cbee82 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c @@ -0,0 +1,19 @@ +#include "ruby/ruby.h" + +static VALUE +arith_seq_s_beg_len_step(VALUE mod, VALUE obj, VALUE len, VALUE err) +{ + VALUE r; + long beg, len2, step; + + r = rb_arithmetic_sequence_beg_len_step(obj, &beg, &len2, &step, NUM2LONG(len), NUM2INT(err)); + + return rb_ary_new_from_args(4, r, LONG2NUM(beg), LONG2NUM(len2), LONG2NUM(step)); +} + +void +Init_beg_len_step(void) +{ + VALUE cArithSeq = rb_path2class("Enumerator::ArithmeticSequence"); + rb_define_singleton_method(cArithSeq, "__beg_len_step__", arith_seq_s_beg_len_step, 3); +} diff --git a/ext/-test-/arith_seq/beg_len_step/depend b/ext/-test-/arith_seq/beg_len_step/depend new file mode 100644 index 0000000000..098c8ff1f0 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/depend @@ -0,0 +1,162 @@ +# AUTOGENERATED DEPENDENCIES START +beg_len_step.o: $(RUBY_EXTCONF_H) +beg_len_step.o: $(arch_hdrdir)/ruby/config.h +beg_len_step.o: $(hdrdir)/ruby/assert.h +beg_len_step.o: $(hdrdir)/ruby/backward.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/assume.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/attributes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/bool.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/inttypes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/limits.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/long_long.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdarg.h +beg_len_step.o: $(hdrdir)/ruby/defines.h +beg_len_step.o: $(hdrdir)/ruby/intern.h +beg_len_step.o: $(hdrdir)/ruby/internal/abi.h +beg_len_step.o: $(hdrdir)/ruby/internal/anyargs.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/char.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/double.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/int.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/short.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/assume.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/artificial.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/cold.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/const.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/constexpr.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/deprecated.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/forceinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/format.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noalias.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noexcept.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noreturn.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/pure.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/restrict.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/weakref.h +beg_len_step.o: $(hdrdir)/ruby/internal/cast.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_since.h +beg_len_step.o: $(hdrdir)/ruby/internal/config.h +beg_len_step.o: $(hdrdir)/ruby/internal/constant_p.h +beg_len_step.o: $(hdrdir)/ruby/internal/core.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rarray.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbasic.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rclass.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rdata.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rfile.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rhash.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/robject.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rregexp.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstring.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstruct.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +beg_len_step.o: $(hdrdir)/ruby/internal/ctype.h +beg_len_step.o: $(hdrdir)/ruby/internal/dllexport.h +beg_len_step.o: $(hdrdir)/ruby/internal/dosish.h +beg_len_step.o: $(hdrdir)/ruby/internal/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/event.h +beg_len_step.o: $(hdrdir)/ruby/internal/fl_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/gc.h +beg_len_step.o: $(hdrdir)/ruby/internal/glob.h +beg_len_step.o: $(hdrdir)/ruby/internal/globals.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/builtin.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/c_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/extension.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/feature.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/array.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/bignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/class.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/compar.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/complex.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/cont.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/dir.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enumerator.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/file.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/hash.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/io.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/load.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/marshal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/numeric.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/object.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/parse.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/proc.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/process.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/random.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/range.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/rational.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/re.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/ruby.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/set.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/signal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/sprintf.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/string.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/struct.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/thread.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/time.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/vm.h +beg_len_step.o: $(hdrdir)/ruby/internal/interpreter.h +beg_len_step.o: $(hdrdir)/ruby/internal/iterator.h +beg_len_step.o: $(hdrdir)/ruby/internal/memory.h +beg_len_step.o: $(hdrdir)/ruby/internal/method.h +beg_len_step.o: $(hdrdir)/ruby/internal/module.h +beg_len_step.o: $(hdrdir)/ruby/internal/newobj.h +beg_len_step.o: $(hdrdir)/ruby/internal/scan_args.h +beg_len_step.o: $(hdrdir)/ruby/internal/special_consts.h +beg_len_step.o: $(hdrdir)/ruby/internal/static_assert.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdbool.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdckdint.h +beg_len_step.o: $(hdrdir)/ruby/internal/symbol.h +beg_len_step.o: $(hdrdir)/ruby/internal/value.h +beg_len_step.o: $(hdrdir)/ruby/internal/value_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/warning_push.h +beg_len_step.o: $(hdrdir)/ruby/internal/xmalloc.h +beg_len_step.o: $(hdrdir)/ruby/missing.h +beg_len_step.o: $(hdrdir)/ruby/ruby.h +beg_len_step.o: $(hdrdir)/ruby/st.h +beg_len_step.o: $(hdrdir)/ruby/subst.h +beg_len_step.o: beg_len_step.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/arith_seq/beg_len_step/extconf.rb b/ext/-test-/arith_seq/beg_len_step/extconf.rb new file mode 100644 index 0000000000..e72b3ad01f --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/arith_seq/beg_len_step") diff --git a/ext/-test-/arith_seq/extract/depend b/ext/-test-/arith_seq/extract/depend index 8bf12c5f47..5c07cea4b4 100644 --- a/ext/-test-/arith_seq/extract/depend +++ b/ext/-test-/arith_seq/extract/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START extract.o: $(RUBY_EXTCONF_H) extract.o: $(arch_hdrdir)/ruby/config.h +extract.o: $(hdrdir)/ruby/assert.h +extract.o: $(hdrdir)/ruby/backward.h +extract.o: $(hdrdir)/ruby/backward/2/assume.h +extract.o: $(hdrdir)/ruby/backward/2/attributes.h +extract.o: $(hdrdir)/ruby/backward/2/bool.h +extract.o: $(hdrdir)/ruby/backward/2/inttypes.h +extract.o: $(hdrdir)/ruby/backward/2/limits.h +extract.o: $(hdrdir)/ruby/backward/2/long_long.h +extract.o: $(hdrdir)/ruby/backward/2/stdalign.h +extract.o: $(hdrdir)/ruby/backward/2/stdarg.h +extract.o: $(hdrdir)/ruby/defines.h +extract.o: $(hdrdir)/ruby/intern.h +extract.o: $(hdrdir)/ruby/internal/abi.h extract.o: $(hdrdir)/ruby/internal/anyargs.h extract.o: $(hdrdir)/ruby/internal/arithmetic.h extract.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ extract.o: $(hdrdir)/ruby/internal/attr/noexcept.h extract.o: $(hdrdir)/ruby/internal/attr/noinline.h extract.o: $(hdrdir)/ruby/internal/attr/nonnull.h extract.o: $(hdrdir)/ruby/internal/attr/noreturn.h +extract.o: $(hdrdir)/ruby/internal/attr/packed_struct.h extract.o: $(hdrdir)/ruby/internal/attr/pure.h extract.o: $(hdrdir)/ruby/internal/attr/restrict.h extract.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ extract.o: $(hdrdir)/ruby/internal/intern/enumerator.h extract.o: $(hdrdir)/ruby/internal/intern/error.h extract.o: $(hdrdir)/ruby/internal/intern/eval.h extract.o: $(hdrdir)/ruby/internal/intern/file.h -extract.o: $(hdrdir)/ruby/internal/intern/gc.h extract.o: $(hdrdir)/ruby/internal/intern/hash.h extract.o: $(hdrdir)/ruby/internal/intern/io.h extract.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ extract.o: $(hdrdir)/ruby/internal/intern/re.h extract.o: $(hdrdir)/ruby/internal/intern/ruby.h extract.o: $(hdrdir)/ruby/internal/intern/select.h extract.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +extract.o: $(hdrdir)/ruby/internal/intern/set.h extract.o: $(hdrdir)/ruby/internal/intern/signal.h extract.o: $(hdrdir)/ruby/internal/intern/sprintf.h extract.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ extract.o: $(hdrdir)/ruby/internal/memory.h extract.o: $(hdrdir)/ruby/internal/method.h extract.o: $(hdrdir)/ruby/internal/module.h extract.o: $(hdrdir)/ruby/internal/newobj.h -extract.o: $(hdrdir)/ruby/internal/rgengc.h extract.o: $(hdrdir)/ruby/internal/scan_args.h extract.o: $(hdrdir)/ruby/internal/special_consts.h extract.o: $(hdrdir)/ruby/internal/static_assert.h extract.o: $(hdrdir)/ruby/internal/stdalign.h extract.o: $(hdrdir)/ruby/internal/stdbool.h +extract.o: $(hdrdir)/ruby/internal/stdckdint.h extract.o: $(hdrdir)/ruby/internal/symbol.h extract.o: $(hdrdir)/ruby/internal/value.h extract.o: $(hdrdir)/ruby/internal/value_type.h extract.o: $(hdrdir)/ruby/internal/variable.h extract.o: $(hdrdir)/ruby/internal/warning_push.h extract.o: $(hdrdir)/ruby/internal/xmalloc.h -extract.o: $(hdrdir)/ruby/assert.h -extract.o: $(hdrdir)/ruby/backward.h -extract.o: $(hdrdir)/ruby/backward/2/assume.h -extract.o: $(hdrdir)/ruby/backward/2/attributes.h -extract.o: $(hdrdir)/ruby/backward/2/bool.h -extract.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -extract.o: $(hdrdir)/ruby/backward/2/inttypes.h -extract.o: $(hdrdir)/ruby/backward/2/limits.h -extract.o: $(hdrdir)/ruby/backward/2/long_long.h -extract.o: $(hdrdir)/ruby/backward/2/stdalign.h -extract.o: $(hdrdir)/ruby/backward/2/stdarg.h -extract.o: $(hdrdir)/ruby/defines.h -extract.o: $(hdrdir)/ruby/intern.h extract.o: $(hdrdir)/ruby/missing.h extract.o: $(hdrdir)/ruby/ruby.h extract.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/array/concat/depend b/ext/-test-/array/concat/depend index ba069376a4..8edf45465f 100644 --- a/ext/-test-/array/concat/depend +++ b/ext/-test-/array/concat/depend @@ -1,321 +1,163 @@ # AUTOGENERATED DEPENDENCIES START -resize.o: $(RUBY_EXTCONF_H) -resize.o: $(arch_hdrdir)/ruby/config.h -resize.o: $(hdrdir)/ruby/assert.h -resize.o: $(hdrdir)/ruby/backward.h -resize.o: $(hdrdir)/ruby/backward/2/assume.h -resize.o: $(hdrdir)/ruby/backward/2/attributes.h -resize.o: $(hdrdir)/ruby/backward/2/bool.h -resize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -resize.o: $(hdrdir)/ruby/backward/2/inttypes.h -resize.o: $(hdrdir)/ruby/backward/2/limits.h -resize.o: $(hdrdir)/ruby/backward/2/long_long.h -resize.o: $(hdrdir)/ruby/backward/2/stdalign.h -resize.o: $(hdrdir)/ruby/backward/2/stdarg.h -resize.o: $(hdrdir)/ruby/defines.h -resize.o: $(hdrdir)/ruby/intern.h -resize.o: $(hdrdir)/ruby/internal/anyargs.h -resize.o: $(hdrdir)/ruby/internal/arithmetic.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/char.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/double.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/int.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/long.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/short.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -resize.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -resize.o: $(hdrdir)/ruby/internal/assume.h -resize.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -resize.o: $(hdrdir)/ruby/internal/attr/artificial.h -resize.o: $(hdrdir)/ruby/internal/attr/cold.h -resize.o: $(hdrdir)/ruby/internal/attr/const.h -resize.o: $(hdrdir)/ruby/internal/attr/constexpr.h -resize.o: $(hdrdir)/ruby/internal/attr/deprecated.h -resize.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -resize.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -resize.o: $(hdrdir)/ruby/internal/attr/error.h -resize.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -resize.o: $(hdrdir)/ruby/internal/attr/forceinline.h -resize.o: $(hdrdir)/ruby/internal/attr/format.h -resize.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -resize.o: $(hdrdir)/ruby/internal/attr/noalias.h -resize.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -resize.o: $(hdrdir)/ruby/internal/attr/noexcept.h -resize.o: $(hdrdir)/ruby/internal/attr/noinline.h -resize.o: $(hdrdir)/ruby/internal/attr/nonnull.h -resize.o: $(hdrdir)/ruby/internal/attr/noreturn.h -resize.o: $(hdrdir)/ruby/internal/attr/pure.h -resize.o: $(hdrdir)/ruby/internal/attr/restrict.h -resize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -resize.o: $(hdrdir)/ruby/internal/attr/warning.h -resize.o: $(hdrdir)/ruby/internal/attr/weakref.h -resize.o: $(hdrdir)/ruby/internal/cast.h -resize.o: $(hdrdir)/ruby/internal/compiler_is.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -resize.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -resize.o: $(hdrdir)/ruby/internal/compiler_since.h -resize.o: $(hdrdir)/ruby/internal/config.h -resize.o: $(hdrdir)/ruby/internal/constant_p.h -resize.o: $(hdrdir)/ruby/internal/core.h -resize.o: $(hdrdir)/ruby/internal/core/rarray.h -resize.o: $(hdrdir)/ruby/internal/core/rbasic.h -resize.o: $(hdrdir)/ruby/internal/core/rbignum.h -resize.o: $(hdrdir)/ruby/internal/core/rclass.h -resize.o: $(hdrdir)/ruby/internal/core/rdata.h -resize.o: $(hdrdir)/ruby/internal/core/rfile.h -resize.o: $(hdrdir)/ruby/internal/core/rhash.h -resize.o: $(hdrdir)/ruby/internal/core/robject.h -resize.o: $(hdrdir)/ruby/internal/core/rregexp.h -resize.o: $(hdrdir)/ruby/internal/core/rstring.h -resize.o: $(hdrdir)/ruby/internal/core/rstruct.h -resize.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -resize.o: $(hdrdir)/ruby/internal/ctype.h -resize.o: $(hdrdir)/ruby/internal/dllexport.h -resize.o: $(hdrdir)/ruby/internal/dosish.h -resize.o: $(hdrdir)/ruby/internal/error.h -resize.o: $(hdrdir)/ruby/internal/eval.h -resize.o: $(hdrdir)/ruby/internal/event.h -resize.o: $(hdrdir)/ruby/internal/fl_type.h -resize.o: $(hdrdir)/ruby/internal/gc.h -resize.o: $(hdrdir)/ruby/internal/glob.h -resize.o: $(hdrdir)/ruby/internal/globals.h -resize.o: $(hdrdir)/ruby/internal/has/attribute.h -resize.o: $(hdrdir)/ruby/internal/has/builtin.h -resize.o: $(hdrdir)/ruby/internal/has/c_attribute.h -resize.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -resize.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -resize.o: $(hdrdir)/ruby/internal/has/extension.h -resize.o: $(hdrdir)/ruby/internal/has/feature.h -resize.o: $(hdrdir)/ruby/internal/has/warning.h -resize.o: $(hdrdir)/ruby/internal/intern/array.h -resize.o: $(hdrdir)/ruby/internal/intern/bignum.h -resize.o: $(hdrdir)/ruby/internal/intern/class.h -resize.o: $(hdrdir)/ruby/internal/intern/compar.h -resize.o: $(hdrdir)/ruby/internal/intern/complex.h -resize.o: $(hdrdir)/ruby/internal/intern/cont.h -resize.o: $(hdrdir)/ruby/internal/intern/dir.h -resize.o: $(hdrdir)/ruby/internal/intern/enum.h -resize.o: $(hdrdir)/ruby/internal/intern/enumerator.h -resize.o: $(hdrdir)/ruby/internal/intern/error.h -resize.o: $(hdrdir)/ruby/internal/intern/eval.h -resize.o: $(hdrdir)/ruby/internal/intern/file.h -resize.o: $(hdrdir)/ruby/internal/intern/gc.h -resize.o: $(hdrdir)/ruby/internal/intern/hash.h -resize.o: $(hdrdir)/ruby/internal/intern/io.h -resize.o: $(hdrdir)/ruby/internal/intern/load.h -resize.o: $(hdrdir)/ruby/internal/intern/marshal.h -resize.o: $(hdrdir)/ruby/internal/intern/numeric.h -resize.o: $(hdrdir)/ruby/internal/intern/object.h -resize.o: $(hdrdir)/ruby/internal/intern/parse.h -resize.o: $(hdrdir)/ruby/internal/intern/proc.h -resize.o: $(hdrdir)/ruby/internal/intern/process.h -resize.o: $(hdrdir)/ruby/internal/intern/random.h -resize.o: $(hdrdir)/ruby/internal/intern/range.h -resize.o: $(hdrdir)/ruby/internal/intern/rational.h -resize.o: $(hdrdir)/ruby/internal/intern/re.h -resize.o: $(hdrdir)/ruby/internal/intern/ruby.h -resize.o: $(hdrdir)/ruby/internal/intern/select.h -resize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -resize.o: $(hdrdir)/ruby/internal/intern/signal.h -resize.o: $(hdrdir)/ruby/internal/intern/sprintf.h -resize.o: $(hdrdir)/ruby/internal/intern/string.h -resize.o: $(hdrdir)/ruby/internal/intern/struct.h -resize.o: $(hdrdir)/ruby/internal/intern/thread.h -resize.o: $(hdrdir)/ruby/internal/intern/time.h -resize.o: $(hdrdir)/ruby/internal/intern/variable.h -resize.o: $(hdrdir)/ruby/internal/intern/vm.h -resize.o: $(hdrdir)/ruby/internal/interpreter.h -resize.o: $(hdrdir)/ruby/internal/iterator.h -resize.o: $(hdrdir)/ruby/internal/memory.h -resize.o: $(hdrdir)/ruby/internal/method.h -resize.o: $(hdrdir)/ruby/internal/module.h -resize.o: $(hdrdir)/ruby/internal/newobj.h -resize.o: $(hdrdir)/ruby/internal/rgengc.h -resize.o: $(hdrdir)/ruby/internal/scan_args.h -resize.o: $(hdrdir)/ruby/internal/special_consts.h -resize.o: $(hdrdir)/ruby/internal/static_assert.h -resize.o: $(hdrdir)/ruby/internal/stdalign.h -resize.o: $(hdrdir)/ruby/internal/stdbool.h -resize.o: $(hdrdir)/ruby/internal/symbol.h -resize.o: $(hdrdir)/ruby/internal/value.h -resize.o: $(hdrdir)/ruby/internal/value_type.h -resize.o: $(hdrdir)/ruby/internal/variable.h -resize.o: $(hdrdir)/ruby/internal/warning_push.h -resize.o: $(hdrdir)/ruby/internal/xmalloc.h -resize.o: $(hdrdir)/ruby/missing.h -resize.o: $(hdrdir)/ruby/ruby.h -resize.o: $(hdrdir)/ruby/st.h -resize.o: $(hdrdir)/ruby/subst.h -resize.o: resize.c -to_ary_conact.o: $(RUBY_EXTCONF_H) -to_ary_conact.o: $(arch_hdrdir)/ruby/config.h -to_ary_conact.o: $(hdrdir)/ruby.h -to_ary_conact.o: $(hdrdir)/ruby/assert.h -to_ary_conact.o: $(hdrdir)/ruby/backward.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/assume.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/attributes.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/bool.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/inttypes.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/limits.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/long_long.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/stdalign.h -to_ary_conact.o: $(hdrdir)/ruby/backward/2/stdarg.h -to_ary_conact.o: $(hdrdir)/ruby/defines.h -to_ary_conact.o: $(hdrdir)/ruby/intern.h -to_ary_conact.o: $(hdrdir)/ruby/internal/anyargs.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/char.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/double.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/int.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/long.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/short.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -to_ary_conact.o: $(hdrdir)/ruby/internal/assume.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/artificial.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/cold.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/const.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/constexpr.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/deprecated.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/error.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/forceinline.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/format.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noalias.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noexcept.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noinline.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/nonnull.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/noreturn.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/pure.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/restrict.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/warning.h -to_ary_conact.o: $(hdrdir)/ruby/internal/attr/weakref.h -to_ary_conact.o: $(hdrdir)/ruby/internal/cast.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -to_ary_conact.o: $(hdrdir)/ruby/internal/compiler_since.h -to_ary_conact.o: $(hdrdir)/ruby/internal/config.h -to_ary_conact.o: $(hdrdir)/ruby/internal/constant_p.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rarray.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rbasic.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rbignum.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rclass.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rdata.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rfile.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rhash.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/robject.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rregexp.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rstring.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rstruct.h -to_ary_conact.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -to_ary_conact.o: $(hdrdir)/ruby/internal/ctype.h -to_ary_conact.o: $(hdrdir)/ruby/internal/dllexport.h -to_ary_conact.o: $(hdrdir)/ruby/internal/dosish.h -to_ary_conact.o: $(hdrdir)/ruby/internal/error.h -to_ary_conact.o: $(hdrdir)/ruby/internal/eval.h -to_ary_conact.o: $(hdrdir)/ruby/internal/event.h -to_ary_conact.o: $(hdrdir)/ruby/internal/fl_type.h -to_ary_conact.o: $(hdrdir)/ruby/internal/gc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/glob.h -to_ary_conact.o: $(hdrdir)/ruby/internal/globals.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/attribute.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/builtin.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/c_attribute.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/extension.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/feature.h -to_ary_conact.o: $(hdrdir)/ruby/internal/has/warning.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/array.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/bignum.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/class.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/compar.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/complex.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/cont.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/dir.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/enum.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/enumerator.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/error.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/eval.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/file.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/gc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/hash.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/io.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/load.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/marshal.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/numeric.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/object.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/parse.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/proc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/process.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/random.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/range.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/rational.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/re.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/ruby.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/select.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/signal.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/sprintf.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/string.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/struct.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/thread.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/time.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/variable.h -to_ary_conact.o: $(hdrdir)/ruby/internal/intern/vm.h -to_ary_conact.o: $(hdrdir)/ruby/internal/interpreter.h -to_ary_conact.o: $(hdrdir)/ruby/internal/iterator.h -to_ary_conact.o: $(hdrdir)/ruby/internal/memory.h -to_ary_conact.o: $(hdrdir)/ruby/internal/method.h -to_ary_conact.o: $(hdrdir)/ruby/internal/module.h -to_ary_conact.o: $(hdrdir)/ruby/internal/newobj.h -to_ary_conact.o: $(hdrdir)/ruby/internal/rgengc.h -to_ary_conact.o: $(hdrdir)/ruby/internal/scan_args.h -to_ary_conact.o: $(hdrdir)/ruby/internal/special_consts.h -to_ary_conact.o: $(hdrdir)/ruby/internal/static_assert.h -to_ary_conact.o: $(hdrdir)/ruby/internal/stdalign.h -to_ary_conact.o: $(hdrdir)/ruby/internal/stdbool.h -to_ary_conact.o: $(hdrdir)/ruby/internal/symbol.h -to_ary_conact.o: $(hdrdir)/ruby/internal/value.h -to_ary_conact.o: $(hdrdir)/ruby/internal/value_type.h -to_ary_conact.o: $(hdrdir)/ruby/internal/variable.h -to_ary_conact.o: $(hdrdir)/ruby/internal/warning_push.h -to_ary_conact.o: $(hdrdir)/ruby/internal/xmalloc.h -to_ary_conact.o: $(hdrdir)/ruby/missing.h -to_ary_conact.o: $(hdrdir)/ruby/ruby.h -to_ary_conact.o: $(hdrdir)/ruby/st.h -to_ary_conact.o: $(hdrdir)/ruby/subst.h -to_ary_conact.o: to_ary_conact.c +to_ary_concat.o: $(RUBY_EXTCONF_H) +to_ary_concat.o: $(arch_hdrdir)/ruby/config.h +to_ary_concat.o: $(hdrdir)/ruby.h +to_ary_concat.o: $(hdrdir)/ruby/assert.h +to_ary_concat.o: $(hdrdir)/ruby/backward.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/assume.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/attributes.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/bool.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/inttypes.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/limits.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/long_long.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/stdalign.h +to_ary_concat.o: $(hdrdir)/ruby/backward/2/stdarg.h +to_ary_concat.o: $(hdrdir)/ruby/defines.h +to_ary_concat.o: $(hdrdir)/ruby/intern.h +to_ary_concat.o: $(hdrdir)/ruby/internal/abi.h +to_ary_concat.o: $(hdrdir)/ruby/internal/anyargs.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/char.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/double.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/int.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/long.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/short.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +to_ary_concat.o: $(hdrdir)/ruby/internal/assume.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/artificial.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/cold.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/const.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/constexpr.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/deprecated.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/error.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/forceinline.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/format.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noalias.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noexcept.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noinline.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/nonnull.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/noreturn.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/pure.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/restrict.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/warning.h +to_ary_concat.o: $(hdrdir)/ruby/internal/attr/weakref.h +to_ary_concat.o: $(hdrdir)/ruby/internal/cast.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +to_ary_concat.o: $(hdrdir)/ruby/internal/compiler_since.h +to_ary_concat.o: $(hdrdir)/ruby/internal/config.h +to_ary_concat.o: $(hdrdir)/ruby/internal/constant_p.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rarray.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rbasic.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rbignum.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rclass.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rdata.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rfile.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rhash.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/robject.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rregexp.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rstring.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rstruct.h +to_ary_concat.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +to_ary_concat.o: $(hdrdir)/ruby/internal/ctype.h +to_ary_concat.o: $(hdrdir)/ruby/internal/dllexport.h +to_ary_concat.o: $(hdrdir)/ruby/internal/dosish.h +to_ary_concat.o: $(hdrdir)/ruby/internal/error.h +to_ary_concat.o: $(hdrdir)/ruby/internal/eval.h +to_ary_concat.o: $(hdrdir)/ruby/internal/event.h +to_ary_concat.o: $(hdrdir)/ruby/internal/fl_type.h +to_ary_concat.o: $(hdrdir)/ruby/internal/gc.h +to_ary_concat.o: $(hdrdir)/ruby/internal/glob.h +to_ary_concat.o: $(hdrdir)/ruby/internal/globals.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/attribute.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/builtin.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/c_attribute.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/extension.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/feature.h +to_ary_concat.o: $(hdrdir)/ruby/internal/has/warning.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/array.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/bignum.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/class.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/compar.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/complex.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/cont.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/dir.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/enum.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/enumerator.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/error.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/eval.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/file.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/hash.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/io.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/load.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/marshal.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/numeric.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/object.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/parse.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/proc.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/process.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/random.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/range.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/rational.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/re.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/ruby.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/select.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/set.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/signal.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/sprintf.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/string.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/struct.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/thread.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/time.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/variable.h +to_ary_concat.o: $(hdrdir)/ruby/internal/intern/vm.h +to_ary_concat.o: $(hdrdir)/ruby/internal/interpreter.h +to_ary_concat.o: $(hdrdir)/ruby/internal/iterator.h +to_ary_concat.o: $(hdrdir)/ruby/internal/memory.h +to_ary_concat.o: $(hdrdir)/ruby/internal/method.h +to_ary_concat.o: $(hdrdir)/ruby/internal/module.h +to_ary_concat.o: $(hdrdir)/ruby/internal/newobj.h +to_ary_concat.o: $(hdrdir)/ruby/internal/scan_args.h +to_ary_concat.o: $(hdrdir)/ruby/internal/special_consts.h +to_ary_concat.o: $(hdrdir)/ruby/internal/static_assert.h +to_ary_concat.o: $(hdrdir)/ruby/internal/stdalign.h +to_ary_concat.o: $(hdrdir)/ruby/internal/stdbool.h +to_ary_concat.o: $(hdrdir)/ruby/internal/stdckdint.h +to_ary_concat.o: $(hdrdir)/ruby/internal/symbol.h +to_ary_concat.o: $(hdrdir)/ruby/internal/value.h +to_ary_concat.o: $(hdrdir)/ruby/internal/value_type.h +to_ary_concat.o: $(hdrdir)/ruby/internal/variable.h +to_ary_concat.o: $(hdrdir)/ruby/internal/warning_push.h +to_ary_concat.o: $(hdrdir)/ruby/internal/xmalloc.h +to_ary_concat.o: $(hdrdir)/ruby/missing.h +to_ary_concat.o: $(hdrdir)/ruby/ruby.h +to_ary_concat.o: $(hdrdir)/ruby/st.h +to_ary_concat.o: $(hdrdir)/ruby/subst.h +to_ary_concat.o: to_ary_concat.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/array/concat/to_ary_conact.c b/ext/-test-/array/concat/to_ary_concat.c index ec1fd321ce..07a96d3907 100644 --- a/ext/-test-/array/concat/to_ary_conact.c +++ b/ext/-test-/array/concat/to_ary_concat.c @@ -17,7 +17,9 @@ Bar_alloc(VALUE klass) return TypedData_Wrap_Struct(klass, &Bar_type, NULL); } -VALUE Bar_to_ary(VALUE _self) { +static VALUE +Bar_to_ary(VALUE _self) +{ VALUE ary = rb_ary_new2(2); VALUE foo = rb_ary_new2(0); rb_ary_push(ary, foo); @@ -26,7 +28,9 @@ VALUE Bar_to_ary(VALUE _self) { return ary; } -void Init_to_ary_concat() { +void +Init_to_ary_concat(void) +{ VALUE mBug = rb_define_module("Bug"); VALUE bar = rb_define_class_under(mBug, "Bar", rb_cObject); rb_define_alloc_func(bar, Bar_alloc); diff --git a/ext/-test-/array/resize/depend b/ext/-test-/array/resize/depend index cf0c2320ae..e6a228b43d 100644 --- a/ext/-test-/array/resize/depend +++ b/ext/-test-/array/resize/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START resize.o: $(RUBY_EXTCONF_H) resize.o: $(arch_hdrdir)/ruby/config.h +resize.o: $(hdrdir)/ruby/assert.h +resize.o: $(hdrdir)/ruby/backward.h +resize.o: $(hdrdir)/ruby/backward/2/assume.h +resize.o: $(hdrdir)/ruby/backward/2/attributes.h +resize.o: $(hdrdir)/ruby/backward/2/bool.h +resize.o: $(hdrdir)/ruby/backward/2/inttypes.h +resize.o: $(hdrdir)/ruby/backward/2/limits.h +resize.o: $(hdrdir)/ruby/backward/2/long_long.h +resize.o: $(hdrdir)/ruby/backward/2/stdalign.h +resize.o: $(hdrdir)/ruby/backward/2/stdarg.h +resize.o: $(hdrdir)/ruby/defines.h +resize.o: $(hdrdir)/ruby/intern.h +resize.o: $(hdrdir)/ruby/internal/abi.h resize.o: $(hdrdir)/ruby/internal/anyargs.h resize.o: $(hdrdir)/ruby/internal/arithmetic.h resize.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ resize.o: $(hdrdir)/ruby/internal/attr/noexcept.h resize.o: $(hdrdir)/ruby/internal/attr/noinline.h resize.o: $(hdrdir)/ruby/internal/attr/nonnull.h resize.o: $(hdrdir)/ruby/internal/attr/noreturn.h +resize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h resize.o: $(hdrdir)/ruby/internal/attr/pure.h resize.o: $(hdrdir)/ruby/internal/attr/restrict.h resize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ resize.o: $(hdrdir)/ruby/internal/intern/enumerator.h resize.o: $(hdrdir)/ruby/internal/intern/error.h resize.o: $(hdrdir)/ruby/internal/intern/eval.h resize.o: $(hdrdir)/ruby/internal/intern/file.h -resize.o: $(hdrdir)/ruby/internal/intern/gc.h resize.o: $(hdrdir)/ruby/internal/intern/hash.h resize.o: $(hdrdir)/ruby/internal/intern/io.h resize.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ resize.o: $(hdrdir)/ruby/internal/intern/re.h resize.o: $(hdrdir)/ruby/internal/intern/ruby.h resize.o: $(hdrdir)/ruby/internal/intern/select.h resize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +resize.o: $(hdrdir)/ruby/internal/intern/set.h resize.o: $(hdrdir)/ruby/internal/intern/signal.h resize.o: $(hdrdir)/ruby/internal/intern/sprintf.h resize.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ resize.o: $(hdrdir)/ruby/internal/memory.h resize.o: $(hdrdir)/ruby/internal/method.h resize.o: $(hdrdir)/ruby/internal/module.h resize.o: $(hdrdir)/ruby/internal/newobj.h -resize.o: $(hdrdir)/ruby/internal/rgengc.h resize.o: $(hdrdir)/ruby/internal/scan_args.h resize.o: $(hdrdir)/ruby/internal/special_consts.h resize.o: $(hdrdir)/ruby/internal/static_assert.h resize.o: $(hdrdir)/ruby/internal/stdalign.h resize.o: $(hdrdir)/ruby/internal/stdbool.h +resize.o: $(hdrdir)/ruby/internal/stdckdint.h resize.o: $(hdrdir)/ruby/internal/symbol.h resize.o: $(hdrdir)/ruby/internal/value.h resize.o: $(hdrdir)/ruby/internal/value_type.h resize.o: $(hdrdir)/ruby/internal/variable.h resize.o: $(hdrdir)/ruby/internal/warning_push.h resize.o: $(hdrdir)/ruby/internal/xmalloc.h -resize.o: $(hdrdir)/ruby/assert.h -resize.o: $(hdrdir)/ruby/backward.h -resize.o: $(hdrdir)/ruby/backward/2/assume.h -resize.o: $(hdrdir)/ruby/backward/2/attributes.h -resize.o: $(hdrdir)/ruby/backward/2/bool.h -resize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -resize.o: $(hdrdir)/ruby/backward/2/inttypes.h -resize.o: $(hdrdir)/ruby/backward/2/limits.h -resize.o: $(hdrdir)/ruby/backward/2/long_long.h -resize.o: $(hdrdir)/ruby/backward/2/stdalign.h -resize.o: $(hdrdir)/ruby/backward/2/stdarg.h -resize.o: $(hdrdir)/ruby/defines.h -resize.o: $(hdrdir)/ruby/intern.h resize.o: $(hdrdir)/ruby/missing.h resize.o: $(hdrdir)/ruby/ruby.h resize.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/bignum/depend b/ext/-test-/bignum/depend index ddc1e63570..82972f1032 100644 --- a/ext/-test-/bignum/depend +++ b/ext/-test-/bignum/depend @@ -1,7 +1,20 @@ # AUTOGENERATED DEPENDENCIES START big2str.o: $(RUBY_EXTCONF_H) big2str.o: $(arch_hdrdir)/ruby/config.h -big2str.o: $(hdrdir)/ruby.h +big2str.o: $(hdrdir)/ruby/assert.h +big2str.o: $(hdrdir)/ruby/backward.h +big2str.o: $(hdrdir)/ruby/backward/2/assume.h +big2str.o: $(hdrdir)/ruby/backward/2/attributes.h +big2str.o: $(hdrdir)/ruby/backward/2/bool.h +big2str.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +big2str.o: $(hdrdir)/ruby/backward/2/inttypes.h +big2str.o: $(hdrdir)/ruby/backward/2/limits.h +big2str.o: $(hdrdir)/ruby/backward/2/long_long.h +big2str.o: $(hdrdir)/ruby/backward/2/stdalign.h +big2str.o: $(hdrdir)/ruby/backward/2/stdarg.h +big2str.o: $(hdrdir)/ruby/defines.h +big2str.o: $(hdrdir)/ruby/intern.h +big2str.o: $(hdrdir)/ruby/internal/abi.h big2str.o: $(hdrdir)/ruby/internal/anyargs.h big2str.o: $(hdrdir)/ruby/internal/arithmetic.h big2str.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ big2str.o: $(hdrdir)/ruby/internal/attr/noexcept.h big2str.o: $(hdrdir)/ruby/internal/attr/noinline.h big2str.o: $(hdrdir)/ruby/internal/attr/nonnull.h big2str.o: $(hdrdir)/ruby/internal/attr/noreturn.h +big2str.o: $(hdrdir)/ruby/internal/attr/packed_struct.h big2str.o: $(hdrdir)/ruby/internal/attr/pure.h big2str.o: $(hdrdir)/ruby/internal/attr/restrict.h big2str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ big2str.o: $(hdrdir)/ruby/internal/intern/enumerator.h big2str.o: $(hdrdir)/ruby/internal/intern/error.h big2str.o: $(hdrdir)/ruby/internal/intern/eval.h big2str.o: $(hdrdir)/ruby/internal/intern/file.h -big2str.o: $(hdrdir)/ruby/internal/intern/gc.h big2str.o: $(hdrdir)/ruby/internal/intern/hash.h big2str.o: $(hdrdir)/ruby/internal/intern/io.h big2str.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ big2str.o: $(hdrdir)/ruby/internal/intern/re.h big2str.o: $(hdrdir)/ruby/internal/intern/ruby.h big2str.o: $(hdrdir)/ruby/internal/intern/select.h big2str.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +big2str.o: $(hdrdir)/ruby/internal/intern/set.h big2str.o: $(hdrdir)/ruby/internal/intern/signal.h big2str.o: $(hdrdir)/ruby/internal/intern/sprintf.h big2str.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,41 +143,41 @@ big2str.o: $(hdrdir)/ruby/internal/memory.h big2str.o: $(hdrdir)/ruby/internal/method.h big2str.o: $(hdrdir)/ruby/internal/module.h big2str.o: $(hdrdir)/ruby/internal/newobj.h -big2str.o: $(hdrdir)/ruby/internal/rgengc.h big2str.o: $(hdrdir)/ruby/internal/scan_args.h big2str.o: $(hdrdir)/ruby/internal/special_consts.h big2str.o: $(hdrdir)/ruby/internal/static_assert.h big2str.o: $(hdrdir)/ruby/internal/stdalign.h big2str.o: $(hdrdir)/ruby/internal/stdbool.h +big2str.o: $(hdrdir)/ruby/internal/stdckdint.h big2str.o: $(hdrdir)/ruby/internal/symbol.h big2str.o: $(hdrdir)/ruby/internal/value.h big2str.o: $(hdrdir)/ruby/internal/value_type.h big2str.o: $(hdrdir)/ruby/internal/variable.h big2str.o: $(hdrdir)/ruby/internal/warning_push.h big2str.o: $(hdrdir)/ruby/internal/xmalloc.h -big2str.o: $(hdrdir)/ruby/assert.h -big2str.o: $(hdrdir)/ruby/backward.h -big2str.o: $(hdrdir)/ruby/backward/2/assume.h -big2str.o: $(hdrdir)/ruby/backward/2/attributes.h -big2str.o: $(hdrdir)/ruby/backward/2/bool.h -big2str.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -big2str.o: $(hdrdir)/ruby/backward/2/inttypes.h -big2str.o: $(hdrdir)/ruby/backward/2/limits.h -big2str.o: $(hdrdir)/ruby/backward/2/long_long.h -big2str.o: $(hdrdir)/ruby/backward/2/stdalign.h -big2str.o: $(hdrdir)/ruby/backward/2/stdarg.h -big2str.o: $(hdrdir)/ruby/defines.h -big2str.o: $(hdrdir)/ruby/intern.h big2str.o: $(hdrdir)/ruby/missing.h big2str.o: $(hdrdir)/ruby/ruby.h big2str.o: $(hdrdir)/ruby/st.h big2str.o: $(hdrdir)/ruby/subst.h -big2str.o: $(top_srcdir)/internal.h big2str.o: $(top_srcdir)/internal/bignum.h +big2str.o: $(top_srcdir)/internal/compilers.h big2str.o: big2str.c bigzero.o: $(RUBY_EXTCONF_H) bigzero.o: $(arch_hdrdir)/ruby/config.h -bigzero.o: $(hdrdir)/ruby.h +bigzero.o: $(hdrdir)/ruby/assert.h +bigzero.o: $(hdrdir)/ruby/backward.h +bigzero.o: $(hdrdir)/ruby/backward/2/assume.h +bigzero.o: $(hdrdir)/ruby/backward/2/attributes.h +bigzero.o: $(hdrdir)/ruby/backward/2/bool.h +bigzero.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +bigzero.o: $(hdrdir)/ruby/backward/2/inttypes.h +bigzero.o: $(hdrdir)/ruby/backward/2/limits.h +bigzero.o: $(hdrdir)/ruby/backward/2/long_long.h +bigzero.o: $(hdrdir)/ruby/backward/2/stdalign.h +bigzero.o: $(hdrdir)/ruby/backward/2/stdarg.h +bigzero.o: $(hdrdir)/ruby/defines.h +bigzero.o: $(hdrdir)/ruby/intern.h +bigzero.o: $(hdrdir)/ruby/internal/abi.h bigzero.o: $(hdrdir)/ruby/internal/anyargs.h bigzero.o: $(hdrdir)/ruby/internal/arithmetic.h bigzero.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -201,6 +215,7 @@ bigzero.o: $(hdrdir)/ruby/internal/attr/noexcept.h bigzero.o: $(hdrdir)/ruby/internal/attr/noinline.h bigzero.o: $(hdrdir)/ruby/internal/attr/nonnull.h bigzero.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bigzero.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bigzero.o: $(hdrdir)/ruby/internal/attr/pure.h bigzero.o: $(hdrdir)/ruby/internal/attr/restrict.h bigzero.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -260,7 +275,6 @@ bigzero.o: $(hdrdir)/ruby/internal/intern/enumerator.h bigzero.o: $(hdrdir)/ruby/internal/intern/error.h bigzero.o: $(hdrdir)/ruby/internal/intern/eval.h bigzero.o: $(hdrdir)/ruby/internal/intern/file.h -bigzero.o: $(hdrdir)/ruby/internal/intern/gc.h bigzero.o: $(hdrdir)/ruby/internal/intern/hash.h bigzero.o: $(hdrdir)/ruby/internal/intern/io.h bigzero.o: $(hdrdir)/ruby/internal/intern/load.h @@ -277,6 +291,7 @@ bigzero.o: $(hdrdir)/ruby/internal/intern/re.h bigzero.o: $(hdrdir)/ruby/internal/intern/ruby.h bigzero.o: $(hdrdir)/ruby/internal/intern/select.h bigzero.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bigzero.o: $(hdrdir)/ruby/internal/intern/set.h bigzero.o: $(hdrdir)/ruby/internal/intern/signal.h bigzero.o: $(hdrdir)/ruby/internal/intern/sprintf.h bigzero.o: $(hdrdir)/ruby/internal/intern/string.h @@ -291,41 +306,41 @@ bigzero.o: $(hdrdir)/ruby/internal/memory.h bigzero.o: $(hdrdir)/ruby/internal/method.h bigzero.o: $(hdrdir)/ruby/internal/module.h bigzero.o: $(hdrdir)/ruby/internal/newobj.h -bigzero.o: $(hdrdir)/ruby/internal/rgengc.h bigzero.o: $(hdrdir)/ruby/internal/scan_args.h bigzero.o: $(hdrdir)/ruby/internal/special_consts.h bigzero.o: $(hdrdir)/ruby/internal/static_assert.h bigzero.o: $(hdrdir)/ruby/internal/stdalign.h bigzero.o: $(hdrdir)/ruby/internal/stdbool.h +bigzero.o: $(hdrdir)/ruby/internal/stdckdint.h bigzero.o: $(hdrdir)/ruby/internal/symbol.h bigzero.o: $(hdrdir)/ruby/internal/value.h bigzero.o: $(hdrdir)/ruby/internal/value_type.h bigzero.o: $(hdrdir)/ruby/internal/variable.h bigzero.o: $(hdrdir)/ruby/internal/warning_push.h bigzero.o: $(hdrdir)/ruby/internal/xmalloc.h -bigzero.o: $(hdrdir)/ruby/assert.h -bigzero.o: $(hdrdir)/ruby/backward.h -bigzero.o: $(hdrdir)/ruby/backward/2/assume.h -bigzero.o: $(hdrdir)/ruby/backward/2/attributes.h -bigzero.o: $(hdrdir)/ruby/backward/2/bool.h -bigzero.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bigzero.o: $(hdrdir)/ruby/backward/2/inttypes.h -bigzero.o: $(hdrdir)/ruby/backward/2/limits.h -bigzero.o: $(hdrdir)/ruby/backward/2/long_long.h -bigzero.o: $(hdrdir)/ruby/backward/2/stdalign.h -bigzero.o: $(hdrdir)/ruby/backward/2/stdarg.h -bigzero.o: $(hdrdir)/ruby/defines.h -bigzero.o: $(hdrdir)/ruby/intern.h bigzero.o: $(hdrdir)/ruby/missing.h bigzero.o: $(hdrdir)/ruby/ruby.h bigzero.o: $(hdrdir)/ruby/st.h bigzero.o: $(hdrdir)/ruby/subst.h -bigzero.o: $(top_srcdir)/internal.h bigzero.o: $(top_srcdir)/internal/bignum.h +bigzero.o: $(top_srcdir)/internal/compilers.h bigzero.o: bigzero.c div.o: $(RUBY_EXTCONF_H) div.o: $(arch_hdrdir)/ruby/config.h -div.o: $(hdrdir)/ruby.h +div.o: $(hdrdir)/ruby/assert.h +div.o: $(hdrdir)/ruby/backward.h +div.o: $(hdrdir)/ruby/backward/2/assume.h +div.o: $(hdrdir)/ruby/backward/2/attributes.h +div.o: $(hdrdir)/ruby/backward/2/bool.h +div.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +div.o: $(hdrdir)/ruby/backward/2/inttypes.h +div.o: $(hdrdir)/ruby/backward/2/limits.h +div.o: $(hdrdir)/ruby/backward/2/long_long.h +div.o: $(hdrdir)/ruby/backward/2/stdalign.h +div.o: $(hdrdir)/ruby/backward/2/stdarg.h +div.o: $(hdrdir)/ruby/defines.h +div.o: $(hdrdir)/ruby/intern.h +div.o: $(hdrdir)/ruby/internal/abi.h div.o: $(hdrdir)/ruby/internal/anyargs.h div.o: $(hdrdir)/ruby/internal/arithmetic.h div.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -363,6 +378,7 @@ div.o: $(hdrdir)/ruby/internal/attr/noexcept.h div.o: $(hdrdir)/ruby/internal/attr/noinline.h div.o: $(hdrdir)/ruby/internal/attr/nonnull.h div.o: $(hdrdir)/ruby/internal/attr/noreturn.h +div.o: $(hdrdir)/ruby/internal/attr/packed_struct.h div.o: $(hdrdir)/ruby/internal/attr/pure.h div.o: $(hdrdir)/ruby/internal/attr/restrict.h div.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -422,7 +438,6 @@ div.o: $(hdrdir)/ruby/internal/intern/enumerator.h div.o: $(hdrdir)/ruby/internal/intern/error.h div.o: $(hdrdir)/ruby/internal/intern/eval.h div.o: $(hdrdir)/ruby/internal/intern/file.h -div.o: $(hdrdir)/ruby/internal/intern/gc.h div.o: $(hdrdir)/ruby/internal/intern/hash.h div.o: $(hdrdir)/ruby/internal/intern/io.h div.o: $(hdrdir)/ruby/internal/intern/load.h @@ -439,6 +454,7 @@ div.o: $(hdrdir)/ruby/internal/intern/re.h div.o: $(hdrdir)/ruby/internal/intern/ruby.h div.o: $(hdrdir)/ruby/internal/intern/select.h div.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +div.o: $(hdrdir)/ruby/internal/intern/set.h div.o: $(hdrdir)/ruby/internal/intern/signal.h div.o: $(hdrdir)/ruby/internal/intern/sprintf.h div.o: $(hdrdir)/ruby/internal/intern/string.h @@ -453,41 +469,41 @@ div.o: $(hdrdir)/ruby/internal/memory.h div.o: $(hdrdir)/ruby/internal/method.h div.o: $(hdrdir)/ruby/internal/module.h div.o: $(hdrdir)/ruby/internal/newobj.h -div.o: $(hdrdir)/ruby/internal/rgengc.h div.o: $(hdrdir)/ruby/internal/scan_args.h div.o: $(hdrdir)/ruby/internal/special_consts.h div.o: $(hdrdir)/ruby/internal/static_assert.h div.o: $(hdrdir)/ruby/internal/stdalign.h div.o: $(hdrdir)/ruby/internal/stdbool.h +div.o: $(hdrdir)/ruby/internal/stdckdint.h div.o: $(hdrdir)/ruby/internal/symbol.h div.o: $(hdrdir)/ruby/internal/value.h div.o: $(hdrdir)/ruby/internal/value_type.h div.o: $(hdrdir)/ruby/internal/variable.h div.o: $(hdrdir)/ruby/internal/warning_push.h div.o: $(hdrdir)/ruby/internal/xmalloc.h -div.o: $(hdrdir)/ruby/assert.h -div.o: $(hdrdir)/ruby/backward.h -div.o: $(hdrdir)/ruby/backward/2/assume.h -div.o: $(hdrdir)/ruby/backward/2/attributes.h -div.o: $(hdrdir)/ruby/backward/2/bool.h -div.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -div.o: $(hdrdir)/ruby/backward/2/inttypes.h -div.o: $(hdrdir)/ruby/backward/2/limits.h -div.o: $(hdrdir)/ruby/backward/2/long_long.h -div.o: $(hdrdir)/ruby/backward/2/stdalign.h -div.o: $(hdrdir)/ruby/backward/2/stdarg.h -div.o: $(hdrdir)/ruby/defines.h -div.o: $(hdrdir)/ruby/intern.h div.o: $(hdrdir)/ruby/missing.h div.o: $(hdrdir)/ruby/ruby.h div.o: $(hdrdir)/ruby/st.h div.o: $(hdrdir)/ruby/subst.h -div.o: $(top_srcdir)/internal.h div.o: $(top_srcdir)/internal/bignum.h +div.o: $(top_srcdir)/internal/compilers.h div.o: div.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -525,6 +541,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -584,7 +601,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -601,6 +617,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -615,31 +632,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -647,7 +651,20 @@ init.o: $(hdrdir)/ruby/subst.h init.o: init.c intpack.o: $(RUBY_EXTCONF_H) intpack.o: $(arch_hdrdir)/ruby/config.h -intpack.o: $(hdrdir)/ruby.h +intpack.o: $(hdrdir)/ruby/assert.h +intpack.o: $(hdrdir)/ruby/backward.h +intpack.o: $(hdrdir)/ruby/backward/2/assume.h +intpack.o: $(hdrdir)/ruby/backward/2/attributes.h +intpack.o: $(hdrdir)/ruby/backward/2/bool.h +intpack.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +intpack.o: $(hdrdir)/ruby/backward/2/inttypes.h +intpack.o: $(hdrdir)/ruby/backward/2/limits.h +intpack.o: $(hdrdir)/ruby/backward/2/long_long.h +intpack.o: $(hdrdir)/ruby/backward/2/stdalign.h +intpack.o: $(hdrdir)/ruby/backward/2/stdarg.h +intpack.o: $(hdrdir)/ruby/defines.h +intpack.o: $(hdrdir)/ruby/intern.h +intpack.o: $(hdrdir)/ruby/internal/abi.h intpack.o: $(hdrdir)/ruby/internal/anyargs.h intpack.o: $(hdrdir)/ruby/internal/arithmetic.h intpack.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -685,6 +702,7 @@ intpack.o: $(hdrdir)/ruby/internal/attr/noexcept.h intpack.o: $(hdrdir)/ruby/internal/attr/noinline.h intpack.o: $(hdrdir)/ruby/internal/attr/nonnull.h intpack.o: $(hdrdir)/ruby/internal/attr/noreturn.h +intpack.o: $(hdrdir)/ruby/internal/attr/packed_struct.h intpack.o: $(hdrdir)/ruby/internal/attr/pure.h intpack.o: $(hdrdir)/ruby/internal/attr/restrict.h intpack.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -744,7 +762,6 @@ intpack.o: $(hdrdir)/ruby/internal/intern/enumerator.h intpack.o: $(hdrdir)/ruby/internal/intern/error.h intpack.o: $(hdrdir)/ruby/internal/intern/eval.h intpack.o: $(hdrdir)/ruby/internal/intern/file.h -intpack.o: $(hdrdir)/ruby/internal/intern/gc.h intpack.o: $(hdrdir)/ruby/internal/intern/hash.h intpack.o: $(hdrdir)/ruby/internal/intern/io.h intpack.o: $(hdrdir)/ruby/internal/intern/load.h @@ -761,6 +778,7 @@ intpack.o: $(hdrdir)/ruby/internal/intern/re.h intpack.o: $(hdrdir)/ruby/internal/intern/ruby.h intpack.o: $(hdrdir)/ruby/internal/intern/select.h intpack.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +intpack.o: $(hdrdir)/ruby/internal/intern/set.h intpack.o: $(hdrdir)/ruby/internal/intern/signal.h intpack.o: $(hdrdir)/ruby/internal/intern/sprintf.h intpack.o: $(hdrdir)/ruby/internal/intern/string.h @@ -775,41 +793,41 @@ intpack.o: $(hdrdir)/ruby/internal/memory.h intpack.o: $(hdrdir)/ruby/internal/method.h intpack.o: $(hdrdir)/ruby/internal/module.h intpack.o: $(hdrdir)/ruby/internal/newobj.h -intpack.o: $(hdrdir)/ruby/internal/rgengc.h intpack.o: $(hdrdir)/ruby/internal/scan_args.h intpack.o: $(hdrdir)/ruby/internal/special_consts.h intpack.o: $(hdrdir)/ruby/internal/static_assert.h intpack.o: $(hdrdir)/ruby/internal/stdalign.h intpack.o: $(hdrdir)/ruby/internal/stdbool.h +intpack.o: $(hdrdir)/ruby/internal/stdckdint.h intpack.o: $(hdrdir)/ruby/internal/symbol.h intpack.o: $(hdrdir)/ruby/internal/value.h intpack.o: $(hdrdir)/ruby/internal/value_type.h intpack.o: $(hdrdir)/ruby/internal/variable.h intpack.o: $(hdrdir)/ruby/internal/warning_push.h intpack.o: $(hdrdir)/ruby/internal/xmalloc.h -intpack.o: $(hdrdir)/ruby/assert.h -intpack.o: $(hdrdir)/ruby/backward.h -intpack.o: $(hdrdir)/ruby/backward/2/assume.h -intpack.o: $(hdrdir)/ruby/backward/2/attributes.h -intpack.o: $(hdrdir)/ruby/backward/2/bool.h -intpack.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -intpack.o: $(hdrdir)/ruby/backward/2/inttypes.h -intpack.o: $(hdrdir)/ruby/backward/2/limits.h -intpack.o: $(hdrdir)/ruby/backward/2/long_long.h -intpack.o: $(hdrdir)/ruby/backward/2/stdalign.h -intpack.o: $(hdrdir)/ruby/backward/2/stdarg.h -intpack.o: $(hdrdir)/ruby/defines.h -intpack.o: $(hdrdir)/ruby/intern.h intpack.o: $(hdrdir)/ruby/missing.h intpack.o: $(hdrdir)/ruby/ruby.h intpack.o: $(hdrdir)/ruby/st.h intpack.o: $(hdrdir)/ruby/subst.h -intpack.o: $(top_srcdir)/internal.h intpack.o: $(top_srcdir)/internal/bignum.h +intpack.o: $(top_srcdir)/internal/compilers.h intpack.o: intpack.c mul.o: $(RUBY_EXTCONF_H) mul.o: $(arch_hdrdir)/ruby/config.h -mul.o: $(hdrdir)/ruby.h +mul.o: $(hdrdir)/ruby/assert.h +mul.o: $(hdrdir)/ruby/backward.h +mul.o: $(hdrdir)/ruby/backward/2/assume.h +mul.o: $(hdrdir)/ruby/backward/2/attributes.h +mul.o: $(hdrdir)/ruby/backward/2/bool.h +mul.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +mul.o: $(hdrdir)/ruby/backward/2/inttypes.h +mul.o: $(hdrdir)/ruby/backward/2/limits.h +mul.o: $(hdrdir)/ruby/backward/2/long_long.h +mul.o: $(hdrdir)/ruby/backward/2/stdalign.h +mul.o: $(hdrdir)/ruby/backward/2/stdarg.h +mul.o: $(hdrdir)/ruby/defines.h +mul.o: $(hdrdir)/ruby/intern.h +mul.o: $(hdrdir)/ruby/internal/abi.h mul.o: $(hdrdir)/ruby/internal/anyargs.h mul.o: $(hdrdir)/ruby/internal/arithmetic.h mul.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -847,6 +865,7 @@ mul.o: $(hdrdir)/ruby/internal/attr/noexcept.h mul.o: $(hdrdir)/ruby/internal/attr/noinline.h mul.o: $(hdrdir)/ruby/internal/attr/nonnull.h mul.o: $(hdrdir)/ruby/internal/attr/noreturn.h +mul.o: $(hdrdir)/ruby/internal/attr/packed_struct.h mul.o: $(hdrdir)/ruby/internal/attr/pure.h mul.o: $(hdrdir)/ruby/internal/attr/restrict.h mul.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -906,7 +925,6 @@ mul.o: $(hdrdir)/ruby/internal/intern/enumerator.h mul.o: $(hdrdir)/ruby/internal/intern/error.h mul.o: $(hdrdir)/ruby/internal/intern/eval.h mul.o: $(hdrdir)/ruby/internal/intern/file.h -mul.o: $(hdrdir)/ruby/internal/intern/gc.h mul.o: $(hdrdir)/ruby/internal/intern/hash.h mul.o: $(hdrdir)/ruby/internal/intern/io.h mul.o: $(hdrdir)/ruby/internal/intern/load.h @@ -923,6 +941,7 @@ mul.o: $(hdrdir)/ruby/internal/intern/re.h mul.o: $(hdrdir)/ruby/internal/intern/ruby.h mul.o: $(hdrdir)/ruby/internal/intern/select.h mul.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +mul.o: $(hdrdir)/ruby/internal/intern/set.h mul.o: $(hdrdir)/ruby/internal/intern/signal.h mul.o: $(hdrdir)/ruby/internal/intern/sprintf.h mul.o: $(hdrdir)/ruby/internal/intern/string.h @@ -937,41 +956,41 @@ mul.o: $(hdrdir)/ruby/internal/memory.h mul.o: $(hdrdir)/ruby/internal/method.h mul.o: $(hdrdir)/ruby/internal/module.h mul.o: $(hdrdir)/ruby/internal/newobj.h -mul.o: $(hdrdir)/ruby/internal/rgengc.h mul.o: $(hdrdir)/ruby/internal/scan_args.h mul.o: $(hdrdir)/ruby/internal/special_consts.h mul.o: $(hdrdir)/ruby/internal/static_assert.h mul.o: $(hdrdir)/ruby/internal/stdalign.h mul.o: $(hdrdir)/ruby/internal/stdbool.h +mul.o: $(hdrdir)/ruby/internal/stdckdint.h mul.o: $(hdrdir)/ruby/internal/symbol.h mul.o: $(hdrdir)/ruby/internal/value.h mul.o: $(hdrdir)/ruby/internal/value_type.h mul.o: $(hdrdir)/ruby/internal/variable.h mul.o: $(hdrdir)/ruby/internal/warning_push.h mul.o: $(hdrdir)/ruby/internal/xmalloc.h -mul.o: $(hdrdir)/ruby/assert.h -mul.o: $(hdrdir)/ruby/backward.h -mul.o: $(hdrdir)/ruby/backward/2/assume.h -mul.o: $(hdrdir)/ruby/backward/2/attributes.h -mul.o: $(hdrdir)/ruby/backward/2/bool.h -mul.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -mul.o: $(hdrdir)/ruby/backward/2/inttypes.h -mul.o: $(hdrdir)/ruby/backward/2/limits.h -mul.o: $(hdrdir)/ruby/backward/2/long_long.h -mul.o: $(hdrdir)/ruby/backward/2/stdalign.h -mul.o: $(hdrdir)/ruby/backward/2/stdarg.h -mul.o: $(hdrdir)/ruby/defines.h -mul.o: $(hdrdir)/ruby/intern.h mul.o: $(hdrdir)/ruby/missing.h mul.o: $(hdrdir)/ruby/ruby.h mul.o: $(hdrdir)/ruby/st.h mul.o: $(hdrdir)/ruby/subst.h -mul.o: $(top_srcdir)/internal.h mul.o: $(top_srcdir)/internal/bignum.h +mul.o: $(top_srcdir)/internal/compilers.h mul.o: mul.c str2big.o: $(RUBY_EXTCONF_H) str2big.o: $(arch_hdrdir)/ruby/config.h -str2big.o: $(hdrdir)/ruby.h +str2big.o: $(hdrdir)/ruby/assert.h +str2big.o: $(hdrdir)/ruby/backward.h +str2big.o: $(hdrdir)/ruby/backward/2/assume.h +str2big.o: $(hdrdir)/ruby/backward/2/attributes.h +str2big.o: $(hdrdir)/ruby/backward/2/bool.h +str2big.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +str2big.o: $(hdrdir)/ruby/backward/2/inttypes.h +str2big.o: $(hdrdir)/ruby/backward/2/limits.h +str2big.o: $(hdrdir)/ruby/backward/2/long_long.h +str2big.o: $(hdrdir)/ruby/backward/2/stdalign.h +str2big.o: $(hdrdir)/ruby/backward/2/stdarg.h +str2big.o: $(hdrdir)/ruby/defines.h +str2big.o: $(hdrdir)/ruby/intern.h +str2big.o: $(hdrdir)/ruby/internal/abi.h str2big.o: $(hdrdir)/ruby/internal/anyargs.h str2big.o: $(hdrdir)/ruby/internal/arithmetic.h str2big.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1009,6 +1028,7 @@ str2big.o: $(hdrdir)/ruby/internal/attr/noexcept.h str2big.o: $(hdrdir)/ruby/internal/attr/noinline.h str2big.o: $(hdrdir)/ruby/internal/attr/nonnull.h str2big.o: $(hdrdir)/ruby/internal/attr/noreturn.h +str2big.o: $(hdrdir)/ruby/internal/attr/packed_struct.h str2big.o: $(hdrdir)/ruby/internal/attr/pure.h str2big.o: $(hdrdir)/ruby/internal/attr/restrict.h str2big.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1068,7 +1088,6 @@ str2big.o: $(hdrdir)/ruby/internal/intern/enumerator.h str2big.o: $(hdrdir)/ruby/internal/intern/error.h str2big.o: $(hdrdir)/ruby/internal/intern/eval.h str2big.o: $(hdrdir)/ruby/internal/intern/file.h -str2big.o: $(hdrdir)/ruby/internal/intern/gc.h str2big.o: $(hdrdir)/ruby/internal/intern/hash.h str2big.o: $(hdrdir)/ruby/internal/intern/io.h str2big.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1085,6 +1104,7 @@ str2big.o: $(hdrdir)/ruby/internal/intern/re.h str2big.o: $(hdrdir)/ruby/internal/intern/ruby.h str2big.o: $(hdrdir)/ruby/internal/intern/select.h str2big.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +str2big.o: $(hdrdir)/ruby/internal/intern/set.h str2big.o: $(hdrdir)/ruby/internal/intern/signal.h str2big.o: $(hdrdir)/ruby/internal/intern/sprintf.h str2big.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1099,36 +1119,23 @@ str2big.o: $(hdrdir)/ruby/internal/memory.h str2big.o: $(hdrdir)/ruby/internal/method.h str2big.o: $(hdrdir)/ruby/internal/module.h str2big.o: $(hdrdir)/ruby/internal/newobj.h -str2big.o: $(hdrdir)/ruby/internal/rgengc.h str2big.o: $(hdrdir)/ruby/internal/scan_args.h str2big.o: $(hdrdir)/ruby/internal/special_consts.h str2big.o: $(hdrdir)/ruby/internal/static_assert.h str2big.o: $(hdrdir)/ruby/internal/stdalign.h str2big.o: $(hdrdir)/ruby/internal/stdbool.h +str2big.o: $(hdrdir)/ruby/internal/stdckdint.h str2big.o: $(hdrdir)/ruby/internal/symbol.h str2big.o: $(hdrdir)/ruby/internal/value.h str2big.o: $(hdrdir)/ruby/internal/value_type.h str2big.o: $(hdrdir)/ruby/internal/variable.h str2big.o: $(hdrdir)/ruby/internal/warning_push.h str2big.o: $(hdrdir)/ruby/internal/xmalloc.h -str2big.o: $(hdrdir)/ruby/assert.h -str2big.o: $(hdrdir)/ruby/backward.h -str2big.o: $(hdrdir)/ruby/backward/2/assume.h -str2big.o: $(hdrdir)/ruby/backward/2/attributes.h -str2big.o: $(hdrdir)/ruby/backward/2/bool.h -str2big.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -str2big.o: $(hdrdir)/ruby/backward/2/inttypes.h -str2big.o: $(hdrdir)/ruby/backward/2/limits.h -str2big.o: $(hdrdir)/ruby/backward/2/long_long.h -str2big.o: $(hdrdir)/ruby/backward/2/stdalign.h -str2big.o: $(hdrdir)/ruby/backward/2/stdarg.h -str2big.o: $(hdrdir)/ruby/defines.h -str2big.o: $(hdrdir)/ruby/intern.h str2big.o: $(hdrdir)/ruby/missing.h str2big.o: $(hdrdir)/ruby/ruby.h str2big.o: $(hdrdir)/ruby/st.h str2big.o: $(hdrdir)/ruby/subst.h -str2big.o: $(top_srcdir)/internal.h str2big.o: $(top_srcdir)/internal/bignum.h +str2big.o: $(top_srcdir)/internal/compilers.h str2big.o: str2big.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/box/yay1/extconf.rb b/ext/-test-/box/yay1/extconf.rb new file mode 100644 index 0000000000..54387cedf1 --- /dev/null +++ b/ext/-test-/box/yay1/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/box/yay1') diff --git a/ext/-test-/box/yay1/yay1.c b/ext/-test-/box/yay1/yay1.c new file mode 100644 index 0000000000..564a221c8c --- /dev/null +++ b/ext/-test-/box/yay1/yay1.c @@ -0,0 +1,28 @@ +#include "yay1.h" + +VALUE +yay_value(void) +{ + return rb_str_new_cstr("yay"); +} + +static VALUE +yay1_f_version(VALUE klass) +{ + return rb_str_new_cstr("1.0.0"); +} + +static VALUE +yay1_yay(VALUE klass) +{ + return yay_value(); +} + +void +Init_yay1(void) +{ + VALUE mod = rb_define_module("Yay"); + rb_define_const(mod, "VERSION", rb_str_new_cstr("1.0.0")); + rb_define_singleton_method(mod, "version", yay1_f_version, 0); + rb_define_singleton_method(mod, "yay", yay1_yay, 0); +} diff --git a/ext/-test-/box/yay1/yay1.def b/ext/-test-/box/yay1/yay1.def new file mode 100644 index 0000000000..510fbe7017 --- /dev/null +++ b/ext/-test-/box/yay1/yay1.def @@ -0,0 +1,3 @@ +EXPORTS + Init_yay1 + yay_value diff --git a/ext/-test-/box/yay1/yay1.h b/ext/-test-/box/yay1/yay1.h new file mode 100644 index 0000000000..c4dade928a --- /dev/null +++ b/ext/-test-/box/yay1/yay1.h @@ -0,0 +1,4 @@ +#include <ruby.h> +#include "ruby/internal/dllexport.h" + +RUBY_FUNC_EXPORTED VALUE yay_value(void); diff --git a/ext/-test-/box/yay2/extconf.rb b/ext/-test-/box/yay2/extconf.rb new file mode 100644 index 0000000000..850ef3edc9 --- /dev/null +++ b/ext/-test-/box/yay2/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/box/yay2') diff --git a/ext/-test-/box/yay2/yay2.c b/ext/-test-/box/yay2/yay2.c new file mode 100644 index 0000000000..b632ae8495 --- /dev/null +++ b/ext/-test-/box/yay2/yay2.c @@ -0,0 +1,28 @@ +#include "yay2.h" + +VALUE +yay_value(void) +{ + return rb_str_new_cstr("yaaay"); +} + +static VALUE +yay2_f_version(VALUE klass) +{ + return rb_str_new_cstr("2.0.0"); +} + +static VALUE +yay2_yay(VALUE klass) +{ + return yay_value(); +} + +void +Init_yay2(void) +{ + VALUE mod = rb_define_module("Yay"); + rb_define_const(mod, "VERSION", rb_str_new_cstr("2.0.0")); + rb_define_singleton_method(mod, "version", yay2_f_version, 0); + rb_define_singleton_method(mod, "yay", yay2_yay, 0); +} diff --git a/ext/-test-/box/yay2/yay2.def b/ext/-test-/box/yay2/yay2.def new file mode 100644 index 0000000000..163fc44c04 --- /dev/null +++ b/ext/-test-/box/yay2/yay2.def @@ -0,0 +1,3 @@ +EXPORTS + Init_yay2 + yay_value diff --git a/ext/-test-/box/yay2/yay2.h b/ext/-test-/box/yay2/yay2.h new file mode 100644 index 0000000000..c4dade928a --- /dev/null +++ b/ext/-test-/box/yay2/yay2.h @@ -0,0 +1,4 @@ +#include <ruby.h> +#include "ruby/internal/dllexport.h" + +RUBY_FUNC_EXPORTED VALUE yay_value(void); diff --git a/ext/-test-/bug-14834/bug-14384.c b/ext/-test-/bug-14834/bug-14834.c index 3a16a2d222..af2070d303 100644 --- a/ext/-test-/bug-14834/bug-14384.c +++ b/ext/-test-/bug-14834/bug-14834.c @@ -7,7 +7,7 @@ static NOINLINE(VALUE f(VALUE)); static NOINLINE(void g(VALUE, void*)); -extern NOINLINE(void Init_bug_14384(void)); +extern NOINLINE(void Init_bug_14834(void)); void Init_bug_14834(void) diff --git a/ext/-test-/bug-14834/depend b/ext/-test-/bug-14834/depend index 5bbaf17089..f83939d559 100644 --- a/ext/-test-/bug-14834/depend +++ b/ext/-test-/bug-14834/depend @@ -1,162 +1,163 @@ # AUTOGENERATED DEPENDENCIES START -bug-14384.o: $(RUBY_EXTCONF_H) -bug-14384.o: $(arch_hdrdir)/ruby/config.h -bug-14384.o: $(hdrdir)/ruby/internal/anyargs.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/char.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/double.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/int.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/long.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/short.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -bug-14384.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -bug-14384.o: $(hdrdir)/ruby/internal/assume.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/artificial.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/cold.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/const.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/constexpr.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/deprecated.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/error.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/forceinline.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/format.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/noalias.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/noexcept.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/noinline.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/nonnull.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/noreturn.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/pure.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/restrict.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/warning.h -bug-14384.o: $(hdrdir)/ruby/internal/attr/weakref.h -bug-14384.o: $(hdrdir)/ruby/internal/cast.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -bug-14384.o: $(hdrdir)/ruby/internal/compiler_since.h -bug-14384.o: $(hdrdir)/ruby/internal/config.h -bug-14384.o: $(hdrdir)/ruby/internal/constant_p.h -bug-14384.o: $(hdrdir)/ruby/internal/core.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rarray.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rbasic.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rbignum.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rclass.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rdata.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rfile.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rhash.h -bug-14384.o: $(hdrdir)/ruby/internal/core/robject.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rregexp.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rstring.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rstruct.h -bug-14384.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -bug-14384.o: $(hdrdir)/ruby/internal/ctype.h -bug-14384.o: $(hdrdir)/ruby/internal/dllexport.h -bug-14384.o: $(hdrdir)/ruby/internal/dosish.h -bug-14384.o: $(hdrdir)/ruby/internal/error.h -bug-14384.o: $(hdrdir)/ruby/internal/eval.h -bug-14384.o: $(hdrdir)/ruby/internal/event.h -bug-14384.o: $(hdrdir)/ruby/internal/fl_type.h -bug-14384.o: $(hdrdir)/ruby/internal/gc.h -bug-14384.o: $(hdrdir)/ruby/internal/glob.h -bug-14384.o: $(hdrdir)/ruby/internal/globals.h -bug-14384.o: $(hdrdir)/ruby/internal/has/attribute.h -bug-14384.o: $(hdrdir)/ruby/internal/has/builtin.h -bug-14384.o: $(hdrdir)/ruby/internal/has/c_attribute.h -bug-14384.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -bug-14384.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -bug-14384.o: $(hdrdir)/ruby/internal/has/extension.h -bug-14384.o: $(hdrdir)/ruby/internal/has/feature.h -bug-14384.o: $(hdrdir)/ruby/internal/has/warning.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/array.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/bignum.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/class.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/compar.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/complex.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/cont.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/dir.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/enum.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/enumerator.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/error.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/eval.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/file.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/gc.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/hash.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/io.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/load.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/marshal.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/numeric.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/object.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/parse.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/proc.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/process.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/random.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/range.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/rational.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/re.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/ruby.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/select.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/signal.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/sprintf.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/string.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/struct.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/thread.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/time.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/variable.h -bug-14384.o: $(hdrdir)/ruby/internal/intern/vm.h -bug-14384.o: $(hdrdir)/ruby/internal/interpreter.h -bug-14384.o: $(hdrdir)/ruby/internal/iterator.h -bug-14384.o: $(hdrdir)/ruby/internal/memory.h -bug-14384.o: $(hdrdir)/ruby/internal/method.h -bug-14384.o: $(hdrdir)/ruby/internal/module.h -bug-14384.o: $(hdrdir)/ruby/internal/newobj.h -bug-14384.o: $(hdrdir)/ruby/internal/rgengc.h -bug-14384.o: $(hdrdir)/ruby/internal/scan_args.h -bug-14384.o: $(hdrdir)/ruby/internal/special_consts.h -bug-14384.o: $(hdrdir)/ruby/internal/static_assert.h -bug-14384.o: $(hdrdir)/ruby/internal/stdalign.h -bug-14384.o: $(hdrdir)/ruby/internal/stdbool.h -bug-14384.o: $(hdrdir)/ruby/internal/symbol.h -bug-14384.o: $(hdrdir)/ruby/internal/value.h -bug-14384.o: $(hdrdir)/ruby/internal/value_type.h -bug-14384.o: $(hdrdir)/ruby/internal/variable.h -bug-14384.o: $(hdrdir)/ruby/internal/warning_push.h -bug-14384.o: $(hdrdir)/ruby/internal/xmalloc.h -bug-14384.o: $(hdrdir)/ruby/assert.h -bug-14384.o: $(hdrdir)/ruby/backward.h -bug-14384.o: $(hdrdir)/ruby/backward/2/assume.h -bug-14384.o: $(hdrdir)/ruby/backward/2/attributes.h -bug-14384.o: $(hdrdir)/ruby/backward/2/bool.h -bug-14384.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bug-14384.o: $(hdrdir)/ruby/backward/2/inttypes.h -bug-14384.o: $(hdrdir)/ruby/backward/2/limits.h -bug-14384.o: $(hdrdir)/ruby/backward/2/long_long.h -bug-14384.o: $(hdrdir)/ruby/backward/2/stdalign.h -bug-14384.o: $(hdrdir)/ruby/backward/2/stdarg.h -bug-14384.o: $(hdrdir)/ruby/debug.h -bug-14384.o: $(hdrdir)/ruby/defines.h -bug-14384.o: $(hdrdir)/ruby/intern.h -bug-14384.o: $(hdrdir)/ruby/missing.h -bug-14384.o: $(hdrdir)/ruby/ruby.h -bug-14384.o: $(hdrdir)/ruby/st.h -bug-14384.o: $(hdrdir)/ruby/subst.h -bug-14384.o: bug-14384.c +bug-14834.o: $(RUBY_EXTCONF_H) +bug-14834.o: $(arch_hdrdir)/ruby/config.h +bug-14834.o: $(hdrdir)/ruby/assert.h +bug-14834.o: $(hdrdir)/ruby/backward.h +bug-14834.o: $(hdrdir)/ruby/backward/2/assume.h +bug-14834.o: $(hdrdir)/ruby/backward/2/attributes.h +bug-14834.o: $(hdrdir)/ruby/backward/2/bool.h +bug-14834.o: $(hdrdir)/ruby/backward/2/inttypes.h +bug-14834.o: $(hdrdir)/ruby/backward/2/limits.h +bug-14834.o: $(hdrdir)/ruby/backward/2/long_long.h +bug-14834.o: $(hdrdir)/ruby/backward/2/stdalign.h +bug-14834.o: $(hdrdir)/ruby/backward/2/stdarg.h +bug-14834.o: $(hdrdir)/ruby/debug.h +bug-14834.o: $(hdrdir)/ruby/defines.h +bug-14834.o: $(hdrdir)/ruby/intern.h +bug-14834.o: $(hdrdir)/ruby/internal/abi.h +bug-14834.o: $(hdrdir)/ruby/internal/anyargs.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/char.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/double.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/int.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/long.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/short.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +bug-14834.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +bug-14834.o: $(hdrdir)/ruby/internal/assume.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/artificial.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/cold.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/const.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/constexpr.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/deprecated.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/error.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/forceinline.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/format.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/noalias.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/noexcept.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/noinline.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/nonnull.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/pure.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/restrict.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/warning.h +bug-14834.o: $(hdrdir)/ruby/internal/attr/weakref.h +bug-14834.o: $(hdrdir)/ruby/internal/cast.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +bug-14834.o: $(hdrdir)/ruby/internal/compiler_since.h +bug-14834.o: $(hdrdir)/ruby/internal/config.h +bug-14834.o: $(hdrdir)/ruby/internal/constant_p.h +bug-14834.o: $(hdrdir)/ruby/internal/core.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rarray.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rbasic.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rbignum.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rclass.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rdata.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rfile.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rhash.h +bug-14834.o: $(hdrdir)/ruby/internal/core/robject.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rregexp.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rstring.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rstruct.h +bug-14834.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +bug-14834.o: $(hdrdir)/ruby/internal/ctype.h +bug-14834.o: $(hdrdir)/ruby/internal/dllexport.h +bug-14834.o: $(hdrdir)/ruby/internal/dosish.h +bug-14834.o: $(hdrdir)/ruby/internal/error.h +bug-14834.o: $(hdrdir)/ruby/internal/eval.h +bug-14834.o: $(hdrdir)/ruby/internal/event.h +bug-14834.o: $(hdrdir)/ruby/internal/fl_type.h +bug-14834.o: $(hdrdir)/ruby/internal/gc.h +bug-14834.o: $(hdrdir)/ruby/internal/glob.h +bug-14834.o: $(hdrdir)/ruby/internal/globals.h +bug-14834.o: $(hdrdir)/ruby/internal/has/attribute.h +bug-14834.o: $(hdrdir)/ruby/internal/has/builtin.h +bug-14834.o: $(hdrdir)/ruby/internal/has/c_attribute.h +bug-14834.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +bug-14834.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +bug-14834.o: $(hdrdir)/ruby/internal/has/extension.h +bug-14834.o: $(hdrdir)/ruby/internal/has/feature.h +bug-14834.o: $(hdrdir)/ruby/internal/has/warning.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/array.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/bignum.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/class.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/compar.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/complex.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/cont.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/dir.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/enum.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/enumerator.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/error.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/eval.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/file.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/hash.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/io.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/load.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/marshal.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/numeric.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/object.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/parse.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/proc.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/process.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/random.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/range.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/rational.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/re.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/ruby.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/select.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/set.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/signal.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/sprintf.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/string.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/struct.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/thread.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/time.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/variable.h +bug-14834.o: $(hdrdir)/ruby/internal/intern/vm.h +bug-14834.o: $(hdrdir)/ruby/internal/interpreter.h +bug-14834.o: $(hdrdir)/ruby/internal/iterator.h +bug-14834.o: $(hdrdir)/ruby/internal/memory.h +bug-14834.o: $(hdrdir)/ruby/internal/method.h +bug-14834.o: $(hdrdir)/ruby/internal/module.h +bug-14834.o: $(hdrdir)/ruby/internal/newobj.h +bug-14834.o: $(hdrdir)/ruby/internal/scan_args.h +bug-14834.o: $(hdrdir)/ruby/internal/special_consts.h +bug-14834.o: $(hdrdir)/ruby/internal/static_assert.h +bug-14834.o: $(hdrdir)/ruby/internal/stdalign.h +bug-14834.o: $(hdrdir)/ruby/internal/stdbool.h +bug-14834.o: $(hdrdir)/ruby/internal/stdckdint.h +bug-14834.o: $(hdrdir)/ruby/internal/symbol.h +bug-14834.o: $(hdrdir)/ruby/internal/value.h +bug-14834.o: $(hdrdir)/ruby/internal/value_type.h +bug-14834.o: $(hdrdir)/ruby/internal/variable.h +bug-14834.o: $(hdrdir)/ruby/internal/warning_push.h +bug-14834.o: $(hdrdir)/ruby/internal/xmalloc.h +bug-14834.o: $(hdrdir)/ruby/missing.h +bug-14834.o: $(hdrdir)/ruby/ruby.h +bug-14834.o: $(hdrdir)/ruby/st.h +bug-14834.o: $(hdrdir)/ruby/subst.h +bug-14834.o: bug-14834.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/bug-3571/depend b/ext/-test-/bug-3571/depend index 506795a137..69c970b6f2 100644 --- a/ext/-test-/bug-3571/depend +++ b/ext/-test-/bug-3571/depend @@ -2,6 +2,19 @@ bug.o: $(RUBY_EXTCONF_H) bug.o: $(arch_hdrdir)/ruby/config.h bug.o: $(hdrdir)/ruby.h +bug.o: $(hdrdir)/ruby/assert.h +bug.o: $(hdrdir)/ruby/backward.h +bug.o: $(hdrdir)/ruby/backward/2/assume.h +bug.o: $(hdrdir)/ruby/backward/2/attributes.h +bug.o: $(hdrdir)/ruby/backward/2/bool.h +bug.o: $(hdrdir)/ruby/backward/2/inttypes.h +bug.o: $(hdrdir)/ruby/backward/2/limits.h +bug.o: $(hdrdir)/ruby/backward/2/long_long.h +bug.o: $(hdrdir)/ruby/backward/2/stdalign.h +bug.o: $(hdrdir)/ruby/backward/2/stdarg.h +bug.o: $(hdrdir)/ruby/defines.h +bug.o: $(hdrdir)/ruby/intern.h +bug.o: $(hdrdir)/ruby/internal/abi.h bug.o: $(hdrdir)/ruby/internal/anyargs.h bug.o: $(hdrdir)/ruby/internal/arithmetic.h bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h bug.o: $(hdrdir)/ruby/internal/attr/noinline.h bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bug.o: $(hdrdir)/ruby/internal/attr/pure.h bug.o: $(hdrdir)/ruby/internal/attr/restrict.h bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h bug.o: $(hdrdir)/ruby/internal/intern/error.h bug.o: $(hdrdir)/ruby/internal/intern/eval.h bug.o: $(hdrdir)/ruby/internal/intern/file.h -bug.o: $(hdrdir)/ruby/internal/intern/gc.h bug.o: $(hdrdir)/ruby/internal/intern/hash.h bug.o: $(hdrdir)/ruby/internal/intern/io.h bug.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/re.h bug.o: $(hdrdir)/ruby/internal/intern/ruby.h bug.o: $(hdrdir)/ruby/internal/intern/select.h bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bug.o: $(hdrdir)/ruby/internal/intern/set.h bug.o: $(hdrdir)/ruby/internal/intern/signal.h bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h bug.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ bug.o: $(hdrdir)/ruby/internal/memory.h bug.o: $(hdrdir)/ruby/internal/method.h bug.o: $(hdrdir)/ruby/internal/module.h bug.o: $(hdrdir)/ruby/internal/newobj.h -bug.o: $(hdrdir)/ruby/internal/rgengc.h bug.o: $(hdrdir)/ruby/internal/scan_args.h bug.o: $(hdrdir)/ruby/internal/special_consts.h bug.o: $(hdrdir)/ruby/internal/static_assert.h bug.o: $(hdrdir)/ruby/internal/stdalign.h bug.o: $(hdrdir)/ruby/internal/stdbool.h +bug.o: $(hdrdir)/ruby/internal/stdckdint.h bug.o: $(hdrdir)/ruby/internal/symbol.h bug.o: $(hdrdir)/ruby/internal/value.h bug.o: $(hdrdir)/ruby/internal/value_type.h bug.o: $(hdrdir)/ruby/internal/variable.h bug.o: $(hdrdir)/ruby/internal/warning_push.h bug.o: $(hdrdir)/ruby/internal/xmalloc.h -bug.o: $(hdrdir)/ruby/assert.h -bug.o: $(hdrdir)/ruby/backward.h -bug.o: $(hdrdir)/ruby/backward/2/assume.h -bug.o: $(hdrdir)/ruby/backward/2/attributes.h -bug.o: $(hdrdir)/ruby/backward/2/bool.h -bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bug.o: $(hdrdir)/ruby/backward/2/inttypes.h -bug.o: $(hdrdir)/ruby/backward/2/limits.h -bug.o: $(hdrdir)/ruby/backward/2/long_long.h -bug.o: $(hdrdir)/ruby/backward/2/stdalign.h -bug.o: $(hdrdir)/ruby/backward/2/stdarg.h -bug.o: $(hdrdir)/ruby/defines.h -bug.o: $(hdrdir)/ruby/intern.h bug.o: $(hdrdir)/ruby/missing.h bug.o: $(hdrdir)/ruby/ruby.h bug.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/bug-5832/depend b/ext/-test-/bug-5832/depend index 506795a137..69c970b6f2 100644 --- a/ext/-test-/bug-5832/depend +++ b/ext/-test-/bug-5832/depend @@ -2,6 +2,19 @@ bug.o: $(RUBY_EXTCONF_H) bug.o: $(arch_hdrdir)/ruby/config.h bug.o: $(hdrdir)/ruby.h +bug.o: $(hdrdir)/ruby/assert.h +bug.o: $(hdrdir)/ruby/backward.h +bug.o: $(hdrdir)/ruby/backward/2/assume.h +bug.o: $(hdrdir)/ruby/backward/2/attributes.h +bug.o: $(hdrdir)/ruby/backward/2/bool.h +bug.o: $(hdrdir)/ruby/backward/2/inttypes.h +bug.o: $(hdrdir)/ruby/backward/2/limits.h +bug.o: $(hdrdir)/ruby/backward/2/long_long.h +bug.o: $(hdrdir)/ruby/backward/2/stdalign.h +bug.o: $(hdrdir)/ruby/backward/2/stdarg.h +bug.o: $(hdrdir)/ruby/defines.h +bug.o: $(hdrdir)/ruby/intern.h +bug.o: $(hdrdir)/ruby/internal/abi.h bug.o: $(hdrdir)/ruby/internal/anyargs.h bug.o: $(hdrdir)/ruby/internal/arithmetic.h bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h bug.o: $(hdrdir)/ruby/internal/attr/noinline.h bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bug.o: $(hdrdir)/ruby/internal/attr/pure.h bug.o: $(hdrdir)/ruby/internal/attr/restrict.h bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h bug.o: $(hdrdir)/ruby/internal/intern/error.h bug.o: $(hdrdir)/ruby/internal/intern/eval.h bug.o: $(hdrdir)/ruby/internal/intern/file.h -bug.o: $(hdrdir)/ruby/internal/intern/gc.h bug.o: $(hdrdir)/ruby/internal/intern/hash.h bug.o: $(hdrdir)/ruby/internal/intern/io.h bug.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/re.h bug.o: $(hdrdir)/ruby/internal/intern/ruby.h bug.o: $(hdrdir)/ruby/internal/intern/select.h bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bug.o: $(hdrdir)/ruby/internal/intern/set.h bug.o: $(hdrdir)/ruby/internal/intern/signal.h bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h bug.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ bug.o: $(hdrdir)/ruby/internal/memory.h bug.o: $(hdrdir)/ruby/internal/method.h bug.o: $(hdrdir)/ruby/internal/module.h bug.o: $(hdrdir)/ruby/internal/newobj.h -bug.o: $(hdrdir)/ruby/internal/rgengc.h bug.o: $(hdrdir)/ruby/internal/scan_args.h bug.o: $(hdrdir)/ruby/internal/special_consts.h bug.o: $(hdrdir)/ruby/internal/static_assert.h bug.o: $(hdrdir)/ruby/internal/stdalign.h bug.o: $(hdrdir)/ruby/internal/stdbool.h +bug.o: $(hdrdir)/ruby/internal/stdckdint.h bug.o: $(hdrdir)/ruby/internal/symbol.h bug.o: $(hdrdir)/ruby/internal/value.h bug.o: $(hdrdir)/ruby/internal/value_type.h bug.o: $(hdrdir)/ruby/internal/variable.h bug.o: $(hdrdir)/ruby/internal/warning_push.h bug.o: $(hdrdir)/ruby/internal/xmalloc.h -bug.o: $(hdrdir)/ruby/assert.h -bug.o: $(hdrdir)/ruby/backward.h -bug.o: $(hdrdir)/ruby/backward/2/assume.h -bug.o: $(hdrdir)/ruby/backward/2/attributes.h -bug.o: $(hdrdir)/ruby/backward/2/bool.h -bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bug.o: $(hdrdir)/ruby/backward/2/inttypes.h -bug.o: $(hdrdir)/ruby/backward/2/limits.h -bug.o: $(hdrdir)/ruby/backward/2/long_long.h -bug.o: $(hdrdir)/ruby/backward/2/stdalign.h -bug.o: $(hdrdir)/ruby/backward/2/stdarg.h -bug.o: $(hdrdir)/ruby/defines.h -bug.o: $(hdrdir)/ruby/intern.h bug.o: $(hdrdir)/ruby/missing.h bug.o: $(hdrdir)/ruby/ruby.h bug.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/bug_reporter/depend b/ext/-test-/bug_reporter/depend index 0eadef5d82..e9993c3295 100644 --- a/ext/-test-/bug_reporter/depend +++ b/ext/-test-/bug_reporter/depend @@ -2,6 +2,19 @@ bug_reporter.o: $(RUBY_EXTCONF_H) bug_reporter.o: $(arch_hdrdir)/ruby/config.h bug_reporter.o: $(hdrdir)/ruby.h +bug_reporter.o: $(hdrdir)/ruby/assert.h +bug_reporter.o: $(hdrdir)/ruby/backward.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/assume.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/attributes.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/bool.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/inttypes.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/limits.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/long_long.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/stdalign.h +bug_reporter.o: $(hdrdir)/ruby/backward/2/stdarg.h +bug_reporter.o: $(hdrdir)/ruby/defines.h +bug_reporter.o: $(hdrdir)/ruby/intern.h +bug_reporter.o: $(hdrdir)/ruby/internal/abi.h bug_reporter.o: $(hdrdir)/ruby/internal/anyargs.h bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic.h bug_reporter.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ bug_reporter.o: $(hdrdir)/ruby/internal/attr/noexcept.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/noinline.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/nonnull.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bug_reporter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/pure.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/restrict.h bug_reporter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ bug_reporter.o: $(hdrdir)/ruby/internal/intern/enumerator.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/error.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/eval.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/file.h -bug_reporter.o: $(hdrdir)/ruby/internal/intern/gc.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/hash.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/io.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ bug_reporter.o: $(hdrdir)/ruby/internal/intern/re.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/ruby.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/select.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bug_reporter.o: $(hdrdir)/ruby/internal/intern/set.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/signal.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/sprintf.h bug_reporter.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ bug_reporter.o: $(hdrdir)/ruby/internal/memory.h bug_reporter.o: $(hdrdir)/ruby/internal/method.h bug_reporter.o: $(hdrdir)/ruby/internal/module.h bug_reporter.o: $(hdrdir)/ruby/internal/newobj.h -bug_reporter.o: $(hdrdir)/ruby/internal/rgengc.h bug_reporter.o: $(hdrdir)/ruby/internal/scan_args.h bug_reporter.o: $(hdrdir)/ruby/internal/special_consts.h bug_reporter.o: $(hdrdir)/ruby/internal/static_assert.h bug_reporter.o: $(hdrdir)/ruby/internal/stdalign.h bug_reporter.o: $(hdrdir)/ruby/internal/stdbool.h +bug_reporter.o: $(hdrdir)/ruby/internal/stdckdint.h bug_reporter.o: $(hdrdir)/ruby/internal/symbol.h bug_reporter.o: $(hdrdir)/ruby/internal/value.h bug_reporter.o: $(hdrdir)/ruby/internal/value_type.h bug_reporter.o: $(hdrdir)/ruby/internal/variable.h bug_reporter.o: $(hdrdir)/ruby/internal/warning_push.h bug_reporter.o: $(hdrdir)/ruby/internal/xmalloc.h -bug_reporter.o: $(hdrdir)/ruby/assert.h -bug_reporter.o: $(hdrdir)/ruby/backward.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/assume.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/attributes.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/bool.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/inttypes.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/limits.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/long_long.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/stdalign.h -bug_reporter.o: $(hdrdir)/ruby/backward/2/stdarg.h -bug_reporter.o: $(hdrdir)/ruby/defines.h -bug_reporter.o: $(hdrdir)/ruby/intern.h bug_reporter.o: $(hdrdir)/ruby/missing.h bug_reporter.o: $(hdrdir)/ruby/ruby.h bug_reporter.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/class/depend b/ext/-test-/class/depend index 69138c6175..557206cefb 100644 --- a/ext/-test-/class/depend +++ b/ext/-test-/class/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START class2name.o: $(RUBY_EXTCONF_H) class2name.o: $(arch_hdrdir)/ruby/config.h +class2name.o: $(hdrdir)/ruby/assert.h +class2name.o: $(hdrdir)/ruby/backward.h +class2name.o: $(hdrdir)/ruby/backward/2/assume.h +class2name.o: $(hdrdir)/ruby/backward/2/attributes.h +class2name.o: $(hdrdir)/ruby/backward/2/bool.h +class2name.o: $(hdrdir)/ruby/backward/2/inttypes.h +class2name.o: $(hdrdir)/ruby/backward/2/limits.h +class2name.o: $(hdrdir)/ruby/backward/2/long_long.h +class2name.o: $(hdrdir)/ruby/backward/2/stdalign.h +class2name.o: $(hdrdir)/ruby/backward/2/stdarg.h +class2name.o: $(hdrdir)/ruby/defines.h +class2name.o: $(hdrdir)/ruby/intern.h +class2name.o: $(hdrdir)/ruby/internal/abi.h class2name.o: $(hdrdir)/ruby/internal/anyargs.h class2name.o: $(hdrdir)/ruby/internal/arithmetic.h class2name.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ class2name.o: $(hdrdir)/ruby/internal/attr/noexcept.h class2name.o: $(hdrdir)/ruby/internal/attr/noinline.h class2name.o: $(hdrdir)/ruby/internal/attr/nonnull.h class2name.o: $(hdrdir)/ruby/internal/attr/noreturn.h +class2name.o: $(hdrdir)/ruby/internal/attr/packed_struct.h class2name.o: $(hdrdir)/ruby/internal/attr/pure.h class2name.o: $(hdrdir)/ruby/internal/attr/restrict.h class2name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ class2name.o: $(hdrdir)/ruby/internal/intern/enumerator.h class2name.o: $(hdrdir)/ruby/internal/intern/error.h class2name.o: $(hdrdir)/ruby/internal/intern/eval.h class2name.o: $(hdrdir)/ruby/internal/intern/file.h -class2name.o: $(hdrdir)/ruby/internal/intern/gc.h class2name.o: $(hdrdir)/ruby/internal/intern/hash.h class2name.o: $(hdrdir)/ruby/internal/intern/io.h class2name.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ class2name.o: $(hdrdir)/ruby/internal/intern/re.h class2name.o: $(hdrdir)/ruby/internal/intern/ruby.h class2name.o: $(hdrdir)/ruby/internal/intern/select.h class2name.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +class2name.o: $(hdrdir)/ruby/internal/intern/set.h class2name.o: $(hdrdir)/ruby/internal/intern/signal.h class2name.o: $(hdrdir)/ruby/internal/intern/sprintf.h class2name.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ class2name.o: $(hdrdir)/ruby/internal/memory.h class2name.o: $(hdrdir)/ruby/internal/method.h class2name.o: $(hdrdir)/ruby/internal/module.h class2name.o: $(hdrdir)/ruby/internal/newobj.h -class2name.o: $(hdrdir)/ruby/internal/rgengc.h class2name.o: $(hdrdir)/ruby/internal/scan_args.h class2name.o: $(hdrdir)/ruby/internal/special_consts.h class2name.o: $(hdrdir)/ruby/internal/static_assert.h class2name.o: $(hdrdir)/ruby/internal/stdalign.h class2name.o: $(hdrdir)/ruby/internal/stdbool.h +class2name.o: $(hdrdir)/ruby/internal/stdckdint.h class2name.o: $(hdrdir)/ruby/internal/symbol.h class2name.o: $(hdrdir)/ruby/internal/value.h class2name.o: $(hdrdir)/ruby/internal/value_type.h class2name.o: $(hdrdir)/ruby/internal/variable.h class2name.o: $(hdrdir)/ruby/internal/warning_push.h class2name.o: $(hdrdir)/ruby/internal/xmalloc.h -class2name.o: $(hdrdir)/ruby/assert.h -class2name.o: $(hdrdir)/ruby/backward.h -class2name.o: $(hdrdir)/ruby/backward/2/assume.h -class2name.o: $(hdrdir)/ruby/backward/2/attributes.h -class2name.o: $(hdrdir)/ruby/backward/2/bool.h -class2name.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -class2name.o: $(hdrdir)/ruby/backward/2/inttypes.h -class2name.o: $(hdrdir)/ruby/backward/2/limits.h -class2name.o: $(hdrdir)/ruby/backward/2/long_long.h -class2name.o: $(hdrdir)/ruby/backward/2/stdalign.h -class2name.o: $(hdrdir)/ruby/backward/2/stdarg.h -class2name.o: $(hdrdir)/ruby/defines.h -class2name.o: $(hdrdir)/ruby/intern.h class2name.o: $(hdrdir)/ruby/missing.h class2name.o: $(hdrdir)/ruby/ruby.h class2name.o: $(hdrdir)/ruby/st.h @@ -161,6 +162,19 @@ class2name.o: class2name.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -198,6 +212,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -257,7 +272,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -274,6 +288,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -288,31 +303,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/class/init.c b/ext/-test-/class/init.c index ed715c1942..108ff7525c 100644 --- a/ext/-test-/class/init.c +++ b/ext/-test-/class/init.c @@ -7,5 +7,6 @@ Init_class(void) { VALUE mBug = rb_define_module("Bug"); VALUE mod = rb_define_module_under(mBug, "Class"); + rb_define_class_under(mod, "TestClassDefinedInC", rb_cObject); TEST_INIT_FUNCS(init); } diff --git a/ext/-test-/cxxanyargs/cxxanyargs.cpp b/ext/-test-/cxxanyargs/cxxanyargs.cpp index eded13e2ee..c7df7f9038 100644 --- a/ext/-test-/cxxanyargs/cxxanyargs.cpp +++ b/ext/-test-/cxxanyargs/cxxanyargs.cpp @@ -97,31 +97,6 @@ struct test_rb_define_hooked_variable { }; VALUE test_rb_define_hooked_variable::v = Qundef; -namespace test_rb_iterate { - VALUE - iter(VALUE self) - { - return rb_funcall(self, rb_intern("yield"), 0); - } - - VALUE - block(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param)) - { - return rb_funcall(arg, rb_intern("=="), 1, param); - } - - VALUE - test(VALUE self) - { -#ifdef HAVE_NULLPTR - rb_iterate(iter, self, nullptr, self); -#endif - - rb_iterate(iter, self, RUBY_METHOD_FUNC(block), self); // old - return rb_iterate(iter, self, block, self); // new - } -} - namespace test_rb_block_call { VALUE block(RB_BLOCK_CALL_FUNC_ARGLIST(arg, param)) @@ -936,7 +911,6 @@ Init_cxxanyargs(void) test(rb_define_virtual_variable); test(rb_define_hooked_variable); - test(rb_iterate); test(rb_block_call); test(rb_rescue); test(rb_rescue2); diff --git a/ext/-test-/cxxanyargs/depend b/ext/-test-/cxxanyargs/depend index ca821409a2..fc3d8e45d9 100644 --- a/ext/-test-/cxxanyargs/depend +++ b/ext/-test-/cxxanyargs/depend @@ -10,16 +10,4 @@ $(TARGET_SO) $(STATIC_LIB): $(FAILURES:.cpp=.failed) -e "File.write(t, err)" $@ $(MAKE) $(*F).o # AUTOGENERATED DEPENDENCIES START -cxxanyargs.o: $(RUBY_EXTCONF_H) -cxxanyargs.o: $(arch_hdrdir)/ruby/config.h -cxxanyargs.o: $(hdrdir)/ruby/assert.h -cxxanyargs.o: $(hdrdir)/ruby/backward.h -cxxanyargs.o: $(hdrdir)/ruby/backward/cxxanyargs.hpp -cxxanyargs.o: $(hdrdir)/ruby/defines.h -cxxanyargs.o: $(hdrdir)/ruby/intern.h -cxxanyargs.o: $(hdrdir)/ruby/missing.h -cxxanyargs.o: $(hdrdir)/ruby/ruby.h -cxxanyargs.o: $(hdrdir)/ruby/st.h -cxxanyargs.o: $(hdrdir)/ruby/subst.h -cxxanyargs.o: cxxanyargs.cpp # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/debug/depend b/ext/-test-/debug/depend index 6c1c736d61..4ae0378ef2 100644 --- a/ext/-test-/debug/depend +++ b/ext/-test-/debug/depend @@ -2,6 +2,19 @@ init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -161,6 +162,20 @@ init.o: $(hdrdir)/ruby/subst.h init.o: init.c inspector.o: $(RUBY_EXTCONF_H) inspector.o: $(arch_hdrdir)/ruby/config.h +inspector.o: $(hdrdir)/ruby/assert.h +inspector.o: $(hdrdir)/ruby/backward.h +inspector.o: $(hdrdir)/ruby/backward/2/assume.h +inspector.o: $(hdrdir)/ruby/backward/2/attributes.h +inspector.o: $(hdrdir)/ruby/backward/2/bool.h +inspector.o: $(hdrdir)/ruby/backward/2/inttypes.h +inspector.o: $(hdrdir)/ruby/backward/2/limits.h +inspector.o: $(hdrdir)/ruby/backward/2/long_long.h +inspector.o: $(hdrdir)/ruby/backward/2/stdalign.h +inspector.o: $(hdrdir)/ruby/backward/2/stdarg.h +inspector.o: $(hdrdir)/ruby/debug.h +inspector.o: $(hdrdir)/ruby/defines.h +inspector.o: $(hdrdir)/ruby/intern.h +inspector.o: $(hdrdir)/ruby/internal/abi.h inspector.o: $(hdrdir)/ruby/internal/anyargs.h inspector.o: $(hdrdir)/ruby/internal/arithmetic.h inspector.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -198,6 +213,7 @@ inspector.o: $(hdrdir)/ruby/internal/attr/noexcept.h inspector.o: $(hdrdir)/ruby/internal/attr/noinline.h inspector.o: $(hdrdir)/ruby/internal/attr/nonnull.h inspector.o: $(hdrdir)/ruby/internal/attr/noreturn.h +inspector.o: $(hdrdir)/ruby/internal/attr/packed_struct.h inspector.o: $(hdrdir)/ruby/internal/attr/pure.h inspector.o: $(hdrdir)/ruby/internal/attr/restrict.h inspector.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -257,7 +273,6 @@ inspector.o: $(hdrdir)/ruby/internal/intern/enumerator.h inspector.o: $(hdrdir)/ruby/internal/intern/error.h inspector.o: $(hdrdir)/ruby/internal/intern/eval.h inspector.o: $(hdrdir)/ruby/internal/intern/file.h -inspector.o: $(hdrdir)/ruby/internal/intern/gc.h inspector.o: $(hdrdir)/ruby/internal/intern/hash.h inspector.o: $(hdrdir)/ruby/internal/intern/io.h inspector.o: $(hdrdir)/ruby/internal/intern/load.h @@ -274,6 +289,7 @@ inspector.o: $(hdrdir)/ruby/internal/intern/re.h inspector.o: $(hdrdir)/ruby/internal/intern/ruby.h inspector.o: $(hdrdir)/ruby/internal/intern/select.h inspector.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +inspector.o: $(hdrdir)/ruby/internal/intern/set.h inspector.o: $(hdrdir)/ruby/internal/intern/signal.h inspector.o: $(hdrdir)/ruby/internal/intern/sprintf.h inspector.o: $(hdrdir)/ruby/internal/intern/string.h @@ -288,32 +304,18 @@ inspector.o: $(hdrdir)/ruby/internal/memory.h inspector.o: $(hdrdir)/ruby/internal/method.h inspector.o: $(hdrdir)/ruby/internal/module.h inspector.o: $(hdrdir)/ruby/internal/newobj.h -inspector.o: $(hdrdir)/ruby/internal/rgengc.h inspector.o: $(hdrdir)/ruby/internal/scan_args.h inspector.o: $(hdrdir)/ruby/internal/special_consts.h inspector.o: $(hdrdir)/ruby/internal/static_assert.h inspector.o: $(hdrdir)/ruby/internal/stdalign.h inspector.o: $(hdrdir)/ruby/internal/stdbool.h +inspector.o: $(hdrdir)/ruby/internal/stdckdint.h inspector.o: $(hdrdir)/ruby/internal/symbol.h inspector.o: $(hdrdir)/ruby/internal/value.h inspector.o: $(hdrdir)/ruby/internal/value_type.h inspector.o: $(hdrdir)/ruby/internal/variable.h inspector.o: $(hdrdir)/ruby/internal/warning_push.h inspector.o: $(hdrdir)/ruby/internal/xmalloc.h -inspector.o: $(hdrdir)/ruby/assert.h -inspector.o: $(hdrdir)/ruby/backward.h -inspector.o: $(hdrdir)/ruby/backward/2/assume.h -inspector.o: $(hdrdir)/ruby/backward/2/attributes.h -inspector.o: $(hdrdir)/ruby/backward/2/bool.h -inspector.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -inspector.o: $(hdrdir)/ruby/backward/2/inttypes.h -inspector.o: $(hdrdir)/ruby/backward/2/limits.h -inspector.o: $(hdrdir)/ruby/backward/2/long_long.h -inspector.o: $(hdrdir)/ruby/backward/2/stdalign.h -inspector.o: $(hdrdir)/ruby/backward/2/stdarg.h -inspector.o: $(hdrdir)/ruby/debug.h -inspector.o: $(hdrdir)/ruby/defines.h -inspector.o: $(hdrdir)/ruby/intern.h inspector.o: $(hdrdir)/ruby/missing.h inspector.o: $(hdrdir)/ruby/ruby.h inspector.o: $(hdrdir)/ruby/st.h @@ -321,6 +323,20 @@ inspector.o: $(hdrdir)/ruby/subst.h inspector.o: inspector.c profile_frames.o: $(RUBY_EXTCONF_H) profile_frames.o: $(arch_hdrdir)/ruby/config.h +profile_frames.o: $(hdrdir)/ruby/assert.h +profile_frames.o: $(hdrdir)/ruby/backward.h +profile_frames.o: $(hdrdir)/ruby/backward/2/assume.h +profile_frames.o: $(hdrdir)/ruby/backward/2/attributes.h +profile_frames.o: $(hdrdir)/ruby/backward/2/bool.h +profile_frames.o: $(hdrdir)/ruby/backward/2/inttypes.h +profile_frames.o: $(hdrdir)/ruby/backward/2/limits.h +profile_frames.o: $(hdrdir)/ruby/backward/2/long_long.h +profile_frames.o: $(hdrdir)/ruby/backward/2/stdalign.h +profile_frames.o: $(hdrdir)/ruby/backward/2/stdarg.h +profile_frames.o: $(hdrdir)/ruby/debug.h +profile_frames.o: $(hdrdir)/ruby/defines.h +profile_frames.o: $(hdrdir)/ruby/intern.h +profile_frames.o: $(hdrdir)/ruby/internal/abi.h profile_frames.o: $(hdrdir)/ruby/internal/anyargs.h profile_frames.o: $(hdrdir)/ruby/internal/arithmetic.h profile_frames.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -358,6 +374,7 @@ profile_frames.o: $(hdrdir)/ruby/internal/attr/noexcept.h profile_frames.o: $(hdrdir)/ruby/internal/attr/noinline.h profile_frames.o: $(hdrdir)/ruby/internal/attr/nonnull.h profile_frames.o: $(hdrdir)/ruby/internal/attr/noreturn.h +profile_frames.o: $(hdrdir)/ruby/internal/attr/packed_struct.h profile_frames.o: $(hdrdir)/ruby/internal/attr/pure.h profile_frames.o: $(hdrdir)/ruby/internal/attr/restrict.h profile_frames.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -417,7 +434,6 @@ profile_frames.o: $(hdrdir)/ruby/internal/intern/enumerator.h profile_frames.o: $(hdrdir)/ruby/internal/intern/error.h profile_frames.o: $(hdrdir)/ruby/internal/intern/eval.h profile_frames.o: $(hdrdir)/ruby/internal/intern/file.h -profile_frames.o: $(hdrdir)/ruby/internal/intern/gc.h profile_frames.o: $(hdrdir)/ruby/internal/intern/hash.h profile_frames.o: $(hdrdir)/ruby/internal/intern/io.h profile_frames.o: $(hdrdir)/ruby/internal/intern/load.h @@ -434,6 +450,7 @@ profile_frames.o: $(hdrdir)/ruby/internal/intern/re.h profile_frames.o: $(hdrdir)/ruby/internal/intern/ruby.h profile_frames.o: $(hdrdir)/ruby/internal/intern/select.h profile_frames.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +profile_frames.o: $(hdrdir)/ruby/internal/intern/set.h profile_frames.o: $(hdrdir)/ruby/internal/intern/signal.h profile_frames.o: $(hdrdir)/ruby/internal/intern/sprintf.h profile_frames.o: $(hdrdir)/ruby/internal/intern/string.h @@ -448,32 +465,18 @@ profile_frames.o: $(hdrdir)/ruby/internal/memory.h profile_frames.o: $(hdrdir)/ruby/internal/method.h profile_frames.o: $(hdrdir)/ruby/internal/module.h profile_frames.o: $(hdrdir)/ruby/internal/newobj.h -profile_frames.o: $(hdrdir)/ruby/internal/rgengc.h profile_frames.o: $(hdrdir)/ruby/internal/scan_args.h profile_frames.o: $(hdrdir)/ruby/internal/special_consts.h profile_frames.o: $(hdrdir)/ruby/internal/static_assert.h profile_frames.o: $(hdrdir)/ruby/internal/stdalign.h profile_frames.o: $(hdrdir)/ruby/internal/stdbool.h +profile_frames.o: $(hdrdir)/ruby/internal/stdckdint.h profile_frames.o: $(hdrdir)/ruby/internal/symbol.h profile_frames.o: $(hdrdir)/ruby/internal/value.h profile_frames.o: $(hdrdir)/ruby/internal/value_type.h profile_frames.o: $(hdrdir)/ruby/internal/variable.h profile_frames.o: $(hdrdir)/ruby/internal/warning_push.h profile_frames.o: $(hdrdir)/ruby/internal/xmalloc.h -profile_frames.o: $(hdrdir)/ruby/assert.h -profile_frames.o: $(hdrdir)/ruby/backward.h -profile_frames.o: $(hdrdir)/ruby/backward/2/assume.h -profile_frames.o: $(hdrdir)/ruby/backward/2/attributes.h -profile_frames.o: $(hdrdir)/ruby/backward/2/bool.h -profile_frames.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -profile_frames.o: $(hdrdir)/ruby/backward/2/inttypes.h -profile_frames.o: $(hdrdir)/ruby/backward/2/limits.h -profile_frames.o: $(hdrdir)/ruby/backward/2/long_long.h -profile_frames.o: $(hdrdir)/ruby/backward/2/stdalign.h -profile_frames.o: $(hdrdir)/ruby/backward/2/stdarg.h -profile_frames.o: $(hdrdir)/ruby/debug.h -profile_frames.o: $(hdrdir)/ruby/defines.h -profile_frames.o: $(hdrdir)/ruby/intern.h profile_frames.o: $(hdrdir)/ruby/missing.h profile_frames.o: $(hdrdir)/ruby/ruby.h profile_frames.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/debug/inspector.c b/ext/-test-/debug/inspector.c index f0c58e59f9..25f9d894d3 100644 --- a/ext/-test-/debug/inspector.c +++ b/ext/-test-/debug/inspector.c @@ -8,13 +8,13 @@ callback(const rb_debug_inspector_t *dbg_context, void *data) long i, len = RARRAY_LEN(locs); VALUE binds = rb_ary_new(); for (i = 0; i < len; ++i) { - VALUE entry = rb_ary_new(); - rb_ary_push(binds, entry); - rb_ary_push(entry, rb_debug_inspector_frame_self_get(dbg_context, i)); - rb_ary_push(entry, rb_debug_inspector_frame_binding_get(dbg_context, i)); - rb_ary_push(entry, rb_debug_inspector_frame_class_get(dbg_context, i)); - rb_ary_push(entry, rb_debug_inspector_frame_iseq_get(dbg_context, i)); - rb_ary_push(entry, rb_ary_entry(locs, i)); + VALUE entry = rb_ary_new(); + rb_ary_push(binds, entry); + rb_ary_push(entry, rb_debug_inspector_frame_self_get(dbg_context, i)); + rb_ary_push(entry, rb_debug_inspector_frame_binding_get(dbg_context, i)); + rb_ary_push(entry, rb_debug_inspector_frame_class_get(dbg_context, i)); + rb_ary_push(entry, rb_debug_inspector_frame_iseq_get(dbg_context, i)); + rb_ary_push(entry, rb_ary_entry(locs, i)); } return binds; } diff --git a/ext/-test-/debug/profile_frames.c b/ext/-test-/debug/profile_frames.c index 1656ff7d4b..f9a77a5a78 100644 --- a/ext/-test-/debug/profile_frames.c +++ b/ext/-test-/debug/profile_frames.c @@ -18,19 +18,40 @@ profile_frames(VALUE self, VALUE start_v, VALUE num_v) collected_size = rb_profile_frames(start, buff_size, buff, lines); for (i=0; i<collected_size; i++) { - VALUE ary = rb_ary_new(); - rb_ary_push(ary, rb_profile_frame_path(buff[i])); - rb_ary_push(ary, rb_profile_frame_absolute_path(buff[i])); - rb_ary_push(ary, rb_profile_frame_label(buff[i])); - rb_ary_push(ary, rb_profile_frame_base_label(buff[i])); - rb_ary_push(ary, rb_profile_frame_full_label(buff[i])); - rb_ary_push(ary, rb_profile_frame_first_lineno(buff[i])); - rb_ary_push(ary, rb_profile_frame_classpath(buff[i])); - rb_ary_push(ary, rb_profile_frame_singleton_method_p(buff[i])); - rb_ary_push(ary, rb_profile_frame_method_name(buff[i])); - rb_ary_push(ary, rb_profile_frame_qualified_method_name(buff[i])); - - rb_ary_push(result, ary); + VALUE ary = rb_ary_new(); + rb_ary_push(ary, rb_profile_frame_path(buff[i])); + rb_ary_push(ary, rb_profile_frame_absolute_path(buff[i])); + rb_ary_push(ary, rb_profile_frame_label(buff[i])); + rb_ary_push(ary, rb_profile_frame_base_label(buff[i])); + rb_ary_push(ary, rb_profile_frame_full_label(buff[i])); + rb_ary_push(ary, rb_profile_frame_first_lineno(buff[i])); + rb_ary_push(ary, rb_profile_frame_classpath(buff[i])); + rb_ary_push(ary, rb_profile_frame_singleton_method_p(buff[i])); + rb_ary_push(ary, rb_profile_frame_method_name(buff[i])); + rb_ary_push(ary, rb_profile_frame_qualified_method_name(buff[i])); + rb_ary_push(ary, INT2NUM(lines[i])); + + rb_ary_push(result, ary); + } + + return result; +} + +static VALUE +profile_thread_frames(VALUE self, VALUE thread, VALUE start_v, VALUE num_v) +{ + int i, collected_size; + int start = NUM2INT(start_v); + int buff_size = NUM2INT(num_v); + VALUE buff[MAX_BUF_SIZE]; + int lines[MAX_BUF_SIZE]; + VALUE result = rb_ary_new(); + + if (buff_size > MAX_BUF_SIZE) rb_raise(rb_eRuntimeError, "too long buff_size"); + + collected_size = rb_profile_thread_frames(thread, start, buff_size, buff, lines); + for (i=0; i<collected_size; i++) { + rb_ary_push(result, rb_profile_frame_full_label(buff[i])); } return result; @@ -40,4 +61,5 @@ void Init_profile_frames(VALUE klass) { rb_define_module_function(klass, "profile_frames", profile_frames, 2); + rb_define_module_function(klass, "profile_thread_frames", profile_thread_frames, 3); } diff --git a/ext/-test-/dln/empty/depend b/ext/-test-/dln/empty/depend index 99151fa055..58f1508598 100644 --- a/ext/-test-/dln/empty/depend +++ b/ext/-test-/dln/empty/depend @@ -1,3 +1,163 @@ # AUTOGENERATED DEPENDENCIES START +empty.o: $(RUBY_EXTCONF_H) +empty.o: $(arch_hdrdir)/ruby/config.h +empty.o: $(hdrdir)/ruby.h +empty.o: $(hdrdir)/ruby/assert.h +empty.o: $(hdrdir)/ruby/backward.h +empty.o: $(hdrdir)/ruby/backward/2/assume.h +empty.o: $(hdrdir)/ruby/backward/2/attributes.h +empty.o: $(hdrdir)/ruby/backward/2/bool.h +empty.o: $(hdrdir)/ruby/backward/2/inttypes.h +empty.o: $(hdrdir)/ruby/backward/2/limits.h +empty.o: $(hdrdir)/ruby/backward/2/long_long.h +empty.o: $(hdrdir)/ruby/backward/2/stdalign.h +empty.o: $(hdrdir)/ruby/backward/2/stdarg.h +empty.o: $(hdrdir)/ruby/defines.h +empty.o: $(hdrdir)/ruby/intern.h +empty.o: $(hdrdir)/ruby/internal/abi.h +empty.o: $(hdrdir)/ruby/internal/anyargs.h +empty.o: $(hdrdir)/ruby/internal/arithmetic.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/char.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/double.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/int.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/long.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/short.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +empty.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +empty.o: $(hdrdir)/ruby/internal/assume.h +empty.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +empty.o: $(hdrdir)/ruby/internal/attr/artificial.h +empty.o: $(hdrdir)/ruby/internal/attr/cold.h +empty.o: $(hdrdir)/ruby/internal/attr/const.h +empty.o: $(hdrdir)/ruby/internal/attr/constexpr.h +empty.o: $(hdrdir)/ruby/internal/attr/deprecated.h +empty.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +empty.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +empty.o: $(hdrdir)/ruby/internal/attr/error.h +empty.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +empty.o: $(hdrdir)/ruby/internal/attr/forceinline.h +empty.o: $(hdrdir)/ruby/internal/attr/format.h +empty.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +empty.o: $(hdrdir)/ruby/internal/attr/noalias.h +empty.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +empty.o: $(hdrdir)/ruby/internal/attr/noexcept.h +empty.o: $(hdrdir)/ruby/internal/attr/noinline.h +empty.o: $(hdrdir)/ruby/internal/attr/nonnull.h +empty.o: $(hdrdir)/ruby/internal/attr/noreturn.h +empty.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +empty.o: $(hdrdir)/ruby/internal/attr/pure.h +empty.o: $(hdrdir)/ruby/internal/attr/restrict.h +empty.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +empty.o: $(hdrdir)/ruby/internal/attr/warning.h +empty.o: $(hdrdir)/ruby/internal/attr/weakref.h +empty.o: $(hdrdir)/ruby/internal/cast.h +empty.o: $(hdrdir)/ruby/internal/compiler_is.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +empty.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +empty.o: $(hdrdir)/ruby/internal/compiler_since.h +empty.o: $(hdrdir)/ruby/internal/config.h +empty.o: $(hdrdir)/ruby/internal/constant_p.h +empty.o: $(hdrdir)/ruby/internal/core.h +empty.o: $(hdrdir)/ruby/internal/core/rarray.h +empty.o: $(hdrdir)/ruby/internal/core/rbasic.h +empty.o: $(hdrdir)/ruby/internal/core/rbignum.h +empty.o: $(hdrdir)/ruby/internal/core/rclass.h +empty.o: $(hdrdir)/ruby/internal/core/rdata.h +empty.o: $(hdrdir)/ruby/internal/core/rfile.h +empty.o: $(hdrdir)/ruby/internal/core/rhash.h +empty.o: $(hdrdir)/ruby/internal/core/robject.h +empty.o: $(hdrdir)/ruby/internal/core/rregexp.h +empty.o: $(hdrdir)/ruby/internal/core/rstring.h +empty.o: $(hdrdir)/ruby/internal/core/rstruct.h +empty.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +empty.o: $(hdrdir)/ruby/internal/ctype.h +empty.o: $(hdrdir)/ruby/internal/dllexport.h +empty.o: $(hdrdir)/ruby/internal/dosish.h +empty.o: $(hdrdir)/ruby/internal/error.h +empty.o: $(hdrdir)/ruby/internal/eval.h +empty.o: $(hdrdir)/ruby/internal/event.h +empty.o: $(hdrdir)/ruby/internal/fl_type.h +empty.o: $(hdrdir)/ruby/internal/gc.h +empty.o: $(hdrdir)/ruby/internal/glob.h +empty.o: $(hdrdir)/ruby/internal/globals.h +empty.o: $(hdrdir)/ruby/internal/has/attribute.h +empty.o: $(hdrdir)/ruby/internal/has/builtin.h +empty.o: $(hdrdir)/ruby/internal/has/c_attribute.h +empty.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +empty.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +empty.o: $(hdrdir)/ruby/internal/has/extension.h +empty.o: $(hdrdir)/ruby/internal/has/feature.h +empty.o: $(hdrdir)/ruby/internal/has/warning.h +empty.o: $(hdrdir)/ruby/internal/intern/array.h +empty.o: $(hdrdir)/ruby/internal/intern/bignum.h +empty.o: $(hdrdir)/ruby/internal/intern/class.h +empty.o: $(hdrdir)/ruby/internal/intern/compar.h +empty.o: $(hdrdir)/ruby/internal/intern/complex.h +empty.o: $(hdrdir)/ruby/internal/intern/cont.h +empty.o: $(hdrdir)/ruby/internal/intern/dir.h +empty.o: $(hdrdir)/ruby/internal/intern/enum.h +empty.o: $(hdrdir)/ruby/internal/intern/enumerator.h +empty.o: $(hdrdir)/ruby/internal/intern/error.h +empty.o: $(hdrdir)/ruby/internal/intern/eval.h +empty.o: $(hdrdir)/ruby/internal/intern/file.h +empty.o: $(hdrdir)/ruby/internal/intern/hash.h +empty.o: $(hdrdir)/ruby/internal/intern/io.h +empty.o: $(hdrdir)/ruby/internal/intern/load.h +empty.o: $(hdrdir)/ruby/internal/intern/marshal.h +empty.o: $(hdrdir)/ruby/internal/intern/numeric.h +empty.o: $(hdrdir)/ruby/internal/intern/object.h +empty.o: $(hdrdir)/ruby/internal/intern/parse.h +empty.o: $(hdrdir)/ruby/internal/intern/proc.h +empty.o: $(hdrdir)/ruby/internal/intern/process.h +empty.o: $(hdrdir)/ruby/internal/intern/random.h +empty.o: $(hdrdir)/ruby/internal/intern/range.h +empty.o: $(hdrdir)/ruby/internal/intern/rational.h +empty.o: $(hdrdir)/ruby/internal/intern/re.h +empty.o: $(hdrdir)/ruby/internal/intern/ruby.h +empty.o: $(hdrdir)/ruby/internal/intern/select.h +empty.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +empty.o: $(hdrdir)/ruby/internal/intern/set.h +empty.o: $(hdrdir)/ruby/internal/intern/signal.h +empty.o: $(hdrdir)/ruby/internal/intern/sprintf.h +empty.o: $(hdrdir)/ruby/internal/intern/string.h +empty.o: $(hdrdir)/ruby/internal/intern/struct.h +empty.o: $(hdrdir)/ruby/internal/intern/thread.h +empty.o: $(hdrdir)/ruby/internal/intern/time.h +empty.o: $(hdrdir)/ruby/internal/intern/variable.h +empty.o: $(hdrdir)/ruby/internal/intern/vm.h +empty.o: $(hdrdir)/ruby/internal/interpreter.h +empty.o: $(hdrdir)/ruby/internal/iterator.h +empty.o: $(hdrdir)/ruby/internal/memory.h +empty.o: $(hdrdir)/ruby/internal/method.h +empty.o: $(hdrdir)/ruby/internal/module.h +empty.o: $(hdrdir)/ruby/internal/newobj.h +empty.o: $(hdrdir)/ruby/internal/scan_args.h +empty.o: $(hdrdir)/ruby/internal/special_consts.h +empty.o: $(hdrdir)/ruby/internal/static_assert.h +empty.o: $(hdrdir)/ruby/internal/stdalign.h +empty.o: $(hdrdir)/ruby/internal/stdbool.h +empty.o: $(hdrdir)/ruby/internal/stdckdint.h +empty.o: $(hdrdir)/ruby/internal/symbol.h +empty.o: $(hdrdir)/ruby/internal/value.h +empty.o: $(hdrdir)/ruby/internal/value_type.h +empty.o: $(hdrdir)/ruby/internal/variable.h +empty.o: $(hdrdir)/ruby/internal/warning_push.h +empty.o: $(hdrdir)/ruby/internal/xmalloc.h +empty.o: $(hdrdir)/ruby/missing.h +empty.o: $(hdrdir)/ruby/ruby.h +empty.o: $(hdrdir)/ruby/st.h +empty.o: $(hdrdir)/ruby/subst.h empty.o: empty.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/dln/empty/empty.c b/ext/-test-/dln/empty/empty.c index c4f94f1644..2b4fd42cd2 100644 --- a/ext/-test-/dln/empty/empty.c +++ b/ext/-test-/dln/empty/empty.c @@ -1,3 +1,5 @@ +#include "ruby.h" + void Init_empty(void) { diff --git a/ext/-test-/econv/append.c b/ext/-test-/econv/append.c new file mode 100644 index 0000000000..eb473c47a3 --- /dev/null +++ b/ext/-test-/econv/append.c @@ -0,0 +1,17 @@ +#include "ruby/ruby.h" +#include "ruby/encoding.h" + +static VALUE +econv_append(VALUE self, VALUE src, VALUE dst) +{ + rb_econv_t *ec = DATA_PTR(self); + StringValue(src); + StringValue(dst); + return rb_econv_str_append(ec, src, dst, 0); +} + +void +Init_econv_append(VALUE klass) +{ + rb_define_method(klass, "append", econv_append, 2); +} diff --git a/ext/-test-/econv/depend b/ext/-test-/econv/depend new file mode 100644 index 0000000000..3a5bc9c659 --- /dev/null +++ b/ext/-test-/econv/depend @@ -0,0 +1,336 @@ +# AUTOGENERATED DEPENDENCIES START +append.o: $(RUBY_EXTCONF_H) +append.o: $(arch_hdrdir)/ruby/config.h +append.o: $(hdrdir)/ruby.h +append.o: $(hdrdir)/ruby/assert.h +append.o: $(hdrdir)/ruby/backward.h +append.o: $(hdrdir)/ruby/backward/2/assume.h +append.o: $(hdrdir)/ruby/backward/2/attributes.h +append.o: $(hdrdir)/ruby/backward/2/bool.h +append.o: $(hdrdir)/ruby/backward/2/inttypes.h +append.o: $(hdrdir)/ruby/backward/2/limits.h +append.o: $(hdrdir)/ruby/backward/2/long_long.h +append.o: $(hdrdir)/ruby/backward/2/stdalign.h +append.o: $(hdrdir)/ruby/backward/2/stdarg.h +append.o: $(hdrdir)/ruby/defines.h +append.o: $(hdrdir)/ruby/encoding.h +append.o: $(hdrdir)/ruby/intern.h +append.o: $(hdrdir)/ruby/internal/abi.h +append.o: $(hdrdir)/ruby/internal/anyargs.h +append.o: $(hdrdir)/ruby/internal/arithmetic.h +append.o: $(hdrdir)/ruby/internal/arithmetic/char.h +append.o: $(hdrdir)/ruby/internal/arithmetic/double.h +append.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +append.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/int.h +append.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/long.h +append.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +append.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/short.h +append.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +append.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +append.o: $(hdrdir)/ruby/internal/assume.h +append.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +append.o: $(hdrdir)/ruby/internal/attr/artificial.h +append.o: $(hdrdir)/ruby/internal/attr/cold.h +append.o: $(hdrdir)/ruby/internal/attr/const.h +append.o: $(hdrdir)/ruby/internal/attr/constexpr.h +append.o: $(hdrdir)/ruby/internal/attr/deprecated.h +append.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +append.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +append.o: $(hdrdir)/ruby/internal/attr/error.h +append.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +append.o: $(hdrdir)/ruby/internal/attr/forceinline.h +append.o: $(hdrdir)/ruby/internal/attr/format.h +append.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +append.o: $(hdrdir)/ruby/internal/attr/noalias.h +append.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +append.o: $(hdrdir)/ruby/internal/attr/noexcept.h +append.o: $(hdrdir)/ruby/internal/attr/noinline.h +append.o: $(hdrdir)/ruby/internal/attr/nonnull.h +append.o: $(hdrdir)/ruby/internal/attr/noreturn.h +append.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +append.o: $(hdrdir)/ruby/internal/attr/pure.h +append.o: $(hdrdir)/ruby/internal/attr/restrict.h +append.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +append.o: $(hdrdir)/ruby/internal/attr/warning.h +append.o: $(hdrdir)/ruby/internal/attr/weakref.h +append.o: $(hdrdir)/ruby/internal/cast.h +append.o: $(hdrdir)/ruby/internal/compiler_is.h +append.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +append.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +append.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +append.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +append.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +append.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +append.o: $(hdrdir)/ruby/internal/compiler_since.h +append.o: $(hdrdir)/ruby/internal/config.h +append.o: $(hdrdir)/ruby/internal/constant_p.h +append.o: $(hdrdir)/ruby/internal/core.h +append.o: $(hdrdir)/ruby/internal/core/rarray.h +append.o: $(hdrdir)/ruby/internal/core/rbasic.h +append.o: $(hdrdir)/ruby/internal/core/rbignum.h +append.o: $(hdrdir)/ruby/internal/core/rclass.h +append.o: $(hdrdir)/ruby/internal/core/rdata.h +append.o: $(hdrdir)/ruby/internal/core/rfile.h +append.o: $(hdrdir)/ruby/internal/core/rhash.h +append.o: $(hdrdir)/ruby/internal/core/robject.h +append.o: $(hdrdir)/ruby/internal/core/rregexp.h +append.o: $(hdrdir)/ruby/internal/core/rstring.h +append.o: $(hdrdir)/ruby/internal/core/rstruct.h +append.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +append.o: $(hdrdir)/ruby/internal/ctype.h +append.o: $(hdrdir)/ruby/internal/dllexport.h +append.o: $(hdrdir)/ruby/internal/dosish.h +append.o: $(hdrdir)/ruby/internal/encoding/coderange.h +append.o: $(hdrdir)/ruby/internal/encoding/ctype.h +append.o: $(hdrdir)/ruby/internal/encoding/encoding.h +append.o: $(hdrdir)/ruby/internal/encoding/pathname.h +append.o: $(hdrdir)/ruby/internal/encoding/re.h +append.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +append.o: $(hdrdir)/ruby/internal/encoding/string.h +append.o: $(hdrdir)/ruby/internal/encoding/symbol.h +append.o: $(hdrdir)/ruby/internal/encoding/transcode.h +append.o: $(hdrdir)/ruby/internal/error.h +append.o: $(hdrdir)/ruby/internal/eval.h +append.o: $(hdrdir)/ruby/internal/event.h +append.o: $(hdrdir)/ruby/internal/fl_type.h +append.o: $(hdrdir)/ruby/internal/gc.h +append.o: $(hdrdir)/ruby/internal/glob.h +append.o: $(hdrdir)/ruby/internal/globals.h +append.o: $(hdrdir)/ruby/internal/has/attribute.h +append.o: $(hdrdir)/ruby/internal/has/builtin.h +append.o: $(hdrdir)/ruby/internal/has/c_attribute.h +append.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +append.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +append.o: $(hdrdir)/ruby/internal/has/extension.h +append.o: $(hdrdir)/ruby/internal/has/feature.h +append.o: $(hdrdir)/ruby/internal/has/warning.h +append.o: $(hdrdir)/ruby/internal/intern/array.h +append.o: $(hdrdir)/ruby/internal/intern/bignum.h +append.o: $(hdrdir)/ruby/internal/intern/class.h +append.o: $(hdrdir)/ruby/internal/intern/compar.h +append.o: $(hdrdir)/ruby/internal/intern/complex.h +append.o: $(hdrdir)/ruby/internal/intern/cont.h +append.o: $(hdrdir)/ruby/internal/intern/dir.h +append.o: $(hdrdir)/ruby/internal/intern/enum.h +append.o: $(hdrdir)/ruby/internal/intern/enumerator.h +append.o: $(hdrdir)/ruby/internal/intern/error.h +append.o: $(hdrdir)/ruby/internal/intern/eval.h +append.o: $(hdrdir)/ruby/internal/intern/file.h +append.o: $(hdrdir)/ruby/internal/intern/hash.h +append.o: $(hdrdir)/ruby/internal/intern/io.h +append.o: $(hdrdir)/ruby/internal/intern/load.h +append.o: $(hdrdir)/ruby/internal/intern/marshal.h +append.o: $(hdrdir)/ruby/internal/intern/numeric.h +append.o: $(hdrdir)/ruby/internal/intern/object.h +append.o: $(hdrdir)/ruby/internal/intern/parse.h +append.o: $(hdrdir)/ruby/internal/intern/proc.h +append.o: $(hdrdir)/ruby/internal/intern/process.h +append.o: $(hdrdir)/ruby/internal/intern/random.h +append.o: $(hdrdir)/ruby/internal/intern/range.h +append.o: $(hdrdir)/ruby/internal/intern/rational.h +append.o: $(hdrdir)/ruby/internal/intern/re.h +append.o: $(hdrdir)/ruby/internal/intern/ruby.h +append.o: $(hdrdir)/ruby/internal/intern/select.h +append.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +append.o: $(hdrdir)/ruby/internal/intern/set.h +append.o: $(hdrdir)/ruby/internal/intern/signal.h +append.o: $(hdrdir)/ruby/internal/intern/sprintf.h +append.o: $(hdrdir)/ruby/internal/intern/string.h +append.o: $(hdrdir)/ruby/internal/intern/struct.h +append.o: $(hdrdir)/ruby/internal/intern/thread.h +append.o: $(hdrdir)/ruby/internal/intern/time.h +append.o: $(hdrdir)/ruby/internal/intern/variable.h +append.o: $(hdrdir)/ruby/internal/intern/vm.h +append.o: $(hdrdir)/ruby/internal/interpreter.h +append.o: $(hdrdir)/ruby/internal/iterator.h +append.o: $(hdrdir)/ruby/internal/memory.h +append.o: $(hdrdir)/ruby/internal/method.h +append.o: $(hdrdir)/ruby/internal/module.h +append.o: $(hdrdir)/ruby/internal/newobj.h +append.o: $(hdrdir)/ruby/internal/scan_args.h +append.o: $(hdrdir)/ruby/internal/special_consts.h +append.o: $(hdrdir)/ruby/internal/static_assert.h +append.o: $(hdrdir)/ruby/internal/stdalign.h +append.o: $(hdrdir)/ruby/internal/stdbool.h +append.o: $(hdrdir)/ruby/internal/stdckdint.h +append.o: $(hdrdir)/ruby/internal/symbol.h +append.o: $(hdrdir)/ruby/internal/value.h +append.o: $(hdrdir)/ruby/internal/value_type.h +append.o: $(hdrdir)/ruby/internal/variable.h +append.o: $(hdrdir)/ruby/internal/warning_push.h +append.o: $(hdrdir)/ruby/internal/xmalloc.h +append.o: $(hdrdir)/ruby/missing.h +append.o: $(hdrdir)/ruby/onigmo.h +append.o: $(hdrdir)/ruby/oniguruma.h +append.o: $(hdrdir)/ruby/ruby.h +append.o: $(hdrdir)/ruby/st.h +append.o: $(hdrdir)/ruby/subst.h +append.o: append.c +init.o: $(RUBY_EXTCONF_H) +init.o: $(arch_hdrdir)/ruby/config.h +init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h +init.o: $(hdrdir)/ruby/internal/anyargs.h +init.o: $(hdrdir)/ruby/internal/arithmetic.h +init.o: $(hdrdir)/ruby/internal/arithmetic/char.h +init.o: $(hdrdir)/ruby/internal/arithmetic/double.h +init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/int.h +init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/short.h +init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +init.o: $(hdrdir)/ruby/internal/assume.h +init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +init.o: $(hdrdir)/ruby/internal/attr/artificial.h +init.o: $(hdrdir)/ruby/internal/attr/cold.h +init.o: $(hdrdir)/ruby/internal/attr/const.h +init.o: $(hdrdir)/ruby/internal/attr/constexpr.h +init.o: $(hdrdir)/ruby/internal/attr/deprecated.h +init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +init.o: $(hdrdir)/ruby/internal/attr/error.h +init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +init.o: $(hdrdir)/ruby/internal/attr/forceinline.h +init.o: $(hdrdir)/ruby/internal/attr/format.h +init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +init.o: $(hdrdir)/ruby/internal/attr/noalias.h +init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +init.o: $(hdrdir)/ruby/internal/attr/noexcept.h +init.o: $(hdrdir)/ruby/internal/attr/noinline.h +init.o: $(hdrdir)/ruby/internal/attr/nonnull.h +init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +init.o: $(hdrdir)/ruby/internal/attr/pure.h +init.o: $(hdrdir)/ruby/internal/attr/restrict.h +init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +init.o: $(hdrdir)/ruby/internal/attr/warning.h +init.o: $(hdrdir)/ruby/internal/attr/weakref.h +init.o: $(hdrdir)/ruby/internal/cast.h +init.o: $(hdrdir)/ruby/internal/compiler_is.h +init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +init.o: $(hdrdir)/ruby/internal/compiler_since.h +init.o: $(hdrdir)/ruby/internal/config.h +init.o: $(hdrdir)/ruby/internal/constant_p.h +init.o: $(hdrdir)/ruby/internal/core.h +init.o: $(hdrdir)/ruby/internal/core/rarray.h +init.o: $(hdrdir)/ruby/internal/core/rbasic.h +init.o: $(hdrdir)/ruby/internal/core/rbignum.h +init.o: $(hdrdir)/ruby/internal/core/rclass.h +init.o: $(hdrdir)/ruby/internal/core/rdata.h +init.o: $(hdrdir)/ruby/internal/core/rfile.h +init.o: $(hdrdir)/ruby/internal/core/rhash.h +init.o: $(hdrdir)/ruby/internal/core/robject.h +init.o: $(hdrdir)/ruby/internal/core/rregexp.h +init.o: $(hdrdir)/ruby/internal/core/rstring.h +init.o: $(hdrdir)/ruby/internal/core/rstruct.h +init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +init.o: $(hdrdir)/ruby/internal/ctype.h +init.o: $(hdrdir)/ruby/internal/dllexport.h +init.o: $(hdrdir)/ruby/internal/dosish.h +init.o: $(hdrdir)/ruby/internal/error.h +init.o: $(hdrdir)/ruby/internal/eval.h +init.o: $(hdrdir)/ruby/internal/event.h +init.o: $(hdrdir)/ruby/internal/fl_type.h +init.o: $(hdrdir)/ruby/internal/gc.h +init.o: $(hdrdir)/ruby/internal/glob.h +init.o: $(hdrdir)/ruby/internal/globals.h +init.o: $(hdrdir)/ruby/internal/has/attribute.h +init.o: $(hdrdir)/ruby/internal/has/builtin.h +init.o: $(hdrdir)/ruby/internal/has/c_attribute.h +init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +init.o: $(hdrdir)/ruby/internal/has/extension.h +init.o: $(hdrdir)/ruby/internal/has/feature.h +init.o: $(hdrdir)/ruby/internal/has/warning.h +init.o: $(hdrdir)/ruby/internal/intern/array.h +init.o: $(hdrdir)/ruby/internal/intern/bignum.h +init.o: $(hdrdir)/ruby/internal/intern/class.h +init.o: $(hdrdir)/ruby/internal/intern/compar.h +init.o: $(hdrdir)/ruby/internal/intern/complex.h +init.o: $(hdrdir)/ruby/internal/intern/cont.h +init.o: $(hdrdir)/ruby/internal/intern/dir.h +init.o: $(hdrdir)/ruby/internal/intern/enum.h +init.o: $(hdrdir)/ruby/internal/intern/enumerator.h +init.o: $(hdrdir)/ruby/internal/intern/error.h +init.o: $(hdrdir)/ruby/internal/intern/eval.h +init.o: $(hdrdir)/ruby/internal/intern/file.h +init.o: $(hdrdir)/ruby/internal/intern/hash.h +init.o: $(hdrdir)/ruby/internal/intern/io.h +init.o: $(hdrdir)/ruby/internal/intern/load.h +init.o: $(hdrdir)/ruby/internal/intern/marshal.h +init.o: $(hdrdir)/ruby/internal/intern/numeric.h +init.o: $(hdrdir)/ruby/internal/intern/object.h +init.o: $(hdrdir)/ruby/internal/intern/parse.h +init.o: $(hdrdir)/ruby/internal/intern/proc.h +init.o: $(hdrdir)/ruby/internal/intern/process.h +init.o: $(hdrdir)/ruby/internal/intern/random.h +init.o: $(hdrdir)/ruby/internal/intern/range.h +init.o: $(hdrdir)/ruby/internal/intern/rational.h +init.o: $(hdrdir)/ruby/internal/intern/re.h +init.o: $(hdrdir)/ruby/internal/intern/ruby.h +init.o: $(hdrdir)/ruby/internal/intern/select.h +init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h +init.o: $(hdrdir)/ruby/internal/intern/signal.h +init.o: $(hdrdir)/ruby/internal/intern/sprintf.h +init.o: $(hdrdir)/ruby/internal/intern/string.h +init.o: $(hdrdir)/ruby/internal/intern/struct.h +init.o: $(hdrdir)/ruby/internal/intern/thread.h +init.o: $(hdrdir)/ruby/internal/intern/time.h +init.o: $(hdrdir)/ruby/internal/intern/variable.h +init.o: $(hdrdir)/ruby/internal/intern/vm.h +init.o: $(hdrdir)/ruby/internal/interpreter.h +init.o: $(hdrdir)/ruby/internal/iterator.h +init.o: $(hdrdir)/ruby/internal/memory.h +init.o: $(hdrdir)/ruby/internal/method.h +init.o: $(hdrdir)/ruby/internal/module.h +init.o: $(hdrdir)/ruby/internal/newobj.h +init.o: $(hdrdir)/ruby/internal/scan_args.h +init.o: $(hdrdir)/ruby/internal/special_consts.h +init.o: $(hdrdir)/ruby/internal/static_assert.h +init.o: $(hdrdir)/ruby/internal/stdalign.h +init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h +init.o: $(hdrdir)/ruby/internal/symbol.h +init.o: $(hdrdir)/ruby/internal/value.h +init.o: $(hdrdir)/ruby/internal/value_type.h +init.o: $(hdrdir)/ruby/internal/variable.h +init.o: $(hdrdir)/ruby/internal/warning_push.h +init.o: $(hdrdir)/ruby/internal/xmalloc.h +init.o: $(hdrdir)/ruby/missing.h +init.o: $(hdrdir)/ruby/ruby.h +init.o: $(hdrdir)/ruby/st.h +init.o: $(hdrdir)/ruby/subst.h +init.o: init.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/econv/extconf.rb b/ext/-test-/econv/extconf.rb new file mode 100644 index 0000000000..d786b15db9 --- /dev/null +++ b/ext/-test-/econv/extconf.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: false +require_relative "../auto_ext.rb" +auto_ext(inc: true) diff --git a/ext/-test-/econv/init.c b/ext/-test-/econv/init.c new file mode 100644 index 0000000000..9772ebe71c --- /dev/null +++ b/ext/-test-/econv/init.c @@ -0,0 +1,11 @@ +#include "ruby.h" + +#define init(n) {void Init_econv_##n(VALUE klass); Init_econv_##n(klass);} + +void +Init_econv(void) +{ + VALUE mBug = rb_define_module("Bug"); + VALUE klass = rb_define_class_under(mBug, "EConv", rb_path2class("Encoding::Converter")); + TEST_INIT_FUNCS(init); +} diff --git a/ext/-test-/ensure_and_callcc/depend b/ext/-test-/ensure_and_callcc/depend new file mode 100644 index 0000000000..54431847a6 --- /dev/null +++ b/ext/-test-/ensure_and_callcc/depend @@ -0,0 +1,163 @@ +# AUTOGENERATED DEPENDENCIES START +ensure_and_callcc.o: $(RUBY_EXTCONF_H) +ensure_and_callcc.o: $(arch_hdrdir)/ruby/config.h +ensure_and_callcc.o: $(hdrdir)/ruby.h +ensure_and_callcc.o: $(hdrdir)/ruby/assert.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/assume.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/attributes.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/bool.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/inttypes.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/limits.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/long_long.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/stdalign.h +ensure_and_callcc.o: $(hdrdir)/ruby/backward/2/stdarg.h +ensure_and_callcc.o: $(hdrdir)/ruby/defines.h +ensure_and_callcc.o: $(hdrdir)/ruby/intern.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/abi.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/anyargs.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/assume.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/artificial.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/cold.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/const.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/error.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/format.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/noalias.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/noinline.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/pure.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/restrict.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/warning.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/attr/weakref.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/cast.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/compiler_since.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/config.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/constant_p.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rarray.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rbasic.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rbignum.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rclass.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rdata.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rfile.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rhash.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/robject.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rregexp.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rstring.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rstruct.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/ctype.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/dllexport.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/dosish.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/error.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/eval.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/event.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/fl_type.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/gc.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/glob.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/globals.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/attribute.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/builtin.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/extension.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/feature.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/has/warning.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/array.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/bignum.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/class.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/compar.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/complex.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/cont.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/dir.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/enum.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/error.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/eval.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/file.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/hash.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/io.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/load.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/marshal.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/numeric.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/object.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/parse.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/proc.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/process.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/random.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/range.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/rational.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/re.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/ruby.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/select.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/set.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/signal.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/string.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/struct.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/thread.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/time.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/variable.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/intern/vm.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/interpreter.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/iterator.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/memory.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/method.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/module.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/newobj.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/scan_args.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/special_consts.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/static_assert.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/stdalign.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/stdbool.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/stdckdint.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/symbol.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/value.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/value_type.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/variable.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/warning_push.h +ensure_and_callcc.o: $(hdrdir)/ruby/internal/xmalloc.h +ensure_and_callcc.o: $(hdrdir)/ruby/missing.h +ensure_and_callcc.o: $(hdrdir)/ruby/ruby.h +ensure_and_callcc.o: $(hdrdir)/ruby/st.h +ensure_and_callcc.o: $(hdrdir)/ruby/subst.h +ensure_and_callcc.o: ensure_and_callcc.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/ensure_and_callcc/ensure_and_callcc.c b/ext/-test-/ensure_and_callcc/ensure_and_callcc.c new file mode 100644 index 0000000000..1a92de69c3 --- /dev/null +++ b/ext/-test-/ensure_and_callcc/ensure_and_callcc.c @@ -0,0 +1,58 @@ +#include "ruby.h" + +static VALUE rb_mEnsureAndCallcc; + +struct require_data { + VALUE obj; + VALUE fname; +}; + +static VALUE +call_require(VALUE arg) +{ + struct require_data *data = (struct require_data *)arg; + rb_f_require(data->obj, data->fname); + return Qnil; +} + +static VALUE +call_ensure(VALUE _) +{ + VALUE v = rb_iv_get(rb_mEnsureAndCallcc, "@ensure_called"); + int called = FIX2INT(v) + 1; + rb_iv_set(rb_mEnsureAndCallcc, "@ensure_called", INT2FIX(called)); + return Qnil; +} + +static VALUE +require_with_ensure(VALUE self, VALUE fname) +{ + struct require_data data = { + .obj = self, + .fname = fname + }; + return rb_ensure(call_require, (VALUE)&data, call_ensure, Qnil); +} + +static VALUE +ensure_called(VALUE self) +{ + return rb_iv_get(rb_mEnsureAndCallcc, "@ensure_called"); +} + +static VALUE +reset(VALUE self) +{ + rb_iv_set(rb_mEnsureAndCallcc, "@ensure_called", INT2FIX(0)); + return Qnil; +} + +void +Init_ensure_and_callcc(void) +{ + rb_mEnsureAndCallcc = rb_define_module("EnsureAndCallcc"); + rb_iv_set(rb_mEnsureAndCallcc, "@ensure_called", INT2FIX(0)); + rb_define_singleton_method(rb_mEnsureAndCallcc, "reset", reset, 0); + rb_define_singleton_method(rb_mEnsureAndCallcc, "ensure_called", ensure_called, 0); + rb_define_singleton_method(rb_mEnsureAndCallcc, "require_with_ensure", require_with_ensure, 1); +} diff --git a/ext/-test-/ensure_and_callcc/extconf.rb b/ext/-test-/ensure_and_callcc/extconf.rb new file mode 100644 index 0000000000..123b80b8d0 --- /dev/null +++ b/ext/-test-/ensure_and_callcc/extconf.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: false +require "mkmf" + +require_relative "../auto_ext.rb" +auto_ext(inc: true) diff --git a/ext/-test-/enumerator_kw/depend b/ext/-test-/enumerator_kw/depend index 482863a288..b6d2f0a998 100644 --- a/ext/-test-/enumerator_kw/depend +++ b/ext/-test-/enumerator_kw/depend @@ -2,6 +2,19 @@ enumerator_kw.o: $(RUBY_EXTCONF_H) enumerator_kw.o: $(arch_hdrdir)/ruby/config.h enumerator_kw.o: $(hdrdir)/ruby.h +enumerator_kw.o: $(hdrdir)/ruby/assert.h +enumerator_kw.o: $(hdrdir)/ruby/backward.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/assume.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/attributes.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/bool.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/limits.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/long_long.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h +enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h +enumerator_kw.o: $(hdrdir)/ruby/defines.h +enumerator_kw.o: $(hdrdir)/ruby/intern.h +enumerator_kw.o: $(hdrdir)/ruby/internal/abi.h enumerator_kw.o: $(hdrdir)/ruby/internal/anyargs.h enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic.h enumerator_kw.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h +enumerator_kw.o: $(hdrdir)/ruby/internal/attr/packed_struct.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/pure.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h enumerator_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/error.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/eval.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/file.h -enumerator_kw.o: $(hdrdir)/ruby/internal/intern/gc.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/hash.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/io.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/intern/re.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/ruby.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/select.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +enumerator_kw.o: $(hdrdir)/ruby/internal/intern/set.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/signal.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/sprintf.h enumerator_kw.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ enumerator_kw.o: $(hdrdir)/ruby/internal/memory.h enumerator_kw.o: $(hdrdir)/ruby/internal/method.h enumerator_kw.o: $(hdrdir)/ruby/internal/module.h enumerator_kw.o: $(hdrdir)/ruby/internal/newobj.h -enumerator_kw.o: $(hdrdir)/ruby/internal/rgengc.h enumerator_kw.o: $(hdrdir)/ruby/internal/scan_args.h enumerator_kw.o: $(hdrdir)/ruby/internal/special_consts.h enumerator_kw.o: $(hdrdir)/ruby/internal/static_assert.h enumerator_kw.o: $(hdrdir)/ruby/internal/stdalign.h enumerator_kw.o: $(hdrdir)/ruby/internal/stdbool.h +enumerator_kw.o: $(hdrdir)/ruby/internal/stdckdint.h enumerator_kw.o: $(hdrdir)/ruby/internal/symbol.h enumerator_kw.o: $(hdrdir)/ruby/internal/value.h enumerator_kw.o: $(hdrdir)/ruby/internal/value_type.h enumerator_kw.o: $(hdrdir)/ruby/internal/variable.h enumerator_kw.o: $(hdrdir)/ruby/internal/warning_push.h enumerator_kw.o: $(hdrdir)/ruby/internal/xmalloc.h -enumerator_kw.o: $(hdrdir)/ruby/assert.h -enumerator_kw.o: $(hdrdir)/ruby/backward.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/assume.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/attributes.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/bool.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/limits.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/long_long.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h -enumerator_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h -enumerator_kw.o: $(hdrdir)/ruby/defines.h -enumerator_kw.o: $(hdrdir)/ruby/intern.h enumerator_kw.o: $(hdrdir)/ruby/missing.h enumerator_kw.o: $(hdrdir)/ruby/ruby.h enumerator_kw.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/enumerator_kw/enumerator_kw.c b/ext/-test-/enumerator_kw/enumerator_kw.c index 947d2b37e6..9104c51869 100644 --- a/ext/-test-/enumerator_kw/enumerator_kw.c +++ b/ext/-test-/enumerator_kw/enumerator_kw.c @@ -14,7 +14,8 @@ enumerator_kw(int argc, VALUE *argv, VALUE self) } void -Init_enumerator_kw(void) { +Init_enumerator_kw(void) +{ VALUE module = rb_define_module("Bug"); module = rb_define_module_under(module, "EnumeratorKw"); rb_define_method(module, "m", enumerator_kw, -1); diff --git a/ext/-test-/eval/depend b/ext/-test-/eval/depend new file mode 100644 index 0000000000..03a1c7d7ef --- /dev/null +++ b/ext/-test-/eval/depend @@ -0,0 +1,162 @@ +# AUTOGENERATED DEPENDENCIES START +eval.o: $(RUBY_EXTCONF_H) +eval.o: $(arch_hdrdir)/ruby/config.h +eval.o: $(hdrdir)/ruby/assert.h +eval.o: $(hdrdir)/ruby/backward.h +eval.o: $(hdrdir)/ruby/backward/2/assume.h +eval.o: $(hdrdir)/ruby/backward/2/attributes.h +eval.o: $(hdrdir)/ruby/backward/2/bool.h +eval.o: $(hdrdir)/ruby/backward/2/inttypes.h +eval.o: $(hdrdir)/ruby/backward/2/limits.h +eval.o: $(hdrdir)/ruby/backward/2/long_long.h +eval.o: $(hdrdir)/ruby/backward/2/stdalign.h +eval.o: $(hdrdir)/ruby/backward/2/stdarg.h +eval.o: $(hdrdir)/ruby/defines.h +eval.o: $(hdrdir)/ruby/intern.h +eval.o: $(hdrdir)/ruby/internal/abi.h +eval.o: $(hdrdir)/ruby/internal/anyargs.h +eval.o: $(hdrdir)/ruby/internal/arithmetic.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/char.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/double.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/int.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/long.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/short.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +eval.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +eval.o: $(hdrdir)/ruby/internal/assume.h +eval.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +eval.o: $(hdrdir)/ruby/internal/attr/artificial.h +eval.o: $(hdrdir)/ruby/internal/attr/cold.h +eval.o: $(hdrdir)/ruby/internal/attr/const.h +eval.o: $(hdrdir)/ruby/internal/attr/constexpr.h +eval.o: $(hdrdir)/ruby/internal/attr/deprecated.h +eval.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +eval.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +eval.o: $(hdrdir)/ruby/internal/attr/error.h +eval.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +eval.o: $(hdrdir)/ruby/internal/attr/forceinline.h +eval.o: $(hdrdir)/ruby/internal/attr/format.h +eval.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +eval.o: $(hdrdir)/ruby/internal/attr/noalias.h +eval.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +eval.o: $(hdrdir)/ruby/internal/attr/noexcept.h +eval.o: $(hdrdir)/ruby/internal/attr/noinline.h +eval.o: $(hdrdir)/ruby/internal/attr/nonnull.h +eval.o: $(hdrdir)/ruby/internal/attr/noreturn.h +eval.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +eval.o: $(hdrdir)/ruby/internal/attr/pure.h +eval.o: $(hdrdir)/ruby/internal/attr/restrict.h +eval.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +eval.o: $(hdrdir)/ruby/internal/attr/warning.h +eval.o: $(hdrdir)/ruby/internal/attr/weakref.h +eval.o: $(hdrdir)/ruby/internal/cast.h +eval.o: $(hdrdir)/ruby/internal/compiler_is.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +eval.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +eval.o: $(hdrdir)/ruby/internal/compiler_since.h +eval.o: $(hdrdir)/ruby/internal/config.h +eval.o: $(hdrdir)/ruby/internal/constant_p.h +eval.o: $(hdrdir)/ruby/internal/core.h +eval.o: $(hdrdir)/ruby/internal/core/rarray.h +eval.o: $(hdrdir)/ruby/internal/core/rbasic.h +eval.o: $(hdrdir)/ruby/internal/core/rbignum.h +eval.o: $(hdrdir)/ruby/internal/core/rclass.h +eval.o: $(hdrdir)/ruby/internal/core/rdata.h +eval.o: $(hdrdir)/ruby/internal/core/rfile.h +eval.o: $(hdrdir)/ruby/internal/core/rhash.h +eval.o: $(hdrdir)/ruby/internal/core/robject.h +eval.o: $(hdrdir)/ruby/internal/core/rregexp.h +eval.o: $(hdrdir)/ruby/internal/core/rstring.h +eval.o: $(hdrdir)/ruby/internal/core/rstruct.h +eval.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +eval.o: $(hdrdir)/ruby/internal/ctype.h +eval.o: $(hdrdir)/ruby/internal/dllexport.h +eval.o: $(hdrdir)/ruby/internal/dosish.h +eval.o: $(hdrdir)/ruby/internal/error.h +eval.o: $(hdrdir)/ruby/internal/eval.h +eval.o: $(hdrdir)/ruby/internal/event.h +eval.o: $(hdrdir)/ruby/internal/fl_type.h +eval.o: $(hdrdir)/ruby/internal/gc.h +eval.o: $(hdrdir)/ruby/internal/glob.h +eval.o: $(hdrdir)/ruby/internal/globals.h +eval.o: $(hdrdir)/ruby/internal/has/attribute.h +eval.o: $(hdrdir)/ruby/internal/has/builtin.h +eval.o: $(hdrdir)/ruby/internal/has/c_attribute.h +eval.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +eval.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +eval.o: $(hdrdir)/ruby/internal/has/extension.h +eval.o: $(hdrdir)/ruby/internal/has/feature.h +eval.o: $(hdrdir)/ruby/internal/has/warning.h +eval.o: $(hdrdir)/ruby/internal/intern/array.h +eval.o: $(hdrdir)/ruby/internal/intern/bignum.h +eval.o: $(hdrdir)/ruby/internal/intern/class.h +eval.o: $(hdrdir)/ruby/internal/intern/compar.h +eval.o: $(hdrdir)/ruby/internal/intern/complex.h +eval.o: $(hdrdir)/ruby/internal/intern/cont.h +eval.o: $(hdrdir)/ruby/internal/intern/dir.h +eval.o: $(hdrdir)/ruby/internal/intern/enum.h +eval.o: $(hdrdir)/ruby/internal/intern/enumerator.h +eval.o: $(hdrdir)/ruby/internal/intern/error.h +eval.o: $(hdrdir)/ruby/internal/intern/eval.h +eval.o: $(hdrdir)/ruby/internal/intern/file.h +eval.o: $(hdrdir)/ruby/internal/intern/hash.h +eval.o: $(hdrdir)/ruby/internal/intern/io.h +eval.o: $(hdrdir)/ruby/internal/intern/load.h +eval.o: $(hdrdir)/ruby/internal/intern/marshal.h +eval.o: $(hdrdir)/ruby/internal/intern/numeric.h +eval.o: $(hdrdir)/ruby/internal/intern/object.h +eval.o: $(hdrdir)/ruby/internal/intern/parse.h +eval.o: $(hdrdir)/ruby/internal/intern/proc.h +eval.o: $(hdrdir)/ruby/internal/intern/process.h +eval.o: $(hdrdir)/ruby/internal/intern/random.h +eval.o: $(hdrdir)/ruby/internal/intern/range.h +eval.o: $(hdrdir)/ruby/internal/intern/rational.h +eval.o: $(hdrdir)/ruby/internal/intern/re.h +eval.o: $(hdrdir)/ruby/internal/intern/ruby.h +eval.o: $(hdrdir)/ruby/internal/intern/select.h +eval.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +eval.o: $(hdrdir)/ruby/internal/intern/set.h +eval.o: $(hdrdir)/ruby/internal/intern/signal.h +eval.o: $(hdrdir)/ruby/internal/intern/sprintf.h +eval.o: $(hdrdir)/ruby/internal/intern/string.h +eval.o: $(hdrdir)/ruby/internal/intern/struct.h +eval.o: $(hdrdir)/ruby/internal/intern/thread.h +eval.o: $(hdrdir)/ruby/internal/intern/time.h +eval.o: $(hdrdir)/ruby/internal/intern/variable.h +eval.o: $(hdrdir)/ruby/internal/intern/vm.h +eval.o: $(hdrdir)/ruby/internal/interpreter.h +eval.o: $(hdrdir)/ruby/internal/iterator.h +eval.o: $(hdrdir)/ruby/internal/memory.h +eval.o: $(hdrdir)/ruby/internal/method.h +eval.o: $(hdrdir)/ruby/internal/module.h +eval.o: $(hdrdir)/ruby/internal/newobj.h +eval.o: $(hdrdir)/ruby/internal/scan_args.h +eval.o: $(hdrdir)/ruby/internal/special_consts.h +eval.o: $(hdrdir)/ruby/internal/static_assert.h +eval.o: $(hdrdir)/ruby/internal/stdalign.h +eval.o: $(hdrdir)/ruby/internal/stdbool.h +eval.o: $(hdrdir)/ruby/internal/stdckdint.h +eval.o: $(hdrdir)/ruby/internal/symbol.h +eval.o: $(hdrdir)/ruby/internal/value.h +eval.o: $(hdrdir)/ruby/internal/value_type.h +eval.o: $(hdrdir)/ruby/internal/variable.h +eval.o: $(hdrdir)/ruby/internal/warning_push.h +eval.o: $(hdrdir)/ruby/internal/xmalloc.h +eval.o: $(hdrdir)/ruby/missing.h +eval.o: $(hdrdir)/ruby/ruby.h +eval.o: $(hdrdir)/ruby/st.h +eval.o: $(hdrdir)/ruby/subst.h +eval.o: eval.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/eval/eval.c b/ext/-test-/eval/eval.c new file mode 100644 index 0000000000..983468fc34 --- /dev/null +++ b/ext/-test-/eval/eval.c @@ -0,0 +1,13 @@ +#include "ruby/ruby.h" + +static VALUE +eval_string(VALUE self, VALUE str) +{ + return rb_eval_string(StringValueCStr(str)); +} + +void +Init_eval(void) +{ + rb_define_global_function("rb_eval_string", eval_string, 1); +} diff --git a/ext/-test-/eval/extconf.rb b/ext/-test-/eval/extconf.rb new file mode 100644 index 0000000000..cdbf6a8597 --- /dev/null +++ b/ext/-test-/eval/extconf.rb @@ -0,0 +1,2 @@ +require 'mkmf' +create_makefile('-test-/eval') diff --git a/ext/-test-/exception/depend b/ext/-test-/exception/depend index 8ecc512841..690e5ad377 100644 --- a/ext/-test-/exception/depend +++ b/ext/-test-/exception/depend @@ -6,7 +6,6 @@ dataerror.o: $(hdrdir)/ruby/backward.h dataerror.o: $(hdrdir)/ruby/backward/2/assume.h dataerror.o: $(hdrdir)/ruby/backward/2/attributes.h dataerror.o: $(hdrdir)/ruby/backward/2/bool.h -dataerror.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h dataerror.o: $(hdrdir)/ruby/backward/2/inttypes.h dataerror.o: $(hdrdir)/ruby/backward/2/limits.h dataerror.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -14,6 +13,7 @@ dataerror.o: $(hdrdir)/ruby/backward/2/stdalign.h dataerror.o: $(hdrdir)/ruby/backward/2/stdarg.h dataerror.o: $(hdrdir)/ruby/defines.h dataerror.o: $(hdrdir)/ruby/intern.h +dataerror.o: $(hdrdir)/ruby/internal/abi.h dataerror.o: $(hdrdir)/ruby/internal/anyargs.h dataerror.o: $(hdrdir)/ruby/internal/arithmetic.h dataerror.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -51,6 +51,7 @@ dataerror.o: $(hdrdir)/ruby/internal/attr/noexcept.h dataerror.o: $(hdrdir)/ruby/internal/attr/noinline.h dataerror.o: $(hdrdir)/ruby/internal/attr/nonnull.h dataerror.o: $(hdrdir)/ruby/internal/attr/noreturn.h +dataerror.o: $(hdrdir)/ruby/internal/attr/packed_struct.h dataerror.o: $(hdrdir)/ruby/internal/attr/pure.h dataerror.o: $(hdrdir)/ruby/internal/attr/restrict.h dataerror.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -110,7 +111,6 @@ dataerror.o: $(hdrdir)/ruby/internal/intern/enumerator.h dataerror.o: $(hdrdir)/ruby/internal/intern/error.h dataerror.o: $(hdrdir)/ruby/internal/intern/eval.h dataerror.o: $(hdrdir)/ruby/internal/intern/file.h -dataerror.o: $(hdrdir)/ruby/internal/intern/gc.h dataerror.o: $(hdrdir)/ruby/internal/intern/hash.h dataerror.o: $(hdrdir)/ruby/internal/intern/io.h dataerror.o: $(hdrdir)/ruby/internal/intern/load.h @@ -127,6 +127,7 @@ dataerror.o: $(hdrdir)/ruby/internal/intern/re.h dataerror.o: $(hdrdir)/ruby/internal/intern/ruby.h dataerror.o: $(hdrdir)/ruby/internal/intern/select.h dataerror.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +dataerror.o: $(hdrdir)/ruby/internal/intern/set.h dataerror.o: $(hdrdir)/ruby/internal/intern/signal.h dataerror.o: $(hdrdir)/ruby/internal/intern/sprintf.h dataerror.o: $(hdrdir)/ruby/internal/intern/string.h @@ -141,12 +142,12 @@ dataerror.o: $(hdrdir)/ruby/internal/memory.h dataerror.o: $(hdrdir)/ruby/internal/method.h dataerror.o: $(hdrdir)/ruby/internal/module.h dataerror.o: $(hdrdir)/ruby/internal/newobj.h -dataerror.o: $(hdrdir)/ruby/internal/rgengc.h dataerror.o: $(hdrdir)/ruby/internal/scan_args.h dataerror.o: $(hdrdir)/ruby/internal/special_consts.h dataerror.o: $(hdrdir)/ruby/internal/static_assert.h dataerror.o: $(hdrdir)/ruby/internal/stdalign.h dataerror.o: $(hdrdir)/ruby/internal/stdbool.h +dataerror.o: $(hdrdir)/ruby/internal/stdckdint.h dataerror.o: $(hdrdir)/ruby/internal/symbol.h dataerror.o: $(hdrdir)/ruby/internal/value.h dataerror.o: $(hdrdir)/ruby/internal/value_type.h @@ -166,7 +167,6 @@ enc_raise.o: $(hdrdir)/ruby/backward.h enc_raise.o: $(hdrdir)/ruby/backward/2/assume.h enc_raise.o: $(hdrdir)/ruby/backward/2/attributes.h enc_raise.o: $(hdrdir)/ruby/backward/2/bool.h -enc_raise.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h enc_raise.o: $(hdrdir)/ruby/backward/2/inttypes.h enc_raise.o: $(hdrdir)/ruby/backward/2/limits.h enc_raise.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -175,6 +175,7 @@ enc_raise.o: $(hdrdir)/ruby/backward/2/stdarg.h enc_raise.o: $(hdrdir)/ruby/defines.h enc_raise.o: $(hdrdir)/ruby/encoding.h enc_raise.o: $(hdrdir)/ruby/intern.h +enc_raise.o: $(hdrdir)/ruby/internal/abi.h enc_raise.o: $(hdrdir)/ruby/internal/anyargs.h enc_raise.o: $(hdrdir)/ruby/internal/arithmetic.h enc_raise.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -212,6 +213,7 @@ enc_raise.o: $(hdrdir)/ruby/internal/attr/noexcept.h enc_raise.o: $(hdrdir)/ruby/internal/attr/noinline.h enc_raise.o: $(hdrdir)/ruby/internal/attr/nonnull.h enc_raise.o: $(hdrdir)/ruby/internal/attr/noreturn.h +enc_raise.o: $(hdrdir)/ruby/internal/attr/packed_struct.h enc_raise.o: $(hdrdir)/ruby/internal/attr/pure.h enc_raise.o: $(hdrdir)/ruby/internal/attr/restrict.h enc_raise.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -280,7 +282,6 @@ enc_raise.o: $(hdrdir)/ruby/internal/intern/enumerator.h enc_raise.o: $(hdrdir)/ruby/internal/intern/error.h enc_raise.o: $(hdrdir)/ruby/internal/intern/eval.h enc_raise.o: $(hdrdir)/ruby/internal/intern/file.h -enc_raise.o: $(hdrdir)/ruby/internal/intern/gc.h enc_raise.o: $(hdrdir)/ruby/internal/intern/hash.h enc_raise.o: $(hdrdir)/ruby/internal/intern/io.h enc_raise.o: $(hdrdir)/ruby/internal/intern/load.h @@ -297,6 +298,7 @@ enc_raise.o: $(hdrdir)/ruby/internal/intern/re.h enc_raise.o: $(hdrdir)/ruby/internal/intern/ruby.h enc_raise.o: $(hdrdir)/ruby/internal/intern/select.h enc_raise.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +enc_raise.o: $(hdrdir)/ruby/internal/intern/set.h enc_raise.o: $(hdrdir)/ruby/internal/intern/signal.h enc_raise.o: $(hdrdir)/ruby/internal/intern/sprintf.h enc_raise.o: $(hdrdir)/ruby/internal/intern/string.h @@ -311,12 +313,12 @@ enc_raise.o: $(hdrdir)/ruby/internal/memory.h enc_raise.o: $(hdrdir)/ruby/internal/method.h enc_raise.o: $(hdrdir)/ruby/internal/module.h enc_raise.o: $(hdrdir)/ruby/internal/newobj.h -enc_raise.o: $(hdrdir)/ruby/internal/rgengc.h enc_raise.o: $(hdrdir)/ruby/internal/scan_args.h enc_raise.o: $(hdrdir)/ruby/internal/special_consts.h enc_raise.o: $(hdrdir)/ruby/internal/static_assert.h enc_raise.o: $(hdrdir)/ruby/internal/stdalign.h enc_raise.o: $(hdrdir)/ruby/internal/stdbool.h +enc_raise.o: $(hdrdir)/ruby/internal/stdckdint.h enc_raise.o: $(hdrdir)/ruby/internal/symbol.h enc_raise.o: $(hdrdir)/ruby/internal/value.h enc_raise.o: $(hdrdir)/ruby/internal/value_type.h @@ -338,7 +340,6 @@ ensured.o: $(hdrdir)/ruby/backward.h ensured.o: $(hdrdir)/ruby/backward/2/assume.h ensured.o: $(hdrdir)/ruby/backward/2/attributes.h ensured.o: $(hdrdir)/ruby/backward/2/bool.h -ensured.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h ensured.o: $(hdrdir)/ruby/backward/2/inttypes.h ensured.o: $(hdrdir)/ruby/backward/2/limits.h ensured.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -346,6 +347,7 @@ ensured.o: $(hdrdir)/ruby/backward/2/stdalign.h ensured.o: $(hdrdir)/ruby/backward/2/stdarg.h ensured.o: $(hdrdir)/ruby/defines.h ensured.o: $(hdrdir)/ruby/intern.h +ensured.o: $(hdrdir)/ruby/internal/abi.h ensured.o: $(hdrdir)/ruby/internal/anyargs.h ensured.o: $(hdrdir)/ruby/internal/arithmetic.h ensured.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -383,6 +385,7 @@ ensured.o: $(hdrdir)/ruby/internal/attr/noexcept.h ensured.o: $(hdrdir)/ruby/internal/attr/noinline.h ensured.o: $(hdrdir)/ruby/internal/attr/nonnull.h ensured.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ensured.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ensured.o: $(hdrdir)/ruby/internal/attr/pure.h ensured.o: $(hdrdir)/ruby/internal/attr/restrict.h ensured.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -442,7 +445,6 @@ ensured.o: $(hdrdir)/ruby/internal/intern/enumerator.h ensured.o: $(hdrdir)/ruby/internal/intern/error.h ensured.o: $(hdrdir)/ruby/internal/intern/eval.h ensured.o: $(hdrdir)/ruby/internal/intern/file.h -ensured.o: $(hdrdir)/ruby/internal/intern/gc.h ensured.o: $(hdrdir)/ruby/internal/intern/hash.h ensured.o: $(hdrdir)/ruby/internal/intern/io.h ensured.o: $(hdrdir)/ruby/internal/intern/load.h @@ -459,6 +461,7 @@ ensured.o: $(hdrdir)/ruby/internal/intern/re.h ensured.o: $(hdrdir)/ruby/internal/intern/ruby.h ensured.o: $(hdrdir)/ruby/internal/intern/select.h ensured.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ensured.o: $(hdrdir)/ruby/internal/intern/set.h ensured.o: $(hdrdir)/ruby/internal/intern/signal.h ensured.o: $(hdrdir)/ruby/internal/intern/sprintf.h ensured.o: $(hdrdir)/ruby/internal/intern/string.h @@ -473,12 +476,12 @@ ensured.o: $(hdrdir)/ruby/internal/memory.h ensured.o: $(hdrdir)/ruby/internal/method.h ensured.o: $(hdrdir)/ruby/internal/module.h ensured.o: $(hdrdir)/ruby/internal/newobj.h -ensured.o: $(hdrdir)/ruby/internal/rgengc.h ensured.o: $(hdrdir)/ruby/internal/scan_args.h ensured.o: $(hdrdir)/ruby/internal/special_consts.h ensured.o: $(hdrdir)/ruby/internal/static_assert.h ensured.o: $(hdrdir)/ruby/internal/stdalign.h ensured.o: $(hdrdir)/ruby/internal/stdbool.h +ensured.o: $(hdrdir)/ruby/internal/stdckdint.h ensured.o: $(hdrdir)/ruby/internal/symbol.h ensured.o: $(hdrdir)/ruby/internal/value.h ensured.o: $(hdrdir)/ruby/internal/value_type.h @@ -498,7 +501,6 @@ init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h init.o: $(hdrdir)/ruby/backward/2/inttypes.h init.o: $(hdrdir)/ruby/backward/2/limits.h init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -506,6 +508,7 @@ init.o: $(hdrdir)/ruby/backward/2/stdalign.h init.o: $(hdrdir)/ruby/backward/2/stdarg.h init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -543,6 +546,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -602,7 +606,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -619,6 +622,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -633,12 +637,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/fatal/depend b/ext/-test-/fatal/depend index 79ac18fd9f..306bc9099c 100644 --- a/ext/-test-/fatal/depend +++ b/ext/-test-/fatal/depend @@ -1,7 +1,343 @@ # AUTOGENERATED DEPENDENCIES START + +init.o: $(RUBY_EXTCONF_H) +init.o: $(arch_hdrdir)/ruby/config.h +init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h +init.o: $(hdrdir)/ruby/internal/anyargs.h +init.o: $(hdrdir)/ruby/internal/arithmetic.h +init.o: $(hdrdir)/ruby/internal/arithmetic/char.h +init.o: $(hdrdir)/ruby/internal/arithmetic/double.h +init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/int.h +init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/short.h +init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +init.o: $(hdrdir)/ruby/internal/assume.h +init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +init.o: $(hdrdir)/ruby/internal/attr/artificial.h +init.o: $(hdrdir)/ruby/internal/attr/cold.h +init.o: $(hdrdir)/ruby/internal/attr/const.h +init.o: $(hdrdir)/ruby/internal/attr/constexpr.h +init.o: $(hdrdir)/ruby/internal/attr/deprecated.h +init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +init.o: $(hdrdir)/ruby/internal/attr/error.h +init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +init.o: $(hdrdir)/ruby/internal/attr/forceinline.h +init.o: $(hdrdir)/ruby/internal/attr/format.h +init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +init.o: $(hdrdir)/ruby/internal/attr/noalias.h +init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +init.o: $(hdrdir)/ruby/internal/attr/noexcept.h +init.o: $(hdrdir)/ruby/internal/attr/noinline.h +init.o: $(hdrdir)/ruby/internal/attr/nonnull.h +init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +init.o: $(hdrdir)/ruby/internal/attr/pure.h +init.o: $(hdrdir)/ruby/internal/attr/restrict.h +init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +init.o: $(hdrdir)/ruby/internal/attr/warning.h +init.o: $(hdrdir)/ruby/internal/attr/weakref.h +init.o: $(hdrdir)/ruby/internal/cast.h +init.o: $(hdrdir)/ruby/internal/compiler_is.h +init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +init.o: $(hdrdir)/ruby/internal/compiler_since.h +init.o: $(hdrdir)/ruby/internal/config.h +init.o: $(hdrdir)/ruby/internal/constant_p.h +init.o: $(hdrdir)/ruby/internal/core.h +init.o: $(hdrdir)/ruby/internal/core/rarray.h +init.o: $(hdrdir)/ruby/internal/core/rbasic.h +init.o: $(hdrdir)/ruby/internal/core/rbignum.h +init.o: $(hdrdir)/ruby/internal/core/rclass.h +init.o: $(hdrdir)/ruby/internal/core/rdata.h +init.o: $(hdrdir)/ruby/internal/core/rfile.h +init.o: $(hdrdir)/ruby/internal/core/rhash.h +init.o: $(hdrdir)/ruby/internal/core/robject.h +init.o: $(hdrdir)/ruby/internal/core/rregexp.h +init.o: $(hdrdir)/ruby/internal/core/rstring.h +init.o: $(hdrdir)/ruby/internal/core/rstruct.h +init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +init.o: $(hdrdir)/ruby/internal/ctype.h +init.o: $(hdrdir)/ruby/internal/dllexport.h +init.o: $(hdrdir)/ruby/internal/dosish.h +init.o: $(hdrdir)/ruby/internal/error.h +init.o: $(hdrdir)/ruby/internal/eval.h +init.o: $(hdrdir)/ruby/internal/event.h +init.o: $(hdrdir)/ruby/internal/fl_type.h +init.o: $(hdrdir)/ruby/internal/gc.h +init.o: $(hdrdir)/ruby/internal/glob.h +init.o: $(hdrdir)/ruby/internal/globals.h +init.o: $(hdrdir)/ruby/internal/has/attribute.h +init.o: $(hdrdir)/ruby/internal/has/builtin.h +init.o: $(hdrdir)/ruby/internal/has/c_attribute.h +init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +init.o: $(hdrdir)/ruby/internal/has/extension.h +init.o: $(hdrdir)/ruby/internal/has/feature.h +init.o: $(hdrdir)/ruby/internal/has/warning.h +init.o: $(hdrdir)/ruby/internal/intern/array.h +init.o: $(hdrdir)/ruby/internal/intern/bignum.h +init.o: $(hdrdir)/ruby/internal/intern/class.h +init.o: $(hdrdir)/ruby/internal/intern/compar.h +init.o: $(hdrdir)/ruby/internal/intern/complex.h +init.o: $(hdrdir)/ruby/internal/intern/cont.h +init.o: $(hdrdir)/ruby/internal/intern/dir.h +init.o: $(hdrdir)/ruby/internal/intern/enum.h +init.o: $(hdrdir)/ruby/internal/intern/enumerator.h +init.o: $(hdrdir)/ruby/internal/intern/error.h +init.o: $(hdrdir)/ruby/internal/intern/eval.h +init.o: $(hdrdir)/ruby/internal/intern/file.h +init.o: $(hdrdir)/ruby/internal/intern/hash.h +init.o: $(hdrdir)/ruby/internal/intern/io.h +init.o: $(hdrdir)/ruby/internal/intern/load.h +init.o: $(hdrdir)/ruby/internal/intern/marshal.h +init.o: $(hdrdir)/ruby/internal/intern/numeric.h +init.o: $(hdrdir)/ruby/internal/intern/object.h +init.o: $(hdrdir)/ruby/internal/intern/parse.h +init.o: $(hdrdir)/ruby/internal/intern/proc.h +init.o: $(hdrdir)/ruby/internal/intern/process.h +init.o: $(hdrdir)/ruby/internal/intern/random.h +init.o: $(hdrdir)/ruby/internal/intern/range.h +init.o: $(hdrdir)/ruby/internal/intern/rational.h +init.o: $(hdrdir)/ruby/internal/intern/re.h +init.o: $(hdrdir)/ruby/internal/intern/ruby.h +init.o: $(hdrdir)/ruby/internal/intern/select.h +init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h +init.o: $(hdrdir)/ruby/internal/intern/signal.h +init.o: $(hdrdir)/ruby/internal/intern/sprintf.h +init.o: $(hdrdir)/ruby/internal/intern/string.h +init.o: $(hdrdir)/ruby/internal/intern/struct.h +init.o: $(hdrdir)/ruby/internal/intern/thread.h +init.o: $(hdrdir)/ruby/internal/intern/time.h +init.o: $(hdrdir)/ruby/internal/intern/variable.h +init.o: $(hdrdir)/ruby/internal/intern/vm.h +init.o: $(hdrdir)/ruby/internal/interpreter.h +init.o: $(hdrdir)/ruby/internal/iterator.h +init.o: $(hdrdir)/ruby/internal/memory.h +init.o: $(hdrdir)/ruby/internal/method.h +init.o: $(hdrdir)/ruby/internal/module.h +init.o: $(hdrdir)/ruby/internal/newobj.h +init.o: $(hdrdir)/ruby/internal/scan_args.h +init.o: $(hdrdir)/ruby/internal/special_consts.h +init.o: $(hdrdir)/ruby/internal/static_assert.h +init.o: $(hdrdir)/ruby/internal/stdalign.h +init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h +init.o: $(hdrdir)/ruby/internal/symbol.h +init.o: $(hdrdir)/ruby/internal/value.h +init.o: $(hdrdir)/ruby/internal/value_type.h +init.o: $(hdrdir)/ruby/internal/variable.h +init.o: $(hdrdir)/ruby/internal/warning_push.h +init.o: $(hdrdir)/ruby/internal/xmalloc.h +init.o: $(hdrdir)/ruby/missing.h +init.o: $(hdrdir)/ruby/ruby.h +init.o: $(hdrdir)/ruby/st.h +init.o: $(hdrdir)/ruby/subst.h +init.o: init.c +invalid.o: $(RUBY_EXTCONF_H) +invalid.o: $(arch_hdrdir)/ruby/config.h +invalid.o: $(hdrdir)/ruby.h +invalid.o: $(hdrdir)/ruby/assert.h +invalid.o: $(hdrdir)/ruby/backward.h +invalid.o: $(hdrdir)/ruby/backward/2/assume.h +invalid.o: $(hdrdir)/ruby/backward/2/attributes.h +invalid.o: $(hdrdir)/ruby/backward/2/bool.h +invalid.o: $(hdrdir)/ruby/backward/2/inttypes.h +invalid.o: $(hdrdir)/ruby/backward/2/limits.h +invalid.o: $(hdrdir)/ruby/backward/2/long_long.h +invalid.o: $(hdrdir)/ruby/backward/2/stdalign.h +invalid.o: $(hdrdir)/ruby/backward/2/stdarg.h +invalid.o: $(hdrdir)/ruby/defines.h +invalid.o: $(hdrdir)/ruby/intern.h +invalid.o: $(hdrdir)/ruby/internal/abi.h +invalid.o: $(hdrdir)/ruby/internal/anyargs.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/char.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/double.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/int.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/long.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/short.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +invalid.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +invalid.o: $(hdrdir)/ruby/internal/assume.h +invalid.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +invalid.o: $(hdrdir)/ruby/internal/attr/artificial.h +invalid.o: $(hdrdir)/ruby/internal/attr/cold.h +invalid.o: $(hdrdir)/ruby/internal/attr/const.h +invalid.o: $(hdrdir)/ruby/internal/attr/constexpr.h +invalid.o: $(hdrdir)/ruby/internal/attr/deprecated.h +invalid.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +invalid.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +invalid.o: $(hdrdir)/ruby/internal/attr/error.h +invalid.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +invalid.o: $(hdrdir)/ruby/internal/attr/forceinline.h +invalid.o: $(hdrdir)/ruby/internal/attr/format.h +invalid.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +invalid.o: $(hdrdir)/ruby/internal/attr/noalias.h +invalid.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +invalid.o: $(hdrdir)/ruby/internal/attr/noexcept.h +invalid.o: $(hdrdir)/ruby/internal/attr/noinline.h +invalid.o: $(hdrdir)/ruby/internal/attr/nonnull.h +invalid.o: $(hdrdir)/ruby/internal/attr/noreturn.h +invalid.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +invalid.o: $(hdrdir)/ruby/internal/attr/pure.h +invalid.o: $(hdrdir)/ruby/internal/attr/restrict.h +invalid.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +invalid.o: $(hdrdir)/ruby/internal/attr/warning.h +invalid.o: $(hdrdir)/ruby/internal/attr/weakref.h +invalid.o: $(hdrdir)/ruby/internal/cast.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +invalid.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +invalid.o: $(hdrdir)/ruby/internal/compiler_since.h +invalid.o: $(hdrdir)/ruby/internal/config.h +invalid.o: $(hdrdir)/ruby/internal/constant_p.h +invalid.o: $(hdrdir)/ruby/internal/core.h +invalid.o: $(hdrdir)/ruby/internal/core/rarray.h +invalid.o: $(hdrdir)/ruby/internal/core/rbasic.h +invalid.o: $(hdrdir)/ruby/internal/core/rbignum.h +invalid.o: $(hdrdir)/ruby/internal/core/rclass.h +invalid.o: $(hdrdir)/ruby/internal/core/rdata.h +invalid.o: $(hdrdir)/ruby/internal/core/rfile.h +invalid.o: $(hdrdir)/ruby/internal/core/rhash.h +invalid.o: $(hdrdir)/ruby/internal/core/robject.h +invalid.o: $(hdrdir)/ruby/internal/core/rregexp.h +invalid.o: $(hdrdir)/ruby/internal/core/rstring.h +invalid.o: $(hdrdir)/ruby/internal/core/rstruct.h +invalid.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +invalid.o: $(hdrdir)/ruby/internal/ctype.h +invalid.o: $(hdrdir)/ruby/internal/dllexport.h +invalid.o: $(hdrdir)/ruby/internal/dosish.h +invalid.o: $(hdrdir)/ruby/internal/error.h +invalid.o: $(hdrdir)/ruby/internal/eval.h +invalid.o: $(hdrdir)/ruby/internal/event.h +invalid.o: $(hdrdir)/ruby/internal/fl_type.h +invalid.o: $(hdrdir)/ruby/internal/gc.h +invalid.o: $(hdrdir)/ruby/internal/glob.h +invalid.o: $(hdrdir)/ruby/internal/globals.h +invalid.o: $(hdrdir)/ruby/internal/has/attribute.h +invalid.o: $(hdrdir)/ruby/internal/has/builtin.h +invalid.o: $(hdrdir)/ruby/internal/has/c_attribute.h +invalid.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +invalid.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +invalid.o: $(hdrdir)/ruby/internal/has/extension.h +invalid.o: $(hdrdir)/ruby/internal/has/feature.h +invalid.o: $(hdrdir)/ruby/internal/has/warning.h +invalid.o: $(hdrdir)/ruby/internal/intern/array.h +invalid.o: $(hdrdir)/ruby/internal/intern/bignum.h +invalid.o: $(hdrdir)/ruby/internal/intern/class.h +invalid.o: $(hdrdir)/ruby/internal/intern/compar.h +invalid.o: $(hdrdir)/ruby/internal/intern/complex.h +invalid.o: $(hdrdir)/ruby/internal/intern/cont.h +invalid.o: $(hdrdir)/ruby/internal/intern/dir.h +invalid.o: $(hdrdir)/ruby/internal/intern/enum.h +invalid.o: $(hdrdir)/ruby/internal/intern/enumerator.h +invalid.o: $(hdrdir)/ruby/internal/intern/error.h +invalid.o: $(hdrdir)/ruby/internal/intern/eval.h +invalid.o: $(hdrdir)/ruby/internal/intern/file.h +invalid.o: $(hdrdir)/ruby/internal/intern/hash.h +invalid.o: $(hdrdir)/ruby/internal/intern/io.h +invalid.o: $(hdrdir)/ruby/internal/intern/load.h +invalid.o: $(hdrdir)/ruby/internal/intern/marshal.h +invalid.o: $(hdrdir)/ruby/internal/intern/numeric.h +invalid.o: $(hdrdir)/ruby/internal/intern/object.h +invalid.o: $(hdrdir)/ruby/internal/intern/parse.h +invalid.o: $(hdrdir)/ruby/internal/intern/proc.h +invalid.o: $(hdrdir)/ruby/internal/intern/process.h +invalid.o: $(hdrdir)/ruby/internal/intern/random.h +invalid.o: $(hdrdir)/ruby/internal/intern/range.h +invalid.o: $(hdrdir)/ruby/internal/intern/rational.h +invalid.o: $(hdrdir)/ruby/internal/intern/re.h +invalid.o: $(hdrdir)/ruby/internal/intern/ruby.h +invalid.o: $(hdrdir)/ruby/internal/intern/select.h +invalid.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +invalid.o: $(hdrdir)/ruby/internal/intern/set.h +invalid.o: $(hdrdir)/ruby/internal/intern/signal.h +invalid.o: $(hdrdir)/ruby/internal/intern/sprintf.h +invalid.o: $(hdrdir)/ruby/internal/intern/string.h +invalid.o: $(hdrdir)/ruby/internal/intern/struct.h +invalid.o: $(hdrdir)/ruby/internal/intern/thread.h +invalid.o: $(hdrdir)/ruby/internal/intern/time.h +invalid.o: $(hdrdir)/ruby/internal/intern/variable.h +invalid.o: $(hdrdir)/ruby/internal/intern/vm.h +invalid.o: $(hdrdir)/ruby/internal/interpreter.h +invalid.o: $(hdrdir)/ruby/internal/iterator.h +invalid.o: $(hdrdir)/ruby/internal/memory.h +invalid.o: $(hdrdir)/ruby/internal/method.h +invalid.o: $(hdrdir)/ruby/internal/module.h +invalid.o: $(hdrdir)/ruby/internal/newobj.h +invalid.o: $(hdrdir)/ruby/internal/scan_args.h +invalid.o: $(hdrdir)/ruby/internal/special_consts.h +invalid.o: $(hdrdir)/ruby/internal/static_assert.h +invalid.o: $(hdrdir)/ruby/internal/stdalign.h +invalid.o: $(hdrdir)/ruby/internal/stdbool.h +invalid.o: $(hdrdir)/ruby/internal/stdckdint.h +invalid.o: $(hdrdir)/ruby/internal/symbol.h +invalid.o: $(hdrdir)/ruby/internal/value.h +invalid.o: $(hdrdir)/ruby/internal/value_type.h +invalid.o: $(hdrdir)/ruby/internal/variable.h +invalid.o: $(hdrdir)/ruby/internal/warning_push.h +invalid.o: $(hdrdir)/ruby/internal/xmalloc.h +invalid.o: $(hdrdir)/ruby/missing.h +invalid.o: $(hdrdir)/ruby/ruby.h +invalid.o: $(hdrdir)/ruby/st.h +invalid.o: $(hdrdir)/ruby/subst.h +invalid.o: invalid.c rb_fatal.o: $(RUBY_EXTCONF_H) rb_fatal.o: $(arch_hdrdir)/ruby/config.h rb_fatal.o: $(hdrdir)/ruby.h +rb_fatal.o: $(hdrdir)/ruby/assert.h +rb_fatal.o: $(hdrdir)/ruby/backward.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/assume.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/attributes.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/bool.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/inttypes.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/limits.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/long_long.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/stdalign.h +rb_fatal.o: $(hdrdir)/ruby/backward/2/stdarg.h +rb_fatal.o: $(hdrdir)/ruby/defines.h +rb_fatal.o: $(hdrdir)/ruby/intern.h +rb_fatal.o: $(hdrdir)/ruby/internal/abi.h rb_fatal.o: $(hdrdir)/ruby/internal/anyargs.h rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic.h rb_fatal.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +375,7 @@ rb_fatal.o: $(hdrdir)/ruby/internal/attr/noexcept.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/noinline.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/nonnull.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rb_fatal.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/pure.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/restrict.h rb_fatal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +435,6 @@ rb_fatal.o: $(hdrdir)/ruby/internal/intern/enumerator.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/error.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/eval.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/file.h -rb_fatal.o: $(hdrdir)/ruby/internal/intern/gc.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/hash.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/io.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +451,7 @@ rb_fatal.o: $(hdrdir)/ruby/internal/intern/re.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/ruby.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/select.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rb_fatal.o: $(hdrdir)/ruby/internal/intern/set.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/signal.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/sprintf.h rb_fatal.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +466,18 @@ rb_fatal.o: $(hdrdir)/ruby/internal/memory.h rb_fatal.o: $(hdrdir)/ruby/internal/method.h rb_fatal.o: $(hdrdir)/ruby/internal/module.h rb_fatal.o: $(hdrdir)/ruby/internal/newobj.h -rb_fatal.o: $(hdrdir)/ruby/internal/rgengc.h rb_fatal.o: $(hdrdir)/ruby/internal/scan_args.h rb_fatal.o: $(hdrdir)/ruby/internal/special_consts.h rb_fatal.o: $(hdrdir)/ruby/internal/static_assert.h rb_fatal.o: $(hdrdir)/ruby/internal/stdalign.h rb_fatal.o: $(hdrdir)/ruby/internal/stdbool.h +rb_fatal.o: $(hdrdir)/ruby/internal/stdckdint.h rb_fatal.o: $(hdrdir)/ruby/internal/symbol.h rb_fatal.o: $(hdrdir)/ruby/internal/value.h rb_fatal.o: $(hdrdir)/ruby/internal/value_type.h rb_fatal.o: $(hdrdir)/ruby/internal/variable.h rb_fatal.o: $(hdrdir)/ruby/internal/warning_push.h rb_fatal.o: $(hdrdir)/ruby/internal/xmalloc.h -rb_fatal.o: $(hdrdir)/ruby/assert.h -rb_fatal.o: $(hdrdir)/ruby/backward.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/assume.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/attributes.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/bool.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/inttypes.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/limits.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/long_long.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/stdalign.h -rb_fatal.o: $(hdrdir)/ruby/backward/2/stdarg.h -rb_fatal.o: $(hdrdir)/ruby/defines.h -rb_fatal.o: $(hdrdir)/ruby/intern.h rb_fatal.o: $(hdrdir)/ruby/missing.h rb_fatal.o: $(hdrdir)/ruby/ruby.h rb_fatal.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/fatal/extconf.rb b/ext/-test-/fatal/extconf.rb index d5849c0733..ca51178a18 100644 --- a/ext/-test-/fatal/extconf.rb +++ b/ext/-test-/fatal/extconf.rb @@ -1,2 +1,3 @@ # frozen_string_literal: false -create_makefile("-test-/fatal/rb_fatal") +require_relative "../auto_ext.rb" +auto_ext diff --git a/ext/-test-/fatal/init.c b/ext/-test-/fatal/init.c new file mode 100644 index 0000000000..3b71708789 --- /dev/null +++ b/ext/-test-/fatal/init.c @@ -0,0 +1,10 @@ +#include "ruby.h" + +#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);} + +void +Init_fatal(void) +{ + VALUE klass = rb_define_module("Bug"); + TEST_INIT_FUNCS(init); +} diff --git a/ext/-test-/fatal/invalid.c b/ext/-test-/fatal/invalid.c new file mode 100644 index 0000000000..6fd970b181 --- /dev/null +++ b/ext/-test-/fatal/invalid.c @@ -0,0 +1,22 @@ +#include <ruby.h> + +static VALUE +invalid_call(VALUE obj, VALUE address) +{ + typedef VALUE (*func_type)(VALUE); + + return (*(func_type)NUM2PTR(address))(obj); +} + +static VALUE +invalid_access(VALUE obj, VALUE address) +{ + return *(VALUE *)NUM2PTR(address) == obj ? Qtrue : Qfalse; +} + +void +Init_invalid(VALUE mBug) +{ + rb_define_singleton_method(mBug, "invalid_call", invalid_call, 1); + rb_define_singleton_method(mBug, "invalid_access", invalid_access, 1); +} diff --git a/ext/-test-/fatal/rb_fatal.c b/ext/-test-/fatal/rb_fatal.c index eedbc51f8b..6c7bb89628 100644 --- a/ext/-test-/fatal/rb_fatal.c +++ b/ext/-test-/fatal/rb_fatal.c @@ -13,8 +13,7 @@ ruby_fatal(VALUE obj, VALUE msg) } void -Init_rb_fatal(void) +Init_rb_fatal(VALUE mBug) { - VALUE mBug = rb_define_module("Bug"); rb_define_singleton_method(mBug, "rb_fatal", ruby_fatal, 1); } diff --git a/ext/-test-/file/depend b/ext/-test-/file/depend index 966cbdfd8a..fe320f3d44 100644 --- a/ext/-test-/file/depend +++ b/ext/-test-/file/depend @@ -6,7 +6,6 @@ fs.o: $(hdrdir)/ruby/backward.h fs.o: $(hdrdir)/ruby/backward/2/assume.h fs.o: $(hdrdir)/ruby/backward/2/attributes.h fs.o: $(hdrdir)/ruby/backward/2/bool.h -fs.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h fs.o: $(hdrdir)/ruby/backward/2/inttypes.h fs.o: $(hdrdir)/ruby/backward/2/limits.h fs.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ fs.o: $(hdrdir)/ruby/backward/2/stdarg.h fs.o: $(hdrdir)/ruby/defines.h fs.o: $(hdrdir)/ruby/encoding.h fs.o: $(hdrdir)/ruby/intern.h +fs.o: $(hdrdir)/ruby/internal/abi.h fs.o: $(hdrdir)/ruby/internal/anyargs.h fs.o: $(hdrdir)/ruby/internal/arithmetic.h fs.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ fs.o: $(hdrdir)/ruby/internal/attr/noexcept.h fs.o: $(hdrdir)/ruby/internal/attr/noinline.h fs.o: $(hdrdir)/ruby/internal/attr/nonnull.h fs.o: $(hdrdir)/ruby/internal/attr/noreturn.h +fs.o: $(hdrdir)/ruby/internal/attr/packed_struct.h fs.o: $(hdrdir)/ruby/internal/attr/pure.h fs.o: $(hdrdir)/ruby/internal/attr/restrict.h fs.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -120,7 +121,6 @@ fs.o: $(hdrdir)/ruby/internal/intern/enumerator.h fs.o: $(hdrdir)/ruby/internal/intern/error.h fs.o: $(hdrdir)/ruby/internal/intern/eval.h fs.o: $(hdrdir)/ruby/internal/intern/file.h -fs.o: $(hdrdir)/ruby/internal/intern/gc.h fs.o: $(hdrdir)/ruby/internal/intern/hash.h fs.o: $(hdrdir)/ruby/internal/intern/io.h fs.o: $(hdrdir)/ruby/internal/intern/load.h @@ -137,6 +137,7 @@ fs.o: $(hdrdir)/ruby/internal/intern/re.h fs.o: $(hdrdir)/ruby/internal/intern/ruby.h fs.o: $(hdrdir)/ruby/internal/intern/select.h fs.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +fs.o: $(hdrdir)/ruby/internal/intern/set.h fs.o: $(hdrdir)/ruby/internal/intern/signal.h fs.o: $(hdrdir)/ruby/internal/intern/sprintf.h fs.o: $(hdrdir)/ruby/internal/intern/string.h @@ -151,12 +152,12 @@ fs.o: $(hdrdir)/ruby/internal/memory.h fs.o: $(hdrdir)/ruby/internal/method.h fs.o: $(hdrdir)/ruby/internal/module.h fs.o: $(hdrdir)/ruby/internal/newobj.h -fs.o: $(hdrdir)/ruby/internal/rgengc.h fs.o: $(hdrdir)/ruby/internal/scan_args.h fs.o: $(hdrdir)/ruby/internal/special_consts.h fs.o: $(hdrdir)/ruby/internal/static_assert.h fs.o: $(hdrdir)/ruby/internal/stdalign.h fs.o: $(hdrdir)/ruby/internal/stdbool.h +fs.o: $(hdrdir)/ruby/internal/stdckdint.h fs.o: $(hdrdir)/ruby/internal/symbol.h fs.o: $(hdrdir)/ruby/internal/value.h fs.o: $(hdrdir)/ruby/internal/value_type.h @@ -179,7 +180,6 @@ init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h init.o: $(hdrdir)/ruby/backward/2/inttypes.h init.o: $(hdrdir)/ruby/backward/2/limits.h init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -187,6 +187,7 @@ init.o: $(hdrdir)/ruby/backward/2/stdalign.h init.o: $(hdrdir)/ruby/backward/2/stdarg.h init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -224,6 +225,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -283,7 +285,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -300,6 +301,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -314,12 +316,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h @@ -331,6 +333,179 @@ init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h init.o: $(hdrdir)/ruby/subst.h init.o: init.c +newline_conv.o: $(RUBY_EXTCONF_H) +newline_conv.o: $(arch_hdrdir)/ruby/config.h +newline_conv.o: $(hdrdir)/ruby/assert.h +newline_conv.o: $(hdrdir)/ruby/backward.h +newline_conv.o: $(hdrdir)/ruby/backward/2/assume.h +newline_conv.o: $(hdrdir)/ruby/backward/2/attributes.h +newline_conv.o: $(hdrdir)/ruby/backward/2/bool.h +newline_conv.o: $(hdrdir)/ruby/backward/2/inttypes.h +newline_conv.o: $(hdrdir)/ruby/backward/2/limits.h +newline_conv.o: $(hdrdir)/ruby/backward/2/long_long.h +newline_conv.o: $(hdrdir)/ruby/backward/2/stdalign.h +newline_conv.o: $(hdrdir)/ruby/backward/2/stdarg.h +newline_conv.o: $(hdrdir)/ruby/defines.h +newline_conv.o: $(hdrdir)/ruby/encoding.h +newline_conv.o: $(hdrdir)/ruby/intern.h +newline_conv.o: $(hdrdir)/ruby/internal/abi.h +newline_conv.o: $(hdrdir)/ruby/internal/anyargs.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/char.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/double.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/int.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/long.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/short.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +newline_conv.o: $(hdrdir)/ruby/internal/assume.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/artificial.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/cold.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/const.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/constexpr.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/deprecated.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/error.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/forceinline.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/format.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/noalias.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/noexcept.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/noinline.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/nonnull.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/noreturn.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/pure.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/restrict.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/warning.h +newline_conv.o: $(hdrdir)/ruby/internal/attr/weakref.h +newline_conv.o: $(hdrdir)/ruby/internal/cast.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +newline_conv.o: $(hdrdir)/ruby/internal/compiler_since.h +newline_conv.o: $(hdrdir)/ruby/internal/config.h +newline_conv.o: $(hdrdir)/ruby/internal/constant_p.h +newline_conv.o: $(hdrdir)/ruby/internal/core.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rarray.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rbasic.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rbignum.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rclass.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rdata.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rfile.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rhash.h +newline_conv.o: $(hdrdir)/ruby/internal/core/robject.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rregexp.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rstring.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rstruct.h +newline_conv.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +newline_conv.o: $(hdrdir)/ruby/internal/ctype.h +newline_conv.o: $(hdrdir)/ruby/internal/dllexport.h +newline_conv.o: $(hdrdir)/ruby/internal/dosish.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/coderange.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/ctype.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/encoding.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/pathname.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/re.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/string.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/symbol.h +newline_conv.o: $(hdrdir)/ruby/internal/encoding/transcode.h +newline_conv.o: $(hdrdir)/ruby/internal/error.h +newline_conv.o: $(hdrdir)/ruby/internal/eval.h +newline_conv.o: $(hdrdir)/ruby/internal/event.h +newline_conv.o: $(hdrdir)/ruby/internal/fl_type.h +newline_conv.o: $(hdrdir)/ruby/internal/gc.h +newline_conv.o: $(hdrdir)/ruby/internal/glob.h +newline_conv.o: $(hdrdir)/ruby/internal/globals.h +newline_conv.o: $(hdrdir)/ruby/internal/has/attribute.h +newline_conv.o: $(hdrdir)/ruby/internal/has/builtin.h +newline_conv.o: $(hdrdir)/ruby/internal/has/c_attribute.h +newline_conv.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +newline_conv.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +newline_conv.o: $(hdrdir)/ruby/internal/has/extension.h +newline_conv.o: $(hdrdir)/ruby/internal/has/feature.h +newline_conv.o: $(hdrdir)/ruby/internal/has/warning.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/array.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/bignum.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/class.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/compar.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/complex.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/cont.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/dir.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/enum.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/enumerator.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/error.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/eval.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/file.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/hash.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/io.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/load.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/marshal.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/numeric.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/object.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/parse.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/proc.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/process.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/random.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/range.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/rational.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/re.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/ruby.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/select.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/set.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/signal.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/sprintf.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/string.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/struct.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/thread.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/time.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/variable.h +newline_conv.o: $(hdrdir)/ruby/internal/intern/vm.h +newline_conv.o: $(hdrdir)/ruby/internal/interpreter.h +newline_conv.o: $(hdrdir)/ruby/internal/iterator.h +newline_conv.o: $(hdrdir)/ruby/internal/memory.h +newline_conv.o: $(hdrdir)/ruby/internal/method.h +newline_conv.o: $(hdrdir)/ruby/internal/module.h +newline_conv.o: $(hdrdir)/ruby/internal/newobj.h +newline_conv.o: $(hdrdir)/ruby/internal/scan_args.h +newline_conv.o: $(hdrdir)/ruby/internal/special_consts.h +newline_conv.o: $(hdrdir)/ruby/internal/static_assert.h +newline_conv.o: $(hdrdir)/ruby/internal/stdalign.h +newline_conv.o: $(hdrdir)/ruby/internal/stdbool.h +newline_conv.o: $(hdrdir)/ruby/internal/stdckdint.h +newline_conv.o: $(hdrdir)/ruby/internal/symbol.h +newline_conv.o: $(hdrdir)/ruby/internal/value.h +newline_conv.o: $(hdrdir)/ruby/internal/value_type.h +newline_conv.o: $(hdrdir)/ruby/internal/variable.h +newline_conv.o: $(hdrdir)/ruby/internal/warning_push.h +newline_conv.o: $(hdrdir)/ruby/internal/xmalloc.h +newline_conv.o: $(hdrdir)/ruby/io.h +newline_conv.o: $(hdrdir)/ruby/missing.h +newline_conv.o: $(hdrdir)/ruby/onigmo.h +newline_conv.o: $(hdrdir)/ruby/oniguruma.h +newline_conv.o: $(hdrdir)/ruby/ruby.h +newline_conv.o: $(hdrdir)/ruby/st.h +newline_conv.o: $(hdrdir)/ruby/subst.h +newline_conv.o: newline_conv.c stat.o: $(RUBY_EXTCONF_H) stat.o: $(arch_hdrdir)/ruby/config.h stat.o: $(hdrdir)/ruby/assert.h @@ -338,7 +513,6 @@ stat.o: $(hdrdir)/ruby/backward.h stat.o: $(hdrdir)/ruby/backward/2/assume.h stat.o: $(hdrdir)/ruby/backward/2/attributes.h stat.o: $(hdrdir)/ruby/backward/2/bool.h -stat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h stat.o: $(hdrdir)/ruby/backward/2/inttypes.h stat.o: $(hdrdir)/ruby/backward/2/limits.h stat.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -347,6 +521,7 @@ stat.o: $(hdrdir)/ruby/backward/2/stdarg.h stat.o: $(hdrdir)/ruby/defines.h stat.o: $(hdrdir)/ruby/encoding.h stat.o: $(hdrdir)/ruby/intern.h +stat.o: $(hdrdir)/ruby/internal/abi.h stat.o: $(hdrdir)/ruby/internal/anyargs.h stat.o: $(hdrdir)/ruby/internal/arithmetic.h stat.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -384,6 +559,7 @@ stat.o: $(hdrdir)/ruby/internal/attr/noexcept.h stat.o: $(hdrdir)/ruby/internal/attr/noinline.h stat.o: $(hdrdir)/ruby/internal/attr/nonnull.h stat.o: $(hdrdir)/ruby/internal/attr/noreturn.h +stat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h stat.o: $(hdrdir)/ruby/internal/attr/pure.h stat.o: $(hdrdir)/ruby/internal/attr/restrict.h stat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -452,7 +628,6 @@ stat.o: $(hdrdir)/ruby/internal/intern/enumerator.h stat.o: $(hdrdir)/ruby/internal/intern/error.h stat.o: $(hdrdir)/ruby/internal/intern/eval.h stat.o: $(hdrdir)/ruby/internal/intern/file.h -stat.o: $(hdrdir)/ruby/internal/intern/gc.h stat.o: $(hdrdir)/ruby/internal/intern/hash.h stat.o: $(hdrdir)/ruby/internal/intern/io.h stat.o: $(hdrdir)/ruby/internal/intern/load.h @@ -469,6 +644,7 @@ stat.o: $(hdrdir)/ruby/internal/intern/re.h stat.o: $(hdrdir)/ruby/internal/intern/ruby.h stat.o: $(hdrdir)/ruby/internal/intern/select.h stat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +stat.o: $(hdrdir)/ruby/internal/intern/set.h stat.o: $(hdrdir)/ruby/internal/intern/signal.h stat.o: $(hdrdir)/ruby/internal/intern/sprintf.h stat.o: $(hdrdir)/ruby/internal/intern/string.h @@ -483,12 +659,12 @@ stat.o: $(hdrdir)/ruby/internal/memory.h stat.o: $(hdrdir)/ruby/internal/method.h stat.o: $(hdrdir)/ruby/internal/module.h stat.o: $(hdrdir)/ruby/internal/newobj.h -stat.o: $(hdrdir)/ruby/internal/rgengc.h stat.o: $(hdrdir)/ruby/internal/scan_args.h stat.o: $(hdrdir)/ruby/internal/special_consts.h stat.o: $(hdrdir)/ruby/internal/static_assert.h stat.o: $(hdrdir)/ruby/internal/stdalign.h stat.o: $(hdrdir)/ruby/internal/stdbool.h +stat.o: $(hdrdir)/ruby/internal/stdckdint.h stat.o: $(hdrdir)/ruby/internal/symbol.h stat.o: $(hdrdir)/ruby/internal/value.h stat.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/file/fs.c b/ext/-test-/file/fs.c index 63d2356d76..eb17e9768e 100644 --- a/ext/-test-/file/fs.c +++ b/ext/-test-/file/fs.c @@ -28,7 +28,7 @@ typedef struct statvfs statfs_t; # if defined HAVE_STRUCT_STATVFS_F_TYPE # define HAVE_STRUCT_STATFS_T_F_TYPE 1 # endif -#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) /* AIX, HP-UX, Solaris */ +#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) /* AIX, Solaris */ typedef struct statvfs statfs_t; # define STATFS(f, s) statvfs((f), (s)) # define HAVE_STRUCT_STATFS_T_F_FSTYPENAME 1 @@ -54,24 +54,24 @@ get_fsname(VALUE self, VALUE str) FilePathValue(str); str = rb_str_encode_ospath(str); if (STATFS(StringValueCStr(str), &st) == -1) { - rb_sys_fail_str(str); + rb_sys_fail_str(str); } # ifdef HAVE_STRUCT_STATFS_T_F_FSTYPENAME if (st.f_fstypename[0]) - return CSTR(st.f_fstypename); + return CSTR(st.f_fstypename); # endif # ifdef HAVE_STRUCT_STATFS_T_F_TYPE switch (st.f_type) { case 0x9123683E: /* BTRFS_SUPER_MAGIC */ - return CSTR("btrfs"); + return CSTR("btrfs"); case 0x7461636f: /* OCFS2_SUPER_MAGIC */ - return CSTR("ocfs"); + return CSTR("ocfs"); case 0xEF53: /* EXT2_SUPER_MAGIC EXT3_SUPER_MAGIC EXT4_SUPER_MAGIC */ - return CSTR("ext4"); + return CSTR("ext4"); case 0x58465342: /* XFS_SUPER_MAGIC */ - return CSTR("xfs"); + return CSTR("xfs"); case 0x01021994: /* TMPFS_MAGIC */ - return CSTR("tmpfs"); + return CSTR("tmpfs"); } # endif #endif diff --git a/ext/-test-/file/newline_conv.c b/ext/-test-/file/newline_conv.c new file mode 100644 index 0000000000..2ac5aef801 --- /dev/null +++ b/ext/-test-/file/newline_conv.c @@ -0,0 +1,73 @@ +#include "ruby/ruby.h" +#include "ruby/io.h" +#include <fcntl.h> + +static VALUE +open_with_rb_file_open(VALUE self, VALUE filename, VALUE read_or_write, VALUE binary_or_text) +{ + char fmode[3] = { 0 }; + if (rb_sym2id(read_or_write) == rb_intern("read")) { + fmode[0] = 'r'; + } + else if (rb_sym2id(read_or_write) == rb_intern("write")) { + fmode[0] = 'w'; + } + else { + rb_raise(rb_eArgError, "read_or_write param must be :read or :write"); + } + + if (rb_sym2id(binary_or_text) == rb_intern("binary")) { + fmode[1] = 'b'; + } + else if (rb_sym2id(binary_or_text) == rb_intern("text")) { + + } + else { + rb_raise(rb_eArgError, "binary_or_text param must be :binary or :text"); + } + + return rb_file_open(StringValueCStr(filename), fmode); +} + +static VALUE +open_with_rb_io_fdopen(VALUE self, VALUE filename, VALUE read_or_write, VALUE binary_or_text) +{ + int omode = 0; + if (rb_sym2id(read_or_write) == rb_intern("read")) { + omode |= O_RDONLY; + } + else if (rb_sym2id(read_or_write) == rb_intern("write")) { + omode |= O_WRONLY; + } + else { + rb_raise(rb_eArgError, "read_or_write param must be :read or :write"); + } + + if (rb_sym2id(binary_or_text) == rb_intern("binary")) { +#ifdef O_BINARY + omode |= O_BINARY; +#endif + } + else if (rb_sym2id(binary_or_text) == rb_intern("text")) { + + } + else { + rb_raise(rb_eArgError, "binary_or_text param must be :binary or :text"); + } + + int fd = rb_cloexec_open(StringValueCStr(filename), omode, 0); + if (fd < 0) { + rb_raise(rb_eIOError, "failed to open the file"); + } + + rb_update_max_fd(fd); + return rb_io_fdopen(fd, omode, StringValueCStr(filename)); +} + +void +Init_newline_conv(VALUE module) +{ + VALUE newline_conv = rb_define_module_under(module, "NewlineConv"); + rb_define_module_function(newline_conv, "rb_file_open", open_with_rb_file_open, 3); + rb_define_module_function(newline_conv, "rb_io_fdopen", open_with_rb_io_fdopen, 3); +} diff --git a/ext/-test-/float/depend b/ext/-test-/float/depend index 55b014e8a0..334ed33c3b 100644 --- a/ext/-test-/float/depend +++ b/ext/-test-/float/depend @@ -5,6 +5,19 @@ nextafter.o: nextafter.c $(top_srcdir)/missing/nextafter.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -42,6 +55,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -101,7 +115,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -118,6 +131,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -132,31 +146,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -165,6 +166,19 @@ init.o: init.c nextafter.o: $(RUBY_EXTCONF_H) nextafter.o: $(arch_hdrdir)/ruby/config.h nextafter.o: $(hdrdir)/ruby.h +nextafter.o: $(hdrdir)/ruby/assert.h +nextafter.o: $(hdrdir)/ruby/backward.h +nextafter.o: $(hdrdir)/ruby/backward/2/assume.h +nextafter.o: $(hdrdir)/ruby/backward/2/attributes.h +nextafter.o: $(hdrdir)/ruby/backward/2/bool.h +nextafter.o: $(hdrdir)/ruby/backward/2/inttypes.h +nextafter.o: $(hdrdir)/ruby/backward/2/limits.h +nextafter.o: $(hdrdir)/ruby/backward/2/long_long.h +nextafter.o: $(hdrdir)/ruby/backward/2/stdalign.h +nextafter.o: $(hdrdir)/ruby/backward/2/stdarg.h +nextafter.o: $(hdrdir)/ruby/defines.h +nextafter.o: $(hdrdir)/ruby/intern.h +nextafter.o: $(hdrdir)/ruby/internal/abi.h nextafter.o: $(hdrdir)/ruby/internal/anyargs.h nextafter.o: $(hdrdir)/ruby/internal/arithmetic.h nextafter.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -202,6 +216,7 @@ nextafter.o: $(hdrdir)/ruby/internal/attr/noexcept.h nextafter.o: $(hdrdir)/ruby/internal/attr/noinline.h nextafter.o: $(hdrdir)/ruby/internal/attr/nonnull.h nextafter.o: $(hdrdir)/ruby/internal/attr/noreturn.h +nextafter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h nextafter.o: $(hdrdir)/ruby/internal/attr/pure.h nextafter.o: $(hdrdir)/ruby/internal/attr/restrict.h nextafter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -261,7 +276,6 @@ nextafter.o: $(hdrdir)/ruby/internal/intern/enumerator.h nextafter.o: $(hdrdir)/ruby/internal/intern/error.h nextafter.o: $(hdrdir)/ruby/internal/intern/eval.h nextafter.o: $(hdrdir)/ruby/internal/intern/file.h -nextafter.o: $(hdrdir)/ruby/internal/intern/gc.h nextafter.o: $(hdrdir)/ruby/internal/intern/hash.h nextafter.o: $(hdrdir)/ruby/internal/intern/io.h nextafter.o: $(hdrdir)/ruby/internal/intern/load.h @@ -278,6 +292,7 @@ nextafter.o: $(hdrdir)/ruby/internal/intern/re.h nextafter.o: $(hdrdir)/ruby/internal/intern/ruby.h nextafter.o: $(hdrdir)/ruby/internal/intern/select.h nextafter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +nextafter.o: $(hdrdir)/ruby/internal/intern/set.h nextafter.o: $(hdrdir)/ruby/internal/intern/signal.h nextafter.o: $(hdrdir)/ruby/internal/intern/sprintf.h nextafter.o: $(hdrdir)/ruby/internal/intern/string.h @@ -292,31 +307,18 @@ nextafter.o: $(hdrdir)/ruby/internal/memory.h nextafter.o: $(hdrdir)/ruby/internal/method.h nextafter.o: $(hdrdir)/ruby/internal/module.h nextafter.o: $(hdrdir)/ruby/internal/newobj.h -nextafter.o: $(hdrdir)/ruby/internal/rgengc.h nextafter.o: $(hdrdir)/ruby/internal/scan_args.h nextafter.o: $(hdrdir)/ruby/internal/special_consts.h nextafter.o: $(hdrdir)/ruby/internal/static_assert.h nextafter.o: $(hdrdir)/ruby/internal/stdalign.h nextafter.o: $(hdrdir)/ruby/internal/stdbool.h +nextafter.o: $(hdrdir)/ruby/internal/stdckdint.h nextafter.o: $(hdrdir)/ruby/internal/symbol.h nextafter.o: $(hdrdir)/ruby/internal/value.h nextafter.o: $(hdrdir)/ruby/internal/value_type.h nextafter.o: $(hdrdir)/ruby/internal/variable.h nextafter.o: $(hdrdir)/ruby/internal/warning_push.h nextafter.o: $(hdrdir)/ruby/internal/xmalloc.h -nextafter.o: $(hdrdir)/ruby/assert.h -nextafter.o: $(hdrdir)/ruby/backward.h -nextafter.o: $(hdrdir)/ruby/backward/2/assume.h -nextafter.o: $(hdrdir)/ruby/backward/2/attributes.h -nextafter.o: $(hdrdir)/ruby/backward/2/bool.h -nextafter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -nextafter.o: $(hdrdir)/ruby/backward/2/inttypes.h -nextafter.o: $(hdrdir)/ruby/backward/2/limits.h -nextafter.o: $(hdrdir)/ruby/backward/2/long_long.h -nextafter.o: $(hdrdir)/ruby/backward/2/stdalign.h -nextafter.o: $(hdrdir)/ruby/backward/2/stdarg.h -nextafter.o: $(hdrdir)/ruby/defines.h -nextafter.o: $(hdrdir)/ruby/intern.h nextafter.o: $(hdrdir)/ruby/missing.h nextafter.o: $(hdrdir)/ruby/ruby.h nextafter.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/funcall/depend b/ext/-test-/funcall/depend index 412ad522d5..e54370306f 100644 --- a/ext/-test-/funcall/depend +++ b/ext/-test-/funcall/depend @@ -2,6 +2,19 @@ funcall.o: $(RUBY_EXTCONF_H) funcall.o: $(arch_hdrdir)/ruby/config.h funcall.o: $(hdrdir)/ruby.h +funcall.o: $(hdrdir)/ruby/assert.h +funcall.o: $(hdrdir)/ruby/backward.h +funcall.o: $(hdrdir)/ruby/backward/2/assume.h +funcall.o: $(hdrdir)/ruby/backward/2/attributes.h +funcall.o: $(hdrdir)/ruby/backward/2/bool.h +funcall.o: $(hdrdir)/ruby/backward/2/inttypes.h +funcall.o: $(hdrdir)/ruby/backward/2/limits.h +funcall.o: $(hdrdir)/ruby/backward/2/long_long.h +funcall.o: $(hdrdir)/ruby/backward/2/stdalign.h +funcall.o: $(hdrdir)/ruby/backward/2/stdarg.h +funcall.o: $(hdrdir)/ruby/defines.h +funcall.o: $(hdrdir)/ruby/intern.h +funcall.o: $(hdrdir)/ruby/internal/abi.h funcall.o: $(hdrdir)/ruby/internal/anyargs.h funcall.o: $(hdrdir)/ruby/internal/arithmetic.h funcall.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ funcall.o: $(hdrdir)/ruby/internal/attr/noexcept.h funcall.o: $(hdrdir)/ruby/internal/attr/noinline.h funcall.o: $(hdrdir)/ruby/internal/attr/nonnull.h funcall.o: $(hdrdir)/ruby/internal/attr/noreturn.h +funcall.o: $(hdrdir)/ruby/internal/attr/packed_struct.h funcall.o: $(hdrdir)/ruby/internal/attr/pure.h funcall.o: $(hdrdir)/ruby/internal/attr/restrict.h funcall.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ funcall.o: $(hdrdir)/ruby/internal/intern/enumerator.h funcall.o: $(hdrdir)/ruby/internal/intern/error.h funcall.o: $(hdrdir)/ruby/internal/intern/eval.h funcall.o: $(hdrdir)/ruby/internal/intern/file.h -funcall.o: $(hdrdir)/ruby/internal/intern/gc.h funcall.o: $(hdrdir)/ruby/internal/intern/hash.h funcall.o: $(hdrdir)/ruby/internal/intern/io.h funcall.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ funcall.o: $(hdrdir)/ruby/internal/intern/re.h funcall.o: $(hdrdir)/ruby/internal/intern/ruby.h funcall.o: $(hdrdir)/ruby/internal/intern/select.h funcall.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +funcall.o: $(hdrdir)/ruby/internal/intern/set.h funcall.o: $(hdrdir)/ruby/internal/intern/signal.h funcall.o: $(hdrdir)/ruby/internal/intern/sprintf.h funcall.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ funcall.o: $(hdrdir)/ruby/internal/memory.h funcall.o: $(hdrdir)/ruby/internal/method.h funcall.o: $(hdrdir)/ruby/internal/module.h funcall.o: $(hdrdir)/ruby/internal/newobj.h -funcall.o: $(hdrdir)/ruby/internal/rgengc.h funcall.o: $(hdrdir)/ruby/internal/scan_args.h funcall.o: $(hdrdir)/ruby/internal/special_consts.h funcall.o: $(hdrdir)/ruby/internal/static_assert.h funcall.o: $(hdrdir)/ruby/internal/stdalign.h funcall.o: $(hdrdir)/ruby/internal/stdbool.h +funcall.o: $(hdrdir)/ruby/internal/stdckdint.h funcall.o: $(hdrdir)/ruby/internal/symbol.h funcall.o: $(hdrdir)/ruby/internal/value.h funcall.o: $(hdrdir)/ruby/internal/value_type.h funcall.o: $(hdrdir)/ruby/internal/variable.h funcall.o: $(hdrdir)/ruby/internal/warning_push.h funcall.o: $(hdrdir)/ruby/internal/xmalloc.h -funcall.o: $(hdrdir)/ruby/assert.h -funcall.o: $(hdrdir)/ruby/backward.h -funcall.o: $(hdrdir)/ruby/backward/2/assume.h -funcall.o: $(hdrdir)/ruby/backward/2/attributes.h -funcall.o: $(hdrdir)/ruby/backward/2/bool.h -funcall.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -funcall.o: $(hdrdir)/ruby/backward/2/inttypes.h -funcall.o: $(hdrdir)/ruby/backward/2/limits.h -funcall.o: $(hdrdir)/ruby/backward/2/long_long.h -funcall.o: $(hdrdir)/ruby/backward/2/stdalign.h -funcall.o: $(hdrdir)/ruby/backward/2/stdarg.h -funcall.o: $(hdrdir)/ruby/defines.h -funcall.o: $(hdrdir)/ruby/intern.h funcall.o: $(hdrdir)/ruby/missing.h funcall.o: $(hdrdir)/ruby/ruby.h funcall.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/funcall/funcall.c b/ext/-test-/funcall/funcall.c index 43521bf2e9..a68d6de255 100644 --- a/ext/-test-/funcall/funcall.c +++ b/ext/-test-/funcall/funcall.c @@ -47,17 +47,17 @@ Init_funcall(void) VALUE cRelay = rb_define_module_under(cTestFuncall, "Relay"); rb_define_singleton_method(cRelay, - "with_funcall2", - with_funcall2, - -1); + "with_funcall2", + with_funcall2, + -1); rb_define_singleton_method(cRelay, "with_funcall_passing_block_kw", with_funcall_passing_block_kw, -1); rb_define_singleton_method(cRelay, - "with_funcall_passing_block", - with_funcall_passing_block, - -1); + "with_funcall_passing_block", + with_funcall_passing_block, + -1); rb_define_singleton_method(cRelay, "with_funcallv_public_kw", with_funcallv_public_kw, diff --git a/ext/-test-/gvl/call_without_gvl/call_without_gvl.c b/ext/-test-/gvl/call_without_gvl/call_without_gvl.c index 233635421b..97946e925d 100644 --- a/ext/-test-/gvl/call_without_gvl/call_without_gvl.c +++ b/ext/-test-/gvl/call_without_gvl/call_without_gvl.c @@ -17,7 +17,7 @@ thread_runnable_sleep(VALUE thread, VALUE timeout) struct timeval timeval; if (NIL_P(timeout)) { - rb_raise(rb_eArgError, "timeout must be non nil"); + rb_raise(rb_eArgError, "timeout must be non nil"); } timeval = rb_time_interval(timeout); diff --git a/ext/-test-/gvl/call_without_gvl/depend b/ext/-test-/gvl/call_without_gvl/depend index e6ecd43ef7..236d1e1d3b 100644 --- a/ext/-test-/gvl/call_without_gvl/depend +++ b/ext/-test-/gvl/call_without_gvl/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START call_without_gvl.o: $(RUBY_EXTCONF_H) call_without_gvl.o: $(arch_hdrdir)/ruby/config.h +call_without_gvl.o: $(hdrdir)/ruby/assert.h +call_without_gvl.o: $(hdrdir)/ruby/backward.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/assume.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/attributes.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/bool.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/inttypes.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/limits.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/long_long.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdalign.h +call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdarg.h +call_without_gvl.o: $(hdrdir)/ruby/defines.h +call_without_gvl.o: $(hdrdir)/ruby/intern.h +call_without_gvl.o: $(hdrdir)/ruby/internal/abi.h call_without_gvl.o: $(hdrdir)/ruby/internal/anyargs.h call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic.h call_without_gvl.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noexcept.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noinline.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/nonnull.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +call_without_gvl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/pure.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/restrict.h call_without_gvl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/intern/enumerator.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/error.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/eval.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/file.h -call_without_gvl.o: $(hdrdir)/ruby/internal/intern/gc.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/hash.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/io.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/intern/re.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/ruby.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/select.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +call_without_gvl.o: $(hdrdir)/ruby/internal/intern/set.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/signal.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/sprintf.h call_without_gvl.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ call_without_gvl.o: $(hdrdir)/ruby/internal/memory.h call_without_gvl.o: $(hdrdir)/ruby/internal/method.h call_without_gvl.o: $(hdrdir)/ruby/internal/module.h call_without_gvl.o: $(hdrdir)/ruby/internal/newobj.h -call_without_gvl.o: $(hdrdir)/ruby/internal/rgengc.h call_without_gvl.o: $(hdrdir)/ruby/internal/scan_args.h call_without_gvl.o: $(hdrdir)/ruby/internal/special_consts.h call_without_gvl.o: $(hdrdir)/ruby/internal/static_assert.h call_without_gvl.o: $(hdrdir)/ruby/internal/stdalign.h call_without_gvl.o: $(hdrdir)/ruby/internal/stdbool.h +call_without_gvl.o: $(hdrdir)/ruby/internal/stdckdint.h call_without_gvl.o: $(hdrdir)/ruby/internal/symbol.h call_without_gvl.o: $(hdrdir)/ruby/internal/value.h call_without_gvl.o: $(hdrdir)/ruby/internal/value_type.h call_without_gvl.o: $(hdrdir)/ruby/internal/variable.h call_without_gvl.o: $(hdrdir)/ruby/internal/warning_push.h call_without_gvl.o: $(hdrdir)/ruby/internal/xmalloc.h -call_without_gvl.o: $(hdrdir)/ruby/assert.h -call_without_gvl.o: $(hdrdir)/ruby/backward.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/assume.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/attributes.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/bool.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/inttypes.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/limits.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/long_long.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdalign.h -call_without_gvl.o: $(hdrdir)/ruby/backward/2/stdarg.h -call_without_gvl.o: $(hdrdir)/ruby/defines.h -call_without_gvl.o: $(hdrdir)/ruby/intern.h call_without_gvl.o: $(hdrdir)/ruby/missing.h call_without_gvl.o: $(hdrdir)/ruby/ruby.h call_without_gvl.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/hash/depend b/ext/-test-/hash/depend index fe52e9bb1a..416b93f9de 100644 --- a/ext/-test-/hash/depend +++ b/ext/-test-/hash/depend @@ -2,6 +2,19 @@ delete.o: $(RUBY_EXTCONF_H) delete.o: $(arch_hdrdir)/ruby/config.h delete.o: $(hdrdir)/ruby.h +delete.o: $(hdrdir)/ruby/assert.h +delete.o: $(hdrdir)/ruby/backward.h +delete.o: $(hdrdir)/ruby/backward/2/assume.h +delete.o: $(hdrdir)/ruby/backward/2/attributes.h +delete.o: $(hdrdir)/ruby/backward/2/bool.h +delete.o: $(hdrdir)/ruby/backward/2/inttypes.h +delete.o: $(hdrdir)/ruby/backward/2/limits.h +delete.o: $(hdrdir)/ruby/backward/2/long_long.h +delete.o: $(hdrdir)/ruby/backward/2/stdalign.h +delete.o: $(hdrdir)/ruby/backward/2/stdarg.h +delete.o: $(hdrdir)/ruby/defines.h +delete.o: $(hdrdir)/ruby/intern.h +delete.o: $(hdrdir)/ruby/internal/abi.h delete.o: $(hdrdir)/ruby/internal/anyargs.h delete.o: $(hdrdir)/ruby/internal/arithmetic.h delete.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ delete.o: $(hdrdir)/ruby/internal/attr/noexcept.h delete.o: $(hdrdir)/ruby/internal/attr/noinline.h delete.o: $(hdrdir)/ruby/internal/attr/nonnull.h delete.o: $(hdrdir)/ruby/internal/attr/noreturn.h +delete.o: $(hdrdir)/ruby/internal/attr/packed_struct.h delete.o: $(hdrdir)/ruby/internal/attr/pure.h delete.o: $(hdrdir)/ruby/internal/attr/restrict.h delete.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ delete.o: $(hdrdir)/ruby/internal/intern/enumerator.h delete.o: $(hdrdir)/ruby/internal/intern/error.h delete.o: $(hdrdir)/ruby/internal/intern/eval.h delete.o: $(hdrdir)/ruby/internal/intern/file.h -delete.o: $(hdrdir)/ruby/internal/intern/gc.h delete.o: $(hdrdir)/ruby/internal/intern/hash.h delete.o: $(hdrdir)/ruby/internal/intern/io.h delete.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ delete.o: $(hdrdir)/ruby/internal/intern/re.h delete.o: $(hdrdir)/ruby/internal/intern/ruby.h delete.o: $(hdrdir)/ruby/internal/intern/select.h delete.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +delete.o: $(hdrdir)/ruby/internal/intern/set.h delete.o: $(hdrdir)/ruby/internal/intern/signal.h delete.o: $(hdrdir)/ruby/internal/intern/sprintf.h delete.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ delete.o: $(hdrdir)/ruby/internal/memory.h delete.o: $(hdrdir)/ruby/internal/method.h delete.o: $(hdrdir)/ruby/internal/module.h delete.o: $(hdrdir)/ruby/internal/newobj.h -delete.o: $(hdrdir)/ruby/internal/rgengc.h delete.o: $(hdrdir)/ruby/internal/scan_args.h delete.o: $(hdrdir)/ruby/internal/special_consts.h delete.o: $(hdrdir)/ruby/internal/static_assert.h delete.o: $(hdrdir)/ruby/internal/stdalign.h delete.o: $(hdrdir)/ruby/internal/stdbool.h +delete.o: $(hdrdir)/ruby/internal/stdckdint.h delete.o: $(hdrdir)/ruby/internal/symbol.h delete.o: $(hdrdir)/ruby/internal/value.h delete.o: $(hdrdir)/ruby/internal/value_type.h delete.o: $(hdrdir)/ruby/internal/variable.h delete.o: $(hdrdir)/ruby/internal/warning_push.h delete.o: $(hdrdir)/ruby/internal/xmalloc.h -delete.o: $(hdrdir)/ruby/assert.h -delete.o: $(hdrdir)/ruby/backward.h -delete.o: $(hdrdir)/ruby/backward/2/assume.h -delete.o: $(hdrdir)/ruby/backward/2/attributes.h -delete.o: $(hdrdir)/ruby/backward/2/bool.h -delete.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -delete.o: $(hdrdir)/ruby/backward/2/inttypes.h -delete.o: $(hdrdir)/ruby/backward/2/limits.h -delete.o: $(hdrdir)/ruby/backward/2/long_long.h -delete.o: $(hdrdir)/ruby/backward/2/stdalign.h -delete.o: $(hdrdir)/ruby/backward/2/stdarg.h -delete.o: $(hdrdir)/ruby/defines.h -delete.o: $(hdrdir)/ruby/intern.h delete.o: $(hdrdir)/ruby/missing.h delete.o: $(hdrdir)/ruby/ruby.h delete.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ delete.o: delete.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/integer/depend b/ext/-test-/integer/depend index 825110658b..0ea007e814 100644 --- a/ext/-test-/integer/depend +++ b/ext/-test-/integer/depend @@ -1,7 +1,20 @@ # AUTOGENERATED DEPENDENCIES START core_ext.o: $(RUBY_EXTCONF_H) core_ext.o: $(arch_hdrdir)/ruby/config.h -core_ext.o: $(hdrdir)/ruby.h +core_ext.o: $(hdrdir)/ruby/assert.h +core_ext.o: $(hdrdir)/ruby/backward.h +core_ext.o: $(hdrdir)/ruby/backward/2/assume.h +core_ext.o: $(hdrdir)/ruby/backward/2/attributes.h +core_ext.o: $(hdrdir)/ruby/backward/2/bool.h +core_ext.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +core_ext.o: $(hdrdir)/ruby/backward/2/inttypes.h +core_ext.o: $(hdrdir)/ruby/backward/2/limits.h +core_ext.o: $(hdrdir)/ruby/backward/2/long_long.h +core_ext.o: $(hdrdir)/ruby/backward/2/stdalign.h +core_ext.o: $(hdrdir)/ruby/backward/2/stdarg.h +core_ext.o: $(hdrdir)/ruby/defines.h +core_ext.o: $(hdrdir)/ruby/intern.h +core_ext.o: $(hdrdir)/ruby/internal/abi.h core_ext.o: $(hdrdir)/ruby/internal/anyargs.h core_ext.o: $(hdrdir)/ruby/internal/arithmetic.h core_ext.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ core_ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h core_ext.o: $(hdrdir)/ruby/internal/attr/noinline.h core_ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h core_ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h +core_ext.o: $(hdrdir)/ruby/internal/attr/packed_struct.h core_ext.o: $(hdrdir)/ruby/internal/attr/pure.h core_ext.o: $(hdrdir)/ruby/internal/attr/restrict.h core_ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ core_ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h core_ext.o: $(hdrdir)/ruby/internal/intern/error.h core_ext.o: $(hdrdir)/ruby/internal/intern/eval.h core_ext.o: $(hdrdir)/ruby/internal/intern/file.h -core_ext.o: $(hdrdir)/ruby/internal/intern/gc.h core_ext.o: $(hdrdir)/ruby/internal/intern/hash.h core_ext.o: $(hdrdir)/ruby/internal/intern/io.h core_ext.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ core_ext.o: $(hdrdir)/ruby/internal/intern/re.h core_ext.o: $(hdrdir)/ruby/internal/intern/ruby.h core_ext.o: $(hdrdir)/ruby/internal/intern/select.h core_ext.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +core_ext.o: $(hdrdir)/ruby/internal/intern/set.h core_ext.o: $(hdrdir)/ruby/internal/intern/signal.h core_ext.o: $(hdrdir)/ruby/internal/intern/sprintf.h core_ext.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,36 +143,22 @@ core_ext.o: $(hdrdir)/ruby/internal/memory.h core_ext.o: $(hdrdir)/ruby/internal/method.h core_ext.o: $(hdrdir)/ruby/internal/module.h core_ext.o: $(hdrdir)/ruby/internal/newobj.h -core_ext.o: $(hdrdir)/ruby/internal/rgengc.h core_ext.o: $(hdrdir)/ruby/internal/scan_args.h core_ext.o: $(hdrdir)/ruby/internal/special_consts.h core_ext.o: $(hdrdir)/ruby/internal/static_assert.h core_ext.o: $(hdrdir)/ruby/internal/stdalign.h core_ext.o: $(hdrdir)/ruby/internal/stdbool.h +core_ext.o: $(hdrdir)/ruby/internal/stdckdint.h core_ext.o: $(hdrdir)/ruby/internal/symbol.h core_ext.o: $(hdrdir)/ruby/internal/value.h core_ext.o: $(hdrdir)/ruby/internal/value_type.h core_ext.o: $(hdrdir)/ruby/internal/variable.h core_ext.o: $(hdrdir)/ruby/internal/warning_push.h core_ext.o: $(hdrdir)/ruby/internal/xmalloc.h -core_ext.o: $(hdrdir)/ruby/assert.h -core_ext.o: $(hdrdir)/ruby/backward.h -core_ext.o: $(hdrdir)/ruby/backward/2/assume.h -core_ext.o: $(hdrdir)/ruby/backward/2/attributes.h -core_ext.o: $(hdrdir)/ruby/backward/2/bool.h -core_ext.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -core_ext.o: $(hdrdir)/ruby/backward/2/inttypes.h -core_ext.o: $(hdrdir)/ruby/backward/2/limits.h -core_ext.o: $(hdrdir)/ruby/backward/2/long_long.h -core_ext.o: $(hdrdir)/ruby/backward/2/stdalign.h -core_ext.o: $(hdrdir)/ruby/backward/2/stdarg.h -core_ext.o: $(hdrdir)/ruby/defines.h -core_ext.o: $(hdrdir)/ruby/intern.h core_ext.o: $(hdrdir)/ruby/missing.h core_ext.o: $(hdrdir)/ruby/ruby.h core_ext.o: $(hdrdir)/ruby/st.h core_ext.o: $(hdrdir)/ruby/subst.h -core_ext.o: $(top_srcdir)/internal.h core_ext.o: $(top_srcdir)/internal/bignum.h core_ext.o: $(top_srcdir)/internal/bits.h core_ext.o: $(top_srcdir)/internal/compilers.h @@ -171,6 +171,19 @@ core_ext.o: core_ext.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -208,6 +221,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -267,7 +281,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -284,6 +297,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -298,31 +312,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -331,6 +332,19 @@ init.o: init.c my_integer.o: $(RUBY_EXTCONF_H) my_integer.o: $(arch_hdrdir)/ruby/config.h my_integer.o: $(hdrdir)/ruby.h +my_integer.o: $(hdrdir)/ruby/assert.h +my_integer.o: $(hdrdir)/ruby/backward.h +my_integer.o: $(hdrdir)/ruby/backward/2/assume.h +my_integer.o: $(hdrdir)/ruby/backward/2/attributes.h +my_integer.o: $(hdrdir)/ruby/backward/2/bool.h +my_integer.o: $(hdrdir)/ruby/backward/2/inttypes.h +my_integer.o: $(hdrdir)/ruby/backward/2/limits.h +my_integer.o: $(hdrdir)/ruby/backward/2/long_long.h +my_integer.o: $(hdrdir)/ruby/backward/2/stdalign.h +my_integer.o: $(hdrdir)/ruby/backward/2/stdarg.h +my_integer.o: $(hdrdir)/ruby/defines.h +my_integer.o: $(hdrdir)/ruby/intern.h +my_integer.o: $(hdrdir)/ruby/internal/abi.h my_integer.o: $(hdrdir)/ruby/internal/anyargs.h my_integer.o: $(hdrdir)/ruby/internal/arithmetic.h my_integer.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -368,6 +382,7 @@ my_integer.o: $(hdrdir)/ruby/internal/attr/noexcept.h my_integer.o: $(hdrdir)/ruby/internal/attr/noinline.h my_integer.o: $(hdrdir)/ruby/internal/attr/nonnull.h my_integer.o: $(hdrdir)/ruby/internal/attr/noreturn.h +my_integer.o: $(hdrdir)/ruby/internal/attr/packed_struct.h my_integer.o: $(hdrdir)/ruby/internal/attr/pure.h my_integer.o: $(hdrdir)/ruby/internal/attr/restrict.h my_integer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -427,7 +442,6 @@ my_integer.o: $(hdrdir)/ruby/internal/intern/enumerator.h my_integer.o: $(hdrdir)/ruby/internal/intern/error.h my_integer.o: $(hdrdir)/ruby/internal/intern/eval.h my_integer.o: $(hdrdir)/ruby/internal/intern/file.h -my_integer.o: $(hdrdir)/ruby/internal/intern/gc.h my_integer.o: $(hdrdir)/ruby/internal/intern/hash.h my_integer.o: $(hdrdir)/ruby/internal/intern/io.h my_integer.o: $(hdrdir)/ruby/internal/intern/load.h @@ -444,6 +458,7 @@ my_integer.o: $(hdrdir)/ruby/internal/intern/re.h my_integer.o: $(hdrdir)/ruby/internal/intern/ruby.h my_integer.o: $(hdrdir)/ruby/internal/intern/select.h my_integer.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +my_integer.o: $(hdrdir)/ruby/internal/intern/set.h my_integer.o: $(hdrdir)/ruby/internal/intern/signal.h my_integer.o: $(hdrdir)/ruby/internal/intern/sprintf.h my_integer.o: $(hdrdir)/ruby/internal/intern/string.h @@ -458,31 +473,18 @@ my_integer.o: $(hdrdir)/ruby/internal/memory.h my_integer.o: $(hdrdir)/ruby/internal/method.h my_integer.o: $(hdrdir)/ruby/internal/module.h my_integer.o: $(hdrdir)/ruby/internal/newobj.h -my_integer.o: $(hdrdir)/ruby/internal/rgengc.h my_integer.o: $(hdrdir)/ruby/internal/scan_args.h my_integer.o: $(hdrdir)/ruby/internal/special_consts.h my_integer.o: $(hdrdir)/ruby/internal/static_assert.h my_integer.o: $(hdrdir)/ruby/internal/stdalign.h my_integer.o: $(hdrdir)/ruby/internal/stdbool.h +my_integer.o: $(hdrdir)/ruby/internal/stdckdint.h my_integer.o: $(hdrdir)/ruby/internal/symbol.h my_integer.o: $(hdrdir)/ruby/internal/value.h my_integer.o: $(hdrdir)/ruby/internal/value_type.h my_integer.o: $(hdrdir)/ruby/internal/variable.h my_integer.o: $(hdrdir)/ruby/internal/warning_push.h my_integer.o: $(hdrdir)/ruby/internal/xmalloc.h -my_integer.o: $(hdrdir)/ruby/assert.h -my_integer.o: $(hdrdir)/ruby/backward.h -my_integer.o: $(hdrdir)/ruby/backward/2/assume.h -my_integer.o: $(hdrdir)/ruby/backward/2/attributes.h -my_integer.o: $(hdrdir)/ruby/backward/2/bool.h -my_integer.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -my_integer.o: $(hdrdir)/ruby/backward/2/inttypes.h -my_integer.o: $(hdrdir)/ruby/backward/2/limits.h -my_integer.o: $(hdrdir)/ruby/backward/2/long_long.h -my_integer.o: $(hdrdir)/ruby/backward/2/stdalign.h -my_integer.o: $(hdrdir)/ruby/backward/2/stdarg.h -my_integer.o: $(hdrdir)/ruby/defines.h -my_integer.o: $(hdrdir)/ruby/intern.h my_integer.o: $(hdrdir)/ruby/missing.h my_integer.o: $(hdrdir)/ruby/ruby.h my_integer.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/integer/my_integer.c b/ext/-test-/integer/my_integer.c index d86474bd7d..94f14d2765 100644 --- a/ext/-test-/integer/my_integer.c +++ b/ext/-test-/integer/my_integer.c @@ -1,9 +1,13 @@ #include "ruby.h" +static const rb_data_type_t my_integer_type = { + "MyInteger", {0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + static VALUE my_integer_s_new(VALUE klass) { - return Data_Wrap_Struct(klass, 0, 0, 0); + return TypedData_Wrap_Struct(klass, &my_integer_type, 0); } void diff --git a/ext/-test-/iseq_load/depend b/ext/-test-/iseq_load/depend index 26d4c01aa2..9361ddb938 100644 --- a/ext/-test-/iseq_load/depend +++ b/ext/-test-/iseq_load/depend @@ -2,6 +2,19 @@ iseq_load.o: $(RUBY_EXTCONF_H) iseq_load.o: $(arch_hdrdir)/ruby/config.h iseq_load.o: $(hdrdir)/ruby.h +iseq_load.o: $(hdrdir)/ruby/assert.h +iseq_load.o: $(hdrdir)/ruby/backward.h +iseq_load.o: $(hdrdir)/ruby/backward/2/assume.h +iseq_load.o: $(hdrdir)/ruby/backward/2/attributes.h +iseq_load.o: $(hdrdir)/ruby/backward/2/bool.h +iseq_load.o: $(hdrdir)/ruby/backward/2/inttypes.h +iseq_load.o: $(hdrdir)/ruby/backward/2/limits.h +iseq_load.o: $(hdrdir)/ruby/backward/2/long_long.h +iseq_load.o: $(hdrdir)/ruby/backward/2/stdalign.h +iseq_load.o: $(hdrdir)/ruby/backward/2/stdarg.h +iseq_load.o: $(hdrdir)/ruby/defines.h +iseq_load.o: $(hdrdir)/ruby/intern.h +iseq_load.o: $(hdrdir)/ruby/internal/abi.h iseq_load.o: $(hdrdir)/ruby/internal/anyargs.h iseq_load.o: $(hdrdir)/ruby/internal/arithmetic.h iseq_load.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ iseq_load.o: $(hdrdir)/ruby/internal/attr/noexcept.h iseq_load.o: $(hdrdir)/ruby/internal/attr/noinline.h iseq_load.o: $(hdrdir)/ruby/internal/attr/nonnull.h iseq_load.o: $(hdrdir)/ruby/internal/attr/noreturn.h +iseq_load.o: $(hdrdir)/ruby/internal/attr/packed_struct.h iseq_load.o: $(hdrdir)/ruby/internal/attr/pure.h iseq_load.o: $(hdrdir)/ruby/internal/attr/restrict.h iseq_load.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ iseq_load.o: $(hdrdir)/ruby/internal/intern/enumerator.h iseq_load.o: $(hdrdir)/ruby/internal/intern/error.h iseq_load.o: $(hdrdir)/ruby/internal/intern/eval.h iseq_load.o: $(hdrdir)/ruby/internal/intern/file.h -iseq_load.o: $(hdrdir)/ruby/internal/intern/gc.h iseq_load.o: $(hdrdir)/ruby/internal/intern/hash.h iseq_load.o: $(hdrdir)/ruby/internal/intern/io.h iseq_load.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ iseq_load.o: $(hdrdir)/ruby/internal/intern/re.h iseq_load.o: $(hdrdir)/ruby/internal/intern/ruby.h iseq_load.o: $(hdrdir)/ruby/internal/intern/select.h iseq_load.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +iseq_load.o: $(hdrdir)/ruby/internal/intern/set.h iseq_load.o: $(hdrdir)/ruby/internal/intern/signal.h iseq_load.o: $(hdrdir)/ruby/internal/intern/sprintf.h iseq_load.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ iseq_load.o: $(hdrdir)/ruby/internal/memory.h iseq_load.o: $(hdrdir)/ruby/internal/method.h iseq_load.o: $(hdrdir)/ruby/internal/module.h iseq_load.o: $(hdrdir)/ruby/internal/newobj.h -iseq_load.o: $(hdrdir)/ruby/internal/rgengc.h iseq_load.o: $(hdrdir)/ruby/internal/scan_args.h iseq_load.o: $(hdrdir)/ruby/internal/special_consts.h iseq_load.o: $(hdrdir)/ruby/internal/static_assert.h iseq_load.o: $(hdrdir)/ruby/internal/stdalign.h iseq_load.o: $(hdrdir)/ruby/internal/stdbool.h +iseq_load.o: $(hdrdir)/ruby/internal/stdckdint.h iseq_load.o: $(hdrdir)/ruby/internal/symbol.h iseq_load.o: $(hdrdir)/ruby/internal/value.h iseq_load.o: $(hdrdir)/ruby/internal/value_type.h iseq_load.o: $(hdrdir)/ruby/internal/variable.h iseq_load.o: $(hdrdir)/ruby/internal/warning_push.h iseq_load.o: $(hdrdir)/ruby/internal/xmalloc.h -iseq_load.o: $(hdrdir)/ruby/assert.h -iseq_load.o: $(hdrdir)/ruby/backward.h -iseq_load.o: $(hdrdir)/ruby/backward/2/assume.h -iseq_load.o: $(hdrdir)/ruby/backward/2/attributes.h -iseq_load.o: $(hdrdir)/ruby/backward/2/bool.h -iseq_load.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -iseq_load.o: $(hdrdir)/ruby/backward/2/inttypes.h -iseq_load.o: $(hdrdir)/ruby/backward/2/limits.h -iseq_load.o: $(hdrdir)/ruby/backward/2/long_long.h -iseq_load.o: $(hdrdir)/ruby/backward/2/stdalign.h -iseq_load.o: $(hdrdir)/ruby/backward/2/stdarg.h -iseq_load.o: $(hdrdir)/ruby/defines.h -iseq_load.o: $(hdrdir)/ruby/intern.h iseq_load.o: $(hdrdir)/ruby/missing.h iseq_load.o: $(hdrdir)/ruby/ruby.h iseq_load.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/iter/depend b/ext/-test-/iter/depend index 85ca8be992..161947382c 100644 --- a/ext/-test-/iter/depend +++ b/ext/-test-/iter/depend @@ -2,6 +2,19 @@ break.o: $(RUBY_EXTCONF_H) break.o: $(arch_hdrdir)/ruby/config.h break.o: $(hdrdir)/ruby.h +break.o: $(hdrdir)/ruby/assert.h +break.o: $(hdrdir)/ruby/backward.h +break.o: $(hdrdir)/ruby/backward/2/assume.h +break.o: $(hdrdir)/ruby/backward/2/attributes.h +break.o: $(hdrdir)/ruby/backward/2/bool.h +break.o: $(hdrdir)/ruby/backward/2/inttypes.h +break.o: $(hdrdir)/ruby/backward/2/limits.h +break.o: $(hdrdir)/ruby/backward/2/long_long.h +break.o: $(hdrdir)/ruby/backward/2/stdalign.h +break.o: $(hdrdir)/ruby/backward/2/stdarg.h +break.o: $(hdrdir)/ruby/defines.h +break.o: $(hdrdir)/ruby/intern.h +break.o: $(hdrdir)/ruby/internal/abi.h break.o: $(hdrdir)/ruby/internal/anyargs.h break.o: $(hdrdir)/ruby/internal/arithmetic.h break.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ break.o: $(hdrdir)/ruby/internal/attr/noexcept.h break.o: $(hdrdir)/ruby/internal/attr/noinline.h break.o: $(hdrdir)/ruby/internal/attr/nonnull.h break.o: $(hdrdir)/ruby/internal/attr/noreturn.h +break.o: $(hdrdir)/ruby/internal/attr/packed_struct.h break.o: $(hdrdir)/ruby/internal/attr/pure.h break.o: $(hdrdir)/ruby/internal/attr/restrict.h break.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ break.o: $(hdrdir)/ruby/internal/intern/enumerator.h break.o: $(hdrdir)/ruby/internal/intern/error.h break.o: $(hdrdir)/ruby/internal/intern/eval.h break.o: $(hdrdir)/ruby/internal/intern/file.h -break.o: $(hdrdir)/ruby/internal/intern/gc.h break.o: $(hdrdir)/ruby/internal/intern/hash.h break.o: $(hdrdir)/ruby/internal/intern/io.h break.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ break.o: $(hdrdir)/ruby/internal/intern/re.h break.o: $(hdrdir)/ruby/internal/intern/ruby.h break.o: $(hdrdir)/ruby/internal/intern/select.h break.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +break.o: $(hdrdir)/ruby/internal/intern/set.h break.o: $(hdrdir)/ruby/internal/intern/signal.h break.o: $(hdrdir)/ruby/internal/intern/sprintf.h break.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ break.o: $(hdrdir)/ruby/internal/memory.h break.o: $(hdrdir)/ruby/internal/method.h break.o: $(hdrdir)/ruby/internal/module.h break.o: $(hdrdir)/ruby/internal/newobj.h -break.o: $(hdrdir)/ruby/internal/rgengc.h break.o: $(hdrdir)/ruby/internal/scan_args.h break.o: $(hdrdir)/ruby/internal/special_consts.h break.o: $(hdrdir)/ruby/internal/static_assert.h break.o: $(hdrdir)/ruby/internal/stdalign.h break.o: $(hdrdir)/ruby/internal/stdbool.h +break.o: $(hdrdir)/ruby/internal/stdckdint.h break.o: $(hdrdir)/ruby/internal/symbol.h break.o: $(hdrdir)/ruby/internal/value.h break.o: $(hdrdir)/ruby/internal/value_type.h break.o: $(hdrdir)/ruby/internal/variable.h break.o: $(hdrdir)/ruby/internal/warning_push.h break.o: $(hdrdir)/ruby/internal/xmalloc.h -break.o: $(hdrdir)/ruby/assert.h -break.o: $(hdrdir)/ruby/backward.h -break.o: $(hdrdir)/ruby/backward/2/assume.h -break.o: $(hdrdir)/ruby/backward/2/attributes.h -break.o: $(hdrdir)/ruby/backward/2/bool.h -break.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -break.o: $(hdrdir)/ruby/backward/2/inttypes.h -break.o: $(hdrdir)/ruby/backward/2/limits.h -break.o: $(hdrdir)/ruby/backward/2/long_long.h -break.o: $(hdrdir)/ruby/backward/2/stdalign.h -break.o: $(hdrdir)/ruby/backward/2/stdarg.h -break.o: $(hdrdir)/ruby/defines.h -break.o: $(hdrdir)/ruby/intern.h break.o: $(hdrdir)/ruby/missing.h break.o: $(hdrdir)/ruby/ruby.h break.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ break.o: break.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -322,6 +324,19 @@ init.o: init.c yield.o: $(RUBY_EXTCONF_H) yield.o: $(arch_hdrdir)/ruby/config.h yield.o: $(hdrdir)/ruby.h +yield.o: $(hdrdir)/ruby/assert.h +yield.o: $(hdrdir)/ruby/backward.h +yield.o: $(hdrdir)/ruby/backward/2/assume.h +yield.o: $(hdrdir)/ruby/backward/2/attributes.h +yield.o: $(hdrdir)/ruby/backward/2/bool.h +yield.o: $(hdrdir)/ruby/backward/2/inttypes.h +yield.o: $(hdrdir)/ruby/backward/2/limits.h +yield.o: $(hdrdir)/ruby/backward/2/long_long.h +yield.o: $(hdrdir)/ruby/backward/2/stdalign.h +yield.o: $(hdrdir)/ruby/backward/2/stdarg.h +yield.o: $(hdrdir)/ruby/defines.h +yield.o: $(hdrdir)/ruby/intern.h +yield.o: $(hdrdir)/ruby/internal/abi.h yield.o: $(hdrdir)/ruby/internal/anyargs.h yield.o: $(hdrdir)/ruby/internal/arithmetic.h yield.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -359,6 +374,7 @@ yield.o: $(hdrdir)/ruby/internal/attr/noexcept.h yield.o: $(hdrdir)/ruby/internal/attr/noinline.h yield.o: $(hdrdir)/ruby/internal/attr/nonnull.h yield.o: $(hdrdir)/ruby/internal/attr/noreturn.h +yield.o: $(hdrdir)/ruby/internal/attr/packed_struct.h yield.o: $(hdrdir)/ruby/internal/attr/pure.h yield.o: $(hdrdir)/ruby/internal/attr/restrict.h yield.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -418,7 +434,6 @@ yield.o: $(hdrdir)/ruby/internal/intern/enumerator.h yield.o: $(hdrdir)/ruby/internal/intern/error.h yield.o: $(hdrdir)/ruby/internal/intern/eval.h yield.o: $(hdrdir)/ruby/internal/intern/file.h -yield.o: $(hdrdir)/ruby/internal/intern/gc.h yield.o: $(hdrdir)/ruby/internal/intern/hash.h yield.o: $(hdrdir)/ruby/internal/intern/io.h yield.o: $(hdrdir)/ruby/internal/intern/load.h @@ -435,6 +450,7 @@ yield.o: $(hdrdir)/ruby/internal/intern/re.h yield.o: $(hdrdir)/ruby/internal/intern/ruby.h yield.o: $(hdrdir)/ruby/internal/intern/select.h yield.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +yield.o: $(hdrdir)/ruby/internal/intern/set.h yield.o: $(hdrdir)/ruby/internal/intern/signal.h yield.o: $(hdrdir)/ruby/internal/intern/sprintf.h yield.o: $(hdrdir)/ruby/internal/intern/string.h @@ -449,31 +465,18 @@ yield.o: $(hdrdir)/ruby/internal/memory.h yield.o: $(hdrdir)/ruby/internal/method.h yield.o: $(hdrdir)/ruby/internal/module.h yield.o: $(hdrdir)/ruby/internal/newobj.h -yield.o: $(hdrdir)/ruby/internal/rgengc.h yield.o: $(hdrdir)/ruby/internal/scan_args.h yield.o: $(hdrdir)/ruby/internal/special_consts.h yield.o: $(hdrdir)/ruby/internal/static_assert.h yield.o: $(hdrdir)/ruby/internal/stdalign.h yield.o: $(hdrdir)/ruby/internal/stdbool.h +yield.o: $(hdrdir)/ruby/internal/stdckdint.h yield.o: $(hdrdir)/ruby/internal/symbol.h yield.o: $(hdrdir)/ruby/internal/value.h yield.o: $(hdrdir)/ruby/internal/value_type.h yield.o: $(hdrdir)/ruby/internal/variable.h yield.o: $(hdrdir)/ruby/internal/warning_push.h yield.o: $(hdrdir)/ruby/internal/xmalloc.h -yield.o: $(hdrdir)/ruby/assert.h -yield.o: $(hdrdir)/ruby/backward.h -yield.o: $(hdrdir)/ruby/backward/2/assume.h -yield.o: $(hdrdir)/ruby/backward/2/attributes.h -yield.o: $(hdrdir)/ruby/backward/2/bool.h -yield.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -yield.o: $(hdrdir)/ruby/backward/2/inttypes.h -yield.o: $(hdrdir)/ruby/backward/2/limits.h -yield.o: $(hdrdir)/ruby/backward/2/long_long.h -yield.o: $(hdrdir)/ruby/backward/2/stdalign.h -yield.o: $(hdrdir)/ruby/backward/2/stdarg.h -yield.o: $(hdrdir)/ruby/defines.h -yield.o: $(hdrdir)/ruby/intern.h yield.o: $(hdrdir)/ruby/missing.h yield.o: $(hdrdir)/ruby/ruby.h yield.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/load/dot.dot/depend b/ext/-test-/load/dot.dot/depend index a0445e288b..339837d183 100644 --- a/ext/-test-/load/dot.dot/depend +++ b/ext/-test-/load/dot.dot/depend @@ -1,3 +1,163 @@ # AUTOGENERATED DEPENDENCIES START +dot.dot.o: $(RUBY_EXTCONF_H) +dot.dot.o: $(arch_hdrdir)/ruby/config.h +dot.dot.o: $(hdrdir)/ruby.h +dot.dot.o: $(hdrdir)/ruby/assert.h +dot.dot.o: $(hdrdir)/ruby/backward.h +dot.dot.o: $(hdrdir)/ruby/backward/2/assume.h +dot.dot.o: $(hdrdir)/ruby/backward/2/attributes.h +dot.dot.o: $(hdrdir)/ruby/backward/2/bool.h +dot.dot.o: $(hdrdir)/ruby/backward/2/inttypes.h +dot.dot.o: $(hdrdir)/ruby/backward/2/limits.h +dot.dot.o: $(hdrdir)/ruby/backward/2/long_long.h +dot.dot.o: $(hdrdir)/ruby/backward/2/stdalign.h +dot.dot.o: $(hdrdir)/ruby/backward/2/stdarg.h +dot.dot.o: $(hdrdir)/ruby/defines.h +dot.dot.o: $(hdrdir)/ruby/intern.h +dot.dot.o: $(hdrdir)/ruby/internal/abi.h +dot.dot.o: $(hdrdir)/ruby/internal/anyargs.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/char.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/double.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/int.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/long.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/short.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +dot.dot.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +dot.dot.o: $(hdrdir)/ruby/internal/assume.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/artificial.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/cold.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/const.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/constexpr.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/deprecated.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/error.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/forceinline.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/format.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/noalias.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/noexcept.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/noinline.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/nonnull.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/noreturn.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/pure.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/restrict.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/warning.h +dot.dot.o: $(hdrdir)/ruby/internal/attr/weakref.h +dot.dot.o: $(hdrdir)/ruby/internal/cast.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +dot.dot.o: $(hdrdir)/ruby/internal/compiler_since.h +dot.dot.o: $(hdrdir)/ruby/internal/config.h +dot.dot.o: $(hdrdir)/ruby/internal/constant_p.h +dot.dot.o: $(hdrdir)/ruby/internal/core.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rarray.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rbasic.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rbignum.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rclass.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rdata.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rfile.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rhash.h +dot.dot.o: $(hdrdir)/ruby/internal/core/robject.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rregexp.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rstring.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rstruct.h +dot.dot.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +dot.dot.o: $(hdrdir)/ruby/internal/ctype.h +dot.dot.o: $(hdrdir)/ruby/internal/dllexport.h +dot.dot.o: $(hdrdir)/ruby/internal/dosish.h +dot.dot.o: $(hdrdir)/ruby/internal/error.h +dot.dot.o: $(hdrdir)/ruby/internal/eval.h +dot.dot.o: $(hdrdir)/ruby/internal/event.h +dot.dot.o: $(hdrdir)/ruby/internal/fl_type.h +dot.dot.o: $(hdrdir)/ruby/internal/gc.h +dot.dot.o: $(hdrdir)/ruby/internal/glob.h +dot.dot.o: $(hdrdir)/ruby/internal/globals.h +dot.dot.o: $(hdrdir)/ruby/internal/has/attribute.h +dot.dot.o: $(hdrdir)/ruby/internal/has/builtin.h +dot.dot.o: $(hdrdir)/ruby/internal/has/c_attribute.h +dot.dot.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +dot.dot.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +dot.dot.o: $(hdrdir)/ruby/internal/has/extension.h +dot.dot.o: $(hdrdir)/ruby/internal/has/feature.h +dot.dot.o: $(hdrdir)/ruby/internal/has/warning.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/array.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/bignum.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/class.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/compar.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/complex.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/cont.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/dir.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/enum.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/enumerator.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/error.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/eval.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/file.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/hash.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/io.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/load.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/marshal.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/numeric.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/object.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/parse.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/proc.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/process.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/random.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/range.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/rational.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/re.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/ruby.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/select.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/set.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/signal.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/sprintf.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/string.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/struct.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/thread.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/time.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/variable.h +dot.dot.o: $(hdrdir)/ruby/internal/intern/vm.h +dot.dot.o: $(hdrdir)/ruby/internal/interpreter.h +dot.dot.o: $(hdrdir)/ruby/internal/iterator.h +dot.dot.o: $(hdrdir)/ruby/internal/memory.h +dot.dot.o: $(hdrdir)/ruby/internal/method.h +dot.dot.o: $(hdrdir)/ruby/internal/module.h +dot.dot.o: $(hdrdir)/ruby/internal/newobj.h +dot.dot.o: $(hdrdir)/ruby/internal/scan_args.h +dot.dot.o: $(hdrdir)/ruby/internal/special_consts.h +dot.dot.o: $(hdrdir)/ruby/internal/static_assert.h +dot.dot.o: $(hdrdir)/ruby/internal/stdalign.h +dot.dot.o: $(hdrdir)/ruby/internal/stdbool.h +dot.dot.o: $(hdrdir)/ruby/internal/stdckdint.h +dot.dot.o: $(hdrdir)/ruby/internal/symbol.h +dot.dot.o: $(hdrdir)/ruby/internal/value.h +dot.dot.o: $(hdrdir)/ruby/internal/value_type.h +dot.dot.o: $(hdrdir)/ruby/internal/variable.h +dot.dot.o: $(hdrdir)/ruby/internal/warning_push.h +dot.dot.o: $(hdrdir)/ruby/internal/xmalloc.h +dot.dot.o: $(hdrdir)/ruby/missing.h +dot.dot.o: $(hdrdir)/ruby/ruby.h +dot.dot.o: $(hdrdir)/ruby/st.h +dot.dot.o: $(hdrdir)/ruby/subst.h dot.dot.o: dot.dot.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/load/dot.dot/dot.dot.c b/ext/-test-/load/dot.dot/dot.dot.c index 936d28931a..ce7563bf8d 100644 --- a/ext/-test-/load/dot.dot/dot.dot.c +++ b/ext/-test-/load/dot.dot/dot.dot.c @@ -1 +1,3 @@ +#include "ruby.h" + void Init_dot(void) {} diff --git a/ext/-test-/load/protect/depend b/ext/-test-/load/protect/depend index 6eb2ea987b..c76c6f88ed 100644 --- a/ext/-test-/load/protect/depend +++ b/ext/-test-/load/protect/depend @@ -2,6 +2,19 @@ protect.o: $(RUBY_EXTCONF_H) protect.o: $(arch_hdrdir)/ruby/config.h protect.o: $(hdrdir)/ruby.h +protect.o: $(hdrdir)/ruby/assert.h +protect.o: $(hdrdir)/ruby/backward.h +protect.o: $(hdrdir)/ruby/backward/2/assume.h +protect.o: $(hdrdir)/ruby/backward/2/attributes.h +protect.o: $(hdrdir)/ruby/backward/2/bool.h +protect.o: $(hdrdir)/ruby/backward/2/inttypes.h +protect.o: $(hdrdir)/ruby/backward/2/limits.h +protect.o: $(hdrdir)/ruby/backward/2/long_long.h +protect.o: $(hdrdir)/ruby/backward/2/stdalign.h +protect.o: $(hdrdir)/ruby/backward/2/stdarg.h +protect.o: $(hdrdir)/ruby/defines.h +protect.o: $(hdrdir)/ruby/intern.h +protect.o: $(hdrdir)/ruby/internal/abi.h protect.o: $(hdrdir)/ruby/internal/anyargs.h protect.o: $(hdrdir)/ruby/internal/arithmetic.h protect.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ protect.o: $(hdrdir)/ruby/internal/attr/noexcept.h protect.o: $(hdrdir)/ruby/internal/attr/noinline.h protect.o: $(hdrdir)/ruby/internal/attr/nonnull.h protect.o: $(hdrdir)/ruby/internal/attr/noreturn.h +protect.o: $(hdrdir)/ruby/internal/attr/packed_struct.h protect.o: $(hdrdir)/ruby/internal/attr/pure.h protect.o: $(hdrdir)/ruby/internal/attr/restrict.h protect.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ protect.o: $(hdrdir)/ruby/internal/intern/enumerator.h protect.o: $(hdrdir)/ruby/internal/intern/error.h protect.o: $(hdrdir)/ruby/internal/intern/eval.h protect.o: $(hdrdir)/ruby/internal/intern/file.h -protect.o: $(hdrdir)/ruby/internal/intern/gc.h protect.o: $(hdrdir)/ruby/internal/intern/hash.h protect.o: $(hdrdir)/ruby/internal/intern/io.h protect.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ protect.o: $(hdrdir)/ruby/internal/intern/re.h protect.o: $(hdrdir)/ruby/internal/intern/ruby.h protect.o: $(hdrdir)/ruby/internal/intern/select.h protect.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +protect.o: $(hdrdir)/ruby/internal/intern/set.h protect.o: $(hdrdir)/ruby/internal/intern/signal.h protect.o: $(hdrdir)/ruby/internal/intern/sprintf.h protect.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ protect.o: $(hdrdir)/ruby/internal/memory.h protect.o: $(hdrdir)/ruby/internal/method.h protect.o: $(hdrdir)/ruby/internal/module.h protect.o: $(hdrdir)/ruby/internal/newobj.h -protect.o: $(hdrdir)/ruby/internal/rgengc.h protect.o: $(hdrdir)/ruby/internal/scan_args.h protect.o: $(hdrdir)/ruby/internal/special_consts.h protect.o: $(hdrdir)/ruby/internal/static_assert.h protect.o: $(hdrdir)/ruby/internal/stdalign.h protect.o: $(hdrdir)/ruby/internal/stdbool.h +protect.o: $(hdrdir)/ruby/internal/stdckdint.h protect.o: $(hdrdir)/ruby/internal/symbol.h protect.o: $(hdrdir)/ruby/internal/value.h protect.o: $(hdrdir)/ruby/internal/value_type.h protect.o: $(hdrdir)/ruby/internal/variable.h protect.o: $(hdrdir)/ruby/internal/warning_push.h protect.o: $(hdrdir)/ruby/internal/xmalloc.h -protect.o: $(hdrdir)/ruby/assert.h -protect.o: $(hdrdir)/ruby/backward.h -protect.o: $(hdrdir)/ruby/backward/2/assume.h -protect.o: $(hdrdir)/ruby/backward/2/attributes.h -protect.o: $(hdrdir)/ruby/backward/2/bool.h -protect.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -protect.o: $(hdrdir)/ruby/backward/2/inttypes.h -protect.o: $(hdrdir)/ruby/backward/2/limits.h -protect.o: $(hdrdir)/ruby/backward/2/long_long.h -protect.o: $(hdrdir)/ruby/backward/2/stdalign.h -protect.o: $(hdrdir)/ruby/backward/2/stdarg.h -protect.o: $(hdrdir)/ruby/defines.h -protect.o: $(hdrdir)/ruby/intern.h protect.o: $(hdrdir)/ruby/missing.h protect.o: $(hdrdir)/ruby/ruby.h protect.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/load/resolve_symbol_resolver/depend b/ext/-test-/load/resolve_symbol_resolver/depend new file mode 100644 index 0000000000..f422898b69 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_resolver/depend @@ -0,0 +1,163 @@ +# AUTOGENERATED DEPENDENCIES START +resolve_symbol_resolver.o: $(RUBY_EXTCONF_H) +resolve_symbol_resolver.o: $(arch_hdrdir)/ruby/config.h +resolve_symbol_resolver.o: $(hdrdir)/ruby.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/assert.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/assume.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/attributes.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/bool.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/inttypes.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/limits.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/long_long.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/stdalign.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/backward/2/stdarg.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/defines.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/intern.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/abi.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/anyargs.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/char.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/double.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/int.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/long.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/short.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/assume.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/artificial.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/cold.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/const.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/constexpr.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/deprecated.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/error.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/forceinline.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/format.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/noalias.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/noexcept.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/noinline.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/nonnull.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/pure.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/restrict.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/warning.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/attr/weakref.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/cast.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/compiler_since.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/config.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/constant_p.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rarray.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rbasic.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rbignum.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rclass.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rdata.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rfile.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rhash.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/robject.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rregexp.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rstring.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rstruct.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/ctype.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/dllexport.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/dosish.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/error.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/eval.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/event.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/fl_type.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/gc.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/glob.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/globals.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/attribute.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/builtin.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/c_attribute.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/extension.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/feature.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/has/warning.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/array.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/bignum.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/class.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/compar.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/complex.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/cont.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/dir.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/enum.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/enumerator.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/error.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/eval.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/file.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/hash.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/io.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/load.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/marshal.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/numeric.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/object.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/parse.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/proc.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/process.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/random.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/range.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/rational.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/re.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/ruby.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/select.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/set.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/signal.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/sprintf.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/string.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/struct.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/thread.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/time.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/variable.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/intern/vm.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/interpreter.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/iterator.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/memory.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/method.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/module.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/newobj.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/scan_args.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/special_consts.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/static_assert.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/stdalign.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/stdbool.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/stdckdint.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/symbol.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/value.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/value_type.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/variable.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/warning_push.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/internal/xmalloc.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/missing.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/ruby.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/st.h +resolve_symbol_resolver.o: $(hdrdir)/ruby/subst.h +resolve_symbol_resolver.o: resolve_symbol_resolver.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/load/resolve_symbol_resolver/extconf.rb b/ext/-test-/load/resolve_symbol_resolver/extconf.rb new file mode 100644 index 0000000000..2299efcfd3 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_resolver/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/load/resolve_symbol_resolver') diff --git a/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c b/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c new file mode 100644 index 0000000000..6cc07cc1f8 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c @@ -0,0 +1,56 @@ +#include <ruby.h> +#include "ruby/internal/intern/load.h" + +typedef VALUE(*target_func)(VALUE); + +static target_func rst_any_method; + +#define resolve_func(file, name) (target_func)(uintptr_t)rb_ext_resolve_symbol(file, name) +VALUE +rsr_any_method(VALUE klass) +{ + return rst_any_method((VALUE)NULL); +} + +VALUE +rsr_try_resolve_fname(VALUE klass) +{ + target_func rst_something_missing = + resolve_func("-test-/load/resolve_symbol_missing", "rst_any_method"); + if (rst_something_missing == NULL) { + // This should be done in Init_*, so the error is LoadError + rb_raise(rb_eLoadError, "symbol not found: missing fname"); + } + return Qtrue; +} + +VALUE +rsr_try_resolve_sname(VALUE klass) +{ + target_func rst_something_missing = + resolve_func("-test-/load/resolve_symbol_target", "rst_something_missing"); + if (rst_something_missing == NULL) { + // This should be done in Init_*, so the error is LoadError + rb_raise(rb_eLoadError, "symbol not found: missing sname"); + } + return Qtrue; +} + +void +Init_resolve_symbol_resolver(void) +{ + /* + * Resolving symbols at the head of Init_ because it raises LoadError (in cases). + * If the module and methods are defined before raising LoadError, retrying `require "this.so"` will + * cause re-defining those methods (and will be warned). + */ + rst_any_method = resolve_func("-test-/load/resolve_symbol_target", "rst_any_method"); + if (rst_any_method == NULL) { + rb_raise(rb_eLoadError, "resolve_symbol_target is not loaded"); + } + + VALUE mod = rb_define_module("ResolveSymbolResolver"); + rb_define_singleton_method(mod, "any_method", rsr_any_method, 0); + rb_define_singleton_method(mod, "try_resolve_fname", rsr_try_resolve_fname, 0); + rb_define_singleton_method(mod, "try_resolve_sname", rsr_try_resolve_sname, 0); +} diff --git a/ext/-test-/load/resolve_symbol_target/depend b/ext/-test-/load/resolve_symbol_target/depend new file mode 100644 index 0000000000..aa0b5327be --- /dev/null +++ b/ext/-test-/load/resolve_symbol_target/depend @@ -0,0 +1,164 @@ +# AUTOGENERATED DEPENDENCIES START +resolve_symbol_target.o: $(RUBY_EXTCONF_H) +resolve_symbol_target.o: $(arch_hdrdir)/ruby/config.h +resolve_symbol_target.o: $(hdrdir)/ruby.h +resolve_symbol_target.o: $(hdrdir)/ruby/assert.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/assume.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/attributes.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/bool.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/inttypes.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/limits.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/long_long.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/stdalign.h +resolve_symbol_target.o: $(hdrdir)/ruby/backward/2/stdarg.h +resolve_symbol_target.o: $(hdrdir)/ruby/defines.h +resolve_symbol_target.o: $(hdrdir)/ruby/intern.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/abi.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/anyargs.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/char.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/double.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/int.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/long.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/short.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/assume.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/artificial.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/cold.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/const.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/constexpr.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/deprecated.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/error.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/forceinline.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/format.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/noalias.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/noexcept.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/noinline.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/nonnull.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/noreturn.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/pure.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/restrict.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/warning.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/attr/weakref.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/cast.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/compiler_since.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/config.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/constant_p.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rarray.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rbasic.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rbignum.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rclass.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rdata.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rfile.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rhash.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/robject.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rregexp.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rstring.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rstruct.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/ctype.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/dllexport.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/dosish.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/error.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/eval.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/event.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/fl_type.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/gc.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/glob.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/globals.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/attribute.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/builtin.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/c_attribute.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/extension.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/feature.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/has/warning.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/array.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/bignum.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/class.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/compar.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/complex.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/cont.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/dir.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/enum.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/enumerator.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/error.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/eval.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/file.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/hash.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/io.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/load.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/marshal.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/numeric.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/object.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/parse.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/proc.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/process.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/random.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/range.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/rational.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/re.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/ruby.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/select.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/set.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/signal.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/sprintf.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/string.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/struct.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/thread.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/time.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/variable.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/intern/vm.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/interpreter.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/iterator.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/memory.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/method.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/module.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/newobj.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/scan_args.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/special_consts.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/static_assert.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/stdalign.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/stdbool.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/stdckdint.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/symbol.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/value.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/value_type.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/variable.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/warning_push.h +resolve_symbol_target.o: $(hdrdir)/ruby/internal/xmalloc.h +resolve_symbol_target.o: $(hdrdir)/ruby/missing.h +resolve_symbol_target.o: $(hdrdir)/ruby/ruby.h +resolve_symbol_target.o: $(hdrdir)/ruby/st.h +resolve_symbol_target.o: $(hdrdir)/ruby/subst.h +resolve_symbol_target.o: resolve_symbol_target.c +resolve_symbol_target.o: resolve_symbol_target.h +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/load/resolve_symbol_target/extconf.rb b/ext/-test-/load/resolve_symbol_target/extconf.rb new file mode 100644 index 0000000000..b5a99ca7f1 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_target/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/load/resolve_symbol_target') diff --git a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c new file mode 100644 index 0000000000..b5bc9e8ee0 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c @@ -0,0 +1,15 @@ +#include <ruby.h> +#include "resolve_symbol_target.h" + +VALUE +rst_any_method(VALUE klass) +{ + return rb_str_new_cstr("from target"); +} + +void +Init_resolve_symbol_target(void) +{ + VALUE mod = rb_define_module("ResolveSymbolTarget"); + rb_define_singleton_method(mod, "any_method", rst_any_method, 0); +} diff --git a/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h new file mode 100644 index 0000000000..847dcb7dd3 --- /dev/null +++ b/ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h @@ -0,0 +1,4 @@ +#include <ruby.h> +#include "ruby/internal/dllexport.h" + +RUBY_FUNC_EXPORTED VALUE rst_any_method(VALUE); diff --git a/ext/-test-/load/stringify_symbols/depend b/ext/-test-/load/stringify_symbols/depend new file mode 100644 index 0000000000..2d4d79a7b7 --- /dev/null +++ b/ext/-test-/load/stringify_symbols/depend @@ -0,0 +1,164 @@ +# AUTOGENERATED DEPENDENCIES START +stringify_symbols.o: $(RUBY_EXTCONF_H) +stringify_symbols.o: $(arch_hdrdir)/ruby/config.h +stringify_symbols.o: $(hdrdir)/ruby.h +stringify_symbols.o: $(hdrdir)/ruby/assert.h +stringify_symbols.o: $(hdrdir)/ruby/backward.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/assume.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/attributes.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/bool.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/inttypes.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/limits.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/long_long.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/stdalign.h +stringify_symbols.o: $(hdrdir)/ruby/backward/2/stdarg.h +stringify_symbols.o: $(hdrdir)/ruby/defines.h +stringify_symbols.o: $(hdrdir)/ruby/intern.h +stringify_symbols.o: $(hdrdir)/ruby/internal/abi.h +stringify_symbols.o: $(hdrdir)/ruby/internal/anyargs.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/char.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/double.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/int.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/long.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/short.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +stringify_symbols.o: $(hdrdir)/ruby/internal/assume.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/artificial.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/cold.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/const.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/constexpr.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/deprecated.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/error.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/forceinline.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/format.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/noalias.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/noexcept.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/noinline.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/nonnull.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/noreturn.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/pure.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/restrict.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/warning.h +stringify_symbols.o: $(hdrdir)/ruby/internal/attr/weakref.h +stringify_symbols.o: $(hdrdir)/ruby/internal/cast.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +stringify_symbols.o: $(hdrdir)/ruby/internal/compiler_since.h +stringify_symbols.o: $(hdrdir)/ruby/internal/config.h +stringify_symbols.o: $(hdrdir)/ruby/internal/constant_p.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rarray.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rbasic.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rbignum.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rclass.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rdata.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rfile.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rhash.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/robject.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rregexp.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rstring.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rstruct.h +stringify_symbols.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +stringify_symbols.o: $(hdrdir)/ruby/internal/ctype.h +stringify_symbols.o: $(hdrdir)/ruby/internal/dllexport.h +stringify_symbols.o: $(hdrdir)/ruby/internal/dosish.h +stringify_symbols.o: $(hdrdir)/ruby/internal/error.h +stringify_symbols.o: $(hdrdir)/ruby/internal/eval.h +stringify_symbols.o: $(hdrdir)/ruby/internal/event.h +stringify_symbols.o: $(hdrdir)/ruby/internal/fl_type.h +stringify_symbols.o: $(hdrdir)/ruby/internal/gc.h +stringify_symbols.o: $(hdrdir)/ruby/internal/glob.h +stringify_symbols.o: $(hdrdir)/ruby/internal/globals.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/attribute.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/builtin.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/c_attribute.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/extension.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/feature.h +stringify_symbols.o: $(hdrdir)/ruby/internal/has/warning.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/array.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/bignum.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/class.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/compar.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/complex.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/cont.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/dir.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/enum.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/enumerator.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/error.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/eval.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/file.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/hash.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/io.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/load.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/marshal.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/numeric.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/object.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/parse.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/proc.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/process.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/random.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/range.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/rational.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/re.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/ruby.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/select.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/set.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/signal.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/sprintf.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/string.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/struct.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/thread.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/time.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/variable.h +stringify_symbols.o: $(hdrdir)/ruby/internal/intern/vm.h +stringify_symbols.o: $(hdrdir)/ruby/internal/interpreter.h +stringify_symbols.o: $(hdrdir)/ruby/internal/iterator.h +stringify_symbols.o: $(hdrdir)/ruby/internal/memory.h +stringify_symbols.o: $(hdrdir)/ruby/internal/method.h +stringify_symbols.o: $(hdrdir)/ruby/internal/module.h +stringify_symbols.o: $(hdrdir)/ruby/internal/newobj.h +stringify_symbols.o: $(hdrdir)/ruby/internal/scan_args.h +stringify_symbols.o: $(hdrdir)/ruby/internal/special_consts.h +stringify_symbols.o: $(hdrdir)/ruby/internal/static_assert.h +stringify_symbols.o: $(hdrdir)/ruby/internal/stdalign.h +stringify_symbols.o: $(hdrdir)/ruby/internal/stdbool.h +stringify_symbols.o: $(hdrdir)/ruby/internal/stdckdint.h +stringify_symbols.o: $(hdrdir)/ruby/internal/symbol.h +stringify_symbols.o: $(hdrdir)/ruby/internal/value.h +stringify_symbols.o: $(hdrdir)/ruby/internal/value_type.h +stringify_symbols.o: $(hdrdir)/ruby/internal/variable.h +stringify_symbols.o: $(hdrdir)/ruby/internal/warning_push.h +stringify_symbols.o: $(hdrdir)/ruby/internal/xmalloc.h +stringify_symbols.o: $(hdrdir)/ruby/missing.h +stringify_symbols.o: $(hdrdir)/ruby/ruby.h +stringify_symbols.o: $(hdrdir)/ruby/st.h +stringify_symbols.o: $(hdrdir)/ruby/subst.h +stringify_symbols.o: $(hdrdir)/ruby/util.h +stringify_symbols.o: stringify_symbols.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/load/stringify_symbols/extconf.rb b/ext/-test-/load/stringify_symbols/extconf.rb new file mode 100644 index 0000000000..ac39c15f09 --- /dev/null +++ b/ext/-test-/load/stringify_symbols/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/load/stringify_symbols') diff --git a/ext/-test-/load/stringify_symbols/stringify_symbols.c b/ext/-test-/load/stringify_symbols/stringify_symbols.c new file mode 100644 index 0000000000..11a5ee3bc5 --- /dev/null +++ b/ext/-test-/load/stringify_symbols/stringify_symbols.c @@ -0,0 +1,29 @@ +#include <ruby.h> +#include "ruby/internal/intern/load.h" +#include "ruby/util.h" + +#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG +# define UINTPTR2NUM ULL2NUM +#elif SIZEOF_INTPTR_T == SIZEOF_LONG +# define UINTPTR2NUM ULONG2NUM +#else +# define UINTPTR2NUM UINT2NUM +#endif + +static VALUE +stringify_symbol(VALUE klass, VALUE fname, VALUE sname) +{ + void *ptr = rb_ext_resolve_symbol(StringValueCStr(fname), StringValueCStr(sname)); + if (ptr == NULL) { + return Qnil; + } + uintptr_t uintptr = (uintptr_t)ptr; + return UINTPTR2NUM(uintptr); +} + +void +Init_stringify_symbols(void) +{ + VALUE mod = rb_define_module("StringifySymbols"); + rb_define_singleton_method(mod, "stringify_symbol", stringify_symbol, 2); +} diff --git a/ext/-test-/load/stringify_target/depend b/ext/-test-/load/stringify_target/depend new file mode 100644 index 0000000000..c66575d4e4 --- /dev/null +++ b/ext/-test-/load/stringify_target/depend @@ -0,0 +1,164 @@ +# AUTOGENERATED DEPENDENCIES START +stringify_target.o: $(RUBY_EXTCONF_H) +stringify_target.o: $(arch_hdrdir)/ruby/config.h +stringify_target.o: $(hdrdir)/ruby.h +stringify_target.o: $(hdrdir)/ruby/assert.h +stringify_target.o: $(hdrdir)/ruby/backward.h +stringify_target.o: $(hdrdir)/ruby/backward/2/assume.h +stringify_target.o: $(hdrdir)/ruby/backward/2/attributes.h +stringify_target.o: $(hdrdir)/ruby/backward/2/bool.h +stringify_target.o: $(hdrdir)/ruby/backward/2/inttypes.h +stringify_target.o: $(hdrdir)/ruby/backward/2/limits.h +stringify_target.o: $(hdrdir)/ruby/backward/2/long_long.h +stringify_target.o: $(hdrdir)/ruby/backward/2/stdalign.h +stringify_target.o: $(hdrdir)/ruby/backward/2/stdarg.h +stringify_target.o: $(hdrdir)/ruby/defines.h +stringify_target.o: $(hdrdir)/ruby/intern.h +stringify_target.o: $(hdrdir)/ruby/internal/abi.h +stringify_target.o: $(hdrdir)/ruby/internal/anyargs.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/char.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/double.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/int.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/long.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/short.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +stringify_target.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +stringify_target.o: $(hdrdir)/ruby/internal/assume.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/artificial.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/cold.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/const.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/constexpr.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/deprecated.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/error.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/forceinline.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/format.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/noalias.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/noexcept.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/noinline.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/nonnull.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/noreturn.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/pure.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/restrict.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/warning.h +stringify_target.o: $(hdrdir)/ruby/internal/attr/weakref.h +stringify_target.o: $(hdrdir)/ruby/internal/cast.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +stringify_target.o: $(hdrdir)/ruby/internal/compiler_since.h +stringify_target.o: $(hdrdir)/ruby/internal/config.h +stringify_target.o: $(hdrdir)/ruby/internal/constant_p.h +stringify_target.o: $(hdrdir)/ruby/internal/core.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rarray.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rbasic.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rbignum.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rclass.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rdata.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rfile.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rhash.h +stringify_target.o: $(hdrdir)/ruby/internal/core/robject.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rregexp.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rstring.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rstruct.h +stringify_target.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +stringify_target.o: $(hdrdir)/ruby/internal/ctype.h +stringify_target.o: $(hdrdir)/ruby/internal/dllexport.h +stringify_target.o: $(hdrdir)/ruby/internal/dosish.h +stringify_target.o: $(hdrdir)/ruby/internal/error.h +stringify_target.o: $(hdrdir)/ruby/internal/eval.h +stringify_target.o: $(hdrdir)/ruby/internal/event.h +stringify_target.o: $(hdrdir)/ruby/internal/fl_type.h +stringify_target.o: $(hdrdir)/ruby/internal/gc.h +stringify_target.o: $(hdrdir)/ruby/internal/glob.h +stringify_target.o: $(hdrdir)/ruby/internal/globals.h +stringify_target.o: $(hdrdir)/ruby/internal/has/attribute.h +stringify_target.o: $(hdrdir)/ruby/internal/has/builtin.h +stringify_target.o: $(hdrdir)/ruby/internal/has/c_attribute.h +stringify_target.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +stringify_target.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +stringify_target.o: $(hdrdir)/ruby/internal/has/extension.h +stringify_target.o: $(hdrdir)/ruby/internal/has/feature.h +stringify_target.o: $(hdrdir)/ruby/internal/has/warning.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/array.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/bignum.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/class.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/compar.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/complex.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/cont.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/dir.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/enum.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/enumerator.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/error.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/eval.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/file.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/hash.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/io.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/load.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/marshal.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/numeric.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/object.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/parse.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/proc.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/process.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/random.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/range.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/rational.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/re.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/ruby.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/select.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/set.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/signal.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/sprintf.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/string.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/struct.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/thread.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/time.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/variable.h +stringify_target.o: $(hdrdir)/ruby/internal/intern/vm.h +stringify_target.o: $(hdrdir)/ruby/internal/interpreter.h +stringify_target.o: $(hdrdir)/ruby/internal/iterator.h +stringify_target.o: $(hdrdir)/ruby/internal/memory.h +stringify_target.o: $(hdrdir)/ruby/internal/method.h +stringify_target.o: $(hdrdir)/ruby/internal/module.h +stringify_target.o: $(hdrdir)/ruby/internal/newobj.h +stringify_target.o: $(hdrdir)/ruby/internal/scan_args.h +stringify_target.o: $(hdrdir)/ruby/internal/special_consts.h +stringify_target.o: $(hdrdir)/ruby/internal/static_assert.h +stringify_target.o: $(hdrdir)/ruby/internal/stdalign.h +stringify_target.o: $(hdrdir)/ruby/internal/stdbool.h +stringify_target.o: $(hdrdir)/ruby/internal/stdckdint.h +stringify_target.o: $(hdrdir)/ruby/internal/symbol.h +stringify_target.o: $(hdrdir)/ruby/internal/value.h +stringify_target.o: $(hdrdir)/ruby/internal/value_type.h +stringify_target.o: $(hdrdir)/ruby/internal/variable.h +stringify_target.o: $(hdrdir)/ruby/internal/warning_push.h +stringify_target.o: $(hdrdir)/ruby/internal/xmalloc.h +stringify_target.o: $(hdrdir)/ruby/missing.h +stringify_target.o: $(hdrdir)/ruby/ruby.h +stringify_target.o: $(hdrdir)/ruby/st.h +stringify_target.o: $(hdrdir)/ruby/subst.h +stringify_target.o: stringify_target.c +stringify_target.o: stringify_target.h +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/load/stringify_target/extconf.rb b/ext/-test-/load/stringify_target/extconf.rb new file mode 100644 index 0000000000..4aa201cb09 --- /dev/null +++ b/ext/-test-/load/stringify_target/extconf.rb @@ -0,0 +1 @@ +create_makefile('-test-/load/stringify_target') diff --git a/ext/-test-/load/stringify_target/stringify_target.c b/ext/-test-/load/stringify_target/stringify_target.c new file mode 100644 index 0000000000..ce09b8fd77 --- /dev/null +++ b/ext/-test-/load/stringify_target/stringify_target.c @@ -0,0 +1,15 @@ +#include <ruby.h> +#include "stringify_target.h" + +VALUE +stt_any_method(VALUE klass) +{ + return rb_str_new_cstr("from target"); +} + +void +Init_stringify_target(void) +{ + VALUE mod = rb_define_module("StringifyTarget"); + rb_define_singleton_method(mod, "any_method", stt_any_method, 0); +} diff --git a/ext/-test-/load/stringify_target/stringify_target.h b/ext/-test-/load/stringify_target/stringify_target.h new file mode 100644 index 0000000000..d95fb65d7c --- /dev/null +++ b/ext/-test-/load/stringify_target/stringify_target.h @@ -0,0 +1,4 @@ +#include <ruby.h> +#include "ruby/internal/dllexport.h" + +RUBY_FUNC_EXPORTED VALUE stt_any_method(VALUE); diff --git a/ext/-test-/marshal/compat/depend b/ext/-test-/marshal/compat/depend index 1fca7a7baf..36b9235c23 100644 --- a/ext/-test-/marshal/compat/depend +++ b/ext/-test-/marshal/compat/depend @@ -2,6 +2,19 @@ usrcompat.o: $(RUBY_EXTCONF_H) usrcompat.o: $(arch_hdrdir)/ruby/config.h usrcompat.o: $(hdrdir)/ruby.h +usrcompat.o: $(hdrdir)/ruby/assert.h +usrcompat.o: $(hdrdir)/ruby/backward.h +usrcompat.o: $(hdrdir)/ruby/backward/2/assume.h +usrcompat.o: $(hdrdir)/ruby/backward/2/attributes.h +usrcompat.o: $(hdrdir)/ruby/backward/2/bool.h +usrcompat.o: $(hdrdir)/ruby/backward/2/inttypes.h +usrcompat.o: $(hdrdir)/ruby/backward/2/limits.h +usrcompat.o: $(hdrdir)/ruby/backward/2/long_long.h +usrcompat.o: $(hdrdir)/ruby/backward/2/stdalign.h +usrcompat.o: $(hdrdir)/ruby/backward/2/stdarg.h +usrcompat.o: $(hdrdir)/ruby/defines.h +usrcompat.o: $(hdrdir)/ruby/intern.h +usrcompat.o: $(hdrdir)/ruby/internal/abi.h usrcompat.o: $(hdrdir)/ruby/internal/anyargs.h usrcompat.o: $(hdrdir)/ruby/internal/arithmetic.h usrcompat.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ usrcompat.o: $(hdrdir)/ruby/internal/attr/noexcept.h usrcompat.o: $(hdrdir)/ruby/internal/attr/noinline.h usrcompat.o: $(hdrdir)/ruby/internal/attr/nonnull.h usrcompat.o: $(hdrdir)/ruby/internal/attr/noreturn.h +usrcompat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h usrcompat.o: $(hdrdir)/ruby/internal/attr/pure.h usrcompat.o: $(hdrdir)/ruby/internal/attr/restrict.h usrcompat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ usrcompat.o: $(hdrdir)/ruby/internal/intern/enumerator.h usrcompat.o: $(hdrdir)/ruby/internal/intern/error.h usrcompat.o: $(hdrdir)/ruby/internal/intern/eval.h usrcompat.o: $(hdrdir)/ruby/internal/intern/file.h -usrcompat.o: $(hdrdir)/ruby/internal/intern/gc.h usrcompat.o: $(hdrdir)/ruby/internal/intern/hash.h usrcompat.o: $(hdrdir)/ruby/internal/intern/io.h usrcompat.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ usrcompat.o: $(hdrdir)/ruby/internal/intern/re.h usrcompat.o: $(hdrdir)/ruby/internal/intern/ruby.h usrcompat.o: $(hdrdir)/ruby/internal/intern/select.h usrcompat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +usrcompat.o: $(hdrdir)/ruby/internal/intern/set.h usrcompat.o: $(hdrdir)/ruby/internal/intern/signal.h usrcompat.o: $(hdrdir)/ruby/internal/intern/sprintf.h usrcompat.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ usrcompat.o: $(hdrdir)/ruby/internal/memory.h usrcompat.o: $(hdrdir)/ruby/internal/method.h usrcompat.o: $(hdrdir)/ruby/internal/module.h usrcompat.o: $(hdrdir)/ruby/internal/newobj.h -usrcompat.o: $(hdrdir)/ruby/internal/rgengc.h usrcompat.o: $(hdrdir)/ruby/internal/scan_args.h usrcompat.o: $(hdrdir)/ruby/internal/special_consts.h usrcompat.o: $(hdrdir)/ruby/internal/static_assert.h usrcompat.o: $(hdrdir)/ruby/internal/stdalign.h usrcompat.o: $(hdrdir)/ruby/internal/stdbool.h +usrcompat.o: $(hdrdir)/ruby/internal/stdckdint.h usrcompat.o: $(hdrdir)/ruby/internal/symbol.h usrcompat.o: $(hdrdir)/ruby/internal/value.h usrcompat.o: $(hdrdir)/ruby/internal/value_type.h usrcompat.o: $(hdrdir)/ruby/internal/variable.h usrcompat.o: $(hdrdir)/ruby/internal/warning_push.h usrcompat.o: $(hdrdir)/ruby/internal/xmalloc.h -usrcompat.o: $(hdrdir)/ruby/assert.h -usrcompat.o: $(hdrdir)/ruby/backward.h -usrcompat.o: $(hdrdir)/ruby/backward/2/assume.h -usrcompat.o: $(hdrdir)/ruby/backward/2/attributes.h -usrcompat.o: $(hdrdir)/ruby/backward/2/bool.h -usrcompat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -usrcompat.o: $(hdrdir)/ruby/backward/2/inttypes.h -usrcompat.o: $(hdrdir)/ruby/backward/2/limits.h -usrcompat.o: $(hdrdir)/ruby/backward/2/long_long.h -usrcompat.o: $(hdrdir)/ruby/backward/2/stdalign.h -usrcompat.o: $(hdrdir)/ruby/backward/2/stdarg.h -usrcompat.o: $(hdrdir)/ruby/defines.h -usrcompat.o: $(hdrdir)/ruby/intern.h usrcompat.o: $(hdrdir)/ruby/missing.h usrcompat.o: $(hdrdir)/ruby/ruby.h usrcompat.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/marshal/internal_ivar/depend b/ext/-test-/marshal/internal_ivar/depend index 2b0f44c0d0..a2e093d809 100644 --- a/ext/-test-/marshal/internal_ivar/depend +++ b/ext/-test-/marshal/internal_ivar/depend @@ -2,6 +2,19 @@ internal_ivar.o: $(RUBY_EXTCONF_H) internal_ivar.o: $(arch_hdrdir)/ruby/config.h internal_ivar.o: $(hdrdir)/ruby.h +internal_ivar.o: $(hdrdir)/ruby/assert.h +internal_ivar.o: $(hdrdir)/ruby/backward.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/assume.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/attributes.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/bool.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/inttypes.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/limits.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/long_long.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/stdalign.h +internal_ivar.o: $(hdrdir)/ruby/backward/2/stdarg.h +internal_ivar.o: $(hdrdir)/ruby/defines.h +internal_ivar.o: $(hdrdir)/ruby/intern.h +internal_ivar.o: $(hdrdir)/ruby/internal/abi.h internal_ivar.o: $(hdrdir)/ruby/internal/anyargs.h internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic.h internal_ivar.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ internal_ivar.o: $(hdrdir)/ruby/internal/attr/noexcept.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/noinline.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/nonnull.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/noreturn.h +internal_ivar.o: $(hdrdir)/ruby/internal/attr/packed_struct.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/pure.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/restrict.h internal_ivar.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ internal_ivar.o: $(hdrdir)/ruby/internal/intern/enumerator.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/error.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/eval.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/file.h -internal_ivar.o: $(hdrdir)/ruby/internal/intern/gc.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/hash.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/io.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ internal_ivar.o: $(hdrdir)/ruby/internal/intern/re.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/ruby.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/select.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +internal_ivar.o: $(hdrdir)/ruby/internal/intern/set.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/signal.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/sprintf.h internal_ivar.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ internal_ivar.o: $(hdrdir)/ruby/internal/memory.h internal_ivar.o: $(hdrdir)/ruby/internal/method.h internal_ivar.o: $(hdrdir)/ruby/internal/module.h internal_ivar.o: $(hdrdir)/ruby/internal/newobj.h -internal_ivar.o: $(hdrdir)/ruby/internal/rgengc.h internal_ivar.o: $(hdrdir)/ruby/internal/scan_args.h internal_ivar.o: $(hdrdir)/ruby/internal/special_consts.h internal_ivar.o: $(hdrdir)/ruby/internal/static_assert.h internal_ivar.o: $(hdrdir)/ruby/internal/stdalign.h internal_ivar.o: $(hdrdir)/ruby/internal/stdbool.h +internal_ivar.o: $(hdrdir)/ruby/internal/stdckdint.h internal_ivar.o: $(hdrdir)/ruby/internal/symbol.h internal_ivar.o: $(hdrdir)/ruby/internal/value.h internal_ivar.o: $(hdrdir)/ruby/internal/value_type.h internal_ivar.o: $(hdrdir)/ruby/internal/variable.h internal_ivar.o: $(hdrdir)/ruby/internal/warning_push.h internal_ivar.o: $(hdrdir)/ruby/internal/xmalloc.h -internal_ivar.o: $(hdrdir)/ruby/assert.h -internal_ivar.o: $(hdrdir)/ruby/backward.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/assume.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/attributes.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/bool.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/inttypes.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/limits.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/long_long.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/stdalign.h -internal_ivar.o: $(hdrdir)/ruby/backward/2/stdarg.h -internal_ivar.o: $(hdrdir)/ruby/defines.h -internal_ivar.o: $(hdrdir)/ruby/intern.h internal_ivar.o: $(hdrdir)/ruby/missing.h internal_ivar.o: $(hdrdir)/ruby/ruby.h internal_ivar.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/marshal/internal_ivar/internal_ivar.c b/ext/-test-/marshal/internal_ivar/internal_ivar.c index de0cf711aa..2e2f9cb235 100644 --- a/ext/-test-/marshal/internal_ivar/internal_ivar.c +++ b/ext/-test-/marshal/internal_ivar/internal_ivar.c @@ -1,13 +1,14 @@ #include <ruby.h> -static ID id_normal_ivar, id_internal_ivar, id_encoding_short; +static ID id_normal_ivar, id_internal_ivar, id_encoding_short, id_encoding_long; static VALUE -init(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3) +init(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4) { rb_ivar_set(self, id_normal_ivar, arg1); rb_ivar_set(self, id_internal_ivar, arg2); rb_ivar_set(self, id_encoding_short, arg3); + rb_ivar_set(self, id_encoding_long, arg4); return self; } @@ -29,6 +30,12 @@ get_encoding_short(VALUE self) return rb_attr_get(self, id_encoding_short); } +static VALUE +get_encoding_long(VALUE self) +{ + return rb_attr_get(self, id_encoding_long); +} + void Init_internal_ivar(void) { @@ -36,13 +43,12 @@ Init_internal_ivar(void) VALUE newclass = rb_define_class_under(mMarshal, "InternalIVar", rb_cObject); id_normal_ivar = rb_intern_const("normal"); -#if 0 - /* leave id_internal_ivar being 0 */ - id_internal_ivar = rb_make_internal_id(); -#endif + id_internal_ivar = rb_intern_const("K"); id_encoding_short = rb_intern_const("E"); - rb_define_method(newclass, "initialize", init, 3); + id_encoding_long = rb_intern_const("encoding"); + rb_define_method(newclass, "initialize", init, 4); rb_define_method(newclass, "normal", get_normal, 0); rb_define_method(newclass, "internal", get_internal, 0); rb_define_method(newclass, "encoding_short", get_encoding_short, 0); + rb_define_method(newclass, "encoding_long", get_encoding_long, 0); } diff --git a/ext/-test-/marshal/usr/depend b/ext/-test-/marshal/usr/depend index 239798bacf..5ffb8c58de 100644 --- a/ext/-test-/marshal/usr/depend +++ b/ext/-test-/marshal/usr/depend @@ -2,6 +2,19 @@ usrmarshal.o: $(RUBY_EXTCONF_H) usrmarshal.o: $(arch_hdrdir)/ruby/config.h usrmarshal.o: $(hdrdir)/ruby.h +usrmarshal.o: $(hdrdir)/ruby/assert.h +usrmarshal.o: $(hdrdir)/ruby/backward.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/assume.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/attributes.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/bool.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/inttypes.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/limits.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/long_long.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/stdalign.h +usrmarshal.o: $(hdrdir)/ruby/backward/2/stdarg.h +usrmarshal.o: $(hdrdir)/ruby/defines.h +usrmarshal.o: $(hdrdir)/ruby/intern.h +usrmarshal.o: $(hdrdir)/ruby/internal/abi.h usrmarshal.o: $(hdrdir)/ruby/internal/anyargs.h usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic.h usrmarshal.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ usrmarshal.o: $(hdrdir)/ruby/internal/attr/noexcept.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/noinline.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/nonnull.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/noreturn.h +usrmarshal.o: $(hdrdir)/ruby/internal/attr/packed_struct.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/pure.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/restrict.h usrmarshal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ usrmarshal.o: $(hdrdir)/ruby/internal/intern/enumerator.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/error.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/eval.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/file.h -usrmarshal.o: $(hdrdir)/ruby/internal/intern/gc.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/hash.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/io.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ usrmarshal.o: $(hdrdir)/ruby/internal/intern/re.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/ruby.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/select.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +usrmarshal.o: $(hdrdir)/ruby/internal/intern/set.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/signal.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/sprintf.h usrmarshal.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ usrmarshal.o: $(hdrdir)/ruby/internal/memory.h usrmarshal.o: $(hdrdir)/ruby/internal/method.h usrmarshal.o: $(hdrdir)/ruby/internal/module.h usrmarshal.o: $(hdrdir)/ruby/internal/newobj.h -usrmarshal.o: $(hdrdir)/ruby/internal/rgengc.h usrmarshal.o: $(hdrdir)/ruby/internal/scan_args.h usrmarshal.o: $(hdrdir)/ruby/internal/special_consts.h usrmarshal.o: $(hdrdir)/ruby/internal/static_assert.h usrmarshal.o: $(hdrdir)/ruby/internal/stdalign.h usrmarshal.o: $(hdrdir)/ruby/internal/stdbool.h +usrmarshal.o: $(hdrdir)/ruby/internal/stdckdint.h usrmarshal.o: $(hdrdir)/ruby/internal/symbol.h usrmarshal.o: $(hdrdir)/ruby/internal/value.h usrmarshal.o: $(hdrdir)/ruby/internal/value_type.h usrmarshal.o: $(hdrdir)/ruby/internal/variable.h usrmarshal.o: $(hdrdir)/ruby/internal/warning_push.h usrmarshal.o: $(hdrdir)/ruby/internal/xmalloc.h -usrmarshal.o: $(hdrdir)/ruby/assert.h -usrmarshal.o: $(hdrdir)/ruby/backward.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/assume.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/attributes.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/bool.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/inttypes.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/limits.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/long_long.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/stdalign.h -usrmarshal.o: $(hdrdir)/ruby/backward/2/stdarg.h -usrmarshal.o: $(hdrdir)/ruby/defines.h -usrmarshal.o: $(hdrdir)/ruby/intern.h usrmarshal.o: $(hdrdir)/ruby/missing.h usrmarshal.o: $(hdrdir)/ruby/ruby.h usrmarshal.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/memory_status/depend b/ext/-test-/memory_status/depend index f8652cb316..4dd503e1bb 100644 --- a/ext/-test-/memory_status/depend +++ b/ext/-test-/memory_status/depend @@ -7,7 +7,6 @@ memory_status.o: $(hdrdir)/ruby/backward.h memory_status.o: $(hdrdir)/ruby/backward/2/assume.h memory_status.o: $(hdrdir)/ruby/backward/2/attributes.h memory_status.o: $(hdrdir)/ruby/backward/2/bool.h -memory_status.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h memory_status.o: $(hdrdir)/ruby/backward/2/inttypes.h memory_status.o: $(hdrdir)/ruby/backward/2/limits.h memory_status.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ memory_status.o: $(hdrdir)/ruby/backward/2/stdalign.h memory_status.o: $(hdrdir)/ruby/backward/2/stdarg.h memory_status.o: $(hdrdir)/ruby/defines.h memory_status.o: $(hdrdir)/ruby/intern.h +memory_status.o: $(hdrdir)/ruby/internal/abi.h memory_status.o: $(hdrdir)/ruby/internal/anyargs.h memory_status.o: $(hdrdir)/ruby/internal/arithmetic.h memory_status.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ memory_status.o: $(hdrdir)/ruby/internal/attr/noexcept.h memory_status.o: $(hdrdir)/ruby/internal/attr/noinline.h memory_status.o: $(hdrdir)/ruby/internal/attr/nonnull.h memory_status.o: $(hdrdir)/ruby/internal/attr/noreturn.h +memory_status.o: $(hdrdir)/ruby/internal/attr/packed_struct.h memory_status.o: $(hdrdir)/ruby/internal/attr/pure.h memory_status.o: $(hdrdir)/ruby/internal/attr/restrict.h memory_status.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -111,7 +112,6 @@ memory_status.o: $(hdrdir)/ruby/internal/intern/enumerator.h memory_status.o: $(hdrdir)/ruby/internal/intern/error.h memory_status.o: $(hdrdir)/ruby/internal/intern/eval.h memory_status.o: $(hdrdir)/ruby/internal/intern/file.h -memory_status.o: $(hdrdir)/ruby/internal/intern/gc.h memory_status.o: $(hdrdir)/ruby/internal/intern/hash.h memory_status.o: $(hdrdir)/ruby/internal/intern/io.h memory_status.o: $(hdrdir)/ruby/internal/intern/load.h @@ -142,12 +142,12 @@ memory_status.o: $(hdrdir)/ruby/internal/memory.h memory_status.o: $(hdrdir)/ruby/internal/method.h memory_status.o: $(hdrdir)/ruby/internal/module.h memory_status.o: $(hdrdir)/ruby/internal/newobj.h -memory_status.o: $(hdrdir)/ruby/internal/rgengc.h memory_status.o: $(hdrdir)/ruby/internal/scan_args.h memory_status.o: $(hdrdir)/ruby/internal/special_consts.h memory_status.o: $(hdrdir)/ruby/internal/static_assert.h memory_status.o: $(hdrdir)/ruby/internal/stdalign.h memory_status.o: $(hdrdir)/ruby/internal/stdbool.h +memory_status.o: $(hdrdir)/ruby/internal/stdckdint.h memory_status.o: $(hdrdir)/ruby/internal/symbol.h memory_status.o: $(hdrdir)/ruby/internal/value.h memory_status.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/memory_status/memory_status.c b/ext/-test-/memory_status/memory_status.c index afacbee785..f124c97ca1 100644 --- a/ext/-test-/memory_status/memory_status.c +++ b/ext/-test-/memory_status/memory_status.c @@ -34,7 +34,7 @@ read_status(VALUE self) taskinfo.virtual_size = 0; taskinfo.resident_size = 0; error = task_info(mach_task_self(), flavor, - (task_info_t)&taskinfo, &out_count); + (task_info_t)&taskinfo, &out_count); if (error != KERN_SUCCESS) return Qnil; #ifndef ULL2NUM /* "long long" does not exist here, use size_t instead. */ @@ -50,7 +50,7 @@ read_status(VALUE self) PROCESS_MEMORY_COUNTERS c; c.cb = sizeof(c); if (!GetProcessMemoryInfo(GetCurrentProcess(), &c, c.cb)) - return Qnil; + return Qnil; size = SIZET2NUM(c.PagefileUsage); rss = SIZET2NUM(c.WorkingSetSize); peak = SIZET2NUM(c.PeakWorkingSetSize); @@ -68,13 +68,13 @@ Init_memory_status(void) { VALUE mMemory = rb_define_module("Memory"); cMemoryStatus = - rb_struct_define_under(mMemory, "Status", "size", + rb_struct_define_under(mMemory, "Status", "size", #ifdef HAVE_RSS - "rss", + "rss", #endif #ifdef HAVE_PEAK - "peak", + "peak", #endif - (char *)NULL); + (char *)NULL); rb_define_method(cMemoryStatus, "_update", read_status, 0); } diff --git a/ext/-test-/memory_view/depend b/ext/-test-/memory_view/depend index 1219888768..a6ffd76f45 100644 --- a/ext/-test-/memory_view/depend +++ b/ext/-test-/memory_view/depend @@ -7,7 +7,6 @@ memory_view.o: $(hdrdir)/ruby/backward.h memory_view.o: $(hdrdir)/ruby/backward/2/assume.h memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h memory_view.o: $(hdrdir)/ruby/backward/2/bool.h -memory_view.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h memory_view.o: $(hdrdir)/ruby/backward/2/limits.h memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h memory_view.o: $(hdrdir)/ruby/defines.h memory_view.o: $(hdrdir)/ruby/intern.h +memory_view.o: $(hdrdir)/ruby/internal/abi.h memory_view.o: $(hdrdir)/ruby/internal/anyargs.h memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h +memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -111,7 +112,6 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h memory_view.o: $(hdrdir)/ruby/internal/intern/error.h memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h memory_view.o: $(hdrdir)/ruby/internal/intern/file.h -memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h memory_view.o: $(hdrdir)/ruby/internal/intern/io.h memory_view.o: $(hdrdir)/ruby/internal/intern/load.h @@ -128,6 +128,7 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/re.h memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h memory_view.o: $(hdrdir)/ruby/internal/intern/select.h memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +memory_view.o: $(hdrdir)/ruby/internal/intern/set.h memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h memory_view.o: $(hdrdir)/ruby/internal/intern/string.h @@ -142,12 +143,12 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h memory_view.o: $(hdrdir)/ruby/internal/method.h memory_view.o: $(hdrdir)/ruby/internal/module.h memory_view.o: $(hdrdir)/ruby/internal/newobj.h -memory_view.o: $(hdrdir)/ruby/internal/rgengc.h memory_view.o: $(hdrdir)/ruby/internal/scan_args.h memory_view.o: $(hdrdir)/ruby/internal/special_consts.h memory_view.o: $(hdrdir)/ruby/internal/static_assert.h memory_view.o: $(hdrdir)/ruby/internal/stdalign.h memory_view.o: $(hdrdir)/ruby/internal/stdbool.h +memory_view.o: $(hdrdir)/ruby/internal/stdckdint.h memory_view.o: $(hdrdir)/ruby/internal/symbol.h memory_view.o: $(hdrdir)/ruby/internal/value.h memory_view.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c index c1df0353cf..63f0beb81e 100644 --- a/ext/-test-/memory_view/memory_view.c +++ b/ext/-test-/memory_view/memory_view.c @@ -313,8 +313,8 @@ mdview_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags) static bool mdview_release_memory_view(VALUE obj, rb_memory_view_t *view) { - if (view->shape) xfree((void *)view->shape); - if (view->strides) xfree((void *)view->strides); + xfree((void *)view->shape); + xfree((void *)view->strides); return true; } diff --git a/ext/-test-/method/depend b/ext/-test-/method/depend index 1aef2cd182..95745b3dae 100644 --- a/ext/-test-/method/depend +++ b/ext/-test-/method/depend @@ -2,6 +2,19 @@ arity.o: $(RUBY_EXTCONF_H) arity.o: $(arch_hdrdir)/ruby/config.h arity.o: $(hdrdir)/ruby.h +arity.o: $(hdrdir)/ruby/assert.h +arity.o: $(hdrdir)/ruby/backward.h +arity.o: $(hdrdir)/ruby/backward/2/assume.h +arity.o: $(hdrdir)/ruby/backward/2/attributes.h +arity.o: $(hdrdir)/ruby/backward/2/bool.h +arity.o: $(hdrdir)/ruby/backward/2/inttypes.h +arity.o: $(hdrdir)/ruby/backward/2/limits.h +arity.o: $(hdrdir)/ruby/backward/2/long_long.h +arity.o: $(hdrdir)/ruby/backward/2/stdalign.h +arity.o: $(hdrdir)/ruby/backward/2/stdarg.h +arity.o: $(hdrdir)/ruby/defines.h +arity.o: $(hdrdir)/ruby/intern.h +arity.o: $(hdrdir)/ruby/internal/abi.h arity.o: $(hdrdir)/ruby/internal/anyargs.h arity.o: $(hdrdir)/ruby/internal/arithmetic.h arity.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ arity.o: $(hdrdir)/ruby/internal/attr/noexcept.h arity.o: $(hdrdir)/ruby/internal/attr/noinline.h arity.o: $(hdrdir)/ruby/internal/attr/nonnull.h arity.o: $(hdrdir)/ruby/internal/attr/noreturn.h +arity.o: $(hdrdir)/ruby/internal/attr/packed_struct.h arity.o: $(hdrdir)/ruby/internal/attr/pure.h arity.o: $(hdrdir)/ruby/internal/attr/restrict.h arity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ arity.o: $(hdrdir)/ruby/internal/intern/enumerator.h arity.o: $(hdrdir)/ruby/internal/intern/error.h arity.o: $(hdrdir)/ruby/internal/intern/eval.h arity.o: $(hdrdir)/ruby/internal/intern/file.h -arity.o: $(hdrdir)/ruby/internal/intern/gc.h arity.o: $(hdrdir)/ruby/internal/intern/hash.h arity.o: $(hdrdir)/ruby/internal/intern/io.h arity.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ arity.o: $(hdrdir)/ruby/internal/intern/re.h arity.o: $(hdrdir)/ruby/internal/intern/ruby.h arity.o: $(hdrdir)/ruby/internal/intern/select.h arity.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +arity.o: $(hdrdir)/ruby/internal/intern/set.h arity.o: $(hdrdir)/ruby/internal/intern/signal.h arity.o: $(hdrdir)/ruby/internal/intern/sprintf.h arity.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ arity.o: $(hdrdir)/ruby/internal/memory.h arity.o: $(hdrdir)/ruby/internal/method.h arity.o: $(hdrdir)/ruby/internal/module.h arity.o: $(hdrdir)/ruby/internal/newobj.h -arity.o: $(hdrdir)/ruby/internal/rgengc.h arity.o: $(hdrdir)/ruby/internal/scan_args.h arity.o: $(hdrdir)/ruby/internal/special_consts.h arity.o: $(hdrdir)/ruby/internal/static_assert.h arity.o: $(hdrdir)/ruby/internal/stdalign.h arity.o: $(hdrdir)/ruby/internal/stdbool.h +arity.o: $(hdrdir)/ruby/internal/stdckdint.h arity.o: $(hdrdir)/ruby/internal/symbol.h arity.o: $(hdrdir)/ruby/internal/value.h arity.o: $(hdrdir)/ruby/internal/value_type.h arity.o: $(hdrdir)/ruby/internal/variable.h arity.o: $(hdrdir)/ruby/internal/warning_push.h arity.o: $(hdrdir)/ruby/internal/xmalloc.h -arity.o: $(hdrdir)/ruby/assert.h -arity.o: $(hdrdir)/ruby/backward.h -arity.o: $(hdrdir)/ruby/backward/2/assume.h -arity.o: $(hdrdir)/ruby/backward/2/attributes.h -arity.o: $(hdrdir)/ruby/backward/2/bool.h -arity.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -arity.o: $(hdrdir)/ruby/backward/2/inttypes.h -arity.o: $(hdrdir)/ruby/backward/2/limits.h -arity.o: $(hdrdir)/ruby/backward/2/long_long.h -arity.o: $(hdrdir)/ruby/backward/2/stdalign.h -arity.o: $(hdrdir)/ruby/backward/2/stdarg.h -arity.o: $(hdrdir)/ruby/defines.h -arity.o: $(hdrdir)/ruby/intern.h arity.o: $(hdrdir)/ruby/missing.h arity.o: $(hdrdir)/ruby/ruby.h arity.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ arity.o: arity.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/notimplement/depend b/ext/-test-/notimplement/depend index 506795a137..69c970b6f2 100644 --- a/ext/-test-/notimplement/depend +++ b/ext/-test-/notimplement/depend @@ -2,6 +2,19 @@ bug.o: $(RUBY_EXTCONF_H) bug.o: $(arch_hdrdir)/ruby/config.h bug.o: $(hdrdir)/ruby.h +bug.o: $(hdrdir)/ruby/assert.h +bug.o: $(hdrdir)/ruby/backward.h +bug.o: $(hdrdir)/ruby/backward/2/assume.h +bug.o: $(hdrdir)/ruby/backward/2/attributes.h +bug.o: $(hdrdir)/ruby/backward/2/bool.h +bug.o: $(hdrdir)/ruby/backward/2/inttypes.h +bug.o: $(hdrdir)/ruby/backward/2/limits.h +bug.o: $(hdrdir)/ruby/backward/2/long_long.h +bug.o: $(hdrdir)/ruby/backward/2/stdalign.h +bug.o: $(hdrdir)/ruby/backward/2/stdarg.h +bug.o: $(hdrdir)/ruby/defines.h +bug.o: $(hdrdir)/ruby/intern.h +bug.o: $(hdrdir)/ruby/internal/abi.h bug.o: $(hdrdir)/ruby/internal/anyargs.h bug.o: $(hdrdir)/ruby/internal/arithmetic.h bug.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ bug.o: $(hdrdir)/ruby/internal/attr/noexcept.h bug.o: $(hdrdir)/ruby/internal/attr/noinline.h bug.o: $(hdrdir)/ruby/internal/attr/nonnull.h bug.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bug.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bug.o: $(hdrdir)/ruby/internal/attr/pure.h bug.o: $(hdrdir)/ruby/internal/attr/restrict.h bug.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ bug.o: $(hdrdir)/ruby/internal/intern/enumerator.h bug.o: $(hdrdir)/ruby/internal/intern/error.h bug.o: $(hdrdir)/ruby/internal/intern/eval.h bug.o: $(hdrdir)/ruby/internal/intern/file.h -bug.o: $(hdrdir)/ruby/internal/intern/gc.h bug.o: $(hdrdir)/ruby/internal/intern/hash.h bug.o: $(hdrdir)/ruby/internal/intern/io.h bug.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ bug.o: $(hdrdir)/ruby/internal/intern/re.h bug.o: $(hdrdir)/ruby/internal/intern/ruby.h bug.o: $(hdrdir)/ruby/internal/intern/select.h bug.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bug.o: $(hdrdir)/ruby/internal/intern/set.h bug.o: $(hdrdir)/ruby/internal/intern/signal.h bug.o: $(hdrdir)/ruby/internal/intern/sprintf.h bug.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ bug.o: $(hdrdir)/ruby/internal/memory.h bug.o: $(hdrdir)/ruby/internal/method.h bug.o: $(hdrdir)/ruby/internal/module.h bug.o: $(hdrdir)/ruby/internal/newobj.h -bug.o: $(hdrdir)/ruby/internal/rgengc.h bug.o: $(hdrdir)/ruby/internal/scan_args.h bug.o: $(hdrdir)/ruby/internal/special_consts.h bug.o: $(hdrdir)/ruby/internal/static_assert.h bug.o: $(hdrdir)/ruby/internal/stdalign.h bug.o: $(hdrdir)/ruby/internal/stdbool.h +bug.o: $(hdrdir)/ruby/internal/stdckdint.h bug.o: $(hdrdir)/ruby/internal/symbol.h bug.o: $(hdrdir)/ruby/internal/value.h bug.o: $(hdrdir)/ruby/internal/value_type.h bug.o: $(hdrdir)/ruby/internal/variable.h bug.o: $(hdrdir)/ruby/internal/warning_push.h bug.o: $(hdrdir)/ruby/internal/xmalloc.h -bug.o: $(hdrdir)/ruby/assert.h -bug.o: $(hdrdir)/ruby/backward.h -bug.o: $(hdrdir)/ruby/backward/2/assume.h -bug.o: $(hdrdir)/ruby/backward/2/attributes.h -bug.o: $(hdrdir)/ruby/backward/2/bool.h -bug.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bug.o: $(hdrdir)/ruby/backward/2/inttypes.h -bug.o: $(hdrdir)/ruby/backward/2/limits.h -bug.o: $(hdrdir)/ruby/backward/2/long_long.h -bug.o: $(hdrdir)/ruby/backward/2/stdalign.h -bug.o: $(hdrdir)/ruby/backward/2/stdarg.h -bug.o: $(hdrdir)/ruby/defines.h -bug.o: $(hdrdir)/ruby/intern.h bug.o: $(hdrdir)/ruby/missing.h bug.o: $(hdrdir)/ruby/ruby.h bug.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/num2int/depend b/ext/-test-/num2int/depend index 692423ac63..75536363ac 100644 --- a/ext/-test-/num2int/depend +++ b/ext/-test-/num2int/depend @@ -2,6 +2,19 @@ num2int.o: $(RUBY_EXTCONF_H) num2int.o: $(arch_hdrdir)/ruby/config.h num2int.o: $(hdrdir)/ruby.h +num2int.o: $(hdrdir)/ruby/assert.h +num2int.o: $(hdrdir)/ruby/backward.h +num2int.o: $(hdrdir)/ruby/backward/2/assume.h +num2int.o: $(hdrdir)/ruby/backward/2/attributes.h +num2int.o: $(hdrdir)/ruby/backward/2/bool.h +num2int.o: $(hdrdir)/ruby/backward/2/inttypes.h +num2int.o: $(hdrdir)/ruby/backward/2/limits.h +num2int.o: $(hdrdir)/ruby/backward/2/long_long.h +num2int.o: $(hdrdir)/ruby/backward/2/stdalign.h +num2int.o: $(hdrdir)/ruby/backward/2/stdarg.h +num2int.o: $(hdrdir)/ruby/defines.h +num2int.o: $(hdrdir)/ruby/intern.h +num2int.o: $(hdrdir)/ruby/internal/abi.h num2int.o: $(hdrdir)/ruby/internal/anyargs.h num2int.o: $(hdrdir)/ruby/internal/arithmetic.h num2int.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ num2int.o: $(hdrdir)/ruby/internal/attr/noexcept.h num2int.o: $(hdrdir)/ruby/internal/attr/noinline.h num2int.o: $(hdrdir)/ruby/internal/attr/nonnull.h num2int.o: $(hdrdir)/ruby/internal/attr/noreturn.h +num2int.o: $(hdrdir)/ruby/internal/attr/packed_struct.h num2int.o: $(hdrdir)/ruby/internal/attr/pure.h num2int.o: $(hdrdir)/ruby/internal/attr/restrict.h num2int.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ num2int.o: $(hdrdir)/ruby/internal/intern/enumerator.h num2int.o: $(hdrdir)/ruby/internal/intern/error.h num2int.o: $(hdrdir)/ruby/internal/intern/eval.h num2int.o: $(hdrdir)/ruby/internal/intern/file.h -num2int.o: $(hdrdir)/ruby/internal/intern/gc.h num2int.o: $(hdrdir)/ruby/internal/intern/hash.h num2int.o: $(hdrdir)/ruby/internal/intern/io.h num2int.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ num2int.o: $(hdrdir)/ruby/internal/intern/re.h num2int.o: $(hdrdir)/ruby/internal/intern/ruby.h num2int.o: $(hdrdir)/ruby/internal/intern/select.h num2int.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +num2int.o: $(hdrdir)/ruby/internal/intern/set.h num2int.o: $(hdrdir)/ruby/internal/intern/signal.h num2int.o: $(hdrdir)/ruby/internal/intern/sprintf.h num2int.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ num2int.o: $(hdrdir)/ruby/internal/memory.h num2int.o: $(hdrdir)/ruby/internal/method.h num2int.o: $(hdrdir)/ruby/internal/module.h num2int.o: $(hdrdir)/ruby/internal/newobj.h -num2int.o: $(hdrdir)/ruby/internal/rgengc.h num2int.o: $(hdrdir)/ruby/internal/scan_args.h num2int.o: $(hdrdir)/ruby/internal/special_consts.h num2int.o: $(hdrdir)/ruby/internal/static_assert.h num2int.o: $(hdrdir)/ruby/internal/stdalign.h num2int.o: $(hdrdir)/ruby/internal/stdbool.h +num2int.o: $(hdrdir)/ruby/internal/stdckdint.h num2int.o: $(hdrdir)/ruby/internal/symbol.h num2int.o: $(hdrdir)/ruby/internal/value.h num2int.o: $(hdrdir)/ruby/internal/value_type.h num2int.o: $(hdrdir)/ruby/internal/variable.h num2int.o: $(hdrdir)/ruby/internal/warning_push.h num2int.o: $(hdrdir)/ruby/internal/xmalloc.h -num2int.o: $(hdrdir)/ruby/assert.h -num2int.o: $(hdrdir)/ruby/backward.h -num2int.o: $(hdrdir)/ruby/backward/2/assume.h -num2int.o: $(hdrdir)/ruby/backward/2/attributes.h -num2int.o: $(hdrdir)/ruby/backward/2/bool.h -num2int.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -num2int.o: $(hdrdir)/ruby/backward/2/inttypes.h -num2int.o: $(hdrdir)/ruby/backward/2/limits.h -num2int.o: $(hdrdir)/ruby/backward/2/long_long.h -num2int.o: $(hdrdir)/ruby/backward/2/stdalign.h -num2int.o: $(hdrdir)/ruby/backward/2/stdarg.h -num2int.o: $(hdrdir)/ruby/defines.h -num2int.o: $(hdrdir)/ruby/intern.h num2int.o: $(hdrdir)/ruby/missing.h num2int.o: $(hdrdir)/ruby/ruby.h num2int.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/num2int/num2int.c b/ext/-test-/num2int/num2int.c index 3aec3ccf3b..63a441fda6 100644 --- a/ext/-test-/num2int/num2int.c +++ b/ext/-test-/num2int/num2int.c @@ -4,7 +4,7 @@ static VALUE test_num2short(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%d", NUM2SHORT(num)); + snprintf(buf, sizeof(buf), "%d", NUM2SHORT(num)); return rb_str_new_cstr(buf); } @@ -12,7 +12,7 @@ static VALUE test_num2ushort(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%u", NUM2USHORT(num)); + snprintf(buf, sizeof(buf), "%u", NUM2USHORT(num)); return rb_str_new_cstr(buf); } @@ -20,7 +20,7 @@ static VALUE test_num2int(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%d", NUM2INT(num)); + snprintf(buf, sizeof(buf), "%d", NUM2INT(num)); return rb_str_new_cstr(buf); } @@ -28,7 +28,7 @@ static VALUE test_num2uint(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%u", NUM2UINT(num)); + snprintf(buf, sizeof(buf), "%u", NUM2UINT(num)); return rb_str_new_cstr(buf); } @@ -36,7 +36,7 @@ static VALUE test_num2long(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%ld", NUM2LONG(num)); + snprintf(buf, sizeof(buf), "%ld", NUM2LONG(num)); return rb_str_new_cstr(buf); } @@ -44,7 +44,7 @@ static VALUE test_num2ulong(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%lu", NUM2ULONG(num)); + snprintf(buf, sizeof(buf), "%lu", NUM2ULONG(num)); return rb_str_new_cstr(buf); } @@ -53,7 +53,7 @@ static VALUE test_num2ll(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%"PRI_LL_PREFIX"d", NUM2LL(num)); + snprintf(buf, sizeof(buf), "%"PRI_LL_PREFIX"d", NUM2LL(num)); return rb_str_new_cstr(buf); } @@ -61,7 +61,7 @@ static VALUE test_num2ull(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%"PRI_LL_PREFIX"u", NUM2ULL(num)); + snprintf(buf, sizeof(buf), "%"PRI_LL_PREFIX"u", NUM2ULL(num)); return rb_str_new_cstr(buf); } #endif @@ -70,7 +70,7 @@ static VALUE test_fix2short(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%d", FIX2SHORT(num)); + snprintf(buf, sizeof(buf), "%d", FIX2SHORT(num)); return rb_str_new_cstr(buf); } @@ -78,7 +78,7 @@ static VALUE test_fix2int(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%d", FIX2INT(num)); + snprintf(buf, sizeof(buf), "%d", FIX2INT(num)); return rb_str_new_cstr(buf); } @@ -86,7 +86,7 @@ static VALUE test_fix2uint(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%u", FIX2UINT(num)); + snprintf(buf, sizeof(buf), "%u", FIX2UINT(num)); return rb_str_new_cstr(buf); } @@ -94,7 +94,7 @@ static VALUE test_fix2long(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%ld", FIX2LONG(num)); + snprintf(buf, sizeof(buf), "%ld", FIX2LONG(num)); return rb_str_new_cstr(buf); } @@ -102,7 +102,7 @@ static VALUE test_fix2ulong(VALUE obj, VALUE num) { char buf[128]; - sprintf(buf, "%lu", FIX2ULONG(num)); + snprintf(buf, sizeof(buf), "%lu", FIX2ULONG(num)); return rb_str_new_cstr(buf); } diff --git a/ext/-test-/path_to_class/depend b/ext/-test-/path_to_class/depend index e2bc971e4e..e535058e09 100644 --- a/ext/-test-/path_to_class/depend +++ b/ext/-test-/path_to_class/depend @@ -2,6 +2,19 @@ path_to_class.o: $(RUBY_EXTCONF_H) path_to_class.o: $(arch_hdrdir)/ruby/config.h path_to_class.o: $(hdrdir)/ruby.h +path_to_class.o: $(hdrdir)/ruby/assert.h +path_to_class.o: $(hdrdir)/ruby/backward.h +path_to_class.o: $(hdrdir)/ruby/backward/2/assume.h +path_to_class.o: $(hdrdir)/ruby/backward/2/attributes.h +path_to_class.o: $(hdrdir)/ruby/backward/2/bool.h +path_to_class.o: $(hdrdir)/ruby/backward/2/inttypes.h +path_to_class.o: $(hdrdir)/ruby/backward/2/limits.h +path_to_class.o: $(hdrdir)/ruby/backward/2/long_long.h +path_to_class.o: $(hdrdir)/ruby/backward/2/stdalign.h +path_to_class.o: $(hdrdir)/ruby/backward/2/stdarg.h +path_to_class.o: $(hdrdir)/ruby/defines.h +path_to_class.o: $(hdrdir)/ruby/intern.h +path_to_class.o: $(hdrdir)/ruby/internal/abi.h path_to_class.o: $(hdrdir)/ruby/internal/anyargs.h path_to_class.o: $(hdrdir)/ruby/internal/arithmetic.h path_to_class.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ path_to_class.o: $(hdrdir)/ruby/internal/attr/noexcept.h path_to_class.o: $(hdrdir)/ruby/internal/attr/noinline.h path_to_class.o: $(hdrdir)/ruby/internal/attr/nonnull.h path_to_class.o: $(hdrdir)/ruby/internal/attr/noreturn.h +path_to_class.o: $(hdrdir)/ruby/internal/attr/packed_struct.h path_to_class.o: $(hdrdir)/ruby/internal/attr/pure.h path_to_class.o: $(hdrdir)/ruby/internal/attr/restrict.h path_to_class.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ path_to_class.o: $(hdrdir)/ruby/internal/intern/enumerator.h path_to_class.o: $(hdrdir)/ruby/internal/intern/error.h path_to_class.o: $(hdrdir)/ruby/internal/intern/eval.h path_to_class.o: $(hdrdir)/ruby/internal/intern/file.h -path_to_class.o: $(hdrdir)/ruby/internal/intern/gc.h path_to_class.o: $(hdrdir)/ruby/internal/intern/hash.h path_to_class.o: $(hdrdir)/ruby/internal/intern/io.h path_to_class.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ path_to_class.o: $(hdrdir)/ruby/internal/intern/re.h path_to_class.o: $(hdrdir)/ruby/internal/intern/ruby.h path_to_class.o: $(hdrdir)/ruby/internal/intern/select.h path_to_class.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +path_to_class.o: $(hdrdir)/ruby/internal/intern/set.h path_to_class.o: $(hdrdir)/ruby/internal/intern/signal.h path_to_class.o: $(hdrdir)/ruby/internal/intern/sprintf.h path_to_class.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ path_to_class.o: $(hdrdir)/ruby/internal/memory.h path_to_class.o: $(hdrdir)/ruby/internal/method.h path_to_class.o: $(hdrdir)/ruby/internal/module.h path_to_class.o: $(hdrdir)/ruby/internal/newobj.h -path_to_class.o: $(hdrdir)/ruby/internal/rgengc.h path_to_class.o: $(hdrdir)/ruby/internal/scan_args.h path_to_class.o: $(hdrdir)/ruby/internal/special_consts.h path_to_class.o: $(hdrdir)/ruby/internal/static_assert.h path_to_class.o: $(hdrdir)/ruby/internal/stdalign.h path_to_class.o: $(hdrdir)/ruby/internal/stdbool.h +path_to_class.o: $(hdrdir)/ruby/internal/stdckdint.h path_to_class.o: $(hdrdir)/ruby/internal/symbol.h path_to_class.o: $(hdrdir)/ruby/internal/value.h path_to_class.o: $(hdrdir)/ruby/internal/value_type.h path_to_class.o: $(hdrdir)/ruby/internal/variable.h path_to_class.o: $(hdrdir)/ruby/internal/warning_push.h path_to_class.o: $(hdrdir)/ruby/internal/xmalloc.h -path_to_class.o: $(hdrdir)/ruby/assert.h -path_to_class.o: $(hdrdir)/ruby/backward.h -path_to_class.o: $(hdrdir)/ruby/backward/2/assume.h -path_to_class.o: $(hdrdir)/ruby/backward/2/attributes.h -path_to_class.o: $(hdrdir)/ruby/backward/2/bool.h -path_to_class.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -path_to_class.o: $(hdrdir)/ruby/backward/2/inttypes.h -path_to_class.o: $(hdrdir)/ruby/backward/2/limits.h -path_to_class.o: $(hdrdir)/ruby/backward/2/long_long.h -path_to_class.o: $(hdrdir)/ruby/backward/2/stdalign.h -path_to_class.o: $(hdrdir)/ruby/backward/2/stdarg.h -path_to_class.o: $(hdrdir)/ruby/defines.h -path_to_class.o: $(hdrdir)/ruby/intern.h path_to_class.o: $(hdrdir)/ruby/missing.h path_to_class.o: $(hdrdir)/ruby/ruby.h path_to_class.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/popen_deadlock/depend b/ext/-test-/popen_deadlock/depend index e36a6c9568..0b8932e8b8 100644 --- a/ext/-test-/popen_deadlock/depend +++ b/ext/-test-/popen_deadlock/depend @@ -1,6 +1,20 @@ # AUTOGENERATED DEPENDENCIES START infinite_loop_dlsym.o: $(RUBY_EXTCONF_H) infinite_loop_dlsym.o: $(arch_hdrdir)/ruby/config.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/assert.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/assume.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/attributes.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/bool.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/inttypes.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/limits.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/long_long.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdalign.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdarg.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/defines.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/intern.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/abi.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/anyargs.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +52,7 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noexcept.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noinline.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/nonnull.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/noreturn.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/packed_struct.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/pure.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/restrict.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +112,6 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/enumerator.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/error.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/eval.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/file.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/gc.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/hash.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/io.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +128,7 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/re.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/ruby.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/select.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/set.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/signal.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/sprintf.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +143,18 @@ infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/memory.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/method.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/module.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/newobj.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/rgengc.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/scan_args.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/special_consts.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/static_assert.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/stdalign.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/stdbool.h +infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/stdckdint.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/symbol.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/value.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/value_type.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/variable.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/warning_push.h infinite_loop_dlsym.o: $(hdrdir)/ruby/internal/xmalloc.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/assert.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/assume.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/attributes.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/bool.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/inttypes.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/limits.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/long_long.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdalign.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/backward/2/stdarg.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/defines.h -infinite_loop_dlsym.o: $(hdrdir)/ruby/intern.h infinite_loop_dlsym.o: $(hdrdir)/ruby/missing.h infinite_loop_dlsym.o: $(hdrdir)/ruby/ruby.h infinite_loop_dlsym.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/postponed_job/depend b/ext/-test-/postponed_job/depend index acabceb0fb..ff567e3921 100644 --- a/ext/-test-/postponed_job/depend +++ b/ext/-test-/postponed_job/depend @@ -2,6 +2,20 @@ postponed_job.o: $(RUBY_EXTCONF_H) postponed_job.o: $(arch_hdrdir)/ruby/config.h postponed_job.o: $(hdrdir)/ruby.h +postponed_job.o: $(hdrdir)/ruby/assert.h +postponed_job.o: $(hdrdir)/ruby/backward.h +postponed_job.o: $(hdrdir)/ruby/backward/2/assume.h +postponed_job.o: $(hdrdir)/ruby/backward/2/attributes.h +postponed_job.o: $(hdrdir)/ruby/backward/2/bool.h +postponed_job.o: $(hdrdir)/ruby/backward/2/inttypes.h +postponed_job.o: $(hdrdir)/ruby/backward/2/limits.h +postponed_job.o: $(hdrdir)/ruby/backward/2/long_long.h +postponed_job.o: $(hdrdir)/ruby/backward/2/stdalign.h +postponed_job.o: $(hdrdir)/ruby/backward/2/stdarg.h +postponed_job.o: $(hdrdir)/ruby/debug.h +postponed_job.o: $(hdrdir)/ruby/defines.h +postponed_job.o: $(hdrdir)/ruby/intern.h +postponed_job.o: $(hdrdir)/ruby/internal/abi.h postponed_job.o: $(hdrdir)/ruby/internal/anyargs.h postponed_job.o: $(hdrdir)/ruby/internal/arithmetic.h postponed_job.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +53,7 @@ postponed_job.o: $(hdrdir)/ruby/internal/attr/noexcept.h postponed_job.o: $(hdrdir)/ruby/internal/attr/noinline.h postponed_job.o: $(hdrdir)/ruby/internal/attr/nonnull.h postponed_job.o: $(hdrdir)/ruby/internal/attr/noreturn.h +postponed_job.o: $(hdrdir)/ruby/internal/attr/packed_struct.h postponed_job.o: $(hdrdir)/ruby/internal/attr/pure.h postponed_job.o: $(hdrdir)/ruby/internal/attr/restrict.h postponed_job.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +113,6 @@ postponed_job.o: $(hdrdir)/ruby/internal/intern/enumerator.h postponed_job.o: $(hdrdir)/ruby/internal/intern/error.h postponed_job.o: $(hdrdir)/ruby/internal/intern/eval.h postponed_job.o: $(hdrdir)/ruby/internal/intern/file.h -postponed_job.o: $(hdrdir)/ruby/internal/intern/gc.h postponed_job.o: $(hdrdir)/ruby/internal/intern/hash.h postponed_job.o: $(hdrdir)/ruby/internal/intern/io.h postponed_job.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +129,7 @@ postponed_job.o: $(hdrdir)/ruby/internal/intern/re.h postponed_job.o: $(hdrdir)/ruby/internal/intern/ruby.h postponed_job.o: $(hdrdir)/ruby/internal/intern/select.h postponed_job.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +postponed_job.o: $(hdrdir)/ruby/internal/intern/set.h postponed_job.o: $(hdrdir)/ruby/internal/intern/signal.h postponed_job.o: $(hdrdir)/ruby/internal/intern/sprintf.h postponed_job.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,32 +144,18 @@ postponed_job.o: $(hdrdir)/ruby/internal/memory.h postponed_job.o: $(hdrdir)/ruby/internal/method.h postponed_job.o: $(hdrdir)/ruby/internal/module.h postponed_job.o: $(hdrdir)/ruby/internal/newobj.h -postponed_job.o: $(hdrdir)/ruby/internal/rgengc.h postponed_job.o: $(hdrdir)/ruby/internal/scan_args.h postponed_job.o: $(hdrdir)/ruby/internal/special_consts.h postponed_job.o: $(hdrdir)/ruby/internal/static_assert.h postponed_job.o: $(hdrdir)/ruby/internal/stdalign.h postponed_job.o: $(hdrdir)/ruby/internal/stdbool.h +postponed_job.o: $(hdrdir)/ruby/internal/stdckdint.h postponed_job.o: $(hdrdir)/ruby/internal/symbol.h postponed_job.o: $(hdrdir)/ruby/internal/value.h postponed_job.o: $(hdrdir)/ruby/internal/value_type.h postponed_job.o: $(hdrdir)/ruby/internal/variable.h postponed_job.o: $(hdrdir)/ruby/internal/warning_push.h postponed_job.o: $(hdrdir)/ruby/internal/xmalloc.h -postponed_job.o: $(hdrdir)/ruby/assert.h -postponed_job.o: $(hdrdir)/ruby/backward.h -postponed_job.o: $(hdrdir)/ruby/backward/2/assume.h -postponed_job.o: $(hdrdir)/ruby/backward/2/attributes.h -postponed_job.o: $(hdrdir)/ruby/backward/2/bool.h -postponed_job.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -postponed_job.o: $(hdrdir)/ruby/backward/2/inttypes.h -postponed_job.o: $(hdrdir)/ruby/backward/2/limits.h -postponed_job.o: $(hdrdir)/ruby/backward/2/long_long.h -postponed_job.o: $(hdrdir)/ruby/backward/2/stdalign.h -postponed_job.o: $(hdrdir)/ruby/backward/2/stdarg.h -postponed_job.o: $(hdrdir)/ruby/debug.h -postponed_job.o: $(hdrdir)/ruby/defines.h -postponed_job.o: $(hdrdir)/ruby/intern.h postponed_job.o: $(hdrdir)/ruby/missing.h postponed_job.o: $(hdrdir)/ruby/ruby.h postponed_job.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/postponed_job/postponed_job.c b/ext/-test-/postponed_job/postponed_job.c index d8684d475a..9ac866ae77 100644 --- a/ext/-test-/postponed_job/postponed_job.c +++ b/ext/-test-/postponed_job/postponed_job.c @@ -1,6 +1,29 @@ #include "ruby.h" #include "ruby/debug.h" +// We're testing deprecated things, don't print the compiler warnings +#if 0 + +#elif defined(_MSC_VER) +#pragma warning(disable : 4996) + +#elif defined(__INTEL_COMPILER) +#pragma warning(disable : 1786) + +#elif defined(__clang__) +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#elif defined(__SUNPRO_CC) +#pragma error_messages (off,symdeprecated) + +#else +// :FIXME: improve here for your compiler. + +#endif + static int counter; static void @@ -58,6 +81,137 @@ pjob_call_direct(VALUE self, VALUE obj) return self; } +static void pjob_noop_callback(void *data) { } + +static VALUE +pjob_register_one_same(VALUE self) +{ + rb_gc_start(); + int r1 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL); + int r2 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL); + int r3 = rb_postponed_job_register_one(0, pjob_noop_callback, NULL); + VALUE ary = rb_ary_new(); + rb_ary_push(ary, INT2FIX(r1)); + rb_ary_push(ary, INT2FIX(r2)); + rb_ary_push(ary, INT2FIX(r3)); + return ary; +} + +#ifdef HAVE_PTHREAD_H +#include <pthread.h> + +static void * +pjob_register_in_c_thread_i(void *obj) +{ + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + rb_postponed_job_register_one(0, pjob_one_callback, (void *)obj); + return NULL; +} + +static VALUE +pjob_register_in_c_thread(VALUE self, VALUE obj) +{ + pthread_t thread; + if (pthread_create(&thread, NULL, pjob_register_in_c_thread_i, (void *)obj)) { + return Qfalse; + } + + if (pthread_join(thread, NULL)) { + return Qfalse; + } + + return Qtrue; +} +#endif + +static void +pjob_preregistered_callback(void *data) +{ + VALUE ary = (VALUE)data; + Check_Type(ary, T_ARRAY); + rb_ary_push(ary, INT2FIX(counter)); +} + +static VALUE +pjob_preregister_and_call_with_sleep(VALUE self, VALUE obj) +{ + counter = 0; + rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, pjob_preregistered_callback, (void *)obj); + counter++; + rb_postponed_job_trigger(h); + rb_thread_sleep(0); + counter++; + rb_postponed_job_trigger(h); + rb_thread_sleep(0); + counter++; + rb_postponed_job_trigger(h); + rb_thread_sleep(0); + return self; +} + +static VALUE +pjob_preregister_and_call_without_sleep(VALUE self, VALUE obj) +{ + counter = 0; + rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, pjob_preregistered_callback, (void *)obj); + counter = 3; + rb_postponed_job_trigger(h); + rb_postponed_job_trigger(h); + rb_postponed_job_trigger(h); + return self; +} + +static VALUE +pjob_preregister_multiple_times(VALUE self) +{ + int r1 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL); + int r2 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL); + int r3 = rb_postponed_job_preregister(0, pjob_noop_callback, NULL); + VALUE ary = rb_ary_new(); + rb_ary_push(ary, INT2FIX(r1)); + rb_ary_push(ary, INT2FIX(r2)); + rb_ary_push(ary, INT2FIX(r3)); + return ary; + +} + +struct pjob_append_data_args { + VALUE ary; + VALUE data; +}; + +static void +pjob_append_data_callback(void *vctx) { + struct pjob_append_data_args *ctx = (struct pjob_append_data_args *)vctx; + Check_Type(ctx->ary, T_ARRAY); + rb_ary_push(ctx->ary, ctx->data); +} + +static VALUE +pjob_preregister_calls_with_last_argument(VALUE self) +{ + VALUE ary = rb_ary_new(); + + struct pjob_append_data_args arg1 = { .ary = ary, .data = INT2FIX(1) }; + struct pjob_append_data_args arg2 = { .ary = ary, .data = INT2FIX(2) }; + struct pjob_append_data_args arg3 = { .ary = ary, .data = INT2FIX(3) }; + struct pjob_append_data_args arg4 = { .ary = ary, .data = INT2FIX(4) }; + + rb_postponed_job_handle_t h; + h = rb_postponed_job_preregister(0, pjob_append_data_callback, &arg1); + rb_postponed_job_preregister(0, pjob_append_data_callback, &arg2); + rb_postponed_job_trigger(h); + rb_postponed_job_preregister(0, pjob_append_data_callback, &arg3); + rb_thread_sleep(0); // should execute with arg3 + + rb_postponed_job_preregister(0, pjob_append_data_callback, &arg4); + rb_postponed_job_trigger(h); + rb_thread_sleep(0); // should execute with arg4 + + return ary; +} + void Init_postponed_job(VALUE self) { @@ -65,5 +219,13 @@ Init_postponed_job(VALUE self) rb_define_module_function(mBug, "postponed_job_register", pjob_register, 1); rb_define_module_function(mBug, "postponed_job_register_one", pjob_register_one, 1); rb_define_module_function(mBug, "postponed_job_call_direct", pjob_call_direct, 1); + rb_define_module_function(mBug, "postponed_job_register_one_same", pjob_register_one_same, 0); +#ifdef HAVE_PTHREAD_H + rb_define_module_function(mBug, "postponed_job_register_in_c_thread", pjob_register_in_c_thread, 1); +#endif + rb_define_module_function(mBug, "postponed_job_preregister_and_call_with_sleep", pjob_preregister_and_call_with_sleep, 1); + rb_define_module_function(mBug, "postponed_job_preregister_and_call_without_sleep", pjob_preregister_and_call_without_sleep, 1); + rb_define_module_function(mBug, "postponed_job_preregister_multiple_times", pjob_preregister_multiple_times, 0); + rb_define_module_function(mBug, "postponed_job_preregister_calls_with_last_argument", pjob_preregister_calls_with_last_argument, 0); } diff --git a/ext/-test-/printf/depend b/ext/-test-/printf/depend index 72f3b081be..be895cf769 100644 --- a/ext/-test-/printf/depend +++ b/ext/-test-/printf/depend @@ -7,7 +7,6 @@ printf.o: $(hdrdir)/ruby/backward.h printf.o: $(hdrdir)/ruby/backward/2/assume.h printf.o: $(hdrdir)/ruby/backward/2/attributes.h printf.o: $(hdrdir)/ruby/backward/2/bool.h -printf.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h printf.o: $(hdrdir)/ruby/backward/2/inttypes.h printf.o: $(hdrdir)/ruby/backward/2/limits.h printf.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ printf.o: $(hdrdir)/ruby/backward/2/stdarg.h printf.o: $(hdrdir)/ruby/defines.h printf.o: $(hdrdir)/ruby/encoding.h printf.o: $(hdrdir)/ruby/intern.h +printf.o: $(hdrdir)/ruby/internal/abi.h printf.o: $(hdrdir)/ruby/internal/anyargs.h printf.o: $(hdrdir)/ruby/internal/arithmetic.h printf.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ printf.o: $(hdrdir)/ruby/internal/attr/noexcept.h printf.o: $(hdrdir)/ruby/internal/attr/noinline.h printf.o: $(hdrdir)/ruby/internal/attr/nonnull.h printf.o: $(hdrdir)/ruby/internal/attr/noreturn.h +printf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h printf.o: $(hdrdir)/ruby/internal/attr/pure.h printf.o: $(hdrdir)/ruby/internal/attr/restrict.h printf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ printf.o: $(hdrdir)/ruby/internal/intern/enumerator.h printf.o: $(hdrdir)/ruby/internal/intern/error.h printf.o: $(hdrdir)/ruby/internal/intern/eval.h printf.o: $(hdrdir)/ruby/internal/intern/file.h -printf.o: $(hdrdir)/ruby/internal/intern/gc.h printf.o: $(hdrdir)/ruby/internal/intern/hash.h printf.o: $(hdrdir)/ruby/internal/intern/io.h printf.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ printf.o: $(hdrdir)/ruby/internal/intern/re.h printf.o: $(hdrdir)/ruby/internal/intern/ruby.h printf.o: $(hdrdir)/ruby/internal/intern/select.h printf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +printf.o: $(hdrdir)/ruby/internal/intern/set.h printf.o: $(hdrdir)/ruby/internal/intern/signal.h printf.o: $(hdrdir)/ruby/internal/intern/sprintf.h printf.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ printf.o: $(hdrdir)/ruby/internal/memory.h printf.o: $(hdrdir)/ruby/internal/method.h printf.o: $(hdrdir)/ruby/internal/module.h printf.o: $(hdrdir)/ruby/internal/newobj.h -printf.o: $(hdrdir)/ruby/internal/rgengc.h printf.o: $(hdrdir)/ruby/internal/scan_args.h printf.o: $(hdrdir)/ruby/internal/special_consts.h printf.o: $(hdrdir)/ruby/internal/static_assert.h printf.o: $(hdrdir)/ruby/internal/stdalign.h printf.o: $(hdrdir)/ruby/internal/stdbool.h +printf.o: $(hdrdir)/ruby/internal/stdckdint.h printf.o: $(hdrdir)/ruby/internal/symbol.h printf.o: $(hdrdir)/ruby/internal/value.h printf.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/printf/printf.c b/ext/-test-/printf/printf.c index e793bb7a48..889c0d9f0d 100644 --- a/ext/-test-/printf/printf.c +++ b/ext/-test-/printf/printf.c @@ -25,7 +25,7 @@ uint_to_str(char *p, char *e, unsigned int x) char *e0 = e; if (e <= p) return p; do { - *--e = x % 10 + '0'; + *--e = x % 10 + '0'; } while ((x /= 10) != 0 && e > p); memmove(p, e, e0 - e); return p + (e0 - e); @@ -44,48 +44,48 @@ printf_test_call(int argc, VALUE *argv, VALUE self) if (RSTRING_LEN(type) != 1) rb_raise(rb_eArgError, "wrong length(%ld)", RSTRING_LEN(type)); switch (cnv = RSTRING_PTR(type)[0]) { case 'd': case 'x': case 'o': case 'X': - n = NUM2INT(num); - break; + n = NUM2INT(num); + break; case 's': - s = StringValueCStr(num); - break; + s = StringValueCStr(num); + break; default: rb_raise(rb_eArgError, "wrong conversion(%c)", cnv); } *p++ = '%'; if (!NIL_P(opt)) { - VALUE v; - Check_Type(opt, T_HASH); - if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("space"))))) { - *p++ = ' '; - } - if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("hash"))))) { - *p++ = '#'; - } - if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("plus"))))) { - *p++ = '+'; - } - if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("minus"))))) { - *p++ = '-'; - } - if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("zero"))))) { - *p++ = '0'; - } - if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("width"))))) { - p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); - } - if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("prec"))))) { - *p++ = '.'; - if (FIXNUM_P(v)) - p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); - } + VALUE v; + Check_Type(opt, T_HASH); + if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("space"))))) { + *p++ = ' '; + } + if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("hash"))))) { + *p++ = '#'; + } + if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("plus"))))) { + *p++ = '+'; + } + if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("minus"))))) { + *p++ = '-'; + } + if (RTEST(rb_hash_aref(opt, ID2SYM(rb_intern("zero"))))) { + *p++ = '0'; + } + if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("width"))))) { + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); + } + if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("prec"))))) { + *p++ = '.'; + if (FIXNUM_P(v)) + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v)); + } } *p++ = cnv; *p++ = '\0'; if (cnv == 's') { - result = rb_enc_sprintf(rb_usascii_encoding(), format, s); + result = rb_enc_sprintf(rb_usascii_encoding(), format, s); } else { - result = rb_enc_sprintf(rb_usascii_encoding(), format, n); + result = rb_enc_sprintf(rb_usascii_encoding(), format, n); } return rb_assoc_new(result, rb_usascii_str_new_cstr(format)); } diff --git a/ext/-test-/proc/depend b/ext/-test-/proc/depend index 929b4927dc..97834db0a2 100644 --- a/ext/-test-/proc/depend +++ b/ext/-test-/proc/depend @@ -2,6 +2,19 @@ init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ init.o: init.c receiver.o: $(RUBY_EXTCONF_H) receiver.o: $(arch_hdrdir)/ruby/config.h receiver.o: $(hdrdir)/ruby.h +receiver.o: $(hdrdir)/ruby/assert.h +receiver.o: $(hdrdir)/ruby/backward.h +receiver.o: $(hdrdir)/ruby/backward/2/assume.h +receiver.o: $(hdrdir)/ruby/backward/2/attributes.h +receiver.o: $(hdrdir)/ruby/backward/2/bool.h +receiver.o: $(hdrdir)/ruby/backward/2/inttypes.h +receiver.o: $(hdrdir)/ruby/backward/2/limits.h +receiver.o: $(hdrdir)/ruby/backward/2/long_long.h +receiver.o: $(hdrdir)/ruby/backward/2/stdalign.h +receiver.o: $(hdrdir)/ruby/backward/2/stdarg.h +receiver.o: $(hdrdir)/ruby/defines.h +receiver.o: $(hdrdir)/ruby/intern.h +receiver.o: $(hdrdir)/ruby/internal/abi.h receiver.o: $(hdrdir)/ruby/internal/anyargs.h receiver.o: $(hdrdir)/ruby/internal/arithmetic.h receiver.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ receiver.o: $(hdrdir)/ruby/internal/attr/noexcept.h receiver.o: $(hdrdir)/ruby/internal/attr/noinline.h receiver.o: $(hdrdir)/ruby/internal/attr/nonnull.h receiver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +receiver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h receiver.o: $(hdrdir)/ruby/internal/attr/pure.h receiver.o: $(hdrdir)/ruby/internal/attr/restrict.h receiver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ receiver.o: $(hdrdir)/ruby/internal/intern/enumerator.h receiver.o: $(hdrdir)/ruby/internal/intern/error.h receiver.o: $(hdrdir)/ruby/internal/intern/eval.h receiver.o: $(hdrdir)/ruby/internal/intern/file.h -receiver.o: $(hdrdir)/ruby/internal/intern/gc.h receiver.o: $(hdrdir)/ruby/internal/intern/hash.h receiver.o: $(hdrdir)/ruby/internal/intern/io.h receiver.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ receiver.o: $(hdrdir)/ruby/internal/intern/re.h receiver.o: $(hdrdir)/ruby/internal/intern/ruby.h receiver.o: $(hdrdir)/ruby/internal/intern/select.h receiver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +receiver.o: $(hdrdir)/ruby/internal/intern/set.h receiver.o: $(hdrdir)/ruby/internal/intern/signal.h receiver.o: $(hdrdir)/ruby/internal/intern/sprintf.h receiver.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ receiver.o: $(hdrdir)/ruby/internal/memory.h receiver.o: $(hdrdir)/ruby/internal/method.h receiver.o: $(hdrdir)/ruby/internal/module.h receiver.o: $(hdrdir)/ruby/internal/newobj.h -receiver.o: $(hdrdir)/ruby/internal/rgengc.h receiver.o: $(hdrdir)/ruby/internal/scan_args.h receiver.o: $(hdrdir)/ruby/internal/special_consts.h receiver.o: $(hdrdir)/ruby/internal/static_assert.h receiver.o: $(hdrdir)/ruby/internal/stdalign.h receiver.o: $(hdrdir)/ruby/internal/stdbool.h +receiver.o: $(hdrdir)/ruby/internal/stdckdint.h receiver.o: $(hdrdir)/ruby/internal/symbol.h receiver.o: $(hdrdir)/ruby/internal/value.h receiver.o: $(hdrdir)/ruby/internal/value_type.h receiver.o: $(hdrdir)/ruby/internal/variable.h receiver.o: $(hdrdir)/ruby/internal/warning_push.h receiver.o: $(hdrdir)/ruby/internal/xmalloc.h -receiver.o: $(hdrdir)/ruby/assert.h -receiver.o: $(hdrdir)/ruby/backward.h -receiver.o: $(hdrdir)/ruby/backward/2/assume.h -receiver.o: $(hdrdir)/ruby/backward/2/attributes.h -receiver.o: $(hdrdir)/ruby/backward/2/bool.h -receiver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -receiver.o: $(hdrdir)/ruby/backward/2/inttypes.h -receiver.o: $(hdrdir)/ruby/backward/2/limits.h -receiver.o: $(hdrdir)/ruby/backward/2/long_long.h -receiver.o: $(hdrdir)/ruby/backward/2/stdalign.h -receiver.o: $(hdrdir)/ruby/backward/2/stdarg.h -receiver.o: $(hdrdir)/ruby/defines.h -receiver.o: $(hdrdir)/ruby/intern.h receiver.o: $(hdrdir)/ruby/missing.h receiver.o: $(hdrdir)/ruby/ruby.h receiver.o: $(hdrdir)/ruby/st.h @@ -322,6 +324,19 @@ receiver.o: receiver.c super.o: $(RUBY_EXTCONF_H) super.o: $(arch_hdrdir)/ruby/config.h super.o: $(hdrdir)/ruby.h +super.o: $(hdrdir)/ruby/assert.h +super.o: $(hdrdir)/ruby/backward.h +super.o: $(hdrdir)/ruby/backward/2/assume.h +super.o: $(hdrdir)/ruby/backward/2/attributes.h +super.o: $(hdrdir)/ruby/backward/2/bool.h +super.o: $(hdrdir)/ruby/backward/2/inttypes.h +super.o: $(hdrdir)/ruby/backward/2/limits.h +super.o: $(hdrdir)/ruby/backward/2/long_long.h +super.o: $(hdrdir)/ruby/backward/2/stdalign.h +super.o: $(hdrdir)/ruby/backward/2/stdarg.h +super.o: $(hdrdir)/ruby/defines.h +super.o: $(hdrdir)/ruby/intern.h +super.o: $(hdrdir)/ruby/internal/abi.h super.o: $(hdrdir)/ruby/internal/anyargs.h super.o: $(hdrdir)/ruby/internal/arithmetic.h super.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -359,6 +374,7 @@ super.o: $(hdrdir)/ruby/internal/attr/noexcept.h super.o: $(hdrdir)/ruby/internal/attr/noinline.h super.o: $(hdrdir)/ruby/internal/attr/nonnull.h super.o: $(hdrdir)/ruby/internal/attr/noreturn.h +super.o: $(hdrdir)/ruby/internal/attr/packed_struct.h super.o: $(hdrdir)/ruby/internal/attr/pure.h super.o: $(hdrdir)/ruby/internal/attr/restrict.h super.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -418,7 +434,6 @@ super.o: $(hdrdir)/ruby/internal/intern/enumerator.h super.o: $(hdrdir)/ruby/internal/intern/error.h super.o: $(hdrdir)/ruby/internal/intern/eval.h super.o: $(hdrdir)/ruby/internal/intern/file.h -super.o: $(hdrdir)/ruby/internal/intern/gc.h super.o: $(hdrdir)/ruby/internal/intern/hash.h super.o: $(hdrdir)/ruby/internal/intern/io.h super.o: $(hdrdir)/ruby/internal/intern/load.h @@ -435,6 +450,7 @@ super.o: $(hdrdir)/ruby/internal/intern/re.h super.o: $(hdrdir)/ruby/internal/intern/ruby.h super.o: $(hdrdir)/ruby/internal/intern/select.h super.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +super.o: $(hdrdir)/ruby/internal/intern/set.h super.o: $(hdrdir)/ruby/internal/intern/signal.h super.o: $(hdrdir)/ruby/internal/intern/sprintf.h super.o: $(hdrdir)/ruby/internal/intern/string.h @@ -449,31 +465,18 @@ super.o: $(hdrdir)/ruby/internal/memory.h super.o: $(hdrdir)/ruby/internal/method.h super.o: $(hdrdir)/ruby/internal/module.h super.o: $(hdrdir)/ruby/internal/newobj.h -super.o: $(hdrdir)/ruby/internal/rgengc.h super.o: $(hdrdir)/ruby/internal/scan_args.h super.o: $(hdrdir)/ruby/internal/special_consts.h super.o: $(hdrdir)/ruby/internal/static_assert.h super.o: $(hdrdir)/ruby/internal/stdalign.h super.o: $(hdrdir)/ruby/internal/stdbool.h +super.o: $(hdrdir)/ruby/internal/stdckdint.h super.o: $(hdrdir)/ruby/internal/symbol.h super.o: $(hdrdir)/ruby/internal/value.h super.o: $(hdrdir)/ruby/internal/value_type.h super.o: $(hdrdir)/ruby/internal/variable.h super.o: $(hdrdir)/ruby/internal/warning_push.h super.o: $(hdrdir)/ruby/internal/xmalloc.h -super.o: $(hdrdir)/ruby/assert.h -super.o: $(hdrdir)/ruby/backward.h -super.o: $(hdrdir)/ruby/backward/2/assume.h -super.o: $(hdrdir)/ruby/backward/2/attributes.h -super.o: $(hdrdir)/ruby/backward/2/bool.h -super.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -super.o: $(hdrdir)/ruby/backward/2/inttypes.h -super.o: $(hdrdir)/ruby/backward/2/limits.h -super.o: $(hdrdir)/ruby/backward/2/long_long.h -super.o: $(hdrdir)/ruby/backward/2/stdalign.h -super.o: $(hdrdir)/ruby/backward/2/stdarg.h -super.o: $(hdrdir)/ruby/defines.h -super.o: $(hdrdir)/ruby/intern.h super.o: $(hdrdir)/ruby/missing.h super.o: $(hdrdir)/ruby/ruby.h super.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/proc/super.c b/ext/-test-/proc/super.c index dbe8af08f1..816520e1df 100644 --- a/ext/-test-/proc/super.c +++ b/ext/-test-/proc/super.c @@ -9,7 +9,7 @@ bug_proc_call_super(RB_BLOCK_CALL_FUNC_ARGLIST(yieldarg, procarg)) args[1] = procarg; ret = rb_call_super(2, args); if (!NIL_P(blockarg)) { - ret = rb_proc_call(blockarg, ret); + ret = rb_proc_call(blockarg, ret); } return ret; } diff --git a/ext/-test-/public_header_warnings/extconf.rb b/ext/-test-/public_header_warnings/extconf.rb new file mode 100644 index 0000000000..4431e09da4 --- /dev/null +++ b/ext/-test-/public_header_warnings/extconf.rb @@ -0,0 +1,28 @@ +# +# Under compilers with WERRORFLAG, MakeMakefile.try_compile treats warnings as errors, so we can +# use append_cflags to test whether the public header files emit warnings with certain flags turned +# on. +# +def check_append_cflags(flag, msg = nil) + msg ||= "flag #{flag} is not acceptable" + if $CFLAGS.include?(flag) + raise("flag #{flag} already present in $CFLAGS") + end + append_cflags(flag) + unless $CFLAGS.include?(flag) + system("cat mkmf.log") + raise(msg) + end +end + +if %w[gcc clang].include?(RbConfig::CONFIG['CC']) + config_string("WERRORFLAG") or raise("expected WERRORFLAG to be defined") + + # should be acceptable on all modern C compilers + check_append_cflags("-D_TEST_OK", "baseline compiler warning test failed") + + # Feature #20507: Allow compilation of C extensions with -Wconversion + check_append_cflags("-Wconversion", "-Wconversion raising warnings in public headers") +end + +create_makefile("-test-/public_header_warnings") diff --git a/ext/-test-/random/bad_version.c b/ext/-test-/random/bad_version.c new file mode 100644 index 0000000000..dae63a6d19 --- /dev/null +++ b/ext/-test-/random/bad_version.c @@ -0,0 +1,135 @@ +#include "ruby/random.h" + +#if RUBY_RANDOM_INTERFACE_VERSION_MAJOR < RUBY_RANDOM_INTERFACE_VERSION_MAJOR_MAX +# define DEFINE_VERSION_MAX 1 +#else +# define DEFINE_VERSION_MAX 0 +#endif + +NORETURN(static void must_not_reach(void)); +static void +must_not_reach(void) +{ + rb_raise(rb_eTypeError, "must not reach"); +} + +NORETURN(static void bad_version_init(rb_random_t *, const uint32_t *, size_t)); +static void +bad_version_init(rb_random_t *rnd, const uint32_t *buf, size_t len) +{ + must_not_reach(); +} + +NORETURN(static void bad_version_init_int32(rb_random_t *, uint32_t)); +RB_RANDOM_DEFINE_INIT_INT32_FUNC(bad_version) + +NORETURN(static void bad_version_get_bytes(rb_random_t *, void *, size_t)); +static void +bad_version_get_bytes(rb_random_t *rnd, void *p, size_t n) +{ + must_not_reach(); +} + +NORETURN(static uint32_t bad_version_get_int32(rb_random_t *)); +static uint32_t +bad_version_get_int32(rb_random_t *rnd) +{ + must_not_reach(); + UNREACHABLE_RETURN(0); +} + +static VALUE +bad_version_alloc(VALUE klass, const rb_data_type_t *type) +{ + rb_random_t *rnd; + VALUE obj = TypedData_Make_Struct(klass, rb_random_t, type, rnd); + rb_random_base_init(rnd); + return obj; +} + +/* version 0 */ +static const rb_random_interface_t random_version_zero_if; + +static rb_random_data_type_t version_zero_type = { + "random/version_zero", + { + rb_random_mark, + RUBY_TYPED_DEFAULT_FREE, + }, + RB_RANDOM_PARENT, + (void *)&random_version_zero_if, + RUBY_TYPED_FREE_IMMEDIATELY +}; + +static VALUE +version_zero_alloc(VALUE klass) +{ + return bad_version_alloc(klass, &version_zero_type); +} + +static void +init_version_zero(VALUE mod, VALUE base) +{ + VALUE c = rb_define_class_under(mod, "VersionZero", base); + rb_define_alloc_func(c, version_zero_alloc); + RB_RANDOM_DATA_INIT_PARENT(version_zero_type); +} + +#if DEFINE_VERSION_MAX +/* version max */ +static const rb_random_interface_t random_version_max_if; +static rb_random_data_type_t version_max_type = { + "random/version_max", + { + rb_random_mark, + RUBY_TYPED_DEFAULT_FREE, + }, + RB_RANDOM_PARENT, + (void *)&random_version_max_if, + RUBY_TYPED_FREE_IMMEDIATELY +}; + +static VALUE +version_max_alloc(VALUE klass) +{ + return bad_version_alloc(klass, &version_max_type); +} + +static void +init_version_max(VALUE mod, VALUE base) +{ + VALUE c = rb_define_class_under(mod, "VersionMax", base); + rb_define_alloc_func(c, version_max_alloc); + RB_RANDOM_DATA_INIT_PARENT(version_max_type); +} +#else +static void +init_version_max(mod, base) +{ +} +#endif + +void +Init_random_bad_version(VALUE mod, VALUE base) +{ + init_version_zero(mod, base); + init_version_max(mod, base); +} + +#undef RUBY_RANDOM_INTERFACE_VERSION_MAJOR + +#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR 0 +static const rb_random_interface_t random_version_zero_if = { + 0, + RB_RANDOM_INTERFACE_DEFINE(bad_version) +}; +#undef RUBY_RANDOM_INTERFACE_VERSION_MAJOR + +#if DEFINE_VERSION_MAX +#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR RUBY_RANDOM_INTERFACE_VERSION_MAJOR_MAX +static const rb_random_interface_t random_version_max_if = { + 0, + RB_RANDOM_INTERFACE_DEFINE(bad_version) +}; +#undef RUBY_RANDOM_INTERFACE_VERSION_MAJOR +#endif diff --git a/ext/-test-/random/depend b/ext/-test-/random/depend index 799b563075..380c30fbe4 100644 --- a/ext/-test-/random/depend +++ b/ext/-test-/random/depend @@ -1,4 +1,165 @@ # AUTOGENERATED DEPENDENCIES START +bad_version.o: $(RUBY_EXTCONF_H) +bad_version.o: $(arch_hdrdir)/ruby/config.h +bad_version.o: $(hdrdir)/ruby/assert.h +bad_version.o: $(hdrdir)/ruby/backward.h +bad_version.o: $(hdrdir)/ruby/backward/2/assume.h +bad_version.o: $(hdrdir)/ruby/backward/2/attributes.h +bad_version.o: $(hdrdir)/ruby/backward/2/bool.h +bad_version.o: $(hdrdir)/ruby/backward/2/inttypes.h +bad_version.o: $(hdrdir)/ruby/backward/2/limits.h +bad_version.o: $(hdrdir)/ruby/backward/2/long_long.h +bad_version.o: $(hdrdir)/ruby/backward/2/stdalign.h +bad_version.o: $(hdrdir)/ruby/backward/2/stdarg.h +bad_version.o: $(hdrdir)/ruby/defines.h +bad_version.o: $(hdrdir)/ruby/intern.h +bad_version.o: $(hdrdir)/ruby/internal/abi.h +bad_version.o: $(hdrdir)/ruby/internal/anyargs.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/char.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/double.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/int.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/long.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/short.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +bad_version.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +bad_version.o: $(hdrdir)/ruby/internal/assume.h +bad_version.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +bad_version.o: $(hdrdir)/ruby/internal/attr/artificial.h +bad_version.o: $(hdrdir)/ruby/internal/attr/cold.h +bad_version.o: $(hdrdir)/ruby/internal/attr/const.h +bad_version.o: $(hdrdir)/ruby/internal/attr/constexpr.h +bad_version.o: $(hdrdir)/ruby/internal/attr/deprecated.h +bad_version.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +bad_version.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +bad_version.o: $(hdrdir)/ruby/internal/attr/error.h +bad_version.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +bad_version.o: $(hdrdir)/ruby/internal/attr/forceinline.h +bad_version.o: $(hdrdir)/ruby/internal/attr/format.h +bad_version.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +bad_version.o: $(hdrdir)/ruby/internal/attr/noalias.h +bad_version.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +bad_version.o: $(hdrdir)/ruby/internal/attr/noexcept.h +bad_version.o: $(hdrdir)/ruby/internal/attr/noinline.h +bad_version.o: $(hdrdir)/ruby/internal/attr/nonnull.h +bad_version.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bad_version.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +bad_version.o: $(hdrdir)/ruby/internal/attr/pure.h +bad_version.o: $(hdrdir)/ruby/internal/attr/restrict.h +bad_version.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +bad_version.o: $(hdrdir)/ruby/internal/attr/warning.h +bad_version.o: $(hdrdir)/ruby/internal/attr/weakref.h +bad_version.o: $(hdrdir)/ruby/internal/cast.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +bad_version.o: $(hdrdir)/ruby/internal/compiler_since.h +bad_version.o: $(hdrdir)/ruby/internal/config.h +bad_version.o: $(hdrdir)/ruby/internal/constant_p.h +bad_version.o: $(hdrdir)/ruby/internal/core.h +bad_version.o: $(hdrdir)/ruby/internal/core/rarray.h +bad_version.o: $(hdrdir)/ruby/internal/core/rbasic.h +bad_version.o: $(hdrdir)/ruby/internal/core/rbignum.h +bad_version.o: $(hdrdir)/ruby/internal/core/rclass.h +bad_version.o: $(hdrdir)/ruby/internal/core/rdata.h +bad_version.o: $(hdrdir)/ruby/internal/core/rfile.h +bad_version.o: $(hdrdir)/ruby/internal/core/rhash.h +bad_version.o: $(hdrdir)/ruby/internal/core/robject.h +bad_version.o: $(hdrdir)/ruby/internal/core/rregexp.h +bad_version.o: $(hdrdir)/ruby/internal/core/rstring.h +bad_version.o: $(hdrdir)/ruby/internal/core/rstruct.h +bad_version.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +bad_version.o: $(hdrdir)/ruby/internal/ctype.h +bad_version.o: $(hdrdir)/ruby/internal/dllexport.h +bad_version.o: $(hdrdir)/ruby/internal/dosish.h +bad_version.o: $(hdrdir)/ruby/internal/error.h +bad_version.o: $(hdrdir)/ruby/internal/eval.h +bad_version.o: $(hdrdir)/ruby/internal/event.h +bad_version.o: $(hdrdir)/ruby/internal/fl_type.h +bad_version.o: $(hdrdir)/ruby/internal/gc.h +bad_version.o: $(hdrdir)/ruby/internal/glob.h +bad_version.o: $(hdrdir)/ruby/internal/globals.h +bad_version.o: $(hdrdir)/ruby/internal/has/attribute.h +bad_version.o: $(hdrdir)/ruby/internal/has/builtin.h +bad_version.o: $(hdrdir)/ruby/internal/has/c_attribute.h +bad_version.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +bad_version.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +bad_version.o: $(hdrdir)/ruby/internal/has/extension.h +bad_version.o: $(hdrdir)/ruby/internal/has/feature.h +bad_version.o: $(hdrdir)/ruby/internal/has/warning.h +bad_version.o: $(hdrdir)/ruby/internal/intern/array.h +bad_version.o: $(hdrdir)/ruby/internal/intern/bignum.h +bad_version.o: $(hdrdir)/ruby/internal/intern/class.h +bad_version.o: $(hdrdir)/ruby/internal/intern/compar.h +bad_version.o: $(hdrdir)/ruby/internal/intern/complex.h +bad_version.o: $(hdrdir)/ruby/internal/intern/cont.h +bad_version.o: $(hdrdir)/ruby/internal/intern/dir.h +bad_version.o: $(hdrdir)/ruby/internal/intern/enum.h +bad_version.o: $(hdrdir)/ruby/internal/intern/enumerator.h +bad_version.o: $(hdrdir)/ruby/internal/intern/error.h +bad_version.o: $(hdrdir)/ruby/internal/intern/eval.h +bad_version.o: $(hdrdir)/ruby/internal/intern/file.h +bad_version.o: $(hdrdir)/ruby/internal/intern/hash.h +bad_version.o: $(hdrdir)/ruby/internal/intern/io.h +bad_version.o: $(hdrdir)/ruby/internal/intern/load.h +bad_version.o: $(hdrdir)/ruby/internal/intern/marshal.h +bad_version.o: $(hdrdir)/ruby/internal/intern/numeric.h +bad_version.o: $(hdrdir)/ruby/internal/intern/object.h +bad_version.o: $(hdrdir)/ruby/internal/intern/parse.h +bad_version.o: $(hdrdir)/ruby/internal/intern/proc.h +bad_version.o: $(hdrdir)/ruby/internal/intern/process.h +bad_version.o: $(hdrdir)/ruby/internal/intern/random.h +bad_version.o: $(hdrdir)/ruby/internal/intern/range.h +bad_version.o: $(hdrdir)/ruby/internal/intern/rational.h +bad_version.o: $(hdrdir)/ruby/internal/intern/re.h +bad_version.o: $(hdrdir)/ruby/internal/intern/ruby.h +bad_version.o: $(hdrdir)/ruby/internal/intern/select.h +bad_version.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bad_version.o: $(hdrdir)/ruby/internal/intern/set.h +bad_version.o: $(hdrdir)/ruby/internal/intern/signal.h +bad_version.o: $(hdrdir)/ruby/internal/intern/sprintf.h +bad_version.o: $(hdrdir)/ruby/internal/intern/string.h +bad_version.o: $(hdrdir)/ruby/internal/intern/struct.h +bad_version.o: $(hdrdir)/ruby/internal/intern/thread.h +bad_version.o: $(hdrdir)/ruby/internal/intern/time.h +bad_version.o: $(hdrdir)/ruby/internal/intern/variable.h +bad_version.o: $(hdrdir)/ruby/internal/intern/vm.h +bad_version.o: $(hdrdir)/ruby/internal/interpreter.h +bad_version.o: $(hdrdir)/ruby/internal/iterator.h +bad_version.o: $(hdrdir)/ruby/internal/memory.h +bad_version.o: $(hdrdir)/ruby/internal/method.h +bad_version.o: $(hdrdir)/ruby/internal/module.h +bad_version.o: $(hdrdir)/ruby/internal/newobj.h +bad_version.o: $(hdrdir)/ruby/internal/scan_args.h +bad_version.o: $(hdrdir)/ruby/internal/special_consts.h +bad_version.o: $(hdrdir)/ruby/internal/static_assert.h +bad_version.o: $(hdrdir)/ruby/internal/stdalign.h +bad_version.o: $(hdrdir)/ruby/internal/stdbool.h +bad_version.o: $(hdrdir)/ruby/internal/stdckdint.h +bad_version.o: $(hdrdir)/ruby/internal/symbol.h +bad_version.o: $(hdrdir)/ruby/internal/value.h +bad_version.o: $(hdrdir)/ruby/internal/value_type.h +bad_version.o: $(hdrdir)/ruby/internal/variable.h +bad_version.o: $(hdrdir)/ruby/internal/warning_push.h +bad_version.o: $(hdrdir)/ruby/internal/xmalloc.h +bad_version.o: $(hdrdir)/ruby/missing.h +bad_version.o: $(hdrdir)/ruby/random.h +bad_version.o: $(hdrdir)/ruby/ruby.h +bad_version.o: $(hdrdir)/ruby/st.h +bad_version.o: $(hdrdir)/ruby/subst.h +bad_version.o: bad_version.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h @@ -7,16 +168,14 @@ init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h init.o: $(hdrdir)/ruby/backward/2/inttypes.h init.o: $(hdrdir)/ruby/backward/2/limits.h init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/r_cast.h -init.o: $(hdrdir)/ruby/backward/2/rmodule.h init.o: $(hdrdir)/ruby/backward/2/stdalign.h init.o: $(hdrdir)/ruby/backward/2/stdarg.h init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -54,6 +213,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -113,7 +273,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -130,6 +289,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -144,12 +304,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h @@ -168,16 +328,14 @@ loop.o: $(hdrdir)/ruby/backward.h loop.o: $(hdrdir)/ruby/backward/2/assume.h loop.o: $(hdrdir)/ruby/backward/2/attributes.h loop.o: $(hdrdir)/ruby/backward/2/bool.h -loop.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h loop.o: $(hdrdir)/ruby/backward/2/inttypes.h loop.o: $(hdrdir)/ruby/backward/2/limits.h loop.o: $(hdrdir)/ruby/backward/2/long_long.h -loop.o: $(hdrdir)/ruby/backward/2/r_cast.h -loop.o: $(hdrdir)/ruby/backward/2/rmodule.h loop.o: $(hdrdir)/ruby/backward/2/stdalign.h loop.o: $(hdrdir)/ruby/backward/2/stdarg.h loop.o: $(hdrdir)/ruby/defines.h loop.o: $(hdrdir)/ruby/intern.h +loop.o: $(hdrdir)/ruby/internal/abi.h loop.o: $(hdrdir)/ruby/internal/anyargs.h loop.o: $(hdrdir)/ruby/internal/arithmetic.h loop.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -215,6 +373,7 @@ loop.o: $(hdrdir)/ruby/internal/attr/noexcept.h loop.o: $(hdrdir)/ruby/internal/attr/noinline.h loop.o: $(hdrdir)/ruby/internal/attr/nonnull.h loop.o: $(hdrdir)/ruby/internal/attr/noreturn.h +loop.o: $(hdrdir)/ruby/internal/attr/packed_struct.h loop.o: $(hdrdir)/ruby/internal/attr/pure.h loop.o: $(hdrdir)/ruby/internal/attr/restrict.h loop.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -274,7 +433,6 @@ loop.o: $(hdrdir)/ruby/internal/intern/enumerator.h loop.o: $(hdrdir)/ruby/internal/intern/error.h loop.o: $(hdrdir)/ruby/internal/intern/eval.h loop.o: $(hdrdir)/ruby/internal/intern/file.h -loop.o: $(hdrdir)/ruby/internal/intern/gc.h loop.o: $(hdrdir)/ruby/internal/intern/hash.h loop.o: $(hdrdir)/ruby/internal/intern/io.h loop.o: $(hdrdir)/ruby/internal/intern/load.h @@ -291,6 +449,7 @@ loop.o: $(hdrdir)/ruby/internal/intern/re.h loop.o: $(hdrdir)/ruby/internal/intern/ruby.h loop.o: $(hdrdir)/ruby/internal/intern/select.h loop.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +loop.o: $(hdrdir)/ruby/internal/intern/set.h loop.o: $(hdrdir)/ruby/internal/intern/signal.h loop.o: $(hdrdir)/ruby/internal/intern/sprintf.h loop.o: $(hdrdir)/ruby/internal/intern/string.h @@ -305,12 +464,12 @@ loop.o: $(hdrdir)/ruby/internal/memory.h loop.o: $(hdrdir)/ruby/internal/method.h loop.o: $(hdrdir)/ruby/internal/module.h loop.o: $(hdrdir)/ruby/internal/newobj.h -loop.o: $(hdrdir)/ruby/internal/rgengc.h loop.o: $(hdrdir)/ruby/internal/scan_args.h loop.o: $(hdrdir)/ruby/internal/special_consts.h loop.o: $(hdrdir)/ruby/internal/static_assert.h loop.o: $(hdrdir)/ruby/internal/stdalign.h loop.o: $(hdrdir)/ruby/internal/stdbool.h +loop.o: $(hdrdir)/ruby/internal/stdckdint.h loop.o: $(hdrdir)/ruby/internal/symbol.h loop.o: $(hdrdir)/ruby/internal/value.h loop.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/random/loop.c b/ext/-test-/random/loop.c index 0572096403..f79e5cfd83 100644 --- a/ext/-test-/random/loop.c +++ b/ext/-test-/random/loop.c @@ -13,6 +13,16 @@ static const rb_random_interface_t random_loop_if = { RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(loop) }; +static void +loop_free(void *ptr) +{ + rand_loop_t *r = ptr; + + xfree(r->buf); + xfree(r); +} + +RB_RANDOM_DEFINE_INIT_INT32_FUNC(loop) static size_t random_loop_memsize(const void *ptr) { @@ -24,7 +34,7 @@ static rb_random_data_type_t random_loop_type = { "random/loop", { rb_random_mark, - RUBY_TYPED_DEFAULT_FREE, + loop_free, random_loop_memsize, }, RB_RANDOM_PARENT, diff --git a/ext/-test-/rational/depend b/ext/-test-/rational/depend index 67ac3c6f90..56d6ab77d6 100644 --- a/ext/-test-/rational/depend +++ b/ext/-test-/rational/depend @@ -5,7 +5,20 @@ rat.o: rat.c $(top_srcdir)/internal.h # AUTOGENERATED DEPENDENCIES START rat.o: $(RUBY_EXTCONF_H) rat.o: $(arch_hdrdir)/ruby/config.h -rat.o: $(hdrdir)/ruby.h +rat.o: $(hdrdir)/ruby/assert.h +rat.o: $(hdrdir)/ruby/backward.h +rat.o: $(hdrdir)/ruby/backward/2/assume.h +rat.o: $(hdrdir)/ruby/backward/2/attributes.h +rat.o: $(hdrdir)/ruby/backward/2/bool.h +rat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +rat.o: $(hdrdir)/ruby/backward/2/inttypes.h +rat.o: $(hdrdir)/ruby/backward/2/limits.h +rat.o: $(hdrdir)/ruby/backward/2/long_long.h +rat.o: $(hdrdir)/ruby/backward/2/stdalign.h +rat.o: $(hdrdir)/ruby/backward/2/stdarg.h +rat.o: $(hdrdir)/ruby/defines.h +rat.o: $(hdrdir)/ruby/intern.h +rat.o: $(hdrdir)/ruby/internal/abi.h rat.o: $(hdrdir)/ruby/internal/anyargs.h rat.o: $(hdrdir)/ruby/internal/arithmetic.h rat.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -43,6 +56,7 @@ rat.o: $(hdrdir)/ruby/internal/attr/noexcept.h rat.o: $(hdrdir)/ruby/internal/attr/noinline.h rat.o: $(hdrdir)/ruby/internal/attr/nonnull.h rat.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rat.o: $(hdrdir)/ruby/internal/attr/pure.h rat.o: $(hdrdir)/ruby/internal/attr/restrict.h rat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -102,7 +116,6 @@ rat.o: $(hdrdir)/ruby/internal/intern/enumerator.h rat.o: $(hdrdir)/ruby/internal/intern/error.h rat.o: $(hdrdir)/ruby/internal/intern/eval.h rat.o: $(hdrdir)/ruby/internal/intern/file.h -rat.o: $(hdrdir)/ruby/internal/intern/gc.h rat.o: $(hdrdir)/ruby/internal/intern/hash.h rat.o: $(hdrdir)/ruby/internal/intern/io.h rat.o: $(hdrdir)/ruby/internal/intern/load.h @@ -119,6 +132,7 @@ rat.o: $(hdrdir)/ruby/internal/intern/re.h rat.o: $(hdrdir)/ruby/internal/intern/ruby.h rat.o: $(hdrdir)/ruby/internal/intern/select.h rat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rat.o: $(hdrdir)/ruby/internal/intern/set.h rat.o: $(hdrdir)/ruby/internal/intern/signal.h rat.o: $(hdrdir)/ruby/internal/intern/sprintf.h rat.o: $(hdrdir)/ruby/internal/intern/string.h @@ -133,36 +147,22 @@ rat.o: $(hdrdir)/ruby/internal/memory.h rat.o: $(hdrdir)/ruby/internal/method.h rat.o: $(hdrdir)/ruby/internal/module.h rat.o: $(hdrdir)/ruby/internal/newobj.h -rat.o: $(hdrdir)/ruby/internal/rgengc.h rat.o: $(hdrdir)/ruby/internal/scan_args.h rat.o: $(hdrdir)/ruby/internal/special_consts.h rat.o: $(hdrdir)/ruby/internal/static_assert.h rat.o: $(hdrdir)/ruby/internal/stdalign.h rat.o: $(hdrdir)/ruby/internal/stdbool.h +rat.o: $(hdrdir)/ruby/internal/stdckdint.h rat.o: $(hdrdir)/ruby/internal/symbol.h rat.o: $(hdrdir)/ruby/internal/value.h rat.o: $(hdrdir)/ruby/internal/value_type.h rat.o: $(hdrdir)/ruby/internal/variable.h rat.o: $(hdrdir)/ruby/internal/warning_push.h rat.o: $(hdrdir)/ruby/internal/xmalloc.h -rat.o: $(hdrdir)/ruby/assert.h -rat.o: $(hdrdir)/ruby/backward.h -rat.o: $(hdrdir)/ruby/backward/2/assume.h -rat.o: $(hdrdir)/ruby/backward/2/attributes.h -rat.o: $(hdrdir)/ruby/backward/2/bool.h -rat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -rat.o: $(hdrdir)/ruby/backward/2/inttypes.h -rat.o: $(hdrdir)/ruby/backward/2/limits.h -rat.o: $(hdrdir)/ruby/backward/2/long_long.h -rat.o: $(hdrdir)/ruby/backward/2/stdalign.h -rat.o: $(hdrdir)/ruby/backward/2/stdarg.h -rat.o: $(hdrdir)/ruby/defines.h -rat.o: $(hdrdir)/ruby/intern.h rat.o: $(hdrdir)/ruby/missing.h rat.o: $(hdrdir)/ruby/ruby.h rat.o: $(hdrdir)/ruby/st.h rat.o: $(hdrdir)/ruby/subst.h -rat.o: $(top_srcdir)/internal.h rat.o: $(top_srcdir)/internal/bignum.h rat.o: $(top_srcdir)/internal/bits.h rat.o: $(top_srcdir)/internal/compilers.h @@ -175,5 +175,6 @@ rat.o: $(top_srcdir)/internal/static_assert.h rat.o: $(top_srcdir)/internal/vm.h rat.o: $(top_srcdir)/internal/warnings.h rat.o: $(top_srcdir)/ruby_assert.h +rat.o: $(top_srcdir)/shape.h rat.o: rat.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/rb_call_super_kw/depend b/ext/-test-/rb_call_super_kw/depend index 25725f9a9a..bf34323ca7 100644 --- a/ext/-test-/rb_call_super_kw/depend +++ b/ext/-test-/rb_call_super_kw/depend @@ -2,6 +2,19 @@ rb_call_super_kw.o: $(RUBY_EXTCONF_H) rb_call_super_kw.o: $(arch_hdrdir)/ruby/config.h rb_call_super_kw.o: $(hdrdir)/ruby.h +rb_call_super_kw.o: $(hdrdir)/ruby/assert.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/assume.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/attributes.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/bool.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/limits.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/long_long.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h +rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h +rb_call_super_kw.o: $(hdrdir)/ruby/defines.h +rb_call_super_kw.o: $(hdrdir)/ruby/intern.h +rb_call_super_kw.o: $(hdrdir)/ruby/internal/abi.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/anyargs.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noexcept.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noinline.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/nonnull.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/pure.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/restrict.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/enumerator.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/error.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/eval.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/file.h -rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/gc.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/hash.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/io.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/re.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/ruby.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/select.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/set.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/signal.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/sprintf.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ rb_call_super_kw.o: $(hdrdir)/ruby/internal/memory.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/method.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/module.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/newobj.h -rb_call_super_kw.o: $(hdrdir)/ruby/internal/rgengc.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/scan_args.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/special_consts.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/static_assert.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/stdalign.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/stdbool.h +rb_call_super_kw.o: $(hdrdir)/ruby/internal/stdckdint.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/symbol.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/value.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/value_type.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/variable.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/warning_push.h rb_call_super_kw.o: $(hdrdir)/ruby/internal/xmalloc.h -rb_call_super_kw.o: $(hdrdir)/ruby/assert.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/assume.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/attributes.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/bool.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/inttypes.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/limits.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/long_long.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdalign.h -rb_call_super_kw.o: $(hdrdir)/ruby/backward/2/stdarg.h -rb_call_super_kw.o: $(hdrdir)/ruby/defines.h -rb_call_super_kw.o: $(hdrdir)/ruby/intern.h rb_call_super_kw.o: $(hdrdir)/ruby/missing.h rb_call_super_kw.o: $(hdrdir)/ruby/ruby.h rb_call_super_kw.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/rb_call_super_kw/rb_call_super_kw.c b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c index 7f094545d2..61681ed733 100644 --- a/ext/-test-/rb_call_super_kw/rb_call_super_kw.c +++ b/ext/-test-/rb_call_super_kw/rb_call_super_kw.c @@ -7,7 +7,8 @@ rb_call_super_kw_m(int argc, VALUE *argv, VALUE self) } void -Init_rb_call_super_kw(void) { +Init_rb_call_super_kw(void) +{ VALUE module = rb_define_module("Bug"); module = rb_define_module_under(module, "RbCallSuperKw"); rb_define_method(module, "m", rb_call_super_kw_m, -1); diff --git a/ext/-test-/recursion/depend b/ext/-test-/recursion/depend index 14bfbfca4e..b6487eb4df 100644 --- a/ext/-test-/recursion/depend +++ b/ext/-test-/recursion/depend @@ -2,6 +2,19 @@ recursion.o: $(RUBY_EXTCONF_H) recursion.o: $(arch_hdrdir)/ruby/config.h recursion.o: $(hdrdir)/ruby.h +recursion.o: $(hdrdir)/ruby/assert.h +recursion.o: $(hdrdir)/ruby/backward.h +recursion.o: $(hdrdir)/ruby/backward/2/assume.h +recursion.o: $(hdrdir)/ruby/backward/2/attributes.h +recursion.o: $(hdrdir)/ruby/backward/2/bool.h +recursion.o: $(hdrdir)/ruby/backward/2/inttypes.h +recursion.o: $(hdrdir)/ruby/backward/2/limits.h +recursion.o: $(hdrdir)/ruby/backward/2/long_long.h +recursion.o: $(hdrdir)/ruby/backward/2/stdalign.h +recursion.o: $(hdrdir)/ruby/backward/2/stdarg.h +recursion.o: $(hdrdir)/ruby/defines.h +recursion.o: $(hdrdir)/ruby/intern.h +recursion.o: $(hdrdir)/ruby/internal/abi.h recursion.o: $(hdrdir)/ruby/internal/anyargs.h recursion.o: $(hdrdir)/ruby/internal/arithmetic.h recursion.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ recursion.o: $(hdrdir)/ruby/internal/attr/noexcept.h recursion.o: $(hdrdir)/ruby/internal/attr/noinline.h recursion.o: $(hdrdir)/ruby/internal/attr/nonnull.h recursion.o: $(hdrdir)/ruby/internal/attr/noreturn.h +recursion.o: $(hdrdir)/ruby/internal/attr/packed_struct.h recursion.o: $(hdrdir)/ruby/internal/attr/pure.h recursion.o: $(hdrdir)/ruby/internal/attr/restrict.h recursion.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ recursion.o: $(hdrdir)/ruby/internal/intern/enumerator.h recursion.o: $(hdrdir)/ruby/internal/intern/error.h recursion.o: $(hdrdir)/ruby/internal/intern/eval.h recursion.o: $(hdrdir)/ruby/internal/intern/file.h -recursion.o: $(hdrdir)/ruby/internal/intern/gc.h recursion.o: $(hdrdir)/ruby/internal/intern/hash.h recursion.o: $(hdrdir)/ruby/internal/intern/io.h recursion.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ recursion.o: $(hdrdir)/ruby/internal/intern/re.h recursion.o: $(hdrdir)/ruby/internal/intern/ruby.h recursion.o: $(hdrdir)/ruby/internal/intern/select.h recursion.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +recursion.o: $(hdrdir)/ruby/internal/intern/set.h recursion.o: $(hdrdir)/ruby/internal/intern/signal.h recursion.o: $(hdrdir)/ruby/internal/intern/sprintf.h recursion.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ recursion.o: $(hdrdir)/ruby/internal/memory.h recursion.o: $(hdrdir)/ruby/internal/method.h recursion.o: $(hdrdir)/ruby/internal/module.h recursion.o: $(hdrdir)/ruby/internal/newobj.h -recursion.o: $(hdrdir)/ruby/internal/rgengc.h recursion.o: $(hdrdir)/ruby/internal/scan_args.h recursion.o: $(hdrdir)/ruby/internal/special_consts.h recursion.o: $(hdrdir)/ruby/internal/static_assert.h recursion.o: $(hdrdir)/ruby/internal/stdalign.h recursion.o: $(hdrdir)/ruby/internal/stdbool.h +recursion.o: $(hdrdir)/ruby/internal/stdckdint.h recursion.o: $(hdrdir)/ruby/internal/symbol.h recursion.o: $(hdrdir)/ruby/internal/value.h recursion.o: $(hdrdir)/ruby/internal/value_type.h recursion.o: $(hdrdir)/ruby/internal/variable.h recursion.o: $(hdrdir)/ruby/internal/warning_push.h recursion.o: $(hdrdir)/ruby/internal/xmalloc.h -recursion.o: $(hdrdir)/ruby/assert.h -recursion.o: $(hdrdir)/ruby/backward.h -recursion.o: $(hdrdir)/ruby/backward/2/assume.h -recursion.o: $(hdrdir)/ruby/backward/2/attributes.h -recursion.o: $(hdrdir)/ruby/backward/2/bool.h -recursion.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -recursion.o: $(hdrdir)/ruby/backward/2/inttypes.h -recursion.o: $(hdrdir)/ruby/backward/2/limits.h -recursion.o: $(hdrdir)/ruby/backward/2/long_long.h -recursion.o: $(hdrdir)/ruby/backward/2/stdalign.h -recursion.o: $(hdrdir)/ruby/backward/2/stdarg.h -recursion.o: $(hdrdir)/ruby/defines.h -recursion.o: $(hdrdir)/ruby/intern.h recursion.o: $(hdrdir)/ruby/missing.h recursion.o: $(hdrdir)/ruby/ruby.h recursion.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/regexp/depend b/ext/-test-/regexp/depend index 1e2b225316..5ba1b92f18 100644 --- a/ext/-test-/regexp/depend +++ b/ext/-test-/regexp/depend @@ -2,6 +2,19 @@ init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ init.o: init.c parse_depth_limit.o: $(RUBY_EXTCONF_H) parse_depth_limit.o: $(arch_hdrdir)/ruby/config.h parse_depth_limit.o: $(hdrdir)/ruby.h +parse_depth_limit.o: $(hdrdir)/ruby/assert.h +parse_depth_limit.o: $(hdrdir)/ruby/backward.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/assume.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/attributes.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/bool.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/inttypes.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/limits.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/long_long.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdalign.h +parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdarg.h +parse_depth_limit.o: $(hdrdir)/ruby/defines.h +parse_depth_limit.o: $(hdrdir)/ruby/intern.h +parse_depth_limit.o: $(hdrdir)/ruby/internal/abi.h parse_depth_limit.o: $(hdrdir)/ruby/internal/anyargs.h parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic.h parse_depth_limit.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noexcept.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noinline.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/nonnull.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/noreturn.h +parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/packed_struct.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/pure.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/restrict.h parse_depth_limit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/enumerator.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/error.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/eval.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/file.h -parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/gc.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/hash.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/io.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/re.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/ruby.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/select.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/set.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/signal.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/sprintf.h parse_depth_limit.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ parse_depth_limit.o: $(hdrdir)/ruby/internal/memory.h parse_depth_limit.o: $(hdrdir)/ruby/internal/method.h parse_depth_limit.o: $(hdrdir)/ruby/internal/module.h parse_depth_limit.o: $(hdrdir)/ruby/internal/newobj.h -parse_depth_limit.o: $(hdrdir)/ruby/internal/rgengc.h parse_depth_limit.o: $(hdrdir)/ruby/internal/scan_args.h parse_depth_limit.o: $(hdrdir)/ruby/internal/special_consts.h parse_depth_limit.o: $(hdrdir)/ruby/internal/static_assert.h parse_depth_limit.o: $(hdrdir)/ruby/internal/stdalign.h parse_depth_limit.o: $(hdrdir)/ruby/internal/stdbool.h +parse_depth_limit.o: $(hdrdir)/ruby/internal/stdckdint.h parse_depth_limit.o: $(hdrdir)/ruby/internal/symbol.h parse_depth_limit.o: $(hdrdir)/ruby/internal/value.h parse_depth_limit.o: $(hdrdir)/ruby/internal/value_type.h parse_depth_limit.o: $(hdrdir)/ruby/internal/variable.h parse_depth_limit.o: $(hdrdir)/ruby/internal/warning_push.h parse_depth_limit.o: $(hdrdir)/ruby/internal/xmalloc.h -parse_depth_limit.o: $(hdrdir)/ruby/assert.h -parse_depth_limit.o: $(hdrdir)/ruby/backward.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/assume.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/attributes.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/bool.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/inttypes.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/limits.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/long_long.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdalign.h -parse_depth_limit.o: $(hdrdir)/ruby/backward/2/stdarg.h -parse_depth_limit.o: $(hdrdir)/ruby/defines.h -parse_depth_limit.o: $(hdrdir)/ruby/intern.h parse_depth_limit.o: $(hdrdir)/ruby/missing.h parse_depth_limit.o: $(hdrdir)/ruby/onigmo.h parse_depth_limit.o: $(hdrdir)/ruby/ruby.h diff --git a/ext/-test-/sanitizers/depend b/ext/-test-/sanitizers/depend new file mode 100644 index 0000000000..0e6e632803 --- /dev/null +++ b/ext/-test-/sanitizers/depend @@ -0,0 +1,162 @@ +# AUTOGENERATED DEPENDENCIES START +sanitizers.o: $(RUBY_EXTCONF_H) +sanitizers.o: $(arch_hdrdir)/ruby/config.h +sanitizers.o: $(hdrdir)/ruby/assert.h +sanitizers.o: $(hdrdir)/ruby/backward.h +sanitizers.o: $(hdrdir)/ruby/backward/2/assume.h +sanitizers.o: $(hdrdir)/ruby/backward/2/attributes.h +sanitizers.o: $(hdrdir)/ruby/backward/2/bool.h +sanitizers.o: $(hdrdir)/ruby/backward/2/inttypes.h +sanitizers.o: $(hdrdir)/ruby/backward/2/limits.h +sanitizers.o: $(hdrdir)/ruby/backward/2/long_long.h +sanitizers.o: $(hdrdir)/ruby/backward/2/stdalign.h +sanitizers.o: $(hdrdir)/ruby/backward/2/stdarg.h +sanitizers.o: $(hdrdir)/ruby/defines.h +sanitizers.o: $(hdrdir)/ruby/intern.h +sanitizers.o: $(hdrdir)/ruby/internal/abi.h +sanitizers.o: $(hdrdir)/ruby/internal/anyargs.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/char.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/double.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/int.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/long.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/short.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +sanitizers.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +sanitizers.o: $(hdrdir)/ruby/internal/assume.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/artificial.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/cold.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/const.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/constexpr.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/deprecated.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/error.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/forceinline.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/format.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/noalias.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/noexcept.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/noinline.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/nonnull.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/pure.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/restrict.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/warning.h +sanitizers.o: $(hdrdir)/ruby/internal/attr/weakref.h +sanitizers.o: $(hdrdir)/ruby/internal/cast.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +sanitizers.o: $(hdrdir)/ruby/internal/compiler_since.h +sanitizers.o: $(hdrdir)/ruby/internal/config.h +sanitizers.o: $(hdrdir)/ruby/internal/constant_p.h +sanitizers.o: $(hdrdir)/ruby/internal/core.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rarray.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rbasic.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rbignum.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rclass.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rdata.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rfile.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rhash.h +sanitizers.o: $(hdrdir)/ruby/internal/core/robject.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rregexp.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rstring.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rstruct.h +sanitizers.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +sanitizers.o: $(hdrdir)/ruby/internal/ctype.h +sanitizers.o: $(hdrdir)/ruby/internal/dllexport.h +sanitizers.o: $(hdrdir)/ruby/internal/dosish.h +sanitizers.o: $(hdrdir)/ruby/internal/error.h +sanitizers.o: $(hdrdir)/ruby/internal/eval.h +sanitizers.o: $(hdrdir)/ruby/internal/event.h +sanitizers.o: $(hdrdir)/ruby/internal/fl_type.h +sanitizers.o: $(hdrdir)/ruby/internal/gc.h +sanitizers.o: $(hdrdir)/ruby/internal/glob.h +sanitizers.o: $(hdrdir)/ruby/internal/globals.h +sanitizers.o: $(hdrdir)/ruby/internal/has/attribute.h +sanitizers.o: $(hdrdir)/ruby/internal/has/builtin.h +sanitizers.o: $(hdrdir)/ruby/internal/has/c_attribute.h +sanitizers.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +sanitizers.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +sanitizers.o: $(hdrdir)/ruby/internal/has/extension.h +sanitizers.o: $(hdrdir)/ruby/internal/has/feature.h +sanitizers.o: $(hdrdir)/ruby/internal/has/warning.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/array.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/bignum.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/class.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/compar.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/complex.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/cont.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/dir.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/enum.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/enumerator.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/error.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/eval.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/file.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/hash.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/io.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/load.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/marshal.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/numeric.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/object.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/parse.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/proc.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/process.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/random.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/range.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/rational.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/re.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/ruby.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/select.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/set.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/signal.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/sprintf.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/string.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/struct.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/thread.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/time.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/variable.h +sanitizers.o: $(hdrdir)/ruby/internal/intern/vm.h +sanitizers.o: $(hdrdir)/ruby/internal/interpreter.h +sanitizers.o: $(hdrdir)/ruby/internal/iterator.h +sanitizers.o: $(hdrdir)/ruby/internal/memory.h +sanitizers.o: $(hdrdir)/ruby/internal/method.h +sanitizers.o: $(hdrdir)/ruby/internal/module.h +sanitizers.o: $(hdrdir)/ruby/internal/newobj.h +sanitizers.o: $(hdrdir)/ruby/internal/scan_args.h +sanitizers.o: $(hdrdir)/ruby/internal/special_consts.h +sanitizers.o: $(hdrdir)/ruby/internal/static_assert.h +sanitizers.o: $(hdrdir)/ruby/internal/stdalign.h +sanitizers.o: $(hdrdir)/ruby/internal/stdbool.h +sanitizers.o: $(hdrdir)/ruby/internal/stdckdint.h +sanitizers.o: $(hdrdir)/ruby/internal/symbol.h +sanitizers.o: $(hdrdir)/ruby/internal/value.h +sanitizers.o: $(hdrdir)/ruby/internal/value_type.h +sanitizers.o: $(hdrdir)/ruby/internal/variable.h +sanitizers.o: $(hdrdir)/ruby/internal/warning_push.h +sanitizers.o: $(hdrdir)/ruby/internal/xmalloc.h +sanitizers.o: $(hdrdir)/ruby/missing.h +sanitizers.o: $(hdrdir)/ruby/ruby.h +sanitizers.o: $(hdrdir)/ruby/st.h +sanitizers.o: $(hdrdir)/ruby/subst.h +sanitizers.o: sanitizers.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/sanitizers/extconf.rb b/ext/-test-/sanitizers/extconf.rb new file mode 100644 index 0000000000..c94a96de6c --- /dev/null +++ b/ext/-test-/sanitizers/extconf.rb @@ -0,0 +1,2 @@ +require 'mkmf' +create_makefile('-test-/sanitizers') diff --git a/ext/-test-/sanitizers/sanitizers.c b/ext/-test-/sanitizers/sanitizers.c new file mode 100644 index 0000000000..97a85b26ef --- /dev/null +++ b/ext/-test-/sanitizers/sanitizers.c @@ -0,0 +1,36 @@ +#include "ruby/ruby.h" + +static VALUE +asan_enabled_p(VALUE self) +{ +#if defined(__has_feature) + /* clang uses __has_feature for determining asan */ + return __has_feature(address_sanitizer) ? Qtrue : Qfalse; +#elif defined(__SANITIZE_ADDRESS__) + /* GCC sets __SANITIZE_ADDRESS__ for determining asan */ + return Qtrue; +#else + return Qfalse; +#endif +} + +static VALUE +lsan_enabled_p(VALUE self) +{ +#if defined(__has_feature) + /* clang uses __has_feature for determining LSAN */ + return __has_feature(leak_sanitizer) ? Qtrue : Qfalse; +#else + return Qfalse; +#endif +} + +void +Init_sanitizers(void) +{ + VALUE m = rb_define_module("Test"); + VALUE c = rb_define_class_under(m, "Sanitizers", rb_cObject); + rb_define_singleton_method(c, "asan_enabled?", asan_enabled_p, 0); + rb_define_singleton_method(c, "lsan_enabled?", lsan_enabled_p, 0); +} + diff --git a/ext/-test-/scan_args/depend b/ext/-test-/scan_args/depend index e01de3124e..ca0fc19238 100644 --- a/ext/-test-/scan_args/depend +++ b/ext/-test-/scan_args/depend @@ -2,6 +2,19 @@ scan_args.o: $(RUBY_EXTCONF_H) scan_args.o: $(arch_hdrdir)/ruby/config.h scan_args.o: $(hdrdir)/ruby.h +scan_args.o: $(hdrdir)/ruby/assert.h +scan_args.o: $(hdrdir)/ruby/backward.h +scan_args.o: $(hdrdir)/ruby/backward/2/assume.h +scan_args.o: $(hdrdir)/ruby/backward/2/attributes.h +scan_args.o: $(hdrdir)/ruby/backward/2/bool.h +scan_args.o: $(hdrdir)/ruby/backward/2/inttypes.h +scan_args.o: $(hdrdir)/ruby/backward/2/limits.h +scan_args.o: $(hdrdir)/ruby/backward/2/long_long.h +scan_args.o: $(hdrdir)/ruby/backward/2/stdalign.h +scan_args.o: $(hdrdir)/ruby/backward/2/stdarg.h +scan_args.o: $(hdrdir)/ruby/defines.h +scan_args.o: $(hdrdir)/ruby/intern.h +scan_args.o: $(hdrdir)/ruby/internal/abi.h scan_args.o: $(hdrdir)/ruby/internal/anyargs.h scan_args.o: $(hdrdir)/ruby/internal/arithmetic.h scan_args.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ scan_args.o: $(hdrdir)/ruby/internal/attr/noexcept.h scan_args.o: $(hdrdir)/ruby/internal/attr/noinline.h scan_args.o: $(hdrdir)/ruby/internal/attr/nonnull.h scan_args.o: $(hdrdir)/ruby/internal/attr/noreturn.h +scan_args.o: $(hdrdir)/ruby/internal/attr/packed_struct.h scan_args.o: $(hdrdir)/ruby/internal/attr/pure.h scan_args.o: $(hdrdir)/ruby/internal/attr/restrict.h scan_args.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ scan_args.o: $(hdrdir)/ruby/internal/intern/enumerator.h scan_args.o: $(hdrdir)/ruby/internal/intern/error.h scan_args.o: $(hdrdir)/ruby/internal/intern/eval.h scan_args.o: $(hdrdir)/ruby/internal/intern/file.h -scan_args.o: $(hdrdir)/ruby/internal/intern/gc.h scan_args.o: $(hdrdir)/ruby/internal/intern/hash.h scan_args.o: $(hdrdir)/ruby/internal/intern/io.h scan_args.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ scan_args.o: $(hdrdir)/ruby/internal/intern/re.h scan_args.o: $(hdrdir)/ruby/internal/intern/ruby.h scan_args.o: $(hdrdir)/ruby/internal/intern/select.h scan_args.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +scan_args.o: $(hdrdir)/ruby/internal/intern/set.h scan_args.o: $(hdrdir)/ruby/internal/intern/signal.h scan_args.o: $(hdrdir)/ruby/internal/intern/sprintf.h scan_args.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ scan_args.o: $(hdrdir)/ruby/internal/memory.h scan_args.o: $(hdrdir)/ruby/internal/method.h scan_args.o: $(hdrdir)/ruby/internal/module.h scan_args.o: $(hdrdir)/ruby/internal/newobj.h -scan_args.o: $(hdrdir)/ruby/internal/rgengc.h scan_args.o: $(hdrdir)/ruby/internal/scan_args.h scan_args.o: $(hdrdir)/ruby/internal/special_consts.h scan_args.o: $(hdrdir)/ruby/internal/static_assert.h scan_args.o: $(hdrdir)/ruby/internal/stdalign.h scan_args.o: $(hdrdir)/ruby/internal/stdbool.h +scan_args.o: $(hdrdir)/ruby/internal/stdckdint.h scan_args.o: $(hdrdir)/ruby/internal/symbol.h scan_args.o: $(hdrdir)/ruby/internal/value.h scan_args.o: $(hdrdir)/ruby/internal/value_type.h scan_args.o: $(hdrdir)/ruby/internal/variable.h scan_args.o: $(hdrdir)/ruby/internal/warning_push.h scan_args.o: $(hdrdir)/ruby/internal/xmalloc.h -scan_args.o: $(hdrdir)/ruby/assert.h -scan_args.o: $(hdrdir)/ruby/backward.h -scan_args.o: $(hdrdir)/ruby/backward/2/assume.h -scan_args.o: $(hdrdir)/ruby/backward/2/attributes.h -scan_args.o: $(hdrdir)/ruby/backward/2/bool.h -scan_args.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -scan_args.o: $(hdrdir)/ruby/backward/2/inttypes.h -scan_args.o: $(hdrdir)/ruby/backward/2/limits.h -scan_args.o: $(hdrdir)/ruby/backward/2/long_long.h -scan_args.o: $(hdrdir)/ruby/backward/2/stdalign.h -scan_args.o: $(hdrdir)/ruby/backward/2/stdarg.h -scan_args.o: $(hdrdir)/ruby/defines.h -scan_args.o: $(hdrdir)/ruby/intern.h scan_args.o: $(hdrdir)/ruby/missing.h scan_args.o: $(hdrdir)/ruby/ruby.h scan_args.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/scheduler/extconf.rb b/ext/-test-/scheduler/extconf.rb new file mode 100644 index 0000000000..159699bd8e --- /dev/null +++ b/ext/-test-/scheduler/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/scheduler") diff --git a/ext/-test-/scheduler/scheduler.c b/ext/-test-/scheduler/scheduler.c new file mode 100644 index 0000000000..b742a5573b --- /dev/null +++ b/ext/-test-/scheduler/scheduler.c @@ -0,0 +1,92 @@ +#include "ruby/ruby.h" +#include "ruby/thread.h" +#include "ruby/io.h" +#include "ruby/fiber/scheduler.h" + +/* + * Test extension for reproducing the gRPC interrupt handling bug. + * + * This reproduces the exact issue from grpc/grpc commit 69f229e (June 2025): + * https://github.com/grpc/grpc/commit/69f229edd1d79ab7a7dfda98e3aef6fd807adcad + * + * The bug occurs when: + * 1. A fiber scheduler uses Thread.handle_interrupt(::SignalException => :never) + * (like Async::Scheduler does) + * 2. Native code uses rb_thread_call_without_gvl in a retry loop that checks + * the interrupted flag and retries (like gRPC's completion queue) + * 3. A signal (SIGINT/SIGTERM) is sent + * 4. The unblock_func sets interrupted=1, but Thread.handle_interrupt defers the signal + * 5. The loop sees interrupted=1 and retries without yielding to the scheduler + * 6. The deferred interrupt never gets processed -> infinite hang + * + * The fix is in vm_check_ints_blocking() in thread.c, which should yield to + * the fiber scheduler when interrupts are pending, allowing the scheduler to + * detect Thread.pending_interrupt? and exit its run loop. + */ + +struct blocking_state { + int notify_descriptor; + volatile int interrupted; +}; + +static void +unblock_callback(void *argument) +{ + struct blocking_state *blocking_state = (struct blocking_state *)argument; + blocking_state->interrupted = 1; +} + +static void * +blocking_operation(void *argument) +{ + struct blocking_state *blocking_state = (struct blocking_state *)argument; + + ssize_t ret = write(blocking_state->notify_descriptor, "x", 1); + (void)ret; // ignore the result for now + + while (!blocking_state->interrupted) { + struct timeval tv = {1, 0}; // 1 second timeout. + int result = select(0, NULL, NULL, NULL, &tv); + + if (result == -1 && errno == EINTR) { + blocking_state->interrupted = 1; + } + + // Otherwise, timeout -> loop again. + } + + return NULL; +} + +static VALUE +scheduler_blocking_loop(VALUE self, VALUE notify) +{ + struct blocking_state blocking_state = { + .notify_descriptor = rb_io_descriptor(notify), + .interrupted = 0, + }; + + while (true) { + blocking_state.interrupted = 0; + + rb_thread_call_without_gvl( + blocking_operation, &blocking_state, + unblock_callback, &blocking_state + ); + + // The bug: When interrupted, loop retries without yielding to scheduler. + // With Thread.handle_interrupt(:never), this causes an infinite hang, + // because the deferred interrupt never gets a chance to be processed. + } while (blocking_state.interrupted); + + return Qnil; +} + +void +Init_scheduler(void) +{ + VALUE mBug = rb_define_module("Bug"); + VALUE mScheduler = rb_define_module_under(mBug, "Scheduler"); + + rb_define_module_function(mScheduler, "blocking_loop", scheduler_blocking_loop, 1); +} diff --git a/ext/-test-/st/foreach/depend b/ext/-test-/st/foreach/depend index d9c0f56d11..29aab2bb29 100644 --- a/ext/-test-/st/foreach/depend +++ b/ext/-test-/st/foreach/depend @@ -2,6 +2,19 @@ foreach.o: $(RUBY_EXTCONF_H) foreach.o: $(arch_hdrdir)/ruby/config.h foreach.o: $(hdrdir)/ruby.h +foreach.o: $(hdrdir)/ruby/assert.h +foreach.o: $(hdrdir)/ruby/backward.h +foreach.o: $(hdrdir)/ruby/backward/2/assume.h +foreach.o: $(hdrdir)/ruby/backward/2/attributes.h +foreach.o: $(hdrdir)/ruby/backward/2/bool.h +foreach.o: $(hdrdir)/ruby/backward/2/inttypes.h +foreach.o: $(hdrdir)/ruby/backward/2/limits.h +foreach.o: $(hdrdir)/ruby/backward/2/long_long.h +foreach.o: $(hdrdir)/ruby/backward/2/stdalign.h +foreach.o: $(hdrdir)/ruby/backward/2/stdarg.h +foreach.o: $(hdrdir)/ruby/defines.h +foreach.o: $(hdrdir)/ruby/intern.h +foreach.o: $(hdrdir)/ruby/internal/abi.h foreach.o: $(hdrdir)/ruby/internal/anyargs.h foreach.o: $(hdrdir)/ruby/internal/arithmetic.h foreach.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ foreach.o: $(hdrdir)/ruby/internal/attr/noexcept.h foreach.o: $(hdrdir)/ruby/internal/attr/noinline.h foreach.o: $(hdrdir)/ruby/internal/attr/nonnull.h foreach.o: $(hdrdir)/ruby/internal/attr/noreturn.h +foreach.o: $(hdrdir)/ruby/internal/attr/packed_struct.h foreach.o: $(hdrdir)/ruby/internal/attr/pure.h foreach.o: $(hdrdir)/ruby/internal/attr/restrict.h foreach.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ foreach.o: $(hdrdir)/ruby/internal/intern/enumerator.h foreach.o: $(hdrdir)/ruby/internal/intern/error.h foreach.o: $(hdrdir)/ruby/internal/intern/eval.h foreach.o: $(hdrdir)/ruby/internal/intern/file.h -foreach.o: $(hdrdir)/ruby/internal/intern/gc.h foreach.o: $(hdrdir)/ruby/internal/intern/hash.h foreach.o: $(hdrdir)/ruby/internal/intern/io.h foreach.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ foreach.o: $(hdrdir)/ruby/internal/intern/re.h foreach.o: $(hdrdir)/ruby/internal/intern/ruby.h foreach.o: $(hdrdir)/ruby/internal/intern/select.h foreach.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +foreach.o: $(hdrdir)/ruby/internal/intern/set.h foreach.o: $(hdrdir)/ruby/internal/intern/signal.h foreach.o: $(hdrdir)/ruby/internal/intern/sprintf.h foreach.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ foreach.o: $(hdrdir)/ruby/internal/memory.h foreach.o: $(hdrdir)/ruby/internal/method.h foreach.o: $(hdrdir)/ruby/internal/module.h foreach.o: $(hdrdir)/ruby/internal/newobj.h -foreach.o: $(hdrdir)/ruby/internal/rgengc.h foreach.o: $(hdrdir)/ruby/internal/scan_args.h foreach.o: $(hdrdir)/ruby/internal/special_consts.h foreach.o: $(hdrdir)/ruby/internal/static_assert.h foreach.o: $(hdrdir)/ruby/internal/stdalign.h foreach.o: $(hdrdir)/ruby/internal/stdbool.h +foreach.o: $(hdrdir)/ruby/internal/stdckdint.h foreach.o: $(hdrdir)/ruby/internal/symbol.h foreach.o: $(hdrdir)/ruby/internal/value.h foreach.o: $(hdrdir)/ruby/internal/value_type.h foreach.o: $(hdrdir)/ruby/internal/variable.h foreach.o: $(hdrdir)/ruby/internal/warning_push.h foreach.o: $(hdrdir)/ruby/internal/xmalloc.h -foreach.o: $(hdrdir)/ruby/assert.h -foreach.o: $(hdrdir)/ruby/backward.h -foreach.o: $(hdrdir)/ruby/backward/2/assume.h -foreach.o: $(hdrdir)/ruby/backward/2/attributes.h -foreach.o: $(hdrdir)/ruby/backward/2/bool.h -foreach.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -foreach.o: $(hdrdir)/ruby/backward/2/inttypes.h -foreach.o: $(hdrdir)/ruby/backward/2/limits.h -foreach.o: $(hdrdir)/ruby/backward/2/long_long.h -foreach.o: $(hdrdir)/ruby/backward/2/stdalign.h -foreach.o: $(hdrdir)/ruby/backward/2/stdarg.h -foreach.o: $(hdrdir)/ruby/defines.h -foreach.o: $(hdrdir)/ruby/intern.h foreach.o: $(hdrdir)/ruby/missing.h foreach.o: $(hdrdir)/ruby/ruby.h foreach.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/st/foreach/foreach.c b/ext/-test-/st/foreach/foreach.c index 27ac18046f..7fbf064694 100644 --- a/ext/-test-/st/foreach/foreach.c +++ b/ext/-test-/st/foreach/foreach.c @@ -12,22 +12,22 @@ static void force_unpack_check(struct checker *c, st_data_t key, st_data_t val) { if (c->nr == 0) { - st_data_t i; + st_data_t i; - if (c->tbl->bins != NULL) rb_bug("should be packed\n"); + if (c->tbl->bins != NULL) rb_bug("should be packed"); - /* force unpacking during iteration: */ - for (i = 1; i < expect_size; i++) - st_add_direct(c->tbl, i, i); + /* force unpacking during iteration: */ + for (i = 1; i < expect_size; i++) + st_add_direct(c->tbl, i, i); - if (c->tbl->bins == NULL) rb_bug("should be unpacked\n"); + if (c->tbl->bins == NULL) rb_bug("should be unpacked"); } if (key != c->nr) { - rb_bug("unexpected key: %"PRIuVALUE" (expected %"PRIuVALUE")\n", (VALUE)key, (VALUE)c->nr); + rb_bug("unexpected key: %"PRIuVALUE" (expected %"PRIuVALUE")", (VALUE)key, (VALUE)c->nr); } if (val != c->nr) { - rb_bug("unexpected val: %"PRIuVALUE" (expected %"PRIuVALUE")\n", (VALUE)val, (VALUE)c->nr); + rb_bug("unexpected val: %"PRIuVALUE" (expected %"PRIuVALUE")", (VALUE)val, (VALUE)c->nr); } c->nr++; @@ -39,34 +39,34 @@ unp_fec_i(st_data_t key, st_data_t val, st_data_t args, int error) struct checker *c = (struct checker *)args; if (error) { - if (c->test == ID2SYM(rb_intern("delete2"))) - return ST_STOP; + if (c->test == ID2SYM(rb_intern("delete2"))) + return ST_STOP; - rb_bug("unexpected error"); + rb_bug("unexpected error"); } force_unpack_check(c, key, val); if (c->test == ID2SYM(rb_intern("check"))) { - return ST_CHECK; + return ST_CHECK; } if (c->test == ID2SYM(rb_intern("delete1"))) { - if (c->nr == 1) return ST_DELETE; - return ST_CHECK; + if (c->nr == 1) return ST_DELETE; + return ST_CHECK; } if (c->test == ID2SYM(rb_intern("delete2"))) { - if (c->nr == 1) { - st_data_t k = 0; - st_data_t v; - - if (!st_delete(c->tbl, &k, &v)) { - rb_bug("failed to delete\n"); - } - if (v != 0) { - rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v); - } - } - return ST_CHECK; + if (c->nr == 1) { + st_data_t k = 0; + st_data_t v; + + if (!st_delete(c->tbl, &k, &v)) { + rb_bug("failed to delete"); + } + if (v != 0) { + rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v); + } + } + return ST_CHECK; } rb_raise(rb_eArgError, "unexpected arg: %+"PRIsVALUE, c->test); @@ -84,21 +84,21 @@ unp_fec(VALUE self, VALUE test) st_add_direct(tbl, 0, 0); - if (tbl->bins != NULL) rb_bug("should still be packed\n"); + if (tbl->bins != NULL) rb_bug("should still be packed"); st_foreach_check(tbl, unp_fec_i, (st_data_t)&c, -1); if (c.test == ID2SYM(rb_intern("delete2"))) { - if (c.nr != 1) { - rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)\n", (VALUE)c.nr); - } + if (c.nr != 1) { + rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)", (VALUE)c.nr); + } } else if (c.nr != expect_size) { - rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE")\n", - (VALUE)c.nr, (VALUE)expect_size); + rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE")", + (VALUE)c.nr, (VALUE)expect_size); } - if (tbl->bins == NULL) rb_bug("should be unpacked\n"); + if (tbl->bins == NULL) rb_bug("should be unpacked"); st_free_table(tbl); @@ -112,22 +112,22 @@ unp_fe_i(st_data_t key, st_data_t val, st_data_t args) force_unpack_check(c, key, val); if (c->test == ID2SYM(rb_intern("unpacked"))) { - return ST_CONTINUE; + return ST_CONTINUE; } else if (c->test == ID2SYM(rb_intern("unpack_delete"))) { - if (c->nr == 1) { - st_data_t k = 0; - st_data_t v; - - if (!st_delete(c->tbl, &k, &v)) { - rb_bug("failed to delete\n"); - } - if (v != 0) { - rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v); - } - return ST_CONTINUE; - } - rb_bug("should never get here\n"); + if (c->nr == 1) { + st_data_t k = 0; + st_data_t v; + + if (!st_delete(c->tbl, &k, &v)) { + rb_bug("failed to delete"); + } + if (v != 0) { + rb_bug("unexpected value deleted: %"PRIuVALUE" (expected 0)", (VALUE)v); + } + return ST_CONTINUE; + } + rb_bug("should never get here"); } rb_raise(rb_eArgError, "unexpected arg: %+"PRIsVALUE, c->test); @@ -145,21 +145,21 @@ unp_fe(VALUE self, VALUE test) st_add_direct(tbl, 0, 0); - if (tbl->bins != NULL) rb_bug("should still be packed\n"); + if (tbl->bins != NULL) rb_bug("should still be packed"); st_foreach(tbl, unp_fe_i, (st_data_t)&c); if (c.test == ID2SYM(rb_intern("unpack_delete"))) { - if (c.nr != 1) { - rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)\n", (VALUE)c.nr); - } + if (c.nr != 1) { + rb_bug("mismatched iteration: %"PRIuVALUE" (expected 1)", (VALUE)c.nr); + } } else if (c.nr != expect_size) { - rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE"o)\n", - (VALUE)c.nr, (VALUE)expect_size); + rb_bug("mismatched iteration: %"PRIuVALUE" (expected %"PRIuVALUE"o)", + (VALUE)c.nr, (VALUE)expect_size); } - if (tbl->bins == NULL) rb_bug("should be unpacked\n"); + if (tbl->bins == NULL) rb_bug("should be unpacked"); st_free_table(tbl); diff --git a/ext/-test-/st/numhash/depend b/ext/-test-/st/numhash/depend index 8df4fed3e4..18320d55f5 100644 --- a/ext/-test-/st/numhash/depend +++ b/ext/-test-/st/numhash/depend @@ -2,6 +2,19 @@ numhash.o: $(RUBY_EXTCONF_H) numhash.o: $(arch_hdrdir)/ruby/config.h numhash.o: $(hdrdir)/ruby.h +numhash.o: $(hdrdir)/ruby/assert.h +numhash.o: $(hdrdir)/ruby/backward.h +numhash.o: $(hdrdir)/ruby/backward/2/assume.h +numhash.o: $(hdrdir)/ruby/backward/2/attributes.h +numhash.o: $(hdrdir)/ruby/backward/2/bool.h +numhash.o: $(hdrdir)/ruby/backward/2/inttypes.h +numhash.o: $(hdrdir)/ruby/backward/2/limits.h +numhash.o: $(hdrdir)/ruby/backward/2/long_long.h +numhash.o: $(hdrdir)/ruby/backward/2/stdalign.h +numhash.o: $(hdrdir)/ruby/backward/2/stdarg.h +numhash.o: $(hdrdir)/ruby/defines.h +numhash.o: $(hdrdir)/ruby/intern.h +numhash.o: $(hdrdir)/ruby/internal/abi.h numhash.o: $(hdrdir)/ruby/internal/anyargs.h numhash.o: $(hdrdir)/ruby/internal/arithmetic.h numhash.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ numhash.o: $(hdrdir)/ruby/internal/attr/noexcept.h numhash.o: $(hdrdir)/ruby/internal/attr/noinline.h numhash.o: $(hdrdir)/ruby/internal/attr/nonnull.h numhash.o: $(hdrdir)/ruby/internal/attr/noreturn.h +numhash.o: $(hdrdir)/ruby/internal/attr/packed_struct.h numhash.o: $(hdrdir)/ruby/internal/attr/pure.h numhash.o: $(hdrdir)/ruby/internal/attr/restrict.h numhash.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ numhash.o: $(hdrdir)/ruby/internal/intern/enumerator.h numhash.o: $(hdrdir)/ruby/internal/intern/error.h numhash.o: $(hdrdir)/ruby/internal/intern/eval.h numhash.o: $(hdrdir)/ruby/internal/intern/file.h -numhash.o: $(hdrdir)/ruby/internal/intern/gc.h numhash.o: $(hdrdir)/ruby/internal/intern/hash.h numhash.o: $(hdrdir)/ruby/internal/intern/io.h numhash.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ numhash.o: $(hdrdir)/ruby/internal/intern/re.h numhash.o: $(hdrdir)/ruby/internal/intern/ruby.h numhash.o: $(hdrdir)/ruby/internal/intern/select.h numhash.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +numhash.o: $(hdrdir)/ruby/internal/intern/set.h numhash.o: $(hdrdir)/ruby/internal/intern/signal.h numhash.o: $(hdrdir)/ruby/internal/intern/sprintf.h numhash.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ numhash.o: $(hdrdir)/ruby/internal/memory.h numhash.o: $(hdrdir)/ruby/internal/method.h numhash.o: $(hdrdir)/ruby/internal/module.h numhash.o: $(hdrdir)/ruby/internal/newobj.h -numhash.o: $(hdrdir)/ruby/internal/rgengc.h numhash.o: $(hdrdir)/ruby/internal/scan_args.h numhash.o: $(hdrdir)/ruby/internal/special_consts.h numhash.o: $(hdrdir)/ruby/internal/static_assert.h numhash.o: $(hdrdir)/ruby/internal/stdalign.h numhash.o: $(hdrdir)/ruby/internal/stdbool.h +numhash.o: $(hdrdir)/ruby/internal/stdckdint.h numhash.o: $(hdrdir)/ruby/internal/symbol.h numhash.o: $(hdrdir)/ruby/internal/value.h numhash.o: $(hdrdir)/ruby/internal/value_type.h numhash.o: $(hdrdir)/ruby/internal/variable.h numhash.o: $(hdrdir)/ruby/internal/warning_push.h numhash.o: $(hdrdir)/ruby/internal/xmalloc.h -numhash.o: $(hdrdir)/ruby/assert.h -numhash.o: $(hdrdir)/ruby/backward.h -numhash.o: $(hdrdir)/ruby/backward/2/assume.h -numhash.o: $(hdrdir)/ruby/backward/2/attributes.h -numhash.o: $(hdrdir)/ruby/backward/2/bool.h -numhash.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -numhash.o: $(hdrdir)/ruby/backward/2/inttypes.h -numhash.o: $(hdrdir)/ruby/backward/2/limits.h -numhash.o: $(hdrdir)/ruby/backward/2/long_long.h -numhash.o: $(hdrdir)/ruby/backward/2/stdalign.h -numhash.o: $(hdrdir)/ruby/backward/2/stdarg.h -numhash.o: $(hdrdir)/ruby/defines.h -numhash.o: $(hdrdir)/ruby/intern.h numhash.o: $(hdrdir)/ruby/missing.h numhash.o: $(hdrdir)/ruby/ruby.h numhash.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/st/numhash/numhash.c b/ext/-test-/st/numhash/numhash.c index aa8015e86c..7e8d5d9fe2 100644 --- a/ext/-test-/st/numhash/numhash.c +++ b/ext/-test-/st/numhash/numhash.c @@ -42,7 +42,7 @@ numhash_aref(VALUE self, VALUE key) st_table *tbl = (st_table *)Check_TypedStruct(self, &numhash_type); if (!SPECIAL_CONST_P(key)) rb_raise(rb_eArgError, "not a special const"); if (st_lookup(tbl, (st_data_t)key, &data)) - return (VALUE)data; + return (VALUE)data; return Qnil; } @@ -79,12 +79,12 @@ update_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing) VALUE ret = rb_yield_values(existing ? 2 : 1, (VALUE)*key, (VALUE)*value); switch (ret) { case Qfalse: - return ST_STOP; + return ST_STOP; case Qnil: - return ST_DELETE; + return ST_DELETE; default: - *value = ret; - return ST_CONTINUE; + *value = ret; + return ST_CONTINUE; } } @@ -93,9 +93,9 @@ numhash_update(VALUE self, VALUE key) { st_table *table = (st_table *)Check_TypedStruct(self, &numhash_type); if (st_update(table, (st_data_t)key, update_func, 0)) - return Qtrue; + return Qtrue; else - return Qfalse; + return Qfalse; } #if SIZEOF_LONG == SIZEOF_VOIDP @@ -117,7 +117,7 @@ numhash_delete_safe(VALUE self, VALUE key) st_table *table = (st_table *)Check_TypedStruct(self, &numhash_type); st_data_t val, k = (st_data_t)key; if (st_delete_safe(table, &k, &val, (st_data_t)self)) { - return val; + return val; } return Qnil; } diff --git a/ext/-test-/st/update/depend b/ext/-test-/st/update/depend index b840e67f3b..247f0efd6b 100644 --- a/ext/-test-/st/update/depend +++ b/ext/-test-/st/update/depend @@ -2,6 +2,19 @@ update.o: $(RUBY_EXTCONF_H) update.o: $(arch_hdrdir)/ruby/config.h update.o: $(hdrdir)/ruby.h +update.o: $(hdrdir)/ruby/assert.h +update.o: $(hdrdir)/ruby/backward.h +update.o: $(hdrdir)/ruby/backward/2/assume.h +update.o: $(hdrdir)/ruby/backward/2/attributes.h +update.o: $(hdrdir)/ruby/backward/2/bool.h +update.o: $(hdrdir)/ruby/backward/2/inttypes.h +update.o: $(hdrdir)/ruby/backward/2/limits.h +update.o: $(hdrdir)/ruby/backward/2/long_long.h +update.o: $(hdrdir)/ruby/backward/2/stdalign.h +update.o: $(hdrdir)/ruby/backward/2/stdarg.h +update.o: $(hdrdir)/ruby/defines.h +update.o: $(hdrdir)/ruby/intern.h +update.o: $(hdrdir)/ruby/internal/abi.h update.o: $(hdrdir)/ruby/internal/anyargs.h update.o: $(hdrdir)/ruby/internal/arithmetic.h update.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ update.o: $(hdrdir)/ruby/internal/attr/noexcept.h update.o: $(hdrdir)/ruby/internal/attr/noinline.h update.o: $(hdrdir)/ruby/internal/attr/nonnull.h update.o: $(hdrdir)/ruby/internal/attr/noreturn.h +update.o: $(hdrdir)/ruby/internal/attr/packed_struct.h update.o: $(hdrdir)/ruby/internal/attr/pure.h update.o: $(hdrdir)/ruby/internal/attr/restrict.h update.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ update.o: $(hdrdir)/ruby/internal/intern/enumerator.h update.o: $(hdrdir)/ruby/internal/intern/error.h update.o: $(hdrdir)/ruby/internal/intern/eval.h update.o: $(hdrdir)/ruby/internal/intern/file.h -update.o: $(hdrdir)/ruby/internal/intern/gc.h update.o: $(hdrdir)/ruby/internal/intern/hash.h update.o: $(hdrdir)/ruby/internal/intern/io.h update.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ update.o: $(hdrdir)/ruby/internal/intern/re.h update.o: $(hdrdir)/ruby/internal/intern/ruby.h update.o: $(hdrdir)/ruby/internal/intern/select.h update.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +update.o: $(hdrdir)/ruby/internal/intern/set.h update.o: $(hdrdir)/ruby/internal/intern/signal.h update.o: $(hdrdir)/ruby/internal/intern/sprintf.h update.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ update.o: $(hdrdir)/ruby/internal/memory.h update.o: $(hdrdir)/ruby/internal/method.h update.o: $(hdrdir)/ruby/internal/module.h update.o: $(hdrdir)/ruby/internal/newobj.h -update.o: $(hdrdir)/ruby/internal/rgengc.h update.o: $(hdrdir)/ruby/internal/scan_args.h update.o: $(hdrdir)/ruby/internal/special_consts.h update.o: $(hdrdir)/ruby/internal/static_assert.h update.o: $(hdrdir)/ruby/internal/stdalign.h update.o: $(hdrdir)/ruby/internal/stdbool.h +update.o: $(hdrdir)/ruby/internal/stdckdint.h update.o: $(hdrdir)/ruby/internal/symbol.h update.o: $(hdrdir)/ruby/internal/value.h update.o: $(hdrdir)/ruby/internal/value_type.h update.o: $(hdrdir)/ruby/internal/variable.h update.o: $(hdrdir)/ruby/internal/warning_push.h update.o: $(hdrdir)/ruby/internal/xmalloc.h -update.o: $(hdrdir)/ruby/assert.h -update.o: $(hdrdir)/ruby/backward.h -update.o: $(hdrdir)/ruby/backward/2/assume.h -update.o: $(hdrdir)/ruby/backward/2/attributes.h -update.o: $(hdrdir)/ruby/backward/2/bool.h -update.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -update.o: $(hdrdir)/ruby/backward/2/inttypes.h -update.o: $(hdrdir)/ruby/backward/2/limits.h -update.o: $(hdrdir)/ruby/backward/2/long_long.h -update.o: $(hdrdir)/ruby/backward/2/stdalign.h -update.o: $(hdrdir)/ruby/backward/2/stdarg.h -update.o: $(hdrdir)/ruby/defines.h -update.o: $(hdrdir)/ruby/intern.h update.o: $(hdrdir)/ruby/missing.h update.o: $(hdrdir)/ruby/ruby.h update.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/st/update/update.c b/ext/-test-/st/update/update.c index 979ad3e334..ea7fab12e1 100644 --- a/ext/-test-/st/update/update.c +++ b/ext/-test-/st/update/update.c @@ -7,12 +7,12 @@ update_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing) VALUE ret = rb_yield_values(existing ? 2 : 1, (VALUE)*key, (VALUE)*value); switch (ret) { case Qfalse: - return ST_STOP; + return ST_STOP; case Qnil: - return ST_DELETE; + return ST_DELETE; default: - *value = ret; - return ST_CONTINUE; + *value = ret; + return ST_CONTINUE; } } @@ -20,9 +20,9 @@ static VALUE test_st_update(VALUE self, VALUE key) { if (st_update(RHASH_TBL(self), (st_data_t)key, update_func, 0)) - return Qtrue; + return Qtrue; else - return Qfalse; + return Qfalse; } void diff --git a/ext/-test-/stack/depend b/ext/-test-/stack/depend new file mode 100644 index 0000000000..77e93bb201 --- /dev/null +++ b/ext/-test-/stack/depend @@ -0,0 +1,179 @@ +# AUTOGENERATED DEPENDENCIES START +stack.o: $(RUBY_EXTCONF_H) +stack.o: $(arch_hdrdir)/ruby/config.h +stack.o: $(hdrdir)/ruby.h +stack.o: $(hdrdir)/ruby/assert.h +stack.o: $(hdrdir)/ruby/backward.h +stack.o: $(hdrdir)/ruby/backward/2/assume.h +stack.o: $(hdrdir)/ruby/backward/2/attributes.h +stack.o: $(hdrdir)/ruby/backward/2/bool.h +stack.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +stack.o: $(hdrdir)/ruby/backward/2/inttypes.h +stack.o: $(hdrdir)/ruby/backward/2/limits.h +stack.o: $(hdrdir)/ruby/backward/2/long_long.h +stack.o: $(hdrdir)/ruby/backward/2/stdalign.h +stack.o: $(hdrdir)/ruby/backward/2/stdarg.h +stack.o: $(hdrdir)/ruby/defines.h +stack.o: $(hdrdir)/ruby/encoding.h +stack.o: $(hdrdir)/ruby/intern.h +stack.o: $(hdrdir)/ruby/internal/abi.h +stack.o: $(hdrdir)/ruby/internal/anyargs.h +stack.o: $(hdrdir)/ruby/internal/arithmetic.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/char.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/double.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/int.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/long.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/short.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +stack.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +stack.o: $(hdrdir)/ruby/internal/assume.h +stack.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +stack.o: $(hdrdir)/ruby/internal/attr/artificial.h +stack.o: $(hdrdir)/ruby/internal/attr/cold.h +stack.o: $(hdrdir)/ruby/internal/attr/const.h +stack.o: $(hdrdir)/ruby/internal/attr/constexpr.h +stack.o: $(hdrdir)/ruby/internal/attr/deprecated.h +stack.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +stack.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +stack.o: $(hdrdir)/ruby/internal/attr/error.h +stack.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +stack.o: $(hdrdir)/ruby/internal/attr/forceinline.h +stack.o: $(hdrdir)/ruby/internal/attr/format.h +stack.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +stack.o: $(hdrdir)/ruby/internal/attr/noalias.h +stack.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +stack.o: $(hdrdir)/ruby/internal/attr/noexcept.h +stack.o: $(hdrdir)/ruby/internal/attr/noinline.h +stack.o: $(hdrdir)/ruby/internal/attr/nonnull.h +stack.o: $(hdrdir)/ruby/internal/attr/noreturn.h +stack.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +stack.o: $(hdrdir)/ruby/internal/attr/pure.h +stack.o: $(hdrdir)/ruby/internal/attr/restrict.h +stack.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +stack.o: $(hdrdir)/ruby/internal/attr/warning.h +stack.o: $(hdrdir)/ruby/internal/attr/weakref.h +stack.o: $(hdrdir)/ruby/internal/cast.h +stack.o: $(hdrdir)/ruby/internal/compiler_is.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +stack.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +stack.o: $(hdrdir)/ruby/internal/compiler_since.h +stack.o: $(hdrdir)/ruby/internal/config.h +stack.o: $(hdrdir)/ruby/internal/constant_p.h +stack.o: $(hdrdir)/ruby/internal/core.h +stack.o: $(hdrdir)/ruby/internal/core/rarray.h +stack.o: $(hdrdir)/ruby/internal/core/rbasic.h +stack.o: $(hdrdir)/ruby/internal/core/rbignum.h +stack.o: $(hdrdir)/ruby/internal/core/rclass.h +stack.o: $(hdrdir)/ruby/internal/core/rdata.h +stack.o: $(hdrdir)/ruby/internal/core/rfile.h +stack.o: $(hdrdir)/ruby/internal/core/rhash.h +stack.o: $(hdrdir)/ruby/internal/core/robject.h +stack.o: $(hdrdir)/ruby/internal/core/rregexp.h +stack.o: $(hdrdir)/ruby/internal/core/rstring.h +stack.o: $(hdrdir)/ruby/internal/core/rstruct.h +stack.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +stack.o: $(hdrdir)/ruby/internal/ctype.h +stack.o: $(hdrdir)/ruby/internal/dllexport.h +stack.o: $(hdrdir)/ruby/internal/dosish.h +stack.o: $(hdrdir)/ruby/internal/encoding/coderange.h +stack.o: $(hdrdir)/ruby/internal/encoding/ctype.h +stack.o: $(hdrdir)/ruby/internal/encoding/encoding.h +stack.o: $(hdrdir)/ruby/internal/encoding/pathname.h +stack.o: $(hdrdir)/ruby/internal/encoding/re.h +stack.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +stack.o: $(hdrdir)/ruby/internal/encoding/string.h +stack.o: $(hdrdir)/ruby/internal/encoding/symbol.h +stack.o: $(hdrdir)/ruby/internal/encoding/transcode.h +stack.o: $(hdrdir)/ruby/internal/error.h +stack.o: $(hdrdir)/ruby/internal/eval.h +stack.o: $(hdrdir)/ruby/internal/event.h +stack.o: $(hdrdir)/ruby/internal/fl_type.h +stack.o: $(hdrdir)/ruby/internal/gc.h +stack.o: $(hdrdir)/ruby/internal/glob.h +stack.o: $(hdrdir)/ruby/internal/globals.h +stack.o: $(hdrdir)/ruby/internal/has/attribute.h +stack.o: $(hdrdir)/ruby/internal/has/builtin.h +stack.o: $(hdrdir)/ruby/internal/has/c_attribute.h +stack.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +stack.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +stack.o: $(hdrdir)/ruby/internal/has/extension.h +stack.o: $(hdrdir)/ruby/internal/has/feature.h +stack.o: $(hdrdir)/ruby/internal/has/warning.h +stack.o: $(hdrdir)/ruby/internal/intern/array.h +stack.o: $(hdrdir)/ruby/internal/intern/bignum.h +stack.o: $(hdrdir)/ruby/internal/intern/class.h +stack.o: $(hdrdir)/ruby/internal/intern/compar.h +stack.o: $(hdrdir)/ruby/internal/intern/complex.h +stack.o: $(hdrdir)/ruby/internal/intern/cont.h +stack.o: $(hdrdir)/ruby/internal/intern/dir.h +stack.o: $(hdrdir)/ruby/internal/intern/enum.h +stack.o: $(hdrdir)/ruby/internal/intern/enumerator.h +stack.o: $(hdrdir)/ruby/internal/intern/error.h +stack.o: $(hdrdir)/ruby/internal/intern/eval.h +stack.o: $(hdrdir)/ruby/internal/intern/file.h +stack.o: $(hdrdir)/ruby/internal/intern/hash.h +stack.o: $(hdrdir)/ruby/internal/intern/io.h +stack.o: $(hdrdir)/ruby/internal/intern/load.h +stack.o: $(hdrdir)/ruby/internal/intern/marshal.h +stack.o: $(hdrdir)/ruby/internal/intern/numeric.h +stack.o: $(hdrdir)/ruby/internal/intern/object.h +stack.o: $(hdrdir)/ruby/internal/intern/parse.h +stack.o: $(hdrdir)/ruby/internal/intern/proc.h +stack.o: $(hdrdir)/ruby/internal/intern/process.h +stack.o: $(hdrdir)/ruby/internal/intern/random.h +stack.o: $(hdrdir)/ruby/internal/intern/range.h +stack.o: $(hdrdir)/ruby/internal/intern/rational.h +stack.o: $(hdrdir)/ruby/internal/intern/re.h +stack.o: $(hdrdir)/ruby/internal/intern/ruby.h +stack.o: $(hdrdir)/ruby/internal/intern/select.h +stack.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +stack.o: $(hdrdir)/ruby/internal/intern/set.h +stack.o: $(hdrdir)/ruby/internal/intern/signal.h +stack.o: $(hdrdir)/ruby/internal/intern/sprintf.h +stack.o: $(hdrdir)/ruby/internal/intern/string.h +stack.o: $(hdrdir)/ruby/internal/intern/struct.h +stack.o: $(hdrdir)/ruby/internal/intern/thread.h +stack.o: $(hdrdir)/ruby/internal/intern/time.h +stack.o: $(hdrdir)/ruby/internal/intern/variable.h +stack.o: $(hdrdir)/ruby/internal/intern/vm.h +stack.o: $(hdrdir)/ruby/internal/interpreter.h +stack.o: $(hdrdir)/ruby/internal/iterator.h +stack.o: $(hdrdir)/ruby/internal/memory.h +stack.o: $(hdrdir)/ruby/internal/method.h +stack.o: $(hdrdir)/ruby/internal/module.h +stack.o: $(hdrdir)/ruby/internal/newobj.h +stack.o: $(hdrdir)/ruby/internal/scan_args.h +stack.o: $(hdrdir)/ruby/internal/special_consts.h +stack.o: $(hdrdir)/ruby/internal/static_assert.h +stack.o: $(hdrdir)/ruby/internal/stdalign.h +stack.o: $(hdrdir)/ruby/internal/stdbool.h +stack.o: $(hdrdir)/ruby/internal/stdckdint.h +stack.o: $(hdrdir)/ruby/internal/symbol.h +stack.o: $(hdrdir)/ruby/internal/value.h +stack.o: $(hdrdir)/ruby/internal/value_type.h +stack.o: $(hdrdir)/ruby/internal/variable.h +stack.o: $(hdrdir)/ruby/internal/warning_push.h +stack.o: $(hdrdir)/ruby/internal/xmalloc.h +stack.o: $(hdrdir)/ruby/missing.h +stack.o: $(hdrdir)/ruby/onigmo.h +stack.o: $(hdrdir)/ruby/oniguruma.h +stack.o: $(hdrdir)/ruby/ruby.h +stack.o: $(hdrdir)/ruby/st.h +stack.o: $(hdrdir)/ruby/subst.h +stack.o: $(top_srcdir)/encindex.h +stack.o: $(top_srcdir)/internal/compilers.h +stack.o: $(top_srcdir)/internal/string.h +stack.o: stack.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/stack/extconf.rb b/ext/-test-/stack/extconf.rb new file mode 100644 index 0000000000..d786b15db9 --- /dev/null +++ b/ext/-test-/stack/extconf.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: false +require_relative "../auto_ext.rb" +auto_ext(inc: true) diff --git a/ext/-test-/stack/stack.c b/ext/-test-/stack/stack.c new file mode 100644 index 0000000000..f0e65e74b2 --- /dev/null +++ b/ext/-test-/stack/stack.c @@ -0,0 +1,35 @@ +#include "ruby.h" +#include "internal/string.h" + +static VALUE +stack_overflow(VALUE self) +{ + size_t i = 0; + + while (1) { + // Allocate and touch memory to force actual stack usage: + volatile char *stack = alloca(1024); + stack[0] = (char)i; + stack[1023] = (char)i; + i++; + } + + return Qnil; +} + +static VALUE +asan_p(VALUE klass) +{ +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) + return Qtrue; +#else + return Qfalse; +#endif +} + +void +Init_stack(VALUE klass) +{ + rb_define_singleton_method(rb_cThread, "stack_overflow", stack_overflow, 0); + rb_define_singleton_method(rb_cThread, "asan?", asan_p, 0); +} diff --git a/ext/-test-/string/capacity.c b/ext/-test-/string/capacity.c index cb8d2c2b3a..33b2023fd3 100644 --- a/ext/-test-/string/capacity.c +++ b/ext/-test-/string/capacity.c @@ -4,10 +4,11 @@ static VALUE bug_str_capacity(VALUE klass, VALUE str) { - return - STR_EMBED_P(str) ? INT2FIX(RSTRING_EMBED_LEN_MAX) : \ - STR_SHARED_P(str) ? INT2FIX(0) : \ - LONG2FIX(RSTRING(str)->as.heap.aux.capa); + if (!STR_EMBED_P(str) && STR_SHARED_P(str)) { + return INT2FIX(0); + } + + return LONG2FIX(rb_str_capacity(str)); } void diff --git a/ext/-test-/string/coderange.c b/ext/-test-/string/coderange.c index bc998ca372..4197ecca9f 100644 --- a/ext/-test-/string/coderange.c +++ b/ext/-test-/string/coderange.c @@ -8,13 +8,13 @@ coderange_int2sym(int coderange) { switch (coderange) { case ENC_CODERANGE_7BIT: - return sym_7bit; + return sym_7bit; case ENC_CODERANGE_VALID: - return sym_valid; + return sym_valid; case ENC_CODERANGE_UNKNOWN: - return sym_unknown; + return sym_unknown; case ENC_CODERANGE_BROKEN: - return sym_broken; + return sym_broken; } rb_bug("wrong condition of coderange"); UNREACHABLE_RETURN(Qnil); diff --git a/ext/-test-/string/cstr.c b/ext/-test-/string/cstr.c index 4f837998d7..b0b1ef5374 100644 --- a/ext/-test-/string/cstr.c +++ b/ext/-test-/string/cstr.c @@ -42,11 +42,11 @@ bug_str_cstr_term_char(VALUE str) len = rb_enc_mbminlen(enc); c = rb_enc_precise_mbclen(s, s + len, enc); if (!MBCLEN_CHARFOUND_P(c)) { - c = (unsigned char)*s; + c = (unsigned char)*s; } else { - c = rb_enc_mbc_to_codepoint(s, s + len, enc); - if (!c) return Qnil; + c = rb_enc_mbc_to_codepoint(s, s + len, enc); + if (!c) return Qnil; } return rb_enc_uint_chr((unsigned int)c, enc); } @@ -61,14 +61,12 @@ bug_str_unterminated_substring(VALUE str, VALUE vbeg, VALUE vlen) if (RSTRING_LEN(str) < beg) rb_raise(rb_eIndexError, "beg: %ld", beg); if (RSTRING_LEN(str) < beg + len) rb_raise(rb_eIndexError, "end: %ld", beg + len); str = rb_str_new_shared(str); + RSTRING(str)->len = len; if (STR_EMBED_P(str)) { - RSTRING(str)->basic.flags &= ~RSTRING_EMBED_LEN_MASK; - RSTRING(str)->basic.flags |= len << RSTRING_EMBED_LEN_SHIFT; - memmove(RSTRING(str)->as.ary, RSTRING(str)->as.ary + beg, len); + memmove(RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.ary + beg, len); } else { - RSTRING(str)->as.heap.ptr += beg; - RSTRING(str)->as.heap.len = len; + RSTRING(str)->as.heap.ptr += beg; } return str; } @@ -100,7 +98,7 @@ bug_str_s_cstr_term_char(VALUE self, VALUE str) const int term_fill_len = (termlen);\ *term_fill_ptr = '\0';\ if (UNLIKELY(term_fill_len > 1))\ - memset(term_fill_ptr, 0, term_fill_len);\ + memset(term_fill_ptr, 0, term_fill_len);\ } while (0) static VALUE @@ -112,10 +110,10 @@ bug_str_s_cstr_noembed(VALUE self, VALUE str) Check_Type(str, T_STRING); FL_SET((str2), STR_NOEMBED); memcpy(buf, RSTRING_PTR(str), capacity); - RBASIC(str2)->flags &= ~RSTRING_EMBED_LEN_MASK; + RBASIC(str2)->flags &= ~(STR_SHARED | FL_USER5 | FL_USER6); RSTRING(str2)->as.heap.aux.capa = capacity; RSTRING(str2)->as.heap.ptr = buf; - RSTRING(str2)->as.heap.len = RSTRING_LEN(str); + RSTRING(str2)->len = RSTRING_LEN(str); TERM_FILL(RSTRING_END(str2), TERM_LEN(str)); return str2; } diff --git a/ext/-test-/string/depend b/ext/-test-/string/depend index 5eb0120578..478ae3b82b 100644 --- a/ext/-test-/string/depend +++ b/ext/-test-/string/depend @@ -16,6 +16,7 @@ capacity.o: $(hdrdir)/ruby/backward/2/stdarg.h capacity.o: $(hdrdir)/ruby/defines.h capacity.o: $(hdrdir)/ruby/encoding.h capacity.o: $(hdrdir)/ruby/intern.h +capacity.o: $(hdrdir)/ruby/internal/abi.h capacity.o: $(hdrdir)/ruby/internal/anyargs.h capacity.o: $(hdrdir)/ruby/internal/arithmetic.h capacity.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +54,7 @@ capacity.o: $(hdrdir)/ruby/internal/attr/noexcept.h capacity.o: $(hdrdir)/ruby/internal/attr/noinline.h capacity.o: $(hdrdir)/ruby/internal/attr/nonnull.h capacity.o: $(hdrdir)/ruby/internal/attr/noreturn.h +capacity.o: $(hdrdir)/ruby/internal/attr/packed_struct.h capacity.o: $(hdrdir)/ruby/internal/attr/pure.h capacity.o: $(hdrdir)/ruby/internal/attr/restrict.h capacity.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +123,6 @@ capacity.o: $(hdrdir)/ruby/internal/intern/enumerator.h capacity.o: $(hdrdir)/ruby/internal/intern/error.h capacity.o: $(hdrdir)/ruby/internal/intern/eval.h capacity.o: $(hdrdir)/ruby/internal/intern/file.h -capacity.o: $(hdrdir)/ruby/internal/intern/gc.h capacity.o: $(hdrdir)/ruby/internal/intern/hash.h capacity.o: $(hdrdir)/ruby/internal/intern/io.h capacity.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +139,7 @@ capacity.o: $(hdrdir)/ruby/internal/intern/re.h capacity.o: $(hdrdir)/ruby/internal/intern/ruby.h capacity.o: $(hdrdir)/ruby/internal/intern/select.h capacity.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +capacity.o: $(hdrdir)/ruby/internal/intern/set.h capacity.o: $(hdrdir)/ruby/internal/intern/signal.h capacity.o: $(hdrdir)/ruby/internal/intern/sprintf.h capacity.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +154,12 @@ capacity.o: $(hdrdir)/ruby/internal/memory.h capacity.o: $(hdrdir)/ruby/internal/method.h capacity.o: $(hdrdir)/ruby/internal/module.h capacity.o: $(hdrdir)/ruby/internal/newobj.h -capacity.o: $(hdrdir)/ruby/internal/rgengc.h capacity.o: $(hdrdir)/ruby/internal/scan_args.h capacity.o: $(hdrdir)/ruby/internal/special_consts.h capacity.o: $(hdrdir)/ruby/internal/static_assert.h capacity.o: $(hdrdir)/ruby/internal/stdalign.h capacity.o: $(hdrdir)/ruby/internal/stdbool.h +capacity.o: $(hdrdir)/ruby/internal/stdckdint.h capacity.o: $(hdrdir)/ruby/internal/symbol.h capacity.o: $(hdrdir)/ruby/internal/value.h capacity.o: $(hdrdir)/ruby/internal/value_type.h @@ -170,10 +172,170 @@ capacity.o: $(hdrdir)/ruby/oniguruma.h capacity.o: $(hdrdir)/ruby/ruby.h capacity.o: $(hdrdir)/ruby/st.h capacity.o: $(hdrdir)/ruby/subst.h -capacity.o: $(top_srcdir)/internal.h +capacity.o: $(top_srcdir)/encindex.h capacity.o: $(top_srcdir)/internal/compilers.h capacity.o: $(top_srcdir)/internal/string.h capacity.o: capacity.c +chilled.o: $(RUBY_EXTCONF_H) +chilled.o: $(arch_hdrdir)/ruby/config.h +chilled.o: $(hdrdir)/ruby.h +chilled.o: $(hdrdir)/ruby/assert.h +chilled.o: $(hdrdir)/ruby/backward.h +chilled.o: $(hdrdir)/ruby/backward/2/assume.h +chilled.o: $(hdrdir)/ruby/backward/2/attributes.h +chilled.o: $(hdrdir)/ruby/backward/2/bool.h +chilled.o: $(hdrdir)/ruby/backward/2/inttypes.h +chilled.o: $(hdrdir)/ruby/backward/2/limits.h +chilled.o: $(hdrdir)/ruby/backward/2/long_long.h +chilled.o: $(hdrdir)/ruby/backward/2/stdalign.h +chilled.o: $(hdrdir)/ruby/backward/2/stdarg.h +chilled.o: $(hdrdir)/ruby/defines.h +chilled.o: $(hdrdir)/ruby/intern.h +chilled.o: $(hdrdir)/ruby/internal/abi.h +chilled.o: $(hdrdir)/ruby/internal/anyargs.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/char.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/double.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/int.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/long.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/short.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +chilled.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +chilled.o: $(hdrdir)/ruby/internal/assume.h +chilled.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +chilled.o: $(hdrdir)/ruby/internal/attr/artificial.h +chilled.o: $(hdrdir)/ruby/internal/attr/cold.h +chilled.o: $(hdrdir)/ruby/internal/attr/const.h +chilled.o: $(hdrdir)/ruby/internal/attr/constexpr.h +chilled.o: $(hdrdir)/ruby/internal/attr/deprecated.h +chilled.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +chilled.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +chilled.o: $(hdrdir)/ruby/internal/attr/error.h +chilled.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +chilled.o: $(hdrdir)/ruby/internal/attr/forceinline.h +chilled.o: $(hdrdir)/ruby/internal/attr/format.h +chilled.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +chilled.o: $(hdrdir)/ruby/internal/attr/noalias.h +chilled.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +chilled.o: $(hdrdir)/ruby/internal/attr/noexcept.h +chilled.o: $(hdrdir)/ruby/internal/attr/noinline.h +chilled.o: $(hdrdir)/ruby/internal/attr/nonnull.h +chilled.o: $(hdrdir)/ruby/internal/attr/noreturn.h +chilled.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +chilled.o: $(hdrdir)/ruby/internal/attr/pure.h +chilled.o: $(hdrdir)/ruby/internal/attr/restrict.h +chilled.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +chilled.o: $(hdrdir)/ruby/internal/attr/warning.h +chilled.o: $(hdrdir)/ruby/internal/attr/weakref.h +chilled.o: $(hdrdir)/ruby/internal/cast.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +chilled.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +chilled.o: $(hdrdir)/ruby/internal/compiler_since.h +chilled.o: $(hdrdir)/ruby/internal/config.h +chilled.o: $(hdrdir)/ruby/internal/constant_p.h +chilled.o: $(hdrdir)/ruby/internal/core.h +chilled.o: $(hdrdir)/ruby/internal/core/rarray.h +chilled.o: $(hdrdir)/ruby/internal/core/rbasic.h +chilled.o: $(hdrdir)/ruby/internal/core/rbignum.h +chilled.o: $(hdrdir)/ruby/internal/core/rclass.h +chilled.o: $(hdrdir)/ruby/internal/core/rdata.h +chilled.o: $(hdrdir)/ruby/internal/core/rfile.h +chilled.o: $(hdrdir)/ruby/internal/core/rhash.h +chilled.o: $(hdrdir)/ruby/internal/core/robject.h +chilled.o: $(hdrdir)/ruby/internal/core/rregexp.h +chilled.o: $(hdrdir)/ruby/internal/core/rstring.h +chilled.o: $(hdrdir)/ruby/internal/core/rstruct.h +chilled.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +chilled.o: $(hdrdir)/ruby/internal/ctype.h +chilled.o: $(hdrdir)/ruby/internal/dllexport.h +chilled.o: $(hdrdir)/ruby/internal/dosish.h +chilled.o: $(hdrdir)/ruby/internal/error.h +chilled.o: $(hdrdir)/ruby/internal/eval.h +chilled.o: $(hdrdir)/ruby/internal/event.h +chilled.o: $(hdrdir)/ruby/internal/fl_type.h +chilled.o: $(hdrdir)/ruby/internal/gc.h +chilled.o: $(hdrdir)/ruby/internal/glob.h +chilled.o: $(hdrdir)/ruby/internal/globals.h +chilled.o: $(hdrdir)/ruby/internal/has/attribute.h +chilled.o: $(hdrdir)/ruby/internal/has/builtin.h +chilled.o: $(hdrdir)/ruby/internal/has/c_attribute.h +chilled.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +chilled.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +chilled.o: $(hdrdir)/ruby/internal/has/extension.h +chilled.o: $(hdrdir)/ruby/internal/has/feature.h +chilled.o: $(hdrdir)/ruby/internal/has/warning.h +chilled.o: $(hdrdir)/ruby/internal/intern/array.h +chilled.o: $(hdrdir)/ruby/internal/intern/bignum.h +chilled.o: $(hdrdir)/ruby/internal/intern/class.h +chilled.o: $(hdrdir)/ruby/internal/intern/compar.h +chilled.o: $(hdrdir)/ruby/internal/intern/complex.h +chilled.o: $(hdrdir)/ruby/internal/intern/cont.h +chilled.o: $(hdrdir)/ruby/internal/intern/dir.h +chilled.o: $(hdrdir)/ruby/internal/intern/enum.h +chilled.o: $(hdrdir)/ruby/internal/intern/enumerator.h +chilled.o: $(hdrdir)/ruby/internal/intern/error.h +chilled.o: $(hdrdir)/ruby/internal/intern/eval.h +chilled.o: $(hdrdir)/ruby/internal/intern/file.h +chilled.o: $(hdrdir)/ruby/internal/intern/hash.h +chilled.o: $(hdrdir)/ruby/internal/intern/io.h +chilled.o: $(hdrdir)/ruby/internal/intern/load.h +chilled.o: $(hdrdir)/ruby/internal/intern/marshal.h +chilled.o: $(hdrdir)/ruby/internal/intern/numeric.h +chilled.o: $(hdrdir)/ruby/internal/intern/object.h +chilled.o: $(hdrdir)/ruby/internal/intern/parse.h +chilled.o: $(hdrdir)/ruby/internal/intern/proc.h +chilled.o: $(hdrdir)/ruby/internal/intern/process.h +chilled.o: $(hdrdir)/ruby/internal/intern/random.h +chilled.o: $(hdrdir)/ruby/internal/intern/range.h +chilled.o: $(hdrdir)/ruby/internal/intern/rational.h +chilled.o: $(hdrdir)/ruby/internal/intern/re.h +chilled.o: $(hdrdir)/ruby/internal/intern/ruby.h +chilled.o: $(hdrdir)/ruby/internal/intern/select.h +chilled.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +chilled.o: $(hdrdir)/ruby/internal/intern/signal.h +chilled.o: $(hdrdir)/ruby/internal/intern/sprintf.h +chilled.o: $(hdrdir)/ruby/internal/intern/string.h +chilled.o: $(hdrdir)/ruby/internal/intern/struct.h +chilled.o: $(hdrdir)/ruby/internal/intern/thread.h +chilled.o: $(hdrdir)/ruby/internal/intern/time.h +chilled.o: $(hdrdir)/ruby/internal/intern/variable.h +chilled.o: $(hdrdir)/ruby/internal/intern/vm.h +chilled.o: $(hdrdir)/ruby/internal/interpreter.h +chilled.o: $(hdrdir)/ruby/internal/iterator.h +chilled.o: $(hdrdir)/ruby/internal/memory.h +chilled.o: $(hdrdir)/ruby/internal/method.h +chilled.o: $(hdrdir)/ruby/internal/module.h +chilled.o: $(hdrdir)/ruby/internal/newobj.h +chilled.o: $(hdrdir)/ruby/internal/scan_args.h +chilled.o: $(hdrdir)/ruby/internal/special_consts.h +chilled.o: $(hdrdir)/ruby/internal/static_assert.h +chilled.o: $(hdrdir)/ruby/internal/stdalign.h +chilled.o: $(hdrdir)/ruby/internal/stdbool.h +chilled.o: $(hdrdir)/ruby/internal/stdckdint.h +chilled.o: $(hdrdir)/ruby/internal/symbol.h +chilled.o: $(hdrdir)/ruby/internal/value.h +chilled.o: $(hdrdir)/ruby/internal/value_type.h +chilled.o: $(hdrdir)/ruby/internal/variable.h +chilled.o: $(hdrdir)/ruby/internal/warning_push.h +chilled.o: $(hdrdir)/ruby/internal/xmalloc.h +chilled.o: $(hdrdir)/ruby/missing.h +chilled.o: $(hdrdir)/ruby/ruby.h +chilled.o: $(hdrdir)/ruby/st.h +chilled.o: $(hdrdir)/ruby/subst.h +chilled.o: chilled.c coderange.o: $(RUBY_EXTCONF_H) coderange.o: $(arch_hdrdir)/ruby/config.h coderange.o: $(hdrdir)/ruby/assert.h @@ -181,7 +343,6 @@ coderange.o: $(hdrdir)/ruby/backward.h coderange.o: $(hdrdir)/ruby/backward/2/assume.h coderange.o: $(hdrdir)/ruby/backward/2/attributes.h coderange.o: $(hdrdir)/ruby/backward/2/bool.h -coderange.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h coderange.o: $(hdrdir)/ruby/backward/2/inttypes.h coderange.o: $(hdrdir)/ruby/backward/2/limits.h coderange.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -190,6 +351,7 @@ coderange.o: $(hdrdir)/ruby/backward/2/stdarg.h coderange.o: $(hdrdir)/ruby/defines.h coderange.o: $(hdrdir)/ruby/encoding.h coderange.o: $(hdrdir)/ruby/intern.h +coderange.o: $(hdrdir)/ruby/internal/abi.h coderange.o: $(hdrdir)/ruby/internal/anyargs.h coderange.o: $(hdrdir)/ruby/internal/arithmetic.h coderange.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -227,6 +389,7 @@ coderange.o: $(hdrdir)/ruby/internal/attr/noexcept.h coderange.o: $(hdrdir)/ruby/internal/attr/noinline.h coderange.o: $(hdrdir)/ruby/internal/attr/nonnull.h coderange.o: $(hdrdir)/ruby/internal/attr/noreturn.h +coderange.o: $(hdrdir)/ruby/internal/attr/packed_struct.h coderange.o: $(hdrdir)/ruby/internal/attr/pure.h coderange.o: $(hdrdir)/ruby/internal/attr/restrict.h coderange.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -295,7 +458,6 @@ coderange.o: $(hdrdir)/ruby/internal/intern/enumerator.h coderange.o: $(hdrdir)/ruby/internal/intern/error.h coderange.o: $(hdrdir)/ruby/internal/intern/eval.h coderange.o: $(hdrdir)/ruby/internal/intern/file.h -coderange.o: $(hdrdir)/ruby/internal/intern/gc.h coderange.o: $(hdrdir)/ruby/internal/intern/hash.h coderange.o: $(hdrdir)/ruby/internal/intern/io.h coderange.o: $(hdrdir)/ruby/internal/intern/load.h @@ -312,6 +474,7 @@ coderange.o: $(hdrdir)/ruby/internal/intern/re.h coderange.o: $(hdrdir)/ruby/internal/intern/ruby.h coderange.o: $(hdrdir)/ruby/internal/intern/select.h coderange.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +coderange.o: $(hdrdir)/ruby/internal/intern/set.h coderange.o: $(hdrdir)/ruby/internal/intern/signal.h coderange.o: $(hdrdir)/ruby/internal/intern/sprintf.h coderange.o: $(hdrdir)/ruby/internal/intern/string.h @@ -326,12 +489,12 @@ coderange.o: $(hdrdir)/ruby/internal/memory.h coderange.o: $(hdrdir)/ruby/internal/method.h coderange.o: $(hdrdir)/ruby/internal/module.h coderange.o: $(hdrdir)/ruby/internal/newobj.h -coderange.o: $(hdrdir)/ruby/internal/rgengc.h coderange.o: $(hdrdir)/ruby/internal/scan_args.h coderange.o: $(hdrdir)/ruby/internal/special_consts.h coderange.o: $(hdrdir)/ruby/internal/static_assert.h coderange.o: $(hdrdir)/ruby/internal/stdalign.h coderange.o: $(hdrdir)/ruby/internal/stdbool.h +coderange.o: $(hdrdir)/ruby/internal/stdckdint.h coderange.o: $(hdrdir)/ruby/internal/symbol.h coderange.o: $(hdrdir)/ruby/internal/value.h coderange.o: $(hdrdir)/ruby/internal/value_type.h @@ -347,7 +510,6 @@ coderange.o: $(hdrdir)/ruby/subst.h coderange.o: coderange.c cstr.o: $(RUBY_EXTCONF_H) cstr.o: $(arch_hdrdir)/ruby/config.h -cstr.o: $(hdrdir)/ruby.h cstr.o: $(hdrdir)/ruby/assert.h cstr.o: $(hdrdir)/ruby/backward.h cstr.o: $(hdrdir)/ruby/backward/2/assume.h @@ -362,6 +524,7 @@ cstr.o: $(hdrdir)/ruby/backward/2/stdarg.h cstr.o: $(hdrdir)/ruby/defines.h cstr.o: $(hdrdir)/ruby/encoding.h cstr.o: $(hdrdir)/ruby/intern.h +cstr.o: $(hdrdir)/ruby/internal/abi.h cstr.o: $(hdrdir)/ruby/internal/anyargs.h cstr.o: $(hdrdir)/ruby/internal/arithmetic.h cstr.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -399,6 +562,7 @@ cstr.o: $(hdrdir)/ruby/internal/attr/noexcept.h cstr.o: $(hdrdir)/ruby/internal/attr/noinline.h cstr.o: $(hdrdir)/ruby/internal/attr/nonnull.h cstr.o: $(hdrdir)/ruby/internal/attr/noreturn.h +cstr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h cstr.o: $(hdrdir)/ruby/internal/attr/pure.h cstr.o: $(hdrdir)/ruby/internal/attr/restrict.h cstr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -467,7 +631,6 @@ cstr.o: $(hdrdir)/ruby/internal/intern/enumerator.h cstr.o: $(hdrdir)/ruby/internal/intern/error.h cstr.o: $(hdrdir)/ruby/internal/intern/eval.h cstr.o: $(hdrdir)/ruby/internal/intern/file.h -cstr.o: $(hdrdir)/ruby/internal/intern/gc.h cstr.o: $(hdrdir)/ruby/internal/intern/hash.h cstr.o: $(hdrdir)/ruby/internal/intern/io.h cstr.o: $(hdrdir)/ruby/internal/intern/load.h @@ -484,6 +647,7 @@ cstr.o: $(hdrdir)/ruby/internal/intern/re.h cstr.o: $(hdrdir)/ruby/internal/intern/ruby.h cstr.o: $(hdrdir)/ruby/internal/intern/select.h cstr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +cstr.o: $(hdrdir)/ruby/internal/intern/set.h cstr.o: $(hdrdir)/ruby/internal/intern/signal.h cstr.o: $(hdrdir)/ruby/internal/intern/sprintf.h cstr.o: $(hdrdir)/ruby/internal/intern/string.h @@ -498,12 +662,12 @@ cstr.o: $(hdrdir)/ruby/internal/memory.h cstr.o: $(hdrdir)/ruby/internal/method.h cstr.o: $(hdrdir)/ruby/internal/module.h cstr.o: $(hdrdir)/ruby/internal/newobj.h -cstr.o: $(hdrdir)/ruby/internal/rgengc.h cstr.o: $(hdrdir)/ruby/internal/scan_args.h cstr.o: $(hdrdir)/ruby/internal/special_consts.h cstr.o: $(hdrdir)/ruby/internal/static_assert.h cstr.o: $(hdrdir)/ruby/internal/stdalign.h cstr.o: $(hdrdir)/ruby/internal/stdbool.h +cstr.o: $(hdrdir)/ruby/internal/stdckdint.h cstr.o: $(hdrdir)/ruby/internal/symbol.h cstr.o: $(hdrdir)/ruby/internal/value.h cstr.o: $(hdrdir)/ruby/internal/value_type.h @@ -516,9 +680,9 @@ cstr.o: $(hdrdir)/ruby/oniguruma.h cstr.o: $(hdrdir)/ruby/ruby.h cstr.o: $(hdrdir)/ruby/st.h cstr.o: $(hdrdir)/ruby/subst.h +cstr.o: $(top_srcdir)/encindex.h cstr.o: $(top_srcdir)/internal.h cstr.o: $(top_srcdir)/internal/compilers.h -cstr.o: $(top_srcdir)/internal/error.h cstr.o: $(top_srcdir)/internal/string.h cstr.o: cstr.c ellipsize.o: $(RUBY_EXTCONF_H) @@ -529,7 +693,6 @@ ellipsize.o: $(hdrdir)/ruby/backward.h ellipsize.o: $(hdrdir)/ruby/backward/2/assume.h ellipsize.o: $(hdrdir)/ruby/backward/2/attributes.h ellipsize.o: $(hdrdir)/ruby/backward/2/bool.h -ellipsize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h ellipsize.o: $(hdrdir)/ruby/backward/2/inttypes.h ellipsize.o: $(hdrdir)/ruby/backward/2/limits.h ellipsize.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -537,6 +700,7 @@ ellipsize.o: $(hdrdir)/ruby/backward/2/stdalign.h ellipsize.o: $(hdrdir)/ruby/backward/2/stdarg.h ellipsize.o: $(hdrdir)/ruby/defines.h ellipsize.o: $(hdrdir)/ruby/intern.h +ellipsize.o: $(hdrdir)/ruby/internal/abi.h ellipsize.o: $(hdrdir)/ruby/internal/anyargs.h ellipsize.o: $(hdrdir)/ruby/internal/arithmetic.h ellipsize.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -574,6 +738,7 @@ ellipsize.o: $(hdrdir)/ruby/internal/attr/noexcept.h ellipsize.o: $(hdrdir)/ruby/internal/attr/noinline.h ellipsize.o: $(hdrdir)/ruby/internal/attr/nonnull.h ellipsize.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ellipsize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ellipsize.o: $(hdrdir)/ruby/internal/attr/pure.h ellipsize.o: $(hdrdir)/ruby/internal/attr/restrict.h ellipsize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -633,7 +798,6 @@ ellipsize.o: $(hdrdir)/ruby/internal/intern/enumerator.h ellipsize.o: $(hdrdir)/ruby/internal/intern/error.h ellipsize.o: $(hdrdir)/ruby/internal/intern/eval.h ellipsize.o: $(hdrdir)/ruby/internal/intern/file.h -ellipsize.o: $(hdrdir)/ruby/internal/intern/gc.h ellipsize.o: $(hdrdir)/ruby/internal/intern/hash.h ellipsize.o: $(hdrdir)/ruby/internal/intern/io.h ellipsize.o: $(hdrdir)/ruby/internal/intern/load.h @@ -650,6 +814,7 @@ ellipsize.o: $(hdrdir)/ruby/internal/intern/re.h ellipsize.o: $(hdrdir)/ruby/internal/intern/ruby.h ellipsize.o: $(hdrdir)/ruby/internal/intern/select.h ellipsize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ellipsize.o: $(hdrdir)/ruby/internal/intern/set.h ellipsize.o: $(hdrdir)/ruby/internal/intern/signal.h ellipsize.o: $(hdrdir)/ruby/internal/intern/sprintf.h ellipsize.o: $(hdrdir)/ruby/internal/intern/string.h @@ -664,12 +829,12 @@ ellipsize.o: $(hdrdir)/ruby/internal/memory.h ellipsize.o: $(hdrdir)/ruby/internal/method.h ellipsize.o: $(hdrdir)/ruby/internal/module.h ellipsize.o: $(hdrdir)/ruby/internal/newobj.h -ellipsize.o: $(hdrdir)/ruby/internal/rgengc.h ellipsize.o: $(hdrdir)/ruby/internal/scan_args.h ellipsize.o: $(hdrdir)/ruby/internal/special_consts.h ellipsize.o: $(hdrdir)/ruby/internal/static_assert.h ellipsize.o: $(hdrdir)/ruby/internal/stdalign.h ellipsize.o: $(hdrdir)/ruby/internal/stdbool.h +ellipsize.o: $(hdrdir)/ruby/internal/stdckdint.h ellipsize.o: $(hdrdir)/ruby/internal/symbol.h ellipsize.o: $(hdrdir)/ruby/internal/value.h ellipsize.o: $(hdrdir)/ruby/internal/value_type.h @@ -689,7 +854,6 @@ enc_associate.o: $(hdrdir)/ruby/backward.h enc_associate.o: $(hdrdir)/ruby/backward/2/assume.h enc_associate.o: $(hdrdir)/ruby/backward/2/attributes.h enc_associate.o: $(hdrdir)/ruby/backward/2/bool.h -enc_associate.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h enc_associate.o: $(hdrdir)/ruby/backward/2/inttypes.h enc_associate.o: $(hdrdir)/ruby/backward/2/limits.h enc_associate.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -698,6 +862,7 @@ enc_associate.o: $(hdrdir)/ruby/backward/2/stdarg.h enc_associate.o: $(hdrdir)/ruby/defines.h enc_associate.o: $(hdrdir)/ruby/encoding.h enc_associate.o: $(hdrdir)/ruby/intern.h +enc_associate.o: $(hdrdir)/ruby/internal/abi.h enc_associate.o: $(hdrdir)/ruby/internal/anyargs.h enc_associate.o: $(hdrdir)/ruby/internal/arithmetic.h enc_associate.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -735,6 +900,7 @@ enc_associate.o: $(hdrdir)/ruby/internal/attr/noexcept.h enc_associate.o: $(hdrdir)/ruby/internal/attr/noinline.h enc_associate.o: $(hdrdir)/ruby/internal/attr/nonnull.h enc_associate.o: $(hdrdir)/ruby/internal/attr/noreturn.h +enc_associate.o: $(hdrdir)/ruby/internal/attr/packed_struct.h enc_associate.o: $(hdrdir)/ruby/internal/attr/pure.h enc_associate.o: $(hdrdir)/ruby/internal/attr/restrict.h enc_associate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -803,7 +969,6 @@ enc_associate.o: $(hdrdir)/ruby/internal/intern/enumerator.h enc_associate.o: $(hdrdir)/ruby/internal/intern/error.h enc_associate.o: $(hdrdir)/ruby/internal/intern/eval.h enc_associate.o: $(hdrdir)/ruby/internal/intern/file.h -enc_associate.o: $(hdrdir)/ruby/internal/intern/gc.h enc_associate.o: $(hdrdir)/ruby/internal/intern/hash.h enc_associate.o: $(hdrdir)/ruby/internal/intern/io.h enc_associate.o: $(hdrdir)/ruby/internal/intern/load.h @@ -820,6 +985,7 @@ enc_associate.o: $(hdrdir)/ruby/internal/intern/re.h enc_associate.o: $(hdrdir)/ruby/internal/intern/ruby.h enc_associate.o: $(hdrdir)/ruby/internal/intern/select.h enc_associate.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +enc_associate.o: $(hdrdir)/ruby/internal/intern/set.h enc_associate.o: $(hdrdir)/ruby/internal/intern/signal.h enc_associate.o: $(hdrdir)/ruby/internal/intern/sprintf.h enc_associate.o: $(hdrdir)/ruby/internal/intern/string.h @@ -834,12 +1000,12 @@ enc_associate.o: $(hdrdir)/ruby/internal/memory.h enc_associate.o: $(hdrdir)/ruby/internal/method.h enc_associate.o: $(hdrdir)/ruby/internal/module.h enc_associate.o: $(hdrdir)/ruby/internal/newobj.h -enc_associate.o: $(hdrdir)/ruby/internal/rgengc.h enc_associate.o: $(hdrdir)/ruby/internal/scan_args.h enc_associate.o: $(hdrdir)/ruby/internal/special_consts.h enc_associate.o: $(hdrdir)/ruby/internal/static_assert.h enc_associate.o: $(hdrdir)/ruby/internal/stdalign.h enc_associate.o: $(hdrdir)/ruby/internal/stdbool.h +enc_associate.o: $(hdrdir)/ruby/internal/stdckdint.h enc_associate.o: $(hdrdir)/ruby/internal/symbol.h enc_associate.o: $(hdrdir)/ruby/internal/value.h enc_associate.o: $(hdrdir)/ruby/internal/value_type.h @@ -853,6 +1019,179 @@ enc_associate.o: $(hdrdir)/ruby/ruby.h enc_associate.o: $(hdrdir)/ruby/st.h enc_associate.o: $(hdrdir)/ruby/subst.h enc_associate.o: enc_associate.c +enc_dummy.o: $(RUBY_EXTCONF_H) +enc_dummy.o: $(arch_hdrdir)/ruby/config.h +enc_dummy.o: $(hdrdir)/ruby.h +enc_dummy.o: $(hdrdir)/ruby/assert.h +enc_dummy.o: $(hdrdir)/ruby/backward.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/assume.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/attributes.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/bool.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/inttypes.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/limits.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/long_long.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/stdalign.h +enc_dummy.o: $(hdrdir)/ruby/backward/2/stdarg.h +enc_dummy.o: $(hdrdir)/ruby/defines.h +enc_dummy.o: $(hdrdir)/ruby/encoding.h +enc_dummy.o: $(hdrdir)/ruby/intern.h +enc_dummy.o: $(hdrdir)/ruby/internal/abi.h +enc_dummy.o: $(hdrdir)/ruby/internal/anyargs.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/char.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/double.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/int.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/long.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/short.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +enc_dummy.o: $(hdrdir)/ruby/internal/assume.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/artificial.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/cold.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/const.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/constexpr.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/deprecated.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/error.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/forceinline.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/format.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/noalias.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/noexcept.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/noinline.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/nonnull.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/noreturn.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/pure.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/restrict.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/warning.h +enc_dummy.o: $(hdrdir)/ruby/internal/attr/weakref.h +enc_dummy.o: $(hdrdir)/ruby/internal/cast.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +enc_dummy.o: $(hdrdir)/ruby/internal/compiler_since.h +enc_dummy.o: $(hdrdir)/ruby/internal/config.h +enc_dummy.o: $(hdrdir)/ruby/internal/constant_p.h +enc_dummy.o: $(hdrdir)/ruby/internal/core.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rarray.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rbasic.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rbignum.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rclass.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rdata.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rfile.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rhash.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/robject.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rregexp.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rstring.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rstruct.h +enc_dummy.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +enc_dummy.o: $(hdrdir)/ruby/internal/ctype.h +enc_dummy.o: $(hdrdir)/ruby/internal/dllexport.h +enc_dummy.o: $(hdrdir)/ruby/internal/dosish.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/coderange.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/ctype.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/encoding.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/pathname.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/re.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/string.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/symbol.h +enc_dummy.o: $(hdrdir)/ruby/internal/encoding/transcode.h +enc_dummy.o: $(hdrdir)/ruby/internal/error.h +enc_dummy.o: $(hdrdir)/ruby/internal/eval.h +enc_dummy.o: $(hdrdir)/ruby/internal/event.h +enc_dummy.o: $(hdrdir)/ruby/internal/fl_type.h +enc_dummy.o: $(hdrdir)/ruby/internal/gc.h +enc_dummy.o: $(hdrdir)/ruby/internal/glob.h +enc_dummy.o: $(hdrdir)/ruby/internal/globals.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/attribute.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/builtin.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/c_attribute.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/extension.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/feature.h +enc_dummy.o: $(hdrdir)/ruby/internal/has/warning.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/array.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/bignum.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/class.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/compar.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/complex.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/cont.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/dir.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/enum.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/enumerator.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/error.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/eval.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/file.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/hash.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/io.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/load.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/marshal.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/numeric.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/object.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/parse.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/proc.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/process.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/random.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/range.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/rational.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/re.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/ruby.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/select.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/set.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/signal.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/sprintf.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/string.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/struct.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/thread.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/time.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/variable.h +enc_dummy.o: $(hdrdir)/ruby/internal/intern/vm.h +enc_dummy.o: $(hdrdir)/ruby/internal/interpreter.h +enc_dummy.o: $(hdrdir)/ruby/internal/iterator.h +enc_dummy.o: $(hdrdir)/ruby/internal/memory.h +enc_dummy.o: $(hdrdir)/ruby/internal/method.h +enc_dummy.o: $(hdrdir)/ruby/internal/module.h +enc_dummy.o: $(hdrdir)/ruby/internal/newobj.h +enc_dummy.o: $(hdrdir)/ruby/internal/scan_args.h +enc_dummy.o: $(hdrdir)/ruby/internal/special_consts.h +enc_dummy.o: $(hdrdir)/ruby/internal/static_assert.h +enc_dummy.o: $(hdrdir)/ruby/internal/stdalign.h +enc_dummy.o: $(hdrdir)/ruby/internal/stdbool.h +enc_dummy.o: $(hdrdir)/ruby/internal/stdckdint.h +enc_dummy.o: $(hdrdir)/ruby/internal/symbol.h +enc_dummy.o: $(hdrdir)/ruby/internal/value.h +enc_dummy.o: $(hdrdir)/ruby/internal/value_type.h +enc_dummy.o: $(hdrdir)/ruby/internal/variable.h +enc_dummy.o: $(hdrdir)/ruby/internal/warning_push.h +enc_dummy.o: $(hdrdir)/ruby/internal/xmalloc.h +enc_dummy.o: $(hdrdir)/ruby/missing.h +enc_dummy.o: $(hdrdir)/ruby/onigmo.h +enc_dummy.o: $(hdrdir)/ruby/oniguruma.h +enc_dummy.o: $(hdrdir)/ruby/ruby.h +enc_dummy.o: $(hdrdir)/ruby/st.h +enc_dummy.o: $(hdrdir)/ruby/subst.h +enc_dummy.o: enc_dummy.c enc_str_buf_cat.o: $(RUBY_EXTCONF_H) enc_str_buf_cat.o: $(arch_hdrdir)/ruby/config.h enc_str_buf_cat.o: $(hdrdir)/ruby/assert.h @@ -860,7 +1199,6 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/backward.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/assume.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/attributes.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/bool.h -enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/inttypes.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/limits.h enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -869,6 +1207,7 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/backward/2/stdarg.h enc_str_buf_cat.o: $(hdrdir)/ruby/defines.h enc_str_buf_cat.o: $(hdrdir)/ruby/encoding.h enc_str_buf_cat.o: $(hdrdir)/ruby/intern.h +enc_str_buf_cat.o: $(hdrdir)/ruby/internal/abi.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/anyargs.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -906,6 +1245,7 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noexcept.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noinline.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/nonnull.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/noreturn.h +enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/packed_struct.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/pure.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/restrict.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -974,7 +1314,6 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/enumerator.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/error.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/eval.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/file.h -enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/gc.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/hash.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/io.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/load.h @@ -991,6 +1330,7 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/re.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/ruby.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/select.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/set.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/signal.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/sprintf.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1005,12 +1345,12 @@ enc_str_buf_cat.o: $(hdrdir)/ruby/internal/memory.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/method.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/module.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/newobj.h -enc_str_buf_cat.o: $(hdrdir)/ruby/internal/rgengc.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/scan_args.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/special_consts.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/static_assert.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/stdalign.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/stdbool.h +enc_str_buf_cat.o: $(hdrdir)/ruby/internal/stdckdint.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/symbol.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/value.h enc_str_buf_cat.o: $(hdrdir)/ruby/internal/value_type.h @@ -1041,6 +1381,7 @@ fstring.o: $(hdrdir)/ruby/backward/2/stdarg.h fstring.o: $(hdrdir)/ruby/defines.h fstring.o: $(hdrdir)/ruby/encoding.h fstring.o: $(hdrdir)/ruby/intern.h +fstring.o: $(hdrdir)/ruby/internal/abi.h fstring.o: $(hdrdir)/ruby/internal/anyargs.h fstring.o: $(hdrdir)/ruby/internal/arithmetic.h fstring.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1078,6 +1419,7 @@ fstring.o: $(hdrdir)/ruby/internal/attr/noexcept.h fstring.o: $(hdrdir)/ruby/internal/attr/noinline.h fstring.o: $(hdrdir)/ruby/internal/attr/nonnull.h fstring.o: $(hdrdir)/ruby/internal/attr/noreturn.h +fstring.o: $(hdrdir)/ruby/internal/attr/packed_struct.h fstring.o: $(hdrdir)/ruby/internal/attr/pure.h fstring.o: $(hdrdir)/ruby/internal/attr/restrict.h fstring.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1146,7 +1488,6 @@ fstring.o: $(hdrdir)/ruby/internal/intern/enumerator.h fstring.o: $(hdrdir)/ruby/internal/intern/error.h fstring.o: $(hdrdir)/ruby/internal/intern/eval.h fstring.o: $(hdrdir)/ruby/internal/intern/file.h -fstring.o: $(hdrdir)/ruby/internal/intern/gc.h fstring.o: $(hdrdir)/ruby/internal/intern/hash.h fstring.o: $(hdrdir)/ruby/internal/intern/io.h fstring.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1163,6 +1504,7 @@ fstring.o: $(hdrdir)/ruby/internal/intern/re.h fstring.o: $(hdrdir)/ruby/internal/intern/ruby.h fstring.o: $(hdrdir)/ruby/internal/intern/select.h fstring.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +fstring.o: $(hdrdir)/ruby/internal/intern/set.h fstring.o: $(hdrdir)/ruby/internal/intern/signal.h fstring.o: $(hdrdir)/ruby/internal/intern/sprintf.h fstring.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1177,12 +1519,12 @@ fstring.o: $(hdrdir)/ruby/internal/memory.h fstring.o: $(hdrdir)/ruby/internal/method.h fstring.o: $(hdrdir)/ruby/internal/module.h fstring.o: $(hdrdir)/ruby/internal/newobj.h -fstring.o: $(hdrdir)/ruby/internal/rgengc.h fstring.o: $(hdrdir)/ruby/internal/scan_args.h fstring.o: $(hdrdir)/ruby/internal/special_consts.h fstring.o: $(hdrdir)/ruby/internal/static_assert.h fstring.o: $(hdrdir)/ruby/internal/stdalign.h fstring.o: $(hdrdir)/ruby/internal/stdbool.h +fstring.o: $(hdrdir)/ruby/internal/stdckdint.h fstring.o: $(hdrdir)/ruby/internal/symbol.h fstring.o: $(hdrdir)/ruby/internal/value.h fstring.o: $(hdrdir)/ruby/internal/value_type.h @@ -1195,6 +1537,9 @@ fstring.o: $(hdrdir)/ruby/oniguruma.h fstring.o: $(hdrdir)/ruby/ruby.h fstring.o: $(hdrdir)/ruby/st.h fstring.o: $(hdrdir)/ruby/subst.h +fstring.o: $(top_srcdir)/encindex.h +fstring.o: $(top_srcdir)/internal/compilers.h +fstring.o: $(top_srcdir)/internal/string.h fstring.o: fstring.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h @@ -1204,7 +1549,6 @@ init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h init.o: $(hdrdir)/ruby/backward/2/inttypes.h init.o: $(hdrdir)/ruby/backward/2/limits.h init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1212,6 +1556,7 @@ init.o: $(hdrdir)/ruby/backward/2/stdalign.h init.o: $(hdrdir)/ruby/backward/2/stdarg.h init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1249,6 +1594,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1308,7 +1654,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1325,6 +1670,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1339,12 +1685,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h @@ -1364,7 +1710,6 @@ modify.o: $(hdrdir)/ruby/backward.h modify.o: $(hdrdir)/ruby/backward/2/assume.h modify.o: $(hdrdir)/ruby/backward/2/attributes.h modify.o: $(hdrdir)/ruby/backward/2/bool.h -modify.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h modify.o: $(hdrdir)/ruby/backward/2/inttypes.h modify.o: $(hdrdir)/ruby/backward/2/limits.h modify.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1372,6 +1717,7 @@ modify.o: $(hdrdir)/ruby/backward/2/stdalign.h modify.o: $(hdrdir)/ruby/backward/2/stdarg.h modify.o: $(hdrdir)/ruby/defines.h modify.o: $(hdrdir)/ruby/intern.h +modify.o: $(hdrdir)/ruby/internal/abi.h modify.o: $(hdrdir)/ruby/internal/anyargs.h modify.o: $(hdrdir)/ruby/internal/arithmetic.h modify.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1409,6 +1755,7 @@ modify.o: $(hdrdir)/ruby/internal/attr/noexcept.h modify.o: $(hdrdir)/ruby/internal/attr/noinline.h modify.o: $(hdrdir)/ruby/internal/attr/nonnull.h modify.o: $(hdrdir)/ruby/internal/attr/noreturn.h +modify.o: $(hdrdir)/ruby/internal/attr/packed_struct.h modify.o: $(hdrdir)/ruby/internal/attr/pure.h modify.o: $(hdrdir)/ruby/internal/attr/restrict.h modify.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1468,7 +1815,6 @@ modify.o: $(hdrdir)/ruby/internal/intern/enumerator.h modify.o: $(hdrdir)/ruby/internal/intern/error.h modify.o: $(hdrdir)/ruby/internal/intern/eval.h modify.o: $(hdrdir)/ruby/internal/intern/file.h -modify.o: $(hdrdir)/ruby/internal/intern/gc.h modify.o: $(hdrdir)/ruby/internal/intern/hash.h modify.o: $(hdrdir)/ruby/internal/intern/io.h modify.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1485,6 +1831,7 @@ modify.o: $(hdrdir)/ruby/internal/intern/re.h modify.o: $(hdrdir)/ruby/internal/intern/ruby.h modify.o: $(hdrdir)/ruby/internal/intern/select.h modify.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +modify.o: $(hdrdir)/ruby/internal/intern/set.h modify.o: $(hdrdir)/ruby/internal/intern/signal.h modify.o: $(hdrdir)/ruby/internal/intern/sprintf.h modify.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1499,12 +1846,12 @@ modify.o: $(hdrdir)/ruby/internal/memory.h modify.o: $(hdrdir)/ruby/internal/method.h modify.o: $(hdrdir)/ruby/internal/module.h modify.o: $(hdrdir)/ruby/internal/newobj.h -modify.o: $(hdrdir)/ruby/internal/rgengc.h modify.o: $(hdrdir)/ruby/internal/scan_args.h modify.o: $(hdrdir)/ruby/internal/special_consts.h modify.o: $(hdrdir)/ruby/internal/static_assert.h modify.o: $(hdrdir)/ruby/internal/stdalign.h modify.o: $(hdrdir)/ruby/internal/stdbool.h +modify.o: $(hdrdir)/ruby/internal/stdckdint.h modify.o: $(hdrdir)/ruby/internal/symbol.h modify.o: $(hdrdir)/ruby/internal/value.h modify.o: $(hdrdir)/ruby/internal/value_type.h @@ -1524,7 +1871,6 @@ new.o: $(hdrdir)/ruby/backward.h new.o: $(hdrdir)/ruby/backward/2/assume.h new.o: $(hdrdir)/ruby/backward/2/attributes.h new.o: $(hdrdir)/ruby/backward/2/bool.h -new.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h new.o: $(hdrdir)/ruby/backward/2/inttypes.h new.o: $(hdrdir)/ruby/backward/2/limits.h new.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1533,6 +1879,7 @@ new.o: $(hdrdir)/ruby/backward/2/stdarg.h new.o: $(hdrdir)/ruby/defines.h new.o: $(hdrdir)/ruby/encoding.h new.o: $(hdrdir)/ruby/intern.h +new.o: $(hdrdir)/ruby/internal/abi.h new.o: $(hdrdir)/ruby/internal/anyargs.h new.o: $(hdrdir)/ruby/internal/arithmetic.h new.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1570,6 +1917,7 @@ new.o: $(hdrdir)/ruby/internal/attr/noexcept.h new.o: $(hdrdir)/ruby/internal/attr/noinline.h new.o: $(hdrdir)/ruby/internal/attr/nonnull.h new.o: $(hdrdir)/ruby/internal/attr/noreturn.h +new.o: $(hdrdir)/ruby/internal/attr/packed_struct.h new.o: $(hdrdir)/ruby/internal/attr/pure.h new.o: $(hdrdir)/ruby/internal/attr/restrict.h new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1638,7 +1986,6 @@ new.o: $(hdrdir)/ruby/internal/intern/enumerator.h new.o: $(hdrdir)/ruby/internal/intern/error.h new.o: $(hdrdir)/ruby/internal/intern/eval.h new.o: $(hdrdir)/ruby/internal/intern/file.h -new.o: $(hdrdir)/ruby/internal/intern/gc.h new.o: $(hdrdir)/ruby/internal/intern/hash.h new.o: $(hdrdir)/ruby/internal/intern/io.h new.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1655,6 +2002,7 @@ new.o: $(hdrdir)/ruby/internal/intern/re.h new.o: $(hdrdir)/ruby/internal/intern/ruby.h new.o: $(hdrdir)/ruby/internal/intern/select.h new.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +new.o: $(hdrdir)/ruby/internal/intern/set.h new.o: $(hdrdir)/ruby/internal/intern/signal.h new.o: $(hdrdir)/ruby/internal/intern/sprintf.h new.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1669,12 +2017,12 @@ new.o: $(hdrdir)/ruby/internal/memory.h new.o: $(hdrdir)/ruby/internal/method.h new.o: $(hdrdir)/ruby/internal/module.h new.o: $(hdrdir)/ruby/internal/newobj.h -new.o: $(hdrdir)/ruby/internal/rgengc.h new.o: $(hdrdir)/ruby/internal/scan_args.h new.o: $(hdrdir)/ruby/internal/special_consts.h new.o: $(hdrdir)/ruby/internal/static_assert.h new.o: $(hdrdir)/ruby/internal/stdalign.h new.o: $(hdrdir)/ruby/internal/stdbool.h +new.o: $(hdrdir)/ruby/internal/stdckdint.h new.o: $(hdrdir)/ruby/internal/symbol.h new.o: $(hdrdir)/ruby/internal/value.h new.o: $(hdrdir)/ruby/internal/value_type.h @@ -1696,7 +2044,6 @@ nofree.o: $(hdrdir)/ruby/backward.h nofree.o: $(hdrdir)/ruby/backward/2/assume.h nofree.o: $(hdrdir)/ruby/backward/2/attributes.h nofree.o: $(hdrdir)/ruby/backward/2/bool.h -nofree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h nofree.o: $(hdrdir)/ruby/backward/2/inttypes.h nofree.o: $(hdrdir)/ruby/backward/2/limits.h nofree.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1704,6 +2051,7 @@ nofree.o: $(hdrdir)/ruby/backward/2/stdalign.h nofree.o: $(hdrdir)/ruby/backward/2/stdarg.h nofree.o: $(hdrdir)/ruby/defines.h nofree.o: $(hdrdir)/ruby/intern.h +nofree.o: $(hdrdir)/ruby/internal/abi.h nofree.o: $(hdrdir)/ruby/internal/anyargs.h nofree.o: $(hdrdir)/ruby/internal/arithmetic.h nofree.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1741,6 +2089,7 @@ nofree.o: $(hdrdir)/ruby/internal/attr/noexcept.h nofree.o: $(hdrdir)/ruby/internal/attr/noinline.h nofree.o: $(hdrdir)/ruby/internal/attr/nonnull.h nofree.o: $(hdrdir)/ruby/internal/attr/noreturn.h +nofree.o: $(hdrdir)/ruby/internal/attr/packed_struct.h nofree.o: $(hdrdir)/ruby/internal/attr/pure.h nofree.o: $(hdrdir)/ruby/internal/attr/restrict.h nofree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1800,7 +2149,6 @@ nofree.o: $(hdrdir)/ruby/internal/intern/enumerator.h nofree.o: $(hdrdir)/ruby/internal/intern/error.h nofree.o: $(hdrdir)/ruby/internal/intern/eval.h nofree.o: $(hdrdir)/ruby/internal/intern/file.h -nofree.o: $(hdrdir)/ruby/internal/intern/gc.h nofree.o: $(hdrdir)/ruby/internal/intern/hash.h nofree.o: $(hdrdir)/ruby/internal/intern/io.h nofree.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1817,6 +2165,7 @@ nofree.o: $(hdrdir)/ruby/internal/intern/re.h nofree.o: $(hdrdir)/ruby/internal/intern/ruby.h nofree.o: $(hdrdir)/ruby/internal/intern/select.h nofree.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +nofree.o: $(hdrdir)/ruby/internal/intern/set.h nofree.o: $(hdrdir)/ruby/internal/intern/signal.h nofree.o: $(hdrdir)/ruby/internal/intern/sprintf.h nofree.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1831,12 +2180,12 @@ nofree.o: $(hdrdir)/ruby/internal/memory.h nofree.o: $(hdrdir)/ruby/internal/method.h nofree.o: $(hdrdir)/ruby/internal/module.h nofree.o: $(hdrdir)/ruby/internal/newobj.h -nofree.o: $(hdrdir)/ruby/internal/rgengc.h nofree.o: $(hdrdir)/ruby/internal/scan_args.h nofree.o: $(hdrdir)/ruby/internal/special_consts.h nofree.o: $(hdrdir)/ruby/internal/static_assert.h nofree.o: $(hdrdir)/ruby/internal/stdalign.h nofree.o: $(hdrdir)/ruby/internal/stdbool.h +nofree.o: $(hdrdir)/ruby/internal/stdckdint.h nofree.o: $(hdrdir)/ruby/internal/symbol.h nofree.o: $(hdrdir)/ruby/internal/value.h nofree.o: $(hdrdir)/ruby/internal/value_type.h @@ -1850,13 +2199,11 @@ nofree.o: $(hdrdir)/ruby/subst.h nofree.o: nofree.c normalize.o: $(RUBY_EXTCONF_H) normalize.o: $(arch_hdrdir)/ruby/config.h -normalize.o: $(hdrdir)/ruby.h normalize.o: $(hdrdir)/ruby/assert.h normalize.o: $(hdrdir)/ruby/backward.h normalize.o: $(hdrdir)/ruby/backward/2/assume.h normalize.o: $(hdrdir)/ruby/backward/2/attributes.h normalize.o: $(hdrdir)/ruby/backward/2/bool.h -normalize.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h normalize.o: $(hdrdir)/ruby/backward/2/inttypes.h normalize.o: $(hdrdir)/ruby/backward/2/limits.h normalize.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1865,6 +2212,7 @@ normalize.o: $(hdrdir)/ruby/backward/2/stdarg.h normalize.o: $(hdrdir)/ruby/defines.h normalize.o: $(hdrdir)/ruby/encoding.h normalize.o: $(hdrdir)/ruby/intern.h +normalize.o: $(hdrdir)/ruby/internal/abi.h normalize.o: $(hdrdir)/ruby/internal/anyargs.h normalize.o: $(hdrdir)/ruby/internal/arithmetic.h normalize.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1902,6 +2250,7 @@ normalize.o: $(hdrdir)/ruby/internal/attr/noexcept.h normalize.o: $(hdrdir)/ruby/internal/attr/noinline.h normalize.o: $(hdrdir)/ruby/internal/attr/nonnull.h normalize.o: $(hdrdir)/ruby/internal/attr/noreturn.h +normalize.o: $(hdrdir)/ruby/internal/attr/packed_struct.h normalize.o: $(hdrdir)/ruby/internal/attr/pure.h normalize.o: $(hdrdir)/ruby/internal/attr/restrict.h normalize.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1970,7 +2319,6 @@ normalize.o: $(hdrdir)/ruby/internal/intern/enumerator.h normalize.o: $(hdrdir)/ruby/internal/intern/error.h normalize.o: $(hdrdir)/ruby/internal/intern/eval.h normalize.o: $(hdrdir)/ruby/internal/intern/file.h -normalize.o: $(hdrdir)/ruby/internal/intern/gc.h normalize.o: $(hdrdir)/ruby/internal/intern/hash.h normalize.o: $(hdrdir)/ruby/internal/intern/io.h normalize.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1987,6 +2335,7 @@ normalize.o: $(hdrdir)/ruby/internal/intern/re.h normalize.o: $(hdrdir)/ruby/internal/intern/ruby.h normalize.o: $(hdrdir)/ruby/internal/intern/select.h normalize.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +normalize.o: $(hdrdir)/ruby/internal/intern/set.h normalize.o: $(hdrdir)/ruby/internal/intern/signal.h normalize.o: $(hdrdir)/ruby/internal/intern/sprintf.h normalize.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2001,12 +2350,12 @@ normalize.o: $(hdrdir)/ruby/internal/memory.h normalize.o: $(hdrdir)/ruby/internal/method.h normalize.o: $(hdrdir)/ruby/internal/module.h normalize.o: $(hdrdir)/ruby/internal/newobj.h -normalize.o: $(hdrdir)/ruby/internal/rgengc.h normalize.o: $(hdrdir)/ruby/internal/scan_args.h normalize.o: $(hdrdir)/ruby/internal/special_consts.h normalize.o: $(hdrdir)/ruby/internal/static_assert.h normalize.o: $(hdrdir)/ruby/internal/stdalign.h normalize.o: $(hdrdir)/ruby/internal/stdbool.h +normalize.o: $(hdrdir)/ruby/internal/stdckdint.h normalize.o: $(hdrdir)/ruby/internal/symbol.h normalize.o: $(hdrdir)/ruby/internal/value.h normalize.o: $(hdrdir)/ruby/internal/value_type.h @@ -2019,7 +2368,6 @@ normalize.o: $(hdrdir)/ruby/oniguruma.h normalize.o: $(hdrdir)/ruby/ruby.h normalize.o: $(hdrdir)/ruby/st.h normalize.o: $(hdrdir)/ruby/subst.h -normalize.o: $(top_srcdir)/internal.h normalize.o: $(top_srcdir)/internal/file.h normalize.o: normalize.c qsort.o: $(RUBY_EXTCONF_H) @@ -2030,7 +2378,6 @@ qsort.o: $(hdrdir)/ruby/backward.h qsort.o: $(hdrdir)/ruby/backward/2/assume.h qsort.o: $(hdrdir)/ruby/backward/2/attributes.h qsort.o: $(hdrdir)/ruby/backward/2/bool.h -qsort.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h qsort.o: $(hdrdir)/ruby/backward/2/inttypes.h qsort.o: $(hdrdir)/ruby/backward/2/limits.h qsort.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -2039,6 +2386,7 @@ qsort.o: $(hdrdir)/ruby/backward/2/stdarg.h qsort.o: $(hdrdir)/ruby/defines.h qsort.o: $(hdrdir)/ruby/encoding.h qsort.o: $(hdrdir)/ruby/intern.h +qsort.o: $(hdrdir)/ruby/internal/abi.h qsort.o: $(hdrdir)/ruby/internal/anyargs.h qsort.o: $(hdrdir)/ruby/internal/arithmetic.h qsort.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2076,6 +2424,7 @@ qsort.o: $(hdrdir)/ruby/internal/attr/noexcept.h qsort.o: $(hdrdir)/ruby/internal/attr/noinline.h qsort.o: $(hdrdir)/ruby/internal/attr/nonnull.h qsort.o: $(hdrdir)/ruby/internal/attr/noreturn.h +qsort.o: $(hdrdir)/ruby/internal/attr/packed_struct.h qsort.o: $(hdrdir)/ruby/internal/attr/pure.h qsort.o: $(hdrdir)/ruby/internal/attr/restrict.h qsort.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2144,7 +2493,6 @@ qsort.o: $(hdrdir)/ruby/internal/intern/enumerator.h qsort.o: $(hdrdir)/ruby/internal/intern/error.h qsort.o: $(hdrdir)/ruby/internal/intern/eval.h qsort.o: $(hdrdir)/ruby/internal/intern/file.h -qsort.o: $(hdrdir)/ruby/internal/intern/gc.h qsort.o: $(hdrdir)/ruby/internal/intern/hash.h qsort.o: $(hdrdir)/ruby/internal/intern/io.h qsort.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2161,6 +2509,7 @@ qsort.o: $(hdrdir)/ruby/internal/intern/re.h qsort.o: $(hdrdir)/ruby/internal/intern/ruby.h qsort.o: $(hdrdir)/ruby/internal/intern/select.h qsort.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +qsort.o: $(hdrdir)/ruby/internal/intern/set.h qsort.o: $(hdrdir)/ruby/internal/intern/signal.h qsort.o: $(hdrdir)/ruby/internal/intern/sprintf.h qsort.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2175,12 +2524,12 @@ qsort.o: $(hdrdir)/ruby/internal/memory.h qsort.o: $(hdrdir)/ruby/internal/method.h qsort.o: $(hdrdir)/ruby/internal/module.h qsort.o: $(hdrdir)/ruby/internal/newobj.h -qsort.o: $(hdrdir)/ruby/internal/rgengc.h qsort.o: $(hdrdir)/ruby/internal/scan_args.h qsort.o: $(hdrdir)/ruby/internal/special_consts.h qsort.o: $(hdrdir)/ruby/internal/static_assert.h qsort.o: $(hdrdir)/ruby/internal/stdalign.h qsort.o: $(hdrdir)/ruby/internal/stdbool.h +qsort.o: $(hdrdir)/ruby/internal/stdckdint.h qsort.o: $(hdrdir)/ruby/internal/symbol.h qsort.o: $(hdrdir)/ruby/internal/value.h qsort.o: $(hdrdir)/ruby/internal/value_type.h @@ -2203,7 +2552,6 @@ rb_interned_str.o: $(hdrdir)/ruby/backward.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/assume.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/attributes.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/bool.h -rb_interned_str.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/inttypes.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/limits.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -2211,6 +2559,7 @@ rb_interned_str.o: $(hdrdir)/ruby/backward/2/stdalign.h rb_interned_str.o: $(hdrdir)/ruby/backward/2/stdarg.h rb_interned_str.o: $(hdrdir)/ruby/defines.h rb_interned_str.o: $(hdrdir)/ruby/intern.h +rb_interned_str.o: $(hdrdir)/ruby/internal/abi.h rb_interned_str.o: $(hdrdir)/ruby/internal/anyargs.h rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic.h rb_interned_str.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2248,6 +2597,7 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noexcept.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noinline.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/nonnull.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rb_interned_str.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/pure.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/restrict.h rb_interned_str.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2307,7 +2657,6 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/intern/enumerator.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/error.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/eval.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/file.h -rb_interned_str.o: $(hdrdir)/ruby/internal/intern/gc.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/hash.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/io.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2324,6 +2673,7 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/intern/re.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/ruby.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/select.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rb_interned_str.o: $(hdrdir)/ruby/internal/intern/set.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/signal.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/sprintf.h rb_interned_str.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2338,12 +2688,12 @@ rb_interned_str.o: $(hdrdir)/ruby/internal/memory.h rb_interned_str.o: $(hdrdir)/ruby/internal/method.h rb_interned_str.o: $(hdrdir)/ruby/internal/module.h rb_interned_str.o: $(hdrdir)/ruby/internal/newobj.h -rb_interned_str.o: $(hdrdir)/ruby/internal/rgengc.h rb_interned_str.o: $(hdrdir)/ruby/internal/scan_args.h rb_interned_str.o: $(hdrdir)/ruby/internal/special_consts.h rb_interned_str.o: $(hdrdir)/ruby/internal/static_assert.h rb_interned_str.o: $(hdrdir)/ruby/internal/stdalign.h rb_interned_str.o: $(hdrdir)/ruby/internal/stdbool.h +rb_interned_str.o: $(hdrdir)/ruby/internal/stdckdint.h rb_interned_str.o: $(hdrdir)/ruby/internal/symbol.h rb_interned_str.o: $(hdrdir)/ruby/internal/value.h rb_interned_str.o: $(hdrdir)/ruby/internal/value_type.h @@ -2363,7 +2713,6 @@ rb_str_dup.o: $(hdrdir)/ruby/backward.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/assume.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/attributes.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/bool.h -rb_str_dup.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/inttypes.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/limits.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -2371,6 +2720,7 @@ rb_str_dup.o: $(hdrdir)/ruby/backward/2/stdalign.h rb_str_dup.o: $(hdrdir)/ruby/backward/2/stdarg.h rb_str_dup.o: $(hdrdir)/ruby/defines.h rb_str_dup.o: $(hdrdir)/ruby/intern.h +rb_str_dup.o: $(hdrdir)/ruby/internal/abi.h rb_str_dup.o: $(hdrdir)/ruby/internal/anyargs.h rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic.h rb_str_dup.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2408,6 +2758,7 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noexcept.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noinline.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/nonnull.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rb_str_dup.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/pure.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/restrict.h rb_str_dup.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2467,7 +2818,6 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/intern/enumerator.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/error.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/eval.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/file.h -rb_str_dup.o: $(hdrdir)/ruby/internal/intern/gc.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/hash.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/io.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2484,6 +2834,7 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/intern/re.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/ruby.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/select.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rb_str_dup.o: $(hdrdir)/ruby/internal/intern/set.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/signal.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/sprintf.h rb_str_dup.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2498,12 +2849,12 @@ rb_str_dup.o: $(hdrdir)/ruby/internal/memory.h rb_str_dup.o: $(hdrdir)/ruby/internal/method.h rb_str_dup.o: $(hdrdir)/ruby/internal/module.h rb_str_dup.o: $(hdrdir)/ruby/internal/newobj.h -rb_str_dup.o: $(hdrdir)/ruby/internal/rgengc.h rb_str_dup.o: $(hdrdir)/ruby/internal/scan_args.h rb_str_dup.o: $(hdrdir)/ruby/internal/special_consts.h rb_str_dup.o: $(hdrdir)/ruby/internal/static_assert.h rb_str_dup.o: $(hdrdir)/ruby/internal/stdalign.h rb_str_dup.o: $(hdrdir)/ruby/internal/stdbool.h +rb_str_dup.o: $(hdrdir)/ruby/internal/stdckdint.h rb_str_dup.o: $(hdrdir)/ruby/internal/symbol.h rb_str_dup.o: $(hdrdir)/ruby/internal/value.h rb_str_dup.o: $(hdrdir)/ruby/internal/value_type.h @@ -2523,7 +2874,6 @@ set_len.o: $(hdrdir)/ruby/backward.h set_len.o: $(hdrdir)/ruby/backward/2/assume.h set_len.o: $(hdrdir)/ruby/backward/2/attributes.h set_len.o: $(hdrdir)/ruby/backward/2/bool.h -set_len.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h set_len.o: $(hdrdir)/ruby/backward/2/inttypes.h set_len.o: $(hdrdir)/ruby/backward/2/limits.h set_len.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -2531,6 +2881,7 @@ set_len.o: $(hdrdir)/ruby/backward/2/stdalign.h set_len.o: $(hdrdir)/ruby/backward/2/stdarg.h set_len.o: $(hdrdir)/ruby/defines.h set_len.o: $(hdrdir)/ruby/intern.h +set_len.o: $(hdrdir)/ruby/internal/abi.h set_len.o: $(hdrdir)/ruby/internal/anyargs.h set_len.o: $(hdrdir)/ruby/internal/arithmetic.h set_len.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2568,6 +2919,7 @@ set_len.o: $(hdrdir)/ruby/internal/attr/noexcept.h set_len.o: $(hdrdir)/ruby/internal/attr/noinline.h set_len.o: $(hdrdir)/ruby/internal/attr/nonnull.h set_len.o: $(hdrdir)/ruby/internal/attr/noreturn.h +set_len.o: $(hdrdir)/ruby/internal/attr/packed_struct.h set_len.o: $(hdrdir)/ruby/internal/attr/pure.h set_len.o: $(hdrdir)/ruby/internal/attr/restrict.h set_len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2627,7 +2979,6 @@ set_len.o: $(hdrdir)/ruby/internal/intern/enumerator.h set_len.o: $(hdrdir)/ruby/internal/intern/error.h set_len.o: $(hdrdir)/ruby/internal/intern/eval.h set_len.o: $(hdrdir)/ruby/internal/intern/file.h -set_len.o: $(hdrdir)/ruby/internal/intern/gc.h set_len.o: $(hdrdir)/ruby/internal/intern/hash.h set_len.o: $(hdrdir)/ruby/internal/intern/io.h set_len.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2644,6 +2995,7 @@ set_len.o: $(hdrdir)/ruby/internal/intern/re.h set_len.o: $(hdrdir)/ruby/internal/intern/ruby.h set_len.o: $(hdrdir)/ruby/internal/intern/select.h set_len.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +set_len.o: $(hdrdir)/ruby/internal/intern/set.h set_len.o: $(hdrdir)/ruby/internal/intern/signal.h set_len.o: $(hdrdir)/ruby/internal/intern/sprintf.h set_len.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2658,12 +3010,12 @@ set_len.o: $(hdrdir)/ruby/internal/memory.h set_len.o: $(hdrdir)/ruby/internal/method.h set_len.o: $(hdrdir)/ruby/internal/module.h set_len.o: $(hdrdir)/ruby/internal/newobj.h -set_len.o: $(hdrdir)/ruby/internal/rgengc.h set_len.o: $(hdrdir)/ruby/internal/scan_args.h set_len.o: $(hdrdir)/ruby/internal/special_consts.h set_len.o: $(hdrdir)/ruby/internal/static_assert.h set_len.o: $(hdrdir)/ruby/internal/stdalign.h set_len.o: $(hdrdir)/ruby/internal/stdbool.h +set_len.o: $(hdrdir)/ruby/internal/stdckdint.h set_len.o: $(hdrdir)/ruby/internal/symbol.h set_len.o: $(hdrdir)/ruby/internal/value.h set_len.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/-test-/string/enc_dummy.c b/ext/-test-/string/enc_dummy.c new file mode 100644 index 0000000000..4169552655 --- /dev/null +++ b/ext/-test-/string/enc_dummy.c @@ -0,0 +1,15 @@ +#include "ruby.h" +#include "ruby/encoding.h" + +VALUE +bug_rb_define_dummy_encoding(VALUE self, VALUE name) +{ + int idx = rb_define_dummy_encoding(RSTRING_PTR(name)); + return rb_enc_from_encoding(rb_enc_from_index(idx)); +} + +void +Init_string_enc_dummy(VALUE klass) +{ + rb_define_singleton_method(klass, "rb_define_dummy_encoding", bug_rb_define_dummy_encoding, 1); +} diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c index 2374319fe3..0b5940f28c 100644 --- a/ext/-test-/string/fstring.c +++ b/ext/-test-/string/fstring.c @@ -1,30 +1,38 @@ #include "ruby.h" #include "ruby/encoding.h" - -VALUE rb_fstring(VALUE str); +#include "internal/string.h" VALUE bug_s_fstring(VALUE self, VALUE str) { - return rb_fstring(str); + return rb_str_to_interned_str(str); +} + +VALUE +bug_s_fstring_fake_str(VALUE self) +{ + static const char literal[] = "abcdefghijklmnopqrstuvwxyz"; + struct RString fake_str = {RBASIC_INIT}; + return rb_str_to_interned_str(rb_setup_fake_str(&fake_str, literal, sizeof(literal) - 1, 0)); } VALUE bug_s_rb_enc_interned_str(VALUE self, VALUE encoding) { - return rb_enc_interned_str("foo", 3, RDATA(encoding)->data); + return rb_enc_interned_str("foo", 3, NIL_P(encoding) ? NULL : RTYPEDDATA_GET_DATA(encoding)); } VALUE bug_s_rb_enc_str_new(VALUE self, VALUE encoding) { - return rb_enc_str_new("foo", 3, RDATA(encoding)->data); + return rb_enc_str_new("foo", 3, NIL_P(encoding) ? NULL : RTYPEDDATA_GET_DATA(encoding)); } void Init_string_fstring(VALUE klass) { rb_define_singleton_method(klass, "fstring", bug_s_fstring, 1); + rb_define_singleton_method(klass, "fstring_fake_str", bug_s_fstring_fake_str, 0); rb_define_singleton_method(klass, "rb_enc_interned_str", bug_s_rb_enc_interned_str, 1); rb_define_singleton_method(klass, "rb_enc_str_new", bug_s_rb_enc_str_new, 1); } diff --git a/ext/-test-/string/qsort.c b/ext/-test-/string/qsort.c index fb7ea3d8cb..4a641e74e3 100644 --- a/ext/-test-/string/qsort.c +++ b/ext/-test-/string/qsort.c @@ -35,22 +35,22 @@ bug_str_qsort_bang(int argc, VALUE *argv, VALUE str) rb_scan_args(argc, argv, "03", &beg, &len, &size); l = RSTRING_LEN(str); if (!NIL_P(beg) && (b = NUM2INT(beg)) < 0 && (b += l) < 0) { - rb_raise(rb_eArgError, "out of bounds"); + rb_raise(rb_eArgError, "out of bounds"); } if (!NIL_P(size) && (s = NUM2INT(size)) < 0) { - rb_raise(rb_eArgError, "negative size"); + rb_raise(rb_eArgError, "negative size"); } if (NIL_P(len) || - (((n = NUM2INT(len)) < 0) ? - (rb_raise(rb_eArgError, "negative length"), 0) : - (b + n * s > l))) { - n = (l - b) / s; + (((n = NUM2INT(len)) < 0) ? + (rb_raise(rb_eArgError, "negative length"), 0) : + (b + n * s > l))) { + n = (l - b) / s; } rb_str_modify(str); d.enc = rb_enc_get(str); d.elsize = s; ruby_qsort(RSTRING_PTR(str) + b, n, s, - rb_block_given_p() ? cmp_1 : cmp_2, &d); + rb_block_given_p() ? cmp_1 : cmp_2, &d); return str; } diff --git a/ext/-test-/string/set_len.c b/ext/-test-/string/set_len.c index 219cea404c..b55ef6f469 100644 --- a/ext/-test-/string/set_len.c +++ b/ext/-test-/string/set_len.c @@ -7,8 +7,26 @@ bug_str_set_len(VALUE str, VALUE len) return str; } +static VALUE +bug_str_append(VALUE str, VALUE addendum) +{ + StringValue(addendum); + rb_str_modify_expand(str, RSTRING_LEN(addendum)); + memcpy(RSTRING_END(str), RSTRING_PTR(addendum), RSTRING_LEN(addendum)); + return str; +} + +static VALUE +bug_str_resize(VALUE str, VALUE len) +{ + rb_str_resize(str, NUM2LONG(len)); + return str; +} + void Init_string_set_len(VALUE klass) { rb_define_method(klass, "set_len", bug_str_set_len, 1); + rb_define_method(klass, "append", bug_str_append, 1); + rb_define_method(klass, "resize", bug_str_resize, 1); } diff --git a/ext/-test-/struct/data.c b/ext/-test-/struct/data.c new file mode 100644 index 0000000000..5841c342e7 --- /dev/null +++ b/ext/-test-/struct/data.c @@ -0,0 +1,13 @@ +#include "ruby.h" + +static VALUE +bug_data_new(VALUE self, VALUE super) +{ + return rb_data_define(super, "mem1", "mem2", NULL); +} + +void +Init_data(VALUE klass) +{ + rb_define_singleton_method(klass, "data_new", bug_data_new, 1); +} diff --git a/ext/-test-/struct/depend b/ext/-test-/struct/depend index aebf9a88b7..e2638e4cdf 100644 --- a/ext/-test-/struct/depend +++ b/ext/-test-/struct/depend @@ -1,7 +1,181 @@ # AUTOGENERATED DEPENDENCIES START +data.o: $(RUBY_EXTCONF_H) +data.o: $(arch_hdrdir)/ruby/config.h +data.o: $(hdrdir)/ruby.h +data.o: $(hdrdir)/ruby/assert.h +data.o: $(hdrdir)/ruby/backward.h +data.o: $(hdrdir)/ruby/backward/2/assume.h +data.o: $(hdrdir)/ruby/backward/2/attributes.h +data.o: $(hdrdir)/ruby/backward/2/bool.h +data.o: $(hdrdir)/ruby/backward/2/inttypes.h +data.o: $(hdrdir)/ruby/backward/2/limits.h +data.o: $(hdrdir)/ruby/backward/2/long_long.h +data.o: $(hdrdir)/ruby/backward/2/stdalign.h +data.o: $(hdrdir)/ruby/backward/2/stdarg.h +data.o: $(hdrdir)/ruby/defines.h +data.o: $(hdrdir)/ruby/intern.h +data.o: $(hdrdir)/ruby/internal/abi.h +data.o: $(hdrdir)/ruby/internal/anyargs.h +data.o: $(hdrdir)/ruby/internal/arithmetic.h +data.o: $(hdrdir)/ruby/internal/arithmetic/char.h +data.o: $(hdrdir)/ruby/internal/arithmetic/double.h +data.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +data.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/int.h +data.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/long.h +data.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +data.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/short.h +data.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +data.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +data.o: $(hdrdir)/ruby/internal/assume.h +data.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +data.o: $(hdrdir)/ruby/internal/attr/artificial.h +data.o: $(hdrdir)/ruby/internal/attr/cold.h +data.o: $(hdrdir)/ruby/internal/attr/const.h +data.o: $(hdrdir)/ruby/internal/attr/constexpr.h +data.o: $(hdrdir)/ruby/internal/attr/deprecated.h +data.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +data.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +data.o: $(hdrdir)/ruby/internal/attr/error.h +data.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +data.o: $(hdrdir)/ruby/internal/attr/forceinline.h +data.o: $(hdrdir)/ruby/internal/attr/format.h +data.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +data.o: $(hdrdir)/ruby/internal/attr/noalias.h +data.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +data.o: $(hdrdir)/ruby/internal/attr/noexcept.h +data.o: $(hdrdir)/ruby/internal/attr/noinline.h +data.o: $(hdrdir)/ruby/internal/attr/nonnull.h +data.o: $(hdrdir)/ruby/internal/attr/noreturn.h +data.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +data.o: $(hdrdir)/ruby/internal/attr/pure.h +data.o: $(hdrdir)/ruby/internal/attr/restrict.h +data.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +data.o: $(hdrdir)/ruby/internal/attr/warning.h +data.o: $(hdrdir)/ruby/internal/attr/weakref.h +data.o: $(hdrdir)/ruby/internal/cast.h +data.o: $(hdrdir)/ruby/internal/compiler_is.h +data.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +data.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +data.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +data.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +data.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +data.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +data.o: $(hdrdir)/ruby/internal/compiler_since.h +data.o: $(hdrdir)/ruby/internal/config.h +data.o: $(hdrdir)/ruby/internal/constant_p.h +data.o: $(hdrdir)/ruby/internal/core.h +data.o: $(hdrdir)/ruby/internal/core/rarray.h +data.o: $(hdrdir)/ruby/internal/core/rbasic.h +data.o: $(hdrdir)/ruby/internal/core/rbignum.h +data.o: $(hdrdir)/ruby/internal/core/rclass.h +data.o: $(hdrdir)/ruby/internal/core/rdata.h +data.o: $(hdrdir)/ruby/internal/core/rfile.h +data.o: $(hdrdir)/ruby/internal/core/rhash.h +data.o: $(hdrdir)/ruby/internal/core/robject.h +data.o: $(hdrdir)/ruby/internal/core/rregexp.h +data.o: $(hdrdir)/ruby/internal/core/rstring.h +data.o: $(hdrdir)/ruby/internal/core/rstruct.h +data.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +data.o: $(hdrdir)/ruby/internal/ctype.h +data.o: $(hdrdir)/ruby/internal/dllexport.h +data.o: $(hdrdir)/ruby/internal/dosish.h +data.o: $(hdrdir)/ruby/internal/error.h +data.o: $(hdrdir)/ruby/internal/eval.h +data.o: $(hdrdir)/ruby/internal/event.h +data.o: $(hdrdir)/ruby/internal/fl_type.h +data.o: $(hdrdir)/ruby/internal/gc.h +data.o: $(hdrdir)/ruby/internal/glob.h +data.o: $(hdrdir)/ruby/internal/globals.h +data.o: $(hdrdir)/ruby/internal/has/attribute.h +data.o: $(hdrdir)/ruby/internal/has/builtin.h +data.o: $(hdrdir)/ruby/internal/has/c_attribute.h +data.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +data.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +data.o: $(hdrdir)/ruby/internal/has/extension.h +data.o: $(hdrdir)/ruby/internal/has/feature.h +data.o: $(hdrdir)/ruby/internal/has/warning.h +data.o: $(hdrdir)/ruby/internal/intern/array.h +data.o: $(hdrdir)/ruby/internal/intern/bignum.h +data.o: $(hdrdir)/ruby/internal/intern/class.h +data.o: $(hdrdir)/ruby/internal/intern/compar.h +data.o: $(hdrdir)/ruby/internal/intern/complex.h +data.o: $(hdrdir)/ruby/internal/intern/cont.h +data.o: $(hdrdir)/ruby/internal/intern/dir.h +data.o: $(hdrdir)/ruby/internal/intern/enum.h +data.o: $(hdrdir)/ruby/internal/intern/enumerator.h +data.o: $(hdrdir)/ruby/internal/intern/error.h +data.o: $(hdrdir)/ruby/internal/intern/eval.h +data.o: $(hdrdir)/ruby/internal/intern/file.h +data.o: $(hdrdir)/ruby/internal/intern/hash.h +data.o: $(hdrdir)/ruby/internal/intern/io.h +data.o: $(hdrdir)/ruby/internal/intern/load.h +data.o: $(hdrdir)/ruby/internal/intern/marshal.h +data.o: $(hdrdir)/ruby/internal/intern/numeric.h +data.o: $(hdrdir)/ruby/internal/intern/object.h +data.o: $(hdrdir)/ruby/internal/intern/parse.h +data.o: $(hdrdir)/ruby/internal/intern/proc.h +data.o: $(hdrdir)/ruby/internal/intern/process.h +data.o: $(hdrdir)/ruby/internal/intern/random.h +data.o: $(hdrdir)/ruby/internal/intern/range.h +data.o: $(hdrdir)/ruby/internal/intern/rational.h +data.o: $(hdrdir)/ruby/internal/intern/re.h +data.o: $(hdrdir)/ruby/internal/intern/ruby.h +data.o: $(hdrdir)/ruby/internal/intern/select.h +data.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +data.o: $(hdrdir)/ruby/internal/intern/set.h +data.o: $(hdrdir)/ruby/internal/intern/signal.h +data.o: $(hdrdir)/ruby/internal/intern/sprintf.h +data.o: $(hdrdir)/ruby/internal/intern/string.h +data.o: $(hdrdir)/ruby/internal/intern/struct.h +data.o: $(hdrdir)/ruby/internal/intern/thread.h +data.o: $(hdrdir)/ruby/internal/intern/time.h +data.o: $(hdrdir)/ruby/internal/intern/variable.h +data.o: $(hdrdir)/ruby/internal/intern/vm.h +data.o: $(hdrdir)/ruby/internal/interpreter.h +data.o: $(hdrdir)/ruby/internal/iterator.h +data.o: $(hdrdir)/ruby/internal/memory.h +data.o: $(hdrdir)/ruby/internal/method.h +data.o: $(hdrdir)/ruby/internal/module.h +data.o: $(hdrdir)/ruby/internal/newobj.h +data.o: $(hdrdir)/ruby/internal/scan_args.h +data.o: $(hdrdir)/ruby/internal/special_consts.h +data.o: $(hdrdir)/ruby/internal/static_assert.h +data.o: $(hdrdir)/ruby/internal/stdalign.h +data.o: $(hdrdir)/ruby/internal/stdbool.h +data.o: $(hdrdir)/ruby/internal/stdckdint.h +data.o: $(hdrdir)/ruby/internal/symbol.h +data.o: $(hdrdir)/ruby/internal/value.h +data.o: $(hdrdir)/ruby/internal/value_type.h +data.o: $(hdrdir)/ruby/internal/variable.h +data.o: $(hdrdir)/ruby/internal/warning_push.h +data.o: $(hdrdir)/ruby/internal/xmalloc.h +data.o: $(hdrdir)/ruby/missing.h +data.o: $(hdrdir)/ruby/ruby.h +data.o: $(hdrdir)/ruby/st.h +data.o: $(hdrdir)/ruby/subst.h +data.o: data.c duplicate.o: $(RUBY_EXTCONF_H) duplicate.o: $(arch_hdrdir)/ruby/config.h duplicate.o: $(hdrdir)/ruby.h +duplicate.o: $(hdrdir)/ruby/assert.h +duplicate.o: $(hdrdir)/ruby/backward.h +duplicate.o: $(hdrdir)/ruby/backward/2/assume.h +duplicate.o: $(hdrdir)/ruby/backward/2/attributes.h +duplicate.o: $(hdrdir)/ruby/backward/2/bool.h +duplicate.o: $(hdrdir)/ruby/backward/2/inttypes.h +duplicate.o: $(hdrdir)/ruby/backward/2/limits.h +duplicate.o: $(hdrdir)/ruby/backward/2/long_long.h +duplicate.o: $(hdrdir)/ruby/backward/2/stdalign.h +duplicate.o: $(hdrdir)/ruby/backward/2/stdarg.h +duplicate.o: $(hdrdir)/ruby/defines.h +duplicate.o: $(hdrdir)/ruby/intern.h +duplicate.o: $(hdrdir)/ruby/internal/abi.h duplicate.o: $(hdrdir)/ruby/internal/anyargs.h duplicate.o: $(hdrdir)/ruby/internal/arithmetic.h duplicate.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +213,7 @@ duplicate.o: $(hdrdir)/ruby/internal/attr/noexcept.h duplicate.o: $(hdrdir)/ruby/internal/attr/noinline.h duplicate.o: $(hdrdir)/ruby/internal/attr/nonnull.h duplicate.o: $(hdrdir)/ruby/internal/attr/noreturn.h +duplicate.o: $(hdrdir)/ruby/internal/attr/packed_struct.h duplicate.o: $(hdrdir)/ruby/internal/attr/pure.h duplicate.o: $(hdrdir)/ruby/internal/attr/restrict.h duplicate.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +273,6 @@ duplicate.o: $(hdrdir)/ruby/internal/intern/enumerator.h duplicate.o: $(hdrdir)/ruby/internal/intern/error.h duplicate.o: $(hdrdir)/ruby/internal/intern/eval.h duplicate.o: $(hdrdir)/ruby/internal/intern/file.h -duplicate.o: $(hdrdir)/ruby/internal/intern/gc.h duplicate.o: $(hdrdir)/ruby/internal/intern/hash.h duplicate.o: $(hdrdir)/ruby/internal/intern/io.h duplicate.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +289,7 @@ duplicate.o: $(hdrdir)/ruby/internal/intern/re.h duplicate.o: $(hdrdir)/ruby/internal/intern/ruby.h duplicate.o: $(hdrdir)/ruby/internal/intern/select.h duplicate.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +duplicate.o: $(hdrdir)/ruby/internal/intern/set.h duplicate.o: $(hdrdir)/ruby/internal/intern/signal.h duplicate.o: $(hdrdir)/ruby/internal/intern/sprintf.h duplicate.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +304,18 @@ duplicate.o: $(hdrdir)/ruby/internal/memory.h duplicate.o: $(hdrdir)/ruby/internal/method.h duplicate.o: $(hdrdir)/ruby/internal/module.h duplicate.o: $(hdrdir)/ruby/internal/newobj.h -duplicate.o: $(hdrdir)/ruby/internal/rgengc.h duplicate.o: $(hdrdir)/ruby/internal/scan_args.h duplicate.o: $(hdrdir)/ruby/internal/special_consts.h duplicate.o: $(hdrdir)/ruby/internal/static_assert.h duplicate.o: $(hdrdir)/ruby/internal/stdalign.h duplicate.o: $(hdrdir)/ruby/internal/stdbool.h +duplicate.o: $(hdrdir)/ruby/internal/stdckdint.h duplicate.o: $(hdrdir)/ruby/internal/symbol.h duplicate.o: $(hdrdir)/ruby/internal/value.h duplicate.o: $(hdrdir)/ruby/internal/value_type.h duplicate.o: $(hdrdir)/ruby/internal/variable.h duplicate.o: $(hdrdir)/ruby/internal/warning_push.h duplicate.o: $(hdrdir)/ruby/internal/xmalloc.h -duplicate.o: $(hdrdir)/ruby/assert.h -duplicate.o: $(hdrdir)/ruby/backward.h -duplicate.o: $(hdrdir)/ruby/backward/2/assume.h -duplicate.o: $(hdrdir)/ruby/backward/2/attributes.h -duplicate.o: $(hdrdir)/ruby/backward/2/bool.h -duplicate.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -duplicate.o: $(hdrdir)/ruby/backward/2/inttypes.h -duplicate.o: $(hdrdir)/ruby/backward/2/limits.h -duplicate.o: $(hdrdir)/ruby/backward/2/long_long.h -duplicate.o: $(hdrdir)/ruby/backward/2/stdalign.h -duplicate.o: $(hdrdir)/ruby/backward/2/stdarg.h -duplicate.o: $(hdrdir)/ruby/defines.h -duplicate.o: $(hdrdir)/ruby/intern.h duplicate.o: $(hdrdir)/ruby/missing.h duplicate.o: $(hdrdir)/ruby/ruby.h duplicate.o: $(hdrdir)/ruby/st.h @@ -162,6 +324,19 @@ duplicate.o: duplicate.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +374,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +434,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +450,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +465,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -322,6 +485,19 @@ init.o: init.c len.o: $(RUBY_EXTCONF_H) len.o: $(arch_hdrdir)/ruby/config.h len.o: $(hdrdir)/ruby.h +len.o: $(hdrdir)/ruby/assert.h +len.o: $(hdrdir)/ruby/backward.h +len.o: $(hdrdir)/ruby/backward/2/assume.h +len.o: $(hdrdir)/ruby/backward/2/attributes.h +len.o: $(hdrdir)/ruby/backward/2/bool.h +len.o: $(hdrdir)/ruby/backward/2/inttypes.h +len.o: $(hdrdir)/ruby/backward/2/limits.h +len.o: $(hdrdir)/ruby/backward/2/long_long.h +len.o: $(hdrdir)/ruby/backward/2/stdalign.h +len.o: $(hdrdir)/ruby/backward/2/stdarg.h +len.o: $(hdrdir)/ruby/defines.h +len.o: $(hdrdir)/ruby/intern.h +len.o: $(hdrdir)/ruby/internal/abi.h len.o: $(hdrdir)/ruby/internal/anyargs.h len.o: $(hdrdir)/ruby/internal/arithmetic.h len.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -359,6 +535,7 @@ len.o: $(hdrdir)/ruby/internal/attr/noexcept.h len.o: $(hdrdir)/ruby/internal/attr/noinline.h len.o: $(hdrdir)/ruby/internal/attr/nonnull.h len.o: $(hdrdir)/ruby/internal/attr/noreturn.h +len.o: $(hdrdir)/ruby/internal/attr/packed_struct.h len.o: $(hdrdir)/ruby/internal/attr/pure.h len.o: $(hdrdir)/ruby/internal/attr/restrict.h len.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -418,7 +595,6 @@ len.o: $(hdrdir)/ruby/internal/intern/enumerator.h len.o: $(hdrdir)/ruby/internal/intern/error.h len.o: $(hdrdir)/ruby/internal/intern/eval.h len.o: $(hdrdir)/ruby/internal/intern/file.h -len.o: $(hdrdir)/ruby/internal/intern/gc.h len.o: $(hdrdir)/ruby/internal/intern/hash.h len.o: $(hdrdir)/ruby/internal/intern/io.h len.o: $(hdrdir)/ruby/internal/intern/load.h @@ -435,6 +611,7 @@ len.o: $(hdrdir)/ruby/internal/intern/re.h len.o: $(hdrdir)/ruby/internal/intern/ruby.h len.o: $(hdrdir)/ruby/internal/intern/select.h len.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +len.o: $(hdrdir)/ruby/internal/intern/set.h len.o: $(hdrdir)/ruby/internal/intern/signal.h len.o: $(hdrdir)/ruby/internal/intern/sprintf.h len.o: $(hdrdir)/ruby/internal/intern/string.h @@ -449,31 +626,18 @@ len.o: $(hdrdir)/ruby/internal/memory.h len.o: $(hdrdir)/ruby/internal/method.h len.o: $(hdrdir)/ruby/internal/module.h len.o: $(hdrdir)/ruby/internal/newobj.h -len.o: $(hdrdir)/ruby/internal/rgengc.h len.o: $(hdrdir)/ruby/internal/scan_args.h len.o: $(hdrdir)/ruby/internal/special_consts.h len.o: $(hdrdir)/ruby/internal/static_assert.h len.o: $(hdrdir)/ruby/internal/stdalign.h len.o: $(hdrdir)/ruby/internal/stdbool.h +len.o: $(hdrdir)/ruby/internal/stdckdint.h len.o: $(hdrdir)/ruby/internal/symbol.h len.o: $(hdrdir)/ruby/internal/value.h len.o: $(hdrdir)/ruby/internal/value_type.h len.o: $(hdrdir)/ruby/internal/variable.h len.o: $(hdrdir)/ruby/internal/warning_push.h len.o: $(hdrdir)/ruby/internal/xmalloc.h -len.o: $(hdrdir)/ruby/assert.h -len.o: $(hdrdir)/ruby/backward.h -len.o: $(hdrdir)/ruby/backward/2/assume.h -len.o: $(hdrdir)/ruby/backward/2/attributes.h -len.o: $(hdrdir)/ruby/backward/2/bool.h -len.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -len.o: $(hdrdir)/ruby/backward/2/inttypes.h -len.o: $(hdrdir)/ruby/backward/2/limits.h -len.o: $(hdrdir)/ruby/backward/2/long_long.h -len.o: $(hdrdir)/ruby/backward/2/stdalign.h -len.o: $(hdrdir)/ruby/backward/2/stdarg.h -len.o: $(hdrdir)/ruby/defines.h -len.o: $(hdrdir)/ruby/intern.h len.o: $(hdrdir)/ruby/missing.h len.o: $(hdrdir)/ruby/ruby.h len.o: $(hdrdir)/ruby/st.h @@ -482,6 +646,19 @@ len.o: len.c member.o: $(RUBY_EXTCONF_H) member.o: $(arch_hdrdir)/ruby/config.h member.o: $(hdrdir)/ruby.h +member.o: $(hdrdir)/ruby/assert.h +member.o: $(hdrdir)/ruby/backward.h +member.o: $(hdrdir)/ruby/backward/2/assume.h +member.o: $(hdrdir)/ruby/backward/2/attributes.h +member.o: $(hdrdir)/ruby/backward/2/bool.h +member.o: $(hdrdir)/ruby/backward/2/inttypes.h +member.o: $(hdrdir)/ruby/backward/2/limits.h +member.o: $(hdrdir)/ruby/backward/2/long_long.h +member.o: $(hdrdir)/ruby/backward/2/stdalign.h +member.o: $(hdrdir)/ruby/backward/2/stdarg.h +member.o: $(hdrdir)/ruby/defines.h +member.o: $(hdrdir)/ruby/intern.h +member.o: $(hdrdir)/ruby/internal/abi.h member.o: $(hdrdir)/ruby/internal/anyargs.h member.o: $(hdrdir)/ruby/internal/arithmetic.h member.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -519,6 +696,7 @@ member.o: $(hdrdir)/ruby/internal/attr/noexcept.h member.o: $(hdrdir)/ruby/internal/attr/noinline.h member.o: $(hdrdir)/ruby/internal/attr/nonnull.h member.o: $(hdrdir)/ruby/internal/attr/noreturn.h +member.o: $(hdrdir)/ruby/internal/attr/packed_struct.h member.o: $(hdrdir)/ruby/internal/attr/pure.h member.o: $(hdrdir)/ruby/internal/attr/restrict.h member.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -578,7 +756,6 @@ member.o: $(hdrdir)/ruby/internal/intern/enumerator.h member.o: $(hdrdir)/ruby/internal/intern/error.h member.o: $(hdrdir)/ruby/internal/intern/eval.h member.o: $(hdrdir)/ruby/internal/intern/file.h -member.o: $(hdrdir)/ruby/internal/intern/gc.h member.o: $(hdrdir)/ruby/internal/intern/hash.h member.o: $(hdrdir)/ruby/internal/intern/io.h member.o: $(hdrdir)/ruby/internal/intern/load.h @@ -595,6 +772,7 @@ member.o: $(hdrdir)/ruby/internal/intern/re.h member.o: $(hdrdir)/ruby/internal/intern/ruby.h member.o: $(hdrdir)/ruby/internal/intern/select.h member.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +member.o: $(hdrdir)/ruby/internal/intern/set.h member.o: $(hdrdir)/ruby/internal/intern/signal.h member.o: $(hdrdir)/ruby/internal/intern/sprintf.h member.o: $(hdrdir)/ruby/internal/intern/string.h @@ -609,31 +787,18 @@ member.o: $(hdrdir)/ruby/internal/memory.h member.o: $(hdrdir)/ruby/internal/method.h member.o: $(hdrdir)/ruby/internal/module.h member.o: $(hdrdir)/ruby/internal/newobj.h -member.o: $(hdrdir)/ruby/internal/rgengc.h member.o: $(hdrdir)/ruby/internal/scan_args.h member.o: $(hdrdir)/ruby/internal/special_consts.h member.o: $(hdrdir)/ruby/internal/static_assert.h member.o: $(hdrdir)/ruby/internal/stdalign.h member.o: $(hdrdir)/ruby/internal/stdbool.h +member.o: $(hdrdir)/ruby/internal/stdckdint.h member.o: $(hdrdir)/ruby/internal/symbol.h member.o: $(hdrdir)/ruby/internal/value.h member.o: $(hdrdir)/ruby/internal/value_type.h member.o: $(hdrdir)/ruby/internal/variable.h member.o: $(hdrdir)/ruby/internal/warning_push.h member.o: $(hdrdir)/ruby/internal/xmalloc.h -member.o: $(hdrdir)/ruby/assert.h -member.o: $(hdrdir)/ruby/backward.h -member.o: $(hdrdir)/ruby/backward/2/assume.h -member.o: $(hdrdir)/ruby/backward/2/attributes.h -member.o: $(hdrdir)/ruby/backward/2/bool.h -member.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -member.o: $(hdrdir)/ruby/backward/2/inttypes.h -member.o: $(hdrdir)/ruby/backward/2/limits.h -member.o: $(hdrdir)/ruby/backward/2/long_long.h -member.o: $(hdrdir)/ruby/backward/2/stdalign.h -member.o: $(hdrdir)/ruby/backward/2/stdarg.h -member.o: $(hdrdir)/ruby/defines.h -member.o: $(hdrdir)/ruby/intern.h member.o: $(hdrdir)/ruby/missing.h member.o: $(hdrdir)/ruby/ruby.h member.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/struct/member.c b/ext/-test-/struct/member.c index 1d404039b4..29ddff93e8 100644 --- a/ext/-test-/struct/member.c +++ b/ext/-test-/struct/member.c @@ -6,7 +6,7 @@ bug_struct_get(VALUE obj, VALUE name) ID id = rb_check_id(&name); if (!id) { - rb_name_error_str(name, "`%"PRIsVALUE"' is not a struct member", name); + rb_name_error_str(name, "'%"PRIsVALUE"' is not a struct member", name); } return rb_struct_getmember(obj, id); } diff --git a/ext/-test-/symbol/depend b/ext/-test-/symbol/depend index 9b75e866da..b1d8e1aab6 100644 --- a/ext/-test-/symbol/depend +++ b/ext/-test-/symbol/depend @@ -2,6 +2,19 @@ init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,19 @@ init.o: init.c type.o: $(RUBY_EXTCONF_H) type.o: $(arch_hdrdir)/ruby/config.h type.o: $(hdrdir)/ruby.h +type.o: $(hdrdir)/ruby/assert.h +type.o: $(hdrdir)/ruby/backward.h +type.o: $(hdrdir)/ruby/backward/2/assume.h +type.o: $(hdrdir)/ruby/backward/2/attributes.h +type.o: $(hdrdir)/ruby/backward/2/bool.h +type.o: $(hdrdir)/ruby/backward/2/inttypes.h +type.o: $(hdrdir)/ruby/backward/2/limits.h +type.o: $(hdrdir)/ruby/backward/2/long_long.h +type.o: $(hdrdir)/ruby/backward/2/stdalign.h +type.o: $(hdrdir)/ruby/backward/2/stdarg.h +type.o: $(hdrdir)/ruby/defines.h +type.o: $(hdrdir)/ruby/intern.h +type.o: $(hdrdir)/ruby/internal/abi.h type.o: $(hdrdir)/ruby/internal/anyargs.h type.o: $(hdrdir)/ruby/internal/arithmetic.h type.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +213,7 @@ type.o: $(hdrdir)/ruby/internal/attr/noexcept.h type.o: $(hdrdir)/ruby/internal/attr/noinline.h type.o: $(hdrdir)/ruby/internal/attr/nonnull.h type.o: $(hdrdir)/ruby/internal/attr/noreturn.h +type.o: $(hdrdir)/ruby/internal/attr/packed_struct.h type.o: $(hdrdir)/ruby/internal/attr/pure.h type.o: $(hdrdir)/ruby/internal/attr/restrict.h type.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +273,6 @@ type.o: $(hdrdir)/ruby/internal/intern/enumerator.h type.o: $(hdrdir)/ruby/internal/intern/error.h type.o: $(hdrdir)/ruby/internal/intern/eval.h type.o: $(hdrdir)/ruby/internal/intern/file.h -type.o: $(hdrdir)/ruby/internal/intern/gc.h type.o: $(hdrdir)/ruby/internal/intern/hash.h type.o: $(hdrdir)/ruby/internal/intern/io.h type.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +289,7 @@ type.o: $(hdrdir)/ruby/internal/intern/re.h type.o: $(hdrdir)/ruby/internal/intern/ruby.h type.o: $(hdrdir)/ruby/internal/intern/select.h type.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +type.o: $(hdrdir)/ruby/internal/intern/set.h type.o: $(hdrdir)/ruby/internal/intern/signal.h type.o: $(hdrdir)/ruby/internal/intern/sprintf.h type.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +304,18 @@ type.o: $(hdrdir)/ruby/internal/memory.h type.o: $(hdrdir)/ruby/internal/method.h type.o: $(hdrdir)/ruby/internal/module.h type.o: $(hdrdir)/ruby/internal/newobj.h -type.o: $(hdrdir)/ruby/internal/rgengc.h type.o: $(hdrdir)/ruby/internal/scan_args.h type.o: $(hdrdir)/ruby/internal/special_consts.h type.o: $(hdrdir)/ruby/internal/static_assert.h type.o: $(hdrdir)/ruby/internal/stdalign.h type.o: $(hdrdir)/ruby/internal/stdbool.h +type.o: $(hdrdir)/ruby/internal/stdckdint.h type.o: $(hdrdir)/ruby/internal/symbol.h type.o: $(hdrdir)/ruby/internal/value.h type.o: $(hdrdir)/ruby/internal/value_type.h type.o: $(hdrdir)/ruby/internal/variable.h type.o: $(hdrdir)/ruby/internal/warning_push.h type.o: $(hdrdir)/ruby/internal/xmalloc.h -type.o: $(hdrdir)/ruby/assert.h -type.o: $(hdrdir)/ruby/backward.h -type.o: $(hdrdir)/ruby/backward/2/assume.h -type.o: $(hdrdir)/ruby/backward/2/attributes.h -type.o: $(hdrdir)/ruby/backward/2/bool.h -type.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -type.o: $(hdrdir)/ruby/backward/2/inttypes.h -type.o: $(hdrdir)/ruby/backward/2/limits.h -type.o: $(hdrdir)/ruby/backward/2/long_long.h -type.o: $(hdrdir)/ruby/backward/2/stdalign.h -type.o: $(hdrdir)/ruby/backward/2/stdarg.h -type.o: $(hdrdir)/ruby/defines.h -type.o: $(hdrdir)/ruby/intern.h type.o: $(hdrdir)/ruby/missing.h type.o: $(hdrdir)/ruby/ruby.h type.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/symbol/type.c b/ext/-test-/symbol/type.c index e51e09eb26..8d0e647340 100644 --- a/ext/-test-/symbol/type.c +++ b/ext/-test-/symbol/type.c @@ -2,12 +2,12 @@ #ifdef HAVE_RB_IS_CONST_NAME # define get_symbol_type(type, t, name) do { \ - ID id = rb_check_id(&name); \ - t = (id ? rb_is_##type##_id(id) : rb_is_##type##_name(name)); \ + ID id = rb_check_id(&name); \ + t = (id ? rb_is_##type##_id(id) : rb_is_##type##_name(name)); \ } while (0) #else # define get_symbol_type(type, t, name) do { \ - t = rb_is_##type##_id(rb_to_id(name)); \ + t = rb_is_##type##_id(rb_to_id(name)); \ } while (0) #endif diff --git a/ext/-test-/thread/id/depend b/ext/-test-/thread/id/depend new file mode 100644 index 0000000000..6b76b31ddc --- /dev/null +++ b/ext/-test-/thread/id/depend @@ -0,0 +1,163 @@ +# AUTOGENERATED DEPENDENCIES START +id.o: $(RUBY_EXTCONF_H) +id.o: $(arch_hdrdir)/ruby/config.h +id.o: $(hdrdir)/ruby.h +id.o: $(hdrdir)/ruby/assert.h +id.o: $(hdrdir)/ruby/backward.h +id.o: $(hdrdir)/ruby/backward/2/assume.h +id.o: $(hdrdir)/ruby/backward/2/attributes.h +id.o: $(hdrdir)/ruby/backward/2/bool.h +id.o: $(hdrdir)/ruby/backward/2/inttypes.h +id.o: $(hdrdir)/ruby/backward/2/limits.h +id.o: $(hdrdir)/ruby/backward/2/long_long.h +id.o: $(hdrdir)/ruby/backward/2/stdalign.h +id.o: $(hdrdir)/ruby/backward/2/stdarg.h +id.o: $(hdrdir)/ruby/defines.h +id.o: $(hdrdir)/ruby/intern.h +id.o: $(hdrdir)/ruby/internal/abi.h +id.o: $(hdrdir)/ruby/internal/anyargs.h +id.o: $(hdrdir)/ruby/internal/arithmetic.h +id.o: $(hdrdir)/ruby/internal/arithmetic/char.h +id.o: $(hdrdir)/ruby/internal/arithmetic/double.h +id.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +id.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/int.h +id.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/long.h +id.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +id.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/short.h +id.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +id.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +id.o: $(hdrdir)/ruby/internal/assume.h +id.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +id.o: $(hdrdir)/ruby/internal/attr/artificial.h +id.o: $(hdrdir)/ruby/internal/attr/cold.h +id.o: $(hdrdir)/ruby/internal/attr/const.h +id.o: $(hdrdir)/ruby/internal/attr/constexpr.h +id.o: $(hdrdir)/ruby/internal/attr/deprecated.h +id.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +id.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +id.o: $(hdrdir)/ruby/internal/attr/error.h +id.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +id.o: $(hdrdir)/ruby/internal/attr/forceinline.h +id.o: $(hdrdir)/ruby/internal/attr/format.h +id.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +id.o: $(hdrdir)/ruby/internal/attr/noalias.h +id.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +id.o: $(hdrdir)/ruby/internal/attr/noexcept.h +id.o: $(hdrdir)/ruby/internal/attr/noinline.h +id.o: $(hdrdir)/ruby/internal/attr/nonnull.h +id.o: $(hdrdir)/ruby/internal/attr/noreturn.h +id.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +id.o: $(hdrdir)/ruby/internal/attr/pure.h +id.o: $(hdrdir)/ruby/internal/attr/restrict.h +id.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +id.o: $(hdrdir)/ruby/internal/attr/warning.h +id.o: $(hdrdir)/ruby/internal/attr/weakref.h +id.o: $(hdrdir)/ruby/internal/cast.h +id.o: $(hdrdir)/ruby/internal/compiler_is.h +id.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +id.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +id.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +id.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +id.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +id.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +id.o: $(hdrdir)/ruby/internal/compiler_since.h +id.o: $(hdrdir)/ruby/internal/config.h +id.o: $(hdrdir)/ruby/internal/constant_p.h +id.o: $(hdrdir)/ruby/internal/core.h +id.o: $(hdrdir)/ruby/internal/core/rarray.h +id.o: $(hdrdir)/ruby/internal/core/rbasic.h +id.o: $(hdrdir)/ruby/internal/core/rbignum.h +id.o: $(hdrdir)/ruby/internal/core/rclass.h +id.o: $(hdrdir)/ruby/internal/core/rdata.h +id.o: $(hdrdir)/ruby/internal/core/rfile.h +id.o: $(hdrdir)/ruby/internal/core/rhash.h +id.o: $(hdrdir)/ruby/internal/core/robject.h +id.o: $(hdrdir)/ruby/internal/core/rregexp.h +id.o: $(hdrdir)/ruby/internal/core/rstring.h +id.o: $(hdrdir)/ruby/internal/core/rstruct.h +id.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +id.o: $(hdrdir)/ruby/internal/ctype.h +id.o: $(hdrdir)/ruby/internal/dllexport.h +id.o: $(hdrdir)/ruby/internal/dosish.h +id.o: $(hdrdir)/ruby/internal/error.h +id.o: $(hdrdir)/ruby/internal/eval.h +id.o: $(hdrdir)/ruby/internal/event.h +id.o: $(hdrdir)/ruby/internal/fl_type.h +id.o: $(hdrdir)/ruby/internal/gc.h +id.o: $(hdrdir)/ruby/internal/glob.h +id.o: $(hdrdir)/ruby/internal/globals.h +id.o: $(hdrdir)/ruby/internal/has/attribute.h +id.o: $(hdrdir)/ruby/internal/has/builtin.h +id.o: $(hdrdir)/ruby/internal/has/c_attribute.h +id.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +id.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +id.o: $(hdrdir)/ruby/internal/has/extension.h +id.o: $(hdrdir)/ruby/internal/has/feature.h +id.o: $(hdrdir)/ruby/internal/has/warning.h +id.o: $(hdrdir)/ruby/internal/intern/array.h +id.o: $(hdrdir)/ruby/internal/intern/bignum.h +id.o: $(hdrdir)/ruby/internal/intern/class.h +id.o: $(hdrdir)/ruby/internal/intern/compar.h +id.o: $(hdrdir)/ruby/internal/intern/complex.h +id.o: $(hdrdir)/ruby/internal/intern/cont.h +id.o: $(hdrdir)/ruby/internal/intern/dir.h +id.o: $(hdrdir)/ruby/internal/intern/enum.h +id.o: $(hdrdir)/ruby/internal/intern/enumerator.h +id.o: $(hdrdir)/ruby/internal/intern/error.h +id.o: $(hdrdir)/ruby/internal/intern/eval.h +id.o: $(hdrdir)/ruby/internal/intern/file.h +id.o: $(hdrdir)/ruby/internal/intern/hash.h +id.o: $(hdrdir)/ruby/internal/intern/io.h +id.o: $(hdrdir)/ruby/internal/intern/load.h +id.o: $(hdrdir)/ruby/internal/intern/marshal.h +id.o: $(hdrdir)/ruby/internal/intern/numeric.h +id.o: $(hdrdir)/ruby/internal/intern/object.h +id.o: $(hdrdir)/ruby/internal/intern/parse.h +id.o: $(hdrdir)/ruby/internal/intern/proc.h +id.o: $(hdrdir)/ruby/internal/intern/process.h +id.o: $(hdrdir)/ruby/internal/intern/random.h +id.o: $(hdrdir)/ruby/internal/intern/range.h +id.o: $(hdrdir)/ruby/internal/intern/rational.h +id.o: $(hdrdir)/ruby/internal/intern/re.h +id.o: $(hdrdir)/ruby/internal/intern/ruby.h +id.o: $(hdrdir)/ruby/internal/intern/select.h +id.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +id.o: $(hdrdir)/ruby/internal/intern/set.h +id.o: $(hdrdir)/ruby/internal/intern/signal.h +id.o: $(hdrdir)/ruby/internal/intern/sprintf.h +id.o: $(hdrdir)/ruby/internal/intern/string.h +id.o: $(hdrdir)/ruby/internal/intern/struct.h +id.o: $(hdrdir)/ruby/internal/intern/thread.h +id.o: $(hdrdir)/ruby/internal/intern/time.h +id.o: $(hdrdir)/ruby/internal/intern/variable.h +id.o: $(hdrdir)/ruby/internal/intern/vm.h +id.o: $(hdrdir)/ruby/internal/interpreter.h +id.o: $(hdrdir)/ruby/internal/iterator.h +id.o: $(hdrdir)/ruby/internal/memory.h +id.o: $(hdrdir)/ruby/internal/method.h +id.o: $(hdrdir)/ruby/internal/module.h +id.o: $(hdrdir)/ruby/internal/newobj.h +id.o: $(hdrdir)/ruby/internal/scan_args.h +id.o: $(hdrdir)/ruby/internal/special_consts.h +id.o: $(hdrdir)/ruby/internal/static_assert.h +id.o: $(hdrdir)/ruby/internal/stdalign.h +id.o: $(hdrdir)/ruby/internal/stdbool.h +id.o: $(hdrdir)/ruby/internal/stdckdint.h +id.o: $(hdrdir)/ruby/internal/symbol.h +id.o: $(hdrdir)/ruby/internal/value.h +id.o: $(hdrdir)/ruby/internal/value_type.h +id.o: $(hdrdir)/ruby/internal/variable.h +id.o: $(hdrdir)/ruby/internal/warning_push.h +id.o: $(hdrdir)/ruby/internal/xmalloc.h +id.o: $(hdrdir)/ruby/missing.h +id.o: $(hdrdir)/ruby/ruby.h +id.o: $(hdrdir)/ruby/st.h +id.o: $(hdrdir)/ruby/subst.h +id.o: id.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/thread/id/extconf.rb b/ext/-test-/thread/id/extconf.rb new file mode 100644 index 0000000000..a0ae0eff15 --- /dev/null +++ b/ext/-test-/thread/id/extconf.rb @@ -0,0 +1,3 @@ +if have_func("gettid") + create_makefile("-test-/thread/id") +end diff --git a/ext/-test-/thread/id/id.c b/ext/-test-/thread/id/id.c new file mode 100644 index 0000000000..b46a5955e2 --- /dev/null +++ b/ext/-test-/thread/id/id.c @@ -0,0 +1,15 @@ +#include <ruby.h> + +static VALUE +bug_gettid(VALUE self) +{ + pid_t tid = gettid(); + return PIDT2NUM(tid); +} + +void +Init_id(void) +{ + VALUE klass = rb_define_module_under(rb_define_module("Bug"), "ThreadID"); + rb_define_module_function(klass, "gettid", bug_gettid, 0); +} diff --git a/ext/-test-/thread/instrumentation/depend b/ext/-test-/thread/instrumentation/depend new file mode 100644 index 0000000000..63e1c7e44f --- /dev/null +++ b/ext/-test-/thread/instrumentation/depend @@ -0,0 +1,165 @@ +# AUTOGENERATED DEPENDENCIES START +instrumentation.o: $(RUBY_EXTCONF_H) +instrumentation.o: $(arch_hdrdir)/ruby/config.h +instrumentation.o: $(hdrdir)/ruby/assert.h +instrumentation.o: $(hdrdir)/ruby/atomic.h +instrumentation.o: $(hdrdir)/ruby/backward.h +instrumentation.o: $(hdrdir)/ruby/backward/2/assume.h +instrumentation.o: $(hdrdir)/ruby/backward/2/attributes.h +instrumentation.o: $(hdrdir)/ruby/backward/2/bool.h +instrumentation.o: $(hdrdir)/ruby/backward/2/inttypes.h +instrumentation.o: $(hdrdir)/ruby/backward/2/limits.h +instrumentation.o: $(hdrdir)/ruby/backward/2/long_long.h +instrumentation.o: $(hdrdir)/ruby/backward/2/stdalign.h +instrumentation.o: $(hdrdir)/ruby/backward/2/stdarg.h +instrumentation.o: $(hdrdir)/ruby/defines.h +instrumentation.o: $(hdrdir)/ruby/intern.h +instrumentation.o: $(hdrdir)/ruby/internal/abi.h +instrumentation.o: $(hdrdir)/ruby/internal/anyargs.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/char.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/double.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/int.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/long.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/short.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +instrumentation.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +instrumentation.o: $(hdrdir)/ruby/internal/assume.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/artificial.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/cold.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/const.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/constexpr.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/deprecated.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/error.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/forceinline.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/format.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/noalias.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/noexcept.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/noinline.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/nonnull.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/noreturn.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/pure.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/restrict.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/warning.h +instrumentation.o: $(hdrdir)/ruby/internal/attr/weakref.h +instrumentation.o: $(hdrdir)/ruby/internal/cast.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +instrumentation.o: $(hdrdir)/ruby/internal/compiler_since.h +instrumentation.o: $(hdrdir)/ruby/internal/config.h +instrumentation.o: $(hdrdir)/ruby/internal/constant_p.h +instrumentation.o: $(hdrdir)/ruby/internal/core.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rarray.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rbasic.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rbignum.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rclass.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rdata.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rfile.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rhash.h +instrumentation.o: $(hdrdir)/ruby/internal/core/robject.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rregexp.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rstring.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rstruct.h +instrumentation.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +instrumentation.o: $(hdrdir)/ruby/internal/ctype.h +instrumentation.o: $(hdrdir)/ruby/internal/dllexport.h +instrumentation.o: $(hdrdir)/ruby/internal/dosish.h +instrumentation.o: $(hdrdir)/ruby/internal/error.h +instrumentation.o: $(hdrdir)/ruby/internal/eval.h +instrumentation.o: $(hdrdir)/ruby/internal/event.h +instrumentation.o: $(hdrdir)/ruby/internal/fl_type.h +instrumentation.o: $(hdrdir)/ruby/internal/gc.h +instrumentation.o: $(hdrdir)/ruby/internal/glob.h +instrumentation.o: $(hdrdir)/ruby/internal/globals.h +instrumentation.o: $(hdrdir)/ruby/internal/has/attribute.h +instrumentation.o: $(hdrdir)/ruby/internal/has/builtin.h +instrumentation.o: $(hdrdir)/ruby/internal/has/c_attribute.h +instrumentation.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +instrumentation.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +instrumentation.o: $(hdrdir)/ruby/internal/has/extension.h +instrumentation.o: $(hdrdir)/ruby/internal/has/feature.h +instrumentation.o: $(hdrdir)/ruby/internal/has/warning.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/array.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/bignum.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/class.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/compar.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/complex.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/cont.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/dir.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/enum.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/enumerator.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/error.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/eval.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/file.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/hash.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/io.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/load.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/marshal.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/numeric.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/object.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/parse.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/proc.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/process.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/random.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/range.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/rational.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/re.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/ruby.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/select.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/set.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/signal.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/sprintf.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/string.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/struct.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/thread.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/time.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/variable.h +instrumentation.o: $(hdrdir)/ruby/internal/intern/vm.h +instrumentation.o: $(hdrdir)/ruby/internal/interpreter.h +instrumentation.o: $(hdrdir)/ruby/internal/iterator.h +instrumentation.o: $(hdrdir)/ruby/internal/memory.h +instrumentation.o: $(hdrdir)/ruby/internal/method.h +instrumentation.o: $(hdrdir)/ruby/internal/module.h +instrumentation.o: $(hdrdir)/ruby/internal/newobj.h +instrumentation.o: $(hdrdir)/ruby/internal/scan_args.h +instrumentation.o: $(hdrdir)/ruby/internal/special_consts.h +instrumentation.o: $(hdrdir)/ruby/internal/static_assert.h +instrumentation.o: $(hdrdir)/ruby/internal/stdalign.h +instrumentation.o: $(hdrdir)/ruby/internal/stdbool.h +instrumentation.o: $(hdrdir)/ruby/internal/stdckdint.h +instrumentation.o: $(hdrdir)/ruby/internal/symbol.h +instrumentation.o: $(hdrdir)/ruby/internal/value.h +instrumentation.o: $(hdrdir)/ruby/internal/value_type.h +instrumentation.o: $(hdrdir)/ruby/internal/variable.h +instrumentation.o: $(hdrdir)/ruby/internal/warning_push.h +instrumentation.o: $(hdrdir)/ruby/internal/xmalloc.h +instrumentation.o: $(hdrdir)/ruby/missing.h +instrumentation.o: $(hdrdir)/ruby/ruby.h +instrumentation.o: $(hdrdir)/ruby/st.h +instrumentation.o: $(hdrdir)/ruby/subst.h +instrumentation.o: $(hdrdir)/ruby/thread.h +instrumentation.o: $(hdrdir)/ruby/thread_native.h +instrumentation.o: instrumentation.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/thread/instrumentation/extconf.rb b/ext/-test-/thread/instrumentation/extconf.rb new file mode 100644 index 0000000000..a48ba3c045 --- /dev/null +++ b/ext/-test-/thread/instrumentation/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/thread/instrumentation") diff --git a/ext/-test-/thread/instrumentation/instrumentation.c b/ext/-test-/thread/instrumentation/instrumentation.c new file mode 100644 index 0000000000..25e2902a78 --- /dev/null +++ b/ext/-test-/thread/instrumentation/instrumentation.c @@ -0,0 +1,218 @@ +#include "ruby/ruby.h" +#include "ruby/atomic.h" +#include "ruby/thread.h" + +#ifndef RB_THREAD_LOCAL_SPECIFIER +# define RB_THREAD_LOCAL_SPECIFIER +#endif + +static VALUE timeline_value = Qnil; + +struct thread_event { + VALUE thread; + rb_event_flag_t event; +}; + +#define MAX_EVENTS 1024 +static struct thread_event event_timeline[MAX_EVENTS]; +static rb_atomic_t timeline_cursor; + +static void +event_timeline_gc_mark(void *ptr) { + rb_atomic_t cursor; + for (cursor = 0; cursor < timeline_cursor; cursor++) { + rb_gc_mark(event_timeline[cursor].thread); + } +} + +static const rb_data_type_t event_timeline_type = { + "TestThreadInstrumentation/event_timeline", + {event_timeline_gc_mark, NULL, NULL,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +reset_timeline(void) +{ + timeline_cursor = 0; + memset(event_timeline, 0, sizeof(struct thread_event) * MAX_EVENTS); +} + +static rb_event_flag_t +find_last_event(VALUE thread) +{ + rb_atomic_t cursor = timeline_cursor; + if (cursor) { + do { + if (event_timeline[cursor].thread == thread){ + return event_timeline[cursor].event; + } + cursor--; + } while (cursor > 0); + } + return 0; +} + +static const char * +event_name(rb_event_flag_t event) +{ + switch (event) { + case RUBY_INTERNAL_THREAD_EVENT_STARTED: + return "started"; + case RUBY_INTERNAL_THREAD_EVENT_READY: + return "ready"; + case RUBY_INTERNAL_THREAD_EVENT_RESUMED: + return "resumed"; + case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED: + return "suspended"; + case RUBY_INTERNAL_THREAD_EVENT_EXITED: + return "exited"; + } + return "no-event"; +} + +static void +unexpected(bool strict, const char *format, VALUE thread, rb_event_flag_t last_event) +{ + const char *last_event_name = event_name(last_event); + if (strict) { + rb_bug(format, thread, last_event_name); + } + else { + fprintf(stderr, format, thread, last_event_name); + fprintf(stderr, "\n"); + } +} + +static void +ex_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *user_data) +{ + rb_event_flag_t last_event = find_last_event(event_data->thread); + bool strict = (bool)user_data; + + if (last_event != 0) { + switch (event) { + case RUBY_INTERNAL_THREAD_EVENT_STARTED: + unexpected(strict, "[thread=%"PRIxVALUE"] `started` event can't be preceded by `%s`", event_data->thread, last_event); + break; + case RUBY_INTERNAL_THREAD_EVENT_READY: + if (last_event != RUBY_INTERNAL_THREAD_EVENT_STARTED && last_event != RUBY_INTERNAL_THREAD_EVENT_SUSPENDED) { + unexpected(strict, "[thread=%"PRIxVALUE"] `ready` must be preceded by `started` or `suspended`, got: `%s`", event_data->thread, last_event); + } + break; + case RUBY_INTERNAL_THREAD_EVENT_RESUMED: + if (last_event != RUBY_INTERNAL_THREAD_EVENT_READY) { + unexpected(strict, "[thread=%"PRIxVALUE"] `resumed` must be preceded by `ready`, got: `%s`", event_data->thread, last_event); + } + break; + case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED: + if (last_event != RUBY_INTERNAL_THREAD_EVENT_RESUMED) { + unexpected(strict, "[thread=%"PRIxVALUE"] `suspended` must be preceded by `resumed`, got: `%s`", event_data->thread, last_event); + } + break; + case RUBY_INTERNAL_THREAD_EVENT_EXITED: + if (last_event != RUBY_INTERNAL_THREAD_EVENT_RESUMED && last_event != RUBY_INTERNAL_THREAD_EVENT_SUSPENDED) { + unexpected(strict, "[thread=%"PRIxVALUE"] `exited` must be preceded by `resumed` or `suspended`, got: `%s`", event_data->thread, last_event); + } + break; + } + } + + rb_atomic_t cursor = RUBY_ATOMIC_FETCH_ADD(timeline_cursor, 1); + if (cursor >= MAX_EVENTS) { + rb_bug("TestThreadInstrumentation: ran out of event_timeline space"); + } + + event_timeline[cursor].thread = event_data->thread; + event_timeline[cursor].event = event; +} + +static rb_internal_thread_event_hook_t * single_hook = NULL; + +static VALUE +thread_register_callback(VALUE thread, VALUE strict) +{ + single_hook = rb_internal_thread_add_event_hook( + ex_callback, + RUBY_INTERNAL_THREAD_EVENT_STARTED | + RUBY_INTERNAL_THREAD_EVENT_READY | + RUBY_INTERNAL_THREAD_EVENT_RESUMED | + RUBY_INTERNAL_THREAD_EVENT_SUSPENDED | + RUBY_INTERNAL_THREAD_EVENT_EXITED, + (void *)RTEST(strict) + ); + + return Qnil; +} + +static VALUE +event_symbol(rb_event_flag_t event) +{ + switch (event) { + case RUBY_INTERNAL_THREAD_EVENT_STARTED: + return rb_id2sym(rb_intern("started")); + case RUBY_INTERNAL_THREAD_EVENT_READY: + return rb_id2sym(rb_intern("ready")); + case RUBY_INTERNAL_THREAD_EVENT_RESUMED: + return rb_id2sym(rb_intern("resumed")); + case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED: + return rb_id2sym(rb_intern("suspended")); + case RUBY_INTERNAL_THREAD_EVENT_EXITED: + return rb_id2sym(rb_intern("exited")); + default: + rb_bug("TestThreadInstrumentation: Unexpected event"); + break; + } +} + +static VALUE +thread_unregister_callback(VALUE thread) +{ + if (single_hook) { + rb_internal_thread_remove_event_hook(single_hook); + single_hook = NULL; + } + + VALUE events = rb_ary_new_capa(timeline_cursor); + rb_atomic_t cursor; + for (cursor = 0; cursor < timeline_cursor; cursor++) { + VALUE pair = rb_ary_new_capa(2); + rb_ary_push(pair, event_timeline[cursor].thread); + rb_ary_push(pair, event_symbol(event_timeline[cursor].event)); + rb_ary_push(events, pair); + } + + reset_timeline(); + + return events; +} + +static VALUE +thread_register_and_unregister_callback(VALUE thread) +{ + rb_internal_thread_event_hook_t * hooks[5]; + for (int i = 0; i < 5; i++) { + hooks[i] = rb_internal_thread_add_event_hook(ex_callback, RUBY_INTERNAL_THREAD_EVENT_READY, NULL); + } + + if (!rb_internal_thread_remove_event_hook(hooks[4])) return Qfalse; + if (!rb_internal_thread_remove_event_hook(hooks[0])) return Qfalse; + if (!rb_internal_thread_remove_event_hook(hooks[3])) return Qfalse; + if (!rb_internal_thread_remove_event_hook(hooks[2])) return Qfalse; + if (!rb_internal_thread_remove_event_hook(hooks[1])) return Qfalse; + return Qtrue; +} + +void +Init_instrumentation(void) +{ + VALUE mBug = rb_define_module("Bug"); + VALUE klass = rb_define_module_under(mBug, "ThreadInstrumentation"); + rb_global_variable(&timeline_value); + timeline_value = TypedData_Wrap_Struct(0, &event_timeline_type, (void *)1); + + rb_define_singleton_method(klass, "register_callback", thread_register_callback, 1); + rb_define_singleton_method(klass, "unregister_callback", thread_unregister_callback, 0); + rb_define_singleton_method(klass, "register_and_unregister_callbacks", thread_register_and_unregister_callback, 0); +} diff --git a/ext/-test-/thread/lock_native_thread/depend b/ext/-test-/thread/lock_native_thread/depend new file mode 100644 index 0000000000..a32843e531 --- /dev/null +++ b/ext/-test-/thread/lock_native_thread/depend @@ -0,0 +1,163 @@ +# AUTOGENERATED DEPENDENCIES START +lock_native_thread.o: $(RUBY_EXTCONF_H) +lock_native_thread.o: $(arch_hdrdir)/ruby/config.h +lock_native_thread.o: $(hdrdir)/ruby/assert.h +lock_native_thread.o: $(hdrdir)/ruby/backward.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/assume.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/attributes.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/bool.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/inttypes.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/limits.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/long_long.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/stdalign.h +lock_native_thread.o: $(hdrdir)/ruby/backward/2/stdarg.h +lock_native_thread.o: $(hdrdir)/ruby/defines.h +lock_native_thread.o: $(hdrdir)/ruby/intern.h +lock_native_thread.o: $(hdrdir)/ruby/internal/abi.h +lock_native_thread.o: $(hdrdir)/ruby/internal/anyargs.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/char.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/double.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/int.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/long.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/short.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +lock_native_thread.o: $(hdrdir)/ruby/internal/assume.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/artificial.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/cold.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/const.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/constexpr.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/deprecated.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/error.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/forceinline.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/format.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/noalias.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/noexcept.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/noinline.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/nonnull.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/noreturn.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/pure.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/restrict.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/warning.h +lock_native_thread.o: $(hdrdir)/ruby/internal/attr/weakref.h +lock_native_thread.o: $(hdrdir)/ruby/internal/cast.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +lock_native_thread.o: $(hdrdir)/ruby/internal/compiler_since.h +lock_native_thread.o: $(hdrdir)/ruby/internal/config.h +lock_native_thread.o: $(hdrdir)/ruby/internal/constant_p.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rarray.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rbasic.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rbignum.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rclass.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rdata.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rfile.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rhash.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/robject.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rregexp.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rstring.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rstruct.h +lock_native_thread.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +lock_native_thread.o: $(hdrdir)/ruby/internal/ctype.h +lock_native_thread.o: $(hdrdir)/ruby/internal/dllexport.h +lock_native_thread.o: $(hdrdir)/ruby/internal/dosish.h +lock_native_thread.o: $(hdrdir)/ruby/internal/error.h +lock_native_thread.o: $(hdrdir)/ruby/internal/eval.h +lock_native_thread.o: $(hdrdir)/ruby/internal/event.h +lock_native_thread.o: $(hdrdir)/ruby/internal/fl_type.h +lock_native_thread.o: $(hdrdir)/ruby/internal/gc.h +lock_native_thread.o: $(hdrdir)/ruby/internal/glob.h +lock_native_thread.o: $(hdrdir)/ruby/internal/globals.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/attribute.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/builtin.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/c_attribute.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/extension.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/feature.h +lock_native_thread.o: $(hdrdir)/ruby/internal/has/warning.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/array.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/bignum.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/class.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/compar.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/complex.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/cont.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/dir.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/enum.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/enumerator.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/error.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/eval.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/file.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/hash.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/io.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/load.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/marshal.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/numeric.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/object.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/parse.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/proc.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/process.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/random.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/range.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/rational.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/re.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/ruby.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/select.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/set.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/signal.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/sprintf.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/string.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/struct.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/thread.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/time.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/variable.h +lock_native_thread.o: $(hdrdir)/ruby/internal/intern/vm.h +lock_native_thread.o: $(hdrdir)/ruby/internal/interpreter.h +lock_native_thread.o: $(hdrdir)/ruby/internal/iterator.h +lock_native_thread.o: $(hdrdir)/ruby/internal/memory.h +lock_native_thread.o: $(hdrdir)/ruby/internal/method.h +lock_native_thread.o: $(hdrdir)/ruby/internal/module.h +lock_native_thread.o: $(hdrdir)/ruby/internal/newobj.h +lock_native_thread.o: $(hdrdir)/ruby/internal/scan_args.h +lock_native_thread.o: $(hdrdir)/ruby/internal/special_consts.h +lock_native_thread.o: $(hdrdir)/ruby/internal/static_assert.h +lock_native_thread.o: $(hdrdir)/ruby/internal/stdalign.h +lock_native_thread.o: $(hdrdir)/ruby/internal/stdbool.h +lock_native_thread.o: $(hdrdir)/ruby/internal/stdckdint.h +lock_native_thread.o: $(hdrdir)/ruby/internal/symbol.h +lock_native_thread.o: $(hdrdir)/ruby/internal/value.h +lock_native_thread.o: $(hdrdir)/ruby/internal/value_type.h +lock_native_thread.o: $(hdrdir)/ruby/internal/variable.h +lock_native_thread.o: $(hdrdir)/ruby/internal/warning_push.h +lock_native_thread.o: $(hdrdir)/ruby/internal/xmalloc.h +lock_native_thread.o: $(hdrdir)/ruby/missing.h +lock_native_thread.o: $(hdrdir)/ruby/ruby.h +lock_native_thread.o: $(hdrdir)/ruby/st.h +lock_native_thread.o: $(hdrdir)/ruby/subst.h +lock_native_thread.o: $(hdrdir)/ruby/thread.h +lock_native_thread.o: lock_native_thread.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/thread/lock_native_thread/extconf.rb b/ext/-test-/thread/lock_native_thread/extconf.rb new file mode 100644 index 0000000000..832bfde01a --- /dev/null +++ b/ext/-test-/thread/lock_native_thread/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/thread/lock_native_thread") diff --git a/ext/-test-/thread/lock_native_thread/lock_native_thread.c b/ext/-test-/thread/lock_native_thread/lock_native_thread.c new file mode 100644 index 0000000000..2eb75809a9 --- /dev/null +++ b/ext/-test-/thread/lock_native_thread/lock_native_thread.c @@ -0,0 +1,50 @@ + +#include "ruby/ruby.h" +#include "ruby/thread.h" + +#ifdef HAVE_PTHREAD_H +#include <pthread.h> + +static pthread_key_t tls_key; + +static VALUE +get_tls(VALUE self) +{ + return (VALUE)pthread_getspecific(tls_key); +} + +static VALUE +set_tls(VALUE self, VALUE vn) +{ + pthread_setspecific(tls_key, (void *)vn); + return Qnil; +} + +static VALUE +lock_native_thread(VALUE self) +{ + return rb_thread_lock_native_thread() ? Qtrue : Qfalse; +} + +void +Init_lock_native_thread(void) +{ + int r; + + if ((r = pthread_key_create(&tls_key, NULL)) != 0) { + rb_bug("pthread_key_create() returns %d", r); + } + pthread_setspecific(tls_key, NULL); + + rb_define_method(rb_cThread, "lock_native_thread", lock_native_thread, 0); + rb_define_method(rb_cThread, "get_tls", get_tls, 0); + rb_define_method(rb_cThread, "set_tls", set_tls, 1); +} + +#else // HAVE_PTHREAD_H +void +Init_lock_native_thread(void) +{ + // do nothing +} +#endif // HAVE_PTHREAD_H diff --git a/ext/-test-/thread_fd/depend b/ext/-test-/thread_fd/depend deleted file mode 100644 index ad6f66f312..0000000000 --- a/ext/-test-/thread_fd/depend +++ /dev/null @@ -1,161 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -thread_fd.o: $(RUBY_EXTCONF_H) -thread_fd.o: $(arch_hdrdir)/ruby/config.h -thread_fd.o: $(hdrdir)/ruby/internal/anyargs.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/char.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/double.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/int.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/long.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/short.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/assume.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/artificial.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/cold.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/const.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/constexpr.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/deprecated.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/error.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/forceinline.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/format.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noalias.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/pure.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/warning.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/weakref.h -thread_fd.o: $(hdrdir)/ruby/internal/cast.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_since.h -thread_fd.o: $(hdrdir)/ruby/internal/config.h -thread_fd.o: $(hdrdir)/ruby/internal/constant_p.h -thread_fd.o: $(hdrdir)/ruby/internal/core.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rarray.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rbasic.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rbignum.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rclass.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rdata.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rfile.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rhash.h -thread_fd.o: $(hdrdir)/ruby/internal/core/robject.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rregexp.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rstring.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rstruct.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -thread_fd.o: $(hdrdir)/ruby/internal/ctype.h -thread_fd.o: $(hdrdir)/ruby/internal/dllexport.h -thread_fd.o: $(hdrdir)/ruby/internal/dosish.h -thread_fd.o: $(hdrdir)/ruby/internal/error.h -thread_fd.o: $(hdrdir)/ruby/internal/eval.h -thread_fd.o: $(hdrdir)/ruby/internal/event.h -thread_fd.o: $(hdrdir)/ruby/internal/fl_type.h -thread_fd.o: $(hdrdir)/ruby/internal/gc.h -thread_fd.o: $(hdrdir)/ruby/internal/glob.h -thread_fd.o: $(hdrdir)/ruby/internal/globals.h -thread_fd.o: $(hdrdir)/ruby/internal/has/attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/builtin.h -thread_fd.o: $(hdrdir)/ruby/internal/has/c_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/extension.h -thread_fd.o: $(hdrdir)/ruby/internal/has/feature.h -thread_fd.o: $(hdrdir)/ruby/internal/has/warning.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/array.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/bignum.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/class.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/compar.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/complex.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/cont.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/dir.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/enum.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/error.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/eval.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/file.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/gc.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/hash.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/io.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/load.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/marshal.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/numeric.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/object.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/parse.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/proc.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/process.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/random.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/range.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/rational.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/re.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/ruby.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/select.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/signal.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/sprintf.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/string.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/struct.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/thread.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/time.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/variable.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/vm.h -thread_fd.o: $(hdrdir)/ruby/internal/interpreter.h -thread_fd.o: $(hdrdir)/ruby/internal/iterator.h -thread_fd.o: $(hdrdir)/ruby/internal/memory.h -thread_fd.o: $(hdrdir)/ruby/internal/method.h -thread_fd.o: $(hdrdir)/ruby/internal/module.h -thread_fd.o: $(hdrdir)/ruby/internal/newobj.h -thread_fd.o: $(hdrdir)/ruby/internal/rgengc.h -thread_fd.o: $(hdrdir)/ruby/internal/scan_args.h -thread_fd.o: $(hdrdir)/ruby/internal/special_consts.h -thread_fd.o: $(hdrdir)/ruby/internal/static_assert.h -thread_fd.o: $(hdrdir)/ruby/internal/stdalign.h -thread_fd.o: $(hdrdir)/ruby/internal/stdbool.h -thread_fd.o: $(hdrdir)/ruby/internal/symbol.h -thread_fd.o: $(hdrdir)/ruby/internal/value.h -thread_fd.o: $(hdrdir)/ruby/internal/value_type.h -thread_fd.o: $(hdrdir)/ruby/internal/variable.h -thread_fd.o: $(hdrdir)/ruby/internal/warning_push.h -thread_fd.o: $(hdrdir)/ruby/internal/xmalloc.h -thread_fd.o: $(hdrdir)/ruby/assert.h -thread_fd.o: $(hdrdir)/ruby/backward.h -thread_fd.o: $(hdrdir)/ruby/backward/2/assume.h -thread_fd.o: $(hdrdir)/ruby/backward/2/attributes.h -thread_fd.o: $(hdrdir)/ruby/backward/2/bool.h -thread_fd.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -thread_fd.o: $(hdrdir)/ruby/backward/2/inttypes.h -thread_fd.o: $(hdrdir)/ruby/backward/2/limits.h -thread_fd.o: $(hdrdir)/ruby/backward/2/long_long.h -thread_fd.o: $(hdrdir)/ruby/backward/2/stdalign.h -thread_fd.o: $(hdrdir)/ruby/backward/2/stdarg.h -thread_fd.o: $(hdrdir)/ruby/defines.h -thread_fd.o: $(hdrdir)/ruby/intern.h -thread_fd.o: $(hdrdir)/ruby/missing.h -thread_fd.o: $(hdrdir)/ruby/ruby.h -thread_fd.o: $(hdrdir)/ruby/st.h -thread_fd.o: $(hdrdir)/ruby/subst.h -thread_fd.o: thread_fd.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/thread_fd/extconf.rb b/ext/-test-/thread_fd/extconf.rb deleted file mode 100644 index a8bbe9d169..0000000000 --- a/ext/-test-/thread_fd/extconf.rb +++ /dev/null @@ -1,2 +0,0 @@ -# frozen_string_literal: true -create_makefile('-test-/thread_fd') diff --git a/ext/-test-/thread_fd/thread_fd.c b/ext/-test-/thread_fd/thread_fd.c deleted file mode 100644 index 042b799dc8..0000000000 --- a/ext/-test-/thread_fd/thread_fd.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "ruby/ruby.h" - -static VALUE -thread_fd_close(VALUE ign, VALUE fd) -{ - rb_thread_fd_close(NUM2INT(fd)); - return Qnil; -} - -static VALUE -thread_fd_wait(VALUE ign, VALUE fd) -{ - int ret = rb_thread_wait_fd(NUM2INT(fd)); - return INT2NUM(ret); -} - -static VALUE -thread_fd_writable(VALUE ign, VALUE fd) -{ - int ret = rb_thread_fd_writable(NUM2INT(fd)); - return INT2NUM(ret); -} - -void -Init_thread_fd(void) -{ - rb_define_singleton_method(rb_cIO, "thread_fd_close", thread_fd_close, 1); - rb_define_singleton_method(rb_cIO, "thread_fd_wait", thread_fd_wait, 1); - rb_define_singleton_method(rb_cIO, "thread_fd_writable", thread_fd_writable, 1); -} diff --git a/ext/-test-/time/depend b/ext/-test-/time/depend index 48b41dd678..e5b05f3113 100644 --- a/ext/-test-/time/depend +++ b/ext/-test-/time/depend @@ -2,6 +2,19 @@ init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h init.o: $(hdrdir)/ruby.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h +init.o: $(hdrdir)/ruby/defines.h +init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h init.o: $(hdrdir)/ruby/internal/variable.h init.o: $(hdrdir)/ruby/internal/warning_push.h init.o: $(hdrdir)/ruby/internal/xmalloc.h -init.o: $(hdrdir)/ruby/assert.h -init.o: $(hdrdir)/ruby/backward.h -init.o: $(hdrdir)/ruby/backward/2/assume.h -init.o: $(hdrdir)/ruby/backward/2/attributes.h -init.o: $(hdrdir)/ruby/backward/2/bool.h -init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -init.o: $(hdrdir)/ruby/backward/2/inttypes.h -init.o: $(hdrdir)/ruby/backward/2/limits.h -init.o: $(hdrdir)/ruby/backward/2/long_long.h -init.o: $(hdrdir)/ruby/backward/2/stdalign.h -init.o: $(hdrdir)/ruby/backward/2/stdarg.h -init.o: $(hdrdir)/ruby/defines.h -init.o: $(hdrdir)/ruby/intern.h init.o: $(hdrdir)/ruby/missing.h init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h @@ -162,6 +163,20 @@ init.o: init.c leap_second.o: $(RUBY_EXTCONF_H) leap_second.o: $(arch_hdrdir)/ruby/config.h leap_second.o: $(hdrdir)/ruby.h +leap_second.o: $(hdrdir)/ruby/assert.h +leap_second.o: $(hdrdir)/ruby/backward.h +leap_second.o: $(hdrdir)/ruby/backward/2/assume.h +leap_second.o: $(hdrdir)/ruby/backward/2/attributes.h +leap_second.o: $(hdrdir)/ruby/backward/2/bool.h +leap_second.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +leap_second.o: $(hdrdir)/ruby/backward/2/inttypes.h +leap_second.o: $(hdrdir)/ruby/backward/2/limits.h +leap_second.o: $(hdrdir)/ruby/backward/2/long_long.h +leap_second.o: $(hdrdir)/ruby/backward/2/stdalign.h +leap_second.o: $(hdrdir)/ruby/backward/2/stdarg.h +leap_second.o: $(hdrdir)/ruby/defines.h +leap_second.o: $(hdrdir)/ruby/intern.h +leap_second.o: $(hdrdir)/ruby/internal/abi.h leap_second.o: $(hdrdir)/ruby/internal/anyargs.h leap_second.o: $(hdrdir)/ruby/internal/arithmetic.h leap_second.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -199,6 +214,7 @@ leap_second.o: $(hdrdir)/ruby/internal/attr/noexcept.h leap_second.o: $(hdrdir)/ruby/internal/attr/noinline.h leap_second.o: $(hdrdir)/ruby/internal/attr/nonnull.h leap_second.o: $(hdrdir)/ruby/internal/attr/noreturn.h +leap_second.o: $(hdrdir)/ruby/internal/attr/packed_struct.h leap_second.o: $(hdrdir)/ruby/internal/attr/pure.h leap_second.o: $(hdrdir)/ruby/internal/attr/restrict.h leap_second.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -258,7 +274,6 @@ leap_second.o: $(hdrdir)/ruby/internal/intern/enumerator.h leap_second.o: $(hdrdir)/ruby/internal/intern/error.h leap_second.o: $(hdrdir)/ruby/internal/intern/eval.h leap_second.o: $(hdrdir)/ruby/internal/intern/file.h -leap_second.o: $(hdrdir)/ruby/internal/intern/gc.h leap_second.o: $(hdrdir)/ruby/internal/intern/hash.h leap_second.o: $(hdrdir)/ruby/internal/intern/io.h leap_second.o: $(hdrdir)/ruby/internal/intern/load.h @@ -275,6 +290,7 @@ leap_second.o: $(hdrdir)/ruby/internal/intern/re.h leap_second.o: $(hdrdir)/ruby/internal/intern/ruby.h leap_second.o: $(hdrdir)/ruby/internal/intern/select.h leap_second.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +leap_second.o: $(hdrdir)/ruby/internal/intern/set.h leap_second.o: $(hdrdir)/ruby/internal/intern/signal.h leap_second.o: $(hdrdir)/ruby/internal/intern/sprintf.h leap_second.o: $(hdrdir)/ruby/internal/intern/string.h @@ -289,31 +305,18 @@ leap_second.o: $(hdrdir)/ruby/internal/memory.h leap_second.o: $(hdrdir)/ruby/internal/method.h leap_second.o: $(hdrdir)/ruby/internal/module.h leap_second.o: $(hdrdir)/ruby/internal/newobj.h -leap_second.o: $(hdrdir)/ruby/internal/rgengc.h leap_second.o: $(hdrdir)/ruby/internal/scan_args.h leap_second.o: $(hdrdir)/ruby/internal/special_consts.h leap_second.o: $(hdrdir)/ruby/internal/static_assert.h leap_second.o: $(hdrdir)/ruby/internal/stdalign.h leap_second.o: $(hdrdir)/ruby/internal/stdbool.h +leap_second.o: $(hdrdir)/ruby/internal/stdckdint.h leap_second.o: $(hdrdir)/ruby/internal/symbol.h leap_second.o: $(hdrdir)/ruby/internal/value.h leap_second.o: $(hdrdir)/ruby/internal/value_type.h leap_second.o: $(hdrdir)/ruby/internal/variable.h leap_second.o: $(hdrdir)/ruby/internal/warning_push.h leap_second.o: $(hdrdir)/ruby/internal/xmalloc.h -leap_second.o: $(hdrdir)/ruby/assert.h -leap_second.o: $(hdrdir)/ruby/backward.h -leap_second.o: $(hdrdir)/ruby/backward/2/assume.h -leap_second.o: $(hdrdir)/ruby/backward/2/attributes.h -leap_second.o: $(hdrdir)/ruby/backward/2/bool.h -leap_second.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -leap_second.o: $(hdrdir)/ruby/backward/2/inttypes.h -leap_second.o: $(hdrdir)/ruby/backward/2/limits.h -leap_second.o: $(hdrdir)/ruby/backward/2/long_long.h -leap_second.o: $(hdrdir)/ruby/backward/2/stdalign.h -leap_second.o: $(hdrdir)/ruby/backward/2/stdarg.h -leap_second.o: $(hdrdir)/ruby/defines.h -leap_second.o: $(hdrdir)/ruby/intern.h leap_second.o: $(hdrdir)/ruby/missing.h leap_second.o: $(hdrdir)/ruby/ruby.h leap_second.o: $(hdrdir)/ruby/st.h @@ -326,6 +329,19 @@ leap_second.o: leap_second.c new.o: $(RUBY_EXTCONF_H) new.o: $(arch_hdrdir)/ruby/config.h new.o: $(hdrdir)/ruby.h +new.o: $(hdrdir)/ruby/assert.h +new.o: $(hdrdir)/ruby/backward.h +new.o: $(hdrdir)/ruby/backward/2/assume.h +new.o: $(hdrdir)/ruby/backward/2/attributes.h +new.o: $(hdrdir)/ruby/backward/2/bool.h +new.o: $(hdrdir)/ruby/backward/2/inttypes.h +new.o: $(hdrdir)/ruby/backward/2/limits.h +new.o: $(hdrdir)/ruby/backward/2/long_long.h +new.o: $(hdrdir)/ruby/backward/2/stdalign.h +new.o: $(hdrdir)/ruby/backward/2/stdarg.h +new.o: $(hdrdir)/ruby/defines.h +new.o: $(hdrdir)/ruby/intern.h +new.o: $(hdrdir)/ruby/internal/abi.h new.o: $(hdrdir)/ruby/internal/anyargs.h new.o: $(hdrdir)/ruby/internal/arithmetic.h new.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -363,6 +379,7 @@ new.o: $(hdrdir)/ruby/internal/attr/noexcept.h new.o: $(hdrdir)/ruby/internal/attr/noinline.h new.o: $(hdrdir)/ruby/internal/attr/nonnull.h new.o: $(hdrdir)/ruby/internal/attr/noreturn.h +new.o: $(hdrdir)/ruby/internal/attr/packed_struct.h new.o: $(hdrdir)/ruby/internal/attr/pure.h new.o: $(hdrdir)/ruby/internal/attr/restrict.h new.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -422,7 +439,6 @@ new.o: $(hdrdir)/ruby/internal/intern/enumerator.h new.o: $(hdrdir)/ruby/internal/intern/error.h new.o: $(hdrdir)/ruby/internal/intern/eval.h new.o: $(hdrdir)/ruby/internal/intern/file.h -new.o: $(hdrdir)/ruby/internal/intern/gc.h new.o: $(hdrdir)/ruby/internal/intern/hash.h new.o: $(hdrdir)/ruby/internal/intern/io.h new.o: $(hdrdir)/ruby/internal/intern/load.h @@ -439,6 +455,7 @@ new.o: $(hdrdir)/ruby/internal/intern/re.h new.o: $(hdrdir)/ruby/internal/intern/ruby.h new.o: $(hdrdir)/ruby/internal/intern/select.h new.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +new.o: $(hdrdir)/ruby/internal/intern/set.h new.o: $(hdrdir)/ruby/internal/intern/signal.h new.o: $(hdrdir)/ruby/internal/intern/sprintf.h new.o: $(hdrdir)/ruby/internal/intern/string.h @@ -453,31 +470,18 @@ new.o: $(hdrdir)/ruby/internal/memory.h new.o: $(hdrdir)/ruby/internal/method.h new.o: $(hdrdir)/ruby/internal/module.h new.o: $(hdrdir)/ruby/internal/newobj.h -new.o: $(hdrdir)/ruby/internal/rgengc.h new.o: $(hdrdir)/ruby/internal/scan_args.h new.o: $(hdrdir)/ruby/internal/special_consts.h new.o: $(hdrdir)/ruby/internal/static_assert.h new.o: $(hdrdir)/ruby/internal/stdalign.h new.o: $(hdrdir)/ruby/internal/stdbool.h +new.o: $(hdrdir)/ruby/internal/stdckdint.h new.o: $(hdrdir)/ruby/internal/symbol.h new.o: $(hdrdir)/ruby/internal/value.h new.o: $(hdrdir)/ruby/internal/value_type.h new.o: $(hdrdir)/ruby/internal/variable.h new.o: $(hdrdir)/ruby/internal/warning_push.h new.o: $(hdrdir)/ruby/internal/xmalloc.h -new.o: $(hdrdir)/ruby/assert.h -new.o: $(hdrdir)/ruby/backward.h -new.o: $(hdrdir)/ruby/backward/2/assume.h -new.o: $(hdrdir)/ruby/backward/2/attributes.h -new.o: $(hdrdir)/ruby/backward/2/bool.h -new.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -new.o: $(hdrdir)/ruby/backward/2/inttypes.h -new.o: $(hdrdir)/ruby/backward/2/limits.h -new.o: $(hdrdir)/ruby/backward/2/long_long.h -new.o: $(hdrdir)/ruby/backward/2/stdalign.h -new.o: $(hdrdir)/ruby/backward/2/stdarg.h -new.o: $(hdrdir)/ruby/defines.h -new.o: $(hdrdir)/ruby/intern.h new.o: $(hdrdir)/ruby/missing.h new.o: $(hdrdir)/ruby/ruby.h new.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/time/leap_second.c b/ext/-test-/time/leap_second.c deleted file mode 100644 index ee7011fa97..0000000000 --- a/ext/-test-/time/leap_second.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "ruby.h" -#include "internal/time.h" - -static VALUE -bug_time_s_reset_leap_second_info(VALUE klass) -{ - ruby_reset_leap_second_info(); - return Qnil; -} - -void -Init_time_leap_second(VALUE klass) -{ - rb_define_singleton_method(klass, "reset_leap_second_info", bug_time_s_reset_leap_second_info, 0); -} diff --git a/ext/-test-/tracepoint/depend b/ext/-test-/tracepoint/depend index dac1bb278e..014ba83b16 100644 --- a/ext/-test-/tracepoint/depend +++ b/ext/-test-/tracepoint/depend @@ -1,6 +1,20 @@ # AUTOGENERATED DEPENDENCIES START gc_hook.o: $(RUBY_EXTCONF_H) gc_hook.o: $(arch_hdrdir)/ruby/config.h +gc_hook.o: $(hdrdir)/ruby/assert.h +gc_hook.o: $(hdrdir)/ruby/backward.h +gc_hook.o: $(hdrdir)/ruby/backward/2/assume.h +gc_hook.o: $(hdrdir)/ruby/backward/2/attributes.h +gc_hook.o: $(hdrdir)/ruby/backward/2/bool.h +gc_hook.o: $(hdrdir)/ruby/backward/2/inttypes.h +gc_hook.o: $(hdrdir)/ruby/backward/2/limits.h +gc_hook.o: $(hdrdir)/ruby/backward/2/long_long.h +gc_hook.o: $(hdrdir)/ruby/backward/2/stdalign.h +gc_hook.o: $(hdrdir)/ruby/backward/2/stdarg.h +gc_hook.o: $(hdrdir)/ruby/debug.h +gc_hook.o: $(hdrdir)/ruby/defines.h +gc_hook.o: $(hdrdir)/ruby/intern.h +gc_hook.o: $(hdrdir)/ruby/internal/abi.h gc_hook.o: $(hdrdir)/ruby/internal/anyargs.h gc_hook.o: $(hdrdir)/ruby/internal/arithmetic.h gc_hook.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +52,7 @@ gc_hook.o: $(hdrdir)/ruby/internal/attr/noexcept.h gc_hook.o: $(hdrdir)/ruby/internal/attr/noinline.h gc_hook.o: $(hdrdir)/ruby/internal/attr/nonnull.h gc_hook.o: $(hdrdir)/ruby/internal/attr/noreturn.h +gc_hook.o: $(hdrdir)/ruby/internal/attr/packed_struct.h gc_hook.o: $(hdrdir)/ruby/internal/attr/pure.h gc_hook.o: $(hdrdir)/ruby/internal/attr/restrict.h gc_hook.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +112,6 @@ gc_hook.o: $(hdrdir)/ruby/internal/intern/enumerator.h gc_hook.o: $(hdrdir)/ruby/internal/intern/error.h gc_hook.o: $(hdrdir)/ruby/internal/intern/eval.h gc_hook.o: $(hdrdir)/ruby/internal/intern/file.h -gc_hook.o: $(hdrdir)/ruby/internal/intern/gc.h gc_hook.o: $(hdrdir)/ruby/internal/intern/hash.h gc_hook.o: $(hdrdir)/ruby/internal/intern/io.h gc_hook.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +128,7 @@ gc_hook.o: $(hdrdir)/ruby/internal/intern/re.h gc_hook.o: $(hdrdir)/ruby/internal/intern/ruby.h gc_hook.o: $(hdrdir)/ruby/internal/intern/select.h gc_hook.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +gc_hook.o: $(hdrdir)/ruby/internal/intern/set.h gc_hook.o: $(hdrdir)/ruby/internal/intern/signal.h gc_hook.o: $(hdrdir)/ruby/internal/intern/sprintf.h gc_hook.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,32 +143,18 @@ gc_hook.o: $(hdrdir)/ruby/internal/memory.h gc_hook.o: $(hdrdir)/ruby/internal/method.h gc_hook.o: $(hdrdir)/ruby/internal/module.h gc_hook.o: $(hdrdir)/ruby/internal/newobj.h -gc_hook.o: $(hdrdir)/ruby/internal/rgengc.h gc_hook.o: $(hdrdir)/ruby/internal/scan_args.h gc_hook.o: $(hdrdir)/ruby/internal/special_consts.h gc_hook.o: $(hdrdir)/ruby/internal/static_assert.h gc_hook.o: $(hdrdir)/ruby/internal/stdalign.h gc_hook.o: $(hdrdir)/ruby/internal/stdbool.h +gc_hook.o: $(hdrdir)/ruby/internal/stdckdint.h gc_hook.o: $(hdrdir)/ruby/internal/symbol.h gc_hook.o: $(hdrdir)/ruby/internal/value.h gc_hook.o: $(hdrdir)/ruby/internal/value_type.h gc_hook.o: $(hdrdir)/ruby/internal/variable.h gc_hook.o: $(hdrdir)/ruby/internal/warning_push.h gc_hook.o: $(hdrdir)/ruby/internal/xmalloc.h -gc_hook.o: $(hdrdir)/ruby/assert.h -gc_hook.o: $(hdrdir)/ruby/backward.h -gc_hook.o: $(hdrdir)/ruby/backward/2/assume.h -gc_hook.o: $(hdrdir)/ruby/backward/2/attributes.h -gc_hook.o: $(hdrdir)/ruby/backward/2/bool.h -gc_hook.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -gc_hook.o: $(hdrdir)/ruby/backward/2/inttypes.h -gc_hook.o: $(hdrdir)/ruby/backward/2/limits.h -gc_hook.o: $(hdrdir)/ruby/backward/2/long_long.h -gc_hook.o: $(hdrdir)/ruby/backward/2/stdalign.h -gc_hook.o: $(hdrdir)/ruby/backward/2/stdarg.h -gc_hook.o: $(hdrdir)/ruby/debug.h -gc_hook.o: $(hdrdir)/ruby/defines.h -gc_hook.o: $(hdrdir)/ruby/intern.h gc_hook.o: $(hdrdir)/ruby/missing.h gc_hook.o: $(hdrdir)/ruby/ruby.h gc_hook.o: $(hdrdir)/ruby/st.h @@ -161,6 +162,20 @@ gc_hook.o: $(hdrdir)/ruby/subst.h gc_hook.o: gc_hook.c tracepoint.o: $(RUBY_EXTCONF_H) tracepoint.o: $(arch_hdrdir)/ruby/config.h +tracepoint.o: $(hdrdir)/ruby/assert.h +tracepoint.o: $(hdrdir)/ruby/backward.h +tracepoint.o: $(hdrdir)/ruby/backward/2/assume.h +tracepoint.o: $(hdrdir)/ruby/backward/2/attributes.h +tracepoint.o: $(hdrdir)/ruby/backward/2/bool.h +tracepoint.o: $(hdrdir)/ruby/backward/2/inttypes.h +tracepoint.o: $(hdrdir)/ruby/backward/2/limits.h +tracepoint.o: $(hdrdir)/ruby/backward/2/long_long.h +tracepoint.o: $(hdrdir)/ruby/backward/2/stdalign.h +tracepoint.o: $(hdrdir)/ruby/backward/2/stdarg.h +tracepoint.o: $(hdrdir)/ruby/debug.h +tracepoint.o: $(hdrdir)/ruby/defines.h +tracepoint.o: $(hdrdir)/ruby/intern.h +tracepoint.o: $(hdrdir)/ruby/internal/abi.h tracepoint.o: $(hdrdir)/ruby/internal/anyargs.h tracepoint.o: $(hdrdir)/ruby/internal/arithmetic.h tracepoint.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -198,6 +213,7 @@ tracepoint.o: $(hdrdir)/ruby/internal/attr/noexcept.h tracepoint.o: $(hdrdir)/ruby/internal/attr/noinline.h tracepoint.o: $(hdrdir)/ruby/internal/attr/nonnull.h tracepoint.o: $(hdrdir)/ruby/internal/attr/noreturn.h +tracepoint.o: $(hdrdir)/ruby/internal/attr/packed_struct.h tracepoint.o: $(hdrdir)/ruby/internal/attr/pure.h tracepoint.o: $(hdrdir)/ruby/internal/attr/restrict.h tracepoint.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -257,7 +273,6 @@ tracepoint.o: $(hdrdir)/ruby/internal/intern/enumerator.h tracepoint.o: $(hdrdir)/ruby/internal/intern/error.h tracepoint.o: $(hdrdir)/ruby/internal/intern/eval.h tracepoint.o: $(hdrdir)/ruby/internal/intern/file.h -tracepoint.o: $(hdrdir)/ruby/internal/intern/gc.h tracepoint.o: $(hdrdir)/ruby/internal/intern/hash.h tracepoint.o: $(hdrdir)/ruby/internal/intern/io.h tracepoint.o: $(hdrdir)/ruby/internal/intern/load.h @@ -274,6 +289,7 @@ tracepoint.o: $(hdrdir)/ruby/internal/intern/re.h tracepoint.o: $(hdrdir)/ruby/internal/intern/ruby.h tracepoint.o: $(hdrdir)/ruby/internal/intern/select.h tracepoint.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +tracepoint.o: $(hdrdir)/ruby/internal/intern/set.h tracepoint.o: $(hdrdir)/ruby/internal/intern/signal.h tracepoint.o: $(hdrdir)/ruby/internal/intern/sprintf.h tracepoint.o: $(hdrdir)/ruby/internal/intern/string.h @@ -288,32 +304,18 @@ tracepoint.o: $(hdrdir)/ruby/internal/memory.h tracepoint.o: $(hdrdir)/ruby/internal/method.h tracepoint.o: $(hdrdir)/ruby/internal/module.h tracepoint.o: $(hdrdir)/ruby/internal/newobj.h -tracepoint.o: $(hdrdir)/ruby/internal/rgengc.h tracepoint.o: $(hdrdir)/ruby/internal/scan_args.h tracepoint.o: $(hdrdir)/ruby/internal/special_consts.h tracepoint.o: $(hdrdir)/ruby/internal/static_assert.h tracepoint.o: $(hdrdir)/ruby/internal/stdalign.h tracepoint.o: $(hdrdir)/ruby/internal/stdbool.h +tracepoint.o: $(hdrdir)/ruby/internal/stdckdint.h tracepoint.o: $(hdrdir)/ruby/internal/symbol.h tracepoint.o: $(hdrdir)/ruby/internal/value.h tracepoint.o: $(hdrdir)/ruby/internal/value_type.h tracepoint.o: $(hdrdir)/ruby/internal/variable.h tracepoint.o: $(hdrdir)/ruby/internal/warning_push.h tracepoint.o: $(hdrdir)/ruby/internal/xmalloc.h -tracepoint.o: $(hdrdir)/ruby/assert.h -tracepoint.o: $(hdrdir)/ruby/backward.h -tracepoint.o: $(hdrdir)/ruby/backward/2/assume.h -tracepoint.o: $(hdrdir)/ruby/backward/2/attributes.h -tracepoint.o: $(hdrdir)/ruby/backward/2/bool.h -tracepoint.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -tracepoint.o: $(hdrdir)/ruby/backward/2/inttypes.h -tracepoint.o: $(hdrdir)/ruby/backward/2/limits.h -tracepoint.o: $(hdrdir)/ruby/backward/2/long_long.h -tracepoint.o: $(hdrdir)/ruby/backward/2/stdalign.h -tracepoint.o: $(hdrdir)/ruby/backward/2/stdarg.h -tracepoint.o: $(hdrdir)/ruby/debug.h -tracepoint.o: $(hdrdir)/ruby/defines.h -tracepoint.o: $(hdrdir)/ruby/intern.h tracepoint.o: $(hdrdir)/ruby/missing.h tracepoint.o: $(hdrdir)/ruby/ruby.h tracepoint.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/tracepoint/gc_hook.c b/ext/-test-/tracepoint/gc_hook.c index 5fd46fa518..525be6da63 100644 --- a/ext/-test-/tracepoint/gc_hook.c +++ b/ext/-test-/tracepoint/gc_hook.c @@ -2,6 +2,7 @@ #include "ruby/debug.h" static int invoking; /* TODO: should not be global variable */ +extern VALUE tp_mBug; static VALUE invoke_proc_ensure(VALUE _) @@ -17,9 +18,9 @@ invoke_proc_begin(VALUE proc) } static void -invoke_proc(void *data) +invoke_proc(void *ivar_name) { - VALUE proc = (VALUE)data; + VALUE proc = rb_ivar_get(tp_mBug, rb_intern(ivar_name)); invoking += 1; rb_ensure(invoke_proc_begin, proc, invoke_proc_ensure, 0); } @@ -28,52 +29,55 @@ static void gc_start_end_i(VALUE tpval, void *data) { if (0) { - rb_trace_arg_t *tparg = rb_tracearg_from_tracepoint(tpval); - fprintf(stderr, "trace: %s\n", rb_tracearg_event_flag(tparg) == RUBY_INTERNAL_EVENT_GC_START ? "gc_start" : "gc_end"); + rb_trace_arg_t *tparg = rb_tracearg_from_tracepoint(tpval); + fprintf(stderr, "trace: %s\n", rb_tracearg_event_flag(tparg) == RUBY_INTERNAL_EVENT_GC_START ? "gc_start" : "gc_end"); } if (invoking == 0) { - rb_postponed_job_register(0, invoke_proc, data); + /* will overwrite the existing handle with new data on the second and subsequent call */ + rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, invoke_proc, data); + rb_postponed_job_trigger(h); } } static VALUE -set_gc_hook(VALUE module, VALUE proc, rb_event_flag_t event, const char *tp_str, const char *proc_str) +set_gc_hook(VALUE proc, rb_event_flag_t event, const char *tp_str, const char *proc_str) { VALUE tpval; ID tp_key = rb_intern(tp_str); /* disable previous keys */ - if (rb_ivar_defined(module, tp_key) != 0 && - RTEST(tpval = rb_ivar_get(module, tp_key))) { - rb_tracepoint_disable(tpval); - rb_ivar_set(module, tp_key, Qnil); + if (rb_ivar_defined(tp_mBug, tp_key) != 0 && + RTEST(tpval = rb_ivar_get(tp_mBug, tp_key))) { + rb_tracepoint_disable(tpval); + rb_ivar_set(tp_mBug, tp_key, Qnil); } if (RTEST(proc)) { - if (!rb_obj_is_proc(proc)) { - rb_raise(rb_eTypeError, "trace_func needs to be Proc"); - } + if (!rb_obj_is_proc(proc)) { + rb_raise(rb_eTypeError, "trace_func needs to be Proc"); + } - tpval = rb_tracepoint_new(0, event, gc_start_end_i, (void *)proc); - rb_ivar_set(module, tp_key, tpval); - rb_tracepoint_enable(tpval); + rb_ivar_set(tp_mBug, rb_intern(proc_str), proc); + tpval = rb_tracepoint_new(0, event, gc_start_end_i, (void *)proc_str); + rb_ivar_set(tp_mBug, tp_key, tpval); + rb_tracepoint_enable(tpval); } return proc; } static VALUE -set_after_gc_start(VALUE module, VALUE proc) +set_after_gc_start(VALUE _self, VALUE proc) { - return set_gc_hook(module, proc, RUBY_INTERNAL_EVENT_GC_START, - "__set_after_gc_start_tpval__", "__set_after_gc_start_proc__"); + return set_gc_hook(proc, RUBY_INTERNAL_EVENT_GC_START, + "__set_after_gc_start_tpval__", "__set_after_gc_start_proc__"); } static VALUE -start_after_gc_exit(VALUE module, VALUE proc) +start_after_gc_exit(VALUE _self, VALUE proc) { - return set_gc_hook(module, proc, RUBY_INTERNAL_EVENT_GC_EXIT, + return set_gc_hook(proc, RUBY_INTERNAL_EVENT_GC_EXIT, "__set_after_gc_exit_tpval__", "__set_after_gc_exit_proc__"); } diff --git a/ext/-test-/tracepoint/tracepoint.c b/ext/-test-/tracepoint/tracepoint.c index aa8c212f99..001d9513b2 100644 --- a/ext/-test-/tracepoint/tracepoint.c +++ b/ext/-test-/tracepoint/tracepoint.c @@ -1,6 +1,8 @@ #include "ruby/ruby.h" #include "ruby/debug.h" +VALUE tp_mBug; + struct tracepoint_track { size_t newobj_count; size_t free_count; @@ -21,35 +23,35 @@ tracepoint_track_objspace_events_i(VALUE tpval, void *data) switch (rb_tracearg_event_flag(tparg)) { case RUBY_INTERNAL_EVENT_NEWOBJ: - { - VALUE obj = rb_tracearg_object(tparg); - if (track->objects_count < objects_max) - track->objects[track->objects_count++] = obj; - track->newobj_count++; - break; - } + { + VALUE obj = rb_tracearg_object(tparg); + if (track->objects_count < objects_max) + track->objects[track->objects_count++] = obj; + track->newobj_count++; + break; + } case RUBY_INTERNAL_EVENT_FREEOBJ: - { - track->free_count++; - break; - } + { + track->free_count++; + break; + } case RUBY_INTERNAL_EVENT_GC_START: - { - track->gc_start_count++; - break; - } + { + track->gc_start_count++; + break; + } case RUBY_INTERNAL_EVENT_GC_END_MARK: - { - track->gc_end_mark_count++; - break; - } + { + track->gc_end_mark_count++; + break; + } case RUBY_INTERNAL_EVENT_GC_END_SWEEP: - { - track->gc_end_sweep_count++; - break; - } + { + track->gc_end_sweep_count++; + break; + } default: - rb_raise(rb_eRuntimeError, "unknown event"); + rb_raise(rb_eRuntimeError, "unknown event"); } } @@ -58,9 +60,9 @@ tracepoint_track_objspace_events(VALUE self) { struct tracepoint_track track = {0, 0, 0, 0, 0,}; VALUE tpval = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ | RUBY_INTERNAL_EVENT_FREEOBJ | - RUBY_INTERNAL_EVENT_GC_START | RUBY_INTERNAL_EVENT_GC_END_MARK | - RUBY_INTERNAL_EVENT_GC_END_SWEEP, - tracepoint_track_objspace_events_i, &track); + RUBY_INTERNAL_EVENT_GC_START | RUBY_INTERNAL_EVENT_GC_END_MARK | + RUBY_INTERNAL_EVENT_GC_END_SWEEP, + tracepoint_track_objspace_events_i, &track); VALUE result = rb_ary_new(); rb_tracepoint_enable(tpval); @@ -89,8 +91,8 @@ void Init_gc_hook(VALUE); void Init_tracepoint(void) { - VALUE mBug = rb_define_module("Bug"); - Init_gc_hook(mBug); - rb_define_module_function(mBug, "tracepoint_track_objspace_events", tracepoint_track_objspace_events, 0); - rb_define_module_function(mBug, "tracepoint_specify_normal_and_internal_events", tracepoint_specify_normal_and_internal_events, 0); + tp_mBug = rb_define_module("Bug"); // GC root + Init_gc_hook(tp_mBug); + rb_define_module_function(tp_mBug, "tracepoint_track_objspace_events", tracepoint_track_objspace_events, 0); + rb_define_module_function(tp_mBug, "tracepoint_specify_normal_and_internal_events", tracepoint_specify_normal_and_internal_events, 0); } diff --git a/ext/-test-/typeddata/depend b/ext/-test-/typeddata/depend index 6204fb0524..b9b4915eee 100644 --- a/ext/-test-/typeddata/depend +++ b/ext/-test-/typeddata/depend @@ -2,6 +2,19 @@ typeddata.o: $(RUBY_EXTCONF_H) typeddata.o: $(arch_hdrdir)/ruby/config.h typeddata.o: $(hdrdir)/ruby.h +typeddata.o: $(hdrdir)/ruby/assert.h +typeddata.o: $(hdrdir)/ruby/backward.h +typeddata.o: $(hdrdir)/ruby/backward/2/assume.h +typeddata.o: $(hdrdir)/ruby/backward/2/attributes.h +typeddata.o: $(hdrdir)/ruby/backward/2/bool.h +typeddata.o: $(hdrdir)/ruby/backward/2/inttypes.h +typeddata.o: $(hdrdir)/ruby/backward/2/limits.h +typeddata.o: $(hdrdir)/ruby/backward/2/long_long.h +typeddata.o: $(hdrdir)/ruby/backward/2/stdalign.h +typeddata.o: $(hdrdir)/ruby/backward/2/stdarg.h +typeddata.o: $(hdrdir)/ruby/defines.h +typeddata.o: $(hdrdir)/ruby/intern.h +typeddata.o: $(hdrdir)/ruby/internal/abi.h typeddata.o: $(hdrdir)/ruby/internal/anyargs.h typeddata.o: $(hdrdir)/ruby/internal/arithmetic.h typeddata.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ typeddata.o: $(hdrdir)/ruby/internal/attr/noexcept.h typeddata.o: $(hdrdir)/ruby/internal/attr/noinline.h typeddata.o: $(hdrdir)/ruby/internal/attr/nonnull.h typeddata.o: $(hdrdir)/ruby/internal/attr/noreturn.h +typeddata.o: $(hdrdir)/ruby/internal/attr/packed_struct.h typeddata.o: $(hdrdir)/ruby/internal/attr/pure.h typeddata.o: $(hdrdir)/ruby/internal/attr/restrict.h typeddata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ typeddata.o: $(hdrdir)/ruby/internal/intern/enumerator.h typeddata.o: $(hdrdir)/ruby/internal/intern/error.h typeddata.o: $(hdrdir)/ruby/internal/intern/eval.h typeddata.o: $(hdrdir)/ruby/internal/intern/file.h -typeddata.o: $(hdrdir)/ruby/internal/intern/gc.h typeddata.o: $(hdrdir)/ruby/internal/intern/hash.h typeddata.o: $(hdrdir)/ruby/internal/intern/io.h typeddata.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ typeddata.o: $(hdrdir)/ruby/internal/intern/re.h typeddata.o: $(hdrdir)/ruby/internal/intern/ruby.h typeddata.o: $(hdrdir)/ruby/internal/intern/select.h typeddata.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +typeddata.o: $(hdrdir)/ruby/internal/intern/set.h typeddata.o: $(hdrdir)/ruby/internal/intern/signal.h typeddata.o: $(hdrdir)/ruby/internal/intern/sprintf.h typeddata.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ typeddata.o: $(hdrdir)/ruby/internal/memory.h typeddata.o: $(hdrdir)/ruby/internal/method.h typeddata.o: $(hdrdir)/ruby/internal/module.h typeddata.o: $(hdrdir)/ruby/internal/newobj.h -typeddata.o: $(hdrdir)/ruby/internal/rgengc.h typeddata.o: $(hdrdir)/ruby/internal/scan_args.h typeddata.o: $(hdrdir)/ruby/internal/special_consts.h typeddata.o: $(hdrdir)/ruby/internal/static_assert.h typeddata.o: $(hdrdir)/ruby/internal/stdalign.h typeddata.o: $(hdrdir)/ruby/internal/stdbool.h +typeddata.o: $(hdrdir)/ruby/internal/stdckdint.h typeddata.o: $(hdrdir)/ruby/internal/symbol.h typeddata.o: $(hdrdir)/ruby/internal/value.h typeddata.o: $(hdrdir)/ruby/internal/value_type.h typeddata.o: $(hdrdir)/ruby/internal/variable.h typeddata.o: $(hdrdir)/ruby/internal/warning_push.h typeddata.o: $(hdrdir)/ruby/internal/xmalloc.h -typeddata.o: $(hdrdir)/ruby/assert.h -typeddata.o: $(hdrdir)/ruby/backward.h -typeddata.o: $(hdrdir)/ruby/backward/2/assume.h -typeddata.o: $(hdrdir)/ruby/backward/2/attributes.h -typeddata.o: $(hdrdir)/ruby/backward/2/bool.h -typeddata.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -typeddata.o: $(hdrdir)/ruby/backward/2/inttypes.h -typeddata.o: $(hdrdir)/ruby/backward/2/limits.h -typeddata.o: $(hdrdir)/ruby/backward/2/long_long.h -typeddata.o: $(hdrdir)/ruby/backward/2/stdalign.h -typeddata.o: $(hdrdir)/ruby/backward/2/stdarg.h -typeddata.o: $(hdrdir)/ruby/defines.h -typeddata.o: $(hdrdir)/ruby/intern.h typeddata.o: $(hdrdir)/ruby/missing.h typeddata.o: $(hdrdir)/ruby/ruby.h typeddata.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/typeddata/typeddata.c b/ext/-test-/typeddata/typeddata.c index 2adfd56ae8..cf3178fd18 100644 --- a/ext/-test-/typeddata/typeddata.c +++ b/ext/-test-/typeddata/typeddata.c @@ -27,7 +27,7 @@ test_make(VALUE klass, VALUE num) unsigned long i, n = NUM2UINT(num); for (i = 0; i < n; i++) { - test_alloc(klass); + test_alloc(klass); } return Qnil; diff --git a/ext/-test-/vm/at_exit.c b/ext/-test-/vm/at_exit.c index 6cfbfafa9e..efc439b26a 100644 --- a/ext/-test-/vm/at_exit.c +++ b/ext/-test-/vm/at_exit.c @@ -23,14 +23,14 @@ register_at_exit(VALUE self, VALUE t) { switch (t) { case Qtrue: - ruby_vm_at_exit(print_begin); - break; + ruby_vm_at_exit(print_begin); + break; case Qfalse: - ruby_vm_at_exit(print_end); - break; + ruby_vm_at_exit(print_end); + break; default: - ruby_vm_at_exit(do_nothing); - break; + ruby_vm_at_exit(do_nothing); + break; } return self; } diff --git a/ext/-test-/vm/depend b/ext/-test-/vm/depend index 6669e52d4c..9313f2ee36 100644 --- a/ext/-test-/vm/depend +++ b/ext/-test-/vm/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START at_exit.o: $(RUBY_EXTCONF_H) at_exit.o: $(arch_hdrdir)/ruby/config.h +at_exit.o: $(hdrdir)/ruby/assert.h +at_exit.o: $(hdrdir)/ruby/backward.h +at_exit.o: $(hdrdir)/ruby/backward/2/assume.h +at_exit.o: $(hdrdir)/ruby/backward/2/attributes.h +at_exit.o: $(hdrdir)/ruby/backward/2/bool.h +at_exit.o: $(hdrdir)/ruby/backward/2/inttypes.h +at_exit.o: $(hdrdir)/ruby/backward/2/limits.h +at_exit.o: $(hdrdir)/ruby/backward/2/long_long.h +at_exit.o: $(hdrdir)/ruby/backward/2/stdalign.h +at_exit.o: $(hdrdir)/ruby/backward/2/stdarg.h +at_exit.o: $(hdrdir)/ruby/defines.h +at_exit.o: $(hdrdir)/ruby/intern.h +at_exit.o: $(hdrdir)/ruby/internal/abi.h at_exit.o: $(hdrdir)/ruby/internal/anyargs.h at_exit.o: $(hdrdir)/ruby/internal/arithmetic.h at_exit.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ at_exit.o: $(hdrdir)/ruby/internal/attr/noexcept.h at_exit.o: $(hdrdir)/ruby/internal/attr/noinline.h at_exit.o: $(hdrdir)/ruby/internal/attr/nonnull.h at_exit.o: $(hdrdir)/ruby/internal/attr/noreturn.h +at_exit.o: $(hdrdir)/ruby/internal/attr/packed_struct.h at_exit.o: $(hdrdir)/ruby/internal/attr/pure.h at_exit.o: $(hdrdir)/ruby/internal/attr/restrict.h at_exit.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ at_exit.o: $(hdrdir)/ruby/internal/intern/enumerator.h at_exit.o: $(hdrdir)/ruby/internal/intern/error.h at_exit.o: $(hdrdir)/ruby/internal/intern/eval.h at_exit.o: $(hdrdir)/ruby/internal/intern/file.h -at_exit.o: $(hdrdir)/ruby/internal/intern/gc.h at_exit.o: $(hdrdir)/ruby/internal/intern/hash.h at_exit.o: $(hdrdir)/ruby/internal/intern/io.h at_exit.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ at_exit.o: $(hdrdir)/ruby/internal/intern/re.h at_exit.o: $(hdrdir)/ruby/internal/intern/ruby.h at_exit.o: $(hdrdir)/ruby/internal/intern/select.h at_exit.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +at_exit.o: $(hdrdir)/ruby/internal/intern/set.h at_exit.o: $(hdrdir)/ruby/internal/intern/signal.h at_exit.o: $(hdrdir)/ruby/internal/intern/sprintf.h at_exit.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ at_exit.o: $(hdrdir)/ruby/internal/memory.h at_exit.o: $(hdrdir)/ruby/internal/method.h at_exit.o: $(hdrdir)/ruby/internal/module.h at_exit.o: $(hdrdir)/ruby/internal/newobj.h -at_exit.o: $(hdrdir)/ruby/internal/rgengc.h at_exit.o: $(hdrdir)/ruby/internal/scan_args.h at_exit.o: $(hdrdir)/ruby/internal/special_consts.h at_exit.o: $(hdrdir)/ruby/internal/static_assert.h at_exit.o: $(hdrdir)/ruby/internal/stdalign.h at_exit.o: $(hdrdir)/ruby/internal/stdbool.h +at_exit.o: $(hdrdir)/ruby/internal/stdckdint.h at_exit.o: $(hdrdir)/ruby/internal/symbol.h at_exit.o: $(hdrdir)/ruby/internal/value.h at_exit.o: $(hdrdir)/ruby/internal/value_type.h at_exit.o: $(hdrdir)/ruby/internal/variable.h at_exit.o: $(hdrdir)/ruby/internal/warning_push.h at_exit.o: $(hdrdir)/ruby/internal/xmalloc.h -at_exit.o: $(hdrdir)/ruby/assert.h -at_exit.o: $(hdrdir)/ruby/backward.h -at_exit.o: $(hdrdir)/ruby/backward/2/assume.h -at_exit.o: $(hdrdir)/ruby/backward/2/attributes.h -at_exit.o: $(hdrdir)/ruby/backward/2/bool.h -at_exit.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -at_exit.o: $(hdrdir)/ruby/backward/2/inttypes.h -at_exit.o: $(hdrdir)/ruby/backward/2/limits.h -at_exit.o: $(hdrdir)/ruby/backward/2/long_long.h -at_exit.o: $(hdrdir)/ruby/backward/2/stdalign.h -at_exit.o: $(hdrdir)/ruby/backward/2/stdarg.h -at_exit.o: $(hdrdir)/ruby/defines.h -at_exit.o: $(hdrdir)/ruby/intern.h at_exit.o: $(hdrdir)/ruby/missing.h at_exit.o: $(hdrdir)/ruby/ruby.h at_exit.o: $(hdrdir)/ruby/st.h diff --git a/ext/-test-/wait/depend b/ext/-test-/wait/depend index f2999f3c51..f793d84831 100644 --- a/ext/-test-/wait/depend +++ b/ext/-test-/wait/depend @@ -6,7 +6,6 @@ wait.o: $(hdrdir)/ruby/backward.h wait.o: $(hdrdir)/ruby/backward/2/assume.h wait.o: $(hdrdir)/ruby/backward/2/attributes.h wait.o: $(hdrdir)/ruby/backward/2/bool.h -wait.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h wait.o: $(hdrdir)/ruby/backward/2/inttypes.h wait.o: $(hdrdir)/ruby/backward/2/limits.h wait.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ wait.o: $(hdrdir)/ruby/backward/2/stdarg.h wait.o: $(hdrdir)/ruby/defines.h wait.o: $(hdrdir)/ruby/encoding.h wait.o: $(hdrdir)/ruby/intern.h +wait.o: $(hdrdir)/ruby/internal/abi.h wait.o: $(hdrdir)/ruby/internal/anyargs.h wait.o: $(hdrdir)/ruby/internal/arithmetic.h wait.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ wait.o: $(hdrdir)/ruby/internal/attr/noexcept.h wait.o: $(hdrdir)/ruby/internal/attr/noinline.h wait.o: $(hdrdir)/ruby/internal/attr/nonnull.h wait.o: $(hdrdir)/ruby/internal/attr/noreturn.h +wait.o: $(hdrdir)/ruby/internal/attr/packed_struct.h wait.o: $(hdrdir)/ruby/internal/attr/pure.h wait.o: $(hdrdir)/ruby/internal/attr/restrict.h wait.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -120,7 +121,6 @@ wait.o: $(hdrdir)/ruby/internal/intern/enumerator.h wait.o: $(hdrdir)/ruby/internal/intern/error.h wait.o: $(hdrdir)/ruby/internal/intern/eval.h wait.o: $(hdrdir)/ruby/internal/intern/file.h -wait.o: $(hdrdir)/ruby/internal/intern/gc.h wait.o: $(hdrdir)/ruby/internal/intern/hash.h wait.o: $(hdrdir)/ruby/internal/intern/io.h wait.o: $(hdrdir)/ruby/internal/intern/load.h @@ -137,6 +137,7 @@ wait.o: $(hdrdir)/ruby/internal/intern/re.h wait.o: $(hdrdir)/ruby/internal/intern/ruby.h wait.o: $(hdrdir)/ruby/internal/intern/select.h wait.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +wait.o: $(hdrdir)/ruby/internal/intern/set.h wait.o: $(hdrdir)/ruby/internal/intern/signal.h wait.o: $(hdrdir)/ruby/internal/intern/sprintf.h wait.o: $(hdrdir)/ruby/internal/intern/string.h @@ -151,12 +152,12 @@ wait.o: $(hdrdir)/ruby/internal/memory.h wait.o: $(hdrdir)/ruby/internal/method.h wait.o: $(hdrdir)/ruby/internal/module.h wait.o: $(hdrdir)/ruby/internal/newobj.h -wait.o: $(hdrdir)/ruby/internal/rgengc.h wait.o: $(hdrdir)/ruby/internal/scan_args.h wait.o: $(hdrdir)/ruby/internal/special_consts.h wait.o: $(hdrdir)/ruby/internal/static_assert.h wait.o: $(hdrdir)/ruby/internal/stdalign.h wait.o: $(hdrdir)/ruby/internal/stdbool.h +wait.o: $(hdrdir)/ruby/internal/stdckdint.h wait.o: $(hdrdir)/ruby/internal/symbol.h wait.o: $(hdrdir)/ruby/internal/value.h wait.o: $(hdrdir)/ruby/internal/value_type.h @@ -171,167 +172,4 @@ wait.o: $(hdrdir)/ruby/ruby.h wait.o: $(hdrdir)/ruby/st.h wait.o: $(hdrdir)/ruby/subst.h wait.o: wait.c -wait_for_single_fd.o: $(RUBY_EXTCONF_H) -wait_for_single_fd.o: $(arch_hdrdir)/ruby/config.h -wait_for_single_fd.o: $(hdrdir)/ruby/assert.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/assume.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/attributes.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/bool.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/inttypes.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/limits.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/long_long.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdalign.h -wait_for_single_fd.o: $(hdrdir)/ruby/backward/2/stdarg.h -wait_for_single_fd.o: $(hdrdir)/ruby/defines.h -wait_for_single_fd.o: $(hdrdir)/ruby/encoding.h -wait_for_single_fd.o: $(hdrdir)/ruby/intern.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/anyargs.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/char.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/double.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/int.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/short.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/assume.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/artificial.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/cold.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/const.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/constexpr.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/deprecated.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/error.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/forceinline.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/format.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noalias.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/pure.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/warning.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/attr/weakref.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/cast.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/compiler_since.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/config.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/constant_p.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rarray.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbasic.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rbignum.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rclass.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rdata.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rfile.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rhash.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/robject.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rregexp.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstring.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rstruct.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/ctype.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/dllexport.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/dosish.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/error.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/eval.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/event.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/fl_type.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/gc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/glob.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/globals.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/attribute.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/builtin.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/c_attribute.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/extension.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/feature.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/has/warning.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/array.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/bignum.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/class.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/compar.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/complex.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/cont.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/dir.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enum.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/error.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/eval.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/file.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/gc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/hash.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/io.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/load.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/marshal.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/numeric.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/object.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/parse.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/proc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/process.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/random.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/range.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/rational.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/re.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/ruby.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/signal.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/sprintf.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/string.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/struct.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/thread.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/time.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/variable.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/intern/vm.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/interpreter.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/iterator.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/memory.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/method.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/module.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/newobj.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/rgengc.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/scan_args.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/special_consts.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/static_assert.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdalign.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/stdbool.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/symbol.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/value.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/value_type.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/variable.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/warning_push.h -wait_for_single_fd.o: $(hdrdir)/ruby/internal/xmalloc.h -wait_for_single_fd.o: $(hdrdir)/ruby/io.h -wait_for_single_fd.o: $(hdrdir)/ruby/missing.h -wait_for_single_fd.o: $(hdrdir)/ruby/onigmo.h -wait_for_single_fd.o: $(hdrdir)/ruby/oniguruma.h -wait_for_single_fd.o: $(hdrdir)/ruby/ruby.h -wait_for_single_fd.o: $(hdrdir)/ruby/st.h -wait_for_single_fd.o: $(hdrdir)/ruby/subst.h -wait_for_single_fd.o: wait_for_single_fd.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/win32/console/attribute.c b/ext/-test-/win32/console/attribute.c index e3e80a199f..b43ba23a5c 100644 --- a/ext/-test-/win32/console/attribute.c +++ b/ext/-test-/win32/console/attribute.c @@ -19,13 +19,13 @@ console_info(VALUE klass, VALUE io) CONSOLE_SCREEN_BUFFER_INFO csbi; if (!GetConsoleScreenBufferInfo(h, &csbi)) - rb_syserr_fail(rb_w32_map_errno(GetLastError()), "not console"); + rb_syserr_fail(rb_w32_map_errno(GetLastError()), "not console"); return rb_struct_new(rb_cConsoleScreenBufferInfo, - INT2FIX(csbi.dwSize.X), - INT2FIX(csbi.dwSize.Y), - INT2FIX(csbi.dwCursorPosition.X), - INT2FIX(csbi.dwCursorPosition.Y), - INT2FIX(csbi.wAttributes)); + INT2FIX(csbi.dwSize.X), + INT2FIX(csbi.dwSize.Y), + INT2FIX(csbi.dwCursorPosition.X), + INT2FIX(csbi.dwCursorPosition.Y), + INT2FIX(csbi.wAttributes)); } static VALUE @@ -44,9 +44,9 @@ void Init_attribute(VALUE m) { rb_cConsoleScreenBufferInfo = rb_struct_define_under(m, "ConsoleScreenBufferInfo", - "size_x", "size_y", - "cur_x", "cur_y", - "attr", NULL); + "size_x", "size_y", + "cur_x", "cur_y", + "attr", NULL); rb_define_singleton_method(m, "console_info", console_info, 1); rb_define_singleton_method(m, "console_attribute", console_set_attribute, 2); diff --git a/ext/-test-/win32/dln/extconf.rb b/ext/-test-/win32/dln/extconf.rb index d72b6a868c..bea52cfec3 100644 --- a/ext/-test-/win32/dln/extconf.rb +++ b/ext/-test-/win32/dln/extconf.rb @@ -7,6 +7,7 @@ if $mingw or $mswin testdll = "dlntest.dll" $cleanfiles << testdll $cleanfiles << "dlntest.#{$LIBEXT}" + $cleanfiles << "libdlntest.#{$OBJEXT}" config_string('cleanobjs') {|t| $cleanfiles.concat(t.gsub(/\$\*/, 'dlntest').split)} create_makefile("-test-/win32/dln") do |m| diff --git a/ext/-test-/win32/fd_setsize/fd_setsize.c b/ext/-test-/win32/fd_setsize/fd_setsize.c index 8da8b1eaa0..e29114a0ca 100644 --- a/ext/-test-/win32/fd_setsize/fd_setsize.c +++ b/ext/-test-/win32/fd_setsize/fd_setsize.c @@ -37,11 +37,11 @@ test_fdset(VALUE self) FD_ZERO(&set); for (i = 0; i < FD_SETSIZE * 2; i++) { - int sd = socket(AF_INET, SOCK_DGRAM, 0); - FD_SET(sd, &set); - if (set.fd_count > FD_SETSIZE) { - return Qfalse; - } + int sd = socket(AF_INET, SOCK_DGRAM, 0); + FD_SET(sd, &set); + if (set.fd_count > FD_SETSIZE) { + return Qfalse; + } } return Qtrue; } diff --git a/ext/.document b/ext/.document index aeb40c60fb..374abe6580 100644 --- a/ext/.document +++ b/ext/.document @@ -11,7 +11,6 @@ date/date_parse.c date/date_strftime.c date/date_strptime.c date/lib -dbm/dbm.c digest/bubblebabble/bubblebabble.c digest/digest.c digest/lib @@ -22,7 +21,6 @@ digest/sha2/sha2init.c digest/sha2/lib etc/etc.c fcntl/fcntl.c -fiber/fiber.c fiddle/closure.c fiddle/conversions.c fiddle/fiddle.c @@ -31,9 +29,7 @@ fiddle/pinned.c fiddle/pointer.c fiddle/handle.c fiddle/lib -gdbm/gdbm.c -io/console/console.c -io/console/lib +io/console/ io/nonblock/nonblock.c io/wait/wait.c json/generator/generator.c @@ -80,8 +76,6 @@ openssl/ossl_x509name.c openssl/ossl_x509req.c openssl/ossl_x509revoked.c openssl/ossl_x509store.c -pathname/lib -pathname/pathname.c psych/lib psych/psych.c psych/psych_emitter.c @@ -96,6 +90,7 @@ readline/readline.c ripper/lib socket stringio/stringio.c +strscan/lib strscan/strscan.c syslog/syslog.c syslog/lib @@ -5,7 +5,6 @@ #continuation #coverage #date -#dbm #digest/bubblebabble #digest #digest/md5 @@ -14,9 +13,7 @@ #digest/sha2 #etc #fcntl -#fiber #fiddle -#gdbm #io/console #io/nonblock #io/wait diff --git a/ext/Setup.atheos b/ext/Setup.atheos index 3f6263b1e2..91f73f32f9 100644 --- a/ext/Setup.atheos +++ b/ext/Setup.atheos @@ -1,23 +1,19 @@ option nodynamic -#Win32API bigdecimal cgi/escape -dbm digest digest/md5 digest/rmd160 digest/sha1 digest/sha2 -enumerator etc fcntl -gdbm io/wait nkf #openssl pty -racc/parse +#racc/cparse readline ripper socket diff --git a/ext/Setup.nt b/ext/Setup.nt index dc36aa8688..1278f183e4 100644 --- a/ext/Setup.nt +++ b/ext/Setup.nt @@ -1,24 +1,20 @@ #option platform cygwin|mingw|mswin #option nodynamic -Win32API bigdecimal cgi/escape -#dbm digest digest/md5 digest/rmd160 digest/sha1 digest/sha2 -enumerator etc fcntl -#gdbm #io/wait nkf #openssl #pty -racc/cparse +#racc/cparse #readline #ripper socket diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c deleted file mode 100644 index 65e7c864e2..0000000000 --- a/ext/bigdecimal/bigdecimal.c +++ /dev/null @@ -1,7054 +0,0 @@ -/* - * - * Ruby BigDecimal(Variable decimal precision) extension library. - * - * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) - * - */ - -/* #define BIGDECIMAL_DEBUG 1 */ -#ifdef BIGDECIMAL_DEBUG -# define BIGDECIMAL_ENABLE_VPRINT 1 -#endif -#include "bigdecimal.h" -#include "ruby/util.h" - -#ifndef BIGDECIMAL_DEBUG -# undef NDEBUG -# define NDEBUG -#endif -#include <assert.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <math.h> - -#ifdef HAVE_IEEEFP_H -#include <ieeefp.h> -#endif - -#include "bits.h" -#include "static_assert.h" - -/* #define ENABLE_NUMERIC_STRING */ - -#define SIGNED_VALUE_MAX INTPTR_MAX -#define SIGNED_VALUE_MIN INTPTR_MIN -#define MUL_OVERFLOW_SIGNED_VALUE_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) - -VALUE rb_cBigDecimal; -VALUE rb_mBigMath; - -static ID id_BigDecimal_exception_mode; -static ID id_BigDecimal_rounding_mode; -static ID id_BigDecimal_precision_limit; - -static ID id_up; -static ID id_down; -static ID id_truncate; -static ID id_half_up; -static ID id_default; -static ID id_half_down; -static ID id_half_even; -static ID id_banker; -static ID id_ceiling; -static ID id_ceil; -static ID id_floor; -static ID id_to_r; -static ID id_eq; -static ID id_half; - -/* MACRO's to guard objects from GC by keeping them in stack */ -#ifdef RBIMPL_ATTR_MAYBE_UNUSED -#define ENTER(n) RBIMPL_ATTR_MAYBE_UNUSED() volatile VALUE vStack[n];int iStack=0 -#else -#define ENTER(n) volatile VALUE RB_UNUSED_VAR(vStack[n]);int iStack=0 -#endif -#define PUSH(x) (vStack[iStack++] = (VALUE)(x)) -#define SAVE(p) PUSH((p)->obj) -#define GUARD_OBJ(p,y) ((p)=(y), SAVE(p)) - -#define BASE_FIG BIGDECIMAL_COMPONENT_FIGURES -#define BASE BIGDECIMAL_BASE - -#define HALF_BASE (BASE/2) -#define BASE1 (BASE/10) - -#define LOG10_2 0.3010299956639812 - -#ifndef RRATIONAL_ZERO_P -# define RRATIONAL_ZERO_P(x) (FIXNUM_P(rb_rational_num(x)) && \ - FIX2LONG(rb_rational_num(x)) == 0) -#endif - -#ifndef RRATIONAL_NEGATIVE_P -# define RRATIONAL_NEGATIVE_P(x) RTEST(rb_funcall((x), '<', 1, INT2FIX(0))) -#endif - -#ifndef DECIMAL_SIZE_OF_BITS -#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999) -/* an approximation of ceil(n * log10(2)), upto 65536 at least */ -#endif - -#ifdef PRIsVALUE -# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) -# define RB_OBJ_STRING(obj) (obj) -#else -# define PRIsVALUE "s" -# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) -# define RB_OBJ_STRING(obj) StringValueCStr(obj) -#endif - -#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0) -#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0) - -/* - * ================== Ruby Interface part ========================== - */ -#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f) - -/* - * VP routines used in BigDecimal part - */ -static unsigned short VpGetException(void); -static void VpSetException(unsigned short f); -static void VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v); -static int VpLimitRound(Real *c, size_t ixDigit); -static Real *VpCopy(Real *pv, Real const* const x); - -#ifdef BIGDECIMAL_ENABLE_VPRINT -static int VPrint(FILE *fp,const char *cntl_chr,Real *a); -#endif - -/* - * **** BigDecimal part **** - */ - -static VALUE BigDecimal_nan(void); -static VALUE BigDecimal_positive_infinity(void); -static VALUE BigDecimal_negative_infinity(void); -static VALUE BigDecimal_positive_zero(void); -static VALUE BigDecimal_negative_zero(void); - -static void -BigDecimal_delete(void *pv) -{ - VpFree(pv); -} - -static size_t -BigDecimal_memsize(const void *ptr) -{ - const Real *pv = ptr; - return (sizeof(*pv) + pv->MaxPrec * sizeof(DECDIG)); -} - -#ifndef HAVE_RB_EXT_RACTOR_SAFE -# undef RUBY_TYPED_FROZEN_SHAREABLE -# define RUBY_TYPED_FROZEN_SHAREABLE 0 -#endif - -static const rb_data_type_t BigDecimal_data_type = { - "BigDecimal", - { 0, BigDecimal_delete, BigDecimal_memsize, }, -#ifdef RUBY_TYPED_FREE_IMMEDIATELY - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE -#endif -}; - -static inline int -is_kind_of_BigDecimal(VALUE const v) -{ - return rb_typeddata_is_kind_of(v, &BigDecimal_data_type); -} - -static void -VpCheckException(Real *p, bool always) -{ - if (VpIsNaN(p)) { - VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'(Not a Number)", always); - } - else if (VpIsPosInf(p)) { - VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", always); - } - else if (VpIsNegInf(p)) { - VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", always); - } -} - -static VALUE -VpCheckGetValue(Real *p) -{ - VpCheckException(p, false); - return p->obj; -} - -NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE)); - -static void -cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) -{ - VALUE str; - - if (rb_special_const_p(v)) { - str = rb_inspect(v); - } - else { - str = rb_class_name(rb_obj_class(v)); - } - - str = rb_str_cat2(rb_str_dup(str), " can't be coerced into BigDecimal"); - rb_exc_raise(rb_exc_new3(exc_class, str)); -} - -static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); -static VALUE rb_inum_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); -static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); -static VALUE rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); -static VALUE rb_cstr_convert_to_BigDecimal(const char *c_str, size_t digs, int raise_exception); -static VALUE rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); - -static Real* -GetVpValueWithPrec(VALUE v, long prec, int must) -{ - const size_t digs = prec < 0 ? SIZE_MAX : (size_t)prec; - - switch(TYPE(v)) { - case T_FLOAT: - v = rb_float_convert_to_BigDecimal(v, digs, must); - break; - - case T_RATIONAL: - v = rb_rational_convert_to_BigDecimal(v, digs, must); - break; - - case T_DATA: - if (!is_kind_of_BigDecimal(v)) { - goto SomeOneMayDoIt; - } - break; - - case T_FIXNUM: { - char szD[128]; - sprintf(szD, "%ld", FIX2LONG(v)); - v = rb_cstr_convert_to_BigDecimal(szD, VpBaseFig() * 2 + 1, must); - break; - } - -#ifdef ENABLE_NUMERIC_STRING - case T_STRING: { - const char *c_str = StringValueCStr(v); - v = rb_cstr_convert_to_BigDecimal(c_str, RSTRING_LEN(v) + VpBaseFig() + 1, must); - break; - } -#endif /* ENABLE_NUMERIC_STRING */ - - case T_BIGNUM: { - VALUE bg = rb_big2str(v, 10); - v = rb_cstr_convert_to_BigDecimal(RSTRING_PTR(bg), RSTRING_LEN(bg) + VpBaseFig() + 1, must); - RB_GC_GUARD(bg); - break; - } - - default: - goto SomeOneMayDoIt; - } - - Real *vp; - TypedData_Get_Struct(v, Real, &BigDecimal_data_type, vp); - return vp; - -SomeOneMayDoIt: - if (must) { - cannot_be_coerced_into_BigDecimal(rb_eTypeError, v); - } - return NULL; /* NULL means to coerce */ -} - -static Real* -GetVpValue(VALUE v, int must) -{ - return GetVpValueWithPrec(v, -1, must); -} - -/* call-seq: - * BigDecimal.double_fig - * - * The BigDecimal.double_fig class method returns the number of digits a - * Float number is allowed to have. The result depends upon the CPU and OS - * in use. - */ -static VALUE -BigDecimal_double_fig(VALUE self) -{ - return INT2FIX(VpDblFig()); -} - -/* call-seq: - * big_decimal.precs -> array - * - * Returns an Array of two Integer values that represent platform-dependent - * internal storage properties. - * - * This method is deprecated and will be removed in the future. - * Instead, use BigDecimal#n_significant_digits for obtaining the number of - * significant digits in scientific notation, and BigDecimal#precision for - * obtaining the number of digits in decimal notation. - * - * BigDecimal('5').precs #=> [9, 18] - */ - -static VALUE -BigDecimal_prec(VALUE self) -{ - ENTER(1); - Real *p; - VALUE obj; - - rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, - "BigDecimal#precs is deprecated and will be removed in the future; " - "use BigDecimal#precision instead."); - - GUARD_OBJ(p, GetVpValue(self, 1)); - obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()), - SIZET2NUM(p->MaxPrec*VpBaseFig())); - return obj; -} - -/* - * call-seq: - * big_decimal.precision -> intreger - * - * Returns the number of decimal digits in this number. - * - * Example: - * - * BigDecimal("0").precision # => 0 - * BigDecimal("1").precision # => 1 - * BigDecimal("-1e20").precision # => 21 - * BigDecimal("1e-20").precision # => 20 - * BigDecimal("Infinity").precision # => 0 - * BigDecimal("-Infinity").precision # => 0 - * BigDecimal("NaN").precision # => 0 - */ -static VALUE -BigDecimal_precision(VALUE self) -{ - ENTER(1); - - Real *p; - GUARD_OBJ(p, GetVpValue(self, 1)); - - /* - * The most significant digit is frac[0], and the least significant digit is frac[Prec-1]. - * When the exponent is zero, the decimal point is located just before frac[0]. - * When the exponent is negative, the decimal point moves to leftward. - * Conversely, when the exponent is positive, the decimal point moves to rightward. - * - * | frac[0] frac[1] frac[2] . frac[3] frac[4] ... frac[Prec-1] - * |------------------------> exponent == 3 - */ - - ssize_t ex = p->exponent; - ssize_t precision = 0; - if (ex < 0) { - precision = (-ex + 1) * BASE_FIG; /* 1 is for p->frac[0] */ - ex = 0; - } - else if (p->Prec > 0) { - DECDIG x = p->frac[0]; - for (precision = 0; x > 0; x /= 10) { - ++precision; - } - } - - if (ex > (ssize_t)p->Prec) { - precision += (ex - 1) * BASE_FIG; - } - else if (p->Prec > 0) { - ssize_t n = (ssize_t)p->Prec - 1; - while (n > 0 && p->frac[n] == 0) --n; - - precision += n * BASE_FIG; - - if (ex < (ssize_t)p->Prec) { - DECDIG x = p->frac[n]; - for (; x > 0 && x % 10 == 0; x /= 10) { - --precision; - } - } - } - - return SSIZET2NUM(precision); -} - -static VALUE -BigDecimal_n_significant_digits(VALUE self) -{ - ENTER(1); - - Real *p; - GUARD_OBJ(p, GetVpValue(self, 1)); - - ssize_t n = p->Prec; - while (n > 0 && p->frac[n-1] == 0) --n; - if (n <= 0) { - return INT2FIX(0); - } - - int nlz, ntz; - - DECDIG x = p->frac[0]; - for (nlz = BASE_FIG; x > 0; x /= 10) --nlz; - - x = p->frac[n-1]; - for (ntz = 0; x > 0 && x % 10 == 0; x /= 10) ++ntz; - - ssize_t n_digits = BASE_FIG * n - nlz - ntz; - return SSIZET2NUM(n_digits); -} - -/* - * call-seq: hash - * - * Creates a hash for this BigDecimal. - * - * Two BigDecimals with equal sign, - * fractional part and exponent have the same hash. - */ -static VALUE -BigDecimal_hash(VALUE self) -{ - ENTER(1); - Real *p; - st_index_t hash; - - GUARD_OBJ(p, GetVpValue(self, 1)); - hash = (st_index_t)p->sign; - /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ - if(hash == 2 || hash == (st_index_t)-2) { - hash ^= rb_memhash(p->frac, sizeof(DECDIG)*p->Prec); - hash += p->exponent; - } - return ST2FIX(hash); -} - -/* - * call-seq: _dump - * - * Method used to provide marshalling support. - * - * inf = BigDecimal('Infinity') - * #=> Infinity - * BigDecimal._load(inf._dump) - * #=> Infinity - * - * See the Marshal module. - */ -static VALUE -BigDecimal_dump(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *vp; - char *psz; - VALUE dummy; - volatile VALUE dump; - - rb_scan_args(argc, argv, "01", &dummy); - GUARD_OBJ(vp,GetVpValue(self, 1)); - dump = rb_str_new(0, VpNumOfChars(vp, "E")+50); - psz = RSTRING_PTR(dump); - sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig()); - VpToString(vp, psz+strlen(psz), 0, 0); - rb_str_resize(dump, strlen(psz)); - return dump; -} - -/* - * Internal method used to provide marshalling support. See the Marshal module. - */ -static VALUE -BigDecimal_load(VALUE self, VALUE str) -{ - ENTER(2); - Real *pv; - unsigned char *pch; - unsigned char ch; - unsigned long m=0; - - pch = (unsigned char *)StringValueCStr(str); - /* First get max prec */ - while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') { - if(!ISDIGIT(ch)) { - rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); - } - m = m*10 + (unsigned long)(ch-'0'); - } - if (m > VpBaseFig()) m -= VpBaseFig(); - GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self, true, true)); - m /= VpBaseFig(); - if (m && pv->MaxPrec > m) { - pv->MaxPrec = m+1; - } - return VpCheckGetValue(pv); -} - -static unsigned short -check_rounding_mode_option(VALUE const opts) -{ - VALUE mode; - char const *s; - long l; - - assert(RB_TYPE_P(opts, T_HASH)); - - if (NIL_P(opts)) - goto noopt; - - mode = rb_hash_lookup2(opts, ID2SYM(id_half), Qundef); - if (mode == Qundef || NIL_P(mode)) - goto noopt; - - if (SYMBOL_P(mode)) - mode = rb_sym2str(mode); - else if (!RB_TYPE_P(mode, T_STRING)) { - VALUE str_mode = rb_check_string_type(mode); - if (NIL_P(str_mode)) goto invalid; - mode = str_mode; - } - s = RSTRING_PTR(mode); - l = RSTRING_LEN(mode); - switch (l) { - case 2: - if (strncasecmp(s, "up", 2) == 0) - return VP_ROUND_HALF_UP; - break; - case 4: - if (strncasecmp(s, "even", 4) == 0) - return VP_ROUND_HALF_EVEN; - else if (strncasecmp(s, "down", 4) == 0) - return VP_ROUND_HALF_DOWN; - break; - default: - break; - } - invalid: - if (NIL_P(mode)) - rb_raise(rb_eArgError, "invalid rounding mode: nil"); - else - rb_raise(rb_eArgError, "invalid rounding mode: %"PRIsVALUE, mode); - - noopt: - return VpGetRoundMode(); -} - -static unsigned short -check_rounding_mode(VALUE const v) -{ - unsigned short sw; - ID id; - switch (TYPE(v)) { - case T_SYMBOL: - id = SYM2ID(v); - if (id == id_up) - return VP_ROUND_UP; - if (id == id_down || id == id_truncate) - return VP_ROUND_DOWN; - if (id == id_half_up || id == id_default) - return VP_ROUND_HALF_UP; - if (id == id_half_down) - return VP_ROUND_HALF_DOWN; - if (id == id_half_even || id == id_banker) - return VP_ROUND_HALF_EVEN; - if (id == id_ceiling || id == id_ceil) - return VP_ROUND_CEIL; - if (id == id_floor) - return VP_ROUND_FLOOR; - rb_raise(rb_eArgError, "invalid rounding mode"); - - default: - break; - } - - sw = NUM2USHORT(v); - if (!VpIsRoundMode(sw)) { - rb_raise(rb_eArgError, "invalid rounding mode"); - } - return sw; -} - -/* call-seq: - * BigDecimal.mode(mode, value) - * - * Controls handling of arithmetic exceptions and rounding. If no value - * is supplied, the current value is returned. - * - * Six values of the mode parameter control the handling of arithmetic - * exceptions: - * - * BigDecimal::EXCEPTION_NaN - * BigDecimal::EXCEPTION_INFINITY - * BigDecimal::EXCEPTION_UNDERFLOW - * BigDecimal::EXCEPTION_OVERFLOW - * BigDecimal::EXCEPTION_ZERODIVIDE - * BigDecimal::EXCEPTION_ALL - * - * For each mode parameter above, if the value set is false, computation - * continues after an arithmetic exception of the appropriate type. - * When computation continues, results are as follows: - * - * EXCEPTION_NaN:: NaN - * EXCEPTION_INFINITY:: +Infinity or -Infinity - * EXCEPTION_UNDERFLOW:: 0 - * EXCEPTION_OVERFLOW:: +Infinity or -Infinity - * EXCEPTION_ZERODIVIDE:: +Infinity or -Infinity - * - * One value of the mode parameter controls the rounding of numeric values: - * BigDecimal::ROUND_MODE. The values it can take are: - * - * ROUND_UP, :up:: round away from zero - * ROUND_DOWN, :down, :truncate:: round towards zero (truncate) - * ROUND_HALF_UP, :half_up, :default:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. (default) - * ROUND_HALF_DOWN, :half_down:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero. - * ROUND_HALF_EVEN, :half_even, :banker:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards the even neighbor (Banker's rounding) - * ROUND_CEILING, :ceiling, :ceil:: round towards positive infinity (ceil) - * ROUND_FLOOR, :floor:: round towards negative infinity (floor) - * - */ -static VALUE -BigDecimal_mode(int argc, VALUE *argv, VALUE self) -{ - VALUE which; - VALUE val; - unsigned long f,fo; - - rb_scan_args(argc, argv, "11", &which, &val); - f = (unsigned long)NUM2INT(which); - - if (f & VP_EXCEPTION_ALL) { - /* Exception mode setting */ - fo = VpGetException(); - if (val == Qnil) return INT2FIX(fo); - if (val != Qfalse && val!=Qtrue) { - rb_raise(rb_eArgError, "second argument must be true or false"); - return Qnil; /* Not reached */ - } - if (f & VP_EXCEPTION_INFINITY) { - VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) : - (fo & (~VP_EXCEPTION_INFINITY)))); - } - fo = VpGetException(); - if (f & VP_EXCEPTION_NaN) { - VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) : - (fo & (~VP_EXCEPTION_NaN)))); - } - fo = VpGetException(); - if (f & VP_EXCEPTION_UNDERFLOW) { - VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) : - (fo & (~VP_EXCEPTION_UNDERFLOW)))); - } - fo = VpGetException(); - if(f & VP_EXCEPTION_ZERODIVIDE) { - VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) : - (fo & (~VP_EXCEPTION_ZERODIVIDE)))); - } - fo = VpGetException(); - return INT2FIX(fo); - } - if (VP_ROUND_MODE == f) { - /* Rounding mode setting */ - unsigned short sw; - fo = VpGetRoundMode(); - if (NIL_P(val)) return INT2FIX(fo); - sw = check_rounding_mode(val); - fo = VpSetRoundMode(sw); - return INT2FIX(fo); - } - rb_raise(rb_eTypeError, "first argument for BigDecimal.mode invalid"); - return Qnil; -} - -static size_t -GetAddSubPrec(Real *a, Real *b) -{ - size_t mxs; - size_t mx = a->Prec; - SIGNED_VALUE d; - - if (!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L; - if (mx < b->Prec) mx = b->Prec; - if (a->exponent != b->exponent) { - mxs = mx; - d = a->exponent - b->exponent; - if (d < 0) d = -d; - mx = mx + (size_t)d; - if (mx < mxs) { - return VpException(VP_EXCEPTION_INFINITY, "Exponent overflow", 0); - } - } - return mx; -} - -static SIGNED_VALUE -GetPrecisionInt(VALUE v) -{ - SIGNED_VALUE n; - n = NUM2INT(v); - if (n < 0) { - rb_raise(rb_eArgError, "negative precision"); - } - return n; -} - -static VALUE -BigDecimal_wrap_struct(VALUE obj, Real *vp) -{ - assert(is_kind_of_BigDecimal(obj)); - assert(vp != NULL); - - if (vp->obj == obj && RTYPEDDATA_DATA(obj) == vp) - return obj; - - assert(RTYPEDDATA_DATA(obj) == NULL); - assert(vp->obj == 0); - - RTYPEDDATA_DATA(obj) = vp; - vp->obj = obj; - RB_OBJ_FREEZE(obj); - return obj; -} - -VP_EXPORT Real * -VpNewRbClass(size_t mx, const char *str, VALUE klass, bool strict_p, bool raise_exception) -{ - VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0); - Real *pv = VpAlloc(mx, str, strict_p, raise_exception); - if (!pv) - return NULL; - BigDecimal_wrap_struct(obj, pv); - return pv; -} - -VP_EXPORT Real * -VpCreateRbObject(size_t mx, const char *str, bool raise_exception) -{ - return VpNewRbClass(mx, str, rb_cBigDecimal, true, raise_exception); -} - -#define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(DECDIG)) -#define VpReallocReal(ptr, prec) (Real *)VpMemRealloc((ptr), offsetof(Real, frac) + (prec) * sizeof(DECDIG)) - -static Real * -VpCopy(Real *pv, Real const* const x) -{ - assert(x != NULL); - - pv = VpReallocReal(pv, x->MaxPrec); - pv->MaxPrec = x->MaxPrec; - pv->Prec = x->Prec; - pv->exponent = x->exponent; - pv->sign = x->sign; - pv->flag = x->flag; - MEMCPY(pv->frac, x->frac, DECDIG, pv->MaxPrec); - - return pv; -} - -/* Returns True if the value is Not a Number. */ -static VALUE -BigDecimal_IsNaN(VALUE self) -{ - Real *p = GetVpValue(self, 1); - if (VpIsNaN(p)) return Qtrue; - return Qfalse; -} - -/* Returns nil, -1, or +1 depending on whether the value is finite, - * -Infinity, or +Infinity. - */ -static VALUE -BigDecimal_IsInfinite(VALUE self) -{ - Real *p = GetVpValue(self, 1); - if (VpIsPosInf(p)) return INT2FIX(1); - if (VpIsNegInf(p)) return INT2FIX(-1); - return Qnil; -} - -/* Returns True if the value is finite (not NaN or infinite). */ -static VALUE -BigDecimal_IsFinite(VALUE self) -{ - Real *p = GetVpValue(self, 1); - if (VpIsNaN(p)) return Qfalse; - if (VpIsInf(p)) return Qfalse; - return Qtrue; -} - -static void -BigDecimal_check_num(Real *p) -{ - VpCheckException(p, true); -} - -static VALUE BigDecimal_split(VALUE self); - -/* Returns the value as an Integer. - * - * If the BigDecimal is infinity or NaN, raises FloatDomainError. - */ -static VALUE -BigDecimal_to_i(VALUE self) -{ - ENTER(5); - ssize_t e, nf; - Real *p; - - GUARD_OBJ(p, GetVpValue(self, 1)); - BigDecimal_check_num(p); - - e = VpExponent10(p); - if (e <= 0) return INT2FIX(0); - nf = VpBaseFig(); - if (e <= nf) { - return LONG2NUM((long)(VpGetSign(p) * (DECDIG_DBL_SIGNED)p->frac[0])); - } - else { - VALUE a = BigDecimal_split(self); - VALUE digits = RARRAY_AREF(a, 1); - VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0); - VALUE ret; - ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits); - - if (BIGDECIMAL_NEGATIVE_P(p)) { - numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); - } - if (dpower < 0) { - ret = rb_funcall(numerator, rb_intern("div"), 1, - rb_funcall(INT2FIX(10), rb_intern("**"), 1, - INT2FIX(-dpower))); - } - else { - ret = rb_funcall(numerator, '*', 1, - rb_funcall(INT2FIX(10), rb_intern("**"), 1, - INT2FIX(dpower))); - } - if (RB_TYPE_P(ret, T_FLOAT)) { - rb_raise(rb_eFloatDomainError, "Infinity"); - } - return ret; - } -} - -/* Returns a new Float object having approximately the same value as the - * BigDecimal number. Normal accuracy limits and built-in errors of binary - * Float arithmetic apply. - */ -static VALUE -BigDecimal_to_f(VALUE self) -{ - ENTER(1); - Real *p; - double d; - SIGNED_VALUE e; - char *buf; - volatile VALUE str; - - GUARD_OBJ(p, GetVpValue(self, 1)); - if (VpVtoD(&d, &e, p) != 1) - return rb_float_new(d); - if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG)) - goto overflow; - if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG)) - goto underflow; - - str = rb_str_new(0, VpNumOfChars(p, "E")); - buf = RSTRING_PTR(str); - VpToString(p, buf, 0, 0); - errno = 0; - d = strtod(buf, 0); - if (errno == ERANGE) { - if (d == 0.0) goto underflow; - if (fabs(d) >= HUGE_VAL) goto overflow; - } - return rb_float_new(d); - -overflow: - VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0); - if (BIGDECIMAL_NEGATIVE_P(p)) - return rb_float_new(VpGetDoubleNegInf()); - else - return rb_float_new(VpGetDoublePosInf()); - -underflow: - VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0); - if (BIGDECIMAL_NEGATIVE_P(p)) - return rb_float_new(-0.0); - else - return rb_float_new(0.0); -} - - -/* Converts a BigDecimal to a Rational. - */ -static VALUE -BigDecimal_to_r(VALUE self) -{ - Real *p; - ssize_t sign, power, denomi_power; - VALUE a, digits, numerator; - - p = GetVpValue(self, 1); - BigDecimal_check_num(p); - - sign = VpGetSign(p); - power = VpExponent10(p); - a = BigDecimal_split(self); - digits = RARRAY_AREF(a, 1); - denomi_power = power - RSTRING_LEN(digits); - numerator = rb_funcall(digits, rb_intern("to_i"), 0); - - if (sign < 0) { - numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); - } - if (denomi_power < 0) { - return rb_Rational(numerator, - rb_funcall(INT2FIX(10), rb_intern("**"), 1, - INT2FIX(-denomi_power))); - } - else { - return rb_Rational1(rb_funcall(numerator, '*', 1, - rb_funcall(INT2FIX(10), rb_intern("**"), 1, - INT2FIX(denomi_power)))); - } -} - -/* The coerce method provides support for Ruby type coercion. It is not - * enabled by default. - * - * This means that binary operations like + * / or - can often be performed - * on a BigDecimal and an object of another type, if the other object can - * be coerced into a BigDecimal value. - * - * e.g. - * a = BigDecimal("1.0") - * b = a / 2.0 #=> 0.5 - * - * Note that coercing a String to a BigDecimal is not supported by default; - * it requires a special compile-time option when building Ruby. - */ -static VALUE -BigDecimal_coerce(VALUE self, VALUE other) -{ - ENTER(2); - VALUE obj; - Real *b; - - if (RB_TYPE_P(other, T_FLOAT)) { - GUARD_OBJ(b, GetVpValueWithPrec(other, 0, 1)); - obj = rb_assoc_new(VpCheckGetValue(b), self); - } - else { - if (RB_TYPE_P(other, T_RATIONAL)) { - Real* pv = DATA_PTR(self); - GUARD_OBJ(b, GetVpValueWithPrec(other, pv->Prec*VpBaseFig(), 1)); - } - else { - GUARD_OBJ(b, GetVpValue(other, 1)); - } - obj = rb_assoc_new(b->obj, self); - } - - return obj; -} - -/* - * call-seq: - * +big_decimal -> big_decimal - * - * Return self. - * - * +BigDecimal('5') #=> 0.5e1 - */ - -static VALUE -BigDecimal_uplus(VALUE self) -{ - return self; -} - - /* - * Document-method: BigDecimal#add - * Document-method: BigDecimal#+ - * - * call-seq: - * add(value, digits) - * - * Add the specified value. - * - * e.g. - * c = a.add(b,n) - * c = a + b - * - * digits:: If specified and less than the number of significant digits of the - * result, the result is rounded to that number of digits, according - * to BigDecimal.mode. - */ -static VALUE -BigDecimal_add(VALUE self, VALUE r) -{ - ENTER(5); - Real *c, *a, *b; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self, 1)); - if (RB_TYPE_P(r, T_FLOAT)) { - b = GetVpValueWithPrec(r, 0, 1); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); - } - else { - b = GetVpValue(r, 0); - } - - if (!b) return DoSomeOne(self,r,'+'); - SAVE(b); - - if (VpIsNaN(b)) return b->obj; - if (VpIsNaN(a)) return a->obj; - - mx = GetAddSubPrec(a, b); - if (mx == (size_t)-1L) { - GUARD_OBJ(c, VpCreateRbObject(VpBaseFig() + 1, "0", true)); - VpAddSub(c, a, b, 1); - } - else { - GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0", true)); - if(!mx) { - VpSetInf(c, VpGetSign(a)); - } - else { - VpAddSub(c, a, b, 1); - } - } - return VpCheckGetValue(c); -} - - /* call-seq: - * a - b -> bigdecimal - * - * Subtract the specified value. - * - * e.g. - * c = a - b - * - * The precision of the result value depends on the type of +b+. - * - * If +b+ is a Float, the precision of the result is Float::DIG+1. - * - * If +b+ is a BigDecimal, the precision of the result is +b+'s precision of - * internal representation from platform. So, it's return value is platform - * dependent. - * - */ -static VALUE -BigDecimal_sub(VALUE self, VALUE r) -{ - ENTER(5); - Real *c, *a, *b; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self,1)); - if (RB_TYPE_P(r, T_FLOAT)) { - b = GetVpValueWithPrec(r, 0, 1); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); - } - else { - b = GetVpValue(r,0); - } - - if (!b) return DoSomeOne(self,r,'-'); - SAVE(b); - - if (VpIsNaN(b)) return b->obj; - if (VpIsNaN(a)) return a->obj; - - mx = GetAddSubPrec(a,b); - if (mx == (size_t)-1L) { - GUARD_OBJ(c, VpCreateRbObject(VpBaseFig() + 1, "0", true)); - VpAddSub(c, a, b, -1); - } - else { - GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0", true)); - if (!mx) { - VpSetInf(c,VpGetSign(a)); - } - else { - VpAddSub(c, a, b, -1); - } - } - return VpCheckGetValue(c); -} - -static VALUE -BigDecimalCmp(VALUE self, VALUE r,char op) -{ - ENTER(5); - SIGNED_VALUE e; - Real *a, *b=0; - GUARD_OBJ(a, GetVpValue(self, 1)); - switch (TYPE(r)) { - case T_DATA: - if (!is_kind_of_BigDecimal(r)) break; - /* fall through */ - case T_FIXNUM: - /* fall through */ - case T_BIGNUM: - GUARD_OBJ(b, GetVpValue(r, 0)); - break; - - case T_FLOAT: - GUARD_OBJ(b, GetVpValueWithPrec(r, 0, 0)); - break; - - case T_RATIONAL: - GUARD_OBJ(b, GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 0)); - break; - - default: - break; - } - if (b == NULL) { - ID f = 0; - - switch (op) { - case '*': - return rb_num_coerce_cmp(self, r, rb_intern("<=>")); - - case '=': - return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse; - - case 'G': - f = rb_intern(">="); - break; - - case 'L': - f = rb_intern("<="); - break; - - case '>': - /* fall through */ - case '<': - f = (ID)op; - break; - - default: - break; - } - return rb_num_coerce_relop(self, r, f); - } - SAVE(b); - e = VpComp(a, b); - if (e == 999) - return (op == '*') ? Qnil : Qfalse; - switch (op) { - case '*': - return INT2FIX(e); /* any op */ - - case '=': - if (e == 0) return Qtrue; - return Qfalse; - - case 'G': - if (e >= 0) return Qtrue; - return Qfalse; - - case '>': - if (e > 0) return Qtrue; - return Qfalse; - - case 'L': - if (e <= 0) return Qtrue; - return Qfalse; - - case '<': - if (e < 0) return Qtrue; - return Qfalse; - - default: - break; - } - - rb_bug("Undefined operation in BigDecimalCmp()"); - - UNREACHABLE; -} - -/* Returns True if the value is zero. */ -static VALUE -BigDecimal_zero(VALUE self) -{ - Real *a = GetVpValue(self, 1); - return VpIsZero(a) ? Qtrue : Qfalse; -} - -/* Returns self if the value is non-zero, nil otherwise. */ -static VALUE -BigDecimal_nonzero(VALUE self) -{ - Real *a = GetVpValue(self, 1); - return VpIsZero(a) ? Qnil : self; -} - -/* The comparison operator. - * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b. - */ -static VALUE -BigDecimal_comp(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, '*'); -} - -/* - * Tests for value equality; returns true if the values are equal. - * - * The == and === operators and the eql? method have the same implementation - * for BigDecimal. - * - * Values may be coerced to perform the comparison: - * - * BigDecimal('1.0') == 1.0 #=> true - */ -static VALUE -BigDecimal_eq(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, '='); -} - -/* call-seq: - * a < b - * - * Returns true if a is less than b. - * - * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce). - */ -static VALUE -BigDecimal_lt(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, '<'); -} - -/* call-seq: - * a <= b - * - * Returns true if a is less than or equal to b. - * - * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce). - */ -static VALUE -BigDecimal_le(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, 'L'); -} - -/* call-seq: - * a > b - * - * Returns true if a is greater than b. - * - * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce). - */ -static VALUE -BigDecimal_gt(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, '>'); -} - -/* call-seq: - * a >= b - * - * Returns true if a is greater than or equal to b. - * - * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce) - */ -static VALUE -BigDecimal_ge(VALUE self, VALUE r) -{ - return BigDecimalCmp(self, r, 'G'); -} - -/* - * call-seq: - * -big_decimal -> big_decimal - * - * Return the negation of self. - * - * -BigDecimal('5') #=> -0.5e1 - */ - -static VALUE -BigDecimal_neg(VALUE self) -{ - ENTER(5); - Real *c, *a; - GUARD_OBJ(a, GetVpValue(self, 1)); - GUARD_OBJ(c, VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0", true)); - VpAsgn(c, a, -1); - return VpCheckGetValue(c); -} - - /* - * Document-method: BigDecimal#mult - * - * call-seq: mult(value, digits) - * - * Multiply by the specified value. - * - * e.g. - * c = a.mult(b,n) - * c = a * b - * - * digits:: If specified and less than the number of significant digits of the - * result, the result is rounded to that number of digits, according - * to BigDecimal.mode. - */ -static VALUE -BigDecimal_mult(VALUE self, VALUE r) -{ - ENTER(5); - Real *c, *a, *b; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self, 1)); - if (RB_TYPE_P(r, T_FLOAT)) { - b = GetVpValueWithPrec(r, 0, 1); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); - } - else { - b = GetVpValue(r,0); - } - - if (!b) return DoSomeOne(self, r, '*'); - SAVE(b); - - mx = a->Prec + b->Prec; - GUARD_OBJ(c, VpCreateRbObject(mx *(VpBaseFig() + 1), "0", true)); - VpMult(c, a, b); - return VpCheckGetValue(c); -} - -static VALUE -BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div) -/* For c = self.div(r): with round operation */ -{ - ENTER(5); - Real *a, *b; - size_t mx; - - TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a); - SAVE(a); - - VALUE rr = r; - if (is_kind_of_BigDecimal(rr)) { - /* do nothing */ - } - else if (RB_INTEGER_TYPE_P(r)) { - rr = rb_inum_convert_to_BigDecimal(r, 0, true); - } - else if (RB_TYPE_P(r, T_FLOAT)) { - rr = rb_float_convert_to_BigDecimal(r, 0, true); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true); - } - - if (!is_kind_of_BigDecimal(rr)) { - return DoSomeOne(self, r, '/'); - } - - TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b); - SAVE(b); - - *div = b; - mx = a->Prec + vabs(a->exponent); - if (mx < b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); - mx++; /* NOTE: An additional digit is needed for the compatibility to - the version 1.2.1 and the former. */ - mx = (mx + 1) * VpBaseFig(); - GUARD_OBJ((*c), VpCreateRbObject(mx, "#0", true)); - GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0", true)); - VpDivd(*c, *res, a, b); - return Qnil; -} - -/* call-seq: - * a / b -> bigdecimal - * quo(value) -> bigdecimal - * - * Divide by the specified value. - * - * See BigDecimal#div. - */ -static VALUE -BigDecimal_div(VALUE self, VALUE r) -/* For c = self/r: with round operation */ -{ - ENTER(5); - Real *c=NULL, *res=NULL, *div = NULL; - r = BigDecimal_divide(self, r, &c, &res, &div); - if (!NIL_P(r)) return r; /* coerced by other */ - SAVE(c); SAVE(res); SAVE(div); - /* a/b = c + r/b */ - /* c xxxxx - r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE - */ - /* Round */ - if (VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */ - VpInternalRound(c, 0, c->frac[c->Prec-1], (DECDIG)(VpBaseVal() * (DECDIG_DBL)res->frac[0] / div->frac[0])); - } - return VpCheckGetValue(c); -} - -/* - * %: mod = a%b = a - (a.to_f/b).floor * b - * div = (a.to_f/b).floor - */ -static VALUE -BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) -{ - ENTER(8); - Real *c=NULL, *d=NULL, *res=NULL; - Real *a, *b; - size_t mx; - - TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a); - SAVE(a); - - VALUE rr = r; - if (is_kind_of_BigDecimal(rr)) { - /* do nothing */ - } - else if (RB_INTEGER_TYPE_P(r)) { - rr = rb_inum_convert_to_BigDecimal(r, 0, true); - } - else if (RB_TYPE_P(r, T_FLOAT)) { - rr = rb_float_convert_to_BigDecimal(r, 0, true); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true); - } - - if (!is_kind_of_BigDecimal(rr)) { - return Qfalse; - } - - TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b); - SAVE(b); - - if (VpIsNaN(a) || VpIsNaN(b)) goto NaN; - if (VpIsInf(a) && VpIsInf(b)) goto NaN; - if (VpIsZero(b)) { - rb_raise(rb_eZeroDivError, "divided by 0"); - } - if (VpIsInf(a)) { - if (VpGetSign(a) == VpGetSign(b)) { - VALUE inf = BigDecimal_positive_infinity(); - TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div); - } - else { - VALUE inf = BigDecimal_negative_infinity(); - TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div); - } - VALUE nan = BigDecimal_nan(); - TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod); - return Qtrue; - } - if (VpIsInf(b)) { - VALUE zero = BigDecimal_positive_zero(); - TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div); - *mod = a; - return Qtrue; - } - if (VpIsZero(a)) { - VALUE zero = BigDecimal_positive_zero(); - TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div); - TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *mod); - return Qtrue; - } - - mx = a->Prec + vabs(a->exponent); - if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); - mx = (mx + 1) * VpBaseFig(); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0", true)); - VpDivd(c, res, a, b); - mx = c->Prec * (VpBaseFig() + 1); - GUARD_OBJ(d, VpCreateRbObject(mx, "0", true)); - VpActiveRound(d, c, VP_ROUND_DOWN, 0); - VpMult(res, d, b); - VpAddSub(c, a, res, -1); - if (!VpIsZero(c) && (VpGetSign(a) * VpGetSign(b) < 0)) { - VpAddSub(res, d, VpOne(), -1); - GUARD_OBJ(d, VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0", true)); - VpAddSub(d, c, b, 1); - *div = res; - *mod = d; - } else { - *div = d; - *mod = c; - } - return Qtrue; - - NaN: - { - VALUE nan = BigDecimal_nan(); - TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *div); - TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod); - } - return Qtrue; -} - -/* call-seq: - * a % b - * a.modulo(b) - * - * Returns the modulus from dividing by b. - * - * See BigDecimal#divmod. - */ -static VALUE -BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ -{ - ENTER(3); - Real *div = NULL, *mod = NULL; - - if (BigDecimal_DoDivmod(self, r, &div, &mod)) { - SAVE(div); SAVE(mod); - return VpCheckGetValue(mod); - } - return DoSomeOne(self, r, '%'); -} - -static VALUE -BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv) -{ - ENTER(10); - size_t mx; - Real *a = NULL, *b = NULL, *c = NULL, *res = NULL, *d = NULL, *rr = NULL, *ff = NULL; - Real *f = NULL; - - GUARD_OBJ(a, GetVpValue(self, 1)); - if (RB_TYPE_P(r, T_FLOAT)) { - b = GetVpValueWithPrec(r, 0, 1); - } - else if (RB_TYPE_P(r, T_RATIONAL)) { - b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); - } - else { - b = GetVpValue(r, 0); - } - - if (!b) return DoSomeOne(self, r, rb_intern("remainder")); - SAVE(b); - - mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig(); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true)); - GUARD_OBJ(rr, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true)); - GUARD_OBJ(ff, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true)); - - VpDivd(c, res, a, b); - - mx = c->Prec *(VpBaseFig() + 1); - - GUARD_OBJ(d, VpCreateRbObject(mx, "0", true)); - GUARD_OBJ(f, VpCreateRbObject(mx, "0", true)); - - VpActiveRound(d, c, VP_ROUND_DOWN, 0); /* 0: round off */ - - VpFrac(f, c); - VpMult(rr, f, b); - VpAddSub(ff, res, rr, 1); - - *dv = d; - *rv = ff; - return Qnil; -} - -/* call-seq: - * remainder(value) - * - * Returns the remainder from dividing by the value. - * - * x.remainder(y) means x-y*(x/y).truncate - */ -static VALUE -BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ -{ - VALUE f; - Real *d, *rv = 0; - f = BigDecimal_divremain(self, r, &d, &rv); - if (!NIL_P(f)) return f; - return VpCheckGetValue(rv); -} - -/* call-seq: - * divmod(value) - * - * Divides by the specified value, and returns the quotient and modulus - * as BigDecimal numbers. The quotient is rounded towards negative infinity. - * - * For example: - * - * require 'bigdecimal' - * - * a = BigDecimal("42") - * b = BigDecimal("9") - * - * q, m = a.divmod(b) - * - * c = q * b + m - * - * a == c #=> true - * - * The quotient q is (a/b).floor, and the modulus is the amount that must be - * added to q * b to get a. - */ -static VALUE -BigDecimal_divmod(VALUE self, VALUE r) -{ - ENTER(5); - Real *div = NULL, *mod = NULL; - - if (BigDecimal_DoDivmod(self, r, &div, &mod)) { - SAVE(div); SAVE(mod); - return rb_assoc_new(VpCheckGetValue(div), VpCheckGetValue(mod)); - } - return DoSomeOne(self,r,rb_intern("divmod")); -} - -/* - * Do the same manner as Float#div when n is nil. - * Do the same manner as BigDecimal#quo when n is 0. - */ -static inline VALUE -BigDecimal_div2(VALUE self, VALUE b, VALUE n) -{ - ENTER(5); - SIGNED_VALUE ix; - - if (NIL_P(n)) { /* div in Float sense */ - Real *div = NULL; - Real *mod; - if (BigDecimal_DoDivmod(self, b, &div, &mod)) { - return BigDecimal_to_i(VpCheckGetValue(div)); - } - return DoSomeOne(self, b, rb_intern("div")); - } - - /* div in BigDecimal sense */ - ix = GetPrecisionInt(n); - if (ix == 0) { - return BigDecimal_div(self, b); - } - else { - Real *res = NULL; - Real *av = NULL, *bv = NULL, *cv = NULL; - size_t mx = ix + VpBaseFig()*2; - size_t pl = VpSetPrecLimit(0); - - GUARD_OBJ(cv, VpCreateRbObject(mx + VpBaseFig(), "0", true)); - GUARD_OBJ(av, GetVpValue(self, 1)); - GUARD_OBJ(bv, GetVpValue(b, 1)); - mx = av->Prec + bv->Prec + 2; - if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1; - GUARD_OBJ(res, VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0", true)); - VpDivd(cv, res, av, bv); - VpSetPrecLimit(pl); - VpLeftRound(cv, VpGetRoundMode(), ix); - return VpCheckGetValue(cv); - } -} - - /* - * Document-method: BigDecimal#div - * - * call-seq: - * div(value, digits) -> bigdecimal or integer - * - * Divide by the specified value. - * - * digits:: If specified and less than the number of significant digits of the - * result, the result is rounded to that number of digits, according - * to BigDecimal.mode. - * - * If digits is 0, the result is the same as for the / operator - * or #quo. - * - * If digits is not specified, the result is an integer, - * by analogy with Float#div; see also BigDecimal#divmod. - * - * Examples: - * - * a = BigDecimal("4") - * b = BigDecimal("3") - * - * a.div(b, 3) # => 0.133e1 - * - * a.div(b, 0) # => 0.1333333333333333333e1 - * a / b # => 0.1333333333333333333e1 - * a.quo(b) # => 0.1333333333333333333e1 - * - * a.div(b) # => 1 - */ -static VALUE -BigDecimal_div3(int argc, VALUE *argv, VALUE self) -{ - VALUE b,n; - - rb_scan_args(argc, argv, "11", &b, &n); - - return BigDecimal_div2(self, b, n); -} - -static VALUE -BigDecimal_add2(VALUE self, VALUE b, VALUE n) -{ - ENTER(2); - Real *cv; - SIGNED_VALUE mx = GetPrecisionInt(n); - if (mx == 0) return BigDecimal_add(self, b); - else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_add(self, b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv, GetVpValue(c, 1)); - VpLeftRound(cv, VpGetRoundMode(), mx); - return VpCheckGetValue(cv); - } -} - -/* call-seq: - * sub(value, digits) -> bigdecimal - * - * Subtract the specified value. - * - * e.g. - * c = a.sub(b,n) - * - * digits:: If specified and less than the number of significant digits of the - * result, the result is rounded to that number of digits, according - * to BigDecimal.mode. - * - */ -static VALUE -BigDecimal_sub2(VALUE self, VALUE b, VALUE n) -{ - ENTER(2); - Real *cv; - SIGNED_VALUE mx = GetPrecisionInt(n); - if (mx == 0) return BigDecimal_sub(self, b); - else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_sub(self, b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv, GetVpValue(c, 1)); - VpLeftRound(cv, VpGetRoundMode(), mx); - return VpCheckGetValue(cv); - } -} - - -static VALUE -BigDecimal_mult2(VALUE self, VALUE b, VALUE n) -{ - ENTER(2); - Real *cv; - SIGNED_VALUE mx = GetPrecisionInt(n); - if (mx == 0) return BigDecimal_mult(self, b); - else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_mult(self, b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv, GetVpValue(c, 1)); - VpLeftRound(cv, VpGetRoundMode(), mx); - return VpCheckGetValue(cv); - } -} - -/* - * call-seq: - * big_decimal.abs -> big_decimal - * - * Returns the absolute value, as a BigDecimal. - * - * BigDecimal('5').abs #=> 0.5e1 - * BigDecimal('-3').abs #=> 0.3e1 - */ - -static VALUE -BigDecimal_abs(VALUE self) -{ - ENTER(5); - Real *c, *a; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpAsgn(c, a, 1); - VpChangeSign(c, 1); - return VpCheckGetValue(c); -} - -/* call-seq: - * sqrt(n) - * - * Returns the square root of the value. - * - * Result has at least n significant digits. - */ -static VALUE -BigDecimal_sqrt(VALUE self, VALUE nFig) -{ - ENTER(5); - Real *c, *a; - size_t mx, n; - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - - n = GetPrecisionInt(nFig) + VpDblFig() + BASE_FIG; - if (mx <= n) mx = n; - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpSqrt(c, a); - return VpCheckGetValue(c); -} - -/* Return the integer part of the number, as a BigDecimal. - */ -static VALUE -BigDecimal_fix(VALUE self) -{ - ENTER(5); - Real *c, *a; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpActiveRound(c, a, VP_ROUND_DOWN, 0); /* 0: round off */ - return VpCheckGetValue(c); -} - -/* call-seq: - * round(n, mode) - * - * Round to the nearest integer (by default), returning the result as a - * BigDecimal if n is specified, or as an Integer if it isn't. - * - * BigDecimal('3.14159').round #=> 3 - * BigDecimal('8.7').round #=> 9 - * BigDecimal('-9.9').round #=> -10 - * - * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal" - * BigDecimal('3.14159').round.class.name #=> "Integer" - * - * If n is specified and positive, the fractional part of the result has no - * more than that many digits. - * - * If n is specified and negative, at least that many digits to the left of the - * decimal point will be 0 in the result, and return value will be an Integer. - * - * BigDecimal('3.14159').round(3) #=> 3.142 - * BigDecimal('13345.234').round(-2) #=> 13300 - * - * The value of the optional mode argument can be used to determine how - * rounding is performed; see BigDecimal.mode. - */ -static VALUE -BigDecimal_round(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *c, *a; - int iLoc = 0; - VALUE vLoc; - VALUE vRound; - int round_to_int = 0; - size_t mx, pl; - - unsigned short sw = VpGetRoundMode(); - - switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { - case 0: - iLoc = 0; - round_to_int = 1; - break; - case 1: - if (RB_TYPE_P(vLoc, T_HASH)) { - sw = check_rounding_mode_option(vLoc); - } - else { - iLoc = NUM2INT(vLoc); - if (iLoc < 1) round_to_int = 1; - } - break; - case 2: - iLoc = NUM2INT(vLoc); - if (RB_TYPE_P(vRound, T_HASH)) { - sw = check_rounding_mode_option(vRound); - } - else { - sw = check_rounding_mode(vRound); - } - break; - default: - break; - } - - pl = VpSetPrecLimit(0); - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpSetPrecLimit(pl); - VpActiveRound(c, a, sw, iLoc); - if (round_to_int) { - return BigDecimal_to_i(VpCheckGetValue(c)); - } - return VpCheckGetValue(c); -} - -/* call-seq: - * truncate(n) - * - * Truncate to the nearest integer (by default), returning the result as a - * BigDecimal. - * - * BigDecimal('3.14159').truncate #=> 3 - * BigDecimal('8.7').truncate #=> 8 - * BigDecimal('-9.9').truncate #=> -9 - * - * If n is specified and positive, the fractional part of the result has no - * more than that many digits. - * - * If n is specified and negative, at least that many digits to the left of the - * decimal point will be 0 in the result. - * - * BigDecimal('3.14159').truncate(3) #=> 3.141 - * BigDecimal('13345.234').truncate(-2) #=> 13300.0 - */ -static VALUE -BigDecimal_truncate(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *c, *a; - int iLoc; - VALUE vLoc; - size_t mx, pl = VpSetPrecLimit(0); - - if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { - iLoc = 0; - } - else { - iLoc = NUM2INT(vLoc); - } - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpSetPrecLimit(pl); - VpActiveRound(c, a, VP_ROUND_DOWN, iLoc); /* 0: truncate */ - if (argc == 0) { - return BigDecimal_to_i(VpCheckGetValue(c)); - } - return VpCheckGetValue(c); -} - -/* Return the fractional part of the number, as a BigDecimal. - */ -static VALUE -BigDecimal_frac(VALUE self) -{ - ENTER(5); - Real *c, *a; - size_t mx; - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpFrac(c, a); - return VpCheckGetValue(c); -} - -/* call-seq: - * floor(n) - * - * Return the largest integer less than or equal to the value, as a BigDecimal. - * - * BigDecimal('3.14159').floor #=> 3 - * BigDecimal('-9.1').floor #=> -10 - * - * If n is specified and positive, the fractional part of the result has no - * more than that many digits. - * - * If n is specified and negative, at least that - * many digits to the left of the decimal point will be 0 in the result. - * - * BigDecimal('3.14159').floor(3) #=> 3.141 - * BigDecimal('13345.234').floor(-2) #=> 13300.0 - */ -static VALUE -BigDecimal_floor(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *c, *a; - int iLoc; - VALUE vLoc; - size_t mx, pl = VpSetPrecLimit(0); - - if (rb_scan_args(argc, argv, "01", &vLoc)==0) { - iLoc = 0; - } - else { - iLoc = NUM2INT(vLoc); - } - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpSetPrecLimit(pl); - VpActiveRound(c, a, VP_ROUND_FLOOR, iLoc); -#ifdef BIGDECIMAL_DEBUG - VPrint(stderr, "floor: c=%\n", c); -#endif - if (argc == 0) { - return BigDecimal_to_i(VpCheckGetValue(c)); - } - return VpCheckGetValue(c); -} - -/* call-seq: - * ceil(n) - * - * Return the smallest integer greater than or equal to the value, as a BigDecimal. - * - * BigDecimal('3.14159').ceil #=> 4 - * BigDecimal('-9.1').ceil #=> -9 - * - * If n is specified and positive, the fractional part of the result has no - * more than that many digits. - * - * If n is specified and negative, at least that - * many digits to the left of the decimal point will be 0 in the result. - * - * BigDecimal('3.14159').ceil(3) #=> 3.142 - * BigDecimal('13345.234').ceil(-2) #=> 13400.0 - */ -static VALUE -BigDecimal_ceil(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *c, *a; - int iLoc; - VALUE vLoc; - size_t mx, pl = VpSetPrecLimit(0); - - if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { - iLoc = 0; - } else { - iLoc = NUM2INT(vLoc); - } - - GUARD_OBJ(a, GetVpValue(self, 1)); - mx = a->Prec * (VpBaseFig() + 1); - GUARD_OBJ(c, VpCreateRbObject(mx, "0", true)); - VpSetPrecLimit(pl); - VpActiveRound(c, a, VP_ROUND_CEIL, iLoc); - if (argc == 0) { - return BigDecimal_to_i(VpCheckGetValue(c)); - } - return VpCheckGetValue(c); -} - -/* call-seq: - * to_s(s) - * - * Converts the value to a string. - * - * The default format looks like 0.xxxxEnn. - * - * The optional parameter s consists of either an integer; or an optional '+' - * or ' ', followed by an optional number, followed by an optional 'E' or 'F'. - * - * If there is a '+' at the start of s, positive values are returned with - * a leading '+'. - * - * A space at the start of s returns positive values with a leading space. - * - * If s contains a number, a space is inserted after each group of that many - * fractional digits. - * - * If s ends with an 'E', engineering notation (0.xxxxEnn) is used. - * - * If s ends with an 'F', conventional floating point notation is used. - * - * Examples: - * - * BigDecimal('-123.45678901234567890').to_s('5F') - * #=> '-123.45678 90123 45678 9' - * - * BigDecimal('123.45678901234567890').to_s('+8F') - * #=> '+123.45678901 23456789' - * - * BigDecimal('123.45678901234567890').to_s(' F') - * #=> ' 123.4567890123456789' - */ -static VALUE -BigDecimal_to_s(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - int fmt = 0; /* 0: E format, 1: F format */ - int fPlus = 0; /* 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ - Real *vp; - volatile VALUE str; - char *psz; - char ch; - size_t nc, mc = 0; - SIGNED_VALUE m; - VALUE f; - - GUARD_OBJ(vp, GetVpValue(self, 1)); - - if (rb_scan_args(argc, argv, "01", &f) == 1) { - if (RB_TYPE_P(f, T_STRING)) { - psz = StringValueCStr(f); - if (*psz == ' ') { - fPlus = 1; - psz++; - } - else if (*psz == '+') { - fPlus = 2; - psz++; - } - while ((ch = *psz++) != 0) { - if (ISSPACE(ch)) { - continue; - } - if (!ISDIGIT(ch)) { - if (ch == 'F' || ch == 'f') { - fmt = 1; /* F format */ - } - break; - } - mc = mc*10 + ch - '0'; - } - } - else { - m = NUM2INT(f); - if (m <= 0) { - rb_raise(rb_eArgError, "argument must be positive"); - } - mc = (size_t)m; - } - } - if (fmt) { - nc = VpNumOfChars(vp, "F"); - } - else { - nc = VpNumOfChars(vp, "E"); - } - if (mc > 0) { - nc += (nc + mc - 1) / mc + 1; - } - - str = rb_usascii_str_new(0, nc); - psz = RSTRING_PTR(str); - - if (fmt) { - VpToFString(vp, psz, mc, fPlus); - } - else { - VpToString (vp, psz, mc, fPlus); - } - rb_str_resize(str, strlen(psz)); - return str; -} - -/* Splits a BigDecimal number into four parts, returned as an array of values. - * - * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 - * if the BigDecimal is Not a Number. - * - * The second value is a string representing the significant digits of the - * BigDecimal, with no leading zeros. - * - * The third value is the base used for arithmetic (currently always 10) as an - * Integer. - * - * The fourth value is an Integer exponent. - * - * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the - * string of significant digits with no leading zeros, and n is the exponent. - * - * From these values, you can translate a BigDecimal to a float as follows: - * - * sign, significant_digits, base, exponent = a.split - * f = sign * "0.#{significant_digits}".to_f * (base ** exponent) - * - * (Note that the to_f method is provided as a more convenient way to translate - * a BigDecimal to a Float.) - */ -static VALUE -BigDecimal_split(VALUE self) -{ - ENTER(5); - Real *vp; - VALUE obj,str; - ssize_t e, s; - char *psz1; - - GUARD_OBJ(vp, GetVpValue(self, 1)); - str = rb_str_new(0, VpNumOfChars(vp, "E")); - psz1 = RSTRING_PTR(str); - VpSzMantissa(vp, psz1); - s = 1; - if(psz1[0] == '-') { - size_t len = strlen(psz1 + 1); - - memmove(psz1, psz1 + 1, len); - psz1[len] = '\0'; - s = -1; - } - if (psz1[0] == 'N') s = 0; /* NaN */ - e = VpExponent10(vp); - obj = rb_ary_new2(4); - rb_ary_push(obj, INT2FIX(s)); - rb_ary_push(obj, str); - rb_str_resize(str, strlen(psz1)); - rb_ary_push(obj, INT2FIX(10)); - rb_ary_push(obj, SSIZET2NUM(e)); - return obj; -} - -/* Returns the exponent of the BigDecimal number, as an Integer. - * - * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string - * of digits with no leading zeros, then n is the exponent. - */ -static VALUE -BigDecimal_exponent(VALUE self) -{ - ssize_t e = VpExponent10(GetVpValue(self, 1)); - return SSIZET2NUM(e); -} - -/* Returns a string representation of self. - * - * BigDecimal("1234.5678").inspect - * #=> "0.12345678e4" - */ -static VALUE -BigDecimal_inspect(VALUE self) -{ - ENTER(5); - Real *vp; - volatile VALUE str; - size_t nc; - - GUARD_OBJ(vp, GetVpValue(self, 1)); - nc = VpNumOfChars(vp, "E"); - - str = rb_str_new(0, nc); - VpToString(vp, RSTRING_PTR(str), 0, 0); - rb_str_resize(str, strlen(RSTRING_PTR(str))); - return str; -} - -static VALUE BigMath_s_exp(VALUE, VALUE, VALUE); -static VALUE BigMath_s_log(VALUE, VALUE, VALUE); - -#define BigMath_exp(x, n) BigMath_s_exp(rb_mBigMath, (x), (n)) -#define BigMath_log(x, n) BigMath_s_log(rb_mBigMath, (x), (n)) - -inline static int -is_integer(VALUE x) -{ - return (RB_TYPE_P(x, T_FIXNUM) || RB_TYPE_P(x, T_BIGNUM)); -} - -inline static int -is_negative(VALUE x) -{ - if (FIXNUM_P(x)) { - return FIX2LONG(x) < 0; - } - else if (RB_TYPE_P(x, T_BIGNUM)) { - return FIX2INT(rb_big_cmp(x, INT2FIX(0))) < 0; - } - else if (RB_TYPE_P(x, T_FLOAT)) { - return RFLOAT_VALUE(x) < 0.0; - } - return RTEST(rb_funcall(x, '<', 1, INT2FIX(0))); -} - -#define is_positive(x) (!is_negative(x)) - -inline static int -is_zero(VALUE x) -{ - VALUE num; - - switch (TYPE(x)) { - case T_FIXNUM: - return FIX2LONG(x) == 0; - - case T_BIGNUM: - return Qfalse; - - case T_RATIONAL: - num = rb_rational_num(x); - return FIXNUM_P(num) && FIX2LONG(num) == 0; - - default: - break; - } - - return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(0))); -} - -inline static int -is_one(VALUE x) -{ - VALUE num, den; - - switch (TYPE(x)) { - case T_FIXNUM: - return FIX2LONG(x) == 1; - - case T_BIGNUM: - return Qfalse; - - case T_RATIONAL: - num = rb_rational_num(x); - den = rb_rational_den(x); - return FIXNUM_P(den) && FIX2LONG(den) == 1 && - FIXNUM_P(num) && FIX2LONG(num) == 1; - - default: - break; - } - - return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(1))); -} - -inline static int -is_even(VALUE x) -{ - switch (TYPE(x)) { - case T_FIXNUM: - return (FIX2LONG(x) % 2) == 0; - - case T_BIGNUM: - { - unsigned long l; - rb_big_pack(x, &l, 1); - return l % 2 == 0; - } - - default: - break; - } - - return 0; -} - -static VALUE -bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n) -{ - VALUE log_x, multiplied, y; - volatile VALUE obj = exp->obj; - - if (VpIsZero(exp)) { - return VpCheckGetValue(VpCreateRbObject(n, "1", true)); - } - - log_x = BigMath_log(x->obj, SSIZET2NUM(n+1)); - multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n+1)); - y = BigMath_exp(multiplied, SSIZET2NUM(n)); - RB_GC_GUARD(obj); - - return y; -} - -/* call-seq: - * power(n) - * power(n, prec) - * - * Returns the value raised to the power of n. - * - * Note that n must be an Integer. - * - * Also available as the operator **. - */ -static VALUE -BigDecimal_power(int argc, VALUE*argv, VALUE self) -{ - ENTER(5); - VALUE vexp, prec; - Real* exp = NULL; - Real *x, *y; - ssize_t mp, ma, n; - SIGNED_VALUE int_exp; - double d; - - rb_scan_args(argc, argv, "11", &vexp, &prec); - - GUARD_OBJ(x, GetVpValue(self, 1)); - n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec); - - if (VpIsNaN(x)) { - y = VpCreateRbObject(n, "0", true); - RB_GC_GUARD(y->obj); - VpSetNaN(y); - return VpCheckGetValue(y); - } - - retry: - switch (TYPE(vexp)) { - case T_FIXNUM: - break; - - case T_BIGNUM: - break; - - case T_FLOAT: - d = RFLOAT_VALUE(vexp); - if (d == round(d)) { - if (FIXABLE(d)) { - vexp = LONG2FIX((long)d); - } - else { - vexp = rb_dbl2big(d); - } - goto retry; - } - if (NIL_P(prec)) { - n += BIGDECIMAL_DOUBLE_FIGURES; - } - exp = GetVpValueWithPrec(vexp, 0, 1); - break; - - case T_RATIONAL: - if (is_zero(rb_rational_num(vexp))) { - if (is_positive(vexp)) { - vexp = INT2FIX(0); - goto retry; - } - } - else if (is_one(rb_rational_den(vexp))) { - vexp = rb_rational_num(vexp); - goto retry; - } - exp = GetVpValueWithPrec(vexp, n, 1); - if (NIL_P(prec)) { - n += n; - } - break; - - case T_DATA: - if (is_kind_of_BigDecimal(vexp)) { - VALUE zero = INT2FIX(0); - VALUE rounded = BigDecimal_round(1, &zero, vexp); - if (RTEST(BigDecimal_eq(vexp, rounded))) { - vexp = BigDecimal_to_i(vexp); - goto retry; - } - if (NIL_P(prec)) { - GUARD_OBJ(y, GetVpValue(vexp, 1)); - n += y->Prec*VpBaseFig(); - } - exp = DATA_PTR(vexp); - break; - } - /* fall through */ - default: - rb_raise(rb_eTypeError, - "wrong argument type %"PRIsVALUE" (expected scalar Numeric)", - RB_OBJ_CLASSNAME(vexp)); - } - - if (VpIsZero(x)) { - if (is_negative(vexp)) { - y = VpCreateRbObject(n, "#0", true); - RB_GC_GUARD(y->obj); - if (BIGDECIMAL_NEGATIVE_P(x)) { - if (is_integer(vexp)) { - if (is_even(vexp)) { - /* (-0) ** (-even_integer) -> Infinity */ - VpSetPosInf(y); - } - else { - /* (-0) ** (-odd_integer) -> -Infinity */ - VpSetNegInf(y); - } - } - else { - /* (-0) ** (-non_integer) -> Infinity */ - VpSetPosInf(y); - } - } - else { - /* (+0) ** (-num) -> Infinity */ - VpSetPosInf(y); - } - return VpCheckGetValue(y); - } - else if (is_zero(vexp)) { - return VpCheckGetValue(VpCreateRbObject(n, "1", true)); - } - else { - return VpCheckGetValue(VpCreateRbObject(n, "0", true)); - } - } - - if (is_zero(vexp)) { - return VpCheckGetValue(VpCreateRbObject(n, "1", true)); - } - else if (is_one(vexp)) { - return self; - } - - if (VpIsInf(x)) { - if (is_negative(vexp)) { - if (BIGDECIMAL_NEGATIVE_P(x)) { - if (is_integer(vexp)) { - if (is_even(vexp)) { - /* (-Infinity) ** (-even_integer) -> +0 */ - return VpCheckGetValue(VpCreateRbObject(n, "0", true)); - } - else { - /* (-Infinity) ** (-odd_integer) -> -0 */ - return VpCheckGetValue(VpCreateRbObject(n, "-0", true)); - } - } - else { - /* (-Infinity) ** (-non_integer) -> -0 */ - return VpCheckGetValue(VpCreateRbObject(n, "-0", true)); - } - } - else { - return VpCheckGetValue(VpCreateRbObject(n, "0", true)); - } - } - else { - y = VpCreateRbObject(n, "0", true); - if (BIGDECIMAL_NEGATIVE_P(x)) { - if (is_integer(vexp)) { - if (is_even(vexp)) { - VpSetPosInf(y); - } - else { - VpSetNegInf(y); - } - } - else { - /* TODO: support complex */ - rb_raise(rb_eMathDomainError, - "a non-integral exponent for a negative base"); - } - } - else { - VpSetPosInf(y); - } - return VpCheckGetValue(y); - } - } - - if (exp != NULL) { - return bigdecimal_power_by_bigdecimal(x, exp, n); - } - else if (RB_TYPE_P(vexp, T_BIGNUM)) { - VALUE abs_value = BigDecimal_abs(self); - if (is_one(abs_value)) { - return VpCheckGetValue(VpCreateRbObject(n, "1", true)); - } - else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) { - if (is_negative(vexp)) { - y = VpCreateRbObject(n, "0", true); - if (is_even(vexp)) { - VpSetInf(y, VpGetSign(x)); - } - else { - VpSetInf(y, -VpGetSign(x)); - } - return VpCheckGetValue(y); - } - else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) { - return VpCheckGetValue(VpCreateRbObject(n, "-0", true)); - } - else { - return VpCheckGetValue(VpCreateRbObject(n, "0", true)); - } - } - else { - if (is_positive(vexp)) { - y = VpCreateRbObject(n, "0", true); - if (is_even(vexp)) { - VpSetInf(y, VpGetSign(x)); - } - else { - VpSetInf(y, -VpGetSign(x)); - } - return VpCheckGetValue(y); - } - else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) { - return VpCheckGetValue(VpCreateRbObject(n, "-0", true)); - } - else { - return VpCheckGetValue(VpCreateRbObject(n, "0", true)); - } - } - } - - int_exp = FIX2LONG(vexp); - ma = int_exp; - if (ma < 0) ma = -ma; - if (ma == 0) ma = 1; - - if (VpIsDef(x)) { - mp = x->Prec * (VpBaseFig() + 1); - GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0", true)); - } - else { - GUARD_OBJ(y, VpCreateRbObject(1, "0", true)); - } - VpPowerByInt(y, x, int_exp); - if (!NIL_P(prec) && VpIsDef(y)) { - VpMidRound(y, VpGetRoundMode(), n); - } - return VpCheckGetValue(y); -} - -/* call-seq: - * a ** n -> bigdecimal - * - * Returns the value raised to the power of n. - * - * See BigDecimal#power. - */ -static VALUE -BigDecimal_power_op(VALUE self, VALUE exp) -{ - return BigDecimal_power(1, &exp, self); -} - -/* :nodoc: - * - * private method for dup and clone the provided BigDecimal +other+ - */ -static VALUE -BigDecimal_initialize_copy(VALUE self, VALUE other) -{ - Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); - Real *x = rb_check_typeddata(other, &BigDecimal_data_type); - - if (self != other) { - DATA_PTR(self) = VpCopy(pv, x); - } - return self; -} - -static VALUE -BigDecimal_clone(VALUE self) -{ - return self; -} - -#ifdef HAVE_RB_OPTS_EXCEPTION_P -int rb_opts_exception_p(VALUE opts, int default_value); -#define opts_exception_p(opts) rb_opts_exception_p((opts), 1) -#else -static int -opts_exception_p(VALUE opts) -{ - static ID kwds[1]; - VALUE exception; - if (!kwds[0]) { - kwds[0] = rb_intern_const("exception"); - } - if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1; - switch (exception) { - case Qtrue: case Qfalse: - break; - default: - rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE, - exception); - } - return exception != Qfalse; -} -#endif - -static VALUE -check_exception(VALUE bd) -{ - assert(is_kind_of_BigDecimal(bd)); - - Real *vp; - TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); - VpCheckGetValue(vp); /* VpCheckGetValue performs exception check */ - - return bd; -} - -static VALUE -rb_uint64_convert_to_BigDecimal(uint64_t uval, RB_UNUSED_VAR(size_t digs), int raise_exception) -{ - VALUE obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); - - Real *vp; - if (uval == 0) { - vp = VpAllocReal(1); - vp->MaxPrec = 1; - vp->Prec = 1; - vp->exponent = 1; - VpSetZero(vp, 1); - vp->frac[0] = 0; - } - else if (uval < BASE) { - vp = VpAllocReal(1); - vp->MaxPrec = 1; - vp->Prec = 1; - vp->exponent = 1; - VpSetSign(vp, 1); - vp->frac[0] = (DECDIG)uval; - } - else { - DECDIG buf[BIGDECIMAL_INT64_MAX_LENGTH] = {0,}; - size_t exp = 0, ntz = 0; - for (; uval > 0; ++exp) { - DECDIG r = uval % BASE; - if (r == 0) ++ntz; - buf[BIGDECIMAL_INT64_MAX_LENGTH - exp - 1] = r; - uval /= BASE; - } - - const size_t len = exp - ntz; - vp = VpAllocReal(len); - vp->MaxPrec = len; - vp->Prec = len; - vp->exponent = exp; - VpSetSign(vp, 1); - MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - exp, DECDIG, len); - } - - return BigDecimal_wrap_struct(obj, vp); -} - -static VALUE -rb_int64_convert_to_BigDecimal(int64_t ival, size_t digs, int raise_exception) -{ - const uint64_t uval = (ival < 0) ? (((uint64_t)-(ival+1))+1) : (uint64_t)ival; - VALUE bd = rb_uint64_convert_to_BigDecimal(uval, digs, raise_exception); - if (ival < 0) { - Real *vp; - TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); - VpSetSign(vp, -1); - } - return bd; -} - -static VALUE -rb_big_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_exception) -{ - assert(RB_TYPE_P(val, T_BIGNUM)); - - size_t size = rb_absint_size(val, NULL); - int sign = FIX2INT(rb_big_cmp(val, INT2FIX(0))); - if (size <= sizeof(long)) { - if (sign < 0) { - return rb_int64_convert_to_BigDecimal(NUM2LONG(val), digs, raise_exception); - } - else { - return rb_uint64_convert_to_BigDecimal(NUM2ULONG(val), digs, raise_exception); - } - } -#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG < SIZEOF_LONG_LONG - else if (size <= sizeof(LONG_LONG)) { - if (sign < 0) { - return rb_int64_convert_to_BigDecimal(NUM2LL(val), digs, raise_exception); - } - else { - return rb_uint64_convert_to_BigDecimal(NUM2ULL(val), digs, raise_exception); - } - } -#endif - else { - VALUE str = rb_big2str(val, 10); - Real *vp = VpCreateRbObject(RSTRING_LEN(str) + BASE_FIG + 1, - RSTRING_PTR(str), true); - RB_GC_GUARD(str); - return check_exception(vp->obj); - } -} - -static VALUE -rb_inum_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_exception) -{ - assert(RB_INTEGER_TYPE_P(val)); - if (FIXNUM_P(val)) { - return rb_int64_convert_to_BigDecimal(FIX2LONG(val), digs, raise_exception); - } - else { - return rb_big_convert_to_BigDecimal(val, digs, raise_exception); - } -} - -static VALUE -rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) -{ - assert(RB_FLOAT_TYPE_P(val)); - - double d = RFLOAT_VALUE(val); - - if (isnan(d)) { - VALUE obj = BigDecimal_nan(); - return check_exception(obj); - } - else if (isinf(d)) { - VALUE obj; - if (d > 0) { - obj = BigDecimal_positive_infinity(); - } - else { - obj = BigDecimal_negative_infinity(); - } - return check_exception(obj); - } - else if (d == 0.0) { - if (1/d < 0.0) { - return BigDecimal_negative_zero(); - } - else { - return BigDecimal_positive_zero(); - } - } - - if (digs == SIZE_MAX) { - if (!raise_exception) - return Qnil; - rb_raise(rb_eArgError, - "can't omit precision for a %"PRIsVALUE".", - CLASS_OF(val)); - } - else if (digs > BIGDECIMAL_DOUBLE_FIGURES) { - if (!raise_exception) - return Qnil; - rb_raise(rb_eArgError, "precision too large."); - } - - /* Use the same logic in flo_to_s to convert a float to a decimal string */ - char buf[BIGDECIMAL_DOUBLE_FIGURES + BASE_FIG + 2 + 1]; /* sizeof(buf) == 28 in the typical case */ - int decpt, negative_p; - char *e; - const int mode = digs == 0 ? 0 : 2; - char *p = BigDecimal_dtoa(d, mode, (int)digs, &decpt, &negative_p, &e); - int len10 = (int)(e - p); - if (len10 > BIGDECIMAL_DOUBLE_FIGURES) { - /* TODO: Presumably, rounding should be done here. */ - len10 = BIGDECIMAL_DOUBLE_FIGURES; - } - memcpy(buf, p, len10); - xfree(p); - - VALUE inum; - size_t RB_UNUSED_VAR(prec) = 0; - size_t exp = 0; - if (decpt > 0) { - if (decpt < len10) { - /* - * len10 |---------------| - * : |-------| frac_len10 = len10 - decpt - * decpt |-------| |--| ntz10 = BASE_FIG - frac_len10 % BASE_FIG - * : : : - * 00 dd dddd.dddd dd 00 - * prec |-----.----.----.-----| prec = exp + roomof(frac_len, BASE_FIG) - * exp |-----.----| exp = roomof(decpt, BASE_FIG) - */ - const size_t frac_len10 = len10 - decpt; - const size_t ntz10 = BASE_FIG - frac_len10 % BASE_FIG; - memset(buf + len10, '0', ntz10); - buf[len10 + ntz10] = '\0'; - inum = rb_cstr_to_inum(buf, 10, false); - - exp = roomof(decpt, BASE_FIG); - prec = exp + roomof(frac_len10, BASE_FIG); - } - else { - /* - * decpt |-----------------------| - * len10 |----------| : - * : |------------| exp10 - * : : : - * 00 dd dddd dd 00 0000 0000.0 - * : : : : - * : |--| ntz10 = exp10 % BASE_FIG - * prec |-----.----.-----| : - * : |----.----| exp10 / BASE_FIG - * exp |-----.----.-----.----.----| - */ - const size_t exp10 = decpt - len10; - const size_t ntz10 = exp10 % BASE_FIG; - - memset(buf + len10, '0', ntz10); - buf[len10 + ntz10] = '\0'; - inum = rb_cstr_to_inum(buf, 10, false); - - prec = roomof(len10 + ntz10, BASE_FIG); - exp = prec + exp10 / BASE_FIG; - } - } - else if (decpt == 0) { - /* - * len10 |------------| - * : : - * 0.dddd dddd dd 00 - * : : : - * : |--| ntz10 = prec * BASE_FIG - len10 - * prec |----.----.-----| roomof(len10, BASE_FIG) - */ - prec = roomof(len10, BASE_FIG); - const size_t ntz10 = prec * BASE_FIG - len10; - - memset(buf + len10, '0', ntz10); - buf[len10 + ntz10] = '\0'; - inum = rb_cstr_to_inum(buf, 10, false); - } - else { - /* - * len10 |---------------| - * : : - * decpt |-------| |--| ntz10 = prec * BASE_FIG - nlz10 - len10 - * : : : - * 0.0000 00 dd dddd dddd dd 00 - * : : : - * nlz10 |--| : decpt % BASE_FIG - * prec |-----.----.----.-----| roomof(decpt + len10, BASE_FIG) - exp - * exp |----| decpt / BASE_FIG - */ - decpt = -decpt; - - const size_t nlz10 = decpt % BASE_FIG; - exp = decpt / BASE_FIG; - prec = roomof(decpt + len10, BASE_FIG) - exp; - const size_t ntz10 = prec * BASE_FIG - nlz10 - len10; - - if (nlz10 > 0) { - memmove(buf + nlz10, buf, len10); - memset(buf, '0', nlz10); - } - memset(buf + nlz10 + len10, '0', ntz10); - buf[nlz10 + len10 + ntz10] = '\0'; - inum = rb_cstr_to_inum(buf, 10, false); - - exp = -exp; - } - - VALUE bd = rb_inum_convert_to_BigDecimal(inum, SIZE_MAX, raise_exception); - Real *vp; - TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); - assert(vp->Prec == prec); - vp->exponent = exp; - - if (negative_p) VpSetSign(vp, -1); - return bd; -} - -static VALUE -rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) -{ - assert(RB_TYPE_P(val, T_RATIONAL)); - - if (digs == SIZE_MAX) { - if (!raise_exception) - return Qnil; - rb_raise(rb_eArgError, - "can't omit precision for a %"PRIsVALUE".", - CLASS_OF(val)); - } - - VALUE num = rb_inum_convert_to_BigDecimal(rb_rational_num(val), 0, raise_exception); - VALUE d = BigDecimal_div2(num, rb_rational_den(val), SIZET2NUM(digs)); - return d; -} - -static VALUE -rb_cstr_convert_to_BigDecimal(const char *c_str, size_t digs, int raise_exception) -{ - if (digs == SIZE_MAX) - digs = 0; - - Real *vp = VpCreateRbObject(digs, c_str, raise_exception); - if (!vp) - return Qnil; - return VpCheckGetValue(vp); -} - -static inline VALUE -rb_str_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) -{ - const char *c_str = StringValueCStr(val); - return rb_cstr_convert_to_BigDecimal(c_str, digs, raise_exception); -} - -static VALUE -rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) -{ - switch (val) { - case Qnil: - case Qtrue: - case Qfalse: - if (raise_exception) { - const char *cname = NIL_P(val) ? "nil" : - val == Qtrue ? "true" : - val == Qfalse ? "false" : - NULL; - rb_raise(rb_eTypeError, - "can't convert %s into BigDecimal", cname); - } - return Qnil; - - default: - break; - } - - if (is_kind_of_BigDecimal(val)) { - if (digs == SIZE_MAX) - return check_exception(val); - - Real *vp; - TypedData_Get_Struct(val, Real, &BigDecimal_data_type, vp); - - VALUE copy = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); - vp = VpCopy(NULL, vp); - /* TODO: rounding */ - BigDecimal_wrap_struct(copy, vp); - return VpCheckGetValue(vp); - } - else if (RB_INTEGER_TYPE_P(val)) { - return rb_inum_convert_to_BigDecimal(val, digs, raise_exception); - } - else if (RB_FLOAT_TYPE_P(val)) { - return rb_float_convert_to_BigDecimal(val, digs, raise_exception); - } - else if (RB_TYPE_P(val, T_RATIONAL)) { - return rb_rational_convert_to_BigDecimal(val, digs, raise_exception); - } - else if (RB_TYPE_P(val, T_COMPLEX)) { - VALUE im = rb_complex_imag(val); - if (!is_zero(im)) { - /* TODO: handle raise_exception */ - rb_raise(rb_eArgError, - "Unable to make a BigDecimal from non-zero imaginary number"); - } - return rb_convert_to_BigDecimal(rb_complex_real(val), digs, raise_exception); - } - else if (RB_TYPE_P(val, T_STRING)) { - return rb_str_convert_to_BigDecimal(val, digs, raise_exception); - } - - /* TODO: chheck to_d */ - /* TODO: chheck to_int */ - - VALUE str = rb_check_convert_type(val, T_STRING, "String", "to_str"); - if (!RB_TYPE_P(str, T_STRING)) { - if (raise_exception) { - rb_raise(rb_eTypeError, - "can't convert %"PRIsVALUE" into BigDecimal", rb_obj_class(val)); - } - return Qnil; - } - return rb_str_convert_to_BigDecimal(str, digs, raise_exception); -} - -/* call-seq: - * BigDecimal(arg, exception: true) - * BigDecimal(arg, digits, exception: true) - * - * Returns <i>arg</i> converted to a BigDecimal. Numeric types are converted - * directly. Other types except for String are first converted to String - * by <code>to_str</code>. Strings can be converted when it has appropriate - * forms of decimal numbers. Exceptions can be suppressed by passing - * <code>exception: false</code>. - * - * When <i>arg</i> is a Float and <i>digits</i> is <code>0</code>, the number - * of digits is determined by the algorithm of <code>dtoa</code> function - * written by David M. Gay. That algorithm is based on "How to Print Floating- - * Point Numbers Accurately" by Guy L. Steele, Jr. and Jon L. White [Proc. ACM - * SIGPLAN '90, pp. 112-126]. - * - * arg:: The value converted to a BigDecimal. - * - * If it is a String, spaces are ignored and unrecognized characters - * terminate the value. - * - * digits:: The number of significant digits, as an Integer. If omitted, - * the number of significant digits is determined from <i>arg</i>. - * - * The actual number of significant digits used in computation is - * usually larger than the specified number. - * - * exception:: Whether an exception should be raised on invalid arguments. - * +true+ by default, if passed +false+, just returns +nil+ - * for invalid. - * - * - * ==== Exceptions - * - * TypeError:: If the +initial+ type is neither Integer, Float, - * Rational, nor BigDecimal, this exception is raised. - * - * TypeError:: If the +digits+ is not an Integer, this exception is raised. - * - * ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than - * Float::DIG + 1, this exception is raised. - * - * ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+ - * value is omitted, this exception is raised. - */ -static VALUE -f_BigDecimal(int argc, VALUE *argv, VALUE self) -{ - VALUE val, digs_v, opts = Qnil; - argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts); - int exception = opts_exception_p(opts); - - size_t digs = SIZE_MAX; /* this means digs is omitted */ - if (argc > 1) { - digs_v = rb_to_int(digs_v); - if (FIXNUM_P(digs_v)) { - long n = FIX2LONG(digs_v); - if (n < 0) - goto negative_digs; - digs = (size_t)n; - } - else { - if (RBIGNUM_NEGATIVE_P(digs_v)) { - negative_digs: - if (!exception) - return Qnil; - rb_raise(rb_eArgError, "negative precision"); - } - digs = NUM2SIZET(digs_v); - } - } - - return rb_convert_to_BigDecimal(val, digs, exception); -} - -static VALUE -BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) -{ - char const *c_str = StringValueCStr(str); - Real *vp = VpNewRbClass(0, c_str, klass, false, true); - if (!vp) - return Qnil; - else - return VpCheckGetValue(vp); -} - - /* call-seq: - * BigDecimal.limit(digits) - * - * Limit the number of significant digits in newly created BigDecimal - * numbers to the specified value. Rounding is performed as necessary, - * as specified by BigDecimal.mode. - * - * A limit of 0, the default, means no upper limit. - * - * The limit specified by this method takes less priority over any limit - * specified to instance methods such as ceil, floor, truncate, or round. - */ -static VALUE -BigDecimal_limit(int argc, VALUE *argv, VALUE self) -{ - VALUE nFig; - VALUE nCur = SIZET2NUM(VpGetPrecLimit()); - - if (rb_scan_args(argc, argv, "01", &nFig) == 1) { - int nf; - if (NIL_P(nFig)) return nCur; - nf = NUM2INT(nFig); - if (nf < 0) { - rb_raise(rb_eArgError, "argument must be positive"); - } - VpSetPrecLimit(nf); - } - return nCur; -} - -/* Returns the sign of the value. - * - * Returns a positive value if > 0, a negative value if < 0, and a - * zero if == 0. - * - * The specific value returned indicates the type and sign of the BigDecimal, - * as follows: - * - * BigDecimal::SIGN_NaN:: value is Not a Number - * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0 - * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0 - * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +Infinity - * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -Infinity - * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive - * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative - */ -static VALUE -BigDecimal_sign(VALUE self) -{ /* sign */ - int s = GetVpValue(self, 1)->sign; - return INT2FIX(s); -} - -/* - * call-seq: BigDecimal.save_exception_mode { ... } - * - * Execute the provided block, but preserve the exception mode - * - * BigDecimal.save_exception_mode do - * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) - * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) - * - * BigDecimal(BigDecimal('Infinity')) - * BigDecimal(BigDecimal('-Infinity')) - * BigDecimal(BigDecimal('NaN')) - * end - * - * For use with the BigDecimal::EXCEPTION_* - * - * See BigDecimal.mode - */ -static VALUE -BigDecimal_save_exception_mode(VALUE self) -{ - unsigned short const exception_mode = VpGetException(); - int state; - VALUE ret = rb_protect(rb_yield, Qnil, &state); - VpSetException(exception_mode); - if (state) rb_jump_tag(state); - return ret; -} - -/* - * call-seq: BigDecimal.save_rounding_mode { ... } - * - * Execute the provided block, but preserve the rounding mode - * - * BigDecimal.save_rounding_mode do - * BigDecimal.mode(BigDecimal::ROUND_MODE, :up) - * puts BigDecimal.mode(BigDecimal::ROUND_MODE) - * end - * - * For use with the BigDecimal::ROUND_* - * - * See BigDecimal.mode - */ -static VALUE -BigDecimal_save_rounding_mode(VALUE self) -{ - unsigned short const round_mode = VpGetRoundMode(); - int state; - VALUE ret = rb_protect(rb_yield, Qnil, &state); - VpSetRoundMode(round_mode); - if (state) rb_jump_tag(state); - return ret; -} - -/* - * call-seq: BigDecimal.save_limit { ... } - * - * Execute the provided block, but preserve the precision limit - * - * BigDecimal.limit(100) - * puts BigDecimal.limit - * BigDecimal.save_limit do - * BigDecimal.limit(200) - * puts BigDecimal.limit - * end - * puts BigDecimal.limit - * - */ -static VALUE -BigDecimal_save_limit(VALUE self) -{ - size_t const limit = VpGetPrecLimit(); - int state; - VALUE ret = rb_protect(rb_yield, Qnil, &state); - VpSetPrecLimit(limit); - if (state) rb_jump_tag(state); - return ret; -} - -/* call-seq: - * BigMath.exp(decimal, numeric) -> BigDecimal - * - * Computes the value of e (the base of natural logarithms) raised to the - * power of +decimal+, to the specified number of digits of precision. - * - * If +decimal+ is infinity, returns Infinity. - * - * If +decimal+ is NaN, returns NaN. - */ -static VALUE -BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec) -{ - ssize_t prec, n, i; - Real* vx = NULL; - VALUE one, d, y; - int negative = 0; - int infinite = 0; - int nan = 0; - double flo; - - prec = NUM2SSIZET(vprec); - if (prec <= 0) { - rb_raise(rb_eArgError, "Zero or negative precision for exp"); - } - - /* TODO: the following switch statement is almost same as one in the - * BigDecimalCmp function. */ - switch (TYPE(x)) { - case T_DATA: - if (!is_kind_of_BigDecimal(x)) break; - vx = DATA_PTR(x); - negative = BIGDECIMAL_NEGATIVE_P(vx); - infinite = VpIsPosInf(vx) || VpIsNegInf(vx); - nan = VpIsNaN(vx); - break; - - case T_FIXNUM: - /* fall through */ - case T_BIGNUM: - vx = GetVpValue(x, 0); - break; - - case T_FLOAT: - flo = RFLOAT_VALUE(x); - negative = flo < 0; - infinite = isinf(flo); - nan = isnan(flo); - if (!infinite && !nan) { - vx = GetVpValueWithPrec(x, 0, 0); - } - break; - - case T_RATIONAL: - vx = GetVpValueWithPrec(x, prec, 0); - break; - - default: - break; - } - if (infinite) { - if (negative) { - return VpCheckGetValue(GetVpValueWithPrec(INT2FIX(0), prec, 1)); - } - else { - Real* vy; - vy = VpCreateRbObject(prec, "#0", true); - VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE); - RB_GC_GUARD(vy->obj); - return VpCheckGetValue(vy); - } - } - else if (nan) { - Real* vy; - vy = VpCreateRbObject(prec, "#0", true); - VpSetNaN(vy); - RB_GC_GUARD(vy->obj); - return VpCheckGetValue(vy); - } - else if (vx == NULL) { - cannot_be_coerced_into_BigDecimal(rb_eArgError, x); - } - x = vx->obj; - - n = prec + BIGDECIMAL_DOUBLE_FIGURES; - negative = BIGDECIMAL_NEGATIVE_P(vx); - if (negative) { - VALUE x_zero = INT2NUM(1); - VALUE x_copy = f_BigDecimal(1, &x_zero, klass); - x = BigDecimal_initialize_copy(x_copy, x); - vx = DATA_PTR(x); - VpSetSign(vx, 1); - } - - one = VpCheckGetValue(VpCreateRbObject(1, "1", true)); - y = one; - d = y; - i = 1; - - while (!VpIsZero((Real*)DATA_PTR(d))) { - SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y)); - SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d)); - ssize_t m = n - vabs(ey - ed); - - rb_thread_check_ints(); - - if (m <= 0) { - break; - } - else if ((size_t)m < BIGDECIMAL_DOUBLE_FIGURES) { - m = BIGDECIMAL_DOUBLE_FIGURES; - } - - d = BigDecimal_mult(d, x); /* d <- d * x */ - d = BigDecimal_div2(d, SSIZET2NUM(i), SSIZET2NUM(m)); /* d <- d / i */ - y = BigDecimal_add(y, d); /* y <- y + d */ - ++i; /* i <- i + 1 */ - } - - if (negative) { - return BigDecimal_div2(one, y, vprec); - } - else { - vprec = SSIZET2NUM(prec - VpExponent10(DATA_PTR(y))); - return BigDecimal_round(1, &vprec, y); - } - - RB_GC_GUARD(one); - RB_GC_GUARD(x); - RB_GC_GUARD(y); - RB_GC_GUARD(d); -} - -/* call-seq: - * BigMath.log(decimal, numeric) -> BigDecimal - * - * Computes the natural logarithm of +decimal+ to the specified number of - * digits of precision, +numeric+. - * - * If +decimal+ is zero or negative, raises Math::DomainError. - * - * If +decimal+ is positive infinity, returns Infinity. - * - * If +decimal+ is NaN, returns NaN. - */ -static VALUE -BigMath_s_log(VALUE klass, VALUE x, VALUE vprec) -{ - ssize_t prec, n, i; - SIGNED_VALUE expo; - Real* vx = NULL; - VALUE vn, one, two, w, x2, y, d; - int zero = 0; - int negative = 0; - int infinite = 0; - int nan = 0; - double flo; - long fix; - - if (!is_integer(vprec)) { - rb_raise(rb_eArgError, "precision must be an Integer"); - } - - prec = NUM2SSIZET(vprec); - if (prec <= 0) { - rb_raise(rb_eArgError, "Zero or negative precision for exp"); - } - - /* TODO: the following switch statement is almost same as one in the - * BigDecimalCmp function. */ - switch (TYPE(x)) { - case T_DATA: - if (!is_kind_of_BigDecimal(x)) break; - vx = DATA_PTR(x); - zero = VpIsZero(vx); - negative = BIGDECIMAL_NEGATIVE_P(vx); - infinite = VpIsPosInf(vx) || VpIsNegInf(vx); - nan = VpIsNaN(vx); - break; - - case T_FIXNUM: - fix = FIX2LONG(x); - zero = fix == 0; - negative = fix < 0; - goto get_vp_value; - - case T_BIGNUM: - i = FIX2INT(rb_big_cmp(x, INT2FIX(0))); - zero = i == 0; - negative = i < 0; -get_vp_value: - if (zero || negative) break; - vx = GetVpValue(x, 0); - break; - - case T_FLOAT: - flo = RFLOAT_VALUE(x); - zero = flo == 0; - negative = flo < 0; - infinite = isinf(flo); - nan = isnan(flo); - if (!zero && !negative && !infinite && !nan) { - vx = GetVpValueWithPrec(x, 0, 1); - } - break; - - case T_RATIONAL: - zero = RRATIONAL_ZERO_P(x); - negative = RRATIONAL_NEGATIVE_P(x); - if (zero || negative) break; - vx = GetVpValueWithPrec(x, prec, 1); - break; - - case T_COMPLEX: - rb_raise(rb_eMathDomainError, - "Complex argument for BigMath.log"); - - default: - break; - } - if (infinite && !negative) { - Real* vy; - vy = VpCreateRbObject(prec, "#0", true); - RB_GC_GUARD(vy->obj); - VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE); - return VpCheckGetValue(vy); - } - else if (nan) { - Real* vy; - vy = VpCreateRbObject(prec, "#0", true); - RB_GC_GUARD(vy->obj); - VpSetNaN(vy); - return VpCheckGetValue(vy); - } - else if (zero || negative) { - rb_raise(rb_eMathDomainError, - "Zero or negative argument for log"); - } - else if (vx == NULL) { - cannot_be_coerced_into_BigDecimal(rb_eArgError, x); - } - x = VpCheckGetValue(vx); - - RB_GC_GUARD(one) = VpCheckGetValue(VpCreateRbObject(1, "1", true)); - RB_GC_GUARD(two) = VpCheckGetValue(VpCreateRbObject(1, "2", true)); - - n = prec + BIGDECIMAL_DOUBLE_FIGURES; - RB_GC_GUARD(vn) = SSIZET2NUM(n); - expo = VpExponent10(vx); - if (expo < 0 || expo >= 3) { - char buf[DECIMAL_SIZE_OF_BITS(SIZEOF_VALUE * CHAR_BIT) + 4]; - snprintf(buf, sizeof(buf), "1E%"PRIdVALUE, -expo); - x = BigDecimal_mult2(x, VpCheckGetValue(VpCreateRbObject(1, buf, true)), vn); - } - else { - expo = 0; - } - w = BigDecimal_sub(x, one); - x = BigDecimal_div2(w, BigDecimal_add(x, one), vn); - RB_GC_GUARD(x2) = BigDecimal_mult2(x, x, vn); - RB_GC_GUARD(y) = x; - RB_GC_GUARD(d) = y; - i = 1; - while (!VpIsZero((Real*)DATA_PTR(d))) { - SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y)); - SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d)); - ssize_t m = n - vabs(ey - ed); - if (m <= 0) { - break; - } - else if ((size_t)m < BIGDECIMAL_DOUBLE_FIGURES) { - m = BIGDECIMAL_DOUBLE_FIGURES; - } - - x = BigDecimal_mult2(x2, x, vn); - i += 2; - d = BigDecimal_div2(x, SSIZET2NUM(i), SSIZET2NUM(m)); - y = BigDecimal_add(y, d); - } - - y = BigDecimal_mult(y, two); - if (expo != 0) { - VALUE log10, vexpo, dy; - log10 = BigMath_s_log(klass, INT2FIX(10), vprec); - vexpo = VpCheckGetValue(GetVpValue(SSIZET2NUM(expo), 1)); - dy = BigDecimal_mult(log10, vexpo); - y = BigDecimal_add(y, dy); - } - - return y; -} - -static VALUE BIGDECIMAL_NAN = Qnil; - -static VALUE -BigDecimal_nan(void) -{ - return BIGDECIMAL_NAN; -} - -static VALUE BIGDECIMAL_POSITIVE_INFINITY = Qnil; - -static VALUE -BigDecimal_positive_infinity(void) -{ - return BIGDECIMAL_POSITIVE_INFINITY; -} - -static VALUE BIGDECIMAL_NEGATIVE_INFINITY = Qnil; - -static VALUE -BigDecimal_negative_infinity(void) -{ - return BIGDECIMAL_NEGATIVE_INFINITY; -} - -static VALUE BIGDECIMAL_POSITIVE_ZERO = Qnil; - -static VALUE -BigDecimal_positive_zero(void) -{ - return BIGDECIMAL_POSITIVE_ZERO; -} - -static VALUE BIGDECIMAL_NEGATIVE_ZERO = Qnil; - -static VALUE -BigDecimal_negative_zero(void) -{ - return BIGDECIMAL_NEGATIVE_ZERO; -} - -/* Document-class: BigDecimal - * BigDecimal provides arbitrary-precision floating point decimal arithmetic. - * - * == Introduction - * - * Ruby provides built-in support for arbitrary precision integer arithmetic. - * - * For example: - * - * 42**13 #=> 1265437718438866624512 - * - * BigDecimal provides similar support for very large or very accurate floating - * point numbers. - * - * Decimal arithmetic is also useful for general calculation, because it - * provides the correct answers people expect--whereas normal binary floating - * point arithmetic often introduces subtle errors because of the conversion - * between base 10 and base 2. - * - * For example, try: - * - * sum = 0 - * 10_000.times do - * sum = sum + 0.0001 - * end - * print sum #=> 0.9999999999999062 - * - * and contrast with the output from: - * - * require 'bigdecimal' - * - * sum = BigDecimal("0") - * 10_000.times do - * sum = sum + BigDecimal("0.0001") - * end - * print sum #=> 0.1E1 - * - * Similarly: - * - * (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true - * - * (1.2 - 1.0) == 0.2 #=> false - * - * == Special features of accurate decimal arithmetic - * - * Because BigDecimal is more accurate than normal binary floating point - * arithmetic, it requires some special values. - * - * === Infinity - * - * BigDecimal sometimes needs to return infinity, for example if you divide - * a value by zero. - * - * BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity - * BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity - * - * You can represent infinite numbers to BigDecimal using the strings - * <code>'Infinity'</code>, <code>'+Infinity'</code> and - * <code>'-Infinity'</code> (case-sensitive) - * - * === Not a Number - * - * When a computation results in an undefined value, the special value +NaN+ - * (for 'not a number') is returned. - * - * Example: - * - * BigDecimal("0.0") / BigDecimal("0.0") #=> NaN - * - * You can also create undefined values. - * - * NaN is never considered to be the same as any other value, even NaN itself: - * - * n = BigDecimal('NaN') - * n == 0.0 #=> false - * n == n #=> false - * - * === Positive and negative zero - * - * If a computation results in a value which is too small to be represented as - * a BigDecimal within the currently specified limits of precision, zero must - * be returned. - * - * If the value which is too small to be represented is negative, a BigDecimal - * value of negative zero is returned. - * - * BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0 - * - * If the value is positive, a value of positive zero is returned. - * - * BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0 - * - * (See BigDecimal.mode for how to specify limits of precision.) - * - * Note that +-0.0+ and +0.0+ are considered to be the same for the purposes of - * comparison. - * - * Note also that in mathematics, there is no particular concept of negative - * or positive zero; true mathematical zero has no sign. - * - * == bigdecimal/util - * - * When you require +bigdecimal/util+, the #to_d method will be - * available on BigDecimal and the native Integer, Float, Rational, - * and String classes: - * - * require 'bigdecimal/util' - * - * 42.to_d # => 0.42e2 - * 0.5.to_d # => 0.5e0 - * (2/3r).to_d(3) # => 0.667e0 - * "0.5".to_d # => 0.5e0 - * - * == License - * - * Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>. - * - * BigDecimal is released under the Ruby and 2-clause BSD licenses. - * See LICENSE.txt for details. - * - * Maintained by mrkn <mrkn@mrkn.jp> and ruby-core members. - * - * Documented by zzak <zachary@zacharyscott.net>, mathew <meta@pobox.com>, and - * many other contributors. - */ -void -Init_bigdecimal(void) -{ -#ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); -#endif - VALUE arg; - - id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode"); - id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode"); - id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit"); - - /* Initialize VP routines */ - VpInit(0UL); - - /* Class and method registration */ - rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric); - - /* Global function */ - rb_define_global_function("BigDecimal", f_BigDecimal, -1); - - /* Class methods */ - rb_undef_alloc_func(rb_cBigDecimal); - rb_undef_method(CLASS_OF(rb_cBigDecimal), "new"); - rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1); - rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1); - rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1); - rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0); - rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1); - - rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0); - rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0); - rb_define_singleton_method(rb_cBigDecimal, "save_limit", BigDecimal_save_limit, 0); - - /* Constants definition */ - -#ifndef RUBY_BIGDECIMAL_VERSION -# error RUBY_BIGDECIMAL_VERSION is not defined -#endif - /* - * The version of bigdecimal library - */ - rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(RUBY_BIGDECIMAL_VERSION)); - - /* - * Base value used in internal calculations. On a 32 bit system, BASE - * is 10000, indicating that calculation is done in groups of 4 digits. - * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't - * guarantee that two groups could always be multiplied together without - * overflow.) - */ - rb_define_const(rb_cBigDecimal, "BASE", INT2FIX((SIGNED_VALUE)VpBaseVal())); - - /* Exceptions */ - - /* - * 0xff: Determines whether overflow, underflow or zero divide result in - * an exception being thrown. See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL", INT2FIX(VP_EXCEPTION_ALL)); - - /* - * 0x02: Determines what happens when the result of a computation is not a - * number (NaN). See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN", INT2FIX(VP_EXCEPTION_NaN)); - - /* - * 0x01: Determines what happens when the result of a computation is - * infinity. See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY", INT2FIX(VP_EXCEPTION_INFINITY)); - - /* - * 0x04: Determines what happens when the result of a computation is an - * underflow (a result too small to be represented). See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW", INT2FIX(VP_EXCEPTION_UNDERFLOW)); - - /* - * 0x01: Determines what happens when the result of a computation is an - * overflow (a result too large to be represented). See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW)); - - /* - * 0x10: Determines what happens when a division by zero is performed. - * See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE)); - - /* - * 0x100: Determines what happens when a result must be rounded in order to - * fit in the appropriate number of significant digits. See - * BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "ROUND_MODE", INT2FIX(VP_ROUND_MODE)); - - /* 1: Indicates that values should be rounded away from zero. See - * BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "ROUND_UP", INT2FIX(VP_ROUND_UP)); - - /* 2: Indicates that values should be rounded towards zero. See - * BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "ROUND_DOWN", INT2FIX(VP_ROUND_DOWN)); - - /* 3: Indicates that digits >= 5 should be rounded up, others rounded down. - * See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP", INT2FIX(VP_ROUND_HALF_UP)); - - /* 4: Indicates that digits >= 6 should be rounded up, others rounded down. - * See BigDecimal.mode. - */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN", INT2FIX(VP_ROUND_HALF_DOWN)); - /* 5: Round towards +Infinity. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_CEILING", INT2FIX(VP_ROUND_CEIL)); - - /* 6: Round towards -Infinity. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_FLOOR", INT2FIX(VP_ROUND_FLOOR)); - - /* 7: Round towards the even neighbor. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN", INT2FIX(VP_ROUND_HALF_EVEN)); - - /* 0: Indicates that a value is not a number. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NaN", INT2FIX(VP_SIGN_NaN)); - - /* 1: Indicates that a value is +0. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO", INT2FIX(VP_SIGN_POSITIVE_ZERO)); - - /* -1: Indicates that a value is -0. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO", INT2FIX(VP_SIGN_NEGATIVE_ZERO)); - - /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE", INT2FIX(VP_SIGN_POSITIVE_FINITE)); - - /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE", INT2FIX(VP_SIGN_NEGATIVE_FINITE)); - - /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE)); - - /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); - - /* Positive zero value. */ - arg = rb_str_new2("+0"); - BIGDECIMAL_POSITIVE_ZERO = f_BigDecimal(1, &arg, rb_cBigDecimal); - rb_gc_register_mark_object(BIGDECIMAL_POSITIVE_ZERO); - - /* Negative zero value. */ - arg = rb_str_new2("-0"); - BIGDECIMAL_NEGATIVE_ZERO = f_BigDecimal(1, &arg, rb_cBigDecimal); - rb_gc_register_mark_object(BIGDECIMAL_NEGATIVE_ZERO); - - /* Positive infinity value. */ - arg = rb_str_new2("+Infinity"); - BIGDECIMAL_POSITIVE_INFINITY = f_BigDecimal(1, &arg, rb_cBigDecimal); - rb_gc_register_mark_object(BIGDECIMAL_POSITIVE_INFINITY); - - /* Negative infinity value. */ - arg = rb_str_new2("-Infinity"); - BIGDECIMAL_NEGATIVE_INFINITY = f_BigDecimal(1, &arg, rb_cBigDecimal); - rb_gc_register_mark_object(BIGDECIMAL_NEGATIVE_INFINITY); - - /* 'Not a Number' value. */ - arg = rb_str_new2("NaN"); - BIGDECIMAL_NAN = f_BigDecimal(1, &arg, rb_cBigDecimal); - rb_gc_register_mark_object(BIGDECIMAL_NAN); - - /* Special value constants */ - rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_POSITIVE_INFINITY); - rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_NAN); - - /* instance methods */ - rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0); - rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0); - rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0); - - rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2); - rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2); - rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2); - rb_define_method(rb_cBigDecimal, "div", BigDecimal_div3, -1); - rb_define_method(rb_cBigDecimal, "hash", BigDecimal_hash, 0); - rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1); - rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0); - rb_define_method(rb_cBigDecimal, "to_int", BigDecimal_to_i, 0); - rb_define_method(rb_cBigDecimal, "to_r", BigDecimal_to_r, 0); - rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0); - rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1); - rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1); - rb_define_method(rb_cBigDecimal, "+@", BigDecimal_uplus, 0); - rb_define_method(rb_cBigDecimal, "-@", BigDecimal_neg, 0); - rb_define_method(rb_cBigDecimal, "*", BigDecimal_mult, 1); - rb_define_method(rb_cBigDecimal, "/", BigDecimal_div, 1); - rb_define_method(rb_cBigDecimal, "quo", BigDecimal_div, 1); - rb_define_method(rb_cBigDecimal, "%", BigDecimal_mod, 1); - rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1); - rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1); - rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1); - rb_define_method(rb_cBigDecimal, "clone", BigDecimal_clone, 0); - rb_define_method(rb_cBigDecimal, "dup", BigDecimal_clone, 0); - rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0); - rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0); - rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1); - rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0); - rb_define_method(rb_cBigDecimal, "round", BigDecimal_round, -1); - rb_define_method(rb_cBigDecimal, "frac", BigDecimal_frac, 0); - rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1); - rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); - rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, -1); - rb_define_method(rb_cBigDecimal, "**", BigDecimal_power_op, 1); - rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); - rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); - rb_define_method(rb_cBigDecimal, "===", BigDecimal_eq, 1); - rb_define_method(rb_cBigDecimal, "eql?", BigDecimal_eq, 1); - rb_define_method(rb_cBigDecimal, "<", BigDecimal_lt, 1); - rb_define_method(rb_cBigDecimal, "<=", BigDecimal_le, 1); - rb_define_method(rb_cBigDecimal, ">", BigDecimal_gt, 1); - rb_define_method(rb_cBigDecimal, ">=", BigDecimal_ge, 1); - rb_define_method(rb_cBigDecimal, "zero?", BigDecimal_zero, 0); - rb_define_method(rb_cBigDecimal, "nonzero?", BigDecimal_nonzero, 0); - rb_define_method(rb_cBigDecimal, "coerce", BigDecimal_coerce, 1); - rb_define_method(rb_cBigDecimal, "inspect", BigDecimal_inspect, 0); - rb_define_method(rb_cBigDecimal, "exponent", BigDecimal_exponent, 0); - rb_define_method(rb_cBigDecimal, "sign", BigDecimal_sign, 0); - rb_define_method(rb_cBigDecimal, "nan?", BigDecimal_IsNaN, 0); - rb_define_method(rb_cBigDecimal, "infinite?", BigDecimal_IsInfinite, 0); - rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); - rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); - rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); - - rb_mBigMath = rb_define_module("BigMath"); - rb_define_singleton_method(rb_mBigMath, "exp", BigMath_s_exp, 2); - rb_define_singleton_method(rb_mBigMath, "log", BigMath_s_log, 2); - - id_up = rb_intern_const("up"); - id_down = rb_intern_const("down"); - id_truncate = rb_intern_const("truncate"); - id_half_up = rb_intern_const("half_up"); - id_default = rb_intern_const("default"); - id_half_down = rb_intern_const("half_down"); - id_half_even = rb_intern_const("half_even"); - id_banker = rb_intern_const("banker"); - id_ceiling = rb_intern_const("ceiling"); - id_ceil = rb_intern_const("ceil"); - id_floor = rb_intern_const("floor"); - id_to_r = rb_intern_const("to_r"); - id_eq = rb_intern_const("=="); - id_half = rb_intern_const("half"); -} - -/* - * - * ============================================================================ - * - * vp_ routines begin from here. - * - * ============================================================================ - * - */ -#ifdef BIGDECIMAL_DEBUG -static int gfDebug = 1; /* Debug switch */ -#if 0 -static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */ -#endif -#endif /* BIGDECIMAL_DEBUG */ - -static Real *VpConstOne; /* constant 1.0 */ -static Real *VpPt5; /* constant 0.5 */ -#define maxnr 100UL /* Maximum iterations for calculating sqrt. */ - /* used in VpSqrt() */ - -/* ETC */ -#define MemCmp(x,y,z) memcmp(x,y,z) -#define StrCmp(x,y) strcmp(x,y) - -enum op_sw { - OP_SW_ADD = 1, /* + */ - OP_SW_SUB, /* - */ - OP_SW_MULT, /* * */ - OP_SW_DIV /* / */ -}; - -static int VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw); -static int AddExponent(Real *a, SIGNED_VALUE n); -static DECDIG VpAddAbs(Real *a,Real *b,Real *c); -static DECDIG VpSubAbs(Real *a,Real *b,Real *c); -static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv); -static int VpNmlz(Real *a); -static void VpFormatSt(char *psz, size_t fFmt); -static int VpRdup(Real *m, size_t ind_m); - -#ifdef BIGDECIMAL_DEBUG -# ifdef HAVE_RB_EXT_RACTOR_SAFE -# error Need to make rewiting gnAlloc atomic -# endif -static int gnAlloc = 0; /* Memory allocation counter */ -#endif /* BIGDECIMAL_DEBUG */ - -VP_EXPORT void * -VpMemAlloc(size_t mb) -{ - void *p = xmalloc(mb); - memset(p, 0, mb); -#ifdef BIGDECIMAL_DEBUG - gnAlloc++; /* Count allocation call */ -#endif /* BIGDECIMAL_DEBUG */ - return p; -} - -VP_EXPORT void * -VpMemRealloc(void *ptr, size_t mb) -{ - return xrealloc(ptr, mb); -} - -VP_EXPORT void -VpFree(Real *pv) -{ - if (pv != NULL) { - xfree(pv); -#ifdef BIGDECIMAL_DEBUG - gnAlloc--; /* Decrement allocation count */ - if (gnAlloc == 0) { - printf(" *************** All memories allocated freed ****************\n"); - /*getchar();*/ - } - if (gnAlloc < 0) { - printf(" ??????????? Too many memory free calls(%d) ?????????????\n", gnAlloc); - /*getchar();*/ - } -#endif /* BIGDECIMAL_DEBUG */ - } -} - -/* - * EXCEPTION Handling. - */ - -#define bigdecimal_set_thread_local_exception_mode(mode) \ - rb_thread_local_aset( \ - rb_thread_current(), \ - id_BigDecimal_exception_mode, \ - INT2FIX((int)(mode)) \ - ) - -static unsigned short -VpGetException (void) -{ - VALUE const vmode = rb_thread_local_aref( - rb_thread_current(), - id_BigDecimal_exception_mode - ); - - if (NIL_P(vmode)) { - bigdecimal_set_thread_local_exception_mode(BIGDECIMAL_EXCEPTION_MODE_DEFAULT); - return BIGDECIMAL_EXCEPTION_MODE_DEFAULT; - } - - return NUM2USHORT(vmode); -} - -static void -VpSetException(unsigned short f) -{ - bigdecimal_set_thread_local_exception_mode(f); -} - -/* - * Precision limit. - */ - -#define bigdecimal_set_thread_local_precision_limit(limit) \ - rb_thread_local_aset( \ - rb_thread_current(), \ - id_BigDecimal_precision_limit, \ - SIZET2NUM(limit) \ - ) -#define BIGDECIMAL_PRECISION_LIMIT_DEFAULT ((size_t)0) - -/* These 2 functions added at v1.1.7 */ -VP_EXPORT size_t -VpGetPrecLimit(void) -{ - VALUE const vlimit = rb_thread_local_aref( - rb_thread_current(), - id_BigDecimal_precision_limit - ); - - if (NIL_P(vlimit)) { - bigdecimal_set_thread_local_precision_limit(BIGDECIMAL_PRECISION_LIMIT_DEFAULT); - return BIGDECIMAL_PRECISION_LIMIT_DEFAULT; - } - - return NUM2SIZET(vlimit); -} - -VP_EXPORT size_t -VpSetPrecLimit(size_t n) -{ - size_t const s = VpGetPrecLimit(); - bigdecimal_set_thread_local_precision_limit(n); - return s; -} - -/* - * Rounding mode. - */ - -#define bigdecimal_set_thread_local_rounding_mode(mode) \ - rb_thread_local_aset( \ - rb_thread_current(), \ - id_BigDecimal_rounding_mode, \ - INT2FIX((int)(mode)) \ - ) - -VP_EXPORT unsigned short -VpGetRoundMode(void) -{ - VALUE const vmode = rb_thread_local_aref( - rb_thread_current(), - id_BigDecimal_rounding_mode - ); - - if (NIL_P(vmode)) { - bigdecimal_set_thread_local_rounding_mode(BIGDECIMAL_ROUNDING_MODE_DEFAULT); - return BIGDECIMAL_ROUNDING_MODE_DEFAULT; - } - - return NUM2USHORT(vmode); -} - -VP_EXPORT int -VpIsRoundMode(unsigned short n) -{ - switch (n) { - case VP_ROUND_UP: - case VP_ROUND_DOWN: - case VP_ROUND_HALF_UP: - case VP_ROUND_HALF_DOWN: - case VP_ROUND_CEIL: - case VP_ROUND_FLOOR: - case VP_ROUND_HALF_EVEN: - return 1; - - default: - return 0; - } -} - -VP_EXPORT unsigned short -VpSetRoundMode(unsigned short n) -{ - if (VpIsRoundMode(n)) { - bigdecimal_set_thread_local_rounding_mode(n); - return n; - } - - return VpGetRoundMode(); -} - -/* - * 0.0 & 1.0 generator - * These gZero_..... and gOne_..... can be any name - * referenced from nowhere except Zero() and One(). - * gZero_..... and gOne_..... must have global scope - * (to let the compiler know they may be changed in outside - * (... but not actually..)). - */ -volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0; - -static double -One(void) -{ - return gOne_ABCED9B4_CE73__00400511F31D; -} - -/* - ---------------------------------------------------------------- - Value of sign in Real structure is reserved for future use. - short sign; - ==0 : NaN - 1 : Positive zero - -1 : Negative zero - 2 : Positive number - -2 : Negative number - 3 : Positive infinite number - -3 : Negative infinite number - ---------------------------------------------------------------- -*/ - -VP_EXPORT double -VpGetDoubleNaN(void) /* Returns the value of NaN */ -{ - return nan(""); -} - -VP_EXPORT double -VpGetDoublePosInf(void) /* Returns the value of +Infinity */ -{ - return HUGE_VAL; -} - -VP_EXPORT double -VpGetDoubleNegInf(void) /* Returns the value of -Infinity */ -{ - return -HUGE_VAL; -} - -VP_EXPORT double -VpGetDoubleNegZero(void) /* Returns the value of -0 */ -{ - static double nzero = 1000.0; - if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf()); - return nzero; -} - -#if 0 /* unused */ -VP_EXPORT int -VpIsNegDoubleZero(double v) -{ - double z = VpGetDoubleNegZero(); - return MemCmp(&v,&z,sizeof(v))==0; -} -#endif - -VP_EXPORT int -VpException(unsigned short f, const char *str,int always) -{ - unsigned short const exception_mode = VpGetException(); - - if (f == VP_EXCEPTION_OP) always = 1; - - if (always || (exception_mode & f)) { - switch(f) { - /* case VP_EXCEPTION_OVERFLOW: */ - case VP_EXCEPTION_ZERODIVIDE: - case VP_EXCEPTION_INFINITY: - case VP_EXCEPTION_NaN: - case VP_EXCEPTION_UNDERFLOW: - case VP_EXCEPTION_OP: - rb_raise(rb_eFloatDomainError, "%s", str); - break; - default: - rb_fatal("%s", str); - } - } - return 0; /* 0 Means VpException() raised no exception */ -} - -/* Throw exception or returns 0,when resulting c is Inf or NaN */ -/* sw=1:+ 2:- 3:* 4:/ */ -static int -VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw) -{ - if (VpIsNaN(a) || VpIsNaN(b)) { - /* at least a or b is NaN */ - VpSetNaN(c); - goto NaN; - } - - if (VpIsInf(a)) { - if (VpIsInf(b)) { - switch(sw) { - case OP_SW_ADD: /* + */ - if (VpGetSign(a) == VpGetSign(b)) { - VpSetInf(c, VpGetSign(a)); - goto Inf; - } - else { - VpSetNaN(c); - goto NaN; - } - case OP_SW_SUB: /* - */ - if (VpGetSign(a) != VpGetSign(b)) { - VpSetInf(c, VpGetSign(a)); - goto Inf; - } - else { - VpSetNaN(c); - goto NaN; - } - case OP_SW_MULT: /* * */ - VpSetInf(c, VpGetSign(a)*VpGetSign(b)); - goto Inf; - case OP_SW_DIV: /* / */ - VpSetNaN(c); - goto NaN; - } - VpSetNaN(c); - goto NaN; - } - /* Inf op Finite */ - switch(sw) { - case OP_SW_ADD: /* + */ - case OP_SW_SUB: /* - */ - VpSetInf(c, VpGetSign(a)); - break; - case OP_SW_MULT: /* * */ - if (VpIsZero(b)) { - VpSetNaN(c); - goto NaN; - } - VpSetInf(c, VpGetSign(a)*VpGetSign(b)); - break; - case OP_SW_DIV: /* / */ - VpSetInf(c, VpGetSign(a)*VpGetSign(b)); - } - goto Inf; - } - - if (VpIsInf(b)) { - switch(sw) { - case OP_SW_ADD: /* + */ - VpSetInf(c, VpGetSign(b)); - break; - case OP_SW_SUB: /* - */ - VpSetInf(c, -VpGetSign(b)); - break; - case OP_SW_MULT: /* * */ - if (VpIsZero(a)) { - VpSetNaN(c); - goto NaN; - } - VpSetInf(c, VpGetSign(a)*VpGetSign(b)); - break; - case OP_SW_DIV: /* / */ - VpSetZero(c, VpGetSign(a)*VpGetSign(b)); - } - goto Inf; - } - return 1; /* Results OK */ - -Inf: - if (VpIsPosInf(c)) { - return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); - } - else { - return VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0); - } - -NaN: - return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); -} - -/* - ---------------------------------------------------------------- -*/ - -/* - * returns number of chars needed to represent vp in specified format. - */ -VP_EXPORT size_t -VpNumOfChars(Real *vp,const char *pszFmt) -{ - SIGNED_VALUE ex; - size_t nc; - - if (vp == NULL) return BASE_FIG*2+6; - if (!VpIsDef(vp)) return 32; /* not sure,may be OK */ - - switch(*pszFmt) { - case 'F': - nc = BASE_FIG*(vp->Prec + 1)+2; - ex = vp->exponent; - if (ex < 0) { - nc += BASE_FIG*(size_t)(-ex); - } - else { - if ((size_t)ex > vp->Prec) { - nc += BASE_FIG*((size_t)ex - vp->Prec); - } - } - break; - case 'E': - /* fall through */ - default: - nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */ - } - return nc; -} - -/* - * Initializer for Vp routines and constants used. - * [Input] - * BaseVal: Base value(assigned to BASE) for Vp calculation. - * It must be the form BaseVal=10**n.(n=1,2,3,...) - * If Base <= 0L,then the BASE will be calculated so - * that BASE is as large as possible satisfying the - * relation MaxVal <= BASE*(BASE+1). Where the value - * MaxVal is the largest value which can be represented - * by one DECDIG word in the computer used. - * - * [Returns] - * BIGDECIMAL_DOUBLE_FIGURES ... OK - */ -VP_EXPORT size_t -VpInit(DECDIG BaseVal) -{ - /* Setup +/- Inf NaN -0 */ - VpGetDoubleNegZero(); - - /* Allocates Vp constants. */ - VpConstOne = VpAlloc(1UL, "1", 1, 1); - VpPt5 = VpAlloc(1UL, ".5", 1, 1); - -#ifdef BIGDECIMAL_DEBUG - gnAlloc = 0; -#endif /* BIGDECIMAL_DEBUG */ - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - printf("VpInit: BaseVal = %"PRIuDECDIG"\n", BaseVal); - printf("\tBASE = %"PRIuDECDIG"\n", BASE); - printf("\tHALF_BASE = %"PRIuDECDIG"\n", HALF_BASE); - printf("\tBASE1 = %"PRIuDECDIG"\n", BASE1); - printf("\tBASE_FIG = %u\n", BASE_FIG); - printf("\tBIGDECIMAL_DOUBLE_FIGURES = %d\n", BIGDECIMAL_DOUBLE_FIGURES); - } -#endif /* BIGDECIMAL_DEBUG */ - - return BIGDECIMAL_DOUBLE_FIGURES; -} - -VP_EXPORT Real * -VpOne(void) -{ - return VpConstOne; -} - -/* If exponent overflows,then raise exception or returns 0 */ -static int -AddExponent(Real *a, SIGNED_VALUE n) -{ - SIGNED_VALUE e = a->exponent; - SIGNED_VALUE m = e+n; - SIGNED_VALUE eb, mb; - if (e > 0) { - if (n > 0) { - if (MUL_OVERFLOW_SIGNED_VALUE_P(m, (SIGNED_VALUE)BASE_FIG) || - MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) - goto overflow; - mb = m*(SIGNED_VALUE)BASE_FIG; - eb = e*(SIGNED_VALUE)BASE_FIG; - if (eb - mb > 0) goto overflow; - } - } - else if (n < 0) { - if (MUL_OVERFLOW_SIGNED_VALUE_P(m, (SIGNED_VALUE)BASE_FIG) || - MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) - goto underflow; - mb = m*(SIGNED_VALUE)BASE_FIG; - eb = e*(SIGNED_VALUE)BASE_FIG; - if (mb - eb > 0) goto underflow; - } - a->exponent = m; - return 1; - -/* Overflow/Underflow ==> Raise exception or returns 0 */ -underflow: - VpSetZero(a, VpGetSign(a)); - return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0); - -overflow: - VpSetInf(a, VpGetSign(a)); - return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0); -} - -Real * -bigdecimal_parse_special_string(const char *str) -{ - static const struct { - const char *str; - size_t len; - int sign; - } table[] = { - { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE }, - { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE }, - { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE }, - { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN } - }; - static const size_t table_length = sizeof(table) / sizeof(table[0]); - size_t i; - - for (i = 0; i < table_length; ++i) { - const char *p; - if (strncmp(str, table[i].str, table[i].len) != 0) { - continue; - } - - p = str + table[i].len; - while (*p && ISSPACE(*p)) ++p; - if (*p == '\0') { - Real *vp = VpAllocReal(1); - vp->MaxPrec = 1; - switch (table[i].sign) { - default: - UNREACHABLE; break; - case VP_SIGN_POSITIVE_INFINITE: - VpSetPosInf(vp); - return vp; - case VP_SIGN_NEGATIVE_INFINITE: - VpSetNegInf(vp); - return vp; - case VP_SIGN_NaN: - VpSetNaN(vp); - return vp; - } - } - } - - return NULL; -} - -/* - * Allocates variable. - * [Input] - * mx ... allocation unit, if zero then mx is determined by szVal. - * The mx is the number of effective digits can to be stored. - * szVal ... value assigned(char). If szVal==NULL,then zero is assumed. - * If szVal[0]=='#' then Max. Prec. will not be considered(1.1.7), - * full precision specified by szVal is allocated. - * - * [Returns] - * Pointer to the newly allocated variable, or - * NULL be returned if memory allocation is failed,or any error. - */ -VP_EXPORT Real * -VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) -{ - const char *orig_szVal = szVal; - size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc; - char v, *psz; - int sign=1; - Real *vp = NULL; - size_t mf = VpGetPrecLimit(); - VALUE buf; - - mx = (mx + BASE_FIG - 1) / BASE_FIG; /* Determine allocation unit. */ - if (mx == 0) ++mx; - - if (szVal) { - /* Skipping leading spaces */ - while (ISSPACE(*szVal)) szVal++; - - /* Processing the leading one `#` */ - if (*szVal != '#') { - if (mf) { - mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */ - if (mx > mf) { - mx = mf; - } - } - } - else { - ++szVal; - } - } - else { - return_zero: - /* necessary to be able to store */ - /* at least mx digits. */ - /* szVal==NULL ==> allocate zero value. */ - vp = VpAllocReal(mx); - vp->MaxPrec = mx; /* set max precision */ - VpSetZero(vp, 1); /* initialize vp to zero. */ - return vp; - } - - /* Check on Inf & NaN */ - if ((vp = bigdecimal_parse_special_string(szVal)) != NULL) { - return vp; - } - - /* Scanning digits */ - - /* A buffer for keeping scanned digits */ - buf = rb_str_tmp_new(strlen(szVal) + 1); - psz = RSTRING_PTR(buf); - - /* cursor: i for psz, and j for szVal */ - i = j = 0; - - /* Scanning: sign part */ - v = psz[i] = szVal[j]; - if ((v == '-') || (v == '+')) { - sign = -(v == '-'); - ++i; - ++j; - } - - /* Scanning: integer part */ - ni = 0; /* number of digits in the integer part */ - while ((v = psz[i] = szVal[j]) != '\0') { - if (!strict_p && ISSPACE(v)) { - v = psz[i] = '\0'; - break; - } - if (v == '_') { - if (ni > 0) { - v = szVal[j+1]; - if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) { - ++j; - continue; - } - if (!strict_p) { - v = psz[i] = '\0'; - break; - } - } - goto invalid_value; - } - if (!ISDIGIT(v)) { - break; - } - ++ni; - ++i; - ++j; - } - - /* Scanning: fractional part */ - nf = 0; /* number of digits in the fractional part */ - ne = 0; /* number of digits in the exponential part */ - ipf = 0; /* index of the beginning of the fractional part */ - ipe = 0; /* index of the beginning of the exponential part */ - dot_seen = 0; - exp_seen = 0; - - if (v != '\0') { - /* Scanning fractional part */ - if ((psz[i] = szVal[j]) == '.') { - dot_seen = 1; - ++i; - ++j; - ipf = i; - while ((v = psz[i] = szVal[j]) != '\0') { - if (!strict_p && ISSPACE(v)) { - v = psz[i] = '\0'; - break; - } - if (v == '_') { - if (nf > 0 && ISDIGIT(szVal[j+1])) { - ++j; - continue; - } - if (!strict_p) { - v = psz[i] = '\0'; - if (nf == 0) { - dot_seen = 0; - } - break; - } - goto invalid_value; - } - if (!ISDIGIT(v)) break; - ++i; - ++j; - ++nf; - } - } - - /* Scanning exponential part */ - if (v != '\0') { - switch ((psz[i] = szVal[j])) { - case '\0': - break; - case 'e': case 'E': - case 'd': case 'D': - exp_seen = 1; - ++i; - ++j; - ipe = i; - v = psz[i] = szVal[j]; - if ((v == '-') || (v == '+')) { - ++i; - ++j; - } - while ((v = psz[i] = szVal[j]) != '\0') { - if (!strict_p && ISSPACE(v)) { - v = psz[i] = '\0'; - break; - } - if (v == '_') { - if (ne > 0 && ISDIGIT(szVal[j+1])) { - ++j; - continue; - } - if (!strict_p) { - v = psz[i] = '\0'; - if (ne == 0) { - exp_seen = 0; - } - break; - } - goto invalid_value; - } - if (!ISDIGIT(v)) break; - ++i; - ++j; - ++ne; - } - break; - default: - break; - } - } - - if (v != '\0') { - /* Scanning trailing spaces */ - while (ISSPACE(szVal[j])) ++j; - - /* Invalid character */ - if (szVal[j] && strict_p) { - goto invalid_value; - } - } - } - - psz[i] = '\0'; - - if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) { - VALUE str; - invalid_value: - if (!strict_p) { - goto return_zero; - } - if (!exc) { - return NULL; - } - str = rb_str_new2(orig_szVal); - rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str); - } - - nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */ - /* units for szVal[] */ - if (mx == 0) mx = 1; - nalloc = Max(nalloc, mx); - mx = nalloc; - vp = VpAllocReal(mx); - vp->MaxPrec = mx; /* set max precision */ - VpSetZero(vp, sign); - VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne); - rb_str_resize(buf, 0); - return vp; -} - -/* - * Assignment(c=a). - * [Input] - * a ... RHSV - * isw ... switch for assignment. - * c = a when isw > 0 - * c = -a when isw < 0 - * if c->MaxPrec < a->Prec,then round operation - * will be performed. - * [Output] - * c ... LHSV - */ -VP_EXPORT size_t -VpAsgn(Real *c, Real *a, int isw) -{ - size_t n; - if (VpIsNaN(a)) { - VpSetNaN(c); - return 0; - } - if (VpIsInf(a)) { - VpSetInf(c, isw * VpGetSign(a)); - return 0; - } - - /* check if the RHS is zero */ - if (!VpIsZero(a)) { - c->exponent = a->exponent; /* store exponent */ - VpSetSign(c, isw * VpGetSign(a)); /* set sign */ - n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec); - c->Prec = n; - memcpy(c->frac, a->frac, n * sizeof(DECDIG)); - /* Needs round ? */ - if (isw != 10) { - /* Not in ActiveRound */ - if(c->Prec < a->Prec) { - VpInternalRound(c, n, (n>0) ? a->frac[n-1] : 0, a->frac[n]); - } - else { - VpLimitRound(c,0); - } - } - } - else { - /* The value of 'a' is zero. */ - VpSetZero(c, isw * VpGetSign(a)); - return 1; - } - return c->Prec * BASE_FIG; -} - -/* - * c = a + b when operation = 1 or 2 - * c = a - b when operation = -1 or -2. - * Returns number of significant digits of c - */ -VP_EXPORT size_t -VpAddSub(Real *c, Real *a, Real *b, int operation) -{ - short sw, isw; - Real *a_ptr, *b_ptr; - size_t n, na, nb, i; - DECDIG mrv; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpAddSub(enter) a=% \n", a); - VPrint(stdout, " b=% \n", b); - printf(" operation=%d\n", operation); - } -#endif /* BIGDECIMAL_DEBUG */ - - if (!VpIsDefOP(c, a, b, (operation > 0) ? OP_SW_ADD : OP_SW_SUB)) return 0; /* No significant digits */ - - /* check if a or b is zero */ - if (VpIsZero(a)) { - /* a is zero,then assign b to c */ - if (!VpIsZero(b)) { - VpAsgn(c, b, operation); - } - else { - /* Both a and b are zero. */ - if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) { - /* -0 -0 */ - VpSetZero(c, -1); - } - else { - VpSetZero(c, 1); - } - return 1; /* 0: 1 significant digits */ - } - return c->Prec * BASE_FIG; - } - if (VpIsZero(b)) { - /* b is zero,then assign a to c. */ - VpAsgn(c, a, 1); - return c->Prec*BASE_FIG; - } - - if (operation < 0) sw = -1; - else sw = 1; - - /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */ - if (a->exponent > b->exponent) { - a_ptr = a; - b_ptr = b; - } /* |a|>|b| */ - else if (a->exponent < b->exponent) { - a_ptr = b; - b_ptr = a; - } /* |a|<|b| */ - else { - /* Exponent part of a and b is the same,then compare fraction */ - /* part */ - na = a->Prec; - nb = b->Prec; - n = Min(na, nb); - for (i=0; i < n; ++i) { - if (a->frac[i] > b->frac[i]) { - a_ptr = a; - b_ptr = b; - goto end_if; - } - else if (a->frac[i] < b->frac[i]) { - a_ptr = b; - b_ptr = a; - goto end_if; - } - } - if (na > nb) { - a_ptr = a; - b_ptr = b; - goto end_if; - } - else if (na < nb) { - a_ptr = b; - b_ptr = a; - goto end_if; - } - /* |a| == |b| */ - if (VpGetSign(a) + sw *VpGetSign(b) == 0) { - VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */ - return c->Prec * BASE_FIG; - } - a_ptr = a; - b_ptr = b; - } - -end_if: - isw = VpGetSign(a) + sw *VpGetSign(b); - /* - * isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1) - * = 2 ...( 1)+( 1),( 1)-(-1) - * =-2 ...(-1)+(-1),(-1)-( 1) - * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|) - * else c =(Sign ofisw)(|a_ptr|+|b_ptr|) - */ - if (isw) { /* addition */ - VpSetSign(c, 1); - mrv = VpAddAbs(a_ptr, b_ptr, c); - VpSetSign(c, isw / 2); - } - else { /* subtraction */ - VpSetSign(c, 1); - mrv = VpSubAbs(a_ptr, b_ptr, c); - if (a_ptr == a) { - VpSetSign(c,VpGetSign(a)); - } - else { - VpSetSign(c, VpGetSign(a_ptr) * sw); - } - } - VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv); - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpAddSub(result) c=% \n", c); - VPrint(stdout, " a=% \n", a); - VPrint(stdout, " b=% \n", b); - printf(" operation=%d\n", operation); - } -#endif /* BIGDECIMAL_DEBUG */ - return c->Prec * BASE_FIG; -} - -/* - * Addition of two values with variable precision - * a and b assuming abs(a)>abs(b). - * c = abs(a) + abs(b) ; where |a|>=|b| - */ -static DECDIG -VpAddAbs(Real *a, Real *b, Real *c) -{ - size_t word_shift; - size_t ap; - size_t bp; - size_t cp; - size_t a_pos; - size_t b_pos, b_pos_with_word_shift; - size_t c_pos; - DECDIG av, bv, carry, mrv; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpAddAbs called: a = %\n", a); - VPrint(stdout, " b = %\n", b); - } -#endif /* BIGDECIMAL_DEBUG */ - - word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); - a_pos = ap; - b_pos = bp; - c_pos = cp; - - if (word_shift == (size_t)-1L) return 0; /* Overflow */ - if (b_pos == (size_t)-1L) goto Assign_a; - - mrv = av + bv; /* Most right val. Used for round. */ - - /* Just assign the last few digits of b to c because a has no */ - /* corresponding digits to be added. */ - if (b_pos > 0) { - while (b_pos > 0 && b_pos + word_shift > a_pos) { - c->frac[--c_pos] = b->frac[--b_pos]; - } - } - if (b_pos == 0 && word_shift > a_pos) { - while (word_shift-- > a_pos) { - c->frac[--c_pos] = 0; - } - } - - /* Just assign the last few digits of a to c because b has no */ - /* corresponding digits to be added. */ - b_pos_with_word_shift = b_pos + word_shift; - while (a_pos > b_pos_with_word_shift) { - c->frac[--c_pos] = a->frac[--a_pos]; - } - carry = 0; /* set first carry be zero */ - - /* Now perform addition until every digits of b will be */ - /* exhausted. */ - while (b_pos > 0) { - c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; - if (c->frac[c_pos] >= BASE) { - c->frac[c_pos] -= BASE; - carry = 1; - } - else { - carry = 0; - } - } - - /* Just assign the first few digits of a with considering */ - /* the carry obtained so far because b has been exhausted. */ - while (a_pos > 0) { - c->frac[--c_pos] = a->frac[--a_pos] + carry; - if (c->frac[c_pos] >= BASE) { - c->frac[c_pos] -= BASE; - carry = 1; - } - else { - carry = 0; - } - } - if (c_pos) c->frac[c_pos - 1] += carry; - goto Exit; - -Assign_a: - VpAsgn(c, a, 1); - mrv = 0; - -Exit: - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpAddAbs exit: c=% \n", c); - } -#endif /* BIGDECIMAL_DEBUG */ - return mrv; -} - -/* - * c = abs(a) - abs(b) - */ -static DECDIG -VpSubAbs(Real *a, Real *b, Real *c) -{ - size_t word_shift; - size_t ap; - size_t bp; - size_t cp; - size_t a_pos; - size_t b_pos, b_pos_with_word_shift; - size_t c_pos; - DECDIG av, bv, borrow, mrv; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpSubAbs called: a = %\n", a); - VPrint(stdout, " b = %\n", b); - } -#endif /* BIGDECIMAL_DEBUG */ - - word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); - a_pos = ap; - b_pos = bp; - c_pos = cp; - if (word_shift == (size_t)-1L) return 0; /* Overflow */ - if (b_pos == (size_t)-1L) goto Assign_a; - - if (av >= bv) { - mrv = av - bv; - borrow = 0; - } - else { - mrv = 0; - borrow = 1; - } - - /* Just assign the values which are the BASE subtracted by */ - /* each of the last few digits of the b because the a has no */ - /* corresponding digits to be subtracted. */ - if (b_pos + word_shift > a_pos) { - while (b_pos > 0 && b_pos + word_shift > a_pos) { - c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow; - borrow = 1; - } - if (b_pos == 0) { - while (word_shift > a_pos) { - --word_shift; - c->frac[--c_pos] = BASE - borrow; - borrow = 1; - } - } - } - /* Just assign the last few digits of a to c because b has no */ - /* corresponding digits to subtract. */ - - b_pos_with_word_shift = b_pos + word_shift; - while (a_pos > b_pos_with_word_shift) { - c->frac[--c_pos] = a->frac[--a_pos]; - } - - /* Now perform subtraction until every digits of b will be */ - /* exhausted. */ - while (b_pos > 0) { - --c_pos; - if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) { - c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; - borrow = 1; - } - else { - c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; - borrow = 0; - } - } - - /* Just assign the first few digits of a with considering */ - /* the borrow obtained so far because b has been exhausted. */ - while (a_pos > 0) { - --c_pos; - if (a->frac[--a_pos] < borrow) { - c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; - borrow = 1; - } - else { - c->frac[c_pos] = a->frac[a_pos] - borrow; - borrow = 0; - } - } - if (c_pos) c->frac[c_pos - 1] -= borrow; - goto Exit; - -Assign_a: - VpAsgn(c, a, 1); - mrv = 0; - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpSubAbs exit: c=% \n", c); - } -#endif /* BIGDECIMAL_DEBUG */ - return mrv; -} - -/* - * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant - * digit of c(In case of addition). - * ------------------------- figure of output ----------------------------------- - * a = xxxxxxxxxxx - * b = xxxxxxxxxx - * c =xxxxxxxxxxxxxxx - * word_shift = | | - * right_word = | | (Total digits in RHSV) - * left_word = | | (Total digits in LHSV) - * a_pos = | - * b_pos = | - * c_pos = | - */ -static size_t -VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv) -{ - size_t left_word, right_word, word_shift; - - size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; - - assert(a->exponent >= b->exponent); - - c->frac[0] = 0; - *av = *bv = 0; - - word_shift = (a->exponent - b->exponent); - left_word = b->Prec + word_shift; - right_word = Max(a->Prec, left_word); - left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */ - - /* - * check if 'round' is needed. - */ - if (right_word > left_word) { /* round ? */ - /*--------------------------------- - * Actual size of a = xxxxxxAxx - * Actual size of b = xxxBxxxxx - * Max. size of c = xxxxxx - * Round off = |-----| - * c_pos = | - * right_word = | - * a_pos = | - */ - *c_pos = right_word = left_word + 1; /* Set resulting precision */ - /* be equal to that of c */ - if (a->Prec >= c->MaxPrec) { - /* - * a = xxxxxxAxxx - * c = xxxxxx - * a_pos = | - */ - *a_pos = left_word; - if (*a_pos <= round_limit) { - *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ - } - } - else { - /* - * a = xxxxxxx - * c = xxxxxxxxxx - * a_pos = | - */ - *a_pos = a->Prec; - } - if (b->Prec + word_shift >= c->MaxPrec) { - /* - * a = xxxxxxxxx - * b = xxxxxxxBxxx - * c = xxxxxxxxxxx - * b_pos = | - */ - if (c->MaxPrec >= word_shift + 1) { - *b_pos = c->MaxPrec - word_shift - 1; - if (*b_pos + word_shift <= round_limit) { - *bv = b->frac[*b_pos]; - } - } - else { - *b_pos = -1L; - } - } - else { - /* - * a = xxxxxxxxxxxxxxxx - * b = xxxxxx - * c = xxxxxxxxxxxxx - * b_pos = | - */ - *b_pos = b->Prec; - } - } - else { /* The MaxPrec of c - 1 > The Prec of a + b */ - /* - * a = xxxxxxx - * b = xxxxxx - * c = xxxxxxxxxxx - * c_pos = | - */ - *b_pos = b->Prec; - *a_pos = a->Prec; - *c_pos = right_word + 1; - } - c->Prec = *c_pos; - c->exponent = a->exponent; - if (!AddExponent(c, 1)) return (size_t)-1L; - return word_shift; -} - -/* - * Return number of significant digits - * c = a * b , Where a = a0a1a2 ... an - * b = b0b1b2 ... bm - * c = c0c1c2 ... cl - * a0 a1 ... an * bm - * a0 a1 ... an * bm-1 - * . . . - * . . . - * a0 a1 .... an * b0 - * +_____________________________ - * c0 c1 c2 ...... cl - * nc <---| - * MaxAB |--------------------| - */ -VP_EXPORT size_t -VpMult(Real *c, Real *a, Real *b) -{ - size_t MxIndA, MxIndB, MxIndAB, MxIndC; - size_t ind_c, i, ii, nc; - size_t ind_as, ind_ae, ind_bs; - DECDIG carry; - DECDIG_DBL s; - Real *w; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpMult(Enter): a=% \n", a); - VPrint(stdout, " b=% \n", b); - } -#endif /* BIGDECIMAL_DEBUG */ - - if (!VpIsDefOP(c, a, b, OP_SW_MULT)) return 0; /* No significant digit */ - - if (VpIsZero(a) || VpIsZero(b)) { - /* at least a or b is zero */ - VpSetZero(c, VpGetSign(a) * VpGetSign(b)); - return 1; /* 0: 1 significant digit */ - } - - if (VpIsOne(a)) { - VpAsgn(c, b, VpGetSign(a)); - goto Exit; - } - if (VpIsOne(b)) { - VpAsgn(c, a, VpGetSign(b)); - goto Exit; - } - if (b->Prec > a->Prec) { - /* Adjust so that digits(a)>digits(b) */ - w = a; - a = b; - b = w; - } - w = NULL; - MxIndA = a->Prec - 1; - MxIndB = b->Prec - 1; - MxIndC = c->MaxPrec - 1; - MxIndAB = a->Prec + b->Prec - 1; - - if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */ - w = c; - c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0", 1, 1); - MxIndC = MxIndAB; - } - - /* set LHSV c info */ - - c->exponent = a->exponent; /* set exponent */ - if (!AddExponent(c, b->exponent)) { - if (w) VpFree(c); - return 0; - } - VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */ - carry = 0; - nc = ind_c = MxIndAB; - memset(c->frac, 0, (nc + 1) * sizeof(DECDIG)); /* Initialize c */ - c->Prec = nc + 1; /* set precision */ - for (nc = 0; nc < MxIndAB; ++nc, --ind_c) { - if (nc < MxIndB) { /* The left triangle of the Fig. */ - ind_as = MxIndA - nc; - ind_ae = MxIndA; - ind_bs = MxIndB; - } - else if (nc <= MxIndA) { /* The middle rectangular of the Fig. */ - ind_as = MxIndA - nc; - ind_ae = MxIndA - (nc - MxIndB); - ind_bs = MxIndB; - } - else /* if (nc > MxIndA) */ { /* The right triangle of the Fig. */ - ind_as = 0; - ind_ae = MxIndAB - nc - 1; - ind_bs = MxIndB - (nc - MxIndA); - } - - for (i = ind_as; i <= ind_ae; ++i) { - s = (DECDIG_DBL)a->frac[i] * b->frac[ind_bs--]; - carry = (DECDIG)(s / BASE); - s -= (DECDIG_DBL)carry * BASE; - c->frac[ind_c] += (DECDIG)s; - if (c->frac[ind_c] >= BASE) { - s = c->frac[ind_c] / BASE; - carry += (DECDIG)s; - c->frac[ind_c] -= (DECDIG)(s * BASE); - } - if (carry) { - ii = ind_c; - while (ii-- > 0) { - c->frac[ii] += carry; - if (c->frac[ii] >= BASE) { - carry = c->frac[ii] / BASE; - c->frac[ii] -= (carry * BASE); - } - else { - break; - } - } - } - } - } - if (w != NULL) { /* free work variable */ - VpNmlz(c); - VpAsgn(w, c, 1); - VpFree(c); - c = w; - } - else { - VpLimitRound(c,0); - } - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpMult(c=a*b): c=% \n", c); - VPrint(stdout, " a=% \n", a); - VPrint(stdout, " b=% \n", b); - } -#endif /*BIGDECIMAL_DEBUG */ - return c->Prec*BASE_FIG; -} - -/* - * c = a / b, remainder = r - */ -VP_EXPORT size_t -VpDivd(Real *c, Real *r, Real *a, Real *b) -{ - size_t word_a, word_b, word_c, word_r; - size_t i, n, ind_a, ind_b, ind_c, ind_r; - size_t nLoop; - DECDIG_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2; - DECDIG borrow, borrow1, borrow2; - DECDIG_DBL qb; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, " VpDivd(c=a/b) a=% \n", a); - VPrint(stdout, " b=% \n", b); - } -#endif /*BIGDECIMAL_DEBUG */ - - VpSetNaN(r); - if (!VpIsDefOP(c, a, b, OP_SW_DIV)) goto Exit; - if (VpIsZero(a) && VpIsZero(b)) { - VpSetNaN(c); - return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); - } - if (VpIsZero(b)) { - VpSetInf(c, VpGetSign(a) * VpGetSign(b)); - return VpException(VP_EXCEPTION_ZERODIVIDE, "Divide by zero", 0); - } - if (VpIsZero(a)) { - /* numerator a is zero */ - VpSetZero(c, VpGetSign(a) * VpGetSign(b)); - VpSetZero(r, VpGetSign(a) * VpGetSign(b)); - goto Exit; - } - if (VpIsOne(b)) { - /* divide by one */ - VpAsgn(c, a, VpGetSign(b)); - VpSetZero(r, VpGetSign(a)); - goto Exit; - } - - word_a = a->Prec; - word_b = b->Prec; - word_c = c->MaxPrec; - word_r = r->MaxPrec; - - ind_c = 0; - ind_r = 1; - - if (word_a >= word_r) goto space_error; - - r->frac[0] = 0; - while (ind_r <= word_a) { - r->frac[ind_r] = a->frac[ind_r - 1]; - ++ind_r; - } - - while (ind_r < word_r) r->frac[ind_r++] = 0; - while (ind_c < word_c) c->frac[ind_c++] = 0; - - /* initial procedure */ - b1 = b1p1 = b->frac[0]; - if (b->Prec <= 1) { - b1b2p1 = b1b2 = b1p1 * BASE; - } - else { - b1p1 = b1 + 1; - b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; - if (b->Prec > 2) ++b1b2p1; - } - - /* */ - /* loop start */ - ind_c = word_r - 1; - nLoop = Min(word_c,ind_c); - ind_c = 1; - while (ind_c < nLoop) { - if (r->frac[ind_c] == 0) { - ++ind_c; - continue; - } - r1r2 = (DECDIG_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1]; - if (r1r2 == b1b2) { - /* The first two word digits is the same */ - ind_b = 2; - ind_a = ind_c + 2; - while (ind_b < word_b) { - if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; - if (r->frac[ind_a] > b->frac[ind_b]) break; - ++ind_a; - ++ind_b; - } - /* The first few word digits of r and b is the same and */ - /* the first different word digit of w is greater than that */ - /* of b, so quotient is 1 and just subtract b from r. */ - borrow = 0; /* quotient=1, then just r-b */ - ind_b = b->Prec - 1; - ind_r = ind_c + ind_b; - if (ind_r >= word_r) goto space_error; - n = ind_b; - for (i = 0; i <= n; ++i) { - if (r->frac[ind_r] < b->frac[ind_b] + borrow) { - r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow)); - borrow = 1; - } - else { - r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow; - borrow = 0; - } - --ind_r; - --ind_b; - } - ++c->frac[ind_c]; - goto carry; - } - /* The first two word digits is not the same, */ - /* then compare magnitude, and divide actually. */ - if (r1r2 >= b1b2p1) { - q = r1r2 / b1b2p1; /* q == (DECDIG)q */ - c->frac[ind_c] += (DECDIG)q; - ind_r = b->Prec + ind_c - 1; - goto sub_mult; - } - -div_b1p1: - if (ind_c + 1 >= word_c) goto out_side; - q = r1r2 / b1p1; /* q == (DECDIG)q */ - c->frac[ind_c + 1] += (DECDIG)q; - ind_r = b->Prec + ind_c; - -sub_mult: - borrow1 = borrow2 = 0; - ind_b = word_b - 1; - if (ind_r >= word_r) goto space_error; - n = ind_b; - for (i = 0; i <= n; ++i) { - /* now, perform r = r - q * b */ - qb = q * b->frac[ind_b]; - if (qb < BASE) borrow1 = 0; - else { - borrow1 = (DECDIG)(qb / BASE); - qb -= (DECDIG_DBL)borrow1 * BASE; /* get qb < BASE */ - } - if(r->frac[ind_r] < qb) { - r->frac[ind_r] += (DECDIG)(BASE - qb); - borrow2 = borrow2 + borrow1 + 1; - } - else { - r->frac[ind_r] -= (DECDIG)qb; - borrow2 += borrow1; - } - if (borrow2) { - if(r->frac[ind_r - 1] < borrow2) { - r->frac[ind_r - 1] += (BASE - borrow2); - borrow2 = 1; - } - else { - r->frac[ind_r - 1] -= borrow2; - borrow2 = 0; - } - } - --ind_r; - --ind_b; - } - - r->frac[ind_r] -= borrow2; -carry: - ind_r = ind_c; - while (c->frac[ind_r] >= BASE) { - c->frac[ind_r] -= BASE; - --ind_r; - ++c->frac[ind_r]; - } - } - /* End of operation, now final arrangement */ -out_side: - c->Prec = word_c; - c->exponent = a->exponent; - if (!AddExponent(c, 2)) return 0; - if (!AddExponent(c, -(b->exponent))) return 0; - - VpSetSign(c, VpGetSign(a) * VpGetSign(b)); - VpNmlz(c); /* normalize c */ - r->Prec = word_r; - r->exponent = a->exponent; - if (!AddExponent(r, 1)) return 0; - VpSetSign(r, VpGetSign(a)); - VpNmlz(r); /* normalize r(remainder) */ - goto Exit; - -space_error: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - printf(" word_a=%"PRIuSIZE"\n", word_a); - printf(" word_b=%"PRIuSIZE"\n", word_b); - printf(" word_c=%"PRIuSIZE"\n", word_c); - printf(" word_r=%"PRIuSIZE"\n", word_r); - printf(" ind_r =%"PRIuSIZE"\n", ind_r); - } -#endif /* BIGDECIMAL_DEBUG */ - rb_bug("ERROR(VpDivd): space for remainder too small."); - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, " VpDivd(c=a/b), c=% \n", c); - VPrint(stdout, " r=% \n", r); - } -#endif /* BIGDECIMAL_DEBUG */ - return c->Prec * BASE_FIG; -} - -/* - * Input a = 00000xxxxxxxx En(5 preceding zeros) - * Output a = xxxxxxxx En-5 - */ -static int -VpNmlz(Real *a) -{ - size_t ind_a, i; - - if (!VpIsDef(a)) goto NoVal; - if (VpIsZero(a)) goto NoVal; - - ind_a = a->Prec; - while (ind_a--) { - if (a->frac[ind_a]) { - a->Prec = ind_a + 1; - i = 0; - while (a->frac[i] == 0) ++i; /* skip the first few zeros */ - if (i) { - a->Prec -= i; - if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; - memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(DECDIG)); - } - return 1; - } - } - /* a is zero(no non-zero digit) */ - VpSetZero(a, VpGetSign(a)); - return 0; - -NoVal: - a->frac[0] = 0; - a->Prec = 1; - return 0; -} - -/* - * VpComp = 0 ... if a=b, - * Pos ... a>b, - * Neg ... a<b. - * 999 ... result undefined(NaN) - */ -VP_EXPORT int -VpComp(Real *a, Real *b) -{ - int val; - size_t mx, ind; - int e; - val = 0; - if (VpIsNaN(a) || VpIsNaN(b)) return 999; - if (!VpIsDef(a)) { - if (!VpIsDef(b)) e = a->sign - b->sign; - else e = a->sign; - - if (e > 0) return 1; - else if (e < 0) return -1; - else return 0; - } - if (!VpIsDef(b)) { - e = -b->sign; - if (e > 0) return 1; - else return -1; - } - /* Zero check */ - if (VpIsZero(a)) { - if (VpIsZero(b)) return 0; /* both zero */ - val = -VpGetSign(b); - goto Exit; - } - if (VpIsZero(b)) { - val = VpGetSign(a); - goto Exit; - } - - /* compare sign */ - if (VpGetSign(a) > VpGetSign(b)) { - val = 1; /* a>b */ - goto Exit; - } - if (VpGetSign(a) < VpGetSign(b)) { - val = -1; /* a<b */ - goto Exit; - } - - /* a and b have same sign, && sign!=0,then compare exponent */ - if (a->exponent > b->exponent) { - val = VpGetSign(a); - goto Exit; - } - if (a->exponent < b->exponent) { - val = -VpGetSign(b); - goto Exit; - } - - /* a and b have same exponent, then compare their significand. */ - mx = (a->Prec < b->Prec) ? a->Prec : b->Prec; - ind = 0; - while (ind < mx) { - if (a->frac[ind] > b->frac[ind]) { - val = VpGetSign(a); - goto Exit; - } - if (a->frac[ind] < b->frac[ind]) { - val = -VpGetSign(b); - goto Exit; - } - ++ind; - } - if (a->Prec > b->Prec) { - val = VpGetSign(a); - } - else if (a->Prec < b->Prec) { - val = -VpGetSign(b); - } - -Exit: - if (val > 1) val = 1; - else if (val < -1) val = -1; - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, " VpComp a=%\n", a); - VPrint(stdout, " b=%\n", b); - printf(" ans=%d\n", val); - } -#endif /* BIGDECIMAL_DEBUG */ - return (int)val; -} - -/* - * cntl_chr ... ASCIIZ Character, print control characters - * Available control codes: - * % ... VP variable. To print '%', use '%%'. - * \n ... new line - * \b ... backspace - * \t ... tab - * Note: % must not appear more than once - * a ... VP variable to be printed - */ -#ifdef BIGDECIMAL_ENABLE_VPRINT -static int -VPrint(FILE *fp, const char *cntl_chr, Real *a) -{ - size_t i, j, nc, nd, ZeroSup, sep = 10; - DECDIG m, e, nn; - - j = 0; - nd = nc = 0; /* nd : number of digits in fraction part(every 10 digits, */ - /* nd<=10). */ - /* nc : number of characters printed */ - ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ - while (*(cntl_chr + j)) { - if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') { - nc = 0; - if (VpIsNaN(a)) { - fprintf(fp, SZ_NaN); - nc += 8; - } - else if (VpIsPosInf(a)) { - fprintf(fp, SZ_INF); - nc += 8; - } - else if (VpIsNegInf(a)) { - fprintf(fp, SZ_NINF); - nc += 9; - } - else if (!VpIsZero(a)) { - if (BIGDECIMAL_NEGATIVE_P(a)) { - fprintf(fp, "-"); - ++nc; - } - nc += fprintf(fp, "0."); - switch (*(cntl_chr + j + 1)) { - default: - break; - - case '0': case 'z': - ZeroSup = 0; - ++j; - sep = cntl_chr[j] == 'z' ? BIGDECIMAL_COMPONENT_FIGURES : 10; - break; - } - for (i = 0; i < a->Prec; ++i) { - m = BASE1; - e = a->frac[i]; - while (m) { - nn = e / m; - if (!ZeroSup || nn) { - nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ - /* as 0.00xx will not */ - /* be printed. */ - ++nd; - ZeroSup = 0; /* Set to print succeeding zeros */ - } - if (nd >= sep) { /* print ' ' after every 10 digits */ - nd = 0; - nc += fprintf(fp, " "); - } - e = e - nn * m; - m /= 10; - } - } - nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); - nc += fprintf(fp, " (%"PRIdVALUE", %lu, %lu)", a->exponent, a->Prec, a->MaxPrec); - } - else { - nc += fprintf(fp, "0.0"); - } - } - else { - ++nc; - if (*(cntl_chr + j) == '\\') { - switch (*(cntl_chr + j + 1)) { - case 'n': - fprintf(fp, "\n"); - ++j; - break; - case 't': - fprintf(fp, "\t"); - ++j; - break; - case 'b': - fprintf(fp, "\n"); - ++j; - break; - default: - fprintf(fp, "%c", *(cntl_chr + j)); - break; - } - } - else { - fprintf(fp, "%c", *(cntl_chr + j)); - if (*(cntl_chr + j) == '%') ++j; - } - } - j++; - } - - return (int)nc; -} -#endif - -static void -VpFormatSt(char *psz, size_t fFmt) -{ - size_t ie, i, nf = 0; - char ch; - - if (fFmt == 0) return; - - ie = strlen(psz); - for (i = 0; i < ie; ++i) { - ch = psz[i]; - if (!ch) break; - if (ISSPACE(ch) || ch=='-' || ch=='+') continue; - if (ch == '.') { nf = 0; continue; } - if (ch == 'E' || ch == 'e') break; - - if (++nf > fFmt) { - memmove(psz + i + 1, psz + i, ie - i + 1); - ++ie; - nf = 0; - psz[i] = ' '; - } - } -} - -VP_EXPORT ssize_t -VpExponent10(Real *a) -{ - ssize_t ex; - size_t n; - - if (!VpHasVal(a)) return 0; - - ex = a->exponent * (ssize_t)BASE_FIG; - n = BASE1; - while ((a->frac[0] / n) == 0) { - --ex; - n /= 10; - } - return ex; -} - -VP_EXPORT void -VpSzMantissa(Real *a,char *psz) -{ - size_t i, n, ZeroSup; - DECDIG_DBL m, e, nn; - - if (VpIsNaN(a)) { - sprintf(psz, SZ_NaN); - return; - } - if (VpIsPosInf(a)) { - sprintf(psz, SZ_INF); - return; - } - if (VpIsNegInf(a)) { - sprintf(psz, SZ_NINF); - return; - } - - ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ - if (!VpIsZero(a)) { - if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-'; - n = a->Prec; - for (i = 0; i < n; ++i) { - m = BASE1; - e = a->frac[i]; - while (m) { - nn = e / m; - if (!ZeroSup || nn) { - sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */ - psz += strlen(psz); - /* as 0.00xx will be ignored. */ - ZeroSup = 0; /* Set to print succeeding zeros */ - } - e = e - nn * m; - m /= 10; - } - } - *psz = 0; - while (psz[-1] == '0') *(--psz) = 0; - } - else { - if (VpIsPosZero(a)) sprintf(psz, "0"); - else sprintf(psz, "-0"); - } -} - -VP_EXPORT int -VpToSpecialString(Real *a,char *psz,int fPlus) -/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ -{ - if (VpIsNaN(a)) { - sprintf(psz,SZ_NaN); - return 1; - } - - if (VpIsPosInf(a)) { - if (fPlus == 1) { - *psz++ = ' '; - } - else if (fPlus == 2) { - *psz++ = '+'; - } - sprintf(psz, SZ_INF); - return 1; - } - if (VpIsNegInf(a)) { - sprintf(psz, SZ_NINF); - return 1; - } - if (VpIsZero(a)) { - if (VpIsPosZero(a)) { - if (fPlus == 1) sprintf(psz, " 0.0"); - else if (fPlus == 2) sprintf(psz, "+0.0"); - else sprintf(psz, "0.0"); - } - else sprintf(psz, "-0.0"); - return 1; - } - return 0; -} - -VP_EXPORT void -VpToString(Real *a, char *psz, size_t fFmt, int fPlus) -/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ -{ - size_t i, n, ZeroSup; - DECDIG shift, m, e, nn; - char *pszSav = psz; - ssize_t ex; - - if (VpToSpecialString(a, psz, fPlus)) return; - - ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ - - if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-'; - else if (fPlus == 1) *psz++ = ' '; - else if (fPlus == 2) *psz++ = '+'; - - *psz++ = '0'; - *psz++ = '.'; - n = a->Prec; - for (i = 0; i < n; ++i) { - m = BASE1; - e = a->frac[i]; - while (m) { - nn = e / m; - if (!ZeroSup || nn) { - sprintf(psz, "%lu", (unsigned long)nn); /* The reading zero(s) */ - psz += strlen(psz); - /* as 0.00xx will be ignored. */ - ZeroSup = 0; /* Set to print succeeding zeros */ - } - e = e - nn * m; - m /= 10; - } - } - ex = a->exponent * (ssize_t)BASE_FIG; - shift = BASE1; - while (a->frac[0] / shift == 0) { - --ex; - shift /= 10; - } - while (psz[-1] == '0') { - *(--psz) = 0; - } - sprintf(psz, "e%"PRIdSIZE, ex); - if (fFmt) VpFormatSt(pszSav, fFmt); -} - -VP_EXPORT void -VpToFString(Real *a, char *psz, size_t fFmt, int fPlus) -/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ -{ - size_t i, n; - DECDIG m, e, nn; - char *pszSav = psz; - ssize_t ex; - - if (VpToSpecialString(a, psz, fPlus)) return; - - if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-'; - else if (fPlus == 1) *psz++ = ' '; - else if (fPlus == 2) *psz++ = '+'; - - n = a->Prec; - ex = a->exponent; - if (ex <= 0) { - *psz++ = '0';*psz++ = '.'; - while (ex < 0) { - for (i=0; i < BASE_FIG; ++i) *psz++ = '0'; - ++ex; - } - ex = -1; - } - - for (i = 0; i < n; ++i) { - --ex; - if (i == 0 && ex >= 0) { - sprintf(psz, "%lu", (unsigned long)a->frac[i]); - psz += strlen(psz); - } - else { - m = BASE1; - e = a->frac[i]; - while (m) { - nn = e / m; - *psz++ = (char)(nn + '0'); - e = e - nn * m; - m /= 10; - } - } - if (ex == 0) *psz++ = '.'; - } - while (--ex>=0) { - m = BASE; - while (m /= 10) *psz++ = '0'; - if (ex == 0) *psz++ = '.'; - } - *psz = 0; - while (psz[-1] == '0') *(--psz) = 0; - if (psz[-1] == '.') sprintf(psz, "0"); - if (fFmt) VpFormatSt(pszSav, fFmt); -} - -/* - * [Output] - * a[] ... variable to be assigned the value. - * [Input] - * int_chr[] ... integer part(may include '+/-'). - * ni ... number of characters in int_chr[],not including '+/-'. - * frac[] ... fraction part. - * nf ... number of characters in frac[]. - * exp_chr[] ... exponent part(including '+/-'). - * ne ... number of characters in exp_chr[],not including '+/-'. - */ -VP_EXPORT int -VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne) -{ - size_t i, j, ind_a, ma, mi, me; - SIGNED_VALUE e, es, eb, ef; - int sign, signe, exponent_overflow; - - /* get exponent part */ - e = 0; - ma = a->MaxPrec; - mi = ni; - me = ne; - signe = 1; - exponent_overflow = 0; - memset(a->frac, 0, ma * sizeof(DECDIG)); - if (ne > 0) { - i = 0; - if (exp_chr[0] == '-') { - signe = -1; - ++i; - ++me; - } - else if (exp_chr[0] == '+') { - ++i; - ++me; - } - while (i < me) { - if (MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) { - es = e; - goto exp_overflow; - } - es = e * (SIGNED_VALUE)BASE_FIG; - if (MUL_OVERFLOW_SIGNED_VALUE_P(e, 10) || - SIGNED_VALUE_MAX - (exp_chr[i] - '0') < e * 10) - goto exp_overflow; - e = e * 10 + exp_chr[i] - '0'; - if (MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) - goto exp_overflow; - if (es > (SIGNED_VALUE)(e * BASE_FIG)) { - exp_overflow: - exponent_overflow = 1; - e = es; /* keep sign */ - break; - } - ++i; - } - } - - /* get integer part */ - i = 0; - sign = 1; - if (1 /*ni >= 0*/) { - if (int_chr[0] == '-') { - sign = -1; - ++i; - ++mi; - } - else if (int_chr[0] == '+') { - ++i; - ++mi; - } - } - - e = signe * e; /* e: The value of exponent part. */ - e = e + ni; /* set actual exponent size. */ - - if (e > 0) signe = 1; - else signe = -1; - - /* Adjust the exponent so that it is the multiple of BASE_FIG. */ - j = 0; - ef = 1; - while (ef) { - if (e >= 0) eb = e; - else eb = -e; - ef = eb / (SIGNED_VALUE)BASE_FIG; - ef = eb - ef * (SIGNED_VALUE)BASE_FIG; - if (ef) { - ++j; /* Means to add one more preceding zero */ - ++e; - } - } - - eb = e / (SIGNED_VALUE)BASE_FIG; - - if (exponent_overflow) { - int zero = 1; - for ( ; i < mi && zero; i++) zero = int_chr[i] == '0'; - for (i = 0; i < nf && zero; i++) zero = frac[i] == '0'; - if (!zero && signe > 0) { - VpSetInf(a, sign); - VpException(VP_EXCEPTION_INFINITY, "exponent overflow",0); - } - else VpSetZero(a, sign); - return 1; - } - - ind_a = 0; - while (i < mi) { - a->frac[ind_a] = 0; - while (j < BASE_FIG && i < mi) { - a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; - ++j; - ++i; - } - if (i < mi) { - ++ind_a; - if (ind_a >= ma) goto over_flow; - j = 0; - } - } - - /* get fraction part */ - - i = 0; - while (i < nf) { - while (j < BASE_FIG && i < nf) { - a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; - ++j; - ++i; - } - if (i < nf) { - ++ind_a; - if (ind_a >= ma) goto over_flow; - j = 0; - } - } - goto Final; - -over_flow: - rb_warn("Conversion from String to BigDecimal overflow (last few digits discarded)."); - -Final: - if (ind_a >= ma) ind_a = ma - 1; - while (j < BASE_FIG) { - a->frac[ind_a] = a->frac[ind_a] * 10; - ++j; - } - a->Prec = ind_a + 1; - a->exponent = eb; - VpSetSign(a, sign); - VpNmlz(a); - return 1; -} - -/* - * [Input] - * *m ... Real - * [Output] - * *d ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig. - * *e ... exponent of m. - * BIGDECIMAL_DOUBLE_FIGURES ... Number of digits in a double variable. - * - * m -> d*10**e, 0<d<BASE - * [Returns] - * 0 ... Zero - * 1 ... Normal - * 2 ... Infinity - * -1 ... NaN - */ -VP_EXPORT int -VpVtoD(double *d, SIGNED_VALUE *e, Real *m) -{ - size_t ind_m, mm, fig; - double div; - int f = 1; - - if (VpIsNaN(m)) { - *d = VpGetDoubleNaN(); - *e = 0; - f = -1; /* NaN */ - goto Exit; - } - else if (VpIsPosZero(m)) { - *d = 0.0; - *e = 0; - f = 0; - goto Exit; - } - else if (VpIsNegZero(m)) { - *d = VpGetDoubleNegZero(); - *e = 0; - f = 0; - goto Exit; - } - else if (VpIsPosInf(m)) { - *d = VpGetDoublePosInf(); - *e = 0; - f = 2; - goto Exit; - } - else if (VpIsNegInf(m)) { - *d = VpGetDoubleNegInf(); - *e = 0; - f = 2; - goto Exit; - } - /* Normal number */ - fig = roomof(BIGDECIMAL_DOUBLE_FIGURES, BASE_FIG); - ind_m = 0; - mm = Min(fig, m->Prec); - *d = 0.0; - div = 1.; - while (ind_m < mm) { - div /= (double)BASE; - *d = *d + (double)m->frac[ind_m++] * div; - } - *e = m->exponent * (SIGNED_VALUE)BASE_FIG; - *d *= VpGetSign(m); - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, " VpVtoD: m=%\n", m); - printf(" d=%e * 10 **%ld\n", *d, *e); - printf(" BIGDECIMAL_DOUBLE_FIGURES = %d\n", BIGDECIMAL_DOUBLE_FIGURES); - } -#endif /*BIGDECIMAL_DEBUG */ - return f; -} - -/* - * m <- d - */ -VP_EXPORT void -VpDtoV(Real *m, double d) -{ - size_t ind_m, mm; - SIGNED_VALUE ne; - DECDIG i; - double val, val2; - - if (isnan(d)) { - VpSetNaN(m); - goto Exit; - } - if (isinf(d)) { - if (d > 0.0) VpSetPosInf(m); - else VpSetNegInf(m); - goto Exit; - } - - if (d == 0.0) { - VpSetZero(m, 1); - goto Exit; - } - val = (d > 0.) ? d : -d; - ne = 0; - if (val >= 1.0) { - while (val >= 1.0) { - val /= (double)BASE; - ++ne; - } - } - else { - val2 = 1.0 / (double)BASE; - while (val < val2) { - val *= (double)BASE; - --ne; - } - } - /* Now val = 0.xxxxx*BASE**ne */ - - mm = m->MaxPrec; - memset(m->frac, 0, mm * sizeof(DECDIG)); - for (ind_m = 0; val > 0.0 && ind_m < mm; ind_m++) { - val *= (double)BASE; - i = (DECDIG)val; - val -= (double)i; - m->frac[ind_m] = i; - } - if (ind_m >= mm) ind_m = mm - 1; - VpSetSign(m, (d > 0.0) ? 1 : -1); - m->Prec = ind_m + 1; - m->exponent = ne; - - VpInternalRound(m, 0, (m->Prec > 0) ? m->frac[m->Prec-1] : 0, - (DECDIG)(val*(double)BASE)); - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - printf("VpDtoV d=%30.30e\n", d); - VPrint(stdout, " m=%\n", m); - } -#endif /* BIGDECIMAL_DEBUG */ - return; -} - -/* - * m <- ival - */ -#if 0 /* unused */ -VP_EXPORT void -VpItoV(Real *m, SIGNED_VALUE ival) -{ - size_t mm, ind_m; - size_t val, v1, v2, v; - int isign; - SIGNED_VALUE ne; - - if (ival == 0) { - VpSetZero(m, 1); - goto Exit; - } - isign = 1; - val = ival; - if (ival < 0) { - isign = -1; - val =(size_t)(-ival); - } - ne = 0; - ind_m = 0; - mm = m->MaxPrec; - while (ind_m < mm) { - m->frac[ind_m] = 0; - ++ind_m; - } - ind_m = 0; - while (val > 0) { - if (val) { - v1 = val; - v2 = 1; - while (v1 >= BASE) { - v1 /= BASE; - v2 *= BASE; - } - val = val - v2 * v1; - v = v1; - } - else { - v = 0; - } - m->frac[ind_m] = v; - ++ind_m; - ++ne; - } - m->Prec = ind_m - 1; - m->exponent = ne; - VpSetSign(m, isign); - VpNmlz(m); - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - printf(" VpItoV i=%d\n", ival); - VPrint(stdout, " m=%\n", m); - } -#endif /* BIGDECIMAL_DEBUG */ - return; -} -#endif - -/* - * y = SQRT(x), y*y - x =>0 - */ -VP_EXPORT int -VpSqrt(Real *y, Real *x) -{ - Real *f = NULL; - Real *r = NULL; - size_t y_prec; - SIGNED_VALUE n, e; - SIGNED_VALUE prec; - ssize_t nr; - double val; - - /* Zero or +Infinity ? */ - if (VpIsZero(x) || VpIsPosInf(x)) { - VpAsgn(y,x,1); - goto Exit; - } - - /* Negative ? */ - if (BIGDECIMAL_NEGATIVE_P(x)) { - VpSetNaN(y); - return VpException(VP_EXCEPTION_OP, "sqrt of negative value", 0); - } - - /* NaN ? */ - if (VpIsNaN(x)) { - VpSetNaN(y); - return VpException(VP_EXCEPTION_OP, "sqrt of 'NaN'(Not a Number)", 0); - } - - /* One ? */ - if (VpIsOne(x)) { - VpSetOne(y); - goto Exit; - } - - n = (SIGNED_VALUE)y->MaxPrec; - if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec; - - /* allocate temporally variables */ - f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1", 1, 1); - r = VpAlloc((n + n) * (BASE_FIG + 2), "#1", 1, 1); - - nr = 0; - y_prec = y->MaxPrec; - - prec = x->exponent - (ssize_t)y_prec; - if (x->exponent > 0) - ++prec; - else - --prec; - - VpVtoD(&val, &e, x); /* val <- x */ - e /= (SIGNED_VALUE)BASE_FIG; - n = e / 2; - if (e - n * 2 != 0) { - val /= BASE; - n = (e + 1) / 2; - } - VpDtoV(y, sqrt(val)); /* y <- sqrt(val) */ - y->exponent += n; - n = (SIGNED_VALUE)roomof(BIGDECIMAL_DOUBLE_FIGURES, BASE_FIG); - y->MaxPrec = Min((size_t)n , y_prec); - f->MaxPrec = y->MaxPrec + 1; - n = (SIGNED_VALUE)(y_prec * BASE_FIG); - if (n < (SIGNED_VALUE)maxnr) n = (SIGNED_VALUE)maxnr; - do { - y->MaxPrec *= 2; - if (y->MaxPrec > y_prec) y->MaxPrec = y_prec; - f->MaxPrec = y->MaxPrec; - VpDivd(f, r, x, y); /* f = x/y */ - VpAddSub(r, f, y, -1); /* r = f - y */ - VpMult(f, VpPt5, r); /* f = 0.5*r */ - if (VpIsZero(f)) goto converge; - VpAddSub(r, f, y, 1); /* r = y + f */ - VpAsgn(y, r, 1); /* y = r */ - } while (++nr < n); - -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - printf("ERROR(VpSqrt): did not converge within %ld iterations.\n", nr); - } -#endif /* BIGDECIMAL_DEBUG */ - y->MaxPrec = y_prec; - -converge: - VpChangeSign(y, 1); -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VpMult(r, y, y); - VpAddSub(f, x, r, -1); - printf("VpSqrt: iterations = %"PRIdSIZE"\n", nr); - VPrint(stdout, " y =% \n", y); - VPrint(stdout, " x =% \n", x); - VPrint(stdout, " x-y*y = % \n", f); - } -#endif /* BIGDECIMAL_DEBUG */ - y->MaxPrec = y_prec; - -Exit: - VpFree(f); - VpFree(r); - return 1; -} - -/* - * Round relatively from the decimal point. - * f: rounding mode - * nf: digit location to round from the decimal point. - */ -VP_EXPORT int -VpMidRound(Real *y, unsigned short f, ssize_t nf) -{ - /* fracf: any positive digit under rounding position? */ - /* fracf_1further: any positive digits under one further than the rounding position? */ - /* exptoadd: number of digits needed to compensate negative nf */ - int fracf, fracf_1further; - ssize_t n,i,ix,ioffset, exptoadd; - DECDIG v, shifter; - DECDIG div; - - nf += y->exponent * (ssize_t)BASE_FIG; - exptoadd=0; - if (nf < 0) { - /* rounding position too left(large). */ - if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { - VpSetZero(y, VpGetSign(y)); /* truncate everything */ - return 0; - } - exptoadd = -nf; - nf = 0; - } - - ix = nf / (ssize_t)BASE_FIG; - if ((size_t)ix >= y->Prec) return 0; /* rounding position too right(small). */ - v = y->frac[ix]; - - ioffset = nf - ix*(ssize_t)BASE_FIG; - n = (ssize_t)BASE_FIG - ioffset - 1; - for (shifter = 1, i = 0; i < n; ++i) shifter *= 10; - - /* so the representation used (in y->frac) is an array of DECDIG, where - each DECDIG contains a value between 0 and BASE-1, consisting of BASE_FIG - decimal places. - - (that numbers of decimal places are typed as ssize_t is somewhat confusing) - - nf is now position (in decimal places) of the digit from the start of - the array. - - ix is the position (in DECDIGs) of the DECDIG containing the decimal digit, - from the start of the array. - - v is the value of this DECDIG - - ioffset is the number of extra decimal places along of this decimal digit - within v. - - n is the number of decimal digits remaining within v after this decimal digit - shifter is 10**n, - - v % shifter are the remaining digits within v - v % (shifter * 10) are the digit together with the remaining digits within v - v / shifter are the digit's predecessors together with the digit - div = v / shifter / 10 is just the digit's precessors - (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to. - */ - - fracf = (v % (shifter * 10) > 0); - fracf_1further = ((v % shifter) > 0); - - v /= shifter; - div = v / 10; - v = v - div*10; - /* now v is just the digit required. - now fracf is whether the digit or any of the remaining digits within v are non-zero - now fracf_1further is whether any of the remaining digits within v are non-zero - */ - - /* now check all the remaining DECDIGs for zero-ness a whole DECDIG at a time. - if we spot any non-zeroness, that means that we found a positive digit under - rounding position, and we also found a positive digit under one further than - the rounding position, so both searches (to see if any such non-zero digit exists) - can stop */ - - for (i = ix + 1; (size_t)i < y->Prec; i++) { - if (y->frac[i] % BASE) { - fracf = fracf_1further = 1; - break; - } - } - - /* now fracf = does any positive digit exist under the rounding position? - now fracf_1further = does any positive digit exist under one further than the - rounding position? - now v = the first digit under the rounding position */ - - /* drop digits after pointed digit */ - memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(DECDIG)); - - switch (f) { - case VP_ROUND_DOWN: /* Truncate */ - break; - case VP_ROUND_UP: /* Roundup */ - if (fracf) ++div; - break; - case VP_ROUND_HALF_UP: - if (v>=5) ++div; - break; - case VP_ROUND_HALF_DOWN: - if (v > 5 || (v == 5 && fracf_1further)) ++div; - break; - case VP_ROUND_CEIL: - if (fracf && BIGDECIMAL_POSITIVE_P(y)) ++div; - break; - case VP_ROUND_FLOOR: - if (fracf && BIGDECIMAL_NEGATIVE_P(y)) ++div; - break; - case VP_ROUND_HALF_EVEN: /* Banker's rounding */ - if (v > 5) ++div; - else if (v == 5) { - if (fracf_1further) { - ++div; - } - else { - if (ioffset == 0) { - /* v is the first decimal digit of its DECDIG; - need to grab the previous DECDIG if present - to check for evenness of the previous decimal - digit (which is same as that of the DECDIG since - base 10 has a factor of 2) */ - if (ix && (y->frac[ix-1] % 2)) ++div; - } - else { - if (div % 2) ++div; - } - } - } - break; - } - for (i = 0; i <= n; ++i) div *= 10; - if (div >= BASE) { - if (ix) { - y->frac[ix] = 0; - VpRdup(y, ix); - } - else { - short s = VpGetSign(y); - SIGNED_VALUE e = y->exponent; - VpSetOne(y); - VpSetSign(y, s); - y->exponent = e + 1; - } - } - else { - y->frac[ix] = div; - VpNmlz(y); - } - if (exptoadd > 0) { - y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG); - exptoadd %= (ssize_t)BASE_FIG; - for (i = 0; i < exptoadd; i++) { - y->frac[0] *= 10; - if (y->frac[0] >= BASE) { - y->frac[0] /= BASE; - y->exponent++; - } - } - } - return 1; -} - -VP_EXPORT int -VpLeftRound(Real *y, unsigned short f, ssize_t nf) -/* - * Round from the left hand side of the digits. - */ -{ - DECDIG v; - if (!VpHasVal(y)) return 0; /* Unable to round */ - v = y->frac[0]; - nf -= VpExponent(y) * (ssize_t)BASE_FIG; - while ((v /= 10) != 0) nf--; - nf += (ssize_t)BASE_FIG-1; - return VpMidRound(y, f, nf); -} - -VP_EXPORT int -VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf) -{ - /* First,assign whole value in truncation mode */ - if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */ - return VpMidRound(y, f, nf); -} - -static int -VpLimitRound(Real *c, size_t ixDigit) -{ - size_t ix = VpGetPrecLimit(); - if (!VpNmlz(c)) return -1; - if (!ix) return 0; - if (!ixDigit) ixDigit = c->Prec-1; - if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0; - return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix); -} - -/* If I understand correctly, this is only ever used to round off the final decimal - digit of precision */ -static void -VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v) -{ - int f = 0; - - unsigned short const rounding_mode = VpGetRoundMode(); - - if (VpLimitRound(c, ixDigit)) return; - if (!v) return; - - v /= BASE1; - switch (rounding_mode) { - case VP_ROUND_DOWN: - break; - case VP_ROUND_UP: - if (v) f = 1; - break; - case VP_ROUND_HALF_UP: - if (v >= 5) f = 1; - break; - case VP_ROUND_HALF_DOWN: - /* this is ok - because this is the last digit of precision, - the case where v == 5 and some further digits are nonzero - will never occur */ - if (v >= 6) f = 1; - break; - case VP_ROUND_CEIL: - if (v && BIGDECIMAL_POSITIVE_P(c)) f = 1; - break; - case VP_ROUND_FLOOR: - if (v && BIGDECIMAL_NEGATIVE_P(c)) f = 1; - break; - case VP_ROUND_HALF_EVEN: /* Banker's rounding */ - /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision, - there is no case to worry about where v == 5 and some further digits are nonzero */ - if (v > 5) f = 1; - else if (v == 5 && vPrev % 2) f = 1; - break; - } - if (f) { - VpRdup(c, ixDigit); - VpNmlz(c); - } -} - -/* - * Rounds up m(plus one to final digit of m). - */ -static int -VpRdup(Real *m, size_t ind_m) -{ - DECDIG carry; - - if (!ind_m) ind_m = m->Prec; - - carry = 1; - while (carry > 0 && ind_m--) { - m->frac[ind_m] += carry; - if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE; - else carry = 0; - } - if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ - if (!AddExponent(m, 1)) return 0; - m->Prec = m->frac[0] = 1; - } - else { - VpNmlz(m); - } - return 1; -} - -/* - * y = x - fix(x) - */ -VP_EXPORT void -VpFrac(Real *y, Real *x) -{ - size_t my, ind_y, ind_x; - - if (!VpHasVal(x)) { - VpAsgn(y, x, 1); - goto Exit; - } - - if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) { - VpSetZero(y, VpGetSign(x)); - goto Exit; - } - else if (x->exponent <= 0) { - VpAsgn(y, x, 1); - goto Exit; - } - - /* satisfy: x->exponent > 0 */ - - y->Prec = x->Prec - (size_t)x->exponent; - y->Prec = Min(y->Prec, y->MaxPrec); - y->exponent = 0; - VpSetSign(y, VpGetSign(x)); - ind_y = 0; - my = y->Prec; - ind_x = x->exponent; - while (ind_y < my) { - y->frac[ind_y] = x->frac[ind_x]; - ++ind_y; - ++ind_x; - } - VpNmlz(y); - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpFrac y=%\n", y); - VPrint(stdout, " x=%\n", x); - } -#endif /* BIGDECIMAL_DEBUG */ - return; -} - -/* - * y = x ** n - */ -VP_EXPORT int -VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n) -{ - size_t s, ss; - ssize_t sign; - Real *w1 = NULL; - Real *w2 = NULL; - - if (VpIsZero(x)) { - if (n == 0) { - VpSetOne(y); - goto Exit; - } - sign = VpGetSign(x); - if (n < 0) { - n = -n; - if (sign < 0) sign = (n % 2) ? -1 : 1; - VpSetInf(y, sign); - } - else { - if (sign < 0) sign = (n % 2) ? -1 : 1; - VpSetZero(y,sign); - } - goto Exit; - } - if (VpIsNaN(x)) { - VpSetNaN(y); - goto Exit; - } - if (VpIsInf(x)) { - if (n == 0) { - VpSetOne(y); - goto Exit; - } - if (n > 0) { - VpSetInf(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); - goto Exit; - } - VpSetZero(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); - goto Exit; - } - - if (x->exponent == 1 && x->Prec == 1 && x->frac[0] == 1) { - /* abs(x) = 1 */ - VpSetOne(y); - if (BIGDECIMAL_POSITIVE_P(x)) goto Exit; - if ((n % 2) == 0) goto Exit; - VpSetSign(y, -1); - goto Exit; - } - - if (n > 0) sign = 1; - else if (n < 0) { - sign = -1; - n = -n; - } - else { - VpSetOne(y); - goto Exit; - } - - /* Allocate working variables */ - - w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0", 1, 1); - w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0", 1, 1); - /* calculation start */ - - VpAsgn(y, x, 1); - --n; - while (n > 0) { - VpAsgn(w1, x, 1); - s = 1; - while (ss = s, (s += s) <= (size_t)n) { - VpMult(w2, w1, w1); - VpAsgn(w1, w2, 1); - } - n -= (SIGNED_VALUE)ss; - VpMult(w2, y, w1); - VpAsgn(y, w2, 1); - } - if (sign < 0) { - VpDivd(w1, w2, VpConstOne, y); - VpAsgn(y, w1, 1); - } - -Exit: -#ifdef BIGDECIMAL_DEBUG - if (gfDebug) { - VPrint(stdout, "VpPowerByInt y=%\n", y); - VPrint(stdout, "VpPowerByInt x=%\n", x); - printf(" n=%"PRIdVALUE"\n", n); - } -#endif /* BIGDECIMAL_DEBUG */ - VpFree(w2); - VpFree(w1); - return 1; -} - -#ifdef BIGDECIMAL_DEBUG -int -VpVarCheck(Real * v) -/* - * Checks the validity of the Real variable v. - * [Input] - * v ... Real *, variable to be checked. - * [Returns] - * 0 ... correct v. - * other ... error - */ -{ - size_t i; - - if (v->MaxPrec == 0) { - printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", - v->MaxPrec); - return 1; - } - if (v->Prec == 0 || v->Prec > v->MaxPrec) { - printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); - printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); - return 2; - } - for (i = 0; i < v->Prec; ++i) { - if (v->frac[i] >= BASE) { - printf("ERROR(VpVarCheck): Illegal fraction\n"); - printf(" Frac[%"PRIuSIZE"]=%"PRIuDECDIG"\n", i, v->frac[i]); - printf(" Prec. =%"PRIuSIZE"\n", v->Prec); - printf(" Exp. =%"PRIdVALUE"\n", v->exponent); - printf(" BASE =%"PRIuDECDIG"\n", BASE); - return 3; - } - } - return 0; -} -#endif /* BIGDECIMAL_DEBUG */ diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec deleted file mode 100644 index 79009aa19b..0000000000 --- a/ext/bigdecimal/bigdecimal.gemspec +++ /dev/null @@ -1,46 +0,0 @@ -# coding: utf-8 - -bigdecimal_version = '3.0.0' - -Gem::Specification.new do |s| - s.name = "bigdecimal" - s.version = bigdecimal_version - s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"] - s.email = ["mrkn@mrkn.jp"] - - s.summary = "Arbitrary-precision decimal floating-point number library." - s.description = "This library provides arbitrary-precision decimal floating-point number class." - s.homepage = "https://github.com/ruby/bigdecimal" - s.license = "Ruby" - - s.require_paths = %w[lib] - s.extensions = %w[ext/bigdecimal/extconf.rb] - s.files = %w[ - bigdecimal.gemspec - ext/bigdecimal/bigdecimal.c - ext/bigdecimal/bigdecimal.h - ext/bigdecimal/bits.h - ext/bigdecimal/feature.h - ext/bigdecimal/missing.c - ext/bigdecimal/missing.h - ext/bigdecimal/missing/dtoa.c - ext/bigdecimal/static_assert.h - lib/bigdecimal.rb - lib/bigdecimal/jacobian.rb - lib/bigdecimal/ludcmp.rb - lib/bigdecimal/math.rb - lib/bigdecimal/newton.rb - lib/bigdecimal/util.rb - sample/linear.rb - sample/nlsolve.rb - sample/pi.rb - ] - - s.required_ruby_version = Gem::Requirement.new(">= 2.4.0") - - s.add_development_dependency "fiddle" - s.add_development_dependency "rake", ">= 12.3.3" - s.add_development_dependency "rake-compiler", ">= 0.9" - s.add_development_dependency "minitest", "< 5.0.0" - s.add_development_dependency "irb" -end diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h deleted file mode 100644 index bd1c46743e..0000000000 --- a/ext/bigdecimal/bigdecimal.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * - * Ruby BigDecimal(Variable decimal precision) extension library. - * - * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) - * - */ - -#ifndef RUBY_BIG_DECIMAL_H -#define RUBY_BIG_DECIMAL_H 1 - -#define RUBY_NO_OLD_COMPATIBILITY -#include "ruby/ruby.h" -#include "missing.h" - -#ifdef HAVE_FLOAT_H -# include <float.h> -#endif - -#ifdef HAVE_INT64_T -# define DECDIG uint32_t -# define DECDIG_DBL uint64_t -# define DECDIG_DBL_SIGNED int64_t -# define SIZEOF_DECDIG 4 -# define PRI_DECDIG_PREFIX "" -# ifdef PRI_LL_PREFIX -# define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX -# else -# define PRI_DECDIG_DBL_PREFIX "l" -# endif -#else -# define DECDIG uint16_t -# define DECDIG_DBL uint32_t -# define DECDIG_DBL_SIGNED int32_t -# define SIZEOF_DECDIG 2 -# define PRI_DECDIG_PREFIX "h" -# define PRI_DECDIG_DBL_PREFIX "" -#endif - -#define PRIdDECDIG PRI_DECDIG_PREFIX"d" -#define PRIiDECDIG PRI_DECDIG_PREFIX"i" -#define PRIoDECDIG PRI_DECDIG_PREFIX"o" -#define PRIuDECDIG PRI_DECDIG_PREFIX"u" -#define PRIxDECDIG PRI_DECDIG_PREFIX"x" -#define PRIXDECDIG PRI_DECDIG_PREFIX"X" - -#define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d" -#define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i" -#define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o" -#define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u" -#define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x" -#define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X" - -#if SIZEOF_DECDIG == 4 -# define BIGDECIMAL_BASE ((DECDIG)1000000000U) -# define BIGDECIMAL_COMPONENT_FIGURES 9 -/* - * The number of components required for a 64-bit integer. - * - * INT64_MAX: 9_223372036_854775807 - * UINT64_MAX: 18_446744073_709551615 - */ -# define BIGDECIMAL_INT64_MAX_LENGTH 3 - -#elif SIZEOF_DECDIG == 2 -# define BIGDECIMAL_BASE ((DECDIG)10000U) -# define BIGDECIMAL_COMPONENT_FIGURES 4 -/* - * The number of components required for a 64-bit integer. - * - * INT64_MAX: 922_3372_0368_5477_5807 - * UINT64_MAX: 1844_6744_0737_0955_1615 - */ -# define BIGDECIMAL_INT64_MAX_LENGTH 5 - -#else -# error Unknown size of DECDIG -#endif - -#define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG) - -#if defined(__cplusplus) -extern "C" { -#if 0 -} /* satisfy cc-mode */ -#endif -#endif - -extern VALUE rb_cBigDecimal; - -/* - * NaN & Infinity - */ -#define SZ_NaN "NaN" -#define SZ_INF "Infinity" -#define SZ_PINF "+Infinity" -#define SZ_NINF "-Infinity" - -/* - * #define VP_EXPORT other than static to let VP_ routines - * be called from outside of this module. - */ -#define VP_EXPORT static - -/* Exception codes */ -#define VP_EXCEPTION_ALL ((unsigned short)0x00FF) -#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001) -#define VP_EXCEPTION_NaN ((unsigned short)0x0002) -#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004) -#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */ -#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010) - -/* Following 2 exceptions can't controlled by user */ -#define VP_EXCEPTION_OP ((unsigned short)0x0020) - -#define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U - -/* Computation mode */ -#define VP_ROUND_MODE ((unsigned short)0x0100) -#define VP_ROUND_UP 1 -#define VP_ROUND_DOWN 2 -#define VP_ROUND_HALF_UP 3 -#define VP_ROUND_HALF_DOWN 4 -#define VP_ROUND_CEIL 5 -#define VP_ROUND_FLOOR 6 -#define VP_ROUND_HALF_EVEN 7 - -#define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP - -#define VP_SIGN_NaN 0 /* NaN */ -#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */ -#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */ -#define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */ -#define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */ -#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */ -#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */ - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#define FLEXIBLE_ARRAY_SIZE /* */ -#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define FLEXIBLE_ARRAY_SIZE 0 -#else -#define FLEXIBLE_ARRAY_SIZE 1 -#endif - -/* - * VP representation - * r = 0.xxxxxxxxx *BASE**exponent - */ -typedef struct { - VALUE obj; /* Back pointer(VALUE) for Ruby object. */ - size_t MaxPrec; /* Maximum precision size */ - /* This is the actual size of frac[] */ - /*(frac[0] to frac[MaxPrec] are available). */ - size_t Prec; /* Current precision size. */ - /* This indicates how much the */ - /* array frac[] is actually used. */ - SIGNED_VALUE exponent; /* Exponent part. */ - short sign; /* Attributes of the value. */ - /* - * ==0 : NaN - * 1 : Positive zero - * -1 : Negative zero - * 2 : Positive number - * -2 : Negative number - * 3 : Positive infinite number - * -3 : Negative infinite number - */ - short flag; /* Not used in vp_routines,space for user. */ - DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */ -} Real; - -/* - * ------------------ - * EXPORTables. - * ------------------ - */ - -VP_EXPORT Real *VpNewRbClass(size_t mx, char const *str, VALUE klass, bool strict_p, bool raise_exception); - -VP_EXPORT Real *VpCreateRbObject(size_t mx, const char *str, bool raise_exception); - -#define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES -#define VpDblFig() BIGDECIMAL_DOUBLE_FIGURES -#define VpBaseVal() BIGDECIMAL_BASE - -/* Zero,Inf,NaN (isinf(),isnan() used to check) */ -VP_EXPORT double VpGetDoubleNaN(void); -VP_EXPORT double VpGetDoublePosInf(void); -VP_EXPORT double VpGetDoubleNegInf(void); -VP_EXPORT double VpGetDoubleNegZero(void); - -/* These 2 functions added at v1.1.7 */ -VP_EXPORT size_t VpGetPrecLimit(void); -VP_EXPORT size_t VpSetPrecLimit(size_t n); - -/* Round mode */ -VP_EXPORT int VpIsRoundMode(unsigned short n); -VP_EXPORT unsigned short VpGetRoundMode(void); -VP_EXPORT unsigned short VpSetRoundMode(unsigned short n); - -VP_EXPORT int VpException(unsigned short f,const char *str,int always); -#if 0 /* unused */ -VP_EXPORT int VpIsNegDoubleZero(double v); -#endif -VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt); -VP_EXPORT size_t VpInit(DECDIG BaseVal); -VP_EXPORT void *VpMemAlloc(size_t mb); -VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb); -VP_EXPORT void VpFree(Real *pv); -VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p, int exc); -VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw); -VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation); -VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b); -VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b); -VP_EXPORT int VpComp(Real *a,Real *b); -VP_EXPORT ssize_t VpExponent10(Real *a); -VP_EXPORT void VpSzMantissa(Real *a,char *psz); -VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus); -VP_EXPORT void VpToString(Real *a, char *psz, size_t fFmt, int fPlus); -VP_EXPORT void VpToFString(Real *a, char *psz, size_t fFmt, int fPlus); -VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne); -VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m); -VP_EXPORT void VpDtoV(Real *m,double d); -#if 0 /* unused */ -VP_EXPORT void VpItoV(Real *m,S_INT ival); -#endif -VP_EXPORT int VpSqrt(Real *y,Real *x); -VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il); -VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf); -VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf); -VP_EXPORT void VpFrac(Real *y, Real *x); -VP_EXPORT int VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n); -#define VpPower VpPowerByInt - -/* VP constants */ -VP_EXPORT Real *VpOne(void); - -/* - * ------------------ - * MACRO definitions. - * ------------------ - */ -#define Abs(a) (((a)>= 0)?(a):(-(a))) -#define Max(a, b) (((a)>(b))?(a):(b)) -#define Min(a, b) (((a)>(b))?(b):(a)) - -#define VpMaxPrec(a) ((a)->MaxPrec) -#define VpPrec(a) ((a)->Prec) -#define VpGetFlag(a) ((a)->flag) - -/* Sign */ - -/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */ -#define VpGetSign(a) (((a)->sign>0)?1:(-1)) -/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */ -#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);} -/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */ -#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;} - -/* 1 */ -#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;} - -/* ZEROs */ -#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO) -#define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO) -#define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a)) -#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO) -#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO) -#define VpSetZero(a,s) (void)(((s)>0)?VpSetPosZero(a):VpSetNegZero(a)) - -/* NaN */ -#define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN) -#define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN) - -/* Infinity */ -#define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE) -#define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE) -#define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a)) -#define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) ) -#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE) -#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE) -#define VpSetInf(a,s) (void)(((s)>0)?VpSetPosInf(a):VpSetNegInf(a)) -#define VpHasVal(a) (a->frac[0]) -#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1)) -#define VpExponent(a) (a->exponent) -#ifdef BIGDECIMAL_DEBUG -int VpVarCheck(Real * v); -#endif /* BIGDECIMAL_DEBUG */ - -#if defined(__cplusplus) -#if 0 -{ /* satisfy cc-mode */ -#endif -} /* extern "C" { */ -#endif -#endif /* RUBY_BIG_DECIMAL_H */ diff --git a/ext/bigdecimal/bits.h b/ext/bigdecimal/bits.h deleted file mode 100644 index 6e1e4776e3..0000000000 --- a/ext/bigdecimal/bits.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef BIGDECIMAL_BITS_H -#define BIGDECIMAL_BITS_H - -#include "feature.h" -#include "static_assert.h" - -#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) -# include <x86intrin.h> /* for _lzcnt_u64, etc. */ -#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) -# include <intrin.h> /* for the following intrinsics */ -#endif - -#if defined(_MSC_VER) && defined(__AVX2__) -# pragma intrinsic(__lzcnt) -# pragma intrinsic(__lzcnt64) -#endif - -#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0]))) -#define roomof(x, y) (((x) + (y) - 1) / (y)) -#define type_roomof(x, y) roomof(sizeof(x), sizeof(y)) - -#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ - (a) == 0 ? 0 : \ - (a) == -1 ? (b) < -(max) : \ - (a) > 0 ? \ - ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \ - ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b))) - -#ifdef HAVE_UINT128_T -# define bit_length(x) \ - (unsigned int) \ - (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ - sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \ - 128 - nlz_int128((uint128_t)(x))) -#else -# define bit_length(x) \ - (unsigned int) \ - (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ - 64 - nlz_int64((uint64_t)(x))) -#endif - -static inline unsigned nlz_int32(uint32_t x); -static inline unsigned nlz_int64(uint64_t x); -#ifdef HAVE_UINT128_T -static inline unsigned nlz_int128(uint128_t x); -#endif - -static inline unsigned int -nlz_int32(uint32_t x) -{ -#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT) - /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC. - * AMD CPUs have had this instruction for decades (since K10) but for - * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum - * safety. */ - return (unsigned int)__lzcnt(x); - -#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32) - return (unsigned int)_lzcnt_u32(x); - -#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE) - unsigned long r; - return _BitScanReverse(&r, x) ? (31 - (int)r) : 32; - -#elif __has_builtin(__builtin_clz) - STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32); - return x ? (unsigned int)__builtin_clz(x) : 32; - -#else - uint32_t y; - unsigned n = 32; - y = x >> 16; if (y) {n -= 16; x = y;} - y = x >> 8; if (y) {n -= 8; x = y;} - y = x >> 4; if (y) {n -= 4; x = y;} - y = x >> 2; if (y) {n -= 2; x = y;} - y = x >> 1; if (y) {return n - 2;} - return (unsigned int)(n - x); -#endif -} - -static inline unsigned int -nlz_int64(uint64_t x) -{ -#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) - return (unsigned int)__lzcnt64(x); - -#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) - return (unsigned int)_lzcnt_u64(x); - -#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) - unsigned long r; - return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; - -#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc)) - if (x == 0) { - return 64; - } - else if (sizeof(long) * CHAR_BIT == 64) { - return (unsigned int)__builtin_clzl((unsigned long)x); - } - else if (sizeof(long long) * CHAR_BIT == 64) { - return (unsigned int)__builtin_clzll((unsigned long long)x); - } - else { - /* :FIXME: Is there a way to make this branch a compile-time error? */ - __builtin_unreachable(); - } - -#else - uint64_t y; - unsigned int n = 64; - y = x >> 32; if (y) {n -= 32; x = y;} - y = x >> 16; if (y) {n -= 16; x = y;} - y = x >> 8; if (y) {n -= 8; x = y;} - y = x >> 4; if (y) {n -= 4; x = y;} - y = x >> 2; if (y) {n -= 2; x = y;} - y = x >> 1; if (y) {return n - 2;} - return (unsigned int)(n - x); - -#endif -} - -#ifdef HAVE_UINT128_T -static inline unsigned int -nlz_int128(uint128_t x) -{ - uint64_t y = (uint64_t)(x >> 64); - - if (x == 0) { - return 128; - } - else if (y == 0) { - return (unsigned int)nlz_int64(x) + 64; - } - else { - return (unsigned int)nlz_int64(y); - } -} -#endif - -#endif /* BIGDECIMAL_BITS_H */ diff --git a/ext/bigdecimal/depend b/ext/bigdecimal/depend deleted file mode 100644 index d54de7c3c7..0000000000 --- a/ext/bigdecimal/depend +++ /dev/null @@ -1,330 +0,0 @@ -extconf.h: $(srcdir)/$(GEMSPEC) -Makefile: $(BIGDECIMAL_RB) - -# AUTOGENERATED DEPENDENCIES START -bigdecimal.o: $(RUBY_EXTCONF_H) -bigdecimal.o: $(arch_hdrdir)/ruby/config.h -bigdecimal.o: $(hdrdir)/ruby/assert.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/assume.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/attributes.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/bool.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/inttypes.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/limits.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/long_long.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/stdalign.h -bigdecimal.o: $(hdrdir)/ruby/backward/2/stdarg.h -bigdecimal.o: $(hdrdir)/ruby/defines.h -bigdecimal.o: $(hdrdir)/ruby/intern.h -bigdecimal.o: $(hdrdir)/ruby/internal/anyargs.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/char.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/double.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/int.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/long.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/short.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -bigdecimal.o: $(hdrdir)/ruby/internal/assume.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/artificial.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/cold.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/const.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/constexpr.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/deprecated.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/error.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/forceinline.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/format.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/noalias.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/noexcept.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/noinline.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/nonnull.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/noreturn.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/pure.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/restrict.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/warning.h -bigdecimal.o: $(hdrdir)/ruby/internal/attr/weakref.h -bigdecimal.o: $(hdrdir)/ruby/internal/cast.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -bigdecimal.o: $(hdrdir)/ruby/internal/compiler_since.h -bigdecimal.o: $(hdrdir)/ruby/internal/config.h -bigdecimal.o: $(hdrdir)/ruby/internal/constant_p.h -bigdecimal.o: $(hdrdir)/ruby/internal/core.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rarray.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rbasic.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rbignum.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rclass.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rdata.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rfile.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rhash.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/robject.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rregexp.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rstring.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rstruct.h -bigdecimal.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -bigdecimal.o: $(hdrdir)/ruby/internal/ctype.h -bigdecimal.o: $(hdrdir)/ruby/internal/dllexport.h -bigdecimal.o: $(hdrdir)/ruby/internal/dosish.h -bigdecimal.o: $(hdrdir)/ruby/internal/error.h -bigdecimal.o: $(hdrdir)/ruby/internal/eval.h -bigdecimal.o: $(hdrdir)/ruby/internal/event.h -bigdecimal.o: $(hdrdir)/ruby/internal/fl_type.h -bigdecimal.o: $(hdrdir)/ruby/internal/gc.h -bigdecimal.o: $(hdrdir)/ruby/internal/glob.h -bigdecimal.o: $(hdrdir)/ruby/internal/globals.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/attribute.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/builtin.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/c_attribute.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/extension.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/feature.h -bigdecimal.o: $(hdrdir)/ruby/internal/has/warning.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/array.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/bignum.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/class.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/compar.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/complex.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/cont.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/dir.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/enum.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/enumerator.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/error.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/eval.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/file.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/gc.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/hash.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/io.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/load.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/marshal.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/numeric.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/object.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/parse.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/proc.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/process.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/random.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/range.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/rational.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/re.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/ruby.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/select.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/signal.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/sprintf.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/string.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/struct.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/thread.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/time.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/variable.h -bigdecimal.o: $(hdrdir)/ruby/internal/intern/vm.h -bigdecimal.o: $(hdrdir)/ruby/internal/interpreter.h -bigdecimal.o: $(hdrdir)/ruby/internal/iterator.h -bigdecimal.o: $(hdrdir)/ruby/internal/memory.h -bigdecimal.o: $(hdrdir)/ruby/internal/method.h -bigdecimal.o: $(hdrdir)/ruby/internal/module.h -bigdecimal.o: $(hdrdir)/ruby/internal/newobj.h -bigdecimal.o: $(hdrdir)/ruby/internal/rgengc.h -bigdecimal.o: $(hdrdir)/ruby/internal/scan_args.h -bigdecimal.o: $(hdrdir)/ruby/internal/special_consts.h -bigdecimal.o: $(hdrdir)/ruby/internal/static_assert.h -bigdecimal.o: $(hdrdir)/ruby/internal/stdalign.h -bigdecimal.o: $(hdrdir)/ruby/internal/stdbool.h -bigdecimal.o: $(hdrdir)/ruby/internal/symbol.h -bigdecimal.o: $(hdrdir)/ruby/internal/value.h -bigdecimal.o: $(hdrdir)/ruby/internal/value_type.h -bigdecimal.o: $(hdrdir)/ruby/internal/variable.h -bigdecimal.o: $(hdrdir)/ruby/internal/warning_push.h -bigdecimal.o: $(hdrdir)/ruby/internal/xmalloc.h -bigdecimal.o: $(hdrdir)/ruby/missing.h -bigdecimal.o: $(hdrdir)/ruby/ruby.h -bigdecimal.o: $(hdrdir)/ruby/st.h -bigdecimal.o: $(hdrdir)/ruby/subst.h -bigdecimal.o: $(hdrdir)/ruby/util.h -bigdecimal.o: bigdecimal.c -bigdecimal.o: bigdecimal.h -bigdecimal.o: bits.h -bigdecimal.o: feature.h -bigdecimal.o: missing.h -bigdecimal.o: static_assert.h -missing.o: $(RUBY_EXTCONF_H) -missing.o: $(arch_hdrdir)/ruby/config.h -missing.o: $(hdrdir)/ruby/assert.h -missing.o: $(hdrdir)/ruby/atomic.h -missing.o: $(hdrdir)/ruby/backward.h -missing.o: $(hdrdir)/ruby/backward/2/assume.h -missing.o: $(hdrdir)/ruby/backward/2/attributes.h -missing.o: $(hdrdir)/ruby/backward/2/bool.h -missing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -missing.o: $(hdrdir)/ruby/backward/2/inttypes.h -missing.o: $(hdrdir)/ruby/backward/2/limits.h -missing.o: $(hdrdir)/ruby/backward/2/long_long.h -missing.o: $(hdrdir)/ruby/backward/2/stdalign.h -missing.o: $(hdrdir)/ruby/backward/2/stdarg.h -missing.o: $(hdrdir)/ruby/defines.h -missing.o: $(hdrdir)/ruby/intern.h -missing.o: $(hdrdir)/ruby/internal/anyargs.h -missing.o: $(hdrdir)/ruby/internal/arithmetic.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/char.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/double.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/int.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/long.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/short.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -missing.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -missing.o: $(hdrdir)/ruby/internal/assume.h -missing.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -missing.o: $(hdrdir)/ruby/internal/attr/artificial.h -missing.o: $(hdrdir)/ruby/internal/attr/cold.h -missing.o: $(hdrdir)/ruby/internal/attr/const.h -missing.o: $(hdrdir)/ruby/internal/attr/constexpr.h -missing.o: $(hdrdir)/ruby/internal/attr/deprecated.h -missing.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -missing.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -missing.o: $(hdrdir)/ruby/internal/attr/error.h -missing.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -missing.o: $(hdrdir)/ruby/internal/attr/forceinline.h -missing.o: $(hdrdir)/ruby/internal/attr/format.h -missing.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -missing.o: $(hdrdir)/ruby/internal/attr/noalias.h -missing.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -missing.o: $(hdrdir)/ruby/internal/attr/noexcept.h -missing.o: $(hdrdir)/ruby/internal/attr/noinline.h -missing.o: $(hdrdir)/ruby/internal/attr/nonnull.h -missing.o: $(hdrdir)/ruby/internal/attr/noreturn.h -missing.o: $(hdrdir)/ruby/internal/attr/pure.h -missing.o: $(hdrdir)/ruby/internal/attr/restrict.h -missing.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -missing.o: $(hdrdir)/ruby/internal/attr/warning.h -missing.o: $(hdrdir)/ruby/internal/attr/weakref.h -missing.o: $(hdrdir)/ruby/internal/cast.h -missing.o: $(hdrdir)/ruby/internal/compiler_is.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -missing.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -missing.o: $(hdrdir)/ruby/internal/compiler_since.h -missing.o: $(hdrdir)/ruby/internal/config.h -missing.o: $(hdrdir)/ruby/internal/constant_p.h -missing.o: $(hdrdir)/ruby/internal/core.h -missing.o: $(hdrdir)/ruby/internal/core/rarray.h -missing.o: $(hdrdir)/ruby/internal/core/rbasic.h -missing.o: $(hdrdir)/ruby/internal/core/rbignum.h -missing.o: $(hdrdir)/ruby/internal/core/rclass.h -missing.o: $(hdrdir)/ruby/internal/core/rdata.h -missing.o: $(hdrdir)/ruby/internal/core/rfile.h -missing.o: $(hdrdir)/ruby/internal/core/rhash.h -missing.o: $(hdrdir)/ruby/internal/core/robject.h -missing.o: $(hdrdir)/ruby/internal/core/rregexp.h -missing.o: $(hdrdir)/ruby/internal/core/rstring.h -missing.o: $(hdrdir)/ruby/internal/core/rstruct.h -missing.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -missing.o: $(hdrdir)/ruby/internal/ctype.h -missing.o: $(hdrdir)/ruby/internal/dllexport.h -missing.o: $(hdrdir)/ruby/internal/dosish.h -missing.o: $(hdrdir)/ruby/internal/error.h -missing.o: $(hdrdir)/ruby/internal/eval.h -missing.o: $(hdrdir)/ruby/internal/event.h -missing.o: $(hdrdir)/ruby/internal/fl_type.h -missing.o: $(hdrdir)/ruby/internal/gc.h -missing.o: $(hdrdir)/ruby/internal/glob.h -missing.o: $(hdrdir)/ruby/internal/globals.h -missing.o: $(hdrdir)/ruby/internal/has/attribute.h -missing.o: $(hdrdir)/ruby/internal/has/builtin.h -missing.o: $(hdrdir)/ruby/internal/has/c_attribute.h -missing.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -missing.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -missing.o: $(hdrdir)/ruby/internal/has/extension.h -missing.o: $(hdrdir)/ruby/internal/has/feature.h -missing.o: $(hdrdir)/ruby/internal/has/warning.h -missing.o: $(hdrdir)/ruby/internal/intern/array.h -missing.o: $(hdrdir)/ruby/internal/intern/bignum.h -missing.o: $(hdrdir)/ruby/internal/intern/class.h -missing.o: $(hdrdir)/ruby/internal/intern/compar.h -missing.o: $(hdrdir)/ruby/internal/intern/complex.h -missing.o: $(hdrdir)/ruby/internal/intern/cont.h -missing.o: $(hdrdir)/ruby/internal/intern/dir.h -missing.o: $(hdrdir)/ruby/internal/intern/enum.h -missing.o: $(hdrdir)/ruby/internal/intern/enumerator.h -missing.o: $(hdrdir)/ruby/internal/intern/error.h -missing.o: $(hdrdir)/ruby/internal/intern/eval.h -missing.o: $(hdrdir)/ruby/internal/intern/file.h -missing.o: $(hdrdir)/ruby/internal/intern/gc.h -missing.o: $(hdrdir)/ruby/internal/intern/hash.h -missing.o: $(hdrdir)/ruby/internal/intern/io.h -missing.o: $(hdrdir)/ruby/internal/intern/load.h -missing.o: $(hdrdir)/ruby/internal/intern/marshal.h -missing.o: $(hdrdir)/ruby/internal/intern/numeric.h -missing.o: $(hdrdir)/ruby/internal/intern/object.h -missing.o: $(hdrdir)/ruby/internal/intern/parse.h -missing.o: $(hdrdir)/ruby/internal/intern/proc.h -missing.o: $(hdrdir)/ruby/internal/intern/process.h -missing.o: $(hdrdir)/ruby/internal/intern/random.h -missing.o: $(hdrdir)/ruby/internal/intern/range.h -missing.o: $(hdrdir)/ruby/internal/intern/rational.h -missing.o: $(hdrdir)/ruby/internal/intern/re.h -missing.o: $(hdrdir)/ruby/internal/intern/ruby.h -missing.o: $(hdrdir)/ruby/internal/intern/select.h -missing.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -missing.o: $(hdrdir)/ruby/internal/intern/signal.h -missing.o: $(hdrdir)/ruby/internal/intern/sprintf.h -missing.o: $(hdrdir)/ruby/internal/intern/string.h -missing.o: $(hdrdir)/ruby/internal/intern/struct.h -missing.o: $(hdrdir)/ruby/internal/intern/thread.h -missing.o: $(hdrdir)/ruby/internal/intern/time.h -missing.o: $(hdrdir)/ruby/internal/intern/variable.h -missing.o: $(hdrdir)/ruby/internal/intern/vm.h -missing.o: $(hdrdir)/ruby/internal/interpreter.h -missing.o: $(hdrdir)/ruby/internal/iterator.h -missing.o: $(hdrdir)/ruby/internal/memory.h -missing.o: $(hdrdir)/ruby/internal/method.h -missing.o: $(hdrdir)/ruby/internal/module.h -missing.o: $(hdrdir)/ruby/internal/newobj.h -missing.o: $(hdrdir)/ruby/internal/rgengc.h -missing.o: $(hdrdir)/ruby/internal/scan_args.h -missing.o: $(hdrdir)/ruby/internal/special_consts.h -missing.o: $(hdrdir)/ruby/internal/static_assert.h -missing.o: $(hdrdir)/ruby/internal/stdalign.h -missing.o: $(hdrdir)/ruby/internal/stdbool.h -missing.o: $(hdrdir)/ruby/internal/symbol.h -missing.o: $(hdrdir)/ruby/internal/value.h -missing.o: $(hdrdir)/ruby/internal/value_type.h -missing.o: $(hdrdir)/ruby/internal/variable.h -missing.o: $(hdrdir)/ruby/internal/warning_push.h -missing.o: $(hdrdir)/ruby/internal/xmalloc.h -missing.o: $(hdrdir)/ruby/missing.h -missing.o: $(hdrdir)/ruby/ruby.h -missing.o: $(hdrdir)/ruby/st.h -missing.o: $(hdrdir)/ruby/subst.h -missing.o: missing.c -missing.o: missing/dtoa.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/bigdecimal/extconf.rb b/ext/bigdecimal/extconf.rb deleted file mode 100644 index c92aacb3f2..0000000000 --- a/ext/bigdecimal/extconf.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: false -require 'mkmf' - -def check_bigdecimal_version(gemspec_path) - message "checking RUBY_BIGDECIMAL_VERSION... " - - bigdecimal_version = - IO.readlines(gemspec_path) - .grep(/\Abigdecimal_version\s+=\s+/)[0][/\'([^\']+)\'/, 1] - - version_components = bigdecimal_version.split('.') - bigdecimal_version = version_components[0, 3].join('.') - bigdecimal_version << "-#{version_components[3]}" if version_components[3] - $defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"] - - message "#{bigdecimal_version}\n" -end - -def have_builtin_func(name, check_expr, opt = "", &b) - checking_for checking_message(name.funcall_style, nil, opt) do - if try_compile(<<SRC, opt, &b) -int foo; -int main() { #{check_expr}; return 0; } -SRC - $defs.push(format("-DHAVE_BUILTIN_%s", name.tr_cpp)) - true - else - false - end - end -end - -gemspec_name = gemspec_path = nil -unless ['', '../../'].any? {|dir| - gemspec_name = "#{dir}bigdecimal.gemspec" - gemspec_path = File.expand_path("../#{gemspec_name}", __FILE__) - File.file?(gemspec_path) - } - $stderr.puts "Unable to find bigdecimal.gemspec" - abort -end - -check_bigdecimal_version(gemspec_path) - -have_builtin_func("__builtin_clz", "__builtin_clz(0)") -have_builtin_func("__builtin_clzl", "__builtin_clzl(0)") -have_builtin_func("__builtin_clzll", "__builtin_clzll(0)") - -have_header("float.h") -have_header("math.h") -have_header("stdbool.h") -have_header("stdlib.h") - -have_header("x86intrin.h") -have_func("_lzcnt_u32", "x86intrin.h") -have_func("_lzcnt_u64", "x86intrin.h") - -have_header("intrin.h") -have_func("__lzcnt", "intrin.h") -have_func("__lzcnt64", "intrin.h") -have_func("_BitScanReverse", "intrin.h") -have_func("_BitScanReverse64", "intrin.h") - -have_func("labs", "stdlib.h") -have_func("llabs", "stdlib.h") -have_func("finite", "math.h") -have_func("isfinite", "math.h") - -have_header("ruby/atomic.h") -have_header("ruby/internal/has/builtin.h") -have_header("ruby/internal/static_assert.h") - -have_type("struct RRational", "ruby.h") -have_func("rb_rational_num", "ruby.h") -have_func("rb_rational_den", "ruby.h") -have_type("struct RComplex", "ruby.h") -have_func("rb_complex_real", "ruby.h") -have_func("rb_complex_imag", "ruby.h") -have_func("rb_array_const_ptr", "ruby.h") -have_func("rb_sym2str", "ruby.h") -have_func("rb_opts_exception_p", "ruby.h") -have_func("rb_category_warn", "ruby.h") -have_const("RB_WARN_CATEGORY_DEPRECATED", "ruby.h") - -if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__)) - bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb" -else - bigdecimal_rb = "$(srcdir)/../../lib/bigdecimal.rb" -end - -create_makefile('bigdecimal') {|mf| - mf << "GEMSPEC = #{gemspec_name}\n" - mf << "BIGDECIMAL_RB = #{bigdecimal_rb}\n" -} diff --git a/ext/bigdecimal/feature.h b/ext/bigdecimal/feature.h deleted file mode 100644 index f628514500..0000000000 --- a/ext/bigdecimal/feature.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BIGDECIMAL_HAS_FEATURE_H -#define BIGDECIMAL_HAS_FEATURE_H - -/* ======== __has_feature ======== */ - -#ifndef __has_feature -# define __has_feature(_) 0 -#endif - -/* ======== __has_extension ======== */ - -#ifndef __has_extension -# define __has_extension __has_feature -#endif - -/* ======== __has_builtin ======== */ - -#ifdef HAVE_RUBY_INTERNAL_HAS_BUILTIN_H -# include <ruby/internal/has/builtin.h> -#endif - -#ifdef RBIMPL_HAS_BUILTIN -# define BIGDECIMAL_HAS_BUILTIN(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__) - -#else -# /* The following section is copied from CRuby's builtin.h */ -# -# ifdef __has_builtin -# if defined(__INTEL_COMPILER) -# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is -# * reportedly broken. We have to skip them. However the situation can -# * change. They might improve someday. We need to revisit here later. */ -# elif defined(__GNUC__) && ! __has_builtin(__builtin_alloca) -# /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of -# * __has_builtin. Cygwin copied that content to be a victim of the -# * broken-ness. We don't take them into account. */ -# else -# define HAVE___HAS_BUILTIN 1 -# endif -# endif -# -# if defined(HAVE___HAS_BUILTIN) -# define BIGDECIMAL_HAS_BUILTIN(_) __has_builtin(_) -# -# elif defined(__GNUC__) -# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ -# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 6)) -# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 1 -# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 1 -# else -# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 0 -# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 0 -# endif -# elif defined(_MSC_VER) -# define BIGDECIMAL_HAS_BUILTIN(_) 0 -# -# else -# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ -# define BIGDECIMAL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ -# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL -# endif -#endif /* RBIMPL_HAS_BUILTIN */ - -#ifndef __has_builtin -# define __has_builtin(...) BIGDECIMAL_HAS_BUILTIN(__VA_ARGS__) -#endif - -#endif /* BIGDECIMAL_HAS_FEATURE_H */ diff --git a/ext/bigdecimal/lib/bigdecimal.rb b/ext/bigdecimal/lib/bigdecimal.rb deleted file mode 100644 index 8fd2587c84..0000000000 --- a/ext/bigdecimal/lib/bigdecimal.rb +++ /dev/null @@ -1 +0,0 @@ -require 'bigdecimal.so' diff --git a/ext/bigdecimal/lib/bigdecimal/jacobian.rb b/ext/bigdecimal/lib/bigdecimal/jacobian.rb deleted file mode 100644 index 5e29304299..0000000000 --- a/ext/bigdecimal/lib/bigdecimal/jacobian.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: false - -require 'bigdecimal' - -# require 'bigdecimal/jacobian' -# -# Provides methods to compute the Jacobian matrix of a set of equations at a -# point x. In the methods below: -# -# f is an Object which is used to compute the Jacobian matrix of the equations. -# It must provide the following methods: -# -# f.values(x):: returns the values of all functions at x -# -# f.zero:: returns 0.0 -# f.one:: returns 1.0 -# f.two:: returns 2.0 -# f.ten:: returns 10.0 -# -# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. -# -# x is the point at which to compute the Jacobian. -# -# fx is f.values(x). -# -module Jacobian - module_function - - # Determines the equality of two numbers by comparing to zero, or using the epsilon value - def isEqual(a,b,zero=0.0,e=1.0e-8) - aa = a.abs - bb = b.abs - if aa == zero && bb == zero then - true - else - if ((a-b)/(aa+bb)).abs < e then - true - else - false - end - end - end - - - # Computes the derivative of f[i] at x[i]. - # fx is the value of f at x. - def dfdxi(f,fx,x,i) - nRetry = 0 - n = x.size - xSave = x[i] - ok = 0 - ratio = f.ten*f.ten*f.ten - dx = x[i].abs/ratio - dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) - dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) - until ok>0 do - deriv = [] - nRetry += 1 - if nRetry > 100 - raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]" - end - dx = dx*f.two - x[i] += dx - fxNew = f.values(x) - for j in 0...n do - if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then - ok += 1 - deriv <<= (fxNew[j]-fx[j])/dx - else - deriv <<= f.zero - end - end - x[i] = xSave - end - deriv - end - - # Computes the Jacobian of f at x. fx is the value of f at x. - def jacobian(f,fx,x) - n = x.size - dfdx = Array.new(n*n) - for i in 0...n do - df = dfdxi(f,fx,x,i) - for j in 0...n do - dfdx[j*n+i] = df[j] - end - end - dfdx - end -end diff --git a/ext/bigdecimal/lib/bigdecimal/ludcmp.rb b/ext/bigdecimal/lib/bigdecimal/ludcmp.rb deleted file mode 100644 index dd265e482a..0000000000 --- a/ext/bigdecimal/lib/bigdecimal/ludcmp.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: false -require 'bigdecimal' - -# -# Solves a*x = b for x, using LU decomposition. -# -module LUSolve - module_function - - # Performs LU decomposition of the n by n matrix a. - def ludecomp(a,n,zero=0,one=1) - prec = BigDecimal.limit(nil) - ps = [] - scales = [] - for i in 0...n do # pick up largest(abs. val.) element in each row. - ps <<= i - nrmrow = zero - ixn = i*n - for j in 0...n do - biggst = a[ixn+j].abs - nrmrow = biggst if biggst>nrmrow - end - if nrmrow>zero then - scales <<= one.div(nrmrow,prec) - else - raise "Singular matrix" - end - end - n1 = n - 1 - for k in 0...n1 do # Gaussian elimination with partial pivoting. - biggst = zero; - for i in k...n do - size = a[ps[i]*n+k].abs*scales[ps[i]] - if size>biggst then - biggst = size - pividx = i - end - end - raise "Singular matrix" if biggst<=zero - if pividx!=k then - j = ps[k] - ps[k] = ps[pividx] - ps[pividx] = j - end - pivot = a[ps[k]*n+k] - for i in (k+1)...n do - psin = ps[i]*n - a[psin+k] = mult = a[psin+k].div(pivot,prec) - if mult!=zero then - pskn = ps[k]*n - for j in (k+1)...n do - a[psin+j] -= mult.mult(a[pskn+j],prec) - end - end - end - end - raise "Singular matrix" if a[ps[n1]*n+n1] == zero - ps - end - - # Solves a*x = b for x, using LU decomposition. - # - # a is a matrix, b is a constant vector, x is the solution vector. - # - # ps is the pivot, a vector which indicates the permutation of rows performed - # during LU decomposition. - def lusolve(a,b,ps,zero=0.0) - prec = BigDecimal.limit(nil) - n = ps.size - x = [] - for i in 0...n do - dot = zero - psin = ps[i]*n - for j in 0...i do - dot = a[psin+j].mult(x[j],prec) + dot - end - x <<= b[ps[i]] - dot - end - (n-1).downto(0) do |i| - dot = zero - psin = ps[i]*n - for j in (i+1)...n do - dot = a[psin+j].mult(x[j],prec) + dot - end - x[i] = (x[i]-dot).div(a[psin+i],prec) - end - x - end -end diff --git a/ext/bigdecimal/lib/bigdecimal/math.rb b/ext/bigdecimal/lib/bigdecimal/math.rb deleted file mode 100644 index 0b9d0648bb..0000000000 --- a/ext/bigdecimal/lib/bigdecimal/math.rb +++ /dev/null @@ -1,232 +0,0 @@ -# frozen_string_literal: false -require 'bigdecimal' - -# -#-- -# Contents: -# sqrt(x, prec) -# sin (x, prec) -# cos (x, prec) -# atan(x, prec) Note: |x|<1, x=0.9999 may not converge. -# PI (prec) -# E (prec) == exp(1.0,prec) -# -# where: -# x ... BigDecimal number to be computed. -# |x| must be small enough to get convergence. -# prec ... Number of digits to be obtained. -#++ -# -# Provides mathematical functions. -# -# Example: -# -# require "bigdecimal/math" -# -# include BigMath -# -# a = BigDecimal((PI(100)/2).to_s) -# puts sin(a,100) # => 0.99999999999999999999......e0 -# -module BigMath - module_function - - # call-seq: - # sqrt(decimal, numeric) -> BigDecimal - # - # Computes the square root of +decimal+ to the specified number of digits of - # precision, +numeric+. - # - # BigMath.sqrt(BigDecimal('2'), 16).to_s - # #=> "0.1414213562373095048801688724e1" - # - def sqrt(x, prec) - x.sqrt(prec) - end - - # call-seq: - # sin(decimal, numeric) -> BigDecimal - # - # Computes the sine of +decimal+ to the specified number of digits of - # precision, +numeric+. - # - # If +decimal+ is Infinity or NaN, returns NaN. - # - # BigMath.sin(BigMath.PI(5)/4, 5).to_s - # #=> "0.70710678118654752440082036563292800375e0" - # - def sin(x, prec) - raise ArgumentError, "Zero or negative precision for sin" if prec <= 0 - return BigDecimal("NaN") if x.infinite? || x.nan? - n = prec + BigDecimal.double_fig - one = BigDecimal("1") - two = BigDecimal("2") - x = -x if neg = x < 0 - if x > (twopi = two * BigMath.PI(prec)) - if x > 30 - x %= twopi - else - x -= twopi while x > twopi - end - end - x1 = x - x2 = x.mult(x,n) - sign = 1 - y = x - d = y - i = one - z = one - while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) - m = BigDecimal.double_fig if m < BigDecimal.double_fig - sign = -sign - x1 = x2.mult(x1,n) - i += two - z *= (i-one) * i - d = sign * x1.div(z,m) - y += d - end - neg ? -y : y - end - - # call-seq: - # cos(decimal, numeric) -> BigDecimal - # - # Computes the cosine of +decimal+ to the specified number of digits of - # precision, +numeric+. - # - # If +decimal+ is Infinity or NaN, returns NaN. - # - # BigMath.cos(BigMath.PI(4), 16).to_s - # #=> "-0.999999999999999999999999999999856613163740061349e0" - # - def cos(x, prec) - raise ArgumentError, "Zero or negative precision for cos" if prec <= 0 - return BigDecimal("NaN") if x.infinite? || x.nan? - n = prec + BigDecimal.double_fig - one = BigDecimal("1") - two = BigDecimal("2") - x = -x if x < 0 - if x > (twopi = two * BigMath.PI(prec)) - if x > 30 - x %= twopi - else - x -= twopi while x > twopi - end - end - x1 = one - x2 = x.mult(x,n) - sign = 1 - y = one - d = y - i = BigDecimal("0") - z = one - while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) - m = BigDecimal.double_fig if m < BigDecimal.double_fig - sign = -sign - x1 = x2.mult(x1,n) - i += two - z *= (i-one) * i - d = sign * x1.div(z,m) - y += d - end - y - end - - # call-seq: - # atan(decimal, numeric) -> BigDecimal - # - # Computes the arctangent of +decimal+ to the specified number of digits of - # precision, +numeric+. - # - # If +decimal+ is NaN, returns NaN. - # - # BigMath.atan(BigDecimal('-1'), 16).to_s - # #=> "-0.785398163397448309615660845819878471907514682065e0" - # - def atan(x, prec) - raise ArgumentError, "Zero or negative precision for atan" if prec <= 0 - return BigDecimal("NaN") if x.nan? - pi = PI(prec) - x = -x if neg = x < 0 - return pi.div(neg ? -2 : 2, prec) if x.infinite? - return pi / (neg ? -4 : 4) if x.round(prec) == 1 - x = BigDecimal("1").div(x, prec) if inv = x > 1 - x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5 - n = prec + BigDecimal.double_fig - y = x - d = y - t = x - r = BigDecimal("3") - x2 = x.mult(x,n) - while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) - m = BigDecimal.double_fig if m < BigDecimal.double_fig - t = -t.mult(x2,n) - d = t.div(r,m) - y += d - r += 2 - end - y *= 2 if dbl - y = pi / 2 - y if inv - y = -y if neg - y - end - - # call-seq: - # PI(numeric) -> BigDecimal - # - # Computes the value of pi to the specified number of digits of precision, - # +numeric+. - # - # BigMath.PI(10).to_s - # #=> "0.3141592653589793238462643388813853786957412e1" - # - def PI(prec) - raise ArgumentError, "Zero or negative precision for PI" if prec <= 0 - n = prec + BigDecimal.double_fig - zero = BigDecimal("0") - one = BigDecimal("1") - two = BigDecimal("2") - - m25 = BigDecimal("-0.04") - m57121 = BigDecimal("-57121") - - pi = zero - - d = one - k = one - t = BigDecimal("-80") - while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) - m = BigDecimal.double_fig if m < BigDecimal.double_fig - t = t*m25 - d = t.div(k,m) - k = k+two - pi = pi + d - end - - d = one - k = one - t = BigDecimal("956") - while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) - m = BigDecimal.double_fig if m < BigDecimal.double_fig - t = t.div(m57121,n) - d = t.div(k,m) - pi = pi + d - k = k+two - end - pi - end - - # call-seq: - # E(numeric) -> BigDecimal - # - # Computes e (the base of natural logarithms) to the specified number of - # digits of precision, +numeric+. - # - # BigMath.E(10).to_s - # #=> "0.271828182845904523536028752390026306410273e1" - # - def E(prec) - raise ArgumentError, "Zero or negative precision for E" if prec <= 0 - BigMath.exp(1, prec) - end -end diff --git a/ext/bigdecimal/lib/bigdecimal/newton.rb b/ext/bigdecimal/lib/bigdecimal/newton.rb deleted file mode 100644 index 85bacb7f2e..0000000000 --- a/ext/bigdecimal/lib/bigdecimal/newton.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: false -require "bigdecimal/ludcmp" -require "bigdecimal/jacobian" - -# -# newton.rb -# -# Solves the nonlinear algebraic equation system f = 0 by Newton's method. -# This program is not dependent on BigDecimal. -# -# To call: -# n = nlsolve(f,x) -# where n is the number of iterations required, -# x is the initial value vector -# f is an Object which is used to compute the values of the equations to be solved. -# It must provide the following methods: -# -# f.values(x):: returns the values of all functions at x -# -# f.zero:: returns 0.0 -# f.one:: returns 1.0 -# f.two:: returns 2.0 -# f.ten:: returns 10.0 -# -# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. -# -# On exit, x is the solution vector. -# -module Newton - include LUSolve - include Jacobian - module_function - - def norm(fv,zero=0.0) # :nodoc: - s = zero - n = fv.size - for i in 0...n do - s += fv[i]*fv[i] - end - s - end - - # See also Newton - def nlsolve(f,x) - nRetry = 0 - n = x.size - - f0 = f.values(x) - zero = f.zero - one = f.one - two = f.two - p5 = one/two - d = norm(f0,zero) - minfact = f.ten*f.ten*f.ten - minfact = one/minfact - e = f.eps - while d >= e do - nRetry += 1 - # Not yet converged. => Compute Jacobian matrix - dfdx = jacobian(f,f0,x) - # Solve dfdx*dx = -f0 to estimate dx - dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) - fact = two - xs = x.dup - begin - fact *= p5 - if fact < minfact then - raise "Failed to reduce function values." - end - for i in 0...n do - x[i] = xs[i] - dx[i]*fact - end - f0 = f.values(x) - dn = norm(f0,zero) - end while(dn>=d) - d = dn - end - nRetry - end -end diff --git a/ext/bigdecimal/lib/bigdecimal/util.rb b/ext/bigdecimal/lib/bigdecimal/util.rb deleted file mode 100644 index cb645d2a71..0000000000 --- a/ext/bigdecimal/lib/bigdecimal/util.rb +++ /dev/null @@ -1,181 +0,0 @@ -# frozen_string_literal: false -# -#-- -# bigdecimal/util extends various native classes to provide the #to_d method, -# and provides BigDecimal#to_d and BigDecimal#to_digits. -#++ - -require 'bigdecimal' - -class Integer < Numeric - # call-seq: - # int.to_d -> bigdecimal - # - # Returns the value of +int+ as a BigDecimal. - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # 42.to_d # => 0.42e2 - # - # See also BigDecimal::new. - # - def to_d - BigDecimal(self) - end -end - - -class Float < Numeric - # call-seq: - # float.to_d -> bigdecimal - # float.to_d(precision) -> bigdecimal - # - # Returns the value of +float+ as a BigDecimal. - # The +precision+ parameter is used to determine the number of - # significant digits for the result (the default is Float::DIG). - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # 0.5.to_d # => 0.5e0 - # 1.234.to_d(2) # => 0.12e1 - # - # See also BigDecimal::new. - # - def to_d(precision=0) - BigDecimal(self, precision) - end -end - - -class String - # call-seq: - # str.to_d -> bigdecimal - # - # Returns the result of interpreting leading characters in +str+ - # as a BigDecimal. - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # "0.5".to_d # => 0.5e0 - # "123.45e1".to_d # => 0.12345e4 - # "45.67 degrees".to_d # => 0.4567e2 - # - # See also BigDecimal::new. - # - def to_d - BigDecimal.interpret_loosely(self) - end -end - - -class BigDecimal < Numeric - # call-seq: - # a.to_digits -> string - # - # Converts a BigDecimal to a String of the form "nnnnnn.mmm". - # This method is deprecated; use BigDecimal#to_s("F") instead. - # - # require 'bigdecimal/util' - # - # d = BigDecimal("3.14") - # d.to_digits # => "3.14" - # - def to_digits - if self.nan? || self.infinite? || self.zero? - self.to_s - else - i = self.to_i.to_s - _,f,_,z = self.frac.split - i + "." + ("0"*(-z)) + f - end - end - - # call-seq: - # a.to_d -> bigdecimal - # - # Returns self. - # - # require 'bigdecimal/util' - # - # d = BigDecimal("3.14") - # d.to_d # => 0.314e1 - # - def to_d - self - end -end - - -class Rational < Numeric - # call-seq: - # rat.to_d(precision) -> bigdecimal - # - # Returns the value as a BigDecimal. - # - # The required +precision+ parameter is used to determine the number of - # significant digits for the result. - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # Rational(22, 7).to_d(3) # => 0.314e1 - # - # See also BigDecimal::new. - # - def to_d(precision) - BigDecimal(self, precision) - end -end - - -class Complex < Numeric - # call-seq: - # cmp.to_d -> bigdecimal - # cmp.to_d(precision) -> bigdecimal - # - # Returns the value as a BigDecimal. - # - # The +precision+ parameter is required for a rational complex number. - # This parameter is used to determine the number of significant digits - # for the result. - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 - # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 - # - # See also BigDecimal::new. - # - def to_d(*args) - BigDecimal(self) unless self.imag.zero? # to raise eerror - - if args.length == 0 - case self.real - when Rational - BigDecimal(self.real) # to raise error - end - end - self.real.to_d(*args) - end -end - - -class NilClass - # call-seq: - # nil.to_d -> bigdecimal - # - # Returns nil represented as a BigDecimal. - # - # require 'bigdecimal' - # require 'bigdecimal/util' - # - # nil.to_d # => 0.0 - # - def to_d - BigDecimal(0) - end -end diff --git a/ext/bigdecimal/missing.c b/ext/bigdecimal/missing.c deleted file mode 100644 index 703232d92f..0000000000 --- a/ext/bigdecimal/missing.c +++ /dev/null @@ -1,27 +0,0 @@ -#include <ruby/ruby.h> - -#ifdef HAVE_RUBY_ATOMIC_H -# include <ruby/atomic.h> -#endif - -#ifdef RUBY_ATOMIC_PTR_CAS -# define ATOMIC_PTR_CAS(var, old, new) RUBY_ATOMIC_PTR_CAS(var, old, new) -#endif - -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -/* GCC warns about unknown sanitizer, which is annoying. */ -# undef NO_SANITIZE -# define NO_SANITIZE(x, y) \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ - __attribute__((__no_sanitize__(x))) y; \ - _Pragma("GCC diagnostic pop") -#endif - -#undef strtod -#define strtod BigDecimal_strtod -#undef dtoa -#define dtoa BigDecimal_dtoa -#undef hdtoa -#define hdtoa BigDecimal_hdtoa -#include "missing/dtoa.c" diff --git a/ext/bigdecimal/missing.h b/ext/bigdecimal/missing.h deleted file mode 100644 index 7969849158..0000000000 --- a/ext/bigdecimal/missing.h +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef MISSING_H -#define MISSING_H 1 - -#if defined(__cplusplus) -extern "C" { -#if 0 -} /* satisfy cc-mode */ -#endif -#endif - -#ifdef HAVE_STDLIB_H -# include <stdlib.h> -#endif - -#ifdef HAVE_MATH_H -# include <math.h> -#endif - -#ifndef RB_UNUSED_VAR -# if defined(_MSC_VER) && _MSC_VER >= 1911 -# define RB_UNUSED_VAR(x) x [[maybe_unused]] - -# elif defined(__has_cpp_attribute) && __has_cpp_attribute(maybe_unused) -# define RB_UNUSED_VAR(x) x [[maybe_unused]] - -# elif defined(__has_c_attribute) && __has_c_attribute(maybe_unused) -# define RB_UNUSED_VAR(x) x [[maybe_unused]] - -# elif defined(__GNUC__) -# define RB_UNUSED_VAR(x) x __attribute__ ((unused)) - -# else -# define RB_UNUSED_VAR(x) x -# endif -#endif /* RB_UNUSED_VAR */ - -#if defined(_MSC_VER) && _MSC_VER >= 1310 -# define HAVE___ASSUME - -#elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300 -# define HAVE___ASSUME -#endif - -#ifndef UNREACHABLE -# if __has_builtin(__builtin_unreachable) -# define UNREACHABLE __builtin_unreachable() - -# elif defined(HAVE___ASSUME) -# define UNREACHABLE __assume(0) - -# else -# define UNREACHABLE /* unreachable */ -# endif -#endif /* UNREACHABLE */ - -/* bool */ - -#if defined(__bool_true_false_are_defined) -# /* Take that. */ - -#elif defined(HAVE_STDBOOL_H) -# include <stdbool.h> - -#else -typedef unsigned char _Bool; -# define bool _Bool -# define true ((_Bool)+1) -# define false ((_Bool)-1) -# define __bool_true_false_are_defined -#endif - -/* abs */ - -#ifndef HAVE_LABS -static inline long -labs(long const x) -{ - if (x < 0) return -x; - return x; -} -#endif - -#ifndef HAVE_LLABS -static inline LONG_LONG -llabs(LONG_LONG const x) -{ - if (x < 0) return -x; - return x; -} -#endif - -#ifdef vabs -# undef vabs -#endif -#if SIZEOF_VALUE <= SIZEOF_INT -# define vabs abs -#elif SIZEOF_VALUE <= SIZEOF_LONG -# define vabs labs -#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG -# define vabs llabs -#endif - -/* finite */ - -#ifndef HAVE_FINITE -static int -finite(double) -{ - return !isnan(n) && !isinf(n); -} -#endif - -#ifndef isfinite -# ifndef HAVE_ISFINITE -# define HAVE_ISFINITE 1 -# define isfinite(x) finite(x) -# endif -#endif - -/* dtoa */ -char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve); - -/* rational */ - -#ifndef HAVE_RB_RATIONAL_NUM -static inline VALUE -rb_rational_num(VALUE rat) -{ -#ifdef HAVE_TYPE_STRUCT_RRATIONAL - return RRATIONAL(rat)->num; -#else - return rb_funcall(rat, rb_intern("numerator"), 0); -#endif -} -#endif - -#ifndef HAVE_RB_RATIONAL_DEN -static inline VALUE -rb_rational_den(VALUE rat) -{ -#ifdef HAVE_TYPE_STRUCT_RRATIONAL - return RRATIONAL(rat)->den; -#else - return rb_funcall(rat, rb_intern("denominator"), 0); -#endif -} -#endif - -/* complex */ - -#ifndef HAVE_RB_COMPLEX_REAL -static inline VALUE -rb_complex_real(VALUE cmp) -{ -#ifdef HAVE_TYPE_STRUCT_RCOMPLEX - return RCOMPLEX(cmp)->real; -#else - return rb_funcall(cmp, rb_intern("real"), 0); -#endif -} -#endif - -#ifndef HAVE_RB_COMPLEX_IMAG -static inline VALUE -rb_complex_imag(VALUE cmp) -{ -# ifdef HAVE_TYPE_STRUCT_RCOMPLEX - return RCOMPLEX(cmp)->imag; -# else - return rb_funcall(cmp, rb_intern("imag"), 0); -# endif -} -#endif - -/* array */ - -#ifndef FIX_CONST_VALUE_PTR -# if defined(__fcc__) || defined(__fcc_version) || \ - defined(__FCC__) || defined(__FCC_VERSION) -/* workaround for old version of Fujitsu C Compiler (fcc) */ -# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x)) -# else -# define FIX_CONST_VALUE_PTR(x) (x) -# endif -#endif - -#ifndef HAVE_RB_ARRAY_CONST_PTR -static inline const VALUE * -rb_array_const_ptr(VALUE a) -{ - return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ? - RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr); -} -#endif - -#ifndef RARRAY_CONST_PTR -# define RARRAY_CONST_PTR(a) rb_array_const_ptr(a) -#endif - -#ifndef RARRAY_AREF -# define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i]) -#endif - -/* symbol */ - -#ifndef HAVE_RB_SYM2STR -static inline VALUE -rb_sym2str(VALUE sym) -{ - return rb_id2str(SYM2ID(sym)); -} -#endif - -/* st */ - -#ifndef ST2FIX -# undef RB_ST2FIX -# define RB_ST2FIX(h) LONG2FIX((long)(h)) -# define ST2FIX(h) RB_ST2FIX(h) -#endif - -/* warning */ - -#if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED) -# define rb_category_warn(category, ...) rb_warn(__VA_ARGS__) -#endif - -#if defined(__cplusplus) -#if 0 -{ /* satisfy cc-mode */ -#endif -} /* extern "C" { */ -#endif - -#endif /* MISSING_H */ diff --git a/ext/bigdecimal/missing/dtoa.c b/ext/bigdecimal/missing/dtoa.c deleted file mode 100644 index 41b0a221d1..0000000000 --- a/ext/bigdecimal/missing/dtoa.c +++ /dev/null @@ -1,3462 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). On some systems (e.g., - * some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define YES_ALIAS to permit aliasing certain double values with - * arrays of ULongs. This leads to slightly better code with - * some compilers and was always used prior to 19990916, but it - * is not strictly legal and can cause trouble with aggressively - * optimizing compilers (e.g., gcc 2.95.1 under -O2). - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - */ - -#ifdef WORDS_BIGENDIAN -#define IEEE_BIG_ENDIAN -#else -#define IEEE_LITTLE_ENDIAN -#endif - -#ifdef __vax__ -#define VAX -#undef IEEE_BIG_ENDIAN -#undef IEEE_LITTLE_ENDIAN -#endif - -#if defined(__arm__) && !defined(__VFP_FP__) -#define IEEE_BIG_ENDIAN -#undef IEEE_LITTLE_ENDIAN -#endif - -#undef Long -#undef ULong - -#include <limits.h> - -#if (INT_MAX >> 30) && !(INT_MAX >> 31) -#define Long int -#define ULong unsigned int -#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31) -#define Long long int -#define ULong unsigned long int -#else -#error No 32bit integer -#endif - -#if HAVE_LONG_LONG -#define Llong LONG_LONG -#else -#define NO_LONG_LONG -#endif - -#ifdef DEBUG -#include <stdio.h> -#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);} -#endif - -#ifndef ISDIGIT -#include <ctype.h> -#define ISDIGIT(c) isdigit(c) -#endif -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#ifdef USE_LOCALE -#include <locale.h> -#endif - -#ifdef MALLOC -extern void *MALLOC(size_t); -#else -#define MALLOC xmalloc -#endif -#ifdef FREE -extern void FREE(void*); -#else -#define FREE xfree -#endif -#ifndef NO_SANITIZE -#define NO_SANITIZE(x, y) y -#endif - -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#undef IEEE_Arith -#undef Avoid_Underflow -#ifdef IEEE_BIG_ENDIAN -#define IEEE_Arith -#endif -#ifdef IEEE_LITTLE_ENDIAN -#define IEEE_Arith -#endif - -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ -#include <float.h> -#endif /* Bad_float_h */ - -#include <math.h> - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* satisfy cc-mode */ -#endif -#endif - -#ifndef hexdigit -static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; -#endif - -#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1 -Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined. -#endif - -typedef union { double d; ULong L[2]; } U; - -#ifdef YES_ALIAS -typedef double double_u; -# define dval(x) (x) -# ifdef IEEE_LITTLE_ENDIAN -# define word0(x) (((ULong *)&(x))[1]) -# define word1(x) (((ULong *)&(x))[0]) -# else -# define word0(x) (((ULong *)&(x))[0]) -# define word1(x) (((ULong *)&(x))[1]) -# endif -#else -typedef U double_u; -# ifdef IEEE_LITTLE_ENDIAN -# define word0(x) ((x).L[1]) -# define word1(x) ((x).L[0]) -# else -# define word0(x) ((x).L[0]) -# define word1(x) ((x).L[1]) -# endif -# define dval(x) ((x).d) -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) -#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \ -((unsigned short *)(a))[0] = (unsigned short)(c), (a)++) -#else -#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \ -((unsigned short *)(a))[1] = (unsigned short)(c), (a)++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#ifdef IEEE_Arith -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#ifndef NO_IEEE_Scale -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif -#endif - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#ifdef Honor_FLT_ROUNDS -#define Rounding rounding -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else -#define Rounding Flt_Rounds -#endif - -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) ((a) = rnd_prod((a), (b))) -#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b))) -extern double rnd_prod(double, double), rnd_quot(double, double); -#else -#define rounded_product(a,b) ((a) *= (b)) -#define rounded_quotient(a,b) ((a) /= (b)) -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Pack_32 -#define Pack_32 -#endif - -#define FFFFFFFF 0xffffffffUL - -#ifdef NO_LONG_LONG -#undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - -#define MULTIPLE_THREADS 1 - -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#else -#define ACQUIRE_DTOA_LOCK(n) /*unused right now*/ -#define FREE_DTOA_LOCK(n) /*unused right now*/ -#endif - -#ifndef ATOMIC_PTR_CAS -#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old)) -#endif -#ifndef LIKELY -#define LIKELY(x) (x) -#endif -#ifndef UNLIKELY -#define UNLIKELY(x) (x) -#endif -#ifndef ASSUME -#define ASSUME(x) (void)(x) -#endif - -#define Kmax 15 - -struct Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - -typedef struct Bigint Bigint; - -static Bigint *freelist[Kmax+1]; - -static Bigint * -Balloc(int k) -{ - int x; - Bigint *rv; -#ifndef Omit_Private_Memory - size_t len; -#endif - - rv = 0; - ACQUIRE_DTOA_LOCK(0); - if (k <= Kmax) { - rv = freelist[k]; - while (rv) { - Bigint *rvn = rv; - rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next); - if (LIKELY(rvn == rv)) { - ASSUME(rv); - break; - } - } - } - if (!rv) { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax) { - double *pnext = pmem_next; - while (pnext - private_mem + len <= PRIVATE_mem) { - double *p = pnext; - pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len); - if (LIKELY(p == pnext)) { - rv = (Bigint*)pnext; - ASSUME(rv); - break; - } - } - } - if (!rv) - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; -} - -static void -Bfree(Bigint *v) -{ - Bigint *vn; - if (v) { - if (v->k > Kmax) { - FREE(v); - return; - } - ACQUIRE_DTOA_LOCK(0); - do { - vn = v->next = freelist[v->k]; - } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn)); - FREE_DTOA_LOCK(0); - } -} - -#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \ -(y)->wds*sizeof(Long) + 2*sizeof(int)) - -static Bigint * -multadd(Bigint *b, int m, int a) /* multiply by m and add a */ -{ - int i, wds; - ULong *x; -#ifdef ULLong - ULLong carry, y; -#else - ULong carry, y; -#ifdef Pack_32 - ULong xi, z; -#endif -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { -#ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = (ULong)(y & FFFFFFFF); -#else -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } while (++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = (ULong)carry; - b->wds = wds; - } - return b; -} - -static Bigint * -s2b(const char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for (k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do { - b = multadd(b, 10, *s++ - '0'); - } while (++i < nd0); - s++; - } - else - s += 10; - for (; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; -} - -static int -hi0bits(register ULong x) -{ - register int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -} - -static int -lo0bits(ULong *y) -{ - register int k; - register ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; -} - -static Bigint * -i2b(int i) -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; -} - -static Bigint * -mult(Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; -#ifdef ULLong - ULLong carry, z; -#else - ULong carry, z; -#ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for (x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef ULLong - for (; xb < xbe; xc0++) { - if ((y = *xb++) != 0) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = (ULong)(z & FFFFFFFF); - } while (x < xae); - *xc = (ULong)carry; - } - } -#else -#ifdef Pack_32 - for (; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff) != 0) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } while (x < xae); - *xc = (ULong)carry; - } - if ((y = *xb >> 16) != 0) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } while (x < xae); - *xc = z2; - } - } -#else - for (; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } while (x < xae); - *xc = (ULong)carry; - } - } -#endif -#endif - for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; -} - -static Bigint *p5s; - -static Bigint * -pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - Bigint *p5tmp; - int i; - static const int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3) != 0) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = i2b(625); - p5->next = 0; - p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5); - if (UNLIKELY(p5tmp)) { - Bfree(p5); - p5 = p5tmp; - } - } - FREE_DTOA_LOCK(1); - } - for (;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = mult(p5,p5); - p51->next = 0; - p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51); - if (UNLIKELY(p5tmp)) { - Bfree(p51); - p51 = p5tmp; - } - } - FREE_DTOA_LOCK(1); - } - p5 = p51; - } - return b; -} - -static Bigint * -lshift(Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for (i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for (i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } while (x < xe); - if ((*x1 = z) != 0) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } while (x < xe); - if (*x1 = z) - ++n1; - } -#endif - else - do { - *x1++ = *x++; - } while (x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; -} - -static int -cmp(Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for (;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; -} - -NO_SANITIZE("unsigned-integer-overflow", static Bigint * diff(Bigint *a, Bigint *b)); -static Bigint * -diff(Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef ULLong - ULLong borrow, y; -#else - ULong borrow, y; -#ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)(y & FFFFFFFF); - } while (xb < xbe); - while (xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)(y & FFFFFFFF); - } -#else -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } while (xb < xbe); - while (xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } while (xb < xbe); - while (xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while (!*--xc) - wa--; - c->wds = wa; - return c; -} - -static double -ulp(double x_) -{ - register Long L; - double_u x, a; - dval(x) = x_; - - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - word0(a) = L; - word1(a) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; - } - else { - word0(a) = 0; - L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(a); -} - -static double -b2d(Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - double_u d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif -ret_d: -#ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return dval(d); -} - -static Bigint * -d2b(double d_, int *e, int *bits) -{ - double_u d; - Bigint *b; - int de, k; - ULong *x, y, z; -#ifndef Sudden_Underflow - int i; -#endif -#ifdef VAX - ULong d0, d1; -#endif - dval(d) = d_; -#ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if ((de = (int)(d0 >> Exp_shift)) != 0) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if ((y = d1) != 0) { - if ((k = lo0bits(&y)) != 0) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; -#ifndef Sudden_Underflow - i = -#endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; -#ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while (!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; -} -#undef d0 -#undef d1 - -static double -ratio(Bigint *a, Bigint *b) -{ - double_u da, db; - int k, ka, kb; - - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(da) *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(db) *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return dval(da) / dval(db); -} - -static const double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif -}; - -static const double -#ifdef IEEE_Arith -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-53 */ -#else - 1e-256 -#endif -}; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static const double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static const double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -#ifndef IEEE_Arith -#undef INFNAN_CHECK -#endif - -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - -static int -match(const char **sp, char *t) -{ - int c, d; - const char *s = *sp; - - while (d = *t++) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; -} - -#ifndef No_Hex_NaN -static void -hexnan(double *rvp, const char **sp) -{ - ULong c, x[2]; - const char *s; - int havedig, udx0, xshift; - - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - while (c = *(const unsigned char*)++s) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c += 10 - 'a'; - else if (c >= 'A' && c <= 'F') - c += 10 - 'A'; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(*rvp) = Exp_mask | x[0]; - word1(*rvp) = x[1]; - } -} -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - -NO_SANITIZE("unsigned-integer-overflow", double strtod(const char *s00, char **se)); -double -strtod(const char *s00, char **se) -{ -#ifdef Avoid_Underflow - int scale; -#endif - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - const char *s, *s0, *s1; - double aadj, adj; - double_u aadj1, rv, rv0; - Long L; - ULong y, z; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef USE_LOCALE - const char *s2; -#endif - - errno = 0; - sign = nz0 = nz = 0; - dval(rv) = 0.; - for (s = s00;;s++) - switch (*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } -break2: - if (*s == '0') { - if (s[1] == 'x' || s[1] == 'X') { - s0 = ++s; - adj = 0; - aadj = 1.0; - nd0 = -4; - - if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; - if (*s == '0') { - while (*++s == '0'); - s1 = strchr(hexdigit, *s); - } - if (s1 != NULL) { - do { - adj += aadj * ((s1 - hexdigit) & 15); - nd0 += 4; - aadj /= 16; - } while (*++s && (s1 = strchr(hexdigit, *s))); - } - - if (*s == '.') { - dsign = 1; - if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; - if (nd0 < 0) { - while (*s == '0') { - s++; - nd0 -= 4; - } - } - for (; *s && (s1 = strchr(hexdigit, *s)); ++s) { - adj += aadj * ((s1 - hexdigit) & 15); - if ((aadj /= 16) == 0.0) { - while (strchr(hexdigit, *++s)); - break; - } - } - } - else { - dsign = 0; - } - - if (*s == 'P' || *s == 'p') { - dsign = 0x2C - *++s; /* +: 2B, -: 2D */ - if (abs(dsign) == 1) s++; - else dsign = 1; - - nd = 0; - c = *s; - if (c < '0' || '9' < c) goto ret0; - do { - nd *= 10; - nd += c; - nd -= '0'; - c = *++s; - /* Float("0x0."+("0"*267)+"1fp2095") */ - if (nd + dsign * nd0 > 2095) { - while ('0' <= c && c <= '9') c = *++s; - break; - } - } while ('0' <= c && c <= '9'); - nd0 += nd * dsign; - } - else { - if (dsign) goto ret0; - } - dval(rv) = ldexp(adj, nd0); - goto ret; - } - nz0 = 1; - while (*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < DBL_DIG + 2) - z = 10*z + c - '0'; - nd0 = nd; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for (;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - if (!ISDIGIT(s[1])) - goto dig_done; - c = *++s; - if (!nd) { - for (; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for (; c >= '0' && c <= '9'; c = *++s) { -have_dig: - nz++; - if (nd > DBL_DIG * 4) { - continue; - } - if (c -= '0') { - nf += nz; - for (i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 2) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 2) - z = 10*z + c; - nz = 0; - } - } - } -dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch (c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while (c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while ((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - switch (c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ -ret0: - s = s00; - sign = 0; - } - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; - dval(rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(rv) = tens[k - 9] * dval(rv) + z; - } - bd0 = bb = bd = bs = delta = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 -#endif -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - dval(rv) = -dval(rv); - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - dval(rv) = -dval(rv); - sign = 0; - } -#endif - e -= i; - dval(rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ -vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(rv), tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - dval(rv) = -dval(rv); - sign = 0; - } -#endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - -#ifdef IEEE_Arith -#ifdef SET_INEXACT - inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow - scale = 0; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15) != 0) - dval(rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { -ovfl: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch (rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; - break; - default: - word0(rv) = Exp_mask; - word1(rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); -#endif -#else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; -#endif /*IEEE_Arith*/ - if (bd0) - goto retfree; - goto ret; - } - e1 >>= 4; - for (j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; - } - else - word0(rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15) != 0) - dval(rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; -#ifdef Avoid_Underflow - if (e1 & Scale_Bit) - scale = 2*P; - for (j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; zap j low bits */ - if (j >= 32) { - word1(rv) = 0; - if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; - else - word0(rv) &= 0xffffffff << (j-32); - } - else - word1(rv) &= 0xffffffff << j; - } -#else - for (j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; -#endif - if (!dval(rv)) { -undfl: - dval(rv) = 0.; -#ifndef NO_ERRNO - errno = ERANGE; -#endif - if (bd0) - goto retfree; - goto ret; - } -#ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for (;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) - bs2++; -#endif -#ifdef Avoid_Underflow - j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; -#ifdef Avoid_Underflow - bd2 += scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (rounding) { - if (dsign) { - adj = 1.; - goto apply_adj; - } - } - else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj = -0.5; - } - } -apply_adj: -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= - P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); - } - break; - } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { - if (!((rounding>>1) ^ dsign)) - y++; - adj = y; - } - } -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - goto cont; - } -#endif /*Honor_FLT_ROUNDS*/ - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask -#ifdef IEEE_Arith -#ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(rv) & Exp_mask) <= Exp_msk1 -#endif -#endif - ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( -#ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(rv) = 0; -#ifdef Avoid_Underflow - dsign = 0; -#endif - break; - } - } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { -drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else -#ifdef Avoid_Underflow - if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ -#endif /*IBM*/ - goto undfl; - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow - if (scale) { - L = word0(rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - goto undfl; - } - } -#endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) - break; -#endif - if (dsign) - dval(rv) += ulp(dval(rv)); -#ifndef ROUND_BIASED - else { - dval(rv) -= ulp(dval(rv)); -#ifndef Sudden_Underflow - if (!dval(rv)) - goto undfl; -#endif - } -#ifdef Avoid_Underflow - dsign = 1 - dsign; -#endif -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = dval(aadj1) = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) - goto undfl; -#endif - aadj = 1.; - dval(aadj1) = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - dval(aadj1) = -aadj; - } - } - else { - aadj *= 0.5; - dval(aadj1) = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch (Rounding) { - case 2: /* towards +infinity */ - dval(aadj1) -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - dval(aadj1) += 0.5; - } -#else - if (Flt_Rounds == 0) - dval(aadj1) += 0.5; -#endif /*Check_FLT_ROUNDS*/ - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) - goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; - goto cont; - } - else - word0(rv) += P*Exp_msk1; - } - else { -#ifdef Avoid_Underflow - if (scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = (int)aadj) <= 0) - z = 1; - aadj = z; - dval(aadj1) = dsign ? aadj : -aadj; - } - word0(aadj1) += (2*P+1)*Exp_msk1 - y; - } - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; -#ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1) - goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; - goto cont; - } - else - word0(rv) -= P*Exp_msk1; - } - else { - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - dval(aadj1) = (double)(int)(aadj + 0.5); - if (!dsign) - dval(aadj1) = -dval(aadj1); - } - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - } - z = word0(rv) & Exp_mask; -#ifndef SET_INEXACT -#ifdef Avoid_Underflow - if (!scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } -#endif -cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow - if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); -#ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ - if (word0(rv) == 0 && word1(rv) == 0) - errno = ERANGE; -#endif - } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { - /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); - } -#endif -retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); -ret: - if (se) - *se = (char *)s; - return sign ? -dval(rv) : dval(rv); -} - -NO_SANITIZE("unsigned-integer-overflow", static int quorem(Bigint *b, Bigint *S)); -static int -quorem(Bigint *b, Bigint *S) -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)(y & FFFFFFFF); -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } while (sx <= sxe); - if (!*bxe) { - bx = b->x; - while (--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)(y & FFFFFFFF); -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } while (sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while (--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; -} - -#ifndef MULTIPLE_THREADS -static char *dtoa_result; -#endif - -#ifndef MULTIPLE_THREADS -static char * -rv_alloc(int i) -{ - return dtoa_result = MALLOC(i); -} -#else -#define rv_alloc(i) MALLOC(i) -#endif - -static char * -nrv_alloc(const char *s, char **rve, size_t n) -{ - char *rv, *t; - - t = rv = rv_alloc(n); - while ((*t = *s++) != 0) t++; - if (rve) - *rve = t; - return rv; -} - -#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1) - -#ifndef MULTIPLE_THREADS -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - -static void -freedtoa(char *s) -{ - FREE(s); -} -#endif - -static const char INFSTR[] = "Infinity"; -static const char NANSTR[] = "NaN"; -static const char ZEROSTR[] = "0"; - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - -char * -dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick, half = 0; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S; - double ds; - double_u d, d2, eps; - char *s, *s0; -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif - - dval(d) = d_; - -#ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - if (word0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) -#else - if (word0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) - return rv_strdup(INFSTR, rve); -#endif - return rv_strdup(NANSTR, rve); - } -#endif -#ifdef IBM - dval(d) += 0; /* normalize */ -#endif - if (!dval(d)) { - *decpt = 1; - return rv_strdup(ZEROSTR, rve); - } - -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (*sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif - - b = d2b(dval(d), &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { -#endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - dval(d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) - : word1(d) << (32 - i); - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; - switch (mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i+1); - -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(d2) = dval(d); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; - ieps++; - } - for (; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(d) /= ds; - } - else if ((j1 = -k) != 0) { - dval(d) *= tens[j1 & 0xf]; - for (j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(d) *= bigtens[i]; - } - } - if (k_check && dval(d) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(d) *= 10.; - ieps++; - } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) - goto one_digit; - if (dval(d) < -dval(eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); - for (i = 0;;) { - L = (int)dval(d); - dval(d) -= L; - *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) - goto ret1; - if (1. - dval(d) < dval(eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(eps) *= 10.; - dval(d) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for (i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) - goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { - while (*--s == '0') ; - s++; - goto ret1; - } - half = 1; - if ((*(s-1) - '0') & 1) { - goto bump_up; - } - break; - } - } -#ifndef No_leftright - } -#endif -fast_failed: - s = s0; - dval(d) = dval(d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) - goto no_digits; - goto one_digit; - } - for (i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { - L--; - dval(d) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(d)) { -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch (rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(d) += dval(d); - if (dval(d) > ds || (dval(d) == ds && (L & 1))) { -bump_up: - while (*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5) != 0) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && rounding == 1 -#endif - ) { - if (!word1(d) && !(word0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) - i = 32 - i; -#else - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ -no_digits: - k = -1 - ndigits; - goto ret; - } -one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for (i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) -#ifdef Honor_FLT_ROUNDS - && rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && mode != 1 -#ifndef ROUND_BIASED - && !(word1(d) & 1) -#endif - )) { - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto accept_dig; - } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch (rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') - goto round_9_up; - } -accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ -round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } -#ifdef Honor_FLT_ROUNDS -keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for (i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - -#ifdef Honor_FLT_ROUNDS - switch (rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || (j == 0 && (dig & 1))) { - roundoff: - while (*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - if (!half || (*s - '0') & 1) - ++*s; - } - else { - while (*--s == '0') ; - } - s++; -ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } -ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; -} - -/*- - * Copyright (c) 2004-2008 David Schultz <das@FreeBSD.ORG> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define DBL_MANH_SIZE 20 -#define DBL_MANL_SIZE 32 -#define DBL_ADJ (DBL_MAX_EXP - 2) -#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1) -#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1) -#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift))) -#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask)) -#define dmanl_get(u) ((uint32_t)word1(u)) - - -/* - * This procedure converts a double-precision number in IEEE format - * into a string of hexadecimal digits and an exponent of 2. Its - * behavior is bug-for-bug compatible with dtoa() in mode 2, with the - * following exceptions: - * - * - An ndigits < 0 causes it to use as many digits as necessary to - * represent the number exactly. - * - The additional xdigs argument should point to either the string - * "0123456789ABCDEF" or the string "0123456789abcdef", depending on - * which case is desired. - * - This routine does not repeat dtoa's mistake of setting decpt - * to 9999 in the case of an infinity or NaN. INT_MAX is used - * for this purpose instead. - * - * Note that the C99 standard does not specify what the leading digit - * should be for non-zero numbers. For instance, 0x1.3p3 is the same - * as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes - * the leading digit a 1. This ensures that the exponent printed is the - * actual base-2 exponent, i.e., ilogb(d). - * - * Inputs: d, xdigs, ndigits - * Outputs: decpt, sign, rve - */ -char * -hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve) -{ - U u; - char *s, *s0; - int bufsize; - uint32_t manh, manl; - - u.d = d; - if (word0(u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - - if (isinf(d)) { /* FP_INFINITE */ - *decpt = INT_MAX; - return rv_strdup(INFSTR, rve); - } - else if (isnan(d)) { /* FP_NAN */ - *decpt = INT_MAX; - return rv_strdup(NANSTR, rve); - } - else if (d == 0.0) { /* FP_ZERO */ - *decpt = 1; - return rv_strdup(ZEROSTR, rve); - } - else if (dexp_get(u)) { /* FP_NORMAL */ - *decpt = dexp_get(u) - DBL_ADJ; - } - else { /* FP_SUBNORMAL */ - u.d *= 5.363123171977039e+154 /* 0x1p514 */; - *decpt = dexp_get(u) - (514 + DBL_ADJ); - } - - if (ndigits == 0) /* dtoa() compatibility */ - ndigits = 1; - - /* - * If ndigits < 0, we are expected to auto-size, so we allocate - * enough space for all the digits. - */ - bufsize = (ndigits > 0) ? ndigits : SIGFIGS; - s0 = rv_alloc(bufsize+1); - - /* Round to the desired number of digits. */ - if (SIGFIGS > ndigits && ndigits > 0) { - float redux = 1.0f; - int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG; - dexp_set(u, offset); - u.d += redux; - u.d -= redux; - *decpt += dexp_get(u) - offset; - } - - manh = dmanh_get(u); - manl = dmanl_get(u); - *s0 = '1'; - for (s = s0 + 1; s < s0 + bufsize; s++) { - *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf]; - manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4)); - manl <<= 4; - } - - /* If ndigits < 0, we are expected to auto-size the precision. */ - if (ndigits < 0) { - for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--) - ; - } - - s = s0 + ndigits; - *s = '\0'; - if (rve != NULL) - *rve = s; - return (s0); -} - -#ifdef __cplusplus -#if 0 -{ /* satisfy cc-mode */ -#endif -} -#endif diff --git a/ext/bigdecimal/sample/linear.rb b/ext/bigdecimal/sample/linear.rb deleted file mode 100644 index 516c2473be..0000000000 --- a/ext/bigdecimal/sample/linear.rb +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/local/bin/ruby -# frozen_string_literal: false - -# -# linear.rb -# -# Solves linear equation system(A*x = b) by LU decomposition method. -# where A is a coefficient matrix,x is an answer vector,b is a constant vector. -# -# USAGE: -# ruby linear.rb [input file solved] -# - -# :stopdoc: -require "bigdecimal" -require "bigdecimal/ludcmp" - -# -# NOTE: -# Change following BigDecimal.limit() if needed. -BigDecimal.limit(100) -# - -include LUSolve -def rd_order(na) - printf("Number of equations ?") if(na <= 0) - n = ARGF.gets().to_i -end - -na = ARGV.size -zero = BigDecimal("0.0") -one = BigDecimal("1.0") - -while (n=rd_order(na))>0 - a = [] - as= [] - b = [] - if na <= 0 - # Read data from console. - printf("\nEnter coefficient matrix element A[i,j]\n") - for i in 0...n do - for j in 0...n do - printf("A[%d,%d]? ",i,j); s = ARGF.gets - a << BigDecimal(s) - as << BigDecimal(s) - end - printf("Contatant vector element b[%d] ? ",i) - b << BigDecimal(ARGF.gets) - end - else - # Read data from specified file. - printf("Coefficient matrix and constant vector.\n") - for i in 0...n do - s = ARGF.gets - printf("%d) %s",i,s) - s = s.split - for j in 0...n do - a << BigDecimal(s[j]) - as << BigDecimal(s[j]) - end - b << BigDecimal(s[n]) - end - end - x = lusolve(a,b,ludecomp(a,n,zero,one),zero) - printf("Answer(x[i] & (A*x-b)[i]) follows\n") - for i in 0...n do - printf("x[%d]=%s ",i,x[i].to_s) - s = zero - for j in 0...n do - s = s + as[i*n+j]*x[j] - end - printf(" & %s\n",(s-b[i]).to_s) - end -end diff --git a/ext/bigdecimal/sample/nlsolve.rb b/ext/bigdecimal/sample/nlsolve.rb deleted file mode 100644 index c2227dac73..0000000000 --- a/ext/bigdecimal/sample/nlsolve.rb +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/local/bin/ruby -# frozen_string_literal: false - -# -# nlsolve.rb -# An example for solving nonlinear algebraic equation system. -# - -require "bigdecimal" -require "bigdecimal/newton" -include Newton - -class Function # :nodoc: all - def initialize() - @zero = BigDecimal("0.0") - @one = BigDecimal("1.0") - @two = BigDecimal("2.0") - @ten = BigDecimal("10.0") - @eps = BigDecimal("1.0e-16") - end - def zero;@zero;end - def one ;@one ;end - def two ;@two ;end - def ten ;@ten ;end - def eps ;@eps ;end - def values(x) # <= defines functions solved - f = [] - f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0 - f2 = x[0] - x[1] # f2 = x - y => 0 - f <<= f1 - f <<= f2 - f - end -end - -f = BigDecimal.limit(100) -f = Function.new -x = [f.zero,f.zero] # Initial values -n = nlsolve(f,x) -p x diff --git a/ext/bigdecimal/sample/pi.rb b/ext/bigdecimal/sample/pi.rb deleted file mode 100644 index ea9663896c..0000000000 --- a/ext/bigdecimal/sample/pi.rb +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/local/bin/ruby -# frozen_string_literal: false - -# -# pi.rb -# -# Calculates 3.1415.... (the number of times that a circle's diameter -# will fit around the circle) using J. Machin's formula. -# - -require "bigdecimal" -require "bigdecimal/math.rb" - -include BigMath - -if ARGV.size == 1 - print "PI("+ARGV[0]+"):\n" - p PI(ARGV[0].to_i) -else - print "TRY: ruby pi.rb 1000 \n" -end diff --git a/ext/bigdecimal/static_assert.h b/ext/bigdecimal/static_assert.h deleted file mode 100644 index 9295729bf6..0000000000 --- a/ext/bigdecimal/static_assert.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BIGDECIMAL_STATIC_ASSERT_H -#define BIGDECIMAL_STATIC_ASSERT_H - -#include "feature.h" - -#ifdef HAVE_RUBY_INTERNAL_STATIC_ASSERT_H -# include <ruby/internal/static_assert.h> -#endif - -#ifdef RBIMPL_STATIC_ASSERT -# define STATIC_ASSERT RBIMPL_STATIC_ASSERT -#endif - -#ifndef STATIC_ASSERT -# /* The following section is copied from CRuby's static_assert.h */ - -# if defined(__cplusplus) && defined(__cpp_static_assert) -# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */ -# define BIGDECIMAL_STATIC_ASSERT0 static_assert - -# elif defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER >= 1600 -# define BIGDECIMAL_STATIC_ASSERT0 static_assert - -# elif defined(__INTEL_CXX11_MODE__) -# define BIGDECIMAL_STATIC_ASSERT0 static_assert - -# elif defined(__cplusplus) && __cplusplus >= 201103L -# define BIGDECIMAL_STATIC_ASSERT0 static_assert - -# elif defined(__cplusplus) && __has_extension(cxx_static_assert) -# define BIGDECIMAL_STATIC_ASSERT0 __extension__ static_assert - -# elif defined(__STDC_VERSION__) && __has_extension(c_static_assert) -# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert - -# elif defined(__STDC_VERSION__) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert -#endif - -# if defined(__DOXYGEN__) -# define STATIC_ASSERT static_assert - -# elif defined(BIGDECIMAL_STATIC_ASSERT0) -# define STATIC_ASSERT(name, expr) \ - BIGDECIMAL_STATIC_ASSERT0(expr, #name ": " #expr) - -# else -# define STATIC_ASSERT(name, expr) \ - typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)] -# endif -#endif /* STATIC_ASSERT */ - - -#endif /* BIGDECIMAL_STATIC_ASSERT_H */ diff --git a/ext/cgi/escape/depend b/ext/cgi/escape/depend index a965ccfca7..05b59bfdea 100644 --- a/ext/cgi/escape/depend +++ b/ext/cgi/escape/depend @@ -7,7 +7,6 @@ escape.o: $(hdrdir)/ruby/backward.h escape.o: $(hdrdir)/ruby/backward/2/assume.h escape.o: $(hdrdir)/ruby/backward/2/attributes.h escape.o: $(hdrdir)/ruby/backward/2/bool.h -escape.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h escape.o: $(hdrdir)/ruby/backward/2/inttypes.h escape.o: $(hdrdir)/ruby/backward/2/limits.h escape.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ escape.o: $(hdrdir)/ruby/backward/2/stdarg.h escape.o: $(hdrdir)/ruby/defines.h escape.o: $(hdrdir)/ruby/encoding.h escape.o: $(hdrdir)/ruby/intern.h +escape.o: $(hdrdir)/ruby/internal/abi.h escape.o: $(hdrdir)/ruby/internal/anyargs.h escape.o: $(hdrdir)/ruby/internal/arithmetic.h escape.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ escape.o: $(hdrdir)/ruby/internal/attr/noexcept.h escape.o: $(hdrdir)/ruby/internal/attr/noinline.h escape.o: $(hdrdir)/ruby/internal/attr/nonnull.h escape.o: $(hdrdir)/ruby/internal/attr/noreturn.h +escape.o: $(hdrdir)/ruby/internal/attr/packed_struct.h escape.o: $(hdrdir)/ruby/internal/attr/pure.h escape.o: $(hdrdir)/ruby/internal/attr/restrict.h escape.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ escape.o: $(hdrdir)/ruby/internal/intern/enumerator.h escape.o: $(hdrdir)/ruby/internal/intern/error.h escape.o: $(hdrdir)/ruby/internal/intern/eval.h escape.o: $(hdrdir)/ruby/internal/intern/file.h -escape.o: $(hdrdir)/ruby/internal/intern/gc.h escape.o: $(hdrdir)/ruby/internal/intern/hash.h escape.o: $(hdrdir)/ruby/internal/intern/io.h escape.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ escape.o: $(hdrdir)/ruby/internal/intern/re.h escape.o: $(hdrdir)/ruby/internal/intern/ruby.h escape.o: $(hdrdir)/ruby/internal/intern/select.h escape.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +escape.o: $(hdrdir)/ruby/internal/intern/set.h escape.o: $(hdrdir)/ruby/internal/intern/signal.h escape.o: $(hdrdir)/ruby/internal/intern/sprintf.h escape.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ escape.o: $(hdrdir)/ruby/internal/memory.h escape.o: $(hdrdir)/ruby/internal/method.h escape.o: $(hdrdir)/ruby/internal/module.h escape.o: $(hdrdir)/ruby/internal/newobj.h -escape.o: $(hdrdir)/ruby/internal/rgengc.h escape.o: $(hdrdir)/ruby/internal/scan_args.h escape.o: $(hdrdir)/ruby/internal/special_consts.h escape.o: $(hdrdir)/ruby/internal/static_assert.h escape.o: $(hdrdir)/ruby/internal/stdalign.h escape.o: $(hdrdir)/ruby/internal/stdbool.h +escape.o: $(hdrdir)/ruby/internal/stdckdint.h escape.o: $(hdrdir)/ruby/internal/symbol.h escape.o: $(hdrdir)/ruby/internal/value.h escape.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c index 3a7837e4df..4773186603 100644 --- a/ext/cgi/escape/escape.c +++ b/ext/cgi/escape/escape.c @@ -8,7 +8,7 @@ RUBY_EXTERN const signed char ruby_digit36_to_number_table[]; #define upper_hexdigits (ruby_hexdigits+16) #define char_to_number(c) ruby_digit36_to_number_table[(unsigned char)(c)] -static VALUE rb_cCGI, rb_mUtil, rb_mEscape; +static VALUE rb_cCGI, rb_mEscape, rb_mEscapeExt; static ID id_accept_charset; #define HTML_ESCAPE_MAX_LEN 6 @@ -32,11 +32,22 @@ preserve_original_state(VALUE orig, VALUE dest) rb_enc_associate(dest, rb_enc_get(orig)); } +static inline long +escaped_length(VALUE str) +{ + const long len = RSTRING_LEN(str); + if (len >= LONG_MAX / HTML_ESCAPE_MAX_LEN) { + ruby_malloc_size_overflow(len, HTML_ESCAPE_MAX_LEN); + } + return len * HTML_ESCAPE_MAX_LEN; +} + static VALUE optimized_escape_html(VALUE str) { + VALUE escaped; VALUE vbuf; - char *buf = ALLOCV_N(char, vbuf, RSTRING_LEN(str) * HTML_ESCAPE_MAX_LEN); + char *buf = ALLOCV_N(char, vbuf, escaped_length(str)); const char *cstr = RSTRING_PTR(str); const char *end = cstr + RSTRING_LEN(str); @@ -53,7 +64,6 @@ optimized_escape_html(VALUE str) } } - VALUE escaped; if (RSTRING_LEN(str) < (dest - buf)) { escaped = rb_str_new(buf, dest - buf); preserve_original_state(str, escaped); @@ -71,9 +81,9 @@ optimized_unescape_html(VALUE str) enum {UNICODE_MAX = 0x10ffff}; rb_encoding *enc = rb_enc_get(str); unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX : - strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 : - 128); - long i, len, beg = 0; + strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 : + 128); + long i, j, len, beg = 0; size_t clen, plen; int overflow; const char *cstr; @@ -84,89 +94,108 @@ optimized_unescape_html(VALUE str) cstr = RSTRING_PTR(str); for (i = 0; i < len; i++) { - unsigned long cc; - char c = cstr[i]; - if (c != '&') continue; - plen = i - beg; - if (++i >= len) break; - c = (unsigned char)cstr[i]; + unsigned long cc; + char c = cstr[i]; + if (c != '&') continue; + plen = i - beg; + if (++i >= len) break; + c = (unsigned char)cstr[i]; + j = i; #define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \ - memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \ - (i += rb_strlen_lit(s) - 1, 1)) - switch (c) { - case 'a': - ++i; - if (MATCH("pos;")) { - c = '\''; - } - else if (MATCH("mp;")) { - c = '&'; - } - else continue; - break; - case 'q': - ++i; - if (MATCH("uot;")) { - c = '"'; - } - else continue; - break; - case 'g': - ++i; - if (MATCH("t;")) { - c = '>'; - } - else continue; - break; - case 'l': - ++i; - if (MATCH("t;")) { - c = '<'; - } - else continue; - break; - case '#': - if (len - ++i >= 2 && ISDIGIT(cstr[i])) { - cc = ruby_scan_digits(&cstr[i], len-i, 10, &clen, &overflow); - } - else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) { - cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow); - } - else continue; - i += clen; - if (overflow || cc >= charlimit || cstr[i] != ';') continue; - if (!dest) { - dest = rb_str_buf_new(len); - } - rb_str_cat(dest, cstr + beg, plen); - if (charlimit > 256) { - rb_str_cat(dest, buf, rb_enc_mbcput((OnigCodePoint)cc, buf, enc)); - } - else { - c = (unsigned char)cc; - rb_str_cat(dest, &c, 1); - } - beg = i + 1; - continue; - default: - --i; - continue; - } - if (!dest) { - dest = rb_str_buf_new(len); - } - rb_str_cat(dest, cstr + beg, plen); - rb_str_cat(dest, &c, 1); - beg = i + 1; + memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \ + (i += rb_strlen_lit(s) - 1, 1)) + switch (c) { + case 'a': + ++i; + if (MATCH("pos;")) { + c = '\''; + } + else if (MATCH("mp;")) { + c = '&'; + } + else { + i = j; + continue; + } + break; + case 'q': + ++i; + if (MATCH("uot;")) { + c = '"'; + } + else { + i = j; + continue; + } + break; + case 'g': + ++i; + if (MATCH("t;")) { + c = '>'; + } + else { + i = j; + continue; + } + break; + case 'l': + ++i; + if (MATCH("t;")) { + c = '<'; + } + else { + i = j; + continue; + } + break; + case '#': + if (len - ++i >= 2 && ISDIGIT(cstr[i])) { + cc = ruby_scan_digits(&cstr[i], len-i, 10, &clen, &overflow); + } + else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) { + cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow); + } + else { + i = j; + continue; + } + i += clen; + if (overflow || cc >= charlimit || cstr[i] != ';') { + i = j; + continue; + } + if (!dest) { + dest = rb_str_buf_new(len); + } + rb_str_cat(dest, cstr + beg, plen); + if (charlimit > 256) { + rb_str_cat(dest, buf, rb_enc_mbcput((OnigCodePoint)cc, buf, enc)); + } + else { + c = (unsigned char)cc; + rb_str_cat(dest, &c, 1); + } + beg = i + 1; + continue; + default: + --i; + continue; + } + if (!dest) { + dest = rb_str_buf_new(len); + } + rb_str_cat(dest, cstr + beg, plen); + rb_str_cat(dest, &c, 1); + beg = i + 1; } if (dest) { - rb_str_cat(dest, cstr + beg, len - beg); - preserve_original_state(str, dest); - return dest; + rb_str_cat(dest, cstr + beg, len - beg); + preserve_original_state(str, dest); + return dest; } else { - return rb_str_dup(str); + return rb_str_dup(str); } } @@ -190,7 +219,7 @@ url_unreserved_char(unsigned char c) } static VALUE -optimized_escape(VALUE str) +optimized_escape(VALUE str, int plus_escape) { long i, len, beg = 0; VALUE dest = 0; @@ -201,38 +230,38 @@ optimized_escape(VALUE str) cstr = RSTRING_PTR(str); for (i = 0; i < len; ++i) { - const unsigned char c = (unsigned char)cstr[i]; - if (!url_unreserved_char(c)) { - if (!dest) { - dest = rb_str_buf_new(len); - } - - rb_str_cat(dest, cstr + beg, i - beg); - beg = i + 1; - - if (c == ' ') { - rb_str_cat_cstr(dest, "+"); - } - else { - buf[1] = upper_hexdigits[(c >> 4) & 0xf]; - buf[2] = upper_hexdigits[c & 0xf]; - rb_str_cat(dest, buf, 3); - } - } + const unsigned char c = (unsigned char)cstr[i]; + if (!url_unreserved_char(c)) { + if (!dest) { + dest = rb_str_buf_new(len); + } + + rb_str_cat(dest, cstr + beg, i - beg); + beg = i + 1; + + if (plus_escape && c == ' ') { + rb_str_cat_cstr(dest, "+"); + } + else { + buf[1] = upper_hexdigits[(c >> 4) & 0xf]; + buf[2] = upper_hexdigits[c & 0xf]; + rb_str_cat(dest, buf, 3); + } + } } if (dest) { - rb_str_cat(dest, cstr + beg, len - beg); - preserve_original_state(str, dest); - return dest; + rb_str_cat(dest, cstr + beg, len - beg); + preserve_original_state(str, dest); + return dest; } else { - return rb_str_dup(str); + return rb_str_dup(str); } } static VALUE -optimized_unescape(VALUE str, VALUE encoding) +optimized_unescape(VALUE str, VALUE encoding, int unescape_plus) { long i, len, beg = 0; VALUE dest = 0; @@ -244,52 +273,52 @@ optimized_unescape(VALUE str, VALUE encoding) cstr = RSTRING_PTR(str); for (i = 0; i < len; ++i) { - char buf[1]; - const char c = cstr[i]; - int clen = 0; - if (c == '%') { - if (i + 3 > len) break; - if (!ISXDIGIT(cstr[i+1])) continue; - if (!ISXDIGIT(cstr[i+2])) continue; - buf[0] = ((char_to_number(cstr[i+1]) << 4) - | char_to_number(cstr[i+2])); - clen = 2; - } - else if (c == '+') { - buf[0] = ' '; - } - else { - continue; - } - - if (!dest) { - dest = rb_str_buf_new(len); - } - - rb_str_cat(dest, cstr + beg, i - beg); - i += clen; - beg = i + 1; - - rb_str_cat(dest, buf, 1); + char buf[1]; + const char c = cstr[i]; + int clen = 0; + if (c == '%') { + if (i + 3 > len) break; + if (!ISXDIGIT(cstr[i+1])) continue; + if (!ISXDIGIT(cstr[i+2])) continue; + buf[0] = ((char_to_number(cstr[i+1]) << 4) + | char_to_number(cstr[i+2])); + clen = 2; + } + else if (unescape_plus && c == '+') { + buf[0] = ' '; + } + else { + continue; + } + + if (!dest) { + dest = rb_str_buf_new(len); + } + + rb_str_cat(dest, cstr + beg, i - beg); + i += clen; + beg = i + 1; + + rb_str_cat(dest, buf, 1); } if (dest) { - rb_str_cat(dest, cstr + beg, len - beg); - preserve_original_state(str, dest); - cr = ENC_CODERANGE_UNKNOWN; + rb_str_cat(dest, cstr + beg, len - beg); + preserve_original_state(str, dest); + cr = ENC_CODERANGE_UNKNOWN; } else { - dest = rb_str_dup(str); - cr = ENC_CODERANGE(str); + dest = rb_str_dup(str); + cr = ENC_CODERANGE(str); } origenc = rb_enc_get_index(str); if (origenc != encidx) { - rb_enc_associate_index(dest, encidx); - if (!ENC_CODERANGE_CLEAN_P(rb_enc_str_coderange(dest))) { - rb_enc_associate_index(dest, origenc); - if (cr != ENC_CODERANGE_UNKNOWN) - ENC_CODERANGE_SET(dest, cr); - } + rb_enc_associate_index(dest, encidx); + if (!ENC_CODERANGE_CLEAN_P(rb_enc_str_coderange(dest))) { + rb_enc_associate_index(dest, origenc); + if (cr != ENC_CODERANGE_UNKNOWN) + ENC_CODERANGE_SET(dest, cr); + } } return dest; } @@ -307,10 +336,10 @@ cgiesc_escape_html(VALUE self, VALUE str) StringValue(str); if (rb_enc_str_asciicompat_p(str)) { - return optimized_escape_html(str); + return optimized_escape_html(str); } else { - return rb_call_super(1, &str); + return rb_call_super(1, &str); } } @@ -327,10 +356,10 @@ cgiesc_unescape_html(VALUE self, VALUE str) StringValue(str); if (rb_enc_str_asciicompat_p(str)) { - return optimized_unescape_html(str); + return optimized_unescape_html(str); } else { - return rb_call_super(1, &str); + return rb_call_super(1, &str); } } @@ -338,7 +367,7 @@ cgiesc_unescape_html(VALUE self, VALUE str) * call-seq: * CGI.escape(string) -> string * - * Returns URL-escaped string. + * Returns URL-escaped string (+application/x-www-form-urlencoded+). * */ static VALUE @@ -347,10 +376,10 @@ cgiesc_escape(VALUE self, VALUE str) StringValue(str); if (rb_enc_str_asciicompat_p(str)) { - return optimized_escape(str); + return optimized_escape(str, 1); } else { - return rb_call_super(1, &str); + return rb_call_super(1, &str); } } @@ -358,7 +387,7 @@ static VALUE accept_charset(int argc, VALUE *argv, VALUE self) { if (argc > 0) - return argv[0]; + return argv[0]; return rb_cvar_get(CLASS_OF(self), id_accept_charset); } @@ -366,7 +395,7 @@ accept_charset(int argc, VALUE *argv, VALUE self) * call-seq: * CGI.unescape(string, encoding=@@accept_charset) -> string * - * Returns URL-unescaped string. + * Returns URL-unescaped string (+application/x-www-form-urlencoded+). * */ static VALUE @@ -377,11 +406,54 @@ cgiesc_unescape(int argc, VALUE *argv, VALUE self) StringValue(str); if (rb_enc_str_asciicompat_p(str)) { - VALUE enc = accept_charset(argc-1, argv+1, self); - return optimized_unescape(str, enc); + VALUE enc = accept_charset(argc-1, argv+1, self); + return optimized_unescape(str, enc, 1); + } + else { + return rb_call_super(argc, argv); + } +} + +/* + * call-seq: + * CGI.escapeURIComponent(string) -> string + * + * Returns URL-escaped string following RFC 3986. + * + */ +static VALUE +cgiesc_escape_uri_component(VALUE self, VALUE str) +{ + StringValue(str); + + if (rb_enc_str_asciicompat_p(str)) { + return optimized_escape(str, 0); + } + else { + return rb_call_super(1, &str); + } +} + +/* + * call-seq: + * CGI.unescapeURIComponent(string, encoding=@@accept_charset) -> string + * + * Returns URL-unescaped string following RFC 3986. + * + */ +static VALUE +cgiesc_unescape_uri_component(int argc, VALUE *argv, VALUE self) +{ + VALUE str = (rb_check_arity(argc, 1, 2), argv[0]); + + StringValue(str); + + if (rb_enc_str_asciicompat_p(str)) { + VALUE enc = accept_charset(argc-1, argv+1, self); + return optimized_unescape(str, enc, 0); } else { - return rb_call_super(argc, argv); + return rb_call_super(argc, argv); } } @@ -399,13 +471,17 @@ Init_escape(void) void InitVM_escape(void) { - rb_cCGI = rb_define_class("CGI", rb_cObject); - rb_mEscape = rb_define_module_under(rb_cCGI, "Escape"); - rb_mUtil = rb_define_module_under(rb_cCGI, "Util"); - rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1); - rb_define_method(rb_mEscape, "unescapeHTML", cgiesc_unescape_html, 1); - rb_define_method(rb_mEscape, "escape", cgiesc_escape, 1); - rb_define_method(rb_mEscape, "unescape", cgiesc_unescape, -1); - rb_prepend_module(rb_mUtil, rb_mEscape); - rb_extend_object(rb_cCGI, rb_mEscape); + rb_cCGI = rb_define_class("CGI", rb_cObject); + rb_mEscapeExt = rb_define_module_under(rb_cCGI, "EscapeExt"); + rb_mEscape = rb_define_module_under(rb_cCGI, "Escape"); + rb_define_method(rb_mEscapeExt, "escapeHTML", cgiesc_escape_html, 1); + rb_define_method(rb_mEscapeExt, "unescapeHTML", cgiesc_unescape_html, 1); + rb_define_method(rb_mEscapeExt, "escapeURIComponent", cgiesc_escape_uri_component, 1); + rb_define_alias(rb_mEscapeExt, "escape_uri_component", "escapeURIComponent"); + rb_define_method(rb_mEscapeExt, "unescapeURIComponent", cgiesc_unescape_uri_component, -1); + rb_define_alias(rb_mEscapeExt, "unescape_uri_component", "unescapeURIComponent"); + rb_define_method(rb_mEscapeExt, "escape", cgiesc_escape, 1); + rb_define_method(rb_mEscapeExt, "unescape", cgiesc_unescape, -1); + rb_prepend_module(rb_mEscape, rb_mEscapeExt); + rb_extend_object(rb_cCGI, rb_mEscapeExt); } diff --git a/ext/cgi/escape/extconf.rb b/ext/cgi/escape/extconf.rb index 16e8ff224d..73acd89ca8 100644 --- a/ext/cgi/escape/extconf.rb +++ b/ext/cgi/escape/extconf.rb @@ -1,3 +1,7 @@ require 'mkmf' -create_makefile 'cgi/escape' +if RUBY_ENGINE == 'truffleruby' + File.write("Makefile", dummy_makefile($srcdir).join("")) +else + create_makefile 'cgi/escape' +end diff --git a/ext/continuation/depend b/ext/continuation/depend index c8e55b0b1c..b395d3d4d7 100644 --- a/ext/continuation/depend +++ b/ext/continuation/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START continuation.o: $(RUBY_EXTCONF_H) continuation.o: $(arch_hdrdir)/ruby/config.h +continuation.o: $(hdrdir)/ruby/assert.h +continuation.o: $(hdrdir)/ruby/backward.h +continuation.o: $(hdrdir)/ruby/backward/2/assume.h +continuation.o: $(hdrdir)/ruby/backward/2/attributes.h +continuation.o: $(hdrdir)/ruby/backward/2/bool.h +continuation.o: $(hdrdir)/ruby/backward/2/inttypes.h +continuation.o: $(hdrdir)/ruby/backward/2/limits.h +continuation.o: $(hdrdir)/ruby/backward/2/long_long.h +continuation.o: $(hdrdir)/ruby/backward/2/stdalign.h +continuation.o: $(hdrdir)/ruby/backward/2/stdarg.h +continuation.o: $(hdrdir)/ruby/defines.h +continuation.o: $(hdrdir)/ruby/intern.h +continuation.o: $(hdrdir)/ruby/internal/abi.h continuation.o: $(hdrdir)/ruby/internal/anyargs.h continuation.o: $(hdrdir)/ruby/internal/arithmetic.h continuation.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ continuation.o: $(hdrdir)/ruby/internal/attr/noexcept.h continuation.o: $(hdrdir)/ruby/internal/attr/noinline.h continuation.o: $(hdrdir)/ruby/internal/attr/nonnull.h continuation.o: $(hdrdir)/ruby/internal/attr/noreturn.h +continuation.o: $(hdrdir)/ruby/internal/attr/packed_struct.h continuation.o: $(hdrdir)/ruby/internal/attr/pure.h continuation.o: $(hdrdir)/ruby/internal/attr/restrict.h continuation.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ continuation.o: $(hdrdir)/ruby/internal/intern/enumerator.h continuation.o: $(hdrdir)/ruby/internal/intern/error.h continuation.o: $(hdrdir)/ruby/internal/intern/eval.h continuation.o: $(hdrdir)/ruby/internal/intern/file.h -continuation.o: $(hdrdir)/ruby/internal/intern/gc.h continuation.o: $(hdrdir)/ruby/internal/intern/hash.h continuation.o: $(hdrdir)/ruby/internal/intern/io.h continuation.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ continuation.o: $(hdrdir)/ruby/internal/intern/re.h continuation.o: $(hdrdir)/ruby/internal/intern/ruby.h continuation.o: $(hdrdir)/ruby/internal/intern/select.h continuation.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +continuation.o: $(hdrdir)/ruby/internal/intern/set.h continuation.o: $(hdrdir)/ruby/internal/intern/signal.h continuation.o: $(hdrdir)/ruby/internal/intern/sprintf.h continuation.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ continuation.o: $(hdrdir)/ruby/internal/memory.h continuation.o: $(hdrdir)/ruby/internal/method.h continuation.o: $(hdrdir)/ruby/internal/module.h continuation.o: $(hdrdir)/ruby/internal/newobj.h -continuation.o: $(hdrdir)/ruby/internal/rgengc.h continuation.o: $(hdrdir)/ruby/internal/scan_args.h continuation.o: $(hdrdir)/ruby/internal/special_consts.h continuation.o: $(hdrdir)/ruby/internal/static_assert.h continuation.o: $(hdrdir)/ruby/internal/stdalign.h continuation.o: $(hdrdir)/ruby/internal/stdbool.h +continuation.o: $(hdrdir)/ruby/internal/stdckdint.h continuation.o: $(hdrdir)/ruby/internal/symbol.h continuation.o: $(hdrdir)/ruby/internal/value.h continuation.o: $(hdrdir)/ruby/internal/value_type.h continuation.o: $(hdrdir)/ruby/internal/variable.h continuation.o: $(hdrdir)/ruby/internal/warning_push.h continuation.o: $(hdrdir)/ruby/internal/xmalloc.h -continuation.o: $(hdrdir)/ruby/assert.h -continuation.o: $(hdrdir)/ruby/backward.h -continuation.o: $(hdrdir)/ruby/backward/2/assume.h -continuation.o: $(hdrdir)/ruby/backward/2/attributes.h -continuation.o: $(hdrdir)/ruby/backward/2/bool.h -continuation.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -continuation.o: $(hdrdir)/ruby/backward/2/inttypes.h -continuation.o: $(hdrdir)/ruby/backward/2/limits.h -continuation.o: $(hdrdir)/ruby/backward/2/long_long.h -continuation.o: $(hdrdir)/ruby/backward/2/stdalign.h -continuation.o: $(hdrdir)/ruby/backward/2/stdarg.h -continuation.o: $(hdrdir)/ruby/defines.h -continuation.o: $(hdrdir)/ruby/intern.h continuation.o: $(hdrdir)/ruby/missing.h continuation.o: $(hdrdir)/ruby/ruby.h continuation.o: $(hdrdir)/ruby/st.h diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c index 0af5579ffc..747f065fba 100644 --- a/ext/coverage/coverage.c +++ b/ext/coverage/coverage.c @@ -8,72 +8,176 @@ ************************************************/ -#include "gc.h" +#include "internal/gc.h" #include "internal/hash.h" #include "internal/thread.h" #include "internal/sanitizers.h" #include "ruby.h" #include "vm_core.h" +static enum { + IDLE, + SUSPENDED, + RUNNING +} current_state = IDLE; static int current_mode; static VALUE me2counter = Qnil; /* + * call-seq: Coverage.supported?(mode) -> true or false + * + * Returns true if coverage measurement is supported for the given mode. + * + * The mode should be one of the following symbols: + * +:lines+, +:oneshot_lines+, +:branches+, +:methods+, +:eval+. + * + * Example: + * + * Coverage.supported?(:lines) #=> true + * Coverage.supported?(:all) #=> false + */ +static VALUE +rb_coverage_supported(VALUE self, VALUE _mode) +{ + ID mode = RB_SYM2ID(_mode); + + return RBOOL( + mode == rb_intern("lines") || + mode == rb_intern("oneshot_lines") || + mode == rb_intern("branches") || + mode == rb_intern("methods") || + mode == rb_intern("eval") + ); +} + +/* * call-seq: - * Coverage.start => nil + * Coverage.setup -> nil + * Coverage.setup(type) -> nil + * Coverage.setup(lines: false, branches: false, methods: false, eval: false, oneshot_lines: false) -> nil + * + * Performs setup for coverage measurement, but does not start coverage measurement. + * To start coverage measurement, use Coverage.resume. + * + * To perform both setup and start coverage measurement, Coverage.start can be used. * - * Enables coverage measurement. + * With argument +type+ given and +type+ is symbol +:all+, enables all types of coverage + * (lines, branches, methods, and eval). + * + * Keyword arguments or hash +type+ can be given with each of the following keys: + * + * - +lines+: Enables line coverage that records the number of times each line was executed. + * If +lines+ is enabled, +oneshot_lines+ cannot be enabled. + * See {Lines Coverage}[rdoc-ref:Coverage@Lines+Coverage]. + * - +branches+: Enables branch coverage that records the number of times each + * branch in each conditional was executed. See {Branches Coverage}[rdoc-ref:Coverage@Branch+Coverage]. + * - +methods+: Enables method coverage that records the number of times each method was exectued. + * See {Methods Coverage}[rdoc-ref:Coverage@Methods+Coverage]. + * - +eval+: Enables coverage for evaluations (e.g. Kernel#eval, Module#class_eval). + * See {Eval Coverage}[rdoc-ref:Coverage@Eval+Coverage]. */ static VALUE -rb_coverage_start(int argc, VALUE *argv, VALUE klass) +rb_coverage_setup(int argc, VALUE *argv, VALUE klass) { VALUE coverages, opt; int mode; + if (current_state != IDLE) { + rb_raise(rb_eRuntimeError, "coverage measurement is already setup"); + } + rb_scan_args(argc, argv, "01", &opt); if (argc == 0) { - mode = 0; /* compatible mode */ + mode = 0; /* compatible mode */ } else if (opt == ID2SYM(rb_intern("all"))) { - mode = COVERAGE_TARGET_LINES | COVERAGE_TARGET_BRANCHES | COVERAGE_TARGET_METHODS; + mode = COVERAGE_TARGET_LINES | COVERAGE_TARGET_BRANCHES | COVERAGE_TARGET_METHODS | COVERAGE_TARGET_EVAL; } else { - mode = 0; - opt = rb_convert_type(opt, T_HASH, "Hash", "to_hash"); - - if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("lines"))))) - mode |= COVERAGE_TARGET_LINES; - if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("branches"))))) - mode |= COVERAGE_TARGET_BRANCHES; - if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("methods"))))) - mode |= COVERAGE_TARGET_METHODS; + mode = 0; + opt = rb_convert_type(opt, T_HASH, "Hash", "to_hash"); + + if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("lines"))))) + mode |= COVERAGE_TARGET_LINES; + if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("branches"))))) + mode |= COVERAGE_TARGET_BRANCHES; + if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("methods"))))) + mode |= COVERAGE_TARGET_METHODS; if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("oneshot_lines"))))) { if (mode & COVERAGE_TARGET_LINES) rb_raise(rb_eRuntimeError, "cannot enable lines and oneshot_lines simultaneously"); mode |= COVERAGE_TARGET_LINES; mode |= COVERAGE_TARGET_ONESHOT_LINES; } + if (RTEST(rb_hash_lookup(opt, ID2SYM(rb_intern("eval"))))) + mode |= COVERAGE_TARGET_EVAL; } if (mode & COVERAGE_TARGET_METHODS) { me2counter = rb_ident_hash_new(); } else { - me2counter = Qnil; + me2counter = Qnil; } coverages = rb_get_coverages(); if (!RTEST(coverages)) { - coverages = rb_hash_new(); - rb_obj_hide(coverages); - current_mode = mode; - if (mode == 0) mode = COVERAGE_TARGET_LINES; - rb_set_coverages(coverages, mode, me2counter); + coverages = rb_hash_new(); + rb_obj_hide(coverages); + current_mode = mode; + if (mode == 0) mode = COVERAGE_TARGET_LINES; + rb_set_coverages(coverages, mode, me2counter); + current_state = SUSPENDED; } else if (current_mode != mode) { - rb_raise(rb_eRuntimeError, "cannot change the measuring target during coverage measurement"); + rb_raise(rb_eRuntimeError, "cannot change the measuring target during coverage measurement"); } + + return Qnil; +} + +/* + * call-seq: + * Coverage.resume => nil + * + * Start/resume the coverage measurement. + * + * Caveat: Currently, only process-global coverage measurement is supported. + * You cannot measure per-thread coverage. If your process has multiple thread, + * using Coverage.resume/suspend to capture code coverage executed from only + * a limited code block, may yield misleading results. + */ +VALUE +rb_coverage_resume(VALUE klass) +{ + if (current_state == IDLE) { + rb_raise(rb_eRuntimeError, "coverage measurement is not set up yet"); + } + if (current_state == RUNNING) { + rb_raise(rb_eRuntimeError, "coverage measurement is already running"); + } + rb_resume_coverages(); + current_state = RUNNING; + return Qnil; +} + +/* + * call-seq: + * Coverage.start => nil + * Coverage.start(:all) => nil + * Coverage.start(lines: bool, branches: bool, methods: bool, eval: bool) => nil + * Coverage.start(oneshot_lines: true) => nil + * + * Enables the coverage measurement. + * See the documentation of Coverage class in detail. + * This is equivalent to Coverage.setup and Coverage.resume. + */ +static VALUE +rb_coverage_start(int argc, VALUE *argv, VALUE klass) +{ + rb_coverage_setup(argc, argv, klass); + rb_coverage_resume(klass); return Qnil; } @@ -151,51 +255,51 @@ method_coverage_i(void *vstart, void *vend, size_t stride, void *data) VALUE ncoverages = *(VALUE*)data, v; for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) { - void *poisoned = asan_poisoned_object_p(v); - asan_unpoison_object(v, false); - - if (RB_TYPE_P(v, T_IMEMO) && imemo_type(v) == imemo_ment) { - const rb_method_entry_t *me = (rb_method_entry_t *) v; - VALUE path, first_lineno, first_column, last_lineno, last_column; - VALUE data[5], ncoverage, methods; - VALUE methods_id = ID2SYM(rb_intern("methods")); - VALUE klass; - const rb_method_entry_t *me2 = rb_resolve_me_location(me, data); - if (me != me2) continue; - klass = me->owner; - if (RB_TYPE_P(klass, T_ICLASS)) { - rb_bug("T_ICLASS"); - } - path = data[0]; - first_lineno = data[1]; - first_column = data[2]; - last_lineno = data[3]; - last_column = data[4]; - if (FIX2LONG(first_lineno) <= 0) continue; - ncoverage = rb_hash_aref(ncoverages, path); - if (NIL_P(ncoverage)) continue; - methods = rb_hash_aref(ncoverage, methods_id); - - { - VALUE method_id = ID2SYM(me->def->original_id); - VALUE rcount = rb_hash_aref(me2counter, (VALUE) me); - VALUE key = rb_ary_new_from_args(6, klass, method_id, first_lineno, first_column, last_lineno, last_column); - VALUE rcount2 = rb_hash_aref(methods, key); - - if (NIL_P(rcount)) rcount = LONG2FIX(0); - if (NIL_P(rcount2)) rcount2 = LONG2FIX(0); - if (!POSFIXABLE(FIX2LONG(rcount) + FIX2LONG(rcount2))) { - rcount = LONG2FIX(FIXNUM_MAX); - } - else { - rcount = LONG2FIX(FIX2LONG(rcount) + FIX2LONG(rcount2)); - } - rb_hash_aset(methods, key, rcount); - } - } + void *poisoned = rb_asan_poisoned_object_p(v); + rb_asan_unpoison_object(v, false); + + if (RB_TYPE_P(v, T_IMEMO) && imemo_type(v) == imemo_ment) { + const rb_method_entry_t *me = (rb_method_entry_t *) v; + VALUE path, first_lineno, first_column, last_lineno, last_column; + VALUE data[5], ncoverage, methods; + VALUE methods_id = ID2SYM(rb_intern("methods")); + VALUE klass; + const rb_method_entry_t *me2 = rb_resolve_me_location(me, data); + if (me != me2) continue; + klass = me->owner; + if (RB_TYPE_P(klass, T_ICLASS)) { + rb_bug("T_ICLASS"); + } + path = data[0]; + first_lineno = data[1]; + first_column = data[2]; + last_lineno = data[3]; + last_column = data[4]; + if (FIX2LONG(first_lineno) <= 0) continue; + ncoverage = rb_hash_aref(ncoverages, path); + if (NIL_P(ncoverage)) continue; + methods = rb_hash_aref(ncoverage, methods_id); + + { + VALUE method_id = ID2SYM(me->def->original_id); + VALUE rcount = rb_hash_aref(me2counter, (VALUE) me); + VALUE key = rb_ary_new_from_args(6, klass, method_id, first_lineno, first_column, last_lineno, last_column); + VALUE rcount2 = rb_hash_aref(methods, key); + + if (NIL_P(rcount)) rcount = LONG2FIX(0); + if (NIL_P(rcount2)) rcount2 = LONG2FIX(0); + if (!POSFIXABLE(FIX2LONG(rcount) + FIX2LONG(rcount2))) { + rcount = LONG2FIX(FIXNUM_MAX); + } + else { + rcount = LONG2FIX(FIX2LONG(rcount) + FIX2LONG(rcount2)); + } + rb_hash_aset(methods, key, rcount); + } + } if (poisoned) { - asan_poison_object(v); + rb_asan_poison_object(v); } } return 0; @@ -208,32 +312,32 @@ coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h) VALUE coverage = (VALUE)val; VALUE coverages = (VALUE)h; if (current_mode == 0) { - /* compatible mode */ - VALUE lines = rb_ary_dup(RARRAY_AREF(coverage, COVERAGE_INDEX_LINES)); - rb_ary_freeze(lines); - coverage = lines; + /* compatible mode */ + VALUE lines = rb_ary_dup(RARRAY_AREF(coverage, COVERAGE_INDEX_LINES)); + rb_ary_freeze(lines); + coverage = lines; } else { - VALUE h = rb_hash_new(); + VALUE h = rb_hash_new(); - if (current_mode & COVERAGE_TARGET_LINES) { - VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES); + if (current_mode & COVERAGE_TARGET_LINES) { + VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES); const char *kw = (current_mode & COVERAGE_TARGET_ONESHOT_LINES) ? "oneshot_lines" : "lines"; - lines = rb_ary_dup(lines); - rb_ary_freeze(lines); + lines = rb_ary_dup(lines); + rb_ary_freeze(lines); rb_hash_aset(h, ID2SYM(rb_intern(kw)), lines); - } + } - if (current_mode & COVERAGE_TARGET_BRANCHES) { - VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES); - rb_hash_aset(h, ID2SYM(rb_intern("branches")), branch_coverage(branches)); - } + if (current_mode & COVERAGE_TARGET_BRANCHES) { + VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES); + rb_hash_aset(h, ID2SYM(rb_intern("branches")), branch_coverage(branches)); + } - if (current_mode & COVERAGE_TARGET_METHODS) { - rb_hash_aset(h, ID2SYM(rb_intern("methods")), rb_hash_new()); - } + if (current_mode & COVERAGE_TARGET_METHODS) { + rb_hash_aset(h, ID2SYM(rb_intern("methods")), rb_hash_new()); + } - coverage = h; + coverage = h; } rb_hash_aset(coverages, path, coverage); @@ -245,7 +349,7 @@ coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h) * Coverage.peek_result => hash * * Returns a hash that contains filename as key and coverage array as value. - * This is the same as `Coverage.result(stop: false, clear: false)`. + * This is the same as <tt>Coverage.result(stop: false, clear: false)</tt>. * * { * "file.rb" => [1, 2, nil], @@ -258,13 +362,13 @@ rb_coverage_peek_result(VALUE klass) VALUE coverages = rb_get_coverages(); VALUE ncoverages = rb_hash_new(); if (!RTEST(coverages)) { - rb_raise(rb_eRuntimeError, "coverage measurement is not enabled"); + rb_raise(rb_eRuntimeError, "coverage measurement is not enabled"); } - OBJ_WB_UNPROTECT(coverages); - st_foreach(RHASH_TBL_RAW(coverages), coverage_peek_result_i, ncoverages); + + rb_hash_foreach(coverages, coverage_peek_result_i, ncoverages); if (current_mode & COVERAGE_TARGET_METHODS) { - rb_objspace_each_objects(method_coverage_i, &ncoverages); + rb_objspace_each_objects(method_coverage_i, &ncoverages); } rb_hash_freeze(ncoverages); @@ -280,6 +384,24 @@ clear_me2counter_i(VALUE key, VALUE value, VALUE unused) } /* + * call-seq: + * Coverage.suspend => nil + * + * Suspend the coverage measurement. + * You can use Coverage.resume to restart the measurement. + */ +VALUE +rb_coverage_suspend(VALUE klass) +{ + if (current_state != RUNNING) { + rb_raise(rb_eRuntimeError, "coverage measurement is not running"); + } + rb_suspend_coverages(); + current_state = SUSPENDED; + return Qnil; +} + +/* * call-seq: * Coverage.result(stop: true, clear: true) => hash * @@ -294,6 +416,10 @@ rb_coverage_result(int argc, VALUE *argv, VALUE klass) VALUE opt; int stop = 1, clear = 1; + if (current_state == IDLE) { + rb_raise(rb_eRuntimeError, "coverage measurement is not enabled"); + } + rb_scan_args(argc, argv, "01", &opt); if (argc == 1) { @@ -312,8 +438,12 @@ rb_coverage_result(int argc, VALUE *argv, VALUE klass) if (!NIL_P(me2counter)) rb_hash_foreach(me2counter, clear_me2counter_i, Qnil); } if (stop) { + if (current_state == RUNNING) { + rb_coverage_suspend(klass); + } rb_reset_coverages(); me2counter = Qnil; + current_state = IDLE; } return ncoverages; } @@ -321,6 +451,23 @@ rb_coverage_result(int argc, VALUE *argv, VALUE klass) /* * call-seq: + * Coverage.state => :idle, :suspended, :running + * + * Returns the state of the coverage measurement. + */ +static VALUE +rb_coverage_state(VALUE klass) +{ + switch (current_state) { + case IDLE: return ID2SYM(rb_intern("idle")); + case SUSPENDED: return ID2SYM(rb_intern("suspended")); + case RUNNING: return ID2SYM(rb_intern("running")); + } + return Qnil; +} + +/* + * call-seq: * Coverage.running? => bool * * Returns true if coverage stats are currently being collected (after @@ -329,13 +476,15 @@ rb_coverage_result(int argc, VALUE *argv, VALUE klass) static VALUE rb_coverage_running(VALUE klass) { - VALUE coverages = rb_get_coverages(); - return RTEST(coverages) ? Qtrue : Qfalse; + return current_state == RUNNING ? Qtrue : Qfalse; } -/* Coverage provides coverage measurement feature for Ruby. +/* \Coverage provides coverage measurement feature for Ruby. * This feature is experimental, so these APIs may be changed in future. * + * Caveat: Currently, only process-global coverage measurement is supported. + * You cannot measure per-thread coverage. + * * = Usage * * 1. require "coverage" @@ -366,7 +515,7 @@ rb_coverage_running(VALUE klass) * require "foo.rb" * p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} * - * == Lines Coverage + * == Lines \Coverage * * If a coverage mode is not explicitly specified when starting coverage, lines * coverage is what will run. It reports the number of line executions for each @@ -386,7 +535,7 @@ rb_coverage_running(VALUE klass) * A +nil+ value means coverage is disabled for this line (lines like +else+ * and +end+). * - * == Oneshot Lines Coverage + * == Oneshot Lines \Coverage * * Oneshot lines coverage tracks and reports on the executed lines while * coverage is running. It will not report how many times a line was executed, @@ -400,7 +549,7 @@ rb_coverage_running(VALUE klass) * The value of the oneshot lines coverage result is an array containing the * line numbers that were executed. * - * == Branches Coverage + * == Branches \Coverage * * Branches coverage reports how many times each branch within each conditional * was executed. @@ -425,7 +574,7 @@ rb_coverage_running(VALUE klass) * 5. The ending line number it appears on in the file. * 6. The ending column number it appears on in the file. * - * == Methods Coverage + * == Methods \Coverage * * Methods coverage reports how many times each method was executed. * @@ -463,7 +612,63 @@ rb_coverage_running(VALUE klass) * 5. The ending line number the method appears on in the file. * 6. The ending column number the method appears on in the file. * - * == All Coverage Modes + * == Eval \Coverage + * + * Eval coverage can be combined with the coverage types above to track + * coverage for eval. + * + * require "coverage" + * Coverage.start(eval: true, lines: true) + * + * eval(<<~RUBY, nil, "eval 1") + * ary = [] + * 10.times do |i| + * ary << "hello" * i + * end + * RUBY + * + * Coverage.result # => {"eval 1" => {lines: [1, 1, 10, nil]}} + * + * Note that the eval must have a filename assigned, otherwise coverage + * will not be measured. + * + * require "coverage" + * Coverage.start(eval: true, lines: true) + * + * eval(<<~RUBY) + * ary = [] + * 10.times do |i| + * ary << "hello" * i + * end + * RUBY + * + * Coverage.result # => {"(eval)" => {lines: [nil, nil, nil, nil]}} + * + * Also note that if a line number is assigned to the eval and it is not 1, + * then the resulting coverage will be padded with +nil+ if the line number is + * greater than 1, and truncated if the line number is less than 1. + * + * require "coverage" + * Coverage.start(eval: true, lines: true) + * + * eval(<<~RUBY, nil, "eval 1", 3) + * ary = [] + * 10.times do |i| + * ary << "hello" * i + * end + * RUBY + * + * eval(<<~RUBY, nil, "eval 2", -1) + * ary = [] + * 10.times do |i| + * ary << "hello" * i + * end + * RUBY + * + * Coverage.result + * # => {"eval 1" => {lines: [nil, nil, 1, 1, 10, nil]}, "eval 2" => {lines: [10, nil]}} + * + * == All \Coverage Modes * * You can also run all modes of coverage simultaneously with this shortcut. * Note that running all coverage modes does not run both lines and oneshot @@ -480,9 +685,16 @@ void Init_coverage(void) { VALUE rb_mCoverage = rb_define_module("Coverage"); + + rb_define_singleton_method(rb_mCoverage, "supported?", rb_coverage_supported, 1); + + rb_define_module_function(rb_mCoverage, "setup", rb_coverage_setup, -1); rb_define_module_function(rb_mCoverage, "start", rb_coverage_start, -1); + rb_define_module_function(rb_mCoverage, "resume", rb_coverage_resume, 0); + rb_define_module_function(rb_mCoverage, "suspend", rb_coverage_suspend, 0); rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, -1); rb_define_module_function(rb_mCoverage, "peek_result", rb_coverage_peek_result, 0); + rb_define_module_function(rb_mCoverage, "state", rb_coverage_state, 0); rb_define_module_function(rb_mCoverage, "running?", rb_coverage_running, 0); rb_global_variable(&me2counter); } diff --git a/ext/coverage/depend b/ext/coverage/depend index 228ee7381a..fb7f9a95af 100644 --- a/ext/coverage/depend +++ b/ext/coverage/depend @@ -15,7 +15,9 @@ coverage.o: $(hdrdir)/ruby/backward/2/long_long.h coverage.o: $(hdrdir)/ruby/backward/2/stdalign.h coverage.o: $(hdrdir)/ruby/backward/2/stdarg.h coverage.o: $(hdrdir)/ruby/defines.h +coverage.o: $(hdrdir)/ruby/encoding.h coverage.o: $(hdrdir)/ruby/intern.h +coverage.o: $(hdrdir)/ruby/internal/abi.h coverage.o: $(hdrdir)/ruby/internal/anyargs.h coverage.o: $(hdrdir)/ruby/internal/arithmetic.h coverage.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +55,7 @@ coverage.o: $(hdrdir)/ruby/internal/attr/noexcept.h coverage.o: $(hdrdir)/ruby/internal/attr/noinline.h coverage.o: $(hdrdir)/ruby/internal/attr/nonnull.h coverage.o: $(hdrdir)/ruby/internal/attr/noreturn.h +coverage.o: $(hdrdir)/ruby/internal/attr/packed_struct.h coverage.o: $(hdrdir)/ruby/internal/attr/pure.h coverage.o: $(hdrdir)/ruby/internal/attr/restrict.h coverage.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -85,6 +88,15 @@ coverage.o: $(hdrdir)/ruby/internal/core/rtypeddata.h coverage.o: $(hdrdir)/ruby/internal/ctype.h coverage.o: $(hdrdir)/ruby/internal/dllexport.h coverage.o: $(hdrdir)/ruby/internal/dosish.h +coverage.o: $(hdrdir)/ruby/internal/encoding/coderange.h +coverage.o: $(hdrdir)/ruby/internal/encoding/ctype.h +coverage.o: $(hdrdir)/ruby/internal/encoding/encoding.h +coverage.o: $(hdrdir)/ruby/internal/encoding/pathname.h +coverage.o: $(hdrdir)/ruby/internal/encoding/re.h +coverage.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +coverage.o: $(hdrdir)/ruby/internal/encoding/string.h +coverage.o: $(hdrdir)/ruby/internal/encoding/symbol.h +coverage.o: $(hdrdir)/ruby/internal/encoding/transcode.h coverage.o: $(hdrdir)/ruby/internal/error.h coverage.o: $(hdrdir)/ruby/internal/eval.h coverage.o: $(hdrdir)/ruby/internal/event.h @@ -112,7 +124,6 @@ coverage.o: $(hdrdir)/ruby/internal/intern/enumerator.h coverage.o: $(hdrdir)/ruby/internal/intern/error.h coverage.o: $(hdrdir)/ruby/internal/intern/eval.h coverage.o: $(hdrdir)/ruby/internal/intern/file.h -coverage.o: $(hdrdir)/ruby/internal/intern/gc.h coverage.o: $(hdrdir)/ruby/internal/intern/hash.h coverage.o: $(hdrdir)/ruby/internal/intern/io.h coverage.o: $(hdrdir)/ruby/internal/intern/load.h @@ -129,6 +140,7 @@ coverage.o: $(hdrdir)/ruby/internal/intern/re.h coverage.o: $(hdrdir)/ruby/internal/intern/ruby.h coverage.o: $(hdrdir)/ruby/internal/intern/select.h coverage.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +coverage.o: $(hdrdir)/ruby/internal/intern/set.h coverage.o: $(hdrdir)/ruby/internal/intern/signal.h coverage.o: $(hdrdir)/ruby/internal/intern/sprintf.h coverage.o: $(hdrdir)/ruby/internal/intern/string.h @@ -143,12 +155,12 @@ coverage.o: $(hdrdir)/ruby/internal/memory.h coverage.o: $(hdrdir)/ruby/internal/method.h coverage.o: $(hdrdir)/ruby/internal/module.h coverage.o: $(hdrdir)/ruby/internal/newobj.h -coverage.o: $(hdrdir)/ruby/internal/rgengc.h coverage.o: $(hdrdir)/ruby/internal/scan_args.h coverage.o: $(hdrdir)/ruby/internal/special_consts.h coverage.o: $(hdrdir)/ruby/internal/static_assert.h coverage.o: $(hdrdir)/ruby/internal/stdalign.h coverage.o: $(hdrdir)/ruby/internal/stdbool.h +coverage.o: $(hdrdir)/ruby/internal/stdckdint.h coverage.o: $(hdrdir)/ruby/internal/symbol.h coverage.o: $(hdrdir)/ruby/internal/value.h coverage.o: $(hdrdir)/ruby/internal/value_type.h @@ -156,6 +168,8 @@ coverage.o: $(hdrdir)/ruby/internal/variable.h coverage.o: $(hdrdir)/ruby/internal/warning_push.h coverage.o: $(hdrdir)/ruby/internal/xmalloc.h coverage.o: $(hdrdir)/ruby/missing.h +coverage.o: $(hdrdir)/ruby/onigmo.h +coverage.o: $(hdrdir)/ruby/oniguruma.h coverage.o: $(hdrdir)/ruby/ruby.h coverage.o: $(hdrdir)/ruby/st.h coverage.o: $(hdrdir)/ruby/subst.h @@ -164,24 +178,30 @@ coverage.o: $(top_srcdir)/ccan/check_type/check_type.h coverage.o: $(top_srcdir)/ccan/container_of/container_of.h coverage.o: $(top_srcdir)/ccan/list/list.h coverage.o: $(top_srcdir)/ccan/str/str.h -coverage.o: $(top_srcdir)/darray.h -coverage.o: $(top_srcdir)/gc.h +coverage.o: $(top_srcdir)/constant.h +coverage.o: $(top_srcdir)/id_table.h coverage.o: $(top_srcdir)/internal.h coverage.o: $(top_srcdir)/internal/array.h +coverage.o: $(top_srcdir)/internal/basic_operators.h +coverage.o: $(top_srcdir)/internal/box.h coverage.o: $(top_srcdir)/internal/compilers.h coverage.o: $(top_srcdir)/internal/gc.h coverage.o: $(top_srcdir)/internal/hash.h coverage.o: $(top_srcdir)/internal/imemo.h coverage.o: $(top_srcdir)/internal/sanitizers.h coverage.o: $(top_srcdir)/internal/serial.h +coverage.o: $(top_srcdir)/internal/set_table.h coverage.o: $(top_srcdir)/internal/static_assert.h coverage.o: $(top_srcdir)/internal/thread.h +coverage.o: $(top_srcdir)/internal/variable.h coverage.o: $(top_srcdir)/internal/vm.h coverage.o: $(top_srcdir)/internal/warnings.h coverage.o: $(top_srcdir)/method.h coverage.o: $(top_srcdir)/node.h coverage.o: $(top_srcdir)/ruby_assert.h coverage.o: $(top_srcdir)/ruby_atomic.h +coverage.o: $(top_srcdir)/rubyparser.h +coverage.o: $(top_srcdir)/shape.h coverage.o: $(top_srcdir)/thread_pthread.h coverage.o: $(top_srcdir)/vm_core.h coverage.o: $(top_srcdir)/vm_opts.h diff --git a/ext/coverage/lib/coverage.rb b/ext/coverage/lib/coverage.rb index f1923ef366..4bd20e22cb 100644 --- a/ext/coverage/lib/coverage.rb +++ b/ext/coverage/lib/coverage.rb @@ -1,6 +1,11 @@ require "coverage.so" module Coverage + # call-seq: + # line_stub(file) -> array + # + # A simple helper function that creates the "stub" of line coverage + # from a given source code. def self.line_stub(file) lines = File.foreach(file).map { nil } iseqs = [RubyVM::InstructionSequence.compile_file(file)] diff --git a/ext/date/date.gemspec b/ext/date/date.gemspec index 88e5838d2e..cb439bd0a5 100644 --- a/ext/date/date.gemspec +++ b/ext/date/date.gemspec @@ -1,21 +1,36 @@ # frozen_string_literal: true + +version = File.foreach(File.expand_path("../lib/date.rb", __FILE__)).find do |line| + /^\s*VERSION\s*=\s*["'](.*)["']/ =~ line and break $1 +end + Gem::Specification.new do |s| s.name = "date" - s.version = '3.2.0' - s.summary = "A subclass of Object includes Comparable module for handling dates." - s.description = "A subclass of Object includes Comparable module for handling dates." + s.version = version + s.summary = "The official date library for Ruby." + s.description = "The official date library for Ruby." - s.require_path = %w{lib} - s.files = [ - "lib/date.rb", "ext/date/date_core.c", "ext/date/date_parse.c", "ext/date/date_strftime.c", - "ext/date/date_strptime.c", "ext/date/date_tmx.h", "ext/date/extconf.rb", "ext/date/prereq.mk", - "ext/date/zonetab.h", "ext/date/zonetab.list" - ] - s.extensions = "ext/date/extconf.rb" - s.required_ruby_version = ">= 2.4.0" + if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby' + s.platform = 'java' + # No files shipped, no require path, no-op for now on JRuby + else + s.require_path = %w{lib} + + s.files = [ + "README.md", "COPYING", "BSDL", + "lib/date.rb", "ext/date/date_core.c", "ext/date/date_parse.c", "ext/date/date_strftime.c", + "ext/date/date_strptime.c", "ext/date/date_tmx.h", "ext/date/extconf.rb", "ext/date/prereq.mk", + "ext/date/zonetab.h", "ext/date/zonetab.list" + ] + s.extensions = "ext/date/extconf.rb" + end + + s.required_ruby_version = ">= 2.6.0" s.authors = ["Tadayoshi Funaba"] s.email = [nil] s.homepage = "https://github.com/ruby/date" s.licenses = ["Ruby", "BSD-2-Clause"] + + s.metadata["changelog_uri"] = s.homepage + "/releases" end diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 146f60fef6..9755fb819e 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -27,6 +27,10 @@ static VALUE eDateError; static VALUE half_days_in_day, day_in_nanoseconds; static double positive_inf, negative_inf; +// used by deconstruct_keys +static VALUE sym_year, sym_month, sym_day, sym_yday, sym_wday; +static VALUE sym_hour, sym_min, sym_sec, sym_sec_fraction, sym_zone; + #define f_boolcast(x) ((x) ? Qtrue : Qfalse) #define f_abs(x) rb_funcall(x, rb_intern("abs"), 0) @@ -53,14 +57,15 @@ static double positive_inf, negative_inf; #define f_add3(x,y,z) f_add(f_add(x, y), z) #define f_sub3(x,y,z) f_sub(f_sub(x, y), z) -#define f_frozen_ary(...) rb_obj_freeze(rb_ary_new3(__VA_ARGS__)) +#define f_frozen_ary(...) rb_ary_freeze(rb_ary_new3(__VA_ARGS__)) static VALUE date_initialize(int argc, VALUE *argv, VALUE self); static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self); #define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse inline static void -check_numeric(VALUE obj, const char* field) { +check_numeric(VALUE obj, const char* field) +{ if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) { rb_raise(rb_eTypeError, "invalid %s (not numeric)", field); } @@ -243,6 +248,11 @@ f_negative_p(VALUE x) #define date_sg_t double #endif +#define JULIAN_EPOCH_DATE "-4712-01-01" +#define JULIAN_EPOCH_DATETIME JULIAN_EPOCH_DATE "T00:00:00+00:00" +#define JULIAN_EPOCH_DATETIME_RFC3339 "Mon, 1 Jan -4712 00:00:00 +0000" +#define JULIAN_EPOCH_DATETIME_HTTPDATE "Mon, 01 Jan -4712 00:00:00 GMT" + /* A set of nth, jd, df and sf denote ajd + 1/2. Each ajd begin at * noon of GMT (assume equal to UTC). However, this begins at * midnight. @@ -442,11 +452,43 @@ do {\ static int c_valid_civil_p(int, int, int, double, int *, int *, int *, int *); +/* Check if using pure Gregorian calendar (sg == -Infinity) */ +#define c_gregorian_only_p(sg) (isinf(sg) && (sg) < 0) + +/* + * Fast path macros for pure Gregorian calendar. + * Sets *rjd to the JD value, *ns to 1 (new style), and returns. + */ +#define GREGORIAN_JD_FAST_PATH_RET(sg, jd_expr, rjd, ns) \ + if (c_gregorian_only_p(sg)) { \ + *(rjd) = (jd_expr); \ + *(ns) = 1; \ + return 1; \ + } + +#define GREGORIAN_JD_FAST_PATH(sg, jd_expr, rjd, ns) \ + if (c_gregorian_only_p(sg)) { \ + *(rjd) = (jd_expr); \ + *(ns) = 1; \ + return; \ + } + +/* Forward declarations for Neri-Schneider optimized functions */ +static int c_gregorian_civil_to_jd(int y, int m, int d); +static void c_gregorian_jd_to_civil(int jd, int *ry, int *rm, int *rd); +static int c_gregorian_fdoy(int y); +static int c_gregorian_ldoy(int y); +static int c_gregorian_ldom_jd(int y, int m); +static int ns_jd_in_range(int jd); + static int c_find_fdoy(int y, double sg, int *rjd, int *ns) { int d, rm, rd; + GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_fdoy(y), rjd, ns); + + /* Keep existing loop for Julian/reform period */ for (d = 1; d < 31; d++) if (c_valid_civil_p(y, 1, d, sg, &rm, &rd, rjd, ns)) return 1; @@ -458,6 +500,9 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns) { int i, rm, rd; + GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_ldoy(y), rjd, ns); + + /* Keep existing loop for Julian/reform period */ for (i = 0; i < 30; i++) if (c_valid_civil_p(y, 12, 31 - i, sg, &rm, &rd, rjd, ns)) return 1; @@ -465,6 +510,7 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns) } #ifndef NDEBUG +/* :nodoc: */ static int c_find_fdom(int y, int m, double sg, int *rjd, int *ns) { @@ -482,6 +528,9 @@ c_find_ldom(int y, int m, double sg, int *rjd, int *ns) { int i, rm, rd; + GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_ldom_jd(y, m), rjd, ns); + + /* Keep existing loop for Julian/reform period */ for (i = 0; i < 30; i++) if (c_valid_civil_p(y, m, 31 - i, sg, &rm, &rd, rjd, ns)) return 1; @@ -491,55 +540,69 @@ c_find_ldom(int y, int m, double sg, int *rjd, int *ns) static void c_civil_to_jd(int y, int m, int d, double sg, int *rjd, int *ns) { - double a, b, jd; + int jd; + + GREGORIAN_JD_FAST_PATH(sg, c_gregorian_civil_to_jd(y, m, d), rjd, ns); + + /* Calculate Gregorian JD using optimized algorithm */ + jd = c_gregorian_civil_to_jd(y, m, d); - if (m <= 2) { - y -= 1; - m += 12; - } - a = floor(y / 100.0); - b = 2 - a + floor(a / 4.0); - jd = floor(365.25 * (y + 4716)) + - floor(30.6001 * (m + 1)) + - d + b - 1524; if (jd < sg) { - jd -= b; + /* Before Gregorian switchover - use Julian calendar */ + int y2 = y, m2 = m; + if (m2 <= 2) { + y2 -= 1; + m2 += 12; + } + jd = (int)(floor(365.25 * (y2 + 4716)) + + floor(30.6001 * (m2 + 1)) + + d - 1524); *ns = 0; } - else + else { *ns = 1; + } - *rjd = (int)jd; + *rjd = jd; } static void c_jd_to_civil(int jd, double sg, int *ry, int *rm, int *rdom) { - double x, a, b, c, d, e, y, m, dom; - - if (jd < sg) - a = jd; - else { - x = floor((jd - 1867216.25) / 36524.25); - a = jd + 1 + x - floor(x / 4.0); - } - b = a + 1524; - c = floor((b - 122.1) / 365.25); - d = floor(365.25 * c); - e = floor((b - d) / 30.6001); - dom = b - d - floor(30.6001 * e); - if (e <= 13) { - m = e - 1; - y = c - 4716; - } - else { - m = e - 13; - y = c - 4715; + /* Fast path: pure Gregorian or date after switchover, within safe range */ + if ((c_gregorian_only_p(sg) || jd >= sg) && ns_jd_in_range(jd)) { + c_gregorian_jd_to_civil(jd, ry, rm, rdom); + return; } - *ry = (int)y; - *rm = (int)m; - *rdom = (int)dom; + /* Original algorithm for Julian calendar or extreme dates */ + { + double x, a, b, c, d, e, y, m, dom; + + if (jd < sg) + a = jd; + else { + x = floor((jd - 1867216.25) / 36524.25); + a = jd + 1 + x - floor(x / 4.0); + } + b = a + 1524; + c = floor((b - 122.1) / 365.25); + d = floor(365.25 * c); + e = floor((b - d) / 30.6001); + dom = b - d - floor(30.6001 * e); + if (e <= 13) { + m = e - 1; + y = c - 4716; + } + else { + m = e - 13; + y = c - 4715; + } + + *ry = (int)y; + *rm = (int)m; + *rdom = (int)dom; + } } static void @@ -621,6 +684,7 @@ c_jd_to_weeknum(int jd, int f, double sg, int *ry, int *rw, int *rd) } #ifndef NDEBUG +/* :nodoc: */ static void c_nth_kday_to_jd(int y, int m, int n, int k, double sg, int *rjd, int *ns) { @@ -646,6 +710,7 @@ c_jd_to_wday(int jd) } #ifndef NDEBUG +/* :nodoc: */ static void c_jd_to_nth_kday(int jd, double sg, int *ry, int *rm, int *rn, int *rk) { @@ -712,6 +777,147 @@ c_gregorian_last_day_of_month(int y, int m) return monthtab[c_gregorian_leap_p(y) ? 1 : 0][m]; } +/* + * Neri-Schneider algorithm for optimized Gregorian date conversion. + * Reference: Neri & Schneider, "Euclidean Affine Functions and Applications + * to Calendar Algorithms", Software: Practice and Experience, 2023. + * https://arxiv.org/abs/2102.06959 + * + * This algorithm provides ~2-3x speedup over traditional floating-point + * implementations by using pure integer arithmetic with multiplication + * and bit-shifts instead of expensive division operations. + */ + +/* JDN of March 1, Year 0 in proleptic Gregorian calendar */ +#define NS_EPOCH 1721120 + +/* Days in a 4-year cycle (3 normal years + 1 leap year) */ +#define NS_DAYS_IN_4_YEARS 1461 + +/* Days in a 400-year Gregorian cycle (97 leap years in 400 years) */ +#define NS_DAYS_IN_400_YEARS 146097 + +/* Years per century */ +#define NS_YEARS_PER_CENTURY 100 + +/* + * Multiplier for extracting year within century using fixed-point arithmetic. + * This is ceil(2^32 / NS_DAYS_IN_4_YEARS) for the Euclidean affine function. + */ +#define NS_YEAR_MULTIPLIER 2939745 + +/* + * Coefficients for month calculation from day-of-year. + * Maps day-of-year to month using: month = (NS_MONTH_COEFF * doy + NS_MONTH_OFFSET) >> 16 + */ +#define NS_MONTH_COEFF 2141 +#define NS_MONTH_OFFSET 197913 + +/* + * Coefficients for civil date to JDN month contribution. + * Maps month to accumulated days: days = (NS_CIVIL_MONTH_COEFF * m - NS_CIVIL_MONTH_OFFSET) / 32 + */ +#define NS_CIVIL_MONTH_COEFF 979 +#define NS_CIVIL_MONTH_OFFSET 2919 +#define NS_CIVIL_MONTH_DIVISOR 32 + +/* Days from March 1 to December 31 (for Jan/Feb year adjustment) */ +#define NS_DAYS_BEFORE_NEW_YEAR 306 + +/* + * Safe bounds for Neri-Schneider algorithm to avoid integer overflow. + * These correspond to approximately years -1,000,000 to +1,000,000. + */ +#define NS_JD_MIN -364000000 +#define NS_JD_MAX 538000000 + +inline static int +ns_jd_in_range(int jd) +{ + return jd >= NS_JD_MIN && jd <= NS_JD_MAX; +} + +/* Optimized: Gregorian date -> Julian Day Number */ +static int +c_gregorian_civil_to_jd(int y, int m, int d) +{ + /* Shift epoch to March 1 of year 0 (Jan/Feb belong to previous year) */ + int j = (m < 3) ? 1 : 0; + int y0 = y - j; + int m0 = j ? m + 12 : m; + int d0 = d - 1; + + /* Calculate year contribution with leap year correction */ + int q1 = DIV(y0, NS_YEARS_PER_CENTURY); + int yc = DIV(NS_DAYS_IN_4_YEARS * y0, 4) - q1 + DIV(q1, 4); + + /* Calculate month contribution using integer arithmetic */ + int mc = (NS_CIVIL_MONTH_COEFF * m0 - NS_CIVIL_MONTH_OFFSET) / NS_CIVIL_MONTH_DIVISOR; + + /* Combine and add epoch offset to get JDN */ + return yc + mc + d0 + NS_EPOCH; +} + +/* Optimized: Julian Day Number -> Gregorian date */ +static void +c_gregorian_jd_to_civil(int jd, int *ry, int *rm, int *rd) +{ + int r0, n1, q1, r1, n2, q2, r2, n3, q3, r3, y0, j; + uint64_t u2; + + /* Convert JDN to rata die (March 1, Year 0 epoch) */ + r0 = jd - NS_EPOCH; + + /* Extract century and day within 400-year cycle */ + /* Use Euclidean (floor) division for negative values */ + n1 = 4 * r0 + 3; + q1 = DIV(n1, NS_DAYS_IN_400_YEARS); + r1 = MOD(n1, NS_DAYS_IN_400_YEARS) / 4; + + /* Calculate year within century and day of year */ + n2 = 4 * r1 + 3; + /* Use 64-bit arithmetic to avoid overflow */ + u2 = (uint64_t)NS_YEAR_MULTIPLIER * (uint64_t)n2; + q2 = (int)(u2 >> 32); + r2 = (int)((uint32_t)u2 / NS_YEAR_MULTIPLIER / 4); + + /* Calculate month and day using integer arithmetic */ + n3 = NS_MONTH_COEFF * r2 + NS_MONTH_OFFSET; + q3 = n3 >> 16; + r3 = (n3 & 0xFFFF) / NS_MONTH_COEFF; + + /* Combine century and year */ + y0 = NS_YEARS_PER_CENTURY * q1 + q2; + + /* Adjust for January/February (shift from fiscal year) */ + j = (r2 >= NS_DAYS_BEFORE_NEW_YEAR) ? 1 : 0; + + *ry = y0 + j; + *rm = j ? q3 - 12 : q3; + *rd = r3 + 1; +} + +/* O(1) first day of year for Gregorian calendar */ +inline static int +c_gregorian_fdoy(int y) +{ + return c_gregorian_civil_to_jd(y, 1, 1); +} + +/* O(1) last day of year for Gregorian calendar */ +inline static int +c_gregorian_ldoy(int y) +{ + return c_gregorian_civil_to_jd(y, 12, 31); +} + +/* O(1) last day of month (JDN) for Gregorian calendar */ +inline static int +c_gregorian_ldom_jd(int y, int m) +{ + return c_gregorian_civil_to_jd(y, m, c_gregorian_last_day_of_month(y, m)); +} + static int c_valid_julian_p(int y, int m, int d, int *rm, int *rd) { @@ -758,6 +964,8 @@ c_valid_civil_p(int y, int m, int d, double sg, if (m < 0) m += 13; + if (m < 1 || m > 12) + return 0; if (d < 0) { if (!c_find_ldom(y, m, sg, rjd, ns)) return 0; @@ -822,6 +1030,7 @@ c_valid_weeknum_p(int y, int w, int d, int f, double sg, } #ifndef NDEBUG +/* :nodoc: */ static int c_valid_nth_kday_p(int y, int m, int n, int k, double sg, int *rm, int *rn, int *rk, int *rjd, int *ns) @@ -963,6 +1172,7 @@ ns_to_day(VALUE n) } #ifndef NDEBUG +/* :nodoc: */ static VALUE ms_to_sec(VALUE m) { @@ -981,6 +1191,7 @@ ns_to_sec(VALUE n) } #ifndef NDEBUG +/* :nodoc: */ inline static VALUE ins_to_day(int n) { @@ -1016,6 +1227,7 @@ day_to_sec(VALUE d) } #ifndef NDEBUG +/* :nodoc: */ static VALUE day_to_ns(VALUE d) { @@ -1040,6 +1252,7 @@ sec_to_ns(VALUE s) } #ifndef NDEBUG +/* :nodoc: */ static VALUE isec_to_ns(int s) { @@ -1066,6 +1279,7 @@ div_df(VALUE d, VALUE *f) } #ifndef NDEBUG +/* :nodoc: */ static VALUE div_sf(VALUE s, VALUE *f) { @@ -1500,6 +1714,7 @@ m_df(union DateData *x) } #ifndef NDEBUG +/* :nodoc: */ static VALUE m_df_in_day(union DateData *x) { @@ -1577,7 +1792,7 @@ m_ajd(union DateData *x) if (simple_dat_p(x)) { r = m_real_jd(x); - if (FIXNUM_P(r) && FIX2LONG(r) <= (FIXNUM_MAX / 2)) { + if (FIXNUM_P(r) && FIX2LONG(r) <= (FIXNUM_MAX / 2) && FIX2LONG(r) >= (FIXNUM_MIN + 1) / 2) { long ir = FIX2LONG(r); ir = ir * 2 - 1; return rb_rational_new2(LONG2FIX(ir), INT2FIX(2)); @@ -1997,6 +2212,7 @@ expect_numeric(VALUE x) } #ifndef NDEBUG +/* :nodoc: */ static void civil_to_jd(VALUE y, int m, int d, double sg, VALUE *nth, int *ry, @@ -2309,6 +2525,7 @@ valid_weeknum_p(VALUE y, int w, int d, int f, double sg, } #ifndef NDEBUG +/* :nodoc: */ static int valid_nth_kday_p(VALUE y, int m, int n, int k, double sg, VALUE *nth, int *ry, @@ -2446,6 +2663,7 @@ valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass) { @@ -2466,13 +2684,16 @@ date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.valid_jd?(jd[, start=Date::ITALY]) -> bool + * Date.valid_jd?(jd, start = Date::ITALY) -> true * - * Just returns true. It's nonsense, but is for symmetry. + * Implemented for compatibility; + * returns +true+ unless +jd+ is invalid (i.e., not a Numeric). * - * Date.valid_jd?(2451944) #=> true + * Date.valid_jd?(2451944) # => true * - * See also ::jd. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd. */ static VALUE date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass) @@ -2532,6 +2753,7 @@ valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass) { @@ -2554,18 +2776,18 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.valid_civil?(year, month, mday[, start=Date::ITALY]) -> bool - * Date.valid_date?(year, month, mday[, start=Date::ITALY]) -> bool + * Date.valid_civil?(year, month, mday, start = Date::ITALY) -> true or false * - * Returns true if the given calendar date is valid, and false if not. - * Valid in this context is whether the arguments passed to this - * method would be accepted by ::new. + * Returns +true+ if the arguments define a valid ordinal date, + * +false+ otherwise: * - * Date.valid_date?(2001,2,3) #=> true - * Date.valid_date?(2001,2,29) #=> false - * Date.valid_date?(2001,2,-1) #=> true + * Date.valid_date?(2001, 2, 3) # => true + * Date.valid_date?(2001, 2, 29) # => false + * Date.valid_date?(2001, 2, -1) # => true * - * See also ::jd and ::civil. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new. */ static VALUE date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass) @@ -2621,6 +2843,7 @@ valid_ordinal_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass) { @@ -2642,14 +2865,17 @@ date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.valid_ordinal?(year, yday[, start=Date::ITALY]) -> bool + * Date.valid_ordinal?(year, yday, start = Date::ITALY) -> true or false * - * Returns true if the given ordinal date is valid, and false if not. + * Returns +true+ if the arguments define a valid ordinal date, + * +false+ otherwise: * - * Date.valid_ordinal?(2001,34) #=> true - * Date.valid_ordinal?(2001,366) #=> false + * Date.valid_ordinal?(2001, 34) # => true + * Date.valid_ordinal?(2001, 366) # => false * - * See also ::jd and ::ordinal. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.ordinal. */ static VALUE date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass) @@ -2704,6 +2930,7 @@ valid_commercial_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass) { @@ -2726,14 +2953,19 @@ date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.valid_commercial?(cwyear, cweek, cwday[, start=Date::ITALY]) -> bool + * Date.valid_commercial?(cwyear, cweek, cwday, start = Date::ITALY) -> true or false + * + * Returns +true+ if the arguments define a valid commercial date, + * +false+ otherwise: + * + * Date.valid_commercial?(2001, 5, 6) # => true + * Date.valid_commercial?(2001, 5, 8) # => false * - * Returns true if the given week date is valid, and false if not. + * See Date.commercial. * - * Date.valid_commercial?(2001,5,6) #=> true - * Date.valid_commercial?(2001,5,8) #=> false + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. * - * See also ::jd and ::commercial. + * Related: Date.jd, Date.commercial. */ static VALUE date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass) @@ -2760,6 +2992,7 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd) { @@ -2791,6 +3024,7 @@ valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } } +/* :nodoc: */ static VALUE date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass) { @@ -2811,6 +3045,7 @@ date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass) return valid_weeknum_sub(5, argv2, klass, 1); } +/* :nodoc: */ static VALUE date_s_valid_weeknum_p(int argc, VALUE *argv, VALUE klass) { @@ -2862,6 +3097,7 @@ valid_nth_kday_sub(int argc, VALUE *argv, VALUE klass, int need_jd) } } +/* :nodoc: */ static VALUE date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) { @@ -2882,6 +3118,7 @@ date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) return valid_nth_kday_sub(5, argv2, klass, 1); } +/* :nodoc: */ static VALUE date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) { @@ -2904,6 +3141,7 @@ date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) return Qtrue; } +/* :nodoc: */ static VALUE date_s_zone_to_diff(VALUE klass, VALUE str) { @@ -2913,13 +3151,15 @@ date_s_zone_to_diff(VALUE klass, VALUE str) /* * call-seq: - * Date.julian_leap?(year) -> bool + * Date.julian_leap?(year) -> true or false + * + * Returns +true+ if the given year is a leap year + * in the {proleptic Julian calendar}[https://en.wikipedia.org/wiki/Proleptic_Julian_calendar], +false+ otherwise: * - * Returns true if the given year is a leap year of the proleptic - * Julian calendar. + * Date.julian_leap?(1900) # => true + * Date.julian_leap?(1901) # => false * - * Date.julian_leap?(1900) #=> true - * Date.julian_leap?(1901) #=> false + * Related: Date.gregorian_leap?. */ static VALUE date_s_julian_leap_p(VALUE klass, VALUE y) @@ -2934,14 +3174,15 @@ date_s_julian_leap_p(VALUE klass, VALUE y) /* * call-seq: - * Date.gregorian_leap?(year) -> bool - * Date.leap?(year) -> bool + * Date.gregorian_leap?(year) -> true or false * - * Returns true if the given year is a leap year of the proleptic - * Gregorian calendar. + * Returns +true+ if the given year is a leap year + * in the {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar], +false+ otherwise: * - * Date.gregorian_leap?(1900) #=> false - * Date.gregorian_leap?(2000) #=> true + * Date.gregorian_leap?(2000) # => true + * Date.gregorian_leap?(2001) # => false + * + * Related: Date.julian_leap?. */ static VALUE date_s_gregorian_leap_p(VALUE klass, VALUE y) @@ -3094,6 +3335,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg, } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s_new_bang(int argc, VALUE *argv, VALUE klass) { @@ -3281,16 +3523,29 @@ static VALUE d_lite_plus(VALUE, VALUE); /* * call-seq: - * Date.jd([jd=0[, start=Date::ITALY]]) -> date + * Date.jd(jd = 0, start = Date::ITALY) -> date + * + * Returns a new \Date object formed from the arguments: + * + * Date.jd(2451944).to_s # => "2001-02-03" + * Date.jd(2451945).to_s # => "2001-02-04" + * Date.jd(0).to_s # => "-4712-01-01" + * + * The returned date is: + * + * - Gregorian, if the argument is greater than or equal to +start+: + * + * Date::ITALY # => 2299161 + * Date.jd(Date::ITALY).gregorian? # => true + * Date.jd(Date::ITALY + 1).gregorian? # => true + * + * - Julian, otherwise * - * Creates a date object denoting the given chronological Julian day - * number. + * Date.jd(Date::ITALY - 1).julian? # => true * - * Date.jd(2451944) #=> #<Date: 2001-02-03 ...> - * Date.jd(2451945) #=> #<Date: 2001-02-04 ...> - * Date.jd(0) #=> #<Date: -4712-01-01 ...> + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. * - * See also ::new. + * Related: Date.new. */ static VALUE date_s_jd(int argc, VALUE *argv, VALUE klass) @@ -3329,19 +3584,33 @@ date_s_jd(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.ordinal([year=-4712[, yday=1[, start=Date::ITALY]]]) -> date + * Date.ordinal(year = -4712, yday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object formed fom the arguments. + * + * With no arguments, returns the date for January 1, -4712: + * + * Date.ordinal.to_s # => "-4712-01-01" + * + * With argument +year+, returns the date for January 1 of that year: + * + * Date.ordinal(2001).to_s # => "2001-01-01" + * Date.ordinal(-2001).to_s # => "-2001-01-01" + * + * With positive argument +yday+ == +n+, + * returns the date for the +nth+ day of the given year: + * + * Date.ordinal(2001, 14).to_s # => "2001-01-14" * - * Creates a date object denoting the given ordinal date. + * With negative argument +yday+, counts backward from the end of the year: * - * The day of year should be a negative or a positive number (as a - * relative day from the end of year when negative). It should not be - * zero. + * Date.ordinal(2001, -14).to_s # => "2001-12-18" * - * Date.ordinal(2001) #=> #<Date: 2001-01-01 ...> - * Date.ordinal(2001,34) #=> #<Date: 2001-02-03 ...> - * Date.ordinal(2001,-1) #=> #<Date: 2001-12-31 ...> + * Raises an exception if +yday+ is zero or out of range. * - * See also ::jd and ::new. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new. */ static VALUE date_s_ordinal(int argc, VALUE *argv, VALUE klass) @@ -3389,29 +3658,7 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass) } /* - * call-seq: - * Date.civil([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) -> date - * Date.new([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) -> date - * - * Creates a date object denoting the given calendar date. - * - * In this class, BCE years are counted astronomically. Thus, the - * year before the year 1 is the year zero, and the year preceding the - * year zero is the year -1. The month and the day of month should be - * a negative or a positive number (as a relative month/day from the - * end of year/month when negative). They should not be zero. - * - * The last argument should be a Julian day number which denotes the - * day of calendar reform. Date::ITALY (2299161=1582-10-15), - * Date::ENGLAND (2361222=1752-09-14), Date::GREGORIAN (the proleptic - * Gregorian calendar) and Date::JULIAN (the proleptic Julian - * calendar) can be specified as a day of calendar reform. - * - * Date.new(2001) #=> #<Date: 2001-01-01 ...> - * Date.new(2001,2,3) #=> #<Date: 2001-02-03 ...> - * Date.new(2001,2,-1) #=> #<Date: 2001-02-28 ...> - * - * See also ::jd. + * Same as Date.new. */ static VALUE date_s_civil(int argc, VALUE *argv, VALUE klass) @@ -3419,6 +3666,29 @@ date_s_civil(int argc, VALUE *argv, VALUE klass) return date_initialize(argc, argv, d_lite_s_alloc_simple(klass)); } +/* + * call-seq: + * Date.new(year = -4712, month = 1, mday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the given arguments: + * + * Date.new(2022).to_s # => "2022-01-01" + * Date.new(2022, 2).to_s # => "2022-02-01" + * Date.new(2022, 2, 4).to_s # => "2022-02-04" + * + * Argument +month+ should be in range (1..12) or range (-12..-1); + * when the argument is negative, counts backward from the end of the year: + * + * Date.new(2022, -11, 4).to_s # => "2022-02-04" + * + * Argument +mday+ should be in range (1..n) or range (-n..-1) + * where +n+ is the number of days in the month; + * when the argument is negative, counts backward from the end of the month. + * + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd. + */ static VALUE date_initialize(int argc, VALUE *argv, VALUE self) { @@ -3483,19 +3753,47 @@ date_initialize(int argc, VALUE *argv, VALUE self) /* * call-seq: - * Date.commercial([cwyear=-4712[, cweek=1[, cwday=1[, start=Date::ITALY]]]]) -> date + * Date.commercial(cwyear = -4712, cweek = 1, cwday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the arguments. + * + * Argument +cwyear+ gives the year, and should be an integer. + * + * Argument +cweek+ gives the index of the week within the year, + * and should be in range (1..53) or (-53..-1); + * in some years, 53 or -53 will be out-of-range; + * if negative, counts backward from the end of the year: + * + * Date.commercial(2022, 1, 1).to_s # => "2022-01-03" + * Date.commercial(2022, 52, 1).to_s # => "2022-12-26" + * + * Argument +cwday+ gives the indes of the weekday within the week, + * and should be in range (1..7) or (-7..-1); + * 1 or -7 is Monday; + * if negative, counts backward from the end of the week: + * + * Date.commercial(2022, 1, 1).to_s # => "2022-01-03" + * Date.commercial(2022, 1, -7).to_s # => "2022-01-03" * - * Creates a date object denoting the given week date. + * When +cweek+ is 1: * - * The week and the day of week should be a negative or a positive - * number (as a relative week/day from the end of year/week when - * negative). They should not be zero. + * - If January 1 is a Friday, Saturday, or Sunday, + * the first week begins in the week after: * - * Date.commercial(2001) #=> #<Date: 2001-01-01 ...> - * Date.commercial(2002) #=> #<Date: 2001-12-31 ...> - * Date.commercial(2001,5,6) #=> #<Date: 2001-02-03 ...> + * Date::ABBR_DAYNAMES[Date.new(2023, 1, 1).wday] # => "Sun" + * Date.commercial(2023, 1, 1).to_s # => "2023-01-02" + Date.commercial(2023, 1, 7).to_s # => "2023-01-08" * - * See also ::jd and ::new. + * - Otherwise, the first week is the week of January 1, + * which may mean some of the days fall on the year before: + * + * Date::ABBR_DAYNAMES[Date.new(2020, 1, 1).wday] # => "Wed" + * Date.commercial(2020, 1, 1).to_s # => "2019-12-30" + Date.commercial(2020, 1, 7).to_s # => "2020-01-05" + * + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new, Date.ordinal. */ static VALUE date_s_commercial(int argc, VALUE *argv, VALUE klass) @@ -3547,6 +3845,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE date_s_weeknum(int argc, VALUE *argv, VALUE klass) { @@ -3596,6 +3895,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass) return ret; } +/* :nodoc: */ static VALUE date_s_nth_kday(int argc, VALUE *argv, VALUE klass) { @@ -3670,11 +3970,14 @@ static void set_sg(union DateData *, double); /* * call-seq: - * Date.today([start=Date::ITALY]) -> date + * Date.today(start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the present date: + * + * Date.today.to_s # => "2022-07-06" * - * Creates a date object denoting the present day. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. * - * Date.today #=> #<Date: 2011-06-11 ...> */ static VALUE date_s_today(int argc, VALUE *argv, VALUE klass) @@ -3768,7 +4071,6 @@ static VALUE rt_complete_frags(VALUE klass, VALUE hash) { static VALUE tab = Qnil; - int g; long e; VALUE k, a, d; @@ -3865,9 +4167,13 @@ rt_complete_frags(VALUE klass, VALUE hash) rb_gc_register_mark_object(tab); } + k = a = Qnil; + { - long i, eno = 0, idx = 0; + long i, eno = 0; + VALUE t = Qnil; + e = 0; for (i = 0; i < RARRAY_LEN(tab); i++) { VALUE x, a; @@ -3882,23 +4188,20 @@ rt_complete_frags(VALUE klass, VALUE hash) n++; if (n > eno) { eno = n; - idx = i; + t = x; } } } - if (eno == 0) - g = 0; - else { - g = 1; - k = RARRAY_AREF(RARRAY_AREF(tab, idx), 0); - a = RARRAY_AREF(RARRAY_AREF(tab, idx), 1); - e = eno; + if (eno > 0) { + k = RARRAY_AREF(t, 0); + a = RARRAY_AREF(t, 1); } + e = eno; } d = Qnil; - if (g && !NIL_P(k) && (RARRAY_LEN(a) - e)) { + if (!NIL_P(k) && (RARRAY_LEN(a) > e)) { if (k == sym("ordinal")) { if (NIL_P(ref_hash("year"))) { if (NIL_P(d)) @@ -3985,7 +4288,7 @@ rt_complete_frags(VALUE klass, VALUE hash) } } - if (g && k == sym("time")) { + if (k == sym("time")) { if (f_le_p(klass, cDateTime)) { if (NIL_P(d)) d = date_s_today(0, (VALUE *)0, cDate); @@ -4265,16 +4568,20 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass, /* * call-seq: - * Date._strptime(string[, format='%F']) -> hash + * Date._strptime(string, format = '%F') -> hash * - * Parses the given representation of date and time with the given - * template, and returns a hash of parsed elements. _strptime does - * not support specification of flags and width unlike strftime. + * Returns a hash of values parsed from +string+ + * according to the given +format+: * - * Date._strptime('2001-02-03', '%Y-%m-%d') - * #=> {:year=>2001, :mon=>2, :mday=>3} + * Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3} * - * See also strptime(3) and #strftime. + * For other formats, see + * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]. + * (Unlike Date.strftime, does not support flags and width.) + * + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date.strptime (returns a \Date object). */ static VALUE date_s__strptime(int argc, VALUE *argv, VALUE klass) @@ -4284,21 +4591,28 @@ date_s__strptime(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.strptime([string='-4712-01-01'[, format='%F'[, start=Date::ITALY]]]) -> date + * Date.strptime(string = '-4712-01-01', format = '%F', start = Date::ITALY) -> date * - * Parses the given representation of date and time with the given - * template, and creates a date object. strptime does not support - * specification of flags and width unlike strftime. + * Returns a new \Date object with values parsed from +string+, + * according to the given +format+: * - * Date.strptime('2001-02-03', '%Y-%m-%d') #=> #<Date: 2001-02-03 ...> - * Date.strptime('03-02-2001', '%d-%m-%Y') #=> #<Date: 2001-02-03 ...> - * Date.strptime('2001-034', '%Y-%j') #=> #<Date: 2001-02-03 ...> - * Date.strptime('2001-W05-6', '%G-W%V-%u') #=> #<Date: 2001-02-03 ...> - * Date.strptime('2001 04 6', '%Y %U %w') #=> #<Date: 2001-02-03 ...> - * Date.strptime('2001 05 6', '%Y %W %u') #=> #<Date: 2001-02-03 ...> - * Date.strptime('sat3feb01', '%a%d%b%y') #=> #<Date: 2001-02-03 ...> + * Date.strptime('2001-02-03', '%Y-%m-%d') # => #<Date: 2001-02-03> + * Date.strptime('03-02-2001', '%d-%m-%Y') # => #<Date: 2001-02-03> + * Date.strptime('2001-034', '%Y-%j') # => #<Date: 2001-02-03> + * Date.strptime('2001-W05-6', '%G-W%V-%u') # => #<Date: 2001-02-03> + * Date.strptime('2001 04 6', '%Y %U %w') # => #<Date: 2001-02-03> + * Date.strptime('2001 05 6', '%Y %W %u') # => #<Date: 2001-02-03> + * Date.strptime('sat3feb01', '%a%d%b%y') # => #<Date: 2001-02-03> * - * See also strptime(3) and #strftime. + * For other formats, see + * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]. + * (Unlike Date.strftime, does not support flags and width.) + * + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date._strptime (returns a hash). */ static VALUE date_s_strptime(int argc, VALUE *argv, VALUE klass) @@ -4309,7 +4623,7 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass) switch (argc) { case 0: - str = rb_str_new2("-4712-01-01"); + str = rb_str_new2(JULIAN_EPOCH_DATE); case 1: fmt = rb_str_new2("%F"); case 2: @@ -4328,13 +4642,42 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass) VALUE date__parse(VALUE str, VALUE comp); +static size_t +get_limit(VALUE opt) +{ + if (!NIL_P(opt)) { + VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit"))); + if (NIL_P(limit)) return SIZE_MAX; + return NUM2SIZET(limit); + } + return 128; +} + +#ifndef HAVE_RB_CATEGORY_WARN +#define rb_category_warn(category, fmt) rb_warn(fmt) +#endif + +static VALUE +check_limit(VALUE str, VALUE opt) +{ + size_t slen, limit; + StringValue(str); + slen = RSTRING_LEN(str); + limit = get_limit(opt); + if (slen > limit) { + rb_raise(rb_eArgError, + "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit); + } + return str; +} + static VALUE date_s__parse_internal(int argc, VALUE *argv, VALUE klass) { - VALUE vstr, vcomp, hash; + VALUE vstr, vcomp, hash, opt; - rb_scan_args(argc, argv, "11", &vstr, &vcomp); - StringValue(vstr); + argc = rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt); + vstr = check_limit(vstr, opt); if (!rb_enc_str_asciicompat_p(vstr)) rb_raise(rb_eArgError, "string should have ASCII compatible encoding"); @@ -4348,21 +4691,32 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date._parse(string[, comp=true]) -> hash + * Date._parse(string, comp = true, limit: 128) -> hash * - * Parses the given representation of date and time, and returns a - * hash of parsed elements. + * <b>Note</b>: + * This method recognizes many forms in +string+, + * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings] * - * This method *does not* function as a validator. If the input - * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `Date._strptime` or - * `DateTime._strptime` instead of this method as possible. + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. * - * If the optional second argument is true and the detected year is in - * the range "00" to "99", considers the year a 2-digit form and makes - * it full. + * Returns a hash of values parsed from +string+: + * + * Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3} + * + * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>, + * the current century is supplied; + * otherwise, the year is taken as given: + * + * Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3} + * Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3} * - * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3} + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.parse(returns a \Date object). */ static VALUE date_s__parse(int argc, VALUE *argv, VALUE klass) @@ -4372,34 +4726,47 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date + * Date.parse(string = '-4712-01-01', comp = true, start = Date::ITALY, limit: 128) -> date * - * Parses the given representation of date and time, and creates a - * date object. + * <b>Note</b>: + * This method recognizes many forms in +string+, + * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings] + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. * - * This method *does not* function as a validator. If the input - * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `Date.strptime` instead of this - * method as possible. + * Returns a new \Date object with values parsed from +string+: * - * If the optional second argument is true and the detected year is in - * the range "00" to "99", considers the year a 2-digit form and makes - * it full. + * Date.parse('2001-02-03') # => #<Date: 2001-02-03> + * Date.parse('20010203') # => #<Date: 2001-02-03> + * Date.parse('3rd Feb 2001') # => #<Date: 2001-02-03> + * + * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>, + * the current century is supplied; + * otherwise, the year is taken as given: + * + * Date.parse('01-02-03', true) # => #<Date: 2001-02-03> + * Date.parse('01-02-03', false) # => #<Date: 0001-02-03> + * + * See: * - * Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...> - * Date.parse('20010203') #=> #<Date: 2001-02-03 ...> - * Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...> + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._parse (returns a hash). */ static VALUE date_s_parse(int argc, VALUE *argv, VALUE klass) { - VALUE str, comp, sg; + VALUE str, comp, sg, opt; - rb_scan_args(argc, argv, "03", &str, &comp, &sg); + argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01"); + str = rb_str_new2(JULIAN_EPOCH_DATE); case 1: comp = Qtrue; case 2: @@ -4407,11 +4774,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass) } { - VALUE argv2[2], hash; - - argv2[0] = str; - argv2[1] = comp; - hash = date_s__parse(2, argv2, klass); + int argc2 = 2; + VALUE argv2[3], hash; + argv2[0] = str; + argv2[1] = comp; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__parse(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } @@ -4425,256 +4793,417 @@ VALUE date__jisx0301(VALUE); /* * call-seq: - * Date._iso8601(string) -> hash + * Date._iso8601(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should contain + * an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]: + * + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Returns a hash of parsed elements. + * Related: Date.iso8601 (returns a \Date object). */ static VALUE -date_s__iso8601(VALUE klass, VALUE str) +date_s__iso8601(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__iso8601(str); } /* * call-seq: - * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.iso8601(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical ISO 8601 formats. + * Returns a new \Date object with values parsed from +string+, + * which should contain + * an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]: + * + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date.iso8601(s) # => #<Date: 2001-02-03> * - * Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...> - * Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...> - * Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...> + * See: + * + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._iso8601 (returns a hash). */ static VALUE date_s_iso8601(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01"); + str = rb_str_new2(JULIAN_EPOCH_DATE); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__iso8601(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__iso8601(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._rfc3339(string) -> hash + * Date._rfc3339(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date._rfc3339(s) + * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0} * - * Returns a hash of parsed elements. + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.rfc3339 (returns a \Date object). */ static VALUE -date_s__rfc3339(VALUE klass, VALUE str) +date_s__rfc3339(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__rfc3339(str); } /* * call-seq: - * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date + * Date.rfc3339(string = '-4712-01-01T00:00:00+00:00', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical RFC 3339 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date.rfc3339(s) # => #<Date: 2001-02-03> + * + * See: + * + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...> + * Related: Date._rfc3339 (returns a hash). */ static VALUE date_s_rfc3339(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__rfc3339(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__rfc3339(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._xmlschema(string) -> hash + * Date._xmlschema(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * XML date format: + * + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Returns a hash of parsed elements. + * Related: Date.xmlschema (returns a \Date object). */ static VALUE -date_s__xmlschema(VALUE klass, VALUE str) +date_s__xmlschema(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__xmlschema(str); } /* * call-seq: - * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.xmlschema(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical XML Schema formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid XML date format: + * + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date.xmlschema(s) # => #<Date: 2001-02-03> * - * Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...> + * See: + * + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._xmlschema (returns a hash). */ static VALUE date_s_xmlschema(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01"); + str = rb_str_new2(JULIAN_EPOCH_DATE); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__xmlschema(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__xmlschema(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._rfc2822(string) -> hash - * Date._rfc822(string) -> hash + * Date._rfc2822(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]: * - * Returns a hash of parsed elements. + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date._rfc2822(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.rfc2822 (returns a \Date object). */ static VALUE -date_s__rfc2822(VALUE klass, VALUE str) +date_s__rfc2822(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__rfc2822(str); } /* * call-seq: - * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date - * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date + * Date.rfc2822(string = 'Mon, 1 Jan -4712 00:00:00 +0000', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical RFC 2822 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date.rfc2822(s) # => #<Date: 2001-02-03> + * + * See: + * + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000') - * #=> #<Date: 2001-02-03 ...> + * Related: Date._rfc2822 (returns a hash). */ static VALUE date_s_rfc2822(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__rfc2822(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__rfc2822(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._httpdate(string) -> hash + * Date._httpdate(string, limit: 128) -> hash * - * Returns a hash of parsed elements. + * Returns a hash of values parsed from +string+, which should be a valid + * {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + * Date._httpdate(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0} + * + * Related: Date.httpdate (returns a \Date object). */ static VALUE -date_s__httpdate(VALUE klass, VALUE str) +date_s__httpdate(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__httpdate(str); } /* * call-seq: - * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date + * Date.httpdate(string = 'Mon, 01 Jan -4712 00:00:00 GMT', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some RFC 2616 format. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]: + * + * d = Date.new(2001, 2, 3) + s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + Date.httpdate(s) # => #<Date: 2001-02-03> + * + * See: * - * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT') - * #=> #<Date: 2001-02-03 ...> + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._httpdate (returns a hash). */ static VALUE date_s_httpdate(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__httpdate(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__httpdate(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._jisx0301(string) -> hash + * Date._jisx0301(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {JIS X 0301 date format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. * - * Returns a hash of parsed elements. + * Related: Date.jisx0301 (returns a \Date object). */ static VALUE -date_s__jisx0301(VALUE klass, VALUE str) +date_s__jisx0301(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + if (!NIL_P(str)) str = check_limit(str, opt); + return date__jisx0301(str); } /* * call-seq: - * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * - * Creates a new Date object by parsing from a string according to - * some typical JIS X 0301 formats. + * Returns a new \Date object with values parsed from +string+, + * which should be a valid {JIS X 0301 format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]: * - * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...> + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date.jisx0301(s) # => #<Date: 2001-02-03> * * For no-era year, legacy format, Heisei is assumed. * - * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...> + * Date.jisx0301('13.02.03') # => #<Date: 2001-02-03> + * + * See: + * + * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._jisx0301 (returns a hash). */ static VALUE date_s_jisx0301(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01"); + str = rb_str_new2(JULIAN_EPOCH_DATE); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__jisx0301(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__jisx0301(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } @@ -4844,6 +5373,7 @@ d_lite_initialize_copy(VALUE copy, VALUE date) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_fill(VALUE self) { @@ -4933,12 +5463,15 @@ d_lite_mjd(VALUE self) /* * call-seq: - * d.ld -> integer + * ld -> integer * - * Returns the Lilian day number. This is a whole number, which is - * adjusted by the offset as the local time. + * Returns the + * {Lilian day number}[https://en.wikipedia.org/wiki/Lilian_date], + * which is the number of days since the beginning of the Gregorian + * calendar, October 15, 1582. + * + * Date.new(2001, 2, 3).ld # => 152784 * - * Date.new(2001,2,3).ld #=> 152784 */ static VALUE d_lite_ld(VALUE self) @@ -4949,12 +5482,13 @@ d_lite_ld(VALUE self) /* * call-seq: - * d.year -> integer + * year -> integer + * + * Returns the year: * - * Returns the year. + * Date.new(2001, 2, 3).year # => 2001 + * (Date.new(1, 1, 1) - 1).year # => 0 * - * Date.new(2001,2,3).year #=> 2001 - * (Date.new(1,1,1) - 1).year #=> 0 */ static VALUE d_lite_year(VALUE self) @@ -4965,11 +5499,12 @@ d_lite_year(VALUE self) /* * call-seq: - * d.yday -> fixnum + * yday -> integer + * + * Returns the day of the year, in range (1..366): * - * Returns the day of the year (1-366). + * Date.new(2001, 2, 3).yday # => 34 * - * Date.new(2001,2,3).yday #=> 34 */ static VALUE d_lite_yday(VALUE self) @@ -4980,12 +5515,12 @@ d_lite_yday(VALUE self) /* * call-seq: - * d.mon -> fixnum - * d.month -> fixnum + * mon -> integer * - * Returns the month (1-12). + * Returns the month in range (1..12): + * + * Date.new(2001, 2, 3).mon # => 2 * - * Date.new(2001,2,3).mon #=> 2 */ static VALUE d_lite_mon(VALUE self) @@ -4996,12 +5531,12 @@ d_lite_mon(VALUE self) /* * call-seq: - * d.mday -> fixnum - * d.day -> fixnum + * mday -> integer + * + * Returns the day of the month in range (1..31): * - * Returns the day of the month (1-31). + * Date.new(2001, 2, 3).mday # => 3 * - * Date.new(2001,2,3).mday #=> 3 */ static VALUE d_lite_mday(VALUE self) @@ -5012,11 +5547,12 @@ d_lite_mday(VALUE self) /* * call-seq: - * d.day_fraction -> rational + * day_fraction -> rational * - * Returns the fractional part of the day. + * Returns the fractional part of the day in range (Rational(0, 1)...Rational(1, 1)): + * + * DateTime.new(2001,2,3,12).day_fraction # => (1/2) * - * DateTime.new(2001,2,3,12).day_fraction #=> (1/2) */ static VALUE d_lite_day_fraction(VALUE self) @@ -5029,12 +5565,14 @@ d_lite_day_fraction(VALUE self) /* * call-seq: - * d.cwyear -> integer + * cwyear -> integer + * + * Returns commercial-date year for +self+ + * (see Date.commercial): * - * Returns the calendar week based year. + * Date.new(2001, 2, 3).cwyear # => 2001 + * Date.new(2000, 1, 1).cwyear # => 1999 * - * Date.new(2001,2,3).cwyear #=> 2001 - * Date.new(2000,1,1).cwyear #=> 1999 */ static VALUE d_lite_cwyear(VALUE self) @@ -5045,11 +5583,13 @@ d_lite_cwyear(VALUE self) /* * call-seq: - * d.cweek -> fixnum + * cweek -> integer * - * Returns the calendar week number (1-53). + * Returns commercial-date week index for +self+ + * (see Date.commercial): + * + * Date.new(2001, 2, 3).cweek # => 5 * - * Date.new(2001,2,3).cweek #=> 5 */ static VALUE d_lite_cweek(VALUE self) @@ -5060,11 +5600,14 @@ d_lite_cweek(VALUE self) /* * call-seq: - * d.cwday -> fixnum + * cwday -> integer + * + * Returns the commercial-date weekday index for +self+ + * (see Date.commercial); + * 1 is Monday: * - * Returns the day of calendar week (1-7, Monday is 1). + * Date.new(2001, 2, 3).cwday # => 6 * - * Date.new(2001,2,3).cwday #=> 6 */ static VALUE d_lite_cwday(VALUE self) @@ -5074,6 +5617,7 @@ d_lite_cwday(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_wnum0(VALUE self) { @@ -5081,6 +5625,7 @@ d_lite_wnum0(VALUE self) return INT2FIX(m_wnum0(dat)); } +/* :nodoc: */ static VALUE d_lite_wnum1(VALUE self) { @@ -5091,11 +5636,12 @@ d_lite_wnum1(VALUE self) /* * call-seq: - * d.wday -> fixnum + * wday -> integer * - * Returns the day of week (0-6, Sunday is zero). + * Returns the day of week in range (0..6); Sunday is 0: + * + * Date.new(2001, 2, 3).wday # => 6 * - * Date.new(2001,2,3).wday #=> 6 */ static VALUE d_lite_wday(VALUE self) @@ -5106,9 +5652,9 @@ d_lite_wday(VALUE self) /* * call-seq: - * d.sunday? -> bool + * sunday? -> true or false * - * Returns true if the date is Sunday. + * Returns +true+ if +self+ is a Sunday, +false+ otherwise. */ static VALUE d_lite_sunday_p(VALUE self) @@ -5119,9 +5665,9 @@ d_lite_sunday_p(VALUE self) /* * call-seq: - * d.monday? -> bool + * monday? -> true or false * - * Returns true if the date is Monday. + * Returns +true+ if +self+ is a Monday, +false+ otherwise. */ static VALUE d_lite_monday_p(VALUE self) @@ -5132,9 +5678,9 @@ d_lite_monday_p(VALUE self) /* * call-seq: - * d.tuesday? -> bool + * tuesday? -> true or false * - * Returns true if the date is Tuesday. + * Returns +true+ if +self+ is a Tuesday, +false+ otherwise. */ static VALUE d_lite_tuesday_p(VALUE self) @@ -5145,9 +5691,9 @@ d_lite_tuesday_p(VALUE self) /* * call-seq: - * d.wednesday? -> bool + * wednesday? -> true or false * - * Returns true if the date is Wednesday. + * Returns +true+ if +self+ is a Wednesday, +false+ otherwise. */ static VALUE d_lite_wednesday_p(VALUE self) @@ -5158,9 +5704,9 @@ d_lite_wednesday_p(VALUE self) /* * call-seq: - * d.thursday? -> bool + * thursday? -> true or false * - * Returns true if the date is Thursday. + * Returns +true+ if +self+ is a Thursday, +false+ otherwise. */ static VALUE d_lite_thursday_p(VALUE self) @@ -5171,9 +5717,9 @@ d_lite_thursday_p(VALUE self) /* * call-seq: - * d.friday? -> bool + * friday? -> true or false * - * Returns true if the date is Friday. + * Returns +true+ if +self+ is a Friday, +false+ otherwise. */ static VALUE d_lite_friday_p(VALUE self) @@ -5184,9 +5730,9 @@ d_lite_friday_p(VALUE self) /* * call-seq: - * d.saturday? -> bool + * saturday? -> true or false * - * Returns true if the date is Saturday. + * Returns +true+ if +self+ is a Saturday, +false+ otherwise. */ static VALUE d_lite_saturday_p(VALUE self) @@ -5196,6 +5742,7 @@ d_lite_saturday_p(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k) { @@ -5217,11 +5764,12 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k) /* * call-seq: - * d.hour -> fixnum + * hour -> integer * - * Returns the hour (0-23). + * Returns the hour in range (0..23): + * + * DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4 * - * DateTime.new(2001,2,3,4,5,6).hour #=> 4 */ static VALUE d_lite_hour(VALUE self) @@ -5232,12 +5780,12 @@ d_lite_hour(VALUE self) /* * call-seq: - * d.min -> fixnum - * d.minute -> fixnum + * min -> integer + * + * Returns the minute in range (0..59): * - * Returns the minute (0-59). + * DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5 * - * DateTime.new(2001,2,3,4,5,6).min #=> 5 */ static VALUE d_lite_min(VALUE self) @@ -5248,12 +5796,12 @@ d_lite_min(VALUE self) /* * call-seq: - * d.sec -> fixnum - * d.second -> fixnum + * sec -> integer * - * Returns the second (0-59). + * Returns the second in range (0..59): + * + * DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6 * - * DateTime.new(2001,2,3,4,5,6).sec #=> 6 */ static VALUE d_lite_sec(VALUE self) @@ -5264,12 +5812,13 @@ d_lite_sec(VALUE self) /* * call-seq: - * d.sec_fraction -> rational - * d.second_fraction -> rational + * sec_fraction -> rational + * + * Returns the fractional part of the second in range + * (Rational(0, 1)...Rational(1, 1)): * - * Returns the fractional part of the second. + * DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2) * - * DateTime.new(2001,2,3,4,5,6.5).sec_fraction #=> (1/2) */ static VALUE d_lite_sec_fraction(VALUE self) @@ -5310,12 +5859,14 @@ d_lite_zone(VALUE self) /* * call-seq: - * d.julian? -> bool + * d.julian? -> true or false + * + * Returns +true+ if the date is before the date of calendar reform, + * +false+ otherwise: * - * Returns true if the date is before the day of calendar reform. + * (Date.new(1582, 10, 15) - 1).julian? # => true + * Date.new(1582, 10, 15).julian? # => false * - * Date.new(1582,10,15).julian? #=> false - * (Date.new(1582,10,15) - 1).julian? #=> true */ static VALUE d_lite_julian_p(VALUE self) @@ -5326,12 +5877,14 @@ d_lite_julian_p(VALUE self) /* * call-seq: - * d.gregorian? -> bool + * gregorian? -> true or false * - * Returns true if the date is on or after the day of calendar reform. + * Returns +true+ if the date is on or after + * the date of calendar reform, +false+ otherwise: + * + * Date.new(1582, 10, 15).gregorian? # => true + * (Date.new(1582, 10, 15) - 1).gregorian? # => false * - * Date.new(1582,10,15).gregorian? #=> true - * (Date.new(1582,10,15) - 1).gregorian? #=> false */ static VALUE d_lite_gregorian_p(VALUE self) @@ -5342,12 +5895,13 @@ d_lite_gregorian_p(VALUE self) /* * call-seq: - * d.leap? -> bool + * leap? -> true or false + * + * Returns +true+ if the year is a leap year, +false+ otherwise: * - * Returns true if the year is a leap year. + * Date.new(2000).leap? # => true + * Date.new(2001).leap? # => false * - * Date.new(2000).leap? #=> true - * Date.new(2001).leap? #=> false */ static VALUE d_lite_leap_p(VALUE self) @@ -5366,12 +5920,25 @@ d_lite_leap_p(VALUE self) /* * call-seq: - * d.start -> float + * start -> float + * + * Returns the Julian start date for calendar reform; + * if not an infinity, the returned value is suitable + * for passing to Date#jd: + * + * d = Date.new(2001, 2, 3, Date::ITALY) + * s = d.start # => 2299161.0 + * Date.jd(s).to_s # => "1582-10-15" * - * Returns the Julian day number denoting the day of calendar reform. + * d = Date.new(2001, 2, 3, Date::ENGLAND) + * s = d.start # => 2361222.0 + * Date.jd(s).to_s # => "1752-09-14" + * + * Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity + * Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity + * + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. * - * Date.new(2001,2,3).start #=> 2299161.0 - * Date.new(2001,2,3,Date::GREGORIAN).start #=> -Infinity */ static VALUE d_lite_start(VALUE self) @@ -5436,12 +6003,17 @@ dup_obj_with_new_start(VALUE obj, double sg) /* * call-seq: - * d.new_start([start=Date::ITALY]) -> date + * new_start(start = Date::ITALY]) -> new_date + * + * Returns a copy of +self+ with the given +start+ value: + * + * d0 = Date.new(2000, 2, 3) + * d0.julian? # => false + * d1 = d0.new_start(Date::JULIAN) + * d1.julian? # => true * - * Duplicates self and resets its day of calendar reform. + * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start]. * - * d = Date.new(1582,10,15) - * d.new_start(Date::JULIAN) #=> #<Date: 1582-10-05 ...> */ static VALUE d_lite_new_start(int argc, VALUE *argv, VALUE self) @@ -5460,9 +6032,10 @@ d_lite_new_start(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.italy -> date + * italy -> new_date + * + * Equivalent to Date#new_start with argument Date::ITALY. * - * This method is equivalent to new_start(Date::ITALY). */ static VALUE d_lite_italy(VALUE self) @@ -5472,9 +6045,9 @@ d_lite_italy(VALUE self) /* * call-seq: - * d.england -> date + * england -> new_date * - * This method is equivalent to new_start(Date::ENGLAND). + * Equivalent to Date#new_start with argument Date::ENGLAND. */ static VALUE d_lite_england(VALUE self) @@ -5484,9 +6057,9 @@ d_lite_england(VALUE self) /* * call-seq: - * d.julian -> date + * julian -> new_date * - * This method is equivalent to new_start(Date::JULIAN). + * Equivalent to Date#new_start with argument Date::JULIAN. */ static VALUE d_lite_julian(VALUE self) @@ -5496,9 +6069,9 @@ d_lite_julian(VALUE self) /* * call-seq: - * d.gregorian -> date + * gregorian -> new_date * - * This method is equivalent to new_start(Date::GREGORIAN). + * Equivalent to Date#new_start with argument Date::GREGORIAN. */ static VALUE d_lite_gregorian(VALUE self) @@ -5944,9 +6517,11 @@ minus_dd(VALUE self, VALUE other) * call-seq: * d - other -> date or rational * - * Returns the difference between the two dates if the other is a date - * object. If the other is a numeric value, returns a date object - * pointing +other+ days before self. If the other is a fractional number, + * If the other is a date object, returns a Rational + * whose value is the difference between the two dates in days. + * If the other is a numeric value, returns a date object + * pointing +other+ days before self. + * If the other is a fractional number, * assumes its precision is at most nanosecond. * * Date.new(2001,2,3) - 1 #=> #<Date: 2001-02-02 ...> @@ -5979,9 +6554,9 @@ d_lite_minus(VALUE self, VALUE other) /* * call-seq: - * d.next_day([n=1]) -> date + * next_day(n = 1) -> new_date * - * This method is equivalent to d + n. + * Equivalent to Date#+ with argument +n+. */ static VALUE d_lite_next_day(int argc, VALUE *argv, VALUE self) @@ -5996,9 +6571,9 @@ d_lite_next_day(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.prev_day([n=1]) -> date + * prev_day(n = 1) -> new_date * - * This method is equivalent to d - n. + * Equivalent to Date#- with argument +n+. */ static VALUE d_lite_prev_day(int argc, VALUE *argv, VALUE self) @@ -6013,10 +6588,14 @@ d_lite_prev_day(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.succ -> date - * d.next -> date + * d.next -> new_date + * + * Returns a new \Date object representing the following day: + * + * d = Date.new(2001, 2, 3) + * d.to_s # => "2001-02-03" + * d.next.to_s # => "2001-02-04" * - * Returns a date object denoting the following day. */ static VALUE d_lite_next(VALUE self) @@ -6026,26 +6605,30 @@ d_lite_next(VALUE self) /* * call-seq: - * d >> n -> date + * d >> n -> new_date + * + * Returns a new \Date object representing the date + * +n+ months later; +n+ should be a numeric: * - * Returns a date object pointing +n+ months after self. - * The argument +n+ should be a numeric value. + * (Date.new(2001, 2, 3) >> 1).to_s # => "2001-03-03" + * (Date.new(2001, 2, 3) >> -2).to_s # => "2000-12-03" * - * Date.new(2001,2,3) >> 1 #=> #<Date: 2001-03-03 ...> - * Date.new(2001,2,3) >> -2 #=> #<Date: 2000-12-03 ...> + * When the same day does not exist for the new month, + * the last day of that month is used instead: * - * When the same day does not exist for the corresponding month, - * the last day of the month is used instead: + * (Date.new(2001, 1, 31) >> 1).to_s # => "2001-02-28" + * (Date.new(2001, 1, 31) >> -4).to_s # => "2000-09-30" * - * Date.new(2001,1,28) >> 1 #=> #<Date: 2001-02-28 ...> - * Date.new(2001,1,31) >> 1 #=> #<Date: 2001-02-28 ...> + * This results in the following, possibly unexpected, behaviors: * - * This also results in the following, possibly unexpected, behavior: + * d0 = Date.new(2001, 1, 31) + * d1 = d0 >> 1 # => #<Date: 2001-02-28> + * d2 = d1 >> 1 # => #<Date: 2001-03-28> * - * Date.new(2001,1,31) >> 2 #=> #<Date: 2001-03-31 ...> - * Date.new(2001,1,31) >> 1 >> 1 #=> #<Date: 2001-03-28 ...> + * d0 = Date.new(2001, 1, 31) + * d1 = d0 >> 1 # => #<Date: 2001-02-28> + * d2 = d1 >> -1 # => #<Date: 2001-01-28> * - * Date.new(2001,1,31) >> 1 >> -1 #=> #<Date: 2001-01-28 ...> */ static VALUE d_lite_rshift(VALUE self, VALUE other) @@ -6090,24 +6673,28 @@ d_lite_rshift(VALUE self, VALUE other) * call-seq: * d << n -> date * - * Returns a date object pointing +n+ months before self. - * The argument +n+ should be a numeric value. + * Returns a new \Date object representing the date + * +n+ months earlier; +n+ should be a numeric: * - * Date.new(2001,2,3) << 1 #=> #<Date: 2001-01-03 ...> - * Date.new(2001,2,3) << -2 #=> #<Date: 2001-04-03 ...> + * (Date.new(2001, 2, 3) << 1).to_s # => "2001-01-03" + * (Date.new(2001, 2, 3) << -2).to_s # => "2001-04-03" * - * When the same day does not exist for the corresponding month, - * the last day of the month is used instead: + * When the same day does not exist for the new month, + * the last day of that month is used instead: * - * Date.new(2001,3,28) << 1 #=> #<Date: 2001-02-28 ...> - * Date.new(2001,3,31) << 1 #=> #<Date: 2001-02-28 ...> + * (Date.new(2001, 3, 31) << 1).to_s # => "2001-02-28" + * (Date.new(2001, 3, 31) << -6).to_s # => "2001-09-30" * - * This also results in the following, possibly unexpected, behavior: + * This results in the following, possibly unexpected, behaviors: * - * Date.new(2001,3,31) << 2 #=> #<Date: 2001-01-31 ...> - * Date.new(2001,3,31) << 1 << 1 #=> #<Date: 2001-01-28 ...> + * d0 = Date.new(2001, 3, 31) + * d0 << 2 # => #<Date: 2001-01-31> + * d0 << 1 << 1 # => #<Date: 2001-01-28> + * + * d0 = Date.new(2001, 3, 31) + * d1 = d0 << 1 # => #<Date: 2001-02-28> + * d2 = d1 << -1 # => #<Date: 2001-03-28> * - * Date.new(2001,3,31) << 1 << -1 #=> #<Date: 2001-03-28 ...> */ static VALUE d_lite_lshift(VALUE self, VALUE other) @@ -6118,11 +6705,9 @@ d_lite_lshift(VALUE self, VALUE other) /* * call-seq: - * d.next_month([n=1]) -> date - * - * This method is equivalent to d >> n. + * next_month(n = 1) -> new_date * - * See Date#>> for examples. + * Equivalent to #>> with argument +n+. */ static VALUE d_lite_next_month(int argc, VALUE *argv, VALUE self) @@ -6137,11 +6722,9 @@ d_lite_next_month(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.prev_month([n=1]) -> date - * - * This method is equivalent to d << n. + * prev_month(n = 1) -> new_date * - * See Date#<< for examples. + * Equivalent to #<< with argument +n+. */ static VALUE d_lite_prev_month(int argc, VALUE *argv, VALUE self) @@ -6156,15 +6739,9 @@ d_lite_prev_month(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.next_year([n=1]) -> date + * next_year(n = 1) -> new_date * - * This method is equivalent to d >> (n * 12). - * - * Date.new(2001,2,3).next_year #=> #<Date: 2002-02-03 ...> - * Date.new(2008,2,29).next_year #=> #<Date: 2009-02-28 ...> - * Date.new(2008,2,29).next_year(4) #=> #<Date: 2012-02-29 ...> - * - * See also Date#>>. + * Equivalent to #>> with argument <tt>n * 12</tt>. */ static VALUE d_lite_next_year(int argc, VALUE *argv, VALUE self) @@ -6179,15 +6756,9 @@ d_lite_next_year(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.prev_year([n=1]) -> date - * - * This method is equivalent to d << (n * 12). - * - * Date.new(2001,2,3).prev_year #=> #<Date: 2000-02-03 ...> - * Date.new(2008,2,29).prev_year #=> #<Date: 2007-02-28 ...> - * Date.new(2008,2,29).prev_year(4) #=> #<Date: 2004-02-29 ...> + * prev_year(n = 1) -> new_date * - * See also Date#<<. + * Equivalent to #<< with argument <tt>n * 12</tt>. */ static VALUE d_lite_prev_year(int argc, VALUE *argv, VALUE self) @@ -6204,14 +6775,33 @@ static VALUE d_lite_cmp(VALUE, VALUE); /* * call-seq: - * d.step(limit[, step=1]) -> enumerator - * d.step(limit[, step=1]){|date| ...} -> self + * step(limit, step = 1){|date| ... } -> self + * + * Calls the block with specified dates; + * returns +self+. + * + * - The first +date+ is +self+. + * - Each successive +date+ is <tt>date + step</tt>, + * where +step+ is the numeric step size in days. + * - The last date is the last one that is before or equal to +limit+, + * which should be a \Date object. + * + * Example: + * + * limit = Date.new(2001, 12, 31) + * Date.new(2001).step(limit){|date| p date.to_s if date.mday == 31 } * - * Iterates evaluation of the given block, which takes a date object. - * The limit should be a date object. + * Output: * - * Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size - * #=> 52 + * "2001-01-31" + * "2001-03-31" + * "2001-05-31" + * "2001-07-31" + * "2001-08-31" + * "2001-10-31" + * "2001-12-31" + * + * Returns an Enumerator if no block is given. */ static VALUE d_lite_step(int argc, VALUE *argv, VALUE self) @@ -6254,10 +6844,9 @@ d_lite_step(int argc, VALUE *argv, VALUE self) /* * call-seq: - * d.upto(max) -> enumerator - * d.upto(max){|date| ...} -> self + * upto(max){|date| ... } -> self * - * This method is equivalent to step(max, 1){|date| ...}. + * Equivalent to #step with arguments +max+ and +1+. */ static VALUE d_lite_upto(VALUE self, VALUE max) @@ -6276,10 +6865,9 @@ d_lite_upto(VALUE self, VALUE max) /* * call-seq: - * d.downto(min) -> enumerator - * d.downto(min){|date| ...} -> self + * downto(min){|date| ... } -> self * - * This method is equivalent to step(min, -1){|date| ...}. + * Equivalent to #step with arguments +min+ and <tt>-1</tt>. */ static VALUE d_lite_downto(VALUE self, VALUE min) @@ -6367,19 +6955,43 @@ cmp_dd(VALUE self, VALUE other) /* * call-seq: - * d <=> other -> -1, 0, +1 or nil + * self <=> other -> -1, 0, 1 or nil + * + * Compares +self+ and +other+, returning: + * + * - <tt>-1</tt> if +other+ is larger. + * - <tt>0</tt> if the two are equal. + * - <tt>1</tt> if +other+ is smaller. + * - +nil+ if the two are incomparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)> + * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)> + * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)> + * d <=> next_date # => -1 + * d <=> d # => 0 + * d <=> prev_date # => 1 + * + * - A DateTime object: * - * Compares the two dates and returns -1, zero, 1 or nil. The other - * should be a date object or a numeric value as an astronomical - * Julian day number. + * d <=> DateTime.new(2022, 7, 26) # => 1 + * d <=> DateTime.new(2022, 7, 27) # => 0 + * d <=> DateTime.new(2022, 7, 28) # => -1 * - * Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1 - * Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0 - * Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1 - * Date.new(2001,2,3) <=> Object.new #=> nil - * Date.new(2001,2,3) <=> Rational(4903887,2) #=> 0 + * - A numeric (compares <tt>self.ajd</tt> to +other+): + * + * d <=> 2459788 # => -1 + * d <=> 2459787 # => 1 + * d <=> 2459786 # => 1 + * d <=> d.ajd # => 0 + * + * - Any other object: + * + * d <=> Object.new # => nil * - * See also Comparable. */ static VALUE d_lite_cmp(VALUE self, VALUE other) @@ -6439,20 +7051,39 @@ equal_gen(VALUE self, VALUE other) /* * call-seq: - * d === other -> bool - * - * Returns true if they are the same day. - * - * Date.new(2001,2,3) === Date.new(2001,2,3) - * #=> true - * Date.new(2001,2,3) === Date.new(2001,2,4) - * #=> false - * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12) - * #=> true - * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00') - * #=> true - * DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00') - * #=> false + * self === other -> true, false, or nil. + * + * Returns +true+ if +self+ and +other+ represent the same date, + * +false+ if not, +nil+ if the two are not comparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)> + * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)> + * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)> + * d === prev_date # => false + * d === d # => true + * d === next_date # => false + * + * - A DateTime object: + * + * d === DateTime.new(2022, 7, 26) # => false + * d === DateTime.new(2022, 7, 27) # => true + * d === DateTime.new(2022, 7, 28) # => false + * + * - A numeric (compares <tt>self.jd</tt> to +other+): + * + * d === 2459788 # => true + * d === 2459787 # => false + * d === 2459786 # => false + * d === d.jd # => true + * + * - An object not comparable: + * + * d === Object.new # => nil + * */ static VALUE d_lite_equal(VALUE self, VALUE other) @@ -6497,13 +7128,24 @@ d_lite_eql_p(VALUE self, VALUE other) static VALUE d_lite_hash(VALUE self) { - st_index_t v, h[4]; + st_index_t v, h[5]; + VALUE nth; get_d1(self); - h[0] = m_nth(dat); - h[1] = m_jd(dat); - h[2] = m_df(dat); - h[3] = m_sf(dat); + nth = m_nth(dat); + + if (FIXNUM_P(nth)) { + h[0] = 0; + h[1] = (st_index_t)nth; + } else { + h[0] = 1; + h[1] = (st_index_t)FIX2LONG(rb_hash(nth)); + } + + h[2] = m_jd(dat); + h[3] = m_df(dat); + h[4] = m_sf(dat); + v = rb_memhash(h, sizeof(h)); return ST2FIX(v); } @@ -6515,12 +7157,14 @@ static VALUE strftimev(const char *, VALUE, /* * call-seq: - * d.to_s -> string + * to_s -> string * - * Returns a string in an ISO 8601 format. (This method doesn't use the - * expanded representations.) + * Returns a string representation of the date in +self+ + * in {ISO 8601 extended date format}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications] + * (<tt>'%Y-%m-%d'</tt>): + * + * Date.new(2001, 2, 3).to_s # => "2001-02-03" * - * Date.new(2001,2,3).to_s #=> "2001-02-03" */ static VALUE d_lite_to_s(VALUE self) @@ -6529,6 +7173,7 @@ d_lite_to_s(VALUE self) } #ifndef NDEBUG +/* :nodoc: */ static VALUE mk_inspect_raw(union DateData *x, VALUE klass) { @@ -6578,6 +7223,7 @@ mk_inspect_raw(union DateData *x, VALUE klass) } } +/* :nodoc: */ static VALUE d_lite_inspect_raw(VALUE self) { @@ -6599,14 +7245,13 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s) /* * call-seq: - * d.inspect -> string + * inspect -> string * - * Returns the value as a string for inspection. + * Returns a string representation of +self+: + * + * Date.new(2001, 2, 3).inspect + * # => "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>" * - * Date.new(2001,2,3).inspect - * #=> "#<Date: 2001-02-03>" - * DateTime.new(2001,2,3,4,5,6,'-7').inspect - * #=> "#<DateTime: 2001-02-03T04:05:06-07:00>" */ static VALUE d_lite_inspect(VALUE self) @@ -6788,180 +7433,16 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self, /* * call-seq: - * d.strftime([format='%F']) -> string - * - * Formats date according to the directives in the given format - * string. - * The directives begin with a percent (%) character. - * Any text not listed as a directive will be passed through to the - * output string. - * - * A directive consists of a percent (%) character, - * zero or more flags, an optional minimum field width, - * an optional modifier, and a conversion specifier - * as follows. - * - * %<flags><width><modifier><conversion> - * - * Flags: - * - don't pad a numerical output. - * _ use spaces for padding. - * 0 use zeros for padding. - * ^ upcase the result string. - * # change case. - * - * The minimum field width specifies the minimum width. - * - * The modifiers are "E", "O", ":", "::" and ":::". - * "E" and "O" are ignored. No effect to result currently. - * - * Format directives: - * - * Date (Year, Month, Day): - * %Y - Year with century (can be negative, 4 digits at least) - * -0001, 0000, 1995, 2009, 14292, etc. - * %C - year / 100 (round down. 20 in 2009) - * %y - year % 100 (00..99) - * - * %m - Month of the year, zero-padded (01..12) - * %_m blank-padded ( 1..12) - * %-m no-padded (1..12) - * %B - The full month name (``January'') - * %^B uppercased (``JANUARY'') - * %b - The abbreviated month name (``Jan'') - * %^b uppercased (``JAN'') - * %h - Equivalent to %b - * - * %d - Day of the month, zero-padded (01..31) - * %-d no-padded (1..31) - * %e - Day of the month, blank-padded ( 1..31) - * - * %j - Day of the year (001..366) - * - * Time (Hour, Minute, Second, Subsecond): - * %H - Hour of the day, 24-hour clock, zero-padded (00..23) - * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23) - * %I - Hour of the day, 12-hour clock, zero-padded (01..12) - * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12) - * %P - Meridian indicator, lowercase (``am'' or ``pm'') - * %p - Meridian indicator, uppercase (``AM'' or ``PM'') - * - * %M - Minute of the hour (00..59) - * - * %S - Second of the minute (00..60) - * - * %L - Millisecond of the second (000..999) - * %N - Fractional seconds digits, default is 9 digits (nanosecond) - * %3N millisecond (3 digits) %15N femtosecond (15 digits) - * %6N microsecond (6 digits) %18N attosecond (18 digits) - * %9N nanosecond (9 digits) %21N zeptosecond (21 digits) - * %12N picosecond (12 digits) %24N yoctosecond (24 digits) - * - * Time zone: - * %z - Time zone as hour and minute offset from UTC (e.g. +0900) - * %:z - hour and minute offset from UTC with a colon (e.g. +09:00) - * %::z - hour, minute and second offset from UTC (e.g. +09:00:00) - * %:::z - hour, minute and second offset from UTC - * (e.g. +09, +09:30, +09:30:30) - * %Z - Equivalent to %:z (e.g. +09:00) - * - * Weekday: - * %A - The full weekday name (``Sunday'') - * %^A uppercased (``SUNDAY'') - * %a - The abbreviated name (``Sun'') - * %^a uppercased (``SUN'') - * %u - Day of the week (Monday is 1, 1..7) - * %w - Day of the week (Sunday is 0, 0..6) - * - * ISO 8601 week-based year and week number: - * The week 1 of YYYY starts with a Monday and includes YYYY-01-04. - * The days in the year before the first week are in the last week of - * the previous year. - * %G - The week-based year - * %g - The last 2 digits of the week-based year (00..99) - * %V - Week number of the week-based year (01..53) - * - * Week number: - * The week 1 of YYYY starts with a Sunday or Monday (according to %U - * or %W). The days in the year before the first week are in week 0. - * %U - Week number of the year. The week starts with Sunday. (00..53) - * %W - Week number of the year. The week starts with Monday. (00..53) - * - * Seconds since the Unix Epoch: - * %s - Number of seconds since 1970-01-01 00:00:00 UTC. - * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC. - * - * Literal string: - * %n - Newline character (\n) - * %t - Tab character (\t) - * %% - Literal ``%'' character - * - * Combination: - * %c - date and time (%a %b %e %T %Y) - * %D - Date (%m/%d/%y) - * %F - The ISO 8601 date format (%Y-%m-%d) - * %v - VMS date (%e-%^b-%Y) - * %x - Same as %D - * %X - Same as %T - * %r - 12-hour time (%I:%M:%S %p) - * %R - 24-hour time (%H:%M) - * %T - 24-hour time (%H:%M:%S) - * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y) - * - * This method is similar to the strftime() function defined in ISO C - * and POSIX. - * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z) - * are locale dependent in the function. - * However, this method is locale independent. - * So, the result may differ even if the same format string is used in other - * systems such as C. - * It is good practice to avoid %x and %X because there are corresponding - * locale independent representations, %D and %T. - * - * Examples: - * - * d = DateTime.new(2007,11,19,8,37,48,"-06:00") - * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...> - * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" - * d.strftime("at %I:%M%p") #=> "at 08:37AM" - * - * Various ISO 8601 formats: - * %Y%m%d => 20071119 Calendar date (basic) - * %F => 2007-11-19 Calendar date (extended) - * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month - * %Y => 2007 Calendar date, reduced accuracy, specific year - * %C => 20 Calendar date, reduced accuracy, specific century - * %Y%j => 2007323 Ordinal date (basic) - * %Y-%j => 2007-323 Ordinal date (extended) - * %GW%V%u => 2007W471 Week date (basic) - * %G-W%V-%u => 2007-W47-1 Week date (extended) - * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic) - * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended) - * %H%M%S => 083748 Local time (basic) - * %T => 08:37:48 Local time (extended) - * %H%M => 0837 Local time, reduced accuracy, specific minute (basic) - * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended) - * %H => 08 Local time, reduced accuracy, specific hour - * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic) - * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended) - * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic) - * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended) - * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic) - * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended) - * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic) - * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended) - * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic) - * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended) - * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic) - * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended) - * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic) - * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended) - * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic) - * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended) - * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic) - * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended) - * - * See also strftime(3) and ::strptime. + * strftime(format = '%F') -> string + * + * Returns a string representation of the date in +self+, + * formatted according the given +format+: + * + * Date.new(2001, 2, 3).strftime # => "2001-02-03" + * + * For other formats, see + * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]. + * */ static VALUE d_lite_strftime(int argc, VALUE *argv, VALUE self) @@ -6989,13 +7470,16 @@ strftimev(const char *fmt, VALUE self, /* * call-seq: - * d.asctime -> string - * d.ctime -> string + * asctime -> string * - * Returns a string in asctime(3) format (but without "\n\0" at the - * end). This method is equivalent to strftime('%c'). + * Equivalent to #strftime with argument <tt>'%a %b %e %T %Y'</tt> + * (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers] + * <tt>'%c'</tt>): + * + * Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001" + * + * See {asctime}[https://linux.die.net/man/3/asctime]. * - * See also asctime(3) or ctime(3). */ static VALUE d_lite_asctime(VALUE self) @@ -7005,10 +7489,14 @@ d_lite_asctime(VALUE self) /* * call-seq: - * d.iso8601 -> string - * d.xmlschema -> string + * iso8601 -> string + * + * Equivalent to #strftime with argument <tt>'%Y-%m-%d'</tt> + * (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers] + * <tt>'%F'</tt>); + * + * Date.new(2001, 2, 3).iso8601 # => "2001-02-03" * - * This method is equivalent to strftime('%F'). */ static VALUE d_lite_iso8601(VALUE self) @@ -7018,9 +7506,13 @@ d_lite_iso8601(VALUE self) /* * call-seq: - * d.rfc3339 -> string + * rfc3339 -> string + * + * Equivalent to #strftime with argument <tt>'%FT%T%:z'</tt>; + * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]: + * + * Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00" * - * This method is equivalent to strftime('%FT%T%:z'). */ static VALUE d_lite_rfc3339(VALUE self) @@ -7030,10 +7522,13 @@ d_lite_rfc3339(VALUE self) /* * call-seq: - * d.rfc2822 -> string - * d.rfc822 -> string + * rfc2822 -> string + * + * Equivalent to #strftime with argument <tt>'%a, %-d %b %Y %T %z'</tt>; + * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]: + * + * Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" * - * This method is equivalent to strftime('%a, %-d %b %Y %T %z'). */ static VALUE d_lite_rfc2822(VALUE self) @@ -7043,10 +7538,13 @@ d_lite_rfc2822(VALUE self) /* * call-seq: - * d.httpdate -> string + * httpdate -> string + * + * Equivalent to #strftime with argument <tt>'%a, %d %b %Y %T GMT'</tt>; + * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]: + * + * Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" * - * This method is equivalent to strftime('%a, %d %b %Y %T GMT'). - * See also RFC 2616. */ static VALUE d_lite_httpdate(VALUE self) @@ -7097,11 +7595,13 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y) /* * call-seq: - * d.jisx0301 -> string + * jisx0301 -> string * - * Returns a string in a JIS X 0301 format. + * Returns a string representation of the date in +self+ + * in JIS X 0301 format. + * + * Date.new(2001, 2, 3).jisx0301 # => "H13.02.03" * - * Date.new(2001,2,3).jisx0301 #=> "H13.02.03" */ static VALUE d_lite_jisx0301(VALUE self) @@ -7116,7 +7616,98 @@ d_lite_jisx0301(VALUE self) return strftimev(fmt, self, set_tmx); } +static VALUE +deconstruct_keys(VALUE self, VALUE keys, int is_datetime) +{ + VALUE h = rb_hash_new(); + long i; + + get_d1(self); + + if (NIL_P(keys)) { + rb_hash_aset(h, sym_year, m_real_year(dat)); + rb_hash_aset(h, sym_month, INT2FIX(m_mon(dat))); + rb_hash_aset(h, sym_day, INT2FIX(m_mday(dat))); + rb_hash_aset(h, sym_yday, INT2FIX(m_yday(dat))); + rb_hash_aset(h, sym_wday, INT2FIX(m_wday(dat))); + if (is_datetime) { + rb_hash_aset(h, sym_hour, INT2FIX(m_hour(dat))); + rb_hash_aset(h, sym_min, INT2FIX(m_min(dat))); + rb_hash_aset(h, sym_sec, INT2FIX(m_sec(dat))); + rb_hash_aset(h, sym_sec_fraction, m_sf_in_sec(dat)); + rb_hash_aset(h, sym_zone, m_zone(dat)); + } + + return h; + } + if (!RB_TYPE_P(keys, T_ARRAY)) { + rb_raise(rb_eTypeError, + "wrong argument type %"PRIsVALUE" (expected Array or nil)", + rb_obj_class(keys)); + + } + + for (i=0; i<RARRAY_LEN(keys); i++) { + VALUE key = RARRAY_AREF(keys, i); + + if (sym_year == key) rb_hash_aset(h, key, m_real_year(dat)); + if (sym_month == key) rb_hash_aset(h, key, INT2FIX(m_mon(dat))); + if (sym_day == key) rb_hash_aset(h, key, INT2FIX(m_mday(dat))); + if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(m_yday(dat))); + if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(m_wday(dat))); + if (is_datetime) { + if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(m_hour(dat))); + if (sym_min == key) rb_hash_aset(h, key, INT2FIX(m_min(dat))); + if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(m_sec(dat))); + if (sym_sec_fraction == key) rb_hash_aset(h, key, m_sf_in_sec(dat)); + if (sym_zone == key) rb_hash_aset(h, key, m_zone(dat)); + } + } + return h; +} + +/* + * call-seq: + * deconstruct_keys(array_of_names_or_nil) -> hash + * + * Returns a hash of the name/value pairs, to use in pattern matching. + * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, + * <tt>:wday</tt>, <tt>:yday</tt>. + * + * Possible usages: + * + * d = Date.new(2022, 10, 5) + * + * if d in wday: 3, day: ..7 # uses deconstruct_keys underneath + * puts "first Wednesday of the month" + * end + * #=> prints "first Wednesday of the month" + * + * case d + * in year: ...2022 + * puts "too old" + * in month: ..9 + * puts "quarter 1-3" + * in wday: 1..5, month: + * puts "working day in month #{month}" + * end + * #=> prints "working day in month 10" + * + * Note that deconstruction by pattern can also be combined with class check: + * + * if d in Date(wday: 3, day: ..7) + * puts "first Wednesday of the month" + * end + * + */ +static VALUE +d_lite_deconstruct_keys(VALUE self, VALUE keys) +{ + return deconstruct_keys(self, keys, /* is_datetime=false */ 0); +} + #ifndef NDEBUG +/* :nodoc: */ static VALUE d_lite_marshal_dump_old(VALUE self) { @@ -7129,10 +7720,7 @@ d_lite_marshal_dump_old(VALUE self) m_of_in_day(dat), DBL2NUM(m_sg(dat))); - if (FL_TEST(self, FL_EXIVAR)) { - rb_copy_generic_ivar(a, self); - FL_SET(a, FL_EXIVAR); - } + rb_copy_generic_ivar(a, self); return a; } @@ -7154,10 +7742,8 @@ d_lite_marshal_dump(VALUE self) INT2FIX(m_of(dat)), DBL2NUM(m_sg(dat))); - if (FL_TEST(self, FL_EXIVAR)) { - rb_copy_generic_ivar(a, self); - FL_SET(a, FL_EXIVAR); - } + + rb_copy_generic_ivar(a, self); return a; } @@ -7230,10 +7816,7 @@ d_lite_marshal_load(VALUE self, VALUE a) HAVE_JD | HAVE_DF); } - if (FL_TEST(a, FL_EXIVAR)) { - rb_copy_generic_ivar(self, a); - FL_SET(self, FL_EXIVAR); - } + rb_copy_generic_ivar(self, a); return self; } @@ -7404,17 +7987,7 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass) } /* - * call-seq: - * DateTime.civil([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime - * DateTime.new([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime - * - * Creates a DateTime object denoting the given calendar date. - * - * DateTime.new(2001,2,3) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...> - * DateTime.new(2001,2,3,4,5,6,'+7') - * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> - * DateTime.new(2001,-11,-26,-20,-55,-54,'+7') - * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * Same as DateTime.new. */ static VALUE datetime_s_civil(int argc, VALUE *argv, VALUE klass) @@ -7604,6 +8177,7 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass) } #ifndef NDEBUG +/* :nodoc: */ static VALUE datetime_s_weeknum(int argc, VALUE *argv, VALUE klass) { @@ -7673,6 +8247,7 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass) return ret; } +/* :nodoc: */ static VALUE datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass) { @@ -7994,7 +8569,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: fmt = rb_str_new2("%FT%T%z"); case 2: @@ -8013,14 +8588,14 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime + * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime * * Parses the given representation of date and time, and creates a * DateTime object. * - * This method *does not* function as a validator. If the input + * This method *does* *not* function as a validator. If the input * string does not match valid formats strictly, you may get a cryptic - * result. Should consider to use `DateTime.strptime` instead of this + * result. Should consider to use DateTime.strptime instead of this * method as possible. * * If the optional second argument is true and the detected year is in @@ -8032,17 +8607,21 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> * DateTime.parse('3rd Feb 2001 04:05:06 PM') * #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_parse(int argc, VALUE *argv, VALUE klass) { - VALUE str, comp, sg; + VALUE str, comp, sg, opt; - rb_scan_args(argc, argv, "03", &str, &comp, &sg); + argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: comp = Qtrue; case 2: @@ -8050,18 +8629,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass) } { - VALUE argv2[2], hash; - - argv2[0] = str; - argv2[1] = comp; - hash = date_s__parse(2, argv2, klass); + int argc2 = 2; + VALUE argv2[3], hash; + argv2[0] = str; + argv2[1] = comp; + argv2[2] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__parse(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical ISO 8601 formats. @@ -8072,114 +8653,150 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass) * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> * DateTime.iso8601('2001-W05-6T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__iso8601(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__iso8601(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical RFC 3339 formats. * * DateTime.rfc3339('2001-02-03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__rfc3339(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__rfc3339(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical XML Schema formats. * * DateTime.xmlschema('2001-02-03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__xmlschema(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__xmlschema(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime - * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime + * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime + * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical RFC 2822 formats. * * DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__rfc2822(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__rfc2822(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } @@ -8193,30 +8810,39 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) * * DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT') * #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__httpdate(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__httpdate(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical JIS X 0301 formats. @@ -8228,23 +8854,32 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) * * DateTime.jisx0301('13.02.03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing <code>limit: nil</code>, but note + * that it may take a long time to parse. */ static VALUE datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: - str = rb_str_new2("-4712-01-01T00:00:00+00:00"); + str = rb_str_new2(JULIAN_EPOCH_DATETIME); case 1: sg = INT2FIX(DEFAULT_SG); } { - VALUE hash = date_s__jisx0301(klass, str); + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__jisx0301(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } @@ -8267,181 +8902,16 @@ dt_lite_to_s(VALUE self) /* * call-seq: - * dt.strftime([format='%FT%T%:z']) -> string - * - * Formats date according to the directives in the given format - * string. - * The directives begin with a percent (%) character. - * Any text not listed as a directive will be passed through to the - * output string. - * - * A directive consists of a percent (%) character, - * zero or more flags, an optional minimum field width, - * an optional modifier, and a conversion specifier - * as follows. - * - * %<flags><width><modifier><conversion> - * - * Flags: - * - don't pad a numerical output. - * _ use spaces for padding. - * 0 use zeros for padding. - * ^ upcase the result string. - * # change case. - * : use colons for %z. - * - * The minimum field width specifies the minimum width. - * - * The modifiers are "E" and "O". - * They are ignored. - * - * Format directives: - * - * Date (Year, Month, Day): - * %Y - Year with century (can be negative, 4 digits at least) - * -0001, 0000, 1995, 2009, 14292, etc. - * %C - year / 100 (round down. 20 in 2009) - * %y - year % 100 (00..99) - * - * %m - Month of the year, zero-padded (01..12) - * %_m blank-padded ( 1..12) - * %-m no-padded (1..12) - * %B - The full month name (``January'') - * %^B uppercased (``JANUARY'') - * %b - The abbreviated month name (``Jan'') - * %^b uppercased (``JAN'') - * %h - Equivalent to %b - * - * %d - Day of the month, zero-padded (01..31) - * %-d no-padded (1..31) - * %e - Day of the month, blank-padded ( 1..31) - * - * %j - Day of the year (001..366) - * - * Time (Hour, Minute, Second, Subsecond): - * %H - Hour of the day, 24-hour clock, zero-padded (00..23) - * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23) - * %I - Hour of the day, 12-hour clock, zero-padded (01..12) - * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12) - * %P - Meridian indicator, lowercase (``am'' or ``pm'') - * %p - Meridian indicator, uppercase (``AM'' or ``PM'') - * - * %M - Minute of the hour (00..59) - * - * %S - Second of the minute (00..60) - * - * %L - Millisecond of the second (000..999) - * %N - Fractional seconds digits, default is 9 digits (nanosecond) - * %3N millisecond (3 digits) %15N femtosecond (15 digits) - * %6N microsecond (6 digits) %18N attosecond (18 digits) - * %9N nanosecond (9 digits) %21N zeptosecond (21 digits) - * %12N picosecond (12 digits) %24N yoctosecond (24 digits) - * - * Time zone: - * %z - Time zone as hour and minute offset from UTC (e.g. +0900) - * %:z - hour and minute offset from UTC with a colon (e.g. +09:00) - * %::z - hour, minute and second offset from UTC (e.g. +09:00:00) - * %:::z - hour, minute and second offset from UTC - * (e.g. +09, +09:30, +09:30:30) - * %Z - Equivalent to %:z (e.g. +09:00) - * - * Weekday: - * %A - The full weekday name (``Sunday'') - * %^A uppercased (``SUNDAY'') - * %a - The abbreviated name (``Sun'') - * %^a uppercased (``SUN'') - * %u - Day of the week (Monday is 1, 1..7) - * %w - Day of the week (Sunday is 0, 0..6) - * - * ISO 8601 week-based year and week number: - * The week 1 of YYYY starts with a Monday and includes YYYY-01-04. - * The days in the year before the first week are in the last week of - * the previous year. - * %G - The week-based year - * %g - The last 2 digits of the week-based year (00..99) - * %V - Week number of the week-based year (01..53) - * - * Week number: - * The week 1 of YYYY starts with a Sunday or Monday (according to %U - * or %W). The days in the year before the first week are in week 0. - * %U - Week number of the year. The week starts with Sunday. (00..53) - * %W - Week number of the year. The week starts with Monday. (00..53) - * - * Seconds since the Unix Epoch: - * %s - Number of seconds since 1970-01-01 00:00:00 UTC. - * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC. - * - * Literal string: - * %n - Newline character (\n) - * %t - Tab character (\t) - * %% - Literal ``%'' character - * - * Combination: - * %c - date and time (%a %b %e %T %Y) - * %D - Date (%m/%d/%y) - * %F - The ISO 8601 date format (%Y-%m-%d) - * %v - VMS date (%e-%^b-%Y) - * %x - Same as %D - * %X - Same as %T - * %r - 12-hour time (%I:%M:%S %p) - * %R - 24-hour time (%H:%M) - * %T - 24-hour time (%H:%M:%S) - * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y) - * - * This method is similar to the strftime() function defined in ISO C - * and POSIX. - * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z) - * are locale dependent in the function. - * However, this method is locale independent. - * So, the result may differ even if the same format string is used in other - * systems such as C. - * It is good practice to avoid %x and %X because there are corresponding - * locale independent representations, %D and %T. - * - * Examples: - * - * d = DateTime.new(2007,11,19,8,37,48,"-06:00") - * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...> - * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" - * d.strftime("at %I:%M%p") #=> "at 08:37AM" - * - * Various ISO 8601 formats: - * %Y%m%d => 20071119 Calendar date (basic) - * %F => 2007-11-19 Calendar date (extended) - * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month - * %Y => 2007 Calendar date, reduced accuracy, specific year - * %C => 20 Calendar date, reduced accuracy, specific century - * %Y%j => 2007323 Ordinal date (basic) - * %Y-%j => 2007-323 Ordinal date (extended) - * %GW%V%u => 2007W471 Week date (basic) - * %G-W%V-%u => 2007-W47-1 Week date (extended) - * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic) - * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended) - * %H%M%S => 083748 Local time (basic) - * %T => 08:37:48 Local time (extended) - * %H%M => 0837 Local time, reduced accuracy, specific minute (basic) - * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended) - * %H => 08 Local time, reduced accuracy, specific hour - * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic) - * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended) - * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic) - * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended) - * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic) - * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended) - * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic) - * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended) - * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic) - * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended) - * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic) - * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended) - * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic) - * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended) - * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic) - * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended) - * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic) - * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended) - * - * See also strftime(3) and ::strptime. + * strftime(format = '%FT%T%:z') -> string + * + * Returns a string representation of +self+, + * formatted according the given +format: + * + * DateTime.now.strftime # => "2022-07-01T11:03:19-05:00" + * + * For other formats, + * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]: + * */ static VALUE dt_lite_strftime(int argc, VALUE *argv, VALUE self) @@ -8529,6 +8999,47 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self) iso8601_timediv(self, n)); } +/* + * call-seq: + * deconstruct_keys(array_of_names_or_nil) -> hash + * + * Returns a hash of the name/value pairs, to use in pattern matching. + * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, + * <tt>:wday</tt>, <tt>:yday</tt>, <tt>:hour</tt>, <tt>:min</tt>, + * <tt>:sec</tt>, <tt>:sec_fraction</tt>, <tt>:zone</tt>. + * + * Possible usages: + * + * dt = DateTime.new(2022, 10, 5, 13, 30) + * + * if d in wday: 1..5, hour: 10..18 # uses deconstruct_keys underneath + * puts "Working time" + * end + * #=> prints "Working time" + * + * case dt + * in year: ...2022 + * puts "too old" + * in month: ..9 + * puts "quarter 1-3" + * in wday: 1..5, month: + * puts "working day in month #{month}" + * end + * #=> prints "working day in month 10" + * + * Note that deconstruction by pattern can also be combined with class check: + * + * if d in DateTime(wday: 1..5, hour: 10..18, day: ..7) + * puts "Working time, first week of the month" + * end + * + */ +static VALUE +dt_lite_deconstruct_keys(VALUE self, VALUE keys) +{ + return deconstruct_keys(self, keys, /* is_datetime=true */ 1); +} + /* conversions */ #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0) @@ -8607,7 +9118,7 @@ time_to_datetime(VALUE self) ret = d_complex_new_internal(cDateTime, nth, 0, 0, sf, - of, DEFAULT_SG, + of, GREGORIAN, ry, m, d, h, min, s, HAVE_CIVIL | HAVE_TIME); @@ -8620,33 +9131,43 @@ time_to_datetime(VALUE self) /* * call-seq: - * d.to_time -> time + * to_time -> time + * + * Returns a new Time object with the same value as +self+; + * if +self+ is a Julian date, derives its Gregorian date + * for conversion to the \Time object: + * + * Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600 + * Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600 * - * Returns a Time object which denotes self. If self is a julian date, - * convert it to a gregorian date before converting it to Time. */ static VALUE date_to_time(VALUE self) { + VALUE t; + get_d1a(self); if (m_julian_p(adat)) { - VALUE tmp = d_lite_gregorian(self); - get_d1b(tmp); + VALUE g = d_lite_gregorian(self); + get_d1b(g); adat = bdat; + self = g; } - return f_local3(rb_cTime, + t = f_local3(rb_cTime, m_real_year(adat), INT2FIX(m_mon(adat)), INT2FIX(m_mday(adat))); + RB_GC_GUARD(self); /* may be the converted gregorian */ + return t; } /* * call-seq: - * d.to_date -> self + * to_date -> self * - * Returns self. + * Returns +self+. */ static VALUE date_to_date(VALUE self) @@ -8658,7 +9179,10 @@ date_to_date(VALUE self) * call-seq: * d.to_datetime -> datetime * - * Returns a DateTime object which denotes self. + * Returns a DateTime whose value is the same as +self+: + * + * Date.new(2001, 2, 3).to_datetime # => #<DateTime: 2001-02-03T00:00:00+00:00> + * */ static VALUE date_to_datetime(VALUE self) @@ -8703,12 +9227,18 @@ date_to_datetime(VALUE self) static VALUE datetime_to_time(VALUE self) { - volatile VALUE dup = dup_obj(self); + get_d1(self); + + if (m_julian_p(dat)) { + VALUE g = d_lite_gregorian(self); + get_d1a(g); + dat = adat; + self = g; + } + { VALUE t; - get_d1(dup); - t = rb_funcall(rb_cTime, rb_intern("new"), 7, @@ -8720,6 +9250,7 @@ datetime_to_time(VALUE self) f_add(INT2FIX(m_sec(dat)), m_sf_in_sec(dat)), INT2FIX(m_of(dat))); + RB_GC_GUARD(self); /* may be the converted gregorian */ return t; } } @@ -8776,6 +9307,7 @@ datetime_to_datetime(VALUE self) #define MIN_JD -327 #define MAX_JD 366963925 +/* :nodoc: */ static int test_civil(int from, int to, double sg) { @@ -8796,6 +9328,7 @@ test_civil(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_civil(VALUE klass) { @@ -8816,6 +9349,7 @@ date_s_test_civil(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_ordinal(int from, int to, double sg) { @@ -8836,6 +9370,7 @@ test_ordinal(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_ordinal(VALUE klass) { @@ -8856,6 +9391,7 @@ date_s_test_ordinal(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_commercial(int from, int to, double sg) { @@ -8876,6 +9412,7 @@ test_commercial(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_commercial(VALUE klass) { @@ -8896,6 +9433,7 @@ date_s_test_commercial(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_weeknum(int from, int to, int f, double sg) { @@ -8916,6 +9454,7 @@ test_weeknum(int from, int to, int f, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_weeknum(VALUE klass) { @@ -8940,6 +9479,7 @@ date_s_test_weeknum(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_nth_kday(int from, int to, double sg) { @@ -8960,6 +9500,7 @@ test_nth_kday(int from, int to, double sg) return 1; } +/* :nodoc: */ static VALUE date_s_test_nth_kday(VALUE klass) { @@ -8980,6 +9521,7 @@ date_s_test_nth_kday(VALUE klass) return Qtrue; } +/* :nodoc: */ static int test_unit_v2v(VALUE i, VALUE (* conv1)(VALUE), @@ -8991,6 +9533,7 @@ test_unit_v2v(VALUE i, return f_eqeq_p(o, i); } +/* :nodoc: */ static int test_unit_v2v_iter2(VALUE (* conv1)(VALUE), VALUE (* conv2)(VALUE)) @@ -9022,6 +9565,7 @@ test_unit_v2v_iter2(VALUE (* conv1)(VALUE), return 1; } +/* :nodoc: */ static int test_unit_v2v_iter(VALUE (* conv1)(VALUE), VALUE (* conv2)(VALUE)) @@ -9033,6 +9577,7 @@ test_unit_v2v_iter(VALUE (* conv1)(VALUE), return 1; } +/* :nodoc: */ static VALUE date_s_test_unit_conv(VALUE klass) { @@ -9047,6 +9592,7 @@ date_s_test_unit_conv(VALUE klass) return Qtrue; } +/* :nodoc: */ static VALUE date_s_test_all(VALUE klass) { @@ -9109,10 +9655,11 @@ mk_ary_of_str(long len, const char *a[]) } rb_ary_push(o, e); } - rb_obj_freeze(o); + rb_ary_freeze(o); return o; } +/* :nodoc: */ static VALUE d_lite_zero(VALUE x) { @@ -9130,7 +9677,19 @@ Init_date_core(void) id_ge_p = rb_intern_const(">="); id_eqeq_p = rb_intern_const("=="); + sym_year = ID2SYM(rb_intern_const("year")); + sym_month = ID2SYM(rb_intern_const("month")); + sym_yday = ID2SYM(rb_intern_const("yday")); + sym_wday = ID2SYM(rb_intern_const("wday")); + sym_day = ID2SYM(rb_intern_const("day")); + sym_hour = ID2SYM(rb_intern_const("hour")); + sym_min = ID2SYM(rb_intern_const("min")); + sym_sec = ID2SYM(rb_intern_const("sec")); + sym_sec_fraction = ID2SYM(rb_intern_const("sec_fraction")); + sym_zone = ID2SYM(rb_intern_const("zone")); + half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2)); + rb_gc_register_mark_object(half_days_in_day); #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS day_in_nanoseconds = LONG2NUM((long)DAY_IN_SECONDS * @@ -9142,160 +9701,87 @@ Init_date_core(void) day_in_nanoseconds = f_mul(INT2FIX(DAY_IN_SECONDS), INT2FIX(SECOND_IN_NANOSECONDS)); #endif - - rb_gc_register_mark_object(half_days_in_day); rb_gc_register_mark_object(day_in_nanoseconds); positive_inf = +INFINITY; negative_inf = -INFINITY; /* - * date and datetime class - Tadayoshi Funaba 1998-2011 - * - * 'date' provides two classes: Date and DateTime. + * \Class \Date provides methods for storing and manipulating + * calendar dates. * - * == Terms and Definitions + * Consider using + * {class Time}[rdoc-ref:Time] + * instead of class \Date if: * - * Some terms and definitions are based on ISO 8601 and JIS X 0301. + * - You need both dates and times; \Date handles only dates. + * - You need only Gregorian dates (and not Julian dates); + * see {Julian and Gregorian Calendars}[rdoc-ref:language/calendars.rdoc]. * - * === Calendar Date + * A \Date object, once created, is immutable, and cannot be modified. * - * The calendar date is a particular day of a calendar year, - * identified by its ordinal number within a calendar month within - * that year. + * == Creating a \Date * - * In those classes, this is so-called "civil". + * You can create a date for the current date, using Date.today: * - * === Ordinal Date + * Date.today # => #<Date: 1999-12-31> * - * The ordinal date is a particular day of a calendar year identified - * by its ordinal number within the year. + * You can create a specific date from various combinations of arguments: * - * In those classes, this is so-called "ordinal". + * - Date.new takes integer year, month, and day-of-month: * - * === Week Date + * Date.new(1999, 12, 31) # => #<Date: 1999-12-31> * - * The week date is a date identified by calendar week and day numbers. + * - Date.ordinal takes integer year and day-of-year: * - * The calendar week is a seven day period within a calendar year, - * starting on a Monday and identified by its ordinal number within - * the year; the first calendar week of the year is the one that - * includes the first Thursday of that year. In the Gregorian - * calendar, this is equivalent to the week which includes January 4. + * Date.ordinal(1999, 365) # => #<Date: 1999-12-31> * - * In those classes, this is so-called "commercial". + * - Date.jd takes integer Julian day: * - * === Julian Day Number + * Date.jd(2451544) # => #<Date: 1999-12-31> * - * The Julian day number is in elapsed days since noon (Greenwich Mean - * Time) on January 1, 4713 BCE (in the Julian calendar). + * - Date.commercial takes integer commercial data (year, week, day-of-week): * - * In this document, the astronomical Julian day number is the same as - * the original Julian day number. And the chronological Julian day - * number is a variation of the Julian day number. Its days begin at - * midnight on local time. + * Date.commercial(1999, 52, 5) # => #<Date: 1999-12-31> * - * In this document, when the term "Julian day number" simply appears, - * it just refers to "chronological Julian day number", not the - * original. + * - Date.parse takes a string, which it parses heuristically: * - * In those classes, those are so-called "ajd" and "jd". + * Date.parse('1999-12-31') # => #<Date: 1999-12-31> + * Date.parse('31-12-1999') # => #<Date: 1999-12-31> + * Date.parse('1999-365') # => #<Date: 1999-12-31> + * Date.parse('1999-W52-5') # => #<Date: 1999-12-31> * - * === Modified Julian Day Number + * - Date.strptime takes a date string and a format string, + * then parses the date string according to the format string: * - * The modified Julian day number is in elapsed days since midnight - * (Coordinated Universal Time) on November 17, 1858 CE (in the - * Gregorian calendar). + * Date.strptime('1999-12-31', '%Y-%m-%d') # => #<Date: 1999-12-31> + * Date.strptime('31-12-1999', '%d-%m-%Y') # => #<Date: 1999-12-31> + * Date.strptime('1999-365', '%Y-%j') # => #<Date: 1999-12-31> + * Date.strptime('1999-W52-5', '%G-W%V-%u') # => #<Date: 1999-12-31> + * Date.strptime('1999 52 5', '%Y %U %w') # => #<Date: 1999-12-31> + * Date.strptime('1999 52 5', '%Y %W %u') # => #<Date: 1999-12-31> + * Date.strptime('fri31dec99', '%a%d%b%y') # => #<Date: 1999-12-31> * - * In this document, the astronomical modified Julian day number is - * the same as the original modified Julian day number. And the - * chronological modified Julian day number is a variation of the - * modified Julian day number. Its days begin at midnight on local - * time. + * See also the specialized methods in + * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings] * - * In this document, when the term "modified Julian day number" simply - * appears, it just refers to "chronological modified Julian day - * number", not the original. + * == Argument +limit+ * - * In those classes, those are so-called "amjd" and "mjd". + * Certain singleton methods in \Date that parse string arguments + * also take optional keyword argument +limit+, + * which can limit the length of the string argument. * - * == Date + * When +limit+ is: * - * A subclass of Object that includes the Comparable module and - * easily handles date. - * - * A Date object is created with Date::new, Date::jd, Date::ordinal, - * Date::commercial, Date::parse, Date::strptime, Date::today, - * Time#to_date, etc. - * - * require 'date' - * - * Date.new(2001,2,3) - * #=> #<Date: 2001-02-03 ...> - * Date.jd(2451944) - * #=> #<Date: 2001-02-03 ...> - * Date.ordinal(2001,34) - * #=> #<Date: 2001-02-03 ...> - * Date.commercial(2001,5,6) - * #=> #<Date: 2001-02-03 ...> - * Date.parse('2001-02-03') - * #=> #<Date: 2001-02-03 ...> - * Date.strptime('03-02-2001', '%d-%m-%Y') - * #=> #<Date: 2001-02-03 ...> - * Time.new(2001,2,3).to_date - * #=> #<Date: 2001-02-03 ...> - * - * All date objects are immutable; hence cannot modify themselves. - * - * The concept of a date object can be represented as a tuple - * of the day count, the offset and the day of calendar reform. - * - * The day count denotes the absolute position of a temporal - * dimension. The offset is relative adjustment, which determines - * decoded local time with the day count. The day of calendar - * reform denotes the start day of the new style. The old style - * of the West is the Julian calendar which was adopted by - * Caesar. The new style is the Gregorian calendar, which is the - * current civil calendar of many countries. - * - * The day count is virtually the astronomical Julian day number. - * The offset in this class is usually zero, and cannot be - * specified directly. - * - * A Date object can be created with an optional argument, - * the day of calendar reform as a Julian day number, which - * should be 2298874 to 2426355 or negative/positive infinity. - * The default value is +Date::ITALY+ (2299161=1582-10-15). - * See also sample/cal.rb. - * - * $ ruby sample/cal.rb -c it 10 1582 - * October 1582 - * S M Tu W Th F S - * 1 2 3 4 15 16 - * 17 18 19 20 21 22 23 - * 24 25 26 27 28 29 30 - * 31 - * - * $ ruby sample/cal.rb -c gb 9 1752 - * September 1752 - * S M Tu W Th F S - * 1 2 14 15 16 - * 17 18 19 20 21 22 23 - * 24 25 26 27 28 29 30 - * - * A Date object has various methods. See each reference. - * - * d = Date.parse('3rd Feb 2001') - * #=> #<Date: 2001-02-03 ...> - * d.year #=> 2001 - * d.mon #=> 2 - * d.mday #=> 3 - * d.wday #=> 6 - * d += 1 #=> #<Date: 2001-02-04 ...> - * d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001" + * - Non-negative: + * raises ArgumentError if the string length is greater than _limit_. + * - Other numeric or +nil+: ignores +limit+. + * - Other non-numeric: raises TypeError. * */ cDate = rb_define_class("Date", rb_cObject); + + /* Exception for invalid date/time */ eDateError = rb_define_class_under(cDate, "Error", rb_eArgError); rb_include_module(cDate, rb_mComparable); @@ -9403,19 +9889,19 @@ Init_date_core(void) rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1); rb_define_singleton_method(cDate, "_parse", date_s__parse, -1); rb_define_singleton_method(cDate, "parse", date_s_parse, -1); - rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1); + rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1); rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1); - rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1); + rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1); rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1); - rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1); + rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1); rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1); - rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1); - rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1); + rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1); + rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1); rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1); rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1); - rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1); + rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1); rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1); - rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1); + rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1); rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1); rb_define_method(cDate, "initialize", date_initialize, -1); @@ -9522,6 +10008,8 @@ Init_date_core(void) rb_define_method(cDate, "httpdate", d_lite_httpdate, 0); rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0); + rb_define_method(cDate, "deconstruct_keys", d_lite_deconstruct_keys, 1); + #ifndef NDEBUG rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0); #endif @@ -9732,6 +10220,8 @@ Init_date_core(void) rb_define_method(cDateTime, "rfc3339", dt_lite_rfc3339, -1); rb_define_method(cDateTime, "jisx0301", dt_lite_jisx0301, -1); + rb_define_method(cDateTime, "deconstruct_keys", dt_lite_deconstruct_keys, 1); + /* conversions */ rb_define_method(rb_cTime, "to_time", time_to_time, 0); diff --git a/ext/date/date_parse.c b/ext/date/date_parse.c index 5fa036ed72..a1600e4708 100644 --- a/ext/date/date_parse.c +++ b/ext/date/date_parse.c @@ -7,6 +7,9 @@ #include "ruby/re.h" #include <ctype.h> +#undef strncasecmp +#define strncasecmp STRNCASECMP + RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y); RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow); @@ -253,6 +256,8 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc) #define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat" #define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec" +#define NUMBER "(?<!\\d)\\d" + #ifdef TIGHT_PARSER #define VALID_DAYS "(?:" DAYS ")" "|(?:tues|wednes|thurs|thur|" ABBR_DAYS ")\\.?" #define VALID_MONTHS "(?:" MONTHS ")" "|(?:sept|" ABBR_MONTHS ")\\.?" @@ -411,7 +416,6 @@ VALUE date_zone_to_diff(VALUE str) { VALUE offset = Qnil; - VALUE vbuf = 0; long l = RSTRING_LEN(str); const char *s = RSTRING_PTR(str); @@ -437,16 +441,26 @@ date_zone_to_diff(VALUE str) l -= w; dst = 1; } + { + const char *zn = s; long sl = shrunk_size(s, l); + char shrunk_buff[MAX_WORD_LENGTH]; /* no terminator to be added */ + const struct zone *z = 0; + + if (sl <= 0) { + sl = l; + } + else if (sl <= MAX_WORD_LENGTH) { + char *d = shrunk_buff; + sl = shrink_space(d, s, l); + zn = d; + } + if (sl > 0 && sl <= MAX_WORD_LENGTH) { - char *d = ALLOCV_N(char, vbuf, sl); - l = shrink_space(d, s, l); - s = d; + z = zonetab(zn, (unsigned int)sl); } - } - if (l > 0 && l <= MAX_WORD_LENGTH) { - const struct zone *z = zonetab(s, (unsigned int)l); + if (z) { int d = z->offset; if (dst) @@ -455,6 +469,7 @@ date_zone_to_diff(VALUE str) goto ok; } } + { char *p; int sign = 0; @@ -471,27 +486,53 @@ date_zone_to_diff(VALUE str) s++; l--; +#define out_of_range(v, min, max) ((v) < (min) || (max) < (v)) hour = STRTOUL(s, &p, 10); if (*p == ':') { + if (out_of_range(hour, 0, 23)) return Qnil; s = ++p; min = STRTOUL(s, &p, 10); + if (out_of_range(min, 0, 59)) return Qnil; if (*p == ':') { s = ++p; sec = STRTOUL(s, &p, 10); + if (out_of_range(sec, 0, 59)) return Qnil; } - goto num; } - if (*p == ',' || *p == '.') { - char *e = 0; - p++; - min = STRTOUL(p, &e, 10) * 3600; + else if (*p == ',' || *p == '.') { + /* fractional hour */ + size_t n; + int ov; + /* no over precision for offset; 10**-7 hour = 0.36 + * milliseconds should be enough. */ + const size_t max_digits = 7; /* 36 * 10**7 < 32-bit FIXNUM_MAX */ + + if (out_of_range(hour, 0, 23)) return Qnil; + + n = (s + l) - ++p; + if (n > max_digits) n = max_digits; + sec = ruby_scan_digits(p, n, 10, &n, &ov); + if ((p += n) < s + l && *p >= ('5' + !(sec & 1)) && *p <= '9') { + /* round half to even */ + sec++; + } + sec *= 36; if (sign) { hour = -hour; - min = -min; + sec = -sec; + } + if (n <= 2) { + /* HH.nn or HH.n */ + if (n == 1) sec *= 10; + offset = INT2FIX(sec + hour * 3600); + } + else { + VALUE denom = rb_int_positive_pow(10, (int)(n - 2)); + offset = f_add(rb_rational_new(INT2FIX(sec), denom), INT2FIX(hour * 3600)); + if (rb_rational_den(offset) == INT2FIX(1)) { + offset = rb_rational_num(offset); + } } - offset = rb_rational_new(INT2FIX(min), - rb_int_positive_pow(10, (int)(e - p))); - offset = f_add(INT2FIX(hour * 3600), offset); goto ok; } else if (l > 2) { @@ -504,18 +545,16 @@ date_zone_to_diff(VALUE str) min = ruby_scan_digits(&s[2 - l % 2], 2, 10, &n, &ov); if (l >= 5) sec = ruby_scan_digits(&s[4 - l % 2], 2, 10, &n, &ov); - goto num; } - num: sec += min * 60 + hour * 3600; if (sign) sec = -sec; offset = INT2FIX(sec); +#undef out_of_range } } } RB_GC_GUARD(str); ok: - ALLOCV_END(vbuf); return offset; } @@ -652,24 +691,27 @@ parse_time(VALUE str, VALUE hash) { static const char pat_source[] = "(" + "" NUMBER "+\\s*" "(?:" - "\\d+\\s*:\\s*\\d+" "(?:" + ":\\s*\\d+" + "(?:" #ifndef TIGHT_PARSER - "\\s*:\\s*\\d+(?:[,.]\\d*)?" + "\\s*:\\s*\\d+(?:[,.]\\d*)?" #else - "\\s*:\\s*\\d+(?:[,.]\\d+)?" + "\\s*:\\s*\\d+(?:[,.]\\d+)?" #endif + ")?" + "|" + "h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?" + ")" + "(?:" + "\\s*" + "[ap](?:m\\b|\\.m\\.)" ")?" "|" - "\\d+\\s*h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?" - ")" - "(?:" - "\\s*" "[ap](?:m\\b|\\.m\\.)" - ")?" - "|" - "\\d+\\s*[ap](?:m\\b|\\.m\\.)" + ")" ")" "(?:" "\\s*" @@ -691,6 +733,9 @@ parse_time(VALUE str, VALUE hash) #endif } +#define BEGIN_ERA "\\b" +#define END_ERA "(?!(?<!\\.)[a-z])" + #ifdef TIGHT_PARSER static int parse_era1_cb(VALUE m, VALUE hash) @@ -702,7 +747,7 @@ static int parse_era1(VALUE str, VALUE hash) { static const char pat_source[] = - "(a(?:d|\\.d\\.))"; + BEGIN_ERA "(a(?:d\\b|\\.d\\.))" END_ERA; static VALUE pat = Qnil; REGCOMP_I(pat); @@ -724,8 +769,9 @@ parse_era2_cb(VALUE m, VALUE hash) static int parse_era2(VALUE str, VALUE hash) { - static const char pat_source[] = - "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|b(?:c|\\.c\\.))"; + static const char pat_source[] = BEGIN_ERA + "(c(?:e\\b|\\.e\\.)|b(?:ce\\b|\\.c\\.e\\.)|b(?:c\\b|\\.c\\.))" + END_ERA; static VALUE pat = Qnil; REGCOMP_I(pat); @@ -829,7 +875,7 @@ parse_eu(VALUE str, VALUE hash) FPW_COM FPT_COM #endif #ifndef TIGHT_PARSER - "('?\\d+)[^-\\d\\s]*" + "('?" NUMBER "+)[^-\\d\\s]*" #else "(\\d+)(?:(?:st|nd|rd|th)\\b)?" #endif @@ -842,7 +888,11 @@ parse_eu(VALUE str, VALUE hash) "(?:" "\\s*" #ifndef TIGHT_PARSER - "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?" + "(?:" + BEGIN_ERA + "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))" + END_ERA + ")?" "\\s*" "('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)" #else @@ -919,8 +969,8 @@ parse_us(VALUE str, VALUE hash) COM_FPT #endif "(?:" - "\\s*,?" - "\\s*" + "\\s*+,?" + "\\s*+" #ifndef TIGHT_PARSER "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?" "\\s*" @@ -967,7 +1017,7 @@ parse_iso(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "('?[-+]?\\d+)-(\\d+)-('?-?\\d+)" + "('?[-+]?" NUMBER "+)-(\\d+)-('?-?\\d+)" #else BOS FPW_COM FPT_COM @@ -1321,7 +1371,7 @@ parse_vms11(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "('?-?\\d+)-(" ABBR_MONTHS ")[^-/.]*" + "('?-?" NUMBER "+)-(" ABBR_MONTHS ")[^-/.]*" "-('?-?\\d+)" #else BOS @@ -1416,7 +1466,7 @@ parse_sla(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "('?-?\\d+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?" + "('?-?" NUMBER "+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?" #else BOS FPW_COM FPT_COM @@ -1524,7 +1574,7 @@ parse_dot(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "('?-?\\d+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)" + "('?-?" NUMBER "+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)" #else BOS FPW_COM FPT_COM @@ -1684,7 +1734,7 @@ parse_mday(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "(\\d+)(st|nd|rd|th)\\b" + "(" NUMBER "+)(st|nd|rd|th)\\b" #else BOS FPW_COM FPT_COM @@ -1922,7 +1972,7 @@ parse_ddd(VALUE str, VALUE hash) #ifdef TIGHT_PARSER BOS #endif - "([-+]?)(\\d{2,14})" + "([-+]?)(" NUMBER "{2,14})" "(?:" "\\s*" "t?" diff --git a/ext/date/date_strptime.c b/ext/date/date_strptime.c index 7b06a31471..f1c8201de8 100644 --- a/ext/date/date_strptime.c +++ b/ext/date/date_strptime.c @@ -7,31 +7,21 @@ #include "ruby/re.h" #include <ctype.h> +#undef strncasecmp +#define strncasecmp STRNCASECMP + static const char *day_names[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", - "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" }; +static const int ABBREVIATED_DAY_NAME_LENGTH = 3; static const char *month_names[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -static const char *merid_names[] = { - "am", "pm", - "a.m.", "p.m." -}; - -static const char *extz_pats[] = { - ":z", - "::z", - ":::z" }; +static const int ABBREVIATED_MONTH_NAME_LENGTH = 3; #define sizeof_array(o) (sizeof o / sizeof o[0]) @@ -75,7 +65,7 @@ num_pattern_p(const char *s) #define NUM_PATTERN_P() num_pattern_p(&fmt[fi + 1]) static long -read_digits(const char *s, VALUE *n, size_t width) +read_digits(const char *s, size_t slen, VALUE *n, size_t width) { size_t l; @@ -83,7 +73,7 @@ read_digits(const char *s, VALUE *n, size_t width) return 0; l = 0; - while (ISDIGIT(s[l])) { + while (l < slen && ISDIGIT(s[l])) { if (++l == width) break; } @@ -131,9 +121,10 @@ do { \ #define READ_DIGITS(n,w) \ do { \ size_t l; \ - l = read_digits(&str[si], &n, w); \ - if (l == 0) \ + l = read_digits(&str[si], slen - si, &n, w); \ + if (l == 0) { \ fail(); \ + } \ si += l; \ } while (0) @@ -161,6 +152,12 @@ do { \ VALUE date_zone_to_diff(VALUE); +static inline int +head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t si) +{ + return slen - si >= len && strncasecmp(name, &str[si], len) == 0; +} + static size_t date__strptime_internal(const char *str, size_t slen, const char *fmt, size_t flen, VALUE hash) @@ -168,9 +165,18 @@ date__strptime_internal(const char *str, size_t slen, size_t si, fi; int c; +#define HEAD_MATCH_P(len, name) head_match_p(len, name, str, slen, si) si = fi = 0; while (fi < flen) { + if (isspace((unsigned char)fmt[fi])) { + while (si < slen && isspace((unsigned char)str[si])) + si++; + while (++fi < flen && isspace((unsigned char)fmt[fi])); + continue; + } + + if (si >= slen) fail(); switch (fmt[fi]) { case '%': @@ -194,12 +200,11 @@ date__strptime_internal(const char *str, size_t slen, { int i; - for (i = 0; i < (int)sizeof_array(extz_pats); i++) - if (strncmp(extz_pats[i], &fmt[fi], - strlen(extz_pats[i])) == 0) { - fi += i; - goto again; - } + for (i = 1; i < 3 && fi + i < flen && fmt[fi+i] == ':'; ++i); + if (fmt[fi+i] == 'z') { + fi += i - 1; + goto again; + } fail(); } @@ -209,10 +214,12 @@ date__strptime_internal(const char *str, size_t slen, int i; for (i = 0; i < (int)sizeof_array(day_names); i++) { - size_t l = strlen(day_names[i]); - if (strncasecmp(day_names[i], &str[si], l) == 0) { + const char *day_name = day_names[i]; + size_t l = strlen(day_name); + if (HEAD_MATCH_P(l, day_name) || + HEAD_MATCH_P(l = ABBREVIATED_DAY_NAME_LENGTH, day_name)) { si += l; - set_hash("wday", INT2FIX(i % 7)); + set_hash("wday", INT2FIX(i)); goto matched; } } @@ -225,10 +232,12 @@ date__strptime_internal(const char *str, size_t slen, int i; for (i = 0; i < (int)sizeof_array(month_names); i++) { - size_t l = strlen(month_names[i]); - if (strncasecmp(month_names[i], &str[si], l) == 0) { + const char *month_name = month_names[i]; + size_t l = strlen(month_name); + if (HEAD_MATCH_P(l, month_name) || + HEAD_MATCH_P(l = ABBREVIATED_MONTH_NAME_LENGTH, month_name)) { si += l; - set_hash("mon", INT2FIX((i % 12) + 1)); + set_hash("mon", INT2FIX(i + 1)); goto matched; } } @@ -402,18 +411,19 @@ date__strptime_internal(const char *str, size_t slen, case 'P': case 'p': + if (slen - si < 2) fail(); { - int i; - - for (i = 0; i < 4; i++) { - size_t l = strlen(merid_names[i]); - if (strncasecmp(merid_names[i], &str[si], l) == 0) { - si += l; - set_hash("_merid", INT2FIX((i % 2) == 0 ? 0 : 12)); - goto matched; - } + char c = str[si]; + const int hour = (c == 'P' || c == 'p') ? 12 : 0; + if (!hour && !(c == 'A' || c == 'a')) fail(); + if ((c = str[si+1]) == '.') { + if (slen - si < 4 || str[si+3] != '.') fail(); + c = str[si += 2]; } - fail(); + if (!(c == 'M' || c == 'm')) fail(); + si += 2; + set_hash("_merid", INT2FIX(hour)); + goto matched; } case 'Q': @@ -587,7 +597,7 @@ date__strptime_internal(const char *str, size_t slen, b = rb_backref_get(); rb_match_busy(b); - m = f_match(pat, rb_usascii_str_new2(&str[si])); + m = f_match(pat, rb_usascii_str_new(&str[si], slen - si)); if (!NIL_P(m)) { VALUE s, l, o; @@ -619,22 +629,13 @@ date__strptime_internal(const char *str, size_t slen, if (str[si] != '%') fail(); si++; - if (fi < flen) - if (str[si] != fmt[fi]) + if (fi < flen) { + if (si >= slen || str[si] != fmt[fi]) fail(); - si++; + si++; + } goto matched; } - case ' ': - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - while (isspace((unsigned char)str[si])) - si++; - fi++; - break; default: ordinal: if (str[si] != fmt[fi]) diff --git a/ext/date/depend b/ext/date/depend index 9c893745b9..4fb78149a1 100644 --- a/ext/date/depend +++ b/ext/date/depend @@ -7,7 +7,6 @@ date_core.o: $(hdrdir)/ruby/backward.h date_core.o: $(hdrdir)/ruby/backward/2/assume.h date_core.o: $(hdrdir)/ruby/backward/2/attributes.h date_core.o: $(hdrdir)/ruby/backward/2/bool.h -date_core.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h date_core.o: $(hdrdir)/ruby/backward/2/inttypes.h date_core.o: $(hdrdir)/ruby/backward/2/limits.h date_core.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ date_core.o: $(hdrdir)/ruby/backward/2/stdarg.h date_core.o: $(hdrdir)/ruby/defines.h date_core.o: $(hdrdir)/ruby/encoding.h date_core.o: $(hdrdir)/ruby/intern.h +date_core.o: $(hdrdir)/ruby/internal/abi.h date_core.o: $(hdrdir)/ruby/internal/anyargs.h date_core.o: $(hdrdir)/ruby/internal/arithmetic.h date_core.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ date_core.o: $(hdrdir)/ruby/internal/attr/noexcept.h date_core.o: $(hdrdir)/ruby/internal/attr/noinline.h date_core.o: $(hdrdir)/ruby/internal/attr/nonnull.h date_core.o: $(hdrdir)/ruby/internal/attr/noreturn.h +date_core.o: $(hdrdir)/ruby/internal/attr/packed_struct.h date_core.o: $(hdrdir)/ruby/internal/attr/pure.h date_core.o: $(hdrdir)/ruby/internal/attr/restrict.h date_core.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ date_core.o: $(hdrdir)/ruby/internal/intern/enumerator.h date_core.o: $(hdrdir)/ruby/internal/intern/error.h date_core.o: $(hdrdir)/ruby/internal/intern/eval.h date_core.o: $(hdrdir)/ruby/internal/intern/file.h -date_core.o: $(hdrdir)/ruby/internal/intern/gc.h date_core.o: $(hdrdir)/ruby/internal/intern/hash.h date_core.o: $(hdrdir)/ruby/internal/intern/io.h date_core.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ date_core.o: $(hdrdir)/ruby/internal/intern/re.h date_core.o: $(hdrdir)/ruby/internal/intern/ruby.h date_core.o: $(hdrdir)/ruby/internal/intern/select.h date_core.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +date_core.o: $(hdrdir)/ruby/internal/intern/set.h date_core.o: $(hdrdir)/ruby/internal/intern/signal.h date_core.o: $(hdrdir)/ruby/internal/intern/sprintf.h date_core.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ date_core.o: $(hdrdir)/ruby/internal/memory.h date_core.o: $(hdrdir)/ruby/internal/method.h date_core.o: $(hdrdir)/ruby/internal/module.h date_core.o: $(hdrdir)/ruby/internal/newobj.h -date_core.o: $(hdrdir)/ruby/internal/rgengc.h date_core.o: $(hdrdir)/ruby/internal/scan_args.h date_core.o: $(hdrdir)/ruby/internal/special_consts.h date_core.o: $(hdrdir)/ruby/internal/static_assert.h date_core.o: $(hdrdir)/ruby/internal/stdalign.h date_core.o: $(hdrdir)/ruby/internal/stdbool.h +date_core.o: $(hdrdir)/ruby/internal/stdckdint.h date_core.o: $(hdrdir)/ruby/internal/symbol.h date_core.o: $(hdrdir)/ruby/internal/value.h date_core.o: $(hdrdir)/ruby/internal/value_type.h @@ -181,7 +182,6 @@ date_parse.o: $(hdrdir)/ruby/backward.h date_parse.o: $(hdrdir)/ruby/backward/2/assume.h date_parse.o: $(hdrdir)/ruby/backward/2/attributes.h date_parse.o: $(hdrdir)/ruby/backward/2/bool.h -date_parse.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h date_parse.o: $(hdrdir)/ruby/backward/2/inttypes.h date_parse.o: $(hdrdir)/ruby/backward/2/limits.h date_parse.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -190,6 +190,7 @@ date_parse.o: $(hdrdir)/ruby/backward/2/stdarg.h date_parse.o: $(hdrdir)/ruby/defines.h date_parse.o: $(hdrdir)/ruby/encoding.h date_parse.o: $(hdrdir)/ruby/intern.h +date_parse.o: $(hdrdir)/ruby/internal/abi.h date_parse.o: $(hdrdir)/ruby/internal/anyargs.h date_parse.o: $(hdrdir)/ruby/internal/arithmetic.h date_parse.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -227,6 +228,7 @@ date_parse.o: $(hdrdir)/ruby/internal/attr/noexcept.h date_parse.o: $(hdrdir)/ruby/internal/attr/noinline.h date_parse.o: $(hdrdir)/ruby/internal/attr/nonnull.h date_parse.o: $(hdrdir)/ruby/internal/attr/noreturn.h +date_parse.o: $(hdrdir)/ruby/internal/attr/packed_struct.h date_parse.o: $(hdrdir)/ruby/internal/attr/pure.h date_parse.o: $(hdrdir)/ruby/internal/attr/restrict.h date_parse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -296,7 +298,6 @@ date_parse.o: $(hdrdir)/ruby/internal/intern/enumerator.h date_parse.o: $(hdrdir)/ruby/internal/intern/error.h date_parse.o: $(hdrdir)/ruby/internal/intern/eval.h date_parse.o: $(hdrdir)/ruby/internal/intern/file.h -date_parse.o: $(hdrdir)/ruby/internal/intern/gc.h date_parse.o: $(hdrdir)/ruby/internal/intern/hash.h date_parse.o: $(hdrdir)/ruby/internal/intern/io.h date_parse.o: $(hdrdir)/ruby/internal/intern/load.h @@ -313,6 +314,7 @@ date_parse.o: $(hdrdir)/ruby/internal/intern/re.h date_parse.o: $(hdrdir)/ruby/internal/intern/ruby.h date_parse.o: $(hdrdir)/ruby/internal/intern/select.h date_parse.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +date_parse.o: $(hdrdir)/ruby/internal/intern/set.h date_parse.o: $(hdrdir)/ruby/internal/intern/signal.h date_parse.o: $(hdrdir)/ruby/internal/intern/sprintf.h date_parse.o: $(hdrdir)/ruby/internal/intern/string.h @@ -327,12 +329,12 @@ date_parse.o: $(hdrdir)/ruby/internal/memory.h date_parse.o: $(hdrdir)/ruby/internal/method.h date_parse.o: $(hdrdir)/ruby/internal/module.h date_parse.o: $(hdrdir)/ruby/internal/newobj.h -date_parse.o: $(hdrdir)/ruby/internal/rgengc.h date_parse.o: $(hdrdir)/ruby/internal/scan_args.h date_parse.o: $(hdrdir)/ruby/internal/special_consts.h date_parse.o: $(hdrdir)/ruby/internal/static_assert.h date_parse.o: $(hdrdir)/ruby/internal/stdalign.h date_parse.o: $(hdrdir)/ruby/internal/stdbool.h +date_parse.o: $(hdrdir)/ruby/internal/stdckdint.h date_parse.o: $(hdrdir)/ruby/internal/symbol.h date_parse.o: $(hdrdir)/ruby/internal/value.h date_parse.o: $(hdrdir)/ruby/internal/value_type.h @@ -357,7 +359,6 @@ date_strftime.o: $(hdrdir)/ruby/backward.h date_strftime.o: $(hdrdir)/ruby/backward/2/assume.h date_strftime.o: $(hdrdir)/ruby/backward/2/attributes.h date_strftime.o: $(hdrdir)/ruby/backward/2/bool.h -date_strftime.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h date_strftime.o: $(hdrdir)/ruby/backward/2/inttypes.h date_strftime.o: $(hdrdir)/ruby/backward/2/limits.h date_strftime.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -365,6 +366,7 @@ date_strftime.o: $(hdrdir)/ruby/backward/2/stdalign.h date_strftime.o: $(hdrdir)/ruby/backward/2/stdarg.h date_strftime.o: $(hdrdir)/ruby/defines.h date_strftime.o: $(hdrdir)/ruby/intern.h +date_strftime.o: $(hdrdir)/ruby/internal/abi.h date_strftime.o: $(hdrdir)/ruby/internal/anyargs.h date_strftime.o: $(hdrdir)/ruby/internal/arithmetic.h date_strftime.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -402,6 +404,7 @@ date_strftime.o: $(hdrdir)/ruby/internal/attr/noexcept.h date_strftime.o: $(hdrdir)/ruby/internal/attr/noinline.h date_strftime.o: $(hdrdir)/ruby/internal/attr/nonnull.h date_strftime.o: $(hdrdir)/ruby/internal/attr/noreturn.h +date_strftime.o: $(hdrdir)/ruby/internal/attr/packed_struct.h date_strftime.o: $(hdrdir)/ruby/internal/attr/pure.h date_strftime.o: $(hdrdir)/ruby/internal/attr/restrict.h date_strftime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -461,7 +464,6 @@ date_strftime.o: $(hdrdir)/ruby/internal/intern/enumerator.h date_strftime.o: $(hdrdir)/ruby/internal/intern/error.h date_strftime.o: $(hdrdir)/ruby/internal/intern/eval.h date_strftime.o: $(hdrdir)/ruby/internal/intern/file.h -date_strftime.o: $(hdrdir)/ruby/internal/intern/gc.h date_strftime.o: $(hdrdir)/ruby/internal/intern/hash.h date_strftime.o: $(hdrdir)/ruby/internal/intern/io.h date_strftime.o: $(hdrdir)/ruby/internal/intern/load.h @@ -478,6 +480,7 @@ date_strftime.o: $(hdrdir)/ruby/internal/intern/re.h date_strftime.o: $(hdrdir)/ruby/internal/intern/ruby.h date_strftime.o: $(hdrdir)/ruby/internal/intern/select.h date_strftime.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +date_strftime.o: $(hdrdir)/ruby/internal/intern/set.h date_strftime.o: $(hdrdir)/ruby/internal/intern/signal.h date_strftime.o: $(hdrdir)/ruby/internal/intern/sprintf.h date_strftime.o: $(hdrdir)/ruby/internal/intern/string.h @@ -492,12 +495,12 @@ date_strftime.o: $(hdrdir)/ruby/internal/memory.h date_strftime.o: $(hdrdir)/ruby/internal/method.h date_strftime.o: $(hdrdir)/ruby/internal/module.h date_strftime.o: $(hdrdir)/ruby/internal/newobj.h -date_strftime.o: $(hdrdir)/ruby/internal/rgengc.h date_strftime.o: $(hdrdir)/ruby/internal/scan_args.h date_strftime.o: $(hdrdir)/ruby/internal/special_consts.h date_strftime.o: $(hdrdir)/ruby/internal/static_assert.h date_strftime.o: $(hdrdir)/ruby/internal/stdalign.h date_strftime.o: $(hdrdir)/ruby/internal/stdbool.h +date_strftime.o: $(hdrdir)/ruby/internal/stdckdint.h date_strftime.o: $(hdrdir)/ruby/internal/symbol.h date_strftime.o: $(hdrdir)/ruby/internal/value.h date_strftime.o: $(hdrdir)/ruby/internal/value_type.h @@ -518,7 +521,6 @@ date_strptime.o: $(hdrdir)/ruby/backward.h date_strptime.o: $(hdrdir)/ruby/backward/2/assume.h date_strptime.o: $(hdrdir)/ruby/backward/2/attributes.h date_strptime.o: $(hdrdir)/ruby/backward/2/bool.h -date_strptime.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h date_strptime.o: $(hdrdir)/ruby/backward/2/inttypes.h date_strptime.o: $(hdrdir)/ruby/backward/2/limits.h date_strptime.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -527,6 +529,7 @@ date_strptime.o: $(hdrdir)/ruby/backward/2/stdarg.h date_strptime.o: $(hdrdir)/ruby/defines.h date_strptime.o: $(hdrdir)/ruby/encoding.h date_strptime.o: $(hdrdir)/ruby/intern.h +date_strptime.o: $(hdrdir)/ruby/internal/abi.h date_strptime.o: $(hdrdir)/ruby/internal/anyargs.h date_strptime.o: $(hdrdir)/ruby/internal/arithmetic.h date_strptime.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -564,6 +567,7 @@ date_strptime.o: $(hdrdir)/ruby/internal/attr/noexcept.h date_strptime.o: $(hdrdir)/ruby/internal/attr/noinline.h date_strptime.o: $(hdrdir)/ruby/internal/attr/nonnull.h date_strptime.o: $(hdrdir)/ruby/internal/attr/noreturn.h +date_strptime.o: $(hdrdir)/ruby/internal/attr/packed_struct.h date_strptime.o: $(hdrdir)/ruby/internal/attr/pure.h date_strptime.o: $(hdrdir)/ruby/internal/attr/restrict.h date_strptime.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -633,7 +637,6 @@ date_strptime.o: $(hdrdir)/ruby/internal/intern/enumerator.h date_strptime.o: $(hdrdir)/ruby/internal/intern/error.h date_strptime.o: $(hdrdir)/ruby/internal/intern/eval.h date_strptime.o: $(hdrdir)/ruby/internal/intern/file.h -date_strptime.o: $(hdrdir)/ruby/internal/intern/gc.h date_strptime.o: $(hdrdir)/ruby/internal/intern/hash.h date_strptime.o: $(hdrdir)/ruby/internal/intern/io.h date_strptime.o: $(hdrdir)/ruby/internal/intern/load.h @@ -650,6 +653,7 @@ date_strptime.o: $(hdrdir)/ruby/internal/intern/re.h date_strptime.o: $(hdrdir)/ruby/internal/intern/ruby.h date_strptime.o: $(hdrdir)/ruby/internal/intern/select.h date_strptime.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +date_strptime.o: $(hdrdir)/ruby/internal/intern/set.h date_strptime.o: $(hdrdir)/ruby/internal/intern/signal.h date_strptime.o: $(hdrdir)/ruby/internal/intern/sprintf.h date_strptime.o: $(hdrdir)/ruby/internal/intern/string.h @@ -664,12 +668,12 @@ date_strptime.o: $(hdrdir)/ruby/internal/memory.h date_strptime.o: $(hdrdir)/ruby/internal/method.h date_strptime.o: $(hdrdir)/ruby/internal/module.h date_strptime.o: $(hdrdir)/ruby/internal/newobj.h -date_strptime.o: $(hdrdir)/ruby/internal/rgengc.h date_strptime.o: $(hdrdir)/ruby/internal/scan_args.h date_strptime.o: $(hdrdir)/ruby/internal/special_consts.h date_strptime.o: $(hdrdir)/ruby/internal/static_assert.h date_strptime.o: $(hdrdir)/ruby/internal/stdalign.h date_strptime.o: $(hdrdir)/ruby/internal/stdbool.h +date_strptime.o: $(hdrdir)/ruby/internal/stdckdint.h date_strptime.o: $(hdrdir)/ruby/internal/symbol.h date_strptime.o: $(hdrdir)/ruby/internal/value.h date_strptime.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/date/extconf.rb b/ext/date/extconf.rb index f891de403d..8a1467df09 100644 --- a/ext/date/extconf.rb +++ b/ext/date/extconf.rb @@ -3,6 +3,8 @@ require 'mkmf' config_string("strict_warnflags") {|w| $warnflags += " #{w}"} +append_cflags("-Wno-compound-token-split-by-macro") if RUBY_VERSION < "2.7." +have_func("rb_category_warn") with_werror("", {:werror => true}) do |opt, | have_var("timezone", "time.h", opt) have_var("altzone", "time.h", opt) diff --git a/ext/date/lib/date.rb b/ext/date/lib/date.rb index 4901219503..0cb763017f 100644 --- a/ext/date/lib/date.rb +++ b/ext/date/lib/date.rb @@ -4,7 +4,12 @@ require 'date_core' class Date + VERSION = "3.5.1" # :nodoc: + # call-seq: + # infinite? -> false + # + # Returns +false+ def infinite? false end diff --git a/ext/date/prereq.mk b/ext/date/prereq.mk index cee7685975..b5d271a32c 100644 --- a/ext/date/prereq.mk +++ b/ext/date/prereq.mk @@ -1,7 +1,7 @@ .SUFFIXES: .list .list.h: - gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \ + gperf --ignore-case -L ANSI-C -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \ | sed -f $(top_srcdir)/tool/gperf.sed \ > $(@F) diff --git a/ext/date/zonetab.h b/ext/date/zonetab.h index d82b011dc1..2a2e8910c9 100644 --- a/ext/date/zonetab.h +++ b/ext/date/zonetab.h @@ -1,5 +1,5 @@ /* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N zonetab zonetab.list */ +/* Command-line: gperf --ignore-case -L ANSI-C -C -c -P -p -j1 -i 1 -g -o -t -N zonetab zonetab.list */ /* Computed positions: -k'1-4,9' */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -29,15 +29,17 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>." #endif -#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n) #line 1 "zonetab.list" +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRNCMP 1 +#define gperf_case_strncmp strncasecmp struct zone { int name; int offset; }; -static const struct zone *zonetab(); -#line 9 "zonetab.list" +static const struct zone *zonetab(register const char *str, register size_t len); +#line 12 "zonetab.list" struct zone; #define TOTAL_KEYWORDS 316 @@ -808,736 +810,736 @@ zonetab (register const char *str, register size_t len) static const struct zone wordlist[] = { {-1}, {-1}, -#line 34 "zonetab.list" - {gperf_offsetof(stringpool, 2), -2*3600}, -#line 43 "zonetab.list" - {gperf_offsetof(stringpool, 3), -11*3600}, -#line 45 "zonetab.list" - {gperf_offsetof(stringpool, 4), 0*3600}, -#line 36 "zonetab.list" - {gperf_offsetof(stringpool, 5), -4*3600}, - {-1}, {-1}, -#line 269 "zonetab.list" - {gperf_offsetof(stringpool, 8),21600}, -#line 268 "zonetab.list" - {gperf_offsetof(stringpool, 9),25200}, -#line 35 "zonetab.list" - {gperf_offsetof(stringpool, 10), -3*3600}, +#line 37 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str2, -2*3600}, +#line 46 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str3, -11*3600}, +#line 48 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str4, 0*3600}, +#line 39 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str5, -4*3600}, {-1}, {-1}, -#line 21 "zonetab.list" - {gperf_offsetof(stringpool, 13), 1*3600}, -#line 25 "zonetab.list" - {gperf_offsetof(stringpool, 14), 5*3600}, -#line 271 "zonetab.list" - {gperf_offsetof(stringpool, 15),-18000}, -#line 279 "zonetab.list" - {gperf_offsetof(stringpool, 16),-10800}, -#line 273 "zonetab.list" - {gperf_offsetof(stringpool, 17),43200}, #line 272 "zonetab.list" - {gperf_offsetof(stringpool, 18),43200}, -#line 80 "zonetab.list" - {gperf_offsetof(stringpool, 19), 2*3600}, -#line 186 "zonetab.list" - {gperf_offsetof(stringpool, 20),36000}, -#line 88 "zonetab.list" - {gperf_offsetof(stringpool, 21), 3*3600}, -#line 87 "zonetab.list" - {gperf_offsetof(stringpool, 22), 3*3600}, - {-1}, -#line 101 "zonetab.list" - {gperf_offsetof(stringpool, 24),-6*3600}, -#line 217 "zonetab.list" - {gperf_offsetof(stringpool, 25),-18000}, -#line 19 "zonetab.list" - {gperf_offsetof(stringpool, 26), -8*3600}, -#line 133 "zonetab.list" - {gperf_offsetof(stringpool, 27), -18000}, -#line 32 "zonetab.list" - {gperf_offsetof(stringpool, 28), 12*3600}, -#line 56 "zonetab.list" - {gperf_offsetof(stringpool, 29), -4*3600}, -#line 13 "zonetab.list" - {gperf_offsetof(stringpool, 30), -5*3600}, -#line 23 "zonetab.list" - {gperf_offsetof(stringpool, 31), 3*3600}, -#line 256 "zonetab.list" - {gperf_offsetof(stringpool, 32),23400}, -#line 73 "zonetab.list" - {gperf_offsetof(stringpool, 33), 1*3600}, - {-1}, -#line 82 "zonetab.list" - {gperf_offsetof(stringpool, 35), 2*3600}, -#line 71 "zonetab.list" - {gperf_offsetof(stringpool, 36), 1*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str8,21600}, +#line 271 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str9,25200}, +#line 38 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str10, -3*3600}, + {-1}, {-1}, #line 24 "zonetab.list" - {gperf_offsetof(stringpool, 37), 4*3600}, -#line 79 "zonetab.list" - {gperf_offsetof(stringpool, 38), 2*3600}, -#line 65 "zonetab.list" - {gperf_offsetof(stringpool, 39),2*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, 1*3600}, +#line 28 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, 5*3600}, +#line 274 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15,-18000}, +#line 282 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16,-10800}, +#line 276 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17,43200}, +#line 275 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18,43200}, +#line 83 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, 2*3600}, +#line 189 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20,36000}, +#line 91 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, 3*3600}, +#line 90 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, 3*3600}, {-1}, -#line 202 "zonetab.list" - {gperf_offsetof(stringpool, 41),28800}, -#line 252 "zonetab.list" - {gperf_offsetof(stringpool, 42),39600}, -#line 251 "zonetab.list" - {gperf_offsetof(stringpool, 43),43200}, -#line 17 "zonetab.list" - {gperf_offsetof(stringpool, 44), -7*3600}, -#line 89 "zonetab.list" - {gperf_offsetof(stringpool, 45), 3*3600}, -#line 212 "zonetab.list" - {gperf_offsetof(stringpool, 46),-18000}, -#line 15 "zonetab.list" - {gperf_offsetof(stringpool, 47), -6*3600}, -#line 192 "zonetab.list" - {gperf_offsetof(stringpool, 48),18000}, -#line 26 "zonetab.list" - {gperf_offsetof(stringpool, 49), 6*3600}, - {-1}, {-1}, -#line 51 "zonetab.list" - {gperf_offsetof(stringpool, 52), -3*3600}, -#line 226 "zonetab.list" - {gperf_offsetof(stringpool, 53),-7200}, -#line 221 "zonetab.list" - {gperf_offsetof(stringpool, 54),10800}, +#line 104 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24,-6*3600}, +#line 220 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25,-18000}, #line 22 "zonetab.list" - {gperf_offsetof(stringpool, 55), 2*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, -8*3600}, +#line 136 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str27, -18000}, +#line 35 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, 12*3600}, +#line 59 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, -4*3600}, +#line 16 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, -5*3600}, +#line 26 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, 3*3600}, +#line 259 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32,23400}, +#line 76 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, 1*3600}, {-1}, -#line 190 "zonetab.list" - {gperf_offsetof(stringpool, 57),43200}, -#line 189 "zonetab.list" - {gperf_offsetof(stringpool, 58),43200}, -#line 199 "zonetab.list" - {gperf_offsetof(stringpool, 59),28800}, -#line 29 "zonetab.list" - {gperf_offsetof(stringpool, 60), 9*3600}, -#line 276 "zonetab.list" - {gperf_offsetof(stringpool, 61),28800}, -#line 48 "zonetab.list" - {gperf_offsetof(stringpool, 62), -2*3600}, -#line 94 "zonetab.list" - {gperf_offsetof(stringpool, 63), 6*3600}, +#line 85 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, 2*3600}, #line 74 "zonetab.list" - {gperf_offsetof(stringpool, 64), 1*3600}, -#line 81 "zonetab.list" - {gperf_offsetof(stringpool, 65), 2*3600}, -#line 64 "zonetab.list" - {gperf_offsetof(stringpool, 66),-10*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, 1*3600}, +#line 27 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, 4*3600}, +#line 82 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, 2*3600}, +#line 68 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39,2*3600}, + {-1}, +#line 205 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41,28800}, +#line 255 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42,39600}, #line 254 "zonetab.list" - {gperf_offsetof(stringpool, 67),18000}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43,43200}, +#line 20 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, -7*3600}, #line 92 "zonetab.list" - {gperf_offsetof(stringpool, 68), 5*3600}, - {-1}, -#line 200 "zonetab.list" - {gperf_offsetof(stringpool, 70),-14400}, -#line 70 "zonetab.list" - {gperf_offsetof(stringpool, 71), 1*3600}, -#line 281 "zonetab.list" - {gperf_offsetof(stringpool, 72),32400}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, 3*3600}, +#line 215 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46,-18000}, +#line 18 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, -6*3600}, +#line 195 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48,18000}, +#line 29 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, 6*3600}, + {-1}, {-1}, +#line 54 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, -3*3600}, +#line 229 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53,-7200}, +#line 224 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54,10800}, +#line 25 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str55, 2*3600}, {-1}, -#line 280 "zonetab.list" - {gperf_offsetof(stringpool, 74),39600}, -#line 238 "zonetab.list" - {gperf_offsetof(stringpool, 75),21600}, -#line 93 "zonetab.list" - {gperf_offsetof(stringpool, 76), (5*3600+1800)}, -#line 194 "zonetab.list" - {gperf_offsetof(stringpool, 77),28800}, +#line 193 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57,43200}, +#line 192 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str58,43200}, +#line 202 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str59,28800}, +#line 32 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60, 9*3600}, +#line 279 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61,28800}, +#line 51 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62, -2*3600}, +#line 97 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63, 6*3600}, +#line 77 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, 1*3600}, +#line 84 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65, 2*3600}, +#line 67 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66,-10*3600}, +#line 257 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67,18000}, +#line 95 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str68, 5*3600}, {-1}, -#line 255 "zonetab.list" - {gperf_offsetof(stringpool, 79),43200}, -#line 75 "zonetab.list" - {gperf_offsetof(stringpool, 80), 1*3600}, -#line 270 "zonetab.list" - {gperf_offsetof(stringpool, 81),18000}, -#line 83 "zonetab.list" - {gperf_offsetof(stringpool, 82), 2*3600}, +#line 203 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str70,-14400}, +#line 73 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71, 1*3600}, +#line 284 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72,32400}, {-1}, -#line 207 "zonetab.list" - {gperf_offsetof(stringpool, 84),36000}, -#line 278 "zonetab.list" - {gperf_offsetof(stringpool, 85),-7200}, - {-1}, {-1}, -#line 126 "zonetab.list" - {gperf_offsetof(stringpool, 88), -21600}, -#line 185 "zonetab.list" - {gperf_offsetof(stringpool, 89),39600}, -#line 183 "zonetab.list" - {gperf_offsetof(stringpool, 90),-18000}, -#line 218 "zonetab.list" - {gperf_offsetof(stringpool, 91),-18000}, -#line 182 "zonetab.list" - {gperf_offsetof(stringpool, 92),34200}, -#line 103 "zonetab.list" - {gperf_offsetof(stringpool, 93),11*3600}, -#line 53 "zonetab.list" - {gperf_offsetof(stringpool, 94), -3*3600}, -#line 208 "zonetab.list" - {gperf_offsetof(stringpool, 95),36000}, -#line 49 "zonetab.list" - {gperf_offsetof(stringpool, 96),-2*3600}, -#line 120 "zonetab.list" - {gperf_offsetof(stringpool, 97), 34200}, - {-1}, {-1}, -#line 215 "zonetab.list" - {gperf_offsetof(stringpool, 100),25200}, -#line 242 "zonetab.list" - {gperf_offsetof(stringpool, 101),12600}, +#line 283 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74,39600}, #line 241 "zonetab.list" - {gperf_offsetof(stringpool, 102),28800}, -#line 240 "zonetab.list" - {gperf_offsetof(stringpool, 103),32400}, -#line 86 "zonetab.list" - {gperf_offsetof(stringpool, 104), 3*3600}, -#line 33 "zonetab.list" - {gperf_offsetof(stringpool, 105), -1*3600}, -#line 201 "zonetab.list" - {gperf_offsetof(stringpool, 106),21600}, -#line 148 "zonetab.list" - {gperf_offsetof(stringpool, 107), -25200}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75,21600}, #line 96 "zonetab.list" - {gperf_offsetof(stringpool, 108), (6*3600+1800)}, -#line 42 "zonetab.list" - {gperf_offsetof(stringpool, 109), -10*3600}, -#line 31 "zonetab.list" - {gperf_offsetof(stringpool, 110), 11*3600}, -#line 72 "zonetab.list" - {gperf_offsetof(stringpool, 111), 1*3600}, - {-1}, -#line 90 "zonetab.list" - {gperf_offsetof(stringpool, 113), 4*3600}, -#line 47 "zonetab.list" - {gperf_offsetof(stringpool, 114), 0*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76, (5*3600+1800)}, +#line 197 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77,28800}, {-1}, +#line 258 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79,43200}, #line 78 "zonetab.list" - {gperf_offsetof(stringpool, 116), 1*3600}, -#line 77 "zonetab.list" - {gperf_offsetof(stringpool, 117), 1*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80, 1*3600}, +#line 273 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81,18000}, +#line 86 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82, 2*3600}, {-1}, -#line 95 "zonetab.list" - {gperf_offsetof(stringpool, 119), 2*3600}, -#line 313 "zonetab.list" - {gperf_offsetof(stringpool, 120),43200}, -#line 55 "zonetab.list" - {gperf_offsetof(stringpool, 121), -(2*3600+1800)}, -#line 184 "zonetab.list" - {gperf_offsetof(stringpool, 122),31500}, -#line 204 "zonetab.list" - {gperf_offsetof(stringpool, 123),45900}, #line 210 "zonetab.list" - {gperf_offsetof(stringpool, 124),-18000}, -#line 198 "zonetab.list" - {gperf_offsetof(stringpool, 125),14400}, -#line 57 "zonetab.list" - {gperf_offsetof(stringpool, 126), -4*3600}, -#line 197 "zonetab.list" - {gperf_offsetof(stringpool, 127),18000}, -#line 54 "zonetab.list" - {gperf_offsetof(stringpool, 128),-3*3600}, -#line 253 "zonetab.list" - {gperf_offsetof(stringpool, 129),-30600}, -#line 91 "zonetab.list" - {gperf_offsetof(stringpool, 130), 4*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84,36000}, +#line 281 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85,-7200}, + {-1}, {-1}, +#line 129 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88, -21600}, +#line 188 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89,39600}, +#line 186 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90,-18000}, +#line 221 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91,-18000}, +#line 185 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92,34200}, +#line 106 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93,11*3600}, +#line 56 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94, -3*3600}, +#line 211 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95,36000}, +#line 52 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96,-2*3600}, +#line 123 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97, 34200}, + {-1}, {-1}, +#line 218 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str100,25200}, +#line 245 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101,12600}, +#line 244 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102,28800}, +#line 243 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103,32400}, +#line 89 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104, 3*3600}, +#line 36 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105, -1*3600}, +#line 204 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106,21600}, +#line 151 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107, -25200}, #line 99 "zonetab.list" - {gperf_offsetof(stringpool, 131), 9*3600}, -#line 122 "zonetab.list" - {gperf_offsetof(stringpool, 132), 21600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108, (6*3600+1800)}, +#line 45 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109, -10*3600}, +#line 34 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str110, 11*3600}, +#line 75 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111, 1*3600}, + {-1}, +#line 93 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str113, 4*3600}, +#line 50 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114, 0*3600}, + {-1}, +#line 81 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str116, 1*3600}, +#line 80 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117, 1*3600}, + {-1}, +#line 98 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str119, 2*3600}, +#line 316 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str120,43200}, +#line 58 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121, -(2*3600+1800)}, #line 187 "zonetab.list" - {gperf_offsetof(stringpool, 133),16200}, -#line 132 "zonetab.list" - {gperf_offsetof(stringpool, 134), -10800}, -#line 121 "zonetab.list" - {gperf_offsetof(stringpool, 135), -21600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122,31500}, +#line 207 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str123,45900}, +#line 213 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124,-18000}, +#line 201 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str125,14400}, +#line 60 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126, -4*3600}, +#line 200 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127,18000}, +#line 57 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128,-3*3600}, +#line 256 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129,-30600}, +#line 94 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130, 4*3600}, +#line 102 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131, 9*3600}, +#line 125 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132, 21600}, +#line 190 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133,16200}, +#line 135 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134, -10800}, +#line 124 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135, -21600}, {-1}, -#line 236 "zonetab.list" - {gperf_offsetof(stringpool, 137),25200}, +#line 239 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137,25200}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 274 "zonetab.list" - {gperf_offsetof(stringpool, 143),36000}, -#line 266 "zonetab.list" - {gperf_offsetof(stringpool, 144),43200}, -#line 146 "zonetab.list" - {gperf_offsetof(stringpool, 145), -21600}, -#line 193 "zonetab.list" - {gperf_offsetof(stringpool, 146),32400}, -#line 220 "zonetab.list" - {gperf_offsetof(stringpool, 147),-3600}, -#line 214 "zonetab.list" - {gperf_offsetof(stringpool, 148),25200}, -#line 219 "zonetab.list" - {gperf_offsetof(stringpool, 149),0}, -#line 275 "zonetab.list" - {gperf_offsetof(stringpool, 150),46800}, -#line 109 "zonetab.list" - {gperf_offsetof(stringpool, 151), -32400}, +#line 277 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143,36000}, +#line 269 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144,43200}, +#line 149 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145, -21600}, +#line 196 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str146,32400}, +#line 223 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147,-3600}, +#line 217 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str148,25200}, +#line 222 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149,0}, +#line 278 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str150,46800}, +#line 112 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151, -32400}, {-1}, {-1}, -#line 68 "zonetab.list" - {gperf_offsetof(stringpool, 154), -11*3600}, +#line 71 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154, -11*3600}, {-1}, {-1}, {-1}, -#line 321 "zonetab.list" - {gperf_offsetof(stringpool, 158),0}, +#line 324 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str158,0}, {-1}, -#line 178 "zonetab.list" - {gperf_offsetof(stringpool, 160), 18000}, #line 181 "zonetab.list" - {gperf_offsetof(stringpool, 161),37800}, -#line 265 "zonetab.list" - {gperf_offsetof(stringpool, 162),20700}, -#line 249 "zonetab.list" - {gperf_offsetof(stringpool, 163),37800}, -#line 108 "zonetab.list" - {gperf_offsetof(stringpool, 164), 16200}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str160, 18000}, +#line 184 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str161,37800}, +#line 268 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162,20700}, +#line 252 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str163,37800}, +#line 111 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164, 16200}, {-1}, {-1}, +#line 33 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167, 10*3600}, + {-1}, #line 30 "zonetab.list" - {gperf_offsetof(stringpool, 167), 10*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str169, 7*3600}, +#line 242 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170,16200}, +#line 209 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171,28800}, +#line 208 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str172,32400}, +#line 15 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str173, 0*3600}, +#line 232 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174,14400}, +#line 267 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str175,25200}, +#line 266 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176,25200}, +#line 226 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177,43200}, +#line 43 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str178, -8*3600}, +#line 225 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179,46800}, {-1}, -#line 27 "zonetab.list" - {gperf_offsetof(stringpool, 169), 7*3600}, -#line 239 "zonetab.list" - {gperf_offsetof(stringpool, 170),16200}, -#line 206 "zonetab.list" - {gperf_offsetof(stringpool, 171),28800}, -#line 205 "zonetab.list" - {gperf_offsetof(stringpool, 172),32400}, -#line 12 "zonetab.list" - {gperf_offsetof(stringpool, 173), 0*3600}, -#line 229 "zonetab.list" - {gperf_offsetof(stringpool, 174),14400}, -#line 264 "zonetab.list" - {gperf_offsetof(stringpool, 175),25200}, +#line 285 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str181,-10800}, #line 263 "zonetab.list" - {gperf_offsetof(stringpool, 176),25200}, -#line 223 "zonetab.list" - {gperf_offsetof(stringpool, 177),43200}, -#line 40 "zonetab.list" - {gperf_offsetof(stringpool, 178), -8*3600}, -#line 222 "zonetab.list" - {gperf_offsetof(stringpool, 179),46800}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182,39600}, +#line 103 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str183, 9*3600}, +#line 247 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str184,39600}, +#line 105 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185, 10*3600}, +#line 146 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str186, 12600}, +#line 132 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str187, 10800}, +#line 101 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188, 8*3600}, +#line 42 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189, -7*3600}, +#line 133 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str190, 36000}, +#line 41 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191, -6*3600}, +#line 206 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str192,49500}, +#line 301 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str193,18000}, +#line 212 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str194,-14400}, +#line 194 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str195,-43200}, {-1}, -#line 282 "zonetab.list" - {gperf_offsetof(stringpool, 181),-10800}, +#line 262 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197,28800}, +#line 182 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198, 36000}, #line 260 "zonetab.list" - {gperf_offsetof(stringpool, 182),39600}, -#line 100 "zonetab.list" - {gperf_offsetof(stringpool, 183), 9*3600}, -#line 244 "zonetab.list" - {gperf_offsetof(stringpool, 184),39600}, -#line 102 "zonetab.list" - {gperf_offsetof(stringpool, 185), 10*3600}, -#line 143 "zonetab.list" - {gperf_offsetof(stringpool, 186), 12600}, -#line 129 "zonetab.list" - {gperf_offsetof(stringpool, 187), 10800}, -#line 98 "zonetab.list" - {gperf_offsetof(stringpool, 188), 8*3600}, -#line 39 "zonetab.list" - {gperf_offsetof(stringpool, 189), -7*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199,14400}, +#line 322 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str200,32400}, +#line 87 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str201, 2*3600}, +#line 289 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str202,39600}, +#line 155 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203, 43200}, +#line 303 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str204,46800}, #line 130 "zonetab.list" - {gperf_offsetof(stringpool, 190), 36000}, -#line 38 "zonetab.list" - {gperf_offsetof(stringpool, 191), -6*3600}, -#line 203 "zonetab.list" - {gperf_offsetof(stringpool, 192),49500}, -#line 298 "zonetab.list" - {gperf_offsetof(stringpool, 193),18000}, -#line 209 "zonetab.list" - {gperf_offsetof(stringpool, 194),-14400}, -#line 191 "zonetab.list" - {gperf_offsetof(stringpool, 195),-43200}, - {-1}, -#line 259 "zonetab.list" - {gperf_offsetof(stringpool, 197),28800}, -#line 179 "zonetab.list" - {gperf_offsetof(stringpool, 198), 36000}, -#line 257 "zonetab.list" - {gperf_offsetof(stringpool, 199),14400}, -#line 319 "zonetab.list" - {gperf_offsetof(stringpool, 200),32400}, -#line 84 "zonetab.list" - {gperf_offsetof(stringpool, 201), 2*3600}, -#line 286 "zonetab.list" - {gperf_offsetof(stringpool, 202),39600}, -#line 152 "zonetab.list" - {gperf_offsetof(stringpool, 203), 43200}, -#line 300 "zonetab.list" - {gperf_offsetof(stringpool, 204),46800}, -#line 127 "zonetab.list" - {gperf_offsetof(stringpool, 205), 28800}, -#line 299 "zonetab.list" - {gperf_offsetof(stringpool, 206),50400}, -#line 85 "zonetab.list" - {gperf_offsetof(stringpool, 207), -11*3600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205, 28800}, +#line 302 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206,50400}, +#line 88 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str207, -11*3600}, {-1}, -#line 142 "zonetab.list" - {gperf_offsetof(stringpool, 209), 19800}, +#line 145 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209, 19800}, {-1}, -#line 314 "zonetab.list" - {gperf_offsetof(stringpool, 211),-10800}, -#line 288 "zonetab.list" - {gperf_offsetof(stringpool, 212),39600}, +#line 317 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str211,-10800}, +#line 291 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str212,39600}, {-1}, -#line 196 "zonetab.list" - {gperf_offsetof(stringpool, 214),-3600}, -#line 195 "zonetab.list" - {gperf_offsetof(stringpool, 215),0}, -#line 293 "zonetab.list" - {gperf_offsetof(stringpool, 216),-36000}, -#line 106 "zonetab.list" - {gperf_offsetof(stringpool, 217), 12*3600}, +#line 199 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str214,-3600}, +#line 198 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215,0}, +#line 296 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str216,-36000}, +#line 109 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217, 12*3600}, +#line 131 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218, -43200}, +#line 108 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str219,12*3600}, +#line 173 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220, 32400}, #line 128 "zonetab.list" - {gperf_offsetof(stringpool, 218), -43200}, -#line 105 "zonetab.list" - {gperf_offsetof(stringpool, 219),12*3600}, -#line 170 "zonetab.list" - {gperf_offsetof(stringpool, 220), 32400}, -#line 125 "zonetab.list" - {gperf_offsetof(stringpool, 221), 39600}, - {-1}, -#line 283 "zonetab.list" - {gperf_offsetof(stringpool, 223),21600}, -#line 113 "zonetab.list" - {gperf_offsetof(stringpool, 224), -14400}, -#line 262 "zonetab.list" - {gperf_offsetof(stringpool, 225),39600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221, 39600}, {-1}, -#line 11 "zonetab.list" - {gperf_offsetof(stringpool, 227), 0*3600}, -#line 301 "zonetab.list" - {gperf_offsetof(stringpool, 228),10800}, -#line 315 "zonetab.list" - {gperf_offsetof(stringpool, 229),43200}, -#line 291 "zonetab.list" - {gperf_offsetof(stringpool, 230),-10800}, -#line 20 "zonetab.list" - {gperf_offsetof(stringpool, 231), -7*3600}, -#line 248 "zonetab.list" - {gperf_offsetof(stringpool, 232),39600}, +#line 286 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str223,21600}, +#line 116 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224, -14400}, +#line 265 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str225,39600}, {-1}, -#line 52 "zonetab.list" - {gperf_offsetof(stringpool, 234), -3*3600}, #line 14 "zonetab.list" - {gperf_offsetof(stringpool, 235), -4*3600}, - {-1}, {-1}, -#line 277 "zonetab.list" - {gperf_offsetof(stringpool, 238),18000}, -#line 188 "zonetab.list" - {gperf_offsetof(stringpool, 239),21600}, -#line 320 "zonetab.list" - {gperf_offsetof(stringpool, 240),28800}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str227, 0*3600}, +#line 304 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str228,10800}, +#line 318 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229,43200}, +#line 294 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str230,-10800}, +#line 23 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str231, -7*3600}, +#line 251 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232,39600}, {-1}, -#line 317 "zonetab.list" - {gperf_offsetof(stringpool, 242),-10800}, -#line 60 "zonetab.list" - {gperf_offsetof(stringpool, 243),-9*3600}, -#line 316 "zonetab.list" - {gperf_offsetof(stringpool, 244),-7200}, +#line 55 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str234, -3*3600}, +#line 17 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235, -4*3600}, + {-1}, {-1}, +#line 280 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str238,18000}, +#line 191 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str239,21600}, +#line 323 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str240,28800}, {-1}, -#line 246 "zonetab.list" - {gperf_offsetof(stringpool, 246),25200}, -#line 245 "zonetab.list" - {gperf_offsetof(stringpool, 247),28800}, -#line 147 "zonetab.list" - {gperf_offsetof(stringpool, 248), -7200}, -#line 18 "zonetab.list" - {gperf_offsetof(stringpool, 249), -6*3600}, -#line 250 "zonetab.list" - {gperf_offsetof(stringpool, 250),50400}, -#line 165 "zonetab.list" - {gperf_offsetof(stringpool, 251), 28800}, -#line 16 "zonetab.list" - {gperf_offsetof(stringpool, 252), -5*3600}, -#line 76 "zonetab.list" - {gperf_offsetof(stringpool, 253), 1*3600}, +#line 320 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242,-7200}, +#line 63 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str243,-9*3600}, +#line 319 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str244,-3600}, {-1}, -#line 164 "zonetab.list" - {gperf_offsetof(stringpool, 255), 25200}, -#line 41 "zonetab.list" - {gperf_offsetof(stringpool, 256), -9*3600}, +#line 249 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str246,25200}, +#line 248 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str247,28800}, +#line 150 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str248, -7200}, +#line 21 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str249, -6*3600}, +#line 253 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str250,50400}, +#line 168 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str251, 28800}, +#line 19 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str252, -5*3600}, +#line 79 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str253, 1*3600}, {-1}, -#line 171 "zonetab.list" - {gperf_offsetof(stringpool, 258), 46800}, -#line 211 "zonetab.list" - {gperf_offsetof(stringpool, 259),-36000}, +#line 167 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str255, 25200}, +#line 44 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256, -9*3600}, {-1}, -#line 308 "zonetab.list" - {gperf_offsetof(stringpool, 261),-14400}, -#line 119 "zonetab.list" - {gperf_offsetof(stringpool, 262), 14400}, -#line 123 "zonetab.list" - {gperf_offsetof(stringpool, 263), 3600}, -#line 28 "zonetab.list" - {gperf_offsetof(stringpool, 264), 8*3600}, -#line 124 "zonetab.list" - {gperf_offsetof(stringpool, 265), 3600}, -#line 153 "zonetab.list" - {gperf_offsetof(stringpool, 266), -12600}, -#line 110 "zonetab.list" - {gperf_offsetof(stringpool, 267), 10800}, -#line 289 "zonetab.list" - {gperf_offsetof(stringpool, 268),14400}, -#line 112 "zonetab.list" - {gperf_offsetof(stringpool, 269), 10800}, -#line 111 "zonetab.list" - {gperf_offsetof(stringpool, 270), 14400}, -#line 216 "zonetab.list" - {gperf_offsetof(stringpool, 271),36000}, +#line 174 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str258, 46800}, +#line 214 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str259,-36000}, {-1}, #line 311 "zonetab.list" - {gperf_offsetof(stringpool, 273),21600}, -#line 66 "zonetab.list" - {gperf_offsetof(stringpool, 274),-10*3600}, -#line 151 "zonetab.list" - {gperf_offsetof(stringpool, 275), 20700}, -#line 267 "zonetab.list" - {gperf_offsetof(stringpool, 276),-39600}, -#line 225 "zonetab.list" - {gperf_offsetof(stringpool, 277),-14400}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str261,-14400}, +#line 122 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str262, 14400}, +#line 126 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str263, 3600}, +#line 31 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str264, 8*3600}, +#line 127 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str265, 3600}, +#line 156 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str266, -12600}, +#line 113 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str267, 10800}, +#line 292 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str268,14400}, +#line 115 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str269, 10800}, +#line 114 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str270, 14400}, +#line 219 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str271,36000}, {-1}, -#line 224 "zonetab.list" - {gperf_offsetof(stringpool, 279),-10800}, -#line 67 "zonetab.list" - {gperf_offsetof(stringpool, 280),-10*3600}, -#line 237 "zonetab.list" - {gperf_offsetof(stringpool, 281),10800}, +#line 314 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str273,21600}, +#line 69 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str274,-10*3600}, +#line 154 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str275, 20700}, +#line 270 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str276,-39600}, +#line 228 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str277,-14400}, + {-1}, +#line 227 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str279,-10800}, +#line 70 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str280,-10*3600}, +#line 240 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str281,10800}, {-1}, {-1}, -#line 297 "zonetab.list" - {gperf_offsetof(stringpool, 284),32400}, -#line 175 "zonetab.list" - {gperf_offsetof(stringpool, 285), 28800}, -#line 134 "zonetab.list" - {gperf_offsetof(stringpool, 286), 7200}, -#line 149 "zonetab.list" - {gperf_offsetof(stringpool, 287), 23400}, -#line 107 "zonetab.list" - {gperf_offsetof(stringpool, 288),13*3600}, -#line 230 "zonetab.list" - {gperf_offsetof(stringpool, 289),-10800}, -#line 307 "zonetab.list" - {gperf_offsetof(stringpool, 290),18000}, +#line 300 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str284,32400}, +#line 178 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str285, 28800}, +#line 137 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str286, 7200}, +#line 152 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str287, 23400}, +#line 110 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str288,13*3600}, +#line 233 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str289,-10800}, +#line 310 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str290,18000}, {-1}, {-1}, -#line 155 "zonetab.list" - {gperf_offsetof(stringpool, 293), 25200}, -#line 258 "zonetab.list" - {gperf_offsetof(stringpool, 294),18000}, -#line 227 "zonetab.list" - {gperf_offsetof(stringpool, 295),-21600}, +#line 158 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str293, 25200}, #line 261 "zonetab.list" - {gperf_offsetof(stringpool, 296),43200}, -#line 213 "zonetab.list" - {gperf_offsetof(stringpool, 297),-3600}, -#line 154 "zonetab.list" - {gperf_offsetof(stringpool, 298), 28800}, - {-1}, -#line 243 "zonetab.list" - {gperf_offsetof(stringpool, 300),21600}, -#line 114 "zonetab.list" - {gperf_offsetof(stringpool, 301), 34200}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str294,18000}, +#line 230 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str295,-21600}, +#line 264 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str296,43200}, +#line 216 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str297,-3600}, #line 157 "zonetab.list" - {gperf_offsetof(stringpool, 302), -28800}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str298, 28800}, {-1}, +#line 246 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str300,21600}, #line 117 "zonetab.list" - {gperf_offsetof(stringpool, 304), -21600}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str301, 34200}, +#line 160 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str302, -28800}, {-1}, -#line 156 "zonetab.list" - {gperf_offsetof(stringpool, 306), -14400}, -#line 116 "zonetab.list" - {gperf_offsetof(stringpool, 307), -3600}, -#line 228 "zonetab.list" - {gperf_offsetof(stringpool, 308),-32400}, -#line 294 "zonetab.list" - {gperf_offsetof(stringpool, 309),18000}, -#line 37 "zonetab.list" - {gperf_offsetof(stringpool, 310), -5*3600}, -#line 137 "zonetab.list" - {gperf_offsetof(stringpool, 311), 7200}, -#line 58 "zonetab.list" - {gperf_offsetof(stringpool, 312),-8*3600}, -#line 304 "zonetab.list" - {gperf_offsetof(stringpool, 313),28800}, -#line 303 "zonetab.list" - {gperf_offsetof(stringpool, 314),32400}, -#line 284 "zonetab.list" - {gperf_offsetof(stringpool, 315),14400}, +#line 120 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str304, -21600}, {-1}, -#line 295 "zonetab.list" - {gperf_offsetof(stringpool, 317),18000}, +#line 159 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str306, -14400}, +#line 119 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str307, -3600}, +#line 231 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str308,-32400}, +#line 297 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str309,18000}, +#line 40 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str310, -5*3600}, +#line 140 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str311, 7200}, +#line 61 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str312,-8*3600}, +#line 307 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str313,28800}, +#line 306 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str314,32400}, +#line 287 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str315,14400}, {-1}, -#line 166 "zonetab.list" - {gperf_offsetof(stringpool, 319), 7200}, +#line 298 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str317,18000}, + {-1}, +#line 169 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str319, 7200}, {-1}, {-1}, {-1}, {-1}, -#line 97 "zonetab.list" - {gperf_offsetof(stringpool, 324), 8*3600}, +#line 100 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str324, 8*3600}, {-1}, -#line 50 "zonetab.list" - {gperf_offsetof(stringpool, 326), -(1*3600+1800)}, -#line 285 "zonetab.list" - {gperf_offsetof(stringpool, 327),-10800}, +#line 53 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str326, -(1*3600+1800)}, +#line 288 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str327,-10800}, {-1}, {-1}, -#line 287 "zonetab.list" - {gperf_offsetof(stringpool, 330),14400}, +#line 290 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str330,14400}, {-1}, -#line 169 "zonetab.list" - {gperf_offsetof(stringpool, 332), 36000}, +#line 172 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str332, 36000}, {-1}, -#line 235 "zonetab.list" - {gperf_offsetof(stringpool, 334),25200}, -#line 234 "zonetab.list" - {gperf_offsetof(stringpool, 335),28800}, +#line 238 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str334,25200}, +#line 237 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str335,28800}, {-1}, {-1}, -#line 232 "zonetab.list" - {gperf_offsetof(stringpool, 338),-14400}, +#line 235 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str338,-14400}, {-1}, {-1}, {-1}, -#line 44 "zonetab.list" - {gperf_offsetof(stringpool, 342), -12*3600}, -#line 61 "zonetab.list" - {gperf_offsetof(stringpool, 343),-9*3600}, -#line 162 "zonetab.list" - {gperf_offsetof(stringpool, 344), -14400}, -#line 141 "zonetab.list" - {gperf_offsetof(stringpool, 345), -36000}, +#line 47 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str342, -12*3600}, +#line 64 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str343,-9*3600}, +#line 165 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str344, -14400}, +#line 144 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str345, -36000}, {-1}, -#line 306 "zonetab.list" - {gperf_offsetof(stringpool, 347),-10800}, +#line 309 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str347,-10800}, {-1}, -#line 305 "zonetab.list" - {gperf_offsetof(stringpool, 349),-7200}, +#line 308 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str349,-7200}, +#line 329 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str350,18000}, +#line 328 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str351,21600}, +#line 250 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str352,14400}, #line 326 "zonetab.list" - {gperf_offsetof(stringpool, 350),18000}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str353,32400}, #line 325 "zonetab.list" - {gperf_offsetof(stringpool, 351),21600}, -#line 247 "zonetab.list" - {gperf_offsetof(stringpool, 352),14400}, -#line 323 "zonetab.list" - {gperf_offsetof(stringpool, 353),32400}, -#line 322 "zonetab.list" - {gperf_offsetof(stringpool, 354),36000}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str354,36000}, {-1}, {-1}, {-1}, -#line 63 "zonetab.list" - {gperf_offsetof(stringpool, 358), -9*3600}, -#line 144 "zonetab.list" - {gperf_offsetof(stringpool, 359), 7200}, +#line 66 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str358, -9*3600}, +#line 147 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str359, 7200}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 167 "zonetab.list" - {gperf_offsetof(stringpool, 365), 21600}, +#line 170 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str365, 21600}, {-1}, -#line 180 "zonetab.list" - {gperf_offsetof(stringpool, 367), 32400}, +#line 183 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str367, 32400}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 318 "zonetab.list" - {gperf_offsetof(stringpool, 375),25200}, +#line 321 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str375,25200}, {-1}, -#line 115 "zonetab.list" - {gperf_offsetof(stringpool, 377), 36000}, -#line 231 "zonetab.list" - {gperf_offsetof(stringpool, 378),43200}, +#line 118 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str377, 36000}, +#line 234 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str378,43200}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 173 "zonetab.list" - {gperf_offsetof(stringpool, 387), -25200}, +#line 176 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str387, -25200}, {-1}, {-1}, {-1}, -#line 310 "zonetab.list" - {gperf_offsetof(stringpool, 391),36000}, -#line 309 "zonetab.list" - {gperf_offsetof(stringpool, 392),39600}, +#line 313 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str391,36000}, +#line 312 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str392,39600}, {-1}, {-1}, -#line 140 "zonetab.list" - {gperf_offsetof(stringpool, 395), 7200}, +#line 143 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str395, 7200}, {-1}, {-1}, -#line 168 "zonetab.list" - {gperf_offsetof(stringpool, 398), 28800}, -#line 290 "zonetab.list" - {gperf_offsetof(stringpool, 399),39600}, +#line 171 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str398, 28800}, +#line 293 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str399,39600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 118 "zonetab.list" - {gperf_offsetof(stringpool, 408), -3600}, +#line 121 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str408, -3600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 296 "zonetab.list" - {gperf_offsetof(stringpool, 417),46800}, -#line 163 "zonetab.list" - {gperf_offsetof(stringpool, 418), -39600}, +#line 299 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str417,46800}, +#line 166 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str418, -39600}, {-1}, {-1}, -#line 161 "zonetab.list" - {gperf_offsetof(stringpool, 421), -18000}, +#line 164 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str421, -18000}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 312 "zonetab.list" - {gperf_offsetof(stringpool, 427),39600}, -#line 69 "zonetab.list" - {gperf_offsetof(stringpool, 428),-12*3600}, +#line 315 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str427,39600}, +#line 72 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str428,-12*3600}, {-1}, {-1}, {-1}, -#line 136 "zonetab.list" - {gperf_offsetof(stringpool, 432), 43200}, +#line 139 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str432, 43200}, {-1}, {-1}, -#line 46 "zonetab.list" - {gperf_offsetof(stringpool, 435), 0*3600}, +#line 49 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str435, 0*3600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 145 "zonetab.list" - {gperf_offsetof(stringpool, 443), 32400}, +#line 148 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str443, 32400}, {-1}, -#line 131 "zonetab.list" - {gperf_offsetof(stringpool, 445), 7200}, +#line 134 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str445, 7200}, {-1}, {-1}, {-1}, -#line 292 "zonetab.list" - {gperf_offsetof(stringpool, 449),10800}, +#line 295 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str449,10800}, {-1}, {-1}, -#line 150 "zonetab.list" - {gperf_offsetof(stringpool, 452), 21600}, +#line 153 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str452, 21600}, {-1}, {-1}, -#line 302 "zonetab.list" - {gperf_offsetof(stringpool, 455),43200}, +#line 305 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str455,43200}, {-1}, {-1}, -#line 176 "zonetab.list" - {gperf_offsetof(stringpool, 458), 3600}, +#line 179 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str458, 3600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 135 "zonetab.list" - {gperf_offsetof(stringpool, 466), 18000}, +#line 138 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str466, 18000}, {-1}, -#line 174 "zonetab.list" - {gperf_offsetof(stringpool, 468), 36000}, +#line 177 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str468, 36000}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 324 "zonetab.list" - {gperf_offsetof(stringpool, 476),36000}, -#line 172 "zonetab.list" - {gperf_offsetof(stringpool, 477), -18000}, +#line 327 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str476,36000}, +#line 175 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str477, -18000}, {-1}, {-1}, {-1}, {-1}, -#line 160 "zonetab.list" - {gperf_offsetof(stringpool, 482), -10800}, +#line 163 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str482, -10800}, {-1}, {-1}, -#line 62 "zonetab.list" - {gperf_offsetof(stringpool, 485), -9*3600}, -#line 159 "zonetab.list" - {gperf_offsetof(stringpool, 486), 10800}, +#line 65 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str485, -9*3600}, +#line 162 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str486, 10800}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 233 "zonetab.list" - {gperf_offsetof(stringpool, 492),28800}, +#line 236 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str492,28800}, {-1}, {-1}, {-1}, {-1}, -#line 158 "zonetab.list" - {gperf_offsetof(stringpool, 497), 3600}, +#line 161 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str497, 3600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 177 "zonetab.list" - {gperf_offsetof(stringpool, 540), 3600}, +#line 180 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str540, 3600}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 59 "zonetab.list" - {gperf_offsetof(stringpool, 563), -8*3600}, +#line 62 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str563, -8*3600}, {-1}, {-1}, -#line 104 "zonetab.list" - {gperf_offsetof(stringpool, 566),12*3600}, -#line 139 "zonetab.list" - {gperf_offsetof(stringpool, 567), 0}, +#line 107 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str566,12*3600}, +#line 142 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str567, 0}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 138 "zonetab.list" - {gperf_offsetof(stringpool, 619), -10800} +#line 141 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str619, -10800} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) @@ -1558,5 +1560,5 @@ zonetab (register const char *str, register size_t len) } return 0; } -#line 327 "zonetab.list" +#line 330 "zonetab.list" diff --git a/ext/date/zonetab.list b/ext/date/zonetab.list index d2f902d2d5..63b6873447 100644 --- a/ext/date/zonetab.list +++ b/ext/date/zonetab.list @@ -1,9 +1,12 @@ %{ +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRNCMP 1 +#define gperf_case_strncmp strncasecmp struct zone { int name; int offset; }; -static const struct zone *zonetab(); +static const struct zone *zonetab(register const char *str, register size_t len); %} struct zone; @@ -313,8 +316,8 @@ vut,39600 wakt,43200 warst,-10800 wft,43200 -wgst,-7200 -wgt,-10800 +wgst,-3600 +wgt,-7200 wib,25200 wit,32400 wita,28800 diff --git a/ext/digest/.document b/ext/digest/.document new file mode 100644 index 0000000000..beab275b5a --- /dev/null +++ b/ext/digest/.document @@ -0,0 +1,3 @@ +digest.c +bubblebabble/bubblebabble.c +*/*init.c diff --git a/ext/digest/bubblebabble/bubblebabble.c b/ext/digest/bubblebabble/bubblebabble.c index 6557e43c9d..dac603c0d7 100644 --- a/ext/digest/bubblebabble/bubblebabble.c +++ b/ext/digest/bubblebabble/bubblebabble.c @@ -37,7 +37,7 @@ bubblebabble_str_new(VALUE str_digest) digest_len = RSTRING_LEN(str_digest); if ((LONG_MAX - 2) / 3 < (digest_len | 1)) { - rb_raise(rb_eRuntimeError, "digest string too long"); + rb_raise(rb_eRuntimeError, "digest string too long"); } str = rb_str_new(0, (digest_len | 1) * 3 + 2); @@ -129,15 +129,14 @@ Init_bubblebabble(void) rb_require("digest"); - rb_mDigest = rb_path2class("Digest"); - rb_mDigest_Instance = rb_path2class("Digest::Instance"); - rb_cDigest_Class = rb_path2class("Digest::Class"); - #if 0 rb_mDigest = rb_define_module("Digest"); rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance"); rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject); #endif + rb_mDigest = rb_digest_namespace(); + rb_mDigest_Instance = rb_const_get(rb_mDigest, rb_intern_const("Instance")); + rb_cDigest_Class = rb_const_get(rb_mDigest, rb_intern_const("Class")); rb_define_module_function(rb_mDigest, "bubblebabble", rb_digest_s_bubblebabble, 1); rb_define_singleton_method(rb_cDigest_Class, "bubblebabble", rb_digest_class_s_bubblebabble, -1); diff --git a/ext/digest/bubblebabble/depend b/ext/digest/bubblebabble/depend index b995438236..02d88e960c 100644 --- a/ext/digest/bubblebabble/depend +++ b/ext/digest/bubblebabble/depend @@ -2,6 +2,19 @@ bubblebabble.o: $(RUBY_EXTCONF_H) bubblebabble.o: $(arch_hdrdir)/ruby/config.h bubblebabble.o: $(hdrdir)/ruby.h +bubblebabble.o: $(hdrdir)/ruby/assert.h +bubblebabble.o: $(hdrdir)/ruby/backward.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/assume.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/attributes.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/bool.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/inttypes.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/limits.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/long_long.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/stdalign.h +bubblebabble.o: $(hdrdir)/ruby/backward/2/stdarg.h +bubblebabble.o: $(hdrdir)/ruby/defines.h +bubblebabble.o: $(hdrdir)/ruby/intern.h +bubblebabble.o: $(hdrdir)/ruby/internal/abi.h bubblebabble.o: $(hdrdir)/ruby/internal/anyargs.h bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic.h bubblebabble.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ bubblebabble.o: $(hdrdir)/ruby/internal/attr/noexcept.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/noinline.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/nonnull.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/noreturn.h +bubblebabble.o: $(hdrdir)/ruby/internal/attr/packed_struct.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/pure.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/restrict.h bubblebabble.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ bubblebabble.o: $(hdrdir)/ruby/internal/intern/enumerator.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/error.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/eval.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/file.h -bubblebabble.o: $(hdrdir)/ruby/internal/intern/gc.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/hash.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/io.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ bubblebabble.o: $(hdrdir)/ruby/internal/intern/re.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/ruby.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/select.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +bubblebabble.o: $(hdrdir)/ruby/internal/intern/set.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/signal.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/sprintf.h bubblebabble.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ bubblebabble.o: $(hdrdir)/ruby/internal/memory.h bubblebabble.o: $(hdrdir)/ruby/internal/method.h bubblebabble.o: $(hdrdir)/ruby/internal/module.h bubblebabble.o: $(hdrdir)/ruby/internal/newobj.h -bubblebabble.o: $(hdrdir)/ruby/internal/rgengc.h bubblebabble.o: $(hdrdir)/ruby/internal/scan_args.h bubblebabble.o: $(hdrdir)/ruby/internal/special_consts.h bubblebabble.o: $(hdrdir)/ruby/internal/static_assert.h bubblebabble.o: $(hdrdir)/ruby/internal/stdalign.h bubblebabble.o: $(hdrdir)/ruby/internal/stdbool.h +bubblebabble.o: $(hdrdir)/ruby/internal/stdckdint.h bubblebabble.o: $(hdrdir)/ruby/internal/symbol.h bubblebabble.o: $(hdrdir)/ruby/internal/value.h bubblebabble.o: $(hdrdir)/ruby/internal/value_type.h bubblebabble.o: $(hdrdir)/ruby/internal/variable.h bubblebabble.o: $(hdrdir)/ruby/internal/warning_push.h bubblebabble.o: $(hdrdir)/ruby/internal/xmalloc.h -bubblebabble.o: $(hdrdir)/ruby/assert.h -bubblebabble.o: $(hdrdir)/ruby/backward.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/assume.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/attributes.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/bool.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/inttypes.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/limits.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/long_long.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/stdalign.h -bubblebabble.o: $(hdrdir)/ruby/backward/2/stdarg.h -bubblebabble.o: $(hdrdir)/ruby/defines.h -bubblebabble.o: $(hdrdir)/ruby/intern.h bubblebabble.o: $(hdrdir)/ruby/missing.h bubblebabble.o: $(hdrdir)/ruby/ruby.h bubblebabble.o: $(hdrdir)/ruby/st.h diff --git a/ext/digest/defs.h b/ext/digest/defs.h index 77a134f364..9b11f4eca9 100644 --- a/ext/digest/defs.h +++ b/ext/digest/defs.h @@ -16,4 +16,26 @@ # define __END_DECLS #endif +#define RB_DIGEST_DIAGNOSTIC(compiler, op, flag) _Pragma(STRINGIZE(compiler diagnostic op flag)) +#ifdef RBIMPL_WARNING_IGNORED +# define RB_DIGEST_WARNING_IGNORED(flag) RBIMPL_WARNING_IGNORED(flag) +# define RB_DIGEST_WARNING_PUSH() RBIMPL_WARNING_PUSH() +# define RB_DIGEST_WARNING_POP() RBIMPL_WARNING_POP() +#elif defined(__clang__) +# define RB_DIGEST_WARNING_IGNORED(flag) RB_DIGEST_DIAGNOSTIC(clang, ignored, #flag) +# define RB_DIGEST_WARNING_PUSH() _Pragma("clang diagnostic push") +# define RB_DIGEST_WARNING_POP() _Pragma("clang diagnostic pop") +#else /* __GNUC__ */ +# define RB_DIGEST_WARNING_IGNORED(flag) RB_DIGEST_DIAGNOSTIC(GCC, ignored, #flag) +# define RB_DIGEST_WARNING_PUSH() _Pragma("GCC diagnostic push") +# define RB_DIGEST_WARNING_POP() _Pragma("GCC diagnostic pop") +#endif +#ifdef RBIMPL_HAS_WARNING +# define RB_DIGEST_HAS_WARNING(_) RBIMPL_HAS_WARNING(_) +#elif defined(__has_warning) +# define RB_DIGEST_HAS_WARNING(_) __has_warning(_) +#else +# define RB_DIGEST_HAS_WARNING(_) 0 +#endif + #endif /* DEFS_H */ diff --git a/ext/digest/depend b/ext/digest/depend index 856f9caa68..3eabb1d1d6 100644 --- a/ext/digest/depend +++ b/ext/digest/depend @@ -2,6 +2,19 @@ digest.o: $(RUBY_EXTCONF_H) digest.o: $(arch_hdrdir)/ruby/config.h digest.o: $(hdrdir)/ruby.h +digest.o: $(hdrdir)/ruby/assert.h +digest.o: $(hdrdir)/ruby/backward.h +digest.o: $(hdrdir)/ruby/backward/2/assume.h +digest.o: $(hdrdir)/ruby/backward/2/attributes.h +digest.o: $(hdrdir)/ruby/backward/2/bool.h +digest.o: $(hdrdir)/ruby/backward/2/inttypes.h +digest.o: $(hdrdir)/ruby/backward/2/limits.h +digest.o: $(hdrdir)/ruby/backward/2/long_long.h +digest.o: $(hdrdir)/ruby/backward/2/stdalign.h +digest.o: $(hdrdir)/ruby/backward/2/stdarg.h +digest.o: $(hdrdir)/ruby/defines.h +digest.o: $(hdrdir)/ruby/intern.h +digest.o: $(hdrdir)/ruby/internal/abi.h digest.o: $(hdrdir)/ruby/internal/anyargs.h digest.o: $(hdrdir)/ruby/internal/arithmetic.h digest.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h digest.o: $(hdrdir)/ruby/internal/attr/noinline.h digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h +digest.o: $(hdrdir)/ruby/internal/attr/packed_struct.h digest.o: $(hdrdir)/ruby/internal/attr/pure.h digest.o: $(hdrdir)/ruby/internal/attr/restrict.h digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h digest.o: $(hdrdir)/ruby/internal/intern/error.h digest.o: $(hdrdir)/ruby/internal/intern/eval.h digest.o: $(hdrdir)/ruby/internal/intern/file.h -digest.o: $(hdrdir)/ruby/internal/intern/gc.h digest.o: $(hdrdir)/ruby/internal/intern/hash.h digest.o: $(hdrdir)/ruby/internal/intern/io.h digest.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ digest.o: $(hdrdir)/ruby/internal/intern/re.h digest.o: $(hdrdir)/ruby/internal/intern/ruby.h digest.o: $(hdrdir)/ruby/internal/intern/select.h digest.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +digest.o: $(hdrdir)/ruby/internal/intern/set.h digest.o: $(hdrdir)/ruby/internal/intern/signal.h digest.o: $(hdrdir)/ruby/internal/intern/sprintf.h digest.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ digest.o: $(hdrdir)/ruby/internal/memory.h digest.o: $(hdrdir)/ruby/internal/method.h digest.o: $(hdrdir)/ruby/internal/module.h digest.o: $(hdrdir)/ruby/internal/newobj.h -digest.o: $(hdrdir)/ruby/internal/rgengc.h digest.o: $(hdrdir)/ruby/internal/scan_args.h digest.o: $(hdrdir)/ruby/internal/special_consts.h digest.o: $(hdrdir)/ruby/internal/static_assert.h digest.o: $(hdrdir)/ruby/internal/stdalign.h digest.o: $(hdrdir)/ruby/internal/stdbool.h +digest.o: $(hdrdir)/ruby/internal/stdckdint.h digest.o: $(hdrdir)/ruby/internal/symbol.h digest.o: $(hdrdir)/ruby/internal/value.h digest.o: $(hdrdir)/ruby/internal/value_type.h digest.o: $(hdrdir)/ruby/internal/variable.h digest.o: $(hdrdir)/ruby/internal/warning_push.h digest.o: $(hdrdir)/ruby/internal/xmalloc.h -digest.o: $(hdrdir)/ruby/assert.h -digest.o: $(hdrdir)/ruby/backward.h -digest.o: $(hdrdir)/ruby/backward/2/assume.h -digest.o: $(hdrdir)/ruby/backward/2/attributes.h -digest.o: $(hdrdir)/ruby/backward/2/bool.h -digest.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -digest.o: $(hdrdir)/ruby/backward/2/inttypes.h -digest.o: $(hdrdir)/ruby/backward/2/limits.h -digest.o: $(hdrdir)/ruby/backward/2/long_long.h -digest.o: $(hdrdir)/ruby/backward/2/stdalign.h -digest.o: $(hdrdir)/ruby/backward/2/stdarg.h -digest.o: $(hdrdir)/ruby/defines.h -digest.o: $(hdrdir)/ruby/intern.h digest.o: $(hdrdir)/ruby/missing.h digest.o: $(hdrdir)/ruby/ruby.h digest.o: $(hdrdir)/ruby/st.h diff --git a/ext/digest/digest.c b/ext/digest/digest.c index 83f4ee42fc..bd8d3e815f 100644 --- a/ext/digest/digest.c +++ b/ext/digest/digest.c @@ -154,7 +154,7 @@ static void rb_digest_instance_method_unimpl(VALUE self, const char *method) { rb_raise(rb_eRuntimeError, "%s does not implement %s()", - rb_obj_classname(self), method); + rb_obj_classname(self), method); } /* @@ -383,8 +383,8 @@ rb_digest_instance_equal(VALUE self, VALUE other) StringValue(str2); if (RSTRING_LEN(str1) == RSTRING_LEN(str2) && - rb_str_cmp(str1, str2) == 0) { - return Qtrue; + rb_str_cmp(str1, str2) == 0) { + return Qtrue; } return Qfalse; } @@ -534,9 +534,39 @@ rb_digest_class_init(VALUE self) * * * rb_ivar_set(cDigest_SHA1, rb_intern("metadata"), - * Data_Wrap_Struct(0, 0, 0, (void *)&sha1)); + * rb_digest_make_metadata(&sha1)); */ +#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL +static const rb_data_type_t metadata_type = { + "digest/metadata", + {0}, +}; + +RUBY_FUNC_EXPORTED VALUE +rb_digest_wrap_metadata(const rb_digest_metadata_t *meta) +{ + return rb_obj_freeze(TypedData_Wrap_Struct(0, &metadata_type, (void *)meta)); +} +#endif + +static rb_digest_metadata_t * +get_metadata_ptr(VALUE obj) +{ + rb_digest_metadata_t *algo; + +#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL + if (!rb_typeddata_is_kind_of(obj, &metadata_type)) return 0; + algo = RTYPEDDATA_DATA(obj); +#else +# undef RUBY_UNTYPED_DATA_WARNING +# define RUBY_UNTYPED_DATA_WARNING 0 + Data_Get_Struct(obj, rb_digest_metadata_t, algo); +#endif + + return algo; +} + static rb_digest_metadata_t * get_digest_base_metadata(VALUE klass) { @@ -554,8 +584,8 @@ get_digest_base_metadata(VALUE klass) if (NIL_P(p)) rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby"); - if (!RB_TYPE_P(obj, T_DATA) || RTYPEDDATA_P(obj)) { - wrong: + algo = get_metadata_ptr(obj); + if (!algo) { if (p == klass) rb_raise(rb_eTypeError, "%"PRIsVALUE"::metadata is not initialized properly", klass); @@ -564,12 +594,6 @@ get_digest_base_metadata(VALUE klass) klass, p); } -#undef RUBY_UNTYPED_DATA_WARNING -#define RUBY_UNTYPED_DATA_WARNING 0 - Data_Get_Struct(obj, rb_digest_metadata_t, algo); - - if (!algo) goto wrong; - switch (algo->api_version) { case 3: break; @@ -602,7 +626,7 @@ static inline void algo_init(const rb_digest_metadata_t *algo, void *pctx) { if (algo->init_func(pctx) != 1) { - rb_raise(rb_eRuntimeError, "Digest initialization failed."); + rb_raise(rb_eRuntimeError, "Digest initialization failed."); } } @@ -614,7 +638,7 @@ rb_digest_base_alloc(VALUE klass) void *pctx; if (klass == rb_cDigest_Base) { - rb_raise(rb_eNotImpError, "Digest::Base is an abstract class"); + rb_raise(rb_eNotImpError, "Digest::Base is an abstract class"); } algo = get_digest_base_metadata(klass); @@ -639,7 +663,7 @@ rb_digest_base_copy(VALUE copy, VALUE obj) algo = get_digest_obj_metadata(copy); if (algo != get_digest_obj_metadata(obj)) - rb_raise(rb_eTypeError, "different algorithms"); + rb_raise(rb_eTypeError, "different algorithms"); TypedData_Get_Struct(obj, void, &digest_type, pctx1); TypedData_Get_Struct(copy, void, &digest_type, pctx2); diff --git a/ext/digest/digest.gemspec b/ext/digest/digest.gemspec index 7a4291c7ca..4a01c5fde1 100644 --- a/ext/digest/digest.gemspec +++ b/ext/digest/digest.gemspec @@ -2,8 +2,13 @@ # frozen_string_literal: true Gem::Specification.new do |spec| + version_module = Module.new do + version_rb = File.join(__dir__, "lib/digest/version.rb") + module_eval(File.read(version_rb), version_rb) + end + spec.name = "digest" - spec.version = "3.1.0.pre2" + spec.version = version_module::Digest::VERSION spec.authors = ["Akinori MUSHA"] spec.email = ["knu@idaemons.org"] @@ -31,7 +36,7 @@ Gem::Specification.new do |spec| else spec.extensions = Dir["ext/digest/**/extconf.rb"] - spec.files += Dir["ext/digest/**/*.{rb,c,h,sh}"] + spec.files += Dir["ext/digest/**/{*.{rb,c,h,sh},depend}"] spec.require_paths = %w[lib] end diff --git a/ext/digest/digest.h b/ext/digest/digest.h index 0d4f0e7cc2..c5c37583a6 100644 --- a/ext/digest/digest.h +++ b/ext/digest/digest.h @@ -38,9 +38,10 @@ rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \ const unsigned int stride = 16384; \ \ for (; size > stride; size -= stride, ptr += stride) { \ - name##_Update(ctx, ptr, stride); \ + name##_Update(ctx, ptr, stride); \ } \ - if (size > 0) name##_Update(ctx, ptr, size); \ + /* Since size <= stride, size should fit into an unsigned int */ \ + if (size > 0) name##_Update(ctx, ptr, (unsigned int)size); \ } #define DEFINE_FINISH_FUNC_FROM_FINAL(name) \ @@ -63,10 +64,43 @@ rb_id_metadata(void) return rb_intern_const("metadata"); } +#if !defined(HAVE_RB_EXT_RESOLVE_SYMBOL) +#elif !defined(RUBY_UNTYPED_DATA_WARNING) +# error RUBY_UNTYPED_DATA_WARNING is not defined +#elif RUBY_UNTYPED_DATA_WARNING +/* rb_ext_resolve_symbol() has been defined since Ruby 3.3, but digest + * bundled with 3.3 didn't use it. */ +# define DIGEST_USE_RB_EXT_RESOLVE_SYMBOL 1 +#endif + static inline VALUE rb_digest_make_metadata(const rb_digest_metadata_t *meta) { -#undef RUBY_UNTYPED_DATA_WARNING -#define RUBY_UNTYPED_DATA_WARNING 0 +#if defined(EXTSTATIC) && EXTSTATIC + /* The extension is built as a static library, so safe to refer to + * rb_digest_wrap_metadata directly. */ + extern VALUE rb_digest_wrap_metadata(const rb_digest_metadata_t *meta); + return rb_digest_wrap_metadata(meta); +#else + /* The extension is built as a shared library, so we can't refer + * to rb_digest_wrap_metadata directly. */ +# ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL + /* If rb_ext_resolve_symbol() is available, use it to get the address of + * rb_digest_wrap_metadata. */ + typedef VALUE (*wrapper_func_type)(const rb_digest_metadata_t *meta); + static wrapper_func_type wrapper; + if (!wrapper) { + wrapper = (wrapper_func_type)(uintptr_t) + rb_ext_resolve_symbol("digest.so", "rb_digest_wrap_metadata"); + if (!wrapper) rb_raise(rb_eLoadError, "rb_digest_wrap_metadata not found"); + } + return wrapper(meta); +# else + /* If rb_ext_resolve_symbol() is not available, keep using untyped + * data. */ +# undef RUBY_UNTYPED_DATA_WARNING +# define RUBY_UNTYPED_DATA_WARNING 0 return rb_obj_freeze(Data_Wrap_Struct(0, 0, 0, (void *)meta)); +# endif +#endif } diff --git a/ext/digest/digest_conf.rb b/ext/digest/digest_conf.rb index 1b929d8732..099d20fcbe 100644 --- a/ext/digest/digest_conf.rb +++ b/ext/digest/digest_conf.rb @@ -2,14 +2,16 @@ def digest_conf(name) unless with_config("bundled-#{name}") - cc = with_config("common-digest") - if cc == true or /\b#{name}\b/ =~ cc - if File.exist?("#$srcdir/#{name}cc.h") and - have_header("CommonCrypto/CommonDigest.h") - $defs << "-D#{name.upcase}_USE_COMMONDIGEST" - $headers << "#{name}cc.h" - return :commondigest - end + case cc = with_config("common-digest", true) + when true, false + else + cc = cc.split(/[\s,]++/).any? {|pat| File.fnmatch?(pat, name)} + end + if cc and File.exist?("#$srcdir/#{name}cc.h") and + have_header("CommonCrypto/CommonDigest.h") + $defs << "-D#{name.upcase}_USE_COMMONDIGEST" + $headers << "#{name}cc.h" + return :commondigest end end $objs << "#{name}.#{$OBJEXT}" diff --git a/ext/digest/extconf.rb b/ext/digest/extconf.rb index a8c68850a2..0e5f08d794 100644 --- a/ext/digest/extconf.rb +++ b/ext/digest/extconf.rb @@ -6,6 +6,6 @@ require "mkmf" $INSTALLFILES = { "digest.h" => "$(HDRDIR)" -} +} if $extmk create_makefile("digest") diff --git a/ext/digest/lib/digest.rb b/ext/digest/lib/digest.rb index 7cb0d2c318..e995adb450 100644 --- a/ext/digest/lib/digest.rb +++ b/ext/digest/lib/digest.rb @@ -1,24 +1,23 @@ # frozen_string_literal: false -# The gem and bundle commands (except for bundle exec) first load -# digest via openssl and then load gems, so if this is installed via -# gem, we are overwriting the default version of digest. Beware not -# to break it or cause redefinition warnings. -# -# When we introduce incompatible changes and overwriting is not an -# option, and given that the default version does not have security -# defects, we may just give up and let those commands just use the -# default version of digest. -# -# return if defined?(Digest) && caller_locations.any? { |l| -# %r{/(rubygems/gem_runner|bundler/cli)\.rb}.match?(l.path) -# } +if defined?(Digest) && + /\A(?:2\.|3\.0\.[0-2]\z)/.match?(RUBY_VERSION) && + caller_locations.any? { |l| + %r{/(rubygems/gem_runner|bundler/cli)\.rb}.match?(l.path) + } + # Before Ruby 3.0.3/3.1.0, the gem and bundle commands used to load + # the digest library before loading additionally installed gems, so + # you will get constant redefinition warnings and unexpected + # implementation overwriting if we proceed here. Avoid that. + return +end +require 'digest/version' require 'digest/loader' module Digest # A mutex for Digest(). - REQUIRE_MUTEX ||= Thread::Mutex.new + REQUIRE_MUTEX = Thread::Mutex.new def self.const_missing(name) # :nodoc: case name diff --git a/ext/digest/lib/digest/version.rb b/ext/digest/lib/digest/version.rb new file mode 100644 index 0000000000..a56e80c54e --- /dev/null +++ b/ext/digest/lib/digest/version.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Digest + # The version string + VERSION = "3.2.1" +end diff --git a/ext/digest/md5/depend b/ext/digest/md5/depend index 258ec88e54..d1c25c28c8 100644 --- a/ext/digest/md5/depend +++ b/ext/digest/md5/depend @@ -10,7 +10,6 @@ md5.o: $(hdrdir)/ruby/backward.h md5.o: $(hdrdir)/ruby/backward/2/assume.h md5.o: $(hdrdir)/ruby/backward/2/attributes.h md5.o: $(hdrdir)/ruby/backward/2/bool.h -md5.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h md5.o: $(hdrdir)/ruby/backward/2/inttypes.h md5.o: $(hdrdir)/ruby/backward/2/limits.h md5.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -18,6 +17,7 @@ md5.o: $(hdrdir)/ruby/backward/2/stdalign.h md5.o: $(hdrdir)/ruby/backward/2/stdarg.h md5.o: $(hdrdir)/ruby/defines.h md5.o: $(hdrdir)/ruby/intern.h +md5.o: $(hdrdir)/ruby/internal/abi.h md5.o: $(hdrdir)/ruby/internal/anyargs.h md5.o: $(hdrdir)/ruby/internal/arithmetic.h md5.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -55,6 +55,7 @@ md5.o: $(hdrdir)/ruby/internal/attr/noexcept.h md5.o: $(hdrdir)/ruby/internal/attr/noinline.h md5.o: $(hdrdir)/ruby/internal/attr/nonnull.h md5.o: $(hdrdir)/ruby/internal/attr/noreturn.h +md5.o: $(hdrdir)/ruby/internal/attr/packed_struct.h md5.o: $(hdrdir)/ruby/internal/attr/pure.h md5.o: $(hdrdir)/ruby/internal/attr/restrict.h md5.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -114,7 +115,6 @@ md5.o: $(hdrdir)/ruby/internal/intern/enumerator.h md5.o: $(hdrdir)/ruby/internal/intern/error.h md5.o: $(hdrdir)/ruby/internal/intern/eval.h md5.o: $(hdrdir)/ruby/internal/intern/file.h -md5.o: $(hdrdir)/ruby/internal/intern/gc.h md5.o: $(hdrdir)/ruby/internal/intern/hash.h md5.o: $(hdrdir)/ruby/internal/intern/io.h md5.o: $(hdrdir)/ruby/internal/intern/load.h @@ -131,6 +131,7 @@ md5.o: $(hdrdir)/ruby/internal/intern/re.h md5.o: $(hdrdir)/ruby/internal/intern/ruby.h md5.o: $(hdrdir)/ruby/internal/intern/select.h md5.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +md5.o: $(hdrdir)/ruby/internal/intern/set.h md5.o: $(hdrdir)/ruby/internal/intern/signal.h md5.o: $(hdrdir)/ruby/internal/intern/sprintf.h md5.o: $(hdrdir)/ruby/internal/intern/string.h @@ -145,12 +146,12 @@ md5.o: $(hdrdir)/ruby/internal/memory.h md5.o: $(hdrdir)/ruby/internal/method.h md5.o: $(hdrdir)/ruby/internal/module.h md5.o: $(hdrdir)/ruby/internal/newobj.h -md5.o: $(hdrdir)/ruby/internal/rgengc.h md5.o: $(hdrdir)/ruby/internal/scan_args.h md5.o: $(hdrdir)/ruby/internal/special_consts.h md5.o: $(hdrdir)/ruby/internal/static_assert.h md5.o: $(hdrdir)/ruby/internal/stdalign.h md5.o: $(hdrdir)/ruby/internal/stdbool.h +md5.o: $(hdrdir)/ruby/internal/stdckdint.h md5.o: $(hdrdir)/ruby/internal/symbol.h md5.o: $(hdrdir)/ruby/internal/value.h md5.o: $(hdrdir)/ruby/internal/value_type.h @@ -172,7 +173,6 @@ md5init.o: $(hdrdir)/ruby/backward.h md5init.o: $(hdrdir)/ruby/backward/2/assume.h md5init.o: $(hdrdir)/ruby/backward/2/attributes.h md5init.o: $(hdrdir)/ruby/backward/2/bool.h -md5init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h md5init.o: $(hdrdir)/ruby/backward/2/inttypes.h md5init.o: $(hdrdir)/ruby/backward/2/limits.h md5init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -180,6 +180,7 @@ md5init.o: $(hdrdir)/ruby/backward/2/stdalign.h md5init.o: $(hdrdir)/ruby/backward/2/stdarg.h md5init.o: $(hdrdir)/ruby/defines.h md5init.o: $(hdrdir)/ruby/intern.h +md5init.o: $(hdrdir)/ruby/internal/abi.h md5init.o: $(hdrdir)/ruby/internal/anyargs.h md5init.o: $(hdrdir)/ruby/internal/arithmetic.h md5init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -217,6 +218,7 @@ md5init.o: $(hdrdir)/ruby/internal/attr/noexcept.h md5init.o: $(hdrdir)/ruby/internal/attr/noinline.h md5init.o: $(hdrdir)/ruby/internal/attr/nonnull.h md5init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +md5init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h md5init.o: $(hdrdir)/ruby/internal/attr/pure.h md5init.o: $(hdrdir)/ruby/internal/attr/restrict.h md5init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -276,7 +278,6 @@ md5init.o: $(hdrdir)/ruby/internal/intern/enumerator.h md5init.o: $(hdrdir)/ruby/internal/intern/error.h md5init.o: $(hdrdir)/ruby/internal/intern/eval.h md5init.o: $(hdrdir)/ruby/internal/intern/file.h -md5init.o: $(hdrdir)/ruby/internal/intern/gc.h md5init.o: $(hdrdir)/ruby/internal/intern/hash.h md5init.o: $(hdrdir)/ruby/internal/intern/io.h md5init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -293,6 +294,7 @@ md5init.o: $(hdrdir)/ruby/internal/intern/re.h md5init.o: $(hdrdir)/ruby/internal/intern/ruby.h md5init.o: $(hdrdir)/ruby/internal/intern/select.h md5init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +md5init.o: $(hdrdir)/ruby/internal/intern/set.h md5init.o: $(hdrdir)/ruby/internal/intern/signal.h md5init.o: $(hdrdir)/ruby/internal/intern/sprintf.h md5init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -307,12 +309,12 @@ md5init.o: $(hdrdir)/ruby/internal/memory.h md5init.o: $(hdrdir)/ruby/internal/method.h md5init.o: $(hdrdir)/ruby/internal/module.h md5init.o: $(hdrdir)/ruby/internal/newobj.h -md5init.o: $(hdrdir)/ruby/internal/rgengc.h md5init.o: $(hdrdir)/ruby/internal/scan_args.h md5init.o: $(hdrdir)/ruby/internal/special_consts.h md5init.o: $(hdrdir)/ruby/internal/static_assert.h md5init.o: $(hdrdir)/ruby/internal/stdalign.h md5init.o: $(hdrdir)/ruby/internal/stdbool.h +md5init.o: $(hdrdir)/ruby/internal/stdckdint.h md5init.o: $(hdrdir)/ruby/internal/symbol.h md5init.o: $(hdrdir)/ruby/internal/value.h md5init.o: $(hdrdir)/ruby/internal/value_type.h @@ -326,5 +328,6 @@ md5init.o: $(hdrdir)/ruby/subst.h md5init.o: $(srcdir)/../defs.h md5init.o: $(srcdir)/../digest.h md5init.o: md5.h +md5init.o: md5cc.h md5init.o: md5init.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/md5/md5.c b/ext/digest/md5/md5.c index 19fe54a693..3a7fe2cdad 100644 --- a/ext/digest/md5/md5.c +++ b/ext/digest/md5/md5.c @@ -225,7 +225,7 @@ md5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/) uint32_t xbuf[16]; const uint32_t *X; - if (!((data - (const uint8_t *)0) & 3)) { + if (!(((uintptr_t)data) & 3)) { /* data are properly aligned */ X = (const uint32_t *)data; } else { diff --git a/ext/digest/md5/md5cc.h b/ext/digest/md5/md5cc.h index e34d7d5c11..a002c17604 100644 --- a/ext/digest/md5/md5cc.h +++ b/ext/digest/md5/md5cc.h @@ -1,8 +1,8 @@ #define COMMON_DIGEST_FOR_OPENSSL 1 #include <CommonCrypto/CommonDigest.h> -#ifdef __clang__ -# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#ifdef __GNUC__ +RB_DIGEST_WARNING_IGNORED(-Wdeprecated-declarations) /* Suppress deprecation warnings of MD5 from Xcode 11.1 */ /* Although we know MD5 is deprecated too, provide just for backward * compatibility, as well as Apple does. */ @@ -17,3 +17,11 @@ static DEFINE_FINISH_FUNC_FROM_FINAL(MD5) #undef MD5_Finish #define MD5_Update rb_digest_MD5_update #define MD5_Finish rb_digest_MD5_finish + +/* + * Pre-10.6 defines are with args, which don't match the argless use in + * the function pointer inits. Thus, we redefine MD5_Init as well. + * This is a NOP on 10.6+. + */ +#undef MD5_Init +#define MD5_Init CC_MD5_Init diff --git a/ext/digest/md5/md5init.c b/ext/digest/md5/md5init.c index 52cba78bf1..c919060587 100644 --- a/ext/digest/md5/md5init.c +++ b/ext/digest/md5/md5init.c @@ -3,6 +3,7 @@ #include <ruby/ruby.h> #include "../digest.h" +#include "../defs.h" #if defined(MD5_USE_COMMONDIGEST) #include "md5cc.h" #else @@ -53,9 +54,8 @@ Init_md5(void) mDigest = rb_define_module("Digest"); /* let rdoc know */ #endif mDigest = rb_digest_namespace(); - cDigest_Base = rb_path2class("Digest::Base"); + cDigest_Base = rb_const_get(mDigest, rb_intern_const("Base")); cDigest_MD5 = rb_define_class_under(mDigest, "MD5", cDigest_Base); - rb_iv_set(cDigest_MD5, "metadata", rb_digest_make_metadata(&md5)); } diff --git a/ext/digest/rmd160/depend b/ext/digest/rmd160/depend index 8a7f555754..aec484f7b3 100644 --- a/ext/digest/rmd160/depend +++ b/ext/digest/rmd160/depend @@ -10,7 +10,6 @@ rmd160.o: $(hdrdir)/ruby/backward.h rmd160.o: $(hdrdir)/ruby/backward/2/assume.h rmd160.o: $(hdrdir)/ruby/backward/2/attributes.h rmd160.o: $(hdrdir)/ruby/backward/2/bool.h -rmd160.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h rmd160.o: $(hdrdir)/ruby/backward/2/inttypes.h rmd160.o: $(hdrdir)/ruby/backward/2/limits.h rmd160.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -18,6 +17,7 @@ rmd160.o: $(hdrdir)/ruby/backward/2/stdalign.h rmd160.o: $(hdrdir)/ruby/backward/2/stdarg.h rmd160.o: $(hdrdir)/ruby/defines.h rmd160.o: $(hdrdir)/ruby/intern.h +rmd160.o: $(hdrdir)/ruby/internal/abi.h rmd160.o: $(hdrdir)/ruby/internal/anyargs.h rmd160.o: $(hdrdir)/ruby/internal/arithmetic.h rmd160.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -55,6 +55,7 @@ rmd160.o: $(hdrdir)/ruby/internal/attr/noexcept.h rmd160.o: $(hdrdir)/ruby/internal/attr/noinline.h rmd160.o: $(hdrdir)/ruby/internal/attr/nonnull.h rmd160.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rmd160.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rmd160.o: $(hdrdir)/ruby/internal/attr/pure.h rmd160.o: $(hdrdir)/ruby/internal/attr/restrict.h rmd160.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -114,7 +115,6 @@ rmd160.o: $(hdrdir)/ruby/internal/intern/enumerator.h rmd160.o: $(hdrdir)/ruby/internal/intern/error.h rmd160.o: $(hdrdir)/ruby/internal/intern/eval.h rmd160.o: $(hdrdir)/ruby/internal/intern/file.h -rmd160.o: $(hdrdir)/ruby/internal/intern/gc.h rmd160.o: $(hdrdir)/ruby/internal/intern/hash.h rmd160.o: $(hdrdir)/ruby/internal/intern/io.h rmd160.o: $(hdrdir)/ruby/internal/intern/load.h @@ -131,6 +131,7 @@ rmd160.o: $(hdrdir)/ruby/internal/intern/re.h rmd160.o: $(hdrdir)/ruby/internal/intern/ruby.h rmd160.o: $(hdrdir)/ruby/internal/intern/select.h rmd160.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rmd160.o: $(hdrdir)/ruby/internal/intern/set.h rmd160.o: $(hdrdir)/ruby/internal/intern/signal.h rmd160.o: $(hdrdir)/ruby/internal/intern/sprintf.h rmd160.o: $(hdrdir)/ruby/internal/intern/string.h @@ -145,12 +146,12 @@ rmd160.o: $(hdrdir)/ruby/internal/memory.h rmd160.o: $(hdrdir)/ruby/internal/method.h rmd160.o: $(hdrdir)/ruby/internal/module.h rmd160.o: $(hdrdir)/ruby/internal/newobj.h -rmd160.o: $(hdrdir)/ruby/internal/rgengc.h rmd160.o: $(hdrdir)/ruby/internal/scan_args.h rmd160.o: $(hdrdir)/ruby/internal/special_consts.h rmd160.o: $(hdrdir)/ruby/internal/static_assert.h rmd160.o: $(hdrdir)/ruby/internal/stdalign.h rmd160.o: $(hdrdir)/ruby/internal/stdbool.h +rmd160.o: $(hdrdir)/ruby/internal/stdckdint.h rmd160.o: $(hdrdir)/ruby/internal/symbol.h rmd160.o: $(hdrdir)/ruby/internal/value.h rmd160.o: $(hdrdir)/ruby/internal/value_type.h @@ -172,7 +173,6 @@ rmd160init.o: $(hdrdir)/ruby/backward.h rmd160init.o: $(hdrdir)/ruby/backward/2/assume.h rmd160init.o: $(hdrdir)/ruby/backward/2/attributes.h rmd160init.o: $(hdrdir)/ruby/backward/2/bool.h -rmd160init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h rmd160init.o: $(hdrdir)/ruby/backward/2/inttypes.h rmd160init.o: $(hdrdir)/ruby/backward/2/limits.h rmd160init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -180,6 +180,7 @@ rmd160init.o: $(hdrdir)/ruby/backward/2/stdalign.h rmd160init.o: $(hdrdir)/ruby/backward/2/stdarg.h rmd160init.o: $(hdrdir)/ruby/defines.h rmd160init.o: $(hdrdir)/ruby/intern.h +rmd160init.o: $(hdrdir)/ruby/internal/abi.h rmd160init.o: $(hdrdir)/ruby/internal/anyargs.h rmd160init.o: $(hdrdir)/ruby/internal/arithmetic.h rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -217,6 +218,7 @@ rmd160init.o: $(hdrdir)/ruby/internal/attr/noexcept.h rmd160init.o: $(hdrdir)/ruby/internal/attr/noinline.h rmd160init.o: $(hdrdir)/ruby/internal/attr/nonnull.h rmd160init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rmd160init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h rmd160init.o: $(hdrdir)/ruby/internal/attr/pure.h rmd160init.o: $(hdrdir)/ruby/internal/attr/restrict.h rmd160init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -276,7 +278,6 @@ rmd160init.o: $(hdrdir)/ruby/internal/intern/enumerator.h rmd160init.o: $(hdrdir)/ruby/internal/intern/error.h rmd160init.o: $(hdrdir)/ruby/internal/intern/eval.h rmd160init.o: $(hdrdir)/ruby/internal/intern/file.h -rmd160init.o: $(hdrdir)/ruby/internal/intern/gc.h rmd160init.o: $(hdrdir)/ruby/internal/intern/hash.h rmd160init.o: $(hdrdir)/ruby/internal/intern/io.h rmd160init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -293,6 +294,7 @@ rmd160init.o: $(hdrdir)/ruby/internal/intern/re.h rmd160init.o: $(hdrdir)/ruby/internal/intern/ruby.h rmd160init.o: $(hdrdir)/ruby/internal/intern/select.h rmd160init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rmd160init.o: $(hdrdir)/ruby/internal/intern/set.h rmd160init.o: $(hdrdir)/ruby/internal/intern/signal.h rmd160init.o: $(hdrdir)/ruby/internal/intern/sprintf.h rmd160init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -307,12 +309,12 @@ rmd160init.o: $(hdrdir)/ruby/internal/memory.h rmd160init.o: $(hdrdir)/ruby/internal/method.h rmd160init.o: $(hdrdir)/ruby/internal/module.h rmd160init.o: $(hdrdir)/ruby/internal/newobj.h -rmd160init.o: $(hdrdir)/ruby/internal/rgengc.h rmd160init.o: $(hdrdir)/ruby/internal/scan_args.h rmd160init.o: $(hdrdir)/ruby/internal/special_consts.h rmd160init.o: $(hdrdir)/ruby/internal/static_assert.h rmd160init.o: $(hdrdir)/ruby/internal/stdalign.h rmd160init.o: $(hdrdir)/ruby/internal/stdbool.h +rmd160init.o: $(hdrdir)/ruby/internal/stdckdint.h rmd160init.o: $(hdrdir)/ruby/internal/symbol.h rmd160init.o: $(hdrdir)/ruby/internal/value.h rmd160init.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/digest/rmd160/rmd160init.c b/ext/digest/rmd160/rmd160init.c index 2ae81ec4d6..e4b707ed9e 100644 --- a/ext/digest/rmd160/rmd160init.c +++ b/ext/digest/rmd160/rmd160init.c @@ -49,9 +49,8 @@ Init_rmd160(void) mDigest = rb_define_module("Digest"); /* let rdoc know */ #endif mDigest = rb_digest_namespace(); - cDigest_Base = rb_path2class("Digest::Base"); + cDigest_Base = rb_const_get(mDigest, rb_intern_const("Base")); cDigest_RMD160 = rb_define_class_under(mDigest, "RMD160", cDigest_Base); - rb_iv_set(cDigest_RMD160, "metadata", rb_digest_make_metadata(&rmd160)); } diff --git a/ext/digest/sha1/depend b/ext/digest/sha1/depend index 055e1fbaa0..e6bd9d8f73 100644 --- a/ext/digest/sha1/depend +++ b/ext/digest/sha1/depend @@ -10,7 +10,6 @@ sha1.o: $(hdrdir)/ruby/backward.h sha1.o: $(hdrdir)/ruby/backward/2/assume.h sha1.o: $(hdrdir)/ruby/backward/2/attributes.h sha1.o: $(hdrdir)/ruby/backward/2/bool.h -sha1.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h sha1.o: $(hdrdir)/ruby/backward/2/inttypes.h sha1.o: $(hdrdir)/ruby/backward/2/limits.h sha1.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -18,6 +17,7 @@ sha1.o: $(hdrdir)/ruby/backward/2/stdalign.h sha1.o: $(hdrdir)/ruby/backward/2/stdarg.h sha1.o: $(hdrdir)/ruby/defines.h sha1.o: $(hdrdir)/ruby/intern.h +sha1.o: $(hdrdir)/ruby/internal/abi.h sha1.o: $(hdrdir)/ruby/internal/anyargs.h sha1.o: $(hdrdir)/ruby/internal/arithmetic.h sha1.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -55,6 +55,7 @@ sha1.o: $(hdrdir)/ruby/internal/attr/noexcept.h sha1.o: $(hdrdir)/ruby/internal/attr/noinline.h sha1.o: $(hdrdir)/ruby/internal/attr/nonnull.h sha1.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sha1.o: $(hdrdir)/ruby/internal/attr/pure.h sha1.o: $(hdrdir)/ruby/internal/attr/restrict.h sha1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -114,7 +115,6 @@ sha1.o: $(hdrdir)/ruby/internal/intern/enumerator.h sha1.o: $(hdrdir)/ruby/internal/intern/error.h sha1.o: $(hdrdir)/ruby/internal/intern/eval.h sha1.o: $(hdrdir)/ruby/internal/intern/file.h -sha1.o: $(hdrdir)/ruby/internal/intern/gc.h sha1.o: $(hdrdir)/ruby/internal/intern/hash.h sha1.o: $(hdrdir)/ruby/internal/intern/io.h sha1.o: $(hdrdir)/ruby/internal/intern/load.h @@ -131,6 +131,7 @@ sha1.o: $(hdrdir)/ruby/internal/intern/re.h sha1.o: $(hdrdir)/ruby/internal/intern/ruby.h sha1.o: $(hdrdir)/ruby/internal/intern/select.h sha1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha1.o: $(hdrdir)/ruby/internal/intern/set.h sha1.o: $(hdrdir)/ruby/internal/intern/signal.h sha1.o: $(hdrdir)/ruby/internal/intern/sprintf.h sha1.o: $(hdrdir)/ruby/internal/intern/string.h @@ -145,12 +146,12 @@ sha1.o: $(hdrdir)/ruby/internal/memory.h sha1.o: $(hdrdir)/ruby/internal/method.h sha1.o: $(hdrdir)/ruby/internal/module.h sha1.o: $(hdrdir)/ruby/internal/newobj.h -sha1.o: $(hdrdir)/ruby/internal/rgengc.h sha1.o: $(hdrdir)/ruby/internal/scan_args.h sha1.o: $(hdrdir)/ruby/internal/special_consts.h sha1.o: $(hdrdir)/ruby/internal/static_assert.h sha1.o: $(hdrdir)/ruby/internal/stdalign.h sha1.o: $(hdrdir)/ruby/internal/stdbool.h +sha1.o: $(hdrdir)/ruby/internal/stdckdint.h sha1.o: $(hdrdir)/ruby/internal/symbol.h sha1.o: $(hdrdir)/ruby/internal/value.h sha1.o: $(hdrdir)/ruby/internal/value_type.h @@ -172,7 +173,6 @@ sha1init.o: $(hdrdir)/ruby/backward.h sha1init.o: $(hdrdir)/ruby/backward/2/assume.h sha1init.o: $(hdrdir)/ruby/backward/2/attributes.h sha1init.o: $(hdrdir)/ruby/backward/2/bool.h -sha1init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h sha1init.o: $(hdrdir)/ruby/backward/2/inttypes.h sha1init.o: $(hdrdir)/ruby/backward/2/limits.h sha1init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -180,6 +180,7 @@ sha1init.o: $(hdrdir)/ruby/backward/2/stdalign.h sha1init.o: $(hdrdir)/ruby/backward/2/stdarg.h sha1init.o: $(hdrdir)/ruby/defines.h sha1init.o: $(hdrdir)/ruby/intern.h +sha1init.o: $(hdrdir)/ruby/internal/abi.h sha1init.o: $(hdrdir)/ruby/internal/anyargs.h sha1init.o: $(hdrdir)/ruby/internal/arithmetic.h sha1init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -217,6 +218,7 @@ sha1init.o: $(hdrdir)/ruby/internal/attr/noexcept.h sha1init.o: $(hdrdir)/ruby/internal/attr/noinline.h sha1init.o: $(hdrdir)/ruby/internal/attr/nonnull.h sha1init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha1init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sha1init.o: $(hdrdir)/ruby/internal/attr/pure.h sha1init.o: $(hdrdir)/ruby/internal/attr/restrict.h sha1init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -276,7 +278,6 @@ sha1init.o: $(hdrdir)/ruby/internal/intern/enumerator.h sha1init.o: $(hdrdir)/ruby/internal/intern/error.h sha1init.o: $(hdrdir)/ruby/internal/intern/eval.h sha1init.o: $(hdrdir)/ruby/internal/intern/file.h -sha1init.o: $(hdrdir)/ruby/internal/intern/gc.h sha1init.o: $(hdrdir)/ruby/internal/intern/hash.h sha1init.o: $(hdrdir)/ruby/internal/intern/io.h sha1init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -293,6 +294,7 @@ sha1init.o: $(hdrdir)/ruby/internal/intern/re.h sha1init.o: $(hdrdir)/ruby/internal/intern/ruby.h sha1init.o: $(hdrdir)/ruby/internal/intern/select.h sha1init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha1init.o: $(hdrdir)/ruby/internal/intern/set.h sha1init.o: $(hdrdir)/ruby/internal/intern/signal.h sha1init.o: $(hdrdir)/ruby/internal/intern/sprintf.h sha1init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -307,12 +309,12 @@ sha1init.o: $(hdrdir)/ruby/internal/memory.h sha1init.o: $(hdrdir)/ruby/internal/method.h sha1init.o: $(hdrdir)/ruby/internal/module.h sha1init.o: $(hdrdir)/ruby/internal/newobj.h -sha1init.o: $(hdrdir)/ruby/internal/rgengc.h sha1init.o: $(hdrdir)/ruby/internal/scan_args.h sha1init.o: $(hdrdir)/ruby/internal/special_consts.h sha1init.o: $(hdrdir)/ruby/internal/static_assert.h sha1init.o: $(hdrdir)/ruby/internal/stdalign.h sha1init.o: $(hdrdir)/ruby/internal/stdbool.h +sha1init.o: $(hdrdir)/ruby/internal/stdckdint.h sha1init.o: $(hdrdir)/ruby/internal/symbol.h sha1init.o: $(hdrdir)/ruby/internal/value.h sha1init.o: $(hdrdir)/ruby/internal/value_type.h @@ -326,5 +328,6 @@ sha1init.o: $(hdrdir)/ruby/subst.h sha1init.o: $(srcdir)/../defs.h sha1init.o: $(srcdir)/../digest.h sha1init.o: sha1.h +sha1init.o: sha1cc.h sha1init.o: sha1init.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/sha1/sha1.c b/ext/digest/sha1/sha1.c index 5311227549..ce200270b7 100644 --- a/ext/digest/sha1/sha1.c +++ b/ext/digest/sha1/sha1.c @@ -232,8 +232,14 @@ void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) if ((j + len) > 63) { (void)memcpy(&context->buffer[j], data, (i = 64-j)); SHA1_Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) + for ( ; i + 63 < len; i += 64) { + RB_DIGEST_WARNING_PUSH(); +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 11 + RB_DIGEST_WARNING_IGNORED(-Wstringop-overread); +#endif SHA1_Transform(context->state, &data[i]); + RB_DIGEST_WARNING_POP(); + } j = 0; } else { i = 0; diff --git a/ext/digest/sha1/sha1cc.h b/ext/digest/sha1/sha1cc.h index 2ed8d646ab..f39ecc6234 100644 --- a/ext/digest/sha1/sha1cc.h +++ b/ext/digest/sha1/sha1cc.h @@ -12,3 +12,11 @@ static DEFINE_FINISH_FUNC_FROM_FINAL(SHA1) #undef SHA1_Finish #define SHA1_Update rb_digest_SHA1_update #define SHA1_Finish rb_digest_SHA1_finish + +/* + * Pre-10.6 defines are with args, which don't match the argless use in + * the function pointer inits. Thus, we redefine SHA1_Init as well. + * This is a NOP on 10.6+. + */ +#undef SHA1_Init +#define SHA1_Init CC_SHA1_Init diff --git a/ext/digest/sha1/sha1init.c b/ext/digest/sha1/sha1init.c index f7047bc6d3..c39959f428 100644 --- a/ext/digest/sha1/sha1init.c +++ b/ext/digest/sha1/sha1init.c @@ -55,9 +55,8 @@ Init_sha1(void) mDigest = rb_define_module("Digest"); /* let rdoc know */ #endif mDigest = rb_digest_namespace(); - cDigest_Base = rb_path2class("Digest::Base"); + cDigest_Base = rb_const_get(mDigest, rb_intern_const("Base")); cDigest_SHA1 = rb_define_class_under(mDigest, "SHA1", cDigest_Base); - rb_iv_set(cDigest_SHA1, "metadata", rb_digest_make_metadata(&sha1)); } diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend index c3399e76f5..2b74776b3e 100644 --- a/ext/digest/sha2/depend +++ b/ext/digest/sha2/depend @@ -10,7 +10,6 @@ sha2.o: $(hdrdir)/ruby/backward.h sha2.o: $(hdrdir)/ruby/backward/2/assume.h sha2.o: $(hdrdir)/ruby/backward/2/attributes.h sha2.o: $(hdrdir)/ruby/backward/2/bool.h -sha2.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h sha2.o: $(hdrdir)/ruby/backward/2/inttypes.h sha2.o: $(hdrdir)/ruby/backward/2/limits.h sha2.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -18,6 +17,7 @@ sha2.o: $(hdrdir)/ruby/backward/2/stdalign.h sha2.o: $(hdrdir)/ruby/backward/2/stdarg.h sha2.o: $(hdrdir)/ruby/defines.h sha2.o: $(hdrdir)/ruby/intern.h +sha2.o: $(hdrdir)/ruby/internal/abi.h sha2.o: $(hdrdir)/ruby/internal/anyargs.h sha2.o: $(hdrdir)/ruby/internal/arithmetic.h sha2.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -55,6 +55,7 @@ sha2.o: $(hdrdir)/ruby/internal/attr/noexcept.h sha2.o: $(hdrdir)/ruby/internal/attr/noinline.h sha2.o: $(hdrdir)/ruby/internal/attr/nonnull.h sha2.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha2.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sha2.o: $(hdrdir)/ruby/internal/attr/pure.h sha2.o: $(hdrdir)/ruby/internal/attr/restrict.h sha2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -114,7 +115,6 @@ sha2.o: $(hdrdir)/ruby/internal/intern/enumerator.h sha2.o: $(hdrdir)/ruby/internal/intern/error.h sha2.o: $(hdrdir)/ruby/internal/intern/eval.h sha2.o: $(hdrdir)/ruby/internal/intern/file.h -sha2.o: $(hdrdir)/ruby/internal/intern/gc.h sha2.o: $(hdrdir)/ruby/internal/intern/hash.h sha2.o: $(hdrdir)/ruby/internal/intern/io.h sha2.o: $(hdrdir)/ruby/internal/intern/load.h @@ -131,6 +131,7 @@ sha2.o: $(hdrdir)/ruby/internal/intern/re.h sha2.o: $(hdrdir)/ruby/internal/intern/ruby.h sha2.o: $(hdrdir)/ruby/internal/intern/select.h sha2.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha2.o: $(hdrdir)/ruby/internal/intern/set.h sha2.o: $(hdrdir)/ruby/internal/intern/signal.h sha2.o: $(hdrdir)/ruby/internal/intern/sprintf.h sha2.o: $(hdrdir)/ruby/internal/intern/string.h @@ -145,12 +146,12 @@ sha2.o: $(hdrdir)/ruby/internal/memory.h sha2.o: $(hdrdir)/ruby/internal/method.h sha2.o: $(hdrdir)/ruby/internal/module.h sha2.o: $(hdrdir)/ruby/internal/newobj.h -sha2.o: $(hdrdir)/ruby/internal/rgengc.h sha2.o: $(hdrdir)/ruby/internal/scan_args.h sha2.o: $(hdrdir)/ruby/internal/special_consts.h sha2.o: $(hdrdir)/ruby/internal/static_assert.h sha2.o: $(hdrdir)/ruby/internal/stdalign.h sha2.o: $(hdrdir)/ruby/internal/stdbool.h +sha2.o: $(hdrdir)/ruby/internal/stdckdint.h sha2.o: $(hdrdir)/ruby/internal/symbol.h sha2.o: $(hdrdir)/ruby/internal/value.h sha2.o: $(hdrdir)/ruby/internal/value_type.h @@ -172,7 +173,6 @@ sha2init.o: $(hdrdir)/ruby/backward.h sha2init.o: $(hdrdir)/ruby/backward/2/assume.h sha2init.o: $(hdrdir)/ruby/backward/2/attributes.h sha2init.o: $(hdrdir)/ruby/backward/2/bool.h -sha2init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h sha2init.o: $(hdrdir)/ruby/backward/2/inttypes.h sha2init.o: $(hdrdir)/ruby/backward/2/limits.h sha2init.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -180,6 +180,7 @@ sha2init.o: $(hdrdir)/ruby/backward/2/stdalign.h sha2init.o: $(hdrdir)/ruby/backward/2/stdarg.h sha2init.o: $(hdrdir)/ruby/defines.h sha2init.o: $(hdrdir)/ruby/intern.h +sha2init.o: $(hdrdir)/ruby/internal/abi.h sha2init.o: $(hdrdir)/ruby/internal/anyargs.h sha2init.o: $(hdrdir)/ruby/internal/arithmetic.h sha2init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -217,6 +218,7 @@ sha2init.o: $(hdrdir)/ruby/internal/attr/noexcept.h sha2init.o: $(hdrdir)/ruby/internal/attr/noinline.h sha2init.o: $(hdrdir)/ruby/internal/attr/nonnull.h sha2init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha2init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sha2init.o: $(hdrdir)/ruby/internal/attr/pure.h sha2init.o: $(hdrdir)/ruby/internal/attr/restrict.h sha2init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -276,7 +278,6 @@ sha2init.o: $(hdrdir)/ruby/internal/intern/enumerator.h sha2init.o: $(hdrdir)/ruby/internal/intern/error.h sha2init.o: $(hdrdir)/ruby/internal/intern/eval.h sha2init.o: $(hdrdir)/ruby/internal/intern/file.h -sha2init.o: $(hdrdir)/ruby/internal/intern/gc.h sha2init.o: $(hdrdir)/ruby/internal/intern/hash.h sha2init.o: $(hdrdir)/ruby/internal/intern/io.h sha2init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -293,6 +294,7 @@ sha2init.o: $(hdrdir)/ruby/internal/intern/re.h sha2init.o: $(hdrdir)/ruby/internal/intern/ruby.h sha2init.o: $(hdrdir)/ruby/internal/intern/select.h sha2init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha2init.o: $(hdrdir)/ruby/internal/intern/set.h sha2init.o: $(hdrdir)/ruby/internal/intern/signal.h sha2init.o: $(hdrdir)/ruby/internal/intern/sprintf.h sha2init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -307,12 +309,12 @@ sha2init.o: $(hdrdir)/ruby/internal/memory.h sha2init.o: $(hdrdir)/ruby/internal/method.h sha2init.o: $(hdrdir)/ruby/internal/module.h sha2init.o: $(hdrdir)/ruby/internal/newobj.h -sha2init.o: $(hdrdir)/ruby/internal/rgengc.h sha2init.o: $(hdrdir)/ruby/internal/scan_args.h sha2init.o: $(hdrdir)/ruby/internal/special_consts.h sha2init.o: $(hdrdir)/ruby/internal/static_assert.h sha2init.o: $(hdrdir)/ruby/internal/stdalign.h sha2init.o: $(hdrdir)/ruby/internal/stdbool.h +sha2init.o: $(hdrdir)/ruby/internal/stdckdint.h sha2init.o: $(hdrdir)/ruby/internal/symbol.h sha2init.o: $(hdrdir)/ruby/internal/value.h sha2init.o: $(hdrdir)/ruby/internal/value_type.h @@ -325,5 +327,6 @@ sha2init.o: $(hdrdir)/ruby/st.h sha2init.o: $(hdrdir)/ruby/subst.h sha2init.o: $(srcdir)/../digest.h sha2init.o: sha2.h +sha2init.o: sha2cc.h sha2init.o: sha2init.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index e7d7b15c5b..21d5acbe96 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -128,7 +128,7 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) -#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) || defined(_HPUX_SOURCE) || defined(__IBMC__) +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) || defined(__IBMC__) #define ULL(number) number##ULL #else #define ULL(number) (uint64_t)(number) diff --git a/ext/digest/sha2/sha2cc.h b/ext/digest/sha2/sha2cc.h index 3f99604465..1245a2e2c7 100644 --- a/ext/digest/sha2/sha2cc.h +++ b/ext/digest/sha2/sha2cc.h @@ -1,6 +1,33 @@ #define COMMON_DIGEST_FOR_OPENSSL 1 #include <CommonCrypto/CommonDigest.h> +/* + * Prior to 10.5, OpenSSL-compatible definitions are missing for + * SHA2 macros, though the CC_ versions are present. + * Add the missing definitions we actually use here if needed. + * Note that the definitions are the argless 10.6+-style. + * The weird CTX mismatch is copied from the 10.6 header. + */ +#ifndef SHA256_DIGEST_LENGTH +#define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH +#define SHA256_CTX CC_SHA256_CTX +#define SHA256_Update CC_SHA256_Update +#define SHA256_Final CC_SHA256_Final +#endif /* !defined SHA256_DIGEST_LENGTH */ + +#ifndef SHA384_DIGEST_LENGTH +#define SHA384_DIGEST_LENGTH CC_SHA384_DIGEST_LENGTH +#define SHA512_CTX CC_SHA512_CTX +#define SHA384_Update CC_SHA384_Update +#define SHA384_Final CC_SHA384_Final +#endif /* !defined SHA384_DIGEST_LENGTH */ + +#ifndef SHA512_DIGEST_LENGTH +#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH +#define SHA512_Update CC_SHA512_Update +#define SHA512_Final CC_SHA512_Final +#endif /* !defined SHA512_DIGEST_LENGTH */ + #define SHA256_BLOCK_LENGTH CC_SHA256_BLOCK_BYTES #define SHA384_BLOCK_LENGTH CC_SHA384_BLOCK_BYTES #define SHA512_BLOCK_LENGTH CC_SHA512_BLOCK_BYTES @@ -29,3 +56,15 @@ static DEFINE_FINISH_FUNC_FROM_FINAL(SHA512) #undef SHA512_Finish #define SHA512_Update rb_digest_SHA512_update #define SHA512_Finish rb_digest_SHA512_finish + +/* + * Pre-10.6 defines are with args, which don't match the argless use in + * the function pointer inits. Thus, we redefine SHA*_Init as well. + * This is a NOP on 10.6+. + */ +#undef SHA256_Init +#define SHA256_Init CC_SHA256_Init +#undef SHA384_Init +#define SHA384_Init CC_SHA384_Init +#undef SHA512_Init +#define SHA512_Init CC_SHA512_Init diff --git a/ext/digest/sha2/sha2init.c b/ext/digest/sha2/sha2init.c index 6ed275eb71..3923e3724c 100644 --- a/ext/digest/sha2/sha2init.c +++ b/ext/digest/sha2/sha2init.c @@ -25,29 +25,50 @@ static const rb_digest_metadata_t sha##bitlen = { \ FOREACH_BITLEN(DEFINE_ALGO_METADATA) /* + * Document-class: Digest::SHA256 < Digest::Base + * * Classes for calculating message digests using the SHA-256/384/512 * Secure Hash Algorithm(s) by NIST (the US' National Institute of * Standards and Technology), described in FIPS PUB 180-2. + * + * See SHA2. + */ +/* + * Document-class: Digest::SHA384 < Digest::Base + * + * Classes for calculating message digests using the SHA-256/384/512 + * Secure Hash Algorithm(s) by NIST (the US' National Institute of + * Standards and Technology), described in FIPS PUB 180-2. + * + * See SHA2. + */ +/* + * Document-class: Digest::SHA512 < Digest::Base + * + * Classes for calculating message digests using the SHA-256/384/512 + * Secure Hash Algorithm(s) by NIST (the US' National Institute of + * Standards and Technology), described in FIPS PUB 180-2. + * + * See SHA2. */ void Init_sha2(void) { - VALUE mDigest, cDigest_Base; + VALUE mDigest, cDigest_Base, cDigest_SHA2; ID id_metadata = rb_id_metadata(); -#define DECLARE_ALGO_CLASS(bitlen) \ - VALUE cDigest_SHA##bitlen; - - FOREACH_BITLEN(DECLARE_ALGO_CLASS) - +#if 0 + mDigest = rb_define_module("Digest"); /* let rdoc know */ +#endif mDigest = rb_digest_namespace(); - cDigest_Base = rb_path2class("Digest::Base"); + cDigest_Base = rb_const_get(mDigest, rb_intern_const("Base")); + + cDigest_SHA2 = rb_define_class_under(mDigest, "SHA256", cDigest_Base); + rb_ivar_set(cDigest_SHA2, id_metadata, rb_digest_make_metadata(&sha256)); -#define DEFINE_ALGO_CLASS(bitlen) \ - cDigest_SHA##bitlen = rb_define_class_under(mDigest, "SHA" #bitlen, cDigest_Base); \ -\ - rb_ivar_set(cDigest_SHA##bitlen, id_metadata, \ - rb_digest_make_metadata(&sha##bitlen)); + cDigest_SHA2 = rb_define_class_under(mDigest, "SHA384", cDigest_Base); + rb_ivar_set(cDigest_SHA2, id_metadata, rb_digest_make_metadata(&sha384)); - FOREACH_BITLEN(DEFINE_ALGO_CLASS) + cDigest_SHA2 = rb_define_class_under(mDigest, "SHA512", cDigest_Base); + rb_ivar_set(cDigest_SHA2, id_metadata, rb_digest_make_metadata(&sha512)); } diff --git a/ext/digest/test.sh b/ext/digest/test.sh deleted file mode 100644 index 328c7575e6..0000000000 --- a/ext/digest/test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# -# $RoughId: test.sh,v 1.5 2001/07/13 15:38:27 knu Exp $ -# $Id$ - -RUBY=${RUBY:=ruby} -MAKE=${MAKE:=make} -CFLAGS=${CFLAGS:=-Wall} - -${RUBY} extconf.rb --with-cflags="${CFLAGS}" -${MAKE} clean -${MAKE} - -for algo in md5 rmd160 sha1 sha2; do - args=--with-cflags="${CFLAGS}" - - if [ $WITH_BUNDLED_ENGINES ]; then - args="$args --with-bundled-$algo" - fi - - (cd $algo && - ${RUBY} extconf.rb $args; - ${MAKE} clean; - ${MAKE}) - ln -sf ../../$algo/$algo.so lib/digest/ -done - -${RUBY} -I. -I./lib ../../test/digest/test_digest.rb - -rm lib/digest/*.so diff --git a/ext/erb/escape/escape.c b/ext/erb/escape/escape.c new file mode 100644 index 0000000000..1794fc30eb --- /dev/null +++ b/ext/erb/escape/escape.c @@ -0,0 +1,114 @@ +#include "ruby.h" +#include "ruby/encoding.h" + +static VALUE rb_cERB, rb_mEscape, rb_cCGI; +static ID id_escapeHTML; + +#define HTML_ESCAPE_MAX_LEN 6 + +static const struct { + uint8_t len; + char str[HTML_ESCAPE_MAX_LEN+1]; +} html_escape_table[UCHAR_MAX+1] = { +#define HTML_ESCAPE(c, str) [c] = {rb_strlen_lit(str), str} + HTML_ESCAPE('\'', "'"), + HTML_ESCAPE('&', "&"), + HTML_ESCAPE('"', """), + HTML_ESCAPE('<', "<"), + HTML_ESCAPE('>', ">"), +#undef HTML_ESCAPE +}; + +static inline void +preserve_original_state(VALUE orig, VALUE dest) +{ + rb_enc_associate(dest, rb_enc_get(orig)); +} + +static inline long +escaped_length(VALUE str) +{ + const long len = RSTRING_LEN(str); + if (len >= LONG_MAX / HTML_ESCAPE_MAX_LEN) { + ruby_malloc_size_overflow(len, HTML_ESCAPE_MAX_LEN); + } + return len * HTML_ESCAPE_MAX_LEN; +} + +static VALUE +optimized_escape_html(VALUE str) +{ + VALUE vbuf; + char *buf = NULL; + const char *cstr = RSTRING_PTR(str); + const char *end = cstr + RSTRING_LEN(str); + + const char *segment_start = cstr; + char *dest = NULL; + while (cstr < end) { + const unsigned char c = *cstr++; + uint8_t len = html_escape_table[c].len; + if (len) { + size_t segment_len = cstr - segment_start - 1; + if (!buf) { + buf = ALLOCV_N(char, vbuf, escaped_length(str)); + dest = buf; + } + if (segment_len) { + memcpy(dest, segment_start, segment_len); + dest += segment_len; + } + segment_start = cstr; + memcpy(dest, html_escape_table[c].str, len); + dest += len; + } + } + VALUE escaped = str; + if (buf) { + size_t segment_len = cstr - segment_start; + if (segment_len) { + memcpy(dest, segment_start, segment_len); + dest += segment_len; + } + escaped = rb_str_new(buf, dest - buf); + preserve_original_state(str, escaped); + ALLOCV_END(vbuf); + } + return escaped; +} + +/* + * ERB::Util.html_escape is similar to CGI.escapeHTML but different in the following two parts: + * + * * ERB::Util.html_escape converts an argument with #to_s first (only if it's not T_STRING) + * * ERB::Util.html_escape does not allocate a new string when nothing needs to be escaped + */ +static VALUE +erb_escape_html(VALUE self, VALUE str) +{ + if (!RB_TYPE_P(str, T_STRING)) { + str = rb_convert_type(str, T_STRING, "String", "to_s"); + } + + if (rb_enc_str_asciicompat_p(str)) { + return optimized_escape_html(str); + } + else { + return rb_funcall(rb_cCGI, id_escapeHTML, 1, str); + } +} + +void +Init_escape(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + rb_cERB = rb_define_class("ERB", rb_cObject); + rb_mEscape = rb_define_module_under(rb_cERB, "Escape"); + rb_define_module_function(rb_mEscape, "html_escape", erb_escape_html, 1); + + rb_cCGI = rb_define_class("CGI", rb_cObject); + id_escapeHTML = rb_intern("escapeHTML"); +} diff --git a/ext/erb/escape/extconf.rb b/ext/erb/escape/extconf.rb new file mode 100644 index 0000000000..b211a9783f --- /dev/null +++ b/ext/erb/escape/extconf.rb @@ -0,0 +1,9 @@ +require 'mkmf' + +case RUBY_ENGINE +when 'jruby', 'truffleruby' + File.write('Makefile', dummy_makefile($srcdir).join) +else + have_func("rb_ext_ractor_safe", "ruby.h") + create_makefile 'erb/escape' +end diff --git a/ext/etc/.document b/ext/etc/.document new file mode 100644 index 0000000000..9bbea23b92 --- /dev/null +++ b/ext/etc/.document @@ -0,0 +1,2 @@ +etc.c +constdefs.h diff --git a/ext/etc/depend b/ext/etc/depend index 2ecd521ef9..77fe56a6bf 100644 --- a/ext/etc/depend +++ b/ext/etc/depend @@ -12,7 +12,6 @@ etc.o: $(hdrdir)/ruby/backward.h etc.o: $(hdrdir)/ruby/backward/2/assume.h etc.o: $(hdrdir)/ruby/backward/2/attributes.h etc.o: $(hdrdir)/ruby/backward/2/bool.h -etc.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h etc.o: $(hdrdir)/ruby/backward/2/inttypes.h etc.o: $(hdrdir)/ruby/backward/2/limits.h etc.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -21,6 +20,7 @@ etc.o: $(hdrdir)/ruby/backward/2/stdarg.h etc.o: $(hdrdir)/ruby/defines.h etc.o: $(hdrdir)/ruby/encoding.h etc.o: $(hdrdir)/ruby/intern.h +etc.o: $(hdrdir)/ruby/internal/abi.h etc.o: $(hdrdir)/ruby/internal/anyargs.h etc.o: $(hdrdir)/ruby/internal/arithmetic.h etc.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -58,6 +58,7 @@ etc.o: $(hdrdir)/ruby/internal/attr/noexcept.h etc.o: $(hdrdir)/ruby/internal/attr/noinline.h etc.o: $(hdrdir)/ruby/internal/attr/nonnull.h etc.o: $(hdrdir)/ruby/internal/attr/noreturn.h +etc.o: $(hdrdir)/ruby/internal/attr/packed_struct.h etc.o: $(hdrdir)/ruby/internal/attr/pure.h etc.o: $(hdrdir)/ruby/internal/attr/restrict.h etc.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -126,7 +127,6 @@ etc.o: $(hdrdir)/ruby/internal/intern/enumerator.h etc.o: $(hdrdir)/ruby/internal/intern/error.h etc.o: $(hdrdir)/ruby/internal/intern/eval.h etc.o: $(hdrdir)/ruby/internal/intern/file.h -etc.o: $(hdrdir)/ruby/internal/intern/gc.h etc.o: $(hdrdir)/ruby/internal/intern/hash.h etc.o: $(hdrdir)/ruby/internal/intern/io.h etc.o: $(hdrdir)/ruby/internal/intern/load.h @@ -143,6 +143,7 @@ etc.o: $(hdrdir)/ruby/internal/intern/re.h etc.o: $(hdrdir)/ruby/internal/intern/ruby.h etc.o: $(hdrdir)/ruby/internal/intern/select.h etc.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +etc.o: $(hdrdir)/ruby/internal/intern/set.h etc.o: $(hdrdir)/ruby/internal/intern/signal.h etc.o: $(hdrdir)/ruby/internal/intern/sprintf.h etc.o: $(hdrdir)/ruby/internal/intern/string.h @@ -157,12 +158,12 @@ etc.o: $(hdrdir)/ruby/internal/memory.h etc.o: $(hdrdir)/ruby/internal/method.h etc.o: $(hdrdir)/ruby/internal/module.h etc.o: $(hdrdir)/ruby/internal/newobj.h -etc.o: $(hdrdir)/ruby/internal/rgengc.h etc.o: $(hdrdir)/ruby/internal/scan_args.h etc.o: $(hdrdir)/ruby/internal/special_consts.h etc.o: $(hdrdir)/ruby/internal/static_assert.h etc.o: $(hdrdir)/ruby/internal/stdalign.h etc.o: $(hdrdir)/ruby/internal/stdbool.h +etc.o: $(hdrdir)/ruby/internal/stdckdint.h etc.o: $(hdrdir)/ruby/internal/symbol.h etc.o: $(hdrdir)/ruby/internal/value.h etc.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 737d295abc..8d50a96a62 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -47,12 +47,18 @@ static VALUE sGroup; #define HAVE_UNAME 1 #endif -#ifndef _WIN32 -char *getenv(); +#ifdef STDC_HEADERS +# include <stdlib.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif #endif -char *getlogin(); +RUBY_EXTERN char *getlogin(void); + +#define RUBY_ETC_VERSION "1.4.6" -#define RUBY_ETC_VERSION "1.3.0" +#define SYMBOL_LIT(str) ID2SYM(rb_intern_const(str "")) #ifdef HAVE_RB_DEPRECATE_CONSTANT void rb_deprecate_constant(VALUE mod, const char *name); @@ -62,6 +68,17 @@ void rb_deprecate_constant(VALUE mod, const char *name); #include "constdefs.h" +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + #ifdef HAVE_RUBY_ATOMIC_H # include "ruby/atomic.h" #else @@ -188,9 +205,10 @@ setup_passwd(struct passwd *pwd) #endif /* call-seq: - * getpwuid(uid) -> Passwd + * getpwuid(uid) -> Etc::Passwd * - * Returns the /etc/passwd information for the user with the given integer +uid+. + * Returns the <tt>/etc/passwd</tt> information for the user with the given + * integer +uid+. * * The information is returned as a Passwd struct. * @@ -199,7 +217,7 @@ setup_passwd(struct passwd *pwd) * * See the unix manpage for <code>getpwuid(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getpwuid(0) * #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> @@ -227,16 +245,16 @@ etc_getpwuid(int argc, VALUE *argv, VALUE obj) } /* call-seq: - * getpwnam(name) -> Passwd + * getpwnam(name) -> Etc::Passwd * - * Returns the /etc/passwd information for the user with specified login - * +name+. + * Returns the <tt>/etc/passwd</tt> information for the user with specified + * login +name+. * * The information is returned as a Passwd struct. * * See the unix manpage for <code>getpwnam(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getpwnam('root') * #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> @@ -291,17 +309,17 @@ each_passwd(void) #endif /* call-seq: - * Etc.passwd { |struct| block } -> Passwd - * Etc.passwd -> Passwd + * passwd { |struct| block } + * passwd -> Etc::Passwd * * Provides a convenient Ruby iterator which executes a block for each entry - * in the /etc/passwd file. + * in the <tt>/etc/passwd</tt> file. * * The code block is passed an Passwd struct. * * See ::getpwent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -327,18 +345,19 @@ etc_passwd(VALUE obj) } /* call-seq: - * Etc::Passwd.each { |struct| block } -> Passwd + * Etc::Passwd.each { |struct| block } -> Etc::Passwd * Etc::Passwd.each -> Enumerator * - * Iterates for each entry in the /etc/passwd file if a block is given. + * Iterates for each entry in the <tt>/etc/passwd</tt> file if a block is + * given. * * If no block is given, returns the Enumerator. * * The code block is passed an Passwd struct. * - * See ::getpwent above for details. + * See Etc.getpwent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -360,8 +379,11 @@ etc_each_passwd(VALUE obj) return obj; } -/* Resets the process of reading the /etc/passwd file, so that the next call - * to ::getpwent will return the first entry again. +/* call-seq: + * setpwent + * + * Resets the process of reading the <tt>/etc/passwd</tt> file, so that the + * next call to ::getpwent will return the first entry again. */ static VALUE etc_setpwent(VALUE obj) @@ -372,8 +394,11 @@ etc_setpwent(VALUE obj) return Qnil; } -/* Ends the process of scanning through the /etc/passwd file begun with - * ::getpwent, and closes the file. +/* call-seq: + * endpwent + * + * Ends the process of scanning through the <tt>/etc/passwd</tt> file begun + * with ::getpwent, and closes the file. */ static VALUE etc_endpwent(VALUE obj) @@ -384,7 +409,10 @@ etc_endpwent(VALUE obj) return Qnil; } -/* Returns an entry from the /etc/passwd file. +/* call-seq: + * getpwent -> Etc::Passwd + * + * Returns an entry from the <tt>/etc/passwd</tt> file. * * The first time it is called it opens the file and returns the first entry; * each successive call returns the next entry, or +nil+ if the end of the file @@ -432,16 +460,16 @@ setup_group(struct group *grp) #endif /* call-seq: - * getgrgid(group_id) -> Group + * getgrgid(group_id) -> Etc::Group * * Returns information about the group with specified integer +group_id+, - * as found in /etc/group. + * as found in <tt>/etc/group</tt>. * * The information is returned as a Group struct. * * See the unix manpage for <code>getgrgid(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getgrgid(100) * #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]> @@ -470,16 +498,16 @@ etc_getgrgid(int argc, VALUE *argv, VALUE obj) } /* call-seq: - * getgrnam(name) -> Group + * getgrnam(name) -> Etc::Group * * Returns information about the group with specified +name+, as found in - * /etc/group. + * <tt>/etc/group</tt>. * * The information is returned as a Group struct. * * See the unix manpage for <code>getgrnam(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getgrnam('users') * #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]> @@ -512,7 +540,6 @@ group_ensure(VALUE _) return Qnil; } - static VALUE group_iterate(VALUE _) { @@ -535,14 +562,18 @@ each_group(void) } #endif -/* Provides a convenient Ruby iterator which executes a block for each entry - * in the /etc/group file. +/* call-seq: + * group { |struct| block } + * group -> Etc::Group + * + * Provides a convenient Ruby iterator which executes a block for each entry + * in the <tt>/etc/group</tt> file. * * The code block is passed an Group struct. * * See ::getgrent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -569,16 +600,17 @@ etc_group(VALUE obj) #ifdef HAVE_GETGRENT /* call-seq: - * Etc::Group.each { |group| block } -> obj + * Etc::Group.each { |group| block } -> Etc::Group * Etc::Group.each -> Enumerator * - * Iterates for each entry in the /etc/group file if a block is given. + * Iterates for each entry in the <tt>/etc/group</tt> file if a block is + * given. * * If no block is given, returns the Enumerator. * * The code block is passed a Group struct. * - * Example: + * *Example:* * * require 'etc' * @@ -599,8 +631,11 @@ etc_each_group(VALUE obj) } #endif -/* Resets the process of reading the /etc/group file, so that the next call - * to ::getgrent will return the first entry again. +/* call-seq: + * setgrent + * + * Resets the process of reading the <tt>/etc/group</tt> file, so that the + * next call to ::getgrent will return the first entry again. */ static VALUE etc_setgrent(VALUE obj) @@ -611,8 +646,11 @@ etc_setgrent(VALUE obj) return Qnil; } -/* Ends the process of scanning through the /etc/group file begun by - * ::getgrent, and closes the file. +/* call-seq: + * endgrent + * + * Ends the process of scanning through the <tt>/etc/group</tt> file begun + * by ::getgrent, and closes the file. */ static VALUE etc_endgrent(VALUE obj) @@ -623,7 +661,10 @@ etc_endgrent(VALUE obj) return Qnil; } -/* Returns an entry from the /etc/group file. +/* call-seq: + * getgrent -> Etc::Group + * + * Returns an entry from the <tt>/etc/group</tt> file. * * The first time it is called it opens the file and returns the first entry; * each successive call returns the next entry, or +nil+ if the end of the file @@ -652,14 +693,28 @@ etc_getgrent(VALUE obj) VALUE rb_w32_special_folder(int type); UINT rb_w32_system_tmpdir(WCHAR *path, UINT len); VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc); +#elif defined(LOAD_RELATIVE) +static inline VALUE +rbconfig(void) +{ + VALUE config; + rb_require("rbconfig"); + config = rb_const_get(rb_path2class("RbConfig"), rb_intern_const("CONFIG")); + Check_Type(config, T_HASH); + return config; +} #endif -/* +/* call-seq: + * sysconfdir -> String + * * Returns system configuration directory. * - * This is typically "/etc", but is modified by the prefix used when Ruby was - * compiled. For example, if Ruby is built and installed in /usr/local, - * returns "/usr/local/etc" on other platforms than Windows. + * This is typically <code>"/etc"</code>, but is modified by the prefix used + * when Ruby was compiled. For example, if Ruby is built and installed in + * <tt>/usr/local</tt>, returns <code>"/usr/local/etc"</code> on other + * platforms than Windows. + * * On Windows, this always returns the directory provided by the system. */ static VALUE @@ -667,12 +722,16 @@ etc_sysconfdir(VALUE obj) { #ifdef _WIN32 return rb_w32_special_folder(CSIDL_COMMON_APPDATA); +#elif defined(LOAD_RELATIVE) + return rb_hash_aref(rbconfig(), rb_str_new_lit("sysconfdir")); #else return rb_filesystem_str_new_cstr(SYSCONFDIR); #endif } -/* +/* call-seq: + * systmpdir -> String + * * Returns system temporary directory; typically "/tmp". */ static VALUE @@ -716,13 +775,15 @@ etc_systmpdir(VALUE _) } #ifdef HAVE_UNAME -/* +/* call-seq: + * uname -> hash + * * Returns the system information obtained by uname system call. * * The return value is a hash which has 5 keys at least: * :sysname, :nodename, :release, :version, :machine * - * Example: + * *Example:* * * require 'etc' * require 'pp' @@ -764,18 +825,14 @@ etc_uname(VALUE obj) sysname = "Windows"; break; } - rb_hash_aset(result, ID2SYM(rb_intern("sysname")), rb_str_new_cstr(sysname)); + rb_hash_aset(result, SYMBOL_LIT("sysname"), rb_str_new_cstr(sysname)); release = rb_sprintf("%lu.%lu.%lu", v.dwMajorVersion, v.dwMinorVersion, v.dwBuildNumber); - rb_hash_aset(result, ID2SYM(rb_intern("release")), release); + rb_hash_aset(result, SYMBOL_LIT("release"), release); version = rb_sprintf("%s Version %"PRIsVALUE": %"PRIsVALUE, sysname, release, rb_w32_conv_from_wchar(v.szCSDVersion, rb_utf8_encoding())); - rb_hash_aset(result, ID2SYM(rb_intern("version")), version); + rb_hash_aset(result, SYMBOL_LIT("version"), version); -# if defined _MSC_VER && _MSC_VER < 1300 -# define GET_COMPUTER_NAME(ptr, plen) GetComputerNameW(ptr, plen) -# else # define GET_COMPUTER_NAME(ptr, plen) GetComputerNameExW(ComputerNameDnsFullyQualified, ptr, plen) -# endif GET_COMPUTER_NAME(NULL, &len); buf = ALLOCV_N(WCHAR, vbuf, len); if (GET_COMPUTER_NAME(buf, &len)) { @@ -783,7 +840,7 @@ etc_uname(VALUE obj) } ALLOCV_END(vbuf); if (NIL_P(nodename)) nodename = rb_str_new(0, 0); - rb_hash_aset(result, ID2SYM(rb_intern("nodename")), nodename); + rb_hash_aset(result, SYMBOL_LIT("nodename"), nodename); # ifndef PROCESSOR_ARCHITECTURE_AMD64 # define PROCESSOR_ARCHITECTURE_AMD64 9 @@ -807,7 +864,7 @@ etc_uname(VALUE obj) break; } - rb_hash_aset(result, ID2SYM(rb_intern("machine")), rb_str_new_cstr(mach)); + rb_hash_aset(result, SYMBOL_LIT("machine"), rb_str_new_cstr(mach)); #else struct utsname u; int ret; @@ -818,11 +875,11 @@ etc_uname(VALUE obj) rb_sys_fail("uname"); result = rb_hash_new(); - rb_hash_aset(result, ID2SYM(rb_intern("sysname")), rb_str_new_cstr(u.sysname)); - rb_hash_aset(result, ID2SYM(rb_intern("nodename")), rb_str_new_cstr(u.nodename)); - rb_hash_aset(result, ID2SYM(rb_intern("release")), rb_str_new_cstr(u.release)); - rb_hash_aset(result, ID2SYM(rb_intern("version")), rb_str_new_cstr(u.version)); - rb_hash_aset(result, ID2SYM(rb_intern("machine")), rb_str_new_cstr(u.machine)); + rb_hash_aset(result, SYMBOL_LIT("sysname"), rb_str_new_cstr(u.sysname)); + rb_hash_aset(result, SYMBOL_LIT("nodename"), rb_str_new_cstr(u.nodename)); + rb_hash_aset(result, SYMBOL_LIT("release"), rb_str_new_cstr(u.release)); + rb_hash_aset(result, SYMBOL_LIT("version"), rb_str_new_cstr(u.version)); + rb_hash_aset(result, SYMBOL_LIT("machine"), rb_str_new_cstr(u.machine)); #endif return result; @@ -832,7 +889,9 @@ etc_uname(VALUE obj) #endif #ifdef HAVE_SYSCONF -/* +/* call-seq: + * sysconf(name) -> Integer + * * Returns system configuration variable using sysconf(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>SC_</code>. @@ -866,7 +925,9 @@ etc_sysconf(VALUE obj, VALUE arg) #endif #ifdef HAVE_CONFSTR -/* +/* call-seq: + * confstr(name) -> String + * * Returns system configuration variable using confstr(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>CS_</code>. @@ -913,7 +974,9 @@ etc_confstr(VALUE obj, VALUE arg) #endif #ifdef HAVE_FPATHCONF -/* +/* call-seq: + * pathconf(name) -> Integer + * * Returns pathname configuration variable using fpathconf(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>PC_</code>. @@ -932,14 +995,11 @@ io_pathconf(VALUE io, VALUE arg) { int name; long ret; - rb_io_t *fptr; name = NUM2INT(arg); - GetOpenFile(io, fptr); - errno = 0; - ret = fpathconf(fptr->fd, name); + ret = fpathconf(rb_io_descriptor(io), name); if (ret == -1) { if (errno == 0) /* no limit */ return Qnil; @@ -1008,7 +1068,9 @@ etc_nprocessors_affin(void) } #endif -/* +/* call-seq: + * nprocessors -> Integer + * * Returns the number of online processors. * * The result is intended as the number of processes to @@ -1018,7 +1080,7 @@ etc_nprocessors_affin(void) * - sched_getaffinity(): Linux * - sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, DragonFly BSD, OpenIndiana, Mac OS X, AIX * - * Example: + * *Example:* * * require 'etc' * p Etc.nprocessors #=> 4 @@ -1027,7 +1089,7 @@ etc_nprocessors_affin(void) * process is bound to specific cpus. This is intended for getting better * parallel processing. * - * Example: (Linux) + * *Example:* (Linux) * * linux$ taskset 0x3 ./ruby -retc -e "p Etc.nprocessors" #=> 2 * @@ -1067,16 +1129,17 @@ etc_nprocessors(VALUE obj) /* * The Etc module provides access to information typically stored in - * files in the /etc directory on Unix systems. + * files in the <tt>/etc</tt> directory on Unix systems. * * The information accessible consists of the information found in the - * /etc/passwd and /etc/group files, plus information about the system's - * temporary directory (/tmp) and configuration directory (/etc). + * <tt>/etc/passwd</tt> and <tt>/etc/group</tt> files, plus information + * about the system's temporary directory (<tt>/tmp</tt>) and configuration + * directory (<tt>/etc</tt>). * * The Etc module provides a more reliable way to access information about * the logged in user than environment variables such as +$USER+. * - * == Example: + * *Example:* * * require 'etc' * @@ -1096,13 +1159,26 @@ Init_etc(void) { VALUE mEtc; - #ifdef HAVE_RB_EXT_RACTOR_SAFE - RB_EXT_RACTOR_SAFE(true); - #endif mEtc = rb_define_module("Etc"); + /* The version */ rb_define_const(mEtc, "VERSION", rb_str_new_cstr(RUBY_ETC_VERSION)); init_constants(mEtc); + /* Ractor-safe methods */ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); +#endif + rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0); + rb_define_module_function(mEtc, "uname", etc_uname, 0); + rb_define_module_function(mEtc, "sysconf", etc_sysconf, 1); + rb_define_module_function(mEtc, "confstr", etc_confstr, 1); + rb_define_method(rb_cIO, "pathconf", io_pathconf, 1); + rb_define_module_function(mEtc, "nprocessors", etc_nprocessors, 0); + + /* Non-Ractor-safe methods, see https://bugs.ruby-lang.org/issues/21115 */ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(false); +#endif rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0); rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1); @@ -1118,13 +1194,9 @@ Init_etc(void) rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0); rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0); rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0); + + /* Uses RbConfig::CONFIG so does not work in a Ractor */ rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0); - rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0); - rb_define_module_function(mEtc, "uname", etc_uname, 0); - rb_define_module_function(mEtc, "sysconf", etc_sysconf, 1); - rb_define_module_function(mEtc, "confstr", etc_confstr, 1); - rb_define_method(rb_cIO, "pathconf", io_pathconf, 1); - rb_define_module_function(mEtc, "nprocessors", etc_nprocessors, 0); sPasswd = rb_struct_define_under(mEtc, "Passwd", "name", @@ -1158,16 +1230,18 @@ Init_etc(void) #endif NULL); #if 0 - /* Define-const: Passwd + /* + * Passwd is a placeholder Struct for user database on Unix systems. * - * Passwd is a Struct that contains the following members: + * === The struct contains the following members * * name:: * contains the short login name of the user as a String. * passwd:: * contains the encrypted password of the user as a String. - * an 'x' is returned if shadow passwords are in use. An '*' is returned - * if the user cannot log in using a password. + * an <code>'x'</code> is returned if shadow passwords are in + * use. An <code>'*'</code> is returned if the user cannot + * log in using a password. * uid:: * contains the integer user ID (uid) of the user. * gid:: @@ -1177,32 +1251,30 @@ Init_etc(void) * shell:: * contains the path to the login shell of the user as a String. * - * === The following members below are optional, and must be compiled with special flags: + * === The following members below are system-dependent * * gecos:: * contains a longer String description of the user, such as * a full name. Some Unix systems provide structured information in the * gecos field, but this is system-dependent. - * must be compiled with +HAVE_STRUCT_PASSWD_PW_GECOS+ * change:: - * password change time(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_CHANGE+ + * password change time(integer). * quota:: - * quota value(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_QUOTA+ + * quota value(integer). * age:: - * password age(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_AGE+ + * password age(integer). * class:: - * user access class(string) must be compiled with +HAVE_STRUCT_PASSWD_PW_CLASS+ + * user access class(string). * comment:: - * comment(string) must be compiled with +HAVE_STRUCT_PASSWD_PW_COMMENT+ + * comment(string). * expire:: - * account expiration time(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_EXPIRE+ + * account expiration time(integer). */ - rb_define_const(mEtc, "Passwd", sPasswd); + sPasswd = rb_define_class_under(mEtc, "Passwd", rb_cStruct); #endif - rb_define_const(rb_cStruct, "Passwd", sPasswd); /* deprecated name */ - rb_deprecate_constant(rb_cStruct, "Passwd"); rb_extend_object(sPasswd, rb_mEnumerable); rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0); + #ifdef HAVE_GETGRENT sGroup = rb_struct_define_under(mEtc, "Group", "name", #ifdef HAVE_STRUCT_GROUP_GR_PASSWD @@ -1211,32 +1283,32 @@ Init_etc(void) "gid", "mem", NULL); #if 0 - /* Define-const: Group - * - * Group is a Struct that is only available when compiled with +HAVE_GETGRENT+. + /* + * Group is a placeholder Struct for user group database on Unix systems. * - * The struct contains the following members: + * === The struct contains the following members * * name:: * contains the name of the group as a String. * passwd:: - * contains the encrypted password as a String. An 'x' is + * contains the encrypted password as a String. An <code>'x'</code> is * returned if password access to the group is not available; an empty * string is returned if no password is needed to obtain membership of * the group. - * - * Must be compiled with +HAVE_STRUCT_GROUP_GR_PASSWD+. + * This is system-dependent. * gid:: * contains the group's numeric ID as an integer. * mem:: * is an Array of Strings containing the short login names of the * members of the group. */ - rb_define_const(mEtc, "Group", sGroup); + sGroup = rb_define_class_under(mEtc, "Group", rb_cStruct); #endif - rb_define_const(rb_cStruct, "Group", sGroup); /* deprecated name */ - rb_deprecate_constant(rb_cStruct, "Group"); rb_extend_object(sGroup, rb_mEnumerable); rb_define_singleton_method(sGroup, "each", etc_each_group, 0); #endif + +#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT) + (void)safe_setup_str; +#endif } diff --git a/ext/etc/etc.gemspec b/ext/etc/etc.gemspec index 7d687e3b99..0e9803dc62 100644 --- a/ext/etc/etc.gemspec +++ b/ext/etc/etc.gemspec @@ -22,23 +22,23 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/ruby/etc" spec.licenses = ["Ruby", "BSD-2-Clause"] + changelogs = Dir.glob("logs/ChangeLog-[1-9]*[^~]", base: __dir__) spec.files = %w[ - LICENSE.txt + BSDL + COPYING README.md + ChangeLog ext/etc/constdefs.h ext/etc/etc.c ext/etc/extconf.rb ext/etc/mkconstants.rb test/etc/test_etc.rb - ] + ] + changelogs + spec.rdoc_options = ["--main", "README.md"] + spec.extra_rdoc_files = spec.files.grep_v(/\.{rb,[ch]}\z/) spec.bindir = "exe" spec.require_paths = ["lib"] spec.extensions = %w{ext/etc/extconf.rb} - spec.required_ruby_version = ">= 2.3.0" - - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake" - spec.add_development_dependency "rake-compiler" - spec.add_development_dependency "test-unit" + spec.required_ruby_version = ">= 2.7.0" end diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb index 6e7810a5e8..497303a4fa 100644 --- a/ext/etc/extconf.rb +++ b/ext/etc/extconf.rb @@ -10,8 +10,30 @@ headers = [] have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4 have_func("uname((struct utsname *)NULL)", headers) have_func("getlogin") -have_func("getpwent") -have_func("getgrent") +if have_func("getpwent") + have_struct_member('struct passwd', 'pw_gecos', 'pwd.h') + have_struct_member('struct passwd', 'pw_change', 'pwd.h') + have_struct_member('struct passwd', 'pw_quota', 'pwd.h') + if have_struct_member('struct passwd', 'pw_age', 'pwd.h') + case what_type?('struct passwd', 'pw_age', 'pwd.h') + when "string" + f = "safe_setup_str" + when "long long" + f = "LL2NUM" + else + f = "INT2NUM" + end + $defs.push("-DPW_AGE2VAL="+f) + end + have_struct_member('struct passwd', 'pw_class', 'pwd.h') + have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM + have_struct_member('struct passwd', 'pw_expire', 'pwd.h') + have_struct_member('struct passwd', 'pw_passwd', 'pwd.h') +end +if have_func("getgrent") + have_struct_member('struct group', 'gr_passwd', 'grp.h') +end + if (sysconfdir = RbConfig::CONFIG["sysconfdir"] and !RbConfig.expand(sysconfdir.dup, "prefix"=>"", "DESTDIR"=>"").empty?) $defs.push("-DSYSCONFDIR=#{Shellwords.escape(sysconfdir.dump)}") @@ -21,34 +43,25 @@ have_func("sysconf") have_func("confstr") have_func("fpathconf") -have_struct_member('struct passwd', 'pw_gecos', 'pwd.h') -have_struct_member('struct passwd', 'pw_change', 'pwd.h') -have_struct_member('struct passwd', 'pw_quota', 'pwd.h') -if have_struct_member('struct passwd', 'pw_age', 'pwd.h') - case what_type?('struct passwd', 'pw_age', 'pwd.h') - when "string" - f = "safe_setup_str" - when "long long" - f = "LL2NUM" - else - f = "INT2NUM" - end - $defs.push("-DPW_AGE2VAL="+f) -end -have_struct_member('struct passwd', 'pw_class', 'pwd.h') -have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM -have_struct_member('struct passwd', 'pw_expire', 'pwd.h') -have_struct_member('struct passwd', 'pw_passwd', 'pwd.h') -have_struct_member('struct group', 'gr_passwd', 'grp.h') - # for https://github.com/ruby/etc srcdir = File.expand_path("..", __FILE__) -if !File.exist?("#{srcdir}/depend") - %x[#{RbConfig.ruby} #{srcdir}/mkconstants.rb -o #{srcdir}/constdefs.h] +constdefs = "#{srcdir}/constdefs.h" +if !File.exist?(constdefs) + ruby = RbConfig.ruby + if File.file?(ruby) + ruby = [ruby] + else + require "shellwords" + ruby = Shellwords.split(ruby) + end + system(*ruby, "#{srcdir}/mkconstants.rb", "-o", constdefs) end +# TODO: remove when dropping 2.7 support, as exported since 3.0 have_func('rb_deprecate_constant(Qnil, "None")') +have_func("rb_io_descriptor", "ruby/io.h") + $distcleanfiles << "constdefs.h" create_makefile("etc") diff --git a/ext/etc/mkconstants.rb b/ext/etc/mkconstants.rb index a752d64519..a766560a8a 100644 --- a/ext/etc/mkconstants.rb +++ b/ext/etc/mkconstants.rb @@ -35,6 +35,12 @@ opt.def_option('-H FILE', 'specify output header file') {|filename| opt.parse! +CONST_PREFIXES = { + 'SC' => 'for Etc.sysconf; See <tt>man sysconf</tt>', + 'CS' => 'for Etc.confstr; See <tt>man constr</tt>', + 'PC' => 'for IO#pathconf; See <tt>man fpathconf</tt>', +} + h = {} COMMENTS = {} @@ -49,6 +55,13 @@ DATA.each_line {|s| next end h[name] = default_value + if additional = CONST_PREFIXES[name[/\A_([A-Z]+)_/, 1]] + if comment&.match(/\w\z/) + comment << " " << additional + else + (comment ||= String.new) << " " << additional.sub(/\A\w/) {$&.upcase} + end + end COMMENTS[name] = comment if comment } DEFS = h.to_a @@ -66,15 +79,11 @@ def each_name(pat) } end -erb_new = lambda do |src, safe, trim| - if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - ERB.new(src, trim_mode: trim) - else - ERB.new(src, safe, trim) - end +erb_new = lambda do |src, trim| + ERB.new(src, trim_mode: trim) end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_decls") % each_const {|name, default_value| #if !defined(<%=name%>) # if defined(HAVE_CONST_<%=name.upcase%>) @@ -88,7 +97,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs") % each_const {|name, default_value| #if defined(<%=name%>) % if comment = COMMENTS[name] @@ -99,13 +108,13 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") % } EOS -header_result = erb_new.call(<<'EOS', nil, '%').result(binding) +header_result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= gen_const_decls %> EOS -result = erb_new.call(<<'EOS', nil, '%').result(binding) +result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ #ifdef HAVE_LONG_LONG @@ -123,6 +132,9 @@ result = erb_new.call(<<'EOS', nil, '%').result(binding) static void init_constants(VALUE mod) { +#if 0 + mod = rb_define_module("Etc"); +#endif <%= gen_const_defs %> } EOS diff --git a/ext/extmk.rb b/ext/extmk.rb index 4a087f294a..578e1cfa01 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -2,6 +2,15 @@ # -*- mode: ruby; coding: us-ascii -*- # frozen_string_literal: false +module Gem + # Used by Gem::Platform.local + def self.target_rbconfig + RbConfig::CONFIG + end +end +# only needs Gem::Platform +require 'rubygems/platform' + # :stopdoc: $extension = nil $extstatic = nil @@ -34,16 +43,14 @@ require 'rbconfig' $topdir = "." $top_srcdir = srcdir +$extmk = true +inplace = File.identical?($top_srcdir, $topdir) $" << "mkmf.rb" load File.expand_path("lib/mkmf.rb", srcdir) require 'optparse/shellwords' -if defined?(File::NULL) - @null = File::NULL -elsif !File.chardev?(@null = "/dev/null") - @null = "nul" -end +@null = File::NULL def verbose? $mflags.defined?("V") == "1" @@ -62,12 +69,17 @@ end def atomic_write_open(filename) filename_new = filename + ".new.#$$" - open(filename_new, "wb") do |f| + clean = false + File.open(filename_new, "wbx") do |f| + clean = true yield f end if File.binread(filename_new) != (File.binread(filename) rescue nil) File.rename(filename_new, filename) - else + clean = false + end +ensure + if clean File.unlink(filename_new) end end @@ -99,7 +111,7 @@ def extract_makefile(makefile, keep = true) end return false end - srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")].map {|fn| File.basename(fn)}.sort + srcs = Dir[*SRC_EXT.map {|e| "*.#{e}"}, base: $srcdir].map {|fn| File.basename(fn)}.sort if !srcs.empty? old_srcs = m[/^ORIG_SRCS[ \t]*=[ \t](.*)/, 1] or return false (old_srcs.split - srcs).empty? or return false @@ -135,7 +147,7 @@ def extmake(target, basedir = 'ext', maybestatic = true) d = target until (d = File.dirname(d)) == '.' if File.exist?("#{$top_srcdir}/#{basedir}/#{d}/extconf.rb") - parent = (/^all:\s*install/ =~ IO.read("#{d}/Makefile") rescue false) + parent = (/^all:\s*install/ =~ File.read("#{d}/Makefile") rescue false) break end end @@ -146,7 +158,7 @@ def extmake(target, basedir = 'ext', maybestatic = true) top_srcdir = $top_srcdir topdir = $topdir hdrdir = $hdrdir - prefix = "../" * (target.count("/")+1) + prefix = "../" * (basedir.count("/")+target.count("/")+1) $top_srcdir = relative_from(top_srcdir, prefix) $hdrdir = relative_from(hdrdir, prefix) $topdir = prefix + $topdir @@ -154,8 +166,6 @@ def extmake(target, basedir = 'ext', maybestatic = true) $mdir = target $srcdir = File.join($top_srcdir, basedir, $mdir) $preload = nil - $objs = [] - $srcs = [] $extso = [] makefile = "./Makefile" static = $static @@ -189,7 +199,7 @@ def extmake(target, basedir = 'ext', maybestatic = true) begin $extconf_h = nil ok &&= extract_makefile(makefile) - old_objs = $objs + old_objs = $objs || [] old_cleanfiles = $distcleanfiles | $cleanfiles conf = ["#{$srcdir}/makefile.rb", "#{$srcdir}/extconf.rb"].find {|f| File.exist?(f)} if (!ok || ($extconf_h && !File.exist?($extconf_h)) || @@ -252,6 +262,8 @@ def extmake(target, basedir = 'ext', maybestatic = true) unless $destdir.to_s.empty? or $mflags.defined?("DESTDIR") args += ["DESTDIR=" + relative_from($destdir, "../"+prefix)] end + $objs ||= [] + $srcs ||= [] if $static and ok and !$objs.empty? and !noinstall args += ["static"] $extlist.push [(maybestatic ? $static : false), target, $target, $preload] @@ -408,8 +420,10 @@ if CROSS_COMPILING $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY'] elsif sep = config_string('BUILD_FILE_SEPARATOR') $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT -else +elsif CONFIG['EXTSTATIC'] $ruby = '$(topdir)/miniruby' + EXEEXT +else + $ruby = '$(topdir)/ruby' + EXEEXT end $ruby = [$ruby] $ruby << "-I'$(topdir)'" @@ -421,6 +435,7 @@ end topruby = $ruby $ruby = topruby.join(' ') $mflags << "ruby=#$ruby" +$builtruby = '$(topdir)/miniruby' + EXEEXT # Must be an executable path MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)} @@ -435,9 +450,8 @@ if $extstatic end for dir in ["ext", File::join($top_srcdir, "ext")] setup = File::join(dir, CONFIG['setup']) - if File.file? setup - f = open(setup) - while line = f.gets() + if (f = File.stat(setup) and f.file? rescue next) + File.foreach(setup) do |line| line.chomp! line.sub!(/#.*$/, '') next if /^\s*$/ =~ line @@ -454,23 +468,24 @@ for dir in ["ext", File::join($top_srcdir, "ext")] end MTIMES << f.mtime $setup = setup - f.close break end end unless $extstatic @gemname = nil -if ARGV[0] - ext_prefix, exts = ARGV.shift.split('/', 2) +if exts = ARGV.shift + ext_prefix = exts[%r[\A(?>\.bundle/)?[^/]+(?:/(?=(.+)?)|\z)]] + exts = $1 $extension = [exts] if exts - if ext_prefix == 'gems' + if ext_prefix.start_with?('.') @gemname = exts - elsif exts - $static_ext.delete_if {|t, *| !File.fnmatch(t, exts)} + exts = [] + else + exts &&= $static_ext.select {|t, *| File.fnmatch(t, exts)} end end -ext_prefix = "#{$top_srcdir}/#{ext_prefix || 'ext'}" -exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t} +ext_prefix ||= 'ext' +exts = (exts || $static_ext).sort_by {|t, i| i}.collect {|t, i| t} default_exclude_exts = case when $cygwin @@ -483,28 +498,30 @@ default_exclude_exts = mandatory_exts = {} withes, withouts = [["--with", nil], ["--without", default_exclude_exts]].collect {|w, d| if !(w = %w[-extensions -ext].collect {|o|arg_config(w+o)}).any? - d ? proc {|c1| d.any?(&c1)} : proc {true} + d ? proc {|&c1| d.any?(&c1)} : proc {true} elsif (w = w.grep(String)).empty? proc {true} else w = w.collect {|o| o.split(/,/)}.flatten w.collect! {|o| o == '+' ? d : o}.flatten! - proc {|c1| w.any?(&c1)} + proc {|&c1| w.any?(&c1)} end } cond = proc {|ext, *| - withes.call(proc {|n| - !n or (mandatory_exts[ext] = true if File.fnmatch(n, ext)) - }) and - !withouts.call(proc {|n| File.fnmatch(n, ext)}) + withes.call {|n| !n or (mandatory_exts[ext] = true if File.fnmatch(n, ext))} and + !withouts.call {|n| File.fnmatch(n, ext)} } ($extension || %w[*]).each do |e| e = e.sub(/\A(?:\.\/)+/, '') - incl, excl = Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d| - d = File.dirname(d) - d.slice!(0, ext_prefix.length + 1) - d + incl, excl = Dir.glob("#{e}/**/extconf.rb", base: "#$top_srcdir/#{ext_prefix}").collect {|d| + File.dirname(d) }.partition {|ext| + if @gemname + ext = ext[%r[\A[^/]+]] # extract gem name + Dir.glob("*.gemspec", base: "#$top_srcdir/#{ext_prefix}/#{ext}") do |g| + break ext = g if ext.start_with?("#{g.chomp!(".gemspec")}-") + end + end with_config(ext, &cond) } incl.sort! @@ -515,14 +532,22 @@ cond = proc {|ext, *| exts.delete_if {|d| File.fnmatch?("-*", d)} end end -ext_prefix = File.basename(ext_prefix) +ext_prefix.chomp!("/") +@ext_prefix = ext_prefix +@inplace = inplace extend Module.new { + def timestamp_file(name, target_prefix = nil) if @gemname and name == '$(TARGET_SO_DIR)' - name = "$(arch)/gems/#{@gemname}#{target_prefix}" + gem = true + name = "$(gem_platform)/$(ruby_version)/gems/#{@gemname}#{target_prefix}" end - super.sub(%r[/\.extout\.(?:-\.)?], '/.') + path = super.sub(%r[/\.extout\.(?:-\.)?], '/.') + if gem + nil while path.sub!(%r[/\.(gem_platform|ruby_version)\.-(?=\.)], '/$(\1)/') + end + path end def configuration(srcdir) @@ -530,28 +555,86 @@ extend Module.new { end def create_makefile(*args, &block) - return super unless @gemname + unless @gemname + if $static and (target = args.first).include?("/") + base = File.basename(target) + $defs << "-DInit_#{base}=Init_#{target.tr('/', '_')}" + $defs << "-DInitVM_#{base}=InitVM_#{target.tr('/', '_')}" + end + return super + end super(*args) do |conf| conf.find do |s| + s.sub!(%r(^(srcdir *= *)\$\(top_srcdir\)/\.bundle/gems/[^/]+(?=/))) { + "gem_#{$&}\n" "#{$1}$(gem_srcdir)" + } + s.sub!(/^(TIMESTAMP_DIR *= *)\$\(extout\)/) { + "TARGET_TOPDIR = $(topdir)/.bundle\n" "#{$1}$(TARGET_TOPDIR)" + } s.sub!(/^(TARGET_SO_DIR *= *)\$\(RUBYARCHDIR\)/) { - "TARGET_GEM_DIR = $(extout)/gems/$(arch)/#{@gemname}\n"\ + "TARGET_GEM_DIR = $(TARGET_TOPDIR)/extensions/$(gem_platform)"\ + "/$(ruby_version)#{$enable_shared ? '' : '-static'}/#{@gemname}\n"\ "#{$1}$(TARGET_GEM_DIR)$(target_prefix)" } end - conf.any? {|s| /^TARGET *= *\S/ =~ s} and conf << %{ + + conf = yield conf if block + + if conf.any? {|s| /^TARGET *= *\S/ =~ s} + conf << %{ +gem_platform = #{Gem::Platform.local} # default target all: +gem = #{@gemname} + build_complete = $(TARGET_GEM_DIR)/gem.build_complete install-so: build_complete +clean-so:: clean-build_complete +$(build_complete) $(OBJS): $(TARGET_SO_DIR_TIMESTAMP) + build_complete: $(build_complete) $(build_complete): $(TARGET_SO) $(Q) $(TOUCH) $@ -clean-so:: +clean-build_complete: -$(Q)$(RM) $(build_complete) + +install: gemspec +clean: clean-gemspec + +gemspec = $(TARGET_TOPDIR)/specifications/$(gem).gemspec +$(gemspec): $(gem_srcdir)/.bundled.$(gem).gemspec + $(Q) $(MAKEDIRS) $(@D) + $(Q) $(COPY) $(gem_srcdir)/.bundled.$(gem).gemspec $@ + +gemspec: $(gemspec) + +clean-gemspec: + -$(Q)$(RM) $(gemspec) + +LN_S = #{config_string('LN_S')} +CP_R = #{config_string('CP')} -r +} + unless @inplace + %w[bin lib].each do |d| + next unless File.directory?("#{$top_srcdir}/#{@ext_prefix}/#{@gemname}/#{d}") + conf << %{ +install-rb: gem#{d} +clean-rb:: clean-gem#{d} + +gem#{d} = $(TARGET_TOPDIR)/gems/$(gem)/#{d} +gem#{d}:#{%{ $(gem#{d})\n$(gem#{d}): $(gem_srcdir)/#{d}} if $nmake} + $(Q) $(RUBY) $(top_srcdir)/tool/ln_sr.rb -q -f -T $(gem_srcdir)/#{d} $(gem#{d}) + +clean-gem#{d}: + $(Q) $(RM_RF) $(gem#{d}) } + end + end + end + conf end end @@ -566,7 +649,9 @@ $hdrdir = ($top_srcdir = relative_from(srcdir, $topdir = "..")) + "/include" extso = [] fails = [] exts.each do |d| - $static = $force_static ? true : $static_ext[d] + $static = $force_static ? true : $static_ext.fetch(d) do + $static_ext.any? {|t, | File.fnmatch?(t, d)} + end if !$nodynamic or $static result = extmake(d, ext_prefix, !@gemname) or abort @@ -634,7 +719,7 @@ rubies = [] end } -Dir.chdir ".." +Dir.chdir dir unless $destdir.to_s.empty? $mflags.defined?("DESTDIR") or $mflags << "DESTDIR=#{$destdir}" end @@ -653,6 +738,8 @@ begin mf.puts "ECHO1 = $(V:1=@:)" mf.puts "ECHO = $(ECHO1:0=@echo)" mf.puts "MFLAGS = -$(MAKEFLAGS)" if $nmake + mf.puts "override MFLAGS := $(filter-out -j%,$(MFLAGS))" if $gnumake + mf.puts "ext_build_dir = #{File.dirname($command_output)}" mf.puts def mf.macro(name, values, max = 70) @@ -690,11 +777,18 @@ begin end submakeopts << 'EXTLDFLAGS="$(EXTLDFLAGS)"' submakeopts << 'EXTINITS="$(EXTINITS)"' - submakeopts << 'UPDATE_LIBRARIES="$(UPDATE_LIBRARIES)"' submakeopts << 'SHOWFLAGS=' mf.macro "SUBMAKEOPTS", submakeopts mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb skip] mf.macro "NOTE_NAME", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb fail] + %w[RM RMDIRS RMDIR RMALL].each {|w| mf.macro w, [RbConfig::CONFIG[w]]} + if $nmake + message = ['@(for %I in (', ') do @echo.%~I)'] + else + message = ['@for line in', '; do echo "$$line"; done'] + end + mf.macro "MESSAGE_BEGIN", [message.first] + mf.macro "MESSAGE_END", [message.last] mf.puts targets = %w[all install static install-so install-rb clean distclean realclean] targets.each do |tgt| @@ -721,24 +815,28 @@ begin if $gnumake == "yes" submake = "$(MAKE) -C $(@D)" else - submake = "cd $(@D) && " - config_string("exec") {|str| submake << str << " "} - submake << "$(MAKE)" + submake = ["cd", (sep ? "$(@D:/=#{sep})" : "$(@D)"), "&&"] + config_string("exec") {|str| submake << str} + submake = (submake << "$(MAKE)").join(" ") end targets.each do |tgt| exts.each do |d| d = d[0..-2] t = "#{d}#{tgt}" - if /^(dist|real)?clean$/ =~ tgt + if clean = /^(dist|real)?clean$/.match(tgt) deps = exts.select {|e|e.start_with?(d)}.map {|e|"#{e[0..-2]}#{tgt}"} - [t] - pd = ' ' + deps.join(' ') unless deps.empty? + pd = [' clean-local', *deps].join(' ') else pext = File.dirname(d) pd = " #{pext}/#{tgt}" if exts.include?("#{pext}/.") end mf.puts "#{t}:#{pd}\n\t$(Q)#{submake} $(MFLAGS) V=$(V) $(@F)" + if clean and clean.begin(1) + mf.puts "\t$(Q)$(RM) $(ext_build_dir)/exts.mk\n\t$(Q)$(RMDIRS) $(@D)" + end end end + mf.puts "\n""clean-local:\n\t$(Q)$(RM) $(ext_build_dir)/*~ $(ext_build_dir)/*.bak $(ext_build_dir)/core" mf.puts "\n""extso:\n" mf.puts "\t@echo EXTSO=$(EXTSO)" @@ -753,15 +851,17 @@ begin fails.each do |ext, (parent, err)| abandon ||= mandatory_exts[ext] mf.puts %Q<\t@$(NOTE_NAME) "#{ext}:"> + mf.puts "\t$(MESSAGE_BEGIN) \\" if parent - mf.puts %Q<\t@echo "\tCould not be configured. It will not be installed."> + mf.puts %Q<\t"\tCould not be configured. It will not be installed." \\> err and err.scan(/.+/) do |ee| - mf.puts %Q<\t@echo "\t#{ee.gsub(/["`$^]/, '\\\\\\&')}"> + mf.puts %Q<\t"\t#{ee.gsub(/["`$^]/, '\\\\\\&')}" \\> end - mf.puts %Q<\t@echo "\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details."> + mf.puts %Q<\t"\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details." \\> else - mf.puts %Q<\t@echo "\tSkipped because its parent was not configured."> + mf.puts %Q<\t"\tSkipped because its parent was not configured." \\> end + mf.puts "\t$(MESSAGE_END)" end mf.puts "note:\n" mf.puts %Q<\t@$(NOTE_MESG) "*** Fix the problems, then remove these directories and try again if you want."> diff --git a/ext/fcntl/depend b/ext/fcntl/depend index 720b67d9bf..57ea0f2106 100644 --- a/ext/fcntl/depend +++ b/ext/fcntl/depend @@ -2,6 +2,19 @@ fcntl.o: $(RUBY_EXTCONF_H) fcntl.o: $(arch_hdrdir)/ruby/config.h fcntl.o: $(hdrdir)/ruby.h +fcntl.o: $(hdrdir)/ruby/assert.h +fcntl.o: $(hdrdir)/ruby/backward.h +fcntl.o: $(hdrdir)/ruby/backward/2/assume.h +fcntl.o: $(hdrdir)/ruby/backward/2/attributes.h +fcntl.o: $(hdrdir)/ruby/backward/2/bool.h +fcntl.o: $(hdrdir)/ruby/backward/2/inttypes.h +fcntl.o: $(hdrdir)/ruby/backward/2/limits.h +fcntl.o: $(hdrdir)/ruby/backward/2/long_long.h +fcntl.o: $(hdrdir)/ruby/backward/2/stdalign.h +fcntl.o: $(hdrdir)/ruby/backward/2/stdarg.h +fcntl.o: $(hdrdir)/ruby/defines.h +fcntl.o: $(hdrdir)/ruby/intern.h +fcntl.o: $(hdrdir)/ruby/internal/abi.h fcntl.o: $(hdrdir)/ruby/internal/anyargs.h fcntl.o: $(hdrdir)/ruby/internal/arithmetic.h fcntl.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -39,6 +52,7 @@ fcntl.o: $(hdrdir)/ruby/internal/attr/noexcept.h fcntl.o: $(hdrdir)/ruby/internal/attr/noinline.h fcntl.o: $(hdrdir)/ruby/internal/attr/nonnull.h fcntl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +fcntl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h fcntl.o: $(hdrdir)/ruby/internal/attr/pure.h fcntl.o: $(hdrdir)/ruby/internal/attr/restrict.h fcntl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -98,7 +112,6 @@ fcntl.o: $(hdrdir)/ruby/internal/intern/enumerator.h fcntl.o: $(hdrdir)/ruby/internal/intern/error.h fcntl.o: $(hdrdir)/ruby/internal/intern/eval.h fcntl.o: $(hdrdir)/ruby/internal/intern/file.h -fcntl.o: $(hdrdir)/ruby/internal/intern/gc.h fcntl.o: $(hdrdir)/ruby/internal/intern/hash.h fcntl.o: $(hdrdir)/ruby/internal/intern/io.h fcntl.o: $(hdrdir)/ruby/internal/intern/load.h @@ -115,6 +128,7 @@ fcntl.o: $(hdrdir)/ruby/internal/intern/re.h fcntl.o: $(hdrdir)/ruby/internal/intern/ruby.h fcntl.o: $(hdrdir)/ruby/internal/intern/select.h fcntl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +fcntl.o: $(hdrdir)/ruby/internal/intern/set.h fcntl.o: $(hdrdir)/ruby/internal/intern/signal.h fcntl.o: $(hdrdir)/ruby/internal/intern/sprintf.h fcntl.o: $(hdrdir)/ruby/internal/intern/string.h @@ -129,31 +143,18 @@ fcntl.o: $(hdrdir)/ruby/internal/memory.h fcntl.o: $(hdrdir)/ruby/internal/method.h fcntl.o: $(hdrdir)/ruby/internal/module.h fcntl.o: $(hdrdir)/ruby/internal/newobj.h -fcntl.o: $(hdrdir)/ruby/internal/rgengc.h fcntl.o: $(hdrdir)/ruby/internal/scan_args.h fcntl.o: $(hdrdir)/ruby/internal/special_consts.h fcntl.o: $(hdrdir)/ruby/internal/static_assert.h fcntl.o: $(hdrdir)/ruby/internal/stdalign.h fcntl.o: $(hdrdir)/ruby/internal/stdbool.h +fcntl.o: $(hdrdir)/ruby/internal/stdckdint.h fcntl.o: $(hdrdir)/ruby/internal/symbol.h fcntl.o: $(hdrdir)/ruby/internal/value.h fcntl.o: $(hdrdir)/ruby/internal/value_type.h fcntl.o: $(hdrdir)/ruby/internal/variable.h fcntl.o: $(hdrdir)/ruby/internal/warning_push.h fcntl.o: $(hdrdir)/ruby/internal/xmalloc.h -fcntl.o: $(hdrdir)/ruby/assert.h -fcntl.o: $(hdrdir)/ruby/backward.h -fcntl.o: $(hdrdir)/ruby/backward/2/assume.h -fcntl.o: $(hdrdir)/ruby/backward/2/attributes.h -fcntl.o: $(hdrdir)/ruby/backward/2/bool.h -fcntl.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -fcntl.o: $(hdrdir)/ruby/backward/2/inttypes.h -fcntl.o: $(hdrdir)/ruby/backward/2/limits.h -fcntl.o: $(hdrdir)/ruby/backward/2/long_long.h -fcntl.o: $(hdrdir)/ruby/backward/2/stdalign.h -fcntl.o: $(hdrdir)/ruby/backward/2/stdarg.h -fcntl.o: $(hdrdir)/ruby/defines.h -fcntl.o: $(hdrdir)/ruby/intern.h fcntl.o: $(hdrdir)/ruby/missing.h fcntl.o: $(hdrdir)/ruby/ruby.h fcntl.o: $(hdrdir)/ruby/st.h diff --git a/ext/fcntl/fcntl.c b/ext/fcntl/fcntl.c index ee42d2abe5..b987e237dd 100644 --- a/ext/fcntl/fcntl.c +++ b/ext/fcntl/fcntl.c @@ -28,7 +28,10 @@ pack up your own arguments to pass as args for locking functions, etc. #include "ruby.h" #include <fcntl.h> -/* Fcntl loads the constants defined in the system's <fcntl.h> C header +/* + * Document-module: Fcntl + * + * Fcntl loads the constants defined in the system's <fcntl.h> C header * file, and used with both the fcntl(2) and open(2) POSIX system calls. * * To perform a fcntl(2) operation, use IO::fcntl. @@ -61,13 +64,19 @@ pack up your own arguments to pass as args for locking functions, etc. * f.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK|m) * */ + +#define FCNTL_VERSION "1.3.0" + void Init_fcntl(void) { VALUE mFcntl = rb_define_module("Fcntl"); + + /* The version string. */ + rb_define_const(mFcntl, "VERSION", rb_str_new_cstr(FCNTL_VERSION)); + #ifdef F_DUPFD - /* Document-const: F_DUPFD - * + /* * Duplicate a file descriptor to the minimum unused file descriptor * greater than or equal to the argument. * @@ -78,182 +87,214 @@ Init_fcntl(void) rb_define_const(mFcntl, "F_DUPFD", INT2NUM(F_DUPFD)); #endif #ifdef F_GETFD - /* Document-const: F_GETFD - * + /* * Read the close-on-exec flag of a file descriptor. */ rb_define_const(mFcntl, "F_GETFD", INT2NUM(F_GETFD)); #endif #ifdef F_GETLK - /* Document-const: F_GETLK - * + /* * Determine whether a given region of a file is locked. This uses one of * the F_*LK flags. */ rb_define_const(mFcntl, "F_GETLK", INT2NUM(F_GETLK)); #endif #ifdef F_SETFD - /* Document-const: F_SETFD - * + /* * Set the close-on-exec flag of a file descriptor. */ rb_define_const(mFcntl, "F_SETFD", INT2NUM(F_SETFD)); #endif #ifdef F_GETFL - /* Document-const: F_GETFL - * + /* * Get the file descriptor flags. This will be one or more of the O_* * flags. */ rb_define_const(mFcntl, "F_GETFL", INT2NUM(F_GETFL)); #endif #ifdef F_SETFL - /* Document-const: F_SETFL - * + /* * Set the file descriptor flags. This will be one or more of the O_* * flags. */ rb_define_const(mFcntl, "F_SETFL", INT2NUM(F_SETFL)); #endif #ifdef F_SETLK - /* Document-const: F_SETLK - * + /* * Acquire a lock on a region of a file. This uses one of the F_*LCK * flags. */ rb_define_const(mFcntl, "F_SETLK", INT2NUM(F_SETLK)); #endif #ifdef F_SETLKW - /* Document-const: F_SETLKW - * + /* * Acquire a lock on a region of a file, waiting if necessary. This uses * one of the F_*LCK flags */ rb_define_const(mFcntl, "F_SETLKW", INT2NUM(F_SETLKW)); #endif #ifdef FD_CLOEXEC - /* Document-const: FD_CLOEXEC - * + /* * the value of the close-on-exec flag. */ rb_define_const(mFcntl, "FD_CLOEXEC", INT2NUM(FD_CLOEXEC)); #endif #ifdef F_RDLCK - /* Document-const: F_RDLCK - * + /* * Read lock for a region of a file */ rb_define_const(mFcntl, "F_RDLCK", INT2NUM(F_RDLCK)); #endif #ifdef F_UNLCK - /* Document-const: F_UNLCK - * + /* * Remove lock for a region of a file */ rb_define_const(mFcntl, "F_UNLCK", INT2NUM(F_UNLCK)); #endif #ifdef F_WRLCK - /* Document-const: F_WRLCK - * + /* * Write lock for a region of a file */ rb_define_const(mFcntl, "F_WRLCK", INT2NUM(F_WRLCK)); #endif #ifdef F_SETPIPE_SZ - /* Document-const: F_SETPIPE_SZ - * + /* * Change the capacity of the pipe referred to by fd to be at least arg bytes. */ rb_define_const(mFcntl, "F_SETPIPE_SZ", INT2NUM(F_SETPIPE_SZ)); #endif #ifdef F_GETPIPE_SZ - /* Document-const: F_GETPIPE_SZ - * + /* * Return (as the function result) the capacity of the pipe referred to by fd. */ rb_define_const(mFcntl, "F_GETPIPE_SZ", INT2NUM(F_GETPIPE_SZ)); #endif #ifdef O_CREAT - /* Document-const: O_CREAT - * + /* * Create the file if it doesn't exist */ rb_define_const(mFcntl, "O_CREAT", INT2NUM(O_CREAT)); #endif #ifdef O_EXCL - /* Document-const: O_EXCL - * + /* * Used with O_CREAT, fail if the file exists */ rb_define_const(mFcntl, "O_EXCL", INT2NUM(O_EXCL)); #endif #ifdef O_NOCTTY - /* Document-const: O_NOCTTY - * + /* * Open TTY without it becoming the controlling TTY */ rb_define_const(mFcntl, "O_NOCTTY", INT2NUM(O_NOCTTY)); #endif #ifdef O_TRUNC - /* Document-const: O_TRUNC - * + /* * Truncate the file on open */ rb_define_const(mFcntl, "O_TRUNC", INT2NUM(O_TRUNC)); #endif #ifdef O_APPEND - /* Document-const: O_APPEND - * + /* * Open the file in append mode */ rb_define_const(mFcntl, "O_APPEND", INT2NUM(O_APPEND)); #endif #ifdef O_NONBLOCK - /* Document-const: O_NONBLOCK - * + /* * Open the file in non-blocking mode */ rb_define_const(mFcntl, "O_NONBLOCK", INT2NUM(O_NONBLOCK)); #endif #ifdef O_NDELAY - /* Document-const: O_NDELAY - * + /* * Open the file in non-blocking mode */ rb_define_const(mFcntl, "O_NDELAY", INT2NUM(O_NDELAY)); #endif #ifdef O_RDONLY - /* Document-const: O_RDONLY - * + /* * Open the file in read-only mode */ rb_define_const(mFcntl, "O_RDONLY", INT2NUM(O_RDONLY)); #endif #ifdef O_RDWR - /* Document-const: O_RDWR - * + /* * Open the file in read-write mode */ rb_define_const(mFcntl, "O_RDWR", INT2NUM(O_RDWR)); #endif #ifdef O_WRONLY - /* Document-const: O_WRONLY - * + /* * Open the file in write-only mode. */ rb_define_const(mFcntl, "O_WRONLY", INT2NUM(O_WRONLY)); #endif -#ifdef O_ACCMODE - /* Document-const: O_ACCMODE - * +#ifndef O_ACCMODE + int O_ACCMODE = (O_RDONLY | O_WRONLY | O_RDWR); +#endif + /* * Mask to extract the read/write flags */ rb_define_const(mFcntl, "O_ACCMODE", INT2FIX(O_ACCMODE)); -#else - /* Document-const: O_ACCMODE - * - * Mask to extract the read/write flags +#ifdef F_DUP2FD + /* + * It is a FreeBSD specific constant and equivalent + * to dup2 call. + */ + rb_define_const(mFcntl, "F_DUP2FD", INT2NUM(F_DUP2FD)); +#endif +#ifdef F_DUP2FD_CLOEXEC + /* + * It is a FreeBSD specific constant and acts + * similarly as F_DUP2FD but set the FD_CLOEXEC + * flag in addition. + */ + rb_define_const(mFcntl, "F_DUP2FD_CLOEXEC", INT2NUM(F_DUP2FD_CLOEXEC)); +#endif + +#ifdef F_PREALLOCATE + /* + * macOS specific flag used for preallocating file space. + */ + rb_define_const(mFcntl, "F_PREALLOCATE", INT2NUM(F_PREALLOCATE)); +#endif + +#ifdef F_ALLOCATECONTIG + /* + * macOS specific flag used with F_PREALLOCATE for allocating contiguous + * space. + */ + rb_define_const(mFcntl, "F_ALLOCATECONTIG", INT2NUM(F_ALLOCATECONTIG)); +#endif + +#ifdef F_ALLOCATEALL + /* + * macOS specific flag used with F_PREALLOCATE for allocating all contiguous + * space or no space. + */ + rb_define_const(mFcntl, "F_ALLOCATEALL", INT2NUM(F_ALLOCATEALL)); +#endif + +#ifdef F_ALLOCATEPERSIST + /* + * macOS specific flag used with F_PREALLOCATE. Allocate space that is not + * freed when close is called. + */ + rb_define_const(mFcntl, "F_ALLOCATEPERSIST", INT2NUM(F_ALLOCATEPERSIST)); +#endif + +#ifdef F_PEOFPOSMODE + /* + * macOS specific flag used with F_PREALLOCATE. Allocate from the physical + * end of file + */ + rb_define_const(mFcntl, "F_PEOFPOSMODE", INT2NUM(F_PEOFPOSMODE)); +#endif + +#ifdef F_VOLPOSMODE + /* + * macOS specific flag used with F_PREALLOCATE. Allocate from the volume offset. */ - rb_define_const(mFcntl, "O_ACCMODE", INT2FIX(O_RDONLY | O_WRONLY | O_RDWR)); + rb_define_const(mFcntl, "F_VOLPOSMODE", INT2NUM(F_VOLPOSMODE)); #endif } diff --git a/ext/fcntl/fcntl.gemspec b/ext/fcntl/fcntl.gemspec index 048e101aa5..613a90d1ae 100644 --- a/ext/fcntl/fcntl.gemspec +++ b/ext/fcntl/fcntl.gemspec @@ -1,9 +1,19 @@ # coding: utf-8 # frozen_string_literal: true +source_version = ["", "ext/fcntl/"].find do |dir| + begin + break File.open(File.join(__dir__, "#{dir}fcntl.c")) {|f| + f.gets("\n#define FCNTL_VERSION ") + f.gets[/\s*"(.+)"/, 1] + } + rescue Errno::ENOENT + end +end + Gem::Specification.new do |spec| spec.name = "fcntl" - spec.version = "1.0.1" + spec.version = source_version spec.authors = ["Yukihiro Matsumoto"] spec.email = ["matz@ruby-lang.org"] @@ -13,9 +23,10 @@ Gem::Specification.new do |spec| spec.licenses = ["Ruby", "BSD-2-Clause"] spec.files = ["ext/fcntl/extconf.rb", "ext/fcntl/fcntl.c"] + spec.extra_rdoc_files = [".document", ".rdoc_options", "BSDL", "COPYING", "README.md"] spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.extensions = "ext/fcntl/extconf.rb" - spec.required_ruby_version = ">= 2.3.0" + spec.required_ruby_version = ">= 2.5.0" end diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c deleted file mode 100644 index 3679e5c9ad..0000000000 --- a/ext/fiddle/closure.c +++ /dev/null @@ -1,360 +0,0 @@ -#include <fiddle.h> -#include <ruby/thread.h> - -int ruby_thread_has_gvl_p(void); /* from internal.h */ - -VALUE cFiddleClosure; - -typedef struct { - void * code; - ffi_closure *pcl; - ffi_cif cif; - int argc; - ffi_type **argv; -} fiddle_closure; - -#if defined(__OpenBSD__) -# define USE_FFI_CLOSURE_ALLOC 0 -#endif - -#if defined(USE_FFI_CLOSURE_ALLOC) -#elif !defined(HAVE_FFI_CLOSURE_ALLOC) -# define USE_FFI_CLOSURE_ALLOC 0 -#else -# define USE_FFI_CLOSURE_ALLOC 1 -#endif - -static void -dealloc(void * ptr) -{ - fiddle_closure * cls = (fiddle_closure *)ptr; -#if USE_FFI_CLOSURE_ALLOC - ffi_closure_free(cls->pcl); -#else - munmap(cls->pcl, sizeof(*cls->pcl)); -#endif - if (cls->argv) xfree(cls->argv); - xfree(cls); -} - -static size_t -closure_memsize(const void * ptr) -{ - fiddle_closure * cls = (fiddle_closure *)ptr; - size_t size = 0; - - size += sizeof(*cls); -#if !defined(FFI_NO_RAW_API) || !FFI_NO_RAW_API - size += ffi_raw_size(&cls->cif); -#endif - size += sizeof(*cls->argv); - size += sizeof(ffi_closure); - - return size; -} - -const rb_data_type_t closure_data_type = { - "fiddle/closure", - {0, dealloc, closure_memsize,}, -}; - -struct callback_args { - ffi_cif *cif; - void *resp; - void **args; - void *ctx; -}; - -static void * -with_gvl_callback(void *ptr) -{ - struct callback_args *x = ptr; - - VALUE self = (VALUE)x->ctx; - VALUE rbargs = rb_iv_get(self, "@args"); - VALUE ctype = rb_iv_get(self, "@ctype"); - int argc = RARRAY_LENINT(rbargs); - VALUE params = rb_ary_tmp_new(argc); - VALUE ret; - VALUE cPointer; - int i, type; - - cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); - - for (i = 0; i < argc; i++) { - type = NUM2INT(RARRAY_AREF(rbargs, i)); - switch (type) { - case TYPE_VOID: - argc = 0; - break; - case TYPE_INT: - rb_ary_push(params, INT2NUM(*(int *)x->args[i])); - break; - case -TYPE_INT: - rb_ary_push(params, UINT2NUM(*(unsigned int *)x->args[i])); - break; - case TYPE_VOIDP: - rb_ary_push(params, - rb_funcall(cPointer, rb_intern("[]"), 1, - PTR2NUM(*(void **)x->args[i]))); - break; - case TYPE_LONG: - rb_ary_push(params, LONG2NUM(*(long *)x->args[i])); - break; - case -TYPE_LONG: - rb_ary_push(params, ULONG2NUM(*(unsigned long *)x->args[i])); - break; - case TYPE_CHAR: - rb_ary_push(params, INT2NUM(*(signed char *)x->args[i])); - break; - case -TYPE_CHAR: - rb_ary_push(params, UINT2NUM(*(unsigned char *)x->args[i])); - break; - case TYPE_SHORT: - rb_ary_push(params, INT2NUM(*(signed short *)x->args[i])); - break; - case -TYPE_SHORT: - rb_ary_push(params, UINT2NUM(*(unsigned short *)x->args[i])); - break; - case TYPE_DOUBLE: - rb_ary_push(params, rb_float_new(*(double *)x->args[i])); - break; - case TYPE_FLOAT: - rb_ary_push(params, rb_float_new(*(float *)x->args[i])); - break; -#if HAVE_LONG_LONG - case TYPE_LONG_LONG: - rb_ary_push(params, LL2NUM(*(LONG_LONG *)x->args[i])); - break; - case -TYPE_LONG_LONG: - rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i])); - break; -#endif - case TYPE_CONST_STRING: - rb_ary_push(params, - rb_str_new_cstr(*((const char **)(x->args[i])))); - break; - default: - rb_raise(rb_eRuntimeError, "closure args: %d", type); - } - } - - ret = rb_funcall2(self, rb_intern("call"), argc, RARRAY_CONST_PTR(params)); - RB_GC_GUARD(params); - - type = NUM2INT(ctype); - switch (type) { - case TYPE_VOID: - break; - case TYPE_LONG: - *(long *)x->resp = NUM2LONG(ret); - break; - case -TYPE_LONG: - *(unsigned long *)x->resp = NUM2ULONG(ret); - break; - case TYPE_CHAR: - case TYPE_SHORT: - case TYPE_INT: - *(ffi_sarg *)x->resp = NUM2INT(ret); - break; - case -TYPE_CHAR: - case -TYPE_SHORT: - case -TYPE_INT: - *(ffi_arg *)x->resp = NUM2UINT(ret); - break; - case TYPE_VOIDP: - *(void **)x->resp = NUM2PTR(ret); - break; - case TYPE_DOUBLE: - *(double *)x->resp = NUM2DBL(ret); - break; - case TYPE_FLOAT: - *(float *)x->resp = (float)NUM2DBL(ret); - break; -#if HAVE_LONG_LONG - case TYPE_LONG_LONG: - *(LONG_LONG *)x->resp = NUM2LL(ret); - break; - case -TYPE_LONG_LONG: - *(unsigned LONG_LONG *)x->resp = NUM2ULL(ret); - break; -#endif - case TYPE_CONST_STRING: - /* Dangerous. Callback must keep reference of the String. */ - *((const char **)(x->resp)) = StringValueCStr(ret); - break; - default: - rb_raise(rb_eRuntimeError, "closure retval: %d", type); - } - return 0; -} - -static void -callback(ffi_cif *cif, void *resp, void **args, void *ctx) -{ - struct callback_args x; - - x.cif = cif; - x.resp = resp; - x.args = args; - x.ctx = ctx; - - if (ruby_thread_has_gvl_p()) { - (void)with_gvl_callback(&x); - } else { - (void)rb_thread_call_with_gvl(with_gvl_callback, &x); - } -} - -static VALUE -allocate(VALUE klass) -{ - fiddle_closure * closure; - - VALUE i = TypedData_Make_Struct(klass, fiddle_closure, - &closure_data_type, closure); - -#if USE_FFI_CLOSURE_ALLOC - closure->pcl = ffi_closure_alloc(sizeof(ffi_closure), &closure->code); -#else - closure->pcl = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); -#endif - - return i; -} - -static VALUE -initialize(int rbargc, VALUE argv[], VALUE self) -{ - VALUE ret; - VALUE args; - VALUE normalized_args; - VALUE abi; - fiddle_closure * cl; - ffi_cif * cif; - ffi_closure *pcl; - ffi_status result; - int i, argc; - - if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi)) - abi = INT2NUM(FFI_DEFAULT_ABI); - - Check_Type(args, T_ARRAY); - - argc = RARRAY_LENINT(args); - - TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); - - cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *)); - - normalized_args = rb_ary_new_capa(argc); - for (i = 0; i < argc; i++) { - VALUE arg = rb_fiddle_type_ensure(RARRAY_AREF(args, i)); - rb_ary_push(normalized_args, arg); - cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg)); - } - cl->argv[argc] = NULL; - - ret = rb_fiddle_type_ensure(ret); - rb_iv_set(self, "@ctype", ret); - rb_iv_set(self, "@args", normalized_args); - - cif = &cl->cif; - pcl = cl->pcl; - - result = ffi_prep_cif(cif, - NUM2INT(abi), - argc, - rb_fiddle_int_to_ffi_type(NUM2INT(ret)), - cl->argv); - - if (FFI_OK != result) - rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); - -#if USE_FFI_CLOSURE_ALLOC - result = ffi_prep_closure_loc(pcl, cif, callback, - (void *)self, cl->code); -#else - result = ffi_prep_closure(pcl, cif, callback, (void *)self); - cl->code = (void *)pcl; - i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC); - if (i) { - rb_sys_fail("mprotect"); - } -#endif - - if (FFI_OK != result) - rb_raise(rb_eRuntimeError, "error prepping closure %d", result); - - return self; -} - -static VALUE -to_i(VALUE self) -{ - fiddle_closure * cl; - void *code; - - TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); - - code = cl->code; - - return PTR2NUM(code); -} - -void -Init_fiddle_closure(void) -{ -#if 0 - mFiddle = rb_define_module("Fiddle"); /* let rdoc know about mFiddle */ -#endif - - /* - * Document-class: Fiddle::Closure - * - * == Description - * - * An FFI closure wrapper, for handling callbacks. - * - * == Example - * - * closure = Class.new(Fiddle::Closure) { - * def call - * 10 - * end - * }.new(Fiddle::TYPE_INT, []) - * #=> #<#<Class:0x0000000150d308>:0x0000000150d240> - * func = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT) - * #=> #<Fiddle::Function:0x00000001516e58> - * func.call - * #=> 10 - */ - cFiddleClosure = rb_define_class_under(mFiddle, "Closure", rb_cObject); - - rb_define_alloc_func(cFiddleClosure, allocate); - - /* - * Document-method: new - * - * call-seq: new(ret, args, abi = Fiddle::DEFAULT) - * - * Construct a new Closure object. - * - * * +ret+ is the C type to be returned - * * +args+ is an Array of arguments, passed to the callback function - * * +abi+ is the abi of the closure - * - * If there is an error in preparing the ffi_cif or ffi_prep_closure, - * then a RuntimeError will be raised. - */ - rb_define_method(cFiddleClosure, "initialize", initialize, -1); - - /* - * Document-method: to_i - * - * Returns the memory address for this closure - */ - rb_define_method(cFiddleClosure, "to_i", to_i, 0); -} -/* vim: set noet sw=4 sts=4 */ diff --git a/ext/fiddle/closure.h b/ext/fiddle/closure.h deleted file mode 100644 index d0a8be6180..0000000000 --- a/ext/fiddle/closure.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef FIDDLE_CLOSURE_H -#define FIDDLE_CLOSURE_H - -#include <fiddle.h> - -void Init_fiddle_closure(void); - -#endif diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c deleted file mode 100644 index 6e0ce36378..0000000000 --- a/ext/fiddle/conversions.c +++ /dev/null @@ -1,330 +0,0 @@ -#include <fiddle.h> - -VALUE -rb_fiddle_type_ensure(VALUE type) -{ - VALUE original_type = type; - - if (!RB_SYMBOL_P(type)) { - VALUE type_string = rb_check_string_type(type); - if (!NIL_P(type_string)) { - type = rb_to_symbol(type_string); - } - } - - if (RB_SYMBOL_P(type)) { - ID type_id = rb_sym2id(type); - ID void_id; - ID voidp_id; - ID char_id; - ID short_id; - ID int_id; - ID long_id; -#ifdef TYPE_LONG_LONG - ID long_long_id; -#endif -#ifdef TYPE_INT8_T - ID int8_t_id; -#endif -#ifdef TYPE_INT16_T - ID int16_t_id; -#endif -#ifdef TYPE_INT32_T - ID int32_t_id; -#endif -#ifdef TYPE_INT64_T - ID int64_t_id; -#endif - ID float_id; - ID double_id; - ID variadic_id; - ID const_string_id; - ID size_t_id; - ID ssize_t_id; - ID ptrdiff_t_id; - ID intptr_t_id; - ID uintptr_t_id; - RUBY_CONST_ID(void_id, "void"); - RUBY_CONST_ID(voidp_id, "voidp"); - RUBY_CONST_ID(char_id, "char"); - RUBY_CONST_ID(short_id, "short"); - RUBY_CONST_ID(int_id, "int"); - RUBY_CONST_ID(long_id, "long"); -#ifdef TYPE_LONG_LONG - RUBY_CONST_ID(long_long_id, "long_long"); -#endif -#ifdef TYPE_INT8_T - RUBY_CONST_ID(int8_t_id, "int8_t"); -#endif -#ifdef TYPE_INT16_T - RUBY_CONST_ID(int16_t_id, "int16_t"); -#endif -#ifdef TYPE_INT32_T - RUBY_CONST_ID(int32_t_id, "int32_t"); -#endif -#ifdef TYPE_INT64_T - RUBY_CONST_ID(int64_t_id, "int64_t"); -#endif - RUBY_CONST_ID(float_id, "float"); - RUBY_CONST_ID(double_id, "double"); - RUBY_CONST_ID(variadic_id, "variadic"); - RUBY_CONST_ID(const_string_id, "const_string"); - RUBY_CONST_ID(size_t_id, "size_t"); - RUBY_CONST_ID(ssize_t_id, "ssize_t"); - RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t"); - RUBY_CONST_ID(intptr_t_id, "intptr_t"); - RUBY_CONST_ID(uintptr_t_id, "uintptr_t"); - if (type_id == void_id) { - return INT2NUM(TYPE_VOID); - } - else if (type_id == voidp_id) { - return INT2NUM(TYPE_VOIDP); - } - else if (type_id == char_id) { - return INT2NUM(TYPE_CHAR); - } - else if (type_id == short_id) { - return INT2NUM(TYPE_SHORT); - } - else if (type_id == int_id) { - return INT2NUM(TYPE_INT); - } - else if (type_id == long_id) { - return INT2NUM(TYPE_LONG); - } -#ifdef TYPE_LONG_LONG - else if (type_id == long_long_id) { - return INT2NUM(TYPE_LONG_LONG); - } -#endif -#ifdef TYPE_INT8_T - else if (type_id == int8_t_id) { - return INT2NUM(TYPE_INT8_T); - } -#endif -#ifdef TYPE_INT16_T - else if (type_id == int16_t_id) { - return INT2NUM(TYPE_INT16_T); - } -#endif -#ifdef TYPE_INT32_T - else if (type_id == int32_t_id) { - return INT2NUM(TYPE_INT32_T); - } -#endif -#ifdef TYPE_INT64_T - else if (type_id == int64_t_id) { - return INT2NUM(TYPE_INT64_T); - } -#endif - else if (type_id == float_id) { - return INT2NUM(TYPE_FLOAT); - } - else if (type_id == double_id) { - return INT2NUM(TYPE_DOUBLE); - } - else if (type_id == variadic_id) { - return INT2NUM(TYPE_VARIADIC); - } - else if (type_id == const_string_id) { - return INT2NUM(TYPE_CONST_STRING); - } - else if (type_id == size_t_id) { - return INT2NUM(TYPE_SIZE_T); - } - else if (type_id == ssize_t_id) { - return INT2NUM(TYPE_SSIZE_T); - } - else if (type_id == ptrdiff_t_id) { - return INT2NUM(TYPE_PTRDIFF_T); - } - else if (type_id == intptr_t_id) { - return INT2NUM(TYPE_INTPTR_T); - } - else if (type_id == uintptr_t_id) { - return INT2NUM(TYPE_UINTPTR_T); - } - else { - type = original_type; - } - } - - return rb_to_int(type); -} - -ffi_type * -rb_fiddle_int_to_ffi_type(int type) -{ - int signed_p = 1; - - if (type < 0) { - type = -1 * type; - signed_p = 0; - } - -#define rb_ffi_type_of(t) (signed_p ? &ffi_type_s##t : &ffi_type_u##t) - - switch (type) { - case TYPE_VOID: - return &ffi_type_void; - case TYPE_VOIDP: - return &ffi_type_pointer; - case TYPE_CHAR: - return rb_ffi_type_of(char); - case TYPE_SHORT: - return rb_ffi_type_of(short); - case TYPE_INT: - return rb_ffi_type_of(int); - case TYPE_LONG: - return rb_ffi_type_of(long); -#if HAVE_LONG_LONG - case TYPE_LONG_LONG: - return rb_ffi_type_of(long_long); -#endif - case TYPE_FLOAT: - return &ffi_type_float; - case TYPE_DOUBLE: - return &ffi_type_double; - case TYPE_CONST_STRING: - return &ffi_type_pointer; - default: - rb_raise(rb_eRuntimeError, "unknown type %d", type); - } - return &ffi_type_pointer; -} - -ffi_type * -int_to_ffi_type(int type) -{ - return rb_fiddle_int_to_ffi_type(type); -} - -void -rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst) -{ - switch (type) { - case TYPE_VOID: - break; - case TYPE_VOIDP: - dst->pointer = NUM2PTR(rb_Integer(*src)); - break; - case TYPE_CHAR: - dst->schar = (signed char)NUM2INT(*src); - break; - case -TYPE_CHAR: - dst->uchar = (unsigned char)NUM2UINT(*src); - break; - case TYPE_SHORT: - dst->sshort = (unsigned short)NUM2INT(*src); - break; - case -TYPE_SHORT: - dst->sshort = (signed short)NUM2UINT(*src); - break; - case TYPE_INT: - dst->sint = NUM2INT(*src); - break; - case -TYPE_INT: - dst->uint = NUM2UINT(*src); - break; - case TYPE_LONG: - dst->slong = NUM2LONG(*src); - break; - case -TYPE_LONG: - dst->ulong = NUM2ULONG(*src); - break; -#if HAVE_LONG_LONG - case TYPE_LONG_LONG: - dst->slong_long = NUM2LL(*src); - break; - case -TYPE_LONG_LONG: - dst->ulong_long = NUM2ULL(*src); - break; -#endif - case TYPE_FLOAT: - dst->ffloat = (float)NUM2DBL(*src); - break; - case TYPE_DOUBLE: - dst->ddouble = NUM2DBL(*src); - break; - case TYPE_CONST_STRING: - if (NIL_P(*src)) { - dst->pointer = NULL; - } - else { - dst->pointer = rb_string_value_cstr(src); - } - break; - default: - rb_raise(rb_eRuntimeError, "unknown type %d", type); - } -} - -void -value_to_generic(int type, VALUE src, fiddle_generic *dst) -{ - /* src isn't safe from GC when type is TYPE_CONST_STRING and src - * isn't String. */ - rb_fiddle_value_to_generic(type, &src, dst); -} - -VALUE -rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval) -{ - int type = NUM2INT(rettype); - VALUE cPointer; - - cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); - - switch (type) { - case TYPE_VOID: - return Qnil; - case TYPE_VOIDP: - return rb_funcall(cPointer, rb_intern("[]"), 1, - PTR2NUM((void *)retval.pointer)); - case TYPE_CHAR: - return INT2NUM((signed char)retval.fffi_sarg); - case -TYPE_CHAR: - return INT2NUM((unsigned char)retval.fffi_arg); - case TYPE_SHORT: - return INT2NUM((signed short)retval.fffi_sarg); - case -TYPE_SHORT: - return INT2NUM((unsigned short)retval.fffi_arg); - case TYPE_INT: - return INT2NUM((signed int)retval.fffi_sarg); - case -TYPE_INT: - return UINT2NUM((unsigned int)retval.fffi_arg); - case TYPE_LONG: - return LONG2NUM(retval.slong); - case -TYPE_LONG: - return ULONG2NUM(retval.ulong); -#if HAVE_LONG_LONG - case TYPE_LONG_LONG: - return LL2NUM(retval.slong_long); - case -TYPE_LONG_LONG: - return ULL2NUM(retval.ulong_long); -#endif - case TYPE_FLOAT: - return rb_float_new(retval.ffloat); - case TYPE_DOUBLE: - return rb_float_new(retval.ddouble); - case TYPE_CONST_STRING: - if (retval.pointer) { - return rb_str_new_cstr(retval.pointer); - } - else { - return Qnil; - } - default: - rb_raise(rb_eRuntimeError, "unknown type %d", type); - } - - UNREACHABLE; -} - -VALUE -generic_to_value(VALUE rettype, fiddle_generic retval) -{ - return rb_fiddle_generic_to_value(rettype, retval); -} - -/* vim: set noet sw=4 sts=4 */ diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h deleted file mode 100644 index c7c12a9234..0000000000 --- a/ext/fiddle/conversions.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef FIDDLE_CONVERSIONS_H -#define FIDDLE_CONVERSIONS_H - -#include <fiddle.h> - -typedef union -{ - ffi_arg fffi_arg; /* rvalue smaller than unsigned long */ - ffi_sarg fffi_sarg; /* rvalue smaller than signed long */ - unsigned char uchar; /* ffi_type_uchar */ - signed char schar; /* ffi_type_schar */ - unsigned short ushort; /* ffi_type_sshort */ - signed short sshort; /* ffi_type_ushort */ - unsigned int uint; /* ffi_type_uint */ - signed int sint; /* ffi_type_sint */ - unsigned long ulong; /* ffi_type_ulong */ - signed long slong; /* ffi_type_slong */ - float ffloat; /* ffi_type_float */ - double ddouble; /* ffi_type_double */ -#if HAVE_LONG_LONG - unsigned LONG_LONG ulong_long; /* ffi_type_ulong_long */ - signed LONG_LONG slong_long; /* ffi_type_ulong_long */ -#endif - void * pointer; /* ffi_type_pointer */ -} fiddle_generic; - -VALUE rb_fiddle_type_ensure(VALUE type); -ffi_type * rb_fiddle_int_to_ffi_type(int type); -void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst); -VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval); - -/* Deprecated. Use rb_fiddle_*() version. */ -ffi_type * int_to_ffi_type(int type); -void value_to_generic(int type, VALUE src, fiddle_generic *dst); -VALUE generic_to_value(VALUE rettype, fiddle_generic retval); - -#define VALUE2GENERIC(_type, _src, _dst) \ - rb_fiddle_value_to_generic((_type), &(_src), (_dst)) -#define INT2FFI_TYPE(_type) \ - rb_fiddle_int_to_ffi_type(_type) -#define GENERIC2VALUE(_type, _retval) \ - rb_fiddle_generic_to_value((_type), (_retval)) - -#if SIZEOF_VOIDP == SIZEOF_LONG -# define PTR2NUM(x) (LONG2NUM((long)(x))) -# define NUM2PTR(x) ((void*)(NUM2ULONG(x))) -#else -/* # error --->> Ruby/DL2 requires sizeof(void*) == sizeof(long) to be compiled. <<--- */ -# define PTR2NUM(x) (LL2NUM((LONG_LONG)(x))) -# define NUM2PTR(x) ((void*)(NUM2ULL(x))) -#endif - -#endif diff --git a/ext/fiddle/depend b/ext/fiddle/depend deleted file mode 100644 index f16320db36..0000000000 --- a/ext/fiddle/depend +++ /dev/null @@ -1,1396 +0,0 @@ -PWD = - -CONFIGURE_LIBFFI = \ - $(LIBFFI_CONFIGURE) --disable-shared \ - --host=$(LIBFFI_ARCH) --enable-builddir=$(arch) \ - CC="$(CC)" CFLAGS="$(LIBFFI_CFLAGS)" \ - LD="$(LD)" LDFLAGS="$(LIBFFI_LDFLAGS)" - -$(STATIC_LIB) $(RUBYARCHDIR)/$(DLLIB) $(DLLIB): $(LIBFFI_A) - -$(OBJS): $(FFI_H) - -.PHONY: .FORCE hdr - -.FORCE: - -hdr: $(FFI_H) - -configure-libffi build-libffi: .FORCE -configure-libffi \ -$(LIBFFI_DIR)/include/ffi.h \ -$(LIBFFI_DIR)/include/ffitarget.h \ -$(LIBFFI_DIR)/fficonfig.h \ -$(LIBFFI_DIR)/Makefile: - $(Q) $(MAKEDIRS) $(LIBFFI_DIR) - $(Q) $(CONFIGURE_LIBFFI) - -build-libffi $(LIBFFI_A): - $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) - -clean-none: -clean-libffi: - $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) clean - -distclean-none: -distclean-libffi: - $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) distclean - $(Q) $(RM) $(LIBFFI_DIR)/local.exp - $(Q) $(RUBY) -rfileutils -e "FileUtils.rmdir(Dir.glob(ARGV[0]+'/**/{,.*/}'), :parents=>true)" $(LIBFFI_DIR) - -realclean-none: -realclean-libffi: - $(Q) $(RMALL) $(LIBFFI_DIR) - -.PHONY: clean-libffi distclean-libffi realclean-libffi -.PHONY: clean-none distclean-none realclean-none - -clean: clean-$(LIBFFI_CLEAN) -distclean: distclean-$(LIBFFI_CLEAN) -realclean: realclean-$(LIBFFI_CLEAN) - -.PHONY: configure configure-libffi - -# AUTOGENERATED DEPENDENCIES START -closure.o: $(RUBY_EXTCONF_H) -closure.o: $(arch_hdrdir)/ruby/config.h -closure.o: $(hdrdir)/ruby.h -closure.o: $(hdrdir)/ruby/assert.h -closure.o: $(hdrdir)/ruby/backward.h -closure.o: $(hdrdir)/ruby/backward/2/assume.h -closure.o: $(hdrdir)/ruby/backward/2/attributes.h -closure.o: $(hdrdir)/ruby/backward/2/bool.h -closure.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -closure.o: $(hdrdir)/ruby/backward/2/inttypes.h -closure.o: $(hdrdir)/ruby/backward/2/limits.h -closure.o: $(hdrdir)/ruby/backward/2/long_long.h -closure.o: $(hdrdir)/ruby/backward/2/stdalign.h -closure.o: $(hdrdir)/ruby/backward/2/stdarg.h -closure.o: $(hdrdir)/ruby/defines.h -closure.o: $(hdrdir)/ruby/intern.h -closure.o: $(hdrdir)/ruby/internal/anyargs.h -closure.o: $(hdrdir)/ruby/internal/arithmetic.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/char.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/double.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/int.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/long.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/short.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -closure.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -closure.o: $(hdrdir)/ruby/internal/assume.h -closure.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -closure.o: $(hdrdir)/ruby/internal/attr/artificial.h -closure.o: $(hdrdir)/ruby/internal/attr/cold.h -closure.o: $(hdrdir)/ruby/internal/attr/const.h -closure.o: $(hdrdir)/ruby/internal/attr/constexpr.h -closure.o: $(hdrdir)/ruby/internal/attr/deprecated.h -closure.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -closure.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -closure.o: $(hdrdir)/ruby/internal/attr/error.h -closure.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -closure.o: $(hdrdir)/ruby/internal/attr/forceinline.h -closure.o: $(hdrdir)/ruby/internal/attr/format.h -closure.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -closure.o: $(hdrdir)/ruby/internal/attr/noalias.h -closure.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -closure.o: $(hdrdir)/ruby/internal/attr/noexcept.h -closure.o: $(hdrdir)/ruby/internal/attr/noinline.h -closure.o: $(hdrdir)/ruby/internal/attr/nonnull.h -closure.o: $(hdrdir)/ruby/internal/attr/noreturn.h -closure.o: $(hdrdir)/ruby/internal/attr/pure.h -closure.o: $(hdrdir)/ruby/internal/attr/restrict.h -closure.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -closure.o: $(hdrdir)/ruby/internal/attr/warning.h -closure.o: $(hdrdir)/ruby/internal/attr/weakref.h -closure.o: $(hdrdir)/ruby/internal/cast.h -closure.o: $(hdrdir)/ruby/internal/compiler_is.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -closure.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -closure.o: $(hdrdir)/ruby/internal/compiler_since.h -closure.o: $(hdrdir)/ruby/internal/config.h -closure.o: $(hdrdir)/ruby/internal/constant_p.h -closure.o: $(hdrdir)/ruby/internal/core.h -closure.o: $(hdrdir)/ruby/internal/core/rarray.h -closure.o: $(hdrdir)/ruby/internal/core/rbasic.h -closure.o: $(hdrdir)/ruby/internal/core/rbignum.h -closure.o: $(hdrdir)/ruby/internal/core/rclass.h -closure.o: $(hdrdir)/ruby/internal/core/rdata.h -closure.o: $(hdrdir)/ruby/internal/core/rfile.h -closure.o: $(hdrdir)/ruby/internal/core/rhash.h -closure.o: $(hdrdir)/ruby/internal/core/robject.h -closure.o: $(hdrdir)/ruby/internal/core/rregexp.h -closure.o: $(hdrdir)/ruby/internal/core/rstring.h -closure.o: $(hdrdir)/ruby/internal/core/rstruct.h -closure.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -closure.o: $(hdrdir)/ruby/internal/ctype.h -closure.o: $(hdrdir)/ruby/internal/dllexport.h -closure.o: $(hdrdir)/ruby/internal/dosish.h -closure.o: $(hdrdir)/ruby/internal/error.h -closure.o: $(hdrdir)/ruby/internal/eval.h -closure.o: $(hdrdir)/ruby/internal/event.h -closure.o: $(hdrdir)/ruby/internal/fl_type.h -closure.o: $(hdrdir)/ruby/internal/gc.h -closure.o: $(hdrdir)/ruby/internal/glob.h -closure.o: $(hdrdir)/ruby/internal/globals.h -closure.o: $(hdrdir)/ruby/internal/has/attribute.h -closure.o: $(hdrdir)/ruby/internal/has/builtin.h -closure.o: $(hdrdir)/ruby/internal/has/c_attribute.h -closure.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -closure.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -closure.o: $(hdrdir)/ruby/internal/has/extension.h -closure.o: $(hdrdir)/ruby/internal/has/feature.h -closure.o: $(hdrdir)/ruby/internal/has/warning.h -closure.o: $(hdrdir)/ruby/internal/intern/array.h -closure.o: $(hdrdir)/ruby/internal/intern/bignum.h -closure.o: $(hdrdir)/ruby/internal/intern/class.h -closure.o: $(hdrdir)/ruby/internal/intern/compar.h -closure.o: $(hdrdir)/ruby/internal/intern/complex.h -closure.o: $(hdrdir)/ruby/internal/intern/cont.h -closure.o: $(hdrdir)/ruby/internal/intern/dir.h -closure.o: $(hdrdir)/ruby/internal/intern/enum.h -closure.o: $(hdrdir)/ruby/internal/intern/enumerator.h -closure.o: $(hdrdir)/ruby/internal/intern/error.h -closure.o: $(hdrdir)/ruby/internal/intern/eval.h -closure.o: $(hdrdir)/ruby/internal/intern/file.h -closure.o: $(hdrdir)/ruby/internal/intern/gc.h -closure.o: $(hdrdir)/ruby/internal/intern/hash.h -closure.o: $(hdrdir)/ruby/internal/intern/io.h -closure.o: $(hdrdir)/ruby/internal/intern/load.h -closure.o: $(hdrdir)/ruby/internal/intern/marshal.h -closure.o: $(hdrdir)/ruby/internal/intern/numeric.h -closure.o: $(hdrdir)/ruby/internal/intern/object.h -closure.o: $(hdrdir)/ruby/internal/intern/parse.h -closure.o: $(hdrdir)/ruby/internal/intern/proc.h -closure.o: $(hdrdir)/ruby/internal/intern/process.h -closure.o: $(hdrdir)/ruby/internal/intern/random.h -closure.o: $(hdrdir)/ruby/internal/intern/range.h -closure.o: $(hdrdir)/ruby/internal/intern/rational.h -closure.o: $(hdrdir)/ruby/internal/intern/re.h -closure.o: $(hdrdir)/ruby/internal/intern/ruby.h -closure.o: $(hdrdir)/ruby/internal/intern/select.h -closure.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -closure.o: $(hdrdir)/ruby/internal/intern/signal.h -closure.o: $(hdrdir)/ruby/internal/intern/sprintf.h -closure.o: $(hdrdir)/ruby/internal/intern/string.h -closure.o: $(hdrdir)/ruby/internal/intern/struct.h -closure.o: $(hdrdir)/ruby/internal/intern/thread.h -closure.o: $(hdrdir)/ruby/internal/intern/time.h -closure.o: $(hdrdir)/ruby/internal/intern/variable.h -closure.o: $(hdrdir)/ruby/internal/intern/vm.h -closure.o: $(hdrdir)/ruby/internal/interpreter.h -closure.o: $(hdrdir)/ruby/internal/iterator.h -closure.o: $(hdrdir)/ruby/internal/memory.h -closure.o: $(hdrdir)/ruby/internal/method.h -closure.o: $(hdrdir)/ruby/internal/module.h -closure.o: $(hdrdir)/ruby/internal/newobj.h -closure.o: $(hdrdir)/ruby/internal/rgengc.h -closure.o: $(hdrdir)/ruby/internal/scan_args.h -closure.o: $(hdrdir)/ruby/internal/special_consts.h -closure.o: $(hdrdir)/ruby/internal/static_assert.h -closure.o: $(hdrdir)/ruby/internal/stdalign.h -closure.o: $(hdrdir)/ruby/internal/stdbool.h -closure.o: $(hdrdir)/ruby/internal/symbol.h -closure.o: $(hdrdir)/ruby/internal/value.h -closure.o: $(hdrdir)/ruby/internal/value_type.h -closure.o: $(hdrdir)/ruby/internal/variable.h -closure.o: $(hdrdir)/ruby/internal/warning_push.h -closure.o: $(hdrdir)/ruby/internal/xmalloc.h -closure.o: $(hdrdir)/ruby/missing.h -closure.o: $(hdrdir)/ruby/ruby.h -closure.o: $(hdrdir)/ruby/st.h -closure.o: $(hdrdir)/ruby/subst.h -closure.o: $(hdrdir)/ruby/thread.h -closure.o: closure.c -closure.o: closure.h -closure.o: conversions.h -closure.o: fiddle.h -closure.o: function.h -conversions.o: $(RUBY_EXTCONF_H) -conversions.o: $(arch_hdrdir)/ruby/config.h -conversions.o: $(hdrdir)/ruby.h -conversions.o: $(hdrdir)/ruby/assert.h -conversions.o: $(hdrdir)/ruby/backward.h -conversions.o: $(hdrdir)/ruby/backward/2/assume.h -conversions.o: $(hdrdir)/ruby/backward/2/attributes.h -conversions.o: $(hdrdir)/ruby/backward/2/bool.h -conversions.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -conversions.o: $(hdrdir)/ruby/backward/2/inttypes.h -conversions.o: $(hdrdir)/ruby/backward/2/limits.h -conversions.o: $(hdrdir)/ruby/backward/2/long_long.h -conversions.o: $(hdrdir)/ruby/backward/2/stdalign.h -conversions.o: $(hdrdir)/ruby/backward/2/stdarg.h -conversions.o: $(hdrdir)/ruby/defines.h -conversions.o: $(hdrdir)/ruby/intern.h -conversions.o: $(hdrdir)/ruby/internal/anyargs.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/char.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/double.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/int.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/long.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/short.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -conversions.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -conversions.o: $(hdrdir)/ruby/internal/assume.h -conversions.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -conversions.o: $(hdrdir)/ruby/internal/attr/artificial.h -conversions.o: $(hdrdir)/ruby/internal/attr/cold.h -conversions.o: $(hdrdir)/ruby/internal/attr/const.h -conversions.o: $(hdrdir)/ruby/internal/attr/constexpr.h -conversions.o: $(hdrdir)/ruby/internal/attr/deprecated.h -conversions.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -conversions.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -conversions.o: $(hdrdir)/ruby/internal/attr/error.h -conversions.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -conversions.o: $(hdrdir)/ruby/internal/attr/forceinline.h -conversions.o: $(hdrdir)/ruby/internal/attr/format.h -conversions.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -conversions.o: $(hdrdir)/ruby/internal/attr/noalias.h -conversions.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -conversions.o: $(hdrdir)/ruby/internal/attr/noexcept.h -conversions.o: $(hdrdir)/ruby/internal/attr/noinline.h -conversions.o: $(hdrdir)/ruby/internal/attr/nonnull.h -conversions.o: $(hdrdir)/ruby/internal/attr/noreturn.h -conversions.o: $(hdrdir)/ruby/internal/attr/pure.h -conversions.o: $(hdrdir)/ruby/internal/attr/restrict.h -conversions.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -conversions.o: $(hdrdir)/ruby/internal/attr/warning.h -conversions.o: $(hdrdir)/ruby/internal/attr/weakref.h -conversions.o: $(hdrdir)/ruby/internal/cast.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -conversions.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -conversions.o: $(hdrdir)/ruby/internal/compiler_since.h -conversions.o: $(hdrdir)/ruby/internal/config.h -conversions.o: $(hdrdir)/ruby/internal/constant_p.h -conversions.o: $(hdrdir)/ruby/internal/core.h -conversions.o: $(hdrdir)/ruby/internal/core/rarray.h -conversions.o: $(hdrdir)/ruby/internal/core/rbasic.h -conversions.o: $(hdrdir)/ruby/internal/core/rbignum.h -conversions.o: $(hdrdir)/ruby/internal/core/rclass.h -conversions.o: $(hdrdir)/ruby/internal/core/rdata.h -conversions.o: $(hdrdir)/ruby/internal/core/rfile.h -conversions.o: $(hdrdir)/ruby/internal/core/rhash.h -conversions.o: $(hdrdir)/ruby/internal/core/robject.h -conversions.o: $(hdrdir)/ruby/internal/core/rregexp.h -conversions.o: $(hdrdir)/ruby/internal/core/rstring.h -conversions.o: $(hdrdir)/ruby/internal/core/rstruct.h -conversions.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -conversions.o: $(hdrdir)/ruby/internal/ctype.h -conversions.o: $(hdrdir)/ruby/internal/dllexport.h -conversions.o: $(hdrdir)/ruby/internal/dosish.h -conversions.o: $(hdrdir)/ruby/internal/error.h -conversions.o: $(hdrdir)/ruby/internal/eval.h -conversions.o: $(hdrdir)/ruby/internal/event.h -conversions.o: $(hdrdir)/ruby/internal/fl_type.h -conversions.o: $(hdrdir)/ruby/internal/gc.h -conversions.o: $(hdrdir)/ruby/internal/glob.h -conversions.o: $(hdrdir)/ruby/internal/globals.h -conversions.o: $(hdrdir)/ruby/internal/has/attribute.h -conversions.o: $(hdrdir)/ruby/internal/has/builtin.h -conversions.o: $(hdrdir)/ruby/internal/has/c_attribute.h -conversions.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -conversions.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -conversions.o: $(hdrdir)/ruby/internal/has/extension.h -conversions.o: $(hdrdir)/ruby/internal/has/feature.h -conversions.o: $(hdrdir)/ruby/internal/has/warning.h -conversions.o: $(hdrdir)/ruby/internal/intern/array.h -conversions.o: $(hdrdir)/ruby/internal/intern/bignum.h -conversions.o: $(hdrdir)/ruby/internal/intern/class.h -conversions.o: $(hdrdir)/ruby/internal/intern/compar.h -conversions.o: $(hdrdir)/ruby/internal/intern/complex.h -conversions.o: $(hdrdir)/ruby/internal/intern/cont.h -conversions.o: $(hdrdir)/ruby/internal/intern/dir.h -conversions.o: $(hdrdir)/ruby/internal/intern/enum.h -conversions.o: $(hdrdir)/ruby/internal/intern/enumerator.h -conversions.o: $(hdrdir)/ruby/internal/intern/error.h -conversions.o: $(hdrdir)/ruby/internal/intern/eval.h -conversions.o: $(hdrdir)/ruby/internal/intern/file.h -conversions.o: $(hdrdir)/ruby/internal/intern/gc.h -conversions.o: $(hdrdir)/ruby/internal/intern/hash.h -conversions.o: $(hdrdir)/ruby/internal/intern/io.h -conversions.o: $(hdrdir)/ruby/internal/intern/load.h -conversions.o: $(hdrdir)/ruby/internal/intern/marshal.h -conversions.o: $(hdrdir)/ruby/internal/intern/numeric.h -conversions.o: $(hdrdir)/ruby/internal/intern/object.h -conversions.o: $(hdrdir)/ruby/internal/intern/parse.h -conversions.o: $(hdrdir)/ruby/internal/intern/proc.h -conversions.o: $(hdrdir)/ruby/internal/intern/process.h -conversions.o: $(hdrdir)/ruby/internal/intern/random.h -conversions.o: $(hdrdir)/ruby/internal/intern/range.h -conversions.o: $(hdrdir)/ruby/internal/intern/rational.h -conversions.o: $(hdrdir)/ruby/internal/intern/re.h -conversions.o: $(hdrdir)/ruby/internal/intern/ruby.h -conversions.o: $(hdrdir)/ruby/internal/intern/select.h -conversions.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -conversions.o: $(hdrdir)/ruby/internal/intern/signal.h -conversions.o: $(hdrdir)/ruby/internal/intern/sprintf.h -conversions.o: $(hdrdir)/ruby/internal/intern/string.h -conversions.o: $(hdrdir)/ruby/internal/intern/struct.h -conversions.o: $(hdrdir)/ruby/internal/intern/thread.h -conversions.o: $(hdrdir)/ruby/internal/intern/time.h -conversions.o: $(hdrdir)/ruby/internal/intern/variable.h -conversions.o: $(hdrdir)/ruby/internal/intern/vm.h -conversions.o: $(hdrdir)/ruby/internal/interpreter.h -conversions.o: $(hdrdir)/ruby/internal/iterator.h -conversions.o: $(hdrdir)/ruby/internal/memory.h -conversions.o: $(hdrdir)/ruby/internal/method.h -conversions.o: $(hdrdir)/ruby/internal/module.h -conversions.o: $(hdrdir)/ruby/internal/newobj.h -conversions.o: $(hdrdir)/ruby/internal/rgengc.h -conversions.o: $(hdrdir)/ruby/internal/scan_args.h -conversions.o: $(hdrdir)/ruby/internal/special_consts.h -conversions.o: $(hdrdir)/ruby/internal/static_assert.h -conversions.o: $(hdrdir)/ruby/internal/stdalign.h -conversions.o: $(hdrdir)/ruby/internal/stdbool.h -conversions.o: $(hdrdir)/ruby/internal/symbol.h -conversions.o: $(hdrdir)/ruby/internal/value.h -conversions.o: $(hdrdir)/ruby/internal/value_type.h -conversions.o: $(hdrdir)/ruby/internal/variable.h -conversions.o: $(hdrdir)/ruby/internal/warning_push.h -conversions.o: $(hdrdir)/ruby/internal/xmalloc.h -conversions.o: $(hdrdir)/ruby/missing.h -conversions.o: $(hdrdir)/ruby/ruby.h -conversions.o: $(hdrdir)/ruby/st.h -conversions.o: $(hdrdir)/ruby/subst.h -conversions.o: closure.h -conversions.o: conversions.c -conversions.o: conversions.h -conversions.o: fiddle.h -conversions.o: function.h -fiddle.o: $(RUBY_EXTCONF_H) -fiddle.o: $(arch_hdrdir)/ruby/config.h -fiddle.o: $(hdrdir)/ruby.h -fiddle.o: $(hdrdir)/ruby/assert.h -fiddle.o: $(hdrdir)/ruby/backward.h -fiddle.o: $(hdrdir)/ruby/backward/2/assume.h -fiddle.o: $(hdrdir)/ruby/backward/2/attributes.h -fiddle.o: $(hdrdir)/ruby/backward/2/bool.h -fiddle.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -fiddle.o: $(hdrdir)/ruby/backward/2/inttypes.h -fiddle.o: $(hdrdir)/ruby/backward/2/limits.h -fiddle.o: $(hdrdir)/ruby/backward/2/long_long.h -fiddle.o: $(hdrdir)/ruby/backward/2/stdalign.h -fiddle.o: $(hdrdir)/ruby/backward/2/stdarg.h -fiddle.o: $(hdrdir)/ruby/defines.h -fiddle.o: $(hdrdir)/ruby/intern.h -fiddle.o: $(hdrdir)/ruby/internal/anyargs.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/char.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/double.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/int.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/long.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/short.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -fiddle.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -fiddle.o: $(hdrdir)/ruby/internal/assume.h -fiddle.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -fiddle.o: $(hdrdir)/ruby/internal/attr/artificial.h -fiddle.o: $(hdrdir)/ruby/internal/attr/cold.h -fiddle.o: $(hdrdir)/ruby/internal/attr/const.h -fiddle.o: $(hdrdir)/ruby/internal/attr/constexpr.h -fiddle.o: $(hdrdir)/ruby/internal/attr/deprecated.h -fiddle.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -fiddle.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -fiddle.o: $(hdrdir)/ruby/internal/attr/error.h -fiddle.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -fiddle.o: $(hdrdir)/ruby/internal/attr/forceinline.h -fiddle.o: $(hdrdir)/ruby/internal/attr/format.h -fiddle.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -fiddle.o: $(hdrdir)/ruby/internal/attr/noalias.h -fiddle.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -fiddle.o: $(hdrdir)/ruby/internal/attr/noexcept.h -fiddle.o: $(hdrdir)/ruby/internal/attr/noinline.h -fiddle.o: $(hdrdir)/ruby/internal/attr/nonnull.h -fiddle.o: $(hdrdir)/ruby/internal/attr/noreturn.h -fiddle.o: $(hdrdir)/ruby/internal/attr/pure.h -fiddle.o: $(hdrdir)/ruby/internal/attr/restrict.h -fiddle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -fiddle.o: $(hdrdir)/ruby/internal/attr/warning.h -fiddle.o: $(hdrdir)/ruby/internal/attr/weakref.h -fiddle.o: $(hdrdir)/ruby/internal/cast.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -fiddle.o: $(hdrdir)/ruby/internal/compiler_since.h -fiddle.o: $(hdrdir)/ruby/internal/config.h -fiddle.o: $(hdrdir)/ruby/internal/constant_p.h -fiddle.o: $(hdrdir)/ruby/internal/core.h -fiddle.o: $(hdrdir)/ruby/internal/core/rarray.h -fiddle.o: $(hdrdir)/ruby/internal/core/rbasic.h -fiddle.o: $(hdrdir)/ruby/internal/core/rbignum.h -fiddle.o: $(hdrdir)/ruby/internal/core/rclass.h -fiddle.o: $(hdrdir)/ruby/internal/core/rdata.h -fiddle.o: $(hdrdir)/ruby/internal/core/rfile.h -fiddle.o: $(hdrdir)/ruby/internal/core/rhash.h -fiddle.o: $(hdrdir)/ruby/internal/core/robject.h -fiddle.o: $(hdrdir)/ruby/internal/core/rregexp.h -fiddle.o: $(hdrdir)/ruby/internal/core/rstring.h -fiddle.o: $(hdrdir)/ruby/internal/core/rstruct.h -fiddle.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -fiddle.o: $(hdrdir)/ruby/internal/ctype.h -fiddle.o: $(hdrdir)/ruby/internal/dllexport.h -fiddle.o: $(hdrdir)/ruby/internal/dosish.h -fiddle.o: $(hdrdir)/ruby/internal/error.h -fiddle.o: $(hdrdir)/ruby/internal/eval.h -fiddle.o: $(hdrdir)/ruby/internal/event.h -fiddle.o: $(hdrdir)/ruby/internal/fl_type.h -fiddle.o: $(hdrdir)/ruby/internal/gc.h -fiddle.o: $(hdrdir)/ruby/internal/glob.h -fiddle.o: $(hdrdir)/ruby/internal/globals.h -fiddle.o: $(hdrdir)/ruby/internal/has/attribute.h -fiddle.o: $(hdrdir)/ruby/internal/has/builtin.h -fiddle.o: $(hdrdir)/ruby/internal/has/c_attribute.h -fiddle.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -fiddle.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -fiddle.o: $(hdrdir)/ruby/internal/has/extension.h -fiddle.o: $(hdrdir)/ruby/internal/has/feature.h -fiddle.o: $(hdrdir)/ruby/internal/has/warning.h -fiddle.o: $(hdrdir)/ruby/internal/intern/array.h -fiddle.o: $(hdrdir)/ruby/internal/intern/bignum.h -fiddle.o: $(hdrdir)/ruby/internal/intern/class.h -fiddle.o: $(hdrdir)/ruby/internal/intern/compar.h -fiddle.o: $(hdrdir)/ruby/internal/intern/complex.h -fiddle.o: $(hdrdir)/ruby/internal/intern/cont.h -fiddle.o: $(hdrdir)/ruby/internal/intern/dir.h -fiddle.o: $(hdrdir)/ruby/internal/intern/enum.h -fiddle.o: $(hdrdir)/ruby/internal/intern/enumerator.h -fiddle.o: $(hdrdir)/ruby/internal/intern/error.h -fiddle.o: $(hdrdir)/ruby/internal/intern/eval.h -fiddle.o: $(hdrdir)/ruby/internal/intern/file.h -fiddle.o: $(hdrdir)/ruby/internal/intern/gc.h -fiddle.o: $(hdrdir)/ruby/internal/intern/hash.h -fiddle.o: $(hdrdir)/ruby/internal/intern/io.h -fiddle.o: $(hdrdir)/ruby/internal/intern/load.h -fiddle.o: $(hdrdir)/ruby/internal/intern/marshal.h -fiddle.o: $(hdrdir)/ruby/internal/intern/numeric.h -fiddle.o: $(hdrdir)/ruby/internal/intern/object.h -fiddle.o: $(hdrdir)/ruby/internal/intern/parse.h -fiddle.o: $(hdrdir)/ruby/internal/intern/proc.h -fiddle.o: $(hdrdir)/ruby/internal/intern/process.h -fiddle.o: $(hdrdir)/ruby/internal/intern/random.h -fiddle.o: $(hdrdir)/ruby/internal/intern/range.h -fiddle.o: $(hdrdir)/ruby/internal/intern/rational.h -fiddle.o: $(hdrdir)/ruby/internal/intern/re.h -fiddle.o: $(hdrdir)/ruby/internal/intern/ruby.h -fiddle.o: $(hdrdir)/ruby/internal/intern/select.h -fiddle.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -fiddle.o: $(hdrdir)/ruby/internal/intern/signal.h -fiddle.o: $(hdrdir)/ruby/internal/intern/sprintf.h -fiddle.o: $(hdrdir)/ruby/internal/intern/string.h -fiddle.o: $(hdrdir)/ruby/internal/intern/struct.h -fiddle.o: $(hdrdir)/ruby/internal/intern/thread.h -fiddle.o: $(hdrdir)/ruby/internal/intern/time.h -fiddle.o: $(hdrdir)/ruby/internal/intern/variable.h -fiddle.o: $(hdrdir)/ruby/internal/intern/vm.h -fiddle.o: $(hdrdir)/ruby/internal/interpreter.h -fiddle.o: $(hdrdir)/ruby/internal/iterator.h -fiddle.o: $(hdrdir)/ruby/internal/memory.h -fiddle.o: $(hdrdir)/ruby/internal/method.h -fiddle.o: $(hdrdir)/ruby/internal/module.h -fiddle.o: $(hdrdir)/ruby/internal/newobj.h -fiddle.o: $(hdrdir)/ruby/internal/rgengc.h -fiddle.o: $(hdrdir)/ruby/internal/scan_args.h -fiddle.o: $(hdrdir)/ruby/internal/special_consts.h -fiddle.o: $(hdrdir)/ruby/internal/static_assert.h -fiddle.o: $(hdrdir)/ruby/internal/stdalign.h -fiddle.o: $(hdrdir)/ruby/internal/stdbool.h -fiddle.o: $(hdrdir)/ruby/internal/symbol.h -fiddle.o: $(hdrdir)/ruby/internal/value.h -fiddle.o: $(hdrdir)/ruby/internal/value_type.h -fiddle.o: $(hdrdir)/ruby/internal/variable.h -fiddle.o: $(hdrdir)/ruby/internal/warning_push.h -fiddle.o: $(hdrdir)/ruby/internal/xmalloc.h -fiddle.o: $(hdrdir)/ruby/missing.h -fiddle.o: $(hdrdir)/ruby/ruby.h -fiddle.o: $(hdrdir)/ruby/st.h -fiddle.o: $(hdrdir)/ruby/subst.h -fiddle.o: closure.h -fiddle.o: conversions.h -fiddle.o: fiddle.c -fiddle.o: fiddle.h -fiddle.o: function.h -function.o: $(RUBY_EXTCONF_H) -function.o: $(arch_hdrdir)/ruby/config.h -function.o: $(hdrdir)/ruby.h -function.o: $(hdrdir)/ruby/assert.h -function.o: $(hdrdir)/ruby/backward.h -function.o: $(hdrdir)/ruby/backward/2/assume.h -function.o: $(hdrdir)/ruby/backward/2/attributes.h -function.o: $(hdrdir)/ruby/backward/2/bool.h -function.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -function.o: $(hdrdir)/ruby/backward/2/inttypes.h -function.o: $(hdrdir)/ruby/backward/2/limits.h -function.o: $(hdrdir)/ruby/backward/2/long_long.h -function.o: $(hdrdir)/ruby/backward/2/stdalign.h -function.o: $(hdrdir)/ruby/backward/2/stdarg.h -function.o: $(hdrdir)/ruby/defines.h -function.o: $(hdrdir)/ruby/intern.h -function.o: $(hdrdir)/ruby/internal/anyargs.h -function.o: $(hdrdir)/ruby/internal/arithmetic.h -function.o: $(hdrdir)/ruby/internal/arithmetic/char.h -function.o: $(hdrdir)/ruby/internal/arithmetic/double.h -function.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -function.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/int.h -function.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/long.h -function.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -function.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/short.h -function.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -function.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -function.o: $(hdrdir)/ruby/internal/assume.h -function.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -function.o: $(hdrdir)/ruby/internal/attr/artificial.h -function.o: $(hdrdir)/ruby/internal/attr/cold.h -function.o: $(hdrdir)/ruby/internal/attr/const.h -function.o: $(hdrdir)/ruby/internal/attr/constexpr.h -function.o: $(hdrdir)/ruby/internal/attr/deprecated.h -function.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -function.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -function.o: $(hdrdir)/ruby/internal/attr/error.h -function.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -function.o: $(hdrdir)/ruby/internal/attr/forceinline.h -function.o: $(hdrdir)/ruby/internal/attr/format.h -function.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -function.o: $(hdrdir)/ruby/internal/attr/noalias.h -function.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -function.o: $(hdrdir)/ruby/internal/attr/noexcept.h -function.o: $(hdrdir)/ruby/internal/attr/noinline.h -function.o: $(hdrdir)/ruby/internal/attr/nonnull.h -function.o: $(hdrdir)/ruby/internal/attr/noreturn.h -function.o: $(hdrdir)/ruby/internal/attr/pure.h -function.o: $(hdrdir)/ruby/internal/attr/restrict.h -function.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -function.o: $(hdrdir)/ruby/internal/attr/warning.h -function.o: $(hdrdir)/ruby/internal/attr/weakref.h -function.o: $(hdrdir)/ruby/internal/cast.h -function.o: $(hdrdir)/ruby/internal/compiler_is.h -function.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -function.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -function.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -function.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -function.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -function.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -function.o: $(hdrdir)/ruby/internal/compiler_since.h -function.o: $(hdrdir)/ruby/internal/config.h -function.o: $(hdrdir)/ruby/internal/constant_p.h -function.o: $(hdrdir)/ruby/internal/core.h -function.o: $(hdrdir)/ruby/internal/core/rarray.h -function.o: $(hdrdir)/ruby/internal/core/rbasic.h -function.o: $(hdrdir)/ruby/internal/core/rbignum.h -function.o: $(hdrdir)/ruby/internal/core/rclass.h -function.o: $(hdrdir)/ruby/internal/core/rdata.h -function.o: $(hdrdir)/ruby/internal/core/rfile.h -function.o: $(hdrdir)/ruby/internal/core/rhash.h -function.o: $(hdrdir)/ruby/internal/core/robject.h -function.o: $(hdrdir)/ruby/internal/core/rregexp.h -function.o: $(hdrdir)/ruby/internal/core/rstring.h -function.o: $(hdrdir)/ruby/internal/core/rstruct.h -function.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -function.o: $(hdrdir)/ruby/internal/ctype.h -function.o: $(hdrdir)/ruby/internal/dllexport.h -function.o: $(hdrdir)/ruby/internal/dosish.h -function.o: $(hdrdir)/ruby/internal/error.h -function.o: $(hdrdir)/ruby/internal/eval.h -function.o: $(hdrdir)/ruby/internal/event.h -function.o: $(hdrdir)/ruby/internal/fl_type.h -function.o: $(hdrdir)/ruby/internal/gc.h -function.o: $(hdrdir)/ruby/internal/glob.h -function.o: $(hdrdir)/ruby/internal/globals.h -function.o: $(hdrdir)/ruby/internal/has/attribute.h -function.o: $(hdrdir)/ruby/internal/has/builtin.h -function.o: $(hdrdir)/ruby/internal/has/c_attribute.h -function.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -function.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -function.o: $(hdrdir)/ruby/internal/has/extension.h -function.o: $(hdrdir)/ruby/internal/has/feature.h -function.o: $(hdrdir)/ruby/internal/has/warning.h -function.o: $(hdrdir)/ruby/internal/intern/array.h -function.o: $(hdrdir)/ruby/internal/intern/bignum.h -function.o: $(hdrdir)/ruby/internal/intern/class.h -function.o: $(hdrdir)/ruby/internal/intern/compar.h -function.o: $(hdrdir)/ruby/internal/intern/complex.h -function.o: $(hdrdir)/ruby/internal/intern/cont.h -function.o: $(hdrdir)/ruby/internal/intern/dir.h -function.o: $(hdrdir)/ruby/internal/intern/enum.h -function.o: $(hdrdir)/ruby/internal/intern/enumerator.h -function.o: $(hdrdir)/ruby/internal/intern/error.h -function.o: $(hdrdir)/ruby/internal/intern/eval.h -function.o: $(hdrdir)/ruby/internal/intern/file.h -function.o: $(hdrdir)/ruby/internal/intern/gc.h -function.o: $(hdrdir)/ruby/internal/intern/hash.h -function.o: $(hdrdir)/ruby/internal/intern/io.h -function.o: $(hdrdir)/ruby/internal/intern/load.h -function.o: $(hdrdir)/ruby/internal/intern/marshal.h -function.o: $(hdrdir)/ruby/internal/intern/numeric.h -function.o: $(hdrdir)/ruby/internal/intern/object.h -function.o: $(hdrdir)/ruby/internal/intern/parse.h -function.o: $(hdrdir)/ruby/internal/intern/proc.h -function.o: $(hdrdir)/ruby/internal/intern/process.h -function.o: $(hdrdir)/ruby/internal/intern/random.h -function.o: $(hdrdir)/ruby/internal/intern/range.h -function.o: $(hdrdir)/ruby/internal/intern/rational.h -function.o: $(hdrdir)/ruby/internal/intern/re.h -function.o: $(hdrdir)/ruby/internal/intern/ruby.h -function.o: $(hdrdir)/ruby/internal/intern/select.h -function.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -function.o: $(hdrdir)/ruby/internal/intern/signal.h -function.o: $(hdrdir)/ruby/internal/intern/sprintf.h -function.o: $(hdrdir)/ruby/internal/intern/string.h -function.o: $(hdrdir)/ruby/internal/intern/struct.h -function.o: $(hdrdir)/ruby/internal/intern/thread.h -function.o: $(hdrdir)/ruby/internal/intern/time.h -function.o: $(hdrdir)/ruby/internal/intern/variable.h -function.o: $(hdrdir)/ruby/internal/intern/vm.h -function.o: $(hdrdir)/ruby/internal/interpreter.h -function.o: $(hdrdir)/ruby/internal/iterator.h -function.o: $(hdrdir)/ruby/internal/memory.h -function.o: $(hdrdir)/ruby/internal/method.h -function.o: $(hdrdir)/ruby/internal/module.h -function.o: $(hdrdir)/ruby/internal/newobj.h -function.o: $(hdrdir)/ruby/internal/rgengc.h -function.o: $(hdrdir)/ruby/internal/scan_args.h -function.o: $(hdrdir)/ruby/internal/special_consts.h -function.o: $(hdrdir)/ruby/internal/static_assert.h -function.o: $(hdrdir)/ruby/internal/stdalign.h -function.o: $(hdrdir)/ruby/internal/stdbool.h -function.o: $(hdrdir)/ruby/internal/symbol.h -function.o: $(hdrdir)/ruby/internal/value.h -function.o: $(hdrdir)/ruby/internal/value_type.h -function.o: $(hdrdir)/ruby/internal/variable.h -function.o: $(hdrdir)/ruby/internal/warning_push.h -function.o: $(hdrdir)/ruby/internal/xmalloc.h -function.o: $(hdrdir)/ruby/missing.h -function.o: $(hdrdir)/ruby/ruby.h -function.o: $(hdrdir)/ruby/st.h -function.o: $(hdrdir)/ruby/subst.h -function.o: $(hdrdir)/ruby/thread.h -function.o: closure.h -function.o: conversions.h -function.o: fiddle.h -function.o: function.c -function.o: function.h -handle.o: $(RUBY_EXTCONF_H) -handle.o: $(arch_hdrdir)/ruby/config.h -handle.o: $(hdrdir)/ruby.h -handle.o: $(hdrdir)/ruby/assert.h -handle.o: $(hdrdir)/ruby/backward.h -handle.o: $(hdrdir)/ruby/backward/2/assume.h -handle.o: $(hdrdir)/ruby/backward/2/attributes.h -handle.o: $(hdrdir)/ruby/backward/2/bool.h -handle.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -handle.o: $(hdrdir)/ruby/backward/2/inttypes.h -handle.o: $(hdrdir)/ruby/backward/2/limits.h -handle.o: $(hdrdir)/ruby/backward/2/long_long.h -handle.o: $(hdrdir)/ruby/backward/2/stdalign.h -handle.o: $(hdrdir)/ruby/backward/2/stdarg.h -handle.o: $(hdrdir)/ruby/defines.h -handle.o: $(hdrdir)/ruby/intern.h -handle.o: $(hdrdir)/ruby/internal/anyargs.h -handle.o: $(hdrdir)/ruby/internal/arithmetic.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/char.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/double.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/int.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/long.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/short.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -handle.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -handle.o: $(hdrdir)/ruby/internal/assume.h -handle.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -handle.o: $(hdrdir)/ruby/internal/attr/artificial.h -handle.o: $(hdrdir)/ruby/internal/attr/cold.h -handle.o: $(hdrdir)/ruby/internal/attr/const.h -handle.o: $(hdrdir)/ruby/internal/attr/constexpr.h -handle.o: $(hdrdir)/ruby/internal/attr/deprecated.h -handle.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -handle.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -handle.o: $(hdrdir)/ruby/internal/attr/error.h -handle.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -handle.o: $(hdrdir)/ruby/internal/attr/forceinline.h -handle.o: $(hdrdir)/ruby/internal/attr/format.h -handle.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -handle.o: $(hdrdir)/ruby/internal/attr/noalias.h -handle.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -handle.o: $(hdrdir)/ruby/internal/attr/noexcept.h -handle.o: $(hdrdir)/ruby/internal/attr/noinline.h -handle.o: $(hdrdir)/ruby/internal/attr/nonnull.h -handle.o: $(hdrdir)/ruby/internal/attr/noreturn.h -handle.o: $(hdrdir)/ruby/internal/attr/pure.h -handle.o: $(hdrdir)/ruby/internal/attr/restrict.h -handle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -handle.o: $(hdrdir)/ruby/internal/attr/warning.h -handle.o: $(hdrdir)/ruby/internal/attr/weakref.h -handle.o: $(hdrdir)/ruby/internal/cast.h -handle.o: $(hdrdir)/ruby/internal/compiler_is.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -handle.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -handle.o: $(hdrdir)/ruby/internal/compiler_since.h -handle.o: $(hdrdir)/ruby/internal/config.h -handle.o: $(hdrdir)/ruby/internal/constant_p.h -handle.o: $(hdrdir)/ruby/internal/core.h -handle.o: $(hdrdir)/ruby/internal/core/rarray.h -handle.o: $(hdrdir)/ruby/internal/core/rbasic.h -handle.o: $(hdrdir)/ruby/internal/core/rbignum.h -handle.o: $(hdrdir)/ruby/internal/core/rclass.h -handle.o: $(hdrdir)/ruby/internal/core/rdata.h -handle.o: $(hdrdir)/ruby/internal/core/rfile.h -handle.o: $(hdrdir)/ruby/internal/core/rhash.h -handle.o: $(hdrdir)/ruby/internal/core/robject.h -handle.o: $(hdrdir)/ruby/internal/core/rregexp.h -handle.o: $(hdrdir)/ruby/internal/core/rstring.h -handle.o: $(hdrdir)/ruby/internal/core/rstruct.h -handle.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -handle.o: $(hdrdir)/ruby/internal/ctype.h -handle.o: $(hdrdir)/ruby/internal/dllexport.h -handle.o: $(hdrdir)/ruby/internal/dosish.h -handle.o: $(hdrdir)/ruby/internal/error.h -handle.o: $(hdrdir)/ruby/internal/eval.h -handle.o: $(hdrdir)/ruby/internal/event.h -handle.o: $(hdrdir)/ruby/internal/fl_type.h -handle.o: $(hdrdir)/ruby/internal/gc.h -handle.o: $(hdrdir)/ruby/internal/glob.h -handle.o: $(hdrdir)/ruby/internal/globals.h -handle.o: $(hdrdir)/ruby/internal/has/attribute.h -handle.o: $(hdrdir)/ruby/internal/has/builtin.h -handle.o: $(hdrdir)/ruby/internal/has/c_attribute.h -handle.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -handle.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -handle.o: $(hdrdir)/ruby/internal/has/extension.h -handle.o: $(hdrdir)/ruby/internal/has/feature.h -handle.o: $(hdrdir)/ruby/internal/has/warning.h -handle.o: $(hdrdir)/ruby/internal/intern/array.h -handle.o: $(hdrdir)/ruby/internal/intern/bignum.h -handle.o: $(hdrdir)/ruby/internal/intern/class.h -handle.o: $(hdrdir)/ruby/internal/intern/compar.h -handle.o: $(hdrdir)/ruby/internal/intern/complex.h -handle.o: $(hdrdir)/ruby/internal/intern/cont.h -handle.o: $(hdrdir)/ruby/internal/intern/dir.h -handle.o: $(hdrdir)/ruby/internal/intern/enum.h -handle.o: $(hdrdir)/ruby/internal/intern/enumerator.h -handle.o: $(hdrdir)/ruby/internal/intern/error.h -handle.o: $(hdrdir)/ruby/internal/intern/eval.h -handle.o: $(hdrdir)/ruby/internal/intern/file.h -handle.o: $(hdrdir)/ruby/internal/intern/gc.h -handle.o: $(hdrdir)/ruby/internal/intern/hash.h -handle.o: $(hdrdir)/ruby/internal/intern/io.h -handle.o: $(hdrdir)/ruby/internal/intern/load.h -handle.o: $(hdrdir)/ruby/internal/intern/marshal.h -handle.o: $(hdrdir)/ruby/internal/intern/numeric.h -handle.o: $(hdrdir)/ruby/internal/intern/object.h -handle.o: $(hdrdir)/ruby/internal/intern/parse.h -handle.o: $(hdrdir)/ruby/internal/intern/proc.h -handle.o: $(hdrdir)/ruby/internal/intern/process.h -handle.o: $(hdrdir)/ruby/internal/intern/random.h -handle.o: $(hdrdir)/ruby/internal/intern/range.h -handle.o: $(hdrdir)/ruby/internal/intern/rational.h -handle.o: $(hdrdir)/ruby/internal/intern/re.h -handle.o: $(hdrdir)/ruby/internal/intern/ruby.h -handle.o: $(hdrdir)/ruby/internal/intern/select.h -handle.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -handle.o: $(hdrdir)/ruby/internal/intern/signal.h -handle.o: $(hdrdir)/ruby/internal/intern/sprintf.h -handle.o: $(hdrdir)/ruby/internal/intern/string.h -handle.o: $(hdrdir)/ruby/internal/intern/struct.h -handle.o: $(hdrdir)/ruby/internal/intern/thread.h -handle.o: $(hdrdir)/ruby/internal/intern/time.h -handle.o: $(hdrdir)/ruby/internal/intern/variable.h -handle.o: $(hdrdir)/ruby/internal/intern/vm.h -handle.o: $(hdrdir)/ruby/internal/interpreter.h -handle.o: $(hdrdir)/ruby/internal/iterator.h -handle.o: $(hdrdir)/ruby/internal/memory.h -handle.o: $(hdrdir)/ruby/internal/method.h -handle.o: $(hdrdir)/ruby/internal/module.h -handle.o: $(hdrdir)/ruby/internal/newobj.h -handle.o: $(hdrdir)/ruby/internal/rgengc.h -handle.o: $(hdrdir)/ruby/internal/scan_args.h -handle.o: $(hdrdir)/ruby/internal/special_consts.h -handle.o: $(hdrdir)/ruby/internal/static_assert.h -handle.o: $(hdrdir)/ruby/internal/stdalign.h -handle.o: $(hdrdir)/ruby/internal/stdbool.h -handle.o: $(hdrdir)/ruby/internal/symbol.h -handle.o: $(hdrdir)/ruby/internal/value.h -handle.o: $(hdrdir)/ruby/internal/value_type.h -handle.o: $(hdrdir)/ruby/internal/variable.h -handle.o: $(hdrdir)/ruby/internal/warning_push.h -handle.o: $(hdrdir)/ruby/internal/xmalloc.h -handle.o: $(hdrdir)/ruby/missing.h -handle.o: $(hdrdir)/ruby/ruby.h -handle.o: $(hdrdir)/ruby/st.h -handle.o: $(hdrdir)/ruby/subst.h -handle.o: closure.h -handle.o: conversions.h -handle.o: fiddle.h -handle.o: function.h -handle.o: handle.c -memory_view.o: $(RUBY_EXTCONF_H) -memory_view.o: $(arch_hdrdir)/ruby/config.h -memory_view.o: $(hdrdir)/ruby.h -memory_view.o: $(hdrdir)/ruby/assert.h -memory_view.o: $(hdrdir)/ruby/backward.h -memory_view.o: $(hdrdir)/ruby/backward/2/assume.h -memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h -memory_view.o: $(hdrdir)/ruby/backward/2/bool.h -memory_view.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h -memory_view.o: $(hdrdir)/ruby/backward/2/limits.h -memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h -memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h -memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h -memory_view.o: $(hdrdir)/ruby/defines.h -memory_view.o: $(hdrdir)/ruby/encoding.h -memory_view.o: $(hdrdir)/ruby/intern.h -memory_view.o: $(hdrdir)/ruby/internal/anyargs.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/double.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/int.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/short.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -memory_view.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -memory_view.o: $(hdrdir)/ruby/internal/assume.h -memory_view.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -memory_view.o: $(hdrdir)/ruby/internal/attr/artificial.h -memory_view.o: $(hdrdir)/ruby/internal/attr/cold.h -memory_view.o: $(hdrdir)/ruby/internal/attr/const.h -memory_view.o: $(hdrdir)/ruby/internal/attr/constexpr.h -memory_view.o: $(hdrdir)/ruby/internal/attr/deprecated.h -memory_view.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -memory_view.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -memory_view.o: $(hdrdir)/ruby/internal/attr/error.h -memory_view.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -memory_view.o: $(hdrdir)/ruby/internal/attr/forceinline.h -memory_view.o: $(hdrdir)/ruby/internal/attr/format.h -memory_view.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -memory_view.o: $(hdrdir)/ruby/internal/attr/noalias.h -memory_view.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h -memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h -memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h -memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h -memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h -memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h -memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -memory_view.o: $(hdrdir)/ruby/internal/attr/warning.h -memory_view.o: $(hdrdir)/ruby/internal/attr/weakref.h -memory_view.o: $(hdrdir)/ruby/internal/cast.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -memory_view.o: $(hdrdir)/ruby/internal/compiler_since.h -memory_view.o: $(hdrdir)/ruby/internal/config.h -memory_view.o: $(hdrdir)/ruby/internal/constant_p.h -memory_view.o: $(hdrdir)/ruby/internal/core.h -memory_view.o: $(hdrdir)/ruby/internal/core/rarray.h -memory_view.o: $(hdrdir)/ruby/internal/core/rbasic.h -memory_view.o: $(hdrdir)/ruby/internal/core/rbignum.h -memory_view.o: $(hdrdir)/ruby/internal/core/rclass.h -memory_view.o: $(hdrdir)/ruby/internal/core/rdata.h -memory_view.o: $(hdrdir)/ruby/internal/core/rfile.h -memory_view.o: $(hdrdir)/ruby/internal/core/rhash.h -memory_view.o: $(hdrdir)/ruby/internal/core/robject.h -memory_view.o: $(hdrdir)/ruby/internal/core/rregexp.h -memory_view.o: $(hdrdir)/ruby/internal/core/rstring.h -memory_view.o: $(hdrdir)/ruby/internal/core/rstruct.h -memory_view.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -memory_view.o: $(hdrdir)/ruby/internal/ctype.h -memory_view.o: $(hdrdir)/ruby/internal/dllexport.h -memory_view.o: $(hdrdir)/ruby/internal/dosish.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/coderange.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/ctype.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/encoding.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/pathname.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/re.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/sprintf.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/string.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/symbol.h -memory_view.o: $(hdrdir)/ruby/internal/encoding/transcode.h -memory_view.o: $(hdrdir)/ruby/internal/error.h -memory_view.o: $(hdrdir)/ruby/internal/eval.h -memory_view.o: $(hdrdir)/ruby/internal/event.h -memory_view.o: $(hdrdir)/ruby/internal/fl_type.h -memory_view.o: $(hdrdir)/ruby/internal/gc.h -memory_view.o: $(hdrdir)/ruby/internal/glob.h -memory_view.o: $(hdrdir)/ruby/internal/globals.h -memory_view.o: $(hdrdir)/ruby/internal/has/attribute.h -memory_view.o: $(hdrdir)/ruby/internal/has/builtin.h -memory_view.o: $(hdrdir)/ruby/internal/has/c_attribute.h -memory_view.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -memory_view.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -memory_view.o: $(hdrdir)/ruby/internal/has/extension.h -memory_view.o: $(hdrdir)/ruby/internal/has/feature.h -memory_view.o: $(hdrdir)/ruby/internal/has/warning.h -memory_view.o: $(hdrdir)/ruby/internal/intern/array.h -memory_view.o: $(hdrdir)/ruby/internal/intern/bignum.h -memory_view.o: $(hdrdir)/ruby/internal/intern/class.h -memory_view.o: $(hdrdir)/ruby/internal/intern/compar.h -memory_view.o: $(hdrdir)/ruby/internal/intern/complex.h -memory_view.o: $(hdrdir)/ruby/internal/intern/cont.h -memory_view.o: $(hdrdir)/ruby/internal/intern/dir.h -memory_view.o: $(hdrdir)/ruby/internal/intern/enum.h -memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h -memory_view.o: $(hdrdir)/ruby/internal/intern/error.h -memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h -memory_view.o: $(hdrdir)/ruby/internal/intern/file.h -memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h -memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h -memory_view.o: $(hdrdir)/ruby/internal/intern/io.h -memory_view.o: $(hdrdir)/ruby/internal/intern/load.h -memory_view.o: $(hdrdir)/ruby/internal/intern/marshal.h -memory_view.o: $(hdrdir)/ruby/internal/intern/numeric.h -memory_view.o: $(hdrdir)/ruby/internal/intern/object.h -memory_view.o: $(hdrdir)/ruby/internal/intern/parse.h -memory_view.o: $(hdrdir)/ruby/internal/intern/proc.h -memory_view.o: $(hdrdir)/ruby/internal/intern/process.h -memory_view.o: $(hdrdir)/ruby/internal/intern/random.h -memory_view.o: $(hdrdir)/ruby/internal/intern/range.h -memory_view.o: $(hdrdir)/ruby/internal/intern/rational.h -memory_view.o: $(hdrdir)/ruby/internal/intern/re.h -memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h -memory_view.o: $(hdrdir)/ruby/internal/intern/select.h -memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h -memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h -memory_view.o: $(hdrdir)/ruby/internal/intern/string.h -memory_view.o: $(hdrdir)/ruby/internal/intern/struct.h -memory_view.o: $(hdrdir)/ruby/internal/intern/thread.h -memory_view.o: $(hdrdir)/ruby/internal/intern/time.h -memory_view.o: $(hdrdir)/ruby/internal/intern/variable.h -memory_view.o: $(hdrdir)/ruby/internal/intern/vm.h -memory_view.o: $(hdrdir)/ruby/internal/interpreter.h -memory_view.o: $(hdrdir)/ruby/internal/iterator.h -memory_view.o: $(hdrdir)/ruby/internal/memory.h -memory_view.o: $(hdrdir)/ruby/internal/method.h -memory_view.o: $(hdrdir)/ruby/internal/module.h -memory_view.o: $(hdrdir)/ruby/internal/newobj.h -memory_view.o: $(hdrdir)/ruby/internal/rgengc.h -memory_view.o: $(hdrdir)/ruby/internal/scan_args.h -memory_view.o: $(hdrdir)/ruby/internal/special_consts.h -memory_view.o: $(hdrdir)/ruby/internal/static_assert.h -memory_view.o: $(hdrdir)/ruby/internal/stdalign.h -memory_view.o: $(hdrdir)/ruby/internal/stdbool.h -memory_view.o: $(hdrdir)/ruby/internal/symbol.h -memory_view.o: $(hdrdir)/ruby/internal/value.h -memory_view.o: $(hdrdir)/ruby/internal/value_type.h -memory_view.o: $(hdrdir)/ruby/internal/variable.h -memory_view.o: $(hdrdir)/ruby/internal/warning_push.h -memory_view.o: $(hdrdir)/ruby/internal/xmalloc.h -memory_view.o: $(hdrdir)/ruby/memory_view.h -memory_view.o: $(hdrdir)/ruby/missing.h -memory_view.o: $(hdrdir)/ruby/onigmo.h -memory_view.o: $(hdrdir)/ruby/oniguruma.h -memory_view.o: $(hdrdir)/ruby/ruby.h -memory_view.o: $(hdrdir)/ruby/st.h -memory_view.o: $(hdrdir)/ruby/subst.h -memory_view.o: closure.h -memory_view.o: conversions.h -memory_view.o: fiddle.h -memory_view.o: function.h -memory_view.o: memory_view.c -pinned.o: $(RUBY_EXTCONF_H) -pinned.o: $(arch_hdrdir)/ruby/config.h -pinned.o: $(hdrdir)/ruby.h -pinned.o: $(hdrdir)/ruby/assert.h -pinned.o: $(hdrdir)/ruby/backward.h -pinned.o: $(hdrdir)/ruby/backward/2/assume.h -pinned.o: $(hdrdir)/ruby/backward/2/attributes.h -pinned.o: $(hdrdir)/ruby/backward/2/bool.h -pinned.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -pinned.o: $(hdrdir)/ruby/backward/2/inttypes.h -pinned.o: $(hdrdir)/ruby/backward/2/limits.h -pinned.o: $(hdrdir)/ruby/backward/2/long_long.h -pinned.o: $(hdrdir)/ruby/backward/2/stdalign.h -pinned.o: $(hdrdir)/ruby/backward/2/stdarg.h -pinned.o: $(hdrdir)/ruby/defines.h -pinned.o: $(hdrdir)/ruby/intern.h -pinned.o: $(hdrdir)/ruby/internal/anyargs.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/char.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/double.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/int.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/long.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/short.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -pinned.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -pinned.o: $(hdrdir)/ruby/internal/assume.h -pinned.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -pinned.o: $(hdrdir)/ruby/internal/attr/artificial.h -pinned.o: $(hdrdir)/ruby/internal/attr/cold.h -pinned.o: $(hdrdir)/ruby/internal/attr/const.h -pinned.o: $(hdrdir)/ruby/internal/attr/constexpr.h -pinned.o: $(hdrdir)/ruby/internal/attr/deprecated.h -pinned.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -pinned.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -pinned.o: $(hdrdir)/ruby/internal/attr/error.h -pinned.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -pinned.o: $(hdrdir)/ruby/internal/attr/forceinline.h -pinned.o: $(hdrdir)/ruby/internal/attr/format.h -pinned.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -pinned.o: $(hdrdir)/ruby/internal/attr/noalias.h -pinned.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -pinned.o: $(hdrdir)/ruby/internal/attr/noexcept.h -pinned.o: $(hdrdir)/ruby/internal/attr/noinline.h -pinned.o: $(hdrdir)/ruby/internal/attr/nonnull.h -pinned.o: $(hdrdir)/ruby/internal/attr/noreturn.h -pinned.o: $(hdrdir)/ruby/internal/attr/pure.h -pinned.o: $(hdrdir)/ruby/internal/attr/restrict.h -pinned.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -pinned.o: $(hdrdir)/ruby/internal/attr/warning.h -pinned.o: $(hdrdir)/ruby/internal/attr/weakref.h -pinned.o: $(hdrdir)/ruby/internal/cast.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -pinned.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -pinned.o: $(hdrdir)/ruby/internal/compiler_since.h -pinned.o: $(hdrdir)/ruby/internal/config.h -pinned.o: $(hdrdir)/ruby/internal/constant_p.h -pinned.o: $(hdrdir)/ruby/internal/core.h -pinned.o: $(hdrdir)/ruby/internal/core/rarray.h -pinned.o: $(hdrdir)/ruby/internal/core/rbasic.h -pinned.o: $(hdrdir)/ruby/internal/core/rbignum.h -pinned.o: $(hdrdir)/ruby/internal/core/rclass.h -pinned.o: $(hdrdir)/ruby/internal/core/rdata.h -pinned.o: $(hdrdir)/ruby/internal/core/rfile.h -pinned.o: $(hdrdir)/ruby/internal/core/rhash.h -pinned.o: $(hdrdir)/ruby/internal/core/robject.h -pinned.o: $(hdrdir)/ruby/internal/core/rregexp.h -pinned.o: $(hdrdir)/ruby/internal/core/rstring.h -pinned.o: $(hdrdir)/ruby/internal/core/rstruct.h -pinned.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -pinned.o: $(hdrdir)/ruby/internal/ctype.h -pinned.o: $(hdrdir)/ruby/internal/dllexport.h -pinned.o: $(hdrdir)/ruby/internal/dosish.h -pinned.o: $(hdrdir)/ruby/internal/error.h -pinned.o: $(hdrdir)/ruby/internal/eval.h -pinned.o: $(hdrdir)/ruby/internal/event.h -pinned.o: $(hdrdir)/ruby/internal/fl_type.h -pinned.o: $(hdrdir)/ruby/internal/gc.h -pinned.o: $(hdrdir)/ruby/internal/glob.h -pinned.o: $(hdrdir)/ruby/internal/globals.h -pinned.o: $(hdrdir)/ruby/internal/has/attribute.h -pinned.o: $(hdrdir)/ruby/internal/has/builtin.h -pinned.o: $(hdrdir)/ruby/internal/has/c_attribute.h -pinned.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -pinned.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -pinned.o: $(hdrdir)/ruby/internal/has/extension.h -pinned.o: $(hdrdir)/ruby/internal/has/feature.h -pinned.o: $(hdrdir)/ruby/internal/has/warning.h -pinned.o: $(hdrdir)/ruby/internal/intern/array.h -pinned.o: $(hdrdir)/ruby/internal/intern/bignum.h -pinned.o: $(hdrdir)/ruby/internal/intern/class.h -pinned.o: $(hdrdir)/ruby/internal/intern/compar.h -pinned.o: $(hdrdir)/ruby/internal/intern/complex.h -pinned.o: $(hdrdir)/ruby/internal/intern/cont.h -pinned.o: $(hdrdir)/ruby/internal/intern/dir.h -pinned.o: $(hdrdir)/ruby/internal/intern/enum.h -pinned.o: $(hdrdir)/ruby/internal/intern/enumerator.h -pinned.o: $(hdrdir)/ruby/internal/intern/error.h -pinned.o: $(hdrdir)/ruby/internal/intern/eval.h -pinned.o: $(hdrdir)/ruby/internal/intern/file.h -pinned.o: $(hdrdir)/ruby/internal/intern/gc.h -pinned.o: $(hdrdir)/ruby/internal/intern/hash.h -pinned.o: $(hdrdir)/ruby/internal/intern/io.h -pinned.o: $(hdrdir)/ruby/internal/intern/load.h -pinned.o: $(hdrdir)/ruby/internal/intern/marshal.h -pinned.o: $(hdrdir)/ruby/internal/intern/numeric.h -pinned.o: $(hdrdir)/ruby/internal/intern/object.h -pinned.o: $(hdrdir)/ruby/internal/intern/parse.h -pinned.o: $(hdrdir)/ruby/internal/intern/proc.h -pinned.o: $(hdrdir)/ruby/internal/intern/process.h -pinned.o: $(hdrdir)/ruby/internal/intern/random.h -pinned.o: $(hdrdir)/ruby/internal/intern/range.h -pinned.o: $(hdrdir)/ruby/internal/intern/rational.h -pinned.o: $(hdrdir)/ruby/internal/intern/re.h -pinned.o: $(hdrdir)/ruby/internal/intern/ruby.h -pinned.o: $(hdrdir)/ruby/internal/intern/select.h -pinned.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -pinned.o: $(hdrdir)/ruby/internal/intern/signal.h -pinned.o: $(hdrdir)/ruby/internal/intern/sprintf.h -pinned.o: $(hdrdir)/ruby/internal/intern/string.h -pinned.o: $(hdrdir)/ruby/internal/intern/struct.h -pinned.o: $(hdrdir)/ruby/internal/intern/thread.h -pinned.o: $(hdrdir)/ruby/internal/intern/time.h -pinned.o: $(hdrdir)/ruby/internal/intern/variable.h -pinned.o: $(hdrdir)/ruby/internal/intern/vm.h -pinned.o: $(hdrdir)/ruby/internal/interpreter.h -pinned.o: $(hdrdir)/ruby/internal/iterator.h -pinned.o: $(hdrdir)/ruby/internal/memory.h -pinned.o: $(hdrdir)/ruby/internal/method.h -pinned.o: $(hdrdir)/ruby/internal/module.h -pinned.o: $(hdrdir)/ruby/internal/newobj.h -pinned.o: $(hdrdir)/ruby/internal/rgengc.h -pinned.o: $(hdrdir)/ruby/internal/scan_args.h -pinned.o: $(hdrdir)/ruby/internal/special_consts.h -pinned.o: $(hdrdir)/ruby/internal/static_assert.h -pinned.o: $(hdrdir)/ruby/internal/stdalign.h -pinned.o: $(hdrdir)/ruby/internal/stdbool.h -pinned.o: $(hdrdir)/ruby/internal/symbol.h -pinned.o: $(hdrdir)/ruby/internal/value.h -pinned.o: $(hdrdir)/ruby/internal/value_type.h -pinned.o: $(hdrdir)/ruby/internal/variable.h -pinned.o: $(hdrdir)/ruby/internal/warning_push.h -pinned.o: $(hdrdir)/ruby/internal/xmalloc.h -pinned.o: $(hdrdir)/ruby/missing.h -pinned.o: $(hdrdir)/ruby/ruby.h -pinned.o: $(hdrdir)/ruby/st.h -pinned.o: $(hdrdir)/ruby/subst.h -pinned.o: closure.h -pinned.o: conversions.h -pinned.o: fiddle.h -pinned.o: function.h -pinned.o: pinned.c -pointer.o: $(RUBY_EXTCONF_H) -pointer.o: $(arch_hdrdir)/ruby/config.h -pointer.o: $(hdrdir)/ruby.h -pointer.o: $(hdrdir)/ruby/assert.h -pointer.o: $(hdrdir)/ruby/backward.h -pointer.o: $(hdrdir)/ruby/backward/2/assume.h -pointer.o: $(hdrdir)/ruby/backward/2/attributes.h -pointer.o: $(hdrdir)/ruby/backward/2/bool.h -pointer.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -pointer.o: $(hdrdir)/ruby/backward/2/inttypes.h -pointer.o: $(hdrdir)/ruby/backward/2/limits.h -pointer.o: $(hdrdir)/ruby/backward/2/long_long.h -pointer.o: $(hdrdir)/ruby/backward/2/stdalign.h -pointer.o: $(hdrdir)/ruby/backward/2/stdarg.h -pointer.o: $(hdrdir)/ruby/defines.h -pointer.o: $(hdrdir)/ruby/encoding.h -pointer.o: $(hdrdir)/ruby/intern.h -pointer.o: $(hdrdir)/ruby/internal/anyargs.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/char.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/double.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/int.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/long.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/short.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -pointer.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -pointer.o: $(hdrdir)/ruby/internal/assume.h -pointer.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -pointer.o: $(hdrdir)/ruby/internal/attr/artificial.h -pointer.o: $(hdrdir)/ruby/internal/attr/cold.h -pointer.o: $(hdrdir)/ruby/internal/attr/const.h -pointer.o: $(hdrdir)/ruby/internal/attr/constexpr.h -pointer.o: $(hdrdir)/ruby/internal/attr/deprecated.h -pointer.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -pointer.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -pointer.o: $(hdrdir)/ruby/internal/attr/error.h -pointer.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -pointer.o: $(hdrdir)/ruby/internal/attr/forceinline.h -pointer.o: $(hdrdir)/ruby/internal/attr/format.h -pointer.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -pointer.o: $(hdrdir)/ruby/internal/attr/noalias.h -pointer.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -pointer.o: $(hdrdir)/ruby/internal/attr/noexcept.h -pointer.o: $(hdrdir)/ruby/internal/attr/noinline.h -pointer.o: $(hdrdir)/ruby/internal/attr/nonnull.h -pointer.o: $(hdrdir)/ruby/internal/attr/noreturn.h -pointer.o: $(hdrdir)/ruby/internal/attr/pure.h -pointer.o: $(hdrdir)/ruby/internal/attr/restrict.h -pointer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -pointer.o: $(hdrdir)/ruby/internal/attr/warning.h -pointer.o: $(hdrdir)/ruby/internal/attr/weakref.h -pointer.o: $(hdrdir)/ruby/internal/cast.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -pointer.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -pointer.o: $(hdrdir)/ruby/internal/compiler_since.h -pointer.o: $(hdrdir)/ruby/internal/config.h -pointer.o: $(hdrdir)/ruby/internal/constant_p.h -pointer.o: $(hdrdir)/ruby/internal/core.h -pointer.o: $(hdrdir)/ruby/internal/core/rarray.h -pointer.o: $(hdrdir)/ruby/internal/core/rbasic.h -pointer.o: $(hdrdir)/ruby/internal/core/rbignum.h -pointer.o: $(hdrdir)/ruby/internal/core/rclass.h -pointer.o: $(hdrdir)/ruby/internal/core/rdata.h -pointer.o: $(hdrdir)/ruby/internal/core/rfile.h -pointer.o: $(hdrdir)/ruby/internal/core/rhash.h -pointer.o: $(hdrdir)/ruby/internal/core/robject.h -pointer.o: $(hdrdir)/ruby/internal/core/rregexp.h -pointer.o: $(hdrdir)/ruby/internal/core/rstring.h -pointer.o: $(hdrdir)/ruby/internal/core/rstruct.h -pointer.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -pointer.o: $(hdrdir)/ruby/internal/ctype.h -pointer.o: $(hdrdir)/ruby/internal/dllexport.h -pointer.o: $(hdrdir)/ruby/internal/dosish.h -pointer.o: $(hdrdir)/ruby/internal/encoding/coderange.h -pointer.o: $(hdrdir)/ruby/internal/encoding/ctype.h -pointer.o: $(hdrdir)/ruby/internal/encoding/encoding.h -pointer.o: $(hdrdir)/ruby/internal/encoding/pathname.h -pointer.o: $(hdrdir)/ruby/internal/encoding/re.h -pointer.o: $(hdrdir)/ruby/internal/encoding/sprintf.h -pointer.o: $(hdrdir)/ruby/internal/encoding/string.h -pointer.o: $(hdrdir)/ruby/internal/encoding/symbol.h -pointer.o: $(hdrdir)/ruby/internal/encoding/transcode.h -pointer.o: $(hdrdir)/ruby/internal/error.h -pointer.o: $(hdrdir)/ruby/internal/eval.h -pointer.o: $(hdrdir)/ruby/internal/event.h -pointer.o: $(hdrdir)/ruby/internal/fl_type.h -pointer.o: $(hdrdir)/ruby/internal/gc.h -pointer.o: $(hdrdir)/ruby/internal/glob.h -pointer.o: $(hdrdir)/ruby/internal/globals.h -pointer.o: $(hdrdir)/ruby/internal/has/attribute.h -pointer.o: $(hdrdir)/ruby/internal/has/builtin.h -pointer.o: $(hdrdir)/ruby/internal/has/c_attribute.h -pointer.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -pointer.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -pointer.o: $(hdrdir)/ruby/internal/has/extension.h -pointer.o: $(hdrdir)/ruby/internal/has/feature.h -pointer.o: $(hdrdir)/ruby/internal/has/warning.h -pointer.o: $(hdrdir)/ruby/internal/intern/array.h -pointer.o: $(hdrdir)/ruby/internal/intern/bignum.h -pointer.o: $(hdrdir)/ruby/internal/intern/class.h -pointer.o: $(hdrdir)/ruby/internal/intern/compar.h -pointer.o: $(hdrdir)/ruby/internal/intern/complex.h -pointer.o: $(hdrdir)/ruby/internal/intern/cont.h -pointer.o: $(hdrdir)/ruby/internal/intern/dir.h -pointer.o: $(hdrdir)/ruby/internal/intern/enum.h -pointer.o: $(hdrdir)/ruby/internal/intern/enumerator.h -pointer.o: $(hdrdir)/ruby/internal/intern/error.h -pointer.o: $(hdrdir)/ruby/internal/intern/eval.h -pointer.o: $(hdrdir)/ruby/internal/intern/file.h -pointer.o: $(hdrdir)/ruby/internal/intern/gc.h -pointer.o: $(hdrdir)/ruby/internal/intern/hash.h -pointer.o: $(hdrdir)/ruby/internal/intern/io.h -pointer.o: $(hdrdir)/ruby/internal/intern/load.h -pointer.o: $(hdrdir)/ruby/internal/intern/marshal.h -pointer.o: $(hdrdir)/ruby/internal/intern/numeric.h -pointer.o: $(hdrdir)/ruby/internal/intern/object.h -pointer.o: $(hdrdir)/ruby/internal/intern/parse.h -pointer.o: $(hdrdir)/ruby/internal/intern/proc.h -pointer.o: $(hdrdir)/ruby/internal/intern/process.h -pointer.o: $(hdrdir)/ruby/internal/intern/random.h -pointer.o: $(hdrdir)/ruby/internal/intern/range.h -pointer.o: $(hdrdir)/ruby/internal/intern/rational.h -pointer.o: $(hdrdir)/ruby/internal/intern/re.h -pointer.o: $(hdrdir)/ruby/internal/intern/ruby.h -pointer.o: $(hdrdir)/ruby/internal/intern/select.h -pointer.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -pointer.o: $(hdrdir)/ruby/internal/intern/signal.h -pointer.o: $(hdrdir)/ruby/internal/intern/sprintf.h -pointer.o: $(hdrdir)/ruby/internal/intern/string.h -pointer.o: $(hdrdir)/ruby/internal/intern/struct.h -pointer.o: $(hdrdir)/ruby/internal/intern/thread.h -pointer.o: $(hdrdir)/ruby/internal/intern/time.h -pointer.o: $(hdrdir)/ruby/internal/intern/variable.h -pointer.o: $(hdrdir)/ruby/internal/intern/vm.h -pointer.o: $(hdrdir)/ruby/internal/interpreter.h -pointer.o: $(hdrdir)/ruby/internal/iterator.h -pointer.o: $(hdrdir)/ruby/internal/memory.h -pointer.o: $(hdrdir)/ruby/internal/method.h -pointer.o: $(hdrdir)/ruby/internal/module.h -pointer.o: $(hdrdir)/ruby/internal/newobj.h -pointer.o: $(hdrdir)/ruby/internal/rgengc.h -pointer.o: $(hdrdir)/ruby/internal/scan_args.h -pointer.o: $(hdrdir)/ruby/internal/special_consts.h -pointer.o: $(hdrdir)/ruby/internal/static_assert.h -pointer.o: $(hdrdir)/ruby/internal/stdalign.h -pointer.o: $(hdrdir)/ruby/internal/stdbool.h -pointer.o: $(hdrdir)/ruby/internal/symbol.h -pointer.o: $(hdrdir)/ruby/internal/value.h -pointer.o: $(hdrdir)/ruby/internal/value_type.h -pointer.o: $(hdrdir)/ruby/internal/variable.h -pointer.o: $(hdrdir)/ruby/internal/warning_push.h -pointer.o: $(hdrdir)/ruby/internal/xmalloc.h -pointer.o: $(hdrdir)/ruby/io.h -pointer.o: $(hdrdir)/ruby/memory_view.h -pointer.o: $(hdrdir)/ruby/missing.h -pointer.o: $(hdrdir)/ruby/onigmo.h -pointer.o: $(hdrdir)/ruby/oniguruma.h -pointer.o: $(hdrdir)/ruby/ruby.h -pointer.o: $(hdrdir)/ruby/st.h -pointer.o: $(hdrdir)/ruby/subst.h -pointer.o: closure.h -pointer.o: conversions.h -pointer.o: fiddle.h -pointer.o: function.h -pointer.o: pointer.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb deleted file mode 100644 index 053456d534..0000000000 --- a/ext/fiddle/extconf.rb +++ /dev/null @@ -1,267 +0,0 @@ -# frozen_string_literal: true -require 'mkmf' - -# :stopdoc: - -def gcc? - RbConfig::CONFIG["GCC"] == "yes" -end - -def disable_optimization_build_flag(flags) - if gcc? - expanded_flags = RbConfig.expand(flags.dup) - optimization_option_pattern = /(^|\s)?-O\d(\s|$)?/ - if optimization_option_pattern.match?(expanded_flags) - expanded_flags.gsub(optimization_option_pattern, '\\1-Og\\2') - else - flags + " -Og" - end - else - flags - end -end - -def enable_debug_build_flag(flags) - if gcc? - expanded_flags = RbConfig.expand(flags.dup) - debug_option_pattern = /(^|\s)-g(?:gdb)?\d?(\s|$)/ - if debug_option_pattern.match?(expanded_flags) - expanded_flags.gsub(debug_option_pattern, '\\1-ggdb3\\2') - else - flags + " -ggdb3" - end - else - flags - end -end - -checking_for(checking_message("--enable-debug-build option")) do - enable_debug_build = enable_config("debug-build", false) - if enable_debug_build - $CFLAGS = disable_optimization_build_flag($CFLAGS) - $CFLAGS = enable_debug_build_flag($CFLAGS) - end - enable_debug_build -end - -libffi_version = nil -have_libffi = false -bundle = enable_config('bundled-libffi') -unless bundle - dir_config 'libffi' - - if pkg_config("libffi") - libffi_version = pkg_config("libffi", "modversion") - end - - have_ffi_header = false - if have_header(ffi_header = 'ffi.h') - have_ffi_header = true - elsif have_header(ffi_header = 'ffi/ffi.h') - $defs.push('-DUSE_HEADER_HACKS') - have_ffi_header = true - end - if have_ffi_header && (have_library('ffi') || have_library('libffi')) - have_libffi = true - end -end - -unless have_libffi - # for https://github.com/ruby/fiddle - extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir) - if bundle && File.exist?(extlibs_rb) - require "fileutils" - require_relative "../../bin/extlibs" - extlibs = ExtLibs.new - cache_dir = File.expand_path("../../tmp/.download_cache", $srcdir) - ext_dir = File.expand_path("../../ext", $srcdir) - Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)} - extlibs.run(["--cache=#{cache_dir}", ext_dir]) - end - if bundle != false - libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/") - .map {|n| File.basename(n)} - .max_by {|n| n.scan(/\d+/).map(&:to_i)} - end - unless libffi_package_name - raise "missing libffi. Please install libffi." - end - - libffi_srcdir = "#{$srcdir}/#{libffi_package_name}" - ffi_header = 'ffi.h' - libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new - libffi.dir = libffi_package_name - if $srcdir == "." - libffi.builddir = libffi_package_name - libffi.srcdir = "." - else - libffi.builddir = libffi.dir - libffi.srcdir = relative_from(libffi_srcdir, "..") - end - libffi.include = "#{libffi.builddir}/include" - libffi.lib = "#{libffi.builddir}/.libs" - libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}" - nowarn = CONFIG.merge("warnflags"=>"") - libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn) - libffi_version = libffi_package_name[/libffi-(.*)/, 1] - - FileUtils.mkdir_p(libffi.dir) - libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1] - libffi.ldflags = RbConfig.expand("$(LDFLAGS) #{libpathflag([relative_from($topdir, "..")])} #{$LIBRUBYARG}".dup) - libffi.arch = RbConfig::CONFIG['host'] - if $mswin - unless find_executable(as = /x64/ =~ libffi.arch ? "ml64" : "ml") - raise "missing #{as} command." - end - $defs << "-DFFI_BUILDING" - libffi_config = "#{relative_from($srcdir, '..')}/win32/libffi-config.rb" - config = CONFIG.merge("top_srcdir" => $top_srcdir) - args = $ruby.gsub(/:\/=\\/, '') - args.gsub!(/\)\\/, ')/') - args = args.shellsplit - args.map! {|s| RbConfig.expand(s, config)} - args << '-C' << libffi.dir << libffi_config - opts = {} - else - args = %W[sh #{libffi.srcdir}/configure ] - opts = {chdir: libffi.dir} - end - cc = RbConfig::CONFIG['CC'] - cxx = RbConfig::CONFIG['CXX'] - ld = RbConfig::CONFIG['LD'] - args.concat %W[ - --srcdir=#{libffi.srcdir} - --host=#{libffi.arch} - ] - args << ($enable_shared || !$static ? '--enable-shared' : '--enable-static') - args << libffi.opt if libffi.opt - args.concat %W[ - CC=#{cc} CFLAGS=#{libffi.cflags} - CXX=#{cxx} CXXFLAGS=#{RbConfig.expand("$(CXXFLAGS)".dup, nowarn)} - LD=#{ld} LDFLAGS=#{libffi.ldflags} - ] - - FileUtils.rm_f("#{libffi.include}/ffitarget.h") - Logging::open do - Logging.message("%p in %p\n", args, opts) - unless system(*args, **opts) - begin - IO.copy_stream(libffi.dir + "/config.log", Logging.instance_variable_get(:@logfile)) - rescue SystemCallError => e - Logging.message("%s\n", e.message) - end - raise "failed to configure libffi. Please install libffi." - end - end - if $mswin && File.file?("#{libffi.include}/ffitarget.h") - FileUtils.rm_f("#{libffi.include}/ffitarget.h") - end - unless File.file?("#{libffi.include}/ffitarget.h") - FileUtils.cp("#{libffi_srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true) - end - $INCFLAGS << " -I" << libffi.include -end - -if libffi_version - # If libffi_version contains rc version, just ignored. - libffi_version = libffi_version.gsub(/-rc\d+/, '') - libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3] - $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }}) - warn "libffi_version: #{libffi_version.join('.')}" -end - -case -when $mswin, $mingw, (libffi_version && (libffi_version <=> [3, 2]) >= 0) - $defs << "-DUSE_FFI_CLOSURE_ALLOC=1" -when (libffi_version && (libffi_version <=> [3, 2]) < 0) -else - have_func('ffi_closure_alloc', ffi_header) -end - -if libffi_version - if (libffi_version <=> [3, 0, 11]) >= 0 - $defs << "-DHAVE_FFI_PREP_CIF_VAR" - end -else - have_func('ffi_prep_cif_var', ffi_header) -end - -have_header 'sys/mman.h' -have_header 'link.h' - -if have_header "dlfcn.h" - have_library "dl" - - %w{ dlopen dlclose dlsym }.each do |func| - abort "missing function #{func}" unless have_func(func) - end - - have_func "dlerror" - have_func "dlinfo" - have_const("RTLD_DI_LINKMAP", "dlfcn.h") -elsif have_header "windows.h" - %w{ LoadLibrary FreeLibrary GetProcAddress GetModuleFileName }.each do |func| - abort "missing function #{func}" unless have_func(func) - end - - have_library "ws2_32" -end - -have_const('FFI_STDCALL', ffi_header) - -config = File.read(RbConfig.expand(File.join($arch_hdrdir, "ruby/config.h"))) -types = {"SIZE_T"=>"SSIZE_T", "PTRDIFF_T"=>nil, "INTPTR_T"=>nil} -types.each do |type, signed| - if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config - if size = $2 and size != 'VOIDP' - size = types.fetch(size) {size} - $defs << "-DTYPE_#{signed||type}=TYPE_#{size}" - end - if signed - check_signedness(type.downcase, "stddef.h") - end - else - check_signedness(type.downcase, "stddef.h") - end -end - -if libffi - $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk - $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)') -end -create_makefile 'fiddle' do |conf| - if !libffi - next conf << "LIBFFI_CLEAN = none\n" - elsif $gnumake && !$nmake - submake_arg = "-C $(LIBFFI_DIR)\n" - else - submake_pre = "cd $(LIBFFI_DIR) && #{config_string("exec")}".strip - end - if $nmake - cmd = "$(RUBY) -C $(LIBFFI_DIR) #{libffi_config} --srcdir=$(LIBFFI_SRCDIR)" - else - cmd = "cd $(LIBFFI_DIR) && #$exec $(LIBFFI_SRCDIR)/configure #{libffi.opt}" - end - sep = "/" - seprpl = config_string('BUILD_FILE_SEPARATOR') {|s| sep = s; ":/=#{s}" if s != "/"} || "" - conf << <<-MK.gsub(/^ +| +$/, '') - PWD = - LIBFFI_CONFIGURE = #{cmd} - LIBFFI_ARCH = #{libffi.arch} - LIBFFI_SRCDIR = #{libffi.srcdir.sub(libffi.dir, '$(LIBFFI_DIR)')} - LIBFFI_DIR = #{libffi.dir} - LIBFFI_A = #{libffi.a.sub(libffi.dir, '$(LIBFFI_DIR)')} - LIBFFI_CFLAGS = #{libffi.cflags} - LIBFFI_LDFLAGS = #{libffi.ldflags} - FFI_H = $(LIBFFI_DIR)/include/ffi.h - SUBMAKE_PRE = #{submake_pre} - SUBMAKE_ARG = #{submake_arg} - LIBFFI_CLEAN = libffi - MK -end - -if libffi - $LIBPATH.pop -end - -# :startdoc: diff --git a/ext/fiddle/extlibs b/ext/fiddle/extlibs deleted file mode 100644 index 68dac46a95..0000000000 --- a/ext/fiddle/extlibs +++ /dev/null @@ -1,13 +0,0 @@ -ver = 3.2.1 -pkg = libffi-$(ver) - -https://ftp.osuosl.org/pub/blfs/conglomeration/libffi/$(pkg).tar.gz \ - md5:83b89587607e3eb65c70d361f13bab43 \ - sha512:980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 \ - # - win32/$(pkg)-mswin.patch -p0 - -$(pkg)/config.guess -> /tool/config.guess -$(pkg)/config.sub -> /tool/config.sub - -! chdir: $(pkg)| autoconf || exit 0 diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c deleted file mode 100644 index a8b5123269..0000000000 --- a/ext/fiddle/fiddle.c +++ /dev/null @@ -1,553 +0,0 @@ -#include <fiddle.h> - -VALUE mFiddle; -VALUE rb_eFiddleDLError; -VALUE rb_eFiddleError; - -void Init_fiddle_pointer(void); -void Init_fiddle_pinned(void); - -#ifdef HAVE_RUBY_MEMORY_VIEW_H -void Init_fiddle_memory_view(void); -#endif - -/* - * call-seq: Fiddle.malloc(size) - * - * Allocate +size+ bytes of memory and return the integer memory address - * for the allocated memory. - */ -static VALUE -rb_fiddle_malloc(VALUE self, VALUE size) -{ - void *ptr; - ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size)); - return PTR2NUM(ptr); -} - -/* - * call-seq: Fiddle.realloc(addr, size) - * - * Change the size of the memory allocated at the memory location +addr+ to - * +size+ bytes. Returns the memory address of the reallocated memory, which - * may be different than the address passed in. - */ -static VALUE -rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size) -{ - void *ptr = NUM2PTR(addr); - - ptr = (void*)ruby_xrealloc(ptr, NUM2SIZET(size)); - return PTR2NUM(ptr); -} - -/* - * call-seq: Fiddle.free(addr) - * - * Free the memory at address +addr+ - */ -VALUE -rb_fiddle_free(VALUE self, VALUE addr) -{ - void *ptr = NUM2PTR(addr); - - ruby_xfree(ptr); - return Qnil; -} - -/* - * call-seq: Fiddle.dlunwrap(addr) - * - * Returns the hexadecimal representation of a memory pointer address +addr+ - * - * Example: - * - * lib = Fiddle.dlopen('/lib64/libc-2.15.so') - * => #<Fiddle::Handle:0x00000001342460> - * - * lib['strcpy'].to_s(16) - * => "7f59de6dd240" - * - * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16))) - * => "7f59de6dd240" - */ -VALUE -rb_fiddle_ptr2value(VALUE self, VALUE addr) -{ - return (VALUE)NUM2PTR(addr); -} - -/* - * call-seq: Fiddle.dlwrap(val) - * - * Returns a memory pointer of a function's hexadecimal address location +val+ - * - * Example: - * - * lib = Fiddle.dlopen('/lib64/libc-2.15.so') - * => #<Fiddle::Handle:0x00000001342460> - * - * Fiddle.dlwrap(lib['strcpy'].to_s(16)) - * => 25522520 - */ -static VALUE -rb_fiddle_value2ptr(VALUE self, VALUE val) -{ - return PTR2NUM((void*)val); -} - -void Init_fiddle_handle(void); - -void -Init_fiddle(void) -{ - /* - * Document-module: Fiddle - * - * A libffi wrapper for Ruby. - * - * == Description - * - * Fiddle is an extension to translate a foreign function interface (FFI) - * with ruby. - * - * It wraps {libffi}[http://sourceware.org/libffi/], a popular C library - * which provides a portable interface that allows code written in one - * language to call code written in another language. - * - * == Example - * - * Here we will use Fiddle::Function to wrap {floor(3) from - * libm}[http://linux.die.net/man/3/floor] - * - * require 'fiddle' - * - * libm = Fiddle.dlopen('/lib/libm.so.6') - * - * floor = Fiddle::Function.new( - * libm['floor'], - * [Fiddle::TYPE_DOUBLE], - * Fiddle::TYPE_DOUBLE - * ) - * - * puts floor.call(3.14159) #=> 3.0 - * - * - */ - mFiddle = rb_define_module("Fiddle"); - - /* - * Document-class: Fiddle::Error - * - * Generic error class for Fiddle - */ - rb_eFiddleError = rb_define_class_under(mFiddle, "Error", rb_eStandardError); - - /* - * Ruby installed by RubyInstaller for Windows always require - * bundled Fiddle because ruby_installer/runtime/dll_directory.rb - * requires Fiddle. It's used by - * rubygems/defaults/operating_system.rb. It means that the - * bundled Fiddle is always required on initialization. - * - * We just remove existing Fiddle::DLError here to override - * the bundled Fiddle. - */ - if (rb_const_defined(mFiddle, rb_intern("DLError"))) { - rb_const_remove(mFiddle, rb_intern("DLError")); - } - - /* - * Document-class: Fiddle::DLError - * - * standard dynamic load exception - */ - rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError); - - /* Document-const: TYPE_VOID - * - * C type - void - */ - rb_define_const(mFiddle, "TYPE_VOID", INT2NUM(TYPE_VOID)); - - /* Document-const: TYPE_VOIDP - * - * C type - void* - */ - rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP)); - - /* Document-const: TYPE_CHAR - * - * C type - char - */ - rb_define_const(mFiddle, "TYPE_CHAR", INT2NUM(TYPE_CHAR)); - - /* Document-const: TYPE_SHORT - * - * C type - short - */ - rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT)); - - /* Document-const: TYPE_INT - * - * C type - int - */ - rb_define_const(mFiddle, "TYPE_INT", INT2NUM(TYPE_INT)); - - /* Document-const: TYPE_LONG - * - * C type - long - */ - rb_define_const(mFiddle, "TYPE_LONG", INT2NUM(TYPE_LONG)); - -#if HAVE_LONG_LONG - /* Document-const: TYPE_LONG_LONG - * - * C type - long long - */ - rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG)); -#endif - -#ifdef TYPE_INT8_T - /* Document-const: TYPE_INT8_T - * - * C type - int8_t - */ - rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T)); -#endif - -#ifdef TYPE_INT16_T - /* Document-const: TYPE_INT16_T - * - * C type - int16_t - */ - rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T)); -#endif - -#ifdef TYPE_INT32_T - /* Document-const: TYPE_INT32_T - * - * C type - int32_t - */ - rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T)); -#endif - -#ifdef TYPE_INT64_T - /* Document-const: TYPE_INT64_T - * - * C type - int64_t - */ - rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T)); -#endif - - /* Document-const: TYPE_FLOAT - * - * C type - float - */ - rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT)); - - /* Document-const: TYPE_DOUBLE - * - * C type - double - */ - rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE)); - -#ifdef HAVE_FFI_PREP_CIF_VAR - /* Document-const: TYPE_VARIADIC - * - * C type - ... - */ - rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC)); -#endif - - /* Document-const: TYPE_CONST_STRING - * - * C type - const char* ('\0' terminated const char*) - */ - rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING)); - - /* Document-const: TYPE_SIZE_T - * - * C type - size_t - */ - rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T)); - - /* Document-const: TYPE_SSIZE_T - * - * C type - ssize_t - */ - rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T)); - - /* Document-const: TYPE_PTRDIFF_T - * - * C type - ptrdiff_t - */ - rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T)); - - /* Document-const: TYPE_INTPTR_T - * - * C type - intptr_t - */ - rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T)); - - /* Document-const: TYPE_UINTPTR_T - * - * C type - uintptr_t - */ - rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T)); - - /* Document-const: ALIGN_VOIDP - * - * The alignment size of a void* - */ - rb_define_const(mFiddle, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP)); - - /* Document-const: ALIGN_CHAR - * - * The alignment size of a char - */ - rb_define_const(mFiddle, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR)); - - /* Document-const: ALIGN_SHORT - * - * The alignment size of a short - */ - rb_define_const(mFiddle, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT)); - - /* Document-const: ALIGN_INT - * - * The alignment size of an int - */ - rb_define_const(mFiddle, "ALIGN_INT", INT2NUM(ALIGN_INT)); - - /* Document-const: ALIGN_LONG - * - * The alignment size of a long - */ - rb_define_const(mFiddle, "ALIGN_LONG", INT2NUM(ALIGN_LONG)); - -#if HAVE_LONG_LONG - /* Document-const: ALIGN_LONG_LONG - * - * The alignment size of a long long - */ - rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG)); -#endif - - /* Document-const: ALIGN_INT8_T - * - * The alignment size of a int8_t - */ - rb_define_const(mFiddle, "ALIGN_INT8_T", INT2NUM(ALIGN_INT8_T)); - - /* Document-const: ALIGN_INT16_T - * - * The alignment size of a int16_t - */ - rb_define_const(mFiddle, "ALIGN_INT16_T", INT2NUM(ALIGN_INT16_T)); - - /* Document-const: ALIGN_INT32_T - * - * The alignment size of a int32_t - */ - rb_define_const(mFiddle, "ALIGN_INT32_T", INT2NUM(ALIGN_INT32_T)); - - /* Document-const: ALIGN_INT64_T - * - * The alignment size of a int64_t - */ - rb_define_const(mFiddle, "ALIGN_INT64_T", INT2NUM(ALIGN_INT64_T)); - - /* Document-const: ALIGN_FLOAT - * - * The alignment size of a float - */ - rb_define_const(mFiddle, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT)); - - /* Document-const: ALIGN_DOUBLE - * - * The alignment size of a double - */ - rb_define_const(mFiddle, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE)); - - /* Document-const: ALIGN_SIZE_T - * - * The alignment size of a size_t - */ - rb_define_const(mFiddle, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t))); - - /* Document-const: ALIGN_SSIZE_T - * - * The alignment size of a ssize_t - */ - rb_define_const(mFiddle, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */ - - /* Document-const: ALIGN_PTRDIFF_T - * - * The alignment size of a ptrdiff_t - */ - rb_define_const(mFiddle, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t))); - - /* Document-const: ALIGN_INTPTR_T - * - * The alignment size of a intptr_t - */ - rb_define_const(mFiddle, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t))); - - /* Document-const: ALIGN_UINTPTR_T - * - * The alignment size of a uintptr_t - */ - rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t))); - - /* Document-const: WINDOWS - * - * Returns a boolean regarding whether the host is WIN32 - */ -#if defined(_WIN32) - rb_define_const(mFiddle, "WINDOWS", Qtrue); -#else - rb_define_const(mFiddle, "WINDOWS", Qfalse); -#endif - - /* Document-const: SIZEOF_VOIDP - * - * size of a void* - */ - rb_define_const(mFiddle, "SIZEOF_VOIDP", INT2NUM(sizeof(void*))); - - /* Document-const: SIZEOF_CHAR - * - * size of a char - */ - rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char))); - - /* Document-const: SIZEOF_SHORT - * - * size of a short - */ - rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short))); - - /* Document-const: SIZEOF_INT - * - * size of an int - */ - rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int))); - - /* Document-const: SIZEOF_LONG - * - * size of a long - */ - rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long))); - -#if HAVE_LONG_LONG - /* Document-const: SIZEOF_LONG_LONG - * - * size of a long long - */ - rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG))); -#endif - - /* Document-const: SIZEOF_INT8_T - * - * size of a int8_t - */ - rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t))); - - /* Document-const: SIZEOF_INT16_T - * - * size of a int16_t - */ - rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t))); - - /* Document-const: SIZEOF_INT32_T - * - * size of a int32_t - */ - rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t))); - - /* Document-const: SIZEOF_INT64_T - * - * size of a int64_t - */ - rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t))); - - /* Document-const: SIZEOF_FLOAT - * - * size of a float - */ - rb_define_const(mFiddle, "SIZEOF_FLOAT", INT2NUM(sizeof(float))); - - /* Document-const: SIZEOF_DOUBLE - * - * size of a double - */ - rb_define_const(mFiddle, "SIZEOF_DOUBLE",INT2NUM(sizeof(double))); - - /* Document-const: SIZEOF_SIZE_T - * - * size of a size_t - */ - rb_define_const(mFiddle, "SIZEOF_SIZE_T", INT2NUM(sizeof(size_t))); - - /* Document-const: SIZEOF_SSIZE_T - * - * size of a ssize_t - */ - rb_define_const(mFiddle, "SIZEOF_SSIZE_T", INT2NUM(sizeof(size_t))); /* same as size_t */ - - /* Document-const: SIZEOF_PTRDIFF_T - * - * size of a ptrdiff_t - */ - rb_define_const(mFiddle, "SIZEOF_PTRDIFF_T", INT2NUM(sizeof(ptrdiff_t))); - - /* Document-const: SIZEOF_INTPTR_T - * - * size of a intptr_t - */ - rb_define_const(mFiddle, "SIZEOF_INTPTR_T", INT2NUM(sizeof(intptr_t))); - - /* Document-const: SIZEOF_UINTPTR_T - * - * size of a uintptr_t - */ - rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t))); - - /* Document-const: SIZEOF_CONST_STRING - * - * size of a const char* - */ - rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*))); - - /* Document-const: RUBY_FREE - * - * Address of the ruby_xfree() function - */ - rb_define_const(mFiddle, "RUBY_FREE", PTR2NUM(ruby_xfree)); - - /* Document-const: BUILD_RUBY_PLATFORM - * - * Platform built against (i.e. "x86_64-linux", etc.) - * - * See also RUBY_PLATFORM - */ - rb_define_const(mFiddle, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM)); - - rb_define_module_function(mFiddle, "dlwrap", rb_fiddle_value2ptr, 1); - rb_define_module_function(mFiddle, "dlunwrap", rb_fiddle_ptr2value, 1); - rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1); - rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2); - rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1); - - Init_fiddle_function(); - Init_fiddle_closure(); - Init_fiddle_handle(); - Init_fiddle_pointer(); - Init_fiddle_pinned(); - -#ifdef HAVE_RUBY_MEMORY_VIEW_H - Init_fiddle_memory_view(); -#endif -} -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/fiddle.gemspec b/ext/fiddle/fiddle.gemspec deleted file mode 100644 index a9c0ec4026..0000000000 --- a/ext/fiddle/fiddle.gemspec +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -version_module = Module.new do - version_rb = File.join(__dir__, "lib/fiddle/version.rb") - module_eval(File.read(version_rb), version_rb, __LINE__) -end - -Gem::Specification.new do |spec| - spec.name = "fiddle" - spec.version = version_module::Fiddle::VERSION - spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"] - spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"] - - spec.summary = %q{A libffi wrapper for Ruby.} - spec.description = %q{A libffi wrapper for Ruby.} - spec.homepage = "https://github.com/ruby/fiddle" - spec.licenses = ["Ruby", "BSD-2-Clause"] - - spec.files = [ - "LICENSE.txt", - "README.md", - "Rakefile", - "bin/downloader.rb", - "bin/extlibs.rb", - "ext/fiddle/closure.c", - "ext/fiddle/closure.h", - "ext/fiddle/conversions.c", - "ext/fiddle/conversions.h", - "ext/fiddle/depend", - "ext/fiddle/extconf.rb", - "ext/fiddle/extlibs", - "ext/fiddle/fiddle.c", - "ext/fiddle/fiddle.h", - "ext/fiddle/function.c", - "ext/fiddle/function.h", - "ext/fiddle/handle.c", - "ext/fiddle/memory_view.c", - "ext/fiddle/pinned.c", - "ext/fiddle/pointer.c", - "ext/fiddle/win32/fficonfig.h", - "ext/fiddle/win32/libffi-3.2.1-mswin.patch", - "ext/fiddle/win32/libffi-config.rb", - "ext/fiddle/win32/libffi.mk.tmpl", - "fiddle.gemspec", - "lib/fiddle.rb", - "lib/fiddle/closure.rb", - "lib/fiddle/cparser.rb", - "lib/fiddle/function.rb", - "lib/fiddle/import.rb", - "lib/fiddle/pack.rb", - "lib/fiddle/struct.rb", - "lib/fiddle/types.rb", - "lib/fiddle/value.rb", - "lib/fiddle/version.rb", - ] - spec.require_paths = ["lib"] - spec.extensions = ["ext/fiddle/extconf.rb"] - - spec.required_ruby_version = ">= 2.5.0" - - spec.metadata["msys2_mingw_dependencies"] = "libffi" -end diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h deleted file mode 100644 index 9de62a58cc..0000000000 --- a/ext/fiddle/fiddle.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef FIDDLE_H -#define FIDDLE_H - -#include <ruby.h> -#include <errno.h> - -#if defined(_WIN32) -#include <windows.h> -#endif - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#if defined(HAVE_LINK_H) -# include <link.h> -#endif - -#if defined(HAVE_DLFCN_H) -# include <dlfcn.h> -# /* some stranger systems may not define all of these */ -#ifndef RTLD_LAZY -#define RTLD_LAZY 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#else -# if defined(_WIN32) -# include <windows.h> -# define dlopen(name,flag) ((void*)LoadLibrary(name)) -# define dlerror() strerror(rb_w32_map_errno(GetLastError())) -# define dlsym(handle,name) ((void*)GetProcAddress((handle),(name))) -# define RTLD_LAZY -1 -# define RTLD_NOW -1 -# define RTLD_GLOBAL -1 -# endif -#endif - -#ifdef USE_HEADER_HACKS -#include <ffi/ffi.h> -#else -#include <ffi.h> -#endif - -#undef ffi_type_uchar -#undef ffi_type_schar -#undef ffi_type_ushort -#undef ffi_type_sshort -#undef ffi_type_uint -#undef ffi_type_sint -#undef ffi_type_ulong -#undef ffi_type_slong - -#if CHAR_BIT == 8 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else -# error "CHAR_BIT not supported" -#endif - -#if SIZEOF_SHORT == 2 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SIZEOF_SHORT == 4 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else -# error "short size not supported" -#endif - -#if SIZEOF_INT == 2 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif SIZEOF_INT == 4 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif SIZEOF_INT == 8 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else -# error "int size not supported" -#endif - -#if SIZEOF_LONG == 4 -# define ffi_type_ulong ffi_type_uint32 -# define ffi_type_slong ffi_type_sint32 -#elif SIZEOF_LONG == 8 -# define ffi_type_ulong ffi_type_uint64 -# define ffi_type_slong ffi_type_sint64 -#else -# error "long size not supported" -#endif - -#if HAVE_LONG_LONG -# if SIZEOF_LONG_LONG == 8 -# define ffi_type_slong_long ffi_type_sint64 -# define ffi_type_ulong_long ffi_type_uint64 -# else -# error "long long size not supported" -# endif -#endif - -#include <closure.h> -#include <conversions.h> -#include <function.h> - -#define TYPE_VOID 0 -#define TYPE_VOIDP 1 -#define TYPE_CHAR 2 -#define TYPE_SHORT 3 -#define TYPE_INT 4 -#define TYPE_LONG 5 -#if HAVE_LONG_LONG -#define TYPE_LONG_LONG 6 -#endif -#define TYPE_FLOAT 7 -#define TYPE_DOUBLE 8 -#define TYPE_VARIADIC 9 -#define TYPE_CONST_STRING 10 - -#define TYPE_INT8_T TYPE_CHAR -#if SIZEOF_SHORT == 2 -# define TYPE_INT16_T TYPE_SHORT -#elif SIZEOF_INT == 2 -# define TYPE_INT16_T TYPE_INT -#endif -#if SIZEOF_SHORT == 4 -# define TYPE_INT32_T TYPE_SHORT -#elif SIZEOF_INT == 4 -# define TYPE_INT32_T TYPE_INT -#elif SIZEOF_LONG == 4 -# define TYPE_INT32_T TYPE_LONG -#endif -#if SIZEOF_INT == 8 -# define TYPE_INT64_T TYPE_INT -#elif SIZEOF_LONG == 8 -# define TYPE_INT64_T TYPE_LONG -#elif defined(TYPE_LONG_LONG) -# define TYPE_INT64_T TYPE_LONG_LONG -#endif - -#ifndef TYPE_SSIZE_T -# if SIZEOF_SIZE_T == SIZEOF_INT -# define TYPE_SSIZE_T TYPE_INT -# elif SIZEOF_SIZE_T == SIZEOF_LONG -# define TYPE_SSIZE_T TYPE_LONG -# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG -# define TYPE_SSIZE_T TYPE_LONG_LONG -# endif -#endif -#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T) - -#ifndef TYPE_PTRDIFF_T -# if SIZEOF_PTRDIFF_T == SIZEOF_INT -# define TYPE_PTRDIFF_T TYPE_INT -# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG -# define TYPE_PTRDIFF_T TYPE_LONG -# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG -# define TYPE_PTRDIFF_T TYPE_LONG_LONG -# endif -#endif - -#ifndef TYPE_INTPTR_T -# if SIZEOF_INTPTR_T == SIZEOF_INT -# define TYPE_INTPTR_T TYPE_INT -# elif SIZEOF_INTPTR_T == SIZEOF_LONG -# define TYPE_INTPTR_T TYPE_LONG -# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG -# define TYPE_INTPTR_T TYPE_LONG_LONG -# endif -#endif -#define TYPE_UINTPTR_T (-TYPE_INTPTR_T) - -#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x) - -#define ALIGN_VOIDP ALIGN_OF(void*) -#define ALIGN_CHAR ALIGN_OF(char) -#define ALIGN_SHORT ALIGN_OF(short) -#define ALIGN_INT ALIGN_OF(int) -#define ALIGN_LONG ALIGN_OF(long) -#if HAVE_LONG_LONG -#define ALIGN_LONG_LONG ALIGN_OF(LONG_LONG) -#endif -#define ALIGN_FLOAT ALIGN_OF(float) -#define ALIGN_DOUBLE ALIGN_OF(double) - -#define ALIGN_INT8_T ALIGN_OF(int8_t) -#define ALIGN_INT16_T ALIGN_OF(int16_t) -#define ALIGN_INT32_T ALIGN_OF(int32_t) -#define ALIGN_INT64_T ALIGN_OF(int64_t) - -extern VALUE mFiddle; -extern VALUE rb_eFiddleDLError; - -VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type); - -typedef void (*rb_fiddle_freefunc_t)(void*); -VALUE rb_fiddle_ptr_new_wrap(void *ptr, long size, rb_fiddle_freefunc_t func, VALUE wrap0, VALUE wrap1); - -#endif -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c deleted file mode 100644 index 274d181d17..0000000000 --- a/ext/fiddle/function.c +++ /dev/null @@ -1,491 +0,0 @@ -#include <fiddle.h> -#include <ruby/thread.h> - -#include <stdbool.h> - -#ifdef PRIsVALUE -# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) -# define RB_OBJ_STRING(obj) (obj) -#else -# define PRIsVALUE "s" -# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) -# define RB_OBJ_STRING(obj) StringValueCStr(obj) -#endif - -VALUE cFiddleFunction; - -#define MAX_ARGS (SIZE_MAX / (sizeof(void *) + sizeof(fiddle_generic)) - 1) - -#define Check_Max_Args(name, len) \ - Check_Max_Args_(name, len, "") -#define Check_Max_Args_Long(name, len) \ - Check_Max_Args_(name, len, "l") -#define Check_Max_Args_(name, len, fmt) \ - do { \ - if ((size_t)(len) >= MAX_ARGS) { \ - rb_raise(rb_eTypeError, \ - "%s is so large " \ - "that it can cause integer overflow (%"fmt"d)", \ - (name), (len)); \ - } \ - } while (0) - -static void -deallocate(void *p) -{ - ffi_cif *cif = p; - if (cif->arg_types) xfree(cif->arg_types); - xfree(cif); -} - -static size_t -function_memsize(const void *p) -{ - /* const */ffi_cif *ptr = (ffi_cif *)p; - size_t size = 0; - - size += sizeof(*ptr); -#if !defined(FFI_NO_RAW_API) || !FFI_NO_RAW_API - size += ffi_raw_size(ptr); -#endif - - return size; -} - -const rb_data_type_t function_data_type = { - "fiddle/function", - {0, deallocate, function_memsize,}, -}; - -static VALUE -allocate(VALUE klass) -{ - ffi_cif * cif; - - return TypedData_Make_Struct(klass, ffi_cif, &function_data_type, cif); -} - -VALUE -rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type) -{ - VALUE argv[3]; - - argv[0] = address; - argv[1] = arg_types; - argv[2] = ret_type; - - return rb_class_new_instance(3, argv, cFiddleFunction); -} - -static VALUE -normalize_argument_types(const char *name, - VALUE arg_types, - bool *is_variadic) -{ - VALUE normalized_arg_types; - int i; - int n_arg_types; - *is_variadic = false; - - Check_Type(arg_types, T_ARRAY); - n_arg_types = RARRAY_LENINT(arg_types); - Check_Max_Args(name, n_arg_types); - - normalized_arg_types = rb_ary_new_capa(n_arg_types); - for (i = 0; i < n_arg_types; i++) { - VALUE arg_type = RARRAY_AREF(arg_types, i); - int c_arg_type; - arg_type = rb_fiddle_type_ensure(arg_type); - c_arg_type = NUM2INT(arg_type); - if (c_arg_type == TYPE_VARIADIC) { - if (i != n_arg_types - 1) { - rb_raise(rb_eArgError, - "Fiddle::TYPE_VARIADIC must be the last argument type: " - "%"PRIsVALUE, - arg_types); - } - *is_variadic = true; - break; - } - else { - (void)INT2FFI_TYPE(c_arg_type); /* raise */ - } - rb_ary_push(normalized_arg_types, INT2FIX(c_arg_type)); - } - - /* freeze to prevent inconsistency at calling #to_int later */ - OBJ_FREEZE(normalized_arg_types); - return normalized_arg_types; -} - -static VALUE -initialize(int argc, VALUE argv[], VALUE self) -{ - ffi_cif * cif; - VALUE ptr, arg_types, ret_type, abi, kwargs; - VALUE name = Qnil; - VALUE need_gvl = Qfalse; - int c_ret_type; - bool is_variadic = false; - ffi_abi c_ffi_abi; - void *cfunc; - - rb_scan_args(argc, argv, "31:", &ptr, &arg_types, &ret_type, &abi, &kwargs); - rb_iv_set(self, "@closure", ptr); - - if (!NIL_P(kwargs)) { - enum { - kw_name, - kw_need_gvl, - kw_max_, - }; - static ID kw[kw_max_]; - VALUE args[kw_max_]; - if (!kw[0]) { - kw[kw_name] = rb_intern_const("name"); - kw[kw_need_gvl] = rb_intern_const("need_gvl"); - } - rb_get_kwargs(kwargs, kw, 0, kw_max_, args); - if (args[kw_name] != Qundef) { - name = args[kw_name]; - } - if (args[kw_need_gvl] != Qundef) { - need_gvl = args[kw_need_gvl]; - } - } - rb_iv_set(self, "@name", name); - rb_iv_set(self, "@need_gvl", need_gvl); - - ptr = rb_Integer(ptr); - cfunc = NUM2PTR(ptr); - PTR2NUM(cfunc); - c_ffi_abi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi); - abi = INT2FIX(c_ffi_abi); - ret_type = rb_fiddle_type_ensure(ret_type); - c_ret_type = NUM2INT(ret_type); - (void)INT2FFI_TYPE(c_ret_type); /* raise */ - ret_type = INT2FIX(c_ret_type); - - arg_types = normalize_argument_types("argument types", - arg_types, - &is_variadic); -#ifndef HAVE_FFI_PREP_CIF_VAR - if (is_variadic) { - rb_raise(rb_eNotImpError, - "ffi_prep_cif_var() is required in libffi " - "for variadic arguments"); - } -#endif - - rb_iv_set(self, "@ptr", ptr); - rb_iv_set(self, "@argument_types", arg_types); - rb_iv_set(self, "@return_type", ret_type); - rb_iv_set(self, "@abi", abi); - rb_iv_set(self, "@is_variadic", is_variadic ? Qtrue : Qfalse); - - TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif); - cif->arg_types = NULL; - - return self; -} - -struct nogvl_ffi_call_args { - ffi_cif *cif; - void (*fn)(void); - void **values; - fiddle_generic retval; -}; - -static void * -nogvl_ffi_call(void *ptr) -{ - struct nogvl_ffi_call_args *args = ptr; - - ffi_call(args->cif, args->fn, &args->retval, args->values); - - return NULL; -} - -static VALUE -function_call(int argc, VALUE argv[], VALUE self) -{ - struct nogvl_ffi_call_args args = { 0 }; - fiddle_generic *generic_args; - VALUE cfunc; - VALUE abi; - VALUE arg_types; - VALUE cPointer; - VALUE is_variadic; - VALUE need_gvl; - int n_arg_types; - int n_fixed_args = 0; - int n_call_args = 0; - int i; - int i_call; - VALUE converted_args = Qnil; - VALUE alloc_buffer = 0; - - cfunc = rb_iv_get(self, "@ptr"); - abi = rb_iv_get(self, "@abi"); - arg_types = rb_iv_get(self, "@argument_types"); - cPointer = rb_const_get(mFiddle, rb_intern("Pointer")); - is_variadic = rb_iv_get(self, "@is_variadic"); - need_gvl = rb_iv_get(self, "@need_gvl"); - - n_arg_types = RARRAY_LENINT(arg_types); - n_fixed_args = n_arg_types; - if (RTEST(is_variadic)) { - if (argc < n_arg_types) { - rb_error_arity(argc, n_arg_types, UNLIMITED_ARGUMENTS); - } - if (((argc - n_arg_types) % 2) != 0) { - rb_raise(rb_eArgError, - "variadic arguments must be type and value pairs: " - "%"PRIsVALUE, - rb_ary_new_from_values(argc, argv)); - } - n_call_args = n_arg_types + ((argc - n_arg_types) / 2); - } - else { - if (argc != n_arg_types) { - rb_error_arity(argc, n_arg_types, n_arg_types); - } - n_call_args = n_arg_types; - } - Check_Max_Args("the number of arguments", n_call_args); - - TypedData_Get_Struct(self, ffi_cif, &function_data_type, args.cif); - - if (is_variadic && args.cif->arg_types) { - xfree(args.cif->arg_types); - args.cif->arg_types = NULL; - } - - if (!args.cif->arg_types) { - VALUE fixed_arg_types = arg_types; - VALUE return_type; - int c_return_type; - ffi_type *ffi_return_type; - ffi_type **ffi_arg_types; - ffi_status result; - - arg_types = rb_ary_dup(fixed_arg_types); - for (i = n_fixed_args; i < argc; i += 2) { - VALUE arg_type = argv[i]; - int c_arg_type; - arg_type = rb_fiddle_type_ensure(arg_type); - c_arg_type = NUM2INT(arg_type); - (void)INT2FFI_TYPE(c_arg_type); /* raise */ - rb_ary_push(arg_types, INT2FIX(c_arg_type)); - } - - return_type = rb_iv_get(self, "@return_type"); - c_return_type = FIX2INT(return_type); - ffi_return_type = INT2FFI_TYPE(c_return_type); - - ffi_arg_types = xcalloc(n_call_args + 1, sizeof(ffi_type *)); - for (i_call = 0; i_call < n_call_args; i_call++) { - VALUE arg_type; - int c_arg_type; - arg_type = RARRAY_AREF(arg_types, i_call); - c_arg_type = FIX2INT(arg_type); - ffi_arg_types[i_call] = INT2FFI_TYPE(c_arg_type); - } - ffi_arg_types[i_call] = NULL; - - if (is_variadic) { -#ifdef HAVE_FFI_PREP_CIF_VAR - result = ffi_prep_cif_var(args.cif, - FIX2INT(abi), - n_fixed_args, - n_call_args, - ffi_return_type, - ffi_arg_types); -#else - /* This code is never used because ffi_prep_cif_var() - * availability check is done in #initialize. */ - result = FFI_BAD_TYPEDEF; -#endif - } - else { - result = ffi_prep_cif(args.cif, - FIX2INT(abi), - n_call_args, - ffi_return_type, - ffi_arg_types); - } - if (result != FFI_OK) { - xfree(ffi_arg_types); - args.cif->arg_types = NULL; - rb_raise(rb_eRuntimeError, "error creating CIF %d", result); - } - } - - generic_args = ALLOCV(alloc_buffer, - sizeof(fiddle_generic) * n_call_args + - sizeof(void *) * (n_call_args + 1)); - args.values = (void **)((char *)generic_args + - sizeof(fiddle_generic) * n_call_args); - - for (i = 0, i_call = 0; - i < argc && i_call < n_call_args; - i++, i_call++) { - VALUE arg_type; - int c_arg_type; - VALUE original_src; - VALUE src; - arg_type = RARRAY_AREF(arg_types, i_call); - c_arg_type = FIX2INT(arg_type); - if (i >= n_fixed_args) { - i++; - } - src = argv[i]; - - if (c_arg_type == TYPE_VOIDP) { - if (NIL_P(src)) { - src = INT2FIX(0); - } - else if (cPointer != CLASS_OF(src)) { - src = rb_funcall(cPointer, rb_intern("[]"), 1, src); - if (NIL_P(converted_args)) { - converted_args = rb_ary_new(); - } - rb_ary_push(converted_args, src); - } - src = rb_Integer(src); - } - - original_src = src; - VALUE2GENERIC(c_arg_type, src, &generic_args[i_call]); - if (src != original_src) { - if (NIL_P(converted_args)) { - converted_args = rb_ary_new(); - } - rb_ary_push(converted_args, src); - } - args.values[i_call] = (void *)&generic_args[i_call]; - } - args.values[i_call] = NULL; - args.fn = (void(*)(void))NUM2PTR(cfunc); - - if (RTEST(need_gvl)) { - ffi_call(args.cif, args.fn, &(args.retval), args.values); - } - else { - (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0); - } - - { - int errno_keep = errno; -#if defined(_WIN32) - DWORD error = WSAGetLastError(); - int socket_error = WSAGetLastError(); - rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, - ULONG2NUM(error)); - rb_funcall(mFiddle, rb_intern("win32_last_socket_error="), 1, - INT2NUM(socket_error)); -#endif - rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno_keep)); - } - - ALLOCV_END(alloc_buffer); - - return GENERIC2VALUE(rb_iv_get(self, "@return_type"), args.retval); -} - -void -Init_fiddle_function(void) -{ - /* - * Document-class: Fiddle::Function - * - * == Description - * - * A representation of a C function - * - * == Examples - * - * === 'strcpy' - * - * @libc = Fiddle.dlopen "/lib/libc.so.6" - * #=> #<Fiddle::Handle:0x00000001d7a8d8> - * f = Fiddle::Function.new( - * @libc['strcpy'], - * [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], - * Fiddle::TYPE_VOIDP) - * #=> #<Fiddle::Function:0x00000001d8ee00> - * buff = "000" - * #=> "000" - * str = f.call(buff, "123") - * #=> #<Fiddle::Pointer:0x00000001d0c380 ptr=0x000000018a21b8 size=0 free=0x00000000000000> - * str.to_s - * => "123" - * - * === ABI check - * - * @libc = Fiddle.dlopen "/lib/libc.so.6" - * #=> #<Fiddle::Handle:0x00000001d7a8d8> - * f = Fiddle::Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP) - * #=> #<Fiddle::Function:0x00000001d8ee00> - * f.abi == Fiddle::Function::DEFAULT - * #=> true - */ - cFiddleFunction = rb_define_class_under(mFiddle, "Function", rb_cObject); - - /* - * Document-const: DEFAULT - * - * Default ABI - * - */ - rb_define_const(cFiddleFunction, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI)); - -#ifdef HAVE_CONST_FFI_STDCALL - /* - * Document-const: STDCALL - * - * FFI implementation of WIN32 stdcall convention - * - */ - rb_define_const(cFiddleFunction, "STDCALL", INT2NUM(FFI_STDCALL)); -#endif - - rb_define_alloc_func(cFiddleFunction, allocate); - - /* - * Document-method: call - * - * Calls the constructed Function, with +args+. - * Caller must ensure the underlying function is called in a - * thread-safe manner if running in a multi-threaded process. - * - * Note that it is not thread-safe to use this method to - * directly or indirectly call many Ruby C-extension APIs unless - * you don't pass +need_gvl: true+ to Fiddle::Function#new. - * - * For an example see Fiddle::Function - * - */ - rb_define_method(cFiddleFunction, "call", function_call, -1); - - /* - * Document-method: new - * call-seq: new(ptr, - * args, - * ret_type, - * abi = DEFAULT, - * name: nil, - * need_gvl: false) - * - * Constructs a Function object. - * * +ptr+ is a referenced function, of a Fiddle::Handle - * * +args+ is an Array of arguments, passed to the +ptr+ function - * * +ret_type+ is the return type of the function - * * +abi+ is the ABI of the function - * * +name+ is the name of the function - * * +need_gvl+ is whether GVL is needed to call the function - * - */ - rb_define_method(cFiddleFunction, "initialize", initialize, -1); -} -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/function.h b/ext/fiddle/function.h deleted file mode 100644 index 829e592c8a..0000000000 --- a/ext/fiddle/function.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef FIDDLE_FUNCTION_H -#define FIDDLE_FUNCTION_H - -#include <fiddle.h> - -void Init_fiddle_function(void); - -#endif diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c deleted file mode 100644 index 76b90909d3..0000000000 --- a/ext/fiddle/handle.c +++ /dev/null @@ -1,535 +0,0 @@ -#include <ruby.h> -#include <fiddle.h> - -VALUE rb_cHandle; - -struct dl_handle { - void *ptr; - int open; - int enable_close; -}; - -#ifdef _WIN32 -# ifndef _WIN32_WCE -static void * -w32_coredll(void) -{ - MEMORY_BASIC_INFORMATION m; - memset(&m, 0, sizeof(m)); - if( !VirtualQuery(_errno, &m, sizeof(m)) ) return NULL; - return m.AllocationBase; -} -# endif - -static int -w32_dlclose(void *ptr) -{ -# ifndef _WIN32_WCE - if( ptr == w32_coredll() ) return 0; -# endif - if( FreeLibrary((HMODULE)ptr) ) return 0; - return errno = rb_w32_map_errno(GetLastError()); -} -#define dlclose(ptr) w32_dlclose(ptr) -#endif - -static void -fiddle_handle_free(void *ptr) -{ - struct dl_handle *fiddle_handle = ptr; - if( fiddle_handle->ptr && fiddle_handle->open && fiddle_handle->enable_close ){ - dlclose(fiddle_handle->ptr); - } - xfree(ptr); -} - -static size_t -fiddle_handle_memsize(const void *ptr) -{ - return sizeof(struct dl_handle); -} - -static const rb_data_type_t fiddle_handle_data_type = { - "fiddle/handle", - {0, fiddle_handle_free, fiddle_handle_memsize,}, -}; - -/* - * call-seq: close - * - * Close this handle. - * - * Calling close more than once will raise a Fiddle::DLError exception. - */ -static VALUE -rb_fiddle_handle_close(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - if(fiddle_handle->open) { - int ret = dlclose(fiddle_handle->ptr); - fiddle_handle->open = 0; - - /* Check dlclose for successful return value */ - if(ret) { -#if defined(HAVE_DLERROR) - rb_raise(rb_eFiddleDLError, "%s", dlerror()); -#else - rb_raise(rb_eFiddleDLError, "could not close handle"); -#endif - } - return INT2NUM(ret); - } - rb_raise(rb_eFiddleDLError, "dlclose() called too many times"); - - UNREACHABLE; -} - -static VALUE -rb_fiddle_handle_s_allocate(VALUE klass) -{ - VALUE obj; - struct dl_handle *fiddle_handle; - - obj = TypedData_Make_Struct(rb_cHandle, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - fiddle_handle->ptr = 0; - fiddle_handle->open = 0; - fiddle_handle->enable_close = 0; - - return obj; -} - -static VALUE -predefined_fiddle_handle(void *handle) -{ - VALUE obj = rb_fiddle_handle_s_allocate(rb_cHandle); - struct dl_handle *fiddle_handle = DATA_PTR(obj); - - fiddle_handle->ptr = handle; - fiddle_handle->open = 1; - OBJ_FREEZE(obj); - return obj; -} - -/* - * call-seq: - * new(library = nil, flags = Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) - * - * Create a new handler that opens +library+ with +flags+. - * - * If no +library+ is specified or +nil+ is given, DEFAULT is used, which is - * the equivalent to RTLD_DEFAULT. See <code>man 3 dlopen</code> for more. - * - * lib = Fiddle::Handle.new - * - * The default is dependent on OS, and provide a handle for all libraries - * already loaded. For example, in most cases you can use this to access +libc+ - * functions, or ruby functions like +rb_str_new+. - */ -static VALUE -rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self) -{ - void *ptr; - struct dl_handle *fiddle_handle; - VALUE lib, flag; - char *clib; - int cflag; - const char *err; - - switch( rb_scan_args(argc, argv, "02", &lib, &flag) ){ - case 0: - clib = NULL; - cflag = RTLD_LAZY | RTLD_GLOBAL; - break; - case 1: - clib = NIL_P(lib) ? NULL : StringValueCStr(lib); - cflag = RTLD_LAZY | RTLD_GLOBAL; - break; - case 2: - clib = NIL_P(lib) ? NULL : StringValueCStr(lib); - cflag = NUM2INT(flag); - break; - default: - rb_bug("rb_fiddle_handle_new"); - } - -#if defined(_WIN32) - if( !clib ){ - HANDLE rb_libruby_handle(void); - ptr = rb_libruby_handle(); - } - else if( STRCASECMP(clib, "libc") == 0 -# ifdef RUBY_COREDLL - || STRCASECMP(clib, RUBY_COREDLL) == 0 - || STRCASECMP(clib, RUBY_COREDLL".dll") == 0 -# endif - ){ -# ifdef _WIN32_WCE - ptr = dlopen("coredll.dll", cflag); -# else - (void)cflag; - ptr = w32_coredll(); -# endif - } - else -#endif - ptr = dlopen(clib, cflag); -#if defined(HAVE_DLERROR) - if( !ptr && (err = dlerror()) ){ - rb_raise(rb_eFiddleDLError, "%s", err); - } -#else - if( !ptr ){ - err = dlerror(); - rb_raise(rb_eFiddleDLError, "%s", err); - } -#endif - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - if( fiddle_handle->ptr && fiddle_handle->open && fiddle_handle->enable_close ){ - dlclose(fiddle_handle->ptr); - } - fiddle_handle->ptr = ptr; - fiddle_handle->open = 1; - fiddle_handle->enable_close = 0; - - if( rb_block_given_p() ){ - rb_ensure(rb_yield, self, rb_fiddle_handle_close, self); - } - - return Qnil; -} - -/* - * call-seq: enable_close - * - * Enable a call to dlclose() when this handle is garbage collected. - */ -static VALUE -rb_fiddle_handle_enable_close(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - fiddle_handle->enable_close = 1; - return Qnil; -} - -/* - * call-seq: disable_close - * - * Disable a call to dlclose() when this handle is garbage collected. - */ -static VALUE -rb_fiddle_handle_disable_close(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - fiddle_handle->enable_close = 0; - return Qnil; -} - -/* - * call-seq: close_enabled? - * - * Returns +true+ if dlclose() will be called when this handle is garbage collected. - * - * See man(3) dlclose() for more info. - */ -static VALUE -rb_fiddle_handle_close_enabled_p(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - - if(fiddle_handle->enable_close) return Qtrue; - return Qfalse; -} - -/* - * call-seq: to_i - * - * Returns the memory address for this handle. - */ -static VALUE -rb_fiddle_handle_to_i(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - return PTR2NUM(fiddle_handle->ptr); -} - -/* - * call-seq: to_ptr - * - * Returns the Fiddle::Pointer of this handle. - */ -static VALUE -rb_fiddle_handle_to_ptr(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - return rb_fiddle_ptr_new_wrap(fiddle_handle->ptr, 0, 0, self, 0); -} - -static VALUE fiddle_handle_sym(void *handle, VALUE symbol); - -/* - * Document-method: sym - * - * call-seq: sym(name) - * - * Get the address as an Integer for the function named +name+. - */ -static VALUE -rb_fiddle_handle_sym(VALUE self, VALUE sym) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - if( ! fiddle_handle->open ){ - rb_raise(rb_eFiddleDLError, "closed handle"); - } - - return fiddle_handle_sym(fiddle_handle->ptr, sym); -} - -#ifndef RTLD_NEXT -#define RTLD_NEXT NULL -#endif -#ifndef RTLD_DEFAULT -#define RTLD_DEFAULT NULL -#endif - -/* - * Document-method: sym - * - * call-seq: sym(name) - * - * Get the address as an Integer for the function named +name+. The function - * is searched via dlsym on RTLD_NEXT. - * - * See man(3) dlsym() for more info. - */ -static VALUE -rb_fiddle_handle_s_sym(VALUE self, VALUE sym) -{ - return fiddle_handle_sym(RTLD_NEXT, sym); -} - -static VALUE -fiddle_handle_sym(void *handle, VALUE symbol) -{ -#if defined(HAVE_DLERROR) - const char *err; -# define CHECK_DLERROR if ((err = dlerror()) != 0) { func = 0; } -#else -# define CHECK_DLERROR -#endif - void (*func)(); - const char *name = StringValueCStr(symbol); - -#ifdef HAVE_DLERROR - dlerror(); -#endif - func = (void (*)())(VALUE)dlsym(handle, name); - CHECK_DLERROR; -#if defined(FUNC_STDCALL) - if( !func ){ - int i; - int len = (int)strlen(name); - char *name_n; -#if defined(__CYGWIN__) || defined(_WIN32) || defined(__MINGW32__) - { - char *name_a = (char*)xmalloc(len+2); - strcpy(name_a, name); - name_n = name_a; - name_a[len] = 'A'; - name_a[len+1] = '\0'; - func = dlsym(handle, name_a); - CHECK_DLERROR; - if( func ) goto found; - name_n = xrealloc(name_a, len+6); - } -#else - name_n = (char*)xmalloc(len+6); -#endif - memcpy(name_n, name, len); - name_n[len++] = '@'; - for( i = 0; i < 256; i += 4 ){ - sprintf(name_n + len, "%d", i); - func = dlsym(handle, name_n); - CHECK_DLERROR; - if( func ) break; - } - if( func ) goto found; - name_n[len-1] = 'A'; - name_n[len++] = '@'; - for( i = 0; i < 256; i += 4 ){ - sprintf(name_n + len, "%d", i); - func = dlsym(handle, name_n); - CHECK_DLERROR; - if( func ) break; - } - found: - xfree(name_n); - } -#endif - if( !func ){ - rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol); - } - - return PTR2NUM(func); -} - -/* - * call-seq: file_name - * - * Returns the file name of this handle. - */ -static VALUE -rb_fiddle_handle_file_name(VALUE self) -{ - struct dl_handle *fiddle_handle; - - TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); - -#if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP) - { - struct link_map *lm = NULL; - int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm); - if (res == 0 && lm != NULL) { - return rb_str_new_cstr(lm->l_name); - } - else { -#if defined(HAVE_DLERROR) - rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror()); -#else - rb_raise(rb_eFiddleDLError, "could not get handle file name"); -#endif - } - } -#elif defined(HAVE_GETMODULEFILENAME) - { - char filename[MAX_PATH]; - DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH); - if (res == 0) { - rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror()); - } - return rb_str_new_cstr(filename); - } -#else - (void)fiddle_handle; - return Qnil; -#endif -} - -void -Init_fiddle_handle(void) -{ - /* - * Document-class: Fiddle::Handle - * - * The Fiddle::Handle is the manner to access the dynamic library - * - * == Example - * - * === Setup - * - * libc_so = "/lib64/libc.so.6" - * => "/lib64/libc.so.6" - * @handle = Fiddle::Handle.new(libc_so) - * => #<Fiddle::Handle:0x00000000d69ef8> - * - * === Setup, with flags - * - * libc_so = "/lib64/libc.so.6" - * => "/lib64/libc.so.6" - * @handle = Fiddle::Handle.new(libc_so, Fiddle::RTLD_LAZY | Fiddle::RTLD_GLOBAL) - * => #<Fiddle::Handle:0x00000000d69ef8> - * - * See RTLD_LAZY and RTLD_GLOBAL - * - * === Addresses to symbols - * - * strcpy_addr = @handle['strcpy'] - * => 140062278451968 - * - * or - * - * strcpy_addr = @handle.sym('strcpy') - * => 140062278451968 - * - */ - rb_cHandle = rb_define_class_under(mFiddle, "Handle", rb_cObject); - rb_define_alloc_func(rb_cHandle, rb_fiddle_handle_s_allocate); - rb_define_singleton_method(rb_cHandle, "sym", rb_fiddle_handle_s_sym, 1); - rb_define_singleton_method(rb_cHandle, "[]", rb_fiddle_handle_s_sym, 1); - - /* Document-const: NEXT - * - * A predefined pseudo-handle of RTLD_NEXT - * - * Which will find the next occurrence of a function in the search order - * after the current library. - */ - rb_define_const(rb_cHandle, "NEXT", predefined_fiddle_handle(RTLD_NEXT)); - - /* Document-const: DEFAULT - * - * A predefined pseudo-handle of RTLD_DEFAULT - * - * Which will find the first occurrence of the desired symbol using the - * default library search order - */ - rb_define_const(rb_cHandle, "DEFAULT", predefined_fiddle_handle(RTLD_DEFAULT)); - - /* Document-const: RTLD_GLOBAL - * - * rtld Fiddle::Handle flag. - * - * The symbols defined by this library will be made available for symbol - * resolution of subsequently loaded libraries. - */ - rb_define_const(rb_cHandle, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL)); - - /* Document-const: RTLD_LAZY - * - * rtld Fiddle::Handle flag. - * - * Perform lazy binding. Only resolve symbols as the code that references - * them is executed. If the symbol is never referenced, then it is never - * resolved. (Lazy binding is only performed for function references; - * references to variables are always immediately bound when the library - * is loaded.) - */ - rb_define_const(rb_cHandle, "RTLD_LAZY", INT2NUM(RTLD_LAZY)); - - /* Document-const: RTLD_NOW - * - * rtld Fiddle::Handle flag. - * - * If this value is specified or the environment variable LD_BIND_NOW is - * set to a nonempty string, all undefined symbols in the library are - * resolved before Fiddle.dlopen returns. If this cannot be done an error - * is returned. - */ - rb_define_const(rb_cHandle, "RTLD_NOW", INT2NUM(RTLD_NOW)); - - rb_define_method(rb_cHandle, "initialize", rb_fiddle_handle_initialize, -1); - rb_define_method(rb_cHandle, "to_i", rb_fiddle_handle_to_i, 0); - rb_define_method(rb_cHandle, "to_ptr", rb_fiddle_handle_to_ptr, 0); - rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0); - rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1); - rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1); - rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0); - rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0); - rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0); - rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0); -} - -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb deleted file mode 100644 index 4512989310..0000000000 --- a/ext/fiddle/lib/fiddle.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require 'fiddle.so' -require 'fiddle/closure' -require 'fiddle/function' -require 'fiddle/version' - -module Fiddle - if WINDOWS - # Returns the last win32 +Error+ of the current executing +Thread+ or nil - # if none - def self.win32_last_error - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] - end - - # Sets the last win32 +Error+ of the current executing +Thread+ to +error+ - def self.win32_last_error= error - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error - end - - # Returns the last win32 socket +Error+ of the current executing - # +Thread+ or nil if none - def self.win32_last_socket_error - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] - end - - # Sets the last win32 socket +Error+ of the current executing - # +Thread+ to +error+ - def self.win32_last_socket_error= error - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error - end - end - - # Returns the last +Error+ of the current executing +Thread+ or nil if none - def self.last_error - Thread.current[:__FIDDLE_LAST_ERROR__] - end - - # Sets the last +Error+ of the current executing +Thread+ to +error+ - def self.last_error= error - Thread.current[:__DL2_LAST_ERROR__] = error - Thread.current[:__FIDDLE_LAST_ERROR__] = error - end - - # call-seq: dlopen(library) => Fiddle::Handle - # - # Creates a new handler that opens +library+, and returns an instance of - # Fiddle::Handle. - # - # If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which - # is the equivalent to RTLD_DEFAULT. See <code>man 3 dlopen</code> for more. - # - # lib = Fiddle.dlopen(nil) - # - # The default is dependent on OS, and provide a handle for all libraries - # already loaded. For example, in most cases you can use this to access - # +libc+ functions, or ruby functions like +rb_str_new+. - # - # See Fiddle::Handle.new for more. - def dlopen library - Fiddle::Handle.new library - end - module_function :dlopen - - # Add constants for backwards compat - - RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc: - RTLD_LAZY = Handle::RTLD_LAZY # :nodoc: - RTLD_NOW = Handle::RTLD_NOW # :nodoc: -end diff --git a/ext/fiddle/lib/fiddle/closure.rb b/ext/fiddle/lib/fiddle/closure.rb deleted file mode 100644 index c865a63c20..0000000000 --- a/ext/fiddle/lib/fiddle/closure.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true -module Fiddle - class Closure - - # the C type of the return of the FFI closure - attr_reader :ctype - - # arguments of the FFI closure - attr_reader :args - - # Extends Fiddle::Closure to allow for building the closure in a block - class BlockCaller < Fiddle::Closure - - # == Description - # - # Construct a new BlockCaller object. - # - # * +ctype+ is the C type to be returned - # * +args+ are passed the callback - # * +abi+ is the abi of the closure - # - # If there is an error in preparing the +ffi_cif+ or +ffi_prep_closure+, - # then a RuntimeError will be raised. - # - # == Example - # - # include Fiddle - # - # cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one| - # one - # end - # - # func = Function.new(cb, [TYPE_INT], TYPE_INT) - # - def initialize ctype, args, abi = Fiddle::Function::DEFAULT, &block - super(ctype, args, abi) - @block = block - end - - # Calls the constructed BlockCaller, with +args+ - # - # For an example see Fiddle::Closure::BlockCaller.new - # - def call *args - @block.call(*args) - end - end - end -end diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb deleted file mode 100644 index 93a05513c9..0000000000 --- a/ext/fiddle/lib/fiddle/cparser.rb +++ /dev/null @@ -1,264 +0,0 @@ -# frozen_string_literal: true -module Fiddle - # A mixin that provides methods for parsing C struct and prototype signatures. - # - # == Example - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_ctype('int') - # #=> Fiddle::TYPE_INT - # - # parse_struct_signature(['int i', 'char c']) - # #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]] - # - # parse_signature('double sum(double, double)') - # #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]] - # - module CParser - # Parses a C struct's members - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_struct_signature(['int i', 'char c']) - # #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]] - # - # parse_struct_signature(['char buffer[80]']) - # #=> [[[Fiddle::TYPE_CHAR, 80]], ["buffer"]] - # - def parse_struct_signature(signature, tymap=nil) - if signature.is_a?(String) - signature = split_arguments(signature, /[,;]/) - elsif signature.is_a?(Hash) - signature = [signature] - end - mems = [] - tys = [] - signature.each{|msig| - msig = compact(msig) if msig.is_a?(String) - case msig - when Hash - msig.each do |struct_name, struct_signature| - struct_name = struct_name.to_s if struct_name.is_a?(Symbol) - struct_name = compact(struct_name) - struct_count = nil - if struct_name =~ /^([\w\*\s]+)\[(\d+)\]$/ - struct_count = $2.to_i - struct_name = $1 - end - if struct_signature.respond_to?(:entity_class) - struct_type = struct_signature - else - parsed_struct = parse_struct_signature(struct_signature, tymap) - struct_type = CStructBuilder.create(CStruct, *parsed_struct) - end - if struct_count - ty = [struct_type, struct_count] - else - ty = struct_type - end - mems.push([struct_name, struct_type.members]) - tys.push(ty) - end - when /^[\w\*\s]+[\*\s](\w+)$/ - mems.push($1) - tys.push(parse_ctype(msig, tymap)) - when /^[\w\*\s]+\(\*(\w+)\)\(.*?\)$/ - mems.push($1) - tys.push(parse_ctype(msig, tymap)) - when /^([\w\*\s]+[\*\s])(\w+)\[(\d+)\]$/ - mems.push($2) - tys.push([parse_ctype($1.strip, tymap), $3.to_i]) - when /^([\w\*\s]+)\[(\d+)\](\w+)$/ - mems.push($3) - tys.push([parse_ctype($1.strip, tymap), $2.to_i]) - else - raise(RuntimeError,"can't parse the struct member: #{msig}") - end - } - return tys, mems - end - - # Parses a C prototype signature - # - # If Hash +tymap+ is provided, the return value and the arguments from the - # +signature+ are expected to be keys, and the value will be the C type to - # be looked up. - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_signature('double sum(double, double)') - # #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]] - # - # parse_signature('void update(void (*cb)(int code))') - # #=> ["update", Fiddle::TYPE_VOID, [Fiddle::TYPE_VOIDP]] - # - # parse_signature('char (*getbuffer(void))[80]') - # #=> ["getbuffer", Fiddle::TYPE_VOIDP, []] - # - def parse_signature(signature, tymap=nil) - tymap ||= {} - case compact(signature) - when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/ - func, args = $1, $2 - return [func, TYPE_VOIDP, split_arguments(args).collect {|arg| parse_ctype(arg, tymap)}] - when /^([\w\*\s]+[\*\s])(\w+)\((.*?)\);?$/ - ret, func, args = $1.strip, $2, $3 - return [func, parse_ctype(ret, tymap), split_arguments(args).collect {|arg| parse_ctype(arg, tymap)}] - else - raise(RuntimeError,"can't parse the function prototype: #{signature}") - end - end - - # Given a String of C type +ty+, returns the corresponding Fiddle constant. - # - # +ty+ can also accept an Array of C type Strings, and will be returned in - # a corresponding Array. - # - # If Hash +tymap+ is provided, +ty+ is expected to be the key, and the - # value will be the C type to be looked up. - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_ctype('int') - # #=> Fiddle::TYPE_INT - # - # parse_ctype('double diff') - # #=> Fiddle::TYPE_DOUBLE - # - # parse_ctype('unsigned char byte') - # #=> -Fiddle::TYPE_CHAR - # - # parse_ctype('const char* const argv[]') - # #=> -Fiddle::TYPE_VOIDP - # - def parse_ctype(ty, tymap=nil) - tymap ||= {} - if ty.is_a?(Array) - return [parse_ctype(ty[0], tymap), ty[1]] - end - ty = ty.gsub(/\Aconst\s+/, "") - case ty - when 'void' - return TYPE_VOID - when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_LONG_LONG) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_LONG_LONG - when /\A(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_LONG_LONG) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_LONG_LONG - when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/ - return TYPE_LONG - when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_LONG - when /\A(?:signed\s+)?int(?:\s+\w+)?\z/ - return TYPE_INT - when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/ - return -TYPE_INT - when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return TYPE_SHORT - when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_SHORT - when /\A(?:signed\s+)?char(?:\s+\w+)?\z/ - return TYPE_CHAR - when /\Aunsigned\s+char(?:\s+\w+)?\z/ - return -TYPE_CHAR - when /\Aint8_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT8_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT8_T - when /\Auint8_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT8_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT8_T - when /\Aint16_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT16_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT16_T - when /\Auint16_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT16_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT16_T - when /\Aint32_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT32_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT32_T - when /\Auint32_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT32_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT32_T - when /\Aint64_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT64_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT64_T - when /\Auint64_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT64_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT64_T - when /\Afloat(?:\s+\w+)?\z/ - return TYPE_FLOAT - when /\Adouble(?:\s+\w+)?\z/ - return TYPE_DOUBLE - when /\Asize_t(?:\s+\w+)?\z/ - return TYPE_SIZE_T - when /\Assize_t(?:\s+\w+)?\z/ - return TYPE_SSIZE_T - when /\Aptrdiff_t(?:\s+\w+)?\z/ - return TYPE_PTRDIFF_T - when /\Aintptr_t(?:\s+\w+)?\z/ - return TYPE_INTPTR_T - when /\Auintptr_t(?:\s+\w+)?\z/ - return TYPE_UINTPTR_T - when /\*/, /\[[\s\d]*\]/ - return TYPE_VOIDP - when "..." - return TYPE_VARIADIC - else - ty = ty.split(' ', 2)[0] - if( tymap[ty] ) - return parse_ctype(tymap[ty], tymap) - else - raise(DLError, "unknown type: #{ty}") - end - end - end - - private - - def split_arguments(arguments, sep=',') - return [] if arguments.strip == 'void' - arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+|\.\.\.)(?:#{sep}\s*|\z)/).collect {|m| m[0]} - end - - def compact(signature) - signature.gsub(/\s+/, ' ').gsub(/\s*([\(\)\[\]\*,;])\s*/, '\1').strip - end - - end -end diff --git a/ext/fiddle/lib/fiddle/function.rb b/ext/fiddle/lib/fiddle/function.rb deleted file mode 100644 index dc2e3e6bf5..0000000000 --- a/ext/fiddle/lib/fiddle/function.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -module Fiddle - class Function - # The ABI of the Function. - attr_reader :abi - - # The address of this function - attr_reader :ptr - - # The name of this function - attr_reader :name - - # Whether GVL is needed to call this function - def need_gvl? - @need_gvl - end - - # The integer memory location of this function - def to_i - ptr.to_i - end - - # Turn this function in to a proc - def to_proc - this = self - lambda { |*args| this.call(*args) } - end - end -end diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb deleted file mode 100644 index 09ffcef544..0000000000 --- a/ext/fiddle/lib/fiddle/import.rb +++ /dev/null @@ -1,320 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' -require 'fiddle/struct' -require 'fiddle/cparser' - -module Fiddle - - # Used internally by Fiddle::Importer - class CompositeHandler - # Create a new handler with the open +handlers+ - # - # Used internally by Fiddle::Importer.dlload - def initialize(handlers) - @handlers = handlers - end - - # Array of the currently loaded libraries. - def handlers() - @handlers - end - - # Returns the address as an Integer from any handlers with the function - # named +symbol+. - # - # Raises a DLError if the handle is closed. - def sym(symbol) - @handlers.each{|handle| - if( handle ) - begin - addr = handle.sym(symbol) - return addr - rescue DLError - end - end - } - return nil - end - - # See Fiddle::CompositeHandler.sym - def [](symbol) - sym(symbol) - end - end - - # A DSL that provides the means to dynamically load libraries and build - # modules around them including calling extern functions within the C - # library that has been loaded. - # - # == Example - # - # require 'fiddle' - # require 'fiddle/import' - # - # module LibSum - # extend Fiddle::Importer - # dlload './libsum.so' - # extern 'double sum(double*, int)' - # extern 'double split(double)' - # end - # - module Importer - include Fiddle - include CParser - extend Importer - - attr_reader :type_alias - private :type_alias - - # Creates an array of handlers for the given +libs+, can be an instance of - # Fiddle::Handle, Fiddle::Importer, or will create a new instance of - # Fiddle::Handle using Fiddle.dlopen - # - # Raises a DLError if the library cannot be loaded. - # - # See Fiddle.dlopen - def dlload(*libs) - handles = libs.collect{|lib| - case lib - when nil - nil - when Handle - lib - when Importer - lib.handlers - else - Fiddle.dlopen(lib) - end - }.flatten() - @handler = CompositeHandler.new(handles) - @func_map = {} - @type_alias = {} - end - - # Sets the type alias for +alias_type+ as +orig_type+ - def typealias(alias_type, orig_type) - @type_alias[alias_type] = orig_type - end - - # Returns the sizeof +ty+, using Fiddle::Importer.parse_ctype to determine - # the C type and the appropriate Fiddle constant. - def sizeof(ty) - case ty - when String - ty = parse_ctype(ty, type_alias).abs() - case ty - when TYPE_CHAR - return SIZEOF_CHAR - when TYPE_SHORT - return SIZEOF_SHORT - when TYPE_INT - return SIZEOF_INT - when TYPE_LONG - return SIZEOF_LONG - when TYPE_FLOAT - return SIZEOF_FLOAT - when TYPE_DOUBLE - return SIZEOF_DOUBLE - when TYPE_VOIDP - return SIZEOF_VOIDP - when TYPE_CONST_STRING - return SIZEOF_CONST_STRING - else - if defined?(TYPE_LONG_LONG) and - ty == TYPE_LONG_LONG - return SIZEOF_LONG_LONG - else - raise(DLError, "unknown type: #{ty}") - end - end - when Class - if( ty.instance_methods().include?(:to_ptr) ) - return ty.size() - end - end - return Pointer[ty].size() - end - - def parse_bind_options(opts) - h = {} - while( opt = opts.shift() ) - case opt - when :stdcall, :cdecl - h[:call_type] = opt - when :carried, :temp, :temporal, :bind - h[:callback_type] = opt - h[:carrier] = opts.shift() - else - h[opt] = true - end - end - h - end - private :parse_bind_options - - # :stopdoc: - CALL_TYPE_TO_ABI = Hash.new { |h, k| - raise RuntimeError, "unsupported call type: #{k}" - }.merge({ :stdcall => Function.const_defined?(:STDCALL) ? Function::STDCALL : - Function::DEFAULT, - :cdecl => Function::DEFAULT, - nil => Function::DEFAULT - }).freeze - private_constant :CALL_TYPE_TO_ABI - # :startdoc: - - # Creates a global method from the given C +signature+. - def extern(signature, *opts) - symname, ctype, argtype = parse_signature(signature, type_alias) - opt = parse_bind_options(opts) - f = import_function(symname, ctype, argtype, opt[:call_type]) - name = symname.gsub(/@.+/,'') - @func_map[name] = f - # define_method(name){|*args,&block| f.call(*args,&block)} - begin - /^(.+?):(\d+)/ =~ caller.first - file, line = $1, $2.to_i - rescue - file, line = __FILE__, __LINE__+3 - end - module_eval(<<-EOS, file, line) - def #{name}(*args, &block) - @func_map['#{name}'].call(*args,&block) - end - EOS - module_function(name) - f - end - - # Creates a global method from the given C +signature+ using the given - # +opts+ as bind parameters with the given block. - def bind(signature, *opts, &blk) - name, ctype, argtype = parse_signature(signature, type_alias) - h = parse_bind_options(opts) - case h[:callback_type] - when :bind, nil - f = bind_function(name, ctype, argtype, h[:call_type], &blk) - else - raise(RuntimeError, "unknown callback type: #{h[:callback_type]}") - end - @func_map[name] = f - #define_method(name){|*args,&block| f.call(*args,&block)} - begin - /^(.+?):(\d+)/ =~ caller.first - file, line = $1, $2.to_i - rescue - file, line = __FILE__, __LINE__+3 - end - module_eval(<<-EOS, file, line) - def #{name}(*args,&block) - @func_map['#{name}'].call(*args,&block) - end - EOS - module_function(name) - f - end - - # Creates a class to wrap the C struct described by +signature+. - # - # MyStruct = struct ['int i', 'char c'] - def struct(signature) - tys, mems = parse_struct_signature(signature, type_alias) - Fiddle::CStructBuilder.create(CStruct, tys, mems) - end - - # Creates a class to wrap the C union described by +signature+. - # - # MyUnion = union ['int i', 'char c'] - def union(signature) - tys, mems = parse_struct_signature(signature, type_alias) - Fiddle::CStructBuilder.create(CUnion, tys, mems) - end - - # Returns the function mapped to +name+, that was created by either - # Fiddle::Importer.extern or Fiddle::Importer.bind - def [](name) - @func_map[name] - end - - # Creates a class to wrap the C struct with the value +ty+ - # - # See also Fiddle::Importer.struct - def create_value(ty, val=nil) - s = struct([ty + " value"]) - ptr = s.malloc() - if( val ) - ptr.value = val - end - return ptr - end - alias value create_value - - # Returns a new instance of the C struct with the value +ty+ at the +addr+ - # address. - def import_value(ty, addr) - s = struct([ty + " value"]) - ptr = s.new(addr) - return ptr - end - - - # The Fiddle::CompositeHandler instance - # - # Will raise an error if no handlers are open. - def handler - (@handler ||= nil) or raise "call dlload before importing symbols and functions" - end - - # Returns a new Fiddle::Pointer instance at the memory address of the given - # +name+ symbol. - # - # Raises a DLError if the +name+ doesn't exist. - # - # See Fiddle::CompositeHandler.sym and Fiddle::Handle.sym - def import_symbol(name) - addr = handler.sym(name) - if( !addr ) - raise(DLError, "cannot find the symbol: #{name}") - end - Pointer.new(addr) - end - - # Returns a new Fiddle::Function instance at the memory address of the given - # +name+ function. - # - # Raises a DLError if the +name+ doesn't exist. - # - # * +argtype+ is an Array of arguments, passed to the +name+ function. - # * +ctype+ is the return type of the function - # * +call_type+ is the ABI of the function - # - # See also Fiddle:Function.new - # - # See Fiddle::CompositeHandler.sym and Fiddle::Handler.sym - def import_function(name, ctype, argtype, call_type = nil) - addr = handler.sym(name) - if( !addr ) - raise(DLError, "cannot find the function: #{name}()") - end - Function.new(addr, argtype, ctype, CALL_TYPE_TO_ABI[call_type], - name: name) - end - - # Returns a new closure wrapper for the +name+ function. - # - # * +ctype+ is the return type of the function - # * +argtype+ is an Array of arguments, passed to the callback function - # * +call_type+ is the abi of the closure - # * +block+ is passed to the callback - # - # See Fiddle::Closure - def bind_function(name, ctype, argtype, call_type = nil, &block) - abi = CALL_TYPE_TO_ABI[call_type] - closure = Class.new(Fiddle::Closure) { - define_method(:call, block) - }.new(ctype, argtype, abi) - - Function.new(closure, argtype, ctype, abi, name: name) - end - end -end diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb deleted file mode 100644 index 22eccedb76..0000000000 --- a/ext/fiddle/lib/fiddle/pack.rb +++ /dev/null @@ -1,136 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' - -module Fiddle - module PackInfo # :nodoc: all - ALIGN_MAP = { - TYPE_VOIDP => ALIGN_VOIDP, - TYPE_CHAR => ALIGN_CHAR, - TYPE_SHORT => ALIGN_SHORT, - TYPE_INT => ALIGN_INT, - TYPE_LONG => ALIGN_LONG, - TYPE_FLOAT => ALIGN_FLOAT, - TYPE_DOUBLE => ALIGN_DOUBLE, - -TYPE_CHAR => ALIGN_CHAR, - -TYPE_SHORT => ALIGN_SHORT, - -TYPE_INT => ALIGN_INT, - -TYPE_LONG => ALIGN_LONG, - } - - PACK_MAP = { - TYPE_VOIDP => "l!", - TYPE_CHAR => "c", - TYPE_SHORT => "s!", - TYPE_INT => "i!", - TYPE_LONG => "l!", - TYPE_FLOAT => "f", - TYPE_DOUBLE => "d", - -TYPE_CHAR => "c", - -TYPE_SHORT => "s!", - -TYPE_INT => "i!", - -TYPE_LONG => "l!", - } - - SIZE_MAP = { - TYPE_VOIDP => SIZEOF_VOIDP, - TYPE_CHAR => SIZEOF_CHAR, - TYPE_SHORT => SIZEOF_SHORT, - TYPE_INT => SIZEOF_INT, - TYPE_LONG => SIZEOF_LONG, - TYPE_FLOAT => SIZEOF_FLOAT, - TYPE_DOUBLE => SIZEOF_DOUBLE, - -TYPE_CHAR => SIZEOF_CHAR, - -TYPE_SHORT => SIZEOF_SHORT, - -TYPE_INT => SIZEOF_INT, - -TYPE_LONG => SIZEOF_LONG, - } - if defined?(TYPE_LONG_LONG) - ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG - PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q" - SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG - PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP - end - - def align(addr, align) - d = addr % align - if( d == 0 ) - addr - else - addr + (align - d) - end - end - module_function :align - end - - class Packer # :nodoc: all - include PackInfo - - def self.[](*types) - new(types) - end - - def initialize(types) - parse_types(types) - end - - def size() - @size - end - - def pack(ary) - case SIZEOF_VOIDP - when SIZEOF_LONG - ary.pack(@template) - else - if defined?(TYPE_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - ary.pack(@template) - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - - def unpack(ary) - case SIZEOF_VOIDP - when SIZEOF_LONG - ary.join().unpack(@template) - else - if defined?(TYPE_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - ary.join().unpack(@template) - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - - private - - def parse_types(types) - @template = "".dup - addr = 0 - types.each{|t| - orig_addr = addr - if( t.is_a?(Array) ) - addr = align(orig_addr, ALIGN_MAP[TYPE_VOIDP]) - else - addr = align(orig_addr, ALIGN_MAP[t]) - end - d = addr - orig_addr - if( d > 0 ) - @template << "x#{d}" - end - if( t.is_a?(Array) ) - @template << (PACK_MAP[t[0]] * t[1]) - addr += (SIZE_MAP[t[0]] * t[1]) - else - @template << PACK_MAP[t] - addr += SIZE_MAP[t] - end - } - addr = align(addr, ALIGN_MAP[TYPE_VOIDP]) - @size = addr - end - end -end diff --git a/ext/fiddle/lib/fiddle/struct.rb b/ext/fiddle/lib/fiddle/struct.rb deleted file mode 100644 index 6d05bbd742..0000000000 --- a/ext/fiddle/lib/fiddle/struct.rb +++ /dev/null @@ -1,539 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' -require 'fiddle/value' -require 'fiddle/pack' - -module Fiddle - # A base class for objects representing a C structure - class CStruct - include Enumerable - - # accessor to Fiddle::CStructEntity - def CStruct.entity_class - CStructEntity - end - - def self.offsetof(name, members, types) # :nodoc: - offset = 0 - worklist = name.split('.') - this_type = self - while search_name = worklist.shift - index = 0 - member_index = members.index(search_name) - - unless member_index - # Possibly a sub-structure - member_index = members.index { |member_name, _| - member_name == search_name - } - return unless member_index - end - - types.each { |type, count = 1| - orig_offset = offset - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = PackInfo::ALIGN_MAP[type] - type_size = PackInfo::SIZE_MAP[type] - end - - # Unions shouldn't advance the offset - if this_type.entity_class == CUnionEntity - type_size = 0 - end - - offset = PackInfo.align(orig_offset, align) - - if worklist.empty? - return offset if index == member_index - else - if index == member_index - subtype = types[member_index] - members = subtype.members - types = subtype.types - this_type = subtype - break - end - end - - offset += (type_size * count) - index += 1 - } - end - nil - end - - def each - return enum_for(__function__) unless block_given? - - self.class.members.each do |name,| - yield(self[name]) - end - end - - def each_pair - return enum_for(__function__) unless block_given? - - self.class.members.each do |name,| - yield(name, self[name]) - end - end - - def to_h - hash = {} - each_pair do |name, value| - hash[name] = unstruct(value) - end - hash - end - - def replace(another) - if another.nil? - self.class.members.each do |name,| - self[name] = nil - end - elsif another.respond_to?(:each_pair) - another.each_pair do |name, value| - self[name] = value - end - else - another.each do |name, value| - self[name] = value - end - end - self - end - - private - def unstruct(value) - case value - when CStruct - value.to_h - when Array - value.collect do |v| - unstruct(v) - end - else - value - end - end - end - - # A base class for objects representing a C union - class CUnion - # accessor to Fiddle::CUnionEntity - def CUnion.entity_class - CUnionEntity - end - - def self.offsetof(name, members, types) # :nodoc: - 0 - end - end - - # Wrapper for arrays within a struct - class StructArray < Array - include ValueUtil - - def initialize(ptr, type, initial_values) - @ptr = ptr - @type = type - @is_struct = @type.respond_to?(:entity_class) - if @is_struct - super(initial_values) - else - @size = Fiddle::PackInfo::SIZE_MAP[type] - @pack_format = Fiddle::PackInfo::PACK_MAP[type] - super(initial_values.collect { |v| unsigned_value(v, type) }) - end - end - - def to_ptr - @ptr - end - - def []=(index, value) - if index < 0 || index >= size - raise IndexError, 'index %d outside of array bounds 0...%d' % [index, size] - end - - if @is_struct - self[index].replace(value) - else - to_ptr[index * @size, @size] = [value].pack(@pack_format) - super(index, value) - end - end - end - - # Used to construct C classes (CUnion, CStruct, etc) - # - # Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an - # easy-to-use manner. - module CStructBuilder - # Construct a new class given a C: - # * class +klass+ (CUnion, CStruct, or other that provide an - # #entity_class) - # * +types+ (Fiddle::TYPE_INT, Fiddle::TYPE_SIZE_T, etc., see the C types - # constants) - # * corresponding +members+ - # - # Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an - # easy-to-use manner. - # - # Examples: - # - # require 'fiddle/struct' - # require 'fiddle/cparser' - # - # include Fiddle::CParser - # - # types, members = parse_struct_signature(['int i','char c']) - # - # MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members) - # - # MyStruct.malloc(Fiddle::RUBY_FREE) do |obj| - # ... - # end - # - # obj = MyStruct.malloc(Fiddle::RUBY_FREE) - # begin - # ... - # ensure - # obj.call_free - # end - # - # obj = MyStruct.malloc - # begin - # ... - # ensure - # Fiddle.free obj.to_ptr - # end - # - def create(klass, types, members) - new_class = Class.new(klass){ - define_method(:initialize){|addr, func = nil| - if addr.is_a?(self.class.entity_class) - @entity = addr - else - @entity = self.class.entity_class.new(addr, types, func) - end - @entity.assign_names(members) - } - define_method(:[]) { |*args| @entity.send(:[], *args) } - define_method(:[]=) { |*args| @entity.send(:[]=, *args) } - define_method(:to_ptr){ @entity } - define_method(:to_i){ @entity.to_i } - define_singleton_method(:types) { types } - define_singleton_method(:members) { members } - - # Return the offset of a struct member given its name. - # For example: - # - # MyStruct = struct [ - # "int64_t i", - # "char c", - # ] - # - # MyStruct.offsetof("i") # => 0 - # MyStruct.offsetof("c") # => 8 - # - define_singleton_method(:offsetof) { |name| - klass.offsetof(name, members, types) - } - members.each{|name| - name = name[0] if name.is_a?(Array) # name is a nested struct - next if method_defined?(name) - define_method(name){ @entity[name] } - define_method(name + "="){|val| @entity[name] = val } - } - entity_class = klass.entity_class - alignment = entity_class.alignment(types) - size = entity_class.size(types) - define_singleton_method(:alignment) { alignment } - define_singleton_method(:size) { size } - define_singleton_method(:malloc) do |func=nil, &block| - if block - entity_class.malloc(types, func, size) do |entity| - block.call(new(entity)) - end - else - new(entity_class.malloc(types, func, size)) - end - end - } - return new_class - end - module_function :create - end - - # A pointer to a C structure - class CStructEntity < Fiddle::Pointer - include PackInfo - include ValueUtil - - def CStructEntity.alignment(types) - max = 1 - types.each do |type, count = 1| - if type.respond_to?(:entity_class) - n = type.alignment - else - n = ALIGN_MAP[type] - end - max = n if n > max - end - max - end - - # Allocates a C struct with the +types+ provided. - # - # See Fiddle::Pointer.malloc for memory management issues. - def CStructEntity.malloc(types, func = nil, size = size(types), &block) - if block_given? - super(size, func) do |struct| - struct.set_ctypes types - yield struct - end - else - struct = super(size, func) - struct.set_ctypes types - struct - end - end - - # Returns the offset for the packed sizes for the given +types+. - # - # Fiddle::CStructEntity.size( - # [ Fiddle::TYPE_DOUBLE, - # Fiddle::TYPE_INT, - # Fiddle::TYPE_CHAR, - # Fiddle::TYPE_VOIDP ]) #=> 24 - def CStructEntity.size(types) - offset = 0 - - max_align = types.map { |type, count = 1| - last_offset = offset - - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = PackInfo::ALIGN_MAP[type] - type_size = PackInfo::SIZE_MAP[type] - end - offset = PackInfo.align(last_offset, align) + - (type_size * count) - - align - }.max - - PackInfo.align(offset, max_align) - end - - # Wraps the C pointer +addr+ as a C struct with the given +types+. - # - # When the instance is garbage collected, the C function +func+ is called. - # - # See also Fiddle::Pointer.new - def initialize(addr, types, func = nil) - if func && addr.is_a?(Pointer) && addr.free - raise ArgumentError, 'free function specified on both underlying struct Pointer and when creating a CStructEntity - who do you want to free this?' - end - set_ctypes(types) - super(addr, @size, func) - end - - # Set the names of the +members+ in this C struct - def assign_names(members) - @members = [] - @nested_structs = {} - members.each_with_index do |member, index| - if member.is_a?(Array) # nested struct - member_name = member[0] - struct_type, struct_count = @ctypes[index] - if struct_count.nil? - struct = struct_type.new(to_i + @offset[index]) - else - structs = struct_count.times.map do |i| - struct_type.new(to_i + @offset[index] + i * struct_type.size) - end - struct = StructArray.new(to_i + @offset[index], - struct_type, - structs) - end - @nested_structs[member_name] = struct - else - member_name = member - end - @members << member_name - end - end - - # Calculates the offsets and sizes for the given +types+ in the struct. - def set_ctypes(types) - @ctypes = types - @offset = [] - offset = 0 - - max_align = types.map { |type, count = 1| - orig_offset = offset - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = ALIGN_MAP[type] - type_size = SIZE_MAP[type] - end - offset = PackInfo.align(orig_offset, align) - - @offset << offset - - offset += (type_size * count) - - align - }.max - - @size = PackInfo.align(offset, max_align) - end - - # Fetch struct member +name+ if only one argument is specified. If two - # arguments are specified, the first is an offset and the second is a - # length and this method returns the string of +length+ bytes beginning at - # +offset+. - # - # Examples: - # - # my_struct = struct(['int id']).malloc - # my_struct.id = 1 - # my_struct['id'] # => 1 - # my_struct[0, 4] # => "\x01\x00\x00\x00".b - # - def [](*args) - return super(*args) if args.size > 1 - name = args[0] - idx = @members.index(name) - if( idx.nil? ) - raise(ArgumentError, "no such member: #{name}") - end - ty = @ctypes[idx] - if( ty.is_a?(Array) ) - if ty.first.respond_to?(:entity_class) - return @nested_structs[name] - else - r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1]) - end - elsif ty.respond_to?(:entity_class) - return @nested_structs[name] - else - r = super(@offset[idx], SIZE_MAP[ty.abs]) - end - packer = Packer.new([ty]) - val = packer.unpack([r]) - case ty - when Array - case ty[0] - when TYPE_VOIDP - val = val.collect{|v| Pointer.new(v)} - end - when TYPE_VOIDP - val = Pointer.new(val[0]) - else - val = val[0] - end - if( ty.is_a?(Integer) && (ty < 0) ) - return unsigned_value(val, ty) - elsif( ty.is_a?(Array) && (ty[0] < 0) ) - return StructArray.new(self + @offset[idx], ty[0], val) - else - return val - end - end - - # Set struct member +name+, to value +val+. If more arguments are - # specified, writes the string of bytes to the memory at the given - # +offset+ and +length+. - # - # Examples: - # - # my_struct = struct(['int id']).malloc - # my_struct['id'] = 1 - # my_struct[0, 4] = "\x01\x00\x00\x00".b - # my_struct.id # => 1 - # - def []=(*args) - return super(*args) if args.size > 2 - name, val = *args - name = name.to_s if name.is_a?(Symbol) - nested_struct = @nested_structs[name] - if nested_struct - if nested_struct.is_a?(StructArray) - if val.nil? - nested_struct.each do |s| - s.replace(nil) - end - else - val.each_with_index do |v, i| - nested_struct[i] = v - end - end - else - nested_struct.replace(val) - end - return val - end - idx = @members.index(name) - if( idx.nil? ) - raise(ArgumentError, "no such member: #{name}") - end - ty = @ctypes[idx] - packer = Packer.new([ty]) - val = wrap_arg(val, ty, []) - buff = packer.pack([val].flatten()) - super(@offset[idx], buff.size, buff) - if( ty.is_a?(Integer) && (ty < 0) ) - return unsigned_value(val, ty) - elsif( ty.is_a?(Array) && (ty[0] < 0) ) - return val.collect{|v| unsigned_value(v,ty[0])} - else - return val - end - end - - undef_method :size= - def to_s() # :nodoc: - super(@size) - end - end - - # A pointer to a C union - class CUnionEntity < CStructEntity - include PackInfo - - # Returns the size needed for the union with the given +types+. - # - # Fiddle::CUnionEntity.size( - # [ Fiddle::TYPE_DOUBLE, - # Fiddle::TYPE_INT, - # Fiddle::TYPE_CHAR, - # Fiddle::TYPE_VOIDP ]) #=> 8 - def CUnionEntity.size(types) - types.map { |type, count = 1| - if type.respond_to?(:entity_class) - type.size * count - else - PackInfo::SIZE_MAP[type] * count - end - }.max - end - - # Calculate the necessary offset and for each union member with the given - # +types+ - def set_ctypes(types) - @ctypes = types - @offset = Array.new(types.length, 0) - @size = self.class.size types - end - end -end diff --git a/ext/fiddle/lib/fiddle/types.rb b/ext/fiddle/lib/fiddle/types.rb deleted file mode 100644 index 7baf31ec9e..0000000000 --- a/ext/fiddle/lib/fiddle/types.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true -module Fiddle - # Adds Windows type aliases to the including class for use with - # Fiddle::Importer. - # - # The aliases added are: - # * ATOM - # * BOOL - # * BYTE - # * DWORD - # * DWORD32 - # * DWORD64 - # * HANDLE - # * HDC - # * HINSTANCE - # * HWND - # * LPCSTR - # * LPSTR - # * PBYTE - # * PDWORD - # * PHANDLE - # * PVOID - # * PWORD - # * UCHAR - # * UINT - # * ULONG - # * WORD - module Win32Types - def included(m) # :nodoc: - # https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types - m.module_eval{ - typealias "ATOM", "WORD" - typealias "BOOL", "int" - typealias "BYTE", "unsigned char" - typealias "DWORD", "unsigned long" - typealias "DWORD32", "uint32_t" - typealias "DWORD64", "uint64_t" - typealias "HANDLE", "PVOID" - typealias "HDC", "HANDLE" - typealias "HINSTANCE", "HANDLE" - typealias "HWND", "HANDLE" - typealias "LPCSTR", "const char *" - typealias "LPSTR", "char *" - typealias "PBYTE", "BYTE *" - typealias "PDWORD", "DWORD *" - typealias "PHANDLE", "HANDLE *" - typealias "PVOID", "void *" - typealias "PWORD", "WORD *" - typealias "UCHAR", "unsigned char" - typealias "UINT", "unsigned int" - typealias "ULONG", "unsigned long" - typealias "WORD", "unsigned short" - } - end - module_function :included - end - - # Adds basic type aliases to the including class for use with Fiddle::Importer. - # - # The aliases added are +uint+ and +u_int+ (<tt>unsigned int</tt>) and - # +ulong+ and +u_long+ (<tt>unsigned long</tt>) - module BasicTypes - def included(m) # :nodoc: - m.module_eval{ - typealias "uint", "unsigned int" - typealias "u_int", "unsigned int" - typealias "ulong", "unsigned long" - typealias "u_long", "unsigned long" - } - end - module_function :included - end -end diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb deleted file mode 100644 index 01fec1c206..0000000000 --- a/ext/fiddle/lib/fiddle/value.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' - -module Fiddle - module ValueUtil #:nodoc: all - def unsigned_value(val, ty) - case ty.abs - when TYPE_CHAR - [val].pack("c").unpack("C")[0] - when TYPE_SHORT - [val].pack("s!").unpack("S!")[0] - when TYPE_INT - [val].pack("i!").unpack("I!")[0] - when TYPE_LONG - [val].pack("l!").unpack("L!")[0] - else - if defined?(TYPE_LONG_LONG) and - ty.abs == TYPE_LONG_LONG - [val].pack("q").unpack("Q")[0] - else - val - end - end - end - - def signed_value(val, ty) - case ty.abs - when TYPE_CHAR - [val].pack("C").unpack("c")[0] - when TYPE_SHORT - [val].pack("S!").unpack("s!")[0] - when TYPE_INT - [val].pack("I!").unpack("i!")[0] - when TYPE_LONG - [val].pack("L!").unpack("l!")[0] - else - if defined?(TYPE_LONG_LONG) and - ty.abs == TYPE_LONG_LONG - [val].pack("Q").unpack("q")[0] - else - val - end - end - end - - def wrap_args(args, tys, funcs, &block) - result = [] - tys ||= [] - args.each_with_index{|arg, idx| - result.push(wrap_arg(arg, tys[idx], funcs, &block)) - } - result - end - - def wrap_arg(arg, ty, funcs = [], &block) - funcs ||= [] - case arg - when nil - return 0 - when Pointer - return arg.to_i - when IO - case ty - when TYPE_VOIDP - return Pointer[arg].to_i - else - return arg.to_i - end - when Function - if( block ) - arg.bind_at_call(&block) - funcs.push(arg) - elsif !arg.bound? - raise(RuntimeError, "block must be given.") - end - return arg.to_i - when String - if( ty.is_a?(Array) ) - return arg.unpack('C*') - else - case SIZEOF_VOIDP - when SIZEOF_LONG - return [arg].pack("p").unpack("l!")[0] - else - if defined?(SIZEOF_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - return [arg].pack("p").unpack("q")[0] - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - when Float, Integer - return arg - when Array - if( ty.is_a?(Array) ) # used only by struct - case ty[0] - when TYPE_VOIDP - return arg.collect{|v| Integer(v)} - when TYPE_CHAR - if( arg.is_a?(String) ) - return val.unpack('C*') - end - end - return arg - else - return arg - end - else - if( arg.respond_to?(:to_ptr) ) - return arg.to_ptr.to_i - else - begin - return Integer(arg) - rescue - raise(ArgumentError, "unknown argument type: #{arg.class}") - end - end - end - end - end -end diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb deleted file mode 100644 index db6504b650..0000000000 --- a/ext/fiddle/lib/fiddle/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Fiddle - VERSION = "1.1.0" -end diff --git a/ext/fiddle/memory_view.c b/ext/fiddle/memory_view.c deleted file mode 100644 index fa66fc2c7b..0000000000 --- a/ext/fiddle/memory_view.c +++ /dev/null @@ -1,321 +0,0 @@ -#include <fiddle.h> - -#ifdef HAVE_RUBY_MEMORY_VIEW_H - -#include <stdbool.h> -#include <ruby/ruby.h> -#include <ruby/encoding.h> -#include <ruby/memory_view.h> - -#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG -# define INTPTR2NUM LL2NUM -# define UINTPTR2NUM ULL2NUM -#elif SIZEOF_INTPTR_T == SIZEOF_LONG -# define INTPTR2NUM LONG2NUM -# define UINTPTR2NUM ULONG2NUM -#else -# define INTPTR2NUM INT2NUM -# define UINTPTR2NUM UINT2NUM -#endif - -VALUE rb_cMemoryView = Qnil; - -struct memview_data { - rb_memory_view_t view; - rb_memory_view_item_component_t *members; - size_t n_members; -}; - -static void -fiddle_memview_mark(void *ptr) -{ - const struct memview_data *data = ptr; - rb_gc_mark(data->view.obj); -} - -static void -fiddle_memview_release(struct memview_data *data) -{ - if (NIL_P(data->view.obj)) return; - - rb_memory_view_release(&data->view); - data->view.obj = Qnil; - data->view.byte_size = 0; - if (data->members) { - xfree(data->members); - data->members = NULL; - data->n_members = 0; - } -} - -static void -fiddle_memview_free(void *ptr) -{ - struct memview_data *data = ptr; - fiddle_memview_release(data); - xfree(ptr); -} - -static size_t -fiddle_memview_memsize(const void *ptr) -{ - const struct memview_data *data = ptr; - return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.byte_size; -} - -static const rb_data_type_t fiddle_memview_data_type = { - "fiddle/memory_view", - {fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,}, -}; - -static VALUE -rb_fiddle_memview_s_allocate(VALUE klass) -{ - struct memview_data *data; - VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data); - data->view.obj = Qnil; - data->view.byte_size = 0; - data->members = NULL; - data->n_members = 0; - return obj; -} - -static VALUE -rb_fiddle_memview_release(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - fiddle_memview_release(data); - return Qnil; -} - -static VALUE -rb_fiddle_memview_s_export(VALUE klass, VALUE target) -{ - ID id_new; - CONST_ID(id_new, "new"); - VALUE memview = rb_funcall(klass, id_new, 1, target); - return rb_ensure(rb_yield, memview, rb_fiddle_memview_release, memview); -} - -static VALUE -rb_fiddle_memview_initialize(VALUE obj, VALUE target) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (!rb_memory_view_get(target, &data->view, 0)) { - data->view.obj = Qnil; - rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target); - } - - return Qnil; -} - -static VALUE -rb_fiddle_memview_get_obj(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - return data->view.obj; -} - -static VALUE -rb_fiddle_memview_get_byte_size(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - return SSIZET2NUM(data->view.byte_size); -} - -static VALUE -rb_fiddle_memview_get_readonly(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - return data->view.readonly ? Qtrue : Qfalse; -} - -static VALUE -rb_fiddle_memview_get_format(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - return data->view.format == NULL ? Qnil : rb_str_new_cstr(data->view.format); -} - -static VALUE -rb_fiddle_memview_get_item_size(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - return SSIZET2NUM(data->view.item_size); -} - -static VALUE -rb_fiddle_memview_get_ndim(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - return SSIZET2NUM(data->view.ndim); -} - -static VALUE -rb_fiddle_memview_get_shape(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - if (data->view.shape == NULL) return Qnil; - - const ssize_t ndim = data->view.ndim; - VALUE shape = rb_ary_new_capa(ndim); - ssize_t i; - for (i = 0; i < ndim; ++i) { - rb_ary_push(shape, SSIZET2NUM(data->view.shape[i])); - } - return shape; -} - -static VALUE -rb_fiddle_memview_get_strides(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - if (data->view.strides == NULL) return Qnil; - - const ssize_t ndim = data->view.ndim; - VALUE strides = rb_ary_new_capa(ndim); - ssize_t i; - for (i = 0; i < ndim; ++i) { - rb_ary_push(strides, SSIZET2NUM(data->view.strides[i])); - } - return strides; -} - -static VALUE -rb_fiddle_memview_get_sub_offsets(VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - if (data->view.sub_offsets == NULL) return Qnil; - - const ssize_t ndim = data->view.ndim; - VALUE sub_offsets = rb_ary_new_capa(ndim); - ssize_t i; - for (i = 0; i < ndim; ++i) { - rb_ary_push(sub_offsets, SSIZET2NUM(data->view.sub_offsets[i])); - } - return sub_offsets; -} - -static VALUE -rb_fiddle_memview_aref(int argc, VALUE *argv, VALUE obj) -{ - struct memview_data *data; - TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); - - if (NIL_P(data->view.obj)) return Qnil; - - const ssize_t ndim = data->view.ndim; - if (argc != ndim) { - rb_raise(rb_eIndexError, "wrong number of index (%d for %"PRIdSIZE")", argc, ndim); - } - - VALUE indices_v = 0; - ssize_t *indices = ALLOCV_N(ssize_t, indices_v, ndim); - - ssize_t i; - for (i = 0; i < ndim; ++i) { - ssize_t x = NUM2SSIZET(argv[i]); - indices[i] = x; - } - - uint8_t *ptr = rb_memory_view_get_item_pointer(&data->view, indices); - ALLOCV_END(indices_v); - - if (data->view.format == NULL) { - return INT2FIX(*ptr); - } - - if (!data->members) { - const char *err; - if (rb_memory_view_parse_item_format(data->view.format, &data->members, &data->n_members, &err) < 0) { - rb_raise(rb_eRuntimeError, "Unable to recognize item format at %"PRIdSIZE" in \"%s\"", - err - data->view.format, data->view.format); - } - } - - return rb_memory_view_extract_item_members(ptr, data->members, data->n_members); -} - -static VALUE -rb_fiddle_memview_to_s(VALUE self) -{ - struct memview_data *data; - const char *raw_data; - long byte_size; - VALUE string; - - TypedData_Get_Struct(self, - struct memview_data, - &fiddle_memview_data_type, - data); - - if (NIL_P(data->view.obj)) { - raw_data = NULL; - byte_size = 0; - } else { - raw_data = data->view.data; - byte_size = data->view.byte_size; - } - - string = rb_enc_str_new_static(raw_data, byte_size, rb_ascii8bit_encoding()); - { - ID id_memory_view; - CONST_ID(id_memory_view, "memory_view"); - rb_ivar_set(string, id_memory_view, self); - } - return rb_obj_freeze(string); -} - -void -Init_fiddle_memory_view(void) -{ - rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject); - rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate); - rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, 1); - rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1); - rb_define_method(rb_cMemoryView, "release", rb_fiddle_memview_release, 0); - rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0); - rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0); - rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0); - rb_define_method(rb_cMemoryView, "format", rb_fiddle_memview_get_format, 0); - rb_define_method(rb_cMemoryView, "item_size", rb_fiddle_memview_get_item_size, 0); - rb_define_method(rb_cMemoryView, "ndim", rb_fiddle_memview_get_ndim, 0); - rb_define_method(rb_cMemoryView, "shape", rb_fiddle_memview_get_shape, 0); - rb_define_method(rb_cMemoryView, "strides", rb_fiddle_memview_get_strides, 0); - rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0); - rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1); - rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0); -} - -#endif /* HAVE_RUBY_MEMORY_VIEW_H */ diff --git a/ext/fiddle/pinned.c b/ext/fiddle/pinned.c deleted file mode 100644 index 019a3020e2..0000000000 --- a/ext/fiddle/pinned.c +++ /dev/null @@ -1,123 +0,0 @@ -#include <fiddle.h> - -VALUE rb_cPinned; -VALUE rb_eFiddleClearedReferenceError; - -struct pinned_data { - VALUE ptr; -}; - -static void -pinned_mark(void *ptr) -{ - struct pinned_data *data = (struct pinned_data*)ptr; - /* Ensure reference is pinned */ - if (data->ptr) { - rb_gc_mark(data->ptr); - } -} - -static size_t -pinned_memsize(const void *ptr) -{ - return sizeof(struct pinned_data); -} - -static const rb_data_type_t pinned_data_type = { - "fiddle/pinned", - {pinned_mark, xfree, pinned_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED -}; - -static VALUE -allocate(VALUE klass) -{ - struct pinned_data *data; - VALUE obj = TypedData_Make_Struct(klass, struct pinned_data, &pinned_data_type, data); - data->ptr = 0; - return obj; -} - -/* - * call-seq: - * Fiddle::Pinned.new(object) => pinned_object - * - * Create a new pinned object reference. The Fiddle::Pinned instance will - * prevent the GC from moving +object+. - */ -static VALUE -initialize(VALUE self, VALUE ref) -{ - struct pinned_data *data; - TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data); - RB_OBJ_WRITE(self, &data->ptr, ref); - return self; -} - -/* - * call-seq: ref - * - * Return the object that this pinned instance references. - */ -static VALUE -ref(VALUE self) -{ - struct pinned_data *data; - TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data); - if (data->ptr) { - return data->ptr; - } else { - rb_raise(rb_eFiddleClearedReferenceError, "`ref` called on a cleared object"); - } -} - -/* - * call-seq: clear - * - * Clear the reference to the object this is pinning. - */ -static VALUE -clear(VALUE self) -{ - struct pinned_data *data; - TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data); - data->ptr = 0; - return self; -} - -/* - * call-seq: cleared? - * - * Returns true if the reference has been cleared, otherwise returns false. - */ -static VALUE -cleared_p(VALUE self) -{ - struct pinned_data *data; - TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data); - if (data->ptr) { - return Qfalse; - } else { - return Qtrue; - } -} - -extern VALUE rb_eFiddleError; - -void -Init_fiddle_pinned(void) -{ - rb_cPinned = rb_define_class_under(mFiddle, "Pinned", rb_cObject); - rb_define_alloc_func(rb_cPinned, allocate); - rb_define_method(rb_cPinned, "initialize", initialize, 1); - rb_define_method(rb_cPinned, "ref", ref, 0); - rb_define_method(rb_cPinned, "clear", clear, 0); - rb_define_method(rb_cPinned, "cleared?", cleared_p, 0); - - /* - * Document-class: Fiddle::ClearedReferenceError - * - * Cleared reference exception - */ - rb_eFiddleClearedReferenceError = rb_define_class_under(mFiddle, "ClearedReferenceError", rb_eFiddleError); -} diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c deleted file mode 100644 index 15107e3862..0000000000 --- a/ext/fiddle/pointer.c +++ /dev/null @@ -1,853 +0,0 @@ -/* -*- C -*- - * $Id$ - */ - -#include <stdbool.h> -#include <ruby/ruby.h> -#include <ruby/io.h> - -#include <ctype.h> -#include <fiddle.h> - -#ifdef HAVE_RUBY_MEMORY_VIEW_H -# include <ruby/memory_view.h> -#endif - -#ifdef PRIsVALUE -# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) -# define RB_OBJ_STRING(obj) (obj) -#else -# define PRIsVALUE "s" -# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) -# define RB_OBJ_STRING(obj) StringValueCStr(obj) -#endif - -VALUE rb_cPointer; - -typedef rb_fiddle_freefunc_t freefunc_t; - -struct ptr_data { - void *ptr; - long size; - freefunc_t free; - bool freed; - VALUE wrap[2]; -}; - -#define RPTR_DATA(obj) ((struct ptr_data *)(DATA_PTR(obj))) - -static inline freefunc_t -get_freefunc(VALUE func, volatile VALUE *wrap) -{ - VALUE addrnum; - if (NIL_P(func)) { - *wrap = 0; - return NULL; - } - addrnum = rb_Integer(func); - *wrap = (addrnum != func) ? func : 0; - return (freefunc_t)(VALUE)NUM2PTR(addrnum); -} - -static ID id_to_ptr; - -static void -fiddle_ptr_mark(void *ptr) -{ - struct ptr_data *data = ptr; - if (data->wrap[0]) { - rb_gc_mark(data->wrap[0]); - } - if (data->wrap[1]) { - rb_gc_mark(data->wrap[1]); - } -} - -static void -fiddle_ptr_free_ptr(void *ptr) -{ - struct ptr_data *data = ptr; - if (data->ptr && data->free && !data->freed) { - data->freed = true; - (*(data->free))(data->ptr); - } -} - -static void -fiddle_ptr_free(void *ptr) -{ - fiddle_ptr_free_ptr(ptr); - xfree(ptr); -} - -static size_t -fiddle_ptr_memsize(const void *ptr) -{ - const struct ptr_data *data = ptr; - return sizeof(*data) + data->size; -} - -static const rb_data_type_t fiddle_ptr_data_type = { - "fiddle/pointer", - {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,}, -}; - -#ifdef HAVE_RUBY_MEMORY_VIEW_H -static struct ptr_data * -fiddle_ptr_check_memory_view(VALUE obj) -{ - struct ptr_data *data; - TypedData_Get_Struct(obj, struct ptr_data, &fiddle_ptr_data_type, data); - if (data->ptr == NULL || data->size == 0) return NULL; - return data; -} - -static bool -fiddle_ptr_memory_view_available_p(VALUE obj) -{ - return fiddle_ptr_check_memory_view(obj) != NULL; -} - -static bool -fiddle_ptr_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags) -{ - struct ptr_data *data = fiddle_ptr_check_memory_view(obj); - rb_memory_view_init_as_byte_array(view, obj, data->ptr, data->size, true); - - return true; -} - -static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = { - fiddle_ptr_get_memory_view, - NULL, - fiddle_ptr_memory_view_available_p -}; -#endif - -static VALUE -rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1) -{ - struct ptr_data *data; - VALUE val; - - val = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data); - data->ptr = ptr; - data->free = func; - data->freed = false; - data->size = size; - data->wrap[0] = wrap0; - data->wrap[1] = wrap1; - - return val; -} - -VALUE -rb_fiddle_ptr_new_wrap(void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1) -{ - return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, wrap0, wrap1); -} - -static VALUE -rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func) -{ - return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, 0, 0); -} - -static VALUE -rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func) -{ - void *ptr; - - ptr = ruby_xmalloc((size_t)size); - memset(ptr,0,(size_t)size); - return rb_fiddle_ptr_new2(klass, ptr, size, func, 0, 0); -} - -static void * -rb_fiddle_ptr2cptr(VALUE val) -{ - struct ptr_data *data; - void *ptr; - - if (rb_obj_is_kind_of(val, rb_cPointer)) { - TypedData_Get_Struct(val, struct ptr_data, &fiddle_ptr_data_type, data); - ptr = data->ptr; - } - else if (val == Qnil) { - ptr = NULL; - } - else{ - rb_raise(rb_eTypeError, "Fiddle::Pointer was expected"); - } - - return ptr; -} - -static VALUE -rb_fiddle_ptr_s_allocate(VALUE klass) -{ - VALUE obj; - struct ptr_data *data; - - obj = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data); - data->ptr = 0; - data->size = 0; - data->free = 0; - data->freed = false; - - return obj; -} - -/* - * call-seq: - * Fiddle::Pointer.new(address) => fiddle_cptr - * new(address, size) => fiddle_cptr - * new(address, size, freefunc) => fiddle_cptr - * - * Create a new pointer to +address+ with an optional +size+ and +freefunc+. - * - * +freefunc+ will be called when the instance is garbage collected. - */ -static VALUE -rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self) -{ - VALUE ptr, sym, size, wrap = 0, funcwrap = 0; - struct ptr_data *data; - void *p = NULL; - freefunc_t f = NULL; - long s = 0; - - if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) { - VALUE addrnum = rb_Integer(ptr); - if (addrnum != ptr) wrap = ptr; - p = NUM2PTR(addrnum); - } - if (argc >= 2) { - s = NUM2LONG(size); - } - if (argc >= 3) { - f = get_freefunc(sym, &funcwrap); - } - - if (p) { - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - if (data->ptr && data->free) { - /* Free previous memory. Use of inappropriate initialize may cause SEGV. */ - (*(data->free))(data->ptr); - } - data->wrap[0] = wrap; - data->wrap[1] = funcwrap; - data->ptr = p; - data->size = s; - data->free = f; - } - - return Qnil; -} - -static VALUE -rb_fiddle_ptr_call_free(VALUE self); - -/* - * call-seq: - * Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance - * Fiddle::Pointer.malloc(size, freefunc) { |pointer| ... } => ... - * - * == Examples - * - * # Automatically freeing the pointer when the block is exited - recommended - * Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) do |pointer| - * ... - * end - * - * # Manually freeing but relying on the garbage collector otherwise - * pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) - * ... - * pointer.call_free - * - * # Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe - * pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) - * ... - * - * # Only manually freeing - * pointer = Fiddle::Pointer.malloc(size) - * begin - * ... - * ensure - * Fiddle.free pointer - * end - * - * # No free function and no call to free - the native memory will leak if the pointer is garbage collected - * pointer = Fiddle::Pointer.malloc(size) - * ... - * - * Allocate +size+ bytes of memory and associate it with an optional - * +freefunc+. - * - * If a block is supplied, the pointer will be yielded to the block instead of - * being returned, and the return value of the block will be returned. A - * +freefunc+ must be supplied if a block is. - * - * If a +freefunc+ is supplied it will be called once, when the pointer is - * garbage collected or when the block is left if a block is supplied or - * when the user calls +call_free+, whichever happens first. +freefunc+ must be - * an address pointing to a function or an instance of +Fiddle::Function+. - */ -static VALUE -rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass) -{ - VALUE size, sym, obj, wrap = 0; - long s; - freefunc_t f; - - switch (rb_scan_args(argc, argv, "11", &size, &sym)) { - case 1: - s = NUM2LONG(size); - f = NULL; - break; - case 2: - s = NUM2LONG(size); - f = get_freefunc(sym, &wrap); - break; - default: - rb_bug("rb_fiddle_ptr_s_malloc"); - } - - obj = rb_fiddle_ptr_malloc(klass, s,f); - if (wrap) RPTR_DATA(obj)->wrap[1] = wrap; - - if (rb_block_given_p()) { - if (!f) { - rb_raise(rb_eArgError, "a free function must be supplied to Fiddle::Pointer.malloc when it is called with a block"); - } - return rb_ensure(rb_yield, obj, rb_fiddle_ptr_call_free, obj); - } else { - return obj; - } -} - -/* - * call-seq: to_i - * - * Returns the integer memory location of this pointer. - */ -static VALUE -rb_fiddle_ptr_to_i(VALUE self) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return PTR2NUM(data->ptr); -} - -/* - * call-seq: to_value - * - * Cast this pointer to a ruby object. - */ -static VALUE -rb_fiddle_ptr_to_value(VALUE self) -{ - struct ptr_data *data; - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return (VALUE)(data->ptr); -} - -/* - * call-seq: ptr - * - * Returns a new Fiddle::Pointer instance that is a dereferenced pointer for - * this pointer. - * - * Analogous to the star operator in C. - */ -static VALUE -rb_fiddle_ptr_ptr(VALUE self) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0); -} - -/* - * call-seq: ref - * - * Returns a new Fiddle::Pointer instance that is a reference pointer for this - * pointer. - * - * Analogous to the ampersand operator in C. - */ -static VALUE -rb_fiddle_ptr_ref(VALUE self) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return rb_fiddle_ptr_new(&(data->ptr),0,0); -} - -/* - * call-seq: null? - * - * Returns +true+ if this is a null pointer. - */ -static VALUE -rb_fiddle_ptr_null_p(VALUE self) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return data->ptr ? Qfalse : Qtrue; -} - -/* - * call-seq: free=(function) - * - * Set the free function for this pointer to +function+ in the given - * Fiddle::Function. - */ -static VALUE -rb_fiddle_ptr_free_set(VALUE self, VALUE val) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - data->free = get_freefunc(val, &data->wrap[1]); - - return Qnil; -} - -/* - * call-seq: free => Fiddle::Function - * - * Get the free function for this pointer. - * - * Returns a new instance of Fiddle::Function. - * - * See Fiddle::Function.new - */ -static VALUE -rb_fiddle_ptr_free_get(VALUE self) -{ - struct ptr_data *pdata; - VALUE address; - VALUE arg_types; - VALUE ret_type; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); - - if (!pdata->free) - return Qnil; - - address = PTR2NUM(pdata->free); - ret_type = INT2NUM(TYPE_VOID); - arg_types = rb_ary_new(); - rb_ary_push(arg_types, INT2NUM(TYPE_VOIDP)); - - return rb_fiddle_new_function(address, arg_types, ret_type); -} - -/* - * call-seq: call_free => nil - * - * Call the free function for this pointer. Calling more than once will do - * nothing. Does nothing if there is no free function attached. - */ -static VALUE -rb_fiddle_ptr_call_free(VALUE self) -{ - struct ptr_data *pdata; - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); - fiddle_ptr_free_ptr(pdata); - return Qnil; -} - -/* - * call-seq: freed? => bool - * - * Returns if the free function for this pointer has been called. - */ -static VALUE -rb_fiddle_ptr_freed_p(VALUE self) -{ - struct ptr_data *pdata; - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata); - return pdata->freed ? Qtrue : Qfalse; -} - -/* - * call-seq: - * - * ptr.to_s => string - * ptr.to_s(len) => string - * - * Returns the pointer contents as a string. - * - * When called with no arguments, this method will return the contents until - * the first NULL byte. - * - * When called with +len+, a string of +len+ bytes will be returned. - * - * See to_str - */ -static VALUE -rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self) -{ - struct ptr_data *data; - VALUE arg1, val; - int len; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - switch (rb_scan_args(argc, argv, "01", &arg1)) { - case 0: - val = rb_str_new2((char*)(data->ptr)); - break; - case 1: - len = NUM2INT(arg1); - val = rb_str_new((char*)(data->ptr), len); - break; - default: - rb_bug("rb_fiddle_ptr_to_s"); - } - - return val; -} - -/* - * call-seq: - * - * ptr.to_str => string - * ptr.to_str(len) => string - * - * Returns the pointer contents as a string. - * - * When called with no arguments, this method will return the contents with the - * length of this pointer's +size+. - * - * When called with +len+, a string of +len+ bytes will be returned. - * - * See to_s - */ -static VALUE -rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self) -{ - struct ptr_data *data; - VALUE arg1, val; - int len; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - switch (rb_scan_args(argc, argv, "01", &arg1)) { - case 0: - val = rb_str_new((char*)(data->ptr),data->size); - break; - case 1: - len = NUM2INT(arg1); - val = rb_str_new((char*)(data->ptr), len); - break; - default: - rb_bug("rb_fiddle_ptr_to_str"); - } - - return val; -} - -/* - * call-seq: inspect - * - * Returns a string formatted with an easily readable representation of the - * internal state of the pointer. - */ -static VALUE -rb_fiddle_ptr_inspect(VALUE self) -{ - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>", - RB_OBJ_CLASSNAME(self), (void *)data, data->ptr, data->size, (void *)data->free); -} - -/* - * call-seq: - * ptr == other => true or false - * ptr.eql?(other) => true or false - * - * Returns true if +other+ wraps the same pointer, otherwise returns - * false. - */ -static VALUE -rb_fiddle_ptr_eql(VALUE self, VALUE other) -{ - void *ptr1, *ptr2; - - if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse; - - ptr1 = rb_fiddle_ptr2cptr(self); - ptr2 = rb_fiddle_ptr2cptr(other); - - return ptr1 == ptr2 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * ptr <=> other => -1, 0, 1, or nil - * - * Returns -1 if less than, 0 if equal to, 1 if greater than +other+. - * - * Returns nil if +ptr+ cannot be compared to +other+. - */ -static VALUE -rb_fiddle_ptr_cmp(VALUE self, VALUE other) -{ - void *ptr1, *ptr2; - SIGNED_VALUE diff; - - if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qnil; - - ptr1 = rb_fiddle_ptr2cptr(self); - ptr2 = rb_fiddle_ptr2cptr(other); - diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2; - if (!diff) return INT2FIX(0); - return diff > 0 ? INT2NUM(1) : INT2NUM(-1); -} - -/* - * call-seq: - * ptr + n => new cptr - * - * Returns a new pointer instance that has been advanced +n+ bytes. - */ -static VALUE -rb_fiddle_ptr_plus(VALUE self, VALUE other) -{ - void *ptr; - long num, size; - - ptr = rb_fiddle_ptr2cptr(self); - size = RPTR_DATA(self)->size; - num = NUM2LONG(other); - return rb_fiddle_ptr_new((char *)ptr + num, size - num, 0); -} - -/* - * call-seq: - * ptr - n => new cptr - * - * Returns a new pointer instance that has been moved back +n+ bytes. - */ -static VALUE -rb_fiddle_ptr_minus(VALUE self, VALUE other) -{ - void *ptr; - long num, size; - - ptr = rb_fiddle_ptr2cptr(self); - size = RPTR_DATA(self)->size; - num = NUM2LONG(other); - return rb_fiddle_ptr_new((char *)ptr - num, size + num, 0); -} - -/* - * call-seq: - * ptr[index] -> an_integer - * ptr[start, length] -> a_string - * - * Returns integer stored at _index_. - * - * If _start_ and _length_ are given, a string containing the bytes from - * _start_ of _length_ will be returned. - */ -static VALUE -rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self) -{ - VALUE arg0, arg1; - VALUE retval = Qnil; - size_t offset, len; - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference"); - switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){ - case 1: - offset = NUM2ULONG(arg0); - retval = INT2NUM(*((char *)data->ptr + offset)); - break; - case 2: - offset = NUM2ULONG(arg0); - len = NUM2ULONG(arg1); - retval = rb_str_new((char *)data->ptr + offset, len); - break; - default: - rb_bug("rb_fiddle_ptr_aref()"); - } - return retval; -} - -/* - * call-seq: - * ptr[index] = int -> int - * ptr[start, length] = string or cptr or addr -> string or dl_cptr or addr - * - * Set the value at +index+ to +int+. - * - * Or, set the memory at +start+ until +length+ with the contents of +string+, - * the memory from +dl_cptr+, or the memory pointed at by the memory address - * +addr+. - */ -static VALUE -rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self) -{ - VALUE arg0, arg1, arg2; - VALUE retval = Qnil; - size_t offset, len; - void *mem; - struct ptr_data *data; - - TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data); - if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference"); - switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){ - case 2: - offset = NUM2ULONG(arg0); - ((char*)data->ptr)[offset] = NUM2UINT(arg1); - retval = arg1; - break; - case 3: - offset = NUM2ULONG(arg0); - len = NUM2ULONG(arg1); - if (RB_TYPE_P(arg2, T_STRING)) { - mem = StringValuePtr(arg2); - } - else if( rb_obj_is_kind_of(arg2, rb_cPointer) ){ - mem = rb_fiddle_ptr2cptr(arg2); - } - else{ - mem = NUM2PTR(arg2); - } - memcpy((char *)data->ptr + offset, mem, len); - retval = arg2; - break; - default: - rb_bug("rb_fiddle_ptr_aset()"); - } - return retval; -} - -/* - * call-seq: size=(size) - * - * Set the size of this pointer to +size+ - */ -static VALUE -rb_fiddle_ptr_size_set(VALUE self, VALUE size) -{ - RPTR_DATA(self)->size = NUM2LONG(size); - return size; -} - -/* - * call-seq: size - * - * Get the size of this pointer. - */ -static VALUE -rb_fiddle_ptr_size_get(VALUE self) -{ - return LONG2NUM(RPTR_DATA(self)->size); -} - -/* - * call-seq: - * Fiddle::Pointer[val] => cptr - * to_ptr(val) => cptr - * - * Get the underlying pointer for ruby object +val+ and return it as a - * Fiddle::Pointer object. - */ -static VALUE -rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val) -{ - VALUE ptr, wrap = val, vptr; - - if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){ - rb_io_t *fptr; - FILE *fp; - GetOpenFile(val, fptr); - fp = rb_io_stdio_file(fptr); - ptr = rb_fiddle_ptr_new(fp, 0, NULL); - } - else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){ - char *str = StringValuePtr(val); - wrap = val; - ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL); - } - else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){ - if (rb_obj_is_kind_of(vptr, rb_cPointer)){ - ptr = vptr; - wrap = 0; - } - else{ - rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object"); - } - } - else{ - VALUE num = rb_Integer(val); - if (num == val) wrap = 0; - ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL); - } - if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap; - return ptr; -} - -void -Init_fiddle_pointer(void) -{ -#undef rb_intern - id_to_ptr = rb_intern("to_ptr"); - - /* Document-class: Fiddle::Pointer - * - * Fiddle::Pointer is a class to handle C pointers - * - */ - rb_cPointer = rb_define_class_under(mFiddle, "Pointer", rb_cObject); - rb_define_alloc_func(rb_cPointer, rb_fiddle_ptr_s_allocate); - rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1); - rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1); - rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1); - rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1); - rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1); - rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0); - rb_define_method(rb_cPointer, "call_free", rb_fiddle_ptr_call_free, 0); - rb_define_method(rb_cPointer, "freed?", rb_fiddle_ptr_freed_p, 0); - rb_define_method(rb_cPointer, "to_i", rb_fiddle_ptr_to_i, 0); - rb_define_method(rb_cPointer, "to_int", rb_fiddle_ptr_to_i, 0); - rb_define_method(rb_cPointer, "to_value", rb_fiddle_ptr_to_value, 0); - rb_define_method(rb_cPointer, "ptr", rb_fiddle_ptr_ptr, 0); - rb_define_method(rb_cPointer, "+@", rb_fiddle_ptr_ptr, 0); - rb_define_method(rb_cPointer, "ref", rb_fiddle_ptr_ref, 0); - rb_define_method(rb_cPointer, "-@", rb_fiddle_ptr_ref, 0); - rb_define_method(rb_cPointer, "null?", rb_fiddle_ptr_null_p, 0); - rb_define_method(rb_cPointer, "to_s", rb_fiddle_ptr_to_s, -1); - rb_define_method(rb_cPointer, "to_str", rb_fiddle_ptr_to_str, -1); - rb_define_method(rb_cPointer, "inspect", rb_fiddle_ptr_inspect, 0); - rb_define_method(rb_cPointer, "<=>", rb_fiddle_ptr_cmp, 1); - rb_define_method(rb_cPointer, "==", rb_fiddle_ptr_eql, 1); - rb_define_method(rb_cPointer, "eql?", rb_fiddle_ptr_eql, 1); - rb_define_method(rb_cPointer, "+", rb_fiddle_ptr_plus, 1); - rb_define_method(rb_cPointer, "-", rb_fiddle_ptr_minus, 1); - rb_define_method(rb_cPointer, "[]", rb_fiddle_ptr_aref, -1); - rb_define_method(rb_cPointer, "[]=", rb_fiddle_ptr_aset, -1); - rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0); - rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1); - -#ifdef HAVE_RUBY_MEMORY_VIEW_H - rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry); -#endif - - /* Document-const: NULL - * - * A NULL pointer - */ - rb_define_const(mFiddle, "NULL", rb_fiddle_ptr_new(0, 0, 0)); -} diff --git a/ext/fiddle/win32/fficonfig.h b/ext/fiddle/win32/fficonfig.h deleted file mode 100644 index 776808159c..0000000000 --- a/ext/fiddle/win32/fficonfig.h +++ /dev/null @@ -1,29 +0,0 @@ -#define HAVE_ALLOCA 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 -#if _MSC_VER >= 1600 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#endif - -#define SIZEOF_DOUBLE 8 -#if defined(X86_WIN64) -#define SIZEOF_SIZE_T 8 -#else -#define SIZEOF_SIZE_T 4 -#endif - -#define STACK_DIRECTION -1 - -#define STDC_HEADERS 1 - -#ifdef LIBFFI_ASM -#define FFI_HIDDEN(name) -#else -#define FFI_HIDDEN -#endif - diff --git a/ext/fiddle/win32/libffi-3.2.1-mswin.patch b/ext/fiddle/win32/libffi-3.2.1-mswin.patch deleted file mode 100644 index f9100e703d..0000000000 --- a/ext/fiddle/win32/libffi-3.2.1-mswin.patch +++ /dev/null @@ -1,191 +0,0 @@ -diff -ru libffi-3.2.1/src/x86/ffi.c libffi-3.2.1/src/x86/ffi.c ---- libffi-3.2.1/src/x86/ffi.c 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/ffi.c 2014-12-25 18:46:14.806761900 +0900 -@@ -99,11 +99,13 @@ - i != 0; - i--, p_arg += dir, p_argv += dir) - { -+ size_t z; -+ - /* Align if necessary */ - if ((sizeof(void*) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void*)); - -- size_t z = (*p_arg)->size; -+ z = (*p_arg)->size; - - #ifdef X86_WIN64 - if (z > FFI_SIZEOF_ARG -@@ -202,6 +204,7 @@ - on top of stack, so that those can be moved to registers by call-handler. */ - if (stack_args_count > 0) - { -+ int i; - if (dir < 0 && stack_args_count > 1) - { - /* Reverse order if iterating arguments backwards */ -@@ -210,7 +213,6 @@ - *(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp; - } - -- int i; - for (i = 0; i < stack_args_count; i++) - { - if (p_stack_data[i] != argp2) -@@ -569,11 +571,12 @@ - i < cif->nargs && passed_regs < max_stack_count; - i++, p_arg++) - { -+ size_t sz; - if ((*p_arg)->type == FFI_TYPE_FLOAT - || (*p_arg)->type == FFI_TYPE_STRUCT) - continue; - -- size_t sz = (*p_arg)->size; -+ sz = (*p_arg)->size; - if(sz == 0 || sz > FFI_SIZEOF_ARG) - continue; - -@@ -599,11 +602,13 @@ - i != 0; - i--, p_arg += dir, p_argv += dir) - { -+ size_t z; -+ - /* Align if necessary */ - if ((sizeof(void*) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void*)); - -- size_t z = (*p_arg)->size; -+ z = (*p_arg)->size; - - #ifdef X86_WIN64 - if (z > FFI_SIZEOF_ARG -@@ -642,7 +647,7 @@ - #endif - } - -- return (size_t)argp - (size_t)stack; -+ return (int)((size_t)argp - (size_t)stack); - } - - #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \ -@@ -855,11 +860,12 @@ - - for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++) - { -+ size_t sz; - if (cif->arg_types[i]->type == FFI_TYPE_FLOAT - || cif->arg_types[i]->type == FFI_TYPE_STRUCT) - continue; - -- size_t sz = cif->arg_types[i]->size; -+ sz = cif->arg_types[i]->size; - if (sz == 0 || sz > FFI_SIZEOF_ARG) - continue; - -diff -ru libffi-3.2.1/src/x86/ffitarget.h libffi-3.2.1/src/x86/ffitarget.h ---- libffi-3.2.1/src/x86/ffitarget.h 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/ffitarget.h 2014-12-22 15:45:54.000000000 +0900 -@@ -50,7 +50,9 @@ - #endif - - #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION -+#ifndef _MSC_VER - #define FFI_TARGET_HAS_COMPLEX_TYPE -+#endif - - /* ---- Generic type definitions ----------------------------------------- */ - -diff -ru libffi-3.2.1/src/x86/win64.S libffi-3.2.1/src/x86/win64.S ---- libffi-3.2.1/src/x86/win64.S 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/win64.S 2014-12-22 16:14:40.000000000 +0900 -@@ -127,7 +127,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov DWORD PTR [rcx], eax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_struct2b$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B -@@ -135,7 +135,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov WORD PTR [rcx], ax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_struct1b$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B -@@ -143,7 +143,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov BYTE PTR [rcx], al -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_uint8$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8 -@@ -152,7 +152,7 @@ - mov rcx, QWORD PTR RVALUE[rbp] - movzx rax, al - mov QWORD PTR [rcx], rax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_sint8$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8 -@@ -161,7 +161,7 @@ - mov rcx, QWORD PTR RVALUE[rbp] - movsx rax, al - mov QWORD PTR [rcx], rax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_uint16$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16 -@@ -188,7 +188,13 @@ - mov rcx, QWORD PTR RVALUE[rbp] - mov eax, eax - mov QWORD PTR [rcx], rax -- jmp SHORT ret_void$ -+ -+ret_void$: -+ xor rax, rax -+ -+ lea rsp, QWORD PTR [rbp+16] -+ pop rbp -+ ret 0 - - ret_sint32$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32 -@@ -247,13 +253,6 @@ - cdqe - mov QWORD PTR [rcx], rax - jmp SHORT ret_void$ -- --ret_void$: -- xor rax, rax -- -- lea rsp, QWORD PTR [rbp+16] -- pop rbp -- ret 0 - ffi_call_win64 ENDP - _TEXT ENDS - END -diff -ru libffi-3.2.1/include/ffi.h.in libffi-3.2.1/include/ffi.h.in ---- libffi-3.2.1/include/ffi.h.in 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/include/ffi.h.in 2015-01-11 12:35:30.000000000 +0900 -@@ -103,6 +103,11 @@ - # undef FFI_64_BIT_MAX - # define FFI_64_BIT_MAX 9223372036854775807LL - # endif -+# ifdef _MSC_VER -+# define FFI_LONG_LONG_MAX _I64_MAX -+# undef FFI_64_BIT_MAX -+# define FFI_64_BIT_MAX 9223372036854775807I64 -+# endif - # endif - #endif - diff --git a/ext/fiddle/win32/libffi-config.rb b/ext/fiddle/win32/libffi-config.rb deleted file mode 100755 index 985fc29d36..0000000000 --- a/ext/fiddle/win32/libffi-config.rb +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/ruby -# frozen_string_literal: true -require 'fileutils' - -basedir = File.dirname(__FILE__) -conf = {} -enable = {} -until ARGV.empty? - arg = ARGV.shift - case arg - when '-C' - # ignore - when /\A--srcdir=(.*)/ - conf['SRCDIR'] = srcdir = $1 - when /\A(CC|CFLAGS|CXX|CXXFLAGS|LD|LDFLAGS)=(.*)/ - conf[$1] = $2 - when /\A--host=(.*)/ - host = $1 - when /\A--enable-([^=]+)(?:=(.*))?/ - enable[$1] = $2 || true - when /\A--disable-([^=]+)/ - enable[$1] = false - end -end - -IO.foreach("#{srcdir}/configure.ac") do |line| - if /^AC_INIT\((.*)\)/ =~ line - version = $1.split(/,\s*/)[1] - version.gsub!(/\A\[|\]\z/, '') - conf['VERSION'] = version - break - end -end - -builddir = srcdir == "." ? (enable['builddir'] || ".") : "." -conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32" - -FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"]) -FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true) - -hdr = IO.binread("#{srcdir}/include/ffi.h.in") -hdr.gsub!(/@(\w+)@/) {conf[$1] || $&} -hdr.gsub!(/^(#if\s+)@\w+@/, '\10') -IO.binwrite("#{builddir}/include/ffi.h", hdr) - -mk = IO.binread("#{basedir}/libffi.mk.tmpl") -mk.gsub!(/@(\w+)@/) {conf[$1] || $&} -IO.binwrite("Makefile", mk) diff --git a/ext/fiddle/win32/libffi.mk.tmpl b/ext/fiddle/win32/libffi.mk.tmpl deleted file mode 100644 index 2a16e8efec..0000000000 --- a/ext/fiddle/win32/libffi.mk.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -# -*- makefile -*- -# ==================================================================== -# -# libffi Windows Makefile -# -# -# ==================================================================== -# -NAME = ffi -TARGET = @TARGET@ -CC = cl -!if "$(TARGET)" == "X86_WIN64" -AS = ml64 -!else -AS = ml -!endif -AR = link -DLEXT = dll -OBJEXT = obj -LIBEXT = lib -TOPDIR = @SRCDIR@ -CPP = $(CC) -EP -CFLAGS = @CFLAGS@ -ARFLAGS = -lib -ASFLAGS = -coff -W3 -Cx -INCLUDES= -I. -I./include -I./src/x86 \ - -I$(TOPDIR)/include -I$(TOPDIR)/include/src/x86 - -SRCDIR = $(TOPDIR)/src -WORKDIR = ./.libs -BUILDDIR= ./src -LIBNAME = lib$(NAME) -STATICLIB= $(WORKDIR)/$(LIBNAME)_convenience.$(LIBEXT) - -HEADERS = \ - ./fficonfig.h -FFI_HEADERS = \ - ./include/ffi.h \ - ./include/ffitarget.h - -!if "$(TARGET)" == "X86_WIN32" -OSSRC = win32 -!else if "$(TARGET)" == "X86_WIN64" -OSSRC = win64 -!else -! error unknown target: $(TARGET) -!endif - -OBJECTS = \ - $(BUILDDIR)/closures.$(OBJEXT) \ - $(BUILDDIR)/debug.$(OBJEXT) \ - $(BUILDDIR)/java_raw_api.$(OBJEXT) \ - $(BUILDDIR)/prep_cif.$(OBJEXT) \ - $(BUILDDIR)/raw_api.$(OBJEXT) \ - $(BUILDDIR)/types.$(OBJEXT) \ - $(BUILDDIR)/x86/ffi.$(OBJEXT) \ - $(BUILDDIR)/x86/$(OSSRC).$(OBJEXT) -ASMSRCS = \ - $(BUILDDIR)/x86/$(OSSRC).asm - -.SUFFIXES : .S .asm - -all: $(WORKDIR) $(STATICLIB) - -{$(SRCDIR)}.c{$(BUILDDIR)}.$(OBJEXT): - $(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/) - -{$(SRCDIR)/x86}.c{$(BUILDDIR)/x86}.$(OBJEXT): - $(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/) - -{$(SRCDIR)/x86}.S{$(BUILDDIR)/x86}.asm: - $(CPP) $(CFLAGS) $(INCLUDES) $(<:\=/) >$(@:\=/) - -{$(BUILDDIR)/x86}.asm{$(BUILDDIR)/x86}.$(OBJEXT): - cd $(@D) && $(AS) -c $(ASFLAGS) -Fo $(@F) $(<F) - -$(BUILDDIR)/x86/$(OSSRC).asm: $(SRCDIR)/x86/$(OSSRC).S - -$(OBJECTS): $(FFI_HEADERS) $(HEADERS) - -$(WORKDIR): - -@if not exist "$(WORKDIR:/=\)\$(NULL)" mkdir $(WORKDIR:/=\) - -$(STATICLIB): $(WORKDIR) $(OBJECTS) - $(AR) $(ARFLAGS) -out:$(STATICLIB) @<< - $(OBJECTS) -<< - -clean: - -@del /Q $(OBJECTS:/=\) 2>NUL - -@del /Q $(ASMSRCS:/=\) 2>NUL - -@del /Q /S $(WORKDIR:/=\) 2>NUL - -distclean: clean - -@del /Q $(HEADERS:/=\) $(FFI_HEADERS:/=\) 2>NUL - -@del /Q Makefile 2>NUL diff --git a/ext/io/console/.document b/ext/io/console/.document new file mode 100644 index 0000000000..945a377256 --- /dev/null +++ b/ext/io/console/.document @@ -0,0 +1,2 @@ +console.c +lib/size.rb diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 5dec1a4c06..7ddaf071a8 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -2,6 +2,10 @@ /* * console IO module */ + +static const char *const +IO_CONSOLE_VERSION = "0.8.2"; + #include "ruby.h" #include "ruby/io.h" #include "ruby/thread.h" @@ -75,9 +79,14 @@ getattr(int fd, conmode *t) #define SET_LAST_ERROR (0) #endif -static ID id_getc, id_console, id_close, id_min, id_time, id_intr; -#if ENABLE_IO_GETPASS -static ID id_gets, id_chomp_bang; +#define CSI "\x1b\x5b" + +static ID id_getc, id_close; +static ID id_gets, id_flush, id_chomp_bang; + +#ifndef HAVE_RB_INTERNED_STR_CSTR +# define rb_str_to_interned_str(str) rb_str_freeze(str) +# define rb_interned_str_cstr(str) rb_str_freeze(rb_usascii_str_new_cstr(str)) #endif #if defined HAVE_RUBY_FIBER_SCHEDULER_H @@ -87,9 +96,54 @@ extern VALUE rb_scheduler_timeout(struct timeval *timeout); # define rb_fiber_scheduler_make_timeout rb_scheduler_timeout #endif -#define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv) +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + +#ifndef HAVE_RB_IO_PATH +static VALUE +io_path_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->pathv; +} +#define rb_io_path io_path_fallback +#endif + +#ifndef HAVE_RB_IO_GET_WRITE_IO +static VALUE +io_get_write_io_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + VALUE wio = fptr->tied_io_for_writing; + return wio ? wio : io; +} +#define rb_io_get_write_io io_get_write_io_fallback +#endif + +#ifndef DHAVE_RB_SYSERR_FAIL_STR +# define rb_syserr_fail_str(e, mesg) rb_exc_raise(rb_syserr_new_str(e, mesg)) +#endif + +#define sys_fail(io) do { \ + int err = errno; \ + rb_syserr_fail_str(err, rb_io_path(io)); \ +} while (0) #ifndef HAVE_RB_F_SEND +#ifndef RB_PASS_CALLED_KEYWORDS +# define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv) +#endif + static ID id___send__; static VALUE @@ -104,22 +158,38 @@ rb_f_send(int argc, VALUE *argv, VALUE recv) else { vid = id___send__; } - return rb_funcallv(recv, vid, argc, argv); + return rb_funcallv_kw(recv, vid, argc, argv, RB_PASS_CALLED_KEYWORDS); } #endif +enum rawmode_opt_ids { + kwd_min, + kwd_time, + kwd_intr, + rawmode_opt_id_count +}; +static ID rawmode_opt_ids[rawmode_opt_id_count]; + typedef struct { int vmin; int vtime; int intr; } rawmode_arg_t; +#ifndef UNDEF_P +# define UNDEF_P(obj) ((obj) == Qundef) +#endif +#ifndef NIL_OR_UNDEF_P +# define NIL_OR_UNDEF_P(obj) (NIL_P(obj) || UNDEF_P(obj)) +#endif + static rawmode_arg_t * rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts) { int argc = *argcp; rawmode_arg_t *optp = NULL; VALUE vopts = Qnil; + VALUE optvals[rawmode_opt_id_count]; #ifdef RB_SCAN_ARGS_PASS_CALLED_KEYWORDS argc = rb_scan_args(argc, argv, "*:", NULL, &vopts); #else @@ -134,19 +204,20 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t * } #endif rb_check_arity(argc, min_argc, max_argc); - if (!NIL_P(vopts)) { - VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min)); - VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time)); - VALUE intr = rb_hash_aref(vopts, ID2SYM(id_intr)); + if (rb_get_kwargs(vopts, rawmode_opt_ids, + 0, rawmode_opt_id_count, optvals)) { + VALUE vmin = optvals[kwd_min]; + VALUE vtime = optvals[kwd_time]; + VALUE intr = optvals[kwd_intr]; /* default values by `stty raw` */ opts->vmin = 1; opts->vtime = 0; opts->intr = 0; - if (!NIL_P(vmin)) { + if (!NIL_OR_UNDEF_P(vmin)) { opts->vmin = NUM2INT(vmin); optp = opts; } - if (!NIL_P(vtime)) { + if (!NIL_OR_UNDEF_P(vtime)) { VALUE v10 = INT2FIX(10); vtime = rb_funcall3(vtime, '*', 1, &v10); opts->vtime = NUM2INT(vtime); @@ -161,6 +232,7 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t * opts->intr = 0; optp = opts; break; + case Qundef: case Qnil: break; default: @@ -271,33 +343,21 @@ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg) return setattr(fd, &r); } -#define GetReadFD(fptr) ((fptr)->fd) - -static inline int -get_write_fd(const rb_io_t *fptr) -{ - VALUE wio = fptr->tied_io_for_writing; - rb_io_t *ofptr; - if (!wio) return fptr->fd; - GetOpenFile(wio, ofptr); - return ofptr->fd; -} -#define GetWriteFD(fptr) get_write_fd(fptr) +#define GetReadFD(io) rb_io_descriptor(io) +#define GetWriteFD(io) rb_io_descriptor(rb_io_get_write_io(io)) #define FD_PER_IO 2 static VALUE ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg) { - rb_io_t *fptr; int status = -1; int error = 0; int fd[FD_PER_IO]; conmode t[FD_PER_IO]; VALUE result = Qnil; - GetOpenFile(io, fptr); - fd[0] = GetReadFD(fptr); + fd[0] = GetReadFD(io); if (fd[0] != -1) { if (set_ttymode(fd[0], t+0, setter, arg)) { status = 0; @@ -307,7 +367,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo fd[0] = -1; } } - fd[1] = GetWriteFD(fptr); + fd[1] = GetWriteFD(io); if (fd[1] != -1 && fd[1] != fd[0]) { if (set_ttymode(fd[1], t+1, setter, arg)) { status = 0; @@ -320,14 +380,13 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo if (status == 0) { result = rb_protect(func, farg, &status); } - GetOpenFile(io, fptr); - if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) { + if (fd[0] != -1 && fd[0] == GetReadFD(io)) { if (!setattr(fd[0], t+0)) { error = errno; status = -1; } } - if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) { + if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(io)) { if (!setattr(fd[1], t+1)) { error = errno; status = -1; @@ -413,15 +472,11 @@ static VALUE console_set_raw(int argc, VALUE *argv, VALUE io) { conmode t; - rb_io_t *fptr; - int fd; rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); - - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!getattr(fd, &t)) sys_fail_fptr(fptr); + int fd = GetReadFD(io); + if (!getattr(fd, &t)) sys_fail(io); set_rawmode(&t, optp); - if (!setattr(fd, &t)) sys_fail_fptr(fptr); + if (!setattr(fd, &t)) sys_fail(io); return io; } @@ -457,14 +512,10 @@ static VALUE console_set_cooked(VALUE io) { conmode t; - rb_io_t *fptr; - int fd; - - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!getattr(fd, &t)) sys_fail_fptr(fptr); + int fd = GetReadFD(io); + if (!getattr(fd, &t)) sys_fail(io); set_cookedmode(&t, NULL); - if (!setattr(fd, &t)) sys_fail_fptr(fptr); + if (!setattr(fd, &t)) sys_fail(io); return io; } @@ -555,8 +606,8 @@ console_getch(int argc, VALUE *argv, VALUE io) if (w < 0) rb_eof_error(); if (!(w & RB_WAITFD_IN)) return Qnil; # else - VALUE result = rb_io_wait(io, RUBY_IO_READABLE, timeout); - if (result == Qfalse) return Qnil; + VALUE result = rb_io_wait(io, RB_INT2NUM(RUBY_IO_READABLE), timeout); + if (!RTEST(result)) return Qnil; # endif } else if (optp->vtime) { @@ -616,17 +667,17 @@ static VALUE console_set_echo(VALUE io, VALUE f) { conmode t; - rb_io_t *fptr; - int fd; + int fd = GetReadFD(io); + + if (!getattr(fd, &t)) sys_fail(io); - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!getattr(fd, &t)) sys_fail_fptr(fptr); if (RTEST(f)) - set_echo(&t, NULL); + set_echo(&t, NULL); else - set_noecho(&t, NULL); - if (!setattr(fd, &t)) sys_fail_fptr(fptr); + set_noecho(&t, NULL); + + if (!setattr(fd, &t)) sys_fail(io); + return io; } @@ -642,12 +693,9 @@ static VALUE console_echo_p(VALUE io) { conmode t; - rb_io_t *fptr; - int fd; + int fd = GetReadFD(io); - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!getattr(fd, &t)) sys_fail_fptr(fptr); + if (!getattr(fd, &t)) sys_fail(io); return echo_p(&t) ? Qtrue : Qfalse; } @@ -726,12 +774,9 @@ static VALUE console_conmode_get(VALUE io) { conmode t; - rb_io_t *fptr; - int fd; + int fd = GetReadFD(io); - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!getattr(fd, &t)) sys_fail_fptr(fptr); + if (!getattr(fd, &t)) sys_fail(io); return conmode_new(cConmode, &t); } @@ -748,14 +793,12 @@ static VALUE console_conmode_set(VALUE io, VALUE mode) { conmode *t, r; - rb_io_t *fptr; - int fd; + int fd = GetReadFD(io); TypedData_Get_Struct(mode, conmode, &conmode_type, t); r = *t; - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); - if (!setattr(fd, &r)) sys_fail_fptr(fptr); + + if (!setattr(fd, &r)) sys_fail(io); return mode; } @@ -791,16 +834,15 @@ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t; static VALUE console_winsize(VALUE io) { - rb_io_t *fptr; - int fd; rb_console_size_t ws; - - GetOpenFile(io, fptr); - fd = GetWriteFD(fptr); - if (!getwinsize(fd, &ws)) sys_fail_fptr(fptr); + int fd = GetWriteFD(io); + if (!getwinsize(fd, &ws)) sys_fail(io); return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws))); } +static VALUE console_scroll(VALUE io, int line); +static VALUE console_goto(VALUE io, VALUE y, VALUE x); + /* * call-seq: * io.winsize = [rows, columns] @@ -813,29 +855,27 @@ console_winsize(VALUE io) static VALUE console_set_winsize(VALUE io, VALUE size) { - rb_io_t *fptr; rb_console_size_t ws; #if defined _WIN32 HANDLE wh; int newrow, newcol; + COORD oldsize; + SMALL_RECT oldwindow; BOOL ret; #endif VALUE row, col, xpixel, ypixel; const VALUE *sz; - int fd; long sizelen; + int fd; - GetOpenFile(io, fptr); size = rb_Array(size); if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) { - rb_raise(rb_eArgError, - "wrong number of arguments (given %ld, expected 2 or 4)", - sizelen); + rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen); } sz = RARRAY_CONST_PTR(size); row = sz[0], col = sz[1], xpixel = ypixel = Qnil; if (sizelen == 4) xpixel = sz[2], ypixel = sz[3]; - fd = GetWriteFD(fptr); + fd = GetWriteFD(io); #if defined TIOCSWINSZ ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) @@ -844,7 +884,7 @@ console_set_winsize(VALUE io, VALUE size) SET(xpixel); SET(ypixel); #undef SET - if (!setwinsize(fd, &ws)) sys_fail_fptr(fptr); + if (!setwinsize(fd, &ws)) sys_fail(io); #elif defined _WIN32 wh = (HANDLE)rb_w32_get_osfhandle(fd); #define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) @@ -856,18 +896,62 @@ console_set_winsize(VALUE io, VALUE size) if (!GetConsoleScreenBufferInfo(wh, &ws)) { rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo"); } + oldsize = ws.dwSize; + oldwindow = ws.srWindow; + if (ws.srWindow.Right + 1 < newcol) { + ws.dwSize.X = newcol; + } + if (ws.dwSize.Y < newrow) { + ws.dwSize.Y = newrow; + } + /* expand screen buffer first if needed */ + if (!SetConsoleScreenBufferSize(wh, ws.dwSize)) { + rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); + } + /* refresh ws for new dwMaximumWindowSize */ + if (!GetConsoleScreenBufferInfo(wh, &ws)) { + rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo"); + } + /* check new size before modifying buffer content */ + if (newrow <= 0 || newcol <= 0 || + newrow > ws.dwMaximumWindowSize.Y || + newcol > ws.dwMaximumWindowSize.X) { + SetConsoleScreenBufferSize(wh, oldsize); + /* remove scrollbar if possible */ + SetConsoleWindowInfo(wh, TRUE, &oldwindow); + rb_raise(rb_eArgError, "out of range winsize: [%d, %d]", newrow, newcol); + } + /* shrink screen buffer width */ ws.dwSize.X = newcol; - ret = SetConsoleScreenBufferSize(wh, ws.dwSize); + /* shrink screen buffer height if window height were the same */ + if (oldsize.Y == ws.srWindow.Bottom - ws.srWindow.Top + 1) { + ws.dwSize.Y = newrow; + } ws.srWindow.Left = 0; - ws.srWindow.Top = 0; - ws.srWindow.Right = newcol-1; - ws.srWindow.Bottom = newrow-1; + ws.srWindow.Right = newcol - 1; + ws.srWindow.Bottom = ws.srWindow.Top + newrow -1; + if (ws.dwCursorPosition.Y > ws.srWindow.Bottom) { + console_scroll(io, ws.dwCursorPosition.Y - ws.srWindow.Bottom); + ws.dwCursorPosition.Y = ws.srWindow.Bottom; + console_goto(io, INT2FIX(ws.dwCursorPosition.Y), INT2FIX(ws.dwCursorPosition.X)); + } + if (ws.srWindow.Bottom > ws.dwSize.Y - 1) { + console_scroll(io, ws.srWindow.Bottom - (ws.dwSize.Y - 1)); + ws.dwCursorPosition.Y -= ws.srWindow.Bottom - (ws.dwSize.Y - 1); + console_goto(io, INT2FIX(ws.dwCursorPosition.Y), INT2FIX(ws.dwCursorPosition.X)); + ws.srWindow.Bottom = ws.dwSize.Y - 1; + } + ws.srWindow.Top = ws.srWindow.Bottom - (newrow - 1); + /* perform changes to winsize */ if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) { - rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo"); + int last_error = LAST_ERROR; + SetConsoleScreenBufferSize(wh, oldsize); + rb_syserr_fail(last_error, "SetConsoleWindowInfo"); } - /* retry when shrinking buffer after shrunk window */ - if (!ret && !SetConsoleScreenBufferSize(wh, ws.dwSize)) { - rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); + /* perform screen buffer shrinking if necessary */ + if ((ws.dwSize.Y < oldsize.Y || ws.dwSize.X < oldsize.X) && + !SetConsoleScreenBufferSize(wh, ws.dwSize)) { + rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); } /* remove scrollbar if possible */ if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) { @@ -879,15 +963,23 @@ console_set_winsize(VALUE io, VALUE size) #endif #ifdef _WIN32 +/* + * call-seq: + * io.check_winsize_changed { ... } -> io + * + * Yields while console input events are queued. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ static VALUE console_check_winsize_changed(VALUE io) { - rb_io_t *fptr; HANDLE h; DWORD num; - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr)); + h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io)); while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) { INPUT_RECORD rec; if (ReadConsoleInput(h, &rec, 1, &num)) { @@ -913,15 +1005,11 @@ console_check_winsize_changed(VALUE io) static VALUE console_iflush(VALUE io) { - rb_io_t *fptr; - int fd; - - GetOpenFile(io, fptr); - fd = GetReadFD(fptr); #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - if (tcflush(fd, TCIFLUSH)) sys_fail_fptr(fptr); + int fd = GetReadFD(io); + if (tcflush(fd, TCIFLUSH)) sys_fail(io); #endif - (void)fd; + return io; } @@ -936,13 +1024,9 @@ console_iflush(VALUE io) static VALUE console_oflush(VALUE io) { - rb_io_t *fptr; - int fd; - - GetOpenFile(io, fptr); - fd = GetWriteFD(fptr); + int fd = GetWriteFD(io); #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - if (tcflush(fd, TCOFLUSH)) sys_fail_fptr(fptr); + if (tcflush(fd, TCOFLUSH)) sys_fail(io); #endif (void)fd; return io; @@ -959,40 +1043,38 @@ console_oflush(VALUE io) static VALUE console_ioflush(VALUE io) { - rb_io_t *fptr; #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - int fd1, fd2; -#endif + int fd1 = GetReadFD(io); + int fd2 = GetWriteFD(io); - GetOpenFile(io, fptr); -#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H - fd1 = GetReadFD(fptr); - fd2 = GetWriteFD(fptr); if (fd2 != -1 && fd1 != fd2) { - if (tcflush(fd1, TCIFLUSH)) sys_fail_fptr(fptr); - if (tcflush(fd2, TCOFLUSH)) sys_fail_fptr(fptr); + if (tcflush(fd1, TCIFLUSH)) sys_fail(io); + if (tcflush(fd2, TCOFLUSH)) sys_fail(io); } else { - if (tcflush(fd1, TCIOFLUSH)) sys_fail_fptr(fptr); + if (tcflush(fd1, TCIOFLUSH)) sys_fail(io); } #endif + return io; } +/* + * call-seq: + * io.beep + * + * Beeps on the output console. + * + * You must require 'io/console' to use this method. + */ static VALUE console_beep(VALUE io) { - rb_io_t *fptr; - int fd; - - GetOpenFile(io, fptr); - fd = GetWriteFD(fptr); #ifdef _WIN32 - (void)fd; MessageBeep(0); #else - if (write(fd, "\a", 1) < 0) - sys_fail_fptr(fptr); + int fd = GetWriteFD(io); + if (write(fd, "\a", 1) < 0) sys_fail(io); #endif return io; } @@ -1013,79 +1095,6 @@ mode_in_range(VALUE val, int high, const char *modename) } #if defined _WIN32 -static VALUE -console_goto(VALUE io, VALUE y, VALUE x) -{ - rb_io_t *fptr; - int fd; - COORD pos; - - GetOpenFile(io, fptr); - fd = GetWriteFD(fptr); - pos.X = NUM2UINT(x); - pos.Y = NUM2UINT(y); - if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - -static VALUE -console_cursor_pos(VALUE io) -{ - rb_io_t *fptr; - int fd; - rb_console_size_t ws; - - GetOpenFile(io, fptr); - fd = GetWriteFD(fptr); - if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X)); -} - -static VALUE -console_move(VALUE io, int y, int x) -{ - rb_io_t *fptr; - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - pos->X += x; - pos->Y += y; - if (!SetConsoleCursorPosition(h, *pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - -static VALUE -console_goto_column(VALUE io, VALUE val) -{ - rb_io_t *fptr; - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - pos->X = NUM2INT(val); - if (!SetConsoleCursorPosition(h, *pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - static void constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) { @@ -1096,86 +1105,12 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) } static VALUE -console_erase_line(VALUE io, VALUE val) -{ - rb_io_t *fptr; - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - DWORD w; - int mode = mode_in_range(val, 2, "line erase"); - - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - w = winsize_col(&ws); - switch (mode) { - case 0: /* after cursor */ - w -= pos->X; - break; - case 1: /* before *and* cursor */ - w = pos->X + 1; - pos->X = 0; - break; - case 2: /* entire line */ - pos->X = 0; - break; - } - constat_clear(h, ws.wAttributes, w, *pos); - return io; -} - -static VALUE -console_erase_screen(VALUE io, VALUE val) -{ - rb_io_t *fptr; - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - DWORD w; - int mode = mode_in_range(val, 3, "screen erase"); - - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - w = winsize_col(&ws); - switch (mode) { - case 0: /* erase after cursor */ - w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X); - break; - case 1: /* erase before *and* cursor */ - w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1); - pos->X = 0; - pos->Y = ws.srWindow.Top; - break; - case 2: /* erase entire screen */ - w = (w * winsize_row(&ws)); - pos->X = 0; - pos->Y = ws.srWindow.Top; - break; - case 3: /* erase entire screen */ - w = (w * ws.dwSize.Y); - pos->X = 0; - pos->Y = 0; - break; - } - constat_clear(h, ws.wAttributes, w, *pos); - return io; -} - -static VALUE console_scroll(VALUE io, int line) { - rb_io_t *fptr; HANDLE h; rb_console_size_t ws; - GetOpenFile(io, fptr); - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr)); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); if (!GetConsoleScreenBufferInfo(h, &ws)) { rb_syserr_fail(LAST_ERROR, 0); } @@ -1197,8 +1132,22 @@ console_scroll(VALUE io, int line) return io; } +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRCMP 1 +#define gperf_case_strcmp STRCASECMP #include "win32_vk.inc" +/* + * call-seq: + * io.pressed?(key) -> bool + * + * Returns +true+ if +key+ is pressed. +key+ may be a virtual key + * code or its name (String or Symbol) with out "VK_" prefix. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ static VALUE console_key_pressed_p(VALUE io, VALUE k) { @@ -1234,23 +1183,11 @@ static int direct_query(VALUE io, const struct query_args *query) { if (RB_TYPE_P(io, T_FILE)) { - rb_io_t *fptr; - VALUE wio; - GetOpenFile(io, fptr); - wio = fptr->tied_io_for_writing; - if (wio) { - VALUE s = rb_str_new_cstr(query->qstr); - rb_io_write(wio, s); - rb_io_flush(wio); - return 1; - } - if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) { - return 1; - } - if (fptr->fd == 0 && - write(1, query->qstr, strlen(query->qstr)) != -1) { - return 1; - } + VALUE wio = rb_io_get_write_io(io); + VALUE s = rb_str_new_cstr(query->qstr); + rb_io_write(wio, s); + rb_io_flush(wio); + return 1; } return 0; } @@ -1301,8 +1238,40 @@ console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qa } static VALUE +console_scroll(VALUE io, int line) +{ + if (line) { + VALUE s = rb_sprintf(CSI "%d%c", line < 0 ? -line : line, + line < 0 ? 'T' : 'S'); + rb_io_write(io, s); + } + return io; +} + +# define console_key_pressed_p rb_f_notimplement +#endif + +/* + * call-seq: + * io.cursor -> [row, column] + * + * Returns the current cursor position as a two-element array of integers (row, column) + * + * io.cursor # => [3, 5] + * + * You must require 'io/console' to use this method. + */ +static VALUE console_cursor_pos(VALUE io) { +#ifdef _WIN32 + rb_console_size_t ws; + int fd = GetWriteFD(io); + if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y - ws.srWindow.Top), UINT2NUM(ws.dwCursorPosition.X)); +#else static const struct query_args query = {"\033[6n", 0}; VALUE resp = console_vt_response(0, 0, io, &query); VALUE row, column, term; @@ -1319,64 +1288,211 @@ console_cursor_pos(VALUE io) RARRAY_ASET(resp, 0, INT2NUM(r)); RARRAY_ASET(resp, 1, INT2NUM(c)); return resp; +#endif } +/* + * call-seq: + * io.goto(line, column) -> io + * + * Set the cursor position at +line+ and +column+. + * + * You must require 'io/console' to use this method. + */ static VALUE console_goto(VALUE io, VALUE y, VALUE x) { - rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X = NUM2UINT(x); + pos->Y = ws.srWindow.Top + NUM2UINT(y); + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else + rb_io_write(io, rb_sprintf(CSI "%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); +#endif return io; } static VALUE console_move(VALUE io, int y, int x) { +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X += x; + pos->Y += y; + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else if (x || y) { VALUE s = rb_str_new_cstr(""); - if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); - if (x) rb_str_catf(s, "\x1b[%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C'); + if (y) rb_str_catf(s, CSI "%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); + if (x) rb_str_catf(s, CSI "%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C'); rb_io_write(io, s); rb_io_flush(io); } +#endif return io; } +/* + * call-seq: + * io.goto_column(column) -> io + * + * Set the cursor position at +column+ in the same line of the current + * position. + * + * You must require 'io/console' to use this method. + */ static VALUE console_goto_column(VALUE io, VALUE val) { - rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1)); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X = NUM2INT(val); + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else + rb_io_write(io, rb_sprintf(CSI "%dG", NUM2UINT(val)+1)); +#endif return io; } +/* + * call-seq: + * io.erase_line(mode) -> io + * + * Erases the line at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire line + * + * You must require 'io/console' to use this method. + */ static VALUE console_erase_line(VALUE io, VALUE val) { int mode = mode_in_range(val, 2, "line erase"); - rb_io_write(io, rb_sprintf("\x1b[%dK", mode)); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + w = winsize_col(&ws); + switch (mode) { + case 0: /* after cursor */ + w -= pos->X; + break; + case 1: /* before *and* cursor */ + w = pos->X + 1; + pos->X = 0; + break; + case 2: /* entire line */ + pos->X = 0; + break; + } + constat_clear(h, ws.wAttributes, w, *pos); + return io; +#else + rb_io_write(io, rb_sprintf(CSI "%dK", mode)); +#endif return io; } +/* + * call-seq: + * io.erase_screen(mode) -> io + * + * Erases the screen at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire screen + * + * You must require 'io/console' to use this method. + */ static VALUE console_erase_screen(VALUE io, VALUE val) { int mode = mode_in_range(val, 3, "screen erase"); - rb_io_write(io, rb_sprintf("\x1b[%dJ", mode)); - return io; -} +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; -static VALUE -console_scroll(VALUE io, int line) -{ - if (line) { - VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line, - line < 0 ? 'T' : 'S'); - rb_io_write(io, s); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + w = winsize_col(&ws); + switch (mode) { + case 0: /* erase after cursor */ + w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X); + break; + case 1: /* erase before *and* cursor */ + w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 2: /* erase entire screen */ + w = (w * winsize_row(&ws)); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 3: /* erase entire screen */ + w = (w * ws.dwSize.Y); + pos->X = 0; + pos->Y = 0; + break; } + constat_clear(h, ws.wAttributes, w, *pos); +#else + rb_io_write(io, rb_sprintf(CSI "%dJ", mode)); +#endif return io; } -# define console_key_pressed_p rb_f_notimplement -#endif +/* + * call-seq: + * io.cursor = [line, column] -> io + * + * Same as <tt>io.goto(line, column)</tt> + * + * See IO#goto. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_set(VALUE io, VALUE cpos) { @@ -1385,42 +1501,98 @@ console_cursor_set(VALUE io, VALUE cpos) return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1)); } +/* + * call-seq: + * io.cursor_up(n) -> io + * + * Moves the cursor up +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_up(VALUE io, VALUE val) { return console_move(io, -NUM2INT(val), 0); } +/* + * call-seq: + * io.cursor_down(n) -> io + * + * Moves the cursor down +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_down(VALUE io, VALUE val) { return console_move(io, +NUM2INT(val), 0); } +/* + * call-seq: + * io.cursor_left(n) -> io + * + * Moves the cursor left +n+ columns. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_left(VALUE io, VALUE val) { return console_move(io, 0, -NUM2INT(val)); } +/* + * call-seq: + * io.cursor_right(n) -> io + * + * Moves the cursor right +n+ columns. + * + * You must require 'io/console' to use this method. + */ static VALUE console_cursor_right(VALUE io, VALUE val) { return console_move(io, 0, +NUM2INT(val)); } +/* + * call-seq: + * io.scroll_forward(n) -> io + * + * Scrolls the entire scrolls forward +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_scroll_forward(VALUE io, VALUE val) { return console_scroll(io, +NUM2INT(val)); } +/* + * call-seq: + * io.scroll_backward(n) -> io + * + * Scrolls the entire scrolls backward +n+ lines. + * + * You must require 'io/console' to use this method. + */ static VALUE console_scroll_backward(VALUE io, VALUE val) { return console_scroll(io, -NUM2INT(val)); } +/* + * call-seq: + * io.clear_screen -> io + * + * Clears the entire screen and moves the cursor top-left corner. + * + * You must require 'io/console' to use this method. + */ static VALUE console_clear_screen(VALUE io) { @@ -1429,6 +1601,92 @@ console_clear_screen(VALUE io) return io; } +#ifndef HAVE_RB_IO_OPEN_DESCRIPTOR +static VALUE +io_open_descriptor_fallback(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, void *encoding) +{ + VALUE arguments[2] = { + (rb_update_max_fd(descriptor), INT2NUM(descriptor)), + INT2FIX(mode), + }; + + VALUE self = rb_class_new_instance(2, arguments, klass); + + rb_io_t *fptr; + GetOpenFile(self, fptr); + fptr->pathv = path; + fptr->mode |= mode; + + return self; +} +#define rb_io_open_descriptor io_open_descriptor_fallback +#endif + +#ifndef HAVE_RB_IO_CLOSED_P +static VALUE +rb_io_closed_p(VALUE io) +{ + rb_io_t *fptr = RFILE(io)->fptr; + return fptr->fd == -1 ? Qtrue : Qfalse; +} +#endif + +#if defined(RB_EXT_RACTOR_SAFE) && defined(HAVE_RB_RACTOR_LOCAL_STORAGE_VALUE_NEWKEY) +# define USE_RACTOR_STORAGE 1 +#else +# define USE_RACTOR_STORAGE 0 +#endif + +#if USE_RACTOR_STORAGE +#include "ruby/ractor.h" +static rb_ractor_local_key_t key_console_dev; + +static bool +console_dev_get(VALUE klass, VALUE *dev) +{ + return rb_ractor_local_storage_value_lookup(key_console_dev, dev); +} + +static void +console_dev_set(VALUE klass, VALUE value) +{ + rb_ractor_local_storage_value_set(key_console_dev, value); +} + +static void +console_dev_remove(VALUE klass) +{ + console_dev_set(klass, Qnil); +} + +#else + +static ID id_console; + +static int +console_dev_get(VALUE klass, VALUE *dev) +{ + if (rb_const_defined(klass, id_console)) { + *dev = rb_const_get(klass, id_console); + return 1; + } + return 0; +} + +static void +console_dev_set(VALUE klass, VALUE value) +{ + rb_const_set(klass, id_console, value); +} + +static void +console_dev_remove(VALUE klass) +{ + rb_const_remove(klass, id_console); +} + +#endif + /* * call-seq: * IO.console -> #<File:/dev/tty> @@ -1446,34 +1704,34 @@ static VALUE console_dev(int argc, VALUE *argv, VALUE klass) { VALUE con = 0; - rb_io_t *fptr; VALUE sym = 0; - rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS); if (argc) { - Check_Type(sym = argv[0], T_SYMBOL); + Check_Type(sym = argv[0], T_SYMBOL); } + + // Force the class to be File. if (klass == rb_cIO) klass = rb_cFile; - if (rb_const_defined(klass, id_console)) { - con = rb_const_get(klass, id_console); - if (!RB_TYPE_P(con, T_FILE) || - (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) { - rb_const_remove(klass, id_console); - con = 0; - } + + if (console_dev_get(klass, &con)) { + if (!RB_TYPE_P(con, T_FILE) || RTEST(rb_io_closed_p(con))) { + console_dev_remove(klass); + con = 0; + } } + if (sym) { - if (sym == ID2SYM(id_close) && argc == 1) { - if (con) { - rb_io_close(con); - rb_const_remove(klass, id_console); - con = 0; - } - return Qnil; - } + if (sym == ID2SYM(id_close) && argc == 1) { + if (con) { + rb_io_close(con); + console_dev_remove(klass); + con = 0; + } + return Qnil; + } } + if (!con) { - VALUE args[2]; #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H # define CONSOLE_DEVICE "/dev/tty" #elif defined _WIN32 @@ -1485,44 +1743,35 @@ console_dev(int argc, VALUE *argv, VALUE klass) # define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE #endif #ifdef CONSOLE_DEVICE_FOR_WRITING - VALUE out; - rb_io_t *ofptr; + VALUE out; #endif - int fd; + int fd; + VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); #ifdef CONSOLE_DEVICE_FOR_WRITING - fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); - if (fd < 0) return Qnil; - rb_update_max_fd(fd); - args[1] = INT2FIX(O_WRONLY); - args[0] = INT2NUM(fd); - out = rb_class_new_instance(2, args, klass); + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); + if (fd < 0) return Qnil; + out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL); #endif - fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); - if (fd < 0) { + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); + if (fd < 0) { #ifdef CONSOLE_DEVICE_FOR_WRITING - rb_io_close(out); + rb_io_close(out); #endif - return Qnil; - } - rb_update_max_fd(fd); - args[1] = INT2FIX(O_RDWR); - args[0] = INT2NUM(fd); - con = rb_class_new_instance(2, args, klass); - GetOpenFile(con, fptr); - fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); + return Qnil; + } + + con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL); #ifdef CONSOLE_DEVICE_FOR_WRITING - GetOpenFile(out, ofptr); - ofptr->pathv = fptr->pathv; - fptr->tied_io_for_writing = out; - ofptr->mode |= FMODE_SYNC; + rb_io_set_write_io(con, out); #endif - fptr->mode |= FMODE_SYNC; - rb_const_set(klass, id_console, con); + console_dev_set(klass, con); } + if (sym) { - return rb_f_send(argc, argv, con); + return rb_f_send(argc, argv, con); } + return con; } @@ -1538,7 +1787,6 @@ io_getch(int argc, VALUE *argv, VALUE io) return rb_funcallv(io, id_getc, argc, argv); } -#if ENABLE_IO_GETPASS static VALUE puts_call(VALUE io) { @@ -1546,6 +1794,12 @@ puts_call(VALUE io) } static VALUE +gets_call(VALUE io) +{ + return rb_funcallv(io, id_gets, 0, 0); +} + +static VALUE getpass_call(VALUE io) { return ttymode(io, rb_io_gets, io, set_noecho, NULL); @@ -1565,7 +1819,8 @@ static VALUE str_chomp(VALUE str) { if (!NIL_P(str)) { - rb_funcallv(str, id_chomp_bang, 0, 0); + const VALUE rs = rb_default_rs; /* rvalue in TruffleRuby */ + rb_funcallv(str, id_chomp_bang, 1, &rs); } return str; } @@ -1582,6 +1837,12 @@ str_chomp(VALUE str) * see String#chomp!. * * You must require 'io/console' to use this method. + * + * require 'io/console' + * IO::console.getpass("Enter password:") + * Enter password: + * # => "mypassword" + * */ static VALUE console_getpass(int argc, VALUE *argv, VALUE io) @@ -1592,6 +1853,7 @@ console_getpass(int argc, VALUE *argv, VALUE io) wio = rb_io_get_write_io(io); if (wio == io && io == rb_stdin) wio = rb_stderr; prompt(argc, argv, wio); + rb_io_flush(wio); str = rb_ensure(getpass_call, io, puts_call, wio); return str_chomp(str); } @@ -1609,10 +1871,64 @@ io_getpass(int argc, VALUE *argv, VALUE io) rb_check_arity(argc, 0, 1); prompt(argc, argv, io); - str = str_chomp(rb_funcallv(io, id_gets, 0, 0)); - puts_call(io); - return str; + rb_check_funcall(io, id_flush, 0, 0); + str = rb_ensure(gets_call, io, puts_call, io); + return str_chomp(str); } + +#if defined(_WIN32) || defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME) +/* + * call-seq: + * io.ttyname -> string or nil + * + * Returns name of associated terminal (tty) if +io+ is not a tty. + * Returns +nil+ otherwise. + */ +static VALUE +console_ttyname(VALUE io) +{ + int fd = rb_io_descriptor(io); + if (!isatty(fd)) return Qnil; +# if defined _WIN32 + return rb_usascii_str_new_lit("con"); +# elif defined HAVE_TTYNAME_R + { + char termname[1024], *tn = termname; + size_t size = sizeof(termname); + int e; + if (ttyname_r(fd, tn, size) == 0) + return rb_interned_str_cstr(tn); + if ((e = errno) == ERANGE) { + VALUE s = rb_str_new(0, size); + while (1) { + tn = RSTRING_PTR(s); + size = rb_str_capacity(s); + if (ttyname_r(fd, tn, size) == 0) { + return rb_str_to_interned_str(rb_str_resize(s, strlen(tn))); + } + if ((e = errno) != ERANGE) break; + if ((size *= 2) >= INT_MAX/2) break; + rb_str_resize(s, size); + } + } + rb_syserr_fail_str(e, rb_sprintf("ttyname_r(%d)", fd)); + UNREACHABLE_RETURN(Qnil); + } +# elif defined HAVE_TTYNAME + { + const char *tn = ttyname(fd); + if (!tn) { + int e = errno; + rb_syserr_fail_str(e, rb_sprintf("ttyname(%d)", fd)); + } + return rb_interned_str_cstr(tn); + } +# else +# error No ttyname function +# endif +} +#else +# define console_ttyname rb_f_notimplement #endif /* @@ -1621,17 +1937,26 @@ io_getpass(int argc, VALUE *argv, VALUE io) void Init_console(void) { +#if USE_RACTOR_STORAGE + RB_EXT_RACTOR_SAFE(true); +#endif + #undef rb_intern +#if USE_RACTOR_STORAGE + key_console_dev = rb_ractor_local_storage_value_newkey(); +#else + id_console = rb_intern("console"); +#endif id_getc = rb_intern("getc"); -#if ENABLE_IO_GETPASS id_gets = rb_intern("gets"); + id_flush = rb_intern("flush"); id_chomp_bang = rb_intern("chomp!"); -#endif - id_console = rb_intern("console"); id_close = rb_intern("close"); - id_min = rb_intern("min"); - id_time = rb_intern("time"); - id_intr = rb_intern("intr"); +#define init_rawmode_opt_id(name) \ + rawmode_opt_ids[kwd_##name] = rb_intern(#name) + init_rawmode_opt_id(min); + init_rawmode_opt_id(time); + init_rawmode_opt_id(intr); #ifndef HAVE_RB_F_SEND id___send__ = rb_intern("__send__"); #endif @@ -1672,20 +1997,20 @@ InitVM_console(void) rb_define_method(rb_cIO, "clear_screen", console_clear_screen, 0); rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1); rb_define_method(rb_cIO, "check_winsize_changed", console_check_winsize_changed, 0); -#if ENABLE_IO_GETPASS rb_define_method(rb_cIO, "getpass", console_getpass, -1); -#endif + rb_define_method(rb_cIO, "ttyname", console_ttyname, 0); rb_define_singleton_method(rb_cIO, "console", console_dev, -1); { + /* :stopdoc: */ VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable"); + /* :startdoc: */ rb_define_method(mReadable, "getch", io_getch, -1); -#if ENABLE_IO_GETPASS rb_define_method(mReadable, "getpass", io_getpass, -1); -#endif } { /* :stopdoc: */ cConmode = rb_define_class_under(rb_cIO, "ConsoleMode", rb_cObject); + rb_define_const(cConmode, "VERSION", rb_obj_freeze(rb_str_new_cstr(IO_CONSOLE_VERSION))); rb_define_alloc_func(cConmode, conmode_alloc); rb_undef_method(cConmode, "initialize"); rb_define_method(cConmode, "initialize_copy", conmode_init_copy, 1); diff --git a/ext/io/console/depend b/ext/io/console/depend index b28df55fe7..150a138d4d 100644 --- a/ext/io/console/depend +++ b/ext/io/console/depend @@ -7,7 +7,6 @@ console.o: $(hdrdir)/ruby/backward.h console.o: $(hdrdir)/ruby/backward/2/assume.h console.o: $(hdrdir)/ruby/backward/2/attributes.h console.o: $(hdrdir)/ruby/backward/2/bool.h -console.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h console.o: $(hdrdir)/ruby/backward/2/inttypes.h console.o: $(hdrdir)/ruby/backward/2/limits.h console.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -17,6 +16,7 @@ console.o: $(hdrdir)/ruby/defines.h console.o: $(hdrdir)/ruby/encoding.h console.o: $(hdrdir)/ruby/fiber/scheduler.h console.o: $(hdrdir)/ruby/intern.h +console.o: $(hdrdir)/ruby/internal/abi.h console.o: $(hdrdir)/ruby/internal/anyargs.h console.o: $(hdrdir)/ruby/internal/arithmetic.h console.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -54,6 +54,7 @@ console.o: $(hdrdir)/ruby/internal/attr/noexcept.h console.o: $(hdrdir)/ruby/internal/attr/noinline.h console.o: $(hdrdir)/ruby/internal/attr/nonnull.h console.o: $(hdrdir)/ruby/internal/attr/noreturn.h +console.o: $(hdrdir)/ruby/internal/attr/packed_struct.h console.o: $(hdrdir)/ruby/internal/attr/pure.h console.o: $(hdrdir)/ruby/internal/attr/restrict.h console.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -122,7 +123,6 @@ console.o: $(hdrdir)/ruby/internal/intern/enumerator.h console.o: $(hdrdir)/ruby/internal/intern/error.h console.o: $(hdrdir)/ruby/internal/intern/eval.h console.o: $(hdrdir)/ruby/internal/intern/file.h -console.o: $(hdrdir)/ruby/internal/intern/gc.h console.o: $(hdrdir)/ruby/internal/intern/hash.h console.o: $(hdrdir)/ruby/internal/intern/io.h console.o: $(hdrdir)/ruby/internal/intern/load.h @@ -139,6 +139,7 @@ console.o: $(hdrdir)/ruby/internal/intern/re.h console.o: $(hdrdir)/ruby/internal/intern/ruby.h console.o: $(hdrdir)/ruby/internal/intern/select.h console.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +console.o: $(hdrdir)/ruby/internal/intern/set.h console.o: $(hdrdir)/ruby/internal/intern/signal.h console.o: $(hdrdir)/ruby/internal/intern/sprintf.h console.o: $(hdrdir)/ruby/internal/intern/string.h @@ -153,12 +154,12 @@ console.o: $(hdrdir)/ruby/internal/memory.h console.o: $(hdrdir)/ruby/internal/method.h console.o: $(hdrdir)/ruby/internal/module.h console.o: $(hdrdir)/ruby/internal/newobj.h -console.o: $(hdrdir)/ruby/internal/rgengc.h console.o: $(hdrdir)/ruby/internal/scan_args.h console.o: $(hdrdir)/ruby/internal/special_consts.h console.o: $(hdrdir)/ruby/internal/static_assert.h console.o: $(hdrdir)/ruby/internal/stdalign.h console.o: $(hdrdir)/ruby/internal/stdbool.h +console.o: $(hdrdir)/ruby/internal/stdckdint.h console.o: $(hdrdir)/ruby/internal/symbol.h console.o: $(hdrdir)/ruby/internal/value.h console.o: $(hdrdir)/ruby/internal/value_type.h @@ -169,6 +170,7 @@ console.o: $(hdrdir)/ruby/io.h console.o: $(hdrdir)/ruby/missing.h console.o: $(hdrdir)/ruby/onigmo.h console.o: $(hdrdir)/ruby/oniguruma.h +console.o: $(hdrdir)/ruby/ractor.h console.o: $(hdrdir)/ruby/ruby.h console.o: $(hdrdir)/ruby/st.h console.o: $(hdrdir)/ruby/subst.h @@ -185,7 +187,7 @@ win32_vk.inc: win32_vk.list -e 'n=$$F[1] and (n.strip!; /\AVK_/=~n) and' \ -e 'puts(%[#ifndef #{n}\n# define #{n} UNDEFINED_VK\n#endif])' \ $< && \ - gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \ + gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \ | sed -f $(top_srcdir)/tool/gperf.sed \ ) > $(@F) diff --git a/ext/io/console/extconf.rb b/ext/io/console/extconf.rb index e8c5923b18..dd3d221ae5 100644 --- a/ext/io/console/extconf.rb +++ b/ext/io/console/extconf.rb @@ -1,7 +1,30 @@ # frozen_string_literal: false require 'mkmf' -ok = true if RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby" +# `--target-rbconfig` compatibility for Ruby 3.3 or earlier +# See https://bugs.ruby-lang.org/issues/20345 +MakeMakefile::RbConfig ||= ::RbConfig + +have_func("rb_syserr_fail_str(0, Qnil)") or +have_func("rb_syserr_new_str(0, Qnil)") or + abort + +have_func("rb_interned_str_cstr") +have_func("rb_io_path", "ruby/io.h") +have_func("rb_io_descriptor", "ruby/io.h") +have_func("rb_io_get_write_io", "ruby/io.h") +have_func("rb_io_closed_p", "ruby/io.h") +have_func("rb_io_open_descriptor", "ruby/io.h") +have_func("rb_ractor_local_storage_value_newkey") + +is_wasi = /wasi/ =~ MakeMakefile::RbConfig::CONFIG["platform"] +# `ok` can be `true`, `false`, or `nil`: +# * `true` : Required headers and functions available, proceed regular build. +# * `false`: Required headers or functions not available, abort build. +# * `nil` : Unsupported compilation target, generate dummy Makefile. +# +# Skip building io/console on WASI, as it does not support termios.h. +ok = true if (RUBY_ENGINE == "ruby" && !is_wasi) || RUBY_ENGINE == "truffleruby" hdr = nil case when macro_defined?("_WIN32", "") @@ -29,7 +52,7 @@ when true elsif have_func("rb_scheduler_timeout") # 3.0 have_func("rb_io_wait") end - $defs << "-D""ENABLE_IO_GETPASS=1" + have_func("ttyname_r") or have_func("ttyname") create_makefile("io/console") {|conf| conf << "\n""VK_HEADER = #{vk_header}\n" } diff --git a/ext/io/console/io-console.gemspec b/ext/io/console/io-console.gemspec index dabe9e68f8..0a19992734 100644 --- a/ext/io/console/io-console.gemspec +++ b/ext/io/console/io-console.gemspec @@ -1,5 +1,13 @@ # -*- ruby -*- -_VERSION = "0.5.9" +_VERSION = ["", "ext/io/console/"].find do |dir| + begin + break File.open(File.join(__dir__, "#{dir}console.c")) {|f| + f.gets("\nIO_CONSOLE_VERSION ") + f.gets[/"(.+)"/, 1] + } + rescue Errno::ENOENT + end +end Gem::Specification.new do |s| s.name = "io-console" @@ -7,13 +15,16 @@ Gem::Specification.new do |s| s.summary = "Console interface" s.email = "nobu@ruby-lang.org" s.description = "add console capabilities to IO instances." - s.required_ruby_version = ">= 2.4.0" + s.required_ruby_version = ">= 2.6.0" s.homepage = "https://github.com/ruby/io-console" s.metadata["source_code_url"] = s.homepage + s.metadata["changelog_uri"] = s.homepage + "/releases" s.authors = ["Nobu Nakada"] s.require_path = %[lib] s.files = %w[ - LICENSE.txt + .document + BSDL + COPYING README.md ext/io/console/console.c ext/io/console/extconf.rb @@ -25,15 +36,16 @@ Gem::Specification.new do |s| if Gem::Platform === s.platform and s.platform =~ 'java' s.files.delete_if {|f| f.start_with?("ext/")} s.extensions.clear + s.require_paths.unshift('lib/ffi') s.files.concat(%w[ - lib/io/console.rb - lib/io/console/ffi/bsd_console.rb - lib/io/console/ffi/common.rb - lib/io/console/ffi/console.rb - lib/io/console/ffi/linux_console.rb - lib/io/console/ffi/native_console.rb - lib/io/console/ffi/stty_console.rb - lib/io/console/ffi/stub_console.rb + lib/ffi/io/console.rb + lib/ffi/io/console/bsd_console.rb + lib/ffi/io/console/common.rb + lib/ffi/io/console/linux_console.rb + lib/ffi/io/console/native_console.rb + lib/ffi/io/console/stty_console.rb + lib/ffi/io/console/stub_console.rb + lib/ffi/io/console/version.rb ]) end diff --git a/ext/io/console/win32_vk.inc b/ext/io/console/win32_vk.inc index cbec7bef15..348e6be5ed 100644 --- a/ext/io/console/win32_vk.inc +++ b/ext/io/console/win32_vk.inc @@ -480,7 +480,7 @@ # define VK_OEM_CLEAR UNDEFINED_VK #endif /* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf --ignore-case -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */ +/* Command-line: gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -509,11 +509,10 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>." #endif -#define gperf_offsetof(s, n) (short)offsetof(struct s##_t, s##_str##n) #line 1 "win32_vk.list" struct vktable {short ofs; unsigned short vk;}; -static const struct vktable *console_win32_vk(/*const char *, unsigned int*/); +static const struct vktable *console_win32_vk(const char *, size_t); #line 5 "win32_vk.list" struct vktable; /* maximum key range = 245, duplicates = 0 */ @@ -1007,368 +1006,368 @@ console_win32_vk (register const char *str, register size_t len) {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, #line 40 "win32_vk.list" - {gperf_offsetof(stringpool, 12), VK_UP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str12, VK_UP}, #line 52 "win32_vk.list" - {gperf_offsetof(stringpool, 13), VK_APPS}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, VK_APPS}, #line 159 "win32_vk.list" - {gperf_offsetof(stringpool, 14), VK_CRSEL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, VK_CRSEL}, #line 34 "win32_vk.list" - {gperf_offsetof(stringpool, 15), VK_SPACE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15, VK_SPACE}, #line 95 "win32_vk.list" - {gperf_offsetof(stringpool, 16), VK_SCROLL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16, VK_SCROLL}, #line 29 "win32_vk.list" - {gperf_offsetof(stringpool, 17), VK_ESCAPE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17, VK_ESCAPE}, #line 9 "win32_vk.list" - {gperf_offsetof(stringpool, 18), VK_CANCEL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18, VK_CANCEL}, #line 32 "win32_vk.list" - {gperf_offsetof(stringpool, 19), VK_ACCEPT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, VK_ACCEPT}, #line 66 "win32_vk.list" - {gperf_offsetof(stringpool, 20), VK_SEPARATOR}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20, VK_SEPARATOR}, #line 43 "win32_vk.list" - {gperf_offsetof(stringpool, 21), VK_SELECT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, VK_SELECT}, #line 18 "win32_vk.list" - {gperf_offsetof(stringpool, 22), VK_CONTROL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, VK_CONTROL}, #line 166 "win32_vk.list" - {gperf_offsetof(stringpool, 23), VK_OEM_CLEAR}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str23, VK_OEM_CLEAR}, #line 145 "win32_vk.list" - {gperf_offsetof(stringpool, 24), VK_OEM_RESET}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24, VK_OEM_RESET}, #line 155 "win32_vk.list" - {gperf_offsetof(stringpool, 25), VK_OEM_AUTO}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25, VK_OEM_AUTO}, #line 151 "win32_vk.list" - {gperf_offsetof(stringpool, 26), VK_OEM_CUSEL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, VK_OEM_CUSEL}, {-1}, #line 22 "win32_vk.list" - {gperf_offsetof(stringpool, 28), VK_KANA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, VK_KANA}, #line 127 "win32_vk.list" - {gperf_offsetof(stringpool, 29), VK_OEM_PLUS}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, VK_OEM_PLUS}, #line 35 "win32_vk.list" - {gperf_offsetof(stringpool, 30), VK_PRIOR}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, VK_PRIOR}, #line 152 "win32_vk.list" - {gperf_offsetof(stringpool, 31), VK_OEM_ATTN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, VK_OEM_ATTN}, #line 20 "win32_vk.list" - {gperf_offsetof(stringpool, 32), VK_PAUSE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32, VK_PAUSE}, #line 13 "win32_vk.list" - {gperf_offsetof(stringpool, 33), VK_BACK}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, VK_BACK}, #line 144 "win32_vk.list" - {gperf_offsetof(stringpool, 34), VK_PACKET}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str34, VK_PACKET}, #line 105 "win32_vk.list" - {gperf_offsetof(stringpool, 35), VK_RCONTROL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, VK_RCONTROL}, #line 104 "win32_vk.list" - {gperf_offsetof(stringpool, 36), VK_LCONTROL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, VK_LCONTROL}, #line 37 "win32_vk.list" - {gperf_offsetof(stringpool, 37), VK_END}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, VK_END}, #line 38 "win32_vk.list" - {gperf_offsetof(stringpool, 38), VK_HOME}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, VK_HOME}, #line 44 "win32_vk.list" - {gperf_offsetof(stringpool, 39), VK_PRINT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39, VK_PRINT}, #line 94 "win32_vk.list" - {gperf_offsetof(stringpool, 40), VK_NUMLOCK}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str40, VK_NUMLOCK}, #line 39 "win32_vk.list" - {gperf_offsetof(stringpool, 41), VK_LEFT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41, VK_LEFT}, #line 25 "win32_vk.list" - {gperf_offsetof(stringpool, 42), VK_JUNJA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42, VK_JUNJA}, #line 19 "win32_vk.list" - {gperf_offsetof(stringpool, 43), VK_MENU}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43, VK_MENU}, #line 150 "win32_vk.list" - {gperf_offsetof(stringpool, 44), VK_OEM_WSCTRL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, VK_OEM_WSCTRL}, #line 156 "win32_vk.list" - {gperf_offsetof(stringpool, 45), VK_OEM_ENLW}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, VK_OEM_ENLW}, #line 36 "win32_vk.list" - {gperf_offsetof(stringpool, 46), VK_NEXT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46, VK_NEXT}, #line 51 "win32_vk.list" - {gperf_offsetof(stringpool, 47), VK_RWIN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, VK_RWIN}, #line 50 "win32_vk.list" - {gperf_offsetof(stringpool, 48), VK_LWIN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48, VK_LWIN}, #line 21 "win32_vk.list" - {gperf_offsetof(stringpool, 49), VK_CAPITAL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, VK_CAPITAL}, #line 49 "win32_vk.list" - {gperf_offsetof(stringpool, 50), VK_HELP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str50, VK_HELP}, #line 164 "win32_vk.list" - {gperf_offsetof(stringpool, 51), VK_NONAME}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str51, VK_NONAME}, #line 8 "win32_vk.list" - {gperf_offsetof(stringpool, 52), VK_RBUTTON}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, VK_RBUTTON}, #line 7 "win32_vk.list" - {gperf_offsetof(stringpool, 53), VK_LBUTTON}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53, VK_LBUTTON}, #line 96 "win32_vk.list" - {gperf_offsetof(stringpool, 54), VK_OEM_NEC_EQUAL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54, VK_OEM_NEC_EQUAL}, {-1}, #line 47 "win32_vk.list" - {gperf_offsetof(stringpool, 56), VK_INSERT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str56, VK_INSERT}, #line 27 "win32_vk.list" - {gperf_offsetof(stringpool, 57), VK_HANJA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57, VK_HANJA}, {-1}, {-1}, #line 46 "win32_vk.list" - {gperf_offsetof(stringpool, 60), VK_SNAPSHOT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60, VK_SNAPSHOT}, #line 158 "win32_vk.list" - {gperf_offsetof(stringpool, 61), VK_ATTN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61, VK_ATTN}, #line 14 "win32_vk.list" - {gperf_offsetof(stringpool, 62), VK_TAB}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62, VK_TAB}, #line 157 "win32_vk.list" - {gperf_offsetof(stringpool, 63), VK_OEM_BACKTAB}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63, VK_OEM_BACKTAB}, #line 143 "win32_vk.list" - {gperf_offsetof(stringpool, 64), VK_ICO_CLEAR}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, VK_ICO_CLEAR}, #line 30 "win32_vk.list" - {gperf_offsetof(stringpool, 65), VK_CONVERT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65, VK_CONVERT}, #line 16 "win32_vk.list" - {gperf_offsetof(stringpool, 66), VK_RETURN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66, VK_RETURN}, #line 146 "win32_vk.list" - {gperf_offsetof(stringpool, 67), VK_OEM_JUMP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67, VK_OEM_JUMP}, {-1}, {-1}, {-1}, #line 111 "win32_vk.list" - {gperf_offsetof(stringpool, 71), VK_BROWSER_STOP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71, VK_BROWSER_STOP}, #line 26 "win32_vk.list" - {gperf_offsetof(stringpool, 72), VK_FINAL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72, VK_FINAL}, #line 163 "win32_vk.list" - {gperf_offsetof(stringpool, 73), VK_ZOOM}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str73, VK_ZOOM}, #line 28 "win32_vk.list" - {gperf_offsetof(stringpool, 74), VK_KANJI}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74, VK_KANJI}, #line 48 "win32_vk.list" - {gperf_offsetof(stringpool, 75), VK_DELETE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75, VK_DELETE}, #line 128 "win32_vk.list" - {gperf_offsetof(stringpool, 76), VK_OEM_COMMA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76, VK_OEM_COMMA}, #line 67 "win32_vk.list" - {gperf_offsetof(stringpool, 77), VK_SUBTRACT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77, VK_SUBTRACT}, {-1}, #line 10 "win32_vk.list" - {gperf_offsetof(stringpool, 79), VK_MBUTTON}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79, VK_MBUTTON}, #line 78 "win32_vk.list" - {gperf_offsetof(stringpool, 80), VK_F9}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80, VK_F9}, #line 17 "win32_vk.list" - {gperf_offsetof(stringpool, 81), VK_SHIFT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81, VK_SHIFT}, #line 103 "win32_vk.list" - {gperf_offsetof(stringpool, 82), VK_RSHIFT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82, VK_RSHIFT}, #line 102 "win32_vk.list" - {gperf_offsetof(stringpool, 83), VK_LSHIFT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str83, VK_LSHIFT}, #line 65 "win32_vk.list" - {gperf_offsetof(stringpool, 84), VK_ADD}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84, VK_ADD}, #line 31 "win32_vk.list" - {gperf_offsetof(stringpool, 85), VK_NONCONVERT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85, VK_NONCONVERT}, #line 160 "win32_vk.list" - {gperf_offsetof(stringpool, 86), VK_EXSEL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str86, VK_EXSEL}, #line 126 "win32_vk.list" - {gperf_offsetof(stringpool, 87), VK_OEM_1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str87, VK_OEM_1}, #line 138 "win32_vk.list" - {gperf_offsetof(stringpool, 88), VK_OEM_AX}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88, VK_OEM_AX}, #line 108 "win32_vk.list" - {gperf_offsetof(stringpool, 89), VK_BROWSER_BACK}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89, VK_BROWSER_BACK}, #line 137 "win32_vk.list" - {gperf_offsetof(stringpool, 90), VK_OEM_8}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90, VK_OEM_8}, #line 129 "win32_vk.list" - {gperf_offsetof(stringpool, 91), VK_OEM_MINUS}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91, VK_OEM_MINUS}, #line 162 "win32_vk.list" - {gperf_offsetof(stringpool, 92), VK_PLAY}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92, VK_PLAY}, #line 131 "win32_vk.list" - {gperf_offsetof(stringpool, 93), VK_OEM_2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93, VK_OEM_2}, #line 15 "win32_vk.list" - {gperf_offsetof(stringpool, 94), VK_CLEAR}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94, VK_CLEAR}, #line 99 "win32_vk.list" - {gperf_offsetof(stringpool, 95), VK_OEM_FJ_TOUROKU}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95, VK_OEM_FJ_TOUROKU}, #line 147 "win32_vk.list" - {gperf_offsetof(stringpool, 96), VK_OEM_PA1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96, VK_OEM_PA1}, #line 140 "win32_vk.list" - {gperf_offsetof(stringpool, 97), VK_ICO_HELP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97, VK_ICO_HELP}, #line 112 "win32_vk.list" - {gperf_offsetof(stringpool, 98), VK_BROWSER_SEARCH}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str98, VK_BROWSER_SEARCH}, #line 53 "win32_vk.list" - {gperf_offsetof(stringpool, 99), VK_SLEEP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str99, VK_SLEEP}, {-1}, #line 70 "win32_vk.list" - {gperf_offsetof(stringpool, 101), VK_F1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101, VK_F1}, #line 148 "win32_vk.list" - {gperf_offsetof(stringpool, 102), VK_OEM_PA2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102, VK_OEM_PA2}, #line 154 "win32_vk.list" - {gperf_offsetof(stringpool, 103), VK_OEM_COPY}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103, VK_OEM_COPY}, #line 77 "win32_vk.list" - {gperf_offsetof(stringpool, 104), VK_F8}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104, VK_F8}, #line 88 "win32_vk.list" - {gperf_offsetof(stringpool, 105), VK_F19}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105, VK_F19}, #line 41 "win32_vk.list" - {gperf_offsetof(stringpool, 106), VK_RIGHT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106, VK_RIGHT}, #line 71 "win32_vk.list" - {gperf_offsetof(stringpool, 107), VK_F2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107, VK_F2}, #line 135 "win32_vk.list" - {gperf_offsetof(stringpool, 108), VK_OEM_6}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108, VK_OEM_6}, #line 87 "win32_vk.list" - {gperf_offsetof(stringpool, 109), VK_F18}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109, VK_F18}, {-1}, #line 117 "win32_vk.list" - {gperf_offsetof(stringpool, 111), VK_VOLUME_UP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111, VK_VOLUME_UP}, {-1}, {-1}, #line 120 "win32_vk.list" - {gperf_offsetof(stringpool, 114), VK_MEDIA_STOP}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114, VK_MEDIA_STOP}, #line 130 "win32_vk.list" - {gperf_offsetof(stringpool, 115), VK_OEM_PERIOD}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str115, VK_OEM_PERIOD}, {-1}, #line 161 "win32_vk.list" - {gperf_offsetof(stringpool, 117), VK_EREOF}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117, VK_EREOF}, {-1}, {-1}, {-1}, #line 114 "win32_vk.list" - {gperf_offsetof(stringpool, 121), VK_BROWSER_HOME}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121, VK_BROWSER_HOME}, #line 75 "win32_vk.list" - {gperf_offsetof(stringpool, 122), VK_F6}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122, VK_F6}, {-1}, #line 110 "win32_vk.list" - {gperf_offsetof(stringpool, 124), VK_BROWSER_REFRESH}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124, VK_BROWSER_REFRESH}, {-1}, #line 165 "win32_vk.list" - {gperf_offsetof(stringpool, 126), VK_PA1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126, VK_PA1}, #line 142 "win32_vk.list" - {gperf_offsetof(stringpool, 127), VK_PROCESSKEY}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127, VK_PROCESSKEY}, #line 68 "win32_vk.list" - {gperf_offsetof(stringpool, 128), VK_DECIMAL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128, VK_DECIMAL}, #line 132 "win32_vk.list" - {gperf_offsetof(stringpool, 129), VK_OEM_3}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129, VK_OEM_3}, #line 107 "win32_vk.list" - {gperf_offsetof(stringpool, 130), VK_RMENU}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130, VK_RMENU}, #line 106 "win32_vk.list" - {gperf_offsetof(stringpool, 131), VK_LMENU}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131, VK_LMENU}, #line 98 "win32_vk.list" - {gperf_offsetof(stringpool, 132), VK_OEM_FJ_MASSHOU}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132, VK_OEM_FJ_MASSHOU}, #line 54 "win32_vk.list" - {gperf_offsetof(stringpool, 133), VK_NUMPAD0}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133, VK_NUMPAD0}, #line 24 "win32_vk.list" - {gperf_offsetof(stringpool, 134), VK_HANGUL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134, VK_HANGUL}, #line 63 "win32_vk.list" - {gperf_offsetof(stringpool, 135), VK_NUMPAD9}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135, VK_NUMPAD9}, #line 23 "win32_vk.list" - {gperf_offsetof(stringpool, 136), VK_HANGEUL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str136, VK_HANGEUL}, #line 134 "win32_vk.list" - {gperf_offsetof(stringpool, 137), VK_OEM_5}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137, VK_OEM_5}, #line 149 "win32_vk.list" - {gperf_offsetof(stringpool, 138), VK_OEM_PA3}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str138, VK_OEM_PA3}, #line 115 "win32_vk.list" - {gperf_offsetof(stringpool, 139), VK_VOLUME_MUTE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str139, VK_VOLUME_MUTE}, #line 133 "win32_vk.list" - {gperf_offsetof(stringpool, 140), VK_OEM_4}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str140, VK_OEM_4}, #line 122 "win32_vk.list" - {gperf_offsetof(stringpool, 141), VK_LAUNCH_MAIL}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str141, VK_LAUNCH_MAIL}, #line 97 "win32_vk.list" - {gperf_offsetof(stringpool, 142), VK_OEM_FJ_JISHO}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str142, VK_OEM_FJ_JISHO}, #line 72 "win32_vk.list" - {gperf_offsetof(stringpool, 143), VK_F3}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143, VK_F3}, #line 101 "win32_vk.list" - {gperf_offsetof(stringpool, 144), VK_OEM_FJ_ROYA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144, VK_OEM_FJ_ROYA}, #line 100 "win32_vk.list" - {gperf_offsetof(stringpool, 145), VK_OEM_FJ_LOYA}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145, VK_OEM_FJ_LOYA}, {-1}, #line 42 "win32_vk.list" - {gperf_offsetof(stringpool, 147), VK_DOWN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147, VK_DOWN}, {-1}, #line 153 "win32_vk.list" - {gperf_offsetof(stringpool, 149), VK_OEM_FINISH}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149, VK_OEM_FINISH}, {-1}, #line 74 "win32_vk.list" - {gperf_offsetof(stringpool, 151), VK_F5}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151, VK_F5}, {-1}, #line 136 "win32_vk.list" - {gperf_offsetof(stringpool, 153), VK_OEM_7}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str153, VK_OEM_7}, #line 73 "win32_vk.list" - {gperf_offsetof(stringpool, 154), VK_F4}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154, VK_F4}, #line 86 "win32_vk.list" - {gperf_offsetof(stringpool, 155), VK_F17}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str155, VK_F17}, #line 55 "win32_vk.list" - {gperf_offsetof(stringpool, 156), VK_NUMPAD1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str156, VK_NUMPAD1}, #line 141 "win32_vk.list" - {gperf_offsetof(stringpool, 157), VK_ICO_00}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str157, VK_ICO_00}, {-1}, #line 62 "win32_vk.list" - {gperf_offsetof(stringpool, 159), VK_NUMPAD8}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str159, VK_NUMPAD8}, {-1}, {-1}, #line 56 "win32_vk.list" - {gperf_offsetof(stringpool, 162), VK_NUMPAD2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162, VK_NUMPAD2}, {-1}, #line 124 "win32_vk.list" - {gperf_offsetof(stringpool, 164), VK_LAUNCH_APP1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164, VK_LAUNCH_APP1}, #line 109 "win32_vk.list" - {gperf_offsetof(stringpool, 165), VK_BROWSER_FORWARD}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str165, VK_BROWSER_FORWARD}, {-1}, #line 76 "win32_vk.list" - {gperf_offsetof(stringpool, 167), VK_F7}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167, VK_F7}, {-1}, {-1}, #line 125 "win32_vk.list" - {gperf_offsetof(stringpool, 170), VK_LAUNCH_APP2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170, VK_LAUNCH_APP2}, #line 64 "win32_vk.list" - {gperf_offsetof(stringpool, 171), VK_MULTIPLY}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171, VK_MULTIPLY}, {-1}, {-1}, #line 45 "win32_vk.list" - {gperf_offsetof(stringpool, 174), VK_EXECUTE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174, VK_EXECUTE}, {-1}, #line 113 "win32_vk.list" - {gperf_offsetof(stringpool, 176), VK_BROWSER_FAVORITES}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176, VK_BROWSER_FAVORITES}, #line 60 "win32_vk.list" - {gperf_offsetof(stringpool, 177), VK_NUMPAD6}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177, VK_NUMPAD6}, {-1}, #line 85 "win32_vk.list" - {gperf_offsetof(stringpool, 179), VK_F16}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179, VK_F16}, {-1}, {-1}, #line 79 "win32_vk.list" - {gperf_offsetof(stringpool, 182), VK_F10}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182, VK_F10}, {-1}, {-1}, #line 116 "win32_vk.list" - {gperf_offsetof(stringpool, 185), VK_VOLUME_DOWN}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185, VK_VOLUME_DOWN}, {-1}, {-1}, #line 89 "win32_vk.list" - {gperf_offsetof(stringpool, 188), VK_F20}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188, VK_F20}, #line 119 "win32_vk.list" - {gperf_offsetof(stringpool, 189), VK_MEDIA_PREV_TRACK}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189, VK_MEDIA_PREV_TRACK}, {-1}, #line 33 "win32_vk.list" - {gperf_offsetof(stringpool, 191), VK_MODECHANGE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191, VK_MODECHANGE}, {-1}, {-1}, {-1}, {-1}, {-1}, #line 83 "win32_vk.list" - {gperf_offsetof(stringpool, 197), VK_F14}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197, VK_F14}, #line 57 "win32_vk.list" - {gperf_offsetof(stringpool, 198), VK_NUMPAD3}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198, VK_NUMPAD3}, #line 11 "win32_vk.list" - {gperf_offsetof(stringpool, 199), VK_XBUTTON1}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199, VK_XBUTTON1}, {-1}, {-1}, {-1}, #line 93 "win32_vk.list" - {gperf_offsetof(stringpool, 203), VK_F24}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203, VK_F24}, {-1}, #line 12 "win32_vk.list" - {gperf_offsetof(stringpool, 205), VK_XBUTTON2}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205, VK_XBUTTON2}, #line 59 "win32_vk.list" - {gperf_offsetof(stringpool, 206), VK_NUMPAD5}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206, VK_NUMPAD5}, {-1}, {-1}, #line 58 "win32_vk.list" - {gperf_offsetof(stringpool, 209), VK_NUMPAD4}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209, VK_NUMPAD4}, {-1}, {-1}, {-1}, {-1}, {-1}, #line 121 "win32_vk.list" - {gperf_offsetof(stringpool, 215), VK_MEDIA_PLAY_PAUSE}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215, VK_MEDIA_PLAY_PAUSE}, {-1}, #line 123 "win32_vk.list" - {gperf_offsetof(stringpool, 217), VK_LAUNCH_MEDIA_SELECT}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217, VK_LAUNCH_MEDIA_SELECT}, #line 80 "win32_vk.list" - {gperf_offsetof(stringpool, 218), VK_F11}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218, VK_F11}, {-1}, #line 139 "win32_vk.list" - {gperf_offsetof(stringpool, 220), VK_OEM_102}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220, VK_OEM_102}, #line 118 "win32_vk.list" - {gperf_offsetof(stringpool, 221), VK_MEDIA_NEXT_TRACK}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221, VK_MEDIA_NEXT_TRACK}, #line 61 "win32_vk.list" - {gperf_offsetof(stringpool, 222), VK_NUMPAD7}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str222, VK_NUMPAD7}, {-1}, #line 90 "win32_vk.list" - {gperf_offsetof(stringpool, 224), VK_F21}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224, VK_F21}, {-1}, #line 82 "win32_vk.list" - {gperf_offsetof(stringpool, 226), VK_F13}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str226, VK_F13}, {-1}, {-1}, #line 81 "win32_vk.list" - {gperf_offsetof(stringpool, 229), VK_F12}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229, VK_F12}, {-1}, {-1}, #line 92 "win32_vk.list" - {gperf_offsetof(stringpool, 232), VK_F23}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232, VK_F23}, {-1}, {-1}, #line 91 "win32_vk.list" - {gperf_offsetof(stringpool, 235), VK_F22}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235, VK_F22}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, #line 84 "win32_vk.list" - {gperf_offsetof(stringpool, 242), VK_F15}, + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242, VK_F15}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, #line 69 "win32_vk.list" - {gperf_offsetof(stringpool, 256), VK_DIVIDE} + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256, VK_DIVIDE} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/ext/io/console/win32_vk.list b/ext/io/console/win32_vk.list index 7909a4d1f0..5df3d6da57 100644 --- a/ext/io/console/win32_vk.list +++ b/ext/io/console/win32_vk.list @@ -1,6 +1,6 @@ %{ struct vktable {short ofs; unsigned short vk;}; -static const struct vktable *console_win32_vk(/*!ANSI{*/const char *, unsigned int/*}!ANSI*/); +static const struct vktable *console_win32_vk(const char *, size_t); %} struct vktable %% diff --git a/ext/io/nonblock/depend b/ext/io/nonblock/depend index 95948937ee..e78a05c316 100644 --- a/ext/io/nonblock/depend +++ b/ext/io/nonblock/depend @@ -7,7 +7,6 @@ nonblock.o: $(hdrdir)/ruby/backward.h nonblock.o: $(hdrdir)/ruby/backward/2/assume.h nonblock.o: $(hdrdir)/ruby/backward/2/attributes.h nonblock.o: $(hdrdir)/ruby/backward/2/bool.h -nonblock.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h nonblock.o: $(hdrdir)/ruby/backward/2/inttypes.h nonblock.o: $(hdrdir)/ruby/backward/2/limits.h nonblock.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ nonblock.o: $(hdrdir)/ruby/backward/2/stdarg.h nonblock.o: $(hdrdir)/ruby/defines.h nonblock.o: $(hdrdir)/ruby/encoding.h nonblock.o: $(hdrdir)/ruby/intern.h +nonblock.o: $(hdrdir)/ruby/internal/abi.h nonblock.o: $(hdrdir)/ruby/internal/anyargs.h nonblock.o: $(hdrdir)/ruby/internal/arithmetic.h nonblock.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ nonblock.o: $(hdrdir)/ruby/internal/attr/noexcept.h nonblock.o: $(hdrdir)/ruby/internal/attr/noinline.h nonblock.o: $(hdrdir)/ruby/internal/attr/nonnull.h nonblock.o: $(hdrdir)/ruby/internal/attr/noreturn.h +nonblock.o: $(hdrdir)/ruby/internal/attr/packed_struct.h nonblock.o: $(hdrdir)/ruby/internal/attr/pure.h nonblock.o: $(hdrdir)/ruby/internal/attr/restrict.h nonblock.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ nonblock.o: $(hdrdir)/ruby/internal/intern/enumerator.h nonblock.o: $(hdrdir)/ruby/internal/intern/error.h nonblock.o: $(hdrdir)/ruby/internal/intern/eval.h nonblock.o: $(hdrdir)/ruby/internal/intern/file.h -nonblock.o: $(hdrdir)/ruby/internal/intern/gc.h nonblock.o: $(hdrdir)/ruby/internal/intern/hash.h nonblock.o: $(hdrdir)/ruby/internal/intern/io.h nonblock.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ nonblock.o: $(hdrdir)/ruby/internal/intern/re.h nonblock.o: $(hdrdir)/ruby/internal/intern/ruby.h nonblock.o: $(hdrdir)/ruby/internal/intern/select.h nonblock.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +nonblock.o: $(hdrdir)/ruby/internal/intern/set.h nonblock.o: $(hdrdir)/ruby/internal/intern/signal.h nonblock.o: $(hdrdir)/ruby/internal/intern/sprintf.h nonblock.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ nonblock.o: $(hdrdir)/ruby/internal/memory.h nonblock.o: $(hdrdir)/ruby/internal/method.h nonblock.o: $(hdrdir)/ruby/internal/module.h nonblock.o: $(hdrdir)/ruby/internal/newobj.h -nonblock.o: $(hdrdir)/ruby/internal/rgengc.h nonblock.o: $(hdrdir)/ruby/internal/scan_args.h nonblock.o: $(hdrdir)/ruby/internal/special_consts.h nonblock.o: $(hdrdir)/ruby/internal/static_assert.h nonblock.o: $(hdrdir)/ruby/internal/stdalign.h nonblock.o: $(hdrdir)/ruby/internal/stdbool.h +nonblock.o: $(hdrdir)/ruby/internal/stdckdint.h nonblock.o: $(hdrdir)/ruby/internal/symbol.h nonblock.o: $(hdrdir)/ruby/internal/value.h nonblock.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/io/nonblock/extconf.rb b/ext/io/nonblock/extconf.rb index d813a01e7c..505c9e6252 100644 --- a/ext/io/nonblock/extconf.rb +++ b/ext/io/nonblock/extconf.rb @@ -2,6 +2,13 @@ require 'mkmf' target = "io/nonblock" +unless RUBY_ENGINE == 'ruby' + File.write("Makefile", dummy_makefile($srcdir).join("")) + return +end + +have_func("rb_io_descriptor", "ruby/io.h") + hdr = %w"fcntl.h" if have_macro("O_NONBLOCK", hdr) and (have_macro("F_GETFL", hdr) or have_macro("F_SETFL", hdr)) diff --git a/ext/io/nonblock/io-nonblock.gemspec b/ext/io/nonblock/io-nonblock.gemspec index 34d736650b..4f5b8cef6f 100644 --- a/ext/io/nonblock/io-nonblock.gemspec +++ b/ext/io/nonblock/io-nonblock.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |spec| spec.name = "io-nonblock" - spec.version = "0.1.0" + spec.version = "0.3.2" spec.authors = ["Nobu Nakada"] spec.email = ["nobu@ruby-lang.org"] @@ -8,18 +8,18 @@ Gem::Specification.new do |spec| spec.description = %q{Enables non-blocking mode with IO class} spec.homepage = "https://github.com/ruby/io-nonblock" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") + spec.required_ruby_version = Gem::Requirement.new(">= 3.0") spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - %x[git ls-files -z].split("\x0").reject do |f| - f.match(%r{\A(?:test|spec|features)/|\A\.(?:git|travis)}) - end - end + spec.files = %w[ + COPYING + README.md + ext/io/nonblock/depend + ext/io/nonblock/extconf.rb + ext/io/nonblock/nonblock.c + ] spec.extensions = %w[ext/io/nonblock/extconf.rb] - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] end diff --git a/ext/io/nonblock/nonblock.c b/ext/io/nonblock/nonblock.c index 1c0bdc68e7..cd40ea3335 100644 --- a/ext/io/nonblock/nonblock.c +++ b/ext/io/nonblock/nonblock.c @@ -17,16 +17,27 @@ #endif #include <fcntl.h> +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + #ifdef F_GETFL static int -io_nonblock_mode(int fd) +get_fcntl_flags(int fd) { int f = fcntl(fd, F_GETFL); if (f == -1) rb_sys_fail(0); return f; } #else -#define io_nonblock_mode(fd) ((void)(fd), 0) +#define get_fcntl_flags(fd) ((void)(fd), 0) #endif #ifdef F_GETFL @@ -39,10 +50,8 @@ io_nonblock_mode(int fd) static VALUE rb_io_nonblock_p(VALUE io) { - rb_io_t *fptr; - GetOpenFile(io, fptr); - if (io_nonblock_mode(fptr->fd) & O_NONBLOCK) - return Qtrue; + if (get_fcntl_flags(rb_io_descriptor(io)) & O_NONBLOCK) + return Qtrue; return Qfalse; } #else @@ -50,6 +59,15 @@ rb_io_nonblock_p(VALUE io) #endif #ifdef F_SETFL +static void +set_fcntl_flags(int fd, int f) +{ + if (fcntl(fd, F_SETFL, f) == -1) + rb_sys_fail(0); +} + +#ifndef RUBY_IO_NONBLOCK_METHODS + static int io_nonblock_set(int fd, int f, int nb) { @@ -63,8 +81,7 @@ io_nonblock_set(int fd, int f, int nb) return 0; f &= ~O_NONBLOCK; } - if (fcntl(fd, F_SETFL, f) == -1) - rb_sys_fail(0); + set_fcntl_flags(fd, f); return 1; } @@ -74,32 +91,77 @@ io_nonblock_set(int fd, int f, int nb) * * Enables non-blocking mode on a stream when set to * +true+, and blocking mode when set to +false+. + * + * This method set or clear O_NONBLOCK flag for the file descriptor + * in <em>ios</em>. + * + * The behavior of most IO methods is not affected by this flag + * because they retry system calls to complete their task + * after EAGAIN and partial read/write. + * (An exception is IO#syswrite which doesn't retry.) + * + * This method can be used to clear non-blocking mode of standard I/O. + * Since nonblocking methods (read_nonblock, etc.) set non-blocking mode but + * they doesn't clear it, this method is usable as follows. + * + * END { STDOUT.nonblock = false } + * STDOUT.write_nonblock("foo") + * + * Since the flag is shared across processes and + * many non-Ruby commands doesn't expect standard I/O with non-blocking mode, + * it would be safe to clear the flag before Ruby program exits. + * + * For example following Ruby program leaves STDIN/STDOUT/STDER non-blocking mode. + * (STDIN, STDOUT and STDERR are connected to a terminal. + * So making one of them nonblocking-mode effects other two.) + * Thus cat command try to read from standard input and + * it causes "Resource temporarily unavailable" error (EAGAIN). + * + * % ruby -e ' + * STDOUT.write_nonblock("foo\n")'; cat + * foo + * cat: -: Resource temporarily unavailable + * + * Clearing the flag makes the behavior of cat command normal. + * (cat command waits input from standard input.) + * + * % ruby -rio/nonblock -e ' + * END { STDOUT.nonblock = false } + * STDOUT.write_nonblock("foo") + * '; cat + * foo + * */ static VALUE -rb_io_nonblock_set(VALUE io, VALUE nb) +rb_io_nonblock_set(VALUE self, VALUE value) { - rb_io_t *fptr; - GetOpenFile(io, fptr); - if (RTEST(nb)) - rb_io_set_nonblock(fptr); - else - io_nonblock_set(fptr->fd, io_nonblock_mode(fptr->fd), RTEST(nb)); - return io; + if (RTEST(value)) { + rb_io_t *fptr; + GetOpenFile(self, fptr); + rb_io_set_nonblock(fptr); + } + else { + int descriptor = rb_io_descriptor(self); + io_nonblock_set(descriptor, get_fcntl_flags(descriptor), RTEST(value)); + } + + return self; } +#endif /* RUBY_IO_NONBLOCK_METHODS */ + static VALUE io_nonblock_restore(VALUE arg) { int *restore = (int *)arg; - if (fcntl(restore[0], F_SETFL, restore[1]) == -1) - rb_sys_fail(0); + set_fcntl_flags(restore[0], restore[1]); return Qnil; } /* * call-seq: - * io.nonblock {|io| } -> io - * io.nonblock(boolean) {|io| } -> io + * io.nonblock {|io| } -> object + * io.nonblock(boolean) {|io| } -> object * * Yields +self+ in non-blocking mode. * @@ -107,24 +169,25 @@ io_nonblock_restore(VALUE arg) * The original mode is restored after the block is executed. */ static VALUE -rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) +rb_io_nonblock_block(int argc, VALUE *argv, VALUE self) { int nb = 1; - rb_io_t *fptr; - int f, restore[2]; - GetOpenFile(io, fptr); + int descriptor = rb_io_descriptor(self); + if (argc > 0) { - VALUE v; - rb_scan_args(argc, argv, "01", &v); - nb = RTEST(v); + VALUE v; + rb_scan_args(argc, argv, "01", &v); + nb = RTEST(v); } - f = io_nonblock_mode(fptr->fd); - restore[0] = fptr->fd; - restore[1] = f; - if (!io_nonblock_set(fptr->fd, f, nb)) - return rb_yield(io); - return rb_ensure(rb_yield, io, io_nonblock_restore, (VALUE)restore); + + int current_flags = get_fcntl_flags(descriptor); + int restore[2] = {descriptor, current_flags}; + + if (!io_nonblock_set(descriptor, current_flags, nb)) + return rb_yield(self); + + return rb_ensure(rb_yield, self, io_nonblock_restore, (VALUE)restore); } #else #define rb_io_nonblock_set rb_f_notimplement @@ -134,7 +197,14 @@ rb_io_nonblock_block(int argc, VALUE *argv, VALUE io) void Init_nonblock(void) { +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + +#ifndef RUBY_IO_NONBLOCK_METHODS rb_define_method(rb_cIO, "nonblock?", rb_io_nonblock_p, 0); rb_define_method(rb_cIO, "nonblock=", rb_io_nonblock_set, 1); +#endif + rb_define_method(rb_cIO, "nonblock", rb_io_nonblock_block, -1); } diff --git a/ext/io/wait/depend b/ext/io/wait/depend index 3c4657795b..41d53c1400 100644 --- a/ext/io/wait/depend +++ b/ext/io/wait/depend @@ -7,7 +7,6 @@ wait.o: $(hdrdir)/ruby/backward.h wait.o: $(hdrdir)/ruby/backward/2/assume.h wait.o: $(hdrdir)/ruby/backward/2/attributes.h wait.o: $(hdrdir)/ruby/backward/2/bool.h -wait.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h wait.o: $(hdrdir)/ruby/backward/2/inttypes.h wait.o: $(hdrdir)/ruby/backward/2/limits.h wait.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ wait.o: $(hdrdir)/ruby/backward/2/stdarg.h wait.o: $(hdrdir)/ruby/defines.h wait.o: $(hdrdir)/ruby/encoding.h wait.o: $(hdrdir)/ruby/intern.h +wait.o: $(hdrdir)/ruby/internal/abi.h wait.o: $(hdrdir)/ruby/internal/anyargs.h wait.o: $(hdrdir)/ruby/internal/arithmetic.h wait.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ wait.o: $(hdrdir)/ruby/internal/attr/noexcept.h wait.o: $(hdrdir)/ruby/internal/attr/noinline.h wait.o: $(hdrdir)/ruby/internal/attr/nonnull.h wait.o: $(hdrdir)/ruby/internal/attr/noreturn.h +wait.o: $(hdrdir)/ruby/internal/attr/packed_struct.h wait.o: $(hdrdir)/ruby/internal/attr/pure.h wait.o: $(hdrdir)/ruby/internal/attr/restrict.h wait.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ wait.o: $(hdrdir)/ruby/internal/intern/enumerator.h wait.o: $(hdrdir)/ruby/internal/intern/error.h wait.o: $(hdrdir)/ruby/internal/intern/eval.h wait.o: $(hdrdir)/ruby/internal/intern/file.h -wait.o: $(hdrdir)/ruby/internal/intern/gc.h wait.o: $(hdrdir)/ruby/internal/intern/hash.h wait.o: $(hdrdir)/ruby/internal/intern/io.h wait.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ wait.o: $(hdrdir)/ruby/internal/intern/re.h wait.o: $(hdrdir)/ruby/internal/intern/ruby.h wait.o: $(hdrdir)/ruby/internal/intern/select.h wait.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +wait.o: $(hdrdir)/ruby/internal/intern/set.h wait.o: $(hdrdir)/ruby/internal/intern/signal.h wait.o: $(hdrdir)/ruby/internal/intern/sprintf.h wait.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ wait.o: $(hdrdir)/ruby/internal/memory.h wait.o: $(hdrdir)/ruby/internal/method.h wait.o: $(hdrdir)/ruby/internal/module.h wait.o: $(hdrdir)/ruby/internal/newobj.h -wait.o: $(hdrdir)/ruby/internal/rgengc.h wait.o: $(hdrdir)/ruby/internal/scan_args.h wait.o: $(hdrdir)/ruby/internal/special_consts.h wait.o: $(hdrdir)/ruby/internal/static_assert.h wait.o: $(hdrdir)/ruby/internal/stdalign.h wait.o: $(hdrdir)/ruby/internal/stdbool.h +wait.o: $(hdrdir)/ruby/internal/stdckdint.h wait.o: $(hdrdir)/ruby/internal/symbol.h wait.o: $(hdrdir)/ruby/internal/value.h wait.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/io/wait/extconf.rb b/ext/io/wait/extconf.rb index b5d36c3fe3..00c455a45c 100644 --- a/ext/io/wait/extconf.rb +++ b/ext/io/wait/extconf.rb @@ -1,19 +1,4 @@ # frozen_string_literal: false require 'mkmf' -target = "io/wait" -unless macro_defined?("DOSISH", "#include <ruby.h>") - have_header(ioctl_h = "sys/ioctl.h") or ioctl_h = nil - fionread = %w[sys/ioctl.h sys/filio.h sys/socket.h].find do |h| - have_macro("FIONREAD", [h, ioctl_h].compact) - end - if fionread - $defs << "-DFIONREAD_HEADER=\"<#{fionread}>\"" - create_makefile(target) - end -else - if have_func("rb_w32_ioctlsocket", "ruby.h") - have_func("rb_w32_is_socket", "ruby.h") - create_makefile(target) - end -end +create_makefile("io/wait") diff --git a/ext/io/wait/io-wait.gemspec b/ext/io/wait/io-wait.gemspec index 103b75e4ac..c1c6172589 100644 --- a/ext/io/wait/io-wait.gemspec +++ b/ext/io/wait/io-wait.gemspec @@ -1,27 +1,39 @@ -_VERSION = "0.1.1" +_VERSION = "0.4.0" Gem::Specification.new do |spec| spec.name = "io-wait" spec.version = _VERSION - spec.authors = ["Nobu Nakada"] - spec.email = ["nobu@ruby-lang.org"] + spec.authors = ["Nobu Nakada", "Charles Oliver Nutter"] + spec.email = ["nobu@ruby-lang.org", "headius@headius.com"] spec.summary = %q{Waits until IO is readable or writable without blocking.} spec.description = %q{Waits until IO is readable or writable without blocking.} spec.homepage = "https://github.com/ruby/io-wait" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0") + spec.required_ruby_version = Gem::Requirement.new(">= 3.2") spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject do |f| - f.match(%r{\A(?:test|spec|features)/|\A\.(?:git|travis)}) - end - end - spec.extensions = %w[ext/io/wait/extconf.rb] + jruby = true if Gem::Platform.new('java') =~ spec.platform or RUBY_ENGINE == 'jruby' + dir, gemspec = File.split(__FILE__) + excludes = [ + *%w[:^/.git* :^/Gemfile* :^/Rakefile* :^/bin/ :^/test/ :^/rakelib/ :^*.java], + *(jruby ? %w[:^/ext/io] : %w[:^/ext/java]), + ":(exclude,literal,top)#{gemspec}" + ] + files = IO.popen(%w[git ls-files -z --] + excludes, chdir: dir, &:read).split("\x0") + + spec.files = files spec.bindir = "exe" spec.executables = [] spec.require_paths = ["lib"] + + if jruby + spec.platform = 'java' + spec.files << "lib/io/wait.jar" + spec.require_paths += ["ext/java/lib"] + else + spec.extensions = %w[ext/io/wait/extconf.rb] + end end diff --git a/ext/io/wait/wait.c b/ext/io/wait/wait.c index 512e4f6a80..f7575191fe 100644 --- a/ext/io/wait/wait.c +++ b/ext/io/wait/wait.c @@ -11,278 +11,13 @@ **********************************************************************/ -#include "ruby.h" -#include "ruby/io.h" - -#include <sys/types.h> -#if defined(HAVE_UNISTD_H) && (defined(__sun)) -#include <unistd.h> -#endif -#if defined(HAVE_SYS_IOCTL_H) -#include <sys/ioctl.h> -#endif -#if defined(FIONREAD_HEADER) -#include FIONREAD_HEADER -#endif - -#ifdef HAVE_RB_W32_IOCTLSOCKET -#define ioctl ioctlsocket -#define ioctl_arg u_long -#define ioctl_arg2num(i) ULONG2NUM(i) -#else -#define ioctl_arg int -#define ioctl_arg2num(i) INT2NUM(i) -#endif - -#ifdef HAVE_RB_W32_IS_SOCKET -#define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd) -#else -#define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue) -#endif - -/* - * call-seq: - * io.nread -> int - * - * Returns number of bytes that can be read without blocking. - * Returns zero if no information available. - */ - -static VALUE -io_nread(VALUE io) -{ - rb_io_t *fptr = NULL; - ioctl_arg n; - - GetOpenFile(io, fptr); - rb_io_check_readable(fptr); - int len = rb_io_read_pending(fptr); - if (len > 0) return INT2FIX(len); - if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0); - if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0); - if (n > 0) return ioctl_arg2num(n); - return INT2FIX(0); -} - -static VALUE -io_wait_event(VALUE io, int event, VALUE timeout) -{ - VALUE result = rb_io_wait(io, RB_INT2NUM(event), timeout); - - if (!RB_TEST(result)) { - return Qnil; - } - - int mask = RB_NUM2INT(result); - - if (mask & event) { - return io; - } - else { - return Qfalse; - } -} - -/* - * call-seq: - * io.ready? -> true or false - * - * Returns +true+ if input available without blocking, or +false+. - */ - -static VALUE -io_ready_p(VALUE io) -{ - rb_io_t *fptr; - - GetOpenFile(io, fptr); - rb_io_check_readable(fptr); - if (rb_io_read_pending(fptr)) return Qtrue; - - return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0)); -} - -/* - * call-seq: - * io.wait_readable -> true or false - * io.wait_readable(timeout) -> true or false - * - * Waits until IO is readable and returns +true+, or - * +false+ when times out. - * Returns +true+ immediately when buffered data is available. - */ - -static VALUE -io_wait_readable(int argc, VALUE *argv, VALUE io) -{ - rb_io_t *fptr = NULL; - - RB_IO_POINTER(io, fptr); - rb_io_check_readable(fptr); - - if (rb_io_read_pending(fptr)) return Qtrue; - - rb_check_arity(argc, 0, 1); - VALUE timeout = (argc == 1 ? argv[0] : Qnil); - - return io_wait_event(io, RUBY_IO_READABLE, timeout); -} +#include "ruby.h" /* abi_version */ /* - * call-seq: - * io.wait_writable -> true or false - * io.wait_writable(timeout) -> true or false - * - * Waits until IO is writable and returns +true+ or - * +false+ when times out. - */ -static VALUE -io_wait_writable(int argc, VALUE *argv, VALUE io) -{ - rb_io_t *fptr = NULL; - - RB_IO_POINTER(io, fptr); - rb_io_check_writable(fptr); - - rb_check_arity(argc, 0, 1); - VALUE timeout = (argc == 1 ? argv[0] : Qnil); - - return io_wait_event(io, RUBY_IO_WRITABLE, timeout); -} - -/* - * call-seq: - * io.wait_priority -> true or false - * io.wait_priority(timeout) -> true or false - * - * Waits until IO is priority and returns +true+ or - * +false+ when times out. - */ -static VALUE -io_wait_priority(int argc, VALUE *argv, VALUE io) -{ - rb_io_t *fptr = NULL; - - RB_IO_POINTER(io, fptr); - rb_io_check_readable(fptr); - - if (rb_io_read_pending(fptr)) return Qtrue; - - rb_check_arity(argc, 0, 1); - VALUE timeout = argc == 1 ? argv[0] : Qnil; - - return io_wait_event(io, RUBY_IO_PRIORITY, timeout); -} - -static int -wait_mode_sym(VALUE mode) -{ - if (mode == ID2SYM(rb_intern("r"))) { - return RB_WAITFD_IN; - } - if (mode == ID2SYM(rb_intern("read"))) { - return RB_WAITFD_IN; - } - if (mode == ID2SYM(rb_intern("readable"))) { - return RB_WAITFD_IN; - } - if (mode == ID2SYM(rb_intern("w"))) { - return RB_WAITFD_OUT; - } - if (mode == ID2SYM(rb_intern("write"))) { - return RB_WAITFD_OUT; - } - if (mode == ID2SYM(rb_intern("writable"))) { - return RB_WAITFD_OUT; - } - if (mode == ID2SYM(rb_intern("rw"))) { - return RB_WAITFD_IN|RB_WAITFD_OUT; - } - if (mode == ID2SYM(rb_intern("read_write"))) { - return RB_WAITFD_IN|RB_WAITFD_OUT; - } - if (mode == ID2SYM(rb_intern("readable_writable"))) { - return RB_WAITFD_IN|RB_WAITFD_OUT; - } - rb_raise(rb_eArgError, "unsupported mode: %"PRIsVALUE, mode); - return 0; -} - -/* - * call-seq: - * io.wait(events, timeout) -> event mask or false. - * io.wait(timeout = nil, mode = :read) -> event mask or false. - * - * Waits until the IO becomes ready for the specified events and returns the - * subset of events that become ready, or +false+ when times out. - * - * The events can be a bit mask of +IO::READABLE+, +IO::WRITABLE+ or - * +IO::PRIORITY+. - * - * Returns +true+ immediately when buffered data is available. - * - * Optional parameter +mode+ is one of +:read+, +:write+, or - * +:read_write+. - */ - -static VALUE -io_wait(int argc, VALUE *argv, VALUE io) -{ - VALUE timeout = Qundef; - rb_io_event_t events = 0; - - if (argc != 2 || (RB_SYMBOL_P(argv[0]) || RB_SYMBOL_P(argv[1]))) { - for (int i = 0; i < argc; i += 1) { - if (RB_SYMBOL_P(argv[i])) { - events |= wait_mode_sym(argv[i]); - } - else if (timeout == Qundef) { - rb_time_interval(timeout = argv[i]); - } - else { - rb_raise(rb_eArgError, "timeout given more than once"); - } - } - if (timeout == Qundef) timeout = Qnil; - } - else /* argc == 2 */ { - events = RB_NUM2UINT(argv[0]); - timeout = argv[1]; - } - - if (events == 0) { - events = RUBY_IO_READABLE; - } - - if (events & RUBY_IO_READABLE) { - rb_io_t *fptr = NULL; - RB_IO_POINTER(io, fptr); - - if (rb_io_read_pending(fptr)) { - return Qtrue; - } - } - - return io_wait_event(io, events, timeout); -} - -/* - * IO wait methods + * IO wait methods are built in ruby now, just for backward compatibility. */ void Init_wait(void) { -#ifdef HAVE_RB_EXT_RACTOR_SAFE - RB_EXT_RACTOR_SAFE(true); -#endif - - rb_define_method(rb_cIO, "nread", io_nread, 0); - rb_define_method(rb_cIO, "ready?", io_ready_p, 0); - - rb_define_method(rb_cIO, "wait", io_wait, -1); - - rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1); - rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1); - rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1); } diff --git a/ext/json/VERSION b/ext/json/VERSION deleted file mode 100644 index e70b4523ae..0000000000 --- a/ext/json/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.6.0 diff --git a/ext/json/fbuffer/fbuffer.h b/ext/json/fbuffer/fbuffer.h index dc8f406b5b..752d153b31 100644 --- a/ext/json/fbuffer/fbuffer.h +++ b/ext/json/fbuffer/fbuffer.h @@ -1,89 +1,71 @@ - #ifndef _FBUFFER_H_ #define _FBUFFER_H_ -#include "ruby.h" - -#ifndef RHASH_SIZE -#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries) -#endif - -#ifndef RFLOAT_VALUE -#define RFLOAT_VALUE(val) (RFLOAT(val)->value) -#endif - -#ifndef RARRAY_LEN -#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len -#endif -#ifndef RSTRING_PTR -#define RSTRING_PTR(string) RSTRING(string)->ptr -#endif -#ifndef RSTRING_LEN -#define RSTRING_LEN(string) RSTRING(string)->len -#endif +#include "../json.h" +#include "../vendor/jeaiii-ltoa.h" -#ifdef PRIsVALUE -# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) -# define RB_OBJ_STRING(obj) (obj) -#else -# define PRIsVALUE "s" -# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) -# define RB_OBJ_STRING(obj) StringValueCStr(obj) -#endif - -#ifdef HAVE_RUBY_ENCODING_H -#include "ruby/encoding.h" -#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding()) -#else -#define FORCE_UTF8(obj) -#endif - -/* We don't need to guard objects for rbx, so let's do nothing at all. */ -#ifndef RB_GC_GUARD -#define RB_GC_GUARD(object) -#endif +enum fbuffer_type { + FBUFFER_HEAP_ALLOCATED = 0, + FBUFFER_STACK_ALLOCATED = 1, +}; typedef struct FBufferStruct { + enum fbuffer_type type; unsigned long initial_length; - char *ptr; unsigned long len; unsigned long capa; +#if JSON_DEBUG + unsigned long requested; +#endif + char *ptr; + VALUE io; } FBuffer; +#define FBUFFER_STACK_SIZE 512 +#define FBUFFER_IO_BUFFER_SIZE (16384 - 1) #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024 -#define FBUFFER_PTR(fb) (fb->ptr) -#define FBUFFER_LEN(fb) (fb->len) -#define FBUFFER_CAPA(fb) (fb->capa) +#define FBUFFER_PTR(fb) ((fb)->ptr) +#define FBUFFER_LEN(fb) ((fb)->len) +#define FBUFFER_CAPA(fb) ((fb)->capa) #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb) -static FBuffer *fbuffer_alloc(unsigned long initial_length); static void fbuffer_free(FBuffer *fb); static void fbuffer_clear(FBuffer *fb); static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); -#ifdef JSON_GENERATOR static void fbuffer_append_long(FBuffer *fb, long number); +static inline void fbuffer_append_char(FBuffer *fb, char newchr); +static VALUE fbuffer_finalize(FBuffer *fb); + +static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size) +{ + fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT; + if (stack_buffer) { + fb->type = FBUFFER_STACK_ALLOCATED; + fb->ptr = stack_buffer; + fb->capa = stack_buffer_size; + } +#if JSON_DEBUG + fb->requested = 0; #endif -static void fbuffer_append_char(FBuffer *fb, char newchr); -#ifdef JSON_GENERATOR -static FBuffer *fbuffer_dup(FBuffer *fb); -static VALUE fbuffer_to_s(FBuffer *fb); -#endif +} -static FBuffer *fbuffer_alloc(unsigned long initial_length) +static inline void fbuffer_consumed(FBuffer *fb, unsigned long consumed) { - FBuffer *fb; - if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; - fb = ALLOC(FBuffer); - memset((void *) fb, 0, sizeof(FBuffer)); - fb->initial_length = initial_length; - return fb; +#if JSON_DEBUG + if (consumed > fb->requested) { + rb_bug("fbuffer: Out of bound write"); + } + fb->requested = 0; +#endif + fb->len += consumed; } static void fbuffer_free(FBuffer *fb) { - if (fb->ptr) ruby_xfree(fb->ptr); - ruby_xfree(fb); + if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) { + ruby_xfree(fb->ptr); + } } static void fbuffer_clear(FBuffer *fb) @@ -91,97 +73,175 @@ static void fbuffer_clear(FBuffer *fb) fb->len = 0; } -static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) +static void fbuffer_flush(FBuffer *fb) +{ + rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len)); + fbuffer_clear(fb); +} + +static void fbuffer_realloc(FBuffer *fb, unsigned long required) { + if (required > fb->capa) { + if (fb->type == FBUFFER_STACK_ALLOCATED) { + const char *old_buffer = fb->ptr; + fb->ptr = ALLOC_N(char, required); + fb->type = FBUFFER_HEAP_ALLOCATED; + MEMCPY(fb->ptr, old_buffer, char, fb->len); + } else { + REALLOC_N(fb->ptr, char, required); + } + fb->capa = required; + } +} + +static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested) +{ + if (RB_UNLIKELY(fb->io)) { + if (fb->capa < FBUFFER_IO_BUFFER_SIZE) { + fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE); + } else { + fbuffer_flush(fb); + } + + if (RB_LIKELY(requested < fb->capa)) { + return; + } + } + unsigned long required; - if (!fb->ptr) { + if (RB_UNLIKELY(!fb->ptr)) { fb->ptr = ALLOC_N(char, fb->initial_length); fb->capa = fb->initial_length; } for (required = fb->capa; requested > required - fb->len; required <<= 1); - if (required > fb->capa) { - REALLOC_N(fb->ptr, char, required); - fb->capa = required; + fbuffer_realloc(fb, required); +} + +static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) +{ +#if JSON_DEBUG + fb->requested = requested; +#endif + + if (RB_UNLIKELY(requested > fb->capa - fb->len)) { + fbuffer_do_inc_capa(fb, requested); } } -static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) +static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, unsigned long len) +{ + MEMCPY(fb->ptr + fb->len, newstr, char, len); + fbuffer_consumed(fb, len); +} + +static inline void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) { if (len > 0) { fbuffer_inc_capa(fb, len); - MEMCPY(fb->ptr + fb->len, newstr, char, len); - fb->len += len; + fbuffer_append_reserved(fb, newstr, len); } } -#ifdef JSON_GENERATOR +/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */ +static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr) +{ +#if JSON_DEBUG + if (fb->requested < 1) { + rb_bug("fbuffer: unreserved write"); + } + fb->requested--; +#endif + + fb->ptr[fb->len] = chr; + fb->len++; +} + static void fbuffer_append_str(FBuffer *fb, VALUE str) { const char *newstr = StringValuePtr(str); unsigned long len = RSTRING_LEN(str); - RB_GC_GUARD(str); - fbuffer_append(fb, newstr, len); } + +static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat) +{ + const char *newstr = StringValuePtr(str); + unsigned long len = RSTRING_LEN(str); + + fbuffer_inc_capa(fb, repeat * len); + while (repeat) { +#if JSON_DEBUG + fb->requested = len; #endif + fbuffer_append_reserved(fb, newstr, len); + repeat--; + } +} -static void fbuffer_append_char(FBuffer *fb, char newchr) +static inline void fbuffer_append_char(FBuffer *fb, char newchr) { fbuffer_inc_capa(fb, 1); *(fb->ptr + fb->len) = newchr; - fb->len++; + fbuffer_consumed(fb, 1); } -#ifdef JSON_GENERATOR -static void freverse(char *start, char *end) +static inline char *fbuffer_cursor(FBuffer *fb) { - char c; - - while (end > start) { - c = *end, *end-- = *start, *start++ = c; - } + return fb->ptr + fb->len; } -static long fltoa(long number, char *buf) +static inline void fbuffer_advance_to(FBuffer *fb, char *end) { - static char digits[] = "0123456789"; - long sign = number; - char* tmp = buf; - - if (sign < 0) number = -number; - do *tmp++ = digits[number % 10]; while (number /= 10); - if (sign < 0) *tmp++ = '-'; - freverse(buf, tmp - 1); - return tmp - buf; + fbuffer_consumed(fb, (end - fb->ptr) - fb->len); } +/* + * Appends the decimal string representation of \a number into the buffer. + */ static void fbuffer_append_long(FBuffer *fb, long number) { - char buf[20]; - unsigned long len = fltoa(number, buf); - fbuffer_append(fb, buf, len); -} - -static FBuffer *fbuffer_dup(FBuffer *fb) -{ - unsigned long len = fb->len; - FBuffer *result; + /* + * The jeaiii_ultoa() function produces digits left-to-right, + * allowing us to write directly into the buffer, but we don't know + * the number of resulting characters. + * + * We do know, however, that the `number` argument is always in the + * range 0xc000000000000000 to 0x3fffffffffffffff, or, in decimal, + * -4611686018427387904 to 4611686018427387903. The max number of chars + * generated is therefore 20 (including a potential sign character). + */ + + static const int MAX_CHARS_FOR_LONG = 20; + + fbuffer_inc_capa(fb, MAX_CHARS_FOR_LONG); + + if (number < 0) { + fbuffer_append_reserved_char(fb, '-'); + + /* + * Since number is always > LONG_MIN, `-number` will not overflow + * and is always the positive abs() value. + */ + number = -number; + } - result = fbuffer_alloc(len); - fbuffer_append(result, FBUFFER_PAIR(fb)); - return result; + char *end = jeaiii_ultoa(fbuffer_cursor(fb), number); + fbuffer_advance_to(fb, end); } -static VALUE fbuffer_to_s(FBuffer *fb) +static VALUE fbuffer_finalize(FBuffer *fb) { - VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); - fbuffer_free(fb); - FORCE_UTF8(result); - return result; + if (fb->io) { + fbuffer_flush(fb); + rb_io_flush(fb->io); + return fb->io; + } else { + return rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); + } } -#endif -#endif + +#endif // _FBUFFER_H_ diff --git a/ext/json/generator/depend b/ext/json/generator/depend index 855e876cdb..3ba4acfdd2 100644 --- a/ext/json/generator/depend +++ b/ext/json/generator/depend @@ -1,5 +1,5 @@ $(OBJS): $(ruby_headers) -generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h +generator.o: generator.c $(srcdir)/../fbuffer/fbuffer.h # AUTOGENERATED DEPENDENCIES START generator.o: $(RUBY_EXTCONF_H) @@ -10,7 +10,6 @@ generator.o: $(hdrdir)/ruby/backward.h generator.o: $(hdrdir)/ruby/backward/2/assume.h generator.o: $(hdrdir)/ruby/backward/2/attributes.h generator.o: $(hdrdir)/ruby/backward/2/bool.h -generator.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h generator.o: $(hdrdir)/ruby/backward/2/inttypes.h generator.o: $(hdrdir)/ruby/backward/2/limits.h generator.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -19,6 +18,7 @@ generator.o: $(hdrdir)/ruby/backward/2/stdarg.h generator.o: $(hdrdir)/ruby/defines.h generator.o: $(hdrdir)/ruby/encoding.h generator.o: $(hdrdir)/ruby/intern.h +generator.o: $(hdrdir)/ruby/internal/abi.h generator.o: $(hdrdir)/ruby/internal/anyargs.h generator.o: $(hdrdir)/ruby/internal/arithmetic.h generator.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -56,6 +56,7 @@ generator.o: $(hdrdir)/ruby/internal/attr/noexcept.h generator.o: $(hdrdir)/ruby/internal/attr/noinline.h generator.o: $(hdrdir)/ruby/internal/attr/nonnull.h generator.o: $(hdrdir)/ruby/internal/attr/noreturn.h +generator.o: $(hdrdir)/ruby/internal/attr/packed_struct.h generator.o: $(hdrdir)/ruby/internal/attr/pure.h generator.o: $(hdrdir)/ruby/internal/attr/restrict.h generator.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -125,7 +126,6 @@ generator.o: $(hdrdir)/ruby/internal/intern/enumerator.h generator.o: $(hdrdir)/ruby/internal/intern/error.h generator.o: $(hdrdir)/ruby/internal/intern/eval.h generator.o: $(hdrdir)/ruby/internal/intern/file.h -generator.o: $(hdrdir)/ruby/internal/intern/gc.h generator.o: $(hdrdir)/ruby/internal/intern/hash.h generator.o: $(hdrdir)/ruby/internal/intern/io.h generator.o: $(hdrdir)/ruby/internal/intern/load.h @@ -142,6 +142,7 @@ generator.o: $(hdrdir)/ruby/internal/intern/re.h generator.o: $(hdrdir)/ruby/internal/intern/ruby.h generator.o: $(hdrdir)/ruby/internal/intern/select.h generator.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +generator.o: $(hdrdir)/ruby/internal/intern/set.h generator.o: $(hdrdir)/ruby/internal/intern/signal.h generator.o: $(hdrdir)/ruby/internal/intern/sprintf.h generator.o: $(hdrdir)/ruby/internal/intern/string.h @@ -156,12 +157,12 @@ generator.o: $(hdrdir)/ruby/internal/memory.h generator.o: $(hdrdir)/ruby/internal/method.h generator.o: $(hdrdir)/ruby/internal/module.h generator.o: $(hdrdir)/ruby/internal/newobj.h -generator.o: $(hdrdir)/ruby/internal/rgengc.h generator.o: $(hdrdir)/ruby/internal/scan_args.h generator.o: $(hdrdir)/ruby/internal/special_consts.h generator.o: $(hdrdir)/ruby/internal/static_assert.h generator.o: $(hdrdir)/ruby/internal/stdalign.h generator.o: $(hdrdir)/ruby/internal/stdbool.h +generator.o: $(hdrdir)/ruby/internal/stdckdint.h generator.o: $(hdrdir)/ruby/internal/symbol.h generator.o: $(hdrdir)/ruby/internal/value.h generator.o: $(hdrdir)/ruby/internal/value_type.h @@ -177,6 +178,9 @@ generator.o: $(hdrdir)/ruby/ruby.h generator.o: $(hdrdir)/ruby/st.h generator.o: $(hdrdir)/ruby/subst.h generator.o: $(srcdir)/../fbuffer/fbuffer.h +generator.o: $(srcdir)/../json.h +generator.o: $(srcdir)/../simd/simd.h +generator.o: $(srcdir)/../vendor/fpconv.c +generator.o: $(srcdir)/../vendor/jeaiii-ltoa.h generator.o: generator.c -generator.o: generator.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/generator/extconf.rb b/ext/json/generator/extconf.rb index 8627c5f4bd..ee1bbeaba7 100644 --- a/ext/json/generator/extconf.rb +++ b/ext/json/generator/extconf.rb @@ -1,4 +1,16 @@ require 'mkmf' -$defs << "-DJSON_GENERATOR" -create_makefile 'json/ext/generator' +if RUBY_ENGINE == 'truffleruby' + # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension + File.write('Makefile', dummy_makefile("").join) +else + append_cflags("-std=c99") + $defs << "-DJSON_GENERATOR" + $defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0" + + if enable_config('generator-use-simd', default=!ENV["JSON_DISABLE_SIMD"]) + load __dir__ + "/../simd/conf.rb" + end + + create_makefile 'json/ext/generator' +end diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index e3a83472e1..dbba99c455 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -1,324 +1,706 @@ +#include "../json.h" #include "../fbuffer/fbuffer.h" -#include "generator.h" +#include "../vendor/fpconv.c" -static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject, - mHash, mArray, +#include <math.h> +#include <ctype.h> + +#include "../simd/simd.h" + +/* ruby api and some helpers */ + +enum duplicate_key_action { + JSON_DEPRECATED = 0, + JSON_IGNORE, + JSON_RAISE, +}; + +typedef struct JSON_Generator_StateStruct { + VALUE indent; + VALUE space; + VALUE space_before; + VALUE object_nl; + VALUE array_nl; + VALUE as_json; + + long max_nesting; + long depth; + long buffer_initial_length; + + enum duplicate_key_action on_duplicate_key; + + bool as_json_single_arg; + bool allow_nan; + bool ascii_only; + bool script_safe; + bool strict; +} JSON_Generator_State; + +static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_UTF_8; + +static ID i_to_s, i_to_json, i_new, i_encode; +static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, sym_allow_duplicate_key, + sym_ascii_only, sym_depth, sym_buffer_initial_length, sym_script_safe, sym_escape_slash, sym_strict, sym_as_json; + + +#define GET_STATE_TO(self, state) \ + TypedData_Get_Struct(self, JSON_Generator_State, &JSON_Generator_State_type, state) + +#define GET_STATE(self) \ + JSON_Generator_State *state; \ + GET_STATE_TO(self, state) + +struct generate_json_data; + +typedef void (*generator_func)(FBuffer *buffer, struct generate_json_data *data, VALUE obj); + +struct generate_json_data { + FBuffer *buffer; + VALUE vstate; + JSON_Generator_State *state; + VALUE obj; + generator_func func; + long depth; +}; + +static SIMD_Implementation simd_impl; + +static VALUE cState_from_state_s(VALUE self, VALUE opts); +static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func, VALUE io); +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj); #ifdef RUBY_INTEGER_UNIFICATION - mInteger, -#else - mFixnum, mBignum, +static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj); #endif - mFloat, mString, mString_Extend, - mTrueClass, mFalseClass, mNilClass, eGeneratorError, - eNestingError; +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj); -static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before, - i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only, - i_pack, i_unpack, i_create_id, i_extend, i_key_p, - i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth, - i_buffer_initial_length, i_dup, i_escape_slash; +static int usascii_encindex, utf8_encindex, binary_encindex; -/* - * Copyright 2001-2004 Unicode, Inc. +NORETURN(static void) raise_generator_error_str(VALUE invalid_object, VALUE str) +{ + rb_enc_associate_index(str, utf8_encindex); + VALUE exc = rb_exc_new_str(eGeneratorError, str); + rb_ivar_set(exc, rb_intern("@invalid_object"), invalid_object); + rb_exc_raise(exc); +} + +#ifdef RBIMPL_ATTR_FORMAT +RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3) +#endif +NORETURN(static void) raise_generator_error(VALUE invalid_object, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + VALUE str = rb_vsprintf(fmt, args); + va_end(args); + raise_generator_error_str(invalid_object, str); +} + +// 0 - single byte char that don't need to be escaped. +// (x | 8) - char that needs to be escaped. +static const unsigned char CHAR_LENGTH_MASK = 7; +static const unsigned char ESCAPE_MASK = 8; + +typedef struct _search_state { + const char *ptr; + const char *end; + const char *cursor; + FBuffer *buffer; + +#ifdef HAVE_SIMD + const char *chunk_base; + const char *chunk_end; + bool has_matches; + +#if defined(HAVE_SIMD_NEON) + uint64_t matches_mask; +#elif defined(HAVE_SIMD_SSE2) + int matches_mask; +#else +#error "Unknown SIMD Implementation." +#endif /* HAVE_SIMD_NEON */ +#endif /* HAVE_SIMD */ +} search_state; + +ALWAYS_INLINE(static) void search_flush(search_state *search) +{ + // Do not remove this conditional without profiling, specifically escape-heavy text. + // escape_UTF8_char_basic will advance search->ptr and search->cursor (effectively a search_flush). + // For back-to-back characters that need to be escaped, specifically for the SIMD code paths, this method + // will be called just before calling escape_UTF8_char_basic. There will be no characters to append for the + // consecutive characters that need to be escaped. While the fbuffer_append is a no-op if + // nothing needs to be flushed, we can save a few memory references with this conditional. + if (search->ptr > search->cursor) { + fbuffer_append(search->buffer, search->cursor, search->ptr - search->cursor); + search->cursor = search->ptr; + } +} + +static const unsigned char escape_table_basic[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static inline unsigned char search_escape_basic(search_state *search) +{ + while (search->ptr < search->end) { + if (RB_UNLIKELY(escape_table_basic[(const unsigned char)*search->ptr])) { + search_flush(search); + return 1; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +ALWAYS_INLINE(static) void escape_UTF8_char_basic(search_state *search) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + search->ptr++; + search->cursor = search->ptr; +} + +/* Converts in_string to a JSON string (without the wrapping '"' + * characters) in FBuffer out_buffer. * - * Disclaimer + * Character are JSON-escaped according to: * - * 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. + * - Always: ASCII control characters (0x00-0x1F), dquote, and + * backslash. * - * Limitations on Rights to Redistribute This Code + * - If out_ascii_only: non-ASCII characters (>0x7F) * - * 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. + * - If script_safe: forwardslash (/), line separator (U+2028), and + * paragraph separator (U+2029) + * + * Everything else (should be UTF-8) is just passed through and + * appended to the result. */ -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; +#if defined(HAVE_SIMD_NEON) +static inline unsigned char search_escape_basic_neon(search_state *search); +#elif defined(HAVE_SIMD_SSE2) +static inline unsigned char search_escape_basic_sse2(search_state *search); +#endif -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns 0. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ -static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length) -{ - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return 0; - /* Everything else falls through when "1"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; - case 2: if ((a = (*--srcptr)) > 0xBF) return 0; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return 0; break; - case 0xED: if (a > 0x9F) return 0; break; - case 0xF0: if (a < 0x90) return 0; break; - case 0xF4: if (a > 0x8F) return 0; break; - default: if (a < 0x80) return 0; - } +static inline unsigned char search_escape_basic(search_state *search); - case 1: if (*source >= 0x80 && *source < 0xC2) return 0; +static inline void convert_UTF8_to_JSON(search_state *search) +{ +#ifdef HAVE_SIMD +#if defined(HAVE_SIMD_NEON) + while (search_escape_basic_neon(search)) { + escape_UTF8_char_basic(search); } - if (*source > 0xF4) return 0; - return 1; +#elif defined(HAVE_SIMD_SSE2) + if (simd_impl == SIMD_SSE2) { + while (search_escape_basic_sse2(search)) { + escape_UTF8_char_basic(search); + } + return; + } + while (search_escape_basic(search)) { + escape_UTF8_char_basic(search); + } +#endif +#else + while (search_escape_basic(search)) { + escape_UTF8_char_basic(search); + } +#endif /* HAVE_SIMD */ +} + +static inline void escape_UTF8_char(search_state *search, unsigned char ch_len) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + break; + } + case 3: { + if (search->ptr[2] & 1) { + fbuffer_append(search->buffer, "\\u2029", 6); + } else { + fbuffer_append(search->buffer, "\\u2028", 6); + } + break; + } + } + search->cursor = (search->ptr += ch_len); } -/* Escapes the UTF16 character and stores the result in the buffer buf. */ -static void unicode_escape(char *buf, UTF16 character) +#ifdef HAVE_SIMD + +ALWAYS_INLINE(static) char *copy_remaining_bytes(search_state *search, unsigned long vec_len, unsigned long len) { - const char *digits = "0123456789abcdef"; + RBIMPL_ASSERT_OR_ASSUME(len < vec_len); + + // Flush the buffer so everything up until the last 'len' characters are unflushed. + search_flush(search); + + FBuffer *buf = search->buffer; + fbuffer_inc_capa(buf, vec_len); - buf[2] = digits[character >> 12]; - buf[3] = digits[(character >> 8) & 0xf]; - buf[4] = digits[(character >> 4) & 0xf]; - buf[5] = digits[character & 0xf]; + char *s = (buf->ptr + buf->len); + + // Pad the buffer with dummy characters that won't need escaping. + // This seem wasteful at first sight, but memset of vector length is very fast. + // This is a space as it can be directly represented as an immediate on AArch64. + memset(s, ' ', vec_len); + + // Optimistically copy the remaining 'len' characters to the output FBuffer. If there are no characters + // to escape, then everything ends up in the correct spot. Otherwise it was convenient temporary storage. + if (vec_len == 16) { + RBIMPL_ASSERT_OR_ASSUME(len >= SIMD_MINIMUM_THRESHOLD); + json_fast_memcpy16(s, search->ptr, len); + } else { + MEMCPY(s, search->ptr, char, len); + } + + return s; } -/* Escapes the UTF16 character and stores the result in the buffer buf, then - * the buffer buf is appended to the FBuffer buffer. */ -static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 - character) +#ifdef HAVE_SIMD_NEON + +ALWAYS_INLINE(static) unsigned char neon_next_match(search_state *search) { - unicode_escape(buf, character); - fbuffer_append(buffer, buf, 6); + uint64_t mask = search->matches_mask; + uint32_t index = trailing_zeros64(mask) >> 2; + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; } -/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII - * and control characters are JSON escaped. */ -static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash) +static inline unsigned char search_escape_basic_neon(search_state *search) { - const UTF8 *source = (UTF8 *) RSTRING_PTR(string); - const UTF8 *sourceEnd = source + RSTRING_LEN(string); - char buf[6] = { '\\', 'u' }; - - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "partial character in source, but hit end"); - } - if (!isLegalUTF8(source, extraBytesToRead+1)) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "source sequence is illegal/malformed utf-8"); + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return neon_next_match(search); + } else { + // neon_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + search->ptr = search->chunk_end; } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; + } + + /* + * The code below implements an SIMD-based algorithm to determine if N bytes at a time + * need to be escaped. + * + * Assume the ptr = "Te\sting!" (the double quotes are included in the string) + * + * The explanation will be limited to the first 8 bytes of the string for simplicity. However + * the vector insructions may work on larger vectors. + * + * First, we load three constants 'lower_bound', 'backslash' and 'dblquote" in vector registers. + * + * lower_bound: [20 20 20 20 20 20 20 20] + * backslash: [5C 5C 5C 5C 5C 5C 5C 5C] + * dblquote: [22 22 22 22 22 22 22 22] + * + * Next we load the first chunk of the ptr: + * [22 54 65 5C 73 74 69 6E] (" T e \ s t i n) + * + * First we check if any byte in chunk is less than 32 (0x20). This returns the following vector + * as no bytes are less than 32 (0x20): + * [0 0 0 0 0 0 0 0] + * + * Next, we check if any byte in chunk is equal to a backslash: + * [0 0 0 FF 0 0 0 0] + * + * Finally we check if any byte in chunk is equal to a double quote: + * [FF 0 0 0 0 0 0 0] + * + * Now we have three vectors where each byte indicates if the corresponding byte in chunk + * needs to be escaped. We combine these vectors with a series of logical OR instructions. + * This is the needs_escape vector and it is equal to: + * [FF 0 0 FF 0 0 0 0] + * + * Next we compute the bitwise AND between each byte and 0x1 and compute the horizontal sum of + * the values in the vector. This computes how many bytes need to be escaped within this chunk. + * + * Finally we compute a mask that indicates which bytes need to be escaped. If the mask is 0 then, + * no bytes need to be escaped and we can continue to the next chunk. If the mask is not 0 then we + * have at least one byte that needs to be escaped. + */ + + if (string_scan_simd_neon(&search->ptr, search->end, &search->matches_mask)) { + search->has_matches = true; + search->chunk_base = search->ptr; + search->chunk_end = search->ptr + sizeof(uint8x16_t); + return neon_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(uint8x16_t), remaining); + + uint64_t mask = compute_chunk_mask_neon(s); + + if (!mask) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { -#if UNI_STRICT_CONVERSION - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - rb_raise(rb_path2class("JSON::GeneratorError"), - "source sequence is illegal/malformed utf-8"); + + search->matches_mask = mask; + search->has_matches = true; + search->chunk_end = search->end; + search->chunk_base = search->ptr; + return neon_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} +#endif /* HAVE_SIMD_NEON */ + +#ifdef HAVE_SIMD_SSE2 + +ALWAYS_INLINE(static) unsigned char sse2_next_match(search_state *search) +{ + int mask = search->matches_mask; + int index = trailing_zeros(mask); + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; +} + +#if defined(__clang__) || defined(__GNUC__) +#define TARGET_SSE2 __attribute__((target("sse2"))) #else - unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR); +#define TARGET_SSE2 #endif + +ALWAYS_INLINE(static) TARGET_SSE2 unsigned char search_escape_basic_sse2(search_state *search) +{ + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return sse2_next_match(search); + } else { + // sse2_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + if (RB_UNLIKELY(search->chunk_base + sizeof(__m128i) >= search->end)) { + search->ptr = search->end; } else { - /* normal case */ - if (ch >= 0x20 && ch <= 0x7f) { - switch (ch) { - case '\\': - fbuffer_append(buffer, "\\\\", 2); - break; - case '"': - fbuffer_append(buffer, "\\\"", 2); - break; - case '/': - if(escape_slash) { - fbuffer_append(buffer, "\\/", 2); - break; - } - default: - fbuffer_append_char(buffer, (char)ch); - break; - } - } else { - switch (ch) { - case '\n': - fbuffer_append(buffer, "\\n", 2); - break; - case '\r': - fbuffer_append(buffer, "\\r", 2); - break; - case '\t': - fbuffer_append(buffer, "\\t", 2); - break; - case '\f': - fbuffer_append(buffer, "\\f", 2); - break; - case '\b': - fbuffer_append(buffer, "\\b", 2); - break; - default: - unicode_escape_to_buffer(buffer, buf, (UTF16) ch); - break; + search->ptr = search->chunk_base + sizeof(__m128i); + } + } + } + + if (string_scan_simd_sse2(&search->ptr, search->end, &search->matches_mask)) { + search->has_matches = true; + search->chunk_base = search->ptr; + search->chunk_end = search->ptr + sizeof(__m128i); + return sse2_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(__m128i), remaining); + + int needs_escape_mask = compute_chunk_mask_sse2(s); + + if (needs_escape_mask == 0) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; + } + + search->has_matches = true; + search->matches_mask = needs_escape_mask; + search->chunk_base = search->ptr; + return sse2_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} + +#endif /* HAVE_SIMD_SSE2 */ + +#endif /* HAVE_SIMD */ + +static const unsigned char script_safe_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, // '"' and '/' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3,11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE2 is the start of \u2028 and \u2029 + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_script_safe_escape(search_state *search) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = script_safe_escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + if (ch_len & ESCAPE_MASK) { + if (RB_UNLIKELY(ch_len == 11)) { + const unsigned char *uptr = (const unsigned char *)search->ptr; + if (!(uptr[1] == 0x80 && (uptr[2] >> 1) == 0x54)) { + search->ptr += 3; + continue; } } + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr += ch_len; } - } else if (ch > UNI_MAX_UTF16) { -#if UNI_STRICT_CONVERSION - source -= (extraBytesToRead+1); /* return to the start */ - rb_raise(rb_path2class("JSON::GeneratorError"), - "source sequence is illegal/malformed utf8"); -#else - unicode_escape_to_buffer(buffer, buf, UNI_REPLACEMENT_CHAR); -#endif } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - ch -= halfBase; - unicode_escape_to_buffer(buffer, buf, (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START)); - unicode_escape_to_buffer(buffer, buf, (UTF16)((ch & halfMask) + UNI_SUR_LOW_START)); + search->ptr++; } } - RB_GC_GUARD(string); -} - -/* Converts string to a JSON string in FBuffer buffer, where only the - * characters required by the JSON standard are JSON escaped. The remaining - * characters (should be UTF8) are just passed through and appended to the - * result. */ -static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash) -{ - const char *ptr = RSTRING_PTR(string), *p; - unsigned long len = RSTRING_LEN(string), start = 0, end = 0; - const char *escape = NULL; - int escape_len; - unsigned char c; - char buf[6] = { '\\', 'u' }; - int ascii_only = rb_enc_str_asciionly_p(string); - - for (start = 0, end = 0; end < len;) { - p = ptr + end; - c = (unsigned char) *p; - if (c < 0x20) { - switch (c) { - case '\n': - escape = "\\n"; - escape_len = 2; - break; - case '\r': - escape = "\\r"; - escape_len = 2; - break; - case '\t': - escape = "\\t"; - escape_len = 2; - break; - case '\f': - escape = "\\f"; - escape_len = 2; - break; - case '\b': - escape = "\\b"; - escape_len = 2; - break; - default: - unicode_escape(buf, (UTF16) *p); - escape = buf; - escape_len = 6; + search_flush(search); + return 0; +} + +static void convert_UTF8_to_script_safe_JSON(search_state *search) +{ + unsigned char ch_len; + while ((ch_len = search_script_safe_escape(search))) { + escape_UTF8_char(search, ch_len); + } +} + +static const unsigned char ascii_only_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_ascii_only_escape(search_state *search, const unsigned char escape_table[256]) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static inline void full_escape_UTF8_char(search_state *search, unsigned char ch_len) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); break; + } } - } else { - switch (c) { - case '\\': - escape = "\\\\"; - escape_len = 2; + break; + } + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[12] = { '\\', 'u', 0, 0, 0, 0, '\\', 'u' }; + + uint32_t wchar = 0; + + switch (ch_len) { + case 2: + wchar = ch & 0x1F; break; - case '"': - escape = "\\\""; - escape_len = 2; + case 3: + wchar = ch & 0x0F; break; - case '/': - if(escape_slash) { - escape = "\\/"; - escape_len = 2; - break; - } - default: - { - unsigned short clen = 1; - if (!ascii_only) { - clen += trailingBytesForUTF8[c]; - if (end + clen > len) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "partial character in source, but hit end"); - } - if (!isLegalUTF8((UTF8 *) p, clen)) { - rb_raise(rb_path2class("JSON::GeneratorError"), - "source sequence is illegal/malformed utf-8"); - } - } - end += clen; - } - continue; + case 4: + wchar = ch & 0x07; break; } + + for (short i = 1; i < ch_len; i++) { + wchar = (wchar << 6) | (search->ptr[i] & 0x3F); + } + + if (wchar <= 0xFFFF) { + scratch[2] = hexdig[wchar >> 12]; + scratch[3] = hexdig[(wchar >> 8) & 0xf]; + scratch[4] = hexdig[(wchar >> 4) & 0xf]; + scratch[5] = hexdig[wchar & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + } else { + uint16_t hi, lo; + wchar -= 0x10000; + hi = 0xD800 + (uint16_t)(wchar >> 10); + lo = 0xDC00 + (uint16_t)(wchar & 0x3FF); + + scratch[2] = hexdig[hi >> 12]; + scratch[3] = hexdig[(hi >> 8) & 0xf]; + scratch[4] = hexdig[(hi >> 4) & 0xf]; + scratch[5] = hexdig[hi & 0xf]; + + scratch[8] = hexdig[lo >> 12]; + scratch[9] = hexdig[(lo >> 8) & 0xf]; + scratch[10] = hexdig[(lo >> 4) & 0xf]; + scratch[11] = hexdig[lo & 0xf]; + + fbuffer_append(search->buffer, scratch, 12); + } + + break; } - fbuffer_append(buffer, ptr + start, end - start); - fbuffer_append(buffer, escape, escape_len); - start = ++end; - escape = NULL; } - fbuffer_append(buffer, ptr + start, end - start); + search->cursor = (search->ptr += ch_len); } -static char *fstrndup(const char *ptr, unsigned long len) { - char *result; - if (len <= 0) return NULL; - result = ALLOC_N(char, len); - memcpy(result, ptr, len); - return result; +static void convert_UTF8_to_ASCII_only_JSON(search_state *search, const unsigned char escape_table[256]) +{ + unsigned char ch_len; + while ((ch_len = search_ascii_only_escape(search, escape_table))) { + full_escape_UTF8_char(search, ch_len); + } } /* @@ -413,7 +795,9 @@ static char *fstrndup(const char *ptr, unsigned long len) { */ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(object); + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_object, Qfalse); } /* @@ -424,8 +808,11 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) * _state_ is a JSON::State object, that can also be used to configure the * produced JSON string output further. */ -static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(array); +static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_array, Qfalse); } #ifdef RUBY_INTEGER_UNIFICATION @@ -436,7 +823,9 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { */ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(integer); + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_integer, Qfalse); } #else @@ -447,7 +836,9 @@ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(fixnum); + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_fixnum, Qfalse); } /* @@ -457,7 +848,9 @@ static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(bignum); + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_bignum, Qfalse); } #endif @@ -468,17 +861,9 @@ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(float); -} - -/* - * call-seq: String.included(modul) - * - * Extends _modul_ with the String::Extend module. - */ -static VALUE mString_included_s(VALUE self, VALUE modul) { - VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend); - return result; + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_float, Qfalse); } /* @@ -490,52 +875,9 @@ static VALUE mString_included_s(VALUE self, VALUE modul) { */ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(string); -} - -/* - * call-seq: to_json_raw_object() - * - * This method creates a raw object hash, that can be nested into - * other data structures and will be generated as a raw string. This - * method should be used, if you want to convert raw strings to JSON - * instead of UTF-8 strings, e. g. binary data. - */ -static VALUE mString_to_json_raw_object(VALUE self) -{ - VALUE ary; - VALUE result = rb_hash_new(); - rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self))); - ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*")); - rb_hash_aset(result, rb_str_new2("raw"), ary); - return result; -} - -/* - * call-seq: to_json_raw(*args) - * - * This method creates a JSON text from the result of a call to - * to_json_raw_object of this String. - */ -static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self) -{ - VALUE obj = mString_to_json_raw_object(self); - Check_Type(obj, T_HASH); - return mHash_to_json(argc, argv, obj); -} - -/* - * call-seq: json_create(o) - * - * Raw Strings are JSON Objects (the raw bytes are stored in an array for the - * key "raw"). The Ruby String can be created by this module method. - */ -static VALUE mString_Extend_json_create(VALUE self, VALUE o) -{ - VALUE ary; - Check_Type(o, T_HASH); - ary = rb_hash_aref(o, rb_str_new2("raw")); - return rb_funcall(ary, i_pack, 1, rb_str_new2("C*")); + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_string, Qfalse); } /* @@ -545,7 +887,8 @@ static VALUE mString_Extend_json_create(VALUE self, VALUE o) */ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(true); + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("true", 4); } /* @@ -555,7 +898,8 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(false); + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("false", 5); } /* @@ -565,7 +909,8 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) */ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) { - GENERATE_JSON(null); + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("null", 4); } /* @@ -582,545 +927,641 @@ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &state); Check_Type(string, T_STRING); state = cState_from_state_s(cState, state); - return cState_partial_generate(state, string); + return cState_partial_generate(state, string, generate_json_string, Qfalse); +} + +static void State_mark(void *ptr) +{ + JSON_Generator_State *state = ptr; + rb_gc_mark_movable(state->indent); + rb_gc_mark_movable(state->space); + rb_gc_mark_movable(state->space_before); + rb_gc_mark_movable(state->object_nl); + rb_gc_mark_movable(state->array_nl); + rb_gc_mark_movable(state->as_json); +} + +static void State_compact(void *ptr) +{ + JSON_Generator_State *state = ptr; + state->indent = rb_gc_location(state->indent); + state->space = rb_gc_location(state->space); + state->space_before = rb_gc_location(state->space_before); + state->object_nl = rb_gc_location(state->object_nl); + state->array_nl = rb_gc_location(state->array_nl); + state->as_json = rb_gc_location(state->as_json); } static void State_free(void *ptr) { JSON_Generator_State *state = ptr; - if (state->indent) ruby_xfree(state->indent); - if (state->space) ruby_xfree(state->space); - if (state->space_before) ruby_xfree(state->space_before); - if (state->object_nl) ruby_xfree(state->object_nl); - if (state->array_nl) ruby_xfree(state->array_nl); - if (state->array_delim) fbuffer_free(state->array_delim); - if (state->object_delim) fbuffer_free(state->object_delim); - if (state->object_delim2) fbuffer_free(state->object_delim2); ruby_xfree(state); } static size_t State_memsize(const void *ptr) { - const JSON_Generator_State *state = ptr; - size_t size = sizeof(*state); - if (state->indent) size += state->indent_len + 1; - if (state->space) size += state->space_len + 1; - if (state->space_before) size += state->space_before_len + 1; - if (state->object_nl) size += state->object_nl_len + 1; - if (state->array_nl) size += state->array_nl_len + 1; - if (state->array_delim) size += FBUFFER_CAPA(state->array_delim); - if (state->object_delim) size += FBUFFER_CAPA(state->object_delim); - if (state->object_delim2) size += FBUFFER_CAPA(state->object_delim2); - return size; -} - -#ifndef HAVE_RB_EXT_RACTOR_SAFE -# undef RUBY_TYPED_FROZEN_SHAREABLE -# define RUBY_TYPED_FROZEN_SHAREABLE 0 -#endif + return sizeof(JSON_Generator_State); +} -#ifdef NEW_TYPEDDATA_WRAPPER static const rb_data_type_t JSON_Generator_State_type = { "JSON/Generator/State", - {NULL, State_free, State_memsize,}, -#ifdef RUBY_TYPED_FREE_IMMEDIATELY + { + .dmark = State_mark, + .dfree = State_free, + .dsize = State_memsize, + .dcompact = State_compact, + }, 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE, -#endif + RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE, }; -#endif + +static void state_init(JSON_Generator_State *state) +{ + state->max_nesting = 100; + state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; +} static VALUE cState_s_allocate(VALUE klass) { JSON_Generator_State *state; - return TypedData_Make_Struct(klass, JSON_Generator_State, - &JSON_Generator_State_type, state); + VALUE obj = TypedData_Make_Struct(klass, JSON_Generator_State, &JSON_Generator_State_type, state); + state_init(state); + return obj; } -/* - * call-seq: configure(opts) - * - * Configure this State instance with the Hash _opts_, and return - * itself. - */ -static VALUE cState_configure(VALUE self, VALUE opts) +static void vstate_spill(struct generate_json_data *data) { - VALUE tmp; - GET_STATE(self); - tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash"); - if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h"); - opts = tmp; - tmp = rb_hash_aref(opts, ID2SYM(i_indent)); - if (RTEST(tmp)) { - unsigned long len; - Check_Type(tmp, T_STRING); - len = RSTRING_LEN(tmp); - state->indent = fstrndup(RSTRING_PTR(tmp), len + 1); - state->indent_len = len; - } - tmp = rb_hash_aref(opts, ID2SYM(i_space)); - if (RTEST(tmp)) { - unsigned long len; - Check_Type(tmp, T_STRING); - len = RSTRING_LEN(tmp); - state->space = fstrndup(RSTRING_PTR(tmp), len + 1); - state->space_len = len; + VALUE vstate = cState_s_allocate(cState); + GET_STATE(vstate); + MEMCPY(state, data->state, JSON_Generator_State, 1); + data->state = state; + data->vstate = vstate; + RB_OBJ_WRITTEN(vstate, Qundef, state->indent); + RB_OBJ_WRITTEN(vstate, Qundef, state->space); + RB_OBJ_WRITTEN(vstate, Qundef, state->space_before); + RB_OBJ_WRITTEN(vstate, Qundef, state->object_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->array_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->as_json); +} + +static inline VALUE json_call_to_json(struct generate_json_data *data, VALUE obj) +{ + if (RB_UNLIKELY(!data->vstate)) { + vstate_spill(data); } - tmp = rb_hash_aref(opts, ID2SYM(i_space_before)); - if (RTEST(tmp)) { - unsigned long len; - Check_Type(tmp, T_STRING); - len = RSTRING_LEN(tmp); - state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1); - state->space_before_len = len; + GET_STATE(data->vstate); + state->depth = data->depth; + VALUE tmp = rb_funcall(obj, i_to_json, 1, data->vstate); + // no need to restore state->depth, vstate is just a temporary State + return tmp; +} + +static VALUE +json_call_as_json(JSON_Generator_State *state, VALUE object, VALUE is_key) +{ + VALUE proc_args[2] = {object, is_key}; + return rb_proc_call_with_block(state->as_json, 2, proc_args, Qnil); +} + +static VALUE +convert_string_subclass(VALUE key) +{ + VALUE key_to_s = rb_funcall(key, i_to_s, 0); + + if (RB_UNLIKELY(!RB_TYPE_P(key_to_s, T_STRING))) { + VALUE cname = rb_obj_class(key); + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")", + cname, "String", cname, "to_s", rb_obj_class(key_to_s)); } - tmp = rb_hash_aref(opts, ID2SYM(i_array_nl)); - if (RTEST(tmp)) { - unsigned long len; - Check_Type(tmp, T_STRING); - len = RSTRING_LEN(tmp); - state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1); - state->array_nl_len = len; + + return key_to_s; +} + +static bool enc_utf8_compatible_p(int enc_idx) +{ + if (enc_idx == usascii_encindex) return true; + if (enc_idx == utf8_encindex) return true; + return false; +} + +static VALUE encode_json_string_try(VALUE str) +{ + return rb_funcall(str, i_encode, 1, Encoding_UTF_8); +} + +static VALUE encode_json_string_rescue(VALUE str, VALUE exception) +{ + raise_generator_error_str(str, rb_funcall(exception, rb_intern("message"), 0)); + return Qundef; +} + +static inline bool valid_json_string_p(VALUE str) +{ + int coderange = rb_enc_str_coderange(str); + + if (RB_LIKELY(coderange == ENC_CODERANGE_7BIT)) { + return true; } - tmp = rb_hash_aref(opts, ID2SYM(i_object_nl)); - if (RTEST(tmp)) { - unsigned long len; - Check_Type(tmp, T_STRING); - len = RSTRING_LEN(tmp); - state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1); - state->object_nl_len = len; + + if (RB_LIKELY(coderange == ENC_CODERANGE_VALID)) { + return enc_utf8_compatible_p(RB_ENCODING_GET_INLINED(str)); } - tmp = ID2SYM(i_max_nesting); - state->max_nesting = 100; - if (option_given_p(opts, tmp)) { - VALUE max_nesting = rb_hash_aref(opts, tmp); - if (RTEST(max_nesting)) { - Check_Type(max_nesting, T_FIXNUM); - state->max_nesting = FIX2LONG(max_nesting); - } else { - state->max_nesting = 0; - } + + return false; +} + +static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) +{ + if (RB_LIKELY(valid_json_string_p(str))) { + return str; } - tmp = ID2SYM(i_depth); - state->depth = 0; - if (option_given_p(opts, tmp)) { - VALUE depth = rb_hash_aref(opts, tmp); - if (RTEST(depth)) { - Check_Type(depth, T_FIXNUM); - state->depth = FIX2LONG(depth); - } else { - state->depth = 0; + + if (!as_json_called && data->state->strict && RTEST(data->state->as_json)) { + VALUE coerced_str = json_call_as_json(data->state, str, Qfalse); + if (coerced_str != str) { + if (RB_TYPE_P(coerced_str, T_STRING)) { + if (!valid_json_string_p(coerced_str)) { + raise_generator_error(str, "source sequence is illegal/malformed utf-8"); + } + } else { + // as_json could return another type than T_STRING + if (is_key) { + raise_generator_error(coerced_str, "%"PRIsVALUE" not allowed as object key in JSON", CLASS_OF(coerced_str)); + } + } + + return coerced_str; } } - tmp = ID2SYM(i_buffer_initial_length); - if (option_given_p(opts, tmp)) { - VALUE buffer_initial_length = rb_hash_aref(opts, tmp); - if (RTEST(buffer_initial_length)) { - long initial_length; - Check_Type(buffer_initial_length, T_FIXNUM); - initial_length = FIX2LONG(buffer_initial_length); - if (initial_length > 0) state->buffer_initial_length = initial_length; + + if (RB_ENCODING_GET_INLINED(str) == binary_encindex) { + VALUE utf8_string = rb_enc_associate_index(rb_str_dup(str), utf8_encindex); + switch (rb_enc_str_coderange(utf8_string)) { + case ENC_CODERANGE_7BIT: + return utf8_string; + case ENC_CODERANGE_VALID: + // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work. + // TODO: Raise in 3.0.0 + rb_warn("JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0"); + return utf8_string; + break; } } - tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan)); - state->allow_nan = RTEST(tmp); - tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only)); - state->ascii_only = RTEST(tmp); - tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash)); - state->escape_slash = RTEST(tmp); - return self; + + return rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str); } -static void set_state_ivars(VALUE hash, VALUE state) +static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - VALUE ivars = rb_obj_instance_variables(state); - int i = 0; - for (i = 0; i < RARRAY_LEN(ivars); i++) { - VALUE key = rb_funcall(rb_ary_entry(ivars, i), i_to_s, 0); - long key_len = RSTRING_LEN(key); - VALUE value = rb_iv_get(state, StringValueCStr(key)); - rb_hash_aset(hash, rb_str_intern(rb_str_substr(key, 1, key_len - 1)), value); + fbuffer_append_char(buffer, '"'); + + long len; + search_state search; + search.buffer = buffer; + RSTRING_GETMEM(obj, search.ptr, len); + search.cursor = search.ptr; + search.end = search.ptr + len; + +#ifdef HAVE_SIMD + search.matches_mask = 0; + search.has_matches = false; + search.chunk_base = NULL; + search.chunk_end = NULL; +#endif /* HAVE_SIMD */ + + switch (rb_enc_str_coderange(obj)) { + case ENC_CODERANGE_7BIT: + case ENC_CODERANGE_VALID: + if (RB_UNLIKELY(data->state->ascii_only)) { + convert_UTF8_to_ASCII_only_JSON(&search, data->state->script_safe ? script_safe_escape_table : ascii_only_escape_table); + } else if (RB_UNLIKELY(data->state->script_safe)) { + convert_UTF8_to_script_safe_JSON(&search); + } else { + convert_UTF8_to_JSON(&search); + } + break; + default: + raise_generator_error(obj, "source sequence is illegal/malformed utf-8"); + break; } + fbuffer_append_char(buffer, '"'); } -/* - * call-seq: to_h - * - * Returns the configuration instance variables as a hash, that can be - * passed to the configure method. - */ -static VALUE cState_to_h(VALUE self) +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - VALUE result = rb_hash_new(); - GET_STATE(self); - set_state_ivars(result, self); - rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len)); - rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len)); - rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len)); - rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len)); - rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len)); - rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse); - rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse); - rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting)); - rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse); - rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth)); - rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length)); - return result; + obj = ensure_valid_encoding(data, obj, false, false); + raw_generate_json_string(buffer, data, obj); } -/* -* call-seq: [](name) -* -* Returns the value returned by method +name+. -*/ -static VALUE cState_aref(VALUE self, VALUE name) -{ - name = rb_funcall(name, i_to_s, 0); - if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) { - return rb_funcall(self, i_send, 1, name); - } else { - return rb_attr_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name))); - } -} +struct hash_foreach_arg { + VALUE hash; + struct generate_json_data *data; + int first_key_type; + bool first; + bool mixed_keys_encountered; +}; -/* -* call-seq: []=(name, value) -* -* Sets the attribute name to value. -*/ -static VALUE cState_aset(VALUE self, VALUE name, VALUE value) +NOINLINE(static) void +json_inspect_hash_with_mixed_keys(struct hash_foreach_arg *arg) { - VALUE name_writer; + if (arg->mixed_keys_encountered) { + return; + } + arg->mixed_keys_encountered = true; - name = rb_funcall(name, i_to_s, 0); - name_writer = rb_str_cat2(rb_str_dup(name), "="); - if (RTEST(rb_funcall(self, i_respond_to_p, 1, name_writer))) { - return rb_funcall(self, i_send, 2, name_writer, value); - } else { - rb_ivar_set(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)), value); + JSON_Generator_State *state = arg->data->state; + if (state->on_duplicate_key != JSON_IGNORE) { + VALUE do_raise = state->on_duplicate_key == JSON_RAISE ? Qtrue : Qfalse; + rb_funcall(mJSON, rb_intern("on_mixed_keys_hash"), 2, arg->hash, do_raise); } - return Qnil; } -struct hash_foreach_arg { - FBuffer *buffer; - JSON_Generator_State *state; - VALUE Vstate; - int iter; -}; - static int json_object_i(VALUE key, VALUE val, VALUE _arg) { struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg; - FBuffer *buffer = arg->buffer; - JSON_Generator_State *state = arg->state; - VALUE Vstate = arg->Vstate; - - char *object_nl = state->object_nl; - long object_nl_len = state->object_nl_len; - char *indent = state->indent; - long indent_len = state->indent_len; - char *delim = FBUFFER_PTR(state->object_delim); - long delim_len = FBUFFER_LEN(state->object_delim); - char *delim2 = FBUFFER_PTR(state->object_delim2); - long delim2_len = FBUFFER_LEN(state->object_delim2); - long depth = state->depth; - int j; - VALUE klass, key_to_s; - - if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len); - if (object_nl) { - fbuffer_append(buffer, object_nl, object_nl_len); + struct generate_json_data *data = arg->data; + + FBuffer *buffer = data->buffer; + JSON_Generator_State *state = data->state; + + long depth = data->depth; + int key_type = rb_type(key); + + if (arg->first) { + arg->first = false; + arg->first_key_type = key_type; } - if (indent) { - for (j = 0; j < depth; j++) { - fbuffer_append(buffer, indent, indent_len); - } + else { + fbuffer_append_char(buffer, ','); } - klass = CLASS_OF(key); - if (klass == rb_cString) { - key_to_s = key; - } else if (klass == rb_cSymbol) { - key_to_s = rb_id2str(SYM2ID(key)); + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); + } + + VALUE key_to_s; + bool as_json_called = false; + + start: + switch (key_type) { + case T_STRING: + if (RB_UNLIKELY(arg->first_key_type != T_STRING)) { + json_inspect_hash_with_mixed_keys(arg); + } + + if (RB_LIKELY(RBASIC_CLASS(key) == rb_cString)) { + key_to_s = key; + } else { + key_to_s = convert_string_subclass(key); + } + break; + case T_SYMBOL: + if (RB_UNLIKELY(arg->first_key_type != T_SYMBOL)) { + json_inspect_hash_with_mixed_keys(arg); + } + + key_to_s = rb_sym2str(key); + break; + default: + if (data->state->strict) { + if (RTEST(data->state->as_json) && !as_json_called) { + key = json_call_as_json(data->state, key, Qtrue); + key_type = rb_type(key); + as_json_called = true; + goto start; + } else { + raise_generator_error(key, "%"PRIsVALUE" not allowed as object key in JSON", CLASS_OF(key)); + } + } + key_to_s = rb_convert_type(key, T_STRING, "String", "to_s"); + break; + } + + key_to_s = ensure_valid_encoding(data, key_to_s, as_json_called, true); + + if (RB_LIKELY(RBASIC_CLASS(key_to_s) == rb_cString)) { + raw_generate_json_string(buffer, data, key_to_s); } else { - key_to_s = rb_funcall(key, i_to_s, 0); + generate_json(buffer, data, key_to_s); } - Check_Type(key_to_s, T_STRING); - generate_json(buffer, Vstate, state, key_to_s); - fbuffer_append(buffer, delim2, delim2_len); - generate_json(buffer, Vstate, state, val); + if (RB_UNLIKELY(state->space_before)) fbuffer_append_str(buffer, data->state->space_before); + fbuffer_append_char(buffer, ':'); + if (RB_UNLIKELY(state->space)) fbuffer_append_str(buffer, data->state->space); + generate_json(buffer, data, val); - arg->iter++; return ST_CONTINUE; } -static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static inline long increase_depth(struct generate_json_data *data) +{ + JSON_Generator_State *state = data->state; + long depth = ++data->depth; + if (RB_UNLIKELY(depth > state->max_nesting && state->max_nesting)) { + rb_raise(eNestingError, "nesting of %ld is too deep. Did you try to serialize objects with circular references?", --data->depth); + } + return depth; +} + +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - char *object_nl = state->object_nl; - long object_nl_len = state->object_nl_len; - char *indent = state->indent; - long indent_len = state->indent_len; - long max_nesting = state->max_nesting; - long depth = ++state->depth; - int j; - struct hash_foreach_arg arg; + long depth = increase_depth(data); - if (max_nesting != 0 && depth > max_nesting) { - fbuffer_free(buffer); - rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth); + if (RHASH_SIZE(obj) == 0) { + fbuffer_append(buffer, "{}", 2); + --data->depth; + return; } + fbuffer_append_char(buffer, '{'); - arg.buffer = buffer; - arg.state = state; - arg.Vstate = Vstate; - arg.iter = 0; + struct hash_foreach_arg arg = { + .hash = obj, + .data = data, + .first = true, + }; rb_hash_foreach(obj, json_object_i, (VALUE)&arg); - depth = --state->depth; - if (object_nl) { - fbuffer_append(buffer, object_nl, object_nl_len); - if (indent) { - for (j = 0; j < depth; j++) { - fbuffer_append(buffer, indent, indent_len); - } + depth = --data->depth; + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); } } fbuffer_append_char(buffer, '}'); } -static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) -{ - char *array_nl = state->array_nl; - long array_nl_len = state->array_nl_len; - char *indent = state->indent; - long indent_len = state->indent_len; - long max_nesting = state->max_nesting; - char *delim = FBUFFER_PTR(state->array_delim); - long delim_len = FBUFFER_LEN(state->array_delim); - long depth = ++state->depth; - int i, j; - if (max_nesting != 0 && depth > max_nesting) { - fbuffer_free(buffer); - rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth); +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + long depth = increase_depth(data); + + if (RARRAY_LEN(obj) == 0) { + fbuffer_append(buffer, "[]", 2); + --data->depth; + return; } + fbuffer_append_char(buffer, '['); - if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len); - for(i = 0; i < RARRAY_LEN(obj); i++) { - if (i > 0) fbuffer_append(buffer, delim, delim_len); - if (indent) { - for (j = 0; j < depth; j++) { - fbuffer_append(buffer, indent, indent_len); - } + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + for (int i = 0; i < RARRAY_LEN(obj); i++) { + if (i > 0) { + fbuffer_append_char(buffer, ','); + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); } - generate_json(buffer, Vstate, state, rb_ary_entry(obj, i)); + generate_json(buffer, data, RARRAY_AREF(obj, i)); } - state->depth = --depth; - if (array_nl) { - fbuffer_append(buffer, array_nl, array_nl_len); - if (indent) { - for (j = 0; j < depth; j++) { - fbuffer_append(buffer, indent, indent_len); - } + data->depth = --depth; + if (RB_UNLIKELY(data->state->array_nl)) { + fbuffer_append_str(buffer, data->state->array_nl); + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); } } fbuffer_append_char(buffer, ']'); } -#ifdef HAVE_RUBY_ENCODING_H -static int enc_utf8_compatible_p(rb_encoding *enc) +static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - if (enc == rb_usascii_encoding()) return 1; - if (enc == rb_utf8_encoding()) return 1; - return 0; + VALUE tmp; + if (rb_respond_to(obj, i_to_json)) { + tmp = json_call_to_json(data, obj); + Check_Type(tmp, T_STRING); + fbuffer_append_str(buffer, tmp); + } else { + tmp = rb_funcall(obj, i_to_s, 0); + Check_Type(tmp, T_STRING); + generate_json_string(buffer, data, tmp); + } } -#endif -static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - fbuffer_append_char(buffer, '"'); -#ifdef HAVE_RUBY_ENCODING_H - if (!enc_utf8_compatible_p(rb_enc_get(obj))) { - obj = rb_str_export_to_enc(obj, rb_utf8_encoding()); - } -#endif - if (state->ascii_only) { - convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash); + if (data->state->strict) { + generate_json_string(buffer, data, rb_sym2str(obj)); } else { - convert_UTF8_to_JSON(buffer, obj, state->escape_slash); + generate_json_fallback(buffer, data, obj); } - fbuffer_append_char(buffer, '"'); } -static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { fbuffer_append(buffer, "null", 4); } -static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { fbuffer_append(buffer, "false", 5); } -static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { fbuffer_append(buffer, "true", 4); } -static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { fbuffer_append_long(buffer, FIX2LONG(obj)); } -static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { VALUE tmp = rb_funcall(obj, i_to_s, 0); fbuffer_append_str(buffer, tmp); } #ifdef RUBY_INTEGER_UNIFICATION -static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { if (FIXNUM_P(obj)) - generate_json_fixnum(buffer, Vstate, state, obj); + generate_json_fixnum(buffer, data, obj); else - generate_json_bignum(buffer, Vstate, state, obj); + generate_json_bignum(buffer, data, obj); } #endif -static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) + +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { double value = RFLOAT_VALUE(obj); - char allow_nan = state->allow_nan; - VALUE tmp = rb_funcall(obj, i_to_s, 0); - if (!allow_nan) { - if (isinf(value)) { - fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); - } else if (isnan(value)) { - fbuffer_free(buffer); - rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp)); + char allow_nan = data->state->allow_nan; + if (isinf(value) || isnan(value)) { + /* for NaN and Infinity values we either raise an error or rely on Float#to_s. */ + if (!allow_nan) { + if (data->state->strict && data->state->as_json) { + VALUE casted_obj = json_call_as_json(data->state, obj, Qfalse); + if (casted_obj != obj) { + increase_depth(data); + generate_json(buffer, data, casted_obj); + data->depth--; + return; + } + } + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", rb_funcall(obj, i_to_s, 0)); } + + VALUE tmp = rb_funcall(obj, i_to_s, 0); + fbuffer_append_str(buffer, tmp); + return; } - fbuffer_append_str(buffer, tmp); + + /* This implementation writes directly into the buffer. We reserve + * the 32 characters that fpconv_dtoa states as its maximum. + */ + fbuffer_inc_capa(buffer, 32); + char* d = buffer->ptr + buffer->len; + int len = fpconv_dtoa(value, d); + /* fpconv_dtoa converts a float to its shortest string representation, + * but it adds a ".0" if this is a plain integer. + */ + fbuffer_consumed(buffer, len); } -static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj) +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { - VALUE tmp; - VALUE klass = CLASS_OF(obj); - if (klass == rb_cHash) { - generate_json_object(buffer, Vstate, state, obj); - } else if (klass == rb_cArray) { - generate_json_array(buffer, Vstate, state, obj); - } else if (klass == rb_cString) { - generate_json_string(buffer, Vstate, state, obj); - } else if (obj == Qnil) { - generate_json_null(buffer, Vstate, state, obj); + VALUE fragment = RSTRUCT_GET(obj, 0); + Check_Type(fragment, T_STRING); + fbuffer_append_str(buffer, fragment); +} + +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + bool as_json_called = false; +start: + if (obj == Qnil) { + generate_json_null(buffer, data, obj); } else if (obj == Qfalse) { - generate_json_false(buffer, Vstate, state, obj); + generate_json_false(buffer, data, obj); } else if (obj == Qtrue) { - generate_json_true(buffer, Vstate, state, obj); - } else if (FIXNUM_P(obj)) { - generate_json_fixnum(buffer, Vstate, state, obj); - } else if (RB_TYPE_P(obj, T_BIGNUM)) { - generate_json_bignum(buffer, Vstate, state, obj); - } else if (klass == rb_cFloat) { - generate_json_float(buffer, Vstate, state, obj); - } else if (rb_respond_to(obj, i_to_json)) { - tmp = rb_funcall(obj, i_to_json, 1, Vstate); - Check_Type(tmp, T_STRING); - fbuffer_append_str(buffer, tmp); + generate_json_true(buffer, data, obj); + } else if (RB_SPECIAL_CONST_P(obj)) { + if (RB_FIXNUM_P(obj)) { + generate_json_fixnum(buffer, data, obj); + } else if (RB_FLONUM_P(obj)) { + generate_json_float(buffer, data, obj); + } else if (RB_STATIC_SYM_P(obj)) { + generate_json_symbol(buffer, data, obj); + } else { + goto general; + } } else { - tmp = rb_funcall(obj, i_to_s, 0); - Check_Type(tmp, T_STRING); - generate_json_string(buffer, Vstate, state, tmp); + VALUE klass = RBASIC_CLASS(obj); + switch (RB_BUILTIN_TYPE(obj)) { + case T_BIGNUM: + generate_json_bignum(buffer, data, obj); + break; + case T_HASH: + if (klass != rb_cHash) goto general; + generate_json_object(buffer, data, obj); + break; + case T_ARRAY: + if (klass != rb_cArray) goto general; + generate_json_array(buffer, data, obj); + break; + case T_STRING: + if (klass != rb_cString) goto general; + + if (RB_LIKELY(valid_json_string_p(obj))) { + raw_generate_json_string(buffer, data, obj); + } else if (as_json_called) { + raise_generator_error(obj, "source sequence is illegal/malformed utf-8"); + } else { + obj = ensure_valid_encoding(data, obj, false, false); + as_json_called = true; + goto start; + } + break; + case T_SYMBOL: + generate_json_symbol(buffer, data, obj); + break; + case T_FLOAT: + if (klass != rb_cFloat) goto general; + generate_json_float(buffer, data, obj); + break; + case T_STRUCT: + if (klass != cFragment) goto general; + generate_json_fragment(buffer, data, obj); + break; + default: + general: + if (data->state->strict) { + if (RTEST(data->state->as_json) && !as_json_called) { + obj = json_call_as_json(data->state, obj, Qfalse); + as_json_called = true; + goto start; + } else { + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj)); + } + } else { + generate_json_fallback(buffer, data, obj); + } + } } } -static FBuffer *cState_prepare_buffer(VALUE self) +static VALUE generate_json_try(VALUE d) { - FBuffer *buffer; - GET_STATE(self); - buffer = fbuffer_alloc(state->buffer_initial_length); + struct generate_json_data *data = (struct generate_json_data *)d; - if (state->object_delim) { - fbuffer_clear(state->object_delim); - } else { - state->object_delim = fbuffer_alloc(16); - } - fbuffer_append_char(state->object_delim, ','); - if (state->object_delim2) { - fbuffer_clear(state->object_delim2); - } else { - state->object_delim2 = fbuffer_alloc(16); - } - if (state->space_before) fbuffer_append(state->object_delim2, state->space_before, state->space_before_len); - fbuffer_append_char(state->object_delim2, ':'); - if (state->space) fbuffer_append(state->object_delim2, state->space, state->space_len); + data->func(data->buffer, data, data->obj); - if (state->array_delim) { - fbuffer_clear(state->array_delim); - } else { - state->array_delim = fbuffer_alloc(16); - } - fbuffer_append_char(state->array_delim, ','); - if (state->array_nl) fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len); - return buffer; + return fbuffer_finalize(data->buffer); } -static VALUE cState_partial_generate(VALUE self, VALUE obj) +static VALUE generate_json_ensure(VALUE d) { - FBuffer *buffer = cState_prepare_buffer(self); - GET_STATE(self); - generate_json(buffer, self, state, obj); - return fbuffer_to_s(buffer); + struct generate_json_data *data = (struct generate_json_data *)d; + fbuffer_free(data->buffer); + + return Qundef; } -/* - * call-seq: generate(obj) +static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io) +{ + GET_STATE(self); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { + .io = RTEST(io) ? io : Qfalse, + }; + fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = Qfalse, // don't use self as it may be frozen and its depth is mutated when calling to_json + .state = state, + .depth = state->depth, + .obj = obj, + .func = func + }; + return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data); +} + +/* call-seq: + * generate(obj) -> String + * generate(obj, anIO) -> anIO * * Generates a valid JSON document from object +obj+ and returns the * result. If no valid JSON document can be created this method raises a * GeneratorError exception. */ -static VALUE cState_generate(VALUE self, VALUE obj) +static VALUE cState_generate(int argc, VALUE *argv, VALUE self) { - VALUE result = cState_partial_generate(self, obj); - GET_STATE(self); - (void)state; - return result; + rb_check_arity(argc, 1, 2); + VALUE obj = argv[0]; + VALUE io = argc > 1 ? argv[1] : Qnil; + return cState_partial_generate(self, obj, generate_json, io); } -/* - * call-seq: new(opts = {}) - * - * Instantiates a new State object, configured by _opts_. - * - * _opts_ can have the following keys: - * - * * *indent*: a string used to indent levels (default: ''), - * * *space*: a string that is put after, a : or , delimiter (default: ''), - * * *space_before*: a string that is put before a : pair delimiter (default: ''), - * * *object_nl*: a string that is put at the end of a JSON object (default: ''), - * * *array_nl*: a string that is put at the end of a JSON array (default: ''), - * * *allow_nan*: true if NaN, Infinity, and -Infinity should be - * generated, otherwise an exception is thrown, if these values are - * encountered. This options defaults to false. - * * *ascii_only*: true if only ASCII characters should be generated. This - * option defaults to false. - * * *buffer_initial_length*: sets the initial length of the generator's - * internal buffer. - */ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) { - VALUE opts; - GET_STATE(self); - state->max_nesting = 100; - state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; - rb_scan_args(argc, argv, "01", &opts); - if (!NIL_P(opts)) cState_configure(self, opts); + rb_warn("The json gem extension was loaded with the stdlib ruby code. You should upgrade rubygems with `gem update --system`"); return self; } @@ -1140,14 +1581,12 @@ static VALUE cState_init_copy(VALUE obj, VALUE orig) if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); MEMCPY(objState, origState, JSON_Generator_State, 1); - objState->indent = fstrndup(origState->indent, origState->indent_len); - objState->space = fstrndup(origState->space, origState->space_len); - objState->space_before = fstrndup(origState->space_before, origState->space_before_len); - objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len); - objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len); - if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim); - if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim); - if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2); + objState->indent = origState->indent; + objState->space = origState->space; + objState->space_before = origState->space_before; + objState->object_nl = origState->object_nl; + objState->array_nl = origState->array_nl; + objState->as_json = origState->as_json; return obj; } @@ -1177,7 +1616,18 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts) static VALUE cState_indent(VALUE self) { GET_STATE(self); - return state->indent ? rb_str_new(state->indent, state->indent_len) : rb_str_new2(""); + return state->indent ? state->indent : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +static VALUE string_config(VALUE config) +{ + if (RTEST(config)) { + Check_Type(config, T_STRING); + if (RSTRING_LEN(config)) { + return rb_str_new_frozen(config); + } + } + return Qfalse; } /* @@ -1187,21 +1637,9 @@ static VALUE cState_indent(VALUE self) */ static VALUE cState_indent_set(VALUE self, VALUE indent) { - unsigned long len; + rb_check_frozen(self); GET_STATE(self); - Check_Type(indent, T_STRING); - len = RSTRING_LEN(indent); - if (len == 0) { - if (state->indent) { - ruby_xfree(state->indent); - state->indent = NULL; - state->indent_len = 0; - } - } else { - if (state->indent) ruby_xfree(state->indent); - state->indent = fstrndup(RSTRING_PTR(indent), len); - state->indent_len = len; - } + RB_OBJ_WRITE(self, &state->indent, string_config(indent)); return Qnil; } @@ -1214,7 +1652,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent) static VALUE cState_space(VALUE self) { GET_STATE(self); - return state->space ? rb_str_new(state->space, state->space_len) : rb_str_new2(""); + return state->space ? state->space : rb_str_freeze(rb_utf8_str_new("", 0)); } /* @@ -1225,21 +1663,9 @@ static VALUE cState_space(VALUE self) */ static VALUE cState_space_set(VALUE self, VALUE space) { - unsigned long len; + rb_check_frozen(self); GET_STATE(self); - Check_Type(space, T_STRING); - len = RSTRING_LEN(space); - if (len == 0) { - if (state->space) { - ruby_xfree(state->space); - state->space = NULL; - state->space_len = 0; - } - } else { - if (state->space) ruby_xfree(state->space); - state->space = fstrndup(RSTRING_PTR(space), len); - state->space_len = len; - } + RB_OBJ_WRITE(self, &state->space, string_config(space)); return Qnil; } @@ -1251,7 +1677,7 @@ static VALUE cState_space_set(VALUE self, VALUE space) static VALUE cState_space_before(VALUE self) { GET_STATE(self); - return state->space_before ? rb_str_new(state->space_before, state->space_before_len) : rb_str_new2(""); + return state->space_before ? state->space_before : rb_str_freeze(rb_utf8_str_new("", 0)); } /* @@ -1261,21 +1687,9 @@ static VALUE cState_space_before(VALUE self) */ static VALUE cState_space_before_set(VALUE self, VALUE space_before) { - unsigned long len; + rb_check_frozen(self); GET_STATE(self); - Check_Type(space_before, T_STRING); - len = RSTRING_LEN(space_before); - if (len == 0) { - if (state->space_before) { - ruby_xfree(state->space_before); - state->space_before = NULL; - state->space_before_len = 0; - } - } else { - if (state->space_before) ruby_xfree(state->space_before); - state->space_before = fstrndup(RSTRING_PTR(space_before), len); - state->space_before_len = len; - } + RB_OBJ_WRITE(self, &state->space_before, string_config(space_before)); return Qnil; } @@ -1288,7 +1702,7 @@ static VALUE cState_space_before_set(VALUE self, VALUE space_before) static VALUE cState_object_nl(VALUE self) { GET_STATE(self); - return state->object_nl ? rb_str_new(state->object_nl, state->object_nl_len) : rb_str_new2(""); + return state->object_nl ? state->object_nl : rb_str_freeze(rb_utf8_str_new("", 0)); } /* @@ -1299,20 +1713,9 @@ static VALUE cState_object_nl(VALUE self) */ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) { - unsigned long len; + rb_check_frozen(self); GET_STATE(self); - Check_Type(object_nl, T_STRING); - len = RSTRING_LEN(object_nl); - if (len == 0) { - if (state->object_nl) { - ruby_xfree(state->object_nl); - state->object_nl = NULL; - } - } else { - if (state->object_nl) ruby_xfree(state->object_nl); - state->object_nl = fstrndup(RSTRING_PTR(object_nl), len); - state->object_nl_len = len; - } + RB_OBJ_WRITE(self, &state->object_nl, string_config(object_nl)); return Qnil; } @@ -1324,7 +1727,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) static VALUE cState_array_nl(VALUE self) { GET_STATE(self); - return state->array_nl ? rb_str_new(state->array_nl, state->array_nl_len) : rb_str_new2(""); + return state->array_nl ? state->array_nl : rb_str_freeze(rb_utf8_str_new("", 0)); } /* @@ -1334,23 +1737,35 @@ static VALUE cState_array_nl(VALUE self) */ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl) { - unsigned long len; + rb_check_frozen(self); GET_STATE(self); - Check_Type(array_nl, T_STRING); - len = RSTRING_LEN(array_nl); - if (len == 0) { - if (state->array_nl) { - ruby_xfree(state->array_nl); - state->array_nl = NULL; - } - } else { - if (state->array_nl) ruby_xfree(state->array_nl); - state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); - state->array_nl_len = len; - } + RB_OBJ_WRITE(self, &state->array_nl, string_config(array_nl)); return Qnil; } +/* + * call-seq: as_json() + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json(VALUE self) +{ + GET_STATE(self); + return state->as_json; +} + +/* + * call-seq: as_json=(as_json) + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json_set(VALUE self, VALUE as_json) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->as_json, rb_convert_type(as_json, T_DATA, "Proc", "to_proc")); + return Qnil; +} /* * call-seq: check_circular? @@ -1376,6 +1791,11 @@ static VALUE cState_max_nesting(VALUE self) return LONG2FIX(state->max_nesting); } +static long long_config(VALUE num) +{ + return RTEST(num) ? FIX2LONG(num) : 0; +} + /* * call-seq: max_nesting=(depth) * @@ -1384,33 +1804,67 @@ static VALUE cState_max_nesting(VALUE self) */ static VALUE cState_max_nesting_set(VALUE self, VALUE depth) { + rb_check_frozen(self); GET_STATE(self); - Check_Type(depth, T_FIXNUM); - return state->max_nesting = FIX2LONG(depth); + state->max_nesting = long_config(depth); + return Qnil; } /* - * call-seq: escape_slash + * call-seq: script_safe * * If this boolean is true, the forward slashes will be escaped in * the json output. */ -static VALUE cState_escape_slash(VALUE self) +static VALUE cState_script_safe(VALUE self) { GET_STATE(self); - return state->escape_slash ? Qtrue : Qfalse; + return state->script_safe ? Qtrue : Qfalse; } /* - * call-seq: escape_slash=(depth) + * call-seq: script_safe=(enable) * * This sets whether or not the forward slashes will be escaped in * the json output. */ -static VALUE cState_escape_slash_set(VALUE self, VALUE enable) +static VALUE cState_script_safe_set(VALUE self, VALUE enable) { + rb_check_frozen(self); GET_STATE(self); - state->escape_slash = RTEST(enable); + state->script_safe = RTEST(enable); + return Qnil; +} + +/* + * call-seq: strict + * + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict(VALUE self) +{ + GET_STATE(self); + return state->strict ? Qtrue : Qfalse; +} + +/* + * call-seq: strict=(enable) + * + * This sets whether or not to serialize types unsupported by the + * JSON format as strings. + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->strict = RTEST(enable); return Qnil; } @@ -1427,6 +1881,19 @@ static VALUE cState_allow_nan_p(VALUE self) } /* + * call-seq: allow_nan=(enable) + * + * This sets whether or not to serialize NaN, Infinity, and -Infinity + */ +static VALUE cState_allow_nan_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->allow_nan = RTEST(enable); + return Qnil; +} + +/* * call-seq: ascii_only? * * Returns true, if only ASCII characters should be generated. Otherwise @@ -1439,6 +1906,32 @@ static VALUE cState_ascii_only_p(VALUE self) } /* + * call-seq: ascii_only=(enable) + * + * This sets whether only ASCII characters should be generated. + */ +static VALUE cState_ascii_only_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->ascii_only = RTEST(enable); + return Qnil; +} + +static VALUE cState_allow_duplicate_key_p(VALUE self) +{ + GET_STATE(self); + switch (state->on_duplicate_key) { + case JSON_IGNORE: + return Qtrue; + case JSON_DEPRECATED: + return Qnil; + default: + return Qfalse; + } +} + +/* * call-seq: depth * * This integer returns the current depth of data structure nesting. @@ -1457,9 +1950,9 @@ static VALUE cState_depth(VALUE self) */ static VALUE cState_depth_set(VALUE self, VALUE depth) { + rb_check_frozen(self); GET_STATE(self); - Check_Type(depth, T_FIXNUM); - state->depth = FIX2LONG(depth); + state->depth = long_config(depth); return Qnil; } @@ -1474,6 +1967,15 @@ static VALUE cState_buffer_initial_length(VALUE self) return LONG2FIX(state->buffer_initial_length); } +static void buffer_initial_length_set(JSON_Generator_State *state, VALUE buffer_initial_length) +{ + Check_Type(buffer_initial_length, T_FIXNUM); + long initial_length = FIX2LONG(buffer_initial_length); + if (initial_length > 0) { + state->buffer_initial_length = initial_length; + } +} + /* * call-seq: buffer_initial_length=(length) * @@ -1482,16 +1984,102 @@ static VALUE cState_buffer_initial_length(VALUE self) */ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length) { - long initial_length; + rb_check_frozen(self); GET_STATE(self); - Check_Type(buffer_initial_length, T_FIXNUM); - initial_length = FIX2LONG(buffer_initial_length); - if (initial_length > 0) { - state->buffer_initial_length = initial_length; - } + buffer_initial_length_set(state, buffer_initial_length); return Qnil; } +struct configure_state_data { + JSON_Generator_State *state; + VALUE vstate; // Ruby object that owns the state, or Qfalse if stack-allocated +}; + +static inline void state_write_value(struct configure_state_data *data, VALUE *field, VALUE value) +{ + if (RTEST(data->vstate)) { + RB_OBJ_WRITE(data->vstate, field, value); + } else { + *field = value; + } +} + +static int configure_state_i(VALUE key, VALUE val, VALUE _arg) +{ + struct configure_state_data *data = (struct configure_state_data *)_arg; + JSON_Generator_State *state = data->state; + + if (key == sym_indent) { state_write_value(data, &state->indent, string_config(val)); } + else if (key == sym_space) { state_write_value(data, &state->space, string_config(val)); } + else if (key == sym_space_before) { state_write_value(data, &state->space_before, string_config(val)); } + else if (key == sym_object_nl) { state_write_value(data, &state->object_nl, string_config(val)); } + else if (key == sym_array_nl) { state_write_value(data, &state->array_nl, string_config(val)); } + else if (key == sym_max_nesting) { state->max_nesting = long_config(val); } + else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); } + else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); } + else if (key == sym_depth) { state->depth = long_config(val); } + else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); } + else if (key == sym_script_safe) { state->script_safe = RTEST(val); } + else if (key == sym_escape_slash) { state->script_safe = RTEST(val); } + else if (key == sym_strict) { state->strict = RTEST(val); } + else if (key == sym_allow_duplicate_key) { state->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } + else if (key == sym_as_json) { + VALUE proc = RTEST(val) ? rb_convert_type(val, T_DATA, "Proc", "to_proc") : Qfalse; + state->as_json_single_arg = proc && rb_proc_arity(proc) == 1; + state_write_value(data, &state->as_json, proc); + } + return ST_CONTINUE; +} + +static void configure_state(JSON_Generator_State *state, VALUE vstate, VALUE config) +{ + if (!RTEST(config)) return; + + Check_Type(config, T_HASH); + + if (!RHASH_SIZE(config)) return; + + struct configure_state_data data = { + .state = state, + .vstate = vstate + }; + + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(config, configure_state_i, (VALUE)&data); +} + +static VALUE cState_configure(VALUE self, VALUE opts) +{ + rb_check_frozen(self); + GET_STATE(self); + configure_state(state, self, opts); + return self; +} + +static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io) +{ + JSON_Generator_State state = {0}; + state_init(&state); + configure_state(&state, Qfalse, opts); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { + .io = RTEST(io) ? io : Qfalse, + }; + fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = Qfalse, + .state = &state, + .depth = state.depth, + .obj = obj, + .func = generate_json, + }; + return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data); +} + /* * */ @@ -1505,18 +2093,26 @@ void Init_generator(void) rb_require("json/common"); mJSON = rb_define_module("JSON"); - mExt = rb_define_module_under(mJSON, "Ext"); - mGenerator = rb_define_module_under(mExt, "Generator"); + rb_global_variable(&cFragment); + cFragment = rb_const_get(mJSON, rb_intern("Fragment")); + + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE mGenerator = rb_define_module_under(mExt, "Generator"); + + rb_global_variable(&eGeneratorError); eGeneratorError = rb_path2class("JSON::GeneratorError"); + + rb_global_variable(&eNestingError); eNestingError = rb_path2class("JSON::NestingError"); - rb_gc_register_mark_object(eGeneratorError); - rb_gc_register_mark_object(eNestingError); cState = rb_define_class_under(mGenerator, "State", rb_cObject); rb_define_alloc_func(cState, cState_s_allocate); rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1); rb_define_method(cState, "initialize", cState_initialize, -1); + rb_define_alias(cState, "initialize", "initialize"); // avoid method redefinition warnings + rb_define_private_method(cState, "_configure", cState_configure, 1); + rb_define_method(cState, "initialize_copy", cState_init_copy, 1); rb_define_method(cState, "indent", cState_indent, 0); rb_define_method(cState, "indent=", cState_indent_set, 1); @@ -1528,81 +2124,99 @@ void Init_generator(void) rb_define_method(cState, "object_nl=", cState_object_nl_set, 1); rb_define_method(cState, "array_nl", cState_array_nl, 0); rb_define_method(cState, "array_nl=", cState_array_nl_set, 1); + rb_define_method(cState, "as_json", cState_as_json, 0); + rb_define_method(cState, "as_json=", cState_as_json_set, 1); rb_define_method(cState, "max_nesting", cState_max_nesting, 0); rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1); - rb_define_method(cState, "escape_slash", cState_escape_slash, 0); - rb_define_method(cState, "escape_slash?", cState_escape_slash, 0); - rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1); + rb_define_method(cState, "script_safe", cState_script_safe, 0); + rb_define_method(cState, "script_safe?", cState_script_safe, 0); + rb_define_method(cState, "script_safe=", cState_script_safe_set, 1); + rb_define_alias(cState, "escape_slash", "script_safe"); + rb_define_alias(cState, "escape_slash?", "script_safe?"); + rb_define_alias(cState, "escape_slash=", "script_safe="); + rb_define_method(cState, "strict", cState_strict, 0); + rb_define_method(cState, "strict?", cState_strict, 0); + rb_define_method(cState, "strict=", cState_strict_set, 1); rb_define_method(cState, "check_circular?", cState_check_circular_p, 0); rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0); + rb_define_method(cState, "allow_nan=", cState_allow_nan_set, 1); rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0); + rb_define_method(cState, "ascii_only=", cState_ascii_only_set, 1); rb_define_method(cState, "depth", cState_depth, 0); rb_define_method(cState, "depth=", cState_depth_set, 1); rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0); rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1); - rb_define_method(cState, "configure", cState_configure, 1); - rb_define_alias(cState, "merge", "configure"); - rb_define_method(cState, "to_h", cState_to_h, 0); - rb_define_alias(cState, "to_hash", "to_h"); - rb_define_method(cState, "[]", cState_aref, 1); - rb_define_method(cState, "[]=", cState_aset, 2); - rb_define_method(cState, "generate", cState_generate, 1); - - mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods"); - mObject = rb_define_module_under(mGeneratorMethods, "Object"); + rb_define_method(cState, "generate", cState_generate, -1); + + rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0); + + rb_define_singleton_method(cState, "generate", cState_m_generate, 3); + + VALUE mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods"); + + VALUE mObject = rb_define_module_under(mGeneratorMethods, "Object"); rb_define_method(mObject, "to_json", mObject_to_json, -1); - mHash = rb_define_module_under(mGeneratorMethods, "Hash"); + + VALUE mHash = rb_define_module_under(mGeneratorMethods, "Hash"); rb_define_method(mHash, "to_json", mHash_to_json, -1); - mArray = rb_define_module_under(mGeneratorMethods, "Array"); + + VALUE mArray = rb_define_module_under(mGeneratorMethods, "Array"); rb_define_method(mArray, "to_json", mArray_to_json, -1); + #ifdef RUBY_INTEGER_UNIFICATION - mInteger = rb_define_module_under(mGeneratorMethods, "Integer"); + VALUE mInteger = rb_define_module_under(mGeneratorMethods, "Integer"); rb_define_method(mInteger, "to_json", mInteger_to_json, -1); #else - mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum"); + VALUE mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum"); rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1); - mBignum = rb_define_module_under(mGeneratorMethods, "Bignum"); + + VALUE mBignum = rb_define_module_under(mGeneratorMethods, "Bignum"); rb_define_method(mBignum, "to_json", mBignum_to_json, -1); #endif - mFloat = rb_define_module_under(mGeneratorMethods, "Float"); + VALUE mFloat = rb_define_module_under(mGeneratorMethods, "Float"); rb_define_method(mFloat, "to_json", mFloat_to_json, -1); - mString = rb_define_module_under(mGeneratorMethods, "String"); - rb_define_singleton_method(mString, "included", mString_included_s, 1); + + VALUE mString = rb_define_module_under(mGeneratorMethods, "String"); rb_define_method(mString, "to_json", mString_to_json, -1); - rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1); - rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0); - mString_Extend = rb_define_module_under(mString, "Extend"); - rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1); - mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass"); + + VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass"); rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1); - mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass"); + + VALUE mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass"); rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1); - mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass"); + + VALUE mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass"); rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1); + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + i_to_s = rb_intern("to_s"); i_to_json = rb_intern("to_json"); i_new = rb_intern("new"); - i_indent = rb_intern("indent"); - i_space = rb_intern("space"); - i_space_before = rb_intern("space_before"); - i_object_nl = rb_intern("object_nl"); - i_array_nl = rb_intern("array_nl"); - i_max_nesting = rb_intern("max_nesting"); - i_escape_slash = rb_intern("escape_slash"); - i_allow_nan = rb_intern("allow_nan"); - i_ascii_only = rb_intern("ascii_only"); - i_depth = rb_intern("depth"); - i_buffer_initial_length = rb_intern("buffer_initial_length"); - i_pack = rb_intern("pack"); - i_unpack = rb_intern("unpack"); - i_create_id = rb_intern("create_id"); - i_extend = rb_intern("extend"); - i_key_p = rb_intern("key?"); - i_aref = rb_intern("[]"); - i_send = rb_intern("__send__"); - i_respond_to_p = rb_intern("respond_to?"); - i_match = rb_intern("match"); - i_keys = rb_intern("keys"); - i_dup = rb_intern("dup"); + i_encode = rb_intern("encode"); + + sym_indent = ID2SYM(rb_intern("indent")); + sym_space = ID2SYM(rb_intern("space")); + sym_space_before = ID2SYM(rb_intern("space_before")); + sym_object_nl = ID2SYM(rb_intern("object_nl")); + sym_array_nl = ID2SYM(rb_intern("array_nl")); + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_ascii_only = ID2SYM(rb_intern("ascii_only")); + sym_depth = ID2SYM(rb_intern("depth")); + sym_buffer_initial_length = ID2SYM(rb_intern("buffer_initial_length")); + sym_script_safe = ID2SYM(rb_intern("script_safe")); + sym_escape_slash = ID2SYM(rb_intern("escape_slash")); + sym_strict = ID2SYM(rb_intern("strict")); + sym_as_json = ID2SYM(rb_intern("as_json")); + sym_allow_duplicate_key = ID2SYM(rb_intern("allow_duplicate_key")); + + usascii_encindex = rb_usascii_encindex(); + utf8_encindex = rb_utf8_encindex(); + binary_encindex = rb_ascii8bit_encindex(); + + rb_require("json/ext/generator/state"); + + simd_impl = find_simd_implementation(); } diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h deleted file mode 100644 index 3ebd622554..0000000000 --- a/ext/json/generator/generator.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _GENERATOR_H_ -#define _GENERATOR_H_ - -#include <math.h> -#include <ctype.h> - -#include "ruby.h" - -#ifdef HAVE_RUBY_RE_H -#include "ruby/re.h" -#else -#include "re.h" -#endif - -#ifndef rb_intern_str -#define rb_intern_str(string) SYM2ID(rb_str_intern(string)) -#endif - -#ifndef rb_obj_instance_variables -#define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0) -#endif - -#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) - -/* unicode definitions */ - -#define UNI_STRICT_CONVERSION 1 - -typedef unsigned long UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ - -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length); -static void unicode_escape(char *buf, UTF16 character); -static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character); -static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash); -static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash); -static char *fstrndup(const char *ptr, unsigned long len); - -/* ruby api and some helpers */ - -typedef struct JSON_Generator_StateStruct { - char *indent; - long indent_len; - char *space; - long space_len; - char *space_before; - long space_before_len; - char *object_nl; - long object_nl_len; - char *array_nl; - long array_nl_len; - FBuffer *array_delim; - FBuffer *object_delim; - FBuffer *object_delim2; - long max_nesting; - char allow_nan; - char ascii_only; - char escape_slash; - long depth; - long buffer_initial_length; -} JSON_Generator_State; - -#define GET_STATE_TO(self, state) \ - TypedData_Get_Struct(self, JSON_Generator_State, &JSON_Generator_State_type, state) - -#define GET_STATE(self) \ - JSON_Generator_State *state; \ - GET_STATE_TO(self, state) - -#define GENERATE_JSON(type) \ - FBuffer *buffer; \ - VALUE Vstate; \ - JSON_Generator_State *state; \ - \ - rb_scan_args(argc, argv, "01", &Vstate); \ - Vstate = cState_from_state_s(cState, Vstate); \ - TypedData_Get_Struct(Vstate, JSON_Generator_State, &JSON_Generator_State_type, state); \ - buffer = cState_prepare_buffer(Vstate); \ - generate_json_##type(buffer, Vstate, state, self); \ - return fbuffer_to_s(buffer) - -static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self); -#ifdef RUBY_INTEGER_UNIFICATION -static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self); -#else -static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self); -#endif -static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mString_included_s(VALUE self, VALUE modul); -static VALUE mString_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mString_to_json_raw_object(VALUE self); -static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self); -static VALUE mString_Extend_json_create(VALUE self, VALUE o); -static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self); -static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self); -static void State_free(void *state); -static VALUE cState_s_allocate(VALUE klass); -static VALUE cState_configure(VALUE self, VALUE opts); -static VALUE cState_to_h(VALUE self); -static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -#ifdef RUBY_INTEGER_UNIFICATION -static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -#endif -static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj); -static VALUE cState_partial_generate(VALUE self, VALUE obj); -static VALUE cState_generate(VALUE self, VALUE obj); -static VALUE cState_initialize(int argc, VALUE *argv, VALUE self); -static VALUE cState_from_state_s(VALUE self, VALUE opts); -static VALUE cState_indent(VALUE self); -static VALUE cState_indent_set(VALUE self, VALUE indent); -static VALUE cState_space(VALUE self); -static VALUE cState_space_set(VALUE self, VALUE space); -static VALUE cState_space_before(VALUE self); -static VALUE cState_space_before_set(VALUE self, VALUE space_before); -static VALUE cState_object_nl(VALUE self); -static VALUE cState_object_nl_set(VALUE self, VALUE object_nl); -static VALUE cState_array_nl(VALUE self); -static VALUE cState_array_nl_set(VALUE self, VALUE array_nl); -static VALUE cState_max_nesting(VALUE self); -static VALUE cState_max_nesting_set(VALUE self, VALUE depth); -static VALUE cState_allow_nan_p(VALUE self); -static VALUE cState_ascii_only_p(VALUE self); -static VALUE cState_depth(VALUE self); -static VALUE cState_depth_set(VALUE self, VALUE depth); -static VALUE cState_escape_slash(VALUE self); -static VALUE cState_escape_slash_set(VALUE self, VALUE depth); -static FBuffer *cState_prepare_buffer(VALUE self); -#ifndef ZALLOC -#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type))) -static inline void *ruby_zalloc(size_t n) -{ - void *p = ruby_xmalloc(n); - memset(p, 0, n); - return p; -} -#endif -#ifdef TypedData_Make_Struct -static const rb_data_type_t JSON_Generator_State_type; -#define NEW_TYPEDDATA_WRAPPER 1 -#else -#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, State_free, json) -#define TypedData_Get_Struct(self, JSON_Generator_State, ignore, json) Data_Get_Struct(self, JSON_Generator_State, json) -#endif - -#endif diff --git a/ext/json/json.gemspec b/ext/json/json.gemspec index 948e92c501..5575731025 100644 --- a/ext/json/json.gemspec +++ b/ext/json/json.gemspec @@ -1,67 +1,62 @@ -# -*- encoding: utf-8 -*- +# frozen_string_literal: true + +version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line| + /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1 +end rescue nil + +spec = Gem::Specification.new do |s| + java_ext = Gem::Platform === s.platform && s.platform =~ 'java' || RUBY_ENGINE == 'jruby' -Gem::Specification.new do |s| s.name = "json" - s.version = File.read(File.expand_path('../VERSION', __FILE__)).chomp + s.version = version s.summary = "JSON Implementation for Ruby" - s.description = "This is a JSON implementation as a Ruby extension in C." + s.homepage = "https://github.com/ruby/json" + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/ruby/json/issues', + 'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md', + 'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html', + 'homepage_uri' => s.homepage, + 'source_code_uri' => 'https://github.com/ruby/json', + } + + s.required_ruby_version = Gem::Requirement.new(">= 2.7") + + if java_ext + s.description = "A JSON implementation as a JRuby extension." + s.author = "Daniel Luz" + s.email = "dev+ruby@mernen.com" + else + s.description = "This is a JSON implementation as a Ruby extension in C." + s.authors = ["Florian Frank"] + s.email = "flori@ping.de" + end + s.licenses = ["Ruby"] - s.authors = ["Florian Frank"] - s.email = "flori@ping.de" - s.extensions = ["ext/json/ext/generator/extconf.rb", "ext/json/ext/parser/extconf.rb", "ext/json/extconf.rb"] s.extra_rdoc_files = ["README.md"] s.rdoc_options = ["--title", "JSON implementation for Ruby", "--main", "README.md"] + s.files = [ "CHANGES.md", - "LICENSE", + "COPYING", + "BSDL", + "LEGAL", "README.md", - "VERSION", - "ext/json/ext/fbuffer/fbuffer.h", - "ext/json/ext/generator/depend", - "ext/json/ext/generator/extconf.rb", - "ext/json/ext/generator/generator.c", - "ext/json/ext/generator/generator.h", - "ext/json/ext/parser/depend", - "ext/json/ext/parser/extconf.rb", - "ext/json/ext/parser/parser.c", - "ext/json/ext/parser/parser.h", - "ext/json/ext/parser/parser.rl", - "ext/json/extconf.rb", "json.gemspec", - "lib/json.rb", - "lib/json/add/bigdecimal.rb", - "lib/json/add/complex.rb", - "lib/json/add/core.rb", - "lib/json/add/date.rb", - "lib/json/add/date_time.rb", - "lib/json/add/exception.rb", - "lib/json/add/ostruct.rb", - "lib/json/add/range.rb", - "lib/json/add/rational.rb", - "lib/json/add/regexp.rb", - "lib/json/add/set.rb", - "lib/json/add/struct.rb", - "lib/json/add/symbol.rb", - "lib/json/add/time.rb", - "lib/json/common.rb", - "lib/json/ext.rb", - "lib/json/generic_object.rb", - "lib/json/pure.rb", - "lib/json/pure/generator.rb", - "lib/json/pure/parser.rb", - "lib/json/version.rb", - ] - s.homepage = "http://flori.github.com/json" - s.metadata = { - 'bug_tracker_uri' => 'https://github.com/flori/json/issues', - 'changelog_uri' => 'https://github.com/flori/json/blob/master/CHANGES.md', - 'documentation_uri' => 'http://flori.github.io/json/doc/index.html', - 'homepage_uri' => 'http://flori.github.io/json/', - 'source_code_uri' => 'https://github.com/flori/json', - 'wiki_uri' => 'https://github.com/flori/json/wiki' - } + ] + Dir.glob("lib/**/*.rb", base: File.expand_path("..", __FILE__)) + + if java_ext + s.platform = 'java' + s.files += Dir["lib/json/ext/**/*.jar"] + else + s.extensions = Dir["ext/json/**/extconf.rb"] + s.files += Dir["ext/json/**/*.{c,h,rb}"] + end +end - s.required_ruby_version = Gem::Requirement.new(">= 2.3") +if RUBY_ENGINE == 'jruby' && $0 == __FILE__ + Gem::Builder.new(spec).build +else + spec end diff --git a/ext/json/json.h b/ext/json/json.h new file mode 100644 index 0000000000..9379d7ae7f --- /dev/null +++ b/ext/json/json.h @@ -0,0 +1,101 @@ +#ifndef _JSON_H_ +#define _JSON_H_ + +#include "ruby.h" +#include "ruby/encoding.h" +#include <stdint.h> + +#ifndef RBIMPL_ASSERT_OR_ASSUME +# define RBIMPL_ASSERT_OR_ASSUME(x) +#endif + +#if defined(RUBY_DEBUG) && RUBY_DEBUG +# define JSON_ASSERT RUBY_ASSERT +#else +# ifdef JSON_DEBUG +# include <assert.h> +# define JSON_ASSERT(x) assert(x) +# else +# define JSON_ASSERT(x) +# endif +#endif + +/* shims */ + +#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG +# define INT64T2NUM(x) LL2NUM(x) +# define UINT64T2NUM(x) ULL2NUM(x) +#elif SIZEOF_UINT64_T == SIZEOF_LONG +# define INT64T2NUM(x) LONG2NUM(x) +# define UINT64T2NUM(x) ULONG2NUM(x) +#else +# error No uint64_t conversion +#endif + +/* This is the fallback definition from Ruby 3.4 */ +#ifndef RBIMPL_STDBOOL_H +#if defined(__cplusplus) +# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L) +# include <cstdbool> +# endif +#elif defined(HAVE_STDBOOL_H) +# include <stdbool.h> +#elif !defined(HAVE__BOOL) +typedef unsigned char _Bool; +# define bool _Bool +# define true ((_Bool)+1) +# define false ((_Bool)+0) +# define __bool_true_false_are_defined +#endif +#endif + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +#ifndef NORETURN +#define NORETURN(x) x +#endif + +#ifndef NOINLINE +#if defined(__has_attribute) && __has_attribute(noinline) +#define NOINLINE(x) __attribute__((noinline)) x +#else +#define NOINLINE(x) x +#endif +#endif + +#ifndef ALWAYS_INLINE +#if defined(__has_attribute) && __has_attribute(always_inline) +#define ALWAYS_INLINE(x) inline __attribute__((always_inline)) x +#else +#define ALWAYS_INLINE(x) inline x +#endif +#endif + +#ifndef RB_UNLIKELY +#define RB_UNLIKELY(expr) expr +#endif + +#ifndef RB_LIKELY +#define RB_LIKELY(expr) expr +#endif + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#ifdef RUBY_DEBUG +#ifndef JSON_DEBUG +#define JSON_DEBUG RUBY_DEBUG +#endif +#endif + +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && INTPTR_MAX == INT64_MAX +#define JSON_CPU_LITTLE_ENDIAN_64BITS 1 +#else +#define JSON_CPU_LITTLE_ENDIAN_64BITS 0 +#endif + +#endif // _JSON_H_ diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb index 1e64bfcb1a..2f6db44227 100644 --- a/ext/json/lib/json.rb +++ b/ext/json/lib/json.rb @@ -1,4 +1,4 @@ -#frozen_string_literal: false +# frozen_string_literal: true require 'json/common' ## @@ -6,6 +6,15 @@ require 'json/common' # # \JSON is a lightweight data-interchange format. # +# \JSON is easy for us humans to read and write, +# and equally simple for machines to read (parse) and write (generate). +# +# \JSON is language-independent, making it an ideal interchange format +# for applications in differing programming languages +# and on differing operating systems. +# +# == \JSON Values +# # A \JSON value is one of the following: # - Double-quoted text: <tt>"foo"</tt>. # - Number: +1+, +1.0+, +2.0e2+. @@ -127,6 +136,24 @@ require 'json/common' # # --- # +# Option +allow_duplicate_key+ specifies whether duplicate keys in objects +# should be ignored or cause an error to be raised: +# +# When not specified: +# # The last value is used and a deprecation warning emitted. +# JSON.parse('{"a": 1, "a":2}') => {"a" => 2} +# # warning: detected duplicate keys in JSON object. +# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true` +# +# When set to `+true+` +# # The last value is used. +# JSON.parse('{"a": 1, "a":2}') => {"a" => 2} +# +# When set to `+false+`, the future default: +# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError) +# +# --- +# # Option +allow_nan+ (boolean) specifies whether to allow # NaN, Infinity, and MinusInfinity in +source+; # defaults to +false+. @@ -143,8 +170,35 @@ require 'json/common' # ruby = JSON.parse(source, {allow_nan: true}) # ruby # => [NaN, Infinity, -Infinity] # +# --- +# +# Option +allow_trailing_comma+ (boolean) specifies whether to allow +# trailing commas in objects and arrays; +# defaults to +false+. +# +# With the default, +false+: +# JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError) +# +# When enabled: +# JSON.parse('[1,]', allow_trailing_comma: true) # => [1] +# +# --- +# +# Option +allow_control_characters+ (boolean) specifies whether to allow +# unescaped ASCII control characters, such as newlines, in strings; +# defaults to +false+. +# +# With the default, +false+: +# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError) +# +# When enabled: +# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld" +# # ====== Output Options # +# Option +freeze+ (boolean) specifies whether the returned objects will be frozen; +# defaults to +false+. +# # Option +symbolize_names+ (boolean) specifies whether returned \Hash keys # should be Symbols; # defaults to +false+ (use Strings). @@ -274,6 +328,25 @@ require 'json/common' # # --- # +# Option +allow_duplicate_key+ (boolean) specifies whether +# hashes with duplicate keys should be allowed or produce an error. +# defaults to emit a deprecation warning. +# +# With the default, (not set): +# Warning[:deprecated] = true +# JSON.generate({ foo: 1, "foo" => 2 }) +# # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}. +# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true` +# # => '{"foo":1,"foo":2}' +# +# With <tt>false</tt> +# JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false) +# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError) +# +# In version 3.0, <tt>false</tt> will become the default. +# +# --- +# # Option +max_nesting+ (\Integer) specifies the maximum nesting depth # in +obj+; defaults to +100+. # @@ -285,6 +358,15 @@ require 'json/common' # # Raises JSON::NestingError (nesting of 2 is too deep): # JSON.generate(obj, max_nesting: 2) # +# ====== Escaping Options +# +# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt> +# and <tt>'/'</tt> should be escaped as to make the JSON object safe to interpolate in script +# tags. +# +# Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range +# should be escaped. +# # ====== Output Options # # The default formatting options generate the most compact @@ -342,6 +424,9 @@ require 'json/common' # # == \JSON Additions # +# Note that JSON Additions must only be used with trusted data, and is +# deprecated. +# # When you "round trip" a non-\String object from Ruby to \JSON and back, # you have a new \String, instead of the object you began with: # ruby0 = Range.new(0, 2) @@ -369,13 +454,13 @@ require 'json/common' # json1 = JSON.generate(ruby) # ruby1 = JSON.parse(json1, create_additions: true) # # Make a nice display. -# display = <<EOT -# Generated JSON: -# Without addition: #{json0} (#{json0.class}) -# With addition: #{json1} (#{json1.class}) -# Parsed JSON: -# Without addition: #{ruby0.inspect} (#{ruby0.class}) -# With addition: #{ruby1.inspect} (#{ruby1.class}) +# display = <<~EOT +# Generated JSON: +# Without addition: #{json0} (#{json0.class}) +# With addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without addition: #{ruby0.inspect} (#{ruby0.class}) +# With addition: #{ruby1.inspect} (#{ruby1.class}) # EOT # puts display # @@ -553,13 +638,13 @@ require 'json/common' # json1 = JSON.generate(foo1) # obj1 = JSON.parse(json1, create_additions: true) # # Make a nice display. -# display = <<EOT -# Generated JSON: -# Without custom addition: #{json0} (#{json0.class}) -# With custom addition: #{json1} (#{json1.class}) -# Parsed JSON: -# Without custom addition: #{obj0.inspect} (#{obj0.class}) -# With custom addition: #{obj1.inspect} (#{obj1.class}) +# display = <<~EOT +# Generated JSON: +# Without custom addition: #{json0} (#{json0.class}) +# With custom addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without custom addition: #{obj0.inspect} (#{obj0.class}) +# With custom addition: #{obj1.inspect} (#{obj1.class}) # EOT # puts display # @@ -574,10 +659,5 @@ require 'json/common' # module JSON require 'json/version' - - begin - require 'json/ext' - rescue LoadError - require 'json/pure' - end + require 'json/ext' end diff --git a/ext/json/lib/json/add/bigdecimal.rb b/ext/json/lib/json/add/bigdecimal.rb index c8b4f567cb..dc84572f31 100644 --- a/ext/json/lib/json/add/bigdecimal.rb +++ b/ext/json/lib/json/add/bigdecimal.rb @@ -1,29 +1,58 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end -defined?(::BigDecimal) or require 'bigdecimal' +begin + require 'bigdecimal' +rescue LoadError +end class BigDecimal - # Import a JSON Marshalled object. - # - # method used for JSON marshalling support. + + # See #as_json. def self.json_create(object) BigDecimal._load object['b'] end - # Marshal the object to JSON. + # Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be used + # to serialize and deserialize a \BigDecimal object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>BigDecimal#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/bigdecimal' + # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"} + # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object: + # + # BigDecimal.json_create(x) # => 0.2e1 + # BigDecimal.json_create(y) # => 0.2e1 + # BigDecimal.json_create(z) # => 0.2e1 # - # method used for JSON marshalling support. def as_json(*) { JSON.create_id => self.class.name, - 'b' => _dump, + 'b' => _dump.force_encoding(Encoding::UTF_8), } end - # return the JSON value + # Returns a JSON string representing +self+: + # + # require 'json/add/bigdecimal' + # puts BigDecimal(2).to_json + # puts BigDecimal(2.0, 4).to_json + # puts BigDecimal(Complex(2, 0)).to_json + # + # Output: + # + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # {"json_class":"BigDecimal","b":"36:0.2e1"} + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # def to_json(*args) as_json.to_json(*args) end -end +end if defined?(::BigDecimal) diff --git a/ext/json/lib/json/add/complex.rb b/ext/json/lib/json/add/complex.rb index e63e29fd22..9e3c6f2d0a 100644 --- a/ext/json/lib/json/add/complex.rb +++ b/ext/json/lib/json/add/complex.rb @@ -1,18 +1,31 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Complex - # Deserializes JSON string by converting Real value <tt>r</tt>, imaginary - # value <tt>i</tt>, to a Complex object. + # See #as_json. def self.json_create(object) Complex(object['r'], object['i']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used + # to serialize and deserialize a \Complex object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Complex#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/complex' + # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0} + # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Complex object: + # + # Complex.json_create(x) # => (2+0i) + # Complex.json_create(y) # => (2.0+4i) + # def as_json(*) { JSON.create_id => self.class.name, @@ -21,7 +34,17 @@ class Complex } end - # Stores class name (Complex) along with real value <tt>r</tt> and imaginary value <tt>i</tt> as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/complex' + # puts Complex(2).to_json + # puts Complex(2.0, 4).to_json + # + # Output: + # + # {"json_class":"Complex","r":2,"i":0} + # {"json_class":"Complex","r":2.0,"i":4} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/core.rb b/ext/json/lib/json/add/core.rb index bfb017c460..61ff454212 100644 --- a/ext/json/lib/json/add/core.rb +++ b/ext/json/lib/json/add/core.rb @@ -1,4 +1,4 @@ -#frozen_string_literal: false +# frozen_string_literal: true # This file requires the implementations of ruby core's custom objects for # serialisation/deserialisation. @@ -7,6 +7,7 @@ require 'json/add/date_time' require 'json/add/exception' require 'json/add/range' require 'json/add/regexp' +require 'json/add/string' require 'json/add/struct' require 'json/add/symbol' require 'json/add/time' diff --git a/ext/json/lib/json/add/date.rb b/ext/json/lib/json/add/date.rb index 25523561a5..88a098b637 100644 --- a/ext/json/lib/json/add/date.rb +++ b/ext/json/lib/json/add/date.rb @@ -1,4 +1,4 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end @@ -6,16 +6,29 @@ require 'date' class Date - # Deserializes JSON string by converting Julian year <tt>y</tt>, month - # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date. + # See #as_json. def self.json_create(object) civil(*object.values_at('y', 'm', 'd', 'sg')) end alias start sg unless method_defined?(:start) - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Date#as_json</tt> and +Date.json_create+ may be used + # to serialize and deserialize a \Date object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Date#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/date' + # x = Date.today.as_json + # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Date object: + # + # Date.json_create(x) + # # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)> + # def as_json(*) { JSON.create_id => self.class.name, @@ -26,8 +39,15 @@ class Date } end - # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day - # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/date' + # puts Date.today.to_json + # + # Output: + # + # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/date_time.rb b/ext/json/lib/json/add/date_time.rb index 38b0e86ab8..8b0bb5d181 100644 --- a/ext/json/lib/json/add/date_time.rb +++ b/ext/json/lib/json/add/date_time.rb @@ -1,4 +1,4 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end @@ -6,9 +6,7 @@ require 'date' class DateTime - # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>, - # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>, - # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime. + # See #as_json. def self.json_create(object) args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') of_a, of_b = object['of'].split('/') @@ -23,8 +21,21 @@ class DateTime alias start sg unless method_defined?(:start) - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>DateTime#as_json</tt> and +DateTime.json_create+ may be used + # to serialize and deserialize a \DateTime object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>DateTime#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/datetime' + # x = DateTime.now.as_json + # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object: + # + # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date" + # def as_json(*) { JSON.create_id => self.class.name, @@ -39,9 +50,15 @@ class DateTime } end - # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>, - # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>, - # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/datetime' + # puts DateTime.now.to_json + # + # Output: + # + # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/exception.rb b/ext/json/lib/json/add/exception.rb index a107e5b3c4..e85d404982 100644 --- a/ext/json/lib/json/add/exception.rb +++ b/ext/json/lib/json/add/exception.rb @@ -1,20 +1,31 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Exception - # Deserializes JSON string by constructing new Exception object with message - # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt> + # See #as_json. def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Exception#as_json</tt> and +Exception.json_create+ may be used + # to serialize and deserialize a \Exception object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Exception#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/exception' + # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Exception object: + # + # Exception.json_create(x) # => #<Exception: Foo> + # def as_json(*) { JSON.create_id => self.class.name, @@ -23,8 +34,15 @@ class Exception } end - # Stores class name (Exception) with message <tt>m</tt> and backtrace array - # <tt>b</tt> as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/exception' + # puts Exception.new('Foo').to_json + # + # Output: + # + # {"json_class":"Exception","m":"Foo","b":null} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/ostruct.rb b/ext/json/lib/json/add/ostruct.rb index 686cf0025d..7750498144 100644 --- a/ext/json/lib/json/add/ostruct.rb +++ b/ext/json/lib/json/add/ostruct.rb @@ -1,19 +1,35 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end -require 'ostruct' +begin + require 'ostruct' +rescue LoadError +end class OpenStruct - # Deserializes JSON string by constructing new Struct object with values - # <tt>t</tt> serialized by <tt>to_json</tt>. + # See #as_json. def self.json_create(object) new(object['t'] || object[:t]) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>OpenStruct#as_json</tt> and +OpenStruct.json_create+ may be used + # to serialize and deserialize a \OpenStruct object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>OpenStruct#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/ostruct' + # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json + # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}} + # + # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object: + # + # OpenStruct.json_create(x) + # # => #<OpenStruct name='Rowdy', age=nil> + # def as_json(*) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" @@ -23,9 +39,16 @@ class OpenStruct } end - # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a - # JSON string. + # Returns a JSON string representing +self+: + # + # require 'json/add/ostruct' + # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json + # + # Output: + # + # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}} + # def to_json(*args) as_json.to_json(*args) end -end +end if defined?(::OpenStruct) diff --git a/ext/json/lib/json/add/range.rb b/ext/json/lib/json/add/range.rb index 93529fb1c4..408d2c32f6 100644 --- a/ext/json/lib/json/add/range.rb +++ b/ext/json/lib/json/add/range.rb @@ -1,18 +1,33 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Range - # Deserializes JSON string by constructing new Range object with arguments - # <tt>a</tt> serialized by <tt>to_json</tt>. + # See #as_json. def self.json_create(object) new(*object['a']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Range#as_json</tt> and +Range.json_create+ may be used + # to serialize and deserialize a \Range object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Range#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/range' + # x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} + # y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} + # z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Range object: + # + # Range.json_create(x) # => 1..4 + # Range.json_create(y) # => 1...4 + # Range.json_create(z) # => "a".."d" + # def as_json(*) { JSON.create_id => self.class.name, @@ -20,9 +35,19 @@ class Range } end - # Stores class name (Range) with JSON array of arguments <tt>a</tt> which - # include <tt>first</tt> (integer), <tt>last</tt> (integer), and - # <tt>exclude_end?</tt> (boolean) as JSON string. + # Returns a JSON string representing +self+: + # + # require 'json/add/range' + # puts (1..4).to_json + # puts (1...4).to_json + # puts ('a'..'d').to_json + # + # Output: + # + # {"json_class":"Range","a":[1,4,false]} + # {"json_class":"Range","a":[1,4,true]} + # {"json_class":"Range","a":["a","d",false]} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/rational.rb b/ext/json/lib/json/add/rational.rb index f776226046..c95812ea8e 100644 --- a/ext/json/lib/json/add/rational.rb +++ b/ext/json/lib/json/add/rational.rb @@ -1,17 +1,31 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Rational - # Deserializes JSON string by converting numerator value <tt>n</tt>, - # denominator value <tt>d</tt>, to a Rational object. + + # See #as_json. def self.json_create(object) Rational(object['n'], object['d']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Rational#as_json</tt> and +Rational.json_create+ may be used + # to serialize and deserialize a \Rational object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Rational#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/rational' + # x = Rational(2, 3).as_json + # # => {"json_class"=>"Rational", "n"=>2, "d"=>3} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Rational object: + # + # Rational.json_create(x) + # # => (2/3) + # def as_json(*) { JSON.create_id => self.class.name, @@ -20,7 +34,15 @@ class Rational } end - # Stores class name (Rational) along with numerator value <tt>n</tt> and denominator value <tt>d</tt> as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/rational' + # puts Rational(2, 3).to_json + # + # Output: + # + # {"json_class":"Rational","n":2,"d":3} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/regexp.rb b/ext/json/lib/json/add/regexp.rb index 39d69fede7..aebfb2db5c 100644 --- a/ext/json/lib/json/add/regexp.rb +++ b/ext/json/lib/json/add/regexp.rb @@ -1,19 +1,30 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Regexp - # Deserializes JSON string by constructing new Regexp object with source - # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by - # <tt>to_json</tt> + # See #as_json. def self.json_create(object) new(object['s'], object['o']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Regexp#as_json</tt> and +Regexp.json_create+ may be used + # to serialize and deserialize a \Regexp object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Regexp#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/regexp' + # x = /foo/.as_json + # # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object: + # + # Regexp.json_create(x) # => /foo/ + # def as_json(*) { JSON.create_id => self.class.name, @@ -22,8 +33,15 @@ class Regexp } end - # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt> - # (Regexp or String) as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/regexp' + # puts /foo/.to_json + # + # Output: + # + # {"json_class":"Regexp","o":0,"s":"foo"} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/set.rb b/ext/json/lib/json/add/set.rb index 71e2a0ac8b..1918353187 100644 --- a/ext/json/lib/json/add/set.rb +++ b/ext/json/lib/json/add/set.rb @@ -4,16 +4,27 @@ end defined?(::Set) or require 'set' class Set - # Import a JSON Marshalled object. - # - # method used for JSON marshalling support. + + # See #as_json. def self.json_create(object) new object['a'] end - # Marshal the object to JSON. + # Methods <tt>Set#as_json</tt> and +Set.json_create+ may be used + # to serialize and deserialize a \Set object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Set#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/set' + # x = Set.new(%w/foo bar baz/).as_json + # # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Set object: + # + # Set.json_create(x) # => #<Set: {"foo", "bar", "baz"}> # - # method used for JSON marshalling support. def as_json(*) { JSON.create_id => self.class.name, @@ -21,7 +32,15 @@ class Set } end - # return the JSON value + # Returns a JSON string representing +self+: + # + # require 'json/add/set' + # puts Set.new(%w/foo bar baz/).to_json + # + # Output: + # + # {"json_class":"Set","a":["foo","bar","baz"]} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/string.rb b/ext/json/lib/json/add/string.rb new file mode 100644 index 0000000000..9c3bde27fb --- /dev/null +++ b/ext/json/lib/json/add/string.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class String + # call-seq: json_create(o) + # + # Raw Strings are JSON Objects (the raw bytes are stored in an array for the + # key "raw"). The Ruby String can be created by this class method. + def self.json_create(object) + object["raw"].pack("C*") + end + + # call-seq: to_json_raw_object() + # + # This method creates a raw object hash, that can be nested into + # other data structures and will be generated as a raw string. This + # method should be used, if you want to convert raw strings to JSON + # instead of UTF-8 strings, e. g. binary data. + def to_json_raw_object + { + JSON.create_id => self.class.name, + "raw" => unpack("C*"), + } + end + + # call-seq: to_json_raw(*args) + # + # This method creates a JSON text from the result of a call to + # to_json_raw_object of this String. + def to_json_raw(...) + to_json_raw_object.to_json(...) + end +end diff --git a/ext/json/lib/json/add/struct.rb b/ext/json/lib/json/add/struct.rb index e8395ed42f..6760c3d86c 100644 --- a/ext/json/lib/json/add/struct.rb +++ b/ext/json/lib/json/add/struct.rb @@ -1,18 +1,32 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Struct - # Deserializes JSON string by constructing new Struct object with values - # <tt>v</tt> serialized by <tt>to_json</tt>. + # See #as_json. def self.json_create(object) new(*object['v']) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Struct#as_json</tt> and +Struct.json_create+ may be used + # to serialize and deserialize a \Struct object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Struct#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # x = Struct::Customer.new.as_json + # # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Struct object: + # + # Struct::Customer.json_create(x) + # # => #<struct Struct::Customer name=nil, address=nil, zip=nil> + # def as_json(*) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" @@ -22,8 +36,16 @@ class Struct } end - # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string. - # Only named structs are supported. + # Returns a JSON string representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # puts Struct::Customer.new.to_json + # + # Output: + # + # {"json_class":"Struct","t":{'name':'Rowdy',"age":null}} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/add/symbol.rb b/ext/json/lib/json/add/symbol.rb index 74b13a423f..806be4f025 100644 --- a/ext/json/lib/json/add/symbol.rb +++ b/ext/json/lib/json/add/symbol.rb @@ -1,11 +1,25 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Symbol - # Returns a hash, that will be turned into a JSON object and represent this - # object. + + # Methods <tt>Symbol#as_json</tt> and +Symbol.json_create+ may be used + # to serialize and deserialize a \Symbol object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Symbol#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/symbol' + # x = :foo.as_json + # # => {"json_class"=>"Symbol", "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object: + # + # Symbol.json_create(x) # => :foo + # def as_json(*) { JSON.create_id => self.class.name, @@ -13,12 +27,25 @@ class Symbol } end - # Stores class name (Symbol) with String representation of Symbol as a JSON string. - def to_json(*a) - as_json.to_json(*a) + # Returns a JSON string representing +self+: + # + # require 'json/add/symbol' + # puts :foo.to_json + # + # Output: + # + # # {"json_class":"Symbol","s":"foo"} + # + def to_json(state = nil, *a) + state = ::JSON::State.from_state(state) + if state.strict? + super + else + as_json.to_json(state, *a) + end end - # Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol + # See #as_json. def self.json_create(o) o['s'].to_sym end diff --git a/ext/json/lib/json/add/time.rb b/ext/json/lib/json/add/time.rb index b73acc4086..b03d4ff251 100644 --- a/ext/json/lib/json/add/time.rb +++ b/ext/json/lib/json/add/time.rb @@ -1,37 +1,51 @@ -#frozen_string_literal: false +# frozen_string_literal: true unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end class Time - # Deserializes JSON string by converting time since epoch to Time + # See #as_json. def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 end - if method_defined?(:tv_nsec) - at(object['s'], Rational(object['n'], 1000)) - else - at(object['s'], object['n'] / 1000) - end + at(object['s'], Rational(object['n'], 1000)) end - # Returns a hash, that will be turned into a JSON object and represent this - # object. + # Methods <tt>Time#as_json</tt> and +Time.json_create+ may be used + # to serialize and deserialize a \Time object; + # see Marshal[rdoc-ref:Marshal]. + # + # \Method <tt>Time#as_json</tt> serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/time' + # x = Time.now.as_json + # # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Time object: + # + # Time.json_create(x) + # # => 2023-11-25 11:00:56.472846644 -0600 + # def as_json(*) - nanoseconds = [ tv_usec * 1000 ] - respond_to?(:tv_nsec) and nanoseconds << tv_nsec - nanoseconds = nanoseconds.max { JSON.create_id => self.class.name, 's' => tv_sec, - 'n' => nanoseconds, + 'n' => tv_nsec, } end - # Stores class name (Time) with number of seconds since epoch and number of - # microseconds for Time as JSON string + # Returns a JSON string representing +self+: + # + # require 'json/add/time' + # puts Time.now.to_json + # + # Output: + # + # {"json_class":"Time","s":1700931678,"n":980650786} + # def to_json(*args) as_json.to_json(*args) end diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index ea46896fcc..877b96814e 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -1,9 +1,123 @@ -#frozen_string_literal: false +# frozen_string_literal: true + require 'json/version' -require 'json/generic_object' module JSON + autoload :GenericObject, 'json/generic_object' + + module ParserOptions # :nodoc: + class << self + def prepare(opts) + if opts[:object_class] || opts[:array_class] + opts = opts.dup + on_load = opts[:on_load] + + on_load = object_class_proc(opts[:object_class], on_load) if opts[:object_class] + on_load = array_class_proc(opts[:array_class], on_load) if opts[:array_class] + opts[:on_load] = on_load + end + + if opts.fetch(:create_additions, false) != false + opts = create_additions_proc(opts) + end + + opts + end + + private + + def object_class_proc(object_class, on_load) + ->(obj) do + if Hash === obj + object = object_class.new + obj.each { |k, v| object[k] = v } + obj = object + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + def array_class_proc(array_class, on_load) + ->(obj) do + if Array === obj + array = array_class.new + obj.each { |v| array << v } + obj = array + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + # TODO: extract :create_additions support to another gem for version 3.0 + def create_additions_proc(opts) + if opts[:symbolize_names] + raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction" + end + + opts = opts.dup + create_additions = opts.fetch(:create_additions, false) + on_load = opts[:on_load] + object_class = opts[:object_class] || Hash + + opts[:on_load] = ->(object) do + case object + when String + opts[:match_string]&.each do |pattern, klass| + if match = pattern.match(object) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + break + end + end + when object_class + if opts[:create_additions] != false + if class_path = object[JSON.create_id] + klass = begin + Object.const_get(class_path) + rescue NameError => e + raise ArgumentError, "can't get const #{class_path}: #{e}" + end + + if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + end + end + end + end + + on_load.nil? ? object : on_load.call(object) + end + + opts + end + + def create_additions_warning + JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \ + "and will be removed in 3.0, use JSON.unsafe_load or explicitly " \ + "pass `create_additions: true`" + end + end + end + class << self + def deprecation_warning(message, uplevel = 3) # :nodoc: + gem_root = File.expand_path("..", __dir__) + "/" + caller_locations(uplevel, 10).each do |frame| + if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c") + uplevel += 1 + else + break + end + end + + if RUBY_VERSION >= "3.0" + warn(message, uplevel: uplevel, category: :deprecated) + else + warn(message, uplevel: uplevel) + end + end + # :call-seq: # JSON[object] -> new_array or new_string # @@ -15,17 +129,20 @@ module JSON # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate): # ruby = [0, 1, nil] # JSON[ruby] # => '[0,1,null]' - def [](object, opts = {}) - if object.respond_to? :to_str - JSON.parse(object.to_str, opts) - else - JSON.generate(object, opts) + def [](object, opts = nil) + if object.is_a?(String) + return JSON.parse(object, opts) + elsif object.respond_to?(:to_str) + str = object.to_str + if str.is_a?(String) + return JSON.parse(str, opts) + end end + + JSON.generate(object, opts) end - # Returns the JSON parser class that is used by JSON. This is either - # JSON::Ext::Parser or JSON::Pure::Parser: - # JSON.parser # => JSON::Ext::Parser + # Returns the JSON parser class that is used by JSON. attr_reader :parser # Set the JSON parser class _parser_ to be used by JSON. @@ -35,32 +152,13 @@ module JSON const_set :Parser, parser end - # Return the constant located at _path_. The format of _path_ has to be - # either ::A::B::C or A::B::C. In any case, A has to be located at the top - # level (absolute namespace path?). If there doesn't exist a constant at - # the given path, an ArgumentError is raised. - def deep_const_get(path) # :nodoc: - path.to_s.split(/::/).inject(Object) do |p, c| - case - when c.empty? then p - when p.const_defined?(c, true) then p.const_get(c) - else - begin - p.const_missing(c) - rescue NameError => e - raise ArgumentError, "can't get const #{path}: #{e}" - end - end - end - end - # Set the module _generator_ to be used by JSON. def generator=(generator) # :nodoc: old, $VERBOSE = $VERBOSE, nil @generator = generator generator_methods = generator::GeneratorMethods for const in generator_methods.constants - klass = deep_const_get(const) + klass = const_get(const) modul = generator_methods.const_get(const) klass.class_eval do instance_methods(false).each do |m| @@ -70,97 +168,135 @@ module JSON end end self.state = generator::State - const_set :State, self.state - const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby - const_set :FAST_STATE_PROTOTYPE, create_fast_state - const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state + const_set :State, state ensure $VERBOSE = old end - def create_fast_state - State.new( - :indent => '', - :space => '', - :object_nl => "", - :array_nl => "", - :max_nesting => false - ) - end - - def create_pretty_state - State.new( - :indent => ' ', - :space => ' ', - :object_nl => "\n", - :array_nl => "\n" - ) - end - - # Returns the JSON generator module that is used by JSON. This is - # either JSON::Ext::Generator or JSON::Pure::Generator: - # JSON.generator # => JSON::Ext::Generator + # Returns the JSON generator module that is used by JSON. attr_reader :generator - # Sets or Returns the JSON generator state class that is used by JSON. This is - # either JSON::Ext::Generator::State or JSON::Pure::Generator::State: - # JSON.state # => JSON::Ext::Generator::State + # Sets or Returns the JSON generator state class that is used by JSON. attr_accessor :state - end - DEFAULT_CREATE_ID = 'json_class'.freeze - private_constant :DEFAULT_CREATE_ID + private + + # Called from the extension when a hash has both string and symbol keys + def on_mixed_keys_hash(hash, do_raise) + set = {} + hash.each_key do |key| + key_str = key.to_s - CREATE_ID_TLS_KEY = "JSON.create_id".freeze - private_constant :CREATE_ID_TLS_KEY + if set[key_str] + message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}" + if do_raise + raise GeneratorError, message + else + deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`") + end + else + set[key_str] = true + end + end + end + + def deprecated_singleton_attr_accessor(*attrs) + args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : "" + attrs.each do |attr| + singleton_class.class_eval <<~RUBY + def #{attr} + warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} + end + + def #{attr}=(val) + warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} = val + end + + def _#{attr} + @#{attr} + end + RUBY + end + end + end # Sets create identifier, which is used to decide if the _json_create_ # hook of a class should be called; initial value is +json_class+: # JSON.create_id # => 'json_class' def self.create_id=(new_value) - Thread.current[CREATE_ID_TLS_KEY] = new_value.dup.freeze + Thread.current[:"JSON.create_id"] = new_value.dup.freeze end # Returns the current create identifier. # See also JSON.create_id=. def self.create_id - Thread.current[CREATE_ID_TLS_KEY] || DEFAULT_CREATE_ID + Thread.current[:"JSON.create_id"] || 'json_class' end - NaN = 0.0/0 + NaN = Float::NAN - Infinity = 1.0/0 + Infinity = Float::INFINITY MinusInfinity = -Infinity # The base exception for JSON errors. - class JSONError < StandardError - def self.wrap(exception) - obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}") - obj.set_backtrace exception.backtrace - obj - end - end + class JSONError < StandardError; end # This exception is raised if a parser error occurs. - class ParserError < JSONError; end + class ParserError < JSONError + attr_reader :line, :column + end # This exception is raised if the nesting of parsed data structures is too # deep. class NestingError < ParserError; end - # :stopdoc: - class CircularDatastructure < NestingError; end - # :startdoc: - # This exception is raised if a generator or unparser error occurs. - class GeneratorError < JSONError; end - # For backwards compatibility - UnparserError = GeneratorError # :nodoc: + class GeneratorError < JSONError + attr_reader :invalid_object + + def initialize(message, invalid_object = nil) + super(message) + @invalid_object = invalid_object + end - # This exception is raised if the required unicode support is missing on the - # system. Usually this means that the iconv library is not installed. - class MissingUnicodeSupport < JSONError; end + def detailed_message(...) + # Exception#detailed_message doesn't exist until Ruby 3.2 + super_message = defined?(super) ? super : message + + if @invalid_object.nil? + super_message + else + "#{super_message}\nInvalid object: #{@invalid_object.inspect}" + end + end + end + + # Fragment of JSON document that is to be included as is: + # fragment = JSON::Fragment.new("[1, 2, 3]") + # JSON.generate({ count: 3, items: fragments }) + # + # This allows to easily assemble multiple JSON fragments that have + # been persisted somewhere without having to parse them nor resorting + # to string interpolation. + # + # Note: no validation is performed on the provided string. It is the + # responsibility of the caller to ensure the string contains valid JSON. + Fragment = Struct.new(:json) do + def initialize(json) + unless string = String.try_convert(json) + raise TypeError, " no implicit conversion of #{json.class} into String" + end + + super(string) + end + + def to_json(state = nil, *) + json + end + end module_function @@ -192,17 +328,17 @@ module JSON # {Parsing \JSON}[#module-JSON-label-Parsing+JSON]. # # Parses nested JSON objects: - # source = <<-EOT - # { - # "name": "Dave", - # "age" :40, - # "hats": [ - # "Cattleman's", - # "Panama", - # "Tophat" - # ] - # } - # EOT + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON # ruby = JSON.parse(source) # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} # @@ -212,10 +348,17 @@ module JSON # # Raises JSON::ParserError (783: unexpected token at ''): # JSON.parse('') # - def parse(source, opts = {}) - Parser.new(source, **(opts||{})).parse + def parse(source, opts = nil) + opts = ParserOptions.prepare(opts) unless opts.nil? + Parser.parse(source, opts) end + PARSE_L_OPTIONS = { + max_nesting: false, + allow_nan: true, + }.freeze + private_constant :PARSE_L_OPTIONS + # :call-seq: # JSON.parse!(source, opts) -> object # @@ -227,12 +370,12 @@ module JSON # - Option +max_nesting+, if not provided, defaults to +false+, # which disables checking for nesting depth. # - Option +allow_nan+, if not provided, defaults to +true+. - def parse!(source, opts = {}) - opts = { - :max_nesting => false, - :allow_nan => true - }.merge(opts) - Parser.new(source, **(opts||{})).parse + def parse!(source, opts = nil) + if opts.nil? + parse(source, PARSE_L_OPTIONS) + else + parse(source, PARSE_L_OPTIONS.merge(opts)) + end end # :call-seq: @@ -242,8 +385,8 @@ module JSON # parse(File.read(path), opts) # # See method #parse. - def load_file(filespec, opts = {}) - parse(File.read(filespec), opts) + def load_file(filespec, opts = nil) + parse(File.read(filespec, encoding: Encoding::UTF_8), opts) end # :call-seq: @@ -253,8 +396,8 @@ module JSON # JSON.parse!(File.read(path, opts)) # # See method #parse! - def load_file!(filespec, opts = {}) - parse!(File.read(filespec), opts) + def load_file!(filespec, opts = nil) + parse!(File.read(filespec, encoding: Encoding::UTF_8), opts) end # :call-seq: @@ -262,7 +405,7 @@ module JSON # # Returns a \String containing the generated \JSON data. # - # See also JSON.fast_generate, JSON.pretty_generate. + # See also JSON.pretty_generate. # # Argument +obj+ is the Ruby object to be converted to \JSON. # @@ -295,30 +438,12 @@ module JSON # def generate(obj, opts = nil) if State === opts - state, opts = opts, nil + opts.generate(obj) else - state = State.new - end - if opts - if opts.respond_to? :to_hash - opts = opts.to_hash - elsif opts.respond_to? :to_h - opts = opts.to_h - else - raise TypeError, "can't convert #{opts.class} into Hash" - end - state = state.configure(opts) + State.generate(obj, opts, nil) end - state.generate(obj) end - # :stopdoc: - # I want to deprecate these later, so I'll first be silent about them, and - # later delete them. - alias unparse generate - module_function :unparse - # :startdoc: - # :call-seq: # JSON.fast_generate(obj, opts) -> new_string # @@ -333,29 +458,21 @@ module JSON # # Raises SystemStackError (stack level too deep): # JSON.fast_generate(a) def fast_generate(obj, opts = nil) - if State === opts - state, opts = opts, nil + if RUBY_VERSION >= "3.0" + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated else - state = JSON.create_fast_state + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 end - if opts - if opts.respond_to? :to_hash - opts = opts.to_hash - elsif opts.respond_to? :to_h - opts = opts.to_h - else - raise TypeError, "can't convert #{opts.class} into Hash" - end - state.configure(opts) - end - state.generate(obj) + generate(obj, opts) end - # :stopdoc: - # I want to deprecate these later, so I'll first be silent about them, and later delete them. - alias fast_unparse fast_generate - module_function :fast_unparse - # :startdoc: + PRETTY_GENERATE_OPTIONS = { + indent: ' ', + space: ' ', + object_nl: "\n", + array_nl: "\n", + }.freeze + private_constant :PRETTY_GENERATE_OPTIONS # :call-seq: # JSON.pretty_generate(obj, opts = nil) -> new_string @@ -388,49 +505,60 @@ module JSON # } # def pretty_generate(obj, opts = nil) - if State === opts - state, opts = opts, nil - else - state = JSON.create_pretty_state - end + return opts.generate(obj) if State === opts + + options = PRETTY_GENERATE_OPTIONS + if opts - if opts.respond_to? :to_hash - opts = opts.to_hash - elsif opts.respond_to? :to_h - opts = opts.to_h - else - raise TypeError, "can't convert #{opts.class} into Hash" + unless opts.is_a?(Hash) + if opts.respond_to? :to_hash + opts = opts.to_hash + elsif opts.respond_to? :to_h + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end end - state.configure(opts) + options = options.merge(opts) end - state.generate(obj) + + State.generate(obj, options, nil) end - # :stopdoc: - # I want to deprecate these later, so I'll first be silent about them, and later delete them. - alias pretty_unparse pretty_generate - module_function :pretty_unparse - # :startdoc: + # Sets or returns default options for the JSON.unsafe_load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :unsafe_load_default_options - class << self - # Sets or returns default options for the JSON.load method. - # Initially: - # opts = JSON.load_default_options - # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} - attr_accessor :load_default_options - end - self.load_default_options = { + @unsafe_load_default_options = { :max_nesting => false, :allow_nan => true, - :allow_blank => true, + :allow_blank => true, :create_additions => true, } + # Sets or returns default options for the JSON.load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :load_default_options + + @load_default_options = { + :allow_nan => true, + :allow_blank => true, + :create_additions => nil, + } # :call-seq: - # JSON.load(source, proc = nil, options = {}) -> object + # JSON.unsafe_load(source, options = {}) -> object + # JSON.unsafe_load(source, proc = nil, options = {}) -> object # # Returns the Ruby objects created by parsing the given +source+. # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # # - Argument +source+ must be, or be convertible to, a \String: # - If +source+ responds to instance method +to_str+, # <tt>source.to_str</tt> becomes the source. @@ -445,12 +573,9 @@ module JSON # - Argument +proc+, if given, must be a \Proc that accepts one argument. # It will be called recursively with each result (depth-first order). # See details below. - # BEWARE: This method is meant to serialise data from trusted user input, - # like from your own database server or clients under your control, it could - # be dangerous to allow untrusted users to pass JSON sources into it. # - Argument +opts+, if given, contains a \Hash of options for the parsing. # See {Parsing Options}[#module-JSON-label-Parsing+Options]. - # The default options can be changed via method JSON.load_default_options=. + # The default options can be changed via method JSON.unsafe_load_default_options=. # # --- # @@ -458,17 +583,188 @@ module JSON # <tt>parse(source, opts)</tt>; see #parse. # # Source for following examples: - # source = <<-EOT + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # + # Load a \String: + # ruby = JSON.unsafe_load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.unsafe_load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.unsafe_load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling <tt>parse(source, opts)</tt>. + # - Recursively calls <tt>proc(result)</tt>. + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF # { - # "name": "Dave", - # "age" :40, - # "hats": [ - # "Cattleman's", - # "Panama", - # "Tophat" - # ] + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} # } - # EOT + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.unsafe_load + # ruby = JSON.unsafe_load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # obj + # }) + # pp ruby + # Output: + # {"users"=> + # [#<User:0x00000000064c4c98 + # @attributes= + # {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #<User:0x00000000064c4bd0 + # @attributes= + # {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #<Account:0x00000000064c4928 + # @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #<Account:0x00000000064c4680 + # @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #<Admin:0x00000000064c41f8 + # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>} + # + def unsafe_load(source, proc = nil, options = nil) + opts = if options.nil? + if proc && proc.is_a?(Hash) + options, proc = proc, nil + options + else + _unsafe_load_default_options + end + else + _unsafe_load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + + if opts[:allow_blank] && (source.nil? || source.empty?) + source = 'null' + end + + if proc + opts = opts.dup + opts[:on_load] = proc.to_proc + end + + parse(source, opts) + end + + # :call-seq: + # JSON.load(source, options = {}) -> object + # JSON.load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # If you must use it, use JSON.unsafe_load instead to make it clear. + # + # Since JSON version 2.8.0, `load` emits a deprecation warning when a + # non native type is deserialized, without `create_additions` being explicitly + # enabled, and in JSON version 3.0, `load` will have `create_additions` disabled + # by default. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # <tt>source.to_str</tt> becomes the source. + # - If +source+ responds to instance method +to_io+, + # <tt>source.to_io.read</tt> becomes the source. + # - If +source+ responds to instance method +read+, + # <tt>source.read</tt> becomes the source. + # - If both of the following are true, source becomes the \String <tt>'null'</tt>: + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String <tt>''</tt>. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # <tt>parse(source, opts)</tt>; see #parse. + # + # Source for following examples: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON # # Load a \String: # ruby = JSON.load(source) @@ -533,6 +829,7 @@ module JSON # when Array # obj.map! {|v| deserialize_obj v } # end + # obj # }) # pp ruby # Output: @@ -554,51 +851,53 @@ module JSON # #<Admin:0x00000000064c41f8 # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>} # - def load(source, proc = nil, options = {}) - opts = load_default_options.merge options - if source.respond_to? :to_str - source = source.to_str - elsif source.respond_to? :to_io - source = source.to_io.read - elsif source.respond_to?(:read) - source = source.read + def load(source, proc = nil, options = nil) + if proc && options.nil? && proc.is_a?(Hash) + options = proc + proc = nil end + + opts = if options.nil? + if proc && proc.is_a?(Hash) + options, proc = proc, nil + options + else + _load_default_options + end + else + _load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end - result = parse(source, opts) - recurse_proc(result, &proc) if proc - result - end - # Recursively calls passed _Proc_ if the parsed data structure is an _Array_ or _Hash_ - def recurse_proc(result, &proc) # :nodoc: - case result - when Array - result.each { |x| recurse_proc x, &proc } - proc.call result - when Hash - result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc } - proc.call result - else - proc.call result + if proc + opts = opts.dup + opts[:on_load] = proc.to_proc end - end - - alias restore load - module_function :restore - class << self - # Sets or returns the default options for the JSON.dump method. - # Initially: - # opts = JSON.dump_default_options - # opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false} - attr_accessor :dump_default_options + parse(source, opts) end - self.dump_default_options = { + + # Sets or returns the default options for the JSON.dump method. + # Initially: + # opts = JSON.dump_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true} + deprecated_singleton_attr_accessor :dump_default_options + @dump_default_options = { :max_nesting => false, :allow_nan => true, - :escape_slash => false, } # :call-seq: @@ -628,30 +927,173 @@ module JSON # puts File.read(path) # Output: # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"} - def dump(obj, anIO = nil, limit = nil) - if anIO and limit.nil? - anIO = anIO.to_io if anIO.respond_to?(:to_io) - unless anIO.respond_to?(:write) - limit = anIO - anIO = nil + def dump(obj, anIO = nil, limit = nil, kwargs = nil) + if kwargs.nil? + if limit.nil? + if anIO.is_a?(Hash) + kwargs = anIO + anIO = nil + end + elsif limit.is_a?(Hash) + kwargs = limit + limit = nil end end - opts = JSON.dump_default_options + + unless anIO.nil? + if anIO.respond_to?(:to_io) + anIO = anIO.to_io + elsif limit.nil? && !anIO.respond_to?(:write) + anIO, limit = nil, anIO + end + end + + opts = JSON._dump_default_options opts = opts.merge(:max_nesting => limit) if limit - result = generate(obj, opts) - if anIO - anIO.write result - anIO + opts = opts.merge(kwargs) if kwargs + + begin + State.generate(obj, opts, anIO) + rescue JSON::NestingError + raise ArgumentError, "exceed depth limit" + end + end + + # :stopdoc: + # All these were meant to be deprecated circa 2009, but were just set as undocumented + # so usage still exist in the wild. + def unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated else - result + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :unparse + + def fast_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :fast_unparse + + def pretty_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + pretty_generate(...) + end + module_function :fast_unparse + + def restore(...) + if RUBY_VERSION >= "3.0" + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated + else + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1 + end + load(...) + end + module_function :restore + + class << self + private + + def const_missing(const_name) + case const_name + when :PRETTY_STATE_PROTOTYPE + if RUBY_VERSION >= "3.0" + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + state.new(PRETTY_GENERATE_OPTIONS) + else + super + end end - rescue JSON::NestingError - raise ArgumentError, "exceed depth limit" end + # :startdoc: + + # JSON::Coder holds a parser and generator configuration. + # + # module MyApp + # JSONC_CODER = JSON::Coder.new( + # allow_trailing_comma: true + # ) + # end + # + # MyApp::JSONC_CODER.load(document) + # + class Coder + # :call-seq: + # JSON.new(options = nil, &block) + # + # Argument +options+, if given, contains a \Hash of options for both parsing and generating. + # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options]. + # + # For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is + # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native + # \JSON counterpart: + # + # module MyApp + # API_JSON_CODER = JSON::Coder.new do |object| + # case object + # when Time + # object.iso8601(3) + # else + # object # Unknown type, will raise + # end + # end + # end + # + # puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z" + # + def initialize(options = nil, &as_json) + if options.nil? + options = { strict: true } + else + options = options.dup + options[:strict] = true + end + options[:as_json] = as_json if as_json - # Encodes string using String.encode. - def self.iconv(to, from, string) - string.encode(to, from) + @state = State.new(options).freeze + @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze + end + + # call-seq: + # dump(object) -> String + # dump(object, io) -> io + # + # Serialize the given object into a \JSON document. + def dump(object, io = nil) + @state.generate(object, io) + end + alias_method :generate, :dump + + # call-seq: + # load(string) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load(source) + @parser_config.parse(source) + end + alias_method :parse, :load + + # call-seq: + # load(path) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load_file(path) + load(File.read(path, encoding: Encoding::UTF_8)) + end end end @@ -661,8 +1103,14 @@ module ::Kernel # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in # one line. def j(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + objs.each do |obj| - puts JSON::generate(obj, :allow_nan => true, :max_nesting => false) + puts JSON.generate(obj, :allow_nan => true, :max_nesting => false) end nil end @@ -670,8 +1118,14 @@ module ::Kernel # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with # indentation and over many lines. def jj(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + objs.each do |obj| - puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false) + puts JSON.pretty_generate(obj, :allow_nan => true, :max_nesting => false) end nil end @@ -682,22 +1136,7 @@ module ::Kernel # # The _opts_ argument is passed through to generate/parse respectively. See # generate and parse for their documentation. - def JSON(object, *args) - if object.respond_to? :to_str - JSON.parse(object.to_str, args.first) - else - JSON.generate(object, args.first) - end - end -end - -# Extends any Class to include _json_creatable?_ method. -class ::Class - # Returns true if this class can be used to create an instance - # from a serialised JSON string. The class has to implement a class - # method _json_create_ that expects a hash as first parameter. The hash - # should include the required data. - def json_creatable? - respond_to?(:json_create) + def JSON(object, opts = nil) + JSON[object, opts] end end diff --git a/ext/json/lib/json/ext.rb b/ext/json/lib/json/ext.rb index 7264a857fa..5bacc5e371 100644 --- a/ext/json/lib/json/ext.rb +++ b/ext/json/lib/json/ext.rb @@ -1,15 +1,45 @@ +# frozen_string_literal: true + require 'json/common' module JSON # This module holds all the modules/classes that implement JSON's # functionality as C extensions. module Ext + class Parser + class << self + def parse(...) + new(...).parse + end + alias_method :parse, :parse # Allow redefinition by extensions + end + + def initialize(source, opts = nil) + @source = source + @config = Config.new(opts) + end + + def source + @source.dup + end + + def parse + @config.parse(@source) + end + end + require 'json/ext/parser' - require 'json/ext/generator' - $DEBUG and warn "Using Ext extension for JSON." - JSON.parser = Parser - JSON.generator = Generator + Ext::Parser::Config = Ext::ParserConfig + JSON.parser = Ext::Parser + + if RUBY_ENGINE == 'truffleruby' + require 'json/truffle_ruby/generator' + JSON.generator = JSON::TruffleRuby::Generator + else + require 'json/ext/generator' + JSON.generator = Generator + end end - JSON_LOADED = true unless defined?(::JSON::JSON_LOADED) + JSON_LOADED = true unless defined?(JSON::JSON_LOADED) end diff --git a/ext/json/lib/json/ext/generator/state.rb b/ext/json/lib/json/ext/generator/state.rb new file mode 100644 index 0000000000..ce5c185cab --- /dev/null +++ b/ext/json/lib/json/ext/generator/state.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module JSON + module Ext + module Generator + class State + # call-seq: new(opts = {}) + # + # Instantiates a new State object, configured by _opts_. + # + # Argument +opts+, if given, contains a \Hash of options for the generation. + # See {Generating Options}[#module-JSON-label-Generating+Options]. + def initialize(opts = nil) + if opts && !opts.empty? + configure(opts) + end + end + + # call-seq: configure(opts) + # + # Configure this State instance with the Hash _opts_, and return + # itself. + def configure(opts) + unless opts.is_a?(Hash) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + end + _configure(opts) + end + + alias_method :merge, :configure + + # call-seq: to_h + # + # Returns the configuration instance variables as a hash, that can be + # passed to the configure method. + def to_h + result = { + indent: indent, + space: space, + space_before: space_before, + object_nl: object_nl, + array_nl: array_nl, + as_json: as_json, + allow_nan: allow_nan?, + ascii_only: ascii_only?, + max_nesting: max_nesting, + script_safe: script_safe?, + strict: strict?, + depth: depth, + buffer_initial_length: buffer_initial_length, + } + + allow_duplicate_key = allow_duplicate_key? + unless allow_duplicate_key.nil? + result[:allow_duplicate_key] = allow_duplicate_key + end + + instance_variables.each do |iv| + iv = iv.to_s[1..-1] + result[iv.to_sym] = self[iv] + end + + result + end + + alias_method :to_hash, :to_h + + # call-seq: [](name) + # + # Returns the value returned by method +name+. + def [](name) + ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0") + + if respond_to?(name) + __send__(name) + else + instance_variable_get("@#{name}") if + instance_variables.include?("@#{name}".to_sym) # avoid warning + end + end + + # call-seq: []=(name, value) + # + # Sets the attribute name to value. + def []=(name, value) + ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0") + + if respond_to?(name_writer = "#{name}=") + __send__ name_writer, value + else + instance_variable_set "@#{name}", value + end + end + end + end + end +end diff --git a/ext/json/lib/json/generic_object.rb b/ext/json/lib/json/generic_object.rb index 108309db26..5c8ace354b 100644 --- a/ext/json/lib/json/generic_object.rb +++ b/ext/json/lib/json/generic_object.rb @@ -1,5 +1,9 @@ -#frozen_string_literal: false -require 'ostruct' +# frozen_string_literal: true +begin + require 'ostruct' +rescue LoadError + warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`." +end module JSON class GenericObject < OpenStruct @@ -48,14 +52,6 @@ module JSON table end - def [](name) - __send__(name) - end unless method_defined?(:[]) - - def []=(name, value) - __send__("#{name}=", value) - end unless method_defined?(:[]=) - def |(other) self.class[other.to_hash.merge(to_hash)] end @@ -67,5 +63,5 @@ module JSON def to_json(*a) as_json.to_json(*a) end - end + end if defined?(::OpenStruct) end diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index 7a72272bd0..631beba83e 100644 --- a/ext/json/lib/json/version.rb +++ b/ext/json/lib/json/version.rb @@ -1,9 +1,5 @@ -# frozen_string_literal: false +# frozen_string_literal: true + module JSON - # JSON version - VERSION = '2.5.1' - VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: - VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: - VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: - VERSION_BUILD = VERSION_ARRAY[2] # :nodoc: + VERSION = '2.18.0' end diff --git a/ext/json/parser/depend b/ext/json/parser/depend index 1a75df405d..d4737b1dfb 100644 --- a/ext/json/parser/depend +++ b/ext/json/parser/depend @@ -1,5 +1,5 @@ $(OBJS): $(ruby_headers) -parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h +parser.o: parser.c $(srcdir)/../fbuffer/fbuffer.h # AUTOGENERATED DEPENDENCIES START parser.o: $(RUBY_EXTCONF_H) @@ -10,7 +10,6 @@ parser.o: $(hdrdir)/ruby/backward.h parser.o: $(hdrdir)/ruby/backward/2/assume.h parser.o: $(hdrdir)/ruby/backward/2/attributes.h parser.o: $(hdrdir)/ruby/backward/2/bool.h -parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h parser.o: $(hdrdir)/ruby/backward/2/inttypes.h parser.o: $(hdrdir)/ruby/backward/2/limits.h parser.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -19,6 +18,7 @@ parser.o: $(hdrdir)/ruby/backward/2/stdarg.h parser.o: $(hdrdir)/ruby/defines.h parser.o: $(hdrdir)/ruby/encoding.h parser.o: $(hdrdir)/ruby/intern.h +parser.o: $(hdrdir)/ruby/internal/abi.h parser.o: $(hdrdir)/ruby/internal/anyargs.h parser.o: $(hdrdir)/ruby/internal/arithmetic.h parser.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -56,6 +56,7 @@ parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h parser.o: $(hdrdir)/ruby/internal/attr/noinline.h parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h +parser.o: $(hdrdir)/ruby/internal/attr/packed_struct.h parser.o: $(hdrdir)/ruby/internal/attr/pure.h parser.o: $(hdrdir)/ruby/internal/attr/restrict.h parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -124,7 +125,6 @@ parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h parser.o: $(hdrdir)/ruby/internal/intern/error.h parser.o: $(hdrdir)/ruby/internal/intern/eval.h parser.o: $(hdrdir)/ruby/internal/intern/file.h -parser.o: $(hdrdir)/ruby/internal/intern/gc.h parser.o: $(hdrdir)/ruby/internal/intern/hash.h parser.o: $(hdrdir)/ruby/internal/intern/io.h parser.o: $(hdrdir)/ruby/internal/intern/load.h @@ -141,6 +141,7 @@ parser.o: $(hdrdir)/ruby/internal/intern/re.h parser.o: $(hdrdir)/ruby/internal/intern/ruby.h parser.o: $(hdrdir)/ruby/internal/intern/select.h parser.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +parser.o: $(hdrdir)/ruby/internal/intern/set.h parser.o: $(hdrdir)/ruby/internal/intern/signal.h parser.o: $(hdrdir)/ruby/internal/intern/sprintf.h parser.o: $(hdrdir)/ruby/internal/intern/string.h @@ -155,12 +156,12 @@ parser.o: $(hdrdir)/ruby/internal/memory.h parser.o: $(hdrdir)/ruby/internal/method.h parser.o: $(hdrdir)/ruby/internal/module.h parser.o: $(hdrdir)/ruby/internal/newobj.h -parser.o: $(hdrdir)/ruby/internal/rgengc.h parser.o: $(hdrdir)/ruby/internal/scan_args.h parser.o: $(hdrdir)/ruby/internal/special_consts.h parser.o: $(hdrdir)/ruby/internal/static_assert.h parser.o: $(hdrdir)/ruby/internal/stdalign.h parser.o: $(hdrdir)/ruby/internal/stdbool.h +parser.o: $(hdrdir)/ruby/internal/stdckdint.h parser.o: $(hdrdir)/ruby/internal/symbol.h parser.o: $(hdrdir)/ruby/internal/value.h parser.o: $(hdrdir)/ruby/internal/value_type.h @@ -174,7 +175,8 @@ parser.o: $(hdrdir)/ruby/ruby.h parser.o: $(hdrdir)/ruby/st.h parser.o: $(hdrdir)/ruby/subst.h parser.o: $(srcdir)/../fbuffer/fbuffer.h +parser.o: $(srcdir)/../json.h +parser.o: $(srcdir)/../simd/simd.h +parser.o: $(srcdir)/../vendor/ryu.h parser.o: parser.c -parser.o: parser.h -parser.o: parser.rl # AUTOGENERATED DEPENDENCIES END diff --git a/ext/json/parser/extconf.rb b/ext/json/parser/extconf.rb index feb586e1b4..2440e66d8b 100644 --- a/ext/json/parser/extconf.rb +++ b/ext/json/parser/extconf.rb @@ -1,32 +1,16 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'mkmf' -have_func("rb_enc_raise", "ruby.h") -have_func("rb_enc_interned_str", "ruby.h") +$defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0" +have_func("rb_enc_interned_str", "ruby/encoding.h") # RUBY_VERSION >= 3.0 +have_func("rb_str_to_interned_str", "ruby.h") # RUBY_VERSION >= 3.0 +have_func("rb_hash_new_capa", "ruby.h") # RUBY_VERSION >= 3.2 +have_func("rb_hash_bulk_insert", "ruby.h") # Missing on TruffleRuby -# checking if String#-@ (str_uminus) dedupes... ' -begin - a = -(%w(t e s t).join) - b = -(%w(t e s t).join) - if a.equal?(b) - $CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 ' - else - $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 ' - end -rescue NoMethodError - $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 ' -end +append_cflags("-std=c99") -# checking if String#-@ (str_uminus) directly interns frozen strings... ' -begin - s = rand.to_s.freeze - if (-s).equal?(s) && (-s.dup).equal?(s) - $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 ' - else - $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 ' - end -rescue NoMethodError - $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 ' +if enable_config('parser-use-simd', default=!ENV["JSON_DISABLE_SIMD"]) + load __dir__ + "/../simd/conf.rb" end create_makefile 'json/ext/parser' diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index b1dc8810c3..f1ea1b6abb 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -1,3338 +1,1672 @@ -/* This file is automatically generated from parser.rl by using ragel */ -#line 1 "parser.rl" -#include "../fbuffer/fbuffer.h" -#include "parser.h" - -#if defined HAVE_RUBY_ENCODING_H -# define EXC_ENCODING rb_utf8_encoding(), -# ifndef HAVE_RB_ENC_RAISE +#include "../json.h" +#include "../vendor/ryu.h" +#include "../simd/simd.h" + +static VALUE mJSON, eNestingError, Encoding_UTF_8; +static VALUE CNaN, CInfinity, CMinusInfinity; + +static ID i_new, i_try_convert, i_uminus, i_encode; + +static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_allow_control_characters, sym_symbolize_names, sym_freeze, + sym_decimal_class, sym_on_load, sym_allow_duplicate_key; + +static int binary_encindex; +static int utf8_encindex; + +#ifndef HAVE_RB_HASH_BULK_INSERT +// For TruffleRuby static void -enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) +rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash) { - va_list args; - VALUE mesg; + long index = 0; + while (index < count) { + VALUE name = pairs[index++]; + VALUE value = pairs[index++]; + rb_hash_aset(hash, name, value); + } + RB_GC_GUARD(hash); +} +#endif - va_start(args, fmt); - mesg = rb_enc_vsprintf(enc, fmt, args); - va_end(args); +#ifndef HAVE_RB_HASH_NEW_CAPA +#define rb_hash_new_capa(n) rb_hash_new() +#endif - rb_exc_raise(rb_exc_new3(exc, mesg)); +#ifndef HAVE_RB_STR_TO_INTERNED_STR +static VALUE rb_str_to_interned_str(VALUE str) +{ + return rb_funcall(rb_str_freeze(str), i_uminus, 0); } -# define rb_enc_raise enc_raise -# endif -#else -# define EXC_ENCODING /* nothing */ -# define rb_enc_raise rb_raise #endif -/* unicode */ +/* name cache */ -static const signed char digit_values[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, - -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1 -}; +#include <string.h> +#include <ctype.h> -static UTF32 unescape_unicode(const unsigned char *p) +// Object names are likely to be repeated, and are frozen. +// As such we can re-use them if we keep a cache of the ones we've seen so far, +// and save much more expensive lookups into the global fstring table. +// This cache implementation is deliberately simple, as we're optimizing for compactness, +// to be able to fit safely on the stack. +// As such, binary search into a sorted array gives a good tradeoff between compactness and +// performance. +#define JSON_RVALUE_CACHE_CAPA 63 +typedef struct rvalue_cache_struct { + int length; + VALUE entries[JSON_RVALUE_CACHE_CAPA]; +} rvalue_cache; + +static rb_encoding *enc_utf8; + +#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55 + +static inline VALUE build_interned_string(const char *str, const long length) { - signed char b; - UTF32 result = 0; - b = digit_values[p[0]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[1]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[2]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[3]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - return result; -} - -static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) +# ifdef HAVE_RB_ENC_INTERNED_STR + return rb_enc_interned_str(str, length, enc_utf8); +# else + VALUE rstring = rb_utf8_str_new(str, length); + return rb_funcall(rb_str_freeze(rstring), i_uminus, 0); +# endif +} + +static inline VALUE build_symbol(const char *str, const long length) { - int len = 1; - if (ch <= 0x7F) { - buf[0] = (char) ch; - } else if (ch <= 0x07FF) { - buf[0] = (char) ((ch >> 6) | 0xC0); - buf[1] = (char) ((ch & 0x3F) | 0x80); - len++; - } else if (ch <= 0xFFFF) { - buf[0] = (char) ((ch >> 12) | 0xE0); - buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); - buf[2] = (char) ((ch & 0x3F) | 0x80); - len += 2; - } else if (ch <= 0x1fffff) { - buf[0] =(char) ((ch >> 18) | 0xF0); - buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); - buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); - buf[3] =(char) ((ch & 0x3F) | 0x80); - len += 3; - } else { - buf[0] = '?'; - } - return len; -} - -static VALUE mJSON, mExt, cParser, eParserError, eNestingError; -static VALUE CNaN, CInfinity, CMinusInfinity; + return rb_str_intern(build_interned_string(str, length)); +} -static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, -i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, -i_object_class, i_array_class, i_decimal_class, i_key_p, -i_deep_const_get, i_match, i_match_string, i_aset, i_aref, -i_leftshift, i_new, i_try_convert, i_freeze, i_uminus; +static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring) +{ + MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index); + cache->length++; + cache->entries[index] = rstring; +} +#define rstring_cache_memcmp memcmp -#line 125 "parser.rl" +#if JSON_CPU_LITTLE_ENDIAN_64BITS +#if __has_builtin(__builtin_bswap64) +#undef rstring_cache_memcmp +ALWAYS_INLINE(static) int rstring_cache_memcmp(const char *str, const char *rptr, const long length) +{ + // The libc memcmp has numerous complex optimizations, but in this particular case, + // we know the string is small (JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH), so being able to + // inline a simpler memcmp outperforms calling the libc version. + long i = 0; + + for (; i + 8 <= length; i += 8) { + uint64_t a, b; + memcpy(&a, str + i, 8); + memcpy(&b, rptr + i, 8); + if (a != b) { + a = __builtin_bswap64(a); + b = __builtin_bswap64(b); + return (a < b) ? -1 : 1; + } + } + + for (; i < length; i++) { + if (str[i] != rptr[i]) { + return (str[i] < rptr[i]) ? -1 : 1; + } + } + + return 0; +} +#endif +#endif +ALWAYS_INLINE(static) int rstring_cache_cmp(const char *str, const long length, VALUE rstring) +{ + const char *rstring_ptr; + long rstring_length; + RSTRING_GETMEM(rstring, rstring_ptr, rstring_length); -enum {JSON_object_start = 1}; -enum {JSON_object_first_final = 27}; -enum {JSON_object_error = 0}; + if (length == rstring_length) { + return rstring_cache_memcmp(str, rstring_ptr, length); + } else { + return (int)(length - rstring_length); + } +} -enum {JSON_object_en_main = 1}; +ALWAYS_INLINE(static) VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + int low = 0; + int high = cache->length - 1; + + while (low <= high) { + int mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + int cmp = rstring_cache_cmp(str, length, entry); + + if (cmp == 0) { + return entry; + } else if (cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + VALUE rstring = build_interned_string(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + rvalue_cache_insert_at(cache, low, rstring); + } + return rstring; +} -static const char MAYBE_UNUSED(_JSON_object_nfa_targs)[] = { - 0, 0 -}; +static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + int low = 0; + int high = cache->length - 1; + + while (low <= high) { + int mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + int cmp = rstring_cache_cmp(str, length, rb_sym2str(entry)); + + if (cmp == 0) { + return entry; + } else if (cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + VALUE rsymbol = build_symbol(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + rvalue_cache_insert_at(cache, low, rsymbol); + } + return rsymbol; +} -static const char MAYBE_UNUSED(_JSON_object_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 -}; +/* rvalue stack */ -static const char MAYBE_UNUSED(_JSON_object_nfa_push_actions)[] = { - 0, 0 -}; +#define RVALUE_STACK_INITIAL_CAPA 128 -static const char MAYBE_UNUSED(_JSON_object_nfa_pop_trans)[] = { - 0, 0 +enum rvalue_stack_type { + RVALUE_STACK_HEAP_ALLOCATED = 0, + RVALUE_STACK_STACK_ALLOCATED = 1, }; +typedef struct rvalue_stack_struct { + enum rvalue_stack_type type; + long capa; + long head; + VALUE *ptr; +} rvalue_stack; -#line 167 "parser.rl" +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref); +static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref) +{ + long required = stack->capa * 2; + + if (stack->type == RVALUE_STACK_STACK_ALLOCATED) { + stack = rvalue_stack_spill(stack, handle, stack_ref); + } else { + REALLOC_N(stack->ptr, VALUE, required); + stack->capa = required; + } + return stack; +} -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) +static VALUE rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref) { - int cs = EVIL; - VALUE last_name = Qnil; - VALUE object_class = json->object_class; - - if (json->max_nesting && current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); - } - - *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); - - - { - cs = (int)JSON_object_start; - } - - #line 182 "parser.rl" - - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 7: - goto st_case_7; - case 8: - goto st_case_8; - case 9: - goto st_case_9; - case 10: - goto st_case_10; - case 11: - goto st_case_11; - case 12: - goto st_case_12; - case 13: - goto st_case_13; - case 14: - goto st_case_14; - case 15: - goto st_case_15; - case 16: - goto st_case_16; - case 17: - goto st_case_17; - case 18: - goto st_case_18; - case 27: - goto st_case_27; - case 19: - goto st_case_19; - case 20: - goto st_case_20; - case 21: - goto st_case_21; - case 22: - goto st_case_22; - case 23: - goto st_case_23; - case 24: - goto st_case_24; - case 25: - goto st_case_25; - case 26: - goto st_case_26; - } - goto st_out; - st_case_1: - if ( ( (*( p))) == 123 ) { - goto st2; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - switch( ( (*( p))) ) { - case 13: { - goto st2; - } - case 32: { - goto st2; - } - case 34: { - goto ctr2; - } - case 47: { - goto st23; - } - case 125: { - goto ctr4; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st2; - } - { - goto st0; - } - ctr2: - { - #line 149 "parser.rl" - - char *np; - json->parsing_name = 1; - np = JSON_parse_string(json, p, pe, &last_name); - json->parsing_name = 0; - if (np == NULL) { {p = p - 1; } {p+= 1; cs = 3; goto _out;} } else {p = (( np))-1;} - - } - - goto st3; - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - switch( ( (*( p))) ) { - case 13: { - goto st3; - } - case 32: { - goto st3; - } - case 47: { - goto st4; - } - case 58: { - goto st8; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st3; - } - { - goto st0; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - switch( ( (*( p))) ) { - case 42: { - goto st5; - } - case 47: { - goto st7; - } - } - { - goto st0; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - if ( ( (*( p))) == 42 ) { - goto st6; - } - { - goto st5; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - switch( ( (*( p))) ) { - case 42: { - goto st6; - } - case 47: { - goto st3; - } - } - { - goto st5; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - if ( ( (*( p))) == 10 ) { - goto st3; - } - { - goto st7; - } - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - switch( ( (*( p))) ) { - case 13: { - goto st8; - } - case 32: { - goto st8; - } - case 34: { - goto ctr11; - } - case 45: { - goto ctr11; - } - case 47: { - goto st19; - } - case 73: { - goto ctr11; - } - case 78: { - goto ctr11; - } - case 91: { - goto ctr11; - } - case 102: { - goto ctr11; - } - case 110: { - goto ctr11; - } - case 116: { - goto ctr11; - } - case 123: { - goto ctr11; - } - } - if ( ( (*( p))) > 10 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto ctr11; - } - } else if ( ( (*( p))) >= 9 ) { - goto st8; - } - { - goto st0; - } - ctr11: - { - #line 133 "parser.rl" - - VALUE v = Qnil; - char *np = JSON_parse_value(json, p, pe, &v, current_nesting); - if (np == NULL) { - {p = p - 1; } {p+= 1; cs = 9; goto _out;} - } else { - if (NIL_P(json->object_class)) { - OBJ_FREEZE(last_name); - rb_hash_aset(*result, last_name, v); - } else { - rb_funcall(*result, i_aset, 2, last_name, v); - } - {p = (( np))-1;} - - } - } - - goto st9; - st9: - p+= 1; - if ( p == pe ) - goto _test_eof9; - st_case_9: - switch( ( (*( p))) ) { - case 13: { - goto st9; - } - case 32: { - goto st9; - } - case 44: { - goto st10; - } - case 47: { - goto st15; - } - case 125: { - goto ctr4; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st9; - } - { - goto st0; - } - st10: - p+= 1; - if ( p == pe ) - goto _test_eof10; - st_case_10: - switch( ( (*( p))) ) { - case 13: { - goto st10; - } - case 32: { - goto st10; - } - case 34: { - goto ctr2; - } - case 47: { - goto st11; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st10; - } - { - goto st0; - } - st11: - p+= 1; - if ( p == pe ) - goto _test_eof11; - st_case_11: - switch( ( (*( p))) ) { - case 42: { - goto st12; - } - case 47: { - goto st14; - } - } - { - goto st0; - } - st12: - p+= 1; - if ( p == pe ) - goto _test_eof12; - st_case_12: - if ( ( (*( p))) == 42 ) { - goto st13; - } - { - goto st12; - } - st13: - p+= 1; - if ( p == pe ) - goto _test_eof13; - st_case_13: - switch( ( (*( p))) ) { - case 42: { - goto st13; - } - case 47: { - goto st10; - } - } - { - goto st12; - } - st14: - p+= 1; - if ( p == pe ) - goto _test_eof14; - st_case_14: - if ( ( (*( p))) == 10 ) { - goto st10; - } - { - goto st14; - } - st15: - p+= 1; - if ( p == pe ) - goto _test_eof15; - st_case_15: - switch( ( (*( p))) ) { - case 42: { - goto st16; - } - case 47: { - goto st18; - } - } - { - goto st0; - } - st16: - p+= 1; - if ( p == pe ) - goto _test_eof16; - st_case_16: - if ( ( (*( p))) == 42 ) { - goto st17; - } - { - goto st16; - } - st17: - p+= 1; - if ( p == pe ) - goto _test_eof17; - st_case_17: - switch( ( (*( p))) ) { - case 42: { - goto st17; - } - case 47: { - goto st9; - } - } - { - goto st16; - } - st18: - p+= 1; - if ( p == pe ) - goto _test_eof18; - st_case_18: - if ( ( (*( p))) == 10 ) { - goto st9; - } - { - goto st18; - } - ctr4: - { - #line 157 "parser.rl" - {p = p - 1; } {p+= 1; cs = 27; goto _out;} } - - goto st27; - st27: - p+= 1; - if ( p == pe ) - goto _test_eof27; - st_case_27: - { - goto st0; - } - st19: - p+= 1; - if ( p == pe ) - goto _test_eof19; - st_case_19: - switch( ( (*( p))) ) { - case 42: { - goto st20; - } - case 47: { - goto st22; - } - } - { - goto st0; - } - st20: - p+= 1; - if ( p == pe ) - goto _test_eof20; - st_case_20: - if ( ( (*( p))) == 42 ) { - goto st21; - } - { - goto st20; - } - st21: - p+= 1; - if ( p == pe ) - goto _test_eof21; - st_case_21: - switch( ( (*( p))) ) { - case 42: { - goto st21; - } - case 47: { - goto st8; - } - } - { - goto st20; - } - st22: - p+= 1; - if ( p == pe ) - goto _test_eof22; - st_case_22: - if ( ( (*( p))) == 10 ) { - goto st8; - } - { - goto st22; - } - st23: - p+= 1; - if ( p == pe ) - goto _test_eof23; - st_case_23: - switch( ( (*( p))) ) { - case 42: { - goto st24; - } - case 47: { - goto st26; - } - } - { - goto st0; - } - st24: - p+= 1; - if ( p == pe ) - goto _test_eof24; - st_case_24: - if ( ( (*( p))) == 42 ) { - goto st25; - } - { - goto st24; - } - st25: - p+= 1; - if ( p == pe ) - goto _test_eof25; - st_case_25: - switch( ( (*( p))) ) { - case 42: { - goto st25; - } - case 47: { - goto st2; - } - } - { - goto st24; - } - st26: - p+= 1; - if ( p == pe ) - goto _test_eof26; - st_case_26: - if ( ( (*( p))) == 10 ) { - goto st2; - } - { - goto st26; - } - st_out: - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 183 "parser.rl" - - - if (cs >= JSON_object_first_final) { - if (json->create_additions) { - VALUE klassname; - if (NIL_P(json->object_class)) { - klassname = rb_hash_aref(*result, json->create_id); - } else { - klassname = rb_funcall(*result, i_aref, 1, json->create_id); - } - if (!NIL_P(klassname)) { - VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname); - if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) { - *result = rb_funcall(klass, i_json_create, 1, *result); - } - } - } - return p + 1; - } else { - return NULL; - } -} - - - -enum {JSON_value_start = 1}; -enum {JSON_value_first_final = 29}; -enum {JSON_value_error = 0}; - -enum {JSON_value_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_value_nfa_targs)[] = { - 0, 0 -}; + if (RB_UNLIKELY(stack->head >= stack->capa)) { + stack = rvalue_stack_grow(stack, handle, stack_ref); + } + stack->ptr[stack->head] = value; + stack->head++; + return value; +} -static const char MAYBE_UNUSED(_JSON_value_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 -}; +static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count) +{ + return stack->ptr + (stack->head - count); +} + +static inline void rvalue_stack_pop(rvalue_stack *stack, long count) +{ + stack->head -= count; +} + +static void rvalue_stack_mark(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + long index; + for (index = 0; index < stack->head; index++) { + rb_gc_mark(stack->ptr[index]); + } +} + +static void rvalue_stack_free(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + if (stack) { + ruby_xfree(stack->ptr); + ruby_xfree(stack); + } +} -static const char MAYBE_UNUSED(_JSON_value_nfa_push_actions)[] = { - 0, 0 +static size_t rvalue_stack_memsize(const void *ptr) +{ + const rvalue_stack *stack = (const rvalue_stack *)ptr; + return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa; +} + +static const rb_data_type_t JSON_Parser_rvalue_stack_type = { + "JSON::Ext::Parser/rvalue_stack", + { + .dmark = rvalue_stack_mark, + .dfree = rvalue_stack_free, + .dsize = rvalue_stack_memsize, + }, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, }; -static const char MAYBE_UNUSED(_JSON_value_nfa_pop_trans)[] = { - 0, 0 +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref) +{ + rvalue_stack *stack; + *handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); + *stack_ref = stack; + MEMCPY(stack, old_stack, rvalue_stack, 1); + + stack->capa = old_stack->capa << 1; + stack->ptr = ALLOC_N(VALUE, stack->capa); + stack->type = RVALUE_STACK_HEAP_ALLOCATED; + MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head); + return stack; +} + +static void rvalue_stack_eagerly_release(VALUE handle) +{ + if (handle) { + rvalue_stack *stack; + TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); + RTYPEDDATA_DATA(handle) = NULL; + rvalue_stack_free(stack); + } +} + +static int convert_UTF32_to_UTF8(char *buf, uint32_t ch) +{ + int len = 1; + if (ch <= 0x7F) { + buf[0] = (char) ch; + } else if (ch <= 0x07FF) { + buf[0] = (char) ((ch >> 6) | 0xC0); + buf[1] = (char) ((ch & 0x3F) | 0x80); + len++; + } else if (ch <= 0xFFFF) { + buf[0] = (char) ((ch >> 12) | 0xE0); + buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); + buf[2] = (char) ((ch & 0x3F) | 0x80); + len += 2; + } else if (ch <= 0x1fffff) { + buf[0] =(char) ((ch >> 18) | 0xF0); + buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); + buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); + buf[3] =(char) ((ch & 0x3F) | 0x80); + len += 3; + } else { + buf[0] = '?'; + } + return len; +} + +enum duplicate_key_action { + JSON_DEPRECATED = 0, + JSON_IGNORE, + JSON_RAISE, }; +typedef struct JSON_ParserStruct { + VALUE on_load_proc; + VALUE decimal_class; + ID decimal_method_id; + enum duplicate_key_action on_duplicate_key; + int max_nesting; + bool allow_nan; + bool allow_trailing_comma; + bool allow_control_characters; + bool symbolize_names; + bool freeze; +} JSON_ParserConfig; + +typedef struct JSON_ParserStateStruct { + VALUE stack_handle; + const char *start; + const char *cursor; + const char *end; + rvalue_stack *stack; + rvalue_cache name_cache; + int in_array; + int current_nesting; +} JSON_ParserState; + +static inline size_t rest(JSON_ParserState *state) { + return state->end - state->cursor; +} -#line 283 "parser.rl" +static inline bool eos(JSON_ParserState *state) { + return state->cursor >= state->end; +} +static inline char peek(JSON_ParserState *state) +{ + if (RB_UNLIKELY(eos(state))) { + return 0; + } + return *state->cursor; +} -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) +static void cursor_position(JSON_ParserState *state, long *line_out, long *column_out) { - int cs = EVIL; - - - { - cs = (int)JSON_value_start; - } - - #line 290 "parser.rl" - - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 29: - goto st_case_29; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 7: - goto st_case_7; - case 8: - goto st_case_8; - case 9: - goto st_case_9; - case 10: - goto st_case_10; - case 11: - goto st_case_11; - case 12: - goto st_case_12; - case 13: - goto st_case_13; - case 14: - goto st_case_14; - case 15: - goto st_case_15; - case 16: - goto st_case_16; - case 17: - goto st_case_17; - case 18: - goto st_case_18; - case 19: - goto st_case_19; - case 20: - goto st_case_20; - case 21: - goto st_case_21; - case 22: - goto st_case_22; - case 23: - goto st_case_23; - case 24: - goto st_case_24; - case 25: - goto st_case_25; - case 26: - goto st_case_26; - case 27: - goto st_case_27; - case 28: - goto st_case_28; - } - goto st_out; - st1: - p+= 1; - if ( p == pe ) - goto _test_eof1; - st_case_1: - switch( ( (*( p))) ) { - case 13: { - goto st1; - } - case 32: { - goto st1; - } - case 34: { - goto ctr2; - } - case 45: { - goto ctr3; - } - case 47: { - goto st6; - } - case 73: { - goto st10; - } - case 78: { - goto st17; - } - case 91: { - goto ctr7; - } - case 102: { - goto st19; - } - case 110: { - goto st23; - } - case 116: { - goto st26; - } - case 123: { - goto ctr11; - } - } - if ( ( (*( p))) > 10 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto ctr3; - } - } else if ( ( (*( p))) >= 9 ) { - goto st1; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - ctr2: - { - #line 235 "parser.rl" - - char *np = JSON_parse_string(json, p, pe, result); - if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;} - - } - - goto st29; - ctr3: - { - #line 240 "parser.rl" - - char *np; - if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { - if (json->allow_nan) { - *result = CMinusInfinity; - {p = (( p + 10))-1;} - - {p = p - 1; } {p+= 1; cs = 29; goto _out;} - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - } - } - np = JSON_parse_float(json, p, pe, result); - if (np != NULL) {p = (( np))-1;} - - np = JSON_parse_integer(json, p, pe, result); - if (np != NULL) {p = (( np))-1;} - - {p = p - 1; } {p+= 1; cs = 29; goto _out;} - } - - goto st29; - ctr7: - { - #line 258 "parser.rl" - - char *np; - np = JSON_parse_array(json, p, pe, result, current_nesting + 1); - if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;} - - } - - goto st29; - ctr11: - { - #line 264 "parser.rl" - - char *np; - np = JSON_parse_object(json, p, pe, result, current_nesting + 1); - if (np == NULL) { {p = p - 1; } {p+= 1; cs = 29; goto _out;} } else {p = (( np))-1;} - - } - - goto st29; - ctr25: - { - #line 228 "parser.rl" - - if (json->allow_nan) { - *result = CInfinity; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); - } - } - - goto st29; - ctr27: - { - #line 221 "parser.rl" - - if (json->allow_nan) { - *result = CNaN; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); - } - } - - goto st29; - ctr31: - { - #line 215 "parser.rl" - - *result = Qfalse; - } - - goto st29; - ctr34: - { - #line 212 "parser.rl" - - *result = Qnil; - } - - goto st29; - ctr37: - { - #line 218 "parser.rl" - - *result = Qtrue; - } - - goto st29; - st29: - p+= 1; - if ( p == pe ) - goto _test_eof29; - st_case_29: - { - #line 270 "parser.rl" - {p = p - 1; } {p+= 1; cs = 29; goto _out;} } - switch( ( (*( p))) ) { - case 13: { - goto st29; - } - case 32: { - goto st29; - } - case 47: { - goto st2; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st29; - } - { - goto st0; - } - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - switch( ( (*( p))) ) { - case 42: { - goto st3; - } - case 47: { - goto st5; - } - } - { - goto st0; - } - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - if ( ( (*( p))) == 42 ) { - goto st4; - } - { - goto st3; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - switch( ( (*( p))) ) { - case 42: { - goto st4; - } - case 47: { - goto st29; - } - } - { - goto st3; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - if ( ( (*( p))) == 10 ) { - goto st29; - } - { - goto st5; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - switch( ( (*( p))) ) { - case 42: { - goto st7; - } - case 47: { - goto st9; - } - } - { - goto st0; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - if ( ( (*( p))) == 42 ) { - goto st8; - } - { - goto st7; - } - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - switch( ( (*( p))) ) { - case 42: { - goto st8; - } - case 47: { - goto st1; - } - } - { - goto st7; - } - st9: - p+= 1; - if ( p == pe ) - goto _test_eof9; - st_case_9: - if ( ( (*( p))) == 10 ) { - goto st1; - } - { - goto st9; - } - st10: - p+= 1; - if ( p == pe ) - goto _test_eof10; - st_case_10: - if ( ( (*( p))) == 110 ) { - goto st11; - } - { - goto st0; - } - st11: - p+= 1; - if ( p == pe ) - goto _test_eof11; - st_case_11: - if ( ( (*( p))) == 102 ) { - goto st12; - } - { - goto st0; - } - st12: - p+= 1; - if ( p == pe ) - goto _test_eof12; - st_case_12: - if ( ( (*( p))) == 105 ) { - goto st13; - } - { - goto st0; - } - st13: - p+= 1; - if ( p == pe ) - goto _test_eof13; - st_case_13: - if ( ( (*( p))) == 110 ) { - goto st14; - } - { - goto st0; - } - st14: - p+= 1; - if ( p == pe ) - goto _test_eof14; - st_case_14: - if ( ( (*( p))) == 105 ) { - goto st15; - } - { - goto st0; - } - st15: - p+= 1; - if ( p == pe ) - goto _test_eof15; - st_case_15: - if ( ( (*( p))) == 116 ) { - goto st16; - } - { - goto st0; - } - st16: - p+= 1; - if ( p == pe ) - goto _test_eof16; - st_case_16: - if ( ( (*( p))) == 121 ) { - goto ctr25; - } - { - goto st0; - } - st17: - p+= 1; - if ( p == pe ) - goto _test_eof17; - st_case_17: - if ( ( (*( p))) == 97 ) { - goto st18; - } - { - goto st0; - } - st18: - p+= 1; - if ( p == pe ) - goto _test_eof18; - st_case_18: - if ( ( (*( p))) == 78 ) { - goto ctr27; - } - { - goto st0; - } - st19: - p+= 1; - if ( p == pe ) - goto _test_eof19; - st_case_19: - if ( ( (*( p))) == 97 ) { - goto st20; - } - { - goto st0; - } - st20: - p+= 1; - if ( p == pe ) - goto _test_eof20; - st_case_20: - if ( ( (*( p))) == 108 ) { - goto st21; - } - { - goto st0; - } - st21: - p+= 1; - if ( p == pe ) - goto _test_eof21; - st_case_21: - if ( ( (*( p))) == 115 ) { - goto st22; - } - { - goto st0; - } - st22: - p+= 1; - if ( p == pe ) - goto _test_eof22; - st_case_22: - if ( ( (*( p))) == 101 ) { - goto ctr31; - } - { - goto st0; - } - st23: - p+= 1; - if ( p == pe ) - goto _test_eof23; - st_case_23: - if ( ( (*( p))) == 117 ) { - goto st24; - } - { - goto st0; - } - st24: - p+= 1; - if ( p == pe ) - goto _test_eof24; - st_case_24: - if ( ( (*( p))) == 108 ) { - goto st25; - } - { - goto st0; - } - st25: - p+= 1; - if ( p == pe ) - goto _test_eof25; - st_case_25: - if ( ( (*( p))) == 108 ) { - goto ctr34; - } - { - goto st0; - } - st26: - p+= 1; - if ( p == pe ) - goto _test_eof26; - st_case_26: - if ( ( (*( p))) == 114 ) { - goto st27; - } - { - goto st0; - } - st27: - p+= 1; - if ( p == pe ) - goto _test_eof27; - st_case_27: - if ( ( (*( p))) == 117 ) { - goto st28; - } - { - goto st0; - } - st28: - p+= 1; - if ( p == pe ) - goto _test_eof28; - st_case_28: - if ( ( (*( p))) == 101 ) { - goto ctr37; - } - { - goto st0; - } - st_out: - _test_eof1: cs = 1; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 291 "parser.rl" - - - if (json->freeze) { - OBJ_FREEZE(*result); - } - - if (cs >= JSON_value_first_final) { - return p; - } else { - return NULL; - } -} - - -enum {JSON_integer_start = 1}; -enum {JSON_integer_first_final = 3}; -enum {JSON_integer_error = 0}; - -enum {JSON_integer_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_integer_nfa_targs)[] = { - 0, 0 -}; + const char *cursor = state->cursor; + long column = 0; + long line = 1; + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + break; + } + column++; + } + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + line++; + } + } + *line_out = line; + *column_out = column; +} -static const char MAYBE_UNUSED(_JSON_integer_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0 -}; +static void emit_parse_warning(const char *message, JSON_ParserState *state) +{ + long line, column; + cursor_position(state, &line, &column); -static const char MAYBE_UNUSED(_JSON_integer_nfa_push_actions)[] = { - 0, 0 -}; + VALUE warning = rb_sprintf("%s at line %ld column %ld", message, line, column); + rb_funcall(mJSON, rb_intern("deprecation_warning"), 1, warning); +} + +#define PARSE_ERROR_FRAGMENT_LEN 32 + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_parse_error(const char *format, JSON_ParserState *state) +{ + unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3]; + long line, column; + cursor_position(state, &line, &column); + + const char *ptr = "EOF"; + if (state->cursor && state->cursor < state->end) { + ptr = state->cursor; + size_t len = 0; + while (len < PARSE_ERROR_FRAGMENT_LEN) { + char ch = ptr[len]; + if (!ch || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\r') { + break; + } + len++; + } + + if (len) { + buffer[0] = '\''; + MEMCPY(buffer + 1, ptr, char, len); + + while (buffer[len] >= 0x80 && buffer[len] < 0xC0) { // Is continuation byte + len--; + } + + if (buffer[len] >= 0xC0) { // multibyte character start + len--; + } + + buffer[len + 1] = '\''; + buffer[len + 2] = '\0'; + ptr = (const char *)buffer; + } + } + + VALUE msg = rb_sprintf(format, ptr); + VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column); + RB_GC_GUARD(msg); + + VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message); + rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line)); + rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column)); + rb_exc_raise(exc); +} -static const char MAYBE_UNUSED(_JSON_integer_nfa_pop_trans)[] = { - 0, 0 +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at) +{ + state->cursor = at; + raise_parse_error(format, state); +} + +/* unicode */ + +static const signed char digit_values[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, + -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1 }; +static uint32_t unescape_unicode(JSON_ParserState *state, const char *sp, const char *spe) +{ + if (RB_UNLIKELY(sp > spe - 4)) { + raise_parse_error_at("incomplete unicode character escape sequence at %s", state, sp - 2); + } + + const unsigned char *p = (const unsigned char *)sp; + + const signed char b0 = digit_values[p[0]]; + const signed char b1 = digit_values[p[1]]; + const signed char b2 = digit_values[p[2]]; + const signed char b3 = digit_values[p[3]]; + + if (RB_UNLIKELY((signed char)(b0 | b1 | b2 | b3) < 0)) { + raise_parse_error_at("incomplete unicode character escape sequence at %s", state, sp - 2); + } + + return ((uint32_t)b0 << 12) | ((uint32_t)b1 << 8) | ((uint32_t)b2 << 4) | (uint32_t)b3; +} + +#define GET_PARSER_CONFIG \ + JSON_ParserConfig *config; \ + TypedData_Get_Struct(self, JSON_ParserConfig, &JSON_ParserConfig_type, config) -#line 311 "parser.rl" +static const rb_data_type_t JSON_ParserConfig_type; +static void +json_eat_comments(JSON_ParserState *state) +{ + const char *start = state->cursor; + state->cursor++; + + switch (peek(state)) { + case '/': { + state->cursor = memchr(state->cursor, '\n', state->end - state->cursor); + if (!state->cursor) { + state->cursor = state->end; + } else { + state->cursor++; + } + break; + } + case '*': { + state->cursor++; + + while (true) { + const char *next_match = memchr(state->cursor, '*', state->end - state->cursor); + if (!next_match) { + raise_parse_error_at("unterminated comment, expected closing '*/'", state, start); + } + + state->cursor = next_match + 1; + if (peek(state) == '/') { + state->cursor++; + break; + } + } + break; + } + default: + raise_parse_error_at("unexpected token %s", state, start); + break; + } +} -static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) +ALWAYS_INLINE(static) void +json_eat_whitespace(JSON_ParserState *state) { - int cs = EVIL; - - - { - cs = (int)JSON_integer_start; - } - - #line 318 "parser.rl" - - json->memo = p; - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - } - goto st_out; - st_case_1: - switch( ( (*( p))) ) { - case 45: { - goto st2; - } - case 48: { - goto st3; - } - } - if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st5; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - if ( ( (*( p))) == 48 ) { - goto st3; - } - if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st5; - } - { - goto st0; - } - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st0; - } - { - goto ctr4; - } - ctr4: - { - #line 308 "parser.rl" - {p = p - 1; } {p+= 1; cs = 4; goto _out;} } - - goto st4; - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - { - goto st0; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st5; - } - { - goto ctr4; - } - st_out: - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 320 "parser.rl" - - - if (cs >= JSON_integer_first_final) { - long len = p - json->memo; - fbuffer_clear(json->fbuffer); - fbuffer_append(json->fbuffer, json->memo, len); - fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10); - return p + 1; - } else { - return NULL; - } -} - - -enum {JSON_float_start = 1}; -enum {JSON_float_first_final = 8}; -enum {JSON_float_error = 0}; - -enum {JSON_float_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_float_nfa_targs)[] = { - 0, 0 -}; + while (true) { + switch (peek(state)) { + case ' ': + state->cursor++; + break; + case '\n': + state->cursor++; + + // Heuristic: if we see a newline, there is likely consecutive spaces after it. +#if JSON_CPU_LITTLE_ENDIAN_64BITS + while (rest(state) > 8) { + uint64_t chunk; + memcpy(&chunk, state->cursor, sizeof(uint64_t)); + if (chunk == 0x2020202020202020) { + state->cursor += 8; + continue; + } + + uint32_t consecutive_spaces = trailing_zeros64(chunk ^ 0x2020202020202020) / CHAR_BIT; + state->cursor += consecutive_spaces; + break; + } +#endif + break; + case '\t': + case '\r': + state->cursor++; + break; + case '/': + json_eat_comments(state); + break; + + default: + return; + } + } +} -static const char MAYBE_UNUSED(_JSON_float_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; +static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize) +{ + if (symbolize) { + intern = true; + } + VALUE result; +# ifdef HAVE_RB_ENC_INTERNED_STR + if (intern) { + result = rb_enc_interned_str(start, (long)(end - start), enc_utf8); + } else { + result = rb_utf8_str_new(start, (long)(end - start)); + } +# else + result = rb_utf8_str_new(start, (long)(end - start)); + if (intern) { + result = rb_funcall(rb_str_freeze(result), i_uminus, 0); + } +# endif -static const char MAYBE_UNUSED(_JSON_float_nfa_push_actions)[] = { - 0, 0 -}; + if (symbolize) { + result = rb_str_intern(result); + } -static const char MAYBE_UNUSED(_JSON_float_nfa_pop_trans)[] = { - 0, 0 -}; + return result; +} +static inline bool json_string_cacheable_p(const char *string, size_t length) +{ + // We mostly want to cache strings that are likely to be repeated. + // Simple heuristics: + // - Common names aren't likely to be very long. So we just don't cache names above an arbitrary threshold. + // - If the first character isn't a letter, we're much less likely to see this string again. + return length <= JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH && rb_isalpha(string[0]); +} -#line 345 "parser.rl" +static inline VALUE json_string_fastpath(JSON_ParserState *state, JSON_ParserConfig *config, const char *string, const char *stringEnd, bool is_name) +{ + bool intern = is_name || config->freeze; + bool symbolize = is_name && config->symbolize_names; + size_t bufferSize = stringEnd - string; + + if (is_name && state->in_array && RB_LIKELY(json_string_cacheable_p(string, bufferSize))) { + VALUE cached_key; + if (RB_UNLIKELY(symbolize)) { + cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize); + } else { + cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize); + } + + if (RB_LIKELY(cached_key)) { + return cached_key; + } + } + + return build_string(string, stringEnd, intern, symbolize); +} +#define JSON_MAX_UNESCAPE_POSITIONS 16 +typedef struct _json_unescape_positions { + long size; + const char **positions; + unsigned long additional_backslashes; +} JSON_UnescapePositions; -static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) +static inline const char *json_next_backslash(const char *pe, const char *stringEnd, JSON_UnescapePositions *positions) { - int cs = EVIL; - - - { - cs = (int)JSON_float_start; - } - - #line 352 "parser.rl" - - json->memo = p; - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 8: - goto st_case_8; - case 9: - goto st_case_9; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 10: - goto st_case_10; - case 7: - goto st_case_7; - } - goto st_out; - st_case_1: - switch( ( (*( p))) ) { - case 45: { - goto st2; - } - case 48: { - goto st3; - } - } - if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st7; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - if ( ( (*( p))) == 48 ) { - goto st3; - } - if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st7; - } - { - goto st0; - } - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - switch( ( (*( p))) ) { - case 46: { - goto st4; - } - case 69: { - goto st5; - } - case 101: { - goto st5; - } - } - { - goto st0; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st8; - } - { - goto st0; - } - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - switch( ( (*( p))) ) { - case 69: { - goto st5; - } - case 101: { - goto st5; - } - } - if ( ( (*( p))) > 46 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st8; - } - } else if ( ( (*( p))) >= 45 ) { - goto st0; - } - { - goto ctr9; - } - ctr9: - { - #line 339 "parser.rl" - {p = p - 1; } {p+= 1; cs = 9; goto _out;} } - - goto st9; - st9: - p+= 1; - if ( p == pe ) - goto _test_eof9; - st_case_9: - { - goto st0; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - switch( ( (*( p))) ) { - case 43: { - goto st6; - } - case 45: { - goto st6; - } - } - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st10; - } - { - goto st0; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st10; - } - { - goto st0; - } - st10: - p+= 1; - if ( p == pe ) - goto _test_eof10; - st_case_10: - switch( ( (*( p))) ) { - case 69: { - goto st0; - } - case 101: { - goto st0; - } - } - if ( ( (*( p))) > 46 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st10; - } - } else if ( ( (*( p))) >= 45 ) { - goto st0; - } - { - goto ctr9; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - switch( ( (*( p))) ) { - case 46: { - goto st4; - } - case 69: { - goto st5; - } - case 101: { - goto st5; - } - } - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st7; - } - { - goto st0; - } - st_out: - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 354 "parser.rl" - - - if (cs >= JSON_float_first_final) { - VALUE mod = Qnil; - ID method_id = 0; - if (rb_respond_to(json->decimal_class, i_try_convert)) { - mod = json->decimal_class; - method_id = i_try_convert; - } else if (rb_respond_to(json->decimal_class, i_new)) { - mod = json->decimal_class; - method_id = i_new; - } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) { - VALUE name = rb_class_name(json->decimal_class); - const char *name_cstr = RSTRING_PTR(name); - const char *last_colon = strrchr(name_cstr, ':'); - if (last_colon) { - const char *mod_path_end = last_colon - 1; - VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); - mod = rb_path_to_class(mod_path); - - const char *method_name_beg = last_colon + 1; - long before_len = method_name_beg - name_cstr; - long len = RSTRING_LEN(name) - before_len; - VALUE method_name = rb_str_substr(name, before_len, len); - method_id = SYM2ID(rb_str_intern(method_name)); - } else { - mod = rb_mKernel; - method_id = SYM2ID(rb_str_intern(name)); - } - } - - long len = p - json->memo; - fbuffer_clear(json->fbuffer); - fbuffer_append(json->fbuffer, json->memo, len); - fbuffer_append_char(json->fbuffer, '\0'); - - if (method_id) { - VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcallv(mod, method_id, 1, &text); - } else { - *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); - } - - return p + 1; - } else { - return NULL; - } -} - - - -enum {JSON_array_start = 1}; -enum {JSON_array_first_final = 17}; -enum {JSON_array_error = 0}; - -enum {JSON_array_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_array_nfa_targs)[] = { - 0, 0 -}; + while (positions->size) { + positions->size--; + const char *next_position = positions->positions[0]; + positions->positions++; + if (next_position >= pe) { + return next_position; + } + } + + if (positions->additional_backslashes) { + positions->additional_backslashes--; + return memchr(pe, '\\', stringEnd - pe); + } + + return NULL; +} -static const char MAYBE_UNUSED(_JSON_array_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0 -}; +NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_ParserConfig *config, const char *string, const char *stringEnd, bool is_name, JSON_UnescapePositions *positions) +{ + bool intern = is_name || config->freeze; + bool symbolize = is_name && config->symbolize_names; + size_t bufferSize = stringEnd - string; + const char *p = string, *pe = string, *bufferStart; + char *buffer; + + VALUE result = rb_str_buf_new(bufferSize); + rb_enc_associate_index(result, utf8_encindex); + buffer = RSTRING_PTR(result); + bufferStart = buffer; + +#define APPEND_CHAR(chr) *buffer++ = chr; p = ++pe; + + while (pe < stringEnd && (pe = json_next_backslash(pe, stringEnd, positions))) { + if (pe > p) { + MEMCPY(buffer, p, char, pe - p); + buffer += pe - p; + } + switch (*++pe) { + case '"': + case '/': + p = pe; // nothing to unescape just need to skip the backslash + break; + case '\\': + APPEND_CHAR('\\'); + break; + case 'n': + APPEND_CHAR('\n'); + break; + case 'r': + APPEND_CHAR('\r'); + break; + case 't': + APPEND_CHAR('\t'); + break; + case 'b': + APPEND_CHAR('\b'); + break; + case 'f': + APPEND_CHAR('\f'); + break; + case 'u': { + uint32_t ch = unescape_unicode(state, ++pe, stringEnd); + pe += 3; + /* To handle values above U+FFFF, we take a sequence of + * \uXXXX escapes in the U+D800..U+DBFF then + * U+DC00..U+DFFF ranges, take the low 10 bits from each + * to make a 20-bit number, then add 0x10000 to get the + * final codepoint. + * + * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling + * Surrogate Pairs in UTF-16", and 23.6 "Surrogates + * Area". + */ + if ((ch & 0xFC00) == 0xD800) { + pe++; + if (RB_LIKELY((pe <= stringEnd - 6) && memcmp(pe, "\\u", 2) == 0)) { + uint32_t sur = unescape_unicode(state, pe + 2, stringEnd); + + if (RB_UNLIKELY((sur & 0xFC00) != 0xDC00)) { + raise_parse_error_at("invalid surrogate pair at %s", state, p); + } + + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) | (sur & 0x3FF)); + pe += 5; + } else { + raise_parse_error_at("incomplete surrogate pair at %s", state, p); + break; + } + } + + int unescape_len = convert_UTF32_to_UTF8(buffer, ch); + buffer += unescape_len; + p = ++pe; + break; + } + default: + if ((unsigned char)*pe < 0x20) { + if (!config->allow_control_characters) { + if (*pe == '\n') { + raise_parse_error_at("Invalid unescaped newline character (\\n) in string: %s", state, pe - 1); + } + raise_parse_error_at("invalid ASCII control character in string: %s", state, pe - 1); + } + } else { + raise_parse_error_at("invalid escape character in string: %s", state, pe - 1); + } + break; + } + } +#undef APPEND_CHAR + + if (stringEnd > p) { + MEMCPY(buffer, p, char, stringEnd - p); + buffer += stringEnd - p; + } + rb_str_set_len(result, buffer - bufferStart); + + if (symbolize) { + result = rb_str_intern(result); + } else if (intern) { + result = rb_str_to_interned_str(result); + } + + return result; +} -static const char MAYBE_UNUSED(_JSON_array_nfa_push_actions)[] = { - 0, 0 -}; +#define MAX_FAST_INTEGER_SIZE 18 -static const char MAYBE_UNUSED(_JSON_array_nfa_pop_trans)[] = { - 0, 0 -}; +static VALUE json_decode_large_integer(const char *start, long len) +{ + VALUE buffer_v; + char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1); + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + VALUE number = rb_cstr2inum(buffer, 10); + RB_ALLOCV_END(buffer_v); + return number; +} +static inline VALUE +json_decode_integer(uint64_t mantissa, int mantissa_digits, bool negative, const char *start, const char *end) +{ + if (RB_LIKELY(mantissa_digits < MAX_FAST_INTEGER_SIZE)) { + if (negative) { + return INT64T2NUM(-((int64_t)mantissa)); + } + return UINT64T2NUM(mantissa); + } + + return json_decode_large_integer(start, end - start); +} -#line 432 "parser.rl" +static VALUE json_decode_large_float(const char *start, long len) +{ + if (RB_LIKELY(len < 64)) { + char buffer[64]; + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + return DBL2NUM(rb_cstr_to_dbl(buffer, 1)); + } + + VALUE buffer_v; + char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1); + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 1)); + RB_ALLOCV_END(buffer_v); + return number; +} +/* Ruby JSON optimized float decoder using vendored Ryu algorithm + * Accepts pre-extracted mantissa and exponent from first-pass validation + */ +static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int32_t exponent, bool negative, + const char *start, const char *end) +{ + if (RB_UNLIKELY(config->decimal_class)) { + VALUE text = rb_str_new(start, end - start); + return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text); + } + + // Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case) + // Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308) + if (RB_UNLIKELY(mantissa_digits > 17 || mantissa_digits + exponent < -307)) { + return json_decode_large_float(start, end - start); + } + + return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, exponent, negative)); +} -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) +static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count) { - int cs = EVIL; - VALUE array_class = json->array_class; - - if (json->max_nesting && current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); - } - *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); - - - { - cs = (int)JSON_array_start; - } - - #line 445 "parser.rl" - - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 7: - goto st_case_7; - case 8: - goto st_case_8; - case 9: - goto st_case_9; - case 10: - goto st_case_10; - case 11: - goto st_case_11; - case 12: - goto st_case_12; - case 17: - goto st_case_17; - case 13: - goto st_case_13; - case 14: - goto st_case_14; - case 15: - goto st_case_15; - case 16: - goto st_case_16; - } - goto st_out; - st_case_1: - if ( ( (*( p))) == 91 ) { - goto st2; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - switch( ( (*( p))) ) { - case 13: { - goto st2; - } - case 32: { - goto st2; - } - case 34: { - goto ctr2; - } - case 45: { - goto ctr2; - } - case 47: { - goto st13; - } - case 73: { - goto ctr2; - } - case 78: { - goto ctr2; - } - case 91: { - goto ctr2; - } - case 93: { - goto ctr4; - } - case 102: { - goto ctr2; - } - case 110: { - goto ctr2; - } - case 116: { - goto ctr2; - } - case 123: { - goto ctr2; - } - } - if ( ( (*( p))) > 10 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto ctr2; - } - } else if ( ( (*( p))) >= 9 ) { - goto st2; - } - { - goto st0; - } - ctr2: - { - #line 409 "parser.rl" - - VALUE v = Qnil; - char *np = JSON_parse_value(json, p, pe, &v, current_nesting); - if (np == NULL) { - {p = p - 1; } {p+= 1; cs = 3; goto _out;} - } else { - if (NIL_P(json->array_class)) { - rb_ary_push(*result, v); - } else { - rb_funcall(*result, i_leftshift, 1, v); - } - {p = (( np))-1;} - - } - } - - goto st3; - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - switch( ( (*( p))) ) { - case 13: { - goto st3; - } - case 32: { - goto st3; - } - case 44: { - goto st4; - } - case 47: { - goto st9; - } - case 93: { - goto ctr4; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st3; - } - { - goto st0; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - switch( ( (*( p))) ) { - case 13: { - goto st4; - } - case 32: { - goto st4; - } - case 34: { - goto ctr2; - } - case 45: { - goto ctr2; - } - case 47: { - goto st5; - } - case 73: { - goto ctr2; - } - case 78: { - goto ctr2; - } - case 91: { - goto ctr2; - } - case 102: { - goto ctr2; - } - case 110: { - goto ctr2; - } - case 116: { - goto ctr2; - } - case 123: { - goto ctr2; - } - } - if ( ( (*( p))) > 10 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto ctr2; - } - } else if ( ( (*( p))) >= 9 ) { - goto st4; - } - { - goto st0; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - switch( ( (*( p))) ) { - case 42: { - goto st6; - } - case 47: { - goto st8; - } - } - { - goto st0; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - if ( ( (*( p))) == 42 ) { - goto st7; - } - { - goto st6; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - switch( ( (*( p))) ) { - case 42: { - goto st7; - } - case 47: { - goto st4; - } - } - { - goto st6; - } - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - if ( ( (*( p))) == 10 ) { - goto st4; - } - { - goto st8; - } - st9: - p+= 1; - if ( p == pe ) - goto _test_eof9; - st_case_9: - switch( ( (*( p))) ) { - case 42: { - goto st10; - } - case 47: { - goto st12; - } - } - { - goto st0; - } - st10: - p+= 1; - if ( p == pe ) - goto _test_eof10; - st_case_10: - if ( ( (*( p))) == 42 ) { - goto st11; - } - { - goto st10; - } - st11: - p+= 1; - if ( p == pe ) - goto _test_eof11; - st_case_11: - switch( ( (*( p))) ) { - case 42: { - goto st11; - } - case 47: { - goto st3; - } - } - { - goto st10; - } - st12: - p+= 1; - if ( p == pe ) - goto _test_eof12; - st_case_12: - if ( ( (*( p))) == 10 ) { - goto st3; - } - { - goto st12; - } - ctr4: - { - #line 424 "parser.rl" - {p = p - 1; } {p+= 1; cs = 17; goto _out;} } - - goto st17; - st17: - p+= 1; - if ( p == pe ) - goto _test_eof17; - st_case_17: - { - goto st0; - } - st13: - p+= 1; - if ( p == pe ) - goto _test_eof13; - st_case_13: - switch( ( (*( p))) ) { - case 42: { - goto st14; - } - case 47: { - goto st16; - } - } - { - goto st0; - } - st14: - p+= 1; - if ( p == pe ) - goto _test_eof14; - st_case_14: - if ( ( (*( p))) == 42 ) { - goto st15; - } - { - goto st14; - } - st15: - p+= 1; - if ( p == pe ) - goto _test_eof15; - st_case_15: - switch( ( (*( p))) ) { - case 42: { - goto st15; - } - case 47: { - goto st2; - } - } - { - goto st14; - } - st16: - p+= 1; - if ( p == pe ) - goto _test_eof16; - st_case_16: - if ( ( (*( p))) == 10 ) { - goto st2; - } - { - goto st16; - } - st_out: - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 446 "parser.rl" - - - if(cs >= JSON_array_first_final) { - return p + 1; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return NULL; - } -} - -static const size_t MAX_STACK_BUFFER_SIZE = 128; -static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize) + VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(state->stack, count)); + rvalue_stack_pop(state->stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(array); + } + + return array; +} + +static VALUE json_find_duplicated_key(size_t count, const VALUE *pairs) { - VALUE result = Qnil; - size_t bufferSize = stringEnd - string; - char *p = string, *pe = string, *unescape, *bufferStart, *buffer; - int unescape_len; - char buf[4]; - - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - bufferStart = buffer = ALLOC_N(char, bufferSize); - } else { - bufferStart = buffer = ALLOCA_N(char, bufferSize); - } - - while (pe < stringEnd) { - if (*pe == '\\') { - unescape = (char *) "?"; - unescape_len = 1; - if (pe > p) { - MEMCPY(buffer, p, char, pe - p); - buffer += pe - p; - } - switch (*++pe) { - case 'n': - unescape = (char *) "\n"; - break; - case 'r': - unescape = (char *) "\r"; - break; - case 't': - unescape = (char *) "\t"; - break; - case '"': - unescape = (char *) "\""; - break; - case '\\': - unescape = (char *) "\\"; - break; - case 'b': - unescape = (char *) "\b"; - break; - case 'f': - unescape = (char *) "\f"; - break; - case 'u': - if (pe > stringEnd - 4) { - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - rb_enc_raise( - EXC_ENCODING eParserError, - "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p - ); - } else { - UTF32 ch = unescape_unicode((unsigned char *) ++pe); - pe += 3; - if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { - pe++; - if (pe > stringEnd - 6) { - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - rb_enc_raise( - EXC_ENCODING eParserError, - "%u: incomplete surrogate pair at '%s'", __LINE__, p - ); - } - if (pe[0] == '\\' && pe[1] == 'u') { - UTF32 sur = unescape_unicode((unsigned char *) pe + 2); - ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) - | (sur & 0x3FF)); - pe += 5; - } else { - unescape = (char *) "?"; - break; - } - } - unescape_len = convert_UTF32_to_UTF8(buf, ch); - unescape = buf; - } - break; - default: - p = pe; - continue; - } - MEMCPY(buffer, unescape, char, unescape_len); - buffer += unescape_len; - p = ++pe; - } else { - pe++; - } - } - - if (pe > p) { - MEMCPY(buffer, p, char, pe - p); - buffer += pe - p; - } - - # ifdef HAVE_RB_ENC_INTERNED_STR - if (intern) { - result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding()); - } else { - result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart)); - } - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - # else - result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart)); - - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - - if (intern) { - # if STR_UMINUS_DEDUPE_FROZEN - // Starting from MRI 2.8 it is preferable to freeze the string - // before deduplication so that it can be interned directly - // otherwise it would be duplicated first which is wasteful. - result = rb_funcall(rb_str_freeze(result), i_uminus, 0); - # elif STR_UMINUS_DEDUPE - // MRI 2.5 and older do not deduplicate strings that are already - // frozen. - result = rb_funcall(result, i_uminus, 0); - # else - result = rb_str_freeze(result); - # endif - } - # endif - - if (symbolize) { - result = rb_str_intern(result); - } - - return result; -} - - -enum {JSON_string_start = 1}; -enum {JSON_string_first_final = 8}; -enum {JSON_string_error = 0}; - -enum {JSON_string_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_string_nfa_targs)[] = { - 0, 0 -}; + VALUE set = rb_hash_new_capa(count / 2); + for (size_t index = 0; index < count; index += 2) { + size_t before = RHASH_SIZE(set); + VALUE key = pairs[index]; + rb_hash_aset(set, key, Qtrue); + if (RHASH_SIZE(set) == before) { + if (RB_SYMBOL_P(key)) { + return rb_sym2str(key); + } + return key; + } + } + return Qfalse; +} -static const char MAYBE_UNUSED(_JSON_string_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; +static void emit_duplicate_key_warning(JSON_ParserState *state, VALUE duplicate_key) +{ + VALUE message = rb_sprintf( + "detected duplicate key %"PRIsVALUE" in JSON object. This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`", + rb_inspect(duplicate_key) + ); -static const char MAYBE_UNUSED(_JSON_string_nfa_push_actions)[] = { - 0, 0 -}; + emit_parse_warning(RSTRING_PTR(message), state); + RB_GC_GUARD(message); +} + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_key) +{ + VALUE message = rb_sprintf( + "duplicate key %"PRIsVALUE, + rb_inspect(duplicate_key) + ); + + raise_parse_error(RSTRING_PTR(message), state); + RB_GC_GUARD(message); +} + +static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, size_t count) +{ + size_t entries_count = count / 2; + VALUE object = rb_hash_new_capa(entries_count); + const VALUE *pairs = rvalue_stack_peek(state->stack, count); + rb_hash_bulk_insert(count, pairs, object); + + if (RB_UNLIKELY(RHASH_SIZE(object) < entries_count)) { + switch (config->on_duplicate_key) { + case JSON_IGNORE: + break; + case JSON_DEPRECATED: + emit_duplicate_key_warning(state, json_find_duplicated_key(count, pairs)); + break; + case JSON_RAISE: + raise_duplicate_key_error(state, json_find_duplicated_key(count, pairs)); + break; + } + } + + rvalue_stack_pop(state->stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(object); + } + + return object; +} + +static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *config, VALUE value) +{ + if (RB_UNLIKELY(config->on_load_proc)) { + value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil); + } + rvalue_stack_push(state->stack, value, &state->stack_handle, &state->stack); + return value; +} -static const char MAYBE_UNUSED(_JSON_string_nfa_pop_trans)[] = { - 0, 0 +static const bool string_scan_table[256] = { + // ASCII Control Characters + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // ASCII Characters + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +#ifdef HAVE_SIMD +static SIMD_Implementation simd_impl = SIMD_NONE; +#endif /* HAVE_SIMD */ + +ALWAYS_INLINE(static) bool string_scan(JSON_ParserState *state) +{ +#ifdef HAVE_SIMD +#if defined(HAVE_SIMD_NEON) + + uint64_t mask = 0; + if (string_scan_simd_neon(&state->cursor, state->end, &mask)) { + state->cursor += trailing_zeros64(mask) >> 2; + return true; + } + +#elif defined(HAVE_SIMD_SSE2) + if (simd_impl == SIMD_SSE2) { + int mask = 0; + if (string_scan_simd_sse2(&state->cursor, state->end, &mask)) { + state->cursor += trailing_zeros(mask); + return true; + } + } +#endif /* HAVE_SIMD_NEON or HAVE_SIMD_SSE2 */ +#endif /* HAVE_SIMD */ + + while (!eos(state)) { + if (RB_UNLIKELY(string_scan_table[(unsigned char)*state->cursor])) { + return true; + } + state->cursor++; + } + return false; +} + +static VALUE json_parse_escaped_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name, const char *start) +{ + const char *backslashes[JSON_MAX_UNESCAPE_POSITIONS]; + JSON_UnescapePositions positions = { + .size = 0, + .positions = backslashes, + .additional_backslashes = 0, + }; + + do { + switch (*state->cursor) { + case '"': { + VALUE string = json_string_unescape(state, config, start, state->cursor, is_name, &positions); + state->cursor++; + return json_push_value(state, config, string); + } + case '\\': { + if (RB_LIKELY(positions.size < JSON_MAX_UNESCAPE_POSITIONS)) { + backslashes[positions.size] = state->cursor; + positions.size++; + } else { + positions.additional_backslashes++; + } + state->cursor++; + break; + } + default: + if (!config->allow_control_characters) { + raise_parse_error("invalid ASCII control character in string: %s", state); + } + break; + } + + state->cursor++; + } while (string_scan(state)); + + raise_parse_error("unexpected end of input, expected closing \"", state); + return Qfalse; +} + +ALWAYS_INLINE(static) VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name) +{ + state->cursor++; + const char *start = state->cursor; + + if (RB_UNLIKELY(!string_scan(state))) { + raise_parse_error("unexpected end of input, expected closing \"", state); + } + + if (RB_LIKELY(*state->cursor == '"')) { + VALUE string = json_string_fastpath(state, config, start, state->cursor, is_name); + state->cursor++; + return json_push_value(state, config, string); + } + return json_parse_escaped_string(state, config, is_name, start); +} + +#if JSON_CPU_LITTLE_ENDIAN_64BITS +// From: https://lemire.me/blog/2022/01/21/swar-explained-parsing-eight-digits/ +// Additional References: +// https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +// http://0x80.pl/notesen/2014-10-12-parsing-decimal-numbers-part-1-swar.html +static inline uint64_t decode_8digits_unrolled(uint64_t val) { + const uint64_t mask = 0x000000FF000000FF; + const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32) + const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32) + val -= 0x3030303030303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32; + return val; +} + +static inline uint64_t decode_4digits_unrolled(uint32_t val) { + const uint32_t mask = 0x000000FF; + const uint32_t mul1 = 100; + val -= 0x30303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = ((val & mask) * mul1) + (((val >> 16) & mask)); + return val; +} +#endif + +static inline int json_parse_digits(JSON_ParserState *state, uint64_t *accumulator) +{ + const char *start = state->cursor; + +#if JSON_CPU_LITTLE_ENDIAN_64BITS + while (rest(state) >= sizeof(uint64_t)) { + uint64_t next_8bytes; + memcpy(&next_8bytes, state->cursor, sizeof(uint64_t)); + + // From: https://github.com/simdjson/simdjson/blob/32b301893c13d058095a07d9868edaaa42ee07aa/include/simdjson/generic/numberparsing.h#L333 + // Branchless version of: http://0x80.pl/articles/swar-digits-validate.html + uint64_t match = (next_8bytes & 0xF0F0F0F0F0F0F0F0) | (((next_8bytes + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4); + + if (match == 0x3333333333333333) { // 8 consecutive digits + *accumulator = (*accumulator * 100000000) + decode_8digits_unrolled(next_8bytes); + state->cursor += 8; + continue; + } + + uint32_t consecutive_digits = trailing_zeros64(match ^ 0x3333333333333333) / CHAR_BIT; + + if (consecutive_digits >= 4) { + *accumulator = (*accumulator * 10000) + decode_4digits_unrolled((uint32_t)next_8bytes); + state->cursor += 4; + consecutive_digits -= 4; + } + + while (consecutive_digits) { + *accumulator = *accumulator * 10 + (*state->cursor - '0'); + consecutive_digits--; + state->cursor++; + } + + return (int)(state->cursor - start); + } +#endif + + char next_char; + while (rb_isdigit(next_char = peek(state))) { + *accumulator = *accumulator * 10 + (next_char - '0'); + state->cursor++; + } + return (int)(state->cursor - start); +} + +static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig *config, bool negative, const char *start) +{ + bool integer = true; + const char first_digit = *state->cursor; + + // Variables for Ryu optimization - extract digits during parsing + int32_t exponent = 0; + int decimal_point_pos = -1; + uint64_t mantissa = 0; + + // Parse integer part and extract mantissa digits + int mantissa_digits = json_parse_digits(state, &mantissa); + + if (RB_UNLIKELY((first_digit == '0' && mantissa_digits > 1) || (negative && mantissa_digits == 0))) { + raise_parse_error_at("invalid number: %s", state, start); + } + + // Parse fractional part + if (peek(state) == '.') { + integer = false; + decimal_point_pos = mantissa_digits; // Remember position of decimal point + state->cursor++; + + int fractional_digits = json_parse_digits(state, &mantissa); + mantissa_digits += fractional_digits; + + if (RB_UNLIKELY(!fractional_digits)) { + raise_parse_error_at("invalid number: %s", state, start); + } + } + + // Parse exponent + if (rb_tolower(peek(state)) == 'e') { + integer = false; + state->cursor++; + + bool negative_exponent = false; + const char next_char = peek(state); + if (next_char == '-' || next_char == '+') { + negative_exponent = next_char == '-'; + state->cursor++; + } + + uint64_t abs_exponent = 0; + int exponent_digits = json_parse_digits(state, &abs_exponent); + + if (RB_UNLIKELY(!exponent_digits)) { + raise_parse_error_at("invalid number: %s", state, start); + } + + exponent = negative_exponent ? -((int32_t)abs_exponent) : ((int32_t)abs_exponent); + } + + if (integer) { + return json_decode_integer(mantissa, mantissa_digits, negative, start, state->cursor); + } + + // Adjust exponent based on decimal point position + if (decimal_point_pos >= 0) { + exponent -= (mantissa_digits - decimal_point_pos); + } + + return json_decode_float(config, mantissa, mantissa_digits, exponent, negative, start, state->cursor); +} -#line 612 "parser.rl" +static inline VALUE json_parse_positive_number(JSON_ParserState *state, JSON_ParserConfig *config) +{ + return json_parse_number(state, config, false, state->cursor); +} +static inline VALUE json_parse_negative_number(JSON_ParserState *state, JSON_ParserConfig *config) +{ + const char *start = state->cursor; + state->cursor++; + return json_parse_number(state, config, true, start); +} -static int -match_i(VALUE regexp, VALUE klass, VALUE memo) +static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) { - if (regexp == Qundef) return ST_STOP; - if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) && - RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) { - rb_ary_push(memo, klass); - return ST_STOP; - } - return ST_CONTINUE; + json_eat_whitespace(state); + + switch (peek(state)) { + case 'n': + if (rest(state) >= 4 && (memcmp(state->cursor, "null", 4) == 0)) { + state->cursor += 4; + return json_push_value(state, config, Qnil); + } + + raise_parse_error("unexpected token %s", state); + break; + case 't': + if (rest(state) >= 4 && (memcmp(state->cursor, "true", 4) == 0)) { + state->cursor += 4; + return json_push_value(state, config, Qtrue); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'f': + // Note: memcmp with a small power of two compile to an integer comparison + if (rest(state) >= 5 && (memcmp(state->cursor + 1, "alse", 4) == 0)) { + state->cursor += 5; + return json_push_value(state, config, Qfalse); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'N': + // Note: memcmp with a small power of two compile to an integer comparison + if (config->allow_nan && rest(state) >= 3 && (memcmp(state->cursor + 1, "aN", 2) == 0)) { + state->cursor += 3; + return json_push_value(state, config, CNaN); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'I': + if (config->allow_nan && rest(state) >= 8 && (memcmp(state->cursor, "Infinity", 8) == 0)) { + state->cursor += 8; + return json_push_value(state, config, CInfinity); + } + + raise_parse_error("unexpected token %s", state); + break; + case '-': { + // Note: memcmp with a small power of two compile to an integer comparison + if (rest(state) >= 9 && (memcmp(state->cursor + 1, "Infinity", 8) == 0)) { + if (config->allow_nan) { + state->cursor += 9; + return json_push_value(state, config, CMinusInfinity); + } else { + raise_parse_error("unexpected token %s", state); + } + } + return json_push_value(state, config, json_parse_negative_number(state, config)); + break; + } + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + return json_push_value(state, config, json_parse_positive_number(state, config)); + break; + case '"': { + // %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"} + return json_parse_string(state, config, false); + break; + } + case '[': { + state->cursor++; + json_eat_whitespace(state); + long stack_head = state->stack->head; + + if (peek(state) == ']') { + state->cursor++; + return json_push_value(state, config, json_decode_array(state, config, 0)); + } else { + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + state->in_array++; + json_parse_any(state, config); + } + + while (true) { + json_eat_whitespace(state); + + const char next_char = peek(state); + + if (RB_LIKELY(next_char == ',')) { + state->cursor++; + if (config->allow_trailing_comma) { + json_eat_whitespace(state); + if (peek(state) == ']') { + continue; + } + } + json_parse_any(state, config); + continue; + } + + if (next_char == ']') { + state->cursor++; + long count = state->stack->head - stack_head; + state->current_nesting--; + state->in_array--; + return json_push_value(state, config, json_decode_array(state, config, count)); + } + + raise_parse_error("expected ',' or ']' after array value", state); + } + break; + } + case '{': { + const char *object_start_cursor = state->cursor; + + state->cursor++; + json_eat_whitespace(state); + long stack_head = state->stack->head; + + if (peek(state) == '}') { + state->cursor++; + return json_push_value(state, config, json_decode_object(state, config, 0)); + } else { + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + + if (peek(state) != '"') { + raise_parse_error("expected object key, got %s", state); + } + json_parse_string(state, config, true); + + json_eat_whitespace(state); + if (peek(state) != ':') { + raise_parse_error("expected ':' after object key", state); + } + state->cursor++; + + json_parse_any(state, config); + } + + while (true) { + json_eat_whitespace(state); + + const char next_char = peek(state); + if (next_char == '}') { + state->cursor++; + state->current_nesting--; + size_t count = state->stack->head - stack_head; + + // Temporary rewind cursor in case an error is raised + const char *final_cursor = state->cursor; + state->cursor = object_start_cursor; + VALUE object = json_decode_object(state, config, count); + state->cursor = final_cursor; + + return json_push_value(state, config, object); + } + + if (next_char == ',') { + state->cursor++; + json_eat_whitespace(state); + + if (config->allow_trailing_comma) { + if (peek(state) == '}') { + continue; + } + } + + if (RB_UNLIKELY(peek(state) != '"')) { + raise_parse_error("expected object key, got: %s", state); + } + json_parse_string(state, config, true); + + json_eat_whitespace(state); + if (RB_UNLIKELY(peek(state) != ':')) { + raise_parse_error("expected ':' after object key, got: %s", state); + } + state->cursor++; + + json_parse_any(state, config); + + continue; + } + + raise_parse_error("expected ',' or '}' after object value, got: %s", state); + } + break; + } + + case 0: + raise_parse_error("unexpected end of input", state); + break; + + default: + raise_parse_error("unexpected character: %s", state); + break; + } + + raise_parse_error("unreachable: %s", state); + return Qundef; } -static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result) +static void json_ensure_eof(JSON_ParserState *state) { - int cs = EVIL; - VALUE match_string; - - - { - cs = (int)JSON_string_start; - } - - #line 632 "parser.rl" - - json->memo = p; - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 2: - goto st_case_2; - case 8: - goto st_case_8; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 7: - goto st_case_7; - } - goto st_out; - st_case_1: - if ( ( (*( p))) == 34 ) { - goto st2; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - switch( ( (*( p))) ) { - case 34: { - goto ctr2; - } - case 92: { - goto st3; - } - } - if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 ) { - goto st0; - } - { - goto st2; - } - ctr2: - { - #line 599 "parser.rl" - - *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names); - if (NIL_P(*result)) { - {p = p - 1; } - {p+= 1; cs = 8; goto _out;} - } else { - {p = (( p + 1))-1;} - - } - } - { - #line 609 "parser.rl" - {p = p - 1; } {p+= 1; cs = 8; goto _out;} } - - goto st8; - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - { - goto st0; - } - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - if ( ( (*( p))) == 117 ) { - goto st4; - } - if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 ) { - goto st0; - } - { - goto st2; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - if ( ( (*( p))) < 65 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st5; - } - } else if ( ( (*( p))) > 70 ) { - if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) { - goto st5; - } - } else { - goto st5; - } - { - goto st0; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - if ( ( (*( p))) < 65 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st6; - } - } else if ( ( (*( p))) > 70 ) { - if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) { - goto st6; - } - } else { - goto st6; - } - { - goto st0; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - if ( ( (*( p))) < 65 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st7; - } - } else if ( ( (*( p))) > 70 ) { - if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) { - goto st7; - } - } else { - goto st7; - } - { - goto st0; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - if ( ( (*( p))) < 65 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto st2; - } - } else if ( ( (*( p))) > 70 ) { - if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) { - goto st2; - } - } else { - goto st2; - } - { - goto st0; - } - st_out: - _test_eof2: cs = 2; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 634 "parser.rl" - - - if (json->create_additions && RTEST(match_string = json->match_string)) { - VALUE klass; - VALUE memo = rb_ary_new2(2); - rb_ary_push(memo, *result); - rb_hash_foreach(match_string, match_i, memo); - klass = rb_ary_entry(memo, 1); - if (RTEST(klass)) { - *result = rb_funcall(klass, i_json_create, 1, *result); - } - } - - if (cs >= JSON_string_first_final) { - return p + 1; - } else { - return NULL; - } + json_eat_whitespace(state); + if (!eos(state)) { + raise_parse_error("unexpected token at end of stream %s", state); + } } /* -* Document-class: JSON::Ext::Parser -* -* This is the JSON parser implemented as a C extension. It can be configured -* to be used by setting -* -* JSON.parser = JSON::Ext::Parser -* -* with the method parser= in JSON. -* -*/ + * Document-class: JSON::Ext::Parser + * + * This is the JSON parser implemented as a C extension. It can be configured + * to be used by setting + * + * JSON.parser = JSON::Ext::Parser + * + * with the method parser= in JSON. + * + */ static VALUE convert_encoding(VALUE source) { - #ifdef HAVE_RUBY_ENCODING_H - rb_encoding *enc = rb_enc_get(source); - if (enc == rb_ascii8bit_encoding()) { - if (OBJ_FROZEN(source)) { - source = rb_str_dup(source); - } - FORCE_UTF8(source); - } else { - source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); - } - #endif - return source; + int encindex = RB_ENCODING_GET(source); + + if (RB_LIKELY(encindex == utf8_encindex)) { + return source; + } + + if (encindex == binary_encindex) { + // For historical reason, we silently reinterpret binary strings as UTF-8 + return rb_enc_associate_index(rb_str_dup(source), utf8_encindex); + } + + return rb_funcall(source, i_encode, 1, Encoding_UTF_8); +} + +static int parser_config_init_i(VALUE key, VALUE val, VALUE data) +{ + JSON_ParserConfig *config = (JSON_ParserConfig *)data; + + if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; } + else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); } + else if (key == sym_allow_trailing_comma) { config->allow_trailing_comma = RTEST(val); } + else if (key == sym_allow_control_characters) { config->allow_control_characters = RTEST(val); } + else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); } + else if (key == sym_freeze) { config->freeze = RTEST(val); } + else if (key == sym_on_load) { config->on_load_proc = RTEST(val) ? val : Qfalse; } + else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } + else if (key == sym_decimal_class) { + if (RTEST(val)) { + if (rb_respond_to(val, i_try_convert)) { + config->decimal_class = val; + config->decimal_method_id = i_try_convert; + } else if (rb_respond_to(val, i_new)) { + config->decimal_class = val; + config->decimal_method_id = i_new; + } else if (RB_TYPE_P(val, T_CLASS)) { + VALUE name = rb_class_name(val); + const char *name_cstr = RSTRING_PTR(name); + const char *last_colon = strrchr(name_cstr, ':'); + if (last_colon) { + const char *mod_path_end = last_colon - 1; + VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); + config->decimal_class = rb_path_to_class(mod_path); + + const char *method_name_beg = last_colon + 1; + long before_len = method_name_beg - name_cstr; + long len = RSTRING_LEN(name) - before_len; + VALUE method_name = rb_str_substr(name, before_len, len); + config->decimal_method_id = SYM2ID(rb_str_intern(method_name)); + } else { + config->decimal_class = rb_mKernel; + config->decimal_method_id = SYM2ID(rb_str_intern(name)); + } + } + } + } + + return ST_CONTINUE; +} + +static void parser_config_init(JSON_ParserConfig *config, VALUE opts) +{ + config->max_nesting = 100; + + if (!NIL_P(opts)) { + Check_Type(opts, T_HASH); + if (RHASH_SIZE(opts) > 0) { + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(opts, parser_config_init_i, (VALUE)config); + } + + } } /* -* call-seq: new(source, opts => {}) -* -* Creates a new JSON::Ext::Parser instance for the string _source_. -* -* Creates a new JSON::Ext::Parser instance for the string _source_. -* -* It will be configured by the _opts_ hash. _opts_ can have the following -* keys: -* -* _opts_ can have the following keys: -* * *max_nesting*: The maximum depth of nesting allowed in the parsed data -* structures. Disable depth checking with :max_nesting => false|nil|0, it -* defaults to 100. -* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in -* defiance of RFC 4627 to be parsed by the Parser. This option defaults to -* false. -* * *symbolize_names*: If set to true, returns symbols for the names -* (keys) in a JSON object. Otherwise strings are returned, which is -* also the default. It's not possible to use this option in -* conjunction with the *create_additions* option. -* * *create_additions*: If set to false, the Parser doesn't create -* additions even if a matching class and create_id was found. This option -* defaults to false. -* * *object_class*: Defaults to Hash -* * *array_class*: Defaults to Array -*/ -static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) + * call-seq: new(opts => {}) + * + * Creates a new JSON::Ext::ParserConfig instance. + * + * It will be configured by the _opts_ hash. _opts_ can have the following + * keys: + * + * _opts_ can have the following keys: + * * *max_nesting*: The maximum depth of nesting allowed in the parsed data + * structures. Disable depth checking with :max_nesting => false|nil|0, it + * defaults to 100. + * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in + * defiance of RFC 4627 to be parsed by the Parser. This option defaults to + * false. + * * *symbolize_names*: If set to true, returns symbols for the names + * (keys) in a JSON object. Otherwise strings are returned, which is + * also the default. It's not possible to use this option in + * conjunction with the *create_additions* option. + * * *decimal_class*: Specifies which class to use instead of the default + * (Float) when parsing decimal numbers. This class must accept a single + * string argument in its constructor. + */ +static VALUE cParserConfig_initialize(VALUE self, VALUE opts) { - VALUE source, opts; - GET_PARSER_INIT; - - if (json->Vsource) { - rb_raise(rb_eTypeError, "already initialized instance"); - } - #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - rb_scan_args(argc, argv, "1:", &source, &opts); - #else - rb_scan_args(argc, argv, "11", &source, &opts); - #endif - if (!NIL_P(opts)) { - #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); - if (NIL_P(opts)) { - rb_raise(rb_eArgError, "opts needs to be like a hash"); - } else { - #endif - VALUE tmp = ID2SYM(i_max_nesting); - if (option_given_p(opts, tmp)) { - VALUE max_nesting = rb_hash_aref(opts, tmp); - if (RTEST(max_nesting)) { - Check_Type(max_nesting, T_FIXNUM); - json->max_nesting = FIX2INT(max_nesting); - } else { - json->max_nesting = 0; - } - } else { - json->max_nesting = 100; - } - tmp = ID2SYM(i_allow_nan); - if (option_given_p(opts, tmp)) { - json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->allow_nan = 0; - } - tmp = ID2SYM(i_symbolize_names); - if (option_given_p(opts, tmp)) { - json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->symbolize_names = 0; - } - tmp = ID2SYM(i_freeze); - if (option_given_p(opts, tmp)) { - json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->freeze = 0; - } - tmp = ID2SYM(i_create_additions); - if (option_given_p(opts, tmp)) { - json->create_additions = RTEST(rb_hash_aref(opts, tmp)); - } else { - json->create_additions = 0; - } - if (json->symbolize_names && json->create_additions) { - rb_raise(rb_eArgError, - "options :symbolize_names and :create_additions cannot be " - " used in conjunction"); - } - tmp = ID2SYM(i_create_id); - if (option_given_p(opts, tmp)) { - json->create_id = rb_hash_aref(opts, tmp); - } else { - json->create_id = rb_funcall(mJSON, i_create_id, 0); - } - tmp = ID2SYM(i_object_class); - if (option_given_p(opts, tmp)) { - json->object_class = rb_hash_aref(opts, tmp); - } else { - json->object_class = Qnil; - } - tmp = ID2SYM(i_array_class); - if (option_given_p(opts, tmp)) { - json->array_class = rb_hash_aref(opts, tmp); - } else { - json->array_class = Qnil; - } - tmp = ID2SYM(i_decimal_class); - if (option_given_p(opts, tmp)) { - json->decimal_class = rb_hash_aref(opts, tmp); - } else { - json->decimal_class = Qnil; - } - tmp = ID2SYM(i_match_string); - if (option_given_p(opts, tmp)) { - VALUE match_string = rb_hash_aref(opts, tmp); - json->match_string = RTEST(match_string) ? match_string : Qnil; - } else { - json->match_string = Qnil; - } - #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - } - #endif - } else { - json->max_nesting = 100; - json->allow_nan = 0; - json->create_additions = 0; - json->create_id = rb_funcall(mJSON, i_create_id, 0); - json->object_class = Qnil; - json->array_class = Qnil; - json->decimal_class = Qnil; - } - source = convert_encoding(StringValue(source)); - StringValue(source); - json->len = RSTRING_LEN(source); - json->source = RSTRING_PTR(source);; - json->Vsource = source; - return self; -} - - -enum {JSON_start = 1}; -enum {JSON_first_final = 10}; -enum {JSON_error = 0}; - -enum {JSON_en_main = 1}; - -static const char MAYBE_UNUSED(_JSON_nfa_targs)[] = { - 0, 0 -}; + rb_check_frozen(self); + GET_PARSER_CONFIG; -static const char MAYBE_UNUSED(_JSON_nfa_offsets)[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; + parser_config_init(config, opts); -static const char MAYBE_UNUSED(_JSON_nfa_push_actions)[] = { - 0, 0 -}; + RB_OBJ_WRITTEN(self, Qundef, config->decimal_class); -static const char MAYBE_UNUSED(_JSON_nfa_pop_trans)[] = { - 0, 0 -}; + return self; +} + +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource) +{ + Vsource = convert_encoding(StringValue(Vsource)); + StringValue(Vsource); + + VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA]; + rvalue_stack stack = { + .type = RVALUE_STACK_STACK_ALLOCATED, + .ptr = rvalue_stack_buffer, + .capa = RVALUE_STACK_INITIAL_CAPA, + }; + + long len; + const char *start; + RSTRING_GETMEM(Vsource, start, len); + + JSON_ParserState _state = { + .start = start, + .cursor = start, + .end = start + len, + .stack = &stack, + }; + JSON_ParserState *state = &_state; + VALUE result = json_parse_any(state, config); -#line 835 "parser.rl" + // This may be skipped in case of exception, but + // it won't cause a leak. + rvalue_stack_eagerly_release(state->stack_handle); + json_ensure_eof(state); + + return result; +} /* -* call-seq: parse() -* -* Parses the current JSON text _source_ and returns the complete data -* structure as a result. -*/ -static VALUE cParser_parse(VALUE self) + * call-seq: parse(source) + * + * Parses the current JSON text _source_ and returns the complete data + * structure as a result. + * It raises JSON::ParserError if fail to parse. + */ +static VALUE cParserConfig_parse(VALUE self, VALUE Vsource) { - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; - - - { - cs = (int)JSON_start; - } - - #line 851 "parser.rl" - - p = json->source; - pe = p + json->len; - - { - if ( p == pe ) - goto _test_eof; - switch ( cs ) - { - case 1: - goto st_case_1; - case 0: - goto st_case_0; - case 10: - goto st_case_10; - case 2: - goto st_case_2; - case 3: - goto st_case_3; - case 4: - goto st_case_4; - case 5: - goto st_case_5; - case 6: - goto st_case_6; - case 7: - goto st_case_7; - case 8: - goto st_case_8; - case 9: - goto st_case_9; - } - goto st_out; - st1: - p+= 1; - if ( p == pe ) - goto _test_eof1; - st_case_1: - switch( ( (*( p))) ) { - case 13: { - goto st1; - } - case 32: { - goto st1; - } - case 34: { - goto ctr2; - } - case 45: { - goto ctr2; - } - case 47: { - goto st6; - } - case 73: { - goto ctr2; - } - case 78: { - goto ctr2; - } - case 91: { - goto ctr2; - } - case 102: { - goto ctr2; - } - case 110: { - goto ctr2; - } - case 116: { - goto ctr2; - } - case 123: { - goto ctr2; - } - } - if ( ( (*( p))) > 10 ) { - if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) { - goto ctr2; - } - } else if ( ( (*( p))) >= 9 ) { - goto st1; - } - { - goto st0; - } - st_case_0: - st0: - cs = 0; - goto _out; - ctr2: - { - #line 827 "parser.rl" - - char *np = JSON_parse_value(json, p, pe, &result, 0); - if (np == NULL) { {p = p - 1; } {p+= 1; cs = 10; goto _out;} } else {p = (( np))-1;} - - } - - goto st10; - st10: - p+= 1; - if ( p == pe ) - goto _test_eof10; - st_case_10: - switch( ( (*( p))) ) { - case 13: { - goto st10; - } - case 32: { - goto st10; - } - case 47: { - goto st2; - } - } - if ( 9 <= ( (*( p))) && ( (*( p))) <= 10 ) { - goto st10; - } - { - goto st0; - } - st2: - p+= 1; - if ( p == pe ) - goto _test_eof2; - st_case_2: - switch( ( (*( p))) ) { - case 42: { - goto st3; - } - case 47: { - goto st5; - } - } - { - goto st0; - } - st3: - p+= 1; - if ( p == pe ) - goto _test_eof3; - st_case_3: - if ( ( (*( p))) == 42 ) { - goto st4; - } - { - goto st3; - } - st4: - p+= 1; - if ( p == pe ) - goto _test_eof4; - st_case_4: - switch( ( (*( p))) ) { - case 42: { - goto st4; - } - case 47: { - goto st10; - } - } - { - goto st3; - } - st5: - p+= 1; - if ( p == pe ) - goto _test_eof5; - st_case_5: - if ( ( (*( p))) == 10 ) { - goto st10; - } - { - goto st5; - } - st6: - p+= 1; - if ( p == pe ) - goto _test_eof6; - st_case_6: - switch( ( (*( p))) ) { - case 42: { - goto st7; - } - case 47: { - goto st9; - } - } - { - goto st0; - } - st7: - p+= 1; - if ( p == pe ) - goto _test_eof7; - st_case_7: - if ( ( (*( p))) == 42 ) { - goto st8; - } - { - goto st7; - } - st8: - p+= 1; - if ( p == pe ) - goto _test_eof8; - st_case_8: - switch( ( (*( p))) ) { - case 42: { - goto st8; - } - case 47: { - goto st1; - } - } - { - goto st7; - } - st9: - p+= 1; - if ( p == pe ) - goto _test_eof9; - st_case_9: - if ( ( (*( p))) == 10 ) { - goto st1; - } - { - goto st9; - } - st_out: - _test_eof1: cs = 1; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - - _test_eof: {} - _out: {} - } - - #line 854 "parser.rl" - - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - -static void JSON_mark(void *ptr) + GET_PARSER_CONFIG; + return cParser_parse(config, Vsource); +} + +static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts) { - JSON_Parser *json = ptr; - rb_gc_mark_maybe(json->Vsource); - rb_gc_mark_maybe(json->create_id); - rb_gc_mark_maybe(json->object_class); - rb_gc_mark_maybe(json->array_class); - rb_gc_mark_maybe(json->decimal_class); - rb_gc_mark_maybe(json->match_string); + Vsource = convert_encoding(StringValue(Vsource)); + StringValue(Vsource); + + JSON_ParserConfig _config = {0}; + JSON_ParserConfig *config = &_config; + parser_config_init(config, opts); + + return cParser_parse(config, Vsource); } -static void JSON_free(void *ptr) +static void JSON_ParserConfig_mark(void *ptr) { - JSON_Parser *json = ptr; - fbuffer_free(json->fbuffer); - ruby_xfree(json); + JSON_ParserConfig *config = ptr; + rb_gc_mark(config->on_load_proc); + rb_gc_mark(config->decimal_class); } -static size_t JSON_memsize(const void *ptr) +static void JSON_ParserConfig_free(void *ptr) { - const JSON_Parser *json = ptr; - return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); -} - -#ifdef NEW_TYPEDDATA_WRAPPER -static const rb_data_type_t JSON_Parser_type = { - "JSON/Parser", - {JSON_mark, JSON_free, JSON_memsize,}, - #ifdef RUBY_TYPED_FREE_IMMEDIATELY - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, - #endif -}; -#endif + JSON_ParserConfig *config = ptr; + ruby_xfree(config); +} -static VALUE cJSON_parser_s_allocate(VALUE klass) +static size_t JSON_ParserConfig_memsize(const void *ptr) { - JSON_Parser *json; - VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); - json->fbuffer = fbuffer_alloc(0); - return obj; + return sizeof(JSON_ParserConfig); } -/* -* call-seq: source() -* -* Returns a copy of the current _source_ string, that was used to construct -* this Parser. -*/ -static VALUE cParser_source(VALUE self) +static const rb_data_type_t JSON_ParserConfig_type = { + "JSON::Ext::Parser/ParserConfig", + { + JSON_ParserConfig_mark, + JSON_ParserConfig_free, + JSON_ParserConfig_memsize, + }, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, +}; + +static VALUE cJSON_parser_s_allocate(VALUE klass) { - GET_PARSER; - return rb_str_dup(json->Vsource); + JSON_ParserConfig *config; + return TypedData_Make_Struct(klass, JSON_ParserConfig, &JSON_ParserConfig_type, config); } void Init_parser(void) { - #ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); - #endif - - #undef rb_intern - rb_require("json/common"); - mJSON = rb_define_module("JSON"); - mExt = rb_define_module_under(mJSON, "Ext"); - cParser = rb_define_class_under(mExt, "Parser", rb_cObject); - eParserError = rb_path2class("JSON::ParserError"); - eNestingError = rb_path2class("JSON::NestingError"); - rb_gc_register_mark_object(eParserError); - rb_gc_register_mark_object(eNestingError); - rb_define_alloc_func(cParser, cJSON_parser_s_allocate); - rb_define_method(cParser, "initialize", cParser_initialize, -1); - rb_define_method(cParser, "parse", cParser_parse, 0); - rb_define_method(cParser, "source", cParser_source, 0); - - CNaN = rb_const_get(mJSON, rb_intern("NaN")); - rb_gc_register_mark_object(CNaN); - - CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); - rb_gc_register_mark_object(CInfinity); - - CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); - rb_gc_register_mark_object(CMinusInfinity); - - i_json_creatable_p = rb_intern("json_creatable?"); - i_json_create = rb_intern("json_create"); - i_create_id = rb_intern("create_id"); - i_create_additions = rb_intern("create_additions"); - i_chr = rb_intern("chr"); - i_max_nesting = rb_intern("max_nesting"); - i_allow_nan = rb_intern("allow_nan"); - i_symbolize_names = rb_intern("symbolize_names"); - i_object_class = rb_intern("object_class"); - i_array_class = rb_intern("array_class"); - i_decimal_class = rb_intern("decimal_class"); - i_match = rb_intern("match"); - i_match_string = rb_intern("match_string"); - i_key_p = rb_intern("key?"); - i_deep_const_get = rb_intern("deep_const_get"); - i_aset = rb_intern("[]="); - i_aref = rb_intern("[]"); - i_leftshift = rb_intern("<<"); - i_new = rb_intern("new"); - i_try_convert = rb_intern("try_convert"); - i_freeze = rb_intern("freeze"); - i_uminus = rb_intern("-@"); -} +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif -/* -* Local variables: -* mode: c -* c-file-style: ruby -* indent-tabs-mode: nil -* End: -*/ +#undef rb_intern + rb_require("json/common"); + mJSON = rb_define_module("JSON"); + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE cParserConfig = rb_define_class_under(mExt, "ParserConfig", rb_cObject); + eNestingError = rb_path2class("JSON::NestingError"); + rb_gc_register_mark_object(eNestingError); + rb_define_alloc_func(cParserConfig, cJSON_parser_s_allocate); + rb_define_method(cParserConfig, "initialize", cParserConfig_initialize, 1); + rb_define_method(cParserConfig, "parse", cParserConfig_parse, 1); + + VALUE cParser = rb_define_class_under(mExt, "Parser", rb_cObject); + rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2); + + CNaN = rb_const_get(mJSON, rb_intern("NaN")); + rb_gc_register_mark_object(CNaN); + + CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); + rb_gc_register_mark_object(CInfinity); + + CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); + rb_gc_register_mark_object(CMinusInfinity); + + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma")); + sym_allow_control_characters = ID2SYM(rb_intern("allow_control_characters")); + sym_symbolize_names = ID2SYM(rb_intern("symbolize_names")); + sym_freeze = ID2SYM(rb_intern("freeze")); + sym_on_load = ID2SYM(rb_intern("on_load")); + sym_decimal_class = ID2SYM(rb_intern("decimal_class")); + sym_allow_duplicate_key = ID2SYM(rb_intern("allow_duplicate_key")); + + i_new = rb_intern("new"); + i_try_convert = rb_intern("try_convert"); + i_uminus = rb_intern("-@"); + i_encode = rb_intern("encode"); + + binary_encindex = rb_ascii8bit_encindex(); + utf8_encindex = rb_utf8_encindex(); + enc_utf8 = rb_utf8_encoding(); + +#ifdef HAVE_SIMD + simd_impl = find_simd_implementation(); +#endif +} diff --git a/ext/json/parser/parser.h b/ext/json/parser/parser.h deleted file mode 100644 index 92ed3fdc5d..0000000000 --- a/ext/json/parser/parser.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _PARSER_H_ -#define _PARSER_H_ - -#include "ruby.h" - -#ifndef HAVE_RUBY_RE_H -#include "re.h" -#endif - -#ifdef HAVE_RUBY_ST_H -#include "ruby/st.h" -#else -#include "st.h" -#endif - -#ifndef MAYBE_UNUSED -# define MAYBE_UNUSED(x) x -#endif - -#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key)) - -/* unicode */ - -typedef unsigned long UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ - -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF - -typedef struct JSON_ParserStruct { - VALUE Vsource; - char *source; - long len; - char *memo; - VALUE create_id; - int max_nesting; - int allow_nan; - int parsing_name; - int symbolize_names; - int freeze; - VALUE object_class; - VALUE array_class; - VALUE decimal_class; - int create_additions; - VALUE match_string; - FBuffer *fbuffer; -} JSON_Parser; - -#define GET_PARSER \ - GET_PARSER_INIT; \ - if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance") -#define GET_PARSER_INIT \ - JSON_Parser *json; \ - TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json) - -#define MinusInfinity "-Infinity" -#define EVIL 0x666 - -static UTF32 unescape_unicode(const unsigned char *p); -static int convert_UTF32_to_UTF8(char *buf, UTF32 ch); -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); -static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result); -static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result); -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting); -static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize); -static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result); -static VALUE convert_encoding(VALUE source); -static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self); -static VALUE cParser_parse(VALUE self); -static void JSON_mark(void *json); -static void JSON_free(void *json); -static VALUE cJSON_parser_s_allocate(VALUE klass); -static VALUE cParser_source(VALUE self); -#ifndef ZALLOC -#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type))) -static inline void *ruby_zalloc(size_t n) -{ - void *p = ruby_xmalloc(n); - memset(p, 0, n); - return p; -} -#endif -#ifdef TypedData_Make_Struct -static const rb_data_type_t JSON_Parser_type; -#define NEW_TYPEDDATA_WRAPPER 1 -#else -#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json) -#define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json) -#endif - -#endif diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl deleted file mode 100644 index f7be1a5acc..0000000000 --- a/ext/json/parser/parser.rl +++ /dev/null @@ -1,977 +0,0 @@ -#include "../fbuffer/fbuffer.h" -#include "parser.h" - -#if defined HAVE_RUBY_ENCODING_H -# define EXC_ENCODING rb_utf8_encoding(), -# ifndef HAVE_RB_ENC_RAISE -static void -enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) -{ - va_list args; - VALUE mesg; - - va_start(args, fmt); - mesg = rb_enc_vsprintf(enc, fmt, args); - va_end(args); - - rb_exc_raise(rb_exc_new3(exc, mesg)); -} -# define rb_enc_raise enc_raise -# endif -#else -# define EXC_ENCODING /* nothing */ -# define rb_enc_raise rb_raise -#endif - -/* unicode */ - -static const signed char digit_values[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, - -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1 -}; - -static UTF32 unescape_unicode(const unsigned char *p) -{ - signed char b; - UTF32 result = 0; - b = digit_values[p[0]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[1]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[2]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - b = digit_values[p[3]]; - if (b < 0) return UNI_REPLACEMENT_CHAR; - result = (result << 4) | (unsigned char)b; - return result; -} - -static int convert_UTF32_to_UTF8(char *buf, UTF32 ch) -{ - int len = 1; - if (ch <= 0x7F) { - buf[0] = (char) ch; - } else if (ch <= 0x07FF) { - buf[0] = (char) ((ch >> 6) | 0xC0); - buf[1] = (char) ((ch & 0x3F) | 0x80); - len++; - } else if (ch <= 0xFFFF) { - buf[0] = (char) ((ch >> 12) | 0xE0); - buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); - buf[2] = (char) ((ch & 0x3F) | 0x80); - len += 2; - } else if (ch <= 0x1fffff) { - buf[0] =(char) ((ch >> 18) | 0xF0); - buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); - buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); - buf[3] =(char) ((ch & 0x3F) | 0x80); - len += 3; - } else { - buf[0] = '?'; - } - return len; -} - -static VALUE mJSON, mExt, cParser, eParserError, eNestingError; -static VALUE CNaN, CInfinity, CMinusInfinity; - -static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, - i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, - i_object_class, i_array_class, i_decimal_class, i_key_p, - i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new, i_try_convert, i_freeze, i_uminus; - -%%{ - machine JSON_common; - - cr = '\n'; - cr_neg = [^\n]; - ws = [ \t\r\n]; - c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/'; - cpp_comment = '//' cr_neg* cr; - comment = c_comment | cpp_comment; - ignore = ws | comment; - name_separator = ':'; - value_separator = ','; - Vnull = 'null'; - Vfalse = 'false'; - Vtrue = 'true'; - VNaN = 'NaN'; - VInfinity = 'Infinity'; - VMinusInfinity = '-Infinity'; - begin_value = [nft\"\-\[\{NI] | digit; - begin_object = '{'; - end_object = '}'; - begin_array = '['; - end_array = ']'; - begin_string = '"'; - begin_name = begin_string; - begin_number = digit | '-'; -}%% - -%%{ - machine JSON_object; - include JSON_common; - - write data; - - action parse_value { - VALUE v = Qnil; - char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting); - if (np == NULL) { - fhold; fbreak; - } else { - if (NIL_P(json->object_class)) { - OBJ_FREEZE(last_name); - rb_hash_aset(*result, last_name, v); - } else { - rb_funcall(*result, i_aset, 2, last_name, v); - } - fexec np; - } - } - - action parse_name { - char *np; - json->parsing_name = 1; - np = JSON_parse_string(json, fpc, pe, &last_name); - json->parsing_name = 0; - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - action exit { fhold; fbreak; } - - pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value; - next_pair = ignore* value_separator pair; - - main := ( - begin_object - (pair (next_pair)*)? ignore* - end_object - ) @exit; -}%% - -static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) -{ - int cs = EVIL; - VALUE last_name = Qnil; - VALUE object_class = json->object_class; - - if (json->max_nesting && current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); - } - - *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); - - %% write init; - %% write exec; - - if (cs >= JSON_object_first_final) { - if (json->create_additions) { - VALUE klassname; - if (NIL_P(json->object_class)) { - klassname = rb_hash_aref(*result, json->create_id); - } else { - klassname = rb_funcall(*result, i_aref, 1, json->create_id); - } - if (!NIL_P(klassname)) { - VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname); - if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) { - *result = rb_funcall(klass, i_json_create, 1, *result); - } - } - } - return p + 1; - } else { - return NULL; - } -} - - -%%{ - machine JSON_value; - include JSON_common; - - write data; - - action parse_null { - *result = Qnil; - } - action parse_false { - *result = Qfalse; - } - action parse_true { - *result = Qtrue; - } - action parse_nan { - if (json->allow_nan) { - *result = CNaN; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); - } - } - action parse_infinity { - if (json->allow_nan) { - *result = CInfinity; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); - } - } - action parse_string { - char *np = JSON_parse_string(json, fpc, pe, result); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - action parse_number { - char *np; - if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) { - if (json->allow_nan) { - *result = CMinusInfinity; - fexec p + 10; - fhold; fbreak; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - } - } - np = JSON_parse_float(json, fpc, pe, result); - if (np != NULL) fexec np; - np = JSON_parse_integer(json, fpc, pe, result); - if (np != NULL) fexec np; - fhold; fbreak; - } - - action parse_array { - char *np; - np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - action parse_object { - char *np; - np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - action exit { fhold; fbreak; } - -main := ignore* ( - Vnull @parse_null | - Vfalse @parse_false | - Vtrue @parse_true | - VNaN @parse_nan | - VInfinity @parse_infinity | - begin_number >parse_number | - begin_string >parse_string | - begin_array >parse_array | - begin_object >parse_object - ) ignore* %*exit; -}%% - -static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) -{ - int cs = EVIL; - - %% write init; - %% write exec; - - if (json->freeze) { - OBJ_FREEZE(*result); - } - - if (cs >= JSON_value_first_final) { - return p; - } else { - return NULL; - } -} - -%%{ - machine JSON_integer; - - write data; - - action exit { fhold; fbreak; } - - main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit); -}%% - -static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) -{ - int cs = EVIL; - - %% write init; - json->memo = p; - %% write exec; - - if (cs >= JSON_integer_first_final) { - long len = p - json->memo; - fbuffer_clear(json->fbuffer); - fbuffer_append(json->fbuffer, json->memo, len); - fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10); - return p + 1; - } else { - return NULL; - } -} - -%%{ - machine JSON_float; - include JSON_common; - - write data; - - action exit { fhold; fbreak; } - - main := '-'? ( - (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?) - | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+)) - ) (^[0-9Ee.\-]? @exit ); -}%% - -static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) -{ - int cs = EVIL; - - %% write init; - json->memo = p; - %% write exec; - - if (cs >= JSON_float_first_final) { - VALUE mod = Qnil; - ID method_id = 0; - if (rb_respond_to(json->decimal_class, i_try_convert)) { - mod = json->decimal_class; - method_id = i_try_convert; - } else if (rb_respond_to(json->decimal_class, i_new)) { - mod = json->decimal_class; - method_id = i_new; - } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) { - VALUE name = rb_class_name(json->decimal_class); - const char *name_cstr = RSTRING_PTR(name); - const char *last_colon = strrchr(name_cstr, ':'); - if (last_colon) { - const char *mod_path_end = last_colon - 1; - VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); - mod = rb_path_to_class(mod_path); - - const char *method_name_beg = last_colon + 1; - long before_len = method_name_beg - name_cstr; - long len = RSTRING_LEN(name) - before_len; - VALUE method_name = rb_str_substr(name, before_len, len); - method_id = SYM2ID(rb_str_intern(method_name)); - } else { - mod = rb_mKernel; - method_id = SYM2ID(rb_str_intern(name)); - } - } - - long len = p - json->memo; - fbuffer_clear(json->fbuffer); - fbuffer_append(json->fbuffer, json->memo, len); - fbuffer_append_char(json->fbuffer, '\0'); - - if (method_id) { - VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); - *result = rb_funcallv(mod, method_id, 1, &text); - } else { - *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); - } - - return p + 1; - } else { - return NULL; - } -} - - -%%{ - machine JSON_array; - include JSON_common; - - write data; - - action parse_value { - VALUE v = Qnil; - char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting); - if (np == NULL) { - fhold; fbreak; - } else { - if (NIL_P(json->array_class)) { - rb_ary_push(*result, v); - } else { - rb_funcall(*result, i_leftshift, 1, v); - } - fexec np; - } - } - - action exit { fhold; fbreak; } - - next_element = value_separator ignore* begin_value >parse_value; - - main := begin_array ignore* - ((begin_value >parse_value ignore*) - (ignore* next_element ignore*)*)? - end_array @exit; -}%% - -static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) -{ - int cs = EVIL; - VALUE array_class = json->array_class; - - if (json->max_nesting && current_nesting > json->max_nesting) { - rb_raise(eNestingError, "nesting of %d is too deep", current_nesting); - } - *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); - - %% write init; - %% write exec; - - if(cs >= JSON_array_first_final) { - return p + 1; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return NULL; - } -} - -static const size_t MAX_STACK_BUFFER_SIZE = 128; -static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize) -{ - VALUE result = Qnil; - size_t bufferSize = stringEnd - string; - char *p = string, *pe = string, *unescape, *bufferStart, *buffer; - int unescape_len; - char buf[4]; - - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - bufferStart = buffer = ALLOC_N(char, bufferSize); - } else { - bufferStart = buffer = ALLOCA_N(char, bufferSize); - } - - while (pe < stringEnd) { - if (*pe == '\\') { - unescape = (char *) "?"; - unescape_len = 1; - if (pe > p) { - MEMCPY(buffer, p, char, pe - p); - buffer += pe - p; - } - switch (*++pe) { - case 'n': - unescape = (char *) "\n"; - break; - case 'r': - unescape = (char *) "\r"; - break; - case 't': - unescape = (char *) "\t"; - break; - case '"': - unescape = (char *) "\""; - break; - case '\\': - unescape = (char *) "\\"; - break; - case 'b': - unescape = (char *) "\b"; - break; - case 'f': - unescape = (char *) "\f"; - break; - case 'u': - if (pe > stringEnd - 4) { - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - rb_enc_raise( - EXC_ENCODING eParserError, - "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p - ); - } else { - UTF32 ch = unescape_unicode((unsigned char *) ++pe); - pe += 3; - if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { - pe++; - if (pe > stringEnd - 6) { - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - rb_enc_raise( - EXC_ENCODING eParserError, - "%u: incomplete surrogate pair at '%s'", __LINE__, p - ); - } - if (pe[0] == '\\' && pe[1] == 'u') { - UTF32 sur = unescape_unicode((unsigned char *) pe + 2); - ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) - | (sur & 0x3FF)); - pe += 5; - } else { - unescape = (char *) "?"; - break; - } - } - unescape_len = convert_UTF32_to_UTF8(buf, ch); - unescape = buf; - } - break; - default: - p = pe; - continue; - } - MEMCPY(buffer, unescape, char, unescape_len); - buffer += unescape_len; - p = ++pe; - } else { - pe++; - } - } - - if (pe > p) { - MEMCPY(buffer, p, char, pe - p); - buffer += pe - p; - } - -# ifdef HAVE_RB_ENC_INTERNED_STR - if (intern) { - result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding()); - } else { - result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart)); - } - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } -# else - result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart)); - - if (bufferSize > MAX_STACK_BUFFER_SIZE) { - free(bufferStart); - } - - if (intern) { - # if STR_UMINUS_DEDUPE_FROZEN - // Starting from MRI 2.8 it is preferable to freeze the string - // before deduplication so that it can be interned directly - // otherwise it would be duplicated first which is wasteful. - result = rb_funcall(rb_str_freeze(result), i_uminus, 0); - # elif STR_UMINUS_DEDUPE - // MRI 2.5 and older do not deduplicate strings that are already - // frozen. - result = rb_funcall(result, i_uminus, 0); - # else - result = rb_str_freeze(result); - # endif - } -# endif - - if (symbolize) { - result = rb_str_intern(result); - } - - return result; -} - -%%{ - machine JSON_string; - include JSON_common; - - write data; - - action parse_string { - *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names); - if (NIL_P(*result)) { - fhold; - fbreak; - } else { - fexec p + 1; - } - } - - action exit { fhold; fbreak; } - - main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit; -}%% - -static int -match_i(VALUE regexp, VALUE klass, VALUE memo) -{ - if (regexp == Qundef) return ST_STOP; - if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) && - RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) { - rb_ary_push(memo, klass); - return ST_STOP; - } - return ST_CONTINUE; -} - -static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result) -{ - int cs = EVIL; - VALUE match_string; - - %% write init; - json->memo = p; - %% write exec; - - if (json->create_additions && RTEST(match_string = json->match_string)) { - VALUE klass; - VALUE memo = rb_ary_new2(2); - rb_ary_push(memo, *result); - rb_hash_foreach(match_string, match_i, memo); - klass = rb_ary_entry(memo, 1); - if (RTEST(klass)) { - *result = rb_funcall(klass, i_json_create, 1, *result); - } - } - - if (cs >= JSON_string_first_final) { - return p + 1; - } else { - return NULL; - } -} - -/* - * Document-class: JSON::Ext::Parser - * - * This is the JSON parser implemented as a C extension. It can be configured - * to be used by setting - * - * JSON.parser = JSON::Ext::Parser - * - * with the method parser= in JSON. - * - */ - -static VALUE convert_encoding(VALUE source) -{ -#ifdef HAVE_RUBY_ENCODING_H - rb_encoding *enc = rb_enc_get(source); - if (enc == rb_ascii8bit_encoding()) { - if (OBJ_FROZEN(source)) { - source = rb_str_dup(source); - } - FORCE_UTF8(source); - } else { - source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); - } -#endif - return source; -} - -/* - * call-seq: new(source, opts => {}) - * - * Creates a new JSON::Ext::Parser instance for the string _source_. - * - * Creates a new JSON::Ext::Parser instance for the string _source_. - * - * It will be configured by the _opts_ hash. _opts_ can have the following - * keys: - * - * _opts_ can have the following keys: - * * *max_nesting*: The maximum depth of nesting allowed in the parsed data - * structures. Disable depth checking with :max_nesting => false|nil|0, it - * defaults to 100. - * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in - * defiance of RFC 4627 to be parsed by the Parser. This option defaults to - * false. - * * *symbolize_names*: If set to true, returns symbols for the names - * (keys) in a JSON object. Otherwise strings are returned, which is - * also the default. It's not possible to use this option in - * conjunction with the *create_additions* option. - * * *create_additions*: If set to false, the Parser doesn't create - * additions even if a matching class and create_id was found. This option - * defaults to false. - * * *object_class*: Defaults to Hash - * * *array_class*: Defaults to Array - */ -static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE source, opts; - GET_PARSER_INIT; - - if (json->Vsource) { - rb_raise(rb_eTypeError, "already initialized instance"); - } -#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - rb_scan_args(argc, argv, "1:", &source, &opts); -#else - rb_scan_args(argc, argv, "11", &source, &opts); -#endif - if (!NIL_P(opts)) { -#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); - if (NIL_P(opts)) { - rb_raise(rb_eArgError, "opts needs to be like a hash"); - } else { -#endif - VALUE tmp = ID2SYM(i_max_nesting); - if (option_given_p(opts, tmp)) { - VALUE max_nesting = rb_hash_aref(opts, tmp); - if (RTEST(max_nesting)) { - Check_Type(max_nesting, T_FIXNUM); - json->max_nesting = FIX2INT(max_nesting); - } else { - json->max_nesting = 0; - } - } else { - json->max_nesting = 100; - } - tmp = ID2SYM(i_allow_nan); - if (option_given_p(opts, tmp)) { - json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->allow_nan = 0; - } - tmp = ID2SYM(i_symbolize_names); - if (option_given_p(opts, tmp)) { - json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->symbolize_names = 0; - } - tmp = ID2SYM(i_freeze); - if (option_given_p(opts, tmp)) { - json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; - } else { - json->freeze = 0; - } - tmp = ID2SYM(i_create_additions); - if (option_given_p(opts, tmp)) { - json->create_additions = RTEST(rb_hash_aref(opts, tmp)); - } else { - json->create_additions = 0; - } - if (json->symbolize_names && json->create_additions) { - rb_raise(rb_eArgError, - "options :symbolize_names and :create_additions cannot be " - " used in conjunction"); - } - tmp = ID2SYM(i_create_id); - if (option_given_p(opts, tmp)) { - json->create_id = rb_hash_aref(opts, tmp); - } else { - json->create_id = rb_funcall(mJSON, i_create_id, 0); - } - tmp = ID2SYM(i_object_class); - if (option_given_p(opts, tmp)) { - json->object_class = rb_hash_aref(opts, tmp); - } else { - json->object_class = Qnil; - } - tmp = ID2SYM(i_array_class); - if (option_given_p(opts, tmp)) { - json->array_class = rb_hash_aref(opts, tmp); - } else { - json->array_class = Qnil; - } - tmp = ID2SYM(i_decimal_class); - if (option_given_p(opts, tmp)) { - json->decimal_class = rb_hash_aref(opts, tmp); - } else { - json->decimal_class = Qnil; - } - tmp = ID2SYM(i_match_string); - if (option_given_p(opts, tmp)) { - VALUE match_string = rb_hash_aref(opts, tmp); - json->match_string = RTEST(match_string) ? match_string : Qnil; - } else { - json->match_string = Qnil; - } -#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH - } -#endif - } else { - json->max_nesting = 100; - json->allow_nan = 0; - json->create_additions = 0; - json->create_id = rb_funcall(mJSON, i_create_id, 0); - json->object_class = Qnil; - json->array_class = Qnil; - json->decimal_class = Qnil; - } - source = convert_encoding(StringValue(source)); - StringValue(source); - json->len = RSTRING_LEN(source); - json->source = RSTRING_PTR(source);; - json->Vsource = source; - return self; -} - -%%{ - machine JSON; - - write data; - - include JSON_common; - - action parse_value { - char *np = JSON_parse_value(json, fpc, pe, &result, 0); - if (np == NULL) { fhold; fbreak; } else fexec np; - } - - main := ignore* ( - begin_value >parse_value - ) ignore*; -}%% - -/* - * call-seq: parse() - * - * Parses the current JSON text _source_ and returns the complete data - * structure as a result. - */ -static VALUE cParser_parse(VALUE self) -{ - char *p, *pe; - int cs = EVIL; - VALUE result = Qnil; - GET_PARSER; - - %% write init; - p = json->source; - pe = p + json->len; - %% write exec; - - if (cs >= JSON_first_final && p == pe) { - return result; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); - return Qnil; - } -} - -static void JSON_mark(void *ptr) -{ - JSON_Parser *json = ptr; - rb_gc_mark_maybe(json->Vsource); - rb_gc_mark_maybe(json->create_id); - rb_gc_mark_maybe(json->object_class); - rb_gc_mark_maybe(json->array_class); - rb_gc_mark_maybe(json->decimal_class); - rb_gc_mark_maybe(json->match_string); -} - -static void JSON_free(void *ptr) -{ - JSON_Parser *json = ptr; - fbuffer_free(json->fbuffer); - ruby_xfree(json); -} - -static size_t JSON_memsize(const void *ptr) -{ - const JSON_Parser *json = ptr; - return sizeof(*json) + FBUFFER_CAPA(json->fbuffer); -} - -#ifdef NEW_TYPEDDATA_WRAPPER -static const rb_data_type_t JSON_Parser_type = { - "JSON/Parser", - {JSON_mark, JSON_free, JSON_memsize,}, -#ifdef RUBY_TYPED_FREE_IMMEDIATELY - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, -#endif -}; -#endif - -static VALUE cJSON_parser_s_allocate(VALUE klass) -{ - JSON_Parser *json; - VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); - json->fbuffer = fbuffer_alloc(0); - return obj; -} - -/* - * call-seq: source() - * - * Returns a copy of the current _source_ string, that was used to construct - * this Parser. - */ -static VALUE cParser_source(VALUE self) -{ - GET_PARSER; - return rb_str_dup(json->Vsource); -} - -void Init_parser(void) -{ -#ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); -#endif - -#undef rb_intern - rb_require("json/common"); - mJSON = rb_define_module("JSON"); - mExt = rb_define_module_under(mJSON, "Ext"); - cParser = rb_define_class_under(mExt, "Parser", rb_cObject); - eParserError = rb_path2class("JSON::ParserError"); - eNestingError = rb_path2class("JSON::NestingError"); - rb_gc_register_mark_object(eParserError); - rb_gc_register_mark_object(eNestingError); - rb_define_alloc_func(cParser, cJSON_parser_s_allocate); - rb_define_method(cParser, "initialize", cParser_initialize, -1); - rb_define_method(cParser, "parse", cParser_parse, 0); - rb_define_method(cParser, "source", cParser_source, 0); - - CNaN = rb_const_get(mJSON, rb_intern("NaN")); - rb_gc_register_mark_object(CNaN); - - CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); - rb_gc_register_mark_object(CInfinity); - - CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); - rb_gc_register_mark_object(CMinusInfinity); - - i_json_creatable_p = rb_intern("json_creatable?"); - i_json_create = rb_intern("json_create"); - i_create_id = rb_intern("create_id"); - i_create_additions = rb_intern("create_additions"); - i_chr = rb_intern("chr"); - i_max_nesting = rb_intern("max_nesting"); - i_allow_nan = rb_intern("allow_nan"); - i_symbolize_names = rb_intern("symbolize_names"); - i_object_class = rb_intern("object_class"); - i_array_class = rb_intern("array_class"); - i_decimal_class = rb_intern("decimal_class"); - i_match = rb_intern("match"); - i_match_string = rb_intern("match_string"); - i_key_p = rb_intern("key?"); - i_deep_const_get = rb_intern("deep_const_get"); - i_aset = rb_intern("[]="); - i_aref = rb_intern("[]"); - i_leftshift = rb_intern("<<"); - i_new = rb_intern("new"); - i_try_convert = rb_intern("try_convert"); - i_freeze = rb_intern("freeze"); - i_uminus = rb_intern("-@"); -} - -/* - * Local variables: - * mode: c - * c-file-style: ruby - * indent-tabs-mode: nil - * End: - */ diff --git a/ext/json/parser/prereq.mk b/ext/json/parser/prereq.mk deleted file mode 100644 index fc59169056..0000000000 --- a/ext/json/parser/prereq.mk +++ /dev/null @@ -1,13 +0,0 @@ -RAGEL = ragel - -.SUFFIXES: .rl - -.rl.c: - $(RAGEL) -G2 $< - $(BASERUBY) -pli -e '$$_.sub!(/[ \t]+$$/, "")' \ - -e '$$_.sub!(/^static const int (JSON_.*=.*);$$/, "enum {\\1};")' \ - -e '$$_.sub!(/^(static const char) (_JSON(?:_\w+)?_nfa_\w+)(?=\[\] =)/, "\\1 MAYBE_UNUSED(\\2)")' \ - -e '$$_.sub!(/0 <= ([\( ]+\*[\( ]*p\)+) && \1 <= 31/, "0 <= (signed char)(*(p)) && (*(p)) <= 31")' \ - -e '$$_ = "/* This file is automatically generated from parser.rl by using ragel */\n" + $$_ if $$. == 1' $@ - -parser.c: diff --git a/ext/json/simd/conf.rb b/ext/json/simd/conf.rb new file mode 100644 index 0000000000..76f774bc97 --- /dev/null +++ b/ext/json/simd/conf.rb @@ -0,0 +1,24 @@ +case RbConfig::CONFIG['host_cpu'] +when /^(arm|aarch64)/ + # Try to compile a small program using NEON instructions + header, type, init, extra = 'arm_neon.h', 'uint8x16_t', 'vdupq_n_u8(32)', nil +when /^(x86_64|x64)/ + header, type, init, extra = 'x86intrin.h', '__m128i', '_mm_set1_epi8(32)', 'if (__builtin_cpu_supports("sse2")) { printf("OK"); }' +end +if header + if have_header(header) && try_compile(<<~SRC, '-Werror=implicit-function-declaration') + #{cpp_include(header)} + int main(int argc, char **argv) { + #{type} test = #{init}; + #{extra} + if (argc > 100000) printf("%p", &test); + return 0; + } + SRC + $defs.push("-DJSON_ENABLE_SIMD") + else + puts "Disable SIMD" + end +end + +have_header('cpuid.h') diff --git a/ext/json/simd/simd.h b/ext/json/simd/simd.h new file mode 100644 index 0000000000..3bb86acdec --- /dev/null +++ b/ext/json/simd/simd.h @@ -0,0 +1,218 @@ +#include "../json.h" + +typedef enum { + SIMD_NONE, + SIMD_NEON, + SIMD_SSE2 +} SIMD_Implementation; + +#ifndef __has_builtin // Optional of course. + #define __has_builtin(x) 0 // Compatibility with non-clang compilers. +#endif + +#ifdef __clang__ +# if __has_builtin(__builtin_ctzll) +# define HAVE_BUILTIN_CTZLL 1 +# else +# define HAVE_BUILTIN_CTZLL 0 +# endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAVE_BUILTIN_CTZLL 1 +#else +# define HAVE_BUILTIN_CTZLL 0 +#endif + +static inline uint32_t trailing_zeros64(uint64_t input) +{ + JSON_ASSERT(input > 0); // __builtin_ctz(0) is undefined behavior + +#if HAVE_BUILTIN_CTZLL + return __builtin_ctzll(input); +#else + uint32_t trailing_zeros = 0; + uint64_t temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; +#endif +} + +static inline int trailing_zeros(int input) +{ + JSON_ASSERT(input > 0); // __builtin_ctz(0) is undefined behavior + +#if HAVE_BUILTIN_CTZLL + return __builtin_ctz(input); +#else + int trailing_zeros = 0; + int temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; +#endif +} + +#ifdef JSON_ENABLE_SIMD + +#define SIMD_MINIMUM_THRESHOLD 4 + +ALWAYS_INLINE(static) void json_fast_memcpy16(char *dst, const char *src, size_t len) +{ + RBIMPL_ASSERT_OR_ASSUME(len < 16); + RBIMPL_ASSERT_OR_ASSUME(len >= SIMD_MINIMUM_THRESHOLD); // 4 +#if defined(__has_builtin) && __has_builtin(__builtin_memcpy) + // If __builtin_memcpy is available, use it to copy between SIMD_MINIMUM_THRESHOLD (4) and vec_len-1 (15) bytes. + // These copies overlap. The first copy will copy the first 8 (or 4) bytes. The second copy will copy + // the last 8 (or 4) bytes but overlap with the first copy. The overlapping bytes will be in the correct + // position in both copies. + + // Please do not attempt to replace __builtin_memcpy with memcpy without profiling and/or looking at the + // generated assembly. On clang-specifically (tested on Apple clang version 17.0.0 (clang-1700.0.13.3)), + // when using memcpy, the compiler will notice the only difference is a 4 or 8 and generate a conditional + // select instruction instead of direct loads and stores with a branch. This ends up slower than the branch + // plus two loads and stores generated when using __builtin_memcpy. + if (len >= 8) { + __builtin_memcpy(dst, src, 8); + __builtin_memcpy(dst + len - 8, src + len - 8, 8); + } else { + __builtin_memcpy(dst, src, 4); + __builtin_memcpy(dst + len - 4, src + len - 4, 4); + } +#else + MEMCPY(dst, src, char, len); +#endif +} + +#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__aarch64__) || defined(_M_ARM64) +#include <arm_neon.h> + +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 +static inline SIMD_Implementation find_simd_implementation(void) +{ + return SIMD_NEON; +} + +#define HAVE_SIMD 1 +#define HAVE_SIMD_NEON 1 + +// See: https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon +ALWAYS_INLINE(static) uint64_t neon_match_mask(uint8x16_t matches) +{ + const uint8x8_t res = vshrn_n_u16(vreinterpretq_u16_u8(matches), 4); + const uint64_t mask = vget_lane_u64(vreinterpret_u64_u8(res), 0); + return mask & 0x8888888888888888ull; +} + +ALWAYS_INLINE(static) uint64_t compute_chunk_mask_neon(const char *ptr) +{ + uint8x16_t chunk = vld1q_u8((const unsigned char *)ptr); + + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + const uint8x16_t too_low_or_dbl_quote = vcltq_u8(veorq_u8(chunk, vdupq_n_u8(2)), vdupq_n_u8(33)); + + uint8x16_t has_backslash = vceqq_u8(chunk, vdupq_n_u8('\\')); + uint8x16_t needs_escape = vorrq_u8(too_low_or_dbl_quote, has_backslash); + return neon_match_mask(needs_escape); +} + +ALWAYS_INLINE(static) int string_scan_simd_neon(const char **ptr, const char *end, uint64_t *mask) +{ + while (*ptr + sizeof(uint8x16_t) <= end) { + uint64_t chunk_mask = compute_chunk_mask_neon(*ptr); + if (chunk_mask) { + *mask = chunk_mask; + return 1; + } + *ptr += sizeof(uint8x16_t); + } + return 0; +} + +static inline uint8x16x4_t load_uint8x16_4(const unsigned char *table) +{ + uint8x16x4_t tab; + tab.val[0] = vld1q_u8(table); + tab.val[1] = vld1q_u8(table+16); + tab.val[2] = vld1q_u8(table+32); + tab.val[3] = vld1q_u8(table+48); + return tab; +} + +#endif /* ARM Neon Support.*/ + +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) + +#ifdef HAVE_X86INTRIN_H +#include <x86intrin.h> + +#define HAVE_SIMD 1 +#define HAVE_SIMD_SSE2 1 + +#ifdef HAVE_CPUID_H +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 + +#if defined(__clang__) || defined(__GNUC__) +#define TARGET_SSE2 __attribute__((target("sse2"))) +#else +#define TARGET_SSE2 +#endif + +#define _mm_cmpge_epu8(a, b) _mm_cmpeq_epi8(_mm_max_epu8(a, b), a) +#define _mm_cmple_epu8(a, b) _mm_cmpge_epu8(b, a) +#define _mm_cmpgt_epu8(a, b) _mm_xor_si128(_mm_cmple_epu8(a, b), _mm_set1_epi8(-1)) +#define _mm_cmplt_epu8(a, b) _mm_cmpgt_epu8(b, a) + +ALWAYS_INLINE(static) TARGET_SSE2 int compute_chunk_mask_sse2(const char *ptr) +{ + __m128i chunk = _mm_loadu_si128((__m128i const*)ptr); + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + __m128i too_low_or_dbl_quote = _mm_cmplt_epu8(_mm_xor_si128(chunk, _mm_set1_epi8(2)), _mm_set1_epi8(33)); + __m128i has_backslash = _mm_cmpeq_epi8(chunk, _mm_set1_epi8('\\')); + __m128i needs_escape = _mm_or_si128(too_low_or_dbl_quote, has_backslash); + return _mm_movemask_epi8(needs_escape); +} + +ALWAYS_INLINE(static) TARGET_SSE2 int string_scan_simd_sse2(const char **ptr, const char *end, int *mask) +{ + while (*ptr + sizeof(__m128i) <= end) { + int chunk_mask = compute_chunk_mask_sse2(*ptr); + if (chunk_mask) { + *mask = chunk_mask; + return 1; + } + *ptr += sizeof(__m128i); + } + + return 0; +} + +#include <cpuid.h> +#endif /* HAVE_CPUID_H */ + +static inline SIMD_Implementation find_simd_implementation(void) +{ + // TODO Revisit. I think the SSE version now only uses SSE2 instructions. + if (__builtin_cpu_supports("sse2")) { + return SIMD_SSE2; + } + + return SIMD_NONE; +} + +#endif /* HAVE_X86INTRIN_H */ +#endif /* X86_64 Support */ + +#endif /* JSON_ENABLE_SIMD */ + +#ifndef FIND_SIMD_IMPLEMENTATION_DEFINED +static inline SIMD_Implementation find_simd_implementation(void) +{ + return SIMD_NONE; +} +#endif diff --git a/ext/json/vendor/fpconv.c b/ext/json/vendor/fpconv.c new file mode 100644 index 0000000000..6c9bc2c103 --- /dev/null +++ b/ext/json/vendor/fpconv.c @@ -0,0 +1,480 @@ +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// The contents of this file is extracted from https://github.com/night-shift/fpconv +// It was slightly modified to append ".0" to plain floats, for use with the https://github.com/ruby/json package. + +#include <stdbool.h> +#include <string.h> +#include <stdint.h> + +#if JSON_DEBUG +#include <assert.h> +#endif + +#define npowers 87 +#define steppowers 8 +#define firstpower -348 /* 10 ^ -348 */ + +#define expmax -32 +#define expmin -60 + +typedef struct Fp { + uint64_t frac; + int exp; +} Fp; + +static const Fp powers_ten[] = { + { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 }, + { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 }, + { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 }, + { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 }, + { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 }, + { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 }, + { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 }, + { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 }, + { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 }, + { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 }, + { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 }, + { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 }, + { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 }, + { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 }, + { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 }, + { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 }, + { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 }, + { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 }, + { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 }, + { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 }, + { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 }, + { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 }, + { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 }, + { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 }, + { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 }, + { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 }, + { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 }, + { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 }, + { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 }, + { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 }, + { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 }, + { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 }, + { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 }, + { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 }, + { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 }, + { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 }, + { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 }, + { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 }, + { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 }, + { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 }, + { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 }, + { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 }, + { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 }, + { 12648080533535911531U, 1066 } +}; + +static Fp find_cachedpow10(int exp, int* k) +{ + const double one_log_ten = 0.30102999566398114; + + int approx = (int)(-(exp + npowers) * one_log_ten); + int idx = (approx - firstpower) / steppowers; + + while(1) { + int current = exp + powers_ten[idx].exp + 64; + + if(current < expmin) { + idx++; + continue; + } + + if(current > expmax) { + idx--; + continue; + } + + *k = (firstpower + idx * steppowers); + + return powers_ten[idx]; + } +} + +#define fracmask 0x000FFFFFFFFFFFFFU +#define expmask 0x7FF0000000000000U +#define hiddenbit 0x0010000000000000U +#define signmask 0x8000000000000000U +#define expbias (1023 + 52) + +#define absv(n) ((n) < 0 ? -(n) : (n)) +#define minv(a, b) ((a) < (b) ? (a) : (b)) + +static const uint64_t tens[] = { + 10000000000000000000U, 1000000000000000000U, 100000000000000000U, + 10000000000000000U, 1000000000000000U, 100000000000000U, + 10000000000000U, 1000000000000U, 100000000000U, + 10000000000U, 1000000000U, 100000000U, + 10000000U, 1000000U, 100000U, + 10000U, 1000U, 100U, + 10U, 1U +}; + +static inline uint64_t get_dbits(double d) +{ + union { + double dbl; + uint64_t i; + } dbl_bits = { d }; + + return dbl_bits.i; +} + +static Fp build_fp(double d) +{ + uint64_t bits = get_dbits(d); + + Fp fp; + fp.frac = bits & fracmask; + fp.exp = (bits & expmask) >> 52; + + if(fp.exp) { + fp.frac += hiddenbit; + fp.exp -= expbias; + + } else { + fp.exp = -expbias + 1; + } + + return fp; +} + +static void normalize(Fp* fp) +{ + while ((fp->frac & hiddenbit) == 0) { + fp->frac <<= 1; + fp->exp--; + } + + int shift = 64 - 52 - 1; + fp->frac <<= shift; + fp->exp -= shift; +} + +static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) +{ + upper->frac = (fp->frac << 1) + 1; + upper->exp = fp->exp - 1; + + while ((upper->frac & (hiddenbit << 1)) == 0) { + upper->frac <<= 1; + upper->exp--; + } + + int u_shift = 64 - 52 - 2; + + upper->frac <<= u_shift; + upper->exp = upper->exp - u_shift; + + + int l_shift = fp->frac == hiddenbit ? 2 : 1; + + lower->frac = (fp->frac << l_shift) - 1; + lower->exp = fp->exp - l_shift; + + + lower->frac <<= lower->exp - upper->exp; + lower->exp = upper->exp; +} + +static Fp multiply(Fp* a, Fp* b) +{ + const uint64_t lomask = 0x00000000FFFFFFFF; + + uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask); + uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32); + uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask); + uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32); + + uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32); + /* round up */ + tmp += 1U << 31; + + Fp fp = { + ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), + a->exp + b->exp + 64 + }; + + return fp; +} + +static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem, uint64_t kappa, uint64_t frac) +{ + while (rem < frac && delta - rem >= kappa && + (rem + kappa < frac || frac - rem > rem + kappa - frac)) { + + digits[ndigits - 1]--; + rem += kappa; + } +} + +static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) +{ + uint64_t wfrac = upper->frac - fp->frac; + uint64_t delta = upper->frac - lower->frac; + + Fp one; + one.frac = 1ULL << -upper->exp; + one.exp = upper->exp; + + uint64_t part1 = upper->frac >> -one.exp; + uint64_t part2 = upper->frac & (one.frac - 1); + + int idx = 0, kappa = 10; + const uint64_t* divp; + /* 1000000000 */ + for(divp = tens + 10; kappa > 0; divp++) { + + uint64_t div = *divp; + unsigned digit = (unsigned) (part1 / div); + + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part1 -= digit * div; + kappa--; + + uint64_t tmp = (part1 <<-one.exp) + part2; + if (tmp <= delta) { + *K += kappa; + round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac); + + return idx; + } + } + + /* 10 */ + const uint64_t* unit = tens + 18; + + while(true) { + part2 *= 10; + delta *= 10; + kappa--; + + unsigned digit = (unsigned) (part2 >> -one.exp); + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part2 &= one.frac - 1; + if (part2 < delta) { + *K += kappa; + round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit); + + return idx; + } + + unit--; + } +} + +static int grisu2(double d, char* digits, int* K) +{ + Fp w = build_fp(d); + + Fp lower, upper; + get_normalized_boundaries(&w, &lower, &upper); + + normalize(&w); + + int k; + Fp cp = find_cachedpow10(upper.exp, &k); + + w = multiply(&w, &cp); + upper = multiply(&upper, &cp); + lower = multiply(&lower, &cp); + + lower.frac++; + upper.frac--; + + *K = -k; + + return generate_digits(&w, &upper, &lower, digits, K); +} + +static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) +{ + int exp = absv(K + ndigits - 1); + + if(K >= 0 && exp < 15) { + memcpy(dest, digits, ndigits); + memset(dest + ndigits, '0', K); + + /* add a .0 to mark this as a float. */ + dest[ndigits + K] = '.'; + dest[ndigits + K + 1] = '0'; + + return ndigits + K + 2; + } + + /* write decimal w/o scientific notation */ + if(K < 0 && (K > -7 || exp < 10)) { + int offset = ndigits - absv(K); + /* fp < 1.0 -> write leading zero */ + if(offset <= 0) { + offset = -offset; + dest[0] = '0'; + dest[1] = '.'; + memset(dest + 2, '0', offset); + memcpy(dest + offset + 2, digits, ndigits); + + return ndigits + 2 + offset; + + /* fp > 1.0 */ + } else { + memcpy(dest, digits, offset); + dest[offset] = '.'; + memcpy(dest + offset + 1, digits + offset, ndigits - offset); + + return ndigits + 1; + } + } + + /* write decimal w/ scientific notation */ + ndigits = minv(ndigits, 18 - neg); + + int idx = 0; + dest[idx++] = digits[0]; + + if(ndigits > 1) { + dest[idx++] = '.'; + memcpy(dest + idx, digits + 1, ndigits - 1); + idx += ndigits - 1; + } + + dest[idx++] = 'e'; + + char sign = K + ndigits - 1 < 0 ? '-' : '+'; + dest[idx++] = sign; + + int cent = 0; + + if(exp > 99) { + cent = exp / 100; + dest[idx++] = cent + '0'; + exp -= cent * 100; + } + if(exp > 9) { + int dec = exp / 10; + dest[idx++] = dec + '0'; + exp -= dec * 10; + + } else if(cent) { + dest[idx++] = '0'; + } + + dest[idx++] = exp % 10 + '0'; + + return idx; +} + +static int filter_special(double fp, char* dest) +{ + if(fp == 0.0) { + dest[0] = '0'; + dest[1] = '.'; + dest[2] = '0'; + return 3; + } + + uint64_t bits = get_dbits(fp); + + bool nan = (bits & expmask) == expmask; + + if(!nan) { + return 0; + } + + if(bits & fracmask) { + dest[0] = 'n'; dest[1] = 'a'; dest[2] = 'n'; + + } else { + dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; + } + + return 3; +} + +/* Fast and accurate double to string conversion based on Florian Loitsch's + * Grisu-algorithm[1]. + * + * Input: + * fp -> the double to convert, dest -> destination buffer. + * The generated string will never be longer than 32 characters. + * Make sure to pass a pointer to at least 32 bytes of memory. + * The emitted string will not be null terminated. + * + * + * + * Output: + * The number of written characters. + * + * Exemplary usage: + * + * void print(double d) + * { + * char buf[28 + 1] // plus null terminator + * int str_len = fpconv_dtoa(d, buf); + * + * buf[str_len] = '\0'; + * printf("%s", buf); + * } + * + */ +static int fpconv_dtoa(double d, char dest[32]) +{ + char digits[18]; + + int str_len = 0; + bool neg = false; + + if(get_dbits(d) & signmask) { + dest[0] = '-'; + str_len++; + neg = true; + } + + int spec = filter_special(d, dest + str_len); + + if(spec) { + return str_len + spec; + } + + int K = 0; + int ndigits = grisu2(d, digits, &K); + + str_len += emit_digits(digits, ndigits, dest + str_len, K, neg); +#if JSON_DEBUG + assert(str_len <= 32); +#endif + + return str_len; +} diff --git a/ext/json/vendor/jeaiii-ltoa.h b/ext/json/vendor/jeaiii-ltoa.h new file mode 100644 index 0000000000..ba4f497fc8 --- /dev/null +++ b/ext/json/vendor/jeaiii-ltoa.h @@ -0,0 +1,267 @@ +/* + +This file is released under the terms of the MIT License. It is based on the +work of James Edward Anhalt III, with the original license listed below. + +MIT License + +Copyright (c) 2024,2025 Enrico Thierbach - https://github.com/radiospiel +Copyright (c) 2022 James Edward Anhalt III - https://github.com/jeaiii/itoa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef JEAIII_TO_TEXT_H_ +#define JEAIII_TO_TEXT_H_ + +#include <stdint.h> + +typedef uint_fast32_t u32_t; +typedef uint_fast64_t u64_t; + +#define u32(x) ((u32_t)(x)) +#define u64(x) ((u64_t)(x)) + +struct digit_pair +{ + char dd[2]; +}; + +static const struct digit_pair *digits_dd = (struct digit_pair *)( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const struct digit_pair *digits_fd = (struct digit_pair *)( + "0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const u64_t mask24 = (u64(1) << 24) - 1; +static const u64_t mask32 = (u64(1) << 32) - 1; +static const u64_t mask57 = (u64(1) << 57) - 1; + +#define COPY(buffer, digits) memcpy(buffer, &(digits), sizeof(struct digit_pair)) + +static char * +jeaiii_ultoa(char *b, u64_t n) +{ + if (n < u32(1e2)) { + COPY(b, digits_fd[n]); + return n < 10 ? b + 1 : b + 2; + } + + if (n < u32(1e6)) { + if (n < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * n); + COPY(b, digits_fd[f0 >> 24]); + + b -= n < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + return b + 4; + } + + u64_t f0 = u64(10 * (1ull << 32ull)/ 1e5 + 1) * n; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + return b + 6; + } + + if (n < u64(1ull << 32ull)) { + if (n < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * n >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; + } + + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * n; + COPY(b, digits_fd[f0 >> 57]); + + b -= n < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + + return b + 10; + } + + // if we get here U must be u64 but some compilers don't know that, so reassign n to a u64 to avoid warnings + u32_t z = n % u32(1e8); + u64_t u = n / u32(1e8); + + if (u < u32(1e2)) { + // u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number) + COPY(b, digits_dd[u]); + b += 2; + } + else if (u < u32(1e6)) { + if (u < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + b += 4; + } + else { + u64_t f0 = u64(10 * (1ull << 32ull) / 1e5 + 1) * u; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + b += 6; + } + } + else if (u < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * u >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + b += 8; + } + else if (u < u64(1ull << 32ull)) { + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * u; + COPY(b, digits_fd[f0 >> 57]); + + b -= u < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + b += 10; + } + else { + u32_t y = u % u32(1e8); + u /= u32(1e8); + + // u is 2, 3, or 4 digits (if u < 10 it would have been handled above) + if (u < u32(1e2)) { + COPY(b, digits_dd[u]); + b += 2; + } + else { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + b += 4; + } + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * y >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + b += 8; + } + + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * z >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; +} + +#undef u32 +#undef u64 +#undef COPY + +#endif // JEAIII_TO_TEXT_H_ diff --git a/ext/json/vendor/ryu.h b/ext/json/vendor/ryu.h new file mode 100644 index 0000000000..f06ec814b4 --- /dev/null +++ b/ext/json/vendor/ryu.h @@ -0,0 +1,819 @@ +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. +// +// --- +// +// Apache License +// Version 2.0, January 2004 +// http://www.apache.org/licenses/ +// +// TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +// +// 1. Definitions. +// +// "License" shall mean the terms and conditions for use, reproduction, +// and distribution as defined by Sections 1 through 9 of this document. +// +// "Licensor" shall mean the copyright owner or entity authorized by +// the copyright owner that is granting the License. +// +// "Legal Entity" shall mean the union of the acting entity and all +// other entities that control, are controlled by, or are under common +// control with that entity. For the purposes of this definition, +// "control" means (i) the power, direct or indirect, to cause the +// direction or management of such entity, whether by contract or +// otherwise, or (ii) ownership of fifty percent (50%) or more of the +// outstanding shares, or (iii) beneficial ownership of such entity. +// +// "You" (or "Your") shall mean an individual or Legal Entity +// exercising permissions granted by this License. +// +// "Source" form shall mean the preferred form for making modifications, +// including but not limited to software source code, documentation +// source, and configuration files. +// +// "Object" form shall mean any form resulting from mechanical +// transformation or translation of a Source form, including but +// not limited to compiled object code, generated documentation, +// and conversions to other media types. +// +// "Work" shall mean the work of authorship, whether in Source or +// Object form, made available under the License, as indicated by a +// copyright notice that is included in or attached to the work +// (an example is provided in the Appendix below). +// +// "Derivative Works" shall mean any work, whether in Source or Object +// form, that is based on (or derived from) the Work and for which the +// editorial revisions, annotations, elaborations, or other modifications +// represent, as a whole, an original work of authorship. For the purposes +// of this License, Derivative Works shall not include works that remain +// separable from, or merely link (or bind by name) to the interfaces of, +// the Work and Derivative Works thereof. +// +// "Contribution" shall mean any work of authorship, including +// the original version of the Work and any modifications or additions +// to that Work or Derivative Works thereof, that is intentionally +// submitted to Licensor for inclusion in the Work by the copyright owner +// or by an individual or Legal Entity authorized to submit on behalf of +// the copyright owner. For the purposes of this definition, "submitted" +// means any form of electronic, verbal, or written communication sent +// to the Licensor or its representatives, including but not limited to +// communication on electronic mailing lists, source code control systems, +// and issue tracking systems that are managed by, or on behalf of, the +// Licensor for the purpose of discussing and improving the Work, but +// excluding communication that is conspicuously marked or otherwise +// designated in writing by the copyright owner as "Not a Contribution." +// +// "Contributor" shall mean Licensor and any individual or Legal Entity +// on behalf of whom a Contribution has been received by Licensor and +// subsequently incorporated within the Work. +// +// 2. Grant of Copyright License. Subject to the terms and conditions of +// this License, each Contributor hereby grants to You a perpetual, +// worldwide, non-exclusive, no-charge, royalty-free, irrevocable +// copyright license to reproduce, prepare Derivative Works of, +// publicly display, publicly perform, sublicense, and distribute the +// Work and such Derivative Works in Source or Object form. +// +// 3. Grant of Patent License. Subject to the terms and conditions of +// this License, each Contributor hereby grants to You a perpetual, +// worldwide, non-exclusive, no-charge, royalty-free, irrevocable +// (except as stated in this section) patent license to make, have made, +// use, offer to sell, sell, import, and otherwise transfer the Work, +// where such license applies only to those patent claims licensable +// by such Contributor that are necessarily infringed by their +// Contribution(s) alone or by combination of their Contribution(s) +// with the Work to which such Contribution(s) was submitted. If You +// institute patent litigation against any entity (including a +// cross-claim or counterclaim in a lawsuit) alleging that the Work +// or a Contribution incorporated within the Work constitutes direct +// or contributory patent infringement, then any patent licenses +// granted to You under this License for that Work shall terminate +// as of the date such litigation is filed. +// +// 4. Redistribution. You may reproduce and distribute copies of the +// Work or Derivative Works thereof in any medium, with or without +// modifications, and in Source or Object form, provided that You +// meet the following conditions: +// +// (a) You must give any other recipients of the Work or +// Derivative Works a copy of this License; and +// +// (b) You must cause any modified files to carry prominent notices +// stating that You changed the files; and +// +// (c) You must retain, in the Source form of any Derivative Works +// that You distribute, all copyright, patent, trademark, and +// attribution notices from the Source form of the Work, +// excluding those notices that do not pertain to any part of +// the Derivative Works; and +// +// (d) If the Work includes a "NOTICE" text file as part of its +// distribution, then any Derivative Works that You distribute must +// include a readable copy of the attribution notices contained +// within such NOTICE file, excluding those notices that do not +// pertain to any part of the Derivative Works, in at least one +// of the following places: within a NOTICE text file distributed +// as part of the Derivative Works; within the Source form or +// documentation, if provided along with the Derivative Works; or, +// within a display generated by the Derivative Works, if and +// wherever such third-party notices normally appear. The contents +// of the NOTICE file are for informational purposes only and +// do not modify the License. You may add Your own attribution +// notices within Derivative Works that You distribute, alongside +// or as an addendum to the NOTICE text from the Work, provided +// that such additional attribution notices cannot be construed +// as modifying the License. +// +// You may add Your own copyright statement to Your modifications and +// may provide additional or different license terms and conditions +// for use, reproduction, or distribution of Your modifications, or +// for any such Derivative Works as a whole, provided Your use, +// reproduction, and distribution of the Work otherwise complies with +// the conditions stated in this License. +// +// 5. Submission of Contributions. Unless You explicitly state otherwise, +// any Contribution intentionally submitted for inclusion in the Work +// by You to the Licensor shall be under the terms and conditions of +// this License, without any additional terms or conditions. +// Notwithstanding the above, nothing herein shall supersede or modify +// the terms of any separate license agreement you may have executed +// with Licensor regarding such Contributions. +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor, +// except as required for reasonable and customary use in describing the +// origin of the Work and reproducing the content of the NOTICE file. +// +// 7. Disclaimer of Warranty. Unless required by applicable law or +// agreed to in writing, Licensor provides the Work (and each +// Contributor provides its Contributions) on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied, including, without limitation, any warranties or conditions +// of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +// PARTICULAR PURPOSE. You are solely responsible for determining the +// appropriateness of using or redistributing the Work and assume any +// risks associated with Your exercise of permissions under this License. +// +// 8. Limitation of Liability. In no event and under no legal theory, +// whether in tort (including negligence), contract, or otherwise, +// unless required by applicable law (such as deliberate and grossly +// negligent acts) or agreed to in writing, shall any Contributor be +// liable to You for damages, including any direct, indirect, special, +// incidental, or consequential damages of any character arising as a +// result of this License or out of the use or inability to use the +// Work (including but not limited to damages for loss of goodwill, +// work stoppage, computer failure or malfunction, or any and all +// other commercial damages or losses), even if such Contributor +// has been advised of the possibility of such damages. +// +// 9. Accepting Warranty or Additional Liability. While redistributing +// the Work or Derivative Works thereof, You may choose to offer, +// and charge a fee for, acceptance of support, warranty, indemnity, +// or other liability obligations and/or rights consistent with this +// License. However, in accepting such obligations, You may act only +// on Your own behalf and on Your sole responsibility, not on behalf +// of any other Contributor, and only if You agree to indemnify, +// defend, and hold each Contributor harmless for any liability +// incurred by, or claims asserted against, such Contributor by reason +// of your accepting any such warranty or additional liability. +// +// END OF TERMS AND CONDITIONS +// +// APPENDIX: How to apply the Apache License to your work. +// +// To apply the Apache License to your work, attach the following +// boilerplate notice, with the fields enclosed by brackets "[]" +// replaced with your own identifying information. (Don't include +// the brackets!) The text should be enclosed in the appropriate +// comment syntax for the file format. We also recommend that a +// file or class name and description of purpose be included on the +// same "printed page" as the copyright notice for easier +// identification within third-party archives. +// +// Copyright [yyyy] [name of copyright owner] +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// --- +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// --- +// Minimal Ryu implementation adapted for Ruby JSON gem by Josef Šimánek +// Optimized for pre-extracted mantissa/exponent from JSON parsing +// This is a stripped-down version containing only what's needed for +// converting decimal mantissa+exponent to IEEE 754 double precision. + +#ifndef RYU_H +#define RYU_H + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> + +// Detect __builtin_clzll availability (for floor_log2) +// Note: MSVC doesn't have __builtin_clzll, so we provide a fallback +#ifdef __clang__ + #if __has_builtin(__builtin_clzll) + #define RYU_HAVE_BUILTIN_CLZLL 1 + #else + #define RYU_HAVE_BUILTIN_CLZLL 0 + #endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define RYU_HAVE_BUILTIN_CLZLL 1 +#else + #define RYU_HAVE_BUILTIN_CLZLL 0 +#endif + +// Count leading zeros (for floor_log2) +static inline uint32_t ryu_leading_zeros64(uint64_t input) +{ +#if RYU_HAVE_BUILTIN_CLZLL + return __builtin_clzll(input); +#else + // Fallback: binary search for the highest set bit + // This works on MSVC and other compilers without __builtin_clzll + if (input == 0) return 64; + uint32_t n = 0; + if (input <= 0x00000000FFFFFFFFULL) { n += 32; input <<= 32; } + if (input <= 0x0000FFFFFFFFFFFFULL) { n += 16; input <<= 16; } + if (input <= 0x00FFFFFFFFFFFFFFULL) { n += 8; input <<= 8; } + if (input <= 0x0FFFFFFFFFFFFFFFULL) { n += 4; input <<= 4; } + if (input <= 0x3FFFFFFFFFFFFFFFULL) { n += 2; input <<= 2; } + if (input <= 0x7FFFFFFFFFFFFFFFULL) { n += 1; } + return n; +#endif +} + +// These tables are generated by PrintDoubleLookupTable. +#define DOUBLE_POW5_INV_BITCOUNT 125 +#define DOUBLE_POW5_BITCOUNT 125 + +#define DOUBLE_POW5_INV_TABLE_SIZE 342 +#define DOUBLE_POW5_TABLE_SIZE 326 + +static const uint64_t DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = { + { 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u }, + { 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u }, + { 8824922364862649494u, 1888946593147858085u }, { 7059937891890119595u, 1511157274518286468u }, + { 13026647942995916322u, 1208925819614629174u }, { 9774590264567735146u, 1934281311383406679u }, + { 11509021026396098440u, 1547425049106725343u }, { 16585914450600699399u, 1237940039285380274u }, + { 15469416676735388068u, 1980704062856608439u }, { 16064882156130220778u, 1584563250285286751u }, + { 9162556910162266299u, 1267650600228229401u }, { 7281393426775805432u, 2028240960365167042u }, + { 16893161185646375315u, 1622592768292133633u }, { 2446482504291369283u, 1298074214633706907u }, + { 7603720821608101175u, 2076918743413931051u }, { 2393627842544570617u, 1661534994731144841u }, + { 16672297533003297786u, 1329227995784915872u }, { 11918280793837635165u, 2126764793255865396u }, + { 5845275820328197809u, 1701411834604692317u }, { 15744267100488289217u, 1361129467683753853u }, + { 3054734472329800808u, 2177807148294006166u }, { 17201182836831481939u, 1742245718635204932u }, + { 6382248639981364905u, 1393796574908163946u }, { 2832900194486363201u, 2230074519853062314u }, + { 5955668970331000884u, 1784059615882449851u }, { 1075186361522890384u, 1427247692705959881u }, + { 12788344622662355584u, 2283596308329535809u }, { 13920024512871794791u, 1826877046663628647u }, + { 3757321980813615186u, 1461501637330902918u }, { 10384555214134712795u, 1169201309864722334u }, + { 5547241898389809503u, 1870722095783555735u }, { 4437793518711847602u, 1496577676626844588u }, + { 10928932444453298728u, 1197262141301475670u }, { 17486291911125277965u, 1915619426082361072u }, + { 6610335899416401726u, 1532495540865888858u }, { 12666966349016942027u, 1225996432692711086u }, + { 12888448528943286597u, 1961594292308337738u }, { 17689456452638449924u, 1569275433846670190u }, + { 14151565162110759939u, 1255420347077336152u }, { 7885109000409574610u, 2008672555323737844u }, + { 9997436015069570011u, 1606938044258990275u }, { 7997948812055656009u, 1285550435407192220u }, + { 12796718099289049614u, 2056880696651507552u }, { 2858676849947419045u, 1645504557321206042u }, + { 13354987924183666206u, 1316403645856964833u }, { 17678631863951955605u, 2106245833371143733u }, + { 3074859046935833515u, 1684996666696914987u }, { 13527933681774397782u, 1347997333357531989u }, + { 10576647446613305481u, 2156795733372051183u }, { 15840015586774465031u, 1725436586697640946u }, + { 8982663654677661702u, 1380349269358112757u }, { 18061610662226169046u, 2208558830972980411u }, + { 10759939715039024913u, 1766847064778384329u }, { 12297300586773130254u, 1413477651822707463u }, + { 15986332124095098083u, 2261564242916331941u }, { 9099716884534168143u, 1809251394333065553u }, + { 14658471137111155161u, 1447401115466452442u }, { 4348079280205103483u, 1157920892373161954u }, + { 14335624477811986218u, 1852673427797059126u }, { 7779150767507678651u, 1482138742237647301u }, + { 2533971799264232598u, 1185710993790117841u }, { 15122401323048503126u, 1897137590064188545u }, + { 12097921058438802501u, 1517710072051350836u }, { 5988988032009131678u, 1214168057641080669u }, + { 16961078480698431330u, 1942668892225729070u }, { 13568862784558745064u, 1554135113780583256u }, + { 7165741412905085728u, 1243308091024466605u }, { 11465186260648137165u, 1989292945639146568u }, + { 16550846638002330379u, 1591434356511317254u }, { 16930026125143774626u, 1273147485209053803u }, + { 4951948911778577463u, 2037035976334486086u }, { 272210314680951647u, 1629628781067588869u }, + { 3907117066486671641u, 1303703024854071095u }, { 6251387306378674625u, 2085924839766513752u }, + { 16069156289328670670u, 1668739871813211001u }, { 9165976216721026213u, 1334991897450568801u }, + { 7286864317269821294u, 2135987035920910082u }, { 16897537898041588005u, 1708789628736728065u }, + { 13518030318433270404u, 1367031702989382452u }, { 6871453250525591353u, 2187250724783011924u }, + { 9186511415162383406u, 1749800579826409539u }, { 11038557946871817048u, 1399840463861127631u }, + { 10282995085511086630u, 2239744742177804210u }, { 8226396068408869304u, 1791795793742243368u }, + { 13959814484210916090u, 1433436634993794694u }, { 11267656730511734774u, 2293498615990071511u }, + { 5324776569667477496u, 1834798892792057209u }, { 7949170070475892320u, 1467839114233645767u }, + { 17427382500606444826u, 1174271291386916613u }, { 5747719112518849781u, 1878834066219066582u }, + { 15666221734240810795u, 1503067252975253265u }, { 12532977387392648636u, 1202453802380202612u }, + { 5295368560860596524u, 1923926083808324180u }, { 4236294848688477220u, 1539140867046659344u }, + { 7078384693692692099u, 1231312693637327475u }, { 11325415509908307358u, 1970100309819723960u }, + { 9060332407926645887u, 1576080247855779168u }, { 14626963555825137356u, 1260864198284623334u }, + { 12335095245094488799u, 2017382717255397335u }, { 9868076196075591040u, 1613906173804317868u }, + { 15273158586344293478u, 1291124939043454294u }, { 13369007293925138595u, 2065799902469526871u }, + { 7005857020398200553u, 1652639921975621497u }, { 16672732060544291412u, 1322111937580497197u }, + { 11918976037903224966u, 2115379100128795516u }, { 5845832015580669650u, 1692303280103036413u }, + { 12055363241948356366u, 1353842624082429130u }, { 841837113407818570u, 2166148198531886609u }, + { 4362818505468165179u, 1732918558825509287u }, { 14558301248600263113u, 1386334847060407429u }, + { 12225235553534690011u, 2218135755296651887u }, { 2401490813343931363u, 1774508604237321510u }, + { 1921192650675145090u, 1419606883389857208u }, { 17831303500047873437u, 2271371013423771532u }, + { 6886345170554478103u, 1817096810739017226u }, { 1819727321701672159u, 1453677448591213781u }, + { 16213177116328979020u, 1162941958872971024u }, { 14873036941900635463u, 1860707134196753639u }, + { 15587778368262418694u, 1488565707357402911u }, { 8780873879868024632u, 1190852565885922329u }, + { 2981351763563108441u, 1905364105417475727u }, { 13453127855076217722u, 1524291284333980581u }, + { 7073153469319063855u, 1219433027467184465u }, { 11317045550910502167u, 1951092843947495144u }, + { 12742985255470312057u, 1560874275157996115u }, { 10194388204376249646u, 1248699420126396892u }, + { 1553625868034358140u, 1997919072202235028u }, { 8621598323911307159u, 1598335257761788022u }, + { 17965325103354776697u, 1278668206209430417u }, { 13987124906400001422u, 2045869129935088668u }, + { 121653480894270168u, 1636695303948070935u }, { 97322784715416134u, 1309356243158456748u }, + { 14913111714512307107u, 2094969989053530796u }, { 8241140556867935363u, 1675975991242824637u }, + { 17660958889720079260u, 1340780792994259709u }, { 17189487779326395846u, 2145249268790815535u }, + { 13751590223461116677u, 1716199415032652428u }, { 18379969808252713988u, 1372959532026121942u }, + { 14650556434236701088u, 2196735251241795108u }, { 652398703163629901u, 1757388200993436087u }, + { 11589965406756634890u, 1405910560794748869u }, { 7475898206584884855u, 2249456897271598191u }, + { 2291369750525997561u, 1799565517817278553u }, { 9211793429904618695u, 1439652414253822842u }, + { 18428218302589300235u, 2303443862806116547u }, { 7363877012587619542u, 1842755090244893238u }, + { 13269799239553916280u, 1474204072195914590u }, { 10615839391643133024u, 1179363257756731672u }, + { 2227947767661371545u, 1886981212410770676u }, { 16539753473096738529u, 1509584969928616540u }, + { 13231802778477390823u, 1207667975942893232u }, { 6413489186596184024u, 1932268761508629172u }, + { 16198837793502678189u, 1545815009206903337u }, { 5580372605318321905u, 1236652007365522670u }, + { 8928596168509315048u, 1978643211784836272u }, { 18210923379033183008u, 1582914569427869017u }, + { 7190041073742725760u, 1266331655542295214u }, { 436019273762630246u, 2026130648867672343u }, + { 7727513048493924843u, 1620904519094137874u }, { 9871359253537050198u, 1296723615275310299u }, + { 4726128361433549347u, 2074757784440496479u }, { 7470251503888749801u, 1659806227552397183u }, + { 13354898832594820487u, 1327844982041917746u }, { 13989140502667892133u, 2124551971267068394u }, + { 14880661216876224029u, 1699641577013654715u }, { 11904528973500979224u, 1359713261610923772u }, + { 4289851098633925465u, 2175541218577478036u }, { 18189276137874781665u, 1740432974861982428u }, + { 3483374466074094362u, 1392346379889585943u }, { 1884050330976640656u, 2227754207823337509u }, + { 5196589079523222848u, 1782203366258670007u }, { 15225317707844309248u, 1425762693006936005u }, + { 5913764258841343181u, 2281220308811097609u }, { 8420360221814984868u, 1824976247048878087u }, + { 17804334621677718864u, 1459980997639102469u }, { 17932816512084085415u, 1167984798111281975u }, + { 10245762345624985047u, 1868775676978051161u }, { 4507261061758077715u, 1495020541582440929u }, + { 7295157664148372495u, 1196016433265952743u }, { 7982903447895485668u, 1913626293225524389u }, + { 10075671573058298858u, 1530901034580419511u }, { 4371188443704728763u, 1224720827664335609u }, + { 14372599139411386667u, 1959553324262936974u }, { 15187428126271019657u, 1567642659410349579u }, + { 15839291315758726049u, 1254114127528279663u }, { 3206773216762499739u, 2006582604045247462u }, + { 13633465017635730761u, 1605266083236197969u }, { 14596120828850494932u, 1284212866588958375u }, + { 4907049252451240275u, 2054740586542333401u }, { 236290587219081897u, 1643792469233866721u }, + { 14946427728742906810u, 1315033975387093376u }, { 16535586736504830250u, 2104054360619349402u }, + { 5849771759720043554u, 1683243488495479522u }, { 15747863852001765813u, 1346594790796383617u }, + { 10439186904235184007u, 2154551665274213788u }, { 15730047152871967852u, 1723641332219371030u }, + { 12584037722297574282u, 1378913065775496824u }, { 9066413911450387881u, 2206260905240794919u }, + { 10942479943902220628u, 1765008724192635935u }, { 8753983955121776503u, 1412006979354108748u }, + { 10317025513452932081u, 2259211166966573997u }, { 874922781278525018u, 1807368933573259198u }, + { 8078635854506640661u, 1445895146858607358u }, { 13841606313089133175u, 1156716117486885886u }, + { 14767872471458792434u, 1850745787979017418u }, { 746251532941302978u, 1480596630383213935u }, + { 597001226353042382u, 1184477304306571148u }, { 15712597221132509104u, 1895163686890513836u }, + { 8880728962164096960u, 1516130949512411069u }, { 10793931984473187891u, 1212904759609928855u }, + { 17270291175157100626u, 1940647615375886168u }, { 2748186495899949531u, 1552518092300708935u }, + { 2198549196719959625u, 1242014473840567148u }, { 18275073973719576693u, 1987223158144907436u }, + { 10930710364233751031u, 1589778526515925949u }, { 12433917106128911148u, 1271822821212740759u }, + { 8826220925580526867u, 2034916513940385215u }, { 7060976740464421494u, 1627933211152308172u }, + { 16716827836597268165u, 1302346568921846537u }, { 11989529279587987770u, 2083754510274954460u }, + { 9591623423670390216u, 1667003608219963568u }, { 15051996368420132820u, 1333602886575970854u }, + { 13015147745246481542u, 2133764618521553367u }, { 3033420566713364587u, 1707011694817242694u }, + { 6116085268112601993u, 1365609355853794155u }, { 9785736428980163188u, 2184974969366070648u }, + { 15207286772667951197u, 1747979975492856518u }, { 1097782973908629988u, 1398383980394285215u }, + { 1756452758253807981u, 2237414368630856344u }, { 5094511021344956708u, 1789931494904685075u }, + { 4075608817075965366u, 1431945195923748060u }, { 6520974107321544586u, 2291112313477996896u }, + { 1527430471115325346u, 1832889850782397517u }, { 12289990821117991246u, 1466311880625918013u }, + { 17210690286378213644u, 1173049504500734410u }, { 9090360384495590213u, 1876879207201175057u }, + { 18340334751822203140u, 1501503365760940045u }, { 14672267801457762512u, 1201202692608752036u }, + { 16096930852848599373u, 1921924308174003258u }, { 1809498238053148529u, 1537539446539202607u }, + { 12515645034668249793u, 1230031557231362085u }, { 1578287981759648052u, 1968050491570179337u }, + { 12330676829633449412u, 1574440393256143469u }, { 13553890278448669853u, 1259552314604914775u }, + { 3239480371808320148u, 2015283703367863641u }, { 17348979556414297411u, 1612226962694290912u }, + { 6500486015647617283u, 1289781570155432730u }, { 10400777625036187652u, 2063650512248692368u }, + { 15699319729512770768u, 1650920409798953894u }, { 16248804598352126938u, 1320736327839163115u }, + { 7551343283653851484u, 2113178124542660985u }, { 6041074626923081187u, 1690542499634128788u }, + { 12211557331022285596u, 1352433999707303030u }, { 1091747655926105338u, 2163894399531684849u }, + { 4562746939482794594u, 1731115519625347879u }, { 7339546366328145998u, 1384892415700278303u }, + { 8053925371383123274u, 2215827865120445285u }, { 6443140297106498619u, 1772662292096356228u }, + { 12533209867169019542u, 1418129833677084982u }, { 5295740528502789974u, 2269007733883335972u }, + { 15304638867027962949u, 1815206187106668777u }, { 4865013464138549713u, 1452164949685335022u }, + { 14960057215536570740u, 1161731959748268017u }, { 9178696285890871890u, 1858771135597228828u }, + { 14721654658196518159u, 1487016908477783062u }, { 4398626097073393881u, 1189613526782226450u }, + { 7037801755317430209u, 1903381642851562320u }, { 5630241404253944167u, 1522705314281249856u }, + { 814844308661245011u, 1218164251424999885u }, { 1303750893857992017u, 1949062802279999816u }, + { 15800395974054034906u, 1559250241823999852u }, { 5261619149759407279u, 1247400193459199882u }, + { 12107939454356961969u, 1995840309534719811u }, { 5997002748743659252u, 1596672247627775849u }, + { 8486951013736837725u, 1277337798102220679u }, { 2511075177753209390u, 2043740476963553087u }, + { 13076906586428298482u, 1634992381570842469u }, { 14150874083884549109u, 1307993905256673975u }, + { 4194654460505726958u, 2092790248410678361u }, { 18113118827372222859u, 1674232198728542688u }, + { 3422448617672047318u, 1339385758982834151u }, { 16543964232501006678u, 2143017214372534641u }, + { 9545822571258895019u, 1714413771498027713u }, { 15015355686490936662u, 1371531017198422170u }, + { 5577825024675947042u, 2194449627517475473u }, { 11840957649224578280u, 1755559702013980378u }, + { 16851463748863483271u, 1404447761611184302u }, { 12204946739213931940u, 2247116418577894884u }, + { 13453306206113055875u, 1797693134862315907u }, { 3383947335406624054u, 1438154507889852726u }, + { 16482362180876329456u, 2301047212623764361u }, { 9496540929959153242u, 1840837770099011489u }, + { 11286581558709232917u, 1472670216079209191u }, { 5339916432225476010u, 1178136172863367353u }, + { 4854517476818851293u, 1885017876581387765u }, { 3883613981455081034u, 1508014301265110212u }, + { 14174937629389795797u, 1206411441012088169u }, { 11611853762797942306u, 1930258305619341071u }, + { 5600134195496443521u, 1544206644495472857u }, { 15548153800622885787u, 1235365315596378285u }, + { 6430302007287065643u, 1976584504954205257u }, { 16212288050055383484u, 1581267603963364205u }, + { 12969830440044306787u, 1265014083170691364u }, { 9683682259845159889u, 2024022533073106183u }, + { 15125643437359948558u, 1619218026458484946u }, { 8411165935146048523u, 1295374421166787957u }, + { 17147214310975587960u, 2072599073866860731u }, { 10028422634038560045u, 1658079259093488585u }, + { 8022738107230848036u, 1326463407274790868u }, { 9147032156827446534u, 2122341451639665389u }, + { 11006974540203867551u, 1697873161311732311u }, { 5116230817421183718u, 1358298529049385849u }, + { 15564666937357714594u, 2173277646479017358u }, { 1383687105660440706u, 1738622117183213887u }, + { 12174996128754083534u, 1390897693746571109u }, { 8411947361780802685u, 2225436309994513775u }, + { 6729557889424642148u, 1780349047995611020u }, { 5383646311539713719u, 1424279238396488816u }, + { 1235136468979721303u, 2278846781434382106u }, { 15745504434151418335u, 1823077425147505684u }, + { 16285752362063044992u, 1458461940118004547u }, { 5649904260166615347u, 1166769552094403638u }, + { 5350498001524674232u, 1866831283351045821u }, { 591049586477829062u, 1493465026680836657u }, + { 11540886113407994219u, 1194772021344669325u }, { 18673707743239135u, 1911635234151470921u }, + { 14772334225162232601u, 1529308187321176736u }, { 8128518565387875758u, 1223446549856941389u }, + { 1937583260394870242u, 1957514479771106223u }, { 8928764237799716840u, 1566011583816884978u }, + { 14521709019723594119u, 1252809267053507982u }, { 8477339172590109297u, 2004494827285612772u }, + { 17849917782297818407u, 1603595861828490217u }, { 6901236596354434079u, 1282876689462792174u }, + { 18420676183650915173u, 2052602703140467478u }, { 3668494502695001169u, 1642082162512373983u }, + { 10313493231639821582u, 1313665730009899186u }, { 9122891541139893884u, 2101865168015838698u }, + { 14677010862395735754u, 1681492134412670958u }, { 673562245690857633u, 1345193707530136767u } +}; + +static const uint64_t DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = { + { 0u, 1152921504606846976u }, { 0u, 1441151880758558720u }, + { 0u, 1801439850948198400u }, { 0u, 2251799813685248000u }, + { 0u, 1407374883553280000u }, { 0u, 1759218604441600000u }, + { 0u, 2199023255552000000u }, { 0u, 1374389534720000000u }, + { 0u, 1717986918400000000u }, { 0u, 2147483648000000000u }, + { 0u, 1342177280000000000u }, { 0u, 1677721600000000000u }, + { 0u, 2097152000000000000u }, { 0u, 1310720000000000000u }, + { 0u, 1638400000000000000u }, { 0u, 2048000000000000000u }, + { 0u, 1280000000000000000u }, { 0u, 1600000000000000000u }, + { 0u, 2000000000000000000u }, { 0u, 1250000000000000000u }, + { 0u, 1562500000000000000u }, { 0u, 1953125000000000000u }, + { 0u, 1220703125000000000u }, { 0u, 1525878906250000000u }, + { 0u, 1907348632812500000u }, { 0u, 1192092895507812500u }, + { 0u, 1490116119384765625u }, { 4611686018427387904u, 1862645149230957031u }, + { 9799832789158199296u, 1164153218269348144u }, { 12249790986447749120u, 1455191522836685180u }, + { 15312238733059686400u, 1818989403545856475u }, { 14528612397897220096u, 2273736754432320594u }, + { 13692068767113150464u, 1421085471520200371u }, { 12503399940464050176u, 1776356839400250464u }, + { 15629249925580062720u, 2220446049250313080u }, { 9768281203487539200u, 1387778780781445675u }, + { 7598665485932036096u, 1734723475976807094u }, { 274959820560269312u, 2168404344971008868u }, + { 9395221924704944128u, 1355252715606880542u }, { 2520655369026404352u, 1694065894508600678u }, + { 12374191248137781248u, 2117582368135750847u }, { 14651398557727195136u, 1323488980084844279u }, + { 13702562178731606016u, 1654361225106055349u }, { 3293144668132343808u, 2067951531382569187u }, + { 18199116482078572544u, 1292469707114105741u }, { 8913837547316051968u, 1615587133892632177u }, + { 15753982952572452864u, 2019483917365790221u }, { 12152082354571476992u, 1262177448353618888u }, + { 15190102943214346240u, 1577721810442023610u }, { 9764256642163156992u, 1972152263052529513u }, + { 17631875447420442880u, 1232595164407830945u }, { 8204786253993389888u, 1540743955509788682u }, + { 1032610780636961552u, 1925929944387235853u }, { 2951224747111794922u, 1203706215242022408u }, + { 3689030933889743652u, 1504632769052528010u }, { 13834660704216955373u, 1880790961315660012u }, + { 17870034976990372916u, 1175494350822287507u }, { 17725857702810578241u, 1469367938527859384u }, + { 3710578054803671186u, 1836709923159824231u }, { 26536550077201078u, 2295887403949780289u }, + { 11545800389866720434u, 1434929627468612680u }, { 14432250487333400542u, 1793662034335765850u }, + { 8816941072311974870u, 2242077542919707313u }, { 17039803216263454053u, 1401298464324817070u }, + { 12076381983474541759u, 1751623080406021338u }, { 5872105442488401391u, 2189528850507526673u }, + { 15199280947623720629u, 1368455531567204170u }, { 9775729147674874978u, 1710569414459005213u }, + { 16831347453020981627u, 2138211768073756516u }, { 1296220121283337709u, 1336382355046097823u }, + { 15455333206886335848u, 1670477943807622278u }, { 10095794471753144002u, 2088097429759527848u }, + { 6309871544845715001u, 1305060893599704905u }, { 12499025449484531656u, 1631326116999631131u }, + { 11012095793428276666u, 2039157646249538914u }, { 11494245889320060820u, 1274473528905961821u }, + { 532749306367912313u, 1593091911132452277u }, { 5277622651387278295u, 1991364888915565346u }, + { 7910200175544436838u, 1244603055572228341u }, { 14499436237857933952u, 1555753819465285426u }, + { 8900923260467641632u, 1944692274331606783u }, { 12480606065433357876u, 1215432671457254239u }, + { 10989071563364309441u, 1519290839321567799u }, { 9124653435777998898u, 1899113549151959749u }, + { 8008751406574943263u, 1186945968219974843u }, { 5399253239791291175u, 1483682460274968554u }, + { 15972438586593889776u, 1854603075343710692u }, { 759402079766405302u, 1159126922089819183u }, + { 14784310654990170340u, 1448908652612273978u }, { 9257016281882937117u, 1811135815765342473u }, + { 16182956370781059300u, 2263919769706678091u }, { 7808504722524468110u, 1414949856066673807u }, + { 5148944884728197234u, 1768687320083342259u }, { 1824495087482858639u, 2210859150104177824u }, + { 1140309429676786649u, 1381786968815111140u }, { 1425386787095983311u, 1727233711018888925u }, + { 6393419502297367043u, 2159042138773611156u }, { 13219259225790630210u, 1349401336733506972u }, + { 16524074032238287762u, 1686751670916883715u }, { 16043406521870471799u, 2108439588646104644u }, + { 803757039314269066u, 1317774742903815403u }, { 14839754354425000045u, 1647218428629769253u }, + { 4714634887749086344u, 2059023035787211567u }, { 9864175832484260821u, 1286889397367007229u }, + { 16941905809032713930u, 1608611746708759036u }, { 2730638187581340797u, 2010764683385948796u }, + { 10930020904093113806u, 1256727927116217997u }, { 18274212148543780162u, 1570909908895272496u }, + { 4396021111970173586u, 1963637386119090621u }, { 5053356204195052443u, 1227273366324431638u }, + { 15540067292098591362u, 1534091707905539547u }, { 14813398096695851299u, 1917614634881924434u }, + { 13870059828862294966u, 1198509146801202771u }, { 12725888767650480803u, 1498136433501503464u }, + { 15907360959563101004u, 1872670541876879330u }, { 14553786618154326031u, 1170419088673049581u }, + { 4357175217410743827u, 1463023860841311977u }, { 10058155040190817688u, 1828779826051639971u }, + { 7961007781811134206u, 2285974782564549964u }, { 14199001900486734687u, 1428734239102843727u }, + { 13137066357181030455u, 1785917798878554659u }, { 11809646928048900164u, 2232397248598193324u }, + { 16604401366885338411u, 1395248280373870827u }, { 16143815690179285109u, 1744060350467338534u }, + { 10956397575869330579u, 2180075438084173168u }, { 6847748484918331612u, 1362547148802608230u }, + { 17783057643002690323u, 1703183936003260287u }, { 17617136035325974999u, 2128979920004075359u }, + { 17928239049719816230u, 1330612450002547099u }, { 17798612793722382384u, 1663265562503183874u }, + { 13024893955298202172u, 2079081953128979843u }, { 5834715712847682405u, 1299426220705612402u }, + { 16516766677914378815u, 1624282775882015502u }, { 11422586310538197711u, 2030353469852519378u }, + { 11750802462513761473u, 1268970918657824611u }, { 10076817059714813937u, 1586213648322280764u }, + { 12596021324643517422u, 1982767060402850955u }, { 5566670318688504437u, 1239229412751781847u }, + { 2346651879933242642u, 1549036765939727309u }, { 7545000868343941206u, 1936295957424659136u }, + { 4715625542714963254u, 1210184973390411960u }, { 5894531928393704067u, 1512731216738014950u }, + { 16591536947346905892u, 1890914020922518687u }, { 17287239619732898039u, 1181821263076574179u }, + { 16997363506238734644u, 1477276578845717724u }, { 2799960309088866689u, 1846595723557147156u }, + { 10973347230035317489u, 1154122327223216972u }, { 13716684037544146861u, 1442652909029021215u }, + { 12534169028502795672u, 1803316136286276519u }, { 11056025267201106687u, 2254145170357845649u }, + { 18439230838069161439u, 1408840731473653530u }, { 13825666510731675991u, 1761050914342066913u }, + { 3447025083132431277u, 2201313642927583642u }, { 6766076695385157452u, 1375821026829739776u }, + { 8457595869231446815u, 1719776283537174720u }, { 10571994836539308519u, 2149720354421468400u }, + { 6607496772837067824u, 1343575221513417750u }, { 17482743002901110588u, 1679469026891772187u }, + { 17241742735199000331u, 2099336283614715234u }, { 15387775227926763111u, 1312085177259197021u }, + { 5399660979626290177u, 1640106471573996277u }, { 11361262242960250625u, 2050133089467495346u }, + { 11712474920277544544u, 1281333180917184591u }, { 10028907631919542777u, 1601666476146480739u }, + { 7924448521472040567u, 2002083095183100924u }, { 14176152362774801162u, 1251301934489438077u }, + { 3885132398186337741u, 1564127418111797597u }, { 9468101516160310080u, 1955159272639746996u }, + { 15140935484454969608u, 1221974545399841872u }, { 479425281859160394u, 1527468181749802341u }, + { 5210967620751338397u, 1909335227187252926u }, { 17091912818251750210u, 1193334516992033078u }, + { 12141518985959911954u, 1491668146240041348u }, { 15176898732449889943u, 1864585182800051685u }, + { 11791404716994875166u, 1165365739250032303u }, { 10127569877816206054u, 1456707174062540379u }, + { 8047776328842869663u, 1820883967578175474u }, { 836348374198811271u, 2276104959472719343u }, + { 7440246761515338900u, 1422565599670449589u }, { 13911994470321561530u, 1778206999588061986u }, + { 8166621051047176104u, 2222758749485077483u }, { 2798295147690791113u, 1389224218428173427u }, + { 17332926989895652603u, 1736530273035216783u }, { 17054472718942177850u, 2170662841294020979u }, + { 8353202440125167204u, 1356664275808763112u }, { 10441503050156459005u, 1695830344760953890u }, + { 3828506775840797949u, 2119787930951192363u }, { 86973725686804766u, 1324867456844495227u }, + { 13943775212390669669u, 1656084321055619033u }, { 3594660960206173375u, 2070105401319523792u }, + { 2246663100128858359u, 1293815875824702370u }, { 12031700912015848757u, 1617269844780877962u }, + { 5816254103165035138u, 2021587305976097453u }, { 5941001823691840913u, 1263492066235060908u }, + { 7426252279614801142u, 1579365082793826135u }, { 4671129331091113523u, 1974206353492282669u }, + { 5225298841145639904u, 1233878970932676668u }, { 6531623551432049880u, 1542348713665845835u }, + { 3552843420862674446u, 1927935892082307294u }, { 16055585193321335241u, 1204959932551442058u }, + { 10846109454796893243u, 1506199915689302573u }, { 18169322836923504458u, 1882749894611628216u }, + { 11355826773077190286u, 1176718684132267635u }, { 9583097447919099954u, 1470898355165334544u }, + { 11978871809898874942u, 1838622943956668180u }, { 14973589762373593678u, 2298278679945835225u }, + { 2440964573842414192u, 1436424174966147016u }, { 3051205717303017741u, 1795530218707683770u }, + { 13037379183483547984u, 2244412773384604712u }, { 8148361989677217490u, 1402757983365377945u }, + { 14797138505523909766u, 1753447479206722431u }, { 13884737113477499304u, 2191809349008403039u }, + { 15595489723564518921u, 1369880843130251899u }, { 14882676136028260747u, 1712351053912814874u }, + { 9379973133180550126u, 2140438817391018593u }, { 17391698254306313589u, 1337774260869386620u }, + { 3292878744173340370u, 1672217826086733276u }, { 4116098430216675462u, 2090272282608416595u }, + { 266718509671728212u, 1306420176630260372u }, { 333398137089660265u, 1633025220787825465u }, + { 5028433689789463235u, 2041281525984781831u }, { 10060300083759496378u, 1275800953740488644u }, + { 12575375104699370472u, 1594751192175610805u }, { 1884160825592049379u, 1993438990219513507u }, + { 17318501580490888525u, 1245899368887195941u }, { 7813068920331446945u, 1557374211108994927u }, + { 5154650131986920777u, 1946717763886243659u }, { 915813323278131534u, 1216698602428902287u }, + { 14979824709379828129u, 1520873253036127858u }, { 9501408849870009354u, 1901091566295159823u }, + { 12855909558809837702u, 1188182228934474889u }, { 2234828893230133415u, 1485227786168093612u }, + { 2793536116537666769u, 1856534732710117015u }, { 8663489100477123587u, 1160334207943823134u }, + { 1605989338741628675u, 1450417759929778918u }, { 11230858710281811652u, 1813022199912223647u }, + { 9426887369424876662u, 2266277749890279559u }, { 12809333633531629769u, 1416423593681424724u }, + { 16011667041914537212u, 1770529492101780905u }, { 6179525747111007803u, 2213161865127226132u }, + { 13085575628799155685u, 1383226165704516332u }, { 16356969535998944606u, 1729032707130645415u }, + { 15834525901571292854u, 2161290883913306769u }, { 2979049660840976177u, 1350806802445816731u }, + { 17558870131333383934u, 1688508503057270913u }, { 8113529608884566205u, 2110635628821588642u }, + { 9682642023980241782u, 1319147268013492901u }, { 16714988548402690132u, 1648934085016866126u }, + { 11670363648648586857u, 2061167606271082658u }, { 11905663298832754689u, 1288229753919426661u }, + { 1047021068258779650u, 1610287192399283327u }, { 15143834390605638274u, 2012858990499104158u }, + { 4853210475701136017u, 1258036869061940099u }, { 1454827076199032118u, 1572546086327425124u }, + { 1818533845248790147u, 1965682607909281405u }, { 3442426662494187794u, 1228551629943300878u }, + { 13526405364972510550u, 1535689537429126097u }, { 3072948650933474476u, 1919611921786407622u }, + { 15755650962115585259u, 1199757451116504763u }, { 15082877684217093670u, 1499696813895630954u }, + { 9630225068416591280u, 1874621017369538693u }, { 8324733676974063502u, 1171638135855961683u }, + { 5794231077790191473u, 1464547669819952104u }, { 7242788847237739342u, 1830684587274940130u }, + { 18276858095901949986u, 2288355734093675162u }, { 16034722328366106645u, 1430222333808546976u }, + { 1596658836748081690u, 1787777917260683721u }, { 6607509564362490017u, 2234722396575854651u }, + { 1823850468512862308u, 1396701497859909157u }, { 6891499104068465790u, 1745876872324886446u }, + { 17837745916940358045u, 2182346090406108057u }, { 4231062170446641922u, 1363966306503817536u }, + { 5288827713058302403u, 1704957883129771920u }, { 6611034641322878003u, 2131197353912214900u }, + { 13355268687681574560u, 1331998346195134312u }, { 16694085859601968200u, 1664997932743917890u }, + { 11644235287647684442u, 2081247415929897363u }, { 4971804045566108824u, 1300779634956185852u }, + { 6214755056957636030u, 1625974543695232315u }, { 3156757802769657134u, 2032468179619040394u }, + { 6584659645158423613u, 1270292612261900246u }, { 17454196593302805324u, 1587865765327375307u }, + { 17206059723201118751u, 1984832206659219134u }, { 6142101308573311315u, 1240520129162011959u }, + { 3065940617289251240u, 1550650161452514949u }, { 8444111790038951954u, 1938312701815643686u }, + { 665883850346957067u, 1211445438634777304u }, { 832354812933696334u, 1514306798293471630u }, + { 10263815553021896226u, 1892883497866839537u }, { 17944099766707154901u, 1183052186166774710u }, + { 13206752671529167818u, 1478815232708468388u }, { 16508440839411459773u, 1848519040885585485u }, + { 12623618533845856310u, 1155324400553490928u }, { 15779523167307320387u, 1444155500691863660u }, + { 1277659885424598868u, 1805194375864829576u }, { 1597074856780748586u, 2256492969831036970u }, + { 5609857803915355770u, 1410308106144398106u }, { 16235694291748970521u, 1762885132680497632u }, + { 1847873790976661535u, 2203606415850622041u }, { 12684136165428883219u, 1377254009906638775u }, + { 11243484188358716120u, 1721567512383298469u }, { 219297180166231438u, 2151959390479123087u }, + { 7054589765244976505u, 1344974619049451929u }, { 13429923224983608535u, 1681218273811814911u }, + { 12175718012802122765u, 2101522842264768639u }, { 14527352785642408584u, 1313451776415480399u }, + { 13547504963625622826u, 1641814720519350499u }, { 12322695186104640628u, 2052268400649188124u }, + { 16925056528170176201u, 1282667750405742577u }, { 7321262604930556539u, 1603334688007178222u }, + { 18374950293017971482u, 2004168360008972777u }, { 4566814905495150320u, 1252605225005607986u }, + { 14931890668723713708u, 1565756531257009982u }, { 9441491299049866327u, 1957195664071262478u }, + { 1289246043478778550u, 1223247290044539049u }, { 6223243572775861092u, 1529059112555673811u }, + { 3167368447542438461u, 1911323890694592264u }, { 1979605279714024038u, 1194577431684120165u }, + { 7086192618069917952u, 1493221789605150206u }, { 18081112809442173248u, 1866527237006437757u }, + { 13606538515115052232u, 1166579523129023598u }, { 7784801107039039482u, 1458224403911279498u }, + { 507629346944023544u, 1822780504889099373u }, { 5246222702107417334u, 2278475631111374216u }, + { 3278889188817135834u, 1424047269444608885u }, { 8710297504448807696u, 1780059086805761106u } +}; + +// IEEE 754 double precision constants +#define DOUBLE_MANTISSA_BITS 52 +#define DOUBLE_EXPONENT_BITS 11 +#define DOUBLE_EXPONENT_BIAS 1023 + +// Helper: floor(log2(value)) using ryu_leading_zeros64 +static inline uint32_t floor_log2(const uint64_t value) { + return 63 - ryu_leading_zeros64(value); +} + +// Helper: log2(5^e) approximation +static inline int32_t log2pow5(const int32_t e) { + return (int32_t) ((((uint32_t) e) * 1217359) >> 19); +} + +// Helper: ceil(log2(5^e)) +static inline int32_t ceil_log2pow5(const int32_t e) { + return log2pow5(e) + 1; +} + +// Helper: max of two int32 +static inline int32_t max32(int32_t a, int32_t b) { + return a < b ? b : a; +} + +// Helper: convert uint64 bits to double +static inline double int64Bits2Double(uint64_t bits) { + double f; + memcpy(&f, &bits, sizeof(double)); + return f; +} + +// Check if value is multiple of 2^p +static inline bool multipleOfPowerOf2(const uint64_t value, const uint32_t p) { + return (value & ((1ull << p) - 1)) == 0; +} + +// Count how many times value is divisible by 5 +// Uses modular inverse to avoid expensive division +static inline uint32_t pow5Factor(uint64_t value) { + const uint64_t m_inv_5 = 14757395258967641293u; // 5 * m_inv_5 = 1 (mod 2^64) + const uint64_t n_div_5 = 3689348814741910323u; // 2^64 / 5 + uint32_t count = 0; + for (;;) { + value *= m_inv_5; + if (value > n_div_5) + break; + ++count; + } + return count; +} + +// Check if value is multiple of 5^p +// Optimized: uses modular inverse instead of division +static inline bool multipleOfPowerOf5(const uint64_t value, const uint32_t p) { + return pow5Factor(value) >= p; +} + +// 128-bit multiplication with shift +// This is the core operation for converting decimal to binary +#if defined(__SIZEOF_INT128__) +// Use native 128-bit integers if available (GCC/Clang) +static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { + const unsigned __int128 b0 = ((unsigned __int128) m) * mul[0]; + const unsigned __int128 b2 = ((unsigned __int128) m) * mul[1]; + return (uint64_t) (((b0 >> 64) + b2) >> (j - 64)); +} +#else +// Fallback for systems without 128-bit integers +static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { + const uint32_t aLo = (uint32_t)a; + const uint32_t aHi = (uint32_t)(a >> 32); + const uint32_t bLo = (uint32_t)b; + const uint32_t bHi = (uint32_t)(b >> 32); + + const uint64_t b00 = (uint64_t)aLo * bLo; + const uint64_t b01 = (uint64_t)aLo * bHi; + const uint64_t b10 = (uint64_t)aHi * bLo; + const uint64_t b11 = (uint64_t)aHi * bHi; + + const uint32_t b00Lo = (uint32_t)b00; + const uint32_t b00Hi = (uint32_t)(b00 >> 32); + + const uint64_t mid1 = b10 + b00Hi; + const uint32_t mid1Lo = (uint32_t)(mid1); + const uint32_t mid1Hi = (uint32_t)(mid1 >> 32); + + const uint64_t mid2 = b01 + mid1Lo; + const uint32_t mid2Lo = (uint32_t)(mid2); + const uint32_t mid2Hi = (uint32_t)(mid2 >> 32); + + const uint64_t pHi = b11 + mid1Hi + mid2Hi; + const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo; + + *productHi = pHi; + return pLo; +} + +static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { + return (hi << (64 - dist)) | (lo >> dist); +} + +static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { + uint64_t high1; + const uint64_t low1 = umul128(m, mul[1], &high1); + uint64_t high0; + umul128(m, mul[0], &high0); + const uint64_t sum = high0 + low1; + if (sum < high0) { + ++high1; + } + return shiftright128(sum, high1, j - 64); +} +#endif + +// Main conversion function: decimal mantissa+exponent to IEEE 754 double +// Optimized for JSON parsing with fast paths for edge cases +static inline double ryu_s2d_from_parts(uint64_t m10, int m10digits, int32_t e10, bool signedM) { + // Fast path: handle zero explicitly (e.g., "0.0", "0e0") + if (m10 == 0) { + return int64Bits2Double(((uint64_t) signedM) << 63); + } + + // Fast path: handle overflow/underflow early + if (m10digits + e10 <= -324) { + // Underflow to zero + return int64Bits2Double(((uint64_t) signedM) << 63); + } + + if (m10digits + e10 >= 310) { + // Overflow to infinity + return int64Bits2Double((((uint64_t) signedM) << 63) | 0x7ff0000000000000ULL); + } + + // Convert decimal to binary: m10 * 10^e10 = m2 * 2^e2 + int32_t e2; + uint64_t m2; + bool trailingZeros; + + if (e10 >= 0) { + // Positive exponent: multiply by 5^e10 and adjust binary exponent + e2 = floor_log2(m10) + e10 + log2pow5(e10) - (DOUBLE_MANTISSA_BITS + 1); + int j = e2 - e10 - ceil_log2pow5(e10) + DOUBLE_POW5_BITCOUNT; + m2 = mulShift64(m10, DOUBLE_POW5_SPLIT[e10], j); + trailingZeros = e2 < e10 || (e2 - e10 < 64 && multipleOfPowerOf2(m10, e2 - e10)); + } else { + // Negative exponent: divide by 5^(-e10) + e2 = floor_log2(m10) + e10 - ceil_log2pow5(-e10) - (DOUBLE_MANTISSA_BITS + 1); + int j = e2 - e10 + ceil_log2pow5(-e10) - 1 + DOUBLE_POW5_INV_BITCOUNT; + m2 = mulShift64(m10, DOUBLE_POW5_INV_SPLIT[-e10], j); + trailingZeros = multipleOfPowerOf5(m10, -e10); + } + + // Compute IEEE 754 exponent + uint32_t ieee_e2 = (uint32_t) max32(0, e2 + DOUBLE_EXPONENT_BIAS + floor_log2(m2)); + + if (ieee_e2 > 0x7fe) { + // Overflow to infinity + return int64Bits2Double((((uint64_t) signedM) << 63) | 0x7ff0000000000000ULL); + } + + // Compute shift amount for rounding + int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - DOUBLE_EXPONENT_BIAS - DOUBLE_MANTISSA_BITS; + + // IEEE 754 round-to-even (banker's rounding) + trailingZeros &= (m2 & ((1ull << (shift - 1)) - 1)) == 0; + uint64_t lastRemovedBit = (m2 >> (shift - 1)) & 1; + bool roundUp = (lastRemovedBit != 0) && (!trailingZeros || (((m2 >> shift) & 1) != 0)); + + uint64_t ieee_m2 = (m2 >> shift) + roundUp; + ieee_m2 &= (1ull << DOUBLE_MANTISSA_BITS) - 1; + + if (ieee_m2 == 0 && roundUp) { + ieee_e2++; + } + + // Pack sign, exponent, and mantissa into IEEE 754 format + // Match original Ryu: group sign+exponent, then shift and add mantissa + uint64_t ieee = (((((uint64_t) signedM) << DOUBLE_EXPONENT_BITS) | (uint64_t)ieee_e2) << DOUBLE_MANTISSA_BITS) | ieee_m2; + return int64Bits2Double(ieee); +} + +#endif // RYU_H diff --git a/ext/monitor/depend b/ext/monitor/depend index 2e3ba40928..0c7d54afc8 100644 --- a/ext/monitor/depend +++ b/ext/monitor/depend @@ -1,6 +1,19 @@ # AUTOGENERATED DEPENDENCIES START monitor.o: $(RUBY_EXTCONF_H) monitor.o: $(arch_hdrdir)/ruby/config.h +monitor.o: $(hdrdir)/ruby/assert.h +monitor.o: $(hdrdir)/ruby/backward.h +monitor.o: $(hdrdir)/ruby/backward/2/assume.h +monitor.o: $(hdrdir)/ruby/backward/2/attributes.h +monitor.o: $(hdrdir)/ruby/backward/2/bool.h +monitor.o: $(hdrdir)/ruby/backward/2/inttypes.h +monitor.o: $(hdrdir)/ruby/backward/2/limits.h +monitor.o: $(hdrdir)/ruby/backward/2/long_long.h +monitor.o: $(hdrdir)/ruby/backward/2/stdalign.h +monitor.o: $(hdrdir)/ruby/backward/2/stdarg.h +monitor.o: $(hdrdir)/ruby/defines.h +monitor.o: $(hdrdir)/ruby/intern.h +monitor.o: $(hdrdir)/ruby/internal/abi.h monitor.o: $(hdrdir)/ruby/internal/anyargs.h monitor.o: $(hdrdir)/ruby/internal/arithmetic.h monitor.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -38,6 +51,7 @@ monitor.o: $(hdrdir)/ruby/internal/attr/noexcept.h monitor.o: $(hdrdir)/ruby/internal/attr/noinline.h monitor.o: $(hdrdir)/ruby/internal/attr/nonnull.h monitor.o: $(hdrdir)/ruby/internal/attr/noreturn.h +monitor.o: $(hdrdir)/ruby/internal/attr/packed_struct.h monitor.o: $(hdrdir)/ruby/internal/attr/pure.h monitor.o: $(hdrdir)/ruby/internal/attr/restrict.h monitor.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -97,7 +111,6 @@ monitor.o: $(hdrdir)/ruby/internal/intern/enumerator.h monitor.o: $(hdrdir)/ruby/internal/intern/error.h monitor.o: $(hdrdir)/ruby/internal/intern/eval.h monitor.o: $(hdrdir)/ruby/internal/intern/file.h -monitor.o: $(hdrdir)/ruby/internal/intern/gc.h monitor.o: $(hdrdir)/ruby/internal/intern/hash.h monitor.o: $(hdrdir)/ruby/internal/intern/io.h monitor.o: $(hdrdir)/ruby/internal/intern/load.h @@ -114,6 +127,7 @@ monitor.o: $(hdrdir)/ruby/internal/intern/re.h monitor.o: $(hdrdir)/ruby/internal/intern/ruby.h monitor.o: $(hdrdir)/ruby/internal/intern/select.h monitor.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +monitor.o: $(hdrdir)/ruby/internal/intern/set.h monitor.o: $(hdrdir)/ruby/internal/intern/signal.h monitor.o: $(hdrdir)/ruby/internal/intern/sprintf.h monitor.o: $(hdrdir)/ruby/internal/intern/string.h @@ -128,31 +142,18 @@ monitor.o: $(hdrdir)/ruby/internal/memory.h monitor.o: $(hdrdir)/ruby/internal/method.h monitor.o: $(hdrdir)/ruby/internal/module.h monitor.o: $(hdrdir)/ruby/internal/newobj.h -monitor.o: $(hdrdir)/ruby/internal/rgengc.h monitor.o: $(hdrdir)/ruby/internal/scan_args.h monitor.o: $(hdrdir)/ruby/internal/special_consts.h monitor.o: $(hdrdir)/ruby/internal/static_assert.h monitor.o: $(hdrdir)/ruby/internal/stdalign.h monitor.o: $(hdrdir)/ruby/internal/stdbool.h +monitor.o: $(hdrdir)/ruby/internal/stdckdint.h monitor.o: $(hdrdir)/ruby/internal/symbol.h monitor.o: $(hdrdir)/ruby/internal/value.h monitor.o: $(hdrdir)/ruby/internal/value_type.h monitor.o: $(hdrdir)/ruby/internal/variable.h monitor.o: $(hdrdir)/ruby/internal/warning_push.h monitor.o: $(hdrdir)/ruby/internal/xmalloc.h -monitor.o: $(hdrdir)/ruby/assert.h -monitor.o: $(hdrdir)/ruby/backward.h -monitor.o: $(hdrdir)/ruby/backward/2/assume.h -monitor.o: $(hdrdir)/ruby/backward/2/attributes.h -monitor.o: $(hdrdir)/ruby/backward/2/bool.h -monitor.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -monitor.o: $(hdrdir)/ruby/backward/2/inttypes.h -monitor.o: $(hdrdir)/ruby/backward/2/limits.h -monitor.o: $(hdrdir)/ruby/backward/2/long_long.h -monitor.o: $(hdrdir)/ruby/backward/2/stdalign.h -monitor.o: $(hdrdir)/ruby/backward/2/stdarg.h -monitor.o: $(hdrdir)/ruby/defines.h -monitor.o: $(hdrdir)/ruby/intern.h monitor.o: $(hdrdir)/ruby/missing.h monitor.o: $(hdrdir)/ruby/ruby.h monitor.o: $(hdrdir)/ruby/st.h diff --git a/ext/monitor/lib/monitor.rb b/ext/monitor/lib/monitor.rb index 11c5ac17d9..82d0a75c56 100644 --- a/ext/monitor/lib/monitor.rb +++ b/ext/monitor/lib/monitor.rb @@ -7,17 +7,19 @@ # You can freely distribute/modify this library. # +require 'monitor.so' + # # In concurrent programming, a monitor is an object or module intended to be -# used safely by more than one thread. The defining characteristic of a -# monitor is that its methods are executed with mutual exclusion. That is, at +# used safely by more than one thread. The defining characteristic of a +# monitor is that its methods are executed with mutual exclusion. That is, at # each point in time, at most one thread may be executing any of its methods. # This mutual exclusion greatly simplifies reasoning about the implementation # of monitors compared to reasoning about parallel code that updates a data # structure. # # You can read more about the general principles on the Wikipedia page for -# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29] +# Monitors[https://en.wikipedia.org/wiki/Monitor_%28synchronization%29]. # # == Examples # @@ -48,7 +50,7 @@ # end # # The consumer thread waits for the producer thread to push a line to buf -# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a +# while <tt>buf.empty?</tt>. The producer thread (main thread) reads a # line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt> # to notify the consumer thread of new data. # @@ -86,9 +88,6 @@ # This Class is implemented as subclass of Array which includes the # MonitorMixin module. # - -require 'monitor.so' - module MonitorMixin # # FIXME: This isn't documented in Nutshell. @@ -144,13 +143,13 @@ module MonitorMixin private - def initialize(monitor) + def initialize(monitor) # :nodoc: @monitor = monitor @cond = Thread::ConditionVariable.new end end - def self.extend_object(obj) + def self.extend_object(obj) # :nodoc: super(obj) obj.__send__(:mon_initialize) end @@ -239,6 +238,8 @@ module MonitorMixin @mon_data_owner_object_id = self.object_id end + # Ensures that the MonitorMixin is owned by the current thread, + # otherwise raises an exception. def mon_check_owner @mon_data.mon_check_owner end @@ -255,6 +256,10 @@ end # end # class Monitor + # + # Creates a new MonitorMixin::ConditionVariable associated with the + # Monitor object. + # def new_cond ::MonitorMixin::ConditionVariable.new(self) end diff --git a/ext/monitor/monitor.c b/ext/monitor/monitor.c index 10209cf2aa..c43751c4e2 100644 --- a/ext/monitor/monitor.c +++ b/ext/monitor/monitor.c @@ -4,28 +4,35 @@ struct rb_monitor { long count; - const VALUE owner; - const VALUE mutex; + VALUE owner; + VALUE mutex; }; static void monitor_mark(void *ptr) { struct rb_monitor *mc = ptr; - rb_gc_mark(mc->owner); - rb_gc_mark(mc->mutex); + rb_gc_mark_movable(mc->owner); + rb_gc_mark_movable(mc->mutex); } -static size_t -monitor_memsize(const void *ptr) +static void +monitor_compact(void *ptr) { - return sizeof(struct rb_monitor); + struct rb_monitor *mc = ptr; + mc->owner = rb_gc_location(mc->owner); + mc->mutex = rb_gc_location(mc->mutex); } static const rb_data_type_t monitor_data_type = { - "monitor", - {monitor_mark, RUBY_TYPED_DEFAULT_FREE, monitor_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED + .wrap_struct_name = "monitor", + .function = { + .dmark = monitor_mark, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = NULL, // Fully embeded + .dcompact = monitor_compact, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static VALUE @@ -50,68 +57,124 @@ monitor_ptr(VALUE monitor) return mc; } -static int -mc_owner_p(struct rb_monitor *mc) +static bool +mc_owner_p(struct rb_monitor *mc, VALUE current_fiber) { - return mc->owner == rb_fiber_current(); + return mc->owner == current_fiber; } +/* + * call-seq: + * try_enter -> true or false + * + * Attempts to enter exclusive section. Returns +false+ if lock fails. + */ static VALUE monitor_try_enter(VALUE monitor) { struct rb_monitor *mc = monitor_ptr(monitor); - if (!mc_owner_p(mc)) { + VALUE current_fiber = rb_fiber_current(); + if (!mc_owner_p(mc, current_fiber)) { if (!rb_mutex_trylock(mc->mutex)) { return Qfalse; } - RB_OBJ_WRITE(monitor, &mc->owner, rb_fiber_current()); + RB_OBJ_WRITE(monitor, &mc->owner, current_fiber); mc->count = 0; } mc->count += 1; return Qtrue; } + +struct monitor_args { + VALUE monitor; + struct rb_monitor *mc; + VALUE current_fiber; +}; + +static inline void +monitor_args_init(struct monitor_args *args, VALUE monitor) +{ + args->monitor = monitor; + args->mc = monitor_ptr(monitor); + args->current_fiber = rb_fiber_current(); +} + +static void +monitor_enter0(struct monitor_args *args) +{ + if (!mc_owner_p(args->mc, args->current_fiber)) { + rb_mutex_lock(args->mc->mutex); + RB_OBJ_WRITE(args->monitor, &args->mc->owner, args->current_fiber); + args->mc->count = 0; + } + args->mc->count++; +} + +/* + * call-seq: + * enter -> nil + * + * Enters exclusive section. + */ static VALUE monitor_enter(VALUE monitor) { - struct rb_monitor *mc = monitor_ptr(monitor); - if (!mc_owner_p(mc)) { - rb_mutex_lock(mc->mutex); - RB_OBJ_WRITE(monitor, &mc->owner, rb_fiber_current()); - mc->count = 0; - } - mc->count++; + struct monitor_args args; + monitor_args_init(&args, monitor); + monitor_enter0(&args); return Qnil; } -static VALUE -monitor_check_owner(VALUE monitor) +static inline void +monitor_check_owner0(struct monitor_args *args) { - struct rb_monitor *mc = monitor_ptr(monitor); - if (!mc_owner_p(mc)) { + if (!mc_owner_p(args->mc, args->current_fiber)) { rb_raise(rb_eThreadError, "current fiber not owner"); } - return Qnil; } +/* :nodoc: */ static VALUE -monitor_exit(VALUE monitor) +monitor_check_owner(VALUE monitor) { - monitor_check_owner(monitor); + struct monitor_args args; + monitor_args_init(&args, monitor); + monitor_check_owner0(&args); + return Qnil; +} - struct rb_monitor *mc = monitor_ptr(monitor); +static void +monitor_exit0(struct monitor_args *args) +{ + monitor_check_owner0(args); - if (mc->count <= 0) rb_bug("monitor_exit: count:%d\n", (int)mc->count); - mc->count--; + if (args->mc->count <= 0) rb_bug("monitor_exit: count:%d", (int)args->mc->count); + args->mc->count--; - if (mc->count == 0) { - RB_OBJ_WRITE(monitor, &mc->owner, Qnil); - rb_mutex_unlock(mc->mutex); + if (args->mc->count == 0) { + RB_OBJ_WRITE(args->monitor, &args->mc->owner, Qnil); + rb_mutex_unlock(args->mc->mutex); } +} + +/* + * call-seq: + * exit -> nil + * + * Leaves exclusive section. + */ +static VALUE +monitor_exit(VALUE monitor) +{ + struct monitor_args args; + monitor_args_init(&args, monitor); + monitor_exit0(&args); return Qnil; } +/* :nodoc: */ static VALUE monitor_locked_p(VALUE monitor) { @@ -119,11 +182,12 @@ monitor_locked_p(VALUE monitor) return rb_mutex_locked_p(mc->mutex); } +/* :nodoc: */ static VALUE monitor_owned_p(VALUE monitor) { struct rb_monitor *mc = monitor_ptr(monitor); - return (rb_mutex_locked_p(mc->mutex) && mc_owner_p(mc)) ? Qtrue : Qfalse; + return rb_mutex_locked_p(mc->mutex) && mc_owner_p(mc, rb_fiber_current()) ? Qtrue : Qfalse; } static VALUE @@ -166,6 +230,7 @@ monitor_enter_for_cond(VALUE v) return Qnil; } +/* :nodoc: */ static VALUE monitor_wait_for_cond(VALUE monitor, VALUE cond, VALUE timeout) { @@ -188,16 +253,27 @@ monitor_sync_body(VALUE monitor) } static VALUE -monitor_sync_ensure(VALUE monitor) +monitor_sync_ensure(VALUE v_args) { - return monitor_exit(monitor); + monitor_exit0((struct monitor_args *)v_args); + return Qnil; } +/* + * call-seq: + * synchronize { } -> result of the block + * + * Enters exclusive section and executes the block. Leaves the exclusive + * section automatically when the block exits. See example under + * +MonitorMixin+. + */ static VALUE monitor_synchronize(VALUE monitor) { - monitor_enter(monitor); - return rb_ensure(monitor_sync_body, monitor, monitor_sync_ensure, monitor); + struct monitor_args args; + monitor_args_init(&args, monitor); + monitor_enter0(&args); + return rb_ensure(monitor_sync_body, (VALUE)&args, monitor_sync_ensure, (VALUE)&args); } void diff --git a/ext/nkf/depend b/ext/nkf/depend deleted file mode 100644 index b66458cd19..0000000000 --- a/ext/nkf/depend +++ /dev/null @@ -1,182 +0,0 @@ -# BSD make needs "nkf.o: nkf.c" dependency BEFORE "nkf.o: nkf-utf8/nkf.c". -# It seems BSD make searches the target for implicit rule in dependencies at first. -nkf.o: nkf.c - -# AUTOGENERATED DEPENDENCIES START -nkf.o: $(RUBY_EXTCONF_H) -nkf.o: $(arch_hdrdir)/ruby/config.h -nkf.o: $(hdrdir)/ruby/assert.h -nkf.o: $(hdrdir)/ruby/backward.h -nkf.o: $(hdrdir)/ruby/backward/2/assume.h -nkf.o: $(hdrdir)/ruby/backward/2/attributes.h -nkf.o: $(hdrdir)/ruby/backward/2/bool.h -nkf.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -nkf.o: $(hdrdir)/ruby/backward/2/inttypes.h -nkf.o: $(hdrdir)/ruby/backward/2/limits.h -nkf.o: $(hdrdir)/ruby/backward/2/long_long.h -nkf.o: $(hdrdir)/ruby/backward/2/stdalign.h -nkf.o: $(hdrdir)/ruby/backward/2/stdarg.h -nkf.o: $(hdrdir)/ruby/defines.h -nkf.o: $(hdrdir)/ruby/encoding.h -nkf.o: $(hdrdir)/ruby/intern.h -nkf.o: $(hdrdir)/ruby/internal/anyargs.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/char.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/double.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/int.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/long.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/short.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -nkf.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -nkf.o: $(hdrdir)/ruby/internal/assume.h -nkf.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -nkf.o: $(hdrdir)/ruby/internal/attr/artificial.h -nkf.o: $(hdrdir)/ruby/internal/attr/cold.h -nkf.o: $(hdrdir)/ruby/internal/attr/const.h -nkf.o: $(hdrdir)/ruby/internal/attr/constexpr.h -nkf.o: $(hdrdir)/ruby/internal/attr/deprecated.h -nkf.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -nkf.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -nkf.o: $(hdrdir)/ruby/internal/attr/error.h -nkf.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -nkf.o: $(hdrdir)/ruby/internal/attr/forceinline.h -nkf.o: $(hdrdir)/ruby/internal/attr/format.h -nkf.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -nkf.o: $(hdrdir)/ruby/internal/attr/noalias.h -nkf.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -nkf.o: $(hdrdir)/ruby/internal/attr/noexcept.h -nkf.o: $(hdrdir)/ruby/internal/attr/noinline.h -nkf.o: $(hdrdir)/ruby/internal/attr/nonnull.h -nkf.o: $(hdrdir)/ruby/internal/attr/noreturn.h -nkf.o: $(hdrdir)/ruby/internal/attr/pure.h -nkf.o: $(hdrdir)/ruby/internal/attr/restrict.h -nkf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -nkf.o: $(hdrdir)/ruby/internal/attr/warning.h -nkf.o: $(hdrdir)/ruby/internal/attr/weakref.h -nkf.o: $(hdrdir)/ruby/internal/cast.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -nkf.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -nkf.o: $(hdrdir)/ruby/internal/compiler_since.h -nkf.o: $(hdrdir)/ruby/internal/config.h -nkf.o: $(hdrdir)/ruby/internal/constant_p.h -nkf.o: $(hdrdir)/ruby/internal/core.h -nkf.o: $(hdrdir)/ruby/internal/core/rarray.h -nkf.o: $(hdrdir)/ruby/internal/core/rbasic.h -nkf.o: $(hdrdir)/ruby/internal/core/rbignum.h -nkf.o: $(hdrdir)/ruby/internal/core/rclass.h -nkf.o: $(hdrdir)/ruby/internal/core/rdata.h -nkf.o: $(hdrdir)/ruby/internal/core/rfile.h -nkf.o: $(hdrdir)/ruby/internal/core/rhash.h -nkf.o: $(hdrdir)/ruby/internal/core/robject.h -nkf.o: $(hdrdir)/ruby/internal/core/rregexp.h -nkf.o: $(hdrdir)/ruby/internal/core/rstring.h -nkf.o: $(hdrdir)/ruby/internal/core/rstruct.h -nkf.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -nkf.o: $(hdrdir)/ruby/internal/ctype.h -nkf.o: $(hdrdir)/ruby/internal/dllexport.h -nkf.o: $(hdrdir)/ruby/internal/dosish.h -nkf.o: $(hdrdir)/ruby/internal/encoding/coderange.h -nkf.o: $(hdrdir)/ruby/internal/encoding/ctype.h -nkf.o: $(hdrdir)/ruby/internal/encoding/encoding.h -nkf.o: $(hdrdir)/ruby/internal/encoding/pathname.h -nkf.o: $(hdrdir)/ruby/internal/encoding/re.h -nkf.o: $(hdrdir)/ruby/internal/encoding/sprintf.h -nkf.o: $(hdrdir)/ruby/internal/encoding/string.h -nkf.o: $(hdrdir)/ruby/internal/encoding/symbol.h -nkf.o: $(hdrdir)/ruby/internal/encoding/transcode.h -nkf.o: $(hdrdir)/ruby/internal/error.h -nkf.o: $(hdrdir)/ruby/internal/eval.h -nkf.o: $(hdrdir)/ruby/internal/event.h -nkf.o: $(hdrdir)/ruby/internal/fl_type.h -nkf.o: $(hdrdir)/ruby/internal/gc.h -nkf.o: $(hdrdir)/ruby/internal/glob.h -nkf.o: $(hdrdir)/ruby/internal/globals.h -nkf.o: $(hdrdir)/ruby/internal/has/attribute.h -nkf.o: $(hdrdir)/ruby/internal/has/builtin.h -nkf.o: $(hdrdir)/ruby/internal/has/c_attribute.h -nkf.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -nkf.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -nkf.o: $(hdrdir)/ruby/internal/has/extension.h -nkf.o: $(hdrdir)/ruby/internal/has/feature.h -nkf.o: $(hdrdir)/ruby/internal/has/warning.h -nkf.o: $(hdrdir)/ruby/internal/intern/array.h -nkf.o: $(hdrdir)/ruby/internal/intern/bignum.h -nkf.o: $(hdrdir)/ruby/internal/intern/class.h -nkf.o: $(hdrdir)/ruby/internal/intern/compar.h -nkf.o: $(hdrdir)/ruby/internal/intern/complex.h -nkf.o: $(hdrdir)/ruby/internal/intern/cont.h -nkf.o: $(hdrdir)/ruby/internal/intern/dir.h -nkf.o: $(hdrdir)/ruby/internal/intern/enum.h -nkf.o: $(hdrdir)/ruby/internal/intern/enumerator.h -nkf.o: $(hdrdir)/ruby/internal/intern/error.h -nkf.o: $(hdrdir)/ruby/internal/intern/eval.h -nkf.o: $(hdrdir)/ruby/internal/intern/file.h -nkf.o: $(hdrdir)/ruby/internal/intern/gc.h -nkf.o: $(hdrdir)/ruby/internal/intern/hash.h -nkf.o: $(hdrdir)/ruby/internal/intern/io.h -nkf.o: $(hdrdir)/ruby/internal/intern/load.h -nkf.o: $(hdrdir)/ruby/internal/intern/marshal.h -nkf.o: $(hdrdir)/ruby/internal/intern/numeric.h -nkf.o: $(hdrdir)/ruby/internal/intern/object.h -nkf.o: $(hdrdir)/ruby/internal/intern/parse.h -nkf.o: $(hdrdir)/ruby/internal/intern/proc.h -nkf.o: $(hdrdir)/ruby/internal/intern/process.h -nkf.o: $(hdrdir)/ruby/internal/intern/random.h -nkf.o: $(hdrdir)/ruby/internal/intern/range.h -nkf.o: $(hdrdir)/ruby/internal/intern/rational.h -nkf.o: $(hdrdir)/ruby/internal/intern/re.h -nkf.o: $(hdrdir)/ruby/internal/intern/ruby.h -nkf.o: $(hdrdir)/ruby/internal/intern/select.h -nkf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -nkf.o: $(hdrdir)/ruby/internal/intern/signal.h -nkf.o: $(hdrdir)/ruby/internal/intern/sprintf.h -nkf.o: $(hdrdir)/ruby/internal/intern/string.h -nkf.o: $(hdrdir)/ruby/internal/intern/struct.h -nkf.o: $(hdrdir)/ruby/internal/intern/thread.h -nkf.o: $(hdrdir)/ruby/internal/intern/time.h -nkf.o: $(hdrdir)/ruby/internal/intern/variable.h -nkf.o: $(hdrdir)/ruby/internal/intern/vm.h -nkf.o: $(hdrdir)/ruby/internal/interpreter.h -nkf.o: $(hdrdir)/ruby/internal/iterator.h -nkf.o: $(hdrdir)/ruby/internal/memory.h -nkf.o: $(hdrdir)/ruby/internal/method.h -nkf.o: $(hdrdir)/ruby/internal/module.h -nkf.o: $(hdrdir)/ruby/internal/newobj.h -nkf.o: $(hdrdir)/ruby/internal/rgengc.h -nkf.o: $(hdrdir)/ruby/internal/scan_args.h -nkf.o: $(hdrdir)/ruby/internal/special_consts.h -nkf.o: $(hdrdir)/ruby/internal/static_assert.h -nkf.o: $(hdrdir)/ruby/internal/stdalign.h -nkf.o: $(hdrdir)/ruby/internal/stdbool.h -nkf.o: $(hdrdir)/ruby/internal/symbol.h -nkf.o: $(hdrdir)/ruby/internal/value.h -nkf.o: $(hdrdir)/ruby/internal/value_type.h -nkf.o: $(hdrdir)/ruby/internal/variable.h -nkf.o: $(hdrdir)/ruby/internal/warning_push.h -nkf.o: $(hdrdir)/ruby/internal/xmalloc.h -nkf.o: $(hdrdir)/ruby/missing.h -nkf.o: $(hdrdir)/ruby/onigmo.h -nkf.o: $(hdrdir)/ruby/oniguruma.h -nkf.o: $(hdrdir)/ruby/ruby.h -nkf.o: $(hdrdir)/ruby/st.h -nkf.o: $(hdrdir)/ruby/subst.h -nkf.o: nkf-utf8/config.h -nkf.o: nkf-utf8/nkf.c -nkf.o: nkf-utf8/nkf.h -nkf.o: nkf-utf8/utf8tbl.c -nkf.o: nkf-utf8/utf8tbl.h -nkf.o: nkf.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/nkf/extconf.rb b/ext/nkf/extconf.rb deleted file mode 100644 index f41f6b11dc..0000000000 --- a/ext/nkf/extconf.rb +++ /dev/null @@ -1,3 +0,0 @@ -# frozen_string_literal: false -require 'mkmf' -create_makefile('nkf') diff --git a/ext/nkf/lib/kconv.rb b/ext/nkf/lib/kconv.rb deleted file mode 100644 index f52b755288..0000000000 --- a/ext/nkf/lib/kconv.rb +++ /dev/null @@ -1,283 +0,0 @@ -# frozen_string_literal: false -# -# kconv.rb - Kanji Converter. -# -# $Id$ -# -# ---- -# -# kconv.rb implements the Kconv class for Kanji Converter. Additionally, -# some methods in String classes are added to allow easy conversion. -# - -require 'nkf' - -# -# Kanji Converter for Ruby. -# -module Kconv - # - # Public Constants - # - - #Constant of Encoding - - # Auto-Detect - AUTO = NKF::AUTO - # ISO-2022-JP - JIS = NKF::JIS - # EUC-JP - EUC = NKF::EUC - # Shift_JIS - SJIS = NKF::SJIS - # BINARY - BINARY = NKF::BINARY - # NOCONV - NOCONV = NKF::NOCONV - # ASCII - ASCII = NKF::ASCII - # UTF-8 - UTF8 = NKF::UTF8 - # UTF-16 - UTF16 = NKF::UTF16 - # UTF-32 - UTF32 = NKF::UTF32 - # UNKNOWN - UNKNOWN = NKF::UNKNOWN - - # - # Public Methods - # - - # call-seq: - # Kconv.kconv(str, to_enc, from_enc=nil) - # - # Convert <code>str</code> to <code>to_enc</code>. - # <code>to_enc</code> and <code>from_enc</code> are given as constants of Kconv or Encoding objects. - def kconv(str, to_enc, from_enc=nil) - opt = '' - opt += ' --ic=' + from_enc.to_s if from_enc - opt += ' --oc=' + to_enc.to_s if to_enc - - ::NKF::nkf(opt, str) - end - module_function :kconv - - # - # Encode to - # - - # call-seq: - # Kconv.tojis(str) => string - # - # Convert <code>str</code> to ISO-2022-JP - def tojis(str) - kconv(str, JIS) - end - module_function :tojis - - # call-seq: - # Kconv.toeuc(str) => string - # - # Convert <code>str</code> to EUC-JP - def toeuc(str) - kconv(str, EUC) - end - module_function :toeuc - - # call-seq: - # Kconv.tosjis(str) => string - # - # Convert <code>str</code> to Shift_JIS - def tosjis(str) - kconv(str, SJIS) - end - module_function :tosjis - - # call-seq: - # Kconv.toutf8(str) => string - # - # Convert <code>str</code> to UTF-8 - def toutf8(str) - kconv(str, UTF8) - end - module_function :toutf8 - - # call-seq: - # Kconv.toutf16(str) => string - # - # Convert <code>str</code> to UTF-16 - def toutf16(str) - kconv(str, UTF16) - end - module_function :toutf16 - - # call-seq: - # Kconv.toutf32(str) => string - # - # Convert <code>str</code> to UTF-32 - def toutf32(str) - kconv(str, UTF32) - end - module_function :toutf32 - - # call-seq: - # Kconv.tolocale => string - # - # Convert <code>self</code> to locale encoding - def tolocale(str) - kconv(str, Encoding.locale_charmap) - end - module_function :tolocale - - # - # guess - # - - # call-seq: - # Kconv.guess(str) => encoding - # - # Guess input encoding by NKF.guess - def guess(str) - ::NKF::guess(str) - end - module_function :guess - - # - # isEncoding - # - - # call-seq: - # Kconv.iseuc(str) => true or false - # - # Returns whether input encoding is EUC-JP or not. - # - # *Note* don't expect this return value is MatchData. - def iseuc(str) - str.dup.force_encoding(EUC).valid_encoding? - end - module_function :iseuc - - # call-seq: - # Kconv.issjis(str) => true or false - # - # Returns whether input encoding is Shift_JIS or not. - def issjis(str) - str.dup.force_encoding(SJIS).valid_encoding? - end - module_function :issjis - - # call-seq: - # Kconv.isjis(str) => true or false - # - # Returns whether input encoding is ISO-2022-JP or not. - def isjis(str) - /\A [\t\n\r\x20-\x7E]* - (?: - (?:\x1b \x28 I [\x21-\x7E]* - |\x1b \x28 J [\x21-\x7E]* - |\x1b \x24 @ (?:[\x21-\x7E]{2})* - |\x1b \x24 B (?:[\x21-\x7E]{2})* - |\x1b \x24 \x28 D (?:[\x21-\x7E]{2})* - )* - \x1b \x28 B [\t\n\r\x20-\x7E]* - )* - \z/nox =~ str.dup.force_encoding('BINARY') ? true : false - end - module_function :isjis - - # call-seq: - # Kconv.isutf8(str) => true or false - # - # Returns whether input encoding is UTF-8 or not. - def isutf8(str) - str.dup.force_encoding(UTF8).valid_encoding? - end - module_function :isutf8 -end - -class String - # call-seq: - # String#kconv(to_enc, from_enc) - # - # Convert <code>self</code> to <code>to_enc</code>. - # <code>to_enc</code> and <code>from_enc</code> are given as constants of Kconv or Encoding objects. - def kconv(to_enc, from_enc=nil) - from_enc = self.encoding if !from_enc && self.encoding != Encoding.list[0] - Kconv::kconv(self, to_enc, from_enc) - end - - # - # to Encoding - # - - # call-seq: - # String#tojis => string - # - # Convert <code>self</code> to ISO-2022-JP - def tojis; Kconv.tojis(self) end - - # call-seq: - # String#toeuc => string - # - # Convert <code>self</code> to EUC-JP - def toeuc; Kconv.toeuc(self) end - - # call-seq: - # String#tosjis => string - # - # Convert <code>self</code> to Shift_JIS - def tosjis; Kconv.tosjis(self) end - - # call-seq: - # String#toutf8 => string - # - # Convert <code>self</code> to UTF-8 - def toutf8; Kconv.toutf8(self) end - - # call-seq: - # String#toutf16 => string - # - # Convert <code>self</code> to UTF-16 - def toutf16; Kconv.toutf16(self) end - - # call-seq: - # String#toutf32 => string - # - # Convert <code>self</code> to UTF-32 - def toutf32; Kconv.toutf32(self) end - - # call-seq: - # String#tolocale => string - # - # Convert <code>self</code> to locale encoding - def tolocale; Kconv.tolocale(self) end - - # - # is Encoding - # - - # call-seq: - # String#iseuc => true or false - # - # Returns whether <code>self</code>'s encoding is EUC-JP or not. - def iseuc; Kconv.iseuc(self) end - - # call-seq: - # String#issjis => true or false - # - # Returns whether <code>self</code>'s encoding is Shift_JIS or not. - def issjis; Kconv.issjis(self) end - - # call-seq: - # String#isjis => true or false - # - # Returns whether <code>self</code>'s encoding is ISO-2022-JP or not. - def isjis; Kconv.isjis(self) end - - # call-seq: - # String#isutf8 => true or false - # - # Returns whether <code>self</code>'s encoding is UTF-8 or not. - def isutf8; Kconv.isutf8(self) end -end diff --git a/ext/nkf/nkf-utf8/config.h b/ext/nkf/nkf-utf8/config.h deleted file mode 100644 index 36898c0b4b..0000000000 --- a/ext/nkf/nkf-utf8/config.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -/* UTF8 input and output */ -#define UTF8_INPUT_ENABLE -#define UTF8_OUTPUT_ENABLE - -/* invert characters invalid in Shift_JIS to CP932 */ -#define SHIFTJIS_CP932 - -/* fix input encoding when given by option */ -#define INPUT_CODE_FIX - -/* --overwrite option */ -/* by Satoru Takabayashi <ccsatoru@vega.aichi-u.ac.jp> */ -#define OVERWRITE - -/* --cap-input, --url-input option */ -#define INPUT_OPTION - -/* --numchar-input option */ -#define NUMCHAR_OPTION - -/* --debug, --no-output option */ -#define CHECK_OPTION - -/* JIS X0212 */ -#define X0212_ENABLE - -/* --exec-in, --exec-out option - * require pipe, fork, execvp and so on. - * please undef this on MS-DOS, MinGW - * this is still buggy around child process - */ -/* #define EXEC_IO */ - -/* Unicode Normalization */ -#define UNICODE_NORMALIZATION - -/* - * Select Default Output Encoding - * - */ - -/* #define DEFAULT_CODE_JIS */ -/* #define DEFAULT_CODE_SJIS */ -/* #define DEFAULT_CODE_WINDOWS_31J */ -/* #define DEFAULT_CODE_EUC */ -/* #define DEFAULT_CODE_UTF8 */ - -#endif /* _CONFIG_H_ */ diff --git a/ext/nkf/nkf-utf8/nkf.c b/ext/nkf/nkf-utf8/nkf.c deleted file mode 100644 index 08b372ffab..0000000000 --- a/ext/nkf/nkf-utf8/nkf.c +++ /dev/null @@ -1,7205 +0,0 @@ -/* - * Copyright (c) 1987, Fujitsu LTD. (Itaru ICHIKAWA). - * Copyright (c) 1996-2018, The nkf Project. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * 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. - */ -#define NKF_VERSION "2.1.5" -#define NKF_RELEASE_DATE "2018-12-15" -#define COPY_RIGHT \ - "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).\n" \ - "Copyright (C) 1996-2018, The nkf Project." - -#include "config.h" -#include "nkf.h" -#include "utf8tbl.h" -#ifdef __WIN32__ -#include <windows.h> -#include <locale.h> -#endif -#if defined(__OS2__) -# define INCL_DOS -# define INCL_DOSERRORS -# include <os2.h> -#endif -#include <assert.h> - - -/* state of output_mode and input_mode - - c2 0 means ASCII - JIS_X_0201_1976_K - ISO_8859_1 - JIS_X_0208 - EOF all termination - c1 32bit data - - */ - -/* MIME ENCODE */ - -#define FIXED_MIME 7 -#define STRICT_MIME 8 - -/* byte order */ -enum byte_order { - ENDIAN_BIG = 1, - ENDIAN_LITTLE = 2, - ENDIAN_2143 = 3, - ENDIAN_3412 = 4 -}; - -/* ASCII CODE */ - -#define BS 0x08 -#define TAB 0x09 -#define LF 0x0a -#define CR 0x0d -#define ESC 0x1b -#define SP 0x20 -#define DEL 0x7f -#define SI 0x0f -#define SO 0x0e -#define SS2 0x8e -#define SS3 0x8f -#define CRLF 0x0D0A - - -/* encodings */ - -enum nkf_encodings { - ASCII, - ISO_8859_1, - ISO_2022_JP, - CP50220, - CP50221, - CP50222, - ISO_2022_JP_1, - ISO_2022_JP_3, - ISO_2022_JP_2004, - SHIFT_JIS, - WINDOWS_31J, - CP10001, - EUC_JP, - EUCJP_NKF, - CP51932, - EUCJP_MS, - EUCJP_ASCII, - SHIFT_JISX0213, - SHIFT_JIS_2004, - EUC_JISX0213, - EUC_JIS_2004, - UTF_8, - UTF_8N, - UTF_8_BOM, - UTF8_MAC, - UTF_16, - UTF_16BE, - UTF_16BE_BOM, - UTF_16LE, - UTF_16LE_BOM, - UTF_32, - UTF_32BE, - UTF_32BE_BOM, - UTF_32LE, - UTF_32LE_BOM, - BINARY, - NKF_ENCODING_TABLE_SIZE, - JIS_X_0201_1976_K = 0x1013, /* I */ /* JIS C 6220-1969 */ - /* JIS_X_0201_1976_R = 0x1014, */ /* J */ /* JIS C 6220-1969 */ - /* JIS_X_0208_1978 = 0x1040, */ /* @ */ /* JIS C 6226-1978 */ - /* JIS_X_0208_1983 = 0x1087, */ /* B */ /* JIS C 6226-1983 */ - JIS_X_0208 = 0x1168, /* @B */ - JIS_X_0212 = 0x1159, /* D */ - /* JIS_X_0213_2000_1 = 0x1228, */ /* O */ - JIS_X_0213_2 = 0x1229, /* P */ - JIS_X_0213_1 = 0x1233 /* Q */ -}; - -static nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0); -static nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0); -static nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0); -static nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0); -static nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0); -static void j_oconv(nkf_char c2, nkf_char c1); -static void s_oconv(nkf_char c2, nkf_char c1); -static void e_oconv(nkf_char c2, nkf_char c1); -static void w_oconv(nkf_char c2, nkf_char c1); -static void w_oconv16(nkf_char c2, nkf_char c1); -static void w_oconv32(nkf_char c2, nkf_char c1); - -typedef struct { - const char *name; - nkf_char (*iconv)(nkf_char c2, nkf_char c1, nkf_char c0); - void (*oconv)(nkf_char c2, nkf_char c1); -} nkf_native_encoding; - -nkf_native_encoding NkfEncodingASCII = { "ASCII", e_iconv, e_oconv }; -nkf_native_encoding NkfEncodingISO_2022_JP = { "ISO-2022-JP", e_iconv, j_oconv }; -nkf_native_encoding NkfEncodingShift_JIS = { "Shift_JIS", s_iconv, s_oconv }; -nkf_native_encoding NkfEncodingEUC_JP = { "EUC-JP", e_iconv, e_oconv }; -nkf_native_encoding NkfEncodingUTF_8 = { "UTF-8", w_iconv, w_oconv }; -nkf_native_encoding NkfEncodingUTF_16 = { "UTF-16", w_iconv16, w_oconv16 }; -nkf_native_encoding NkfEncodingUTF_32 = { "UTF-32", w_iconv32, w_oconv32 }; - -typedef struct { - const int id; - const char *name; - const nkf_native_encoding *base_encoding; -} nkf_encoding; - -nkf_encoding nkf_encoding_table[] = { - {ASCII, "US-ASCII", &NkfEncodingASCII}, - {ISO_8859_1, "ISO-8859-1", &NkfEncodingASCII}, - {ISO_2022_JP, "ISO-2022-JP", &NkfEncodingISO_2022_JP}, - {CP50220, "CP50220", &NkfEncodingISO_2022_JP}, - {CP50221, "CP50221", &NkfEncodingISO_2022_JP}, - {CP50222, "CP50222", &NkfEncodingISO_2022_JP}, - {ISO_2022_JP_1, "ISO-2022-JP-1", &NkfEncodingISO_2022_JP}, - {ISO_2022_JP_3, "ISO-2022-JP-3", &NkfEncodingISO_2022_JP}, - {ISO_2022_JP_2004, "ISO-2022-JP-2004", &NkfEncodingISO_2022_JP}, - {SHIFT_JIS, "Shift_JIS", &NkfEncodingShift_JIS}, - {WINDOWS_31J, "Windows-31J", &NkfEncodingShift_JIS}, - {CP10001, "CP10001", &NkfEncodingShift_JIS}, - {EUC_JP, "EUC-JP", &NkfEncodingEUC_JP}, - {EUCJP_NKF, "eucJP-nkf", &NkfEncodingEUC_JP}, - {CP51932, "CP51932", &NkfEncodingEUC_JP}, - {EUCJP_MS, "eucJP-MS", &NkfEncodingEUC_JP}, - {EUCJP_ASCII, "eucJP-ASCII", &NkfEncodingEUC_JP}, - {SHIFT_JISX0213, "Shift_JISX0213", &NkfEncodingShift_JIS}, - {SHIFT_JIS_2004, "Shift_JIS-2004", &NkfEncodingShift_JIS}, - {EUC_JISX0213, "EUC-JISX0213", &NkfEncodingEUC_JP}, - {EUC_JIS_2004, "EUC-JIS-2004", &NkfEncodingEUC_JP}, - {UTF_8, "UTF-8", &NkfEncodingUTF_8}, - {UTF_8N, "UTF-8N", &NkfEncodingUTF_8}, - {UTF_8_BOM, "UTF-8-BOM", &NkfEncodingUTF_8}, - {UTF8_MAC, "UTF8-MAC", &NkfEncodingUTF_8}, - {UTF_16, "UTF-16", &NkfEncodingUTF_16}, - {UTF_16BE, "UTF-16BE", &NkfEncodingUTF_16}, - {UTF_16BE_BOM, "UTF-16BE-BOM", &NkfEncodingUTF_16}, - {UTF_16LE, "UTF-16LE", &NkfEncodingUTF_16}, - {UTF_16LE_BOM, "UTF-16LE-BOM", &NkfEncodingUTF_16}, - {UTF_32, "UTF-32", &NkfEncodingUTF_32}, - {UTF_32BE, "UTF-32BE", &NkfEncodingUTF_32}, - {UTF_32BE_BOM, "UTF-32BE-BOM", &NkfEncodingUTF_32}, - {UTF_32LE, "UTF-32LE", &NkfEncodingUTF_32}, - {UTF_32LE_BOM, "UTF-32LE-BOM", &NkfEncodingUTF_32}, - {BINARY, "BINARY", &NkfEncodingASCII}, - {-1, NULL, NULL} -}; - -struct { - const char *name; - const int id; -} encoding_name_to_id_table[] = { - {"US-ASCII", ASCII}, - {"ASCII", ASCII}, - {"646", ASCII}, - {"ROMAN8", ASCII}, - {"ISO-2022-JP", ISO_2022_JP}, - {"ISO2022JP-CP932", CP50220}, - {"CP50220", CP50220}, - {"CP50221", CP50221}, - {"CSISO2022JP", CP50221}, - {"CP50222", CP50222}, - {"ISO-2022-JP-1", ISO_2022_JP_1}, - {"ISO-2022-JP-3", ISO_2022_JP_3}, - {"ISO-2022-JP-2004", ISO_2022_JP_2004}, - {"SHIFT_JIS", SHIFT_JIS}, - {"SJIS", SHIFT_JIS}, - {"MS_Kanji", SHIFT_JIS}, - {"PCK", SHIFT_JIS}, - {"WINDOWS-31J", WINDOWS_31J}, - {"CSWINDOWS31J", WINDOWS_31J}, - {"CP932", WINDOWS_31J}, - {"MS932", WINDOWS_31J}, - {"CP10001", CP10001}, - {"EUCJP", EUC_JP}, - {"EUC-JP", EUC_JP}, - {"EUCJP-NKF", EUCJP_NKF}, - {"CP51932", CP51932}, - {"EUC-JP-MS", EUCJP_MS}, - {"EUCJP-MS", EUCJP_MS}, - {"EUCJPMS", EUCJP_MS}, - {"EUC-JP-ASCII", EUCJP_ASCII}, - {"EUCJP-ASCII", EUCJP_ASCII}, - {"SHIFT_JISX0213", SHIFT_JISX0213}, - {"SHIFT_JIS-2004", SHIFT_JIS_2004}, - {"EUC-JISX0213", EUC_JISX0213}, - {"EUC-JIS-2004", EUC_JIS_2004}, - {"UTF-8", UTF_8}, - {"UTF-8N", UTF_8N}, - {"UTF-8-BOM", UTF_8_BOM}, - {"UTF8-MAC", UTF8_MAC}, - {"UTF-8-MAC", UTF8_MAC}, - {"UTF-16", UTF_16}, - {"UTF-16BE", UTF_16BE}, - {"UTF-16BE-BOM", UTF_16BE_BOM}, - {"UTF-16LE", UTF_16LE}, - {"UTF-16LE-BOM", UTF_16LE_BOM}, - {"UTF-32", UTF_32}, - {"UTF-32BE", UTF_32BE}, - {"UTF-32BE-BOM", UTF_32BE_BOM}, - {"UTF-32LE", UTF_32LE}, - {"UTF-32LE-BOM", UTF_32LE_BOM}, - {"BINARY", BINARY}, - {NULL, -1} -}; - -#if defined(DEFAULT_CODE_JIS) -#define DEFAULT_ENCIDX ISO_2022_JP -#elif defined(DEFAULT_CODE_SJIS) -#define DEFAULT_ENCIDX SHIFT_JIS -#elif defined(DEFAULT_CODE_WINDOWS_31J) -#define DEFAULT_ENCIDX WINDOWS_31J -#elif defined(DEFAULT_CODE_EUC) -#define DEFAULT_ENCIDX EUC_JP -#elif defined(DEFAULT_CODE_UTF8) -#define DEFAULT_ENCIDX UTF_8 -#endif - - -#define is_alnum(c) \ - (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9')) - -/* I don't trust portablity of toupper */ -#define nkf_toupper(c) (('a'<=c && c<='z')?(c-('a'-'A')):c) -#define nkf_isoctal(c) ('0'<=c && c<='7') -#define nkf_isdigit(c) ('0'<=c && c<='9') -#define nkf_isxdigit(c) (nkf_isdigit(c) || ('a'<=c && c<='f') || ('A'<=c && c <= 'F')) -#define nkf_isblank(c) (c == SP || c == TAB) -#define nkf_isspace(c) (nkf_isblank(c) || c == CR || c == LF) -#define nkf_isalpha(c) (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) -#define nkf_isalnum(c) (nkf_isdigit(c) || nkf_isalpha(c)) -#define nkf_isprint(c) (SP<=c && c<='~') -#define nkf_isgraph(c) ('!'<=c && c<='~') -#define hex2bin(c) (('0'<=c&&c<='9') ? (c-'0') : \ - ('A'<=c&&c<='F') ? (c-'A'+10) : \ - ('a'<=c&&c<='f') ? (c-'a'+10) : 0) -#define bin2hex(c) ("0123456789ABCDEF"[c&15]) -#define is_eucg3(c2) (((unsigned short)c2 >> 8) == SS3) -#define nkf_noescape_mime(c) ((c == CR) || (c == LF) || \ - ((c > SP) && (c < DEL) && (c != '?') && (c != '=') && (c != '_') \ - && (c != '(') && (c != ')') && (c != '.') && (c != 0x22))) - -#define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END) -#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c <= 0x5F) - -#define HOLD_SIZE 1024 -#if defined(INT_IS_SHORT) -#define IOBUF_SIZE 2048 -#else -#define IOBUF_SIZE 16384 -#endif - -#define DEFAULT_J 'B' -#define DEFAULT_R 'B' - - -#define GETA1 0x22 -#define GETA2 0x2e - - -/* MIME preprocessor */ - -#ifdef EASYWIN /*Easy Win */ -extern POINT _BufferSize; -#endif - -struct input_code{ - const char *name; - nkf_char stat; - nkf_char score; - nkf_char index; - nkf_char buf[3]; - void (*status_func)(struct input_code *, nkf_char); - nkf_char (*iconv_func)(nkf_char c2, nkf_char c1, nkf_char c0); - int _file_stat; -}; - -static const char *input_codename = NULL; /* NULL: unestablished, "": BINARY */ -static nkf_encoding *input_encoding = NULL; -static nkf_encoding *output_encoding = NULL; - -#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE) -/* UCS Mapping - * 0: Shift_JIS, eucJP-ascii - * 1: eucJP-ms - * 2: CP932, CP51932 - * 3: CP10001 - */ -#define UCS_MAP_ASCII 0 -#define UCS_MAP_MS 1 -#define UCS_MAP_CP932 2 -#define UCS_MAP_CP10001 3 -static int ms_ucs_map_f = UCS_MAP_ASCII; -#endif -#ifdef UTF8_INPUT_ENABLE -/* no NEC special, NEC-selected IBM extended and IBM extended characters */ -static int no_cp932ext_f = FALSE; -/* ignore ZERO WIDTH NO-BREAK SPACE */ -static int no_best_fit_chars_f = FALSE; -static int input_endian = ENDIAN_BIG; -static int input_bom_f = FALSE; -static nkf_char unicode_subchar = '?'; /* the regular substitution character */ -static void (*encode_fallback)(nkf_char c) = NULL; -static void w_status(struct input_code *, nkf_char); -#endif -#ifdef UTF8_OUTPUT_ENABLE -static int output_bom_f = FALSE; -static int output_endian = ENDIAN_BIG; -#endif - -static void std_putc(nkf_char c); -static nkf_char std_getc(FILE *f); -static nkf_char std_ungetc(nkf_char c,FILE *f); - -static nkf_char broken_getc(FILE *f); -static nkf_char broken_ungetc(nkf_char c,FILE *f); - -static nkf_char mime_getc(FILE *f); - -static void mime_putc(nkf_char c); - -/* buffers */ - -#if !defined(PERL_XS) && !defined(WIN32DLL) -static unsigned char stdibuf[IOBUF_SIZE]; -static unsigned char stdobuf[IOBUF_SIZE]; -#endif - -#define NKF_UNSPECIFIED (-TRUE) - -/* flags */ -static int unbuf_f = FALSE; -static int estab_f = FALSE; -static int nop_f = FALSE; -static int binmode_f = TRUE; /* binary mode */ -static int rot_f = FALSE; /* rot14/43 mode */ -static int hira_f = FALSE; /* hira/kata henkan */ -static int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */ -static int mime_f = MIME_DECODE_DEFAULT; /* convert MIME B base64 or Q */ -static int mime_decode_f = FALSE; /* mime decode is explicitly on */ -static int mimebuf_f = FALSE; /* MIME buffered input */ -static int broken_f = FALSE; /* convert ESC-less broken JIS */ -static int iso8859_f = FALSE; /* ISO8859 through */ -static int mimeout_f = FALSE; /* base64 mode */ -static int x0201_f = NKF_UNSPECIFIED; /* convert JIS X 0201 */ -static int iso2022jp_f = FALSE; /* replace non ISO-2022-JP with GETA */ - -#ifdef UNICODE_NORMALIZATION -static int nfc_f = FALSE; -static nkf_char (*i_nfc_getc)(FILE *) = std_getc; /* input of ugetc */ -static nkf_char (*i_nfc_ungetc)(nkf_char c ,FILE *f) = std_ungetc; -#endif - -#ifdef INPUT_OPTION -static int cap_f = FALSE; -static nkf_char (*i_cgetc)(FILE *) = std_getc; /* input of cgetc */ -static nkf_char (*i_cungetc)(nkf_char c ,FILE *f) = std_ungetc; - -static int url_f = FALSE; -static nkf_char (*i_ugetc)(FILE *) = std_getc; /* input of ugetc */ -static nkf_char (*i_uungetc)(nkf_char c ,FILE *f) = std_ungetc; -#endif - -#define PREFIX_EUCG3 NKF_INT32_C(0x8F00) -#define CLASS_MASK NKF_INT32_C(0xFF000000) -#define CLASS_UNICODE NKF_INT32_C(0x01000000) -#define VALUE_MASK NKF_INT32_C(0x00FFFFFF) -#define UNICODE_BMP_MAX NKF_INT32_C(0x0000FFFF) -#define UNICODE_MAX NKF_INT32_C(0x0010FFFF) -#define nkf_char_euc3_new(c) ((c) | PREFIX_EUCG3) -#define nkf_char_unicode_new(c) ((c) | CLASS_UNICODE) -#define nkf_char_unicode_p(c) ((c & CLASS_MASK) == CLASS_UNICODE) -#define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= UNICODE_BMP_MAX) -#define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= UNICODE_MAX) - -#define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00)) - -#ifdef NUMCHAR_OPTION -static int numchar_f = FALSE; -static nkf_char (*i_ngetc)(FILE *) = std_getc; /* input of ugetc */ -static nkf_char (*i_nungetc)(nkf_char c ,FILE *f) = std_ungetc; -#endif - -#ifdef CHECK_OPTION -static int noout_f = FALSE; -static void no_putc(nkf_char c); -static int debug_f = FALSE; -static void debug(const char *str); -static nkf_char (*iconv_for_check)(nkf_char c2,nkf_char c1,nkf_char c0) = 0; -#endif - -static int guess_f = 0; /* 0: OFF, 1: ON, 2: VERBOSE */ -static void set_input_codename(const char *codename); - -#ifdef EXEC_IO -static int exec_f = 0; -#endif - -#ifdef SHIFTJIS_CP932 -/* invert IBM extended characters to others */ -static int cp51932_f = FALSE; - -/* invert NEC-selected IBM extended characters to IBM extended characters */ -static int cp932inv_f = TRUE; - -/* static nkf_char cp932_conv(nkf_char c2, nkf_char c1); */ -#endif /* SHIFTJIS_CP932 */ - -static int x0212_f = FALSE; -static int x0213_f = FALSE; - -static unsigned char prefix_table[256]; - -static void e_status(struct input_code *, nkf_char); -static void s_status(struct input_code *, nkf_char); - -struct input_code input_code_list[] = { - {"EUC-JP", 0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0}, - {"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0}, -#ifdef UTF8_INPUT_ENABLE - {"UTF-8", 0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0}, - {"UTF-16", 0, 0, 0, {0, 0, 0}, NULL, w_iconv16, 0}, - {"UTF-32", 0, 0, 0, {0, 0, 0}, NULL, w_iconv32, 0}, -#endif - {NULL, 0, 0, 0, {0, 0, 0}, NULL, NULL, 0} -}; - -static int mimeout_mode = 0; /* 0, -1, 'Q', 'B', 1, 2 */ -static int base64_count = 0; - -/* X0208 -> ASCII converter */ - -/* fold parameter */ -static int f_line = 0; /* chars in line */ -static int f_prev = 0; -static int fold_preserve_f = FALSE; /* preserve new lines */ -static int fold_f = FALSE; -static int fold_len = 0; - -/* options */ -static unsigned char kanji_intro = DEFAULT_J; -static unsigned char ascii_intro = DEFAULT_R; - -/* Folding */ - -#define FOLD_MARGIN 10 -#define DEFAULT_FOLD 60 - -static int fold_margin = FOLD_MARGIN; - -/* process default */ - -static nkf_char -no_connection2(ARG_UNUSED nkf_char c2, ARG_UNUSED nkf_char c1, ARG_UNUSED nkf_char c0) -{ - fprintf(stderr,"nkf internal module connection failure.\n"); - exit(EXIT_FAILURE); - return 0; /* LINT */ -} - -static void -no_connection(nkf_char c2, nkf_char c1) -{ - no_connection2(c2,c1,0); -} - -static nkf_char (*iconv)(nkf_char c2,nkf_char c1,nkf_char c0) = no_connection2; -static void (*oconv)(nkf_char c2,nkf_char c1) = no_connection; - -static void (*o_zconv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_fconv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_eol_conv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_rot_conv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_hira_conv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_base64conv)(nkf_char c2,nkf_char c1) = no_connection; -static void (*o_iso2022jp_check_conv)(nkf_char c2,nkf_char c1) = no_connection; - -/* static redirections */ - -static void (*o_putc)(nkf_char c) = std_putc; - -static nkf_char (*i_getc)(FILE *f) = std_getc; /* general input */ -static nkf_char (*i_ungetc)(nkf_char c,FILE *f) =std_ungetc; - -static nkf_char (*i_bgetc)(FILE *) = std_getc; /* input of mgetc */ -static nkf_char (*i_bungetc)(nkf_char c ,FILE *f) = std_ungetc; - -static void (*o_mputc)(nkf_char c) = std_putc ; /* output of mputc */ - -static nkf_char (*i_mgetc)(FILE *) = std_getc; /* input of mgetc */ -static nkf_char (*i_mungetc)(nkf_char c ,FILE *f) = std_ungetc; - -/* for strict mime */ -static nkf_char (*i_mgetc_buf)(FILE *) = std_getc; /* input of mgetc_buf */ -static nkf_char (*i_mungetc_buf)(nkf_char c,FILE *f) = std_ungetc; - -/* Global states */ -static int output_mode = ASCII; /* output kanji mode */ -static int input_mode = ASCII; /* input kanji mode */ -static int mime_decode_mode = FALSE; /* MIME mode B base64, Q hex */ - -/* X0201 / X0208 conversion tables */ - -/* X0201 kana conversion table */ -/* 90-9F A0-DF */ -static const unsigned char cv[]= { - 0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57, - 0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21, - 0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29, - 0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43, - 0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26, - 0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d, - 0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35, - 0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d, - 0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46, - 0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c, - 0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52, - 0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e, - 0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62, - 0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69, - 0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d, - 0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c, - 0x00,0x00}; - - -/* X0201 kana conversion table for dakuten */ -/* 90-9F A0-DF */ -static const unsigned char dv[]= { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x74, - 0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e, - 0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36, - 0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e, - 0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47, - 0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53, - 0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00}; - -/* X0201 kana conversion table for han-dakuten */ -/* 90-9F A0-DF */ -static const unsigned char ev[]= { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54, - 0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00}; - -/* X0201 kana to X0213 conversion table for han-dakuten */ -/* 90-9F A0-DF */ -static const unsigned char ev_x0213[]= { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x25,0x77,0x25,0x78, - 0x25,0x79,0x25,0x7a,0x25,0x7b,0x00,0x00, - 0x00,0x00,0x00,0x00,0x25,0x7c,0x00,0x00, - 0x00,0x00,0x00,0x00,0x25,0x7d,0x00,0x00, - 0x25,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00}; - - -/* X0208 kigou conversion table */ -/* 0x8140 - 0x819e */ -static const unsigned char fv[] = { - - 0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a, - 0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00, - 0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f, - 0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27, - 0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d, - 0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00, - 0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -} ; - - - -static int option_mode = 0; -static int file_out_f = FALSE; -#ifdef OVERWRITE -static int overwrite_f = FALSE; -static int preserve_time_f = FALSE; -static int backup_f = FALSE; -static char *backup_suffix = ""; -#endif - -static int eolmode_f = 0; /* CR, LF, CRLF */ -static int input_eol = 0; /* 0: unestablished, EOF: MIXED */ -static nkf_char prev_cr = 0; /* CR or 0 */ -#ifdef EASYWIN /*Easy Win */ -static int end_check; -#endif /*Easy Win */ - -static void * -nkf_xmalloc(size_t size) -{ - void *ptr; - - if (size == 0) size = 1; - - ptr = malloc(size); - if (ptr == NULL) { - perror("can't malloc"); - exit(EXIT_FAILURE); - } - - return ptr; -} - -static void * -nkf_xrealloc(void *ptr, size_t size) -{ - if (size == 0) size = 1; - - ptr = realloc(ptr, size); - if (ptr == NULL) { - perror("can't realloc"); - exit(EXIT_FAILURE); - } - - return ptr; -} - -#define nkf_xfree(ptr) free(ptr) - -static int -nkf_str_caseeql(const char *src, const char *target) -{ - int i; - for (i = 0; src[i] && target[i]; i++) { - if (nkf_toupper(src[i]) != nkf_toupper(target[i])) return FALSE; - } - if (src[i] || target[i]) return FALSE; - else return TRUE; -} - -static nkf_encoding* -nkf_enc_from_index(int idx) -{ - if (idx < 0 || NKF_ENCODING_TABLE_SIZE <= idx) { - return 0; - } - return &nkf_encoding_table[idx]; -} - -static int -nkf_enc_find_index(const char *name) -{ - int i; - if (name[0] == 'X' && *(name+1) == '-') name += 2; - for (i = 0; encoding_name_to_id_table[i].id >= 0; i++) { - if (nkf_str_caseeql(encoding_name_to_id_table[i].name, name)) { - return encoding_name_to_id_table[i].id; - } - } - return -1; -} - -static nkf_encoding* -nkf_enc_find(const char *name) -{ - int idx = -1; - idx = nkf_enc_find_index(name); - if (idx < 0) return 0; - return nkf_enc_from_index(idx); -} - -#define nkf_enc_name(enc) (enc)->name -#define nkf_enc_to_index(enc) (enc)->id -#define nkf_enc_to_base_encoding(enc) (enc)->base_encoding -#define nkf_enc_to_iconv(enc) nkf_enc_to_base_encoding(enc)->iconv -#define nkf_enc_to_oconv(enc) nkf_enc_to_base_encoding(enc)->oconv -#define nkf_enc_asciicompat(enc) (\ - nkf_enc_to_base_encoding(enc) == &NkfEncodingASCII ||\ - nkf_enc_to_base_encoding(enc) == &NkfEncodingISO_2022_JP) -#define nkf_enc_unicode_p(enc) (\ - nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_8 ||\ - nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_16 ||\ - nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_32) -#define nkf_enc_cp5022x_p(enc) (\ - nkf_enc_to_index(enc) == CP50220 ||\ - nkf_enc_to_index(enc) == CP50221 ||\ - nkf_enc_to_index(enc) == CP50222) - -#ifdef DEFAULT_CODE_LOCALE -static const char* -nkf_locale_charmap(void) -{ -#ifdef HAVE_LANGINFO_H - return nl_langinfo(CODESET); -#elif defined(__WIN32__) - static char buf[16]; - sprintf(buf, "CP%d", GetACP()); - return buf; -#elif defined(__OS2__) -# if defined(INT_IS_SHORT) - /* OS/2 1.x */ - return NULL; -# else - /* OS/2 32bit */ - static char buf[16]; - ULONG ulCP[1], ulncp; - DosQueryCp(sizeof(ulCP), ulCP, &ulncp); - if (ulCP[0] == 932 || ulCP[0] == 943) - strcpy(buf, "Shift_JIS"); - else - sprintf(buf, "CP%lu", ulCP[0]); - return buf; -# endif -#endif - return NULL; -} - -static nkf_encoding* -nkf_locale_encoding(void) -{ - nkf_encoding *enc = 0; - const char *encname = nkf_locale_charmap(); - if (encname) - enc = nkf_enc_find(encname); - return enc; -} -#endif /* DEFAULT_CODE_LOCALE */ - -static nkf_encoding* -nkf_utf8_encoding(void) -{ - return &nkf_encoding_table[UTF_8]; -} - -static nkf_encoding* -nkf_default_encoding(void) -{ - nkf_encoding *enc = 0; -#ifdef DEFAULT_CODE_LOCALE - enc = nkf_locale_encoding(); -#elif defined(DEFAULT_ENCIDX) - enc = nkf_enc_from_index(DEFAULT_ENCIDX); -#endif - if (!enc) enc = nkf_utf8_encoding(); - return enc; -} - -typedef struct { - long capa; - long len; - nkf_char *ptr; -} nkf_buf_t; - -static nkf_buf_t * -nkf_buf_new(int length) -{ - nkf_buf_t *buf = nkf_xmalloc(sizeof(nkf_buf_t)); - buf->ptr = nkf_xmalloc(sizeof(nkf_char) * length); - buf->capa = length; - buf->len = 0; - return buf; -} - -#if 0 -static void -nkf_buf_dispose(nkf_buf_t *buf) -{ - nkf_xfree(buf->ptr); - nkf_xfree(buf); -} -#endif - -#define nkf_buf_length(buf) ((buf)->len) -#define nkf_buf_empty_p(buf) ((buf)->len == 0) - -static nkf_char -nkf_buf_at(nkf_buf_t *buf, int index) -{ - assert(index <= buf->len); - return buf->ptr[index]; -} - -static void -nkf_buf_clear(nkf_buf_t *buf) -{ - buf->len = 0; -} - -static void -nkf_buf_push(nkf_buf_t *buf, nkf_char c) -{ - if (buf->capa <= buf->len) { - exit(EXIT_FAILURE); - } - buf->ptr[buf->len++] = c; -} - -static nkf_char -nkf_buf_pop(nkf_buf_t *buf) -{ - assert(!nkf_buf_empty_p(buf)); - return buf->ptr[--buf->len]; -} - -/* Normalization Form C */ -#ifndef PERL_XS -#ifdef WIN32DLL -#define fprintf dllprintf -#endif - -static void -version(void) -{ - fprintf(HELP_OUTPUT,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n"); -} - -static void -usage(void) -{ - fprintf(HELP_OUTPUT, - "Usage: nkf -[flags] [--] [in file] .. [out file for -O flag]\n" -#ifdef UTF8_OUTPUT_ENABLE - " j/s/e/w Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n" - " UTF options is -w[8[0],{16,32}[{B,L}[0]]]\n" -#else -#endif -#ifdef UTF8_INPUT_ENABLE - " J/S/E/W Specify input encoding ISO-2022-JP, Shift_JIS, EUC-JP\n" - " UTF option is -W[8,[16,32][B,L]]\n" -#else - " J/S/E Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n" -#endif - ); - fprintf(HELP_OUTPUT, - " m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:nonstrict,0:no decode]\n" - " M[BQ] MIME encode [B:base64 Q:quoted]\n" - " f/F Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n" - ); - fprintf(HELP_OUTPUT, - " Z[0-4] Default/0: Convert JISX0208 Alphabet to ASCII\n" - " 1: Kankaku to one space 2: to two spaces 3: HTML Entity\n" - " 4: JISX0208 Katakana to JISX0201 Katakana\n" - " X,x Convert Halfwidth Katakana to Fullwidth or preserve it\n" - ); - fprintf(HELP_OUTPUT, - " O Output to File (DEFAULT 'nkf.out')\n" - " L[uwm] Line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n" - ); - fprintf(HELP_OUTPUT, - " --ic=<encoding> Specify the input encoding\n" - " --oc=<encoding> Specify the output encoding\n" - " --hiragana --katakana Hiragana/Katakana Conversion\n" - " --katakana-hiragana Converts each other\n" - ); - fprintf(HELP_OUTPUT, -#ifdef INPUT_OPTION - " --{cap, url}-input Convert hex after ':' or '%%'\n" -#endif -#ifdef NUMCHAR_OPTION - " --numchar-input Convert Unicode Character Reference\n" -#endif -#ifdef UTF8_INPUT_ENABLE - " --fb-{skip, html, xml, perl, java, subchar}\n" - " Specify unassigned character's replacement\n" -#endif - ); - fprintf(HELP_OUTPUT, -#ifdef OVERWRITE - " --in-place[=SUF] Overwrite original files\n" - " --overwrite[=SUF] Preserve timestamp of original files\n" -#endif - " -g --guess Guess the input code\n" - " -v --version Print the version\n" - " --help/-V Print this help / configuration\n" - ); - version(); -} - -static void -show_configuration(void) -{ - fprintf(HELP_OUTPUT, - "Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n" - " Compile-time options:\n" - " Compiled at: " __DATE__ " " __TIME__ "\n" - ); - fprintf(HELP_OUTPUT, - " Default output encoding: " -#ifdef DEFAULT_CODE_LOCALE - "LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding()) -#elif defined(DEFAULT_ENCIDX) - "CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding()) -#else - "NONE\n" -#endif - ); - fprintf(HELP_OUTPUT, - " Default output end of line: " -#if DEFAULT_NEWLINE == CR - "CR" -#elif DEFAULT_NEWLINE == CRLF - "CRLF" -#else - "LF" -#endif - "\n" - " Decode MIME encoded string: " -#if MIME_DECODE_DEFAULT - "ON" -#else - "OFF" -#endif - "\n" - " Convert JIS X 0201 Katakana: " -#if X0201_DEFAULT - "ON" -#else - "OFF" -#endif - "\n" - " --help, --version output: " -#if HELP_OUTPUT_HELP_OUTPUT - "HELP_OUTPUT" -#else - "STDOUT" -#endif - "\n"); -} -#endif /*PERL_XS*/ - -#ifdef OVERWRITE -static char* -get_backup_filename(const char *suffix, const char *filename) -{ - char *backup_filename; - int asterisk_count = 0; - int i, j; - int filename_length = strlen(filename); - - for(i = 0; suffix[i]; i++){ - if(suffix[i] == '*') asterisk_count++; - } - - if(asterisk_count){ - backup_filename = nkf_xmalloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1); - for(i = 0, j = 0; suffix[i];){ - if(suffix[i] == '*'){ - backup_filename[j] = '\0'; - strncat(backup_filename, filename, filename_length); - i++; - j += filename_length; - }else{ - backup_filename[j++] = suffix[i++]; - } - } - backup_filename[j] = '\0'; - }else{ - j = filename_length + strlen(suffix); - backup_filename = nkf_xmalloc(j + 1); - strcpy(backup_filename, filename); - strcat(backup_filename, suffix); - backup_filename[j] = '\0'; - } - return backup_filename; -} -#endif - -#ifdef UTF8_INPUT_ENABLE -static void -nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c) -{ - int shift = 20; - c &= VALUE_MASK; - while(shift >= 0){ - if(c >= NKF_INT32_C(1)<<shift){ - while(shift >= 0){ - (*f)(0, bin2hex(c>>shift)); - shift -= 4; - } - }else{ - shift -= 4; - } - } - return; -} - -static void -encode_fallback_html(nkf_char c) -{ - (*oconv)(0, '&'); - (*oconv)(0, '#'); - c &= VALUE_MASK; - if(c >= NKF_INT32_C(1000000)) - (*oconv)(0, 0x30+(c/NKF_INT32_C(1000000))%10); - if(c >= NKF_INT32_C(100000)) - (*oconv)(0, 0x30+(c/NKF_INT32_C(100000) )%10); - if(c >= 10000) - (*oconv)(0, 0x30+(c/10000 )%10); - if(c >= 1000) - (*oconv)(0, 0x30+(c/1000 )%10); - if(c >= 100) - (*oconv)(0, 0x30+(c/100 )%10); - if(c >= 10) - (*oconv)(0, 0x30+(c/10 )%10); - if(c >= 0) - (*oconv)(0, 0x30+ c %10); - (*oconv)(0, ';'); - return; -} - -static void -encode_fallback_xml(nkf_char c) -{ - (*oconv)(0, '&'); - (*oconv)(0, '#'); - (*oconv)(0, 'x'); - nkf_each_char_to_hex(oconv, c); - (*oconv)(0, ';'); - return; -} - -static void -encode_fallback_java(nkf_char c) -{ - (*oconv)(0, '\\'); - c &= VALUE_MASK; - if(!nkf_char_unicode_bmp_p(c)){ - int high = (c >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */ - int low = (c & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */ - (*oconv)(0, 'u'); - (*oconv)(0, bin2hex(high>>12)); - (*oconv)(0, bin2hex(high>> 8)); - (*oconv)(0, bin2hex(high>> 4)); - (*oconv)(0, bin2hex(high )); - (*oconv)(0, '\\'); - (*oconv)(0, 'u'); - (*oconv)(0, bin2hex(low>>12)); - (*oconv)(0, bin2hex(low>> 8)); - (*oconv)(0, bin2hex(low>> 4)); - (*oconv)(0, bin2hex(low )); - }else{ - (*oconv)(0, 'u'); - (*oconv)(0, bin2hex(c>>12)); - (*oconv)(0, bin2hex(c>> 8)); - (*oconv)(0, bin2hex(c>> 4)); - (*oconv)(0, bin2hex(c )); - } - return; -} - -static void -encode_fallback_perl(nkf_char c) -{ - (*oconv)(0, '\\'); - (*oconv)(0, 'x'); - (*oconv)(0, '{'); - nkf_each_char_to_hex(oconv, c); - (*oconv)(0, '}'); - return; -} - -static void -encode_fallback_subchar(nkf_char c) -{ - c = unicode_subchar; - (*oconv)((c>>8)&0xFF, c&0xFF); - return; -} -#endif - -static const struct { - const char *name; - const char *alias; -} long_option[] = { - {"ic=", ""}, - {"oc=", ""}, - {"base64","jMB"}, - {"euc","e"}, - {"euc-input","E"}, - {"fj","jm"}, - {"help",""}, - {"jis","j"}, - {"jis-input","J"}, - {"mac","sLm"}, - {"mime","jM"}, - {"mime-input","m"}, - {"msdos","sLw"}, - {"sjis","s"}, - {"sjis-input","S"}, - {"unix","eLu"}, - {"version","v"}, - {"windows","sLw"}, - {"hiragana","h1"}, - {"katakana","h2"}, - {"katakana-hiragana","h3"}, - {"guess=", ""}, - {"guess", "g2"}, - {"cp932", ""}, - {"no-cp932", ""}, -#ifdef X0212_ENABLE - {"x0212", ""}, -#endif -#ifdef UTF8_OUTPUT_ENABLE - {"utf8", "w"}, - {"utf16", "w16"}, - {"ms-ucs-map", ""}, - {"fb-skip", ""}, - {"fb-html", ""}, - {"fb-xml", ""}, - {"fb-perl", ""}, - {"fb-java", ""}, - {"fb-subchar", ""}, - {"fb-subchar=", ""}, -#endif -#ifdef UTF8_INPUT_ENABLE - {"utf8-input", "W"}, - {"utf16-input", "W16"}, - {"no-cp932ext", ""}, - {"no-best-fit-chars",""}, -#endif -#ifdef UNICODE_NORMALIZATION - {"utf8mac-input", ""}, -#endif -#ifdef OVERWRITE - {"overwrite", ""}, - {"overwrite=", ""}, - {"in-place", ""}, - {"in-place=", ""}, -#endif -#ifdef INPUT_OPTION - {"cap-input", ""}, - {"url-input", ""}, -#endif -#ifdef NUMCHAR_OPTION - {"numchar-input", ""}, -#endif -#ifdef CHECK_OPTION - {"no-output", ""}, - {"debug", ""}, -#endif -#ifdef SHIFTJIS_CP932 - {"cp932inv", ""}, -#endif -#ifdef EXEC_IO - {"exec-in", ""}, - {"exec-out", ""}, -#endif - {"prefix=", ""}, -}; - -static void -set_input_encoding(nkf_encoding *enc) -{ - switch (nkf_enc_to_index(enc)) { - case ISO_8859_1: - iso8859_f = TRUE; - break; - case CP50221: - case CP50222: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ - case CP50220: -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case ISO_2022_JP_1: - x0212_f = TRUE; - break; - case ISO_2022_JP_3: - x0212_f = TRUE; - x0213_f = TRUE; - break; - case ISO_2022_JP_2004: - x0212_f = TRUE; - x0213_f = TRUE; - break; - case SHIFT_JIS: - break; - case WINDOWS_31J: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - break; - case CP10001: -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP10001; -#endif - break; - case EUC_JP: - break; - case EUCJP_NKF: - break; - case CP51932: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case EUCJP_MS: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - cp51932_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_MS; -#endif - break; - case EUCJP_ASCII: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - cp51932_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_ASCII; -#endif - break; - case SHIFT_JISX0213: - case SHIFT_JIS_2004: - x0213_f = TRUE; -#ifdef SHIFTJIS_CP932 - cp51932_f = FALSE; - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; - case EUC_JISX0213: - case EUC_JIS_2004: - x0213_f = TRUE; -#ifdef SHIFTJIS_CP932 - cp51932_f = FALSE; -#endif - break; -#ifdef UTF8_INPUT_ENABLE -#ifdef UNICODE_NORMALIZATION - case UTF8_MAC: - nfc_f = TRUE; - break; -#endif - case UTF_16: - case UTF_16BE: - case UTF_16BE_BOM: - input_endian = ENDIAN_BIG; - break; - case UTF_16LE: - case UTF_16LE_BOM: - input_endian = ENDIAN_LITTLE; - break; - case UTF_32: - case UTF_32BE: - case UTF_32BE_BOM: - input_endian = ENDIAN_BIG; - break; - case UTF_32LE: - case UTF_32LE_BOM: - input_endian = ENDIAN_LITTLE; - break; -#endif - } -} - -static void -set_output_encoding(nkf_encoding *enc) -{ - switch (nkf_enc_to_index(enc)) { - case CP50220: -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case CP50221: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case ISO_2022_JP: -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; - case ISO_2022_JP_1: - x0212_f = TRUE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; - case ISO_2022_JP_3: - case ISO_2022_JP_2004: - x0212_f = TRUE; - x0213_f = TRUE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; - case SHIFT_JIS: - break; - case WINDOWS_31J: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case CP10001: -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP10001; -#endif - break; - case EUC_JP: - x0212_f = TRUE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_ASCII; -#endif - break; - case EUCJP_NKF: - x0212_f = FALSE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_ASCII; -#endif - break; - case CP51932: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - break; - case EUCJP_MS: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ - x0212_f = TRUE; -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_MS; -#endif - break; - case EUCJP_ASCII: - if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */ - x0212_f = TRUE; -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_ASCII; -#endif - break; - case SHIFT_JISX0213: - case SHIFT_JIS_2004: - x0213_f = TRUE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; - case EUC_JISX0213: - case EUC_JIS_2004: - x0212_f = TRUE; - x0213_f = TRUE; -#ifdef SHIFTJIS_CP932 - if (cp932inv_f == TRUE) cp932inv_f = FALSE; -#endif - break; -#ifdef UTF8_OUTPUT_ENABLE - case UTF_8_BOM: - output_bom_f = TRUE; - break; - case UTF_16: - case UTF_16BE_BOM: - output_bom_f = TRUE; - break; - case UTF_16LE: - output_endian = ENDIAN_LITTLE; - output_bom_f = FALSE; - break; - case UTF_16LE_BOM: - output_endian = ENDIAN_LITTLE; - output_bom_f = TRUE; - break; - case UTF_32: - case UTF_32BE_BOM: - output_bom_f = TRUE; - break; - case UTF_32LE: - output_endian = ENDIAN_LITTLE; - output_bom_f = FALSE; - break; - case UTF_32LE_BOM: - output_endian = ENDIAN_LITTLE; - output_bom_f = TRUE; - break; -#endif - } -} - -static struct input_code* -find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0)) -{ - if (iconv_func){ - struct input_code *p = input_code_list; - while (p->name){ - if (iconv_func == p->iconv_func){ - return p; - } - p++; - } - } - return 0; -} - -static void -set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0)) -{ -#ifdef INPUT_CODE_FIX - if (f || !input_encoding) -#endif - if (estab_f != f){ - estab_f = f; - } - - if (iconv_func -#ifdef INPUT_CODE_FIX - && (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */ -#endif - ){ - iconv = iconv_func; - } -#ifdef CHECK_OPTION - if (estab_f && iconv_for_check != iconv){ - struct input_code *p = find_inputcode_byfunc(iconv); - if (p){ - set_input_codename(p->name); - debug(p->name); - } - iconv_for_check = iconv; - } -#endif -} - -#ifdef X0212_ENABLE -static nkf_char -x0212_shift(nkf_char c) -{ - nkf_char ret = c; - c &= 0x7f; - if (is_eucg3(ret)){ - if (0x75 <= c && c <= 0x7f){ - ret = c + (0x109 - 0x75); - } - }else{ - if (0x75 <= c && c <= 0x7f){ - ret = c + (0x113 - 0x75); - } - } - return ret; -} - - -static nkf_char -x0212_unshift(nkf_char c) -{ - nkf_char ret = c; - if (0x7f <= c && c <= 0x88){ - ret = c + (0x75 - 0x7f); - }else if (0x89 <= c && c <= 0x92){ - ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89)); - } - return ret; -} -#endif /* X0212_ENABLE */ - -static int -is_x0213_2_in_x0212(nkf_char c1) -{ - static const char x0213_2_table[] = - {0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1}; - int ku = c1 - 0x20; - if (ku <= 15) - return x0213_2_table[ku]; /* 1, 3-5, 8, 12-15 */ - if (78 <= ku && ku <= 94) - return 1; - return 0; -} - -static nkf_char -e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1) -{ - nkf_char ndx; - if (is_eucg3(c2)){ - ndx = c2 & 0x7f; - if (x0213_f && is_x0213_2_in_x0212(ndx)){ - if((0x21 <= ndx && ndx <= 0x2F)){ - if (p2) *p2 = ((ndx - 1) >> 1) + 0xec - ndx / 8 * 3; - if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e); - return 0; - }else if(0x6E <= ndx && ndx <= 0x7E){ - if (p2) *p2 = ((ndx - 1) >> 1) + 0xbe; - if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e); - return 0; - } - return 1; - } -#ifdef X0212_ENABLE - else if(nkf_isgraph(ndx)){ - nkf_char val = 0; - const unsigned short *ptr; - ptr = x0212_shiftjis[ndx - 0x21]; - if (ptr){ - val = ptr[(c1 & 0x7f) - 0x21]; - } - if (val){ - c2 = val >> 8; - c1 = val & 0xff; - if (p2) *p2 = c2; - if (p1) *p1 = c1; - return 0; - } - c2 = x0212_shift(c2); - } -#endif /* X0212_ENABLE */ - } - if(0x7F < c2) return 1; - if (p2) *p2 = ((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1); - if (p1) *p1 = c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e); - return 0; -} - -static nkf_char -s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1) -{ -#if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE) - nkf_char val; -#endif - static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} }; - if (0xFC < c1) return 1; -#ifdef SHIFTJIS_CP932 - if (!cp932inv_f && !x0213_f && is_ibmext_in_sjis(c2)){ - val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40]; - if (val){ - c2 = val >> 8; - c1 = val & 0xff; - } - } - if (cp932inv_f - && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){ - val = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40]; - if (val){ - c2 = val >> 8; - c1 = val & 0xff; - } - } -#endif /* SHIFTJIS_CP932 */ -#ifdef X0212_ENABLE - if (!x0213_f && is_ibmext_in_sjis(c2)){ - val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40]; - if (val){ - if (val > 0x7FFF){ - c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f); - c1 = val & 0xff; - }else{ - c2 = val >> 8; - c1 = val & 0xff; - } - if (p2) *p2 = c2; - if (p1) *p1 = c1; - return 0; - } - } -#endif - if(c2 >= 0x80){ - if(x0213_f && c2 >= 0xF0){ - if(c2 <= 0xF3 || (c2 == 0xF4 && c1 < 0x9F)){ /* k=1, 3<=k<=5, k=8, 12<=k<=15 */ - c2 = PREFIX_EUCG3 | 0x20 | shift_jisx0213_s1a3_table[c2 - 0xF0][0x9E < c1]; - }else{ /* 78<=k<=94 */ - c2 = PREFIX_EUCG3 | (c2 * 2 - 0x17B); - if (0x9E < c1) c2++; - } - }else{ -#define SJ0162 0x00e1 /* 01 - 62 ku offset */ -#define SJ6394 0x0161 /* 63 - 94 ku offset */ - c2 = c2 + c2 - ((c2 <= 0x9F) ? SJ0162 : SJ6394); - if (0x9E < c1) c2++; - } - if (c1 < 0x9F) - c1 = c1 - ((c1 > DEL) ? SP : 0x1F); - else { - c1 = c1 - 0x7E; - } - } - -#ifdef X0212_ENABLE - c2 = x0212_unshift(c2); -#endif - if (p2) *p2 = c2; - if (p1) *p1 = c1; - return 0; -} - -#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE) -static void -nkf_unicode_to_utf8(nkf_char val, nkf_char *p1, nkf_char *p2, nkf_char *p3, nkf_char *p4) -{ - val &= VALUE_MASK; - if (val < 0x80){ - *p1 = val; - *p2 = 0; - *p3 = 0; - *p4 = 0; - }else if (val < 0x800){ - *p1 = 0xc0 | (val >> 6); - *p2 = 0x80 | (val & 0x3f); - *p3 = 0; - *p4 = 0; - } else if (nkf_char_unicode_bmp_p(val)) { - *p1 = 0xe0 | (val >> 12); - *p2 = 0x80 | ((val >> 6) & 0x3f); - *p3 = 0x80 | ( val & 0x3f); - *p4 = 0; - } else if (nkf_char_unicode_value_p(val)) { - *p1 = 0xf0 | (val >> 18); - *p2 = 0x80 | ((val >> 12) & 0x3f); - *p3 = 0x80 | ((val >> 6) & 0x3f); - *p4 = 0x80 | ( val & 0x3f); - } else { - *p1 = 0; - *p2 = 0; - *p3 = 0; - *p4 = 0; - } -} - -static nkf_char -nkf_utf8_to_unicode(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc; - if (c1 <= 0x7F) { - /* single byte */ - wc = c1; - } - else if (c1 <= 0xC1) { - /* trail byte or invalid */ - return -1; - } - else if (c1 <= 0xDF) { - /* 2 bytes */ - wc = (c1 & 0x1F) << 6; - wc |= (c2 & 0x3F); - } - else if (c1 <= 0xEF) { - /* 3 bytes */ - wc = (c1 & 0x0F) << 12; - wc |= (c2 & 0x3F) << 6; - wc |= (c3 & 0x3F); - } - else if (c2 <= 0xF4) { - /* 4 bytes */ - wc = (c1 & 0x0F) << 18; - wc |= (c2 & 0x3F) << 12; - wc |= (c3 & 0x3F) << 6; - wc |= (c4 & 0x3F); - } - else { - return -1; - } - return wc; -} -#endif - -#ifdef UTF8_INPUT_ENABLE -static int -unicode_to_jis_common2(nkf_char c1, nkf_char c0, - const unsigned short *const *pp, nkf_char psize, - nkf_char *p2, nkf_char *p1) -{ - nkf_char c2; - const unsigned short *p; - unsigned short val; - - if (pp == 0) return 1; - - c1 -= 0x80; - if (c1 < 0 || psize <= c1) return 1; - p = pp[c1]; - if (p == 0) return 1; - - c0 -= 0x80; - if (c0 < 0 || sizeof_utf8_to_euc_C2 <= c0) return 1; - val = p[c0]; - if (val == 0) return 1; - if (no_cp932ext_f && ( - (val>>8) == 0x2D || /* NEC special characters */ - val > NKF_INT32_C(0xF300) /* IBM extended characters */ - )) return 1; - - c2 = val >> 8; - if (val > 0x7FFF){ - c2 &= 0x7f; - c2 |= PREFIX_EUCG3; - } - if (c2 == SO) c2 = JIS_X_0201_1976_K; - c1 = val & 0xFF; - if (p2) *p2 = c2; - if (p1) *p1 = c1; - return 0; -} - -static int -unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1) -{ - const unsigned short *const *pp; - const unsigned short *const *const *ppp; - static const char no_best_fit_chars_table_C2[] = - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 2, - 0, 0, 1, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1}; - static const char no_best_fit_chars_table_C2_ms[] = - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0}; - static const char no_best_fit_chars_table_932_C2[] = - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}; - static const char no_best_fit_chars_table_932_C3[] = - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}; - nkf_char ret = 0; - - if(c2 < 0x80){ - *p2 = 0; - *p1 = c2; - }else if(c2 < 0xe0){ - if(no_best_fit_chars_f){ - if(ms_ucs_map_f == UCS_MAP_CP932){ - switch(c2){ - case 0xC2: - if(no_best_fit_chars_table_932_C2[c1&0x3F]) return 1; - break; - case 0xC3: - if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1; - break; - } - }else if(!cp932inv_f){ - switch(c2){ - case 0xC2: - if(no_best_fit_chars_table_C2[c1&0x3F]) return 1; - break; - case 0xC3: - if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1; - break; - } - }else if(ms_ucs_map_f == UCS_MAP_MS){ - if(c2 == 0xC2 && no_best_fit_chars_table_C2_ms[c1&0x3F]) return 1; - }else if(ms_ucs_map_f == UCS_MAP_CP10001){ - switch(c2){ - case 0xC2: - switch(c1){ - case 0xA2: - case 0xA3: - case 0xA5: - case 0xA6: - case 0xAC: - case 0xAF: - case 0xB8: - return 1; - } - break; - } - } - } - pp = - ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_2bytes_932 : - ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms : - ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_2bytes_mac : - x0213_f ? utf8_to_euc_2bytes_x0213 : - utf8_to_euc_2bytes; - ret = unicode_to_jis_common2(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1); - }else if(c0 < 0xF0){ - if(no_best_fit_chars_f){ - if(ms_ucs_map_f == UCS_MAP_CP932){ - if(c2 == 0xE3 && c1 == 0x82 && c0 == 0x94) return 1; - }else if(ms_ucs_map_f == UCS_MAP_MS){ - switch(c2){ - case 0xE2: - switch(c1){ - case 0x80: - if(c0 == 0x94 || c0 == 0x96 || c0 == 0xBE) return 1; - break; - case 0x88: - if(c0 == 0x92) return 1; - break; - } - break; - case 0xE3: - if(c1 == 0x80 || c0 == 0x9C) return 1; - break; - } - }else if(ms_ucs_map_f == UCS_MAP_CP10001){ - switch(c2){ - case 0xE3: - switch(c1){ - case 0x82: - if(c0 == 0x94) return 1; - break; - case 0x83: - if(c0 == 0xBB) return 1; - break; - } - break; - } - }else{ - switch(c2){ - case 0xE2: - switch(c1){ - case 0x80: - if(c0 == 0x95) return 1; - break; - case 0x88: - if(c0 == 0xA5) return 1; - break; - } - break; - case 0xEF: - switch(c1){ - case 0xBC: - if(c0 == 0x8D) return 1; - break; - case 0xBD: - if(c0 == 0x9E && !cp932inv_f) return 1; - break; - case 0xBF: - if(0xA0 <= c0 && c0 <= 0xA5) return 1; - break; - } - break; - } - } - } - ppp = - ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_3bytes_932 : - ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms : - ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_3bytes_mac : - x0213_f ? utf8_to_euc_3bytes_x0213 : - utf8_to_euc_3bytes; - ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1); - }else return -1; -#ifdef SHIFTJIS_CP932 - if (!ret&& is_eucg3(*p2)) { - if (cp932inv_f) { - if (encode_fallback) ret = 1; - } - else { - nkf_char s2, s1; - if (e2s_conv(*p2, *p1, &s2, &s1) == 0) { - s2e_conv(s2, s1, p2, p1); - }else{ - ret = 1; - } - } - } -#endif - return ret; -} - -#ifdef UTF8_OUTPUT_ENABLE -#define X0213_SURROGATE_FIND(tbl, size, euc) do { \ - int i; \ - for (i = 0; i < size; i++) \ - if (tbl[i][0] == euc) { \ - low = tbl[i][2]; \ - break; \ - } \ - } while (0) - -static nkf_char -e2w_conv(nkf_char c2, nkf_char c1) -{ - const unsigned short *p; - - if (c2 == JIS_X_0201_1976_K) { - if (ms_ucs_map_f == UCS_MAP_CP10001) { - switch (c1) { - case 0x20: - return 0xA0; - case 0x7D: - return 0xA9; - } - } - p = euc_to_utf8_1byte; -#ifdef X0212_ENABLE - } else if (is_eucg3(c2)){ - if(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){ - return 0xA6; - } - c2 = (c2&0x7f) - 0x21; - if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes) - p = - x0213_f ? x0212_to_utf8_2bytes_x0213[c2] : - x0212_to_utf8_2bytes[c2]; - else - return 0; -#endif - } else { - c2 &= 0x7f; - c2 = (c2&0x7f) - 0x21; - if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes) - p = - x0213_f ? euc_to_utf8_2bytes_x0213[c2] : - ms_ucs_map_f == UCS_MAP_ASCII ? euc_to_utf8_2bytes[c2] : - ms_ucs_map_f == UCS_MAP_CP10001 ? euc_to_utf8_2bytes_mac[c2] : - euc_to_utf8_2bytes_ms[c2]; - else - return 0; - } - if (!p) return 0; - c1 = (c1 & 0x7f) - 0x21; - if (0<=c1 && c1<sizeof_euc_to_utf8_1byte) { - nkf_char val = p[c1]; - if (x0213_f && 0xD800<=val && val<=0xDBFF) { - nkf_char euc = (c2+0x21)<<8 | (c1+0x21); - nkf_char low = 0; - if (p==x0212_to_utf8_2bytes_x0213[c2]) { - X0213_SURROGATE_FIND(x0213_2_surrogate_table, sizeof_x0213_2_surrogate_table, euc); - } else { - X0213_SURROGATE_FIND(x0213_1_surrogate_table, sizeof_x0213_1_surrogate_table, euc); - } - if (!low) return 0; - return UTF16_TO_UTF32(val, low); - } else { - return val; - } - } - return 0; -} - -static nkf_char -e2w_combining(nkf_char comb, nkf_char c2, nkf_char c1) -{ - nkf_char euc; - int i; - for (i = 0; i < sizeof_x0213_combining_chars; i++) - if (x0213_combining_chars[i] == comb) - break; - if (i >= sizeof_x0213_combining_chars) - return 0; - euc = (c2&0x7f)<<8 | (c1&0x7f); - for (i = 0; i < sizeof_x0213_combining_table; i++) - if (x0213_combining_table[i][0] == euc) - return x0213_combining_table[i][1]; - return 0; -} -#endif - -static nkf_char -w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1) -{ - nkf_char ret = 0; - - if (!c1){ - *p2 = 0; - *p1 = c2; - }else if (0xc0 <= c2 && c2 <= 0xef) { - ret = unicode_to_jis_common(c2, c1, c0, p2, p1); -#ifdef NUMCHAR_OPTION - if (ret > 0){ - if (p2) *p2 = 0; - if (p1) *p1 = nkf_char_unicode_new(nkf_utf8_to_unicode(c2, c1, c0, 0)); - ret = 0; - } -#endif - } - return ret; -} - -#ifdef UTF8_INPUT_ENABLE -static nkf_char -w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1) -{ - nkf_char c1, c2, c3, c4; - nkf_char ret = 0; - val &= VALUE_MASK; - if (val < 0x80) { - *p2 = 0; - *p1 = val; - } - else if (nkf_char_unicode_bmp_p(val)){ - nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4); - ret = unicode_to_jis_common(c1, c2, c3, p2, p1); - if (ret > 0){ - *p2 = 0; - *p1 = nkf_char_unicode_new(val); - ret = 0; - } - } - else { - int i; - if (x0213_f) { - c1 = (val >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */ - c2 = (val & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */ - for (i = 0; i < sizeof_x0213_1_surrogate_table; i++) - if (x0213_1_surrogate_table[i][1] == c1 && x0213_1_surrogate_table[i][2] == c2) { - val = x0213_1_surrogate_table[i][0]; - *p2 = val >> 8; - *p1 = val & 0xFF; - return 0; - } - for (i = 0; i < sizeof_x0213_2_surrogate_table; i++) - if (x0213_2_surrogate_table[i][1] == c1 && x0213_2_surrogate_table[i][2] == c2) { - val = x0213_2_surrogate_table[i][0]; - *p2 = PREFIX_EUCG3 | (val >> 8); - *p1 = val & 0xFF; - return 0; - } - } - *p2 = 0; - *p1 = nkf_char_unicode_new(val); - } - return ret; -} -#endif - -static nkf_char -e_iconv(nkf_char c2, nkf_char c1, nkf_char c0) -{ - if (c2 == JIS_X_0201_1976_K || c2 == SS2){ - if (iso2022jp_f && !x0201_f) { - c2 = GETA1; c1 = GETA2; - } else { - c2 = JIS_X_0201_1976_K; - c1 &= 0x7f; - } -#ifdef X0212_ENABLE - }else if (c2 == 0x8f){ - if (c0 == 0){ - return -1; - } - if (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) { - /* encoding is eucJP-ms, so invert to Unicode Private User Area */ - c1 = nkf_char_unicode_new((c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC); - c2 = 0; - } else { - c2 = (c2 << 8) | (c1 & 0x7f); - c1 = c0 & 0x7f; -#ifdef SHIFTJIS_CP932 - if (cp51932_f){ - nkf_char s2, s1; - if (e2s_conv(c2, c1, &s2, &s1) == 0){ - s2e_conv(s2, s1, &c2, &c1); - if (c2 < 0x100){ - c1 &= 0x7f; - c2 &= 0x7f; - } - } - } -#endif /* SHIFTJIS_CP932 */ - } -#endif /* X0212_ENABLE */ - } else if ((c2 == EOF) || (c2 == 0) || c2 < SP || c2 == ISO_8859_1) { - /* NOP */ - } else { - if (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) { - /* encoding is eucJP-ms, so invert to Unicode Private User Area */ - c1 = nkf_char_unicode_new((c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000); - c2 = 0; - } else { - c1 &= 0x7f; - c2 &= 0x7f; -#ifdef SHIFTJIS_CP932 - if (cp51932_f && 0x79 <= c2 && c2 <= 0x7c){ - nkf_char s2, s1; - if (e2s_conv(c2, c1, &s2, &s1) == 0){ - s2e_conv(s2, s1, &c2, &c1); - if (c2 < 0x100){ - c1 &= 0x7f; - c2 &= 0x7f; - } - } - } -#endif /* SHIFTJIS_CP932 */ - } - } - (*oconv)(c2, c1); - return 0; -} - -static nkf_char -s_iconv(ARG_UNUSED nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0) -{ - if (c2 == JIS_X_0201_1976_K || (0xA1 <= c2 && c2 <= 0xDF)) { - if (iso2022jp_f && !x0201_f) { - c2 = GETA1; c1 = GETA2; - } else { - c1 &= 0x7f; - } - } else if ((c2 == EOF) || (c2 == 0) || c2 < SP) { - /* NOP */ - } else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) { - /* CP932 UDC */ - if(c1 == 0x7F) return 0; - c1 = nkf_char_unicode_new((c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000); - c2 = 0; - } else { - nkf_char ret = s2e_conv(c2, c1, &c2, &c1); - if (ret) return ret; - } - (*oconv)(c2, c1); - return 0; -} - -static int -x0213_wait_combining_p(nkf_char wc) -{ - int i; - for (i = 0; i < sizeof_x0213_combining_table; i++) { - if (x0213_combining_table[i][1] == wc) { - return TRUE; - } - } - return FALSE; -} - -static int -x0213_combining_p(nkf_char wc) -{ - int i; - for (i = 0; i < sizeof_x0213_combining_chars; i++) { - if (x0213_combining_chars[i] == wc) { - return TRUE; - } - } - return FALSE; -} - -static nkf_char -w_iconv(nkf_char c1, nkf_char c2, nkf_char c3) -{ - nkf_char ret = 0, c4 = 0; - static const char w_iconv_utf8_1st_byte[] = - { /* 0xC0 - 0xFF */ - 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33, - 40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70}; - - if (c3 > 0xFF) { - c4 = c3 & 0xFF; - c3 >>= 8; - } - - if (c1 < 0 || 0xff < c1) { - }else if (c1 == 0) { /* 0 : 1 byte*/ - c3 = 0; - } else if ((c1 & 0xC0) == 0x80) { /* 0x80-0xbf : trail byte */ - return 0; - } else{ - switch (w_iconv_utf8_1st_byte[c1 - 0xC0]) { - case 21: - if (c2 < 0x80 || 0xBF < c2) return 0; - break; - case 30: - if (c3 == 0) return -1; - if (c2 < 0xA0 || 0xBF < c2 || (c3 & 0xC0) != 0x80) - return 0; - break; - case 31: - case 33: - if (c3 == 0) return -1; - if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80) - return 0; - break; - case 32: - if (c3 == 0) return -1; - if (c2 < 0x80 || 0x9F < c2 || (c3 & 0xC0) != 0x80) - return 0; - break; - case 40: - if (c3 == 0) return -2; - if (c2 < 0x90 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return 0; - break; - case 41: - if (c3 == 0) return -2; - if (c2 < 0x80 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return 0; - break; - case 42: - if (c3 == 0) return -2; - if (c2 < 0x80 || 0x8F < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) - return 0; - break; - default: - return 0; - break; - } - } - if (c1 == 0 || c1 == EOF){ - } else if ((c1 & 0xf8) == 0xf0) { /* 4 bytes */ - c2 = nkf_char_unicode_new(nkf_utf8_to_unicode(c1, c2, c3, c4)); - c1 = 0; - } else { - if (x0213_f && x0213_wait_combining_p(nkf_utf8_to_unicode(c1, c2, c3, c4))) - return -3; - ret = w2e_conv(c1, c2, c3, &c1, &c2); - } - if (ret == 0){ - (*oconv)(c1, c2); - } - return ret; -} - -static nkf_char -w_iconv_nocombine(nkf_char c1, nkf_char c2, nkf_char c3) -{ - /* continue from the line below 'return -3;' in w_iconv() */ - nkf_char ret = w2e_conv(c1, c2, c3, &c1, &c2); - if (ret == 0){ - (*oconv)(c1, c2); - } - return ret; -} - -#define NKF_ICONV_INVALID_CODE_RANGE -13 -#define NKF_ICONV_WAIT_COMBINING_CHAR -14 -#define NKF_ICONV_NOT_COMBINED -15 -static size_t -unicode_iconv(nkf_char wc, int nocombine) -{ - nkf_char c1, c2; - int ret = 0; - - if (wc < 0x80) { - c2 = 0; - c1 = wc; - }else if ((wc>>11) == 27) { - /* unpaired surrogate */ - return NKF_ICONV_INVALID_CODE_RANGE; - }else if (wc < 0xFFFF) { - if (!nocombine && x0213_f && x0213_wait_combining_p(wc)) - return NKF_ICONV_WAIT_COMBINING_CHAR; - ret = w16e_conv(wc, &c2, &c1); - if (ret) return ret; - }else if (wc < 0x10FFFF) { - c2 = 0; - c1 = nkf_char_unicode_new(wc); - } else { - return NKF_ICONV_INVALID_CODE_RANGE; - } - (*oconv)(c2, c1); - return 0; -} - -static nkf_char -unicode_iconv_combine(nkf_char wc, nkf_char wc2) -{ - nkf_char c1, c2; - int i; - - if (wc2 < 0x80) { - return NKF_ICONV_NOT_COMBINED; - }else if ((wc2>>11) == 27) { - /* unpaired surrogate */ - return NKF_ICONV_INVALID_CODE_RANGE; - }else if (wc2 < 0xFFFF) { - if (!x0213_combining_p(wc2)) - return NKF_ICONV_NOT_COMBINED; - for (i = 0; i < sizeof_x0213_combining_table; i++) { - if (x0213_combining_table[i][1] == wc && - x0213_combining_table[i][2] == wc2) { - c2 = x0213_combining_table[i][0] >> 8; - c1 = x0213_combining_table[i][0] & 0x7f; - (*oconv)(c2, c1); - return 0; - } - } - }else if (wc2 < 0x10FFFF) { - return NKF_ICONV_NOT_COMBINED; - } else { - return NKF_ICONV_INVALID_CODE_RANGE; - } - return NKF_ICONV_NOT_COMBINED; -} - -static nkf_char -w_iconv_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4, nkf_char c5, nkf_char c6) -{ - nkf_char wc, wc2; - wc = nkf_utf8_to_unicode(c1, c2, c3, 0); - wc2 = nkf_utf8_to_unicode(c4, c5, c6, 0); - if (wc2 < 0) - return wc2; - return unicode_iconv_combine(wc, wc2); -} - -#define NKF_ICONV_NEED_ONE_MORE_BYTE (size_t)-1 -#define NKF_ICONV_NEED_TWO_MORE_BYTES (size_t)-2 -static size_t -nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc; - - if (c1 == EOF) { - (*oconv)(EOF, 0); - return 0; - } - - if (input_endian == ENDIAN_BIG) { - if (0xD8 <= c1 && c1 <= 0xDB) { - if (0xDC <= c3 && c3 <= 0xDF) { - wc = UTF16_TO_UTF32(c1 << 8 | c2, c3 << 8 | c4); - } else return NKF_ICONV_NEED_TWO_MORE_BYTES; - } else { - wc = c1 << 8 | c2; - } - } else { - if (0xD8 <= c2 && c2 <= 0xDB) { - if (0xDC <= c4 && c4 <= 0xDF) { - wc = UTF16_TO_UTF32(c2 << 8 | c1, c4 << 8 | c3); - } else return NKF_ICONV_NEED_TWO_MORE_BYTES; - } else { - wc = c2 << 8 | c1; - } - } - - return (*unicode_iconv)(wc, FALSE); -} - -static size_t -nkf_iconv_utf_16_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc, wc2; - - if (input_endian == ENDIAN_BIG) { - if (0xD8 <= c3 && c3 <= 0xDB) { - return NKF_ICONV_NOT_COMBINED; - } else { - wc = c1 << 8 | c2; - wc2 = c3 << 8 | c4; - } - } else { - if (0xD8 <= c2 && c2 <= 0xDB) { - return NKF_ICONV_NOT_COMBINED; - } else { - wc = c2 << 8 | c1; - wc2 = c4 << 8 | c3; - } - } - - return unicode_iconv_combine(wc, wc2); -} - -static size_t -nkf_iconv_utf_16_nocombine(nkf_char c1, nkf_char c2) -{ - nkf_char wc; - if (input_endian == ENDIAN_BIG) - wc = c1 << 8 | c2; - else - wc = c2 << 8 | c1; - return (*unicode_iconv)(wc, TRUE); -} - -static nkf_char -w_iconv16(nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0) -{ - (*oconv)(c2, c1); - return 16; /* different from w_iconv32 */ -} - -static nkf_char -w_iconv32(nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0) -{ - (*oconv)(c2, c1); - return 32; /* different from w_iconv16 */ -} - -static nkf_char -utf32_to_nkf_char(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc; - - switch(input_endian){ - case ENDIAN_BIG: - wc = c2 << 16 | c3 << 8 | c4; - break; - case ENDIAN_LITTLE: - wc = c3 << 16 | c2 << 8 | c1; - break; - case ENDIAN_2143: - wc = c1 << 16 | c4 << 8 | c3; - break; - case ENDIAN_3412: - wc = c4 << 16 | c1 << 8 | c2; - break; - default: - return NKF_ICONV_INVALID_CODE_RANGE; - } - return wc; -} - -static size_t -nkf_iconv_utf_32(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc; - - if (c1 == EOF) { - (*oconv)(EOF, 0); - return 0; - } - - wc = utf32_to_nkf_char(c1, c2, c3, c4); - if (wc < 0) - return wc; - - return (*unicode_iconv)(wc, FALSE); -} - -static nkf_char -nkf_iconv_utf_32_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4, nkf_char c5, nkf_char c6, nkf_char c7, nkf_char c8) -{ - nkf_char wc, wc2; - - wc = utf32_to_nkf_char(c1, c2, c3, c4); - if (wc < 0) - return wc; - wc2 = utf32_to_nkf_char(c5, c6, c7, c8); - if (wc2 < 0) - return wc2; - - return unicode_iconv_combine(wc, wc2); -} - -static size_t -nkf_iconv_utf_32_nocombine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4) -{ - nkf_char wc; - - wc = utf32_to_nkf_char(c1, c2, c3, c4); - return (*unicode_iconv)(wc, TRUE); -} -#endif - -#define output_ascii_escape_sequence(mode) do { \ - if (output_mode != ASCII && output_mode != ISO_8859_1) { \ - (*o_putc)(ESC); \ - (*o_putc)('('); \ - (*o_putc)(ascii_intro); \ - output_mode = mode; \ - } \ - } while (0) - -static void -output_escape_sequence(int mode) -{ - if (output_mode == mode) - return; - switch(mode) { - case ISO_8859_1: - (*o_putc)(ESC); - (*o_putc)('.'); - (*o_putc)('A'); - break; - case JIS_X_0201_1976_K: - (*o_putc)(ESC); - (*o_putc)('('); - (*o_putc)('I'); - break; - case JIS_X_0208: - (*o_putc)(ESC); - (*o_putc)('$'); - (*o_putc)(kanji_intro); - break; - case JIS_X_0212: - (*o_putc)(ESC); - (*o_putc)('$'); - (*o_putc)('('); - (*o_putc)('D'); - break; - case JIS_X_0213_1: - (*o_putc)(ESC); - (*o_putc)('$'); - (*o_putc)('('); - (*o_putc)('Q'); - break; - case JIS_X_0213_2: - (*o_putc)(ESC); - (*o_putc)('$'); - (*o_putc)('('); - (*o_putc)('P'); - break; - } - output_mode = mode; -} - -static void -j_oconv(nkf_char c2, nkf_char c1) -{ -#ifdef NUMCHAR_OPTION - if (c2 == 0 && nkf_char_unicode_p(c1)){ - w16e_conv(c1, &c2, &c1); - if (c2 == 0 && nkf_char_unicode_p(c1)){ - c2 = c1 & VALUE_MASK; - if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) { - /* CP5022x UDC */ - c1 &= 0xFFF; - c2 = 0x7F + c1 / 94; - c1 = 0x21 + c1 % 94; - } else { - if (encode_fallback) (*encode_fallback)(c1); - return; - } - } - } -#endif - if (c2 == 0) { - output_ascii_escape_sequence(ASCII); - (*o_putc)(c1); - } - else if (c2 == EOF) { - output_ascii_escape_sequence(ASCII); - (*o_putc)(EOF); - } - else if (c2 == ISO_8859_1) { - output_ascii_escape_sequence(ISO_8859_1); - (*o_putc)(c1|0x80); - } - else if (c2 == JIS_X_0201_1976_K) { - output_escape_sequence(JIS_X_0201_1976_K); - (*o_putc)(c1); -#ifdef X0212_ENABLE - } else if (is_eucg3(c2)){ - output_escape_sequence(x0213_f ? JIS_X_0213_2 : JIS_X_0212); - (*o_putc)(c2 & 0x7f); - (*o_putc)(c1); -#endif - } else { - if(ms_ucs_map_f - ? c2<0x20 || 0x92<c2 || c1<0x20 || 0x7e<c1 - : c2<0x20 || 0x7e<c2 || c1<0x20 || 0x7e<c1) return; - output_escape_sequence(x0213_f ? JIS_X_0213_1 : JIS_X_0208); - (*o_putc)(c2); - (*o_putc)(c1); - } -} - -static void -e_oconv(nkf_char c2, nkf_char c1) -{ - if (c2 == 0 && nkf_char_unicode_p(c1)){ - w16e_conv(c1, &c2, &c1); - if (c2 == 0 && nkf_char_unicode_p(c1)){ - c2 = c1 & VALUE_MASK; - if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) { - /* eucJP-ms UDC */ - c1 &= 0xFFF; - c2 = c1 / 94; - c2 += c2 < 10 ? 0x75 : 0x8FEB; - c1 = 0x21 + c1 % 94; - if (is_eucg3(c2)){ - (*o_putc)(0x8f); - (*o_putc)((c2 & 0x7f) | 0x080); - (*o_putc)(c1 | 0x080); - }else{ - (*o_putc)((c2 & 0x7f) | 0x080); - (*o_putc)(c1 | 0x080); - } - return; - } else { - if (encode_fallback) (*encode_fallback)(c1); - return; - } - } - } - - if (c2 == EOF) { - (*o_putc)(EOF); - } else if (c2 == 0) { - output_mode = ASCII; - (*o_putc)(c1); - } else if (c2 == JIS_X_0201_1976_K) { - output_mode = EUC_JP; - (*o_putc)(SS2); (*o_putc)(c1|0x80); - } else if (c2 == ISO_8859_1) { - output_mode = ISO_8859_1; - (*o_putc)(c1 | 0x080); -#ifdef X0212_ENABLE - } else if (is_eucg3(c2)){ - output_mode = EUC_JP; -#ifdef SHIFTJIS_CP932 - if (!cp932inv_f){ - nkf_char s2, s1; - if (e2s_conv(c2, c1, &s2, &s1) == 0){ - s2e_conv(s2, s1, &c2, &c1); - } - } -#endif - if (c2 == 0) { - output_mode = ASCII; - (*o_putc)(c1); - }else if (is_eucg3(c2)){ - if (x0212_f){ - (*o_putc)(0x8f); - (*o_putc)((c2 & 0x7f) | 0x080); - (*o_putc)(c1 | 0x080); - } - }else{ - (*o_putc)((c2 & 0x7f) | 0x080); - (*o_putc)(c1 | 0x080); - } -#endif - } else { - if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) { - set_iconv(FALSE, 0); - return; /* too late to rescue this char */ - } - output_mode = EUC_JP; - (*o_putc)(c2 | 0x080); - (*o_putc)(c1 | 0x080); - } -} - -static void -s_oconv(nkf_char c2, nkf_char c1) -{ -#ifdef NUMCHAR_OPTION - if (c2 == 0 && nkf_char_unicode_p(c1)){ - w16e_conv(c1, &c2, &c1); - if (c2 == 0 && nkf_char_unicode_p(c1)){ - c2 = c1 & VALUE_MASK; - if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) { - /* CP932 UDC */ - c1 &= 0xFFF; - c2 = c1 / 188 + (cp932inv_f ? 0xF0 : 0xEB); - c1 = c1 % 188; - c1 += 0x40 + (c1 > 0x3e); - (*o_putc)(c2); - (*o_putc)(c1); - return; - } else { - if(encode_fallback)(*encode_fallback)(c1); - return; - } - } - } -#endif - if (c2 == EOF) { - (*o_putc)(EOF); - return; - } else if (c2 == 0) { - output_mode = ASCII; - (*o_putc)(c1); - } else if (c2 == JIS_X_0201_1976_K) { - output_mode = SHIFT_JIS; - (*o_putc)(c1|0x80); - } else if (c2 == ISO_8859_1) { - output_mode = ISO_8859_1; - (*o_putc)(c1 | 0x080); -#ifdef X0212_ENABLE - } else if (is_eucg3(c2)){ - output_mode = SHIFT_JIS; - if (e2s_conv(c2, c1, &c2, &c1) == 0){ - (*o_putc)(c2); - (*o_putc)(c1); - } -#endif - } else { - if (!nkf_isprint(c1) || !nkf_isprint(c2)) { - set_iconv(FALSE, 0); - return; /* too late to rescue this char */ - } - output_mode = SHIFT_JIS; - e2s_conv(c2, c1, &c2, &c1); - -#ifdef SHIFTJIS_CP932 - if (cp932inv_f - && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){ - nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40]; - if (c){ - c2 = c >> 8; - c1 = c & 0xff; - } - } -#endif /* SHIFTJIS_CP932 */ - - (*o_putc)(c2); - if (prefix_table[(unsigned char)c1]){ - (*o_putc)(prefix_table[(unsigned char)c1]); - } - (*o_putc)(c1); - } -} - -#ifdef UTF8_OUTPUT_ENABLE -#define OUTPUT_UTF8(val) do { \ - nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4); \ - (*o_putc)(c1); \ - if (c2) (*o_putc)(c2); \ - if (c3) (*o_putc)(c3); \ - if (c4) (*o_putc)(c4); \ - } while (0) - -static void -w_oconv(nkf_char c2, nkf_char c1) -{ - nkf_char c3, c4; - nkf_char val, val2; - - if (output_bom_f) { - output_bom_f = FALSE; - (*o_putc)('\357'); - (*o_putc)('\273'); - (*o_putc)('\277'); - } - - if (c2 == EOF) { - (*o_putc)(EOF); - return; - } - - if (c2 == 0 && nkf_char_unicode_p(c1)){ - val = c1 & VALUE_MASK; - OUTPUT_UTF8(val); - return; - } - - if (c2 == 0) { - (*o_putc)(c1); - } else { - val = e2w_conv(c2, c1); - if (val){ - val2 = e2w_combining(val, c2, c1); - if (val2) - OUTPUT_UTF8(val2); - OUTPUT_UTF8(val); - } - } -} - -#define OUTPUT_UTF16_BYTES(c1, c2) do { \ - if (output_endian == ENDIAN_LITTLE){ \ - (*o_putc)(c1); \ - (*o_putc)(c2); \ - }else{ \ - (*o_putc)(c2); \ - (*o_putc)(c1); \ - } \ - } while (0) - -#define OUTPUT_UTF16(val) do { \ - if (nkf_char_unicode_bmp_p(val)) { \ - c2 = (val >> 8) & 0xff; \ - c1 = val & 0xff; \ - OUTPUT_UTF16_BYTES(c1, c2); \ - } else { \ - val &= VALUE_MASK; \ - if (val <= UNICODE_MAX) { \ - c2 = (val >> 10) + NKF_INT32_C(0xD7C0); /* high surrogate */ \ - c1 = (val & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */ \ - OUTPUT_UTF16_BYTES(c2 & 0xff, (c2 >> 8) & 0xff); \ - OUTPUT_UTF16_BYTES(c1 & 0xff, (c1 >> 8) & 0xff); \ - } \ - } \ - } while (0) - -static void -w_oconv16(nkf_char c2, nkf_char c1) -{ - if (output_bom_f) { - output_bom_f = FALSE; - OUTPUT_UTF16_BYTES(0xFF, 0xFE); - } - - if (c2 == EOF) { - (*o_putc)(EOF); - return; - } - - if (c2 == 0 && nkf_char_unicode_p(c1)) { - OUTPUT_UTF16(c1); - } else if (c2) { - nkf_char val, val2; - val = e2w_conv(c2, c1); - if (!val) return; - val2 = e2w_combining(val, c2, c1); - if (val2) - OUTPUT_UTF16(val2); - OUTPUT_UTF16(val); - } else { - OUTPUT_UTF16_BYTES(c1, c2); - } -} - -#define OUTPUT_UTF32(c) do { \ - if (output_endian == ENDIAN_LITTLE){ \ - (*o_putc)( (c) & 0xFF); \ - (*o_putc)(((c) >> 8) & 0xFF); \ - (*o_putc)(((c) >> 16) & 0xFF); \ - (*o_putc)(0); \ - }else{ \ - (*o_putc)(0); \ - (*o_putc)(((c) >> 16) & 0xFF); \ - (*o_putc)(((c) >> 8) & 0xFF); \ - (*o_putc)( (c) & 0xFF); \ - } \ - } while (0) - -static void -w_oconv32(nkf_char c2, nkf_char c1) -{ - if (output_bom_f) { - output_bom_f = FALSE; - if (output_endian == ENDIAN_LITTLE){ - (*o_putc)(0xFF); - (*o_putc)(0xFE); - (*o_putc)(0); - (*o_putc)(0); - }else{ - (*o_putc)(0); - (*o_putc)(0); - (*o_putc)(0xFE); - (*o_putc)(0xFF); - } - } - - if (c2 == EOF) { - (*o_putc)(EOF); - return; - } - - if (c2 == ISO_8859_1) { - c1 |= 0x80; - } else if (c2 == 0 && nkf_char_unicode_p(c1)) { - c1 &= VALUE_MASK; - } else if (c2) { - nkf_char val, val2; - val = e2w_conv(c2, c1); - if (!val) return; - val2 = e2w_combining(val, c2, c1); - if (val2) - OUTPUT_UTF32(val2); - c1 = val; - } - OUTPUT_UTF32(c1); -} -#endif - -#define SCORE_L2 (1) /* Kanji Level 2 */ -#define SCORE_KANA (SCORE_L2 << 1) /* Halfwidth Katakana */ -#define SCORE_DEPEND (SCORE_KANA << 1) /* MD Characters */ -#define SCORE_CP932 (SCORE_DEPEND << 1) /* IBM extended characters */ -#define SCORE_X0212 (SCORE_CP932 << 1) /* JIS X 0212 */ -#define SCORE_X0213 (SCORE_X0212 << 1) /* JIS X 0213 */ -#define SCORE_NO_EXIST (SCORE_X0213 << 1) /* Undefined Characters */ -#define SCORE_iMIME (SCORE_NO_EXIST << 1) /* MIME selected */ -#define SCORE_ERROR (SCORE_iMIME << 1) /* Error */ - -#define SCORE_INIT (SCORE_iMIME) - -static const nkf_char score_table_A0[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, - SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_X0213, -}; - -static const nkf_char score_table_F0[] = { - SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2, - SCORE_L2, SCORE_DEPEND, SCORE_X0213, SCORE_X0213, - SCORE_DEPEND, SCORE_DEPEND, SCORE_CP932, SCORE_CP932, - SCORE_CP932, SCORE_X0213, SCORE_X0213, SCORE_ERROR, -}; - -static const nkf_char score_table_8FA0[] = { - 0, SCORE_X0213, SCORE_X0212, SCORE_X0213, - SCORE_X0213, SCORE_X0213, SCORE_X0212, SCORE_X0212, - SCORE_X0213, SCORE_X0212, SCORE_X0212, SCORE_X0212, - SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213, -}; - -static const nkf_char score_table_8FE0[] = { - SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212, - SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212, - SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212, - SCORE_X0212, SCORE_X0212, SCORE_X0213, SCORE_X0213, -}; - -static const nkf_char score_table_8FF0[] = { - SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0212, - SCORE_X0212, SCORE_X0213, SCORE_X0213, SCORE_X0213, - SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213, - SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213, -}; - -static void -set_code_score(struct input_code *ptr, nkf_char score) -{ - if (ptr){ - ptr->score |= score; - } -} - -static void -clr_code_score(struct input_code *ptr, nkf_char score) -{ - if (ptr){ - ptr->score &= ~score; - } -} - -static void -code_score(struct input_code *ptr) -{ - nkf_char c2 = ptr->buf[0]; - nkf_char c1 = ptr->buf[1]; - if (c2 < 0){ - set_code_score(ptr, SCORE_ERROR); - }else if (c2 == SS2){ - set_code_score(ptr, SCORE_KANA); - }else if (c2 == 0x8f){ - if ((c1 & 0x70) == 0x20){ - set_code_score(ptr, score_table_8FA0[c1 & 0x0f]); - }else if ((c1 & 0x70) == 0x60){ - set_code_score(ptr, score_table_8FE0[c1 & 0x0f]); - }else if ((c1 & 0x70) == 0x70){ - set_code_score(ptr, score_table_8FF0[c1 & 0x0f]); - }else{ - set_code_score(ptr, SCORE_X0212); - } -#ifdef UTF8_OUTPUT_ENABLE - }else if (!e2w_conv(c2, c1)){ - set_code_score(ptr, SCORE_NO_EXIST); -#endif - }else if ((c2 & 0x70) == 0x20){ - set_code_score(ptr, score_table_A0[c2 & 0x0f]); - }else if ((c2 & 0x70) == 0x70){ - set_code_score(ptr, score_table_F0[c2 & 0x0f]); - }else if ((c2 & 0x70) >= 0x50){ - set_code_score(ptr, SCORE_L2); - } -} - -static void -status_disable(struct input_code *ptr) -{ - ptr->stat = -1; - ptr->buf[0] = -1; - code_score(ptr); - if (iconv == ptr->iconv_func) set_iconv(FALSE, 0); -} - -static void -status_push_ch(struct input_code *ptr, nkf_char c) -{ - ptr->buf[ptr->index++] = c; -} - -static void -status_clear(struct input_code *ptr) -{ - ptr->stat = 0; - ptr->index = 0; -} - -static void -status_reset(struct input_code *ptr) -{ - status_clear(ptr); - ptr->score = SCORE_INIT; -} - -static void -status_reinit(struct input_code *ptr) -{ - status_reset(ptr); - ptr->_file_stat = 0; -} - -static void -status_check(struct input_code *ptr, nkf_char c) -{ - if (c <= DEL && estab_f){ - status_reset(ptr); - } -} - -static void -s_status(struct input_code *ptr, nkf_char c) -{ - switch(ptr->stat){ - case -1: - status_check(ptr, c); - break; - case 0: - if (c <= DEL){ - break; - }else if (nkf_char_unicode_p(c)){ - break; - }else if (0xa1 <= c && c <= 0xdf){ - status_push_ch(ptr, SS2); - status_push_ch(ptr, c); - code_score(ptr); - status_clear(ptr); - }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){ - ptr->stat = 1; - status_push_ch(ptr, c); - }else if (0xed <= c && c <= 0xee){ - ptr->stat = 3; - status_push_ch(ptr, c); -#ifdef SHIFTJIS_CP932 - }else if (is_ibmext_in_sjis(c)){ - ptr->stat = 2; - status_push_ch(ptr, c); -#endif /* SHIFTJIS_CP932 */ -#ifdef X0212_ENABLE - }else if (0xf0 <= c && c <= 0xfc){ - ptr->stat = 1; - status_push_ch(ptr, c); -#endif /* X0212_ENABLE */ - }else{ - status_disable(ptr); - } - break; - case 1: - if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){ - status_push_ch(ptr, c); - s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]); - code_score(ptr); - status_clear(ptr); - }else{ - status_disable(ptr); - } - break; - case 2: -#ifdef SHIFTJIS_CP932 - if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) { - status_push_ch(ptr, c); - if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0) { - set_code_score(ptr, SCORE_CP932); - status_clear(ptr); - break; - } - } -#endif /* SHIFTJIS_CP932 */ - status_disable(ptr); - break; - case 3: - if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){ - status_push_ch(ptr, c); - s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]); - set_code_score(ptr, SCORE_CP932); - status_clear(ptr); - }else{ - status_disable(ptr); - } - break; - } -} - -static void -e_status(struct input_code *ptr, nkf_char c) -{ - switch (ptr->stat){ - case -1: - status_check(ptr, c); - break; - case 0: - if (c <= DEL){ - break; - }else if (nkf_char_unicode_p(c)){ - break; - }else if (SS2 == c || (0xa1 <= c && c <= 0xfe)){ - ptr->stat = 1; - status_push_ch(ptr, c); -#ifdef X0212_ENABLE - }else if (0x8f == c){ - ptr->stat = 2; - status_push_ch(ptr, c); -#endif /* X0212_ENABLE */ - }else{ - status_disable(ptr); - } - break; - case 1: - if (0xa1 <= c && c <= 0xfe){ - status_push_ch(ptr, c); - code_score(ptr); - status_clear(ptr); - }else{ - status_disable(ptr); - } - break; -#ifdef X0212_ENABLE - case 2: - if (0xa1 <= c && c <= 0xfe){ - ptr->stat = 1; - status_push_ch(ptr, c); - }else{ - status_disable(ptr); - } -#endif /* X0212_ENABLE */ - } -} - -#ifdef UTF8_INPUT_ENABLE -static void -w_status(struct input_code *ptr, nkf_char c) -{ - switch (ptr->stat){ - case -1: - status_check(ptr, c); - break; - case 0: - if (c <= DEL){ - break; - }else if (nkf_char_unicode_p(c)){ - break; - }else if (0xc0 <= c && c <= 0xdf){ - ptr->stat = 1; - status_push_ch(ptr, c); - }else if (0xe0 <= c && c <= 0xef){ - ptr->stat = 2; - status_push_ch(ptr, c); - }else if (0xf0 <= c && c <= 0xf4){ - ptr->stat = 3; - status_push_ch(ptr, c); - }else{ - status_disable(ptr); - } - break; - case 1: - case 2: - if (0x80 <= c && c <= 0xbf){ - status_push_ch(ptr, c); - if (ptr->index > ptr->stat){ - int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb - && ptr->buf[2] == 0xbf); - w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2], - &ptr->buf[0], &ptr->buf[1]); - if (!bom){ - code_score(ptr); - } - status_clear(ptr); - } - }else{ - status_disable(ptr); - } - break; - case 3: - if (0x80 <= c && c <= 0xbf){ - if (ptr->index < ptr->stat){ - status_push_ch(ptr, c); - } else { - status_clear(ptr); - } - }else{ - status_disable(ptr); - } - break; - } -} -#endif - -static void -code_status(nkf_char c) -{ - int action_flag = 1; - struct input_code *result = 0; - struct input_code *p = input_code_list; - while (p->name){ - if (!p->status_func) { - ++p; - continue; - } - if (!p->status_func) - continue; - (p->status_func)(p, c); - if (p->stat > 0){ - action_flag = 0; - }else if(p->stat == 0){ - if (result){ - action_flag = 0; - }else{ - result = p; - } - } - ++p; - } - - if (action_flag){ - if (result && !estab_f){ - set_iconv(TRUE, result->iconv_func); - }else if (c <= DEL){ - struct input_code *ptr = input_code_list; - while (ptr->name){ - status_reset(ptr); - ++ptr; - } - } - } -} - -typedef struct { - nkf_buf_t *std_gc_buf; - nkf_char broken_state; - nkf_buf_t *broken_buf; - nkf_char mimeout_state; - nkf_buf_t *nfc_buf; -} nkf_state_t; - -static nkf_state_t *nkf_state = NULL; - -#define STD_GC_BUFSIZE (256) - -static void -nkf_state_init(void) -{ - if (nkf_state) { - nkf_buf_clear(nkf_state->std_gc_buf); - nkf_buf_clear(nkf_state->broken_buf); - nkf_buf_clear(nkf_state->nfc_buf); - } - else { - nkf_state = nkf_xmalloc(sizeof(nkf_state_t)); - nkf_state->std_gc_buf = nkf_buf_new(STD_GC_BUFSIZE); - nkf_state->broken_buf = nkf_buf_new(3); - nkf_state->nfc_buf = nkf_buf_new(9); - } - nkf_state->broken_state = 0; - nkf_state->mimeout_state = 0; -} - -#ifndef WIN32DLL -static nkf_char -std_getc(FILE *f) -{ - if (!nkf_buf_empty_p(nkf_state->std_gc_buf)){ - return nkf_buf_pop(nkf_state->std_gc_buf); - } - return getc(f); -} -#endif /*WIN32DLL*/ - -static nkf_char -std_ungetc(nkf_char c, ARG_UNUSED FILE *f) -{ - nkf_buf_push(nkf_state->std_gc_buf, c); - return c; -} - -#ifndef WIN32DLL -static void -std_putc(nkf_char c) -{ - if(c!=EOF) - putchar(c); -} -#endif /*WIN32DLL*/ - -static nkf_char hold_buf[HOLD_SIZE*2]; -static int hold_count = 0; -static nkf_char -push_hold_buf(nkf_char c2) -{ - if (hold_count >= HOLD_SIZE*2) - return (EOF); - hold_buf[hold_count++] = c2; - return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count); -} - -static int -h_conv(FILE *f, nkf_char c1, nkf_char c2) -{ - int ret; - int hold_index; - int fromhold_count; - nkf_char c3, c4; - - /** it must NOT be in the kanji shifte sequence */ - /** it must NOT be written in JIS7 */ - /** and it must be after 2 byte 8bit code */ - - hold_count = 0; - push_hold_buf(c1); - push_hold_buf(c2); - - while ((c2 = (*i_getc)(f)) != EOF) { - if (c2 == ESC){ - (*i_ungetc)(c2,f); - break; - } - code_status(c2); - if (push_hold_buf(c2) == EOF || estab_f) { - break; - } - } - - if (!estab_f) { - struct input_code *p = input_code_list; - struct input_code *result = p; - if (c2 == EOF) { - code_status(c2); - } - while (p->name) { - if (p->status_func && p->score < result->score) { - result = p; - } - p++; - } - set_iconv(TRUE, result->iconv_func); - } - - - /** now, - ** 1) EOF is detected, or - ** 2) Code is established, or - ** 3) Buffer is FULL (but last word is pushed) - ** - ** in 1) and 3) cases, we continue to use - ** Kanji codes by oconv and leave estab_f unchanged. - **/ - - ret = c2; - hold_index = 0; - while (hold_index < hold_count){ - c1 = hold_buf[hold_index++]; - if (nkf_char_unicode_p(c1)) { - (*oconv)(0, c1); - continue; - } - else if (c1 <= DEL){ - (*iconv)(0, c1, 0); - continue; - }else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){ - (*iconv)(JIS_X_0201_1976_K, c1, 0); - continue; - } - fromhold_count = 1; - if (hold_index < hold_count){ - c2 = hold_buf[hold_index++]; - fromhold_count++; - }else{ - c2 = (*i_getc)(f); - if (c2 == EOF){ - c4 = EOF; - break; - } - code_status(c2); - } - c3 = 0; - switch ((*iconv)(c1, c2, 0)) { /* can be EUC/SJIS/UTF-8 */ - case -2: - /* 4 bytes UTF-8 */ - if (hold_index < hold_count){ - c3 = hold_buf[hold_index++]; - } else if ((c3 = (*i_getc)(f)) == EOF) { - ret = EOF; - break; - } - code_status(c3); - if (hold_index < hold_count){ - c4 = hold_buf[hold_index++]; - } else if ((c4 = (*i_getc)(f)) == EOF) { - c3 = ret = EOF; - break; - } - code_status(c4); - (*iconv)(c1, c2, (c3<<8)|c4); - break; - case -3: - /* 4 bytes UTF-8 (check combining character) */ - if (hold_index < hold_count){ - c3 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c3 = (*i_getc)(f)) == EOF) { - w_iconv_nocombine(c1, c2, 0); - break; - } - if (hold_index < hold_count){ - c4 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c4 = (*i_getc)(f)) == EOF) { - w_iconv_nocombine(c1, c2, 0); - if (fromhold_count <= 2) - (*i_ungetc)(c3,f); - else - hold_index--; - continue; - } - if (w_iconv_combine(c1, c2, 0, c3, c4, 0)) { - w_iconv_nocombine(c1, c2, 0); - if (fromhold_count <= 2) { - (*i_ungetc)(c4,f); - (*i_ungetc)(c3,f); - } else if (fromhold_count == 3) { - (*i_ungetc)(c4,f); - hold_index--; - } else { - hold_index -= 2; - } - } - break; - case -1: - /* 3 bytes EUC or UTF-8 */ - if (hold_index < hold_count){ - c3 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c3 = (*i_getc)(f)) == EOF) { - ret = EOF; - break; - } else { - code_status(c3); - } - if ((*iconv)(c1, c2, c3) == -3) { - /* 6 bytes UTF-8 (check combining character) */ - nkf_char c5, c6; - if (hold_index < hold_count){ - c4 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c4 = (*i_getc)(f)) == EOF) { - w_iconv_nocombine(c1, c2, c3); - continue; - } - if (hold_index < hold_count){ - c5 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c5 = (*i_getc)(f)) == EOF) { - w_iconv_nocombine(c1, c2, c3); - if (fromhold_count == 4) - hold_index--; - else - (*i_ungetc)(c4,f); - continue; - } - if (hold_index < hold_count){ - c6 = hold_buf[hold_index++]; - fromhold_count++; - } else if ((c6 = (*i_getc)(f)) == EOF) { - w_iconv_nocombine(c1, c2, c3); - if (fromhold_count == 5) { - hold_index -= 2; - } else if (fromhold_count == 4) { - hold_index--; - (*i_ungetc)(c5,f); - } else { - (*i_ungetc)(c5,f); - (*i_ungetc)(c4,f); - } - continue; - } - if (w_iconv_combine(c1, c2, c3, c4, c5, c6)) { - w_iconv_nocombine(c1, c2, c3); - if (fromhold_count == 6) { - hold_index -= 3; - } else if (fromhold_count == 5) { - hold_index -= 2; - (*i_ungetc)(c6,f); - } else if (fromhold_count == 4) { - hold_index--; - (*i_ungetc)(c6,f); - (*i_ungetc)(c5,f); - } else { - (*i_ungetc)(c6,f); - (*i_ungetc)(c5,f); - (*i_ungetc)(c4,f); - } - } - } - break; - } - if (c3 == EOF) break; - } - return ret; -} - -/* - * Check and Ignore BOM - */ -static void -check_bom(FILE *f) -{ - int c2; - input_bom_f = FALSE; - switch(c2 = (*i_getc)(f)){ - case 0x00: - if((c2 = (*i_getc)(f)) == 0x00){ - if((c2 = (*i_getc)(f)) == 0xFE){ - if((c2 = (*i_getc)(f)) == 0xFF){ - if(!input_encoding){ - set_iconv(TRUE, w_iconv32); - } - if (iconv == w_iconv32) { - input_bom_f = TRUE; - input_endian = ENDIAN_BIG; - return; - } - (*i_ungetc)(0xFF,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xFE,f); - }else if(c2 == 0xFF){ - if((c2 = (*i_getc)(f)) == 0xFE){ - if(!input_encoding){ - set_iconv(TRUE, w_iconv32); - } - if (iconv == w_iconv32) { - input_endian = ENDIAN_2143; - return; - } - (*i_ungetc)(0xFF,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xFF,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0x00,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0x00,f); - break; - case 0xEF: - if((c2 = (*i_getc)(f)) == 0xBB){ - if((c2 = (*i_getc)(f)) == 0xBF){ - if(!input_encoding){ - set_iconv(TRUE, w_iconv); - } - if (iconv == w_iconv) { - input_bom_f = TRUE; - return; - } - (*i_ungetc)(0xBF,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xBB,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xEF,f); - break; - case 0xFE: - if((c2 = (*i_getc)(f)) == 0xFF){ - if((c2 = (*i_getc)(f)) == 0x00){ - if((c2 = (*i_getc)(f)) == 0x00){ - if(!input_encoding){ - set_iconv(TRUE, w_iconv32); - } - if (iconv == w_iconv32) { - input_endian = ENDIAN_3412; - return; - } - (*i_ungetc)(0x00,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0x00,f); - }else (*i_ungetc)(c2,f); - if(!input_encoding){ - set_iconv(TRUE, w_iconv16); - } - if (iconv == w_iconv16) { - input_endian = ENDIAN_BIG; - input_bom_f = TRUE; - return; - } - (*i_ungetc)(0xFF,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xFE,f); - break; - case 0xFF: - if((c2 = (*i_getc)(f)) == 0xFE){ - if((c2 = (*i_getc)(f)) == 0x00){ - if((c2 = (*i_getc)(f)) == 0x00){ - if(!input_encoding){ - set_iconv(TRUE, w_iconv32); - } - if (iconv == w_iconv32) { - input_endian = ENDIAN_LITTLE; - input_bom_f = TRUE; - return; - } - (*i_ungetc)(0x00,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0x00,f); - }else (*i_ungetc)(c2,f); - if(!input_encoding){ - set_iconv(TRUE, w_iconv16); - } - if (iconv == w_iconv16) { - input_endian = ENDIAN_LITTLE; - input_bom_f = TRUE; - return; - } - (*i_ungetc)(0xFE,f); - }else (*i_ungetc)(c2,f); - (*i_ungetc)(0xFF,f); - break; - default: - (*i_ungetc)(c2,f); - break; - } -} - -static nkf_char -broken_getc(FILE *f) -{ - nkf_char c, c1; - - if (!nkf_buf_empty_p(nkf_state->broken_buf)) { - return nkf_buf_pop(nkf_state->broken_buf); - } - c = (*i_bgetc)(f); - if (c=='$' && nkf_state->broken_state != ESC - && (input_mode == ASCII || input_mode == JIS_X_0201_1976_K)) { - c1= (*i_bgetc)(f); - nkf_state->broken_state = 0; - if (c1=='@'|| c1=='B') { - nkf_buf_push(nkf_state->broken_buf, c1); - nkf_buf_push(nkf_state->broken_buf, c); - return ESC; - } else { - (*i_bungetc)(c1,f); - return c; - } - } else if (c=='(' && nkf_state->broken_state != ESC - && (input_mode == JIS_X_0208 || input_mode == JIS_X_0201_1976_K)) { - c1= (*i_bgetc)(f); - nkf_state->broken_state = 0; - if (c1=='J'|| c1=='B') { - nkf_buf_push(nkf_state->broken_buf, c1); - nkf_buf_push(nkf_state->broken_buf, c); - return ESC; - } else { - (*i_bungetc)(c1,f); - return c; - } - } else { - nkf_state->broken_state = c; - return c; - } -} - -static nkf_char -broken_ungetc(nkf_char c, ARG_UNUSED FILE *f) -{ - if (nkf_buf_length(nkf_state->broken_buf) < 2) - nkf_buf_push(nkf_state->broken_buf, c); - return c; -} - -static void -eol_conv(nkf_char c2, nkf_char c1) -{ - if (guess_f && input_eol != EOF) { - if (c2 == 0 && c1 == LF) { - if (!input_eol) input_eol = prev_cr ? CRLF : LF; - else if (input_eol != (prev_cr ? CRLF : LF)) input_eol = EOF; - } else if (c2 == 0 && c1 == CR && input_eol == LF) input_eol = EOF; - else if (!prev_cr); - else if (!input_eol) input_eol = CR; - else if (input_eol != CR) input_eol = EOF; - } - if (prev_cr || (c2 == 0 && c1 == LF)) { - prev_cr = 0; - if (eolmode_f != LF) (*o_eol_conv)(0, CR); - if (eolmode_f != CR) (*o_eol_conv)(0, LF); - } - if (c2 == 0 && c1 == CR) prev_cr = CR; - else if (c2 != 0 || c1 != LF) (*o_eol_conv)(c2, c1); -} - -static void -put_newline(void (*func)(nkf_char)) -{ - switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) { - case CRLF: - (*func)(0x0D); - (*func)(0x0A); - break; - case CR: - (*func)(0x0D); - break; - case LF: - (*func)(0x0A); - break; - } -} - -static void -oconv_newline(void (*func)(nkf_char, nkf_char)) -{ - switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) { - case CRLF: - (*func)(0, 0x0D); - (*func)(0, 0x0A); - break; - case CR: - (*func)(0, 0x0D); - break; - case LF: - (*func)(0, 0x0A); - break; - } -} - -/* - Return value of fold_conv() - - LF add newline and output char - CR add newline and output nothing - SP space - 0 skip - 1 (or else) normal output - - fold state in prev (previous character) - - >0x80 Japanese (X0208/X0201) - <0x80 ASCII - LF new line - SP space - - This fold algorithm does not preserve heading space in a line. - This is the main difference from fmt. - */ - -#define char_size(c2,c1) (c2?2:1) - -static void -fold_conv(nkf_char c2, nkf_char c1) -{ - nkf_char prev0; - nkf_char fold_state; - - if (c1== CR && !fold_preserve_f) { - fold_state=0; /* ignore cr */ - }else if (c1== LF&&f_prev==CR && fold_preserve_f) { - f_prev = LF; - fold_state=0; /* ignore cr */ - } else if (c1== BS) { - if (f_line>0) f_line--; - fold_state = 1; - } else if (c2==EOF && f_line != 0) { /* close open last line */ - fold_state = LF; - } else if ((c1==LF && !fold_preserve_f) - || ((c1==CR||(c1==LF&&f_prev!=CR)) - && fold_preserve_f)) { - /* new line */ - if (fold_preserve_f) { - f_prev = c1; - f_line = 0; - fold_state = CR; - } else if ((f_prev == c1) - || (f_prev == LF) - ) { /* duplicate newline */ - if (f_line) { - f_line = 0; - fold_state = LF; /* output two newline */ - } else { - f_line = 0; - fold_state = 1; - } - } else { - if (f_prev&0x80) { /* Japanese? */ - f_prev = c1; - fold_state = 0; /* ignore given single newline */ - } else if (f_prev==SP) { - fold_state = 0; - } else { - f_prev = c1; - if (++f_line<=fold_len) - fold_state = SP; - else { - f_line = 0; - fold_state = CR; /* fold and output nothing */ - } - } - } - } else if (c1=='\f') { - f_prev = LF; - f_line = 0; - fold_state = LF; /* output newline and clear */ - } else if ((c2==0 && nkf_isblank(c1)) || (c2 == '!' && c1 == '!')) { - /* X0208 kankaku or ascii space */ - if (f_prev == SP) { - fold_state = 0; /* remove duplicate spaces */ - } else { - f_prev = SP; - if (++f_line<=fold_len) - fold_state = SP; /* output ASCII space only */ - else { - f_prev = SP; f_line = 0; - fold_state = CR; /* fold and output nothing */ - } - } - } else { - prev0 = f_prev; /* we still need this one... , but almost done */ - f_prev = c1; - if (c2 || c2 == JIS_X_0201_1976_K) - f_prev |= 0x80; /* this is Japanese */ - f_line += c2 == JIS_X_0201_1976_K ? 1: char_size(c2,c1); - if (f_line<=fold_len) { /* normal case */ - fold_state = 1; - } else { - if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */ - f_line = char_size(c2,c1); - fold_state = LF; /* We can't wait, do fold now */ - } else if (c2 == JIS_X_0201_1976_K) { - /* simple kinsoku rules return 1 means no folding */ - if (c1==(0xde&0x7f)) fold_state = 1; /* $B!+(B*/ - else if (c1==(0xdf&0x7f)) fold_state = 1; /* $B!,(B*/ - else if (c1==(0xa4&0x7f)) fold_state = 1; /* $B!#(B*/ - else if (c1==(0xa3&0x7f)) fold_state = 1; /* $B!$(B*/ - else if (c1==(0xa1&0x7f)) fold_state = 1; /* $B!W(B*/ - else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */ - else if (SP<=c1 && c1<=(0xdf&0x7f)) { /* X0201 */ - f_line = 1; - fold_state = LF;/* add one new f_line before this character */ - } else { - f_line = 1; - fold_state = LF;/* add one new f_line before this character */ - } - } else if (c2==0) { - /* kinsoku point in ASCII */ - if ( c1==')'|| /* { [ ( */ - c1==']'|| - c1=='}'|| - c1=='.'|| - c1==','|| - c1=='!'|| - c1=='?'|| - c1=='/'|| - c1==':'|| - c1==';') { - fold_state = 1; - /* just after special */ - } else if (!is_alnum(prev0)) { - f_line = char_size(c2,c1); - fold_state = LF; - } else if ((prev0==SP) || /* ignored new f_line */ - (prev0==LF)|| /* ignored new f_line */ - (prev0&0x80)) { /* X0208 - ASCII */ - f_line = char_size(c2,c1); - fold_state = LF;/* add one new f_line before this character */ - } else { - fold_state = 1; /* default no fold in ASCII */ - } - } else { - if (c2=='!') { - if (c1=='"') fold_state = 1; /* $B!"(B */ - else if (c1=='#') fold_state = 1; /* $B!#(B */ - else if (c1=='W') fold_state = 1; /* $B!W(B */ - else if (c1=='K') fold_state = 1; /* $B!K(B */ - else if (c1=='$') fold_state = 1; /* $B!$(B */ - else if (c1=='%') fold_state = 1; /* $B!%(B */ - else if (c1=='\'') fold_state = 1; /* $B!\(B */ - else if (c1=='(') fold_state = 1; /* $B!((B */ - else if (c1==')') fold_state = 1; /* $B!)(B */ - else if (c1=='*') fold_state = 1; /* $B!*(B */ - else if (c1=='+') fold_state = 1; /* $B!+(B */ - else if (c1==',') fold_state = 1; /* $B!,(B */ - /* default no fold in kinsoku */ - else { - fold_state = LF; - f_line = char_size(c2,c1); - /* add one new f_line before this character */ - } - } else { - f_line = char_size(c2,c1); - fold_state = LF; - /* add one new f_line before this character */ - } - } - } - } - /* terminator process */ - switch(fold_state) { - case LF: - oconv_newline(o_fconv); - (*o_fconv)(c2,c1); - break; - case 0: - return; - case CR: - oconv_newline(o_fconv); - break; - case TAB: - case SP: - (*o_fconv)(0,SP); - break; - default: - (*o_fconv)(c2,c1); - } -} - -static nkf_char z_prev2=0,z_prev1=0; - -static void -z_conv(nkf_char c2, nkf_char c1) -{ - - /* if (c2) c1 &= 0x7f; assertion */ - - if (c2 == JIS_X_0201_1976_K && (c1 == 0x20 || c1 == 0x7D || c1 == 0x7E)) { - (*o_zconv)(c2,c1); - return; - } - - if (x0201_f) { - if (z_prev2 == JIS_X_0201_1976_K) { - if (c2 == JIS_X_0201_1976_K) { - if (c1 == (0xde&0x7f)) { /* $BByE@(B */ - z_prev2 = 0; - (*o_zconv)(dv[(z_prev1-SP)*2], dv[(z_prev1-SP)*2+1]); - return; - } else if (c1 == (0xdf&0x7f) && ev[(z_prev1-SP)*2]) { /* $BH>ByE@(B */ - z_prev2 = 0; - (*o_zconv)(ev[(z_prev1-SP)*2], ev[(z_prev1-SP)*2+1]); - return; - } else if (x0213_f && c1 == (0xdf&0x7f) && ev_x0213[(z_prev1-SP)*2]) { /* $BH>ByE@(B */ - z_prev2 = 0; - (*o_zconv)(ev_x0213[(z_prev1-SP)*2], ev_x0213[(z_prev1-SP)*2+1]); - return; - } - } - z_prev2 = 0; - (*o_zconv)(cv[(z_prev1-SP)*2], cv[(z_prev1-SP)*2+1]); - } - if (c2 == JIS_X_0201_1976_K) { - if (dv[(c1-SP)*2] || ev[(c1-SP)*2] || (x0213_f && ev_x0213[(c1-SP)*2])) { - /* wait for $BByE@(B or $BH>ByE@(B */ - z_prev1 = c1; - z_prev2 = c2; - return; - } else { - (*o_zconv)(cv[(c1-SP)*2], cv[(c1-SP)*2+1]); - return; - } - } - } - - if (c2 == EOF) { - (*o_zconv)(c2, c1); - return; - } - - if (alpha_f&1 && c2 == 0x23) { - /* JISX0208 Alphabet */ - c2 = 0; - } else if (c2 == 0x21) { - /* JISX0208 Kigou */ - if (0x21==c1) { - if (alpha_f&2) { - c2 = 0; - c1 = SP; - } else if (alpha_f&4) { - (*o_zconv)(0, SP); - (*o_zconv)(0, SP); - return; - } - } else if (alpha_f&1 && 0x20<c1 && c1<0x7f && fv[c1-0x20]) { - c2 = 0; - c1 = fv[c1-0x20]; - } - } - - if (alpha_f&8 && c2 == 0) { - /* HTML Entity */ - const char *entity = 0; - switch (c1){ - case '>': entity = ">"; break; - case '<': entity = "<"; break; - case '\"': entity = """; break; - case '&': entity = "&"; break; - } - if (entity){ - while (*entity) (*o_zconv)(0, *entity++); - return; - } - } - - if (alpha_f & 16) { - /* JIS X 0208 Katakana to JIS X 0201 Katakana */ - if (c2 == 0x21) { - nkf_char c = 0; - switch (c1) { - case 0x23: - /* U+3002 (0x8142) Ideographic Full Stop -> U+FF61 (0xA1) Halfwidth Ideographic Full Stop */ - c = 0xA1; - break; - case 0x56: - /* U+300C (0x8175) Left Corner Bracket -> U+FF62 (0xA2) Halfwidth Left Corner Bracket */ - c = 0xA2; - break; - case 0x57: - /* U+300D (0x8176) Right Corner Bracket -> U+FF63 (0xA3) Halfwidth Right Corner Bracket */ - c = 0xA3; - break; - case 0x22: - /* U+3001 (0x8141) Ideographic Comma -> U+FF64 (0xA4) Halfwidth Ideographic Comma */ - c = 0xA4; - break; - case 0x26: - /* U+30FB (0x8145) Katakana Middle Dot -> U+FF65 (0xA5) Halfwidth Katakana Middle Dot */ - c = 0xA5; - break; - case 0x3C: - /* U+30FC (0x815B) Katakana-Hiragana Prolonged Sound Mark -> U+FF70 (0xB0) Halfwidth Katakana-Hiragana Prolonged Sound Mark */ - c = 0xB0; - break; - case 0x2B: - /* U+309B (0x814A) Katakana-Hiragana Voiced Sound Mark -> U+FF9E (0xDE) Halfwidth Katakana Voiced Sound Mark */ - c = 0xDE; - break; - case 0x2C: - /* U+309C (0x814B) Katakana-Hiragana Semi-Voiced Sound Mark -> U+FF9F (0xDF) Halfwidth Katakana Semi-Voiced Sound Mark */ - c = 0xDF; - break; - } - if (c) { - (*o_zconv)(JIS_X_0201_1976_K, c); - return; - } - } else if (c2 == 0x25) { - /* JISX0208 Katakana */ - static const int fullwidth_to_halfwidth[] = - { - 0x0000, 0x2700, 0x3100, 0x2800, 0x3200, 0x2900, 0x3300, 0x2A00, - 0x3400, 0x2B00, 0x3500, 0x3600, 0x365E, 0x3700, 0x375E, 0x3800, - 0x385E, 0x3900, 0x395E, 0x3A00, 0x3A5E, 0x3B00, 0x3B5E, 0x3C00, - 0x3C5E, 0x3D00, 0x3D5E, 0x3E00, 0x3E5E, 0x3F00, 0x3F5E, 0x4000, - 0x405E, 0x4100, 0x415E, 0x2F00, 0x4200, 0x425E, 0x4300, 0x435E, - 0x4400, 0x445E, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, - 0x4A5E, 0x4A5F, 0x4B00, 0x4B5E, 0x4B5F, 0x4C00, 0x4C5E, 0x4C5F, - 0x4D00, 0x4D5E, 0x4D5F, 0x4E00, 0x4E5E, 0x4E5F, 0x4F00, 0x5000, - 0x5100, 0x5200, 0x5300, 0x2C00, 0x5400, 0x2D00, 0x5500, 0x2E00, - 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x0000, 0x5C00, - 0x0000, 0x0000, 0x2600, 0x5D00, 0x335E, 0x0000, 0x0000, 0x365F, - 0x375F, 0x385F, 0x395F, 0x3A5F, 0x3E5F, 0x425F, 0x445F, 0x0000 - }; - if (fullwidth_to_halfwidth[c1-0x20]){ - c2 = fullwidth_to_halfwidth[c1-0x20]; - (*o_zconv)(JIS_X_0201_1976_K, c2>>8); - if (c2 & 0xFF) { - (*o_zconv)(JIS_X_0201_1976_K, c2&0xFF); - } - return; - } - } else if (c2 == 0 && nkf_char_unicode_p(c1) && - ((c1&VALUE_MASK) == 0x3099 || (c1&VALUE_MASK) == 0x309A)) { /* $B9g@.MQByE@!&H>ByE@(B */ - (*o_zconv)(JIS_X_0201_1976_K, 0x5E + (c1&VALUE_MASK) - 0x3099); - return; - } - } - (*o_zconv)(c2,c1); -} - - -#define rot13(c) ( \ - ( c < 'A') ? c: \ - (c <= 'M') ? (c + 13): \ - (c <= 'Z') ? (c - 13): \ - (c < 'a') ? (c): \ - (c <= 'm') ? (c + 13): \ - (c <= 'z') ? (c - 13): \ - (c) \ - ) - -#define rot47(c) ( \ - ( c < '!') ? c: \ - ( c <= 'O') ? (c + 47) : \ - ( c <= '~') ? (c - 47) : \ - c \ - ) - -static void -rot_conv(nkf_char c2, nkf_char c1) -{ - if (c2 == 0 || c2 == JIS_X_0201_1976_K || c2 == ISO_8859_1) { - c1 = rot13(c1); - } else if (c2) { - c1 = rot47(c1); - c2 = rot47(c2); - } - (*o_rot_conv)(c2,c1); -} - -static void -hira_conv(nkf_char c2, nkf_char c1) -{ - if (hira_f & 1) { - if (c2 == 0x25) { - if (0x20 < c1 && c1 < 0x74) { - c2 = 0x24; - (*o_hira_conv)(c2,c1); - return; - } else if (c1 == 0x74 && nkf_enc_unicode_p(output_encoding)) { - c2 = 0; - c1 = nkf_char_unicode_new(0x3094); - (*o_hira_conv)(c2,c1); - return; - } - } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) { - c1 += 2; - (*o_hira_conv)(c2,c1); - return; - } - } - if (hira_f & 2) { - if (c2 == 0 && c1 == nkf_char_unicode_new(0x3094)) { - c2 = 0x25; - c1 = 0x74; - } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) { - c2 = 0x25; - } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) { - c1 -= 2; - } - } - (*o_hira_conv)(c2,c1); -} - - -static void -iso2022jp_check_conv(nkf_char c2, nkf_char c1) -{ -#define RANGE_NUM_MAX 18 - static const nkf_char range[RANGE_NUM_MAX][2] = { - {0x222f, 0x2239,}, - {0x2242, 0x2249,}, - {0x2251, 0x225b,}, - {0x226b, 0x2271,}, - {0x227a, 0x227d,}, - {0x2321, 0x232f,}, - {0x233a, 0x2340,}, - {0x235b, 0x2360,}, - {0x237b, 0x237e,}, - {0x2474, 0x247e,}, - {0x2577, 0x257e,}, - {0x2639, 0x2640,}, - {0x2659, 0x267e,}, - {0x2742, 0x2750,}, - {0x2772, 0x277e,}, - {0x2841, 0x287e,}, - {0x4f54, 0x4f7e,}, - {0x7425, 0x747e}, - }; - nkf_char i; - nkf_char start, end, c; - - if(c2 >= 0x00 && c2 <= 0x20 && c1 >= 0x7f && c1 <= 0xff) { - c2 = GETA1; - c1 = GETA2; - } - if((c2 >= 0x29 && c2 <= 0x2f) || (c2 >= 0x75 && c2 <= 0x7e)) { - c2 = GETA1; - c1 = GETA2; - } - - for (i = 0; i < RANGE_NUM_MAX; i++) { - start = range[i][0]; - end = range[i][1]; - c = (c2 << 8) + c1; - if (c >= start && c <= end) { - c2 = GETA1; - c1 = GETA2; - } - } - (*o_iso2022jp_check_conv)(c2,c1); -} - - -/* This converts =?ISO-2022-JP?B?HOGE HOGE?= */ - -static const unsigned char *mime_pattern[] = { - (const unsigned char *)"\075?EUC-JP?B?", - (const unsigned char *)"\075?SHIFT_JIS?B?", - (const unsigned char *)"\075?ISO-8859-1?Q?", - (const unsigned char *)"\075?ISO-8859-1?B?", - (const unsigned char *)"\075?ISO-2022-JP?B?", - (const unsigned char *)"\075?ISO-2022-JP?B?", - (const unsigned char *)"\075?ISO-2022-JP?Q?", -#if defined(UTF8_INPUT_ENABLE) - (const unsigned char *)"\075?UTF-8?B?", - (const unsigned char *)"\075?UTF-8?Q?", -#endif - (const unsigned char *)"\075?US-ASCII?Q?", - NULL -}; - - -/* $B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\0u(B */ -nkf_char (*mime_priority_func[])(nkf_char c2, nkf_char c1, nkf_char c0) = { - e_iconv, s_iconv, 0, 0, 0, 0, 0, -#if defined(UTF8_INPUT_ENABLE) - w_iconv, w_iconv, -#endif - 0, -}; - -static const nkf_char mime_encode[] = { - EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K, JIS_X_0201_1976_K, -#if defined(UTF8_INPUT_ENABLE) - UTF_8, UTF_8, -#endif - ASCII, - 0 -}; - -static const nkf_char mime_encode_method[] = { - 'B', 'B','Q', 'B', 'B', 'B', 'Q', -#if defined(UTF8_INPUT_ENABLE) - 'B', 'Q', -#endif - 'Q', - 0 -}; - - -/* MIME preprocessor fifo */ - -#define MIME_BUF_SIZE (1024) /* 2^n ring buffer */ -#define MIME_BUF_MASK (MIME_BUF_SIZE-1) -#define mime_input_buf(n) mime_input_state.buf[(n)&MIME_BUF_MASK] -static struct { - unsigned char buf[MIME_BUF_SIZE]; - unsigned int top; - unsigned int last; /* decoded */ - unsigned int input; /* undecoded */ -} mime_input_state; -static nkf_char (*mime_iconv_back)(nkf_char c2,nkf_char c1,nkf_char c0) = NULL; - -#define MAXRECOVER 20 - -static void -mime_input_buf_unshift(nkf_char c) -{ - mime_input_buf(--mime_input_state.top) = (unsigned char)c; -} - -static nkf_char -mime_ungetc(nkf_char c, ARG_UNUSED FILE *f) -{ - mime_input_buf_unshift(c); - return c; -} - -static nkf_char -mime_ungetc_buf(nkf_char c, FILE *f) -{ - if (mimebuf_f) - (*i_mungetc_buf)(c,f); - else - mime_input_buf(--mime_input_state.input) = (unsigned char)c; - return c; -} - -static nkf_char -mime_getc_buf(FILE *f) -{ - /* we don't keep eof of mime_input_buf, because it contains ?= as - a terminator. It was checked in mime_integrity. */ - return ((mimebuf_f)? - (*i_mgetc_buf)(f):mime_input_buf(mime_input_state.input++)); -} - -static void -switch_mime_getc(void) -{ - if (i_getc!=mime_getc) { - i_mgetc = i_getc; i_getc = mime_getc; - i_mungetc = i_ungetc; i_ungetc = mime_ungetc; - if(mime_f==STRICT_MIME) { - i_mgetc_buf = i_mgetc; i_mgetc = mime_getc_buf; - i_mungetc_buf = i_mungetc; i_mungetc = mime_ungetc_buf; - } - } -} - -static void -unswitch_mime_getc(void) -{ - if(mime_f==STRICT_MIME) { - i_mgetc = i_mgetc_buf; - i_mungetc = i_mungetc_buf; - } - i_getc = i_mgetc; - i_ungetc = i_mungetc; - if(mime_iconv_back)set_iconv(FALSE, mime_iconv_back); - mime_iconv_back = NULL; -} - -static nkf_char -mime_integrity(FILE *f, const unsigned char *p) -{ - nkf_char c,d; - unsigned int q; - /* In buffered mode, read until =? or NL or buffer full - */ - mime_input_state.input = mime_input_state.top; - mime_input_state.last = mime_input_state.top; - - while(*p) mime_input_buf(mime_input_state.input++) = *p++; - d = 0; - q = mime_input_state.input; - while((c=(*i_getc)(f))!=EOF) { - if (((mime_input_state.input-mime_input_state.top)&MIME_BUF_MASK)==0) { - break; /* buffer full */ - } - if (c=='=' && d=='?') { - /* checked. skip header, start decode */ - mime_input_buf(mime_input_state.input++) = (unsigned char)c; - /* mime_last_input = mime_input_state.input; */ - mime_input_state.input = q; - switch_mime_getc(); - return 1; - } - if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c)))) - break; - /* Should we check length mod 4? */ - mime_input_buf(mime_input_state.input++) = (unsigned char)c; - d=c; - } - /* In case of Incomplete MIME, no MIME decode */ - mime_input_buf(mime_input_state.input++) = (unsigned char)c; - mime_input_state.last = mime_input_state.input; /* point undecoded buffer */ - mime_decode_mode = 1; /* no decode on mime_input_buf last in mime_getc */ - switch_mime_getc(); /* anyway we need buffered getc */ - return 1; -} - -static nkf_char -mime_begin_strict(FILE *f) -{ - nkf_char c1 = 0; - int i,j,k; - const unsigned char *p,*q; - nkf_char r[MAXRECOVER]; /* recovery buffer, max mime pattern length */ - - mime_decode_mode = FALSE; - /* =? has been checked */ - j = 0; - p = mime_pattern[j]; - r[0]='='; r[1]='?'; - - for(i=2;p[i]>SP;i++) { /* start at =? */ - if (((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i]) { - /* pattern fails, try next one */ - q = p; - while (mime_pattern[++j]) { - p = mime_pattern[j]; - for(k=2;k<i;k++) /* assume length(p) > i */ - if (p[k]!=q[k]) break; - if (k==i && nkf_toupper(c1)==p[k]) break; - } - p = mime_pattern[j]; - if (p) continue; /* found next one, continue */ - /* all fails, output from recovery buffer */ - (*i_ungetc)(c1,f); - for(j=0;j<i;j++) { - (*oconv)(0,r[j]); - } - return c1; - } - } - mime_decode_mode = p[i-2]; - - mime_iconv_back = iconv; - set_iconv(FALSE, mime_priority_func[j]); - clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME); - - if (mime_decode_mode=='B') { - mimebuf_f = unbuf_f; - if (!unbuf_f) { - /* do MIME integrity check */ - return mime_integrity(f,mime_pattern[j]); - } - } - switch_mime_getc(); - mimebuf_f = TRUE; - return c1; -} - -static nkf_char -mime_begin(FILE *f) -{ - nkf_char c1 = 0; - int i,k; - - /* In NONSTRICT mode, only =? is checked. In case of failure, we */ - /* re-read and convert again from mime_buffer. */ - - /* =? has been checked */ - k = mime_input_state.last; - mime_input_buf(mime_input_state.last++)='='; mime_input_buf(mime_input_state.last++)='?'; - for(i=2;i<MAXRECOVER;i++) { /* start at =? */ - /* We accept any character type even if it is breaked by new lines */ - c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1; - if (c1==LF||c1==SP||c1==CR|| - c1=='-'||c1=='_'||is_alnum(c1)) continue; - if (c1=='=') { - /* Failed. But this could be another MIME preemble */ - (*i_ungetc)(c1,f); - mime_input_state.last--; - break; - } - if (c1!='?') break; - else { - /* c1=='?' */ - c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1; - if (!(++i<MAXRECOVER) || c1==EOF) break; - if (c1=='b'||c1=='B') { - mime_decode_mode = 'B'; - } else if (c1=='q'||c1=='Q') { - mime_decode_mode = 'Q'; - } else { - break; - } - c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1; - if (!(++i<MAXRECOVER) || c1==EOF) break; - if (c1!='?') { - mime_decode_mode = FALSE; - } - break; - } - } - switch_mime_getc(); - if (!mime_decode_mode) { - /* false MIME premble, restart from mime_buffer */ - mime_decode_mode = 1; /* no decode, but read from the mime_buffer */ - /* Since we are in MIME mode until buffer becomes empty, */ - /* we never go into mime_begin again for a while. */ - return c1; - } - /* discard mime preemble, and goto MIME mode */ - mime_input_state.last = k; - /* do no MIME integrity check */ - return c1; /* used only for checking EOF */ -} - -#ifdef CHECK_OPTION -static void -no_putc(ARG_UNUSED nkf_char c) -{ - ; -} - -static void -debug(const char *str) -{ - if (debug_f){ - fprintf(stderr, "%s\n", str ? str : "NULL"); - } -} -#endif - -static void -set_input_codename(const char *codename) -{ - if (!input_codename) { - input_codename = codename; - } else if (strcmp(codename, input_codename) != 0) { - input_codename = ""; - } -} - -static const char* -get_guessed_code(void) -{ - if (input_codename && !*input_codename) { - input_codename = "BINARY"; - } else { - struct input_code *p = find_inputcode_byfunc(iconv); - if (!input_codename) { - input_codename = "ASCII"; - } else if (strcmp(input_codename, "Shift_JIS") == 0) { - if (p->score & (SCORE_DEPEND|SCORE_CP932)) - input_codename = "CP932"; - } else if (strcmp(input_codename, "EUC-JP") == 0) { - if (p->score & SCORE_X0213) - input_codename = "EUC-JIS-2004"; - else if (p->score & (SCORE_X0212)) - input_codename = "EUCJP-MS"; - else if (p->score & (SCORE_DEPEND|SCORE_CP932)) - input_codename = "CP51932"; - } else if (strcmp(input_codename, "ISO-2022-JP") == 0) { - if (p->score & (SCORE_KANA)) - input_codename = "CP50221"; - else if (p->score & (SCORE_DEPEND|SCORE_CP932)) - input_codename = "CP50220"; - } - } - return input_codename; -} - -#if !defined(PERL_XS) && !defined(WIN32DLL) -static void -print_guessed_code(char *filename) -{ - if (filename != NULL) printf("%s: ", filename); - if (input_codename && !*input_codename) { - printf("BINARY\n"); - } else { - input_codename = get_guessed_code(); - if (guess_f == 1) { - printf("%s\n", input_codename); - } else { - printf("%s%s%s%s\n", - input_codename, - iconv != w_iconv16 && iconv != w_iconv32 ? "" : - input_endian == ENDIAN_LITTLE ? " LE" : - input_endian == ENDIAN_BIG ? " BE" : - "[BUG]", - input_bom_f ? " (BOM)" : "", - input_eol == CR ? " (CR)" : - input_eol == LF ? " (LF)" : - input_eol == CRLF ? " (CRLF)" : - input_eol == EOF ? " (MIXED NL)" : - ""); - } - } -} -#endif /*WIN32DLL*/ - -#ifdef INPUT_OPTION - -static nkf_char -hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f)) -{ - nkf_char c1, c2, c3; - c1 = (*g)(f); - if (c1 != ch){ - return c1; - } - c2 = (*g)(f); - if (!nkf_isxdigit(c2)){ - (*u)(c2, f); - return c1; - } - c3 = (*g)(f); - if (!nkf_isxdigit(c3)){ - (*u)(c2, f); - (*u)(c3, f); - return c1; - } - return (hex2bin(c2) << 4) | hex2bin(c3); -} - -static nkf_char -cap_getc(FILE *f) -{ - return hex_getc(':', f, i_cgetc, i_cungetc); -} - -static nkf_char -cap_ungetc(nkf_char c, FILE *f) -{ - return (*i_cungetc)(c, f); -} - -static nkf_char -url_getc(FILE *f) -{ - return hex_getc('%', f, i_ugetc, i_uungetc); -} - -static nkf_char -url_ungetc(nkf_char c, FILE *f) -{ - return (*i_uungetc)(c, f); -} -#endif - -#ifdef NUMCHAR_OPTION -static nkf_char -numchar_getc(FILE *f) -{ - nkf_char (*g)(FILE *) = i_ngetc; - nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc; - int i = 0, j; - nkf_char buf[12]; - nkf_char c = -1; - - buf[i] = (*g)(f); - if (buf[i] == '&'){ - buf[++i] = (*g)(f); - if (buf[i] == '#'){ - c = 0; - buf[++i] = (*g)(f); - if (buf[i] == 'x' || buf[i] == 'X'){ - for (j = 0; j < 7; j++){ - buf[++i] = (*g)(f); - if (!nkf_isxdigit(buf[i])){ - if (buf[i] != ';'){ - c = -1; - } - break; - } - c <<= 4; - c |= hex2bin(buf[i]); - } - }else{ - for (j = 0; j < 8; j++){ - if (j){ - buf[++i] = (*g)(f); - } - if (!nkf_isdigit(buf[i])){ - if (buf[i] != ';'){ - c = -1; - } - break; - } - c *= 10; - c += hex2bin(buf[i]); - } - } - } - } - if (c != -1){ - return nkf_char_unicode_new(c); - } - while (i > 0){ - (*u)(buf[i], f); - --i; - } - return buf[0]; -} - -static nkf_char -numchar_ungetc(nkf_char c, FILE *f) -{ - return (*i_nungetc)(c, f); -} -#endif - -#ifdef UNICODE_NORMALIZATION - -static nkf_char -nfc_getc(FILE *f) -{ - nkf_char (*g)(FILE *f) = i_nfc_getc; - nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc; - nkf_buf_t *buf = nkf_state->nfc_buf; - const unsigned char *array; - int lower=0, upper=NORMALIZATION_TABLE_LENGTH-1; - nkf_char c = (*g)(f); - - if (c == EOF || c > 0xFF || (c & 0xc0) == 0x80) return c; - - nkf_buf_push(buf, c); - do { - while (lower <= upper) { - int mid = (lower+upper) / 2; - int len; - array = normalization_table[mid].nfd; - for (len=0; len < NORMALIZATION_TABLE_NFD_LENGTH && array[len]; len++) { - if (len >= nkf_buf_length(buf)) { - c = (*g)(f); - if (c == EOF) { - len = 0; - lower = 1, upper = 0; - break; - } - nkf_buf_push(buf, c); - } - if (array[len] != nkf_buf_at(buf, len)) { - if (array[len] < nkf_buf_at(buf, len)) lower = mid + 1; - else upper = mid - 1; - len = 0; - break; - } - } - if (len > 0) { - int i; - array = normalization_table[mid].nfc; - nkf_buf_clear(buf); - for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++) - nkf_buf_push(buf, array[i]); - break; - } - } - } while (lower <= upper); - - while (nkf_buf_length(buf) > 1) (*u)(nkf_buf_pop(buf), f); - c = nkf_buf_pop(buf); - - return c; -} - -static nkf_char -nfc_ungetc(nkf_char c, FILE *f) -{ - return (*i_nfc_ungetc)(c, f); -} -#endif /* UNICODE_NORMALIZATION */ - - -static nkf_char -base64decode(nkf_char c) -{ - int i; - if (c > '@') { - if (c < '[') { - i = c - 'A'; /* A..Z 0-25 */ - } else if (c == '_') { - i = '?' /* 63 */ ; /* _ 63 */ - } else { - i = c - 'G' /* - 'a' + 26 */ ; /* a..z 26-51 */ - } - } else if (c > '/') { - i = c - '0' + '4' /* - '0' + 52 */ ; /* 0..9 52-61 */ - } else if (c == '+' || c == '-') { - i = '>' /* 62 */ ; /* + and - 62 */ - } else { - i = '?' /* 63 */ ; /* / 63 */ - } - return (i); -} - -static nkf_char -mime_getc(FILE *f) -{ - nkf_char c1, c2, c3, c4, cc; - nkf_char t1, t2, t3, t4, mode, exit_mode; - nkf_char lwsp_count; - char *lwsp_buf; - char *lwsp_buf_new; - nkf_char lwsp_size = 128; - - if (mime_input_state.top != mime_input_state.last) { /* Something is in FIFO */ - return mime_input_buf(mime_input_state.top++); - } - if (mime_decode_mode==1 ||mime_decode_mode==FALSE) { - mime_decode_mode=FALSE; - unswitch_mime_getc(); - return (*i_getc)(f); - } - - if (mimebuf_f == FIXED_MIME) - exit_mode = mime_decode_mode; - else - exit_mode = FALSE; - if (mime_decode_mode == 'Q') { - if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF); - restart_mime_q: - if (c1=='_' && mimebuf_f != FIXED_MIME) return SP; - if (c1<=SP || DEL<=c1) { - mime_decode_mode = exit_mode; /* prepare for quit */ - return c1; - } - if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) { - return c1; - } - - mime_decode_mode = exit_mode; /* prepare for quit */ - if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF); - if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) { - /* end Q encoding */ - input_mode = exit_mode; - lwsp_count = 0; - lwsp_buf = nkf_xmalloc((lwsp_size+5)*sizeof(char)); - while ((c1=(*i_getc)(f))!=EOF) { - switch (c1) { - case LF: - case CR: - if (c1==LF) { - if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - c1 = LF; - } else { - if ((c1=(*i_getc)(f))!=EOF && c1 == LF) { - if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - i_ungetc(LF,f); - } else { - i_ungetc(c1,f); - } - c1 = CR; - } - break; - case SP: - case TAB: - lwsp_buf[lwsp_count] = (unsigned char)c1; - if (lwsp_count++>lwsp_size){ - lwsp_size <<= 1; - lwsp_buf_new = nkf_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char)); - lwsp_buf = lwsp_buf_new; - } - continue; - } - break; - } - if (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SP && lwsp_buf[lwsp_count-1] != TAB))) { - i_ungetc(c1,f); - for(lwsp_count--;lwsp_count>0;lwsp_count--) - i_ungetc(lwsp_buf[lwsp_count],f); - c1 = lwsp_buf[0]; - } - nkf_xfree(lwsp_buf); - return c1; - } - if (c1=='='&&c2<SP) { /* this is soft wrap */ - while((c1 = (*i_mgetc)(f)) <=SP) { - if (c1 == EOF) return (EOF); - } - mime_decode_mode = 'Q'; /* still in MIME */ - goto restart_mime_q; - } - if (c1=='?') { - mime_decode_mode = 'Q'; /* still in MIME */ - (*i_mungetc)(c2,f); - return c1; - } - if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF); - if (c2<=SP) return c2; - mime_decode_mode = 'Q'; /* still in MIME */ - return ((hex2bin(c2)<<4) + hex2bin(c3)); - } - - if (mime_decode_mode != 'B') { - mime_decode_mode = FALSE; - return (*i_mgetc)(f); - } - - - /* Base64 encoding */ - /* - MIME allows line break in the middle of - Base64, but we are very pessimistic in decoding - in unbuf mode because MIME encoded code may broken by - less or editor's control sequence (such as ESC-[-K in unbuffered - mode. ignore incomplete MIME. - */ - mode = mime_decode_mode; - mime_decode_mode = exit_mode; /* prepare for quit */ - - while ((c1 = (*i_mgetc)(f))<=SP) { - if (c1==EOF) - return (EOF); - } - mime_c2_retry: - if ((c2 = (*i_mgetc)(f))<=SP) { - if (c2==EOF) - return (EOF); - if (mime_f != STRICT_MIME) goto mime_c2_retry; - if (mimebuf_f!=FIXED_MIME) input_mode = ASCII; - return c2; - } - if ((c1 == '?') && (c2 == '=')) { - input_mode = ASCII; - lwsp_count = 0; - lwsp_buf = nkf_xmalloc((lwsp_size+5)*sizeof(char)); - while ((c1=(*i_getc)(f))!=EOF) { - switch (c1) { - case LF: - case CR: - if (c1==LF) { - if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - c1 = LF; - } else { - if ((c1=(*i_getc)(f))!=EOF) { - if (c1==SP) { - i_ungetc(SP,f); - continue; - } else if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - i_ungetc(LF,f); - } else { - i_ungetc(c1,f); - } - c1 = CR; - } - break; - case SP: - case TAB: - lwsp_buf[lwsp_count] = (unsigned char)c1; - if (lwsp_count++>lwsp_size){ - lwsp_size <<= 1; - lwsp_buf_new = nkf_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char)); - lwsp_buf = lwsp_buf_new; - } - continue; - } - break; - } - if (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SP && lwsp_buf[lwsp_count-1] != TAB))) { - i_ungetc(c1,f); - for(lwsp_count--;lwsp_count>0;lwsp_count--) - i_ungetc(lwsp_buf[lwsp_count],f); - c1 = lwsp_buf[0]; - } - nkf_xfree(lwsp_buf); - return c1; - } - mime_c3_retry: - if ((c3 = (*i_mgetc)(f))<=SP) { - if (c3==EOF) - return (EOF); - if (mime_f != STRICT_MIME) goto mime_c3_retry; - if (mimebuf_f!=FIXED_MIME) input_mode = ASCII; - return c3; - } - mime_c4_retry: - if ((c4 = (*i_mgetc)(f))<=SP) { - if (c4==EOF) - return (EOF); - if (mime_f != STRICT_MIME) goto mime_c4_retry; - if (mimebuf_f!=FIXED_MIME) input_mode = ASCII; - return c4; - } - - mime_decode_mode = mode; /* still in MIME sigh... */ - - /* BASE 64 decoding */ - - t1 = 0x3f & base64decode(c1); - t2 = 0x3f & base64decode(c2); - t3 = 0x3f & base64decode(c3); - t4 = 0x3f & base64decode(c4); - cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03); - if (c2 != '=') { - mime_input_buf(mime_input_state.last++) = (unsigned char)cc; - cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f); - if (c3 != '=') { - mime_input_buf(mime_input_state.last++) = (unsigned char)cc; - cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f); - if (c4 != '=') - mime_input_buf(mime_input_state.last++) = (unsigned char)cc; - } - } else { - return c1; - } - return mime_input_buf(mime_input_state.top++); -} - -static const char basis_64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -#define MIMEOUT_BUF_LENGTH 74 -static struct { - unsigned char buf[MIMEOUT_BUF_LENGTH+1]; - int count; -} mimeout_state; - -/*nkf_char mime_lastchar2, mime_lastchar1;*/ - -static void -open_mime(nkf_char mode) -{ - const unsigned char *p; - int i; - int j; - p = mime_pattern[0]; - for(i=0;mime_pattern[i];i++) { - if (mode == mime_encode[i]) { - p = mime_pattern[i]; - break; - } - } - mimeout_mode = mime_encode_method[i]; - i = 0; - if (base64_count>45) { - if (mimeout_state.count>0 && nkf_isblank(mimeout_state.buf[i])){ - (*o_mputc)(mimeout_state.buf[i]); - i++; - } - put_newline(o_mputc); - (*o_mputc)(SP); - base64_count = 1; - if (mimeout_state.count>0 && nkf_isspace(mimeout_state.buf[i])) { - i++; - } - } - for (;i<mimeout_state.count;i++) { - if (nkf_isspace(mimeout_state.buf[i])) { - (*o_mputc)(mimeout_state.buf[i]); - base64_count ++; - } else { - break; - } - } - while(*p) { - (*o_mputc)(*p++); - base64_count ++; - } - j = mimeout_state.count; - mimeout_state.count = 0; - for (;i<j;i++) { - mime_putc(mimeout_state.buf[i]); - } -} - -static void -mime_prechar(nkf_char c2, nkf_char c1) -{ - if (mimeout_mode > 0){ - if (c2 == EOF){ - if (base64_count + mimeout_state.count/3*4> 73){ - (*o_base64conv)(EOF,0); - oconv_newline(o_base64conv); - (*o_base64conv)(0,SP); - base64_count = 1; - } - } else { - if ((c2 != 0 || c1 > DEL) && base64_count + mimeout_state.count/3*4> 66) { - (*o_base64conv)(EOF,0); - oconv_newline(o_base64conv); - (*o_base64conv)(0,SP); - base64_count = 1; - mimeout_mode = -1; - } - } - } else if (c2) { - if (c2 != EOF && base64_count + mimeout_state.count/3*4> 60) { - mimeout_mode = (output_mode==ASCII ||output_mode == ISO_8859_1) ? 'Q' : 'B'; - open_mime(output_mode); - (*o_base64conv)(EOF,0); - oconv_newline(o_base64conv); - (*o_base64conv)(0,SP); - base64_count = 1; - mimeout_mode = -1; - } - } -} - -static void -close_mime(void) -{ - (*o_mputc)('?'); - (*o_mputc)('='); - base64_count += 2; - mimeout_mode = 0; -} - -static void -eof_mime(void) -{ - switch(mimeout_mode) { - case 'Q': - case 'B': - break; - case 2: - (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0x3)<< 4)]); - (*o_mputc)('='); - (*o_mputc)('='); - base64_count += 3; - break; - case 1: - (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0xF) << 2)]); - (*o_mputc)('='); - base64_count += 2; - break; - } - if (mimeout_mode > 0) { - if (mimeout_f!=FIXED_MIME) { - close_mime(); - } else if (mimeout_mode != 'Q') - mimeout_mode = 'B'; - } -} - -static void -mimeout_addchar(nkf_char c) -{ - switch(mimeout_mode) { - case 'Q': - if (c==CR||c==LF) { - (*o_mputc)(c); - base64_count = 0; - } else if(!nkf_isalnum(c)) { - (*o_mputc)('='); - (*o_mputc)(bin2hex(((c>>4)&0xf))); - (*o_mputc)(bin2hex((c&0xf))); - base64_count += 3; - } else { - (*o_mputc)(c); - base64_count++; - } - break; - case 'B': - nkf_state->mimeout_state=c; - (*o_mputc)(basis_64[c>>2]); - mimeout_mode=2; - base64_count ++; - break; - case 2: - (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0x3)<< 4) | ((c & 0xF0) >> 4)]); - nkf_state->mimeout_state=c; - mimeout_mode=1; - base64_count ++; - break; - case 1: - (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0xF) << 2) | ((c & 0xC0) >>6)]); - (*o_mputc)(basis_64[c & 0x3F]); - mimeout_mode='B'; - base64_count += 2; - break; - default: - (*o_mputc)(c); - base64_count++; - break; - } -} - -static void -mime_putc(nkf_char c) -{ - int i, j; - nkf_char lastchar; - - if (mimeout_f == FIXED_MIME){ - if (mimeout_mode == 'Q'){ - if (base64_count > 71){ - if (c!=CR && c!=LF) { - (*o_mputc)('='); - put_newline(o_mputc); - } - base64_count = 0; - } - }else{ - if (base64_count > 71){ - eof_mime(); - put_newline(o_mputc); - base64_count = 0; - } - if (c == EOF) { /* c==EOF */ - eof_mime(); - } - } - if (c != EOF) { /* c==EOF */ - mimeout_addchar(c); - } - return; - } - - /* mimeout_f != FIXED_MIME */ - - if (c == EOF) { /* c==EOF */ - if (mimeout_mode == -1 && mimeout_state.count > 1) open_mime(output_mode); - j = mimeout_state.count; - mimeout_state.count = 0; - i = 0; - if (mimeout_mode > 0) { - if (!nkf_isblank(mimeout_state.buf[j-1])) { - for (;i<j;i++) { - if (nkf_isspace(mimeout_state.buf[i]) && base64_count < 71){ - break; - } - mimeout_addchar(mimeout_state.buf[i]); - } - eof_mime(); - for (;i<j;i++) { - mimeout_addchar(mimeout_state.buf[i]); - } - } else { - for (;i<j;i++) { - mimeout_addchar(mimeout_state.buf[i]); - } - eof_mime(); - } - } else { - for (;i<j;i++) { - mimeout_addchar(mimeout_state.buf[i]); - } - } - return; - } - - if (mimeout_state.count > 0){ - lastchar = mimeout_state.buf[mimeout_state.count - 1]; - }else{ - lastchar = -1; - } - - if (mimeout_mode=='Q') { - if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) { - if (c == CR || c == LF) { - close_mime(); - (*o_mputc)(c); - base64_count = 0; - return; - } else if (c <= SP) { - close_mime(); - if (base64_count > 70) { - put_newline(o_mputc); - base64_count = 0; - } - if (!nkf_isblank(c)) { - (*o_mputc)(SP); - base64_count++; - } - } else { - if (base64_count > 70) { - close_mime(); - put_newline(o_mputc); - (*o_mputc)(SP); - base64_count = 1; - open_mime(output_mode); - } - if (!nkf_noescape_mime(c)) { - mimeout_addchar(c); - return; - } - } - if (c != 0x1B) { - (*o_mputc)(c); - base64_count++; - return; - } - } - } - - if (mimeout_mode <= 0) { - if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 || - output_mode == UTF_8)) { - if (nkf_isspace(c)) { - int flag = 0; - if (mimeout_mode == -1) { - flag = 1; - } - if (c==CR || c==LF) { - if (flag) { - open_mime(output_mode); - output_mode = 0; - } else { - base64_count = 0; - } - } - for (i=0;i<mimeout_state.count;i++) { - (*o_mputc)(mimeout_state.buf[i]); - if (mimeout_state.buf[i] == CR || mimeout_state.buf[i] == LF){ - base64_count = 0; - }else{ - base64_count++; - } - } - if (flag) { - eof_mime(); - base64_count = 0; - mimeout_mode = 0; - } - mimeout_state.buf[0] = (char)c; - mimeout_state.count = 1; - }else{ - if (base64_count > 1 - && base64_count + mimeout_state.count > 76 - && mimeout_state.buf[0] != CR && mimeout_state.buf[0] != LF){ - static const char *str = "boundary=\""; - static int len = 10; - i = 0; - - for (; i < mimeout_state.count - len; ++i) { - if (!strncmp((char *)(mimeout_state.buf+i), str, len)) { - i += len - 2; - break; - } - } - - if (i == 0 || i == mimeout_state.count - len) { - put_newline(o_mputc); - base64_count = 0; - if (!nkf_isspace(mimeout_state.buf[0])){ - (*o_mputc)(SP); - base64_count++; - } - } - else { - int j; - for (j = 0; j <= i; ++j) { - (*o_mputc)(mimeout_state.buf[j]); - } - put_newline(o_mputc); - base64_count = 1; - for (; j <= mimeout_state.count; ++j) { - mimeout_state.buf[j - i] = mimeout_state.buf[j]; - } - mimeout_state.count -= i; - } - } - mimeout_state.buf[mimeout_state.count++] = (char)c; - if (mimeout_state.count>MIMEOUT_BUF_LENGTH) { - open_mime(output_mode); - } - } - return; - }else{ - if (lastchar==CR || lastchar == LF){ - for (i=0;i<mimeout_state.count;i++) { - (*o_mputc)(mimeout_state.buf[i]); - } - base64_count = 0; - mimeout_state.count = 0; - } - if (lastchar==SP) { - for (i=0;i<mimeout_state.count-1;i++) { - (*o_mputc)(mimeout_state.buf[i]); - base64_count++; - } - mimeout_state.buf[0] = SP; - mimeout_state.count = 1; - } - open_mime(output_mode); - } - }else{ - /* mimeout_mode == 'B', 1, 2 */ - if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 || - output_mode == UTF_8)) { - if (lastchar == CR || lastchar == LF){ - if (nkf_isblank(c)) { - for (i=0;i<mimeout_state.count;i++) { - mimeout_addchar(mimeout_state.buf[i]); - } - mimeout_state.count = 0; - } else { - eof_mime(); - for (i=0;i<mimeout_state.count;i++) { - (*o_mputc)(mimeout_state.buf[i]); - } - base64_count = 0; - mimeout_state.count = 0; - } - mimeout_state.buf[mimeout_state.count++] = (char)c; - return; - } - if (nkf_isspace(c)) { - for (i=0;i<mimeout_state.count;i++) { - if (SP<mimeout_state.buf[i] && mimeout_state.buf[i]<DEL) { - eof_mime(); - for (i=0;i<mimeout_state.count;i++) { - (*o_mputc)(mimeout_state.buf[i]); - base64_count++; - } - mimeout_state.count = 0; - } - } - mimeout_state.buf[mimeout_state.count++] = (char)c; - if (mimeout_state.count>MIMEOUT_BUF_LENGTH) { - eof_mime(); - for (j=0;j<mimeout_state.count;j++) { - (*o_mputc)(mimeout_state.buf[j]); - base64_count++; - } - mimeout_state.count = 0; - } - return; - } - if (mimeout_state.count>0 && SP<c && c!='=') { - mimeout_state.buf[mimeout_state.count++] = (char)c; - if (mimeout_state.count>MIMEOUT_BUF_LENGTH) { - j = mimeout_state.count; - mimeout_state.count = 0; - for (i=0;i<j;i++) { - mimeout_addchar(mimeout_state.buf[i]); - } - } - return; - } - } - } - if (mimeout_state.count>0) { - j = mimeout_state.count; - mimeout_state.count = 0; - for (i=0;i<j;i++) { - if (mimeout_state.buf[i]==CR || mimeout_state.buf[i]==LF) - break; - mimeout_addchar(mimeout_state.buf[i]); - } - if (i<j) { - eof_mime(); - base64_count=0; - for (;i<j;i++) { - (*o_mputc)(mimeout_state.buf[i]); - } - open_mime(output_mode); - } - } - mimeout_addchar(c); -} - -static void -base64_conv(nkf_char c2, nkf_char c1) -{ - mime_prechar(c2, c1); - (*o_base64conv)(c2,c1); -} - -#ifdef HAVE_ICONV_H -typedef struct nkf_iconv_t { - iconv_t cd; - char *input_buffer; - size_t input_buffer_size; - char *output_buffer; - size_t output_buffer_size; -}; - -static nkf_iconv_t -nkf_iconv_new(char *tocode, char *fromcode) -{ - nkf_iconv_t converter; - - converter->input_buffer_size = IOBUF_SIZE; - converter->input_buffer = nkf_xmalloc(converter->input_buffer_size); - converter->output_buffer_size = IOBUF_SIZE * 2; - converter->output_buffer = nkf_xmalloc(converter->output_buffer_size); - converter->cd = iconv_open(tocode, fromcode); - if (converter->cd == (iconv_t)-1) - { - switch (errno) { - case EINVAL: - perror(fprintf("iconv doesn't support %s to %s conversion.", fromcode, tocode)); - return -1; - default: - perror("can't iconv_open"); - } - } -} - -static size_t -nkf_iconv_convert(nkf_iconv_t *converter, FILE *input) -{ - size_t invalid = (size_t)0; - char *input_buffer = converter->input_buffer; - size_t input_length = (size_t)0; - char *output_buffer = converter->output_buffer; - size_t output_length = converter->output_buffer_size; - int c; - - do { - if (c != EOF) { - while ((c = (*i_getc)(f)) != EOF) { - input_buffer[input_length++] = c; - if (input_length < converter->input_buffer_size) break; - } - } - - size_t ret = iconv(converter->cd, &input_buffer, &input_length, &output_buffer, &output_length); - while (output_length-- > 0) { - (*o_putc)(output_buffer[converter->output_buffer_size-output_length]); - } - if (ret == (size_t) - 1) { - switch (errno) { - case EINVAL: - if (input_buffer != converter->input_buffer) - memmove(converter->input_buffer, input_buffer, input_length); - break; - case E2BIG: - converter->output_buffer_size *= 2; - output_buffer = realloc(converter->outbuf, converter->output_buffer_size); - if (output_buffer == NULL) { - perror("can't realloc"); - return -1; - } - converter->output_buffer = output_buffer; - break; - default: - perror("can't iconv"); - return -1; - } - } else { - invalid += ret; - } - } while (1); - - return invalid; -} - - -static void -nkf_iconv_close(nkf_iconv_t *convert) -{ - nkf_xfree(converter->inbuf); - nkf_xfree(converter->outbuf); - iconv_close(converter->cd); -} -#endif - - -static void -reinit(void) -{ - { - struct input_code *p = input_code_list; - while (p->name){ - status_reinit(p++); - } - } - unbuf_f = FALSE; - estab_f = FALSE; - nop_f = FALSE; - binmode_f = TRUE; - rot_f = FALSE; - hira_f = FALSE; - alpha_f = FALSE; - mime_f = MIME_DECODE_DEFAULT; - mime_decode_f = FALSE; - mimebuf_f = FALSE; - broken_f = FALSE; - iso8859_f = FALSE; - mimeout_f = FALSE; - x0201_f = NKF_UNSPECIFIED; - iso2022jp_f = FALSE; -#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE) - ms_ucs_map_f = UCS_MAP_ASCII; -#endif -#ifdef UTF8_INPUT_ENABLE - no_cp932ext_f = FALSE; - no_best_fit_chars_f = FALSE; - encode_fallback = NULL; - unicode_subchar = '?'; - input_endian = ENDIAN_BIG; -#endif -#ifdef UTF8_OUTPUT_ENABLE - output_bom_f = FALSE; - output_endian = ENDIAN_BIG; -#endif -#ifdef UNICODE_NORMALIZATION - nfc_f = FALSE; -#endif -#ifdef INPUT_OPTION - cap_f = FALSE; - url_f = FALSE; - numchar_f = FALSE; -#endif -#ifdef CHECK_OPTION - noout_f = FALSE; - debug_f = FALSE; -#endif - guess_f = 0; -#ifdef EXEC_IO - exec_f = 0; -#endif -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; - cp932inv_f = TRUE; -#endif -#ifdef X0212_ENABLE - x0212_f = FALSE; - x0213_f = FALSE; -#endif - { - int i; - for (i = 0; i < 256; i++){ - prefix_table[i] = 0; - } - } - hold_count = 0; - mimeout_state.count = 0; - mimeout_mode = 0; - base64_count = 0; - f_line = 0; - f_prev = 0; - fold_preserve_f = FALSE; - fold_f = FALSE; - fold_len = 0; - kanji_intro = DEFAULT_J; - ascii_intro = DEFAULT_R; - fold_margin = FOLD_MARGIN; - o_zconv = no_connection; - o_fconv = no_connection; - o_eol_conv = no_connection; - o_rot_conv = no_connection; - o_hira_conv = no_connection; - o_base64conv = no_connection; - o_iso2022jp_check_conv = no_connection; - o_putc = std_putc; - i_getc = std_getc; - i_ungetc = std_ungetc; - i_bgetc = std_getc; - i_bungetc = std_ungetc; - o_mputc = std_putc; - i_mgetc = std_getc; - i_mungetc = std_ungetc; - i_mgetc_buf = std_getc; - i_mungetc_buf = std_ungetc; - output_mode = ASCII; - input_mode = ASCII; - mime_decode_mode = FALSE; - file_out_f = FALSE; - eolmode_f = 0; - input_eol = 0; - prev_cr = 0; - option_mode = 0; - z_prev2=0,z_prev1=0; -#ifdef CHECK_OPTION - iconv_for_check = 0; -#endif - input_codename = NULL; - input_encoding = NULL; - output_encoding = NULL; - nkf_state_init(); -#ifdef WIN32DLL - reinitdll(); -#endif /*WIN32DLL*/ -} - -static int -module_connection(void) -{ - if (input_encoding) set_input_encoding(input_encoding); - if (!output_encoding) { - output_encoding = nkf_default_encoding(); - } - if (!output_encoding) { - if (noout_f || guess_f) output_encoding = nkf_enc_from_index(ISO_2022_JP); - else return -1; - } - set_output_encoding(output_encoding); - oconv = nkf_enc_to_oconv(output_encoding); - o_putc = std_putc; - if (nkf_enc_unicode_p(output_encoding)) - output_mode = UTF_8; - - if (x0201_f == NKF_UNSPECIFIED) { - x0201_f = X0201_DEFAULT; - } - - /* replace continuation module, from output side */ - - /* output redirection */ -#ifdef CHECK_OPTION - if (noout_f || guess_f){ - o_putc = no_putc; - } -#endif - if (mimeout_f) { - o_mputc = o_putc; - o_putc = mime_putc; - if (mimeout_f == TRUE) { - o_base64conv = oconv; oconv = base64_conv; - } - /* base64_count = 0; */ - } - - if (eolmode_f || guess_f) { - o_eol_conv = oconv; oconv = eol_conv; - } - if (rot_f) { - o_rot_conv = oconv; oconv = rot_conv; - } - if (iso2022jp_f) { - o_iso2022jp_check_conv = oconv; oconv = iso2022jp_check_conv; - } - if (hira_f) { - o_hira_conv = oconv; oconv = hira_conv; - } - if (fold_f) { - o_fconv = oconv; oconv = fold_conv; - f_line = 0; - } - if (alpha_f || x0201_f) { - o_zconv = oconv; oconv = z_conv; - } - - i_getc = std_getc; - i_ungetc = std_ungetc; - /* input redirection */ -#ifdef INPUT_OPTION - if (cap_f){ - i_cgetc = i_getc; i_getc = cap_getc; - i_cungetc = i_ungetc; i_ungetc= cap_ungetc; - } - if (url_f){ - i_ugetc = i_getc; i_getc = url_getc; - i_uungetc = i_ungetc; i_ungetc= url_ungetc; - } -#endif -#ifdef NUMCHAR_OPTION - if (numchar_f){ - i_ngetc = i_getc; i_getc = numchar_getc; - i_nungetc = i_ungetc; i_ungetc= numchar_ungetc; - } -#endif -#ifdef UNICODE_NORMALIZATION - if (nfc_f){ - i_nfc_getc = i_getc; i_getc = nfc_getc; - i_nfc_ungetc = i_ungetc; i_ungetc= nfc_ungetc; - } -#endif - if (mime_f && mimebuf_f==FIXED_MIME) { - i_mgetc = i_getc; i_getc = mime_getc; - i_mungetc = i_ungetc; i_ungetc = mime_ungetc; - } - if (broken_f & 1) { - i_bgetc = i_getc; i_getc = broken_getc; - i_bungetc = i_ungetc; i_ungetc = broken_ungetc; - } - if (input_encoding) { - set_iconv(-TRUE, nkf_enc_to_iconv(input_encoding)); - } else { - set_iconv(FALSE, e_iconv); - } - - { - struct input_code *p = input_code_list; - while (p->name){ - status_reinit(p++); - } - } - return 0; -} - -/* - Conversion main loop. Code detection only. - */ - -#if !defined(PERL_XS) && !defined(WIN32DLL) -static nkf_char -noconvert(FILE *f) -{ - nkf_char c; - - if (nop_f == 2) - module_connection(); - while ((c = (*i_getc)(f)) != EOF) - (*o_putc)(c); - (*o_putc)(EOF); - return 1; -} -#endif - -#define NEXT continue /* no output, get next */ -#define SKIP c2=0;continue /* no output, get next */ -#define MORE c2=c1;continue /* need one more byte */ -#define SEND (void)0 /* output c1 and c2, get next */ -#define LAST break /* end of loop, go closing */ -#define set_input_mode(mode) do { \ - input_mode = mode; \ - shift_mode = 0; \ - set_input_codename("ISO-2022-JP"); \ - debug("ISO-2022-JP"); \ -} while (0) - -static int -kanji_convert(FILE *f) -{ - nkf_char c1=0, c2=0, c3=0, c4=0; - int shift_mode = 0; /* 0, 1, 2, 3 */ - int g2 = 0; - int is_8bit = FALSE; - - if (input_encoding && !nkf_enc_asciicompat(input_encoding)) { - is_8bit = TRUE; - } - - input_mode = ASCII; - output_mode = ASCII; - - if (module_connection() < 0) { -#if !defined(PERL_XS) && !defined(WIN32DLL) - fprintf(stderr, "no output encoding given\n"); -#endif - return -1; - } - check_bom(f); - -#ifdef UTF8_INPUT_ENABLE - if(iconv == w_iconv32){ - while ((c1 = (*i_getc)(f)) != EOF && - (c2 = (*i_getc)(f)) != EOF && - (c3 = (*i_getc)(f)) != EOF && - (c4 = (*i_getc)(f)) != EOF) { - nkf_char c5, c6, c7, c8; - if (nkf_iconv_utf_32(c1, c2, c3, c4) == (size_t)NKF_ICONV_WAIT_COMBINING_CHAR) { - if ((c5 = (*i_getc)(f)) != EOF && - (c6 = (*i_getc)(f)) != EOF && - (c7 = (*i_getc)(f)) != EOF && - (c8 = (*i_getc)(f)) != EOF) { - if (nkf_iconv_utf_32_combine(c1, c2, c3, c4, c5, c6, c7, c8)) { - (*i_ungetc)(c8, f); - (*i_ungetc)(c7, f); - (*i_ungetc)(c6, f); - (*i_ungetc)(c5, f); - nkf_iconv_utf_32_nocombine(c1, c2, c3, c4); - } - } else { - nkf_iconv_utf_32_nocombine(c1, c2, c3, c4); - } - } - } - goto finished; - } - else if (iconv == w_iconv16) { - while ((c1 = (*i_getc)(f)) != EOF && - (c2 = (*i_getc)(f)) != EOF) { - size_t ret = nkf_iconv_utf_16(c1, c2, 0, 0); - if (ret == NKF_ICONV_NEED_TWO_MORE_BYTES && - (c3 = (*i_getc)(f)) != EOF && - (c4 = (*i_getc)(f)) != EOF) { - nkf_iconv_utf_16(c1, c2, c3, c4); - } else if (ret == (size_t)NKF_ICONV_WAIT_COMBINING_CHAR) { - if ((c3 = (*i_getc)(f)) != EOF && - (c4 = (*i_getc)(f)) != EOF) { - if (nkf_iconv_utf_16_combine(c1, c2, c3, c4)) { - (*i_ungetc)(c4, f); - (*i_ungetc)(c3, f); - nkf_iconv_utf_16_nocombine(c1, c2); - } - } else { - nkf_iconv_utf_16_nocombine(c1, c2); - } - } - } - goto finished; - } -#endif - - while ((c1 = (*i_getc)(f)) != EOF) { -#ifdef INPUT_CODE_FIX - if (!input_encoding) -#endif - code_status(c1); - if (c2) { - /* second byte */ - if (c2 > ((input_encoding && nkf_enc_cp5022x_p(input_encoding)) ? 0x92 : DEL)) { - /* in case of 8th bit is on */ - if (!estab_f&&!mime_decode_mode) { - /* in case of not established yet */ - /* It is still ambiguous */ - if (h_conv(f, c2, c1)==EOF) { - LAST; - } - else { - SKIP; - } - } - else { - /* in case of already established */ - if (c1 < 0x40) { - /* ignore bogus code */ - SKIP; - } else { - SEND; - } - } - } - else { - /* 2nd byte of 7 bit code or SJIS */ - SEND; - } - } - else if (nkf_char_unicode_p(c1)) { - (*oconv)(0, c1); - NEXT; - } - else { - /* first byte */ - if (input_mode == JIS_X_0208 && DEL <= c1 && c1 < 0x92) { - /* CP5022x */ - MORE; - }else if (input_codename && input_codename[0] == 'I' && - 0xA1 <= c1 && c1 <= 0xDF) { - /* JIS X 0201 Katakana in 8bit JIS */ - c2 = JIS_X_0201_1976_K; - c1 &= 0x7f; - SEND; - } else if (c1 > DEL) { - /* 8 bit code */ - if (!estab_f && !iso8859_f) { - /* not established yet */ - MORE; - } else { /* estab_f==TRUE */ - if (iso8859_f) { - c2 = ISO_8859_1; - c1 &= 0x7f; - SEND; - } - else if ((iconv == s_iconv && 0xA0 <= c1 && c1 <= 0xDF) || - (ms_ucs_map_f == UCS_MAP_CP10001 && (c1 == 0xFD || c1 == 0xFE))) { - /* JIS X 0201 */ - c2 = JIS_X_0201_1976_K; - c1 &= 0x7f; - SEND; - } - else { - /* already established */ - MORE; - } - } - } else if (SP < c1 && c1 < DEL) { - /* in case of Roman characters */ - if (shift_mode) { - /* output 1 shifted byte */ - if (iso8859_f) { - c2 = ISO_8859_1; - SEND; - } else if (nkf_byte_jisx0201_katakana_p(c1)){ - /* output 1 shifted byte */ - c2 = JIS_X_0201_1976_K; - SEND; - } else { - /* look like bogus code */ - SKIP; - } - } else if (input_mode == JIS_X_0208 || input_mode == JIS_X_0212 || - input_mode == JIS_X_0213_1 || input_mode == JIS_X_0213_2) { - /* in case of Kanji shifted */ - MORE; - } else if (c1 == '=' && mime_f && !mime_decode_mode) { - /* Check MIME code */ - if ((c1 = (*i_getc)(f)) == EOF) { - (*oconv)(0, '='); - LAST; - } else if (c1 == '?') { - /* =? is mime conversion start sequence */ - if(mime_f == STRICT_MIME) { - /* check in real detail */ - if (mime_begin_strict(f) == EOF) - LAST; - SKIP; - } else if (mime_begin(f) == EOF) - LAST; - SKIP; - } else { - (*oconv)(0, '='); - (*i_ungetc)(c1,f); - SKIP; - } - } else { - /* normal ASCII code */ - SEND; - } - } else if (c1 == SI && (!is_8bit || mime_decode_mode)) { - shift_mode = 0; - SKIP; - } else if (c1 == SO && (!is_8bit || mime_decode_mode)) { - shift_mode = 1; - SKIP; - } else if (c1 == ESC && (!is_8bit || mime_decode_mode)) { - if ((c1 = (*i_getc)(f)) == EOF) { - (*oconv)(0, ESC); - LAST; - } - else if (c1 == '&') { - /* IRR */ - if ((c1 = (*i_getc)(f)) == EOF) { - LAST; - } else { - SKIP; - } - } - else if (c1 == '$') { - /* GZDMx */ - if ((c1 = (*i_getc)(f)) == EOF) { - /* don't send bogus code - (*oconv)(0, ESC); - (*oconv)(0, '$'); */ - LAST; - } else if (c1 == '@' || c1 == 'B') { - /* JIS X 0208 */ - set_input_mode(JIS_X_0208); - SKIP; - } else if (c1 == '(') { - /* GZDM4 */ - if ((c1 = (*i_getc)(f)) == EOF) { - /* don't send bogus code - (*oconv)(0, ESC); - (*oconv)(0, '$'); - (*oconv)(0, '('); - */ - LAST; - } else if (c1 == '@'|| c1 == 'B') { - /* JIS X 0208 */ - set_input_mode(JIS_X_0208); - SKIP; -#ifdef X0212_ENABLE - } else if (c1 == 'D'){ - set_input_mode(JIS_X_0212); - SKIP; -#endif /* X0212_ENABLE */ - } else if (c1 == 'O' || c1 == 'Q'){ - set_input_mode(JIS_X_0213_1); - SKIP; - } else if (c1 == 'P'){ - set_input_mode(JIS_X_0213_2); - SKIP; - } else { - /* could be some special code */ - (*oconv)(0, ESC); - (*oconv)(0, '$'); - (*oconv)(0, '('); - (*oconv)(0, c1); - SKIP; - } - } else if (broken_f&0x2) { - /* accept any ESC-(-x as broken code ... */ - input_mode = JIS_X_0208; - shift_mode = 0; - SKIP; - } else { - (*oconv)(0, ESC); - (*oconv)(0, '$'); - (*oconv)(0, c1); - SKIP; - } - } else if (c1 == '(') { - /* GZD4 */ - if ((c1 = (*i_getc)(f)) == EOF) { - /* don't send bogus code - (*oconv)(0, ESC); - (*oconv)(0, '('); */ - LAST; - } - else if (c1 == 'I') { - /* JIS X 0201 Katakana */ - set_input_mode(JIS_X_0201_1976_K); - shift_mode = 1; - SKIP; - } - else if (c1 == 'B' || c1 == 'J' || c1 == 'H') { - /* ISO-646IRV:1983 or JIS X 0201 Roman or JUNET */ - set_input_mode(ASCII); - SKIP; - } - else if (broken_f&0x2) { - set_input_mode(ASCII); - SKIP; - } - else { - (*oconv)(0, ESC); - (*oconv)(0, '('); - SEND; - } - } - else if (c1 == '.') { - /* G2D6 */ - if ((c1 = (*i_getc)(f)) == EOF) { - LAST; - } - else if (c1 == 'A') { - /* ISO-8859-1 */ - g2 = ISO_8859_1; - SKIP; - } - else { - (*oconv)(0, ESC); - (*oconv)(0, '.'); - SEND; - } - } - else if (c1 == 'N') { - /* SS2 */ - c1 = (*i_getc)(f); - if (g2 == ISO_8859_1) { - c2 = ISO_8859_1; - SEND; - }else{ - (*i_ungetc)(c1, f); - /* lonely ESC */ - (*oconv)(0, ESC); - SEND; - } - } - else { - i_ungetc(c1,f); - /* lonely ESC */ - (*oconv)(0, ESC); - SKIP; - } - } else if (c1 == ESC && iconv == s_iconv) { - /* ESC in Shift_JIS */ - if ((c1 = (*i_getc)(f)) == EOF) { - (*oconv)(0, ESC); - LAST; - } else if (c1 == '$') { - /* J-PHONE emoji */ - if ((c1 = (*i_getc)(f)) == EOF) { - LAST; - } else if (('E' <= c1 && c1 <= 'G') || - ('O' <= c1 && c1 <= 'Q')) { - /* - NUM : 0 1 2 3 4 5 - BYTE: G E F O P Q - C%7 : 1 6 0 2 3 4 - C%7 : 0 1 2 3 4 5 6 - NUM : 2 0 3 4 5 X 1 - */ - static const nkf_char jphone_emoji_first_table[7] = - {0xE1E0, 0xDFE0, 0xE2E0, 0xE3E0, 0xE4E0, 0xDFE0, 0xE0E0}; - c3 = nkf_char_unicode_new(jphone_emoji_first_table[c1 % 7]); - if ((c1 = (*i_getc)(f)) == EOF) LAST; - while (SP <= c1 && c1 <= 'z') { - (*oconv)(0, c1 + c3); - if ((c1 = (*i_getc)(f)) == EOF) LAST; - } - SKIP; - } - else { - (*oconv)(0, ESC); - (*oconv)(0, '$'); - SEND; - } - } - else { - i_ungetc(c1,f); - /* lonely ESC */ - (*oconv)(0, ESC); - SKIP; - } - } else if (c1 == LF || c1 == CR) { - if (broken_f&4) { - input_mode = ASCII; set_iconv(FALSE, 0); - SEND; - } else if (mime_decode_f && !mime_decode_mode){ - if (c1 == LF) { - if ((c1=(*i_getc)(f))!=EOF && c1 == SP) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - c1 = LF; - SEND; - } else { /* if (c1 == CR)*/ - if ((c1=(*i_getc)(f))!=EOF) { - if (c1==SP) { - i_ungetc(SP,f); - continue; - } else if (c1 == LF && (c1=(*i_getc)(f))!=EOF && c1 == SP) { - i_ungetc(SP,f); - continue; - } else { - i_ungetc(c1,f); - } - i_ungetc(LF,f); - } else { - i_ungetc(c1,f); - } - c1 = CR; - SEND; - } - } - } else - SEND; - } - /* send: */ - switch(input_mode){ - case ASCII: - switch ((*iconv)(c2, c1, 0)) { /* can be EUC / SJIS / UTF-8 */ - case -2: - /* 4 bytes UTF-8 */ - if ((c3 = (*i_getc)(f)) != EOF) { - code_status(c3); - c3 <<= 8; - if ((c4 = (*i_getc)(f)) != EOF) { - code_status(c4); - (*iconv)(c2, c1, c3|c4); - } - } - break; - case -3: - /* 4 bytes UTF-8 (check combining character) */ - if ((c3 = (*i_getc)(f)) != EOF) { - if ((c4 = (*i_getc)(f)) != EOF) { - if (w_iconv_combine(c2, c1, 0, c3, c4, 0)) { - (*i_ungetc)(c4, f); - (*i_ungetc)(c3, f); - w_iconv_nocombine(c2, c1, 0); - } - } else { - (*i_ungetc)(c3, f); - w_iconv_nocombine(c2, c1, 0); - } - } else { - w_iconv_nocombine(c2, c1, 0); - } - break; - case -1: - /* 3 bytes EUC or UTF-8 */ - if ((c3 = (*i_getc)(f)) != EOF) { - code_status(c3); - if ((*iconv)(c2, c1, c3) == -3) { - /* 6 bytes UTF-8 (check combining character) */ - nkf_char c5, c6; - if ((c4 = (*i_getc)(f)) != EOF) { - if ((c5 = (*i_getc)(f)) != EOF) { - if ((c6 = (*i_getc)(f)) != EOF) { - if (w_iconv_combine(c2, c1, c3, c4, c5, c6)) { - (*i_ungetc)(c6, f); - (*i_ungetc)(c5, f); - (*i_ungetc)(c4, f); - w_iconv_nocombine(c2, c1, c3); - } - } else { - (*i_ungetc)(c5, f); - (*i_ungetc)(c4, f); - w_iconv_nocombine(c2, c1, c3); - } - } else { - (*i_ungetc)(c4, f); - w_iconv_nocombine(c2, c1, c3); - } - } else { - w_iconv_nocombine(c2, c1, c3); - } - } - } - break; - } - break; - case JIS_X_0208: - case JIS_X_0213_1: - if (ms_ucs_map_f && - 0x7F <= c2 && c2 <= 0x92 && - 0x21 <= c1 && c1 <= 0x7E) { - /* CP932 UDC */ - c1 = nkf_char_unicode_new((c2 - 0x7F) * 94 + c1 - 0x21 + 0xE000); - c2 = 0; - } - (*oconv)(c2, c1); /* this is JIS, not SJIS/EUC case */ - break; -#ifdef X0212_ENABLE - case JIS_X_0212: - (*oconv)(PREFIX_EUCG3 | c2, c1); - break; -#endif /* X0212_ENABLE */ - case JIS_X_0213_2: - (*oconv)(PREFIX_EUCG3 | c2, c1); - break; - default: - (*oconv)(input_mode, c1); /* other special case */ - } - - c2 = 0; - c3 = 0; - continue; - /* goto next_word */ - } - -finished: - /* epilogue */ - (*iconv)(EOF, 0, 0); - if (!input_codename) - { - if (is_8bit) { - struct input_code *p = input_code_list; - struct input_code *result = p; - while (p->name){ - if (p->score < result->score) result = p; - ++p; - } - set_input_codename(result->name); -#ifdef CHECK_OPTION - debug(result->name); -#endif - } - } - return 0; -} - -/* - * int options(unsigned char *cp) - * - * return values: - * 0: success - * -1: ArgumentError - */ -static int -options(unsigned char *cp) -{ - nkf_char i, j; - unsigned char *p; - unsigned char *cp_back = NULL; - nkf_encoding *enc; - - if (option_mode==1) - return 0; - while(*cp && *cp++!='-'); - while (*cp || cp_back) { - if(!*cp){ - cp = cp_back; - cp_back = NULL; - continue; - } - p = 0; - switch (*cp++) { - case '-': /* literal options */ - if (!*cp || *cp == SP) { /* ignore the rest of arguments */ - option_mode = 1; - return 0; - } - for (i=0;i<(int)(sizeof(long_option)/sizeof(long_option[0]));i++) { - p = (unsigned char *)long_option[i].name; - for (j=0;*p && *p != '=' && *p == cp[j];p++, j++); - if (*p == cp[j] || cp[j] == SP){ - p = &cp[j] + 1; - break; - } - p = 0; - } - if (p == 0) { -#if !defined(PERL_XS) && !defined(WIN32DLL) - fprintf(stderr, "unknown long option: --%s\n", cp); -#endif - return -1; - } - while(*cp && *cp != SP && cp++); - if (long_option[i].alias[0]){ - cp_back = cp; - cp = (unsigned char *)long_option[i].alias; - }else{ -#ifndef PERL_XS - if (strcmp(long_option[i].name, "help") == 0){ - usage(); - exit(EXIT_SUCCESS); - } -#endif - if (strcmp(long_option[i].name, "ic=") == 0){ - enc = nkf_enc_find((char *)p); - if (!enc) continue; - input_encoding = enc; - continue; - } - if (strcmp(long_option[i].name, "oc=") == 0){ - enc = nkf_enc_find((char *)p); - /* if (enc <= 0) continue; */ - if (!enc) continue; - output_encoding = enc; - continue; - } - if (strcmp(long_option[i].name, "guess=") == 0){ - if (p[0] == '0' || p[0] == '1') { - guess_f = 1; - } else { - guess_f = 2; - } - continue; - } -#ifdef OVERWRITE - if (strcmp(long_option[i].name, "overwrite") == 0){ - file_out_f = TRUE; - overwrite_f = TRUE; - preserve_time_f = TRUE; - continue; - } - if (strcmp(long_option[i].name, "overwrite=") == 0){ - file_out_f = TRUE; - overwrite_f = TRUE; - preserve_time_f = TRUE; - backup_f = TRUE; - backup_suffix = (char *)p; - continue; - } - if (strcmp(long_option[i].name, "in-place") == 0){ - file_out_f = TRUE; - overwrite_f = TRUE; - preserve_time_f = FALSE; - continue; - } - if (strcmp(long_option[i].name, "in-place=") == 0){ - file_out_f = TRUE; - overwrite_f = TRUE; - preserve_time_f = FALSE; - backup_f = TRUE; - backup_suffix = (char *)p; - continue; - } -#endif -#ifdef INPUT_OPTION - if (strcmp(long_option[i].name, "cap-input") == 0){ - cap_f = TRUE; - continue; - } - if (strcmp(long_option[i].name, "url-input") == 0){ - url_f = TRUE; - continue; - } -#endif -#ifdef NUMCHAR_OPTION - if (strcmp(long_option[i].name, "numchar-input") == 0){ - numchar_f = TRUE; - continue; - } -#endif -#ifdef CHECK_OPTION - if (strcmp(long_option[i].name, "no-output") == 0){ - noout_f = TRUE; - continue; - } - if (strcmp(long_option[i].name, "debug") == 0){ - debug_f = TRUE; - continue; - } -#endif - if (strcmp(long_option[i].name, "cp932") == 0){ -#ifdef SHIFTJIS_CP932 - cp51932_f = TRUE; - cp932inv_f = -TRUE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_CP932; -#endif - continue; - } - if (strcmp(long_option[i].name, "no-cp932") == 0){ -#ifdef SHIFTJIS_CP932 - cp51932_f = FALSE; - cp932inv_f = FALSE; -#endif -#ifdef UTF8_OUTPUT_ENABLE - ms_ucs_map_f = UCS_MAP_ASCII; -#endif - continue; - } -#ifdef SHIFTJIS_CP932 - if (strcmp(long_option[i].name, "cp932inv") == 0){ - cp932inv_f = -TRUE; - continue; - } -#endif - -#ifdef X0212_ENABLE - if (strcmp(long_option[i].name, "x0212") == 0){ - x0212_f = TRUE; - continue; - } -#endif - -#ifdef EXEC_IO - if (strcmp(long_option[i].name, "exec-in") == 0){ - exec_f = 1; - return 0; - } - if (strcmp(long_option[i].name, "exec-out") == 0){ - exec_f = -1; - return 0; - } -#endif -#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE) - if (strcmp(long_option[i].name, "no-cp932ext") == 0){ - no_cp932ext_f = TRUE; - continue; - } - if (strcmp(long_option[i].name, "no-best-fit-chars") == 0){ - no_best_fit_chars_f = TRUE; - continue; - } - if (strcmp(long_option[i].name, "fb-skip") == 0){ - encode_fallback = NULL; - continue; - } - if (strcmp(long_option[i].name, "fb-html") == 0){ - encode_fallback = encode_fallback_html; - continue; - } - if (strcmp(long_option[i].name, "fb-xml") == 0){ - encode_fallback = encode_fallback_xml; - continue; - } - if (strcmp(long_option[i].name, "fb-java") == 0){ - encode_fallback = encode_fallback_java; - continue; - } - if (strcmp(long_option[i].name, "fb-perl") == 0){ - encode_fallback = encode_fallback_perl; - continue; - } - if (strcmp(long_option[i].name, "fb-subchar") == 0){ - encode_fallback = encode_fallback_subchar; - continue; - } - if (strcmp(long_option[i].name, "fb-subchar=") == 0){ - encode_fallback = encode_fallback_subchar; - unicode_subchar = 0; - if (p[0] != '0'){ - /* decimal number */ - for (i = 0; i < 7 && nkf_isdigit(p[i]); i++){ - unicode_subchar *= 10; - unicode_subchar += hex2bin(p[i]); - } - }else if(p[1] == 'x' || p[1] == 'X'){ - /* hexadecimal number */ - for (i = 2; i < 8 && nkf_isxdigit(p[i]); i++){ - unicode_subchar <<= 4; - unicode_subchar |= hex2bin(p[i]); - } - }else{ - /* octal number */ - for (i = 1; i < 8 && nkf_isoctal(p[i]); i++){ - unicode_subchar *= 8; - unicode_subchar += hex2bin(p[i]); - } - } - w16e_conv(unicode_subchar, &i, &j); - unicode_subchar = i<<8 | j; - continue; - } -#endif -#ifdef UTF8_OUTPUT_ENABLE - if (strcmp(long_option[i].name, "ms-ucs-map") == 0){ - ms_ucs_map_f = UCS_MAP_MS; - continue; - } -#endif -#ifdef UNICODE_NORMALIZATION - if (strcmp(long_option[i].name, "utf8mac-input") == 0){ - nfc_f = TRUE; - continue; - } -#endif - if (strcmp(long_option[i].name, "prefix=") == 0){ - if (nkf_isgraph(p[0])){ - for (i = 1; nkf_isgraph(p[i]); i++){ - prefix_table[p[i]] = p[0]; - } - } - continue; - } -#if !defined(PERL_XS) && !defined(WIN32DLL) - fprintf(stderr, "unsupported long option: --%s\n", long_option[i].name); -#endif - return -1; - } - continue; - case 'b': /* buffered mode */ - unbuf_f = FALSE; - continue; - case 'u': /* non bufferd mode */ - unbuf_f = TRUE; - continue; - case 't': /* transparent mode */ - if (*cp=='1') { - /* alias of -t */ - cp++; - nop_f = TRUE; - } else if (*cp=='2') { - /* - * -t with put/get - * - * nkf -t2MB hoge.bin | nkf -t2mB | diff -s - hoge.bin - * - */ - cp++; - nop_f = 2; - } else - nop_f = TRUE; - continue; - case 'j': /* JIS output */ - case 'n': - output_encoding = nkf_enc_from_index(ISO_2022_JP); - continue; - case 'e': /* AT&T EUC output */ - output_encoding = nkf_enc_from_index(EUCJP_NKF); - continue; - case 's': /* SJIS output */ - output_encoding = nkf_enc_from_index(SHIFT_JIS); - continue; - case 'l': /* ISO8859 Latin-1 support, no conversion */ - iso8859_f = TRUE; /* Only compatible with ISO-2022-JP */ - input_encoding = nkf_enc_from_index(ISO_8859_1); - continue; - case 'i': /* Kanji IN ESC-$-@/B */ - if (*cp=='@'||*cp=='B') - kanji_intro = *cp++; - continue; - case 'o': /* ASCII IN ESC-(-J/B/H */ - /* ESC ( H was used in initial JUNET messages */ - if (*cp=='J'||*cp=='B'||*cp=='H') - ascii_intro = *cp++; - continue; - case 'h': - /* - bit:1 katakana->hiragana - bit:2 hiragana->katakana - */ - if ('9'>= *cp && *cp>='0') - hira_f |= (*cp++ -'0'); - else - hira_f |= 1; - continue; - case 'r': - rot_f = TRUE; - continue; -#if defined(MSDOS) || defined(__OS2__) - case 'T': - binmode_f = FALSE; - continue; -#endif -#ifndef PERL_XS - case 'V': - show_configuration(); - exit(EXIT_SUCCESS); - break; - case 'v': - version(); - exit(EXIT_SUCCESS); - break; -#endif -#ifdef UTF8_OUTPUT_ENABLE - case 'w': /* UTF-{8,16,32} output */ - if (cp[0] == '8') { - cp++; - if (cp[0] == '0'){ - cp++; - output_encoding = nkf_enc_from_index(UTF_8N); - } else { - output_bom_f = TRUE; - output_encoding = nkf_enc_from_index(UTF_8_BOM); - } - } else { - int enc_idx; - if ('1'== cp[0] && '6'==cp[1]) { - cp += 2; - enc_idx = UTF_16; - } else if ('3'== cp[0] && '2'==cp[1]) { - cp += 2; - enc_idx = UTF_32; - } else { - output_encoding = nkf_enc_from_index(UTF_8); - continue; - } - if (cp[0]=='L') { - cp++; - output_endian = ENDIAN_LITTLE; - output_bom_f = TRUE; - } else if (cp[0] == 'B') { - cp++; - output_bom_f = TRUE; - } - if (cp[0] == '0'){ - output_bom_f = FALSE; - cp++; - enc_idx = enc_idx == UTF_16 - ? (output_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE) - : (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE); - } else { - enc_idx = enc_idx == UTF_16 - ? (output_endian == ENDIAN_LITTLE ? UTF_16LE_BOM : UTF_16BE_BOM) - : (output_endian == ENDIAN_LITTLE ? UTF_32LE_BOM : UTF_32BE_BOM); - } - output_encoding = nkf_enc_from_index(enc_idx); - } - continue; -#endif -#ifdef UTF8_INPUT_ENABLE - case 'W': /* UTF input */ - if (cp[0] == '8') { - cp++; - input_encoding = nkf_enc_from_index(UTF_8); - }else{ - int enc_idx; - if ('1'== cp[0] && '6'==cp[1]) { - cp += 2; - input_endian = ENDIAN_BIG; - enc_idx = UTF_16; - } else if ('3'== cp[0] && '2'==cp[1]) { - cp += 2; - input_endian = ENDIAN_BIG; - enc_idx = UTF_32; - } else { - input_encoding = nkf_enc_from_index(UTF_8); - continue; - } - if (cp[0]=='L') { - cp++; - input_endian = ENDIAN_LITTLE; - } else if (cp[0] == 'B') { - cp++; - input_endian = ENDIAN_BIG; - } - enc_idx = (enc_idx == UTF_16 - ? (input_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE) - : (input_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE)); - input_encoding = nkf_enc_from_index(enc_idx); - } - continue; -#endif - /* Input code assumption */ - case 'J': /* ISO-2022-JP input */ - input_encoding = nkf_enc_from_index(ISO_2022_JP); - continue; - case 'E': /* EUC-JP input */ - input_encoding = nkf_enc_from_index(EUCJP_NKF); - continue; - case 'S': /* Shift_JIS input */ - input_encoding = nkf_enc_from_index(SHIFT_JIS); - continue; - case 'Z': /* Convert X0208 alphabet to ascii */ - /* alpha_f - bit:0 Convert JIS X 0208 Alphabet to ASCII - bit:1 Convert Kankaku to one space - bit:2 Convert Kankaku to two spaces - bit:3 Convert HTML Entity - bit:4 Convert JIS X 0208 Katakana to JIS X 0201 Katakana - */ - while ('0'<= *cp && *cp <='4') { - alpha_f |= 1 << (*cp++ - '0'); - } - alpha_f |= 1; - continue; - case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */ - x0201_f = FALSE; /* No X0201->X0208 conversion */ - /* accept X0201 - ESC-(-I in JIS, EUC, MS Kanji - SI/SO in JIS, EUC, MS Kanji - SS2 in EUC, JIS, not in MS Kanji - MS Kanji (0xa0-0xdf) - output X0201 - ESC-(-I in JIS (0x20-0x5f) - SS2 in EUC (0xa0-0xdf) - 0xa0-0xd in MS Kanji (0xa0-0xdf) - */ - continue; - case 'X': /* Convert X0201 kana to X0208 */ - x0201_f = TRUE; - continue; - case 'F': /* prserve new lines */ - fold_preserve_f = TRUE; - case 'f': /* folding -f60 or -f */ - fold_f = TRUE; - fold_len = 0; - while('0'<= *cp && *cp <='9') { /* we don't use atoi here */ - fold_len *= 10; - fold_len += *cp++ - '0'; - } - if (!(0<fold_len && fold_len<BUFSIZ)) - fold_len = DEFAULT_FOLD; - if (*cp=='-') { - fold_margin = 0; - cp++; - while('0'<= *cp && *cp <='9') { /* we don't use atoi here */ - fold_margin *= 10; - fold_margin += *cp++ - '0'; - } - } - continue; - case 'm': /* MIME support */ - /* mime_decode_f = TRUE; */ /* this has too large side effects... */ - if (*cp=='B'||*cp=='Q') { - mime_decode_mode = *cp++; - mimebuf_f = FIXED_MIME; - } else if (*cp=='N') { - mime_f = TRUE; cp++; - } else if (*cp=='S') { - mime_f = STRICT_MIME; cp++; - } else if (*cp=='0') { - mime_decode_f = FALSE; - mime_f = FALSE; cp++; - } else { - mime_f = STRICT_MIME; - } - continue; - case 'M': /* MIME output */ - if (*cp=='B') { - mimeout_mode = 'B'; - mimeout_f = FIXED_MIME; cp++; - } else if (*cp=='Q') { - mimeout_mode = 'Q'; - mimeout_f = FIXED_MIME; cp++; - } else { - mimeout_f = TRUE; - } - continue; - case 'B': /* Broken JIS support */ - /* bit:0 no ESC JIS - bit:1 allow any x on ESC-(-x or ESC-$-x - bit:2 reset to ascii on NL - */ - if ('9'>= *cp && *cp>='0') - broken_f |= 1<<(*cp++ -'0'); - else - broken_f |= TRUE; - continue; -#ifndef PERL_XS - case 'O':/* for Output file */ - file_out_f = TRUE; - continue; -#endif - case 'c':/* add cr code */ - eolmode_f = CRLF; - continue; - case 'd':/* delete cr code */ - eolmode_f = LF; - continue; - case 'I': /* ISO-2022-JP output */ - iso2022jp_f = TRUE; - continue; - case 'L': /* line mode */ - if (*cp=='u') { /* unix */ - eolmode_f = LF; cp++; - } else if (*cp=='m') { /* mac */ - eolmode_f = CR; cp++; - } else if (*cp=='w') { /* windows */ - eolmode_f = CRLF; cp++; - } else if (*cp=='0') { /* no conversion */ - eolmode_f = 0; cp++; - } - continue; -#ifndef PERL_XS - case 'g': - if ('2' <= *cp && *cp <= '9') { - guess_f = 2; - cp++; - } else if (*cp == '0' || *cp == '1') { - guess_f = 1; - cp++; - } else { - guess_f = 1; - } - continue; -#endif - case SP: - /* module multiple options in a string are allowed for Perl module */ - while(*cp && *cp++!='-'); - continue; - default: -#if !defined(PERL_XS) && !defined(WIN32DLL) - fprintf(stderr, "unknown option: -%c\n", *(cp-1)); -#endif - /* bogus option but ignored */ - return -1; - } - } - return 0; -} - -#ifdef WIN32DLL -#include "nkf32dll.c" -#elif defined(PERL_XS) -#else /* WIN32DLL */ -int -main(int argc, char **argv) -{ - FILE *fin; - unsigned char *cp; - - char *outfname = NULL; - char *origfname; - -#ifdef EASYWIN /*Easy Win */ - _BufferSize.y = 400;/*Set Scroll Buffer Size*/ -#endif -#ifdef DEFAULT_CODE_LOCALE - setlocale(LC_CTYPE, ""); -#endif - nkf_state_init(); - - for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) { - cp = (unsigned char *)*argv; - options(cp); -#ifdef EXEC_IO - if (exec_f){ - int fds[2], pid; - if (pipe(fds) < 0 || (pid = fork()) < 0){ - abort(); - } - if (pid == 0){ - if (exec_f > 0){ - close(fds[0]); - dup2(fds[1], 1); - }else{ - close(fds[1]); - dup2(fds[0], 0); - } - execvp(argv[1], &argv[1]); - } - if (exec_f > 0){ - close(fds[1]); - dup2(fds[0], 0); - }else{ - close(fds[0]); - dup2(fds[1], 1); - } - argc = 0; - break; - } -#endif - } - - if (guess_f) { -#ifdef CHECK_OPTION - int debug_f_back = debug_f; -#endif -#ifdef EXEC_IO - int exec_f_back = exec_f; -#endif -#ifdef X0212_ENABLE - int x0212_f_back = x0212_f; -#endif - int x0213_f_back = x0213_f; - int guess_f_back = guess_f; - reinit(); - guess_f = guess_f_back; - mime_f = FALSE; -#ifdef CHECK_OPTION - debug_f = debug_f_back; -#endif -#ifdef EXEC_IO - exec_f = exec_f_back; -#endif - x0212_f = x0212_f_back; - x0213_f = x0213_f_back; - } - - if (binmode_f == TRUE) -#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__)) - if (freopen("","wb",stdout) == NULL) - return (-1); -#else - setbinmode(stdout); -#endif - - if (unbuf_f) - setbuf(stdout, (char *) NULL); - else - setvbuffer(stdout, (char *) stdobuf, IOBUF_SIZE); - - if (argc == 0) { - if (binmode_f == TRUE) -#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__)) - if (freopen("","rb",stdin) == NULL) return (-1); -#else - setbinmode(stdin); -#endif - setvbuffer(stdin, (char *) stdibuf, IOBUF_SIZE); - if (nop_f) - noconvert(stdin); - else { - kanji_convert(stdin); - if (guess_f) print_guessed_code(NULL); - } - } else { - int nfiles = argc; - int is_argument_error = FALSE; - while (argc--) { - input_codename = NULL; - input_eol = 0; -#ifdef CHECK_OPTION - iconv_for_check = 0; -#endif - if ((fin = fopen((origfname = *argv++), "r")) == NULL) { - perror(*(argv-1)); - is_argument_error = TRUE; - continue; - } else { -#ifdef OVERWRITE - int fd = 0; - int fd_backup = 0; -#endif - - /* reopen file for stdout */ - if (file_out_f == TRUE) { -#ifdef OVERWRITE - if (overwrite_f){ - outfname = nkf_xmalloc(strlen(origfname) - + strlen(".nkftmpXXXXXX") - + 1); - strcpy(outfname, origfname); -#ifdef MSDOS - { - int i; - for (i = strlen(outfname); i; --i){ - if (outfname[i - 1] == '/' - || outfname[i - 1] == '\\'){ - break; - } - } - outfname[i] = '\0'; - } - strcat(outfname, "ntXXXXXX"); - mktemp(outfname); - fd = open(outfname, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, - S_IREAD | S_IWRITE); -#else - strcat(outfname, ".nkftmpXXXXXX"); - fd = mkstemp(outfname); -#endif - if (fd < 0 - || (fd_backup = dup(fileno(stdout))) < 0 - || dup2(fd, fileno(stdout)) < 0 - ){ - perror(origfname); - return -1; - } - }else -#endif - if(argc == 1) { - outfname = *argv++; - argc--; - } else { - outfname = "nkf.out"; - } - - if(freopen(outfname, "w", stdout) == NULL) { - perror (outfname); - return (-1); - } - if (binmode_f == TRUE) { -#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__)) - if (freopen("","wb",stdout) == NULL) - return (-1); -#else - setbinmode(stdout); -#endif - } - } - if (binmode_f == TRUE) -#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__)) - if (freopen("","rb",fin) == NULL) - return (-1); -#else - setbinmode(fin); -#endif - setvbuffer(fin, (char *) stdibuf, IOBUF_SIZE); - if (nop_f) - noconvert(fin); - else { - char *filename = NULL; - kanji_convert(fin); - if (nfiles > 1) filename = origfname; - if (guess_f) print_guessed_code(filename); - } - fclose(fin); -#ifdef OVERWRITE - if (overwrite_f) { - struct stat sb; -#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__) - time_t tb[2]; -#else - struct utimbuf tb; -#endif - - fflush(stdout); - close(fd); - if (dup2(fd_backup, fileno(stdout)) < 0){ - perror("dup2"); - } - if (stat(origfname, &sb)) { - fprintf(stderr, "Can't stat %s\n", origfname); - } - /* $B%Q!<%_%C%7%g%s$rI|85(B */ - if (chmod(outfname, sb.st_mode)) { - fprintf(stderr, "Can't set permission %s\n", outfname); - } - - /* $B%?%$%`%9%?%s%W$rI|85(B */ - if(preserve_time_f){ -#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__) - tb[0] = tb[1] = sb.st_mtime; - if (utime(outfname, tb)) { - fprintf(stderr, "Can't set timestamp %s\n", outfname); - } -#else - tb.actime = sb.st_atime; - tb.modtime = sb.st_mtime; - if (utime(outfname, &tb)) { - fprintf(stderr, "Can't set timestamp %s\n", outfname); - } -#endif - } - if(backup_f){ - char *backup_filename = get_backup_filename(backup_suffix, origfname); -#ifdef MSDOS - unlink(backup_filename); -#endif - if (rename(origfname, backup_filename)) { - perror(backup_filename); - fprintf(stderr, "Can't rename %s to %s\n", - origfname, backup_filename); - } - nkf_xfree(backup_filename); - }else{ -#ifdef MSDOS - if (unlink(origfname)){ - perror(origfname); - } -#endif - } - if (rename(outfname, origfname)) { - perror(origfname); - fprintf(stderr, "Can't rename %s to %s\n", - outfname, origfname); - } - nkf_xfree(outfname); - } -#endif - } - } - if (is_argument_error) - return(-1); - } -#ifdef EASYWIN /*Easy Win */ - if (file_out_f == FALSE) - scanf("%d",&end_check); - else - fclose(stdout); -#else /* for Other OS */ - if (file_out_f == TRUE) - fclose(stdout); -#endif /*Easy Win */ - return (0); -} -#endif /* WIN32DLL */ diff --git a/ext/nkf/nkf-utf8/nkf.h b/ext/nkf/nkf-utf8/nkf.h deleted file mode 100644 index b3a520da54..0000000000 --- a/ext/nkf/nkf-utf8/nkf.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * - * nkf.h - Header file for nkf - * - */ - -#ifndef NKF_H -#define NKF_H - -/* Wrapper of configurations */ - -#ifndef MIME_DECODE_DEFAULT -#define MIME_DECODE_DEFAULT STRICT_MIME -#endif -#ifndef X0201_DEFAULT -#define X0201_DEFAULT TRUE -#endif - -#if defined(DEFAULT_NEWLINE) && DEFAULT_NEWLINE == 0x0D0A -#elif defined(DEFAULT_NEWLINE) && DEFAULT_NEWLINE == 0x0D -#else -#define DEFAULT_NEWLINE 0x0A -#endif -#ifdef HELP_OUTPUT_STDERR -#define HELP_OUTPUT stderr -#else -#define HELP_OUTPUT stdout -#endif - - -/* Compatibility definitions */ - -#ifdef nkf_char -#elif defined(INT_IS_SHORT) -typedef long nkf_char; -#define NKF_INT32_C(n) (n##L) -#else -typedef int nkf_char; -#define NKF_INT32_C(n) (n) -#endif - -#if (defined(__TURBOC__) || defined(_MSC_VER) || defined(LSI_C) || (defined(__WATCOMC__) && defined(__386__) && !defined(__LINUX__)) || defined(__MINGW32__) || defined(__EMX__) || defined(__MSDOS__) || defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)) && !defined(MSDOS) -#define MSDOS -#if (defined(__Win32__) || defined(_WIN32)) && !defined(__WIN32__) -#define __WIN32__ -#endif -#endif - -#ifdef PERL_XS -#undef OVERWRITE -#endif - -#ifndef PERL_XS -#include <stdio.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#if defined(MSDOS) || defined(__OS2__) -#include <fcntl.h> -#include <io.h> -#if defined(_MSC_VER) || defined(__WATCOMC__) -#define mktemp _mktemp -#endif -#endif - -#ifdef MSDOS -#ifdef LSI_C -#define setbinmode(fp) fsetbin(fp) -#elif defined(__DJGPP__) -#include <libc/dosio.h> -void setbinmode(FILE *fp) -{ - /* we do not use libc's setmode(), which changes COOKED/RAW mode in device. */ - int fd, m; - fd = fileno(fp); - m = (__file_handle_modes[fd] & (~O_TEXT)) | O_BINARY; - __file_handle_set(fd, m); -} -#else /* Microsoft C, Turbo C */ -#define setbinmode(fp) setmode(fileno(fp), O_BINARY) -#endif -#else /* UNIX */ -#define setbinmode(fp) (void)(fp) -#endif - -#ifdef _IOFBF /* SysV and MSDOS, Windows */ -#define setvbuffer(fp, buf, size) setvbuf(fp, buf, _IOFBF, size) -#else /* BSD */ -#define setvbuffer(fp, buf, size) setbuffer(fp, buf, size) -#endif - -/*Borland C++ 4.5 EasyWin*/ -#if defined(__TURBOC__) && defined(_Windows) && !defined(__WIN32__) /*Easy Win */ -#define EASYWIN -#ifndef __WIN16__ -#define __WIN16__ -#endif -#include <windows.h> -#endif - -#ifdef OVERWRITE -/* added by satoru@isoternet.org */ -#if defined(__EMX__) -#include <sys/types.h> -#endif -#include <sys/stat.h> -#if !defined(MSDOS) || defined(__DJGPP__) /* UNIX, djgpp */ -#include <unistd.h> -#if defined(__WATCOMC__) -#include <sys/utime.h> -#else -#include <utime.h> -#endif -#else /* defined(MSDOS) */ -#ifdef __WIN32__ -#ifdef __BORLANDC__ /* BCC32 */ -#include <utime.h> -#else /* !defined(__BORLANDC__) */ -#include <sys/utime.h> -#endif /* (__BORLANDC__) */ -#else /* !defined(__WIN32__) */ -#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__) || defined(__OS2__) || defined(__EMX__) || defined(__IBMC__) || defined(__IBMCPP__) /* VC++, MinGW, Watcom, emx+gcc, IBM VAC++ */ -#include <sys/utime.h> -#elif defined(__TURBOC__) /* BCC */ -#include <utime.h> -#elif defined(LSI_C) /* LSI C */ -#endif /* (__WIN32__) */ -#endif -#endif -#endif - -#if !defined(DEFAULT_CODE_JIS) && !defined(DEFAULT_CODE_SJIS) && \ - !defined(DEFAULT_CODE_WINDOWS_31J) && !defined(DEFAULT_CODE_EUC) && \ - !defined(DEFAULT_CODE_UTF8) && !defined(DEFAULT_CODE_LOCALE) -#define DEFAULT_CODE_LOCALE -#endif - -#ifdef DEFAULT_CODE_LOCALE - -#if defined(__WIN32__) /* not win32 should be posix */ -# ifndef HAVE_LOCALE_H -# define HAVE_LOCALE_H -# endif -#elif defined(__OS2__) -# undef HAVE_LANGINFO_H /* We do not use kLIBC's langinfo. */ -# ifndef HAVE_LOCALE_H -# define HAVE_LOCALE_H -# endif -#elif defined(MSDOS) -# ifndef HAVE_LOCALE_H -# define HAVE_LOCALE_H -# endif -#elif defined(__BIONIC__) /* bionic doesn't have locale */ -#else -# ifndef HAVE_LANGINFO_H -# define HAVE_LANGINFO_H -# endif -# ifndef HAVE_LOCALE_H -# define HAVE_LOCALE_H -# endif -#endif - -#ifdef HAVE_LANGINFO_H -#include <langinfo.h> -#endif -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#endif /* DEFAULT_CODE_LOCALE */ - -#define FALSE 0 -#define TRUE 1 - -#ifndef ARG_UNUSED -#if defined(__GNUC__) -# define ARG_UNUSED __attribute__ ((unused)) -#else -# define ARG_UNUSED -#endif -#endif - -#ifdef WIN32DLL -#include "nkf32.h" -#endif - -#endif /* NKF_H */ diff --git a/ext/nkf/nkf-utf8/utf8tbl.c b/ext/nkf/nkf-utf8/utf8tbl.c deleted file mode 100644 index a31e4e7805..0000000000 --- a/ext/nkf/nkf-utf8/utf8tbl.c +++ /dev/null @@ -1,14638 +0,0 @@ -/* - * utf8tbl.c - Conversion Table for nkf - * - */ - -#include "config.h" -#include "utf8tbl.h" - -#ifdef UTF8_OUTPUT_ENABLE -static const unsigned short euc_to_utf8_A1[] = { - 0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, - 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, - 0xFF3E, 0x203E, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, - 0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2014, 0x2010, 0xFF0F, - 0xFF3C, 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, - 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, - 0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, - 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, 0x00D7, - 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, - 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0x00A5, - 0xFF04, 0x00A2, 0x00A3, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, - 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7, -}; - -/* Microsoft UCS Mapping Compatible */ -static const unsigned short euc_to_utf8_A1_ms[] = { - 0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, - 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, - 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, - 0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, - 0xFF3C, 0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, - 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, - 0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, - 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, - 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, - 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, - 0xFF04, 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, - 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7, -}; -static const unsigned short euc_to_utf8_A2[] = { - 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, - 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, - 0x222A, 0x2229, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2227, 0x2228, 0x00AC, 0x21D2, 0x21D4, 0x2200, - 0x2203, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2220, 0x22A5, 0x2312, 0x2202, - 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, - 0x2235, 0x222B, 0x222C, 0, 0, 0, 0, 0, - 0, 0, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, - 0x2021, 0x00B6, 0, 0, 0, 0, 0x25EF, -}; - -/* Microsoft UCS Mapping Compatible */ -static const unsigned short euc_to_utf8_A2_ms[] = { - 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, - 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, - 0x222A, 0x2229, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200, - 0x2203, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2220, 0x22A5, 0x2312, 0x2202, - 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, - 0x2235, 0x222B, 0x222C, 0, 0, 0, 0, 0, - 0, 0, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, - 0x2021, 0x00B6, 0, 0, 0, 0, 0x25EF, -}; -static const unsigned short euc_to_utf8_A2_x0213[] = { - 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, - 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0xFF07, - 0xFF02, 0xFF0D, 0xFF5E, 0x3033, 0x3034, 0x3035, 0x303B, 0x303C, - 0x30FF, 0x309F, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, - 0x222A, 0x2229, 0x2284, 0x2285, 0x228A, 0x228B, 0x2209, 0x2205, - 0x2305, 0x2306, 0x2227, 0x2228, 0x00AC, 0x21D2, 0x21D4, 0x2200, - 0x2203, 0x2295, 0x2296, 0x2297, 0x2225, 0x2226, 0xFF5F, 0xFF60, - 0x3018, 0x3019, 0x3016, 0x3017, 0x2220, 0x22A5, 0x2312, 0x2202, - 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, - 0x2235, 0x222B, 0x222C, 0x2262, 0x2243, 0x2245, 0x2248, 0x2276, - 0x2277, 0x2194, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, - 0x2021, 0x00B6, 0x266E, 0x266B, 0x266C, 0x2669, 0x25EF, -}; -static const unsigned short euc_to_utf8_A3[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, - 0xFF18, 0xFF19, 0, 0, 0, 0, 0, 0, - 0, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, - 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, - 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, - 0xFF38, 0xFF39, 0xFF3A, 0, 0, 0, 0, 0, - 0, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, - 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, - 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, - 0xFF58, 0xFF59, 0xFF5A, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A3_x0213[] = { - 0x25B7, 0x25B6, 0x25C1, 0x25C0, 0x2197, 0x2198, 0x2196, - 0x2199, 0x21C4, 0x21E8, 0x21E6, 0x21E7, 0x21E9, 0x2934, 0x2935, - 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, - 0xFF18, 0xFF19, 0x29BF, 0x25C9, 0x303D, 0xFE46, 0xFE45, 0x25E6, - 0x2022, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, - 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, - 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, - 0xFF38, 0xFF39, 0xFF3A, 0x2213, 0x2135, 0x210F, 0x33CB, 0x2113, - 0x2127, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, - 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, - 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, - 0xFF58, 0xFF59, 0xFF5A, 0x30A0, 0x2013, 0x29FA, 0x29FB, -}; -static const unsigned short euc_to_utf8_A4[] = { - 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, - 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, - 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, - 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, - 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, - 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, - 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, - 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, - 0x3090, 0x3091, 0x3092, 0x3093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A4_x0213[] = { - 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, - 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, - 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, - 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, - 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, - 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, - 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, - 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, - 0x3090, 0x3091, 0x3092, 0x3093, 0x3094, 0x3095, 0x3096, /*0x304B*/ 0x309A, - /*0x304D*/ 0x309A, /*0x304F*/ 0x309A, /*0x3051*/ 0x309A, /*0x3053*/ 0x309A, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A5[] = { - 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, - 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, - 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, - 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, - 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, - 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, - 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, - 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, - 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, - 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, - 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A5_x0213[] = { - 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, - 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, - 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, - 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, - 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, - 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, - 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, - 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, - 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, - 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, - 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, /*0x30AB*/ 0x309A, - /*0x30AD*/ 0x309A, /*0x30AF*/ 0x309A, /*0x30B1*/ 0x309A, /*0x30B3*/ 0x309A, /*0x30BB*/ 0x309A, /*0x30C4*/ 0x309A, /*0x30C8*/ 0x309A, -}; -static const unsigned short euc_to_utf8_A6[] = { - 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, - 0x03A9, 0, 0, 0, 0, 0, 0, 0, - 0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, - 0x03C9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A6_x0213[] = { - 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, - 0x03A9, 0x2664, 0x2660, 0x2662, 0x2666, 0x2661, 0x2665, 0x2667, - 0x2663, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, - 0x03C9, 0x03C2, 0x24F5, 0x24F6, 0x24F7, 0x24F8, 0x24F9, 0x24FA, - 0x24FB, 0x24FC, 0x24FD, 0x24FE, 0x2616, 0x2617, 0x3020, 0x260E, - 0x2600, 0x2601, 0x2602, 0x2603, 0x2668, 0x25B1, 0x31F0, 0x31F1, - 0x31F2, 0x31F3, 0x31F4, 0x31F5, 0x31F6, 0x31F7, 0x31F8, 0x31F9, - /*0x31F7*/ 0x309A, 0x31FA, 0x31FB, 0x31FC, 0x31FD, 0x31FE, 0x31FF, -}; -static const unsigned short euc_to_utf8_A7[] = { - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, - 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, - 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, - 0x042E, 0x042F, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, - 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, - 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, - 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, - 0x044E, 0x044F, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A7_x0213[] = { - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, - 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, - 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, - 0x042E, 0x042F, 0x23BE, 0x23BF, 0x23C0, 0x23C1, 0x23C2, 0x23C3, - 0x23C4, 0x23C5, 0x23C6, 0x23C7, 0x23C8, 0x23C9, 0x23CA, 0x23CB, - 0x23CC, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, - 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, - 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, - 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, - 0x044E, 0x044F, 0x30F7, 0x30F8, 0x30F9, 0x30FA, 0x22DA, 0x22DB, - 0x2153, 0x2154, 0x2155, 0x2713, 0x2318, 0x2423, 0x23CE, -}; -static const unsigned short euc_to_utf8_A8[] = { - 0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, - 0x252C, 0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, - 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, - 0x252F, 0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, - 0x2542, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A8_x0213[] = { - 0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, - 0x252C, 0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, - 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, - 0x252F, 0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, - 0x2542, 0x3251, 0x3252, 0x3253, 0x3254, 0x3255, 0x3256, 0x3257, - 0x3258, 0x3259, 0x325A, 0x325B, 0x325C, 0x325D, 0x325E, 0x325F, - 0x32B1, 0x32B2, 0x32B3, 0x32B4, 0x32B5, 0x32B6, 0x32B7, 0x32B8, - 0x32B9, 0x32BA, 0x32BB, 0x32BC, 0x32BD, 0x32BE, 0x32BF, 0, - 0, 0, 0, 0, 0, 0, 0, 0x25D0, - 0x25D1, 0x25D2, 0x25D3, 0x203C, 0x2047, 0x2048, 0x2049, 0x01CD, - 0x01CE, 0x01D0, 0x1E3E, 0x1E3F, 0x01F8, 0x01F9, 0x01D1, 0x01D2, - 0x01D4, 0x01D6, 0x01D8, 0x01DA, 0x01DC, 0, 0, -}; -static const unsigned short euc_to_utf8_A9[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, - 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, - 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2474, - 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, - 0x247D, 0x247E, 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, - 0x2485, 0x2486, 0x2487, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2776, 0x2777, 0x2778, - 0x2779, 0x277A, 0x277B, 0x277C, 0x277D, 0x277E, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, - 0x248E, 0x248F, 0x2490, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_A9_x0213[] = { - 0x20AC, 0x00A0, 0x00A1, 0x00A4, 0x00A6, 0x00A9, 0x00AA, - 0x00AB, 0x00AD, 0x00AE, 0x00AF, 0x00B2, 0x00B3, 0x00B7, 0x00B8, - 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, - 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, - 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, - 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8, 0x00D9, - 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, - 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, - 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, - 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x00F9, 0x00FA, - 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x012A, 0x016A, - 0x0112, 0x014C, 0x0101, 0x012B, 0x016B, 0x0113, 0x014D, -}; -static const unsigned short euc_to_utf8_AA[] = { - 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, - 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2170, 0x2171, 0x2172, - 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, - 0x217B, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x249C, 0x249D, 0x249E, - 0x249F, 0x24A0, 0x24A1, 0x24A2, 0x24A3, 0x24A4, 0x24A5, 0x24A6, - 0x24A7, 0x24A8, 0x24A9, 0x24AA, 0x24AB, 0x24AC, 0x24AD, 0x24AE, - 0x24AF, 0x24B0, 0x24B1, 0x24B2, 0x24B3, 0x24B4, 0x24B5, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_AA_x0213[] = { - 0x0104, 0x02D8, 0x0141, 0x013D, 0x015A, 0x0160, 0x015E, - 0x0164, 0x0179, 0x017D, 0x017B, 0x0105, 0x02DB, 0x0142, 0x013E, - 0x015B, 0x02C7, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, - 0x017C, 0x0154, 0x0102, 0x0139, 0x0106, 0x010C, 0x0118, 0x011A, - 0x010E, 0x0143, 0x0147, 0x0150, 0x0158, 0x016E, 0x0170, 0x0162, - 0x0155, 0x0103, 0x013A, 0x0107, 0x010D, 0x0119, 0x011B, 0x010F, - 0x0111, 0x0144, 0x0148, 0x0151, 0x0159, 0x016F, 0x0171, 0x0163, - 0x02D9, 0x0108, 0x011C, 0x0124, 0x0134, 0x015C, 0x016C, 0x0109, - 0x011D, 0x0125, 0x0135, 0x015D, 0x016D, 0x0271, 0x028B, 0x027E, - 0x0283, 0x0292, 0x026C, 0x026E, 0x0279, 0x0288, 0x0256, 0x0273, - 0x027D, 0x0282, 0x0290, 0x027B, 0x026D, 0x025F, 0x0272, 0x029D, - 0x028E, 0x0261, 0x014B, 0x0270, 0x0281, 0x0127, 0x0295, -}; -static const unsigned short euc_to_utf8_AB[] = { - 0x339C, 0x339F, 0x339D, 0x33A0, 0x33A4, 0, 0x33A1, - 0x33A5, 0x339E, 0x33A2, 0x338E, 0, 0x338F, 0x33C4, 0x3396, - 0x3397, 0x2113, 0x3398, 0x33B3, 0x33B2, 0x33B1, 0x33B0, 0x2109, - 0x33D4, 0x33CB, 0x3390, 0x3385, 0x3386, 0x3387, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2116, 0x33CD, 0x2121, 0, -}; -static const unsigned short euc_to_utf8_AB_x0213[] = { - 0x0294, 0x0266, 0x0298, 0x01C2, 0x0253, 0x0257, 0x0284, - 0x0260, 0x0193, 0x0153, 0x0152, 0x0268, 0x0289, 0x0258, 0x0275, - 0x0259, 0x025C, 0x025E, 0x0250, 0x026F, 0x028A, 0x0264, 0x028C, - 0x0254, 0x0251, 0x0252, 0x028D, 0x0265, 0x02A2, 0x02A1, 0x0255, - 0x0291, 0x027A, 0x0267, 0x025A, /*0x00E6*/ 0x0300, 0x01FD, 0x1F70, 0x1F71, - /*0x0254*/ 0x0300, /*0x0254*/ 0x0301, /*0x028C*/ 0x0300, /*0x028C*/ 0x0301, /*0x0259*/ 0x0300, /*0x0259*/ 0x0301, /*0x025A*/ 0x0300, /*0x025A*/ 0x0301, - 0x1F72, 0x1F73, 0x0361, 0x02C8, 0x02CC, 0x02D0, 0x02D1, 0x0306, - 0x203F, 0x030B, /*0*/ 0x0301, 0x0304, /*0*/ 0x0300, 0x030F, 0x030C, 0x0302, - /*0*/ 0x02E5, 0x02E6, 0x02E7, 0x02E8, /*0*/ 0x02E9, /*0x02E9*/ 0x02E5, /*0x02E5*/ 0x02E9, 0x0325, - 0x032C, 0x0339, 0x031C, 0x031F, 0x0320, 0x0308, 0x033D, 0x0329, - 0x032F, 0x02DE, 0x0324, 0x0330, 0x033C, 0x0334, 0x031D, 0x031E, - 0x0318, 0x0319, 0x032A, 0x033A, 0x033B, 0x0303, 0x031A, -}; -static const unsigned short euc_to_utf8_AC[] = { - 0x2664, 0x2667, 0x2661, 0x2662, 0x2660, 0x2663, 0x2665, - 0x2666, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x3020, 0x260E, 0x3004, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x261E, 0x261C, 0x261D, 0x261F, 0x21C6, 0x21C4, 0x21C5, - 0, 0x21E8, 0x21E6, 0x21E7, 0x21E9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_AC_mac[] = { - 0x2664, 0x2667, 0x2661, 0x2662, 0x2660, 0x2663, 0x2665, - 0x2666, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x3020, 0x260E, 0x3004, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x261E, 0x261C, 0x261D, 0x261F, 0x21C6, 0x21C4, 0x21C5, - 0, 0x21E8, 0x21E6, 0x21E7, 0x21E9, 0x2192, 0x2190, 0x2191, - 0x2193, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_AC_x0213[] = { - 0x2776, 0x2777, 0x2778, 0x2779, 0x277A, 0x277B, 0x277C, - 0x277D, 0x277E, 0x277F, 0x24EB, 0x24EC, 0x24ED, 0x24EE, 0x24EF, - 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4, 0x2170, 0x2171, 0x2172, - 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, - 0x217B, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, - 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE, - 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, - 0x24E7, 0x24E8, 0x24E9, 0x32D0, 0x32D1, 0x32D2, 0x32D3, 0x32D4, - 0x32D5, 0x32D6, 0x32D7, 0x32D8, 0x32D9, 0x32DA, 0x32DB, 0x32DC, - 0x32DD, 0x32DE, 0x32DF, 0x32E0, 0x32E1, 0x32E2, 0x32E3, 0x32FA, - 0x32E9, 0x32E5, 0x32ED, 0x32EC, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2051, 0x2042, -}; -static const unsigned short euc_to_utf8_AD[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, - 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, - 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, - 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0, - 0x3349, 0x3314, 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, - 0x3351, 0x3357, 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, - 0x339C, 0x339D, 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0, - 0, 0, 0, 0, 0, 0, 0, 0x337B, - 0x301D, 0x301F, 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, - 0x32A7, 0x32A8, 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, - 0x2252, 0x2261, 0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220, - 0x221F, 0x22BF, 0x2235, 0x2229, 0x222A, 0, 0x3299, -}; -static const unsigned short euc_to_utf8_AD_mac[] = { - 0x65E5, 0x6708, 0x706B, 0x6C34, 0x6728, 0x91D1, 0x571F, - 0x796D, 0x795D, 0x81EA, 0x81F3, 0x3239, 0x547C, 0x3231, 0x8CC7, - 0x540D, 0x3232, 0x5B66, 0x8CA1, 0x793E, 0x7279, 0x76E3, 0x4F01, - 0x5354, 0x52B4, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0, - 0x3349, 0x3314, 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, - 0x3351, 0x3357, 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, - 0x339C, 0x339D, 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0, - 0, 0, 0, 0, 0, 0, 0, 0x337B, - 0x301D, 0x301F, 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, - 0x32A7, 0x32A8, 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, - 0x2252, 0x5927, 0x5C0F, 0x32A4, 0x32A5, 0x32A6, 0x32A7, 0x32A8, - 0x533B, 0x8CA1, 0x512A, 0x52B4, 0x5370, 0x63A7, 0x79D8, -}; -static const unsigned short euc_to_utf8_AD_x0213[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, - 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, - 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, - 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, - 0x3349, 0x3314, 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, - 0x3351, 0x3357, 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, - 0x339C, 0x339D, 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0x216B, - 0, 0, 0, 0, 0, 0, 0, 0x337B, - 0x301D, 0x301F, 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, - 0x32A7, 0x32A8, 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, - 0x2252, 0x2261, 0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220, - 0x221F, 0x22BF, 0x2235, 0x2229, 0x222A, 0x2756, 0x261E, -}; -static const unsigned short euc_to_utf8_AE[] = { - 0x3349, 0x3322, 0x334D, 0x3314, 0x3316, 0x3305, 0x3333, - 0x334E, 0x3303, 0x3336, 0x3318, 0x3315, 0x3327, 0x3351, 0x334A, - 0x3339, 0x3357, 0x330D, 0x3342, 0x3323, 0x3326, 0x333B, 0x332B, - 0, 0, 0, 0, 0, 0, 0, 0x3300, - 0x331E, 0x332A, 0x3331, 0x3347, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x337E, - 0x337D, 0x337C, 0x337B, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x337F, 0, 0, -}; -static const unsigned short euc_to_utf8_AE_x0213[] = { - 0x4FF1, 0xD840 /*0xDC0B*/, 0x3402, 0x4E28, 0x4E2F, 0x4E30, 0x4E8D, - 0x4EE1, 0x4EFD, 0x4EFF, 0x4F03, 0x4F0B, 0x4F60, 0x4F48, 0x4F49, - 0x4F56, 0x4F5F, 0x4F6A, 0x4F6C, 0x4F7E, 0x4F8A, 0x4F94, 0x4F97, - 0xFA30, 0x4FC9, 0x4FE0, 0x5001, 0x5002, 0x500E, 0x5018, 0x5027, - 0x502E, 0x5040, 0x503B, 0x5041, 0x5094, 0x50CC, 0x50F2, 0x50D0, - 0x50E6, 0xFA31, 0x5106, 0x5103, 0x510B, 0x511E, 0x5135, 0x514A, - 0xFA32, 0x5155, 0x5157, 0x34B5, 0x519D, 0x51C3, 0x51CA, 0x51DE, - 0x51E2, 0x51EE, 0x5201, 0x34DB, 0x5213, 0x5215, 0x5249, 0x5257, - 0x5261, 0x5293, 0x52C8, 0xFA33, 0x52CC, 0x52D0, 0x52D6, 0x52DB, - 0xFA34, 0x52F0, 0x52FB, 0x5300, 0x5307, 0x531C, 0xFA35, 0x5361, - 0x5363, 0x537D, 0x5393, 0x539D, 0x53B2, 0x5412, 0x5427, 0x544D, - 0x549C, 0x546B, 0x5474, 0x547F, 0x5488, 0x5496, 0x54A1, -}; -static const unsigned short euc_to_utf8_AF[] = { - 0x222E, 0x221F, 0x22BF, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x301D, 0x301F, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x3094, 0, 0x30F7, 0x30F8, 0x30F9, 0x30FA, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_AF_x0213[] = { - 0x54A9, 0x54C6, 0x54FF, 0x550E, 0x552B, 0x5535, 0x5550, - 0x555E, 0x5581, 0x5586, 0x558E, 0xFA36, 0x55AD, 0x55CE, 0xFA37, - 0x5608, 0x560E, 0x563B, 0x5649, 0x5676, 0x5666, 0xFA38, 0x566F, - 0x5671, 0x5672, 0x5699, 0x569E, 0x56A9, 0x56AC, 0x56B3, 0x56C9, - 0x56CA, 0x570A, 0xD844 /*0xDE3D*/, 0x5721, 0x572F, 0x5733, 0x5734, 0x5770, - 0x5777, 0x577C, 0x579C, 0xFA0F, 0xD844 /*0xDF1B*/, 0x57B8, 0x57C7, 0x57C8, - 0x57CF, 0x57E4, 0x57ED, 0x57F5, 0x57F6, 0x57FF, 0x5809, 0xFA10, - 0x5861, 0x5864, 0xFA39, 0x587C, 0x5889, 0x589E, 0xFA3A, 0x58A9, - 0xD845 /*0xDC6E*/, 0x58D2, 0x58CE, 0x58D4, 0x58DA, 0x58E0, 0x58E9, 0x590C, - 0x8641, 0x595D, 0x596D, 0x598B, 0x5992, 0x59A4, 0x59C3, 0x59D2, - 0x59DD, 0x5A13, 0x5A23, 0x5A67, 0x5A6D, 0x5A77, 0x5A7E, 0x5A84, - 0x5A9E, 0x5AA7, 0x5AC4, 0xD846 /*0xDCBD*/, 0x5B19, 0x5B25, 0x525D, -}; -static const unsigned short euc_to_utf8_B0[] = { - 0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328, - 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, - 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271, - 0x5B9B, 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216, - 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, - 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2, - 0x5937, 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613, - 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, - 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5, - 0x57DF, 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038, - 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, - 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D, -}; -static const unsigned short euc_to_utf8_B1[] = { - 0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, - 0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11, - 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B, - 0x59E5, 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, - 0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620, - 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E, - 0x9834, 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, - 0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186, - 0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4, - 0x6CBF, 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, - 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC, - 0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC, -}; -static const unsigned short euc_to_utf8_B2[] = { - 0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, - 0x8956, 0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, - 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, - 0x6069, 0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, - 0x4F3D, 0x4FA1, 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, - 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, - 0x706B, 0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, - 0x8304, 0x8377, 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, - 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, - 0x753B, 0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, - 0x4ECB, 0x4F1A, 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, - 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539, -}; -static const unsigned short euc_to_utf8_B3[] = { - 0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, - 0x7D75, 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, 0x52BE, - 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D, - 0x84CB, 0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, - 0x57A3, 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, 0x5ED3, - 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B, - 0x899A, 0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, - 0x5B66, 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, 0x6A2B, - 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC, - 0x6D3B, 0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, - 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, 0x7AC3, 0x84B2, - 0x91DC, 0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431, -}; -static const unsigned short euc_to_utf8_B4[] = { - 0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0, - 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, - 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163, - 0x61BE, 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53, - 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, - 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266, - 0x839E, 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591, - 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, - 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1, - 0x9811, 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668, - 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, - 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4, -}; -static const unsigned short euc_to_utf8_B5[] = { - 0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, - 0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77, - 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100, - 0x5993, 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, - 0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0, - 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775, - 0x9ECD, 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, - 0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551, - 0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE, - 0x7B08, 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, - 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD, - 0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC, -}; -static const unsigned short euc_to_utf8_B6[] = { - 0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, - 0x5354, 0x5321, 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, - 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, - 0x72C2, 0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, - 0x93E1, 0x97FF, 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, - 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, - 0x52E4, 0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, - 0x7981, 0x79BD, 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, - 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, - 0x533A, 0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, - 0x99D2, 0x5177, 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, - 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48, -}; -static const unsigned short euc_to_utf8_B7[] = { - 0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, - 0x9688, 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, 0x541B, - 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941, - 0x4FC2, 0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, - 0x5951, 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, 0x63B2, - 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB, - 0x7D4C, 0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, - 0x8A63, 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, - 0x5287, 0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20, - 0x6C7A, 0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, - 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, 0x55A7, 0x570F, - 0x5805, 0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372, -}; -static const unsigned short euc_to_utf8_B8[] = { - 0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F, - 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, - 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3, - 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237, - 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, - 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF, - 0x6E56, 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E, - 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, - 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F, - 0x68A7, 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190, - 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, - 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411, -}; -static const unsigned short euc_to_utf8_B9[] = { - 0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, - 0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7, - 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602, - 0x6643, 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, - 0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0, - 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1, - 0x8154, 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, - 0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D, - 0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408, - 0x58D5, 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, - 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09, - 0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC, -}; -static const unsigned short euc_to_utf8_BA[] = { - 0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, - 0x6068, 0x61C7, 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, - 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, - 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, - 0x88DF, 0x5750, 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, - 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, - 0x6B73, 0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, - 0x658E, 0x7D30, 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, - 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, - 0x80B4, 0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, - 0x548B, 0x643E, 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, - 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237, -}; -static const unsigned short euc_to_utf8_BB[] = { - 0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, - 0x96D1, 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, 0x6652, - 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F, - 0x71E6, 0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, - 0x9178, 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, - 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB, - 0x59C9, 0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, - 0x6307, 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, 0x6B62, - 0x6B7B, 0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, - 0x80A2, 0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, - 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, - 0x4F8D, 0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642, -}; -static const unsigned short euc_to_utf8_BC[] = { - 0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1, - 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, - 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03, - 0x53F1, 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06, - 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, - 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66, - 0x659C, 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E, - 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, - 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B, - 0x53D6, 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, - 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, - 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468, -}; -static const unsigned short euc_to_utf8_BD[] = { - 0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, - 0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490, - 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C, - 0x96C6, 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, - 0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4, - 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F, - 0x51FA, 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, - 0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3, - 0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806, - 0x51E6, 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, - 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973, - 0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F, -}; -static const unsigned short euc_to_utf8_BE[] = { - 0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, - 0x5617, 0x5968, 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, - 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, - 0x638C, 0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, - 0x6A1F, 0x6A35, 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, - 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, - 0x7B11, 0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, - 0x88F3, 0x8A1F, 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, - 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, - 0x4E57, 0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, - 0x60C5, 0x64FE, 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, - 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE, -}; -static const unsigned short euc_to_utf8_BF[] = { - 0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, - 0x89E6, 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, - 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0, - 0x664B, 0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, - 0x795E, 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, 0x8A3A, - 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203, - 0x5875, 0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, - 0x9663, 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, 0x53A8, - 0x9017, 0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761, - 0x7C8B, 0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, - 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, 0x8DA8, 0x96DB, - 0x636E, 0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE, -}; -static const unsigned short euc_to_utf8_C0[] = { - 0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F, - 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, - 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272, - 0x751F, 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0, - 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, - 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790, - 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1, - 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, - 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9, - 0x5148, 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226, - 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, - 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA, -}; -static const unsigned short euc_to_utf8_C1[] = { - 0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, - 0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE, - 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3, - 0x7CCE, 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, - 0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20, - 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275, - 0x53CC, 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, - 0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB, - 0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5, - 0x4E89, 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, - 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001, - 0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E, -}; -static const unsigned short euc_to_utf8_C2[] = { - 0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, - 0x5373, 0x606F, 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, - 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, - 0x5B58, 0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, - 0x592A, 0x6C70, 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, - 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, - 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, - 0x66FF, 0x6CF0, 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, - 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, - 0x7B2C, 0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, - 0x5B85, 0x6258, 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, - 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA, -}; -static const unsigned short euc_to_utf8_C3[] = { - 0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, - 0x7AEA, 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, 0x8AB0, - 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E, - 0x6DE1, 0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, - 0x80C6, 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, 0x65AD, - 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730, - 0x5F1B, 0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, - 0x8718, 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, 0x84C4, - 0x9010, 0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, - 0x5B99, 0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, - 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, 0x732A, 0x82E7, - 0x8457, 0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5, -}; -static const unsigned short euc_to_utf8_C4[] = { - 0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, - 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, - 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3, - 0x929A, 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715, - 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, - 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4, - 0x69FB, 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354, - 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, - 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E, - 0x5448, 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, - 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, - 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013, -}; -static const unsigned short euc_to_utf8_C5[] = { - 0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, - 0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2, - 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929, - 0x5C55, 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, - 0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410, - 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21, - 0x767B, 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, - 0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC, - 0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6, - 0x5D8B, 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, - 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8, - 0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230, -}; -static const unsigned short euc_to_utf8_C6[] = { - 0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, - 0x9003, 0x900F, 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, - 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, - 0x7AE5, 0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, - 0x5F97, 0x5FB3, 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, - 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, - 0x9CF6, 0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, - 0x6566, 0x6C8C, 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, - 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, - 0x637A, 0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, - 0x8EDF, 0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, - 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165, -}; -static const unsigned short euc_to_utf8_C7[] = { - 0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, - 0x6FE1, 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, 0x5E74, - 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, - 0x57DC, 0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, - 0x8FB2, 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, 0x6777, - 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC, - 0x4FF3, 0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, - 0x80CC, 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, 0x6885, - 0x6973, 0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019, - 0x877F, 0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, - 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, 0x8584, 0x8FEB, - 0x66DD, 0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6, -}; -static const unsigned short euc_to_utf8_C8[] = { - 0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8, - 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, - 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9, - 0x567A, 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD, - 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, - 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4, - 0x91C6, 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4, - 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, - 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC, - 0x75B2, 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB, - 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, - 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E, -}; -static const unsigned short euc_to_utf8_C9[] = { - 0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, - 0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C, - 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A, - 0x6A19, 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, - 0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C, - 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7, - 0x8CD3, 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, - 0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577, - 0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299, - 0x8B5C, 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, - 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8, - 0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D, -}; -static const unsigned short euc_to_utf8_CA[] = { - 0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, - 0x6CB8, 0x4ECF, 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, - 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, - 0x6587, 0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, - 0x5F0A, 0x67C4, 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, - 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, - 0x504F, 0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, - 0x4FBF, 0x52C9, 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, - 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, - 0x5893, 0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, - 0x4FF8, 0x5305, 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, - 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B, -}; -static const unsigned short euc_to_utf8_CB[] = { - 0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, - 0x840C, 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, 0x92D2, - 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A, - 0x59A8, 0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, - 0x68D2, 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, 0x8CBF, - 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8, - 0x64B2, 0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, - 0x6B86, 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, 0x76C6, - 0x6469, 0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A, - 0x6BCE, 0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, - 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, 0x672B, 0x6CAB, - 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80, -}; -static const unsigned short euc_to_utf8_CC[] = { - 0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95, - 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, - 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB, - 0x9727, 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D, - 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, - 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21, - 0x8302, 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017, - 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, - 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580, - 0x5301, 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25, - 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, - 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652, -}; -static const unsigned short euc_to_utf8_CD[] = { - 0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, - 0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67, - 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A, - 0x9091, 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, - 0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8, - 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6, - 0x7194, 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, - 0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32, - 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8, - 0x6765, 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, - 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7, - 0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483, -}; -static const unsigned short euc_to_utf8_CE[] = { - 0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, - 0x7387, 0x7ACB, 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, - 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, - 0x616E, 0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, - 0x5BEE, 0x6599, 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, - 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, - 0x7DD1, 0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, - 0x8F2A, 0x96A3, 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, - 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, - 0x73B2, 0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, - 0x9F62, 0x66A6, 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, - 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F, -}; -static const unsigned short euc_to_utf8_CF[] = { - 0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, - 0x8CC2, 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717, - 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, - 0x807E, 0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, - 0x8AD6, 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1, - 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, - 0x6900, 0x6E7E, 0x7897, 0x8155, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_CF_x0213[] = { - 0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, - 0x8CC2, 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717, - 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, - 0x807E, 0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, - 0x8AD6, 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1, - 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, - 0x6900, 0x6E7E, 0x7897, 0x8155, 0xD842 /*0xDF9F*/, 0x5B41, 0x5B56, 0x5B7D, - 0x5B93, 0x5BD8, 0x5BEC, 0x5C12, 0x5C1E, 0x5C23, 0x5C2B, 0x378D, - 0x5C62, 0xFA3B, 0xFA3C, 0xD845 /*0xDEB4*/, 0x5C7A, 0x5C8F, 0x5C9F, 0x5CA3, - 0x5CAA, 0x5CBA, 0x5CCB, 0x5CD0, 0x5CD2, 0x5CF4, 0xD847 /*0xDE34*/, 0x37E2, - 0x5D0D, 0x5D27, 0xFA11, 0x5D46, 0x5D47, 0x5D53, 0x5D4A, 0x5D6D, - 0x5D81, 0x5DA0, 0x5DA4, 0x5DA7, 0x5DB8, 0x5DCB, 0x541E, -}; -static const unsigned short euc_to_utf8_D0[] = { - 0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, - 0x4E3F, 0x4E42, 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, - 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0, - 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, - 0x4EDE, 0x4EED, 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, - 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B, - 0x4F69, 0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4, - 0x4FDF, 0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, - 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C, - 0x4FF6, 0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006, - 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, - 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2, -}; -static const unsigned short euc_to_utf8_D1[] = { - 0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, - 0x50ED, 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, 0x5102, - 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C, - 0x513B, 0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, - 0x5169, 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, 0x5189, - 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2, - 0x51A9, 0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, - 0x51BD, 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, 0x51ED, - 0x51F0, 0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227, - 0x522A, 0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, - 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, 0x527F, 0x527D, - 0x528D, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8, -}; -static const unsigned short euc_to_utf8_D2[] = { - 0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD, - 0x52D7, 0x52DE, 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, - 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F, - 0x5315, 0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340, - 0x5346, 0x5345, 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, - 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6, - 0x53A5, 0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF, - 0x66FC, 0x71EE, 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, - 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D, - 0x544E, 0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470, - 0x5492, 0x547B, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, - 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8, -}; -static const unsigned short euc_to_utf8_D3[] = { - 0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, - 0x54E6, 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, 0x54E2, - 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556, - 0x5557, 0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, - 0x559F, 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, 0x5583, - 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC, - 0x55E4, 0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, - 0x55F9, 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, 0x5638, - 0x566B, 0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A, - 0x56A0, 0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, - 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, 0x56D1, 0x56D3, - 0x56D7, 0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709, -}; -static const unsigned short euc_to_utf8_D4[] = { - 0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7, - 0x571C, 0x5726, 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, - 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0, - 0x57B3, 0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2, - 0x57D3, 0x580A, 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, - 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879, - 0x5885, 0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8, - 0x58AE, 0x58C5, 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, - 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC, - 0x58FD, 0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C, - 0x592D, 0x5932, 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, - 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969, -}; -static const unsigned short euc_to_utf8_D5[] = { - 0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, - 0x59C6, 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, 0x5A1F, - 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35, - 0x5A36, 0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, - 0x5ABD, 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, 0x5AFB, - 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E, - 0x5B43, 0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, - 0x5B69, 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, 0x5B80, - 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, - 0x5BE4, 0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, - 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, 0x5C20, 0x5C22, - 0x5C28, 0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53, -}; -static const unsigned short euc_to_utf8_D6[] = { - 0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, - 0x5C79, 0x5C8C, 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, - 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD, - 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, - 0x5D1F, 0x5D1B, 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, - 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87, - 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, - 0x5DB7, 0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, - 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B, - 0x5E36, 0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54, - 0x5E5F, 0x5E62, 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, - 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF, -}; -static const unsigned short euc_to_utf8_D7[] = { - 0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, - 0x5EE8, 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, 0x5EF8, - 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16, - 0x5F29, 0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, - 0x5F51, 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, 0x5F77, - 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E, - 0x5F99, 0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, - 0x5FE4, 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, 0x6060, - 0x6019, 0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B, - 0x6026, 0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, - 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, 0x6042, 0x606C, - 0x606B, 0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A, -}; -static const unsigned short euc_to_utf8_D8[] = { - 0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B, - 0x60E1, 0x60B8, 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, - 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100, - 0x60F4, 0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E, - 0x6147, 0x613E, 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, - 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, - 0x615A, 0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D, - 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, - 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7, - 0x61C8, 0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6, - 0x61E3, 0x61F6, 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, - 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B, -}; -static const unsigned short euc_to_utf8_D9[] = { - 0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, - 0x6241, 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, 0x627C, - 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283, - 0x6294, 0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, - 0x62C8, 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, 0x62C9, - 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5, - 0x6350, 0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, - 0x63AB, 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, 0x636B, - 0x6369, 0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2, - 0x63F6, 0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, - 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, 0x6476, 0x644E, - 0x652A, 0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC, -}; -static const unsigned short euc_to_utf8_DA[] = { - 0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2, - 0x64F1, 0x64E7, 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, - 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518, - 0x651C, 0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537, - 0x6536, 0x6538, 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, - 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B, - 0x659F, 0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC, - 0x65D2, 0x65DB, 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, - 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F, - 0x6644, 0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668, - 0x665F, 0x6662, 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, - 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC, -}; -static const unsigned short euc_to_utf8_DB[] = { - 0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, - 0x66E9, 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, 0x6726, - 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737, - 0x6746, 0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, - 0x67A9, 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, 0x6785, - 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4, - 0x67DE, 0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, - 0x6A9C, 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, 0x684E, - 0x68B3, 0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F, - 0x68AD, 0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, - 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, 0x6901, 0x68CA, - 0x6908, 0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD, -}; -static const unsigned short euc_to_utf8_DC[] = { - 0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7, - 0x68E3, 0x6925, 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, - 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B, - 0x6954, 0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930, - 0x6961, 0x695E, 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, - 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD, - 0x69BB, 0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995, - 0x69B4, 0x69DE, 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, - 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB, - 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72, - 0x6A36, 0x6A78, 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, - 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3, -}; -static const unsigned short euc_to_utf8_DD[] = { - 0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, - 0x6AAC, 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, 0x6AFB, - 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38, - 0x6B37, 0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, - 0x6B59, 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, 0x6B7F, - 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4, - 0x6BAA, 0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, - 0x6BC6, 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, 0x6BEF, - 0x9EBE, 0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, - 0x6C55, 0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, - 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, 0x6CF1, 0x6CD3, - 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE, -}; -static const unsigned short euc_to_utf8_DE[] = { - 0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, - 0x6D36, 0x6D2B, 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, - 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E, - 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, - 0x6DE6, 0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, - 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D, - 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, - 0x6E2B, 0x6E76, 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, - 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7, - 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, - 0x6EA5, 0x6EC2, 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, - 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC, -}; -static const unsigned short euc_to_utf8_DF[] = { - 0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, - 0x6F80, 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, 0x6F58, - 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4, - 0x6FB9, 0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, - 0x6FF1, 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, 0x7001, - 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F, - 0x7030, 0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, - 0x70F1, 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, 0x70DD, - 0x70D9, 0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188, - 0x7166, 0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, - 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, 0x71D2, 0x71C9, - 0x71D4, 0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC, -}; -static const unsigned short euc_to_utf8_E0[] = { - 0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D, - 0x722C, 0x7230, 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, - 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292, - 0x7296, 0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4, - 0x72CE, 0x72D2, 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, - 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329, - 0x7325, 0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368, - 0x7370, 0x7378, 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, - 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F, - 0x7425, 0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459, - 0x7441, 0x745C, 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, - 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1, -}; -static const unsigned short euc_to_utf8_E1[] = { - 0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, - 0x74F1, 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, 0x750E, - 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544, - 0x754D, 0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, - 0x7567, 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, - 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3, - 0x75C2, 0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, - 0x75CD, 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, 0x75FF, - 0x75FC, 0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D, - 0x7609, 0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, - 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, 0x7658, 0x7661, - 0x7662, 0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670, -}; -static const unsigned short euc_to_utf8_E2[] = { - 0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688, - 0x768B, 0x768E, 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, - 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE, - 0x76E1, 0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707, - 0x7704, 0x7729, 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, - 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F, - 0x777E, 0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0, - 0x77B6, 0x77B9, 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, - 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812, - 0x7926, 0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C, - 0x789A, 0x788C, 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, - 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC, -}; -static const unsigned short euc_to_utf8_E3[] = { - 0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, - 0x7919, 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, 0x795A, - 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B, - 0x79AA, 0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, - 0x79EC, 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, 0x7A20, - 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57, - 0x7A49, 0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, - 0x7A88, 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, 0x7AB0, - 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, - 0x7ACF, 0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, - 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, 0x7B06, 0x7B33, - 0x7B18, 0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50, -}; -static const unsigned short euc_to_utf8_E4[] = { - 0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, - 0x7B65, 0x7B74, 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, - 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F, - 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, - 0x7BDD, 0x7BE9, 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, - 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23, - 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, - 0x7C54, 0x7C4F, 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, - 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2, - 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, - 0x7CBD, 0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, - 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06, -}; -static const unsigned short euc_to_utf8_E5[] = { - 0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, - 0x7D32, 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, 0x7D72, - 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F, - 0x7D7D, 0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, - 0x7DAB, 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, 0x7DB0, - 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05, - 0x7E0A, 0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, - 0x7E22, 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, 0x7E37, - 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, - 0x7E79, 0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, - 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, 0x7E90, 0x7E93, - 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A, -}; -static const unsigned short euc_to_utf8_E6[] = { - 0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55, - 0x7F54, 0x7F58, 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, - 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E, - 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, - 0x7FB8, 0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, - 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B, - 0x8012, 0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B, - 0x804A, 0x8046, 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, - 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084, - 0x8086, 0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC, - 0x80DB, 0x80E5, 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, - 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B, -}; -static const unsigned short euc_to_utf8_E7[] = { - 0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, - 0x816E, 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, 0x8180, - 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9, - 0x81B0, 0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, - 0x81C9, 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, 0x81DF, - 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205, - 0x8207, 0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, - 0x8233, 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, 0x8264, - 0x8262, 0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278, - 0x827E, 0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, - 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, 0x8393, 0x8303, - 0x82FB, 0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9, -}; -static const unsigned short euc_to_utf8_E8[] = { - 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, - 0x8350, 0x8345, 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, - 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A, - 0x837C, 0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4, - 0x8413, 0x83EB, 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, - 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD, - 0x8438, 0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484, - 0x8477, 0x846B, 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, - 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F, - 0x84D9, 0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6, - 0x84A1, 0x8521, 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, - 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548, -}; -static const unsigned short euc_to_utf8_E9[] = { - 0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, - 0x8591, 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, 0x8587, - 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9, - 0x85D0, 0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, - 0x860B, 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, 0x863F, - 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3, - 0x86A9, 0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, - 0x86B0, 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, 0x86EC, - 0x86DF, 0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, - 0x86FB, 0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, - 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, 0x875F, 0x8778, - 0x874C, 0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759, -}; -static const unsigned short euc_to_utf8_EA[] = { - 0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782, - 0x87AF, 0x87CB, 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, - 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F, - 0x880D, 0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816, - 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, - 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881, - 0x887E, 0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897, - 0x8892, 0x88AE, 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, - 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9, - 0x8902, 0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A, - 0x8913, 0x8943, 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, - 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E, -}; -static const unsigned short euc_to_utf8_EB[] = { - 0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, - 0x897E, 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, 0x89A9, - 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0, - 0x89DA, 0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, - 0x8A10, 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, 0x8A5B, - 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85, - 0x8A82, 0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, - 0x8AA3, 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, 0x8AE7, - 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, - 0x8B0C, 0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, - 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, 0x8B41, 0x8B4C, - 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B, -}; -static const unsigned short euc_to_utf8_EC[] = { - 0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, - 0x8B8E, 0x8B92, 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, - 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C, - 0x8C78, 0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, - 0x8C94, 0x8C7C, 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, - 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA, - 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, - 0x8D0D, 0x8D10, 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, - 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA, - 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, - 0x8DDF, 0x8DE3, 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, - 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A, -}; -static const unsigned short euc_to_utf8_ED[] = { - 0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, - 0x8E60, 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, 0x8E81, - 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94, - 0x8E99, 0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, - 0x8EC5, 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, 0x8EEB, - 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C, - 0x8F1F, 0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, - 0x8F42, 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, 0x8F5C, - 0x8F62, 0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, - 0x8FB7, 0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, - 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, 0x900D, 0x901E, - 0x9016, 0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8, -}; -static const unsigned short euc_to_utf8_EE[] = { - 0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E, - 0x9056, 0x9058, 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, - 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8, - 0x90AF, 0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102, - 0x9112, 0x9119, 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, - 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2, - 0x91AB, 0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1, - 0x91C9, 0x91CB, 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, - 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211, - 0x925E, 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F, - 0x924B, 0x9250, 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, - 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E, -}; -static const unsigned short euc_to_utf8_EF[] = { - 0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, - 0x935C, 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, 0x93AD, - 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3, - 0x93DD, 0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, - 0x9407, 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, 0x9441, - 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229, - 0x9470, 0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, - 0x947F, 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, 0x9599, - 0x95A0, 0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE, - 0x95CA, 0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, - 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, 0x962E, 0x962F, - 0x9642, 0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E, -}; -static const unsigned short euc_to_utf8_F0[] = { - 0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698, - 0x9695, 0x9697, 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, - 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D, - 0x96DC, 0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713, - 0x970E, 0x9711, 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, - 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, - 0x975C, 0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771, - 0x9779, 0x9785, 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, - 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3, - 0x97C6, 0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, - 0x97F6, 0x97F5, 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, - 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870, -}; -static const unsigned short euc_to_utf8_F1[] = { - 0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, - 0x98C4, 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, 0x9912, - 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C, - 0x992E, 0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, - 0x9951, 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, 0x99AD, - 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED, - 0x99EE, 0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, - 0x99E2, 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, 0x9A43, - 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65, - 0x9A64, 0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, - 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, 0x9AE2, 0x9AE3, - 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7, -}; -static const unsigned short euc_to_utf8_F2[] = { - 0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, - 0x9B25, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, - 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74, - 0x9B93, 0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, - 0x9BB4, 0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, - 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1, - 0x9BF0, 0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08, - 0x9C12, 0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, - 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67, - 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, - 0x9D03, 0x9D06, 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, - 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48, -}; -static const unsigned short euc_to_utf8_F3[] = { - 0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, - 0x9D89, 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, 0x9DA9, - 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF, - 0x9DC2, 0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, - 0x9E1A, 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, 0x9E88, - 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9, - 0x9EB8, 0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, - 0x9ED4, 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, 0x9EEF, - 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, - 0x9F08, 0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, - 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, 0x9F67, 0x9F6C, - 0x9F6A, 0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0, -}; -static const unsigned short euc_to_utf8_F4[] = { - 0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_F4_x0213[] = { - 0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0x5653, - 0x5DE2, 0x5E14, 0x5E18, 0x5E58, 0x5E5E, 0x5EBE, 0xF928, 0x5ECB, - 0x5EF9, 0x5F00, 0x5F02, 0x5F07, 0x5F1D, 0x5F23, 0x5F34, 0x5F36, - 0x5F3D, 0x5F40, 0x5F45, 0x5F54, 0x5F58, 0x5F64, 0x5F67, 0x5F7D, - 0x5F89, 0x5F9C, 0x5FA7, 0x5FAF, 0x5FB5, 0x5FB7, 0x5FC9, 0x5FDE, - 0x5FE1, 0x5FE9, 0x600D, 0x6014, 0x6018, 0x6033, 0x6035, 0x6047, - 0xFA3D, 0x609D, 0x609E, 0x60CB, 0x60D4, 0x60D5, 0x60DD, 0x60F8, - 0x611C, 0x612B, 0x6130, 0x6137, 0xFA3E, 0x618D, 0xFA3F, 0x61BC, - 0x61B9, 0xFA40, 0x6222, 0x623E, 0x6243, 0x6256, 0x625A, 0x626F, - 0x6285, 0x62C4, 0x62D6, 0x62FC, 0x630A, 0x6318, 0x6339, 0x6343, - 0x6365, 0x637C, 0x63E5, 0x63ED, 0x63F5, 0x6410, 0x6414, 0x6422, - 0x6479, 0x6451, 0x6460, 0x646D, 0x64CE, 0x64BE, 0x64BF, -}; -static const unsigned short euc_to_utf8_F5[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFE33, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFE31, 0, 0, - 0, 0, 0, 0, 0, 0xFE30, 0, 0, - 0, 0, 0xFE35, 0xFE36, 0xFE39, 0xFE3A, 0, 0, - 0xFE37, 0xFE38, 0xFE3F, 0xFE40, 0xFE3D, 0xFE3E, 0xFE41, 0xFE42, - 0xFE43, 0xFE44, 0xFE3B, 0xFE3C, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_F5_x0213[] = { - 0x64C4, 0x64CA, 0x64D0, 0x64F7, 0x64FB, 0x6522, 0x6529, - 0xFA41, 0x6567, 0x659D, 0xFA42, 0x6600, 0x6609, 0x6615, 0x661E, - 0x663A, 0x6622, 0x6624, 0x662B, 0x6630, 0x6631, 0x6633, 0x66FB, - 0x6648, 0x664C, 0xD84C /*0xDDC4*/, 0x6659, 0x665A, 0x6661, 0x6665, 0x6673, - 0x6677, 0x6678, 0x668D, 0xFA43, 0x66A0, 0x66B2, 0x66BB, 0x66C6, - 0x66C8, 0x3B22, 0x66DB, 0x66E8, 0x66FA, 0x6713, 0xF929, 0x6733, - 0x6766, 0x6747, 0x6748, 0x677B, 0x6781, 0x6793, 0x6798, 0x679B, - 0x67BB, 0x67F9, 0x67C0, 0x67D7, 0x67FC, 0x6801, 0x6852, 0x681D, - 0x682C, 0x6831, 0x685B, 0x6872, 0x6875, 0xFA44, 0x68A3, 0x68A5, - 0x68B2, 0x68C8, 0x68D0, 0x68E8, 0x68ED, 0x68F0, 0x68F1, 0x68FC, - 0x690A, 0x6949, 0xD84D /*0xDDC4*/, 0x6935, 0x6942, 0x6957, 0x6963, 0x6964, - 0x6968, 0x6980, 0xFA14, 0x69A5, 0x69AD, 0x69CF, 0x3BB6, -}; -static const unsigned short euc_to_utf8_F6_x0213[] = { - 0x3BC3, 0x69E2, 0x69E9, 0x69EA, 0x69F5, 0x69F6, 0x6A0F, - 0x6A15, 0xD84D /*0xDF3F*/, 0x6A3B, 0x6A3E, 0x6A45, 0x6A50, 0x6A56, 0x6A5B, - 0x6A6B, 0x6A73, 0xD84D /*0xDF63*/, 0x6A89, 0x6A94, 0x6A9D, 0x6A9E, 0x6AA5, - 0x6AE4, 0x6AE7, 0x3C0F, 0xF91D, 0x6B1B, 0x6B1E, 0x6B2C, 0x6B35, - 0x6B46, 0x6B56, 0x6B60, 0x6B65, 0x6B67, 0x6B77, 0x6B82, 0x6BA9, - 0x6BAD, 0xF970, 0x6BCF, 0x6BD6, 0x6BD7, 0x6BFF, 0x6C05, 0x6C10, - 0x6C33, 0x6C59, 0x6C5C, 0x6CAA, 0x6C74, 0x6C76, 0x6C85, 0x6C86, - 0x6C98, 0x6C9C, 0x6CFB, 0x6CC6, 0x6CD4, 0x6CE0, 0x6CEB, 0x6CEE, - 0xD84F /*0xDCFE*/, 0x6D04, 0x6D0E, 0x6D2E, 0x6D31, 0x6D39, 0x6D3F, 0x6D58, - 0x6D65, 0xFA45, 0x6D82, 0x6D87, 0x6D89, 0x6D94, 0x6DAA, 0x6DAC, - 0x6DBF, 0x6DC4, 0x6DD6, 0x6DDA, 0x6DDB, 0x6DDD, 0x6DFC, 0xFA46, - 0x6E34, 0x6E44, 0x6E5C, 0x6E5E, 0x6EAB, 0x6EB1, 0x6EC1, -}; -static const unsigned short euc_to_utf8_F7_x0213[] = { - 0x6EC7, 0x6ECE, 0x6F10, 0x6F1A, 0xFA47, 0x6F2A, 0x6F2F, - 0x6F33, 0x6F51, 0x6F59, 0x6F5E, 0x6F61, 0x6F62, 0x6F7E, 0x6F88, - 0x6F8C, 0x6F8D, 0x6F94, 0x6FA0, 0x6FA7, 0x6FB6, 0x6FBC, 0x6FC7, - 0x6FCA, 0x6FF9, 0x6FF0, 0x6FF5, 0x7005, 0x7006, 0x7028, 0x704A, - 0x705D, 0x705E, 0x704E, 0x7064, 0x7075, 0x7085, 0x70A4, 0x70AB, - 0x70B7, 0x70D4, 0x70D8, 0x70E4, 0x710F, 0x712B, 0x711E, 0x7120, - 0x712E, 0x7130, 0x7146, 0x7147, 0x7151, 0xFA48, 0x7152, 0x715C, - 0x7160, 0x7168, 0xFA15, 0x7185, 0x7187, 0x7192, 0x71C1, 0x71BA, - 0x71C4, 0x71FE, 0x7200, 0x7215, 0x7255, 0x7256, 0x3E3F, 0x728D, - 0x729B, 0x72BE, 0x72C0, 0x72FB, 0xD851 /*0xDFF1*/, 0x7327, 0x7328, 0xFA16, - 0x7350, 0x7366, 0x737C, 0x7395, 0x739F, 0x73A0, 0x73A2, 0x73A6, - 0x73AB, 0x73C9, 0x73CF, 0x73D6, 0x73D9, 0x73E3, 0x73E9, -}; -static const unsigned short euc_to_utf8_F8_x0213[] = { - 0x7407, 0x740A, 0x741A, 0x741B, 0xFA4A, 0x7426, 0x7428, - 0x742A, 0x742B, 0x742C, 0x742E, 0x742F, 0x7430, 0x7444, 0x7446, - 0x7447, 0x744B, 0x7457, 0x7462, 0x746B, 0x746D, 0x7486, 0x7487, - 0x7489, 0x7498, 0x749C, 0x749F, 0x74A3, 0x7490, 0x74A6, 0x74A8, - 0x74A9, 0x74B5, 0x74BF, 0x74C8, 0x74C9, 0x74DA, 0x74FF, 0x7501, - 0x7517, 0x752F, 0x756F, 0x7579, 0x7592, 0x3F72, 0x75CE, 0x75E4, - 0x7600, 0x7602, 0x7608, 0x7615, 0x7616, 0x7619, 0x761E, 0x762D, - 0x7635, 0x7643, 0x764B, 0x7664, 0x7665, 0x766D, 0x766F, 0x7671, - 0x7681, 0x769B, 0x769D, 0x769E, 0x76A6, 0x76AA, 0x76B6, 0x76C5, - 0x76CC, 0x76CE, 0x76D4, 0x76E6, 0x76F1, 0x76FC, 0x770A, 0x7719, - 0x7734, 0x7736, 0x7746, 0x774D, 0x774E, 0x775C, 0x775F, 0x7762, - 0x777A, 0x7780, 0x7794, 0x77AA, 0x77E0, 0x782D, 0xD855 /*0xDC8E*/, -}; -static const unsigned short euc_to_utf8_F9[] = { - 0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, - 0x6631, 0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC, - 0x4F00, 0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, - 0x4FCD, 0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, - 0x5094, 0x50F4, 0x50D8, 0x514A, 0x5164, 0x519D, 0x51BE, 0x51EC, - 0x5215, 0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, - 0x5372, 0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, - 0x54FF, 0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F, - 0xFA10, 0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, - 0x59A4, 0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, - 0x5CA6, 0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, - 0x5DB8, 0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7, -}; -static const unsigned short euc_to_utf8_F9_x0213[] = { - 0x7843, 0x784E, 0x784F, 0x7851, 0x7868, 0x786E, 0xFA4B, - 0x78B0, 0xD855 /*0xDD0E*/, 0x78AD, 0x78E4, 0x78F2, 0x7900, 0x78F7, 0x791C, - 0x792E, 0x7931, 0x7934, 0xFA4C, 0xFA4D, 0x7945, 0x7946, 0xFA4E, - 0xFA4F, 0xFA50, 0x795C, 0xFA51, 0xFA19, 0xFA1A, 0x7979, 0xFA52, - 0xFA53, 0xFA1B, 0x7998, 0x79B1, 0x79B8, 0x79C8, 0x79CA, 0xD855 /*0xDF71*/, - 0x79D4, 0x79DE, 0x79EB, 0x79ED, 0x7A03, 0xFA54, 0x7A39, 0x7A5D, - 0x7A6D, 0xFA55, 0x7A85, 0x7AA0, 0xD856 /*0xDDC4*/, 0x7AB3, 0x7ABB, 0x7ACE, - 0x7AEB, 0x7AFD, 0x7B12, 0x7B2D, 0x7B3B, 0x7B47, 0x7B4E, 0x7B60, - 0x7B6D, 0x7B6F, 0x7B72, 0x7B9E, 0xFA56, 0x7BD7, 0x7BD9, 0x7C01, - 0x7C31, 0x7C1E, 0x7C20, 0x7C33, 0x7C36, 0x4264, 0xD857 /*0xDDA1*/, 0x7C59, - 0x7C6D, 0x7C79, 0x7C8F, 0x7C94, 0x7CA0, 0x7CBC, 0x7CD5, 0x7CD9, - 0x7CDD, 0x7D07, 0x7D08, 0x7D13, 0x7D1D, 0x7D23, 0x7D31, -}; -static const unsigned short euc_to_utf8_FA[] = { - 0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, - 0x60F2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5, - 0x6460, 0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, - 0x662E, 0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, - 0x6699, 0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766, - 0x67BB, 0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, - 0xFA14, 0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, - 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, - 0x6D04, 0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, - 0x6DFC, 0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, - 0x6FF5, 0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104, - 0x715C, 0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1, -}; -static const unsigned short euc_to_utf8_FA_x0213[] = { - 0x7D41, 0x7D48, 0x7D53, 0x7D5C, 0x7D7A, 0x7D83, 0x7D8B, - 0x7DA0, 0x7DA6, 0x7DC2, 0x7DCC, 0x7DD6, 0x7DE3, 0xFA57, 0x7E28, - 0x7E08, 0x7E11, 0x7E15, 0xFA59, 0x7E47, 0x7E52, 0x7E61, 0x7E8A, - 0x7E8D, 0x7F47, 0xFA5A, 0x7F91, 0x7F97, 0x7FBF, 0x7FCE, 0x7FDB, - 0x7FDF, 0x7FEC, 0x7FEE, 0x7FFA, 0xFA5B, 0x8014, 0x8026, 0x8035, - 0x8037, 0x803C, 0x80CA, 0x80D7, 0x80E0, 0x80F3, 0x8118, 0x814A, - 0x8160, 0x8167, 0x8168, 0x816D, 0x81BB, 0x81CA, 0x81CF, 0x81D7, - 0xFA5C, 0x4453, 0x445B, 0x8260, 0x8274, 0xD85A /*0xDEFF*/, 0x828E, 0x82A1, - 0x82A3, 0x82A4, 0x82A9, 0x82AE, 0x82B7, 0x82BE, 0x82BF, 0x82C6, - 0x82D5, 0x82FD, 0x82FE, 0x8300, 0x8301, 0x8362, 0x8322, 0x832D, - 0x833A, 0x8343, 0x8347, 0x8351, 0x8355, 0x837D, 0x8386, 0x8392, - 0x8398, 0x83A7, 0x83A9, 0x83BF, 0x83C0, 0x83C7, 0x83CF, -}; -static const unsigned short euc_to_utf8_FB[] = { - 0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, - 0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E, - 0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, - 0x769B, 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, - 0x787A, 0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B, - 0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, - 0x7DB7, 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, - 0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559, - 0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, - 0x8A37, 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, - 0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24, - 0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA, -}; -static const unsigned short euc_to_utf8_FB_x0213[] = { - 0x83D1, 0x83E1, 0x83EA, 0x8401, 0x8406, 0x840A, 0xFA5F, - 0x8448, 0x845F, 0x8470, 0x8473, 0x8485, 0x849E, 0x84AF, 0x84B4, - 0x84BA, 0x84C0, 0x84C2, 0xD85B /*0xDE40*/, 0x8532, 0x851E, 0x8523, 0x852F, - 0x8559, 0x8564, 0xFA1F, 0x85AD, 0x857A, 0x858C, 0x858F, 0x85A2, - 0x85B0, 0x85CB, 0x85CE, 0x85ED, 0x8612, 0x85FF, 0x8604, 0x8605, - 0x8610, 0xD85C /*0xDCF4*/, 0x8618, 0x8629, 0x8638, 0x8657, 0x865B, 0xF936, - 0x8662, 0x459D, 0x866C, 0x8675, 0x8698, 0x86B8, 0x86FA, 0x86FC, - 0x86FD, 0x870B, 0x8771, 0x8787, 0x8788, 0x87AC, 0x87AD, 0x87B5, - 0x45EA, 0x87D6, 0x87EC, 0x8806, 0x880A, 0x8810, 0x8814, 0x881F, - 0x8898, 0x88AA, 0x88CA, 0x88CE, 0xD85D /*0xDE84*/, 0x88F5, 0x891C, 0xFA60, - 0x8918, 0x8919, 0x891A, 0x8927, 0x8930, 0x8932, 0x8939, 0x8940, - 0x8994, 0xFA61, 0x89D4, 0x89E5, 0x89F6, 0x8A12, 0x8A15, -}; -static const unsigned short euc_to_utf8_FC[] = { - 0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, - 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, - 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, - 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, - 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, - 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, - 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, - 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, - 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, - 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0, - 0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, - 0x2177, 0x2178, 0x2179, 0xFFE2, 0x00A6, 0xFF07, 0xFF02, -}; - -/* Microsoft UCS Mapping Compatible */ -static const unsigned short euc_to_utf8_FC_ms[] = { - 0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, - 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, - 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, - 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, - 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, - 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, - 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, - 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, - 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, - 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0, - 0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, - 0x2177, 0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02, -}; -static const unsigned short euc_to_utf8_FC_x0213[] = { - 0x8A22, 0x8A37, 0x8A47, 0x8A4E, 0x8A5D, 0x8A61, 0x8A75, - 0x8A79, 0x8AA7, 0x8AD0, 0x8ADF, 0x8AF4, 0x8AF6, 0xFA22, 0xFA62, - 0xFA63, 0x8B46, 0x8B54, 0x8B59, 0x8B69, 0x8B9D, 0x8C49, 0x8C68, - 0xFA64, 0x8CE1, 0x8CF4, 0x8CF8, 0x8CFE, 0xFA65, 0x8D12, 0x8D1B, - 0x8DAF, 0x8DCE, 0x8DD1, 0x8DD7, 0x8E20, 0x8E23, 0x8E3D, 0x8E70, - 0x8E7B, 0xD860 /*0xDE77*/, 0x8EC0, 0x4844, 0x8EFA, 0x8F1E, 0x8F2D, 0x8F36, - 0x8F54, 0xD860 /*0xDFCD*/, 0x8FA6, 0x8FB5, 0x8FE4, 0x8FE8, 0x8FEE, 0x9008, - 0x902D, 0xFA67, 0x9088, 0x9095, 0x9097, 0x9099, 0x909B, 0x90A2, - 0x90B3, 0x90BE, 0x90C4, 0x90C5, 0x90C7, 0x90D7, 0x90DD, 0x90DE, - 0x90EF, 0x90F4, 0xFA26, 0x9114, 0x9115, 0x9116, 0x9122, 0x9123, - 0x9127, 0x912F, 0x9131, 0x9134, 0x913D, 0x9148, 0x915B, 0x9183, - 0x919E, 0x91AC, 0x91B1, 0x91BC, 0x91D7, 0x91FB, 0x91E4, -}; -static const unsigned short euc_to_utf8_FD_x0213[] = { - 0x91E5, 0x91ED, 0x91F1, 0x9207, 0x9210, 0x9238, 0x9239, - 0x923A, 0x923C, 0x9240, 0x9243, 0x924F, 0x9278, 0x9288, 0x92C2, - 0x92CB, 0x92CC, 0x92D3, 0x92E0, 0x92FF, 0x9304, 0x931F, 0x9321, - 0x9325, 0x9348, 0x9349, 0x934A, 0x9364, 0x9365, 0x936A, 0x9370, - 0x939B, 0x93A3, 0x93BA, 0x93C6, 0x93DE, 0x93DF, 0x9404, 0x93FD, - 0x9433, 0x944A, 0x9463, 0x946B, 0x9471, 0x9472, 0x958E, 0x959F, - 0x95A6, 0x95A9, 0x95AC, 0x95B6, 0x95BD, 0x95CB, 0x95D0, 0x95D3, - 0x49B0, 0x95DA, 0x95DE, 0x9658, 0x9684, 0xF9DC, 0x969D, 0x96A4, - 0x96A5, 0x96D2, 0x96DE, 0xFA68, 0x96E9, 0x96EF, 0x9733, 0x973B, - 0x974D, 0x974E, 0x974F, 0x975A, 0x976E, 0x9773, 0x9795, 0x97AE, - 0x97BA, 0x97C1, 0x97C9, 0x97DE, 0x97DB, 0x97F4, 0xFA69, 0x980A, - 0x981E, 0x982B, 0x9830, 0xFA6A, 0x9852, 0x9853, 0x9856, -}; -static const unsigned short euc_to_utf8_FE_x0213[] = { - 0x9857, 0x9859, 0x985A, 0xF9D0, 0x9865, 0x986C, 0x98BA, - 0x98C8, 0x98E7, 0x9958, 0x999E, 0x9A02, 0x9A03, 0x9A24, 0x9A2D, - 0x9A2E, 0x9A38, 0x9A4A, 0x9A4E, 0x9A52, 0x9AB6, 0x9AC1, 0x9AC3, - 0x9ACE, 0x9AD6, 0x9AF9, 0x9B02, 0x9B08, 0x9B20, 0x4C17, 0x9B2D, - 0x9B5E, 0x9B79, 0x9B66, 0x9B72, 0x9B75, 0x9B84, 0x9B8A, 0x9B8F, - 0x9B9E, 0x9BA7, 0x9BC1, 0x9BCE, 0x9BE5, 0x9BF8, 0x9BFD, 0x9C00, - 0x9C23, 0x9C41, 0x9C4F, 0x9C50, 0x9C53, 0x9C63, 0x9C65, 0x9C77, - 0x9D1D, 0x9D1E, 0x9D43, 0x9D47, 0x9D52, 0x9D63, 0x9D70, 0x9D7C, - 0x9D8A, 0x9D96, 0x9DC0, 0x9DAC, 0x9DBC, 0x9DD7, 0xD868 /*0xDD90*/, 0x9DE7, - 0x9E07, 0x9E15, 0x9E7C, 0x9E9E, 0x9EA4, 0x9EAC, 0x9EAF, 0x9EB4, - 0x9EB5, 0x9EC3, 0x9ED1, 0x9F10, 0x9F39, 0x9F57, 0x9F90, 0x9F94, - 0x9F97, 0x9FA2, 0x59F8, 0x5C5B, 0x5E77, 0x7626, 0x7E6B, -}; - -static const unsigned short euc_to_utf8_8FA1_x0213[] = { - 0xD840 /*0xDC89*/, 0x4E02, 0x4E0F, 0x4E12, 0x4E29, 0x4E2B, 0x4E2E, - 0x4E40, 0x4E47, 0x4E48, 0xD840 /*0xDCA2*/, 0x4E51, 0x3406, 0xD840 /*0xDCA4*/, 0x4E5A, - 0x4E69, 0x4E9D, 0x342C, 0x342E, 0x4EB9, 0x4EBB, 0xD840 /*0xDDA2*/, 0x4EBC, - 0x4EC3, 0x4EC8, 0x4ED0, 0x4EEB, 0x4EDA, 0x4EF1, 0x4EF5, 0x4F00, - 0x4F16, 0x4F64, 0x4F37, 0x4F3E, 0x4F54, 0x4F58, 0xD840 /*0xDE13*/, 0x4F77, - 0x4F78, 0x4F7A, 0x4F7D, 0x4F82, 0x4F85, 0x4F92, 0x4F9A, 0x4FE6, - 0x4FB2, 0x4FBE, 0x4FC5, 0x4FCB, 0x4FCF, 0x4FD2, 0x346A, 0x4FF2, - 0x5000, 0x5010, 0x5013, 0x501C, 0x501E, 0x5022, 0x3468, 0x5042, - 0x5046, 0x504E, 0x5053, 0x5057, 0x5063, 0x5066, 0x506A, 0x5070, - 0x50A3, 0x5088, 0x5092, 0x5093, 0x5095, 0x5096, 0x509C, 0x50AA, - 0xD840 /*0xDF2B*/, 0x50B1, 0x50BA, 0x50BB, 0x50C4, 0x50C7, 0x50F3, 0xD840 /*0xDF81*/, - 0x50CE, 0xD840 /*0xDF71*/, 0x50D4, 0x50D9, 0x50E1, 0x50E9, 0x3492, -}; -static const unsigned short euc_to_utf8_8FA3_x0213[] = { - 0x5108, 0xD840 /*0xDFF9*/, 0x5117, 0x511B, 0xD841 /*0xDC4A*/, 0x5160, 0xD841 /*0xDD09*/, - 0x5173, 0x5183, 0x518B, 0x34BC, 0x5198, 0x51A3, 0x51AD, 0x34C7, - 0x51BC, 0xD841 /*0xDDD6*/, 0xD841 /*0xDE28*/, 0x51F3, 0x51F4, 0x5202, 0x5212, 0x5216, - 0xD841 /*0xDF4F*/, 0x5255, 0x525C, 0x526C, 0x5277, 0x5284, 0x5282, 0xD842 /*0xDC07*/, - 0x5298, 0xD842 /*0xDC3A*/, 0x52A4, 0x52A6, 0x52AF, 0x52BA, 0x52BB, 0x52CA, - 0x351F, 0x52D1, 0xD842 /*0xDCB9*/, 0x52F7, 0x530A, 0x530B, 0x5324, 0x5335, - 0x533E, 0x5342, 0xD842 /*0xDD7C*/, 0xD842 /*0xDD9D*/, 0x5367, 0x536C, 0x537A, 0x53A4, - 0x53B4, 0xD842 /*0xDED3*/, 0x53B7, 0x53C0, 0xD842 /*0xDF1D*/, 0x355D, 0x355E, 0x53D5, - 0x53DA, 0x3563, 0x53F4, 0x53F5, 0x5455, 0x5424, 0x5428, 0x356E, - 0x5443, 0x5462, 0x5466, 0x546C, 0x548A, 0x548D, 0x5495, 0x54A0, - 0x54A6, 0x54AD, 0x54AE, 0x54B7, 0x54BA, 0x54BF, 0x54C3, 0xD843 /*0xDD45*/, - 0x54EC, 0x54EF, 0x54F1, 0x54F3, 0x5500, 0x5501, 0x5509, -}; -static const unsigned short euc_to_utf8_8FA4_x0213[] = { - 0x553C, 0x5541, 0x35A6, 0x5547, 0x554A, 0x35A8, 0x5560, - 0x5561, 0x5564, 0xD843 /*0xDDE1*/, 0x557D, 0x5582, 0x5588, 0x5591, 0x35C5, - 0x55D2, 0xD843 /*0xDE95*/, 0xD843 /*0xDE6D*/, 0x55BF, 0x55C9, 0x55CC, 0x55D1, 0x55DD, - 0x35DA, 0x55E2, 0xD843 /*0xDE64*/, 0x55E9, 0x5628, 0xD843 /*0xDF5F*/, 0x5607, 0x5610, - 0x5630, 0x5637, 0x35F4, 0x563D, 0x563F, 0x5640, 0x5647, 0x565E, - 0x5660, 0x566D, 0x3605, 0x5688, 0x568C, 0x5695, 0x569A, 0x569D, - 0x56A8, 0x56AD, 0x56B2, 0x56C5, 0x56CD, 0x56DF, 0x56E8, 0x56F6, - 0x56F7, 0xD844 /*0xDE01*/, 0x5715, 0x5723, 0xD844 /*0xDE55*/, 0x5729, 0xD844 /*0xDE7B*/, 0x5745, - 0x5746, 0x574C, 0x574D, 0xD844 /*0xDE74*/, 0x5768, 0x576F, 0x5773, 0x5774, - 0x5775, 0x577B, 0xD844 /*0xDEE4*/, 0xD844 /*0xDED7*/, 0x57AC, 0x579A, 0x579D, 0x579E, - 0x57A8, 0x57D7, 0xD844 /*0xDEFD*/, 0x57CC, 0xD844 /*0xDF36*/, 0xD844 /*0xDF44*/, 0x57DE, 0x57E6, - 0x57F0, 0x364A, 0x57F8, 0x57FB, 0x57FD, 0x5804, 0x581E, -}; -static const unsigned short euc_to_utf8_8FA5_x0213[] = { - 0x5820, 0x5827, 0x5832, 0x5839, 0xD844 /*0xDFC4*/, 0x5849, 0x584C, - 0x5867, 0x588A, 0x588B, 0x588D, 0x588F, 0x5890, 0x5894, 0x589D, - 0x58AA, 0x58B1, 0xD845 /*0xDC6D*/, 0x58C3, 0x58CD, 0x58E2, 0x58F3, 0x58F4, - 0x5905, 0x5906, 0x590B, 0x590D, 0x5914, 0x5924, 0xD845 /*0xDDD7*/, 0x3691, - 0x593D, 0x3699, 0x5946, 0x3696, 0xD85B /*0xDC29*/, 0x595B, 0x595F, 0xD845 /*0xDE47*/, - 0x5975, 0x5976, 0x597C, 0x599F, 0x59AE, 0x59BC, 0x59C8, 0x59CD, - 0x59DE, 0x59E3, 0x59E4, 0x59E7, 0x59EE, 0xD845 /*0xDF06*/, 0xD845 /*0xDF42*/, 0x36CF, - 0x5A0C, 0x5A0D, 0x5A17, 0x5A27, 0x5A2D, 0x5A55, 0x5A65, 0x5A7A, - 0x5A8B, 0x5A9C, 0x5A9F, 0x5AA0, 0x5AA2, 0x5AB1, 0x5AB3, 0x5AB5, - 0x5ABA, 0x5ABF, 0x5ADA, 0x5ADC, 0x5AE0, 0x5AE5, 0x5AF0, 0x5AEE, - 0x5AF5, 0x5B00, 0x5B08, 0x5B17, 0x5B34, 0x5B2D, 0x5B4C, 0x5B52, - 0x5B68, 0x5B6F, 0x5B7C, 0x5B7F, 0x5B81, 0x5B84, 0xD846 /*0xDDC3*/, -}; -static const unsigned short euc_to_utf8_8FA8_x0213[] = { - 0x5B96, 0x5BAC, 0x3761, 0x5BC0, 0x3762, 0x5BCE, 0x5BD6, - 0x376C, 0x376B, 0x5BF1, 0x5BFD, 0x3775, 0x5C03, 0x5C29, 0x5C30, - 0xD847 /*0xDC56*/, 0x5C5F, 0x5C63, 0x5C67, 0x5C68, 0x5C69, 0x5C70, 0xD847 /*0xDD2D*/, - 0xD847 /*0xDD45*/, 0x5C7C, 0xD847 /*0xDD78*/, 0xD847 /*0xDD62*/, 0x5C88, 0x5C8A, 0x37C1, 0xD847 /*0xDDA1*/, - 0xD847 /*0xDD9C*/, 0x5CA0, 0x5CA2, 0x5CA6, 0x5CA7, 0xD847 /*0xDD92*/, 0x5CAD, 0x5CB5, - 0xD847 /*0xDDB7*/, 0x5CC9, 0xD847 /*0xDDE0*/, 0xD847 /*0xDE33*/, 0x5D06, 0x5D10, 0x5D2B, 0x5D1D, - 0x5D20, 0x5D24, 0x5D26, 0x5D31, 0x5D39, 0x5D42, 0x37E8, 0x5D61, - 0x5D6A, 0x37F4, 0x5D70, 0xD847 /*0xDF1E*/, 0x37FD, 0x5D88, 0x3800, 0x5D92, - 0x5D94, 0x5D97, 0x5D99, 0x5DB0, 0x5DB2, 0x5DB4, 0xD847 /*0xDF76*/, 0x5DB9, - 0x5DD1, 0x5DD7, 0x5DD8, 0x5DE0, 0xD847 /*0xDFFA*/, 0x5DE4, 0x5DE9, 0x382F, - 0x5E00, 0x3836, 0x5E12, 0x5E15, 0x3840, 0x5E1F, 0x5E2E, 0x5E3E, - 0x5E49, 0x385C, 0x5E56, 0x3861, 0x5E6B, 0x5E6C, 0x5E6D, -}; -static const unsigned short euc_to_utf8_8FAC_x0213[] = { - 0x5E6E, 0xD848 /*0xDD7B*/, 0x5EA5, 0x5EAA, 0x5EAC, 0x5EB9, 0x5EBF, - 0x5EC6, 0x5ED2, 0x5ED9, 0xD848 /*0xDF1E*/, 0x5EFD, 0x5F08, 0x5F0E, 0x5F1C, - 0xD848 /*0xDFAD*/, 0x5F1E, 0x5F47, 0x5F63, 0x5F72, 0x5F7E, 0x5F8F, 0x5FA2, - 0x5FA4, 0x5FB8, 0x5FC4, 0x38FA, 0x5FC7, 0x5FCB, 0x5FD2, 0x5FD3, - 0x5FD4, 0x5FE2, 0x5FEE, 0x5FEF, 0x5FF3, 0x5FFC, 0x3917, 0x6017, - 0x6022, 0x6024, 0x391A, 0x604C, 0x607F, 0x608A, 0x6095, 0x60A8, - 0xD849 /*0xDEF3*/, 0x60B0, 0x60B1, 0x60BE, 0x60C8, 0x60D9, 0x60DB, 0x60EE, - 0x60F2, 0x60F5, 0x6110, 0x6112, 0x6113, 0x6119, 0x611E, 0x613A, - 0x396F, 0x6141, 0x6146, 0x6160, 0x617C, 0xD84A /*0xDC5B*/, 0x6192, 0x6193, - 0x6197, 0x6198, 0x61A5, 0x61A8, 0x61AD, 0xD84A /*0xDCAB*/, 0x61D5, 0x61DD, - 0x61DF, 0x61F5, 0xD84A /*0xDD8F*/, 0x6215, 0x6223, 0x6229, 0x6246, 0x624C, - 0x6251, 0x6252, 0x6261, 0x6264, 0x627B, 0x626D, 0x6273, -}; -static const unsigned short euc_to_utf8_8FAD_x0213[] = { - 0x6299, 0x62A6, 0x62D5, 0xD84A /*0xDEB8*/, 0x62FD, 0x6303, 0x630D, - 0x6310, 0xD84A /*0xDF4F*/, 0xD84A /*0xDF50*/, 0x6332, 0x6335, 0x633B, 0x633C, 0x6341, - 0x6344, 0x634E, 0xD84A /*0xDF46*/, 0x6359, 0xD84B /*0xDC1D*/, 0xD84A /*0xDFA6*/, 0x636C, 0x6384, - 0x6399, 0xD84B /*0xDC24*/, 0x6394, 0x63BD, 0x63F7, 0x63D4, 0x63D5, 0x63DC, - 0x63E0, 0x63EB, 0x63EC, 0x63F2, 0x6409, 0x641E, 0x6425, 0x6429, - 0x642F, 0x645A, 0x645B, 0x645D, 0x6473, 0x647D, 0x6487, 0x6491, - 0x649D, 0x649F, 0x64CB, 0x64CC, 0x64D5, 0x64D7, 0xD84B /*0xDDE1*/, 0x64E4, - 0x64E5, 0x64FF, 0x6504, 0x3A6E, 0x650F, 0x6514, 0x6516, 0x3A73, - 0x651E, 0x6532, 0x6544, 0x6554, 0x656B, 0x657A, 0x6581, 0x6584, - 0x6585, 0x658A, 0x65B2, 0x65B5, 0x65B8, 0x65BF, 0x65C2, 0x65C9, - 0x65D4, 0x3AD6, 0x65F2, 0x65F9, 0x65FC, 0x6604, 0x6608, 0x6621, - 0x662A, 0x6645, 0x6651, 0x664E, 0x3AEA, 0xD84C /*0xDDC3*/, 0x6657, -}; -static const unsigned short euc_to_utf8_8FAE_x0213[] = { - 0x665B, 0x6663, 0xD84C /*0xDDF5*/, 0xD84C /*0xDDB6*/, 0x666A, 0x666B, 0x666C, - 0x666D, 0x667B, 0x6680, 0x6690, 0x6692, 0x6699, 0x3B0E, 0x66AD, - 0x66B1, 0x66B5, 0x3B1A, 0x66BF, 0x3B1C, 0x66EC, 0x3AD7, 0x6701, - 0x6705, 0x6712, 0xD84C /*0xDF72*/, 0x6719, 0xD84C /*0xDFD3*/, 0xD84C /*0xDFD2*/, 0x674C, 0x674D, - 0x6754, 0x675D, 0xD84C /*0xDFD0*/, 0xD84C /*0xDFE4*/, 0xD84C /*0xDFD5*/, 0x6774, 0x6776, 0xD84C /*0xDFDA*/, - 0x6792, 0xD84C /*0xDFDF*/, 0x8363, 0x6810, 0x67B0, 0x67B2, 0x67C3, 0x67C8, - 0x67D2, 0x67D9, 0x67DB, 0x67F0, 0x67F7, 0xD84D /*0xDC4A*/, 0xD84D /*0xDC51*/, 0xD84D /*0xDC4B*/, - 0x6818, 0x681F, 0x682D, 0xD84D /*0xDC65*/, 0x6833, 0x683B, 0x683E, 0x6844, - 0x6845, 0x6849, 0x684C, 0x6855, 0x6857, 0x3B77, 0x686B, 0x686E, - 0x687A, 0x687C, 0x6882, 0x6890, 0x6896, 0x3B6D, 0x6898, 0x6899, - 0x689A, 0x689C, 0x68AA, 0x68AB, 0x68B4, 0x68BB, 0x68FB, 0xD84D /*0xDCE4*/, - 0xD84D /*0xDD5A*/, 0xFA13, 0x68C3, 0x68C5, 0x68CC, 0x68CF, 0x68D6, -}; -static const unsigned short euc_to_utf8_8FAF_x0213[] = { - 0x68D9, 0x68E4, 0x68E5, 0x68EC, 0x68F7, 0x6903, 0x6907, - 0x3B87, 0x3B88, 0xD84D /*0xDD94*/, 0x693B, 0x3B8D, 0x6946, 0x6969, 0x696C, - 0x6972, 0x697A, 0x697F, 0x6992, 0x3BA4, 0x6996, 0x6998, 0x69A6, - 0x69B0, 0x69B7, 0x69BA, 0x69BC, 0x69C0, 0x69D1, 0x69D6, 0xD84D /*0xDE39*/, - 0xD84D /*0xDE47*/, 0x6A30, 0xD84D /*0xDE38*/, 0xD84D /*0xDE3A*/, 0x69E3, 0x69EE, 0x69EF, 0x69F3, - 0x3BCD, 0x69F4, 0x69FE, 0x6A11, 0x6A1A, 0x6A1D, 0xD84D /*0xDF1C*/, 0x6A32, - 0x6A33, 0x6A34, 0x6A3F, 0x6A46, 0x6A49, 0x6A7A, 0x6A4E, 0x6A52, - 0x6A64, 0xD84D /*0xDF0C*/, 0x6A7E, 0x6A83, 0x6A8B, 0x3BF0, 0x6A91, 0x6A9F, - 0x6AA1, 0xD84D /*0xDF64*/, 0x6AAB, 0x6ABD, 0x6AC6, 0x6AD4, 0x6AD0, 0x6ADC, - 0x6ADD, 0xD84D /*0xDFFF*/, 0xD84D /*0xDFE7*/, 0x6AEC, 0x6AF1, 0x6AF2, 0x6AF3, 0x6AFD, - 0xD84E /*0xDC24*/, 0x6B0B, 0x6B0F, 0x6B10, 0x6B11, 0xD84E /*0xDC3D*/, 0x6B17, 0x3C26, - 0x6B2F, 0x6B4A, 0x6B58, 0x6B6C, 0x6B75, 0x6B7A, 0x6B81, -}; -static const unsigned short euc_to_utf8_8FEE_x0213[] = { - 0x6B9B, 0x6BAE, 0xD84E /*0xDE98*/, 0x6BBD, 0x6BBE, 0x6BC7, 0x6BC8, - 0x6BC9, 0x6BDA, 0x6BE6, 0x6BE7, 0x6BEE, 0x6BF1, 0x6C02, 0x6C0A, - 0x6C0E, 0x6C35, 0x6C36, 0x6C3A, 0xD84F /*0xDC7F*/, 0x6C3F, 0x6C4D, 0x6C5B, - 0x6C6D, 0x6C84, 0x6C89, 0x3CC3, 0x6C94, 0x6C95, 0x6C97, 0x6CAD, - 0x6CC2, 0x6CD0, 0x3CD2, 0x6CD6, 0x6CDA, 0x6CDC, 0x6CE9, 0x6CEC, - 0x6CED, 0xD84F /*0xDD00*/, 0x6D00, 0x6D0A, 0x6D24, 0x6D26, 0x6D27, 0x6C67, - 0x6D2F, 0x6D3C, 0x6D5B, 0x6D5E, 0x6D60, 0x6D70, 0x6D80, 0x6D81, - 0x6D8A, 0x6D8D, 0x6D91, 0x6D98, 0xD84F /*0xDD40*/, 0x6E17, 0xD84F /*0xDDFA*/, 0xD84F /*0xDDF9*/, - 0xD84F /*0xDDD3*/, 0x6DAB, 0x6DAE, 0x6DB4, 0x6DC2, 0x6D34, 0x6DC8, 0x6DCE, - 0x6DCF, 0x6DD0, 0x6DDF, 0x6DE9, 0x6DF6, 0x6E36, 0x6E1E, 0x6E22, - 0x6E27, 0x3D11, 0x6E32, 0x6E3C, 0x6E48, 0x6E49, 0x6E4B, 0x6E4C, - 0x6E4F, 0x6E51, 0x6E53, 0x6E54, 0x6E57, 0x6E63, 0x3D1E, -}; -static const unsigned short euc_to_utf8_8FEF_x0213[] = { - 0x6E93, 0x6EA7, 0x6EB4, 0x6EBF, 0x6EC3, 0x6ECA, 0x6ED9, - 0x6F35, 0x6EEB, 0x6EF9, 0x6EFB, 0x6F0A, 0x6F0C, 0x6F18, 0x6F25, - 0x6F36, 0x6F3C, 0xD84F /*0xDF7E*/, 0x6F52, 0x6F57, 0x6F5A, 0x6F60, 0x6F68, - 0x6F98, 0x6F7D, 0x6F90, 0x6F96, 0x6FBE, 0x6F9F, 0x6FA5, 0x6FAF, - 0x3D64, 0x6FB5, 0x6FC8, 0x6FC9, 0x6FDA, 0x6FDE, 0x6FE9, 0xD850 /*0xDC96*/, - 0x6FFC, 0x7000, 0x7007, 0x700A, 0x7023, 0xD850 /*0xDD03*/, 0x7039, 0x703A, - 0x703C, 0x7043, 0x7047, 0x704B, 0x3D9A, 0x7054, 0x7065, 0x7069, - 0x706C, 0x706E, 0x7076, 0x707E, 0x7081, 0x7086, 0x7095, 0x7097, - 0x70BB, 0xD850 /*0xDDC6*/, 0x709F, 0x70B1, 0xD850 /*0xDDFE*/, 0x70EC, 0x70CA, 0x70D1, - 0x70D3, 0x70DC, 0x7103, 0x7104, 0x7106, 0x7107, 0x7108, 0x710C, - 0x3DC0, 0x712F, 0x7131, 0x7150, 0x714A, 0x7153, 0x715E, 0x3DD4, - 0x7196, 0x7180, 0x719B, 0x71A0, 0x71A2, 0x71AE, 0x71AF, -}; -static const unsigned short euc_to_utf8_8FF0_x0213[] = { - 0x71B3, 0xD850 /*0xDFBC*/, 0x71CB, 0x71D3, 0x71D9, 0x71DC, 0x7207, - 0x3E05, 0xFA49, 0x722B, 0x7234, 0x7238, 0x7239, 0x4E2C, 0x7242, - 0x7253, 0x7257, 0x7263, 0xD851 /*0xDE29*/, 0x726E, 0x726F, 0x7278, 0x727F, - 0x728E, 0xD851 /*0xDEA5*/, 0x72AD, 0x72AE, 0x72B0, 0x72B1, 0x72C1, 0x3E60, - 0x72CC, 0x3E66, 0x3E68, 0x72F3, 0x72FA, 0x7307, 0x7312, 0x7318, - 0x7319, 0x3E83, 0x7339, 0x732C, 0x7331, 0x7333, 0x733D, 0x7352, - 0x3E94, 0x736B, 0x736C, 0xD852 /*0xDC96*/, 0x736E, 0x736F, 0x7371, 0x7377, - 0x7381, 0x7385, 0x738A, 0x7394, 0x7398, 0x739C, 0x739E, 0x73A5, - 0x73A8, 0x73B5, 0x73B7, 0x73B9, 0x73BC, 0x73BF, 0x73C5, 0x73CB, - 0x73E1, 0x73E7, 0x73F9, 0x7413, 0x73FA, 0x7401, 0x7424, 0x7431, - 0x7439, 0x7453, 0x7440, 0x7443, 0x744D, 0x7452, 0x745D, 0x7471, - 0x7481, 0x7485, 0x7488, 0xD852 /*0xDE4D*/, 0x7492, 0x7497, 0x7499, -}; -static const unsigned short euc_to_utf8_8FF1_x0213[] = { - 0x74A0, 0x74A1, 0x74A5, 0x74AA, 0x74AB, 0x74B9, 0x74BB, - 0x74BA, 0x74D6, 0x74D8, 0x74DE, 0x74EF, 0x74EB, 0xD852 /*0xDF56*/, 0x74FA, - 0xD852 /*0xDF6F*/, 0x7520, 0x7524, 0x752A, 0x3F57, 0xD853 /*0xDC16*/, 0x753D, 0x753E, - 0x7540, 0x7548, 0x754E, 0x7550, 0x7552, 0x756C, 0x7572, 0x7571, - 0x757A, 0x757D, 0x757E, 0x7581, 0xD853 /*0xDD14*/, 0x758C, 0x3F75, 0x75A2, - 0x3F77, 0x75B0, 0x75B7, 0x75BF, 0x75C0, 0x75C6, 0x75CF, 0x75D3, - 0x75DD, 0x75DF, 0x75E0, 0x75E7, 0x75EC, 0x75EE, 0x75F1, 0x75F9, - 0x7603, 0x7618, 0x7607, 0x760F, 0x3FAE, 0xD853 /*0xDE0E*/, 0x7613, 0x761B, - 0x761C, 0xD853 /*0xDE37*/, 0x7625, 0x7628, 0x763C, 0x7633, 0xD853 /*0xDE6A*/, 0x3FC9, - 0x7641, 0xD853 /*0xDE8B*/, 0x7649, 0x7655, 0x3FD7, 0x766E, 0x7695, 0x769C, - 0x76A1, 0x76A0, 0x76A7, 0x76A8, 0x76AF, 0xD854 /*0xDC4A*/, 0x76C9, 0xD854 /*0xDC55*/, - 0x76E8, 0x76EC, 0xD854 /*0xDD22*/, 0x7717, 0x771A, 0x772D, 0x7735, -}; -static const unsigned short euc_to_utf8_8FF2_x0213[] = { - 0xD854 /*0xDDA9*/, 0x4039, 0xD854 /*0xDDE5*/, 0xD854 /*0xDDCD*/, 0x7758, 0x7760, 0x776A, - 0xD854 /*0xDE1E*/, 0x7772, 0x777C, 0x777D, 0xD854 /*0xDE4C*/, 0x4058, 0x779A, 0x779F, - 0x77A2, 0x77A4, 0x77A9, 0x77DE, 0x77DF, 0x77E4, 0x77E6, 0x77EA, - 0x77EC, 0x4093, 0x77F0, 0x77F4, 0x77FB, 0xD855 /*0xDC2E*/, 0x7805, 0x7806, - 0x7809, 0x780D, 0x7819, 0x7821, 0x782C, 0x7847, 0x7864, 0x786A, - 0xD855 /*0xDCD9*/, 0x788A, 0x7894, 0x78A4, 0x789D, 0x789E, 0x789F, 0x78BB, - 0x78C8, 0x78CC, 0x78CE, 0x78D5, 0x78E0, 0x78E1, 0x78E6, 0x78F9, - 0x78FA, 0x78FB, 0x78FE, 0xD855 /*0xDDA7*/, 0x7910, 0x791B, 0x7930, 0x7925, - 0x793B, 0x794A, 0x7958, 0x795B, 0x4105, 0x7967, 0x7972, 0x7994, - 0x7995, 0x7996, 0x799B, 0x79A1, 0x79A9, 0x79B4, 0x79BB, 0x79C2, - 0x79C7, 0x79CC, 0x79CD, 0x79D6, 0x4148, 0xD855 /*0xDFA9*/, 0xD855 /*0xDFB4*/, 0x414F, - 0x7A0A, 0x7A11, 0x7A15, 0x7A1B, 0x7A1E, 0x4163, 0x7A2D, -}; -static const unsigned short euc_to_utf8_8FF3_x0213[] = { - 0x7A38, 0x7A47, 0x7A4C, 0x7A56, 0x7A59, 0x7A5C, 0x7A5F, - 0x7A60, 0x7A67, 0x7A6A, 0x7A75, 0x7A78, 0x7A82, 0x7A8A, 0x7A90, - 0x7AA3, 0x7AAC, 0xD856 /*0xDDD4*/, 0x41B4, 0x7AB9, 0x7ABC, 0x7ABE, 0x41BF, - 0x7ACC, 0x7AD1, 0x7AE7, 0x7AE8, 0x7AF4, 0xD856 /*0xDEE4*/, 0xD856 /*0xDEE3*/, 0x7B07, - 0xD856 /*0xDEF1*/, 0x7B3D, 0x7B27, 0x7B2A, 0x7B2E, 0x7B2F, 0x7B31, 0x41E6, - 0x41F3, 0x7B7F, 0x7B41, 0x41EE, 0x7B55, 0x7B79, 0x7B64, 0x7B66, - 0x7B69, 0x7B73, 0xD856 /*0xDFB2*/, 0x4207, 0x7B90, 0x7B91, 0x7B9B, 0x420E, - 0x7BAF, 0x7BB5, 0x7BBC, 0x7BC5, 0x7BCA, 0xD857 /*0xDC4B*/, 0xD857 /*0xDC64*/, 0x7BD4, - 0x7BD6, 0x7BDA, 0x7BEA, 0x7BF0, 0x7C03, 0x7C0B, 0x7C0E, 0x7C0F, - 0x7C26, 0x7C45, 0x7C4A, 0x7C51, 0x7C57, 0x7C5E, 0x7C61, 0x7C69, - 0x7C6E, 0x7C6F, 0x7C70, 0xD857 /*0xDE2E*/, 0xD857 /*0xDE56*/, 0xD857 /*0xDE65*/, 0x7CA6, 0xD857 /*0xDE62*/, - 0x7CB6, 0x7CB7, 0x7CBF, 0xD857 /*0xDED8*/, 0x7CC4, 0xD857 /*0xDEC2*/, 0x7CC8, -}; -static const unsigned short euc_to_utf8_8FF4_x0213[] = { - 0x7CCD, 0xD857 /*0xDEE8*/, 0x7CD7, 0xD857 /*0xDF23*/, 0x7CE6, 0x7CEB, 0xD857 /*0xDF5C*/, - 0x7CF5, 0x7D03, 0x7D09, 0x42C6, 0x7D12, 0x7D1E, 0xD857 /*0xDFE0*/, 0xD857 /*0xDFD4*/, - 0x7D3D, 0x7D3E, 0x7D40, 0x7D47, 0xD858 /*0xDC0C*/, 0xD857 /*0xDFFB*/, 0x42D6, 0x7D59, - 0x7D5A, 0x7D6A, 0x7D70, 0x42DD, 0x7D7F, 0xD858 /*0xDC17*/, 0x7D86, 0x7D88, - 0x7D8C, 0x7D97, 0xD858 /*0xDC60*/, 0x7D9D, 0x7DA7, 0x7DAA, 0x7DB6, 0x7DB7, - 0x7DC0, 0x7DD7, 0x7DD9, 0x7DE6, 0x7DF1, 0x7DF9, 0x4302, 0xD858 /*0xDCED*/, - 0xFA58, 0x7E10, 0x7E17, 0x7E1D, 0x7E20, 0x7E27, 0x7E2C, 0x7E45, - 0x7E73, 0x7E75, 0x7E7E, 0x7E86, 0x7E87, 0x432B, 0x7E91, 0x7E98, - 0x7E9A, 0x4343, 0x7F3C, 0x7F3B, 0x7F3E, 0x7F43, 0x7F44, 0x7F4F, - 0x34C1, 0xD858 /*0xDE70*/, 0x7F52, 0xD858 /*0xDE86*/, 0x7F61, 0x7F63, 0x7F64, 0x7F6D, - 0x7F7D, 0x7F7E, 0xD858 /*0xDF4C*/, 0x7F90, 0x517B, 0xD84F /*0xDD0E*/, 0x7F96, 0x7F9C, - 0x7FAD, 0xD859 /*0xDC02*/, 0x7FC3, 0x7FCF, 0x7FE3, 0x7FE5, 0x7FEF, -}; -static const unsigned short euc_to_utf8_8FF5_x0213[] = { - 0x7FF2, 0x8002, 0x800A, 0x8008, 0x800E, 0x8011, 0x8016, - 0x8024, 0x802C, 0x8030, 0x8043, 0x8066, 0x8071, 0x8075, 0x807B, - 0x8099, 0x809C, 0x80A4, 0x80A7, 0x80B8, 0xD859 /*0xDE7E*/, 0x80C5, 0x80D5, - 0x80D8, 0x80E6, 0xD859 /*0xDEB0*/, 0x810D, 0x80F5, 0x80FB, 0x43EE, 0x8135, - 0x8116, 0x811E, 0x43F0, 0x8124, 0x8127, 0x812C, 0xD859 /*0xDF1D*/, 0x813D, - 0x4408, 0x8169, 0x4417, 0x8181, 0x441C, 0x8184, 0x8185, 0x4422, - 0x8198, 0x81B2, 0x81C1, 0x81C3, 0x81D6, 0x81DB, 0xD85A /*0xDCDD*/, 0x81E4, - 0xD85A /*0xDCEA*/, 0x81EC, 0xD85A /*0xDD51*/, 0x81FD, 0x81FF, 0xD85A /*0xDD6F*/, 0x8204, 0xD85A /*0xDDDD*/, - 0x8219, 0x8221, 0x8222, 0xD85A /*0xDE1E*/, 0x8232, 0x8234, 0x823C, 0x8246, - 0x8249, 0x8245, 0xD85A /*0xDE58*/, 0x824B, 0x4476, 0x824F, 0x447A, 0x8257, - 0xD85A /*0xDE8C*/, 0x825C, 0x8263, 0xD85A /*0xDEB7*/, 0xFA5D, 0xFA5E, 0x8279, 0x4491, - 0x827D, 0x827F, 0x8283, 0x828A, 0x8293, 0x82A7, 0x82A8, -}; -static const unsigned short euc_to_utf8_8FF6_x0213[] = { - 0x82B2, 0x82B4, 0x82BA, 0x82BC, 0x82E2, 0x82E8, 0x82F7, - 0x8307, 0x8308, 0x830C, 0x8354, 0x831B, 0x831D, 0x8330, 0x833C, - 0x8344, 0x8357, 0x44BE, 0x837F, 0x44D4, 0x44B3, 0x838D, 0x8394, - 0x8395, 0x839B, 0x839D, 0x83C9, 0x83D0, 0x83D4, 0x83DD, 0x83E5, - 0x83F9, 0x840F, 0x8411, 0x8415, 0xD85B /*0xDC73*/, 0x8417, 0x8439, 0x844A, - 0x844F, 0x8451, 0x8452, 0x8459, 0x845A, 0x845C, 0xD85B /*0xDCDD*/, 0x8465, - 0x8476, 0x8478, 0x847C, 0x8481, 0x450D, 0x84DC, 0x8497, 0x84A6, - 0x84BE, 0x4508, 0x84CE, 0x84CF, 0x84D3, 0xD85B /*0xDE65*/, 0x84E7, 0x84EA, - 0x84EF, 0x84F0, 0x84F1, 0x84FA, 0x84FD, 0x850C, 0x851B, 0x8524, - 0x8525, 0x852B, 0x8534, 0x854F, 0x856F, 0x4525, 0x4543, 0x853E, - 0x8551, 0x8553, 0x855E, 0x8561, 0x8562, 0xD85B /*0xDF94*/, 0x857B, 0x857D, - 0x857F, 0x8581, 0x8586, 0x8593, 0x859D, 0x859F, 0xD85B /*0xDFF8*/, -}; -static const unsigned short euc_to_utf8_8FF7_x0213[] = { - 0xD85B /*0xDFF6*/, 0xD85B /*0xDFF7*/, 0x85B7, 0x85BC, 0x85C7, 0x85CA, 0x85D8, - 0x85D9, 0x85DF, 0x85E1, 0x85E6, 0x85F6, 0x8600, 0x8611, 0x861E, - 0x8621, 0x8624, 0x8627, 0xD85C /*0xDD0D*/, 0x8639, 0x863C, 0xD85C /*0xDD39*/, 0x8640, - 0xFA20, 0x8653, 0x8656, 0x866F, 0x8677, 0x867A, 0x8687, 0x8689, - 0x868D, 0x8691, 0x869C, 0x869D, 0x86A8, 0xFA21, 0x86B1, 0x86B3, - 0x86C1, 0x86C3, 0x86D1, 0x86D5, 0x86D7, 0x86E3, 0x86E6, 0x45B8, - 0x8705, 0x8707, 0x870E, 0x8710, 0x8713, 0x8719, 0x871F, 0x8721, - 0x8723, 0x8731, 0x873A, 0x873E, 0x8740, 0x8743, 0x8751, 0x8758, - 0x8764, 0x8765, 0x8772, 0x877C, 0xD85C /*0xDFDB*/, 0xD85C /*0xDFDA*/, 0x87A7, 0x8789, - 0x878B, 0x8793, 0x87A0, 0xD85C /*0xDFFE*/, 0x45E5, 0x87BE, 0xD85D /*0xDC10*/, 0x87C1, - 0x87CE, 0x87F5, 0x87DF, 0xD85D /*0xDC49*/, 0x87E3, 0x87E5, 0x87E6, 0x87EA, - 0x87EB, 0x87ED, 0x8801, 0x8803, 0x880B, 0x8813, 0x8828, -}; -static const unsigned short euc_to_utf8_8FF8_x0213[] = { - 0x882E, 0x8832, 0x883C, 0x460F, 0x884A, 0x8858, 0x885F, - 0x8864, 0xD85D /*0xDE15*/, 0xD85D /*0xDE14*/, 0x8869, 0xD85D /*0xDE31*/, 0x886F, 0x88A0, 0x88BC, - 0x88BD, 0x88BE, 0x88C0, 0x88D2, 0xD85D /*0xDE93*/, 0x88D1, 0x88D3, 0x88DB, - 0x88F0, 0x88F1, 0x4641, 0x8901, 0xD85D /*0xDF0E*/, 0x8937, 0xD85D /*0xDF23*/, 0x8942, - 0x8945, 0x8949, 0xD85D /*0xDF52*/, 0x4665, 0x8962, 0x8980, 0x8989, 0x8990, - 0x899F, 0x89B0, 0x89B7, 0x89D6, 0x89D8, 0x89EB, 0x46A1, 0x89F1, - 0x89F3, 0x89FD, 0x89FF, 0x46AF, 0x8A11, 0x8A14, 0xD85E /*0xDD85*/, 0x8A21, - 0x8A35, 0x8A3E, 0x8A45, 0x8A4D, 0x8A58, 0x8AAE, 0x8A90, 0x8AB7, - 0x8ABE, 0x8AD7, 0x8AFC, 0xD85E /*0xDE84*/, 0x8B0A, 0x8B05, 0x8B0D, 0x8B1C, - 0x8B1F, 0x8B2D, 0x8B43, 0x470C, 0x8B51, 0x8B5E, 0x8B76, 0x8B7F, - 0x8B81, 0x8B8B, 0x8B94, 0x8B95, 0x8B9C, 0x8B9E, 0x8C39, 0xD85E /*0xDFB3*/, - 0x8C3D, 0xD85E /*0xDFBE*/, 0xD85E /*0xDFC7*/, 0x8C45, 0x8C47, 0x8C4F, 0x8C54, -}; -static const unsigned short euc_to_utf8_8FF9_x0213[] = { - 0x8C57, 0x8C69, 0x8C6D, 0x8C73, 0xD85F /*0xDCB8*/, 0x8C93, 0x8C92, - 0x8C99, 0x4764, 0x8C9B, 0x8CA4, 0x8CD6, 0x8CD5, 0x8CD9, 0xD85F /*0xDDA0*/, - 0x8CF0, 0x8CF1, 0xD85F /*0xDE10*/, 0x8D09, 0x8D0E, 0x8D6C, 0x8D84, 0x8D95, - 0x8DA6, 0xD85F /*0xDFB7*/, 0x8DC6, 0x8DC8, 0x8DD9, 0x8DEC, 0x8E0C, 0x47FD, - 0x8DFD, 0x8E06, 0xD860 /*0xDC8A*/, 0x8E14, 0x8E16, 0x8E21, 0x8E22, 0x8E27, - 0xD860 /*0xDCBB*/, 0x4816, 0x8E36, 0x8E39, 0x8E4B, 0x8E54, 0x8E62, 0x8E6C, - 0x8E6D, 0x8E6F, 0x8E98, 0x8E9E, 0x8EAE, 0x8EB3, 0x8EB5, 0x8EB6, - 0x8EBB, 0xD860 /*0xDE82*/, 0x8ED1, 0x8ED4, 0x484E, 0x8EF9, 0xD860 /*0xDEF3*/, 0x8F00, - 0x8F08, 0x8F17, 0x8F2B, 0x8F40, 0x8F4A, 0x8F58, 0xD861 /*0xDC0C*/, 0x8FA4, - 0x8FB4, 0xFA66, 0x8FB6, 0xD861 /*0xDC55*/, 0x8FC1, 0x8FC6, 0xFA24, 0x8FCA, - 0x8FCD, 0x8FD3, 0x8FD5, 0x8FE0, 0x8FF1, 0x8FF5, 0x8FFB, 0x9002, - 0x900C, 0x9037, 0xD861 /*0xDD6B*/, 0x9043, 0x9044, 0x905D, 0xD861 /*0xDDC8*/, -}; -static const unsigned short euc_to_utf8_8FFA_x0213[] = { - 0xD861 /*0xDDC9*/, 0x9085, 0x908C, 0x9090, 0x961D, 0x90A1, 0x48B5, - 0x90B0, 0x90B6, 0x90C3, 0x90C8, 0xD861 /*0xDED7*/, 0x90DC, 0x90DF, 0xD861 /*0xDEFA*/, - 0x90F6, 0x90F2, 0x9100, 0x90EB, 0x90FE, 0x90FF, 0x9104, 0x9106, - 0x9118, 0x911C, 0x911E, 0x9137, 0x9139, 0x913A, 0x9146, 0x9147, - 0x9157, 0x9159, 0x9161, 0x9164, 0x9174, 0x9179, 0x9185, 0x918E, - 0x91A8, 0x91AE, 0x91B3, 0x91B6, 0x91C3, 0x91C4, 0x91DA, 0xD862 /*0xDD49*/, - 0xD862 /*0xDD46*/, 0x91EC, 0x91EE, 0x9201, 0x920A, 0x9216, 0x9217, 0xD862 /*0xDD6B*/, - 0x9233, 0x9242, 0x9247, 0x924A, 0x924E, 0x9251, 0x9256, 0x9259, - 0x9260, 0x9261, 0x9265, 0x9267, 0x9268, 0xD862 /*0xDD87*/, 0xD862 /*0xDD88*/, 0x927C, - 0x927D, 0x927F, 0x9289, 0x928D, 0x9297, 0x9299, 0x929F, 0x92A7, - 0x92AB, 0xD862 /*0xDDBA*/, 0xD862 /*0xDDBB*/, 0x92B2, 0x92BF, 0x92C0, 0x92C6, 0x92CE, - 0x92D0, 0x92D7, 0x92D9, 0x92E5, 0x92E7, 0x9311, 0xD862 /*0xDE1E*/, -}; -static const unsigned short euc_to_utf8_8FFB_x0213[] = { - 0xD862 /*0xDE29*/, 0x92F7, 0x92F9, 0x92FB, 0x9302, 0x930D, 0x9315, - 0x931D, 0x931E, 0x9327, 0x9329, 0xD862 /*0xDE71*/, 0xD862 /*0xDE43*/, 0x9347, 0x9351, - 0x9357, 0x935A, 0x936B, 0x9371, 0x9373, 0x93A1, 0xD862 /*0xDE99*/, 0xD862 /*0xDECD*/, - 0x9388, 0x938B, 0x938F, 0x939E, 0x93F5, 0xD862 /*0xDEE4*/, 0xD862 /*0xDEDD*/, 0x93F1, - 0x93C1, 0x93C7, 0x93DC, 0x93E2, 0x93E7, 0x9409, 0x940F, 0x9416, - 0x9417, 0x93FB, 0x9432, 0x9434, 0x943B, 0x9445, 0xD862 /*0xDFC1*/, 0xD862 /*0xDFEF*/, - 0x946D, 0x946F, 0x9578, 0x9579, 0x9586, 0x958C, 0x958D, 0xD863 /*0xDD10*/, - 0x95AB, 0x95B4, 0xD863 /*0xDD71*/, 0x95C8, 0xD863 /*0xDDFB*/, 0xD863 /*0xDE1F*/, 0x962C, 0x9633, - 0x9634, 0xD863 /*0xDE36*/, 0x963C, 0x9641, 0x9661, 0xD863 /*0xDE89*/, 0x9682, 0xD863 /*0xDEEB*/, - 0x969A, 0xD863 /*0xDF32*/, 0x49E7, 0x96A9, 0x96AF, 0x96B3, 0x96BA, 0x96BD, - 0x49FA, 0xD863 /*0xDFF8*/, 0x96D8, 0x96DA, 0x96DD, 0x4A04, 0x9714, 0x9723, - 0x4A29, 0x9736, 0x9741, 0x9747, 0x9755, 0x9757, 0x975B, -}; -static const unsigned short euc_to_utf8_8FFC_x0213[] = { - 0x976A, 0xD864 /*0xDEA0*/, 0xD864 /*0xDEB1*/, 0x9796, 0x979A, 0x979E, 0x97A2, - 0x97B1, 0x97B2, 0x97BE, 0x97CC, 0x97D1, 0x97D4, 0x97D8, 0x97D9, - 0x97E1, 0x97F1, 0x9804, 0x980D, 0x980E, 0x9814, 0x9816, 0x4ABC, - 0xD865 /*0xDC90*/, 0x9823, 0x9832, 0x9833, 0x9825, 0x9847, 0x9866, 0x98AB, - 0x98AD, 0x98B0, 0xD865 /*0xDDCF*/, 0x98B7, 0x98B8, 0x98BB, 0x98BC, 0x98BF, - 0x98C2, 0x98C7, 0x98CB, 0x98E0, 0xD865 /*0xDE7F*/, 0x98E1, 0x98E3, 0x98E5, - 0x98EA, 0x98F0, 0x98F1, 0x98F3, 0x9908, 0x4B3B, 0xD865 /*0xDEF0*/, 0x9916, - 0x9917, 0xD865 /*0xDF19*/, 0x991A, 0x991B, 0x991C, 0xD865 /*0xDF50*/, 0x9931, 0x9932, - 0x9933, 0x993A, 0x993B, 0x993C, 0x9940, 0x9941, 0x9946, 0x994D, - 0x994E, 0x995C, 0x995F, 0x9960, 0x99A3, 0x99A6, 0x99B9, 0x99BD, - 0x99BF, 0x99C3, 0x99C9, 0x99D4, 0x99D9, 0x99DE, 0xD866 /*0xDCC6*/, 0x99F0, - 0x99F9, 0x99FC, 0x9A0A, 0x9A11, 0x9A16, 0x9A1A, 0x9A20, -}; -static const unsigned short euc_to_utf8_8FFD_x0213[] = { - 0x9A31, 0x9A36, 0x9A44, 0x9A4C, 0x9A58, 0x4BC2, 0x9AAF, - 0x4BCA, 0x9AB7, 0x4BD2, 0x9AB9, 0xD866 /*0xDE72*/, 0x9AC6, 0x9AD0, 0x9AD2, - 0x9AD5, 0x4BE8, 0x9ADC, 0x9AE0, 0x9AE5, 0x9AE9, 0x9B03, 0x9B0C, - 0x9B10, 0x9B12, 0x9B16, 0x9B1C, 0x9B2B, 0x9B33, 0x9B3D, 0x4C20, - 0x9B4B, 0x9B63, 0x9B65, 0x9B6B, 0x9B6C, 0x9B73, 0x9B76, 0x9B77, - 0x9BA6, 0x9BAC, 0x9BB1, 0xD867 /*0xDDDB*/, 0xD867 /*0xDE3D*/, 0x9BB2, 0x9BB8, 0x9BBE, - 0x9BC7, 0x9BF3, 0x9BD8, 0x9BDD, 0x9BE7, 0x9BEA, 0x9BEB, 0x9BEF, - 0x9BEE, 0xD867 /*0xDE15*/, 0x9BFA, 0xD867 /*0xDE8A*/, 0x9BF7, 0xD867 /*0xDE49*/, 0x9C16, 0x9C18, - 0x9C19, 0x9C1A, 0x9C1D, 0x9C22, 0x9C27, 0x9C29, 0x9C2A, 0xD867 /*0xDEC4*/, - 0x9C31, 0x9C36, 0x9C37, 0x9C45, 0x9C5C, 0xD867 /*0xDEE9*/, 0x9C49, 0x9C4A, - 0xD867 /*0xDEDB*/, 0x9C54, 0x9C58, 0x9C5B, 0x9C5D, 0x9C5F, 0x9C69, 0x9C6A, - 0x9C6B, 0x9C6D, 0x9C6E, 0x9C70, 0x9C72, 0x9C75, 0x9C7A, -}; -static const unsigned short euc_to_utf8_8FFE_x0213[] = { - 0x9CE6, 0x9CF2, 0x9D0B, 0x9D02, 0xD867 /*0xDFCE*/, 0x9D11, 0x9D17, - 0x9D18, 0xD868 /*0xDC2F*/, 0x4CC4, 0xD868 /*0xDC1A*/, 0x9D32, 0x4CD1, 0x9D42, 0x9D4A, - 0x9D5F, 0x9D62, 0xD868 /*0xDCF9*/, 0x9D69, 0x9D6B, 0xD868 /*0xDC82*/, 0x9D73, 0x9D76, - 0x9D77, 0x9D7E, 0x9D84, 0x9D8D, 0x9D99, 0x9DA1, 0x9DBF, 0x9DB5, - 0x9DB9, 0x9DBD, 0x9DC3, 0x9DC7, 0x9DC9, 0x9DD6, 0x9DDA, 0x9DDF, - 0x9DE0, 0x9DE3, 0x9DF4, 0x4D07, 0x9E0A, 0x9E02, 0x9E0D, 0x9E19, - 0x9E1C, 0x9E1D, 0x9E7B, 0xD848 /*0xDE18*/, 0x9E80, 0x9E85, 0x9E9B, 0x9EA8, - 0xD868 /*0xDF8C*/, 0x9EBD, 0xD869 /*0xDC37*/, 0x9EDF, 0x9EE7, 0x9EEE, 0x9EFF, 0x9F02, - 0x4D77, 0x9F03, 0x9F17, 0x9F19, 0x9F2F, 0x9F37, 0x9F3A, 0x9F3D, - 0x9F41, 0x9F45, 0x9F46, 0x9F53, 0x9F55, 0x9F58, 0xD869 /*0xDDF1*/, 0x9F5D, - 0xD869 /*0xDE02*/, 0x9F69, 0xD869 /*0xDE1A*/, 0x9F6D, 0x9F70, 0x9F75, 0xD869 /*0xDEB2*/, 0, - 0, 0, 0, 0, 0, 0, 0, -}; - -#ifdef X0212_ENABLE -static const unsigned short euc_to_utf8_8FA2[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x02D8, - 0x02C7, 0x00B8, 0x02D9, 0x02DD, 0x00AF, 0x02DB, 0x02DA, 0xFF5E, - 0x0384, 0x0385, 0, 0, 0, 0, 0, 0, - 0, 0, 0x00A1, 0xFFE4, 0x00BF, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x00BA, 0x00AA, 0x00A9, 0x00AE, 0x2122, - 0x00A4, 0x2116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_8FA6[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x0386, 0x0388, 0x0389, 0x038A, 0x03AA, 0, 0x038C, - 0, 0x038E, 0x03AB, 0, 0x038F, 0, 0, 0, - 0, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03CA, 0x0390, 0x03CC, - 0x03C2, 0x03CD, 0x03CB, 0x03B0, 0x03CE, 0, 0, -}; -static const unsigned short euc_to_utf8_8FA7[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, - 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040E, 0x040F, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, - 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045E, 0x045F, -}; -static const unsigned short euc_to_utf8_8FA9[] = { - 0x00C6, 0x0110, 0, 0x0126, 0, 0x0132, 0, - 0x0141, 0x013F, 0, 0x014A, 0x00D8, 0x0152, 0, 0x0166, - 0x00DE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0138, - 0x0142, 0x0140, 0x0149, 0x014B, 0x00F8, 0x0153, 0x00DF, 0x0167, - 0x00FE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_8FAA[] = { - 0x00C1, 0x00C0, 0x00C4, 0x00C2, 0x0102, 0x01CD, 0x0100, - 0x0104, 0x00C5, 0x00C3, 0x0106, 0x0108, 0x010C, 0x00C7, 0x010A, - 0x010E, 0x00C9, 0x00C8, 0x00CB, 0x00CA, 0x011A, 0x0116, 0x0112, - 0x0118, 0, 0x011C, 0x011E, 0x0122, 0x0120, 0x0124, 0x00CD, - 0x00CC, 0x00CF, 0x00CE, 0x01CF, 0x0130, 0x012A, 0x012E, 0x0128, - 0x0134, 0x0136, 0x0139, 0x013D, 0x013B, 0x0143, 0x0147, 0x0145, - 0x00D1, 0x00D3, 0x00D2, 0x00D6, 0x00D4, 0x01D1, 0x0150, 0x014C, - 0x00D5, 0x0154, 0x0158, 0x0156, 0x015A, 0x015C, 0x0160, 0x015E, - 0x0164, 0x0162, 0x00DA, 0x00D9, 0x00DC, 0x00DB, 0x016C, 0x01D3, - 0x0170, 0x016A, 0x0172, 0x016E, 0x0168, 0x01D7, 0x01DB, 0x01D9, - 0x01D5, 0x0174, 0x00DD, 0x0178, 0x0176, 0x0179, 0x017D, 0x017B, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_8FAB[] = { - 0x00E1, 0x00E0, 0x00E4, 0x00E2, 0x0103, 0x01CE, 0x0101, - 0x0105, 0x00E5, 0x00E3, 0x0107, 0x0109, 0x010D, 0x00E7, 0x010B, - 0x010F, 0x00E9, 0x00E8, 0x00EB, 0x00EA, 0x011B, 0x0117, 0x0113, - 0x0119, 0x01F5, 0x011D, 0x011F, 0, 0x0121, 0x0125, 0x00ED, - 0x00EC, 0x00EF, 0x00EE, 0x01D0, 0, 0x012B, 0x012F, 0x0129, - 0x0135, 0x0137, 0x013A, 0x013E, 0x013C, 0x0144, 0x0148, 0x0146, - 0x00F1, 0x00F3, 0x00F2, 0x00F6, 0x00F4, 0x01D2, 0x0151, 0x014D, - 0x00F5, 0x0155, 0x0159, 0x0157, 0x015B, 0x015D, 0x0161, 0x015F, - 0x0165, 0x0163, 0x00FA, 0x00F9, 0x00FC, 0x00FB, 0x016D, 0x01D4, - 0x0171, 0x016B, 0x0173, 0x016F, 0x0169, 0x01D8, 0x01DC, 0x01DA, - 0x01D6, 0x0175, 0x00FD, 0x00FF, 0x0177, 0x017A, 0x017E, 0x017C, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_8FB0[] = { - 0x4E02, 0x4E04, 0x4E05, 0x4E0C, 0x4E12, 0x4E1F, 0x4E23, - 0x4E24, 0x4E28, 0x4E2B, 0x4E2E, 0x4E2F, 0x4E30, 0x4E35, 0x4E40, - 0x4E41, 0x4E44, 0x4E47, 0x4E51, 0x4E5A, 0x4E5C, 0x4E63, 0x4E68, - 0x4E69, 0x4E74, 0x4E75, 0x4E79, 0x4E7F, 0x4E8D, 0x4E96, 0x4E97, - 0x4E9D, 0x4EAF, 0x4EB9, 0x4EC3, 0x4ED0, 0x4EDA, 0x4EDB, 0x4EE0, - 0x4EE1, 0x4EE2, 0x4EE8, 0x4EEF, 0x4EF1, 0x4EF3, 0x4EF5, 0x4EFD, - 0x4EFE, 0x4EFF, 0x4F00, 0x4F02, 0x4F03, 0x4F08, 0x4F0B, 0x4F0C, - 0x4F12, 0x4F15, 0x4F16, 0x4F17, 0x4F19, 0x4F2E, 0x4F31, 0x4F60, - 0x4F33, 0x4F35, 0x4F37, 0x4F39, 0x4F3B, 0x4F3E, 0x4F40, 0x4F42, - 0x4F48, 0x4F49, 0x4F4B, 0x4F4C, 0x4F52, 0x4F54, 0x4F56, 0x4F58, - 0x4F5F, 0x4F63, 0x4F6A, 0x4F6C, 0x4F6E, 0x4F71, 0x4F77, 0x4F78, - 0x4F79, 0x4F7A, 0x4F7D, 0x4F7E, 0x4F81, 0x4F82, 0x4F84, -}; -static const unsigned short euc_to_utf8_8FB1[] = { - 0x4F85, 0x4F89, 0x4F8A, 0x4F8C, 0x4F8E, 0x4F90, 0x4F92, - 0x4F93, 0x4F94, 0x4F97, 0x4F99, 0x4F9A, 0x4F9E, 0x4F9F, 0x4FB2, - 0x4FB7, 0x4FB9, 0x4FBB, 0x4FBC, 0x4FBD, 0x4FBE, 0x4FC0, 0x4FC1, - 0x4FC5, 0x4FC6, 0x4FC8, 0x4FC9, 0x4FCB, 0x4FCC, 0x4FCD, 0x4FCF, - 0x4FD2, 0x4FDC, 0x4FE0, 0x4FE2, 0x4FF0, 0x4FF2, 0x4FFC, 0x4FFD, - 0x4FFF, 0x5000, 0x5001, 0x5004, 0x5007, 0x500A, 0x500C, 0x500E, - 0x5010, 0x5013, 0x5017, 0x5018, 0x501B, 0x501C, 0x501D, 0x501E, - 0x5022, 0x5027, 0x502E, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040, - 0x5041, 0x5042, 0x5045, 0x5046, 0x504A, 0x504C, 0x504E, 0x5051, - 0x5052, 0x5053, 0x5057, 0x5059, 0x505F, 0x5060, 0x5062, 0x5063, - 0x5066, 0x5067, 0x506A, 0x506D, 0x5070, 0x5071, 0x503B, 0x5081, - 0x5083, 0x5084, 0x5086, 0x508A, 0x508E, 0x508F, 0x5090, -}; -static const unsigned short euc_to_utf8_8FB2[] = { - 0x5092, 0x5093, 0x5094, 0x5096, 0x509B, 0x509C, 0x509E, - 0x509F, 0x50A0, 0x50A1, 0x50A2, 0x50AA, 0x50AF, 0x50B0, 0x50B9, - 0x50BA, 0x50BD, 0x50C0, 0x50C3, 0x50C4, 0x50C7, 0x50CC, 0x50CE, - 0x50D0, 0x50D3, 0x50D4, 0x50D8, 0x50DC, 0x50DD, 0x50DF, 0x50E2, - 0x50E4, 0x50E6, 0x50E8, 0x50E9, 0x50EF, 0x50F1, 0x50F6, 0x50FA, - 0x50FE, 0x5103, 0x5106, 0x5107, 0x5108, 0x510B, 0x510C, 0x510D, - 0x510E, 0x50F2, 0x5110, 0x5117, 0x5119, 0x511B, 0x511C, 0x511D, - 0x511E, 0x5123, 0x5127, 0x5128, 0x512C, 0x512D, 0x512F, 0x5131, - 0x5133, 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514A, 0x514F, - 0x5153, 0x5155, 0x5157, 0x5158, 0x515F, 0x5164, 0x5166, 0x517E, - 0x5183, 0x5184, 0x518B, 0x518E, 0x5198, 0x519D, 0x51A1, 0x51A3, - 0x51AD, 0x51B8, 0x51BA, 0x51BC, 0x51BE, 0x51BF, 0x51C2, -}; -static const unsigned short euc_to_utf8_8FB3[] = { - 0x51C8, 0x51CF, 0x51D1, 0x51D2, 0x51D3, 0x51D5, 0x51D8, - 0x51DE, 0x51E2, 0x51E5, 0x51EE, 0x51F2, 0x51F3, 0x51F4, 0x51F7, - 0x5201, 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218, - 0x5222, 0x5228, 0x5231, 0x5232, 0x5235, 0x523C, 0x5245, 0x5249, - 0x5255, 0x5257, 0x5258, 0x525A, 0x525C, 0x525F, 0x5260, 0x5261, - 0x5266, 0x526E, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285, - 0x528A, 0x528C, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529A, - 0x529C, 0x52A4, 0x52A5, 0x52A6, 0x52A7, 0x52AF, 0x52B0, 0x52B6, - 0x52B7, 0x52B8, 0x52BA, 0x52BB, 0x52BD, 0x52C0, 0x52C4, 0x52C6, - 0x52C8, 0x52CC, 0x52CF, 0x52D1, 0x52D4, 0x52D6, 0x52DB, 0x52DC, - 0x52E1, 0x52E5, 0x52E8, 0x52E9, 0x52EA, 0x52EC, 0x52F0, 0x52F1, - 0x52F4, 0x52F6, 0x52F7, 0x5300, 0x5303, 0x530A, 0x530B, -}; -static const unsigned short euc_to_utf8_8FB4[] = { - 0x530C, 0x5311, 0x5313, 0x5318, 0x531B, 0x531C, 0x531E, - 0x531F, 0x5325, 0x5327, 0x5328, 0x5329, 0x532B, 0x532C, 0x532D, - 0x5330, 0x5332, 0x5335, 0x533C, 0x533D, 0x533E, 0x5342, 0x534C, - 0x534B, 0x5359, 0x535B, 0x5361, 0x5363, 0x5365, 0x536C, 0x536D, - 0x5372, 0x5379, 0x537E, 0x5383, 0x5387, 0x5388, 0x538E, 0x5393, - 0x5394, 0x5399, 0x539D, 0x53A1, 0x53A4, 0x53AA, 0x53AB, 0x53AF, - 0x53B2, 0x53B4, 0x53B5, 0x53B7, 0x53B8, 0x53BA, 0x53BD, 0x53C0, - 0x53C5, 0x53CF, 0x53D2, 0x53D3, 0x53D5, 0x53DA, 0x53DD, 0x53DE, - 0x53E0, 0x53E6, 0x53E7, 0x53F5, 0x5402, 0x5413, 0x541A, 0x5421, - 0x5427, 0x5428, 0x542A, 0x542F, 0x5431, 0x5434, 0x5435, 0x5443, - 0x5444, 0x5447, 0x544D, 0x544F, 0x545E, 0x5462, 0x5464, 0x5466, - 0x5467, 0x5469, 0x546B, 0x546D, 0x546E, 0x5474, 0x547F, -}; -static const unsigned short euc_to_utf8_8FB5[] = { - 0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548D, 0x5491, - 0x5495, 0x5496, 0x549C, 0x549F, 0x54A1, 0x54A6, 0x54A7, 0x54A9, - 0x54AA, 0x54AD, 0x54AE, 0x54B1, 0x54B7, 0x54B9, 0x54BA, 0x54BB, - 0x54BF, 0x54C6, 0x54CA, 0x54CD, 0x54CE, 0x54E0, 0x54EA, 0x54EC, - 0x54EF, 0x54F6, 0x54FC, 0x54FE, 0x54FF, 0x5500, 0x5501, 0x5505, - 0x5508, 0x5509, 0x550C, 0x550D, 0x550E, 0x5515, 0x552A, 0x552B, - 0x5532, 0x5535, 0x5536, 0x553B, 0x553C, 0x553D, 0x5541, 0x5547, - 0x5549, 0x554A, 0x554D, 0x5550, 0x5551, 0x5558, 0x555A, 0x555B, - 0x555E, 0x5560, 0x5561, 0x5564, 0x5566, 0x557F, 0x5581, 0x5582, - 0x5586, 0x5588, 0x558E, 0x558F, 0x5591, 0x5592, 0x5593, 0x5594, - 0x5597, 0x55A3, 0x55A4, 0x55AD, 0x55B2, 0x55BF, 0x55C1, 0x55C3, - 0x55C6, 0x55C9, 0x55CB, 0x55CC, 0x55CE, 0x55D1, 0x55D2, -}; -static const unsigned short euc_to_utf8_8FB6[] = { - 0x55D3, 0x55D7, 0x55D8, 0x55DB, 0x55DE, 0x55E2, 0x55E9, - 0x55F6, 0x55FF, 0x5605, 0x5608, 0x560A, 0x560D, 0x560E, 0x560F, - 0x5610, 0x5611, 0x5612, 0x5619, 0x562C, 0x5630, 0x5633, 0x5635, - 0x5637, 0x5639, 0x563B, 0x563C, 0x563D, 0x563F, 0x5640, 0x5641, - 0x5643, 0x5644, 0x5646, 0x5649, 0x564B, 0x564D, 0x564F, 0x5654, - 0x565E, 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566D, - 0x566F, 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568B, - 0x568C, 0x5695, 0x5699, 0x569A, 0x569D, 0x569E, 0x569F, 0x56A6, - 0x56A7, 0x56A8, 0x56A9, 0x56AB, 0x56AC, 0x56AD, 0x56B1, 0x56B3, - 0x56B7, 0x56BE, 0x56C5, 0x56C9, 0x56CA, 0x56CB, 0x56CF, 0x56D0, - 0x56CC, 0x56CD, 0x56D9, 0x56DC, 0x56DD, 0x56DF, 0x56E1, 0x56E4, - 0x56E5, 0x56E6, 0x56E7, 0x56E8, 0x56F1, 0x56EB, 0x56ED, -}; -static const unsigned short euc_to_utf8_8FB7[] = { - 0x56F6, 0x56F7, 0x5701, 0x5702, 0x5707, 0x570A, 0x570C, - 0x5711, 0x5715, 0x571A, 0x571B, 0x571D, 0x5720, 0x5722, 0x5723, - 0x5724, 0x5725, 0x5729, 0x572A, 0x572C, 0x572E, 0x572F, 0x5733, - 0x5734, 0x573D, 0x573E, 0x573F, 0x5745, 0x5746, 0x574C, 0x574D, - 0x5752, 0x5762, 0x5765, 0x5767, 0x5768, 0x576B, 0x576D, 0x576E, - 0x576F, 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779, - 0x577A, 0x577B, 0x577C, 0x577E, 0x5781, 0x5783, 0x578C, 0x5794, - 0x5797, 0x5799, 0x579A, 0x579C, 0x579D, 0x579E, 0x579F, 0x57A1, - 0x5795, 0x57A7, 0x57A8, 0x57A9, 0x57AC, 0x57B8, 0x57BD, 0x57C7, - 0x57C8, 0x57CC, 0x57CF, 0x57D5, 0x57DD, 0x57DE, 0x57E4, 0x57E6, - 0x57E7, 0x57E9, 0x57ED, 0x57F0, 0x57F5, 0x57F6, 0x57F8, 0x57FD, - 0x57FE, 0x57FF, 0x5803, 0x5804, 0x5808, 0x5809, 0x57E1, -}; -static const unsigned short euc_to_utf8_8FB8[] = { - 0x580C, 0x580D, 0x581B, 0x581E, 0x581F, 0x5820, 0x5826, - 0x5827, 0x582D, 0x5832, 0x5839, 0x583F, 0x5849, 0x584C, 0x584D, - 0x584F, 0x5850, 0x5855, 0x585F, 0x5861, 0x5864, 0x5867, 0x5868, - 0x5878, 0x587C, 0x587F, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889, - 0x588A, 0x588C, 0x588D, 0x588F, 0x5890, 0x5894, 0x5896, 0x589D, - 0x58A0, 0x58A1, 0x58A2, 0x58A6, 0x58A9, 0x58B1, 0x58B2, 0x58C4, - 0x58BC, 0x58C2, 0x58C8, 0x58CD, 0x58CE, 0x58D0, 0x58D2, 0x58D4, - 0x58D6, 0x58DA, 0x58DD, 0x58E1, 0x58E2, 0x58E9, 0x58F3, 0x5905, - 0x5906, 0x590B, 0x590C, 0x5912, 0x5913, 0x5914, 0x8641, 0x591D, - 0x5921, 0x5923, 0x5924, 0x5928, 0x592F, 0x5930, 0x5933, 0x5935, - 0x5936, 0x593F, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595B, - 0x595D, 0x595E, 0x595F, 0x5961, 0x5963, 0x596B, 0x596D, -}; -static const unsigned short euc_to_utf8_8FB9[] = { - 0x596F, 0x5972, 0x5975, 0x5976, 0x5979, 0x597B, 0x597C, - 0x598B, 0x598C, 0x598E, 0x5992, 0x5995, 0x5997, 0x599F, 0x59A4, - 0x59A7, 0x59AD, 0x59AE, 0x59AF, 0x59B0, 0x59B3, 0x59B7, 0x59BA, - 0x59BC, 0x59C1, 0x59C3, 0x59C4, 0x59C8, 0x59CA, 0x59CD, 0x59D2, - 0x59DD, 0x59DE, 0x59DF, 0x59E3, 0x59E4, 0x59E7, 0x59EE, 0x59EF, - 0x59F1, 0x59F2, 0x59F4, 0x59F7, 0x5A00, 0x5A04, 0x5A0C, 0x5A0D, - 0x5A0E, 0x5A12, 0x5A13, 0x5A1E, 0x5A23, 0x5A24, 0x5A27, 0x5A28, - 0x5A2A, 0x5A2D, 0x5A30, 0x5A44, 0x5A45, 0x5A47, 0x5A48, 0x5A4C, - 0x5A50, 0x5A55, 0x5A5E, 0x5A63, 0x5A65, 0x5A67, 0x5A6D, 0x5A77, - 0x5A7A, 0x5A7B, 0x5A7E, 0x5A8B, 0x5A90, 0x5A93, 0x5A96, 0x5A99, - 0x5A9C, 0x5A9E, 0x5A9F, 0x5AA0, 0x5AA2, 0x5AA7, 0x5AAC, 0x5AB1, - 0x5AB2, 0x5AB3, 0x5AB5, 0x5AB8, 0x5ABA, 0x5ABB, 0x5ABF, -}; -static const unsigned short euc_to_utf8_8FBA[] = { - 0x5AC4, 0x5AC6, 0x5AC8, 0x5ACF, 0x5ADA, 0x5ADC, 0x5AE0, - 0x5AE5, 0x5AEA, 0x5AEE, 0x5AF5, 0x5AF6, 0x5AFD, 0x5B00, 0x5B01, - 0x5B08, 0x5B17, 0x5B34, 0x5B19, 0x5B1B, 0x5B1D, 0x5B21, 0x5B25, - 0x5B2D, 0x5B38, 0x5B41, 0x5B4B, 0x5B4C, 0x5B52, 0x5B56, 0x5B5E, - 0x5B68, 0x5B6E, 0x5B6F, 0x5B7C, 0x5B7D, 0x5B7E, 0x5B7F, 0x5B81, - 0x5B84, 0x5B86, 0x5B8A, 0x5B8E, 0x5B90, 0x5B91, 0x5B93, 0x5B94, - 0x5B96, 0x5BA8, 0x5BA9, 0x5BAC, 0x5BAD, 0x5BAF, 0x5BB1, 0x5BB2, - 0x5BB7, 0x5BBA, 0x5BBC, 0x5BC0, 0x5BC1, 0x5BCD, 0x5BCF, 0x5BD6, - 0x5BD7, 0x5BD8, 0x5BD9, 0x5BDA, 0x5BE0, 0x5BEF, 0x5BF1, 0x5BF4, - 0x5BFD, 0x5C0C, 0x5C17, 0x5C1E, 0x5C1F, 0x5C23, 0x5C26, 0x5C29, - 0x5C2B, 0x5C2C, 0x5C2E, 0x5C30, 0x5C32, 0x5C35, 0x5C36, 0x5C59, - 0x5C5A, 0x5C5C, 0x5C62, 0x5C63, 0x5C67, 0x5C68, 0x5C69, -}; -static const unsigned short euc_to_utf8_8FBB[] = { - 0x5C6D, 0x5C70, 0x5C74, 0x5C75, 0x5C7A, 0x5C7B, 0x5C7C, - 0x5C7D, 0x5C87, 0x5C88, 0x5C8A, 0x5C8F, 0x5C92, 0x5C9D, 0x5C9F, - 0x5CA0, 0x5CA2, 0x5CA3, 0x5CA6, 0x5CAA, 0x5CB2, 0x5CB4, 0x5CB5, - 0x5CBA, 0x5CC9, 0x5CCB, 0x5CD2, 0x5CDD, 0x5CD7, 0x5CEE, 0x5CF1, - 0x5CF2, 0x5CF4, 0x5D01, 0x5D06, 0x5D0D, 0x5D12, 0x5D2B, 0x5D23, - 0x5D24, 0x5D26, 0x5D27, 0x5D31, 0x5D34, 0x5D39, 0x5D3D, 0x5D3F, - 0x5D42, 0x5D43, 0x5D46, 0x5D48, 0x5D55, 0x5D51, 0x5D59, 0x5D4A, - 0x5D5F, 0x5D60, 0x5D61, 0x5D62, 0x5D64, 0x5D6A, 0x5D6D, 0x5D70, - 0x5D79, 0x5D7A, 0x5D7E, 0x5D7F, 0x5D81, 0x5D83, 0x5D88, 0x5D8A, - 0x5D92, 0x5D93, 0x5D94, 0x5D95, 0x5D99, 0x5D9B, 0x5D9F, 0x5DA0, - 0x5DA7, 0x5DAB, 0x5DB0, 0x5DB4, 0x5DB8, 0x5DB9, 0x5DC3, 0x5DC7, - 0x5DCB, 0x5DD0, 0x5DCE, 0x5DD8, 0x5DD9, 0x5DE0, 0x5DE4, -}; -static const unsigned short euc_to_utf8_8FBC[] = { - 0x5DE9, 0x5DF8, 0x5DF9, 0x5E00, 0x5E07, 0x5E0D, 0x5E12, - 0x5E14, 0x5E15, 0x5E18, 0x5E1F, 0x5E20, 0x5E2E, 0x5E28, 0x5E32, - 0x5E35, 0x5E3E, 0x5E4B, 0x5E50, 0x5E49, 0x5E51, 0x5E56, 0x5E58, - 0x5E5B, 0x5E5C, 0x5E5E, 0x5E68, 0x5E6A, 0x5E6B, 0x5E6C, 0x5E6D, - 0x5E6E, 0x5E70, 0x5E80, 0x5E8B, 0x5E8E, 0x5EA2, 0x5EA4, 0x5EA5, - 0x5EA8, 0x5EAA, 0x5EAC, 0x5EB1, 0x5EB3, 0x5EBD, 0x5EBE, 0x5EBF, - 0x5EC6, 0x5ECC, 0x5ECB, 0x5ECE, 0x5ED1, 0x5ED2, 0x5ED4, 0x5ED5, - 0x5EDC, 0x5EDE, 0x5EE5, 0x5EEB, 0x5F02, 0x5F06, 0x5F07, 0x5F08, - 0x5F0E, 0x5F19, 0x5F1C, 0x5F1D, 0x5F21, 0x5F22, 0x5F23, 0x5F24, - 0x5F28, 0x5F2B, 0x5F2C, 0x5F2E, 0x5F30, 0x5F34, 0x5F36, 0x5F3B, - 0x5F3D, 0x5F3F, 0x5F40, 0x5F44, 0x5F45, 0x5F47, 0x5F4D, 0x5F50, - 0x5F54, 0x5F58, 0x5F5B, 0x5F60, 0x5F63, 0x5F64, 0x5F67, -}; -static const unsigned short euc_to_utf8_8FBD[] = { - 0x5F6F, 0x5F72, 0x5F74, 0x5F75, 0x5F78, 0x5F7A, 0x5F7D, - 0x5F7E, 0x5F89, 0x5F8D, 0x5F8F, 0x5F96, 0x5F9C, 0x5F9D, 0x5FA2, - 0x5FA7, 0x5FAB, 0x5FA4, 0x5FAC, 0x5FAF, 0x5FB0, 0x5FB1, 0x5FB8, - 0x5FC4, 0x5FC7, 0x5FC8, 0x5FC9, 0x5FCB, 0x5FD0, 0x5FD1, 0x5FD2, - 0x5FD3, 0x5FD4, 0x5FDE, 0x5FE1, 0x5FE2, 0x5FE8, 0x5FE9, 0x5FEA, - 0x5FEC, 0x5FED, 0x5FEE, 0x5FEF, 0x5FF2, 0x5FF3, 0x5FF6, 0x5FFA, - 0x5FFC, 0x6007, 0x600A, 0x600D, 0x6013, 0x6014, 0x6017, 0x6018, - 0x601A, 0x601F, 0x6024, 0x602D, 0x6033, 0x6035, 0x6040, 0x6047, - 0x6048, 0x6049, 0x604C, 0x6051, 0x6054, 0x6056, 0x6057, 0x605D, - 0x6061, 0x6067, 0x6071, 0x607E, 0x607F, 0x6082, 0x6086, 0x6088, - 0x608A, 0x608E, 0x6091, 0x6093, 0x6095, 0x6098, 0x609D, 0x609E, - 0x60A2, 0x60A4, 0x60A5, 0x60A8, 0x60B0, 0x60B1, 0x60B7, -}; -static const unsigned short euc_to_utf8_8FBE[] = { - 0x60BB, 0x60BE, 0x60C2, 0x60C4, 0x60C8, 0x60C9, 0x60CA, - 0x60CB, 0x60CE, 0x60CF, 0x60D4, 0x60D5, 0x60D9, 0x60DB, 0x60DD, - 0x60DE, 0x60E2, 0x60E5, 0x60F2, 0x60F5, 0x60F8, 0x60FC, 0x60FD, - 0x6102, 0x6107, 0x610A, 0x610C, 0x6110, 0x6111, 0x6112, 0x6113, - 0x6114, 0x6116, 0x6117, 0x6119, 0x611C, 0x611E, 0x6122, 0x612A, - 0x612B, 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141, - 0x6145, 0x6146, 0x6149, 0x615E, 0x6160, 0x616C, 0x6172, 0x6178, - 0x617B, 0x617C, 0x617F, 0x6180, 0x6181, 0x6183, 0x6184, 0x618B, - 0x618D, 0x6192, 0x6193, 0x6197, 0x6198, 0x619C, 0x619D, 0x619F, - 0x61A0, 0x61A5, 0x61A8, 0x61AA, 0x61AD, 0x61B8, 0x61B9, 0x61BC, - 0x61C0, 0x61C1, 0x61C2, 0x61CE, 0x61CF, 0x61D5, 0x61DC, 0x61DD, - 0x61DE, 0x61DF, 0x61E1, 0x61E2, 0x61E7, 0x61E9, 0x61E5, -}; -static const unsigned short euc_to_utf8_8FBF[] = { - 0x61EC, 0x61ED, 0x61EF, 0x6201, 0x6203, 0x6204, 0x6207, - 0x6213, 0x6215, 0x621C, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229, - 0x622B, 0x6239, 0x623D, 0x6242, 0x6243, 0x6244, 0x6246, 0x624C, - 0x6250, 0x6251, 0x6252, 0x6254, 0x6256, 0x625A, 0x625C, 0x6264, - 0x626D, 0x626F, 0x6273, 0x627A, 0x627D, 0x628D, 0x628E, 0x628F, - 0x6290, 0x62A6, 0x62A8, 0x62B3, 0x62B6, 0x62B7, 0x62BA, 0x62BE, - 0x62BF, 0x62C4, 0x62CE, 0x62D5, 0x62D6, 0x62DA, 0x62EA, 0x62F2, - 0x62F4, 0x62FC, 0x62FD, 0x6303, 0x6304, 0x630A, 0x630B, 0x630D, - 0x6310, 0x6313, 0x6316, 0x6318, 0x6329, 0x632A, 0x632D, 0x6335, - 0x6336, 0x6339, 0x633C, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346, - 0x634A, 0x634B, 0x634E, 0x6352, 0x6353, 0x6354, 0x6358, 0x635B, - 0x6365, 0x6366, 0x636C, 0x636D, 0x6371, 0x6374, 0x6375, -}; -static const unsigned short euc_to_utf8_8FC0[] = { - 0x6378, 0x637C, 0x637D, 0x637F, 0x6382, 0x6384, 0x6387, - 0x638A, 0x6390, 0x6394, 0x6395, 0x6399, 0x639A, 0x639E, 0x63A4, - 0x63A6, 0x63AD, 0x63AE, 0x63AF, 0x63BD, 0x63C1, 0x63C5, 0x63C8, - 0x63CE, 0x63D1, 0x63D3, 0x63D4, 0x63D5, 0x63DC, 0x63E0, 0x63E5, - 0x63EA, 0x63EC, 0x63F2, 0x63F3, 0x63F5, 0x63F8, 0x63F9, 0x6409, - 0x640A, 0x6410, 0x6412, 0x6414, 0x6418, 0x641E, 0x6420, 0x6422, - 0x6424, 0x6425, 0x6429, 0x642A, 0x642F, 0x6430, 0x6435, 0x643D, - 0x643F, 0x644B, 0x644F, 0x6451, 0x6452, 0x6453, 0x6454, 0x645A, - 0x645B, 0x645C, 0x645D, 0x645F, 0x6460, 0x6461, 0x6463, 0x646D, - 0x6473, 0x6474, 0x647B, 0x647D, 0x6485, 0x6487, 0x648F, 0x6490, - 0x6491, 0x6498, 0x6499, 0x649B, 0x649D, 0x649F, 0x64A1, 0x64A3, - 0x64A6, 0x64A8, 0x64AC, 0x64B3, 0x64BD, 0x64BE, 0x64BF, -}; -static const unsigned short euc_to_utf8_8FC1[] = { - 0x64C4, 0x64C9, 0x64CA, 0x64CB, 0x64CC, 0x64CE, 0x64D0, - 0x64D1, 0x64D5, 0x64D7, 0x64E4, 0x64E5, 0x64E9, 0x64EA, 0x64ED, - 0x64F0, 0x64F5, 0x64F7, 0x64FB, 0x64FF, 0x6501, 0x6504, 0x6508, - 0x6509, 0x650A, 0x650F, 0x6513, 0x6514, 0x6516, 0x6519, 0x651B, - 0x651E, 0x651F, 0x6522, 0x6526, 0x6529, 0x652E, 0x6531, 0x653A, - 0x653C, 0x653D, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554, - 0x655F, 0x6560, 0x6567, 0x656B, 0x657A, 0x657D, 0x6581, 0x6585, - 0x658A, 0x6592, 0x6595, 0x6598, 0x659D, 0x65A0, 0x65A3, 0x65A6, - 0x65AE, 0x65B2, 0x65B3, 0x65B4, 0x65BF, 0x65C2, 0x65C8, 0x65C9, - 0x65CE, 0x65D0, 0x65D4, 0x65D6, 0x65D8, 0x65DF, 0x65F0, 0x65F2, - 0x65F4, 0x65F5, 0x65F9, 0x65FE, 0x65FF, 0x6600, 0x6604, 0x6608, - 0x6609, 0x660D, 0x6611, 0x6612, 0x6615, 0x6616, 0x661D, -}; -static const unsigned short euc_to_utf8_8FC2[] = { - 0x661E, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629, - 0x662A, 0x662B, 0x662C, 0x662E, 0x6630, 0x6631, 0x6633, 0x6639, - 0x6637, 0x6640, 0x6645, 0x6646, 0x664A, 0x664C, 0x6651, 0x664E, - 0x6657, 0x6658, 0x6659, 0x665B, 0x665C, 0x6660, 0x6661, 0x66FB, - 0x666A, 0x666B, 0x666C, 0x667E, 0x6673, 0x6675, 0x667F, 0x6677, - 0x6678, 0x6679, 0x667B, 0x6680, 0x667C, 0x668B, 0x668C, 0x668D, - 0x6690, 0x6692, 0x6699, 0x669A, 0x669B, 0x669C, 0x669F, 0x66A0, - 0x66A4, 0x66AD, 0x66B1, 0x66B2, 0x66B5, 0x66BB, 0x66BF, 0x66C0, - 0x66C2, 0x66C3, 0x66C8, 0x66CC, 0x66CE, 0x66CF, 0x66D4, 0x66DB, - 0x66DF, 0x66E8, 0x66EB, 0x66EC, 0x66EE, 0x66FA, 0x6705, 0x6707, - 0x670E, 0x6713, 0x6719, 0x671C, 0x6720, 0x6722, 0x6733, 0x673E, - 0x6745, 0x6747, 0x6748, 0x674C, 0x6754, 0x6755, 0x675D, -}; -static const unsigned short euc_to_utf8_8FC3[] = { - 0x6766, 0x676C, 0x676E, 0x6774, 0x6776, 0x677B, 0x6781, - 0x6784, 0x678E, 0x678F, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799, - 0x679B, 0x67B0, 0x67B1, 0x67B2, 0x67B5, 0x67BB, 0x67BC, 0x67BD, - 0x67F9, 0x67C0, 0x67C2, 0x67C3, 0x67C5, 0x67C8, 0x67C9, 0x67D2, - 0x67D7, 0x67D9, 0x67DC, 0x67E1, 0x67E6, 0x67F0, 0x67F2, 0x67F6, - 0x67F7, 0x6852, 0x6814, 0x6819, 0x681D, 0x681F, 0x6828, 0x6827, - 0x682C, 0x682D, 0x682F, 0x6830, 0x6831, 0x6833, 0x683B, 0x683F, - 0x6844, 0x6845, 0x684A, 0x684C, 0x6855, 0x6857, 0x6858, 0x685B, - 0x686B, 0x686E, 0x686F, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879, - 0x687A, 0x687B, 0x687C, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896, - 0x6898, 0x689A, 0x689C, 0x68A1, 0x68A3, 0x68A5, 0x68A9, 0x68AA, - 0x68AE, 0x68B2, 0x68BB, 0x68C5, 0x68C8, 0x68CC, 0x68CF, -}; -static const unsigned short euc_to_utf8_8FC4[] = { - 0x68D0, 0x68D1, 0x68D3, 0x68D6, 0x68D9, 0x68DC, 0x68DD, - 0x68E5, 0x68E8, 0x68EA, 0x68EB, 0x68EC, 0x68ED, 0x68F0, 0x68F1, - 0x68F5, 0x68F6, 0x68FB, 0x68FC, 0x68FD, 0x6906, 0x6909, 0x690A, - 0x6910, 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935, - 0x6938, 0x693B, 0x6942, 0x6945, 0x6949, 0x694E, 0x6957, 0x695B, - 0x6963, 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696C, 0x6970, - 0x6971, 0x6972, 0x697A, 0x697B, 0x697F, 0x6980, 0x698D, 0x6992, - 0x6996, 0x6998, 0x69A1, 0x69A5, 0x69A6, 0x69A8, 0x69AB, 0x69AD, - 0x69AF, 0x69B7, 0x69B8, 0x69BA, 0x69BC, 0x69C5, 0x69C8, 0x69D1, - 0x69D6, 0x69D7, 0x69E2, 0x69E5, 0x69EE, 0x69EF, 0x69F1, 0x69F3, - 0x69F5, 0x69FE, 0x6A00, 0x6A01, 0x6A03, 0x6A0F, 0x6A11, 0x6A15, - 0x6A1A, 0x6A1D, 0x6A20, 0x6A24, 0x6A28, 0x6A30, 0x6A32, -}; -static const unsigned short euc_to_utf8_8FC5[] = { - 0x6A34, 0x6A37, 0x6A3B, 0x6A3E, 0x6A3F, 0x6A45, 0x6A46, - 0x6A49, 0x6A4A, 0x6A4E, 0x6A50, 0x6A51, 0x6A52, 0x6A55, 0x6A56, - 0x6A5B, 0x6A64, 0x6A67, 0x6A6A, 0x6A71, 0x6A73, 0x6A7E, 0x6A81, - 0x6A83, 0x6A86, 0x6A87, 0x6A89, 0x6A8B, 0x6A91, 0x6A9B, 0x6A9D, - 0x6A9E, 0x6A9F, 0x6AA5, 0x6AAB, 0x6AAF, 0x6AB0, 0x6AB1, 0x6AB4, - 0x6ABD, 0x6ABE, 0x6ABF, 0x6AC6, 0x6AC9, 0x6AC8, 0x6ACC, 0x6AD0, - 0x6AD4, 0x6AD5, 0x6AD6, 0x6ADC, 0x6ADD, 0x6AE4, 0x6AE7, 0x6AEC, - 0x6AF0, 0x6AF1, 0x6AF2, 0x6AFC, 0x6AFD, 0x6B02, 0x6B03, 0x6B06, - 0x6B07, 0x6B09, 0x6B0F, 0x6B10, 0x6B11, 0x6B17, 0x6B1B, 0x6B1E, - 0x6B24, 0x6B28, 0x6B2B, 0x6B2C, 0x6B2F, 0x6B35, 0x6B36, 0x6B3B, - 0x6B3F, 0x6B46, 0x6B4A, 0x6B4D, 0x6B52, 0x6B56, 0x6B58, 0x6B5D, - 0x6B60, 0x6B67, 0x6B6B, 0x6B6E, 0x6B70, 0x6B75, 0x6B7D, -}; -static const unsigned short euc_to_utf8_8FC6[] = { - 0x6B7E, 0x6B82, 0x6B85, 0x6B97, 0x6B9B, 0x6B9F, 0x6BA0, - 0x6BA2, 0x6BA3, 0x6BA8, 0x6BA9, 0x6BAC, 0x6BAD, 0x6BAE, 0x6BB0, - 0x6BB8, 0x6BB9, 0x6BBD, 0x6BBE, 0x6BC3, 0x6BC4, 0x6BC9, 0x6BCC, - 0x6BD6, 0x6BDA, 0x6BE1, 0x6BE3, 0x6BE6, 0x6BE7, 0x6BEE, 0x6BF1, - 0x6BF7, 0x6BF9, 0x6BFF, 0x6C02, 0x6C04, 0x6C05, 0x6C09, 0x6C0D, - 0x6C0E, 0x6C10, 0x6C12, 0x6C19, 0x6C1F, 0x6C26, 0x6C27, 0x6C28, - 0x6C2C, 0x6C2E, 0x6C33, 0x6C35, 0x6C36, 0x6C3A, 0x6C3B, 0x6C3F, - 0x6C4A, 0x6C4B, 0x6C4D, 0x6C4F, 0x6C52, 0x6C54, 0x6C59, 0x6C5B, - 0x6C5C, 0x6C6B, 0x6C6D, 0x6C6F, 0x6C74, 0x6C76, 0x6C78, 0x6C79, - 0x6C7B, 0x6C85, 0x6C86, 0x6C87, 0x6C89, 0x6C94, 0x6C95, 0x6C97, - 0x6C98, 0x6C9C, 0x6C9F, 0x6CB0, 0x6CB2, 0x6CB4, 0x6CC2, 0x6CC6, - 0x6CCD, 0x6CCF, 0x6CD0, 0x6CD1, 0x6CD2, 0x6CD4, 0x6CD6, -}; -static const unsigned short euc_to_utf8_8FC7[] = { - 0x6CDA, 0x6CDC, 0x6CE0, 0x6CE7, 0x6CE9, 0x6CEB, 0x6CEC, - 0x6CEE, 0x6CF2, 0x6CF4, 0x6D04, 0x6D07, 0x6D0A, 0x6D0E, 0x6D0F, - 0x6D11, 0x6D13, 0x6D1A, 0x6D26, 0x6D27, 0x6D28, 0x6C67, 0x6D2E, - 0x6D2F, 0x6D31, 0x6D39, 0x6D3C, 0x6D3F, 0x6D57, 0x6D5E, 0x6D5F, - 0x6D61, 0x6D65, 0x6D67, 0x6D6F, 0x6D70, 0x6D7C, 0x6D82, 0x6D87, - 0x6D91, 0x6D92, 0x6D94, 0x6D96, 0x6D97, 0x6D98, 0x6DAA, 0x6DAC, - 0x6DB4, 0x6DB7, 0x6DB9, 0x6DBD, 0x6DBF, 0x6DC4, 0x6DC8, 0x6DCA, - 0x6DCE, 0x6DCF, 0x6DD6, 0x6DDB, 0x6DDD, 0x6DDF, 0x6DE0, 0x6DE2, - 0x6DE5, 0x6DE9, 0x6DEF, 0x6DF0, 0x6DF4, 0x6DF6, 0x6DFC, 0x6E00, - 0x6E04, 0x6E1E, 0x6E22, 0x6E27, 0x6E32, 0x6E36, 0x6E39, 0x6E3B, - 0x6E3C, 0x6E44, 0x6E45, 0x6E48, 0x6E49, 0x6E4B, 0x6E4F, 0x6E51, - 0x6E52, 0x6E53, 0x6E54, 0x6E57, 0x6E5C, 0x6E5D, 0x6E5E, -}; -static const unsigned short euc_to_utf8_8FC8[] = { - 0x6E62, 0x6E63, 0x6E68, 0x6E73, 0x6E7B, 0x6E7D, 0x6E8D, - 0x6E93, 0x6E99, 0x6EA0, 0x6EA7, 0x6EAD, 0x6EAE, 0x6EB1, 0x6EB3, - 0x6EBB, 0x6EBF, 0x6EC0, 0x6EC1, 0x6EC3, 0x6EC7, 0x6EC8, 0x6ECA, - 0x6ECD, 0x6ECE, 0x6ECF, 0x6EEB, 0x6EED, 0x6EEE, 0x6EF9, 0x6EFB, - 0x6EFD, 0x6F04, 0x6F08, 0x6F0A, 0x6F0C, 0x6F0D, 0x6F16, 0x6F18, - 0x6F1A, 0x6F1B, 0x6F26, 0x6F29, 0x6F2A, 0x6F2F, 0x6F30, 0x6F33, - 0x6F36, 0x6F3B, 0x6F3C, 0x6F2D, 0x6F4F, 0x6F51, 0x6F52, 0x6F53, - 0x6F57, 0x6F59, 0x6F5A, 0x6F5D, 0x6F5E, 0x6F61, 0x6F62, 0x6F68, - 0x6F6C, 0x6F7D, 0x6F7E, 0x6F83, 0x6F87, 0x6F88, 0x6F8B, 0x6F8C, - 0x6F8D, 0x6F90, 0x6F92, 0x6F93, 0x6F94, 0x6F96, 0x6F9A, 0x6F9F, - 0x6FA0, 0x6FA5, 0x6FA6, 0x6FA7, 0x6FA8, 0x6FAE, 0x6FAF, 0x6FB0, - 0x6FB5, 0x6FB6, 0x6FBC, 0x6FC5, 0x6FC7, 0x6FC8, 0x6FCA, -}; -static const unsigned short euc_to_utf8_8FC9[] = { - 0x6FDA, 0x6FDE, 0x6FE8, 0x6FE9, 0x6FF0, 0x6FF5, 0x6FF9, - 0x6FFC, 0x6FFD, 0x7000, 0x7005, 0x7006, 0x7007, 0x700D, 0x7017, - 0x7020, 0x7023, 0x702F, 0x7034, 0x7037, 0x7039, 0x703C, 0x7043, - 0x7044, 0x7048, 0x7049, 0x704A, 0x704B, 0x7054, 0x7055, 0x705D, - 0x705E, 0x704E, 0x7064, 0x7065, 0x706C, 0x706E, 0x7075, 0x7076, - 0x707E, 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097, - 0x7098, 0x709B, 0x70A4, 0x70AB, 0x70B0, 0x70B1, 0x70B4, 0x70B7, - 0x70CA, 0x70D1, 0x70D3, 0x70D4, 0x70D5, 0x70D6, 0x70D8, 0x70DC, - 0x70E4, 0x70FA, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710B, - 0x710C, 0x710F, 0x711E, 0x7120, 0x712B, 0x712D, 0x712F, 0x7130, - 0x7131, 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714A, 0x714B, - 0x7150, 0x7152, 0x7157, 0x715A, 0x715C, 0x715E, 0x7160, -}; -static const unsigned short euc_to_utf8_8FCA[] = { - 0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718C, 0x7192, - 0x719A, 0x719B, 0x71A0, 0x71A2, 0x71AF, 0x71B0, 0x71B2, 0x71B3, - 0x71BA, 0x71BF, 0x71C0, 0x71C1, 0x71C4, 0x71CB, 0x71CC, 0x71D3, - 0x71D6, 0x71D9, 0x71DA, 0x71DC, 0x71F8, 0x71FE, 0x7200, 0x7207, - 0x7208, 0x7209, 0x7213, 0x7217, 0x721A, 0x721D, 0x721F, 0x7224, - 0x722B, 0x722F, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243, - 0x7245, 0x724E, 0x724F, 0x7250, 0x7253, 0x7255, 0x7256, 0x725A, - 0x725C, 0x725E, 0x7260, 0x7263, 0x7268, 0x726B, 0x726E, 0x726F, - 0x7271, 0x7277, 0x7278, 0x727B, 0x727C, 0x727F, 0x7284, 0x7289, - 0x728D, 0x728E, 0x7293, 0x729B, 0x72A8, 0x72AD, 0x72AE, 0x72B1, - 0x72B4, 0x72BE, 0x72C1, 0x72C7, 0x72C9, 0x72CC, 0x72D5, 0x72D6, - 0x72D8, 0x72DF, 0x72E5, 0x72F3, 0x72F4, 0x72FA, 0x72FB, -}; -static const unsigned short euc_to_utf8_8FCB[] = { - 0x72FE, 0x7302, 0x7304, 0x7305, 0x7307, 0x730B, 0x730D, - 0x7312, 0x7313, 0x7318, 0x7319, 0x731E, 0x7322, 0x7324, 0x7327, - 0x7328, 0x732C, 0x7331, 0x7332, 0x7335, 0x733A, 0x733B, 0x733D, - 0x7343, 0x734D, 0x7350, 0x7352, 0x7356, 0x7358, 0x735D, 0x735E, - 0x735F, 0x7360, 0x7366, 0x7367, 0x7369, 0x736B, 0x736C, 0x736E, - 0x736F, 0x7371, 0x7377, 0x7379, 0x737C, 0x7380, 0x7381, 0x7383, - 0x7385, 0x7386, 0x738E, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398, - 0x739C, 0x739E, 0x739F, 0x73A0, 0x73A2, 0x73A5, 0x73A6, 0x73AA, - 0x73AB, 0x73AD, 0x73B5, 0x73B7, 0x73B9, 0x73BC, 0x73BD, 0x73BF, - 0x73C5, 0x73C6, 0x73C9, 0x73CB, 0x73CC, 0x73CF, 0x73D2, 0x73D3, - 0x73D6, 0x73D9, 0x73DD, 0x73E1, 0x73E3, 0x73E6, 0x73E7, 0x73E9, - 0x73F4, 0x73F5, 0x73F7, 0x73F9, 0x73FA, 0x73FB, 0x73FD, -}; -static const unsigned short euc_to_utf8_8FCC[] = { - 0x73FF, 0x7400, 0x7401, 0x7404, 0x7407, 0x740A, 0x7411, - 0x741A, 0x741B, 0x7424, 0x7426, 0x7428, 0x7429, 0x742A, 0x742B, - 0x742C, 0x742D, 0x742E, 0x742F, 0x7430, 0x7431, 0x7439, 0x7440, - 0x7443, 0x7444, 0x7446, 0x7447, 0x744B, 0x744D, 0x7451, 0x7452, - 0x7457, 0x745D, 0x7462, 0x7466, 0x7467, 0x7468, 0x746B, 0x746D, - 0x746E, 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487, - 0x7489, 0x748F, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749A, - 0x749C, 0x749F, 0x74A0, 0x74A1, 0x74A3, 0x74A6, 0x74A8, 0x74A9, - 0x74AA, 0x74AB, 0x74AE, 0x74AF, 0x74B1, 0x74B2, 0x74B5, 0x74B9, - 0x74BB, 0x74BF, 0x74C8, 0x74C9, 0x74CC, 0x74D0, 0x74D3, 0x74D8, - 0x74DA, 0x74DB, 0x74DE, 0x74DF, 0x74E4, 0x74E8, 0x74EA, 0x74EB, - 0x74EF, 0x74F4, 0x74FA, 0x74FB, 0x74FC, 0x74FF, 0x7506, -}; -static const unsigned short euc_to_utf8_8FCD[] = { - 0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527, - 0x7529, 0x752A, 0x752F, 0x7536, 0x7539, 0x753D, 0x753E, 0x753F, - 0x7540, 0x7543, 0x7547, 0x7548, 0x754E, 0x7550, 0x7552, 0x7557, - 0x755E, 0x755F, 0x7561, 0x756F, 0x7571, 0x7579, 0x757A, 0x757B, - 0x757C, 0x757D, 0x757E, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593, - 0x7595, 0x7599, 0x759C, 0x75A2, 0x75A4, 0x75B4, 0x75BA, 0x75BF, - 0x75C0, 0x75C1, 0x75C4, 0x75C6, 0x75CC, 0x75CE, 0x75CF, 0x75D7, - 0x75DC, 0x75DF, 0x75E0, 0x75E1, 0x75E4, 0x75E7, 0x75EC, 0x75EE, - 0x75EF, 0x75F1, 0x75F9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607, - 0x7608, 0x760A, 0x760C, 0x760F, 0x7612, 0x7613, 0x7615, 0x7616, - 0x7619, 0x761B, 0x761C, 0x761D, 0x761E, 0x7623, 0x7625, 0x7626, - 0x7629, 0x762D, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639, -}; -static const unsigned short euc_to_utf8_8FCE[] = { - 0x763A, 0x763C, 0x764A, 0x7640, 0x7641, 0x7643, 0x7644, - 0x7645, 0x7649, 0x764B, 0x7655, 0x7659, 0x765F, 0x7664, 0x7665, - 0x766D, 0x766E, 0x766F, 0x7671, 0x7674, 0x7681, 0x7685, 0x768C, - 0x768D, 0x7695, 0x769B, 0x769C, 0x769D, 0x769F, 0x76A0, 0x76A2, - 0x76A3, 0x76A4, 0x76A5, 0x76A6, 0x76A7, 0x76A8, 0x76AA, 0x76AD, - 0x76BD, 0x76C1, 0x76C5, 0x76C9, 0x76CB, 0x76CC, 0x76CE, 0x76D4, - 0x76D9, 0x76E0, 0x76E6, 0x76E8, 0x76EC, 0x76F0, 0x76F1, 0x76F6, - 0x76F9, 0x76FC, 0x7700, 0x7706, 0x770A, 0x770E, 0x7712, 0x7714, - 0x7715, 0x7717, 0x7719, 0x771A, 0x771C, 0x7722, 0x7728, 0x772D, - 0x772E, 0x772F, 0x7734, 0x7735, 0x7736, 0x7739, 0x773D, 0x773E, - 0x7742, 0x7745, 0x7746, 0x774A, 0x774D, 0x774E, 0x774F, 0x7752, - 0x7756, 0x7757, 0x775C, 0x775E, 0x775F, 0x7760, 0x7762, -}; -static const unsigned short euc_to_utf8_8FCF[] = { - 0x7764, 0x7767, 0x776A, 0x776C, 0x7770, 0x7772, 0x7773, - 0x7774, 0x777A, 0x777D, 0x7780, 0x7784, 0x778C, 0x778D, 0x7794, - 0x7795, 0x7796, 0x779A, 0x779F, 0x77A2, 0x77A7, 0x77AA, 0x77AE, - 0x77AF, 0x77B1, 0x77B5, 0x77BE, 0x77C3, 0x77C9, 0x77D1, 0x77D2, - 0x77D5, 0x77D9, 0x77DE, 0x77DF, 0x77E0, 0x77E4, 0x77E6, 0x77EA, - 0x77EC, 0x77F0, 0x77F1, 0x77F4, 0x77F8, 0x77FB, 0x7805, 0x7806, - 0x7809, 0x780D, 0x780E, 0x7811, 0x781D, 0x7821, 0x7822, 0x7823, - 0x782D, 0x782E, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847, - 0x7848, 0x784C, 0x784E, 0x7852, 0x785C, 0x785E, 0x7860, 0x7861, - 0x7863, 0x7864, 0x7868, 0x786A, 0x786E, 0x787A, 0x787E, 0x788A, - 0x788F, 0x7894, 0x7898, 0x78A1, 0x789D, 0x789E, 0x789F, 0x78A4, - 0x78A8, 0x78AC, 0x78AD, 0x78B0, 0x78B1, 0x78B2, 0x78B3, -}; -static const unsigned short euc_to_utf8_8FD0[] = { - 0x78BB, 0x78BD, 0x78BF, 0x78C7, 0x78C8, 0x78C9, 0x78CC, - 0x78CE, 0x78D2, 0x78D3, 0x78D5, 0x78D6, 0x78E4, 0x78DB, 0x78DF, - 0x78E0, 0x78E1, 0x78E6, 0x78EA, 0x78F2, 0x78F3, 0x7900, 0x78F6, - 0x78F7, 0x78FA, 0x78FB, 0x78FF, 0x7906, 0x790C, 0x7910, 0x791A, - 0x791C, 0x791E, 0x791F, 0x7920, 0x7925, 0x7927, 0x7929, 0x792D, - 0x7931, 0x7934, 0x7935, 0x793B, 0x793D, 0x793F, 0x7944, 0x7945, - 0x7946, 0x794A, 0x794B, 0x794F, 0x7951, 0x7954, 0x7958, 0x795B, - 0x795C, 0x7967, 0x7969, 0x796B, 0x7972, 0x7979, 0x797B, 0x797C, - 0x797E, 0x798B, 0x798C, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996, - 0x7998, 0x799B, 0x799C, 0x79A1, 0x79A8, 0x79A9, 0x79AB, 0x79AF, - 0x79B1, 0x79B4, 0x79B8, 0x79BB, 0x79C2, 0x79C4, 0x79C7, 0x79C8, - 0x79CA, 0x79CF, 0x79D4, 0x79D6, 0x79DA, 0x79DD, 0x79DE, -}; -static const unsigned short euc_to_utf8_8FD1[] = { - 0x79E0, 0x79E2, 0x79E5, 0x79EA, 0x79EB, 0x79ED, 0x79F1, - 0x79F8, 0x79FC, 0x7A02, 0x7A03, 0x7A07, 0x7A09, 0x7A0A, 0x7A0C, - 0x7A11, 0x7A15, 0x7A1B, 0x7A1E, 0x7A21, 0x7A27, 0x7A2B, 0x7A2D, - 0x7A2F, 0x7A30, 0x7A34, 0x7A35, 0x7A38, 0x7A39, 0x7A3A, 0x7A44, - 0x7A45, 0x7A47, 0x7A48, 0x7A4C, 0x7A55, 0x7A56, 0x7A59, 0x7A5C, - 0x7A5D, 0x7A5F, 0x7A60, 0x7A65, 0x7A67, 0x7A6A, 0x7A6D, 0x7A75, - 0x7A78, 0x7A7E, 0x7A80, 0x7A82, 0x7A85, 0x7A86, 0x7A8A, 0x7A8B, - 0x7A90, 0x7A91, 0x7A94, 0x7A9E, 0x7AA0, 0x7AA3, 0x7AAC, 0x7AB3, - 0x7AB5, 0x7AB9, 0x7ABB, 0x7ABC, 0x7AC6, 0x7AC9, 0x7ACC, 0x7ACE, - 0x7AD1, 0x7ADB, 0x7AE8, 0x7AE9, 0x7AEB, 0x7AEC, 0x7AF1, 0x7AF4, - 0x7AFB, 0x7AFD, 0x7AFE, 0x7B07, 0x7B14, 0x7B1F, 0x7B23, 0x7B27, - 0x7B29, 0x7B2A, 0x7B2B, 0x7B2D, 0x7B2E, 0x7B2F, 0x7B30, -}; -static const unsigned short euc_to_utf8_8FD2[] = { - 0x7B31, 0x7B34, 0x7B3D, 0x7B3F, 0x7B40, 0x7B41, 0x7B47, - 0x7B4E, 0x7B55, 0x7B60, 0x7B64, 0x7B66, 0x7B69, 0x7B6A, 0x7B6D, - 0x7B6F, 0x7B72, 0x7B73, 0x7B77, 0x7B84, 0x7B89, 0x7B8E, 0x7B90, - 0x7B91, 0x7B96, 0x7B9B, 0x7B9E, 0x7BA0, 0x7BA5, 0x7BAC, 0x7BAF, - 0x7BB0, 0x7BB2, 0x7BB5, 0x7BB6, 0x7BBA, 0x7BBB, 0x7BBC, 0x7BBD, - 0x7BC2, 0x7BC5, 0x7BC8, 0x7BCA, 0x7BD4, 0x7BD6, 0x7BD7, 0x7BD9, - 0x7BDA, 0x7BDB, 0x7BE8, 0x7BEA, 0x7BF2, 0x7BF4, 0x7BF5, 0x7BF8, - 0x7BF9, 0x7BFA, 0x7BFC, 0x7BFE, 0x7C01, 0x7C02, 0x7C03, 0x7C04, - 0x7C06, 0x7C09, 0x7C0B, 0x7C0C, 0x7C0E, 0x7C0F, 0x7C19, 0x7C1B, - 0x7C20, 0x7C25, 0x7C26, 0x7C28, 0x7C2C, 0x7C31, 0x7C33, 0x7C34, - 0x7C36, 0x7C39, 0x7C3A, 0x7C46, 0x7C4A, 0x7C55, 0x7C51, 0x7C52, - 0x7C53, 0x7C59, 0x7C5A, 0x7C5B, 0x7C5C, 0x7C5D, 0x7C5E, -}; -static const unsigned short euc_to_utf8_8FD3[] = { - 0x7C61, 0x7C63, 0x7C67, 0x7C69, 0x7C6D, 0x7C6E, 0x7C70, - 0x7C72, 0x7C79, 0x7C7C, 0x7C7D, 0x7C86, 0x7C87, 0x7C8F, 0x7C94, - 0x7C9E, 0x7CA0, 0x7CA6, 0x7CB0, 0x7CB6, 0x7CB7, 0x7CBA, 0x7CBB, - 0x7CBC, 0x7CBF, 0x7CC4, 0x7CC7, 0x7CC8, 0x7CC9, 0x7CCD, 0x7CCF, - 0x7CD3, 0x7CD4, 0x7CD5, 0x7CD7, 0x7CD9, 0x7CDA, 0x7CDD, 0x7CE6, - 0x7CE9, 0x7CEB, 0x7CF5, 0x7D03, 0x7D07, 0x7D08, 0x7D09, 0x7D0F, - 0x7D11, 0x7D12, 0x7D13, 0x7D16, 0x7D1D, 0x7D1E, 0x7D23, 0x7D26, - 0x7D2A, 0x7D2D, 0x7D31, 0x7D3C, 0x7D3D, 0x7D3E, 0x7D40, 0x7D41, - 0x7D47, 0x7D48, 0x7D4D, 0x7D51, 0x7D53, 0x7D57, 0x7D59, 0x7D5A, - 0x7D5C, 0x7D5D, 0x7D65, 0x7D67, 0x7D6A, 0x7D70, 0x7D78, 0x7D7A, - 0x7D7B, 0x7D7F, 0x7D81, 0x7D82, 0x7D83, 0x7D85, 0x7D86, 0x7D88, - 0x7D8B, 0x7D8C, 0x7D8D, 0x7D91, 0x7D96, 0x7D97, 0x7D9D, -}; -static const unsigned short euc_to_utf8_8FD4[] = { - 0x7D9E, 0x7DA6, 0x7DA7, 0x7DAA, 0x7DB3, 0x7DB6, 0x7DB7, - 0x7DB9, 0x7DC2, 0x7DC3, 0x7DC4, 0x7DC5, 0x7DC6, 0x7DCC, 0x7DCD, - 0x7DCE, 0x7DD7, 0x7DD9, 0x7E00, 0x7DE2, 0x7DE5, 0x7DE6, 0x7DEA, - 0x7DEB, 0x7DED, 0x7DF1, 0x7DF5, 0x7DF6, 0x7DF9, 0x7DFA, 0x7E08, - 0x7E10, 0x7E11, 0x7E15, 0x7E17, 0x7E1C, 0x7E1D, 0x7E20, 0x7E27, - 0x7E28, 0x7E2C, 0x7E2D, 0x7E2F, 0x7E33, 0x7E36, 0x7E3F, 0x7E44, - 0x7E45, 0x7E47, 0x7E4E, 0x7E50, 0x7E52, 0x7E58, 0x7E5F, 0x7E61, - 0x7E62, 0x7E65, 0x7E6B, 0x7E6E, 0x7E6F, 0x7E73, 0x7E78, 0x7E7E, - 0x7E81, 0x7E86, 0x7E87, 0x7E8A, 0x7E8D, 0x7E91, 0x7E95, 0x7E98, - 0x7E9A, 0x7E9D, 0x7E9E, 0x7F3C, 0x7F3B, 0x7F3D, 0x7F3E, 0x7F3F, - 0x7F43, 0x7F44, 0x7F47, 0x7F4F, 0x7F52, 0x7F53, 0x7F5B, 0x7F5C, - 0x7F5D, 0x7F61, 0x7F63, 0x7F64, 0x7F65, 0x7F66, 0x7F6D, -}; -static const unsigned short euc_to_utf8_8FD5[] = { - 0x7F71, 0x7F7D, 0x7F7E, 0x7F7F, 0x7F80, 0x7F8B, 0x7F8D, - 0x7F8F, 0x7F90, 0x7F91, 0x7F96, 0x7F97, 0x7F9C, 0x7FA1, 0x7FA2, - 0x7FA6, 0x7FAA, 0x7FAD, 0x7FB4, 0x7FBC, 0x7FBF, 0x7FC0, 0x7FC3, - 0x7FC8, 0x7FCE, 0x7FCF, 0x7FDB, 0x7FDF, 0x7FE3, 0x7FE5, 0x7FE8, - 0x7FEC, 0x7FEE, 0x7FEF, 0x7FF2, 0x7FFA, 0x7FFD, 0x7FFE, 0x7FFF, - 0x8007, 0x8008, 0x800A, 0x800D, 0x800E, 0x800F, 0x8011, 0x8013, - 0x8014, 0x8016, 0x801D, 0x801E, 0x801F, 0x8020, 0x8024, 0x8026, - 0x802C, 0x802E, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803A, - 0x803C, 0x803E, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806D, - 0x8071, 0x8075, 0x8081, 0x8088, 0x808E, 0x809C, 0x809E, 0x80A6, - 0x80A7, 0x80AB, 0x80B8, 0x80B9, 0x80C8, 0x80CD, 0x80CF, 0x80D2, - 0x80D4, 0x80D5, 0x80D7, 0x80D8, 0x80E0, 0x80ED, 0x80EE, -}; -static const unsigned short euc_to_utf8_8FD6[] = { - 0x80F0, 0x80F2, 0x80F3, 0x80F6, 0x80F9, 0x80FA, 0x80FE, - 0x8103, 0x810B, 0x8116, 0x8117, 0x8118, 0x811C, 0x811E, 0x8120, - 0x8124, 0x8127, 0x812C, 0x8130, 0x8135, 0x813A, 0x813C, 0x8145, - 0x8147, 0x814A, 0x814C, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167, - 0x8168, 0x8169, 0x816D, 0x816F, 0x8177, 0x8181, 0x8190, 0x8184, - 0x8185, 0x8186, 0x818B, 0x818E, 0x8196, 0x8198, 0x819B, 0x819E, - 0x81A2, 0x81AE, 0x81B2, 0x81B4, 0x81BB, 0x81CB, 0x81C3, 0x81C5, - 0x81CA, 0x81CE, 0x81CF, 0x81D5, 0x81D7, 0x81DB, 0x81DD, 0x81DE, - 0x81E1, 0x81E4, 0x81EB, 0x81EC, 0x81F0, 0x81F1, 0x81F2, 0x81F5, - 0x81F6, 0x81F8, 0x81F9, 0x81FD, 0x81FF, 0x8200, 0x8203, 0x820F, - 0x8213, 0x8214, 0x8219, 0x821A, 0x821D, 0x8221, 0x8222, 0x8228, - 0x8232, 0x8234, 0x823A, 0x8243, 0x8244, 0x8245, 0x8246, -}; -static const unsigned short euc_to_utf8_8FD7[] = { - 0x824B, 0x824E, 0x824F, 0x8251, 0x8256, 0x825C, 0x8260, - 0x8263, 0x8267, 0x826D, 0x8274, 0x827B, 0x827D, 0x827F, 0x8280, - 0x8281, 0x8283, 0x8284, 0x8287, 0x8289, 0x828A, 0x828E, 0x8291, - 0x8294, 0x8296, 0x8298, 0x829A, 0x829B, 0x82A0, 0x82A1, 0x82A3, - 0x82A4, 0x82A7, 0x82A8, 0x82A9, 0x82AA, 0x82AE, 0x82B0, 0x82B2, - 0x82B4, 0x82B7, 0x82BA, 0x82BC, 0x82BE, 0x82BF, 0x82C6, 0x82D0, - 0x82D5, 0x82DA, 0x82E0, 0x82E2, 0x82E4, 0x82E8, 0x82EA, 0x82ED, - 0x82EF, 0x82F6, 0x82F7, 0x82FD, 0x82FE, 0x8300, 0x8301, 0x8307, - 0x8308, 0x830A, 0x830B, 0x8354, 0x831B, 0x831D, 0x831E, 0x831F, - 0x8321, 0x8322, 0x832C, 0x832D, 0x832E, 0x8330, 0x8333, 0x8337, - 0x833A, 0x833C, 0x833D, 0x8342, 0x8343, 0x8344, 0x8347, 0x834D, - 0x834E, 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378, -}; -static const unsigned short euc_to_utf8_8FD8[] = { - 0x837D, 0x837F, 0x8380, 0x8382, 0x8384, 0x8386, 0x838D, - 0x8392, 0x8394, 0x8395, 0x8398, 0x8399, 0x839B, 0x839C, 0x839D, - 0x83A6, 0x83A7, 0x83A9, 0x83AC, 0x83BE, 0x83BF, 0x83C0, 0x83C7, - 0x83C9, 0x83CF, 0x83D0, 0x83D1, 0x83D4, 0x83DD, 0x8353, 0x83E8, - 0x83EA, 0x83F6, 0x83F8, 0x83F9, 0x83FC, 0x8401, 0x8406, 0x840A, - 0x840F, 0x8411, 0x8415, 0x8419, 0x83AD, 0x842F, 0x8439, 0x8445, - 0x8447, 0x8448, 0x844A, 0x844D, 0x844F, 0x8451, 0x8452, 0x8456, - 0x8458, 0x8459, 0x845A, 0x845C, 0x8460, 0x8464, 0x8465, 0x8467, - 0x846A, 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847C, 0x847D, - 0x8481, 0x8485, 0x8492, 0x8493, 0x8495, 0x849E, 0x84A6, 0x84A8, - 0x84A9, 0x84AA, 0x84AF, 0x84B1, 0x84B4, 0x84BA, 0x84BD, 0x84BE, - 0x84C0, 0x84C2, 0x84C7, 0x84C8, 0x84CC, 0x84CF, 0x84D3, -}; -static const unsigned short euc_to_utf8_8FD9[] = { - 0x84DC, 0x84E7, 0x84EA, 0x84EF, 0x84F0, 0x84F1, 0x84F2, - 0x84F7, 0x8532, 0x84FA, 0x84FB, 0x84FD, 0x8502, 0x8503, 0x8507, - 0x850C, 0x850E, 0x8510, 0x851C, 0x851E, 0x8522, 0x8523, 0x8524, - 0x8525, 0x8527, 0x852A, 0x852B, 0x852F, 0x8533, 0x8534, 0x8536, - 0x853F, 0x8546, 0x854F, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556, - 0x8559, 0x855C, 0x855D, 0x855E, 0x855F, 0x8560, 0x8561, 0x8562, - 0x8564, 0x856B, 0x856F, 0x8579, 0x857A, 0x857B, 0x857D, 0x857F, - 0x8581, 0x8585, 0x8586, 0x8589, 0x858B, 0x858C, 0x858F, 0x8593, - 0x8598, 0x859D, 0x859F, 0x85A0, 0x85A2, 0x85A5, 0x85A7, 0x85B4, - 0x85B6, 0x85B7, 0x85B8, 0x85BC, 0x85BD, 0x85BE, 0x85BF, 0x85C2, - 0x85C7, 0x85CA, 0x85CB, 0x85CE, 0x85AD, 0x85D8, 0x85DA, 0x85DF, - 0x85E0, 0x85E6, 0x85E8, 0x85ED, 0x85F3, 0x85F6, 0x85FC, -}; -static const unsigned short euc_to_utf8_8FDA[] = { - 0x85FF, 0x8600, 0x8604, 0x8605, 0x860D, 0x860E, 0x8610, - 0x8611, 0x8612, 0x8618, 0x8619, 0x861B, 0x861E, 0x8621, 0x8627, - 0x8629, 0x8636, 0x8638, 0x863A, 0x863C, 0x863D, 0x8640, 0x8642, - 0x8646, 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865D, - 0x8660, 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866C, 0x866F, - 0x8675, 0x8676, 0x8677, 0x867A, 0x868D, 0x8691, 0x8696, 0x8698, - 0x869A, 0x869C, 0x86A1, 0x86A6, 0x86A7, 0x86A8, 0x86AD, 0x86B1, - 0x86B3, 0x86B4, 0x86B5, 0x86B7, 0x86B8, 0x86B9, 0x86BF, 0x86C0, - 0x86C1, 0x86C3, 0x86C5, 0x86D1, 0x86D2, 0x86D5, 0x86D7, 0x86DA, - 0x86DC, 0x86E0, 0x86E3, 0x86E5, 0x86E7, 0x8688, 0x86FA, 0x86FC, - 0x86FD, 0x8704, 0x8705, 0x8707, 0x870B, 0x870E, 0x870F, 0x8710, - 0x8713, 0x8714, 0x8719, 0x871E, 0x871F, 0x8721, 0x8723, -}; -static const unsigned short euc_to_utf8_8FDB[] = { - 0x8728, 0x872E, 0x872F, 0x8731, 0x8732, 0x8739, 0x873A, - 0x873C, 0x873D, 0x873E, 0x8740, 0x8743, 0x8745, 0x874D, 0x8758, - 0x875D, 0x8761, 0x8764, 0x8765, 0x876F, 0x8771, 0x8772, 0x877B, - 0x8783, 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878B, - 0x878C, 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879E, - 0x87A0, 0x87A3, 0x87A7, 0x87AC, 0x87AD, 0x87AE, 0x87B1, 0x87B5, - 0x87BE, 0x87BF, 0x87C1, 0x87C8, 0x87C9, 0x87CA, 0x87CE, 0x87D5, - 0x87D6, 0x87D9, 0x87DA, 0x87DC, 0x87DF, 0x87E2, 0x87E3, 0x87E4, - 0x87EA, 0x87EB, 0x87ED, 0x87F1, 0x87F3, 0x87F8, 0x87FA, 0x87FF, - 0x8801, 0x8803, 0x8806, 0x8809, 0x880A, 0x880B, 0x8810, 0x8819, - 0x8812, 0x8813, 0x8814, 0x8818, 0x881A, 0x881B, 0x881C, 0x881E, - 0x881F, 0x8828, 0x882D, 0x882E, 0x8830, 0x8832, 0x8835, -}; -static const unsigned short euc_to_utf8_8FDC[] = { - 0x883A, 0x883C, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849, - 0x884A, 0x884B, 0x884E, 0x8851, 0x8855, 0x8856, 0x8858, 0x885A, - 0x885C, 0x885F, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887B, - 0x8880, 0x8898, 0x889A, 0x889B, 0x889C, 0x889F, 0x88A0, 0x88A8, - 0x88AA, 0x88BA, 0x88BD, 0x88BE, 0x88C0, 0x88CA, 0x88CB, 0x88CC, - 0x88CD, 0x88CE, 0x88D1, 0x88D2, 0x88D3, 0x88DB, 0x88DE, 0x88E7, - 0x88EF, 0x88F0, 0x88F1, 0x88F5, 0x88F7, 0x8901, 0x8906, 0x890D, - 0x890E, 0x890F, 0x8915, 0x8916, 0x8918, 0x8919, 0x891A, 0x891C, - 0x8920, 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935, - 0x8939, 0x893A, 0x893E, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949, - 0x894F, 0x8952, 0x8957, 0x895A, 0x895B, 0x895C, 0x8961, 0x8962, - 0x8963, 0x896B, 0x896E, 0x8970, 0x8973, 0x8975, 0x897A, -}; -static const unsigned short euc_to_utf8_8FDD[] = { - 0x897B, 0x897C, 0x897D, 0x8989, 0x898D, 0x8990, 0x8994, - 0x8995, 0x899B, 0x899C, 0x899F, 0x89A0, 0x89A5, 0x89B0, 0x89B4, - 0x89B5, 0x89B6, 0x89B7, 0x89BC, 0x89D4, 0x89D5, 0x89D6, 0x89D7, - 0x89D8, 0x89E5, 0x89E9, 0x89EB, 0x89ED, 0x89F1, 0x89F3, 0x89F6, - 0x89F9, 0x89FD, 0x89FF, 0x8A04, 0x8A05, 0x8A07, 0x8A0F, 0x8A11, - 0x8A12, 0x8A14, 0x8A15, 0x8A1E, 0x8A20, 0x8A22, 0x8A24, 0x8A26, - 0x8A2B, 0x8A2C, 0x8A2F, 0x8A35, 0x8A37, 0x8A3D, 0x8A3E, 0x8A40, - 0x8A43, 0x8A45, 0x8A47, 0x8A49, 0x8A4D, 0x8A4E, 0x8A53, 0x8A56, - 0x8A57, 0x8A58, 0x8A5C, 0x8A5D, 0x8A61, 0x8A65, 0x8A67, 0x8A75, - 0x8A76, 0x8A77, 0x8A79, 0x8A7A, 0x8A7B, 0x8A7E, 0x8A7F, 0x8A80, - 0x8A83, 0x8A86, 0x8A8B, 0x8A8F, 0x8A90, 0x8A92, 0x8A96, 0x8A97, - 0x8A99, 0x8A9F, 0x8AA7, 0x8AA9, 0x8AAE, 0x8AAF, 0x8AB3, -}; -static const unsigned short euc_to_utf8_8FDE[] = { - 0x8AB6, 0x8AB7, 0x8ABB, 0x8ABE, 0x8AC3, 0x8AC6, 0x8AC8, - 0x8AC9, 0x8ACA, 0x8AD1, 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD7, 0x8ADD, - 0x8ADF, 0x8AEC, 0x8AF0, 0x8AF4, 0x8AF5, 0x8AF6, 0x8AFC, 0x8AFF, - 0x8B05, 0x8B06, 0x8B0B, 0x8B11, 0x8B1C, 0x8B1E, 0x8B1F, 0x8B0A, - 0x8B2D, 0x8B30, 0x8B37, 0x8B3C, 0x8B42, 0x8B43, 0x8B44, 0x8B45, - 0x8B46, 0x8B48, 0x8B52, 0x8B53, 0x8B54, 0x8B59, 0x8B4D, 0x8B5E, - 0x8B63, 0x8B6D, 0x8B76, 0x8B78, 0x8B79, 0x8B7C, 0x8B7E, 0x8B81, - 0x8B84, 0x8B85, 0x8B8B, 0x8B8D, 0x8B8F, 0x8B94, 0x8B95, 0x8B9C, - 0x8B9E, 0x8B9F, 0x8C38, 0x8C39, 0x8C3D, 0x8C3E, 0x8C45, 0x8C47, - 0x8C49, 0x8C4B, 0x8C4F, 0x8C51, 0x8C53, 0x8C54, 0x8C57, 0x8C58, - 0x8C5B, 0x8C5D, 0x8C59, 0x8C63, 0x8C64, 0x8C66, 0x8C68, 0x8C69, - 0x8C6D, 0x8C73, 0x8C75, 0x8C76, 0x8C7B, 0x8C7E, 0x8C86, -}; -static const unsigned short euc_to_utf8_8FDF[] = { - 0x8C87, 0x8C8B, 0x8C90, 0x8C92, 0x8C93, 0x8C99, 0x8C9B, - 0x8C9C, 0x8CA4, 0x8CB9, 0x8CBA, 0x8CC5, 0x8CC6, 0x8CC9, 0x8CCB, - 0x8CCF, 0x8CD6, 0x8CD5, 0x8CD9, 0x8CDD, 0x8CE1, 0x8CE8, 0x8CEC, - 0x8CEF, 0x8CF0, 0x8CF2, 0x8CF5, 0x8CF7, 0x8CF8, 0x8CFE, 0x8CFF, - 0x8D01, 0x8D03, 0x8D09, 0x8D12, 0x8D17, 0x8D1B, 0x8D65, 0x8D69, - 0x8D6C, 0x8D6E, 0x8D7F, 0x8D82, 0x8D84, 0x8D88, 0x8D8D, 0x8D90, - 0x8D91, 0x8D95, 0x8D9E, 0x8D9F, 0x8DA0, 0x8DA6, 0x8DAB, 0x8DAC, - 0x8DAF, 0x8DB2, 0x8DB5, 0x8DB7, 0x8DB9, 0x8DBB, 0x8DC0, 0x8DC5, - 0x8DC6, 0x8DC7, 0x8DC8, 0x8DCA, 0x8DCE, 0x8DD1, 0x8DD4, 0x8DD5, - 0x8DD7, 0x8DD9, 0x8DE4, 0x8DE5, 0x8DE7, 0x8DEC, 0x8DF0, 0x8DBC, - 0x8DF1, 0x8DF2, 0x8DF4, 0x8DFD, 0x8E01, 0x8E04, 0x8E05, 0x8E06, - 0x8E0B, 0x8E11, 0x8E14, 0x8E16, 0x8E20, 0x8E21, 0x8E22, -}; -static const unsigned short euc_to_utf8_8FE0[] = { - 0x8E23, 0x8E26, 0x8E27, 0x8E31, 0x8E33, 0x8E36, 0x8E37, - 0x8E38, 0x8E39, 0x8E3D, 0x8E40, 0x8E41, 0x8E4B, 0x8E4D, 0x8E4E, - 0x8E4F, 0x8E54, 0x8E5B, 0x8E5C, 0x8E5D, 0x8E5E, 0x8E61, 0x8E62, - 0x8E69, 0x8E6C, 0x8E6D, 0x8E6F, 0x8E70, 0x8E71, 0x8E79, 0x8E7A, - 0x8E7B, 0x8E82, 0x8E83, 0x8E89, 0x8E90, 0x8E92, 0x8E95, 0x8E9A, - 0x8E9B, 0x8E9D, 0x8E9E, 0x8EA2, 0x8EA7, 0x8EA9, 0x8EAD, 0x8EAE, - 0x8EB3, 0x8EB5, 0x8EBA, 0x8EBB, 0x8EC0, 0x8EC1, 0x8EC3, 0x8EC4, - 0x8EC7, 0x8ECF, 0x8ED1, 0x8ED4, 0x8EDC, 0x8EE8, 0x8EEE, 0x8EF0, - 0x8EF1, 0x8EF7, 0x8EF9, 0x8EFA, 0x8EED, 0x8F00, 0x8F02, 0x8F07, - 0x8F08, 0x8F0F, 0x8F10, 0x8F16, 0x8F17, 0x8F18, 0x8F1E, 0x8F20, - 0x8F21, 0x8F23, 0x8F25, 0x8F27, 0x8F28, 0x8F2C, 0x8F2D, 0x8F2E, - 0x8F34, 0x8F35, 0x8F36, 0x8F37, 0x8F3A, 0x8F40, 0x8F41, -}; -static const unsigned short euc_to_utf8_8FE1[] = { - 0x8F43, 0x8F47, 0x8F4F, 0x8F51, 0x8F52, 0x8F53, 0x8F54, - 0x8F55, 0x8F58, 0x8F5D, 0x8F5E, 0x8F65, 0x8F9D, 0x8FA0, 0x8FA1, - 0x8FA4, 0x8FA5, 0x8FA6, 0x8FB5, 0x8FB6, 0x8FB8, 0x8FBE, 0x8FC0, - 0x8FC1, 0x8FC6, 0x8FCA, 0x8FCB, 0x8FCD, 0x8FD0, 0x8FD2, 0x8FD3, - 0x8FD5, 0x8FE0, 0x8FE3, 0x8FE4, 0x8FE8, 0x8FEE, 0x8FF1, 0x8FF5, - 0x8FF6, 0x8FFB, 0x8FFE, 0x9002, 0x9004, 0x9008, 0x900C, 0x9018, - 0x901B, 0x9028, 0x9029, 0x902F, 0x902A, 0x902C, 0x902D, 0x9033, - 0x9034, 0x9037, 0x903F, 0x9043, 0x9044, 0x904C, 0x905B, 0x905D, - 0x9062, 0x9066, 0x9067, 0x906C, 0x9070, 0x9074, 0x9079, 0x9085, - 0x9088, 0x908B, 0x908C, 0x908E, 0x9090, 0x9095, 0x9097, 0x9098, - 0x9099, 0x909B, 0x90A0, 0x90A1, 0x90A2, 0x90A5, 0x90B0, 0x90B2, - 0x90B3, 0x90B4, 0x90B6, 0x90BD, 0x90CC, 0x90BE, 0x90C3, -}; -static const unsigned short euc_to_utf8_8FE2[] = { - 0x90C4, 0x90C5, 0x90C7, 0x90C8, 0x90D5, 0x90D7, 0x90D8, - 0x90D9, 0x90DC, 0x90DD, 0x90DF, 0x90E5, 0x90D2, 0x90F6, 0x90EB, - 0x90EF, 0x90F0, 0x90F4, 0x90FE, 0x90FF, 0x9100, 0x9104, 0x9105, - 0x9106, 0x9108, 0x910D, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118, - 0x911A, 0x911C, 0x911E, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127, - 0x9129, 0x912E, 0x912F, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139, - 0x913A, 0x913C, 0x913D, 0x9143, 0x9147, 0x9148, 0x914F, 0x9153, - 0x9157, 0x9159, 0x915A, 0x915B, 0x9161, 0x9164, 0x9167, 0x916D, - 0x9174, 0x9179, 0x917A, 0x917B, 0x9181, 0x9183, 0x9185, 0x9186, - 0x918A, 0x918E, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919E, - 0x91A1, 0x91A6, 0x91A8, 0x91AC, 0x91AD, 0x91AE, 0x91B0, 0x91B1, - 0x91B2, 0x91B3, 0x91B6, 0x91BB, 0x91BC, 0x91BD, 0x91BF, -}; -static const unsigned short euc_to_utf8_8FE3[] = { - 0x91C2, 0x91C3, 0x91C5, 0x91D3, 0x91D4, 0x91D7, 0x91D9, - 0x91DA, 0x91DE, 0x91E4, 0x91E5, 0x91E9, 0x91EA, 0x91EC, 0x91ED, - 0x91EE, 0x91EF, 0x91F0, 0x91F1, 0x91F7, 0x91F9, 0x91FB, 0x91FD, - 0x9200, 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920A, - 0x920C, 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921C, 0x921D, - 0x9223, 0x9224, 0x9225, 0x9226, 0x9228, 0x922E, 0x922F, 0x9230, - 0x9233, 0x9235, 0x9236, 0x9238, 0x9239, 0x923A, 0x923C, 0x923E, - 0x9240, 0x9242, 0x9243, 0x9246, 0x9247, 0x924A, 0x924D, 0x924E, - 0x924F, 0x9251, 0x9258, 0x9259, 0x925C, 0x925D, 0x9260, 0x9261, - 0x9265, 0x9267, 0x9268, 0x9269, 0x926E, 0x926F, 0x9270, 0x9275, - 0x9276, 0x9277, 0x9278, 0x9279, 0x927B, 0x927C, 0x927D, 0x927F, - 0x9288, 0x9289, 0x928A, 0x928D, 0x928E, 0x9292, 0x9297, -}; -static const unsigned short euc_to_utf8_8FE4[] = { - 0x9299, 0x929F, 0x92A0, 0x92A4, 0x92A5, 0x92A7, 0x92A8, - 0x92AB, 0x92AF, 0x92B2, 0x92B6, 0x92B8, 0x92BA, 0x92BB, 0x92BC, - 0x92BD, 0x92BF, 0x92C0, 0x92C1, 0x92C2, 0x92C3, 0x92C5, 0x92C6, - 0x92C7, 0x92C8, 0x92CB, 0x92CC, 0x92CD, 0x92CE, 0x92D0, 0x92D3, - 0x92D5, 0x92D7, 0x92D8, 0x92D9, 0x92DC, 0x92DD, 0x92DF, 0x92E0, - 0x92E1, 0x92E3, 0x92E5, 0x92E7, 0x92E8, 0x92EC, 0x92EE, 0x92F0, - 0x92F9, 0x92FB, 0x92FF, 0x9300, 0x9302, 0x9308, 0x930D, 0x9311, - 0x9314, 0x9315, 0x931C, 0x931D, 0x931E, 0x931F, 0x9321, 0x9324, - 0x9325, 0x9327, 0x9329, 0x932A, 0x9333, 0x9334, 0x9336, 0x9337, - 0x9347, 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357, - 0x9358, 0x935A, 0x935E, 0x9364, 0x9365, 0x9367, 0x9369, 0x936A, - 0x936D, 0x936F, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376, -}; -static const unsigned short euc_to_utf8_8FE5[] = { - 0x937A, 0x937D, 0x937F, 0x9380, 0x9381, 0x9382, 0x9388, - 0x938A, 0x938B, 0x938D, 0x938F, 0x9392, 0x9395, 0x9398, 0x939B, - 0x939E, 0x93A1, 0x93A3, 0x93A4, 0x93A6, 0x93A8, 0x93AB, 0x93B4, - 0x93B5, 0x93B6, 0x93BA, 0x93A9, 0x93C1, 0x93C4, 0x93C5, 0x93C6, - 0x93C7, 0x93C9, 0x93CA, 0x93CB, 0x93CC, 0x93CD, 0x93D3, 0x93D9, - 0x93DC, 0x93DE, 0x93DF, 0x93E2, 0x93E6, 0x93E7, 0x93F9, 0x93F7, - 0x93F8, 0x93FA, 0x93FB, 0x93FD, 0x9401, 0x9402, 0x9404, 0x9408, - 0x9409, 0x940D, 0x940E, 0x940F, 0x9415, 0x9416, 0x9417, 0x941F, - 0x942E, 0x942F, 0x9431, 0x9432, 0x9433, 0x9434, 0x943B, 0x943F, - 0x943D, 0x9443, 0x9445, 0x9448, 0x944A, 0x944C, 0x9455, 0x9459, - 0x945C, 0x945F, 0x9461, 0x9463, 0x9468, 0x946B, 0x946D, 0x946E, - 0x946F, 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579, -}; -static const unsigned short euc_to_utf8_8FE6[] = { - 0x957E, 0x9584, 0x9588, 0x958C, 0x958D, 0x958E, 0x959D, - 0x959E, 0x959F, 0x95A1, 0x95A6, 0x95A9, 0x95AB, 0x95AC, 0x95B4, - 0x95B6, 0x95BA, 0x95BD, 0x95BF, 0x95C6, 0x95C8, 0x95C9, 0x95CB, - 0x95D0, 0x95D1, 0x95D2, 0x95D3, 0x95D9, 0x95DA, 0x95DD, 0x95DE, - 0x95DF, 0x95E0, 0x95E4, 0x95E6, 0x961D, 0x961E, 0x9622, 0x9624, - 0x9625, 0x9626, 0x962C, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639, - 0x963A, 0x963C, 0x963D, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657, - 0x9658, 0x9661, 0x966E, 0x9674, 0x967B, 0x967C, 0x967E, 0x967F, - 0x9681, 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969A, - 0x969D, 0x969F, 0x96A4, 0x96A5, 0x96A6, 0x96A9, 0x96AE, 0x96AF, - 0x96B3, 0x96BA, 0x96CA, 0x96D2, 0x5DB2, 0x96D8, 0x96DA, 0x96DD, - 0x96DE, 0x96DF, 0x96E9, 0x96EF, 0x96F1, 0x96FA, 0x9702, -}; -static const unsigned short euc_to_utf8_8FE7[] = { - 0x9703, 0x9705, 0x9709, 0x971A, 0x971B, 0x971D, 0x9721, - 0x9722, 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974A, - 0x974E, 0x974F, 0x9755, 0x9757, 0x9758, 0x975A, 0x975B, 0x9763, - 0x9767, 0x976A, 0x976E, 0x9773, 0x9776, 0x9777, 0x9778, 0x977B, - 0x977D, 0x977F, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799, - 0x979A, 0x979E, 0x979F, 0x97A2, 0x97AC, 0x97AE, 0x97B1, 0x97B2, - 0x97B5, 0x97B6, 0x97B8, 0x97B9, 0x97BA, 0x97BC, 0x97BE, 0x97BF, - 0x97C1, 0x97C4, 0x97C5, 0x97C7, 0x97C9, 0x97CA, 0x97CC, 0x97CD, - 0x97CE, 0x97D0, 0x97D1, 0x97D4, 0x97D7, 0x97D8, 0x97D9, 0x97DD, - 0x97DE, 0x97E0, 0x97DB, 0x97E1, 0x97E4, 0x97EF, 0x97F1, 0x97F4, - 0x97F7, 0x97F8, 0x97FA, 0x9807, 0x980A, 0x9819, 0x980D, 0x980E, - 0x9814, 0x9816, 0x981C, 0x981E, 0x9820, 0x9823, 0x9826, -}; -static const unsigned short euc_to_utf8_8FE8[] = { - 0x982B, 0x982E, 0x982F, 0x9830, 0x9832, 0x9833, 0x9835, - 0x9825, 0x983E, 0x9844, 0x9847, 0x984A, 0x9851, 0x9852, 0x9853, - 0x9856, 0x9857, 0x9859, 0x985A, 0x9862, 0x9863, 0x9865, 0x9866, - 0x986A, 0x986C, 0x98AB, 0x98AD, 0x98AE, 0x98B0, 0x98B4, 0x98B7, - 0x98B8, 0x98BA, 0x98BB, 0x98BF, 0x98C2, 0x98C5, 0x98C8, 0x98CC, - 0x98E1, 0x98E3, 0x98E5, 0x98E6, 0x98E7, 0x98EA, 0x98F3, 0x98F6, - 0x9902, 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991A, - 0x991B, 0x991C, 0x991F, 0x9922, 0x9926, 0x9927, 0x992B, 0x9931, - 0x9932, 0x9933, 0x9934, 0x9935, 0x9939, 0x993A, 0x993B, 0x993C, - 0x9940, 0x9941, 0x9946, 0x9947, 0x9948, 0x994D, 0x994E, 0x9954, - 0x9958, 0x9959, 0x995B, 0x995C, 0x995E, 0x995F, 0x9960, 0x999B, - 0x999D, 0x999F, 0x99A6, 0x99B0, 0x99B1, 0x99B2, 0x99B5, -}; -static const unsigned short euc_to_utf8_8FE9[] = { - 0x99B9, 0x99BA, 0x99BD, 0x99BF, 0x99C3, 0x99C9, 0x99D3, - 0x99D4, 0x99D9, 0x99DA, 0x99DC, 0x99DE, 0x99E7, 0x99EA, 0x99EB, - 0x99EC, 0x99F0, 0x99F4, 0x99F5, 0x99F9, 0x99FD, 0x99FE, 0x9A02, - 0x9A03, 0x9A04, 0x9A0B, 0x9A0C, 0x9A10, 0x9A11, 0x9A16, 0x9A1E, - 0x9A20, 0x9A22, 0x9A23, 0x9A24, 0x9A27, 0x9A2D, 0x9A2E, 0x9A33, - 0x9A35, 0x9A36, 0x9A38, 0x9A47, 0x9A41, 0x9A44, 0x9A4A, 0x9A4B, - 0x9A4C, 0x9A4E, 0x9A51, 0x9A54, 0x9A56, 0x9A5D, 0x9AAA, 0x9AAC, - 0x9AAE, 0x9AAF, 0x9AB2, 0x9AB4, 0x9AB5, 0x9AB6, 0x9AB9, 0x9ABB, - 0x9ABE, 0x9ABF, 0x9AC1, 0x9AC3, 0x9AC6, 0x9AC8, 0x9ACE, 0x9AD0, - 0x9AD2, 0x9AD5, 0x9AD6, 0x9AD7, 0x9ADB, 0x9ADC, 0x9AE0, 0x9AE4, - 0x9AE5, 0x9AE7, 0x9AE9, 0x9AEC, 0x9AF2, 0x9AF3, 0x9AF5, 0x9AF9, - 0x9AFA, 0x9AFD, 0x9AFF, 0x9B00, 0x9B01, 0x9B02, 0x9B03, -}; -static const unsigned short euc_to_utf8_8FEA[] = { - 0x9B04, 0x9B05, 0x9B08, 0x9B09, 0x9B0B, 0x9B0C, 0x9B0D, - 0x9B0E, 0x9B10, 0x9B12, 0x9B16, 0x9B19, 0x9B1B, 0x9B1C, 0x9B20, - 0x9B26, 0x9B2B, 0x9B2D, 0x9B33, 0x9B34, 0x9B35, 0x9B37, 0x9B39, - 0x9B3A, 0x9B3D, 0x9B48, 0x9B4B, 0x9B4C, 0x9B55, 0x9B56, 0x9B57, - 0x9B5B, 0x9B5E, 0x9B61, 0x9B63, 0x9B65, 0x9B66, 0x9B68, 0x9B6A, - 0x9B6B, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B73, 0x9B75, 0x9B77, 0x9B78, - 0x9B79, 0x9B7F, 0x9B80, 0x9B84, 0x9B85, 0x9B86, 0x9B87, 0x9B89, - 0x9B8A, 0x9B8B, 0x9B8D, 0x9B8F, 0x9B90, 0x9B94, 0x9B9A, 0x9B9D, - 0x9B9E, 0x9BA6, 0x9BA7, 0x9BA9, 0x9BAC, 0x9BB0, 0x9BB1, 0x9BB2, - 0x9BB7, 0x9BB8, 0x9BBB, 0x9BBC, 0x9BBE, 0x9BBF, 0x9BC1, 0x9BC7, - 0x9BC8, 0x9BCE, 0x9BD0, 0x9BD7, 0x9BD8, 0x9BDD, 0x9BDF, 0x9BE5, - 0x9BE7, 0x9BEA, 0x9BEB, 0x9BEF, 0x9BF3, 0x9BF7, 0x9BF8, -}; -static const unsigned short euc_to_utf8_8FEB[] = { - 0x9BF9, 0x9BFA, 0x9BFD, 0x9BFF, 0x9C00, 0x9C02, 0x9C0B, - 0x9C0F, 0x9C11, 0x9C16, 0x9C18, 0x9C19, 0x9C1A, 0x9C1C, 0x9C1E, - 0x9C22, 0x9C23, 0x9C26, 0x9C27, 0x9C28, 0x9C29, 0x9C2A, 0x9C31, - 0x9C35, 0x9C36, 0x9C37, 0x9C3D, 0x9C41, 0x9C43, 0x9C44, 0x9C45, - 0x9C49, 0x9C4A, 0x9C4E, 0x9C4F, 0x9C50, 0x9C53, 0x9C54, 0x9C56, - 0x9C58, 0x9C5B, 0x9C5D, 0x9C5E, 0x9C5F, 0x9C63, 0x9C69, 0x9C6A, - 0x9C5C, 0x9C6B, 0x9C68, 0x9C6E, 0x9C70, 0x9C72, 0x9C75, 0x9C77, - 0x9C7B, 0x9CE6, 0x9CF2, 0x9CF7, 0x9CF9, 0x9D0B, 0x9D02, 0x9D11, - 0x9D17, 0x9D18, 0x9D1C, 0x9D1D, 0x9D1E, 0x9D2F, 0x9D30, 0x9D32, - 0x9D33, 0x9D34, 0x9D3A, 0x9D3C, 0x9D45, 0x9D3D, 0x9D42, 0x9D43, - 0x9D47, 0x9D4A, 0x9D53, 0x9D54, 0x9D5F, 0x9D63, 0x9D62, 0x9D65, - 0x9D69, 0x9D6A, 0x9D6B, 0x9D70, 0x9D76, 0x9D77, 0x9D7B, -}; -static const unsigned short euc_to_utf8_8FEC[] = { - 0x9D7C, 0x9D7E, 0x9D83, 0x9D84, 0x9D86, 0x9D8A, 0x9D8D, - 0x9D8E, 0x9D92, 0x9D93, 0x9D95, 0x9D96, 0x9D97, 0x9D98, 0x9DA1, - 0x9DAA, 0x9DAC, 0x9DAE, 0x9DB1, 0x9DB5, 0x9DB9, 0x9DBC, 0x9DBF, - 0x9DC3, 0x9DC7, 0x9DC9, 0x9DCA, 0x9DD4, 0x9DD5, 0x9DD6, 0x9DD7, - 0x9DDA, 0x9DDE, 0x9DDF, 0x9DE0, 0x9DE5, 0x9DE7, 0x9DE9, 0x9DEB, - 0x9DEE, 0x9DF0, 0x9DF3, 0x9DF4, 0x9DFE, 0x9E0A, 0x9E02, 0x9E07, - 0x9E0E, 0x9E10, 0x9E11, 0x9E12, 0x9E15, 0x9E16, 0x9E19, 0x9E1C, - 0x9E1D, 0x9E7A, 0x9E7B, 0x9E7C, 0x9E80, 0x9E82, 0x9E83, 0x9E84, - 0x9E85, 0x9E87, 0x9E8E, 0x9E8F, 0x9E96, 0x9E98, 0x9E9B, 0x9E9E, - 0x9EA4, 0x9EA8, 0x9EAC, 0x9EAE, 0x9EAF, 0x9EB0, 0x9EB3, 0x9EB4, - 0x9EB5, 0x9EC6, 0x9EC8, 0x9ECB, 0x9ED5, 0x9EDF, 0x9EE4, 0x9EE7, - 0x9EEC, 0x9EED, 0x9EEE, 0x9EF0, 0x9EF1, 0x9EF2, 0x9EF5, -}; -static const unsigned short euc_to_utf8_8FED[] = { - 0x9EF8, 0x9EFF, 0x9F02, 0x9F03, 0x9F09, 0x9F0F, 0x9F10, - 0x9F11, 0x9F12, 0x9F14, 0x9F16, 0x9F17, 0x9F19, 0x9F1A, 0x9F1B, - 0x9F1F, 0x9F22, 0x9F26, 0x9F2A, 0x9F2B, 0x9F2F, 0x9F31, 0x9F32, - 0x9F34, 0x9F37, 0x9F39, 0x9F3A, 0x9F3C, 0x9F3D, 0x9F3F, 0x9F41, - 0x9F43, 0x9F44, 0x9F45, 0x9F46, 0x9F47, 0x9F53, 0x9F55, 0x9F56, - 0x9F57, 0x9F58, 0x9F5A, 0x9F5D, 0x9F5E, 0x9F68, 0x9F69, 0x9F6D, - 0x9F6E, 0x9F6F, 0x9F70, 0x9F71, 0x9F73, 0x9F75, 0x9F7A, 0x9F7D, - 0x9F8F, 0x9F90, 0x9F91, 0x9F92, 0x9F94, 0x9F96, 0x9F97, 0x9F9E, - 0x9FA1, 0x9FA2, 0x9FA3, 0x9FA5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short euc_to_utf8_8FF3[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, - 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2160, 0x2161, -}; -static const unsigned short euc_to_utf8_8FF4[] = { - 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, - 0x2169, 0xff07, 0xff02, 0x3231, 0x2116, 0x2121, 0x70bb, 0x4efc, - 0x50f4, 0x51ec, 0x5307, 0x5324, 0xfa0e, 0x548a, 0x5759, 0xfa0f, - 0xfa10, 0x589e, 0x5bec, 0x5cf5, 0x5d53, 0xfa11, 0x5fb7, 0x6085, - 0x6120, 0x654e, 0x663b, 0x6665, 0xfa12, 0xf929, 0x6801, 0xfa13, - 0xfa14, 0x6a6b, 0x6ae2, 0x6df8, 0x6df2, 0x7028, 0xfa15, 0xfa16, - 0x7501, 0x7682, 0x769e, 0xfa17, 0x7930, 0xfa18, 0xfa19, 0xfa1a, - 0xfa1b, 0x7ae7, 0xfa1c, 0xfa1d, 0x7da0, 0x7dd6, 0xfa1e, 0x8362, - 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0xfa22, 0x8b7f, 0x8cf4, - 0x8d76, 0xfa23, 0xfa24, 0xfa25, 0x90de, 0xfa26, 0x9115, 0xfa27, - 0xfa28, 0x9592, 0xf9dc, 0xfa29, 0x973b, 0x974d, 0x9751, 0xfa2a, - 0xfa2b, 0xfa2c, 0x999e, 0x9ad9, 0x9b72, 0xfa2d, 0x9ed1, -}; -#endif /* X0212_ENABLE */ - -const unsigned short euc_to_utf8_1byte[] = { - 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, - 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, - 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, - 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, - 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, - 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, - 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, - 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x00A9, 0x2122, -}; -const unsigned short *const euc_to_utf8_2bytes[] = { - euc_to_utf8_A1, euc_to_utf8_A2, euc_to_utf8_A3, - euc_to_utf8_A4, euc_to_utf8_A5, euc_to_utf8_A6, euc_to_utf8_A7, - euc_to_utf8_A8, euc_to_utf8_A9, euc_to_utf8_AA, euc_to_utf8_AB, - euc_to_utf8_AC, euc_to_utf8_AD, euc_to_utf8_AE, euc_to_utf8_AF, - euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3, - euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7, - euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB, - euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF, - euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3, - euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7, - euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB, - euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF, - euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3, - euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7, - euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB, - euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF, - euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3, - euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7, - euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB, - euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF, - euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3, - euc_to_utf8_F4, euc_to_utf8_F5, 0, 0, - 0, euc_to_utf8_F9, euc_to_utf8_FA, euc_to_utf8_FB, - euc_to_utf8_FC, 0, 0, -}; -/* Microsoft UCS Mapping Compatible */ -const unsigned short *const euc_to_utf8_2bytes_ms[] = { - euc_to_utf8_A1_ms, euc_to_utf8_A2_ms, euc_to_utf8_A3, - euc_to_utf8_A4, euc_to_utf8_A5, euc_to_utf8_A6, euc_to_utf8_A7, - euc_to_utf8_A8, euc_to_utf8_A9, euc_to_utf8_AA, euc_to_utf8_AB, - euc_to_utf8_AC, euc_to_utf8_AD, euc_to_utf8_AE, euc_to_utf8_AF, - euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3, - euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7, - euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB, - euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF, - euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3, - euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7, - euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB, - euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF, - euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3, - euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7, - euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB, - euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF, - euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3, - euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7, - euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB, - euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF, - euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3, - euc_to_utf8_F4, euc_to_utf8_F5, 0, 0, - 0, euc_to_utf8_F9, euc_to_utf8_FA, euc_to_utf8_FB, - euc_to_utf8_FC_ms, 0, 0, -}; -/* CP10001 */ -const unsigned short *const euc_to_utf8_2bytes_mac[] = { - euc_to_utf8_A1_ms, euc_to_utf8_A2_ms, euc_to_utf8_A3, - euc_to_utf8_A4, euc_to_utf8_A5, euc_to_utf8_A6, euc_to_utf8_A7, - euc_to_utf8_A8, euc_to_utf8_A9, euc_to_utf8_AA, euc_to_utf8_AB, - euc_to_utf8_AC_mac, euc_to_utf8_AD_mac, euc_to_utf8_AE, euc_to_utf8_AF, - euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3, - euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7, - euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB, - euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF, - euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3, - euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7, - euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB, - euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF, - euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3, - euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7, - euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB, - euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF, - euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3, - euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7, - euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB, - euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF, - euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3, - euc_to_utf8_F4, euc_to_utf8_F5, 0, 0, - 0, euc_to_utf8_F9, euc_to_utf8_FA, euc_to_utf8_FB, - euc_to_utf8_FC_ms, 0, 0, -}; -const unsigned short *const euc_to_utf8_2bytes_x0213[] = { - euc_to_utf8_A1, euc_to_utf8_A2_x0213, euc_to_utf8_A3_x0213, - euc_to_utf8_A4_x0213, euc_to_utf8_A5_x0213, euc_to_utf8_A6_x0213, euc_to_utf8_A7_x0213, - euc_to_utf8_A8_x0213, euc_to_utf8_A9_x0213, euc_to_utf8_AA_x0213, euc_to_utf8_AB_x0213, - euc_to_utf8_AC_x0213, euc_to_utf8_AD_x0213, euc_to_utf8_AE_x0213, euc_to_utf8_AF_x0213, - euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3, - euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7, - euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB, - euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF, - euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3, - euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7, - euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB, - euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF_x0213, - euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3, - euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7, - euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB, - euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF, - euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3, - euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7, - euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB, - euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF, - euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3, - euc_to_utf8_F4_x0213, euc_to_utf8_F5_x0213, euc_to_utf8_F6_x0213, euc_to_utf8_F7_x0213, - euc_to_utf8_F8_x0213, euc_to_utf8_F9_x0213, euc_to_utf8_FA_x0213, euc_to_utf8_FB_x0213, - euc_to_utf8_FC_x0213, euc_to_utf8_FD_x0213, euc_to_utf8_FE_x0213, -}; - -#ifdef X0212_ENABLE -const unsigned short *const x0212_to_utf8_2bytes[] = { - 0, euc_to_utf8_8FA2, 0, - 0, 0, euc_to_utf8_8FA6, euc_to_utf8_8FA7, - 0, euc_to_utf8_8FA9, euc_to_utf8_8FAA, euc_to_utf8_8FAB, - 0, 0, 0, 0, - euc_to_utf8_8FB0, euc_to_utf8_8FB1, euc_to_utf8_8FB2, euc_to_utf8_8FB3, - euc_to_utf8_8FB4, euc_to_utf8_8FB5, euc_to_utf8_8FB6, euc_to_utf8_8FB7, - euc_to_utf8_8FB8, euc_to_utf8_8FB9, euc_to_utf8_8FBA, euc_to_utf8_8FBB, - euc_to_utf8_8FBC, euc_to_utf8_8FBD, euc_to_utf8_8FBE, euc_to_utf8_8FBF, - euc_to_utf8_8FC0, euc_to_utf8_8FC1, euc_to_utf8_8FC2, euc_to_utf8_8FC3, - euc_to_utf8_8FC4, euc_to_utf8_8FC5, euc_to_utf8_8FC6, euc_to_utf8_8FC7, - euc_to_utf8_8FC8, euc_to_utf8_8FC9, euc_to_utf8_8FCA, euc_to_utf8_8FCB, - euc_to_utf8_8FCC, euc_to_utf8_8FCD, euc_to_utf8_8FCE, euc_to_utf8_8FCF, - euc_to_utf8_8FD0, euc_to_utf8_8FD1, euc_to_utf8_8FD2, euc_to_utf8_8FD3, - euc_to_utf8_8FD4, euc_to_utf8_8FD5, euc_to_utf8_8FD6, euc_to_utf8_8FD7, - euc_to_utf8_8FD8, euc_to_utf8_8FD9, euc_to_utf8_8FDA, euc_to_utf8_8FDB, - euc_to_utf8_8FDC, euc_to_utf8_8FDD, euc_to_utf8_8FDE, euc_to_utf8_8FDF, - euc_to_utf8_8FE0, euc_to_utf8_8FE1, euc_to_utf8_8FE2, euc_to_utf8_8FE3, - euc_to_utf8_8FE4, euc_to_utf8_8FE5, euc_to_utf8_8FE6, euc_to_utf8_8FE7, - euc_to_utf8_8FE8, euc_to_utf8_8FE9, euc_to_utf8_8FEA, euc_to_utf8_8FEB, - euc_to_utf8_8FEC, euc_to_utf8_8FED, 0, 0, - 0, 0, 0, euc_to_utf8_8FF3, - euc_to_utf8_8FF4, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0,}; - -const unsigned short *const x0212_to_utf8_2bytes_x0213[] = { - euc_to_utf8_8FA1_x0213, euc_to_utf8_8FA2, euc_to_utf8_8FA3_x0213, - euc_to_utf8_8FA4_x0213, euc_to_utf8_8FA5_x0213, euc_to_utf8_8FA6, euc_to_utf8_8FA7, - euc_to_utf8_8FA8_x0213, euc_to_utf8_8FA9, euc_to_utf8_8FAA, euc_to_utf8_8FAB, - euc_to_utf8_8FAC_x0213, euc_to_utf8_8FAD_x0213, euc_to_utf8_8FAE_x0213, euc_to_utf8_8FAF_x0213, - euc_to_utf8_8FB0, euc_to_utf8_8FB1, euc_to_utf8_8FB2, euc_to_utf8_8FB3, - euc_to_utf8_8FB4, euc_to_utf8_8FB5, euc_to_utf8_8FB6, euc_to_utf8_8FB7, - euc_to_utf8_8FB8, euc_to_utf8_8FB9, euc_to_utf8_8FBA, euc_to_utf8_8FBB, - euc_to_utf8_8FBC, euc_to_utf8_8FBD, euc_to_utf8_8FBE, euc_to_utf8_8FBF, - euc_to_utf8_8FC0, euc_to_utf8_8FC1, euc_to_utf8_8FC2, euc_to_utf8_8FC3, - euc_to_utf8_8FC4, euc_to_utf8_8FC5, euc_to_utf8_8FC6, euc_to_utf8_8FC7, - euc_to_utf8_8FC8, euc_to_utf8_8FC9, euc_to_utf8_8FCA, euc_to_utf8_8FCB, - euc_to_utf8_8FCC, euc_to_utf8_8FCD, euc_to_utf8_8FCE, euc_to_utf8_8FCF, - euc_to_utf8_8FD0, euc_to_utf8_8FD1, euc_to_utf8_8FD2, euc_to_utf8_8FD3, - euc_to_utf8_8FD4, euc_to_utf8_8FD5, euc_to_utf8_8FD6, euc_to_utf8_8FD7, - euc_to_utf8_8FD8, euc_to_utf8_8FD9, euc_to_utf8_8FDA, euc_to_utf8_8FDB, - euc_to_utf8_8FDC, euc_to_utf8_8FDD, euc_to_utf8_8FDE, euc_to_utf8_8FDF, - euc_to_utf8_8FE0, euc_to_utf8_8FE1, euc_to_utf8_8FE2, euc_to_utf8_8FE3, - euc_to_utf8_8FE4, euc_to_utf8_8FE5, euc_to_utf8_8FE6, euc_to_utf8_8FE7, - euc_to_utf8_8FE8, euc_to_utf8_8FE9, euc_to_utf8_8FEA, euc_to_utf8_8FEB, - euc_to_utf8_8FEC, euc_to_utf8_8FED, euc_to_utf8_8FEE_x0213, euc_to_utf8_8FEF_x0213, - euc_to_utf8_8FF0_x0213, euc_to_utf8_8FF1_x0213, euc_to_utf8_8FF2_x0213, euc_to_utf8_8FF3_x0213, - euc_to_utf8_8FF4_x0213, euc_to_utf8_8FF5_x0213, euc_to_utf8_8FF6_x0213, euc_to_utf8_8FF7_x0213, - euc_to_utf8_8FF8_x0213, euc_to_utf8_8FF9_x0213, euc_to_utf8_8FFA_x0213, euc_to_utf8_8FFB_x0213, - euc_to_utf8_8FFC_x0213, euc_to_utf8_8FFD_x0213, euc_to_utf8_8FFE_x0213,}; -#endif /* X0212_ENABLE */ - -const unsigned short x0213_combining_chars[sizeof_x0213_combining_chars] = { - 0x309A, 0x0300, 0x0301, 0x02E5, 0x02E9, -}; -const unsigned short x0213_combining_table[sizeof_x0213_combining_table][3] = { - {0x2477, 0x304B, 0x309A}, - {0x2478, 0x304D, 0x309A}, - {0x2479, 0x304F, 0x309A}, - {0x247A, 0x3051, 0x309A}, - {0x247B, 0x3053, 0x309A}, - {0x2577, 0x30AB, 0x309A}, - {0x2578, 0x30AD, 0x309A}, - {0x2579, 0x30AF, 0x309A}, - {0x257A, 0x30B1, 0x309A}, - {0x257B, 0x30B3, 0x309A}, - {0x257C, 0x30BB, 0x309A}, - {0x257D, 0x30C4, 0x309A}, - {0x257E, 0x30C8, 0x309A}, - {0x2678, 0x31F7, 0x309A}, - {0x2B44, 0x00E6, 0x0300}, - {0x2B48, 0x0254, 0x0300}, - {0x2B49, 0x0254, 0x0301}, - {0x2B4A, 0x028C, 0x0300}, - {0x2B4B, 0x028C, 0x0301}, - {0x2B4C, 0x0259, 0x0300}, - {0x2B4D, 0x0259, 0x0301}, - {0x2B4E, 0x025A, 0x0300}, - {0x2B4F, 0x025A, 0x0301}, - {0x2B65, 0x02E9, 0x02E5}, - {0x2B66, 0x02E5, 0x02E9}, -}; -const unsigned short x0213_1_surrogate_table[sizeof_x0213_1_surrogate_table][3] = { - {0x2E22, 0xD840, 0xDC0B}, - {0x2F42, 0xD844, 0xDE3D}, - {0x2F4C, 0xD844, 0xDF1B}, - {0x2F60, 0xD845, 0xDC6E}, - {0x2F7B, 0xD846, 0xDCBD}, - {0x4F54, 0xD842, 0xDF9F}, - {0x4F63, 0xD845, 0xDEB4}, - {0x4F6E, 0xD847, 0xDE34}, - {0x753A, 0xD84C, 0xDDC4}, - {0x7572, 0xD84D, 0xDDC4}, - {0x7629, 0xD84D, 0xDF3F}, - {0x7632, 0xD84D, 0xDF63}, - {0x7660, 0xD84F, 0xDCFE}, - {0x776C, 0xD851, 0xDFF1}, - {0x787E, 0xD855, 0xDC8E}, - {0x7929, 0xD855, 0xDD0E}, - {0x7947, 0xD855, 0xDF71}, - {0x7954, 0xD856, 0xDDC4}, - {0x796E, 0xD857, 0xDDA1}, - {0x7A5D, 0xD85A, 0xDEFF}, - {0x7B33, 0xD85B, 0xDE40}, - {0x7B49, 0xD85C, 0xDCF4}, - {0x7B6C, 0xD85D, 0xDE84}, - {0x7C49, 0xD860, 0xDE77}, - {0x7C51, 0xD860, 0xDFCD}, - {0x7E66, 0xD868, 0xDD90}, -}; -const unsigned short x0213_2_surrogate_table[sizeof_x0213_2_surrogate_table][3] = { - {0x2121, 0xD840, 0xDC89}, - {0x212B, 0xD840, 0xDCA2}, - {0x212E, 0xD840, 0xDCA4}, - {0x2136, 0xD840, 0xDDA2}, - {0x2146, 0xD840, 0xDE13}, - {0x2170, 0xD840, 0xDF2B}, - {0x2177, 0xD840, 0xDF81}, - {0x2179, 0xD840, 0xDF71}, - {0x2322, 0xD840, 0xDFF9}, - {0x2325, 0xD841, 0xDC4A}, - {0x2327, 0xD841, 0xDD09}, - {0x2331, 0xD841, 0xDDD6}, - {0x2332, 0xD841, 0xDE28}, - {0x2338, 0xD841, 0xDF4F}, - {0x233F, 0xD842, 0xDC07}, - {0x2341, 0xD842, 0xDC3A}, - {0x234A, 0xD842, 0xDCB9}, - {0x2352, 0xD842, 0xDD7C}, - {0x2353, 0xD842, 0xDD9D}, - {0x2359, 0xD842, 0xDED3}, - {0x235C, 0xD842, 0xDF1D}, - {0x2377, 0xD843, 0xDD45}, - {0x242A, 0xD843, 0xDDE1}, - {0x2431, 0xD843, 0xDE95}, - {0x2432, 0xD843, 0xDE6D}, - {0x243A, 0xD843, 0xDE64}, - {0x243D, 0xD843, 0xDF5F}, - {0x2459, 0xD844, 0xDE01}, - {0x245C, 0xD844, 0xDE55}, - {0x245E, 0xD844, 0xDE7B}, - {0x2463, 0xD844, 0xDE74}, - {0x246A, 0xD844, 0xDEE4}, - {0x246B, 0xD844, 0xDED7}, - {0x2472, 0xD844, 0xDEFD}, - {0x2474, 0xD844, 0xDF36}, - {0x2475, 0xD844, 0xDF44}, - {0x2525, 0xD844, 0xDFC4}, - {0x2532, 0xD845, 0xDC6D}, - {0x253E, 0xD845, 0xDDD7}, - {0x2544, 0xD85B, 0xDC29}, - {0x2547, 0xD845, 0xDE47}, - {0x2555, 0xD845, 0xDF06}, - {0x2556, 0xD845, 0xDF42}, - {0x257E, 0xD846, 0xDDC3}, - {0x2830, 0xD847, 0xDC56}, - {0x2837, 0xD847, 0xDD2D}, - {0x2838, 0xD847, 0xDD45}, - {0x283A, 0xD847, 0xDD78}, - {0x283B, 0xD847, 0xDD62}, - {0x283F, 0xD847, 0xDDA1}, - {0x2840, 0xD847, 0xDD9C}, - {0x2845, 0xD847, 0xDD92}, - {0x2848, 0xD847, 0xDDB7}, - {0x284A, 0xD847, 0xDDE0}, - {0x284B, 0xD847, 0xDE33}, - {0x285B, 0xD847, 0xDF1E}, - {0x2866, 0xD847, 0xDF76}, - {0x286C, 0xD847, 0xDFFA}, - {0x2C22, 0xD848, 0xDD7B}, - {0x2C2B, 0xD848, 0xDF1E}, - {0x2C30, 0xD848, 0xDFAD}, - {0x2C50, 0xD849, 0xDEF3}, - {0x2C65, 0xD84A, 0xDC5B}, - {0x2C6D, 0xD84A, 0xDCAB}, - {0x2C72, 0xD84A, 0xDD8F}, - {0x2D24, 0xD84A, 0xDEB8}, - {0x2D29, 0xD84A, 0xDF4F}, - {0x2D2A, 0xD84A, 0xDF50}, - {0x2D32, 0xD84A, 0xDF46}, - {0x2D34, 0xD84B, 0xDC1D}, - {0x2D35, 0xD84A, 0xDFA6}, - {0x2D39, 0xD84B, 0xDC24}, - {0x2D56, 0xD84B, 0xDDE1}, - {0x2D7D, 0xD84C, 0xDDC3}, - {0x2E23, 0xD84C, 0xDDF5}, - {0x2E24, 0xD84C, 0xDDB6}, - {0x2E3A, 0xD84C, 0xDF72}, - {0x2E3C, 0xD84C, 0xDFD3}, - {0x2E3D, 0xD84C, 0xDFD2}, - {0x2E42, 0xD84C, 0xDFD0}, - {0x2E43, 0xD84C, 0xDFE4}, - {0x2E44, 0xD84C, 0xDFD5}, - {0x2E47, 0xD84C, 0xDFDA}, - {0x2E49, 0xD84C, 0xDFDF}, - {0x2E55, 0xD84D, 0xDC4A}, - {0x2E56, 0xD84D, 0xDC51}, - {0x2E57, 0xD84D, 0xDC4B}, - {0x2E5B, 0xD84D, 0xDC65}, - {0x2E77, 0xD84D, 0xDCE4}, - {0x2E78, 0xD84D, 0xDD5A}, - {0x2F2A, 0xD84D, 0xDD94}, - {0x2F3F, 0xD84D, 0xDE39}, - {0x2F40, 0xD84D, 0xDE47}, - {0x2F42, 0xD84D, 0xDE38}, - {0x2F43, 0xD84D, 0xDE3A}, - {0x2F4E, 0xD84D, 0xDF1C}, - {0x2F59, 0xD84D, 0xDF0C}, - {0x2F61, 0xD84D, 0xDF64}, - {0x2F69, 0xD84D, 0xDFFF}, - {0x2F6A, 0xD84D, 0xDFE7}, - {0x2F70, 0xD84E, 0xDC24}, - {0x2F75, 0xD84E, 0xDC3D}, - {0x6E23, 0xD84E, 0xDE98}, - {0x6E34, 0xD84F, 0xDC7F}, - {0x6E49, 0xD84F, 0xDD00}, - {0x6E5C, 0xD84F, 0xDD40}, - {0x6E5E, 0xD84F, 0xDDFA}, - {0x6E5F, 0xD84F, 0xDDF9}, - {0x6E60, 0xD84F, 0xDDD3}, - {0x6F32, 0xD84F, 0xDF7E}, - {0x6F47, 0xD850, 0xDC96}, - {0x6F4D, 0xD850, 0xDD03}, - {0x6F61, 0xD850, 0xDDC6}, - {0x6F64, 0xD850, 0xDDFE}, - {0x7022, 0xD850, 0xDFBC}, - {0x7033, 0xD851, 0xDE29}, - {0x7039, 0xD851, 0xDEA5}, - {0x7053, 0xD852, 0xDC96}, - {0x707B, 0xD852, 0xDE4D}, - {0x712E, 0xD852, 0xDF56}, - {0x7130, 0xD852, 0xDF6F}, - {0x7135, 0xD853, 0xDC16}, - {0x7144, 0xD853, 0xDD14}, - {0x715D, 0xD853, 0xDE0E}, - {0x7161, 0xD853, 0xDE37}, - {0x7166, 0xD853, 0xDE6A}, - {0x7169, 0xD853, 0xDE8B}, - {0x7175, 0xD854, 0xDC4A}, - {0x7177, 0xD854, 0xDC55}, - {0x717A, 0xD854, 0xDD22}, - {0x7221, 0xD854, 0xDDA9}, - {0x7223, 0xD854, 0xDDE5}, - {0x7224, 0xD854, 0xDDCD}, - {0x7228, 0xD854, 0xDE1E}, - {0x722C, 0xD854, 0xDE4C}, - {0x723D, 0xD855, 0xDC2E}, - {0x7248, 0xD855, 0xDCD9}, - {0x725B, 0xD855, 0xDDA7}, - {0x7275, 0xD855, 0xDFA9}, - {0x7276, 0xD855, 0xDFB4}, - {0x7332, 0xD856, 0xDDD4}, - {0x733D, 0xD856, 0xDEE4}, - {0x733E, 0xD856, 0xDEE3}, - {0x7340, 0xD856, 0xDEF1}, - {0x7352, 0xD856, 0xDFB2}, - {0x735D, 0xD857, 0xDC4B}, - {0x735E, 0xD857, 0xDC64}, - {0x7373, 0xD857, 0xDE2E}, - {0x7374, 0xD857, 0xDE56}, - {0x7375, 0xD857, 0xDE65}, - {0x7377, 0xD857, 0xDE62}, - {0x737B, 0xD857, 0xDED8}, - {0x737D, 0xD857, 0xDEC2}, - {0x7422, 0xD857, 0xDEE8}, - {0x7424, 0xD857, 0xDF23}, - {0x7427, 0xD857, 0xDF5C}, - {0x742E, 0xD857, 0xDFE0}, - {0x742F, 0xD857, 0xDFD4}, - {0x7434, 0xD858, 0xDC0C}, - {0x7435, 0xD857, 0xDFFB}, - {0x743D, 0xD858, 0xDC17}, - {0x7442, 0xD858, 0xDC60}, - {0x744F, 0xD858, 0xDCED}, - {0x7469, 0xD858, 0xDE70}, - {0x746B, 0xD858, 0xDE86}, - {0x7472, 0xD858, 0xDF4C}, - {0x7475, 0xD84F, 0xDD0E}, - {0x7479, 0xD859, 0xDC02}, - {0x7535, 0xD859, 0xDE7E}, - {0x753A, 0xD859, 0xDEB0}, - {0x7546, 0xD859, 0xDF1D}, - {0x7556, 0xD85A, 0xDCDD}, - {0x7558, 0xD85A, 0xDCEA}, - {0x755A, 0xD85A, 0xDD51}, - {0x755D, 0xD85A, 0xDD6F}, - {0x755F, 0xD85A, 0xDDDD}, - {0x7563, 0xD85A, 0xDE1E}, - {0x756A, 0xD85A, 0xDE58}, - {0x7570, 0xD85A, 0xDE8C}, - {0x7573, 0xD85A, 0xDEB7}, - {0x7644, 0xD85B, 0xDC73}, - {0x764E, 0xD85B, 0xDCDD}, - {0x765D, 0xD85B, 0xDE65}, - {0x7675, 0xD85B, 0xDF94}, - {0x767E, 0xD85B, 0xDFF8}, - {0x7721, 0xD85B, 0xDFF6}, - {0x7722, 0xD85B, 0xDFF7}, - {0x7733, 0xD85C, 0xDD0D}, - {0x7736, 0xD85C, 0xDD39}, - {0x7764, 0xD85C, 0xDFDB}, - {0x7765, 0xD85C, 0xDFDA}, - {0x776B, 0xD85C, 0xDFFE}, - {0x776E, 0xD85D, 0xDC10}, - {0x7773, 0xD85D, 0xDC49}, - {0x7829, 0xD85D, 0xDE15}, - {0x782A, 0xD85D, 0xDE14}, - {0x782C, 0xD85D, 0xDE31}, - {0x7834, 0xD85D, 0xDE93}, - {0x783C, 0xD85D, 0xDF0E}, - {0x783E, 0xD85D, 0xDF23}, - {0x7842, 0xD85D, 0xDF52}, - {0x7856, 0xD85E, 0xDD85}, - {0x7863, 0xD85E, 0xDE84}, - {0x7877, 0xD85E, 0xDFB3}, - {0x7879, 0xD85E, 0xDFBE}, - {0x787A, 0xD85E, 0xDFC7}, - {0x7925, 0xD85F, 0xDCB8}, - {0x792F, 0xD85F, 0xDDA0}, - {0x7932, 0xD85F, 0xDE10}, - {0x7939, 0xD85F, 0xDFB7}, - {0x7942, 0xD860, 0xDC8A}, - {0x7948, 0xD860, 0xDCBB}, - {0x7959, 0xD860, 0xDE82}, - {0x795E, 0xD860, 0xDEF3}, - {0x7966, 0xD861, 0xDC0C}, - {0x796B, 0xD861, 0xDC55}, - {0x797A, 0xD861, 0xDD6B}, - {0x797E, 0xD861, 0xDDC8}, - {0x7A21, 0xD861, 0xDDC9}, - {0x7A2C, 0xD861, 0xDED7}, - {0x7A2F, 0xD861, 0xDEFA}, - {0x7A4F, 0xD862, 0xDD49}, - {0x7A50, 0xD862, 0xDD46}, - {0x7A57, 0xD862, 0xDD6B}, - {0x7A65, 0xD862, 0xDD87}, - {0x7A66, 0xD862, 0xDD88}, - {0x7A71, 0xD862, 0xDDBA}, - {0x7A72, 0xD862, 0xDDBB}, - {0x7A7E, 0xD862, 0xDE1E}, - {0x7B21, 0xD862, 0xDE29}, - {0x7B2C, 0xD862, 0xDE71}, - {0x7B2D, 0xD862, 0xDE43}, - {0x7B36, 0xD862, 0xDE99}, - {0x7B37, 0xD862, 0xDECD}, - {0x7B3D, 0xD862, 0xDEE4}, - {0x7B3E, 0xD862, 0xDEDD}, - {0x7B4E, 0xD862, 0xDFC1}, - {0x7B4F, 0xD862, 0xDFEF}, - {0x7B57, 0xD863, 0xDD10}, - {0x7B5A, 0xD863, 0xDD71}, - {0x7B5C, 0xD863, 0xDDFB}, - {0x7B5D, 0xD863, 0xDE1F}, - {0x7B61, 0xD863, 0xDE36}, - {0x7B65, 0xD863, 0xDE89}, - {0x7B67, 0xD863, 0xDEEB}, - {0x7B69, 0xD863, 0xDF32}, - {0x7B71, 0xD863, 0xDFF8}, - {0x7C22, 0xD864, 0xDEA0}, - {0x7C23, 0xD864, 0xDEB1}, - {0x7C38, 0xD865, 0xDC90}, - {0x7C42, 0xD865, 0xDDCF}, - {0x7C4C, 0xD865, 0xDE7F}, - {0x7C56, 0xD865, 0xDEF0}, - {0x7C59, 0xD865, 0xDF19}, - {0x7C5D, 0xD865, 0xDF50}, - {0x7C76, 0xD866, 0xDCC6}, - {0x7D2C, 0xD866, 0xDE72}, - {0x7D4B, 0xD867, 0xDDDB}, - {0x7D4C, 0xD867, 0xDE3D}, - {0x7D59, 0xD867, 0xDE15}, - {0x7D5B, 0xD867, 0xDE8A}, - {0x7D5D, 0xD867, 0xDE49}, - {0x7D67, 0xD867, 0xDEC4}, - {0x7D6D, 0xD867, 0xDEE9}, - {0x7D70, 0xD867, 0xDEDB}, - {0x7E25, 0xD867, 0xDFCE}, - {0x7E29, 0xD868, 0xDC2F}, - {0x7E2B, 0xD868, 0xDC1A}, - {0x7E32, 0xD868, 0xDCF9}, - {0x7E35, 0xD868, 0xDC82}, - {0x7E53, 0xD848, 0xDE18}, - {0x7E58, 0xD868, 0xDF8C}, - {0x7E5A, 0xD869, 0xDC37}, - {0x7E6E, 0xD869, 0xDDF1}, - {0x7E70, 0xD869, 0xDE02}, - {0x7E72, 0xD869, 0xDE1A}, - {0x7E76, 0xD869, 0xDEB2}, -}; -#endif /* UTF8_OUTPUT_ENABLE */ - -#ifdef UTF8_INPUT_ENABLE -static const unsigned short utf8_to_euc_C2[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xA242, 0x2171, 0x2172, 0xA270, 0x216F, 0xA243, 0x2178, - 0x212F, 0xA26D, 0xA26C, 0, 0x224C, 0, 0xA26E, 0xA234, - 0x216B, 0x215E, 0, 0, 0x212D, 0, 0x2279, 0, - 0xA231, 0, 0xA26B, 0, 0, 0, 0, 0xA244, -}; -static const unsigned short utf8_to_euc_C2_ms[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xA242, 0x2171, 0x2172, 0xA270, 0x5C, 0xA243, 0x2178, - 0x212F, 0xA26D, 0xA26C, 0, 0x224C, 0, 0xA26E, 0xA234, - 0x216B, 0x215E, 0, 0, 0x212D, 0, 0x2279, 0, - 0xA231, 0, 0xA26B, 0, 0, 0, 0, 0xA244, -}; -static const unsigned short utf8_to_euc_C2_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x00A0, 0xA242, 0x2171, 0x2172, 0xA270, 0x5C, 0xA243, 0x2178, - 0x212F, 0x00FD, 0xA26C, 0, 0x224C, 0, 0xA26E, 0xA234, - 0x216B, 0x215E, 0, 0, 0x212D, 0, 0x2279, 0, - 0xA231, 0, 0xA26B, 0, 0, 0, 0, 0xA244, -}; -static const unsigned short utf8_to_euc_C2_932[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x21, 0x2171, 0x2172, 0, 0x5C, 0x7C, 0x2178, - 0x212F, 0x63, 0x61, 0x2263, 0x224C, 0x2D, 0x52, 0x2131, - 0x216B, 0x215E, 0x32, 0x33, 0x212D, 0x264C, 0x2279, 0x2126, - 0x2124, 0x31, 0x6F, 0x2264, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_C2_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2922, 0x2923, 0x2171, 0x2172, 0x2924, 0x216F, 0x2925, 0x2178, - 0x212F, 0x2926, 0x2927, 0x2928, 0x224C, 0x2929, 0x292A, 0x292B, - 0x216B, 0x215E, 0x292C, 0x292D, 0x212D, 0, 0x2279, 0x292E, - 0x292F, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, -}; -static const unsigned short utf8_to_euc_C3[] = { - 0xAA22, 0xAA21, 0xAA24, 0xAA2A, 0xAA23, 0xAA29, 0xA921, 0xAA2E, - 0xAA32, 0xAA31, 0xAA34, 0xAA33, 0xAA40, 0xAA3F, 0xAA42, 0xAA41, - 0, 0xAA50, 0xAA52, 0xAA51, 0xAA54, 0xAA58, 0xAA53, 0x215F, - 0xA92C, 0xAA63, 0xAA62, 0xAA65, 0xAA64, 0xAA72, 0xA930, 0xA94E, - 0xAB22, 0xAB21, 0xAB24, 0xAB2A, 0xAB23, 0xAB29, 0xA941, 0xAB2E, - 0xAB32, 0xAB31, 0xAB34, 0xAB33, 0xAB40, 0xAB3F, 0xAB42, 0xAB41, - 0xA943, 0xAB50, 0xAB52, 0xAB51, 0xAB54, 0xAB58, 0xAB53, 0x2160, - 0xA94C, 0xAB63, 0xAB62, 0xAB65, 0xAB64, 0xAB72, 0xA950, 0xAB73, -}; -static const unsigned short utf8_to_euc_C3_932[] = { - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, - 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x215F, - 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0x73, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x63, - 0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, - 0x64, 0x6E, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x2160, - 0x6F, 0x75, 0x75, 0x75, 0x75, 0x79, 0x74, 0x79, -}; -static const unsigned short utf8_to_euc_C3_x0213[] = { - 0x2937, 0x2938, 0x2939, 0x293A, 0x293B, 0x293C, 0x293D, 0x293E, - 0x293F, 0x2940, 0x2941, 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, - 0x2947, 0x2948, 0x2949, 0x294A, 0x294B, 0x294C, 0x294D, 0x215F, - 0x294E, 0x294F, 0x2950, 0x2951, 0x2952, 0x2953, 0x2954, 0x2955, - 0x2956, 0x2957, 0x2958, 0x2959, 0x295A, 0x295B, 0x295C, 0x295D, - 0x295E, 0x295F, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, 0x2965, - 0x2966, 0x2967, 0x2968, 0x2969, 0x296A, 0x296B, 0x296C, 0x2160, - 0x296D, 0x296E, 0x296F, 0x2970, 0x2971, 0x2972, 0x2973, 0x2974, -}; -static const unsigned short utf8_to_euc_C4[] = { - 0xAA27, 0xAB27, 0xAA25, 0xAB25, 0xAA28, 0xAB28, 0xAA2B, 0xAB2B, - 0xAA2C, 0xAB2C, 0xAA2F, 0xAB2F, 0xAA2D, 0xAB2D, 0xAA30, 0xAB30, - 0xA922, 0xA942, 0xAA37, 0xAB37, 0, 0, 0xAA36, 0xAB36, - 0xAA38, 0xAB38, 0xAA35, 0xAB35, 0xAA3A, 0xAB3A, 0xAA3B, 0xAB3B, - 0xAA3D, 0xAB3D, 0xAA3C, 0, 0xAA3E, 0xAB3E, 0xA924, 0xA944, - 0xAA47, 0xAB47, 0xAA45, 0xAB45, 0, 0, 0xAA46, 0xAB46, - 0xAA44, 0xA945, 0xA926, 0xA946, 0xAA48, 0xAB48, 0xAA49, 0xAB49, - 0xA947, 0xAA4A, 0xAB4A, 0xAA4C, 0xAB4C, 0xAA4B, 0xAB4B, 0xA929, -}; -static const unsigned short utf8_to_euc_C4_x0213[] = { - 0x2975, 0x297A, 0x2A3A, 0x2A49, 0x2A21, 0x2A2C, 0x2A3C, 0x2A4B, - 0x2A59, 0x2A5F, 0xAA2F, 0xAB2F, 0x2A3D, 0x2A4C, 0x2A40, 0x2A4F, - 0xA922, 0x2A50, 0x2978, 0x297D, 0, 0, 0xAA36, 0xAB36, - 0x2A3E, 0x2A4D, 0x2A3F, 0x2A4E, 0x2A5A, 0x2A60, 0xAA3B, 0xAB3B, - 0xAA3D, 0xAB3D, 0xAA3C, 0, 0x2A5B, 0x2A61, 0xA924, 0x2A7D, - 0xAA47, 0xAB47, 0x2976, 0x297B, 0, 0, 0xAA46, 0xAB46, - 0xAA44, 0xA945, 0xA926, 0xA946, 0x2A5C, 0x2A62, 0xAA49, 0xAB49, - 0xA947, 0x2A3B, 0x2A4A, 0xAA4C, 0xAB4C, 0x2A24, 0x2A2F, 0xA929, -}; -static const unsigned short utf8_to_euc_C5[] = { - 0xA949, 0xA928, 0xA948, 0xAA4D, 0xAB4D, 0xAA4F, 0xAB4F, 0xAA4E, - 0xAB4E, 0xA94A, 0xA92B, 0xA94B, 0xAA57, 0xAB57, 0, 0, - 0xAA56, 0xAB56, 0xA92D, 0xA94D, 0xAA59, 0xAB59, 0xAA5B, 0xAB5B, - 0xAA5A, 0xAB5A, 0xAA5C, 0xAB5C, 0xAA5D, 0xAB5D, 0xAA5F, 0xAB5F, - 0xAA5E, 0xAB5E, 0xAA61, 0xAB61, 0xAA60, 0xAB60, 0xA92F, 0xA94F, - 0xAA6C, 0xAB6C, 0xAA69, 0xAB69, 0xAA66, 0xAB66, 0xAA6B, 0xAB6B, - 0xAA68, 0xAB68, 0xAA6A, 0xAB6A, 0xAA71, 0xAB71, 0xAA74, 0xAB74, - 0xAA73, 0xAA75, 0xAB75, 0xAA77, 0xAB77, 0xAA76, 0xAB76, 0, -}; -static const unsigned short utf8_to_euc_C5_x0213[] = { - 0xA949, 0x2A23, 0x2A2E, 0x2A41, 0x2A51, 0xAA4F, 0xAB4F, 0x2A42, - 0x2A52, 0xA94A, 0xA92B, 0x2A7A, 0x2979, 0x297E, 0, 0, - 0x2A43, 0x2A53, 0x2B2B, 0x2B2A, 0x2A39, 0x2A48, 0xAA5B, 0xAB5B, - 0x2A44, 0x2A54, 0x2A25, 0x2A30, 0x2A5D, 0x2A63, 0x2A27, 0x2A33, - 0x2A26, 0x2A32, 0x2A47, 0x2A57, 0x2A28, 0x2A34, 0xA92F, 0xA94F, - 0xAA6C, 0xAB6C, 0x2977, 0x297C, 0x2A5E, 0x2A64, 0x2A45, 0x2A55, - 0x2A46, 0x2A56, 0xAA6A, 0xAB6A, 0xAA71, 0xAB71, 0xAA74, 0xAB74, - 0xAA73, 0x2A29, 0x2A35, 0x2A2B, 0x2A38, 0x2A2A, 0x2A37, 0, -}; -static const unsigned short utf8_to_euc_C6_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2B29, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_C7[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xAA26, 0xAB26, 0xAA43, - 0xAB43, 0xAA55, 0xAB55, 0xAA67, 0xAB67, 0xAA70, 0xAB70, 0xAA6D, - 0xAB6D, 0xAA6F, 0xAB6F, 0xAA6E, 0xAB6E, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xAB39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_C7_x0213[] = { - 0, 0, 0x2B24, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x286F, 0x2870, 0xAA43, - 0x2871, 0x2876, 0x2877, 0xAA67, 0x2878, 0xAA70, 0x2879, 0xAA6D, - 0x287A, 0xAA6F, 0x287B, 0xAA6E, 0x287C, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xAB39, 0, 0, - 0x2874, 0x2875, 0, 0, 0, 0x2B45, 0, 0, -}; -static const unsigned short utf8_to_euc_C9_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2B33, 0x2B39, 0x2B3A, 0x2B25, 0x2B38, 0x2B3F, 0x2A6E, 0x2B26, - 0x2B2E, 0x2B30, 0x2B43, 0, 0x2B31, 0, 0x2B32, 0x2A75, - 0x2B28, 0x2A79, 0, 0, 0x2B36, 0x2B3C, 0x2B22, 0x2B42, - 0x2B2C, 0, 0, 0, 0x2A6A, 0x2A74, 0x2A6B, 0x2B34, - 0x2A7B, 0x2A65, 0x2A76, 0x2A6F, 0, 0x2B2F, 0, 0, - 0, 0x2A6C, 0x2B41, 0x2A73, 0, 0x2A70, 0x2A67, 0, -}; -static const unsigned short utf8_to_euc_CA_x0213[] = { - 0, 0x2A7C, 0x2A71, 0x2A68, 0x2B27, 0, 0, 0, - 0x2A6D, 0x2B2D, 0x2B35, 0x2A66, 0x2B37, 0x2B3B, 0x2A78, 0, - 0x2A72, 0x2B40, 0x2A69, 0, 0x2B21, 0x2A7E, 0, 0, - 0x2B23, 0, 0, 0, 0, 0x2A77, 0, 0, - 0, 0x2B3E, 0x2B3D, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_CB[] = { - 0, 0, 0, 0, 0, 0, 0, 0xA230, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xA22F, 0xA232, 0xA236, 0xA235, 0, 0xA233, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_CB_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0x2A31, - 0x2B53, 0, 0, 0, 0x2B54, 0, 0, 0, - 0x2B55, 0x2B56, 0, 0, 0, 0, 0, 0, - 0x2A22, 0x2A58, 0xA236, 0x2A2D, 0, 0x2A36, 0x2B71, 0, - 0, 0, 0, 0, 0, 0x2B60, 0x2B61, 0x2B62, - 0x2B63, 0x2B64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_CC_x0213[] = { - 0x2B5C, 0x2B5A, 0x2B5F, 0x2B7D, 0x2B5B, 0, 0x2B57, 0, - 0x2B6D, 0, 0, 0x2B59, 0x2B5E, 0, 0, 0x2B5D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2B78, 0x2B79, 0x2B7E, 0, 0x2B6A, 0x2B76, 0x2B77, 0x2B6B, - 0x2B6C, 0, 0, 0, 0x2B72, 0x2B67, 0, 0, - 0, 0x2B6F, 0x2B7A, 0, 0x2B68, 0, 0, 0x2B70, - 0x2B73, 0, 0, 0, 0x2B75, 0, 0, 0, - 0, 0x2B69, 0x2B7B, 0x2B7C, 0x2B74, 0x2B6E, 0, 0, -}; -static const unsigned short utf8_to_euc_CD_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2B52, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_CE[] = { - 0, 0, 0, 0, 0xA238, 0xA239, 0xA661, 0, - 0xA662, 0xA663, 0xA664, 0, 0xA667, 0, 0xA669, 0xA66C, - 0xA676, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, - 0x2628, 0x2629, 0x262A, 0x262B, 0x262C, 0x262D, 0x262E, 0x262F, - 0x2630, 0x2631, 0, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636, - 0x2637, 0x2638, 0xA665, 0xA66A, 0xA671, 0xA672, 0xA673, 0xA674, - 0xA67B, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647, - 0x2648, 0x2649, 0x264A, 0x264B, 0x264C, 0x264D, 0x264E, 0x264F, -}; -static const unsigned short utf8_to_euc_CF[] = { - 0x2650, 0x2651, 0xA678, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656, - 0x2657, 0x2658, 0xA675, 0xA67A, 0xA677, 0xA679, 0xA67C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_CF_x0213[] = { - 0x2650, 0x2651, 0x2659, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656, - 0x2657, 0x2658, 0xA675, 0xA67A, 0xA677, 0xA679, 0xA67C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_D0[] = { - 0, 0x2727, 0xA742, 0xA743, 0xA744, 0xA745, 0xA746, 0xA747, - 0xA748, 0xA749, 0xA74A, 0xA74B, 0xA74C, 0, 0xA74D, 0xA74E, - 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2728, 0x2729, - 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, 0x2730, 0x2731, - 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, - 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F, 0x2740, 0x2741, - 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2758, 0x2759, - 0x275A, 0x275B, 0x275C, 0x275D, 0x275E, 0x275F, 0x2760, 0x2761, -}; -static const unsigned short utf8_to_euc_D1[] = { - 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2768, 0x2769, - 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F, 0x2770, 0x2771, - 0, 0x2757, 0xA772, 0xA773, 0xA774, 0xA775, 0xA776, 0xA777, - 0xA778, 0xA779, 0xA77A, 0xA77B, 0xA77C, 0, 0xA77D, 0xA77E, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E1B8_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2872, 0x2873, -}; -static const unsigned short utf8_to_euc_E1BD_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2B46, 0x2B47, 0x2B50, 0x2B51, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E280[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x213E, 0, 0, 0, 0x213D, 0x213D, 0x2142, 0, - 0x2146, 0x2147, 0, 0, 0x2148, 0x2149, 0, 0, - 0x2277, 0x2278, 0, 0, 0, 0x2145, 0x2144, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2273, 0, 0x216C, 0x216D, 0, 0, 0, 0, - 0, 0, 0, 0x2228, 0, 0, 0x2131, 0, -}; -static const unsigned short utf8_to_euc_E280_ms[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x213E, 0, 0, 0, 0x213D, 0x213D, 0x2142, 0, - 0x2146, 0x2147, 0, 0, 0x2148, 0x2149, 0, 0, - 0x2277, 0x2278, 0, 0, 0, 0x2145, 0x2144, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2273, 0, 0x216C, 0x216D, 0, 0, 0, 0, - 0, 0, 0, 0x2228, 0, 0, 0x7E, 0, -}; -static const unsigned short utf8_to_euc_E280_932[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x213E, 0, 0, 0, 0, 0x213D, 0, 0, - 0x2146, 0x2147, 0, 0, 0x2148, 0x2149, 0, 0, - 0x2277, 0x2278, 0, 0, 0, 0x2145, 0x2144, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2273, 0, 0x216C, 0x216D, 0, 0, 0, 0, - 0, 0, 0, 0x2228, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E280_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x213E, 0, 0, 0x237C, 0x213D, 0x213D, 0x2142, 0, - 0x2146, 0x2147, 0, 0, 0x2148, 0x2149, 0, 0, - 0x2277, 0x2278, 0x2340, 0, 0, 0x2145, 0x2144, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2273, 0, 0x216C, 0x216D, 0, 0, 0, 0, - 0, 0, 0, 0x2228, 0x286B, 0, 0x2131, 0x2B58, -}; -static const unsigned short utf8_to_euc_E281_x0213[] = { - 0, 0, 0x2C7E, 0, 0, 0, 0, 0x286C, - 0x286D, 0x286E, 0, 0, 0, 0, 0, 0, - 0, 0x2C7D, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E282_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2921, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E284[] = { - 0, 0, 0, 0x216E, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2D62, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2D64, 0xA26F, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2272, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E284_mac[] = { - 0, 0, 0, 0x216E, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2B7B, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2B7D, 0x00FE, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2272, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E284_x0213[] = { - 0, 0, 0, 0x216E, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x235D, - 0, 0, 0, 0x235F, 0, 0, 0x2D62, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2D64, 0xA26F, 0, 0, 0, 0, 0x2360, - 0, 0, 0, 0x2272, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x235C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E285[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2D35, 0x2D36, 0x2D37, 0x2D38, 0x2D39, 0x2D3A, 0x2D3B, 0x2D3C, - 0x2D3D, 0x2D3E, 0, 0, 0, 0, 0, 0, - 0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378, 0xF379, 0xF37A, - 0xF37B, 0xF37C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E285_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2A21, 0x2A22, 0x2A23, 0x2A24, 0x2A25, 0x2A26, 0x2A27, 0x2A28, - 0x2A29, 0x2A2A, 0, 0, 0, 0, 0, 0, - 0x2A35, 0x2A36, 0x2A37, 0x2A38, 0x2A39, 0x2A3A, 0x2A3B, 0x2A3C, - 0x2A3D, 0x2A3E, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E285_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2778, 0x2779, 0x277A, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2D35, 0x2D36, 0x2D37, 0x2D38, 0x2D39, 0x2D3A, 0x2D3B, 0x2D3C, - 0x2D3D, 0x2D3E, 0x2D3F, 0x2D57, 0, 0, 0, 0, - 0x2C35, 0x2C36, 0x2C37, 0x2C38, 0x2C39, 0x2C3A, 0x2C3B, 0x2C3C, - 0x2C3D, 0x2C3E, 0x2C3F, 0x2C40, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E286[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x222B, 0x222C, 0x222A, 0x222D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E286_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x222B, 0x222C, 0x222A, 0x222D, 0x2271, 0, 0x2327, 0x2325, - 0x2326, 0x2328, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E287[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x224D, 0, 0x224E, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E287_x0213[] = { - 0, 0, 0, 0, 0x2329, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x224D, 0, 0x224E, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x232B, 0x232C, - 0x232A, 0x232D, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E288[] = { - 0x224F, 0, 0x225F, 0x2250, 0, 0, 0, 0x2260, - 0x223A, 0, 0, 0x223B, 0, 0, 0, 0, - 0, 0x2D74, 0x215D, 0, 0, 0, 0, 0, - 0, 0, 0x2265, 0, 0, 0x2267, 0x2167, 0x2D78, - 0x225C, 0, 0, 0, 0, 0x2142, 0, 0x224A, - 0x224B, 0x2241, 0x2240, 0x2269, 0x226A, 0, 0x2D73, 0, - 0, 0, 0, 0, 0x2168, 0x2268, 0, 0, - 0, 0, 0, 0, 0, 0x2266, 0, 0, -}; -static const unsigned short utf8_to_euc_E288_932[] = { - 0x224F, 0, 0x225F, 0x2250, 0, 0, 0, 0x2260, - 0x223A, 0, 0, 0x223B, 0, 0, 0, 0, - 0, 0x2D74, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2265, 0, 0, 0x2267, 0x2167, 0x2D78, - 0x225C, 0, 0, 0, 0, 0x2142, 0, 0x224A, - 0x224B, 0x2241, 0x2240, 0x2269, 0x226A, 0, 0x2D73, 0, - 0, 0, 0, 0, 0x2168, 0x2268, 0, 0, - 0, 0, 0, 0, 0, 0x2266, 0, 0, -}; -static const unsigned short utf8_to_euc_E288_mac[] = { - 0x224F, 0, 0x225F, 0x2250, 0, 0, 0, 0x2260, - 0x223A, 0, 0, 0x223B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2265, 0, 0, 0x2267, 0x2167, 0x2F22, - 0x225C, 0, 0, 0, 0, 0x2142, 0, 0x224A, - 0x224B, 0x2241, 0x2240, 0x2269, 0x226A, 0, 0x2F21, 0, - 0, 0, 0, 0, 0x2168, 0x2268, 0, 0, - 0, 0, 0, 0, 0, 0x2266, 0, 0, -}; -static const unsigned short utf8_to_euc_E288_x0213[] = { - 0x224F, 0, 0x225F, 0x2250, 0, 0x2247, 0, 0x2260, - 0x223A, 0x2246, 0, 0x223B, 0, 0, 0, 0, - 0, 0x2D74, 0x215D, 0x235B, 0, 0, 0, 0, - 0, 0, 0x2265, 0, 0, 0x2267, 0x2167, 0x2D78, - 0x225C, 0, 0, 0, 0, 0x2254, 0x2255, 0x224A, - 0x224B, 0x2241, 0x2240, 0x2269, 0x226A, 0, 0x2D73, 0, - 0, 0, 0, 0, 0x2168, 0x2268, 0, 0, - 0, 0, 0, 0, 0, 0x2266, 0, 0, -}; -static const unsigned short utf8_to_euc_E289[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2262, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2162, 0x2261, 0, 0, 0, 0, 0x2165, 0x2166, - 0, 0, 0x2263, 0x2264, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E289_x0213[] = { - 0, 0, 0, 0x226C, 0, 0x226D, 0, 0, - 0x226E, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2262, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2162, 0x2261, 0x226B, 0, 0, 0, 0x2165, 0x2166, - 0, 0, 0x2263, 0x2264, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x226F, 0x2270, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E28A[] = { - 0, 0, 0x223E, 0x223F, 0, 0, 0x223C, 0x223D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x225D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2D79, -}; -static const unsigned short utf8_to_euc_E28A_mac[] = { - 0, 0, 0x223E, 0x223F, 0, 0, 0x223C, 0x223D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x225D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2F23, -}; -static const unsigned short utf8_to_euc_E28A_x0213[] = { - 0, 0, 0x223E, 0x223F, 0x2242, 0x2243, 0x223C, 0x223D, - 0, 0, 0x2244, 0x2245, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2251, 0x2252, 0x2253, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x225D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2D79, -}; -static const unsigned short utf8_to_euc_E28B_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2776, 0x2777, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E28C[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x225E, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E28C_x0213[] = { - 0, 0, 0, 0, 0, 0x2248, 0x2249, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x225E, 0, 0, 0, 0, 0, - 0x277C, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E28E_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2742, 0x2743, -}; -static const unsigned short utf8_to_euc_E28F_x0213[] = { - 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274A, 0x274B, - 0x274C, 0x274D, 0x274E, 0x274F, 0x2750, 0, 0x277E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E290_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x277D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E291[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2D21, 0x2D22, 0x2D23, 0x2D24, 0x2D25, 0x2D26, 0x2D27, 0x2D28, - 0x2D29, 0x2D2A, 0x2D2B, 0x2D2C, 0x2D2D, 0x2D2E, 0x2D2F, 0x2D30, - 0x2D31, 0x2D32, 0x2D33, 0x2D34, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E291_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2921, 0x2922, 0x2923, 0x2924, 0x2925, 0x2926, 0x2927, 0x2928, - 0x2929, 0x292A, 0x292B, 0x292C, 0x292D, 0x292E, 0x292F, 0x2930, - 0x2931, 0x2932, 0x2933, 0x2934, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E293_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2C41, 0x2C42, 0x2C43, 0x2C44, 0x2C45, 0x2C46, 0x2C47, 0x2C48, - 0x2C49, 0x2C4A, 0x2C4B, 0x2C4C, 0x2C4D, 0x2C4E, 0x2C4F, 0x2C50, - 0x2C51, 0x2C52, 0x2C53, 0x2C54, 0x2C55, 0x2C56, 0x2C57, 0x2C58, - 0x2C59, 0x2C5A, 0, 0x2C2B, 0x2C2C, 0x2C2D, 0x2C2E, 0x2C2F, - 0x2C30, 0x2C31, 0x2C32, 0x2C33, 0x2C34, 0x265A, 0x265B, 0x265C, - 0x265D, 0x265E, 0x265F, 0x2660, 0x2661, 0x2662, 0x2663, 0, -}; -static const unsigned short utf8_to_euc_E294[] = { - 0x2821, 0x282C, 0x2822, 0x282D, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2823, 0, 0, 0x282E, - 0x2824, 0, 0, 0x282F, 0x2826, 0, 0, 0x2831, - 0x2825, 0, 0, 0x2830, 0x2827, 0x283C, 0, 0, - 0x2837, 0, 0, 0x2832, 0x2829, 0x283E, 0, 0, - 0x2839, 0, 0, 0x2834, 0x2828, 0, 0, 0x2838, - 0x283D, 0, 0, 0x2833, 0x282A, 0, 0, 0x283A, - 0x283F, 0, 0, 0x2835, 0x282B, 0, 0, 0x283B, -}; -static const unsigned short utf8_to_euc_E295[] = { - 0, 0, 0x2840, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2836, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E296[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2223, 0x2222, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2225, 0x2224, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2227, 0x2226, 0, 0, -}; -static const unsigned short utf8_to_euc_E296_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2223, 0x2222, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x266D, 0x2225, 0x2224, 0, 0, 0x2322, 0x2321, - 0, 0, 0, 0, 0x2227, 0x2226, 0, 0, -}; -static const unsigned short utf8_to_euc_E297[] = { - 0, 0, 0, 0, 0, 0, 0x2221, 0x217E, - 0, 0, 0, 0x217B, 0, 0, 0x217D, 0x217C, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x227E, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E297_x0213[] = { - 0x2324, 0x2323, 0, 0, 0, 0, 0x2221, 0x217E, - 0, 0x233B, 0, 0x217B, 0, 0, 0x217D, 0x217C, - 0x2867, 0x2868, 0x2869, 0x286A, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x233F, 0, - 0, 0, 0, 0, 0, 0, 0, 0x227E, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E298[] = { - 0, 0, 0, 0, 0, 0x217A, 0x2179, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E298_x0213[] = { - 0x2668, 0x2669, 0x266A, 0x266B, 0, 0x217A, 0x2179, 0, - 0, 0, 0, 0, 0, 0, 0x2667, 0, - 0, 0, 0, 0, 0, 0, 0x2664, 0x2665, - 0, 0, 0, 0, 0, 0, 0x2D7E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E299[] = { - 0x216A, 0, 0x2169, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2276, 0, 0, 0x2275, 0, 0x2274, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E299_x0213[] = { - 0x216A, 0, 0x2169, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x263A, 0x263D, 0x263B, 0x2640, 0x2639, 0x263E, 0x263C, 0x263F, - 0x266C, 0x227D, 0x2276, 0x227B, 0x227C, 0x2275, 0x227A, 0x2274, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E29C_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x277B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E29D_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2D7D, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2C21, 0x2C22, - 0x2C23, 0x2C24, 0x2C25, 0x2C26, 0x2C27, 0x2C28, 0x2C29, 0x2C2A, -}; -static const unsigned short utf8_to_euc_E2A4_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x232E, 0x232F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E2A6_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x233A, -}; -static const unsigned short utf8_to_euc_E2A7_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x237D, 0x237E, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E380[] = { - 0x2121, 0x2122, 0x2123, 0x2137, 0, 0x2139, 0x213A, 0x213B, - 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, - 0x215A, 0x215B, 0x2229, 0x222E, 0x214C, 0x214D, 0, 0, - 0, 0, 0, 0, 0x2141, 0x2D60, 0, 0x2D61, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E380_932[] = { - 0x2121, 0x2122, 0x2123, 0x2137, 0, 0x2139, 0x213A, 0x213B, - 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, - 0x215A, 0x215B, 0x2229, 0x222E, 0x214C, 0x214D, 0, 0, - 0, 0, 0, 0, 0, 0x2D60, 0, 0x2D61, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E380_x0213[] = { - 0x2121, 0x2122, 0x2123, 0x2137, 0, 0x2139, 0x213A, 0x213B, - 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, - 0x215A, 0x215B, 0x2229, 0x222E, 0x214C, 0x214D, 0x225A, 0x225B, - 0x2258, 0x2259, 0, 0, 0x2141, 0x2D60, 0, 0x2D61, - 0x2666, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2233, 0x2234, 0x2235, 0, 0, - 0, 0, 0, 0x2236, 0x2237, 0x233C, 0, 0, -}; -static const unsigned short utf8_to_euc_E381[] = { - 0, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, - 0x2428, 0x2429, 0x242A, 0x242B, 0x242C, 0x242D, 0x242E, 0x242F, - 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, - 0x2438, 0x2439, 0x243A, 0x243B, 0x243C, 0x243D, 0x243E, 0x243F, - 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, - 0x2448, 0x2449, 0x244A, 0x244B, 0x244C, 0x244D, 0x244E, 0x244F, - 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, - 0x2458, 0x2459, 0x245A, 0x245B, 0x245C, 0x245D, 0x245E, 0x245F, -}; -static const unsigned short utf8_to_euc_E382[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, - 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F, - 0x2470, 0x2471, 0x2472, 0x2473, 0, 0, 0, 0, - 0, 0, 0, 0x212B, 0x212C, 0x2135, 0x2136, 0, - 0, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, - 0x2528, 0x2529, 0x252A, 0x252B, 0x252C, 0x252D, 0x252E, 0x252F, - 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, - 0x2538, 0x2539, 0x253A, 0x253B, 0x253C, 0x253D, 0x253E, 0x253F, -}; -static const unsigned short utf8_to_euc_E382_932[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, - 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F, - 0x2470, 0x2471, 0x2472, 0x2473, 0x2574, 0, 0, 0, - 0, 0, 0, 0x212B, 0x212C, 0x2135, 0x2136, 0, - 0, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, - 0x2528, 0x2529, 0x252A, 0x252B, 0x252C, 0x252D, 0x252E, 0x252F, - 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, - 0x2538, 0x2539, 0x253A, 0x253B, 0x253C, 0x253D, 0x253E, 0x253F, -}; -static const unsigned short utf8_to_euc_E382_x0213[] = { - 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, - 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F, - 0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0, - 0, 0, 0, 0x212B, 0x212C, 0x2135, 0x2136, 0x2239, - 0x237B, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, - 0x2528, 0x2529, 0x252A, 0x252B, 0x252C, 0x252D, 0x252E, 0x252F, - 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, - 0x2538, 0x2539, 0x253A, 0x253B, 0x253C, 0x253D, 0x253E, 0x253F, -}; -static const unsigned short utf8_to_euc_E383[] = { - 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, - 0x2548, 0x2549, 0x254A, 0x254B, 0x254C, 0x254D, 0x254E, 0x254F, - 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, - 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 0x255F, - 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, - 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x256D, 0x256E, 0x256F, - 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0, - 0, 0, 0, 0x2126, 0x213C, 0x2133, 0x2134, 0, -}; -static const unsigned short utf8_to_euc_E383_x0213[] = { - 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, - 0x2548, 0x2549, 0x254A, 0x254B, 0x254C, 0x254D, 0x254E, 0x254F, - 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, - 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 0x255F, - 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, - 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x256D, 0x256E, 0x256F, - 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2772, - 0x2773, 0x2774, 0x2775, 0x2126, 0x213C, 0x2133, 0x2134, 0x2238, -}; -static const unsigned short utf8_to_euc_E387_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x266E, 0x266F, 0x2670, 0x2671, 0x2672, 0x2673, 0x2674, 0x2675, - 0x2676, 0x2677, 0x2679, 0x267A, 0x267B, 0x267C, 0x267D, 0x267E, -}; -static const unsigned short utf8_to_euc_E388[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2D6A, 0x2D6B, 0, 0, 0, 0, 0, - 0, 0x2D6C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E388_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2D2E, 0x2D31, 0, 0, 0, 0, 0, - 0, 0x2D2C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E389_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, 0x2846, 0x2847, - 0x2848, 0x2849, 0x284A, 0x284B, 0x284C, 0x284D, 0x284E, 0x284F, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38A[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2D65, 0x2D66, 0x2D67, 0x2D68, - 0x2D69, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38A_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2D73, 0x2D74, 0x2D75, 0x2D76, - 0x2D77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38A_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2D65, 0x2D66, 0x2D67, 0x2D68, - 0x2D69, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2850, 0x2851, 0x2852, 0x2853, 0x2854, 0x2855, 0x2856, - 0x2857, 0x2858, 0x2859, 0x285A, 0x285B, 0x285C, 0x285D, 0x285E, -}; -static const unsigned short utf8_to_euc_E38B_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2C5B, 0x2C5C, 0x2C5D, 0x2C5E, 0x2C5F, 0x2C60, 0x2C61, 0x2C62, - 0x2C63, 0x2C64, 0x2C65, 0x2C66, 0x2C67, 0x2C68, 0x2C69, 0x2C6A, - 0x2C6B, 0x2C6C, 0x2C6D, 0x2C6E, 0, 0x2C71, 0, 0, - 0, 0x2C70, 0, 0, 0x2C73, 0x2C72, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2C6F, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38C[] = { - 0, 0, 0, 0x2D46, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2D4A, 0, 0, - 0, 0, 0, 0, 0x2D41, 0, 0, 0, - 0x2D44, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2D42, 0x2D4C, 0, 0, 0x2D4B, 0x2D45, - 0, 0, 0, 0x2D4D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2D47, 0, - 0, 0, 0, 0x2D4F, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38C_mac[] = { - 0, 0, 0, 0x2E29, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2E32, 0, 0, - 0, 0, 0, 0, 0x2E24, 0, 0, 0, - 0x2E2B, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x2E22, 0x2E34, 0, 0, 0x2E35, 0x2E2D, - 0, 0, 0, 0x2E37, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2E2A, 0, - 0, 0, 0, 0x2E36, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38D[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2D40, 0x2D4E, 0, 0, 0x2D43, 0, 0, - 0, 0x2D48, 0, 0, 0, 0, 0, 0x2D49, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2D5F, 0x2D6F, 0x2D6E, 0x2D6D, 0, -}; -static const unsigned short utf8_to_euc_E38D_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x2E21, 0x2E2F, 0, 0, 0x2E23, 0, 0, - 0, 0x2E2E, 0, 0, 0, 0, 0, 0x2E31, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2E6A, 0x2E69, 0x2E68, 0x2E67, 0, -}; -static const unsigned short utf8_to_euc_E38E[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2D53, 0x2D54, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2D50, 0x2D51, 0x2D52, 0, - 0, 0x2D56, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38E_mac[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x2B2B, 0x2B2D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x2B21, 0x2B23, 0x2B29, 0, - 0, 0x2B27, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38F[] = { - 0, 0, 0, 0, 0x2D55, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2D63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38F_mac[] = { - 0, 0, 0, 0, 0x2B2E, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2B7C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E38F_x0213[] = { - 0, 0, 0, 0, 0x2D55, 0, 0, 0, - 0, 0, 0, 0x235E, 0, 0x2D63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E390_x0213[] = { - 0, 0, 0x2E23, 0, 0, 0, 0xA12D, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xA132, 0, 0xA133, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E391_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xA15E, 0, 0xA156, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E392_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xA17E, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x2E53, 0, 0, - 0, 0, 0, 0, 0xA32B, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E393_x0213[] = { - 0, 0xF468, 0, 0, 0, 0, 0, 0xA32F, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2E5B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E394_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xA348, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E395_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xA35D, 0xA35E, 0, - 0, 0, 0, 0xA361, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xA367, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E396_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xA423, 0, - 0xA426, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E397_x0213[] = { - 0, 0, 0, 0, 0, 0xA42F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xA438, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xA442, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E398_x0213[] = { - 0, 0, 0, 0, 0, 0xA44A, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E399_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xA479, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E39A_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xA53F, 0, 0, 0, 0, 0xA543, 0, - 0, 0xA541, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E39B_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xA557, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E39D_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xA823, 0xA825, 0, 0, 0, 0, 0, - 0, 0, 0, 0xA829, 0xA828, 0, 0, 0, - 0, 0, 0, 0, 0, 0xA82C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E39E_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x4F5F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E39F_x0213[] = { - 0, 0xA83E, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x4F6F, 0, 0, 0, 0, 0, - 0xA856, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xA859, 0, 0, 0, - 0, 0, 0, 0, 0, 0xA85C, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A0_x0213[] = { - 0xA85E, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xA86F, - 0, 0, 0, 0, 0, 0, 0xA871, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A1_x0213[] = { - 0xA874, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xA879, 0, 0, 0, - 0, 0xA87B, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A3_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xAC3B, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A4_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xAC46, - 0, 0, 0xAC4A, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A5_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xAC60, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3A9_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xAD5B, 0, - 0, 0, 0, 0xAD5F, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3AB_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xAD71, 0xAE36, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xAD7C, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3AC_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xAE2E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xAE32, 0, 0xAE34, 0, 0, 0, - 0, 0, 0x7549, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3AD_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xAE6D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xAE65, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3AE_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xAF28, - 0xAF29, 0, 0, 0, 0, 0xAF2C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xAF34, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x757E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3AF_x0213[] = { - 0, 0, 0, 0x7621, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xAF48, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xAF5D, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B0_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x763A, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xAF77, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B3_x0213[] = { - 0, 0, 0, 0xEE3B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xEE42, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B4_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xEE71, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xEE7E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B5_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xEF40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B6_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xEF54, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B7_x0213[] = { - 0xEF70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xEF77, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3B8_x0213[] = { - 0, 0, 0, 0, 0, 0xF028, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x7766, -}; -static const unsigned short utf8_to_euc_E3B9_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF03F, 0, 0, 0, 0, 0, 0xF041, 0, - 0xF042, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3BA_x0213[] = { - 0, 0, 0, 0xF049, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF050, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3BD_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF134, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x784D, 0, 0, 0xF146, 0, 0xF148, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3BE_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF15C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E3BF_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xF167, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF16C, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E480_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xF222, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E481_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF22D, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E482_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xF239, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E484_x0213[] = { - 0, 0, 0, 0, 0, 0xF264, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E485_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF274, 0, 0, 0, 0, 0, 0, 0xF277, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xF27D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E486_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF333, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF337, -}; -static const unsigned short utf8_to_euc_E487_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF347, 0, - 0, 0, 0, 0, 0, 0, 0xF34B, 0, - 0, 0, 0, 0xF348, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E488_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xF353, - 0, 0, 0, 0, 0, 0, 0xF357, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E489_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x796D, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E48B_x0213[] = { - 0, 0, 0, 0, 0, 0, 0xF42B, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF436, 0, - 0, 0, 0, 0, 0, 0xF43B, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E48C_x0213[] = { - 0, 0, 0xF44E, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xF45D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E48D_x0213[] = { - 0, 0, 0, 0xF461, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E48F_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF53E, 0, - 0xF542, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E490_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF548, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF54A, - 0, 0, 0, 0, 0xF54C, 0, 0, 0, - 0, 0, 0xF54F, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E491_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x7A59, 0, 0, 0, 0, - 0, 0, 0, 0x7A5A, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF56C, 0, - 0, 0, 0xF56E, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E492_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xF577, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xF635, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF632, 0, -}; -static const unsigned short utf8_to_euc_E493_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF634, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E494_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF659, 0, 0, 0, 0, 0xF654, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xF66D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E495_x0213[] = { - 0, 0, 0, 0xF66E, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E496_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x7B51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xF74F, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E497_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xF76C, 0, 0, - 0, 0, 0x7B60, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E498_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF824, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E499_x0213[] = { - 0, 0xF83A, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xF843, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E49A_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xF84E, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF853, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E49C_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF86B, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E49D_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF929, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E49F_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xF93F, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A0_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF949, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A1_x0213[] = { - 0, 0, 0, 0, 0x7C4B, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF95C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A2_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFA27, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A6_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x7D58, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A7_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFB6A, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB70, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4A8_x0213[] = { - 0, 0, 0, 0, 0xFB75, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB78, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4AA_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFC37, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4AC_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFC55, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4AF_x0213[] = { - 0, 0, 0xFD26, 0, 0, 0, 0, 0, - 0, 0, 0xFD28, 0, 0, 0, 0, 0, - 0, 0, 0xFD2A, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFD31, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4B0_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x7E3E, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFD3F, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4B3_x0213[] = { - 0, 0, 0, 0, 0xFE2A, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFE2D, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4B4_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xFE4B, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4B5_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFE60, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4B8[] = { - 0x306C, 0x437A, 0xB021, 0x3C37, 0xB022, 0xB023, 0, 0x4B7C, - 0x3E66, 0x3B30, 0x3E65, 0x323C, 0xB024, 0x4954, 0x4D3F, 0, - 0x5022, 0x312F, 0xB025, 0, 0x336E, 0x5023, 0x4024, 0x5242, - 0x3556, 0x4A3A, 0, 0, 0, 0, 0x3E67, 0xB026, - 0, 0x4E3E, 0, 0xB027, 0xB028, 0, 0x4A42, 0, - 0xB029, 0, 0x5024, 0xB02A, 0, 0x4366, 0xB02B, 0xB02C, - 0xB02D, 0x5025, 0x367A, 0, 0, 0xB02E, 0x5026, 0, - 0x345D, 0x4330, 0, 0x3C67, 0x5027, 0, 0, 0x5028, -}; -static const unsigned short utf8_to_euc_E4B8_x0213[] = { - 0x306C, 0x437A, 0xA122, 0x3C37, 0xB022, 0xB023, 0, 0x4B7C, - 0x3E66, 0x3B30, 0x3E65, 0x323C, 0xB024, 0x4954, 0x4D3F, 0xA123, - 0x5022, 0x312F, 0xA124, 0, 0x336E, 0x5023, 0x4024, 0x5242, - 0x3556, 0x4A3A, 0, 0, 0, 0, 0x3E67, 0xB026, - 0, 0x4E3E, 0, 0xB027, 0xB028, 0, 0x4A42, 0, - 0x2E24, 0xA125, 0x5024, 0xA126, 0xF02E, 0x4366, 0xA127, 0x2E25, - 0x2E26, 0x5025, 0x367A, 0, 0, 0xB02E, 0x5026, 0, - 0x345D, 0x4330, 0, 0x3C67, 0x5027, 0, 0, 0x5028, -}; -static const unsigned short utf8_to_euc_E4B9[] = { - 0xB02F, 0xB030, 0x5029, 0x4735, 0xB031, 0x3557, 0, 0xB032, - 0, 0, 0, 0x4737, 0, 0x4663, 0x3843, 0x4B33, - 0, 0xB033, 0, 0, 0, 0x6949, 0x502A, 0x3E68, - 0x502B, 0x3235, 0xB034, 0, 0xB035, 0x3665, 0x3870, 0x4C69, - 0, 0, 0x5626, 0xB036, 0, 0, 0, 0, - 0xB037, 0xB038, 0, 0, 0, 0, 0, 0, - 0, 0x4D70, 0, 0x467D, 0xB039, 0xB03A, 0, 0, - 0, 0xB03B, 0, 0, 0, 0, 0x3425, 0xB03C, -}; -static const unsigned short utf8_to_euc_E4B9_x0213[] = { - 0xA128, 0xB030, 0x5029, 0x4735, 0xB031, 0x3557, 0, 0xA129, - 0xA12A, 0, 0, 0x4737, 0, 0x4663, 0x3843, 0x4B33, - 0, 0xA12C, 0, 0, 0, 0x6949, 0x502A, 0x3E68, - 0x502B, 0x3235, 0xA12F, 0, 0xB035, 0x3665, 0x3870, 0x4C69, - 0, 0, 0x5626, 0xB036, 0, 0, 0, 0, - 0xB037, 0xA130, 0, 0, 0, 0, 0, 0, - 0, 0x4D70, 0, 0x467D, 0xB039, 0xB03A, 0, 0, - 0, 0xB03B, 0, 0, 0, 0, 0x3425, 0xB03C, -}; -static const unsigned short utf8_to_euc_E4BA[] = { - 0x3535, 0, 0x502C, 0, 0, 0x502D, 0x4E3B, 0, - 0x4D3D, 0x4168, 0x502F, 0x3B76, 0x4673, 0xB03D, 0x5032, 0, - 0, 0x313E, 0x385F, 0, 0x385E, 0x3066, 0xB03E, 0xB03F, - 0x4F4B, 0x4F4A, 0, 0x3A33, 0x3021, 0xB040, 0x5033, 0x5034, - 0x5035, 0x4B34, 0x5036, 0, 0x3872, 0x3067, 0x4B72, 0, - 0x357C, 0, 0, 0x357D, 0x357E, 0x4462, 0x4E3C, 0xB041, - 0x5037, 0, 0, 0x5038, 0, 0, 0x5039, 0, - 0, 0xB042, 0x3F4D, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4BA_x0213[] = { - 0x3535, 0, 0x502C, 0, 0, 0x502D, 0x4E3B, 0, - 0x4D3D, 0x4168, 0x502F, 0x3B76, 0x4673, 0x2E27, 0x5032, 0, - 0, 0x313E, 0x385F, 0, 0x385E, 0x3066, 0xB03E, 0xB03F, - 0x4F4B, 0x4F4A, 0, 0x3A33, 0x3021, 0xA131, 0x5033, 0x5034, - 0x5035, 0x4B34, 0x5036, 0, 0x3872, 0x3067, 0x4B72, 0, - 0x357C, 0, 0, 0x357D, 0x357E, 0x4462, 0x4E3C, 0xB041, - 0x5037, 0, 0, 0x5038, 0, 0, 0x5039, 0, - 0, 0xA134, 0x3F4D, 0xA135, 0xA137, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E4BB[] = { - 0x3D3A, 0x3F4E, 0x503E, 0xB043, 0x503C, 0, 0x503D, 0x3558, - 0, 0, 0x3A23, 0x3270, 0, 0x503B, 0x503A, 0x4A29, - 0xB044, 0, 0, 0, 0x3B46, 0x3B45, 0x423E, 0x503F, - 0x4955, 0x4067, 0xB045, 0xB046, 0, 0x2138, 0x5040, 0x5042, - 0xB047, 0xB048, 0xB049, 0x4265, 0x4E61, 0x304A, 0, 0, - 0xB04A, 0, 0, 0, 0, 0x5041, 0x323E, 0xB04B, - 0x3644, 0xB04C, 0x4367, 0xB04D, 0, 0xB04E, 0x376F, 0x5043, - 0, 0, 0, 0x4724, 0xF42F, 0xB04F, 0xB050, 0xB051, -}; -static const unsigned short utf8_to_euc_E4BB_x0213[] = { - 0x3D3A, 0x3F4E, 0x503E, 0xA138, 0x503C, 0, 0x503D, 0x3558, - 0xA139, 0, 0x3A23, 0x3270, 0, 0x503B, 0x503A, 0x4A29, - 0xA13A, 0, 0, 0, 0x3B46, 0x3B45, 0x423E, 0x503F, - 0x4955, 0x4067, 0xA13C, 0xB046, 0, 0x2138, 0x5040, 0x5042, - 0xB047, 0x2E28, 0xB049, 0x4265, 0x4E61, 0x304A, 0, 0, - 0xB04A, 0, 0, 0xA13B, 0, 0x5041, 0x323E, 0xB04B, - 0x3644, 0xA13D, 0x4367, 0xB04D, 0, 0xA13E, 0x376F, 0x5043, - 0, 0, 0, 0x4724, 0, 0x2E29, 0xB050, 0x2E2A, -}; -static const unsigned short utf8_to_euc_E4BC[] = { - 0xB052, 0x346B, 0xB053, 0xB054, 0, 0, 0, 0, - 0xB055, 0x5044, 0x304B, 0xB056, 0xB057, 0x3860, 0x346C, 0x497A, - 0x4832, 0x3559, 0xB058, 0, 0, 0xB059, 0xB05A, 0xB05B, - 0, 0xB05C, 0x3271, 0, 0x5067, 0x4541, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB05D, 0x476C, - 0x5046, 0xB05E, 0, 0xB060, 0x483C, 0xB061, 0x4E62, 0xB062, - 0x3F2D, 0xB063, 0x3B47, 0xB064, 0x3B77, 0x3240, 0xB065, 0, -}; -static const unsigned short utf8_to_euc_E4BC_x0213[] = { - 0xA13F, 0x346B, 0xB053, 0x2E2B, 0, 0, 0, 0, - 0xB055, 0x5044, 0x304B, 0x2E2C, 0xB057, 0x3860, 0x346C, 0x497A, - 0x4832, 0x3559, 0xB058, 0, 0, 0xB059, 0xA140, 0xB05B, - 0, 0xB05C, 0x3271, 0, 0x5067, 0x4541, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB05D, 0x476C, - 0x5046, 0xB05E, 0, 0xB060, 0x483C, 0xB061, 0x4E62, 0xA142, - 0x3F2D, 0, 0x3B47, 0xB064, 0x3B77, 0x3240, 0xA143, 0, -}; -static const unsigned short utf8_to_euc_E4BD[] = { - 0xB066, 0, 0xB067, 0x4451, 0, 0, 0x4322, 0x504A, - 0xB068, 0xB069, 0, 0xB06A, 0xB06B, 0x304C, 0x4463, 0x3D3B, - 0x3A34, 0x4D24, 0xB06C, 0x424E, 0xB06D, 0x323F, 0xB06E, 0x5049, - 0xB06F, 0x4D3E, 0x5045, 0x5047, 0x3A6E, 0x5048, 0x5524, 0xB070, - 0xB05F, 0, 0, 0xB071, 0, 0, 0, 0, - 0, 0x5050, 0xB072, 0, 0xB073, 0, 0xB074, 0x5053, - 0x5051, 0xB075, 0, 0x3242, 0, 0x4A3B, 0x504B, 0xB076, - 0xB077, 0xB078, 0xB079, 0x504F, 0x3873, 0xB07A, 0xB07B, 0x3B48, -}; -static const unsigned short utf8_to_euc_E4BD_x0213[] = { - 0xB066, 0, 0xB067, 0x4451, 0, 0, 0x4322, 0x504A, - 0x2E2E, 0x2E2F, 0, 0xB06A, 0xB06B, 0x304C, 0x4463, 0x3D3B, - 0x3A34, 0x4D24, 0xB06C, 0x424E, 0xA144, 0x323F, 0x2E30, 0x5049, - 0xA145, 0x4D3E, 0x5045, 0x5047, 0x3A6E, 0x5048, 0x5524, 0x2E31, - 0x2E2D, 0, 0, 0xB071, 0xA141, 0, 0, 0, - 0, 0x5050, 0x2E32, 0, 0x2E33, 0, 0xB074, 0x5053, - 0x5051, 0xB075, 0, 0x3242, 0, 0x4A3B, 0x504B, 0xA147, - 0xA148, 0xB078, 0xA149, 0x504F, 0x3873, 0xA14A, 0x2E34, 0x3B48, -}; -static const unsigned short utf8_to_euc_E4BE[] = { - 0, 0xB07C, 0xB07D, 0x3426, 0xB07E, 0xB121, 0x5054, 0, - 0x504C, 0xB122, 0xB123, 0x4E63, 0xB124, 0x3B78, 0xB125, 0x504D, - 0xB126, 0x5052, 0xB127, 0xB128, 0xB129, 0, 0x5055, 0xB12A, - 0x504E, 0xB12B, 0xB12C, 0x3621, 0, 0x304D, 0xB12D, 0xB12E, - 0x3622, 0x3241, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x5525, 0, 0x4B79, 0x496E, 0x3874, - 0, 0, 0xB12F, 0, 0, 0x3F2F, 0x4E37, 0xB130, - 0, 0xB131, 0, 0xB132, 0xB133, 0xB134, 0xB135, 0x4A58, -}; -static const unsigned short utf8_to_euc_E4BE_x0213[] = { - 0, 0xB07C, 0xA14B, 0x3426, 0xB07E, 0xA14C, 0x5054, 0, - 0x504C, 0xB122, 0x2E35, 0x4E63, 0xB124, 0x3B78, 0xB125, 0x504D, - 0xB126, 0x5052, 0xA14D, 0xB128, 0x2E36, 0, 0x5055, 0x2E37, - 0x504E, 0xB12B, 0xA14E, 0x3621, 0, 0x304D, 0xB12D, 0xB12E, - 0x3622, 0x3241, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x5525, 0, 0x4B79, 0x496E, 0x3874, - 0, 0, 0xA150, 0, 0, 0x3F2F, 0x4E37, 0xB130, - 0, 0xB131, 0, 0xB132, 0xB133, 0xB134, 0xA151, 0x4A58, -}; -static const unsigned short utf8_to_euc_E4BF[] = { - 0xB136, 0xB137, 0x3738, 0x4225, 0x3264, 0xB138, 0xB139, 0, - 0xB13A, 0xB13B, 0x3D53, 0xB13C, 0xB13D, 0xB13E, 0x5059, 0xB13F, - 0x505E, 0x505C, 0xB140, 0, 0x5057, 0, 0, 0x422F, - 0x505A, 0, 0x505D, 0x505B, 0xB141, 0x4A5D, 0, 0x5058, - 0xB142, 0x3F2E, 0xB143, 0x4B73, 0x505F, 0x5060, 0, 0, - 0, 0, 0, 0, 0, 0, 0x3D24, 0x506D, - 0xB144, 0, 0xB145, 0x4750, 0, 0x4936, 0x5068, 0, - 0x4A70, 0, 0x3236, 0, 0xB146, 0xB147, 0x506C, 0xB148, -}; -static const unsigned short utf8_to_euc_E4BF_x0213[] = { - 0xB136, 0xB137, 0x3738, 0x4225, 0x3264, 0xA152, 0xB139, 0, - 0xB13A, 0x2E39, 0x3D53, 0xA153, 0xB13D, 0, 0x5059, 0xA154, - 0x505E, 0x505C, 0xA155, 0, 0x5057, 0, 0, 0x422F, - 0x505A, 0, 0x505D, 0x505B, 0xB141, 0x4A5D, 0, 0x5058, - 0x2E3A, 0x3F2E, 0xB143, 0x4B73, 0x505F, 0x5060, 0xA14F, 0, - 0, 0, 0, 0, 0, 0, 0x3D24, 0x506D, - 0xB144, 0x2E21, 0xA157, 0x4750, 0, 0x4936, 0x5068, 0, - 0x4A70, 0, 0x3236, 0, 0xB146, 0xB147, 0x506C, 0, -}; -static const unsigned short utf8_to_euc_E580[] = { - 0xB149, 0xB14A, 0, 0, 0xB14B, 0x5066, 0x506F, 0xB14C, - 0, 0x4152, 0xB14D, 0x3844, 0xB14E, 0x475C, 0xB14F, 0x6047, - 0xB150, 0x506E, 0x455D, 0xB151, 0x5063, 0, 0x3876, 0xB152, - 0xB153, 0x3875, 0x5061, 0xB154, 0xB155, 0xB156, 0xB157, 0x3C5A, - 0, 0x5069, 0xB158, 0x4A6F, 0x434D, 0x5065, 0x3771, 0xB159, - 0x5062, 0x506A, 0x5064, 0x4E51, 0x506B, 0x4F41, 0xB15A, 0, - 0xB15B, 0, 0xB15C, 0xB15D, 0, 0xB15E, 0x3666, 0, - 0, 0x3770, 0, 0xB176, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E580_x0213[] = { - 0xA158, 0x2E3B, 0x2E3C, 0, 0xB14B, 0x5066, 0x506F, 0xB14C, - 0, 0x4152, 0xB14D, 0x3844, 0xB14E, 0x475C, 0x2E3D, 0x6047, - 0xA159, 0x506E, 0x455D, 0xA15A, 0x5063, 0, 0x3876, 0xB152, - 0x2E3E, 0x3875, 0x5061, 0xB154, 0xA15B, 0xB156, 0xA15C, 0x3C5A, - 0, 0x5069, 0xA15D, 0x4A6F, 0x434D, 0x5065, 0x3771, 0x2E3F, - 0x5062, 0x506A, 0x5064, 0x4E51, 0x506B, 0x4F41, 0x2E40, 0, - 0xB15B, 0, 0xB15C, 0xB15D, 0, 0xB15E, 0x3666, 0, - 0, 0x3770, 0, 0x2E42, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E581[] = { - 0xB15F, 0xB160, 0xB161, 0x5070, 0, 0xB162, 0xB163, 0x5071, - 0x5075, 0x304E, 0xB164, 0, 0xB165, 0, 0xB166, 0x4A50, - 0x5074, 0xB167, 0xB168, 0xB169, 0, 0x5073, 0x5077, 0xB16A, - 0, 0xB16B, 0x5076, 0, 0x4464, 0, 0, 0xB16C, - 0xB16D, 0, 0xB16E, 0xB16F, 0, 0x3772, 0xB170, 0xB171, - 0, 0, 0xB172, 0, 0x5078, 0xB173, 0, 0, - 0xB174, 0xB175, 0x3C45, 0, 0x4226, 0x4465, 0x3676, 0, - 0x5079, 0, 0, 0, 0, 0x3536, 0, 0, -}; -static const unsigned short utf8_to_euc_E581_x0213[] = { - 0x2E41, 0x2E43, 0xA15F, 0x5070, 0, 0xB162, 0xA160, 0x5071, - 0x5075, 0x304E, 0xB164, 0, 0xB165, 0, 0xA161, 0x4A50, - 0x5074, 0xB167, 0xB168, 0xA162, 0, 0x5073, 0x5077, 0xA163, - 0, 0xB16B, 0x5076, 0, 0x4464, 0, 0, 0xB16C, - 0xB16D, 0, 0xB16E, 0xA164, 0, 0x3772, 0xA165, 0xB171, - 0, 0, 0xA166, 0, 0x5078, 0xB173, 0, 0, - 0xA167, 0xB175, 0x3C45, 0, 0x4226, 0x4465, 0x3676, 0, - 0x5079, 0, 0, 0, 0, 0x3536, 0, 0, -}; -static const unsigned short utf8_to_euc_E582[] = { - 0x507A, 0xB177, 0, 0xB178, 0xB179, 0x507C, 0xB17A, 0, - 0, 0, 0xB17B, 0, 0, 0x4B35, 0xB17C, 0xB17D, - 0xB17E, 0x3766, 0xB221, 0xB222, 0xB223, 0, 0xB224, 0, - 0x3B31, 0x4877, 0x507B, 0xB225, 0xB226, 0, 0xB227, 0xB228, - 0xB229, 0xB22A, 0xB22B, 0, 0, 0, 0, 0, - 0, 0, 0xB22C, 0, 0x3A45, 0x4D43, 0, 0xB22D, - 0xB22E, 0, 0x507E, 0x5123, 0x507D, 0x3A44, 0, 0x3D7D, - 0, 0xB22F, 0xB230, 0, 0, 0xB231, 0x3739, 0, -}; -static const unsigned short utf8_to_euc_E582_x0213[] = { - 0x507A, 0xB177, 0, 0xB178, 0xB179, 0x507C, 0xB17A, 0, - 0xA169, 0, 0xB17B, 0, 0, 0x4B35, 0xB17C, 0xB17D, - 0xB17E, 0x3766, 0xA16A, 0xA16B, 0x2E44, 0xA16C, 0xA16D, 0, - 0x3B31, 0x4877, 0x507B, 0xB225, 0xA16E, 0, 0xB227, 0xB228, - 0xB229, 0xB22A, 0xB22B, 0xA168, 0, 0, 0, 0, - 0, 0, 0xA16F, 0, 0x3A45, 0x4D43, 0, 0xB22D, - 0xB22E, 0xA171, 0x507E, 0x5123, 0x507D, 0x3A44, 0, 0x3D7D, - 0, 0xB22F, 0xA172, 0xA173, 0, 0xB231, 0x3739, 0, -}; -static const unsigned short utf8_to_euc_E583[] = { - 0xB232, 0, 0x5124, 0xB233, 0xB234, 0x364F, 0, 0xB235, - 0, 0x5121, 0x5122, 0, 0xB236, 0x462F, 0xB237, 0x417C, - 0xB238, 0x3623, 0, 0xB239, 0xB23A, 0x4B4D, 0x5125, 0, - 0xB23B, 0, 0x4E3D, 0, 0xB23C, 0xB23D, 0x5126, 0xB23E, - 0, 0, 0xB23F, 0x5129, 0xB240, 0x5127, 0xB241, 0x414E, - 0xB242, 0xB243, 0, 0, 0, 0x5128, 0x512A, 0xB244, - 0, 0xB245, 0xB251, 0, 0xF430, 0x512C, 0xB246, 0, - 0, 0x512B, 0xB247, 0x4A48, 0, 0, 0xB248, 0, -}; -static const unsigned short utf8_to_euc_E583_x0213[] = { - 0xB232, 0, 0x5124, 0xB233, 0xA174, 0x364F, 0, 0xA175, - 0, 0x5121, 0x5122, 0, 0x2E45, 0x462F, 0xA178, 0x417C, - 0x2E47, 0x3623, 0, 0xB239, 0xA17A, 0x4B4D, 0x5125, 0, - 0, 0xA17B, 0x4E3D, 0, 0xB23C, 0xB23D, 0x5126, 0xB23E, - 0, 0xA17C, 0xB23F, 0x5129, 0xB240, 0x5127, 0x2E48, 0x414E, - 0xB242, 0xA17D, 0, 0, 0, 0x5128, 0x512A, 0xB244, - 0, 0xB245, 0x2E46, 0xA176, 0, 0x512C, 0xB246, 0, - 0, 0x512B, 0xB247, 0x4A48, 0, 0, 0xB248, 0, -}; -static const unsigned short utf8_to_euc_E584[] = { - 0x3537, 0x512E, 0x512F, 0xB249, 0x322F, 0, 0xB24A, 0xB24B, - 0xB24C, 0x512D, 0, 0xB24D, 0xB24E, 0xB24F, 0xB250, 0, - 0xB252, 0, 0x3C74, 0, 0x5132, 0x5131, 0x5130, 0xB253, - 0x5056, 0xB254, 0x5133, 0xB255, 0xB256, 0xB257, 0xB258, 0x3D7E, - 0, 0x5134, 0, 0xB259, 0, 0, 0, 0xB25A, - 0xB25B, 0, 0x4D25, 0, 0xB25C, 0xB25D, 0, 0xB25E, - 0, 0xB25F, 0x4C59, 0xB260, 0xB261, 0xB262, 0, 0x5136, - 0xB263, 0xB264, 0x5135, 0x5138, 0x5137, 0, 0, 0x5139, -}; -static const unsigned short utf8_to_euc_E584_x0213[] = { - 0x3537, 0x512E, 0x512F, 0x2E4B, 0x322F, 0, 0x2E4A, 0xB24B, - 0xA321, 0x512D, 0, 0x2E4C, 0xB24E, 0xB24F, 0xB250, 0, - 0xB252, 0, 0x3C74, 0, 0x5132, 0x5131, 0x5130, 0xA323, - 0x5056, 0xB254, 0x5133, 0xA324, 0xB256, 0xB257, 0x2E4D, 0x3D7E, - 0, 0x5134, 0, 0xB259, 0, 0, 0, 0xB25A, - 0xB25B, 0, 0x4D25, 0, 0xB25C, 0xB25D, 0, 0xB25E, - 0, 0xB25F, 0x4C59, 0xB260, 0xB261, 0x2E4E, 0, 0x5136, - 0xB263, 0xB264, 0x5135, 0x5138, 0x5137, 0, 0, 0x5139, -}; -static const unsigned short utf8_to_euc_E585[] = { - 0x513A, 0x3074, 0xB265, 0x3835, 0x373B, 0x3D3C, 0x437B, 0x3624, - 0x4068, 0x3877, 0xB266, 0x396E, 0x513C, 0x4C48, 0x4546, 0xB267, - 0x3B79, 0, 0x513B, 0xB268, 0x513D, 0xB269, 0, 0xB26A, - 0xB26B, 0, 0x455E, 0, 0x3375, 0, 0, 0xB26C, - 0, 0, 0x513E, 0, 0xB26D, 0x467E, 0xB26E, 0, - 0x4134, 0x5140, 0x5141, 0x482C, 0x3878, 0x4F3B, 0x5142, 0, - 0, 0x3626, 0, 0, 0, 0x4A3C, 0x4236, 0x3671, - 0x4535, 0, 0, 0, 0x3773, 0, 0xB26F, 0, -}; -static const unsigned short utf8_to_euc_E585_x0213[] = { - 0x513A, 0x3074, 0xB265, 0x3835, 0x373B, 0x3D3C, 0x437B, 0x3624, - 0x4068, 0x3877, 0x2E4F, 0x396E, 0x513C, 0x4C48, 0x4546, 0xB267, - 0x3B79, 0, 0x513B, 0xB268, 0x513D, 0x2E51, 0, 0x2E52, - 0xB26B, 0, 0x455E, 0, 0x3375, 0, 0, 0xB26C, - 0xA326, 0, 0x513E, 0, 0, 0x467E, 0xB26E, 0, - 0x4134, 0x5140, 0x5141, 0x482C, 0x3878, 0x4F3B, 0x5142, 0, - 0, 0x3626, 0, 0xA328, 0, 0x4A3C, 0x4236, 0x3671, - 0x4535, 0, 0, 0xF474, 0x3773, 0, 0xB26F, 0, -}; -static const unsigned short utf8_to_euc_E586[] = { - 0x5143, 0, 0x5144, 0xB270, 0xB271, 0x4662, 0x315F, 0, - 0, 0x5147, 0x3A7D, 0xB272, 0x5146, 0x3A46, 0xB273, 0x5148, - 0x666E, 0x5149, 0x4B41, 0x514A, 0, 0x514B, 0x514C, 0x3E69, - 0xB274, 0x3C4C, 0, 0, 0, 0xB275, 0, 0, - 0x3427, 0xB276, 0x514F, 0xB277, 0x514D, 0x4C3D, 0x514E, 0, - 0x495A, 0x5150, 0x5151, 0x5152, 0x455F, 0xB278, 0, 0, - 0x5156, 0x5154, 0x5155, 0x5153, 0x3A63, 0x5157, 0x4C6A, 0x4E64, - 0xB279, 0, 0xB27A, 0, 0xB27B, 0x5158, 0xB27C, 0xB27D, -}; -static const unsigned short utf8_to_euc_E586_x0213[] = { - 0x5143, 0, 0x5144, 0xA329, 0xB271, 0x4662, 0x315F, 0, - 0, 0x5147, 0x3A7D, 0xA32A, 0x5146, 0x3A46, 0xB273, 0x5148, - 0x666E, 0x5149, 0x4B41, 0x514A, 0, 0x514B, 0x514C, 0x3E69, - 0xA32C, 0x3C4C, 0, 0, 0, 0x2E54, 0, 0, - 0x3427, 0xB276, 0x514F, 0xA32D, 0x514D, 0x4C3D, 0x514E, 0, - 0x495A, 0x5150, 0x5151, 0x5152, 0x455F, 0xA32E, 0, 0, - 0x5156, 0x5154, 0x5155, 0x5153, 0x3A63, 0x5157, 0x4C6A, 0x4E64, - 0xB279, 0, 0xB27A, 0, 0xA330, 0x5158, 0, 0xB27D, -}; -static const unsigned short utf8_to_euc_E587[] = { - 0, 0, 0xB27E, 0, 0x4028, 0x5159, 0x3D5A, 0, - 0xB321, 0x515A, 0, 0x437C, 0x4E3F, 0x4560, 0, 0xB322, - 0, 0xB323, 0xB324, 0xB325, 0, 0xB326, 0x5245, 0, - 0xB327, 0, 0, 0x515B, 0x7425, 0x3645, 0xB328, 0, - 0x515C, 0x4B5E, 0xB329, 0, 0, 0xB32A, 0x3D68, 0x427C, - 0, 0x515E, 0x4664, 0, 0xF431, 0x515F, 0xB32B, 0, - 0x5160, 0x332E, 0xB32C, 0xB32D, 0xB32E, 0x5161, 0x3627, 0xB32F, - 0x464C, 0x317A, 0x3D50, 0, 0, 0x4821, 0x5162, 0, -}; -static const unsigned short utf8_to_euc_E587_x0213[] = { - 0, 0, 0xB27E, 0x2E55, 0x4028, 0x5159, 0x3D5A, 0, - 0xB321, 0x515A, 0x2E56, 0x437C, 0x4E3F, 0x4560, 0, 0xB322, - 0, 0xB323, 0xB324, 0xB325, 0, 0xB326, 0x5245, 0, - 0xB327, 0, 0, 0x515B, 0x7425, 0x3645, 0x2E57, 0, - 0x515C, 0x4B5E, 0x2E58, 0, 0, 0xB32A, 0x3D68, 0x427C, - 0, 0x515E, 0x4664, 0, 0, 0x515F, 0x2E59, 0, - 0x5160, 0x332E, 0xB32C, 0xA333, 0xA334, 0x5161, 0x3627, 0xB32F, - 0x464C, 0x317A, 0x3D50, 0, 0, 0x4821, 0x5162, 0, -}; -static const unsigned short utf8_to_euc_E588[] = { - 0x4561, 0xB330, 0xB331, 0x3F4F, 0x5163, 0xB332, 0x4A2C, 0x405A, - 0x3422, 0, 0x3429, 0x5164, 0, 0, 0x5166, 0, - 0, 0x373A, 0xB333, 0xB334, 0x5165, 0xB335, 0xB336, 0x4E73, - 0xB337, 0, 0, 0, 0, 0x3D69, 0, 0, - 0, 0, 0xB338, 0, 0x483D, 0x4A4C, 0, 0x5167, - 0xB339, 0x4D78, 0x5168, 0, 0, 0, 0x5169, 0, - 0x457E, 0xB33A, 0xB33B, 0x516A, 0, 0xB33C, 0x4029, 0x3A7E, - 0x3774, 0x516B, 0x3B49, 0x396F, 0xB33D, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E588_x0213[] = { - 0x4561, 0x2E5A, 0xA335, 0x3F4F, 0x5163, 0xB332, 0x4A2C, 0x405A, - 0x3422, 0, 0x3429, 0x5164, 0, 0, 0x5166, 0, - 0, 0x373A, 0xA336, 0x2E5C, 0x5165, 0x2E5D, 0xA337, 0x4E73, - 0xB337, 0, 0, 0, 0, 0x3D69, 0, 0, - 0, 0, 0xB338, 0, 0x483D, 0x4A4C, 0, 0x5167, - 0xB339, 0x4D78, 0x5168, 0, 0, 0, 0x5169, 0, - 0x457E, 0xB33A, 0xB33B, 0x516A, 0, 0xB33C, 0x4029, 0x3A7E, - 0x3774, 0x516B, 0x3B49, 0x396F, 0xB33D, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E589[] = { - 0, 0, 0, 0x4466, 0x516D, 0xB33E, 0, 0x4227, - 0, 0xB33F, 0x3A6F, 0x516E, 0x516F, 0x4130, 0, 0x516C, - 0, 0, 0, 0, 0x5171, 0xB340, 0x4B36, 0xB341, - 0xB342, 0, 0xB343, 0x3964, 0xB344, 0, 0x5170, 0xB345, - 0xB346, 0xB347, 0, 0x3775, 0x3A5E, 0x476D, 0xB348, 0, - 0, 0x5174, 0x5172, 0, 0, 0, 0xB349, 0x497B, - 0x3E6A, 0x517B, 0x3364, 0x5175, 0x5173, 0x414F, 0, 0xB34A, - 0xB34B, 0xB34C, 0, 0, 0, 0x5177, 0, 0x5176, -}; -static const unsigned short utf8_to_euc_E589_x0213[] = { - 0, 0, 0, 0x4466, 0x516D, 0xB33E, 0, 0x4227, - 0, 0x2E5E, 0x3A6F, 0x516E, 0x516F, 0x4130, 0, 0x516C, - 0, 0, 0, 0, 0x5171, 0xA339, 0x4B36, 0x2E5F, - 0xB342, 0, 0xB343, 0x3964, 0xA33A, 0x2F7E, 0x5170, 0xB345, - 0xB346, 0x2E60, 0, 0x3775, 0x3A5E, 0x476D, 0xB348, 0, - 0, 0x5174, 0x5172, 0, 0xA33B, 0, 0xB349, 0x497B, - 0x3E6A, 0x517B, 0x3364, 0x5175, 0x5173, 0x414F, 0, 0xA33C, - 0xB34B, 0xB34C, 0, 0, 0, 0x5177, 0, 0x5176, -}; -static const unsigned short utf8_to_euc_E58A[] = { - 0xB34D, 0, 0xB34E, 0x3344, 0, 0xB34F, 0, 0x3760, - 0x517C, 0x4E2D, 0xB350, 0, 0xB351, 0x5178, 0, 0, - 0, 0x517D, 0x517A, 0xB352, 0x5179, 0xB353, 0xB354, 0xB355, - 0xB356, 0, 0xB357, 0x4E4F, 0xB358, 0, 0, 0x3879, - 0x3243, 0, 0, 0x4E74, 0xB359, 0xB35A, 0xB35B, 0xB35C, - 0, 0x3D75, 0x4558, 0x3965, 0x5222, 0x5223, 0, 0xB35D, - 0xB35E, 0x4E65, 0, 0, 0x4F2B, 0x5225, 0xB35F, 0xB360, - 0xB361, 0x387A, 0xB362, 0xB363, 0x5224, 0xB364, 0x332F, 0, -}; -static const unsigned short utf8_to_euc_E58A_x0213[] = { - 0xB34D, 0, 0xA33E, 0x3344, 0xA33D, 0xB34F, 0, 0x3760, - 0x517C, 0x4E2D, 0xB350, 0, 0xB351, 0x5178, 0, 0, - 0, 0x517D, 0x517A, 0x2E61, 0x5179, 0xB353, 0xB354, 0xB355, - 0xA340, 0, 0xB357, 0x4E4F, 0, 0, 0, 0x3879, - 0x3243, 0, 0, 0x4E74, 0xA342, 0xB35A, 0xA343, 0xB35C, - 0, 0x3D75, 0x4558, 0x3965, 0x5222, 0x5223, 0, 0xA344, - 0xB35E, 0x4E65, 0, 0, 0x4F2B, 0x5225, 0xB35F, 0xB360, - 0xB361, 0x387A, 0xA345, 0xA346, 0x5224, 0xB364, 0x332F, 0, -}; -static const unsigned short utf8_to_euc_E58B[] = { - 0xB365, 0x5226, 0, 0x4B56, 0xB366, 0x443C, 0xB367, 0x4D26, - 0xB368, 0x4A59, 0, 0, 0xB369, 0x5227, 0, 0xB36A, - 0, 0xB36B, 0x7055, 0, 0xB36C, 0x4630, 0xB36D, 0x5228, - 0x342A, 0x4C33, 0, 0xB36E, 0xB36F, 0x3E21, 0x5229, 0x4A67, - 0x522D, 0xB370, 0x402A, 0x522A, 0x3650, 0xB371, 0x522B, 0x342B, - 0xB372, 0xB373, 0xB374, 0, 0xB375, 0, 0, 0, - 0xB376, 0xB377, 0x372E, 0x522E, 0xB378, 0x522F, 0xB379, 0xB37A, - 0x5230, 0x5231, 0x3C5B, 0, 0, 0, 0x387B, 0x4C5E, -}; -static const unsigned short utf8_to_euc_E58B_x0213[] = { - 0, 0x5226, 0, 0x4B56, 0xB366, 0x443C, 0xB367, 0x4D26, - 0x2E62, 0x4A59, 0xA347, 0, 0x2E64, 0x5227, 0, 0xB36A, - 0x2E65, 0xA349, 0x7055, 0, 0xB36C, 0x4630, 0x2E66, 0x5228, - 0x342A, 0x4C33, 0, 0x2E67, 0xB36F, 0x3E21, 0x5229, 0x4A67, - 0x522D, 0xB370, 0x402A, 0x522A, 0x3650, 0xB371, 0x522B, 0x342B, - 0xB372, 0xB373, 0xB374, 0, 0xB375, 0, 0, 0, - 0x2E69, 0xB377, 0x372E, 0x522E, 0xB378, 0x522F, 0xB379, 0xA34B, - 0x5230, 0x5231, 0x3C5B, 0x2E6A, 0, 0, 0x387B, 0x4C5E, -}; -static const unsigned short utf8_to_euc_E58C[] = { - 0xB37B, 0x4C68, 0x4677, 0xB37C, 0, 0x4A71, 0x5232, 0xF432, - 0x5233, 0, 0xB37D, 0xB37E, 0xB421, 0x5235, 0, 0x5237, - 0x5236, 0xB422, 0, 0xB423, 0, 0x5238, 0x323D, 0x4B4C, - 0xB424, 0x3A7C, 0x5239, 0xB425, 0xB426, 0x4159, 0xB427, 0xB428, - 0x3E22, 0x3629, 0, 0x523A, 0xF433, 0xB429, 0, 0xB42A, - 0xB42B, 0xB42C, 0x485B, 0xB42D, 0xB42E, 0xB42F, 0, 0x523B, - 0xB430, 0x523C, 0xB431, 0x523D, 0, 0xB432, 0, 0, - 0x523E, 0x4924, 0x3668, 0x3065, 0xB433, 0xB434, 0xB435, 0x463F, -}; -static const unsigned short utf8_to_euc_E58C_x0213[] = { - 0x2E6B, 0x4C68, 0x4677, 0xB37C, 0, 0x4A71, 0x5232, 0x2E6C, - 0x5233, 0, 0xA34C, 0xA34D, 0xB421, 0x5235, 0, 0x5237, - 0x5236, 0xB422, 0, 0xB423, 0, 0x5238, 0x323D, 0x4B4C, - 0xB424, 0x3A7C, 0x5239, 0xB425, 0x2E6D, 0x4159, 0xB427, 0xB428, - 0x3E22, 0x3629, 0, 0x523A, 0xA34E, 0xB429, 0, 0xB42A, - 0xB42B, 0xB42C, 0x485B, 0xB42D, 0xB42E, 0xB42F, 0, 0x523B, - 0xB430, 0x523C, 0xB431, 0x523D, 0, 0xA34F, 0, 0, - 0x523E, 0x4924, 0x3668, 0x3065, 0xB433, 0xB434, 0xA350, 0x463F, -}; -static const unsigned short utf8_to_euc_E58D[] = { - 0x523F, 0x3D3D, 0xB436, 0x4069, 0, 0x5241, 0x5240, 0x3E23, - 0x3861, 0x5243, 0x483E, 0xB438, 0xB437, 0x5244, 0, 0, - 0, 0x485C, 0x4234, 0x426E, 0x3628, 0, 0, 0x466E, - 0x4331, 0xB439, 0x476E, 0xB43A, 0x4B4E, 0, 0x5246, 0, - 0x406A, 0xB43B, 0, 0xB43C, 0, 0xB43D, 0x3735, 0, - 0, 0x5247, 0, 0, 0xB43E, 0xB43F, 0x5248, 0x312C, - 0x3075, 0x346D, 0xB440, 0x4228, 0x3551, 0x4D71, 0, 0x524B, - 0x3237, 0xB441, 0, 0x524A, 0, 0, 0xB442, 0x362A, -}; -static const unsigned short utf8_to_euc_E58D_x0213[] = { - 0x523F, 0x3D3D, 0xA351, 0x4069, 0, 0x5241, 0x5240, 0x3E23, - 0x3861, 0x5243, 0x483E, 0xB438, 0xB437, 0x5244, 0, 0, - 0, 0x485C, 0x4234, 0x426E, 0x3628, 0, 0, 0x466E, - 0x4331, 0xB439, 0x476E, 0xB43A, 0x4B4E, 0, 0x5246, 0, - 0x406A, 0x2E6F, 0, 0x2E70, 0, 0xB43D, 0x3735, 0xA354, - 0, 0x5247, 0, 0, 0xA355, 0xB43F, 0x5248, 0x312C, - 0x3075, 0x346D, 0, 0x4228, 0x3551, 0x4D71, 0, 0x524B, - 0x3237, 0xB441, 0xA356, 0x524A, 0, 0x2E71, 0xB442, 0x362A, -}; -static const unsigned short utf8_to_euc_E58E[] = { - 0, 0, 0x524C, 0xB443, 0x4C71, 0, 0, 0xB444, - 0xB445, 0, 0, 0, 0, 0, 0xB446, 0, - 0, 0, 0, 0xB447, 0xB448, 0, 0x524D, 0, - 0x4E52, 0xB449, 0x387C, 0, 0, 0xB44A, 0, 0x3836, - 0x524E, 0xB44B, 0, 0, 0xB44C, 0x5250, 0x524F, 0, - 0x3F5F, 0x3139, 0xB44D, 0xB44E, 0, 0x315E, 0x5251, 0xB44F, - 0x5252, 0, 0xB450, 0x3837, 0xB451, 0xB452, 0x5253, 0xB453, - 0xB454, 0, 0xB455, 0x356E, 0, 0xB456, 0, 0, -}; -static const unsigned short utf8_to_euc_E58E_x0213[] = { - 0, 0, 0x524C, 0xB443, 0x4C71, 0, 0, 0xB444, - 0xB445, 0, 0, 0, 0, 0, 0xB446, 0, - 0, 0, 0, 0x2E72, 0xB448, 0, 0x524D, 0, - 0x4E52, 0xB449, 0x387C, 0, 0, 0x2E73, 0, 0x3836, - 0x524E, 0xB44B, 0, 0, 0xA357, 0x5250, 0x524F, 0, - 0x3F5F, 0x3139, 0xB44D, 0xB44E, 0, 0x315E, 0x5251, 0xB44F, - 0x5252, 0, 0x2E74, 0x3837, 0xA358, 0xB452, 0x5253, 0xA35A, - 0xB454, 0, 0xB455, 0x356E, 0, 0xB456, 0, 0, -}; -static const unsigned short utf8_to_euc_E58F[] = { - 0xB457, 0, 0x3B32, 0x5254, 0, 0xB458, 0, 0, - 0x4B74, 0x3A35, 0x355A, 0x4D27, 0x4150, 0x483F, 0x3C7D, 0xB459, - 0, 0, 0xB45A, 0xB45B, 0x3D47, 0xB45C, 0x3C68, 0x3C75, - 0, 0x3D76, 0xB45D, 0x4840, 0, 0xB45E, 0xB45F, 0x5257, - 0xB460, 0x3143, 0x4151, 0x387D, 0x3845, 0x3667, 0xB461, 0xB462, - 0x525B, 0x4321, 0x427E, 0x362B, 0x3E24, 0x525C, 0x525A, 0x3244, - 0x4266, 0x3C38, 0x3B4B, 0x3126, 0, 0xB463, 0x3370, 0x3966, - 0x3B4A, 0, 0x525D, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E58F_x0213[] = { - 0xA35B, 0, 0x3B32, 0x5254, 0, 0xB458, 0, 0, - 0x4B74, 0x3A35, 0x355A, 0x4D27, 0x4150, 0x483F, 0x3C7D, 0xB459, - 0, 0, 0xB45A, 0xB45B, 0x3D47, 0xA35F, 0x3C68, 0x3C75, - 0, 0x3D76, 0xA360, 0x4840, 0, 0, 0xB45F, 0x5257, - 0xB460, 0x3143, 0x4151, 0x387D, 0x3845, 0x3667, 0xB461, 0xB462, - 0x525B, 0x4321, 0x427E, 0x362B, 0x3E24, 0x525C, 0x525A, 0x3244, - 0x4266, 0x3C38, 0x3B4B, 0x3126, 0xA362, 0xA363, 0x3370, 0x3966, - 0x3B4A, 0, 0x525D, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E590[] = { - 0, 0x525E, 0xB464, 0x3549, 0x3346, 0, 0, 0, - 0x3967, 0x3548, 0x445F, 0x3125, 0x4631, 0x4C3E, 0x3921, 0x4D79, - 0x4547, 0x387E, 0, 0xB465, 0, 0, 0, 0, - 0, 0, 0xB466, 0x372F, 0, 0x5267, 0, 0x3663, - 0x4B4A, 0xB467, 0, 0, 0, 0, 0x485D, 0xB468, - 0xB469, 0x5266, 0xB46A, 0x345E, 0x5261, 0x5262, 0x5264, 0xB46B, - 0, 0xB46C, 0, 0, 0xB46D, 0xB46E, 0x5265, 0, - 0x355B, 0x3F61, 0, 0x4A2D, 0x5263, 0x525F, 0x3863, 0, -}; -static const unsigned short utf8_to_euc_E590_x0213[] = { - 0, 0x525E, 0xB464, 0x3549, 0x3346, 0, 0, 0, - 0x3967, 0x3548, 0x445F, 0x3125, 0x4631, 0x4C3E, 0x3921, 0x4D79, - 0x4547, 0x387E, 0x2E75, 0xB465, 0, 0, 0, 0, - 0, 0, 0xB466, 0x372F, 0, 0x5267, 0x4F7E, 0x3663, - 0x4B4A, 0xB467, 0, 0, 0xA365, 0, 0x485D, 0x2E76, - 0xA366, 0x5266, 0xB46A, 0x345E, 0x5261, 0x5262, 0x5264, 0xB46B, - 0, 0xB46C, 0, 0, 0xB46D, 0xB46E, 0x5265, 0, - 0x355B, 0x3F61, 0, 0x4A2D, 0x5263, 0x525F, 0x3863, 0, -}; -static const unsigned short utf8_to_euc_E591[] = { - 0x5260, 0, 0x4F24, 0xB46F, 0xB470, 0, 0x4A72, 0xB471, - 0x4468, 0x3862, 0x3970, 0, 0, 0xB472, 0x5268, 0xB473, - 0, 0x465D, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB474, 0x526C, - 0, 0, 0xB475, 0, 0xB476, 0, 0xB477, 0xB478, - 0x3C7E, 0xB479, 0x3C76, 0xB47A, 0, 0xB47B, 0xB47C, 0, - 0x526F, 0x526D, 0, 0x4C23, 0xB47D, 0x526A, 0x5273, 0x526E, - 0, 0, 0, 0x5271, 0x3846, 0x4C3F, 0, 0xB47E, -}; -static const unsigned short utf8_to_euc_E591_x0213[] = { - 0x5260, 0, 0x4F24, 0xA368, 0xB470, 0, 0x4A72, 0xB471, - 0x4468, 0x3862, 0x3970, 0, 0, 0x2E77, 0x5268, 0xB473, - 0, 0x465D, 0, 0, 0, 0xA364, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB474, 0x526C, - 0, 0, 0xA369, 0, 0xB476, 0, 0xA36A, 0xB478, - 0x3C7E, 0xB479, 0x3C76, 0x2E79, 0xA36B, 0xB47B, 0xB47C, 0, - 0x526F, 0x526D, 0, 0x4C23, 0x2E7A, 0x526A, 0x5273, 0x526E, - 0, 0, 0, 0x5271, 0x3846, 0x4C3F, 0, 0x2E7B, -}; -static const unsigned short utf8_to_euc_E592[] = { - 0x5272, 0xB521, 0, 0xB522, 0x5274, 0xB523, 0x5276, 0, - 0xB524, 0xB525, 0xF435, 0x3A70, 0x4F42, 0xB526, 0x526B, 0x5269, - 0x5275, 0xB527, 0x5270, 0, 0, 0xB528, 0xB529, 0, - 0, 0, 0, 0, 0xB52A, 0, 0, 0xB52B, - 0, 0xB52C, 0x5278, 0, 0x5323, 0x527A, 0xB52D, 0xB52E, - 0x527E, 0xB52F, 0xB530, 0x5321, 0x527B, 0xB531, 0xB532, 0x533E, - 0, 0xB533, 0x3A69, 0x3331, 0, 0, 0, 0xB534, - 0x5279, 0xB535, 0xB536, 0xB537, 0x5325, 0x3076, 0x5324, 0xB538, -}; -static const unsigned short utf8_to_euc_E592_x0213[] = { - 0x5272, 0xB521, 0, 0xB522, 0x5274, 0xB523, 0x5276, 0, - 0x2E7C, 0xB525, 0xA36C, 0x3A70, 0x4F42, 0xA36D, 0x526B, 0x5269, - 0x5275, 0xB527, 0x5270, 0, 0, 0xA36E, 0x2E7D, 0, - 0, 0, 0, 0, 0x2E78, 0, 0, 0xB52B, - 0xA36F, 0x2E7E, 0x5278, 0, 0x5323, 0x527A, 0xA370, 0xB52E, - 0x527E, 0x2F21, 0xB530, 0x5321, 0x527B, 0xA371, 0xA372, 0x533E, - 0, 0xB533, 0x3A69, 0x3331, 0, 0, 0, 0xA373, - 0x5279, 0xB535, 0xA374, 0xB537, 0x5325, 0x3076, 0x5324, 0xA375, -}; -static const unsigned short utf8_to_euc_E593[] = { - 0x3025, 0x494A, 0x5322, 0, 0x527C, 0, 0xB539, 0x5277, - 0x527D, 0x3A48, 0xB53A, 0, 0, 0xB53B, 0xB53C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x5326, 0, 0, 0, 0, 0, 0, 0, - 0xB53D, 0x3077, 0x532F, 0, 0, 0x5327, 0x5328, 0, - 0x3E25, 0x4B69, 0xB53E, 0, 0xB53F, 0x532D, 0x532C, 0xB540, - 0, 0, 0x452F, 0, 0, 0, 0xB541, 0, - 0, 0, 0x532E, 0, 0xB542, 0x532B, 0xB543, 0xB544, -}; -static const unsigned short utf8_to_euc_E593_x0213[] = { - 0x3025, 0x494A, 0x5322, 0xA376, 0x527C, 0, 0x2F22, 0x5277, - 0x527D, 0x3A48, 0xB53A, 0, 0, 0xB53B, 0xB53C, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x5326, 0, 0, 0, 0, 0, 0, 0, - 0xB53D, 0x3077, 0x532F, 0, 0, 0x5327, 0x5328, 0, - 0x3E25, 0x4B69, 0xB53E, 0, 0xA378, 0x532D, 0x532C, 0xA379, - 0, 0xA37A, 0x452F, 0xA37B, 0, 0, 0xB541, 0, - 0, 0, 0x532E, 0, 0xB542, 0x532B, 0xB543, 0x2F23, -}; -static const unsigned short utf8_to_euc_E594[] = { - 0xB545, 0xB546, 0, 0, 0x3134, 0xB547, 0x3A36, 0x3F30, - 0xB548, 0xB549, 0, 0, 0xB54A, 0xB54B, 0xB54C, 0x5329, - 0x4562, 0, 0, 0, 0x532A, 0xB54D, 0x3022, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xB54E, 0xB54F, 0, 0, 0x5334, 0x4D23, - 0, 0x3E27, 0xB550, 0x533A, 0, 0xB551, 0xB552, 0, - 0x5339, 0x5330, 0, 0xB553, 0xB554, 0xB555, 0x4243, 0, -}; -static const unsigned short utf8_to_euc_E594_x0213[] = { - 0xA37C, 0xA37D, 0, 0, 0x3134, 0xB547, 0x3A36, 0x3F30, - 0xB548, 0xA37E, 0, 0, 0xB54A, 0xB54B, 0x2F24, 0x5329, - 0x4562, 0, 0, 0, 0x532A, 0xB54D, 0x3022, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xB54E, 0x2F25, 0, 0, 0x5334, 0x4D23, - 0, 0x3E27, 0xB550, 0x533A, 0, 0x2F26, 0xB552, 0, - 0x5339, 0x5330, 0, 0xB553, 0xA421, 0xB555, 0x4243, 0, -}; -static const unsigned short utf8_to_euc_E595[] = { - 0x5331, 0xB556, 0, 0, 0x426F, 0x5336, 0x3E26, 0xB557, - 0, 0xB558, 0xB559, 0, 0x5333, 0xB55A, 0, 0x4C64, - 0xB55B, 0xB55C, 0, 0x373C, 0, 0, 0x5337, 0x5338, - 0xB55D, 0, 0xB55E, 0xB55F, 0x5335, 0x533B, 0xB560, 0, - 0xB561, 0xB562, 0, 0x5332, 0xB563, 0, 0xB564, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x5341, 0x5346, 0, 0x5342, 0xB565, -}; -static const unsigned short utf8_to_euc_E595_x0213[] = { - 0x5331, 0xA422, 0, 0, 0x426F, 0x5336, 0x3E26, 0xA424, - 0, 0xB558, 0xA425, 0, 0x5333, 0xB55A, 0, 0x4C64, - 0x2F27, 0xB55C, 0, 0x373C, 0, 0, 0x5337, 0x5338, - 0xB55D, 0, 0xB55E, 0xB55F, 0x5335, 0x533B, 0x2F28, 0, - 0xA427, 0xA428, 0, 0x5332, 0xA429, 0, 0xB564, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x5341, 0x5346, 0xA42B, 0x5342, 0xB565, -}; -static const unsigned short utf8_to_euc_E596[] = { - 0x533D, 0xB566, 0xB567, 0x5347, 0x4131, 0, 0xB568, 0x5349, - 0xB569, 0x3922, 0x533F, 0x437D, 0, 0, 0xB56A, 0xB56B, - 0, 0xB56C, 0xB56D, 0xB56E, 0xB56F, 0, 0, 0xB570, - 0x5343, 0x533C, 0x342D, 0, 0x346E, 0x3365, 0x5344, 0x5340, - 0, 0, 0, 0xB571, 0xB572, 0, 0, 0x3776, - 0x534A, 0x5348, 0x4153, 0x354A, 0x362C, 0xB573, 0x5345, 0, - 0x3674, 0, 0xB574, 0, 0, 0, 0x3144, 0, - 0, 0, 0, 0, 0, 0, 0, 0xB575, -}; -static const unsigned short utf8_to_euc_E596_x0213[] = { - 0x533D, 0x2F29, 0xA42C, 0x5347, 0x4131, 0, 0x2F2A, 0x5349, - 0xA42D, 0x3922, 0x533F, 0x437D, 0, 0, 0x2F2B, 0xB56B, - 0, 0xA42E, 0xB56D, 0xB56E, 0xB56F, 0, 0, 0xB570, - 0x5343, 0x533C, 0x342D, 0, 0x346E, 0x3365, 0x5344, 0x5340, - 0, 0, 0, 0xB571, 0xB572, 0, 0, 0x3776, - 0x534A, 0x5348, 0x4153, 0x354A, 0x362C, 0x2F2D, 0x5345, 0, - 0x3674, 0, 0xB574, 0, 0, 0, 0x3144, 0, - 0, 0, 0, 0, 0, 0, 0, 0xA433, -}; -static const unsigned short utf8_to_euc_E597[] = { - 0, 0xB576, 0, 0xB577, 0x534E, 0x534C, 0xB578, 0x5427, - 0, 0xB579, 0, 0xB57A, 0xB57B, 0, 0xB57C, 0, - 0, 0xB57D, 0xB57E, 0xB621, 0x5351, 0, 0, 0xB622, - 0xB623, 0, 0x534B, 0xB624, 0x534F, 0, 0xB625, 0x534D, - 0, 0, 0xB626, 0x3B4C, 0x5350, 0, 0, 0, - 0, 0xB627, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB628, 0x5353, - 0, 0x5358, 0, 0, 0, 0x5356, 0x5355, 0xB629, -}; -static const unsigned short utf8_to_euc_E597_x0213[] = { - 0, 0xB576, 0, 0xB577, 0x534E, 0x534C, 0xB578, 0x5427, - 0, 0xA434, 0, 0xB57A, 0xA435, 0, 0x2F2E, 0, - 0, 0xA436, 0xA430, 0xB621, 0x5351, 0, 0, 0xB622, - 0xB623, 0, 0x534B, 0xB624, 0x534F, 0xA437, 0xB625, 0x534D, - 0, 0, 0xA439, 0x3B4C, 0x5350, 0, 0, 0, - 0, 0xA43B, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xB628, 0x5353, - 0, 0x5358, 0, 0, 0, 0x5356, 0x5355, 0xB629, -}; -static const unsigned short utf8_to_euc_E598[] = { - 0, 0, 0, 0, 0, 0xB62A, 0x4332, 0, - 0xB62B, 0x3245, 0xB62C, 0, 0, 0xB62D, 0xB62E, 0xB62F, - 0xB630, 0xB631, 0xB632, 0, 0x5352, 0, 0x5354, 0x3E28, - 0x3133, 0xB633, 0, 0x5357, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x325E, 0, 0, 0xB634, 0, 0, 0x5362, - 0xB635, 0x3E7C, 0x535E, 0xB636, 0x535C, 0xB637, 0x535D, 0xB638, - 0x535F, 0xB639, 0, 0xB63A, 0xB63B, 0xB63C, 0, 0xB63D, -}; -static const unsigned short utf8_to_euc_E598_x0213[] = { - 0, 0, 0, 0, 0, 0xB62A, 0x4332, 0xA43E, - 0x2F30, 0x3245, 0xB62C, 0, 0, 0xB62D, 0x2F31, 0xB62F, - 0xA43F, 0xB631, 0xB632, 0, 0x5352, 0, 0x5354, 0x3E28, - 0x3133, 0xB633, 0, 0x5357, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xA43C, 0x325E, 0, 0, 0xB634, 0, 0, 0x5362, - 0xA440, 0x3E7C, 0x535E, 0xB636, 0x535C, 0xB637, 0x535D, 0xA441, - 0x535F, 0xB639, 0, 0x2F32, 0xB63B, 0xA443, 0, 0xA444, -}; -static const unsigned short utf8_to_euc_E599[] = { - 0xB63E, 0xB63F, 0x313D, 0xB640, 0xB641, 0, 0xB642, 0, - 0, 0xB643, 0, 0xB644, 0x4139, 0xB645, 0x5359, 0xB646, - 0x535A, 0, 0, 0, 0xB647, 0, 0, 0, - 0, 0, 0, 0x337A, 0, 0, 0xB648, 0, - 0xB649, 0xB64A, 0xB64B, 0xB64C, 0x5361, 0, 0xB64D, 0, - 0x346F, 0xB64E, 0x5364, 0x5360, 0x5363, 0xB64F, 0, 0xB650, - 0, 0xB651, 0xB652, 0, 0x4A2E, 0xB653, 0, 0, - 0x4655, 0, 0x4838, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E599_x0213[] = { - 0xA445, 0xB63F, 0x313D, 0xB640, 0xB641, 0, 0xB642, 0xA446, - 0, 0x2F33, 0, 0xB644, 0x4139, 0xB645, 0x5359, 0xB646, - 0x535A, 0, 0, 0x7427, 0xB647, 0, 0, 0, - 0, 0, 0, 0x337A, 0, 0, 0xA447, 0, - 0xA448, 0xB64A, 0xB64B, 0xB64C, 0x5361, 0, 0x2F35, 0, - 0x346F, 0xB64E, 0x5364, 0x5360, 0x5363, 0xA449, 0, 0x2F37, - 0, 0x2F38, 0x2F39, 0, 0x4A2E, 0xB653, 0x2F34, 0, - 0x4655, 0, 0x4838, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E59A[] = { - 0x5366, 0, 0, 0, 0xB654, 0xB655, 0x5365, 0x3345, - 0xB656, 0, 0x5367, 0xB657, 0xB658, 0, 0, 0x536A, - 0, 0, 0, 0, 0x5369, 0xB659, 0, 0, - 0, 0xB65A, 0xB65B, 0, 0, 0xB65C, 0xB65D, 0xB65E, - 0x5368, 0, 0x4739, 0, 0, 0x536B, 0xB65F, 0xB660, - 0xB661, 0xB662, 0, 0xB663, 0xB664, 0xB665, 0x536C, 0, - 0, 0xB666, 0, 0xB667, 0x536E, 0, 0x536D, 0xB668, - 0, 0, 0, 0, 0x5370, 0, 0xB669, 0, -}; -static const unsigned short utf8_to_euc_E59A_x0213[] = { - 0x5366, 0, 0, 0, 0xB654, 0xB655, 0x5365, 0x3345, - 0xA44B, 0, 0x5367, 0xB657, 0xA44C, 0, 0, 0x536A, - 0, 0, 0, 0, 0x5369, 0xA44D, 0, 0, - 0, 0x2F3A, 0xA44E, 0, 0, 0xA44F, 0x2F3B, 0xB65E, - 0x5368, 0, 0x4739, 0, 0, 0x536B, 0xB65F, 0xB660, - 0xA450, 0x2F3C, 0, 0xB663, 0x2F3D, 0xA451, 0x536C, 0, - 0, 0xB666, 0xA452, 0x2F3E, 0x536E, 0, 0x536D, 0xB668, - 0, 0, 0, 0, 0x5370, 0, 0xB669, 0, -}; -static const unsigned short utf8_to_euc_E59B[] = { - 0x5373, 0x5371, 0x536F, 0x5372, 0, 0xB66A, 0, 0, - 0x5374, 0xB66B, 0xB66C, 0xB66D, 0xB670, 0xB671, 0x5375, 0xB66E, - 0xB66F, 0x5376, 0, 0x5377, 0, 0, 0, 0x5378, - 0x5145, 0xB672, 0x3C7C, 0x3B4D, 0xB673, 0xB674, 0x3273, 0xB675, - 0x3078, 0xB676, 0, 0x4344, 0xB677, 0xB678, 0xB679, 0xB67A, - 0xB67B, 0, 0, 0xB67D, 0, 0xB67E, 0x5379, 0, - 0x3A24, 0xB67C, 0x304F, 0x3F5E, 0, 0, 0xB721, 0xB722, - 0, 0x537A, 0x3847, 0, 0, 0x3971, 0, 0x537C, -}; -static const unsigned short utf8_to_euc_E59B_x0213[] = { - 0x5373, 0x5371, 0x536F, 0x5372, 0, 0xA453, 0, 0, - 0x5374, 0x2F3F, 0x2F40, 0xB66D, 0xB670, 0xA454, 0x5375, 0xB66E, - 0xB66F, 0x5376, 0, 0x5377, 0, 0, 0, 0x5378, - 0x5145, 0xB672, 0x3C7C, 0x3B4D, 0xB673, 0xB674, 0x3273, 0xA455, - 0x3078, 0xB676, 0, 0x4344, 0xB677, 0xB678, 0xB679, 0xB67A, - 0xA456, 0, 0, 0xB67D, 0, 0xB67E, 0x5379, 0, - 0x3A24, 0xB67C, 0x304F, 0x3F5E, 0, 0, 0xA457, 0xA458, - 0, 0x537A, 0x3847, 0, 0, 0x3971, 0, 0x537C, -}; -static const unsigned short utf8_to_euc_E59C[] = { - 0x537B, 0xB723, 0xB724, 0x4A60, 0x537D, 0, 0, 0xB725, - 0x5421, 0x537E, 0xB726, 0x5422, 0xB727, 0x5423, 0, 0x3777, - 0, 0xB728, 0x3160, 0x5424, 0, 0xB729, 0x5426, 0, - 0x5425, 0, 0xB72A, 0xB72B, 0x5428, 0xB72C, 0, 0x455A, - 0xB72D, 0, 0xB72E, 0xB72F, 0xB730, 0xB731, 0x5429, 0x3035, - 0x3A5F, 0xB732, 0xB733, 0, 0xB734, 0x373D, 0xB735, 0xB736, - 0x434F, 0, 0, 0xB737, 0xB738, 0, 0, 0x542A, - 0x542B, 0, 0, 0x542D, 0, 0xB739, 0xB73A, 0xB73B, -}; -static const unsigned short utf8_to_euc_E59C_x0213[] = { - 0x537B, 0xB723, 0xB724, 0x4A60, 0x537D, 0, 0, 0xB725, - 0x5421, 0x537E, 0x2F41, 0x5422, 0xB727, 0x5423, 0, 0x3777, - 0, 0xB728, 0x3160, 0x5424, 0, 0xA45A, 0x5426, 0, - 0x5425, 0, 0xB72A, 0xB72B, 0x5428, 0xB72C, 0, 0x455A, - 0xB72D, 0x2F43, 0xB72E, 0xA45B, 0xB730, 0xB731, 0x5429, 0x3035, - 0x3A5F, 0xA45D, 0xB733, 0, 0xB734, 0x373D, 0xB735, 0x2F44, - 0x434F, 0, 0, 0x2F45, 0x2F46, 0, 0, 0x542A, - 0x542B, 0, 0, 0x542D, 0, 0xB739, 0xB73A, 0xB73B, -}; -static const unsigned short utf8_to_euc_E59D[] = { - 0x542E, 0, 0x3A64, 0, 0, 0xB73C, 0xB73D, 0x3651, - 0, 0, 0x4B37, 0, 0xB73E, 0xB73F, 0x542C, 0x542F, - 0x3A41, 0x3923, 0xB740, 0, 0, 0, 0, 0, - 0, 0xF436, 0, 0, 0, 0, 0, 0, - 0, 0x5433, 0xB741, 0, 0x3A25, 0xB742, 0x4333, 0xB743, - 0xB744, 0x5430, 0x445A, 0xB745, 0, 0xB746, 0xB747, 0xB748, - 0xB749, 0xB74A, 0, 0xB74B, 0xB74C, 0xB74D, 0, 0xB74E, - 0, 0xB74F, 0xB750, 0xB751, 0xB752, 0, 0xB753, 0x5434, -}; -static const unsigned short utf8_to_euc_E59D_x0213[] = { - 0x542E, 0, 0x3A64, 0, 0, 0xA45F, 0xA460, 0x3651, - 0, 0, 0x4B37, 0, 0xA461, 0xA462, 0x542C, 0x542F, - 0x3A41, 0x3923, 0xB740, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x5433, 0xB741, 0, 0x3A25, 0, 0x4333, 0xB743, - 0xA464, 0x5430, 0x445A, 0xB745, 0, 0xB746, 0xB747, 0xA465, - 0x2F47, 0xB74A, 0, 0xA466, 0xA467, 0xA468, 0, 0x2F48, - 0, 0xB74F, 0xB750, 0xA469, 0x2F49, 0, 0xB753, 0x5434, -}; -static const unsigned short utf8_to_euc_E59E[] = { - 0, 0xB754, 0x3F62, 0xB755, 0, 0, 0, 0, - 0x5432, 0x5435, 0, 0x373F, 0xB756, 0, 0, 0, - 0, 0, 0, 0x5436, 0xB757, 0xB760, 0, 0xB758, - 0, 0xB759, 0xB75A, 0, 0xB75B, 0xB75C, 0xB75D, 0xB75E, - 0x5437, 0xB75F, 0x3924, 0x3340, 0x5439, 0, 0, 0xB761, - 0xB762, 0xB763, 0x543A, 0, 0xB764, 0, 0, 0, - 0x543B, 0, 0, 0x5438, 0, 0, 0, 0, - 0xB765, 0, 0, 0, 0, 0xB766, 0, 0, -}; -static const unsigned short utf8_to_euc_E59E_x0213[] = { - 0, 0xB754, 0x3F62, 0xB755, 0, 0, 0, 0, - 0x5432, 0x5435, 0, 0x373F, 0xB756, 0, 0, 0, - 0, 0, 0, 0x5436, 0xB757, 0xB760, 0, 0xB758, - 0, 0xB759, 0xA46D, 0, 0x2F4A, 0xA46E, 0xA46F, 0xB75E, - 0x5437, 0xB75F, 0x3924, 0x3340, 0x5439, 0, 0, 0xB761, - 0xA470, 0xB763, 0x543A, 0, 0xA46C, 0, 0, 0, - 0x543B, 0, 0, 0x5438, 0, 0, 0, 0, - 0x2F4D, 0, 0, 0, 0, 0xB766, 0, 0, -}; -static const unsigned short utf8_to_euc_E59F[] = { - 0x5431, 0, 0, 0x543C, 0, 0, 0x543D, 0xB767, - 0xB768, 0, 0, 0x4B64, 0xB769, 0, 0x3E6B, 0xB76A, - 0, 0, 0x543F, 0x5440, 0x543E, 0xB76B, 0x5442, 0, - 0, 0, 0, 0, 0x4738, 0xB76C, 0xB76D, 0x3068, - 0x4956, 0xB77E, 0, 0x5443, 0xB76E, 0, 0xB76F, 0xB770, - 0, 0xB771, 0, 0, 0, 0xB772, 0, 0, - 0xB773, 0, 0, 0, 0x3E7D, 0xB774, 0xB775, 0x3C39, - 0xB776, 0x475D, 0x3470, 0, 0x3A6B, 0xB777, 0xB778, 0xB779, -}; -static const unsigned short utf8_to_euc_E59F_x0213[] = { - 0x5431, 0, 0, 0x543C, 0, 0, 0x543D, 0x2F4E, - 0x2F4F, 0, 0, 0x4B64, 0xA473, 0, 0x3E6B, 0x2F50, - 0, 0, 0x543F, 0x5440, 0x543E, 0xB76B, 0x5442, 0xA471, - 0, 0, 0, 0, 0x4738, 0xB76C, 0xA476, 0x3068, - 0x4956, 0xB77E, 0, 0x5443, 0x2F51, 0, 0xA477, 0xB770, - 0, 0xB771, 0, 0, 0, 0x2F52, 0, 0, - 0xA478, 0, 0, 0, 0x3E7D, 0x2F53, 0x2F54, 0x3C39, - 0xA47A, 0x475D, 0x3470, 0xA47B, 0x3A6B, 0xA47C, 0xB778, 0x2F55, -}; -static const unsigned short utf8_to_euc_E5A0[] = { - 0x4B59, 0, 0x4632, 0xB77A, 0xB77B, 0x3778, 0x424F, 0, - 0xB77C, 0xB77D, 0x5441, 0x5444, 0xB821, 0xB822, 0, 0, - 0, 0, 0, 0, 0, 0x4244, 0, 0, - 0, 0x5445, 0, 0xB823, 0, 0x5446, 0xB824, 0xB825, - 0xB826, 0x5448, 0, 0, 0x4469, 0, 0xB827, 0xB828, - 0, 0, 0x342E, 0, 0, 0xB829, 0, 0x7421, - 0x3161, 0x4A73, 0xB82A, 0, 0x3E6C, 0x4548, 0, 0, - 0, 0xB82B, 0x3A66, 0, 0, 0x544E, 0, 0xB82C, -}; -static const unsigned short utf8_to_euc_E5A0_x0213[] = { - 0x4B59, 0, 0x4632, 0xB77A, 0xA47D, 0x3778, 0x424F, 0, - 0xB77C, 0x2F56, 0x5441, 0x5444, 0xB821, 0xB822, 0, 0, - 0, 0, 0, 0, 0, 0x4244, 0, 0, - 0, 0x5445, 0, 0xB823, 0, 0x5446, 0xA47E, 0xB825, - 0xA521, 0x5448, 0, 0, 0x4469, 0, 0xB827, 0xA522, - 0, 0, 0x342E, 0, 0, 0xB829, 0, 0x7421, - 0x3161, 0x4A73, 0xA523, 0, 0x3E6C, 0x4548, 0, 0, - 0, 0xA524, 0x3A66, 0, 0, 0x544E, 0, 0xB82C, -}; -static const unsigned short utf8_to_euc_E5A1[] = { - 0x4A3D, 0x4E5D, 0, 0, 0, 0, 0, 0, - 0, 0xB82D, 0x3274, 0x544A, 0xB82E, 0xB82F, 0, 0xB830, - 0xB831, 0x413A, 0x544D, 0, 0x4563, 0xB832, 0, 0x4549, - 0x4564, 0x4839, 0x444D, 0, 0, 0, 0x3A49, 0xB833, - 0, 0xB834, 0x5449, 0, 0xB835, 0, 0, 0xB836, - 0xB837, 0x3176, 0, 0x4536, 0, 0, 0, 0, - 0x544B, 0, 0x5447, 0, 0, 0x3F50, 0, 0, - 0xB838, 0x544F, 0, 0, 0xB839, 0, 0x3D4E, 0xB83A, -}; -static const unsigned short utf8_to_euc_E5A1_x0213[] = { - 0x4A3D, 0x4E5D, 0, 0, 0, 0, 0, 0, - 0, 0xA526, 0x3274, 0x544A, 0xA527, 0xB82F, 0, 0xB830, - 0xB831, 0x413A, 0x544D, 0, 0x4563, 0xB832, 0, 0x4549, - 0x4564, 0x4839, 0x444D, 0, 0, 0, 0x3A49, 0xB833, - 0, 0x2F58, 0x5449, 0, 0x2F59, 0, 0, 0xA528, - 0xB837, 0x3176, 0, 0x4536, 0, 0, 0, 0, - 0x544B, 0, 0x5447, 0, 0, 0x3F50, 0, 0, - 0xB838, 0x544F, 0, 0, 0x2F5B, 0, 0x3D4E, 0xB83A, -}; -static const unsigned short utf8_to_euc_E5A2[] = { - 0xB83B, 0xB83C, 0, 0x362D, 0, 0x5450, 0, 0xB83D, - 0xB83E, 0xB83F, 0xB840, 0, 0xB841, 0xB842, 0, 0xB843, - 0xB844, 0, 0, 0x4A68, 0xB845, 0, 0xB846, 0x417D, - 0, 0, 0, 0, 0x4446, 0xB847, 0xF439, 0x5452, - 0xB848, 0xB849, 0xB84A, 0, 0, 0, 0xB84B, 0, - 0x4B4F, 0xB84C, 0, 0x5453, 0, 0, 0x5458, 0, - 0, 0xB84D, 0xB84E, 0x4A2F, 0, 0, 0, 0, - 0x5457, 0x5451, 0x5454, 0x5456, 0xB850, 0, 0x3A26, 0, -}; -static const unsigned short utf8_to_euc_E5A2_x0213[] = { - 0xB83B, 0xB83C, 0, 0x362D, 0, 0x5450, 0, 0xB83D, - 0xB83E, 0x2F5C, 0xA529, 0xA52A, 0xB841, 0xA52B, 0, 0xA52C, - 0xA52D, 0, 0, 0x4A68, 0xA52E, 0, 0xB846, 0x417D, - 0, 0, 0, 0, 0x4446, 0xA52F, 0x2F5D, 0x5452, - 0xB848, 0xB849, 0xB84A, 0, 0, 0, 0xB84B, 0, - 0x4B4F, 0x2F5F, 0xA530, 0x5453, 0, 0, 0x5458, 0, - 0, 0xA531, 0, 0x4A2F, 0, 0, 0, 0, - 0x5457, 0x5451, 0x5454, 0x5456, 0xB850, 0, 0x3A26, 0, -}; -static const unsigned short utf8_to_euc_E5A3[] = { - 0, 0x4A49, 0xB851, 0, 0xB84F, 0x5459, 0, 0x4345, - 0xB852, 0, 0x3275, 0, 0x3E6D, 0xB853, 0xB854, 0, - 0xB855, 0x545B, 0xB856, 0x545A, 0xB857, 0x3968, 0xB858, 0x545C, - 0x545E, 0x545D, 0xB859, 0, 0x5460, 0xB85A, 0x5455, 0x5462, - 0, 0xB85B, 0xB85C, 0, 0x5461, 0x545F, 0, 0, - 0, 0xB85D, 0, 0x3B4E, 0x3F51, 0, 0x4154, 0x5463, - 0x403C, 0x306D, 0x4764, 0xB85E, 0, 0, 0, 0x445B, - 0, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A3_x0213[] = { - 0, 0x4A49, 0xB851, 0xA533, 0xB84F, 0x5459, 0, 0x4345, - 0xB852, 0, 0x3275, 0, 0x3E6D, 0xA534, 0x2F62, 0, - 0xB855, 0x545B, 0x2F61, 0x545A, 0x2F63, 0x3968, 0xB858, 0x545C, - 0x545E, 0x545D, 0x2F64, 0, 0x5460, 0xB85A, 0x5455, 0x5462, - 0x2F65, 0xB85B, 0xA535, 0, 0x5461, 0x545F, 0, 0, - 0, 0x2F66, 0, 0x3B4E, 0x3F51, 0, 0x4154, 0x5463, - 0x403C, 0x306D, 0x4764, 0xA536, 0xA537, 0, 0, 0x445B, - 0, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A4[] = { - 0, 0, 0x5469, 0, 0, 0xB85F, 0xB860, 0, - 0, 0x4A51, 0x546A, 0xB861, 0xB862, 0, 0, 0x3246, - 0x546B, 0, 0xB863, 0xB864, 0xB865, 0x4D3C, 0x3330, 0, - 0x5249, 0x3D48, 0x423F, 0x546C, 0x4C6B, 0xB867, 0, 0, - 0, 0xB868, 0x4C34, 0xB869, 0xB86A, 0x546E, 0, 0x4267, - 0xB86B, 0x4537, 0x4240, 0x4957, 0x546F, 0x5470, 0x317B, 0xB86C, - 0xB86D, 0x3C3A, 0x5471, 0xB86E, 0, 0xB86F, 0xB870, 0x3050, - 0x5472, 0, 0, 0, 0, 0, 0x5473, 0xB871, -}; -static const unsigned short utf8_to_euc_E5A4_x0213[] = { - 0, 0, 0x5469, 0, 0, 0xA538, 0xA539, 0, - 0, 0x4A51, 0x546A, 0xA53A, 0x2F67, 0xA53B, 0, 0x3246, - 0x546B, 0, 0xB863, 0xB864, 0xA53C, 0x4D3C, 0x3330, 0, - 0x5249, 0x3D48, 0x423F, 0x546C, 0x4C6B, 0xB867, 0, 0, - 0, 0xB868, 0x4C34, 0xB869, 0xA53D, 0x546E, 0, 0x4267, - 0xB86B, 0x4537, 0x4240, 0x4957, 0x546F, 0x5470, 0x317B, 0xB86C, - 0xB86D, 0x3C3A, 0x5471, 0xB86E, 0, 0xB86F, 0xB870, 0x3050, - 0x5472, 0, 0, 0, 0, 0xA540, 0x5473, 0xB871, -}; -static const unsigned short utf8_to_euc_E5A5[] = { - 0, 0, 0, 0xB872, 0x3162, 0, 0xB873, 0x3471, - 0x4660, 0x4A74, 0, 0, 0, 0, 0x5477, 0x4155, - 0x5476, 0x3740, 0xB874, 0xB875, 0x4B5B, 0x5475, 0, 0x4565, - 0x5479, 0xB876, 0x5478, 0xB877, 0, 0xB878, 0xB879, 0xB87A, - 0x547B, 0xB87B, 0x547A, 0xB87C, 0, 0x317C, 0, 0x547C, - 0x3E29, 0x547E, 0x4325, 0xB87D, 0x547D, 0xB87E, 0x4A33, 0xB921, - 0, 0, 0xB922, 0x3D77, 0x455B, 0xB923, 0xB924, 0, - 0x5521, 0xB925, 0, 0xB926, 0xB927, 0x3925, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A5_x0213[] = { - 0, 0, 0, 0xB872, 0x3162, 0, 0xA542, 0x3471, - 0x4660, 0x4A74, 0, 0, 0, 0, 0x5477, 0x4155, - 0x5476, 0x3740, 0xB874, 0, 0x4B5B, 0x5475, 0, 0x4565, - 0x5479, 0xB876, 0x5478, 0xA545, 0, 0x2F69, 0xB879, 0xA546, - 0x547B, 0xB87B, 0x547A, 0, 0, 0x317C, 0, 0x547C, - 0x3E29, 0x547E, 0x4325, 0xB87D, 0x547D, 0x2F6A, 0x4A33, 0xB921, - 0, 0, 0xB922, 0x3D77, 0x455B, 0xA548, 0xA549, 0, - 0x5521, 0xB925, 0, 0xB926, 0xA54A, 0x3925, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A6[] = { - 0, 0x5522, 0x4721, 0x485E, 0x4C51, 0, 0, 0, - 0, 0, 0x4725, 0xB928, 0xB929, 0x552B, 0xB92A, 0, - 0, 0, 0xB92B, 0x3538, 0, 0xB92C, 0x4D45, 0xB92D, - 0, 0x4C2F, 0, 0x562C, 0, 0x5523, 0, 0xB92E, - 0, 0, 0, 0x5526, 0xB92F, 0x4245, 0, 0xB930, - 0x4B38, 0, 0, 0, 0x454A, 0xB931, 0xB932, 0xB933, - 0xB934, 0, 0x5527, 0xB935, 0, 0, 0, 0xB936, - 0, 0x4B65, 0xB937, 0x3A4A, 0xB938, 0, 0x3E2A, 0, -}; -static const unsigned short utf8_to_euc_E5A6_x0213[] = { - 0, 0x5522, 0x4721, 0x485E, 0x4C51, 0, 0, 0, - 0, 0, 0x4725, 0x2F6B, 0xB929, 0x552B, 0xB92A, 0, - 0, 0, 0x2F6C, 0x3538, 0, 0xB92C, 0x4D45, 0xB92D, - 0, 0x4C2F, 0, 0x562C, 0, 0x5523, 0, 0xA54B, - 0, 0, 0, 0x5526, 0x2F6D, 0x4245, 0, 0xB930, - 0x4B38, 0, 0, 0, 0x454A, 0xB931, 0xA54C, 0xB933, - 0xB934, 0, 0x5527, 0xB935, 0, 0, 0, 0xB936, - 0, 0x4B65, 0, 0x3A4A, 0xA54D, 0, 0x3E2A, 0, -}; -static const unsigned short utf8_to_euc_E5A7[] = { - 0, 0xB939, 0, 0xB93A, 0xB93B, 0, 0x5528, 0, - 0xB93C, 0x3B50, 0xB93D, 0x3B4F, 0, 0xB93E, 0, 0, - 0x3039, 0x3848, 0xB93F, 0x402B, 0x3051, 0, 0, 0, - 0, 0x552C, 0x552D, 0, 0x552A, 0xB940, 0xB941, 0xB942, - 0, 0, 0, 0xB943, 0xB944, 0x3138, 0x342F, 0xB945, - 0x5529, 0, 0x4C45, 0x4931, 0, 0, 0xB946, 0xB947, - 0, 0xB948, 0xB949, 0, 0xB94A, 0, 0x3028, 0xB94B, - 0, 0, 0, 0x3079, 0, 0, 0, 0x3B51, -}; -static const unsigned short utf8_to_euc_E5A7_x0213[] = { - 0, 0xB939, 0, 0x2F6E, 0xB93B, 0, 0x5528, 0, - 0xA54E, 0x3B50, 0xB93D, 0x3B4F, 0, 0xA54F, 0, 0, - 0x3039, 0x3848, 0x2F6F, 0x402B, 0x3051, 0, 0, 0, - 0, 0x552C, 0x552D, 0, 0x552A, 0x2F70, 0xA550, 0xB942, - 0, 0, 0, 0xA551, 0xA552, 0x3138, 0x342F, 0xA553, - 0x5529, 0, 0x4C45, 0x4931, 0, 0, 0xA554, 0xB947, - 0, 0xB948, 0xB949, 0, 0xB94A, 0, 0x3028, 0xB94B, - 0x7E7A, 0, 0, 0x3079, 0, 0, 0, 0x3B51, -}; -static const unsigned short utf8_to_euc_E5A8[] = { - 0xB94C, 0x3052, 0, 0x3023, 0xB94D, 0, 0, 0, - 0, 0x5532, 0, 0, 0xB94E, 0xB94F, 0xB950, 0, - 0, 0x5530, 0xB951, 0xB952, 0, 0, 0, 0, - 0x4C3C, 0, 0x5533, 0, 0x5531, 0, 0xB953, 0x552F, - 0x3F31, 0, 0, 0xB954, 0xB955, 0x552E, 0, 0xB956, - 0xB957, 0x4A5A, 0xB958, 0, 0, 0xB959, 0, 0x3864, - 0xB95A, 0, 0, 0, 0, 0x5537, 0x5538, 0, - 0, 0, 0, 0, 0x3E2B, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A8_x0213[] = { - 0xB94C, 0x3052, 0, 0x3023, 0xB94D, 0, 0, 0, - 0, 0x5532, 0, 0, 0xA558, 0xA559, 0xB950, 0, - 0, 0x5530, 0xB951, 0x2F71, 0, 0, 0, 0xA55A, - 0x4C3C, 0, 0x5533, 0, 0x5531, 0, 0xB953, 0x552F, - 0x3F31, 0, 0, 0x2F72, 0xB955, 0x552E, 0, 0xA55B, - 0xB957, 0x4A5A, 0xB958, 0, 0, 0xA55C, 0, 0x3864, - 0xB95A, 0, 0, 0, 0, 0x5537, 0x5538, 0, - 0, 0, 0, 0, 0x3E2B, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E5A9[] = { - 0x5534, 0x4F2C, 0, 0, 0xB95B, 0xB95C, 0x474C, 0xB95D, - 0xB95E, 0x5536, 0, 0, 0xB95F, 0, 0, 0, - 0xB960, 0, 0, 0, 0, 0xB961, 0, 0, - 0, 0, 0x3A27, 0, 0, 0, 0xB962, 0, - 0, 0, 0x5539, 0xB963, 0, 0xB964, 0x4958, 0xB965, - 0, 0, 0x553A, 0, 0x5535, 0xB966, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xB967, - 0, 0, 0xB968, 0xB969, 0, 0, 0xB96A, 0x4C3B, -}; -static const unsigned short utf8_to_euc_E5A9_x0213[] = { - 0x5534, 0x4F2C, 0, 0, 0xB95B, 0xB95C, 0x474C, 0xB95D, - 0xB95E, 0x5536, 0, 0, 0xB95F, 0, 0, 0, - 0xB960, 0, 0, 0, 0, 0xA55D, 0, 0, - 0, 0, 0x3A27, 0, 0, 0, 0xB962, 0, - 0, 0, 0x5539, 0xB963, 0, 0xA55E, 0x4958, 0x2F73, - 0, 0, 0x553A, 0, 0x5535, 0x2F74, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2F75, - 0, 0, 0xA55F, 0xB969, 0, 0, 0x2F76, 0x4C3B, -}; -static const unsigned short utf8_to_euc_E5AA[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xB96B, 0, 0, 0, 0, - 0xB96C, 0, 0x475E, 0xB96D, 0, 0, 0xB96E, 0, - 0, 0xB96F, 0x553B, 0x4932, 0xB970, 0, 0xB971, 0xB972, - 0xB973, 0, 0xB974, 0, 0, 0, 0, 0xB975, - 0, 0, 0, 0, 0xB976, 0, 0, 0, - 0, 0xB977, 0xB978, 0xB979, 0, 0xB97A, 0, 0, - 0xB97B, 0, 0xB97C, 0xB97D, 0x553C, 0x5540, 0x553D, 0xB97E, -}; -static const unsigned short utf8_to_euc_E5AA_x0213[] = { - 0, 0, 0, 0, 0x2F77, 0, 0, 0, - 0, 0, 0, 0xA560, 0, 0, 0, 0, - 0xB96C, 0, 0x475E, 0xB96D, 0, 0, 0xB96E, 0, - 0, 0xB96F, 0x553B, 0x4932, 0xA561, 0, 0x2F78, 0xA562, - 0xA563, 0, 0xA564, 0, 0, 0, 0, 0x2F79, - 0, 0, 0, 0, 0xB976, 0, 0, 0, - 0, 0xA565, 0xB978, 0xA566, 0, 0xA567, 0, 0, - 0xB97B, 0, 0xA568, 0xB97D, 0x553C, 0x5540, 0x553D, 0xA569, -}; -static const unsigned short utf8_to_euc_E5AB[] = { - 0, 0x3247, 0x553F, 0, 0xBA21, 0, 0xBA22, 0, - 0xBA23, 0x3C3B, 0, 0x553E, 0x3779, 0, 0, 0xBA24, - 0x554C, 0, 0, 0, 0, 0, 0x5545, 0x5542, - 0, 0, 0xBA25, 0, 0xBA26, 0, 0, 0, - 0xBA27, 0x4364, 0, 0x5541, 0, 0xBA28, 0x5543, 0, - 0, 0x5544, 0xBA29, 0, 0, 0, 0xBA2A, 0, - 0, 0, 0, 0, 0, 0xBA2B, 0xBA2C, 0, - 0, 0, 0x5546, 0x5547, 0, 0xBA2D, 0, 0, -}; -static const unsigned short utf8_to_euc_E5AB_x0213[] = { - 0, 0x3247, 0x553F, 0, 0x2F7A, 0, 0xBA22, 0, - 0xBA23, 0x3C3B, 0, 0x553E, 0x3779, 0, 0, 0xBA24, - 0x554C, 0, 0, 0, 0, 0, 0x5545, 0x5542, - 0, 0, 0xA56A, 0, 0xA56B, 0, 0, 0, - 0xA56C, 0x4364, 0, 0x5541, 0, 0xA56D, 0x5543, 0, - 0, 0x5544, 0xBA29, 0, 0, 0, 0xA56F, 0, - 0xA56E, 0, 0, 0, 0, 0xA570, 0xBA2C, 0, - 0, 0, 0x5546, 0x5547, 0, 0xBA2D, 0, 0, -}; -static const unsigned short utf8_to_euc_E5AC[] = { - 0xBA2E, 0xBA2F, 0, 0, 0, 0, 0, 0, - 0xBA30, 0x3472, 0, 0x5549, 0x5548, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x554A, 0xBA31, - 0, 0xBA33, 0, 0xBA34, 0, 0xBA35, 0, 0, - 0, 0xBA36, 0x3E6E, 0, 0, 0xBA37, 0, 0, - 0, 0, 0x554D, 0, 0x445C, 0xBA38, 0, 0, - 0x3145, 0, 0x554B, 0, 0xBA32, 0, 0x554E, 0, - 0xBA39, 0, 0, 0, 0, 0, 0x554F, 0, -}; -static const unsigned short utf8_to_euc_E5AC_x0213[] = { - 0xA571, 0xBA2F, 0, 0, 0, 0, 0, 0, - 0xA572, 0x3472, 0, 0x5549, 0x5548, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x554A, 0xA573, - 0, 0x2F7C, 0, 0xBA34, 0, 0xBA35, 0, 0, - 0, 0xBA36, 0x3E6E, 0, 0, 0x2F7D, 0, 0, - 0, 0, 0x554D, 0, 0x445C, 0xA575, 0, 0, - 0x3145, 0, 0x554B, 0, 0xA574, 0, 0x554E, 0, - 0xBA39, 0, 0, 0, 0, 0, 0x554F, 0, -}; -static const unsigned short utf8_to_euc_E5AD[] = { - 0x5552, 0xBA3A, 0, 0x5550, 0, 0x5551, 0, 0, - 0, 0, 0, 0xBA3B, 0xBA3C, 0, 0, 0, - 0x3B52, 0x5553, 0xBA3D, 0, 0x3926, 0x5554, 0xBA3E, 0x3B7A, - 0x4238, 0, 0x5555, 0x5556, 0x3B5A, 0x3927, 0xBA3F, 0x4C52, - 0, 0, 0, 0x3528, 0x3849, 0x5557, 0x3358, 0, - 0xBA40, 0x5558, 0, 0x4239, 0, 0, 0xBA41, 0xBA42, - 0x5559, 0x5623, 0, 0x555A, 0, 0x555B, 0, 0, - 0x555C, 0, 0x555E, 0, 0xBA43, 0xBA44, 0xBA45, 0xBA46, -}; -static const unsigned short utf8_to_euc_E5AD_x0213[] = { - 0x5552, 0x4F55, 0, 0x5550, 0, 0x5551, 0, 0, - 0, 0, 0, 0xBA3B, 0xA576, 0, 0, 0, - 0x3B52, 0x5553, 0xA577, 0, 0x3926, 0x5554, 0x4F56, 0x3B7A, - 0x4238, 0, 0x5555, 0x5556, 0x3B5A, 0x3927, 0xBA3F, 0x4C52, - 0, 0, 0, 0x3528, 0x3849, 0x5557, 0x3358, 0, - 0xA578, 0x5558, 0, 0x4239, 0, 0, 0xBA41, 0xA579, - 0x5559, 0x5623, 0, 0x555A, 0, 0x555B, 0, 0, - 0x555C, 0, 0x555E, 0, 0xA57A, 0x4F57, 0xBA45, 0xA57B, -}; -static const unsigned short utf8_to_euc_E5AE[] = { - 0x555F, 0xBA47, 0, 0x5560, 0xBA48, 0x4270, 0xBA49, 0x3127, - 0x3C69, 0x3042, 0xBA4A, 0x4157, 0x3430, 0x3C35, 0xBA4B, 0x3928, - 0xBA4C, 0xBA4D, 0, 0xBA4E, 0xBA4F, 0x4566, 0xBA50, 0x3D21, - 0x3431, 0x4368, 0x446A, 0x3038, 0x3539, 0x4A75, 0, 0x3C42, - 0, 0, 0x3552, 0x406B, 0x3C3C, 0x4D28, 0x5561, 0, - 0xBA51, 0xBA52, 0, 0, 0xBA53, 0xBA54, 0x355C, 0xBA55, - 0x3A4B, 0xBA56, 0xBA57, 0x3332, 0x3163, 0x3E2C, 0x3248, 0xBA58, - 0x5562, 0x4D46, 0xBA59, 0, 0xBA5A, 0, 0, 0x3D49, -}; -static const unsigned short utf8_to_euc_E5AE_x0213[] = { - 0x555F, 0xA57C, 0, 0x5560, 0xA57D, 0x4270, 0xBA49, 0x3127, - 0x3C69, 0x3042, 0xBA4A, 0x4157, 0x3430, 0x3C35, 0xBA4B, 0x3928, - 0xBA4C, 0xBA4D, 0, 0x4F58, 0xBA4F, 0x4566, 0xA821, 0x3D21, - 0x3431, 0x4368, 0x446A, 0x3038, 0x3539, 0x4A75, 0, 0x3C42, - 0, 0, 0x3552, 0x406B, 0x3C3C, 0x4D28, 0x5561, 0, - 0xBA51, 0xBA52, 0, 0, 0xA822, 0xBA54, 0x355C, 0xBA55, - 0x3A4B, 0xBA56, 0xBA57, 0x3332, 0x3163, 0x3E2C, 0x3248, 0xBA58, - 0x5562, 0x4D46, 0xBA59, 0, 0xBA5A, 0, 0, 0x3D49, -}; -static const unsigned short utf8_to_euc_E5AF[] = { - 0xBA5B, 0xBA5C, 0x3C64, 0x5563, 0x3473, 0x4652, 0x4C29, 0x5564, - 0, 0x5565, 0, 0, 0x4959, 0xBA5D, 0, 0xBA5E, - 0x5567, 0, 0x3428, 0x3677, 0x5566, 0, 0xBA5F, 0xBA60, - 0xBA61, 0xBA62, 0xBA63, 0x3432, 0, 0x3F32, 0x556B, 0x3B21, - 0xBA64, 0x3249, 0x556A, 0, 0x5568, 0x556C, 0x5569, 0x472B, - 0x5C4D, 0x3F33, 0, 0x556D, 0xF43A, 0, 0x4E40, 0xBA65, - 0x556E, 0xBA66, 0, 0x5570, 0xBA67, 0x437E, 0x556F, 0, - 0x4023, 0, 0x3B7B, 0, 0, 0xBA68, 0x4250, 0x3C77, -}; -static const unsigned short utf8_to_euc_E5AF_x0213[] = { - 0xA824, 0xBA5C, 0x3C64, 0x5563, 0x3473, 0x4652, 0x4C29, 0x5564, - 0, 0x5565, 0, 0, 0x4959, 0xBA5D, 0xA826, 0xBA5E, - 0x5567, 0, 0x3428, 0x3677, 0x5566, 0, 0xA827, 0xBA60, - 0x4F59, 0xBA62, 0xBA63, 0x3432, 0, 0x3F32, 0x556B, 0x3B21, - 0xBA64, 0x3249, 0x556A, 0, 0x5568, 0x556C, 0x5569, 0x472B, - 0x5C4D, 0x3F33, 0, 0x556D, 0x4F5A, 0, 0x4E40, 0xBA65, - 0x556E, 0xA82A, 0, 0x5570, 0xBA67, 0x437E, 0x556F, 0, - 0x4023, 0, 0x3B7B, 0, 0, 0xA82B, 0x4250, 0x3C77, -}; -static const unsigned short utf8_to_euc_E5B0[] = { - 0, 0x4975, 0x406C, 0, 0x3C4D, 0x5571, 0x3E2D, 0x5572, - 0x5573, 0x3053, 0x423A, 0x3F52, 0xBA69, 0x5574, 0x4633, 0x3E2E, - 0, 0x3E2F, 0, 0x5575, 0, 0, 0x406D, 0xBA6A, - 0, 0, 0x3E30, 0, 0, 0, 0xBA6B, 0xBA6C, - 0x5576, 0, 0x5577, 0xBA6D, 0x4C60, 0, 0xBA6E, 0, - 0x5578, 0xBA6F, 0, 0xBA70, 0xBA71, 0x3646, 0xBA72, 0, - 0xBA73, 0x3D22, 0xBA74, 0, 0, 0xBA75, 0xBA76, 0, - 0x5579, 0x557A, 0x3C5C, 0x3F2C, 0x4674, 0x3F54, 0x4878, 0x4722, -}; -static const unsigned short utf8_to_euc_E5B0_x0213[] = { - 0, 0x4975, 0x406C, 0xA82D, 0x3C4D, 0x5571, 0x3E2D, 0x5572, - 0x5573, 0x3053, 0x423A, 0x3F52, 0xBA69, 0x5574, 0x4633, 0x3E2E, - 0, 0x3E2F, 0x4F5B, 0x5575, 0, 0, 0x406D, 0xBA6A, - 0, 0, 0x3E30, 0, 0, 0, 0x4F5C, 0xBA6C, - 0x5576, 0, 0x5577, 0x4F5D, 0x4C60, 0, 0xBA6E, 0, - 0x5578, 0xA82E, 0, 0x4F5E, 0xBA71, 0x3646, 0xBA72, 0, - 0xA82F, 0x3D22, 0xBA74, 0, 0, 0xBA75, 0xBA76, 0, - 0x5579, 0x557A, 0x3C5C, 0x3F2C, 0x4674, 0x3F54, 0x4878, 0x4722, -}; -static const unsigned short utf8_to_euc_E5B1[] = { - 0x3649, 0x557B, 0, 0, 0, 0x356F, 0x557C, 0, - 0x367E, 0, 0x464F, 0x3230, 0, 0x3B53, 0x557D, 0x5622, - 0x5621, 0x367D, 0, 0x557E, 0, 0x4538, 0, 0, - 0, 0xBA77, 0xBA78, 0, 0xBA79, 0, 0x4230, 0, - 0x454B, 0x3C48, 0xBA7A, 0xBA7B, 0x4158, 0x4D7A, 0, 0xBA7C, - 0xBA7D, 0xBA7E, 0, 0, 0x5624, 0xBB21, 0x5625, 0x4656, - 0xBB22, 0x3B33, 0, 0, 0xBB23, 0xBB24, 0x5627, 0, - 0, 0x5628, 0xBB25, 0xBB26, 0xBB27, 0xBB28, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B1_x0213[] = { - 0x3649, 0x557B, 0, 0, 0, 0x356F, 0x557C, 0, - 0x367E, 0, 0x464F, 0x3230, 0, 0x3B53, 0x557D, 0x5622, - 0x5621, 0x367D, 0, 0x557E, 0, 0x4538, 0, 0, - 0, 0xBA77, 0xBA78, 0x7E7B, 0xBA79, 0, 0x4230, 0xA831, - 0x454B, 0x3C48, 0x4F60, 0xA832, 0x4158, 0x4D7A, 0, 0xA833, - 0xA834, 0xA835, 0, 0, 0x5624, 0xBB21, 0x5625, 0x4656, - 0xA836, 0x3B33, 0, 0, 0xBB23, 0xBB24, 0x5627, 0, - 0, 0x5628, 0x4F64, 0xBB26, 0xA839, 0xBB28, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B2[] = { - 0, 0, 0, 0, 0, 0, 0, 0xBB29, - 0xBB2A, 0, 0xBB2B, 0, 0x5629, 0, 0, 0xBB2C, - 0x3474, 0x562A, 0xBB2D, 0, 0x562B, 0, 0, 0, - 0, 0, 0, 0, 0, 0xBB2E, 0, 0xBB2F, - 0xBB30, 0x322C, 0xBB31, 0xBB32, 0, 0, 0xBB33, 0, - 0x413B, 0x3464, 0xBB34, 0x562D, 0x4C28, 0, 0, 0, - 0, 0x4252, 0xBB35, 0x3359, 0xBB36, 0xBB37, 0x562F, 0x5631, - 0x345F, 0, 0xBB38, 0x562E, 0x5630, 0, 0x5633, 0, -}; -static const unsigned short utf8_to_euc_E5B2_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xBB29, - 0xA83C, 0, 0xA83D, 0, 0x5629, 0, 0, 0x4F65, - 0x3474, 0x562A, 0xBB2D, 0, 0x562B, 0, 0, 0, - 0, 0, 0, 0, 0, 0xBB2E, 0, 0x4F66, - 0xA841, 0x322C, 0xA842, 0x4F67, 0, 0, 0xA843, 0xA844, - 0x413B, 0x3464, 0x4F68, 0x562D, 0x4C28, 0xA846, 0, 0, - 0, 0x4252, 0xBB35, 0x3359, 0xBB36, 0xA847, 0x562F, 0x5631, - 0x345F, 0, 0x4F69, 0x562E, 0x5630, 0, 0x5633, 0, -}; -static const unsigned short utf8_to_euc_E5B3[] = { - 0, 0, 0, 0, 0, 0x5632, 0, 0x5634, - 0, 0xBB39, 0, 0xBB3A, 0, 0, 0, 0, - 0, 0, 0xBB3B, 0, 0, 0, 0, 0xBB3D, - 0, 0x5635, 0, 0, 0, 0xBB3C, 0, 0, - 0x463D, 0x362E, 0, 0, 0, 0, 0, 0, - 0x3265, 0x5636, 0x563B, 0, 0, 0x5639, 0xBB3E, 0x4A77, - 0x4A76, 0xBB3F, 0xBB40, 0, 0xBB41, 0xF43B, 0x4567, 0, - 0, 0, 0x5638, 0x3D54, 0, 0x5637, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B3_x0213[] = { - 0, 0, 0, 0, 0, 0x5632, 0, 0x5634, - 0, 0xA849, 0, 0x4F6A, 0, 0, 0, 0, - 0x4F6B, 0, 0x4F6C, 0, 0, 0, 0, 0xBB3D, - 0, 0x5635, 0, 0, 0, 0xBB3C, 0, 0, - 0x463D, 0x362E, 0, 0, 0, 0, 0, 0, - 0x3265, 0x5636, 0x563B, 0, 0, 0x5639, 0xBB3E, 0x4A77, - 0x4A76, 0xBB3F, 0xBB40, 0, 0x4F6D, 0, 0x4567, 0, - 0, 0, 0x5638, 0x3D54, 0, 0x5637, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B4[] = { - 0, 0xBB42, 0, 0, 0, 0, 0xBB43, 0x3F72, - 0, 0, 0, 0x563C, 0, 0xBB44, 0x3A6A, 0, - 0, 0x5642, 0xBB45, 0, 0x5643, 0x563D, 0x3333, 0x563E, - 0x5647, 0x5646, 0x5645, 0x5641, 0, 0, 0, 0x5640, - 0, 0, 0x5644, 0xBB47, 0xBB48, 0, 0xBB49, 0xBB4A, - 0, 0x4A78, 0, 0xBB46, 0, 0, 0, 0, - 0, 0xBB4B, 0, 0, 0xBB4C, 0, 0, 0, - 0, 0xBB4D, 0, 0, 0, 0xBB4E, 0, 0xBB4F, -}; -static const unsigned short utf8_to_euc_E5B4_x0213[] = { - 0, 0xBB42, 0, 0, 0, 0, 0xA84C, 0x3F72, - 0, 0, 0, 0x563C, 0, 0x4F70, 0x3A6A, 0, - 0xA84D, 0x5642, 0xBB45, 0, 0x5643, 0x563D, 0x3333, 0x563E, - 0x5647, 0x5646, 0x5645, 0x5641, 0, 0xA84F, 0, 0x5640, - 0xA850, 0, 0x5644, 0xBB47, 0xA851, 0, 0xA852, 0x4F71, - 0, 0x4A78, 0, 0xA84E, 0, 0, 0, 0, - 0, 0xA853, 0, 0, 0xBB4C, 0, 0, 0, - 0, 0xA854, 0, 0, 0, 0xBB4E, 0, 0xBB4F, -}; -static const unsigned short utf8_to_euc_E5B5[] = { - 0, 0, 0xBB50, 0xBB51, 0, 0, 0xBB52, 0, - 0xBB53, 0, 0xBB57, 0x564B, 0x5648, 0, 0x564A, 0, - 0x4D72, 0xBB55, 0x5649, 0xF43C, 0, 0xBB54, 0, 0, - 0, 0xBB56, 0, 0, 0x563F, 0, 0, 0xBB58, - 0xBB59, 0xBB5A, 0xBB5B, 0, 0xBB5C, 0, 0, 0, - 0, 0x3F73, 0xBB5D, 0, 0x564C, 0xBB5E, 0, 0x3A37, - 0xBB5F, 0, 0, 0x564D, 0, 0, 0x564E, 0, - 0, 0xBB60, 0xBB61, 0, 0, 0, 0xBB62, 0xBB63, -}; -static const unsigned short utf8_to_euc_E5B5_x0213[] = { - 0, 0, 0xA855, 0xBB51, 0, 0, 0x4F73, 0x4F74, - 0xBB53, 0, 0x4F76, 0x564B, 0x5648, 0, 0x564A, 0, - 0x4D72, 0xBB55, 0x5649, 0x4F75, 0, 0xBB54, 0, 0, - 0, 0xBB56, 0, 0, 0x563F, 0, 0, 0xBB58, - 0xBB59, 0xA857, 0xBB5B, 0, 0xBB5C, 0, 0, 0, - 0, 0x3F73, 0xA858, 0, 0x564C, 0x4F77, 0, 0x3A37, - 0xA85A, 0, 0, 0x564D, 0, 0, 0x564E, 0, - 0, 0xBB60, 0xBB61, 0, 0, 0, 0xBB62, 0xBB63, -}; -static const unsigned short utf8_to_euc_E5B6[] = { - 0, 0xBB64, 0x5651, 0xBB65, 0x5650, 0, 0, 0x564F, - 0xBB66, 0, 0xBB67, 0x4568, 0x563A, 0, 0, 0, - 0x5657, 0, 0xBB68, 0xBB69, 0xBB6A, 0xBB6B, 0, 0, - 0, 0xBB6C, 0, 0xBB6D, 0, 0x5653, 0, 0xBB6E, - 0xBB6F, 0, 0x5652, 0, 0, 0, 0, 0xBB70, - 0, 0, 0, 0xBB71, 0x5654, 0, 0x5655, 0, - 0xBB72, 0, 0xE674, 0, 0xBB73, 0, 0, 0x5658, - 0xBB74, 0xBB75, 0x4E66, 0, 0x5659, 0x5656, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B6_x0213[] = { - 0, 0x4F78, 0x5651, 0xBB65, 0x5650, 0, 0, 0x564F, - 0xA85D, 0, 0xBB67, 0x4568, 0x563A, 0, 0, 0, - 0x5657, 0, 0xA85F, 0xBB69, 0xA860, 0xBB6B, 0, 0xA861, - 0, 0xA862, 0, 0xBB6D, 0, 0x5653, 0, 0xBB6E, - 0x4F79, 0, 0x5652, 0, 0x4F7A, 0, 0, 0x4F7B, - 0, 0, 0, 0xBB71, 0x5654, 0, 0x5655, 0, - 0xA863, 0, 0xA864, 0, 0xA865, 0, 0, 0x5658, - 0x4F7C, 0xA867, 0x4E66, 0, 0x5659, 0x5656, 0, 0, -}; -static const unsigned short utf8_to_euc_E5B7[] = { - 0, 0, 0, 0xBB76, 0, 0, 0, 0xBB77, - 0, 0x565A, 0, 0xBB78, 0x3460, 0x565B, 0xBB7A, 0, - 0xBB79, 0, 0x565D, 0x565C, 0, 0, 0x565E, 0, - 0xBB7B, 0xBB7C, 0, 0x565F, 0, 0x406E, 0x3D23, 0, - 0xBB7D, 0x3D64, 0, 0x4163, 0xBB7E, 0x3929, 0x3A38, 0x392A, - 0x3570, 0xBC21, 0, 0x5660, 0, 0, 0x3A39, 0, - 0, 0x384A, 0x5661, 0x4C26, 0x4743, 0x5662, 0, 0x392B, - 0xBC22, 0xBC23, 0, 0x342C, 0, 0x4327, 0x3652, 0, -}; -static const unsigned short utf8_to_euc_E5B7_x0213[] = { - 0, 0, 0, 0xBB76, 0, 0, 0, 0xBB77, - 0, 0x565A, 0, 0x4F7D, 0x3460, 0x565B, 0xBB7A, 0, - 0, 0xA868, 0x565D, 0x565C, 0, 0, 0x565E, 0xA869, - 0xA86A, 0xBB7C, 0, 0x565F, 0, 0x406E, 0x3D23, 0, - 0xA86B, 0x3D64, 0x7428, 0x4163, 0xA86D, 0x3929, 0x3A38, 0x392A, - 0x3570, 0xA86E, 0, 0x5660, 0, 0, 0x3A39, 0, - 0, 0x384A, 0x5661, 0x4C26, 0x4743, 0x5662, 0, 0x392B, - 0xBC22, 0xBC23, 0, 0x342C, 0, 0x4327, 0x3652, 0, -}; -static const unsigned short utf8_to_euc_E5B8[] = { - 0xBC24, 0, 0x3B54, 0x495B, 0, 0, 0x4841, 0xBC25, - 0, 0, 0, 0x5663, 0x3475, 0xBC26, 0, 0, - 0, 0x5666, 0xBC27, 0, 0xBC28, 0xBC29, 0x4421, 0, - 0xBC2A, 0x5665, 0x5664, 0x5667, 0, 0x446B, 0, 0xBC2B, - 0xBC2C, 0, 0, 0, 0, 0x3F63, 0, 0, - 0xBC2E, 0, 0, 0x3B55, 0, 0x404A, 0xBC2D, 0x4253, - 0x3522, 0, 0xBC2F, 0x4422, 0, 0xBC30, 0x5668, 0x5669, - 0x3E6F, 0, 0, 0, 0, 0x4B39, 0xBC31, 0, -}; -static const unsigned short utf8_to_euc_E5B8_x0213[] = { - 0xA870, 0, 0x3B54, 0x495B, 0, 0, 0x4841, 0xBC25, - 0, 0, 0, 0x5663, 0x3475, 0xBC26, 0, 0, - 0, 0x5666, 0xA872, 0, 0x7429, 0xA873, 0x4421, 0, - 0x742A, 0x5665, 0x5664, 0x5667, 0, 0x446B, 0, 0xA875, - 0xBC2C, 0, 0, 0, 0, 0x3F63, 0, 0, - 0xBC2E, 0, 0, 0x3B55, 0, 0x404A, 0xA876, 0x4253, - 0x3522, 0, 0xBC2F, 0x4422, 0, 0xBC30, 0x5668, 0x5669, - 0x3E6F, 0, 0, 0, 0, 0x4B39, 0xA877, 0, -}; -static const unsigned short utf8_to_euc_E5B9[] = { - 0x566C, 0, 0, 0x566B, 0x566A, 0x497D, 0, 0x5673, - 0, 0xBC34, 0, 0xBC32, 0x4B5A, 0, 0x566D, 0, - 0xBC33, 0xBC35, 0, 0, 0x566F, 0x4B6B, 0xBC36, 0x566E, - 0xBC37, 0, 0, 0xBC38, 0xBC39, 0, 0xBC3A, 0x5670, - 0, 0x4828, 0x5671, 0x4A3E, 0x5672, 0, 0, 0, - 0xBC3B, 0, 0xBC3C, 0xBC3D, 0xBC3E, 0xBC3F, 0xBC40, 0, - 0xBC41, 0, 0x3433, 0x4A3F, 0x472F, 0x5674, 0x5675, 0, - 0x392C, 0x3434, 0x5676, 0x3838, 0x4D44, 0x4D29, 0x3476, 0x5678, -}; -static const unsigned short utf8_to_euc_E5B9_x0213[] = { - 0x566C, 0, 0, 0x566B, 0x566A, 0x497D, 0, 0x5673, - 0, 0xA878, 0, 0xBC32, 0x4B5A, 0, 0x566D, 0, - 0xBC33, 0xBC35, 0, 0, 0x566F, 0x4B6B, 0xA87A, 0x566E, - 0x742B, 0, 0, 0xBC38, 0xBC39, 0, 0x742C, 0x5670, - 0, 0x4828, 0x5671, 0x4A3E, 0x5672, 0, 0, 0, - 0xBC3B, 0, 0xBC3C, 0xA87C, 0xA87D, 0xA87E, 0xAC21, 0, - 0xBC41, 0, 0x3433, 0x4A3F, 0x472F, 0x5674, 0x5675, 0x7E7C, - 0x392C, 0x3434, 0x5676, 0x3838, 0x4D44, 0x4D29, 0x3476, 0x5678, -}; -static const unsigned short utf8_to_euc_E5BA[] = { - 0xBC42, 0x4423, 0, 0x392D, 0x3E31, 0, 0, 0x485F, - 0, 0, 0x3E32, 0xBC43, 0, 0, 0xBC44, 0x3D78, - 0, 0, 0, 0, 0, 0x446C, 0x4A79, 0x4539, - 0, 0, 0x392E, 0, 0x495C, 0, 0, 0, - 0x5679, 0, 0xBC45, 0, 0xBC46, 0xBC47, 0x4559, 0x3A42, - 0xBC48, 0, 0xBC49, 0x384B, 0xBC4A, 0x446D, 0, 0, - 0, 0xBC4B, 0, 0xBC4C, 0, 0x3043, 0x3D6E, 0x392F, - 0x4D47, 0, 0, 0, 0, 0xBC4D, 0xBC4E, 0xBC4F, -}; -static const unsigned short utf8_to_euc_E5BA_x0213[] = { - 0xBC42, 0x4423, 0, 0x392D, 0x3E31, 0, 0, 0x485F, - 0, 0, 0x3E32, 0xBC43, 0, 0, 0xBC44, 0x3D78, - 0, 0, 0, 0, 0, 0x446C, 0x4A79, 0x4539, - 0, 0, 0x392E, 0, 0x495C, 0, 0, 0, - 0x5679, 0, 0xBC45, 0, 0xBC46, 0xAC23, 0x4559, 0x3A42, - 0xBC48, 0, 0xAC24, 0x384B, 0xAC25, 0x446D, 0, 0, - 0, 0xBC4B, 0, 0xBC4C, 0, 0x3043, 0x3D6E, 0x392F, - 0x4D47, 0xAC26, 0, 0, 0, 0xBC4D, 0x742D, 0xAC27, -}; -static const unsigned short utf8_to_euc_E5BB[] = { - 0, 0x567A, 0x567B, 0x4751, 0, 0, 0xBC50, 0, - 0x567C, 0x4E77, 0x4F2D, 0xBC52, 0xBC51, 0, 0xBC53, 0x567E, - 0x567D, 0xBC54, 0xBC55, 0x3347, 0xBC56, 0xBC57, 0x5721, 0, - 0, 0, 0x5724, 0x5725, 0xBC58, 0x5723, 0xBC59, 0x4940, - 0x3E33, 0x5727, 0x5726, 0x5722, 0, 0xBC5A, 0, 0, - 0x5728, 0x5729, 0, 0xBC5B, 0x572A, 0, 0, 0, - 0x572D, 0x572B, 0, 0x572C, 0x572E, 0, 0x3164, 0x446E, - 0x572F, 0, 0x377A, 0x3276, 0x4736, 0, 0x5730, 0x467B, -}; -static const unsigned short utf8_to_euc_E5BB_x0213[] = { - 0, 0x567A, 0x567B, 0x4751, 0, 0, 0xAC28, 0, - 0x567C, 0x4E77, 0x4F2D, 0x742F, 0xBC51, 0, 0xBC53, 0x567E, - 0x567D, 0xBC54, 0xAC29, 0x3347, 0xBC56, 0xBC57, 0x5721, 0, - 0, 0xAC2A, 0x5724, 0x5725, 0xBC58, 0x5723, 0xBC59, 0x4940, - 0x3E33, 0x5727, 0x5726, 0x5722, 0, 0xBC5A, 0, 0, - 0x5728, 0x5729, 0, 0xBC5B, 0x572A, 0, 0, 0, - 0x572D, 0x572B, 0, 0x572C, 0x572E, 0, 0x3164, 0x446E, - 0x572F, 0x7430, 0x377A, 0x3276, 0x4736, 0xAC2C, 0x5730, 0x467B, -}; -static const unsigned short utf8_to_euc_E5BC[] = { - 0, 0x4A5B, 0xBC5C, 0x5731, 0x4F2E, 0, 0xBC5D, 0xBC5E, - 0xBC5F, 0x5732, 0x4A40, 0x5735, 0x5021, 0x5031, 0xBC60, 0x3C30, - 0x4675, 0x5736, 0, 0x355D, 0x4424, 0x307A, 0x5737, 0x4A26, - 0x3930, 0xBC61, 0, 0x4350, 0xBC62, 0xBC63, 0, 0x446F, - 0, 0xBC64, 0xBC65, 0xBC66, 0xBC67, 0x4C6F, 0x3839, 0x384C, - 0xBC68, 0x5738, 0, 0xBC69, 0xBC6A, 0x5739, 0xBC6B, 0x573F, - 0xBC6C, 0x3C65, 0, 0, 0xBC6D, 0x4425, 0xBC6E, 0x362F, - 0x573A, 0, 0, 0xBC6F, 0x492B, 0xBC70, 0x4346, 0xBC71, -}; -static const unsigned short utf8_to_euc_E5BC_x0213[] = { - 0x7431, 0x4A5B, 0x7432, 0x5731, 0x4F2E, 0, 0xBC5D, 0x7433, - 0xAC2D, 0x5732, 0x4A40, 0x5735, 0x5021, 0x5031, 0xAC2E, 0x3C30, - 0x4675, 0x5736, 0, 0x355D, 0x4424, 0x307A, 0x5737, 0x4A26, - 0x3930, 0xBC61, 0, 0x4350, 0xAC2F, 0x7434, 0xAC31, 0x446F, - 0, 0, 0xBC65, 0x7435, 0xBC67, 0x4C6F, 0x3839, 0x384C, - 0xBC68, 0x5738, 0, 0xBC69, 0xBC6A, 0x5739, 0xBC6B, 0x573F, - 0xBC6C, 0x3C65, 0, 0, 0x7436, 0x4425, 0x7437, 0x362F, - 0x573A, 0, 0, 0xBC6F, 0x492B, 0x7438, 0x4346, 0xBC71, -}; -static const unsigned short utf8_to_euc_E5BD[] = { - 0xBC72, 0x573B, 0, 0, 0xBC73, 0xBC74, 0, 0xBC75, - 0x573C, 0, 0x3630, 0, 0x573D, 0xBC76, 0x573E, 0, - 0xBC77, 0x5740, 0, 0x4576, 0xBC78, 0, 0x5741, 0x5742, - 0xBC79, 0x5743, 0, 0xBC7A, 0x5734, 0x5733, 0, 0, - 0xBC7B, 0x5744, 0x3741, 0xBC7C, 0xBC7D, 0, 0x4927, 0xBC7E, - 0, 0x3A4C, 0x4937, 0x4426, 0x494B, 0x5745, 0, 0xBD21, - 0x3E34, 0x3146, 0xBD22, 0x5746, 0xBD23, 0xBD24, 0, 0x5747, - 0xBD25, 0x4C72, 0xBD26, 0, 0x4860, 0xBD27, 0xBD28, 0x574A, -}; -static const unsigned short utf8_to_euc_E5BD_x0213[] = { - 0x7439, 0x573B, 0, 0, 0xBC73, 0x743A, 0, 0xAC32, - 0x573C, 0, 0x3630, 0, 0x573D, 0xBC76, 0x573E, 0, - 0xBC77, 0x5740, 0, 0x4576, 0x743B, 0, 0x5741, 0x5742, - 0x743C, 0x5743, 0, 0xBC7A, 0x5734, 0x5733, 0, 0, - 0xBC7B, 0x5744, 0x3741, 0xAC33, 0x743D, 0, 0x4927, 0x743E, - 0, 0x3A4C, 0x4937, 0x4426, 0x494B, 0x5745, 0, 0xBD21, - 0x3E34, 0x3146, 0xAC34, 0x5746, 0xBD23, 0xBD24, 0, 0x5747, - 0xBD25, 0x4C72, 0xBD26, 0, 0x4860, 0x743F, 0xAC35, 0x574A, -}; -static const unsigned short utf8_to_euc_E5BE[] = { - 0x317D, 0x402C, 0x5749, 0x5748, 0x3742, 0x4254, 0, 0x574E, - 0x574C, 0xBD29, 0x574B, 0x4E27, 0x3865, 0xBD2A, 0, 0xBD2B, - 0x3D79, 0x574D, 0x454C, 0x3D3E, 0, 0, 0xBD2C, 0x4640, - 0x5751, 0x5750, 0, 0, 0xBD2D, 0xBD2E, 0x574F, 0, - 0x5752, 0x3866, 0xBD2F, 0, 0xBD32, 0, 0, 0xBD30, - 0x5753, 0x497C, 0x3D5B, 0xBD31, 0xBD33, 0x5754, 0x4879, 0xBD34, - 0xBD35, 0xBD36, 0, 0x4641, 0x4427, 0, 0, 0xF43E, - 0xBD37, 0x4530, 0, 0, 0x5755, 0x352B, 0, 0, -}; -static const unsigned short utf8_to_euc_E5BE_x0213[] = { - 0x317D, 0x402C, 0x5749, 0x5748, 0x3742, 0x4254, 0, 0x574E, - 0x574C, 0x7440, 0x574B, 0x4E27, 0x3865, 0xBD2A, 0, 0xAC36, - 0x3D79, 0x574D, 0x454C, 0x3D3E, 0, 0, 0xBD2C, 0x4640, - 0x5751, 0x5750, 0, 0, 0x7441, 0xBD2E, 0x574F, 0, - 0x5752, 0x3866, 0xAC37, 0, 0xAC38, 0, 0, 0x7442, - 0x5753, 0x497C, 0x3D5B, 0xBD31, 0xBD33, 0x5754, 0x4879, 0x7443, - 0xBD35, 0xBD36, 0, 0x4641, 0x4427, 0x7444, 0, 0x7445, - 0xAC39, 0x4530, 0, 0, 0x5755, 0x352B, 0, 0, -}; -static const unsigned short utf8_to_euc_E5BF[] = { - 0, 0, 0, 0x3F34, 0xBD38, 0x492C, 0, 0xBD39, - 0xBD3A, 0xBD3B, 0, 0xBD3C, 0x3477, 0x4726, 0, 0, - 0xBD3D, 0xBD3E, 0xBD3F, 0xBD40, 0xBD41, 0, 0x5756, 0x3B56, - 0x4B3A, 0x4B3B, 0, 0, 0x317E, 0x575B, 0xBD42, 0, - 0x4369, 0xBD43, 0xBD44, 0, 0x5758, 0, 0, 0, - 0xBD45, 0xBD46, 0xBD47, 0x3277, 0xBD48, 0xBD49, 0xBD4A, 0xBD4B, - 0x582D, 0x575A, 0xBD4C, 0xBD4D, 0, 0x4730, 0xBD4E, 0, - 0x5759, 0, 0xBD4F, 0x5757, 0xBD50, 0x397A, 0, 0x575D, -}; -static const unsigned short utf8_to_euc_E5BF_x0213[] = { - 0, 0, 0, 0x3F34, 0xAC3A, 0x492C, 0, 0xAC3C, - 0xBD3A, 0x7446, 0, 0xAC3D, 0x3477, 0x4726, 0, 0, - 0xBD3D, 0xBD3E, 0xAC3E, 0xAC3F, 0xAC40, 0, 0x5756, 0x3B56, - 0x4B3A, 0x4B3B, 0, 0, 0x317E, 0x575B, 0x7447, 0, - 0x4369, 0x7448, 0xAC41, 0, 0x5758, 0, 0, 0, - 0xBD45, 0x7449, 0xBD47, 0x3277, 0xBD48, 0xBD49, 0xAC42, 0xAC43, - 0x582D, 0x575A, 0xBD4C, 0xAC44, 0, 0x4730, 0xBD4E, 0, - 0x5759, 0, 0xBD4F, 0x5757, 0xAC45, 0x397A, 0, 0x575D, -}; -static const unsigned short utf8_to_euc_E680[] = { - 0, 0, 0, 0, 0, 0, 0, 0xBD51, - 0, 0, 0xBD52, 0, 0, 0xBD53, 0x5763, 0x5769, - 0x5761, 0, 0x455C, 0xBD54, 0xBD55, 0x5766, 0x495D, 0xBD56, - 0xBD57, 0x5760, 0xBD58, 0x5765, 0x4E67, 0x3B57, 0, 0xBD59, - 0x4255, 0x575E, 0, 0, 0xBD5A, 0x355E, 0x5768, 0x402D, - 0x3165, 0x5762, 0x3278, 0x5767, 0, 0xBD5B, 0, 0x3631, - 0, 0x5764, 0, 0xBD5C, 0, 0xBD5D, 0, 0, - 0, 0, 0x576A, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E680_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xBD51, - 0, 0, 0xBD52, 0, 0, 0x744A, 0x5763, 0x5769, - 0x5761, 0, 0x455C, 0xBD54, 0x744B, 0x5766, 0x495D, 0xAC47, - 0x744C, 0x5760, 0xBD58, 0x5765, 0x4E67, 0x3B57, 0, 0xBD59, - 0x4255, 0x575E, 0xAC48, 0, 0xAC49, 0x355E, 0x5768, 0x402D, - 0x3165, 0x5762, 0x3278, 0x5767, 0, 0xBD5B, 0, 0x3631, - 0, 0x5764, 0, 0x744D, 0, 0x744E, 0, 0, - 0, 0, 0x576A, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E681[] = { - 0xBD5E, 0x576C, 0x5776, 0x5774, 0, 0, 0x5771, 0xBD5F, - 0xBD60, 0xBD61, 0x5770, 0x4E78, 0xBD62, 0x5772, 0, 0, - 0x3632, 0xBD63, 0x3931, 0, 0xBD64, 0x3D7A, 0xBD65, 0xBD66, - 0, 0x5779, 0x576B, 0, 0, 0xBD67, 0, 0x576F, - 0x575F, 0xBD68, 0x327A, 0x5773, 0x5775, 0x4351, 0, 0xBD69, - 0x3A28, 0x3238, 0x576D, 0x5778, 0x5777, 0x3633, 0, 0x4229, - 0x3366, 0xBD6A, 0, 0, 0, 0x3743, 0, 0x576E, - 0, 0, 0, 0, 0, 0, 0xBD6B, 0xBD6C, -}; -static const unsigned short utf8_to_euc_E681_x0213[] = { - 0xBD5E, 0x576C, 0x5776, 0x5774, 0, 0, 0x5771, 0x744F, - 0xBD60, 0xBD61, 0x5770, 0x4E78, 0xAC4B, 0x5772, 0, 0, - 0x3632, 0xBD63, 0x3931, 0, 0xBD64, 0x3D7A, 0xBD65, 0xBD66, - 0, 0x5779, 0x576B, 0, 0, 0, 0, 0x576F, - 0x575F, 0xBD68, 0x327A, 0x5773, 0x5775, 0x4351, 0, 0xBD69, - 0x3A28, 0x3238, 0x576D, 0x5778, 0x5777, 0x3633, 0, 0x4229, - 0x3366, 0xBD6A, 0, 0, 0, 0x3743, 0, 0x576E, - 0, 0, 0, 0, 0, 0, 0xBD6B, 0xAC4C, -}; -static const unsigned short utf8_to_euc_E682[] = { - 0, 0x577A, 0xBD6D, 0x577D, 0x5821, 0xF43F, 0xBD6E, 0, - 0xBD6F, 0x3C3D, 0xBD70, 0x5827, 0x4470, 0x577B, 0xBD71, 0, - 0, 0xBD72, 0x5825, 0xBD73, 0x3279, 0xBD74, 0x5823, 0x5824, - 0xBD75, 0, 0x577E, 0x5822, 0, 0xBD76, 0xBD77, 0x3867, - 0x4D2A, 0, 0xBD78, 0x3435, 0xBD79, 0xBD7A, 0x3159, 0x5826, - 0xBD7B, 0x473A, 0x302D, 0, 0, 0, 0, 0, - 0xBD7C, 0xBD7D, 0x4861, 0x575C, 0x582C, 0x5830, 0x4C65, 0xBD7E, - 0x5829, 0, 0, 0xBE21, 0x4569, 0x582E, 0xBE22, 0, -}; -static const unsigned short utf8_to_euc_E682_x0213[] = { - 0, 0x577A, 0xBD6D, 0x577D, 0x5821, 0, 0xBD6E, 0, - 0xBD6F, 0x3C3D, 0xAC4D, 0x5827, 0x4470, 0x577B, 0xBD71, 0, - 0, 0xBD72, 0x5825, 0xBD73, 0x3279, 0xAC4E, 0x5823, 0x5824, - 0xBD75, 0, 0x577E, 0x5822, 0, 0x7451, 0x7452, 0x3867, - 0x4D2A, 0, 0xBD78, 0x3435, 0xBD79, 0xBD7A, 0x3159, 0x5826, - 0xAC4F, 0x473A, 0x302D, 0, 0, 0, 0, 0, - 0xAC51, 0xAC52, 0x4861, 0x575C, 0x582C, 0x5830, 0x4C65, 0xBD7E, - 0x5829, 0, 0, 0xBE21, 0x4569, 0x582E, 0xAC53, 0, -}; -static const unsigned short utf8_to_euc_E683[] = { - 0, 0, 0xBE23, 0, 0xBE24, 0x3E70, 0x582F, 0x4657, - 0xBE25, 0xBE26, 0xBE27, 0xBE28, 0, 0, 0xBE29, 0xBE2A, - 0, 0x4F47, 0, 0x582B, 0xBE2B, 0xBE2C, 0, 0, - 0x5831, 0xBE2D, 0x397B, 0xBE2E, 0x404B, 0xBE2F, 0xBE30, 0x3054, - 0x582A, 0x5828, 0xBE31, 0x415A, 0, 0xBE32, 0, 0x577C, - 0x3B34, 0, 0, 0, 0, 0, 0, 0, - 0x4246, 0x583D, 0xBE33, 0x415B, 0x5838, 0xBE34, 0x5835, 0x5836, - 0xBE35, 0x3C66, 0x5839, 0x583C, 0xBE36, 0xBE37, 0, 0, -}; -static const unsigned short utf8_to_euc_E683_x0213[] = { - 0, 0, 0xBE23, 0, 0xBE24, 0x3E70, 0x582F, 0x4657, - 0xAC54, 0xBE26, 0xBE27, 0x7453, 0, 0, 0xBE29, 0xBE2A, - 0, 0x4F47, 0, 0x582B, 0x7454, 0x7455, 0, 0, - 0x5831, 0xAC55, 0x397B, 0xAC56, 0x404B, 0x7456, 0, 0x3054, - 0x582A, 0x5828, 0xBE31, 0x415A, 0, 0xBE32, 0, 0x577C, - 0x3B34, 0, 0, 0, 0, 0, 0xAC57, 0, - 0x4246, 0x583D, 0xAC58, 0x415B, 0x5838, 0xAC59, 0x5835, 0x5836, - 0x7457, 0x3C66, 0x5839, 0x583C, 0xBE36, 0xBE37, 0, 0, -}; -static const unsigned short utf8_to_euc_E684[] = { - 0x5837, 0x3D25, 0xBE38, 0x583A, 0, 0, 0x5834, 0xBE39, - 0x4C7C, 0x4C7B, 0xBE3A, 0, 0xBE3B, 0x583E, 0x583F, 0x3055, - 0xBE3C, 0xBE3D, 0xBE3E, 0xBE3F, 0xBE40, 0x5833, 0xBE41, 0xBE42, - 0, 0xBE43, 0x3672, 0x3026, 0xBE44, 0, 0xBE45, 0x3436, - 0xF440, 0x583B, 0xBE46, 0, 0, 0, 0, 0x5843, - 0x5842, 0, 0xBE47, 0xBE48, 0x5847, 0, 0, 0, - 0xBE49, 0xBE4A, 0, 0, 0x5848, 0xBE4B, 0xBE4C, 0xBE4D, - 0, 0xBE4E, 0, 0, 0x5846, 0x5849, 0x5841, 0x5845, -}; -static const unsigned short utf8_to_euc_E684_x0213[] = { - 0x5837, 0x3D25, 0xBE38, 0x583A, 0, 0, 0x5834, 0xBE39, - 0x4C7C, 0x4C7B, 0xBE3A, 0, 0xBE3B, 0x583E, 0x583F, 0x3055, - 0xAC5A, 0, 0xAC5B, 0xAC5C, 0xBE40, 0x5833, 0xBE41, 0xBE42, - 0, 0xAC5D, 0x3672, 0x3026, 0x7458, 0, 0xAC5E, 0x3436, - 0, 0x583B, 0xBE46, 0, 0, 0, 0, 0x5843, - 0x5842, 0, 0xBE47, 0x7459, 0x5847, 0, 0, 0, - 0x745A, 0xBE4A, 0, 0, 0x5848, 0xBE4B, 0xBE4C, 0x745B, - 0, 0xBE4E, 0xAC5F, 0, 0x5846, 0x5849, 0x5841, 0x5845, -}; -static const unsigned short utf8_to_euc_E685[] = { - 0, 0xBE4F, 0x584A, 0, 0x584B, 0xBE50, 0xBE51, 0x5840, - 0x3B7C, 0xBE52, 0x5844, 0x4256, 0x3932, 0x5832, 0x3F35, 0, - 0, 0, 0, 0x5858, 0, 0x4A69, 0, 0, - 0x584E, 0x584F, 0x5850, 0, 0, 0x5857, 0xBE53, 0x5856, - 0xBE54, 0, 0x4B7D, 0x3437, 0, 0x5854, 0, 0x3745, - 0x3334, 0, 0, 0x5851, 0xBE55, 0, 0x4E38, 0x5853, - 0x3056, 0x5855, 0xBE56, 0x584C, 0x5852, 0x5859, 0x3744, 0x584D, - 0xBE57, 0, 0, 0xBE58, 0xBE59, 0, 0x4D5D, 0xBE5A, -}; -static const unsigned short utf8_to_euc_E685_x0213[] = { - 0, 0xAC61, 0x584A, 0, 0x584B, 0xBE50, 0xAC62, 0x5840, - 0x3B7C, 0xBE52, 0x5844, 0x4256, 0x3932, 0x5832, 0x3F35, 0, - 0, 0, 0, 0x5858, 0, 0x4A69, 0, 0, - 0x584E, 0x584F, 0x5850, 0, 0, 0x5857, 0xBE53, 0x5856, - 0xAC63, 0, 0x4B7D, 0x3437, 0, 0x5854, 0, 0x3745, - 0x3334, 0, 0, 0x5851, 0xBE55, 0, 0x4E38, 0x5853, - 0x3056, 0x5855, 0xBE56, 0x584C, 0x5852, 0x5859, 0x3744, 0x584D, - 0xBE57, 0, 0, 0xBE58, 0xAC64, 0, 0x4D5D, 0xBE5A, -}; -static const unsigned short utf8_to_euc_E686[] = { - 0xBE5B, 0xBE5C, 0x4D2B, 0xBE5D, 0xBE5E, 0, 0, 0x585C, - 0, 0, 0x5860, 0xBE5F, 0, 0xBE60, 0x417E, 0, - 0x4E79, 0x5861, 0xBE61, 0xBE62, 0x585E, 0, 0x585B, 0xBE63, - 0xBE64, 0x585A, 0x585F, 0, 0xBE65, 0xBE66, 0, 0xBE67, - 0xBE68, 0, 0, 0, 0x4A30, 0xBE69, 0, 0x4634, - 0xBE6A, 0x3746, 0xBE6B, 0x5862, 0x585D, 0xBE6C, 0x5863, 0, - 0, 0, 0x377B, 0, 0, 0, 0x3231, 0, - 0xBE6D, 0xBE6E, 0x586B, 0, 0xBE6F, 0, 0x3438, 0, -}; -static const unsigned short utf8_to_euc_E686_x0213[] = { - 0xBE5B, 0xBE5C, 0x4D2B, 0xBE5D, 0xBE5E, 0, 0, 0x585C, - 0, 0, 0x5860, 0xBE5F, 0, 0x745D, 0x417E, 0, - 0x4E79, 0x5861, 0xAC66, 0xAC67, 0x585E, 0, 0x585B, 0xAC68, - 0xAC69, 0x585A, 0x585F, 0, 0xBE65, 0xBE66, 0, 0xBE67, - 0xBE68, 0, 0, 0, 0x4A30, 0xAC6A, 0, 0x4634, - 0xAC6B, 0x3746, 0xBE6B, 0x5862, 0x585D, 0xAC6C, 0x5863, 0, - 0, 0, 0x377B, 0, 0, 0, 0x3231, 0, - 0xBE6D, 0x7460, 0x586B, 0, 0x745F, 0, 0x3438, 0, -}; -static const unsigned short utf8_to_euc_E687[] = { - 0xBE70, 0xBE71, 0xBE72, 0x5869, 0, 0, 0x586A, 0x3A29, - 0x5868, 0x5866, 0x5865, 0x586C, 0x5864, 0x586E, 0xBE73, 0xBE74, - 0x327B, 0, 0, 0, 0, 0xBE75, 0, 0, - 0, 0, 0, 0, 0xBE76, 0xBE77, 0xBE78, 0xBE79, - 0, 0xBE7A, 0xBE7B, 0x5870, 0, 0xBE7E, 0x586F, 0xBE7C, - 0, 0xBE7D, 0, 0, 0xBF21, 0xBF22, 0, 0xBF23, - 0, 0, 0x4428, 0, 0x5873, 0, 0x5871, 0x5867, - 0x377C, 0, 0x5872, 0, 0x5876, 0x5875, 0x5877, 0x5874, -}; -static const unsigned short utf8_to_euc_E687_x0213[] = { - 0xBE70, 0xBE71, 0xBE72, 0x5869, 0, 0, 0x586A, 0x3A29, - 0x5868, 0x5866, 0x5865, 0x586C, 0x5864, 0x586E, 0xBE73, 0xBE74, - 0x327B, 0, 0, 0, 0, 0xAC6E, 0, 0, - 0, 0, 0, 0, 0xBE76, 0xAC6F, 0xBE78, 0xAC70, - 0, 0xBE7A, 0xBE7B, 0x5870, 0, 0xBE7E, 0x586F, 0xBE7C, - 0, 0xBE7D, 0, 0, 0xBF21, 0xBF22, 0, 0xBF23, - 0, 0, 0x4428, 0, 0x5873, 0xAC71, 0x5871, 0x5867, - 0x377C, 0, 0x5872, 0, 0x5876, 0x5875, 0x5877, 0x5874, -}; -static const unsigned short utf8_to_euc_E688[] = { - 0x5878, 0xBF24, 0, 0xBF25, 0xBF26, 0, 0, 0xBF27, - 0x5879, 0x587A, 0x4A6A, 0, 0x587C, 0x587B, 0x3D3F, 0, - 0x402E, 0x3266, 0x327C, 0xBF28, 0x587D, 0xBF29, 0x303F, 0, - 0, 0, 0x404C, 0x587E, 0xBF2A, 0x6C43, 0x5921, 0x3761, - 0xBF2B, 0x5922, 0xBF2C, 0xBF2D, 0, 0, 0x406F, 0xBF2E, - 0, 0xBF2F, 0x5923, 0xBF30, 0, 0, 0x5924, 0x353A, - 0x5925, 0, 0x5926, 0x5927, 0x4257, 0, 0, 0, - 0x384D, 0xBF31, 0, 0x4C61, 0, 0xBF32, 0, 0x4B3C, -}; -static const unsigned short utf8_to_euc_E688_x0213[] = { - 0x5878, 0xBF24, 0, 0xBF25, 0xBF26, 0, 0, 0xBF27, - 0x5879, 0x587A, 0x4A6A, 0, 0x587C, 0x587B, 0x3D3F, 0, - 0x402E, 0x3266, 0x327C, 0, 0x587D, 0xAC73, 0x303F, 0, - 0, 0, 0x404C, 0x587E, 0xBF2A, 0x6C43, 0x5921, 0x3761, - 0xBF2B, 0x5922, 0x7462, 0xAC74, 0, 0, 0x406F, 0xBF2E, - 0, 0xAC75, 0x5923, 0xBF30, 0, 0, 0x5924, 0x353A, - 0x5925, 0, 0x5926, 0x5927, 0x4257, 0, 0, 0, - 0x384D, 0xBF31, 0, 0x4C61, 0, 0xBF32, 0x7463, 0x4B3C, -}; -static const unsigned short utf8_to_euc_E689[] = { - 0x3D6A, 0x5928, 0xBF33, 0xBF34, 0xBF35, 0, 0xBF36, 0x4070, - 0x6E3D, 0x4862, 0, 0x3C6A, 0xBF37, 0x3A4D, 0x5929, 0, - 0xBF38, 0xBF39, 0xBF3A, 0x4247, 0xBF3B, 0x4A27, 0xBF3C, 0, - 0x4271, 0, 0xBF3D, 0x592C, 0xBF3E, 0, 0x592A, 0, - 0x592D, 0, 0, 0x592B, 0xBF3F, 0, 0, 0, - 0x592E, 0, 0, 0, 0, 0xBF40, 0x4A31, 0xBF41, - 0, 0x3037, 0, 0xBF42, 0, 0, 0x495E, 0, - 0, 0x4863, 0xBF43, 0, 0x592F, 0xBF44, 0x5932, 0x3E35, -}; -static const unsigned short utf8_to_euc_E689_x0213[] = { - 0x3D6A, 0x5928, 0xBF33, 0x7464, 0xBF35, 0, 0xAC76, 0x4070, - 0x6E3D, 0x4862, 0, 0x3C6A, 0xAC77, 0x3A4D, 0x5929, 0, - 0xBF38, 0xAC78, 0xAC79, 0x4247, 0xBF3B, 0x4A27, 0x7465, 0, - 0x4271, 0, 0x7466, 0x592C, 0xBF3E, 0, 0x592A, 0, - 0x592D, 0xAC7A, 0, 0x592B, 0xAC7B, 0, 0, 0, - 0x592E, 0, 0, 0, 0, 0xAC7D, 0x4A31, 0x7467, - 0, 0x3037, 0, 0xAC7E, 0, 0, 0x495E, 0, - 0, 0x4863, 0xBF43, 0xAC7C, 0x592F, 0xBF44, 0x5932, 0x3E35, -}; -static const unsigned short utf8_to_euc_E68A[] = { - 0x353B, 0, 0x5930, 0x5937, 0x3E36, 0, 0, 0, - 0, 0x5931, 0x4744, 0, 0, 0xBF45, 0xBF46, 0xBF47, - 0xBF48, 0x4D5E, 0x5933, 0x5934, 0x5938, 0x456A, 0x5935, 0x3933, - 0x405E, 0, 0, 0x5946, 0x4834, 0, 0x4272, 0, - 0, 0, 0, 0, 0, 0, 0xBF49, 0, - 0xBF4A, 0, 0, 0x4864, 0x5A2D, 0, 0, 0, - 0, 0x4A7A, 0, 0xBF4B, 0, 0x4471, 0xBF4C, 0xBF4D, - 0, 0x4B75, 0xBF4E, 0x593B, 0x3221, 0x436A, 0xBF4F, 0xBF50, -}; -static const unsigned short utf8_to_euc_E68A_x0213[] = { - 0x353B, 0, 0x5930, 0x5937, 0x3E36, 0x7468, 0, 0, - 0, 0x5931, 0x4744, 0, 0, 0xBF45, 0xBF46, 0xBF47, - 0xBF48, 0x4D5E, 0x5933, 0x5934, 0x5938, 0x456A, 0x5935, 0x3933, - 0x405E, 0xAD21, 0, 0x5946, 0x4834, 0, 0x4272, 0, - 0, 0, 0, 0, 0, 0, 0xAD22, 0, - 0xBF4A, 0, 0, 0x4864, 0x5A2D, 0, 0, 0, - 0, 0x4A7A, 0, 0xBF4B, 0, 0x4471, 0xBF4C, 0xBF4D, - 0, 0x4B75, 0xBF4E, 0x593B, 0x3221, 0x436A, 0xBF4F, 0xBF50, -}; -static const unsigned short utf8_to_euc_E68B[] = { - 0, 0, 0x5944, 0, 0xBF51, 0x4334, 0x593E, 0x5945, - 0x5940, 0x5947, 0x5943, 0, 0x5942, 0x476F, 0xBF52, 0x593C, - 0x327D, 0x593A, 0x3571, 0x4273, 0x5936, 0xBF53, 0xBF54, 0x5939, - 0x3934, 0x405B, 0xBF55, 0x3E37, 0x5941, 0x4752, 0, 0, - 0x3572, 0x3348, 0, 0, 0, 0, 0, 0, - 0, 0, 0xBF56, 0, 0x3367, 0x3F21, 0x5949, 0x594E, - 0, 0x594A, 0xBF57, 0x377D, 0xBF58, 0x594F, 0x3B22, 0x3969, - 0, 0, 0, 0, 0xBF59, 0xBF5A, 0x3D26, 0x593D, -}; -static const unsigned short utf8_to_euc_E68B_x0213[] = { - 0, 0, 0x5944, 0, 0x7469, 0x4334, 0x593E, 0x5945, - 0x5940, 0x5947, 0x5943, 0, 0x5942, 0x476F, 0xBF52, 0x593C, - 0x327D, 0x593A, 0x3571, 0x4273, 0x5936, 0xAD23, 0x746A, 0x5939, - 0x3934, 0x405B, 0xBF55, 0x3E37, 0x5941, 0x4752, 0, 0, - 0x3572, 0x3348, 0, 0, 0, 0, 0, 0, - 0, 0, 0xBF56, 0, 0x3367, 0x3F21, 0x5949, 0x594E, - 0, 0x594A, 0xBF57, 0x377D, 0xBF58, 0x594F, 0x3B22, 0x3969, - 0, 0, 0, 0, 0x746B, 0xAD25, 0x3D26, 0x593D, -}; -static const unsigned short utf8_to_euc_E68C[] = { - 0, 0x3B7D, 0x594C, 0xBF5B, 0xBF5C, 0, 0, 0x3B58, - 0x594D, 0x3044, 0xBF5D, 0xBF5E, 0x5948, 0xBF5F, 0, 0, - 0xBF60, 0x4429, 0, 0xBF61, 0, 0, 0xBF62, 0, - 0xBF63, 0x3573, 0, 0, 0, 0, 0, 0x3634, - 0, 0, 0, 0, 0, 0, 0, 0x594B, - 0x3027, 0xBF64, 0xBF65, 0x3A43, 0, 0xBF66, 0, 0x3F36, - 0, 0, 0, 0, 0, 0xBF67, 0xBF68, 0, - 0, 0xBF69, 0x4472, 0, 0xBF6A, 0x4854, 0x5951, 0x415E, -}; -static const unsigned short utf8_to_euc_E68C_x0213[] = { - 0, 0x3B7D, 0x594C, 0xAD26, 0xBF5C, 0, 0, 0x3B58, - 0x594D, 0x3044, 0x746C, 0xBF5E, 0x5948, 0xAD27, 0, 0, - 0xAD28, 0x4429, 0, 0xBF61, 0, 0, 0xBF62, 0, - 0x746D, 0x3573, 0, 0, 0, 0, 0, 0x3634, - 0, 0, 0, 0, 0, 0, 0, 0x594B, - 0x3027, 0xBF64, 0xBF65, 0x3A43, 0, 0xBF66, 0, 0x3F36, - 0, 0, 0xAD2B, 0, 0, 0xAD2C, 0xBF68, 0, - 0, 0x746E, 0x4472, 0xAD2D, 0xAD2E, 0x4854, 0x5951, 0x415E, -}; -static const unsigned short utf8_to_euc_E68D[] = { - 0, 0xBF6B, 0xBF6C, 0xBF6D, 0xBF6E, 0, 0xBF6F, 0, - 0, 0x422A, 0xBF70, 0xBF71, 0x3B2B, 0x5952, 0xBF72, 0x5954, - 0x5950, 0, 0xBF73, 0xBF74, 0xBF75, 0x4A61, 0, 0x443D, - 0xBF76, 0, 0, 0xBF77, 0x415C, 0, 0, 0, - 0, 0, 0, 0, 0, 0xBF78, 0xBF79, 0x4A7B, - 0x3C4E, 0x5960, 0, 0x595F, 0xBF7A, 0xBF7B, 0x3F78, 0, - 0, 0xBF7C, 0x377E, 0, 0xBF7D, 0xBF7E, 0x5959, 0x3E39, - 0xC021, 0, 0x4668, 0x4731, 0xC022, 0xC023, 0, 0xC024, -}; -static const unsigned short utf8_to_euc_E68D_x0213[] = { - 0, 0xAD2F, 0xBF6C, 0x746F, 0xAD30, 0, 0xBF6F, 0, - 0, 0x422A, 0xBF70, 0xBF71, 0x3B2B, 0x5952, 0xAD31, 0x5954, - 0x5950, 0, 0xBF73, 0xBF74, 0xBF75, 0x4A61, 0, 0x443D, - 0xBF76, 0xAD33, 0, 0xBF77, 0x415C, 0, 0, 0, - 0, 0, 0, 0, 0, 0x7470, 0xBF79, 0x4A7B, - 0x3C4E, 0x5960, 0, 0x595F, 0xAD36, 0xBF7B, 0x3F78, 0, - 0, 0xBF7C, 0x377E, 0, 0xBF7D, 0xBF7E, 0x5959, 0x3E39, - 0xC021, 0, 0x4668, 0x4731, 0x7471, 0xC023, 0, 0xC024, -}; -static const unsigned short utf8_to_euc_E68E[] = { - 0x5957, 0, 0xC025, 0x415D, 0xC026, 0, 0, 0xC027, - 0x3C78, 0x595C, 0xC028, 0, 0x3E38, 0, 0x5956, 0x595B, - 0xC029, 0, 0x4753, 0, 0xC02A, 0xC02B, 0x5955, 0, - 0x3721, 0xC02C, 0xC02D, 0x335D, 0, 0, 0xC02E, 0x595D, - 0x4E2B, 0x3A4E, 0x4335, 0x595A, 0xC02F, 0x405C, 0xC030, 0x3935, - 0x3F64, 0x3166, 0x413C, 0x5958, 0x3545, 0xC031, 0xC032, 0xC033, - 0, 0, 0x3747, 0, 0x444F, 0x595E, 0, 0, - 0, 0, 0, 0x415F, 0, 0xC034, 0x5961, 0, -}; -static const unsigned short utf8_to_euc_E68E_x0213[] = { - 0x5957, 0, 0xC025, 0x415D, 0xAD37, 0, 0, 0xC027, - 0x3C78, 0x595C, 0xC028, 0, 0x3E38, 0, 0x5956, 0x595B, - 0xC029, 0, 0x4753, 0, 0xAD3A, 0xC02B, 0x5955, 0, - 0x3721, 0xAD38, 0xC02D, 0x335D, 0, 0, 0xC02E, 0x595D, - 0x4E2B, 0x3A4E, 0x4335, 0x595A, 0xC02F, 0x405C, 0xC030, 0x3935, - 0x3F64, 0x3166, 0x413C, 0x5958, 0x3545, 0xC031, 0xC032, 0xC033, - 0, 0, 0x3747, 0, 0x444F, 0x595E, 0, 0, - 0, 0, 0, 0x415F, 0, 0xAD3B, 0x5961, 0, -}; -static const unsigned short utf8_to_euc_E68F[] = { - 0x5963, 0xC035, 0, 0x4237, 0x5969, 0xC036, 0x5964, 0, - 0xC037, 0x5966, 0, 0, 0, 0, 0xC038, 0x4941, - 0x4473, 0xC039, 0x5967, 0xC03A, 0xC03B, 0xC03C, 0x4D2C, 0, - 0, 0, 0x4D48, 0x3439, 0xC03D, 0, 0, 0, - 0xC03E, 0x302E, 0, 0x5965, 0, 0xC03F, 0, 0, - 0, 0x5962, 0xC040, 0, 0xC041, 0, 0x3478, 0, - 0, 0, 0xC042, 0xC043, 0x3167, 0xC044, 0x5968, 0, - 0xC045, 0xC046, 0x4D49, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E68F_x0213[] = { - 0x5963, 0xC035, 0, 0x4237, 0x5969, 0xC036, 0x5964, 0, - 0xC037, 0x5966, 0, 0, 0, 0, 0xC038, 0x4941, - 0x4473, 0xC039, 0x5967, 0xC03A, 0xAD3D, 0xAD3E, 0x4D2C, 0, - 0, 0, 0x4D48, 0x3439, 0xAD3F, 0, 0, 0, - 0xAD40, 0x302E, 0, 0x5965, 0, 0x7472, 0, 0, - 0, 0x5962, 0xC040, 0xAD41, 0xAD42, 0x7473, 0x3478, 0, - 0, 0, 0xAD43, 0xC043, 0x3167, 0x7474, 0x5968, 0xAD3C, - 0xC045, 0xC046, 0x4D49, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E690[] = { - 0, 0, 0, 0, 0, 0, 0x596C, 0, - 0, 0xC047, 0xC048, 0, 0, 0x423B, 0, 0x5973, - 0xC049, 0, 0xC04A, 0x596D, 0xC04B, 0, 0x596A, 0x5971, - 0xC04C, 0, 0, 0, 0x5953, 0, 0xC04D, 0, - 0xC04E, 0, 0xC04F, 0, 0xC050, 0xC051, 0x596E, 0, - 0x5972, 0xC052, 0xC053, 0, 0x4842, 0x456B, 0, 0xC054, - 0xC055, 0, 0, 0, 0x596B, 0xC056, 0x596F, 0, - 0, 0, 0x3748, 0, 0, 0xC057, 0x3A71, 0xC058, -}; -static const unsigned short utf8_to_euc_E690_x0213[] = { - 0, 0, 0, 0, 0, 0, 0x596C, 0, - 0, 0xAD44, 0xC048, 0, 0, 0x423B, 0, 0x5973, - 0x7475, 0, 0xC04A, 0x596D, 0x7476, 0, 0x596A, 0x5971, - 0xC04C, 0, 0, 0, 0x5953, 0, 0xAD45, 0, - 0xC04E, 0, 0x7477, 0, 0xC050, 0xAD46, 0x596E, 0, - 0x5972, 0xAD47, 0xC053, 0, 0x4842, 0x456B, 0, 0xAD48, - 0xC055, 0, 0, 0, 0x596B, 0xC056, 0x596F, 0, - 0, 0, 0x3748, 0, 0, 0xC057, 0x3A71, 0xC058, -}; -static const unsigned short utf8_to_euc_E691[] = { - 0, 0, 0x405D, 0, 0, 0, 0, 0, - 0, 0, 0, 0xC059, 0, 0, 0x5977, 0xC05A, - 0, 0xC05B, 0xC05C, 0xC05D, 0xC05E, 0, 0, 0, - 0x4526, 0, 0xC05F, 0xC060, 0xC061, 0xC062, 0, 0xC063, - 0xC064, 0xC065, 0, 0xC066, 0, 0, 0, 0x5974, - 0, 0x4B60, 0, 0, 0, 0xC067, 0, 0x5975, - 0, 0, 0, 0xC068, 0xC069, 0, 0x5976, 0, - 0x4C4E, 0, 0x4022, 0xC06A, 0, 0xC06B, 0, 0, -}; -static const unsigned short utf8_to_euc_E691_x0213[] = { - 0, 0, 0x405D, 0, 0, 0, 0, 0, - 0, 0, 0, 0xC059, 0, 0, 0x5977, 0xC05A, - 0, 0x7479, 0xC05C, 0xC05D, 0xC05E, 0, 0, 0, - 0x4526, 0, 0xAD49, 0xAD4A, 0xC061, 0xAD4B, 0, 0xC063, - 0x747A, 0xC065, 0, 0xC066, 0, 0, 0, 0x5974, - 0, 0x4B60, 0, 0, 0, 0x747B, 0, 0x5975, - 0, 0, 0, 0xAD4C, 0xC069, 0, 0x5976, 0, - 0x4C4E, 0x7478, 0x4022, 0xC06A, 0, 0xAD4D, 0, 0, -}; -static const unsigned short utf8_to_euc_E692[] = { - 0, 0, 0, 0x3762, 0, 0xC06C, 0, 0xC06D, - 0x597D, 0, 0, 0, 0, 0, 0, 0xC06E, - 0xC06F, 0xC070, 0x3B35, 0x597A, 0, 0x5979, 0, 0, - 0xC071, 0xC072, 0x4732, 0xC073, 0, 0xC074, 0x4635, 0xC075, - 0, 0xC076, 0, 0xC077, 0x4531, 0x597B, 0xC078, 0, - 0xC079, 0x597C, 0, 0x496F, 0xC07A, 0x4745, 0x3B23, 0, - 0x4071, 0, 0x4B50, 0xC07B, 0, 0, 0, 0, - 0, 0x3349, 0, 0x5A25, 0x597E, 0xC07C, 0xC07D, 0xC07E, -}; -static const unsigned short utf8_to_euc_E692_x0213[] = { - 0, 0, 0, 0x3762, 0, 0xC06C, 0, 0xAD4E, - 0x597D, 0, 0, 0, 0, 0, 0, 0xC06E, - 0xC06F, 0xAD4F, 0x3B35, 0x597A, 0, 0x5979, 0, 0, - 0xC071, 0xC072, 0x4732, 0xC073, 0, 0xAD50, 0x4635, 0xAD51, - 0, 0xC076, 0, 0xC077, 0x4531, 0x597B, 0xC078, 0, - 0xC079, 0x597C, 0, 0x496F, 0xC07A, 0x4745, 0x3B23, 0, - 0x4071, 0, 0x4B50, 0xC07B, 0, 0, 0, 0, - 0, 0x3349, 0, 0x5A25, 0x597E, 0xC07C, 0x747D, 0x747E, -}; -static const unsigned short utf8_to_euc_E693[] = { - 0, 0x4D4A, 0x5A27, 0, 0xC121, 0x5A23, 0, 0x5A24, - 0, 0xC122, 0xC123, 0xC124, 0xC125, 0x4160, 0xC126, 0, - 0xC127, 0xC128, 0x5A22, 0, 0x593F, 0xC129, 0, 0xC12A, - 0x5A26, 0, 0x5A21, 0, 0, 0, 0, 0, - 0x5A2B, 0x5A2C, 0x4527, 0x5A2E, 0xC12B, 0xC12C, 0x3B24, 0x5A29, - 0, 0xC12D, 0xC12E, 0, 0x353C, 0xC12F, 0, 0x5A2F, - 0xC130, 0x5A28, 0x5A33, 0, 0x5A32, 0xC131, 0x5A31, 0xC132, - 0, 0, 0x5A34, 0xC133, 0, 0x5A36, 0x3E71, 0xC134, -}; -static const unsigned short utf8_to_euc_E693_x0213[] = { - 0, 0x4D4A, 0x5A27, 0, 0x7521, 0x5A23, 0, 0x5A24, - 0, 0xC122, 0x7522, 0xAD52, 0xAD53, 0x4160, 0x747C, 0, - 0x7523, 0xC128, 0x5A22, 0, 0x593F, 0xAD54, 0, 0xAD55, - 0x5A26, 0, 0x5A21, 0, 0, 0, 0, 0, - 0x5A2B, 0x5A2C, 0x4527, 0x5A2E, 0xAD57, 0xAD58, 0x3B24, 0x5A29, - 0, 0xC12D, 0xC12E, 0, 0x353C, 0xC12F, 0, 0x5A2F, - 0xC130, 0x5A28, 0x5A33, 0, 0x5A32, 0xC131, 0x5A31, 0x7524, - 0, 0, 0x5A34, 0x7525, 0, 0x5A36, 0x3E71, 0xAD59, -}; -static const unsigned short utf8_to_euc_E694[] = { - 0x5A35, 0xC135, 0, 0, 0xC136, 0x5A39, 0, 0, - 0xC137, 0xC138, 0xC139, 0, 0, 0, 0, 0xC13A, - 0, 0, 0, 0xC13B, 0xC13C, 0, 0xC13D, 0, - 0x5A37, 0xC13E, 0, 0xC13F, 0x5A38, 0x5970, 0xC140, 0xC141, - 0, 0, 0xC142, 0x5A3B, 0x5A3A, 0, 0xC143, 0, - 0, 0xC144, 0x5978, 0x5A3C, 0x5A30, 0, 0xC145, 0x3B59, - 0, 0xC146, 0, 0, 0x5A3D, 0x5A3E, 0x5A40, 0x5A3F, - 0x5A41, 0x327E, 0xC147, 0x3936, 0xC148, 0xC149, 0x4A7C, 0x402F, -}; -static const unsigned short utf8_to_euc_E694_x0213[] = { - 0x5A35, 0xC135, 0, 0, 0xAD5A, 0x5A39, 0, 0, - 0xC137, 0xC138, 0xC139, 0, 0, 0, 0, 0xAD5C, - 0, 0, 0, 0xC13B, 0xAD5D, 0, 0xAD5E, 0, - 0x5A37, 0xC13E, 0, 0xC13F, 0x5A38, 0x5970, 0xAD60, 0xC141, - 0, 0, 0x7526, 0x5A3B, 0x5A3A, 0, 0xC143, 0, - 0, 0x7527, 0x5978, 0x5A3C, 0x5A30, 0, 0xC145, 0x3B59, - 0, 0xC146, 0xAD61, 0, 0x5A3D, 0x5A3E, 0x5A40, 0x5A3F, - 0x5A41, 0x327E, 0xC147, 0x3936, 0xC148, 0xC149, 0x4A7C, 0x402F, -}; -static const unsigned short utf8_to_euc_E695[] = { - 0, 0, 0, 0xC14A, 0, 0x384E, 0, 0xC14B, - 0x5A43, 0xC14C, 0, 0, 0, 0x5A46, 0xF441, 0x4952, - 0xC14D, 0x355F, 0xC14E, 0, 0xC14F, 0x5A45, 0x5A44, 0x4754, - 0x5A47, 0x3635, 0, 0, 0, 0x5A49, 0x5A48, 0xC150, - 0xC151, 0, 0x343A, 0x3B36, 0, 0, 0x4658, 0xC152, - 0, 0, 0, 0xC153, 0x3749, 0, 0, 0, - 0x3F74, 0, 0x5A4A, 0, 0x4030, 0x4528, 0, 0x495F, - 0x5A4B, 0, 0xC154, 0, 0, 0xC155, 0, 0, -}; -static const unsigned short utf8_to_euc_E695_x0213[] = { - 0, 0, 0, 0xC14A, 0xAD62, 0x384E, 0, 0xC14B, - 0x5A43, 0xC14C, 0, 0, 0, 0x5A46, 0, 0x4952, - 0xC14D, 0x355F, 0xC14E, 0, 0xAD63, 0x5A45, 0x5A44, 0x4754, - 0x5A47, 0x3635, 0, 0, 0, 0x5A49, 0x5A48, 0xC150, - 0xC151, 0, 0x343A, 0x3B36, 0, 0, 0x4658, 0x7529, - 0, 0, 0, 0xAD64, 0x3749, 0, 0, 0, - 0x3F74, 0, 0x5A4A, 0, 0x4030, 0x4528, 0, 0x495F, - 0x5A4B, 0, 0xAD65, 0, 0, 0xC155, 0, 0, -}; -static const unsigned short utf8_to_euc_E696[] = { - 0, 0xC156, 0x5A4C, 0x5A4D, 0, 0xC157, 0, 0x4A38, - 0x555D, 0x4046, 0xC158, 0, 0x494C, 0, 0x3A58, 0, - 0x4865, 0x4843, 0xC159, 0, 0, 0xC15A, 0, 0x454D, - 0xC15B, 0x4E41, 0, 0x5A4F, 0x3C50, 0xC15C, 0, 0x5A50, - 0xC15D, 0x3036, 0, 0xC15E, 0x3654, 0x404D, 0xC15F, 0x4960, - 0, 0, 0, 0x5A51, 0x3B42, 0x4347, 0xC160, 0x3B5B, - 0x3F37, 0, 0xC161, 0xC162, 0xC163, 0, 0, 0x5A52, - 0, 0x4A7D, 0, 0, 0x3177, 0x3B5C, 0, 0xC164, -}; -static const unsigned short utf8_to_euc_E696_x0213[] = { - 0, 0xAD66, 0x5A4C, 0x5A4D, 0xAD67, 0xAD68, 0, 0x4A38, - 0x555D, 0x4046, 0xAD69, 0, 0x494C, 0, 0x3A58, 0, - 0x4865, 0x4843, 0xC159, 0, 0, 0xC15A, 0, 0x454D, - 0xC15B, 0x4E41, 0, 0x5A4F, 0x3C50, 0x752A, 0, 0x5A50, - 0xC15D, 0x3036, 0, 0xC15E, 0x3654, 0x404D, 0xC15F, 0x4960, - 0, 0, 0, 0x5A51, 0x3B42, 0x4347, 0xC160, 0x3B5B, - 0x3F37, 0, 0xAD6A, 0xC162, 0xC163, 0xAD6B, 0, 0x5A52, - 0xAD6C, 0x4A7D, 0, 0, 0x3177, 0x3B5C, 0, 0xAD6D, -}; -static const unsigned short utf8_to_euc_E697[] = { - 0, 0x5A55, 0xC165, 0x5A53, 0x5A56, 0x4E39, 0x5A54, 0, - 0xC166, 0xC167, 0, 0x407B, 0x5A57, 0, 0xC168, 0x4232, - 0xC169, 0, 0x5A58, 0, 0xC16A, 0, 0xC16B, 0x347A, - 0xC16C, 0x5A5A, 0, 0x5A59, 0, 0, 0, 0xC16D, - 0x5A5B, 0x5A5C, 0x347B, 0, 0, 0x467C, 0x4336, 0x356C, - 0x3B5D, 0x4161, 0, 0, 0x3D5C, 0x3030, 0, 0, - 0xC16E, 0x5A5D, 0xC16F, 0, 0xC170, 0xC171, 0, 0, - 0, 0xC172, 0x3222, 0x5A61, 0, 0, 0xC173, 0xC174, -}; -static const unsigned short utf8_to_euc_E697_x0213[] = { - 0, 0x5A55, 0xAD6E, 0x5A53, 0x5A56, 0x4E39, 0x5A54, 0, - 0xC166, 0xAD6F, 0, 0x407B, 0x5A57, 0, 0xC168, 0x4232, - 0xC169, 0, 0x5A58, 0, 0xAD70, 0, 0xC16B, 0x347A, - 0xC16C, 0x5A5A, 0, 0x5A59, 0, 0, 0, 0xC16D, - 0x5A5B, 0x5A5C, 0x347B, 0, 0, 0x467C, 0x4336, 0x356C, - 0x3B5D, 0x4161, 0, 0, 0x3D5C, 0x3030, 0, 0, - 0xC16E, 0x5A5D, 0xAD72, 0, 0xC170, 0xC171, 0, 0, - 0, 0xAD73, 0x3222, 0x5A61, 0xAD74, 0, 0xC173, 0xC174, -}; -static const unsigned short utf8_to_euc_E698[] = { - 0xC175, 0, 0x3937, 0x5A60, 0xC176, 0, 0x3A2B, 0x3E3A, - 0xC177, 0xC178, 0x5A5F, 0, 0x3E3B, 0xC179, 0x4C40, 0x3A2A, - 0, 0xC17A, 0xC17B, 0x3057, 0x404E, 0xC17C, 0xC17D, 0, - 0, 0, 0, 0, 0x5A66, 0xC17E, 0xC221, 0x4031, - 0x3147, 0xC222, 0xC223, 0xC224, 0xC225, 0x3D55, 0xC226, 0x4B66, - 0x3A72, 0xC227, 0xC228, 0xC229, 0xC22A, 0x3E3C, 0xC22B, 0x4027, - 0xC22C, 0xC22D, 0, 0xC22E, 0x5A65, 0x5A63, 0x5A64, 0xC230, - 0, 0xC22F, 0, 0xF442, 0x436B, 0, 0, 0x5B26, -}; -static const unsigned short utf8_to_euc_E698_x0213[] = { - 0x752C, 0, 0x3937, 0x5A60, 0xAD75, 0, 0x3A2B, 0x3E3A, - 0xAD76, 0x752D, 0x5A5F, 0, 0x3E3B, 0xC179, 0x4C40, 0x3A2A, - 0, 0xC17A, 0xC17B, 0x3057, 0x404E, 0x752E, 0xC17D, 0, - 0, 0, 0, 0, 0x5A66, 0xC17E, 0x752F, 0x4031, - 0x3147, 0xAD77, 0x7531, 0xC224, 0x7532, 0x3D55, 0xC226, 0x4B66, - 0x3A72, 0xC227, 0xAD78, 0x7533, 0xC22A, 0x3E3C, 0, 0x4027, - 0x7534, 0x7535, 0, 0x7536, 0x5A65, 0x5A63, 0x5A64, 0xC230, - 0, 0xC22F, 0x7530, 0, 0x436B, 0, 0, 0x5B26, -}; -static const unsigned short utf8_to_euc_E699[] = { - 0xC231, 0x5A6A, 0x3B7E, 0x3938, 0x5A68, 0xC232, 0xC233, 0, - 0, 0x5A69, 0xC234, 0x3F38, 0xC235, 0, 0xC237, 0x5A67, - 0, 0xC236, 0x3B2F, 0, 0, 0, 0, 0xC238, - 0xC239, 0xC23A, 0, 0xC23B, 0xC23C, 0x5A6C, 0x5A6B, 0x5A70, - 0xC23D, 0xC23E, 0x5A71, 0, 0x5A6D, 0xF443, 0x3322, 0x5A6E, - 0x5A6F, 0x4855, 0xC240, 0xC241, 0xC242, 0, 0x4961, 0x374A, - 0x5A72, 0, 0, 0xC244, 0x4032, 0xC245, 0x3E3D, 0xC247, - 0xC248, 0xC249, 0x4352, 0xC24A, 0xC24C, 0, 0xC243, 0xC246, -}; -static const unsigned short utf8_to_euc_E699_x0213[] = { - 0xC231, 0x5A6A, 0x3B7E, 0x3938, 0x5A68, 0xAD79, 0xC233, 0, - 0x7538, 0x5A69, 0xC234, 0x3F38, 0x7539, 0, 0xAD7B, 0x5A67, - 0, 0xAD7A, 0x3B2F, 0, 0, 0, 0, 0xAD7E, - 0xC239, 0x753B, 0x753C, 0xAE21, 0xC23C, 0x5A6C, 0x5A6B, 0x5A70, - 0xC23D, 0x753D, 0x5A71, 0xAE22, 0x5A6D, 0x753E, 0x3322, 0x5A6E, - 0x5A6F, 0x4855, 0xAE25, 0xAE26, 0xAE27, 0xAE28, 0x4961, 0x374A, - 0x5A72, 0, 0, 0x753F, 0x4032, 0xC245, 0x3E3D, 0x7540, - 0x7541, 0xC249, 0x4352, 0xAE29, 0xC24C, 0, 0xC243, 0xC246, -}; -static const unsigned short utf8_to_euc_E69A[] = { - 0xC24B, 0x3647, 0, 0x5A73, 0x5A77, 0, 0, 0x324B, - 0x5A74, 0x5A76, 0, 0xC24D, 0xC24E, 0xC24F, 0x5A75, 0, - 0xC250, 0x3D6B, 0xC251, 0, 0, 0, 0x4348, 0x3045, - 0x5A78, 0xC252, 0xC253, 0xC254, 0xC255, 0x5A79, 0, 0xC256, - 0xC257, 0, 0x442A, 0, 0xC258, 0, 0x4E71, 0, - 0, 0, 0, 0x3B43, 0, 0xC259, 0x4A6B, 0, - 0, 0xC25A, 0xC25B, 0, 0x4B3D, 0xC25C, 0, 0, - 0x5B22, 0x5A7B, 0, 0xC25D, 0x5A7E, 0, 0x5A7D, 0xC25E, -}; -static const unsigned short utf8_to_euc_E69A_x0213[] = { - 0xAE2A, 0x3647, 0, 0x5A73, 0x5A77, 0, 0, 0x324B, - 0x5A74, 0x5A76, 0, 0xC24D, 0xC24E, 0x7542, 0x5A75, 0, - 0xAE2B, 0x3D6B, 0xAE2C, 0, 0, 0, 0x4348, 0x3045, - 0x5A78, 0xAE2D, 0xC253, 0xC254, 0xC255, 0x5A79, 0, 0xC256, - 0x7544, 0, 0x442A, 0, 0xC258, 0, 0x4E71, 0, - 0, 0, 0, 0x3B43, 0, 0xAE2F, 0x4A6B, 0, - 0, 0xAE30, 0x7545, 0, 0x4B3D, 0xAE31, 0, 0, - 0x5B22, 0x5A7B, 0, 0x7546, 0x5A7E, 0, 0x5A7D, 0xAE33, -}; -static const unsigned short utf8_to_euc_E69B[] = { - 0xC25F, 0x5A7A, 0xC260, 0xC261, 0x5B21, 0, 0, 0x465E, - 0xC262, 0x5A7C, 0, 0, 0xC263, 0, 0xC264, 0xC265, - 0, 0, 0, 0, 0xC266, 0, 0x5B23, 0, - 0, 0x3D6C, 0x5B24, 0xC267, 0x4D4B, 0x4778, 0, 0xC268, - 0x5B25, 0, 0, 0, 0, 0, 0x5B27, 0, - 0xC269, 0x5B28, 0, 0xC26A, 0xC26B, 0, 0xC26C, 0, - 0x5B29, 0, 0x364A, 0x3148, 0x3939, 0x5B2A, 0, 0x5B2B, - 0x3D71, 0x4162, 0xC26D, 0xC23F, 0x5258, 0x413E, 0x413D, 0x4258, -}; -static const unsigned short utf8_to_euc_E69B_x0213[] = { - 0xC25F, 0x5A7A, 0xC260, 0xC261, 0x5B21, 0, 0x7547, 0x465E, - 0x7548, 0x5A7C, 0, 0, 0xC263, 0, 0xC264, 0xC265, - 0, 0, 0, 0, 0xC266, 0, 0x5B23, 0, - 0, 0x3D6C, 0x5B24, 0x754A, 0x4D4B, 0x4778, 0, 0xC268, - 0x5B25, 0, 0, 0, 0, 0, 0x5B27, 0, - 0x754B, 0x5B28, 0, 0xC26A, 0xAE35, 0, 0xC26C, 0, - 0x5B29, 0, 0x364A, 0x3148, 0x3939, 0x5B2A, 0, 0x5B2B, - 0x3D71, 0x4162, 0x754C, 0x7537, 0x5258, 0x413E, 0x413D, 0x4258, -}; -static const unsigned short utf8_to_euc_E69C[] = { - 0x3A47, 0, 0, 0x5072, 0, 0xC26E, 0, 0xC26F, - 0x376E, 0x4D2D, 0, 0x4A7E, 0, 0x497E, 0xC270, 0x5B2C, - 0, 0, 0, 0xC271, 0x3A73, 0x443F, 0x5B2D, 0x4F2F, - 0, 0xC272, 0, 0x4B3E, 0xC273, 0x442B, 0x5B2E, 0x347C, - 0xC274, 0, 0xC275, 0, 0, 0, 0x5B2F, 0x5B30, - 0x4C5A, 0, 0x4C24, 0x4B76, 0x4B5C, 0x3B25, 0x5B32, 0, - 0, 0x3C6B, 0, 0xC276, 0x4B51, 0, 0x5B34, 0x5B37, - 0x5B36, 0, 0x3479, 0, 0, 0x3560, 0xC277, 0x5B33, -}; -static const unsigned short utf8_to_euc_E69C_x0213[] = { - 0x3A47, 0xAE37, 0, 0x5072, 0, 0xAE38, 0, 0xC26F, - 0x376E, 0x4D2D, 0, 0x4A7E, 0, 0x497E, 0, 0x5B2C, - 0, 0, 0xAE39, 0x754D, 0x3A73, 0x443F, 0x5B2D, 0x4F2F, - 0, 0xAE3B, 0, 0x4B3E, 0xC273, 0x442B, 0x5B2E, 0x347C, - 0xC274, 0, 0xC275, 0, 0, 0, 0x5B2F, 0x5B30, - 0x4C5A, 0, 0x4C24, 0x4B76, 0x4B5C, 0x3B25, 0x5B32, 0, - 0, 0x3C6B, 0, 0x754F, 0x4B51, 0, 0x5B34, 0x5B37, - 0x5B36, 0, 0x3479, 0, 0, 0x3560, 0xC277, 0x5B33, -}; -static const unsigned short utf8_to_euc_E69D[] = { - 0, 0x5B35, 0, 0, 0, 0xC278, 0x5B38, 0xC279, - 0xC27A, 0x3F79, 0, 0, 0xC27B, 0, 0x4D7B, 0x3049, - 0x3A60, 0x423C, 0, 0x3C5D, 0xC27C, 0xC27D, 0x3E73, 0, - 0, 0x5B3B, 0, 0, 0x454E, 0xC27E, 0x5B39, 0x422B, - 0x5B3A, 0x3E72, 0x4C5D, 0x5B3C, 0x5B3D, 0x4D68, 0xC321, 0, - 0, 0, 0x5B42, 0, 0xC322, 0x393A, 0xC323, 0x4755, - 0x5B3F, 0x456C, 0x5A5E, 0x5A62, 0xC324, 0x354F, 0xC325, 0x4747, - 0, 0, 0, 0xC326, 0x5B41, 0, 0x3E3E, 0x4844, -}; -static const unsigned short utf8_to_euc_E69D_x0213[] = { - 0, 0x5B35, 0, 0, 0, 0xC278, 0x5B38, 0x7551, - 0x7552, 0x3F79, 0, 0, 0xAE3E, 0xAE3F, 0x4D7B, 0x3049, - 0x3A60, 0x423C, 0, 0x3C5D, 0xAE40, 0xC27D, 0x3E73, 0, - 0, 0x5B3B, 0, 0, 0x454E, 0xAE41, 0x5B39, 0x422B, - 0x5B3A, 0x3E72, 0x4C5D, 0x5B3C, 0x5B3D, 0x4D68, 0x7550, 0, - 0, 0, 0x5B42, 0, 0xC322, 0x393A, 0xC323, 0x4755, - 0x5B3F, 0x456C, 0x5A5E, 0x5A62, 0xAE45, 0x354F, 0xAE46, 0x4747, - 0, 0, 0, 0x7553, 0x5B41, 0, 0x3E3E, 0x4844, -}; -static const unsigned short utf8_to_euc_E69E[] = { - 0, 0xC327, 0, 0, 0xC328, 0x5B47, 0, 0x487A, - 0, 0x5B3E, 0, 0x5B44, 0x5B43, 0, 0xC329, 0xC32A, - 0x404F, 0xC32B, 0, 0xC32C, 0, 0x4B6D, 0xC32D, 0x4E53, - 0xC32E, 0xC32F, 0x4B67, 0xC330, 0x324C, 0x3B5E, 0, 0, - 0x4F48, 0x5B46, 0x3F75, 0, 0, 0, 0x5B45, 0, - 0, 0x5B40, 0, 0, 0, 0, 0, 0x384F, - 0xC331, 0xC332, 0xC333, 0x5B4C, 0x5B4A, 0xC334, 0x324D, 0x5B48, - 0x5B4E, 0x5B54, 0, 0xC335, 0xC336, 0xC337, 0, 0, -}; -static const unsigned short utf8_to_euc_E69E_x0213[] = { - 0, 0x7554, 0, 0, 0xC328, 0x5B47, 0, 0x487A, - 0, 0x5B3E, 0, 0x5B44, 0x5B43, 0, 0xC329, 0xC32A, - 0x404F, 0xC32B, 0xAE48, 0x7555, 0, 0x4B6D, 0xC32D, 0x4E53, - 0x7556, 0xC32F, 0x4B67, 0x7557, 0x324C, 0x3B5E, 0, 0, - 0x4F48, 0x5B46, 0x3F75, 0, 0, 0, 0x5B45, 0, - 0, 0x5B40, 0, 0, 0, 0, 0, 0x384F, - 0xAE4C, 0xC332, 0xAE4D, 0x5B4C, 0x5B4A, 0xC334, 0x324D, 0x5B48, - 0x5B4E, 0x5B54, 0, 0x7558, 0xC336, 0xC337, 0, 0, -}; -static const unsigned short utf8_to_euc_E69F[] = { - 0xC339, 0x4248, 0xC33A, 0xC33B, 0x4A41, 0xC33C, 0x5B56, 0, - 0xC33D, 0xC33E, 0x4922, 0, 0, 0, 0x5B55, 0x4770, - 0x4B3F, 0x343B, 0xC33F, 0x4077, 0x3D40, 0, 0, 0xC340, - 0x4453, 0xC341, 0x4D2E, 0, 0xC342, 0x5B51, 0x5B50, 0, - 0, 0xC343, 0x5B52, 0, 0x5B4F, 0, 0xC344, 0x5B57, - 0, 0x5B4D, 0, 0, 0x5B4B, 0, 0x5B53, 0x5B49, - 0xC345, 0x436C, 0xC346, 0x4C78, 0x3C46, 0x3A74, 0xC347, 0xC348, - 0, 0xC338, 0, 0x3A3A, 0, 0, 0x4B6F, 0x3341, -}; -static const unsigned short utf8_to_euc_E69F_x0213[] = { - 0x755A, 0x4248, 0xC33A, 0xAE4E, 0x4A41, 0xC33C, 0x5B56, 0, - 0xAE4F, 0xC33E, 0x4922, 0, 0, 0, 0x5B55, 0x4770, - 0x4B3F, 0x343B, 0xAE50, 0x4077, 0x3D40, 0, 0, 0x755B, - 0x4453, 0xAE51, 0x4D2E, 0xAE52, 0xC342, 0x5B51, 0x5B50, 0, - 0, 0xC343, 0x5B52, 0, 0x5B4F, 0, 0xC344, 0x5B57, - 0, 0x5B4D, 0, 0, 0x5B4B, 0, 0x5B53, 0x5B49, - 0xAE53, 0x436C, 0xC346, 0x4C78, 0x3C46, 0x3A74, 0xC347, 0xAE54, - 0, 0x7559, 0, 0x3A3A, 0x755C, 0, 0x4B6F, 0x3341, -}; -static const unsigned short utf8_to_euc_E6A0[] = { - 0, 0xF446, 0x444E, 0x464A, 0x3149, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x4072, 0xC34A, 0, 0x4034, 0x372A, - 0, 0xC34B, 0, 0, 0, 0xC34C, 0x5B59, 0xC34D, - 0, 0x393B, 0x337C, 0, 0, 0, 0, 0xC34F, - 0xC34E, 0x5B5B, 0x3374, 0x5B61, 0xC350, 0xC351, 0, 0xC352, - 0xC353, 0xC354, 0x5B5E, 0xC355, 0x4073, 0, 0, 0, - 0x334B, 0x3A2C, 0, 0xC356, 0x334A, 0x3A4F, 0, 0xC357, -}; -static const unsigned short utf8_to_euc_E6A0_x0213[] = { - 0, 0x755D, 0x444E, 0x464A, 0x3149, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xAE4B, 0, 0, 0x4072, 0xC34A, 0, 0x4034, 0x372A, - 0xAE58, 0xC34B, 0, 0, 0, 0x755F, 0x5B59, 0xAE59, - 0, 0x393B, 0x337C, 0, 0, 0, 0, 0xC34F, - 0xC34E, 0x5B5B, 0x3374, 0x5B61, 0x7560, 0xAE5A, 0, 0xC352, - 0xC353, 0x7561, 0x5B5E, 0xAE5C, 0x4073, 0, 0, 0, - 0x334B, 0x3A2C, 0, 0xAE5D, 0x334A, 0x3A4F, 0xAE5E, 0xC357, -}; -static const unsigned short utf8_to_euc_E6A1[] = { - 0x5B5C, 0x3765, 0x374B, 0x456D, 0xC358, 0xC359, 0x5B5A, 0, - 0x3046, 0, 0xC35A, 0, 0xC35B, 0x5B5D, 0x5B5F, 0, - 0x364D, 0x372C, 0xC349, 0x343C, 0x354B, 0xC35C, 0, 0xC35D, - 0xC35E, 0x5B62, 0, 0xC35F, 0x3A79, 0x4B71, 0, 0x3B37, - 0, 0, 0, 0x5B63, 0, 0, 0, 0x4930, - 0, 0, 0, 0xC360, 0, 0, 0xC361, 0xC362, - 0xC363, 0xC364, 0xC365, 0, 0x5B6F, 0xC366, 0x3233, 0x5B64, - 0, 0xC367, 0xC368, 0xC369, 0xC36A, 0, 0x5B75, 0x5B65, -}; -static const unsigned short utf8_to_euc_E6A1_x0213[] = { - 0x5B5C, 0x3765, 0x374B, 0x456D, 0xAE5F, 0xAE60, 0x5B5A, 0, - 0x3046, 0xAE61, 0xC35A, 0, 0xAE62, 0x5B5D, 0x5B5F, 0, - 0x364D, 0x372C, 0x755E, 0x343C, 0x354B, 0xAE63, 0, 0xAE64, - 0xC35E, 0x5B62, 0, 0x7562, 0x3A79, 0x4B71, 0, 0x3B37, - 0, 0, 0, 0x5B63, 0, 0, 0, 0x4930, - 0, 0, 0, 0xAE66, 0, 0, 0xAE67, 0xC362, - 0xC363, 0xC364, 0x7563, 0, 0x5B6F, 0x7564, 0x3233, 0x5B64, - 0, 0xC367, 0xAE68, 0xC369, 0xAE69, 0, 0x5B75, 0x5B65, -}; -static const unsigned short utf8_to_euc_E6A2[] = { - 0, 0x4E42, 0xC36B, 0x5B6C, 0xC36C, 0x475F, 0xC36D, 0, - 0xC36E, 0, 0, 0, 0, 0x5B74, 0, 0x5B67, - 0, 0, 0, 0x3034, 0x5B69, 0, 0xC36F, 0x393C, - 0xC370, 0, 0xC371, 0x5B6B, 0xC372, 0x5B6A, 0, 0x5B66, - 0x5B71, 0xC373, 0x3E3F, 0xC374, 0, 0xC375, 0x546D, 0x3868, - 0x4D7C, 0xC376, 0xC377, 0, 0, 0x5B68, 0xC378, 0x4474, - 0x3323, 0x3A2D, 0xC379, 0x5B60, 0, 0x5B70, 0x3361, 0, - 0, 0x5B6E, 0x5B72, 0xC37A, 0x456E, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6A2_x0213[] = { - 0, 0x4E42, 0xAE6A, 0x5B6C, 0xC36C, 0x475F, 0xC36D, 0, - 0xC36E, 0, 0, 0, 0, 0x5B74, 0, 0x5B67, - 0xAE6B, 0, 0, 0x3034, 0x5B69, 0, 0xAE6C, 0x393C, - 0xAE6E, 0xAE6F, 0xAE70, 0x5B6B, 0xAE71, 0x5B6A, 0, 0x5B66, - 0x5B71, 0xC373, 0x3E3F, 0x7566, 0, 0x7567, 0x546D, 0x3868, - 0x4D7C, 0xC376, 0xAE72, 0xAE73, 0, 0x5B68, 0xC378, 0x4474, - 0x3323, 0x3A2D, 0x7568, 0x5B60, 0xAE74, 0x5B70, 0x3361, 0, - 0, 0x5B6E, 0x5B72, 0xAE75, 0x456E, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6A3[] = { - 0, 0, 0, 0, 0x347E, 0xC37B, 0x5C32, 0, - 0xC37C, 0x4C49, 0x5B77, 0x347D, 0xC37D, 0x5B7E, 0, 0xC37E, - 0xC421, 0xC422, 0x4B40, 0xC423, 0x5C21, 0x5C23, 0xC424, 0x5C27, - 0x5B79, 0xC425, 0x432A, 0, 0xC426, 0xC427, 0, 0x456F, - 0x5C2B, 0x5B7C, 0, 0x5C28, 0, 0xC428, 0, 0x5C22, - 0xC429, 0, 0xC42A, 0xC42B, 0xC42C, 0xC42D, 0x3F39, 0x5C2C, - 0xC42E, 0xC42F, 0x4033, 0, 0, 0xC430, 0xC431, 0, - 0, 0x5C2A, 0x343D, 0xC432, 0xC433, 0xC434, 0, 0, -}; -static const unsigned short utf8_to_euc_E6A3_x0213[] = { - 0, 0, 0, 0xAE7A, 0x347E, 0xAE7B, 0x5C32, 0, - 0x7569, 0x4C49, 0x5B77, 0x347D, 0xAE7C, 0x5B7E, 0, 0xAE7D, - 0x756A, 0xC422, 0x4B40, 0xC423, 0x5C21, 0x5C23, 0xAE7E, 0x5C27, - 0x5B79, 0xAF21, 0x432A, 0, 0xC426, 0xC427, 0, 0x456F, - 0x5C2B, 0x5B7C, 0, 0x5C28, 0xAF22, 0xAF23, 0, 0x5C22, - 0x756B, 0, 0xC42A, 0xC42B, 0xAF24, 0x756C, 0x3F39, 0x5C2C, - 0x756D, 0x756E, 0x4033, 0, 0, 0xC430, 0xC431, 0xAF25, - 0, 0x5C2A, 0x343D, 0xAE76, 0x756F, 0xC434, 0, 0, -}; -static const unsigned short utf8_to_euc_E6A4[] = { - 0x4F50, 0x5B76, 0, 0, 0x5C26, 0x3058, 0xC435, 0, - 0x5B78, 0xC436, 0xC437, 0x4C3A, 0x5B7D, 0x3F22, 0x4447, 0x5B73, - 0xC438, 0xC439, 0x5C25, 0xC43A, 0, 0, 0xC43B, 0xC43C, - 0, 0x3F7A, 0x5C2F, 0x3371, 0x3821, 0, 0, 0, - 0, 0x5C31, 0x5B7A, 0x5C30, 0, 0x5C29, 0x5B7B, 0, - 0x5C2D, 0, 0x5C2E, 0, 0, 0, 0, 0, - 0x5C3F, 0xC43D, 0, 0xC43E, 0x464E, 0xC43F, 0x5C24, 0, - 0xC440, 0x5C3B, 0, 0xC441, 0, 0x5C3D, 0, 0x4458, -}; -static const unsigned short utf8_to_euc_E6A4_x0213[] = { - 0x4F50, 0x5B76, 0, 0xAF26, 0x5C26, 0x3058, 0xC435, 0xAF27, - 0x5B78, 0xC436, 0x7570, 0x4C3A, 0x5B7D, 0x3F22, 0x4447, 0x5B73, - 0xC438, 0xC439, 0x5C25, 0xC43A, 0, 0, 0xC43B, 0xC43C, - 0, 0x3F7A, 0x5C2F, 0x3371, 0x3821, 0, 0, 0, - 0, 0x5C31, 0x5B7A, 0x5C30, 0, 0x5C29, 0x5B7B, 0, - 0x5C2D, 0, 0x5C2E, 0, 0, 0, 0, 0, - 0x5C3F, 0xC43D, 0, 0xC43E, 0x464E, 0x7573, 0x5C24, 0, - 0xC440, 0x5C3B, 0, 0xAF2B, 0, 0x5C3D, 0, 0x4458, -}; -static const unsigned short utf8_to_euc_E6A5[] = { - 0, 0, 0xC442, 0, 0, 0xC443, 0, 0, - 0, 0xC444, 0x4D4C, 0, 0, 0, 0xC445, 0, - 0, 0, 0, 0x4976, 0x5C38, 0x424A, 0, 0xC446, - 0, 0x5C3E, 0x413F, 0xC447, 0x5C35, 0x5C42, 0x5C41, 0, - 0x466F, 0x5C40, 0x466A, 0xC448, 0xC449, 0xC44A, 0xC44B, 0, - 0xC44C, 0xC44D, 0x5C44, 0x5C37, 0xC44E, 0x3648, 0x5C3A, 0x3D5D, - 0xC44F, 0xC450, 0xC451, 0x4760, 0x5C3C, 0x364B, 0, 0x5C34, - 0x5C36, 0x5C33, 0xC452, 0xC453, 0x4F30, 0x335A, 0x5C39, 0xC454, -}; -static const unsigned short utf8_to_euc_E6A5_x0213[] = { - 0, 0, 0x7574, 0, 0, 0xC443, 0xAF2D, 0, - 0, 0x7571, 0x4D4C, 0, 0, 0, 0xC445, 0, - 0, 0, 0, 0x4976, 0x5C38, 0x424A, 0, 0x7575, - 0, 0x5C3E, 0x413F, 0xC447, 0x5C35, 0x5C42, 0x5C41, 0, - 0x466F, 0x5C40, 0x466A, 0x7576, 0x7577, 0xC44A, 0xC44B, 0, - 0x7578, 0xAF2E, 0x5C44, 0x5C37, 0xAF2F, 0x3648, 0x5C3A, 0x3D5D, - 0xC44F, 0xC450, 0xAF30, 0x4760, 0x5C3C, 0x364B, 0, 0x5C34, - 0x5C36, 0x5C33, 0xAF31, 0xC453, 0x4F30, 0x335A, 0x5C39, 0xAF32, -}; -static const unsigned short utf8_to_euc_E6A6[] = { - 0xC455, 0x5C43, 0x3335, 0, 0, 0, 0, 0, - 0, 0, 0x3A67, 0, 0, 0xC456, 0x315D, 0, - 0, 0x5C54, 0xC457, 0, 0x4F31, 0x5C57, 0xC458, 0, - 0xC459, 0, 0, 0x3F3A, 0x5C56, 0, 0, 0, - 0x5C55, 0xC45A, 0, 0, 0, 0xC45B, 0xC45C, 0x5C52, - 0xC45D, 0, 0, 0xC45E, 0, 0xC45F, 0x5C46, 0xC460, - 0, 0x5C63, 0x5C45, 0, 0x5C58, 0, 0, 0xC461, - 0xC462, 0, 0xC463, 0x5C50, 0xC464, 0, 0x5C4B, 0x5C48, -}; -static const unsigned short utf8_to_euc_E6A6_x0213[] = { - 0x7579, 0x5C43, 0x3335, 0, 0, 0, 0, 0, - 0, 0, 0x3A67, 0, 0, 0xC456, 0x315D, 0, - 0, 0x5C54, 0xAF33, 0, 0x4F31, 0x5C57, 0xAF35, 0, - 0xAF36, 0, 0, 0x3F3A, 0x5C56, 0, 0, 0, - 0x5C55, 0xC45A, 0, 0, 0, 0x757B, 0xAF37, 0x5C52, - 0xC45D, 0, 0, 0xC45E, 0, 0x757C, 0x5C46, 0xC460, - 0xAF38, 0x5C63, 0x5C45, 0, 0x5C58, 0, 0, 0xAF39, - 0xC462, 0, 0xAF3A, 0x5C50, 0xAF3B, 0, 0x5C4B, 0x5C48, -}; -static const unsigned short utf8_to_euc_E6A7[] = { - 0, 0x5C49, 0, 0x5C51, 0, 0xC465, 0, 0x7422, - 0xC466, 0, 0x5C4E, 0x393D, 0x4448, 0x4164, 0x5C4C, 0, - 0x5C47, 0xC467, 0, 0x5C4A, 0, 0, 0xC468, 0xC469, - 0x4D4D, 0x4B6A, 0, 0, 0, 0x5C4F, 0x5C59, 0, - 0, 0, 0xC46A, 0, 0, 0xC46B, 0, 0x5C61, - 0x5C5A, 0, 0, 0x5C67, 0, 0x5C65, 0xC46C, 0xC46D, - 0, 0xC46E, 0x5C60, 0xC46F, 0, 0xC470, 0, 0, - 0, 0x5C5F, 0, 0x4450, 0, 0x4165, 0xC471, 0x5C5D, -}; -static const unsigned short utf8_to_euc_E6A7_x0213[] = { - 0xAF3C, 0x5C49, 0, 0x5C51, 0, 0xC465, 0, 0x7422, - 0xC466, 0, 0x5C4E, 0x393D, 0x4448, 0x4164, 0x5C4C, 0x757D, - 0x5C47, 0xAF3D, 0, 0x5C4A, 0, 0, 0xAF3E, 0xC469, - 0x4D4D, 0x4B6A, 0, 0, 0, 0x5C4F, 0x5C59, 0, - 0, 0, 0x7622, 0xAF44, 0, 0xC46B, 0, 0x5C61, - 0x5C5A, 0x7623, 0x7624, 0x5C67, 0, 0x5C65, 0xAF45, 0xAF46, - 0, 0xC46E, 0x5C60, 0xAF47, 0xAF49, 0x7625, 0x7626, 0, - 0, 0x5C5F, 0, 0x4450, 0, 0x4165, 0xAF4A, 0x5C5D, -}; -static const unsigned short utf8_to_euc_E6A8[] = { - 0xC472, 0xC473, 0x5C5B, 0xC474, 0, 0x5C62, 0, 0, - 0, 0, 0x5C68, 0x4875, 0x5C6E, 0, 0, 0xC475, - 0, 0xC476, 0x5C69, 0x5C6C, 0x5C66, 0xC477, 0, 0x4374, - 0, 0x4938, 0xC478, 0x5C5C, 0, 0xC479, 0x5C64, 0x3E40, - 0xC47A, 0x4C4F, 0x5C78, 0x5C6B, 0xC47B, 0, 0, 0, - 0xC47C, 0x3822, 0x3223, 0x335F, 0, 0, 0x5C53, 0, - 0xC47D, 0, 0xC47E, 0, 0xC521, 0x3E41, 0x5C70, 0xC522, - 0x5C77, 0x3C79, 0x3372, 0xC523, 0, 0x432E, 0xC524, 0xC525, -}; -static const unsigned short utf8_to_euc_E6A8_x0213[] = { - 0xC472, 0xC473, 0x5C5B, 0xC474, 0, 0x5C62, 0, 0, - 0, 0, 0x5C68, 0x4875, 0x5C6E, 0, 0, 0x7627, - 0, 0xAF4B, 0x5C69, 0x5C6C, 0x5C66, 0x7628, 0, 0x4374, - 0, 0x4938, 0xAF4C, 0x5C5C, 0, 0xAF4D, 0x5C64, 0x3E40, - 0xC47A, 0x4C4F, 0x5C78, 0x5C6B, 0xC47B, 0, 0, 0, - 0xC47C, 0x3822, 0x3223, 0x335F, 0, 0, 0x5C53, 0, - 0xAF41, 0, 0xAF4F, 0xAF50, 0xAF51, 0x3E41, 0x5C70, 0xC522, - 0x5C77, 0x3C79, 0x3372, 0x762A, 0, 0x432E, 0x762B, 0xAF52, -}; -static const unsigned short utf8_to_euc_E6A9[] = { - 0, 0, 0, 0, 0x5C6D, 0xC526, 0xC527, 0x5C72, - 0x5C76, 0xC528, 0xC529, 0x3636, 0, 0, 0xC52A, 0, - 0xC52B, 0xC52C, 0xC52D, 0, 0, 0xC52E, 0xC52F, 0, - 0x354C, 0x5C74, 0, 0xC530, 0, 0, 0, 0x3521, - 0, 0x464B, 0x5C73, 0, 0xC531, 0, 0x5C75, 0xC532, - 0, 0, 0xC533, 0xF449, 0, 0, 0, 0, - 0, 0xC534, 0x5C6F, 0xC535, 0, 0, 0, 0, - 0x5C71, 0, 0, 0, 0, 0, 0xC536, 0x3360, -}; -static const unsigned short utf8_to_euc_E6A9_x0213[] = { - 0, 0, 0, 0, 0x5C6D, 0x762C, 0xAF53, 0x5C72, - 0x5C76, 0xAF54, 0xC529, 0x3636, 0, 0, 0xAF56, 0, - 0x762D, 0xC52C, 0xAF57, 0, 0, 0xC52E, 0x762E, 0, - 0x354C, 0x5C74, 0, 0x762F, 0, 0, 0, 0x3521, - 0, 0x464B, 0x5C73, 0, 0xAF58, 0, 0x5C75, 0xC532, - 0, 0, 0xC533, 0x7630, 0, 0, 0, 0, - 0, 0xC534, 0x5C6F, 0x7631, 0, 0, 0, 0, - 0x5C71, 0, 0xAF55, 0, 0, 0, 0xAF5A, 0x3360, -}; -static const unsigned short utf8_to_euc_E6AA[] = { - 0x4349, 0xC537, 0, 0xC538, 0x5C7C, 0, 0xC539, 0xC53A, - 0, 0xC53B, 0, 0xC53C, 0, 0x5C7A, 0x3869, 0, - 0x5C79, 0xC53D, 0, 0, 0, 0, 0, 0x5D21, - 0, 0, 0, 0xC53E, 0x5B58, 0xC53F, 0xC540, 0xC541, - 0x5C7B, 0, 0x5C7D, 0x5C7E, 0, 0xC542, 0, 0, - 0, 0, 0x5D2C, 0xC543, 0x5D28, 0, 0x5B6D, 0xC544, - 0xC545, 0xC546, 0, 0x5D27, 0xC547, 0, 0, 0, - 0x5D26, 0, 0, 0x5D23, 0, 0xC548, 0xC549, 0xC54A, -}; -static const unsigned short utf8_to_euc_E6AA_x0213[] = { - 0x4349, 0xC537, 0, 0xAF5B, 0x5C7C, 0, 0xC539, 0xC53A, - 0, 0x7633, 0, 0xAF5C, 0, 0x5C7A, 0x3869, 0, - 0x5C79, 0xAF5E, 0, 0, 0x7634, 0, 0, 0x5D21, - 0, 0, 0, 0xC53E, 0x5B58, 0x7635, 0x7636, 0xAF5F, - 0x5C7B, 0xAF60, 0x5C7D, 0x5C7E, 0, 0x7637, 0, 0, - 0, 0, 0x5D2C, 0xAF62, 0x5D28, 0, 0x5B6D, 0xC544, - 0xC545, 0xC546, 0, 0x5D27, 0xC547, 0, 0, 0, - 0x5D26, 0, 0, 0x5D23, 0, 0xAF63, 0xC549, 0xC54A, -}; -static const unsigned short utf8_to_euc_E6AB[] = { - 0, 0x5C6A, 0x5D25, 0x5D24, 0, 0, 0xC54B, 0, - 0xC54D, 0xC54C, 0, 0, 0xC54E, 0, 0, 0, - 0xC54F, 0x5D2A, 0, 0x4F26, 0xC550, 0xC551, 0xC552, 0, - 0, 0, 0x5D2D, 0x367B, 0xC553, 0xC554, 0x5D29, 0x5D2B, - 0, 0, 0xF44A, 0, 0xC555, 0, 0, 0xC556, - 0x4827, 0, 0x5D2E, 0, 0xC557, 0, 0, 0, - 0xC558, 0xC559, 0xC55A, 0, 0, 0, 0, 0, - 0, 0, 0x5D32, 0x5D2F, 0xC55B, 0xC55C, 0, 0, -}; -static const unsigned short utf8_to_euc_E6AB_x0213[] = { - 0, 0x5C6A, 0x5D25, 0x5D24, 0, 0, 0xAF64, 0, - 0xC54D, 0xC54C, 0, 0, 0xC54E, 0, 0, 0, - 0xAF66, 0x5D2A, 0, 0x4F26, 0xAF65, 0xC551, 0xC552, 0, - 0, 0, 0x5D2D, 0x367B, 0xAF67, 0xAF68, 0x5D29, 0x5D2B, - 0, 0, 0, 0, 0x7638, 0, 0, 0x7639, - 0x4827, 0, 0x5D2E, 0, 0xAF6B, 0, 0, 0, - 0xC558, 0xAF6C, 0xAF6D, 0xAF6E, 0, 0, 0, 0, - 0, 0, 0x5D32, 0x5D2F, 0xC55B, 0xAF6F, 0, 0, -}; -static const unsigned short utf8_to_euc_E6AC[] = { - 0, 0, 0xC55D, 0xC55E, 0x4D73, 0x5D30, 0xC55F, 0xC560, - 0, 0xC561, 0x5C5E, 0, 0, 0, 0, 0xC562, - 0xC563, 0xC564, 0x5D33, 0, 0, 0, 0x5D34, 0xC565, - 0, 0, 0, 0xC566, 0, 0x3135, 0xC567, 0x5D36, - 0x3767, 0x3C21, 0, 0x3655, 0xC568, 0, 0, 0x3224, - 0xC569, 0, 0, 0xC56A, 0xC56B, 0, 0, 0xC56C, - 0, 0, 0x4D5F, 0, 0, 0xC56D, 0xC56E, 0x5D38, - 0x5D37, 0x5D3A, 0x353D, 0xC56F, 0, 0x3656, 0x343E, 0xC570, -}; -static const unsigned short utf8_to_euc_E6AC_x0213[] = { - 0, 0, 0xC55D, 0xC55E, 0x4D73, 0x5D30, 0xC55F, 0xC560, - 0, 0xC561, 0x5C5E, 0xAF71, 0, 0, 0, 0xAF72, - 0xAF73, 0xAF74, 0x5D33, 0, 0, 0, 0x5D34, 0xAF76, - 0, 0, 0, 0x763C, 0, 0x3135, 0x763D, 0x5D36, - 0x3767, 0x3C21, 0, 0x3655, 0xC568, 0, 0, 0x3224, - 0xC569, 0, 0, 0xC56A, 0x763E, 0, 0, 0xAF78, - 0, 0, 0x4D5F, 0, 0, 0x763F, 0xC56E, 0x5D38, - 0x5D37, 0x5D3A, 0x353D, 0xC56F, 0, 0x3656, 0x343E, 0xC570, -}; -static const unsigned short utf8_to_euc_E6AD[] = { - 0, 0, 0, 0x5D3D, 0, 0, 0xC571, 0x5D3C, - 0, 0x5D3E, 0xC572, 0, 0x324E, 0xC573, 0x4337, 0, - 0x5D3F, 0, 0xC574, 0x343F, 0x5D41, 0, 0xC575, 0, - 0xC576, 0x5D40, 0, 0x5D42, 0, 0xC577, 0, 0x5D43, - 0xC578, 0x5D44, 0x3B5F, 0x4035, 0x3A21, 0, 0x4970, 0xC579, - 0, 0x4A62, 0x4F44, 0xC57A, 0, 0, 0xC57B, 0x3B75, - 0xC57C, 0, 0, 0x3A50, 0x4E72, 0xC57D, 0, 0, - 0x5D45, 0x5D46, 0, 0x3B60, 0, 0xC57E, 0xC621, 0x5D47, -}; -static const unsigned short utf8_to_euc_E6AD_x0213[] = { - 0, 0, 0, 0x5D3D, 0, 0, 0x7640, 0x5D3C, - 0, 0x5D3E, 0xAF79, 0, 0x324E, 0xC573, 0x4337, 0, - 0x5D3F, 0, 0xC574, 0x343F, 0x5D41, 0, 0x7641, 0, - 0xAF7A, 0x5D40, 0, 0x5D42, 0, 0xC577, 0, 0x5D43, - 0x7642, 0x5D44, 0x3B5F, 0x4035, 0x3A21, 0x7643, 0x4970, 0x7644, - 0, 0x4A62, 0x4F44, 0xC57A, 0xAF7B, 0, 0xC57B, 0x3B75, - 0xC57C, 0, 0, 0x3A50, 0x4E72, 0xAF7C, 0, 0x7645, - 0x5D45, 0x5D46, 0xAF7D, 0x3B60, 0, 0xC57E, 0xC621, 0x5D47, -}; -static const unsigned short utf8_to_euc_E6AE[] = { - 0x5D48, 0, 0xC622, 0x5D4A, 0x5D49, 0xC623, 0x4B58, 0, - 0, 0x3D5E, 0x3C6C, 0x3B44, 0, 0x5D4B, 0, 0, - 0, 0, 0, 0, 0, 0x5D4D, 0x3F23, 0xC624, - 0x5D4C, 0, 0, 0xC625, 0, 0, 0x5D4E, 0xC626, - 0xC627, 0, 0xC628, 0xC629, 0x5D4F, 0, 0, 0, - 0xC62A, 0xC62B, 0x5D50, 0x5D51, 0xC62C, 0xC62D, 0xC62E, 0x5D52, - 0xC62F, 0x5D54, 0x5D53, 0x5D55, 0x3225, 0x434A, 0, 0x5D56, - 0xC630, 0xC631, 0x3B26, 0x334C, 0x5D57, 0xC632, 0xC633, 0x4542, -}; -static const unsigned short utf8_to_euc_E6AE_x0213[] = { - 0x5D48, 0xAF7E, 0x7646, 0x5D4A, 0x5D49, 0xC623, 0x4B58, 0, - 0, 0x3D5E, 0x3C6C, 0x3B44, 0, 0x5D4B, 0, 0, - 0, 0, 0, 0, 0, 0x5D4D, 0x3F23, 0xC624, - 0x5D4C, 0, 0, 0xEE21, 0, 0, 0x5D4E, 0xC626, - 0xC627, 0, 0xC628, 0xC629, 0x5D4F, 0, 0, 0, - 0xC62A, 0x7647, 0x5D50, 0x5D51, 0xC62C, 0x7648, 0xEE22, 0x5D52, - 0xC62F, 0x5D54, 0x5D53, 0x5D55, 0x3225, 0x434A, 0, 0x5D56, - 0xC630, 0xC631, 0x3B26, 0x334C, 0x5D57, 0xEE24, 0xEE25, 0x4542, -}; -static const unsigned short utf8_to_euc_E6AF[] = { - 0x544C, 0, 0, 0xC634, 0xC635, 0x3523, 0x5D58, 0, - 0, 0xC636, 0, 0x5D59, 0xC637, 0x4A6C, 0x4B68, 0, - 0, 0, 0x4647, 0x5D5A, 0x4866, 0, 0xC638, 0, - 0x487B, 0, 0xC639, 0x4C53, 0, 0, 0, 0x5D5B, - 0, 0xC63A, 0, 0xC63B, 0, 0, 0xC63C, 0xC63D, - 0, 0, 0, 0x5D5D, 0x5D5C, 0, 0xC63E, 0x5D5F, - 0, 0xC63F, 0, 0x5D5E, 0, 0, 0, 0xC640, - 0, 0xC641, 0, 0, 0, 0, 0, 0xC642, -}; -static const unsigned short utf8_to_euc_E6AF_x0213[] = { - 0x544C, 0, 0, 0xC634, 0xC635, 0x3523, 0x5D58, 0xEE26, - 0xEE27, 0xEE28, 0, 0x5D59, 0xC637, 0x4A6C, 0x4B68, 0x764A, - 0, 0, 0x4647, 0x5D5A, 0x4866, 0, 0x764B, 0x764C, - 0x487B, 0, 0xEE29, 0x4C53, 0, 0, 0, 0x5D5B, - 0, 0xC63A, 0, 0xC63B, 0, 0, 0xEE2A, 0xEE2B, - 0, 0, 0, 0x5D5D, 0x5D5C, 0, 0xEE2C, 0x5D5F, - 0, 0xEE2D, 0, 0x5D5E, 0, 0, 0, 0xC640, - 0, 0xC641, 0, 0, 0, 0, 0, 0x764D, -}; -static const unsigned short utf8_to_euc_E6B0[] = { - 0, 0, 0xC643, 0, 0xC644, 0xC645, 0, 0, - 0x5D61, 0xC646, 0, 0, 0, 0xC647, 0xC648, 0x3B61, - 0xC649, 0x4C31, 0xC64A, 0x5D62, 0x5D63, 0, 0, 0x3524, - 0, 0xC64B, 0, 0x5D64, 0, 0, 0, 0xC64C, - 0, 0, 0, 0x5D66, 0x5D65, 0, 0xC64D, 0xC64E, - 0xC64F, 0, 0, 0, 0xC650, 0, 0xC651, 0, - 0, 0, 0, 0xC652, 0x3F65, 0xC653, 0xC654, 0x4939, - 0x314A, 0, 0xC655, 0xC656, 0, 0, 0x4845, 0xC657, -}; -static const unsigned short utf8_to_euc_E6B0_x0213[] = { - 0, 0, 0xEE2E, 0, 0xC644, 0x764E, 0, 0, - 0x5D61, 0xC646, 0xEE2F, 0, 0, 0xC647, 0xEE30, 0x3B61, - 0x764F, 0x4C31, 0xC64A, 0x5D62, 0x5D63, 0, 0, 0x3524, - 0, 0xC64B, 0, 0x5D64, 0, 0, 0, 0xC64C, - 0, 0, 0, 0x5D66, 0x5D65, 0, 0xC64D, 0xC64E, - 0xC64F, 0, 0, 0, 0xC650, 0, 0xC651, 0, - 0, 0, 0, 0x7650, 0x3F65, 0xEE31, 0xEE32, 0x4939, - 0x314A, 0, 0xEE33, 0xC656, 0, 0, 0x4845, 0xEE35, -}; -static const unsigned short utf8_to_euc_E6B1[] = { - 0x4475, 0x3D41, 0x3561, 0, 0, 0, 0, 0, - 0, 0, 0xC658, 0xC659, 0, 0xC65A, 0x4846, 0xC65B, - 0x3C2E, 0, 0xC65C, 0, 0xC65D, 0x5D68, 0, 0x3440, - 0, 0xC65E, 0x3178, 0xC65F, 0xC660, 0x4672, 0x5D67, 0x393E, - 0x4353, 0, 0x5D69, 0, 0, 0, 0, 0xC736, - 0x5D71, 0, 0x5D6A, 0xC661, 0, 0xC662, 0, 0xC663, - 0x4241, 0, 0x3562, 0x5D72, 0xC664, 0, 0xC665, 0, - 0xC666, 0xC667, 0x3768, 0xC668, 0, 0x3525, 0x5D70, 0, -}; -static const unsigned short utf8_to_euc_E6B1_x0213[] = { - 0x4475, 0x3D41, 0x3561, 0, 0, 0, 0, 0, - 0, 0, 0xC658, 0xC659, 0, 0xEE36, 0x4846, 0xC65B, - 0x3C2E, 0, 0xC65C, 0, 0xC65D, 0x5D68, 0, 0x3440, - 0, 0x7651, 0x3178, 0xEE37, 0x7652, 0x4672, 0x5D67, 0x393E, - 0x4353, 0, 0x5D69, 0, 0, 0, 0, 0xEE4F, - 0x5D71, 0, 0x5D6A, 0xC661, 0, 0xEE38, 0, 0, - 0x4241, 0, 0x3562, 0x5D72, 0x7654, 0, 0x7655, 0, - 0xC666, 0xC667, 0x3768, 0xC668, 0, 0x3525, 0x5D70, 0, -}; -static const unsigned short utf8_to_euc_E6B2[] = { - 0, 0x5D6E, 0x5D6B, 0x4D60, 0, 0xC669, 0xC66A, 0xC66B, - 0x4440, 0xC66C, 0, 0, 0x4659, 0x5D6C, 0, 0, - 0x5D74, 0, 0x5D73, 0x3723, 0xC66D, 0xC66E, 0x322D, 0xC66F, - 0xC670, 0x3A3B, 0x5D6D, 0x5D6F, 0xC671, 0, 0, 0xC672, - 0, 0x4B57, 0x4274, 0, 0, 0, 0, 0, - 0, 0, 0, 0x4B77, 0, 0, 0x5D7C, 0, - 0xC673, 0x5D7D, 0xC674, 0x324F, 0xC675, 0, 0, 0, - 0x4A28, 0x4C7D, 0x5E21, 0x3C23, 0x3E42, 0x5D78, 0x5D7E, 0x3168, -}; -static const unsigned short utf8_to_euc_E6B2_x0213[] = { - 0, 0x5D6E, 0x5D6B, 0x4D60, 0xEE39, 0x7656, 0x7657, 0xC66B, - 0x4440, 0xEE3A, 0, 0, 0x4659, 0x5D6C, 0, 0, - 0x5D74, 0, 0x5D73, 0x3723, 0xEE3C, 0xEE3D, 0x322D, 0xEE3E, - 0x7658, 0x3A3B, 0x5D6D, 0x5D6F, 0x7659, 0, 0, 0xC672, - 0, 0x4B57, 0x4274, 0, 0, 0, 0, 0, - 0, 0, 0x7653, 0x4B77, 0, 0xEE3F, 0x5D7C, 0, - 0xC673, 0x5D7D, 0xC674, 0x324F, 0xC675, 0, 0, 0, - 0x4A28, 0x4C7D, 0x5E21, 0x3C23, 0x3E42, 0x5D78, 0x5D7E, 0x3168, -}; -static const unsigned short utf8_to_euc_E6B3[] = { - 0, 0x3637, 0xC676, 0, 0x5D75, 0x5D7A, 0xC677, 0, - 0, 0x4074, 0x4771, 0, 0x4867, 0xC678, 0, 0xC679, - 0xC67A, 0xC67B, 0xC67C, 0x5D77, 0xC67D, 0x4B21, 0xC67E, 0x5D79, - 0, 0x5E24, 0xC721, 0x5E22, 0xC722, 0x5D7B, 0, 0, - 0xC723, 0x4B22, 0x4748, 0x3563, 0, 0x4525, 0, 0xC724, - 0x436D, 0xC725, 0x5E25, 0xC726, 0xC727, 0, 0xC728, 0x5E23, - 0x4259, 0x5D76, 0xC729, 0x314B, 0xC72A, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B3_x0213[] = { - 0, 0x3637, 0xEE40, 0, 0x5D75, 0x5D7A, 0x765B, 0, - 0, 0x4074, 0x4771, 0, 0x4867, 0xC678, 0, 0xC679, - 0xEE41, 0xC67B, 0xC67C, 0x5D77, 0x765C, 0x4B21, 0xEE43, 0x5D79, - 0, 0x5E24, 0xEE44, 0x5E22, 0xEE45, 0x5D7B, 0, 0, - 0x765D, 0x4B22, 0x4748, 0x3563, 0, 0x4525, 0, 0xC724, - 0x436D, 0xEE46, 0x5E25, 0x765E, 0xEE47, 0xEE48, 0x765F, 0x5E23, - 0x4259, 0x5D76, 0xC729, 0x314B, 0xC72A, 0, 0, 0, - 0, 0, 0, 0x765A, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B4[] = { - 0, 0, 0, 0, 0xC72B, 0, 0, 0xC72C, - 0, 0, 0xC72D, 0x4D4E, 0x5E30, 0, 0xC72E, 0xC72F, - 0, 0xC730, 0x5E2F, 0xC731, 0, 0, 0, 0x4076, - 0, 0x5E2C, 0xC732, 0x4D6C, 0, 0, 0x4636, 0x5E26, - 0, 0, 0, 0, 0, 0x4445, 0xC733, 0xC734, - 0xC735, 0x314C, 0x393F, 0x5E29, 0, 0, 0xC737, 0xC738, - 0, 0xC739, 0x3D27, 0x5E2E, 0, 0x5E2D, 0x5E28, 0, - 0x5E2B, 0xC73A, 0, 0x3368, 0xC73B, 0x5E2A, 0x4749, 0xC73C, -}; -static const unsigned short utf8_to_euc_E6B4_x0213[] = { - 0xEE4A, 0, 0, 0, 0x7661, 0, 0, 0xC72C, - 0, 0, 0xEE4B, 0x4D4E, 0x5E30, 0, 0x7662, 0xC72F, - 0, 0xC730, 0x5E2F, 0xC731, 0, 0, 0, 0x4076, - 0, 0x5E2C, 0xC732, 0x4D6C, 0, 0, 0x4636, 0x5E26, - 0, 0, 0, 0, 0xEE4C, 0x4445, 0xEE4D, 0xEE4E, - 0xC735, 0x314C, 0x393F, 0x5E29, 0, 0, 0x7663, 0xEE50, - 0, 0x7664, 0x3D27, 0x5E2E, 0xEE65, 0x5E2D, 0x5E28, 0, - 0x5E2B, 0x7665, 0, 0x3368, 0xEE51, 0x5E2A, 0x4749, 0x7666, -}; -static const unsigned short utf8_to_euc_E6B5[] = { - 0, 0x4E2E, 0, 0, 0x3E74, 0x4075, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xC73D, - 0, 0x5E36, 0x5E34, 0, 0x494D, 0, 0xC73E, 0xC73F, - 0, 0xC740, 0, 0x5E31, 0x5E33, 0xC741, 0x313A, 0xC742, - 0, 0x3940, 0x4F32, 0, 0x333D, 0, 0x4962, 0xC743, - 0xC744, 0, 0, 0, 0x4D61, 0, 0, 0x3324, - 0x3F3B, 0x5E35, 0, 0, 0xC745, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B5_x0213[] = { - 0, 0x4E2E, 0, 0, 0x3E74, 0x4075, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xC73D, - 0x7667, 0x5E36, 0x5E34, 0xEE52, 0x494D, 0, 0xEE53, 0xC73F, - 0xEE54, 0xC740, 0, 0x5E31, 0x5E33, 0x7668, 0x313A, 0xC742, - 0, 0x3940, 0x4F32, 0, 0x333D, 0, 0x4962, 0, - 0xEE55, 0, 0, 0, 0x4D61, 0, 0, 0x3324, - 0x3F3B, 0x5E35, 0, 0, 0xC745, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B6[] = { - 0, 0, 0xC746, 0, 0, 0x5E3A, 0, 0xC747, - 0x3E43, 0, 0, 0, 0x4D30, 0, 0x5E37, 0, - 0, 0xC748, 0xC749, 0x5E32, 0xC74A, 0x5E38, 0xC74B, 0xC74C, - 0xC74D, 0x4E5E, 0, 0x4573, 0x4642, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xC74E, 0, 0xC74F, 0, 0, 0x3336, - 0, 0, 0x3155, 0, 0xC750, 0x5E3E, 0, 0xC751, - 0x5E41, 0xC752, 0, 0, 0x4E43, 0xC753, 0, 0xC754, -}; -static const unsigned short utf8_to_euc_E6B6_x0213[] = { - 0xEE56, 0xEE57, 0x766A, 0, 0, 0x5E3A, 0, 0x766B, - 0x3E43, 0x766C, 0xEE58, 0, 0x4D30, 0xEE59, 0x5E37, 0, - 0, 0xEE5A, 0xC749, 0x5E32, 0x766D, 0x5E38, 0, 0xC74C, - 0xEE5B, 0x4E5E, 0, 0x4573, 0x4642, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x766E, 0xEE61, 0x766F, 0, 0xEE62, 0x3336, - 0, 0, 0x3155, 0, 0xEE63, 0x5E3E, 0, 0xC751, - 0x5E41, 0xC752, 0, 0, 0x4E43, 0xC753, 0, 0x7670, -}; -static const unsigned short utf8_to_euc_E6B7[] = { - 0x4D64, 0, 0, 0, 0xC755, 0x5E48, 0x5E42, 0x5E3F, - 0xC756, 0, 0xC757, 0x4E54, 0x5E45, 0, 0xC758, 0xC759, - 0, 0x3D4A, 0x5E47, 0, 0, 0x5E4C, 0xC75A, 0, - 0x4571, 0x5E4A, 0, 0xC75B, 0, 0xC75C, 0x5E44, 0xC75D, - 0xC75E, 0x4338, 0xC75F, 0, 0x5E4B, 0xC760, 0x5E40, 0, - 0x5E46, 0xC761, 0x5E4D, 0x307C, 0x5E43, 0, 0x5E4E, 0xC762, - 0xC763, 0x3F3C, 0xF44C, 0x3D5F, 0xC764, 0x4A25, 0xC765, 0x3A2E, - 0xF44B, 0x5E3B, 0x5E49, 0x453A, 0xC766, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B7_x0213[] = { - 0x4D64, 0, 0xEE64, 0, 0x7671, 0x5E48, 0x5E42, 0x5E3F, - 0xEE66, 0, 0xC757, 0x4E54, 0x5E45, 0, 0xEE67, 0xEE68, - 0xEE69, 0x3D4A, 0x5E47, 0, 0, 0x5E4C, 0x7672, 0, - 0x4571, 0x5E4A, 0x7673, 0x7674, 0, 0x7675, 0x5E44, 0xEE6A, - 0xC75E, 0x4338, 0xC75F, 0, 0x5E4B, 0xC760, 0x5E40, 0, - 0x5E46, 0xEE6B, 0x5E4D, 0x307C, 0x5E43, 0, 0x5E4E, 0xC762, - 0xC763, 0x3F3C, 0, 0x3D5F, 0xC764, 0x4A25, 0xEE6C, 0x3A2E, - 0, 0x5E3B, 0x5E49, 0x453A, 0x7676, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6B8[] = { - 0xC767, 0, 0, 0, 0xC768, 0x4036, 0, 0x3369, - 0x3A51, 0x3E44, 0x5E3D, 0x3D42, 0, 0, 0, 0, - 0, 0, 0, 0x374C, 0, 0x5E3C, 0, 0, - 0, 0x5E52, 0x3D6D, 0x383A, 0, 0x5E61, 0xC769, 0x5E5B, - 0x3574, 0x454F, 0xC76A, 0x5E56, 0x5E5F, 0x302F, 0x3132, 0xC76B, - 0, 0x3239, 0, 0x5E58, 0x422C, 0x5E4F, 0x5E51, 0x3941, - 0, 0, 0xC76C, 0, 0, 0, 0xC76D, 0, - 0x5E62, 0xC76E, 0x5E5D, 0xC76F, 0xC770, 0, 0x5E55, 0, -}; -static const unsigned short utf8_to_euc_E6B8_x0213[] = { - 0xC767, 0, 0, 0, 0xC768, 0x4036, 0, 0x3369, - 0x3A51, 0x3E44, 0x5E3D, 0x3D42, 0, 0, 0, 0, - 0, 0, 0, 0x374C, 0, 0x5E3C, 0, 0xEE5D, - 0, 0x5E52, 0x3D6D, 0x383A, 0, 0x5E61, 0xEE6E, 0x5E5B, - 0x3574, 0x454F, 0xEE6F, 0x5E56, 0x5E5F, 0x302F, 0x3132, 0xEE70, - 0, 0x3239, 0, 0x5E58, 0x422C, 0x5E4F, 0x5E51, 0x3941, - 0, 0, 0xEE72, 0, 0x7678, 0, 0xEE6D, 0, - 0x5E62, 0, 0x5E5D, 0xC76F, 0xEE73, 0, 0x5E55, 0, -}; -static const unsigned short utf8_to_euc_E6B9[] = { - 0, 0, 0, 0x5E5C, 0xC771, 0xC772, 0, 0, - 0xC773, 0xC774, 0x4C2B, 0xC775, 0, 0x5E5A, 0x5E5E, 0xC776, - 0, 0xC777, 0xC778, 0xC779, 0xC77A, 0, 0x3850, 0xC77B, - 0x3E45, 0, 0, 0x4339, 0xC77C, 0xC77D, 0xC77E, 0x5E54, - 0, 0, 0xC821, 0xC822, 0, 0, 0, 0x4D2F, - 0xC823, 0, 0, 0x5E57, 0, 0, 0x5E50, 0x4572, - 0, 0, 0x5E53, 0xC824, 0, 0, 0x5E59, 0, - 0, 0, 0, 0xC825, 0, 0xC826, 0x4F51, 0x3C3E, -}; -static const unsigned short utf8_to_euc_E6B9_x0213[] = { - 0, 0, 0, 0x5E5C, 0x7679, 0xC772, 0, 0, - 0xEE74, 0xEE75, 0x4C2B, 0xEE76, 0xEE77, 0x5E5A, 0x5E5E, 0xEE78, - 0, 0xEE79, 0xC778, 0xEE7A, 0xEE7B, 0, 0x3850, 0xEE7C, - 0x3E45, 0, 0, 0x4339, 0x767A, 0xC77D, 0x767B, 0x5E54, - 0, 0, 0xC821, 0xEE7D, 0, 0, 0, 0x4D2F, - 0xC823, 0, 0, 0x5E57, 0, 0, 0x5E50, 0x4572, - 0, 0, 0x5E53, 0xC824, 0, 0, 0x5E59, 0, - 0, 0, 0, 0xC825, 0, 0xC826, 0x4F51, 0x3C3E, -}; -static const unsigned short utf8_to_euc_E6BA[] = { - 0x4B7E, 0, 0x5E63, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x482E, 0xC827, 0, 0x5E6F, - 0x383B, 0, 0, 0xC828, 0, 0, 0x3D60, 0, - 0x5E65, 0xC829, 0, 0, 0x4E2F, 0x3942, 0, 0x5E72, - 0xC82A, 0, 0x306E, 0, 0, 0x5E70, 0, 0xC82B, - 0, 0, 0x5E64, 0, 0, 0xC82C, 0xC82D, 0x5E6A, - 0, 0xC82E, 0x5E6C, 0xC82F, 0, 0, 0x4D4F, 0x5E67, - 0, 0, 0x452E, 0xC830, 0, 0x5E69, 0, 0xC831, -}; -static const unsigned short utf8_to_euc_E6BA_x0213[] = { - 0x4B7E, 0, 0x5E63, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x482E, 0xC827, 0, 0x5E6F, - 0x383B, 0, 0, 0xEF21, 0, 0, 0x3D60, 0, - 0x5E65, 0xC829, 0, 0, 0x4E2F, 0x3942, 0, 0x5E72, - 0xC82A, 0, 0x306E, 0, 0, 0x5E70, 0, 0xEF22, - 0, 0, 0x5E64, 0x767C, 0, 0xC82C, 0xC82D, 0x5E6A, - 0, 0x767D, 0x5E6C, 0xC82F, 0xEF23, 0, 0x4D4F, 0x5E67, - 0, 0, 0x452E, 0xC830, 0, 0x5E69, 0, 0xEF24, -}; -static const unsigned short utf8_to_euc_E6BB[] = { - 0xC832, 0xC833, 0x5E71, 0xC834, 0x5E6B, 0x4C47, 0, 0xC835, - 0xC836, 0x5E66, 0xC837, 0x3C22, 0x5E7E, 0xC838, 0xC839, 0xC83A, - 0, 0x336A, 0, 0x5E68, 0x5E6D, 0x5E6E, 0, 0, - 0, 0, 0, 0, 0, 0x426C, 0x425A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xC83B, 0x5E76, 0xC83C, 0xC83D, 0x5E7C, - 0, 0, 0x5E7A, 0, 0x4529, 0, 0, 0x5F23, - 0x5E77, 0xC83E, 0, 0xC83F, 0, 0xC840, 0x5E78, 0x5E60, -}; -static const unsigned short utf8_to_euc_E6BB_x0213[] = { - 0xC832, 0x767E, 0x5E71, 0xEF25, 0x5E6B, 0x4C47, 0, 0x7721, - 0xC836, 0x5E66, 0xEF26, 0x3C22, 0x5E7E, 0xC838, 0x7722, 0xC83A, - 0, 0x336A, 0, 0x5E68, 0x5E6D, 0x5E6E, 0, 0, - 0, 0xEF27, 0, 0, 0, 0x426C, 0x425A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xEF29, 0x5E76, 0xC83C, 0xC83D, 0x5E7C, - 0, 0, 0x5E7A, 0, 0x4529, 0, 0, 0x5F23, - 0x5E77, 0xEF2A, 0, 0xEF2B, 0, 0xC840, 0x5E78, 0x5E60, -}; -static const unsigned short utf8_to_euc_E6BC[] = { - 0, 0x3579, 0x493A, 0, 0xC841, 0, 0x3C3F, 0, - 0xC842, 0x3977, 0xC843, 0, 0xC844, 0xC845, 0, 0x4F33, - 0, 0x5E74, 0, 0x5F22, 0x3169, 0x4166, 0xC846, 0, - 0xC847, 0, 0xC848, 0xC849, 0, 0, 0, 0, - 0x4779, 0, 0x3441, 0x4E7A, 0, 0, 0xC84A, 0, - 0, 0xC84B, 0xC84C, 0x4C21, 0x4452, 0xC853, 0, 0xC84D, - 0xC84E, 0x5E7B, 0x5E7D, 0xC84F, 0, 0, 0xC850, 0, - 0x4132, 0, 0, 0xC851, 0xC852, 0, 0x5F21, 0x5E79, -}; -static const unsigned short utf8_to_euc_E6BC_x0213[] = { - 0, 0x3579, 0x493A, 0, 0xC841, 0, 0x3C3F, 0, - 0xC842, 0x3977, 0xEF2C, 0, 0xEF2D, 0xC845, 0, 0x4F33, - 0x7723, 0x5E74, 0, 0x5F22, 0x3169, 0x4166, 0xC846, 0, - 0xEF2E, 0, 0x7724, 0xC849, 0, 0, 0, 0, - 0x4779, 0, 0x3441, 0x4E7A, 0, 0xEF2F, 0xC84A, 0, - 0, 0xC84B, 0x7726, 0x4C21, 0x4452, 0xC853, 0, 0x7727, - 0xC84E, 0x5E7B, 0x5E7D, 0x7728, 0, 0xEF28, 0xEF30, 0, - 0x4132, 0, 0, 0xC851, 0xEF31, 0, 0x5F21, 0x5E79, -}; -static const unsigned short utf8_to_euc_E6BD[] = { - 0, 0x5E73, 0, 0, 0, 0x3443, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xC854, - 0, 0xC855, 0xC856, 0xC857, 0x3769, 0, 0, 0xC858, - 0x5F2F, 0xC859, 0xC85A, 0x5F2A, 0x4078, 0xC85B, 0xC85C, 0x3363, - 0, 0xC85D, 0xC85E, 0, 0x3D61, 0, 0x5F33, 0, - 0xC85F, 0, 0, 0, 0xC860, 0x5F2C, 0x442C, 0x5F29, - 0x4459, 0, 0, 0, 0x5F4C, 0, 0, 0, - 0x5F26, 0, 0x5F25, 0, 0x5F2E, 0xC861, 0xC862, 0, -}; -static const unsigned short utf8_to_euc_E6BD_x0213[] = { - 0, 0x5E73, 0, 0, 0, 0x3443, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xC854, - 0, 0x7729, 0xEF33, 0xC857, 0x3769, 0, 0, 0xEF34, - 0x5F2F, 0x772A, 0xEF35, 0x5F2A, 0x4078, 0xC85B, 0x772B, 0x3363, - 0xEF36, 0x772C, 0x772D, 0, 0x3D61, 0, 0x5F33, 0, - 0xEF37, 0, 0, 0, 0xC860, 0x5F2C, 0x442C, 0x5F29, - 0x4459, 0, 0, 0, 0x5F4C, 0, 0, 0, - 0x5F26, 0, 0x5F25, 0, 0x5F2E, 0xEF39, 0x772E, 0, -}; -static const unsigned short utf8_to_euc_E6BE[] = { - 0x5F28, 0x5F27, 0x5F2D, 0xC863, 0x4021, 0, 0x5F24, 0xC864, - 0xC865, 0, 0, 0xC866, 0xC867, 0xC868, 0x5F30, 0, - 0xC869, 0x5F31, 0xC86A, 0xC86B, 0xC86C, 0, 0xC86D, 0x3442, - 0, 0, 0xC86E, 0, 0, 0, 0, 0xC86F, - 0xC870, 0x5F36, 0, 0x5F35, 0x5F37, 0xC871, 0xC872, 0xC873, - 0xC874, 0, 0x5F3A, 0, 0, 0, 0xC875, 0xC876, - 0xC877, 0x4543, 0, 0x5F34, 0, 0xC878, 0xC879, 0, - 0, 0x5F38, 0, 0, 0xC87A, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E6BE_x0213[] = { - 0x5F28, 0x5F27, 0x5F2D, 0xC863, 0x4021, 0, 0x5F24, 0xC864, - 0x772F, 0, 0, 0xC866, 0x7730, 0x7731, 0x5F30, 0, - 0xEF3A, 0x5F31, 0xC86A, 0xC86B, 0x7732, 0, 0xEF3B, 0x3442, - 0xEF38, 0, 0xC86E, 0, 0, 0, 0, 0xEF3D, - 0x7733, 0x5F36, 0, 0x5F35, 0x5F37, 0xEF3E, 0xC872, 0x7734, - 0xC874, 0, 0x5F3A, 0, 0, 0, 0xC875, 0xEF3F, - 0xC877, 0x4543, 0, 0x5F34, 0, 0xEF41, 0x7735, 0, - 0, 0x5F38, 0, 0, 0x7736, 0, 0xEF3C, 0, -}; -static const unsigned short utf8_to_euc_E6BF[] = { - 0x3763, 0x4279, 0x5F32, 0x473B, 0, 0xC87B, 0x5F39, 0xC87C, - 0xC87D, 0, 0xC87E, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x5F3E, 0x5F3C, 0, 0, - 0x5F3F, 0, 0xC921, 0x5F42, 0, 0, 0xC922, 0x5F3B, - 0x396A, 0x4728, 0, 0, 0x5E39, 0, 0, 0, - 0xC923, 0xC924, 0, 0x4D74, 0x5F3D, 0, 0x5F41, 0x4275, - 0xC925, 0x5F40, 0, 0x5F2B, 0, 0xC926, 0x6F69, 0, - 0, 0xC927, 0x5F45, 0, 0xC928, 0xC929, 0x5F49, 0, -}; -static const unsigned short utf8_to_euc_E6BF_x0213[] = { - 0x3763, 0x4279, 0x5F32, 0x473B, 0, 0xC87B, 0x5F39, 0x7737, - 0xEF42, 0xEF43, 0x7738, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x5F3E, 0x5F3C, 0, 0, - 0x5F3F, 0, 0xEF44, 0x5F42, 0, 0, 0xEF45, 0x5F3B, - 0x396A, 0x4728, 0, 0, 0x5E39, 0, 0, 0, - 0xC923, 0xEF46, 0, 0x4D74, 0x5F3D, 0, 0x5F41, 0x4275, - 0x773A, 0x5F40, 0, 0x5F2B, 0, 0x773B, 0x6F69, 0, - 0, 0x7739, 0x5F45, 0, 0xEF48, 0xC929, 0x5F49, 0, -}; -static const unsigned short utf8_to_euc_E780[] = { - 0xC92A, 0x5F47, 0, 0, 0, 0xC92B, 0xC92C, 0xC92D, - 0, 0x5F43, 0, 0x5F44, 0, 0xC92E, 0, 0x5F48, - 0, 0x5F46, 0, 0, 0, 0x494E, 0, 0xC92F, - 0x5F4E, 0, 0x5F4B, 0x5F4A, 0, 0x5F4D, 0x4654, 0x5F4F, - 0xC930, 0, 0, 0xC931, 0, 0, 0x4375, 0x426D, - 0xF44D, 0, 0, 0, 0x4025, 0, 0, 0xC932, - 0x5F50, 0, 0x5F52, 0, 0xC933, 0, 0, 0xC934, - 0, 0xC935, 0, 0, 0xC936, 0, 0x5F51, 0, -}; -static const unsigned short utf8_to_euc_E780_x0213[] = { - 0xEF49, 0x5F47, 0, 0, 0, 0x773C, 0x773D, 0xEF4A, - 0, 0x5F43, 0xEF4B, 0x5F44, 0, 0xC92E, 0, 0x5F48, - 0, 0x5F46, 0, 0, 0, 0x494E, 0, 0xC92F, - 0x5F4E, 0, 0x5F4B, 0x5F4A, 0, 0x5F4D, 0x4654, 0x5F4F, - 0xC930, 0, 0, 0xEF4C, 0, 0, 0x4375, 0x426D, - 0x773E, 0, 0, 0, 0x4025, 0, 0, 0xC932, - 0x5F50, 0, 0x5F52, 0, 0xC933, 0, 0, 0xC934, - 0, 0xEF4E, 0xEF4F, 0, 0xEF50, 0, 0x5F51, 0, -}; -static const unsigned short utf8_to_euc_E781[] = { - 0, 0, 0, 0xC937, 0xC938, 0, 0, 0, - 0xC939, 0xC93A, 0xC93B, 0xC93C, 0x5E75, 0, 0xC941, 0, - 0, 0x5F53, 0, 0, 0xC93D, 0xC93E, 0, 0, - 0x4667, 0, 0, 0, 0, 0xC93F, 0xC940, 0, - 0, 0, 0, 0x5F54, 0xC942, 0xC943, 0, 0, - 0, 0, 0, 0x3250, 0xC944, 0, 0xC945, 0x4574, - 0x3325, 0, 0, 0, 0, 0xC946, 0xC947, 0, - 0x3564, 0, 0, 0, 0x3C5E, 0x3A52, 0xC948, 0, -}; -static const unsigned short utf8_to_euc_E781_x0213[] = { - 0, 0, 0, 0xEF51, 0xC938, 0, 0, 0xEF52, - 0xC939, 0xC93A, 0x773F, 0xEF53, 0x5E75, 0, 0x7742, 0, - 0, 0x5F53, 0, 0, 0xEF55, 0xC93E, 0, 0, - 0x4667, 0, 0, 0, 0, 0x7740, 0x7741, 0, - 0, 0, 0, 0x5F54, 0x7743, 0xEF56, 0, 0, - 0, 0xEF57, 0, 0x3250, 0xEF58, 0, 0xEF59, 0x4574, - 0x3325, 0, 0, 0, 0, 0x7744, 0xEF5A, 0, - 0x3564, 0, 0, 0, 0x3C5E, 0x3A52, 0xEF5B, 0, -}; -static const unsigned short utf8_to_euc_E782[] = { - 0, 0xC949, 0, 0, 0, 0xC94A, 0xC94B, 0, - 0, 0x4F27, 0x3F66, 0, 0, 0, 0x316A, 0, - 0, 0, 0x5F56, 0, 0xC94C, 0xC94D, 0xC94E, 0xC94F, - 0xC950, 0x5F55, 0, 0xC951, 0, 0, 0, 0, - 0, 0, 0, 0, 0xC952, 0, 0, 0, - 0, 0, 0, 0xC953, 0x5F59, 0x433A, 0x5F5C, 0x5F57, - 0xC954, 0xC955, 0, 0x5F5B, 0xC956, 0, 0, 0xC957, - 0x5F5A, 0x4540, 0x3059, 0xF42E, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E782_x0213[] = { - 0, 0xEF5C, 0, 0, 0, 0x7745, 0xEF5D, 0, - 0, 0x4F27, 0x3F66, 0, 0, 0, 0x316A, 0, - 0, 0, 0x5F56, 0, 0xC94C, 0xEF5E, 0xC94E, 0xEF5F, - 0xC950, 0x5F55, 0, 0xC951, 0, 0, 0, 0xEF62, - 0, 0, 0, 0, 0x7746, 0, 0, 0, - 0, 0, 0, 0x7747, 0x5F59, 0x433A, 0x5F5C, 0x5F57, - 0xC954, 0xEF63, 0, 0x5F5B, 0xC956, 0, 0, 0x7748, - 0x5F5A, 0x4540, 0x3059, 0xEF60, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E783[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0x4E75, 0, 0xC958, 0x5F5E, 0, 0, 0, 0x3128, - 0, 0xC959, 0, 0xC95A, 0xC95B, 0xC95C, 0xC95D, 0, - 0xC95E, 0x5F60, 0, 0, 0xC95F, 0x5F5F, 0, 0x5F5D, - 0, 0, 0, 0, 0xC960, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x5F58, 0, 0, 0, 0, 0, 0, - 0, 0x4B23, 0xC961, 0, 0, 0x5F62, 0, 0, -}; -static const unsigned short utf8_to_euc_E783_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0x4E75, 0, 0xEF66, 0x5F5E, 0, 0, 0, 0x3128, - 0, 0xEF67, 0, 0xEF68, 0x7749, 0xC95C, 0xC95D, 0, - 0x774A, 0x5F60, 0, 0, 0xEF69, 0x5F5F, 0, 0x5F5D, - 0, 0, 0, 0, 0x774B, 0, 0, 0, - 0, 0, 0, 0, 0xEF65, 0, 0, 0, - 0, 0x5F58, 0, 0, 0, 0, 0, 0, - 0, 0x4B23, 0xC961, 0, 0, 0x5F62, 0, 0, -}; -static const unsigned short utf8_to_euc_E784[] = { - 0, 0, 0, 0xC962, 0xC963, 0xC964, 0xC965, 0xC966, - 0, 0x5F61, 0, 0xC967, 0xC968, 0, 0, 0xC969, - 0, 0, 0, 0, 0x316B, 0, 0, 0, - 0, 0x5F64, 0x4A32, 0, 0x5F63, 0, 0xC96A, 0, - 0xC96B, 0x4C35, 0, 0, 0, 0, 0x3E47, 0, - 0, 0, 0, 0xC96C, 0, 0xC96D, 0, 0xC96E, - 0xC96F, 0xC970, 0, 0, 0, 0, 0x4133, 0, - 0xC971, 0, 0, 0, 0x3E46, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E784_x0213[] = { - 0, 0, 0, 0xEF6A, 0xEF6B, 0xC964, 0xEF6C, 0xEF6D, - 0xEF6E, 0x5F61, 0, 0xC967, 0xEF6F, 0, 0, 0x774C, - 0, 0, 0, 0, 0x316B, 0, 0, 0, - 0, 0x5F64, 0x4A32, 0, 0x5F63, 0, 0x774E, 0, - 0x774F, 0x4C35, 0, 0, 0, 0, 0x3E47, 0, - 0, 0, 0, 0x774D, 0, 0xC96D, 0x7750, 0xEF71, - 0x7751, 0xEF72, 0, 0, 0, 0, 0x4133, 0, - 0xC971, 0, 0, 0, 0x3E46, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E785[] = { - 0, 0xC972, 0, 0, 0, 0xC973, 0xC974, 0xC975, - 0, 0x4E7B, 0xC976, 0xC977, 0x5F6A, 0, 0x4079, 0, - 0xC978, 0, 0xC979, 0, 0, 0x5F66, 0x5F6B, 0xC97A, - 0, 0x316C, 0xC97B, 0, 0xC97C, 0, 0xC97D, 0, - 0xC97E, 0, 0x5F69, 0, 0x4761, 0x5F65, 0x5F68, 0x3E48, - 0xCA21, 0x4851, 0, 0, 0x5F6C, 0, 0x3C51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xCA22, 0, 0, 0, 0x407A, 0, 0, -}; -static const unsigned short utf8_to_euc_E785_x0213[] = { - 0, 0xC972, 0, 0, 0, 0xC973, 0x7752, 0x7753, - 0, 0x4E7B, 0xEF74, 0xC977, 0x5F6A, 0, 0x4079, 0, - 0xEF73, 0x7754, 0x7756, 0xEF75, 0, 0x5F66, 0x5F6B, 0xC97A, - 0, 0x316C, 0xC97B, 0, 0x7757, 0, 0xEF76, 0, - 0x7758, 0, 0x5F69, 0, 0x4761, 0x5F65, 0x5F68, 0x3E48, - 0x7759, 0x4851, 0, 0, 0x5F6C, 0, 0x3C51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xCA22, 0, 0, 0, 0x407A, 0, 0, -}; -static const unsigned short utf8_to_euc_E786[] = { - 0xCA23, 0, 0, 0, 0x5F6F, 0xCA24, 0, 0xCA25, - 0x5F67, 0, 0x3727, 0, 0xCA26, 0, 0, 0x5F6D, - 0, 0, 0xCA27, 0, 0x4D50, 0x5F70, 0, 0, - 0, 0x7426, 0xCA28, 0xCA29, 0, 0, 0, 0x3D4F, - 0xCA2A, 0, 0xCA2B, 0, 0, 0, 0, 0, - 0x5F71, 0, 0, 0, 0x5F72, 0, 0, 0xCA2C, - 0xCA2D, 0x472E, 0xCA2E, 0xCA2F, 0, 0, 0, 0, - 0, 0x5F74, 0xCA30, 0, 0, 0, 0x5F75, 0xCA31, -}; -static const unsigned short utf8_to_euc_E786_x0213[] = { - 0xEF79, 0, 0, 0, 0x5F6F, 0x775B, 0, 0x775C, - 0x5F67, 0, 0x3727, 0, 0xCA26, 0, 0, 0x5F6D, - 0, 0, 0x775D, 0, 0x4D50, 0x5F70, 0xEF78, 0, - 0, 0x7426, 0xCA28, 0xEF7A, 0, 0, 0, 0x3D4F, - 0xEF7B, 0, 0xEF7C, 0, 0, 0, 0, 0, - 0x5F71, 0, 0, 0, 0x5F72, 0, 0xEF7D, 0xEF7E, - 0xCA2D, 0x472E, 0xCA2E, 0xF021, 0, 0, 0, 0, - 0, 0x5F74, 0x775F, 0, 0, 0, 0x5F75, 0xCA31, -}; -static const unsigned short utf8_to_euc_E787[] = { - 0xCA32, 0xCA33, 0, 0x4733, 0xCA34, 0, 0, 0, - 0x4575, 0x5F77, 0, 0xCA35, 0xCA36, 0, 0x5F79, 0, - 0x4E55, 0, 0x5F76, 0xCA37, 0x5F78, 0x316D, 0xCA38, 0x5F73, - 0, 0xCA39, 0xCA3A, 0, 0xCA3B, 0, 0, 0x535B, - 0x5F7A, 0, 0, 0, 0, 0x4167, 0x3B38, 0x5F7C, - 0, 0, 0, 0, 0x5F7B, 0x3F24, 0x5259, 0, - 0, 0, 0, 0, 0, 0x5F7D, 0, 0, - 0xCA3C, 0x6021, 0, 0x5F6E, 0x5F7E, 0, 0xCA3D, 0x6022, -}; -static const unsigned short utf8_to_euc_E787_x0213[] = { - 0xCA32, 0x775E, 0, 0x4733, 0x7760, 0, 0, 0, - 0x4575, 0x5F77, 0, 0xF023, 0xCA36, 0, 0x5F79, 0, - 0x4E55, 0, 0x5F76, 0xF024, 0x5F78, 0x316D, 0xCA38, 0x5F73, - 0, 0xF025, 0xCA3A, 0, 0xF026, 0, 0, 0x535B, - 0x5F7A, 0, 0, 0, 0, 0x4167, 0x3B38, 0x5F7C, - 0, 0, 0, 0, 0x5F7B, 0x3F24, 0x5259, 0, - 0, 0, 0, 0, 0, 0x5F7D, 0, 0, - 0xCA3C, 0x6021, 0, 0x5F6E, 0x5F7E, 0, 0x7761, 0x6022, -}; -static const unsigned short utf8_to_euc_E788[] = { - 0xCA3E, 0, 0, 0, 0, 0, 0x477A, 0xCA3F, - 0xCA40, 0xCA41, 0, 0, 0, 0x6023, 0, 0, - 0x6024, 0, 0, 0xCA42, 0, 0, 0, 0xCA43, - 0, 0, 0xCA44, 0x6025, 0, 0xCA45, 0, 0xCA46, - 0, 0, 0, 0, 0xCA47, 0, 0, 0, - 0x6026, 0, 0x445E, 0xCA48, 0x6028, 0x6027, 0, 0xCA49, - 0x6029, 0, 0x602A, 0, 0xCA4A, 0x3C5F, 0x4963, 0, - 0xCA4B, 0xCA4C, 0x4C6C, 0x602B, 0x602C, 0x4156, 0x3C24, 0x602D, -}; -static const unsigned short utf8_to_euc_E788_x0213[] = { - 0x7762, 0, 0, 0, 0, 0, 0x477A, 0xF027, - 0xCA40, 0xCA41, 0, 0, 0, 0x6023, 0, 0, - 0x6024, 0, 0, 0xCA42, 0, 0x7763, 0, 0xCA43, - 0, 0, 0xCA44, 0x6025, 0, 0xCA45, 0, 0xCA46, - 0, 0, 0, 0, 0xCA47, 0, 0, 0, - 0x6026, 0, 0x445E, 0xF02A, 0x6028, 0x6027, 0, 0xCA49, - 0x6029, 0, 0x602A, 0, 0xF02B, 0x3C5F, 0x4963, 0, - 0xF02C, 0xF02D, 0x4C6C, 0x602B, 0x602C, 0x4156, 0x3C24, 0x602D, -}; -static const unsigned short utf8_to_euc_E789[] = { - 0x602E, 0xCA4D, 0xCA4E, 0xCA4F, 0, 0xCA50, 0x602F, 0x4A52, - 0x4847, 0, 0, 0x6030, 0x4757, 0, 0xCA51, 0xCA52, - 0xCA53, 0, 0x442D, 0xCA54, 0, 0xCA55, 0xCA56, 0, - 0x6031, 0x3267, 0xCA57, 0x356D, 0xCA58, 0x4C46, 0xCA59, 0x4C36, - 0xCA5A, 0x3234, 0x4F34, 0xCA5B, 0, 0, 0, 0x4B52, - 0xCA5C, 0x4A2A, 0, 0xCA5D, 0, 0, 0xCA5E, 0xCA5F, - 0, 0xCA60, 0x4037, 0, 0x6032, 0, 0, 0xCA61, - 0xCA62, 0x4643, 0, 0xCA63, 0xCA64, 0x3823, 0x6033, 0xCA65, -}; -static const unsigned short utf8_to_euc_E789_x0213[] = { - 0x602E, 0xCA4D, 0xF02F, 0xCA4F, 0, 0xCA50, 0x602F, 0x4A52, - 0x4847, 0, 0, 0x6030, 0x4757, 0, 0xCA51, 0xCA52, - 0xCA53, 0, 0x442D, 0xF030, 0, 0x7764, 0x7765, 0xF031, - 0x6031, 0x3267, 0xCA57, 0x356D, 0xCA58, 0x4C46, 0xCA59, 0x4C36, - 0xCA5A, 0x3234, 0x4F34, 0xF032, 0, 0, 0, 0x4B52, - 0xCA5C, 0x4A2A, 0, 0xCA5D, 0, 0, 0xF034, 0xF035, - 0, 0xCA60, 0x4037, 0, 0x6032, 0, 0, 0xCA61, - 0xF036, 0x4643, 0, 0xCA63, 0xCA64, 0x3823, 0x6033, 0xF037, -}; -static const unsigned short utf8_to_euc_E78A[] = { - 0x3A54, 0x6035, 0x6034, 0, 0xCA66, 0, 0, 0x6036, - 0, 0xCA67, 0, 0, 0, 0xCA68, 0xCA69, 0, - 0, 0, 0x6037, 0xCA6A, 0, 0, 0x6038, 0, - 0, 0, 0, 0xCA6B, 0, 0, 0, 0, - 0x353E, 0, 0x6039, 0, 0, 0, 0, 0x603A, - 0xCA6C, 0, 0, 0, 0x3824, 0xCA6D, 0xCA6E, 0x4848, - 0, 0xCA6F, 0x603C, 0, 0xCA70, 0, 0x3E75, 0, - 0, 0x603B, 0, 0, 0, 0, 0xCA71, 0, -}; -static const unsigned short utf8_to_euc_E78A_x0213[] = { - 0x3A54, 0x6035, 0x6034, 0, 0xCA66, 0, 0, 0x6036, - 0, 0xCA67, 0, 0, 0, 0x7767, 0xF038, 0, - 0, 0, 0x6037, 0xCA6A, 0, 0, 0x6038, 0, - 0, 0, 0, 0x7768, 0, 0, 0, 0, - 0x353E, 0, 0x6039, 0, 0, 0, 0, 0x603A, - 0xCA6C, 0, 0, 0, 0x3824, 0xF03A, 0xF03B, 0x4848, - 0xF03C, 0xF03D, 0x603C, 0, 0xCA70, 0, 0x3E75, 0, - 0, 0x603B, 0, 0, 0, 0, 0x7769, 0, -}; -static const unsigned short utf8_to_euc_E78B[] = { - 0, 0xCA72, 0x3638, 0x603D, 0x603F, 0, 0x603E, 0xCA73, - 0, 0xCA74, 0, 0, 0xCA75, 0, 0x6040, 0, - 0x3851, 0, 0x6041, 0, 0, 0xCA76, 0xCA77, 0x3669, - 0xCA78, 0x4140, 0, 0x397D, 0, 0, 0, 0xCA79, - 0x6043, 0x6044, 0x6042, 0, 0, 0xCA7A, 0, 0, - 0, 0x3C6D, 0, 0, 0x4648, 0x3639, 0, 0, - 0, 0, 0, 0xCA7B, 0xCA7C, 0, 0, 0x6046, - 0x432C, 0x6045, 0xCA7D, 0xCA7E, 0x4F35, 0x4762, 0xCB21, 0, -}; -static const unsigned short utf8_to_euc_E78B_x0213[] = { - 0x776A, 0xF03E, 0x3638, 0x603D, 0x603F, 0, 0x603E, 0xCA73, - 0, 0xCA74, 0, 0, 0xF040, 0, 0x6040, 0, - 0x3851, 0, 0x6041, 0, 0, 0xCA76, 0xCA77, 0x3669, - 0xCA78, 0x4140, 0, 0x397D, 0, 0, 0, 0xCA79, - 0x6043, 0x6044, 0x6042, 0, 0, 0xCA7A, 0, 0, - 0, 0x3C6D, 0, 0, 0x4648, 0x3639, 0, 0, - 0, 0, 0, 0xF043, 0xCA7C, 0, 0, 0x6046, - 0x432C, 0x6045, 0xF044, 0x776B, 0x4F35, 0x4762, 0xCB21, 0, -}; -static const unsigned short utf8_to_euc_E78C[] = { - 0, 0, 0xCB22, 0, 0xCB23, 0xCB24, 0, 0xCB25, - 0, 0, 0x6049, 0xCB26, 0, 0xCB27, 0, 0, - 0, 0, 0xCB28, 0xCB29, 0, 0, 0x604B, 0x6048, - 0xCB2A, 0xCB2B, 0, 0x4C54, 0x604A, 0x604C, 0xCB2C, 0x4E44, - 0, 0, 0xCB2D, 0, 0xCB2E, 0x6050, 0, 0xCB2F, - 0xCB30, 0x604F, 0x4376, 0x472D, 0xCB31, 0, 0x3825, 0x604E, - 0, 0xCB32, 0xCB33, 0, 0x604D, 0xCB34, 0x4D31, 0x4D32, - 0, 0, 0xCB35, 0xCB36, 0, 0xCB37, 0x6051, 0x316E, -}; -static const unsigned short utf8_to_euc_E78C_x0213[] = { - 0, 0, 0xCB22, 0, 0xCB23, 0xCB24, 0, 0xF045, - 0, 0, 0x6049, 0xCB26, 0, 0xCB27, 0, 0, - 0, 0, 0xF046, 0xCB29, 0, 0, 0x604B, 0x6048, - 0xF047, 0xF048, 0, 0x4C54, 0x604A, 0x604C, 0xCB2C, 0x4E44, - 0, 0, 0xCB2D, 0, 0, 0x6050, 0, 0x776D, - 0x776E, 0x604F, 0x4376, 0x472D, 0xF04B, 0, 0x3825, 0x604E, - 0, 0xF04C, 0xCB33, 0xF04D, 0x604D, 0xCB34, 0x4D31, 0x4D32, - 0, 0xF04A, 0xCB35, 0xCB36, 0, 0xF04E, 0x6051, 0x316E, -}; -static const unsigned short utf8_to_euc_E78D[] = { - 0, 0, 0, 0xCB38, 0x3976, 0x3B62, 0, 0, - 0, 0, 0, 0, 0, 0xCB39, 0x6052, 0x6053, - 0xCB3A, 0, 0xCB3B, 0, 0, 0, 0xCB3C, 0x6055, - 0xCB3D, 0, 0, 0, 0, 0xCB3E, 0xCB3F, 0xCB40, - 0xCB41, 0, 0, 0x3D43, 0, 0, 0xCB42, 0xCB43, - 0x6057, 0xCB44, 0x6056, 0xCB45, 0xCB46, 0, 0xCB47, 0xCB48, - 0x6058, 0xCB49, 0x334D, 0, 0, 0x605A, 0, 0xCB4A, - 0x6059, 0xCB4B, 0x605C, 0x605B, 0xCB4C, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E78D_x0213[] = { - 0, 0, 0, 0xCB38, 0x3976, 0x3B62, 0, 0, - 0, 0, 0, 0, 0, 0xCB39, 0x6052, 0x6053, - 0x7770, 0, 0xF04F, 0, 0, 0, 0xCB3C, 0x6055, - 0xCB3D, 0, 0, 0, 0, 0xCB3E, 0xCB3F, 0xCB40, - 0xCB41, 0, 0, 0x3D43, 0, 0, 0x7771, 0xCB43, - 0x6057, 0xCB44, 0x6056, 0xF051, 0xF052, 0, 0xF054, 0xF055, - 0x6058, 0xF056, 0x334D, 0, 0, 0x605A, 0, 0xF057, - 0x6059, 0xCB4B, 0x605C, 0x605B, 0x7772, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E78E[] = { - 0xCB4D, 0xCB4E, 0, 0xCB4F, 0x383C, 0xCB50, 0xCB51, 0x4E28, - 0, 0x364C, 0, 0x3226, 0, 0, 0xCB52, 0, - 0xCB53, 0, 0, 0xCB54, 0, 0xCB55, 0x366A, 0xCB56, - 0xCB57, 0, 0, 0, 0xCB58, 0, 0xCB59, 0xCB5A, - 0xCB5B, 0, 0xCB5C, 0, 0, 0xCB5D, 0xCB5E, 0, - 0, 0x3461, 0xCB5F, 0xCB60, 0, 0xCB61, 0, 0, - 0, 0, 0x4E68, 0x605E, 0, 0xCB62, 0, 0xCB63, - 0, 0xCB64, 0, 0x6060, 0xCB65, 0xCB66, 0, 0xCB67, -}; -static const unsigned short utf8_to_euc_E78E_x0213[] = { - 0xCB4D, 0xF058, 0, 0xCB4F, 0x383C, 0xF059, 0xCB51, 0x4E28, - 0, 0x364C, 0xF05A, 0x3226, 0, 0, 0xCB52, 0, - 0xCB53, 0, 0, 0xCB54, 0xF05B, 0x7773, 0x366A, 0xCB56, - 0xF05C, 0, 0, 0, 0xF05D, 0, 0xF05E, 0x7774, - 0x7775, 0, 0x7776, 0, 0, 0xF05F, 0x7777, 0, - 0xF060, 0x3461, 0xCB5F, 0x7778, 0, 0xCB61, 0, 0, - 0, 0, 0x4E68, 0x605E, 0, 0xF061, 0, 0xF062, - 0, 0xF063, 0, 0x6060, 0xF064, 0, 0, 0xF065, -}; -static const unsigned short utf8_to_euc_E78F[] = { - 0x6061, 0, 0x3251, 0, 0, 0xCB68, 0xCB69, 0, - 0x605D, 0xCB6A, 0x3B39, 0xCB6B, 0xCB6C, 0x4441, 0x605F, 0xCB6D, - 0, 0, 0xCB6E, 0xCB6F, 0, 0, 0xCB70, 0, - 0, 0xCB71, 0, 0, 0, 0xCB72, 0x6064, 0, - 0x3C6E, 0xCB73, 0, 0xCB74, 0, 0x6062, 0xCB75, 0xCB76, - 0, 0xCB77, 0x373E, 0, 0, 0x4849, 0x6063, 0, - 0, 0x607E, 0, 0, 0xCB78, 0xCB79, 0, 0xCB7A, - 0x6069, 0xCB7B, 0xCB7C, 0xCB7D, 0, 0xCB7E, 0x383D, 0xCC21, -}; -static const unsigned short utf8_to_euc_E78F_x0213[] = { - 0x6061, 0, 0x3251, 0, 0, 0xF066, 0xCB69, 0, - 0x605D, 0x7779, 0x3B39, 0xF067, 0xCB6C, 0x4441, 0x605F, 0x777A, - 0, 0, 0, 0xCB6F, 0, 0, 0x777B, 0, - 0, 0x777C, 0, 0, 0, 0xCB72, 0x6064, 0, - 0x3C6E, 0xF068, 0, 0x777D, 0, 0x6062, 0xCB75, 0xF069, - 0, 0x777E, 0x373E, 0, 0, 0x4849, 0x6063, 0, - 0, 0x607E, 0, 0, 0xCB78, 0, 0, 0xCB7A, - 0x6069, 0xF06A, 0xF06C, 0xCB7D, 0, 0xCB7E, 0x383D, 0xCC21, -}; -static const unsigned short utf8_to_euc_E790[] = { - 0xCC22, 0xCC23, 0, 0x3565, 0xCC24, 0x6066, 0x4D7D, 0xCC25, - 0, 0x4E30, 0xCC26, 0, 0, 0, 0, 0, - 0, 0xCC27, 0, 0, 0, 0, 0, 0, - 0, 0, 0xCC28, 0xCC29, 0, 0, 0, 0, - 0, 0, 0x4276, 0, 0xCC2A, 0x6068, 0xCC2B, 0, - 0xCC2C, 0xCC2D, 0xCC2E, 0xCC2F, 0xCC30, 0xCC31, 0xCC32, 0xCC33, - 0xCC34, 0xCC35, 0x606A, 0x4E56, 0x3657, 0x487C, 0x474A, 0, - 0, 0xCC36, 0x606B, 0, 0, 0, 0, 0x606D, -}; -static const unsigned short utf8_to_euc_E790_x0213[] = { - 0xCC22, 0xF06D, 0, 0x3565, 0xCC24, 0x6066, 0x4D7D, 0x7821, - 0, 0x4E30, 0x7822, 0, 0, 0, 0, 0, - 0, 0xCC27, 0, 0xF06B, 0, 0, 0, 0, - 0, 0, 0x7823, 0x7824, 0, 0, 0, 0, - 0, 0, 0x4276, 0, 0xF06E, 0x6068, 0x7826, 0, - 0x7827, 0, 0x7828, 0x7829, 0x782A, 0xCC31, 0x782B, 0x782C, - 0x782D, 0xF06F, 0x606A, 0x4E56, 0x3657, 0x487C, 0x474A, 0, - 0, 0xF070, 0x606B, 0, 0, 0, 0, 0x606D, -}; -static const unsigned short utf8_to_euc_E791[] = { - 0xCC37, 0x6070, 0, 0xCC38, 0xCC39, 0, 0xCC3A, 0xCC3B, - 0, 0, 0, 0xCC3C, 0, 0xCC3D, 0, 0, - 0, 0xCC3E, 0xCC3F, 0, 0, 0x606C, 0, 0xCC40, - 0, 0x606F, 0x386A, 0x314D, 0x6071, 0xCC41, 0x3F70, 0x606E, - 0x4E5C, 0, 0xCC42, 0x6074, 0x7424, 0, 0xCC43, 0xCC44, - 0xCC45, 0x6072, 0x6075, 0xCC46, 0, 0xCC47, 0xCC48, 0x6067, - 0x6073, 0xCC49, 0xCC4A, 0x3A3C, 0, 0, 0x6076, 0, - 0, 0, 0, 0, 0, 0, 0x6077, 0, -}; -static const unsigned short utf8_to_euc_E791_x0213[] = { - 0xF072, 0x6070, 0, 0xF073, 0x782E, 0, 0x782F, 0x7830, - 0, 0, 0, 0x7831, 0, 0xF074, 0, 0, - 0, 0xCC3E, 0xF075, 0xF071, 0, 0x606C, 0, 0x7832, - 0, 0x606F, 0x386A, 0x314D, 0x6071, 0xF076, 0x3F70, 0x606E, - 0x4E5C, 0, 0x7833, 0x6074, 0x7424, 0, 0xCC43, 0xCC44, - 0xCC45, 0x6072, 0x6075, 0x7834, 0, 0x7835, 0xCC48, 0x6067, - 0x6073, 0xF077, 0xCC4A, 0x3A3C, 0, 0, 0x6076, 0, - 0, 0, 0, 0, 0, 0, 0x6077, 0, -}; -static const unsigned short utf8_to_euc_E792[] = { - 0xCC4B, 0xCC4C, 0, 0x4D7E, 0, 0xCC4D, 0xCC4E, 0xCC4F, - 0, 0xCC50, 0, 0x6078, 0, 0, 0, 0xCC51, - 0xCC52, 0xCC53, 0xCC54, 0, 0, 0, 0, 0, - 0xCC55, 0xCC56, 0xCC57, 0, 0xCC58, 0, 0x6079, 0xCC59, - 0xCC5A, 0xCC5B, 0x6065, 0xCC5C, 0, 0, 0xCC5D, 0x607A, - 0xCC5E, 0xCC5F, 0xCC60, 0xCC61, 0, 0, 0xCC62, 0xCC63, - 0x3444, 0xCC64, 0xCC65, 0, 0, 0xCC66, 0, 0, - 0, 0xCC67, 0, 0xCC68, 0, 0x3C25, 0, 0xCC69, -}; -static const unsigned short utf8_to_euc_E792_x0213[] = { - 0xCC4B, 0xF078, 0, 0x4D7E, 0, 0xF079, 0x7836, 0x7837, - 0xF07A, 0x7838, 0, 0x6078, 0, 0, 0, 0xCC51, - 0x783D, 0xCC53, 0xF07C, 0, 0, 0, 0, 0xF07D, - 0x7839, 0xF07E, 0xCC57, 0, 0x783A, 0, 0x6079, 0x783B, - 0xF121, 0xF122, 0x6065, 0x783C, 0, 0xF123, 0x783E, 0x607A, - 0x783F, 0x7840, 0xF124, 0xF125, 0, 0, 0xCC62, 0xCC63, - 0x3444, 0xCC64, 0xCC65, 0, 0, 0x7841, 0, 0, - 0, 0xF126, 0xF128, 0xF127, 0, 0x3C25, 0, 0x7842, -}; -static const unsigned short utf8_to_euc_E793[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0xCC6A, 0xCC6B, 0x607B, 0, 0xCC6C, 0, 0, 0x607C, - 0xCC6D, 0, 0, 0xCC6E, 0x607D, 0, 0, 0, - 0xCC6F, 0, 0xCC70, 0xCC71, 0x313B, 0, 0xCC72, 0xCC73, - 0x6121, 0, 0x493B, 0x6122, 0xCC74, 0, 0x3424, 0x6123, - 0xCC75, 0x6124, 0xCC76, 0xCC77, 0, 0, 0x6125, 0xCC78, - 0x6127, 0x6128, 0x6126, 0, 0xCC79, 0, 0x4953, 0x612A, - 0x6129, 0, 0xCC7A, 0xCC7B, 0xCC7C, 0, 0, 0xCC7D, -}; -static const unsigned short utf8_to_euc_E793_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0x7843, 0x7844, 0x607B, 0, 0xCC6C, 0, 0, 0x607C, - 0xCC6D, 0, 0, 0xCC6E, 0x607D, 0, 0xF129, 0, - 0xF12A, 0, 0x7845, 0xCC71, 0x313B, 0, 0xF12B, 0xCC73, - 0x6121, 0, 0x493B, 0x6122, 0xCC74, 0, 0x3424, 0x6123, - 0xCC75, 0x6124, 0xCC76, 0xF12D, 0, 0, 0x6125, 0xF12C, - 0x6127, 0x6128, 0x6126, 0, 0xCC79, 0, 0x4953, 0x612A, - 0x6129, 0, 0xF12F, 0xCC7B, 0xCC7C, 0, 0, 0x7846, -}; -static const unsigned short utf8_to_euc_E794[] = { - 0, 0xF450, 0, 0x612C, 0x612B, 0x612D, 0xCC7E, 0, - 0, 0, 0, 0, 0x612E, 0x6130, 0x612F, 0, - 0, 0x3979, 0xCD21, 0x6132, 0, 0x6131, 0xCD22, 0xCD23, - 0x3445, 0, 0x3F53, 0, 0x453C, 0, 0x6133, 0x4038, - 0xCD24, 0xCD25, 0, 0x3B3A, 0xCD26, 0x3179, 0x6134, 0xCD27, - 0x4D51, 0xCD28, 0xCD29, 0x4A63, 0x6135, 0, 0, 0xCD2A, - 0x4544, 0x4D33, 0x3943, 0x3F3D, 0, 0, 0xCD2B, 0x434B, - 0x5234, 0xCD2C, 0x442E, 0x3268, 0x6136, 0xCD2D, 0xCD2E, 0xCD2F, -}; -static const unsigned short utf8_to_euc_E794_x0213[] = { - 0, 0x7847, 0, 0x612C, 0x612B, 0x612D, 0xCC7E, 0, - 0, 0, 0, 0, 0x612E, 0x6130, 0x612F, 0, - 0, 0x3979, 0xCD21, 0x6132, 0, 0x6131, 0xCD22, 0x7848, - 0x3445, 0, 0x3F53, 0, 0x453C, 0, 0x6133, 0x4038, - 0xF131, 0xCD25, 0, 0x3B3A, 0xF132, 0x3179, 0x6134, 0xCD27, - 0x4D51, 0xCD28, 0xF133, 0x4A63, 0x6135, 0, 0, 0x7849, - 0x4544, 0x4D33, 0x3943, 0x3F3D, 0, 0, 0xCD2B, 0x434B, - 0x5234, 0xCD2C, 0x442E, 0x3268, 0x6136, 0xF136, 0xF137, 0xCD2F, -}; -static const unsigned short utf8_to_euc_E795[] = { - 0xCD30, 0, 0, 0xCD31, 0x6137, 0, 0x613C, 0xCD32, - 0xCD33, 0x613A, 0x6139, 0x5A42, 0x3326, 0x6138, 0xCD34, 0x305A, - 0xCD35, 0x482A, 0xCD36, 0, 0x484A, 0, 0, 0xCD37, - 0, 0x4E31, 0x613D, 0x613B, 0x435C, 0x4026, 0xCD38, 0xCD39, - 0x482B, 0xCD3A, 0x492D, 0, 0x613F, 0x4E2C, 0x374D, 0x6140, - 0, 0x613E, 0x4856, 0x6141, 0, 0x6142, 0, 0xCD3B, - 0x305B, 0xCD3C, 0, 0x3E76, 0x6147, 0, 0x6144, 0x466D, - 0x6143, 0xCD3D, 0xCD3E, 0xCD3F, 0xCD40, 0xCD41, 0xCD42, 0x3526, -}; -static const unsigned short utf8_to_euc_E795_x0213[] = { - 0xF138, 0, 0, 0xCD31, 0x6137, 0, 0x613C, 0xCD32, - 0xF139, 0x613A, 0x6139, 0x5A42, 0x3326, 0x6138, 0xF13A, 0x305A, - 0xF13B, 0x482A, 0xF13C, 0, 0x484A, 0, 0, 0xCD37, - 0, 0x4E31, 0x613D, 0x613B, 0x435C, 0x4026, 0xCD38, 0xCD39, - 0x482B, 0xCD3A, 0x492D, 0, 0x613F, 0x4E2C, 0x374D, 0x6140, - 0, 0x613E, 0x4856, 0x6141, 0xF13D, 0x6142, 0, 0x784A, - 0x305B, 0xF13F, 0xF13E, 0x3E76, 0x6147, 0, 0x6144, 0x466D, - 0x6143, 0x784B, 0xF140, 0xCD3F, 0xCD40, 0xF141, 0xF142, 0x3526, -}; -static const unsigned short utf8_to_euc_E796[] = { - 0, 0xCD43, 0x614A, 0, 0, 0xCD44, 0x6145, 0x6146, - 0, 0x6149, 0x6148, 0x4925, 0, 0, 0x4142, 0x4141, - 0xCD45, 0x353F, 0xCD46, 0xCD47, 0x614B, 0xCD48, 0, 0, - 0, 0xCD49, 0x614C, 0, 0xCD4A, 0x614D, 0, 0, - 0, 0, 0xCD4B, 0x614F, 0xCD4C, 0x614E, 0, 0, - 0, 0, 0, 0x3156, 0, 0, 0, 0, - 0, 0x6157, 0x4868, 0x6151, 0xCD4D, 0x6153, 0, 0, - 0x6155, 0x3F3E, 0xCD4E, 0, 0x6156, 0x6154, 0x3C40, 0xCD4F, -}; -static const unsigned short utf8_to_euc_E796_x0213[] = { - 0, 0xF143, 0x614A, 0, 0, 0xCD44, 0x6145, 0x6146, - 0, 0x6149, 0x6148, 0x4925, 0xF145, 0, 0x4142, 0x4141, - 0xCD45, 0x353F, 0x784C, 0xCD47, 0x614B, 0xCD48, 0, 0, - 0, 0xCD49, 0x614C, 0, 0xCD4A, 0x614D, 0, 0, - 0, 0, 0xF147, 0x614F, 0xCD4C, 0x614E, 0, 0, - 0, 0, 0, 0x3156, 0, 0, 0, 0, - 0xF149, 0x6157, 0x4868, 0x6151, 0xCD4D, 0x6153, 0, 0xF14A, - 0x6155, 0x3F3E, 0xCD4E, 0, 0x6156, 0x6154, 0x3C40, 0xF14B, -}; -static const unsigned short utf8_to_euc_E797[] = { - 0xCD50, 0xCD51, 0x6150, 0x6152, 0xCD52, 0x4942, 0xCD53, 0x3E49, - 0, 0, 0x6159, 0, 0xCD54, 0x6158, 0xCD55, 0xCD56, - 0, 0, 0x615A, 0, 0x3C26, 0x3A2F, 0, 0xCD57, - 0x4577, 0x615B, 0, 0x444B, 0xCD58, 0, 0x615D, 0xCD59, - 0xCD5A, 0xCD5B, 0x4E21, 0x615C, 0xCD5C, 0, 0, 0xCD5D, - 0, 0x4169, 0, 0, 0xCD5E, 0, 0xCD5F, 0xCD60, - 0x6162, 0xCD61, 0x6164, 0x6165, 0x4354, 0, 0, 0, - 0, 0xCD62, 0x6163, 0, 0x6160, 0, 0x615E, 0x615F, -}; -static const unsigned short utf8_to_euc_E797_x0213[] = { - 0xF14C, 0xCD51, 0x6150, 0x6152, 0xCD52, 0x4942, 0xF14D, 0x3E49, - 0, 0, 0x6159, 0, 0xCD54, 0x6158, 0x784E, 0xF14E, - 0, 0, 0x615A, 0xF14F, 0x3C26, 0x3A2F, 0, 0xCD57, - 0x4577, 0x615B, 0, 0x444B, 0xCD58, 0xF150, 0x615D, 0xF151, - 0xF152, 0xCD5B, 0x4E21, 0x615C, 0x784F, 0, 0, 0xF153, - 0, 0x4169, 0, 0, 0xF154, 0, 0xF155, 0xCD60, - 0x6162, 0xF156, 0x6164, 0x6165, 0x4354, 0, 0, 0, - 0, 0xF157, 0x6163, 0, 0x6160, 0, 0x615E, 0x615F, -}; -static const unsigned short utf8_to_euc_E798[] = { - 0xCD63, 0x6161, 0xCD64, 0xCD65, 0xCD66, 0, 0, 0xCD67, - 0xCD68, 0x6168, 0xCD69, 0x6166, 0xCD6A, 0x6167, 0, 0xCD6B, - 0, 0, 0xCD6C, 0xCD6D, 0, 0xCD6E, 0xCD6F, 0, - 0, 0xCD70, 0, 0xCD71, 0xCD72, 0xCD73, 0xCD74, 0x6169, - 0x616B, 0x616C, 0x616D, 0xCD75, 0x616E, 0xCD76, 0xCD77, 0x616A, - 0, 0xCD78, 0, 0, 0, 0xCD79, 0, 0, - 0x6170, 0, 0xCD7A, 0xCD7B, 0x616F, 0xCD7C, 0, 0, - 0xCD7D, 0xCD7E, 0xCE21, 0x6171, 0xCE22, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E798_x0213[] = { - 0x7850, 0x6161, 0x7851, 0xF158, 0xCD66, 0, 0, 0xF15A, - 0x7852, 0x6168, 0xCD69, 0x6166, 0xCD6A, 0x6167, 0, 0xF15B, - 0, 0, 0xCD6C, 0xF15E, 0, 0x7853, 0x7854, 0, - 0xF159, 0x7855, 0, 0xF15F, 0xF160, 0xCD73, 0x7856, 0x6169, - 0x616B, 0x616C, 0x616D, 0xCD75, 0x616E, 0xF162, 0x7E7D, 0x616A, - 0xF163, 0xCD78, 0, 0, 0, 0x7857, 0, 0, - 0x6170, 0, 0xCD7A, 0xF165, 0x616F, 0x7858, 0, 0, - 0xCD7D, 0xCD7E, 0xCE21, 0x6171, 0xF164, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E799[] = { - 0xCE24, 0xCE25, 0x4E45, 0xCE26, 0xCE27, 0xCE28, 0x6174, 0x6172, - 0x6173, 0xCE29, 0xCE23, 0xCE2A, 0x3462, 0, 0, 0, - 0, 0, 0x4C7E, 0, 0, 0xCE2B, 0x4A4A, 0, - 0x6176, 0xCE2C, 0, 0, 0x6175, 0, 0, 0xCE2D, - 0, 0x6177, 0x6178, 0, 0xCE2E, 0xCE2F, 0, 0x617C, - 0x6179, 0x617A, 0x617B, 0, 0x617D, 0xCE30, 0xCE31, 0xCE32, - 0x617E, 0xCE33, 0x6221, 0, 0xCE34, 0, 0x6222, 0, - 0x6223, 0, 0x482F, 0x4550, 0x6224, 0x4772, 0x4934, 0, -}; -static const unsigned short utf8_to_euc_E799_x0213[] = { - 0xCE24, 0xF168, 0x4E45, 0x7859, 0xCE27, 0xCE28, 0x6174, 0x6172, - 0x6173, 0xF16A, 0xCE23, 0x785A, 0x3462, 0, 0, 0, - 0, 0, 0x4C7E, 0, 0, 0xF16B, 0x4A4A, 0, - 0x6176, 0xCE2C, 0, 0, 0x6175, 0, 0, 0xCE2D, - 0, 0x6177, 0x6178, 0, 0x785B, 0x785C, 0, 0x617C, - 0x6179, 0x617A, 0x617B, 0, 0x617D, 0x785D, 0xF16D, 0x785E, - 0x617E, 0x785F, 0x6221, 0, 0xCE34, 0, 0x6222, 0, - 0x6223, 0, 0x482F, 0x4550, 0x6224, 0x4772, 0x4934, 0, -}; -static const unsigned short utf8_to_euc_E79A[] = { - 0x6225, 0xCE35, 0xF451, 0x6226, 0x452A, 0xCE36, 0x3327, 0x3944, - 0x6227, 0, 0, 0x6228, 0xCE37, 0xCE38, 0x6229, 0, - 0x3B29, 0, 0, 0x622B, 0, 0xCE39, 0x622A, 0, - 0, 0x622C, 0x622D, 0xCE3A, 0xCE3B, 0xCE3C, 0xF452, 0xCE3D, - 0xCE3E, 0, 0xCE3F, 0xCE40, 0xCE41, 0xCE42, 0xCE43, 0xCE44, - 0xCE45, 0, 0xCE46, 0, 0, 0xCE47, 0x4869, 0, - 0x622E, 0, 0, 0, 0x622F, 0, 0, 0x7369, - 0x6230, 0x6231, 0x6232, 0, 0, 0xCE48, 0, 0x3B2E, -}; -static const unsigned short utf8_to_euc_E79A_x0213[] = { - 0x6225, 0x7860, 0, 0x6226, 0x452A, 0xCE36, 0x3327, 0x3944, - 0x6227, 0, 0, 0x6228, 0xCE37, 0xCE38, 0x6229, 0, - 0x3B29, 0, 0, 0x622B, 0, 0xF16E, 0x622A, 0, - 0, 0x622C, 0x622D, 0x7861, 0xF16F, 0x7862, 0x7863, 0xCE3D, - 0xF171, 0xF170, 0xCE3F, 0xCE40, 0xCE41, 0xCE42, 0x7864, 0xF172, - 0xF173, 0, 0x7865, 0, 0, 0xCE47, 0x4869, 0xF174, - 0x622E, 0, 0, 0, 0x622F, 0, 0x7866, 0x7369, - 0x6230, 0x6231, 0x6232, 0, 0, 0xCE48, 0, 0x3B2E, -}; -static const unsigned short utf8_to_euc_E79B[] = { - 0, 0xCE49, 0x6233, 0x4756, 0, 0xCE4A, 0x4B5F, 0, - 0x314E, 0xCE4B, 0x3157, 0xCE4C, 0xCE4D, 0x6234, 0xCE4E, 0, - 0, 0, 0x6236, 0, 0xCE4F, 0, 0x6235, 0x4570, - 0, 0xCE50, 0, 0x4039, 0x5D39, 0, 0x6237, 0x4C41, - 0xCE51, 0x6238, 0, 0x3446, 0x4857, 0x6239, 0xCE52, 0x623A, - 0xCE53, 0, 0x623B, 0, 0xCE54, 0, 0x4C5C, 0, - 0xCE55, 0xCE56, 0x4C55, 0, 0x443E, 0, 0xCE57, 0, - 0x416A, 0xCE58, 0, 0x623D, 0xCE59, 0, 0x3D62, 0, -}; -static const unsigned short utf8_to_euc_E79B_x0213[] = { - 0, 0xCE49, 0x6233, 0x4756, 0, 0x7867, 0x4B5F, 0, - 0x314E, 0xF176, 0x3157, 0xCE4C, 0x7868, 0x6234, 0x7869, 0, - 0, 0, 0x6236, 0, 0x786A, 0, 0x6235, 0x4570, - 0, 0xCE50, 0, 0x4039, 0x5D39, 0, 0x6237, 0x4C41, - 0xCE51, 0x6238, 0, 0x3446, 0x4857, 0x6239, 0x786B, 0x623A, - 0xF178, 0, 0x623B, 0, 0xF179, 0, 0x4C5C, 0, - 0xCE55, 0x786C, 0x4C55, 0, 0x443E, 0, 0xCE57, 0, - 0x416A, 0xCE58, 0, 0x623D, 0x786D, 0, 0x3D62, 0, -}; -static const unsigned short utf8_to_euc_E79C[] = { - 0xCE5A, 0x3E4A, 0, 0, 0x6240, 0, 0xCE5B, 0x623F, - 0x623E, 0x487D, 0xCE5C, 0x3447, 0x3829, 0, 0xCE5D, 0, - 0, 0, 0xCE5E, 0, 0xCE5F, 0xCE60, 0, 0xCE61, - 0, 0xCE62, 0xCE63, 0x6246, 0xCE64, 0, 0x6243, 0x3F3F, - 0x4C32, 0, 0xCE65, 0, 0x6242, 0x6244, 0x6245, 0, - 0xCE66, 0x6241, 0, 0, 0, 0xCE67, 0xCE68, 0xCE69, - 0, 0, 0, 0, 0xCE6A, 0xCE6B, 0xCE6C, 0x6247, - 0x6248, 0xCE6D, 0x442F, 0, 0x3463, 0xCE6E, 0xCE6F, 0, -}; -static const unsigned short utf8_to_euc_E79C_x0213[] = { - 0xCE5A, 0x3E4A, 0, 0, 0x6240, 0, 0xCE5B, 0x623F, - 0x623E, 0x487D, 0x786E, 0x3447, 0x3829, 0, 0xCE5D, 0, - 0, 0, 0xCE5E, 0, 0xCE5F, 0xCE60, 0, 0xF17B, - 0, 0x786F, 0xF17C, 0x6246, 0xCE64, 0, 0x6243, 0x3F3F, - 0x4C32, 0, 0xCE65, 0, 0x6242, 0x6244, 0x6245, 0, - 0xCE66, 0x6241, 0, 0, 0, 0xF17D, 0xCE68, 0xCE69, - 0, 0, 0, 0, 0x7870, 0xF17E, 0x7871, 0x6247, - 0x6248, 0xCE6D, 0x442F, 0, 0x3463, 0xCE6E, 0xCE6F, 0, -}; -static const unsigned short utf8_to_euc_E79D[] = { - 0x4365, 0, 0xCE70, 0, 0, 0xCE71, 0xCE72, 0x6249, - 0, 0, 0xCE73, 0, 0, 0xCE74, 0xCE75, 0xCE76, - 0, 0, 0xCE77, 0, 0, 0, 0xCE78, 0xCE79, - 0, 0, 0x624A, 0x624D, 0xCE7A, 0, 0xCE7B, 0xCE7C, - 0xCE7D, 0x3F67, 0xCE7E, 0x4644, 0xCF21, 0x624E, 0x4B53, 0xCF22, - 0x624B, 0, 0xCF23, 0x624C, 0xCF24, 0, 0, 0, - 0xCF25, 0, 0xCF26, 0xCF27, 0xCF28, 0, 0, 0, - 0, 0x6251, 0xCF29, 0, 0, 0xCF2A, 0x6250, 0x624F, -}; -static const unsigned short utf8_to_euc_E79D_x0213[] = { - 0x4365, 0, 0xCE70, 0, 0, 0xCE71, 0x7872, 0x6249, - 0, 0, 0xCE73, 0, 0, 0x7873, 0x7874, 0xCE76, - 0, 0, 0xCE77, 0, 0, 0, 0xCE78, 0xCE79, - 0xF225, 0, 0x624A, 0x624D, 0x7875, 0, 0xCE7B, 0x7876, - 0xF226, 0x3F67, 0x7877, 0x4644, 0xCF21, 0x624E, 0x4B53, 0xCF22, - 0x624B, 0, 0xF227, 0x624C, 0xCF24, 0, 0, 0, - 0xCF25, 0, 0xF229, 0xCF27, 0xCF28, 0, 0, 0, - 0, 0x6251, 0x7878, 0, 0xF22A, 0xF22B, 0x6250, 0x624F, -}; -static const unsigned short utf8_to_euc_E79E[] = { - 0xCF2B, 0, 0, 0, 0xCF2C, 0, 0, 0, - 0, 0, 0, 0x6253, 0xCF2D, 0xCF2E, 0x6252, 0, - 0, 0x6254, 0, 0, 0xCF2F, 0xCF30, 0xCF31, 0, - 0, 0, 0xCF32, 0, 0, 0, 0x6256, 0xCF33, - 0x6255, 0, 0xCF34, 0, 0, 0x4A4D, 0, 0xCF35, - 0, 0, 0xCF36, 0, 0x3D56, 0x4E46, 0xCF37, 0xCF38, - 0x6257, 0xCF39, 0, 0x4637, 0, 0xCF3A, 0x6258, 0, - 0, 0x6259, 0, 0x625D, 0x625B, 0x625C, 0xCF3B, 0x625A, -}; -static const unsigned short utf8_to_euc_E79E_x0213[] = { - 0x7879, 0, 0, 0, 0xCF2C, 0, 0, 0, - 0, 0, 0, 0x6253, 0xCF2D, 0xCF2E, 0x6252, 0, - 0, 0x6254, 0, 0, 0x787A, 0xCF30, 0xCF31, 0, - 0, 0, 0xF22E, 0, 0, 0, 0x6256, 0xF22F, - 0x6255, 0, 0xF230, 0, 0xF231, 0x4A4D, 0, 0xCF35, - 0, 0xF232, 0x787B, 0, 0x3D56, 0x4E46, 0xCF37, 0xCF38, - 0x6257, 0xCF39, 0, 0x4637, 0, 0xCF3A, 0x6258, 0, - 0, 0x6259, 0, 0x625D, 0x625B, 0x625C, 0xCF3B, 0x625A, -}; -static const unsigned short utf8_to_euc_E79F[] = { - 0, 0, 0, 0xCF3C, 0, 0, 0, 0x625E, - 0, 0xCF3D, 0, 0, 0, 0x625F, 0, 0, - 0, 0xCF3E, 0xCF3F, 0, 0, 0xCF40, 0, 0x6260, - 0, 0xCF41, 0x6261, 0x4C37, 0x6262, 0, 0xCF42, 0xCF43, - 0xCF44, 0, 0x4C70, 0x6263, 0xCF45, 0x434E, 0xCF46, 0x476A, - 0, 0x366B, 0xCF47, 0, 0xCF48, 0x433B, 0x6264, 0x363A, - 0xCF49, 0xCF4A, 0, 0x4050, 0xCF4B, 0, 0, 0, - 0xCF4C, 0, 0, 0xCF4D, 0x6265, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E79F_x0213[] = { - 0, 0, 0, 0xCF3C, 0, 0, 0, 0x625E, - 0, 0xCF3D, 0, 0, 0, 0x625F, 0, 0, - 0, 0xCF3E, 0xCF3F, 0, 0, 0xCF40, 0, 0x6260, - 0, 0xCF41, 0x6261, 0x4C37, 0x6262, 0, 0xF233, 0xF234, - 0x787C, 0, 0x4C70, 0x6263, 0xF235, 0x434E, 0xF236, 0x476A, - 0, 0x366B, 0xF237, 0, 0xF238, 0x433B, 0x6264, 0x363A, - 0xF23A, 0xCF4A, 0, 0x4050, 0xF23B, 0, 0, 0, - 0xCF4C, 0, 0, 0xF23C, 0x6265, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7A0[] = { - 0, 0, 0x3A3D, 0, 0, 0xCF4E, 0xCF4F, 0, - 0, 0xCF50, 0, 0, 0x6266, 0xCF51, 0xCF52, 0, - 0, 0xCF53, 0x6267, 0, 0x3826, 0x3A55, 0, 0, - 0, 0, 0, 0, 0, 0xCF54, 0, 0, - 0x6269, 0xCF55, 0xCF56, 0xCF57, 0, 0x4556, 0x3A56, 0x354E, - 0, 0, 0, 0, 0, 0xCF58, 0xCF59, 0, - 0xCF5A, 0, 0x4B24, 0, 0x474B, 0xCF5B, 0, 0xCF5C, - 0, 0, 0x4557, 0, 0, 0, 0, 0x395C, -}; -static const unsigned short utf8_to_euc_E7A0_x0213[] = { - 0, 0, 0x3A3D, 0, 0, 0xF23E, 0xF23F, 0, - 0, 0xF240, 0, 0, 0x6266, 0xF241, 0xCF52, 0, - 0, 0xCF53, 0x6267, 0, 0x3826, 0x3A55, 0, 0, - 0, 0xF242, 0, 0, 0, 0xCF54, 0, 0, - 0x6269, 0xF243, 0xCF56, 0xCF57, 0, 0x4556, 0x3A56, 0x354E, - 0, 0, 0, 0, 0xF244, 0x787D, 0xCF59, 0, - 0xCF5A, 0, 0x4B24, 0, 0x474B, 0xCF5B, 0, 0xCF5C, - 0, 0, 0x4557, 0, 0, 0, 0, 0x395C, -}; -static const unsigned short utf8_to_euc_E7A1[] = { - 0, 0, 0, 0xCF5D, 0xCF5E, 0x626B, 0, 0xCF5F, - 0xCF60, 0, 0, 0, 0xCF61, 0, 0xCF62, 0, - 0, 0, 0xCF63, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xCF64, 0x3E4B, 0xCF65, 0, - 0xCF66, 0xCF67, 0, 0xCF68, 0xCF69, 0, 0, 0, - 0xCF6A, 0, 0xCF6B, 0x4E32, 0x3945, 0, 0xCF6C, 0x3827, - 0, 0, 0x4823, 0, 0x626D, 0, 0, 0, - 0, 0, 0xCF6D, 0, 0x626F, 0, 0xCF6E, 0, -}; -static const unsigned short utf8_to_euc_E7A1_x0213[] = { - 0, 0, 0, 0x7921, 0xCF5E, 0x626B, 0, 0xF245, - 0xCF60, 0, 0, 0, 0xCF61, 0, 0x7922, 0x7923, - 0, 0x7924, 0xCF63, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xCF64, 0x3E4B, 0xCF65, 0, - 0xCF66, 0xCF67, 0, 0xCF68, 0xF246, 0, 0, 0, - 0x7925, 0, 0xF247, 0x4E32, 0x3945, 0, 0x7926, 0x3827, - 0, 0, 0x4823, 0, 0x626D, 0, 0, 0, - 0, 0, 0, 0, 0x626F, 0, 0xCF6E, 0, -}; -static const unsigned short utf8_to_euc_E7A2[] = { - 0, 0x386B, 0, 0, 0, 0, 0x626E, 0x4476, - 0, 0, 0xCF6F, 0, 0x6271, 0x3337, 0x626C, 0xCF70, - 0, 0x486A, 0, 0x3130, 0xCF71, 0x3A6C, 0, 0x4F52, - 0xCF72, 0, 0x6270, 0, 0, 0xCF74, 0xCF75, 0xCF76, - 0, 0xCF73, 0, 0x6272, 0xCF77, 0, 0, 0x4A4B, - 0xCF78, 0x4059, 0x6274, 0, 0xCF79, 0xCF7A, 0, 0x6275, - 0xCF7B, 0xCF7C, 0xCF7D, 0xCF7E, 0, 0x6273, 0, 0, - 0, 0, 0x334E, 0xD021, 0x627B, 0xD022, 0x627A, 0xD023, -}; -static const unsigned short utf8_to_euc_E7A2_x0213[] = { - 0, 0x386B, 0, 0, 0, 0, 0x626E, 0x4476, - 0, 0, 0xF249, 0, 0x6271, 0x3337, 0x626C, 0xCF70, - 0, 0x486A, 0, 0x3130, 0xF24A, 0x3A6C, 0, 0x4F52, - 0xCF72, 0, 0x6270, 0, 0, 0xF24C, 0xF24D, 0xF24E, - 0, 0xCF73, 0, 0x6272, 0xF24B, 0, 0, 0x4A4B, - 0xCF78, 0x4059, 0x6274, 0, 0xCF79, 0x792A, 0, 0x6275, - 0x7928, 0xCF7C, 0xCF7D, 0xCF7E, 0, 0x6273, 0, 0, - 0, 0, 0x334E, 0xF24F, 0x627B, 0xD022, 0x627A, 0xD023, -}; -static const unsigned short utf8_to_euc_E7A3[] = { - 0, 0x3C27, 0, 0, 0, 0x627C, 0x6277, 0xD024, - 0xD025, 0xD026, 0x627D, 0x6278, 0xD027, 0, 0xD028, 0, - 0x4858, 0x6276, 0xD029, 0xD02A, 0x6279, 0xD02B, 0xD02C, 0, - 0, 0, 0x6322, 0xD02E, 0, 0, 0, 0xD02F, - 0xD030, 0xD031, 0, 0, 0xD02D, 0, 0xD032, 0x6321, - 0x4B61, 0, 0xD033, 0, 0x627E, 0, 0, 0x306B, - 0, 0, 0xD034, 0xD035, 0x6324, 0, 0xD037, 0xD038, - 0, 0, 0xD039, 0xD03A, 0, 0x6323, 0, 0xD03B, -}; -static const unsigned short utf8_to_euc_E7A3_x0213[] = { - 0, 0x3C27, 0, 0, 0, 0x627C, 0x6277, 0xD024, - 0xF250, 0xD026, 0x627D, 0x6278, 0xF251, 0, 0xF252, 0, - 0x4858, 0x6276, 0xD029, 0xD02A, 0x6279, 0xF253, 0xD02C, 0, - 0, 0, 0x6322, 0xD02E, 0, 0, 0, 0xD02F, - 0xF254, 0xF255, 0, 0, 0x792B, 0, 0xF256, 0x6321, - 0x4B61, 0, 0xD033, 0, 0x627E, 0, 0, 0x306B, - 0, 0, 0x792C, 0xD035, 0x6324, 0, 0xD037, 0x792E, - 0, 0xF257, 0xF258, 0xF259, 0, 0x6323, 0xF25A, 0xD03B, -}; -static const unsigned short utf8_to_euc_E7A4[] = { - 0xD036, 0x3E4C, 0, 0, 0, 0, 0xD03C, 0x6325, - 0, 0, 0, 0, 0xD03D, 0, 0x4143, 0, - 0xD03E, 0x6327, 0x6326, 0, 0, 0, 0, 0, - 0, 0x6328, 0xD03F, 0, 0xD040, 0, 0xD041, 0xD042, - 0xD043, 0, 0, 0, 0, 0xD044, 0x6268, 0xD045, - 0, 0xD046, 0x626A, 0x632A, 0x6329, 0xD047, 0, 0, - 0xF454, 0xD048, 0, 0, 0xD049, 0xD04A, 0, 0, - 0, 0, 0x3C28, 0xD04B, 0x4E69, 0xD04C, 0x3C52, 0xD04D, -}; -static const unsigned short utf8_to_euc_E7A4_x0213[] = { - 0x792D, 0x3E4C, 0, 0, 0, 0, 0xD03C, 0x6325, - 0, 0, 0, 0, 0xD03D, 0, 0x4143, 0, - 0xF25C, 0x6327, 0x6326, 0, 0, 0, 0, 0, - 0, 0x6328, 0xD03F, 0xF25D, 0x792F, 0, 0xD041, 0xD042, - 0xD043, 0, 0, 0, 0, 0xF25F, 0x6268, 0xD045, - 0, 0xD046, 0x626A, 0x632A, 0x6329, 0xD047, 0x7930, 0, - 0xF25E, 0x7931, 0, 0, 0x7932, 0xD04A, 0, 0, - 0, 0, 0x3C28, 0xF260, 0x4E69, 0xD04C, 0x3C52, 0xD04D, -}; -static const unsigned short utf8_to_euc_E7A5[] = { - 0x632B, 0x3737, 0, 0, 0xD04E, 0xD04F, 0xD050, 0x3540, - 0x3527, 0x3B63, 0xD051, 0xD052, 0, 0, 0, 0xD053, - 0x4D34, 0xD054, 0, 0x6331, 0xD055, 0x6330, 0x4144, 0x632D, - 0xD056, 0, 0x632F, 0xD057, 0xD058, 0x3D4B, 0x3F40, 0x632E, - 0x632C, 0, 0x472A, 0, 0, 0x3E4D, 0, 0xD059, - 0x493C, 0xD05A, 0, 0xD05B, 0, 0x3A57, 0, 0, - 0, 0, 0xD05C, 0, 0, 0, 0, 0x4578, - 0, 0xD05D, 0x6332, 0xD05E, 0xD05F, 0, 0xD060, 0x6333, -}; -static const unsigned short utf8_to_euc_E7A5_x0213[] = { - 0x632B, 0x3737, 0, 0, 0xD04E, 0x7935, 0x7936, 0x3540, - 0x3527, 0x3B63, 0xF261, 0xD052, 0, 0, 0, 0xD053, - 0x4D34, 0xD054, 0, 0x6331, 0xD055, 0x6330, 0x4144, 0x632D, - 0xF262, 0, 0x632F, 0xF263, 0x793A, 0x3D4B, 0x3F40, 0x632E, - 0x632C, 0, 0x472A, 0, 0, 0x3E4D, 0, 0xF265, - 0x493C, 0xD05A, 0, 0xD05B, 0, 0x3A57, 0, 0, - 0, 0, 0xF266, 0, 0, 0, 0, 0x4578, - 0, 0x793E, 0x6332, 0xD05E, 0xD05F, 0, 0xD060, 0x6333, -}; -static const unsigned short utf8_to_euc_E7A6[] = { - 0x6349, 0x3658, 0, 0, 0x4F3D, 0x4135, 0, 0, - 0, 0, 0x6334, 0xD061, 0xD062, 0x3252, 0x4477, 0x4A21, - 0, 0xD063, 0, 0xD064, 0xD065, 0xD066, 0xD067, 0, - 0xD068, 0, 0, 0xD069, 0xD06A, 0x6335, 0, 0, - 0, 0xD06B, 0, 0, 0, 0, 0x357A, 0x6336, - 0xD06C, 0xD06D, 0x6338, 0xD06E, 0, 0, 0x6339, 0xD06F, - 0x4729, 0xD070, 0, 0x633A, 0xD071, 0, 0, 0, - 0xD072, 0x633B, 0x633C, 0xD073, 0, 0x3659, 0x3253, 0x4645, -}; -static const unsigned short utf8_to_euc_E7A6_x0213[] = { - 0x6349, 0x3658, 0, 0, 0x4F3D, 0x4135, 0, 0, - 0, 0, 0x6334, 0xD061, 0xD062, 0x3252, 0x4477, 0x4A21, - 0, 0xD063, 0, 0xD064, 0xF267, 0xF268, 0xF269, 0, - 0x7942, 0, 0, 0xF26A, 0xD06A, 0x6335, 0, 0, - 0, 0xF26B, 0, 0, 0, 0, 0x357A, 0x6336, - 0xD06C, 0xF26C, 0x6338, 0xD06E, 0, 0, 0x6339, 0xD06F, - 0x4729, 0x7943, 0, 0x633A, 0xF26D, 0, 0, 0, - 0x7944, 0x633B, 0x633C, 0xF26E, 0, 0x3659, 0x3253, 0x4645, -}; -static const unsigned short utf8_to_euc_E7A7[] = { - 0x3D28, 0x3B64, 0xD074, 0, 0xD075, 0, 0, 0xD076, - 0xD077, 0x633D, 0xD078, 0x3D29, 0, 0, 0, 0xD079, - 0, 0x324A, 0x4943, 0, 0xD07A, 0x633E, 0xD07B, 0, - 0x486B, 0, 0xD07C, 0, 0, 0xD07D, 0xD07E, 0x4145, - 0xD121, 0x6341, 0xD122, 0x6342, 0x4769, 0xD123, 0x3F41, 0x633F, - 0, 0x4361, 0xD124, 0xD125, 0x6340, 0xD126, 0, 0, - 0x3E4E, 0xD127, 0, 0, 0, 0, 0, 0, - 0xD128, 0, 0, 0x305C, 0xD129, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7A7_x0213[] = { - 0x3D28, 0x3B64, 0xF26F, 0, 0xD075, 0, 0, 0xF270, - 0x7945, 0x633D, 0x7946, 0x3D29, 0xF271, 0xF272, 0, 0xD079, - 0, 0x324A, 0x4943, 0, 0x7948, 0x633E, 0xF273, 0, - 0x486B, 0, 0xD07C, 0, 0, 0xD07D, 0x7949, 0x4145, - 0xD121, 0x6341, 0xD122, 0x6342, 0x4769, 0xD123, 0x3F41, 0x633F, - 0, 0x4361, 0xD124, 0x794A, 0x6340, 0x794B, 0, 0, - 0x3E4E, 0xD127, 0, 0, 0, 0, 0, 0, - 0xD128, 0, 0, 0x305C, 0xD129, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7A8[] = { - 0x3529, 0, 0xD12A, 0xD12B, 0, 0, 0, 0xD12C, - 0x6343, 0xD12D, 0xD12E, 0x4478, 0xD12F, 0x6344, 0x4047, 0, - 0, 0xD130, 0, 0, 0x4C2D, 0xD131, 0, 0x4923, - 0x6345, 0x6346, 0x4355, 0xD132, 0x4E47, 0, 0xD133, 0x6348, - 0x6347, 0xD134, 0, 0, 0, 0, 0, 0xD135, - 0, 0, 0, 0xD136, 0, 0xD137, 0x3C6F, 0xD138, - 0xD139, 0x634A, 0x3070, 0, 0xD13A, 0xD13B, 0, 0x634D, - 0xD13C, 0xD13D, 0xD13E, 0x634B, 0x3254, 0x374E, 0x634C, 0x3946, -}; -static const unsigned short utf8_to_euc_E7A8_x0213[] = { - 0x3529, 0, 0xD12A, 0x794C, 0, 0, 0, 0xD12C, - 0x6343, 0xD12D, 0xF278, 0x4478, 0xD12F, 0x6344, 0x4047, 0, - 0, 0xF279, 0, 0, 0x4C2D, 0xF27A, 0, 0x4923, - 0x6345, 0x6346, 0x4355, 0xF27B, 0x4E47, 0, 0xF27C, 0x6348, - 0x6347, 0xD134, 0, 0, 0, 0, 0, 0xD135, - 0, 0, 0, 0xD136, 0, 0xF27E, 0x3C6F, 0xD138, - 0xD139, 0x634A, 0x3070, 0, 0xD13A, 0xD13B, 0, 0x634D, - 0xF321, 0x794E, 0xD13E, 0x634B, 0x3254, 0x374E, 0x634C, 0x3946, -}; -static const unsigned short utf8_to_euc_E7A9[] = { - 0x3972, 0, 0x4A66, 0x634E, 0xD13F, 0xD140, 0x4B54, 0xD141, - 0xD142, 0x6350, 0, 0, 0xD143, 0x4051, 0x314F, 0x323A, - 0x302C, 0, 0, 0, 0, 0xD144, 0xD145, 0x634F, - 0, 0xD146, 0, 0, 0xD147, 0xD148, 0, 0xD149, - 0xD14A, 0x6351, 0x6352, 0x3E77, 0, 0xD14B, 0, 0xD14C, - 0, 0x6353, 0xD14D, 0x334F, 0, 0xD14E, 0, 0, - 0x6355, 0, 0, 0, 0x376A, 0xD14F, 0x3566, 0, - 0xD150, 0x6356, 0x3675, 0, 0, 0x6357, 0xD151, 0x407C, -}; -static const unsigned short utf8_to_euc_E7A9_x0213[] = { - 0x3972, 0, 0x4A66, 0x634E, 0xD13F, 0xD140, 0x4B54, 0xF322, - 0xD142, 0x6350, 0, 0, 0xF323, 0x4051, 0x314F, 0x323A, - 0x302C, 0, 0, 0, 0, 0xD144, 0xF324, 0x634F, - 0, 0xF325, 0, 0, 0xF326, 0x794F, 0, 0xF327, - 0xF328, 0x6351, 0x6352, 0x3E77, 0, 0xD14B, 0, 0xF329, - 0, 0x6353, 0xF32A, 0x334F, 0, 0x7950, 0, 0, - 0x6355, 0, 0, 0, 0x376A, 0xF32B, 0x3566, 0, - 0xF32C, 0x6356, 0x3675, 0, 0, 0x6357, 0xD151, 0x407C, -}; -static const unsigned short utf8_to_euc_E7AA[] = { - 0xD152, 0x464D, 0xD153, 0x4060, 0x3A75, 0xD154, 0xD155, 0, - 0x6358, 0, 0xD156, 0xD157, 0, 0, 0, 0, - 0xD158, 0xD159, 0x4362, 0x416B, 0xD15A, 0x635A, 0x635C, 0x6359, - 0x635B, 0, 0, 0, 0, 0, 0xD15B, 0x3722, - 0xD15C, 0, 0, 0xD15D, 0, 0, 0, 0, - 0, 0x635D, 0x3726, 0, 0xD15E, 0, 0x3567, 0x4D52, - 0x635F, 0, 0, 0xD15F, 0, 0xD160, 0x6360, 0, - 0, 0xD161, 0x312E, 0xD162, 0xD163, 0, 0, 0x6363, -}; -static const unsigned short utf8_to_euc_E7AA_x0213[] = { - 0xD152, 0x464D, 0xF32D, 0x4060, 0x3A75, 0x7952, 0xD155, 0, - 0x6358, 0, 0xF32E, 0xD157, 0, 0, 0, 0, - 0xF32F, 0xD159, 0x4362, 0x416B, 0xD15A, 0x635A, 0x635C, 0x6359, - 0x635B, 0, 0, 0, 0, 0, 0xD15B, 0x3722, - 0x7953, 0, 0, 0xF330, 0, 0, 0, 0, - 0, 0x635D, 0x3726, 0, 0xF331, 0, 0x3567, 0x4D52, - 0x635F, 0, 0, 0x7955, 0, 0xD160, 0x6360, 0, - 0, 0xF334, 0x312E, 0x7956, 0xF335, 0, 0xF336, 0x6363, -}; -static const unsigned short utf8_to_euc_E7AB[] = { - 0, 0, 0, 0x3376, 0x6362, 0x6361, 0xD164, 0x6365, - 0x635E, 0xD165, 0x6366, 0x4E29, 0xD166, 0x6367, 0xD167, 0x6368, - 0, 0xD168, 0x5474, 0x636A, 0, 0x6369, 0, 0, - 0, 0x636B, 0x636C, 0xD169, 0x4E35, 0x636D, 0, 0x706F, - 0x3E4F, 0x636E, 0x636F, 0x3D57, 0, 0x4638, 0x6370, 0xF459, - 0xD16A, 0xD16B, 0x4328, 0xD16C, 0xD16D, 0x6371, 0, 0x433C, - 0x6372, 0xD16E, 0, 0, 0xD16F, 0, 0x3625, 0, - 0x513F, 0x435D, 0x3C33, 0xD170, 0, 0xD171, 0xD172, 0x3448, -}; -static const unsigned short utf8_to_euc_E7AB_x0213[] = { - 0, 0, 0, 0x3376, 0x6362, 0x6361, 0xD164, 0x6365, - 0x635E, 0xD165, 0x6366, 0x4E29, 0xF338, 0x6367, 0x7957, 0x6368, - 0, 0xF339, 0x5474, 0x636A, 0, 0x6369, 0, 0, - 0, 0x636B, 0x636C, 0xD169, 0x4E35, 0x636D, 0, 0x706F, - 0x3E4F, 0x636E, 0x636F, 0x3D57, 0, 0x4638, 0x6370, 0xF33A, - 0xF33B, 0xD16B, 0x4328, 0x7958, 0xD16D, 0x6371, 0, 0x433C, - 0x6372, 0xD16E, 0, 0, 0xF33C, 0, 0x3625, 0, - 0x513F, 0x435D, 0x3C33, 0xD170, 0, 0x7959, 0xD172, 0x3448, -}; -static const unsigned short utf8_to_euc_E7AC[] = { - 0, 0, 0x6373, 0, 0x6422, 0, 0x6376, 0xD173, - 0x3568, 0, 0x6375, 0x6424, 0, 0, 0, 0x6374, - 0, 0x3E50, 0, 0, 0xD174, 0, 0, 0, - 0x6378, 0x6379, 0, 0x452B, 0, 0, 0x637A, 0xD175, - 0x335E, 0, 0, 0xD176, 0, 0x3F5A, 0x4964, 0xD177, - 0x637C, 0xD178, 0xD179, 0xD17A, 0x4268, 0xD17B, 0xD17C, 0xD17D, - 0xD17E, 0xD221, 0, 0x6377, 0xD222, 0x637B, 0x637D, 0, - 0, 0x3A7B, 0, 0, 0, 0xD223, 0, 0xD224, -}; -static const unsigned short utf8_to_euc_E7AC_x0213[] = { - 0, 0, 0x6373, 0, 0x6422, 0, 0x6376, 0xF33F, - 0x3568, 0, 0x6375, 0x6424, 0, 0, 0, 0x6374, - 0, 0x3E50, 0x795A, 0, 0xD174, 0, 0, 0, - 0x6378, 0x6379, 0, 0x452B, 0, 0, 0x637A, 0xD175, - 0x335E, 0, 0, 0xD176, 0, 0x3F5A, 0x4964, 0xF342, - 0x637C, 0xD178, 0xF343, 0xD17A, 0x4268, 0x795B, 0xF344, 0xF345, - 0xD17E, 0xF346, 0, 0x6377, 0xD222, 0x637B, 0x637D, 0, - 0, 0x3A7B, 0, 0x795C, 0, 0xF341, 0, 0xD224, -}; -static const unsigned short utf8_to_euc_E7AD[] = { - 0xD225, 0xD226, 0, 0, 0, 0x6426, 0x492E, 0xD227, - 0x4826, 0x4579, 0, 0x365A, 0x6425, 0x6423, 0xD228, 0x4835, - 0x637E, 0x435E, 0x457B, 0, 0x457A, 0xD229, 0x3A76, 0, - 0, 0, 0, 0, 0, 0x6438, 0, 0, - 0xD22A, 0, 0, 0, 0xD22B, 0x6428, 0xD22C, 0x642A, - 0, 0xD22D, 0xD22E, 0, 0x642D, 0xD22F, 0x642E, 0xD230, - 0x642B, 0x642C, 0xD231, 0xD232, 0x6429, 0x6427, 0, 0xD233, - 0, 0, 0x6421, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7AD_x0213[] = { - 0xD225, 0xF34A, 0, 0, 0, 0x6426, 0x492E, 0x795D, - 0x4826, 0x4579, 0, 0x365A, 0x6425, 0x6423, 0x795E, 0x4835, - 0x637E, 0x435E, 0x457B, 0, 0x457A, 0xF34C, 0x3A76, 0, - 0, 0, 0, 0, 0, 0x6438, 0, 0, - 0x795F, 0, 0, 0, 0xF34E, 0x6428, 0xF34F, 0x642A, - 0, 0xF350, 0xD22E, 0, 0x642D, 0x7960, 0x642E, 0x7961, - 0x642B, 0x642C, 0x7962, 0xF351, 0x6429, 0x6427, 0, 0xD233, - 0, 0xF34D, 0x6421, 0, 0, 0, 0, 0xF349, -}; -static const unsigned short utf8_to_euc_E7AE[] = { - 0, 0, 0, 0, 0xD234, 0, 0x4A4F, 0x3255, - 0, 0xD235, 0, 0x6435, 0, 0x6432, 0xD236, 0x6437, - 0xD237, 0xD238, 0x6436, 0, 0x4773, 0x4C27, 0xD239, 0x3B3B, - 0x6430, 0x6439, 0x6434, 0xD23A, 0x6433, 0x642F, 0xD23B, 0x6431, - 0xD23C, 0x3449, 0, 0, 0, 0xD23D, 0, 0, - 0, 0, 0x433D, 0, 0xD23E, 0x407D, 0, 0xD23F, - 0xD240, 0x4822, 0xD241, 0, 0x643E, 0xD242, 0xD243, 0, - 0x4824, 0, 0xD244, 0xD245, 0xD246, 0xD247, 0, 0, -}; -static const unsigned short utf8_to_euc_E7AE_x0213[] = { - 0, 0, 0, 0, 0xD234, 0, 0x4A4F, 0x3255, - 0, 0xD235, 0, 0x6435, 0, 0x6432, 0xD236, 0x6437, - 0xF354, 0xF355, 0x6436, 0, 0x4773, 0x4C27, 0xD239, 0x3B3B, - 0x6430, 0x6439, 0x6434, 0xF356, 0x6433, 0x642F, 0x7963, 0x6431, - 0xD23C, 0x3449, 0, 0, 0, 0xD23D, 0, 0, - 0, 0, 0x433D, 0, 0xD23E, 0x407D, 0, 0xF358, - 0xD240, 0x4822, 0xD241, 0, 0x643E, 0xF359, 0xD243, 0, - 0x4824, 0, 0xD244, 0xD245, 0xF35A, 0xD247, 0, 0, -}; -static const unsigned short utf8_to_euc_E7AF[] = { - 0x4061, 0x643B, 0xD248, 0, 0x484F, 0xD249, 0x643F, 0x4A53, - 0xD24A, 0x435B, 0xD24B, 0x643A, 0x643C, 0, 0, 0x643D, - 0, 0, 0, 0, 0xD24C, 0, 0xD24D, 0xD24E, - 0, 0xD24F, 0xD250, 0xD251, 0, 0x6440, 0, 0, - 0x3C44, 0, 0, 0, 0x4646, 0x6445, 0x6444, 0, - 0xD252, 0x6441, 0xD253, 0, 0, 0x4F36, 0, 0, - 0, 0, 0xD254, 0x644A, 0xD255, 0xD256, 0x644E, 0x644B, - 0xD257, 0xD258, 0xD259, 0, 0xD25A, 0, 0xD25B, 0, -}; -static const unsigned short utf8_to_euc_E7AF_x0213[] = { - 0x4061, 0x643B, 0xD248, 0, 0x484F, 0xF35B, 0x643F, 0x4A53, - 0xD24A, 0x435B, 0xF35C, 0x643A, 0x643C, 0, 0, 0x643D, - 0, 0, 0, 0, 0xF35F, 0, 0xF360, 0x7965, - 0, 0x7966, 0xF361, 0xD251, 0, 0x6440, 0, 0, - 0x3C44, 0, 0, 0, 0x4646, 0x6445, 0x6444, 0, - 0xD252, 0x6441, 0xF362, 0, 0, 0x4F36, 0, 0, - 0xF363, 0, 0xD254, 0x644A, 0xD255, 0xD256, 0x644E, 0x644B, - 0xD257, 0xD258, 0xD259, 0, 0xD25A, 0, 0xD25B, 0, -}; -static const unsigned short utf8_to_euc_E7B0[] = { - 0x6447, 0xD25C, 0xD25D, 0xD25E, 0xD25F, 0, 0xD260, 0x6448, - 0, 0xD261, 0, 0xD262, 0xD263, 0x644D, 0xD264, 0xD265, - 0, 0x6442, 0x5255, 0x6449, 0x6443, 0, 0, 0x644C, - 0, 0xD266, 0, 0xD267, 0, 0, 0, 0x6452, - 0xD268, 0x344A, 0, 0x644F, 0, 0xD269, 0xD26A, 0x6450, - 0xD26B, 0, 0x6451, 0x6454, 0xD26C, 0, 0, 0, - 0, 0xD26D, 0, 0xD26E, 0xD26F, 0, 0xD270, 0x6453, - 0x4876, 0xD271, 0xD272, 0, 0, 0x6455, 0x4E7C, 0x4A6D, -}; -static const unsigned short utf8_to_euc_E7B0_x0213[] = { - 0x6447, 0x7967, 0xD25D, 0xF364, 0xD25F, 0, 0xD260, 0x6448, - 0, 0xD261, 0, 0xF365, 0xD263, 0x644D, 0xF366, 0xF367, - 0, 0x6442, 0x5255, 0x6449, 0x6443, 0, 0, 0x644C, - 0, 0xD266, 0, 0xD267, 0, 0, 0x7969, 0x6452, - 0x796A, 0x344A, 0, 0x644F, 0, 0xD269, 0xF368, 0x6450, - 0xD26B, 0, 0x6451, 0x6454, 0xD26C, 0, 0, 0, - 0, 0x7968, 0, 0x796B, 0xD26F, 0, 0x796C, 0x6453, - 0x4876, 0xD271, 0xD272, 0, 0, 0x6455, 0x4E7C, 0x4A6D, -}; -static const unsigned short utf8_to_euc_E7B1[] = { - 0x645A, 0, 0, 0x6457, 0, 0, 0xD273, 0, - 0, 0, 0xD274, 0, 0x6456, 0x4052, 0, 0x6459, - 0x645B, 0xD276, 0xD277, 0xD278, 0x6458, 0xD275, 0x645F, 0, - 0x645C, 0xD279, 0xD27A, 0xD27B, 0xD27C, 0xD27D, 0xD27E, 0x645D, - 0x6446, 0xD321, 0, 0xD322, 0x645E, 0x6460, 0, 0xD323, - 0, 0xD324, 0, 0, 0x6461, 0xD325, 0xD326, 0, - 0xD327, 0, 0xD328, 0x4A46, 0, 0x6462, 0, 0, - 0, 0xD329, 0, 0, 0xD32A, 0xD32B, 0x4C62, 0, -}; -static const unsigned short utf8_to_euc_E7B1_x0213[] = { - 0x645A, 0, 0, 0x6457, 0, 0xF369, 0xD273, 0, - 0, 0, 0xF36A, 0, 0x6456, 0x4052, 0, 0x6459, - 0x645B, 0xF36B, 0xD277, 0xD278, 0x6458, 0xD275, 0x645F, 0xF36C, - 0x645C, 0x796F, 0xD27A, 0xD27B, 0xD27C, 0xD27D, 0xF36D, 0x645D, - 0x6446, 0xF36E, 0, 0xD322, 0x645E, 0x6460, 0, 0xD323, - 0, 0xF36F, 0, 0, 0x6461, 0x7970, 0xF370, 0xF371, - 0xF372, 0, 0xD328, 0x4A46, 0, 0x6462, 0, 0, - 0, 0x7971, 0, 0, 0xD32A, 0xD32B, 0x4C62, 0, -}; -static const unsigned short utf8_to_euc_E7B2[] = { - 0, 0x364E, 0x3729, 0x6463, 0, 0, 0xD32C, 0xD32D, - 0, 0x4A34, 0, 0x3F68, 0, 0x4C30, 0, 0xD32E, - 0x6464, 0, 0x4E33, 0, 0xD32F, 0x4774, 0, 0x4146, - 0x4734, 0, 0, 0x3D4D, 0, 0, 0xD330, 0x3040, - 0xD331, 0x6469, 0x6467, 0, 0x6465, 0x3421, 0xD332, 0x3E51, - 0x646A, 0, 0, 0x6468, 0, 0x6466, 0x646E, 0, - 0xD333, 0x646D, 0x646C, 0x646B, 0, 0, 0xD334, 0xD335, - 0, 0x646F, 0xD336, 0xD337, 0xD338, 0x6470, 0x403A, 0xD339, -}; -static const unsigned short utf8_to_euc_E7B2_x0213[] = { - 0, 0x364E, 0x3729, 0x6463, 0, 0, 0xD32C, 0xD32D, - 0, 0x4A34, 0, 0x3F68, 0, 0x4C30, 0, 0x7972, - 0x6464, 0, 0x4E33, 0, 0x7973, 0x4774, 0, 0x4146, - 0x4734, 0, 0, 0x3D4D, 0, 0, 0xD330, 0x3040, - 0x7974, 0x6469, 0x6467, 0, 0x6465, 0x3421, 0xF376, 0x3E51, - 0x646A, 0, 0, 0x6468, 0, 0x6466, 0x646E, 0, - 0xD333, 0x646D, 0x646C, 0x646B, 0, 0, 0xF378, 0xF379, - 0, 0x646F, 0xD336, 0xD337, 0x7975, 0x6470, 0x403A, 0xF37A, -}; -static const unsigned short utf8_to_euc_E7B3[] = { - 0x6471, 0, 0x6473, 0, 0xD33A, 0x6472, 0, 0xD33B, - 0xD33C, 0xD33D, 0x3852, 0, 0, 0xD33E, 0x4138, 0xD33F, - 0, 0, 0x6475, 0xD340, 0xD341, 0xD342, 0x457C, 0xD343, - 0x6474, 0xD344, 0xD345, 0, 0x6476, 0xD346, 0x4A35, 0x416C, - 0x3947, 0, 0x6477, 0, 0, 0, 0xD347, 0x4E48, - 0, 0xD348, 0, 0xD349, 0, 0, 0, 0x6479, - 0, 0, 0x647A, 0, 0x647B, 0xD34A, 0x647C, 0, - 0x3B65, 0, 0x647D, 0x374F, 0, 0, 0x356A, 0, -}; -static const unsigned short utf8_to_euc_E7B3_x0213[] = { - 0x6471, 0, 0x6473, 0, 0xF37C, 0x6472, 0, 0xD33B, - 0xF37E, 0xD33D, 0x3852, 0, 0, 0xF421, 0x4138, 0xD33F, - 0, 0, 0x6475, 0xD340, 0xD341, 0x7976, 0x457C, 0xF423, - 0x6474, 0x7977, 0xD345, 0, 0x6476, 0x7978, 0x4A35, 0x416C, - 0x3947, 0, 0x6477, 0, 0, 0, 0xF425, 0x4E48, - 0, 0xD348, 0, 0xF426, 0, 0, 0, 0x6479, - 0, 0, 0x647A, 0, 0x647B, 0xF428, 0x647C, 0, - 0x3B65, 0, 0x647D, 0x374F, 0, 0, 0x356A, 0, -}; -static const unsigned short utf8_to_euc_E7B4[] = { - 0x352A, 0, 0x6521, 0xD34B, 0x4C73, 0x3948, 0x647E, 0xD34C, - 0xD34D, 0xD34E, 0x6524, 0x4C66, 0, 0x473C, 0, 0xD34F, - 0x4933, 0xD350, 0xD351, 0xD352, 0x3D63, 0x6523, 0xD353, 0x3C53, - 0x3949, 0x3B66, 0x3569, 0x4A36, 0x6522, 0xD354, 0xD355, 0, - 0x4147, 0x4B42, 0x3A77, 0xD356, 0, 0, 0xD357, 0, - 0, 0, 0xD358, 0x3B67, 0x445D, 0xD359, 0x6527, 0x4E5F, - 0x3A59, 0xD35A, 0x6528, 0x3F42, 0, 0x652A, 0, 0, - 0, 0x3E52, 0x3A30, 0, 0xD35B, 0xD35C, 0xD35D, 0x6529, -}; -static const unsigned short utf8_to_euc_E7B4_x0213[] = { - 0x352A, 0, 0x6521, 0xF429, 0x4C73, 0x3948, 0x647E, 0x7979, - 0x797A, 0xF42A, 0x6524, 0x4C66, 0, 0x473C, 0, 0xD34F, - 0x4933, 0xD350, 0xF42C, 0x797B, 0x3D63, 0x6523, 0xD353, 0x3C53, - 0x3949, 0x3B66, 0x3569, 0x4A36, 0x6522, 0x797C, 0xF42D, 0, - 0x4147, 0x4B42, 0x3A77, 0x797D, 0, 0, 0xD357, 0, - 0, 0, 0xD358, 0x3B67, 0x445D, 0xD359, 0x6527, 0x4E5F, - 0x3A59, 0x797E, 0x6528, 0x3F42, 0, 0x652A, 0, 0, - 0, 0x3E52, 0x3A30, 0, 0xD35B, 0xF430, 0xF431, 0x6529, -}; -static const unsigned short utf8_to_euc_E7B5[] = { - 0xD35E, 0xD35F, 0x3D2A, 0x383E, 0x4148, 0x6525, 0x652B, 0xD360, - 0xD361, 0, 0, 0x6526, 0x3750, 0xD362, 0x652E, 0x6532, - 0x376B, 0xD363, 0, 0xD364, 0, 0, 0x652D, 0xD365, - 0, 0xD366, 0xD367, 0x6536, 0xD368, 0xD369, 0x394A, 0, - 0, 0x4D6D, 0x303C, 0x6533, 0, 0xD36A, 0x356B, 0xD36B, - 0x6530, 0, 0xD36C, 0, 0, 0, 0x6531, 0, - 0xD36D, 0x457D, 0x652F, 0x652C, 0, 0x3328, 0x4064, 0, - 0xD36E, 0x3828, 0xD36F, 0xD370, 0, 0x6538, 0, 0xD371, -}; -static const unsigned short utf8_to_euc_E7B5_x0213[] = { - 0xF432, 0x7A21, 0x3D2A, 0x383E, 0x4148, 0x6525, 0x652B, 0xF433, - 0x7A22, 0, 0, 0x6526, 0x3750, 0xD362, 0x652E, 0x6532, - 0x376B, 0xD363, 0, 0x7A23, 0, 0, 0x652D, 0xD365, - 0, 0xF437, 0xF438, 0x6536, 0x7A24, 0xD369, 0x394A, 0, - 0, 0x4D6D, 0x303C, 0x6533, 0, 0xD36A, 0x356B, 0xD36B, - 0x6530, 0, 0xF439, 0, 0, 0, 0x6531, 0, - 0xF43A, 0x457D, 0x652F, 0x652C, 0, 0x3328, 0x4064, 0, - 0xD36E, 0x3828, 0x7A25, 0xD370, 0, 0x6538, 0, 0xF43C, -}; -static const unsigned short utf8_to_euc_E7B6[] = { - 0, 0xD372, 0xD373, 0xD374, 0, 0xD375, 0xD376, 0, - 0xD377, 0x6535, 0, 0xD378, 0xD379, 0xD37A, 0, 0x6537, - 0, 0xD37B, 0, 0x6534, 0, 0, 0xD37C, 0xD37D, - 0, 0x3751, 0x4233, 0x6539, 0x416E, 0xD37E, 0xD421, 0x6546, - 0xF45C, 0, 0x6542, 0x653C, 0, 0, 0xD422, 0xD423, - 0, 0, 0xD424, 0x6540, 0x3C7A, 0x305D, 0x653B, 0x6543, - 0x6547, 0x394B, 0x4C56, 0xD425, 0x4456, 0x653D, 0xD426, 0xD427, - 0x6545, 0xD428, 0x653A, 0x433E, 0, 0x653F, 0x303D, 0x4C4A, -}; -static const unsigned short utf8_to_euc_E7B6_x0213[] = { - 0, 0xD372, 0xD373, 0x7A26, 0, 0xD375, 0xF43E, 0, - 0xF43F, 0x6535, 0, 0x7A27, 0xF440, 0xD37A, 0, 0x6537, - 0, 0xD37B, 0, 0x6534, 0, 0, 0xD37C, 0xF441, - 0, 0x3751, 0x4233, 0x6539, 0x416E, 0xF443, 0xD421, 0x6546, - 0x7A28, 0, 0x6542, 0x653C, 0, 0, 0x7A29, 0xF444, - 0, 0, 0xF445, 0x6540, 0x3C7A, 0x305D, 0x653B, 0x6543, - 0x6547, 0x394B, 0x4C56, 0xD425, 0x4456, 0x653D, 0xF446, 0xF447, - 0x6545, 0xD428, 0x653A, 0x433E, 0, 0x653F, 0x303D, 0x4C4A, -}; -static const unsigned short utf8_to_euc_E7B7[] = { - 0, 0, 0xD429, 0xD42A, 0xD42B, 0xD42C, 0xD42D, 0x653E, - 0, 0, 0x365B, 0x486C, 0xD42E, 0xD42F, 0xD430, 0x416D, - 0, 0x4E50, 0x3D6F, 0, 0, 0x656E, 0xF45D, 0xD431, - 0x6548, 0xD432, 0x407E, 0, 0x6544, 0x6549, 0x654B, 0, - 0x4479, 0x654E, 0xD434, 0, 0x654A, 0xD435, 0xD436, 0, - 0x4A54, 0x344B, 0xD437, 0xD438, 0x4C4B, 0xD439, 0, 0x305E, - 0, 0xD43A, 0x654D, 0, 0x4E7D, 0xD43B, 0xD43C, 0, - 0, 0xD43D, 0xD43E, 0x654C, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7B7_x0213[] = { - 0xF448, 0, 0x7A2A, 0xD42A, 0xD42B, 0xD42C, 0xD42D, 0x653E, - 0, 0, 0x365B, 0x486C, 0x7A2B, 0xD42F, 0xD430, 0x416D, - 0, 0x4E50, 0x3D6F, 0, 0, 0x656E, 0x7A2C, 0xF449, - 0x6548, 0xF44A, 0x407E, 0, 0x6544, 0x6549, 0x654B, 0, - 0x4479, 0x654E, 0xD434, 0x7A2D, 0x654A, 0xD435, 0xF44B, 0, - 0x4A54, 0x344B, 0xD437, 0xD438, 0x4C4B, 0xD439, 0, 0x305E, - 0, 0xF44C, 0x654D, 0, 0x4E7D, 0xD43B, 0xD43C, 0, - 0, 0xF44D, 0xD43E, 0x654C, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7B8[] = { - 0xD433, 0x316F, 0, 0, 0x466C, 0x654F, 0, 0, - 0xD43F, 0x6556, 0x6550, 0x6557, 0, 0, 0, 0, - 0xD440, 0xD441, 0x6553, 0, 0, 0xD442, 0, 0xD443, - 0, 0, 0, 0x477B, 0xD444, 0xD445, 0x3C4A, 0x6555, - 0xD446, 0x6552, 0x6558, 0x6551, 0, 0, 0x3D44, 0xD447, - 0xD448, 0, 0, 0x4B25, 0xD449, 0xD44A, 0x3D4C, 0xD44B, - 0, 0x6554, 0x6560, 0xD44C, 0, 0x655C, 0xD44D, 0x655F, - 0, 0x655D, 0x6561, 0x655B, 0, 0x6541, 0x4053, 0xD44E, -}; -static const unsigned short utf8_to_euc_E7B8_x0213[] = { - 0xD433, 0x316F, 0, 0, 0x466C, 0x654F, 0, 0, - 0x7A30, 0x6556, 0x6550, 0x6557, 0, 0, 0, 0, - 0xF451, 0x7A31, 0x6553, 0, 0, 0x7A32, 0, 0xF452, - 0, 0, 0, 0x477B, 0xD444, 0xF453, 0x3C4A, 0x6555, - 0xF454, 0x6552, 0x6558, 0x6551, 0, 0, 0x3D44, 0xF455, - 0x7A2F, 0, 0, 0x4B25, 0xF456, 0xD44A, 0x3D4C, 0xD44B, - 0, 0x6554, 0x6560, 0xD44C, 0, 0x655C, 0xD44D, 0x655F, - 0, 0x655D, 0x6561, 0x655B, 0, 0x6541, 0x4053, 0xD44E, -}; -static const unsigned short utf8_to_euc_E7B9[] = { - 0, 0x484B, 0, 0x655E, 0xD44F, 0xD450, 0x6559, 0xD451, - 0, 0, 0x4121, 0x3752, 0, 0x3D2B, 0xD452, 0, - 0xD453, 0, 0xD454, 0, 0x3F25, 0x4136, 0x6564, 0, - 0xD455, 0x6566, 0x6567, 0, 0, 0x6563, 0x6565, 0xD456, - 0, 0xD457, 0xD458, 0, 0, 0xD459, 0x655A, 0x6562, - 0, 0x656A, 0x6569, 0xD45A, 0, 0x4B7A, 0xD45B, 0xD45C, - 0x372B, 0, 0, 0xD45D, 0, 0, 0, 0, - 0xD45E, 0x6568, 0, 0x656C, 0x656B, 0x656F, 0xD45F, 0x6571, -}; -static const unsigned short utf8_to_euc_E7B9_x0213[] = { - 0, 0x484B, 0, 0x655E, 0xD44F, 0xF457, 0x6559, 0x7A34, - 0, 0, 0x4121, 0x3752, 0, 0x3D2B, 0xD452, 0, - 0xD453, 0, 0x7A35, 0, 0x3F25, 0x4136, 0x6564, 0, - 0xD455, 0x6566, 0x6567, 0, 0, 0x6563, 0x6565, 0xD456, - 0, 0x7A36, 0xD458, 0, 0, 0xD459, 0x655A, 0x6562, - 0, 0x656A, 0x6569, 0x7E7E, 0, 0x4B7A, 0xD45B, 0xD45C, - 0x372B, 0, 0, 0xF458, 0, 0xF459, 0, 0, - 0xD45E, 0x6568, 0, 0x656C, 0x656B, 0x656F, 0xF45A, 0x6571, -}; -static const unsigned short utf8_to_euc_E7BA[] = { - 0, 0xD460, 0x3B3C, 0x656D, 0, 0, 0xD461, 0xD462, - 0x6572, 0x6573, 0xD463, 0, 0x6574, 0xD464, 0x657A, 0x453B, - 0x6576, 0xD465, 0x6575, 0x6577, 0x6578, 0xD466, 0x6579, 0, - 0xD467, 0, 0xD468, 0x657B, 0x657C, 0xD469, 0xD46A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7BA_x0213[] = { - 0, 0xD460, 0x3B3C, 0x656D, 0, 0, 0xF45B, 0xF45C, - 0x6572, 0x6573, 0x7A37, 0, 0x6574, 0x7A38, 0x657A, 0x453B, - 0x6576, 0xF45E, 0x6575, 0x6577, 0x6578, 0xD466, 0x6579, 0, - 0xF45F, 0, 0xF460, 0x657B, 0x657C, 0xD469, 0xD46A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E7BC[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x344C, 0, - 0x657D, 0, 0x657E, 0xD46C, 0xD46B, 0xD46D, 0xD46E, 0xD46F, -}; -static const unsigned short utf8_to_euc_E7BC_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x344C, 0, - 0x657D, 0, 0x657E, 0xF463, 0xF462, 0xD46D, 0xF464, 0xD46F, -}; -static const unsigned short utf8_to_euc_E7BD[] = { - 0, 0, 0, 0xD470, 0xD471, 0x6621, 0, 0xD472, - 0, 0, 0, 0, 0x6622, 0x6623, 0x6624, 0xD473, - 0x6625, 0x6626, 0xD474, 0xD475, 0x6628, 0x6627, 0, 0, - 0x6629, 0, 0, 0xD476, 0xD477, 0xD478, 0, 0x662A, - 0x662B, 0xD479, 0, 0xD47A, 0xD47B, 0xD47C, 0xD47D, 0x662E, - 0x662C, 0x662D, 0x3A61, 0x3753, 0, 0xD47E, 0x4356, 0, - 0x4833, 0xD521, 0x3D70, 0, 0, 0x474D, 0, 0x486D, - 0x662F, 0x586D, 0, 0, 0, 0xD522, 0xD523, 0xD524, -}; -static const unsigned short utf8_to_euc_E7BD_x0213[] = { - 0, 0, 0, 0xF465, 0xF466, 0x6621, 0, 0x7A39, - 0, 0, 0, 0, 0x6622, 0x6623, 0x6624, 0xF467, - 0x6625, 0x6626, 0xF46A, 0xD475, 0x6628, 0x6627, 0, 0, - 0x6629, 0, 0, 0xD476, 0xD477, 0xD478, 0, 0x662A, - 0x662B, 0xF46C, 0, 0xF46D, 0xF46E, 0xD47C, 0xD47D, 0x662E, - 0x662C, 0x662D, 0x3A61, 0x3753, 0, 0xF46F, 0x4356, 0, - 0x4833, 0xD521, 0x3D70, 0, 0, 0x474D, 0, 0x486D, - 0x662F, 0x586D, 0, 0, 0, 0xF470, 0xF471, 0xD524, -}; -static const unsigned short utf8_to_euc_E7BE[] = { - 0xD525, 0, 0x6630, 0x6632, 0, 0x4D65, 0x6631, 0x6634, - 0x6633, 0, 0x4D53, 0xD526, 0x6635, 0xD527, 0x487E, 0xD528, - 0xD529, 0xD52A, 0, 0, 0x6636, 0, 0xD52B, 0xD52C, - 0, 0, 0x6639, 0, 0xD52D, 0x6638, 0x6637, 0, - 0, 0xD52E, 0xD52F, 0x663A, 0x3732, 0, 0xD530, 0, - 0x4122, 0x3541, 0xD531, 0, 0, 0xD532, 0x663E, 0x663B, - 0, 0, 0x663C, 0, 0xD533, 0, 0x663F, 0, - 0x6640, 0x663D, 0, 0, 0xD534, 0x3129, 0, 0xD535, -}; -static const unsigned short utf8_to_euc_E7BE_x0213[] = { - 0xD525, 0, 0x6630, 0x6632, 0, 0x4D65, 0x6631, 0x6634, - 0x6633, 0, 0x4D53, 0xD526, 0x6635, 0xD527, 0x487E, 0xD528, - 0xF473, 0x7A3B, 0, 0, 0x6636, 0, 0xF476, 0x7A3C, - 0, 0, 0x6639, 0, 0xF477, 0x6638, 0x6637, 0, - 0, 0, 0xD52F, 0x663A, 0x3732, 0, 0xD530, 0, - 0x4122, 0x3541, 0xD531, 0, 0, 0xF478, 0x663E, 0x663B, - 0, 0, 0x663C, 0, 0xD533, 0, 0x663F, 0, - 0x6640, 0x663D, 0, 0, 0xD534, 0x3129, 0, 0x7A3D, -}; -static const unsigned short utf8_to_euc_E7BF[] = { - 0xD536, 0x3227, 0, 0xD537, 0, 0x6642, 0x6643, 0, - 0xD538, 0, 0x6644, 0, 0x4D62, 0, 0xD539, 0xD53A, - 0, 0, 0x3D2C, 0, 0x6646, 0x6645, 0, 0, - 0, 0, 0, 0xD53B, 0, 0, 0, 0xD53C, - 0x3F69, 0x6647, 0, 0xD53D, 0, 0xD53E, 0x6648, 0, - 0xD53F, 0x6649, 0, 0x3465, 0xD540, 0, 0xD541, 0xD542, - 0x344D, 0, 0xD543, 0x664A, 0, 0, 0, 0, - 0, 0x664B, 0xD544, 0x4B5D, 0x4D63, 0xD545, 0xD546, 0xD547, -}; -static const unsigned short utf8_to_euc_E7BF_x0213[] = { - 0xD536, 0x3227, 0, 0xF47A, 0, 0x6642, 0x6643, 0, - 0xD538, 0, 0x6644, 0, 0x4D62, 0, 0x7A3E, 0xF47B, - 0, 0, 0x3D2C, 0, 0x6646, 0x6645, 0, 0, - 0, 0, 0, 0x7A3F, 0, 0, 0, 0x7A40, - 0x3F69, 0x6647, 0, 0xF47C, 0, 0xF47D, 0x6648, 0, - 0xD53F, 0x6649, 0, 0x3465, 0x7A41, 0, 0x7A42, 0xF47E, - 0x344D, 0, 0xF521, 0x664A, 0, 0, 0, 0, - 0, 0x664B, 0x7A43, 0x4B5D, 0x4D63, 0xD545, 0xD546, 0xD547, -}; -static const unsigned short utf8_to_euc_E880[] = { - 0x4D54, 0x4F37, 0, 0x394D, 0x664E, 0x3C54, 0x664D, 0xD548, - 0xD549, 0, 0xD54A, 0x664F, 0x3C29, 0xD54B, 0xD54C, 0xD54D, - 0x4251, 0xD54E, 0x6650, 0xD54F, 0xD550, 0x394C, 0xD551, 0x4C57, - 0x6651, 0x6652, 0, 0, 0x6653, 0xD552, 0xD553, 0xD554, - 0xD555, 0x6654, 0, 0, 0xD556, 0, 0xD557, 0, - 0x6655, 0, 0, 0, 0xD558, 0, 0xD559, 0, - 0xD55A, 0, 0, 0x3C2A, 0xD55B, 0xD55C, 0x4C6D, 0xD55D, - 0, 0xD55E, 0xD55F, 0x6657, 0xD560, 0x433F, 0xD561, 0x6656, -}; -static const unsigned short utf8_to_euc_E880_x0213[] = { - 0x4D54, 0x4F37, 0xF522, 0x394D, 0x664E, 0x3C54, 0x664D, 0xD548, - 0xF524, 0, 0xF523, 0x664F, 0x3C29, 0xD54B, 0xF525, 0xD54D, - 0x4251, 0xF526, 0x6650, 0xD54F, 0x7A45, 0x394C, 0xF527, 0x4C57, - 0x6651, 0x6652, 0, 0, 0x6653, 0xD552, 0xD553, 0xD554, - 0xD555, 0x6654, 0, 0, 0xF528, 0, 0x7A46, 0, - 0x6655, 0, 0, 0, 0xF529, 0, 0xD559, 0, - 0xF52A, 0, 0, 0x3C2A, 0xD55B, 0x7A47, 0x4C6D, 0x7A48, - 0, 0xD55E, 0xD55F, 0x6657, 0x7A49, 0x433F, 0xD561, 0x6656, -}; -static const unsigned short utf8_to_euc_E881[] = { - 0xD562, 0, 0, 0, 0xD563, 0, 0x6659, 0, - 0, 0, 0x6658, 0, 0, 0, 0, 0, - 0, 0, 0x665A, 0, 0, 0, 0x403B, 0, - 0x665B, 0, 0x665C, 0, 0, 0, 0x4A39, 0x665D, - 0xD564, 0x416F, 0x665E, 0, 0xD565, 0, 0xD566, 0, - 0x665F, 0, 0, 0, 0, 0xD567, 0, 0x4E7E, - 0x6662, 0xD568, 0x6661, 0x6660, 0x4430, 0xD569, 0x6663, 0x3F26, - 0, 0x6664, 0, 0, 0, 0x6665, 0x4F38, 0x6666, -}; -static const unsigned short utf8_to_euc_E881_x0213[] = { - 0xD562, 0, 0, 0xF52B, 0xD563, 0, 0x6659, 0, - 0, 0, 0x6658, 0, 0, 0, 0, 0, - 0, 0, 0x665A, 0, 0, 0, 0x403B, 0, - 0x665B, 0, 0x665C, 0, 0, 0, 0x4A39, 0x665D, - 0xD564, 0x416F, 0x665E, 0, 0xD565, 0, 0xF52C, 0, - 0x665F, 0, 0, 0, 0, 0xD567, 0, 0x4E7E, - 0x6662, 0xF52D, 0x6661, 0x6660, 0x4430, 0xF52E, 0x6663, 0x3F26, - 0, 0x6664, 0, 0xF52F, 0, 0x6665, 0x4F38, 0x6666, -}; -static const unsigned short utf8_to_euc_E882[] = { - 0, 0xD56A, 0, 0, 0x6667, 0x6669, 0x6668, 0x4825, - 0xD56B, 0x4679, 0, 0x4F3E, 0x4829, 0, 0xD56C, 0, - 0, 0, 0, 0x666B, 0, 0, 0x3E53, 0, - 0x492A, 0, 0x666C, 0x666A, 0xD56D, 0x344E, 0xD56E, 0, - 0, 0x3854, 0x3B68, 0, 0, 0x486E, 0xD56F, 0xD570, - 0, 0x382A, 0x4B43, 0xD571, 0x666F, 0x666D, 0, 0x394E, - 0, 0x394F, 0x3069, 0, 0x3A68, 0, 0, 0, - 0xD572, 0xD573, 0x4759, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E882_x0213[] = { - 0, 0xD56A, 0, 0, 0x6667, 0x6669, 0x6668, 0x4825, - 0xD56B, 0x4679, 0, 0x4F3E, 0x4829, 0, 0xD56C, 0, - 0, 0, 0, 0x666B, 0, 0, 0x3E53, 0, - 0x492A, 0xF530, 0x666C, 0x666A, 0xF531, 0x344E, 0xD56E, 0, - 0, 0x3854, 0x3B68, 0, 0xF532, 0x486E, 0xD56F, 0xF533, - 0, 0x382A, 0x4B43, 0xD571, 0x666F, 0x666D, 0, 0x394E, - 0, 0x394F, 0x3069, 0, 0x3A68, 0, 0, 0, - 0xF534, 0xD573, 0x4759, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E883[] = { - 0, 0, 0, 0x305F, 0x6674, 0, 0x4340, 0, - 0xD574, 0, 0, 0, 0x4758, 0xD575, 0x425B, 0xD576, - 0, 0, 0xD577, 0, 0xD578, 0xD579, 0x6676, 0xD57A, - 0xD57B, 0x6672, 0x6675, 0x6670, 0, 0x6673, 0x4B26, 0, - 0xD57C, 0x3855, 0, 0, 0x307D, 0x6671, 0, 0, - 0, 0, 0, 0, 0, 0xD57D, 0xD57E, 0x6678, - 0xD621, 0x6679, 0xD622, 0xD623, 0x4639, 0, 0xD624, 0, - 0x363B, 0xD625, 0xD626, 0, 0x6726, 0x473D, 0xD627, 0, -}; -static const unsigned short utf8_to_euc_E883_x0213[] = { - 0, 0, 0, 0x305F, 0x6674, 0xF536, 0x4340, 0, - 0xD574, 0, 0x7A4A, 0, 0x4758, 0xD575, 0x425B, 0xD576, - 0, 0, 0xD577, 0, 0xD578, 0xF537, 0x6676, 0x7A4B, - 0xF538, 0x6672, 0x6675, 0x6670, 0, 0x6673, 0x4B26, 0, - 0x7A4C, 0x3855, 0, 0, 0x307D, 0x6671, 0xF539, 0, - 0, 0, 0, 0, 0, 0xD57D, 0xD57E, 0x6678, - 0xD621, 0x6679, 0xD622, 0x7A4D, 0x4639, 0xF53C, 0xD624, 0, - 0x363B, 0xD625, 0xD626, 0xF53D, 0x6726, 0x473D, 0xD627, 0, -}; -static const unsigned short utf8_to_euc_E884[] = { - 0, 0, 0x3B69, 0xD628, 0, 0x363C, 0x4048, 0x4F46, - 0x4C2E, 0x6677, 0x4054, 0xD629, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xD62A, 0xD62B, - 0xD62C, 0, 0x3553, 0x667A, 0xD62D, 0, 0xD62E, 0, - 0xD62F, 0, 0, 0x667C, 0xD630, 0, 0, 0xD631, - 0, 0x667B, 0, 0, 0xD632, 0, 0, 0x667D, - 0xD633, 0x4326, 0, 0x473E, 0, 0xD634, 0, 0, - 0, 0x4431, 0xD635, 0, 0xD636, 0, 0x6723, 0, -}; -static const unsigned short utf8_to_euc_E884_x0213[] = { - 0, 0, 0x3B69, 0xD628, 0, 0x363C, 0x4048, 0x4F46, - 0x4C2E, 0x6677, 0x4054, 0xD629, 0, 0xF53B, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF540, 0xD62B, - 0x7A4E, 0, 0x3553, 0x667A, 0xD62D, 0, 0xF541, 0, - 0xD62F, 0, 0, 0x667C, 0xF543, 0, 0, 0xF544, - 0, 0x667B, 0, 0, 0xF545, 0, 0, 0x667D, - 0xD633, 0x4326, 0, 0x473E, 0, 0xF53F, 0, 0, - 0, 0x4431, 0xD635, 0, 0xD636, 0xF547, 0x6723, 0, -}; -static const unsigned short utf8_to_euc_E885[] = { - 0, 0, 0, 0, 0, 0xD637, 0x6722, 0xD638, - 0, 0, 0xD639, 0x667E, 0xD63A, 0, 0x3F55, 0, - 0x4965, 0x6725, 0xD63B, 0x6724, 0x3950, 0x4F53, 0, 0xD63C, - 0, 0, 0, 0, 0, 0, 0, 0x6735, - 0xD63D, 0xD63E, 0, 0, 0, 0x6729, 0x672A, 0xD63F, - 0xD640, 0xD641, 0, 0x3C70, 0, 0xD642, 0x6728, 0xD643, - 0x3978, 0x6727, 0, 0, 0x672B, 0, 0, 0xD644, - 0x4432, 0x4A22, 0x4123, 0, 0, 0, 0, 0x425C, -}; -static const unsigned short utf8_to_euc_E885_x0213[] = { - 0, 0, 0, 0, 0, 0xD637, 0x6722, 0xD638, - 0, 0, 0x7A4F, 0x667E, 0xD63A, 0, 0x3F55, 0, - 0x4965, 0x6725, 0xD63B, 0x6724, 0x3950, 0x4F53, 0, 0xD63C, - 0, 0, 0, 0, 0, 0, 0, 0x6735, - 0x7A50, 0xD63E, 0, 0, 0, 0x6729, 0x672A, 0x7A51, - 0x7A52, 0xF549, 0, 0x3C70, 0, 0x7A53, 0x6728, 0xD643, - 0x3978, 0x6727, 0, 0, 0x672B, 0, 0, 0xD644, - 0x4432, 0x4A22, 0x4123, 0, 0, 0, 0, 0x425C, -}; -static const unsigned short utf8_to_euc_E886[] = { - 0x672F, 0xD645, 0x6730, 0x672C, 0xD647, 0xD648, 0xD649, 0, - 0x672D, 0, 0x672E, 0xD64A, 0, 0, 0xD64B, 0x3951, - 0xD646, 0, 0, 0x6736, 0, 0x6732, 0xD64C, 0, - 0xD64D, 0, 0x4966, 0xD64E, 0x4B6C, 0x4928, 0xD64F, 0, - 0x6731, 0, 0xD650, 0x6734, 0x6733, 0, 0, 0, - 0x4B44, 0x6737, 0, 0, 0, 0, 0xD651, 0, - 0x6738, 0, 0xD652, 0x4137, 0xD653, 0x6739, 0, 0, - 0x673B, 0, 0x673F, 0xD654, 0, 0x673C, 0x673A, 0x473F, -}; -static const unsigned short utf8_to_euc_E886_x0213[] = { - 0x672F, 0xF54B, 0x6730, 0x672C, 0xF54D, 0xF54E, 0xD649, 0, - 0x672D, 0, 0x672E, 0xD64A, 0, 0, 0xD64B, 0x3951, - 0xD646, 0, 0, 0x6736, 0, 0x6732, 0xD64C, 0, - 0xF550, 0, 0x4966, 0xD64E, 0x4B6C, 0x4928, 0xD64F, 0, - 0x6731, 0, 0xD650, 0x6734, 0x6733, 0, 0, 0, - 0x4B44, 0x6737, 0, 0, 0, 0, 0xD651, 0, - 0x6738, 0, 0xF551, 0x4137, 0xD653, 0x6739, 0, 0, - 0x673B, 0, 0x673F, 0x7A54, 0, 0x673C, 0x673A, 0x473F, -}; -static const unsigned short utf8_to_euc_E887[] = { - 0x673D, 0, 0x673E, 0xD656, 0, 0xD657, 0x3232, 0, - 0x6745, 0x6740, 0xD658, 0xD655, 0, 0x6741, 0xD659, 0xD65A, - 0, 0x6742, 0, 0x4221, 0, 0xD65B, 0, 0xD65C, - 0x6744, 0x6743, 0x6746, 0xD65D, 0, 0xD65E, 0xD65F, 0x6747, - 0x6748, 0xD660, 0, 0x3F43, 0xD661, 0x3269, 0, 0x6749, - 0x4E57, 0, 0x3C2B, 0xD662, 0xD663, 0x3D2D, 0, 0, - 0xD664, 0xD665, 0xD666, 0x3B6A, 0x4357, 0xD667, 0xD668, 0, - 0xD669, 0xD66A, 0x674A, 0x674B, 0x3131, 0xD66B, 0x674C, 0xD66C, -}; -static const unsigned short utf8_to_euc_E887_x0213[] = { - 0x673D, 0xF552, 0x673E, 0xF553, 0, 0xD657, 0x3232, 0, - 0x6745, 0x6740, 0x7A55, 0xD655, 0, 0x6741, 0xD659, 0x7A56, - 0, 0x6742, 0, 0x4221, 0, 0xD65B, 0xF554, 0x7A57, - 0x6744, 0x6743, 0x6746, 0xF555, 0, 0xD65E, 0xD65F, 0x6747, - 0x6748, 0xD660, 0, 0x3F43, 0xF557, 0x3269, 0, 0x6749, - 0x4E57, 0, 0x3C2B, 0xD662, 0xF559, 0x3D2D, 0, 0, - 0xD664, 0xD665, 0xD666, 0x3B6A, 0x4357, 0xD667, 0xD668, 0, - 0xD669, 0xD66A, 0x674A, 0x674B, 0x3131, 0xF55B, 0x674C, 0xF55C, -}; -static const unsigned short utf8_to_euc_E888[] = { - 0xD66D, 0x674D, 0x674E, 0xD66E, 0, 0x674F, 0, 0x6750, - 0x363D, 0x5A2A, 0x6751, 0, 0x4065, 0x6752, 0x3C4B, 0xD66F, - 0x6753, 0, 0x5030, 0xD670, 0xD671, 0, 0x6754, 0x4A5E, - 0x345C, 0xD672, 0xD673, 0x4124, 0x3D58, 0xD674, 0x4971, 0x3D2E, - 0, 0xD675, 0xD676, 0, 0, 0, 0, 0, - 0xD677, 0x6755, 0x3952, 0x6756, 0x484C, 0, 0x6764, 0, - 0, 0, 0xD678, 0x6758, 0xD679, 0x4249, 0x4775, 0x383F, - 0x6757, 0x4125, 0xD67A, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E888_x0213[] = { - 0xD66D, 0x674D, 0x674E, 0xD66E, 0xF55E, 0x674F, 0, 0x6750, - 0x363D, 0x5A2A, 0x6751, 0, 0x4065, 0x6752, 0x3C4B, 0xD66F, - 0x6753, 0, 0x5030, 0xD670, 0xD671, 0, 0x6754, 0x4A5E, - 0x345C, 0xF560, 0xD673, 0x4124, 0x3D58, 0xD674, 0x4971, 0x3D2E, - 0, 0xF561, 0xF562, 0, 0, 0, 0, 0, - 0xD677, 0x6755, 0x3952, 0x6756, 0x484C, 0, 0x6764, 0, - 0, 0, 0xF564, 0x6758, 0xF565, 0x4249, 0x4775, 0x383F, - 0x6757, 0x4125, 0xD67A, 0, 0xF566, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E889[] = { - 0x6759, 0, 0, 0xD67B, 0xD67C, 0xD67D, 0xD67E, 0x447A, - 0, 0, 0, 0xD721, 0, 0, 0xD722, 0xD723, - 0, 0xD724, 0, 0, 0, 0, 0xD725, 0, - 0x675B, 0x675A, 0x675D, 0, 0xD726, 0x675C, 0, 0x675E, - 0xD727, 0, 0x6760, 0xD728, 0x675F, 0, 0x344F, 0xD729, - 0x6761, 0, 0x6762, 0x6763, 0, 0xD72A, 0x3A31, 0x4E49, - 0, 0x6765, 0x3F27, 0, 0xD72B, 0, 0x3170, 0x6766, - 0x6767, 0, 0, 0xD72C, 0, 0xD72D, 0x6768, 0xD72E, -}; -static const unsigned short utf8_to_euc_E889_x0213[] = { - 0x6759, 0, 0, 0xD67B, 0xD67C, 0xF569, 0xF567, 0x447A, - 0, 0xF568, 0, 0xF56B, 0, 0, 0xD722, 0xF56D, - 0, 0xD724, 0, 0, 0, 0, 0xD725, 0xF56F, - 0x675B, 0x675A, 0x675D, 0, 0xF571, 0x675C, 0, 0x675E, - 0x7A5B, 0, 0x6760, 0xF572, 0x675F, 0, 0x344F, 0xD729, - 0x6761, 0, 0x6762, 0x6763, 0, 0xD72A, 0x3A31, 0x4E49, - 0, 0x6765, 0x3F27, 0, 0x7A5C, 0, 0x3170, 0x6766, - 0x6767, 0xF576, 0, 0xD72C, 0, 0xF578, 0x6768, 0xF579, -}; -static const unsigned short utf8_to_euc_E88A[] = { - 0xD72F, 0xD730, 0, 0xD731, 0xD732, 0, 0, 0xD733, - 0, 0xD734, 0xD735, 0x3072, 0, 0x6769, 0xD736, 0, - 0, 0xD737, 0x676A, 0, 0xD738, 0, 0xD739, 0, - 0xD73A, 0x4967, 0xD73B, 0xD73C, 0, 0x3C47, 0, 0x676C, - 0xD73D, 0xD73E, 0, 0xD73F, 0xD740, 0x3329, 0x3032, 0xD741, - 0xD742, 0xD743, 0xD744, 0x676B, 0x676E, 0x474E, 0xD745, 0x3F44, - 0xD746, 0x3256, 0xD747, 0x4B27, 0xD748, 0, 0, 0xD749, - 0x375D, 0x365C, 0xD74A, 0x676D, 0xD74B, 0x326A, 0xD74C, 0xD74D, -}; -static const unsigned short utf8_to_euc_E88A_x0213[] = { - 0xD72F, 0xD730, 0, 0xF57A, 0xD732, 0, 0, 0xD733, - 0, 0xD734, 0xF57B, 0x3072, 0, 0x6769, 0x7A5E, 0, - 0, 0xD737, 0x676A, 0xF57C, 0xD738, 0, 0xD739, 0, - 0xD73A, 0x4967, 0xD73B, 0xD73C, 0, 0x3C47, 0, 0x676C, - 0xD73D, 0x7A5F, 0, 0x7A60, 0x7A61, 0x3329, 0x3032, 0xF57D, - 0xF57E, 0x7A62, 0xD744, 0x676B, 0x676E, 0x474E, 0x7A63, 0x3F44, - 0xD746, 0x3256, 0xF621, 0x4B27, 0xF622, 0, 0, 0x7A64, - 0x375D, 0x365C, 0xF623, 0x676D, 0xF624, 0x326A, 0x7A65, 0x7A66, -}; -static const unsigned short utf8_to_euc_E88B[] = { - 0, 0, 0, 0, 0, 0x3423, 0xD74E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xD74F, 0x3171, 0x6772, 0x4E6A, 0x425D, 0xD750, 0, 0x4944, - 0, 0x677E, 0xD751, 0x3257, 0x677C, 0, 0x677A, 0x6771, - 0xD752, 0x676F, 0xD753, 0x6770, 0xD754, 0x3C63, 0x366C, 0x4377, - 0xD755, 0, 0xD756, 0x4651, 0, 0xD757, 0, 0xD758, - 0, 0x3151, 0, 0x6774, 0x6773, 0, 0xD759, 0xD75A, - 0, 0x6779, 0x6775, 0x6778, 0, 0xD75B, 0xD75C, 0, -}; -static const unsigned short utf8_to_euc_E88B_x0213[] = { - 0, 0, 0, 0, 0, 0x3423, 0x7A67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xD74F, 0x3171, 0x6772, 0x4E6A, 0x425D, 0x7A68, 0, 0x4944, - 0, 0x677E, 0xD751, 0x3257, 0x677C, 0, 0x677A, 0x6771, - 0xD752, 0x676F, 0xF625, 0x6770, 0xD754, 0x3C63, 0x366C, 0x4377, - 0xF626, 0, 0xD756, 0x4651, 0, 0xD757, 0, 0xD758, - 0, 0x3151, 0, 0x6774, 0x6773, 0, 0xD759, 0xF627, - 0, 0x6779, 0x6775, 0x6778, 0, 0x7A69, 0x7A6A, 0, -}; -static const unsigned short utf8_to_euc_E88C[] = { - 0xD75D, 0xD75E, 0x4C50, 0x6777, 0x3258, 0x337D, 0x677B, 0xD75F, - 0xD760, 0x677D, 0xD761, 0xD762, 0, 0, 0x3754, 0, - 0, 0, 0, 0, 0, 0, 0x6823, 0x682C, - 0x682D, 0, 0, 0xD764, 0x302B, 0xD765, 0xD766, 0xD767, - 0, 0xD768, 0xD769, 0x6834, 0, 0, 0, 0, - 0x3071, 0, 0, 0x682B, 0xD76A, 0xD76B, 0xD76C, 0x682A, - 0xD76D, 0x6825, 0x6824, 0xD76E, 0x6822, 0x6821, 0x4363, 0xD76F, - 0x427B, 0x6827, 0xD770, 0, 0xD771, 0xD772, 0, 0, -}; -static const unsigned short utf8_to_euc_E88C_x0213[] = { - 0x7A6B, 0x7A6C, 0x4C50, 0x6777, 0x3258, 0x337D, 0x677B, 0xF628, - 0xF629, 0x677D, 0xD761, 0xD762, 0xF62A, 0, 0x3754, 0, - 0, 0, 0, 0, 0, 0, 0x6823, 0x682C, - 0x682D, 0, 0, 0xF62C, 0x302B, 0xF62D, 0xD766, 0xD767, - 0, 0xD768, 0x7A6E, 0x6834, 0, 0, 0, 0, - 0x3071, 0, 0, 0x682B, 0xD76A, 0x7A6F, 0xD76C, 0x682A, - 0xF62E, 0x6825, 0x6824, 0xD76E, 0x6822, 0x6821, 0x4363, 0xD76F, - 0x427B, 0x6827, 0x7A70, 0, 0xF62F, 0xD772, 0, 0, -}; -static const unsigned short utf8_to_euc_E88D[] = { - 0x6826, 0, 0xD773, 0xD774, 0xD775, 0x6829, 0, 0xD776, - 0, 0x4170, 0x3755, 0, 0, 0xD777, 0xD778, 0x3141, - 0x6828, 0xD779, 0x3953, 0xD83E, 0xD763, 0xD77A, 0xD77B, 0xD77C, - 0x4171, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xF45F, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xD77D, 0, 0, 0x683A, 0, 0x683B, 0, 0x3259, - 0xD77E, 0, 0, 0x322E, 0x6838, 0xD821, 0, 0xD822, -}; -static const unsigned short utf8_to_euc_E88D_x0213[] = { - 0x6826, 0, 0xD773, 0x7A71, 0xF630, 0x6829, 0, 0x7A72, - 0, 0x4170, 0x3755, 0, 0, 0xD777, 0xD778, 0x3141, - 0x6828, 0x7A73, 0x3953, 0xD83E, 0xF62B, 0x7A74, 0xD77B, 0xF631, - 0x4171, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x7A6D, 0xAE4A, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xD77D, 0, 0, 0x683A, 0, 0x683B, 0, 0x3259, - 0xD77E, 0, 0, 0x322E, 0x6838, 0x7A75, 0, 0xF633, -}; -static const unsigned short utf8_to_euc_E88E[] = { - 0xD823, 0, 0xD824, 0, 0xD825, 0x682E, 0xD826, 0x6836, - 0, 0x683D, 0x6837, 0, 0, 0xD827, 0x6835, 0, - 0, 0, 0xD828, 0x6776, 0xD829, 0xD82A, 0x6833, 0, - 0xD82B, 0xD82C, 0x682F, 0xD82D, 0xD82E, 0xD82F, 0x3450, 0x6831, - 0x683C, 0, 0x6832, 0, 0, 0, 0xD830, 0xD831, - 0x683E, 0xD832, 0x6830, 0x477C, 0xD833, 0xD84C, 0, 0, - 0, 0x4D69, 0, 0, 0, 0x6839, 0, 0, - 0, 0, 0, 0, 0, 0x684F, 0xD834, 0xD835, -}; -static const unsigned short utf8_to_euc_E88E_x0213[] = { - 0xD823, 0, 0xD824, 0, 0xD825, 0x682E, 0x7A76, 0x6836, - 0, 0x683D, 0x6837, 0, 0, 0xF636, 0x6835, 0, - 0, 0, 0x7A77, 0x6776, 0xF637, 0xF638, 0x6833, 0, - 0x7A78, 0xD82C, 0x682F, 0xF639, 0xD82E, 0xF63A, 0x3450, 0x6831, - 0x683C, 0, 0x6832, 0, 0, 0, 0xD830, 0x7A79, - 0x683E, 0x7A7A, 0x6830, 0x477C, 0xD833, 0xD84C, 0, 0, - 0, 0x4D69, 0, 0, 0, 0x6839, 0, 0, - 0, 0, 0, 0, 0, 0x684F, 0xD834, 0x7A7B, -}; -static const unsigned short utf8_to_euc_E88F[] = { - 0xD836, 0x6847, 0, 0, 0, 0x3F7B, 0, 0xD837, - 0, 0xD838, 0x3546, 0, 0x365D, 0, 0x6842, 0xD839, - 0xD83A, 0xD83B, 0, 0x325B, 0xD83C, 0, 0x3E54, 0, - 0x6845, 0, 0, 0, 0x3A5A, 0xD83D, 0, 0x4551, - 0x684A, 0, 0, 0, 0, 0, 0, 0, - 0xD83F, 0x4A6E, 0xD840, 0x6841, 0, 0, 0, 0x325A, - 0x3856, 0x4929, 0x684B, 0, 0x683F, 0, 0xD841, 0x6848, - 0xD842, 0xD843, 0, 0x6852, 0xD844, 0x6843, 0, 0, -}; -static const unsigned short utf8_to_euc_E88F_x0213[] = { - 0x7A7C, 0x6847, 0, 0, 0, 0x3F7B, 0, 0x7A7D, - 0, 0xF63B, 0x3546, 0, 0x365D, 0, 0x6842, 0x7A7E, - 0xF63C, 0x7B21, 0, 0x325B, 0xF63D, 0, 0x3E54, 0, - 0x6845, 0, 0, 0, 0x3A5A, 0xF63E, 0, 0x4551, - 0x684A, 0x7B22, 0, 0, 0, 0xF63F, 0, 0, - 0xD83F, 0x4A6E, 0x7B23, 0x6841, 0, 0, 0, 0x325A, - 0x3856, 0x4929, 0x684B, 0, 0x683F, 0, 0, 0x6848, - 0xD842, 0xF640, 0, 0x6852, 0xD844, 0x6843, 0, 0, -}; -static const unsigned short utf8_to_euc_E890[] = { - 0, 0xD845, 0, 0x6844, 0x463A, 0, 0xD846, 0x6849, - 0, 0, 0xD847, 0x6846, 0x4B28, 0x684C, 0x3060, 0xD848, - 0, 0xD849, 0, 0x6840, 0, 0xD84A, 0, 0, - 0, 0xD84B, 0, 0, 0, 0, 0, 0, - 0x684E, 0, 0x684D, 0, 0, 0, 0, 0, - 0, 0x476B, 0x6854, 0, 0x685F, 0, 0, 0xD84D, - 0, 0x337E, 0, 0, 0, 0x6862, 0, 0, - 0x6850, 0xD84E, 0, 0, 0x6855, 0x4D6E, 0, 0, -}; -static const unsigned short utf8_to_euc_E890_x0213[] = { - 0, 0x7B24, 0, 0x6844, 0x463A, 0, 0x7B25, 0x6849, - 0, 0, 0x7B26, 0x6846, 0x4B28, 0x684C, 0x3060, 0xF641, - 0, 0xF642, 0, 0x6840, 0, 0xF643, 0, 0xF645, - 0, 0xD84B, 0, 0, 0, 0, 0, 0, - 0x684E, 0, 0x684D, 0, 0, 0, 0, 0, - 0, 0x476B, 0x6854, 0, 0x685F, 0, 0, 0xD84D, - 0, 0x337E, 0, 0, 0, 0x6862, 0, 0, - 0x6850, 0xF646, 0, 0, 0x6855, 0x4D6E, 0, 0, -}; -static const unsigned short utf8_to_euc_E891[] = { - 0, 0, 0, 0, 0, 0xD84F, 0x685E, 0xD850, - 0xD851, 0x4D55, 0xD852, 0, 0, 0xD853, 0x4E2A, 0xD854, - 0, 0xD855, 0xD856, 0, 0, 0, 0xD857, 0x4378, - 0xD858, 0xD859, 0xD85A, 0x336B, 0xD85B, 0, 0, 0, - 0xD85C, 0x4972, 0x6864, 0x4621, 0xD85D, 0xD85E, 0x3031, 0xD85F, - 0, 0x685D, 0xD860, 0x6859, 0x4172, 0x6853, 0x685B, 0x6860, - 0xD861, 0x472C, 0, 0xD862, 0xD863, 0x302A, 0xD864, 0x6858, - 0xD865, 0x6861, 0x4978, 0, 0xD866, 0xD867, 0, 0, -}; -static const unsigned short utf8_to_euc_E891_x0213[] = { - 0, 0, 0, 0, 0, 0xD84F, 0x685E, 0xD850, - 0x7B28, 0x4D55, 0xF647, 0, 0, 0xD853, 0x4E2A, 0xF648, - 0, 0xF649, 0xF64A, 0, 0, 0, 0xD857, 0x4378, - 0xD858, 0xF64B, 0xF64C, 0x336B, 0xF64D, 0, 0, 0x7B29, - 0xD85C, 0x4972, 0x6864, 0x4621, 0xD85D, 0xF64F, 0x3031, 0xD85F, - 0, 0x685D, 0xD860, 0x6859, 0x4172, 0x6853, 0x685B, 0x6860, - 0x7B2A, 0x472C, 0, 0x7B2B, 0xD863, 0x302A, 0xF650, 0x6858, - 0xF651, 0x6861, 0x4978, 0, 0xF652, 0xD867, 0, 0, -}; -static const unsigned short utf8_to_euc_E892[] = { - 0, 0xD868, 0x685C, 0, 0x6857, 0xD869, 0, 0, - 0, 0, 0, 0x3E55, 0, 0, 0, 0, - 0x3D2F, 0, 0xD86A, 0xD86B, 0x3C2C, 0xD86C, 0, 0, - 0, 0x4C58, 0, 0, 0x4947, 0, 0xD86D, 0x6867, - 0, 0x6870, 0, 0, 0, 0, 0xD86E, 0, - 0xD86F, 0xD870, 0xD871, 0, 0, 0x685A, 0, 0xD872, - 0, 0xD873, 0x3377, 0, 0xD874, 0, 0, 0, - 0x3E78, 0x6865, 0xD875, 0x686A, 0x4173, 0xD876, 0xD877, 0x6866, -}; -static const unsigned short utf8_to_euc_E892_x0213[] = { - 0, 0xF653, 0x685C, 0, 0x6857, 0x7B2C, 0, 0, - 0, 0, 0, 0x3E55, 0, 0, 0, 0, - 0x3D2F, 0, 0xD86A, 0xD86B, 0x3C2C, 0xD86C, 0, 0xF656, - 0, 0x4C58, 0, 0, 0x4947, 0, 0x7B2D, 0x6867, - 0, 0x6870, 0, 0, 0, 0, 0xF657, 0, - 0xD86F, 0xD870, 0xD871, 0, 0, 0x685A, 0, 0x7B2E, - 0, 0xD873, 0x3377, 0, 0x7B2F, 0, 0, 0, - 0x3E78, 0x6865, 0x7B30, 0x686A, 0x4173, 0xD876, 0xF658, 0x6866, -}; -static const unsigned short utf8_to_euc_E893[] = { - 0xD878, 0x686D, 0xD879, 0, 0x435F, 0, 0x686E, 0xD87A, - 0xD87B, 0x4D56, 0x6863, 0x3338, 0xD87C, 0x6869, 0, 0xD87D, - 0x686C, 0x4C2C, 0, 0xD87E, 0, 0, 0x686F, 0, - 0, 0x6868, 0x686B, 0, 0xD921, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xD922, - 0, 0, 0xD923, 0, 0x4B29, 0, 0x4F21, 0xD924, - 0xD925, 0xD926, 0xD927, 0, 0x6873, 0, 0, 0xD928, - 0, 0, 0xD92A, 0xD92B, 0x687A, 0xD92C, 0, 0x6872, -}; -static const unsigned short utf8_to_euc_E893_x0213[] = { - 0x7B31, 0x686D, 0x7B32, 0, 0x435F, 0, 0x686E, 0xD87A, - 0xD87B, 0x4D56, 0x6863, 0x3338, 0xD87C, 0x6869, 0xF65A, 0xF65B, - 0x686C, 0x4C2C, 0, 0xF65C, 0, 0, 0x686F, 0, - 0, 0x6868, 0x686B, 0, 0xF655, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xF65E, - 0, 0, 0xF65F, 0, 0x4B29, 0, 0x4F21, 0xF660, - 0xF661, 0xF662, 0xD927, 0, 0x6873, 0, 0, 0xD928, - 0, 0, 0xF663, 0xD92B, 0x687A, 0xF664, 0, 0x6872, -}; -static const unsigned short utf8_to_euc_E894[] = { - 0x3C43, 0, 0xD92D, 0xD92E, 0, 0, 0x6851, 0xD92F, - 0, 0, 0, 0, 0xD930, 0, 0xD931, 0, - 0xD932, 0x4A4E, 0, 0x4C22, 0x6879, 0x6878, 0, 0x6874, - 0x6875, 0, 0x3136, 0, 0xD933, 0, 0xD934, 0x6877, - 0, 0x6871, 0xD935, 0xD936, 0xD937, 0xD938, 0x4455, 0xD939, - 0, 0, 0xD93A, 0xD93B, 0x6876, 0x307E, 0, 0xD93C, - 0, 0, 0xD929, 0xD93D, 0xD93E, 0x4222, 0xD93F, 0, - 0, 0, 0, 0, 0, 0x4A43, 0, 0xD940, -}; -static const unsigned short utf8_to_euc_E894_x0213[] = { - 0x3C43, 0, 0xD92D, 0xD92E, 0, 0, 0x6851, 0xD92F, - 0, 0, 0, 0, 0xF665, 0, 0xD931, 0, - 0xD932, 0x4A4E, 0, 0x4C22, 0x6879, 0x6878, 0, 0x6874, - 0x6875, 0, 0x3136, 0xF666, 0xD933, 0, 0x7B35, 0x6877, - 0, 0x6871, 0xD935, 0x7B36, 0xF667, 0xF668, 0x4455, 0xD939, - 0, 0, 0xD93A, 0xF669, 0x6876, 0x307E, 0, 0x7B37, - 0, 0, 0x7B34, 0xD93D, 0xF66A, 0x4222, 0xD93F, 0, - 0, 0, 0, 0, 0, 0x4A43, 0xF66F, 0xD940, -}; -static const unsigned short utf8_to_euc_E895[] = { - 0x687B, 0x6921, 0, 0x4859, 0, 0, 0xD941, 0, - 0x687E, 0x3E56, 0x3C49, 0x6923, 0, 0, 0x363E, 0xD942, - 0xD943, 0xD944, 0xD945, 0xD946, 0, 0x6924, 0xD947, 0x4979, - 0x687D, 0xD948, 0x6856, 0, 0xD949, 0xD94A, 0xD94B, 0xD94C, - 0xD94D, 0xD94E, 0xD94F, 0x687C, 0xD950, 0, 0, 0, - 0x4F4F, 0x4622, 0x4973, 0xD951, 0, 0x692B, 0, 0xD952, - 0, 0, 0, 0, 0, 0, 0, 0x6931, - 0, 0xD953, 0xD954, 0xD955, 0, 0xD956, 0x6932, 0xD957, -}; -static const unsigned short utf8_to_euc_E895_x0213[] = { - 0x687B, 0x6921, 0, 0x4859, 0, 0, 0xD941, 0, - 0x687E, 0x3E56, 0x3C49, 0x6923, 0, 0, 0x363E, 0xF66B, - 0xD943, 0xF670, 0xD945, 0xF671, 0, 0x6924, 0xD947, 0x4979, - 0x687D, 0x7B38, 0x6856, 0, 0xD949, 0xD94A, 0xF672, 0xD94C, - 0xD94D, 0xF673, 0xF674, 0x687C, 0x7B39, 0, 0, 0, - 0x4F4F, 0x4622, 0x4973, 0, 0, 0x692B, 0, 0xF66C, - 0, 0, 0, 0, 0, 0, 0, 0x6931, - 0, 0xD953, 0x7B3C, 0xF676, 0, 0xF677, 0x6932, 0xF678, -}; -static const unsigned short utf8_to_euc_E896[] = { - 0x6925, 0xD958, 0, 0, 0x4776, 0xD959, 0xD95A, 0x692F, - 0x6927, 0xD95B, 0x6929, 0xD95C, 0xD95D, 0, 0, 0xD95E, - 0x6933, 0x6928, 0, 0xD95F, 0x692C, 0, 0, 0x3172, - 0xD960, 0x4665, 0, 0x692D, 0x6930, 0xD961, 0, 0xD962, - 0xD963, 0, 0xD964, 0, 0x6926, 0xD965, 0x4126, 0xD966, - 0x692A, 0x3B27, 0x3F45, 0x3730, 0x4C74, 0xD974, 0x4C79, 0x3D72, - 0xF461, 0, 0, 0, 0xD967, 0, 0xD968, 0xD969, - 0xD96A, 0x6937, 0x6935, 0, 0xD96B, 0xD96C, 0xD96D, 0xD96E, -}; -static const unsigned short utf8_to_euc_E896_x0213[] = { - 0x6925, 0xF679, 0, 0, 0x4776, 0xD959, 0xF67A, 0x692F, - 0x6927, 0xD95B, 0x6929, 0xD95C, 0x7B3D, 0, 0, 0x7B3E, - 0x6933, 0x6928, 0, 0xF67B, 0x692C, 0, 0, 0x3172, - 0xD960, 0x4665, 0, 0x692D, 0x6930, 0xF67C, 0, 0xF67D, - 0xD963, 0, 0x7B3F, 0, 0x6926, 0xD965, 0x4126, 0xD966, - 0x692A, 0x3B27, 0x3F45, 0x3730, 0x4C74, 0x7B3B, 0x4C79, 0x3D72, - 0x7B40, 0, 0, 0, 0xD967, 0, 0xD968, 0xF723, - 0xD96A, 0x6937, 0x6935, 0, 0xF724, 0xD96C, 0xD96D, 0xD96E, -}; -static const unsigned short utf8_to_euc_E897[] = { - 0, 0x4F4E, 0xD96F, 0, 0, 0, 0, 0xD970, - 0, 0x6934, 0xD971, 0xD972, 0, 0x4D75, 0xD973, 0x6936, - 0x6938, 0, 0, 0, 0, 0x6939, 0, 0, - 0xD975, 0, 0xD976, 0, 0x693C, 0x693A, 0, 0xD977, - 0xD978, 0, 0, 0, 0x4623, 0x693B, 0xD979, 0, - 0xD97A, 0x484D, 0x692E, 0, 0, 0xD97B, 0, 0, - 0, 0, 0, 0xD97C, 0, 0, 0xD97D, 0x3D73, - 0, 0x693D, 0x6942, 0x4174, 0xD97E, 0, 0x6941, 0xDA21, -}; -static const unsigned short utf8_to_euc_E897_x0213[] = { - 0, 0x4F4E, 0xD96F, 0, 0, 0, 0, 0xF725, - 0, 0x6934, 0xF726, 0x7B41, 0, 0x4D75, 0x7B42, 0x6936, - 0x6938, 0, 0, 0, 0, 0x6939, 0, 0, - 0xF727, 0xF728, 0xD976, 0, 0x693C, 0x693A, 0, 0xF729, - 0xD978, 0xF72A, 0, 0, 0x4623, 0x693B, 0xF72B, 0, - 0xD97A, 0x484D, 0x692E, 0, 0, 0x7B43, 0, 0, - 0, 0, 0, 0xD97C, 0, 0, 0xF72C, 0x3D73, - 0, 0x693D, 0x6942, 0x4174, 0xD97E, 0, 0x6941, 0x7B45, -}; -static const unsigned short utf8_to_euc_E898[] = { - 0xDA22, 0, 0x6922, 0, 0xDA23, 0xDA24, 0x6943, 0x4149, - 0, 0, 0x693E, 0x6940, 0, 0xDA25, 0xDA26, 0, - 0xDA27, 0xDA28, 0xDA29, 0x693F, 0, 0, 0x5D31, 0x5D22, - 0xDA2A, 0xDA2B, 0x6945, 0xDA2C, 0, 0, 0xDA2D, 0, - 0, 0xDA2E, 0x6944, 0, 0, 0, 0, 0xDA2F, - 0, 0xDA30, 0, 0, 0, 0x4D76, 0, 0x623C, - 0x6946, 0, 0, 0, 0, 0, 0xDA31, 0, - 0xDA32, 0, 0xDA33, 0, 0xDA34, 0xDA35, 0, 0x6947, -}; -static const unsigned short utf8_to_euc_E898_x0213[] = { - 0xF72D, 0, 0x6922, 0, 0x7B46, 0x7B47, 0x6943, 0x4149, - 0, 0, 0x693E, 0x6940, 0, 0xDA25, 0xDA26, 0, - 0x7B48, 0xF72E, 0x7B44, 0x693F, 0, 0, 0x5D31, 0x5D22, - 0x7B4A, 0xDA2B, 0x6945, 0xDA2C, 0, 0, 0xF72F, 0, - 0, 0xF730, 0x6944, 0, 0xF731, 0, 0, 0xF732, - 0, 0x7B4B, 0, 0, 0, 0x4D76, 0, 0x623C, - 0x6946, 0, 0, 0, 0, 0, 0xDA31, 0, - 0x7B4C, 0xF734, 0xDA33, 0, 0xF735, 0xDA35, 0, 0x6947, -}; -static const unsigned short utf8_to_euc_E899[] = { - 0xDA36, 0xB866, 0xDA37, 0, 0, 0, 0xDA38, 0, - 0, 0, 0, 0, 0, 0x6948, 0x3857, 0, - 0x3554, 0, 0xDA39, 0xDA3A, 0x694A, 0x515D, 0xDA3B, 0xDA3C, - 0xDA3D, 0xDA3E, 0x3575, 0, 0x4E3A, 0xDA3F, 0x3673, 0x694B, - 0xDA40, 0xDA41, 0xDA42, 0xDA43, 0xDA44, 0, 0, 0x694C, - 0, 0xDA45, 0, 0x436E, 0xDA46, 0, 0, 0xDA47, - 0, 0x694D, 0, 0, 0, 0xDA48, 0xDA49, 0xDA4A, - 0, 0x467A, 0xDA4B, 0x303A, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E899_x0213[] = { - 0xF737, 0x2F68, 0xDA37, 0, 0, 0, 0xDA38, 0, - 0, 0, 0, 0, 0, 0x6948, 0x3857, 0, - 0x3554, 0, 0xDA39, 0xF739, 0x694A, 0x515D, 0xF73A, 0x7B4D, - 0xDA3D, 0xDA3E, 0x3575, 0x7B4E, 0x4E3A, 0xDA3F, 0x3673, 0x694B, - 0xDA40, 0xDA41, 0x7B50, 0xDA43, 0xDA44, 0, 0, 0x694C, - 0, 0xDA45, 0, 0x436E, 0x7B52, 0, 0, 0xF73B, - 0, 0x694D, 0, 0, 0, 0x7B53, 0xDA49, 0xF73C, - 0, 0x467A, 0xF73D, 0x303A, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E89A[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0xDA6D, 0, 0x3263, 0x6952, 0x6953, 0xDA4C, 0, 0, - 0, 0xDA4D, 0, 0x694E, 0, 0x3B3D, 0xDA4E, 0, - 0xDA4F, 0, 0xDA50, 0, 0xDA51, 0, 0, 0, - 0, 0xDA52, 0, 0x694F, 0x4742, 0, 0xDA53, 0xDA54, - 0xDA55, 0x6950, 0x6951, 0x695B, 0, 0xDA56, 0, 0x6955, - 0x6958, 0xDA57, 0, 0xDA58, 0xDA59, 0xDA5A, 0x6954, 0xDA5B, - 0xDA5C, 0xDA5D, 0, 0, 0, 0, 0, 0xDA5E, -}; -static const unsigned short utf8_to_euc_E89A_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0xF73E, - 0xDA6D, 0xF73F, 0x3263, 0x6952, 0x6953, 0xF740, 0, 0, - 0, 0xF741, 0, 0x694E, 0, 0x3B3D, 0xDA4E, 0, - 0x7B54, 0, 0xDA50, 0, 0xF742, 0xF743, 0, 0, - 0, 0xDA52, 0, 0x694F, 0x4742, 0, 0xDA53, 0xDA54, - 0xF744, 0x6950, 0x6951, 0x695B, 0, 0xDA56, 0, 0x6955, - 0x6958, 0xF746, 0, 0xF747, 0xDA59, 0xDA5A, 0x6954, 0xDA5B, - 0x7B55, 0xDA5D, 0, 0, 0, 0, 0, 0xDA5E, -}; -static const unsigned short utf8_to_euc_E89B[] = { - 0xDA5F, 0xDA60, 0, 0xDA61, 0x6956, 0xDA62, 0x6957, 0x3C58, - 0, 0x6959, 0, 0x4341, 0, 0x3756, 0x3342, 0, - 0, 0xDA63, 0xDA64, 0, 0x695C, 0xDA65, 0, 0xDA66, - 0, 0x333F, 0xDA67, 0x6961, 0xDA68, 0, 0x695D, 0x6960, - 0xDA69, 0, 0, 0xDA6A, 0x483A, 0xDA6B, 0, 0xDA6C, - 0, 0x695E, 0, 0, 0x695F, 0x4948, 0x485A, 0x6962, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x427D, 0x696C, 0xDA6E, 0x6968, 0xDA6F, 0xDA70, 0x326B, 0, -}; -static const unsigned short utf8_to_euc_E89B_x0213[] = { - 0xDA5F, 0xF748, 0, 0xF749, 0x6956, 0xDA62, 0x6957, 0x3C58, - 0, 0x6959, 0, 0x4341, 0, 0x3756, 0x3342, 0, - 0, 0xF74A, 0xDA64, 0, 0x695C, 0xF74B, 0, 0xF74C, - 0, 0x333F, 0xDA67, 0x6961, 0xDA68, 0, 0x695D, 0x6960, - 0xDA69, 0, 0, 0xF74D, 0x483A, 0xDA6B, 0xF74E, 0xDA6C, - 0, 0x695E, 0, 0, 0x695F, 0x4948, 0x485A, 0x6962, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x427D, 0x696C, 0x7B56, 0x6968, 0x7B57, 0x7B58, 0x326B, 0, -}; -static const unsigned short utf8_to_euc_E89C[] = { - 0x6966, 0, 0x4B2A, 0x6967, 0xDA71, 0xDA72, 0x6964, 0xDA73, - 0x6965, 0x696A, 0x696D, 0xDA74, 0, 0x696B, 0xDA75, 0xDA76, - 0xDA77, 0x6969, 0x6963, 0xDA78, 0xDA79, 0, 0, 0, - 0x4358, 0xDA7A, 0x6974, 0, 0x4C2A, 0, 0xDA7B, 0xDA7C, - 0, 0xDA7D, 0, 0xDA7E, 0, 0x6972, 0, 0, - 0xDB21, 0x6973, 0, 0, 0, 0, 0xDB22, 0xDB23, - 0, 0xDB24, 0xDB25, 0, 0x696E, 0, 0, 0x6970, - 0, 0xDB26, 0xDB27, 0x6971, 0xDB28, 0xDB29, 0xDB2A, 0x696F, -}; -static const unsigned short utf8_to_euc_E89C_x0213[] = { - 0x6966, 0, 0x4B2A, 0x6967, 0xDA71, 0xF750, 0x6964, 0xF751, - 0x6965, 0x696A, 0x696D, 0x7B59, 0, 0x696B, 0xF752, 0xDA76, - 0xF753, 0x6969, 0x6963, 0xF754, 0xDA79, 0, 0, 0, - 0x4358, 0xF755, 0x6974, 0, 0x4C2A, 0, 0xDA7B, 0xF756, - 0, 0xF757, 0, 0xF758, 0, 0x6972, 0, 0, - 0xDB21, 0x6973, 0, 0, 0, 0, 0xDB22, 0xDB23, - 0, 0xF759, 0xDB25, 0, 0x696E, 0, 0, 0x6970, - 0, 0xDB26, 0xF75A, 0x6971, 0xDB28, 0xDB29, 0xF75B, 0x696F, -}; -static const unsigned short utf8_to_euc_E89D[] = { - 0xDB2B, 0, 0, 0xDB2C, 0, 0xDB2D, 0, 0, - 0, 0x4066, 0, 0x4F39, 0x6978, 0xDB2E, 0x6979, 0, - 0, 0, 0, 0x6A21, 0, 0x3F2A, 0, 0x697B, - 0xDB2F, 0x697E, 0, 0, 0, 0xDB30, 0, 0x6976, - 0x6975, 0xDB31, 0, 0x6A22, 0xDB32, 0xDB33, 0x325C, 0, - 0x697C, 0, 0x6A23, 0, 0, 0, 0x697D, 0xDB34, - 0, 0xDB35, 0xDB36, 0, 0x697A, 0, 0x4433, 0, - 0x6977, 0, 0, 0xDB37, 0, 0, 0, 0x4768, -}; -static const unsigned short utf8_to_euc_E89D_x0213[] = { - 0xF75C, 0, 0, 0xF75D, 0, 0xDB2D, 0, 0, - 0, 0x4066, 0, 0x4F39, 0x6978, 0xDB2E, 0x6979, 0, - 0, 0xF75E, 0, 0x6A21, 0, 0x3F2A, 0, 0x697B, - 0xF75F, 0x697E, 0, 0, 0, 0xDB30, 0, 0x6976, - 0x6975, 0xDB31, 0, 0x6A22, 0xF760, 0xF761, 0x325C, 0, - 0x697C, 0, 0x6A23, 0, 0, 0, 0x697D, 0xDB34, - 0, 0x7B5A, 0xF762, 0, 0x697A, 0, 0x4433, 0, - 0x6977, 0, 0, 0xDB37, 0xF763, 0, 0, 0x4768, -}; -static const unsigned short utf8_to_euc_E89E[] = { - 0, 0, 0x6A27, 0xDB38, 0xDB39, 0xDB3A, 0xDB3B, 0xDB3C, - 0xDB3D, 0xDB3E, 0, 0xDB3F, 0xDB40, 0x4D3B, 0, 0, - 0xDB41, 0, 0, 0xDB42, 0, 0xDB43, 0, 0xDB44, - 0xDB45, 0xDB46, 0, 0, 0, 0, 0xDB47, 0x6A26, - 0xDB48, 0, 0x6A25, 0xDB49, 0, 0, 0, 0xDB4A, - 0, 0, 0, 0x6A2E, 0xDB4B, 0xDB4C, 0xDB4D, 0x6A28, - 0, 0xDB4E, 0, 0x6A30, 0, 0xDB4F, 0, 0, - 0, 0, 0x4D66, 0x6A33, 0, 0x6A2A, 0xDB50, 0xDB51, -}; -static const unsigned short utf8_to_euc_E89E_x0213[] = { - 0, 0, 0x6A27, 0xDB38, 0xDB39, 0xDB3A, 0xDB3B, 0x7B5B, - 0x7B5C, 0xF767, 0, 0xF768, 0xDB40, 0x4D3B, 0, 0, - 0xDB41, 0, 0, 0xF769, 0, 0xDB43, 0, 0xDB44, - 0xDB45, 0xDB46, 0, 0, 0, 0, 0xDB47, 0x6A26, - 0xF76A, 0, 0x6A25, 0xDB49, 0, 0, 0, 0xF766, - 0, 0, 0, 0x6A2E, 0x7B5D, 0x7B5E, 0xDB4D, 0x6A28, - 0, 0xDB4E, 0, 0x6A30, 0, 0x7B5F, 0, 0, - 0, 0, 0x4D66, 0x6A33, 0, 0x6A2A, 0xF76D, 0xDB51, -}; -static const unsigned short utf8_to_euc_E89F[] = { - 0x6A2B, 0xDB52, 0, 0, 0x6A2F, 0, 0x6A32, 0x6A31, - 0xDB53, 0xDB54, 0xDB55, 0x6A29, 0, 0, 0xDB56, 0, - 0x6A2C, 0, 0x6A3D, 0, 0, 0xDB57, 0xDB58, 0, - 0, 0xDB59, 0xDB5A, 0, 0xDB5B, 0, 0, 0xDB5C, - 0x6A36, 0, 0xDB5D, 0xDB5E, 0xDB5F, 0, 0, 0, - 0, 0, 0xDB60, 0xDB61, 0, 0xDB62, 0, 0x6A34, - 0, 0xDB63, 0x6A35, 0xDB64, 0, 0, 0x6A3A, 0x6A3B, - 0xDB65, 0x332A, 0xDB66, 0x3542, 0, 0, 0x6A39, 0xDB67, -}; -static const unsigned short utf8_to_euc_E89F_x0213[] = { - 0x6A2B, 0xF76F, 0, 0, 0x6A2F, 0, 0x6A32, 0x6A31, - 0xDB53, 0xDB54, 0xDB55, 0x6A29, 0, 0, 0xF770, 0, - 0x6A2C, 0, 0x6A3D, 0, 0, 0xDB57, 0x7B61, 0, - 0, 0xDB59, 0xDB5A, 0, 0xDB5B, 0, 0, 0xF772, - 0x6A36, 0, 0xDB5D, 0xF774, 0xDB5F, 0xF775, 0xF776, 0, - 0, 0, 0xF777, 0xF778, 0x7B62, 0xF779, 0, 0x6A34, - 0, 0xDB63, 0x6A35, 0xDB64, 0, 0xF771, 0x6A3A, 0x6A3B, - 0xDB65, 0x332A, 0xDB66, 0x3542, 0, 0, 0x6A39, 0xDB67, -}; -static const unsigned short utf8_to_euc_E8A0[] = { - 0, 0xDB68, 0, 0xDB69, 0, 0x6A24, 0xDB6A, 0xF464, - 0, 0xDB6B, 0xDB6C, 0xDB6D, 0, 0x6A38, 0x6A3C, 0x6A37, - 0xDB6E, 0x6A3E, 0xDB70, 0xDB71, 0xDB72, 0x6A40, 0x6A3F, 0, - 0xDB73, 0xDB6F, 0xDB74, 0xDB75, 0xDB76, 0, 0xDB77, 0xDB78, - 0, 0x6A42, 0x6A41, 0x695A, 0, 0, 0, 0x6A46, - 0xDB79, 0, 0, 0, 0, 0xDB7A, 0xDB7B, 0, - 0xDB7C, 0x6A43, 0xDB7D, 0, 0, 0xDB7E, 0x6A44, 0, - 0, 0x6A45, 0xDC21, 0x6A47, 0xDC22, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8A0_x0213[] = { - 0, 0xF77A, 0, 0xF77B, 0, 0x6A24, 0x7B63, 0, - 0, 0xDB6B, 0x7B64, 0xF77C, 0, 0x6A38, 0x6A3C, 0x6A37, - 0x7B65, 0x6A3E, 0xDB70, 0xF77D, 0x7B66, 0x6A40, 0x6A3F, 0, - 0xDB73, 0xDB6F, 0xDB74, 0xDB75, 0xDB76, 0, 0xDB77, 0x7B67, - 0, 0x6A42, 0x6A41, 0x695A, 0, 0, 0, 0x6A46, - 0xF77E, 0, 0, 0, 0, 0xDB7A, 0xF821, 0, - 0xDB7C, 0x6A43, 0xF822, 0, 0, 0xDB7E, 0x6A44, 0, - 0, 0x6A45, 0xDC21, 0x6A47, 0xF823, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8A1[] = { - 0x376C, 0xDC23, 0x6A49, 0xDC24, 0x6A48, 0xDC25, 0x3D30, 0, - 0xDC26, 0xDC27, 0xDC28, 0xDC29, 0x3954, 0x5E27, 0xDC2A, 0, - 0, 0xDC2B, 0x6A4A, 0x3D51, 0, 0xDC2C, 0xDC2D, 0x3339, - 0xDC2E, 0x6A4B, 0xDC2F, 0x3152, 0xDC30, 0x3E57, 0x6A4C, 0xDC31, - 0xDC32, 0x3955, 0x6A4D, 0x3061, 0xDC33, 0, 0, 0, - 0x493D, 0xDC34, 0, 0x6A4E, 0, 0, 0, 0, - 0x3F6A, 0xDC35, 0x6A55, 0, 0, 0x6A52, 0, 0x436F, - 0, 0xDC36, 0, 0xDC37, 0, 0x6A53, 0x6A50, 0x365E, -}; -static const unsigned short utf8_to_euc_E8A1_x0213[] = { - 0x376C, 0xDC23, 0x6A49, 0xDC24, 0x6A48, 0xDC25, 0x3D30, 0, - 0xDC26, 0xDC27, 0xF825, 0xDC29, 0x3954, 0x5E27, 0xDC2A, 0, - 0, 0xDC2B, 0x6A4A, 0x3D51, 0, 0xDC2C, 0xDC2D, 0x3339, - 0xF826, 0x6A4B, 0xDC2F, 0x3152, 0xDC30, 0x3E57, 0x6A4C, 0xF827, - 0xDC32, 0x3955, 0x6A4D, 0x3061, 0xF828, 0, 0, 0, - 0x493D, 0xF82B, 0, 0x6A4E, 0, 0, 0, 0xF82D, - 0x3F6A, 0xDC35, 0x6A55, 0, 0, 0x6A52, 0, 0x436F, - 0, 0xDC36, 0, 0xDC37, 0, 0x6A53, 0x6A50, 0x365E, -}; -static const unsigned short utf8_to_euc_E8A2[] = { - 0xDC38, 0x6A4F, 0x6A56, 0, 0, 0, 0, 0, - 0x3736, 0, 0, 0x425E, 0, 0x6A5C, 0, 0, - 0, 0, 0x6A58, 0, 0, 0, 0x4235, 0x6A57, - 0xDC39, 0x6A5A, 0xDC3A, 0xDC3B, 0xDC3C, 0, 0x6A51, 0xDC3D, - 0xDC3E, 0, 0x6A5B, 0, 0x6A5D, 0, 0, 0, - 0xDC3F, 0, 0xDC40, 0x486F, 0, 0, 0x6A59, 0, - 0x6A5E, 0x6A60, 0, 0, 0x3853, 0x6A54, 0, 0x3041, - 0, 0, 0xDC41, 0, 0, 0xDC42, 0xDC43, 0x6A5F, -}; -static const unsigned short utf8_to_euc_E8A2_x0213[] = { - 0xDC38, 0x6A4F, 0x6A56, 0, 0, 0, 0, 0, - 0x3736, 0, 0, 0x425E, 0, 0x6A5C, 0, 0, - 0, 0, 0x6A58, 0, 0, 0, 0x4235, 0x6A57, - 0x7B68, 0x6A5A, 0xDC3A, 0xDC3B, 0xDC3C, 0, 0x6A51, 0xDC3D, - 0xF82E, 0, 0x6A5B, 0, 0x6A5D, 0, 0, 0, - 0xDC3F, 0, 0x7B69, 0x486F, 0, 0, 0x6A59, 0, - 0x6A5E, 0x6A60, 0, 0, 0x3853, 0x6A54, 0, 0x3041, - 0, 0, 0xDC41, 0, 0xF82F, 0xF830, 0xF831, 0x6A5F, -}; -static const unsigned short utf8_to_euc_E8A3[] = { - 0xDC44, 0x3A5B, 0x4E76, 0x6A61, 0x6A62, 0x4175, 0, 0, - 0, 0, 0xDC45, 0xDC46, 0xDC47, 0xDC48, 0xDC49, 0x4E22, - 0, 0xDC4A, 0xDC4B, 0xDC4C, 0x6A63, 0x4D35, 0, 0, - 0x6A64, 0x6A65, 0, 0xDC4D, 0x4A64, 0x6A66, 0xDC4E, 0x3A40, - 0, 0x4E23, 0, 0, 0, 0, 0, 0xDC4F, - 0x6A6B, 0, 0, 0, 0, 0, 0, 0xDC50, - 0xDC51, 0xDC52, 0x6A6C, 0x3E58, 0x6A6A, 0xDC53, 0, 0xDC54, - 0x4D67, 0x6A67, 0, 0, 0x6A69, 0x403D, 0x3F7E, 0, -}; -static const unsigned short utf8_to_euc_E8A3_x0213[] = { - 0xF832, 0x3A5B, 0x4E76, 0x6A61, 0x6A62, 0x4175, 0, 0, - 0, 0, 0x7B6A, 0xDC46, 0xDC47, 0xDC48, 0x7B6B, 0x4E22, - 0, 0xF835, 0xF833, 0xF836, 0x6A63, 0x4D35, 0, 0, - 0x6A64, 0x6A65, 0, 0xF837, 0x4A64, 0x6A66, 0xDC4E, 0x3A40, - 0, 0x4E23, 0, 0, 0, 0, 0, 0xDC4F, - 0x6A6B, 0, 0, 0, 0, 0, 0, 0xDC50, - 0xF838, 0xF839, 0x6A6C, 0x3E58, 0x6A6A, 0x7B6D, 0, 0xDC54, - 0x4D67, 0x6A67, 0, 0, 0x6A69, 0x403D, 0x3F7E, 0, -}; -static const unsigned short utf8_to_euc_E8A4[] = { - 0, 0xDC55, 0x6A68, 0, 0x6A6D, 0, 0xDC56, 0x4A23, - 0, 0, 0x6A6F, 0, 0x6A6E, 0xDC57, 0xDC58, 0xDC59, - 0x336C, 0, 0x4B2B, 0x6A70, 0, 0xDC5A, 0xDC5B, 0, - 0xDC5C, 0xDC5D, 0xDC5E, 0, 0xDC5F, 0x6A7C, 0x6A72, 0, - 0xDC60, 0, 0, 0, 0, 0x6A73, 0xDC61, 0xDC62, - 0xDC63, 0, 0x6A74, 0x6A75, 0, 0, 0, 0, - 0xDC64, 0xDC65, 0xDC66, 0, 0, 0xDC67, 0x6A79, 0, - 0x6A7A, 0xDC68, 0xDC69, 0x6A78, 0, 0, 0xDC6A, 0, -}; -static const unsigned short utf8_to_euc_E8A4_x0213[] = { - 0, 0xF83B, 0x6A68, 0, 0x6A6D, 0, 0xDC56, 0x4A23, - 0, 0, 0x6A6F, 0, 0x6A6E, 0xDC57, 0xDC58, 0xDC59, - 0x336C, 0, 0x4B2B, 0x6A70, 0, 0xDC5A, 0xDC5B, 0, - 0x7B70, 0x7B71, 0x7B72, 0, 0x7B6E, 0x6A7C, 0x6A72, 0, - 0xDC60, 0, 0, 0, 0, 0x6A73, 0xDC61, 0x7B73, - 0xDC63, 0, 0x6A74, 0x6A75, 0, 0, 0, 0, - 0x7B74, 0xDC65, 0x7B75, 0, 0, 0xDC67, 0x6A79, 0xF83D, - 0x6A7A, 0x7B76, 0xDC69, 0x6A78, 0, 0, 0xDC6A, 0, -}; -static const unsigned short utf8_to_euc_E8A5[] = { - 0xDC6B, 0x6A76, 0xDC6C, 0x6A71, 0x6A77, 0xDC6D, 0xDC6E, 0, - 0, 0xDC6F, 0, 0, 0x6A7B, 0x7037, 0, 0xDC70, - 0, 0, 0xDC71, 0, 0, 0, 0x3228, 0xDC72, - 0, 0, 0xDC73, 0xDC74, 0xDC75, 0, 0x6A7E, 0x365F, - 0x6A7D, 0xDC76, 0xDC77, 0xDC78, 0x6B22, 0, 0x6B21, 0, - 0, 0, 0x6B24, 0xDC79, 0, 0x6B23, 0xDC7A, 0x6B25, - 0xDC7B, 0, 0x3D31, 0xDC7C, 0x6B26, 0xDC7D, 0, 0x6B27, - 0, 0, 0xDC7E, 0xDD21, 0xDD22, 0xDD23, 0x6B28, 0x403E, -}; -static const unsigned short utf8_to_euc_E8A5_x0213[] = { - 0x7B77, 0x6A76, 0xF83F, 0x6A71, 0x6A77, 0xF840, 0xDC6E, 0, - 0, 0xF841, 0, 0, 0x6A7B, 0x7037, 0, 0xDC70, - 0, 0, 0xDC71, 0, 0, 0, 0x3228, 0xDC72, - 0, 0, 0xDC73, 0xDC74, 0xDC75, 0, 0x6A7E, 0x365F, - 0x6A7D, 0xDC76, 0xF844, 0xDC78, 0x6B22, 0, 0x6B21, 0, - 0, 0, 0x6B24, 0xDC79, 0, 0x6B23, 0xDC7A, 0x6B25, - 0xDC7B, 0, 0x3D31, 0xDC7C, 0x6B26, 0xDC7D, 0, 0x6B27, - 0, 0, 0xDC7E, 0xDD21, 0xDD22, 0xDD23, 0x6B28, 0x403E, -}; -static const unsigned short utf8_to_euc_E8A6[] = { - 0, 0x4D57, 0, 0x6B29, 0, 0, 0x4A24, 0x4746, - 0x6B2A, 0xDD24, 0x6B2B, 0x382B, 0, 0xDD25, 0, 0x352C, - 0xDD26, 0, 0, 0x6B2C, 0xDD27, 0xDD28, 0x3B6B, 0x4741, - 0x6B2D, 0, 0x3350, 0xDD29, 0xDD2A, 0, 0, 0xDD2B, - 0xDD2C, 0x6B2E, 0, 0, 0, 0xDD2D, 0x6B30, 0x4D77, - 0, 0x6B2F, 0x3F46, 0, 0x6B31, 0, 0, 0x6B32, - 0xDD2E, 0, 0x6B33, 0x3451, 0xDD2F, 0xDD30, 0xDD31, 0xDD32, - 0, 0, 0x6B34, 0, 0xDD33, 0x6B35, 0, 0x6B36, -}; -static const unsigned short utf8_to_euc_E8A6_x0213[] = { - 0xF845, 0x4D57, 0, 0x6B29, 0, 0, 0x4A24, 0x4746, - 0x6B2A, 0xF846, 0x6B2B, 0x382B, 0, 0xDD25, 0, 0x352C, - 0xF847, 0, 0, 0x6B2C, 0x7B78, 0xDD28, 0x3B6B, 0x4741, - 0x6B2D, 0, 0x3350, 0xDD29, 0xDD2A, 0, 0, 0xF848, - 0xDD2C, 0x6B2E, 0, 0, 0, 0xDD2D, 0x6B30, 0x4D77, - 0, 0x6B2F, 0x3F46, 0, 0x6B31, 0, 0, 0x6B32, - 0xF849, 0, 0x6B33, 0x3451, 0xDD2F, 0xDD30, 0xDD31, 0xF84A, - 0, 0, 0x6B34, 0, 0xDD33, 0x6B35, 0, 0x6B36, -}; -static const unsigned short utf8_to_euc_E8A7[] = { - 0x6B37, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x3351, 0, 0xDD34, 0xDD35, 0xDD36, 0xDD37, - 0xDD38, 0, 0x6B38, 0, 0x6B39, 0x6B3A, 0, 0, - 0, 0, 0, 0x3272, 0, 0xDD39, 0x3F28, 0x6B3B, - 0, 0xDD3A, 0, 0xDD3B, 0, 0xDD3C, 0, 0, - 0, 0xDD3D, 0, 0xDD3E, 0x6B3C, 0, 0xDD3F, 0, - 0x6B3D, 0xDD40, 0, 0, 0, 0xDD41, 0, 0xDD42, -}; -static const unsigned short utf8_to_euc_E8A7_x0213[] = { - 0x6B37, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x3351, 0, 0x7B7A, 0xDD35, 0xF84B, 0xDD37, - 0xF84C, 0, 0x6B38, 0, 0x6B39, 0x6B3A, 0, 0, - 0, 0, 0, 0x3272, 0, 0x7B7B, 0x3F28, 0x6B3B, - 0, 0xDD3A, 0, 0xF84D, 0, 0xDD3C, 0, 0, - 0, 0xF84F, 0, 0xF850, 0x6B3C, 0, 0x7B7C, 0, - 0x6B3D, 0xDD40, 0, 0, 0, 0xF851, 0, 0xF852, -}; -static const unsigned short utf8_to_euc_E8A8[] = { - 0x3840, 0, 0x447B, 0x6B3E, 0xDD43, 0xDD44, 0, 0xDD45, - 0x3757, 0, 0x3F56, 0, 0x6B41, 0, 0x4624, 0xDD46, - 0x6B40, 0xDD47, 0xDD48, 0x3731, 0xDD49, 0xDD4A, 0x6B3F, 0x4277, - 0x352D, 0, 0, 0x6B42, 0, 0x6B43, 0xDD4B, 0x3E59, - 0xDD4C, 0, 0xDD4D, 0x376D, 0xDD4E, 0x6B44, 0xDD4F, 0, - 0, 0, 0x4B2C, 0xDD50, 0xDD51, 0x405F, 0, 0xDD52, - 0, 0x3576, 0, 0x4C75, 0x414A, 0xDD53, 0x6B45, 0xDD54, - 0, 0, 0x3F47, 0x4370, 0x3E5A, 0xDD55, 0xDD56, 0, -}; -static const unsigned short utf8_to_euc_E8A8_x0213[] = { - 0x3840, 0, 0x447B, 0x6B3E, 0xDD43, 0xDD44, 0, 0xDD45, - 0x3757, 0, 0x3F56, 0, 0x6B41, 0, 0x4624, 0xDD46, - 0x6B40, 0xF854, 0x7B7D, 0x3731, 0xF855, 0x7B7E, 0x6B3F, 0x4277, - 0x352D, 0, 0, 0x6B42, 0, 0x6B43, 0xDD4B, 0x3E59, - 0xDD4C, 0xF857, 0x7C21, 0x376D, 0xDD4E, 0x6B44, 0xDD4F, 0, - 0, 0, 0x4B2C, 0xDD50, 0xDD51, 0x405F, 0, 0xDD52, - 0, 0x3576, 0, 0x4C75, 0x414A, 0xF858, 0x6B45, 0x7C22, - 0, 0, 0x3F47, 0x4370, 0x3E5A, 0xDD55, 0xF859, 0, -}; -static const unsigned short utf8_to_euc_E8A9[] = { - 0xDD57, 0x6B46, 0, 0xDD58, 0, 0xDD59, 0x6B49, 0xDD5A, - 0x6B4A, 0xDD5B, 0, 0, 0, 0xDD5C, 0xDD5D, 0, - 0x3A3E, 0x4242, 0x6B48, 0xDD5E, 0x3E5B, 0x493E, 0xDD5F, 0xDD60, - 0xDD61, 0, 0, 0x6B47, 0xDD62, 0xDD63, 0x3B6C, 0, - 0x3153, 0xDD64, 0x6B4E, 0x3758, 0, 0xDD65, 0x3B6E, 0xDD66, - 0, 0x3B6D, 0, 0x4F4D, 0x6B4D, 0x6B4C, 0x4127, 0, - 0x354D, 0x4F43, 0x333A, 0x3E5C, 0, 0xDD67, 0xDD68, 0xDD69, - 0, 0xDD6A, 0xDD6B, 0xDD6C, 0x6B4B, 0, 0xDD6D, 0xDD6E, -}; -static const unsigned short utf8_to_euc_E8A9_x0213[] = { - 0xDD57, 0x6B46, 0, 0xDD58, 0, 0xF85A, 0x6B49, 0x7C23, - 0x6B4A, 0xDD5B, 0, 0, 0, 0xF85B, 0x7C24, 0, - 0x3A3E, 0x4242, 0x6B48, 0xDD5E, 0x3E5B, 0x493E, 0xDD5F, 0xDD60, - 0xF85C, 0, 0, 0x6B47, 0xDD62, 0x7C25, 0x3B6C, 0, - 0x3153, 0x7C26, 0x6B4E, 0x3758, 0, 0xDD65, 0x3B6E, 0xDD66, - 0, 0x3B6D, 0, 0x4F4D, 0x6B4D, 0x6B4C, 0x4127, 0, - 0x354D, 0x4F43, 0x333A, 0x3E5C, 0, 0x7C27, 0xDD68, 0xDD69, - 0, 0x7C28, 0xDD6B, 0xDD6C, 0x6B4B, 0, 0xDD6D, 0xDD6E, -}; -static const unsigned short utf8_to_euc_E8AA[] = { - 0xDD6F, 0, 0x6B50, 0xDD70, 0x6B51, 0x6B4F, 0xDD71, 0x3858, - 0, 0x4D40, 0, 0xDD72, 0x3B6F, 0x4727, 0, 0xDD73, - 0xDD74, 0x6B54, 0xDD75, 0x4040, 0, 0x4342, 0xDD76, 0xDD77, - 0x4D36, 0xDD78, 0x6B57, 0, 0, 0, 0x386C, 0xDD79, - 0x403F, 0x6B53, 0, 0x6B58, 0x386D, 0x6B55, 0x6B56, 0xDD7A, - 0x6B52, 0xDD7B, 0, 0, 0x4062, 0x4649, 0xDD7C, 0xDD7D, - 0x432F, 0, 0x325D, 0xDD7E, 0, 0, 0xDE21, 0xDE22, - 0, 0x4870, 0, 0xDE23, 0x3543, 0, 0xDE24, 0x4434, -}; -static const unsigned short utf8_to_euc_E8AA_x0213[] = { - 0xDD6F, 0, 0x6B50, 0xDD70, 0x6B51, 0x6B4F, 0xDD71, 0x3858, - 0, 0x4D40, 0, 0xDD72, 0x3B6F, 0x4727, 0, 0xDD73, - 0xF85E, 0x6B54, 0xDD75, 0x4040, 0, 0x4342, 0xDD76, 0xDD77, - 0x4D36, 0xDD78, 0x6B57, 0, 0, 0, 0x386C, 0xDD79, - 0x403F, 0x6B53, 0, 0x6B58, 0x386D, 0x6B55, 0x6B56, 0x7C29, - 0x6B52, 0xDD7B, 0, 0, 0x4062, 0x4649, 0xF85D, 0xDD7D, - 0x432F, 0, 0x325D, 0xDD7E, 0, 0, 0xDE21, 0xF85F, - 0, 0x4870, 0, 0xDE23, 0x3543, 0, 0xF860, 0x4434, -}; -static const unsigned short utf8_to_euc_E8AB[] = { - 0, 0, 0x6B5B, 0xDE25, 0x6B59, 0, 0xDE26, 0x434C, - 0xDE27, 0xDE28, 0xDE29, 0x4041, 0x3452, 0x6B5A, 0, 0x3F5B, - 0, 0xDE2A, 0x4E4A, 0xDE2B, 0xDE2C, 0xDE2D, 0x4F40, 0xDE2E, - 0, 0, 0x6B5C, 0x6B67, 0x4435, 0xDE2F, 0x6B66, 0xDE30, - 0x6B63, 0x6B6B, 0x6B64, 0, 0x6B60, 0, 0x447C, 0x6B5F, - 0, 0, 0, 0x6B5D, 0xDE31, 0x4D21, 0x3B70, 0, - 0xDE32, 0x6B61, 0, 0x6B5E, 0xDE33, 0xDE34, 0xDE35, 0x6B65, - 0x3D74, 0, 0x3841, 0, 0xDE36, 0, 0x427A, 0xDE37, -}; -static const unsigned short utf8_to_euc_E8AB_x0213[] = { - 0, 0, 0x6B5B, 0xDE25, 0x6B59, 0, 0xDE26, 0x434C, - 0xDE27, 0xDE28, 0xDE29, 0x4041, 0x3452, 0x6B5A, 0, 0x3F5B, - 0x7C2A, 0xDE2A, 0x4E4A, 0xDE2B, 0xDE2C, 0xDE2D, 0x4F40, 0xF861, - 0, 0, 0x6B5C, 0x6B67, 0x4435, 0xDE2F, 0x6B66, 0x7C2B, - 0x6B63, 0x6B6B, 0x6B64, 0, 0x6B60, 0, 0x447C, 0x6B5F, - 0, 0, 0, 0x6B5D, 0xDE31, 0x4D21, 0x3B70, 0, - 0xDE32, 0x6B61, 0, 0x6B5E, 0x7C2C, 0xDE34, 0x7C2D, 0x6B65, - 0x3D74, 0, 0x3841, 0, 0xF862, 0, 0x427A, 0xDE37, -}; -static const unsigned short utf8_to_euc_E8AC[] = { - 0x4B45, 0x315A, 0x3062, 0, 0x4625, 0xDE38, 0xDE39, 0x6B69, - 0, 0, 0xDE3F, 0xDE3A, 0x6B68, 0, 0x4666, 0, - 0x6B6D, 0xDE3B, 0, 0, 0x6B62, 0, 0x6B6C, 0x6B6E, - 0, 0x382C, 0x6B6A, 0x3956, 0xDE3C, 0x3C55, 0xDE3D, 0xDE3E, - 0x6B6F, 0x4D58, 0, 0, 0, 0, 0x6B72, 0, - 0x6B75, 0, 0, 0x6B73, 0x4935, 0xDE40, 0, 0, - 0xDE41, 0, 0, 0x6B70, 0, 0, 0, 0xDE42, - 0, 0x3660, 0, 0, 0xDE43, 0, 0x6B74, 0, -}; -static const unsigned short utf8_to_euc_E8AC_x0213[] = { - 0x4B45, 0x315A, 0x3062, 0, 0x4625, 0xF865, 0xDE39, 0x6B69, - 0, 0, 0xF864, 0xDE3A, 0x6B68, 0xF866, 0x4666, 0, - 0x6B6D, 0xDE3B, 0, 0, 0x6B62, 0, 0x6B6C, 0x6B6E, - 0, 0x382C, 0x6B6A, 0x3956, 0xF867, 0x3C55, 0xDE3D, 0xF868, - 0x6B6F, 0x4D58, 0, 0, 0, 0, 0x6B72, 0, - 0x6B75, 0, 0, 0x6B73, 0x4935, 0xF869, 0, 0, - 0xDE41, 0, 0, 0x6B70, 0, 0, 0, 0xDE42, - 0, 0x3660, 0, 0, 0xDE43, 0, 0x6B74, 0, -}; -static const unsigned short utf8_to_euc_E8AD[] = { - 0, 0x6B76, 0xDE44, 0xDE45, 0xDE46, 0xDE47, 0xDE48, 0, - 0xDE49, 0x6B7A, 0, 0, 0x6B77, 0xDE4E, 0x6B79, 0x6B78, - 0, 0, 0xDE4A, 0xDE4B, 0xDE4C, 0, 0x6B7B, 0, - 0x3C31, 0xDE4D, 0x6B7D, 0x6B7C, 0x4968, 0, 0xDE4F, 0x6C21, - 0, 0, 0, 0xDE50, 0, 0, 0x3759, 0, - 0, 0, 0, 0x6B7E, 0x6C22, 0xDE51, 0, 0x6C23, - 0x3544, 0x6641, 0x3E79, 0, 0x6C24, 0, 0xDE52, 0x386E, - 0xDE53, 0xDE54, 0, 0, 0xDE55, 0x6C25, 0xDE56, 0xF466, -}; -static const unsigned short utf8_to_euc_E8AD_x0213[] = { - 0, 0x6B76, 0xDE44, 0xF86A, 0xDE46, 0xDE47, 0x7C31, 0, - 0xDE49, 0x6B7A, 0, 0, 0x6B77, 0xDE4E, 0x6B79, 0x6B78, - 0, 0xF86C, 0xDE4A, 0, 0x7C32, 0, 0x6B7B, 0, - 0x3C31, 0x7C33, 0x6B7D, 0x6B7C, 0x4968, 0, 0xF86D, 0x6C21, - 0, 0, 0, 0xDE50, 0, 0, 0x3759, 0, - 0, 0x7C34, 0, 0x6B7E, 0x6C22, 0xDE51, 0, 0x6C23, - 0x3544, 0x6641, 0x3E79, 0, 0x6C24, 0, 0xF86E, 0x386E, - 0xDE53, 0xDE54, 0, 0, 0xDE55, 0x6C25, 0xDE56, 0xF86F, -}; -static const unsigned short utf8_to_euc_E8AE[] = { - 0x6C26, 0xDE57, 0, 0x3B3E, 0xDE58, 0xDE59, 0, 0, - 0, 0, 0x5A4E, 0xDE5A, 0x6C27, 0xDE5B, 0x6C28, 0xDE5C, - 0x3D32, 0, 0x6C29, 0x6C2A, 0xDE5D, 0xDE5E, 0x6C2B, 0, - 0, 0x6C2C, 0x6C2D, 0, 0xDE5F, 0, 0xDE60, 0xDE61, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8AE_x0213[] = { - 0x6C26, 0xF870, 0, 0x3B3E, 0xDE58, 0xDE59, 0, 0, - 0, 0, 0x5A4E, 0xF871, 0x6C27, 0xDE5B, 0x6C28, 0xDE5C, - 0x3D32, 0, 0x6C29, 0x6C2A, 0xF872, 0xF873, 0x6C2B, 0, - 0, 0x6C2C, 0x6C2D, 0, 0xF874, 0x7C35, 0xF875, 0xDE61, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B0[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x432B, - 0xDE62, 0xDE63, 0x6C2E, 0, 0, 0xDE64, 0xDE65, 0x6C30, -}; -static const unsigned short utf8_to_euc_E8B0_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x432B, - 0xDE62, 0xF876, 0x6C2E, 0, 0, 0xF878, 0xDE65, 0x6C30, -}; -static const unsigned short utf8_to_euc_E8B1[] = { - 0, 0x6C2F, 0, 0, 0, 0xDE66, 0x4626, 0xDE67, - 0x6C31, 0xDE68, 0x4B2D, 0xDE69, 0x6C32, 0, 0x6C33, 0xDE6A, - 0x6C34, 0xDE6B, 0, 0xDE6C, 0xDE6D, 0x6C35, 0, 0xDE6E, - 0xDE6F, 0xDE72, 0x465A, 0xDE70, 0, 0xDE71, 0, 0, - 0, 0x3E5D, 0x6C36, 0xDE73, 0xDE74, 0, 0xDE75, 0, - 0xDE76, 0xDE77, 0x396B, 0x502E, 0x6C37, 0xDE78, 0, 0, - 0, 0, 0, 0xDE79, 0, 0xDE7A, 0xDE7B, 0, - 0x6C38, 0x493F, 0x6C39, 0xDE7C, 0x6C41, 0, 0xDE7D, 0, -}; -static const unsigned short utf8_to_euc_E8B1_x0213[] = { - 0, 0x6C2F, 0, 0, 0, 0xF87B, 0x4626, 0xF87C, - 0x6C31, 0x7C36, 0x4B2D, 0xDE69, 0x6C32, 0, 0x6C33, 0xF87D, - 0x6C34, 0xDE6B, 0, 0xDE6C, 0xF87E, 0x6C35, 0, 0xF921, - 0xDE6F, 0xDE72, 0x465A, 0xDE70, 0, 0xDE71, 0, 0, - 0, 0x3E5D, 0x6C36, 0xDE73, 0xDE74, 0, 0xDE75, 0, - 0x7C37, 0xF922, 0x396B, 0x502E, 0x6C37, 0xF923, 0, 0, - 0, 0, 0, 0xF924, 0, 0xDE7A, 0xDE7B, 0, - 0x6C38, 0x493F, 0x6C39, 0xDE7C, 0x6C41, 0, 0xDE7D, 0, -}; -static const unsigned short utf8_to_euc_E8B2[] = { - 0, 0, 0x6C3A, 0, 0, 0x6C3C, 0xDE7E, 0xDF21, - 0, 0x6C3B, 0x6C3D, 0xDF22, 0x4B46, 0x6C3E, 0x6C3F, 0, - 0xDF23, 0, 0xDF24, 0xDF25, 0x6C40, 0, 0, 0, - 0x6C42, 0xDF26, 0, 0xDF27, 0xDF28, 0x332D, 0x4467, 0, - 0x4969, 0x3A62, 0x3957, 0, 0xDF29, 0, 0, 0x494F, - 0x325F, 0x484E, 0x6C45, 0x3453, 0x4055, 0x6C44, 0x6C49, 0x4379, - 0x4C63, 0, 0x6C47, 0x6C48, 0x352E, 0, 0x6C4A, 0x4763, - 0x425F, 0xDF2A, 0xDF2B, 0x4871, 0x453D, 0x6C46, 0, 0x4B47, -}; -static const unsigned short utf8_to_euc_E8B2_x0213[] = { - 0, 0, 0x6C3A, 0, 0, 0x6C3C, 0xDE7E, 0xDF21, - 0, 0x6C3B, 0x6C3D, 0xDF22, 0x4B46, 0x6C3E, 0x6C3F, 0, - 0xDF23, 0, 0xF927, 0xF926, 0x6C40, 0, 0, 0, - 0x6C42, 0xF928, 0, 0xF92A, 0xDF28, 0x332D, 0x4467, 0, - 0x4969, 0x3A62, 0x3957, 0, 0xF92B, 0, 0, 0x494F, - 0x325F, 0x484E, 0x6C45, 0x3453, 0x4055, 0x6C44, 0x6C49, 0x4379, - 0x4C63, 0, 0x6C47, 0x6C48, 0x352E, 0, 0x6C4A, 0x4763, - 0x425F, 0xDF2A, 0xDF2B, 0x4871, 0x453D, 0x6C46, 0, 0x4B47, -}; -static const unsigned short utf8_to_euc_E8B3[] = { - 0x326C, 0x6C4C, 0x4F28, 0x4442, 0x4F45, 0xDF2C, 0xDF2D, 0x3B71, - 0x6C4B, 0xDF2E, 0x4231, 0xDF2F, 0, 0x6C5C, 0x4128, 0xDF30, - 0, 0x4678, 0, 0x4950, 0, 0xDF32, 0xDF31, 0, - 0, 0xDF33, 0x6C4F, 0x3B3F, 0x3B72, 0xDF34, 0x3E5E, 0, - 0x4765, 0xDF35, 0x382D, 0x6C4E, 0x6C4D, 0, 0x496A, 0, - 0xDF36, 0, 0x3C41, 0, 0xDF37, 0x4552, 0, 0xDF38, - 0xDF39, 0, 0xDF3A, 0, 0xF467, 0xDF3B, 0, 0xDF3C, - 0xDF3D, 0, 0x6C51, 0x6C52, 0x3958, 0x6C50, 0xDF3E, 0xDF3F, -}; -static const unsigned short utf8_to_euc_E8B3_x0213[] = { - 0x326C, 0x6C4C, 0x4F28, 0x4442, 0x4F45, 0xDF2C, 0xDF2D, 0x3B71, - 0x6C4B, 0xDF2E, 0x4231, 0xDF2F, 0, 0x6C5C, 0x4128, 0xDF30, - 0, 0x4678, 0, 0x4950, 0, 0xF92D, 0xF92C, 0, - 0, 0xF92E, 0x6C4F, 0x3B3F, 0x3B72, 0xDF34, 0x3E5E, 0, - 0x4765, 0x7C39, 0x382D, 0x6C4E, 0x6C4D, 0, 0x496A, 0, - 0xDF36, 0, 0x3C41, 0, 0xDF37, 0x4552, 0, 0xDF38, - 0xF930, 0xF931, 0xDF3A, 0, 0x7C3A, 0xDF3B, 0, 0xDF3C, - 0x7C3B, 0, 0x6C51, 0x6C52, 0x3958, 0x6C50, 0x7C3C, 0xDF3F, -}; -static const unsigned short utf8_to_euc_E8B4[] = { - 0, 0xDF40, 0, 0xDF41, 0x6C53, 0x6C54, 0, 0x6C56, - 0x4223, 0xDF42, 0x6C55, 0x3466, 0, 0x6C58, 0, 0x6C57, - 0x6C59, 0, 0xDF43, 0x6C5B, 0x6C5D, 0, 0x6C5E, 0xDF44, - 0, 0, 0, 0xDF45, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B4_x0213[] = { - 0, 0xDF40, 0, 0xDF41, 0x6C53, 0x6C54, 0, 0x6C56, - 0x4223, 0xF933, 0x6C55, 0x3466, 0, 0x6C58, 0xF934, 0x6C57, - 0x6C59, 0, 0x7C3E, 0x6C5B, 0x6C5D, 0, 0x6C5E, 0xDF44, - 0, 0, 0, 0x7C3F, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B5[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x4056, 0xDF46, 0x3C4F, 0x6C5F, - 0, 0xDF47, 0, 0x3352, 0xDF48, 0x6C60, 0xDF49, 0, - 0x4176, 0x6C61, 0, 0x6C62, 0x496B, 0, 0xF468, 0x352F, - 0, 0, 0, 0, 0, 0, 0, 0xDF4A, -}; -static const unsigned short utf8_to_euc_E8B5_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x4056, 0xDF46, 0x3C4F, 0x6C5F, - 0, 0xDF47, 0, 0x3352, 0xF935, 0x6C60, 0xDF49, 0, - 0x4176, 0x6C61, 0, 0x6C62, 0x496B, 0, 0, 0x352F, - 0, 0, 0, 0, 0, 0, 0, 0xDF4A, -}; -static const unsigned short utf8_to_euc_E8B6[] = { - 0, 0x6C63, 0xDF4B, 0, 0xDF4C, 0x4436, 0, 0, - 0xDF4D, 0, 0x315B, 0, 0, 0xDF4E, 0, 0, - 0xDF4F, 0xDF50, 0, 0, 0, 0xDF51, 0, 0, - 0, 0x6C64, 0, 0, 0, 0, 0xDF52, 0xDF53, - 0xDF54, 0, 0, 0x3C71, 0, 0, 0xDF55, 0, - 0x3F76, 0, 0, 0xDF56, 0xDF57, 0, 0, 0xDF58, - 0, 0, 0xDF59, 0x422D, 0, 0xDF5A, 0, 0xDF5B, - 0, 0xDF5C, 0x6C67, 0xDF5D, 0xDF6F, 0, 0x6C66, 0, -}; -static const unsigned short utf8_to_euc_E8B6_x0213[] = { - 0, 0x6C63, 0xDF4B, 0, 0xF936, 0x4436, 0, 0, - 0xDF4D, 0, 0x315B, 0, 0, 0xDF4E, 0, 0, - 0xDF4F, 0xDF50, 0, 0, 0, 0xF937, 0, 0, - 0, 0x6C64, 0, 0, 0, 0, 0xDF52, 0xDF53, - 0xDF54, 0, 0, 0x3C71, 0, 0, 0xF938, 0, - 0x3F76, 0, 0, 0xDF56, 0xDF57, 0, 0, 0x7C40, - 0, 0, 0xDF59, 0x422D, 0, 0xDF5A, 0, 0xDF5B, - 0, 0xDF5C, 0x6C67, 0xDF5D, 0xDF6F, 0, 0x6C66, 0, -}; -static const unsigned short utf8_to_euc_E8B7[] = { - 0xDF5E, 0, 0x6C65, 0, 0, 0xDF5F, 0xDF60, 0xDF61, - 0xDF62, 0, 0xDF63, 0x6C6D, 0x6C6B, 0, 0xDF64, 0x6C68, - 0, 0xDF65, 0, 0, 0xDF66, 0xDF67, 0x6C6A, 0xDF68, - 0, 0xDF69, 0x6C69, 0x6C6C, 0, 0x3577, 0, 0x6C70, - 0, 0x4057, 0, 0x6C71, 0xDF6A, 0xDF6B, 0, 0xDF6C, - 0x3859, 0, 0x6C6E, 0x6C6F, 0xDF6D, 0, 0, 0x4F29, - 0xDF6E, 0xDF70, 0xDF71, 0x4437, 0xDF72, 0x4129, 0, 0, - 0, 0, 0, 0, 0x6C72, 0xDF73, 0, 0x6C75, -}; -static const unsigned short utf8_to_euc_E8B7_x0213[] = { - 0xDF5E, 0, 0x6C65, 0, 0, 0xDF5F, 0xF93A, 0xDF61, - 0xF93B, 0, 0xDF63, 0x6C6D, 0x6C6B, 0, 0x7C41, 0x6C68, - 0, 0x7C42, 0, 0, 0xDF66, 0xDF67, 0x6C6A, 0x7C43, - 0, 0xF93C, 0x6C69, 0x6C6C, 0, 0x3577, 0, 0x6C70, - 0, 0x4057, 0, 0x6C71, 0xDF6A, 0xDF6B, 0, 0xDF6C, - 0x3859, 0, 0x6C6E, 0x6C6F, 0xF93D, 0, 0, 0x4F29, - 0xDF6E, 0xDF70, 0xDF71, 0x4437, 0xDF72, 0x4129, 0, 0, - 0, 0, 0, 0, 0x6C72, 0xF940, 0, 0x6C75, -}; -static const unsigned short utf8_to_euc_E8B8[] = { - 0, 0xDF74, 0, 0, 0xDF75, 0xDF76, 0xDF77, 0, - 0x6C73, 0x6C74, 0x4D59, 0xDF78, 0, 0, 0, 0x4627, - 0x6C78, 0xDF79, 0, 0, 0xDF7A, 0, 0xDF7B, 0, - 0, 0, 0, 0, 0, 0x6C76, 0x6C77, 0x6C79, - 0xDF7C, 0xDF7D, 0xDF7E, 0xE021, 0, 0, 0xE022, 0xE023, - 0, 0, 0x6D29, 0, 0, 0, 0, 0, - 0x6C7C, 0xE024, 0, 0xE025, 0x6C7D, 0x6C7B, 0xE026, 0xE027, - 0xE028, 0xE029, 0, 0, 0, 0xE02A, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B8_x0213[] = { - 0, 0xDF74, 0, 0, 0xDF75, 0xDF76, 0xF941, 0, - 0x6C73, 0x6C74, 0x4D59, 0xDF78, 0xF93E, 0, 0, 0x4627, - 0x6C78, 0xDF79, 0, 0, 0xF943, 0, 0xF944, 0, - 0, 0, 0, 0, 0, 0x6C76, 0x6C77, 0x6C79, - 0x7C44, 0xF945, 0xF946, 0x7C45, 0, 0, 0xE022, 0xF947, - 0, 0, 0x6D29, 0, 0, 0, 0, 0, - 0x6C7C, 0xE024, 0, 0xE025, 0x6C7D, 0x6C7B, 0xF94A, 0xE027, - 0xE028, 0xF94B, 0, 0, 0, 0x7C46, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B9[] = { - 0xE02B, 0xE02C, 0x6C7A, 0, 0x447D, 0, 0, 0x6D21, - 0x6D25, 0x6D22, 0x6C7E, 0xE02D, 0x6D23, 0xE02E, 0xE02F, 0xE030, - 0x6D24, 0, 0, 0, 0xE031, 0x6D2B, 0, 0, - 0, 0x6D26, 0, 0xE032, 0xE033, 0xE034, 0xE035, 0x4058, - 0x6D28, 0xE036, 0xE037, 0x6D2A, 0x6D27, 0, 0, 0, - 0, 0xE038, 0, 0, 0xE039, 0xE03A, 0, 0xE03B, - 0xE03C, 0xE03D, 0x6D2D, 0, 0x3D33, 0, 0x6D2C, 0, - 0, 0xE03E, 0xE03F, 0xE040, 0x6D2E, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8B9_x0213[] = { - 0xE02B, 0xE02C, 0x6C7A, 0, 0x447D, 0, 0, 0x6D21, - 0x6D25, 0x6D22, 0x6C7E, 0xF94C, 0x6D23, 0xE02E, 0xE02F, 0xE030, - 0x6D24, 0, 0, 0, 0xF94D, 0x6D2B, 0, 0, - 0, 0x6D26, 0, 0xE032, 0xE033, 0xE034, 0xE035, 0x4058, - 0x6D28, 0xE036, 0xF94E, 0x6D2A, 0x6D27, 0, 0, 0, - 0, 0xE038, 0, 0, 0xF94F, 0xF950, 0, 0xF951, - 0x7C47, 0xE03D, 0x6D2D, 0, 0x3D33, 0, 0x6D2C, 0, - 0, 0xE03E, 0xE03F, 0x7C48, 0x6D2E, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8BA[] = { - 0, 0x6D2F, 0xE041, 0xE042, 0x6D32, 0x6D31, 0, 0x6D30, - 0, 0xE043, 0x6D34, 0x6D33, 0, 0x4C76, 0, 0, - 0xE044, 0x6D36, 0xE045, 0x6D35, 0x6D37, 0xE046, 0, 0, - 0, 0x6D38, 0xE047, 0xE048, 0, 0xE049, 0xE04A, 0, - 0, 0x6D3A, 0xE04B, 0, 0, 0, 0, 0xE04C, - 0, 0xE04D, 0x6D39, 0x3F48, 0x6D3B, 0xE04E, 0xE04F, 0x366D, - 0x6D3C, 0x6D3E, 0, 0xE050, 0, 0xE051, 0, 0, - 0, 0, 0xE052, 0xE053, 0, 0, 0x6D3F, 0, -}; -static const unsigned short utf8_to_euc_E8BA_x0213[] = { - 0, 0x6D2F, 0xE041, 0xE042, 0x6D32, 0x6D31, 0, 0x6D30, - 0, 0xE043, 0x6D34, 0x6D33, 0, 0x4C76, 0, 0, - 0xE044, 0x6D36, 0xE045, 0x6D35, 0x6D37, 0xE046, 0, 0, - 0xF952, 0x6D38, 0xE047, 0xE048, 0, 0xE049, 0xF953, 0, - 0, 0x6D3A, 0xE04B, 0, 0, 0, 0, 0xE04C, - 0, 0xE04D, 0x6D39, 0x3F48, 0x6D3B, 0xE04E, 0xF954, 0x366D, - 0x6D3C, 0x6D3E, 0, 0xF955, 0, 0xF956, 0xF957, 0, - 0, 0, 0xE052, 0xF958, 0, 0, 0x6D3F, 0, -}; -static const unsigned short utf8_to_euc_E8BB[] = { - 0xE054, 0xE055, 0, 0xE056, 0xE057, 0x6D40, 0x6D3D, 0xE058, - 0x6D41, 0, 0x3C56, 0x6D42, 0x3530, 0x3733, 0, 0xE059, - 0, 0xE05A, 0x382E, 0, 0xE05B, 0, 0, 0, - 0, 0, 0, 0x6D43, 0xE05C, 0, 0, 0x4670, - 0, 0, 0x453E, 0x6D44, 0, 0, 0, 0, - 0xE05D, 0, 0, 0x6D47, 0, 0xE064, 0xE05E, 0, - 0xE05F, 0xE060, 0, 0, 0, 0, 0, 0xE061, - 0x3C34, 0xE062, 0xE063, 0x6D46, 0x6D45, 0x375A, 0x6D48, 0, -}; -static const unsigned short utf8_to_euc_E8BB_x0213[] = { - 0x7C4A, 0xE055, 0, 0xE056, 0xE057, 0x6D40, 0x6D3D, 0xE058, - 0x6D41, 0, 0x3C56, 0x6D42, 0x3530, 0x3733, 0, 0, - 0, 0xF95A, 0x382E, 0, 0xF95B, 0, 0, 0, - 0, 0, 0, 0x6D43, 0xE05C, 0, 0, 0x4670, - 0, 0, 0x453E, 0x6D44, 0, 0, 0, 0, - 0xE05D, 0, 0, 0x6D47, 0, 0xE064, 0xE05E, 0, - 0xE05F, 0xE060, 0, 0, 0, 0, 0, 0xE061, - 0x3C34, 0xF95D, 0x7C4C, 0x6D46, 0x6D45, 0x375A, 0x6D48, 0, -}; -static const unsigned short utf8_to_euc_E8BC[] = { - 0xE065, 0, 0xE066, 0x3353, 0, 0x6D4A, 0, 0xE067, - 0xE068, 0x3A5C, 0x6D49, 0, 0x6D52, 0, 0, 0xE069, - 0xE06A, 0, 0x6D4C, 0x6D4E, 0x4A65, 0x6D4B, 0xE06B, 0xE06C, - 0xE06D, 0x6D4D, 0, 0x6D51, 0x6D4F, 0x3531, 0xE06E, 0x6D50, - 0xE06F, 0xE070, 0, 0xE071, 0, 0xE072, 0x6D53, 0xE073, - 0xE074, 0x475A, 0x4E58, 0, 0xE075, 0xE076, 0xE077, 0x3D34, - 0, 0, 0, 0x6D54, 0xE078, 0xE079, 0xE07A, 0xE07B, - 0x4D22, 0x6D56, 0xE07C, 0x6D55, 0, 0, 0x6D59, 0x4D41, -}; -static const unsigned short utf8_to_euc_E8BC_x0213[] = { - 0xF95F, 0, 0xE066, 0x3353, 0, 0x6D4A, 0, 0xE067, - 0xF960, 0x3A5C, 0x6D49, 0, 0x6D52, 0, 0, 0xE069, - 0xE06A, 0, 0x6D4C, 0x6D4E, 0x4A65, 0x6D4B, 0xE06B, 0xF961, - 0xE06D, 0x6D4D, 0, 0x6D51, 0x6D4F, 0x3531, 0x7C4D, 0x6D50, - 0xE06F, 0xE070, 0, 0xE071, 0, 0xE072, 0x6D53, 0xE073, - 0xE074, 0x475A, 0x4E58, 0xF962, 0xE075, 0x7C4E, 0xE077, 0x3D34, - 0, 0, 0, 0x6D54, 0xE078, 0xE079, 0x7C4F, 0xE07B, - 0x4D22, 0x6D56, 0xE07C, 0x6D55, 0, 0, 0x6D59, 0x4D41, -}; -static const unsigned short utf8_to_euc_E8BD[] = { - 0xE07D, 0xE07E, 0x6D58, 0xE121, 0x336D, 0x6D57, 0x6D5C, 0xE122, - 0, 0x6D5B, 0, 0, 0x6D5A, 0x4532, 0x6D5D, 0xE123, - 0, 0xE124, 0xE125, 0xE126, 0xE127, 0xE128, 0, 0x6D5E, - 0xE129, 0, 0, 0, 0x6D5F, 0xE12A, 0xE12B, 0x396C, - 0, 0x3725, 0x6D60, 0x6D61, 0x6D62, 0xE12C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8BD_x0213[] = { - 0xF963, 0xE07E, 0x6D58, 0xE121, 0x336D, 0x6D57, 0x6D5C, 0xE122, - 0, 0x6D5B, 0xF964, 0, 0x6D5A, 0x4532, 0x6D5D, 0xE123, - 0, 0xE124, 0xE125, 0xE126, 0x7C50, 0xE128, 0, 0x6D5E, - 0xF965, 0, 0, 0, 0x6D5F, 0xE12A, 0xE12B, 0x396C, - 0, 0x3725, 0x6D60, 0x6D61, 0x6D62, 0xE12C, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E8BE[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x3F49, 0x6D63, 0xE12D, 0x3C2D, 0x6D64, - 0xE12E, 0xE12F, 0, 0x6D65, 0xE130, 0xE131, 0xE132, 0x5221, - 0x517E, 0, 0, 0, 0, 0x6D66, 0x6570, 0x6D67, - 0x4324, 0x3F2B, 0x4740, 0, 0, 0xE133, 0xE134, 0x6D68, - 0xE135, 0, 0x4A55, 0x4454, 0x397E, 0, 0xE136, 0x4329, -}; -static const unsigned short utf8_to_euc_E8BE_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x3F49, 0x6D63, 0xE12D, 0x3C2D, 0x6D64, - 0xE12E, 0xE12F, 0, 0x6D65, 0xF967, 0xE131, 0x7C52, 0x5221, - 0x517E, 0, 0, 0, 0, 0x6D66, 0x6570, 0x6D67, - 0x4324, 0x3F2B, 0x4740, 0, 0xF968, 0x7C53, 0xF96A, 0x6D68, - 0xE135, 0, 0x4A55, 0x4454, 0x397E, 0, 0xE136, 0x4329, -}; -static const unsigned short utf8_to_euc_E8BF[] = { - 0xE137, 0xE138, 0x312A, 0, 0x4B78, 0x3F57, 0xE139, 0, - 0, 0, 0xE13A, 0xE13B, 0, 0xE13C, 0x375E, 0, - 0xE13D, 0x3661, 0xE13E, 0xE13F, 0x4A56, 0xE140, 0, 0, - 0, 0, 0x6D69, 0, 0, 0, 0, 0, - 0xE141, 0, 0x6D6B, 0xE142, 0xE143, 0x6D6A, 0x3260, 0, - 0xE144, 0x4676, 0x6D6C, 0x4777, 0, 0x4533, 0xE145, 0x6D6D, - 0x3D52, 0xE146, 0, 0, 0x6D6F, 0xE147, 0xE148, 0x4C42, - 0x6D7E, 0x6D71, 0x6D72, 0xE149, 0, 0x4449, 0xE14A, 0, -}; -static const unsigned short utf8_to_euc_E8BF_x0213[] = { - 0xE137, 0xF96C, 0x312A, 0, 0x4B78, 0x3F57, 0xF96D, 0, - 0, 0, 0xF96F, 0xE13B, 0, 0xF970, 0x375E, 0, - 0xE13D, 0x3661, 0xE13E, 0xF971, 0x4A56, 0xF972, 0, 0, - 0, 0, 0x6D69, 0, 0, 0, 0, 0, - 0xF973, 0, 0x6D6B, 0xE142, 0x7C54, 0x6D6A, 0x3260, 0, - 0x7C55, 0x4676, 0x6D6C, 0x4777, 0, 0x4533, 0x7C56, 0x6D6D, - 0x3D52, 0xF974, 0, 0, 0x6D6F, 0xF975, 0xE148, 0x4C42, - 0x6D7E, 0x6D71, 0x6D72, 0xF976, 0, 0x4449, 0xE14A, 0, -}; -static const unsigned short utf8_to_euc_E980[] = { - 0x4260, 0x4177, 0xE14B, 0x4628, 0xE14C, 0x6D70, 0x3555, 0, - 0xE14D, 0, 0, 0x6D79, 0xE14E, 0x6D76, 0x6E25, 0x4629, - 0x4360, 0x6D73, 0, 0x447E, 0x4553, 0x6D74, 0x6D78, 0x3F60, - 0xE14F, 0x4767, 0x444C, 0xE150, 0, 0x4042, 0x6D77, 0x422E, - 0x4224, 0x6D75, 0x3029, 0x4F22, 0, 0, 0, 0x6D7A, - 0xE151, 0xE152, 0xE154, 0, 0xE155, 0xE156, 0x4261, 0xE153, - 0, 0x3D35, 0x3F4A, 0xE157, 0xE158, 0x6D7C, 0x6D7B, 0xE159, - 0x306F, 0x6D7D, 0, 0, 0x492F, 0, 0x6E27, 0xE15A, -}; -static const unsigned short utf8_to_euc_E980_x0213[] = { - 0x4260, 0x4177, 0xF977, 0x4628, 0xE14C, 0x6D70, 0x3555, 0, - 0x7C57, 0, 0, 0x6D79, 0xF978, 0x6D76, 0x6E25, 0x4629, - 0x4360, 0x6D73, 0, 0x447E, 0x4553, 0x6D74, 0x6D78, 0x3F60, - 0xE14F, 0x4767, 0x444C, 0xE150, 0, 0x4042, 0x6D77, 0x422E, - 0x4224, 0x6D75, 0x3029, 0x4F22, 0, 0, 0, 0x6D7A, - 0xE151, 0xE152, 0xE154, 0, 0xE155, 0x7C58, 0x4261, 0xE153, - 0, 0x3D35, 0x3F4A, 0xE157, 0xE158, 0x6D7C, 0x6D7B, 0xF979, - 0x306F, 0x6D7D, 0, 0, 0x492F, 0, 0x6E27, 0xE15A, -}; -static const unsigned short utf8_to_euc_E981[] = { - 0, 0x465B, 0x3F6B, 0xE15B, 0xE15C, 0x4359, 0, 0x3678, - 0, 0x6E26, 0x4D37, 0x313F, 0xE15D, 0x4A57, 0x3261, 0x6E21, - 0x6E22, 0x6E23, 0x6E24, 0x463B, 0x4323, 0x3063, 0x6E28, 0, - 0x6E29, 0x7423, 0, 0xE15E, 0x423D, 0xE15F, 0x6E2A, 0, - 0x3173, 0x414C, 0xE160, 0x382F, 0, 0x4D5A, 0xE161, 0xE162, - 0x6E2B, 0x452C, 0, 0, 0xE163, 0x4178, 0x3C57, 0x6E2C, - 0xE164, 0, 0x6E2F, 0, 0xE165, 0x3D65, 0x6E2D, 0x412B, - 0x412A, 0xE166, 0x3064, 0, 0x4E4B, 0x6E31, 0, 0x4872, -}; -static const unsigned short utf8_to_euc_E981_x0213[] = { - 0, 0x465B, 0x3F6B, 0xF97B, 0xF97C, 0x4359, 0, 0x3678, - 0, 0x6E26, 0x4D37, 0x313F, 0xE15D, 0x4A57, 0x3261, 0x6E21, - 0x6E22, 0x6E23, 0x6E24, 0x463B, 0x4323, 0x3063, 0x6E28, 0, - 0x6E29, 0x7423, 0, 0xE15E, 0x423D, 0xF97D, 0x6E2A, 0, - 0x3173, 0x414C, 0xE160, 0x382F, 0, 0x4D5A, 0xE161, 0, - 0x6E2B, 0x452C, 0, 0, 0xE163, 0x4178, 0x3C57, 0x6E2C, - 0xE164, 0, 0x6E2F, 0, 0xE165, 0x3D65, 0x6E2D, 0x412B, - 0x412A, 0xE166, 0x3064, 0, 0x4E4B, 0x6E31, 0, 0x4872, -}; -static const unsigned short utf8_to_euc_E982[] = { - 0x6E33, 0x6E32, 0x6E30, 0x6364, 0x3454, 0xE167, 0, 0x6D6E, - 0xE168, 0x6E35, 0x6E34, 0xE169, 0xE16A, 0, 0xE16B, 0x6E36, - 0xE16C, 0x4D38, 0, 0, 0, 0xE16D, 0, 0xE16E, - 0xE16F, 0xE170, 0, 0xE171, 0, 0, 0, 0, - 0xE172, 0xE173, 0xE174, 0x4661, 0, 0xE175, 0x4B2E, 0, - 0x6E37, 0, 0x3C59, 0, 0, 0, 0, 0x6E38, - 0xE176, 0x6E39, 0xE177, 0xE178, 0xE179, 0x6E3A, 0xE17A, 0, - 0x4521, 0, 0, 0, 0, 0xE17B, 0xE17D, 0, -}; -static const unsigned short utf8_to_euc_E982_x0213[] = { - 0x6E33, 0x6E32, 0x6E30, 0x6364, 0x3454, 0xFA22, 0, 0x6D6E, - 0x7C5A, 0x6E35, 0x6E34, 0xE169, 0xFA23, 0, 0xE16B, 0x6E36, - 0xFA24, 0x4D38, 0, 0, 0, 0x7C5B, 0, 0x7C5C, - 0xE16F, 0x7C5D, 0, 0x7C5E, 0, 0, 0, 0, - 0xE172, 0xFA26, 0x7C5F, 0x4661, 0, 0xE175, 0x4B2E, 0, - 0x6E37, 0, 0x3C59, 0, 0, 0, 0, 0x6E38, - 0xFA28, 0x6E39, 0xE177, 0x7C60, 0xE179, 0x6E3A, 0xFA29, 0, - 0x4521, 0, 0, 0, 0, 0xE17B, 0x7C61, 0, -}; -static const unsigned short utf8_to_euc_E983[] = { - 0, 0x306A, 0, 0xE17E, 0xE221, 0xE222, 0, 0xE223, - 0xE224, 0, 0x3959, 0, 0xE17C, 0, 0x4F3A, 0, - 0, 0, 0xE22D, 0, 0, 0xE225, 0, 0xE226, - 0xE227, 0xE228, 0, 0x6E3E, 0xE229, 0xE22A, 0xF46C, 0xE22B, - 0, 0x3734, 0x6E3B, 0, 0x6E3C, 0xE22C, 0, 0, - 0x4974, 0, 0, 0xE22F, 0, 0x3354, 0, 0xE230, - 0xE231, 0, 0, 0, 0xE232, 0x4D39, 0xE22E, 0x363F, - 0, 0, 0, 0, 0, 0x4554, 0xE233, 0xE234, -}; -static const unsigned short utf8_to_euc_E983_x0213[] = { - 0, 0x306A, 0, 0xFA2A, 0x7C62, 0x7C63, 0, 0x7C64, - 0xFA2B, 0, 0x3959, 0, 0xE17C, 0, 0x4F3A, 0, - 0, 0, 0xE22D, 0, 0, 0xE225, 0, 0x7C65, - 0xE227, 0xE228, 0, 0x6E3E, 0xFA2D, 0x7C66, 0x7C67, 0xFA2E, - 0, 0x3734, 0x6E3B, 0, 0x6E3C, 0xE22C, 0, 0, - 0x4974, 0, 0, 0xFA33, 0, 0x3354, 0, 0x7C68, - 0xE231, 0, 0xFA31, 0, 0x7C69, 0x4D39, 0xFA30, 0x363F, - 0, 0, 0, 0, 0, 0x4554, 0xFA34, 0xFA35, -}; -static const unsigned short utf8_to_euc_E984[] = { - 0xE235, 0, 0x6E3F, 0, 0xE236, 0xE237, 0xE238, 0, - 0xE239, 0, 0, 0, 0, 0xE23A, 0, 0, - 0xE23B, 0, 0x6E40, 0, 0xE23C, 0xF46E, 0xE23D, 0xE23E, - 0xE23F, 0x6E41, 0xE240, 0, 0xE241, 0, 0xE242, 0, - 0xE243, 0, 0xE245, 0xE246, 0, 0xE244, 0, 0xE247, - 0, 0xE248, 0, 0, 0, 0x4522, 0xE249, 0xE24A, - 0x6E43, 0xE24B, 0x6E42, 0, 0xE24C, 0, 0xE24D, 0xE24E, - 0, 0xE24F, 0xE250, 0, 0xE251, 0xE252, 0, 0, -}; -static const unsigned short utf8_to_euc_E984_x0213[] = { - 0xFA32, 0, 0x6E3F, 0, 0xFA36, 0xE237, 0xFA37, 0, - 0xE239, 0, 0, 0, 0, 0xE23A, 0, 0, - 0xE23B, 0, 0x6E40, 0, 0x7C6B, 0x7C6C, 0x7C6D, 0xE23E, - 0xFA38, 0x6E41, 0xE240, 0, 0xFA39, 0, 0xFA3A, 0, - 0xE243, 0, 0x7C6E, 0x7C6F, 0, 0xE244, 0, 0x7C70, - 0, 0xE248, 0, 0, 0, 0x4522, 0xE249, 0x7C71, - 0x6E43, 0x7C72, 0x6E42, 0, 0x7C73, 0, 0xE24D, 0xFA3B, - 0, 0xFA3C, 0xFA3D, 0, 0xE251, 0x7C74, 0, 0, -}; -static const unsigned short utf8_to_euc_E985[] = { - 0, 0, 0, 0xE253, 0, 0, 0, 0xE254, - 0xE255, 0x4653, 0x6E44, 0x3D36, 0x3C60, 0x475B, 0x4371, 0xE256, - 0, 0, 0x3C72, 0xE257, 0x3F6C, 0, 0x6E45, 0xE258, - 0x6E46, 0xE259, 0xE25A, 0xE25B, 0, 0, 0, 0, - 0, 0xE25C, 0x3F5D, 0x6E47, 0xE25D, 0x6E48, 0, 0xE25E, - 0, 0x6E49, 0x4D6F, 0, 0x3D37, 0xE25F, 0, 0, - 0, 0, 0x6E4B, 0x6E4A, 0xE260, 0x395A, 0, 0x3973, - 0x3B40, 0xE261, 0xE262, 0xE263, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E985_x0213[] = { - 0, 0, 0, 0xE253, 0, 0, 0xFA3E, 0xFA3F, - 0x7C75, 0x4653, 0x6E44, 0x3D36, 0x3C60, 0x475B, 0x4371, 0xE256, - 0, 0, 0x3C72, 0xE257, 0x3F6C, 0, 0x6E45, 0xFA40, - 0x6E46, 0xFA41, 0xE25A, 0x7C76, 0, 0, 0, 0, - 0, 0xFA42, 0x3F5D, 0x6E47, 0xFA43, 0x6E48, 0, 0xE25E, - 0, 0x6E49, 0x4D6F, 0, 0x3D37, 0xE25F, 0, 0, - 0, 0, 0x6E4B, 0x6E4A, 0xFA44, 0x395A, 0, 0x3973, - 0x3B40, 0xFA45, 0xE262, 0xE263, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E986[] = { - 0, 0xE264, 0x6E4E, 0xE265, 0, 0xE266, 0xE267, 0x3D66, - 0, 0x6E4D, 0xE268, 0x6E4C, 0, 0x4269, 0xE269, 0, - 0x386F, 0xE26A, 0x4043, 0xE26B, 0xE26C, 0xE26D, 0, 0x4830, - 0xE26E, 0, 0, 0, 0x3D39, 0, 0xE26F, 0, - 0, 0xE270, 0x6E4F, 0, 0x3E5F, 0, 0xE271, 0, - 0xE272, 0, 0x6E52, 0x6E50, 0xE273, 0xE274, 0xE275, 0x6E51, - 0xE276, 0xE277, 0xE278, 0xE279, 0x6E54, 0x6E53, 0xE27A, 0, - 0x3E7A, 0, 0x6E55, 0xE27B, 0xE27C, 0xE27D, 0, 0xE27E, -}; -static const unsigned short utf8_to_euc_E986_x0213[] = { - 0, 0xE264, 0x6E4E, 0x7C77, 0, 0xFA46, 0xE267, 0x3D66, - 0, 0x6E4D, 0xE268, 0x6E4C, 0, 0x4269, 0xFA47, 0, - 0x386F, 0xE26A, 0x4043, 0xE26B, 0xE26C, 0xE26D, 0, 0x4830, - 0xE26E, 0, 0, 0, 0x3D39, 0, 0x7C78, 0, - 0, 0xE270, 0x6E4F, 0, 0x3E5F, 0, 0xE271, 0, - 0xFA48, 0, 0x6E52, 0x6E50, 0x7C79, 0xE274, 0xFA49, 0x6E51, - 0xE276, 0x7C7A, 0xE278, 0xFA4A, 0x6E54, 0x6E53, 0xFA4B, 0, - 0x3E7A, 0, 0x6E55, 0xE27B, 0x7C7B, 0xE27D, 0, 0xE27E, -}; -static const unsigned short utf8_to_euc_E987[] = { - 0x6E56, 0x6E57, 0xE321, 0xE322, 0, 0xE323, 0x4850, 0x3A53, - 0x3C61, 0x6E58, 0, 0x6E59, 0x4E24, 0x3D45, 0x4C6E, 0x4E4C, - 0x6E5A, 0x3662, 0, 0xE324, 0xE325, 0, 0x6E5B, 0xE326, - 0x4523, 0xE327, 0xE328, 0x6E5E, 0x3378, 0x3F4B, 0xE329, 0x6E5C, - 0, 0x6E5D, 0, 0x4460, 0xE32A, 0xE32B, 0x4B55, 0x367C, - 0, 0xE32C, 0xE32D, 0, 0xE32E, 0xE32F, 0xE330, 0xE331, - 0xE332, 0xE333, 0, 0, 0, 0x6E60, 0x6E61, 0xE334, - 0, 0xE335, 0, 0xE336, 0x6E5F, 0xE337, 0, 0x6E63, -}; -static const unsigned short utf8_to_euc_E987_x0213[] = { - 0x6E56, 0x6E57, 0xE321, 0xFA4C, 0xFA4D, 0xE323, 0x4850, 0x3A53, - 0x3C61, 0x6E58, 0, 0x6E59, 0x4E24, 0x3D45, 0x4C6E, 0x4E4C, - 0x6E5A, 0x3662, 0, 0xE324, 0xE325, 0, 0x6E5B, 0x7C7C, - 0x4523, 0xE327, 0xFA4E, 0x6E5E, 0x3378, 0x3F4B, 0, 0x6E5C, - 0, 0x6E5D, 0, 0x4460, 0x7C7E, 0x7D21, 0x4B55, 0x367C, - 0, 0xE32C, 0xE32D, 0, 0xFA51, 0x7D22, 0xFA52, 0xE331, - 0xE332, 0x7D23, 0, 0, 0, 0x6E60, 0x6E61, 0xE334, - 0, 0xE335, 0, 0x7C7D, 0x6E5F, 0xE337, 0, 0x6E63, -}; -static const unsigned short utf8_to_euc_E988[] = { - 0xE338, 0xE339, 0, 0, 0xE33A, 0xE33B, 0xE33C, 0xE33D, - 0, 0xE33E, 0xE33F, 0, 0xE340, 0x465F, 0x3343, 0, - 0xE341, 0x6E67, 0xE342, 0xE343, 0x6E64, 0x6E66, 0xE344, 0, - 0xE345, 0, 0, 0, 0xE346, 0xE347, 0x6E62, 0, - 0, 0, 0, 0xE348, 0xE349, 0xE34A, 0xE34B, 0, - 0xE34C, 0x6F4F, 0, 0, 0x6E65, 0, 0xE34D, 0xE34E, - 0xE34F, 0, 0, 0xE350, 0x4E6B, 0xE351, 0xE352, 0x385A, - 0xE353, 0xE354, 0xE355, 0, 0xE356, 0, 0xE357, 0x6E6F, -}; -static const unsigned short utf8_to_euc_E988_x0213[] = { - 0xE338, 0xFA53, 0, 0, 0xE33A, 0xE33B, 0, 0x7D24, - 0, 0xE33E, 0xFA54, 0, 0xE340, 0x465F, 0x3343, 0, - 0x7D25, 0x6E67, 0xE342, 0xE343, 0x6E64, 0x6E66, 0xFA55, 0xFA56, - 0xE345, 0, 0, 0, 0xE346, 0xE347, 0x6E62, 0, - 0, 0, 0, 0xE348, 0xE349, 0xE34A, 0xE34B, 0, - 0xE34C, 0x6F4F, 0, 0, 0x6E65, 0, 0xE34D, 0xE34E, - 0xE34F, 0, 0, 0xFA58, 0x4E6B, 0xE351, 0xE352, 0x385A, - 0x7D26, 0x7D27, 0x7D28, 0, 0x7D29, 0, 0xE357, 0x6E6F, -}; -static const unsigned short utf8_to_euc_E989[] = { - 0xE358, 0, 0xE359, 0xE35A, 0x4534, 0x6E6A, 0xE35B, 0xE35C, - 0x6E6D, 0x6E6B, 0xE35D, 0x6E70, 0, 0xE35E, 0xE35F, 0xE360, - 0x6E71, 0xE361, 0, 0, 0, 0, 0, 0x6E69, - 0xE362, 0xE363, 0x6E76, 0x3174, 0xE364, 0xE365, 0x6E68, 0, - 0xE366, 0xE367, 0x482D, 0, 0x6E6C, 0xE368, 0x3E60, 0xE369, - 0xE36A, 0xE36B, 0, 0, 0, 0, 0xE36C, 0xE36D, - 0xE36E, 0x395B, 0, 0, 0, 0xE36F, 0xE370, 0xE371, - 0xE372, 0xE373, 0, 0xE374, 0xE375, 0xE376, 0x4B48, 0xE377, -}; -static const unsigned short utf8_to_euc_E989_x0213[] = { - 0x7D2A, 0, 0xFA59, 0x7D2B, 0x4534, 0x6E6A, 0xE35B, 0xFA5A, - 0x6E6D, 0x6E6B, 0xFA5B, 0x6E70, 0, 0xE35E, 0xFA5C, 0x7D2C, - 0x6E71, 0xFA5D, 0, 0, 0, 0, 0xFA5E, 0x6E69, - 0xE362, 0xFA5F, 0x6E76, 0x3174, 0xE364, 0xE365, 0x6E68, 0, - 0xFA60, 0xFA61, 0x482D, 0, 0x6E6C, 0xFA62, 0x3E60, 0xFA63, - 0xFA64, 0xE36B, 0, 0, 0, 0, 0xE36C, 0xE36D, - 0xE36E, 0x395B, 0, 0, 0, 0xE36F, 0xE370, 0, - 0x7D2D, 0xE373, 0, 0xE374, 0xFA67, 0xFA68, 0x4B48, 0xFA69, -}; -static const unsigned short utf8_to_euc_E98A[] = { - 0x3664, 0, 0, 0x3D46, 0, 0x463C, 0, 0, - 0xE378, 0xE379, 0xE37A, 0, 0, 0xE37B, 0xE37C, 0, - 0, 0x412D, 0xE37D, 0x6E74, 0, 0x6E6E, 0x6E73, 0xE37E, - 0x4C43, 0xE421, 0x4438, 0x6E75, 0x6E72, 0, 0, 0xE422, - 0xE423, 0, 0, 0, 0xE424, 0xE425, 0, 0xE426, - 0xE427, 0, 0, 0xE428, 0, 0x412C, 0, 0xE429, - 0, 0, 0xE42A, 0, 0, 0, 0xE42B, 0x6E79, - 0xE42C, 0x6E78, 0xE42D, 0xE42E, 0xE42F, 0xE430, 0, 0xE431, -}; -static const unsigned short utf8_to_euc_E98A_x0213[] = { - 0x3664, 0, 0, 0x3D46, 0, 0x463C, 0, 0, - 0x7D2E, 0xFA6A, 0xE37A, 0, 0, 0xFA6B, 0xE37C, 0, - 0, 0x412D, 0xE37D, 0x6E74, 0, 0x6E6E, 0x6E73, 0xFA6C, - 0x4C43, 0xFA6D, 0x4438, 0x6E75, 0x6E72, 0, 0, 0xFA6E, - 0xE423, 0, 0, 0, 0xE424, 0xE425, 0, 0xFA6F, - 0xE427, 0, 0, 0xFA70, 0, 0x412C, 0, 0xE429, - 0, 0, 0xFA73, 0, 0, 0, 0xE42B, 0x6E79, - 0xE42C, 0x6E78, 0xE42D, 0xE42E, 0xE42F, 0xE430, 0, 0xFA74, -}; -static const unsigned short utf8_to_euc_E98B[] = { - 0xE432, 0xE433, 0xE434, 0xE435, 0, 0xE436, 0xE437, 0xE438, - 0xE439, 0, 0, 0xE43A, 0xE43B, 0xE43C, 0xE43D, 0x6E77, - 0xE43E, 0, 0x4B2F, 0xE43F, 0, 0xE440, 0, 0xE441, - 0xE442, 0xE443, 0, 0, 0xE444, 0xE445, 0, 0xE446, - 0xE447, 0xE448, 0, 0xE449, 0x3D7B, 0xE44A, 0, 0xE44B, - 0xE44C, 0x6E7A, 0x4A5F, 0, 0xE44D, 0x3154, 0xE44E, 0, - 0xE44F, 0, 0x4946, 0x4372, 0, 0, 0, 0, - 0x3578, 0xE450, 0x6E7C, 0xE451, 0x395D, 0, 0, 0xE452, -}; -static const unsigned short utf8_to_euc_E98B_x0213[] = { - 0xFA75, 0xE433, 0x7D2F, 0xE435, 0, 0xE436, 0xFA76, 0xE438, - 0xE439, 0, 0, 0x7D30, 0x7D31, 0xE43C, 0xFA77, 0x6E77, - 0xFA78, 0, 0x4B2F, 0x7D32, 0, 0, 0, 0xFA79, - 0xE442, 0xFA7A, 0, 0, 0xE444, 0xE445, 0, 0xE446, - 0x7D33, 0xE448, 0, 0xE449, 0x3D7B, 0xFA7B, 0, 0xFA7C, - 0xE44C, 0x6E7A, 0x4A5F, 0, 0xE44D, 0x3154, 0xE44E, 0, - 0xE44F, 0, 0x4946, 0x4372, 0, 0, 0, 0xFB22, - 0x3578, 0xFB23, 0x6E7C, 0xFB24, 0x395D, 0, 0, 0x7D34, -}; -static const unsigned short utf8_to_euc_E98C[] = { - 0xE453, 0, 0xE454, 0, 0, 0, 0x3B2C, 0, - 0xE455, 0, 0, 0, 0, 0xE456, 0, 0x6E7B, - 0x3F6D, 0xE457, 0, 0, 0xE458, 0xE459, 0, 0, - 0x3F6E, 0x6F21, 0x6F23, 0, 0xE45A, 0xE45B, 0xE45C, 0xE45D, - 0x3E7B, 0xE45E, 0x6F22, 0x6F24, 0xE45F, 0xE460, 0x3653, 0xE461, - 0x4945, 0xE462, 0xE463, 0x3C62, 0x4F23, 0, 0x6E7E, 0x3A78, - 0, 0, 0x4F3F, 0xE464, 0xE465, 0x6F26, 0xE466, 0xE467, - 0, 0, 0x6F25, 0x6F27, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E98C_x0213[] = { - 0xE453, 0, 0xFB25, 0, 0x7D35, 0, 0x3B2C, 0, - 0xE455, 0, 0, 0, 0, 0xFB26, 0, 0x6E7B, - 0x3F6D, 0xFA7D, 0, 0, 0xE458, 0xFB27, 0, 0, - 0x3F6E, 0x6F21, 0x6F23, 0, 0xE45A, 0xFB28, 0xFB29, 0x7D36, - 0x3E7B, 0x7D37, 0x6F22, 0x6F24, 0xE45F, 0x7D38, 0x3653, 0xFB2A, - 0x4945, 0xFB2B, 0xE463, 0x3C62, 0x4F23, 0, 0x6E7E, 0x3A78, - 0, 0, 0x4F3F, 0xE464, 0xE465, 0x6F26, 0xE466, 0xE467, - 0, 0, 0x6F25, 0x6F27, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E98D[] = { - 0, 0, 0, 0, 0x6E7D, 0, 0, 0xE468, - 0xE469, 0xE46A, 0, 0x4669, 0, 0x4555, 0, 0, - 0xE46B, 0xE46C, 0xE46D, 0, 0x4457, 0xE46E, 0x6F2C, 0xE46F, - 0xE470, 0, 0xE471, 0x4343, 0x6F28, 0, 0xE472, 0, - 0x6F29, 0, 0, 0, 0xE473, 0xE474, 0, 0xE475, - 0, 0xE476, 0xE477, 0, 0x372D, 0xE478, 0x6F2B, 0xE479, - 0xE47A, 0xE47B, 0, 0xE47C, 0xE47D, 0x3830, 0xE47E, 0, - 0, 0, 0xE521, 0, 0x6F2A, 0xE522, 0x3E61, 0xE523, -}; -static const unsigned short utf8_to_euc_E98D_x0213[] = { - 0, 0, 0, 0, 0x6E7D, 0, 0, 0xFB2E, - 0x7D39, 0x7D3A, 0x7D3B, 0x4669, 0, 0x4555, 0, 0, - 0xE46B, 0xFB2F, 0xE46D, 0, 0x4457, 0xE46E, 0x6F2C, 0xFB30, - 0xE470, 0, 0xFB31, 0x4343, 0x6F28, 0, 0xE472, 0, - 0x6F29, 0, 0, 0, 0x7D3C, 0x7D3D, 0, 0xE475, - 0, 0xE476, 0x7D3E, 0xFB32, 0x372D, 0xE478, 0x6F2B, 0xE479, - 0x7D3F, 0xFB33, 0, 0xFB34, 0xE47D, 0x3830, 0xE47E, 0, - 0, 0, 0xE521, 0, 0x6F2A, 0xE522, 0x3E61, 0xE523, -}; -static const unsigned short utf8_to_euc_E98E[] = { - 0xE524, 0xE525, 0xE526, 0, 0, 0, 0, 0, - 0xE527, 0, 0xE528, 0xE529, 0x3379, 0xE52A, 0, 0xE52B, - 0, 0, 0xE52C, 0, 0x6F30, 0xE52D, 0x3A3F, 0x4179, - 0xE52E, 0, 0x444A, 0xE52F, 0, 0, 0xE530, 0, - 0, 0xE531, 0, 0xE532, 0xE533, 0, 0xE534, 0x333B, - 0xE535, 0xE53B, 0, 0xE536, 0x6F2E, 0x6F2F, 0x4443, 0, - 0x6F2D, 0, 0, 0, 0xE537, 0xE538, 0xE539, 0, - 0, 0x6F31, 0xE53A, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E98E_x0213[] = { - 0xE524, 0xE525, 0xE526, 0, 0, 0, 0, 0, - 0xFB38, 0, 0xE528, 0xFB39, 0x3379, 0xE52A, 0, 0xFB3A, - 0, 0, 0xE52C, 0, 0x6F30, 0xE52D, 0x3A3F, 0x4179, - 0xE52E, 0, 0x444A, 0x7D40, 0, 0, 0xFB3B, 0, - 0, 0xFB35, 0, 0x7D41, 0, 0, 0xE534, 0x333B, - 0xE535, 0xE53B, 0, 0xE536, 0x6F2E, 0x6F2F, 0x4443, 0, - 0x6F2D, 0, 0, 0, 0xE537, 0xE538, 0xE539, 0, - 0, 0x6F31, 0x7D42, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E98F[] = { - 0, 0xE53C, 0, 0x6F37, 0xE53D, 0xE53E, 0xE53F, 0xE540, - 0x6F3A, 0xE541, 0xE542, 0xE543, 0xE544, 0xE545, 0, 0, - 0x6F39, 0x452D, 0, 0xE546, 0, 0, 0x6F32, 0x6F33, - 0x6F36, 0xE547, 0, 0, 0xE548, 0x6F38, 0xE549, 0xE54A, - 0, 0x3640, 0xE54B, 0, 0x6F3B, 0x6F35, 0xE54C, 0xE54D, - 0x6F34, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xE54F, - 0xE550, 0xE54E, 0xE551, 0xE552, 0, 0xE553, 0, 0, -}; -static const unsigned short utf8_to_euc_E98F_x0213[] = { - 0, 0xFB40, 0, 0x6F37, 0xE53D, 0xE53E, 0x7D43, 0xFB41, - 0x6F3A, 0xE541, 0xE542, 0xE543, 0xE544, 0xE545, 0, 0, - 0x6F39, 0x452D, 0, 0xE546, 0, 0, 0x6F32, 0x6F33, - 0x6F36, 0xE547, 0, 0, 0xFB42, 0x6F38, 0x7D44, 0x7D45, - 0, 0x3640, 0xFB43, 0, 0x6F3B, 0x6F35, 0xE54C, 0xFB44, - 0x6F34, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB3F, 0, 0, 0, 0xFB3C, 0, 0xE54F, - 0, 0xE54E, 0xE551, 0xFB49, 0, 0x7D47, 0, 0, -}; -static const unsigned short utf8_to_euc_E990[] = { - 0, 0xE554, 0xE555, 0x6F3F, 0xE556, 0, 0, 0x6F40, - 0xE557, 0xE558, 0, 0, 0, 0xE559, 0xE55A, 0xE55B, - 0x6F41, 0, 0, 0x6F3E, 0x6F3D, 0xE55C, 0xE55D, 0xE55E, - 0x3E62, 0x462A, 0x6F3C, 0, 0, 0, 0, 0xE55F, - 0, 0x6F45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x6F43, 0, 0, 0xE560, 0xE561, - 0, 0xE562, 0xE563, 0xE564, 0xE565, 0x6F44, 0x6F42, 0, - 0x4278, 0, 0x6F46, 0xE566, 0, 0xE568, 0, 0xE567, -}; -static const unsigned short utf8_to_euc_E990_x0213[] = { - 0, 0xE554, 0xE555, 0x6F3F, 0x7D46, 0, 0, 0x6F40, - 0xE557, 0xFB45, 0, 0, 0, 0xE559, 0xE55A, 0xFB46, - 0x6F41, 0, 0, 0x6F3E, 0x6F3D, 0xE55C, 0xFB47, 0xFB48, - 0x3E62, 0x462A, 0x6F3C, 0, 0, 0, 0, 0xE55F, - 0, 0x6F45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x6F43, 0, 0, 0xE560, 0xE561, - 0, 0, 0xFB4A, 0x7D48, 0xFB4B, 0x6F44, 0x6F42, 0, - 0x4278, 0, 0x6F46, 0xFB4C, 0, 0xE568, 0, 0xE567, -}; -static const unsigned short utf8_to_euc_E991[] = { - 0, 0x6F47, 0, 0xE569, 0x6F49, 0xE56A, 0, 0, - 0xE56B, 0, 0xE56C, 0, 0xE56D, 0, 0, 0, - 0, 0x3455, 0x6F48, 0x4C7A, 0, 0xE56E, 0, 0, - 0, 0xE56F, 0x6F54, 0x6F4A, 0xE570, 0, 0x6F4D, 0xE571, - 0x6F4B, 0xE572, 0x6F4C, 0xE573, 0, 0, 0, 0, - 0xE574, 0, 0x6F4E, 0xE575, 0, 0xE576, 0xE577, 0xE578, - 0x6F50, 0xE579, 0xE57A, 0, 0, 0x6F51, 0, 0x6F52, - 0, 0, 0, 0, 0x6F55, 0x6F53, 0x6F56, 0x6F58, -}; -static const unsigned short utf8_to_euc_E991_x0213[] = { - 0, 0x6F47, 0, 0xE569, 0x6F49, 0xFB4D, 0, 0, - 0, 0, 0x7D49, 0, 0xE56D, 0, 0, 0, - 0, 0x3455, 0x6F48, 0x4C7A, 0, 0xE56E, 0, 0, - 0, 0xE56F, 0x6F54, 0x6F4A, 0xE570, 0, 0x6F4D, 0xE571, - 0x6F4B, 0xE572, 0x6F4C, 0x7D4A, 0, 0, 0, 0, - 0xE574, 0, 0x6F4E, 0x7D4B, 0, 0xFB50, 0xE577, 0xFB51, - 0x6F50, 0x7D4C, 0x7D4D, 0, 0, 0x6F51, 0, 0x6F52, - 0, 0, 0, 0, 0x6F55, 0x6F53, 0x6F56, 0x6F58, -}; -static const unsigned short utf8_to_euc_E992[] = { - 0, 0x6F57, 0, 0xE57C, 0xE57B, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E995[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x4439, - 0xE57D, 0xE57E, 0, 0, 0, 0, 0xE621, 0, -}; -static const unsigned short utf8_to_euc_E995_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x4439, - 0xFB52, 0xFB53, 0, 0, 0, 0, 0xE621, 0, -}; -static const unsigned short utf8_to_euc_E996[] = { - 0x4C67, 0, 0x6F59, 0x412E, 0xE622, 0, 0, 0x6F5A, - 0xE623, 0x4A44, 0x6F5B, 0x332B, 0xE624, 0xE625, 0xE626, 0x313C, - 0, 0x3457, 0xF471, 0x3456, 0x6F5C, 0, 0x6F5D, 0, - 0x6F5E, 0x6F5F, 0, 0, 0, 0xE627, 0xE628, 0xE629, - 0x6F60, 0xE62A, 0x3458, 0x3355, 0x395E, 0x4836, 0xE62B, 0x6F62, - 0x6F61, 0xE62C, 0, 0xE62D, 0xE62E, 0x6F63, 0, 0, - 0, 0, 0x315C, 0, 0xE62F, 0, 0xE630, 0, - 0, 0x6F66, 0xE631, 0x6F65, 0x6F64, 0xE632, 0x6F67, 0xE633, -}; -static const unsigned short utf8_to_euc_E996_x0213[] = { - 0x4C67, 0, 0x6F59, 0x412E, 0xE622, 0, 0xFB54, 0x6F5A, - 0xE623, 0x4A44, 0x6F5B, 0x332B, 0xFB55, 0xFB56, 0x7D4E, 0x313C, - 0, 0x3457, 0, 0x3456, 0x6F5C, 0, 0x6F5D, 0, - 0x6F5E, 0x6F5F, 0, 0, 0, 0xE627, 0xE628, 0x7D4F, - 0x6F60, 0xE62A, 0x3458, 0x3355, 0x395E, 0x4836, 0x7D50, 0x6F62, - 0x6F61, 0x7D51, 0, 0xFB58, 0x7D52, 0x6F63, 0, 0, - 0, 0, 0x315C, 0, 0xFB59, 0, 0x7D53, 0, - 0, 0x6F66, 0xE631, 0x6F65, 0x6F64, 0x7D54, 0x6F67, 0xE633, -}; -static const unsigned short utf8_to_euc_E997[] = { - 0, 0, 0, 0x6F6A, 0, 0, 0xE634, 0x3047, - 0xE635, 0xE636, 0x6F68, 0xE637, 0x6F6C, 0x6F6B, 0, 0, - 0xE638, 0xE639, 0xE63A, 0xE63B, 0x6F6E, 0x6F6D, 0x6F6F, 0, - 0x462E, 0xE63C, 0xE63D, 0, 0x6F70, 0xE63E, 0xE63F, 0xE640, - 0xE641, 0x6F71, 0x6F73, 0, 0xE642, 0x6F72, 0xE643, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E997_x0213[] = { - 0, 0, 0, 0x6F6A, 0, 0, 0xE634, 0x3047, - 0xFB5B, 0xE636, 0x6F68, 0x7D55, 0x6F6C, 0x6F6B, 0, 0, - 0x7D56, 0xE639, 0xE63A, 0x7D57, 0x6F6E, 0x6F6D, 0x6F6F, 0, - 0x462E, 0xE63C, 0x7D59, 0, 0x6F70, 0xE63E, 0x7D5A, 0xE640, - 0xE641, 0x6F71, 0x6F73, 0, 0xE642, 0x6F72, 0xE643, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E998[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x496C, 0xE644, 0xE645, 0, - 0, 0x6F74, 0xE646, 0, 0xE647, 0xE648, 0xE649, 0, - 0x6F75, 0, 0x3A65, 0, 0xE64A, 0, 0x6F76, 0x6F77, - 0, 0xE64B, 0x4B49, 0xE64C, 0, 0, 0, 0xE64D, - 0xE64E, 0xE64F, 0xE650, 0x414B, 0xE651, 0xE652, 0, 0x3024, -}; -static const unsigned short utf8_to_euc_E998_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x496C, 0xFA25, 0xE645, 0, - 0, 0x6F74, 0xE646, 0, 0xE647, 0xE648, 0xE649, 0, - 0x6F75, 0, 0x3A65, 0, 0xFB5E, 0, 0x6F76, 0x6F77, - 0, 0xE64B, 0x4B49, 0xFB5F, 0xFB60, 0, 0, 0xE64D, - 0xE64E, 0xE64F, 0xE650, 0x414B, 0xFB62, 0xE652, 0, 0x3024, -}; -static const unsigned short utf8_to_euc_E999[] = { - 0x424B, 0xE653, 0x6F78, 0, 0x496D, 0, 0, 0, - 0, 0, 0, 0x6F7B, 0x6F79, 0x395F, 0, 0x6F7A, - 0x3842, 0, 0xE654, 0, 0xE655, 0, 0xE656, 0xE657, - 0xE658, 0, 0, 0x4A45, 0x6F7D, 0x7021, 0x6F7E, 0x7022, - 0, 0xE659, 0x3121, 0x3F58, 0x3D7C, 0x3459, 0x7023, 0, - 0, 0, 0x4766, 0, 0x7025, 0, 0xE65A, 0, - 0x3122, 0, 0x7024, 0x4444, 0xE65B, 0x4E4D, 0x462B, 0x6F7C, - 0x4E26, 0, 0x3831, 0xE65C, 0xE65D, 0x4D5B, 0xE65E, 0xE65F, -}; -static const unsigned short utf8_to_euc_E999_x0213[] = { - 0x424B, 0xFB63, 0x6F78, 0, 0x496D, 0, 0, 0, - 0, 0, 0, 0x6F7B, 0x6F79, 0x395F, 0, 0x6F7A, - 0x3842, 0, 0xE654, 0, 0xE655, 0, 0xE656, 0xE657, - 0x7D5B, 0, 0, 0x4A45, 0x6F7D, 0x7021, 0x6F7E, 0x7022, - 0, 0xFB64, 0x3121, 0x3F58, 0x3D7C, 0x3459, 0x7023, 0, - 0, 0, 0x4766, 0, 0x7025, 0, 0xE65A, 0, - 0x3122, 0, 0x7024, 0x4444, 0xE65B, 0x4E4D, 0x462B, 0x6F7C, - 0x4E26, 0, 0x3831, 0xE65C, 0xE65D, 0x4D5B, 0xE65E, 0xE65F, -}; -static const unsigned short utf8_to_euc_E99A[] = { - 0, 0xE660, 0xE661, 0xE662, 0xE663, 0x3679, 0x4E34, 0, - 0x3728, 0xE664, 0x4262, 0x6721, 0, 0x7026, 0x332C, 0x3F6F, - 0, 0xE665, 0, 0, 0x3356, 0x7028, 0xE666, 0x7029, - 0x7027, 0x3764, 0xE667, 0x3A5D, 0x3E63, 0xE668, 0, 0xE669, - 0x3123, 0, 0, 0x4E59, 0xE66A, 0xE66B, 0xE66C, 0x702B, - 0x6E2E, 0xE66D, 0x702A, 0, 0, 0, 0xE66E, 0xE66F, - 0x702E, 0x702C, 0x702D, 0xE670, 0x702F, 0, 0x7030, 0x4E6C, - 0x7031, 0x7032, 0xE671, 0x4049, 0x483B, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E99A_x0213[] = { - 0, 0xE660, 0xFB66, 0xE662, 0x7D5C, 0x3679, 0x4E34, 0, - 0x3728, 0xE664, 0x4262, 0x6721, 0, 0x7026, 0x332C, 0x3F6F, - 0, 0xE665, 0, 0, 0x3356, 0x7028, 0xE666, 0x7029, - 0x7027, 0x3764, 0xFB68, 0x3A5D, 0x3E63, 0x7D5E, 0, 0xE669, - 0x3123, 0, 0, 0x4E59, 0x7D5F, 0x7D60, 0xE66C, 0x702B, - 0x6E2E, 0xFB6B, 0x702A, 0, 0, 0, 0xE66E, 0xFB6C, - 0x702E, 0x702C, 0x702D, 0xFB6D, 0x702F, 0, 0x7030, 0x4E6C, - 0x7031, 0x7032, 0xFB6E, 0x4049, 0x483B, 0xFB6F, 0, 0, -}; -static const unsigned short utf8_to_euc_E99B[] = { - 0x3F7D, 0x3467, 0, 0, 0x4D3A, 0x326D, 0x3D38, 0x385B, - 0, 0x7035, 0xE672, 0x7034, 0x3B73, 0x7036, 0x7033, 0, - 0, 0x3B28, 0xE673, 0, 0, 0x703A, 0x6A2D, 0, - 0xE675, 0x5256, 0xE676, 0x3F77, 0x7038, 0xE677, 0xE678, 0xE679, - 0, 0, 0x4E25, 0x4671, 0, 0, 0, 0, - 0x312B, 0xE67A, 0x4063, 0x3C36, 0, 0, 0, 0xE67B, - 0x4A37, 0xE67C, 0x3140, 0, 0, 0, 0x4E6D, 0x4D6B, - 0, 0x703B, 0xE67D, 0x4545, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E99B_x0213[] = { - 0x3F7D, 0x3467, 0, 0, 0x4D3A, 0x326D, 0x3D38, 0x385B, - 0, 0x7035, 0xE672, 0x7034, 0x3B73, 0x7036, 0x7033, 0, - 0, 0x3B28, 0x7D61, 0, 0, 0x703A, 0x6A2D, 0, - 0xFB72, 0x5256, 0xFB73, 0x3F77, 0x7038, 0xFB74, 0x7D62, 0xE679, - 0, 0, 0x4E25, 0x4671, 0, 0, 0, 0, - 0x312B, 0x7D64, 0x4063, 0x3C36, 0, 0, 0, 0x7D65, - 0x4A37, 0xE67C, 0x3140, 0, 0, 0, 0x4E6D, 0x4D6B, - 0, 0x703B, 0xE67D, 0x4545, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E99C[] = { - 0x3C7B, 0, 0xE67E, 0xE721, 0x703C, 0xE722, 0x703D, 0x3F4C, - 0x703E, 0xE723, 0x4E6E, 0, 0, 0x7039, 0x7040, 0x7042, - 0, 0x7041, 0, 0x703F, 0, 0, 0x7043, 0, - 0, 0x7044, 0xE724, 0xE725, 0x417A, 0xE726, 0x3262, 0, - 0, 0xE727, 0xE728, 0xE729, 0x7045, 0, 0, 0x4C38, - 0xE72A, 0, 0x7046, 0, 0, 0, 0, 0, - 0x7047, 0xE72B, 0x4F2A, 0xE72C, 0, 0, 0, 0, - 0x5B31, 0x7048, 0, 0xF474, 0, 0x7049, 0x704A, 0, -}; -static const unsigned short utf8_to_euc_E99C_x0213[] = { - 0x3C7B, 0, 0xE67E, 0xE721, 0x703C, 0xE722, 0x703D, 0x3F4C, - 0x703E, 0xE723, 0x4E6E, 0, 0, 0x7039, 0x7040, 0x7042, - 0, 0x7041, 0, 0x703F, 0xFB76, 0, 0x7043, 0, - 0, 0x7044, 0xE724, 0xE725, 0x417A, 0xE726, 0x3262, 0, - 0, 0xE727, 0xE728, 0xFB77, 0x7045, 0, 0, 0x4C38, - 0xE72A, 0, 0x7046, 0, 0, 0, 0, 0, - 0x7047, 0xE72B, 0x4F2A, 0x7D66, 0, 0, 0xFB79, 0, - 0x5B31, 0x7048, 0, 0x7D67, 0, 0x7049, 0x704A, 0, -}; -static const unsigned short utf8_to_euc_E99D[] = { - 0, 0xE72D, 0x704E, 0xE72E, 0x704B, 0, 0x704C, 0, - 0x704D, 0x704F, 0xE72F, 0, 0, 0xF475, 0xE730, 0xE731, - 0, 0xF476, 0x4044, 0, 0, 0xE732, 0x4C77, 0xE733, - 0xE734, 0x4045, 0xE735, 0xE736, 0x7050, 0, 0x4873, 0, - 0x7051, 0x7353, 0x4C4C, 0xE737, 0x7052, 0, 0x7053, 0xE738, - 0x7054, 0x3357, 0xE739, 0x7056, 0, 0x3F59, 0xE73A, 0, - 0, 0x7057, 0, 0xE73B, 0x3724, 0, 0xE73C, 0xE73D, - 0xE73E, 0x7058, 0x705C, 0xE73F, 0x705A, 0xE740, 0, 0xE741, -}; -static const unsigned short utf8_to_euc_E99D_x0213[] = { - 0, 0xFB7A, 0x704E, 0, 0x704B, 0, 0x704C, 0xFB7B, - 0x704D, 0x704F, 0xE72F, 0, 0, 0x7D68, 0x7D69, 0x7D6A, - 0, 0, 0x4044, 0, 0, 0xFB7C, 0x4C77, 0xFB7D, - 0xE734, 0x4045, 0x7D6B, 0xFB7E, 0x7050, 0, 0x4873, 0, - 0x7051, 0x7353, 0x4C4C, 0xE737, 0x7052, 0, 0x7053, 0xE738, - 0x7054, 0x3357, 0xFC21, 0x7056, 0, 0x3F59, 0x7D6C, 0, - 0, 0x7057, 0, 0x7D6D, 0x3724, 0, 0xE73C, 0xE73D, - 0xE73E, 0x7058, 0x705C, 0xE73F, 0x705A, 0xE740, 0, 0xE741, -}; -static const unsigned short utf8_to_euc_E99E[] = { - 0xE742, 0x705B, 0, 0, 0x3373, 0x7059, 0x705D, 0, - 0, 0xE743, 0, 0x705E, 0, 0x3048, 0, 0x705F, - 0x7060, 0, 0, 0, 0, 0xE744, 0xE745, 0xE746, - 0x3E64, 0xE747, 0xE748, 0, 0x7061, 0, 0xE749, 0xE74A, - 0x3547, 0, 0xE74B, 0x7064, 0, 0, 0x7063, 0, - 0x7062, 0, 0, 0x6B71, 0xE74C, 0x4A5C, 0xE74D, 0, - 0, 0xE74E, 0xE74F, 0x7065, 0x7066, 0xE750, 0xE751, 0, - 0xE752, 0xE753, 0xE754, 0, 0xE755, 0, 0xE756, 0xE757, -}; -static const unsigned short utf8_to_euc_E99E_x0213[] = { - 0xE742, 0x705B, 0, 0, 0x3373, 0x7059, 0x705D, 0, - 0, 0xE743, 0, 0x705E, 0, 0x3048, 0, 0x705F, - 0x7060, 0, 0, 0, 0, 0x7D6E, 0xFC24, 0xE746, - 0x3E64, 0xE747, 0xFC25, 0, 0x7061, 0, 0xFC26, 0xE74A, - 0x3547, 0, 0xFC27, 0x7064, 0, 0, 0x7063, 0, - 0x7062, 0, 0, 0x6B71, 0xE74C, 0x4A5C, 0x7D6F, 0, - 0, 0xFC28, 0xFC29, 0x7065, 0x7066, 0xE750, 0xE751, 0, - 0xE752, 0xE753, 0x7D70, 0, 0xE755, 0, 0xFC2A, 0xE757, -}; -static const unsigned short utf8_to_euc_E99F[] = { - 0, 0xE758, 0, 0x7067, 0xE759, 0xE75A, 0x7068, 0xE75B, - 0x7069, 0xE75C, 0xE75D, 0x706A, 0xE75E, 0xE75F, 0xE760, 0, - 0xE761, 0xE762, 0, 0x345A, 0xE763, 0, 0, 0xE764, - 0xE765, 0xE766, 0, 0xE76A, 0x706B, 0xE767, 0xE768, 0, - 0xE769, 0xE76B, 0, 0, 0xE76C, 0, 0, 0, - 0, 0, 0, 0, 0, 0x706C, 0x4723, 0xE76D, - 0, 0xE76E, 0x706E, 0x323B, 0xE76F, 0x7071, 0x7070, 0xE770, - 0xE771, 0, 0xE772, 0x3124, 0, 0, 0, 0x3641, -}; -static const unsigned short utf8_to_euc_E99F_x0213[] = { - 0, 0x7D71, 0, 0x7067, 0xE759, 0xE75A, 0x7068, 0xE75B, - 0x7069, 0x7D72, 0xE75D, 0x706A, 0xFC2B, 0xE75F, 0xE760, 0, - 0xE761, 0xFC2C, 0, 0x345A, 0xFC2D, 0, 0, 0xE764, - 0xFC2E, 0xFC2F, 0, 0x7D74, 0x706B, 0xE767, 0x7D73, 0, - 0xE769, 0xFC30, 0, 0, 0xE76C, 0, 0, 0, - 0, 0, 0, 0, 0, 0x706C, 0x4723, 0xE76D, - 0, 0xFC31, 0x706E, 0x323B, 0x7D75, 0x7071, 0x7070, 0xE770, - 0xE771, 0, 0xE772, 0x3124, 0, 0, 0, 0x3641, -}; -static const unsigned short utf8_to_euc_E9A0[] = { - 0, 0x4A47, 0x443A, 0x3A22, 0, 0x3960, 0x3D67, 0xE773, - 0x3F5C, 0, 0xE774, 0, 0x7073, 0xE776, 0xE777, 0x7072, - 0x4D42, 0x3468, 0x4852, 0x465C, 0xE778, 0, 0xE779, 0x3F7C, - 0x4E4E, 0xE775, 0x375B, 0, 0xE77A, 0, 0xE77B, 0, - 0xE77C, 0x7076, 0, 0xE77D, 0x7075, 0xE828, 0xE77E, 0, - 0, 0, 0, 0xE821, 0x4B4B, 0x462C, 0xE822, 0xE823, - 0xE824, 0, 0xE825, 0xE826, 0x3150, 0xE827, 0, 0x7077, - 0x7074, 0, 0, 0x4951, 0x4D6A, 0x7078, 0xE829, 0, -}; -static const unsigned short utf8_to_euc_E9A0_x0213[] = { - 0, 0x4A47, 0x443A, 0x3A22, 0xFC32, 0x3960, 0x3D67, 0xE773, - 0x3F5C, 0, 0x7D77, 0, 0x7073, 0xFC33, 0xFC34, 0x7072, - 0x4D42, 0x3468, 0x4852, 0x465C, 0xFC35, 0, 0xFC36, 0x3F7C, - 0x4E4E, 0xE775, 0x375B, 0, 0xE77A, 0, 0x7D78, 0, - 0xE77C, 0x7076, 0, 0xFC39, 0x7075, 0xFC3C, 0xE77E, 0, - 0, 0, 0, 0x7D79, 0x4B4B, 0x462C, 0xE822, 0xE823, - 0x7D7A, 0, 0xFC3A, 0xFC3B, 0x3150, 0xE827, 0, 0x7077, - 0x7074, 0, 0, 0x4951, 0x4D6A, 0x7078, 0xE829, 0, -}; -static const unsigned short utf8_to_euc_E9A1[] = { - 0, 0, 0, 0, 0xE82A, 0, 0x7079, 0xE82B, - 0, 0, 0xE82C, 0x707B, 0x426A, 0x335B, 0x335C, 0x707A, - 0, 0xE82D, 0xE82E, 0xE82F, 0x3469, 0x3832, 0xE830, 0xE831, - 0x346A, 0xE832, 0xE833, 0x453F, 0, 0, 0x4E60, 0, - 0, 0, 0xE834, 0xE835, 0, 0xE836, 0xE837, 0x385C, - 0, 0, 0xE838, 0x707C, 0xE839, 0, 0, 0x707D, - 0x707E, 0x7121, 0, 0x7123, 0x7122, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9A1_x0213[] = { - 0, 0, 0, 0, 0xE82A, 0, 0x7079, 0xFC3D, - 0, 0, 0xE82C, 0x707B, 0x426A, 0x335B, 0x335C, 0x707A, - 0, 0xE82D, 0x7D7C, 0x7D7D, 0x3469, 0x3832, 0x7D7E, 0x7E21, - 0x346A, 0x7E22, 0x7E23, 0x453F, 0, 0, 0x4E60, 0, - 0, 0, 0xE834, 0xE835, 0, 0x7E25, 0xFC3E, 0x385C, - 0, 0, 0xE838, 0x707C, 0x7E26, 0, 0, 0x707D, - 0x707E, 0x7121, 0, 0x7123, 0x7122, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9A2[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x4977, 0, 0x7124, 0xE83A, 0, 0xE83B, 0xE83C, 0x7125, - 0xE83D, 0x7126, 0, 0, 0xE83E, 0, 0x7127, 0xE83F, - 0xE840, 0, 0xE841, 0xE842, 0, 0, 0, 0xE843, -}; -static const unsigned short utf8_to_euc_E9A2_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x4977, 0, 0x7124, 0xFC3F, 0, 0xFC40, 0xE83C, 0x7125, - 0xFC41, 0x7126, 0, 0, 0xE83E, 0, 0x7127, 0xFC43, - 0xFC44, 0, 0x7E27, 0xFC45, 0xFC46, 0, 0, 0xFC47, -}; -static const unsigned short utf8_to_euc_E9A3[] = { - 0, 0, 0xE844, 0x7129, 0x7128, 0xE845, 0x712A, 0, - 0xE846, 0, 0, 0, 0xE847, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x4874, 0x664C, 0, 0, 0x3F29, - 0, 0xE848, 0x3532, 0xE849, 0, 0xE84A, 0xE84B, 0xE84C, - 0, 0x712B, 0xE84D, 0x712C, 0, 0x522C, 0x5D3B, 0x4853, - 0, 0, 0x307B, 0xE84E, 0x303B, 0, 0xE84F, 0, - 0, 0, 0, 0, 0x3B74, 0x4B30, 0x3E7E, 0, -}; -static const unsigned short utf8_to_euc_E9A3_x0213[] = { - 0, 0, 0xFC48, 0x7129, 0x7128, 0xE845, 0x712A, 0xFC49, - 0x7E28, 0, 0, 0xFC4A, 0xE847, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x4874, 0x664C, 0, 0, 0x3F29, - 0xFC4B, 0xFC4D, 0x3532, 0xFC4E, 0, 0xFC4F, 0xE84B, 0x7E29, - 0, 0x712B, 0xFC50, 0x712C, 0, 0x522C, 0x5D3B, 0x4853, - 0xFC51, 0xFC52, 0x307B, 0xFC53, 0x303B, 0, 0xE84F, 0, - 0, 0, 0, 0, 0x3B74, 0x4B30, 0x3E7E, 0, -}; -static const unsigned short utf8_to_euc_E9A4[] = { - 0, 0, 0xE850, 0x712D, 0, 0x4C5F, 0, 0xE851, - 0xE852, 0x712E, 0x4D5C, 0, 0x3142, 0, 0, 0, - 0x3B41, 0xE853, 0x712F, 0x326E, 0x7130, 0xE854, 0xE855, 0xE856, - 0x7131, 0, 0xE857, 0xE858, 0xE859, 0x7133, 0x7134, 0xE85A, - 0x7136, 0x7132, 0xE85B, 0, 0x7135, 0, 0xE85C, 0xE85D, - 0x345B, 0, 0, 0xE85E, 0x7137, 0, 0x7138, 0, - 0, 0xE85F, 0xE860, 0xE861, 0xE862, 0xE863, 0, 0, - 0, 0xE864, 0xE865, 0xE866, 0xE867, 0x7139, 0x713A, 0, -}; -static const unsigned short utf8_to_euc_E9A4_x0213[] = { - 0, 0, 0xE850, 0x712D, 0, 0x4C5F, 0, 0xE851, - 0xFC54, 0x712E, 0x4D5C, 0, 0x3142, 0, 0, 0, - 0x3B41, 0xE853, 0x712F, 0x326E, 0x7130, 0xE854, 0xFC57, 0xFC58, - 0x7131, 0, 0xFC5A, 0xFC5B, 0xFC5C, 0x7133, 0x7134, 0xE85A, - 0x7136, 0x7132, 0xE85B, 0, 0x7135, 0, 0xE85C, 0, - 0x345B, 0, 0, 0xE85E, 0x7137, 0, 0x7138, 0, - 0, 0xFC5E, 0xFC5F, 0xFC60, 0xE862, 0xE863, 0, 0, - 0, 0xE864, 0xFC61, 0xFC62, 0xFC63, 0x7139, 0x713A, 0, -}; -static const unsigned short utf8_to_euc_E9A5[] = { - 0xE868, 0xE869, 0x713B, 0, 0, 0x713D, 0xE86A, 0xE86B, - 0xE86C, 0x713C, 0, 0x713F, 0x7142, 0xE86D, 0xE86E, 0, - 0x713E, 0x7140, 0x7141, 0, 0xE86F, 0x7143, 0, 0x3642, - 0xE870, 0xE871, 0, 0xE872, 0xE873, 0, 0xE874, 0xE875, - 0xE876, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9A5_x0213[] = { - 0xFC64, 0xFC65, 0x713B, 0, 0, 0x713D, 0xFC66, 0xE86B, - 0xE86C, 0x713C, 0, 0x713F, 0x7142, 0xFC67, 0xFC68, 0, - 0x713E, 0x7140, 0x7141, 0, 0xE86F, 0x7143, 0, 0x3642, - 0x7E2A, 0xE871, 0, 0xE872, 0xFC69, 0, 0xE874, 0xFC6A, - 0xFC6B, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9A6[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x3C73, 0x7144, - 0x7145, 0x3961, 0, 0xE877, 0, 0xE878, 0xF47A, 0xE879, - 0, 0, 0, 0, 0, 0x7146, 0xE87A, 0, - 0x333E, 0, 0, 0, 0x474F, 0x7147, 0x7148, 0, - 0xE87B, 0xE87C, 0xE87D, 0x435A, 0x466B, 0xE87E, 0, 0, - 0, 0xE921, 0xE922, 0, 0x7149, 0xE923, 0, 0xE924, -}; -static const unsigned short utf8_to_euc_E9A6_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x3C73, 0x7144, - 0x7145, 0x3961, 0, 0xE877, 0, 0xE878, 0x7E2B, 0xE879, - 0, 0, 0, 0xFC6C, 0, 0x7146, 0xFC6D, 0, - 0x333E, 0, 0, 0, 0x474F, 0x7147, 0x7148, 0, - 0xE87B, 0xE87C, 0xE87D, 0x435A, 0x466B, 0xE87E, 0, 0, - 0, 0xFC6E, 0xE922, 0, 0x7149, 0xFC6F, 0, 0xFC70, -}; -static const unsigned short utf8_to_euc_E9A7[] = { - 0, 0x477D, 0, 0xE925, 0x424C, 0x3158, 0x366E, 0, - 0x366F, 0xE926, 0, 0, 0, 0, 0, 0, - 0x4373, 0x714E, 0x3670, 0xE927, 0xE928, 0x326F, 0, 0, - 0x714D, 0xE929, 0xE92A, 0x714B, 0xE92B, 0x714C, 0xE92C, 0x714A, - 0, 0, 0x7158, 0, 0, 0, 0, 0xE92D, - 0, 0, 0xE92E, 0xE92F, 0xE930, 0x714F, 0x7150, 0, - 0xE931, 0x7151, 0x7152, 0, 0xE932, 0xE933, 0, 0, - 0x7154, 0xE934, 0, 0x7153, 0, 0xE935, 0xE936, 0x3D59, -}; -static const unsigned short utf8_to_euc_E9A7_x0213[] = { - 0, 0x477D, 0, 0xFC71, 0x424C, 0x3158, 0x366E, 0, - 0x366F, 0xFC72, 0, 0, 0, 0, 0, 0, - 0x4373, 0x714E, 0x3670, 0xE927, 0xFC73, 0x326F, 0, 0, - 0x714D, 0xFC74, 0xE92A, 0x714B, 0xE92B, 0x714C, 0xFC75, 0x714A, - 0, 0, 0x7158, 0, 0, 0, 0, 0xE92D, - 0, 0, 0xE92E, 0xE92F, 0xE930, 0x714F, 0x7150, 0, - 0xFC77, 0x7151, 0x7152, 0, 0xE932, 0xE933, 0, 0, - 0x7154, 0xFC78, 0, 0x7153, 0xFC79, 0xE935, 0xE936, 0x3D59, -}; -static const unsigned short utf8_to_euc_E9A8[] = { - 0, 0x7155, 0xE937, 0xE938, 0xE939, 0x7157, 0, 0, - 0, 0, 0, 0xE93A, 0xE93B, 0, 0x3533, 0x7156, - 0xE93C, 0xE93D, 0x417B, 0x3833, 0, 0, 0xE93E, 0, - 0, 0x7159, 0, 0, 0, 0, 0xE93F, 0, - 0xE940, 0, 0xE941, 0xE942, 0xE943, 0, 0, 0xE944, - 0x424D, 0, 0, 0x715A, 0, 0xE945, 0xE946, 0, - 0x462D, 0, 0, 0xE947, 0, 0xE948, 0xE949, 0x715B, - 0xE94A, 0, 0, 0, 0, 0, 0x7160, 0, -}; -static const unsigned short utf8_to_euc_E9A8_x0213[] = { - 0, 0x7155, 0x7E2C, 0x7E2D, 0xE939, 0x7157, 0, 0, - 0, 0, 0xFC7A, 0xE93A, 0xE93B, 0, 0x3533, 0x7156, - 0xE93C, 0xFC7B, 0x417B, 0x3833, 0, 0, 0xFC7C, 0, - 0, 0x7159, 0xFC7D, 0, 0, 0, 0xE93F, 0, - 0xFC7E, 0, 0xE941, 0xE942, 0x7E2E, 0, 0, 0xE944, - 0x424D, 0, 0, 0x715A, 0, 0x7E2F, 0x7E30, 0, - 0x462D, 0xFD21, 0, 0xE947, 0, 0xE948, 0xFD22, 0x715B, - 0x7E31, 0, 0, 0, 0, 0, 0x7160, 0, -}; -static const unsigned short utf8_to_euc_E9A9[] = { - 0x715E, 0xE94C, 0x715D, 0x715F, 0xE94D, 0x715C, 0, 0xE94B, - 0, 0, 0xE94E, 0xE94F, 0xE950, 0x7162, 0xE951, 0, - 0, 0xE952, 0, 0, 0xE953, 0x7161, 0xE954, 0x7164, - 0, 0, 0x3643, 0x7163, 0, 0xE955, 0, 0x7165, - 0, 0, 0x7166, 0, 0x7168, 0x7167, 0, 0, - 0, 0x7169, 0x716B, 0x716A, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9A9_x0213[] = { - 0x715E, 0xE94C, 0x715D, 0x715F, 0xFD23, 0x715C, 0, 0xE94B, - 0, 0, 0x7E32, 0xE94F, 0xFD24, 0x7162, 0x7E33, 0, - 0, 0xE952, 0x7E34, 0, 0xE953, 0x7161, 0xE954, 0x7164, - 0xFD25, 0, 0x3643, 0x7163, 0, 0xE955, 0, 0x7165, - 0, 0, 0x7166, 0, 0x7168, 0x7167, 0, 0, - 0, 0x7169, 0x716B, 0x716A, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9AA[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x397C, 0, 0xE956, 0, 0xE957, 0x716C, 0xE958, 0xE959, - 0x716D, 0, 0xE95A, 0, 0xE95B, 0xE95C, 0xE95D, 0, - 0x333C, 0xE95E, 0, 0xE95F, 0x716E, 0, 0xE960, 0xE961, -}; -static const unsigned short utf8_to_euc_E9AA_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x397C, 0, 0xE956, 0, 0xE957, 0x716C, 0xE958, 0xFD27, - 0x716D, 0, 0xE95A, 0, 0xE95B, 0xE95C, 0x7E35, 0xFD29, - 0x333C, 0xFD2B, 0, 0xE95F, 0x716E, 0, 0xE960, 0xE961, -}; -static const unsigned short utf8_to_euc_E9AB[] = { - 0x716F, 0xE962, 0, 0xE963, 0x3F71, 0, 0xE964, 0, - 0xE965, 0, 0, 0, 0, 0, 0xE966, 0x7170, - 0xE967, 0x7171, 0xE968, 0x7172, 0x7173, 0xE969, 0xE96A, 0xE96B, - 0x3962, 0xF47B, 0, 0xE96C, 0xE96D, 0, 0x7174, 0x7175, - 0xE96E, 0, 0x7176, 0x7177, 0xE96F, 0xE970, 0x7178, 0xE971, - 0, 0xE972, 0x4831, 0x717A, 0xE973, 0x4926, 0x717B, 0x7179, - 0, 0x717D, 0xE974, 0xE975, 0x717C, 0xE976, 0, 0x717E, - 0, 0xE977, 0xE978, 0x7221, 0, 0xE979, 0, 0xE97A, -}; -static const unsigned short utf8_to_euc_E9AB_x0213[] = { - 0x716F, 0x7E36, 0, 0x7E37, 0x3F71, 0, 0xFD2D, 0, - 0xE965, 0, 0, 0, 0, 0, 0x7E38, 0x7170, - 0xFD2E, 0x7171, 0xFD2F, 0x7172, 0x7173, 0xFD30, 0x7E39, 0xE96B, - 0x3962, 0, 0, 0xE96C, 0xFD32, 0, 0x7174, 0x7175, - 0xFD33, 0, 0x7176, 0x7177, 0xE96F, 0xFD34, 0x7178, 0xE971, - 0, 0xFD35, 0x4831, 0x717A, 0xE973, 0x4926, 0x717B, 0x7179, - 0, 0x717D, 0xE974, 0xE975, 0x717C, 0xE976, 0, 0x717E, - 0, 0x7E3A, 0xE978, 0x7221, 0, 0xE979, 0, 0xE97A, -}; -static const unsigned short utf8_to_euc_E9AC[] = { - 0xE97B, 0xE97C, 0xE97D, 0xE97E, 0xEA21, 0xEA22, 0x7222, 0, - 0xEA23, 0xEA24, 0, 0xEA25, 0xEA26, 0xEA27, 0xEA28, 0, - 0xEA29, 0, 0xEA2A, 0, 0, 0, 0xEA2B, 0, - 0x7223, 0xEA2C, 0x7224, 0xEA2D, 0xEA2E, 0, 0, 0x7225, - 0xEA2F, 0, 0x7226, 0x7227, 0, 0x7228, 0xEA30, 0x7229, - 0x722A, 0x722B, 0x722C, 0xEA31, 0, 0xEA32, 0x722D, 0x722E, - 0, 0x5D35, 0x722F, 0xEA33, 0xEA34, 0xEA35, 0, 0xEA36, - 0, 0xEA37, 0xEA38, 0x6478, 0x3534, 0xEA39, 0, 0, -}; -static const unsigned short utf8_to_euc_E9AC_x0213[] = { - 0xE97B, 0xE97C, 0x7E3B, 0xFD36, 0xEA21, 0xEA22, 0x7222, 0, - 0x7E3C, 0xEA24, 0, 0xEA25, 0xFD37, 0xEA27, 0xEA28, 0, - 0xFD38, 0, 0xFD39, 0, 0, 0, 0xFD3A, 0, - 0x7223, 0xEA2C, 0x7224, 0xEA2D, 0xFD3B, 0, 0, 0x7225, - 0x7E3D, 0, 0x7226, 0x7227, 0, 0x7228, 0xEA30, 0x7229, - 0x722A, 0x722B, 0x722C, 0xFD3C, 0, 0x7E3F, 0x722D, 0x722E, - 0, 0x5D35, 0x722F, 0xFD3D, 0xEA34, 0xEA35, 0, 0xEA36, - 0, 0xEA37, 0xEA38, 0x6478, 0x3534, 0xFD3E, 0, 0, -}; -static const unsigned short utf8_to_euc_E9AD[] = { - 0, 0x3321, 0x3A32, 0x7231, 0x7230, 0x4C25, 0, 0, - 0xEA3A, 0, 0, 0xEA3B, 0xEA3C, 0x7233, 0x7234, 0x7232, - 0, 0x7235, 0, 0, 0x4B62, 0xEA3D, 0xEA3E, 0xEA3F, - 0x7236, 0, 0x357B, 0xEA40, 0, 0, 0xEA41, 0, - 0, 0xEA42, 0, 0xEA43, 0, 0xEA44, 0xEA45, 0, - 0xEA46, 0, 0xEA47, 0xEA48, 0xEA49, 0xEA4A, 0xEA4B, 0x4F25, - 0, 0, 0xF47C, 0xEA4C, 0x7237, 0xEA4D, 0, 0xEA4E, - 0xEA4F, 0xEA50, 0, 0, 0, 0, 0, 0xEA51, -}; -static const unsigned short utf8_to_euc_E9AD_x0213[] = { - 0, 0x3321, 0x3A32, 0x7231, 0x7230, 0x4C25, 0, 0, - 0xEA3A, 0, 0, 0xFD40, 0xEA3C, 0x7233, 0x7234, 0x7232, - 0, 0x7235, 0, 0, 0x4B62, 0xEA3D, 0xEA3E, 0xEA3F, - 0x7236, 0, 0x357B, 0xEA40, 0, 0, 0x7E40, 0, - 0, 0xEA42, 0, 0xFD41, 0, 0xFD42, 0x7E42, 0, - 0xEA46, 0, 0xEA47, 0xFD43, 0xFD44, 0xEA4A, 0xEA4B, 0x4F25, - 0, 0, 0x7E43, 0xFD45, 0x7237, 0x7E44, 0xFD46, 0xFD47, - 0xEA4F, 0x7E41, 0, 0, 0, 0, 0, 0xEA51, -}; -static const unsigned short utf8_to_euc_E9AE[] = { - 0xEA52, 0, 0, 0x7239, 0xEA53, 0xEA54, 0xEA55, 0xEA56, - 0, 0xEA57, 0xEA58, 0xEA59, 0, 0xEA5A, 0x303E, 0xEA5B, - 0xEA5C, 0x723A, 0x4A2B, 0x7238, 0xEA5D, 0, 0x723B, 0x723C, - 0, 0, 0xEA5E, 0, 0, 0xEA5F, 0xEA60, 0x723D, - 0x723E, 0, 0, 0, 0, 0, 0xEA61, 0xEA62, - 0x723F, 0xEA63, 0x4B6E, 0x3B2D, 0xEA64, 0x3A7A, 0x412F, 0, - 0xEA65, 0xEA66, 0xEA67, 0, 0x7240, 0, 0, 0xEA68, - 0xEA69, 0x7243, 0, 0xEA6A, 0xEA6B, 0, 0xEA6C, 0xEA6D, -}; -static const unsigned short utf8_to_euc_E9AE_x0213[] = { - 0xEA52, 0, 0, 0x7239, 0x7E45, 0xEA54, 0xEA55, 0xEA56, - 0, 0xEA57, 0x7E46, 0xEA59, 0, 0xEA5A, 0x303E, 0x7E47, - 0xEA5C, 0x723A, 0x4A2B, 0x7238, 0xEA5D, 0, 0x723B, 0x723C, - 0, 0, 0xEA5E, 0, 0, 0xEA5F, 0x7E48, 0x723D, - 0x723E, 0, 0, 0, 0, 0, 0xFD48, 0x7E49, - 0x723F, 0xEA63, 0x4B6E, 0x3B2D, 0xFD49, 0x3A7A, 0x412F, 0, - 0xEA65, 0xFD4A, 0xFD4D, 0, 0x7240, 0, 0, 0xEA68, - 0xFD4E, 0x7243, 0, 0, 0xEA6B, 0, 0xFD4F, 0xEA6D, -}; -static const unsigned short utf8_to_euc_E9AF[] = { - 0x7241, 0xEA6E, 0, 0, 0, 0, 0x7244, 0xEA6F, - 0xEA70, 0x3871, 0x7242, 0, 0, 0, 0xEA71, 0x7245, - 0xEA72, 0x7246, 0x7247, 0, 0x724B, 0, 0x3B2A, 0xEA73, - 0xEA74, 0, 0, 0x4264, 0, 0xEA75, 0, 0xEA76, - 0, 0x724C, 0x7249, 0x7248, 0x724A, 0xEA77, 0, 0xEA78, - 0x375F, 0, 0xEA79, 0xEA7A, 0, 0, 0, 0xEA7B, - 0x7250, 0x724F, 0x724E, 0xEA7C, 0, 0x3033, 0, 0xEA7D, - 0xEA7E, 0xEB21, 0xEB22, 0, 0, 0xEB23, 0, 0xEB24, -}; -static const unsigned short utf8_to_euc_E9AF_x0213[] = { - 0x7241, 0x7E4A, 0, 0, 0, 0, 0x7244, 0xFD50, - 0xEA70, 0x3871, 0x7242, 0, 0, 0, 0x7E4B, 0x7245, - 0xEA72, 0x7246, 0x7247, 0, 0x724B, 0, 0x3B2A, 0xEA73, - 0xFD52, 0, 0, 0x4264, 0, 0xFD53, 0, 0xEA76, - 0, 0x724C, 0x7249, 0x7248, 0x724A, 0x7E4C, 0, 0xFD54, - 0x375F, 0, 0xFD55, 0xFD56, 0, 0, 0xFD58, 0xFD57, - 0x7250, 0x724F, 0x724E, 0xFD51, 0, 0x3033, 0, 0xFD5C, - 0x7E4D, 0xEB21, 0xFD5A, 0, 0, 0x7E4E, 0, 0xEB24, -}; -static const unsigned short utf8_to_euc_E9B0[] = { - 0xEB25, 0, 0xEB26, 0, 0x725A, 0, 0x7256, 0, - 0x7257, 0x7253, 0x7259, 0xEB27, 0x7255, 0x3362, 0, 0xEB28, - 0x4F4C, 0xEB29, 0x7258, 0x7254, 0x7252, 0x7251, 0xEB2A, 0, - 0xEB2B, 0xEB2C, 0xEB2D, 0x725C, 0xEB2E, 0, 0xEB2F, 0, - 0, 0x725F, 0xEB30, 0xEB31, 0x725E, 0x725D, 0xEB32, 0xEB33, - 0xEB34, 0xEB35, 0xEB36, 0, 0, 0x4949, 0x725B, 0x3073, - 0x7260, 0xEB37, 0x7262, 0, 0, 0xEB38, 0xEB39, 0xEB3A, - 0, 0x336F, 0x724D, 0x3137, 0, 0xEB3B, 0x7264, 0, -}; -static const unsigned short utf8_to_euc_E9B0_x0213[] = { - 0x7E4F, 0, 0xEB26, 0, 0x725A, 0, 0x7256, 0, - 0x7257, 0x7253, 0x7259, 0xEB27, 0x7255, 0x3362, 0, 0xEB28, - 0x4F4C, 0xEB29, 0x7258, 0x7254, 0x7252, 0x7251, 0xFD5E, 0, - 0xFD5F, 0xFD60, 0xFD61, 0x725C, 0xEB2E, 0xFD62, 0xEB2F, 0, - 0, 0x725F, 0xFD63, 0x7E50, 0x725E, 0x725D, 0xEB32, 0xFD64, - 0xEB34, 0xFD65, 0xFD66, 0, 0, 0x4949, 0x725B, 0x3073, - 0x7260, 0xFD68, 0x7262, 0, 0, 0xEB38, 0xFD69, 0xFD6A, - 0, 0x336F, 0x724D, 0x3137, 0, 0xEB3B, 0x7264, 0, -}; -static const unsigned short utf8_to_euc_E9B1[] = { - 0, 0xEB3C, 0, 0xEB3D, 0xEB3E, 0xEB3F, 0x7263, 0x7261, - 0x432D, 0xEB40, 0xEB41, 0, 0, 0, 0xEB42, 0xEB43, - 0xEB44, 0, 0x4B70, 0xEB45, 0xEB46, 0, 0xEB47, 0x4E5A, - 0xEB48, 0, 0x7265, 0xEB49, 0xEB50, 0xEB4A, 0xEB4B, 0xEB4C, - 0x7266, 0, 0, 0xEB4D, 0, 0, 0, 0x7267, - 0xEB52, 0xEB4E, 0xEB4F, 0xEB51, 0, 0, 0xEB53, 0, - 0xEB54, 0, 0xEB55, 0, 0, 0xEB56, 0x7268, 0xEB57, - 0x7269, 0, 0, 0xEB58, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B1_x0213[] = { - 0, 0x7E51, 0, 0xEB3D, 0xEB3E, 0xFD6B, 0x7263, 0x7261, - 0x432D, 0xFD6E, 0xFD6F, 0, 0, 0, 0xEB42, 0x7E52, - 0x7E53, 0, 0x4B70, 0x7E54, 0xFD71, 0, 0xEB47, 0x4E5A, - 0xFD72, 0, 0x7265, 0xFD73, 0xFD6C, 0xFD74, 0xEB4B, 0xFD75, - 0x7266, 0, 0, 0x7E55, 0, 0x7E56, 0, 0x7267, - 0xEB52, 0xFD76, 0xFD77, 0xFD78, 0, 0xFD79, 0xFD7A, 0, - 0xFD7B, 0, 0xFD7C, 0, 0, 0xFD7D, 0x7268, 0x7E57, - 0x7269, 0, 0xFD7E, 0xEB58, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B3[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x443B, 0xEB59, 0x726A, - 0, 0x4837, 0, 0x726F, 0x726B, 0, 0, 0, - 0x726C, 0, 0xEB5A, 0x4B31, 0x4C44, 0, 0x4650, 0xEB5B, - 0, 0xEB5C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B3_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x443B, 0xFE21, 0x726A, - 0, 0x4837, 0, 0x726F, 0x726B, 0, 0, 0, - 0x726C, 0, 0xFE22, 0x4B31, 0x4C44, 0, 0x4650, 0xEB5B, - 0, 0xEB5C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B4[] = { - 0, 0, 0xEB5E, 0x7270, 0, 0, 0x7271, 0x463E, - 0x726E, 0x726D, 0, 0xEB5D, 0, 0, 0x322A, 0, - 0, 0xEB5F, 0x7279, 0, 0, 0x7278, 0, 0xEB60, - 0xEB61, 0, 0, 0x3175, 0xEB62, 0xEB63, 0xEB64, 0x7276, - 0, 0, 0, 0x7275, 0, 0, 0x7273, 0, - 0x337B, 0, 0x7272, 0x3C32, 0x3229, 0, 0, 0xEB65, - 0xEB66, 0, 0xEB67, 0xEB68, 0xEB69, 0, 0, 0, - 0, 0, 0xEB6A, 0x3963, 0xEB6B, 0xEB6D, 0x727C, 0x727B, -}; -static const unsigned short utf8_to_euc_E9B4_x0213[] = { - 0, 0, 0xFE24, 0x7270, 0, 0, 0x7271, 0x463E, - 0x726E, 0x726D, 0, 0xFE23, 0, 0, 0x322A, 0, - 0, 0xFE26, 0x7279, 0, 0, 0x7278, 0, 0xFE27, - 0xFE28, 0, 0, 0x3175, 0xEB62, 0x7E58, 0x7E59, 0x7276, - 0, 0, 0, 0x7275, 0, 0, 0x7273, 0, - 0x337B, 0, 0x7272, 0x3C32, 0x3229, 0, 0, 0xEB65, - 0xEB66, 0, 0xFE2C, 0xEB68, 0xEB69, 0, 0, 0, - 0, 0, 0xEB6A, 0x3963, 0xEB6B, 0xEB6D, 0x727C, 0x727B, -}; -static const unsigned short utf8_to_euc_E9B5[] = { - 0, 0x727A, 0xEB6E, 0xEB6F, 0x7277, 0xEB6C, 0x727D, 0xEB70, - 0x727E, 0, 0xEB71, 0, 0, 0, 0, 0, - 0x7325, 0x7324, 0, 0xEB72, 0xEB73, 0, 0, 0, - 0, 0x7326, 0, 0, 0x312D, 0x7321, 0x7322, 0xEB74, - 0x3974, 0x4C39, 0xEB76, 0xEB75, 0x7323, 0xEB77, 0, 0, - 0, 0xEB78, 0xEB79, 0xEB7A, 0x4B32, 0, 0, 0x732B, - 0xEB7B, 0, 0x7327, 0, 0, 0, 0xEB7C, 0xEB7D, - 0, 0, 0x732C, 0xEB7E, 0xEC21, 0, 0xEC22, 0, -}; -static const unsigned short utf8_to_euc_E9B5_x0213[] = { - 0, 0x727A, 0xFE2E, 0x7E5A, 0x7277, 0xEB6C, 0x727D, 0x7E5B, - 0x727E, 0, 0xFE2F, 0, 0, 0, 0, 0, - 0x7325, 0x7324, 0x7E5C, 0xEB72, 0xEB73, 0, 0, 0, - 0, 0x7326, 0, 0, 0x312D, 0x7321, 0x7322, 0xFE30, - 0x3974, 0x4C39, 0xFE31, 0x7E5D, 0x7323, 0xEB77, 0, 0, - 0, 0xFE33, 0xEB79, 0xFE34, 0x4B32, 0, 0, 0x732B, - 0x7E5E, 0, 0x7327, 0xFE36, 0, 0, 0xFE37, 0xFE38, - 0, 0, 0x732C, 0xEB7E, 0x7E5F, 0, 0xFE39, 0, -}; -static const unsigned short utf8_to_euc_E9B6[] = { - 0, 0, 0, 0xEC23, 0xEC24, 0, 0xEC25, 0x7329, - 0, 0x7328, 0xEC26, 0, 0, 0xEC27, 0xEC28, 0x375C, - 0, 0, 0xEC29, 0xEC2A, 0, 0xEC2B, 0xEC2C, 0xEC2D, - 0xEC2E, 0, 0x732D, 0, 0, 0, 0, 0, - 0, 0xEC2F, 0, 0, 0x732E, 0, 0, 0, - 0, 0x732F, 0xEC30, 0x732A, 0xEC31, 0, 0xEC32, 0x7274, - 0, 0xEC33, 0x7330, 0, 0x4461, 0xEC34, 0, 0, - 0x7334, 0xEC35, 0x7335, 0x7333, 0xEC36, 0, 0, 0xEC37, -}; -static const unsigned short utf8_to_euc_E9B6_x0213[] = { - 0, 0, 0, 0xEC23, 0xFE3A, 0, 0xEC25, 0x7329, - 0, 0x7328, 0x7E60, 0, 0, 0xFE3B, 0xEC28, 0x375C, - 0, 0, 0xEC29, 0xEC2A, 0, 0xEC2B, 0x7E61, 0xEC2D, - 0xEC2E, 0xFE3C, 0x732D, 0, 0, 0, 0, 0, - 0, 0xFE3D, 0, 0, 0x732E, 0, 0, 0, - 0, 0x732F, 0xEC30, 0x732A, 0x7E63, 0, 0xEC32, 0x7274, - 0, 0xEC33, 0x7330, 0, 0x4461, 0xFE3F, 0, 0, - 0x7334, 0xFE40, 0x7335, 0x7333, 0x7E64, 0xFE41, 0, 0xFE3E, -}; -static const unsigned short utf8_to_euc_E9B7[] = { - 0, 0x7332, 0x7338, 0xEC38, 0x7331, 0, 0x7336, 0xEC39, - 0, 0xEC3A, 0xEC3B, 0, 0, 0, 0, 0x7337, - 0, 0, 0, 0x733A, 0xEC3C, 0xEC3D, 0xEC3E, 0xEC3F, - 0, 0x7339, 0xEC40, 0, 0, 0, 0xEC41, 0xEC42, - 0xEC43, 0, 0, 0, 0, 0xEC44, 0x733C, 0xEC45, - 0, 0xEC46, 0, 0xEC47, 0, 0x733D, 0xEC48, 0x733E, - 0xEC49, 0, 0x4F49, 0xEC4A, 0xEC4B, 0, 0, 0, - 0x733B, 0x426B, 0x3A6D, 0, 0, 0x733F, 0xEC4C, 0, -}; -static const unsigned short utf8_to_euc_E9B7_x0213[] = { - 0x7E62, 0x7332, 0x7338, 0xFE42, 0x7331, 0, 0x7336, 0xFE43, - 0, 0xFE44, 0xEC3B, 0, 0, 0, 0, 0x7337, - 0, 0, 0, 0x733A, 0xEC3C, 0xEC3D, 0xFE45, 0x7E65, - 0, 0x7339, 0xFE46, 0, 0, 0, 0xEC41, 0xFE47, - 0xFE48, 0, 0, 0xFE49, 0, 0xEC44, 0x733C, 0x7E67, - 0, 0xEC46, 0, 0xEC47, 0, 0x733D, 0xEC48, 0x733E, - 0xEC49, 0, 0x4F49, 0xEC4A, 0xFE4A, 0, 0, 0, - 0x733B, 0x426B, 0x3A6D, 0, 0, 0x733F, 0xEC4C, 0, -}; -static const unsigned short utf8_to_euc_E9B8[] = { - 0, 0, 0xEC4E, 0, 0, 0, 0, 0xEC4F, - 0, 0, 0xEC4D, 0, 0, 0, 0xEC50, 0, - 0xEC51, 0xEC52, 0xEC53, 0, 0, 0xEC54, 0xEC55, 0, - 0, 0xEC56, 0x7340, 0x7341, 0xEC57, 0xEC58, 0x7342, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B8_x0213[] = { - 0, 0, 0xFE4D, 0, 0, 0, 0, 0x7E68, - 0, 0, 0xFE4C, 0, 0, 0xFE4E, 0xEC50, 0, - 0xEC51, 0xEC52, 0xEC53, 0, 0, 0x7E69, 0xEC55, 0, - 0, 0xFE4F, 0x7340, 0x7341, 0xFE50, 0xFE51, 0x7342, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9B9[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x7343, 0, 0, - 0x3834, 0x7344, 0xEC59, 0xEC5A, 0xEC5B, 0x7345, 0, 0x3C2F, -}; -static const unsigned short utf8_to_euc_E9B9_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x7343, 0, 0, - 0x3834, 0x7344, 0xEC59, 0xFE52, 0x7E6A, 0x7345, 0, 0x3C2F, -}; -static const unsigned short utf8_to_euc_E9BA[] = { - 0xEC5C, 0x7346, 0xEC5D, 0xEC5E, 0xEC5F, 0xEC60, 0, 0xEC61, - 0x7347, 0, 0, 0x7348, 0x7349, 0, 0xEC62, 0xEC63, - 0, 0x734C, 0x734A, 0x4F3C, 0, 0x734B, 0xEC64, 0x4E6F, - 0xEC65, 0, 0, 0xEC66, 0, 0x734D, 0xEC67, 0x4E5B, - 0, 0, 0, 0, 0xEC68, 0x734E, 0x477E, 0, - 0xEC69, 0x734F, 0x7351, 0, 0xEC6A, 0x7352, 0xEC6B, 0xEC6C, - 0xEC6D, 0, 0, 0xEC6E, 0xEC6F, 0xEC70, 0, 0, - 0x7350, 0x396D, 0x4C4D, 0x4B63, 0x5677, 0, 0x5D60, 0x4B7B, -}; -static const unsigned short utf8_to_euc_E9BA_x0213[] = { - 0xFE54, 0x7346, 0xEC5D, 0xEC5E, 0xEC5F, 0xFE55, 0, 0xEC61, - 0x7347, 0, 0, 0x7348, 0x7349, 0, 0xEC62, 0xEC63, - 0, 0x734C, 0x734A, 0x4F3C, 0, 0x734B, 0xEC64, 0x4E6F, - 0xEC65, 0, 0, 0xFE56, 0, 0x734D, 0x7E6B, 0x4E5B, - 0, 0, 0, 0, 0x7E6C, 0x734E, 0x477E, 0, - 0xFE57, 0x734F, 0x7351, 0, 0x7E6D, 0x7352, 0xEC6B, 0x7E6E, - 0xEC6D, 0, 0, 0xEC6E, 0x7E6F, 0x7E70, 0, 0, - 0x7350, 0x396D, 0x4C4D, 0x4B63, 0x5677, 0xFE59, 0x5D60, 0x4B7B, -}; -static const unsigned short utf8_to_euc_E9BB[] = { - 0, 0, 0, 0, 0x322B, 0, 0xEC71, 0, - 0xEC72, 0, 0, 0xEC73, 0x7354, 0x3550, 0x7355, 0x7356, - 0x7357, 0xF47E, 0x3975, 0, 0x7358, 0xEC74, 0, 0, - 0x6054, 0x4C5B, 0, 0x4263, 0x7359, 0x735B, 0x735A, 0xEC75, - 0x735C, 0, 0, 0, 0xEC76, 0x735D, 0, 0xEC77, - 0x735E, 0, 0, 0, 0xEC78, 0xEC79, 0xEC7A, 0x735F, - 0xEC7B, 0xEC7C, 0xEC7D, 0, 0x7360, 0xEC7E, 0x7361, 0x7362, - 0xED21, 0x7363, 0, 0x7364, 0x7365, 0x7366, 0, 0xED22, -}; -static const unsigned short utf8_to_euc_E9BB_x0213[] = { - 0, 0, 0, 0x7E71, 0x322B, 0, 0xEC71, 0, - 0xEC72, 0, 0, 0xEC73, 0x7354, 0x3550, 0x7355, 0x7356, - 0x7357, 0x7E72, 0x3975, 0, 0x7358, 0xEC74, 0, 0, - 0x6054, 0x4C5B, 0, 0x4263, 0x7359, 0x735B, 0x735A, 0xFE5B, - 0x735C, 0, 0, 0, 0xEC76, 0x735D, 0, 0xFE5C, - 0x735E, 0, 0, 0, 0xEC78, 0xEC79, 0xFE5D, 0x735F, - 0xEC7B, 0xEC7C, 0xEC7D, 0, 0x7360, 0xEC7E, 0x7361, 0x7362, - 0xED21, 0x7363, 0, 0x7364, 0x7365, 0x7366, 0, 0xFE5E, -}; -static const unsigned short utf8_to_euc_E9BC[] = { - 0, 0, 0xED23, 0xED24, 0, 0, 0, 0x7367, - 0x7368, 0xED25, 0, 0, 0, 0, 0x4524, 0xED26, - 0xED27, 0xED28, 0xED29, 0x385D, 0xED2A, 0x736A, 0xED2B, 0xED2C, - 0, 0xED2D, 0xED2E, 0xED2F, 0, 0, 0, 0xED30, - 0x414D, 0x736B, 0xED31, 0, 0, 0, 0xED32, 0, - 0, 0, 0xED33, 0xED34, 0x736C, 0, 0, 0xED35, - 0, 0xED36, 0xED37, 0, 0xED38, 0, 0, 0xED39, - 0, 0xED3A, 0xED3B, 0x4921, 0xED3C, 0xED3D, 0x736D, 0xED3E, -}; -static const unsigned short utf8_to_euc_E9BC_x0213[] = { - 0, 0, 0xFE5F, 0xFE61, 0, 0, 0, 0x7367, - 0x7368, 0xED25, 0, 0, 0, 0, 0x4524, 0xED26, - 0x7E73, 0xED28, 0xED29, 0x385D, 0xED2A, 0x736A, 0xED2B, 0xFE62, - 0, 0xFE63, 0xED2E, 0xED2F, 0, 0, 0, 0xED30, - 0x414D, 0x736B, 0xED31, 0, 0, 0, 0xED32, 0, - 0, 0, 0xED33, 0xED34, 0x736C, 0, 0, 0xFE64, - 0, 0xED36, 0xED37, 0, 0xED38, 0, 0, 0xFE65, - 0, 0x7E74, 0xFE66, 0x4921, 0xED3C, 0xFE67, 0x736D, 0xED3E, -}; -static const unsigned short utf8_to_euc_E9BD[] = { - 0, 0xED3F, 0, 0xED40, 0xED41, 0xED42, 0xED43, 0xED44, - 0, 0, 0x736E, 0x6337, 0, 0, 0x6C5A, 0x706D, - 0, 0, 0x736F, 0xED45, 0x7370, 0xED46, 0xED47, 0xED48, - 0xED49, 0, 0xED4A, 0, 0, 0xED4B, 0xED4C, 0x7372, - 0x7373, 0x7374, 0x4E70, 0x7371, 0, 0, 0x7375, 0x7376, - 0xED4D, 0xED4E, 0x7378, 0, 0x7377, 0xED4F, 0xED50, 0xED51, - 0xED52, 0xED53, 0x737A, 0xED54, 0, 0xED55, 0x737B, 0x7379, - 0, 0, 0xED56, 0, 0, 0xED57, 0, 0, -}; -static const unsigned short utf8_to_euc_E9BD_x0213[] = { - 0, 0xFE68, 0, 0xED40, 0xED41, 0xFE69, 0xFE6A, 0xED44, - 0, 0, 0x736E, 0x6337, 0, 0, 0x6C5A, 0x706D, - 0, 0, 0x736F, 0xFE6B, 0x7370, 0xFE6C, 0xED47, 0x7E75, - 0xFE6D, 0, 0xED4A, 0, 0, 0xFE6F, 0xED4C, 0x7372, - 0x7373, 0x7374, 0x4E70, 0x7371, 0, 0, 0x7375, 0x7376, - 0xED4D, 0xFE71, 0x7378, 0, 0x7377, 0xFE73, 0xED50, 0xED51, - 0xFE74, 0xED53, 0x737A, 0xED54, 0, 0xFE75, 0x737B, 0x7379, - 0, 0, 0xED56, 0, 0, 0xED57, 0, 0, -}; -static const unsigned short utf8_to_euc_E9BE[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x4E36, 0, 0xED58, - 0xED59, 0xED5A, 0xED5B, 0, 0xED5C, 0x737C, 0xED5D, 0xED5E, - 0, 0, 0, 0, 0x737D, 0x6354, 0xED5F, 0, - 0x737E, 0xED60, 0xED61, 0xED62, 0, 0xED63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_E9BE_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x4E36, 0, 0xED58, - 0x7E76, 0xED5A, 0xED5B, 0, 0x7E77, 0x737C, 0xED5D, 0x7E78, - 0, 0, 0, 0, 0x737D, 0x6354, 0xED5F, 0, - 0x737E, 0xED60, 0x7E79, 0xED62, 0, 0xED63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA4[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xF445, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA4_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0x763B, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x742E, 0x754E, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x7B4F, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA5_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x7649, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA7[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xF472, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA7_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x7E24, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x7D5D, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA8[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xF434, 0xF437, - 0xF438, 0xF43D, 0xF444, 0xF447, 0xF448, 0xF44E, 0xF44F, 0xF453, - 0xF455, 0xF456, 0xF457, 0xF458, 0xF45A, 0xF45B, 0xF45E, 0xF460, - 0xF462, 0xF463, 0xF465, 0xF469, 0xF46A, 0xF46B, 0xF46D, 0xF46F, - 0xF470, 0xF473, 0xF477, 0xF478, 0xF479, 0xF47D, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFA8_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x2F4B, - 0x2F57, 0x4F72, 0, 0xAE79, 0x757A, 0x775A, 0x776F, 0, - 0, 0x793C, 0x793D, 0x7941, 0, 0, 0, 0x7B3A, - 0xF738, 0xF745, 0x7C2E, 0, 0xF96E, 0, 0x7C6A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2E38, 0x2E49, 0x2E50, 0x2E63, 0x2E68, 0x2E6E, 0x2F2C, 0x2F2F, - 0x2F36, 0x2F5A, 0x2F5E, 0x4F61, 0x4F62, 0x7450, 0x745C, 0x745E, -}; -static const unsigned short utf8_to_euc_EFA9_x0213[] = { - 0x7461, 0x7528, 0x752B, 0x7543, 0x7565, 0x7669, 0x7677, 0x7725, - 0x7755, 0xF029, 0x7825, 0x7927, 0x7933, 0x7934, 0x7937, 0x7938, - 0x7939, 0x793B, 0x793F, 0x7940, 0x794D, 0x7951, 0x7964, 0x7A2E, - 0xF450, 0x7A33, 0x7A3A, 0x7A44, 0x7A58, 0xF574, 0xF575, 0x7B27, - 0x7B6F, 0x7B79, 0x7C2F, 0x7C30, 0x7C38, 0x7C3D, 0xF969, 0x7C59, - 0x7D63, 0x7D76, 0x7D7B, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFB9_x0213[] = { - 0, 0, 0, 0, 0, 0x233E, 0x233D, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFBC[] = { - 0, 0x212A, 0xF42A, 0x2174, 0x2170, 0x2173, 0x2175, 0xF429, - 0x214A, 0x214B, 0x2176, 0x215C, 0x2124, 0x215D, 0x2125, 0x213F, - 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, - 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, - 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, - 0x2348, 0x2349, 0x234A, 0x234B, 0x234C, 0x234D, 0x234E, 0x234F, - 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, - 0x2358, 0x2359, 0x235A, 0x214E, 0x2140, 0x214F, 0x2130, 0x2132, -}; -static const unsigned short utf8_to_euc_EFBC_x0213[] = { - 0, 0x212A, 0x2230, 0x2174, 0x2170, 0x2173, 0x2175, 0x222F, - 0x214A, 0x214B, 0x2176, 0x215C, 0x2124, 0x2231, 0x2125, 0x213F, - 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, - 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, - 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, - 0x2348, 0x2349, 0x234A, 0x234B, 0x234C, 0x234D, 0x234E, 0x234F, - 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, - 0x2358, 0x2359, 0x235A, 0x214E, 0x2140, 0x214F, 0x2130, 0x2132, -}; -static const unsigned short utf8_to_euc_EFBD[] = { - 0x212E, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, - 0x2368, 0x2369, 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, 0x236F, - 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, - 0x2378, 0x2379, 0x237A, 0x2150, 0x2143, 0x2151, 0xA237, 0, - 0, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, - 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, - 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, - 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F, -}; -static const unsigned short utf8_to_euc_EFBD_ms[] = { - 0x212E, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, - 0x2368, 0x2369, 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, 0x236F, - 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, - 0x2378, 0x2379, 0x237A, 0x2150, 0x2143, 0x2151, 0x2141, 0, - 0, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, - 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, - 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, - 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F, -}; -static const unsigned short utf8_to_euc_EFBD_x0213[] = { - 0x212E, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, - 0x2368, 0x2369, 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, 0x236F, - 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, - 0x2378, 0x2379, 0x237A, 0x2150, 0x2143, 0x2151, 0x2232, 0x2256, - 0x2257, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, - 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, - 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, - 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F, -}; -static const unsigned short utf8_to_euc_EFBE[] = { - 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, - 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, - 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, - 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0E5C, 0x0E5D, 0x0E5E, 0x0E5F, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFBF[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x2171, 0x2172, 0x224C, 0x2131, 0xA243, 0x216F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short utf8_to_euc_EFBF_x0213[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0x2131, 0, 0x216F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E1_x0213[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_E1B8_x0213, 0, 0, 0, - 0, utf8_to_euc_E1BD_x0213, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E2[] = { - utf8_to_euc_E280, 0, 0, 0, - utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287, - utf8_to_euc_E288, utf8_to_euc_E289, utf8_to_euc_E28A, 0, - utf8_to_euc_E28C, 0, 0, 0, - 0, utf8_to_euc_E291, 0, 0, - utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297, - utf8_to_euc_E298, utf8_to_euc_E299, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E2_ms[] = { - utf8_to_euc_E280_ms, 0, 0, 0, - utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287, - utf8_to_euc_E288, utf8_to_euc_E289, utf8_to_euc_E28A, 0, - utf8_to_euc_E28C, 0, 0, 0, - 0, utf8_to_euc_E291, 0, 0, - utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297, - utf8_to_euc_E298, utf8_to_euc_E299, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E2_932[] = { - utf8_to_euc_E280_932, 0, 0, 0, - utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287, - utf8_to_euc_E288_932, utf8_to_euc_E289, utf8_to_euc_E28A, 0, - utf8_to_euc_E28C, 0, 0, 0, - 0, utf8_to_euc_E291, 0, 0, - utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297, - utf8_to_euc_E298, utf8_to_euc_E299, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E2_mac[] = { - utf8_to_euc_E280_932, 0, 0, 0, - utf8_to_euc_E284_mac, utf8_to_euc_E285_mac, utf8_to_euc_E286, utf8_to_euc_E287, - utf8_to_euc_E288_mac, utf8_to_euc_E289, utf8_to_euc_E28A_mac, 0, - utf8_to_euc_E28C, 0, 0, 0, - 0, utf8_to_euc_E291_mac, 0, 0, - utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297, - utf8_to_euc_E298, utf8_to_euc_E299, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E2_x0213[] = { - utf8_to_euc_E280_x0213, utf8_to_euc_E281_x0213, utf8_to_euc_E282_x0213, 0, - utf8_to_euc_E284_x0213, utf8_to_euc_E285_x0213, utf8_to_euc_E286_x0213, utf8_to_euc_E287_x0213, - utf8_to_euc_E288_x0213, utf8_to_euc_E289_x0213, utf8_to_euc_E28A_x0213, utf8_to_euc_E28B_x0213, - utf8_to_euc_E28C_x0213, 0, utf8_to_euc_E28E_x0213, utf8_to_euc_E28F_x0213, - utf8_to_euc_E290_x0213, utf8_to_euc_E291, 0, utf8_to_euc_E293_x0213, - utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296_x0213, utf8_to_euc_E297_x0213, - utf8_to_euc_E298_x0213, utf8_to_euc_E299_x0213, 0, 0, - utf8_to_euc_E29C_x0213, utf8_to_euc_E29D_x0213, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_E2A4_x0213, 0, utf8_to_euc_E2A6_x0213, utf8_to_euc_E2A7_x0213, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E3[] = { - utf8_to_euc_E380, utf8_to_euc_E381, utf8_to_euc_E382, utf8_to_euc_E383, - 0, 0, 0, 0, - utf8_to_euc_E388, 0, utf8_to_euc_E38A, 0, - utf8_to_euc_E38C, utf8_to_euc_E38D, utf8_to_euc_E38E, utf8_to_euc_E38F, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E3_932[] = { - utf8_to_euc_E380_932, utf8_to_euc_E381, utf8_to_euc_E382_932, utf8_to_euc_E383, - 0, 0, 0, 0, - utf8_to_euc_E388, 0, utf8_to_euc_E38A, 0, - utf8_to_euc_E38C, utf8_to_euc_E38D, utf8_to_euc_E38E, utf8_to_euc_E38F, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E3_mac[] = { - utf8_to_euc_E380_932, utf8_to_euc_E381, utf8_to_euc_E382_932, utf8_to_euc_E383, - 0, 0, 0, 0, - utf8_to_euc_E388_mac, 0, utf8_to_euc_E38A_mac, 0, - utf8_to_euc_E38C_mac, utf8_to_euc_E38D_mac, utf8_to_euc_E38E_mac, utf8_to_euc_E38F_mac, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -static const unsigned short *const utf8_to_euc_E3_x0213[] = { - utf8_to_euc_E380_x0213, utf8_to_euc_E381, utf8_to_euc_E382_x0213, utf8_to_euc_E383_x0213, - 0, 0, 0, utf8_to_euc_E387_x0213, - utf8_to_euc_E388, utf8_to_euc_E389_x0213, utf8_to_euc_E38A_x0213, utf8_to_euc_E38B_x0213, - utf8_to_euc_E38C, utf8_to_euc_E38D, utf8_to_euc_E38E, utf8_to_euc_E38F_x0213, - utf8_to_euc_E390_x0213, utf8_to_euc_E391_x0213, utf8_to_euc_E392_x0213, utf8_to_euc_E393_x0213, - utf8_to_euc_E394_x0213, utf8_to_euc_E395_x0213, utf8_to_euc_E396_x0213, utf8_to_euc_E397_x0213, - utf8_to_euc_E398_x0213, utf8_to_euc_E399_x0213, utf8_to_euc_E39A_x0213, utf8_to_euc_E39B_x0213, - 0, utf8_to_euc_E39D_x0213, utf8_to_euc_E39E_x0213, utf8_to_euc_E39F_x0213, - utf8_to_euc_E3A0_x0213, utf8_to_euc_E3A1_x0213, 0, utf8_to_euc_E3A3_x0213, - utf8_to_euc_E3A4_x0213, utf8_to_euc_E3A5_x0213, 0, 0, - 0, utf8_to_euc_E3A9_x0213, 0, utf8_to_euc_E3AB_x0213, - utf8_to_euc_E3AC_x0213, utf8_to_euc_E3AD_x0213, utf8_to_euc_E3AE_x0213, utf8_to_euc_E3AF_x0213, - utf8_to_euc_E3B0_x0213, 0, 0, utf8_to_euc_E3B3_x0213, - utf8_to_euc_E3B4_x0213, utf8_to_euc_E3B5_x0213, utf8_to_euc_E3B6_x0213, utf8_to_euc_E3B7_x0213, - utf8_to_euc_E3B8_x0213, utf8_to_euc_E3B9_x0213, utf8_to_euc_E3BA_x0213, 0, - 0, utf8_to_euc_E3BD_x0213, utf8_to_euc_E3BE_x0213, utf8_to_euc_E3BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E4[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_E4B8, utf8_to_euc_E4B9, utf8_to_euc_E4BA, utf8_to_euc_E4BB, - utf8_to_euc_E4BC, utf8_to_euc_E4BD, utf8_to_euc_E4BE, utf8_to_euc_E4BF, -}; -static const unsigned short *const utf8_to_euc_E4_x0213[] = { - utf8_to_euc_E480_x0213, utf8_to_euc_E481_x0213, utf8_to_euc_E482_x0213, 0, - utf8_to_euc_E484_x0213, utf8_to_euc_E485_x0213, utf8_to_euc_E486_x0213, utf8_to_euc_E487_x0213, - utf8_to_euc_E488_x0213, utf8_to_euc_E489_x0213, 0, utf8_to_euc_E48B_x0213, - utf8_to_euc_E48C_x0213, utf8_to_euc_E48D_x0213, 0, utf8_to_euc_E48F_x0213, - utf8_to_euc_E490_x0213, utf8_to_euc_E491_x0213, utf8_to_euc_E492_x0213, utf8_to_euc_E493_x0213, - utf8_to_euc_E494_x0213, utf8_to_euc_E495_x0213, utf8_to_euc_E496_x0213, utf8_to_euc_E497_x0213, - utf8_to_euc_E498_x0213, utf8_to_euc_E499_x0213, utf8_to_euc_E49A_x0213, 0, - utf8_to_euc_E49C_x0213, utf8_to_euc_E49D_x0213, 0, utf8_to_euc_E49F_x0213, - utf8_to_euc_E4A0_x0213, utf8_to_euc_E4A1_x0213, utf8_to_euc_E4A2_x0213, 0, - 0, 0, utf8_to_euc_E4A6_x0213, utf8_to_euc_E4A7_x0213, - utf8_to_euc_E4A8_x0213, 0, utf8_to_euc_E4AA_x0213, 0, - utf8_to_euc_E4AC_x0213, 0, 0, utf8_to_euc_E4AF_x0213, - utf8_to_euc_E4B0_x0213, 0, 0, utf8_to_euc_E4B3_x0213, - utf8_to_euc_E4B4_x0213, utf8_to_euc_E4B5_x0213, 0, 0, - utf8_to_euc_E4B8_x0213, utf8_to_euc_E4B9_x0213, utf8_to_euc_E4BA_x0213, utf8_to_euc_E4BB_x0213, - utf8_to_euc_E4BC_x0213, utf8_to_euc_E4BD_x0213, utf8_to_euc_E4BE_x0213, utf8_to_euc_E4BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E5[] = { - utf8_to_euc_E580, utf8_to_euc_E581, utf8_to_euc_E582, utf8_to_euc_E583, - utf8_to_euc_E584, utf8_to_euc_E585, utf8_to_euc_E586, utf8_to_euc_E587, - utf8_to_euc_E588, utf8_to_euc_E589, utf8_to_euc_E58A, utf8_to_euc_E58B, - utf8_to_euc_E58C, utf8_to_euc_E58D, utf8_to_euc_E58E, utf8_to_euc_E58F, - utf8_to_euc_E590, utf8_to_euc_E591, utf8_to_euc_E592, utf8_to_euc_E593, - utf8_to_euc_E594, utf8_to_euc_E595, utf8_to_euc_E596, utf8_to_euc_E597, - utf8_to_euc_E598, utf8_to_euc_E599, utf8_to_euc_E59A, utf8_to_euc_E59B, - utf8_to_euc_E59C, utf8_to_euc_E59D, utf8_to_euc_E59E, utf8_to_euc_E59F, - utf8_to_euc_E5A0, utf8_to_euc_E5A1, utf8_to_euc_E5A2, utf8_to_euc_E5A3, - utf8_to_euc_E5A4, utf8_to_euc_E5A5, utf8_to_euc_E5A6, utf8_to_euc_E5A7, - utf8_to_euc_E5A8, utf8_to_euc_E5A9, utf8_to_euc_E5AA, utf8_to_euc_E5AB, - utf8_to_euc_E5AC, utf8_to_euc_E5AD, utf8_to_euc_E5AE, utf8_to_euc_E5AF, - utf8_to_euc_E5B0, utf8_to_euc_E5B1, utf8_to_euc_E5B2, utf8_to_euc_E5B3, - utf8_to_euc_E5B4, utf8_to_euc_E5B5, utf8_to_euc_E5B6, utf8_to_euc_E5B7, - utf8_to_euc_E5B8, utf8_to_euc_E5B9, utf8_to_euc_E5BA, utf8_to_euc_E5BB, - utf8_to_euc_E5BC, utf8_to_euc_E5BD, utf8_to_euc_E5BE, utf8_to_euc_E5BF, -}; -static const unsigned short *const utf8_to_euc_E5_x0213[] = { - utf8_to_euc_E580_x0213, utf8_to_euc_E581_x0213, utf8_to_euc_E582_x0213, utf8_to_euc_E583_x0213, - utf8_to_euc_E584_x0213, utf8_to_euc_E585_x0213, utf8_to_euc_E586_x0213, utf8_to_euc_E587_x0213, - utf8_to_euc_E588_x0213, utf8_to_euc_E589_x0213, utf8_to_euc_E58A_x0213, utf8_to_euc_E58B_x0213, - utf8_to_euc_E58C_x0213, utf8_to_euc_E58D_x0213, utf8_to_euc_E58E_x0213, utf8_to_euc_E58F_x0213, - utf8_to_euc_E590_x0213, utf8_to_euc_E591_x0213, utf8_to_euc_E592_x0213, utf8_to_euc_E593_x0213, - utf8_to_euc_E594_x0213, utf8_to_euc_E595_x0213, utf8_to_euc_E596_x0213, utf8_to_euc_E597_x0213, - utf8_to_euc_E598_x0213, utf8_to_euc_E599_x0213, utf8_to_euc_E59A_x0213, utf8_to_euc_E59B_x0213, - utf8_to_euc_E59C_x0213, utf8_to_euc_E59D_x0213, utf8_to_euc_E59E_x0213, utf8_to_euc_E59F_x0213, - utf8_to_euc_E5A0_x0213, utf8_to_euc_E5A1_x0213, utf8_to_euc_E5A2_x0213, utf8_to_euc_E5A3_x0213, - utf8_to_euc_E5A4_x0213, utf8_to_euc_E5A5_x0213, utf8_to_euc_E5A6_x0213, utf8_to_euc_E5A7_x0213, - utf8_to_euc_E5A8_x0213, utf8_to_euc_E5A9_x0213, utf8_to_euc_E5AA_x0213, utf8_to_euc_E5AB_x0213, - utf8_to_euc_E5AC_x0213, utf8_to_euc_E5AD_x0213, utf8_to_euc_E5AE_x0213, utf8_to_euc_E5AF_x0213, - utf8_to_euc_E5B0_x0213, utf8_to_euc_E5B1_x0213, utf8_to_euc_E5B2_x0213, utf8_to_euc_E5B3_x0213, - utf8_to_euc_E5B4_x0213, utf8_to_euc_E5B5_x0213, utf8_to_euc_E5B6_x0213, utf8_to_euc_E5B7_x0213, - utf8_to_euc_E5B8_x0213, utf8_to_euc_E5B9_x0213, utf8_to_euc_E5BA_x0213, utf8_to_euc_E5BB_x0213, - utf8_to_euc_E5BC_x0213, utf8_to_euc_E5BD_x0213, utf8_to_euc_E5BE_x0213, utf8_to_euc_E5BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E6[] = { - utf8_to_euc_E680, utf8_to_euc_E681, utf8_to_euc_E682, utf8_to_euc_E683, - utf8_to_euc_E684, utf8_to_euc_E685, utf8_to_euc_E686, utf8_to_euc_E687, - utf8_to_euc_E688, utf8_to_euc_E689, utf8_to_euc_E68A, utf8_to_euc_E68B, - utf8_to_euc_E68C, utf8_to_euc_E68D, utf8_to_euc_E68E, utf8_to_euc_E68F, - utf8_to_euc_E690, utf8_to_euc_E691, utf8_to_euc_E692, utf8_to_euc_E693, - utf8_to_euc_E694, utf8_to_euc_E695, utf8_to_euc_E696, utf8_to_euc_E697, - utf8_to_euc_E698, utf8_to_euc_E699, utf8_to_euc_E69A, utf8_to_euc_E69B, - utf8_to_euc_E69C, utf8_to_euc_E69D, utf8_to_euc_E69E, utf8_to_euc_E69F, - utf8_to_euc_E6A0, utf8_to_euc_E6A1, utf8_to_euc_E6A2, utf8_to_euc_E6A3, - utf8_to_euc_E6A4, utf8_to_euc_E6A5, utf8_to_euc_E6A6, utf8_to_euc_E6A7, - utf8_to_euc_E6A8, utf8_to_euc_E6A9, utf8_to_euc_E6AA, utf8_to_euc_E6AB, - utf8_to_euc_E6AC, utf8_to_euc_E6AD, utf8_to_euc_E6AE, utf8_to_euc_E6AF, - utf8_to_euc_E6B0, utf8_to_euc_E6B1, utf8_to_euc_E6B2, utf8_to_euc_E6B3, - utf8_to_euc_E6B4, utf8_to_euc_E6B5, utf8_to_euc_E6B6, utf8_to_euc_E6B7, - utf8_to_euc_E6B8, utf8_to_euc_E6B9, utf8_to_euc_E6BA, utf8_to_euc_E6BB, - utf8_to_euc_E6BC, utf8_to_euc_E6BD, utf8_to_euc_E6BE, utf8_to_euc_E6BF, -}; -static const unsigned short *const utf8_to_euc_E6_x0213[] = { - utf8_to_euc_E680_x0213, utf8_to_euc_E681_x0213, utf8_to_euc_E682_x0213, utf8_to_euc_E683_x0213, - utf8_to_euc_E684_x0213, utf8_to_euc_E685_x0213, utf8_to_euc_E686_x0213, utf8_to_euc_E687_x0213, - utf8_to_euc_E688_x0213, utf8_to_euc_E689_x0213, utf8_to_euc_E68A_x0213, utf8_to_euc_E68B_x0213, - utf8_to_euc_E68C_x0213, utf8_to_euc_E68D_x0213, utf8_to_euc_E68E_x0213, utf8_to_euc_E68F_x0213, - utf8_to_euc_E690_x0213, utf8_to_euc_E691_x0213, utf8_to_euc_E692_x0213, utf8_to_euc_E693_x0213, - utf8_to_euc_E694_x0213, utf8_to_euc_E695_x0213, utf8_to_euc_E696_x0213, utf8_to_euc_E697_x0213, - utf8_to_euc_E698_x0213, utf8_to_euc_E699_x0213, utf8_to_euc_E69A_x0213, utf8_to_euc_E69B_x0213, - utf8_to_euc_E69C_x0213, utf8_to_euc_E69D_x0213, utf8_to_euc_E69E_x0213, utf8_to_euc_E69F_x0213, - utf8_to_euc_E6A0_x0213, utf8_to_euc_E6A1_x0213, utf8_to_euc_E6A2_x0213, utf8_to_euc_E6A3_x0213, - utf8_to_euc_E6A4_x0213, utf8_to_euc_E6A5_x0213, utf8_to_euc_E6A6_x0213, utf8_to_euc_E6A7_x0213, - utf8_to_euc_E6A8_x0213, utf8_to_euc_E6A9_x0213, utf8_to_euc_E6AA_x0213, utf8_to_euc_E6AB_x0213, - utf8_to_euc_E6AC_x0213, utf8_to_euc_E6AD_x0213, utf8_to_euc_E6AE_x0213, utf8_to_euc_E6AF_x0213, - utf8_to_euc_E6B0_x0213, utf8_to_euc_E6B1_x0213, utf8_to_euc_E6B2_x0213, utf8_to_euc_E6B3_x0213, - utf8_to_euc_E6B4_x0213, utf8_to_euc_E6B5_x0213, utf8_to_euc_E6B6_x0213, utf8_to_euc_E6B7_x0213, - utf8_to_euc_E6B8_x0213, utf8_to_euc_E6B9_x0213, utf8_to_euc_E6BA_x0213, utf8_to_euc_E6BB_x0213, - utf8_to_euc_E6BC_x0213, utf8_to_euc_E6BD_x0213, utf8_to_euc_E6BE_x0213, utf8_to_euc_E6BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E7[] = { - utf8_to_euc_E780, utf8_to_euc_E781, utf8_to_euc_E782, utf8_to_euc_E783, - utf8_to_euc_E784, utf8_to_euc_E785, utf8_to_euc_E786, utf8_to_euc_E787, - utf8_to_euc_E788, utf8_to_euc_E789, utf8_to_euc_E78A, utf8_to_euc_E78B, - utf8_to_euc_E78C, utf8_to_euc_E78D, utf8_to_euc_E78E, utf8_to_euc_E78F, - utf8_to_euc_E790, utf8_to_euc_E791, utf8_to_euc_E792, utf8_to_euc_E793, - utf8_to_euc_E794, utf8_to_euc_E795, utf8_to_euc_E796, utf8_to_euc_E797, - utf8_to_euc_E798, utf8_to_euc_E799, utf8_to_euc_E79A, utf8_to_euc_E79B, - utf8_to_euc_E79C, utf8_to_euc_E79D, utf8_to_euc_E79E, utf8_to_euc_E79F, - utf8_to_euc_E7A0, utf8_to_euc_E7A1, utf8_to_euc_E7A2, utf8_to_euc_E7A3, - utf8_to_euc_E7A4, utf8_to_euc_E7A5, utf8_to_euc_E7A6, utf8_to_euc_E7A7, - utf8_to_euc_E7A8, utf8_to_euc_E7A9, utf8_to_euc_E7AA, utf8_to_euc_E7AB, - utf8_to_euc_E7AC, utf8_to_euc_E7AD, utf8_to_euc_E7AE, utf8_to_euc_E7AF, - utf8_to_euc_E7B0, utf8_to_euc_E7B1, utf8_to_euc_E7B2, utf8_to_euc_E7B3, - utf8_to_euc_E7B4, utf8_to_euc_E7B5, utf8_to_euc_E7B6, utf8_to_euc_E7B7, - utf8_to_euc_E7B8, utf8_to_euc_E7B9, utf8_to_euc_E7BA, 0, - utf8_to_euc_E7BC, utf8_to_euc_E7BD, utf8_to_euc_E7BE, utf8_to_euc_E7BF, -}; -static const unsigned short *const utf8_to_euc_E7_x0213[] = { - utf8_to_euc_E780_x0213, utf8_to_euc_E781_x0213, utf8_to_euc_E782_x0213, utf8_to_euc_E783_x0213, - utf8_to_euc_E784_x0213, utf8_to_euc_E785_x0213, utf8_to_euc_E786_x0213, utf8_to_euc_E787_x0213, - utf8_to_euc_E788_x0213, utf8_to_euc_E789_x0213, utf8_to_euc_E78A_x0213, utf8_to_euc_E78B_x0213, - utf8_to_euc_E78C_x0213, utf8_to_euc_E78D_x0213, utf8_to_euc_E78E_x0213, utf8_to_euc_E78F_x0213, - utf8_to_euc_E790_x0213, utf8_to_euc_E791_x0213, utf8_to_euc_E792_x0213, utf8_to_euc_E793_x0213, - utf8_to_euc_E794_x0213, utf8_to_euc_E795_x0213, utf8_to_euc_E796_x0213, utf8_to_euc_E797_x0213, - utf8_to_euc_E798_x0213, utf8_to_euc_E799_x0213, utf8_to_euc_E79A_x0213, utf8_to_euc_E79B_x0213, - utf8_to_euc_E79C_x0213, utf8_to_euc_E79D_x0213, utf8_to_euc_E79E_x0213, utf8_to_euc_E79F_x0213, - utf8_to_euc_E7A0_x0213, utf8_to_euc_E7A1_x0213, utf8_to_euc_E7A2_x0213, utf8_to_euc_E7A3_x0213, - utf8_to_euc_E7A4_x0213, utf8_to_euc_E7A5_x0213, utf8_to_euc_E7A6_x0213, utf8_to_euc_E7A7_x0213, - utf8_to_euc_E7A8_x0213, utf8_to_euc_E7A9_x0213, utf8_to_euc_E7AA_x0213, utf8_to_euc_E7AB_x0213, - utf8_to_euc_E7AC_x0213, utf8_to_euc_E7AD_x0213, utf8_to_euc_E7AE_x0213, utf8_to_euc_E7AF_x0213, - utf8_to_euc_E7B0_x0213, utf8_to_euc_E7B1_x0213, utf8_to_euc_E7B2_x0213, utf8_to_euc_E7B3_x0213, - utf8_to_euc_E7B4_x0213, utf8_to_euc_E7B5_x0213, utf8_to_euc_E7B6_x0213, utf8_to_euc_E7B7_x0213, - utf8_to_euc_E7B8_x0213, utf8_to_euc_E7B9_x0213, utf8_to_euc_E7BA_x0213, 0, - utf8_to_euc_E7BC_x0213, utf8_to_euc_E7BD_x0213, utf8_to_euc_E7BE_x0213, utf8_to_euc_E7BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E8[] = { - utf8_to_euc_E880, utf8_to_euc_E881, utf8_to_euc_E882, utf8_to_euc_E883, - utf8_to_euc_E884, utf8_to_euc_E885, utf8_to_euc_E886, utf8_to_euc_E887, - utf8_to_euc_E888, utf8_to_euc_E889, utf8_to_euc_E88A, utf8_to_euc_E88B, - utf8_to_euc_E88C, utf8_to_euc_E88D, utf8_to_euc_E88E, utf8_to_euc_E88F, - utf8_to_euc_E890, utf8_to_euc_E891, utf8_to_euc_E892, utf8_to_euc_E893, - utf8_to_euc_E894, utf8_to_euc_E895, utf8_to_euc_E896, utf8_to_euc_E897, - utf8_to_euc_E898, utf8_to_euc_E899, utf8_to_euc_E89A, utf8_to_euc_E89B, - utf8_to_euc_E89C, utf8_to_euc_E89D, utf8_to_euc_E89E, utf8_to_euc_E89F, - utf8_to_euc_E8A0, utf8_to_euc_E8A1, utf8_to_euc_E8A2, utf8_to_euc_E8A3, - utf8_to_euc_E8A4, utf8_to_euc_E8A5, utf8_to_euc_E8A6, utf8_to_euc_E8A7, - utf8_to_euc_E8A8, utf8_to_euc_E8A9, utf8_to_euc_E8AA, utf8_to_euc_E8AB, - utf8_to_euc_E8AC, utf8_to_euc_E8AD, utf8_to_euc_E8AE, 0, - utf8_to_euc_E8B0, utf8_to_euc_E8B1, utf8_to_euc_E8B2, utf8_to_euc_E8B3, - utf8_to_euc_E8B4, utf8_to_euc_E8B5, utf8_to_euc_E8B6, utf8_to_euc_E8B7, - utf8_to_euc_E8B8, utf8_to_euc_E8B9, utf8_to_euc_E8BA, utf8_to_euc_E8BB, - utf8_to_euc_E8BC, utf8_to_euc_E8BD, utf8_to_euc_E8BE, utf8_to_euc_E8BF, -}; -static const unsigned short *const utf8_to_euc_E8_x0213[] = { - utf8_to_euc_E880_x0213, utf8_to_euc_E881_x0213, utf8_to_euc_E882_x0213, utf8_to_euc_E883_x0213, - utf8_to_euc_E884_x0213, utf8_to_euc_E885_x0213, utf8_to_euc_E886_x0213, utf8_to_euc_E887_x0213, - utf8_to_euc_E888_x0213, utf8_to_euc_E889_x0213, utf8_to_euc_E88A_x0213, utf8_to_euc_E88B_x0213, - utf8_to_euc_E88C_x0213, utf8_to_euc_E88D_x0213, utf8_to_euc_E88E_x0213, utf8_to_euc_E88F_x0213, - utf8_to_euc_E890_x0213, utf8_to_euc_E891_x0213, utf8_to_euc_E892_x0213, utf8_to_euc_E893_x0213, - utf8_to_euc_E894_x0213, utf8_to_euc_E895_x0213, utf8_to_euc_E896_x0213, utf8_to_euc_E897_x0213, - utf8_to_euc_E898_x0213, utf8_to_euc_E899_x0213, utf8_to_euc_E89A_x0213, utf8_to_euc_E89B_x0213, - utf8_to_euc_E89C_x0213, utf8_to_euc_E89D_x0213, utf8_to_euc_E89E_x0213, utf8_to_euc_E89F_x0213, - utf8_to_euc_E8A0_x0213, utf8_to_euc_E8A1_x0213, utf8_to_euc_E8A2_x0213, utf8_to_euc_E8A3_x0213, - utf8_to_euc_E8A4_x0213, utf8_to_euc_E8A5_x0213, utf8_to_euc_E8A6_x0213, utf8_to_euc_E8A7_x0213, - utf8_to_euc_E8A8_x0213, utf8_to_euc_E8A9_x0213, utf8_to_euc_E8AA_x0213, utf8_to_euc_E8AB_x0213, - utf8_to_euc_E8AC_x0213, utf8_to_euc_E8AD_x0213, utf8_to_euc_E8AE_x0213, 0, - utf8_to_euc_E8B0_x0213, utf8_to_euc_E8B1_x0213, utf8_to_euc_E8B2_x0213, utf8_to_euc_E8B3_x0213, - utf8_to_euc_E8B4_x0213, utf8_to_euc_E8B5_x0213, utf8_to_euc_E8B6_x0213, utf8_to_euc_E8B7_x0213, - utf8_to_euc_E8B8_x0213, utf8_to_euc_E8B9_x0213, utf8_to_euc_E8BA_x0213, utf8_to_euc_E8BB_x0213, - utf8_to_euc_E8BC_x0213, utf8_to_euc_E8BD_x0213, utf8_to_euc_E8BE_x0213, utf8_to_euc_E8BF_x0213, -}; -static const unsigned short *const utf8_to_euc_E9[] = { - utf8_to_euc_E980, utf8_to_euc_E981, utf8_to_euc_E982, utf8_to_euc_E983, - utf8_to_euc_E984, utf8_to_euc_E985, utf8_to_euc_E986, utf8_to_euc_E987, - utf8_to_euc_E988, utf8_to_euc_E989, utf8_to_euc_E98A, utf8_to_euc_E98B, - utf8_to_euc_E98C, utf8_to_euc_E98D, utf8_to_euc_E98E, utf8_to_euc_E98F, - utf8_to_euc_E990, utf8_to_euc_E991, utf8_to_euc_E992, 0, - 0, utf8_to_euc_E995, utf8_to_euc_E996, utf8_to_euc_E997, - utf8_to_euc_E998, utf8_to_euc_E999, utf8_to_euc_E99A, utf8_to_euc_E99B, - utf8_to_euc_E99C, utf8_to_euc_E99D, utf8_to_euc_E99E, utf8_to_euc_E99F, - utf8_to_euc_E9A0, utf8_to_euc_E9A1, utf8_to_euc_E9A2, utf8_to_euc_E9A3, - utf8_to_euc_E9A4, utf8_to_euc_E9A5, utf8_to_euc_E9A6, utf8_to_euc_E9A7, - utf8_to_euc_E9A8, utf8_to_euc_E9A9, utf8_to_euc_E9AA, utf8_to_euc_E9AB, - utf8_to_euc_E9AC, utf8_to_euc_E9AD, utf8_to_euc_E9AE, utf8_to_euc_E9AF, - utf8_to_euc_E9B0, utf8_to_euc_E9B1, 0, utf8_to_euc_E9B3, - utf8_to_euc_E9B4, utf8_to_euc_E9B5, utf8_to_euc_E9B6, utf8_to_euc_E9B7, - utf8_to_euc_E9B8, utf8_to_euc_E9B9, utf8_to_euc_E9BA, utf8_to_euc_E9BB, - utf8_to_euc_E9BC, utf8_to_euc_E9BD, utf8_to_euc_E9BE, 0, -}; -static const unsigned short *const utf8_to_euc_E9_x0213[] = { - utf8_to_euc_E980_x0213, utf8_to_euc_E981_x0213, utf8_to_euc_E982_x0213, utf8_to_euc_E983_x0213, - utf8_to_euc_E984_x0213, utf8_to_euc_E985_x0213, utf8_to_euc_E986_x0213, utf8_to_euc_E987_x0213, - utf8_to_euc_E988_x0213, utf8_to_euc_E989_x0213, utf8_to_euc_E98A_x0213, utf8_to_euc_E98B_x0213, - utf8_to_euc_E98C_x0213, utf8_to_euc_E98D_x0213, utf8_to_euc_E98E_x0213, utf8_to_euc_E98F_x0213, - utf8_to_euc_E990_x0213, utf8_to_euc_E991_x0213, utf8_to_euc_E992, 0, - 0, utf8_to_euc_E995_x0213, utf8_to_euc_E996_x0213, utf8_to_euc_E997_x0213, - utf8_to_euc_E998_x0213, utf8_to_euc_E999_x0213, utf8_to_euc_E99A_x0213, utf8_to_euc_E99B_x0213, - utf8_to_euc_E99C_x0213, utf8_to_euc_E99D_x0213, utf8_to_euc_E99E_x0213, utf8_to_euc_E99F_x0213, - utf8_to_euc_E9A0_x0213, utf8_to_euc_E9A1_x0213, utf8_to_euc_E9A2_x0213, utf8_to_euc_E9A3_x0213, - utf8_to_euc_E9A4_x0213, utf8_to_euc_E9A5_x0213, utf8_to_euc_E9A6_x0213, utf8_to_euc_E9A7_x0213, - utf8_to_euc_E9A8_x0213, utf8_to_euc_E9A9_x0213, utf8_to_euc_E9AA_x0213, utf8_to_euc_E9AB_x0213, - utf8_to_euc_E9AC_x0213, utf8_to_euc_E9AD_x0213, utf8_to_euc_E9AE_x0213, utf8_to_euc_E9AF_x0213, - utf8_to_euc_E9B0_x0213, utf8_to_euc_E9B1_x0213, 0, utf8_to_euc_E9B3_x0213, - utf8_to_euc_E9B4_x0213, utf8_to_euc_E9B5_x0213, utf8_to_euc_E9B6_x0213, utf8_to_euc_E9B7_x0213, - utf8_to_euc_E9B8_x0213, utf8_to_euc_E9B9_x0213, utf8_to_euc_E9BA_x0213, utf8_to_euc_E9BB_x0213, - utf8_to_euc_E9BC_x0213, utf8_to_euc_E9BD_x0213, utf8_to_euc_E9BE_x0213, 0, -}; -static const unsigned short *const utf8_to_euc_EF[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_EFA4, 0, 0, utf8_to_euc_EFA7, - utf8_to_euc_EFA8, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_EFBC, utf8_to_euc_EFBD, utf8_to_euc_EFBE, utf8_to_euc_EFBF, -}; -static const unsigned short *const utf8_to_euc_EF_ms[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_EFA4, 0, 0, utf8_to_euc_EFA7, - utf8_to_euc_EFA8, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_EFBC, utf8_to_euc_EFBD_ms, utf8_to_euc_EFBE, utf8_to_euc_EFBF, -}; -static const unsigned short *const utf8_to_euc_EF_x0213[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - utf8_to_euc_EFA4_x0213, utf8_to_euc_EFA5_x0213, 0, utf8_to_euc_EFA7_x0213, - utf8_to_euc_EFA8_x0213, utf8_to_euc_EFA9_x0213, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, utf8_to_euc_EFB9_x0213, 0, 0, - utf8_to_euc_EFBC_x0213, utf8_to_euc_EFBD_x0213, utf8_to_euc_EFBE, utf8_to_euc_EFBF_x0213, -}; -const unsigned short *const utf8_to_euc_2bytes[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, utf8_to_euc_C2, utf8_to_euc_C3, - utf8_to_euc_C4, utf8_to_euc_C5, 0, utf8_to_euc_C7, - 0, 0, 0, utf8_to_euc_CB, - 0, 0, utf8_to_euc_CE, utf8_to_euc_CF, - utf8_to_euc_D0, utf8_to_euc_D1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -const unsigned short *const utf8_to_euc_2bytes_ms[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, utf8_to_euc_C2_ms, utf8_to_euc_C3, - utf8_to_euc_C4, utf8_to_euc_C5, 0, utf8_to_euc_C7, - 0, 0, 0, utf8_to_euc_CB, - 0, 0, utf8_to_euc_CE, utf8_to_euc_CF, - utf8_to_euc_D0, utf8_to_euc_D1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -const unsigned short *const utf8_to_euc_2bytes_932[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, utf8_to_euc_C2_932, utf8_to_euc_C3_932, - utf8_to_euc_C4, utf8_to_euc_C5, 0, utf8_to_euc_C7, - 0, 0, 0, utf8_to_euc_CB, - 0, 0, utf8_to_euc_CE, utf8_to_euc_CF, - utf8_to_euc_D0, utf8_to_euc_D1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -const unsigned short *const utf8_to_euc_2bytes_mac[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, utf8_to_euc_C2_mac, utf8_to_euc_C3, - utf8_to_euc_C4, utf8_to_euc_C5, 0, utf8_to_euc_C7, - 0, 0, 0, utf8_to_euc_CB, - 0, 0, utf8_to_euc_CE, utf8_to_euc_CF, - utf8_to_euc_D0, utf8_to_euc_D1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -const unsigned short *const utf8_to_euc_2bytes_x0213[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, utf8_to_euc_C2_x0213, utf8_to_euc_C3_x0213, - utf8_to_euc_C4_x0213, utf8_to_euc_C5_x0213, utf8_to_euc_C6_x0213, utf8_to_euc_C7_x0213, - 0, utf8_to_euc_C9_x0213, utf8_to_euc_CA_x0213, utf8_to_euc_CB_x0213, - utf8_to_euc_CC_x0213, utf8_to_euc_CD_x0213, utf8_to_euc_CE, utf8_to_euc_CF_x0213, - utf8_to_euc_D0, utf8_to_euc_D1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -const unsigned short *const *const utf8_to_euc_3bytes[] = { - 0, 0, utf8_to_euc_E2, utf8_to_euc_E3, - utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7, - utf8_to_euc_E8, utf8_to_euc_E9, 0, 0, - 0, 0, 0, utf8_to_euc_EF, -}; -const unsigned short *const *const utf8_to_euc_3bytes_ms[] = { - 0, 0, utf8_to_euc_E2_ms, utf8_to_euc_E3, - utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7, - utf8_to_euc_E8, utf8_to_euc_E9, 0, 0, - 0, 0, 0, utf8_to_euc_EF_ms, -}; -const unsigned short *const *const utf8_to_euc_3bytes_932[] = { - 0, 0, utf8_to_euc_E2_932, utf8_to_euc_E3_932, - utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7, - utf8_to_euc_E8, utf8_to_euc_E9, 0, 0, - 0, 0, 0, utf8_to_euc_EF_ms, -}; -const unsigned short *const *const utf8_to_euc_3bytes_mac[] = { - 0, 0, utf8_to_euc_E2_mac, utf8_to_euc_E3_mac, - utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7, - utf8_to_euc_E8, utf8_to_euc_E9, 0, 0, - 0, 0, 0, utf8_to_euc_EF_ms, -}; -const unsigned short *const *const utf8_to_euc_3bytes_x0213[] = { - 0, utf8_to_euc_E1_x0213, utf8_to_euc_E2_x0213, utf8_to_euc_E3_x0213, - utf8_to_euc_E4_x0213, utf8_to_euc_E5_x0213, utf8_to_euc_E6_x0213, utf8_to_euc_E7_x0213, - utf8_to_euc_E8_x0213, utf8_to_euc_E9_x0213, 0, 0, - 0, 0, 0, utf8_to_euc_EF_x0213, -}; - -#ifdef UNICODE_NORMALIZATION - -/* Normalization Table by Apple */ -/* http://developer.apple.com/technotes/tn/tn1150table.html */ - -const struct normalization_pair normalization_table[] = { - {{0xcd,0xbe}, {0x3b}}, - {{0xc3,0x80}, {0x41,0xcc,0x80,0x00}}, - {{0xc3,0x81}, {0x41,0xcc,0x81}}, - {{0xc3,0x82}, {0x41,0xcc,0x82}}, - {{0xe1,0xba,0xa6}, {0x41,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xba,0xa4}, {0x41,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xba,0xaa}, {0x41,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xba,0xa8}, {0x41,0xcc,0x82,0xcc,0x89}}, - {{0xc3,0x83}, {0x41,0xcc,0x83}}, - {{0xc4,0x80}, {0x41,0xcc,0x84}}, - {{0xc4,0x82}, {0x41,0xcc,0x86}}, - {{0xe1,0xba,0xb0}, {0x41,0xcc,0x86,0xcc,0x80}}, - {{0xe1,0xba,0xae}, {0x41,0xcc,0x86,0xcc,0x81}}, - {{0xe1,0xba,0xb4}, {0x41,0xcc,0x86,0xcc,0x83}}, - {{0xe1,0xba,0xb2}, {0x41,0xcc,0x86,0xcc,0x89}}, - {{0xc7,0xa0}, {0x41,0xcc,0x87,0xcc,0x84}}, - {{0xc3,0x84}, {0x41,0xcc,0x88}}, - {{0xc7,0x9e}, {0x41,0xcc,0x88,0xcc,0x84}}, - {{0xe1,0xba,0xa2}, {0x41,0xcc,0x89}}, - {{0xc3,0x85}, {0x41,0xcc,0x8a}}, - {{0xc7,0xba}, {0x41,0xcc,0x8a,0xcc,0x81}}, - {{0xc7,0x8d}, {0x41,0xcc,0x8c}}, - {{0xc8,0x80}, {0x41,0xcc,0x8f}}, - {{0xc8,0x82}, {0x41,0xcc,0x91}}, - {{0xe1,0xba,0xa0}, {0x41,0xcc,0xa3}}, - {{0xe1,0xba,0xac}, {0x41,0xcc,0xa3,0xcc,0x82}}, - {{0xe1,0xba,0xb6}, {0x41,0xcc,0xa3,0xcc,0x86}}, - {{0xe1,0xb8,0x80}, {0x41,0xcc,0xa5}}, - {{0xc4,0x84}, {0x41,0xcc,0xa8}}, - {{0xe1,0xb8,0x82}, {0x42,0xcc,0x87}}, - {{0xe1,0xb8,0x84}, {0x42,0xcc,0xa3}}, - {{0xe1,0xb8,0x86}, {0x42,0xcc,0xb1}}, - {{0xc4,0x86}, {0x43,0xcc,0x81}}, - {{0xc4,0x88}, {0x43,0xcc,0x82}}, - {{0xc4,0x8a}, {0x43,0xcc,0x87}}, - {{0xc4,0x8c}, {0x43,0xcc,0x8c}}, - {{0xc3,0x87}, {0x43,0xcc,0xa7}}, - {{0xe1,0xb8,0x88}, {0x43,0xcc,0xa7,0xcc,0x81}}, - {{0xe1,0xb8,0x8a}, {0x44,0xcc,0x87}}, - {{0xc4,0x8e}, {0x44,0xcc,0x8c}}, - {{0xe1,0xb8,0x8c}, {0x44,0xcc,0xa3}}, - {{0xe1,0xb8,0x90}, {0x44,0xcc,0xa7}}, - {{0xe1,0xb8,0x92}, {0x44,0xcc,0xad}}, - {{0xe1,0xb8,0x8e}, {0x44,0xcc,0xb1}}, - {{0xc3,0x88}, {0x45,0xcc,0x80}}, - {{0xc3,0x89}, {0x45,0xcc,0x81}}, - {{0xc3,0x8a}, {0x45,0xcc,0x82}}, - {{0xe1,0xbb,0x80}, {0x45,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xba,0xbe}, {0x45,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xbb,0x84}, {0x45,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xbb,0x82}, {0x45,0xcc,0x82,0xcc,0x89}}, - {{0xe1,0xba,0xbc}, {0x45,0xcc,0x83}}, - {{0xc4,0x92}, {0x45,0xcc,0x84}}, - {{0xe1,0xb8,0x94}, {0x45,0xcc,0x84,0xcc,0x80}}, - {{0xe1,0xb8,0x96}, {0x45,0xcc,0x84,0xcc,0x81}}, - {{0xc4,0x94}, {0x45,0xcc,0x86}}, - {{0xc4,0x96}, {0x45,0xcc,0x87}}, - {{0xc3,0x8b}, {0x45,0xcc,0x88}}, - {{0xe1,0xba,0xba}, {0x45,0xcc,0x89}}, - {{0xc4,0x9a}, {0x45,0xcc,0x8c}}, - {{0xc8,0x84}, {0x45,0xcc,0x8f}}, - {{0xc8,0x86}, {0x45,0xcc,0x91}}, - {{0xe1,0xba,0xb8}, {0x45,0xcc,0xa3}}, - {{0xe1,0xbb,0x86}, {0x45,0xcc,0xa3,0xcc,0x82}}, - {{0xe1,0xb8,0x9c}, {0x45,0xcc,0xa7,0xcc,0x86}}, - {{0xc4,0x98}, {0x45,0xcc,0xa8}}, - {{0xe1,0xb8,0x98}, {0x45,0xcc,0xad}}, - {{0xe1,0xb8,0x9a}, {0x45,0xcc,0xb0}}, - {{0xe1,0xb8,0x9e}, {0x46,0xcc,0x87}}, - {{0xc7,0xb4}, {0x47,0xcc,0x81}}, - {{0xc4,0x9c}, {0x47,0xcc,0x82}}, - {{0xe1,0xb8,0xa0}, {0x47,0xcc,0x84}}, - {{0xc4,0x9e}, {0x47,0xcc,0x86}}, - {{0xc4,0xa0}, {0x47,0xcc,0x87}}, - {{0xc7,0xa6}, {0x47,0xcc,0x8c}}, - {{0xc4,0xa2}, {0x47,0xcc,0xa7}}, - {{0xc4,0xa4}, {0x48,0xcc,0x82}}, - {{0xe1,0xb8,0xa2}, {0x48,0xcc,0x87}}, - {{0xe1,0xb8,0xa6}, {0x48,0xcc,0x88}}, - {{0xe1,0xb8,0xa4}, {0x48,0xcc,0xa3}}, - {{0xe1,0xb8,0xa8}, {0x48,0xcc,0xa7}}, - {{0xe1,0xb8,0xaa}, {0x48,0xcc,0xae}}, - {{0xc3,0x8c}, {0x49,0xcc,0x80}}, - {{0xc3,0x8d}, {0x49,0xcc,0x81}}, - {{0xc3,0x8e}, {0x49,0xcc,0x82}}, - {{0xc4,0xa8}, {0x49,0xcc,0x83}}, - {{0xc4,0xaa}, {0x49,0xcc,0x84}}, - {{0xc4,0xac}, {0x49,0xcc,0x86}}, - {{0xc4,0xb0}, {0x49,0xcc,0x87}}, - {{0xc3,0x8f}, {0x49,0xcc,0x88}}, - {{0xe1,0xb8,0xae}, {0x49,0xcc,0x88,0xcc,0x81}}, - {{0xe1,0xbb,0x88}, {0x49,0xcc,0x89}}, - {{0xc7,0x8f}, {0x49,0xcc,0x8c}}, - {{0xc8,0x88}, {0x49,0xcc,0x8f}}, - {{0xc8,0x8a}, {0x49,0xcc,0x91}}, - {{0xe1,0xbb,0x8a}, {0x49,0xcc,0xa3}}, - {{0xc4,0xae}, {0x49,0xcc,0xa8}}, - {{0xe1,0xb8,0xac}, {0x49,0xcc,0xb0}}, - {{0xc4,0xb4}, {0x4a,0xcc,0x82}}, - {{0xe1,0xb8,0xb0}, {0x4b,0xcc,0x81}}, - {{0xc7,0xa8}, {0x4b,0xcc,0x8c}}, - {{0xe1,0xb8,0xb2}, {0x4b,0xcc,0xa3}}, - {{0xc4,0xb6}, {0x4b,0xcc,0xa7}}, - {{0xe1,0xb8,0xb4}, {0x4b,0xcc,0xb1}}, - {{0xc4,0xb9}, {0x4c,0xcc,0x81}}, - {{0xc4,0xbd}, {0x4c,0xcc,0x8c}}, - {{0xe1,0xb8,0xb6}, {0x4c,0xcc,0xa3}}, - {{0xe1,0xb8,0xb8}, {0x4c,0xcc,0xa3,0xcc,0x84}}, - {{0xc4,0xbb}, {0x4c,0xcc,0xa7}}, - {{0xe1,0xb8,0xbc}, {0x4c,0xcc,0xad}}, - {{0xe1,0xb8,0xba}, {0x4c,0xcc,0xb1}}, - {{0xe1,0xb8,0xbe}, {0x4d,0xcc,0x81}}, - {{0xe1,0xb9,0x80}, {0x4d,0xcc,0x87}}, - {{0xe1,0xb9,0x82}, {0x4d,0xcc,0xa3}}, - {{0xc5,0x83}, {0x4e,0xcc,0x81}}, - {{0xc3,0x91}, {0x4e,0xcc,0x83}}, - {{0xe1,0xb9,0x84}, {0x4e,0xcc,0x87}}, - {{0xc5,0x87}, {0x4e,0xcc,0x8c}}, - {{0xe1,0xb9,0x86}, {0x4e,0xcc,0xa3}}, - {{0xc5,0x85}, {0x4e,0xcc,0xa7}}, - {{0xe1,0xb9,0x8a}, {0x4e,0xcc,0xad}}, - {{0xe1,0xb9,0x88}, {0x4e,0xcc,0xb1}}, - {{0xc3,0x92}, {0x4f,0xcc,0x80}}, - {{0xc3,0x93}, {0x4f,0xcc,0x81}}, - {{0xc3,0x94}, {0x4f,0xcc,0x82}}, - {{0xe1,0xbb,0x92}, {0x4f,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xbb,0x90}, {0x4f,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xbb,0x96}, {0x4f,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xbb,0x94}, {0x4f,0xcc,0x82,0xcc,0x89}}, - {{0xc3,0x95}, {0x4f,0xcc,0x83}}, - {{0xe1,0xb9,0x8c}, {0x4f,0xcc,0x83,0xcc,0x81}}, - {{0xe1,0xb9,0x8e}, {0x4f,0xcc,0x83,0xcc,0x88}}, - {{0xc5,0x8c}, {0x4f,0xcc,0x84}}, - {{0xe1,0xb9,0x90}, {0x4f,0xcc,0x84,0xcc,0x80}}, - {{0xe1,0xb9,0x92}, {0x4f,0xcc,0x84,0xcc,0x81}}, - {{0xc5,0x8e}, {0x4f,0xcc,0x86}}, - {{0xc3,0x96}, {0x4f,0xcc,0x88}}, - {{0xe1,0xbb,0x8e}, {0x4f,0xcc,0x89}}, - {{0xc5,0x90}, {0x4f,0xcc,0x8b}}, - {{0xc7,0x91}, {0x4f,0xcc,0x8c}}, - {{0xc8,0x8c}, {0x4f,0xcc,0x8f}}, - {{0xc8,0x8e}, {0x4f,0xcc,0x91}}, - {{0xc6,0xa0}, {0x4f,0xcc,0x9b}}, - {{0xe1,0xbb,0x9c}, {0x4f,0xcc,0x9b,0xcc,0x80}}, - {{0xe1,0xbb,0x9a}, {0x4f,0xcc,0x9b,0xcc,0x81}}, - {{0xe1,0xbb,0xa0}, {0x4f,0xcc,0x9b,0xcc,0x83}}, - {{0xe1,0xbb,0x9e}, {0x4f,0xcc,0x9b,0xcc,0x89}}, - {{0xe1,0xbb,0xa2}, {0x4f,0xcc,0x9b,0xcc,0xa3}}, - {{0xe1,0xbb,0x8c}, {0x4f,0xcc,0xa3}}, - {{0xe1,0xbb,0x98}, {0x4f,0xcc,0xa3,0xcc,0x82}}, - {{0xc7,0xaa}, {0x4f,0xcc,0xa8}}, - {{0xc7,0xac}, {0x4f,0xcc,0xa8,0xcc,0x84}}, - {{0xe1,0xb9,0x94}, {0x50,0xcc,0x81}}, - {{0xe1,0xb9,0x96}, {0x50,0xcc,0x87}}, - {{0xc5,0x94}, {0x52,0xcc,0x81}}, - {{0xe1,0xb9,0x98}, {0x52,0xcc,0x87}}, - {{0xc5,0x98}, {0x52,0xcc,0x8c}}, - {{0xc8,0x90}, {0x52,0xcc,0x8f}}, - {{0xc8,0x92}, {0x52,0xcc,0x91}}, - {{0xe1,0xb9,0x9a}, {0x52,0xcc,0xa3}}, - {{0xe1,0xb9,0x9c}, {0x52,0xcc,0xa3,0xcc,0x84}}, - {{0xc5,0x96}, {0x52,0xcc,0xa7}}, - {{0xe1,0xb9,0x9e}, {0x52,0xcc,0xb1}}, - {{0xc5,0x9a}, {0x53,0xcc,0x81}}, - {{0xe1,0xb9,0xa4}, {0x53,0xcc,0x81,0xcc,0x87}}, - {{0xc5,0x9c}, {0x53,0xcc,0x82}}, - {{0xe1,0xb9,0xa0}, {0x53,0xcc,0x87}}, - {{0xc5,0xa0}, {0x53,0xcc,0x8c}}, - {{0xe1,0xb9,0xa6}, {0x53,0xcc,0x8c,0xcc,0x87}}, - {{0xe1,0xb9,0xa2}, {0x53,0xcc,0xa3}}, - {{0xe1,0xb9,0xa8}, {0x53,0xcc,0xa3,0xcc,0x87}}, - {{0xc5,0x9e}, {0x53,0xcc,0xa7}}, - {{0xe1,0xb9,0xaa}, {0x54,0xcc,0x87}}, - {{0xc5,0xa4}, {0x54,0xcc,0x8c}}, - {{0xe1,0xb9,0xac}, {0x54,0xcc,0xa3}}, - {{0xc5,0xa2}, {0x54,0xcc,0xa7}}, - {{0xe1,0xb9,0xb0}, {0x54,0xcc,0xad}}, - {{0xe1,0xb9,0xae}, {0x54,0xcc,0xb1}}, - {{0xc3,0x99}, {0x55,0xcc,0x80}}, - {{0xc3,0x9a}, {0x55,0xcc,0x81}}, - {{0xc3,0x9b}, {0x55,0xcc,0x82}}, - {{0xc5,0xa8}, {0x55,0xcc,0x83}}, - {{0xe1,0xb9,0xb8}, {0x55,0xcc,0x83,0xcc,0x81}}, - {{0xc5,0xaa}, {0x55,0xcc,0x84}}, - {{0xe1,0xb9,0xba}, {0x55,0xcc,0x84,0xcc,0x88}}, - {{0xc5,0xac}, {0x55,0xcc,0x86}}, - {{0xc3,0x9c}, {0x55,0xcc,0x88}}, - {{0xc7,0x9b}, {0x55,0xcc,0x88,0xcc,0x80}}, - {{0xc7,0x97}, {0x55,0xcc,0x88,0xcc,0x81}}, - {{0xc7,0x95}, {0x55,0xcc,0x88,0xcc,0x84}}, - {{0xc7,0x99}, {0x55,0xcc,0x88,0xcc,0x8c}}, - {{0xe1,0xbb,0xa6}, {0x55,0xcc,0x89}}, - {{0xc5,0xae}, {0x55,0xcc,0x8a}}, - {{0xc5,0xb0}, {0x55,0xcc,0x8b}}, - {{0xc7,0x93}, {0x55,0xcc,0x8c}}, - {{0xc8,0x94}, {0x55,0xcc,0x8f}}, - {{0xc8,0x96}, {0x55,0xcc,0x91}}, - {{0xc6,0xaf}, {0x55,0xcc,0x9b}}, - {{0xe1,0xbb,0xaa}, {0x55,0xcc,0x9b,0xcc,0x80}}, - {{0xe1,0xbb,0xa8}, {0x55,0xcc,0x9b,0xcc,0x81}}, - {{0xe1,0xbb,0xae}, {0x55,0xcc,0x9b,0xcc,0x83}}, - {{0xe1,0xbb,0xac}, {0x55,0xcc,0x9b,0xcc,0x89}}, - {{0xe1,0xbb,0xb0}, {0x55,0xcc,0x9b,0xcc,0xa3}}, - {{0xe1,0xbb,0xa4}, {0x55,0xcc,0xa3}}, - {{0xe1,0xb9,0xb2}, {0x55,0xcc,0xa4}}, - {{0xc5,0xb2}, {0x55,0xcc,0xa8}}, - {{0xe1,0xb9,0xb6}, {0x55,0xcc,0xad}}, - {{0xe1,0xb9,0xb4}, {0x55,0xcc,0xb0}}, - {{0xe1,0xb9,0xbc}, {0x56,0xcc,0x83}}, - {{0xe1,0xb9,0xbe}, {0x56,0xcc,0xa3}}, - {{0xe1,0xba,0x80}, {0x57,0xcc,0x80}}, - {{0xe1,0xba,0x82}, {0x57,0xcc,0x81}}, - {{0xc5,0xb4}, {0x57,0xcc,0x82}}, - {{0xe1,0xba,0x86}, {0x57,0xcc,0x87}}, - {{0xe1,0xba,0x84}, {0x57,0xcc,0x88}}, - {{0xe1,0xba,0x88}, {0x57,0xcc,0xa3}}, - {{0xe1,0xba,0x8a}, {0x58,0xcc,0x87}}, - {{0xe1,0xba,0x8c}, {0x58,0xcc,0x88}}, - {{0xe1,0xbb,0xb2}, {0x59,0xcc,0x80}}, - {{0xc3,0x9d}, {0x59,0xcc,0x81}}, - {{0xc5,0xb6}, {0x59,0xcc,0x82}}, - {{0xe1,0xbb,0xb8}, {0x59,0xcc,0x83}}, - {{0xe1,0xba,0x8e}, {0x59,0xcc,0x87}}, - {{0xc5,0xb8}, {0x59,0xcc,0x88}}, - {{0xe1,0xbb,0xb6}, {0x59,0xcc,0x89}}, - {{0xe1,0xbb,0xb4}, {0x59,0xcc,0xa3}}, - {{0xc5,0xb9}, {0x5a,0xcc,0x81}}, - {{0xe1,0xba,0x90}, {0x5a,0xcc,0x82}}, - {{0xc5,0xbb}, {0x5a,0xcc,0x87}}, - {{0xc5,0xbd}, {0x5a,0xcc,0x8c}}, - {{0xe1,0xba,0x92}, {0x5a,0xcc,0xa3}}, - {{0xe1,0xba,0x94}, {0x5a,0xcc,0xb1}}, - {{0xe1,0xbf,0xaf}, {0x60}}, - {{0xc3,0xa0}, {0x61,0xcc,0x80}}, - {{0xc3,0xa1}, {0x61,0xcc,0x81}}, - {{0xc3,0xa2}, {0x61,0xcc,0x82}}, - {{0xe1,0xba,0xa7}, {0x61,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xba,0xa5}, {0x61,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xba,0xab}, {0x61,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xba,0xa9}, {0x61,0xcc,0x82,0xcc,0x89}}, - {{0xc3,0xa3}, {0x61,0xcc,0x83}}, - {{0xc4,0x81}, {0x61,0xcc,0x84}}, - {{0xc4,0x83}, {0x61,0xcc,0x86}}, - {{0xe1,0xba,0xb1}, {0x61,0xcc,0x86,0xcc,0x80}}, - {{0xe1,0xba,0xaf}, {0x61,0xcc,0x86,0xcc,0x81}}, - {{0xe1,0xba,0xb5}, {0x61,0xcc,0x86,0xcc,0x83}}, - {{0xe1,0xba,0xb3}, {0x61,0xcc,0x86,0xcc,0x89}}, - {{0xc7,0xa1}, {0x61,0xcc,0x87,0xcc,0x84}}, - {{0xc3,0xa4}, {0x61,0xcc,0x88}}, - {{0xc7,0x9f}, {0x61,0xcc,0x88,0xcc,0x84}}, - {{0xe1,0xba,0xa3}, {0x61,0xcc,0x89}}, - {{0xc3,0xa5}, {0x61,0xcc,0x8a}}, - {{0xc7,0xbb}, {0x61,0xcc,0x8a,0xcc,0x81}}, - {{0xc7,0x8e}, {0x61,0xcc,0x8c}}, - {{0xc8,0x81}, {0x61,0xcc,0x8f}}, - {{0xc8,0x83}, {0x61,0xcc,0x91}}, - {{0xe1,0xba,0xa1}, {0x61,0xcc,0xa3}}, - {{0xe1,0xba,0xad}, {0x61,0xcc,0xa3,0xcc,0x82}}, - {{0xe1,0xba,0xb7}, {0x61,0xcc,0xa3,0xcc,0x86}}, - {{0xe1,0xb8,0x81}, {0x61,0xcc,0xa5}}, - {{0xc4,0x85}, {0x61,0xcc,0xa8}}, - {{0xe1,0xb8,0x83}, {0x62,0xcc,0x87}}, - {{0xe1,0xb8,0x85}, {0x62,0xcc,0xa3}}, - {{0xe1,0xb8,0x87}, {0x62,0xcc,0xb1}}, - {{0xc4,0x87}, {0x63,0xcc,0x81}}, - {{0xc4,0x89}, {0x63,0xcc,0x82}}, - {{0xc4,0x8b}, {0x63,0xcc,0x87}}, - {{0xc4,0x8d}, {0x63,0xcc,0x8c}}, - {{0xc3,0xa7}, {0x63,0xcc,0xa7}}, - {{0xe1,0xb8,0x89}, {0x63,0xcc,0xa7,0xcc,0x81}}, - {{0xe1,0xb8,0x8b}, {0x64,0xcc,0x87}}, - {{0xc4,0x8f}, {0x64,0xcc,0x8c}}, - {{0xe1,0xb8,0x8d}, {0x64,0xcc,0xa3}}, - {{0xe1,0xb8,0x91}, {0x64,0xcc,0xa7}}, - {{0xe1,0xb8,0x93}, {0x64,0xcc,0xad}}, - {{0xe1,0xb8,0x8f}, {0x64,0xcc,0xb1}}, - {{0xc3,0xa8}, {0x65,0xcc,0x80}}, - {{0xc3,0xa9}, {0x65,0xcc,0x81}}, - {{0xc3,0xaa}, {0x65,0xcc,0x82}}, - {{0xe1,0xbb,0x81}, {0x65,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xba,0xbf}, {0x65,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xbb,0x85}, {0x65,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xbb,0x83}, {0x65,0xcc,0x82,0xcc,0x89}}, - {{0xe1,0xba,0xbd}, {0x65,0xcc,0x83}}, - {{0xc4,0x93}, {0x65,0xcc,0x84}}, - {{0xe1,0xb8,0x95}, {0x65,0xcc,0x84,0xcc,0x80}}, - {{0xe1,0xb8,0x97}, {0x65,0xcc,0x84,0xcc,0x81}}, - {{0xc4,0x95}, {0x65,0xcc,0x86}}, - {{0xc4,0x97}, {0x65,0xcc,0x87}}, - {{0xc3,0xab}, {0x65,0xcc,0x88}}, - {{0xe1,0xba,0xbb}, {0x65,0xcc,0x89}}, - {{0xc4,0x9b}, {0x65,0xcc,0x8c}}, - {{0xc8,0x85}, {0x65,0xcc,0x8f}}, - {{0xc8,0x87}, {0x65,0xcc,0x91}}, - {{0xe1,0xba,0xb9}, {0x65,0xcc,0xa3}}, - {{0xe1,0xbb,0x87}, {0x65,0xcc,0xa3,0xcc,0x82}}, - {{0xe1,0xb8,0x9d}, {0x65,0xcc,0xa7,0xcc,0x86}}, - {{0xc4,0x99}, {0x65,0xcc,0xa8}}, - {{0xe1,0xb8,0x99}, {0x65,0xcc,0xad}}, - {{0xe1,0xb8,0x9b}, {0x65,0xcc,0xb0}}, - {{0xe1,0xb8,0x9f}, {0x66,0xcc,0x87}}, - {{0xc7,0xb5}, {0x67,0xcc,0x81}}, - {{0xc4,0x9d}, {0x67,0xcc,0x82}}, - {{0xe1,0xb8,0xa1}, {0x67,0xcc,0x84}}, - {{0xc4,0x9f}, {0x67,0xcc,0x86}}, - {{0xc4,0xa1}, {0x67,0xcc,0x87}}, - {{0xc7,0xa7}, {0x67,0xcc,0x8c}}, - {{0xc4,0xa3}, {0x67,0xcc,0xa7}}, - {{0xc4,0xa5}, {0x68,0xcc,0x82}}, - {{0xe1,0xb8,0xa3}, {0x68,0xcc,0x87}}, - {{0xe1,0xb8,0xa7}, {0x68,0xcc,0x88}}, - {{0xe1,0xb8,0xa5}, {0x68,0xcc,0xa3}}, - {{0xe1,0xb8,0xa9}, {0x68,0xcc,0xa7}}, - {{0xe1,0xb8,0xab}, {0x68,0xcc,0xae}}, - {{0xe1,0xba,0x96}, {0x68,0xcc,0xb1}}, - {{0xc3,0xac}, {0x69,0xcc,0x80}}, - {{0xc3,0xad}, {0x69,0xcc,0x81}}, - {{0xc3,0xae}, {0x69,0xcc,0x82}}, - {{0xc4,0xa9}, {0x69,0xcc,0x83}}, - {{0xc4,0xab}, {0x69,0xcc,0x84}}, - {{0xc4,0xad}, {0x69,0xcc,0x86}}, - {{0xc3,0xaf}, {0x69,0xcc,0x88}}, - {{0xe1,0xb8,0xaf}, {0x69,0xcc,0x88,0xcc,0x81}}, - {{0xe1,0xbb,0x89}, {0x69,0xcc,0x89}}, - {{0xc7,0x90}, {0x69,0xcc,0x8c}}, - {{0xc8,0x89}, {0x69,0xcc,0x8f}}, - {{0xc8,0x8b}, {0x69,0xcc,0x91}}, - {{0xe1,0xbb,0x8b}, {0x69,0xcc,0xa3}}, - {{0xc4,0xaf}, {0x69,0xcc,0xa8}}, - {{0xe1,0xb8,0xad}, {0x69,0xcc,0xb0}}, - {{0xc4,0xb5}, {0x6a,0xcc,0x82}}, - {{0xc7,0xb0}, {0x6a,0xcc,0x8c}}, - {{0xe1,0xb8,0xb1}, {0x6b,0xcc,0x81}}, - {{0xc7,0xa9}, {0x6b,0xcc,0x8c}}, - {{0xe1,0xb8,0xb3}, {0x6b,0xcc,0xa3}}, - {{0xc4,0xb7}, {0x6b,0xcc,0xa7}}, - {{0xe1,0xb8,0xb5}, {0x6b,0xcc,0xb1}}, - {{0xc4,0xba}, {0x6c,0xcc,0x81}}, - {{0xc4,0xbe}, {0x6c,0xcc,0x8c}}, - {{0xe1,0xb8,0xb7}, {0x6c,0xcc,0xa3}}, - {{0xe1,0xb8,0xb9}, {0x6c,0xcc,0xa3,0xcc,0x84}}, - {{0xc4,0xbc}, {0x6c,0xcc,0xa7}}, - {{0xe1,0xb8,0xbd}, {0x6c,0xcc,0xad}}, - {{0xe1,0xb8,0xbb}, {0x6c,0xcc,0xb1}}, - {{0xe1,0xb8,0xbf}, {0x6d,0xcc,0x81}}, - {{0xe1,0xb9,0x81}, {0x6d,0xcc,0x87}}, - {{0xe1,0xb9,0x83}, {0x6d,0xcc,0xa3}}, - {{0xc5,0x84}, {0x6e,0xcc,0x81}}, - {{0xc3,0xb1}, {0x6e,0xcc,0x83}}, - {{0xe1,0xb9,0x85}, {0x6e,0xcc,0x87}}, - {{0xc5,0x88}, {0x6e,0xcc,0x8c}}, - {{0xe1,0xb9,0x87}, {0x6e,0xcc,0xa3}}, - {{0xc5,0x86}, {0x6e,0xcc,0xa7}}, - {{0xe1,0xb9,0x8b}, {0x6e,0xcc,0xad}}, - {{0xe1,0xb9,0x89}, {0x6e,0xcc,0xb1}}, - {{0xc3,0xb2}, {0x6f,0xcc,0x80}}, - {{0xc3,0xb3}, {0x6f,0xcc,0x81}}, - {{0xc3,0xb4}, {0x6f,0xcc,0x82}}, - {{0xe1,0xbb,0x93}, {0x6f,0xcc,0x82,0xcc,0x80}}, - {{0xe1,0xbb,0x91}, {0x6f,0xcc,0x82,0xcc,0x81}}, - {{0xe1,0xbb,0x97}, {0x6f,0xcc,0x82,0xcc,0x83}}, - {{0xe1,0xbb,0x95}, {0x6f,0xcc,0x82,0xcc,0x89}}, - {{0xc3,0xb5}, {0x6f,0xcc,0x83}}, - {{0xe1,0xb9,0x8d}, {0x6f,0xcc,0x83,0xcc,0x81}}, - {{0xe1,0xb9,0x8f}, {0x6f,0xcc,0x83,0xcc,0x88}}, - {{0xc5,0x8d}, {0x6f,0xcc,0x84}}, - {{0xe1,0xb9,0x91}, {0x6f,0xcc,0x84,0xcc,0x80}}, - {{0xe1,0xb9,0x93}, {0x6f,0xcc,0x84,0xcc,0x81}}, - {{0xc5,0x8f}, {0x6f,0xcc,0x86}}, - {{0xc3,0xb6}, {0x6f,0xcc,0x88}}, - {{0xe1,0xbb,0x8f}, {0x6f,0xcc,0x89}}, - {{0xc5,0x91}, {0x6f,0xcc,0x8b}}, - {{0xc7,0x92}, {0x6f,0xcc,0x8c}}, - {{0xc8,0x8d}, {0x6f,0xcc,0x8f}}, - {{0xc8,0x8f}, {0x6f,0xcc,0x91}}, - {{0xc6,0xa1}, {0x6f,0xcc,0x9b}}, - {{0xe1,0xbb,0x9d}, {0x6f,0xcc,0x9b,0xcc,0x80}}, - {{0xe1,0xbb,0x9b}, {0x6f,0xcc,0x9b,0xcc,0x81}}, - {{0xe1,0xbb,0xa1}, {0x6f,0xcc,0x9b,0xcc,0x83}}, - {{0xe1,0xbb,0x9f}, {0x6f,0xcc,0x9b,0xcc,0x89}}, - {{0xe1,0xbb,0xa3}, {0x6f,0xcc,0x9b,0xcc,0xa3}}, - {{0xe1,0xbb,0x8d}, {0x6f,0xcc,0xa3}}, - {{0xe1,0xbb,0x99}, {0x6f,0xcc,0xa3,0xcc,0x82}}, - {{0xc7,0xab}, {0x6f,0xcc,0xa8}}, - {{0xc7,0xad}, {0x6f,0xcc,0xa8,0xcc,0x84}}, - {{0xe1,0xb9,0x95}, {0x70,0xcc,0x81}}, - {{0xe1,0xb9,0x97}, {0x70,0xcc,0x87}}, - {{0xc5,0x95}, {0x72,0xcc,0x81}}, - {{0xe1,0xb9,0x99}, {0x72,0xcc,0x87}}, - {{0xc5,0x99}, {0x72,0xcc,0x8c}}, - {{0xc8,0x91}, {0x72,0xcc,0x8f}}, - {{0xc8,0x93}, {0x72,0xcc,0x91}}, - {{0xe1,0xb9,0x9b}, {0x72,0xcc,0xa3}}, - {{0xe1,0xb9,0x9d}, {0x72,0xcc,0xa3,0xcc,0x84}}, - {{0xc5,0x97}, {0x72,0xcc,0xa7}}, - {{0xe1,0xb9,0x9f}, {0x72,0xcc,0xb1}}, - {{0xc5,0x9b}, {0x73,0xcc,0x81}}, - {{0xe1,0xb9,0xa5}, {0x73,0xcc,0x81,0xcc,0x87}}, - {{0xc5,0x9d}, {0x73,0xcc,0x82}}, - {{0xe1,0xb9,0xa1}, {0x73,0xcc,0x87}}, - {{0xc5,0xa1}, {0x73,0xcc,0x8c}}, - {{0xe1,0xb9,0xa7}, {0x73,0xcc,0x8c,0xcc,0x87}}, - {{0xe1,0xb9,0xa3}, {0x73,0xcc,0xa3}}, - {{0xe1,0xb9,0xa9}, {0x73,0xcc,0xa3,0xcc,0x87}}, - {{0xc5,0x9f}, {0x73,0xcc,0xa7}}, - {{0xe1,0xb9,0xab}, {0x74,0xcc,0x87}}, - {{0xe1,0xba,0x97}, {0x74,0xcc,0x88}}, - {{0xc5,0xa5}, {0x74,0xcc,0x8c}}, - {{0xe1,0xb9,0xad}, {0x74,0xcc,0xa3}}, - {{0xc5,0xa3}, {0x74,0xcc,0xa7}}, - {{0xe1,0xb9,0xb1}, {0x74,0xcc,0xad}}, - {{0xe1,0xb9,0xaf}, {0x74,0xcc,0xb1}}, - {{0xc3,0xb9}, {0x75,0xcc,0x80}}, - {{0xc3,0xba}, {0x75,0xcc,0x81}}, - {{0xc3,0xbb}, {0x75,0xcc,0x82}}, - {{0xc5,0xa9}, {0x75,0xcc,0x83}}, - {{0xe1,0xb9,0xb9}, {0x75,0xcc,0x83,0xcc,0x81}}, - {{0xc5,0xab}, {0x75,0xcc,0x84}}, - {{0xe1,0xb9,0xbb}, {0x75,0xcc,0x84,0xcc,0x88}}, - {{0xc5,0xad}, {0x75,0xcc,0x86}}, - {{0xc3,0xbc}, {0x75,0xcc,0x88}}, - {{0xc7,0x9c}, {0x75,0xcc,0x88,0xcc,0x80}}, - {{0xc7,0x98}, {0x75,0xcc,0x88,0xcc,0x81}}, - {{0xc7,0x96}, {0x75,0xcc,0x88,0xcc,0x84}}, - {{0xc7,0x9a}, {0x75,0xcc,0x88,0xcc,0x8c}}, - {{0xe1,0xbb,0xa7}, {0x75,0xcc,0x89}}, - {{0xc5,0xaf}, {0x75,0xcc,0x8a}}, - {{0xc5,0xb1}, {0x75,0xcc,0x8b}}, - {{0xc7,0x94}, {0x75,0xcc,0x8c}}, - {{0xc8,0x95}, {0x75,0xcc,0x8f}}, - {{0xc8,0x97}, {0x75,0xcc,0x91}}, - {{0xc6,0xb0}, {0x75,0xcc,0x9b}}, - {{0xe1,0xbb,0xab}, {0x75,0xcc,0x9b,0xcc,0x80}}, - {{0xe1,0xbb,0xa9}, {0x75,0xcc,0x9b,0xcc,0x81}}, - {{0xe1,0xbb,0xaf}, {0x75,0xcc,0x9b,0xcc,0x83}}, - {{0xe1,0xbb,0xad}, {0x75,0xcc,0x9b,0xcc,0x89}}, - {{0xe1,0xbb,0xb1}, {0x75,0xcc,0x9b,0xcc,0xa3}}, - {{0xe1,0xbb,0xa5}, {0x75,0xcc,0xa3}}, - {{0xe1,0xb9,0xb3}, {0x75,0xcc,0xa4}}, - {{0xc5,0xb3}, {0x75,0xcc,0xa8}}, - {{0xe1,0xb9,0xb7}, {0x75,0xcc,0xad}}, - {{0xe1,0xb9,0xb5}, {0x75,0xcc,0xb0}}, - {{0xe1,0xb9,0xbd}, {0x76,0xcc,0x83}}, - {{0xe1,0xb9,0xbf}, {0x76,0xcc,0xa3}}, - {{0xe1,0xba,0x81}, {0x77,0xcc,0x80}}, - {{0xe1,0xba,0x83}, {0x77,0xcc,0x81}}, - {{0xc5,0xb5}, {0x77,0xcc,0x82}}, - {{0xe1,0xba,0x87}, {0x77,0xcc,0x87}}, - {{0xe1,0xba,0x85}, {0x77,0xcc,0x88}}, - {{0xe1,0xba,0x98}, {0x77,0xcc,0x8a}}, - {{0xe1,0xba,0x89}, {0x77,0xcc,0xa3}}, - {{0xe1,0xba,0x8b}, {0x78,0xcc,0x87}}, - {{0xe1,0xba,0x8d}, {0x78,0xcc,0x88}}, - {{0xe1,0xbb,0xb3}, {0x79,0xcc,0x80}}, - {{0xc3,0xbd}, {0x79,0xcc,0x81}}, - {{0xc5,0xb7}, {0x79,0xcc,0x82}}, - {{0xe1,0xbb,0xb9}, {0x79,0xcc,0x83}}, - {{0xe1,0xba,0x8f}, {0x79,0xcc,0x87}}, - {{0xc3,0xbf}, {0x79,0xcc,0x88}}, - {{0xe1,0xbb,0xb7}, {0x79,0xcc,0x89}}, - {{0xe1,0xba,0x99}, {0x79,0xcc,0x8a}}, - {{0xe1,0xbb,0xb5}, {0x79,0xcc,0xa3}}, - {{0xc5,0xba}, {0x7a,0xcc,0x81}}, - {{0xe1,0xba,0x91}, {0x7a,0xcc,0x82}}, - {{0xc5,0xbc}, {0x7a,0xcc,0x87}}, - {{0xc5,0xbe}, {0x7a,0xcc,0x8c}}, - {{0xe1,0xba,0x93}, {0x7a,0xcc,0xa3}}, - {{0xe1,0xba,0x95}, {0x7a,0xcc,0xb1}}, - {{0xe1,0xbf,0xad}, {0xc2,0xa8,0xcc,0x80}}, - {{0xe1,0xbf,0xae}, {0xc2,0xa8,0xcc,0x81}}, - {{0xce,0x85}, {0xc2,0xa8,0xcc,0x8d}}, - {{0xe1,0xbf,0x81}, {0xc2,0xa8,0xcd,0x82}}, - {{0xe1,0xbf,0xbd}, {0xc2,0xb4}}, - {{0xce,0x87}, {0xc2,0xb7}}, - {{0xd3,0x94}, {0xc3,0x86}}, - {{0xc7,0xbc}, {0xc3,0x86,0xcc,0x81}}, - {{0xc7,0xa2}, {0xc3,0x86,0xcc,0x84}}, - {{0xc7,0xbe}, {0xc3,0x98,0xcc,0x81}}, - {{0xd3,0x95}, {0xc3,0xa6}}, - {{0xc7,0xbd}, {0xc3,0xa6,0xcc,0x81}}, - {{0xc7,0xa3}, {0xc3,0xa6,0xcc,0x84}}, - {{0xc7,0xbf}, {0xc3,0xb8,0xcc,0x81}}, - {{0xe1,0xba,0x9b}, {0xc5,0xbf,0xcc,0x87}}, - {{0xd3,0x98}, {0xc6,0x8f}}, - {{0xd3,0x9a}, {0xc6,0x8f,0xcc,0x88}}, - {{0xd3,0xa8}, {0xc6,0x9f}}, - {{0xd3,0xaa}, {0xc6,0x9f,0xcc,0x88}}, - {{0xd3,0xa0}, {0xc6,0xb7}}, - {{0xc7,0xae}, {0xc6,0xb7,0xcc,0x8c}}, - {{0xd3,0x99}, {0xc9,0x99}}, - {{0xd3,0x9b}, {0xc9,0x99,0xcc,0x88}}, - {{0xd3,0xa9}, {0xc9,0xb5}}, - {{0xd3,0xab}, {0xc9,0xb5,0xcc,0x88}}, - {{0xd3,0xa1}, {0xca,0x92}}, - {{0xc7,0xaf}, {0xca,0x92,0xcc,0x8c}}, - {{0xcd,0xb4}, {0xca,0xb9}}, - {{0xcd,0x80}, {0xcc,0x80}}, - {{0xcd,0x81}, {0xcc,0x81}}, - {{0xcc,0x90}, {0xcc,0x86,0xcc,0x87}}, - {{0xcd,0x84}, {0xcc,0x88,0xcc,0x8d}}, - {{0xcd,0x83}, {0xcc,0x93}}, - {{0xe1,0xbe,0xba}, {0xce,0x91,0xcc,0x80}}, - {{0xe1,0xbe,0xbb}, {0xce,0x91,0xcc,0x81}}, - {{0xe1,0xbe,0xb9}, {0xce,0x91,0xcc,0x84}}, - {{0xe1,0xbe,0xb8}, {0xce,0x91,0xcc,0x86}}, - {{0xce,0x86}, {0xce,0x91,0xcc,0x8d}}, - {{0xe1,0xbc,0x88}, {0xce,0x91,0xcc,0x93}}, - {{0xe1,0xbc,0x8a}, {0xce,0x91,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0x8c}, {0xce,0x91,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0x8e}, {0xce,0x91,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0x89}, {0xce,0x91,0xcc,0x94}}, - {{0xe1,0xbc,0x8b}, {0xce,0x91,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0x8d}, {0xce,0x91,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0x8f}, {0xce,0x91,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbe,0xbc}, {0xce,0x91,0xcd,0x85}}, - {{0xe1,0xbe,0x88}, {0xce,0x91,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0x8a}, {0xce,0x91,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0x8c}, {0xce,0x91,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0x8e}, {0xce,0x91,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0x89}, {0xce,0x91,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0x8b}, {0xce,0x91,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0x8d}, {0xce,0x91,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0x8f}, {0xce,0x91,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x88}, {0xce,0x95,0xcc,0x80}}, - {{0xe1,0xbf,0x89}, {0xce,0x95,0xcc,0x81}}, - {{0xce,0x88}, {0xce,0x95,0xcc,0x8d}}, - {{0xe1,0xbc,0x98}, {0xce,0x95,0xcc,0x93}}, - {{0xe1,0xbc,0x9a}, {0xce,0x95,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0x9c}, {0xce,0x95,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0x99}, {0xce,0x95,0xcc,0x94}}, - {{0xe1,0xbc,0x9b}, {0xce,0x95,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0x9d}, {0xce,0x95,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbf,0x8a}, {0xce,0x97,0xcc,0x80}}, - {{0xe1,0xbf,0x8b}, {0xce,0x97,0xcc,0x81}}, - {{0xce,0x89}, {0xce,0x97,0xcc,0x8d}}, - {{0xe1,0xbc,0xa8}, {0xce,0x97,0xcc,0x93}}, - {{0xe1,0xbc,0xaa}, {0xce,0x97,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0xac}, {0xce,0x97,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0xae}, {0xce,0x97,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0xa9}, {0xce,0x97,0xcc,0x94}}, - {{0xe1,0xbc,0xab}, {0xce,0x97,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0xad}, {0xce,0x97,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0xaf}, {0xce,0x97,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x8c}, {0xce,0x97,0xcd,0x85}}, - {{0xe1,0xbe,0x98}, {0xce,0x97,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0x9a}, {0xce,0x97,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0x9c}, {0xce,0x97,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0x9e}, {0xce,0x97,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0x99}, {0xce,0x97,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0x9b}, {0xce,0x97,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0x9d}, {0xce,0x97,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0x9f}, {0xce,0x97,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x9a}, {0xce,0x99,0xcc,0x80}}, - {{0xe1,0xbf,0x9b}, {0xce,0x99,0xcc,0x81}}, - {{0xe1,0xbf,0x99}, {0xce,0x99,0xcc,0x84}}, - {{0xe1,0xbf,0x98}, {0xce,0x99,0xcc,0x86}}, - {{0xce,0xaa}, {0xce,0x99,0xcc,0x88}}, - {{0xce,0x8a}, {0xce,0x99,0xcc,0x8d}}, - {{0xe1,0xbc,0xb8}, {0xce,0x99,0xcc,0x93}}, - {{0xe1,0xbc,0xba}, {0xce,0x99,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0xbc}, {0xce,0x99,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0xbe}, {0xce,0x99,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0xb9}, {0xce,0x99,0xcc,0x94}}, - {{0xe1,0xbc,0xbb}, {0xce,0x99,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0xbd}, {0xce,0x99,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0xbf}, {0xce,0x99,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xb8}, {0xce,0x9f,0xcc,0x80}}, - {{0xe1,0xbf,0xb9}, {0xce,0x9f,0xcc,0x81}}, - {{0xce,0x8c}, {0xce,0x9f,0xcc,0x8d}}, - {{0xe1,0xbd,0x88}, {0xce,0x9f,0xcc,0x93}}, - {{0xe1,0xbd,0x8a}, {0xce,0x9f,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbd,0x8c}, {0xce,0x9f,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbd,0x89}, {0xce,0x9f,0xcc,0x94}}, - {{0xe1,0xbd,0x8b}, {0xce,0x9f,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0x8d}, {0xce,0x9f,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbf,0xac}, {0xce,0xa1,0xcc,0x94}}, - {{0xe1,0xbf,0xaa}, {0xce,0xa5,0xcc,0x80}}, - {{0xe1,0xbf,0xab}, {0xce,0xa5,0xcc,0x81}}, - {{0xe1,0xbf,0xa9}, {0xce,0xa5,0xcc,0x84}}, - {{0xe1,0xbf,0xa8}, {0xce,0xa5,0xcc,0x86}}, - {{0xce,0xab}, {0xce,0xa5,0xcc,0x88}}, - {{0xce,0x8e}, {0xce,0xa5,0xcc,0x8d}}, - {{0xe1,0xbd,0x99}, {0xce,0xa5,0xcc,0x94}}, - {{0xe1,0xbd,0x9b}, {0xce,0xa5,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0x9d}, {0xce,0xa5,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbd,0x9f}, {0xce,0xa5,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xba}, {0xce,0xa9,0xcc,0x80}}, - {{0xe1,0xbf,0xbb}, {0xce,0xa9,0xcc,0x81}}, - {{0xce,0x8f}, {0xce,0xa9,0xcc,0x8d}}, - {{0xe1,0xbd,0xa8}, {0xce,0xa9,0xcc,0x93}}, - {{0xe1,0xbd,0xaa}, {0xce,0xa9,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbd,0xac}, {0xce,0xa9,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbd,0xae}, {0xce,0xa9,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbd,0xa9}, {0xce,0xa9,0xcc,0x94}}, - {{0xe1,0xbd,0xab}, {0xce,0xa9,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0xad}, {0xce,0xa9,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbd,0xaf}, {0xce,0xa9,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xbc}, {0xce,0xa9,0xcd,0x85}}, - {{0xe1,0xbe,0xa8}, {0xce,0xa9,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0xaa}, {0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0xac}, {0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0xae}, {0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0xa9}, {0xce,0xa9,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0xab}, {0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0xad}, {0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0xaf}, {0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbd,0xb0}, {0xce,0xb1,0xcc,0x80}}, - {{0xe1,0xbd,0xb1}, {0xce,0xb1,0xcc,0x81}}, - {{0xe1,0xbe,0xb1}, {0xce,0xb1,0xcc,0x84}}, - {{0xe1,0xbe,0xb0}, {0xce,0xb1,0xcc,0x86}}, - {{0xce,0xac}, {0xce,0xb1,0xcc,0x8d}}, - {{0xe1,0xbc,0x80}, {0xce,0xb1,0xcc,0x93}}, - {{0xe1,0xbc,0x82}, {0xce,0xb1,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0x84}, {0xce,0xb1,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0x86}, {0xce,0xb1,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0x81}, {0xce,0xb1,0xcc,0x94}}, - {{0xe1,0xbc,0x83}, {0xce,0xb1,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0x85}, {0xce,0xb1,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0x87}, {0xce,0xb1,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbe,0xb6}, {0xce,0xb1,0xcd,0x82}}, - {{0xe1,0xbe,0xb3}, {0xce,0xb1,0xcd,0x85}}, - {{0xe1,0xbe,0xb2}, {0xce,0xb1,0xcd,0x85,0xcc,0x80}}, - {{0xe1,0xbe,0xb4}, {0xce,0xb1,0xcd,0x85,0xcc,0x81}}, - {{0xe1,0xbe,0x80}, {0xce,0xb1,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0x82}, {0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0x84}, {0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0x86}, {0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0x81}, {0xce,0xb1,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0x83}, {0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0x85}, {0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0x87}, {0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbe,0xb7}, {0xce,0xb1,0xcd,0x85,0xcd,0x82}}, - {{0xe1,0xbd,0xb2}, {0xce,0xb5,0xcc,0x80}}, - {{0xe1,0xbd,0xb3}, {0xce,0xb5,0xcc,0x81}}, - {{0xce,0xad}, {0xce,0xb5,0xcc,0x8d}}, - {{0xe1,0xbc,0x90}, {0xce,0xb5,0xcc,0x93}}, - {{0xe1,0xbc,0x92}, {0xce,0xb5,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0x94}, {0xce,0xb5,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0x91}, {0xce,0xb5,0xcc,0x94}}, - {{0xe1,0xbc,0x93}, {0xce,0xb5,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0x95}, {0xce,0xb5,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbd,0xb4}, {0xce,0xb7,0xcc,0x80}}, - {{0xe1,0xbd,0xb5}, {0xce,0xb7,0xcc,0x81}}, - {{0xce,0xae}, {0xce,0xb7,0xcc,0x8d}}, - {{0xe1,0xbc,0xa0}, {0xce,0xb7,0xcc,0x93}}, - {{0xe1,0xbc,0xa2}, {0xce,0xb7,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0xa4}, {0xce,0xb7,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0xa6}, {0xce,0xb7,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0xa1}, {0xce,0xb7,0xcc,0x94}}, - {{0xe1,0xbc,0xa3}, {0xce,0xb7,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0xa5}, {0xce,0xb7,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0xa7}, {0xce,0xb7,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x86}, {0xce,0xb7,0xcd,0x82}}, - {{0xe1,0xbf,0x83}, {0xce,0xb7,0xcd,0x85}}, - {{0xe1,0xbf,0x82}, {0xce,0xb7,0xcd,0x85,0xcc,0x80}}, - {{0xe1,0xbf,0x84}, {0xce,0xb7,0xcd,0x85,0xcc,0x81}}, - {{0xe1,0xbe,0x90}, {0xce,0xb7,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0x92}, {0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0x94}, {0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0x96}, {0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0x91}, {0xce,0xb7,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0x93}, {0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0x95}, {0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0x97}, {0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x87}, {0xce,0xb7,0xcd,0x85,0xcd,0x82}}, - {{0xe1,0xbe,0xbe}, {0xce,0xb9}}, - {{0xe1,0xbd,0xb6}, {0xce,0xb9,0xcc,0x80}}, - {{0xe1,0xbd,0xb7}, {0xce,0xb9,0xcc,0x81}}, - {{0xe1,0xbf,0x91}, {0xce,0xb9,0xcc,0x84}}, - {{0xe1,0xbf,0x90}, {0xce,0xb9,0xcc,0x86}}, - {{0xcf,0x8a}, {0xce,0xb9,0xcc,0x88}}, - {{0xe1,0xbf,0x92}, {0xce,0xb9,0xcc,0x88,0xcc,0x80}}, - {{0xe1,0xbf,0x93}, {0xce,0xb9,0xcc,0x88,0xcc,0x81}}, - {{0xce,0x90}, {0xce,0xb9,0xcc,0x88,0xcc,0x8d}}, - {{0xe1,0xbf,0x97}, {0xce,0xb9,0xcc,0x88,0xcd,0x82}}, - {{0xce,0xaf}, {0xce,0xb9,0xcc,0x8d}}, - {{0xe1,0xbc,0xb0}, {0xce,0xb9,0xcc,0x93}}, - {{0xe1,0xbc,0xb2}, {0xce,0xb9,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbc,0xb4}, {0xce,0xb9,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbc,0xb6}, {0xce,0xb9,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbc,0xb1}, {0xce,0xb9,0xcc,0x94}}, - {{0xe1,0xbc,0xb3}, {0xce,0xb9,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbc,0xb5}, {0xce,0xb9,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbc,0xb7}, {0xce,0xb9,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0x96}, {0xce,0xb9,0xcd,0x82}}, - {{0xe1,0xbd,0xb8}, {0xce,0xbf,0xcc,0x80}}, - {{0xe1,0xbd,0xb9}, {0xce,0xbf,0xcc,0x81}}, - {{0xcf,0x8c}, {0xce,0xbf,0xcc,0x8d}}, - {{0xe1,0xbd,0x80}, {0xce,0xbf,0xcc,0x93}}, - {{0xe1,0xbd,0x82}, {0xce,0xbf,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbd,0x84}, {0xce,0xbf,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbd,0x81}, {0xce,0xbf,0xcc,0x94}}, - {{0xe1,0xbd,0x83}, {0xce,0xbf,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0x85}, {0xce,0xbf,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbf,0xb4}, {0xce,0xbf,0xcd,0x85,0xcc,0x81}}, - {{0xe1,0xbf,0xa4}, {0xcf,0x81,0xcc,0x93}}, - {{0xe1,0xbf,0xa5}, {0xcf,0x81,0xcc,0x94}}, - {{0xe1,0xbd,0xba}, {0xcf,0x85,0xcc,0x80}}, - {{0xe1,0xbd,0xbb}, {0xcf,0x85,0xcc,0x81}}, - {{0xe1,0xbf,0xa1}, {0xcf,0x85,0xcc,0x84}}, - {{0xe1,0xbf,0xa0}, {0xcf,0x85,0xcc,0x86}}, - {{0xcf,0x8b}, {0xcf,0x85,0xcc,0x88}}, - {{0xe1,0xbf,0xa2}, {0xcf,0x85,0xcc,0x88,0xcc,0x80}}, - {{0xe1,0xbf,0xa3}, {0xcf,0x85,0xcc,0x88,0xcc,0x81}}, - {{0xce,0xb0}, {0xcf,0x85,0xcc,0x88,0xcc,0x8d}}, - {{0xe1,0xbf,0xa7}, {0xcf,0x85,0xcc,0x88,0xcd,0x82}}, - {{0xcf,0x8d}, {0xcf,0x85,0xcc,0x8d}}, - {{0xe1,0xbd,0x90}, {0xcf,0x85,0xcc,0x93}}, - {{0xe1,0xbd,0x92}, {0xcf,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbd,0x94}, {0xcf,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbd,0x96}, {0xcf,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbd,0x91}, {0xcf,0x85,0xcc,0x94}}, - {{0xe1,0xbd,0x93}, {0xcf,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0x95}, {0xcf,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbd,0x97}, {0xcf,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xa6}, {0xcf,0x85,0xcd,0x82}}, - {{0xe1,0xbd,0xbc}, {0xcf,0x89,0xcc,0x80}}, - {{0xe1,0xbd,0xbd}, {0xcf,0x89,0xcc,0x81}}, - {{0xcf,0x8e}, {0xcf,0x89,0xcc,0x8d}}, - {{0xe1,0xbd,0xa0}, {0xcf,0x89,0xcc,0x93}}, - {{0xe1,0xbd,0xa2}, {0xcf,0x89,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbd,0xa4}, {0xcf,0x89,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbd,0xa6}, {0xcf,0x89,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbd,0xa1}, {0xcf,0x89,0xcc,0x94}}, - {{0xe1,0xbd,0xa3}, {0xcf,0x89,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbd,0xa5}, {0xcf,0x89,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbd,0xa7}, {0xcf,0x89,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xb6}, {0xcf,0x89,0xcd,0x82}}, - {{0xe1,0xbf,0xb3}, {0xcf,0x89,0xcd,0x85}}, - {{0xe1,0xbf,0xb2}, {0xcf,0x89,0xcd,0x85,0xcc,0x80}}, - {{0xe1,0xbe,0xa0}, {0xcf,0x89,0xcd,0x85,0xcc,0x93}}, - {{0xe1,0xbe,0xa2}, {0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcc,0x80}}, - {{0xe1,0xbe,0xa4}, {0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcc,0x81}}, - {{0xe1,0xbe,0xa6}, {0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcd,0x82}}, - {{0xe1,0xbe,0xa1}, {0xcf,0x89,0xcd,0x85,0xcc,0x94}}, - {{0xe1,0xbe,0xa3}, {0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcc,0x80}}, - {{0xe1,0xbe,0xa5}, {0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcc,0x81}}, - {{0xe1,0xbe,0xa7}, {0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcd,0x82}}, - {{0xe1,0xbf,0xb7}, {0xcf,0x89,0xcd,0x85,0xcd,0x82}}, - {{0xcf,0x94}, {0xcf,0x92,0xcc,0x88}}, - {{0xcf,0x93}, {0xcf,0x92,0xcc,0x8d}}, - {{0xd0,0x87}, {0xd0,0x86,0xcc,0x88}}, - {{0xd3,0x90}, {0xd0,0x90,0xcc,0x86}}, - {{0xd3,0x92}, {0xd0,0x90,0xcc,0x88}}, - {{0xd0,0x83}, {0xd0,0x93,0xcc,0x81}}, - {{0xd3,0x96}, {0xd0,0x95,0xcc,0x86}}, - {{0xd0,0x81}, {0xd0,0x95,0xcc,0x88}}, - {{0xd3,0x81}, {0xd0,0x96,0xcc,0x86}}, - {{0xd3,0x9c}, {0xd0,0x96,0xcc,0x88}}, - {{0xd3,0x9e}, {0xd0,0x97,0xcc,0x88}}, - {{0xd3,0xa2}, {0xd0,0x98,0xcc,0x84}}, - {{0xd0,0x99}, {0xd0,0x98,0xcc,0x86}}, - {{0xd3,0xa4}, {0xd0,0x98,0xcc,0x88}}, - {{0xd0,0x8c}, {0xd0,0x9a,0xcc,0x81}}, - {{0xd3,0xa6}, {0xd0,0x9e,0xcc,0x88}}, - {{0xd3,0xae}, {0xd0,0xa3,0xcc,0x84}}, - {{0xd0,0x8e}, {0xd0,0xa3,0xcc,0x86}}, - {{0xd3,0xb0}, {0xd0,0xa3,0xcc,0x88}}, - {{0xd3,0xb2}, {0xd0,0xa3,0xcc,0x8b}}, - {{0xd3,0xb4}, {0xd0,0xa7,0xcc,0x88}}, - {{0xd3,0xb8}, {0xd0,0xab,0xcc,0x88}}, - {{0xd3,0x91}, {0xd0,0xb0,0xcc,0x86}}, - {{0xd3,0x93}, {0xd0,0xb0,0xcc,0x88}}, - {{0xd1,0x93}, {0xd0,0xb3,0xcc,0x81}}, - {{0xd3,0x97}, {0xd0,0xb5,0xcc,0x86}}, - {{0xd1,0x91}, {0xd0,0xb5,0xcc,0x88}}, - {{0xd3,0x82}, {0xd0,0xb6,0xcc,0x86}}, - {{0xd3,0x9d}, {0xd0,0xb6,0xcc,0x88}}, - {{0xd3,0x9f}, {0xd0,0xb7,0xcc,0x88}}, - {{0xd3,0xa3}, {0xd0,0xb8,0xcc,0x84}}, - {{0xd0,0xb9}, {0xd0,0xb8,0xcc,0x86}}, - {{0xd3,0xa5}, {0xd0,0xb8,0xcc,0x88}}, - {{0xd1,0x9c}, {0xd0,0xba,0xcc,0x81}}, - {{0xd3,0xa7}, {0xd0,0xbe,0xcc,0x88}}, - {{0xd3,0xaf}, {0xd1,0x83,0xcc,0x84}}, - {{0xd1,0x9e}, {0xd1,0x83,0xcc,0x86}}, - {{0xd3,0xb1}, {0xd1,0x83,0xcc,0x88}}, - {{0xd3,0xb3}, {0xd1,0x83,0xcc,0x8b}}, - {{0xd3,0xb5}, {0xd1,0x87,0xcc,0x88}}, - {{0xd3,0xb9}, {0xd1,0x8b,0xcc,0x88}}, - {{0xd1,0x97}, {0xd1,0x96,0xcc,0x88}}, - {{0xd1,0xb6}, {0xd1,0xb4,0xcc,0x8f}}, - {{0xd1,0xb7}, {0xd1,0xb5,0xcc,0x8f}}, - {{0xef,0xac,0xae}, {0xd7,0x90,0xd6,0xb7}}, - {{0xef,0xac,0xaf}, {0xd7,0x90,0xd6,0xb8}}, - {{0xef,0xac,0xb0}, {0xd7,0x90,0xd6,0xbc}}, - {{0xef,0xac,0xb1}, {0xd7,0x91,0xd6,0xbc}}, - {{0xef,0xad,0x8c}, {0xd7,0x91,0xd6,0xbf}}, - {{0xef,0xac,0xb2}, {0xd7,0x92,0xd6,0xbc}}, - {{0xef,0xac,0xb3}, {0xd7,0x93,0xd6,0xbc}}, - {{0xef,0xac,0xb4}, {0xd7,0x94,0xd6,0xbc}}, - {{0xef,0xad,0x8b}, {0xd7,0x95,0xd6,0xb9}}, - {{0xef,0xac,0xb5}, {0xd7,0x95,0xd6,0xbc}}, - {{0xef,0xac,0xb6}, {0xd7,0x96,0xd6,0xbc}}, - {{0xef,0xac,0xb8}, {0xd7,0x98,0xd6,0xbc}}, - {{0xef,0xac,0xb9}, {0xd7,0x99,0xd6,0xbc}}, - {{0xef,0xac,0xba}, {0xd7,0x9a,0xd6,0xbc}}, - {{0xef,0xac,0xbb}, {0xd7,0x9b,0xd6,0xbc}}, - {{0xef,0xad,0x8d}, {0xd7,0x9b,0xd6,0xbf}}, - {{0xef,0xac,0xbc}, {0xd7,0x9c,0xd6,0xbc}}, - {{0xef,0xac,0xbe}, {0xd7,0x9e,0xd6,0xbc}}, - {{0xef,0xad,0x80}, {0xd7,0xa0,0xd6,0xbc}}, - {{0xef,0xad,0x81}, {0xd7,0xa1,0xd6,0xbc}}, - {{0xef,0xad,0x83}, {0xd7,0xa3,0xd6,0xbc}}, - {{0xef,0xad,0x84}, {0xd7,0xa4,0xd6,0xbc}}, - {{0xef,0xad,0x8e}, {0xd7,0xa4,0xd6,0xbf}}, - {{0xef,0xad,0x86}, {0xd7,0xa6,0xd6,0xbc}}, - {{0xef,0xad,0x87}, {0xd7,0xa7,0xd6,0xbc}}, - {{0xef,0xad,0x88}, {0xd7,0xa8,0xd6,0xbc}}, - {{0xef,0xad,0x89}, {0xd7,0xa9,0xd6,0xbc}}, - {{0xef,0xac,0xac}, {0xd7,0xa9,0xd6,0xbc,0xd7,0x81}}, - {{0xef,0xac,0xad}, {0xd7,0xa9,0xd6,0xbc,0xd7,0x82}}, - {{0xef,0xac,0xaa}, {0xd7,0xa9,0xd7,0x81}}, - {{0xef,0xac,0xab}, {0xd7,0xa9,0xd7,0x82}}, - {{0xef,0xad,0x8a}, {0xd7,0xaa,0xd6,0xbc}}, - {{0xef,0xac,0x9f}, {0xd7,0xb2,0xd6,0xb7}}, - {{0xe0,0xa5,0x98}, {0xe0,0xa4,0x95,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x99}, {0xe0,0xa4,0x96,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9a}, {0xe0,0xa4,0x97,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9b}, {0xe0,0xa4,0x9c,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9c}, {0xe0,0xa4,0xa1,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9d}, {0xe0,0xa4,0xa2,0xe0,0xa4,0xbc}}, - {{0xe0,0xa4,0xa9}, {0xe0,0xa4,0xa8,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9e}, {0xe0,0xa4,0xab,0xe0,0xa4,0xbc}}, - {{0xe0,0xa5,0x9f}, {0xe0,0xa4,0xaf,0xe0,0xa4,0xbc}}, - {{0xe0,0xa4,0xb1}, {0xe0,0xa4,0xb0,0xe0,0xa4,0xbc}}, - {{0xe0,0xa4,0xb4}, {0xe0,0xa4,0xb3,0xe0,0xa4,0xbc}}, - {{0xe0,0xa7,0x9c}, {0xe0,0xa6,0xa1,0xe0,0xa6,0xbc}}, - {{0xe0,0xa7,0x9d}, {0xe0,0xa6,0xa2,0xe0,0xa6,0xbc}}, - {{0xe0,0xa6,0xb0}, {0xe0,0xa6,0xac,0xe0,0xa6,0xbc}}, - {{0xe0,0xa7,0x9f}, {0xe0,0xa6,0xaf,0xe0,0xa6,0xbc}}, - {{0xe0,0xa7,0x8b}, {0xe0,0xa7,0x87,0xe0,0xa6,0xbe}}, - {{0xe0,0xa7,0x8c}, {0xe0,0xa7,0x87,0xe0,0xa7,0x97}}, - {{0xe0,0xa9,0x99}, {0xe0,0xa8,0x96,0xe0,0xa8,0xbc}}, - {{0xe0,0xa9,0x9a}, {0xe0,0xa8,0x97,0xe0,0xa8,0xbc}}, - {{0xe0,0xa9,0x9b}, {0xe0,0xa8,0x9c,0xe0,0xa8,0xbc}}, - {{0xe0,0xa9,0x9c}, {0xe0,0xa8,0xa1,0xe0,0xa8,0xbc}}, - {{0xe0,0xa9,0x9e}, {0xe0,0xa8,0xab,0xe0,0xa8,0xbc}}, - {{0xe0,0xad,0x9c}, {0xe0,0xac,0xa1,0xe0,0xac,0xbc}}, - {{0xe0,0xad,0x9d}, {0xe0,0xac,0xa2,0xe0,0xac,0xbc}}, - {{0xe0,0xad,0x9f}, {0xe0,0xac,0xaf,0xe0,0xac,0xbc}}, - {{0xe0,0xad,0x8b}, {0xe0,0xad,0x87,0xe0,0xac,0xbe}}, - {{0xe0,0xad,0x88}, {0xe0,0xad,0x87,0xe0,0xad,0x96}}, - {{0xe0,0xad,0x8c}, {0xe0,0xad,0x87,0xe0,0xad,0x97}}, - {{0xe0,0xae,0x94}, {0xe0,0xae,0x92,0xe0,0xaf,0x97}}, - {{0xe0,0xaf,0x8a}, {0xe0,0xaf,0x86,0xe0,0xae,0xbe}}, - {{0xe0,0xaf,0x8c}, {0xe0,0xaf,0x86,0xe0,0xaf,0x97}}, - {{0xe0,0xaf,0x8b}, {0xe0,0xaf,0x87,0xe0,0xae,0xbe}}, - {{0xe0,0xb1,0x88}, {0xe0,0xb1,0x86,0xe0,0xb1,0x96}}, - {{0xe0,0xb3,0x80}, {0xe0,0xb2,0xbf,0xe0,0xb3,0x95}}, - {{0xe0,0xb3,0x8a}, {0xe0,0xb3,0x86,0xe0,0xb3,0x82}}, - {{0xe0,0xb3,0x8b}, {0xe0,0xb3,0x86,0xe0,0xb3,0x82,0xe0,0xb3,0x95}}, - {{0xe0,0xb3,0x87}, {0xe0,0xb3,0x86,0xe0,0xb3,0x95}}, - {{0xe0,0xb3,0x88}, {0xe0,0xb3,0x86,0xe0,0xb3,0x96}}, - {{0xe0,0xb5,0x8a}, {0xe0,0xb5,0x86,0xe0,0xb4,0xbe}}, - {{0xe0,0xb5,0x8c}, {0xe0,0xb5,0x86,0xe0,0xb5,0x97}}, - {{0xe0,0xb5,0x8b}, {0xe0,0xb5,0x87,0xe0,0xb4,0xbe}}, - {{0xe0,0xb8,0xb3}, {0xe0,0xb9,0x8d,0xe0,0xb8,0xb2}}, - {{0xe0,0xba,0xb3}, {0xe0,0xbb,0x8d,0xe0,0xba,0xb2}}, - {{0xe0,0xbd,0xa9}, {0xe0,0xbd,0x80,0xe0,0xbe,0xb5}}, - {{0xe0,0xbd,0x83}, {0xe0,0xbd,0x82,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0x8d}, {0xe0,0xbd,0x8c,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0x92}, {0xe0,0xbd,0x91,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0x97}, {0xe0,0xbd,0x96,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0x9c}, {0xe0,0xbd,0x9b,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0xb3}, {0xe0,0xbd,0xb2,0xe0,0xbd,0xb1}}, - {{0xe0,0xbd,0xb5}, {0xe0,0xbd,0xb4,0xe0,0xbd,0xb1}}, - {{0xe0,0xbe,0x81}, {0xe0,0xbe,0x80,0xe0,0xbd,0xb1}}, - {{0xe0,0xbe,0xb9}, {0xe0,0xbe,0x90,0xe0,0xbe,0xb5}}, - {{0xe0,0xbe,0x93}, {0xe0,0xbe,0x92,0xe0,0xbe,0xb7}}, - {{0xe0,0xbe,0x9d}, {0xe0,0xbe,0x9c,0xe0,0xbe,0xb7}}, - {{0xe0,0xbe,0xa2}, {0xe0,0xbe,0xa1,0xe0,0xbe,0xb7}}, - {{0xe0,0xbe,0xa7}, {0xe0,0xbe,0xa6,0xe0,0xbe,0xb7}}, - {{0xe0,0xbe,0xac}, {0xe0,0xbe,0xab,0xe0,0xbe,0xb7}}, - {{0xe0,0xbd,0xb6}, {0xe0,0xbe,0xb2,0xe0,0xbe,0x80}}, - {{0xe0,0xbd,0xb7}, {0xe0,0xbe,0xb2,0xe0,0xbe,0x80,0xe0,0xbd,0xb1}}, - {{0xe0,0xbd,0xb8}, {0xe0,0xbe,0xb3,0xe0,0xbe,0x80}}, - {{0xe0,0xbd,0xb9}, {0xe0,0xbe,0xb3,0xe0,0xbe,0x80,0xe0,0xbd,0xb1}}, - {{0xe1,0xbf,0x8d}, {0xe1,0xbe,0xbf,0xcc,0x80}}, - {{0xe1,0xbf,0x8e}, {0xe1,0xbe,0xbf,0xcc,0x81}}, - {{0xe1,0xbf,0x8f}, {0xe1,0xbe,0xbf,0xcd,0x82}}, - {{0xe1,0xbf,0x9d}, {0xe1,0xbf,0xbe,0xcc,0x80}}, - {{0xe1,0xbf,0x9e}, {0xe1,0xbf,0xbe,0xcc,0x81}}, - {{0xe1,0xbf,0x9f}, {0xe1,0xbf,0xbe,0xcd,0x82}}, - {{0xe3,0x82,0x94}, {0xe3,0x81,0x86,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x8c}, {0xe3,0x81,0x8b,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x8e}, {0xe3,0x81,0x8d,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x90}, {0xe3,0x81,0x8f,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x92}, {0xe3,0x81,0x91,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x94}, {0xe3,0x81,0x93,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x96}, {0xe3,0x81,0x95,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x98}, {0xe3,0x81,0x97,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x9a}, {0xe3,0x81,0x99,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x9c}, {0xe3,0x81,0x9b,0xe3,0x82,0x99}}, - {{0xe3,0x81,0x9e}, {0xe3,0x81,0x9d,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xa0}, {0xe3,0x81,0x9f,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xa2}, {0xe3,0x81,0xa1,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xa5}, {0xe3,0x81,0xa4,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xa7}, {0xe3,0x81,0xa6,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xa9}, {0xe3,0x81,0xa8,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xb0}, {0xe3,0x81,0xaf,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xb1}, {0xe3,0x81,0xaf,0xe3,0x82,0x9a}}, - {{0xe3,0x81,0xb3}, {0xe3,0x81,0xb2,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xb4}, {0xe3,0x81,0xb2,0xe3,0x82,0x9a}}, - {{0xe3,0x81,0xb6}, {0xe3,0x81,0xb5,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xb7}, {0xe3,0x81,0xb5,0xe3,0x82,0x9a}}, - {{0xe3,0x81,0xb9}, {0xe3,0x81,0xb8,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xba}, {0xe3,0x81,0xb8,0xe3,0x82,0x9a}}, - {{0xe3,0x81,0xbc}, {0xe3,0x81,0xbb,0xe3,0x82,0x99}}, - {{0xe3,0x81,0xbd}, {0xe3,0x81,0xbb,0xe3,0x82,0x9a}}, - {{0xe3,0x82,0x9e}, {0xe3,0x82,0x9d,0xe3,0x82,0x99}}, - {{0xe3,0x83,0xb4}, {0xe3,0x82,0xa6,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xac}, {0xe3,0x82,0xab,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xae}, {0xe3,0x82,0xad,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xb0}, {0xe3,0x82,0xaf,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xb2}, {0xe3,0x82,0xb1,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xb4}, {0xe3,0x82,0xb3,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xb6}, {0xe3,0x82,0xb5,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xb8}, {0xe3,0x82,0xb7,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xba}, {0xe3,0x82,0xb9,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xbc}, {0xe3,0x82,0xbb,0xe3,0x82,0x99}}, - {{0xe3,0x82,0xbe}, {0xe3,0x82,0xbd,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x80}, {0xe3,0x82,0xbf,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x82}, {0xe3,0x83,0x81,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x85}, {0xe3,0x83,0x84,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x87}, {0xe3,0x83,0x86,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x89}, {0xe3,0x83,0x88,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x90}, {0xe3,0x83,0x8f,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x91}, {0xe3,0x83,0x8f,0xe3,0x82,0x9a}}, - {{0xe3,0x83,0x93}, {0xe3,0x83,0x92,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x94}, {0xe3,0x83,0x92,0xe3,0x82,0x9a}}, - {{0xe3,0x83,0x96}, {0xe3,0x83,0x95,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x97}, {0xe3,0x83,0x95,0xe3,0x82,0x9a}}, - {{0xe3,0x83,0x99}, {0xe3,0x83,0x98,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x9a}, {0xe3,0x83,0x98,0xe3,0x82,0x9a}}, - {{0xe3,0x83,0x9c}, {0xe3,0x83,0x9b,0xe3,0x82,0x99}}, - {{0xe3,0x83,0x9d}, {0xe3,0x83,0x9b,0xe3,0x82,0x9a}}, - {{0xe3,0x83,0xb7}, {0xe3,0x83,0xaf,0xe3,0x82,0x99}}, - {{0xe3,0x83,0xb8}, {0xe3,0x83,0xb0,0xe3,0x82,0x99}}, - {{0xe3,0x83,0xb9}, {0xe3,0x83,0xb1,0xe3,0x82,0x99}}, - {{0xe3,0x83,0xba}, {0xe3,0x83,0xb2,0xe3,0x82,0x99}}, - {{0xe3,0x83,0xbe}, {0xe3,0x83,0xbd,0xe3,0x82,0x99}}, -}; -#endif /* UNICODE_NORMALIZATION */ -#endif /* UTF8_INPUT_ENABLE */ - -#ifdef SHIFTJIS_CP932 -const unsigned short shiftjis_cp932[3][189] = { - { - 0xEEEF, 0xEEF0, 0xEEF1, 0xEEF2, 0xEEF3, 0xEEF4, 0xEEF5, 0xEEF6, - 0xEEF7, 0xEEF8, 0x8754, 0x8755, 0x8756, 0x8757, 0x8758, 0x8759, - 0x875A, 0x875B, 0x875C, 0x875D, 0x81CA, 0xEEFA, 0xEEFB, 0xEEFC, - 0x878A, 0x8782, 0x8784, 0x81E6, 0xED40, 0xED41, 0xED42, 0xED43, - 0xED44, 0xED45, 0xED46, 0xED47, 0xED48, 0xED49, 0xED4A, 0xED4B, - 0xED4C, 0xED4D, 0xED4E, 0xED4F, 0xED50, 0xED51, 0xED52, 0xED53, - 0xED54, 0xED55, 0xED56, 0xED57, 0xED58, 0xED59, 0xED5A, 0xED5B, - 0xED5C, 0xED5D, 0xED5E, 0xED5F, 0xED60, 0xED61, 0xED62, 0, - 0xED63, 0xED64, 0xED65, 0xED66, 0xED67, 0xED68, 0xED69, 0xED6A, - 0xED6B, 0xED6C, 0xED6D, 0xED6E, 0xED6F, 0xED70, 0xED71, 0xED72, - 0xED73, 0xED74, 0xED75, 0xED76, 0xED77, 0xED78, 0xED79, 0xED7A, - 0xED7B, 0xED7C, 0xED7D, 0xED7E, 0xED80, 0xED81, 0xED82, 0xED83, - 0xED84, 0xED85, 0xED86, 0xED87, 0xED88, 0xED89, 0xED8A, 0xED8B, - 0xED8C, 0xED8D, 0xED8E, 0xED8F, 0xED90, 0xED91, 0xED92, 0xED93, - 0xED94, 0xED95, 0xED96, 0xED97, 0xED98, 0xED99, 0xED9A, 0xED9B, - 0xED9C, 0xED9D, 0xED9E, 0xED9F, 0xEDA0, 0xEDA1, 0xEDA2, 0xEDA3, - 0xEDA4, 0xEDA5, 0xEDA6, 0xEDA7, 0xEDA8, 0xEDA9, 0xEDAA, 0xEDAB, - 0xEDAC, 0xEDAD, 0xEDAE, 0xEDAF, 0xEDB0, 0xEDB1, 0xEDB2, 0xEDB3, - 0xEDB4, 0xEDB5, 0xEDB6, 0xEDB7, 0xEDB8, 0xEDB9, 0xEDBA, 0xEDBB, - 0xEDBC, 0xEDBD, 0xEDBE, 0xEDBF, 0xEDC0, 0xEDC1, 0xEDC2, 0xEDC3, - 0xEDC4, 0xEDC5, 0xEDC6, 0xEDC7, 0xEDC8, 0xEDC9, 0xEDCA, 0xEDCB, - 0xEDCC, 0xEDCD, 0xEDCE, 0xEDCF, 0xEDD0, 0xEDD1, 0xEDD2, 0xEDD3, - 0xEDD4, 0xEDD5, 0xEDD6, 0xEDD7, 0xEDD8, 0xEDD9, 0xEDDA, 0xEDDB, - 0xEDDC, 0xEDDD, 0xEDDE, 0xEDDF, 0xEDE0, - }, - { - 0xEDE1, 0xEDE2, 0xEDE3, 0xEDE4, 0xEDE5, 0xEDE6, 0xEDE7, 0xEDE8, - 0xEDE9, 0xEDEA, 0xEDEB, 0xEDEC, 0xEDED, 0xEDEE, 0xEDEF, 0xEDF0, - 0xEDF1, 0xEDF2, 0xEDF3, 0xEDF4, 0xEDF5, 0xEDF6, 0xEDF7, 0xEDF8, - 0xEDF9, 0xEDFA, 0xEDFB, 0xEDFC, 0xEE40, 0xEE41, 0xEE42, 0xEE43, - 0xEE44, 0xEE45, 0xEE46, 0xEE47, 0xEE48, 0xEE49, 0xEE4A, 0xEE4B, - 0xEE4C, 0xEE4D, 0xEE4E, 0xEE4F, 0xEE50, 0xEE51, 0xEE52, 0xEE53, - 0xEE54, 0xEE55, 0xEE56, 0xEE57, 0xEE58, 0xEE59, 0xEE5A, 0xEE5B, - 0xEE5C, 0xEE5D, 0xEE5E, 0xEE5F, 0xEE60, 0xEE61, 0xEE62, 0, - 0xEE63, 0xEE64, 0xEE65, 0xEE66, 0xEE67, 0xEE68, 0xEE69, 0xEE6A, - 0xEE6B, 0xEE6C, 0xEE6D, 0xEE6E, 0xEE6F, 0xEE70, 0xEE71, 0xEE72, - 0xEE73, 0xEE74, 0xEE75, 0xEE76, 0xEE77, 0xEE78, 0xEE79, 0xEE7A, - 0xEE7B, 0xEE7C, 0xEE7D, 0xEE7E, 0xEE80, 0xEE81, 0xEE82, 0xEE83, - 0xEE84, 0xEE85, 0xEE86, 0xEE87, 0xEE88, 0xEE89, 0xEE8A, 0xEE8B, - 0xEE8C, 0xEE8D, 0xEE8E, 0xEE8F, 0xEE90, 0xEE91, 0xEE92, 0xEE93, - 0xEE94, 0xEE95, 0xEE96, 0xEE97, 0xEE98, 0xEE99, 0xEE9A, 0xEE9B, - 0xEE9C, 0xEE9D, 0xEE9E, 0xEE9F, 0xEEA0, 0xEEA1, 0xEEA2, 0xEEA3, - 0xEEA4, 0xEEA5, 0xEEA6, 0xEEA7, 0xEEA8, 0xEEA9, 0xEEAA, 0xEEAB, - 0xEEAC, 0xEEAD, 0xEEAE, 0xEEAF, 0xEEB0, 0xEEB1, 0xEEB2, 0xEEB3, - 0xEEB4, 0xEEB5, 0xEEB6, 0xEEB7, 0xEEB8, 0xEEB9, 0xEEBA, 0xEEBB, - 0xEEBC, 0xEEBD, 0xEEBE, 0xEEBF, 0xEEC0, 0xEEC1, 0xEEC2, 0xEEC3, - 0xEEC4, 0xEEC5, 0xEEC6, 0xEEC7, 0xEEC8, 0xEEC9, 0xEECA, 0xEECB, - 0xEECC, 0xEECD, 0xEECE, 0xEECF, 0xEED0, 0xEED1, 0xEED2, 0xEED3, - 0xEED4, 0xEED5, 0xEED6, 0xEED7, 0xEED8, 0xEED9, 0xEEDA, 0xEEDB, - 0xEEDC, 0xEEDD, 0xEEDE, 0xEEDF, 0xEEE0, - }, - { - 0xEEE1, 0xEEE2, 0xEEE3, 0xEEE4, 0xEEE5, 0xEEE6, 0xEEE7, 0xEEE8, - 0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, -}; -const unsigned short cp932inv[2][189] = { - { - 0xFA5C, 0xFA5D, 0xFA5E, 0xFA5F, 0xFA60, 0xFA61, 0xFA62, 0xFA63, - 0xFA64, 0xFA65, 0xFA66, 0xFA67, 0xFA68, 0xFA69, 0xFA6A, 0xFA6B, - 0xFA6C, 0xFA6D, 0xFA6E, 0xFA6F, 0xFA70, 0xFA71, 0xFA72, 0xFA73, - 0xFA74, 0xFA75, 0xFA76, 0xFA77, 0xFA78, 0xFA79, 0xFA7A, 0xFA7B, - 0xFA7C, 0xFA7D, 0xFA7E, 0xFA80, 0xFA81, 0xFA82, 0xFA83, 0xFA84, - 0xFA85, 0xFA86, 0xFA87, 0xFA88, 0xFA89, 0xFA8A, 0xFA8B, 0xFA8C, - 0xFA8D, 0xFA8E, 0xFA8F, 0xFA90, 0xFA91, 0xFA92, 0xFA93, 0xFA94, - 0xFA95, 0xFA96, 0xFA97, 0xFA98, 0xFA99, 0xFA9A, 0xFA9B, 0, - 0xFA9C, 0xFA9D, 0xFA9E, 0xFA9F, 0xFAA0, 0xFAA1, 0xFAA2, 0xFAA3, - 0xFAA4, 0xFAA5, 0xFAA6, 0xFAA7, 0xFAA8, 0xFAA9, 0xFAAA, 0xFAAB, - 0xFAAC, 0xFAAD, 0xFAAE, 0xFAAF, 0xFAB0, 0xFAB1, 0xFAB2, 0xFAB3, - 0xFAB4, 0xFAB5, 0xFAB6, 0xFAB7, 0xFAB8, 0xFAB9, 0xFABA, 0xFABB, - 0xFABC, 0xFABD, 0xFABE, 0xFABF, 0xFAC0, 0xFAC1, 0xFAC2, 0xFAC3, - 0xFAC4, 0xFAC5, 0xFAC6, 0xFAC7, 0xFAC8, 0xFAC9, 0xFACA, 0xFACB, - 0xFACC, 0xFACD, 0xFACE, 0xFACF, 0xFAD0, 0xFAD1, 0xFAD2, 0xFAD3, - 0xFAD4, 0xFAD5, 0xFAD6, 0xFAD7, 0xFAD8, 0xFAD9, 0xFADA, 0xFADB, - 0xFADC, 0xFADD, 0xFADE, 0xFADF, 0xFAE0, 0xFAE1, 0xFAE2, 0xFAE3, - 0xFAE4, 0xFAE5, 0xFAE6, 0xFAE7, 0xFAE8, 0xFAE9, 0xFAEA, 0xFAEB, - 0xFAEC, 0xFAED, 0xFAEE, 0xFAEF, 0xFAF0, 0xFAF1, 0xFAF2, 0xFAF3, - 0xFAF4, 0xFAF5, 0xFAF6, 0xFAF7, 0xFAF8, 0xFAF9, 0xFAFA, 0xFAFB, - 0xFAFC, 0xFB40, 0xFB41, 0xFB42, 0xFB43, 0xFB44, 0xFB45, 0xFB46, - 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, 0xFB4D, 0xFB4E, - 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55, 0xFB56, - 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, - }, - { - 0xFB5C, 0xFB5D, 0xFB5E, 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, - 0xFB64, 0xFB65, 0xFB66, 0xFB67, 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, - 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, 0xFB71, 0xFB72, 0xFB73, - 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, 0xFB7A, 0xFB7B, - 0xFB7C, 0xFB7D, 0xFB7E, 0xFB80, 0xFB81, 0xFB82, 0xFB83, 0xFB84, - 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, 0xFB8C, - 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94, - 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0, - 0xFB9C, 0xFB9D, 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, - 0xFBA4, 0xFBA5, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, - 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, - 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, 0xFBB9, 0xFBBA, 0xFBBB, - 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, 0xFBC2, 0xFBC3, - 0xFBC4, 0xFBC5, 0xFBC6, 0xFBC7, 0xFBC8, 0xFBC9, 0xFBCA, 0xFBCB, - 0xFBCC, 0xFBCD, 0xFBCE, 0xFBCF, 0xFBD0, 0xFBD1, 0xFBD2, 0xFBD3, - 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB, - 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, - 0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, - 0xFBEC, 0xFBED, 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, - 0xFBF4, 0xFBF5, 0xFBF6, 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, - 0xFBFC, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, - 0xFC47, 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0, 0, 0xFA40, - 0xFA41, 0xFA42, 0xFA43, 0xFA44, 0xFA45, 0xFA46, 0xFA47, 0xFA48, - 0xFA49, 0x81CA, 0xFA55, 0xFA56, 0xFA57, - }, -}; -#endif /* SHIFTJIS_CP932 */ - -#ifdef X0212_ENABLE -const unsigned short shiftjis_x0212[3][189] = { - { - 0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378, 0xF379, 0xF37A, - 0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF421, 0xF422, 0xF423, 0xF424, - 0xF425, 0xF426, 0xF427, 0xF428, 0x224C, 0xA243, 0xF429, 0xF42A, - 0xF42B, 0xF42C, 0xF42D, 0x2268, 0xD463, 0xDC5F, 0xE469, 0xE378, - 0xD921, 0xB13B, 0xF42E, 0xC22D, 0xC37C, 0xE450, 0xC23F, 0xBC74, - 0xB029, 0xB048, 0xF42F, 0xB052, 0xB054, 0xB063, 0xB06E, 0xB127, - 0xB123, 0xB12C, 0xB129, 0xB13E, 0xB15F, 0xB158, 0xB148, 0xB157, - 0xB163, 0xB174, 0xB161, 0xB223, 0xF430, 0xB23B, 0xB266, 0, - 0xB26D, 0xB275, 0xB27C, 0xF431, 0xB335, 0xB358, 0xB35B, 0xB365, - 0xB36E, 0xB37B, 0xF432, 0xF433, 0xB440, 0xB447, 0xB450, 0xB45E, - 0xF434, 0xB52A, 0xF435, 0xB52F, 0xB544, 0xB568, 0xF436, 0xB742, - 0xB764, 0xB768, 0xB767, 0xF437, 0xF438, 0xF439, 0xB84E, 0xB861, - 0xB875, 0xB877, 0xB878, 0xB87C, 0xB92F, 0xB937, 0xBA3E, 0xBA5B, - 0xCD2A, 0xBA61, 0xF43A, 0xBA6B, 0xBB33, 0xBB38, 0xF43B, 0xBB4A, - 0xF43C, 0xF43D, 0xBB50, 0xBB5E, 0xBB74, 0xBB75, 0xBB79, 0xBC64, - 0xBC6D, 0xBC7E, 0xF43E, 0xBD42, 0xBD67, 0xF43F, 0xBD70, 0xBE30, - 0xBE2C, 0xF440, 0xBE33, 0xBE3D, 0xBE4D, 0xBE49, 0xBE64, 0xBF28, - 0xBF49, 0xC044, 0xC064, 0xC074, 0xC126, 0xF441, 0xC175, 0xC17C, - 0xF442, 0xC178, 0xC22B, 0xC221, 0xC225, 0xF443, 0xC238, 0xC23A, - 0xF444, 0xC244, 0xC252, 0xC257, 0xC25B, 0xC25E, 0xC26D, 0xC270, - 0xF445, 0xC321, 0xC335, 0xC349, 0xC339, 0xF446, 0xC358, 0xC37E, - 0xF447, 0xC44C, 0xF448, 0xC459, 0xC46A, 0xC47D, 0xF449, 0xC527, - 0xC535, 0xC536, 0xF44A, 0xC555, 0xC638, 0xC657, 0xC660, 0xC66A, - 0xC663, 0xC721, 0xC72B, 0xC747, 0xC743, - }, - { - 0xC74B, 0xC74F, 0xC759, 0xF44B, 0xF44C, 0xC766, 0xC76E, 0xC77C, - 0xC76B, 0xC770, 0xC831, 0xC865, 0xC878, 0xC926, 0xC92B, 0xC92D, - 0xF44D, 0xC94A, 0xC953, 0xC969, 0xC963, 0xC97C, 0xC974, 0xC975, - 0xF44E, 0xCA33, 0xCA3D, 0xCA6F, 0xCA71, 0xCB2E, 0xF44F, 0xCB4A, - 0xCB66, 0xCB6A, 0xCB70, 0xCB74, 0xCB6E, 0xCC25, 0xCB79, 0xCC2B, - 0xCC2E, 0xCC2D, 0xCC32, 0xCC42, 0xCC50, 0xCC59, 0xF450, 0xCD3B, - 0xF451, 0xCE3B, 0xF452, 0xCE3A, 0xCE43, 0xF453, 0xCE72, 0xB35D, - 0xCF55, 0xCF62, 0xCF69, 0xCF6D, 0xF454, 0xF455, 0xF456, 0, - 0xF457, 0xD065, 0xF458, 0xD069, 0xD168, 0xF459, 0xF45A, 0xD16C, - 0xD23B, 0xF45B, 0xD361, 0xD368, 0xD427, 0xF45C, 0xF45D, 0xD454, - 0xD472, 0xD52E, 0xF45E, 0xD75E, 0xF45F, 0xD822, 0xD837, 0xD841, - 0xD851, 0xD874, 0xD946, 0xD948, 0xD951, 0xF460, 0xF461, 0xF462, - 0xF463, 0xF464, 0xDC53, 0xDD48, 0xDD54, 0xDD6A, 0xDD7A, 0xDE24, - 0xDE30, 0xF465, 0xDE35, 0xDE4B, 0xF466, 0xDF39, 0xF467, 0xDF43, - 0xF468, 0xF469, 0xE059, 0xF46A, 0xF46B, 0xE162, 0xF46C, 0xF46D, - 0xF46E, 0xE247, 0xE328, 0xE326, 0xE329, 0xE32F, 0xE330, 0xE32A, - 0xE32B, 0xE33C, 0xE341, 0xE33F, 0xE355, 0xE358, 0xE356, 0xE35F, - 0xE363, 0xE361, 0xE354, 0xE369, 0xE426, 0xE371, 0xE372, 0xE44B, - 0xE441, 0xE443, 0xE43E, 0xF46F, 0xE440, 0xE447, 0xE43F, 0xE460, - 0xE45E, 0xE451, 0xF470, 0xE45C, 0xE452, 0xE45B, 0xE454, 0xE47A, - 0xE46F, 0xE533, 0xE53F, 0xE549, 0xE550, 0xE562, 0xE56A, 0xE56B, - 0xF471, 0xF472, 0xF473, 0xE668, 0xE66F, 0xE72C, 0xF474, 0xE72E, - 0xF475, 0xE731, 0xF476, 0xE732, 0xE831, 0xE836, 0xF477, 0xF478, - 0xE85D, 0xF479, 0xF47A, 0xE951, 0xF47B, - }, - { - 0xE96D, 0xEA4D, 0xF47C, 0xEA5B, 0xEA66, 0xEA6A, 0xEB25, 0xEB7B, - 0xEB7A, 0xF47D, 0xEC56, 0xF47E, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, -}; - -static const unsigned short x0212_shiftjis_A2[] = { - 0x819F, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0x8143, 0, 0, 0x8150, 0, 0, 0x8160, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B0[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0xFA68, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA69, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFA6B, 0, 0xFA6C, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA6D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFA6E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B1[] = { - 0, 0, 0xFA70, 0, 0, 0, 0xFA6F, - 0, 0xFA72, 0, 0, 0xFA71, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA61, 0, 0, 0xFA73, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA76, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFA77, - 0xFA75, 0, 0, 0, 0, 0, 0, 0xFA74, - 0, 0xFA7A, 0, 0xFA78, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFA79, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B2[] = { - 0, 0, 0xFA7B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA7D, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFA7E, 0, - 0, 0, 0, 0, 0, 0xFA80, 0, 0, - 0, 0, 0, 0, 0, 0xFA81, 0, 0, - 0, 0, 0, 0, 0xFA82, 0, 0, -}; -static const unsigned short x0212_shiftjis_B3[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFA84, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA85, 0, 0, 0xFA86, 0, 0xFB77, 0, 0, - 0, 0, 0, 0, 0, 0xFA87, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFA88, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA89, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B4[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA8C, 0, 0, 0, 0, 0, 0, 0xFA8D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA8E, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFA8F, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B5[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFA91, 0, 0, 0, 0, 0xFA93, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFA94, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFA95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B7[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFA97, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFA98, 0, 0, 0xFA9A, - 0xFA99, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_B8[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFA9E, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFA9F, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAA0, 0, 0xFAA1, - 0xFAA2, 0, 0, 0, 0xFAA3, 0, 0, -}; -static const unsigned short x0212_shiftjis_B9[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFAA4, - 0, 0, 0, 0, 0, 0, 0, 0xFAA5, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_BA[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFAA6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFAA7, 0, 0, 0, 0, - 0, 0xFAA9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFAAB, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_BB[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFAAC, 0, 0, 0, 0, - 0xFAAD, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFAAF, 0, 0, 0, 0, 0, - 0xFAB2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFAB3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAB4, 0xFAB5, 0, 0, - 0, 0xFAB6, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_BC[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAB7, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAB8, 0, 0, - 0, 0, 0, 0, 0xFA67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFAB9, -}; -static const unsigned short x0212_shiftjis_BD[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFABB, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFABC, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFABE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_BE[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAC0, 0, 0, 0, - 0xFABF, 0, 0, 0xFAC2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAC3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFAC5, 0, 0, 0, 0xFAC4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAC6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_BF[] = { - 0, 0, 0, 0, 0, 0, 0, - 0xFAC7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFAC8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C0[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAC9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFACA, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFACB, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C1[] = { - 0, 0, 0, 0, 0, 0xFACC, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFACE, 0, 0, - 0xFAD1, 0, 0, 0, 0xFACF, 0, 0, -}; -static const unsigned short x0212_shiftjis_C2[] = { - 0xFAD3, 0, 0, 0, 0xFAD4, 0, 0, - 0, 0, 0, 0xFAD2, 0, 0xFA63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFAD6, 0, 0xFAD7, 0, 0, 0, 0, 0xFA66, - 0, 0, 0, 0, 0xFAD9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFADA, 0, 0, 0, 0, 0xFADB, - 0, 0, 0, 0xFADC, 0, 0, 0xFADD, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFADE, 0, 0, - 0xFADF, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C3[] = { - 0xFAE1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAE2, 0, 0, - 0, 0xFAE4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFAE3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFAE6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFA64, 0, 0xFAE7, -}; -static const unsigned short x0212_shiftjis_C4[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFAE9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFAEB, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFAEC, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAED, 0, -}; -static const unsigned short x0212_shiftjis_C5[] = { - 0, 0, 0, 0, 0, 0, 0xFAEF, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAF0, 0xFAF1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFAF3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C6[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFAF4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFAF5, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFAF6, 0, 0, 0xFAF8, 0, 0, 0, 0, - 0, 0, 0xFAF7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C7[] = { - 0xFAF9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFAFA, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFAFC, 0, 0, 0, 0xFAFB, - 0, 0, 0, 0xFB40, 0, 0, 0, 0xFB41, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB42, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB45, 0, - 0, 0, 0, 0xFB48, 0, 0, 0xFB46, 0, - 0xFB49, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFB47, 0, 0, -}; -static const unsigned short x0212_shiftjis_C8[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB4A, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFB4B, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFB4C, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_C9[] = { - 0, 0, 0, 0, 0, 0xFB4D, 0, - 0, 0, 0, 0xFB4E, 0, 0xFB4F, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB51, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFB52, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFB54, 0, 0, 0, 0, - 0, 0xFB53, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFB56, 0xFB57, 0, 0, - 0, 0, 0, 0, 0xFB55, 0, 0, -}; -static const unsigned short x0212_shiftjis_CA[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFB59, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFB5A, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFB5B, - 0, 0xFB5C, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_CB[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB5D, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB5F, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB60, 0, - 0, 0, 0xFB61, 0, 0, 0, 0xFB64, 0, - 0xFB62, 0, 0, 0, 0xFB63, 0, 0, 0, - 0, 0xFB66, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_CC[] = { - 0, 0, 0, 0, 0xFB65, 0, 0, - 0, 0, 0, 0xFB67, 0, 0xFB69, 0xFB68, 0, - 0, 0, 0xFB6A, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB6B, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFB6C, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB6D, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_CD[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFAA8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFB6F, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_CE[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB73, 0xFB71, 0, 0, 0, 0, - 0, 0, 0, 0xFB74, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB76, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_CF[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFB78, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB79, 0, 0, 0, 0, 0, - 0, 0xFB7A, 0, 0, 0, 0xFB7B, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D0[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFB81, 0, 0, - 0, 0xFB83, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D1[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFB84, 0, 0, 0, 0xFB87, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D2[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFB88, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D3[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB8A, 0, 0, 0, 0, 0, 0, - 0xFB8B, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D4[] = { - 0, 0, 0, 0, 0, 0, 0xFB8C, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFB8F, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA5C, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFB90, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D5[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB91, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D7[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB93, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D8[] = { - 0, 0xFB95, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFB96, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB97, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB98, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFB99, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_D9[] = { - 0xFA60, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFB9A, 0, - 0xFB9B, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFB9C, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_DC[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFBA2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFA5D, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_DD[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFBA3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFBA4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFBA5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFBA6, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_DE[] = { - 0, 0, 0, 0xFBA7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFBA8, 0, 0, 0, 0, 0xFBAA, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFBAB, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_DF[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFBAD, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFBAF, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E0[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFBB2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E1[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFBB5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E2[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFBB9, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E3[] = { - 0, 0, 0, 0, 0, 0xFBBB, 0, - 0xFBBA, 0xFBBC, 0xFBBF, 0xFBC0, 0, 0, 0, 0xFBBD, - 0xFBBE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFBC1, 0, 0, 0xFBC3, - 0, 0xFBC2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFBCA, 0xFBC4, 0xFBC6, 0, - 0xFBC5, 0, 0, 0, 0, 0, 0, 0xFBC7, - 0, 0xFBC9, 0, 0xFBC8, 0, 0, 0, 0, - 0, 0xFBCB, 0, 0, 0, 0, 0, 0, - 0, 0xFBCD, 0xFBCE, 0, 0, 0, 0, 0, - 0xFA5F, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E4[] = { - 0, 0, 0, 0, 0, 0xFBCC, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFBD2, 0xFBD6, - 0xFBD4, 0xFBD0, 0, 0xFBD1, 0, 0, 0, 0xFBD5, - 0, 0, 0, 0xFBCF, 0, 0, 0, 0, - 0xFA65, 0xFBD9, 0xFBDC, 0, 0xFBDE, 0, 0, 0, - 0, 0, 0, 0xFBDD, 0xFBDB, 0, 0xFBD8, 0, - 0xFBD7, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFA5E, 0, 0, 0, 0, 0, 0xFBE0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFBDF, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E5[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFBE1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFBE2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFBE3, 0, 0, 0, 0, 0, 0, - 0xFBE4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFBE5, 0, 0, 0, 0, 0, - 0, 0, 0xFBE6, 0xFBE7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E6[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFBEB, 0, 0, 0, 0, 0, 0, 0xFBEC, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E7[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFBED, 0, 0xFBEF, 0, - 0, 0xFBF1, 0xFBF3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E8[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFBF4, 0, 0, 0, 0, 0xFBF5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFBF8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_E9[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xFBFB, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFC40, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_EA[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0xFC41, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFC43, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFC44, 0, - 0, 0, 0xFC45, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_EB[] = { - 0, 0, 0, 0, 0xFC46, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFC48, 0xFC47, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_EC[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xFC4A, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -}; -static const unsigned short x0212_shiftjis_F3[] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFA40, 0xFA41, 0xFA42, 0xFA43, 0xFA44, - 0xFA45, 0xFA46, 0xFA47, 0xFA48, 0xFA49, 0xFA4A, 0xFA4B, -}; -static const unsigned short x0212_shiftjis_F4[] = { - 0xFA4C, 0xFA4D, 0xFA4E, 0xFA4F, 0xFA50, 0xFA51, 0xFA52, - 0xFA53, 0xFA56, 0xFA57, 0xFA58, 0xFA59, 0xFA5A, 0xFA62, 0xFA6A, - 0xFA7C, 0xFA83, 0xFA8A, 0xFA8B, 0xFA90, 0xFA92, 0xFA96, 0xFA9B, - 0xFA9C, 0xFA9D, 0xFAAA, 0xFAAE, 0xFAB0, 0xFAB1, 0xFABA, 0xFABD, - 0xFAC1, 0xFACD, 0xFAD0, 0xFAD5, 0xFAD8, 0xFAE0, 0xFAE5, 0xFAE8, - 0xFAEA, 0xFAEE, 0xFAF2, 0xFB43, 0xFB44, 0xFB50, 0xFB58, 0xFB5E, - 0xFB6E, 0xFB70, 0xFB72, 0xFB75, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB80, - 0xFB82, 0xFB85, 0xFB86, 0xFB89, 0xFB8D, 0xFB8E, 0xFB92, 0xFB94, - 0xFB9D, 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA9, 0xFBAC, 0xFBAE, - 0xFBB0, 0xFBB1, 0xFBB3, 0xFBB4, 0xFBB6, 0xFBB7, 0xFBB8, 0xFBD3, - 0xFBDA, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEE, 0xFBF0, 0xFBF2, 0xFBF6, - 0xFBF7, 0xFBF9, 0xFBFA, 0xFBFC, 0xFC42, 0xFC49, 0xFC4B, -}; -const unsigned short *const x0212_shiftjis[] = { - 0, x0212_shiftjis_A2, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - x0212_shiftjis_B0, x0212_shiftjis_B1, x0212_shiftjis_B2, x0212_shiftjis_B3, - x0212_shiftjis_B4, x0212_shiftjis_B5, 0, x0212_shiftjis_B7, - x0212_shiftjis_B8, x0212_shiftjis_B9, x0212_shiftjis_BA, x0212_shiftjis_BB, - x0212_shiftjis_BC, x0212_shiftjis_BD, x0212_shiftjis_BE, x0212_shiftjis_BF, - x0212_shiftjis_C0, x0212_shiftjis_C1, x0212_shiftjis_C2, x0212_shiftjis_C3, - x0212_shiftjis_C4, x0212_shiftjis_C5, x0212_shiftjis_C6, x0212_shiftjis_C7, - x0212_shiftjis_C8, x0212_shiftjis_C9, x0212_shiftjis_CA, x0212_shiftjis_CB, - x0212_shiftjis_CC, x0212_shiftjis_CD, x0212_shiftjis_CE, x0212_shiftjis_CF, - x0212_shiftjis_D0, x0212_shiftjis_D1, x0212_shiftjis_D2, x0212_shiftjis_D3, - x0212_shiftjis_D4, x0212_shiftjis_D5, 0, x0212_shiftjis_D7, - x0212_shiftjis_D8, x0212_shiftjis_D9, 0, 0, - x0212_shiftjis_DC, x0212_shiftjis_DD, x0212_shiftjis_DE, x0212_shiftjis_DF, - x0212_shiftjis_E0, x0212_shiftjis_E1, x0212_shiftjis_E2, x0212_shiftjis_E3, - x0212_shiftjis_E4, x0212_shiftjis_E5, x0212_shiftjis_E6, x0212_shiftjis_E7, - x0212_shiftjis_E8, x0212_shiftjis_E9, x0212_shiftjis_EA, x0212_shiftjis_EB, - x0212_shiftjis_EC, 0, 0, 0, - 0, 0, 0, x0212_shiftjis_F3, - x0212_shiftjis_F4, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, -}; -#endif /* X0212_ENABLE */ diff --git a/ext/nkf/nkf-utf8/utf8tbl.h b/ext/nkf/nkf-utf8/utf8tbl.h deleted file mode 100644 index 54a34271dd..0000000000 --- a/ext/nkf/nkf-utf8/utf8tbl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * utf8tbl.h - Header file for Conversion Table - * - */ - -#ifndef _UTF8TBL_H_ -#define _UTF8TBL_H_ - -#ifdef UTF8_OUTPUT_ENABLE -#define sizeof_euc_to_utf8_1byte 94 -#define sizeof_euc_to_utf8_2bytes 94 -extern const unsigned short euc_to_utf8_1byte[]; -extern const unsigned short *const euc_to_utf8_2bytes[]; -extern const unsigned short *const euc_to_utf8_2bytes_ms[]; -extern const unsigned short *const euc_to_utf8_2bytes_mac[]; -extern const unsigned short *const euc_to_utf8_2bytes_x0213[]; -extern const unsigned short *const x0212_to_utf8_2bytes[]; -extern const unsigned short *const x0212_to_utf8_2bytes_x0213[]; -#define sizeof_x0213_combining_chars 5 -#define sizeof_x0213_combining_table 25 -#define sizeof_x0213_1_surrogate_table 26 -#define sizeof_x0213_2_surrogate_table 277 -extern const unsigned short x0213_combining_chars[sizeof_x0213_combining_chars]; -extern const unsigned short x0213_combining_table[sizeof_x0213_combining_table][3]; -extern const unsigned short x0213_1_surrogate_table[sizeof_x0213_1_surrogate_table][3]; -extern const unsigned short x0213_2_surrogate_table[sizeof_x0213_2_surrogate_table][3]; -#endif /* UTF8_OUTPUT_ENABLE */ - -#ifdef UTF8_INPUT_ENABLE -#define sizeof_utf8_to_euc_C2 64 -#define sizeof_utf8_to_euc_E5B8 64 -#define sizeof_utf8_to_euc_2bytes 112 -#define sizeof_utf8_to_euc_3bytes 16 -extern const unsigned short *const utf8_to_euc_2bytes[]; -extern const unsigned short *const utf8_to_euc_2bytes_ms[]; -extern const unsigned short *const utf8_to_euc_2bytes_932[]; -extern const unsigned short *const utf8_to_euc_2bytes_mac[]; -extern const unsigned short *const utf8_to_euc_2bytes_x0213[]; -extern const unsigned short *const *const utf8_to_euc_3bytes[]; -extern const unsigned short *const *const utf8_to_euc_3bytes_ms[]; -extern const unsigned short *const *const utf8_to_euc_3bytes_932[]; -extern const unsigned short *const *const utf8_to_euc_3bytes_mac[]; -extern const unsigned short *const *const utf8_to_euc_3bytes_x0213[]; -#endif /* UTF8_INPUT_ENABLE */ - -#ifdef UNICODE_NORMALIZATION - -#define NORMALIZATION_TABLE_LENGTH 942 -#define NORMALIZATION_TABLE_NFC_LENGTH 3 -#define NORMALIZATION_TABLE_NFD_LENGTH 9 -struct normalization_pair { - const unsigned char nfc[NORMALIZATION_TABLE_NFC_LENGTH]; - const unsigned char nfd[NORMALIZATION_TABLE_NFD_LENGTH]; -}; -extern const struct normalization_pair normalization_table[]; -#endif - -#ifdef SHIFTJIS_CP932 -#define CP932_TABLE_BEGIN 0xFA -#define CP932_TABLE_END 0xFC -extern const unsigned short shiftjis_cp932[3][189]; -#define CP932INV_TABLE_BEGIN 0xED -#define CP932INV_TABLE_END 0xEE -extern const unsigned short cp932inv[2][189]; -#endif /* SHIFTJIS_CP932 */ - -#ifdef X0212_ENABLE -extern const unsigned short shiftjis_x0212[3][189]; -extern const unsigned short *const x0212_shiftjis[]; -#endif /* X0212_ENABLE */ - -#endif diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c deleted file mode 100644 index 76f7648d1b..0000000000 --- a/ext/nkf/nkf.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * NKF - Ruby extension for Network Kanji Filter - * - * original nkf2.x is maintained at http://sourceforge.jp/projects/nkf/ - * - * $Id$ - * - */ - -#define RUBY_NKF_REVISION "$Revision$" -#define RUBY_NKF_VERSION NKF_VERSION " (" NKF_RELEASE_DATE ")" - -#include "ruby/ruby.h" -#include "ruby/encoding.h" - -/* Replace nkf's getchar/putchar for variable modification */ -/* we never use getc, ungetc */ - -#undef getc -#undef ungetc -#define getc(f) (input_ctr>=i_len?-1:input[input_ctr++]) -#define ungetc(c,f) input_ctr-- - -#define INCSIZE 32 -#undef putchar -#undef TRUE -#undef FALSE -#define putchar(c) rb_nkf_putchar(c) - -/* Input/Output pointers */ - -static unsigned char *output; -static unsigned char *input; -static int input_ctr; -static int i_len; -static int output_ctr; -static int o_len; -static int incsize; - -static VALUE result; - -static int -rb_nkf_putchar(unsigned int c) -{ - if (output_ctr >= o_len) { - o_len += incsize; - rb_str_resize(result, o_len); - incsize *= 2; - output = (unsigned char *)RSTRING_PTR(result); - } - output[output_ctr++] = c; - - return c; -} - -/* Include kanji filter main part */ -/* getchar and putchar will be replaced during inclusion */ - -#define PERL_XS 1 -#include "nkf-utf8/config.h" -#include "nkf-utf8/utf8tbl.c" -#include "nkf-utf8/nkf.c" - -rb_encoding* rb_nkf_enc_get(const char *name) -{ - int idx = rb_enc_find_index(name); - if (idx < 0) { - nkf_encoding *nkf_enc = nkf_enc_find(name); - idx = rb_enc_find_index(nkf_enc_name(nkf_enc_to_base_encoding(nkf_enc))); - if (idx < 0) { - idx = rb_define_dummy_encoding(name); - } - } - return rb_enc_from_index(idx); -} - -int nkf_split_options(const char *arg) -{ - int count = 0; - unsigned char option[256]; - int i = 0, j = 0; - int is_escaped = FALSE; - int is_single_quoted = FALSE; - int is_double_quoted = FALSE; - for(i = 0; arg[i]; i++){ - if(j == 255){ - return -1; - }else if(is_single_quoted){ - if(arg[i] == '\''){ - is_single_quoted = FALSE; - }else{ - option[j++] = arg[i]; - } - }else if(is_escaped){ - is_escaped = FALSE; - option[j++] = arg[i]; - }else if(arg[i] == '\\'){ - is_escaped = TRUE; - }else if(is_double_quoted){ - if(arg[i] == '"'){ - is_double_quoted = FALSE; - }else{ - option[j++] = arg[i]; - } - }else if(arg[i] == '\''){ - is_single_quoted = TRUE; - }else if(arg[i] == '"'){ - is_double_quoted = TRUE; - }else if(arg[i] == ' '){ - option[j] = '\0'; - options(option); - j = 0; - }else{ - option[j++] = arg[i]; - } - } - if(j){ - option[j] = '\0'; - options(option); - } - return count; -} - -/* - * call-seq: - * NKF.nkf(opt, str) => string - * - * Convert _str_ and return converted result. - * Conversion details are specified by _opt_ as String. - * - * require 'nkf' - * output = NKF.nkf("-s", input) - */ - -static VALUE -rb_nkf_convert(VALUE obj, VALUE opt, VALUE src) -{ - VALUE tmp; - reinit(); - nkf_split_options(StringValueCStr(opt)); - if (!output_encoding) rb_raise(rb_eArgError, "no output encoding given"); - - switch (nkf_enc_to_index(output_encoding)) { - case UTF_8_BOM: output_encoding = nkf_enc_from_index(UTF_8); break; - case UTF_16BE_BOM: output_encoding = nkf_enc_from_index(UTF_16BE); break; - case UTF_16LE_BOM: output_encoding = nkf_enc_from_index(UTF_16LE); break; - case UTF_32BE_BOM: output_encoding = nkf_enc_from_index(UTF_32BE); break; - case UTF_32LE_BOM: output_encoding = nkf_enc_from_index(UTF_32LE); break; - } - output_bom_f = FALSE; - - incsize = INCSIZE; - - input_ctr = 0; - input = (unsigned char *)StringValuePtr(src); - i_len = RSTRING_LENINT(src); - tmp = rb_str_new(0, i_len*3 + 10); - - output_ctr = 0; - output = (unsigned char *)RSTRING_PTR(tmp); - o_len = RSTRING_LENINT(tmp); - *output = '\0'; - - /* use _result_ begin*/ - result = tmp; - kanji_convert(NULL); - result = Qnil; - /* use _result_ end */ - - rb_str_set_len(tmp, output_ctr); - - if (mimeout_f) - rb_enc_associate(tmp, rb_usascii_encoding()); - else - rb_enc_associate(tmp, rb_nkf_enc_get(nkf_enc_name(output_encoding))); - - return tmp; -} - - -/* - * call-seq: - * NKF.guess(str) => encoding - * - * Returns guessed encoding of _str_ by nkf routine. - * - */ - -static VALUE -rb_nkf_guess(VALUE obj, VALUE src) -{ - reinit(); - - input_ctr = 0; - input = (unsigned char *)StringValuePtr(src); - i_len = RSTRING_LENINT(src); - - guess_f = TRUE; - kanji_convert( NULL ); - guess_f = FALSE; - - return rb_enc_from_encoding(rb_nkf_enc_get(get_guessed_code())); -} - - -/* - * NKF - Ruby extension for Network Kanji Filter - * - * == Description - * - * This is a Ruby Extension version of nkf (Network Kanji Filter). - * It converts the first argument and returns converted result. Conversion - * details are specified by flags as the first argument. - * - * *Nkf* is a yet another kanji code converter among networks, hosts and terminals. - * It converts input kanji code to designated kanji code - * such as ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 or UTF-16. - * - * One of the most unique faculty of *nkf* is the guess of the input kanji encodings. - * It currently recognizes ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 and UTF-16. - * So users needn't set the input kanji code explicitly. - * - * By default, X0201 kana is converted into X0208 kana. - * For X0201 kana, SO/SI, SSO and ESC-(-I methods are supported. - * For automatic code detection, nkf assumes no X0201 kana in Shift_JIS. - * To accept X0201 in Shift_JIS, use <b>-X</b>, <b>-x</b> or <b>-S</b>. - * - * == Flags - * - * === -b -u - * - * Output is buffered (DEFAULT), Output is unbuffered. - * - * === -j -s -e -w -w16 -w32 - * - * Output code is ISO-2022-JP (7bit JIS), Shift_JIS, EUC-JP, - * UTF-8N, UTF-16BE, UTF-32BE. - * Without this option and compile option, ISO-2022-JP is assumed. - * - * === -J -S -E -W -W16 -W32 - * - * Input assumption is JIS 7 bit, Shift_JIS, EUC-JP, - * UTF-8, UTF-16, UTF-32. - * - * ==== -J - * - * Assume JIS input. It also accepts EUC-JP. - * This is the default. This flag does not exclude Shift_JIS. - * - * ==== -S - * - * Assume Shift_JIS and X0201 kana input. It also accepts JIS. - * EUC-JP is recognized as X0201 kana. Without <b>-x</b> flag, - * X0201 kana (halfwidth kana) is converted into X0208. - * - * ==== -E - * - * Assume EUC-JP input. It also accepts JIS. - * Same as -J. - * - * === -t - * - * No conversion. - * - * === -i_ - * - * Output sequence to designate JIS-kanji. (DEFAULT B) - * - * === -o_ - * - * Output sequence to designate ASCII. (DEFAULT B) - * - * === -r - * - * {de/en}crypt ROT13/47 - * - * === -h[123] --hiragana --katakana --katakana-hiragana - * - * [-h1 --hiragana] Katakana to Hiragana conversion. - * - * [-h2 --katakana] Hiragana to Katakana conversion. - * - * [-h3 --katakana-hiragana] Katakana to Hiragana and Hiragana to Katakana conversion. - * - * === -T - * - * Text mode output (MS-DOS) - * - * === -l - * - * ISO8859-1 (Latin-1) support - * - * === -f[<code>m</code> [- <code>n</code>]] - * - * Folding on <code>m</code> length with <code>n</code> margin in a line. - * Without this option, fold length is 60 and fold margin is 10. - * - * === -F - * - * New line preserving line folding. - * - * === -Z[0-3] - * - * Convert X0208 alphabet (Fullwidth Alphabets) to ASCII. - * - * [-Z -Z0] Convert X0208 alphabet to ASCII. - * - * [-Z1] Converts X0208 kankaku to single ASCII space. - * - * [-Z2] Converts X0208 kankaku to double ASCII spaces. - * - * [-Z3] Replacing Fullwidth >, <, ", & into '>', '<', '"', '&' as in HTML. - * - * === -X -x - * - * Assume X0201 kana in MS-Kanji. - * With <b>-X</b> or without this option, X0201 is converted into X0208 Kana. - * With <b>-x</b>, try to preserve X0208 kana and do not convert X0201 kana to X0208. - * In JIS output, ESC-(-I is used. In EUC output, SSO is used. - * - * === -B[0-2] - * - * Assume broken JIS-Kanji input, which lost ESC. - * Useful when your site is using old B-News Nihongo patch. - * - * [-B1] allows any char after ESC-( or ESC-$. - * - * [-B2] forces ASCII after NL. - * - * === -I - * - * Replacing non iso-2022-jp char into a geta character - * (substitute character in Japanese). - * - * === -d -c - * - * Delete \r in line feed, Add \r in line feed. - * - * === -m[BQN0] - * - * MIME ISO-2022-JP/ISO8859-1 decode. (DEFAULT) - * To see ISO8859-1 (Latin-1) -l is necessary. - * - * [-mB] Decode MIME base64 encoded stream. Remove header or other part before - * conversion. - * - * [-mQ] Decode MIME quoted stream. '_' in quoted stream is converted to space. - * - * [-mN] Non-strict decoding. - * It allows line break in the middle of the base64 encoding. - * - * [-m0] No MIME decode. - * - * === -M - * - * MIME encode. Header style. All ASCII code and control characters are intact. - * Kanji conversion is performed before encoding, so this cannot be used as a picture encoder. - * - * [-MB] MIME encode Base64 stream. - * - * [-MQ] Perfome quoted encoding. - * - * === -l - * - * Input and output code is ISO8859-1 (Latin-1) and ISO-2022-JP. - * <b>-s</b>, <b>-e</b> and <b>-x</b> are not compatible with this option. - * - * === -L[uwm] - * - * new line mode - * Without this option, nkf doesn't convert line breaks. - * - * [-Lu] unix (LF) - * - * [-Lw] windows (CRLF) - * - * [-Lm] mac (CR) - * - * === --fj --unix --mac --msdos --windows - * - * convert for these system - * - * === --jis --euc --sjis --mime --base64 - * - * convert for named code - * - * === --jis-input --euc-input --sjis-input --mime-input --base64-input - * - * assume input system - * - * === --ic=<code>input codeset</code> --oc=<code>output codeset</code> - * - * Set the input or output codeset. - * NKF supports following codesets and those codeset name are case insensitive. - * - * [ISO-2022-JP] a.k.a. RFC1468, 7bit JIS, JUNET - * - * [EUC-JP (eucJP-nkf)] a.k.a. AT&T JIS, Japanese EUC, UJIS - * - * [eucJP-ascii] a.k.a. x-eucjp-open-19970715-ascii - * - * [eucJP-ms] a.k.a. x-eucjp-open-19970715-ms - * - * [CP51932] Microsoft Version of EUC-JP. - * - * [Shift_JIS] SJIS, MS-Kanji - * - * [Windows-31J] a.k.a. CP932 - * - * [UTF-8] same as UTF-8N - * - * [UTF-8N] UTF-8 without BOM - * - * [UTF-8-BOM] UTF-8 with BOM - * - * [UTF-16] same as UTF-16BE - * - * [UTF-16BE] UTF-16 Big Endian without BOM - * - * [UTF-16BE-BOM] UTF-16 Big Endian with BOM - * - * [UTF-16LE] UTF-16 Little Endian without BOM - * - * [UTF-16LE-BOM] UTF-16 Little Endian with BOM - * - * [UTF-32] same as UTF-32BE - * - * [UTF-32BE] UTF-32 Big Endian without BOM - * - * [UTF-32BE-BOM] UTF-32 Big Endian with BOM - * - * [UTF-32LE] UTF-32 Little Endian without BOM - * - * [UTF-32LE-BOM] UTF-32 Little Endian with BOM - * - * [UTF8-MAC] NKDed UTF-8, a.k.a. UTF8-NFD (input only) - * - * === --fb-{skip, html, xml, perl, java, subchar} - * - * Specify the way that nkf handles unassigned characters. - * Without this option, --fb-skip is assumed. - * - * === --prefix= <code>escape character</code> <code>target character</code> .. - * - * When nkf converts to Shift_JIS, - * nkf adds a specified escape character to specified 2nd byte of Shift_JIS characters. - * 1st byte of argument is the escape character and following bytes are target characters. - * - * === --no-cp932ext - * - * Handle the characters extended in CP932 as unassigned characters. - * - * == --no-best-fit-chars - * - * When Unicode to Encoded byte conversion, - * don't convert characters which is not round trip safe. - * When Unicode to Unicode conversion, - * with this and -x option, nkf can be used as UTF converter. - * (In other words, without this and -x option, nkf doesn't save some characters) - * - * When nkf convert string which related to path, you should use this option. - * - * === --cap-input - * - * Decode hex encoded characters. - * - * === --url-input - * - * Unescape percent escaped characters. - * - * === -- - * - * Ignore rest of -option. - */ - -void -Init_nkf(void) -{ - VALUE mNKF = rb_define_module("NKF"); - - rb_define_module_function(mNKF, "nkf", rb_nkf_convert, 2); - rb_define_module_function(mNKF, "guess", rb_nkf_guess, 1); - rb_define_alias(rb_singleton_class(mNKF), "guess", "guess"); - - rb_define_const(mNKF, "AUTO", Qnil); - rb_define_const(mNKF, "NOCONV", Qnil); - rb_define_const(mNKF, "UNKNOWN", Qnil); - rb_define_const(mNKF, "BINARY", rb_enc_from_encoding(rb_nkf_enc_get("BINARY"))); - rb_define_const(mNKF, "ASCII", rb_enc_from_encoding(rb_nkf_enc_get("US-ASCII"))); - rb_define_const(mNKF, "JIS", rb_enc_from_encoding(rb_nkf_enc_get("ISO-2022-JP"))); - rb_define_const(mNKF, "EUC", rb_enc_from_encoding(rb_nkf_enc_get("EUC-JP"))); - rb_define_const(mNKF, "SJIS", rb_enc_from_encoding(rb_nkf_enc_get("Shift_JIS"))); - rb_define_const(mNKF, "UTF8", rb_enc_from_encoding(rb_utf8_encoding())); - rb_define_const(mNKF, "UTF16", rb_enc_from_encoding(rb_nkf_enc_get("UTF-16BE"))); - rb_define_const(mNKF, "UTF32", rb_enc_from_encoding(rb_nkf_enc_get("UTF-32BE"))); - - /* Full version string of nkf */ - rb_define_const(mNKF, "VERSION", rb_str_new2(RUBY_NKF_VERSION)); - /* Version of nkf */ - rb_define_const(mNKF, "NKF_VERSION", rb_str_new2(NKF_VERSION)); - /* Release date of nkf */ - rb_define_const(mNKF, "NKF_RELEASE_DATE", rb_str_new2(NKF_RELEASE_DATE)); -} diff --git a/ext/nkf/nkf.gemspec b/ext/nkf/nkf.gemspec deleted file mode 100644 index 2d77c71ff8..0000000000 --- a/ext/nkf/nkf.gemspec +++ /dev/null @@ -1,24 +0,0 @@ -Gem::Specification.new do |spec| - spec.name = "nkf" - spec.version = "0.1.1" - spec.authors = ["NARUSE Yui"] - spec.email = ["naruse@airemix.jp"] - - spec.summary = %q{Ruby extension for Network Kanji Filter} - spec.description = %q{Ruby extension for Network Kanji Filter} - spec.homepage = "https://github.com/ruby/nkf" - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") - spec.licenses = ["Ruby", "BSD-2-Clause"] - - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = spec.homepage - - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] -end diff --git a/ext/objspace/depend b/ext/objspace/depend index 364d6faba6..d9dfc0c42b 100644 --- a/ext/objspace/depend +++ b/ext/objspace/depend @@ -1,8 +1,8 @@ # AUTOGENERATED DEPENDENCIES START object_tracing.o: $(RUBY_EXTCONF_H) object_tracing.o: $(arch_hdrdir)/ruby/config.h -object_tracing.o: $(hdrdir)/ruby.h object_tracing.o: $(hdrdir)/ruby/assert.h +object_tracing.o: $(hdrdir)/ruby/atomic.h object_tracing.o: $(hdrdir)/ruby/backward.h object_tracing.o: $(hdrdir)/ruby/backward/2/assume.h object_tracing.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -11,13 +11,13 @@ object_tracing.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h object_tracing.o: $(hdrdir)/ruby/backward/2/inttypes.h object_tracing.o: $(hdrdir)/ruby/backward/2/limits.h object_tracing.o: $(hdrdir)/ruby/backward/2/long_long.h -object_tracing.o: $(hdrdir)/ruby/backward/2/r_cast.h -object_tracing.o: $(hdrdir)/ruby/backward/2/rmodule.h object_tracing.o: $(hdrdir)/ruby/backward/2/stdalign.h object_tracing.o: $(hdrdir)/ruby/backward/2/stdarg.h object_tracing.o: $(hdrdir)/ruby/debug.h object_tracing.o: $(hdrdir)/ruby/defines.h +object_tracing.o: $(hdrdir)/ruby/encoding.h object_tracing.o: $(hdrdir)/ruby/intern.h +object_tracing.o: $(hdrdir)/ruby/internal/abi.h object_tracing.o: $(hdrdir)/ruby/internal/anyargs.h object_tracing.o: $(hdrdir)/ruby/internal/arithmetic.h object_tracing.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -55,6 +55,7 @@ object_tracing.o: $(hdrdir)/ruby/internal/attr/noexcept.h object_tracing.o: $(hdrdir)/ruby/internal/attr/noinline.h object_tracing.o: $(hdrdir)/ruby/internal/attr/nonnull.h object_tracing.o: $(hdrdir)/ruby/internal/attr/noreturn.h +object_tracing.o: $(hdrdir)/ruby/internal/attr/packed_struct.h object_tracing.o: $(hdrdir)/ruby/internal/attr/pure.h object_tracing.o: $(hdrdir)/ruby/internal/attr/restrict.h object_tracing.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -87,6 +88,15 @@ object_tracing.o: $(hdrdir)/ruby/internal/core/rtypeddata.h object_tracing.o: $(hdrdir)/ruby/internal/ctype.h object_tracing.o: $(hdrdir)/ruby/internal/dllexport.h object_tracing.o: $(hdrdir)/ruby/internal/dosish.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/coderange.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/ctype.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/encoding.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/pathname.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/re.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/string.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/symbol.h +object_tracing.o: $(hdrdir)/ruby/internal/encoding/transcode.h object_tracing.o: $(hdrdir)/ruby/internal/error.h object_tracing.o: $(hdrdir)/ruby/internal/eval.h object_tracing.o: $(hdrdir)/ruby/internal/event.h @@ -114,7 +124,6 @@ object_tracing.o: $(hdrdir)/ruby/internal/intern/enumerator.h object_tracing.o: $(hdrdir)/ruby/internal/intern/error.h object_tracing.o: $(hdrdir)/ruby/internal/intern/eval.h object_tracing.o: $(hdrdir)/ruby/internal/intern/file.h -object_tracing.o: $(hdrdir)/ruby/internal/intern/gc.h object_tracing.o: $(hdrdir)/ruby/internal/intern/hash.h object_tracing.o: $(hdrdir)/ruby/internal/intern/io.h object_tracing.o: $(hdrdir)/ruby/internal/intern/load.h @@ -131,6 +140,7 @@ object_tracing.o: $(hdrdir)/ruby/internal/intern/re.h object_tracing.o: $(hdrdir)/ruby/internal/intern/ruby.h object_tracing.o: $(hdrdir)/ruby/internal/intern/select.h object_tracing.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +object_tracing.o: $(hdrdir)/ruby/internal/intern/set.h object_tracing.o: $(hdrdir)/ruby/internal/intern/signal.h object_tracing.o: $(hdrdir)/ruby/internal/intern/sprintf.h object_tracing.o: $(hdrdir)/ruby/internal/intern/string.h @@ -145,12 +155,12 @@ object_tracing.o: $(hdrdir)/ruby/internal/memory.h object_tracing.o: $(hdrdir)/ruby/internal/method.h object_tracing.o: $(hdrdir)/ruby/internal/module.h object_tracing.o: $(hdrdir)/ruby/internal/newobj.h -object_tracing.o: $(hdrdir)/ruby/internal/rgengc.h object_tracing.o: $(hdrdir)/ruby/internal/scan_args.h object_tracing.o: $(hdrdir)/ruby/internal/special_consts.h object_tracing.o: $(hdrdir)/ruby/internal/static_assert.h object_tracing.o: $(hdrdir)/ruby/internal/stdalign.h object_tracing.o: $(hdrdir)/ruby/internal/stdbool.h +object_tracing.o: $(hdrdir)/ruby/internal/stdckdint.h object_tracing.o: $(hdrdir)/ruby/internal/symbol.h object_tracing.o: $(hdrdir)/ruby/internal/value.h object_tracing.o: $(hdrdir)/ruby/internal/value_type.h @@ -158,16 +168,45 @@ object_tracing.o: $(hdrdir)/ruby/internal/variable.h object_tracing.o: $(hdrdir)/ruby/internal/warning_push.h object_tracing.o: $(hdrdir)/ruby/internal/xmalloc.h object_tracing.o: $(hdrdir)/ruby/missing.h +object_tracing.o: $(hdrdir)/ruby/onigmo.h +object_tracing.o: $(hdrdir)/ruby/oniguruma.h object_tracing.o: $(hdrdir)/ruby/ruby.h object_tracing.o: $(hdrdir)/ruby/st.h object_tracing.o: $(hdrdir)/ruby/subst.h +object_tracing.o: $(hdrdir)/ruby/thread_native.h +object_tracing.o: $(top_srcdir)/ccan/check_type/check_type.h +object_tracing.o: $(top_srcdir)/ccan/container_of/container_of.h +object_tracing.o: $(top_srcdir)/ccan/list/list.h +object_tracing.o: $(top_srcdir)/ccan/str/str.h +object_tracing.o: $(top_srcdir)/id_table.h object_tracing.o: $(top_srcdir)/internal.h +object_tracing.o: $(top_srcdir)/internal/array.h +object_tracing.o: $(top_srcdir)/internal/basic_operators.h +object_tracing.o: $(top_srcdir)/internal/box.h +object_tracing.o: $(top_srcdir)/internal/compilers.h +object_tracing.o: $(top_srcdir)/internal/gc.h +object_tracing.o: $(top_srcdir)/internal/imemo.h +object_tracing.o: $(top_srcdir)/internal/sanitizers.h +object_tracing.o: $(top_srcdir)/internal/serial.h +object_tracing.o: $(top_srcdir)/internal/set_table.h +object_tracing.o: $(top_srcdir)/internal/static_assert.h +object_tracing.o: $(top_srcdir)/internal/vm.h +object_tracing.o: $(top_srcdir)/internal/warnings.h +object_tracing.o: $(top_srcdir)/method.h +object_tracing.o: $(top_srcdir)/node.h +object_tracing.o: $(top_srcdir)/ruby_assert.h +object_tracing.o: $(top_srcdir)/ruby_atomic.h +object_tracing.o: $(top_srcdir)/rubyparser.h +object_tracing.o: $(top_srcdir)/thread_pthread.h +object_tracing.o: $(top_srcdir)/vm_core.h +object_tracing.o: $(top_srcdir)/vm_opts.h object_tracing.o: object_tracing.c object_tracing.o: objspace.h +object_tracing.o: {$(VPATH)}id.h objspace.o: $(RUBY_EXTCONF_H) objspace.o: $(arch_hdrdir)/ruby/config.h -objspace.o: $(hdrdir)/ruby.h objspace.o: $(hdrdir)/ruby/assert.h +objspace.o: $(hdrdir)/ruby/atomic.h objspace.o: $(hdrdir)/ruby/backward.h objspace.o: $(hdrdir)/ruby/backward/2/assume.h objspace.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -176,13 +215,12 @@ objspace.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h objspace.o: $(hdrdir)/ruby/backward/2/inttypes.h objspace.o: $(hdrdir)/ruby/backward/2/limits.h objspace.o: $(hdrdir)/ruby/backward/2/long_long.h -objspace.o: $(hdrdir)/ruby/backward/2/r_cast.h -objspace.o: $(hdrdir)/ruby/backward/2/rmodule.h objspace.o: $(hdrdir)/ruby/backward/2/stdalign.h objspace.o: $(hdrdir)/ruby/backward/2/stdarg.h objspace.o: $(hdrdir)/ruby/defines.h objspace.o: $(hdrdir)/ruby/encoding.h objspace.o: $(hdrdir)/ruby/intern.h +objspace.o: $(hdrdir)/ruby/internal/abi.h objspace.o: $(hdrdir)/ruby/internal/anyargs.h objspace.o: $(hdrdir)/ruby/internal/arithmetic.h objspace.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -220,6 +258,7 @@ objspace.o: $(hdrdir)/ruby/internal/attr/noexcept.h objspace.o: $(hdrdir)/ruby/internal/attr/noinline.h objspace.o: $(hdrdir)/ruby/internal/attr/nonnull.h objspace.o: $(hdrdir)/ruby/internal/attr/noreturn.h +objspace.o: $(hdrdir)/ruby/internal/attr/packed_struct.h objspace.o: $(hdrdir)/ruby/internal/attr/pure.h objspace.o: $(hdrdir)/ruby/internal/attr/restrict.h objspace.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -289,7 +328,6 @@ objspace.o: $(hdrdir)/ruby/internal/intern/enumerator.h objspace.o: $(hdrdir)/ruby/internal/intern/error.h objspace.o: $(hdrdir)/ruby/internal/intern/eval.h objspace.o: $(hdrdir)/ruby/internal/intern/file.h -objspace.o: $(hdrdir)/ruby/internal/intern/gc.h objspace.o: $(hdrdir)/ruby/internal/intern/hash.h objspace.o: $(hdrdir)/ruby/internal/intern/io.h objspace.o: $(hdrdir)/ruby/internal/intern/load.h @@ -306,6 +344,7 @@ objspace.o: $(hdrdir)/ruby/internal/intern/re.h objspace.o: $(hdrdir)/ruby/internal/intern/ruby.h objspace.o: $(hdrdir)/ruby/internal/intern/select.h objspace.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +objspace.o: $(hdrdir)/ruby/internal/intern/set.h objspace.o: $(hdrdir)/ruby/internal/intern/signal.h objspace.o: $(hdrdir)/ruby/internal/intern/sprintf.h objspace.o: $(hdrdir)/ruby/internal/intern/string.h @@ -320,12 +359,12 @@ objspace.o: $(hdrdir)/ruby/internal/memory.h objspace.o: $(hdrdir)/ruby/internal/method.h objspace.o: $(hdrdir)/ruby/internal/module.h objspace.o: $(hdrdir)/ruby/internal/newobj.h -objspace.o: $(hdrdir)/ruby/internal/rgengc.h objspace.o: $(hdrdir)/ruby/internal/scan_args.h objspace.o: $(hdrdir)/ruby/internal/special_consts.h objspace.o: $(hdrdir)/ruby/internal/static_assert.h objspace.o: $(hdrdir)/ruby/internal/stdalign.h objspace.o: $(hdrdir)/ruby/internal/stdbool.h +objspace.o: $(hdrdir)/ruby/internal/stdckdint.h objspace.o: $(hdrdir)/ruby/internal/symbol.h objspace.o: $(hdrdir)/ruby/internal/value.h objspace.o: $(hdrdir)/ruby/internal/value_type.h @@ -341,10 +380,18 @@ objspace.o: $(hdrdir)/ruby/regex.h objspace.o: $(hdrdir)/ruby/ruby.h objspace.o: $(hdrdir)/ruby/st.h objspace.o: $(hdrdir)/ruby/subst.h -objspace.o: $(top_srcdir)/gc.h +objspace.o: $(hdrdir)/ruby/thread_native.h +objspace.o: $(top_srcdir)/ccan/check_type/check_type.h +objspace.o: $(top_srcdir)/ccan/container_of/container_of.h +objspace.o: $(top_srcdir)/ccan/list/list.h +objspace.o: $(top_srcdir)/ccan/str/str.h +objspace.o: $(top_srcdir)/constant.h +objspace.o: $(top_srcdir)/debug_counter.h objspace.o: $(top_srcdir)/id_table.h objspace.o: $(top_srcdir)/internal.h objspace.o: $(top_srcdir)/internal/array.h +objspace.o: $(top_srcdir)/internal/basic_operators.h +objspace.o: $(top_srcdir)/internal/box.h objspace.o: $(top_srcdir)/internal/class.h objspace.o: $(top_srcdir)/internal/compilers.h objspace.o: $(top_srcdir)/internal/gc.h @@ -352,15 +399,28 @@ objspace.o: $(top_srcdir)/internal/hash.h objspace.o: $(top_srcdir)/internal/imemo.h objspace.o: $(top_srcdir)/internal/sanitizers.h objspace.o: $(top_srcdir)/internal/serial.h +objspace.o: $(top_srcdir)/internal/set_table.h objspace.o: $(top_srcdir)/internal/static_assert.h +objspace.o: $(top_srcdir)/internal/struct.h +objspace.o: $(top_srcdir)/internal/variable.h +objspace.o: $(top_srcdir)/internal/vm.h objspace.o: $(top_srcdir)/internal/warnings.h +objspace.o: $(top_srcdir)/method.h objspace.o: $(top_srcdir)/node.h +objspace.o: $(top_srcdir)/ruby_assert.h +objspace.o: $(top_srcdir)/ruby_atomic.h +objspace.o: $(top_srcdir)/rubyparser.h +objspace.o: $(top_srcdir)/shape.h objspace.o: $(top_srcdir)/symbol.h +objspace.o: $(top_srcdir)/thread_pthread.h +objspace.o: $(top_srcdir)/vm_core.h +objspace.o: $(top_srcdir)/vm_debug.h +objspace.o: $(top_srcdir)/vm_opts.h +objspace.o: $(top_srcdir)/vm_sync.h objspace.o: objspace.c objspace.o: {$(VPATH)}id.h objspace_dump.o: $(RUBY_EXTCONF_H) objspace_dump.o: $(arch_hdrdir)/ruby/config.h -objspace_dump.o: $(hdrdir)/ruby.h objspace_dump.o: $(hdrdir)/ruby/assert.h objspace_dump.o: $(hdrdir)/ruby/atomic.h objspace_dump.o: $(hdrdir)/ruby/backward.h @@ -371,14 +431,13 @@ objspace_dump.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h objspace_dump.o: $(hdrdir)/ruby/backward/2/inttypes.h objspace_dump.o: $(hdrdir)/ruby/backward/2/limits.h objspace_dump.o: $(hdrdir)/ruby/backward/2/long_long.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/r_cast.h -objspace_dump.o: $(hdrdir)/ruby/backward/2/rmodule.h objspace_dump.o: $(hdrdir)/ruby/backward/2/stdalign.h objspace_dump.o: $(hdrdir)/ruby/backward/2/stdarg.h objspace_dump.o: $(hdrdir)/ruby/debug.h objspace_dump.o: $(hdrdir)/ruby/defines.h objspace_dump.o: $(hdrdir)/ruby/encoding.h objspace_dump.o: $(hdrdir)/ruby/intern.h +objspace_dump.o: $(hdrdir)/ruby/internal/abi.h objspace_dump.o: $(hdrdir)/ruby/internal/anyargs.h objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic.h objspace_dump.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -416,6 +475,7 @@ objspace_dump.o: $(hdrdir)/ruby/internal/attr/noexcept.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/noinline.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/nonnull.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/noreturn.h +objspace_dump.o: $(hdrdir)/ruby/internal/attr/packed_struct.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/pure.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/restrict.h objspace_dump.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -484,7 +544,6 @@ objspace_dump.o: $(hdrdir)/ruby/internal/intern/enumerator.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/error.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/eval.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/file.h -objspace_dump.o: $(hdrdir)/ruby/internal/intern/gc.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/hash.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/io.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/load.h @@ -501,6 +560,7 @@ objspace_dump.o: $(hdrdir)/ruby/internal/intern/re.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/ruby.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/select.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +objspace_dump.o: $(hdrdir)/ruby/internal/intern/set.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/signal.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/sprintf.h objspace_dump.o: $(hdrdir)/ruby/internal/intern/string.h @@ -515,12 +575,12 @@ objspace_dump.o: $(hdrdir)/ruby/internal/memory.h objspace_dump.o: $(hdrdir)/ruby/internal/method.h objspace_dump.o: $(hdrdir)/ruby/internal/module.h objspace_dump.o: $(hdrdir)/ruby/internal/newobj.h -objspace_dump.o: $(hdrdir)/ruby/internal/rgengc.h objspace_dump.o: $(hdrdir)/ruby/internal/scan_args.h objspace_dump.o: $(hdrdir)/ruby/internal/special_consts.h objspace_dump.o: $(hdrdir)/ruby/internal/static_assert.h objspace_dump.o: $(hdrdir)/ruby/internal/stdalign.h objspace_dump.o: $(hdrdir)/ruby/internal/stdbool.h +objspace_dump.o: $(hdrdir)/ruby/internal/stdckdint.h objspace_dump.o: $(hdrdir)/ruby/internal/symbol.h objspace_dump.o: $(hdrdir)/ruby/internal/value.h objspace_dump.o: $(hdrdir)/ruby/internal/value_type.h @@ -540,27 +600,42 @@ objspace_dump.o: $(top_srcdir)/ccan/check_type/check_type.h objspace_dump.o: $(top_srcdir)/ccan/container_of/container_of.h objspace_dump.o: $(top_srcdir)/ccan/list/list.h objspace_dump.o: $(top_srcdir)/ccan/str/str.h -objspace_dump.o: $(top_srcdir)/darray.h -objspace_dump.o: $(top_srcdir)/gc.h +objspace_dump.o: $(top_srcdir)/constant.h +objspace_dump.o: $(top_srcdir)/debug_counter.h +objspace_dump.o: $(top_srcdir)/encindex.h +objspace_dump.o: $(top_srcdir)/id_table.h objspace_dump.o: $(top_srcdir)/internal.h objspace_dump.o: $(top_srcdir)/internal/array.h +objspace_dump.o: $(top_srcdir)/internal/basic_operators.h +objspace_dump.o: $(top_srcdir)/internal/box.h +objspace_dump.o: $(top_srcdir)/internal/class.h objspace_dump.o: $(top_srcdir)/internal/compilers.h objspace_dump.o: $(top_srcdir)/internal/gc.h objspace_dump.o: $(top_srcdir)/internal/hash.h objspace_dump.o: $(top_srcdir)/internal/imemo.h +objspace_dump.o: $(top_srcdir)/internal/io.h objspace_dump.o: $(top_srcdir)/internal/sanitizers.h objspace_dump.o: $(top_srcdir)/internal/serial.h +objspace_dump.o: $(top_srcdir)/internal/set_table.h objspace_dump.o: $(top_srcdir)/internal/static_assert.h objspace_dump.o: $(top_srcdir)/internal/string.h +objspace_dump.o: $(top_srcdir)/internal/struct.h +objspace_dump.o: $(top_srcdir)/internal/variable.h objspace_dump.o: $(top_srcdir)/internal/vm.h objspace_dump.o: $(top_srcdir)/internal/warnings.h objspace_dump.o: $(top_srcdir)/method.h objspace_dump.o: $(top_srcdir)/node.h objspace_dump.o: $(top_srcdir)/ruby_assert.h objspace_dump.o: $(top_srcdir)/ruby_atomic.h +objspace_dump.o: $(top_srcdir)/rubyparser.h +objspace_dump.o: $(top_srcdir)/shape.h +objspace_dump.o: $(top_srcdir)/symbol.h objspace_dump.o: $(top_srcdir)/thread_pthread.h +objspace_dump.o: $(top_srcdir)/vm_callinfo.h objspace_dump.o: $(top_srcdir)/vm_core.h +objspace_dump.o: $(top_srcdir)/vm_debug.h objspace_dump.o: $(top_srcdir)/vm_opts.h +objspace_dump.o: $(top_srcdir)/vm_sync.h objspace_dump.o: objspace.h objspace_dump.o: objspace_dump.c objspace_dump.o: {$(VPATH)}id.h diff --git a/ext/objspace/lib/objspace.rb b/ext/objspace/lib/objspace.rb index 0298b0646c..47873f5112 100644 --- a/ext/objspace/lib/objspace.rb +++ b/ext/objspace/lib/objspace.rb @@ -6,17 +6,21 @@ module ObjectSpace class << self private :_dump private :_dump_all + private :_dump_shapes end module_function - # call-seq: - # ObjectSpace.dump(obj[, output: :string]) # => "{ ... }" - # ObjectSpace.dump(obj, output: :file) # => #<File:/tmp/rubyobj20131125-88733-1xkfmpv.json> - # ObjectSpace.dump(obj, output: :stdout) # => nil - # # Dump the contents of a ruby object as JSON. # + # _output_ can be one of: +:stdout+, +:file+, +:string+, or IO object. + # + # * +:file+ means dumping to a tempfile and returning corresponding File object; + # * +:stdout+ means printing the dump and returning +nil+; + # * +:string+ means returning a string with the dump; + # * if an instance of IO object is provided, the output goes there, and the object + # is returned. + # # This method is only expected to work with C Ruby. # This is an experimental method and is subject to change. # In particular, the function signature and output format are @@ -42,38 +46,78 @@ module ObjectSpace end - # call-seq: - # ObjectSpace.dump_all([output: :file]) # => #<File:/tmp/rubyheap20131125-88469-laoj3v.json> - # ObjectSpace.dump_all(output: :stdout) # => nil - # ObjectSpace.dump_all(output: :string) # => "{...}\n{...}\n..." - # ObjectSpace.dump_all(output: - # File.open('heap.json','w')) # => #<File:heap.json> - # ObjectSpace.dump_all(output: :string, - # since: 42) # => "{...}\n{...}\n..." + # Dump the contents of the ruby heap as JSON. + # + # _output_ argument is the same as for #dump. + # + # _full_ must be a boolean. If true, all heap slots are dumped including the empty ones (+T_NONE+). # - # Dump the contents of the ruby heap as JSON. + # _since_ must be a non-negative integer or +nil+. # - # _since_ must be a non-negative integer or +nil+. + # If _since_ is a positive integer, only objects of that generation and + # newer generations are dumped. The current generation can be accessed using + # GC::count. Objects that were allocated without object allocation tracing enabled + # are ignored. See ::trace_object_allocations for more information and + # examples. # - # If _since_ is a positive integer, only objects of that generation and - # newer generations are dumped. The current generation can be accessed using - # GC::count. + # If _since_ is omitted or is +nil+, all objects are dumped. # - # Objects that were allocated without object allocation tracing enabled - # are ignored. See ::trace_object_allocations for more information and - # examples. + # _shapes_ must be a boolean or a non-negative integer. # - # If _since_ is omitted or is +nil+, all objects are dumped. + # If _shapes_ is a positive integer, only shapes newer than the provided + # shape id are dumped. The current shape_id can be accessed using <tt>RubyVM.stat(:next_shape_id)</tt>. + # + # If _shapes_ is +false+, no shapes are dumped. + # + # To only dump objects allocated past a certain point you can combine _since_ and _shapes_: + # ObjectSpace.trace_object_allocations + # GC.start + # gc_generation = GC.count + # shape_generation = RubyVM.stat(:next_shape_id) + # call_method_to_instrument + # ObjectSpace.dump_all(since: gc_generation, shapes: shape_generation) + # + # This method is only expected to work with C Ruby. + # This is an experimental method and is subject to change. + # In particular, the function signature and output format are + # not guaranteed to be compatible in future versions of ruby. + def dump_all(output: :file, full: false, since: nil, shapes: true) + out = case output + when :file, nil + require 'tempfile' + Tempfile.create(%w(rubyheap .json)) + when :stdout + STDOUT + when :string + +'' + when IO + output + else + raise ArgumentError, "wrong output option: #{output.inspect}" + end + + shapes = 0 if shapes == true + ret = _dump_all(out, full, since, shapes) + return nil if output == :stdout + ret + end + + # Dump the contents of the ruby shape tree as JSON. + # + # _output_ argument is the same as for #dump. + # + # If _since_ is a positive integer, only shapes newer than the provided + # shape id are dumped. The current shape_id can be accessed using <tt>RubyVM.stat(:next_shape_id)</tt>. # # This method is only expected to work with C Ruby. # This is an experimental method and is subject to change. # In particular, the function signature and output format are # not guaranteed to be compatible in future versions of ruby. - def dump_all(output: :file, full: false, since: nil) + def dump_shapes(output: :file, since: 0) out = case output when :file, nil require 'tempfile' - Tempfile.create(%w(rubyheap .json)) + Tempfile.create(%w(rubyshapes .json)) when :stdout STDOUT when :string @@ -84,7 +128,7 @@ module ObjectSpace raise ArgumentError, "wrong output option: #{output.inspect}" end - ret = _dump_all(out, full, since) + ret = _dump_shapes(out, since) return nil if output == :stdout ret end diff --git a/ext/objspace/object_tracing.c b/ext/objspace/object_tracing.c index 4973a7535b..c06f1f68dd 100644 --- a/ext/objspace/object_tracing.c +++ b/ext/objspace/object_tracing.c @@ -14,6 +14,7 @@ **********************************************************************/ #include "internal.h" +#include "internal/gc.h" #include "ruby/debug.h" #include "objspace.h" @@ -31,42 +32,50 @@ static const char * make_unique_str(st_table *tbl, const char *str, long len) { if (!str) { - return NULL; + return NULL; } else { - st_data_t n; - char *result; - - if (st_lookup(tbl, (st_data_t)str, &n)) { - st_insert(tbl, (st_data_t)str, n+1); - st_get_key(tbl, (st_data_t)str, &n); - result = (char *)n; - } - else { - result = (char *)ruby_xmalloc(len+1); - strncpy(result, str, len); - result[len] = 0; - st_add_direct(tbl, (st_data_t)result, 1); - } - return result; + st_data_t n; + char *result; + + if (st_lookup(tbl, (st_data_t)str, &n)) { + st_insert(tbl, (st_data_t)str, n+1); + st_get_key(tbl, (st_data_t)str, &n); + result = (char *)n; + } + else { + result = (char *)ruby_xmalloc(len+1); + strncpy(result, str, len); + result[len] = 0; + st_add_direct(tbl, (st_data_t)result, 1); + } + return result; } } +static int +delete_unique_str_dec(st_data_t *key, st_data_t *value, st_data_t arg, int existing) +{ + assert(existing); + *value = arg; + return ST_CONTINUE; +} + static void delete_unique_str(st_table *tbl, const char *str) { if (str) { - st_data_t n; - - st_lookup(tbl, (st_data_t)str, &n); - if (n == 1) { - n = (st_data_t)str; - st_delete(tbl, &n, 0); - ruby_xfree((char *)n); - } - else { - st_insert(tbl, (st_data_t)str, n-1); - } + st_data_t n; + + st_lookup(tbl, (st_data_t)str, &n); + if (n == 1) { + n = (st_data_t)str; + st_delete(tbl, &n, 0); + ruby_xfree((char *)n); + } + else { + st_update(tbl, (st_data_t)str, delete_unique_str_dec, (st_data_t)(n-1)); + } } } @@ -87,18 +96,18 @@ newobj_i(VALUE tpval, void *data) st_data_t v; if (st_lookup(arg->object_table, (st_data_t)obj, &v)) { - info = (struct allocation_info *)v; - if (arg->keep_remains) { - if (info->living) { - /* do nothing. there is possibility to keep living if FREEOBJ events while suppressing tracing */ - } - } - /* reuse info */ - delete_unique_str(arg->str_table, info->path); - delete_unique_str(arg->str_table, info->class_path); + info = (struct allocation_info *)v; + if (arg->keep_remains) { + if (info->living) { + /* do nothing. there is possibility to keep living if FREEOBJ events while suppressing tracing */ + } + } + /* reuse info */ + delete_unique_str(arg->str_table, info->path); + delete_unique_str(arg->str_table, info->class_path); } else { - info = (struct allocation_info *)ruby_xmalloc(sizeof(struct allocation_info)); + info = (struct allocation_info *)ruby_xmalloc(sizeof(struct allocation_info)); } info->living = 1; info->flags = RBASIC(obj)->flags; @@ -121,20 +130,26 @@ freeobj_i(VALUE tpval, void *data) st_data_t v; struct allocation_info *info; + /* Modifying the st table can cause allocations, which can trigger GC. + * Since freeobj_i is called during GC, it must not trigger another GC. */ + VALUE gc_disabled = rb_gc_disable_no_rest(); + if (arg->keep_remains) { - if (st_lookup(arg->object_table, obj, &v)) { - info = (struct allocation_info *)v; - info->living = 0; - } + if (st_lookup(arg->object_table, obj, &v)) { + info = (struct allocation_info *)v; + info->living = 0; + } } else { - if (st_delete(arg->object_table, &obj, &v)) { - info = (struct allocation_info *)v; - delete_unique_str(arg->str_table, info->path); - delete_unique_str(arg->str_table, info->class_path); - ruby_xfree(info); - } + if (st_delete(arg->object_table, &obj, &v)) { + info = (struct allocation_info *)v; + delete_unique_str(arg->str_table, info->path); + delete_unique_str(arg->str_table, info->class_path); + ruby_xfree(info); + } } + + if (gc_disabled == Qfalse) rb_gc_enable(); } static int @@ -183,22 +198,25 @@ allocation_info_tracer_memsize(const void *ptr) } static int -hash_foreach_should_replace_key(st_data_t key, st_data_t value, st_data_t argp, int error) +allocation_info_tracer_compact_update_object_table_i(st_data_t key, st_data_t value, st_data_t data) { - VALUE allocated_object; + st_table *table = (st_table *)data; - allocated_object = (VALUE)value; - if (allocated_object != rb_gc_location(allocated_object)) { - return ST_REPLACE; + if (!rb_gc_pointer_to_heap_p(key)) { + struct allocation_info *info = (struct allocation_info *)value; + xfree(info); + return ST_DELETE; } - return ST_CONTINUE; -} + if (key != rb_gc_location(key)) { + DURING_GC_COULD_MALLOC_REGION_START(); + { + st_insert(table, rb_gc_location(key), value); + } + DURING_GC_COULD_MALLOC_REGION_END(); -static int -hash_replace_key(st_data_t *key, st_data_t *value, st_data_t argp, int existing) -{ - *key = rb_gc_location((VALUE)*key); + return ST_DELETE; + } return ST_CONTINUE; } @@ -208,7 +226,11 @@ allocation_info_tracer_compact(void *ptr) { struct traceobj_arg *trace_arg = (struct traceobj_arg *)ptr; - if (st_foreach_with_replace(trace_arg->object_table, hash_foreach_should_replace_key, hash_replace_key, 0)) { + if (trace_arg->object_table && + st_foreach( + trace_arg->object_table, + allocation_info_tracer_compact_update_object_table_i, + (st_data_t)trace_arg->object_table)) { rb_raise(rb_eRuntimeError, "hash modified during iteration"); } } @@ -235,12 +257,12 @@ get_traceobj_arg(void) VALUE obj = TypedData_Make_Struct(rb_cObject, struct traceobj_arg, &allocation_info_tracer_type, tmp_trace_arg); traceobj_arg = obj; rb_gc_register_mark_object(traceobj_arg); - tmp_trace_arg->running = 0; - tmp_trace_arg->keep_remains = tmp_keep_remains; - tmp_trace_arg->newobj_trace = 0; - tmp_trace_arg->freeobj_trace = 0; - tmp_trace_arg->object_table = st_init_numtable(); - tmp_trace_arg->str_table = st_init_strtable(); + tmp_trace_arg->running = 0; + tmp_trace_arg->keep_remains = tmp_keep_remains; + tmp_trace_arg->newobj_trace = 0; + tmp_trace_arg->freeobj_trace = 0; + tmp_trace_arg->object_table = st_init_numtable(); + tmp_trace_arg->str_table = st_init_strtable(); } return tmp_trace_arg; } @@ -257,15 +279,15 @@ trace_object_allocations_start(VALUE self) struct traceobj_arg *arg = get_traceobj_arg(); if (arg->running++ > 0) { - /* do nothing */ + /* do nothing */ } else { - if (arg->newobj_trace == 0) { - arg->newobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, newobj_i, arg); - arg->freeobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_FREEOBJ, freeobj_i, arg); - } - rb_tracepoint_enable(arg->newobj_trace); - rb_tracepoint_enable(arg->freeobj_trace); + if (arg->newobj_trace == 0) { + arg->newobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, newobj_i, arg); + arg->freeobj_trace = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_FREEOBJ, freeobj_i, arg); + } + rb_tracepoint_enable(arg->newobj_trace); + rb_tracepoint_enable(arg->freeobj_trace); } return Qnil; @@ -286,7 +308,7 @@ trace_object_allocations_stop(VALUE self) struct traceobj_arg *arg = get_traceobj_arg(); if (arg->running > 0) { - arg->running--; + arg->running--; } if (arg->running == 0) { @@ -373,8 +395,8 @@ object_allocations_reporter_i(st_data_t key, st_data_t val, st_data_t ptr) else fprintf(out, "C: %p", (void *)info->klass); fprintf(out, "@%s:%lu", info->path ? info->path : "", info->line); if (!NIL_P(info->mid)) { - VALUE m = rb_sym2str(info->mid); - fprintf(out, " (%s)", RSTRING_PTR(m)); + VALUE m = rb_sym2str(info->mid); + fprintf(out, " (%s)", RSTRING_PTR(m)); } fprintf(out, ")\n"); @@ -386,18 +408,25 @@ object_allocations_reporter(FILE *out, void *ptr) { fprintf(out, "== object_allocations_reporter: START\n"); if (tmp_trace_arg) { - st_foreach(tmp_trace_arg->object_table, object_allocations_reporter_i, (st_data_t)out); + st_foreach(tmp_trace_arg->object_table, object_allocations_reporter_i, (st_data_t)out); } fprintf(out, "== object_allocations_reporter: END\n"); } +/* + * call-seq: trace_object_allocations_debug_start + * + * Starts tracing object allocations for GC debugging. + * If you encounter the BUG "... is T_NONE" (and so on) on your + * application, please try this method at the beginning of your app. + */ static VALUE trace_object_allocations_debug_start(VALUE self) { tmp_keep_remains = 1; if (object_allocations_reporter_registered == 0) { - object_allocations_reporter_registered = 1; - rb_bug_reporter_add(object_allocations_reporter, 0); + object_allocations_reporter_registered = 1; + rb_bug_reporter_add(object_allocations_reporter, 0); } return trace_object_allocations_start(self); @@ -407,10 +436,10 @@ static struct allocation_info * lookup_allocation_info(VALUE obj) { if (tmp_trace_arg) { - st_data_t info; - if (st_lookup(tmp_trace_arg->object_table, obj, &info)) { - return (struct allocation_info *)info; - } + st_data_t info; + if (st_lookup(tmp_trace_arg->object_table, obj, &info)) { + return (struct allocation_info *)info; + } } return NULL; } @@ -434,10 +463,10 @@ allocation_sourcefile(VALUE self, VALUE obj) struct allocation_info *info = lookup_allocation_info(obj); if (info && info->path) { - return rb_str_new2(info->path); + return rb_str_new2(info->path); } else { - return Qnil; + return Qnil; } } @@ -454,10 +483,10 @@ allocation_sourceline(VALUE self, VALUE obj) struct allocation_info *info = lookup_allocation_info(obj); if (info) { - return INT2FIX(info->line); + return INT2FIX(info->line); } else { - return Qnil; + return Qnil; } } @@ -485,10 +514,10 @@ allocation_class_path(VALUE self, VALUE obj) struct allocation_info *info = lookup_allocation_info(obj); if (info && info->class_path) { - return rb_str_new2(info->class_path); + return rb_str_new2(info->class_path); } else { - return Qnil; + return Qnil; } } @@ -517,10 +546,10 @@ allocation_method_id(VALUE self, VALUE obj) { struct allocation_info *info = lookup_allocation_info(obj); if (info) { - return info->mid; + return info->mid; } else { - return Qnil; + return Qnil; } } @@ -549,10 +578,10 @@ allocation_generation(VALUE self, VALUE obj) { struct allocation_info *info = lookup_allocation_info(obj); if (info) { - return SIZET2NUM(info->generation); + return SIZET2NUM(info->generation); } else { - return Qnil; + return Qnil; } } diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index 3fa4fd279b..1143e4801d 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -12,14 +12,13 @@ **********************************************************************/ -#include "gc.h" #include "internal.h" #include "internal/class.h" #include "internal/compilers.h" +#include "internal/gc.h" #include "internal/hash.h" #include "internal/imemo.h" #include "internal/sanitizers.h" -#include "node.h" #include "ruby/io.h" #include "ruby/re.h" #include "ruby/st.h" @@ -39,10 +38,11 @@ * information as only a *HINT*. Especially, the size of +T_DATA+ may not be * correct. * - * This method is only expected to work with C Ruby. + * This method is only expected to work with CRuby. * - * From Ruby 2.2, memsize_of(obj) returns a memory size includes - * sizeof(RVALUE). + * From Ruby 3.2 with Variable Width Allocation, it returns the actual slot + * size used plus any additional memory allocated outside the slot (such + * as external strings, arrays, or hash tables). */ static VALUE @@ -61,17 +61,10 @@ total_i(VALUE v, void *ptr) { struct total_data *data = (struct total_data *)ptr; - switch (BUILTIN_TYPE(v)) { - case T_NONE: - case T_IMEMO: - case T_ICLASS: - case T_NODE: - case T_ZOMBIE: - return; - default: - if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) { - data->total += rb_obj_memsize_of(v); - } + if (!rb_objspace_internal_object_p(v)) { + if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) { + data->total += rb_obj_memsize_of(v); + } } } @@ -89,15 +82,15 @@ heap_iter(void *vstart, void *vend, size_t stride, void *ptr) VALUE v; for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) { - void *poisoned = asan_poisoned_object_p(v); - asan_unpoison_object(v, false); + void *poisoned = rb_asan_poisoned_object_p(v); + rb_asan_unpoison_object(v, false); if (RBASIC(v)->flags) { (*ctx->cb)(v, ctx->data); } if (poisoned) { - asan_poison_object(v); + rb_asan_poison_object(v); } } @@ -115,28 +108,24 @@ each_object_with_flags(each_obj_with_flags cb, void *ctx) /* * call-seq: - * ObjectSpace.memsize_of_all([klass]) -> Integer + * ObjectSpace.memsize_of_all(klass = nil) -> integer * - * Return consuming memory size of all living objects in bytes. + * Returns the total memory size of all living objects in bytes. * - * If +klass+ (should be Class object) is given, return the total memory size - * of instances of the given class. + * ObjectSpace.memsize_of_all # => 12502001 * - * Note that the returned size is incomplete. You need to deal with this - * information as only a *HINT*. Especially, the size of +T_DATA+ may not be - * correct. + * If +klass+ is given (which must be a Class or Module), returns the total + * memory size of objects whose class is, or is a subclass, of +klass+. * - * Note that this method does *NOT* return total malloc'ed memory size. + * class MyClass; end + * ObjectSpace.memsize_of_all(MyClass) # => 0 + * o = MyClass.new + * ObjectSpace.memsize_of_all(MyClass) # => 40 * - * This method can be defined by the following Ruby code: - * - * def memsize_of_all klass = false - * total = 0 - * ObjectSpace.each_object{|e| - * total += ObjectSpace.memsize_of(e) if klass == false || e.kind_of?(klass) - * } - * total - * end + * Note that the value returned may be an underestimate of the actual amount + * of memory used. Therefore, the value returned should only be used as a hint, + * rather than a source of truth. In particular, the size of +T_DATA+ objects may + * not be correct. * * This method is only expected to work with C Ruby. */ @@ -147,7 +136,8 @@ memsize_of_all_m(int argc, VALUE *argv, VALUE self) struct total_data data = {0, 0}; if (argc > 0) { - rb_scan_args(argc, argv, "01", &data.klass); + rb_scan_args(argc, argv, "01", &data.klass); + if (!NIL_P(data.klass)) rb_obj_is_kind_of(Qnil, data.klass); } each_object_with_flags(total_i, &data); @@ -177,8 +167,7 @@ setup_hash(int argc, VALUE *argv) hash = rb_hash_new(); } else if (!RHASH_EMPTY_P(hash)) { - /* WB: no new reference */ - st_foreach(RHASH_TBL_RAW(hash), set_zero_i, hash); + rb_hash_foreach(hash, set_zero_i, (st_data_t)hash); } return hash; @@ -197,33 +186,33 @@ type2sym(enum ruby_value_type i) VALUE type; switch (i) { #define CASE_TYPE(t) case t: type = ID2SYM(rb_intern(#t)); break; - CASE_TYPE(T_NONE); - CASE_TYPE(T_OBJECT); - CASE_TYPE(T_CLASS); - CASE_TYPE(T_MODULE); - CASE_TYPE(T_FLOAT); - CASE_TYPE(T_STRING); - CASE_TYPE(T_REGEXP); - CASE_TYPE(T_ARRAY); - CASE_TYPE(T_HASH); - CASE_TYPE(T_STRUCT); - CASE_TYPE(T_BIGNUM); - CASE_TYPE(T_FILE); - CASE_TYPE(T_DATA); - CASE_TYPE(T_MATCH); - CASE_TYPE(T_COMPLEX); - CASE_TYPE(T_RATIONAL); - CASE_TYPE(T_NIL); - CASE_TYPE(T_TRUE); - CASE_TYPE(T_FALSE); - CASE_TYPE(T_SYMBOL); - CASE_TYPE(T_FIXNUM); - CASE_TYPE(T_UNDEF); - CASE_TYPE(T_IMEMO); - CASE_TYPE(T_NODE); - CASE_TYPE(T_ICLASS); + CASE_TYPE(T_NONE); + CASE_TYPE(T_OBJECT); + CASE_TYPE(T_CLASS); + CASE_TYPE(T_MODULE); + CASE_TYPE(T_FLOAT); + CASE_TYPE(T_STRING); + CASE_TYPE(T_REGEXP); + CASE_TYPE(T_ARRAY); + CASE_TYPE(T_HASH); + CASE_TYPE(T_STRUCT); + CASE_TYPE(T_BIGNUM); + CASE_TYPE(T_FILE); + CASE_TYPE(T_DATA); + CASE_TYPE(T_MATCH); + CASE_TYPE(T_COMPLEX); + CASE_TYPE(T_RATIONAL); + CASE_TYPE(T_NIL); + CASE_TYPE(T_TRUE); + CASE_TYPE(T_FALSE); + CASE_TYPE(T_SYMBOL); + CASE_TYPE(T_FIXNUM); + CASE_TYPE(T_UNDEF); + CASE_TYPE(T_IMEMO); + CASE_TYPE(T_NODE); + CASE_TYPE(T_ICLASS); CASE_TYPE(T_MOVED); - CASE_TYPE(T_ZOMBIE); + CASE_TYPE(T_ZOMBIE); #undef CASE_TYPE default: rb_bug("type2sym: unknown type (%d)", i); } @@ -262,17 +251,17 @@ count_objects_size(int argc, VALUE *argv, VALUE os) VALUE hash = setup_hash(argc, argv); for (i = 0; i <= T_MASK; i++) { - counts[i] = 0; + counts[i] = 0; } each_object_with_flags(cos_i, &counts[0]); for (i = 0; i <= T_MASK; i++) { - if (counts[i]) { - VALUE type = type2sym(i); - total += counts[i]; - rb_hash_aset(hash, type, SIZET2NUM(counts[i])); - } + if (counts[i]) { + VALUE type = type2sym(i); + total += counts[i]; + rb_hash_aset(hash, type, SIZET2NUM(counts[i])); + } } rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total)); return hash; @@ -303,28 +292,27 @@ size_t rb_sym_immortal_count(void); /* * call-seq: - * ObjectSpace.count_symbols([result_hash]) -> hash + * ObjectSpace.count_symbols(result_hash = nil) -> hash * - * Counts symbols for each Symbol type. + * Returns a hash containing the number of objects for each Symbol type. * - * This method is only for MRI developers interested in performance and memory - * usage of Ruby programs. + * The types of Symbols are the following: * - * If the optional argument, result_hash, is given, it is overwritten and - * returned. This is intended to avoid probe effect. + * - +mortal_dynamic_symbol+: Symbols that are garbage collectable. + * - +immortal_dynamic_symbol+: Symbols that are objects allocated from the + * garbage collector, but are not garbage collectable. + * - +immortal_static_symbol+: Symbols that are not allocated from the + * garbage collector, and are thus not garbage collectable. + * - +immortal_symbol+: the sum of +immortal_dynamic_symbol+ and +immortal_static_symbol+. * - * Note: - * The contents of the returned hash is implementation defined. - * It may be changed in future. - * - * This method is only expected to work with C Ruby. + * If the optional argument +result_hash+ is given, it is overwritten and + * returned. This is intended to avoid the probe effect. * - * On this version of MRI, they have 3 types of Symbols (and 1 total counts). + * This method is intended for developers interested in performance and memory + * usage of Ruby programs. The contents of the returned hash is implementation + * specific and may change in the future. * - * * mortal_dynamic_symbol: GC target symbols (collected by GC) - * * immortal_dynamic_symbol: Immortal symbols promoted from dynamic symbols (do not collected by GC) - * * immortal_static_symbol: Immortal symbols (do not collected by GC) - * * immortal_symbol: total immortal symbols (immortal_dynamic_symbol+immortal_static_symbol) + * This method is only expected to work with C Ruby. */ static VALUE @@ -345,174 +333,6 @@ count_symbols(int argc, VALUE *argv, VALUE os) } static void -cn_i(VALUE v, void *n) -{ - size_t *nodes = (size_t *)n; - - if (BUILTIN_TYPE(v) == T_NODE) { - size_t s = nd_type((NODE *)v); - nodes[s]++; - } -} - -/* - * call-seq: - * ObjectSpace.count_nodes([result_hash]) -> hash - * - * Counts nodes for each node type. - * - * This method is only for MRI developers interested in performance and memory - * usage of Ruby programs. - * - * It returns a hash as: - * - * {:NODE_METHOD=>2027, :NODE_FBODY=>1927, :NODE_CFUNC=>1798, ...} - * - * If the optional argument, result_hash, is given, it is overwritten and - * returned. This is intended to avoid probe effect. - * - * Note: - * The contents of the returned hash is implementation defined. - * It may be changed in future. - * - * This method is only expected to work with C Ruby. - */ - -static VALUE -count_nodes(int argc, VALUE *argv, VALUE os) -{ - size_t nodes[NODE_LAST+1]; - enum node_type i; - VALUE hash = setup_hash(argc, argv); - - for (i = 0; i <= NODE_LAST; i++) { - nodes[i] = 0; - } - - each_object_with_flags(cn_i, &nodes[0]); - - for (i=0; i<NODE_LAST; i++) { - if (nodes[i] != 0) { - VALUE node; - switch (i) { -#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); goto set - COUNT_NODE(NODE_SCOPE); - COUNT_NODE(NODE_BLOCK); - COUNT_NODE(NODE_IF); - COUNT_NODE(NODE_UNLESS); - COUNT_NODE(NODE_CASE); - COUNT_NODE(NODE_CASE2); - COUNT_NODE(NODE_CASE3); - COUNT_NODE(NODE_WHEN); - COUNT_NODE(NODE_IN); - COUNT_NODE(NODE_WHILE); - COUNT_NODE(NODE_UNTIL); - COUNT_NODE(NODE_ITER); - COUNT_NODE(NODE_FOR); - COUNT_NODE(NODE_FOR_MASGN); - COUNT_NODE(NODE_BREAK); - COUNT_NODE(NODE_NEXT); - COUNT_NODE(NODE_REDO); - COUNT_NODE(NODE_RETRY); - COUNT_NODE(NODE_BEGIN); - COUNT_NODE(NODE_RESCUE); - COUNT_NODE(NODE_RESBODY); - COUNT_NODE(NODE_ENSURE); - COUNT_NODE(NODE_AND); - COUNT_NODE(NODE_OR); - COUNT_NODE(NODE_MASGN); - COUNT_NODE(NODE_LASGN); - COUNT_NODE(NODE_DASGN); - COUNT_NODE(NODE_DASGN_CURR); - COUNT_NODE(NODE_GASGN); - COUNT_NODE(NODE_IASGN); - COUNT_NODE(NODE_CDECL); - COUNT_NODE(NODE_CVASGN); - COUNT_NODE(NODE_OP_ASGN1); - COUNT_NODE(NODE_OP_ASGN2); - COUNT_NODE(NODE_OP_ASGN_AND); - COUNT_NODE(NODE_OP_ASGN_OR); - COUNT_NODE(NODE_OP_CDECL); - COUNT_NODE(NODE_CALL); - COUNT_NODE(NODE_OPCALL); - COUNT_NODE(NODE_FCALL); - COUNT_NODE(NODE_VCALL); - COUNT_NODE(NODE_QCALL); - COUNT_NODE(NODE_SUPER); - COUNT_NODE(NODE_ZSUPER); - COUNT_NODE(NODE_LIST); - COUNT_NODE(NODE_ZLIST); - COUNT_NODE(NODE_VALUES); - COUNT_NODE(NODE_HASH); - COUNT_NODE(NODE_RETURN); - COUNT_NODE(NODE_YIELD); - COUNT_NODE(NODE_LVAR); - COUNT_NODE(NODE_DVAR); - COUNT_NODE(NODE_GVAR); - COUNT_NODE(NODE_IVAR); - COUNT_NODE(NODE_CONST); - COUNT_NODE(NODE_CVAR); - COUNT_NODE(NODE_NTH_REF); - COUNT_NODE(NODE_BACK_REF); - COUNT_NODE(NODE_MATCH); - COUNT_NODE(NODE_MATCH2); - COUNT_NODE(NODE_MATCH3); - COUNT_NODE(NODE_LIT); - COUNT_NODE(NODE_STR); - COUNT_NODE(NODE_DSTR); - COUNT_NODE(NODE_XSTR); - COUNT_NODE(NODE_DXSTR); - COUNT_NODE(NODE_EVSTR); - COUNT_NODE(NODE_DREGX); - COUNT_NODE(NODE_ONCE); - COUNT_NODE(NODE_ARGS); - COUNT_NODE(NODE_ARGS_AUX); - COUNT_NODE(NODE_OPT_ARG); - COUNT_NODE(NODE_KW_ARG); - COUNT_NODE(NODE_POSTARG); - COUNT_NODE(NODE_ARGSCAT); - COUNT_NODE(NODE_ARGSPUSH); - COUNT_NODE(NODE_SPLAT); - COUNT_NODE(NODE_BLOCK_PASS); - COUNT_NODE(NODE_DEFN); - COUNT_NODE(NODE_DEFS); - COUNT_NODE(NODE_ALIAS); - COUNT_NODE(NODE_VALIAS); - COUNT_NODE(NODE_UNDEF); - COUNT_NODE(NODE_CLASS); - COUNT_NODE(NODE_MODULE); - COUNT_NODE(NODE_SCLASS); - COUNT_NODE(NODE_COLON2); - COUNT_NODE(NODE_COLON3); - COUNT_NODE(NODE_DOT2); - COUNT_NODE(NODE_DOT3); - COUNT_NODE(NODE_FLIP2); - COUNT_NODE(NODE_FLIP3); - COUNT_NODE(NODE_SELF); - COUNT_NODE(NODE_NIL); - COUNT_NODE(NODE_TRUE); - COUNT_NODE(NODE_FALSE); - COUNT_NODE(NODE_ERRINFO); - COUNT_NODE(NODE_DEFINED); - COUNT_NODE(NODE_POSTEXE); - COUNT_NODE(NODE_DSYM); - COUNT_NODE(NODE_ATTRASGN); - COUNT_NODE(NODE_LAMBDA); - COUNT_NODE(NODE_ARYPTN); - COUNT_NODE(NODE_FNDPTN); - COUNT_NODE(NODE_HSHPTN); -#undef COUNT_NODE - case NODE_LAST: break; - } - UNREACHABLE; - set: - rb_hash_aset(hash, node, SIZET2NUM(nodes[i])); - } - } - return hash; -} - -static void cto_i(VALUE v, void *data) { VALUE hash = (VALUE)data; @@ -541,32 +361,22 @@ cto_i(VALUE v, void *data) /* * call-seq: - * ObjectSpace.count_tdata_objects([result_hash]) -> hash - * - * Counts objects for each +T_DATA+ type. + * ObjectSpace.count_tdata_objects(result_hash = nil) -> hash * - * This method is only for MRI developers interested in performance and memory - * usage of Ruby programs. - * - * It returns a hash as: + * Returns a hash containing the number of objects for each +T_DATA+ type. + * The keys are Class objects when the +T_DATA+ object has an associated class, + * or Symbol objects of the name defined in the +rb_data_type_struct+ for internal + * +T_DATA+ objects. * - * {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6, - * :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99, - * ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1, - * Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2} - * # T_DATA objects existing at startup on r32276. + * ObjectSpace.count_tdata_objects + * # => {RBS::Location => 39255, marshal_compat_table: 1, Encoding => 103, mutex: 1, ... } * - * If the optional argument, result_hash, is given, it is overwritten and - * returned. This is intended to avoid probe effect. + * If the optional argument +result_hash+ is given, it is overwritten and + * returned. This is intended to avoid the probe effect. * - * The contents of the returned hash is implementation specific and may change - * in the future. - * - * In this version, keys are Class object or Symbol object. - * - * If object is kind of normal (accessible) object, the key is Class object. - * If object is not a kind of normal (internal) object, the key is symbol - * name, registered by rb_data_type_struct. + * This method is intended for developers interested in performance and memory + * usage of Ruby programs. The contents of the returned hash is implementation + * specific and may change in the future. * * This method is only expected to work with C Ruby. */ @@ -605,28 +415,22 @@ count_imemo_objects_i(VALUE v, void *data) /* * call-seq: - * ObjectSpace.count_imemo_objects([result_hash]) -> hash - * - * Counts objects for each +T_IMEMO+ type. - * - * This method is only for MRI developers interested in performance and memory - * usage of Ruby programs. + * ObjectSpace.count_imemo_objects(result_hash = nil) -> hash * - * It returns a hash as: - * - * {:imemo_ifunc=>8, - * :imemo_svar=>7, - * :imemo_cref=>509, - * :imemo_memo=>1, - * :imemo_throw_data=>1} + * Returns a hash containing the number of objects for each +T_IMEMO+ type. + * The keys are Symbol objects of the +T_IMEMO+ type name. + * +T_IMEMO+ objects are Ruby internal objects that are not visible to Ruby + * programs. * - * If the optional argument, result_hash, is given, it is overwritten and - * returned. This is intended to avoid probe effect. + * ObjectSpace.count_imemo_objects + * # => {imemo_callcache: 5482, imemo_constcache: 1258, imemo_ment: 13906, ... } * - * The contents of the returned hash is implementation specific and may change - * in the future. + * If the optional argument +result_hash+ is given, it is overwritten and + * returned. This is intended to avoid the probe effect. * - * In this version, keys are symbol objects. + * This method is intended for developers interested in performance and memory + * usage of Ruby programs. The contents of the returned hash is implementation + * specific and may change in the future. * * This method is only expected to work with C Ruby. */ @@ -637,20 +441,21 @@ count_imemo_objects(int argc, VALUE *argv, VALUE self) VALUE hash = setup_hash(argc, argv); if (imemo_type_ids[0] == 0) { - imemo_type_ids[0] = rb_intern("imemo_env"); - imemo_type_ids[1] = rb_intern("imemo_cref"); - imemo_type_ids[2] = rb_intern("imemo_svar"); - imemo_type_ids[3] = rb_intern("imemo_throw_data"); - imemo_type_ids[4] = rb_intern("imemo_ifunc"); - imemo_type_ids[5] = rb_intern("imemo_memo"); - imemo_type_ids[6] = rb_intern("imemo_ment"); - imemo_type_ids[7] = rb_intern("imemo_iseq"); - imemo_type_ids[8] = rb_intern("imemo_tmpbuf"); - imemo_type_ids[9] = rb_intern("imemo_ast"); - imemo_type_ids[10] = rb_intern("imemo_parser_strterm"); - imemo_type_ids[11] = rb_intern("imemo_callinfo"); - imemo_type_ids[12] = rb_intern("imemo_callcache"); - imemo_type_ids[13] = rb_intern("imemo_constcache"); +#define INIT_IMEMO_TYPE_ID(n) (imemo_type_ids[n] = rb_intern_const(#n)) + INIT_IMEMO_TYPE_ID(imemo_env); + INIT_IMEMO_TYPE_ID(imemo_cref); + INIT_IMEMO_TYPE_ID(imemo_svar); + INIT_IMEMO_TYPE_ID(imemo_throw_data); + INIT_IMEMO_TYPE_ID(imemo_ifunc); + INIT_IMEMO_TYPE_ID(imemo_memo); + INIT_IMEMO_TYPE_ID(imemo_ment); + INIT_IMEMO_TYPE_ID(imemo_iseq); + INIT_IMEMO_TYPE_ID(imemo_tmpbuf); + INIT_IMEMO_TYPE_ID(imemo_callinfo); + INIT_IMEMO_TYPE_ID(imemo_callcache); + INIT_IMEMO_TYPE_ID(imemo_constcache); + INIT_IMEMO_TYPE_ID(imemo_fields); +#undef INIT_IMEMO_TYPE_ID } each_object_with_flags(count_imemo_objects_i, (void *)hash); @@ -713,7 +518,7 @@ iow_internal_object_id(VALUE self) struct rof_data { VALUE refs; - VALUE internals; + VALUE values; }; static void @@ -723,12 +528,16 @@ reachable_object_from_i(VALUE obj, void *data_ptr) VALUE key = obj; VALUE val = obj; - if (rb_objspace_markable_object_p(obj)) { - if (rb_objspace_internal_object_p(obj)) { - val = iow_newobj(obj); - rb_ary_push(data->internals, val); - } - rb_hash_aset(data->refs, key, val); + if (!rb_objspace_garbage_object_p(obj)) { + if (NIL_P(rb_hash_lookup(data->refs, key))) { + rb_hash_aset(data->refs, key, Qtrue); + + if (rb_objspace_internal_object_p(obj)) { + val = iow_newobj(obj); + } + + rb_ary_push(data->values, val); + } } } @@ -765,7 +574,7 @@ collect_values(st_data_t key, st_data_t value, st_data_t data) * * With this method, you can find memory leaks. * - * This method is only expected to work except with C Ruby. + * This method is only expected to work with C Ruby. * * Example: * ObjectSpace.reachable_objects_from(['a', 'b', 'c']) @@ -785,22 +594,22 @@ collect_values(st_data_t key, st_data_t value, st_data_t data) static VALUE reachable_objects_from(VALUE self, VALUE obj) { - if (rb_objspace_markable_object_p(obj)) { - struct rof_data data; + if (!RB_SPECIAL_CONST_P(obj)) { + struct rof_data data; - if (rb_typeddata_is_kind_of(obj, &iow_data_type)) { - obj = (VALUE)DATA_PTR(obj); - } + if (rb_typeddata_is_kind_of(obj, &iow_data_type)) { + obj = (VALUE)DATA_PTR(obj); + } - data.refs = rb_ident_hash_new(); - data.internals = rb_ary_new(); + data.refs = rb_obj_hide(rb_ident_hash_new()); + data.values = rb_ary_new(); - rb_objspace_reachable_objects_from(obj, reachable_object_from_i, &data); + rb_objspace_reachable_objects_from(obj, reachable_object_from_i, &data); - return rb_funcall(data.refs, rb_intern("values"), 0); + return data.values; } else { - return Qnil; + return Qnil; } } @@ -819,26 +628,26 @@ reachable_object_from_root_i(const char *category, VALUE obj, void *ptr) VALUE category_objects; if (category == data->last_category) { - category_str = data->last_category_str; - category_objects = data->last_category_objects; + category_str = data->last_category_str; + category_objects = data->last_category_objects; } else { - data->last_category = category; - category_str = data->last_category_str = rb_str_new2(category); - category_objects = data->last_category_objects = rb_ident_hash_new(); - if (!NIL_P(rb_hash_lookup(data->categories, category_str))) { - rb_bug("reachable_object_from_root_i: category should insert at once"); - } - rb_hash_aset(data->categories, category_str, category_objects); + data->last_category = category; + category_str = data->last_category_str = rb_str_new2(category); + category_objects = data->last_category_objects = rb_ident_hash_new(); + if (!NIL_P(rb_hash_lookup(data->categories, category_str))) { + rb_bug("reachable_object_from_root_i: category should insert at once"); + } + rb_hash_aset(data->categories, category_str, category_objects); } - if (rb_objspace_markable_object_p(obj) && - obj != data->categories && - obj != data->last_category_objects) { - if (rb_objspace_internal_object_p(obj)) { - obj = iow_newobj(obj); - } - rb_hash_aset(category_objects, obj, obj); + if (!rb_objspace_garbage_object_p(obj) && + obj != data->categories && + obj != data->last_category_objects) { + if (rb_objspace_internal_object_p(obj)) { + obj = iow_newobj(obj); + } + rb_hash_aset(category_objects, obj, obj); } } @@ -874,14 +683,14 @@ static VALUE wrap_klass_iow(VALUE klass) { if (!RTEST(klass)) { - return Qnil; + return Qnil; } else if (RB_TYPE_P(klass, T_ICLASS) || CLASS_OF(klass) == Qfalse /* hidden object */) { - return iow_newobj(klass); + return iow_newobj(klass); } else { - return klass; + return klass; } } @@ -900,7 +709,7 @@ objspace_internal_class_of(VALUE self, VALUE obj) VALUE klass; if (rb_typeddata_is_kind_of(obj, &iow_data_type)) { - obj = (VALUE)DATA_PTR(obj); + obj = (VALUE)DATA_PTR(obj); } if (RB_TYPE_P(obj, T_IMEMO)) { @@ -927,17 +736,17 @@ objspace_internal_super_of(VALUE self, VALUE obj) VALUE super; if (rb_typeddata_is_kind_of(obj, &iow_data_type)) { - obj = (VALUE)DATA_PTR(obj); + obj = (VALUE)DATA_PTR(obj); } switch (OBJ_BUILTIN_TYPE(obj)) { case T_MODULE: case T_CLASS: case T_ICLASS: - super = RCLASS_SUPER(obj); - break; + super = rb_class_super_of(obj); + break; default: - rb_raise(rb_eArgError, "class or module is expected"); + rb_raise(rb_eArgError, "class or module is expected"); } return wrap_klass_iow(super); @@ -955,7 +764,7 @@ void Init_objspace_dump(VALUE rb_mObjSpace); * * You need to <code>require 'objspace'</code> to use this extension module. * - * Generally, you *SHOULD NOT* use this library if you do not know + * Generally, you *SHOULD* *NOT* use this library if you do not know * about the MRI implementation. Mainly, this library is for (memory) * profiler developers and MRI developers who need to know about MRI * memory usage. @@ -976,7 +785,6 @@ Init_objspace(void) rb_define_module_function(rb_mObjSpace, "count_objects_size", count_objects_size, -1); rb_define_module_function(rb_mObjSpace, "count_symbols", count_symbols, -1); - rb_define_module_function(rb_mObjSpace, "count_nodes", count_nodes, -1); rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1); rb_define_module_function(rb_mObjSpace, "count_imemo_objects", count_imemo_objects, -1); diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c index cf7acb5c6f..da64698346 100644 --- a/ext/objspace/objspace_dump.c +++ b/ext/objspace/objspace_dump.c @@ -12,34 +12,44 @@ **********************************************************************/ -#include "gc.h" +#include "id_table.h" #include "internal.h" +#include "internal/array.h" +#include "internal/class.h" +#include "internal/gc.h" #include "internal/hash.h" +#include "internal/io.h" #include "internal/string.h" #include "internal/sanitizers.h" +#include "symbol.h" +#include "shape.h" #include "node.h" #include "objspace.h" #include "ruby/debug.h" #include "ruby/util.h" #include "ruby/io.h" -#include "vm_core.h" +#include "vm_callinfo.h" +#include "vm_sync.h" RUBY_EXTERN const char ruby_hexdigits[]; #define BUFFER_CAPACITY 4096 struct dump_config { - VALUE type; - VALUE stream; + VALUE given_output; + VALUE output_io; VALUE string; + FILE *stream; const char *root_category; VALUE cur_obj; VALUE cur_obj_klass; + size_t cur_page_slot_size; size_t cur_obj_references; unsigned int roots: 1; unsigned int full_heap: 1; unsigned int partial_dump; size_t since; + size_t shapes_since; unsigned long buffer_len; char buffer[BUFFER_CAPACITY]; }; @@ -49,7 +59,7 @@ dump_flush(struct dump_config *dc) { if (dc->buffer_len) { if (dc->stream) { - size_t written = rb_io_bufwrite(dc->stream, dc->buffer, dc->buffer_len); + size_t written = fwrite(dc->buffer, sizeof(dc->buffer[0]), dc->buffer_len, dc->stream); if (written < dc->buffer_len) { MEMMOVE(dc->buffer, dc->buffer + written, char, dc->buffer_len - written); dc->buffer_len -= written; @@ -75,7 +85,8 @@ buffer_ensure_capa(struct dump_config *dc, unsigned long requested) } } -static void buffer_append(struct dump_config *dc, const char *cstr, unsigned long len) +static void +buffer_append(struct dump_config *dc, const char *cstr, unsigned long len) { if (LIKELY(len > 0)) { buffer_ensure_capa(dc, len); @@ -141,10 +152,10 @@ dump_append_sizet(struct dump_config *dc, const size_t number) } static void -dump_append_c(struct dump_config *dc, char c) +dump_append_c(struct dump_config *dc, unsigned char c) { if (c <= 0x1f) { - const unsigned int width = (sizeof(c) * CHAR_BIT / 4) + 5; + const unsigned int width = rb_strlen_lit("\\u0000") + 1; buffer_ensure_capa(dc, width); unsigned long required = snprintf(dc->buffer + dc->buffer_len, width, "\\u00%02x", c); RUBY_ASSERT(required <= width); @@ -158,11 +169,9 @@ dump_append_c(struct dump_config *dc, char c) } static void -dump_append_ref(struct dump_config *dc, VALUE ref) +dump_append_ptr(struct dump_config *dc, VALUE ref) { - RUBY_ASSERT(ref > 0); - - char buffer[((sizeof(VALUE) * CHAR_BIT + 3) / 4) + 4]; + char buffer[roomof(sizeof(VALUE) * CHAR_BIT, 4) + rb_strlen_lit("\"0x\"")]; char *buffer_start, *buffer_end; buffer_start = buffer_end = &buffer[sizeof(buffer)]; @@ -178,6 +187,14 @@ dump_append_ref(struct dump_config *dc, VALUE ref) } static void +dump_append_ref(struct dump_config *dc, VALUE ref) +{ + RUBY_ASSERT(ref > 0); + dump_append_ptr(dc, ref); +} + + +static void dump_append_string_value(struct dump_config *dc, VALUE obj) { long i; @@ -234,32 +251,32 @@ obj_type(VALUE obj) { switch (BUILTIN_TYPE(obj)) { #define CASE_TYPE(type) case T_##type: return #type - CASE_TYPE(NONE); - CASE_TYPE(NIL); - CASE_TYPE(OBJECT); - CASE_TYPE(CLASS); - CASE_TYPE(ICLASS); - CASE_TYPE(MODULE); - CASE_TYPE(FLOAT); - CASE_TYPE(STRING); - CASE_TYPE(REGEXP); - CASE_TYPE(ARRAY); - CASE_TYPE(HASH); - CASE_TYPE(STRUCT); - CASE_TYPE(BIGNUM); - CASE_TYPE(FILE); - CASE_TYPE(FIXNUM); - CASE_TYPE(TRUE); - CASE_TYPE(FALSE); - CASE_TYPE(DATA); - CASE_TYPE(MATCH); - CASE_TYPE(SYMBOL); - CASE_TYPE(RATIONAL); - CASE_TYPE(COMPLEX); - CASE_TYPE(IMEMO); - CASE_TYPE(UNDEF); - CASE_TYPE(NODE); - CASE_TYPE(ZOMBIE); + CASE_TYPE(NONE); + CASE_TYPE(NIL); + CASE_TYPE(OBJECT); + CASE_TYPE(CLASS); + CASE_TYPE(ICLASS); + CASE_TYPE(MODULE); + CASE_TYPE(FLOAT); + CASE_TYPE(STRING); + CASE_TYPE(REGEXP); + CASE_TYPE(ARRAY); + CASE_TYPE(HASH); + CASE_TYPE(STRUCT); + CASE_TYPE(BIGNUM); + CASE_TYPE(FILE); + CASE_TYPE(FIXNUM); + CASE_TYPE(TRUE); + CASE_TYPE(FALSE); + CASE_TYPE(DATA); + CASE_TYPE(MATCH); + CASE_TYPE(SYMBOL); + CASE_TYPE(RATIONAL); + CASE_TYPE(COMPLEX); + CASE_TYPE(IMEMO); + CASE_TYPE(UNDEF); + CASE_TYPE(NODE); + CASE_TYPE(ZOMBIE); #undef CASE_TYPE default: break; } @@ -312,6 +329,17 @@ reachable_object_i(VALUE ref, void *data) dc->cur_obj_references++; } +static bool +dump_string_ascii_only(const char *str, long size) +{ + for (long i = 0; i < size; i++) { + if (str[i] & 0x80) { + return false; + } + } + return true; +} + static void dump_append_string_content(struct dump_config *dc, VALUE obj) { @@ -322,20 +350,42 @@ dump_append_string_content(struct dump_config *dc, VALUE obj) dump_append_sizet(dc, rb_str_capacity(obj)); } - if (is_ascii_string(obj)) { - dump_append(dc, ", \"value\":"); - dump_append_string_value(dc, obj); + if (RSTRING_LEN(obj) && rb_enc_asciicompat(rb_enc_from_index(ENCODING_GET(obj)))) { + int cr = ENC_CODERANGE(obj); + if (cr == RUBY_ENC_CODERANGE_UNKNOWN) { + if (dump_string_ascii_only(RSTRING_PTR(obj), RSTRING_LEN(obj))) { + cr = RUBY_ENC_CODERANGE_7BIT; + } + } + if (cr == RUBY_ENC_CODERANGE_7BIT) { + dump_append(dc, ", \"value\":"); + dump_append_string_value(dc, obj); + } + } +} + +static inline void +dump_append_id(struct dump_config *dc, ID id) +{ + VALUE str = rb_sym2str(ID2SYM(id)); + if (RTEST(str)) { + dump_append_string_value(dc, str); + } + else { + dump_append(dc, "\"ID_INTERNAL("); + dump_append_sizet(dc, rb_id_to_serial(id)); + dump_append(dc, ")\""); } } + static void dump_object(VALUE obj, struct dump_config *dc) { size_t memsize; struct allocation_info *ainfo = objspace_lookup_allocation_info(obj); rb_io_t *fptr; - ID flags[RB_OBJ_GC_FLAGS_MAX]; - size_t n, i; + ID mid; if (SPECIAL_CONST_P(obj)) { dump_append_special_const(dc, obj); @@ -344,7 +394,12 @@ dump_object(VALUE obj, struct dump_config *dc) dc->cur_obj = obj; dc->cur_obj_references = 0; - dc->cur_obj_klass = BUILTIN_TYPE(obj) == T_NODE ? 0 : RBASIC_CLASS(obj); + if (BUILTIN_TYPE(obj) == T_NODE || (BUILTIN_TYPE(obj) == T_IMEMO && !IMEMO_TYPE_P(obj, imemo_fields))) { + dc->cur_obj_klass = 0; + } + else { + dc->cur_obj_klass = RBASIC_CLASS(obj); + } if (dc->partial_dump && (!ainfo || ainfo->generation < dc->since)) { return; @@ -360,6 +415,15 @@ dump_object(VALUE obj, struct dump_config *dc) dump_append(dc, obj_type(obj)); dump_append(dc, "\""); + if (BUILTIN_TYPE(obj) != T_IMEMO || IMEMO_TYPE_P(obj, imemo_fields)) { + size_t shape_id = rb_obj_shape_id(obj) & SHAPE_ID_OFFSET_MASK; + dump_append(dc, ", \"shape_id\":"); + dump_append_sizet(dc, shape_id); + } + + dump_append(dc, ", \"slot_size\":"); + dump_append_sizet(dc, dc->cur_page_slot_size); + if (dc->cur_obj_klass) { dump_append(dc, ", \"class\":"); dump_append_ref(dc, dc->cur_obj_klass); @@ -376,6 +440,36 @@ dump_object(VALUE obj, struct dump_config *dc) dump_append(dc, ", \"imemo_type\":\""); dump_append(dc, rb_imemo_name(imemo_type(obj))); dump_append(dc, "\""); + + switch (imemo_type(obj)) { + case imemo_callinfo: + mid = vm_ci_mid((const struct rb_callinfo *)obj); + if (mid != 0) { + dump_append(dc, ", \"mid\":"); + dump_append_id(dc, mid); + } + break; + + case imemo_callcache: + { + VALUE klass = ((const struct rb_callcache *)obj)->klass; + if (klass != Qundef) { + mid = vm_cc_cme((const struct rb_callcache *)obj)->called_id; + if (mid != 0) { + dump_append(dc, ", \"called_id\":"); + dump_append_id(dc, mid); + + } + + dump_append(dc, ", \"receiver_class\":"); + dump_append_ref(dc, klass); + } + } + break; + + default: + break; + } break; case T_SYMBOL: @@ -385,10 +479,10 @@ dump_object(VALUE obj, struct dump_config *dc) case T_STRING: if (STR_EMBED_P(obj)) dump_append(dc, ", \"embedded\":true"); - if (is_broken_string(obj)) - dump_append(dc, ", \"broken\":true"); if (FL_TEST(obj, RSTRING_FSTR)) dump_append(dc, ", \"fstring\":true"); + if (CHILLED_STRING_P(obj)) + dump_append(dc, ", \"chilled\":true"); if (STR_SHARED_P(obj)) dump_append(dc, ", \"shared\":true"); else @@ -399,6 +493,27 @@ dump_object(VALUE obj, struct dump_config *dc) dump_append(dc, rb_enc_name(rb_enc_from_index(ENCODING_GET(obj)))); dump_append(dc, "\""); } + + dump_append(dc, ", \"coderange\":\""); + switch (RB_ENC_CODERANGE(obj)) { + case RUBY_ENC_CODERANGE_UNKNOWN: + dump_append(dc, "unknown"); + break; + case RUBY_ENC_CODERANGE_7BIT: + dump_append(dc, "7bit"); + break; + case RUBY_ENC_CODERANGE_VALID: + dump_append(dc, "valid"); + break; + case RUBY_ENC_CODERANGE_BROKEN: + dump_append(dc, "broken"); + break; + } + dump_append(dc, "\""); + + if (RB_ENC_CODERANGE(obj) == RUBY_ENC_CODERANGE_BROKEN) + dump_append(dc, ", \"broken\":true"); + break; case T_HASH: @@ -413,9 +528,9 @@ dump_object(VALUE obj, struct dump_config *dc) case T_ARRAY: dump_append(dc, ", \"length\":"); dump_append_ld(dc, RARRAY_LEN(obj)); - if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, ELTS_SHARED)) + if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, RARRAY_SHARED_FLAG)) dump_append(dc, ", \"shared\":true"); - if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, RARRAY_EMBED_FLAG)) + if (FL_TEST(obj, RARRAY_EMBED_FLAG)) dump_append(dc, ", \"embedded\":true"); break; @@ -427,6 +542,9 @@ dump_object(VALUE obj, struct dump_config *dc) break; case T_CLASS: + dump_append(dc, ", \"variation_count\":"); + dump_append_d(dc, rb_class_variation_count(obj)); + case T_MODULE: if (rb_class_get_superclass(obj)) { dump_append(dc, ", \"superclass\":"); @@ -436,10 +554,10 @@ dump_object(VALUE obj, struct dump_config *dc) if (dc->cur_obj_klass) { VALUE mod_name = rb_mod_name(obj); if (!NIL_P(mod_name)) { - dump_append(dc, ", \"name\":\""); - dump_append(dc, RSTRING_PTR(mod_name)); - dump_append(dc, "\""); - } else { + dump_append(dc, ", \"name\":"); + dump_append_string_value(dc, mod_name); + } + else { VALUE real_mod_name = rb_mod_name(rb_class_real(obj)); if (RTEST(real_mod_name)) { dump_append(dc, ", \"real_class_name\":\""); @@ -448,7 +566,7 @@ dump_object(VALUE obj, struct dump_config *dc) } } - if (FL_TEST(obj, FL_SINGLETON)) { + if (rb_class_singleton_p(obj)) { dump_append(dc, ", \"singleton\":true"); } } @@ -469,8 +587,15 @@ dump_object(VALUE obj, struct dump_config *dc) break; case T_OBJECT: + if (!FL_TEST_RAW(obj, ROBJECT_HEAP)) { + dump_append(dc, ", \"embedded\":true"); + } + dump_append(dc, ", \"ivars\":"); - dump_append_lu(dc, ROBJECT_NUMIV(obj)); + dump_append_lu(dc, ROBJECT_FIELDS_COUNT(obj)); + if (rb_shape_obj_too_complex_p(obj)) { + dump_append(dc, ", \"too_complex_shape\":true"); + } break; case T_FILE: @@ -482,8 +607,8 @@ dump_object(VALUE obj, struct dump_config *dc) break; case T_ZOMBIE: - dump_append(dc, "}\n"); - return; + dump_append(dc, "}\n"); + return; default: break; @@ -517,14 +642,24 @@ dump_object(VALUE obj, struct dump_config *dc) dump_append_sizet(dc, memsize); } - if ((n = rb_obj_gc_flags(obj, flags, sizeof(flags))) > 0) { - dump_append(dc, ", \"flags\":{"); - for (i=0; i<n; i++) { - dump_append(dc, "\""); - dump_append(dc, rb_id2name(flags[i])); - dump_append(dc, "\":true"); - if (i != n-1) dump_append(dc, ", "); + struct rb_gc_object_metadata_entry *gc_metadata = rb_gc_object_metadata(obj); + for (int i = 0; gc_metadata[i].name != 0; i++) { + if (i == 0) { + dump_append(dc, ", \"flags\":{"); + } + else { + dump_append(dc, ", "); } + + dump_append(dc, "\""); + dump_append(dc, rb_id2name(gc_metadata[i].name)); + dump_append(dc, "\":"); + dump_append_special_const(dc, gc_metadata[i].val); + } + + /* If rb_gc_object_metadata had any entries, we need to close the opening + * `"flags":{`. */ + if (gc_metadata[0].name != 0) { dump_append(dc, "}"); } @@ -537,14 +672,15 @@ heap_i(void *vstart, void *vend, size_t stride, void *data) struct dump_config *dc = (struct dump_config *)data; VALUE v = (VALUE)vstart; for (; v != (VALUE)vend; v += stride) { - void *ptr = asan_poisoned_object_p(v); - asan_unpoison_object(v, false); + void *ptr = rb_asan_poisoned_object_p(v); + rb_asan_unpoison_object(v, false); + dc->cur_page_slot_size = stride; - if (dc->full_heap || RBASIC(v)->flags) - dump_object(v, dc); + if (dc->full_heap || RBASIC(v)->flags) + dump_object(v, dc); if (ptr) { - asan_poison_object(v); + rb_asan_poison_object(v); } } return 0; @@ -573,17 +709,36 @@ root_obj_i(const char *category, VALUE obj, void *data) } static void -dump_output(struct dump_config *dc, VALUE output, VALUE full, VALUE since) +dump_output(struct dump_config *dc, VALUE output, VALUE full, VALUE since, VALUE shapes) { - + dc->given_output = output; dc->full_heap = 0; dc->buffer_len = 0; if (TYPE(output) == T_STRING) { - dc->stream = Qfalse; + dc->stream = NULL; dc->string = output; - } else { - dc->stream = output; + } + else { + rb_io_t *fptr; + // Output should be an IO, typecheck and get a FILE* for writing. + // We cannot write with the usual IO code here because writes + // interleave with calls to rb_gc_mark(). The usual IO code can + // cause a thread switch, raise exceptions, and even run arbitrary + // ruby code through the fiber scheduler. + // + // Mark functions generally can't handle these possibilities so + // the usual IO code is unsafe in this context. (For example, + // there are many ways to crash when ruby code runs and mutates + // the execution context while rb_execution_context_mark() is in + // progress.) + // + // Using FILE* isn't perfect, but it avoids the most acute problems. + output = rb_io_get_io(output); + dc->output_io = rb_io_get_write_io(output); + rb_io_flush(dc->output_io); + GetOpenFile(dc->output_io, fptr); + dc->stream = rb_io_stdio_file(fptr); dc->string = Qfalse; } @@ -594,9 +749,12 @@ dump_output(struct dump_config *dc, VALUE output, VALUE full, VALUE since) if (RTEST(since)) { dc->partial_dump = 1; dc->since = NUM2SIZET(since); - } else { + } + else { dc->partial_dump = 0; } + + dc->shapes_since = RTEST(shapes) ? NUM2SIZET(shapes) : 0; } static VALUE @@ -604,30 +762,100 @@ dump_result(struct dump_config *dc) { dump_flush(dc); + if (dc->stream) { + fflush(dc->stream); + } if (dc->string) { return dc->string; - } else { - rb_io_flush(dc->stream); - return dc->stream; } + return dc->given_output; } static VALUE -objspace_dump(VALUE os, VALUE obj, VALUE output) +dump_locked(void *args_p) { struct dump_config dc = {0,}; - dump_output(&dc, output, Qnil, Qnil); + VALUE obj = ((VALUE*)args_p)[0]; + VALUE output = ((VALUE*)args_p)[1]; + + if (!RB_SPECIAL_CONST_P(obj)) { + dc.cur_page_slot_size = rb_gc_obj_slot_size(obj); + } + dump_output(&dc, output, Qnil, Qnil, Qnil); dump_object(obj, &dc); return dump_result(&dc); } +/* :nodoc: */ +static VALUE +objspace_dump(VALUE os, VALUE obj, VALUE output) +{ + VALUE args[2]; + args[0] = obj; + args[1] = output; + return rb_vm_lock_with_barrier(dump_locked, (void*)args); +} + +static void +shape_id_i(shape_id_t shape_id, void *data) +{ + struct dump_config *dc = (struct dump_config *)data; + + if (shape_id < dc->shapes_since) { + return; + } + + dump_append(dc, "{\"address\":"); + dump_append_ref(dc, (VALUE)RSHAPE(shape_id)); + + dump_append(dc, ", \"type\":\"SHAPE\", \"id\":"); + dump_append_sizet(dc, shape_id); + + if (RSHAPE_TYPE(shape_id) != SHAPE_ROOT) { + dump_append(dc, ", \"parent_id\":"); + dump_append_lu(dc, RSHAPE_PARENT_RAW_ID(shape_id)); + } + + dump_append(dc, ", \"depth\":"); + dump_append_sizet(dc, rb_shape_depth(shape_id)); + + switch (RSHAPE_TYPE(shape_id)) { + case SHAPE_ROOT: + dump_append(dc, ", \"shape_type\":\"ROOT\""); + break; + case SHAPE_IVAR: + dump_append(dc, ", \"shape_type\":\"IVAR\""); + + dump_append(dc, ",\"edge_name\":"); + dump_append_id(dc, RSHAPE_EDGE_NAME(shape_id)); + + break; + case SHAPE_OBJ_ID: + dump_append(dc, ", \"shape_type\":\"OBJ_ID\""); + break; + } + + dump_append(dc, ", \"edges\":"); + dump_append_sizet(dc, rb_shape_edges_count(shape_id)); + + dump_append(dc, ", \"memsize\":"); + dump_append_sizet(dc, rb_shape_memsize(shape_id)); + + dump_append(dc, "}\n"); +} + static VALUE -objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since) +dump_all_locked(void *args_p) { struct dump_config dc = {0,}; - dump_output(&dc, output, full, since); + VALUE output = ((VALUE*)args_p)[0]; + VALUE full = ((VALUE*)args_p)[1]; + VALUE since = ((VALUE*)args_p)[2]; + VALUE shapes = ((VALUE*)args_p)[3]; + + dump_output(&dc, output, full, since, shapes); if (!dc.partial_dump || dc.since == 0) { /* dump roots */ @@ -635,12 +863,53 @@ objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since) if (dc.roots) dump_append(&dc, "]}\n"); } + if (RTEST(shapes)) { + rb_shape_each_shape_id(shape_id_i, &dc); + } + /* dump all objects */ rb_objspace_each_objects(heap_i, &dc); return dump_result(&dc); } +/* :nodoc: */ +static VALUE +objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes) +{ + VALUE args[4]; + args[0] = output; + args[1] = full; + args[2] = since; + args[3] = shapes; + return rb_vm_lock_with_barrier(dump_all_locked, (void*)args); +} + +static VALUE +dump_shapes_locked(void *args_p) +{ + struct dump_config dc = {0,}; + VALUE output = ((VALUE*)args_p)[0]; + VALUE shapes = ((VALUE*)args_p)[1]; + + dump_output(&dc, output, Qfalse, Qnil, shapes); + + if (RTEST(shapes)) { + rb_shape_each_shape_id(shape_id_i, &dc); + } + return dump_result(&dc); +} + +/* :nodoc: */ +static VALUE +objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes) +{ + VALUE args[2]; + args[0] = output; + args[1] = shapes; + return rb_vm_lock_with_barrier(dump_shapes_locked, (void*)args); +} + void Init_objspace_dump(VALUE rb_mObjSpace) { @@ -648,10 +917,11 @@ Init_objspace_dump(VALUE rb_mObjSpace) #if 0 rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */ #endif +#ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); +#endif rb_define_module_function(rb_mObjSpace, "_dump", objspace_dump, 2); - rb_define_module_function(rb_mObjSpace, "_dump_all", objspace_dump_all, 3); - - /* force create static IDs */ - rb_obj_gc_flags(rb_mObjSpace, 0, 0); + rb_define_module_function(rb_mObjSpace, "_dump_all", objspace_dump_all, 4); + rb_define_module_function(rb_mObjSpace, "_dump_shapes", objspace_dump_shapes, 2); } diff --git a/ext/openssl/History.md b/ext/openssl/History.md index 46435f9be6..419237ff16 100644 --- a/ext/openssl/History.md +++ b/ext/openssl/History.md @@ -1,3 +1,489 @@ +Version 4.0.0 +============= + +Compatibility +------------- + +* Ruby >= 2.7 +* OpenSSL >= 1.1.1, LibreSSL >= 3.9, and AWS-LC 1.66.0 + - Removed support for OpenSSL 1.0.2-1.1.0 and LibreSSL 3.1-3.8. + [[GitHub #835]](https://github.com/ruby/openssl/issues/835) + - Added support for AWS-LC. + [[GitHub #833]](https://github.com/ruby/openssl/issues/833) + + +Notable changes +--------------- + +* `OpenSSL::SSL` + - Reduce overhead when writing to `OpenSSL::SSL::SSLSocket`. `#syswrite` no + longer creates a temporary String object. + [[GitHub #831]](https://github.com/ruby/openssl/pull/831) + - Make `OpenSSL::SSL::SSLContext#min_version=` and `#max_version=` wrap the + corresponding OpenSSL APIs directly, and remove the fallback to SSL options. + [[GitHub #849]](https://github.com/ruby/openssl/pull/849) + - Add `OpenSSL::SSL::SSLContext#sigalgs=` and `#client_sigalgs=` for + specifying signature algorithms to use for connections. + [[GitHub #895]](https://github.com/ruby/openssl/pull/895) + - Rename `OpenSSL::SSL::SSLContext#ecdh_curves=` to `#groups=` following + the underlying OpenSSL API rename. This method is no longer specific to + ECDHE. The old method remains as an alias. + [[GitHub #900]](https://github.com/ruby/openssl/pull/900) + - Add `OpenSSL::SSL::SSLSocket#sigalg`, `#peer_sigalg`, and `#group` for + getting the signature algorithm and the key agreement group used in the + current connection. + [[GitHub #908]](https://github.com/ruby/openssl/pull/908) + - Enable `SSL_CTX_set_dh_auto()` for servers by default. + [[GitHub #924]](https://github.com/ruby/openssl/pull/924) + - Improve Ractor compatibility. Note that the internal-use constant + `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS` is now frozen. + [[GitHub #925]](https://github.com/ruby/openssl/pull/925) +* `OpenSSL::PKey` + - Remove `OpenSSL::PKey::EC::Point#mul` support with array arguments. The + underlying OpenSSL API has been removed, and the method has been deprecated + since ruby/openssl v3.0.0. + [[GitHub #843]](https://github.com/ruby/openssl/pull/843) + - `OpenSSL::PKey::{RSA,DSA,DH}#params` uses `nil` to indicate missing fields + instead of the number `0`. + [[GitHub #774]](https://github.com/ruby/openssl/pull/774) + - Unify `OpenSSL::PKey::PKeyError` classes. The former subclasses + `OpenSSL::PKey::DHError`, `OpenSSL::PKey::DSAError`, + `OpenSSL::PKey::ECError`, and `OpenSSL::PKey::RSAError` have been merged + into a single class. + [[GitHub #929]](https://github.com/ruby/openssl/pull/929) +* `OpenSSL::Cipher` + - `OpenSSL::Cipher#encrypt` and `#decrypt` no longer accept arguments. + Passing passwords has been deprecated since Ruby 1.8.2 (released in 2004). + [[GitHub #887]](https://github.com/ruby/openssl/pull/887) + - `OpenSSL::Cipher#final` raises `OpenSSL::Cipher::AuthTagError` when the + integrity check fails for AEAD ciphers. `OpenSSL::Cipher::AuthTagError` is a + new subclass of `OpenSSL::Cipher::CipherError`, which was previously raised. + [[GitHub #939]](https://github.com/ruby/openssl/pull/939) + - `OpenSSL::Cipher.new` now raises `OpenSSL::Cipher::CipherError` instead of + `RuntimeError` when OpenSSL does not recognize the algorithm. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) + - Add support for "fetched" cipher algorithms with OpenSSL 3.0 or later. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) +* `OpenSSL::Digest` + - `OpenSSL::Digest.new` now raises `OpenSSL::Digest::DigestError` instead of + `RuntimeError` when OpenSSL does not recognize the algorithm. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) + - Add support for "fetched" digest algorithms with OpenSSL 3.0 or later. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) +* `OpenSSL::ASN1.decode` now assumes a 1950-2049 year range for `UTCTime` + according to RFC 5280. It previously used a 1969-2068 range. The encoder + has always used the 1950-2049 range. + [[GitHub #909]](https://github.com/ruby/openssl/pull/909) +* `OpenSSL::OpenSSLError`, the base class for all ruby/openssl errors, carry + an additional attribute `#errors` to keep the content of OpenSSL's error + queue. Also, add `#detailed_message` for Ruby 3.2 or later. + [[GitHub #976]](https://github.com/ruby/openssl/pull/976) +* `OpenSSL::PKCS7.new` raises `OpenSSL::PKCS7::PKCS7Error` instead of + `ArgumentError` on error to be consistent with other constructors. + [[GitHub #983]](https://github.com/ruby/openssl/pull/983) + + +Version 3.3.2 +============= + +Merged changes in 3.1.3 and 3.2.3. + + +Version 3.3.1 +============= + +Merged changes in 3.1.2 and 3.2.2. + + +Version 3.3.0 +============= + +Compatibility +------------- + +* Ruby version: 2.7 or later +* OpenSSL version: OpenSSL 1.0.2 or later, and LibreSSL 3.1 or later + +Notable changes +--------------- + +* `OpenSSL::SSL` + - `OpenSSL::SSL::SSLSocket#set_params` no longer sets `#min_version=` to TLS + 1.0 except when OpenSSL 1.0.2 is used. This has been done to disable + SSL 3.0, which is not supported by default in OpenSSL 1.1.0 or later, or in + LibreSSL. This lets it respect the system default if the system-wide + configuration file specifies a higher minimum protocol version. + [[GitHub #710]](https://github.com/ruby/openssl/pull/710) + - `OpenSSL::SSL::SSLSocket.new` no longer enables the `OpenSSL::SSL::OP_ALL` + SSL options by default and follows the system default. + [[GitHub #767]](https://github.com/ruby/openssl/pull/767) + - Add the following IO methods to `OpenSSL::SSL::SSLSocket`, which will pass + along to the underlying socket: `#local_address`, `#remote_address`, + `#close_on_exec=`, `#close_on_exec?`, `#wait`, `#wait_readable`, and + `#wait_writable`. + [[GitHub #708]](https://github.com/ruby/openssl/pull/708) + - Update `OpenSSL::SSL::SSLSocket#gets` to take the `chomp` keyword argument. + [[GitHub #708]](https://github.com/ruby/openssl/pull/708) + - Make `OpenSSL::SSL::SSLSocket` respect the `IO#timeout` value of the + underlying socket on Ruby 3.2 or later. `#timeout` and `#timeout=` methods + are also added. + [[GitHub #714]](https://github.com/ruby/openssl/pull/714) + - Add `OpenSSL::SSL::SSLSocket#close_read` and `#close_write`. + [[GitHub #743]](https://github.com/ruby/openssl/pull/743) + - Add `OpenSSL::Digest.digests` to get a list of all available digest + algorithms. + [[GitHub #726]](https://github.com/ruby/openssl/pull/726) + - Fix `OpenSSL::SSL::SSLSocket#read_nonblock` clearing the passed String + buffer when nothing can be read from the connection. + [[GitHub #739]](https://github.com/ruby/openssl/pull/739) +* Add `#to_text` methods to `OpenSSL::Timestamp::Response`, + `OpenSSL::Timestamp::Request`, `OpenSSL::Timestamp::TokenInfo`, and + `OpenSSL::PKCS7` to get a human-readable representation of the object. + [[GitHub #756]](https://github.com/ruby/openssl/pull/756) +* Add `OpenSSL::X509::Certificate#tbs_bytes` to get the DER encoding of the + TBSCertificate. + [[GitHub #753]](https://github.com/ruby/openssl/pull/753) +* Allow passing `nil` as the digest algorithm to `#sign` methods on + `OpenSSL::X509::Certificate`, `OpenSSL::X509::Request`, and + `OpenSSL::X509::CRL`. This adds supports for signing with EdDSA keys. + [[GitHub #761]](https://github.com/ruby/openssl/pull/761) + [[GitHub #804]](https://github.com/ruby/openssl/pull/804) +* Add `OpenSSL::SSL::SSLSocket#readbyte`. + [[GitHub #771]](https://github.com/ruby/openssl/pull/771) +* Change `OpenSSL::X509::Store#time=` to set the time to the `X509_VERIFY_PARAM` + in the `X509_STORE`. This allows `OpenSSL::Timestamp::Response#verify` to + verify a signature with the specified timestamp. + [[GitHub #770]](https://github.com/ruby/openssl/pull/770) +* Make `OpenSSL::PKCS7.encrypt`'s third parameter `cipher` mandatory. It had + an undocumented default value "RC2-40-CBC", which is not only insecure, but + also not supported in OpenSSL 3.0 or later. + [[GitHub #796]](https://github.com/ruby/openssl/pull/796) +* Make `OpenSSL::BN` shareable between ractors when frozen. + [[GitHub #808]](https://github.com/ruby/openssl/pull/808) +* Make `OpenSSL::Config` instances frozen by default, and make it shareable + between ractors. `OpenSSL::Config::DEFAULT_CONFIG_FILE` is also frozen. + [[GitHub #809]](https://github.com/ruby/openssl/pull/809) +* Add `OpenSSL::PKCS12#set_mac` to configure the MAC parameters and recalculate + a MAC for the content. + [[GitHub #788]](https://github.com/ruby/openssl/pull/788) + +And various non-user-visible changes and bug fixes. Please see the commit +history for more details. + + +Version 3.2.3 +============= + +Merged changes in 3.1.3. + + +Version 3.2.2 +============= + +Merged changes in 3.1.2. + + +Version 3.2.1 +============= + +Merged changes in 3.0.3. + + +Version 3.2.0 +============= + +Compatibility +------------- + +* Ruby >= 2.7 + - Support for Ruby 2.6 has been removed. Note that Ruby 2.6 reached the + end-of-life in 2022-04. + [[GitHub #639]](https://github.com/ruby/openssl/pull/639) +* OpenSSL >= 1.0.2 or LibreSSL >= 3.1 + +Notable changes +--------------- + +* Add a stub gemspec for JRuby, which depends on the `jruby-openssl` gem. + [[GitHub #598]](https://github.com/ruby/openssl/pull/598) +* Add support for the FIPS module in OpenSSL 3.0/3.1. + [[GitHub #608]](https://github.com/ruby/openssl/pull/608) +* Rework `OpenSSL::PKey` routines for loading DER or PEM encoded keys for better + compatibility with OpenSSL 3.0/3.1 with the FIPS module. + [[GitHub #615]](https://github.com/ruby/openssl/pull/615) + [[GitHub #669]](https://github.com/ruby/openssl/pull/669) +* Add `OpenSSL::Provider` module for loading and unloading OpenSSL 3 providers. + [[GitHub #635]](https://github.com/ruby/openssl/pull/635) +* Add `OpenSSL::PKey.new_raw_private_key`, `.new_raw_public_key`, + `OpenSSL::PKey::PKey#raw_private_key`, and `#raw_public_key` for public key + algorithms that use "raw private/public key", such as X25519 and Ed25519. + [[GitHub #646]](https://github.com/ruby/openssl/pull/646) +* Improve OpenSSL error messages to include additional information when + it is available in OpenSSL's error queue. + [[GitHub #648]](https://github.com/ruby/openssl/pull/648) +* Change `OpenSSL::SSL::SSLContext#ca_file=` and `#ca_path=` to raise + `OpenSSL::SSL::SSLError` instead of printing a warning message. + [[GitHub #659]](https://github.com/ruby/openssl/pull/659) +* Allow `OpenSSL::X509::ExtensionFactory#create_extension` to take OIDs in the + dotted-decimal notation. + [[GitHub #141]](https://github.com/ruby/openssl/pull/141) + + +Version 3.1.3 +============= + +Bug fixes +--------- + +* Fix missing NULL check for `EVP_PKEY_get0()` functions with OpenSSL 3.x. + [[GitHub #957]](https://github.com/ruby/openssl/pull/957) + + +Version 3.1.2 +============= + +Bug fixes +--------- + +* Fix crash when attempting to export an incomplete `OpenSSL::PKey::DSA` key. + [[GitHub #845]](https://github.com/ruby/openssl/issues/845) + [[GitHub #847]](https://github.com/ruby/openssl/pull/847) +* Remove the `OpenSSL::X509::V_FLAG_CRL_CHECK_ALL` flag from the default store + used by `OpenSSL::SSL::SSLContext#set_params`. It causes certificate + verification to fail with OpenSSL 3.6.0. It has no effect with any other + OpenSSL versions. + [[GitHub #949]](https://github.com/ruby/openssl/issues/949) + [[GitHub #950]](https://github.com/ruby/openssl/pull/950) + + +Version 3.1.1 +============= + +Merged changes in 3.0.3. + + +Version 3.1.0 +============= + +Ruby/OpenSSL 3.1 will be maintained for the lifetime of Ruby 3.2. + +Merged bug fixes in 2.2.3 and 3.0.2. Among the new features and changes are: + +Notable changes +--------------- + +* Add `OpenSSL::SSL::SSLContext#ciphersuites=` to allow setting TLS 1.3 cipher + suites. + [[GitHub #493]](https://github.com/ruby/openssl/pull/493) +* Add `OpenSSL::SSL::SSLSocket#export_keying_material` for exporting keying + material of the session, as defined in RFC 5705. + [[GitHub #530]](https://github.com/ruby/openssl/pull/530) +* Add `OpenSSL::SSL::SSLContext#keylog_cb=` for setting the TLS key logging + callback, which is useful for supporting NSS's SSLKEYLOGFILE debugging output. + [[GitHub #536]](https://github.com/ruby/openssl/pull/536) +* Remove the default digest algorithm from `OpenSSL::OCSP::BasicResponse#sign` + and `OpenSSL::OCSP::Request#sign`. Omitting the 5th parameter of these + methods used to be equivalent of specifying SHA-1. This default value is now + removed and we will let the underlying OpenSSL library decide instead. + [[GitHub #507]](https://github.com/ruby/openssl/pull/507) +* Add `OpenSSL::BN#mod_sqrt`. + [[GitHub #553]](https://github.com/ruby/openssl/pull/553) +* Allow calling `OpenSSL::Cipher#update` with an empty string. This was + prohibited to workaround an ancient bug in OpenSSL. + [[GitHub #568]](https://github.com/ruby/openssl/pull/568) +* Fix build on platforms without socket support, such as WASI. `OpenSSL::SSL` + will not be defined if OpenSSL is compiled with `OPENSSL_NO_SOCK`. + [[GitHub #558]](https://github.com/ruby/openssl/pull/558) +* Improve support for recent LibreSSL versions. This includes HKDF support in + LibreSSL 3.6 and Ed25519 support in LibreSSL 3.7. + + +Version 3.0.3 +============= + +Bug fixes +--------- + +* Fix a performance regression introduced in v2.1.3 on a buffered write to + `SSLSocket`. + [[GitHub #706]](https://github.com/ruby/openssl/pull/706) +* Fix `OpenSSL::PKCS7` to handle PKCS#7 structures without content. + [[GitHub #690]](https://github.com/ruby/openssl/pull/690) + [[GitHub #752]](https://github.com/ruby/openssl/pull/752) +* Fix `OpenSSL::ASN1::ObjectId#==` with OIDs without a known name. + [[GitHub #791]](https://github.com/ruby/openssl/issues/791) + [[GitHub #792]](https://github.com/ruby/openssl/pull/792) +* Fix `OpenSSL::X509::Certificate#crl_uris` to handle CDP with multiple CRL + URIs. + [[GitHub #775]](https://github.com/ruby/openssl/issues/775) + [[GitHub #776]](https://github.com/ruby/openssl/pull/776) +* Fix `OpenSSL::Cipher#update` to always make the output buffer `String` + independent. + [[Bug #20937]](https://bugs.ruby-lang.org/issues/20937) + [[GitHub #824]](https://github.com/ruby/openssl/pull/824) + + +Version 3.0.2 +============= + +Merged changes in 2.2.3. Additionally, the following issues are fixed by this +release. + +Bug fixes +--------- + +* Fix OpenSSL::PKey::EC#check_key not working correctly on OpenSSL 3.0. + [[GitHub #563]](https://github.com/ruby/openssl/issues/563) + [[GitHub #580]](https://github.com/ruby/openssl/pull/580) + + +Version 3.0.1 +============= + +Merged changes in 2.1.4 and 2.2.2. Additionally, the following issues are fixed +by this release. + +Bug fixes +--------- + +* Add missing type check in OpenSSL::PKey::PKey#sign's optional parameters. + [[GitHub #531]](https://github.com/ruby/openssl/pull/531) +* Work around OpenSSL 3.0's HMAC issues with a zero-length key. + [[GitHub #538]](https://github.com/ruby/openssl/pull/538) +* Fix a regression in OpenSSL::PKey::DSA.generate's default of 'q' size. + [[GitHub #483]](https://github.com/ruby/openssl/issues/483) + [[GitHub #539]](https://github.com/ruby/openssl/pull/539) +* Restore OpenSSL::PKey.read's ability to decode "openssl ecparam -genkey" + output when linked against OpenSSL 3.0. + [[GitHub #535]](https://github.com/ruby/openssl/pull/535) + [[GitHub #540]](https://github.com/ruby/openssl/pull/540) +* Restore error checks in OpenSSL::PKey::EC#{to_der,to_pem}. + [[GitHub #541]](https://github.com/ruby/openssl/pull/541) + + +Version 3.0.0 +============= + +Compatibility notes +------------------- + +* OpenSSL 1.0.1 and Ruby 2.3-2.5 are no longer supported. + [[GitHub #396]](https://github.com/ruby/openssl/pull/396) + [[GitHub #466]](https://github.com/ruby/openssl/pull/466) + +* OpenSSL 3.0 support is added. It is the first major version bump from OpenSSL + 1.1 and contains incompatible changes that affect Ruby/OpenSSL. + Note that OpenSSL 3.0 support is preliminary and not all features are + currently available: + [[GitHub #369]](https://github.com/ruby/openssl/issues/369) + + - Deprecate the ability to modify `OpenSSL::PKey::PKey` instances. OpenSSL 3.0 + made EVP_PKEY structure immutable, and hence the following methods are not + available when Ruby/OpenSSL is linked against OpenSSL 3.0. + [[GitHub #480]](https://github.com/ruby/openssl/pull/480) + + - `OpenSSL::PKey::RSA#set_key`, `#set_factors`, `#set_crt_params` + - `OpenSSL::PKey::DSA#set_pqg`, `#set_key` + - `OpenSSL::PKey::DH#set_pqg`, `#set_key`, `#generate_key!` + - `OpenSSL::PKey::EC#private_key=`, `#public_key=`, `#group=`, `#generate_key!` + + - Deprecate `OpenSSL::Engine`. The ENGINE API has been deprecated in OpenSSL 3.0 + in favor of the new "provider" concept and will be removed in a future + version. + [[GitHub #481]](https://github.com/ruby/openssl/pull/481) + +* `OpenSSL::SSL::SSLContext#tmp_ecdh_callback` has been removed. It has been + deprecated since v2.0.0 because it is incompatible with modern OpenSSL + versions. + [[GitHub #394]](https://github.com/ruby/openssl/pull/394) + +* `OpenSSL::SSL::SSLSocket#read` and `#write` now raise `OpenSSL::SSL::SSLError` + if called before a TLS connection is established. Historically, they + read/wrote unencrypted data to the underlying socket directly in that case. + [[GitHub #9]](https://github.com/ruby/openssl/issues/9) + [[GitHub #469]](https://github.com/ruby/openssl/pull/469) + + +Notable changes +--------------- + +* Enhance OpenSSL::PKey's common interface. + [[GitHub #370]](https://github.com/ruby/openssl/issues/370) + + - Key deserialization: Enhance `OpenSSL::PKey.read` to handle PEM encoding of + DH parameters, which used to be only deserialized by `OpenSSL::PKey::DH.new`. + [[GitHub #328]](https://github.com/ruby/openssl/issues/328) + - Key generation: Add `OpenSSL::PKey.generate_parameters` and + `OpenSSL::PKey.generate_key`. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Public key signing: Enhance `OpenSSL::PKey::PKey#sign` and `#verify` to use + the new EVP_DigestSign() family to enable PureEdDSA support on OpenSSL 1.1.1 + or later. They also now take optional algorithm-specific parameters for more + control. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Low-level public key signing and verification: Add + `OpenSSL::PKey::PKey#sign_raw`, `#verify_raw`, and `#verify_recover`. + [[GitHub #382]](https://github.com/ruby/openssl/issues/382) + - Public key encryption: Add `OpenSSL::PKey::PKey#encrypt` and `#decrypt`. + [[GitHub #382]](https://github.com/ruby/openssl/issues/382) + - Key agreement: Add `OpenSSL::PKey::PKey#derive`. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Key comparison: Add `OpenSSL::PKey::PKey#compare?` to conveniently check + that two keys have common parameters and a public key. + [[GitHub #383]](https://github.com/ruby/openssl/issues/383) + +* Add `OpenSSL::BN#set_flags` and `#get_flags`. This can be used in combination + with `OpenSSL::BN::CONSTTIME` to force constant-time computation. + [[GitHub #417]](https://github.com/ruby/openssl/issues/417) + +* Add `OpenSSL::BN#abs` to get the absolute value of the BIGNUM. + [[GitHub #430]](https://github.com/ruby/openssl/issues/430) + +* Add `OpenSSL::SSL::SSLSocket#getbyte`. + [[GitHub #438]](https://github.com/ruby/openssl/issues/438) + +* Add `OpenSSL::SSL::SSLContext#tmp_dh=`. + [[GitHub #459]](https://github.com/ruby/openssl/pull/459) + +* Add `OpenSSL::X509::Certificate.load` to load a PEM-encoded and concatenated + list of X.509 certificates at once. + [[GitHub #441]](https://github.com/ruby/openssl/pull/441) + +* Change `OpenSSL::X509::Certificate.new` to attempt to deserialize the given + string first as DER encoding first and then as PEM encoding to ensure the + round-trip consistency. + [[GitHub #442]](https://github.com/ruby/openssl/pull/442) + +* Update various part of the code base to use the modern API. No breaking + changes are intended with this. This includes: + + - `OpenSSL::HMAC` uses the EVP API. + [[GitHub #371]](https://github.com/ruby/openssl/issues/371) + - `OpenSSL::Config` uses native OpenSSL API to parse config files. + [[GitHub #342]](https://github.com/ruby/openssl/issues/342) + + +Version 2.2.3 +============= + +Bug fixes +--------- + +* Fix serveral methods in OpenSSL::PKey::EC::Point attempting to raise an error + with an incorrect class, which would end up with a TypeError. + [[GitHub #570]](https://github.com/ruby/openssl/pull/570) +* Fix OpenSSL::PKey::EC::Point#eql? and OpenSSL::PKey::EC::Group#eql? + incorrectly treated OpenSSL's internal errors as "not equal". + [[GitHub #564]](https://github.com/ruby/openssl/pull/564) +* Fix build with LibreSSL 3.5 or later. + + +Version 2.2.2 +============= + +Merged changes in 2.1.4. + + Version 2.2.1 ============= @@ -92,6 +578,16 @@ Notable changes [[GitHub #297]](https://github.com/ruby/openssl/pull/297) +Version 2.1.4 +============= + +Bug fixes +--------- + +* Do not use pkg-config if --with-openssl-dir option is specified. + [[GitHub #486]](https://github.com/ruby/openssl/pull/486) + + Version 2.1.3 ============= @@ -113,7 +609,7 @@ Bug fixes [[GitHub #453]](https://github.com/ruby/openssl/pull/453) * Fix misuse of input record separator in `OpenSSL::Buffering` where it was for output. -* Fix wrong interger casting in `OpenSSL::PKey::EC#dsa_verify_asn1`. +* Fix wrong integer casting in `OpenSSL::PKey::EC#dsa_verify_asn1`. [[GitHub #460]](https://github.com/ruby/openssl/pull/460) * `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support @@ -210,7 +706,7 @@ Security fixes Bug fixes --------- -* Fixed OpenSSL::PKey::*.{new,generate} immediately aborting if the thread is +* Fixed OpenSSL::PKey::\*.{new,generate} immediately aborting if the thread is interrupted. [[Bug #14882]](https://bugs.ruby-lang.org/issues/14882) [[GitHub #205]](https://github.com/ruby/openssl/pull/205) diff --git a/ext/openssl/depend b/ext/openssl/depend index 742c8bbd19..435f4a1c68 100644 --- a/ext/openssl/depend +++ b/ext/openssl/depend @@ -19,6 +19,7 @@ ossl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl.o: $(hdrdir)/ruby/defines.h ossl.o: $(hdrdir)/ruby/encoding.h ossl.o: $(hdrdir)/ruby/intern.h +ossl.o: $(hdrdir)/ruby/internal/abi.h ossl.o: $(hdrdir)/ruby/internal/anyargs.h ossl.o: $(hdrdir)/ruby/internal/arithmetic.h ossl.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -56,6 +57,7 @@ ossl.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl.o: $(hdrdir)/ruby/internal/attr/pure.h ossl.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -124,7 +126,6 @@ ossl.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl.o: $(hdrdir)/ruby/internal/intern/error.h ossl.o: $(hdrdir)/ruby/internal/intern/eval.h ossl.o: $(hdrdir)/ruby/internal/intern/file.h -ossl.o: $(hdrdir)/ruby/internal/intern/gc.h ossl.o: $(hdrdir)/ruby/internal/intern/hash.h ossl.o: $(hdrdir)/ruby/internal/intern/io.h ossl.o: $(hdrdir)/ruby/internal/intern/load.h @@ -141,6 +142,7 @@ ossl.o: $(hdrdir)/ruby/internal/intern/re.h ossl.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl.o: $(hdrdir)/ruby/internal/intern/select.h ossl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl.o: $(hdrdir)/ruby/internal/intern/set.h ossl.o: $(hdrdir)/ruby/internal/intern/signal.h ossl.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl.o: $(hdrdir)/ruby/internal/intern/string.h @@ -155,12 +157,12 @@ ossl.o: $(hdrdir)/ruby/internal/memory.h ossl.o: $(hdrdir)/ruby/internal/method.h ossl.o: $(hdrdir)/ruby/internal/module.h ossl.o: $(hdrdir)/ruby/internal/newobj.h -ossl.o: $(hdrdir)/ruby/internal/rgengc.h ossl.o: $(hdrdir)/ruby/internal/scan_args.h ossl.o: $(hdrdir)/ruby/internal/special_consts.h ossl.o: $(hdrdir)/ruby/internal/static_assert.h ossl.o: $(hdrdir)/ruby/internal/stdalign.h ossl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl.o: $(hdrdir)/ruby/internal/stdckdint.h ossl.o: $(hdrdir)/ruby/internal/symbol.h ossl.o: $(hdrdir)/ruby/internal/value.h ossl.o: $(hdrdir)/ruby/internal/value_type.h @@ -171,6 +173,7 @@ ossl.o: $(hdrdir)/ruby/io.h ossl.o: $(hdrdir)/ruby/missing.h ossl.o: $(hdrdir)/ruby/onigmo.h ossl.o: $(hdrdir)/ruby/oniguruma.h +ossl.o: $(hdrdir)/ruby/ractor.h ossl.o: $(hdrdir)/ruby/ruby.h ossl.o: $(hdrdir)/ruby/st.h ossl.o: $(hdrdir)/ruby/subst.h @@ -192,6 +195,7 @@ ossl.o: ossl_ocsp.h ossl.o: ossl_pkcs12.h ossl.o: ossl_pkcs7.h ossl.o: ossl_pkey.h +ossl.o: ossl_provider.h ossl.o: ossl_rand.h ossl.o: ossl_ssl.h ossl.o: ossl_ts.h @@ -212,6 +216,7 @@ ossl_asn1.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_asn1.o: $(hdrdir)/ruby/defines.h ossl_asn1.o: $(hdrdir)/ruby/encoding.h ossl_asn1.o: $(hdrdir)/ruby/intern.h +ossl_asn1.o: $(hdrdir)/ruby/internal/abi.h ossl_asn1.o: $(hdrdir)/ruby/internal/anyargs.h ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -249,6 +254,7 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_asn1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -317,7 +323,6 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/error.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_asn1.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/io.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/load.h @@ -334,6 +339,7 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/intern/re.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/set.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_asn1.o: $(hdrdir)/ruby/internal/intern/string.h @@ -348,12 +354,12 @@ ossl_asn1.o: $(hdrdir)/ruby/internal/memory.h ossl_asn1.o: $(hdrdir)/ruby/internal/method.h ossl_asn1.o: $(hdrdir)/ruby/internal/module.h ossl_asn1.o: $(hdrdir)/ruby/internal/newobj.h -ossl_asn1.o: $(hdrdir)/ruby/internal/rgengc.h ossl_asn1.o: $(hdrdir)/ruby/internal/scan_args.h ossl_asn1.o: $(hdrdir)/ruby/internal/special_consts.h ossl_asn1.o: $(hdrdir)/ruby/internal/static_assert.h ossl_asn1.o: $(hdrdir)/ruby/internal/stdalign.h ossl_asn1.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_asn1.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_asn1.o: $(hdrdir)/ruby/internal/symbol.h ossl_asn1.o: $(hdrdir)/ruby/internal/value.h ossl_asn1.o: $(hdrdir)/ruby/internal/value_type.h @@ -364,6 +370,7 @@ ossl_asn1.o: $(hdrdir)/ruby/io.h ossl_asn1.o: $(hdrdir)/ruby/missing.h ossl_asn1.o: $(hdrdir)/ruby/onigmo.h ossl_asn1.o: $(hdrdir)/ruby/oniguruma.h +ossl_asn1.o: $(hdrdir)/ruby/ractor.h ossl_asn1.o: $(hdrdir)/ruby/ruby.h ossl_asn1.o: $(hdrdir)/ruby/st.h ossl_asn1.o: $(hdrdir)/ruby/subst.h @@ -385,6 +392,7 @@ ossl_asn1.o: ossl_ocsp.h ossl_asn1.o: ossl_pkcs12.h ossl_asn1.o: ossl_pkcs7.h ossl_asn1.o: ossl_pkey.h +ossl_asn1.o: ossl_provider.h ossl_asn1.o: ossl_rand.h ossl_asn1.o: ossl_ssl.h ossl_asn1.o: ossl_ts.h @@ -405,6 +413,7 @@ ossl_bio.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_bio.o: $(hdrdir)/ruby/defines.h ossl_bio.o: $(hdrdir)/ruby/encoding.h ossl_bio.o: $(hdrdir)/ruby/intern.h +ossl_bio.o: $(hdrdir)/ruby/internal/abi.h ossl_bio.o: $(hdrdir)/ruby/internal/anyargs.h ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -442,6 +451,7 @@ ossl_bio.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_bio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -510,7 +520,6 @@ ossl_bio.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/error.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_bio.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/io.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/load.h @@ -527,6 +536,7 @@ ossl_bio.o: $(hdrdir)/ruby/internal/intern/re.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/select.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/set.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_bio.o: $(hdrdir)/ruby/internal/intern/string.h @@ -541,12 +551,12 @@ ossl_bio.o: $(hdrdir)/ruby/internal/memory.h ossl_bio.o: $(hdrdir)/ruby/internal/method.h ossl_bio.o: $(hdrdir)/ruby/internal/module.h ossl_bio.o: $(hdrdir)/ruby/internal/newobj.h -ossl_bio.o: $(hdrdir)/ruby/internal/rgengc.h ossl_bio.o: $(hdrdir)/ruby/internal/scan_args.h ossl_bio.o: $(hdrdir)/ruby/internal/special_consts.h ossl_bio.o: $(hdrdir)/ruby/internal/static_assert.h ossl_bio.o: $(hdrdir)/ruby/internal/stdalign.h ossl_bio.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_bio.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_bio.o: $(hdrdir)/ruby/internal/symbol.h ossl_bio.o: $(hdrdir)/ruby/internal/value.h ossl_bio.o: $(hdrdir)/ruby/internal/value_type.h @@ -557,6 +567,7 @@ ossl_bio.o: $(hdrdir)/ruby/io.h ossl_bio.o: $(hdrdir)/ruby/missing.h ossl_bio.o: $(hdrdir)/ruby/onigmo.h ossl_bio.o: $(hdrdir)/ruby/oniguruma.h +ossl_bio.o: $(hdrdir)/ruby/ractor.h ossl_bio.o: $(hdrdir)/ruby/ruby.h ossl_bio.o: $(hdrdir)/ruby/st.h ossl_bio.o: $(hdrdir)/ruby/subst.h @@ -578,6 +589,7 @@ ossl_bio.o: ossl_ocsp.h ossl_bio.o: ossl_pkcs12.h ossl_bio.o: ossl_pkcs7.h ossl_bio.o: ossl_pkey.h +ossl_bio.o: ossl_provider.h ossl_bio.o: ossl_rand.h ossl_bio.o: ossl_ssl.h ossl_bio.o: ossl_ts.h @@ -598,6 +610,7 @@ ossl_bn.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_bn.o: $(hdrdir)/ruby/defines.h ossl_bn.o: $(hdrdir)/ruby/encoding.h ossl_bn.o: $(hdrdir)/ruby/intern.h +ossl_bn.o: $(hdrdir)/ruby/internal/abi.h ossl_bn.o: $(hdrdir)/ruby/internal/anyargs.h ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -635,6 +648,7 @@ ossl_bn.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_bn.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -703,7 +717,6 @@ ossl_bn.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/error.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_bn.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/io.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/load.h @@ -720,6 +733,7 @@ ossl_bn.o: $(hdrdir)/ruby/internal/intern/re.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/select.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/set.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_bn.o: $(hdrdir)/ruby/internal/intern/string.h @@ -734,12 +748,12 @@ ossl_bn.o: $(hdrdir)/ruby/internal/memory.h ossl_bn.o: $(hdrdir)/ruby/internal/method.h ossl_bn.o: $(hdrdir)/ruby/internal/module.h ossl_bn.o: $(hdrdir)/ruby/internal/newobj.h -ossl_bn.o: $(hdrdir)/ruby/internal/rgengc.h ossl_bn.o: $(hdrdir)/ruby/internal/scan_args.h ossl_bn.o: $(hdrdir)/ruby/internal/special_consts.h ossl_bn.o: $(hdrdir)/ruby/internal/static_assert.h ossl_bn.o: $(hdrdir)/ruby/internal/stdalign.h ossl_bn.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_bn.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_bn.o: $(hdrdir)/ruby/internal/symbol.h ossl_bn.o: $(hdrdir)/ruby/internal/value.h ossl_bn.o: $(hdrdir)/ruby/internal/value_type.h @@ -772,6 +786,7 @@ ossl_bn.o: ossl_ocsp.h ossl_bn.o: ossl_pkcs12.h ossl_bn.o: ossl_pkcs7.h ossl_bn.o: ossl_pkey.h +ossl_bn.o: ossl_provider.h ossl_bn.o: ossl_rand.h ossl_bn.o: ossl_ssl.h ossl_bn.o: ossl_ts.h @@ -792,6 +807,7 @@ ossl_cipher.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_cipher.o: $(hdrdir)/ruby/defines.h ossl_cipher.o: $(hdrdir)/ruby/encoding.h ossl_cipher.o: $(hdrdir)/ruby/intern.h +ossl_cipher.o: $(hdrdir)/ruby/internal/abi.h ossl_cipher.o: $(hdrdir)/ruby/internal/anyargs.h ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -829,6 +845,7 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_cipher.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -897,7 +914,6 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/error.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_cipher.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/io.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/load.h @@ -914,6 +930,7 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/intern/re.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/set.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_cipher.o: $(hdrdir)/ruby/internal/intern/string.h @@ -928,12 +945,12 @@ ossl_cipher.o: $(hdrdir)/ruby/internal/memory.h ossl_cipher.o: $(hdrdir)/ruby/internal/method.h ossl_cipher.o: $(hdrdir)/ruby/internal/module.h ossl_cipher.o: $(hdrdir)/ruby/internal/newobj.h -ossl_cipher.o: $(hdrdir)/ruby/internal/rgengc.h ossl_cipher.o: $(hdrdir)/ruby/internal/scan_args.h ossl_cipher.o: $(hdrdir)/ruby/internal/special_consts.h ossl_cipher.o: $(hdrdir)/ruby/internal/static_assert.h ossl_cipher.o: $(hdrdir)/ruby/internal/stdalign.h ossl_cipher.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_cipher.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_cipher.o: $(hdrdir)/ruby/internal/symbol.h ossl_cipher.o: $(hdrdir)/ruby/internal/value.h ossl_cipher.o: $(hdrdir)/ruby/internal/value_type.h @@ -944,6 +961,7 @@ ossl_cipher.o: $(hdrdir)/ruby/io.h ossl_cipher.o: $(hdrdir)/ruby/missing.h ossl_cipher.o: $(hdrdir)/ruby/onigmo.h ossl_cipher.o: $(hdrdir)/ruby/oniguruma.h +ossl_cipher.o: $(hdrdir)/ruby/ractor.h ossl_cipher.o: $(hdrdir)/ruby/ruby.h ossl_cipher.o: $(hdrdir)/ruby/st.h ossl_cipher.o: $(hdrdir)/ruby/subst.h @@ -965,6 +983,7 @@ ossl_cipher.o: ossl_ocsp.h ossl_cipher.o: ossl_pkcs12.h ossl_cipher.o: ossl_pkcs7.h ossl_cipher.o: ossl_pkey.h +ossl_cipher.o: ossl_provider.h ossl_cipher.o: ossl_rand.h ossl_cipher.o: ossl_ssl.h ossl_cipher.o: ossl_ts.h @@ -985,6 +1004,7 @@ ossl_config.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_config.o: $(hdrdir)/ruby/defines.h ossl_config.o: $(hdrdir)/ruby/encoding.h ossl_config.o: $(hdrdir)/ruby/intern.h +ossl_config.o: $(hdrdir)/ruby/internal/abi.h ossl_config.o: $(hdrdir)/ruby/internal/anyargs.h ossl_config.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1022,6 +1042,7 @@ ossl_config.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_config.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_config.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_config.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_config.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_config.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_config.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1090,7 +1111,6 @@ ossl_config.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_config.o: $(hdrdir)/ruby/internal/intern/error.h ossl_config.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_config.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_config.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_config.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_config.o: $(hdrdir)/ruby/internal/intern/io.h ossl_config.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1107,6 +1127,7 @@ ossl_config.o: $(hdrdir)/ruby/internal/intern/re.h ossl_config.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_config.o: $(hdrdir)/ruby/internal/intern/select.h ossl_config.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/set.h ossl_config.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_config.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_config.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1121,12 +1142,12 @@ ossl_config.o: $(hdrdir)/ruby/internal/memory.h ossl_config.o: $(hdrdir)/ruby/internal/method.h ossl_config.o: $(hdrdir)/ruby/internal/module.h ossl_config.o: $(hdrdir)/ruby/internal/newobj.h -ossl_config.o: $(hdrdir)/ruby/internal/rgengc.h ossl_config.o: $(hdrdir)/ruby/internal/scan_args.h ossl_config.o: $(hdrdir)/ruby/internal/special_consts.h ossl_config.o: $(hdrdir)/ruby/internal/static_assert.h ossl_config.o: $(hdrdir)/ruby/internal/stdalign.h ossl_config.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_config.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_config.o: $(hdrdir)/ruby/internal/symbol.h ossl_config.o: $(hdrdir)/ruby/internal/value.h ossl_config.o: $(hdrdir)/ruby/internal/value_type.h @@ -1137,6 +1158,7 @@ ossl_config.o: $(hdrdir)/ruby/io.h ossl_config.o: $(hdrdir)/ruby/missing.h ossl_config.o: $(hdrdir)/ruby/onigmo.h ossl_config.o: $(hdrdir)/ruby/oniguruma.h +ossl_config.o: $(hdrdir)/ruby/ractor.h ossl_config.o: $(hdrdir)/ruby/ruby.h ossl_config.o: $(hdrdir)/ruby/st.h ossl_config.o: $(hdrdir)/ruby/subst.h @@ -1158,6 +1180,7 @@ ossl_config.o: ossl_ocsp.h ossl_config.o: ossl_pkcs12.h ossl_config.o: ossl_pkcs7.h ossl_config.o: ossl_pkey.h +ossl_config.o: ossl_provider.h ossl_config.o: ossl_rand.h ossl_config.o: ossl_ssl.h ossl_config.o: ossl_ts.h @@ -1178,6 +1201,7 @@ ossl_digest.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_digest.o: $(hdrdir)/ruby/defines.h ossl_digest.o: $(hdrdir)/ruby/encoding.h ossl_digest.o: $(hdrdir)/ruby/intern.h +ossl_digest.o: $(hdrdir)/ruby/internal/abi.h ossl_digest.o: $(hdrdir)/ruby/internal/anyargs.h ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1215,6 +1239,7 @@ ossl_digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1283,7 +1308,6 @@ ossl_digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/error.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_digest.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/io.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1300,6 +1324,7 @@ ossl_digest.o: $(hdrdir)/ruby/internal/intern/re.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/select.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/set.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_digest.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1314,12 +1339,12 @@ ossl_digest.o: $(hdrdir)/ruby/internal/memory.h ossl_digest.o: $(hdrdir)/ruby/internal/method.h ossl_digest.o: $(hdrdir)/ruby/internal/module.h ossl_digest.o: $(hdrdir)/ruby/internal/newobj.h -ossl_digest.o: $(hdrdir)/ruby/internal/rgengc.h ossl_digest.o: $(hdrdir)/ruby/internal/scan_args.h ossl_digest.o: $(hdrdir)/ruby/internal/special_consts.h ossl_digest.o: $(hdrdir)/ruby/internal/static_assert.h ossl_digest.o: $(hdrdir)/ruby/internal/stdalign.h ossl_digest.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_digest.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_digest.o: $(hdrdir)/ruby/internal/symbol.h ossl_digest.o: $(hdrdir)/ruby/internal/value.h ossl_digest.o: $(hdrdir)/ruby/internal/value_type.h @@ -1330,6 +1355,7 @@ ossl_digest.o: $(hdrdir)/ruby/io.h ossl_digest.o: $(hdrdir)/ruby/missing.h ossl_digest.o: $(hdrdir)/ruby/onigmo.h ossl_digest.o: $(hdrdir)/ruby/oniguruma.h +ossl_digest.o: $(hdrdir)/ruby/ractor.h ossl_digest.o: $(hdrdir)/ruby/ruby.h ossl_digest.o: $(hdrdir)/ruby/st.h ossl_digest.o: $(hdrdir)/ruby/subst.h @@ -1351,6 +1377,7 @@ ossl_digest.o: ossl_ocsp.h ossl_digest.o: ossl_pkcs12.h ossl_digest.o: ossl_pkcs7.h ossl_digest.o: ossl_pkey.h +ossl_digest.o: ossl_provider.h ossl_digest.o: ossl_rand.h ossl_digest.o: ossl_ssl.h ossl_digest.o: ossl_ts.h @@ -1371,6 +1398,7 @@ ossl_engine.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_engine.o: $(hdrdir)/ruby/defines.h ossl_engine.o: $(hdrdir)/ruby/encoding.h ossl_engine.o: $(hdrdir)/ruby/intern.h +ossl_engine.o: $(hdrdir)/ruby/internal/abi.h ossl_engine.o: $(hdrdir)/ruby/internal/anyargs.h ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1408,6 +1436,7 @@ ossl_engine.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_engine.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1476,7 +1505,6 @@ ossl_engine.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/error.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_engine.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/io.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1493,6 +1521,7 @@ ossl_engine.o: $(hdrdir)/ruby/internal/intern/re.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/select.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/set.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_engine.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1507,12 +1536,12 @@ ossl_engine.o: $(hdrdir)/ruby/internal/memory.h ossl_engine.o: $(hdrdir)/ruby/internal/method.h ossl_engine.o: $(hdrdir)/ruby/internal/module.h ossl_engine.o: $(hdrdir)/ruby/internal/newobj.h -ossl_engine.o: $(hdrdir)/ruby/internal/rgengc.h ossl_engine.o: $(hdrdir)/ruby/internal/scan_args.h ossl_engine.o: $(hdrdir)/ruby/internal/special_consts.h ossl_engine.o: $(hdrdir)/ruby/internal/static_assert.h ossl_engine.o: $(hdrdir)/ruby/internal/stdalign.h ossl_engine.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_engine.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_engine.o: $(hdrdir)/ruby/internal/symbol.h ossl_engine.o: $(hdrdir)/ruby/internal/value.h ossl_engine.o: $(hdrdir)/ruby/internal/value_type.h @@ -1523,6 +1552,7 @@ ossl_engine.o: $(hdrdir)/ruby/io.h ossl_engine.o: $(hdrdir)/ruby/missing.h ossl_engine.o: $(hdrdir)/ruby/onigmo.h ossl_engine.o: $(hdrdir)/ruby/oniguruma.h +ossl_engine.o: $(hdrdir)/ruby/ractor.h ossl_engine.o: $(hdrdir)/ruby/ruby.h ossl_engine.o: $(hdrdir)/ruby/st.h ossl_engine.o: $(hdrdir)/ruby/subst.h @@ -1544,6 +1574,7 @@ ossl_engine.o: ossl_ocsp.h ossl_engine.o: ossl_pkcs12.h ossl_engine.o: ossl_pkcs7.h ossl_engine.o: ossl_pkey.h +ossl_engine.o: ossl_provider.h ossl_engine.o: ossl_rand.h ossl_engine.o: ossl_ssl.h ossl_engine.o: ossl_ts.h @@ -1564,6 +1595,7 @@ ossl_hmac.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_hmac.o: $(hdrdir)/ruby/defines.h ossl_hmac.o: $(hdrdir)/ruby/encoding.h ossl_hmac.o: $(hdrdir)/ruby/intern.h +ossl_hmac.o: $(hdrdir)/ruby/internal/abi.h ossl_hmac.o: $(hdrdir)/ruby/internal/anyargs.h ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1601,6 +1633,7 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_hmac.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1669,7 +1702,6 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/error.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_hmac.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/io.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1686,6 +1718,7 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/intern/re.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/set.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_hmac.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1700,12 +1733,12 @@ ossl_hmac.o: $(hdrdir)/ruby/internal/memory.h ossl_hmac.o: $(hdrdir)/ruby/internal/method.h ossl_hmac.o: $(hdrdir)/ruby/internal/module.h ossl_hmac.o: $(hdrdir)/ruby/internal/newobj.h -ossl_hmac.o: $(hdrdir)/ruby/internal/rgengc.h ossl_hmac.o: $(hdrdir)/ruby/internal/scan_args.h ossl_hmac.o: $(hdrdir)/ruby/internal/special_consts.h ossl_hmac.o: $(hdrdir)/ruby/internal/static_assert.h ossl_hmac.o: $(hdrdir)/ruby/internal/stdalign.h ossl_hmac.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_hmac.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_hmac.o: $(hdrdir)/ruby/internal/symbol.h ossl_hmac.o: $(hdrdir)/ruby/internal/value.h ossl_hmac.o: $(hdrdir)/ruby/internal/value_type.h @@ -1716,6 +1749,7 @@ ossl_hmac.o: $(hdrdir)/ruby/io.h ossl_hmac.o: $(hdrdir)/ruby/missing.h ossl_hmac.o: $(hdrdir)/ruby/onigmo.h ossl_hmac.o: $(hdrdir)/ruby/oniguruma.h +ossl_hmac.o: $(hdrdir)/ruby/ractor.h ossl_hmac.o: $(hdrdir)/ruby/ruby.h ossl_hmac.o: $(hdrdir)/ruby/st.h ossl_hmac.o: $(hdrdir)/ruby/subst.h @@ -1737,6 +1771,7 @@ ossl_hmac.o: ossl_ocsp.h ossl_hmac.o: ossl_pkcs12.h ossl_hmac.o: ossl_pkcs7.h ossl_hmac.o: ossl_pkey.h +ossl_hmac.o: ossl_provider.h ossl_hmac.o: ossl_rand.h ossl_hmac.o: ossl_ssl.h ossl_hmac.o: ossl_ts.h @@ -1757,6 +1792,7 @@ ossl_kdf.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_kdf.o: $(hdrdir)/ruby/defines.h ossl_kdf.o: $(hdrdir)/ruby/encoding.h ossl_kdf.o: $(hdrdir)/ruby/intern.h +ossl_kdf.o: $(hdrdir)/ruby/internal/abi.h ossl_kdf.o: $(hdrdir)/ruby/internal/anyargs.h ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1794,6 +1830,7 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_kdf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1862,7 +1899,6 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/error.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_kdf.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/io.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1879,6 +1915,7 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/intern/re.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/set.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_kdf.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1893,12 +1930,12 @@ ossl_kdf.o: $(hdrdir)/ruby/internal/memory.h ossl_kdf.o: $(hdrdir)/ruby/internal/method.h ossl_kdf.o: $(hdrdir)/ruby/internal/module.h ossl_kdf.o: $(hdrdir)/ruby/internal/newobj.h -ossl_kdf.o: $(hdrdir)/ruby/internal/rgengc.h ossl_kdf.o: $(hdrdir)/ruby/internal/scan_args.h ossl_kdf.o: $(hdrdir)/ruby/internal/special_consts.h ossl_kdf.o: $(hdrdir)/ruby/internal/static_assert.h ossl_kdf.o: $(hdrdir)/ruby/internal/stdalign.h ossl_kdf.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_kdf.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_kdf.o: $(hdrdir)/ruby/internal/symbol.h ossl_kdf.o: $(hdrdir)/ruby/internal/value.h ossl_kdf.o: $(hdrdir)/ruby/internal/value_type.h @@ -1909,6 +1946,7 @@ ossl_kdf.o: $(hdrdir)/ruby/io.h ossl_kdf.o: $(hdrdir)/ruby/missing.h ossl_kdf.o: $(hdrdir)/ruby/onigmo.h ossl_kdf.o: $(hdrdir)/ruby/oniguruma.h +ossl_kdf.o: $(hdrdir)/ruby/ractor.h ossl_kdf.o: $(hdrdir)/ruby/ruby.h ossl_kdf.o: $(hdrdir)/ruby/st.h ossl_kdf.o: $(hdrdir)/ruby/subst.h @@ -1930,6 +1968,7 @@ ossl_kdf.o: ossl_ocsp.h ossl_kdf.o: ossl_pkcs12.h ossl_kdf.o: ossl_pkcs7.h ossl_kdf.o: ossl_pkey.h +ossl_kdf.o: ossl_provider.h ossl_kdf.o: ossl_rand.h ossl_kdf.o: ossl_ssl.h ossl_kdf.o: ossl_ts.h @@ -1950,6 +1989,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ns_spki.o: $(hdrdir)/ruby/defines.h ossl_ns_spki.o: $(hdrdir)/ruby/encoding.h ossl_ns_spki.o: $(hdrdir)/ruby/intern.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/abi.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/anyargs.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1987,6 +2027,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2055,7 +2096,6 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/error.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/io.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2072,6 +2112,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/re.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/set.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2086,12 +2127,12 @@ ossl_ns_spki.o: $(hdrdir)/ruby/internal/memory.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/method.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/module.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/newobj.h -ossl_ns_spki.o: $(hdrdir)/ruby/internal/rgengc.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/scan_args.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/special_consts.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/static_assert.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdalign.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/symbol.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/value.h ossl_ns_spki.o: $(hdrdir)/ruby/internal/value_type.h @@ -2102,6 +2143,7 @@ ossl_ns_spki.o: $(hdrdir)/ruby/io.h ossl_ns_spki.o: $(hdrdir)/ruby/missing.h ossl_ns_spki.o: $(hdrdir)/ruby/onigmo.h ossl_ns_spki.o: $(hdrdir)/ruby/oniguruma.h +ossl_ns_spki.o: $(hdrdir)/ruby/ractor.h ossl_ns_spki.o: $(hdrdir)/ruby/ruby.h ossl_ns_spki.o: $(hdrdir)/ruby/st.h ossl_ns_spki.o: $(hdrdir)/ruby/subst.h @@ -2123,6 +2165,7 @@ ossl_ns_spki.o: ossl_ocsp.h ossl_ns_spki.o: ossl_pkcs12.h ossl_ns_spki.o: ossl_pkcs7.h ossl_ns_spki.o: ossl_pkey.h +ossl_ns_spki.o: ossl_provider.h ossl_ns_spki.o: ossl_rand.h ossl_ns_spki.o: ossl_ssl.h ossl_ns_spki.o: ossl_ts.h @@ -2143,6 +2186,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ocsp.o: $(hdrdir)/ruby/defines.h ossl_ocsp.o: $(hdrdir)/ruby/encoding.h ossl_ocsp.o: $(hdrdir)/ruby/intern.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/abi.h ossl_ocsp.o: $(hdrdir)/ruby/internal/anyargs.h ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2180,6 +2224,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2248,7 +2293,6 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/error.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/io.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2265,6 +2309,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/re.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/set.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2279,12 +2324,12 @@ ossl_ocsp.o: $(hdrdir)/ruby/internal/memory.h ossl_ocsp.o: $(hdrdir)/ruby/internal/method.h ossl_ocsp.o: $(hdrdir)/ruby/internal/module.h ossl_ocsp.o: $(hdrdir)/ruby/internal/newobj.h -ossl_ocsp.o: $(hdrdir)/ruby/internal/rgengc.h ossl_ocsp.o: $(hdrdir)/ruby/internal/scan_args.h ossl_ocsp.o: $(hdrdir)/ruby/internal/special_consts.h ossl_ocsp.o: $(hdrdir)/ruby/internal/static_assert.h ossl_ocsp.o: $(hdrdir)/ruby/internal/stdalign.h ossl_ocsp.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_ocsp.o: $(hdrdir)/ruby/internal/symbol.h ossl_ocsp.o: $(hdrdir)/ruby/internal/value.h ossl_ocsp.o: $(hdrdir)/ruby/internal/value_type.h @@ -2295,6 +2340,7 @@ ossl_ocsp.o: $(hdrdir)/ruby/io.h ossl_ocsp.o: $(hdrdir)/ruby/missing.h ossl_ocsp.o: $(hdrdir)/ruby/onigmo.h ossl_ocsp.o: $(hdrdir)/ruby/oniguruma.h +ossl_ocsp.o: $(hdrdir)/ruby/ractor.h ossl_ocsp.o: $(hdrdir)/ruby/ruby.h ossl_ocsp.o: $(hdrdir)/ruby/st.h ossl_ocsp.o: $(hdrdir)/ruby/subst.h @@ -2316,6 +2362,7 @@ ossl_ocsp.o: ossl_ocsp.h ossl_ocsp.o: ossl_pkcs12.h ossl_ocsp.o: ossl_pkcs7.h ossl_ocsp.o: ossl_pkey.h +ossl_ocsp.o: ossl_provider.h ossl_ocsp.o: ossl_rand.h ossl_ocsp.o: ossl_ssl.h ossl_ocsp.o: ossl_ts.h @@ -2336,6 +2383,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkcs12.o: $(hdrdir)/ruby/defines.h ossl_pkcs12.o: $(hdrdir)/ruby/encoding.h ossl_pkcs12.o: $(hdrdir)/ruby/intern.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/abi.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2373,6 +2421,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2441,7 +2490,6 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2458,6 +2506,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2472,12 +2521,12 @@ ossl_pkcs12.o: $(hdrdir)/ruby/internal/memory.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/method.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/module.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkcs12.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/value.h ossl_pkcs12.o: $(hdrdir)/ruby/internal/value_type.h @@ -2488,6 +2537,7 @@ ossl_pkcs12.o: $(hdrdir)/ruby/io.h ossl_pkcs12.o: $(hdrdir)/ruby/missing.h ossl_pkcs12.o: $(hdrdir)/ruby/onigmo.h ossl_pkcs12.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkcs12.o: $(hdrdir)/ruby/ractor.h ossl_pkcs12.o: $(hdrdir)/ruby/ruby.h ossl_pkcs12.o: $(hdrdir)/ruby/st.h ossl_pkcs12.o: $(hdrdir)/ruby/subst.h @@ -2509,6 +2559,7 @@ ossl_pkcs12.o: ossl_pkcs12.c ossl_pkcs12.o: ossl_pkcs12.h ossl_pkcs12.o: ossl_pkcs7.h ossl_pkcs12.o: ossl_pkey.h +ossl_pkcs12.o: ossl_provider.h ossl_pkcs12.o: ossl_rand.h ossl_pkcs12.o: ossl_ssl.h ossl_pkcs12.o: ossl_ts.h @@ -2529,6 +2580,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkcs7.o: $(hdrdir)/ruby/defines.h ossl_pkcs7.o: $(hdrdir)/ruby/encoding.h ossl_pkcs7.o: $(hdrdir)/ruby/intern.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/abi.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2566,6 +2618,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2634,7 +2687,6 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2651,6 +2703,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2665,12 +2718,12 @@ ossl_pkcs7.o: $(hdrdir)/ruby/internal/memory.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/method.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/module.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkcs7.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/value.h ossl_pkcs7.o: $(hdrdir)/ruby/internal/value_type.h @@ -2681,6 +2734,7 @@ ossl_pkcs7.o: $(hdrdir)/ruby/io.h ossl_pkcs7.o: $(hdrdir)/ruby/missing.h ossl_pkcs7.o: $(hdrdir)/ruby/onigmo.h ossl_pkcs7.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkcs7.o: $(hdrdir)/ruby/ractor.h ossl_pkcs7.o: $(hdrdir)/ruby/ruby.h ossl_pkcs7.o: $(hdrdir)/ruby/st.h ossl_pkcs7.o: $(hdrdir)/ruby/subst.h @@ -2702,6 +2756,7 @@ ossl_pkcs7.o: ossl_pkcs12.h ossl_pkcs7.o: ossl_pkcs7.c ossl_pkcs7.o: ossl_pkcs7.h ossl_pkcs7.o: ossl_pkey.h +ossl_pkcs7.o: ossl_provider.h ossl_pkcs7.o: ossl_rand.h ossl_pkcs7.o: ossl_ssl.h ossl_pkcs7.o: ossl_ts.h @@ -2722,6 +2777,7 @@ ossl_pkey.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey.o: $(hdrdir)/ruby/defines.h ossl_pkey.o: $(hdrdir)/ruby/encoding.h ossl_pkey.o: $(hdrdir)/ruby/intern.h +ossl_pkey.o: $(hdrdir)/ruby/internal/abi.h ossl_pkey.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2759,6 +2815,7 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkey.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2827,7 +2884,6 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkey.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2844,6 +2900,7 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkey.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2858,12 +2915,12 @@ ossl_pkey.o: $(hdrdir)/ruby/internal/memory.h ossl_pkey.o: $(hdrdir)/ruby/internal/method.h ossl_pkey.o: $(hdrdir)/ruby/internal/module.h ossl_pkey.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkey.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkey.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkey.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkey.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkey.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkey.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkey.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkey.o: $(hdrdir)/ruby/internal/value.h ossl_pkey.o: $(hdrdir)/ruby/internal/value_type.h @@ -2874,6 +2931,7 @@ ossl_pkey.o: $(hdrdir)/ruby/io.h ossl_pkey.o: $(hdrdir)/ruby/missing.h ossl_pkey.o: $(hdrdir)/ruby/onigmo.h ossl_pkey.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey.o: $(hdrdir)/ruby/ractor.h ossl_pkey.o: $(hdrdir)/ruby/ruby.h ossl_pkey.o: $(hdrdir)/ruby/st.h ossl_pkey.o: $(hdrdir)/ruby/subst.h @@ -2895,6 +2953,7 @@ ossl_pkey.o: ossl_pkcs12.h ossl_pkey.o: ossl_pkcs7.h ossl_pkey.o: ossl_pkey.c ossl_pkey.o: ossl_pkey.h +ossl_pkey.o: ossl_provider.h ossl_pkey.o: ossl_rand.h ossl_pkey.o: ossl_ssl.h ossl_pkey.o: ossl_ts.h @@ -2915,6 +2974,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_dh.o: $(hdrdir)/ruby/defines.h ossl_pkey_dh.o: $(hdrdir)/ruby/encoding.h ossl_pkey_dh.o: $(hdrdir)/ruby/intern.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/abi.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2952,6 +3012,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3020,7 +3081,6 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/load.h @@ -3037,6 +3097,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/string.h @@ -3051,12 +3112,12 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/internal/memory.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/method.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/module.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkey_dh.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value.h ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value_type.h @@ -3067,6 +3128,7 @@ ossl_pkey_dh.o: $(hdrdir)/ruby/io.h ossl_pkey_dh.o: $(hdrdir)/ruby/missing.h ossl_pkey_dh.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_dh.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_dh.o: $(hdrdir)/ruby/ractor.h ossl_pkey_dh.o: $(hdrdir)/ruby/ruby.h ossl_pkey_dh.o: $(hdrdir)/ruby/st.h ossl_pkey_dh.o: $(hdrdir)/ruby/subst.h @@ -3088,6 +3150,7 @@ ossl_pkey_dh.o: ossl_pkcs12.h ossl_pkey_dh.o: ossl_pkcs7.h ossl_pkey_dh.o: ossl_pkey.h ossl_pkey_dh.o: ossl_pkey_dh.c +ossl_pkey_dh.o: ossl_provider.h ossl_pkey_dh.o: ossl_rand.h ossl_pkey_dh.o: ossl_ssl.h ossl_pkey_dh.o: ossl_ts.h @@ -3108,6 +3171,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_dsa.o: $(hdrdir)/ruby/defines.h ossl_pkey_dsa.o: $(hdrdir)/ruby/encoding.h ossl_pkey_dsa.o: $(hdrdir)/ruby/intern.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/abi.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -3145,6 +3209,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3213,7 +3278,6 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/load.h @@ -3230,6 +3294,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/string.h @@ -3244,12 +3309,12 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/memory.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/method.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/module.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value.h ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value_type.h @@ -3260,6 +3325,7 @@ ossl_pkey_dsa.o: $(hdrdir)/ruby/io.h ossl_pkey_dsa.o: $(hdrdir)/ruby/missing.h ossl_pkey_dsa.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_dsa.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/ractor.h ossl_pkey_dsa.o: $(hdrdir)/ruby/ruby.h ossl_pkey_dsa.o: $(hdrdir)/ruby/st.h ossl_pkey_dsa.o: $(hdrdir)/ruby/subst.h @@ -3281,6 +3347,7 @@ ossl_pkey_dsa.o: ossl_pkcs12.h ossl_pkey_dsa.o: ossl_pkcs7.h ossl_pkey_dsa.o: ossl_pkey.h ossl_pkey_dsa.o: ossl_pkey_dsa.c +ossl_pkey_dsa.o: ossl_provider.h ossl_pkey_dsa.o: ossl_rand.h ossl_pkey_dsa.o: ossl_ssl.h ossl_pkey_dsa.o: ossl_ts.h @@ -3301,6 +3368,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_ec.o: $(hdrdir)/ruby/defines.h ossl_pkey_ec.o: $(hdrdir)/ruby/encoding.h ossl_pkey_ec.o: $(hdrdir)/ruby/intern.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/abi.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -3338,6 +3406,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3406,7 +3475,6 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/load.h @@ -3423,6 +3491,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/string.h @@ -3437,12 +3506,12 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/internal/memory.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/method.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/module.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkey_ec.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value.h ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value_type.h @@ -3453,6 +3522,7 @@ ossl_pkey_ec.o: $(hdrdir)/ruby/io.h ossl_pkey_ec.o: $(hdrdir)/ruby/missing.h ossl_pkey_ec.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_ec.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_ec.o: $(hdrdir)/ruby/ractor.h ossl_pkey_ec.o: $(hdrdir)/ruby/ruby.h ossl_pkey_ec.o: $(hdrdir)/ruby/st.h ossl_pkey_ec.o: $(hdrdir)/ruby/subst.h @@ -3474,6 +3544,7 @@ ossl_pkey_ec.o: ossl_pkcs12.h ossl_pkey_ec.o: ossl_pkcs7.h ossl_pkey_ec.o: ossl_pkey.h ossl_pkey_ec.o: ossl_pkey_ec.c +ossl_pkey_ec.o: ossl_provider.h ossl_pkey_ec.o: ossl_rand.h ossl_pkey_ec.o: ossl_ssl.h ossl_pkey_ec.o: ossl_ts.h @@ -3494,6 +3565,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_rsa.o: $(hdrdir)/ruby/defines.h ossl_pkey_rsa.o: $(hdrdir)/ruby/encoding.h ossl_pkey_rsa.o: $(hdrdir)/ruby/intern.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/abi.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/anyargs.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -3531,6 +3603,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3599,7 +3672,6 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/error.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/io.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/load.h @@ -3616,6 +3688,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/re.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/set.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/string.h @@ -3630,12 +3703,12 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/memory.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/method.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/module.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/newobj.h -ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/rgengc.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/scan_args.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/special_consts.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/static_assert.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdalign.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/symbol.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value.h ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value_type.h @@ -3646,6 +3719,7 @@ ossl_pkey_rsa.o: $(hdrdir)/ruby/io.h ossl_pkey_rsa.o: $(hdrdir)/ruby/missing.h ossl_pkey_rsa.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_rsa.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/ractor.h ossl_pkey_rsa.o: $(hdrdir)/ruby/ruby.h ossl_pkey_rsa.o: $(hdrdir)/ruby/st.h ossl_pkey_rsa.o: $(hdrdir)/ruby/subst.h @@ -3667,10 +3741,208 @@ ossl_pkey_rsa.o: ossl_pkcs12.h ossl_pkey_rsa.o: ossl_pkcs7.h ossl_pkey_rsa.o: ossl_pkey.h ossl_pkey_rsa.o: ossl_pkey_rsa.c +ossl_pkey_rsa.o: ossl_provider.h ossl_pkey_rsa.o: ossl_rand.h ossl_pkey_rsa.o: ossl_ssl.h ossl_pkey_rsa.o: ossl_ts.h ossl_pkey_rsa.o: ossl_x509.h +ossl_provider.o: $(RUBY_EXTCONF_H) +ossl_provider.o: $(arch_hdrdir)/ruby/config.h +ossl_provider.o: $(hdrdir)/ruby.h +ossl_provider.o: $(hdrdir)/ruby/assert.h +ossl_provider.o: $(hdrdir)/ruby/backward.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/stdarg.h +ossl_provider.o: $(hdrdir)/ruby/defines.h +ossl_provider.o: $(hdrdir)/ruby/encoding.h +ossl_provider.o: $(hdrdir)/ruby/intern.h +ossl_provider.o: $(hdrdir)/ruby/internal/abi.h +ossl_provider.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/assume.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_provider.o: $(hdrdir)/ruby/internal/cast.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_provider.o: $(hdrdir)/ruby/internal/config.h +ossl_provider.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_provider.o: $(hdrdir)/ruby/internal/core.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_provider.o: $(hdrdir)/ruby/internal/ctype.h +ossl_provider.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_provider.o: $(hdrdir)/ruby/internal/dosish.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_provider.o: $(hdrdir)/ruby/internal/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/eval.h +ossl_provider.o: $(hdrdir)/ruby/internal/event.h +ossl_provider.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_provider.o: $(hdrdir)/ruby/internal/gc.h +ossl_provider.o: $(hdrdir)/ruby/internal/glob.h +ossl_provider.o: $(hdrdir)/ruby/internal/globals.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_provider.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_provider.o: $(hdrdir)/ruby/internal/iterator.h +ossl_provider.o: $(hdrdir)/ruby/internal/memory.h +ossl_provider.o: $(hdrdir)/ruby/internal/method.h +ossl_provider.o: $(hdrdir)/ruby/internal/module.h +ossl_provider.o: $(hdrdir)/ruby/internal/newobj.h +ossl_provider.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_provider.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_provider.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_provider.o: $(hdrdir)/ruby/internal/symbol.h +ossl_provider.o: $(hdrdir)/ruby/internal/value.h +ossl_provider.o: $(hdrdir)/ruby/internal/value_type.h +ossl_provider.o: $(hdrdir)/ruby/internal/variable.h +ossl_provider.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_provider.o: $(hdrdir)/ruby/internal/xmalloc.h +ossl_provider.o: $(hdrdir)/ruby/io.h +ossl_provider.o: $(hdrdir)/ruby/missing.h +ossl_provider.o: $(hdrdir)/ruby/onigmo.h +ossl_provider.o: $(hdrdir)/ruby/oniguruma.h +ossl_provider.o: $(hdrdir)/ruby/ractor.h +ossl_provider.o: $(hdrdir)/ruby/ruby.h +ossl_provider.o: $(hdrdir)/ruby/st.h +ossl_provider.o: $(hdrdir)/ruby/subst.h +ossl_provider.o: $(hdrdir)/ruby/thread.h +ossl_provider.o: openssl_missing.h +ossl_provider.o: ossl.h +ossl_provider.o: ossl_asn1.h +ossl_provider.o: ossl_bio.h +ossl_provider.o: ossl_bn.h +ossl_provider.o: ossl_cipher.h +ossl_provider.o: ossl_config.h +ossl_provider.o: ossl_digest.h +ossl_provider.o: ossl_engine.h +ossl_provider.o: ossl_hmac.h +ossl_provider.o: ossl_kdf.h +ossl_provider.o: ossl_ns_spki.h +ossl_provider.o: ossl_ocsp.h +ossl_provider.o: ossl_pkcs12.h +ossl_provider.o: ossl_pkcs7.h +ossl_provider.o: ossl_pkey.h +ossl_provider.o: ossl_provider.c +ossl_provider.o: ossl_provider.h +ossl_provider.o: ossl_rand.h +ossl_provider.o: ossl_ssl.h +ossl_provider.o: ossl_ts.h +ossl_provider.o: ossl_x509.h ossl_rand.o: $(RUBY_EXTCONF_H) ossl_rand.o: $(arch_hdrdir)/ruby/config.h ossl_rand.o: $(hdrdir)/ruby.h @@ -3687,6 +3959,7 @@ ossl_rand.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_rand.o: $(hdrdir)/ruby/defines.h ossl_rand.o: $(hdrdir)/ruby/encoding.h ossl_rand.o: $(hdrdir)/ruby/intern.h +ossl_rand.o: $(hdrdir)/ruby/internal/abi.h ossl_rand.o: $(hdrdir)/ruby/internal/anyargs.h ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -3724,6 +3997,7 @@ ossl_rand.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_rand.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3792,7 +4066,6 @@ ossl_rand.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/error.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_rand.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/io.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/load.h @@ -3809,6 +4082,7 @@ ossl_rand.o: $(hdrdir)/ruby/internal/intern/re.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/select.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/set.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_rand.o: $(hdrdir)/ruby/internal/intern/string.h @@ -3823,12 +4097,12 @@ ossl_rand.o: $(hdrdir)/ruby/internal/memory.h ossl_rand.o: $(hdrdir)/ruby/internal/method.h ossl_rand.o: $(hdrdir)/ruby/internal/module.h ossl_rand.o: $(hdrdir)/ruby/internal/newobj.h -ossl_rand.o: $(hdrdir)/ruby/internal/rgengc.h ossl_rand.o: $(hdrdir)/ruby/internal/scan_args.h ossl_rand.o: $(hdrdir)/ruby/internal/special_consts.h ossl_rand.o: $(hdrdir)/ruby/internal/static_assert.h ossl_rand.o: $(hdrdir)/ruby/internal/stdalign.h ossl_rand.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_rand.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_rand.o: $(hdrdir)/ruby/internal/symbol.h ossl_rand.o: $(hdrdir)/ruby/internal/value.h ossl_rand.o: $(hdrdir)/ruby/internal/value_type.h @@ -3839,6 +4113,7 @@ ossl_rand.o: $(hdrdir)/ruby/io.h ossl_rand.o: $(hdrdir)/ruby/missing.h ossl_rand.o: $(hdrdir)/ruby/onigmo.h ossl_rand.o: $(hdrdir)/ruby/oniguruma.h +ossl_rand.o: $(hdrdir)/ruby/ractor.h ossl_rand.o: $(hdrdir)/ruby/ruby.h ossl_rand.o: $(hdrdir)/ruby/st.h ossl_rand.o: $(hdrdir)/ruby/subst.h @@ -3859,6 +4134,7 @@ ossl_rand.o: ossl_ocsp.h ossl_rand.o: ossl_pkcs12.h ossl_rand.o: ossl_pkcs7.h ossl_rand.o: ossl_pkey.h +ossl_rand.o: ossl_provider.h ossl_rand.o: ossl_rand.c ossl_rand.o: ossl_rand.h ossl_rand.o: ossl_ssl.h @@ -3880,6 +4156,7 @@ ossl_ssl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ssl.o: $(hdrdir)/ruby/defines.h ossl_ssl.o: $(hdrdir)/ruby/encoding.h ossl_ssl.o: $(hdrdir)/ruby/intern.h +ossl_ssl.o: $(hdrdir)/ruby/internal/abi.h ossl_ssl.o: $(hdrdir)/ruby/internal/anyargs.h ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -3917,6 +4194,7 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_ssl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -3985,7 +4263,6 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/error.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_ssl.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/io.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4002,6 +4279,7 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/intern/re.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/set.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_ssl.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4016,12 +4294,12 @@ ossl_ssl.o: $(hdrdir)/ruby/internal/memory.h ossl_ssl.o: $(hdrdir)/ruby/internal/method.h ossl_ssl.o: $(hdrdir)/ruby/internal/module.h ossl_ssl.o: $(hdrdir)/ruby/internal/newobj.h -ossl_ssl.o: $(hdrdir)/ruby/internal/rgengc.h ossl_ssl.o: $(hdrdir)/ruby/internal/scan_args.h ossl_ssl.o: $(hdrdir)/ruby/internal/special_consts.h ossl_ssl.o: $(hdrdir)/ruby/internal/static_assert.h ossl_ssl.o: $(hdrdir)/ruby/internal/stdalign.h ossl_ssl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ssl.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_ssl.o: $(hdrdir)/ruby/internal/symbol.h ossl_ssl.o: $(hdrdir)/ruby/internal/value.h ossl_ssl.o: $(hdrdir)/ruby/internal/value_type.h @@ -4032,6 +4310,7 @@ ossl_ssl.o: $(hdrdir)/ruby/io.h ossl_ssl.o: $(hdrdir)/ruby/missing.h ossl_ssl.o: $(hdrdir)/ruby/onigmo.h ossl_ssl.o: $(hdrdir)/ruby/oniguruma.h +ossl_ssl.o: $(hdrdir)/ruby/ractor.h ossl_ssl.o: $(hdrdir)/ruby/ruby.h ossl_ssl.o: $(hdrdir)/ruby/st.h ossl_ssl.o: $(hdrdir)/ruby/subst.h @@ -4052,6 +4331,7 @@ ossl_ssl.o: ossl_ocsp.h ossl_ssl.o: ossl_pkcs12.h ossl_ssl.o: ossl_pkcs7.h ossl_ssl.o: ossl_pkey.h +ossl_ssl.o: ossl_provider.h ossl_ssl.o: ossl_rand.h ossl_ssl.o: ossl_ssl.c ossl_ssl.o: ossl_ssl.h @@ -4073,6 +4353,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ssl_session.o: $(hdrdir)/ruby/defines.h ossl_ssl_session.o: $(hdrdir)/ruby/encoding.h ossl_ssl_session.o: $(hdrdir)/ruby/intern.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/abi.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/anyargs.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -4110,6 +4391,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -4178,7 +4460,6 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/error.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/io.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4195,6 +4476,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/re.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/set.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4209,12 +4491,12 @@ ossl_ssl_session.o: $(hdrdir)/ruby/internal/memory.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/method.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/module.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/newobj.h -ossl_ssl_session.o: $(hdrdir)/ruby/internal/rgengc.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/scan_args.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/special_consts.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/static_assert.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdalign.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/symbol.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/value.h ossl_ssl_session.o: $(hdrdir)/ruby/internal/value_type.h @@ -4225,6 +4507,7 @@ ossl_ssl_session.o: $(hdrdir)/ruby/io.h ossl_ssl_session.o: $(hdrdir)/ruby/missing.h ossl_ssl_session.o: $(hdrdir)/ruby/onigmo.h ossl_ssl_session.o: $(hdrdir)/ruby/oniguruma.h +ossl_ssl_session.o: $(hdrdir)/ruby/ractor.h ossl_ssl_session.o: $(hdrdir)/ruby/ruby.h ossl_ssl_session.o: $(hdrdir)/ruby/st.h ossl_ssl_session.o: $(hdrdir)/ruby/subst.h @@ -4245,6 +4528,7 @@ ossl_ssl_session.o: ossl_ocsp.h ossl_ssl_session.o: ossl_pkcs12.h ossl_ssl_session.o: ossl_pkcs7.h ossl_ssl_session.o: ossl_pkey.h +ossl_ssl_session.o: ossl_provider.h ossl_ssl_session.o: ossl_rand.h ossl_ssl_session.o: ossl_ssl.h ossl_ssl_session.o: ossl_ssl_session.c @@ -4266,6 +4550,7 @@ ossl_ts.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ts.o: $(hdrdir)/ruby/defines.h ossl_ts.o: $(hdrdir)/ruby/encoding.h ossl_ts.o: $(hdrdir)/ruby/intern.h +ossl_ts.o: $(hdrdir)/ruby/internal/abi.h ossl_ts.o: $(hdrdir)/ruby/internal/anyargs.h ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -4303,6 +4588,7 @@ ossl_ts.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_ts.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -4371,7 +4657,6 @@ ossl_ts.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/error.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_ts.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/io.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4388,6 +4673,7 @@ ossl_ts.o: $(hdrdir)/ruby/internal/intern/re.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/select.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/set.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_ts.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4402,12 +4688,12 @@ ossl_ts.o: $(hdrdir)/ruby/internal/memory.h ossl_ts.o: $(hdrdir)/ruby/internal/method.h ossl_ts.o: $(hdrdir)/ruby/internal/module.h ossl_ts.o: $(hdrdir)/ruby/internal/newobj.h -ossl_ts.o: $(hdrdir)/ruby/internal/rgengc.h ossl_ts.o: $(hdrdir)/ruby/internal/scan_args.h ossl_ts.o: $(hdrdir)/ruby/internal/special_consts.h ossl_ts.o: $(hdrdir)/ruby/internal/static_assert.h ossl_ts.o: $(hdrdir)/ruby/internal/stdalign.h ossl_ts.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ts.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_ts.o: $(hdrdir)/ruby/internal/symbol.h ossl_ts.o: $(hdrdir)/ruby/internal/value.h ossl_ts.o: $(hdrdir)/ruby/internal/value_type.h @@ -4418,6 +4704,7 @@ ossl_ts.o: $(hdrdir)/ruby/io.h ossl_ts.o: $(hdrdir)/ruby/missing.h ossl_ts.o: $(hdrdir)/ruby/onigmo.h ossl_ts.o: $(hdrdir)/ruby/oniguruma.h +ossl_ts.o: $(hdrdir)/ruby/ractor.h ossl_ts.o: $(hdrdir)/ruby/ruby.h ossl_ts.o: $(hdrdir)/ruby/st.h ossl_ts.o: $(hdrdir)/ruby/subst.h @@ -4438,6 +4725,7 @@ ossl_ts.o: ossl_ocsp.h ossl_ts.o: ossl_pkcs12.h ossl_ts.o: ossl_pkcs7.h ossl_ts.o: ossl_pkey.h +ossl_ts.o: ossl_provider.h ossl_ts.o: ossl_rand.h ossl_ts.o: ossl_ssl.h ossl_ts.o: ossl_ts.c @@ -4459,6 +4747,7 @@ ossl_x509.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509.o: $(hdrdir)/ruby/defines.h ossl_x509.o: $(hdrdir)/ruby/encoding.h ossl_x509.o: $(hdrdir)/ruby/intern.h +ossl_x509.o: $(hdrdir)/ruby/internal/abi.h ossl_x509.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -4496,6 +4785,7 @@ ossl_x509.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -4564,7 +4854,6 @@ ossl_x509.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4581,6 +4870,7 @@ ossl_x509.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4595,12 +4885,12 @@ ossl_x509.o: $(hdrdir)/ruby/internal/memory.h ossl_x509.o: $(hdrdir)/ruby/internal/method.h ossl_x509.o: $(hdrdir)/ruby/internal/module.h ossl_x509.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509.o: $(hdrdir)/ruby/internal/value.h ossl_x509.o: $(hdrdir)/ruby/internal/value_type.h @@ -4611,6 +4901,7 @@ ossl_x509.o: $(hdrdir)/ruby/io.h ossl_x509.o: $(hdrdir)/ruby/missing.h ossl_x509.o: $(hdrdir)/ruby/onigmo.h ossl_x509.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509.o: $(hdrdir)/ruby/ractor.h ossl_x509.o: $(hdrdir)/ruby/ruby.h ossl_x509.o: $(hdrdir)/ruby/st.h ossl_x509.o: $(hdrdir)/ruby/subst.h @@ -4631,6 +4922,7 @@ ossl_x509.o: ossl_ocsp.h ossl_x509.o: ossl_pkcs12.h ossl_x509.o: ossl_pkcs7.h ossl_x509.o: ossl_pkey.h +ossl_x509.o: ossl_provider.h ossl_x509.o: ossl_rand.h ossl_x509.o: ossl_ssl.h ossl_x509.o: ossl_ts.h @@ -4652,6 +4944,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509attr.o: $(hdrdir)/ruby/defines.h ossl_x509attr.o: $(hdrdir)/ruby/encoding.h ossl_x509attr.o: $(hdrdir)/ruby/intern.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/abi.h ossl_x509attr.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -4689,6 +4982,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -4757,7 +5051,6 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4774,6 +5067,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4788,12 +5082,12 @@ ossl_x509attr.o: $(hdrdir)/ruby/internal/memory.h ossl_x509attr.o: $(hdrdir)/ruby/internal/method.h ossl_x509attr.o: $(hdrdir)/ruby/internal/module.h ossl_x509attr.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509attr.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509attr.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509attr.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509attr.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509attr.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509attr.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509attr.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509attr.o: $(hdrdir)/ruby/internal/value.h ossl_x509attr.o: $(hdrdir)/ruby/internal/value_type.h @@ -4804,6 +5098,7 @@ ossl_x509attr.o: $(hdrdir)/ruby/io.h ossl_x509attr.o: $(hdrdir)/ruby/missing.h ossl_x509attr.o: $(hdrdir)/ruby/onigmo.h ossl_x509attr.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509attr.o: $(hdrdir)/ruby/ractor.h ossl_x509attr.o: $(hdrdir)/ruby/ruby.h ossl_x509attr.o: $(hdrdir)/ruby/st.h ossl_x509attr.o: $(hdrdir)/ruby/subst.h @@ -4824,6 +5119,7 @@ ossl_x509attr.o: ossl_ocsp.h ossl_x509attr.o: ossl_pkcs12.h ossl_x509attr.o: ossl_pkcs7.h ossl_x509attr.o: ossl_pkey.h +ossl_x509attr.o: ossl_provider.h ossl_x509attr.o: ossl_rand.h ossl_x509attr.o: ossl_ssl.h ossl_x509attr.o: ossl_ts.h @@ -4845,6 +5141,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509cert.o: $(hdrdir)/ruby/defines.h ossl_x509cert.o: $(hdrdir)/ruby/encoding.h ossl_x509cert.o: $(hdrdir)/ruby/intern.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/abi.h ossl_x509cert.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -4882,6 +5179,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -4950,7 +5248,6 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/load.h @@ -4967,6 +5264,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/string.h @@ -4981,12 +5279,12 @@ ossl_x509cert.o: $(hdrdir)/ruby/internal/memory.h ossl_x509cert.o: $(hdrdir)/ruby/internal/method.h ossl_x509cert.o: $(hdrdir)/ruby/internal/module.h ossl_x509cert.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509cert.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509cert.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509cert.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509cert.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509cert.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509cert.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509cert.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509cert.o: $(hdrdir)/ruby/internal/value.h ossl_x509cert.o: $(hdrdir)/ruby/internal/value_type.h @@ -4997,6 +5295,7 @@ ossl_x509cert.o: $(hdrdir)/ruby/io.h ossl_x509cert.o: $(hdrdir)/ruby/missing.h ossl_x509cert.o: $(hdrdir)/ruby/onigmo.h ossl_x509cert.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509cert.o: $(hdrdir)/ruby/ractor.h ossl_x509cert.o: $(hdrdir)/ruby/ruby.h ossl_x509cert.o: $(hdrdir)/ruby/st.h ossl_x509cert.o: $(hdrdir)/ruby/subst.h @@ -5017,6 +5316,7 @@ ossl_x509cert.o: ossl_ocsp.h ossl_x509cert.o: ossl_pkcs12.h ossl_x509cert.o: ossl_pkcs7.h ossl_x509cert.o: ossl_pkey.h +ossl_x509cert.o: ossl_provider.h ossl_x509cert.o: ossl_rand.h ossl_x509cert.o: ossl_ssl.h ossl_x509cert.o: ossl_ts.h @@ -5038,6 +5338,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509crl.o: $(hdrdir)/ruby/defines.h ossl_x509crl.o: $(hdrdir)/ruby/encoding.h ossl_x509crl.o: $(hdrdir)/ruby/intern.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/abi.h ossl_x509crl.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -5075,6 +5376,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -5143,7 +5445,6 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/load.h @@ -5160,6 +5461,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/string.h @@ -5174,12 +5476,12 @@ ossl_x509crl.o: $(hdrdir)/ruby/internal/memory.h ossl_x509crl.o: $(hdrdir)/ruby/internal/method.h ossl_x509crl.o: $(hdrdir)/ruby/internal/module.h ossl_x509crl.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509crl.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509crl.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509crl.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509crl.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509crl.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509crl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509crl.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509crl.o: $(hdrdir)/ruby/internal/value.h ossl_x509crl.o: $(hdrdir)/ruby/internal/value_type.h @@ -5190,6 +5492,7 @@ ossl_x509crl.o: $(hdrdir)/ruby/io.h ossl_x509crl.o: $(hdrdir)/ruby/missing.h ossl_x509crl.o: $(hdrdir)/ruby/onigmo.h ossl_x509crl.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509crl.o: $(hdrdir)/ruby/ractor.h ossl_x509crl.o: $(hdrdir)/ruby/ruby.h ossl_x509crl.o: $(hdrdir)/ruby/st.h ossl_x509crl.o: $(hdrdir)/ruby/subst.h @@ -5210,6 +5513,7 @@ ossl_x509crl.o: ossl_ocsp.h ossl_x509crl.o: ossl_pkcs12.h ossl_x509crl.o: ossl_pkcs7.h ossl_x509crl.o: ossl_pkey.h +ossl_x509crl.o: ossl_provider.h ossl_x509crl.o: ossl_rand.h ossl_x509crl.o: ossl_ssl.h ossl_x509crl.o: ossl_ts.h @@ -5231,6 +5535,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509ext.o: $(hdrdir)/ruby/defines.h ossl_x509ext.o: $(hdrdir)/ruby/encoding.h ossl_x509ext.o: $(hdrdir)/ruby/intern.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/abi.h ossl_x509ext.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -5268,6 +5573,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -5336,7 +5642,6 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/load.h @@ -5353,6 +5658,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/string.h @@ -5367,12 +5673,12 @@ ossl_x509ext.o: $(hdrdir)/ruby/internal/memory.h ossl_x509ext.o: $(hdrdir)/ruby/internal/method.h ossl_x509ext.o: $(hdrdir)/ruby/internal/module.h ossl_x509ext.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509ext.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509ext.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509ext.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509ext.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509ext.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509ext.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509ext.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509ext.o: $(hdrdir)/ruby/internal/value.h ossl_x509ext.o: $(hdrdir)/ruby/internal/value_type.h @@ -5383,6 +5689,7 @@ ossl_x509ext.o: $(hdrdir)/ruby/io.h ossl_x509ext.o: $(hdrdir)/ruby/missing.h ossl_x509ext.o: $(hdrdir)/ruby/onigmo.h ossl_x509ext.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509ext.o: $(hdrdir)/ruby/ractor.h ossl_x509ext.o: $(hdrdir)/ruby/ruby.h ossl_x509ext.o: $(hdrdir)/ruby/st.h ossl_x509ext.o: $(hdrdir)/ruby/subst.h @@ -5403,6 +5710,7 @@ ossl_x509ext.o: ossl_ocsp.h ossl_x509ext.o: ossl_pkcs12.h ossl_x509ext.o: ossl_pkcs7.h ossl_x509ext.o: ossl_pkey.h +ossl_x509ext.o: ossl_provider.h ossl_x509ext.o: ossl_rand.h ossl_x509ext.o: ossl_ssl.h ossl_x509ext.o: ossl_ts.h @@ -5424,6 +5732,7 @@ ossl_x509name.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509name.o: $(hdrdir)/ruby/defines.h ossl_x509name.o: $(hdrdir)/ruby/encoding.h ossl_x509name.o: $(hdrdir)/ruby/intern.h +ossl_x509name.o: $(hdrdir)/ruby/internal/abi.h ossl_x509name.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -5461,6 +5770,7 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -5529,7 +5839,6 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509name.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/load.h @@ -5546,6 +5855,7 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509name.o: $(hdrdir)/ruby/internal/intern/string.h @@ -5560,12 +5870,12 @@ ossl_x509name.o: $(hdrdir)/ruby/internal/memory.h ossl_x509name.o: $(hdrdir)/ruby/internal/method.h ossl_x509name.o: $(hdrdir)/ruby/internal/module.h ossl_x509name.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509name.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509name.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509name.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509name.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509name.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509name.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509name.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509name.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509name.o: $(hdrdir)/ruby/internal/value.h ossl_x509name.o: $(hdrdir)/ruby/internal/value_type.h @@ -5576,6 +5886,7 @@ ossl_x509name.o: $(hdrdir)/ruby/io.h ossl_x509name.o: $(hdrdir)/ruby/missing.h ossl_x509name.o: $(hdrdir)/ruby/onigmo.h ossl_x509name.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509name.o: $(hdrdir)/ruby/ractor.h ossl_x509name.o: $(hdrdir)/ruby/ruby.h ossl_x509name.o: $(hdrdir)/ruby/st.h ossl_x509name.o: $(hdrdir)/ruby/subst.h @@ -5596,6 +5907,7 @@ ossl_x509name.o: ossl_ocsp.h ossl_x509name.o: ossl_pkcs12.h ossl_x509name.o: ossl_pkcs7.h ossl_x509name.o: ossl_pkey.h +ossl_x509name.o: ossl_provider.h ossl_x509name.o: ossl_rand.h ossl_x509name.o: ossl_ssl.h ossl_x509name.o: ossl_ts.h @@ -5617,6 +5929,7 @@ ossl_x509req.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509req.o: $(hdrdir)/ruby/defines.h ossl_x509req.o: $(hdrdir)/ruby/encoding.h ossl_x509req.o: $(hdrdir)/ruby/intern.h +ossl_x509req.o: $(hdrdir)/ruby/internal/abi.h ossl_x509req.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -5654,6 +5967,7 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509req.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -5722,7 +6036,6 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509req.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/load.h @@ -5739,6 +6052,7 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509req.o: $(hdrdir)/ruby/internal/intern/string.h @@ -5753,12 +6067,12 @@ ossl_x509req.o: $(hdrdir)/ruby/internal/memory.h ossl_x509req.o: $(hdrdir)/ruby/internal/method.h ossl_x509req.o: $(hdrdir)/ruby/internal/module.h ossl_x509req.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509req.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509req.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509req.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509req.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509req.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509req.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509req.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509req.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509req.o: $(hdrdir)/ruby/internal/value.h ossl_x509req.o: $(hdrdir)/ruby/internal/value_type.h @@ -5769,6 +6083,7 @@ ossl_x509req.o: $(hdrdir)/ruby/io.h ossl_x509req.o: $(hdrdir)/ruby/missing.h ossl_x509req.o: $(hdrdir)/ruby/onigmo.h ossl_x509req.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509req.o: $(hdrdir)/ruby/ractor.h ossl_x509req.o: $(hdrdir)/ruby/ruby.h ossl_x509req.o: $(hdrdir)/ruby/st.h ossl_x509req.o: $(hdrdir)/ruby/subst.h @@ -5789,6 +6104,7 @@ ossl_x509req.o: ossl_ocsp.h ossl_x509req.o: ossl_pkcs12.h ossl_x509req.o: ossl_pkcs7.h ossl_x509req.o: ossl_pkey.h +ossl_x509req.o: ossl_provider.h ossl_x509req.o: ossl_rand.h ossl_x509req.o: ossl_ssl.h ossl_x509req.o: ossl_ts.h @@ -5810,6 +6126,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509revoked.o: $(hdrdir)/ruby/defines.h ossl_x509revoked.o: $(hdrdir)/ruby/encoding.h ossl_x509revoked.o: $(hdrdir)/ruby/intern.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/abi.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -5847,6 +6164,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -5915,7 +6233,6 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/load.h @@ -5932,6 +6249,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/string.h @@ -5946,12 +6264,12 @@ ossl_x509revoked.o: $(hdrdir)/ruby/internal/memory.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/method.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/module.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509revoked.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/value.h ossl_x509revoked.o: $(hdrdir)/ruby/internal/value_type.h @@ -5962,6 +6280,7 @@ ossl_x509revoked.o: $(hdrdir)/ruby/io.h ossl_x509revoked.o: $(hdrdir)/ruby/missing.h ossl_x509revoked.o: $(hdrdir)/ruby/onigmo.h ossl_x509revoked.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509revoked.o: $(hdrdir)/ruby/ractor.h ossl_x509revoked.o: $(hdrdir)/ruby/ruby.h ossl_x509revoked.o: $(hdrdir)/ruby/st.h ossl_x509revoked.o: $(hdrdir)/ruby/subst.h @@ -5982,6 +6301,7 @@ ossl_x509revoked.o: ossl_ocsp.h ossl_x509revoked.o: ossl_pkcs12.h ossl_x509revoked.o: ossl_pkcs7.h ossl_x509revoked.o: ossl_pkey.h +ossl_x509revoked.o: ossl_provider.h ossl_x509revoked.o: ossl_rand.h ossl_x509revoked.o: ossl_ssl.h ossl_x509revoked.o: ossl_ts.h @@ -6003,6 +6323,7 @@ ossl_x509store.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509store.o: $(hdrdir)/ruby/defines.h ossl_x509store.o: $(hdrdir)/ruby/encoding.h ossl_x509store.o: $(hdrdir)/ruby/intern.h +ossl_x509store.o: $(hdrdir)/ruby/internal/abi.h ossl_x509store.o: $(hdrdir)/ruby/internal/anyargs.h ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic.h ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -6040,6 +6361,7 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noexcept.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noinline.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nonnull.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/pure.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/restrict.h ossl_x509store.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -6108,7 +6430,6 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enumerator.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/error.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/eval.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/file.h -ossl_x509store.o: $(hdrdir)/ruby/internal/intern/gc.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/hash.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/io.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/load.h @@ -6125,6 +6446,7 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/intern/re.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/ruby.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/set.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/signal.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/sprintf.h ossl_x509store.o: $(hdrdir)/ruby/internal/intern/string.h @@ -6139,12 +6461,12 @@ ossl_x509store.o: $(hdrdir)/ruby/internal/memory.h ossl_x509store.o: $(hdrdir)/ruby/internal/method.h ossl_x509store.o: $(hdrdir)/ruby/internal/module.h ossl_x509store.o: $(hdrdir)/ruby/internal/newobj.h -ossl_x509store.o: $(hdrdir)/ruby/internal/rgengc.h ossl_x509store.o: $(hdrdir)/ruby/internal/scan_args.h ossl_x509store.o: $(hdrdir)/ruby/internal/special_consts.h ossl_x509store.o: $(hdrdir)/ruby/internal/static_assert.h ossl_x509store.o: $(hdrdir)/ruby/internal/stdalign.h ossl_x509store.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509store.o: $(hdrdir)/ruby/internal/stdckdint.h ossl_x509store.o: $(hdrdir)/ruby/internal/symbol.h ossl_x509store.o: $(hdrdir)/ruby/internal/value.h ossl_x509store.o: $(hdrdir)/ruby/internal/value_type.h @@ -6155,6 +6477,7 @@ ossl_x509store.o: $(hdrdir)/ruby/io.h ossl_x509store.o: $(hdrdir)/ruby/missing.h ossl_x509store.o: $(hdrdir)/ruby/onigmo.h ossl_x509store.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509store.o: $(hdrdir)/ruby/ractor.h ossl_x509store.o: $(hdrdir)/ruby/ruby.h ossl_x509store.o: $(hdrdir)/ruby/st.h ossl_x509store.o: $(hdrdir)/ruby/subst.h @@ -6175,6 +6498,7 @@ ossl_x509store.o: ossl_ocsp.h ossl_x509store.o: ossl_pkcs12.h ossl_x509store.o: ossl_pkcs7.h ossl_x509store.o: ossl_pkey.h +ossl_x509store.o: ossl_provider.h ossl_x509store.o: ossl_rand.h ossl_x509store.o: ossl_ssl.h ossl_x509store.o: ossl_ts.h diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 9a822f60ac..a897c86b65 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -8,25 +8,43 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require "mkmf" -dir_config("openssl") -dir_config("kerberos") +ssl_dirs = dir_config("openssl") +dir_config_given = ssl_dirs.any? + +_, ssl_ldir = ssl_dirs +if ssl_ldir&.split(File::PATH_SEPARATOR)&.none? { |dir| File.directory?(dir) } + # According to the `mkmf.rb#dir_config`, the `--with-openssl-dir=<dir>` uses + # the value of the `File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])` as a + # loaded library directory name. + ruby_ldir_name = File.basename(RbConfig::MAKEFILE_CONFIG["libdir"]) + + raise "OpenSSL library directory could not be found in '#{ssl_ldir}'. " \ + "You might want to fix this error in one of the following ways.\n" \ + " * Recompile OpenSSL by configuring it with --libdir=#{ruby_ldir_name} " \ + " to specify the OpenSSL library directory.\n" \ + " * Recompile Ruby by configuring it with --libdir=<dir> to specify the " \ + "Ruby library directory.\n" \ + " * Compile this openssl gem with --with-openssl-include=<dir> and " \ + "--with-openssl-lib=<dir> options to specify the OpenSSL include and " \ + "library directories." +end Logging::message "=== OpenSSL for Ruby configurator ===\n" -## -# Adds -DOSSL_DEBUG for compilation and some more targets when GCC is used -# To turn it on, use: --with-debug or --enable-debug -# -if with_config("debug") or enable_config("debug") - $defs.push("-DOSSL_DEBUG") -end +$defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED") -have_func("rb_io_maybe_wait") # Ruby 3.1 +# Missing in TruffleRuby +have_func("rb_call_super_kw(0, NULL, 0)", "ruby.h") +# Ruby 3.1 +have_func("rb_io_descriptor", "ruby/io.h") +have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") +# Ruby 3.2 +have_func("rb_io_timeout", "ruby/io.h") Logging::message "=== Checking for system dependent stuff... ===\n" have_library("nsl", "t_open") @@ -44,7 +62,6 @@ end def find_openssl_library if $mswin || $mingw # required for static OpenSSL libraries - have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen()) have_library("crypt32") end @@ -61,12 +78,6 @@ def find_openssl_library return true end - # OpenSSL <= 1.0.2: libeay32.lib and ssleay32.lib. - if have_library("libeay32", "CRYPTO_malloc") && - have_library("ssleay32", "SSL_new") - return true - end - # LibreSSL: libcrypto-##.lib and libssl-##.lib, where ## is the ABI version # number. We have to find the version number out by scanning libpath. libpath = $LIBPATH.dup @@ -92,7 +103,7 @@ def find_openssl_library end Logging::message "=== Checking for required stuff... ===\n" -pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h") +pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h") if !pkg_config_found && !find_openssl_library Logging::message "=== Checking for required stuff failed. ===\n" @@ -104,14 +115,15 @@ end version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") is_libressl = true - checking_for("LibreSSL version >= 3.1.0") { - try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x30100000L", "openssl/opensslv.h") } + checking_for("LibreSSL version >= 3.9.0") { + try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x30900000L", "openssl/opensslv.h") } else - checking_for("OpenSSL version >= 1.0.2") { - try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10002000L", "openssl/opensslv.h") } + is_openssl = true + checking_for("OpenSSL version >= 1.1.1") { + try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10101000L", "openssl/opensslv.h") } end unless version_ok - raise "OpenSSL >= 1.0.2 or LibreSSL >= 3.1.0 is required" + raise "OpenSSL >= 1.1.1 or LibreSSL >= 3.9.0 is required" end # Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h @@ -120,61 +132,51 @@ if is_libressl && ($mswin || $mingw) end Logging::message "=== Checking for OpenSSL features... ===\n" +evp_h = "openssl/evp.h".freeze +ts_h = "openssl/ts.h".freeze +ssl_h = "openssl/ssl.h".freeze + # compile options -have_func("RAND_egd") -engines = %w{dynamic 4758cca aep atalla chil - cswift nuron sureware ubsec padlock capi gmp gost cryptodev} -engines.each { |name| - have_func("ENGINE_load_#{name}()", "openssl/engine.h") -} - -# added in 1.1.0 -if !have_struct_member("SSL", "ctx", "openssl/ssl.h") || is_libressl - $defs.push("-DHAVE_OPAQUE_OPENSSL") -end -have_func("EVP_MD_CTX_new") -have_func("EVP_MD_CTX_free") -have_func("EVP_MD_CTX_pkey_ctx") -have_func("X509_STORE_get_ex_data") -have_func("X509_STORE_set_ex_data") -have_func("X509_STORE_get_ex_new_index") -have_func("X509_CRL_get0_signature") -have_func("X509_REQ_get0_signature") -have_func("X509_REVOKED_get0_serialNumber") -have_func("X509_REVOKED_get0_revocationDate") -have_func("X509_get0_tbs_sigalg") -have_func("X509_STORE_CTX_get0_untrusted") -have_func("X509_STORE_CTX_get0_cert") -have_func("X509_STORE_CTX_get0_chain") -have_func("OCSP_SINGLERESP_get0_id") -have_func("SSL_CTX_get_ciphers") -have_func("X509_up_ref") -have_func("X509_CRL_up_ref") -have_func("X509_STORE_up_ref") -have_func("SSL_SESSION_up_ref") -have_func("EVP_PKEY_up_ref") -have_func("SSL_CTX_set_min_proto_version(NULL, 0)", "openssl/ssl.h") -have_func("SSL_CTX_get_security_level") -have_func("X509_get0_notBefore") -have_func("SSL_SESSION_get_protocol_version") -have_func("TS_STATUS_INFO_get0_status") -have_func("TS_STATUS_INFO_get0_text") -have_func("TS_STATUS_INFO_get0_failure_info") -have_func("TS_VERIFY_CTS_set_certs") -have_func("TS_VERIFY_CTX_set_store") -have_func("TS_VERIFY_CTX_add_flags") -have_func("TS_RESP_CTX_set_time_cb") -have_func("EVP_PBE_scrypt") -have_func("SSL_CTX_set_post_handshake_auth") - -# added in 1.1.1 -have_func("EVP_PKEY_check") +have_func("RAND_egd()", "openssl/rand.h") + +# added in OpenSSL 1.0.2, not in LibreSSL yet +have_func("SSL_CTX_set1_sigalgs_list(NULL, NULL)", ssl_h) +# added in OpenSSL 1.0.2, not in LibreSSL or AWS-LC yet +have_func("SSL_CTX_set1_client_sigalgs_list(NULL, NULL)", ssl_h) + +# added in 1.1.0, currently not in LibreSSL +have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h) + +# added in OpenSSL 1.1.1 and LibreSSL 3.5.0, then removed in LibreSSL 4.0.0 +have_func("EVP_PKEY_check(NULL)", evp_h) # added in 3.0.0 -have_func("SSL_set0_tmp_dh_pkey") +have_func("SSL_CTX_set0_tmp_dh_pkey(NULL, NULL)", ssl_h) +have_func("ERR_get_error_all(NULL, NULL, NULL, NULL, NULL)", "openssl/err.h") +have_func("SSL_CTX_load_verify_file(NULL, \"\")", ssl_h) +have_func("BN_check_prime(NULL, NULL, NULL)", "openssl/bn.h") +have_func("EVP_MD_CTX_get0_md(NULL)", evp_h) +have_func("EVP_MD_CTX_get_pkey_ctx(NULL)", evp_h) +have_func("EVP_PKEY_eq(NULL, NULL)", evp_h) +have_func("EVP_PKEY_dup(NULL)", evp_h) + +# added in 3.2.0 +have_func("SSL_get0_group_name(NULL)", ssl_h) + +# added in 3.4.0 +have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h) + +# added in 3.5.0 +have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h) Logging::message "=== Checking done. ===\n" +# Append flags from environment variables. +extcflags = ENV["RUBY_OPENSSL_EXTCFLAGS"] +append_cflags(extcflags.split) if extcflags +extldflags = ENV["RUBY_OPENSSL_EXTLDFLAGS"] +append_ldflags(extldflags.split) if extldflags + create_header create_makefile("openssl") Logging::message "Done.\n" diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb index 8a342f15b6..98fa8d39f2 100644 --- a/ext/openssl/lib/openssl.rb +++ b/ext/openssl/lib/openssl.rb @@ -7,28 +7,32 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require 'openssl.so' require_relative 'openssl/bn' -require_relative 'openssl/pkey' require_relative 'openssl/cipher' require_relative 'openssl/digest' require_relative 'openssl/hmac' -require_relative 'openssl/x509' -require_relative 'openssl/ssl' require_relative 'openssl/pkcs5' +require_relative 'openssl/pkey' +require_relative 'openssl/ssl' require_relative 'openssl/version' +require_relative 'openssl/x509' module OpenSSL - # call-seq: - # OpenSSL.secure_compare(string, string) -> boolean + # :call-seq: + # OpenSSL.secure_compare(string, string) -> true or false # # Constant time memory comparison. Inputs are hashed using SHA-256 to mask # the length of the secret. Returns +true+ if the strings are identical, # +false+ otherwise. + # + # This method is expensive due to the SHA-256 hashing. In most cases, where + # the input lengths are known to be equal or are not sensitive, + # OpenSSL.fixed_length_secure_compare should be used instead. def self.secure_compare(a, b) hashed_a = OpenSSL::Digest.digest('SHA256', a) hashed_b = OpenSSL::Digest.digest('SHA256', b) diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb index 0a5e11b4c2..e4889a140c 100644 --- a/ext/openssl/lib/openssl/bn.rb +++ b/ext/openssl/lib/openssl/bn.rb @@ -10,7 +10,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index d47e1082ef..1464a4292d 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -8,7 +8,7 @@ # #= Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ ## @@ -24,25 +24,21 @@ module OpenSSL::Buffering # A buffer which will retain binary encoding. class Buffer < String - BINARY = Encoding::BINARY - - def initialize - super - - force_encoding(BINARY) - end + unless String.method_defined?(:append_as_bytes) + alias_method :_append, :<< + def append_as_bytes(string) + if string.encoding == Encoding::BINARY + _append(string) + else + _append(string.b) + end - def << string - if string.encoding == BINARY - super(string) - else - super(string.b) + self end - - return self end - alias concat << + undef_method :concat + undef_method :<< end ## @@ -77,7 +73,7 @@ module OpenSSL::Buffering def fill_rbuff begin - @rbuffer << self.sysread(BLOCK_SIZE) + @rbuffer.append_as_bytes(self.sysread(BLOCK_SIZE)) rescue Errno::EAGAIN retry rescue EOFError @@ -93,9 +89,7 @@ module OpenSSL::Buffering nil else size = @rbuffer.size unless size - ret = @rbuffer[0, size] - @rbuffer[0, size] = "" - ret + @rbuffer.slice!(0, size) end end @@ -106,8 +100,13 @@ module OpenSSL::Buffering # # Get the next 8bit byte from `ssl`. Returns `nil` on EOF def getbyte - byte = read(1) - byte && byte.unpack1("C") + read(1)&.ord + end + + # Get the next 8bit byte. Raises EOFError on EOF + def readbyte + raise EOFError if eof? + getbyte end ## @@ -232,7 +231,7 @@ module OpenSSL::Buffering # # Unlike IO#gets the separator must be provided if a limit is provided. - def gets(eol=$/, limit=nil) + def gets(eol=$/, limit=nil, chomp: false) idx = @rbuffer.index(eol) until @eof break if idx @@ -247,7 +246,11 @@ module OpenSSL::Buffering if size && limit && limit >= 0 size = [size, limit].min end - consume_rbuff(size) + line = consume_rbuff(size) + if chomp && line + line.chomp!(eol) + end + line end ## @@ -345,17 +348,32 @@ module OpenSSL::Buffering def do_write(s) @wbuffer = Buffer.new unless defined? @wbuffer - @wbuffer << s - @wbuffer.force_encoding(Encoding::BINARY) + @wbuffer.append_as_bytes(s) + @sync ||= false - if @sync or @wbuffer.size > BLOCK_SIZE - until @wbuffer.empty? - begin - nwrote = syswrite(@wbuffer) - rescue Errno::EAGAIN - retry + buffer_size = @wbuffer.bytesize + if @sync or buffer_size > BLOCK_SIZE + nwrote = 0 + begin + while nwrote < buffer_size do + begin + chunk = if nwrote > 0 + @wbuffer.byteslice(nwrote, @wbuffer.bytesize) + else + @wbuffer + end + + nwrote += syswrite(chunk) + rescue Errno::EAGAIN + retry + end + end + ensure + if nwrote < @wbuffer.bytesize + @wbuffer[0, nwrote] = "" + else + @wbuffer.clear end - @wbuffer[0, nwrote] = "" end end end @@ -432,10 +450,10 @@ module OpenSSL::Buffering def puts(*args) s = Buffer.new if args.empty? - s << "\n" + s.append_as_bytes("\n") end args.each{|arg| - s << arg.to_s + s.append_as_bytes(arg.to_s) s.sub!(/(?<!\n)\z/, "\n") } do_write(s) @@ -449,7 +467,7 @@ module OpenSSL::Buffering def print(*args) s = Buffer.new - args.each{ |arg| s << arg.to_s } + args.each{ |arg| s.append_as_bytes(arg.to_s) } do_write(s) nil end diff --git a/ext/openssl/lib/openssl/cipher.rb b/ext/openssl/lib/openssl/cipher.rb index 8ad8c35dd3..ab75ac8e1a 100644 --- a/ext/openssl/lib/openssl/cipher.rb +++ b/ext/openssl/lib/openssl/cipher.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb index 2ff8398e44..46ddfd6021 100644 --- a/ext/openssl/lib/openssl/digest.rb +++ b/ext/openssl/lib/openssl/digest.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL @@ -18,13 +18,9 @@ module OpenSSL # Return the hash value computed with _name_ Digest. _name_ is either the # long name or short name of a supported digest algorithm. # - # === Examples + # === Example # # OpenSSL::Digest.digest("SHA256", "abc") - # - # which is equivalent to: - # - # OpenSSL::Digest.digest('SHA256', "abc") def self.digest(name, data) super(data, name) @@ -61,7 +57,7 @@ module OpenSSL # OpenSSL::Digest("MD5") # # => OpenSSL::Digest::MD5 # - # Digest("Foo") + # OpenSSL::Digest("Foo") # # => NameError: wrong constant name Foo def Digest(name) diff --git a/ext/openssl/lib/openssl/marshal.rb b/ext/openssl/lib/openssl/marshal.rb index af5647192a..eb8eda4748 100644 --- a/ext/openssl/lib/openssl/marshal.rb +++ b/ext/openssl/lib/openssl/marshal.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL module Marshal diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb index f6bf5892b0..39871e15dd 100644 --- a/ext/openssl/lib/openssl/pkey.rb +++ b/ext/openssl/lib/openssl/pkey.rb @@ -7,6 +7,9 @@ require_relative 'marshal' module OpenSSL::PKey + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + DHError = PKeyError + class DH include OpenSSL::Marshal @@ -35,6 +38,18 @@ module OpenSSL::PKey end # :call-seq: + # dh.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'. + def params + %w{p q g pub_key priv_key}.map { |name| + [name, send(name)] + }.to_h + end + + # :call-seq: # dh.compute_key(pub_bn) -> string # # Returns a String containing a shared secret computed from the other @@ -47,9 +62,19 @@ module OpenSSL::PKey # * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by # DH#public_key as that contains the DH parameters only. def compute_key(pub_bn) - peer = dup - peer.set_key(pub_bn, nil) - derive(peer) + # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very + # inefficient + obj = OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.ObjectId("dhKeyAgreement"), + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Integer(p), + OpenSSL::ASN1.Integer(g), + ]), + ]), + OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der), + ]) + derive(OpenSSL::PKey.read(obj.to_der)) end # :call-seq: @@ -61,14 +86,29 @@ module OpenSSL::PKey # called first in order to generate the per-session keys before performing # the actual key exchange. # + # <b>Deprecated in version 3.0</b>. This method is incompatible with + # OpenSSL 3.0.0 or later. + # # See also OpenSSL::PKey.generate_key. # # Example: - # dh = OpenSSL::PKey::DH.new(2048) - # public_key = dh.public_key #contains no private/public key yet - # public_key.generate_key! - # puts public_key.private? # => true + # # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later + # dh0 = OpenSSL::PKey::DH.new(2048) + # dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name) + # dh.generate_key! + # puts dh.private? # => true + # puts dh0.pub_key == dh.pub_key #=> false + # + # # With OpenSSL::PKey.generate_key + # dh0 = OpenSSL::PKey::DH.new(2048) + # dh = OpenSSL::PKey.generate_key(dh0) + # puts dh0.pub_key == dh.pub_key #=> false def generate_key! + if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000 + raise PKeyError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \ + "use OpenSSL::PKey.generate_key instead" + end + unless priv_key tmp = OpenSSL::PKey.generate_key(self) set_key(tmp.pub_key, tmp.priv_key) @@ -110,6 +150,9 @@ module OpenSSL::PKey end end + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + DSAError = PKeyError + class DSA include OpenSSL::Marshal @@ -129,6 +172,18 @@ module OpenSSL::PKey OpenSSL::PKey.read(public_to_der) end + # :call-seq: + # dsa.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'. + def params + %w{p q g pub_key priv_key}.map { |name| + [name, send(name)] + }.to_h + end + class << self # :call-seq: # DSA.generate(size) -> dsa @@ -142,8 +197,16 @@ module OpenSSL::PKey # +size+:: # The desired key size in bits. def generate(size, &blk) + # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224), + # (2048,256), and (3072,256). + # + # q size is derived here with compatibility with + # DSA_generator_parameters_ex() which previous versions of ruby/openssl + # used to call. + qsize = size >= 2048 ? 256 : 160 dsaparams = OpenSSL::PKey.generate_parameters("DSA", { "dsa_paramgen_bits" => size, + "dsa_paramgen_q_bits" => qsize, }, &blk) OpenSSL::PKey.generate_key(dsaparams) end @@ -185,13 +248,9 @@ module OpenSSL::PKey # sig = dsa.sign_raw(nil, digest) # p dsa.verify_raw(nil, sig, digest) #=> true def syssign(string) - q or raise OpenSSL::PKey::DSAError, "incomplete DSA" - private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!" - begin - sign_raw(nil, string) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::DSAError, $!.message - end + q or raise PKeyError, "incomplete DSA" + private? or raise PKeyError, "Private DSA key needed!" + sign_raw(nil, string) end # :call-seq: @@ -209,12 +268,13 @@ module OpenSSL::PKey # A \DSA signature value. def sysverify(digest, sig) verify_raw(nil, sig, digest) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::DSAError, $!.message end end if defined?(EC) + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + ECError = PKeyError + class EC include OpenSSL::Marshal @@ -225,8 +285,6 @@ module OpenSSL::PKey # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. def dsa_sign_asn1(data) sign_raw(nil, data) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::ECError, $!.message end # :call-seq: @@ -236,8 +294,6 @@ module OpenSSL::PKey # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. def dsa_verify_asn1(data, sig) verify_raw(nil, sig, data) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::ECError, $!.message end # :call-seq: @@ -249,9 +305,14 @@ module OpenSSL::PKey # This method is provided for backwards compatibility, and calls #derive # internally. def dh_compute_key(pubkey) - peer = OpenSSL::PKey::EC.new(group) - peer.public_key = pubkey - derive(peer) + obj = OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.ObjectId("id-ecPublicKey"), + group.to_der, + ]), + OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)), + ]) + derive(OpenSSL::PKey.read(obj.to_der)) end end @@ -272,6 +333,9 @@ module OpenSSL::PKey end end + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + RSAError = PKeyError + class RSA include OpenSSL::Marshal @@ -290,6 +354,18 @@ module OpenSSL::PKey OpenSSL::PKey.read(public_to_der) end + # :call-seq: + # rsa.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'n', 'e', 'd', 'p', 'q', 'dmp1', 'dmq1', and 'iqmp'. + def params + %w{n e d p q dmp1 dmq1 iqmp}.map { |name| + [name, send(name)] + }.to_h + end + class << self # :call-seq: # RSA.generate(size, exponent = 65537) -> RSA @@ -325,22 +401,19 @@ module OpenSSL::PKey # rsa.private_encrypt(string, padding) -> String # # Encrypt +string+ with the private key. +padding+ defaults to - # PKCS1_PADDING. The encrypted string output can be decrypted using + # PKCS1_PADDING, which is known to be insecure but is kept for backwards + # compatibility. The encrypted string output can be decrypted using # #public_decrypt. # # <b>Deprecated in version 3.0</b>. # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and # PKey::PKey#verify_recover instead. def private_encrypt(string, padding = PKCS1_PADDING) - n or raise OpenSSL::PKey::RSAError, "incomplete RSA" - private? or raise OpenSSL::PKey::RSAError, "private key needed." - begin - sign_raw(nil, string, { - "rsa_padding_mode" => translate_padding_mode(padding), - }) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::RSAError, $!.message - end + n or raise PKeyError, "incomplete RSA" + private? or raise PKeyError, "private key needed." + sign_raw(nil, string, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) end # :call-seq: @@ -348,20 +421,17 @@ module OpenSSL::PKey # rsa.public_decrypt(string, padding) -> String # # Decrypt +string+, which has been encrypted with the private key, with the - # public key. +padding+ defaults to PKCS1_PADDING. + # public key. +padding+ defaults to PKCS1_PADDING which is known to be + # insecure but is kept for backwards compatibility. # # <b>Deprecated in version 3.0</b>. # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and # PKey::PKey#verify_recover instead. def public_decrypt(string, padding = PKCS1_PADDING) - n or raise OpenSSL::PKey::RSAError, "incomplete RSA" - begin - verify_recover(nil, string, { - "rsa_padding_mode" => translate_padding_mode(padding), - }) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::RSAError, $!.message - end + n or raise PKeyError, "incomplete RSA" + verify_recover(nil, string, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) end # :call-seq: @@ -369,20 +439,17 @@ module OpenSSL::PKey # rsa.public_encrypt(string, padding) -> String # # Encrypt +string+ with the public key. +padding+ defaults to - # PKCS1_PADDING. The encrypted string output can be decrypted using + # PKCS1_PADDING, which is known to be insecure but is kept for backwards + # compatibility. The encrypted string output can be decrypted using # #private_decrypt. # # <b>Deprecated in version 3.0</b>. # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. def public_encrypt(data, padding = PKCS1_PADDING) - n or raise OpenSSL::PKey::RSAError, "incomplete RSA" - begin - encrypt(data, { - "rsa_padding_mode" => translate_padding_mode(padding), - }) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::RSAError, $!.message - end + n or raise PKeyError, "incomplete RSA" + encrypt(data, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) end # :call-seq: @@ -390,20 +457,17 @@ module OpenSSL::PKey # rsa.private_decrypt(string, padding) -> String # # Decrypt +string+, which has been encrypted with the public key, with the - # private key. +padding+ defaults to PKCS1_PADDING. + # private key. +padding+ defaults to PKCS1_PADDING, which is known to be + # insecure but is kept for backwards compatibility. # # <b>Deprecated in version 3.0</b>. # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. def private_decrypt(data, padding = PKCS1_PADDING) - n or raise OpenSSL::PKey::RSAError, "incomplete RSA" - private? or raise OpenSSL::PKey::RSAError, "private key needed." - begin - decrypt(data, { - "rsa_padding_mode" => translate_padding_mode(padding), - }) - rescue OpenSSL::PKey::PKeyError - raise OpenSSL::PKey::RSAError, $!.message - end + n or raise PKeyError, "incomplete RSA" + private? or raise PKeyError, "private key needed." + decrypt(data, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) end PKCS1_PADDING = 1 @@ -422,7 +486,7 @@ module OpenSSL::PKey when PKCS1_OAEP_PADDING "oaep" else - raise OpenSSL::PKey::PKeyError, "unsupported padding mode" + raise PKeyError, "unsupported padding mode" end end end diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index a9103ecd27..3268c126b9 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -7,10 +7,13 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require "openssl/buffering" + +if defined?(OpenSSL::SSL) + require "io/nonblock" require "ipaddr" require "socket" @@ -19,7 +22,6 @@ module OpenSSL module SSL class SSLContext DEFAULT_PARAMS = { # :nodoc: - :min_version => OpenSSL::SSL::TLS1_VERSION, :verify_mode => OpenSSL::SSL::VERIFY_PEER, :verify_hostname => true, :options => -> { @@ -30,28 +32,9 @@ module OpenSSL }.call } - if defined?(OpenSSL::PKey::DH) - DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY -JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab -VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6 -YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 -1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD -7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg== ------END DH PARAMETERS----- - _end_of_pem_ - private_constant :DEFAULT_2048 - - DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc: - warn "using default DH parameters." if $VERBOSE - DEFAULT_2048 - } - end - - if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") && - OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000) + if !OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") DEFAULT_PARAMS.merge!( + min_version: OpenSSL::SSL::TLS1_VERSION, ciphers: %w{ ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 @@ -83,26 +66,13 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 AES256-SHA256 AES128-SHA AES256-SHA - }.join(":"), + }.join(":").freeze, ) end + DEFAULT_PARAMS.freeze DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc: DEFAULT_CERT_STORE.set_default_paths - DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL - - # A callback invoked when DH parameters are required for ephemeral DH key - # exchange. - # - # The callback is invoked with the SSLSocket, a - # flag indicating the use of an export cipher and the keylength - # required. - # - # The callback must return an OpenSSL::PKey::DH instance of the correct - # key length. - # - # <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead. - attr_accessor :tmp_dh_callback # A callback invoked at connect time to distinguish between multiple # server names. @@ -122,7 +92,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 # that this form is deprecated. New applications should use #min_version= # and #max_version= as necessary. def initialize(version = nil) - self.options |= OpenSSL::SSL::OP_ALL self.ssl_version = version if version self.verify_mode = OpenSSL::SSL::VERIFY_NONE self.verify_hostname = false @@ -142,54 +111,24 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 # used. def set_params(params={}) params = DEFAULT_PARAMS.merge(params) - self.options = params.delete(:options) # set before min_version/max_version + self.options |= params.delete(:options) # set before min_version/max_version params.each{|name, value| self.__send__("#{name}=", value) } if self.verify_mode != OpenSSL::SSL::VERIFY_NONE unless self.ca_file or self.ca_path or self.cert_store - self.cert_store = DEFAULT_CERT_STORE + if not defined?(Ractor) or Ractor.current == Ractor.main + self.cert_store = DEFAULT_CERT_STORE + else + self.cert_store = Ractor.current[:__openssl_default_store__] ||= + OpenSSL::X509::Store.new.tap { |store| + store.set_default_paths + } + end end end return params end # call-seq: - # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION - # ctx.min_version = :TLS1_2 - # ctx.min_version = nil - # - # Sets the lower bound on the supported SSL/TLS protocol version. The - # version may be specified by an integer constant named - # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version". - # - # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v* - # options by #options= once you have called #min_version= or - # #max_version=. - # - # === Example - # ctx = OpenSSL::SSL::SSLContext.new - # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION - # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION - # - # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx) - # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2 - def min_version=(version) - set_minmax_proto_version(version, @max_proto_version ||= nil) - @min_proto_version = version - end - - # call-seq: - # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION - # ctx.max_version = :TLS1_2 - # ctx.max_version = nil - # - # Sets the upper bound of the supported SSL/TLS protocol version. See - # #min_version= for the possible values. - def max_version=(version) - set_minmax_proto_version(@min_proto_version ||= nil, version) - @max_proto_version = version - end - - # call-seq: # ctx.ssl_version = :TLSv1 # ctx.ssl_version = "SSLv23" # @@ -213,8 +152,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end version = METHODS_MAP[meth.intern] or raise ArgumentError, "unknown SSL method `%s'" % meth - set_minmax_proto_version(version, version) - @min_proto_version = @max_proto_version = version + self.min_version = self.max_version = version end METHODS_MAP = { @@ -249,6 +187,14 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 to_io.peeraddr end + def local_address + to_io.local_address + end + + def remote_address + to_io.remote_address + end + def setsockopt(level, optname, optval) to_io.setsockopt(level, optname, optval) end @@ -268,6 +214,36 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 def do_not_reverse_lookup=(flag) to_io.do_not_reverse_lookup = flag end + + def close_on_exec=(value) + to_io.close_on_exec = value + end + + def close_on_exec? + to_io.close_on_exec? + end + + def wait(*args) + to_io.wait(*args) + end + + def wait_readable(*args) + to_io.wait_readable(*args) + end + + def wait_writable(*args) + to_io.wait_writable(*args) + end + + if IO.method_defined?(:timeout) + def timeout + to_io.timeout + end + + def timeout=(value) + to_io.timeout=(value) + end + end end def verify_certificate_identity(cert, hostname) @@ -418,6 +394,32 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 nil end + # Close the stream for reading. + # This method is ignored by OpenSSL as there is no reasonable way to + # implement it, but exists for compatibility with IO. + def close_read + # Unsupported and ignored. + # Just don't read any more. + end + + # Closes the stream for writing. The behavior of this method depends on + # the version of OpenSSL and the TLS protocol in use. + # + # - Sends a 'close_notify' alert to the peer. + # - Does not wait for the peer's 'close_notify' alert in response. + # + # In TLS 1.2 and earlier: + # - On receipt of a 'close_notify' alert, responds with a 'close_notify' + # alert of its own and close down the connection immediately, + # discarding any pending writes. + # + # Therefore, on TLS 1.2, this method will cause the connection to be + # completely shut down. On TLS 1.3, the connection will remain open for + # reading only. + def close_write + stop + end + private def using_anon_cipher? @@ -430,10 +432,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 @context.client_cert_cb end - def tmp_dh_callback - @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK - end - def session_new_cb @context.session_new_cb end @@ -491,7 +489,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 unless ctx.session_id_context # see #6137 - session id may not exceed 32 bytes prng = ::Random.new($0.hash) - session_id = prng.bytes(16).unpack('H*')[0] + session_id = prng.bytes(16).unpack1('H*') @ctx.session_id_context = session_id end @start_immediately = true @@ -540,3 +538,5 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end end end + +end diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb index acd53d440d..88570562e2 100644 --- a/ext/openssl/lib/openssl/version.rb +++ b/ext/openssl/lib/openssl/version.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true module OpenSSL - VERSION = "3.0.0.pre" + # The version string of Ruby/OpenSSL. + VERSION = "4.0.0" end diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb index 448941f75e..66765ffeab 100644 --- a/ext/openssl/lib/openssl/x509.rb +++ b/ext/openssl/lib/openssl/x509.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ require_relative 'marshal' @@ -122,8 +122,8 @@ module OpenSSL include Helpers # Get the distributionPoint fullName URI from the certificate's CRL - # distribution points extension, as described in RFC5280 Section - # 4.2.1.13 + # distribution points extension, as described in RFC 5280 Section + # 4.2.1.13. # # Returns an array of strings or nil or raises ASN1::ASN1Error. def crl_uris @@ -135,19 +135,19 @@ module OpenSSL raise ASN1::ASN1Error, "invalid extension" end - crl_uris = cdp_asn1.map do |crl_distribution_point| + crl_uris = cdp_asn1.flat_map do |crl_distribution_point| distribution_point = crl_distribution_point.value.find do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 end full_name = distribution_point&.value&.find do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 end - full_name&.value&.find do |v| + full_name&.value&.select do |v| v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier end end - crl_uris&.map(&:value) + crl_uris.empty? ? nil : crl_uris.map(&:value) end end @@ -279,11 +279,29 @@ module OpenSSL end class << self + # Parses the UTF-8 string representation of a distinguished name, + # according to RFC 2253. + # + # See also #to_utf8 for the opposite operation. def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end + # Parses the string representation of a distinguished name. Two + # different forms are supported: + # + # - \OpenSSL format (<tt>X509_NAME_oneline()</tt>) used by + # <tt>#to_s</tt>. For example: <tt>/DC=com/DC=example/CN=nobody</tt> + # - \OpenSSL format (<tt>X509_NAME_print()</tt>) + # used by <tt>#to_s(OpenSSL::X509::Name::COMPAT)</tt>. For example: + # <tt>DC=com, DC=example, CN=nobody</tt> + # + # Neither of them is standardized and has quirks and inconsistencies + # in handling of escaped characters or multi-valued RDNs. + # + # Use of this method is discouraged in new applications. See + # Name.parse_rfc2253 and #to_utf8 for the alternative. def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) if str.start_with?("/") # /A=B/C=D format @@ -328,6 +346,15 @@ module OpenSSL include Extension::CRLDistributionPoints include Extension::AuthorityInfoAccess + def inspect + "#<#{self.class}: " \ + "subject=#{subject.inspect}, " \ + "issuer=#{issuer.inspect}, " \ + "serial=#{serial.inspect}, " \ + "not_before=#{not_before.inspect rescue "(error)"}, " \ + "not_after=#{not_after.inspect rescue "(error)"}>" + end + def pretty_print(q) q.object_group(self) { q.breakable diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec index 38bcb9db5f..7072d599d8 100644 --- a/ext/openssl/openssl.gemspec +++ b/ext/openssl/openssl.gemspec @@ -1,21 +1,28 @@ Gem::Specification.new do |spec| spec.name = "openssl" - spec.version = "3.0.0.pre" + spec.version = "4.0.0" spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"] spec.email = ["ruby-core@ruby-lang.org"] - spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.} - spec.description = %q{It wraps the OpenSSL library.} + spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby} + spec.description = %q{OpenSSL for Ruby provides access to SSL/TLS and general-purpose cryptography based on the OpenSSL library.} spec.homepage = "https://github.com/ruby/openssl" - spec.license = "Ruby" + spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"] - spec.require_paths = ["lib"] - spec.extensions = ["ext/openssl/extconf.rb"] + if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' + spec.platform = "java" + spec.files = [] + spec.add_runtime_dependency('jruby-openssl', '~> 0.14') + else + spec.files = Dir.glob(["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md"], base: File.expand_path("..", __FILE__)) + + ["BSDL", "COPYING"] + spec.require_paths = ["lib"] + spec.extensions = ["ext/openssl/extconf.rb"] + end spec.extra_rdoc_files = Dir["*.md"] spec.rdoc_options = ["--main", "README.md"] - spec.required_ruby_version = ">= 2.6.0" + spec.required_ruby_version = ">= 2.7.0" spec.metadata["msys2_mingw_dependencies"] = "openssl" end diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c deleted file mode 100644 index 8b93cba6d4..0000000000 --- a/ext/openssl/openssl_missing.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include RUBY_EXTCONF_H - -#include <string.h> /* memcpy() */ -#if !defined(OPENSSL_NO_ENGINE) -# include <openssl/engine.h> -#endif -#include <openssl/x509_vfy.h> - -#include "openssl_missing.h" - -/*** added in 1.1.0 ***/ -#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) -void -ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = crl->signature; - if (palg != NULL) - *palg = crl->sig_alg; -} -#endif - -#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) -void -ossl_X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = req->signature; - if (palg != NULL) - *palg = req->sig_alg; -} -#endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 4d9b880138..6592f9ccea 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -5,213 +5,28 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OPENSSL_MISSING_H_) #define _OSSL_OPENSSL_MISSING_H_ #include "ruby/config.h" -/* added in 1.1.0 */ -#if !defined(HAVE_EVP_MD_CTX_NEW) -# define EVP_MD_CTX_new EVP_MD_CTX_create +/* added in 3.0.0 */ +#ifndef HAVE_EVP_MD_CTX_GET0_MD +# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) #endif -#if !defined(HAVE_EVP_MD_CTX_FREE) -# define EVP_MD_CTX_free EVP_MD_CTX_destroy -#endif - -#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX) -# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx -#endif - -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -# define X509_STORE_get_ex_data(x, idx) \ - CRYPTO_get_ex_data(&(x)->ex_data, (idx)) -#endif - -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -# define X509_STORE_set_ex_data(x, idx, data) \ - CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data)) -#endif - -#if !defined(HAVE_X509_STORE_GET_EX_NEW_INDEX) && !defined(X509_STORE_get_ex_new_index) -# define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ - CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \ - (newf), (dupf), (freef)) -#endif - -#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) -void ossl_X509_CRL_get0_signature(const X509_CRL *, const ASN1_BIT_STRING **, const X509_ALGOR **); -# define X509_CRL_get0_signature ossl_X509_CRL_get0_signature -#endif - -#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) -void ossl_X509_REQ_get0_signature(const X509_REQ *, const ASN1_BIT_STRING **, const X509_ALGOR **); -# define X509_REQ_get0_signature ossl_X509_REQ_get0_signature -#endif - -#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER) -# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber) -#endif - -#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE) -# define X509_REVOKED_get0_revocationDate(x) ((x)->revocationDate) -#endif - -#if !defined(HAVE_X509_GET0_TBS_SIGALG) -# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_UNTRUSTED) -# define X509_STORE_CTX_get0_untrusted(x) ((x)->untrusted) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_CERT) -# define X509_STORE_CTX_get0_cert(x) ((x)->cert) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_CHAIN) -# define X509_STORE_CTX_get0_chain(ctx) X509_STORE_CTX_get_chain(ctx) -#endif - -#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID) -# define OCSP_SINGLERESP_get0_id(s) ((s)->certId) -#endif - -#if !defined(HAVE_SSL_CTX_GET_CIPHERS) -# define SSL_CTX_get_ciphers(ctx) ((ctx)->cipher_list) -#endif - -#if !defined(HAVE_X509_UP_REF) -# define X509_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509) -#endif - -#if !defined(HAVE_X509_CRL_UP_REF) -# define X509_CRL_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_CRL); -#endif - -#if !defined(HAVE_X509_STORE_UP_REF) -# define X509_STORE_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_STORE); -#endif - -#if !defined(HAVE_SSL_SESSION_UP_REF) -# define SSL_SESSION_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_SSL_SESSION); -#endif - -#if !defined(HAVE_EVP_PKEY_UP_REF) -# define EVP_PKEY_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY); -#endif - -#if !defined(HAVE_OPAQUE_OPENSSL) -#define IMPL_PKEY_GETTER(_type, _name) \ -static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \ - return pkey->pkey._name; } -#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \ -static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2) { \ - if (a1) *a1 = obj->a1; \ - if (a2) *a2 = obj->a2; } \ -static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \ - if (_fail_cond) return 0; \ - BN_clear_free(obj->a1); obj->a1 = a1; \ - BN_clear_free(obj->a2); obj->a2 = a2; \ - return 1; } -#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \ -static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \ - if (a1) *a1 = obj->a1; \ - if (a2) *a2 = obj->a2; \ - if (a3) *a3 = obj->a3; } \ -static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2, BIGNUM *a3) { \ - if (_fail_cond) return 0; \ - BN_clear_free(obj->a1); obj->a1 = a1; \ - BN_clear_free(obj->a2); obj->a2 = a2; \ - BN_clear_free(obj->a3); obj->a3 = a3; \ - return 1; } - -#if !defined(OPENSSL_NO_RSA) -IMPL_PKEY_GETTER(RSA, rsa) -IMPL_KEY_ACCESSOR3(RSA, key, n, e, d, (n == obj->n || e == obj->e || (obj->d && d == obj->d))) -IMPL_KEY_ACCESSOR2(RSA, factors, p, q, (p == obj->p || q == obj->q)) -IMPL_KEY_ACCESSOR3(RSA, crt_params, dmp1, dmq1, iqmp, (dmp1 == obj->dmp1 || dmq1 == obj->dmq1 || iqmp == obj->iqmp)) -#endif - -#if !defined(OPENSSL_NO_DSA) -IMPL_PKEY_GETTER(DSA, dsa) -IMPL_KEY_ACCESSOR2(DSA, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) -IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g)) -#endif - -#if !defined(OPENSSL_NO_DH) -IMPL_PKEY_GETTER(DH, dh) -IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) -IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || (obj->q && q == obj->q) || g == obj->g)) -static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } -#endif - -#if !defined(OPENSSL_NO_EC) -IMPL_PKEY_GETTER(EC_KEY, ec) -#endif - -#undef IMPL_PKEY_GETTER -#undef IMPL_KEY_ACCESSOR2 -#undef IMPL_KEY_ACCESSOR3 -#endif /* HAVE_OPAQUE_OPENSSL */ - -#if !defined(EVP_CTRL_AEAD_GET_TAG) -# define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG -# define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG -# define EVP_CTRL_AEAD_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN -#endif - -#if !defined(HAVE_X509_GET0_NOTBEFORE) -# define X509_get0_notBefore(x) X509_get_notBefore(x) -# define X509_get0_notAfter(x) X509_get_notAfter(x) -# define X509_CRL_get0_lastUpdate(x) X509_CRL_get_lastUpdate(x) -# define X509_CRL_get0_nextUpdate(x) X509_CRL_get_nextUpdate(x) -# define X509_set1_notBefore(x, t) X509_set_notBefore(x, t) -# define X509_set1_notAfter(x, t) X509_set_notAfter(x, t) -# define X509_CRL_set1_lastUpdate(x, t) X509_CRL_set_lastUpdate(x, t) -# define X509_CRL_set1_nextUpdate(x, t) X509_CRL_set_nextUpdate(x, t) -#endif - -#if !defined(HAVE_SSL_SESSION_GET_PROTOCOL_VERSION) -# define SSL_SESSION_get_protocol_version(s) ((s)->ssl_version) -#endif - -#if !defined(HAVE_TS_STATUS_INFO_GET0_STATUS) -# define TS_STATUS_INFO_get0_status(a) ((a)->status) -#endif - -#if !defined(HAVE_TS_STATUS_INFO_GET0_TEXT) -# define TS_STATUS_INFO_get0_text(a) ((a)->text) -#endif - -#if !defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO) -# define TS_STATUS_INFO_get0_failure_info(a) ((a)->failure_info) -#endif - -#if !defined(HAVE_TS_VERIFY_CTS_SET_CERTS) -# define TS_VERIFY_CTS_set_certs(ctx, crts) ((ctx)->certs=(crts)) -#endif - -#if !defined(HAVE_TS_VERIFY_CTX_SET_STORE) -# define TS_VERIFY_CTX_set_store(ctx, str) ((ctx)->store=(str)) -#endif - -#if !defined(HAVE_TS_VERIFY_CTX_ADD_FLAGS) -# define TS_VERIFY_CTX_add_flags(ctx, f) ((ctx)->flags |= (f)) +/* + * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to + * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0. + */ +#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX +# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x) #endif -#if !defined(HAVE_TS_RESP_CTX_SET_TIME_CB) -# define TS_RESP_CTX_set_time_cb(ctx, callback, dta) do { \ - (ctx)->time_cb = (callback); \ - (ctx)->time_cb_data = (dta); \ - } while (0) +#ifndef HAVE_EVP_PKEY_EQ +# define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b) #endif #endif /* _OSSL_OPENSSL_MISSING_H_ */ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index c7a755ceda..98127fcba0 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -5,93 +5,79 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" #include <stdarg.h> /* for ossl_raise */ -/* OpenSSL >= 1.1.0 and LibreSSL >= 2.9.0 */ -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000 -# define HAVE_OPENSSL_110_THREADING_API -#else -# include <ruby/thread_native.h> -#endif - /* * Data Conversion */ -#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \ -VALUE \ -ossl_##name##_ary2sk0(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - VALUE val; \ - type *x; \ - int i; \ - \ - Check_Type(ary, T_ARRAY); \ - sk = sk_##type##_new_null(); \ - if (!sk) ossl_raise(eOSSLError, NULL); \ - \ - for (i = 0; i < RARRAY_LEN(ary); i++) { \ - val = rb_ary_entry(ary, i); \ - if (!rb_obj_is_kind_of(val, expected_class)) { \ - sk_##type##_pop_free(sk, type##_free); \ - ossl_raise(eOSSLError, "object in array not" \ - " of class ##type##"); \ - } \ - x = dup(val); /* NEED TO DUP */ \ - sk_##type##_push(sk, x); \ - } \ - return (VALUE)sk; \ -} \ - \ -STACK_OF(type) * \ -ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ -{ \ - return (STACK_OF(type)*)rb_protect( \ - (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \ - ary, \ - status); \ -} \ - \ -STACK_OF(type) * \ -ossl_##name##_ary2sk(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - int status = 0; \ - \ - sk = ossl_protect_##name##_ary2sk(ary, &status); \ - if (status) rb_jump_tag(status); \ - \ - return sk; \ +#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \ +VALUE \ +ossl_##name##_ary2sk0(VALUE ary) \ +{ \ + STACK_OF(type) *sk; \ + VALUE val; \ + type *x; \ + int i; \ + \ + Check_Type(ary, T_ARRAY); \ + sk = sk_##type##_new_null(); \ + if (!sk) ossl_raise(eOSSLError, NULL); \ + \ + for (i = 0; i < RARRAY_LEN(ary); i++) { \ + val = rb_ary_entry(ary, i); \ + if (!rb_obj_is_kind_of(val, expected_class)) { \ + sk_##type##_pop_free(sk, type##_free); \ + ossl_raise(eOSSLError, "object in array not" \ + " of class ##type##"); \ + } \ + x = dup(val); /* NEED TO DUP */ \ + sk_##type##_push(sk, x); \ + } \ + return (VALUE)sk; \ +} \ + \ +STACK_OF(type) * \ +ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ +{ \ + return (STACK_OF(type)*)rb_protect( \ + (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \ + ary, \ + status); \ +} \ + \ +STACK_OF(type) * \ +ossl_##name##_ary2sk(VALUE ary) \ +{ \ + STACK_OF(type) *sk; \ + int status = 0; \ + \ + sk = ossl_protect_##name##_ary2sk(ary, &status); \ + if (status) rb_jump_tag(status); \ + \ + return sk; \ } OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr) -#define OSSL_IMPL_SK2ARY(name, type) \ -VALUE \ -ossl_##name##_sk2ary(const STACK_OF(type) *sk) \ -{ \ - type *t; \ - int i, num; \ - VALUE ary; \ - \ - if (!sk) { \ - OSSL_Debug("empty sk!"); \ - return Qnil; \ - } \ - num = sk_##type##_num(sk); \ - if (num < 0) { \ - OSSL_Debug("items in sk < -1???"); \ - return rb_ary_new(); \ - } \ - ary = rb_ary_new2(num); \ - \ - for (i=0; i<num; i++) { \ - t = sk_##type##_value(sk, i); \ - rb_ary_push(ary, ossl_##name##_new(t)); \ - } \ - return ary; \ +#define OSSL_IMPL_SK2ARY(name, type) \ +VALUE \ +ossl_##name##_sk2ary(const STACK_OF(type) *sk) \ +{ \ + type *t; \ + int i, num; \ + VALUE ary; \ + \ + RUBY_ASSERT(sk != NULL); \ + num = sk_##type##_num(sk); \ + ary = rb_ary_new_capa(num); \ + \ + for (i=0; i<num; i++) { \ + t = sk_##type##_value(sk, i); \ + rb_ary_push(ary, ossl_##name##_new(t)); \ + } \ + return ary; \ } OSSL_IMPL_SK2ARY(x509, X509) OSSL_IMPL_SK2ARY(x509crl, X509_CRL) @@ -111,14 +97,14 @@ ossl_str_new(const char *ptr, long len, int *pstate) str = rb_protect(ossl_str_new_i, len, &state); if (pstate) - *pstate = state; + *pstate = state; if (state) { - if (!pstate) - rb_set_errinfo(Qnil); - return Qnil; + if (!pstate) + rb_set_errinfo(Qnil); + return Qnil; } if (ptr) - memcpy(RSTRING_PTR(str), ptr, len); + memcpy(RSTRING_PTR(str), ptr, len); return str; } @@ -131,22 +117,22 @@ ossl_buf2str(char *buf, int len) str = ossl_str_new(buf, len, &state); OPENSSL_free(buf); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return str; } void -ossl_bin2hex(unsigned char *in, char *out, size_t inlen) +ossl_bin2hex(const unsigned char *in, char *out, size_t inlen) { const char *hex = "0123456789abcdef"; size_t i; assert(inlen <= LONG_MAX / 2); for (i = 0; i < inlen; i++) { - unsigned char p = in[i]; + unsigned char p = in[i]; - out[i * 2 + 0] = hex[p >> 4]; - out[i * 2 + 1] = hex[p & 0x0f]; + out[i * 2 + 0] = hex[p >> 4]; + out[i * 2 + 1] = hex[p & 0x0f]; } } @@ -157,14 +143,14 @@ VALUE ossl_pem_passwd_value(VALUE pass) { if (NIL_P(pass)) - return Qnil; + return Qnil; StringValue(pass); /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb, * that is +max_len+ of ossl_pem_passwd_cb() */ if (RSTRING_LEN(pass) > PEM_BUFSIZE) - ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE); + ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE); return pass; } @@ -174,7 +160,7 @@ ossl_pem_passwd_cb0(VALUE flag) { VALUE pass = rb_yield(flag); if (NIL_P(pass)) - return Qnil; + return Qnil; StringValue(pass); return pass; } @@ -187,46 +173,46 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_) VALUE rflag, pass = (VALUE)pwd_; if (RTEST(pass)) { - /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not - * work because it does not allow NUL characters and truncates to 1024 - * bytes silently if the input is over 1024 bytes */ - if (RB_TYPE_P(pass, T_STRING)) { - len = RSTRING_LEN(pass); - if (len <= max_len) { - memcpy(buf, RSTRING_PTR(pass), len); - return (int)len; - } - } - OSSL_Debug("passed data is not valid String???"); - return -1; + /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not + * work because it does not allow NUL characters and truncates to 1024 + * bytes silently if the input is over 1024 bytes */ + if (RB_TYPE_P(pass, T_STRING)) { + len = RSTRING_LEN(pass); + if (len <= max_len) { + memcpy(buf, RSTRING_PTR(pass), len); + return (int)len; + } + } + OSSL_Debug("passed data is not valid String???"); + return -1; } if (!rb_block_given_p()) { - return PEM_def_callback(buf, max_len, flag, NULL); + return PEM_def_callback(buf, max_len, flag, NULL); } while (1) { - /* - * when the flag is nonzero, this passphrase - * will be used to perform encryption; otherwise it will - * be used to perform decryption. - */ - rflag = flag ? Qtrue : Qfalse; - pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); - if (status) { - /* ignore an exception raised. */ - rb_set_errinfo(Qnil); - return -1; - } - if (NIL_P(pass)) - return -1; - len = RSTRING_LEN(pass); - if (len > max_len) { - rb_warning("password must not be longer than %d bytes", max_len); - continue; - } - memcpy(buf, RSTRING_PTR(pass), len); - break; + /* + * when the flag is nonzero, this password + * will be used to perform encryption; otherwise it will + * be used to perform decryption. + */ + rflag = flag ? Qtrue : Qfalse; + pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); + if (status) { + /* ignore an exception raised. */ + rb_set_errinfo(Qnil); + return -1; + } + if (NIL_P(pass)) + return -1; + len = RSTRING_LEN(pass); + if (len > max_len) { + rb_warning("password must not be longer than %d bytes", max_len); + continue; + } + memcpy(buf, RSTRING_PTR(pass), len); + break; } return (int)len; } @@ -261,34 +247,46 @@ VALUE ossl_to_der_if_possible(VALUE obj) { if(rb_respond_to(obj, ossl_s_to_der)) - return ossl_to_der(obj); + return ossl_to_der(obj); return obj; } /* * Errors */ +static ID id_i_errors; + +static void collect_errors_into(VALUE ary); + VALUE ossl_make_error(VALUE exc, VALUE str) { unsigned long e; + const char *data; + int flags; + VALUE errors = rb_ary_new(); + + if (NIL_P(str)) + str = rb_str_new(NULL, 0); - e = ERR_peek_last_error(); +#ifdef HAVE_ERR_GET_ERROR_ALL + e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags); +#else + e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags); +#endif if (e) { - const char *msg = ERR_reason_error_string(e); - - if (NIL_P(str)) { - if (msg) str = rb_str_new_cstr(msg); - } - else { - if (RSTRING_LEN(str)) rb_str_cat2(str, ": "); - rb_str_cat2(str, msg ? msg : "(null)"); - } - ossl_clear_error(); + const char *msg = ERR_reason_error_string(e); + + if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": "); + rb_str_cat_cstr(str, msg ? msg : "(null)"); + if (flags & ERR_TXT_STRING && data) + rb_str_catf(str, " (%s)", data); + collect_errors_into(errors); } - if (NIL_P(str)) str = rb_str_new(0, 0); - return rb_exc_new3(exc, str); + VALUE obj = rb_exc_new_str(exc, str); + rb_ivar_set(obj, id_i_errors, errors); + return obj; } void @@ -298,55 +296,108 @@ ossl_raise(VALUE exc, const char *fmt, ...) VALUE err; if (fmt) { - va_start(args, fmt); - err = rb_vsprintf(fmt, args); - va_end(args); + va_start(args, fmt); + err = rb_vsprintf(fmt, args); + va_end(args); } else { - err = Qnil; + err = Qnil; } rb_exc_raise(ossl_make_error(exc, err)); } -void -ossl_clear_error(void) +static void +collect_errors_into(VALUE ary) { - if (dOSSL == Qtrue) { - unsigned long e; - const char *file, *data, *errstr; - int line, flags; - - while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) { - errstr = ERR_error_string(e, NULL); - if (!errstr) - errstr = "(null)"; - - if (flags & ERR_TXT_STRING) { - if (!data) - data = "(null)"; - rb_warn("error on stack: %s (%s)", errstr, data); - } - else { - rb_warn("error on stack: %s", errstr); - } - } + if (dOSSL == Qtrue || !NIL_P(ary)) { + unsigned long e; + const char *file, *data, *func, *lib, *reason; + int line, flags; + +#ifdef HAVE_ERR_GET_ERROR_ALL + while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) { +#else + while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) { + func = ERR_func_error_string(e); +#endif + lib = ERR_lib_error_string(e); + reason = ERR_reason_error_string(e); + + VALUE str = rb_sprintf("error:%08lX:%s:%s:%s", e, lib ? lib : "", + func ? func : "", reason ? reason : ""); + if (flags & ERR_TXT_STRING) { + if (!data) + data = "(null)"; + rb_str_catf(str, " (%s)", data); + } + + if (dOSSL == Qtrue) + rb_warn("error on stack: %"PRIsVALUE, str); + if (!NIL_P(ary)) + rb_ary_push(ary, str); + } } else { - ERR_clear_error(); + ERR_clear_error(); } } +void +ossl_clear_error(void) +{ + collect_errors_into(Qnil); +} + +/* + * call-seq: + * ossl_error.detailed_message(**) -> string + * + * Returns the exception message decorated with the captured \OpenSSL error + * queue entries. + */ +static VALUE +osslerror_detailed_message(int argc, VALUE *argv, VALUE self) +{ + VALUE str; +#ifdef HAVE_RB_CALL_SUPER_KW + // Ruby >= 3.2 + if (RTEST(rb_funcall(rb_eException, rb_intern("method_defined?"), 1, + ID2SYM(rb_intern("detailed_message"))))) + str = rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS); + else +#endif + str = rb_funcall(self, rb_intern("message"), 0); + VALUE errors = rb_attr_get(self, id_i_errors); + + // OpenSSLError was not created by ossl_make_error() + if (!RB_TYPE_P(errors, T_ARRAY)) + return str; + + str = rb_str_resurrect(str); + rb_str_catf(str, "\nOpenSSL error queue reported %ld errors:", + RARRAY_LEN(errors)); + for (long i = 0; i < RARRAY_LEN(errors); i++) { + VALUE err = RARRAY_AREF(errors, i); + rb_str_catf(str, "\n%"PRIsVALUE, err); + } + return str; +} + /* * call-seq: * OpenSSL.errors -> [String...] * - * See any remaining errors held in queue. + * Returns any remaining errors held in the \OpenSSL thread-local error queue + * and clears the queue. This should normally return an empty array. * - * Any errors you see here are probably due to a bug in Ruby's OpenSSL - * implementation. + * This is intended for debugging Ruby/OpenSSL. If you see any errors here, + * it likely indicates a bug in the extension. Please file an issue at + * https://github.com/ruby/openssl. + * + * For debugging your program, OpenSSL.debug= may be useful. */ -VALUE +static VALUE ossl_get_errors(VALUE _) { VALUE ary; @@ -365,25 +416,11 @@ ossl_get_errors(VALUE _) */ VALUE dOSSL; -#if !defined(HAVE_VA_ARGS_MACRO) -void -ossl_debug(const char *fmt, ...) -{ - va_list args; - - if (dOSSL == Qtrue) { - fprintf(stderr, "OSSL_DEBUG: "); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, " [CONTEXT N/A]\n"); - } -} -#endif - /* * call-seq: * OpenSSL.debug -> true | false + * + * Returns whether Ruby/OpenSSL's debug mode is currently enabled. */ static VALUE ossl_debug_get(VALUE self) @@ -393,9 +430,9 @@ ossl_debug_get(VALUE self) /* * call-seq: - * OpenSSL.debug = boolean -> boolean + * OpenSSL.debug = boolean * - * Turns on or off debug mode. With debug mode, all errors added to the OpenSSL + * Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL * error queue will be printed to stderr. */ static VALUE @@ -409,12 +446,18 @@ ossl_debug_set(VALUE self, VALUE val) /* * call-seq: * OpenSSL.fips_mode -> true | false + * + * Returns whether the FIPS mode is currently enabled. */ static VALUE ossl_fips_mode_get(VALUE self) { -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + VALUE enabled; + enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse; + return enabled; +#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) VALUE enabled; enabled = FIPS_mode() ? Qtrue : Qfalse; return enabled; @@ -425,10 +468,10 @@ ossl_fips_mode_get(VALUE self) /* * call-seq: - * OpenSSL.fips_mode = boolean -> boolean + * OpenSSL.fips_mode = boolean * * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an - * effect for FIPS-capable installations of the OpenSSL library. Trying to do + * effect for FIPS-capable installations of the \OpenSSL library. Trying to do * so otherwise will result in an error. * * === Examples @@ -438,193 +481,43 @@ ossl_fips_mode_get(VALUE self) static VALUE ossl_fips_mode_set(VALUE self, VALUE enabled) { - -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) if (RTEST(enabled)) { - int mode = FIPS_mode(); - if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ - ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + if (!EVP_default_properties_enable_fips(NULL, 1)) { + ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + } } else { - if(!FIPS_mode_set(0)) /* turning off twice is OK */ - ossl_raise(eOSSLError, "Turning off FIPS mode failed"); + if (!EVP_default_properties_enable_fips(NULL, 0)) { + ossl_raise(eOSSLError, "Turning off FIPS mode failed"); + } + } + return enabled; +#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) + if (RTEST(enabled)) { + int mode = FIPS_mode(); + if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ + ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + } else { + if(!FIPS_mode_set(0)) /* turning off twice is OK */ + ossl_raise(eOSSLError, "Turning off FIPS mode failed"); } return enabled; #else if (RTEST(enabled)) - ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode"); + ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode"); return enabled; #endif } -#if defined(OSSL_DEBUG) -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \ - defined(CRYPTO_malloc_debug_init)) -/* - * call-seq: - * OpenSSL.mem_check_start -> nil - * - * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory - * allocations. See also OpenSSL.print_mem_leaks. - * - * This is available only when built with a capable OpenSSL and --enable-debug - * configure option. - */ -static VALUE -mem_check_start(VALUE self) -{ - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - return Qnil; -} - -/* - * call-seq: - * OpenSSL.print_mem_leaks -> true | false - * - * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr). - * Prints detected memory leaks to standard error. This cleans the global state - * up thus you cannot use any methods of the library after calling this. - * - * Returns +true+ if leaks detected, +false+ otherwise. - * - * This is available only when built with a capable OpenSSL and --enable-debug - * configure option. - * - * === Example - * OpenSSL.mem_check_start - * NOT_GCED = OpenSSL::PKey::RSA.new(256) - * - * END { - * GC.start - * OpenSSL.print_mem_leaks # will print the leakage - * } - */ -static VALUE -print_mem_leaks(VALUE self) -{ -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - int ret; -#endif - -#ifndef HAVE_RB_EXT_RACTOR_SAFE - // for Ruby 2.x - void ossl_bn_ctx_free(void); // ossl_bn.c - ossl_bn_ctx_free(); -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ret = CRYPTO_mem_leaks_fp(stderr); - if (ret < 0) - ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp"); - return ret ? Qfalse : Qtrue; -#else - CRYPTO_mem_leaks_fp(stderr); - return Qnil; -#endif -} -#endif -#endif - -#if !defined(HAVE_OPENSSL_110_THREADING_API) -/** - * Stores locks needed for OpenSSL thread safety - */ -struct CRYPTO_dynlock_value { - rb_nativethread_lock_t lock; - rb_nativethread_id_t owner; - size_t count; -}; - -static void -ossl_lock_init(struct CRYPTO_dynlock_value *l) -{ - rb_nativethread_lock_initialize(&l->lock); - l->count = 0; -} - -static void -ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l) -{ - if (mode & CRYPTO_LOCK) { - /* TODO: rb_nativethread_id_t is not necessarily compared with ==. */ - rb_nativethread_id_t tid = rb_nativethread_self(); - if (l->count && l->owner == tid) { - l->count++; - return; - } - rb_nativethread_lock_lock(&l->lock); - l->owner = tid; - l->count = 1; - } else { - if (!--l->count) - rb_nativethread_lock_unlock(&l->lock); - } -} - -static struct CRYPTO_dynlock_value * -ossl_dyn_create_callback(const char *file, int line) -{ - /* Do not use xmalloc() here, since it may raise NoMemoryError */ - struct CRYPTO_dynlock_value *dynlock = - OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value)); - if (dynlock) - ossl_lock_init(dynlock); - return dynlock; -} - -static void -ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) -{ - ossl_lock_unlock(mode, l); -} - -static void -ossl_dyn_destroy_callback(struct CRYPTO_dynlock_value *l, const char *file, int line) -{ - rb_nativethread_lock_destroy(&l->lock); - OPENSSL_free(l); -} - -static void ossl_threadid_func(CRYPTO_THREADID *id) -{ - /* register native thread id */ - CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self()); -} - -static struct CRYPTO_dynlock_value *ossl_locks; - -static void -ossl_lock_callback(int mode, int type, const char *file, int line) -{ - ossl_lock_unlock(mode, &ossl_locks[type]); -} - -static void Init_ossl_locks(void) -{ - int i; - int num_locks = CRYPTO_num_locks(); - - ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks); - for (i = 0; i < num_locks; i++) - ossl_lock_init(&ossl_locks[i]); - - CRYPTO_THREADID_set_callback(ossl_threadid_func); - CRYPTO_set_locking_callback(ossl_lock_callback); - CRYPTO_set_dynlock_create_callback(ossl_dyn_create_callback); - CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback); - CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback); -} -#endif /* !HAVE_OPENSSL_110_THREADING_API */ - /* * call-seq: - * OpenSSL.fixed_length_secure_compare(string, string) -> boolean + * OpenSSL.fixed_length_secure_compare(string, string) -> true or false * * Constant time memory comparison for fixed length strings, such as results - * of HMAC calculations. + * of \HMAC calculations. * * Returns +true+ if the strings are identical, +false+ if they are of the same - * length but not identical. If the length is different, +ArgumentError+ is + * length but not identical. If the length is different, ArgumentError is * raised. */ static VALUE @@ -640,13 +533,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) } switch (CRYPTO_memcmp(p1, p2, len1)) { - case 0: return Qtrue; - default: return Qfalse; + case 0: return Qtrue; + default: return Qfalse; } } /* - * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the + * OpenSSL provides \SSL, TLS and general purpose cryptography. It wraps the * OpenSSL[https://www.openssl.org/] library. * * = Examples @@ -667,23 +560,21 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * key = OpenSSL::PKey::RSA.new 2048 * - * open 'private_key.pem', 'w' do |io| io.write key.to_pem end - * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end + * File.write 'private_key.pem', key.private_to_pem + * File.write 'public_key.pem', key.public_to_pem * * === Exporting a Key * * Keys saved to disk without encryption are not secure as anyone who gets * ahold of the key may use it unless it is encrypted. In order to securely - * export a key you may export it with a pass phrase. + * export a key you may export it with a password. * * cipher = OpenSSL::Cipher.new 'aes-256-cbc' - * pass_phrase = 'my secure pass phrase goes here' + * password = 'my secure password goes here' * - * key_secure = key.export cipher, pass_phrase + * key_secure = key.private_to_pem cipher, password * - * open 'private.secure.pem', 'w' do |io| - * io.write key_secure - * end + * File.write 'private.secure.pem', key_secure * * OpenSSL::Cipher.ciphers returns a list of available ciphers. * @@ -703,13 +594,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * === Loading an Encrypted Key * - * OpenSSL will prompt you for your pass phrase when loading an encrypted key. - * If you will not be able to type in the pass phrase you may provide it when + * \OpenSSL will prompt you for your password when loading an encrypted key. + * If you will not be able to type in the password you may provide it when * loading the key: * * key4_pem = File.read 'private.secure.pem' - * pass_phrase = 'my secure pass phrase goes here' - * key4 = OpenSSL::PKey.read key4_pem, pass_phrase + * password = 'my secure password goes here' + * key4 = OpenSSL::PKey.read key4_pem, password * * == RSA Encryption * @@ -766,7 +657,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * == PBKDF2 Password-based Encryption * - * If supported by the underlying OpenSSL version used, Password-based + * If supported by the underlying \OpenSSL version used, Password-based * Encryption should use the features of PKCS5. If not supported or if * required by legacy applications, the older, less secure methods specified * in RFC 2898 are also supported (see below). @@ -825,46 +716,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * decrypted = cipher.update encrypted * decrypted << cipher.final * - * == PKCS #5 Password-based Encryption - * - * PKCS #5 is a password-based encryption standard documented at - * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or - * passphrase to be used to create a secure encryption key. If possible, PBKDF2 - * as described above should be used if the circumstances allow it. - * - * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption - * key. - * - * pass_phrase = 'my secure pass phrase goes here' - * salt = '8 octets' - * - * === Encryption - * - * First set up the cipher for encryption - * - * encryptor = OpenSSL::Cipher.new 'aes-256-cbc' - * encryptor.encrypt - * encryptor.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to encrypt through - * - * encrypted = encryptor.update 'top secret document' - * encrypted << encryptor.final - * - * === Decryption - * - * Use a new Cipher instance set up for decryption - * - * decryptor = OpenSSL::Cipher.new 'aes-256-cbc' - * decryptor.decrypt - * decryptor.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to decrypt through - * - * plain = decryptor.update encrypted - * plain << decryptor.final - * - * == X509 Certificates + * == \X509 Certificates * * === Creating a Certificate * @@ -901,7 +753,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * extension_factory.create_extension('subjectKeyIdentifier', 'hash') * * The list of supported extensions (and in some cases their possible values) - * can be derived from the "objects.h" file in the OpenSSL source code. + * can be derived from the "objects.h" file in the \OpenSSL source code. * * === Signing a Certificate * @@ -941,12 +793,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * not readable by other users. * * ca_key = OpenSSL::PKey::RSA.new 2048 - * pass_phrase = 'my secure pass phrase goes here' + * password = 'my secure password goes here' * - * cipher = OpenSSL::Cipher.new 'aes-256-cbc' + * cipher = 'aes-256-cbc' * * open 'ca_key.pem', 'w', 0400 do |io| - * io.write ca_key.export(cipher, pass_phrase) + * io.write ca_key.private_to_pem(cipher, password) * end * * === CA Certificate @@ -1055,23 +907,23 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * io.write csr_cert.to_pem * end * - * == SSL and TLS Connections + * == \SSL and TLS Connections * - * Using our created key and certificate we can create an SSL or TLS connection. - * An SSLContext is used to set up an SSL session. + * Using our created key and certificate we can create an \SSL or TLS + * connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session. * * context = OpenSSL::SSL::SSLContext.new * - * === SSL Server + * === \SSL Server * - * An SSL server requires the certificate and private key to communicate + * An \SSL server requires the certificate and private key to communicate * securely with its clients: * * context.cert = cert * context.key = key * - * Then create an SSLServer with a TCP server socket and the context. Use the - * SSLServer like an ordinary TCP server. + * Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the + * context. Use the SSLServer like an ordinary TCP server. * * require 'socket' * @@ -1090,14 +942,15 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * ssl_connection.close * end * - * === SSL client + * === \SSL client * - * An SSL client is created with a TCP socket and the context. - * SSLSocket#connect must be called to initiate the SSL handshake and start - * encryption. A key and certificate are not required for the client socket. + * An \SSL client is created with a TCP socket and the context. + * OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake + * and start encryption. A key and certificate are not required for the client + * socket. * - * Note that SSLSocket#close doesn't close the underlying socket by default. Set - * SSLSocket#sync_close to true if you want. + * Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket + * by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want. * * require 'socket' * @@ -1113,7 +966,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * === Peer Verification * - * An unverified SSL connection does not provide much security. For enhanced + * An unverified \SSL connection does not provide much security. For enhanced * security the client or server can verify the certificate of its peer. * * The client can be modified to verify the server's certificate against the @@ -1153,63 +1006,109 @@ Init_openssl(void) /* * Init all digests, ciphers */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 if (!OPENSSL_init_ssl(0, NULL)) rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl"); -#else - OpenSSL_add_ssl_algorithms(); - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); -#endif /* * Init main module */ - mOSSL = rb_define_module("OpenSSL"); rb_global_variable(&mOSSL); + mOSSL = rb_define_module("OpenSSL"); rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2); /* - * Version of OpenSSL the ruby OpenSSL extension was built with + * \OpenSSL library version string used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. */ - rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT)); + rb_define_const(mOSSL, "OPENSSL_VERSION", + rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT))); /* - * Version of OpenSSL the ruby OpenSSL extension is running with + * \OpenSSL library version string currently used at runtime. */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 - rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION))); -#else - rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION))); -#endif + rb_define_const( + mOSSL, + "OPENSSL_LIBRARY_VERSION", + rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION))) + ); /* - * Version number of OpenSSL the ruby OpenSSL extension was built with - * (base 16) + * \OpenSSL library version number used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. + * + * The version number is encoded into a single integer value. The number + * follows the format: + * + * [\OpenSSL 3.0.0 or later] + * <tt>0xMNN00PP0</tt> (major minor 00 patch 0) + * [\OpenSSL 1.1.1 or earlier] + * <tt>0xMNNFFPPS</tt> (major minor fix patch status) + * [LibreSSL] + * <tt>0x20000000</tt> (a fixed value) + * + * See also the man page OPENSSL_VERSION_NUMBER(3). */ rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER)); +#if defined(LIBRESSL_VERSION_NUMBER) + /* + * LibreSSL library version number used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. + * + * This constant is only defined if the extension was compiled against + * LibreSSL. The number follows the format: + * <tt>0xMNNFF00f</tt> (major minor fix 00 status). + * + * See also the man page LIBRESSL_VERSION_NUMBER(3). + */ + rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER)); +#endif + /* - * Boolean indicating whether OpenSSL is FIPS-capable or not + * Boolean indicating whether the \OpenSSL library is FIPS-capable or not. + * Always <tt>true</tt> for \OpenSSL 3.0 and later. + * + * This is obsolete and will be removed in the future. + * See also OpenSSL.fips_mode. */ rb_define_const(mOSSL, "OPENSSL_FIPS", -#ifdef OPENSSL_FIPS - Qtrue +/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */ +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + Qtrue +#elif defined(OPENSSL_FIPS) + Qtrue +#elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time. + FIPS_mode() ? Qtrue : Qfalse #else - Qfalse + Qfalse #endif - ); + ); rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0); rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1); + rb_global_variable(&eOSSLError); /* - * Generic error, - * common for all classes under OpenSSL module + * Generic error class for OpenSSL. All error classes in this library + * inherit from this class. + * + * This class indicates that an error was reported by the underlying + * \OpenSSL library. */ - eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError); - rb_global_variable(&eOSSLError); + eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); + /* + * \OpenSSL error queue entries captured at the time the exception was + * raised. The same information is printed to stderr if OpenSSL.debug is + * set to +true+. + * + * This is an array of zero or more strings, ordered from the oldest to the + * newest. The format of the strings is not stable and may vary across + * versions of \OpenSSL or versions of this Ruby extension. + * + * See also the man page ERR_get_error(3). + */ + rb_attr(eOSSLError, rb_intern_const("errors"), 1, 0, 0); + rb_define_method(eOSSLError, "detailed_message", osslerror_detailed_message, -1); /* * Init debug core @@ -1225,67 +1124,27 @@ Init_openssl(void) * Get ID of to_der */ ossl_s_to_der = rb_intern("to_der"); - -#if !defined(HAVE_OPENSSL_110_THREADING_API) - Init_ossl_locks(); -#endif + id_i_errors = rb_intern("@errors"); /* * Init components */ + Init_ossl_asn1(); Init_ossl_bn(); Init_ossl_cipher(); Init_ossl_config(); Init_ossl_digest(); + Init_ossl_engine(); Init_ossl_hmac(); + Init_ossl_kdf(); Init_ossl_ns_spki(); + Init_ossl_ocsp(); Init_ossl_pkcs12(); Init_ossl_pkcs7(); Init_ossl_pkey(); + Init_ossl_provider(); Init_ossl_rand(); Init_ossl_ssl(); -#ifndef OPENSSL_NO_TS Init_ossl_ts(); -#endif Init_ossl_x509(); - Init_ossl_ocsp(); - Init_ossl_engine(); - Init_ossl_asn1(); - Init_ossl_kdf(); - -#if defined(OSSL_DEBUG) - /* - * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug - */ -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \ - defined(CRYPTO_malloc_debug_init)) - rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0); - rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0); - -#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */ - CRYPTO_malloc_debug_init(); -#endif - -#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */ - CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */ - { - int i; - /* - * See crypto/ex_data.c; call def_get_class() immediately to avoid - * allocations. 15 is the maximum number that is used as the class index - * in OpenSSL 1.0.2. - */ - for (i = 0; i <= 15; i++) { - if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0) - rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for " - "class index %d failed", i); - } - } -#endif -#endif -#endif } diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index be9dcbdff1..0b479a7200 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_H_) #define _OSSL_H_ @@ -17,7 +17,14 @@ #include <errno.h> #include <ruby/io.h> #include <ruby/thread.h> +#ifdef HAVE_RUBY_RACTOR_H +#include <ruby/ractor.h> +#else +#define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + #include <openssl/opensslv.h> + #include <openssl/err.h> #include <openssl/asn1.h> #include <openssl/x509v3.h> @@ -30,9 +37,6 @@ #include <openssl/ts.h> #endif #include <openssl/crypto.h> -#if !defined(OPENSSL_NO_ENGINE) -# include <openssl/engine.h> -#endif #if !defined(OPENSSL_NO_OCSP) # include <openssl/ocsp.h> #endif @@ -41,6 +45,38 @@ #include <openssl/dsa.h> #include <openssl/evp.h> #include <openssl/dh.h> +#include "openssl_missing.h" + +#ifndef LIBRESSL_VERSION_NUMBER +# define OSSL_IS_LIBRESSL 0 +# define OSSL_OPENSSL_PREREQ(maj, min, pat) \ + (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) +# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 +#else +# define OSSL_IS_LIBRESSL 1 +# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 +# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ + (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_3_const const +#else +# define OSSL_3_const /* const */ +#endif + +#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_USE_ENGINE +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_USE_PROVIDER +# include <openssl/provider.h> +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_HAVE_IMMUTABLE_PKEY +#endif /* * Common Module @@ -56,10 +92,10 @@ extern VALUE eOSSLError; * CheckTypes */ #define OSSL_Check_Kind(obj, klass) do {\ - if (!rb_obj_is_kind_of((obj), (klass))) {\ - ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ - rb_obj_class(obj), (klass));\ - }\ + if (!rb_obj_is_kind_of((obj), (klass))) {\ + ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ + rb_obj_class(obj), (klass));\ + }\ } while (0) /* @@ -95,7 +131,7 @@ do{\ * Convert binary string to hex string. The caller is responsible for * ensuring out has (2 * len) bytes of capacity. */ -void ossl_bin2hex(unsigned char *in, char *out, size_t len); +void ossl_bin2hex(const unsigned char *in, char *out, size_t len); /* * Our default PEM callback @@ -137,44 +173,36 @@ VALUE ossl_to_der_if_possible(VALUE); */ extern VALUE dOSSL; -#if defined(HAVE_VA_ARGS_MACRO) #define OSSL_Debug(...) do { \ - if (dOSSL == Qtrue) { \ - fprintf(stderr, "OSSL_DEBUG: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \ - } \ + if (dOSSL == Qtrue) { \ + fprintf(stderr, "OSSL_DEBUG: "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \ + } \ } while (0) -#else -void ossl_debug(const char *, ...); -#define OSSL_Debug ossl_debug -#endif - /* * Include all parts */ -#include "openssl_missing.h" #include "ossl_asn1.h" #include "ossl_bio.h" #include "ossl_bn.h" #include "ossl_cipher.h" #include "ossl_config.h" #include "ossl_digest.h" +#include "ossl_engine.h" #include "ossl_hmac.h" +#include "ossl_kdf.h" #include "ossl_ns_spki.h" #include "ossl_ocsp.h" #include "ossl_pkcs12.h" #include "ossl_pkcs7.h" #include "ossl_pkey.h" +#include "ossl_provider.h" #include "ossl_rand.h" #include "ossl_ssl.h" -#ifndef OPENSSL_NO_TS - #include "ossl_ts.h" -#endif +#include "ossl_ts.h" #include "ossl_x509.h" -#include "ossl_engine.h" -#include "ossl_kdf.h" void Init_openssl(void); diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index a61d3eefb1..71a87f0463 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -5,68 +5,85 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, - int depth, int yield, long *num_read); -static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); +/********/ +/* + * ASN1 module + */ +#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) +#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) +#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) +#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) +#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) + +#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) +#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) +#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) +#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) +#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) + +VALUE mASN1; +static VALUE eASN1Error; + +VALUE cASN1Data; +static VALUE cASN1Primitive; +static VALUE cASN1Constructive; + +static VALUE cASN1EndOfContent; +static VALUE cASN1Boolean; /* BOOLEAN */ +static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ +static VALUE cASN1BitString; /* BIT STRING */ +static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ +static VALUE cASN1NumericString, cASN1PrintableString; +static VALUE cASN1T61String, cASN1VideotexString; +static VALUE cASN1IA5String, cASN1GraphicString; +static VALUE cASN1ISO64String, cASN1GeneralString; +static VALUE cASN1UniversalString, cASN1BMPString; +static VALUE cASN1Null; /* NULL */ +static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ +static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ +static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ + +static VALUE sym_IMPLICIT, sym_EXPLICIT; +static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE; +static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS; +static ID id_each; /* * DATE conversion */ +static VALUE +time_utc_new(VALUE args) +{ + return rb_funcallv(rb_cTime, rb_intern("utc"), 6, (VALUE *)args); +} + +static VALUE +time_utc_new_rescue(VALUE args, VALUE exc) +{ + rb_raise(eASN1Error, "invalid time"); +} + VALUE asn1time_to_time(const ASN1_TIME *time) { struct tm tm; - VALUE argv[6]; - int count; - - memset(&tm, 0, sizeof(struct tm)); - - switch (time->type) { - case V_ASN1_UTCTIME: - count = sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, - &tm.tm_sec); - - if (count == 5) { - tm.tm_sec = 0; - } else if (count != 6) { - ossl_raise(rb_eTypeError, "bad UTCTIME format: \"%s\"", - time->data); - } - if (tm.tm_year < 69) { - tm.tm_year += 2000; - } else { - tm.tm_year += 1900; - } - break; - case V_ASN1_GENERALIZEDTIME: - count = sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, - &tm.tm_sec); - if (count == 5) { - tm.tm_sec = 0; - } - else if (count != 6) { - ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"", - time->data); - } - break; - default: - rb_warning("unknown time format"); - return Qnil; - } - argv[0] = INT2NUM(tm.tm_year); - argv[1] = INT2NUM(tm.tm_mon); - argv[2] = INT2NUM(tm.tm_mday); - argv[3] = INT2NUM(tm.tm_hour); - argv[4] = INT2NUM(tm.tm_min); - argv[5] = INT2NUM(tm.tm_sec); - - return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); + if (!ASN1_TIME_to_tm(time, &tm)) + ossl_raise(eASN1Error, "ASN1_TIME_to_tm"); + + VALUE args[] = { + INT2NUM(tm.tm_year + 1900), + INT2NUM(tm.tm_mon + 1), + INT2NUM(tm.tm_mday), + INT2NUM(tm.tm_hour), + INT2NUM(tm.tm_min), + INT2NUM(tm.tm_sec), + }; + return rb_rescue2(time_utc_new, (VALUE)args, time_utc_new_rescue, Qnil, + rb_eArgError, 0); } static VALUE @@ -81,13 +98,13 @@ ossl_time_split(VALUE time, time_t *sec, int *days) VALUE num = rb_Integer(time); if (FIXNUM_P(num)) { - time_t t = FIX2LONG(num); - *sec = t % 86400; - *days = rb_long2int(t / 86400); + time_t t = FIX2LONG(num); + *sec = t % 86400; + *days = rb_long2int(t / 86400); } else { - *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400))); - *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400))); + *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400))); + *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400))); } } @@ -97,7 +114,8 @@ ossl_time_split(VALUE time, time_t *sec, int *days) VALUE asn1str_to_str(const ASN1_STRING *str) { - return rb_str_new((const char *)str->data, str->length); + return rb_str_new((const char *)ASN1_STRING_get0_data(str), + ASN1_STRING_length(str)); } /* @@ -110,16 +128,15 @@ asn1integer_to_num(const ASN1_INTEGER *ai) VALUE num; if (!ai) { - ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); + ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); } - if (ai->type == V_ASN1_ENUMERATED) - /* const_cast: workaround for old OpenSSL */ - bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL); + if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED) + bn = ASN1_ENUMERATED_to_BN(ai, NULL); else - bn = ASN1_INTEGER_to_BN(ai, NULL); + bn = ASN1_INTEGER_to_BN(ai, NULL); if (!bn) - ossl_raise(eOSSLError, NULL); + ossl_raise(eOSSLError, NULL); num = ossl_bn_new(bn); BN_free(bn); @@ -132,12 +149,12 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) BIGNUM *bn; if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Integer"); + ossl_raise(rb_eTypeError, "Can't convert nil into Integer"); bn = GetBNPtr(obj); if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) - ossl_raise(eOSSLError, NULL); + ossl_raise(eOSSLError, NULL); return ai; } @@ -148,48 +165,47 @@ asn1integer_to_num_i(VALUE arg) return asn1integer_to_num((ASN1_INTEGER *)arg); } -/********/ /* - * ASN1 module + * ASN1_OBJECT conversions */ -#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) -#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) -#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) -#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) -#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) - -#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) -#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) -#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) -#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) -#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) +VALUE +ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj) +{ + VALUE str; + int len; -VALUE mASN1; -VALUE eASN1Error; + str = rb_usascii_str_new(NULL, 127); + len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1); + if (len <= 0 || len == INT_MAX) + ossl_raise(eOSSLError, "OBJ_obj2txt"); + if (len > RSTRING_LEN(str)) { + /* +1 is for the \0 terminator added by OBJ_obj2txt() */ + rb_str_resize(str, len + 1); + len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1); + if (len <= 0) + ossl_raise(eOSSLError, "OBJ_obj2txt"); + } + rb_str_set_len(str, len); + return str; +} -VALUE cASN1Data; -VALUE cASN1Primitive; -VALUE cASN1Constructive; - -VALUE cASN1EndOfContent; -VALUE cASN1Boolean; /* BOOLEAN */ -VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ -VALUE cASN1BitString; /* BIT STRING */ -VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ -VALUE cASN1NumericString, cASN1PrintableString; -VALUE cASN1T61String, cASN1VideotexString; -VALUE cASN1IA5String, cASN1GraphicString; -VALUE cASN1ISO64String, cASN1GeneralString; -VALUE cASN1UniversalString, cASN1BMPString; -VALUE cASN1Null; /* NULL */ -VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ -VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ -VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ +VALUE +ossl_asn1obj_to_string(const ASN1_OBJECT *obj) +{ + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) + return rb_str_new_cstr(OBJ_nid2sn(nid)); + return ossl_asn1obj_to_string_oid(obj); +} -static VALUE sym_IMPLICIT, sym_EXPLICIT; -static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE; -static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS; -static ID id_each; +VALUE +ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj) +{ + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) + return rb_str_new_cstr(OBJ_nid2ln(nid)); + return ossl_asn1obj_to_string_oid(obj); +} /* * Ruby to ASN1 converters @@ -198,9 +214,9 @@ static ASN1_BOOLEAN obj_to_asn1bool(VALUE obj) { if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Boolean"); + ossl_raise(rb_eTypeError, "Can't convert nil into Boolean"); - return RTEST(obj) ? 0xff : 0x0; + return RTEST(obj) ? 0xff : 0x0; } static ASN1_INTEGER* @@ -215,11 +231,11 @@ obj_to_asn1bstr(VALUE obj, long unused_bits) ASN1_BIT_STRING *bstr; if (unused_bits < 0 || unused_bits > 7) - ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\ - "the range 0 to 7"); + ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\ + "the range 0 to 7"); StringValue(obj); if(!(bstr = ASN1_BIT_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj)); bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits; @@ -234,7 +250,7 @@ obj_to_asn1str(VALUE obj) StringValue(obj); if(!(str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj)); return str; @@ -246,15 +262,15 @@ obj_to_asn1null(VALUE obj) ASN1_NULL *null; if(!NIL_P(obj)) - ossl_raise(eASN1Error, "nil expected"); + ossl_raise(eASN1Error, "nil expected"); if(!(null = ASN1_NULL_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return null; } -static ASN1_OBJECT* -obj_to_asn1obj(VALUE obj) +ASN1_OBJECT * +ossl_to_asn1obj(VALUE obj) { ASN1_OBJECT *a1obj; @@ -276,7 +292,7 @@ obj_to_asn1utime(VALUE time) ossl_time_split(time, &sec, &off_days); if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return t; } @@ -291,7 +307,7 @@ obj_to_asn1gtime(VALUE time) ossl_time_split(time, &sec, &off_days); if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return t; } @@ -304,7 +320,7 @@ obj_to_asn1derstr(VALUE obj) str = ossl_to_der(obj); if(!(a1str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str)); return a1str; @@ -319,9 +335,9 @@ decode_bool(unsigned char* der, long length) const unsigned char *p = der; if (length != 3) - ossl_raise(eASN1Error, "invalid length for BOOLEAN"); + ossl_raise(eASN1Error, "invalid length for BOOLEAN"); if (p[0] != 1 || p[1] != 1) - ossl_raise(eASN1Error, "invalid BOOLEAN"); + ossl_raise(eASN1Error, "invalid BOOLEAN"); return p[2] ? Qtrue : Qfalse; } @@ -336,9 +352,9 @@ decode_int(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ret = rb_protect(asn1integer_to_num_i, - (VALUE)ai, &status); + (VALUE)ai, &status); ASN1_INTEGER_free(ai); if(status) rb_jump_tag(status); @@ -355,11 +371,11 @@ decode_bstr(unsigned char* der, long length, long *unused_bits) p = der; if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); len = bstr->length; *unused_bits = 0; if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) - *unused_bits = bstr->flags & 0x07; + *unused_bits = bstr->flags & 0x07; ret = rb_str_new((const char *)bstr->data, len); ASN1_BIT_STRING_free(bstr); @@ -376,9 +392,9 @@ decode_enum(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ret = rb_protect(asn1integer_to_num_i, - (VALUE)ai, &status); + (VALUE)ai, &status); ASN1_ENUMERATED_free(ai); if(status) rb_jump_tag(status); @@ -393,38 +409,33 @@ decode_null(unsigned char* der, long length) p = der; if(!(null = d2i_ASN1_NULL(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_NULL_free(null); return Qnil; } +VALUE +asn1obj_to_string_i(VALUE arg) +{ + return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg); +} + static VALUE decode_obj(unsigned char* der, long length) { ASN1_OBJECT *obj; const unsigned char *p; VALUE ret; - int nid; - BIO *bio; + int state; p = der; - if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - if((nid = OBJ_obj2nid(obj)) != NID_undef){ - ASN1_OBJECT_free(obj); - ret = rb_str_new2(OBJ_nid2sn(nid)); - } - else{ - if(!(bio = BIO_new(BIO_s_mem()))){ - ASN1_OBJECT_free(obj); - ossl_raise(eASN1Error, NULL); - } - i2a_ASN1_OBJECT(bio, obj); - ASN1_OBJECT_free(obj); - ret = ossl_membio2str(bio); - } - + if (!(obj = d2i_ASN1_OBJECT(NULL, &p, length))) + ossl_raise(eASN1Error, "d2i_ASN1_OBJECT"); + ret = rb_protect(asn1obj_to_string_i, (VALUE)obj, &state); + ASN1_OBJECT_free(obj); + if (state) + rb_jump_tag(state); return ret; } @@ -438,9 +449,9 @@ decode_time(unsigned char* der, long length) p = der; if(!(time = d2i_ASN1_TIME(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ret = rb_protect(asn1time_to_time_i, - (VALUE)time, &status); + (VALUE)time, &status); ASN1_TIME_free(time); if(status) rb_jump_tag(status); @@ -451,7 +462,7 @@ static VALUE decode_eoc(unsigned char *der, long length) { if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00)) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return rb_str_new("", 0); } @@ -503,74 +514,75 @@ static VALUE class_tag_map; static int ossl_asn1_default_tag(VALUE obj); -ASN1_TYPE* +static ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj) { ASN1_TYPE *ret; VALUE value, rflag; void *ptr; - void (*free_func)(); + typedef void free_func_type(void *); + free_func_type *free_func; int tag; tag = ossl_asn1_default_tag(obj); value = ossl_asn1_get_value(obj); switch(tag){ - case V_ASN1_BOOLEAN: - ptr = (void*)(VALUE)obj_to_asn1bool(value); - free_func = NULL; - break; - case V_ASN1_INTEGER: /* FALLTHROUGH */ - case V_ASN1_ENUMERATED: - ptr = obj_to_asn1int(value); - free_func = ASN1_INTEGER_free; - break; - case V_ASN1_BIT_STRING: + case V_ASN1_BOOLEAN: + ptr = (void*)(VALUE)obj_to_asn1bool(value); + free_func = NULL; + break; + case V_ASN1_INTEGER: /* FALLTHROUGH */ + case V_ASN1_ENUMERATED: + ptr = obj_to_asn1int(value); + free_func = (free_func_type *)ASN1_INTEGER_free; + break; + case V_ASN1_BIT_STRING: rflag = rb_attr_get(obj, sivUNUSED_BITS); - ptr = obj_to_asn1bstr(value, NUM2INT(rflag)); - free_func = ASN1_BIT_STRING_free; - break; - case V_ASN1_NULL: - ptr = obj_to_asn1null(value); - free_func = ASN1_NULL_free; - break; - case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ - case V_ASN1_UTF8STRING: /* FALLTHROUGH */ - case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ - case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ - case V_ASN1_T61STRING: /* FALLTHROUGH */ - case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ - case V_ASN1_IA5STRING: /* FALLTHROUGH */ - case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ - case V_ASN1_ISO64STRING: /* FALLTHROUGH */ - case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ - case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ - case V_ASN1_BMPSTRING: - ptr = obj_to_asn1str(value); - free_func = ASN1_STRING_free; - break; - case V_ASN1_OBJECT: - ptr = obj_to_asn1obj(value); - free_func = ASN1_OBJECT_free; - break; - case V_ASN1_UTCTIME: - ptr = obj_to_asn1utime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_GENERALIZEDTIME: - ptr = obj_to_asn1gtime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_SET: /* FALLTHROUGH */ - case V_ASN1_SEQUENCE: - ptr = obj_to_asn1derstr(obj); - free_func = ASN1_STRING_free; - break; - default: - ossl_raise(eASN1Error, "unsupported ASN.1 type"); + ptr = obj_to_asn1bstr(value, NUM2INT(rflag)); + free_func = (free_func_type *)ASN1_BIT_STRING_free; + break; + case V_ASN1_NULL: + ptr = obj_to_asn1null(value); + free_func = (free_func_type *)ASN1_NULL_free; + break; + case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ + case V_ASN1_UTF8STRING: /* FALLTHROUGH */ + case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ + case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ + case V_ASN1_T61STRING: /* FALLTHROUGH */ + case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ + case V_ASN1_IA5STRING: /* FALLTHROUGH */ + case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ + case V_ASN1_ISO64STRING: /* FALLTHROUGH */ + case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ + case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ + case V_ASN1_BMPSTRING: + ptr = obj_to_asn1str(value); + free_func = (free_func_type *)ASN1_STRING_free; + break; + case V_ASN1_OBJECT: + ptr = ossl_to_asn1obj(value); + free_func = (free_func_type *)ASN1_OBJECT_free; + break; + case V_ASN1_UTCTIME: + ptr = obj_to_asn1utime(value); + free_func = (free_func_type *)ASN1_TIME_free; + break; + case V_ASN1_GENERALIZEDTIME: + ptr = obj_to_asn1gtime(value); + free_func = (free_func_type *)ASN1_TIME_free; + break; + case V_ASN1_SET: /* FALLTHROUGH */ + case V_ASN1_SEQUENCE: + ptr = obj_to_asn1derstr(obj); + free_func = (free_func_type *)ASN1_STRING_free; + break; + default: + ossl_raise(eASN1Error, "unsupported ASN.1 type"); } if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){ - if(free_func) free_func(ptr); - ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); + if(free_func) free_func(ptr); + ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); } memset(ret, 0, sizeof(ASN1_TYPE)); ASN1_TYPE_set(ret, tag, ptr); @@ -585,10 +597,10 @@ ossl_asn1_default_tag(VALUE obj) tmp_class = CLASS_OF(obj); while (!NIL_P(tmp_class)) { - tag = rb_hash_lookup(class_tag_map, tmp_class); - if (tag != Qnil) - return NUM2INT(tag); - tmp_class = rb_class_superclass(tmp_class); + tag = rb_hash_lookup(class_tag_map, tmp_class); + if (tag != Qnil) + return NUM2INT(tag); + tmp_class = rb_class_superclass(tmp_class); } return -1; @@ -601,7 +613,7 @@ ossl_asn1_tag(VALUE obj) tag = ossl_asn1_get_tag(obj); if(NIL_P(tag)) - ossl_raise(eASN1Error, "tag number not specified"); + ossl_raise(eASN1Error, "tag number not specified"); return NUM2INT(tag); } @@ -613,28 +625,28 @@ ossl_asn1_tag_class(VALUE obj) s = ossl_asn1_get_tag_class(obj); if (NIL_P(s) || s == sym_UNIVERSAL) - return V_ASN1_UNIVERSAL; + return V_ASN1_UNIVERSAL; else if (s == sym_APPLICATION) - return V_ASN1_APPLICATION; + return V_ASN1_APPLICATION; else if (s == sym_CONTEXT_SPECIFIC) - return V_ASN1_CONTEXT_SPECIFIC; + return V_ASN1_CONTEXT_SPECIFIC; else if (s == sym_PRIVATE) - return V_ASN1_PRIVATE; + return V_ASN1_PRIVATE; else - ossl_raise(eASN1Error, "invalid tag class"); + ossl_raise(eASN1Error, "invalid tag class"); } static VALUE ossl_asn1_class2sym(int tc) { if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - return sym_PRIVATE; + return sym_PRIVATE; else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - return sym_CONTEXT_SPECIFIC; + return sym_CONTEXT_SPECIFIC; else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - return sym_APPLICATION; + return sym_APPLICATION; else - return sym_UNIVERSAL; + return sym_UNIVERSAL; } /* @@ -657,7 +669,7 @@ static VALUE ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class) { if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); + ossl_raise(eASN1Error, "invalid tag class"); ossl_asn1_set_tag(self, tag); ossl_asn1_set_value(self, value); ossl_asn1_set_tag_class(self, tag_class); @@ -679,35 +691,35 @@ to_der_internal(VALUE self, int constructed, int indef_len, VALUE body) body_length = RSTRING_LENINT(body); if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) { - int inner_length, e_encoding = indef_len ? 2 : 1; - - if (default_tag_number == -1) - ossl_raise(eASN1Error, "explicit tagging of unknown tag"); - - inner_length = ASN1_object_size(encoding, body_length, default_tag_number); - total_length = ASN1_object_size(e_encoding, inner_length, tag_number); - str = rb_str_new(NULL, total_length); - p = (unsigned char *)RSTRING_PTR(str); - /* Put explicit tag */ - ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class); - /* Append inner object */ - ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL); - memcpy(p, RSTRING_PTR(body), body_length); - p += body_length; - if (indef_len) { - ASN1_put_eoc(&p); /* For inner object */ - ASN1_put_eoc(&p); /* For wrapper object */ - } + int inner_length, e_encoding = indef_len ? 2 : 1; + + if (default_tag_number == -1) + ossl_raise(eASN1Error, "explicit tagging of unknown tag"); + + inner_length = ASN1_object_size(encoding, body_length, default_tag_number); + total_length = ASN1_object_size(e_encoding, inner_length, tag_number); + str = rb_str_new(NULL, total_length); + p = (unsigned char *)RSTRING_PTR(str); + /* Put explicit tag */ + ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class); + /* Append inner object */ + ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL); + memcpy(p, RSTRING_PTR(body), body_length); + p += body_length; + if (indef_len) { + ASN1_put_eoc(&p); /* For inner object */ + ASN1_put_eoc(&p); /* For wrapper object */ + } } else { - total_length = ASN1_object_size(encoding, body_length, tag_number); - str = rb_str_new(NULL, total_length); - p = (unsigned char *)RSTRING_PTR(str); - ASN1_put_object(&p, encoding, body_length, tag_number, tag_class); - memcpy(p, RSTRING_PTR(body), body_length); - p += body_length; - if (indef_len) - ASN1_put_eoc(&p); + total_length = ASN1_object_size(encoding, body_length, tag_number); + str = rb_str_new(NULL, total_length); + p = (unsigned char *)RSTRING_PTR(str); + ASN1_put_object(&p, encoding, body_length, tag_number, tag_class); + memcpy(p, RSTRING_PTR(body), body_length); + p += body_length; + if (indef_len) + ASN1_put_eoc(&p); } assert(p - (unsigned char *)RSTRING_PTR(str) == total_length); return str; @@ -730,18 +742,22 @@ ossl_asn1data_to_der(VALUE self) VALUE value = ossl_asn1_get_value(self); if (rb_obj_is_kind_of(value, rb_cArray)) - return ossl_asn1cons_to_der(self); + return ossl_asn1cons_to_der(self); else { - if (RTEST(ossl_asn1_get_indefinite_length(self))) - ossl_raise(eASN1Error, "indefinite length form cannot be used " \ - "with primitive encoding"); - return ossl_asn1prim_to_der(self); + if (RTEST(ossl_asn1_get_indefinite_length(self))) + ossl_raise(eASN1Error, "indefinite length form cannot be used " \ + "with primitive encoding"); + return ossl_asn1prim_to_der(self); } } +static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); +static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, + int depth, int yield, long *num_read); + static VALUE int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, - VALUE tc, long *num_read) + VALUE tc, long *num_read) { VALUE value, asn1data; unsigned char *p; @@ -750,64 +766,64 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, p = *pp; if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) { - switch(tag){ - case V_ASN1_EOC: - value = decode_eoc(p, hlen+length); - break; - case V_ASN1_BOOLEAN: - value = decode_bool(p, hlen+length); - break; - case V_ASN1_INTEGER: - value = decode_int(p, hlen+length); - break; - case V_ASN1_BIT_STRING: - value = decode_bstr(p, hlen+length, &flag); - break; - case V_ASN1_NULL: - value = decode_null(p, hlen+length); - break; - case V_ASN1_ENUMERATED: - value = decode_enum(p, hlen+length); - break; - case V_ASN1_OBJECT: - value = decode_obj(p, hlen+length); - break; - case V_ASN1_UTCTIME: /* FALLTHROUGH */ - case V_ASN1_GENERALIZEDTIME: - value = decode_time(p, hlen+length); - break; - default: - /* use original value */ - p += hlen; - value = rb_str_new((const char *)p, length); - break; - } + switch(tag){ + case V_ASN1_EOC: + value = decode_eoc(p, hlen+length); + break; + case V_ASN1_BOOLEAN: + value = decode_bool(p, hlen+length); + break; + case V_ASN1_INTEGER: + value = decode_int(p, hlen+length); + break; + case V_ASN1_BIT_STRING: + value = decode_bstr(p, hlen+length, &flag); + break; + case V_ASN1_NULL: + value = decode_null(p, hlen+length); + break; + case V_ASN1_ENUMERATED: + value = decode_enum(p, hlen+length); + break; + case V_ASN1_OBJECT: + value = decode_obj(p, hlen+length); + break; + case V_ASN1_UTCTIME: /* FALLTHROUGH */ + case V_ASN1_GENERALIZEDTIME: + value = decode_time(p, hlen+length); + break; + default: + /* use original value */ + p += hlen; + value = rb_str_new((const char *)p, length); + break; + } } else { - p += hlen; - value = rb_str_new((const char *)p, length); + p += hlen; + value = rb_str_new((const char *)p, length); } *pp += hlen + length; *num_read = hlen + length; if (tc == sym_UNIVERSAL && - tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { - VALUE klass = *ossl_asn1_info[tag].klass; - VALUE args[4]; - args[0] = value; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - asn1data = rb_obj_alloc(klass); - ossl_asn1_initialize(4, args, asn1data); - if(tag == V_ASN1_BIT_STRING){ - rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); - } + tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { + VALUE klass = *ossl_asn1_info[tag].klass; + VALUE args[4]; + args[0] = value; + args[1] = INT2NUM(tag); + args[2] = Qnil; + args[3] = tc; + asn1data = rb_obj_alloc(klass); + ossl_asn1_initialize(4, args, asn1data); + if(tag == V_ASN1_BIT_STRING){ + rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); + } } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc); + asn1data = rb_obj_alloc(cASN1Data); + ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc); } return asn1data; @@ -815,8 +831,8 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, static VALUE int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, - long *offset, int depth, int yield, int j, - int tag, VALUE tc, long *num_read) + long *offset, int depth, int yield, int j, + int tag, VALUE tc, long *num_read) { VALUE value, asn1data, ary; int indefinite; @@ -827,40 +843,42 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, available_len = indefinite ? max_len : length; while (available_len > 0) { - long inner_read = 0; - value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); - *num_read += inner_read; - available_len -= inner_read; - - if (indefinite && - ossl_asn1_tag(value) == V_ASN1_EOC && - ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) { - break; - } - rb_ary_push(ary, value); + long inner_read = 0; + value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); + *num_read += inner_read; + available_len -= inner_read; + + if (indefinite) { + if (ossl_asn1_tag(value) == V_ASN1_EOC && + ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) + break; + if (available_len == 0) + ossl_raise(eASN1Error, "EOC missing in indefinite length encoding"); + } + rb_ary_push(ary, value); } if (tc == sym_UNIVERSAL) { - VALUE args[4]; - if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET) - asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass); - else - asn1data = rb_obj_alloc(cASN1Constructive); - args[0] = ary; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - ossl_asn1_initialize(4, args, asn1data); + VALUE args[4]; + if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET) + asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass); + else + asn1data = rb_obj_alloc(cASN1Constructive); + args[0] = ary; + args[1] = INT2NUM(tag); + args[2] = Qnil; + args[3] = tc; + ossl_asn1_initialize(4, args, asn1data); } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc); + asn1data = rb_obj_alloc(cASN1Data); + ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc); } if (indefinite) - ossl_asn1_set_indefinite_length(asn1data, Qtrue); + ossl_asn1_set_indefinite_length(asn1data, Qtrue); else - ossl_asn1_set_indefinite_length(asn1data, Qfalse); + ossl_asn1_set_indefinite_length(asn1data, Qfalse); *offset = off; return asn1data; @@ -868,7 +886,7 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, - int yield, long *num_read) + int yield, long *num_read) { unsigned char *start, *p; const unsigned char *p0; @@ -884,46 +902,46 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, if(j & 0x80) ossl_raise(eASN1Error, NULL); if(len > length) ossl_raise(eASN1Error, "value is too short"); if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - tag_class = sym_PRIVATE; + tag_class = sym_PRIVATE; else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - tag_class = sym_CONTEXT_SPECIFIC; + tag_class = sym_CONTEXT_SPECIFIC; else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - tag_class = sym_APPLICATION; + tag_class = sym_APPLICATION; else - tag_class = sym_UNIVERSAL; + tag_class = sym_UNIVERSAL; hlen = p - start; if(yield) { - VALUE arg = rb_ary_new(); - rb_ary_push(arg, LONG2NUM(depth)); - rb_ary_push(arg, LONG2NUM(*offset)); - rb_ary_push(arg, LONG2NUM(hlen)); - rb_ary_push(arg, LONG2NUM(len)); - rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse); - rb_ary_push(arg, ossl_asn1_class2sym(tc)); - rb_ary_push(arg, INT2NUM(tag)); - rb_yield(arg); + VALUE arg = rb_ary_new(); + rb_ary_push(arg, LONG2NUM(depth)); + rb_ary_push(arg, LONG2NUM(*offset)); + rb_ary_push(arg, LONG2NUM(hlen)); + rb_ary_push(arg, LONG2NUM(len)); + rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse); + rb_ary_push(arg, ossl_asn1_class2sym(tc)); + rb_ary_push(arg, INT2NUM(tag)); + rb_yield(arg); } if(j & V_ASN1_CONSTRUCTED) { - *pp += hlen; - off += hlen; - asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); - inner_read += hlen; + *pp += hlen; + off += hlen; + asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); + inner_read += hlen; } else { - if ((j & 0x01) && (len == 0)) - ossl_raise(eASN1Error, "indefinite length for primitive value"); - asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read); - off += hlen + len; + if ((j & 0x01) && (len == 0)) + ossl_raise(eASN1Error, "indefinite length for primitive value"); + asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read); + off += hlen + len; } if (num_read) - *num_read = inner_read; + *num_read = inner_read; if (len != 0 && inner_read != hlen + len) { - ossl_raise(eASN1Error, - "Type mismatch. Bytes read: %ld Bytes available: %ld", - inner_read, hlen + len); + ossl_raise(eASN1Error, + "Type mismatch. Bytes read: %ld Bytes available: %ld", + inner_read, hlen + len); } *offset = off; @@ -934,9 +952,9 @@ static void int_ossl_decode_sanity_check(long len, long read, long offset) { if (len != 0 && (read != len || offset != len)) { - ossl_raise(eASN1Error, - "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld", - read, len, offset); + ossl_raise(eASN1Error, + "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld", + read, len, offset); } } @@ -1036,11 +1054,11 @@ ossl_asn1_decode_all(VALUE self, VALUE obj) tmp_len = len; ary = rb_ary_new(); while (tmp_len > 0) { - long tmp_read = 0; - val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read); - rb_ary_push(ary, val); - read += tmp_read; - tmp_len -= tmp_read; + long tmp_read = 0; + val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read); + rb_ary_push(ary, val); + read += tmp_read; + tmp_len -= tmp_read; } RB_GC_GUARD(tmp); int_ossl_decode_sanity_check(len, read, offset); @@ -1080,23 +1098,23 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) default_tag = ossl_asn1_default_tag(self); if (default_tag == -1 || argc > 1) { - if(NIL_P(tag)) - ossl_raise(eASN1Error, "must specify tag number"); - if(!NIL_P(tagging) && !SYMBOL_P(tagging)) - ossl_raise(eASN1Error, "invalid tagging method"); - if(NIL_P(tag_class)) { - if (NIL_P(tagging)) - tag_class = sym_UNIVERSAL; - else - tag_class = sym_CONTEXT_SPECIFIC; - } - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); + if(NIL_P(tag)) + ossl_raise(eASN1Error, "must specify tag number"); + if(!NIL_P(tagging) && !SYMBOL_P(tagging)) + ossl_raise(eASN1Error, "invalid tagging method"); + if(NIL_P(tag_class)) { + if (NIL_P(tagging)) + tag_class = sym_UNIVERSAL; + else + tag_class = sym_CONTEXT_SPECIFIC; + } + if(!SYMBOL_P(tag_class)) + ossl_raise(eASN1Error, "invalid tag class"); } else{ - tag = INT2NUM(default_tag); - tagging = Qnil; - tag_class = sym_UNIVERSAL; + tag = INT2NUM(default_tag); + tagging = Qnil; + tag_class = sym_UNIVERSAL; } ossl_asn1_set_tag(self, tag); ossl_asn1_set_value(self, value); @@ -1104,7 +1122,7 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) ossl_asn1_set_tag_class(self, tag_class); ossl_asn1_set_indefinite_length(self, Qfalse); if (default_tag == V_ASN1_BIT_STRING) - rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0)); + rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0)); return self; } @@ -1146,30 +1164,33 @@ ossl_asn1prim_to_der(VALUE self) VALUE str; if (ossl_asn1_default_tag(self) == -1) { - str = ossl_asn1_get_value(self); - return to_der_internal(self, 0, 0, StringValue(str)); + str = ossl_asn1_get_value(self); + return to_der_internal(self, 0, 0, StringValue(str)); } asn1 = ossl_asn1_get_asn1type(self); alllen = i2d_ASN1_TYPE(asn1, NULL); if (alllen < 0) { - ASN1_TYPE_free(asn1); - ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); + ASN1_TYPE_free(asn1); + ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); } str = ossl_str_new(NULL, alllen, &state); if (state) { - ASN1_TYPE_free(asn1); - rb_jump_tag(state); + ASN1_TYPE_free(asn1); + rb_jump_tag(state); } p0 = p1 = (unsigned char *)RSTRING_PTR(str); - i2d_ASN1_TYPE(asn1, &p0); + if (i2d_ASN1_TYPE(asn1, &p0) < 0) { + ASN1_TYPE_free(asn1); + ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); + } ASN1_TYPE_free(asn1); - assert(p0 - p1 == alllen); + ossl_str_adjust(str, p0); /* Strip header since to_der_internal() wants only the payload */ j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen); if (j & 0x80) - ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */ + ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */ return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen)); } @@ -1191,22 +1212,22 @@ ossl_asn1cons_to_der(VALUE self) ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a"); str = rb_str_new(NULL, 0); for (i = 0; i < RARRAY_LEN(ary); i++) { - VALUE item = RARRAY_AREF(ary, i); - - if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) { - if (i != RARRAY_LEN(ary) - 1) - ossl_raise(eASN1Error, "illegal EOC octets in value"); - - /* - * EOC is not really part of the content, but we required to add one - * at the end in the past. - */ - break; - } - - item = ossl_to_der_if_possible(item); - StringValue(item); - rb_str_append(str, item); + VALUE item = RARRAY_AREF(ary, i); + + if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) { + if (i != RARRAY_LEN(ary) - 1) + ossl_raise(eASN1Error, "illegal EOC octets in value"); + + /* + * EOC is not really part of the content, but we required to add one + * at the end in the past. + */ + break; + } + + item = ossl_to_der_if_possible(item); + StringValue(item); + rb_str_append(str, item); } return to_der_internal(self, 1, indef_len, str); @@ -1252,7 +1273,7 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln) StringValueCStr(ln); if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return Qtrue; } @@ -1272,7 +1293,7 @@ ossl_asn1obj_get_sn(VALUE self) val = ossl_asn1_get_value(self); if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); + ret = rb_str_new2(OBJ_nid2sn(nid)); return ret; } @@ -1292,55 +1313,15 @@ ossl_asn1obj_get_ln(VALUE self) val = ossl_asn1_get_value(self); if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2ln(nid)); + ret = rb_str_new2(OBJ_nid2ln(nid)); return ret; } -/* - * call-seq: - * oid == other_oid => true or false - * - * Returns +true+ if _other_oid_ is the same as _oid_ - */ -static VALUE -ossl_asn1obj_eq(VALUE self, VALUE other) -{ - VALUE valSelf, valOther; - int nidSelf, nidOther; - - valSelf = ossl_asn1_get_value(self); - valOther = ossl_asn1_get_value(other); - - if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef) - ossl_raise(eASN1Error, "OBJ_txt2nid"); - - if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef) - ossl_raise(eASN1Error, "OBJ_txt2nid"); - - return nidSelf == nidOther ? Qtrue : Qfalse; -} - static VALUE asn1obj_get_oid_i(VALUE vobj) { - ASN1_OBJECT *a1obj = (void *)vobj; - VALUE str; - int len; - - str = rb_usascii_str_new(NULL, 127); - len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1); - if (len <= 0 || len == INT_MAX) - ossl_raise(eASN1Error, "OBJ_obj2txt"); - if (len > RSTRING_LEN(str)) { - /* +1 is for the \0 terminator added by OBJ_obj2txt() */ - rb_str_resize(str, len + 1); - len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1); - if (len <= 0) - ossl_raise(eASN1Error, "OBJ_obj2txt"); - } - rb_str_set_len(str, len); - return str; + return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj); } /* @@ -1357,14 +1338,33 @@ ossl_asn1obj_get_oid(VALUE self) ASN1_OBJECT *a1obj; int state; - a1obj = obj_to_asn1obj(ossl_asn1_get_value(self)); + a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self)); str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state); ASN1_OBJECT_free(a1obj); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return str; } +/* + * call-seq: + * oid == other_oid => true or false + * + * Returns +true+ if _other_oid_ is the same as _oid_. + */ +static VALUE +ossl_asn1obj_eq(VALUE self, VALUE other) +{ + VALUE oid1, oid2; + + if (!rb_obj_is_kind_of(other, cASN1ObjectId)) + return Qfalse; + + oid1 = ossl_asn1obj_get_oid(self); + oid2 = ossl_asn1obj_get_oid(other); + return rb_str_equal(oid1, oid2); +} + #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\ { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); } @@ -1397,13 +1397,6 @@ void Init_ossl_asn1(void) { #undef rb_intern - VALUE ary; - int i; - -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL")); sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC")); @@ -1522,7 +1515,7 @@ Init_ossl_asn1(void) * * An Array that stores the name of a given tag number. These names are * the same as the name of the tag constant that is additionally defined, - * e.g. +UNIVERSAL_TAG_NAME[2] = "INTEGER"+ and +OpenSSL::ASN1::INTEGER = 2+. + * e.g. <tt>UNIVERSAL_TAG_NAME[2] = "INTEGER"</tt> and <tt>OpenSSL::ASN1::INTEGER = 2</tt>. * * == Example usage * @@ -1553,17 +1546,20 @@ Init_ossl_asn1(void) rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1); rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1); rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1); - ary = rb_ary_new(); + VALUE ary = rb_ary_new_capa(ossl_asn1_info_size); + for (int i = 0; i < ossl_asn1_info_size; i++) { + const char *name = ossl_asn1_info[i].name; + if (name[0] == '[') + continue; + rb_define_const(mASN1, name, INT2NUM(i)); + rb_ary_store(ary, i, rb_obj_freeze(rb_str_new_cstr(name))); + } + rb_obj_freeze(ary); /* * Array storing tag names at the tag's index. */ rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary); - for(i = 0; i < ossl_asn1_info_size; i++){ - if(ossl_asn1_info[i].name[0] == '[') continue; - rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i)); - rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name)); - } /* Document-class: OpenSSL::ASN1::ASN1Data * @@ -1885,6 +1881,7 @@ do{\ rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING)); rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING)); rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING)); + rb_obj_freeze(class_tag_map); id_each = rb_intern_const("each"); } diff --git a/ext/openssl/ossl_asn1.h b/ext/openssl/ossl_asn1.h index 939a96ce74..b605df8f3f 100644 --- a/ext/openssl/ossl_asn1.h +++ b/ext/openssl/ossl_asn1.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_ASN1_H_) #define _OSSL_ASN1_H_ @@ -32,30 +32,26 @@ VALUE asn1integer_to_num(const ASN1_INTEGER *); ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); /* + * ASN1_OBJECT conversions + */ +ASN1_OBJECT *ossl_to_asn1obj(VALUE obj); +/* + * Returns the short name if available, the dotted decimal notation otherwise. + * This is the most common way to return ASN1_OBJECT to Ruby. + */ +VALUE ossl_asn1obj_to_string(const ASN1_OBJECT *a1obj); +/* + * However, some places use long names instead. This is likely unintentional, + * but we keep the current behavior in existing methods. + */ +VALUE ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *a1obj); + +/* * ASN1 module */ extern VALUE mASN1; -extern VALUE eASN1Error; extern VALUE cASN1Data; -extern VALUE cASN1Primitive; -extern VALUE cASN1Constructive; - -extern VALUE cASN1Boolean; /* BOOLEAN */ -extern VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ -extern VALUE cASN1BitString; /* BIT STRING */ -extern VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ -extern VALUE cASN1NumericString, cASN1PrintableString; -extern VALUE cASN1T61String, cASN1VideotexString; -extern VALUE cASN1IA5String, cASN1GraphicString; -extern VALUE cASN1ISO64String, cASN1GeneralString; -extern VALUE cASN1UniversalString, cASN1BMPString; -extern VALUE cASN1Null; /* NULL */ -extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ -extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ -extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ - -ASN1_TYPE *ossl_asn1_get_asn1type(VALUE); void Init_ossl_asn1(void); diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index 42833d901a..4edde5091d 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -16,11 +16,11 @@ ossl_obj2bio(volatile VALUE *pobj) BIO *bio; if (RB_TYPE_P(obj, T_FILE)) - obj = rb_funcallv(obj, rb_intern("read"), 0, NULL); + obj = rb_funcallv(obj, rb_intern("read"), 0, NULL); StringValue(obj); bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj)); if (!bio) - ossl_raise(eOSSLError, "BIO_new_mem_buf"); + ossl_raise(eOSSLError, "BIO_new_mem_buf"); *pobj = obj; return bio; } @@ -36,7 +36,7 @@ ossl_membio2str(BIO *bio) ret = ossl_str_new(buf->data, buf->length, &state); BIO_free(bio); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return ret; } diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h index da68c5e5a2..1b871f1cd7 100644 --- a/ext/openssl/ossl_bio.h +++ b/ext/openssl/ossl_bio.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BIO_H_) #define _OSSL_BIO_H_ diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index 8d0f63a986..9014f2df2b 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -5,29 +5,25 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */ #include "ossl.h" -#ifdef HAVE_RB_EXT_RACTOR_SAFE -#include <ruby/ractor.h> -#endif - #define NewBN(klass) \ - TypedData_Wrap_Struct((klass), &ossl_bn_type, 0) + TypedData_Wrap_Struct((klass), &ossl_bn_type, 0) #define SetBN(obj, bn) do { \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (bn); \ + if (!(bn)) { \ + ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ + } \ + RTYPEDDATA_DATA(obj) = (bn); \ } while (0) #define GetBN(obj, bn) do { \ - TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ + TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \ + if (!(bn)) { \ + ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ + } \ } while (0) static void @@ -39,9 +35,9 @@ ossl_bn_free(void *ptr) static const rb_data_type_t ossl_bn_type = { "OpenSSL/BN", { - 0, ossl_bn_free, + 0, ossl_bn_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, }; /* @@ -53,7 +49,7 @@ VALUE cBN; * * Generic Error for all of OpenSSL::BN (big num) */ -VALUE eBNError; +static VALUE eBNError; /* * Public @@ -65,10 +61,9 @@ ossl_bn_new(const BIGNUM *bn) VALUE obj; obj = NewBN(cBN); - newbn = bn ? BN_dup(bn) : BN_new(); - if (!newbn) { - ossl_raise(eBNError, NULL); - } + newbn = BN_dup(bn); + if (!newbn) + ossl_raise(eBNError, "BN_dup"); SetBN(obj, newbn); return obj; @@ -80,40 +75,40 @@ integer_to_bnptr(VALUE obj, BIGNUM *orig) BIGNUM *bn; if (FIXNUM_P(obj)) { - long i; - unsigned char bin[sizeof(long)]; - long n = FIX2LONG(obj); - unsigned long un = labs(n); - - for (i = sizeof(long) - 1; 0 <= i; i--) { - bin[i] = un & 0xff; - un >>= 8; - } - - bn = BN_bin2bn(bin, sizeof(bin), orig); - if (!bn) - ossl_raise(eBNError, "BN_bin2bn"); - if (n < 0) - BN_set_negative(bn, 1); + long i; + unsigned char bin[sizeof(long)]; + long n = FIX2LONG(obj); + unsigned long un = labs(n); + + for (i = sizeof(long) - 1; 0 <= i; i--) { + bin[i] = un & 0xff; + un >>= 8; + } + + bn = BN_bin2bn(bin, sizeof(bin), orig); + if (!bn) + ossl_raise(eBNError, "BN_bin2bn"); + if (n < 0) + BN_set_negative(bn, 1); } else { /* assuming Bignum */ - size_t len = rb_absint_size(obj, NULL); - unsigned char *bin; - VALUE buf; - int sign; - - if (INT_MAX < len) { - rb_raise(eBNError, "bignum too long"); - } - bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len); - sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN); - - bn = BN_bin2bn(bin, (int)len, orig); - ALLOCV_END(buf); - if (!bn) - ossl_raise(eBNError, "BN_bin2bn"); - if (sign < 0) - BN_set_negative(bn, 1); + size_t len = rb_absint_size(obj, NULL); + unsigned char *bin; + VALUE buf; + int sign; + + if (INT_MAX < len) { + rb_raise(eBNError, "bignum too long"); + } + bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len); + sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN); + + bn = BN_bin2bn(bin, (int)len, orig); + ALLOCV_END(buf); + if (!bn) + ossl_raise(eBNError, "BN_bin2bn"); + if (sign < 0) + BN_set_negative(bn, 1); } return bn; @@ -126,11 +121,11 @@ try_convert_to_bn(VALUE obj) VALUE newobj = Qnil; if (rb_obj_is_kind_of(obj, cBN)) - return obj; + return obj; if (RB_INTEGER_TYPE_P(obj)) { - newobj = NewBN(cBN); /* Handle potential mem leaks */ - bn = integer_to_bnptr(obj, NULL); - SetBN(newobj, bn); + newobj = NewBN(cBN); /* Handle potential mem leaks */ + bn = integer_to_bnptr(obj, NULL); + SetBN(newobj, bn); } return newobj; @@ -144,7 +139,7 @@ ossl_bn_value_ptr(volatile VALUE *ptr) tmp = try_convert_to_bn(*ptr); if (NIL_P(tmp)) - ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); + ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); GetBN(tmp, bn); *ptr = tmp; @@ -156,19 +151,19 @@ ossl_bn_value_ptr(volatile VALUE *ptr) */ #ifdef HAVE_RB_EXT_RACTOR_SAFE -void +static void ossl_bn_ctx_free(void *ptr) { BN_CTX *ctx = (BN_CTX *)ptr; BN_CTX_free(ctx); } -struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = { +static struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = { NULL, // mark ossl_bn_ctx_free, }; -rb_ractor_local_key_t ossl_bn_ctx_key; +static rb_ractor_local_key_t ossl_bn_ctx_key; BN_CTX * ossl_bn_ctx_get(void) @@ -214,7 +209,7 @@ ossl_bn_alloc(VALUE klass) VALUE obj = NewBN(klass); if (!(bn = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } SetBN(obj, bn); @@ -244,7 +239,7 @@ ossl_bn_alloc(VALUE klass) * number. * - +10+ - Decimal number representation, with a leading '-' for a negative * number. - * - +16+ - Hexadeciaml number representation, with a leading '-' for a + * - +16+ - Hexadecimal number representation, with a leading '-' for a * negative number. */ static VALUE @@ -256,57 +251,58 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self) char *ptr; if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) { - base = NUM2INT(bs); + base = NUM2INT(bs); } if (NIL_P(str)) { ossl_raise(rb_eArgError, "invalid argument"); } + rb_check_frozen(self); if (RB_INTEGER_TYPE_P(str)) { - GetBN(self, bn); - integer_to_bnptr(str, bn); + GetBN(self, bn); + integer_to_bnptr(str, bn); - return self; + return self; } if (RTEST(rb_obj_is_kind_of(str, cBN))) { - BIGNUM *other; - - GetBN(self, bn); - GetBN(str, other); /* Safe - we checked kind_of? above */ - if (!BN_copy(bn, other)) { - ossl_raise(eBNError, NULL); - } - return self; + BIGNUM *other; + + GetBN(self, bn); + GetBN(str, other); /* Safe - we checked kind_of? above */ + if (!BN_copy(bn, other)) { + ossl_raise(eBNError, NULL); + } + return self; } GetBN(self, bn); switch (base) { - case 0: + case 0: ptr = StringValuePtr(str); if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 2: + ossl_raise(eBNError, NULL); + } + break; + case 2: ptr = StringValuePtr(str); if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 10: - if (!BN_dec2bn(&bn, StringValueCStr(str))) { - ossl_raise(eBNError, NULL); - } - break; - case 16: - if (!BN_hex2bn(&bn, StringValueCStr(str))) { - ossl_raise(eBNError, NULL); - } - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); + ossl_raise(eBNError, NULL); + } + break; + case 10: + if (!BN_dec2bn(&bn, StringValueCStr(str))) { + ossl_raise(eBNError, NULL); + } + break; + case 16: + if (!BN_hex2bn(&bn, StringValueCStr(str))) { + ossl_raise(eBNError, NULL); + } + break; + default: + ossl_raise(rb_eArgError, "invalid radix %d", base); } return self; } @@ -326,7 +322,7 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self) * the bignum is ignored. * - +10+ - Decimal number representation, with a leading '-' for a negative * bignum. - * - +16+ - Hexadeciaml number representation, with a leading '-' for a + * - +16+ - Hexadecimal number representation, with a leading '-' for a * negative bignum. */ static VALUE @@ -338,32 +334,32 @@ ossl_bn_to_s(int argc, VALUE *argv, VALUE self) char *buf; if (rb_scan_args(argc, argv, "01", &bs) == 1) { - base = NUM2INT(bs); + base = NUM2INT(bs); } GetBN(self, bn); switch (base) { - case 0: - len = BN_bn2mpi(bn, NULL); + case 0: + len = BN_bn2mpi(bn, NULL); str = rb_str_new(0, len); - if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 2: - len = BN_num_bytes(bn); + if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len) + ossl_raise(eBNError, NULL); + break; + case 2: + len = BN_num_bytes(bn); str = rb_str_new(0, len); - if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 10: - if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - case 16: - if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); + if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len) + ossl_raise(eBNError, NULL); + break; + case 10: + if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL); + str = ossl_buf2str(buf, rb_long2int(strlen(buf))); + break; + case 16: + if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL); + str = ossl_buf2str(buf, rb_long2int(strlen(buf))); + break; + default: + ossl_raise(rb_eArgError, "invalid radix %d", base); } return str; @@ -383,7 +379,7 @@ ossl_bn_to_i(VALUE self) GetBN(self, bn); if (!(txt = BN_bn2hex(bn))) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } num = rb_cstr_to_inum(txt, 16, Qtrue); OPENSSL_free(txt); @@ -401,31 +397,31 @@ static VALUE ossl_bn_coerce(VALUE self, VALUE other) { switch(TYPE(other)) { - case T_STRING: - self = ossl_bn_to_s(0, NULL, self); - break; - case T_FIXNUM: - case T_BIGNUM: - self = ossl_bn_to_i(self); - break; - default: - if (!RTEST(rb_obj_is_kind_of(other, cBN))) { - ossl_raise(rb_eTypeError, "Don't know how to coerce"); - } + case T_STRING: + self = ossl_bn_to_s(0, NULL, self); + break; + case T_FIXNUM: + case T_BIGNUM: + self = ossl_bn_to_i(self); + break; + default: + if (!RTEST(rb_obj_is_kind_of(other, cBN))) { + ossl_raise(rb_eTypeError, "Don't know how to coerce"); + } } return rb_assoc_new(other, self); } -#define BIGNUM_BOOL1(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (BN_##func(bn)) { \ - return Qtrue; \ - } \ - return Qfalse; \ +#define BIGNUM_BOOL1(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn; \ + GetBN(self, bn); \ + if (BN_##func(bn)) { \ + return Qtrue; \ + } \ + return Qfalse; \ } /* @@ -460,27 +456,27 @@ ossl_bn_is_negative(VALUE self) GetBN(self, bn); if (BN_is_zero(bn)) - return Qfalse; + return Qfalse; return BN_is_negative(bn) ? Qtrue : Qfalse; } -#define BIGNUM_1c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn, *result; \ - VALUE obj; \ - GetBN(self, bn); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_1c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn, *result; \ + VALUE obj; \ + GetBN(self, bn); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -490,23 +486,23 @@ ossl_bn_is_negative(VALUE self) */ BIGNUM_1c(sqr) -#define BIGNUM_2(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, bn1, bn2) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_2(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -523,23 +519,23 @@ BIGNUM_2(add) */ BIGNUM_2(sub) -#define BIGNUM_2c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_2c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -577,22 +573,33 @@ BIGNUM_2c(gcd) */ BIGNUM_2c(mod_sqr) +#define BIGNUM_2cr(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_##func(NULL, bn1, bn2, ossl_bn_ctx))) \ + ossl_raise(eBNError, NULL); \ + SetBN(obj, result); \ + return obj; \ + } + /* + * Document-method: OpenSSL::BN#mod_sqrt + * call-seq: + * bn.mod_sqrt(bn2) => aBN + */ +BIGNUM_2cr(mod_sqrt) + +/* + * Document-method: OpenSSL::BN#mod_inverse * call-seq: * bn.mod_inverse(bn2) => aBN */ -static VALUE -ossl_bn_mod_inverse(VALUE self, VALUE other) -{ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; - VALUE obj; - GetBN(self, bn1); - obj = NewBN(rb_obj_class(self)); - if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx))) - ossl_raise(eBNError, "BN_mod_inverse"); - SetBN(obj, result); - return obj; -} +BIGNUM_2cr(mod_inverse) /* * call-seq: @@ -612,16 +619,16 @@ ossl_bn_div(VALUE self, VALUE other) obj1 = NewBN(klass); obj2 = NewBN(klass); if (!(r1 = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } if (!(r2 = BN_new())) { - BN_free(r1); - ossl_raise(eBNError, NULL); + BN_free(r1); + ossl_raise(eBNError, NULL); } if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) { - BN_free(r1); - BN_free(r2); - ossl_raise(eBNError, NULL); + BN_free(r1); + BN_free(r2); + ossl_raise(eBNError, NULL); } SetBN(obj1, r1); SetBN(obj2, r2); @@ -629,24 +636,24 @@ ossl_bn_div(VALUE self, VALUE other) return rb_ary_new3(2, obj1, obj2); } -#define BIGNUM_3c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other1); \ - BIGNUM *bn3 = GetBNPtr(other2), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_3c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other1); \ + BIGNUM *bn3 = GetBNPtr(other2), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -677,16 +684,17 @@ BIGNUM_3c(mod_mul) */ BIGNUM_3c(mod_exp) -#define BIGNUM_BIT(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bit) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (BN_##func(bn, NUM2INT(bit)) <= 0) { \ - ossl_raise(eBNError, NULL); \ - } \ - return self; \ +#define BIGNUM_BIT(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE bit) \ + { \ + BIGNUM *bn; \ + rb_check_frozen(self); \ + GetBN(self, bn); \ + if (BN_##func(bn, NUM2INT(bit)) <= 0) { \ + ossl_raise(eBNError, NULL); \ + } \ + return self; \ } /* @@ -725,30 +733,30 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit) b = NUM2INT(bit); GetBN(self, bn); if (BN_is_bit_set(bn, b)) { - return Qtrue; + return Qtrue; } return Qfalse; } -#define BIGNUM_SHIFT(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn, *result; \ - int b; \ - VALUE obj; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, bn, b) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_SHIFT(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE bits) \ + { \ + BIGNUM *bn, *result; \ + int b; \ + VALUE obj; \ + b = NUM2INT(bits); \ + GetBN(self, bn); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn, b) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -765,17 +773,18 @@ BIGNUM_SHIFT(lshift) */ BIGNUM_SHIFT(rshift) -#define BIGNUM_SELF_SHIFT(func) \ - static VALUE \ - ossl_bn_self_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn; \ - int b; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - if (BN_##func(bn, bn, b) <= 0) \ - ossl_raise(eBNError, NULL); \ - return self; \ +#define BIGNUM_SELF_SHIFT(func) \ + static VALUE \ + ossl_bn_self_##func(VALUE self, VALUE bits) \ + { \ + BIGNUM *bn; \ + int b; \ + rb_check_frozen(self); \ + b = NUM2INT(bits); \ + GetBN(self, bn); \ + if (BN_##func(bn, bn, b) <= 0) \ + ossl_raise(eBNError, NULL); \ + return self; \ } /* @@ -792,78 +801,64 @@ BIGNUM_SELF_SHIFT(lshift) */ BIGNUM_SELF_SHIFT(rshift) -#define BIGNUM_RAND(func) \ - static VALUE \ - ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \ - { \ - BIGNUM *result; \ - int bottom = 0, top = 0, b; \ - VALUE bits, fill, odd, obj; \ - \ - switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \ - case 3: \ - bottom = (odd == Qtrue) ? 1 : 0; \ - /* FALLTHROUGH */ \ - case 2: \ - top = NUM2INT(fill); \ - } \ - b = NUM2INT(bits); \ - obj = NewBN(klass); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func(result, b, top, bottom) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - -/* - * Document-method: OpenSSL::BN.rand - * BN.rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(rand) - -/* - * Document-method: OpenSSL::BN.pseudo_rand - * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(pseudo_rand) - -#define BIGNUM_RAND_RANGE(func) \ - static VALUE \ - ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ - { \ - BIGNUM *bn = GetBNPtr(range), *result; \ - VALUE obj = NewBN(klass); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func##_range(result, bn) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - /* - * Document-method: OpenSSL::BN.rand_range * call-seq: - * BN.rand_range(range) -> aBN + * BN.rand(bits [, fill [, odd]]) -> aBN * + * Generates a cryptographically strong pseudo-random number of +bits+. + * + * See also the man page BN_rand(3). */ -BIGNUM_RAND_RANGE(rand) +static VALUE +ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass) +{ + BIGNUM *result; + int bottom = 0, top = 0, b; + VALUE bits, fill, odd, obj; + + switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { + case 3: + bottom = (odd == Qtrue) ? 1 : 0; + /* FALLTHROUGH */ + case 2: + top = NUM2INT(fill); + } + b = NUM2INT(bits); + obj = NewBN(klass); + if (!(result = BN_new())) { + ossl_raise(eBNError, "BN_new"); + } + if (BN_rand(result, b, top, bottom) <= 0) { + BN_free(result); + ossl_raise(eBNError, "BN_rand"); + } + SetBN(obj, result); + return obj; +} /* - * Document-method: OpenSSL::BN.pseudo_rand_range * call-seq: - * BN.pseudo_rand_range(range) -> aBN + * BN.rand_range(range) -> aBN + * + * Generates a cryptographically strong pseudo-random number in the range + * 0...+range+. * + * See also the man page BN_rand_range(3). */ -BIGNUM_RAND_RANGE(pseudo_rand) +static VALUE +ossl_bn_s_rand_range(VALUE klass, VALUE range) +{ + BIGNUM *bn = GetBNPtr(range), *result; + VALUE obj = NewBN(klass); + if (!(result = BN_new())) + ossl_raise(eBNError, "BN_new"); + if (BN_rand_range(result, bn) <= 0) { + BN_free(result); + ossl_raise(eBNError, "BN_rand_range"); + } + SetBN(obj, result); + return obj; +} /* * call-seq: @@ -891,32 +886,32 @@ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) num = NUM2INT(vnum); if (vsafe == Qfalse) { - safe = 0; + safe = 0; } if (!NIL_P(vadd)) { - add = GetBNPtr(vadd); - rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem); + add = GetBNPtr(vadd); + rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem); } obj = NewBN(klass); if (!(result = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) { - BN_free(result); - ossl_raise(eBNError, NULL); + BN_free(result); + ossl_raise(eBNError, NULL); } SetBN(obj, result); return obj; } -#define BIGNUM_NUM(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - return INT2NUM(BN_##func(bn)); \ +#define BIGNUM_NUM(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn; \ + GetBN(self, bn); \ + return INT2NUM(BN_##func(bn)); \ } /* @@ -933,6 +928,7 @@ BIGNUM_NUM(num_bytes) */ BIGNUM_NUM(num_bits) +/* :nodoc: */ static VALUE ossl_bn_copy(VALUE self, VALUE other) { @@ -946,7 +942,7 @@ ossl_bn_copy(VALUE self, VALUE other) bn2 = GetBNPtr(other); if (!BN_copy(bn1, bn2)) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } return self; } @@ -965,7 +961,7 @@ ossl_bn_uplus(VALUE self) obj = NewBN(cBN); bn2 = BN_dup(bn1); if (!bn2) - ossl_raise(eBNError, "BN_dup"); + ossl_raise(eBNError, "BN_dup"); SetBN(obj, bn2); return obj; @@ -985,7 +981,7 @@ ossl_bn_uminus(VALUE self) obj = NewBN(cBN); bn2 = BN_dup(bn1); if (!bn2) - ossl_raise(eBNError, "BN_dup"); + ossl_raise(eBNError, "BN_dup"); SetBN(obj, bn2); BN_set_negative(bn2, !BN_is_negative(bn2)); @@ -1010,13 +1006,13 @@ ossl_bn_abs(VALUE self) } } -#define BIGNUM_CMP(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other); \ - GetBN(self, bn1); \ - return INT2NUM(BN_##func(bn1, bn2)); \ +#define BIGNUM_CMP(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other); \ + GetBN(self, bn1); \ + return INT2NUM(BN_##func(bn1, bn2)); \ } /* @@ -1053,11 +1049,11 @@ ossl_bn_eq(VALUE self, VALUE other) GetBN(self, bn1); other = try_convert_to_bn(other); if (NIL_P(other)) - return Qfalse; + return Qfalse; GetBN(other, bn2); if (!BN_cmp(bn1, bn2)) { - return Qtrue; + return Qtrue; } return Qfalse; } @@ -1076,7 +1072,7 @@ ossl_bn_eql(VALUE self, VALUE other) BIGNUM *bn1, *bn2; if (!rb_obj_is_kind_of(other, cBN)) - return Qfalse; + return Qfalse; GetBN(self, bn1); GetBN(other, bn2); @@ -1103,8 +1099,8 @@ ossl_bn_hash(VALUE self) len = BN_num_bytes(bn); buf = ALLOCV(tmp, len); if (BN_bn2bin(bn, buf) != len) { - ALLOCV_END(tmp); - ossl_raise(eBNError, "BN_bn2bin"); + ALLOCV_END(tmp); + ossl_raise(eBNError, "BN_bn2bin"); } hash = ST2FIX(rb_memhash(buf, len)); @@ -1118,34 +1114,29 @@ ossl_bn_hash(VALUE self) * bn.prime? => true | false * bn.prime?(checks) => true | false * - * Performs a Miller-Rabin probabilistic primality test with _checks_ - * iterations. If _checks_ is not specified, a number of iterations is used - * that yields a false positive rate of at most 2^-80 for random input. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer + * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect. */ static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) { BIGNUM *bn; - VALUE vchecks; - int checks = BN_prime_checks; + int ret; - if (rb_scan_args(argc, argv, "01", &vchecks) == 1) { - checks = NUM2INT(vchecks); - } + rb_check_arity(argc, 0, 1); GetBN(self, bn); - switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; + +#ifdef HAVE_BN_CHECK_PRIME + ret = BN_check_prime(bn, ossl_bn_ctx, NULL); + if (ret < 0) + ossl_raise(eBNError, "BN_check_prime"); +#else + ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL); + if (ret < 0) + ossl_raise(eBNError, "BN_is_prime_fasttest_ex"); +#endif + return ret ? Qtrue : Qfalse; } /* @@ -1154,40 +1145,17 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) * bn.prime_fasttest?(checks) => true | false * bn.prime_fasttest?(checks, trial_div) => true | false * - * Performs a Miller-Rabin primality test. This is same as #prime? except this - * first attempts trial divisions with some small primes. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer - * * _trial_div_ - boolean + * <b>Deprecated in version 3.0.</b> Use #prime? instead. + * + * +checks+ and +trial_div+ parameters no longer have any effect. */ static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self) { - BIGNUM *bn; - VALUE vchecks, vtrivdiv; - int checks = BN_prime_checks, do_trial_division = 1; - - rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv); - - if (!NIL_P(vchecks)) { - checks = NUM2INT(vchecks); - } - GetBN(self, bn); - /* handle true/false */ - if (vtrivdiv == Qfalse) { - do_trial_division = 0; - } - switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; + rb_check_arity(argc, 0, 2); + return ossl_bn_is_prime(0, argv, self); } /* @@ -1222,6 +1190,7 @@ ossl_bn_set_flags(VALUE self, VALUE arg) BIGNUM *bn; GetBN(self, bn); + rb_check_frozen(self); BN_set_flags(bn, NUM2INT(arg)); return Qnil; } @@ -1233,11 +1202,6 @@ ossl_bn_set_flags(VALUE self, VALUE arg) void Init_ossl_bn(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - #ifdef HAVE_RB_EXT_RACTOR_SAFE ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type); #else @@ -1276,6 +1240,7 @@ Init_ossl_bn(void) rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2); rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2); rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1); + rb_define_method(cBN, "mod_sqrt", ossl_bn_mod_sqrt, 1); rb_define_method(cBN, "**", ossl_bn_exp, 1); rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2); rb_define_method(cBN, "gcd", ossl_bn_gcd, 1); @@ -1306,9 +1271,9 @@ Init_ossl_bn(void) * get_word */ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1); - rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1); rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1); - rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand"); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range"); rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1); rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1); diff --git a/ext/openssl/ossl_bn.h b/ext/openssl/ossl_bn.h index 1cc041fc22..0c186bd1c5 100644 --- a/ext/openssl/ossl_bn.h +++ b/ext/openssl/ossl_bn.h @@ -5,13 +5,12 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BN_H_) #define _OSSL_BN_H_ extern VALUE cBN; -extern VALUE eBNError; BN_CTX *ossl_bn_ctx_get(void); #define ossl_bn_ctx ossl_bn_ctx_get() diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index d9c7891433..f3cd247c8f 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,7 +14,7 @@ #define AllocCipher(obj, ctx) do { \ (ctx) = EVP_CIPHER_CTX_new(); \ if (!(ctx)) \ - ossl_raise(rb_eRuntimeError, NULL); \ + ossl_raise(rb_eRuntimeError, NULL); \ RTYPEDDATA_DATA(obj) = (ctx); \ } while (0) #define GetCipherInit(obj, ctx) do { \ @@ -23,16 +23,17 @@ #define GetCipher(obj, ctx) do { \ GetCipherInit((obj), (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ + ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cCipher; -VALUE eCipherError; -static ID id_auth_tag_len, id_key_set; +static VALUE cCipher; +static VALUE eCipherError; +static VALUE eAuthTagError; +static ID id_auth_tag_len, id_key_set, id_cipher_holder; static VALUE ossl_cipher_alloc(VALUE klass); static void ossl_cipher_free(void *ptr); @@ -40,35 +41,63 @@ static void ossl_cipher_free(void *ptr); static const rb_data_type_t ossl_cipher_type = { "OpenSSL/Cipher", { - 0, ossl_cipher_free, + 0, ossl_cipher_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +#ifdef OSSL_USE_PROVIDER +static void +ossl_evp_cipher_free(void *ptr) +{ + // This is safe to call against const EVP_CIPHER * returned by + // EVP_get_cipherbyname() + EVP_CIPHER_free(ptr); +} + +static const rb_data_type_t ossl_evp_cipher_holder_type = { + "OpenSSL/EVP_CIPHER", + { + .dfree = ossl_evp_cipher_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; +#endif + /* * PUBLIC */ const EVP_CIPHER * -ossl_evp_get_cipherbyname(VALUE obj) +ossl_evp_cipher_fetch(VALUE obj, volatile VALUE *holder) { + *holder = Qnil; if (rb_obj_is_kind_of(obj, cCipher)) { - EVP_CIPHER_CTX *ctx; - - GetCipher(obj, ctx); - - return EVP_CIPHER_CTX_cipher(ctx); + EVP_CIPHER_CTX *ctx; + GetCipher(obj, ctx); + EVP_CIPHER *cipher = (EVP_CIPHER *)EVP_CIPHER_CTX_cipher(ctx); +#ifdef OSSL_USE_PROVIDER + *holder = TypedData_Wrap_Struct(0, &ossl_evp_cipher_holder_type, NULL); + if (!EVP_CIPHER_up_ref(cipher)) + ossl_raise(eCipherError, "EVP_CIPHER_up_ref"); + RTYPEDDATA_DATA(*holder) = cipher; +#endif + return cipher; } - else { - const EVP_CIPHER *cipher; - - StringValueCStr(obj); - cipher = EVP_get_cipherbyname(RSTRING_PTR(obj)); - if (!cipher) - ossl_raise(rb_eArgError, - "unsupported cipher algorithm: %"PRIsVALUE, obj); - return cipher; + const char *name = StringValueCStr(obj); + EVP_CIPHER *cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name); +#ifdef OSSL_USE_PROVIDER + if (!cipher) { + ossl_clear_error(); + *holder = TypedData_Wrap_Struct(0, &ossl_evp_cipher_holder_type, NULL); + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + RTYPEDDATA_DATA(*holder) = cipher; } +#endif + if (!cipher) + ossl_raise(eCipherError, "unsupported cipher algorithm: %"PRIsVALUE, + obj); + return cipher; } VALUE @@ -77,10 +106,13 @@ ossl_cipher_new(const EVP_CIPHER *cipher) VALUE ret; EVP_CIPHER_CTX *ctx; + // NOTE: This does not set id_cipher_holder because this function should + // only be called from ossl_engine.c, which will not use any + // reference-counted ciphers. ret = ossl_cipher_alloc(cCipher); AllocCipher(ret, ctx); if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return ret; } @@ -113,23 +145,22 @@ ossl_cipher_initialize(VALUE self, VALUE str) { EVP_CIPHER_CTX *ctx; const EVP_CIPHER *cipher; - char *name; + VALUE cipher_holder; - name = StringValueCStr(str); GetCipherInit(self, ctx); if (ctx) { - ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); + ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); } + cipher = ossl_evp_cipher_fetch(str, &cipher_holder); AllocCipher(self, ctx); - if (!(cipher = EVP_get_cipherbyname(name))) { - ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str); - } if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, "EVP_CipherInit_ex"); + rb_ivar_set(self, id_cipher_holder, cipher_holder); return self; } +/* :nodoc: */ static VALUE ossl_cipher_copy(VALUE self, VALUE other) { @@ -140,11 +171,11 @@ ossl_cipher_copy(VALUE self, VALUE other) GetCipherInit(self, ctx1); if (!ctx1) { - AllocCipher(self, ctx1); + AllocCipher(self, ctx1); } GetCipher(other, ctx2); if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return self; } @@ -169,8 +200,8 @@ ossl_s_ciphers(VALUE self) ary = rb_ary_new(); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - add_cipher_name_to_ary, - (void*)ary); + add_cipher_name_to_ary, + (void*)ary); return ary; } @@ -191,53 +222,22 @@ ossl_cipher_reset(VALUE self) GetCipher(self, ctx); if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return self; } static VALUE -ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) +ossl_cipher_init(VALUE self, int enc) { EVP_CIPHER_CTX *ctx; - unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; - VALUE pass, init_v; - - if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ - /* - * oops. this code mistakes salt for IV. - * We deprecated the arguments for this method, but we decided - * keeping this behaviour for backward compatibility. - */ - VALUE cname = rb_class_path(rb_obj_class(self)); - rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; " - "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV", - cname, cname, cname); - StringValue(pass); - GetCipher(self, ctx); - if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); - else{ - StringValue(init_v); - if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { - memset(iv, 0, EVP_MAX_IV_LENGTH); - memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); - } - else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); - } - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, - (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); - p_key = key; - p_iv = iv; - } - else { - GetCipher(self, ctx); - } - if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { - ossl_raise(eCipherError, NULL); + + GetCipher(self, ctx); + if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, enc) != 1) { + ossl_raise(eCipherError, "EVP_CipherInit_ex"); } - rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse); + rb_ivar_set(self, id_key_set, Qfalse); return self; } @@ -248,16 +248,15 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) * * Initializes the Cipher for encryption. * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen] + * Make sure to call either #encrypt or #decrypt before using the Cipher for + * any operation or setting any parameters. * * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1). */ static VALUE -ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) +ossl_cipher_encrypt(VALUE self) { - return ossl_cipher_init(argc, argv, self, 1); + return ossl_cipher_init(self, 1); } /* @@ -266,16 +265,15 @@ ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) * * Initializes the Cipher for decryption. * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen] + * Make sure to call either #encrypt or #decrypt before using the Cipher for + * any operation or setting any parameters. * * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0). */ static VALUE -ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) +ossl_cipher_decrypt(VALUE self) { - return ossl_cipher_init(argc, argv, self, 0); + return ossl_cipher_init(self, 0); } /* @@ -284,46 +282,42 @@ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) * * Generates and sets the key/IV based on a password. * - * *WARNING*: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, - * or DES with MD5 or SHA1. Using anything else (like AES) will generate the - * key/iv using an OpenSSL specific method. This method is deprecated and - * should no longer be used. Use a PKCS5 v2 key generation method from - * OpenSSL::PKCS5 instead. + * *WARNING*: This method is deprecated and should not be used. This method + * corresponds to EVP_BytesToKey(), a non-standard OpenSSL extension of the + * legacy PKCS #5 v1.5 key derivation function. See OpenSSL::KDF for other + * options to derive keys from passwords. * * === Parameters * * _salt_ must be an 8 byte string if provided. * * _iterations_ is an integer with a default of 2048. * * _digest_ is a Digest object that defaults to 'MD5' - * - * A minimum of 1000 iterations is recommended. - * */ static VALUE ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) { EVP_CIPHER_CTX *ctx; const EVP_MD *digest; - VALUE vpass, vsalt, viter, vdigest; + VALUE vpass, vsalt, viter, vdigest, md_holder; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL; int iter; rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest); StringValue(vpass); if(!NIL_P(vsalt)){ - StringValue(vsalt); - if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) - ossl_raise(eCipherError, "salt must be an 8-octet string"); - salt = (unsigned char *)RSTRING_PTR(vsalt); + StringValue(vsalt); + if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) + ossl_raise(eCipherError, "salt must be an 8-octet string"); + salt = (unsigned char *)RSTRING_PTR(vsalt); } iter = NIL_P(viter) ? 2048 : NUM2INT(viter); if (iter <= 0) - rb_raise(rb_eArgError, "iterations must be a positive integer"); - digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest); + rb_raise(rb_eArgError, "iterations must be a positive integer"); + digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_md_fetch(vdigest, &md_holder); GetCipher(self, ctx); EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt, - (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); + (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); OPENSSL_cleanse(key, sizeof key); OPENSSL_cleanse(iv, sizeof iv); @@ -334,25 +328,25 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) static int ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr, - const unsigned char *in, long in_len) + const unsigned char *in, long in_len) { int out_part_len; int limit = INT_MAX / 2 + 1; long out_len = 0; do { - int in_part_len = in_len > limit ? limit : (int)in_len; + int in_part_len = in_len > limit ? limit : (int)in_len; - if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, - &out_part_len, in, in_part_len)) - return 0; + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, in_part_len)) + return 0; - out_len += out_part_len; - in += in_part_len; + out_len += out_part_len; + in += in_part_len; } while ((in_len -= limit) > 0); if (out_len_ptr) - *out_len_ptr = out_len; + *out_len_ptr = out_len; return 1; } @@ -368,6 +362,9 @@ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_p * * If _buffer_ is given, the encryption/decryption result will be written to * it. _buffer_ will be resized automatically. + * + * *NOTE*: When decrypting using an AEAD cipher, the integrity of the output + * is not verified until #final has been called. */ static VALUE ossl_cipher_update(int argc, VALUE *argv, VALUE self) @@ -380,29 +377,43 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &data, &str); if (!RTEST(rb_attr_get(self, id_key_set))) - ossl_raise(eCipherError, "key not set"); + ossl_raise(eCipherError, "key not set"); StringValue(data); in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LEN(data)) == 0) - ossl_raise(rb_eArgError, "data must not be empty"); + in_len = RSTRING_LEN(data); GetCipher(self, ctx); - out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); - if (out_len <= 0) { - ossl_raise(rb_eRangeError, - "data too big to make output buffer: %ld bytes", in_len); + + /* + * As of OpenSSL 3.2, there is no reliable way to determine the required + * output buffer size for arbitrary cipher modes. + * https://github.com/openssl/openssl/issues/22628 + * + * in_len+block_size is usually sufficient, but AES key wrap with padding + * ciphers require in_len+15 even though they have a block size of 8 bytes. + * + * Using EVP_MAX_BLOCK_LENGTH (32) as a safe upper bound for ciphers + * currently implemented in OpenSSL, but this can change in the future. + */ + if (in_len > LONG_MAX - EVP_MAX_BLOCK_LENGTH) { + ossl_raise(rb_eRangeError, + "data too big to make output buffer: %ld bytes", in_len); } + out_len = in_len + EVP_MAX_BLOCK_LENGTH; - if (NIL_P(str)) { - str = rb_str_new(0, out_len); - } else { + if (NIL_P(str)) + str = rb_str_buf_new(out_len); + else { StringValue(str); - rb_str_resize(str, out_len); + if ((long)rb_str_capacity(str) >= out_len) + rb_str_modify(str); + else + rb_str_modify_expand(str, out_len - RSTRING_LEN(str)); } - if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) - ossl_raise(eCipherError, NULL); - assert(out_len < RSTRING_LEN(str)); + if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), + &out_len, in, in_len)) + ossl_raise(eCipherError, "EVP_CipherUpdate"); rb_str_set_len(str, out_len); return str; @@ -413,14 +424,17 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) * cipher.final -> string * * Returns the remaining data held in the cipher object. Further calls to - * Cipher#update or Cipher#final will return garbage. This call should always + * Cipher#update or Cipher#final are invalid. This call should always * be made as the last call of an encryption or decryption operation, after * having fed the entire plaintext or ciphertext to the Cipher instance. * - * If an authenticated cipher was used, a CipherError is raised if the tag - * could not be authenticated successfully. Only call this method after - * setting the authentication tag and passing the entire contents of the - * ciphertext into the cipher. + * When encrypting using an AEAD cipher, the authentication tag can be + * retrieved by #auth_tag after #final has been called. + * + * When decrypting using an AEAD cipher, this method will verify the integrity + * of the ciphertext and the associated data with the authentication tag, + * which must be set by #auth_tag= prior to calling this method. + * If the verification fails, CipherError will be raised. */ static VALUE ossl_cipher_final(VALUE self) @@ -431,9 +445,17 @@ ossl_cipher_final(VALUE self) GetCipher(self, ctx); str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx)); - if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) - ossl_raise(eCipherError, NULL); - assert(out_len <= RSTRING_LEN(str)); + if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) { + /* For AEAD ciphers, this is likely an authentication failure */ + if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) { + /* For AEAD ciphers, EVP_CipherFinal_ex failures are authentication tag verification failures */ + ossl_raise(eAuthTagError, "AEAD authentication tag verification failed"); + } + else { + /* For non-AEAD ciphers */ + ossl_raise(eCipherError, "cipher final failed"); + } + } rb_str_set_len(str, out_len); return str; @@ -443,8 +465,8 @@ ossl_cipher_final(VALUE self) * call-seq: * cipher.name -> string * - * Returns the name of the cipher which may differ slightly from the original - * name provided. + * Returns the short name of the cipher which may differ slightly from the + * original name provided. */ static VALUE ossl_cipher_name(VALUE self) @@ -458,7 +480,7 @@ ossl_cipher_name(VALUE self) /* * call-seq: - * cipher.key = string -> string + * cipher.key = string * * Sets the cipher key. To generate a key, you should either use a secure * random byte string or, if the key is to be derived from a password, you @@ -466,6 +488,8 @@ ossl_cipher_name(VALUE self) * generate a secure random-based key, Cipher#random_key may be used. * * Only call this method after calling Cipher#encrypt or Cipher#decrypt. + * + * See also the man page EVP_CipherInit_ex(3). */ static VALUE ossl_cipher_set_key(VALUE self, VALUE key) @@ -478,10 +502,10 @@ ossl_cipher_set_key(VALUE self, VALUE key) key_len = EVP_CIPHER_CTX_key_length(ctx); if (RSTRING_LEN(key) != key_len) - ossl_raise(rb_eArgError, "key must be %d bytes", key_len); + ossl_raise(rb_eArgError, "key must be %d bytes", key_len); if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); rb_ivar_set(self, id_key_set, Qtrue); @@ -490,15 +514,21 @@ ossl_cipher_set_key(VALUE self, VALUE key) /* * call-seq: - * cipher.iv = string -> string + * cipher.iv = string * * Sets the cipher IV. Please note that since you should never be using ECB * mode, an IV is always explicitly required and should be set prior to - * encryption. The IV itself can be safely transmitted in public, but it - * should be unpredictable to prevent certain kinds of attacks. You may use - * Cipher#random_iv to create a secure random IV. + * encryption. The IV itself can be safely transmitted in public. * - * Only call this method after calling Cipher#encrypt or Cipher#decrypt. + * This method expects the String to have the length equal to #iv_len. To use + * a different IV length with an AEAD cipher, #iv_len= must be set prior to + * calling this method. + * + * *NOTE*: In OpenSSL API conventions, the IV value may correspond to the + * "nonce" instead in some cipher modes. Refer to the OpenSSL man pages for + * details. + * + * See also the man page EVP_CipherInit_ex(3). */ static VALUE ossl_cipher_set_iv(VALUE self, VALUE iv) @@ -510,14 +540,14 @@ ossl_cipher_set_iv(VALUE self, VALUE iv) GetCipher(self, ctx); if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) - iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); + iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); if (!iv_len) - iv_len = EVP_CIPHER_CTX_iv_length(ctx); + iv_len = EVP_CIPHER_CTX_iv_length(ctx); if (RSTRING_LEN(iv) != iv_len) - ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len); + ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len); if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return iv; } @@ -526,8 +556,7 @@ ossl_cipher_set_iv(VALUE self, VALUE iv) * call-seq: * cipher.authenticated? -> true | false * - * Indicated whether this Cipher instance uses an Authenticated Encryption - * mode. + * Indicates whether this Cipher instance uses an AEAD mode. */ static VALUE ossl_cipher_is_authenticated(VALUE self) @@ -541,21 +570,23 @@ ossl_cipher_is_authenticated(VALUE self) /* * call-seq: - * cipher.auth_data = string -> string + * cipher.auth_data = string + * + * Sets additional authenticated data (AAD), also called associated data, for + * this Cipher. This method is available for AEAD ciphers. * - * Sets the cipher's additional authenticated data. This field must be - * set when using AEAD cipher modes such as GCM or CCM. If no associated - * data shall be used, this method must *still* be called with a value of "". * The contents of this field should be non-sensitive data which will be * added to the ciphertext to generate the authentication tag which validates * the contents of the ciphertext. * - * The AAD must be set prior to encryption or decryption. In encryption mode, - * it must be set after calling Cipher#encrypt and setting Cipher#key= and - * Cipher#iv=. When decrypting, the authenticated data must be set after key, - * iv and especially *after* the authentication tag has been set. I.e. set it - * only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and - * Cipher#auth_tag= first. + * This method must be called after #key= and #iv= have been set, but before + * starting actual encryption or decryption with #update. In some cipher modes, + * #auth_tag_len= and #ccm_data_len= may also need to be called before this + * method. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CipherUpdate() with the output buffer + * set to NULL. */ static VALUE ossl_cipher_set_auth_data(VALUE self, VALUE data) @@ -571,7 +602,7 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "AEAD not supported by this cipher"); + ossl_raise(eCipherError, "AEAD not supported by this cipher"); if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); @@ -583,16 +614,17 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data) * call-seq: * cipher.auth_tag(tag_len = 16) -> String * - * Gets the authentication tag generated by Authenticated Encryption Cipher - * modes (GCM for example). This tag may be stored along with the ciphertext, - * then set on the decryption cipher to authenticate the contents of the - * ciphertext against changes. If the optional integer parameter _tag_len_ is - * given, the returned tag will be _tag_len_ bytes long. If the parameter is - * omitted, the default length of 16 bytes or the length previously set by - * #auth_tag_len= will be used. For maximum security, the longest possible - * should be chosen. + * Gets the generated authentication tag. This method is available for AEAD + * ciphers, and should be called after encryption has been finalized by calling + * #final. * - * The tag may only be retrieved after calling Cipher#final. + * The returned tag will be _tag_len_ bytes long. Some cipher modes require + * the desired length in advance using a separate call to #auth_tag_len=, + * before starting encryption. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_GET_TAG. */ static VALUE ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self) @@ -603,34 +635,42 @@ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &vtag_len); if (NIL_P(vtag_len)) - vtag_len = rb_attr_get(self, id_auth_tag_len); + vtag_len = rb_attr_get(self, id_auth_tag_len); if (!NIL_P(vtag_len)) - tag_len = NUM2INT(vtag_len); + tag_len = NUM2INT(vtag_len); GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "authentication tag not supported by this cipher"); + ossl_raise(eCipherError, "authentication tag not supported by this cipher"); ret = rb_str_new(NULL, tag_len); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, RSTRING_PTR(ret))) - ossl_raise(eCipherError, "retrieving the authentication tag failed"); + ossl_raise(eCipherError, "retrieving the authentication tag failed"); return ret; } /* * call-seq: - * cipher.auth_tag = string -> string + * cipher.auth_tag = string * * Sets the authentication tag to verify the integrity of the ciphertext. - * This can be called only when the cipher supports AE. The tag must be set - * after calling Cipher#decrypt, Cipher#key= and Cipher#iv=, but before - * calling Cipher#final. After all decryption is performed, the tag is - * verified automatically in the call to Cipher#final. * - * For OCB mode, the tag length must be supplied with #auth_tag_len= - * beforehand. + * The authentication tag must be set before #final is called. The tag is + * verified during the #final call. + * + * Note that, for CCM mode and OCB mode, the expected length of the tag must + * be set before starting decryption by a separate call to #auth_tag_len=. + * The content of the tag can be provided at any time before #final is called. + * + * *NOTE*: The caller must ensure that the String passed to this method has + * the desired length. Some cipher modes support variable tag lengths, and + * this method may accept a truncated tag without raising an exception. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_TAG. */ static VALUE ossl_cipher_set_auth_tag(VALUE self, VALUE vtag) @@ -645,24 +685,27 @@ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "authentication tag not supported by this cipher"); + ossl_raise(eCipherError, "authentication tag not supported by this cipher"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag)) - ossl_raise(eCipherError, "unable to set AEAD tag"); + ossl_raise(eCipherError, "unable to set AEAD tag"); return vtag; } /* * call-seq: - * cipher.auth_tag_len = Integer -> Integer + * cipher.auth_tag_len = integer * - * Sets the length of the authentication tag to be generated or to be given for - * AEAD ciphers that requires it as in input parameter. Note that not all AEAD - * ciphers support this method. + * Sets the length of the expected authentication tag for this Cipher. This + * method is available for some of AEAD ciphers that require the length to be + * set before starting encryption or decryption, such as CCM mode or OCB mode. * - * In OCB mode, the length must be supplied both when encrypting and when - * decrypting, and must be before specifying an IV. + * For CCM mode and OCB mode, the tag length must be set before #iv= is set. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_TAG and a NULL buffer. */ static VALUE ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) @@ -672,10 +715,10 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "AEAD not supported by this cipher"); + ossl_raise(eCipherError, "AEAD not supported by this cipher"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL)) - ossl_raise(eCipherError, "unable to set authentication tag length"); + ossl_raise(eCipherError, "unable to set authentication tag length"); /* for #auth_tag */ rb_ivar_set(self, id_auth_tag_len, INT2NUM(tag_len)); @@ -685,11 +728,16 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) /* * call-seq: - * cipher.iv_len = integer -> integer + * cipher.iv_len = integer + * + * Sets the IV/nonce length for this Cipher. This method is available for AEAD + * ciphers that support variable IV lengths. This method can be called if a + * different IV length than OpenSSL's default is desired, prior to calling + * #iv=. * - * Sets the IV/nonce length of the Cipher. Normally block ciphers don't allow - * changing the IV length, but some make use of IV for 'nonce'. You may need - * this for interoperability with other applications. + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_IVLEN. */ static VALUE ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) @@ -699,10 +747,10 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "cipher does not support AEAD"); + ossl_raise(eCipherError, "cipher does not support AEAD"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)) - ossl_raise(eCipherError, "unable to set IV length"); + ossl_raise(eCipherError, "unable to set IV length"); /* * EVP_CIPHER_CTX_iv_length() returns the default length. So we need to save @@ -715,13 +763,14 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) /* * call-seq: - * cipher.key_len = integer -> integer + * cipher.key_len = integer * * Sets the key length of the cipher. If the cipher is a fixed length cipher * then attempting to set the key length to any value other than the fixed * value is an error. * - * Under normal circumstances you do not need to call this method (and probably shouldn't). + * Under normal circumstances you do not need to call this method (and + * probably shouldn't). * * See EVP_CIPHER_CTX_set_key_length for further information. */ @@ -738,13 +787,16 @@ ossl_cipher_set_key_length(VALUE self, VALUE key_length) return key_length; } +// TODO: Should #padding= take a boolean value instead? /* * call-seq: - * cipher.padding = integer -> integer + * cipher.padding = 1 or 0 * - * Enables or disables padding. By default encryption operations are padded using standard block padding and the - * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the - * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur. + * Enables or disables padding. By default encryption operations are padded + * using standard block padding and the padding is checked and removed when + * decrypting. If the pad parameter is zero then no padding is performed, the + * total amount of data encrypted or decrypted must then be a multiple of the + * block size or an error will occur. * * See EVP_CIPHER_CTX_set_padding for further information. */ @@ -756,7 +808,7 @@ ossl_cipher_set_padding(VALUE self, VALUE padding) GetCipher(self, ctx); if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return padding; } @@ -790,9 +842,9 @@ ossl_cipher_iv_length(VALUE self) GetCipher(self, ctx); if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) - len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); + len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); if (!len) - len = EVP_CIPHER_CTX_iv_length(ctx); + len = EVP_CIPHER_CTX_iv_length(ctx); return INT2NUM(len); } @@ -815,13 +867,17 @@ ossl_cipher_block_size(VALUE self) /* * call-seq: - * cipher.ccm_data_len = integer -> integer + * cipher.ccm_data_len = integer * - * Sets the length of the plaintext / ciphertext message that will be - * processed in CCM mode. Make sure to call this method after #key= and - * #iv= have been set, and before #auth_data=. + * Sets the total length of the plaintext / ciphertext message that will be + * processed by #update in CCM mode. * - * Only call this method after calling Cipher#encrypt or Cipher#decrypt. + * Make sure to call this method after #key= and #iv= have been set, and + * before #auth_data= or #update are called. + * + * This method is only available for CCM mode ciphers. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). */ static VALUE ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len) @@ -844,11 +900,6 @@ ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len) void Init_ossl_cipher(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-class: OpenSSL::Cipher * * Provides symmetric algorithms for encryption and decryption. The @@ -1004,24 +1055,28 @@ Init_ossl_cipher(void) * could otherwise be exploited to modify ciphertexts in ways beneficial to * potential attackers. * - * An associated data is used where there is additional information, such as + * Associated data, also called additional authenticated data (AAD), is + * optionally used where there is additional information, such as * headers or some metadata, that must be also authenticated but not - * necessarily need to be encrypted. If no associated data is needed for - * encryption and later decryption, the OpenSSL library still requires a - * value to be set - "" may be used in case none is available. + * necessarily need to be encrypted. * * An example using the GCM (Galois/Counter Mode). You have 16 bytes _key_, * 12 bytes (96 bits) _nonce_ and the associated data _auth_data_. Be sure * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the * security guarantees of GCM mode. * + * key = OpenSSL::Random.random_bytes(16) + * nonce = OpenSSL::Random.random_bytes(12) + * auth_data = "authenticated but unencrypted data" + * data = "encrypted data" + * * cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt * cipher.key = key * cipher.iv = nonce * cipher.auth_data = auth_data * * encrypted = cipher.update(data) + cipher.final - * tag = cipher.auth_tag # produces 16 bytes tag by default + * tag = cipher.auth_tag(16) * * Now you are the receiver. You know the _key_ and have received _nonce_, * _auth_data_, _encrypted_ and _tag_ through an untrusted network. Note @@ -1034,23 +1089,29 @@ Init_ossl_cipher(void) * decipher = OpenSSL::Cipher.new('aes-128-gcm').decrypt * decipher.key = key * decipher.iv = nonce - * decipher.auth_tag = tag + * decipher.auth_tag = tag # could be called at any time before #final * decipher.auth_data = auth_data * * decrypted = decipher.update(encrypted) + decipher.final * * puts data == decrypted #=> true + * + * Note that other AEAD ciphers may require additional steps, such as + * setting the expected tag length (#auth_tag_len=) or the total data + * length (#ccm_data_len=) in advance. Make sure to read the relevant man + * page for details. */ cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject); eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError); + eAuthTagError = rb_define_class_under(cCipher, "AuthTagError", eCipherError); rb_define_alloc_func(cCipher, ossl_cipher_alloc); rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1); rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0); rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); - rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); - rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); + rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, 0); + rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, 0); rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1); rb_define_method(cCipher, "update", ossl_cipher_update, -1); rb_define_method(cCipher, "final", ossl_cipher_final, 0); @@ -1072,4 +1133,5 @@ Init_ossl_cipher(void) id_auth_tag_len = rb_intern_const("auth_tag_len"); id_key_set = rb_intern_const("key_set"); + id_cipher_holder = rb_intern_const("EVP_CIPHER_holder"); } diff --git a/ext/openssl/ossl_cipher.h b/ext/openssl/ossl_cipher.h index 2392d41c6a..fba63a140f 100644 --- a/ext/openssl/ossl_cipher.h +++ b/ext/openssl/ossl_cipher.h @@ -5,15 +5,21 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_CIPHER_H_) #define _OSSL_CIPHER_H_ -extern VALUE cCipher; -extern VALUE eCipherError; - -const EVP_CIPHER *ossl_evp_get_cipherbyname(VALUE); +/* + * Gets EVP_CIPHER from a String or an OpenSSL::Digest instance (discouraged, + * but still supported for compatibility). A holder object is created if the + * EVP_CIPHER is a "fetched" algorithm. + */ +const EVP_CIPHER *ossl_evp_cipher_fetch(VALUE obj, volatile VALUE *holder); +/* + * This is meant for OpenSSL::Engine#cipher. EVP_CIPHER must not be a fetched + * one. + */ VALUE ossl_cipher_new(const EVP_CIPHER *); void Init_ossl_cipher(void); diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c index 0bac027487..274875a978 100644 --- a/ext/openssl/ossl_config.c +++ b/ext/openssl/ossl_config.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -22,7 +22,7 @@ static const rb_data_type_t ossl_config_type = { { 0, nconf_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, }; CONF * @@ -87,6 +87,7 @@ config_s_parse(VALUE klass, VALUE str) bio = ossl_obj2bio(&str); config_load_bio(conf, bio); /* Consumes BIO */ + rb_obj_freeze(obj); return obj; } @@ -144,6 +145,7 @@ config_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eConfigError, "BIO_new_file"); config_load_bio(conf, bio); /* Consumes BIO */ } + rb_obj_freeze(self); return self; } @@ -158,6 +160,7 @@ config_initialize_copy(VALUE self, VALUE other) rb_check_frozen(self); bio = ossl_obj2bio(&str); config_load_bio(conf, bio); /* Consumes BIO */ + rb_obj_freeze(self); return self; } @@ -305,18 +308,16 @@ static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, VALUE) * * Gets the parsable form of the current configuration. * - * Given the following configuration being created: + * Given the following configuration file being loaded: * - * config = OpenSSL::Config.new - * #=> #<OpenSSL::Config sections=[]> - * config['default'] = {"foo"=>"bar","baz"=>"buz"} - * #=> {"foo"=>"bar", "baz"=>"buz"} + * config = OpenSSL::Config.load('baz.cnf') + * #=> #<OpenSSL::Config sections=["default"]> * puts config.to_s * #=> [ default ] * # foo=bar * # baz=buz * - * You can parse get the serialized configuration using #to_s and then parse + * You can get the serialized configuration using #to_s and then parse * it later: * * serialized_config = config.to_s @@ -412,11 +413,6 @@ Init_ossl_config(void) char *path; VALUE path_str; -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-class: OpenSSL::Config * * Configuration for the openssl library. @@ -425,7 +421,7 @@ Init_ossl_config(void) * configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for * the location of the file for your host. * - * See also http://www.openssl.org/docs/apps/config.html + * See also https://docs.openssl.org/master/man5/config/ */ cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject); @@ -455,6 +451,6 @@ Init_ossl_config(void) * The default system configuration file for OpenSSL. */ path = CONF_get1_default_config_file(); - path_str = ossl_buf2str(path, rb_long2int(strlen(path))); + path_str = rb_obj_freeze(ossl_buf2str(path, rb_long2int(strlen(path)))); rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", path_str); } diff --git a/ext/openssl/ossl_config.h b/ext/openssl/ossl_config.h index 4e604f1aed..a254360c2c 100644 --- a/ext/openssl/ossl_config.h +++ b/ext/openssl/ossl_config.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #ifndef OSSL_CONFIG_H #define OSSL_CONFIG_H diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index b2506de7f7..e23968b1e3 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -5,22 +5,23 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" #define GetDigest(obj, ctx) do { \ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_digest_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cDigest; -VALUE eDigestError; +static VALUE cDigest; +static VALUE eDigestError; +static ID id_md_holder; static VALUE ossl_digest_alloc(VALUE klass); @@ -33,39 +34,67 @@ ossl_digest_free(void *ctx) static const rb_data_type_t ossl_digest_type = { "OpenSSL/Digest", { - 0, ossl_digest_free, + 0, ossl_digest_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +#ifdef OSSL_USE_PROVIDER +static void +ossl_evp_md_free(void *ptr) +{ + // This is safe to call against const EVP_MD * returned by + // EVP_get_digestbyname() + EVP_MD_free(ptr); +} + +static const rb_data_type_t ossl_evp_md_holder_type = { + "OpenSSL/EVP_MD", + { + .dfree = ossl_evp_md_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; +#endif + /* * Public */ const EVP_MD * -ossl_evp_get_digestbyname(VALUE obj) +ossl_evp_md_fetch(VALUE obj, volatile VALUE *holder) { - const EVP_MD *md; - ASN1_OBJECT *oid = NULL; - - if (RB_TYPE_P(obj, T_STRING)) { - const char *name = StringValueCStr(obj); - - md = EVP_get_digestbyname(name); - if (!md) { - oid = OBJ_txt2obj(name, 0); - md = EVP_get_digestbyobj(oid); - ASN1_OBJECT_free(oid); - } - if(!md) - ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%"PRIsVALUE").", obj); - } else { + *holder = Qnil; + if (rb_obj_is_kind_of(obj, cDigest)) { EVP_MD_CTX *ctx; - GetDigest(obj, ctx); - - md = EVP_MD_CTX_md(ctx); + EVP_MD *md = (EVP_MD *)EVP_MD_CTX_get0_md(ctx); +#ifdef OSSL_USE_PROVIDER + *holder = TypedData_Wrap_Struct(0, &ossl_evp_md_holder_type, NULL); + if (!EVP_MD_up_ref(md)) + ossl_raise(eDigestError, "EVP_MD_up_ref"); + RTYPEDDATA_DATA(*holder) = md; +#endif + return md; } + const char *name = StringValueCStr(obj); + EVP_MD *md = (EVP_MD *)EVP_get_digestbyname(name); + if (!md) { + ASN1_OBJECT *oid = OBJ_txt2obj(name, 0); + md = (EVP_MD *)EVP_get_digestbyobj(oid); + ASN1_OBJECT_free(oid); + } +#ifdef OSSL_USE_PROVIDER + if (!md) { + ossl_clear_error(); + *holder = TypedData_Wrap_Struct(0, &ossl_evp_md_holder_type, NULL); + md = EVP_MD_fetch(NULL, name, NULL); + RTYPEDDATA_DATA(*holder) = md; + } +#endif + if (!md) + ossl_raise(eDigestError, "unsupported digest algorithm: %"PRIsVALUE, + obj); return md; } @@ -75,14 +104,17 @@ ossl_digest_new(const EVP_MD *md) VALUE ret; EVP_MD_CTX *ctx; + // NOTE: This does not set id_md_holder because this function should + // only be called from ossl_engine.c, which will not use any + // reference-counted digests. ret = ossl_digest_alloc(cDigest); ctx = EVP_MD_CTX_new(); if (!ctx) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + ossl_raise(eDigestError, "EVP_MD_CTX_new"); RTYPEDDATA_DATA(ret) = ctx; if (!EVP_DigestInit_ex(ctx, md, NULL)) - ossl_raise(eDigestError, "Digest initialization failed"); + ossl_raise(eDigestError, "Digest initialization failed"); return ret; } @@ -96,14 +128,15 @@ ossl_digest_alloc(VALUE klass) return TypedData_Wrap_Struct(klass, &ossl_digest_type, 0); } -VALUE ossl_digest_update(VALUE, VALUE); +static VALUE ossl_digest_update(VALUE, VALUE); /* * call-seq: * Digest.new(string [, data]) -> Digest * * Creates a Digest instance based on _string_, which is either the ln - * (long name) or sn (short name) of a supported digest algorithm. + * (long name) or sn (short name) of a supported digest algorithm. A list of + * supported algorithms can be obtained by calling OpenSSL::Digest.digests. * * If _data_ (a String) is given, it is used as the initial input to the * Digest instance, i.e. @@ -120,26 +153,28 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self) { EVP_MD_CTX *ctx; const EVP_MD *md; - VALUE type, data; + VALUE type, data, md_holder; rb_scan_args(argc, argv, "11", &type, &data); - md = ossl_evp_get_digestbyname(type); + md = ossl_evp_md_fetch(type, &md_holder); if (!NIL_P(data)) StringValue(data); TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx); if (!ctx) { - RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new(); - if (!ctx) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new(); + if (!ctx) + ossl_raise(eDigestError, "EVP_MD_CTX_new"); } if (!EVP_DigestInit_ex(ctx, md, NULL)) - ossl_raise(eDigestError, "Digest initialization failed"); + ossl_raise(eDigestError, "Digest initialization failed"); + rb_ivar_set(self, id_md_holder, md_holder); if (!NIL_P(data)) return ossl_digest_update(self, data); return self; } +/* :nodoc: */ static VALUE ossl_digest_copy(VALUE self, VALUE other) { @@ -150,18 +185,44 @@ ossl_digest_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1); if (!ctx1) { - RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new(); - if (!ctx1) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new(); + if (!ctx1) + ossl_raise(eDigestError, "EVP_MD_CTX_new"); } GetDigest(other, ctx2); if (!EVP_MD_CTX_copy(ctx1, ctx2)) { - ossl_raise(eDigestError, NULL); + ossl_raise(eDigestError, NULL); } return self; } +static void +add_digest_name_to_ary(const OBJ_NAME *name, void *arg) +{ + VALUE ary = (VALUE)arg; + rb_ary_push(ary, rb_str_new2(name->name)); +} + +/* + * call-seq: + * OpenSSL::Digest.digests -> array[string...] + * + * Returns the names of all available digests in an array. + */ +static VALUE +ossl_s_digests(VALUE self) +{ + VALUE ary; + + ary = rb_ary_new(); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, + add_digest_name_to_ary, + (void*)ary); + + return ary; +} + /* * call-seq: * digest.reset -> self @@ -176,8 +237,8 @@ ossl_digest_reset(VALUE self) EVP_MD_CTX *ctx; GetDigest(self, ctx); - if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); + if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) { + ossl_raise(eDigestError, "Digest initialization failed."); } return self; @@ -198,7 +259,7 @@ ossl_digest_reset(VALUE self) * result = digest.digest * */ -VALUE +static VALUE ossl_digest_update(VALUE self, VALUE data) { EVP_MD_CTX *ctx; @@ -207,7 +268,7 @@ ossl_digest_update(VALUE self, VALUE data) GetDigest(self, ctx); if (!EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) - ossl_raise(eDigestError, "EVP_DigestUpdate"); + ossl_raise(eDigestError, "EVP_DigestUpdate"); return self; } @@ -218,25 +279,15 @@ ossl_digest_update(VALUE self, VALUE data) * */ static VALUE -ossl_digest_finish(int argc, VALUE *argv, VALUE self) +ossl_digest_finish(VALUE self) { EVP_MD_CTX *ctx; VALUE str; - int out_len; GetDigest(self, ctx); - rb_scan_args(argc, argv, "01", &str); - out_len = EVP_MD_CTX_size(ctx); - - if (NIL_P(str)) { - str = rb_str_new(NULL, out_len); - } else { - StringValue(str); - rb_str_resize(str, out_len); - } - + str = rb_str_new(NULL, EVP_MD_CTX_size(ctx)); if (!EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL)) - ossl_raise(eDigestError, "EVP_DigestFinal_ex"); + ossl_raise(eDigestError, "EVP_DigestFinal_ex"); return str; } @@ -245,7 +296,8 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self) * call-seq: * digest.name -> string * - * Returns the sn of this Digest algorithm. + * Returns the short name of this Digest algorithm which may differ slightly + * from the original name provided. * * === Example * digest = OpenSSL::Digest.new('SHA512') @@ -259,7 +311,7 @@ ossl_digest_name(VALUE self) GetDigest(self, ctx); - return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); + return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx))); } /* @@ -313,11 +365,6 @@ ossl_digest_block_length(VALUE self) void Init_ossl_digest(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-class: OpenSSL::Digest * * OpenSSL::Digest allows you to compute message digests (sometimes @@ -412,14 +459,17 @@ Init_ossl_digest(void) rb_define_alloc_func(cDigest, ossl_digest_alloc); + rb_define_module_function(cDigest, "digests", ossl_s_digests, 0); rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1); rb_define_method(cDigest, "initialize_copy", ossl_digest_copy, 1); rb_define_method(cDigest, "reset", ossl_digest_reset, 0); rb_define_method(cDigest, "update", ossl_digest_update, 1); rb_define_alias(cDigest, "<<", "update"); - rb_define_private_method(cDigest, "finish", ossl_digest_finish, -1); + rb_define_private_method(cDigest, "finish", ossl_digest_finish, 0); rb_define_method(cDigest, "digest_length", ossl_digest_size, 0); rb_define_method(cDigest, "block_length", ossl_digest_block_length, 0); rb_define_method(cDigest, "name", ossl_digest_name, 0); + + id_md_holder = rb_intern_const("EVP_MD_holder"); } diff --git a/ext/openssl/ossl_digest.h b/ext/openssl/ossl_digest.h index 50bf5666a3..9c3bb2b149 100644 --- a/ext/openssl/ossl_digest.h +++ b/ext/openssl/ossl_digest.h @@ -5,15 +5,20 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_DIGEST_H_) #define _OSSL_DIGEST_H_ -extern VALUE cDigest; -extern VALUE eDigestError; - -const EVP_MD *ossl_evp_get_digestbyname(VALUE); +/* + * Gets EVP_MD from a String or an OpenSSL::Digest instance (discouraged, but + * still supported for compatibility). A holder object is created if the EVP_MD + * is a "fetched" algorithm. + */ +const EVP_MD *ossl_evp_md_fetch(VALUE obj, volatile VALUE *holder); +/* + * This is meant for OpenSSL::Engine#digest. EVP_MD must not be a fetched one. + */ VALUE ossl_digest_new(const EVP_MD *); void Init_ossl_digest(void); diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c index 661a1368e2..a2bcb07ea4 100644 --- a/ext/openssl/ossl_engine.c +++ b/ext/openssl/ossl_engine.c @@ -5,17 +5,18 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -#if !defined(OPENSSL_NO_ENGINE) +#ifdef OSSL_USE_ENGINE +# include <openssl/engine.h> #define NewEngine(klass) \ TypedData_Wrap_Struct((klass), &ossl_engine_type, 0) #define SetEngine(obj, engine) do { \ if (!(engine)) { \ - ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (engine); \ } while(0) @@ -36,35 +37,25 @@ * * See also, https://www.openssl.org/docs/crypto/engine.html */ -VALUE cEngine; +static VALUE cEngine; /* Document-class: OpenSSL::Engine::EngineError * * This is the generic exception for OpenSSL::Engine related errors */ -VALUE eEngineError; +static VALUE eEngineError; /* * Private */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 #define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \ do{\ - if(!strcmp(#engine_name, RSTRING_PTR(name))){\ - if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\ - return Qtrue;\ - else\ - ossl_raise(eEngineError, "OPENSSL_init_crypto"); \ - }\ -}while(0) -#else -#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \ -do{\ - if(!strcmp(#engine_name, RSTRING_PTR(name))){\ - ENGINE_load_##engine_name();\ - return Qtrue;\ - }\ + if(!strcmp(#engine_name, RSTRING_PTR(name))){\ + if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\ + return Qtrue;\ + else\ + ossl_raise(eEngineError, "OPENSSL_init_crypto"); \ + }\ }while(0) -#endif static void ossl_engine_free(void *engine) @@ -75,9 +66,9 @@ ossl_engine_free(void *engine) static const rb_data_type_t ossl_engine_type = { "OpenSSL/Engine", { - 0, ossl_engine_free, + 0, ossl_engine_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -101,50 +92,10 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) return Qtrue; } StringValueCStr(name); -#ifdef HAVE_ENGINE_LOAD_DYNAMIC OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC); -#endif -#ifndef OPENSSL_NO_STATIC_ENGINE -#ifdef HAVE_ENGINE_LOAD_4758CCA - OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA); -#endif -#ifdef HAVE_ENGINE_LOAD_AEP - OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP); -#endif -#ifdef HAVE_ENGINE_LOAD_ATALLA - OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA); -#endif -#ifdef HAVE_ENGINE_LOAD_CHIL - OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL); -#endif -#ifdef HAVE_ENGINE_LOAD_CSWIFT - OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT); -#endif -#ifdef HAVE_ENGINE_LOAD_NURON - OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON); -#endif -#ifdef HAVE_ENGINE_LOAD_SUREWARE - OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE); -#endif -#ifdef HAVE_ENGINE_LOAD_UBSEC - OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC); -#endif -#ifdef HAVE_ENGINE_LOAD_PADLOCK OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK); -#endif -#ifdef HAVE_ENGINE_LOAD_CAPI OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI); -#endif -#ifdef HAVE_ENGINE_LOAD_GMP - OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP); -#endif -#ifdef HAVE_ENGINE_LOAD_GOST - OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST); -#endif -#endif -#ifdef HAVE_ENGINE_LOAD_CRYPTODEV OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV); -#endif OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL); rb_warning("no such builtin loader for `%"PRIsVALUE"'", name); return Qnil; @@ -162,9 +113,6 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) static VALUE ossl_engine_s_cleanup(VALUE self) { -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000 - ENGINE_cleanup(); -#endif return Qnil; } @@ -182,12 +130,12 @@ ossl_engine_s_engines(VALUE klass) ary = rb_ary_new(); for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){ - obj = NewEngine(klass); - /* Need a ref count of two here because of ENGINE_free being - * called internally by OpenSSL when moving to the next ENGINE - * and by us when releasing the ENGINE reference */ - ENGINE_up_ref(e); - SetEngine(obj, e); + obj = NewEngine(klass); + /* Need a ref count of two here because of ENGINE_free being + * called internally by OpenSSL when moving to the next ENGINE + * and by us when releasing the ENGINE reference */ + ENGINE_up_ref(e); + SetEngine(obj, e); rb_ary_push(ary, obj); } @@ -215,13 +163,13 @@ ossl_engine_s_by_id(VALUE klass, VALUE id) ossl_engine_s_load(1, &id, klass); obj = NewEngine(klass); if(!(e = ENGINE_by_id(RSTRING_PTR(id)))) - ossl_raise(eEngineError, NULL); + ossl_raise(eEngineError, NULL); SetEngine(obj, e); if(rb_block_given_p()) rb_yield(obj); if(!ENGINE_init(e)) - ossl_raise(eEngineError, NULL); + ossl_raise(eEngineError, NULL); ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK, - 0, NULL, (void(*)(void))ossl_pem_passwd_cb); + 0, NULL, (void(*)(void))ossl_pem_passwd_cb); ossl_clear_error(); return obj; @@ -236,7 +184,7 @@ ossl_engine_s_by_id(VALUE klass, VALUE id) * OpenSSL::Engine.load * OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...] * OpenSSL::Engine.engines.first.id - * #=> "rsax" + * #=> "rsax" */ static VALUE ossl_engine_get_id(VALUE self) @@ -255,7 +203,7 @@ ossl_engine_get_id(VALUE self) * OpenSSL::Engine.load * OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...] * OpenSSL::Engine.engines.first.name - * #=> "RSAX engine support" + * #=> "RSAX engine support" * */ static VALUE @@ -326,11 +274,11 @@ ossl_engine_get_cipher(VALUE self, VALUE name) * Will raise an EngineError if the digest is unavailable. * * e = OpenSSL::Engine.by_id("openssl") - * #=> #<OpenSSL::Engine id="openssl" name="Software engine support"> + * #=> #<OpenSSL::Engine id="openssl" name="Software engine support"> * e.digest("SHA1") - * #=> #<OpenSSL::Digest: da39a3ee5e6b4b0d3255bfef95601890afd80709> + * #=> #<OpenSSL::Digest: da39a3ee5e6b4b0d3255bfef95601890afd80709> * e.digest("zomg") - * #=> OpenSSL::Engine::EngineError: no such digest `zomg' + * #=> OpenSSL::Engine::EngineError: no such digest `zomg' */ static VALUE ossl_engine_get_digest(VALUE self, VALUE name) @@ -372,7 +320,7 @@ ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self) GetEngine(self, e); pkey = ENGINE_load_private_key(e, sid, NULL, sdata); if (!pkey) ossl_raise(eEngineError, NULL); - obj = ossl_pkey_new(pkey); + obj = ossl_pkey_wrap(pkey); OSSL_PKEY_SET_PRIVATE(obj); return obj; @@ -402,7 +350,7 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self) pkey = ENGINE_load_public_key(e, sid, NULL, sdata); if (!pkey) ossl_raise(eEngineError, NULL); - return ossl_pkey_new(pkey); + return ossl_pkey_wrap(pkey); } /* @@ -417,7 +365,7 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self) * your OS. * * [All flags] 0xFFFF - * [No flags] 0x0000 + * [No flags] 0x0000 * * See also <openssl/engine.h> */ @@ -451,7 +399,7 @@ ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self) GetEngine(self, e); rb_scan_args(argc, argv, "11", &cmd, &val); ret = ENGINE_ctrl_cmd_string(e, StringValueCStr(cmd), - NIL_P(val) ? NULL : StringValueCStr(val), 0); + NIL_P(val) ? NULL : StringValueCStr(val), 0); if (!ret) ossl_raise(eEngineError, NULL); return self; @@ -461,11 +409,11 @@ static VALUE ossl_engine_cmd_flag_to_name(int flag) { switch(flag){ - case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC"); - case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING"); - case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT"); - case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL"); - default: return rb_str_new2("UNKNOWN"); + case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC"); + case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING"); + case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT"); + case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL"); + default: return rb_str_new2("UNKNOWN"); } } @@ -485,13 +433,13 @@ ossl_engine_get_cmds(VALUE self) GetEngine(self, e); ary = rb_ary_new(); if ((defn = ENGINE_get_cmd_defns(e)) != NULL){ - for (p = defn; p->cmd_num > 0; p++){ - tmp = rb_ary_new(); - rb_ary_push(tmp, rb_str_new2(p->cmd_name)); - rb_ary_push(tmp, rb_str_new2(p->cmd_desc)); - rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags)); - rb_ary_push(ary, tmp); - } + for (p = defn; p->cmd_num > 0; p++){ + tmp = rb_ary_new(); + rb_ary_push(tmp, rb_str_new2(p->cmd_name)); + rb_ary_push(tmp, rb_str_new2(p->cmd_desc)); + rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags)); + rb_ary_push(ary, tmp); + } } return ary; @@ -510,7 +458,7 @@ ossl_engine_inspect(VALUE self) GetEngine(self, e); return rb_sprintf("#<%"PRIsVALUE" id=\"%s\" name=\"%s\">", - rb_obj_class(self), ENGINE_get_id(e), ENGINE_get_name(e)); + rb_obj_class(self), ENGINE_get_id(e), ENGINE_get_name(e)); } #define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x)) @@ -518,11 +466,6 @@ ossl_engine_inspect(VALUE self) void Init_ossl_engine(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject); eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError); @@ -548,12 +491,6 @@ Init_ossl_engine(void) DefEngineConst(METHOD_DSA); DefEngineConst(METHOD_DH); DefEngineConst(METHOD_RAND); -#ifdef ENGINE_METHOD_BN_MOD_EXP - DefEngineConst(METHOD_BN_MOD_EXP); -#endif -#ifdef ENGINE_METHOD_BN_MOD_EXP_CRT - DefEngineConst(METHOD_BN_MOD_EXP_CRT); -#endif DefEngineConst(METHOD_CIPHERS); DefEngineConst(METHOD_DIGESTS); DefEngineConst(METHOD_ALL); diff --git a/ext/openssl/ossl_engine.h b/ext/openssl/ossl_engine.h index cd548beea3..cedcebb772 100644 --- a/ext/openssl/ossl_engine.h +++ b/ext/openssl/ossl_engine.h @@ -6,14 +6,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(OSSL_ENGINE_H) #define OSSL_ENGINE_H -extern VALUE cEngine; -extern VALUE eEngineError; - void Init_ossl_engine(void); #endif /* OSSL_ENGINE_H */ diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index a21db6c481..ddcc6a5f8d 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,15 +14,16 @@ #define GetHMAC(obj, ctx) do { \ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ + ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ } \ } while (0) /* * Classes */ -VALUE cHMAC; -VALUE eHMACError; +static VALUE cHMAC; +static VALUE eHMACError; +static ID id_md_holder; /* * Public @@ -40,9 +41,9 @@ ossl_hmac_free(void *ctx) static const rb_data_type_t ossl_hmac_type = { "OpenSSL/HMAC", { - 0, ossl_hmac_free, + 0, ossl_hmac_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -73,17 +74,17 @@ ossl_hmac_alloc(VALUE klass) * * === Example * - * key = 'key' - * instance = OpenSSL::HMAC.new(key, 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance.class - * #=> OpenSSL::HMAC + * key = 'key' + * instance = OpenSSL::HMAC.new(key, 'SHA1') + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance.class + * #=> OpenSSL::HMAC * * === A note about comparisons * * Two instances can be securely compared with #== in constant time: * - * other_instance = OpenSSL::HMAC.new('key', 'SHA1') + * other_instance = OpenSSL::HMAC.new('key', 'SHA1') * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * instance == other_instance * #=> true @@ -94,25 +95,29 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) { EVP_MD_CTX *ctx; EVP_PKEY *pkey; + const EVP_MD *md; + VALUE md_holder; GetHMAC(self, ctx); StringValue(key); - pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, - (unsigned char *)RSTRING_PTR(key), - RSTRING_LENINT(key)); + md = ossl_evp_md_fetch(digest, &md_holder); + pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, + (unsigned char *)RSTRING_PTR(key), + RSTRING_LENINT(key)); if (!pkey) - ossl_raise(eHMACError, "EVP_PKEY_new_mac_key"); - if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest), - NULL, pkey) != 1) { + ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key"); + if (EVP_DigestSignInit(ctx, NULL, md, NULL, pkey) != 1) { EVP_PKEY_free(pkey); ossl_raise(eHMACError, "EVP_DigestSignInit"); } + rb_ivar_set(self, id_md_holder, md_holder); /* Decrement reference counter; EVP_MD_CTX still keeps it */ EVP_PKEY_free(pkey); return self; } +/* :nodoc: */ static VALUE ossl_hmac_copy(VALUE self, VALUE other) { @@ -137,13 +142,13 @@ ossl_hmac_copy(VALUE self, VALUE other) * * === Example * - * first_chunk = 'The quick brown fox jumps ' - * second_chunk = 'over the lazy dog' + * first_chunk = 'The quick brown fox jumps ' + * second_chunk = 'over the lazy dog' * - * instance.update(first_chunk) - * #=> 5b9a8038a65d571076d97fe783989e52278a492a - * instance.update(second_chunk) - * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 + * instance.update(first_chunk) + * #=> 5b9a8038a65d571076d97fe783989e52278a492a + * instance.update(second_chunk) + * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 * */ static VALUE @@ -175,7 +180,7 @@ static VALUE ossl_hmac_digest(VALUE self) { EVP_MD_CTX *ctx; - size_t buf_len; + size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); @@ -200,7 +205,7 @@ ossl_hmac_hexdigest(VALUE self) { EVP_MD_CTX *ctx; unsigned char buf[EVP_MAX_MD_SIZE]; - size_t buf_len; + size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); @@ -221,14 +226,14 @@ ossl_hmac_hexdigest(VALUE self) * * === Example * - * data = "The quick brown fox jumps over the lazy dog" - * instance = OpenSSL::HMAC.new('key', 'SHA1') - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * data = "The quick brown fox jumps over the lazy dog" + * instance = OpenSSL::HMAC.new('key', 'SHA1') + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * - * instance.update(data) - * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 - * instance.reset - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance.update(data) + * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 + * instance.reset + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * */ static VALUE @@ -238,8 +243,8 @@ ossl_hmac_reset(VALUE self) EVP_PKEY *pkey; GetHMAC(self, ctx); - pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); - if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1) + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); + if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) ossl_raise(eHMACError, "EVP_DigestSignInit"); return self; @@ -251,11 +256,6 @@ ossl_hmac_reset(VALUE self) void Init_ossl_hmac(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Document-class: OpenSSL::HMAC * @@ -299,4 +299,6 @@ Init_ossl_hmac(void) rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0); rb_define_alias(cHMAC, "inspect", "hexdigest"); rb_define_alias(cHMAC, "to_s", "hexdigest"); + + id_md_holder = rb_intern_const("EVP_MD_holder"); } diff --git a/ext/openssl/ossl_hmac.h b/ext/openssl/ossl_hmac.h index 7c51f4722d..e5bed37c9f 100644 --- a/ext/openssl/ossl_hmac.h +++ b/ext/openssl/ossl_hmac.h @@ -5,14 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_HMAC_H_) #define _OSSL_HMAC_H_ -extern VALUE cHMAC; -extern VALUE eHMACError; - void Init_ossl_hmac(void); #endif /* _OSSL_HMAC_H_ */ diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c index 7fa38b865e..1f28016440 100644 --- a/ext/openssl/ossl_kdf.c +++ b/ext/openssl/ossl_kdf.c @@ -3,9 +3,7 @@ * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors */ #include "ossl.h" -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) -# include <openssl/kdf.h> -#endif +#include <openssl/kdf.h> static VALUE mKDF, eKDF; @@ -18,10 +16,10 @@ static VALUE mKDF, eKDF; * of _length_ bytes. * * For more information about PBKDF2, see RFC 2898 Section 5.2 - * (https://tools.ietf.org/html/rfc2898#section-5.2). + * (https://www.rfc-editor.org/rfc/rfc2898#section-5.2). * * === Parameters - * pass :: The passphrase. + * pass :: The password. * salt :: The salt. Salts prevent attacks based on dictionaries of common * passwords and attacks based on rainbow tables. It is a public * value that can be safely stored along with the password (e.g. @@ -37,16 +35,16 @@ static VALUE mKDF, eKDF; static VALUE kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) { - VALUE pass, salt, opts, kwargs[4], str; + VALUE pass, salt, opts, kwargs[4], str, md_holder; static ID kwargs_ids[4]; int iters, len; const EVP_MD *md; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("iterations"); - kwargs_ids[2] = rb_intern_const("length"); - kwargs_ids[3] = rb_intern_const("hash"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("iterations"); + kwargs_ids[2] = rb_intern_const("length"); + kwargs_ids[3] = rb_intern_const("hash"); } rb_scan_args(argc, argv, "1:", &pass, &opts); rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs); @@ -55,14 +53,14 @@ kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) salt = StringValue(kwargs[0]); iters = NUM2INT(kwargs[1]); len = NUM2INT(kwargs[2]); - md = ossl_evp_get_digestbyname(kwargs[3]); + md = ossl_evp_md_fetch(kwargs[3], &md_holder); str = rb_str_new(0, len); if (!PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass), - (unsigned char *)RSTRING_PTR(salt), - RSTRING_LENINT(salt), iters, md, len, - (unsigned char *)RSTRING_PTR(str))) - ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC"); + (unsigned char *)RSTRING_PTR(salt), + RSTRING_LENINT(salt), iters, md, len, + (unsigned char *)RSTRING_PTR(str))) + ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC"); return str; } @@ -81,10 +79,10 @@ kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) * bcrypt. * * The keyword arguments _N_, _r_ and _p_ can be used to tune scrypt. RFC 7914 - * (published on 2016-08, https://tools.ietf.org/html/rfc7914#section-2) states + * (published on 2016-08, https://www.rfc-editor.org/rfc/rfc7914#section-2) states * that using values r=8 and p=1 appears to yield good results. * - * See RFC 7914 (https://tools.ietf.org/html/rfc7914) for more information. + * See RFC 7914 (https://www.rfc-editor.org/rfc/rfc7914) for more information. * * === Parameters * pass :: Passphrase. @@ -109,11 +107,11 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) uint64_t N, r, p, maxmem; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("N"); - kwargs_ids[2] = rb_intern_const("r"); - kwargs_ids[3] = rb_intern_const("p"); - kwargs_ids[4] = rb_intern_const("length"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("N"); + kwargs_ids[2] = rb_intern_const("r"); + kwargs_ids[3] = rb_intern_const("p"); + kwargs_ids[4] = rb_intern_const("length"); } rb_scan_args(argc, argv, "1:", &pass, &opts); rb_get_kwargs(opts, kwargs_ids, 5, 0, kwargs); @@ -133,21 +131,20 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) str = rb_str_new(0, len); if (!EVP_PBE_scrypt(RSTRING_PTR(pass), RSTRING_LEN(pass), - (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt), - N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len)) - ossl_raise(eKDF, "EVP_PBE_scrypt"); + (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt), + N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len)) + ossl_raise(eKDF, "EVP_PBE_scrypt"); return str; } #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) /* * call-seq: * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String * * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in - * {RFC 5869}[https://tools.ietf.org/html/rfc5869]. + * {RFC 5869}[https://www.rfc-editor.org/rfc/rfc5869]. * * New in OpenSSL 1.1.0. * @@ -165,7 +162,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) * The hash function. * * === Example - * # The values from https://datatracker.ietf.org/doc/html/rfc5869#appendix-A.1 + * # The values from https://www.rfc-editor.org/rfc/rfc5869#appendix-A.1 * ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") * salt = ["000102030405060708090a0b0c"].pack("H*") * info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*") @@ -175,7 +172,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) static VALUE kdf_hkdf(int argc, VALUE *argv, VALUE self) { - VALUE ikm, salt, info, opts, kwargs[4], str; + VALUE ikm, salt, info, opts, kwargs[4], str, md_holder; static ID kwargs_ids[4]; int saltlen, ikmlen, infolen; size_t len; @@ -183,10 +180,10 @@ kdf_hkdf(int argc, VALUE *argv, VALUE self) EVP_PKEY_CTX *pctx; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("info"); - kwargs_ids[2] = rb_intern_const("length"); - kwargs_ids[3] = rb_intern_const("hash"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("info"); + kwargs_ids[2] = rb_intern_const("length"); + kwargs_ids[3] = rb_intern_const("hash"); } rb_scan_args(argc, argv, "1:", &ikm, &opts); rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs); @@ -199,55 +196,49 @@ kdf_hkdf(int argc, VALUE *argv, VALUE self) infolen = RSTRING_LENINT(info); len = (size_t)NUM2LONG(kwargs[2]); if (len > LONG_MAX) - rb_raise(rb_eArgError, "length must be non-negative"); - md = ossl_evp_get_digestbyname(kwargs[3]); + rb_raise(rb_eArgError, "length must be non-negative"); + md = ossl_evp_md_fetch(kwargs[3], &md_holder); str = rb_str_new(NULL, (long)len); pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); if (!pctx) - ossl_raise(eKDF, "EVP_PKEY_CTX_new_id"); + ossl_raise(eKDF, "EVP_PKEY_CTX_new_id"); if (EVP_PKEY_derive_init(pctx) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_derive_init"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_derive_init"); } if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md"); } if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (unsigned char *)RSTRING_PTR(salt), - saltlen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt"); + saltlen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt"); } if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (unsigned char *)RSTRING_PTR(ikm), - ikmlen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key"); + ikmlen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key"); } if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *)RSTRING_PTR(info), - infolen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info"); + infolen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info"); } if (EVP_PKEY_derive(pctx, (unsigned char *)RSTRING_PTR(str), &len) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_derive"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_derive"); } rb_str_set_len(str, (long)len); EVP_PKEY_CTX_free(pctx); return str; } -#endif void Init_ossl_kdf(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Document-module: OpenSSL::KDF * @@ -305,7 +296,5 @@ Init_ossl_kdf(void) #if defined(HAVE_EVP_PBE_SCRYPT) rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1); #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1); -#endif } diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 9b1147367a..8440c2ee82 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,23 +13,23 @@ TypedData_Wrap_Struct((klass), &ossl_netscape_spki_type, 0) #define SetSPKI(obj, spki) do { \ if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (spki); \ } while (0) #define GetSPKI(obj, spki) do { \ TypedData_Get_Struct((obj), NETSCAPE_SPKI, &ossl_netscape_spki_type, (spki)); \ if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE mNetscape; -VALUE cSPKI; -VALUE eSPKIError; +static VALUE mNetscape; +static VALUE cSPKI; +static VALUE eSPKIError; /* * Public functions @@ -48,9 +48,9 @@ ossl_netscape_spki_free(void *spki) static const rb_data_type_t ossl_netscape_spki_type = { "OpenSSL/NETSCAPE_SPKI", { - 0, ossl_netscape_spki_free, + 0, ossl_netscape_spki_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -61,7 +61,7 @@ ossl_spki_alloc(VALUE klass) obj = NewSPKI(klass); if (!(spki = NETSCAPE_SPKI_new())) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } SetSPKI(obj, spki); @@ -83,15 +83,15 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self) const unsigned char *p; if (rb_scan_args(argc, argv, "01", &buffer) == 0) { - return self; + return self; } StringValue(buffer); if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) { - ossl_clear_error(); - p = (unsigned char *)RSTRING_PTR(buffer); - if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { - ossl_raise(eSPKIError, NULL); - } + ossl_clear_error(); + p = (unsigned char *)RSTRING_PTR(buffer); + if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { + ossl_raise(eSPKIError, NULL); + } } NETSCAPE_SPKI_free(DATA_PTR(self)); SetSPKI(self, spki); @@ -115,11 +115,11 @@ ossl_spki_to_der(VALUE self) GetSPKI(self, spki); if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eSPKIError, "i2d_NETSCAPE_SPKI"); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_NETSCAPE_SPKI(spki, &p) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eSPKIError, "i2d_NETSCAPE_SPKI"); ossl_str_adjust(str, p); return str; @@ -140,7 +140,7 @@ ossl_spki_to_pem(VALUE self) GetSPKI(self, spki); if (!(data = NETSCAPE_SPKI_b64_encode(spki))) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } str = ossl_buf2str(data, rb_long2int(strlen(data))); @@ -162,11 +162,11 @@ ossl_spki_print(VALUE self) GetSPKI(self, spki); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } if (!NETSCAPE_SPKI_print(out, spki)) { - BIO_free(out); - ossl_raise(eSPKIError, NULL); + BIO_free(out); + ossl_raise(eSPKIError, NULL); } return ossl_membio2str(out); @@ -187,10 +187,10 @@ ossl_spki_get_public_key(VALUE self) GetSPKI(self, spki); if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */ - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } /* @@ -214,7 +214,7 @@ ossl_spki_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) - ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey"); + ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey"); return key; } @@ -230,13 +230,12 @@ ossl_spki_get_challenge(VALUE self) NETSCAPE_SPKI *spki; GetSPKI(self, spki); - if (spki->spkac->challenge->length <= 0) { - OSSL_Debug("Challenge.length <= 0?"); - return rb_str_new(0, 0); + if (ASN1_STRING_length(spki->spkac->challenge) <= 0) { + OSSL_Debug("Challenge.length <= 0?"); + return rb_str_new(0, 0); } - return rb_str_new((const char *)spki->spkac->challenge->data, - spki->spkac->challenge->length); + return asn1str_to_str(spki->spkac->challenge); } /* @@ -257,8 +256,8 @@ ossl_spki_set_challenge(VALUE self, VALUE str) StringValue(str); GetSPKI(self, spki); if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str), - RSTRING_LENINT(str))) { - ossl_raise(eSPKIError, NULL); + RSTRING_LENINT(str))) { + ossl_raise(eSPKIError, NULL); } return str; @@ -283,13 +282,13 @@ ossl_spki_sign(VALUE self, VALUE key, VALUE digest) NETSCAPE_SPKI *spki; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); GetSPKI(self, spki); - if (!NETSCAPE_SPKI_sign(spki, pkey, md)) { - ossl_raise(eSPKIError, NULL); - } + if (!NETSCAPE_SPKI_sign(spki, pkey, md)) + ossl_raise(eSPKIError, "NETSCAPE_SPKI_sign"); return self; } @@ -315,12 +314,12 @@ ossl_spki_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (NETSCAPE_SPKI_verify(spki, pkey)) { case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; case 1: - return Qtrue; + return Qtrue; default: - ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify"); + ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify"); } } @@ -365,8 +364,8 @@ ossl_spki_verify(VALUE self, VALUE key) * * OpenSSL::Netscape is a namespace for SPKI (Simple Public Key * Infrastructure) which implements Signed Public Key and Challenge. - * See {RFC 2692}[http://tools.ietf.org/html/rfc2692] and {RFC - * 2693}[http://tools.ietf.org/html/rfc2692] for details. + * See {RFC 2692}[https://www.rfc-editor.org/rfc/rfc2692] and {RFC + * 2693}[https://www.rfc-editor.org/rfc/rfc2692] for details. */ /* Document-class: OpenSSL::Netscape::SPKIError @@ -378,11 +377,6 @@ ossl_spki_verify(VALUE self, VALUE key) void Init_ossl_ns_spki(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - mNetscape = rb_define_module_under(mOSSL, "Netscape"); eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError); diff --git a/ext/openssl/ossl_ns_spki.h b/ext/openssl/ossl_ns_spki.h index 62ba8cb163..043b6cdb66 100644 --- a/ext/openssl/ossl_ns_spki.h +++ b/ext/openssl/ossl_ns_spki.h @@ -5,15 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_NS_SPKI_H_) #define _OSSL_NS_SPKI_H_ -extern VALUE mNetscape; -extern VALUE cSPKI; -extern VALUE eSPKIError; - void Init_ossl_ns_spki(void); #endif /* _OSSL_NS_SPKI_H_ */ diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index d4ca958a58..93d8bc8567 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -6,7 +6,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -67,13 +67,13 @@ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ } while (0) -VALUE mOCSP; -VALUE eOCSPError; -VALUE cOCSPReq; -VALUE cOCSPRes; -VALUE cOCSPBasicRes; -VALUE cOCSPSingleRes; -VALUE cOCSPCertId; +static VALUE mOCSP; +static VALUE eOCSPError; +static VALUE cOCSPReq; +static VALUE cOCSPRes; +static VALUE cOCSPBasicRes; +static VALUE cOCSPSingleRes; +static VALUE cOCSPCertId; static void ossl_ocsp_request_free(void *ptr) @@ -84,9 +84,9 @@ ossl_ocsp_request_free(void *ptr) static const rb_data_type_t ossl_ocsp_request_type = { "OpenSSL/OCSP/REQUEST", { - 0, ossl_ocsp_request_free, + 0, ossl_ocsp_request_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -98,9 +98,9 @@ ossl_ocsp_response_free(void *ptr) static const rb_data_type_t ossl_ocsp_response_type = { "OpenSSL/OCSP/RESPONSE", { - 0, ossl_ocsp_response_free, + 0, ossl_ocsp_response_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -112,9 +112,9 @@ ossl_ocsp_basicresp_free(void *ptr) static const rb_data_type_t ossl_ocsp_basicresp_type = { "OpenSSL/OCSP/BASICRESP", { - 0, ossl_ocsp_basicresp_free, + 0, ossl_ocsp_basicresp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -126,9 +126,9 @@ ossl_ocsp_singleresp_free(void *ptr) static const rb_data_type_t ossl_ocsp_singleresp_type = { "OpenSSL/OCSP/SINGLERESP", { - 0, ossl_ocsp_singleresp_free, + 0, ossl_ocsp_singleresp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -140,19 +140,23 @@ ossl_ocsp_certid_free(void *ptr) static const rb_data_type_t ossl_ocsp_certid_type = { "OpenSSL/OCSP/CERTID", { - 0, ossl_ocsp_certid_free, + 0, ossl_ocsp_certid_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* * Public */ static VALUE -ossl_ocspcertid_new(OCSP_CERTID *cid) +ossl_ocspcid_new(const OCSP_CERTID *cid) { VALUE obj = NewOCSPCertId(cOCSPCertId); - SetOCSPCertId(obj, cid); + /* OpenSSL 1.1.1 takes a non-const pointer */ + OCSP_CERTID *cid_new = OCSP_CERTID_dup((OCSP_CERTID *)cid); + if (!cid_new) + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + SetOCSPCertId(obj, cid_new); return obj; } @@ -167,12 +171,13 @@ ossl_ocspreq_alloc(VALUE klass) obj = NewOCSPReq(klass); if (!(req = OCSP_REQUEST_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPReq(obj, req); return obj; } +/* :nodoc: */ static VALUE ossl_ocspreq_initialize_copy(VALUE self, VALUE other) { @@ -184,7 +189,7 @@ ossl_ocspreq_initialize_copy(VALUE self, VALUE other) req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req); if (!req_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPReq(self, req_new); OCSP_REQUEST_free(req_old); @@ -210,15 +215,15 @@ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if(!NIL_P(arg)){ - GetOCSPReq(self, req); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg)); - if (!req_new) - ossl_raise(eOCSPError, "d2i_OCSP_REQUEST"); - SetOCSPReq(self, req_new); - OCSP_REQUEST_free(req); + GetOCSPReq(self, req); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg)); + if (!req_new) + ossl_raise(eOCSPError, "d2i_OCSP_REQUEST"); + SetOCSPReq(self, req_new); + OCSP_REQUEST_free(req); } return self; @@ -244,13 +249,13 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &val); if(NIL_P(val)) { - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, NULL, -1); + GetOCSPReq(self, req); + ret = OCSP_request_add1_nonce(req, NULL, -1); } else{ - StringValue(val); - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); + StringValue(val); + GetOCSPReq(self, req); + ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); } if(!ret) ossl_raise(eOCSPError, NULL); @@ -307,10 +312,10 @@ ossl_ocspreq_add_certid(VALUE self, VALUE certid) GetOCSPCertId(certid, id); if (!(id_new = OCSP_CERTID_dup(id))) - ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); if (!OCSP_request_add0_id(req, id_new)) { - OCSP_CERTID_free(id_new); - ossl_raise(eOCSPError, "OCSP_request_add0_id"); + OCSP_CERTID_free(id_new); + ossl_raise(eOCSPError, "OCSP_request_add0_id"); } return self; @@ -327,21 +332,19 @@ static VALUE ossl_ocspreq_get_certid(VALUE self) { OCSP_REQUEST *req; - OCSP_ONEREQ *one; - OCSP_CERTID *id; - VALUE ary, tmp; - int i, count; GetOCSPReq(self, req); - count = OCSP_request_onereq_count(req); - ary = (count > 0) ? rb_ary_new() : Qnil; - for(i = 0; i < count; i++){ - one = OCSP_request_onereq_get0(req, i); - tmp = NewOCSPCertId(cOCSPCertId); - if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one)))) - ossl_raise(eOCSPError, NULL); - SetOCSPCertId(tmp, id); - rb_ary_push(ary, tmp); + int count = OCSP_request_onereq_count(req); + if (count < 0) + ossl_raise(eOCSPError, "OCSP_request_onereq_count"); + if (count == 0) + return Qnil; + + VALUE ary = rb_ary_new_capa(count); + for (int i = 0; i < count; i++) { + OCSP_ONEREQ *one = OCSP_request_onereq_get0(req, i); + OCSP_CERTID *cid = OCSP_onereq_get0_id(one); + rb_ary_push(ary, ossl_ocspcid_new(cid)); } return ary; @@ -366,7 +369,7 @@ ossl_ocspreq_get_certid(VALUE self) static VALUE ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) { - VALUE signer_cert, signer_key, certs, flags, digest; + VALUE signer_cert, signer_key, certs, flags, digest, md_holder; OCSP_REQUEST *req; X509 *signer; EVP_PKEY *key; @@ -380,19 +383,17 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) signer = GetX509CertPtr(signer_cert); key = GetPrivPKeyPtr(signer_key); if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) - md = EVP_sha1(); - else - md = ossl_evp_get_digestbyname(digest); + flg = NUM2INT(flags); + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); if (NIL_P(certs)) - flg |= OCSP_NOCERTS; + flg |= OCSP_NOCERTS; else - x509s = ossl_x509_ary2sk(certs); + x509s = ossl_x509_ary2sk(certs); ret = OCSP_request_sign(req, signer, key, md, x509s, flg); sk_X509_pop_free(x509s, X509_free); - if (!ret) ossl_raise(eOCSPError, NULL); + if (!ret) + ossl_raise(eOCSPError, "OCSP_request_sign"); return self; } @@ -426,7 +427,7 @@ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self) result = OCSP_request_verify(req, x509s, x509st, flg); sk_X509_pop_free(x509s, X509_free); if (result <= 0) - ossl_clear_error(); + ossl_clear_error(); return result > 0 ? Qtrue : Qfalse; } @@ -445,11 +446,11 @@ ossl_ocspreq_to_der(VALUE self) GetOCSPReq(self, req); if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_OCSP_REQUEST(req, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -493,7 +494,7 @@ ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp) else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */ obj = NewOCSPRes(klass); if(!(res = OCSP_response_create(st, bs))) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPRes(obj, res); return obj; @@ -507,12 +508,13 @@ ossl_ocspres_alloc(VALUE klass) obj = NewOCSPRes(klass); if(!(res = OCSP_RESPONSE_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPRes(obj, res); return obj; } +/* :nodoc: */ static VALUE ossl_ocspres_initialize_copy(VALUE self, VALUE other) { @@ -524,7 +526,7 @@ ossl_ocspres_initialize_copy(VALUE self, VALUE other) res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res); if (!res_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPRes(self, res_new); OCSP_RESPONSE_free(res_old); @@ -550,15 +552,15 @@ ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if(!NIL_P(arg)){ - GetOCSPRes(self, res); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE"); - SetOCSPRes(self, res_new); - OCSP_RESPONSE_free(res); + GetOCSPRes(self, res); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg)); + if (!res_new) + ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE"); + SetOCSPRes(self, res_new); + OCSP_RESPONSE_free(res); } return self; @@ -619,7 +621,7 @@ ossl_ocspres_get_basic(VALUE self) GetOCSPRes(self, res); ret = NewOCSPBasicRes(cOCSPBasicRes); if(!(bs = OCSP_response_get1_basic(res))) - return Qnil; + return Qnil; SetOCSPBasicRes(ret, bs); return ret; @@ -642,11 +644,11 @@ ossl_ocspres_to_der(VALUE self) GetOCSPRes(self, res); if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_OCSP_RESPONSE(res, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -663,12 +665,13 @@ ossl_ocspbres_alloc(VALUE klass) obj = NewOCSPBasicRes(klass); if(!(bs = OCSP_BASICRESP_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPBasicRes(obj, bs); return obj; } +/* :nodoc: */ static VALUE ossl_ocspbres_initialize_copy(VALUE self, VALUE other) { @@ -680,7 +683,7 @@ ossl_ocspbres_initialize_copy(VALUE self, VALUE other) bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs); if (!bs_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPBasicRes(self, bs_new); OCSP_BASICRESP_free(bs_old); @@ -705,15 +708,15 @@ ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if (!NIL_P(arg)) { - GetOCSPBasicRes(self, res); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"); - SetOCSPBasicRes(self, res_new); - OCSP_BASICRESP_free(res); + GetOCSPBasicRes(self, res); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); + if (!res_new) + ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"); + SetOCSPBasicRes(self, res_new); + OCSP_BASICRESP_free(res); } return self; @@ -758,13 +761,13 @@ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &val); if(NIL_P(val)) { - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, NULL, -1); + GetOCSPBasicRes(self, bs); + ret = OCSP_basic_add1_nonce(bs, NULL, -1); } else{ - StringValue(val); - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); + StringValue(val); + GetOCSPBasicRes(self, bs); + ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); } if(!ret) ossl_raise(eOCSPError, NULL); @@ -777,12 +780,12 @@ add_status_convert_time(VALUE obj) ASN1_TIME *time; if (RB_INTEGER_TYPE_P(obj)) - time = X509_gmtime_adj(NULL, NUM2INT(obj)); + time = X509_gmtime_adj(NULL, NUM2INT(obj)); else - time = ossl_x509_time_adjust(NULL, obj); + time = ossl_x509_time_adjust(NULL, obj); if (!time) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); return (VALUE)time; } @@ -803,7 +806,7 @@ add_status_convert_time(VALUE obj) * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants. * _revocation_time_ is the time when the certificate is revoked. * - * _this_update_ and _next_update_ indicate the time at which ths status is + * _this_update_ and _next_update_ indicate the time at which the status is * verified to be correct and the time at or before which newer information * will be available, respectively. _next_update_ is optional. * @@ -816,8 +819,8 @@ add_status_convert_time(VALUE obj) */ static VALUE ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, - VALUE reason, VALUE revtime, - VALUE thisupd, VALUE nextupd, VALUE ext) + VALUE reason, VALUE revtime, + VALUE thisupd, VALUE nextupd, VALUE ext) { OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; @@ -831,16 +834,16 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, GetOCSPCertId(cid, id); st = NUM2INT(status); if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */ - ext = rb_check_array_type(ext); - for (i = 0; i < RARRAY_LEN(ext); i++) - OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext); + ext = rb_check_array_type(ext); + for (i = 0; i < RARRAY_LEN(ext); i++) + OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext); } if (st == V_OCSP_CERTSTATUS_REVOKED) { - rsn = NUM2INT(reason); - tmp = rb_protect(add_status_convert_time, revtime, &rstatus); - if (rstatus) goto err; - rev = (ASN1_TIME *)tmp; + rsn = NUM2INT(reason); + tmp = rb_protect(add_status_convert_time, revtime, &rstatus); + if (rstatus) goto err; + rev = (ASN1_TIME *)tmp; } tmp = rb_protect(add_status_convert_time, thisupd, &rstatus); @@ -848,29 +851,29 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, ths = (ASN1_TIME *)tmp; if (!NIL_P(nextupd)) { - tmp = rb_protect(add_status_convert_time, nextupd, &rstatus); - if (rstatus) goto err; - nxt = (ASN1_TIME *)tmp; + tmp = rb_protect(add_status_convert_time, nextupd, &rstatus); + if (rstatus) goto err; + nxt = (ASN1_TIME *)tmp; } if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ - error = 1; - goto err; + error = 1; + goto err; } if(!NIL_P(ext)){ - X509_EXTENSION *x509ext; - - for(i = 0; i < RARRAY_LEN(ext); i++){ - x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i)); - if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ - error = 1; - goto err; - } - } + X509_EXTENSION *x509ext; + + for(i = 0; i < RARRAY_LEN(ext); i++){ + x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i)); + if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ + error = 1; + goto err; + } + } } - err: + err: ASN1_TIME_free(ths); ASN1_TIME_free(nxt); ASN1_TIME_free(rev); @@ -896,48 +899,40 @@ static VALUE ossl_ocspbres_get_status(VALUE self) { OCSP_BASICRESP *bs; - OCSP_SINGLERESP *single; - OCSP_CERTID *cid; - ASN1_TIME *revtime, *thisupd, *nextupd; - int status, reason; - X509_EXTENSION *x509ext; - VALUE ret, ary, ext; - int count, ext_count, i, j; GetOCSPBasicRes(self, bs); - ret = rb_ary_new(); - count = OCSP_resp_count(bs); - for(i = 0; i < count; i++){ - single = OCSP_resp_get0(bs, i); - if(!single) continue; - - revtime = thisupd = nextupd = NULL; - status = OCSP_single_get0_status(single, &reason, &revtime, - &thisupd, &nextupd); - if(status < 0) continue; - if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */ - ossl_raise(eOCSPError, NULL); - ary = rb_ary_new(); - rb_ary_push(ary, ossl_ocspcertid_new(cid)); - rb_ary_push(ary, INT2NUM(status)); - rb_ary_push(ary, INT2NUM(reason)); - rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); - rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); - rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); - ext = rb_ary_new(); - ext_count = OCSP_SINGLERESP_get_ext_count(single); - for(j = 0; j < ext_count; j++){ - x509ext = OCSP_SINGLERESP_get_ext(single, j); - rb_ary_push(ext, ossl_x509ext_new(x509ext)); - } - rb_ary_push(ary, ext); - rb_ary_push(ret, ary); + VALUE ret = rb_ary_new(); + int count = OCSP_resp_count(bs); + for (int i = 0; i < count; i++) { + OCSP_SINGLERESP *single = OCSP_resp_get0(bs, i); + ASN1_TIME *revtime, *thisupd, *nextupd; + int reason; + + int status = OCSP_single_get0_status(single, &reason, &revtime, &thisupd, &nextupd); + if (status < 0) + ossl_raise(eOCSPError, "OCSP_single_get0_status"); + + VALUE ary = rb_ary_new(); + rb_ary_push(ary, ossl_ocspcid_new(OCSP_SINGLERESP_get0_id(single))); + rb_ary_push(ary, INT2NUM(status)); + rb_ary_push(ary, INT2NUM(reason)); + rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); + rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); + rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); + VALUE ext = rb_ary_new(); + int ext_count = OCSP_SINGLERESP_get_ext_count(single); + for (int j = 0; j < ext_count; j++) { + X509_EXTENSION *x509ext = OCSP_SINGLERESP_get_ext(single, j); + rb_ary_push(ext, ossl_x509ext_new(x509ext)); + } + rb_ary_push(ary, ext); + rb_ary_push(ret, ary); } return ret; } -static VALUE ossl_ocspsres_new(OCSP_SINGLERESP *); +static VALUE ossl_ocspsres_new(const OCSP_SINGLERESP *); /* * call-seq: @@ -955,17 +950,10 @@ ossl_ocspbres_get_responses(VALUE self) GetOCSPBasicRes(self, bs); count = OCSP_resp_count(bs); - ret = rb_ary_new2(count); + ret = rb_ary_new_capa(count); for (i = 0; i < count; i++) { - OCSP_SINGLERESP *sres, *sres_new; - - sres = OCSP_resp_get0(bs, i); - sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); - if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); - - rb_ary_push(ret, ossl_ocspsres_new(sres_new)); + rb_ary_push(ret, ossl_ocspsres_new(OCSP_resp_get0(bs, i))); } return ret; @@ -983,7 +971,6 @@ static VALUE ossl_ocspbres_find_response(VALUE self, VALUE target) { OCSP_BASICRESP *bs; - OCSP_SINGLERESP *sres, *sres_new; OCSP_CERTID *id; int n; @@ -991,14 +978,8 @@ ossl_ocspbres_find_response(VALUE self, VALUE target) GetOCSPBasicRes(self, bs); if ((n = OCSP_resp_find(bs, id, -1)) == -1) - return Qnil; - - sres = OCSP_resp_get0(bs, n); - sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); - if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); - - return ossl_ocspsres_new(sres_new); + return Qnil; + return ossl_ocspsres_new(OCSP_resp_get0(bs, n)); } /* @@ -1017,7 +998,7 @@ ossl_ocspbres_find_response(VALUE self, VALUE target) static VALUE ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) { - VALUE signer_cert, signer_key, certs, flags, digest; + VALUE signer_cert, signer_key, certs, flags, digest, md_holder; OCSP_BASICRESP *bs; X509 *signer; EVP_PKEY *key; @@ -1031,19 +1012,17 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) signer = GetX509CertPtr(signer_cert); key = GetPrivPKeyPtr(signer_key); if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) - md = EVP_sha1(); - else - md = ossl_evp_get_digestbyname(digest); + flg = NUM2INT(flags); + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); if (NIL_P(certs)) - flg |= OCSP_NOCERTS; + flg |= OCSP_NOCERTS; else - x509s = ossl_x509_ary2sk(certs); + x509s = ossl_x509_ary2sk(certs); ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg); sk_X509_pop_free(x509s, X509_free); - if (!ret) ossl_raise(eOCSPError, NULL); + if (!ret) + ossl_raise(eOCSPError, "OCSP_basic_sign"); return self; } @@ -1072,7 +1051,7 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self) result = OCSP_basic_verify(bs, x509s, x509st, flg); sk_X509_pop_free(x509s, X509_free); if (result <= 0) - ossl_clear_error(); + ossl_clear_error(); return result > 0 ? Qtrue : Qfalse; } @@ -1093,11 +1072,11 @@ ossl_ocspbres_to_der(VALUE self) GetOCSPBasicRes(self, res); if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_BASICRESP(res, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1107,12 +1086,18 @@ ossl_ocspbres_to_der(VALUE self) * OCSP::SingleResponse */ static VALUE -ossl_ocspsres_new(OCSP_SINGLERESP *sres) +ossl_ocspsres_new(const OCSP_SINGLERESP *sres) { VALUE obj; + OCSP_SINGLERESP *sres_new; obj = NewOCSPSingleRes(cOCSPSingleRes); - SetOCSPSingleRes(obj, sres); + /* OpenSSL 1.1.1 takes a non-const pointer */ + sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), + (OCSP_SINGLERESP *)sres); + if (!sres_new) + ossl_raise(eOCSPError, "ASN1_item_dup"); + SetOCSPSingleRes(obj, sres_new); return obj; } @@ -1125,7 +1110,7 @@ ossl_ocspsres_alloc(VALUE klass) obj = NewOCSPSingleRes(klass); if (!(sres = OCSP_SINGLERESP_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPSingleRes(obj, sres); return obj; @@ -1150,13 +1135,14 @@ ossl_ocspsres_initialize(VALUE self, VALUE arg) p = (unsigned char*)RSTRING_PTR(arg); res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg)); if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP"); + ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP"); SetOCSPSingleRes(self, res_new); OCSP_SINGLERESP_free(res); return self; } +/* :nodoc: */ static VALUE ossl_ocspsres_initialize_copy(VALUE self, VALUE other) { @@ -1168,7 +1154,7 @@ ossl_ocspsres_initialize_copy(VALUE self, VALUE other) sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPSingleRes(self, sres_new); OCSP_SINGLERESP_free(sres_old); @@ -1207,15 +1193,15 @@ ossl_ocspsres_check_validity(int argc, VALUE *argv, VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, &this_update, &next_update); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); ret = OCSP_check_validity(this_update, next_update, nsec, maxsec); if (ret) - return Qtrue; + return Qtrue; else { - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; } } @@ -1229,12 +1215,9 @@ static VALUE ossl_ocspsres_get_certid(VALUE self) { OCSP_SINGLERESP *sres; - OCSP_CERTID *id; GetOCSPSingleRes(self, sres); - id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */ - - return ossl_ocspcertid_new(id); + return ossl_ocspcid_new(OCSP_SINGLERESP_get0_id(sres)); } /* @@ -1260,7 +1243,7 @@ ossl_ocspsres_get_cert_status(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); return INT2NUM(status); } @@ -1279,9 +1262,9 @@ ossl_ocspsres_get_this_update(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1300,9 +1283,9 @@ ossl_ocspsres_get_next_update(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1321,11 +1304,11 @@ ossl_ocspsres_get_revocation_time(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, &time, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (status != V_OCSP_CERTSTATUS_REVOKED) - ossl_raise(eOCSPError, "certificate is not revoked"); + ossl_raise(eOCSPError, "certificate is not revoked"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1343,9 +1326,9 @@ ossl_ocspsres_get_revocation_reason(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, &reason, NULL, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (status != V_OCSP_CERTSTATUS_REVOKED) - ossl_raise(eOCSPError, "certificate is not revoked"); + ossl_raise(eOCSPError, "certificate is not revoked"); return INT2NUM(reason); } @@ -1367,8 +1350,8 @@ ossl_ocspsres_get_extensions(VALUE self) count = OCSP_SINGLERESP_get_ext_count(sres); ary = rb_ary_new2(count); for (i = 0; i < count; i++) { - ext = OCSP_SINGLERESP_get_ext(sres, i); - rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */ + ext = OCSP_SINGLERESP_get_ext(sres, i); + rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */ } return ary; @@ -1390,11 +1373,11 @@ ossl_ocspsres_to_der(VALUE self) GetOCSPSingleRes(self, sres); if ((len = i2d_OCSP_SINGLERESP(sres, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_SINGLERESP(sres, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1412,12 +1395,13 @@ ossl_ocspcid_alloc(VALUE klass) obj = NewOCSPCertId(klass); if(!(id = OCSP_CERTID_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPCertId(obj, id); return obj; } +/* :nodoc: */ static VALUE ossl_ocspcid_initialize_copy(VALUE self, VALUE other) { @@ -1429,7 +1413,7 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other) cid_new = OCSP_CERTID_dup(cid); if (!cid_new) - ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); SetOCSPCertId(self, cid_new); OCSP_CERTID_free(cid_old); @@ -1459,27 +1443,28 @@ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) GetOCSPCertId(self, id); if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) { - VALUE arg; - const unsigned char *p; - - arg = ossl_to_der_if_possible(subject); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg)); - if (!newid) - ossl_raise(eOCSPError, "d2i_OCSP_CERTID"); + VALUE arg; + const unsigned char *p; + + arg = ossl_to_der_if_possible(subject); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg)); + if (!newid) + ossl_raise(eOCSPError, "d2i_OCSP_CERTID"); } else { - X509 *x509s, *x509i; - const EVP_MD *md; + X509 *x509s, *x509i; + const EVP_MD *md; + VALUE md_holder; - x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ - x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ - md = !NIL_P(digest) ? ossl_evp_get_digestbyname(digest) : NULL; + x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ + x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); - newid = OCSP_cert_to_id(md, x509s, x509i); - if (!newid) - ossl_raise(eOCSPError, "OCSP_cert_to_id"); + newid = OCSP_cert_to_id(md, x509s, x509i); + if (!newid) + ossl_raise(eOCSPError, "OCSP_cert_to_id"); } SetOCSPCertId(self, newid); @@ -1565,8 +1550,9 @@ ossl_ocspcid_get_issuer_name_hash(VALUE self) GetOCSPCertId(self, id); OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id); - ret = rb_str_new(NULL, name_hash->length * 2); - ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length); + ret = rb_str_new(NULL, ASN1_STRING_length(name_hash) * 2); + ossl_bin2hex(ASN1_STRING_get0_data(name_hash), RSTRING_PTR(ret), + ASN1_STRING_length(name_hash)); return ret; } @@ -1588,8 +1574,9 @@ ossl_ocspcid_get_issuer_key_hash(VALUE self) GetOCSPCertId(self, id); OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id); - ret = rb_str_new(NULL, key_hash->length * 2); - ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length); + ret = rb_str_new(NULL, ASN1_STRING_length(key_hash) * 2); + ossl_bin2hex(ASN1_STRING_get0_data(key_hash), RSTRING_PTR(ret), + ASN1_STRING_length(key_hash)); return ret; } @@ -1606,19 +1593,10 @@ ossl_ocspcid_get_hash_algorithm(VALUE self) { OCSP_CERTID *id; ASN1_OBJECT *oid; - BIO *out; GetOCSPCertId(self, id); OCSP_id_get0_info(NULL, &oid, NULL, NULL, id); - - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eOCSPError, "BIO_new"); - - if (!i2a_ASN1_OBJECT(out, oid)) { - BIO_free(out); - ossl_raise(eOCSPError, "i2a_ASN1_OBJECT"); - } - return ossl_membio2str(out); + return ossl_asn1obj_to_string_long_name(oid); } /* @@ -1637,11 +1615,11 @@ ossl_ocspcid_to_der(VALUE self) GetOCSPCertId(self, id); if ((len = i2d_OCSP_CERTID(id, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_CERTID(id, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1650,11 +1628,6 @@ ossl_ocspcid_to_der(VALUE self) void Init_ossl_ocsp(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * OpenSSL::OCSP implements Online Certificate Status Protocol requests * and responses. @@ -1701,7 +1674,7 @@ Init_ossl_ocsp(void) * require 'net/http' * * http_response = - * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http| + * Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http| * http.post ocsp_uri.path, request.to_der, * 'content-type' => 'application/ocsp-request' * end diff --git a/ext/openssl/ossl_ocsp.h b/ext/openssl/ossl_ocsp.h index 6d2aac8657..becd70ffed 100644 --- a/ext/openssl/ossl_ocsp.h +++ b/ext/openssl/ossl_ocsp.h @@ -6,18 +6,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OCSP_H_) #define _OSSL_OCSP_H_ -#if !defined(OPENSSL_NO_OCSP) -extern VALUE mOCSP; -extern VALUE cOCSPReq; -extern VALUE cOCSPRes; -extern VALUE cOCSPBasicRes; -#endif - void Init_ossl_ocsp(void); #endif /* _OSSL_OCSP_H_ */ diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index fb947df1d0..32b82a881c 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -1,6 +1,6 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -27,8 +27,8 @@ /* * Classes */ -VALUE cPKCS12; -VALUE ePKCS12Error; +static VALUE cPKCS12; +static VALUE ePKCS12Error; /* * Private @@ -42,9 +42,9 @@ ossl_pkcs12_free(void *ptr) static const rb_data_type_t ossl_pkcs12_type = { "OpenSSL/PKCS12", { - 0, ossl_pkcs12_free, + 0, ossl_pkcs12_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -60,6 +60,7 @@ ossl_pkcs12_s_allocate(VALUE klass) return obj; } +/* :nodoc: */ static VALUE ossl_pkcs12_initialize_copy(VALUE self, VALUE other) { @@ -71,7 +72,7 @@ ossl_pkcs12_initialize_copy(VALUE self, VALUE other) p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12); if (!p12_new) - ossl_raise(ePKCS12Error, "ASN1_dup"); + ossl_raise(ePKCS12Error, "ASN1_dup"); SetPKCS12(self, p12_new); PKCS12_free(p12_old); @@ -121,11 +122,11 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) /* TODO: make a VALUE to nid function */ if (!NIL_P(key_nid)) { if ((nkey = OBJ_txt2nid(StringValueCStr(key_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid); + ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid); } if (!NIL_P(cert_nid)) { if ((ncert = OBJ_txt2nid(StringValueCStr(cert_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid); + ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid); } if (!NIL_P(key_iter)) kiter = NUM2INT(key_iter); @@ -134,6 +135,16 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) if (!NIL_P(keytype)) ktype = NUM2INT(keytype); +#if defined(OPENSSL_IS_AWSLC) + if (ktype != 0) { + ossl_raise(rb_eArgError, "Unknown key usage type %"PRIsVALUE, INT2NUM(ktype)); + } +#else + if (ktype != 0 && ktype != KEY_SIG && ktype != KEY_EX) { + ossl_raise(rb_eArgError, "Unknown key usage type %"PRIsVALUE, INT2NUM(ktype)); + } +#endif + obj = NewPKCS12(cPKCS12); x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, @@ -150,9 +161,9 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) } static VALUE -ossl_pkey_new_i(VALUE arg) +ossl_pkey_wrap_i(VALUE arg) { - return ossl_pkey_new((EVP_PKEY *)arg); + return ossl_pkey_wrap((EVP_PKEY *)arg); } static VALUE @@ -197,23 +208,19 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) BIO_free(in); pkey = cert = ca = Qnil; - /* OpenSSL's bug; PKCS12_parse() puts errors even if it succeeds. - * Fixed in OpenSSL 1.0.0t, 1.0.1p, 1.0.2d */ - ERR_set_mark(); if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) - ossl_raise(ePKCS12Error, "PKCS12_parse"); - ERR_pop_to_mark(); + ossl_raise(ePKCS12Error, "PKCS12_parse"); if (key) { - pkey = rb_protect(ossl_pkey_new_i, (VALUE)key, &st); - if (st) goto err; + pkey = rb_protect(ossl_pkey_wrap_i, (VALUE)key, &st); + if (st) goto err; } if (x509) { - cert = rb_protect(ossl_x509_new_i, (VALUE)x509, &st); - if (st) goto err; + cert = rb_protect(ossl_x509_new_i, (VALUE)x509, &st); + if (st) goto err; } if (x509s) { - ca = rb_protect(ossl_x509_sk2ary_i, (VALUE)x509s, &st); - if (st) goto err; + ca = rb_protect(ossl_x509_sk2ary_i, (VALUE)x509s, &st); + if (st) goto err; } err: @@ -237,25 +244,62 @@ ossl_pkcs12_to_der(VALUE self) GetPKCS12(self, p12); if((len = i2d_PKCS12(p12, NULL)) <= 0) - ossl_raise(ePKCS12Error, NULL); + ossl_raise(ePKCS12Error, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_PKCS12(p12, &p) <= 0) - ossl_raise(ePKCS12Error, NULL); + ossl_raise(ePKCS12Error, NULL); ossl_str_adjust(str, p); return str; } +/* + * call-seq: + * pkcs12.set_mac(pass, salt = nil, iter = nil, md_type = nil) + * + * Sets MAC parameters and generates MAC over the PKCS #12 structure. + * + * This method uses HMAC and the PKCS #12 specific password-based KDF as + * specified in the original PKCS #12. + * + * See also the man page PKCS12_set_mac(3). + * + * Added in version 3.3.0. + */ +static VALUE +pkcs12_set_mac(int argc, VALUE *argv, VALUE self) +{ + PKCS12 *p12; + VALUE pass, salt, iter, md_name, md_holder = Qnil; + int iter_i = 0; + const EVP_MD *md_type = NULL; + + rb_scan_args(argc, argv, "13", &pass, &salt, &iter, &md_name); + rb_check_frozen(self); + GetPKCS12(self, p12); + + StringValue(pass); + if (!NIL_P(salt)) + StringValue(salt); + if (!NIL_P(iter)) + iter_i = NUM2INT(iter); + if (!NIL_P(md_name)) + md_type = ossl_evp_md_fetch(md_name, &md_holder); + + if (!PKCS12_set_mac(p12, RSTRING_PTR(pass), RSTRING_LENINT(pass), + !NIL_P(salt) ? (unsigned char *)RSTRING_PTR(salt) : NULL, + !NIL_P(salt) ? RSTRING_LENINT(salt) : 0, + iter_i, md_type)) + ossl_raise(ePKCS12Error, "PKCS12_set_mac"); + + return Qnil; +} + void Init_ossl_pkcs12(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Defines a file format commonly used to store private keys with * accompanying public key certificates, protected with a password-based @@ -272,4 +316,11 @@ Init_ossl_pkcs12(void) rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse); rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1); rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0); + rb_define_method(cPKCS12, "set_mac", pkcs12_set_mac, -1); + +#if !defined(OPENSSL_IS_AWSLC) + /* MSIE specific PKCS12 key usage extensions */ + rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX)); + rb_define_const(cPKCS12, "KEY_SIG", INT2NUM(KEY_SIG)); +#endif } diff --git a/ext/openssl/ossl_pkcs12.h b/ext/openssl/ossl_pkcs12.h index fe4f15ef60..6d2cd901cb 100644 --- a/ext/openssl/ossl_pkcs12.h +++ b/ext/openssl/ossl_pkcs12.h @@ -1,13 +1,10 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS12_H_) #define _OSSL_PKCS12_H_ -extern VALUE cPKCS12; -extern VALUE ePKCS12Error; - void Init_ossl_pkcs12(void); #endif /* _OSSL_PKCS12_H_ */ diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index dbe5347639..6e51fd42b9 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -5,22 +5,37 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +#define NewPKCS7(klass) \ + TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0) +#define SetPKCS7(obj, pkcs7) do { \ + if (!(pkcs7)) { \ + ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (pkcs7); \ +} while (0) +#define GetPKCS7(obj, pkcs7) do { \ + TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \ + if (!(pkcs7)) { \ + ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ + } \ +} while (0) + #define NewPKCS7si(klass) \ TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0) #define SetPKCS7si(obj, p7si) do { \ if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (p7si); \ } while (0) #define GetPKCS7si(obj, p7si) do { \ TypedData_Get_Struct((obj), PKCS7_SIGNER_INFO, &ossl_pkcs7_signer_info_type, (p7si)); \ if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ } while (0) @@ -28,14 +43,14 @@ TypedData_Wrap_Struct((klass), &ossl_pkcs7_recip_info_type, 0) #define SetPKCS7ri(obj, p7ri) do { \ if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (p7ri); \ } while (0) #define GetPKCS7ri(obj, p7ri) do { \ TypedData_Get_Struct((obj), PKCS7_RECIP_INFO, &ossl_pkcs7_recip_info_type, (p7ri)); \ if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ } while (0) @@ -49,10 +64,11 @@ /* * Classes */ -VALUE cPKCS7; -VALUE cPKCS7Signer; -VALUE cPKCS7Recipient; -VALUE ePKCS7Error; +static VALUE cPKCS7; +static VALUE cPKCS7Signer; +static VALUE cPKCS7Recipient; +static VALUE ePKCS7Error; +static ID id_md_holder, id_cipher_holder; static void ossl_pkcs7_free(void *ptr) @@ -60,14 +76,28 @@ ossl_pkcs7_free(void *ptr) PKCS7_free(ptr); } -const rb_data_type_t ossl_pkcs7_type = { +static const rb_data_type_t ossl_pkcs7_type = { "OpenSSL/PKCS7", { - 0, ossl_pkcs7_free, + 0, ossl_pkcs7_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +VALUE +ossl_pkcs7_new(PKCS7 *p7) +{ + PKCS7 *new; + VALUE obj = NewPKCS7(cPKCS7); + + new = PKCS7_dup(p7); + if (!new) + ossl_raise(ePKCS7Error, "PKCS7_dup"); + SetPKCS7(obj, new); + + return obj; +} + static void ossl_pkcs7_signer_info_free(void *ptr) { @@ -77,9 +107,9 @@ ossl_pkcs7_signer_info_free(void *ptr) static const rb_data_type_t ossl_pkcs7_signer_info_type = { "OpenSSL/PKCS7/SIGNER_INFO", { - 0, ossl_pkcs7_signer_info_free, + 0, ossl_pkcs7_signer_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -91,9 +121,9 @@ ossl_pkcs7_recip_info_free(void *ptr) static const rb_data_type_t ossl_pkcs7_recip_info_type = { "OpenSSL/PKCS7/RECIP_INFO", { - 0, ossl_pkcs7_recip_info_free, + 0, ossl_pkcs7_recip_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -114,23 +144,32 @@ ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si) } static PKCS7_RECIP_INFO * -ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *si) +ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *ri) { - return ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, - (d2i_of_void *)d2i_PKCS7_RECIP_INFO, - si); + PKCS7_RECIP_INFO *ri_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, + (d2i_of_void *)d2i_PKCS7_RECIP_INFO, + ri); + if (ri_new && ri->cert) { + if (!X509_up_ref(ri->cert)) { + PKCS7_RECIP_INFO_free(ri_new); + return NULL; + } + ri_new->cert = ri->cert; + } + return ri_new; } static VALUE ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) { - PKCS7_SIGNER_INFO *pkcs7; + PKCS7_SIGNER_INFO *p7si_new; VALUE obj; obj = NewPKCS7si(cPKCS7Signer); - pkcs7 = p7si ? ossl_PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - SetPKCS7si(obj, pkcs7); + p7si_new = ossl_PKCS7_SIGNER_INFO_dup(p7si); + if (!p7si_new) + ossl_raise(ePKCS7Error, "ASN1_dup"); + SetPKCS7si(obj, p7si_new); return obj; } @@ -138,13 +177,14 @@ ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) static VALUE ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri) { - PKCS7_RECIP_INFO *pkcs7; + PKCS7_RECIP_INFO *p7ri_new; VALUE obj; obj = NewPKCS7ri(cPKCS7Recipient); - pkcs7 = p7ri ? ossl_PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - SetPKCS7ri(obj, pkcs7); + p7ri_new = ossl_PKCS7_RECIP_INFO_dup(p7ri); + if (!p7ri_new) + ossl_raise(ePKCS7Error,"ASN1_dup"); + SetPKCS7ri(obj, p7ri_new); return obj; } @@ -165,7 +205,13 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) out = NULL; pkcs7 = SMIME_read_PKCS7(in, &out); BIO_free(in); - if(!pkcs7) ossl_raise(ePKCS7Error, NULL); + if (!pkcs7) + ossl_raise(ePKCS7Error, "Could not parse the PKCS7"); + if (!pkcs7->d.ptr) { + PKCS7_free(pkcs7); + ossl_raise(ePKCS7Error, "No content in PKCS7"); + } + data = out ? ossl_membio2str(out) : Qnil; SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); @@ -192,7 +238,7 @@ ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass) if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7); GetPKCS7(pkcs7, p7); if(!NIL_P(data) && PKCS7_is_detached(p7)) - flg |= PKCS7_DETACHED; + flg |= PKCS7_DETACHED; in = NIL_P(data) ? NULL : ossl_obj2bio(&data); if(!(out = BIO_new(BIO_s_mem()))){ BIO_free(in); @@ -233,16 +279,16 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) in = ossl_obj2bio(&data); if(NIL_P(certs)) x509s = NULL; else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } + x509s = ossl_protect_x509_ary2sk(certs, &status); + if(status){ + BIO_free(in); + rb_jump_tag(status); + } } if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); @@ -255,12 +301,19 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7 + * PKCS7.encrypt(certs, data, cipher, flags = 0) => pkcs7 + * + * Creates a PKCS #7 enveloped-data structure. + * + * Before version 3.3.0, +cipher+ was optional and defaulted to + * <tt>"RC2-40-CBC"</tt>. + * + * See also the man page PKCS7_encrypt(3). */ static VALUE ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) { - VALUE certs, data, cipher, flags; + VALUE certs, data, cipher, flags, cipher_holder; STACK_OF(X509) *x509s; BIO *in; const EVP_CIPHER *ciph; @@ -269,37 +322,29 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) PKCS7 *p7; rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags); - if(NIL_P(cipher)){ -#if !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_DES) - ciph = EVP_des_ede3_cbc(); -#elif !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_AES) - ciph = EVP_EVP_aes_128_cbc(); -#else - ossl_raise(ePKCS7Error, "Must specify cipher"); -#endif - + if (NIL_P(cipher)) { + rb_raise(rb_eArgError, + "cipher must be specified. Before version 3.3, " \ + "the default cipher was RC2-40-CBC."); } - else ciph = ossl_evp_get_cipherbyname(cipher); + ciph = ossl_evp_cipher_fetch(cipher, &cipher_holder); flg = NIL_P(flags) ? 0 : NUM2INT(flags); ret = NewPKCS7(cPKCS7); in = ossl_obj2bio(&data); x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ - BIO_free(in); - rb_jump_tag(status); + BIO_free(in); + rb_jump_tag(status); } - if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + if (!(p7 = PKCS7_encrypt(x509s, in, ciph, flg))) { + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } BIO_free(in); SetPKCS7(ret, p7); ossl_pkcs7_set_data(ret, data); + rb_ivar_set(ret, id_cipher_holder, cipher_holder); sk_X509_pop_free(x509s, X509_free); return ret; @@ -313,7 +358,7 @@ ossl_pkcs7_alloc(VALUE klass) obj = NewPKCS7(klass); if (!(pkcs7 = PKCS7_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7(obj, pkcs7); @@ -335,7 +380,7 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) - return self; + return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); p7 = d2i_PKCS7_bio(in, NULL); @@ -345,7 +390,11 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) } BIO_free(in); if (!p7) - ossl_raise(rb_eArgError, "Could not parse the PKCS7"); + ossl_raise(ePKCS7Error, "Could not parse the PKCS7"); + if (!p7->d.ptr) { + PKCS7_free(p7); + ossl_raise(ePKCS7Error, "No content in PKCS7"); + } RTYPEDDATA_DATA(self) = p7; PKCS7_free(p7_orig); @@ -355,6 +404,7 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_pkcs7_copy(VALUE self, VALUE other) { @@ -368,7 +418,7 @@ ossl_pkcs7_copy(VALUE self, VALUE other) pkcs7 = PKCS7_dup(b); if (!pkcs7) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } DATA_PTR(self) = pkcs7; PKCS7_free(a); @@ -400,13 +450,13 @@ ossl_pkcs7_sym2typeid(VALUE sym) RSTRING_GETMEM(sym, s, l); for(i = 0; ; i++){ - if(i == numberof(p7_type_tab)) - ossl_raise(ePKCS7Error, "unknown type \"%"PRIsVALUE"\"", sym); - if(strlen(p7_type_tab[i].name) != l) continue; - if(strcmp(p7_type_tab[i].name, s) == 0){ - ret = p7_type_tab[i].nid; - break; - } + if(i == numberof(p7_type_tab)) + ossl_raise(ePKCS7Error, "unknown type \"%"PRIsVALUE"\"", sym); + if(strlen(p7_type_tab[i].name) != l) continue; + if(strcmp(p7_type_tab[i].name, s) == 0){ + ret = p7_type_tab[i].nid; + break; + } } return ret; @@ -423,7 +473,7 @@ ossl_pkcs7_set_type(VALUE self, VALUE type) GetPKCS7(self, p7); if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type))) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); return type; } @@ -439,15 +489,15 @@ ossl_pkcs7_get_type(VALUE self) GetPKCS7(self, p7); if(PKCS7_type_is_signed(p7)) - return ID2SYM(rb_intern("signed")); + return ID2SYM(rb_intern("signed")); if(PKCS7_type_is_encrypted(p7)) - return ID2SYM(rb_intern("encrypted")); + return ID2SYM(rb_intern("encrypted")); if(PKCS7_type_is_enveloped(p7)) - return ID2SYM(rb_intern("enveloped")); + return ID2SYM(rb_intern("enveloped")); if(PKCS7_type_is_signedAndEnveloped(p7)) - return ID2SYM(rb_intern("signedAndEnveloped")); + return ID2SYM(rb_intern("signedAndEnveloped")); if(PKCS7_type_is_data(p7)) - return ID2SYM(rb_intern("data")); + return ID2SYM(rb_intern("data")); return Qnil; } @@ -458,9 +508,9 @@ ossl_pkcs7_set_detached(VALUE self, VALUE flag) GetPKCS7(self, p7); if(flag != Qtrue && flag != Qfalse) - ossl_raise(ePKCS7Error, "must specify a boolean"); + ossl_raise(ePKCS7Error, "must specify a boolean"); if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0)) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); return flag; } @@ -470,6 +520,8 @@ ossl_pkcs7_get_detached(VALUE self) { PKCS7 *p7; GetPKCS7(self, p7); + if (!PKCS7_type_is_signed(p7)) + return Qfalse; return PKCS7_get_detached(p7) ? Qtrue : Qfalse; } @@ -485,11 +537,14 @@ static VALUE ossl_pkcs7_set_cipher(VALUE self, VALUE cipher) { PKCS7 *pkcs7; + const EVP_CIPHER *ciph; + VALUE cipher_holder; GetPKCS7(self, pkcs7); - if (!PKCS7_set_cipher(pkcs7, ossl_evp_get_cipherbyname(cipher))) { - ossl_raise(ePKCS7Error, NULL); - } + ciph = ossl_evp_cipher_fetch(cipher, &cipher_holder); + if (!PKCS7_set_cipher(pkcs7, ciph)) + ossl_raise(ePKCS7Error, "PKCS7_set_cipher"); + rb_ivar_set(self, id_cipher_holder, cipher_holder); return cipher; } @@ -520,22 +575,17 @@ ossl_pkcs7_get_signer(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_SIGNER_INFO) *sk; - PKCS7_SIGNER_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); - if (!(sk = PKCS7_get_signer_info(pkcs7))) { - OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!"); - return rb_ary_new(); - } - if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of signers!"); - } - ary = rb_ary_new2(num); + if (!(sk = PKCS7_get_signer_info(pkcs7))) + return rb_ary_new(); + num = sk_PKCS7_SIGNER_INFO_num(sk); + ary = rb_ary_new_capa(num); for (i=0; i<num; i++) { - si = sk_PKCS7_SIGNER_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7si_new(si)); + PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sk, i); + rb_ary_push(ary, ossl_pkcs7si_new(si)); } return ary; @@ -567,24 +617,21 @@ ossl_pkcs7_get_recipient(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_RECIP_INFO) *sk; - PKCS7_RECIP_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); if (PKCS7_type_is_enveloped(pkcs7)) - sk = pkcs7->d.enveloped->recipientinfo; + sk = pkcs7->d.enveloped->recipientinfo; else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) - sk = pkcs7->d.signed_and_enveloped->recipientinfo; + sk = pkcs7->d.signed_and_enveloped->recipientinfo; else sk = NULL; if (!sk) return rb_ary_new(); - if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of recipient!"); - } - ary = rb_ary_new2(num); + num = sk_PKCS7_RECIP_INFO_num(sk); + ary = rb_ary_new_capa(num); for (i=0; i<num; i++) { - si = sk_PKCS7_RECIP_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7ri_new(si)); + PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(sk, i); + rb_ary_push(ary, ossl_pkcs7ri_new(ri)); } return ary; @@ -599,7 +646,7 @@ ossl_pkcs7_add_certificate(VALUE self, VALUE cert) GetPKCS7(self, pkcs7); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ if (!PKCS7_add_certificate(pkcs7, x509)){ - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -615,13 +662,13 @@ pkcs7_get_certs(VALUE self) GetPKCS7(self, pkcs7); i = OBJ_obj2nid(pkcs7->type); switch(i){ - case NID_pkcs7_signed: + case NID_pkcs7_signed: certs = pkcs7->d.sign->cert; break; - case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_signedAndEnveloped: certs = pkcs7->d.signed_and_enveloped->cert; break; - default: + default: certs = NULL; } @@ -638,13 +685,13 @@ pkcs7_get_crls(VALUE self) GetPKCS7(self, pkcs7); i = OBJ_obj2nid(pkcs7->type); switch(i){ - case NID_pkcs7_signed: + case NID_pkcs7_signed: crls = pkcs7->d.sign->crl; break; - case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_signedAndEnveloped: crls = pkcs7->d.signed_and_enveloped->crl; break; - default: + default: crls = NULL; } @@ -664,7 +711,10 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) X509 *cert; certs = pkcs7_get_certs(self); - while((cert = sk_X509_pop(certs))) X509_free(cert); + if (certs) { + while ((cert = sk_X509_pop(certs))) + X509_free(cert); + } rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self); return ary; @@ -673,7 +723,10 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_certificates(VALUE self) { - return ossl_x509_sk2ary(pkcs7_get_certs(self)); + STACK_OF(X509) *certs = pkcs7_get_certs(self); + if (!certs) + return Qnil; + return ossl_x509_sk2ary(certs); } static VALUE @@ -685,7 +738,7 @@ ossl_pkcs7_add_crl(VALUE self, VALUE crl) GetPKCS7(self, pkcs7); /* NO DUP needed! */ x509crl = GetX509CRLPtr(crl); if (!PKCS7_add_crl(pkcs7, x509crl)) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -704,7 +757,10 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) X509_CRL *crl; crls = pkcs7_get_crls(self); - while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl); + if (crls) { + while ((crl = sk_X509_CRL_pop(crls))) + X509_CRL_free(crl); + } rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self); return ary; @@ -713,7 +769,10 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_crls(VALUE self) { - return ossl_x509crl_sk2ary(pkcs7_get_crls(self)); + STACK_OF(X509_CRL) *crls = pkcs7_get_crls(self); + if (!crls) + return Qnil; + return ossl_x509crl_sk2ary(crls); } static VALUE @@ -726,7 +785,6 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) BIO *in, *out; PKCS7 *p7; VALUE data; - const char *msg; GetPKCS7(self, p7); rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags); @@ -736,28 +794,30 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) in = NIL_P(indata) ? NULL : ossl_obj2bio(&indata); if(NIL_P(certs)) x509s = NULL; else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } + x509s = ossl_protect_x509_ary2sk(certs, &status); + if(status){ + BIO_free(in); + rb_jump_tag(status); + } } if(!(out = BIO_new(BIO_s_mem()))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } ok = PKCS7_verify(p7, x509s, x509st, in, out, flg); BIO_free(in); sk_X509_pop_free(x509s, X509_free); - if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify"); - msg = ERR_reason_error_string(ERR_peek_error()); - ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil); - ossl_clear_error(); data = ossl_membio2str(out); ossl_pkcs7_set_data(self, data); - - return (ok == 1) ? Qtrue : Qfalse; + if (ok != 1) { + const char *msg = ERR_reason_error_string(ERR_peek_error()); + ossl_pkcs7_set_err_string(self, msg ? rb_str_new_cstr(msg) : Qnil); + ossl_clear_error(); + return Qfalse; + } + ossl_pkcs7_set_err_string(self, Qnil); + return Qtrue; } static VALUE @@ -777,10 +837,10 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self) flg = NIL_P(flags) ? 0 : NUM2INT(flags); GetPKCS7(self, p7); if(!(out = BIO_new(BIO_s_mem()))) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); if(!PKCS7_decrypt(p7, key, x509, out, flg)){ - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); /* out will be free */ @@ -793,30 +853,38 @@ ossl_pkcs7_add_data(VALUE self, VALUE data) PKCS7 *pkcs7; BIO *out, *in; char buf[4096]; - int len; + int len, ret; GetPKCS7(self, pkcs7); - if(PKCS7_type_is_signed(pkcs7)){ - if(!PKCS7_content_new(pkcs7, NID_pkcs7_data)) - ossl_raise(ePKCS7Error, NULL); + if (PKCS7_type_is_signed(pkcs7)) { + if (!PKCS7_content_new(pkcs7, NID_pkcs7_data)) + ossl_raise(ePKCS7Error, "PKCS7_content_new"); } in = ossl_obj2bio(&data); - if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err; - for(;;){ - if((len = BIO_read(in, buf, sizeof(buf))) <= 0) - break; - if(BIO_write(out, buf, len) != len) - goto err; + if (!(out = PKCS7_dataInit(pkcs7, NULL))) { + BIO_free(in); + ossl_raise(ePKCS7Error, "PKCS7_dataInit"); } - if(!PKCS7_dataFinal(pkcs7, out)) goto err; - ossl_pkcs7_set_data(self, Qnil); - - err: + for (;;) { + if ((len = BIO_read(in, buf, sizeof(buf))) <= 0) + break; + if (BIO_write(out, buf, len) != len) { + BIO_free_all(out); + BIO_free(in); + ossl_raise(ePKCS7Error, "BIO_write"); + } + } + if (BIO_flush(out) <= 0) { + BIO_free_all(out); + BIO_free(in); + ossl_raise(ePKCS7Error, "BIO_flush"); + } + ret = PKCS7_dataFinal(pkcs7, out); BIO_free_all(out); BIO_free(in); - if(ERR_peek_error()){ - ossl_raise(ePKCS7Error, NULL); - } + if (!ret) + ossl_raise(ePKCS7Error, "PKCS7_dataFinal"); + ossl_pkcs7_set_data(self, Qnil); return data; } @@ -831,17 +899,36 @@ ossl_pkcs7_to_der(VALUE self) GetPKCS7(self, pkcs7); if((len = i2d_PKCS7(pkcs7, NULL)) <= 0) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_PKCS7(pkcs7, &p) <= 0) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); ossl_str_adjust(str, p); return str; } static VALUE +ossl_pkcs7_to_text(VALUE self) +{ + PKCS7 *pkcs7; + BIO *out; + VALUE str; + + GetPKCS7(self, pkcs7); + if(!(out = BIO_new(BIO_s_mem()))) + ossl_raise(ePKCS7Error, NULL); + if(!PKCS7_print_ctx(out, pkcs7, 0, NULL)) { + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); + } + str = ossl_membio2str(out); + + return str; +} + +static VALUE ossl_pkcs7_to_pem(VALUE self) { PKCS7 *pkcs7; @@ -850,11 +937,11 @@ ossl_pkcs7_to_pem(VALUE self) GetPKCS7(self, pkcs7); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } if (!PEM_write_bio_PKCS7(out, pkcs7)) { - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); @@ -872,7 +959,7 @@ ossl_pkcs7si_alloc(VALUE klass) obj = NewPKCS7si(klass); if (!(p7si = PKCS7_SIGNER_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7si(obj, p7si); @@ -886,14 +973,15 @@ ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest) EVP_PKEY *pkey; X509 *x509; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); GetPKCS7si(self, p7si); - if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) { - ossl_raise(ePKCS7Error, NULL); - } + if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, md))) + ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_set"); + rb_ivar_set(self, id_md_holder, md_holder); return self; } @@ -927,10 +1015,10 @@ ossl_pkcs7si_get_signed_time(VALUE self) GetPKCS7si(self, p7si); if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } if (asn1obj->type == V_ASN1_UTCTIME) { - return asn1time_to_time(asn1obj->value.utctime); + return asn1time_to_time(asn1obj->value.utctime); } /* * OR @@ -952,7 +1040,7 @@ ossl_pkcs7ri_alloc(VALUE klass) obj = NewPKCS7ri(klass); if (!(p7ri = PKCS7_RECIP_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7ri(obj, p7ri); @@ -968,7 +1056,7 @@ ossl_pkcs7ri_initialize(VALUE self, VALUE cert) x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ GetPKCS7ri(self, p7ri); if (!PKCS7_RECIP_INFO_set(p7ri, x509)) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -1011,11 +1099,6 @@ void Init_ossl_pkcs7(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cPKCS7 = rb_define_class_under(mOSSL, "PKCS7", rb_cObject); ePKCS7Error = rb_define_class_under(cPKCS7, "PKCS7Error", eOSSLError); rb_define_singleton_method(cPKCS7, "read_smime", ossl_pkcs7_s_read_smime, 1); @@ -1050,6 +1133,7 @@ Init_ossl_pkcs7(void) rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0); rb_define_alias(cPKCS7, "to_s", "to_pem"); rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0); + rb_define_method(cPKCS7, "to_text", ossl_pkcs7_to_text, 0); cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject); rb_define_const(cPKCS7, "Signer", cPKCS7Signer); @@ -1078,4 +1162,7 @@ Init_ossl_pkcs7(void) DefPKCS7Const(BINARY); DefPKCS7Const(NOATTR); DefPKCS7Const(NOSMIMECAP); + + id_md_holder = rb_intern_const("EVP_MD_holder"); + id_cipher_holder = rb_intern_const("EVP_CIPHER_holder"); } diff --git a/ext/openssl/ossl_pkcs7.h b/ext/openssl/ossl_pkcs7.h index 3e1b094670..140fda1835 100644 --- a/ext/openssl/ossl_pkcs7.h +++ b/ext/openssl/ossl_pkcs7.h @@ -5,32 +5,12 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS7_H_) #define _OSSL_PKCS7_H_ -#define NewPKCS7(klass) \ - TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0) -#define SetPKCS7(obj, pkcs7) do { \ - if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (pkcs7); \ -} while (0) -#define GetPKCS7(obj, pkcs7) do { \ - TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \ - if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ - } \ -} while (0) - -extern const rb_data_type_t ossl_pkcs7_type; -extern VALUE cPKCS7; -extern VALUE cPKCS7Signer; -extern VALUE cPKCS7Recipient; -extern VALUE ePKCS7Error; - +VALUE ossl_pkcs7_new(PKCS7 *p7); void Init_ossl_pkcs7(void); #endif /* _OSSL_PKCS7_H_ */ diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 95a2ea1ed9..d2fd5b29c3 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -5,10 +5,14 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +#ifdef OSSL_USE_ENGINE +# include <openssl/engine.h> +#endif + /* * Classes */ @@ -29,22 +33,18 @@ ossl_evp_pkey_free(void *ptr) const rb_data_type_t ossl_evp_pkey_type = { "OpenSSL/EVP_PKEY", { - 0, ossl_evp_pkey_free, + 0, ossl_evp_pkey_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE -pkey_new0(VALUE arg) +pkey_wrap0(VALUE arg) { EVP_PKEY *pkey = (EVP_PKEY *)arg; VALUE klass, obj; - int type; - if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE) - ossl_raise(rb_eRuntimeError, "pkey is empty"); - - switch (type) { + switch (EVP_PKEY_base_id(pkey)) { #if !defined(OPENSSL_NO_RSA) case EVP_PKEY_RSA: klass = cRSA; break; #endif @@ -59,26 +59,128 @@ pkey_new0(VALUE arg) #endif default: klass = cPKey; break; } - obj = NewPKey(klass); - SetPKey(obj, pkey); + obj = rb_obj_alloc(klass); + RTYPEDDATA_DATA(obj) = pkey; return obj; } VALUE -ossl_pkey_new(EVP_PKEY *pkey) +ossl_pkey_wrap(EVP_PKEY *pkey) { VALUE obj; int status; - obj = rb_protect(pkey_new0, (VALUE)pkey, &status); + obj = rb_protect(pkey_wrap0, (VALUE)pkey, &status); if (status) { - EVP_PKEY_free(pkey); - rb_jump_tag(status); + EVP_PKEY_free(pkey); + rb_jump_tag(status); } return obj; } +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# include <openssl/decoder.h> + +static EVP_PKEY * +ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass) +{ + void *ppass = (void *)pass; + OSSL_DECODER_CTX *dctx; + EVP_PKEY *pkey = NULL; + int pos = 0, pos2; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL, + selection, NULL, NULL); + if (!dctx) + goto out; + if (selection == EVP_PKEY_KEYPAIR && + OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, + ppass) != 1) + goto out; + while (1) { + if (OSSL_DECODER_from_bio(dctx, bio) == 1) + goto out; + if (BIO_eof(bio)) + break; + pos2 = BIO_tell(bio); + if (pos2 < 0 || pos2 <= pos) + break; + ossl_clear_error(); + pos = pos2; + } + out: + OSSL_BIO_reset(bio); + OSSL_DECODER_CTX_free(dctx); + return pkey; +} + +EVP_PKEY * +ossl_pkey_read_generic(BIO *bio, VALUE pass) +{ + EVP_PKEY *pkey = NULL; + /* First check DER, then check PEM. */ + const char *input_types[] = {"DER", "PEM"}; + int input_type_num = (int)(sizeof(input_types) / sizeof(char *)); + /* + * Non-zero selections to try to decode. + * + * See EVP_PKEY_fromdata(3) - Selections to see all the selections. + * + * This is a workaround for the decoder failing to decode or returning + * bogus keys with selection 0, if a key management provider is different + * from a decoder provider. The workaround is to avoid using selection 0. + * + * Affected OpenSSL versions: >= 3.1.0, <= 3.1.2, or >= 3.0.0, <= 3.0.10 + * Fixed OpenSSL versions: 3.2, next release of the 3.1.z and 3.0.z + * + * See https://github.com/openssl/openssl/pull/21519 for details. + * + * First check for private key formats (EVP_PKEY_KEYPAIR). This is to keep + * compatibility with ruby/openssl < 3.0 which decoded the following as a + * private key. + * + * $ openssl ecparam -name prime256v1 -genkey -outform PEM + * -----BEGIN EC PARAMETERS----- + * BggqhkjOPQMBBw== + * -----END EC PARAMETERS----- + * -----BEGIN EC PRIVATE KEY----- + * MHcCAQEEIAG8ugBbA5MHkqnZ9ujQF93OyUfL9tk8sxqM5Wv5tKg5oAoGCCqGSM49 + * AwEHoUQDQgAEVcjhJfkwqh5C7kGuhAf8XaAjVuG5ADwb5ayg/cJijCgs+GcXeedj + * 86avKpGH84DXUlB23C/kPt+6fXYlitUmXQ== + * -----END EC PRIVATE KEY----- + * + * While the first PEM block is a proper encoding of ECParameters, thus + * OSSL_DECODER_from_bio() would pick it up, ruby/openssl used to return + * the latter instead. Existing applications expect this behavior. + * + * Note that normally, the input is supposed to contain a single decodable + * PEM block only, so this special handling should not create a new problem. + * + * Note that we need to create the OSSL_DECODER_CTX variable each time when + * we use the different selection as a workaround. + * See https://github.com/openssl/openssl/issues/20657 for details. + */ + int selections[] = { + EVP_PKEY_KEYPAIR, + EVP_PKEY_KEY_PARAMETERS, + EVP_PKEY_PUBLIC_KEY + }; + int selection_num = (int)(sizeof(selections) / sizeof(int)); + int i, j; + + for (i = 0; i < input_type_num; i++) { + for (j = 0; j < selection_num; j++) { + pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass); + if (pkey) { + goto out; + } + } + } + out: + return pkey; +} +#else EVP_PKEY * ossl_pkey_read_generic(BIO *bio, VALUE pass) { @@ -86,27 +188,28 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass) EVP_PKEY *pkey; if ((pkey = d2i_PrivateKey_bio(bio, NULL))) - goto out; + goto out; OSSL_BIO_reset(bio); if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass))) - goto out; + goto out; OSSL_BIO_reset(bio); if ((pkey = d2i_PUBKEY_bio(bio, NULL))) - goto out; + goto out; OSSL_BIO_reset(bio); /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */ if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, ppass))) - goto out; + goto out; OSSL_BIO_reset(bio); if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) - goto out; + goto out; OSSL_BIO_reset(bio); if ((pkey = PEM_read_bio_Parameters(bio, NULL))) - goto out; + goto out; out: return pkey; } +#endif /* * call-seq: @@ -136,8 +239,8 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass)); BIO_free(bio); if (!pkey) - ossl_raise(ePKeyError, "Could not parse PKey"); - return ossl_pkey_new(pkey); + ossl_raise(ePKeyError, "Could not parse PKey"); + return ossl_pkey_wrap(pkey); } static VALUE @@ -160,6 +263,7 @@ static VALUE pkey_ctx_apply_options0(VALUE args_v) { VALUE *args = (VALUE *)args_v; + Check_Type(args[1], T_HASH); rb_block_call(args[1], rb_intern("each"), 0, NULL, pkey_ctx_apply_options_i, args[0]); @@ -180,9 +284,9 @@ struct pkey_blocking_generate_arg { EVP_PKEY_CTX *ctx; EVP_PKEY *pkey; int state; - int yield: 1; - int genparam: 1; - int interrupted: 1; + unsigned int yield: 1; + unsigned int genparam: 1; + unsigned int interrupted: 1; }; static VALUE @@ -276,6 +380,11 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); } else { +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + ctx = EVP_PKEY_CTX_new_from_name(NULL, StringValueCStr(alg), NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_from_name"); +#else const EVP_PKEY_ASN1_METHOD *ameth; ENGINE *tmpeng; int pkey_id; @@ -294,6 +403,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */); if (!ctx) ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id"); +#endif } if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) { @@ -334,7 +444,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) } } - return ossl_pkey_new(gen_arg.pkey); + return ossl_pkey_wrap(gen_arg.pkey); } /* @@ -389,44 +499,54 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self) return pkey_generate(argc, argv, self, 0); } +/* + * TODO: There is no convenient way to check the presence of public key + * components on OpenSSL 3.0. But since keys are immutable on 3.0, pkeys without + * these should only be created by OpenSSL::PKey.generate_parameters or by + * parsing DER-/PEM-encoded string. We would need another flag for that. + */ void ossl_pkey_check_public_key(const EVP_PKEY *pkey) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + if (EVP_PKEY_missing_parameters(pkey)) + ossl_raise(ePKeyError, "parameters missing"); +#else void *ptr; const BIGNUM *n, *e, *pubkey; if (EVP_PKEY_missing_parameters(pkey)) - ossl_raise(ePKeyError, "parameters missing"); + ossl_raise(ePKeyError, "parameters missing"); - /* OpenSSL < 1.1.0 takes non-const pointer */ - ptr = EVP_PKEY_get0((EVP_PKEY *)pkey); + ptr = EVP_PKEY_get0(pkey); switch (EVP_PKEY_base_id(pkey)) { case EVP_PKEY_RSA: - RSA_get0_key(ptr, &n, &e, NULL); - if (n && e) - return; - break; + RSA_get0_key(ptr, &n, &e, NULL); + if (n && e) + return; + break; case EVP_PKEY_DSA: - DSA_get0_key(ptr, &pubkey, NULL); - if (pubkey) - return; - break; + DSA_get0_key(ptr, &pubkey, NULL); + if (pubkey) + return; + break; case EVP_PKEY_DH: - DH_get0_key(ptr, &pubkey, NULL); - if (pubkey) - return; - break; + DH_get0_key(ptr, &pubkey, NULL); + if (pubkey) + return; + break; #if !defined(OPENSSL_NO_EC) case EVP_PKEY_EC: - if (EC_KEY_get0_public_key(ptr)) - return; - break; + if (EC_KEY_get0_public_key(ptr)) + return; + break; #endif default: - /* unsupported type; assuming ok */ - return; + /* unsupported type; assuming ok */ + return; } ossl_raise(ePKeyError, "public key missing"); +#endif } EVP_PKEY * @@ -476,16 +596,7 @@ DupPKeyPtr(VALUE obj) static VALUE ossl_pkey_alloc(VALUE klass) { - EVP_PKEY *pkey; - VALUE obj; - - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - ossl_raise(ePKeyError, NULL); - } - SetPKey(obj, pkey); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL); } /* @@ -499,10 +610,118 @@ static VALUE ossl_pkey_initialize(VALUE self) { if (rb_obj_is_instance_of(self, cPKey)) { - ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly"); + ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly"); + } + return self; +} + +#ifdef HAVE_EVP_PKEY_DUP +/* :nodoc: */ +static VALUE +ossl_pkey_initialize_copy(VALUE self, VALUE other) +{ + EVP_PKEY *pkey, *pkey_other; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + TypedData_Get_Struct(other, EVP_PKEY, &ossl_evp_pkey_type, pkey_other); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + if (pkey_other) { + pkey = EVP_PKEY_dup(pkey_other); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_dup"); + RTYPEDDATA_DATA(self) = pkey; } return self; } +#endif + +#ifndef OSSL_USE_PROVIDER +static int +lookup_pkey_type(VALUE type) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; + + StringValue(type); + /* + * XXX: EVP_PKEY_asn1_find_str() looks up a PEM type string. Should we use + * OBJ_txt2nid() instead (and then somehow check if the NID is an acceptable + * EVP_PKEY type)? + * It is probably fine, though, since it can handle all algorithms that + * support raw keys in 1.1.1: { X25519, X448, ED25519, ED448, HMAC }. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + return pkey_id; +} +#endif + +/* + * call-seq: + * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() + */ + +static VALUE +ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + size_t keylen; + + StringValue(key); + keylen = RSTRING_LEN(key); + +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); + pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); +#endif + + return ossl_pkey_wrap(pkey); +} + +/* + * call-seq: + * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() + */ + +static VALUE +ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + size_t keylen; + + StringValue(key); + keylen = RSTRING_LEN(key); + +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); + pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key"); +#endif + + return ossl_pkey_wrap(pkey); +} /* * call-seq: @@ -518,6 +737,10 @@ ossl_pkey_oid(VALUE self) GetPKey(self, pkey); nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid == EVP_PKEY_KEYMGMT) + ossl_raise(ePKeyError, "EVP_PKEY_id"); +#endif return rb_str_new_cstr(OBJ_nid2sn(nid)); } @@ -531,13 +754,23 @@ static VALUE ossl_pkey_inspect(VALUE self) { EVP_PKEY *pkey; - int nid; GetPKey(self, pkey); - nid = EVP_PKEY_id(pkey); - return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>", - rb_class_name(CLASS_OF(self)), (void *)self, - OBJ_nid2sn(nid)); + VALUE str = rb_sprintf("#<%"PRIsVALUE":%p", + rb_obj_class(self), (void *)self); + int nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid != EVP_PKEY_KEYMGMT) +#endif + rb_str_catf(str, " oid=%s", OBJ_nid2sn(nid)); +#ifdef OSSL_USE_PROVIDER + rb_str_catf(str, " type_name=%s", EVP_PKEY_get0_type_name(pkey)); + const OSSL_PROVIDER *prov = EVP_PKEY_get0_provider(pkey); + if (prov) + rb_str_catf(str, " provider=%s", OSSL_PROVIDER_get0_name(prov)); +#endif + rb_str_catf(str, ">"); + return str; } /* @@ -581,44 +814,33 @@ VALUE ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) { EVP_PKEY *pkey; - VALUE cipher, pass; + VALUE cipher, pass, cipher_holder; const EVP_CIPHER *enc = NULL; BIO *bio; GetPKey(self, pkey); rb_scan_args(argc, argv, "02", &cipher, &pass); if (!NIL_P(cipher)) { - enc = ossl_evp_get_cipherbyname(cipher); - pass = ossl_pem_passwd_value(pass); + enc = ossl_evp_cipher_fetch(cipher, &cipher_holder); + pass = ossl_pem_passwd_value(pass); } bio = BIO_new(BIO_s_mem()); if (!bio) - ossl_raise(ePKeyError, "BIO_new"); + ossl_raise(ePKeyError, "BIO_new"); if (to_der) { - if (!i2d_PrivateKey_bio(bio, pkey)) { - BIO_free(bio); - ossl_raise(ePKeyError, "i2d_PrivateKey_bio"); - } + if (!i2d_PrivateKey_bio(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PrivateKey_bio"); + } } else { -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) - if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, - ossl_pem_passwd_cb, - (void *)pass)) { -#else - char pem_str[80]; - const char *aname; - - EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &aname, pkey->ameth); - snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY", aname); - if (!PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, pem_str, bio, - pkey, enc, NULL, 0, ossl_pem_passwd_cb, - (void *)pass)) { -#endif - BIO_free(bio); - ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional"); - } + if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, + (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional"); + } } return ossl_membio2str(bio); } @@ -627,37 +849,37 @@ static VALUE do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der) { EVP_PKEY *pkey; - VALUE cipher, pass; + VALUE cipher, pass, cipher_holder; const EVP_CIPHER *enc = NULL; BIO *bio; GetPKey(self, pkey); rb_scan_args(argc, argv, "02", &cipher, &pass); if (argc > 0) { - /* - * TODO: EncryptedPrivateKeyInfo actually has more options. - * Should they be exposed? - */ - enc = ossl_evp_get_cipherbyname(cipher); - pass = ossl_pem_passwd_value(pass); + /* + * TODO: EncryptedPrivateKeyInfo actually has more options. + * Should they be exposed? + */ + enc = ossl_evp_cipher_fetch(cipher, &cipher_holder); + pass = ossl_pem_passwd_value(pass); } bio = BIO_new(BIO_s_mem()); if (!bio) - ossl_raise(ePKeyError, "BIO_new"); + ossl_raise(ePKeyError, "BIO_new"); if (to_der) { - if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0, - ossl_pem_passwd_cb, (void *)pass)) { - BIO_free(bio); - ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio"); - } + if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio"); + } } else { - if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0, - ossl_pem_passwd_cb, (void *)pass)) { - BIO_free(bio); - ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey"); - } + if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey"); + } } return ossl_membio2str(bio); } @@ -685,6 +907,18 @@ ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self) * * Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der * for more details. + * + * An unencrypted PEM-encoded key will look like: + * + * -----BEGIN PRIVATE KEY----- + * [...] + * -----END PRIVATE KEY----- + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN ENCRYPTED PRIVATE KEY----- + * [...] + * -----END ENCRYPTED PRIVATE KEY----- */ static VALUE ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) @@ -692,6 +926,33 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) return do_pkcs8_export(argc, argv, self, 0); } +/* + * call-seq: + * pkey.raw_private_key => string + * + * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() + */ + +static VALUE +ossl_pkey_raw_private_key(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); + + rb_str_set_len(str, len); + + return str; +} + VALUE ossl_pkey_export_spki(VALUE self, int to_der) { @@ -699,20 +960,21 @@ ossl_pkey_export_spki(VALUE self, int to_der) BIO *bio; GetPKey(self, pkey); + ossl_pkey_check_public_key(pkey); bio = BIO_new(BIO_s_mem()); if (!bio) - ossl_raise(ePKeyError, "BIO_new"); + ossl_raise(ePKeyError, "BIO_new"); if (to_der) { - if (!i2d_PUBKEY_bio(bio, pkey)) { - BIO_free(bio); - ossl_raise(ePKeyError, "i2d_PUBKEY_bio"); - } + if (!i2d_PUBKEY_bio(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PUBKEY_bio"); + } } else { - if (!PEM_write_bio_PUBKEY(bio, pkey)) { - BIO_free(bio); - ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY"); - } + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY"); + } } return ossl_membio2str(bio); } @@ -734,6 +996,12 @@ ossl_pkey_public_to_der(VALUE self) * pkey.public_to_pem -> string * * Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- */ static VALUE ossl_pkey_public_to_pem(VALUE self) @@ -743,6 +1011,33 @@ ossl_pkey_public_to_pem(VALUE self) /* * call-seq: + * pkey.raw_public_key => string + * + * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() + */ + +static VALUE +ossl_pkey_raw_public_key(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); + + rb_str_set_len(str, len); + + return str; +} + +/* + * call-seq: * pkey.compare?(another_pkey) -> true | false * * Used primarily to check if an OpenSSL::X509::Certificate#public_key compares to its private key. @@ -769,14 +1064,14 @@ ossl_pkey_compare(VALUE self, VALUE other) if (EVP_PKEY_id(selfPKey) != EVP_PKEY_id(otherPKey)) ossl_raise(rb_eTypeError, "cannot match different PKey types"); - ret = EVP_PKEY_cmp(selfPKey, otherPKey); + ret = EVP_PKEY_eq(selfPKey, otherPKey); if (ret == 0) return Qfalse; else if (ret == 1) return Qtrue; else - ossl_raise(ePKeyError, "EVP_PKEY_cmp"); + ossl_raise(ePKeyError, "EVP_PKEY_eq"); } /* @@ -816,7 +1111,7 @@ static VALUE ossl_pkey_sign(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - VALUE digest, data, options, sig; + VALUE digest, data, options, sig, md_holder; const EVP_MD *md = NULL; EVP_MD_CTX *ctx; EVP_PKEY_CTX *pctx; @@ -826,7 +1121,7 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self) pkey = GetPrivPKeyPtr(self); rb_scan_args(argc, argv, "21", &digest, &data, &options); if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(data); ctx = EVP_MD_CTX_new(); @@ -843,7 +1138,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self) rb_jump_tag(state); } } -#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { EVP_MD_CTX_free(ctx); @@ -864,30 +1158,6 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self) EVP_MD_CTX_free(ctx); ossl_raise(ePKeyError, "EVP_DigestSign"); } -#else - if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignUpdate"); - } - if (EVP_DigestSignFinal(ctx, NULL, &siglen) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } - if (siglen > LONG_MAX) { - EVP_MD_CTX_free(ctx); - rb_raise(ePKeyError, "signature would be too large"); - } - sig = ossl_str_new(NULL, (long)siglen, &state); - if (state) { - EVP_MD_CTX_free(ctx); - rb_jump_tag(state); - } - if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig), - &siglen) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestSignFinal"); - } -#endif EVP_MD_CTX_free(ctx); rb_str_set_len(sig, siglen); return sig; @@ -920,7 +1190,7 @@ static VALUE ossl_pkey_verify(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - VALUE digest, sig, data, options; + VALUE digest, sig, data, options, md_holder; const EVP_MD *md = NULL; EVP_MD_CTX *ctx; EVP_PKEY_CTX *pctx; @@ -930,7 +1200,7 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); ossl_pkey_check_public_key(pkey); if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(sig); StringValue(data); @@ -948,24 +1218,12 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self) rb_jump_tag(state); } } -#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)); EVP_MD_CTX_free(ctx); if (ret < 0) ossl_raise(ePKeyError, "EVP_DigestVerify"); -#else - if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) < 1) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_DigestVerifyUpdate"); - } - ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), - RSTRING_LEN(sig)); - EVP_MD_CTX_free(ctx); - if (ret < 0) - ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); -#endif if (ret) return Qtrue; else { @@ -1011,7 +1269,7 @@ static VALUE ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - VALUE digest, data, options, sig; + VALUE digest, data, options, sig, md_holder; const EVP_MD *md = NULL; EVP_PKEY_CTX *ctx; size_t outlen; @@ -1020,7 +1278,7 @@ ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self) GetPKey(self, pkey); rb_scan_args(argc, argv, "21", &digest, &data, &options); if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(data); ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); @@ -1087,7 +1345,7 @@ static VALUE ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - VALUE digest, sig, data, options; + VALUE digest, sig, data, options, md_holder; const EVP_MD *md = NULL; EVP_PKEY_CTX *ctx; int state, ret; @@ -1096,7 +1354,7 @@ ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); ossl_pkey_check_public_key(pkey); if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(sig); StringValue(data); @@ -1150,7 +1408,7 @@ static VALUE ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - VALUE digest, sig, options, out; + VALUE digest, sig, options, out, md_holder; const EVP_MD *md = NULL; EVP_PKEY_CTX *ctx; int state; @@ -1160,7 +1418,7 @@ ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "21", &digest, &sig, &options); ossl_pkey_check_public_key(pkey); if (!NIL_P(digest)) - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(sig); ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); @@ -1400,11 +1658,6 @@ void Init_ossl_pkey(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-module: OpenSSL::PKey * * == Asymmetric Public Key Algorithms @@ -1460,7 +1713,16 @@ Init_ossl_pkey(void) /* Document-class: OpenSSL::PKey::PKeyError * - *Raised when errors occur during PKey#sign or PKey#verify. + * Raised when errors occur during PKey#sign or PKey#verify. + * + * Before version 4.0.0, OpenSSL::PKey::PKeyError had the following + * subclasses. These subclasses have been removed and the constants are + * now defined as aliases of OpenSSL::PKey::PKeyError. + * + * * OpenSSL::PKey::DHError + * * OpenSSL::PKey::DSAError + * * OpenSSL::PKey::ECError + * * OpenSSL::PKey::RSAError */ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); @@ -1478,9 +1740,16 @@ Init_ossl_pkey(void) rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); + rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2); + rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2); rb_define_alloc_func(cPKey, ossl_pkey_alloc); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); +#ifdef HAVE_EVP_PKEY_DUP + rb_define_method(cPKey, "initialize_copy", ossl_pkey_initialize_copy, 1); +#else + rb_undef_method(cPKey, "initialize_copy"); +#endif rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); @@ -1488,6 +1757,8 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); + rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); + rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 4beede22b5..023361b90f 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(OSSL_PKEY_H) #define OSSL_PKEY_H @@ -15,27 +15,19 @@ extern VALUE cPKey; extern VALUE ePKeyError; extern const rb_data_type_t ossl_evp_pkey_type; -#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) -#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) -#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue) +/* For ENGINE */ +#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue) +#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue) -#define NewPKey(klass) \ - TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0) -#define SetPKey(obj, pkey) do { \ - if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (pkey); \ - OSSL_PKEY_SET_PUBLIC(obj); \ -} while (0) #define GetPKey(obj, pkey) do {\ TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \ if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ + rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ } \ } while (0) -VALUE ossl_pkey_new(EVP_PKEY *); +/* Takes ownership of the EVP_PKEY */ +VALUE ossl_pkey_wrap(EVP_PKEY *); void ossl_pkey_check_public_key(const EVP_PKEY *); EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); EVP_PKEY *GetPKeyPtr(VALUE); @@ -53,7 +45,7 @@ VALUE ossl_pkey_export_spki(VALUE self, int to_der); * #to_der. */ VALUE ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, - int to_der); + int to_der); void Init_ossl_pkey(void); @@ -61,136 +53,141 @@ void Init_ossl_pkey(void); * RSA */ extern VALUE cRSA; -extern VALUE eRSAError; - void Init_ossl_rsa(void); /* * DSA */ extern VALUE cDSA; -extern VALUE eDSAError; - void Init_ossl_dsa(void); /* * DH */ extern VALUE cDH; -extern VALUE eDHError; - void Init_ossl_dh(void); /* * EC */ extern VALUE cEC; -extern VALUE eECError; -extern VALUE cEC_GROUP; -extern VALUE eEC_GROUP; -extern VALUE cEC_POINT; -extern VALUE eEC_POINT; VALUE ossl_ec_new(EVP_PKEY *); void Init_ossl_ec(void); -#define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \ -/* \ - * call-seq: \ - * _keytype##.##_name -> aBN \ - */ \ -static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ -{ \ - _type *obj; \ - const BIGNUM *bn; \ - \ - Get##_type(self, obj); \ - _get; \ - if (bn == NULL) \ - return Qnil; \ - return ossl_bn_new(bn); \ +#define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \ +/* \ + * call-seq: \ + * _keytype##.##_name -> aBN \ + */ \ +static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ +{ \ + const _type *obj; \ + const BIGNUM *bn; \ + \ + Get##_type(self, obj); \ + _get; \ + if (bn == NULL) \ + return Qnil; \ + return ossl_bn_new(bn); \ } -#define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ - _type##_get0_##_group(obj, &bn, NULL, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ - _type##_get0_##_group(obj, NULL, &bn, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \ - _type##_get0_##_group(obj, NULL, NULL, &bn)) - -#define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ - _type##_get0_##_group(obj, &bn, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ - _type##_get0_##_group(obj, NULL, &bn)) - -#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ -/* \ - * call-seq: \ - * _keytype##.set_##_group(a1, a2, a3) -> self \ - */ \ +#define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ + _type##_get0_##_group(obj, &bn, NULL, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ + _type##_get0_##_group(obj, NULL, &bn, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \ + _type##_get0_##_group(obj, NULL, NULL, &bn)) + +#define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ + _type##_get0_##_group(obj, &bn, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ + _type##_get0_##_group(obj, NULL, &bn)) + +#ifndef OSSL_HAVE_IMMUTABLE_PKEY +#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ +/* \ + * call-seq: \ + * _keytype##.set_##_group(a1, a2, a3) -> self \ + */ \ +static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ +{ \ + _type *obj; \ + BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ + BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ + BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\ + \ + Get##_type(self, obj); \ + if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ + (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \ + (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + BN_clear_free(bn3); \ + ossl_raise(ePKeyError, "BN_dup"); \ + } \ + \ + if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + BN_clear_free(bn3); \ + ossl_raise(ePKeyError, #_type"_set0_"#_group); \ + } \ + return self; \ +} + +#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ +/* \ + * call-seq: \ + * _keytype##.set_##_group(a1, a2) -> self \ + */ \ +static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ +{ \ + _type *obj; \ + BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ + BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ + \ + Get##_type(self, obj); \ + if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ + (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + ossl_raise(ePKeyError, "BN_dup"); \ + } \ + \ + if (!_type##_set0_##_group(obj, bn1, bn2)) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + ossl_raise(ePKeyError, #_type"_set0_"#_group); \ + } \ + return self; \ +} +#else +#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ -{ \ - _type *obj; \ - BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ - BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ - BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\ - \ - Get##_type(self, obj); \ - if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ - (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \ - (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - BN_clear_free(bn3); \ - ossl_raise(eBNError, NULL); \ - } \ - \ - if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - BN_clear_free(bn3); \ - ossl_raise(ePKeyError, #_type"_set0_"#_group); \ - } \ - return self; \ +{ \ + rb_raise(ePKeyError, \ + #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ } -#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ -/* \ - * call-seq: \ - * _keytype##.set_##_group(a1, a2) -> self \ - */ \ +#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ -{ \ - _type *obj; \ - BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ - BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ - \ - Get##_type(self, obj); \ - if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ - (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - ossl_raise(eBNError, NULL); \ - } \ - \ - if (!_type##_set0_##_group(obj, bn1, bn2)) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - ossl_raise(ePKeyError, #_type"_set0_"#_group); \ - } \ - return self; \ +{ \ + rb_raise(ePKeyError, \ + #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ } +#endif -#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) +#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) -#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) +#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) -#define DEF_OSSL_PKEY_BN(class, keytype, name) \ - rb_define_method((class), #name, ossl_##keytype##_get_##name, 0) +#define DEF_OSSL_PKEY_BN(class, keytype, name) \ + rb_define_method((class), #name, ossl_##keytype##_get_##name, 0) #endif /* OSSL_PKEY_H */ diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index ca782bbe59..3f2975c5a3 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,20 +14,21 @@ #define GetPKeyDH(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ } \ } while (0) #define GetDH(obj, dh) do { \ EVP_PKEY *_pkey; \ GetPKeyDH((obj), _pkey); \ (dh) = EVP_PKEY_get0_DH(_pkey); \ + if ((dh) == NULL) \ + ossl_raise(ePKeyError, "failed to get DH from EVP_PKEY"); \ } while (0) /* * Classes */ VALUE cDH; -VALUE eDHError; /* * Private @@ -43,6 +44,7 @@ VALUE eDHError; * If called without arguments, an empty instance without any parameter or key * components is created. Use #set_pqg to manually set the parameters afterwards * (and optionally #set_key to set private and public key components). + * This form is not compatible with OpenSSL 3.0 or later. * * If a String is given, tries to parse it as a DER- or PEM- encoded parameters. * See also OpenSSL::PKey.read which can parse keys of any kinds. @@ -58,51 +60,83 @@ VALUE eDHError; * * Examples: * # Creating an instance from scratch - * dh = DH.new + * # Note that this is deprecated and will result in ArgumentError when + * # using OpenSSL 3.0 or later. + * dh = OpenSSL::PKey::DH.new * dh.set_pqg(bn_p, nil, bn_g) * * # Generating a parameters and a key pair - * dh = DH.new(2048) # An alias of DH.generate(2048) + * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048) * - * # Reading DH parameters - * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet - * dh.generate_key! # -> dh with public and private key + * # Reading DH parameters from a PEM-encoded string + * dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only + * dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair */ static VALUE ossl_dh_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; + int type; DH *dh; - BIO *in; + BIO *in = NULL; VALUE arg; - GetPKey(self, pkey); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ if (rb_scan_args(argc, argv, "01", &arg) == 0) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::DH.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else dh = DH_new(); if (!dh) - ossl_raise(eDHError, "DH_new"); + ossl_raise(ePKeyError, "DH_new"); + goto legacy; +#endif } - else { - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh){ - OSSL_BIO_reset(in); - dh = d2i_DHparams_bio(in, NULL); - } - BIO_free(in); - if (!dh) { - ossl_raise(eDHError, NULL); - } + + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* + * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic + * routine does not support DER-encoded parameters + */ + dh = d2i_DHparams_bio(in, NULL); + if (dh) + goto legacy; + OSSL_BIO_reset(in); + + pkey = ossl_pkey_read_generic(in, Qnil); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "could not parse pkey"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_DH) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } - if (!EVP_PKEY_assign_DH(pkey, dh)) { - DH_free(dh); - ossl_raise(eDHError, NULL); + RTYPEDDATA_DATA(self) = pkey; + return self; + + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { + EVP_PKEY_free(pkey); + DH_free(dh); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DH"); } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_dh_initialize_copy(VALUE self, VALUE other) { @@ -110,31 +144,38 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) DH *dh, *dh_other; const BIGNUM *pub, *priv; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eDHError, "DH already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetDH(other, dh_other); dh = DHparams_dup(dh_other); if (!dh) - ossl_raise(eDHError, "DHparams_dup"); - EVP_PKEY_assign_DH(pkey, dh); + ossl_raise(ePKeyError, "DHparams_dup"); DH_get0_key(dh_other, &pub, &priv); if (pub) { - BIGNUM *pub2 = BN_dup(pub); - BIGNUM *priv2 = BN_dup(priv); + BIGNUM *pub2 = BN_dup(pub); + BIGNUM *priv2 = BN_dup(priv); if (!pub2 || (priv && !priv2)) { - BN_clear_free(pub2); - BN_clear_free(priv2); - ossl_raise(eDHError, "BN_dup"); - } - DH_set0_key(dh, pub2, priv2); + BN_clear_free(pub2); + BN_clear_free(priv2); + ossl_raise(ePKeyError, "BN_dup"); + } + DH_set0_key(dh, pub2, priv2); } + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { + EVP_PKEY_free(pkey); + DH_free(dh); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DH"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -146,7 +187,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) static VALUE ossl_dh_is_public(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; const BIGNUM *bn; GetDH(self, dh); @@ -165,14 +206,14 @@ ossl_dh_is_public(VALUE self) static VALUE ossl_dh_is_private(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; const BIGNUM *bn; GetDH(self, dh); DH_get0_key(dh, NULL, &bn); #if !defined(OPENSSL_NO_ENGINE) - return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse; + return (bn || DH_get0_engine((DH *)dh)) ? Qtrue : Qfalse; #else return bn ? Qtrue : Qfalse; #endif @@ -184,24 +225,35 @@ ossl_dh_is_private(VALUE self) * dh.to_pem -> aString * dh.to_s -> aString * - * Encodes this DH to its PEM encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. + * Serializes the DH parameters to a PEM-encoding. + * + * Note that any existing per-session public/private keys will *not* get + * encoded, just the Diffie-Hellman parameters will be encoded. + * + * PEM-encoded parameters will look like: + * + * -----BEGIN DH PARAMETERS----- + * [...] + * -----END DH PARAMETERS----- + * + * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and + * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for + * serialization with the private or public key components. */ static VALUE ossl_dh_export(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; BIO *out; VALUE str; GetDH(self, dh); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); } if (!PEM_write_bio_DHparams(out, dh)) { - BIO_free(out); - ossl_raise(eDHError, NULL); + BIO_free(out); + ossl_raise(ePKeyError, NULL); } str = ossl_membio2str(out); @@ -212,26 +264,30 @@ ossl_dh_export(VALUE self) * call-seq: * dh.to_der -> aString * - * Encodes this DH to its DER encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. - + * Serializes the DH parameters to a DER-encoding + * + * Note that any existing per-session public/private keys will *not* get + * encoded, just the Diffie-Hellman parameters will be encoded. + * + * See also #public_to_der (X.509 SubjectPublicKeyInfo) and + * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for + * serialization with the private or public key components. */ static VALUE ossl_dh_to_der(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; unsigned char *p; long len; VALUE str; GetDH(self, dh); if((len = i2d_DHparams(dh, NULL)) <= 0) - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_DHparams(dh, &p) < 0) - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); ossl_str_adjust(str, p); return str; @@ -239,35 +295,6 @@ ossl_dh_to_der(VALUE self) /* * call-seq: - * dh.params -> hash - * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dh_get_params(VALUE self) -{ - DH *dh; - VALUE hash; - const BIGNUM *p, *q, *g, *pub_key, *priv_key; - - GetDH(self, dh); - DH_get0_pqg(dh, &p, &q, &g); - DH_get0_key(dh, &pub_key, &priv_key); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); - - return hash; -} - -/* - * call-seq: * dh.params_ok? -> true | false * * Validates the Diffie-Hellman parameters associated with this instance. @@ -287,7 +314,7 @@ ossl_dh_check_params(VALUE self) GetPKey(self, pkey); pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); if (!pctx) - ossl_raise(eDHError, "EVP_PKEY_CTX_new"); + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); ret = EVP_PKEY_param_check(pctx); EVP_PKEY_CTX_free(pctx); #else @@ -330,19 +357,6 @@ OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key) void Init_ossl_dh(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::DHError - * - * Generic exception that is raised if an operation on a DH PKey - * fails unexpectedly or in case an instantiation of an instance of DH - * fails due to non-conformant input data. - */ - eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError); /* Document-class: OpenSSL::PKey::DH * * An implementation of the Diffie-Hellman key exchange protocol based on @@ -378,7 +392,9 @@ Init_ossl_dh(void) */ cDH = rb_define_class_under(mPKey, "DH", cPKey); rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); +#endif rb_define_method(cDH, "public?", ossl_dh_is_public, 0); rb_define_method(cDH, "private?", ossl_dh_is_private, 0); rb_define_method(cDH, "export", ossl_dh_export, 0); @@ -394,8 +410,6 @@ Init_ossl_dh(void) DEF_OSSL_PKEY_BN(cDH, dh, priv_key); rb_define_method(cDH, "set_pqg", ossl_dh_set_pqg, 3); rb_define_method(cDH, "set_key", ossl_dh_set_key, 2); - - rb_define_method(cDH, "params", ossl_dh_get_params, 0); } #else /* defined NO_DH */ diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 7af00eebec..041646a058 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,17 +14,19 @@ #define GetPKeyDSA(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \ } \ } while (0) #define GetDSA(obj, dsa) do { \ EVP_PKEY *_pkey; \ GetPKeyDSA((obj), _pkey); \ (dsa) = EVP_PKEY_get0_DSA(_pkey); \ + if ((dsa) == NULL) \ + ossl_raise(ePKeyError, "failed to get DSA from EVP_PKEY"); \ } while (0) static inline int -DSA_HAS_PRIVATE(DSA *dsa) +DSA_HAS_PRIVATE(OSSL_3_const DSA *dsa) { const BIGNUM *bn; DSA_get0_key(dsa, NULL, &bn); @@ -32,7 +34,7 @@ DSA_HAS_PRIVATE(DSA *dsa) } static inline int -DSA_PRIVATE(VALUE obj, DSA *dsa) +DSA_PRIVATE(VALUE obj, OSSL_3_const DSA *dsa) { return DSA_HAS_PRIVATE(dsa) || OSSL_PKEY_IS_PRIVATE(obj); } @@ -41,7 +43,6 @@ DSA_PRIVATE(VALUE obj, DSA *dsa) * Classes */ VALUE cDSA; -VALUE eDSAError; /* * Private @@ -56,6 +57,7 @@ VALUE eDSAError; * * If called without arguments, creates a new instance with no key components * set. They can be set individually by #set_pqg and #set_key. + * This form is not compatible with OpenSSL 3.0 or later. * * If called with a String, tries to parse as DER or PEM encoding of a \DSA key. * See also OpenSSL::PKey.read which can parse keys of any kinds. @@ -83,72 +85,97 @@ VALUE eDSAError; static VALUE ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) { - EVP_PKEY *pkey, *tmp; - DSA *dsa = NULL; - BIO *in; + EVP_PKEY *pkey; + DSA *dsa; + BIO *in = NULL; VALUE arg, pass; + int type; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); - GetPKey(self, pkey); /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ rb_scan_args(argc, argv, "02", &arg, &pass); if (argc == 0) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::DSA.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else dsa = DSA_new(); if (!dsa) - ossl_raise(eDSAError, "DSA_new"); - } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - - tmp = ossl_pkey_read_generic(in, pass); - if (tmp) { - if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA) - rb_raise(eDSAError, "incorrect pkey type: %s", - OBJ_nid2sn(EVP_PKEY_base_id(tmp))); - dsa = EVP_PKEY_get1_DSA(tmp); - EVP_PKEY_free(tmp); - } - if (!dsa) { - OSSL_BIO_reset(in); -#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u)) - dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); -#undef PEM_read_bio_DSAPublicKey - } - BIO_free(in); - if (!dsa) { - ossl_clear_error(); - ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); - } + ossl_raise(ePKeyError, "DSA_new"); + goto legacy; +#endif } - if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* DER-encoded DSAPublicKey format isn't supported by the generic routine */ + dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey, + PEM_STRING_DSA_PUBLIC, + in, NULL, NULL, NULL); + if (dsa) + goto legacy; + OSSL_BIO_reset(in); + + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "Neither PUB key nor PRIV key"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_DSA) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } + RTYPEDDATA_DATA(self) = pkey; + return self; + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) { + EVP_PKEY_free(pkey); + DSA_free(dsa); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_dsa_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; DSA *dsa, *dsa_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eDSAError, "DSA already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetDSA(other, dsa); - dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa); + dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, + (d2i_of_void *)d2i_DSAPrivateKey, + (char *)dsa); if (!dsa_new) - ossl_raise(eDSAError, "ASN1_dup"); + ossl_raise(ePKeyError, "ASN1_dup"); - EVP_PKEY_assign_DSA(pkey, dsa_new); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) { + EVP_PKEY_free(pkey); + DSA_free(dsa_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -160,7 +187,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) static VALUE ossl_dsa_is_public(VALUE self) { - DSA *dsa; + const DSA *dsa; const BIGNUM *bn; GetDSA(self, dsa); @@ -179,7 +206,7 @@ ossl_dsa_is_public(VALUE self) static VALUE ossl_dsa_is_private(VALUE self) { - DSA *dsa; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); @@ -192,21 +219,63 @@ ossl_dsa_is_private(VALUE self) * dsa.to_pem([cipher, password]) -> aString * dsa.to_s([cipher, password]) -> aString * - * Encodes this DSA to its PEM encoding. + * Serializes a private or public key to a PEM-encoding. + * + * [When the key contains public components only] + * + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + * + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether it is a public key + * or a private key. + * + * [When the key contains private components, and no parameters are given] + * + * Serializes it into a traditional \OpenSSL DSAPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN DSA PRIVATE KEY----- + * [...] + * -----END DSA PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] + * + * Serializes it into a traditional \OpenSSL DSAPrivateKey and encrypts it in + * OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN DSA PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 * - * === Parameters - * * _cipher_ is an OpenSSL::Cipher. - * * _password_ is a string containing your password. + * [...] + * -----END DSA PRIVATE KEY----- * - * === Examples - * DSA.to_pem -> aString - * DSA.to_pem(cipher, 'mypassword') -> aString + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. * + * <b>This method is kept for compatibility.</b> + * This should only be used when the traditional, non-standard \OpenSSL format + * is required. + * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ static VALUE ossl_dsa_export(int argc, VALUE *argv, VALUE self) { - DSA *dsa; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); if (DSA_HAS_PRIVATE(dsa)) @@ -219,13 +288,20 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self) * call-seq: * dsa.to_der -> aString * - * Encodes this DSA to its DER encoding. + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the traditional, non-standard \OpenSSL format + * is required. * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE ossl_dsa_to_der(VALUE self) { - DSA *dsa; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); if (DSA_HAS_PRIVATE(dsa)) @@ -236,35 +312,6 @@ ossl_dsa_to_der(VALUE self) /* - * call-seq: - * dsa.params -> hash - * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dsa_get_params(VALUE self) -{ - DSA *dsa; - VALUE hash; - const BIGNUM *p, *q, *g, *pub_key, *priv_key; - - GetDSA(self, dsa); - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, &priv_key); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); - - return hash; -} - -/* * Document-method: OpenSSL::PKey::DSA#set_pqg * call-seq: * dsa.set_pqg(p, q, g) -> self @@ -287,20 +334,6 @@ OSSL_PKEY_BN_DEF2(dsa, DSA, key, pub_key, priv_key) void Init_ossl_dsa(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::DSAError - * - * Generic exception that is raised if an operation on a DSA PKey - * fails unexpectedly or in case an instantiation of an instance of DSA - * fails due to non-conformant input data. - */ - eDSAError = rb_define_class_under(mPKey, "DSAError", ePKeyError); - /* Document-class: OpenSSL::PKey::DSA * * DSA, the Digital Signature Algorithm, is specified in NIST's @@ -310,7 +343,9 @@ Init_ossl_dsa(void) cDSA = rb_define_class_under(mPKey, "DSA", cPKey); rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1); +#endif rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); @@ -326,8 +361,6 @@ Init_ossl_dsa(void) DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key); rb_define_method(cDSA, "set_pqg", ossl_dsa_set_pqg, 3); rb_define_method(cDSA, "set_key", ossl_dsa_set_key, 2); - - rb_define_method(cDSA, "params", ossl_dsa_get_params, 0); } #else /* defined NO_DSA */ diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index 47de7ccdbb..35f031819d 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -15,25 +15,27 @@ static const rb_data_type_t ossl_ec_point_type; #define GetPKeyEC(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \ } \ } while (0) #define GetEC(obj, key) do { \ EVP_PKEY *_pkey; \ GetPKeyEC(obj, _pkey); \ (key) = EVP_PKEY_get0_EC_KEY(_pkey); \ + if ((key) == NULL) \ + ossl_raise(ePKeyError, "failed to get EC_KEY from EVP_PKEY"); \ } while (0) #define GetECGroup(obj, group) do { \ TypedData_Get_Struct(obj, EC_GROUP, &ossl_ec_group_type, group); \ if ((group) == NULL) \ - ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \ + ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \ } while (0) #define GetECPoint(obj, point) do { \ TypedData_Get_Struct(obj, EC_POINT, &ossl_ec_point_type, point); \ if ((point) == NULL) \ - ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \ + ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \ } while (0) #define GetECPointGroup(obj, group) do { \ VALUE _group = rb_attr_get(obj, id_i_group); \ @@ -41,17 +43,13 @@ static const rb_data_type_t ossl_ec_point_type; } while (0) VALUE cEC; -VALUE eECError; -VALUE cEC_GROUP; -VALUE eEC_GROUP; -VALUE cEC_POINT; -VALUE eEC_POINT; +static VALUE cEC_GROUP; +static VALUE eEC_GROUP; +static VALUE cEC_POINT; +static VALUE eEC_POINT; -static ID s_GFp, s_GF2m; - -static ID ID_uncompressed; -static ID ID_compressed; -static ID ID_hybrid; +static VALUE sym_GFp, sym_GF2m; +static VALUE sym_uncompressed, sym_compressed, sym_hybrid; static ID id_i_group; @@ -68,27 +66,27 @@ ec_key_new_from_group(VALUE arg) EC_KEY *ec; if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - EC_GROUP *group; + EC_GROUP *group; - GetECGroup(arg, group); - if (!(ec = EC_KEY_new())) - ossl_raise(eECError, NULL); + GetECGroup(arg, group); + if (!(ec = EC_KEY_new())) + ossl_raise(ePKeyError, NULL); - if (!EC_KEY_set_group(ec, group)) { - EC_KEY_free(ec); - ossl_raise(eECError, NULL); - } + if (!EC_KEY_set_group(ec, group)) { + EC_KEY_free(ec); + ossl_raise(ePKeyError, NULL); + } } else { - int nid = OBJ_sn2nid(StringValueCStr(arg)); + int nid = OBJ_sn2nid(StringValueCStr(arg)); - if (nid == NID_undef) - ossl_raise(eECError, "invalid curve name"); + if (nid == NID_undef) + ossl_raise(ePKeyError, "invalid curve name"); - if (!(ec = EC_KEY_new_by_curve_name(nid))) - ossl_raise(eECError, NULL); + if (!(ec = EC_KEY_new_by_curve_name(nid))) + ossl_raise(ePKeyError, NULL); - EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); + EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); + EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } return ec; @@ -109,15 +107,18 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) VALUE obj; obj = rb_obj_alloc(klass); - GetPKey(obj, pkey); ec = ec_key_new_from_group(arg); - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { + EVP_PKEY_free(pkey); EC_KEY_free(ec); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); } + RTYPEDDATA_DATA(obj) = pkey; + if (!EC_KEY_generate_key(ec)) - ossl_raise(eECError, "EC_KEY_generate_key"); + ossl_raise(ePKeyError, "EC_KEY_generate_key"); return obj; } @@ -136,75 +137,89 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - EC_KEY *ec = NULL; + EC_KEY *ec; + BIO *in; VALUE arg, pass; + int type; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eECError, "EC_KEY already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); - if (NIL_P(arg)) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::EC.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else if (!(ec = EC_KEY_new())) - ossl_raise(eECError, NULL); - } else if (rb_obj_is_kind_of(arg, cEC)) { - EC_KEY *other_ec = NULL; - - GetEC(arg, other_ec); - if (!(ec = EC_KEY_dup(other_ec))) - ossl_raise(eECError, NULL); - } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - ec = ec_key_new_from_group(arg); - } else { - BIO *in = ossl_obj2bio(&arg); - EVP_PKEY *tmp; - pass = ossl_pem_passwd_value(pass); - tmp = ossl_pkey_read_generic(in, pass); - if (tmp) { - if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC) - rb_raise(eECError, "incorrect pkey type: %s", - OBJ_nid2sn(EVP_PKEY_base_id(tmp))); - ec = EVP_PKEY_get1_EC_KEY(tmp); - EVP_PKEY_free(tmp); - } - BIO_free(in); + ossl_raise(ePKeyError, "EC_KEY_new"); + goto legacy; +#endif + } + else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { + ec = ec_key_new_from_group(arg); + goto legacy; + } + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); - if (!ec) { - ossl_clear_error(); - ec = ec_key_new_from_group(arg); - } + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) { + ossl_clear_error(); + ec = ec_key_new_from_group(arg); + goto legacy; } - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { - EC_KEY_free(ec); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_EC) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } + RTYPEDDATA_DATA(self) = pkey; + return self; + legacy: + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { + EVP_PKEY_free(pkey); + EC_KEY_free(ec); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_ec_key_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; EC_KEY *ec, *ec_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eECError, "EC already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetEC(other, ec); ec_new = EC_KEY_dup(ec); if (!ec_new) - ossl_raise(eECError, "EC_KEY_dup"); - if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { - EC_KEY_free(ec_new); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); + ossl_raise(ePKeyError, "EC_KEY_dup"); + + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) { + EC_KEY_free(ec_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -216,13 +231,13 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) static VALUE ossl_ec_key_get_group(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const EC_GROUP *group; GetEC(self, ec); group = EC_KEY_get0_group(ec); if (!group) - return Qnil; + return Qnil; return ec_group_new(group); } @@ -237,6 +252,9 @@ ossl_ec_key_get_group(VALUE self) static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; EC_GROUP *group; @@ -244,9 +262,10 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) GetECGroup(group_v, group); if (EC_KEY_set_group(ec, group) != 1) - ossl_raise(eECError, "EC_KEY_set_group"); + ossl_raise(ePKeyError, "EC_KEY_set_group"); return group_v; +#endif } /* @@ -257,7 +276,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) */ static VALUE ossl_ec_key_get_private_key(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const BIGNUM *bn; GetEC(self, ec); @@ -275,6 +294,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self) */ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; BIGNUM *bn = NULL; @@ -283,17 +305,18 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) bn = GetBNPtr(private_key); switch (EC_KEY_set_private_key(ec, bn)) { - case 1: + case 1: break; - case 0: + case 0: if (bn == NULL) break; - /* fallthrough */ - default: - ossl_raise(eECError, "EC_KEY_set_private_key"); + /* fallthrough */ + default: + ossl_raise(ePKeyError, "EC_KEY_set_private_key"); } return private_key; +#endif } /* @@ -304,7 +327,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) */ static VALUE ossl_ec_key_get_public_key(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const EC_POINT *point; GetEC(self, ec); @@ -322,6 +345,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self) */ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; EC_POINT *point = NULL; @@ -330,17 +356,18 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) GetECPoint(public_key, point); switch (EC_KEY_set_public_key(ec, point)) { - case 1: + case 1: break; - case 0: + case 0: if (point == NULL) break; - /* fallthrough */ - default: - ossl_raise(eECError, "EC_KEY_set_public_key"); + /* fallthrough */ + default: + ossl_raise(ePKeyError, "EC_KEY_set_public_key"); } return public_key; +#endif } /* @@ -352,7 +379,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) */ static VALUE ossl_ec_key_is_public(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); @@ -368,7 +395,7 @@ static VALUE ossl_ec_key_is_public(VALUE self) */ static VALUE ossl_ec_key_is_private(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); @@ -377,20 +404,70 @@ static VALUE ossl_ec_key_is_private(VALUE self) /* * call-seq: - * key.export([cipher, pass_phrase]) => String - * key.to_pem([cipher, pass_phrase]) => String + * key.export([cipher, password]) => String + * key.to_pem([cipher, password]) => String + * + * Serializes a private or public key to a PEM-encoding. + * + * [When the key contains public components only] + * + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + * + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether it is a public key + * or a private key. + * + * [When the key contains private components, and no parameters are given] + * + * Serializes it into a SEC 1/RFC 5915 ECPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN EC PRIVATE KEY----- + * [...] + * -----END EC PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] * - * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given - * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher - * instance. Note that encryption will only be effective for a private key, - * public keys will always be encoded in plain text. + * Serializes it into a SEC 1/RFC 5915 ECPrivateKey + * and encrypts it in OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN EC PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 + * + * [...] + * -----END EC PRIVATE KEY----- + * + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is + * required. + * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); + if (EC_KEY_get0_public_key(ec) == NULL) + ossl_raise(ePKeyError, "can't export - no public key set"); if (EC_KEY_get0_private_key(ec)) return ossl_pkey_export_traditional(argc, argv, self, 0); else @@ -401,14 +478,24 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self) * call-seq: * key.to_der => String * - * See the OpenSSL documentation for i2d_ECPrivateKey_bio() + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is + * required. + * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE ossl_ec_key_to_der(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); + if (EC_KEY_get0_public_key(ec) == NULL) + ossl_raise(ePKeyError, "can't export - no public key set"); if (EC_KEY_get0_private_key(ec)) return ossl_pkey_export_traditional(0, NULL, self, 1); else @@ -430,13 +517,17 @@ ossl_ec_key_to_der(VALUE self) */ static VALUE ossl_ec_key_generate_key(VALUE self) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; GetEC(self, ec); if (EC_KEY_generate_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_generate_key"); + ossl_raise(ePKeyError, "EC_KEY_generate_key"); return self; +#endif } /* @@ -452,22 +543,34 @@ static VALUE ossl_ec_key_check_key(VALUE self) #ifdef HAVE_EVP_PKEY_CHECK EVP_PKEY *pkey; EVP_PKEY_CTX *pctx; - int ret; + const EC_KEY *ec; GetPKey(self, pkey); + GetEC(self, ec); pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); if (!pctx) - ossl_raise(eDHError, "EVP_PKEY_CTX_new"); - ret = EVP_PKEY_public_check(pctx); + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + + if (EC_KEY_get0_private_key(ec) != NULL) { + if (EVP_PKEY_check(pctx) != 1) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(ePKeyError, "EVP_PKEY_check"); + } + } + else { + if (EVP_PKEY_public_check(pctx) != 1) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(ePKeyError, "EVP_PKEY_public_check"); + } + } + EVP_PKEY_CTX_free(pctx); - if (ret != 1) - ossl_raise(eECError, "EVP_PKEY_public_check"); #else EC_KEY *ec; GetEC(self, ec); if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_check_key"); + ossl_raise(ePKeyError, "EC_KEY_check_key"); #endif return Qtrue; @@ -479,15 +582,15 @@ static VALUE ossl_ec_key_check_key(VALUE self) static void ossl_ec_group_free(void *ptr) { - EC_GROUP_clear_free(ptr); + EC_GROUP_free(ptr); } static const rb_data_type_t ossl_ec_group_type = { "OpenSSL/ec_group", { - 0, ossl_ec_group_free, + 0, ossl_ec_group_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -505,7 +608,7 @@ ec_group_new(const EC_GROUP *group) obj = ossl_ec_group_alloc(cEC_GROUP); group_new = EC_GROUP_dup(group); if (!group_new) - ossl_raise(eEC_GROUP, "EC_GROUP_dup"); + ossl_raise(eEC_GROUP, "EC_GROUP_dup"); RTYPEDDATA_DATA(obj) = group_new; return obj; @@ -533,7 +636,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized"); switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) { - case 1: + case 1: if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { const EC_GROUP *arg1_group; @@ -545,7 +648,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); if (!group) { - OSSL_BIO_reset(in); + OSSL_BIO_reset(in); group = d2i_ECPKParameters_bio(in, NULL); } @@ -555,11 +658,14 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) const char *name = StringValueCStr(arg1); int nid = OBJ_sn2nid(name); - ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ + ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ if (nid == NID_undef) ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1); - +#if !defined(OPENSSL_IS_AWSLC) group = EC_GROUP_new_by_curve_name(nid); +#else /* EC_GROUPs are static and immutable by default in AWS-LC. */ + group = EC_GROUP_new_by_curve_name_mutable(nid); +#endif if (group == NULL) ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1); @@ -569,33 +675,34 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) } break; - case 4: + case 4: if (SYMBOL_P(arg1)) { - ID id = SYM2ID(arg1); EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; const BIGNUM *p = GetBNPtr(arg2); const BIGNUM *a = GetBNPtr(arg3); const BIGNUM *b = GetBNPtr(arg4); - if (id == s_GFp) { + if (arg1 == sym_GFp) { new_curve = EC_GROUP_new_curve_GFp; + } #if !defined(OPENSSL_NO_EC2M) - } else if (id == s_GF2m) { + else if (arg1 == sym_GF2m) { new_curve = EC_GROUP_new_curve_GF2m; + } #endif - } else { + else { ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m"); } if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL) ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*"); } else { - ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m"); + ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m"); } break; - default: - ossl_raise(rb_eArgError, "wrong number of arguments"); + default: + ossl_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1 or 4)", argc); } ASSUME(group); @@ -604,6 +711,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_ec_group_initialize_copy(VALUE self, VALUE other) { @@ -611,12 +719,12 @@ ossl_ec_group_initialize_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new); if (group_new) - ossl_raise(eEC_GROUP, "EC::Group already initialized"); + ossl_raise(eEC_GROUP, "EC::Group already initialized"); GetECGroup(other, group); group_new = EC_GROUP_dup(group); if (!group_new) - ossl_raise(eEC_GROUP, "EC_GROUP_dup"); + ossl_raise(eEC_GROUP, "EC_GROUP_dup"); RTYPEDDATA_DATA(self) = group_new; return self; @@ -637,10 +745,11 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b) GetECGroup(a, group1); GetECGroup(b, group2); - if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1) - return Qfalse; - - return Qtrue; + switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) { + case 0: return Qtrue; + case 1: return Qfalse; + default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp"); + } } /* @@ -659,7 +768,7 @@ static VALUE ossl_ec_group_get_generator(VALUE self) GetECGroup(self, group); generator = EC_GROUP_get0_generator(group); if (!generator) - return Qnil; + return Qnil; return ec_point_new(generator, group); } @@ -702,11 +811,10 @@ static VALUE ossl_ec_group_get_order(VALUE self) { VALUE bn_obj; BIGNUM *bn; - EC_GROUP *group = NULL; + EC_GROUP *group; GetECGroup(self, group); - - bn_obj = ossl_bn_new(NULL); + bn_obj = ossl_bn_new(BN_value_one()); bn = GetBNPtr(bn_obj); if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1) @@ -727,11 +835,10 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) { VALUE bn_obj; BIGNUM *bn; - EC_GROUP *group = NULL; + EC_GROUP *group; GetECGroup(self, group); - - bn_obj = ossl_bn_new(NULL); + bn_obj = ossl_bn_new(BN_value_one()); bn = GetBNPtr(bn_obj); if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1) @@ -742,25 +849,23 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) /* * call-seq: - * group.curve_name => String + * group.curve_name -> string or nil * - * Returns the curve name (sn). + * Returns the curve name (short name) corresponding to this group, or +nil+ + * if \OpenSSL does not have an OID associated with the group. * * See the OpenSSL documentation for EC_GROUP_get_curve_name() */ static VALUE ossl_ec_group_get_curve_name(VALUE self) { - EC_GROUP *group = NULL; + EC_GROUP *group; int nid; GetECGroup(self, group); - if (group == NULL) - return Qnil; - nid = EC_GROUP_get_curve_name(group); - -/* BUG: an nid or asn1 object should be returned, maybe. */ - return rb_str_new2(OBJ_nid2sn(nid)); + if (nid == NID_undef) + return Qnil; + return rb_str_new_cstr(OBJ_nid2sn(nid)); } /* @@ -853,37 +958,36 @@ static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v) */ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self) { - EC_GROUP *group = NULL; + EC_GROUP *group; point_conversion_form_t form; - VALUE ret; GetECGroup(self, group); form = EC_GROUP_get_point_conversion_form(group); switch (form) { - case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break; - case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break; - case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break; - default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form); + case POINT_CONVERSION_UNCOMPRESSED: + return sym_uncompressed; + case POINT_CONVERSION_COMPRESSED: + return sym_compressed; + case POINT_CONVERSION_HYBRID: + return sym_hybrid; + default: + ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, " \ + "this module should be updated", form); } - - return ID2SYM(ret); } static point_conversion_form_t parse_point_conversion_form_symbol(VALUE sym) { - ID id = SYM2ID(sym); - - if (id == ID_uncompressed) - return POINT_CONVERSION_UNCOMPRESSED; - else if (id == ID_compressed) - return POINT_CONVERSION_COMPRESSED; - else if (id == ID_hybrid) - return POINT_CONVERSION_HYBRID; - else - ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE - " (expected :compressed, :uncompressed, or :hybrid)", sym); + if (sym == sym_uncompressed) + return POINT_CONVERSION_UNCOMPRESSED; + if (sym == sym_compressed) + return POINT_CONVERSION_COMPRESSED; + if (sym == sym_hybrid) + return POINT_CONVERSION_HYBRID; + ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE + " (expected :compressed, :uncompressed, or :hybrid)", sym); } /* @@ -988,20 +1092,20 @@ static VALUE ossl_ec_group_to_string(VALUE self, int format) ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); switch(format) { - case EXPORT_PEM: + case EXPORT_PEM: i = PEM_write_bio_ECPKParameters(out, group); - break; - case EXPORT_DER: + break; + case EXPORT_DER: i = i2d_ECPKParameters_bio(out, group); - break; - default: + break; + default: BIO_free(out); - ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); + ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); } if (i != 1) { BIO_free(out); - ossl_raise(eECError, NULL); + ossl_raise(ePKeyError, NULL); } str = ossl_membio2str(out); @@ -1045,11 +1149,11 @@ static VALUE ossl_ec_group_to_text(VALUE self) GetECGroup(self, group); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); + ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); } if (!ECPKParameters_print(out, group, 0)) { - BIO_free(out); - ossl_raise(eEC_GROUP, NULL); + BIO_free(out); + ossl_raise(eEC_GROUP, NULL); } str = ossl_membio2str(out); @@ -1069,9 +1173,9 @@ ossl_ec_point_free(void *ptr) static const rb_data_type_t ossl_ec_point_type = { "OpenSSL/EC_POINT", { - 0, ossl_ec_point_free, + 0, ossl_ec_point_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1089,7 +1193,7 @@ ec_point_new(const EC_POINT *point, const EC_GROUP *group) obj = ossl_ec_point_alloc(cEC_POINT); point_new = EC_POINT_dup(point, group); if (!point_new) - ossl_raise(eEC_POINT, "EC_POINT_dup"); + ossl_raise(eEC_POINT, "EC_POINT_dup"); RTYPEDDATA_DATA(obj) = point_new; rb_ivar_set(obj, id_i_group, ec_group_new(group)); @@ -1117,39 +1221,39 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point); if (point) - rb_raise(eEC_POINT, "EC_POINT already initialized"); + rb_raise(eEC_POINT, "EC_POINT already initialized"); rb_scan_args(argc, argv, "11", &group_v, &arg2); if (rb_obj_is_kind_of(group_v, cEC_POINT)) { - if (argc != 1) - rb_raise(rb_eArgError, "invalid second argument"); - return ossl_ec_point_initialize_copy(self, group_v); + if (argc != 1) + rb_raise(rb_eArgError, "invalid second argument"); + return ossl_ec_point_initialize_copy(self, group_v); } GetECGroup(group_v, group); if (argc == 1) { - point = EC_POINT_new(group); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_new"); + point = EC_POINT_new(group); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_new"); } else { - if (rb_obj_is_kind_of(arg2, cBN)) { - point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_bn2point"); - } - else { - StringValue(arg2); - point = EC_POINT_new(group); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_new"); - if (!EC_POINT_oct2point(group, point, - (unsigned char *)RSTRING_PTR(arg2), - RSTRING_LEN(arg2), ossl_bn_ctx)) { - EC_POINT_free(point); - ossl_raise(eEC_POINT, "EC_POINT_oct2point"); - } - } + if (rb_obj_is_kind_of(arg2, cBN)) { + point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_bn2point"); + } + else { + StringValue(arg2); + point = EC_POINT_new(group); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_new"); + if (!EC_POINT_oct2point(group, point, + (unsigned char *)RSTRING_PTR(arg2), + RSTRING_LEN(arg2), ossl_bn_ctx)) { + EC_POINT_free(point); + ossl_raise(eEC_POINT, "EC_POINT_oct2point"); + } + } } RTYPEDDATA_DATA(self) = point; @@ -1158,6 +1262,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_ec_point_initialize_copy(VALUE self, VALUE other) { @@ -1167,7 +1272,7 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new); if (point_new) - ossl_raise(eEC_POINT, "EC::Point already initialized"); + ossl_raise(eEC_POINT, "EC::Point already initialized"); GetECPoint(other, point); group_v = rb_obj_dup(rb_attr_get(other, id_i_group)); @@ -1175,7 +1280,7 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other) point_new = EC_POINT_dup(point, group); if (!point_new) - ossl_raise(eEC_POINT, "EC_POINT_dup"); + ossl_raise(eEC_POINT, "EC_POINT_dup"); RTYPEDDATA_DATA(self) = point_new; rb_ivar_set(self, id_i_group, group_v); @@ -1201,10 +1306,13 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b) GetECPoint(b, point2); GetECGroup(group_v1, group); - if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1) - return Qfalse; + switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) { + case 0: return Qtrue; + case 1: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_cmp"); + } - return Qtrue; + UNREACHABLE; } /* @@ -1220,9 +1328,9 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self) GetECPointGroup(self, group); switch (EC_POINT_is_at_infinity(group, point)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity"); + case 1: return Qtrue; + case 0: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity"); } UNREACHABLE; @@ -1241,9 +1349,9 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self) GetECPointGroup(self, group); switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve"); + case 1: return Qtrue; + case 0: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve"); } UNREACHABLE; @@ -1252,6 +1360,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self) /* * call-seq: * point.make_affine! => self + * + * This method is deprecated and should not be used. This is a no-op. */ static VALUE ossl_ec_point_make_affine(VALUE self) { @@ -1261,8 +1371,11 @@ static VALUE ossl_ec_point_make_affine(VALUE self) GetECPoint(self, point); GetECPointGroup(self, group); + rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated"); +#if !defined(OSSL_HAVE_IMMUTABLE_PKEY) && !defined(OPENSSL_IS_AWSLC) if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_make_affine"); + ossl_raise(eEC_POINT, "EC_POINT_make_affine"); +#endif return self; } @@ -1280,7 +1393,7 @@ static VALUE ossl_ec_point_invert(VALUE self) GetECPointGroup(self, group); if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_invert"); + ossl_raise(eEC_POINT, "EC_POINT_invert"); return self; } @@ -1298,7 +1411,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self) GetECPointGroup(self, group); if (EC_POINT_set_to_infinity(group, point) != 1) - ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity"); + ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity"); return self; } @@ -1330,12 +1443,12 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form) len = EC_POINT_point2oct(group, point, form, NULL, 0, ossl_bn_ctx); if (!len) - ossl_raise(eEC_POINT, "EC_POINT_point2oct"); + ossl_raise(eEC_POINT, "EC_POINT_point2oct"); str = rb_str_new(NULL, (long)len); if (!EC_POINT_point2oct(group, point, form, - (unsigned char *)RSTRING_PTR(str), len, - ossl_bn_ctx)) - ossl_raise(eEC_POINT, "EC_POINT_point2oct"); + (unsigned char *)RSTRING_PTR(str), len, + ossl_bn_ctx)) + ossl_raise(eEC_POINT, "EC_POINT_point2oct"); return str; } @@ -1370,7 +1483,6 @@ static VALUE ossl_ec_point_add(VALUE self, VALUE other) /* * call-seq: * point.mul(bn1 [, bn2]) => point - * point.mul(bns, points [, bn2]) => point * * Performs elliptic curve point multiplication. * @@ -1378,11 +1490,9 @@ static VALUE ossl_ec_point_add(VALUE self, VALUE other) * generator of the group of _point_. _bn2_ may be omitted, and in that case, * the result is just <tt>bn1 * point</tt>. * - * The second form calculates <tt>bns[0] * point + bns[1] * points[0] + ... - * + bns[-1] * points[-1] + bn2 * G</tt>. _bn2_ may be omitted. _bns_ must be - * an array of OpenSSL::BN. _points_ must be an array of - * OpenSSL::PKey::EC::Point. Please note that <tt>points[0]</tt> is not - * multiplied by <tt>bns[0]</tt>, but <tt>bns[1]</tt>. + * Before version 4.0.0, and when compiled with OpenSSL 1.1.1 or older, this + * method allowed another form: + * point.mul(bns, points [, bn2]) => point */ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) { @@ -1400,62 +1510,15 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) GetECPoint(result, point_result); rb_scan_args(argc, argv, "12", &arg1, &arg2, &arg3); - if (!RB_TYPE_P(arg1, T_ARRAY)) { - BIGNUM *bn = GetBNPtr(arg1); + if (RB_TYPE_P(arg1, T_ARRAY) || argc > 2) + rb_raise(rb_eNotImpError, "OpenSSL::PKey::EC::Point#mul with arrays " \ + "is no longer supported"); - if (!NIL_P(arg2)) - bn_g = GetBNPtr(arg2); - if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) - ossl_raise(eEC_POINT, NULL); - } else { -#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER) - rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \ - "supported by this OpenSSL version"); -#else - /* - * bignums | arg1[0] | arg1[1] | arg1[2] | ... - * points | self | arg2[0] | arg2[1] | ... - */ - long i, num; - VALUE bns_tmp, tmp_p, tmp_b; - const EC_POINT **points; - const BIGNUM **bignums; - - Check_Type(arg1, T_ARRAY); - Check_Type(arg2, T_ARRAY); - if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */ - ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation"); - - rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \ - "use #mul(bn) form instead"); - - num = RARRAY_LEN(arg1); - bns_tmp = rb_ary_tmp_new(num); - bignums = ALLOCV_N(const BIGNUM *, tmp_b, num); - for (i = 0; i < num; i++) { - VALUE item = RARRAY_AREF(arg1, i); - bignums[i] = GetBNPtr(item); - rb_ary_push(bns_tmp, item); - } - - points = ALLOCV_N(const EC_POINT *, tmp_p, num); - points[0] = point_self; /* self */ - for (i = 0; i < num - 1; i++) - GetECPoint(RARRAY_AREF(arg2, i), points[i + 1]); - - if (!NIL_P(arg3)) - bn_g = GetBNPtr(arg3); - - if (EC_POINTs_mul(group, point_result, bn_g, num, points, bignums, ossl_bn_ctx) != 1) { - ALLOCV_END(tmp_b); - ALLOCV_END(tmp_p); - ossl_raise(eEC_POINT, NULL); - } - - ALLOCV_END(tmp_b); - ALLOCV_END(tmp_p); -#endif - } + BIGNUM *bn = GetBNPtr(arg1); + if (!NIL_P(arg2)) + bn_g = GetBNPtr(arg2); + if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) + ossl_raise(eEC_POINT, NULL); return result; } @@ -1463,15 +1526,6 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) void Init_ossl_ec(void) { #undef rb_intern -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - eECError = rb_define_class_under(mPKey, "ECError", ePKeyError); - /* * Document-class: OpenSSL::PKey::EC * @@ -1493,24 +1547,23 @@ void Init_ossl_ec(void) eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError); eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError); - s_GFp = rb_intern("GFp"); - s_GF2m = rb_intern("GF2m"); + sym_GFp = ID2SYM(rb_intern_const("GFp")); + sym_GF2m = ID2SYM(rb_intern_const("GF2m")); - ID_uncompressed = rb_intern("uncompressed"); - ID_compressed = rb_intern("compressed"); - ID_hybrid = rb_intern("hybrid"); + sym_uncompressed = ID2SYM(rb_intern_const("uncompressed")); + sym_compressed = ID2SYM(rb_intern_const("compressed")); + sym_hybrid = ID2SYM(rb_intern_const("hybrid")); rb_define_const(cEC, "NAMED_CURVE", INT2NUM(OPENSSL_EC_NAMED_CURVE)); -#if defined(OPENSSL_EC_EXPLICIT_CURVE) rb_define_const(cEC, "EXPLICIT_CURVE", INT2NUM(OPENSSL_EC_EXPLICIT_CURVE)); -#endif rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0); rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1); rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1); -/* copy/dup/cmp */ +#endif rb_define_method(cEC, "group", ossl_ec_key_get_group, 0); rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1); diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 8ebd3ec559..039b2c6a34 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,17 +14,19 @@ #define GetPKeyRSA(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \ } \ } while (0) #define GetRSA(obj, rsa) do { \ EVP_PKEY *_pkey; \ GetPKeyRSA((obj), _pkey); \ (rsa) = EVP_PKEY_get0_RSA(_pkey); \ + if ((rsa) == NULL) \ + ossl_raise(ePKeyError, "failed to get RSA from EVP_PKEY"); \ } while (0) static inline int -RSA_HAS_PRIVATE(RSA *rsa) +RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa) { const BIGNUM *e, *d; @@ -33,7 +35,7 @@ RSA_HAS_PRIVATE(RSA *rsa) } static inline int -RSA_PRIVATE(VALUE obj, RSA *rsa) +RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa) { return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj); } @@ -42,7 +44,6 @@ RSA_PRIVATE(VALUE obj, RSA *rsa) * Classes */ VALUE cRSA; -VALUE eRSAError; /* * Private @@ -50,8 +51,8 @@ VALUE eRSAError; /* * call-seq: * RSA.new -> rsa - * RSA.new(encoded_key [, passphrase]) -> rsa - * RSA.new(encoded_key) { passphrase } -> rsa + * RSA.new(encoded_key [, password ]) -> rsa + * RSA.new(encoded_key) { password } -> rsa * RSA.new(size [, exponent]) -> rsa * * Generates or loads an \RSA keypair. @@ -59,11 +60,12 @@ VALUE eRSAError; * If called without arguments, creates a new instance with no key components * set. They can be set individually by #set_key, #set_factors, and * #set_crt_params. + * This form is not compatible with OpenSSL 3.0 or later. * * If called with a String, tries to parse as DER or PEM encoding of an \RSA key. - * Note that, if _passphrase_ is not specified but the key is encrypted with a - * passphrase, \OpenSSL will prompt for it. - * See also OpenSSL::PKey.read which can parse keys of any kinds. + * Note that if _password_ is not specified, but the key is encrypted with a + * password, \OpenSSL will prompt for it. + * See also OpenSSL::PKey.read which can parse keys of any kind. * * If called with a number, generates a new key pair. This form works as an * alias of RSA.generate. @@ -71,78 +73,104 @@ VALUE eRSAError; * Examples: * OpenSSL::PKey::RSA.new 2048 * OpenSSL::PKey::RSA.new File.read 'rsa.pem' - * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase' + * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password' */ static VALUE ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) { - EVP_PKEY *pkey, *tmp; - RSA *rsa = NULL; - BIO *in; + EVP_PKEY *pkey; + RSA *rsa; + BIO *in = NULL; VALUE arg, pass; + int type; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); - GetPKey(self, pkey); /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ rb_scan_args(argc, argv, "02", &arg, &pass); if (argc == 0) { - rsa = RSA_new(); +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::RSA.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else + rsa = RSA_new(); if (!rsa) - ossl_raise(eRSAError, "RSA_new"); - } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - - tmp = ossl_pkey_read_generic(in, pass); - if (tmp) { - if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA) - rb_raise(eRSAError, "incorrect pkey type: %s", - OBJ_nid2sn(EVP_PKEY_base_id(tmp))); - rsa = EVP_PKEY_get1_RSA(tmp); - EVP_PKEY_free(tmp); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSAPublicKey_bio(in, NULL); - } - BIO_free(in); - if (!rsa) { - ossl_clear_error(); - ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); - } + ossl_raise(ePKeyError, "RSA_new"); + goto legacy; +#endif } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); - ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* First try RSAPublicKey format */ + rsa = d2i_RSAPublicKey_bio(in, NULL); + if (rsa) + goto legacy; + OSSL_BIO_reset(in); + rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); + if (rsa) + goto legacy; + OSSL_BIO_reset(in); + + /* Use the generic routine */ + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "Neither PUB key nor PRIV key"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_RSA) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } + RTYPEDDATA_DATA(self) = pkey; + return self; + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + EVP_PKEY_free(pkey); + RSA_free(rsa); + ossl_raise(ePKeyError, "EVP_PKEY_assign_RSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_rsa_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; RSA *rsa, *rsa_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eRSAError, "RSA already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetRSA(other, rsa); - rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa); + rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, + (d2i_of_void *)d2i_RSAPrivateKey, + (char *)rsa); if (!rsa_new) - ossl_raise(eRSAError, "ASN1_dup"); + ossl_raise(ePKeyError, "ASN1_dup"); - EVP_PKEY_assign_RSA(pkey, rsa_new); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) { + RSA_free(rsa_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_RSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -154,7 +182,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) static VALUE ossl_rsa_is_public(VALUE self) { - RSA *rsa; + OSSL_3_const RSA *rsa; GetRSA(self, rsa); /* @@ -173,7 +201,7 @@ ossl_rsa_is_public(VALUE self) static VALUE ossl_rsa_is_private(VALUE self) { - RSA *rsa; + OSSL_3_const RSA *rsa; GetRSA(self, rsa); @@ -183,7 +211,7 @@ ossl_rsa_is_private(VALUE self) static int can_export_rsaprivatekey(VALUE self) { - RSA *rsa; + OSSL_3_const RSA *rsa; const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; GetRSA(self, rsa); @@ -197,13 +225,61 @@ can_export_rsaprivatekey(VALUE self) /* * call-seq: - * rsa.export([cipher, pass_phrase]) => PEM-format String - * rsa.to_pem([cipher, pass_phrase]) => PEM-format String - * rsa.to_s([cipher, pass_phrase]) => PEM-format String + * rsa.export([cipher, password]) => PEM-format String + * rsa.to_pem([cipher, password]) => PEM-format String + * rsa.to_s([cipher, password]) => PEM-format String + * + * Serializes a private or public key to a PEM-encoding. + * + * [When the key contains public components only] + * + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + * + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether the key is a public key + * or a private key. + * + * [When the key contains private components, and no parameters are given] + * + * Serializes it into a PKCS #1 RSAPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN RSA PRIVATE KEY----- + * [...] + * -----END RSA PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] + * + * Serializes it into a PKCS #1 RSAPrivateKey + * and encrypts it in OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN RSA PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 + * + * [...] + * -----END RSA PRIVATE KEY----- + * + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. * - * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are - * given they will be used to encrypt the key. _cipher_ must be an - * OpenSSL::Cipher instance. + * <b>This method is kept for compatibility.</b> + * This should only be used when the PKCS #1 RSAPrivateKey format is required. + * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ static VALUE ossl_rsa_export(int argc, VALUE *argv, VALUE self) @@ -218,7 +294,14 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self) * call-seq: * rsa.to_der => DER-format String * - * Outputs this keypair in DER encoding. + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the PKCS #1 RSAPrivateKey format is required. + * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE ossl_rsa_to_der(VALUE self) @@ -236,7 +319,7 @@ ossl_rsa_to_der(VALUE self) * Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns * the calculated signature. * - * RSAError will be raised if an error occurs. + * PKeyError will be raised if an error occurs. * * See #verify_pss for the verification operation. * @@ -265,7 +348,7 @@ ossl_rsa_to_der(VALUE self) static VALUE ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) { - VALUE digest, data, options, kwargs[2], signature; + VALUE digest, data, options, kwargs[2], signature, mgf1md_holder, md_holder; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; @@ -275,46 +358,46 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) int salt_len; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt_length"); - kwargs_ids[1] = rb_intern_const("mgf1_hash"); + kwargs_ids[0] = rb_intern_const("salt_length"); + kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "2:", &digest, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("max"))) - salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */ + salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) - salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ + salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else - salt_len = NUM2INT(kwargs[0]); - mgf1md = ossl_evp_get_digestbyname(kwargs[1]); + salt_len = NUM2INT(kwargs[0]); + mgf1md = ossl_evp_md_fetch(kwargs[1], &mgf1md_holder); pkey = GetPrivPKeyPtr(self); buf_len = EVP_PKEY_size(pkey); - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(data); signature = rb_str_new(NULL, (long)buf_len); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) - goto err; + goto err; if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) - goto err; + goto err; if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) - goto err; + goto err; if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1) - goto err; + goto err; rb_str_set_len(signature, (long)buf_len); @@ -323,7 +406,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) err: EVP_MD_CTX_free(md_ctx); - ossl_raise(eRSAError, NULL); + ossl_raise(ePKeyError, NULL); } /* @@ -333,7 +416,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) * Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS). * * The return value is +true+ if the signature is valid, +false+ otherwise. - * RSAError will be raised if an error occurs. + * PKeyError will be raised if an error occurs. * * See #sign_pss for the signing operation and an example code. * @@ -352,7 +435,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) static VALUE ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self) { - VALUE digest, signature, data, options, kwargs[2]; + VALUE digest, signature, data, options, kwargs[2], mgf1md_holder, md_holder; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; @@ -361,98 +444,61 @@ ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self) int result, salt_len; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt_length"); - kwargs_ids[1] = rb_intern_const("mgf1_hash"); + kwargs_ids[0] = rb_intern_const("salt_length"); + kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("auto"))) - salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */ + salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) - salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ + salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else - salt_len = NUM2INT(kwargs[0]); - mgf1md = ossl_evp_get_digestbyname(kwargs[1]); + salt_len = NUM2INT(kwargs[0]); + mgf1md = ossl_evp_md_fetch(kwargs[1], &mgf1md_holder); GetPKey(self, pkey); - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(signature); StringValue(data); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) - goto err; + goto err; if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) - goto err; + goto err; if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) - goto err; + goto err; result = EVP_DigestVerifyFinal(md_ctx, - (unsigned char *)RSTRING_PTR(signature), - RSTRING_LEN(signature)); + (unsigned char *)RSTRING_PTR(signature), + RSTRING_LEN(signature)); + EVP_MD_CTX_free(md_ctx); switch (result) { case 0: - ossl_clear_error(); - EVP_MD_CTX_free(md_ctx); - return Qfalse; + ossl_clear_error(); + return Qfalse; case 1: - EVP_MD_CTX_free(md_ctx); - return Qtrue; + return Qtrue; default: - goto err; + ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); } err: EVP_MD_CTX_free(md_ctx); - ossl_raise(eRSAError, NULL); -} - -/* - * call-seq: - * rsa.params => hash - * - * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! - * - * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd', - * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'. - * - * Don't use :-)) (It's up to you) - */ -static VALUE -ossl_rsa_get_params(VALUE self) -{ - RSA *rsa; - VALUE hash; - const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &n, &e, &d); - RSA_get0_factors(rsa, &p, &q); - RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n)); - rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e)); - rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d)); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1)); - rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1)); - rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp)); - - return hash; + ossl_raise(ePKeyError, NULL); } /* @@ -490,20 +536,6 @@ OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp) void Init_ossl_rsa(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::RSAError - * - * Generic exception that is raised if an operation on an RSA PKey - * fails unexpectedly or in case an instantiation of an instance of RSA - * fails due to non-conformant input data. - */ - eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError); - /* Document-class: OpenSSL::PKey::RSA * * RSA is an asymmetric public key algorithm that has been formalized in @@ -517,7 +549,9 @@ Init_ossl_rsa(void) cRSA = rb_define_class_under(mPKey, "RSA", cPKey); rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1); +#endif rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); @@ -540,8 +574,6 @@ Init_ossl_rsa(void) rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2); rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3); - rb_define_method(cRSA, "params", ossl_rsa_get_params, 0); - /* * TODO: Test it rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c new file mode 100644 index 0000000000..ea5abb8e48 --- /dev/null +++ b/ext/openssl/ossl_provider.c @@ -0,0 +1,204 @@ +/* + * This program is licensed under the same licence as Ruby. + * (See the file 'COPYING'.) + */ +#include "ossl.h" + +#ifdef OSSL_USE_PROVIDER +#define NewProvider(klass) \ + TypedData_Wrap_Struct((klass), &ossl_provider_type, 0) +#define SetProvider(obj, provider) do { \ + if (!(provider)) { \ + ossl_raise(rb_eRuntimeError, "Provider wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (provider); \ +} while(0) +#define GetProvider(obj, provider) do { \ + TypedData_Get_Struct((obj), OSSL_PROVIDER, &ossl_provider_type, (provider)); \ + if (!(provider)) { \ + ossl_raise(rb_eRuntimeError, "PROVIDER wasn't initialized."); \ + } \ +} while (0) + +static const rb_data_type_t ossl_provider_type = { + "OpenSSL/Provider", + { + 0, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +/* + * Classes + */ +/* Document-class: OpenSSL::Provider + * + * This class is the access to openssl's Provider + * See also, https://www.openssl.org/docs/manmaster/man7/provider.html + */ +static VALUE cProvider; +/* Document-class: OpenSSL::Provider::ProviderError + * + * This is the generic exception for OpenSSL::Provider related errors + */ +static VALUE eProviderError; + +/* + * call-seq: + * OpenSSL::Provider.load(name) -> provider + * + * This method loads and initializes a provider + */ +static VALUE +ossl_provider_s_load(VALUE klass, VALUE name) +{ + OSSL_PROVIDER *provider = NULL; + VALUE obj; + + const char *provider_name_ptr = StringValueCStr(name); + + provider = OSSL_PROVIDER_load(NULL, provider_name_ptr); + if (provider == NULL) { + ossl_raise(eProviderError, "Failed to load %s provider", provider_name_ptr); + } + obj = NewProvider(klass); + SetProvider(obj, provider); + + return obj; +} + +struct ary_with_state { VALUE ary; int state; }; +struct rb_push_provider_name_args { OSSL_PROVIDER *prov; VALUE ary; }; + +static VALUE +rb_push_provider_name(VALUE rb_push_provider_name_args) +{ + struct rb_push_provider_name_args *args = (struct rb_push_provider_name_args *)rb_push_provider_name_args; + + VALUE name = rb_str_new2(OSSL_PROVIDER_get0_name(args->prov)); + return rb_ary_push(args->ary, name); +} + +static int +push_provider(OSSL_PROVIDER *prov, void *cbdata) +{ + struct ary_with_state *ary_with_state = (struct ary_with_state *)cbdata; + struct rb_push_provider_name_args args = { prov, ary_with_state->ary }; + + rb_protect(rb_push_provider_name, (VALUE)&args, &ary_with_state->state); + if (ary_with_state->state) { + return 0; + } else { + return 1; + } +} + +/* + * call-seq: + * OpenSSL::Provider.provider_names -> [provider_name, ...] + * + * Returns an array of currently loaded provider names. + */ +static VALUE +ossl_provider_s_provider_names(VALUE klass) +{ + VALUE ary = rb_ary_new(); + struct ary_with_state cbdata = { ary, 0 }; + + int result = OSSL_PROVIDER_do_all(NULL, &push_provider, (void*)&cbdata); + if (result != 1 ) { + if (cbdata.state) { + rb_jump_tag(cbdata.state); + } else { + ossl_raise(eProviderError, "Failed to load provider names"); + } + } + + return ary; +} + +/* + * call-seq: + * provider.unload -> true + * + * This method unloads this provider. + * + * if provider unload fails or already unloaded, it raises OpenSSL::Provider::ProviderError + */ +static VALUE +ossl_provider_unload(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL) { + ossl_raise(eProviderError, "Provider already unloaded."); + } + GetProvider(self, prov); + + int result = OSSL_PROVIDER_unload(prov); + + if (result != 1) { + ossl_raise(eProviderError, "Failed to unload provider"); + } + RTYPEDDATA_DATA(self) = NULL; + return Qtrue; +} + +/* + * call-seq: + * provider.name -> string + * + * Get the name of this provider. + * + * if this provider is already unloaded, it raises OpenSSL::Provider::ProviderError + */ +static VALUE +ossl_provider_get_name(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL) { + ossl_raise(eProviderError, "Provider already unloaded."); + } + GetProvider(self, prov); + + return rb_str_new2(OSSL_PROVIDER_get0_name(prov)); +} + +/* + * call-seq: + * provider.inspect -> string + * + * Pretty prints this provider. + */ +static VALUE +ossl_provider_inspect(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL ) { + return rb_sprintf("#<%"PRIsVALUE" unloaded provider>", rb_obj_class(self)); + } + GetProvider(self, prov); + + return rb_sprintf("#<%"PRIsVALUE" name=\"%s\">", + rb_obj_class(self), OSSL_PROVIDER_get0_name(prov)); +} + +void +Init_ossl_provider(void) +{ + cProvider = rb_define_class_under(mOSSL, "Provider", rb_cObject); + eProviderError = rb_define_class_under(cProvider, "ProviderError", eOSSLError); + + rb_undef_alloc_func(cProvider); + rb_define_singleton_method(cProvider, "load", ossl_provider_s_load, 1); + rb_define_singleton_method(cProvider, "provider_names", ossl_provider_s_provider_names, 0); + + rb_define_method(cProvider, "unload", ossl_provider_unload, 0); + rb_define_method(cProvider, "name", ossl_provider_get_name, 0); + rb_define_method(cProvider, "inspect", ossl_provider_inspect, 0); +} +#else +void +Init_ossl_provider(void) +{ +} +#endif diff --git a/ext/openssl/ossl_provider.h b/ext/openssl/ossl_provider.h new file mode 100644 index 0000000000..1d69cb1e44 --- /dev/null +++ b/ext/openssl/ossl_provider.h @@ -0,0 +1,5 @@ +#if !defined(OSSL_PROVIDER_H) +#define OSSL_PROVIDER_H + +void Init_ossl_provider(void); +#endif diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c index 659dc818b6..753f8b25f7 100644 --- a/ext/openssl/ossl_rand.c +++ b/ext/openssl/ossl_rand.c @@ -5,12 +5,12 @@ * All rights reserved. * * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -VALUE mRandom; -VALUE eRandomError; +static VALUE mRandom; +static VALUE eRandomError; /* * call-seq: @@ -68,7 +68,7 @@ static VALUE ossl_rand_load_file(VALUE self, VALUE filename) { if(!RAND_load_file(StringValueCStr(filename), -1)) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -85,14 +85,14 @@ static VALUE ossl_rand_write_file(VALUE self, VALUE filename) { if (RAND_write_file(StringValueCStr(filename)) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } /* * call-seq: - * random_bytes(length) -> string + * random_bytes(length) -> string * * Generates a String with _length_ number of cryptographically strong * pseudo-random bytes. @@ -112,9 +112,9 @@ ossl_rand_bytes(VALUE self, VALUE len) str = rb_str_new(0, n); ret = RAND_bytes((unsigned char *)RSTRING_PTR(str), n); if (ret == 0) { - ossl_raise(eRandomError, "RAND_bytes"); + ossl_raise(eRandomError, "RAND_bytes"); } else if (ret == -1) { - ossl_raise(eRandomError, "RAND_bytes is not supported"); + ossl_raise(eRandomError, "RAND_bytes is not supported"); } return str; @@ -131,7 +131,7 @@ static VALUE ossl_rand_egd(VALUE self, VALUE filename) { if (RAND_egd(StringValueCStr(filename)) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -151,7 +151,7 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len) int n = NUM2INT(len); if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -175,11 +175,6 @@ ossl_rand_status(VALUE self) void Init_ossl_rand(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - mRandom = rb_define_module_under(mOSSL, "Random"); eRandomError = rb_define_class_under(mRandom, "RandomError", eOSSLError); @@ -189,9 +184,7 @@ Init_ossl_rand(void) rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1); rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1); rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1); -#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER) rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes"); -#endif #ifdef HAVE_RAND_EGD rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1); rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2); diff --git a/ext/openssl/ossl_rand.h b/ext/openssl/ossl_rand.h index 8f77a3b239..294986d017 100644 --- a/ext/openssl/ossl_rand.h +++ b/ext/openssl/ossl_rand.h @@ -5,14 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_RAND_H_) #define _OSSL_RAND_H_ -extern VALUE mRandom; -extern VALUE eRandomError; - void Init_ossl_rand(void); #endif /* _OSSL_RAND_H_ */ diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index d6d321e446..630d46e43f 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -7,16 +7,15 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +#ifndef OPENSSL_NO_SOCK #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) -#if !defined(TLS1_3_VERSION) && \ - defined(LIBRESSL_VERSION_NUMBER) && \ - LIBRESSL_VERSION_NUMBER >= 0x3020000fL -# define TLS1_3_VERSION 0x0304 +#if !defined(OPENSSL_NO_NEXTPROTONEG) && !OSSL_IS_LIBRESSL +# define OSSL_USE_NEXTPROTONEG #endif #ifdef _WIN32 @@ -26,33 +25,30 @@ #endif #define GetSSLCTX(obj, ctx) do { \ - TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \ + TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \ } while (0) VALUE mSSL; -static VALUE mSSLExtConfig; static VALUE eSSLError; -VALUE cSSLContext; +static VALUE cSSLContext; VALUE cSSLSocket; static VALUE eSSLErrorWaitReadable; static VALUE eSSLErrorWaitWritable; -static ID id_call, ID_callback_state, id_tmp_dh_callback, - id_npn_protocols_encoded, id_each; +static ID id_call, ID_callback_state, id_npn_protocols_encoded, id_each; static VALUE sym_exception, sym_wait_readable, sym_wait_writable; static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode, - id_i_verify_depth, id_i_verify_callback, id_i_client_ca, - id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert, - id_i_client_cert_cb, id_i_timeout, - id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb, - id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols, - id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb, - id_i_verify_hostname; + id_i_verify_depth, id_i_verify_callback, id_i_client_ca, + id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert, + id_i_client_cert_cb, id_i_timeout, + id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb, + id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols, + id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb, + id_i_verify_hostname, id_i_keylog_cb, id_i_tmp_dh_callback; static ID id_i_io, id_i_context, id_i_hostname; -static int ossl_ssl_ex_vcb_idx; static int ossl_ssl_ex_ptr_idx; static int ossl_sslctx_ex_ptr_idx; @@ -74,7 +70,7 @@ static const rb_data_type_t ossl_sslctx_type = { { ossl_sslctx_mark, ossl_sslctx_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -82,127 +78,24 @@ ossl_sslctx_s_alloc(VALUE klass) { SSL_CTX *ctx; long mode = 0 | - SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | - SSL_MODE_RELEASE_BUFFERS; + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_RELEASE_BUFFERS; VALUE obj; obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) ctx = SSL_CTX_new(TLS_method()); -#else - ctx = SSL_CTX_new(SSLv23_method()); -#endif if (!ctx) { ossl_raise(eSSLError, "SSL_CTX_new"); } SSL_CTX_set_mode(ctx, mode); + SSL_CTX_set_dh_auto(ctx, 1); RTYPEDDATA_DATA(obj) = ctx; SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj); -#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \ - !defined(LIBRESSL_VERSION_NUMBER) - /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It - * allows to specify multiple curve names and OpenSSL will select - * automatically from them. In OpenSSL 1.0.2, the automatic selection has to - * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob - * and it is always enabled. To uniform the behavior, we enable the - * automatic selection also in 1.0.2. Users can still disable ECDH by - * removing ECDH cipher suites by SSLContext#ciphers=. */ - if (!SSL_CTX_set_ecdh_auto(ctx, 1)) - ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); -#endif - return obj; } -static int -parse_proto_version(VALUE str) -{ - int i; - static const struct { - const char *name; - int version; - } map[] = { - { "SSL2", SSL2_VERSION }, - { "SSL3", SSL3_VERSION }, - { "TLS1", TLS1_VERSION }, - { "TLS1_1", TLS1_1_VERSION }, - { "TLS1_2", TLS1_2_VERSION }, -#ifdef TLS1_3_VERSION - { "TLS1_3", TLS1_3_VERSION }, -#endif - }; - - if (NIL_P(str)) - return 0; - if (RB_INTEGER_TYPE_P(str)) - return NUM2INT(str); - - if (SYMBOL_P(str)) - str = rb_sym2str(str); - StringValue(str); - for (i = 0; i < numberof(map); i++) - if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str))) - return map[i].version; - rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str); -} - -/* - * call-seq: - * ctx.set_minmax_proto_version(min, max) -> nil - * - * Sets the minimum and maximum supported protocol versions. See #min_version= - * and #max_version=. - */ -static VALUE -ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v) -{ - SSL_CTX *ctx; - int min, max; - - GetSSLCTX(self, ctx); - min = parse_proto_version(min_v); - max = parse_proto_version(max_v); - -#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION - if (!SSL_CTX_set_min_proto_version(ctx, min)) - ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version"); - if (!SSL_CTX_set_max_proto_version(ctx, max)) - ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version"); -#else - { - unsigned long sum = 0, opts = 0; - int i; - static const struct { - int ver; - unsigned long opts; - } options_map[] = { - { SSL2_VERSION, SSL_OP_NO_SSLv2 }, - { SSL3_VERSION, SSL_OP_NO_SSLv3 }, - { TLS1_VERSION, SSL_OP_NO_TLSv1 }, - { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 }, - { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 }, -# if defined(TLS1_3_VERSION) - { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 }, -# endif - }; - - for (i = 0; i < numberof(options_map); i++) { - sum |= options_map[i].opts; - if ((min && min > options_map[i].ver) || - (max && max < options_map[i].ver)) { - opts |= options_map[i].opts; - } - } - SSL_CTX_clear_options(ctx, sum); - SSL_CTX_set_options(ctx, opts); - } -#endif - - return Qnil; -} - static VALUE ossl_call_client_cert_cb(VALUE obj) { @@ -211,7 +104,7 @@ ossl_call_client_cert_cb(VALUE obj) ctx_obj = rb_attr_get(obj, id_i_context); cb = rb_attr_get(ctx_obj, id_i_client_cert_cb); if (NIL_P(cb)) - return Qnil; + return Qnil; ary = rb_funcallv(cb, id_call, 1, &obj); Check_Type(ary, T_ARRAY); @@ -229,7 +122,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); ret = rb_protect(ossl_call_client_cert_cb, obj, NULL); if (NIL_P(ret)) - return 0; + return 0; *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0)); *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1)); @@ -240,8 +133,6 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) #if !defined(OPENSSL_NO_DH) struct tmp_dh_callback_args { VALUE ssl_obj; - ID id; - int type; int is_export; int keylength; }; @@ -250,48 +141,36 @@ static VALUE ossl_call_tmp_dh_callback(VALUE arg) { struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg; - VALUE cb, dh; - EVP_PKEY *pkey; + VALUE ctx_obj, cb, obj; + const DH *dh; - cb = rb_funcall(args->ssl_obj, args->id, 0); + ctx_obj = rb_attr_get(args->ssl_obj, id_i_context); + cb = rb_attr_get(ctx_obj, id_i_tmp_dh_callback); if (NIL_P(cb)) - return (VALUE)NULL; - dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export), - INT2NUM(args->keylength)); - pkey = GetPKeyPtr(dh); - if (EVP_PKEY_base_id(pkey) != args->type) - return (VALUE)NULL; + return (VALUE)NULL; + + obj = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export), + INT2NUM(args->keylength)); + // TODO: We should riase if obj is not DH + dh = EVP_PKEY_get0_DH(GetPKeyPtr(obj)); + if (!dh) + ossl_clear_error(); - return (VALUE)pkey; + return (VALUE)dh; } -#endif -#if !defined(OPENSSL_NO_DH) static DH * ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) { - VALUE rb_ssl; - EVP_PKEY *pkey; - struct tmp_dh_callback_args args; int state; - - rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - args.ssl_obj = rb_ssl; - args.id = id_tmp_dh_callback; - args.is_export = is_export; - args.keylength = keylength; - args.type = EVP_PKEY_DH; - - pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback, - (VALUE)&args, &state); + VALUE rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + struct tmp_dh_callback_args args = {rb_ssl, is_export, keylength}; + VALUE ret = rb_protect(ossl_call_tmp_dh_callback, (VALUE)&args, &state); if (state) { - rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state)); - return NULL; + rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state)); + return NULL; } - if (!pkey) - return NULL; - - return EVP_PKEY_get0_DH(pkey); + return (DH *)ret; } #endif /* OPENSSL_NO_DH */ @@ -307,13 +186,13 @@ call_verify_certificate_identity(VALUE ctx_v) hostname = rb_attr_get(ssl_obj, id_i_hostname); if (!RTEST(hostname)) { - rb_warning("verify_hostname requires hostname to be set"); - return Qtrue; + rb_warning("verify_hostname requires hostname to be set"); + return Qtrue; } cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2, - cert_obj, hostname); + cert_obj, hostname); } static int @@ -324,25 +203,21 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) int status; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); sslctx_obj = rb_attr_get(ssl_obj, id_i_context); + cb = rb_attr_get(sslctx_obj, id_i_verify_callback); verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname); if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) && - !X509_STORE_CTX_get_error_depth(ctx)) { - ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status); - if (status) { - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); - return 0; - } + !X509_STORE_CTX_get_error_depth(ctx)) { + ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status); + if (status) { + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); + return 0; + } if (ret != Qtrue) { preverify_ok = 0; -#if defined(X509_V_ERR_HOSTNAME_MISMATCH) X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH); -#else - X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); -#endif } } @@ -364,11 +239,7 @@ ossl_call_session_get_cb(VALUE ary) } static SSL_SESSION * -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000 ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy) -#else -ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) -#endif { VALUE ary, ssl_obj, ret_obj; SSL_SESSION *sess; @@ -441,6 +312,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess) return 0; } +#if !OSSL_IS_LIBRESSL +/* + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + */ + +struct ossl_call_keylog_cb_args { + VALUE ssl_obj; + const char * line; +}; + +static VALUE +ossl_call_keylog_cb(VALUE args_v) +{ + VALUE sslctx_obj, cb, line_v; + struct ossl_call_keylog_cb_args *args = (struct ossl_call_keylog_cb_args *) args_v; + + sslctx_obj = rb_attr_get(args->ssl_obj, id_i_context); + + cb = rb_attr_get(sslctx_obj, id_i_keylog_cb); + if (NIL_P(cb)) return Qnil; + + line_v = rb_str_new_cstr(args->line); + + return rb_funcall(cb, id_call, 2, args->ssl_obj, line_v); +} + +static void +ossl_sslctx_keylog_cb(const SSL *ssl, const char *line) +{ + VALUE ssl_obj; + struct ossl_call_keylog_cb_args args; + int state = 0; + + OSSL_Debug("SSL keylog callback entered"); + + ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + args.ssl_obj = ssl_obj; + args.line = line; + + rb_protect(ossl_call_keylog_cb, (VALUE)&args, &state); + if (state) { + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); + } +} +#endif + static VALUE ossl_call_session_remove_cb(VALUE ary) { @@ -466,7 +385,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) * when SSL_CTX_free() is called. */ if (rb_during_gc()) - return; + return; OSSL_Debug("SSL SESSION remove callback entered"); @@ -497,8 +416,9 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg)) GetSSLCTX(arg, ctx); x509 = DupX509CertPtr(i); - if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ - ossl_raise(eSSLError, NULL); + if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) { + X509_free(x509); + ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert"); } return i; @@ -507,52 +427,42 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg)) static VALUE ossl_sslctx_setup(VALUE self); static VALUE -ossl_call_servername_cb(VALUE ary) +ossl_call_servername_cb(VALUE arg) { - VALUE ssl_obj, sslctx_obj, cb, ret_obj; - - Check_Type(ary, T_ARRAY); - ssl_obj = rb_ary_entry(ary, 0); + SSL *ssl = (void *)arg; + const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + if (!servername) + return Qnil; - sslctx_obj = rb_attr_get(ssl_obj, id_i_context); - cb = rb_attr_get(sslctx_obj, id_i_servername_cb); - if (NIL_P(cb)) return Qnil; + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + VALUE sslctx_obj = rb_attr_get(ssl_obj, id_i_context); + VALUE cb = rb_attr_get(sslctx_obj, id_i_servername_cb); + VALUE ary = rb_assoc_new(ssl_obj, rb_str_new_cstr(servername)); - ret_obj = rb_funcallv(cb, id_call, 1, &ary); + VALUE ret_obj = rb_funcallv(cb, id_call, 1, &ary); if (rb_obj_is_kind_of(ret_obj, cSSLContext)) { - SSL *ssl; SSL_CTX *ctx2; - ossl_sslctx_setup(ret_obj); - GetSSL(ssl_obj, ssl); GetSSLCTX(ret_obj, ctx2); - SSL_set_SSL_CTX(ssl, ctx2); + if (!SSL_set_SSL_CTX(ssl, ctx2)) + ossl_raise(eSSLError, "SSL_set_SSL_CTX"); rb_ivar_set(ssl_obj, id_i_context, ret_obj); } else if (!NIL_P(ret_obj)) { - ossl_raise(rb_eArgError, "servername_cb must return an " - "OpenSSL::SSL::SSLContext object or nil"); + ossl_raise(rb_eArgError, "servername_cb must return an " + "OpenSSL::SSL::SSLContext object or nil"); } - return ret_obj; + return Qnil; } static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) { - VALUE ary, ssl_obj; - int state = 0; - const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - - if (!servername) - return SSL_TLSEXT_ERR_OK; - - ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - ary = rb_ary_new2(2); - rb_ary_push(ary, ssl_obj); - rb_ary_push(ary, rb_str_new2(servername)); + int state; - rb_protect(ossl_call_servername_cb, ary, &state); + rb_protect(ossl_call_servername_cb, (VALUE)ssl, &state); if (state) { + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); return SSL_TLSEXT_ERR_ALERT_FATAL; } @@ -579,7 +489,7 @@ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded)) int len = RSTRING_LENINT(cur); char len_byte; if (len < 1 || len > 255) - ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); + ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); /* Encode the length byte */ len_byte = len; rb_str_buf_cat(encoded, &len_byte, 1); @@ -613,16 +523,16 @@ npn_select_cb_common_i(VALUE tmp) /* assume OpenSSL verifies this format */ /* The format is len_1|proto_1|...|len_n|proto_n */ while (in < in_end) { - l = *in++; - rb_ary_push(protocols, rb_str_new((const char *)in, l)); - in += l; + l = *in++; + rb_ary_push(protocols, rb_str_new((const char *)in, l)); + in += l; } selected = rb_funcallv(args->cb, id_call, 1, &protocols); StringValue(selected); len = RSTRING_LEN(selected); if (len < 1 || len >= 256) { - ossl_raise(eSSLError, "Selected protocol name must have length 1..255"); + ossl_raise(eSSLError, "Selected protocol name must have length 1..255"); } return selected; @@ -630,8 +540,8 @@ npn_select_cb_common_i(VALUE tmp) static int ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, - unsigned char *outlen, const unsigned char *in, - unsigned int inlen) + unsigned char *outlen, const unsigned char *in, + unsigned int inlen) { VALUE selected; int status; @@ -643,10 +553,10 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status); if (status) { - VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); - return SSL_TLSEXT_ERR_ALERT_FATAL; + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); + return SSL_TLSEXT_ERR_ALERT_FATAL; } *out = (unsigned char *)RSTRING_PTR(selected); @@ -655,10 +565,10 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, return SSL_TLSEXT_ERR_OK; } -#ifndef OPENSSL_NO_NEXTPROTONEG +#ifdef OSSL_USE_NEXTPROTONEG static int ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, - void *arg) + void *arg) { VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded); @@ -670,7 +580,7 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, static int ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) + const unsigned char *in, unsigned int inlen, void *arg) { VALUE sslctx_obj, cb; @@ -678,13 +588,13 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen, cb = rb_attr_get(sslctx_obj, id_i_npn_select_cb); return ssl_npn_select_cb_common(ssl, cb, (const unsigned char **)out, - outlen, in, inlen); + outlen, in, inlen); } #endif static int ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) + const unsigned char *in, unsigned int inlen, void *arg) { VALUE sslctx_obj, cb; @@ -701,12 +611,15 @@ ssl_info_cb(const SSL *ssl, int where, int val) int is_server = SSL_is_server((SSL *)ssl); if (is_server && where & SSL_CB_HANDSHAKE_START) { - ssl_renegotiation_cb(ssl); + ssl_renegotiation_cb(ssl); } } /* - * Gets various OpenSSL options. + * call-seq: + * ctx.options -> integer + * + * Gets various \OpenSSL options. */ static VALUE ossl_sslctx_get_options(VALUE self) @@ -721,7 +634,17 @@ ossl_sslctx_get_options(VALUE self) } /* - * Sets various OpenSSL options. + * call-seq: + * ctx.options = integer + * + * Sets various \OpenSSL options. The options are a bit field and can be + * combined with the bitwise OR operator (<tt>|</tt>). Available options are + * defined as constants in OpenSSL::SSL that begin with +OP_+. + * + * For backwards compatibility, passing +nil+ has the same effect as passing + * OpenSSL::SSL::OP_ALL. + * + * See also man page SSL_CTX_set_options(3). */ static VALUE ossl_sslctx_set_options(VALUE self, VALUE options) @@ -734,9 +657,9 @@ ossl_sslctx_set_options(VALUE self, VALUE options) SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx)); if (NIL_P(options)) { - SSL_CTX_set_options(ctx, SSL_OP_ALL); + SSL_CTX_set_options(ctx, SSL_OP_ALL); } else { - SSL_CTX_set_options(ctx, NUM2ULONG(options)); + SSL_CTX_set_options(ctx, NUM2ULONG(options)); } return self; @@ -766,23 +689,26 @@ ossl_sslctx_setup(VALUE self) GetSSLCTX(self, ctx); #if !defined(OPENSSL_NO_DH) - SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); + if (!NIL_P(rb_attr_get(self, id_i_tmp_dh_callback))) { + SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); + SSL_CTX_set_dh_auto(ctx, 0); + } #endif -#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH +#if !defined(OPENSSL_IS_AWSLC) /* AWS-LC has no support for TLS 1.3 PHA. */ SSL_CTX_set_post_handshake_auth(ctx, 1); #endif val = rb_attr_get(self, id_i_cert_store); if (!NIL_P(val)) { - X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */ - SSL_CTX_set_cert_store(ctx, store); - X509_STORE_up_ref(store); + X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */ + SSL_CTX_set_cert_store(ctx, store); + X509_STORE_up_ref(store); } val = rb_attr_get(self, id_i_extra_chain_cert); if(!NIL_P(val)){ - rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); + rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); } /* private key may be bundled in certificate file. */ @@ -806,38 +732,45 @@ ossl_sslctx_setup(VALUE self) val = rb_attr_get(self, id_i_client_ca); if(!NIL_P(val)){ - if (RB_TYPE_P(val, T_ARRAY)) { - for(i = 0; i < RARRAY_LEN(val); i++){ - client_ca = GetX509CertPtr(RARRAY_AREF(val, i)); - if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); - } - } + if (RB_TYPE_P(val, T_ARRAY)) { + for(i = 0; i < RARRAY_LEN(val); i++){ + client_ca = GetX509CertPtr(RARRAY_AREF(val, i)); + if (!SSL_CTX_add_client_CA(ctx, client_ca)){ + /* Copies X509_NAME => FREE it. */ + ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); + } + } } - else{ - client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ + else{ + client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); + /* Copies X509_NAME => FREE it. */ + ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } - } + } } val = rb_attr_get(self, id_i_ca_file); ca_file = NIL_P(val) ? NULL : StringValueCStr(val); val = rb_attr_get(self, id_i_ca_path); ca_path = NIL_P(val) ? NULL : StringValueCStr(val); - if(ca_file || ca_path){ - if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) - rb_warning("can't set verify locations"); +#ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE + if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_file"); + if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_dir"); +#else + if (ca_file || ca_path) { + if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_locations"); } +#endif val = rb_attr_get(self, id_i_verify_mode); verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); if (RTEST(rb_attr_get(self, id_i_client_cert_cb))) - SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); + SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); val = rb_attr_get(self, id_i_timeout); if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); @@ -845,68 +778,167 @@ ossl_sslctx_setup(VALUE self) val = rb_attr_get(self, id_i_verify_depth); if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val)); -#ifndef OPENSSL_NO_NEXTPROTONEG +#ifdef OSSL_USE_NEXTPROTONEG val = rb_attr_get(self, id_i_npn_protocols); if (!NIL_P(val)) { - VALUE encoded = ssl_encode_npn_protocols(val); - rb_ivar_set(self, id_npn_protocols_encoded, encoded); - SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self); - OSSL_Debug("SSL NPN advertise callback added"); + VALUE encoded = ssl_encode_npn_protocols(val); + rb_ivar_set(self, id_npn_protocols_encoded, encoded); + SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self); + OSSL_Debug("SSL NPN advertise callback added"); } if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) { - SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self); - OSSL_Debug("SSL NPN select callback added"); + SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self); + OSSL_Debug("SSL NPN select callback added"); } #endif val = rb_attr_get(self, id_i_alpn_protocols); if (!NIL_P(val)) { - VALUE rprotos = ssl_encode_npn_protocols(val); + VALUE rprotos = ssl_encode_npn_protocols(val); - /* returns 0 on success */ - if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos), - RSTRING_LENINT(rprotos))) - ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos"); - OSSL_Debug("SSL ALPN values added"); + /* returns 0 on success */ + if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos), + RSTRING_LENINT(rprotos))) + ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos"); + OSSL_Debug("SSL ALPN values added"); } if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) { - SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self); - OSSL_Debug("SSL ALPN select callback added"); + SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self); + OSSL_Debug("SSL ALPN select callback added"); } rb_obj_freeze(self); val = rb_attr_get(self, id_i_session_id_context); if (!NIL_P(val)){ - StringValue(val); - if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), - RSTRING_LENINT(val))){ - ossl_raise(eSSLError, "SSL_CTX_set_session_id_context"); - } + StringValue(val); + if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), + RSTRING_LENINT(val))){ + ossl_raise(eSSLError, "SSL_CTX_set_session_id_context"); + } } if (RTEST(rb_attr_get(self, id_i_session_get_cb))) { - SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); - OSSL_Debug("SSL SESSION get callback added"); + SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); + OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_attr_get(self, id_i_session_new_cb))) { - SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); - OSSL_Debug("SSL SESSION new callback added"); + SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); + OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) { - SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); - OSSL_Debug("SSL SESSION remove callback added"); + SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); + OSSL_Debug("SSL SESSION remove callback added"); } val = rb_attr_get(self, id_i_servername_cb); if (!NIL_P(val)) { SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); - OSSL_Debug("SSL TLSEXT servername callback added"); + OSSL_Debug("SSL TLSEXT servername callback added"); } +#if !OSSL_IS_LIBRESSL + /* + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + */ + if (RTEST(rb_attr_get(self, id_i_keylog_cb))) { + SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb); + OSSL_Debug("SSL keylog callback added"); + } +#endif + return Qtrue; } +static int +parse_proto_version(VALUE str) +{ + int i; + static const struct { + const char *name; + int version; + } map[] = { + { "SSL2", SSL2_VERSION }, + { "SSL3", SSL3_VERSION }, + { "TLS1", TLS1_VERSION }, + { "TLS1_1", TLS1_1_VERSION }, + { "TLS1_2", TLS1_2_VERSION }, + { "TLS1_3", TLS1_3_VERSION }, + }; + + if (NIL_P(str)) + return 0; + if (RB_INTEGER_TYPE_P(str)) + return NUM2INT(str); + + if (SYMBOL_P(str)) + str = rb_sym2str(str); + StringValue(str); + for (i = 0; i < numberof(map); i++) + if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str))) + return map[i].version; + rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str); +} + +/* + * call-seq: + * ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION + * ctx.min_version = :TLS1_2 + * ctx.min_version = nil + * + * Sets the lower bound on the supported SSL/TLS protocol version. The + * version may be specified by an integer constant named + * OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version". + * + * === Example + * ctx = OpenSSL::SSL::SSLContext.new + * ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION + * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION + * + * sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx) + * sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2 + */ +static VALUE +ossl_sslctx_set_min_version(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + int version; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + version = parse_proto_version(v); + + if (!SSL_CTX_set_min_proto_version(ctx, version)) + ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version"); + return v; +} + +/* + * call-seq: + * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION + * ctx.max_version = :TLS1_2 + * ctx.max_version = nil + * + * Sets the upper bound of the supported SSL/TLS protocol version. See + * #min_version= for the possible values. + */ +static VALUE +ossl_sslctx_set_max_version(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + int version; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + version = parse_proto_version(v); + + if (!SSL_CTX_set_max_proto_version(ctx, version)) + ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version"); + return v; +} + static VALUE ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher) { @@ -952,29 +984,14 @@ ossl_sslctx_get_ciphers(VALUE self) return ary; } -/* - * call-seq: - * ctx.ciphers = "cipher1:cipher2:..." - * ctx.ciphers = [name, ...] - * ctx.ciphers = [[name, version, bits, alg_bits], ...] - * - * Sets the list of available cipher suites for this context. Note in a server - * context some ciphers require the appropriate certificates. For example, an - * RSA cipher suite can only be chosen when an RSA certificate is available. - */ static VALUE -ossl_sslctx_set_ciphers(VALUE self, VALUE v) +build_cipher_string(VALUE v) { - SSL_CTX *ctx; VALUE str, elem; - int i; - rb_check_frozen(self); - if (NIL_P(v)) - return v; - else if (RB_TYPE_P(v, T_ARRAY)) { + if (RB_TYPE_P(v, T_ARRAY)) { str = rb_str_new(0, 0); - for (i = 0; i < RARRAY_LEN(v); i++) { + for (long i = 0; i < RARRAY_LEN(v); i++) { elem = rb_ary_entry(v, i); if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0); elem = rb_String(elem); @@ -986,14 +1003,128 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) StringValue(str); } + return str; +} + +/* + * call-seq: + * ctx.ciphers = "cipher1:cipher2:..." + * ctx.ciphers = [name, ...] + * ctx.ciphers = [[name, version, bits, alg_bits], ...] + * + * Sets the list of available cipher suites for TLS 1.2 and below for this + * context. + * + * Note in a server context some ciphers require the appropriate certificates. + * For example, an RSA cipher suite can only be chosen when an RSA certificate + * is available. + * + * This method does not affect TLS 1.3 connections. See also #ciphersuites=. + */ +static VALUE +ossl_sslctx_set_ciphers(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + VALUE str; + + rb_check_frozen(self); + // Assigning nil is a no-op for compatibility + if (NIL_P(v)) + return v; + + str = build_cipher_string(v); + GetSSLCTX(self, ctx); - if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) { + if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); - } return v; } +/* + * call-seq: + * ctx.ciphersuites = "cipher1:cipher2:..." + * ctx.ciphersuites = [name, ...] + * + * Sets the list of available TLS 1.3 cipher suites for this context. + */ +static VALUE +ossl_sslctx_set_ciphersuites(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + VALUE str; + + rb_check_frozen(self); + // Assigning nil is a no-op for compatibility + if (NIL_P(v)) + return v; + + str = build_cipher_string(v); + + GetSSLCTX(self, ctx); + if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str))) + ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites"); + + return v; +} + +#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST +/* + * call-seq: + * ctx.sigalgs = "sigalg1:sigalg2:..." + * + * Sets the list of "supported signature algorithms" for this context. + * + * For a TLS client, the list is used in the "signature_algorithms" extension + * in the ClientHello message. For a server, the list is used by OpenSSL to + * determine the set of shared signature algorithms. OpenSSL will pick the most + * appropriate one from it. + * + * See also #client_sigalgs= for the client authentication equivalent. + */ +static VALUE +ossl_sslctx_set_sigalgs(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + + if (!SSL_CTX_set1_sigalgs_list(ctx, StringValueCStr(v))) + ossl_raise(eSSLError, "SSL_CTX_set1_sigalgs_list"); + + return v; +} +#endif + +#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST +/* + * call-seq: + * ctx.client_sigalgs = "sigalg1:sigalg2:..." + * + * Sets the list of "supported signature algorithms" for client authentication + * for this context. + * + * For a TLS server, the list is sent to the client as part of the + * CertificateRequest message. + * + * See also #sigalgs= for the server authentication equivalent. + */ +static VALUE +ossl_sslctx_set_client_sigalgs(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + + if (!SSL_CTX_set1_client_sigalgs_list(ctx, StringValueCStr(v))) + ossl_raise(eSSLError, "SSL_CTX_set1_client_sigalgs_list"); + + return v; +} +#endif + #ifndef OPENSSL_NO_DH /* * call-seq: @@ -1006,7 +1137,7 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) * contained in the key object, if any, are ignored. The server will always * generate a new key pair for each handshake. * - * Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3). + * Added in version 3.0. See also the man page SSL_CTX_set0_tmp_dh_pkey(3). * * Example: * ctx = OpenSSL::SSL::SSLContext.new @@ -1027,7 +1158,7 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg) if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) rb_raise(eSSLError, "invalid pkey type %s (expected DH)", OBJ_nid2sn(EVP_PKEY_base_id(pkey))); -#ifdef HAVE_SSL_SET0_TMP_DH_PKEY +#ifdef HAVE_SSL_CTX_SET0_TMP_DH_PKEY if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey)) ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey"); EVP_PKEY_up_ref(pkey); @@ -1036,29 +1167,36 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg) ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh"); #endif + // Turn off the "auto" DH parameters set by ossl_sslctx_s_alloc() + SSL_CTX_set_dh_auto(ctx, 0); + return arg; } #endif -#if !defined(OPENSSL_NO_EC) /* * call-seq: - * ctx.ecdh_curves = curve_list -> curve_list + * ctx.groups = groups_list + * ctx.ecdh_curves = groups_list + * + * Sets the list of supported groups for key agreement for this context. * - * Sets the list of "supported elliptic curves" for this context. + * For a TLS client, the list is directly used in the "supported_groups" + * extension. For a server, the list is used by OpenSSL to determine the set of + * shared supported groups. OpenSSL will pick the most appropriate one from it. * - * For a TLS client, the list is directly used in the Supported Elliptic Curves - * Extension. For a server, the list is used by OpenSSL to determine the set of - * shared curves. OpenSSL will pick the most appropriate one from it. + * #ecdh_curves= is a deprecated alias for #groups=. + * + * See also the man page SSL_CTX_set1_groups_list(3). * * === Example * ctx1 = OpenSSL::SSL::SSLContext.new - * ctx1.ecdh_curves = "X25519:P-256:P-224" + * ctx1.groups = "X25519:P-256:P-224" * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1) * Thread.new { svr.accept } * * ctx2 = OpenSSL::SSL::SSLContext.new - * ctx2.ecdh_curves = "P-256" + * ctx2.groups = "P-256" * cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2) * cli.connect * @@ -1066,7 +1204,7 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg) * # => "prime256v1" (is an alias for NIST P-256) */ static VALUE -ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) +ossl_sslctx_set_groups(VALUE self, VALUE arg) { SSL_CTX *ctx; @@ -1074,13 +1212,10 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) GetSSLCTX(self, ctx); StringValueCStr(arg); - if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg))) - ossl_raise(eSSLError, NULL); + if (!SSL_CTX_set1_groups_list(ctx, RSTRING_PTR(arg))) + ossl_raise(eSSLError, "SSL_CTX_set1_groups_list"); return arg; } -#else -#define ossl_sslctx_set_ecdh_curves rb_f_notimplement -#endif /* * call-seq: @@ -1097,12 +1232,7 @@ ossl_sslctx_get_security_level(VALUE self) GetSSLCTX(self, ctx); -#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) return INT2NUM(SSL_CTX_get_security_level(ctx)); -#else - (void)ctx; - return INT2FIX(0); -#endif } /* @@ -1132,14 +1262,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value) rb_check_frozen(self); GetSSLCTX(self, ctx); -#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) SSL_CTX_set_security_level(ctx, NUM2INT(value)); -#else - (void)ctx; - if (NUM2INT(value) != 0) - ossl_raise(rb_eNotImpError, "setting security level to other than 0 is " - "not supported in this version of OpenSSL"); -#endif return value; } @@ -1221,20 +1344,20 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) pub_pkey = X509_get_pubkey(x509); EVP_PKEY_free(pub_pkey); if (!pub_pkey) - rb_raise(rb_eArgError, "certificate does not contain public key"); - if (EVP_PKEY_cmp(pub_pkey, pkey) != 1) - rb_raise(rb_eArgError, "public key mismatch"); + rb_raise(rb_eArgError, "certificate does not contain public key"); + if (EVP_PKEY_eq(pub_pkey, pkey) != 1) + rb_raise(rb_eArgError, "public key mismatch"); if (argc >= 3) - extra_chain = ossl_x509_ary2sk(extra_chain_ary); + extra_chain = ossl_x509_ary2sk(extra_chain_ary); if (!SSL_CTX_use_certificate(ctx, x509)) { - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_use_certificate"); + sk_X509_pop_free(extra_chain, X509_free); + ossl_raise(eSSLError, "SSL_CTX_use_certificate"); } if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey"); + sk_X509_pop_free(extra_chain, X509_free); + ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey"); } if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) { sk_X509_pop_free(extra_chain, X509_free); @@ -1432,12 +1555,11 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) /* * SSLSocket class */ -#ifndef OPENSSL_NO_SOCK static inline int ssl_started(SSL *ssl) { - /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */ - return SSL_get_fd(ssl) >= 0; + /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */ + return SSL_get_rbio(ssl) != NULL; } static void @@ -1445,7 +1567,6 @@ ossl_ssl_mark(void *ptr) { SSL *ssl = ptr; rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)); - rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx)); } static void @@ -1459,7 +1580,7 @@ const rb_data_type_t ossl_ssl_type = { { ossl_ssl_mark, ossl_ssl_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1510,40 +1631,50 @@ peeraddr_ip_str(VALUE self) static VALUE ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) { - VALUE io, v_ctx, verify_cb; + VALUE io, v_ctx; SSL *ssl; SSL_CTX *ctx; TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl); if (ssl) - ossl_raise(eSSLError, "SSL already initialized"); + ossl_raise(eSSLError, "SSL already initialized"); if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1) - v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); + v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); GetSSLCTX(v_ctx, ctx); rb_ivar_set(self, id_i_context, v_ctx); ossl_sslctx_setup(v_ctx); if (rb_respond_to(io, rb_intern("nonblock="))) - rb_funcall(io, rb_intern("nonblock="), 1, Qtrue); + rb_funcall(io, rb_intern("nonblock="), 1, Qtrue); + Check_Type(io, T_FILE); rb_ivar_set(self, id_i_io, io); ssl = SSL_new(ctx); if (!ssl) - ossl_raise(eSSLError, NULL); + ossl_raise(eSSLError, NULL); RTYPEDDATA_DATA(self) = ssl; SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self); SSL_set_info_callback(ssl, ssl_info_cb); - verify_cb = rb_attr_get(v_ctx, id_i_verify_callback); - SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb); rb_call_super(0, NULL); return self; } +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + static VALUE ossl_ssl_setup(VALUE self) { @@ -1553,14 +1684,14 @@ ossl_ssl_setup(VALUE self) GetSSL(self, ssl); if (ssl_started(ssl)) - return Qtrue; + return Qtrue; io = rb_attr_get(self, id_i_io); GetOpenFile(io, fptr); rb_io_check_readable(fptr); rb_io_check_writable(fptr); - if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd))) - ossl_raise(eSSLError, "SSL_set_fd"); + if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io)))) + ossl_raise(eSSLError, "SSL_set_fd"); return Qtrue; } @@ -1575,14 +1706,14 @@ static void write_would_block(int nonblock) { if (nonblock) - ossl_raise(eSSLErrorWaitWritable, "write would block"); + ossl_raise(eSSLErrorWaitWritable, "write would block"); } static void read_would_block(int nonblock) { if (nonblock) - ossl_raise(eSSLErrorWaitReadable, "read would block"); + ossl_raise(eSSLErrorWaitReadable, "read would block"); } static int @@ -1590,103 +1721,122 @@ no_exception_p(VALUE opts) { if (RB_TYPE_P(opts, T_HASH) && rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse) - return 1; + return 1; return 0; } +// Provided by Ruby 3.2.0 and later in order to support the default IO#timeout. +#ifndef RUBY_IO_TIMEOUT_DEFAULT +#define RUBY_IO_TIMEOUT_DEFAULT Qnil +#endif + +#ifdef HAVE_RB_IO_TIMEOUT +#define IO_TIMEOUT_ERROR rb_eIOTimeoutError +#else +#define IO_TIMEOUT_ERROR rb_eIOError +#endif + + static void -io_wait_writable(rb_io_t *fptr) +io_wait_writable(VALUE io) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_writable(errno, fptr->self, Qnil); + if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!"); + } #else + rb_io_t *fptr; + GetOpenFile(io, fptr); rb_io_wait_writable(fptr->fd); #endif } static void -io_wait_readable(rb_io_t *fptr) +io_wait_readable(VALUE io) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_readable(errno, fptr->self, Qnil); + if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!"); + } #else + rb_io_t *fptr; + GetOpenFile(io, fptr); rb_io_wait_readable(fptr->fd); #endif } static VALUE -ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) +ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts) { SSL *ssl; - rb_io_t *fptr; int ret, ret2; VALUE cb_state; int nonblock = opts != Qfalse; -#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) - unsigned long err; -#endif rb_ivar_set(self, ID_callback_state, Qnil); GetSSL(self, ssl); - GetOpenFile(rb_attr_get(self, id_i_io), fptr); - for(;;){ - ret = func(ssl); + VALUE io = rb_attr_get(self, id_i_io); + for (;;) { + ret = func(ssl); - cb_state = rb_attr_get(self, ID_callback_state); + cb_state = rb_attr_get(self, ID_callback_state); if (!NIL_P(cb_state)) { - /* must cleanup OpenSSL error stack before re-raising */ - ossl_clear_error(); - rb_jump_tag(NUM2INT(cb_state)); - } + /* must cleanup OpenSSL error stack before re-raising */ + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); + } - if (ret > 0) - break; + if (ret > 0) + break; - switch((ret2 = ssl_get_error(ssl, ret))){ - case SSL_ERROR_WANT_WRITE: + switch ((ret2 = ssl_get_error(ssl, ret))) { + case SSL_ERROR_WANT_WRITE: if (no_exception_p(opts)) { return sym_wait_writable; } write_would_block(nonblock); - io_wait_writable(fptr); + io_wait_writable(io); continue; - case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_READ: if (no_exception_p(opts)) { return sym_wait_readable; } read_would_block(nonblock); - io_wait_readable(fptr); + io_wait_readable(io); continue; - case SSL_ERROR_SYSCALL: + case SSL_ERROR_SYSCALL: #ifdef __APPLE__ /* See ossl_ssl_write_internal() */ if (errno == EPROTOTYPE) continue; #endif - if (errno) rb_sys_fail(funcname); - ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s", - funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl)); - + if (errno) rb_sys_fail(funcname); + /* fallthrough */ + default: { + VALUE error_append = Qnil; #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) - case SSL_ERROR_SSL: - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_SSL && - ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) { - const char *err_msg = ERR_reason_error_string(err), - *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl)); - if (!err_msg) - err_msg = "(null)"; - if (!verify_msg) - verify_msg = "(null)"; - ossl_clear_error(); /* let ossl_raise() not append message */ - ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)", - funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl), - err_msg, verify_msg); - } + unsigned long err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_SSL && + ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) { + const char *err_msg = ERR_reason_error_string(err), + *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl)); + if (!err_msg) + err_msg = "(null)"; + if (!verify_msg) + verify_msg = "(null)"; + ossl_clear_error(); /* let ossl_raise() not append message */ + error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg); + } #endif - /* fallthrough */ - default: - ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s", - funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl)); - } + ossl_raise(eSSLError, + "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE, + funcname, + ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "", + ret2, + errno, + peeraddr_ip_str(self), + SSL_state_string_long(ssl), + error_append); + } + } } return self; @@ -1696,8 +1846,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) * call-seq: * ssl.connect => self * - * Initiates an SSL/TLS handshake with a server. The handshake may be started - * after unencrypted data has been sent over the socket. + * Initiates an SSL/TLS handshake with a server. */ static VALUE ossl_ssl_connect(VALUE self) @@ -1744,8 +1893,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self) * call-seq: * ssl.accept => self * - * Waits for a SSL/TLS client to initiate a handshake. The handshake may be - * started after unencrypted data has been sent over the socket. + * Waits for a SSL/TLS client to initiate a handshake. */ static VALUE ossl_ssl_accept(VALUE self) @@ -1792,110 +1940,96 @@ static VALUE ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) { SSL *ssl; - int ilen, nread = 0; - VALUE len, str; - rb_io_t *fptr; - VALUE io, opts = Qnil; + int ilen; + VALUE len, str, cb_state; + VALUE opts = Qnil; if (nonblock) { - rb_scan_args(argc, argv, "11:", &len, &str, &opts); + rb_scan_args(argc, argv, "11:", &len, &str, &opts); } else { - rb_scan_args(argc, argv, "11", &len, &str); + rb_scan_args(argc, argv, "11", &len, &str); } + GetSSL(self, ssl); + if (!ssl_started(ssl)) + rb_raise(eSSLError, "SSL session is not started yet"); ilen = NUM2INT(len); if (NIL_P(str)) - str = rb_str_new(0, ilen); + str = rb_str_new(0, ilen); else { - StringValue(str); - if (RSTRING_LEN(str) >= ilen) - rb_str_modify(str); - else - rb_str_modify_expand(str, ilen - RSTRING_LEN(str)); + StringValue(str); + if (RSTRING_LEN(str) >= ilen) + rb_str_modify(str); + else + rb_str_modify_expand(str, ilen - RSTRING_LEN(str)); } - rb_str_set_len(str, 0); - if (ilen == 0) - return str; - GetSSL(self, ssl); - io = rb_attr_get(self, id_i_io); - GetOpenFile(io, fptr); - if (ssl_started(ssl)) { - rb_str_locktmp(str); - for (;;) { - nread = SSL_read(ssl, RSTRING_PTR(str), ilen); - switch(ssl_get_error(ssl, nread)){ - case SSL_ERROR_NONE: - rb_str_unlocktmp(str); - goto end; - case SSL_ERROR_ZERO_RETURN: - rb_str_unlocktmp(str); - if (no_exception_p(opts)) { return Qnil; } - rb_eof_error(); - case SSL_ERROR_WANT_WRITE: - if (nonblock) { - rb_str_unlocktmp(str); - if (no_exception_p(opts)) { return sym_wait_writable; } - write_would_block(nonblock); - } - io_wait_writable(fptr); - continue; - case SSL_ERROR_WANT_READ: - if (nonblock) { - rb_str_unlocktmp(str); - if (no_exception_p(opts)) { return sym_wait_readable; } - read_would_block(nonblock); - } - io_wait_readable(fptr); - continue; - case SSL_ERROR_SYSCALL: - if (!ERR_peek_error()) { - rb_str_unlocktmp(str); - if (errno) - rb_sys_fail(0); - else { - /* - * The underlying BIO returned 0. This is actually a - * protocol error. But unfortunately, not all - * implementations cleanly shutdown the TLS connection - * but just shutdown/close the TCP connection. So report - * EOF for now... - */ - if (no_exception_p(opts)) { return Qnil; } - rb_eof_error(); - } - } - /* fall through */ - default: - rb_str_unlocktmp(str); - ossl_raise(eSSLError, "SSL_read"); - } - } + if (ilen == 0) { + rb_str_set_len(str, 0); + return str; } - else { - ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); - - rb_warning("SSL session is not started yet."); -#if defined(RB_PASS_KEYWORDS) - if (nonblock) { - VALUE argv[3]; - argv[0] = len; - argv[1] = str; - argv[2] = opts; - return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS); + + VALUE io = rb_attr_get(self, id_i_io); + + for (;;) { + rb_str_locktmp(str); + int nread = SSL_read(ssl, RSTRING_PTR(str), ilen); + rb_str_unlocktmp(str); + + cb_state = rb_attr_get(self, ID_callback_state); + if (!NIL_P(cb_state)) { + rb_ivar_set(self, ID_callback_state, Qnil); + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); } -#else - if (nonblock) { - return rb_funcall(io, meth, 3, len, str, opts); + + switch (ssl_get_error(ssl, nread)) { + case SSL_ERROR_NONE: + rb_str_set_len(str, nread); + return str; + case SSL_ERROR_ZERO_RETURN: + if (no_exception_p(opts)) { return Qnil; } + rb_eof_error(); + case SSL_ERROR_WANT_WRITE: + if (nonblock) { + if (no_exception_p(opts)) { return sym_wait_writable; } + write_would_block(nonblock); + } + io_wait_writable(io); + break; + case SSL_ERROR_WANT_READ: + if (nonblock) { + if (no_exception_p(opts)) { return sym_wait_readable; } + read_would_block(nonblock); + } + io_wait_readable(io); + break; + case SSL_ERROR_SYSCALL: + if (!ERR_peek_error()) { + if (errno) + rb_sys_fail(0); + else { + /* + * The underlying BIO returned 0. This is actually a + * protocol error. But unfortunately, not all + * implementations cleanly shutdown the TLS connection + * but just shutdown/close the TCP connection. So report + * EOF for now... + */ + if (no_exception_p(opts)) { return Qnil; } + rb_eof_error(); + } + } + /* fall through */ + default: + ossl_raise(eSSLError, "SSL_read"); } -#endif - else - return rb_funcall(io, meth, 2, len, str); - } - end: - rb_str_set_len(str, nread); - return str; + // Ensure the buffer is not modified during io_wait_*able() + rb_str_modify(str); + if (rb_str_capacity(str) < (size_t)ilen) + rb_raise(eSSLError, "read buffer was modified"); + } } /* @@ -1932,81 +2066,92 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) } static VALUE -ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) +ossl_ssl_write_internal_safe(VALUE _args) { + VALUE *args = (VALUE*)_args; + VALUE self = args[0]; + VALUE str = args[1]; + VALUE opts = args[2]; + SSL *ssl; - int nwrite = 0; rb_io_t *fptr; - int nonblock = opts != Qfalse; - VALUE tmp, io; + int num, nonblock = opts != Qfalse; + VALUE cb_state; - tmp = rb_str_new_frozen(StringValue(str)); GetSSL(self, ssl); - io = rb_attr_get(self, id_i_io); + if (!ssl_started(ssl)) + rb_raise(eSSLError, "SSL session is not started yet"); + + VALUE io = rb_attr_get(self, id_i_io); GetOpenFile(io, fptr); - if (ssl_started(ssl)) { - for (;;) { - int num = RSTRING_LENINT(tmp); - - /* SSL_write(3ssl) manpage states num == 0 is undefined */ - if (num == 0) - goto end; - - nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num); - switch(ssl_get_error(ssl, nwrite)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_WANT_WRITE: - if (no_exception_p(opts)) { return sym_wait_writable; } - write_would_block(nonblock); - io_wait_writable(fptr); - continue; - case SSL_ERROR_WANT_READ: - if (no_exception_p(opts)) { return sym_wait_readable; } - read_would_block(nonblock); - io_wait_readable(fptr); - continue; - case SSL_ERROR_SYSCALL: + + /* SSL_write(3ssl) manpage states num == 0 is undefined */ + num = RSTRING_LENINT(str); + if (num == 0) + return INT2FIX(0); + + for (;;) { + int nwritten = SSL_write(ssl, RSTRING_PTR(str), num); + + cb_state = rb_attr_get(self, ID_callback_state); + if (!NIL_P(cb_state)) { + rb_ivar_set(self, ID_callback_state, Qnil); + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); + } + + switch (ssl_get_error(ssl, nwritten)) { + case SSL_ERROR_NONE: + return INT2NUM(nwritten); + case SSL_ERROR_WANT_WRITE: + if (no_exception_p(opts)) { return sym_wait_writable; } + write_would_block(nonblock); + io_wait_writable(io); + continue; + case SSL_ERROR_WANT_READ: + if (no_exception_p(opts)) { return sym_wait_readable; } + read_would_block(nonblock); + io_wait_readable(io); + continue; + case SSL_ERROR_SYSCALL: #ifdef __APPLE__ - /* - * It appears that send syscall can return EPROTOTYPE if the - * socket is being torn down. Retry to get a proper errno to - * make the error handling in line with the socket library. - * [Bug #14713] https://bugs.ruby-lang.org/issues/14713 - */ - if (errno == EPROTOTYPE) - continue; + /* + * It appears that send syscall can return EPROTOTYPE if the + * socket is being torn down. Retry to get a proper errno to + * make the error handling in line with the socket library. + * [Bug #14713] https://bugs.ruby-lang.org/issues/14713 + */ + if (errno == EPROTOTYPE) + continue; #endif - if (errno) rb_sys_fail(0); - /* fallthrough */ - default: - ossl_raise(eSSLError, "SSL_write"); - } + if (errno) rb_sys_fail(0); + /* fallthrough */ + default: + ossl_raise(eSSLError, "SSL_write"); } } - else { - ID meth = nonblock ? - rb_intern("write_nonblock") : rb_intern("syswrite"); - - rb_warning("SSL session is not started yet."); -#if defined(RB_PASS_KEYWORDS) - if (nonblock) { - VALUE argv[2]; - argv[0] = str; - argv[1] = opts; - return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS); - } -#else - if (nonblock) { - return rb_funcall(io, meth, 2, str, opts); - } -#endif - else - return rb_funcall(io, meth, 1, str); +} + + +static VALUE +ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) +{ + StringValue(str); + int frozen = RB_OBJ_FROZEN(str); + if (!frozen) { + rb_str_locktmp(str); + } + int state; + VALUE args[3] = {self, str, opts}; + VALUE result = rb_protect(ossl_ssl_write_internal_safe, (VALUE)args, &state); + if (!frozen) { + rb_str_unlocktmp(str); } - end: - return INT2NUM(nwrite); + if (state) { + rb_jump_tag(state); + } + return result; } /* @@ -2053,12 +2198,12 @@ ossl_ssl_stop(VALUE self) GetSSL(self, ssl); if (!ssl_started(ssl)) - return Qnil; + return Qnil; ret = SSL_shutdown(ssl); if (ret == 1) /* Have already received close_notify */ - return Qnil; + return Qnil; if (ret == 0) /* Sent close_notify, but we don't wait for reply */ - return Qnil; + return Qnil; /* * XXX: Something happened. Possibly it failed because the underlying socket @@ -2144,20 +2289,20 @@ ossl_ssl_get_peer_cert_chain(VALUE self) num = sk_X509_num(chain); ary = rb_ary_new2(num); for (i = 0; i < num; i++){ - cert = sk_X509_value(chain, i); - rb_ary_push(ary, ossl_x509_new(cert)); + cert = sk_X509_value(chain, i); + rb_ary_push(ary, ossl_x509_new(cert)); } return ary; } /* -* call-seq: -* ssl.ssl_version => String -* -* Returns a String representing the SSL/TLS version that was negotiated -* for the connection, for example "TLSv1.2". -*/ + * call-seq: + * ssl.ssl_version => String + * + * Returns a String representing the SSL/TLS version that was negotiated + * for the connection, for example "TLSv1.2". + */ static VALUE ossl_ssl_get_version(VALUE self) { @@ -2278,10 +2423,10 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg) GetSSL(self, ssl); if (!NIL_P(arg)) - hostname = StringValueCStr(arg); + hostname = StringValueCStr(arg); if (!SSL_set_tlsext_host_name(ssl, hostname)) - ossl_raise(eSSLError, NULL); + ossl_raise(eSSLError, NULL); /* for SSLSocket#hostname */ rb_ivar_set(self, id_i_hostname, arg); @@ -2360,7 +2505,7 @@ ossl_ssl_get_peer_finished(VALUE self) /* * call-seq: - * ssl.client_ca => [x509name, ...] + * ssl.client_ca => [x509name, ...] or nil * * Returns the list of client CAs. Please note that in contrast to * SSLContext#client_ca= no array of X509::Certificate is returned but @@ -2378,10 +2523,12 @@ ossl_ssl_get_client_ca_list(VALUE self) GetSSL(self, ssl); ca = SSL_get_client_CA_list(ssl); + if (!ca) + return Qnil; return ossl_x509name_sk2ary(ca); } -# ifndef OPENSSL_NO_NEXTPROTONEG +# ifdef OSSL_USE_NEXTPROTONEG /* * call-seq: * ssl.npn_protocol => String | nil @@ -2400,9 +2547,9 @@ ossl_ssl_npn_protocol(VALUE self) SSL_get0_next_proto_negotiated(ssl, &out, &outlen); if (!outlen) - return Qnil; + return Qnil; else - return rb_str_new((const char *) out, outlen); + return rb_str_new((const char *) out, outlen); } # endif @@ -2424,9 +2571,52 @@ ossl_ssl_alpn_protocol(VALUE self) SSL_get0_alpn_selected(ssl, &out, &outlen); if (!outlen) - return Qnil; + return Qnil; else - return rb_str_new((const char *) out, outlen); + return rb_str_new((const char *) out, outlen); +} + +/* + * call-seq: + * session.export_keying_material(label, length) -> String + * + * Enables use of shared session key material in accordance with RFC 5705. + */ +static VALUE +ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self) +{ + SSL *ssl; + VALUE str; + VALUE label; + VALUE length; + VALUE context; + unsigned char *p; + size_t len; + int use_ctx = 0; + unsigned char *ctx = NULL; + size_t ctx_len = 0; + int ret; + + rb_scan_args(argc, argv, "21", &label, &length, &context); + StringValue(label); + + GetSSL(self, ssl); + + len = (size_t)NUM2LONG(length); + str = rb_str_new(0, len); + p = (unsigned char *)RSTRING_PTR(str); + if (!NIL_P(context)) { + use_ctx = 1; + StringValue(context); + ctx = (unsigned char *)RSTRING_PTR(context); + ctx_len = RSTRING_LEN(context); + } + ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label), + RSTRING_LENINT(label), ctx, ctx_len, use_ctx); + if (ret == 0 || ret == -1) { + ossl_raise(eSSLError, "SSL_export_keying_material"); + } + return str; } /* @@ -2443,33 +2633,91 @@ ossl_ssl_tmp_key(VALUE self) GetSSL(self, ssl); if (!SSL_get_server_tmp_key(ssl, &key)) - return Qnil; - return ossl_pkey_new(key); + return Qnil; + return ossl_pkey_wrap(key); +} + +#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME +/* + * call-seq: + * ssl.sigalg => String or nil + * + * Returns the signature algorithm name, the IANA name of the signature scheme + * used by the local to sign the TLS handshake. + */ +static VALUE +ossl_ssl_get_sigalg(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!SSL_get0_signature_name(ssl, &name)) + return Qnil; + return rb_str_new_cstr(name); } + +/* + * call-seq: + * ssl.peer_sigalg => String or nil + * + * Returns the signature algorithm name, the IANA name of the signature scheme + * used by the peer to sign the TLS handshake. + */ +static VALUE +ossl_ssl_get_peer_sigalg(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!SSL_get0_peer_signature_name(ssl, &name)) + return Qnil; + return rb_str_new_cstr(name); +} +#endif + +#ifdef HAVE_SSL_GET0_GROUP_NAME +/* + * call-seq: + * ssl.group => String or nil + * + * Returns the name of the group that was used for the key agreement of the + * current TLS session establishment. + */ +static VALUE +ossl_ssl_get_group(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!(name = SSL_get0_group_name(ssl))) + return Qnil; + return rb_str_new_cstr(name); +} +#endif + #endif /* !defined(OPENSSL_NO_SOCK) */ void Init_ossl_ssl(void) { #if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable"); rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable"); #endif +#ifndef OPENSSL_NO_SOCK id_call = rb_intern_const("call"); ID_callback_state = rb_intern_const("callback_state"); - ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0); - if (ossl_ssl_ex_vcb_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0); if (ossl_ssl_ex_ptr_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); + ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0); if (ossl_sslctx_ex_ptr_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); + ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); /* Document-module: OpenSSL::SSL * @@ -2480,16 +2728,6 @@ Init_ossl_ssl(void) */ mSSL = rb_define_module_under(mOSSL, "SSL"); - /* Document-module: OpenSSL::ExtConfig - * - * This module contains configuration information about the SSL extension, - * for example if socket support is enabled, or the host name TLS extension - * is enabled. Constants in this module will always be defined, but contain - * +true+ or +false+ values depending on the configuration of your OpenSSL - * installation. - */ - mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig"); - /* Document-class: OpenSSL::SSL::SSLError * * Generic error class raised by SSLSocket and SSLContext. @@ -2617,6 +2855,23 @@ Init_ossl_ssl(void) */ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse); +#ifndef OPENSSL_NO_DH + /* + * A callback invoked when DH parameters are required for ephemeral DH key + * exchange. + * + * The callback is invoked with the SSLSocket, a + * flag indicating the use of an export cipher and the keylength + * required. + * + * The callback must return an OpenSSL::PKey::DH instance of the correct + * key length. + * + * <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead. + */ + rb_attr(cSSLContext, rb_intern_const("tmp_dh_callback"), 1, 1, Qfalse); +#endif + /* * Sets the context in which a session can be reused. This allows * sessions for multiple applications to be distinguished, for example, by @@ -2652,8 +2907,6 @@ Init_ossl_ssl(void) */ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse); - rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue); - /* * A callback invoked whenever a new handshake is initiated on an * established connection. May be used to disable renegotiation entirely. @@ -2674,7 +2927,7 @@ Init_ossl_ssl(void) * end */ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse); -#ifndef OPENSSL_NO_NEXTPROTONEG +#ifdef OSSL_USE_NEXTPROTONEG /* * An Enumerable of Strings. Each String represents a protocol to be * advertised as the list of supported protocols for Next Protocol @@ -2736,16 +2989,47 @@ Init_ossl_ssl(void) */ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse); + /* + * A callback invoked when TLS key material is generated or received, in + * order to allow applications to store this keying material for debugging + * purposes. + * + * The callback is invoked with an SSLSocket and a string containing the + * key material in the format used by NSS for its SSLKEYLOGFILE debugging + * output. + * + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + * + * === Example + * + * context.keylog_cb = proc do |_sock, line| + * File.open('ssl_keylog_file', "a") do |f| + * f.write("#{line}\n") + * end + * end + */ + rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse); + rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); - rb_define_private_method(cSSLContext, "set_minmax_proto_version", - ossl_sslctx_set_minmax_proto_version, 2); + rb_define_method(cSSLContext, "min_version=", ossl_sslctx_set_min_version, 1); + rb_define_method(cSSLContext, "max_version=", ossl_sslctx_set_max_version, 1); rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); + rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1); +#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet + rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1); +#endif +#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet + rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1); +#endif #ifndef OPENSSL_NO_DH rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1); #endif - rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1); + rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1); + rb_define_alias(cSSLContext, "ecdh_curves=", "groups="); rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0); rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1); #ifdef SSL_MODE_SEND_FALLBACK_SCSV @@ -2818,11 +3102,6 @@ Init_ossl_ssl(void) * Document-class: OpenSSL::SSL::SSLSocket */ cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); -#ifdef OPENSSL_NO_SOCK - rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue); - rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1); -#else - rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse); rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); rb_undef_method(cSSLSocket, "initialize_copy"); @@ -2853,9 +3132,16 @@ Init_ossl_ssl(void) rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0); rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0); rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0); -# ifndef OPENSSL_NO_NEXTPROTONEG + rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1); +# ifdef OSSL_USE_NEXTPROTONEG rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0); # endif +#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME + rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0); + rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0); +#endif +#ifdef HAVE_SSL_GET0_GROUP_NAME + rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0); #endif rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE)); @@ -2864,10 +3150,25 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE)); rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL)); +#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT)); +#endif rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT)); +#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS)); +#endif rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)); -#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */ +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF)); +#endif +#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION)); +#endif +#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES)); +#endif +#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX)); #endif rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)); @@ -2875,23 +3176,29 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)); rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION)); rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)); -#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */ +#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */ rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC)); #endif - rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); - rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); -#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ - rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); +#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)); +#endif +#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA)); +#endif +#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY)); #endif - rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); - rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3)); rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1)); rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1)); rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2)); -#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */ rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3)); + rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); + rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); +#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); #endif + rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); /* SSL_OP_* flags for DTLS */ #if 0 @@ -2950,17 +3257,14 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION)); /* TLS 1.2 */ rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION)); -#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */ /* TLS 1.3 */ rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION)); -#endif sym_exception = ID2SYM(rb_intern_const("exception")); sym_wait_readable = ID2SYM(rb_intern_const("wait_readable")); sym_wait_writable = ID2SYM(rb_intern_const("wait_writable")); - id_tmp_dh_callback = rb_intern_const("tmp_dh_callback"); id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded"); id_each = rb_intern_const("each"); @@ -2990,8 +3294,11 @@ Init_ossl_ssl(void) DefIVarID(alpn_select_cb); DefIVarID(servername_cb); DefIVarID(verify_hostname); + DefIVarID(keylog_cb); + DefIVarID(tmp_dh_callback); DefIVarID(io); DefIVarID(context); DefIVarID(hostname); +#endif /* !defined(OPENSSL_NO_SOCK) */ } diff --git a/ext/openssl/ossl_ssl.h b/ext/openssl/ossl_ssl.h index 535c56097c..a87e62d450 100644 --- a/ext/openssl/ossl_ssl.h +++ b/ext/openssl/ossl_ssl.h @@ -5,23 +5,23 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_SSL_H_) #define _OSSL_SSL_H_ #define GetSSL(obj, ssl) do { \ - TypedData_Get_Struct((obj), SSL, &ossl_ssl_type, (ssl)); \ - if (!(ssl)) { \ - ossl_raise(rb_eRuntimeError, "SSL is not initialized"); \ - } \ + TypedData_Get_Struct((obj), SSL, &ossl_ssl_type, (ssl)); \ + if (!(ssl)) { \ + ossl_raise(rb_eRuntimeError, "SSL is not initialized"); \ + } \ } while (0) #define GetSSLSession(obj, sess) do { \ - TypedData_Get_Struct((obj), SSL_SESSION, &ossl_ssl_session_type, (sess)); \ - if (!(sess)) { \ - ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ - } \ + TypedData_Get_Struct((obj), SSL_SESSION, &ossl_ssl_session_type, (sess)); \ + if (!(sess)) { \ + ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ + } \ } while (0) extern const rb_data_type_t ossl_ssl_type; diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index 92eb1365fe..8a2fbf4100 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -4,6 +4,7 @@ #include "ossl.h" +#ifndef OPENSSL_NO_SOCK VALUE cSSLSession; static VALUE eSSLSession; @@ -16,14 +17,14 @@ ossl_ssl_session_free(void *ptr) const rb_data_type_t ossl_ssl_session_type = { "OpenSSL/SSL/Session", { - 0, ossl_ssl_session_free, + 0, ossl_ssl_session_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE ossl_ssl_session_alloc(VALUE klass) { - return TypedData_Wrap_Struct(klass, &ossl_ssl_session_type, NULL); + return TypedData_Wrap_Struct(klass, &ossl_ssl_session_type, NULL); } /* @@ -68,6 +69,7 @@ ossl_ssl_session_initialize(VALUE self, VALUE arg1) return self; } +/* :nodoc: */ static VALUE ossl_ssl_session_initialize_copy(VALUE self, VALUE other) { @@ -78,9 +80,9 @@ ossl_ssl_session_initialize_copy(VALUE self, VALUE other) GetSSLSession(other, sess_other); sess_new = ASN1_dup((i2d_of_void *)i2d_SSL_SESSION, (d2i_of_void *)d2i_SSL_SESSION, - (char *)sess_other); + (char *)sess_other); if (!sess_new) - ossl_raise(eSSLSession, "ASN1_dup"); + ossl_raise(eSSLSession, "ASN1_dup"); RTYPEDDATA_DATA(self) = sess_new; SSL_SESSION_free(sess); @@ -97,9 +99,9 @@ ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) const unsigned char *b_sid = SSL_SESSION_get_id(b, &b_len); if (SSL_SESSION_get_protocol_version(a) != SSL_SESSION_get_protocol_version(b)) - return 1; + return 1; if (a_len != b_len) - return 1; + return 1; return CRYPTO_memcmp(a_sid, b_sid, a_len); } @@ -112,15 +114,15 @@ ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) */ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2) { - SSL_SESSION *ctx1, *ctx2; + SSL_SESSION *ctx1, *ctx2; - GetSSLSession(val1, ctx1); - GetSSLSession(val2, ctx2); + GetSSLSession(val1, ctx1); + GetSSLSession(val2, ctx2); - switch (ossl_SSL_SESSION_cmp(ctx1, ctx2)) { - case 0: return Qtrue; - default: return Qfalse; - } + switch (ossl_SSL_SESSION_cmp(ctx1, ctx2)) { + case 0: return Qtrue; + default: return Qfalse; + } } /* @@ -138,7 +140,7 @@ ossl_ssl_session_get_time(VALUE self) GetSSLSession(self, ctx); t = SSL_SESSION_get_time(ctx); if (t == 0) - return Qnil; + return Qnil; return rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(t)); } @@ -173,16 +175,16 @@ ossl_ssl_session_get_timeout(VALUE self) */ static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v) { - SSL_SESSION *ctx; - long t; - - GetSSLSession(self, ctx); - if (rb_obj_is_instance_of(time_v, rb_cTime)) { - time_v = rb_funcall(time_v, rb_intern("to_i"), 0); - } - t = NUM2LONG(time_v); - SSL_SESSION_set_time(ctx, t); - return ossl_ssl_session_get_time(self); + SSL_SESSION *ctx; + long t; + + GetSSLSession(self, ctx); + if (rb_obj_is_instance_of(time_v, rb_cTime)) { + time_v = rb_funcall(time_v, rb_intern("to_i"), 0); + } + t = NUM2LONG(time_v); + SSL_SESSION_set_time(ctx, t); + return ossl_ssl_session_get_time(self); } /* @@ -193,13 +195,13 @@ static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v) */ static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v) { - SSL_SESSION *ctx; - long t; + SSL_SESSION *ctx; + long t; - GetSSLSession(self, ctx); - t = NUM2LONG(time_v); - SSL_SESSION_set_timeout(ctx, t); - return ossl_ssl_session_get_timeout(self); + GetSSLSession(self, ctx); + t = NUM2LONG(time_v); + SSL_SESSION_set_timeout(ctx, t); + return ossl_ssl_session_get_timeout(self); } /* @@ -207,18 +209,18 @@ static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v) * session.id -> String * * Returns the Session ID. -*/ + */ static VALUE ossl_ssl_session_get_id(VALUE self) { - SSL_SESSION *ctx; - const unsigned char *p = NULL; - unsigned int i = 0; + SSL_SESSION *ctx; + const unsigned char *p = NULL; + unsigned int i = 0; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - p = SSL_SESSION_get_id(ctx, &i); + p = SSL_SESSION_get_id(ctx, &i); - return rb_str_new((const char *) p, i); + return rb_str_new((const char *) p, i); } /* @@ -229,22 +231,22 @@ static VALUE ossl_ssl_session_get_id(VALUE self) */ static VALUE ossl_ssl_session_to_der(VALUE self) { - SSL_SESSION *ctx; - unsigned char *p; - int len; - VALUE str; - - GetSSLSession(self, ctx); - len = i2d_SSL_SESSION(ctx, NULL); - if (len <= 0) { - ossl_raise(eSSLSession, "i2d_SSL_SESSION"); - } - - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - i2d_SSL_SESSION(ctx, &p); - ossl_str_adjust(str, p); - return str; + SSL_SESSION *ctx; + unsigned char *p; + int len; + VALUE str; + + GetSSLSession(self, ctx); + len = i2d_SSL_SESSION(ctx, NULL); + if (len <= 0) { + ossl_raise(eSSLSession, "i2d_SSL_SESSION"); + } + + str = rb_str_new(0, len); + p = (unsigned char *)RSTRING_PTR(str); + i2d_SSL_SESSION(ctx, &p); + ossl_str_adjust(str, p); + return str; } /* @@ -255,22 +257,22 @@ static VALUE ossl_ssl_session_to_der(VALUE self) */ static VALUE ossl_ssl_session_to_pem(VALUE self) { - SSL_SESSION *ctx; - BIO *out; + SSL_SESSION *ctx; + BIO *out; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } + if (!(out = BIO_new(BIO_s_mem()))) { + ossl_raise(eSSLSession, "BIO_s_mem()"); + } - if (!PEM_write_bio_SSL_SESSION(out, ctx)) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } + if (!PEM_write_bio_SSL_SESSION(out, ctx)) { + BIO_free(out); + ossl_raise(eSSLSession, "SSL_SESSION_print()"); + } - return ossl_membio2str(out); + return ossl_membio2str(out); } @@ -282,46 +284,44 @@ static VALUE ossl_ssl_session_to_pem(VALUE self) */ static VALUE ossl_ssl_session_to_text(VALUE self) { - SSL_SESSION *ctx; - BIO *out; + SSL_SESSION *ctx; + BIO *out; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } + if (!(out = BIO_new(BIO_s_mem()))) { + ossl_raise(eSSLSession, "BIO_s_mem()"); + } - if (!SSL_SESSION_print(out, ctx)) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } + if (!SSL_SESSION_print(out, ctx)) { + BIO_free(out); + ossl_raise(eSSLSession, "SSL_SESSION_print()"); + } - return ossl_membio2str(out); + return ossl_membio2str(out); } +#endif /* !defined(OPENSSL_NO_SOCK) */ void Init_ossl_ssl_session(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - mSSL = rb_define_module_under(mOSSL, "SSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject); - eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError); - - rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); - rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); - rb_define_method(cSSLSession, "initialize_copy", ossl_ssl_session_initialize_copy, 1); - - rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); - - rb_define_method(cSSLSession, "time", ossl_ssl_session_get_time, 0); - rb_define_method(cSSLSession, "time=", ossl_ssl_session_set_time, 1); - rb_define_method(cSSLSession, "timeout", ossl_ssl_session_get_timeout, 0); - rb_define_method(cSSLSession, "timeout=", ossl_ssl_session_set_timeout, 1); - rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0); - rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0); - rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0); - rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0); +#ifndef OPENSSL_NO_SOCK + cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject); + eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError); + + rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); + rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); + rb_define_method(cSSLSession, "initialize_copy", ossl_ssl_session_initialize_copy, 1); + + rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); + + rb_define_method(cSSLSession, "time", ossl_ssl_session_get_time, 0); + rb_define_method(cSSLSession, "time=", ossl_ssl_session_set_time, 1); + rb_define_method(cSSLSession, "timeout", ossl_ssl_session_get_timeout, 0); + rb_define_method(cSSLSession, "timeout=", ossl_ssl_session_set_timeout, 1); + rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0); + rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0); + rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0); + rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0); +#endif /* !defined(OPENSSL_NO_SOCK) */ } diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index b9a62fd9e4..b31a854a63 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -5,7 +5,7 @@ */ /* * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -83,7 +83,7 @@ static const rb_data_type_t ossl_ts_req_type = { { 0, ossl_ts_req_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -97,13 +97,13 @@ static const rb_data_type_t ossl_ts_resp_type = { { 0, ossl_ts_resp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void ossl_ts_token_info_free(void *ptr) { - TS_TST_INFO_free(ptr); + TS_TST_INFO_free(ptr); } static const rb_data_type_t ossl_ts_token_info_type = { @@ -111,7 +111,7 @@ static const rb_data_type_t ossl_ts_token_info_type = { { 0, ossl_ts_token_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -132,41 +132,10 @@ asn1_to_der(void *template, int (*i2d)(void *template, unsigned char **pp)) return str; } -static ASN1_OBJECT* -obj_to_asn1obj(VALUE obj) -{ - ASN1_OBJECT *a1obj; - - StringValue(obj); - a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0); - if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1); - if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID"); - - return a1obj; -} - static VALUE obj_to_asn1obj_i(VALUE obj) { - return (VALUE)obj_to_asn1obj(obj); -} - -static VALUE -get_asn1obj(ASN1_OBJECT *obj) -{ - BIO *out; - VALUE ret; - int nid; - if ((nid = OBJ_obj2nid(obj)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509AttrError, NULL); - i2a_ASN1_OBJECT(out, obj); - ret = ossl_membio2str(out); - } - - return ret; + return (VALUE)ossl_to_asn1obj(obj); } static VALUE @@ -233,11 +202,13 @@ ossl_ts_req_get_algorithm(VALUE self) TS_REQ *req; TS_MSG_IMPRINT *mi; X509_ALGOR *algor; + const ASN1_OBJECT *obj; GetTSRequest(self, req); mi = TS_REQ_get_msg_imprint(req); algor = TS_MSG_IMPRINT_get_algo(mi); - return get_asn1obj(algor->algorithm); + X509_ALGOR_get0(&obj, NULL, NULL, algor); + return ossl_asn1obj_to_string(obj); } /* @@ -259,7 +230,7 @@ ossl_ts_req_set_algorithm(VALUE self, VALUE algo) X509_ALGOR *algor; GetTSRequest(self, req); - obj = obj_to_asn1obj(algo); + obj = ossl_to_asn1obj(algo); mi = TS_REQ_get_msg_imprint(req); algor = TS_MSG_IMPRINT_get_algo(mi); if (!X509_ALGOR_set0(algor, obj, V_ASN1_NULL, NULL)) { @@ -288,7 +259,7 @@ ossl_ts_req_get_msg_imprint(VALUE self) mi = TS_REQ_get_msg_imprint(req); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length); + ret = asn1str_to_str(hashed_msg); return ret; } @@ -366,7 +337,7 @@ ossl_ts_req_get_policy_id(VALUE self) GetTSRequest(self, req); if (!TS_REQ_get_policy_id(req)) return Qnil; - return get_asn1obj(TS_REQ_get_policy_id(req)); + return ossl_asn1obj_to_string(TS_REQ_get_policy_id(req)); } /* @@ -389,7 +360,7 @@ ossl_ts_req_set_policy_id(VALUE self, VALUE oid) int ok; GetTSRequest(self, req); - obj = obj_to_asn1obj(oid); + obj = ossl_to_asn1obj(oid); ok = TS_REQ_set_policy_id(req, obj); ASN1_OBJECT_free(obj); if (!ok) @@ -487,23 +458,44 @@ ossl_ts_req_to_der(VALUE self) TS_REQ *req; TS_MSG_IMPRINT *mi; X509_ALGOR *algo; + const ASN1_OBJECT *obj; ASN1_OCTET_STRING *hashed_msg; GetTSRequest(self, req); mi = TS_REQ_get_msg_imprint(req); algo = TS_MSG_IMPRINT_get_algo(mi); - if (OBJ_obj2nid(algo->algorithm) == NID_undef) + X509_ALGOR_get0(&obj, NULL, NULL, algo); + if (OBJ_obj2nid(obj) == NID_undef) ossl_raise(eTimestampError, "Message imprint missing algorithm"); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - if (!hashed_msg->length) + if (!ASN1_STRING_length(hashed_msg)) ossl_raise(eTimestampError, "Message imprint missing hashed message"); return asn1_to_der((void *)req, (int (*)(void *, unsigned char **))i2d_TS_REQ); } static VALUE +ossl_ts_req_to_text(VALUE self) +{ + TS_REQ *req; + BIO *out; + + GetTSRequest(self, req); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_REQ_print_bio(out, req)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +static VALUE ossl_ts_resp_alloc(VALUE klass) { TS_RESP *resp; @@ -598,14 +590,7 @@ ossl_ts_resp_get_failure_info(VALUE self) { TS_RESP *resp; TS_STATUS_INFO *si; - - /* The ASN1_BIT_STRING_get_bit changed from 1.0.0. to 1.1.0, making this - * const. */ - #if defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO) const ASN1_BIT_STRING *fi; - #else - ASN1_BIT_STRING *fi; - #endif GetTSResponse(self, resp); si = TS_RESP_get_status_info(resp); @@ -672,21 +657,12 @@ static VALUE ossl_ts_resp_get_token(VALUE self) { TS_RESP *resp; - PKCS7 *p7, *copy; - VALUE obj; + PKCS7 *p7; GetTSResponse(self, resp); if (!(p7 = TS_RESP_get_token(resp))) return Qnil; - - obj = NewPKCS7(cPKCS7); - - if (!(copy = PKCS7_dup(p7))) - ossl_raise(eTimestampError, NULL); - - SetPKCS7(obj, copy); - - return obj; + return ossl_pkcs7_new(p7); } /* @@ -757,6 +733,25 @@ ossl_ts_resp_to_der(VALUE self) return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP); } +static VALUE +ossl_ts_resp_to_text(VALUE self) +{ + TS_RESP *resp; + BIO *out; + + GetTSResponse(self, resp); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_RESP_print_bio(out, resp)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + /* * Verifies a timestamp token by checking the signature, validating the * certificate chain implied by tsa_certificate and by checking conformance to @@ -826,16 +821,26 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) X509_up_ref(cert); } + if (!X509_STORE_up_ref(x509st)) { + sk_X509_pop_free(x509inter, X509_free); + TS_VERIFY_CTX_free(ctx); + ossl_raise(eTimestampError, "X509_STORE_up_ref"); + } + +#ifdef HAVE_TS_VERIFY_CTX_SET0_CERTS + TS_VERIFY_CTX_set0_certs(ctx, x509inter); + TS_VERIFY_CTX_set0_store(ctx, x509st); +#else +# if OSSL_OPENSSL_PREREQ(3, 0, 0) || OSSL_IS_LIBRESSL + TS_VERIFY_CTX_set_certs(ctx, x509inter); +# else TS_VERIFY_CTS_set_certs(ctx, x509inter); - TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); +# endif TS_VERIFY_CTX_set_store(ctx, x509st); +#endif + TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); ok = TS_RESP_verify_response(ctx, resp); - /* - * TS_VERIFY_CTX_set_store() call above does not increment the reference - * counter, so it must be unset before TS_VERIFY_CTX_free() is called. - */ - TS_VERIFY_CTX_set_store(ctx, NULL); TS_VERIFY_CTX_free(ctx); if (!ok) @@ -922,7 +927,7 @@ ossl_ts_token_info_get_policy_id(VALUE self) TS_TST_INFO *info; GetTSTokenInfo(self, info); - return get_asn1obj(TS_TST_INFO_get_policy_id(info)); + return ossl_asn1obj_to_string(TS_TST_INFO_get_policy_id(info)); } /* @@ -944,11 +949,13 @@ ossl_ts_token_info_get_algorithm(VALUE self) TS_TST_INFO *info; TS_MSG_IMPRINT *mi; X509_ALGOR *algo; + const ASN1_OBJECT *obj; GetTSTokenInfo(self, info); mi = TS_TST_INFO_get_msg_imprint(info); algo = TS_MSG_IMPRINT_get_algo(mi); - return get_asn1obj(algo->algorithm); + X509_ALGOR_get0(&obj, NULL, NULL, algo); + return ossl_asn1obj_to_string(obj); } /* @@ -974,7 +981,7 @@ ossl_ts_token_info_get_msg_imprint(VALUE self) GetTSTokenInfo(self, info); mi = TS_TST_INFO_get_msg_imprint(info); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length); + ret = asn1str_to_str(hashed_msg); return ret; } @@ -1073,6 +1080,25 @@ ossl_ts_token_info_to_der(VALUE self) return asn1_to_der((void *)info, (int (*)(void *, unsigned char **))i2d_TS_TST_INFO); } +static VALUE +ossl_ts_token_info_to_text(VALUE self) +{ + TS_TST_INFO *info; + BIO *out; + + GetTSTokenInfo(self, info); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_TST_INFO_print_bio(out, info)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + static ASN1_INTEGER * ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data) { @@ -1095,9 +1121,14 @@ ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec) } static VALUE -ossl_evp_get_digestbyname_i(VALUE arg) +ossl_evp_md_fetch_i(VALUE args_) { - return (VALUE)ossl_evp_get_digestbyname(arg); + VALUE *args = (VALUE *)args_, md_holder; + const EVP_MD *md; + + md = ossl_evp_md_fetch(args[1], &md_holder); + rb_ary_push(args[0], md_holder); + return (VALUE)md; } static VALUE @@ -1133,7 +1164,8 @@ ossl_obj2bio_i(VALUE arg) static VALUE ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) { - VALUE serial_number, def_policy_id, gen_time, additional_certs, allowed_digests; + VALUE serial_number, def_policy_id, gen_time, additional_certs, + allowed_digests, allowed_digests_tmp = Qnil; VALUE str; STACK_OF(X509) *inter_certs; VALUE tsresp, ret = Qnil; @@ -1194,7 +1226,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) if (rb_obj_is_kind_of(additional_certs, rb_cArray)) { inter_certs = ossl_protect_x509_ary2sk(additional_certs, &status); if (status) - goto end; + goto end; /* this dups the sk_X509 and ups each cert's ref count */ TS_RESP_CTX_set_certs(ctx, inter_certs); @@ -1210,16 +1242,18 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) allowed_digests = ossl_tsfac_get_allowed_digests(self); if (rb_obj_is_kind_of(allowed_digests, rb_cArray)) { - int i; - VALUE rbmd; - const EVP_MD *md; - - for (i = 0; i < RARRAY_LEN(allowed_digests); i++) { - rbmd = rb_ary_entry(allowed_digests, i); - md = (const EVP_MD *)rb_protect(ossl_evp_get_digestbyname_i, rbmd, &status); + allowed_digests_tmp = rb_ary_new_capa(RARRAY_LEN(allowed_digests)); + for (long i = 0; i < RARRAY_LEN(allowed_digests); i++) { + VALUE args[] = { + allowed_digests_tmp, + rb_ary_entry(allowed_digests, i), + }; + const EVP_MD *md = (const EVP_MD *)rb_protect(ossl_evp_md_fetch_i, + (VALUE)args, &status); if (status) goto end; - TS_RESP_CTX_add_md(ctx, md); + if (!TS_RESP_CTX_add_md(ctx, md)) + goto end; } } @@ -1233,6 +1267,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) response = TS_RESP_create_response(ctx, req_bio); BIO_free(req_bio); + RB_GC_GUARD(allowed_digests_tmp); if (!response) { err_msg = "Error during response generation"; @@ -1246,7 +1281,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) SetTSResponse(tsresp, response); ret = tsresp; -end: + end: ASN1_INTEGER_free(asn1_serial); ASN1_OBJECT_free(def_policy_id_obj); TS_RESP_CTX_free(ctx); @@ -1263,10 +1298,6 @@ end: void Init_ossl_ts(void) { - #if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ - #endif - /* * Possible return value for +Response#failure_info+. Indicates that the * timestamp server rejects the message imprint algorithm used in the @@ -1356,6 +1387,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampResponse, "token_info", ossl_ts_resp_get_token_info, 0); rb_define_method(cTimestampResponse, "tsa_certificate", ossl_ts_resp_get_tsa_certificate, 0); rb_define_method(cTimestampResponse, "to_der", ossl_ts_resp_to_der, 0); + rb_define_method(cTimestampResponse, "to_text", ossl_ts_resp_to_text, 0); rb_define_method(cTimestampResponse, "verify", ossl_ts_resp_verify, -1); /* Document-class: OpenSSL::Timestamp::TokenInfo @@ -1374,6 +1406,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampTokenInfo, "ordering", ossl_ts_token_info_get_ordering, 0); rb_define_method(cTimestampTokenInfo, "nonce", ossl_ts_token_info_get_nonce, 0); rb_define_method(cTimestampTokenInfo, "to_der", ossl_ts_token_info_to_der, 0); + rb_define_method(cTimestampTokenInfo, "to_text", ossl_ts_token_info_to_text, 0); /* Document-class: OpenSSL::Timestamp::Request * Allows to create timestamp requests or parse existing ones. A Request is @@ -1399,6 +1432,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampRequest, "cert_requested=", ossl_ts_req_set_cert_requested, 1); rb_define_method(cTimestampRequest, "cert_requested?", ossl_ts_req_get_cert_requested, 0); rb_define_method(cTimestampRequest, "to_der", ossl_ts_req_to_der, 0); + rb_define_method(cTimestampRequest, "to_text", ossl_ts_req_to_text, 0); /* * Indicates a successful response. Equal to +0+. @@ -1473,67 +1507,45 @@ Init_ossl_ts(void) * fac.default_policy_id = '1.2.3.4.5' * fac.additional_certificates = [ inter1, inter2 ] * timestamp = fac.create_timestamp(p12.key, p12.certificate, req) - * - * ==Attributes - * - * ===default_policy_id + */ + cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject); + /* + * The list of digest algorithms that the factory is allowed + * create timestamps for. Known vulnerable or weak algorithms should not be + * allowed where possible. Must be an Array of String or OpenSSL::Digest + * subclass instances. + */ + rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0); + /* + * A String representing the default policy object identifier, or +nil+. * * Request#policy_id will always be preferred over this if present in the - * Request, only if Request#policy_id is nil default_policy will be used. + * Request, only if Request#policy_id is +nil+ default_policy will be used. * If none of both is present, a TimestampError will be raised when trying * to create a Response. - * - * call-seq: - * factory.default_policy_id = "string" -> string - * factory.default_policy_id -> string or nil - * - * ===serial_number - * - * Sets or retrieves the serial number to be used for timestamp creation. - * Must be present for timestamp creation. - * - * call-seq: - * factory.serial_number = number -> number - * factory.serial_number -> number or nil - * - * ===gen_time - * - * Sets or retrieves the Time value to be used in the Response. Must be - * present for timestamp creation. - * - * call-seq: - * factory.gen_time = Time -> Time - * factory.gen_time -> Time or nil - * - * ===additional_certs - * - * Sets or retrieves additional certificates apart from the timestamp - * certificate (e.g. intermediate certificates) to be added to the Response. - * Must be an Array of OpenSSL::X509::Certificate. - * - * call-seq: - * factory.additional_certs = [cert1, cert2] -> [ cert1, cert2 ] - * factory.additional_certs -> array or nil - * - * ===allowed_digests - * - * Sets or retrieves the digest algorithms that the factory is allowed - * create timestamps for. Known vulnerable or weak algorithms should not be - * allowed where possible. - * Must be an Array of String or OpenSSL::Digest subclass instances. - * - * call-seq: - * factory.allowed_digests = ["sha1", OpenSSL::Digest.new('SHA256').new] -> [ "sha1", OpenSSL::Digest) ] - * factory.allowed_digests -> array or nil - * */ - cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject); - rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0); rb_attr(cTimestampFactory, rb_intern_const("default_policy_id"), 1, 1, 0); + /* + * The serial number to be used for timestamp creation. Must be present for + * timestamp creation. Must be an instance of OpenSSL::BN or Integer. + */ rb_attr(cTimestampFactory, rb_intern_const("serial_number"), 1, 1, 0); + /* + * The Time value to be used in the Response. Must be present for timestamp + * creation. + */ rb_attr(cTimestampFactory, rb_intern_const("gen_time"), 1, 1, 0); + /* + * Additional certificates apart from the timestamp certificate (e.g. + * intermediate certificates) to be added to the Response. + * Must be an Array of OpenSSL::X509::Certificate, or +nil+. + */ rb_attr(cTimestampFactory, rb_intern_const("additional_certs"), 1, 1, 0); rb_define_method(cTimestampFactory, "create_timestamp", ossl_tsfac_create_ts, 3); } - +#else /* OPENSSL_NO_TS */ +void +Init_ossl_ts(void) +{ +} #endif diff --git a/ext/openssl/ossl_ts.h b/ext/openssl/ossl_ts.h index 25fb0e1d64..eeca3046eb 100644 --- a/ext/openssl/ossl_ts.h +++ b/ext/openssl/ossl_ts.h @@ -5,7 +5,7 @@ */ /* * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_TS_H_) diff --git a/ext/openssl/ossl_x509.c b/ext/openssl/ossl_x509.c index f8470703fc..bc3914fda2 100644 --- a/ext/openssl/ossl_x509.c +++ b/ext/openssl/ossl_x509.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,7 +13,8 @@ VALUE mX509; #define DefX509Const(x) rb_define_const(mX509, #x, INT2NUM(X509_##x)) #define DefX509Default(x,i) \ - rb_define_const(mX509, "DEFAULT_" #x, rb_str_new2(X509_get_default_##i())) + rb_define_const(mX509, "DEFAULT_" #x, \ + rb_obj_freeze(rb_str_new_cstr(X509_get_default_##i()))) ASN1_TIME * ossl_x509_time_adjust(ASN1_TIME *s, VALUE time) @@ -29,10 +30,6 @@ ossl_x509_time_adjust(ASN1_TIME *s, VALUE time) void Init_ossl_x509(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); -#endif - mX509 = rb_define_module_under(mOSSL, "X509"); Init_ossl_x509attr(); @@ -48,9 +45,7 @@ Init_ossl_x509(void) /* Certificate verification error code */ DefX509Const(V_OK); -#if defined(X509_V_ERR_UNSPECIFIED) /* 1.0.1r, 1.0.2f, 1.1.0 */ DefX509Const(V_ERR_UNSPECIFIED); -#endif DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT); DefX509Const(V_ERR_UNABLE_TO_GET_CRL); DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE); @@ -104,10 +99,10 @@ Init_ossl_x509(void) DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX); DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX); DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR); -#if defined(X509_V_ERR_PATH_LOOP) +#if defined(X509_V_ERR_PATH_LOOP) /* OpenSSL 1.1.0, missing in LibreSSL */ DefX509Const(V_ERR_PATH_LOOP); #endif -#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION) +#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION) /* OpenSSL 1.1.0, missing in LibreSSL */ DefX509Const(V_ERR_SUITE_B_INVALID_VERSION); DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM); DefX509Const(V_ERR_SUITE_B_INVALID_CURVE); @@ -118,27 +113,21 @@ Init_ossl_x509(void) DefX509Const(V_ERR_HOSTNAME_MISMATCH); DefX509Const(V_ERR_EMAIL_MISMATCH); DefX509Const(V_ERR_IP_ADDRESS_MISMATCH); -#if defined(X509_V_ERR_DANE_NO_MATCH) +#if defined(X509_V_ERR_DANE_NO_MATCH) /* OpenSSL 1.1.0, missing in LibreSSL */ DefX509Const(V_ERR_DANE_NO_MATCH); #endif -#if defined(X509_V_ERR_EE_KEY_TOO_SMALL) DefX509Const(V_ERR_EE_KEY_TOO_SMALL); DefX509Const(V_ERR_CA_KEY_TOO_SMALL); DefX509Const(V_ERR_CA_MD_TOO_WEAK); -#endif -#if defined(X509_V_ERR_INVALID_CALL) DefX509Const(V_ERR_INVALID_CALL); -#endif -#if defined(X509_V_ERR_STORE_LOOKUP) DefX509Const(V_ERR_STORE_LOOKUP); -#endif -#if defined(X509_V_ERR_NO_VALID_SCTS) +#if defined(X509_V_ERR_NO_VALID_SCTS) /* OpenSSL 1.1.0, missing in LibreSSL */ DefX509Const(V_ERR_NO_VALID_SCTS); #endif -#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION) +#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION) /* OpenSSL 1.1.0, missing in LibreSSL */ DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION); #endif -#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED) +#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED) /* OpenSSL 1.1.1, missing in LibreSSL */ DefX509Const(V_ERR_OCSP_VERIFY_NEEDED); DefX509Const(V_ERR_OCSP_VERIFY_FAILED); DefX509Const(V_ERR_OCSP_CERT_UNKNOWN); @@ -189,17 +178,13 @@ Init_ossl_x509(void) * certificate chain, search the Store first for the issuer certificate. * Enabled by default in OpenSSL >= 1.1.0. */ DefX509Const(V_FLAG_TRUSTED_FIRST); -#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY) +#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY) /* OpenSSL 1.1.0, missing in LibreSSL */ /* Set by Store#flags= and StoreContext#flags=. * Enables Suite B 128 bit only mode. */ DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY); -#endif -#if defined(X509_V_FLAG_SUITEB_192_LOS) /* Set by Store#flags= and StoreContext#flags=. * Enables Suite B 192 bit only mode. */ DefX509Const(V_FLAG_SUITEB_192_LOS); -#endif -#if defined(X509_V_FLAG_SUITEB_128_LOS) /* Set by Store#flags= and StoreContext#flags=. * Enables Suite B 128 bit mode allowing 192 bit algorithms. */ DefX509Const(V_FLAG_SUITEB_128_LOS); @@ -207,17 +192,13 @@ Init_ossl_x509(void) /* Set by Store#flags= and StoreContext#flags=. * Allows partial chains if at least one certificate is in trusted store. */ DefX509Const(V_FLAG_PARTIAL_CHAIN); -#if defined(X509_V_FLAG_NO_ALT_CHAINS) /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for * a alternative chain. No effect in OpenSSL >= 1.1.0. */ DefX509Const(V_FLAG_NO_ALT_CHAINS); -#endif -#if defined(X509_V_FLAG_NO_CHECK_TIME) /* Set by Store#flags= and StoreContext#flags=. Suppresses checking the * validity period of certificates and CRLs. No effect when the current * time is explicitly set by Store#time= or StoreContext#time=. */ DefX509Const(V_FLAG_NO_CHECK_TIME); -#endif /* Set by Store#purpose=. SSL/TLS client. */ DefX509Const(PURPOSE_SSL_CLIENT); diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h index 4fadfa6b82..d25167ee7b 100644 --- a/ext/openssl/ossl_x509.h +++ b/ext/openssl/ossl_x509.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_X509_H_) #define _OSSL_X509_H_ @@ -28,7 +28,6 @@ void Init_ossl_x509(void); * X509Attr */ extern VALUE cX509Attr; -extern VALUE eX509AttrError; VALUE ossl_x509attr_new(X509_ATTRIBUTE *); X509_ATTRIBUTE *GetX509AttrPtr(VALUE); @@ -38,7 +37,6 @@ void Init_ossl_x509attr(void); * X509Cert */ extern VALUE cX509Cert; -extern VALUE eX509CertError; VALUE ossl_x509_new(X509 *); X509 *GetX509CertPtr(VALUE); @@ -48,9 +46,6 @@ void Init_ossl_x509cert(void); /* * X509CRL */ -extern VALUE cX509CRL; -extern VALUE eX509CRLError; - VALUE ossl_x509crl_new(X509_CRL *); X509_CRL *GetX509CRLPtr(VALUE); void Init_ossl_x509crl(void); @@ -59,8 +54,6 @@ void Init_ossl_x509crl(void); * X509Extension */ extern VALUE cX509Ext; -extern VALUE cX509ExtFactory; -extern VALUE eX509ExtError; VALUE ossl_x509ext_new(X509_EXTENSION *); X509_EXTENSION *GetX509ExtPtr(VALUE); @@ -69,9 +62,6 @@ void Init_ossl_x509ext(void); /* * X509Name */ -extern VALUE cX509Name; -extern VALUE eX509NameError; - VALUE ossl_x509name_new(X509_NAME *); X509_NAME *GetX509NamePtr(VALUE); void Init_ossl_x509name(void); @@ -79,9 +69,6 @@ void Init_ossl_x509name(void); /* * X509Request */ -extern VALUE cX509Req; -extern VALUE eX509ReqError; - X509_REQ *GetX509ReqPtr(VALUE); void Init_ossl_x509req(void); @@ -89,7 +76,6 @@ void Init_ossl_x509req(void); * X509Revoked */ extern VALUE cX509Rev; -extern VALUE eX509RevError; VALUE ossl_x509revoked_new(X509_REVOKED *); X509_REVOKED *DupX509RevokedPtr(VALUE); @@ -98,12 +84,7 @@ void Init_ossl_x509revoked(void); /* * X509Store and X509StoreContext */ -extern VALUE cX509Store; -extern VALUE cX509StoreContext; -extern VALUE eX509StoreError; - X509_STORE *GetX509StorePtr(VALUE); - void Init_ossl_x509store(void); /* diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 60846cfe9d..4769e56e1e 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509attr_type, 0) #define SetX509Attr(obj, attr) do { \ if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (attr); \ } while (0) #define GetX509Attr(obj, attr) do { \ TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \ if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Attr; -VALUE eX509AttrError; +static VALUE eX509AttrError; static void ossl_x509attr_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509attr_free(void *ptr) static const rb_data_type_t ossl_x509attr_type = { "OpenSSL/X509/ATTRIBUTE", { - 0, ossl_x509attr_free, + 0, ossl_x509attr_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr) VALUE obj; obj = NewX509Attr(cX509Attr); - if (!attr) { - new = X509_ATTRIBUTE_new(); - } else { - new = X509_ATTRIBUTE_dup(attr); - } - if (!new) { - ossl_raise(eX509AttrError, NULL); - } + new = X509_ATTRIBUTE_dup(attr); + if (!new) + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); SetX509Attr(obj, new); return obj; @@ -88,7 +83,7 @@ ossl_x509attr_alloc(VALUE klass) obj = NewX509Attr(klass); if (!(attr = X509_ATTRIBUTE_new())) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); SetX509Attr(obj, attr); return obj; @@ -107,15 +102,15 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) GetX509Attr(self, attr); if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = attr; - if(!x){ - ossl_raise(eX509AttrError, NULL); - } - return self; + oid = ossl_to_der_if_possible(oid); + StringValue(oid); + p = (unsigned char *)RSTRING_PTR(oid); + x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); + DATA_PTR(self) = attr; + if(!x){ + ossl_raise(eX509AttrError, NULL); + } + return self; } rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); @@ -123,6 +118,7 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509attr_initialize_copy(VALUE self, VALUE other) { @@ -134,7 +130,7 @@ ossl_x509attr_initialize_copy(VALUE self, VALUE other) attr_new = X509_ATTRIBUTE_dup(attr_other); if (!attr_new) - ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); SetX509Attr(self, attr_new); X509_ATTRIBUTE_free(attr); @@ -158,8 +154,8 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid) obj = OBJ_txt2obj(s, 0); if(!obj) ossl_raise(eX509AttrError, NULL); if (!X509_ATTRIBUTE_set1_object(attr, obj)) { - ASN1_OBJECT_free(obj); - ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object"); + ASN1_OBJECT_free(obj); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object"); } ASN1_OBJECT_free(obj); @@ -168,29 +164,18 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid) /* * call-seq: - * attr.oid => string + * attr.oid -> string + * + * Returns the OID of the attribute. Returns the short name or the dotted + * decimal notation. */ static VALUE ossl_x509attr_get_oid(VALUE self) { X509_ATTRIBUTE *attr; - ASN1_OBJECT *oid; - BIO *out; - VALUE ret; - int nid; GetX509Attr(self, attr); - oid = X509_ATTRIBUTE_get0_object(attr); - if ((nid = OBJ_obj2nid(oid)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509AttrError, NULL); - i2a_ASN1_OBJECT(out, oid); - ret = ossl_membio2str(out); - } - - return ret; + return ossl_asn1obj_to_string(X509_ATTRIBUTE_get0_object(attr)); } /* @@ -201,37 +186,36 @@ static VALUE ossl_x509attr_set_value(VALUE self, VALUE value) { X509_ATTRIBUTE *attr; - VALUE asn1_value; - int i, asn1_tag; + GetX509Attr(self, attr); OSSL_Check_Kind(value, cASN1Data); - asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag"))); - asn1_value = rb_attr_get(value, rb_intern("@value")); - if (asn1_tag != V_ASN1_SET) - ossl_raise(eASN1Error, "argument must be ASN1::Set"); - if (!RB_TYPE_P(asn1_value, T_ARRAY)) - ossl_raise(eASN1Error, "ASN1::Set has non-array value"); + VALUE der = ossl_to_der(value); + const unsigned char *p = (const unsigned char *)RSTRING_PTR(der); + STACK_OF(ASN1_TYPE) *sk = d2i_ASN1_SET_ANY(NULL, &p, RSTRING_LEN(der)); + if (!sk) + ossl_raise(eX509AttrError, "attribute value must be ASN1::Set"); - GetX509Attr(self, attr); if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */ - ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); - X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); - if (!new_attr) - ossl_raise(eX509AttrError, NULL); - SetX509Attr(self, new_attr); - X509_ATTRIBUTE_free(attr); - attr = new_attr; + ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); + X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); + if (!new_attr) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_create_by_OBJ"); + } + SetX509Attr(self, new_attr); + X509_ATTRIBUTE_free(attr); + attr = new_attr; } - for (i = 0; i < RARRAY_LEN(asn1_value); i++) { - ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i)); - if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), - a1type->value.ptr, -1)) { - ASN1_TYPE_free(a1type); - ossl_raise(eX509AttrError, NULL); - } - ASN1_TYPE_free(a1type); + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + ASN1_TYPE *a1type = sk_ASN1_TYPE_value(sk, i); + if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), + a1type->value.ptr, -1)) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_data"); + } } + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); return value; } @@ -252,21 +236,21 @@ ossl_x509attr_get_value(VALUE self) GetX509Attr(self, attr); /* there is no X509_ATTRIBUTE_get0_set() :( */ if (!(sk = sk_ASN1_TYPE_new_null())) - ossl_raise(eX509AttrError, "sk_new"); + ossl_raise(eX509AttrError, "sk_new"); count = X509_ATTRIBUTE_count(attr); for (i = 0; i < count; i++) - sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); + sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) { - sk_ASN1_TYPE_free(sk); - ossl_raise(eX509AttrError, NULL); + sk_ASN1_TYPE_free(sk); + ossl_raise(eX509AttrError, NULL); } str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_ASN1_SET_ANY(sk, &p) <= 0) { - sk_ASN1_TYPE_free(sk); - ossl_raise(eX509AttrError, NULL); + sk_ASN1_TYPE_free(sk); + ossl_raise(eX509AttrError, NULL); } ossl_str_adjust(str, p); sk_ASN1_TYPE_free(sk); @@ -288,11 +272,11 @@ ossl_x509attr_to_der(VALUE self) GetX509Attr(self, attr); if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_ATTRIBUTE(attr, &p) <= 0) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); ossl_str_adjust(str, p); return str; @@ -304,12 +288,6 @@ ossl_x509attr_to_der(VALUE self) void Init_ossl_x509attr(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError); cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject); diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 996f184170..95679c7d24 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509_type, 0) #define SetX509(obj, x509) do { \ if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (x509); \ } while (0) #define GetX509(obj, x509) do { \ TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \ if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Cert; -VALUE eX509CertError; +static VALUE eX509CertError; static void ossl_x509_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509_free(void *ptr) static const rb_data_type_t ossl_x509_type = { "OpenSSL/X509", { - 0, ossl_x509_free, + 0, ossl_x509_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509_new(X509 *x509) VALUE obj; obj = NewX509(cX509Cert); - if (!x509) { - new = X509_new(); - } else { - new = X509_dup(x509); - } - if (!new) { - ossl_raise(eX509CertError, NULL); - } + new = X509_dup(x509); + if (!new) + ossl_raise(eX509CertError, "X509_dup"); SetX509(obj, new); return obj; @@ -120,8 +115,8 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self) rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - /* create just empty X509Cert */ - return self; + /* create just empty X509Cert */ + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); @@ -140,6 +135,7 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509_copy(VALUE self, VALUE other) { @@ -174,11 +170,11 @@ ossl_x509_to_der(VALUE self) GetX509(self, x509); if ((len = i2d_X509(x509, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509(x509, &p) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); ossl_str_adjust(str, p); return str; @@ -200,8 +196,8 @@ ossl_x509_to_pem(VALUE self) if (!out) ossl_raise(eX509CertError, NULL); if (!PEM_write_bio_X509(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); + BIO_free(out); + ossl_raise(eX509CertError, NULL); } str = ossl_membio2str(out); @@ -225,8 +221,8 @@ ossl_x509_to_text(VALUE self) if (!out) ossl_raise(eX509CertError, NULL); if (!X509_print(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); + BIO_free(out); + ossl_raise(eX509CertError, NULL); } str = ossl_membio2str(out); @@ -246,7 +242,7 @@ ossl_x509_to_req(VALUE self) GetX509(self, x509); if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } obj = ossl_x509req_new(req); X509_REQ_free(req); @@ -280,11 +276,11 @@ ossl_x509_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CertError, "version must be >= 0!"); + ossl_raise(eX509CertError, "version must be >= 0!"); } GetX509(self, x509); if (!X509_set_version(x509, ver)) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return version; @@ -322,25 +318,23 @@ ossl_x509_set_serial(VALUE self, VALUE num) /* * call-seq: * cert.signature_algorithm => string + * + * Returns the signature algorithm used to sign this certificate. This returns + * the algorithm name found in the TBSCertificate structure, not the outer + * \Certificate structure. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. */ static VALUE ossl_x509_get_signature_algorithm(VALUE self) { X509 *x509; - BIO *out; - VALUE str; + const ASN1_OBJECT *obj; GetX509(self, x509); - out = BIO_new(BIO_s_mem()); - if (!out) ossl_raise(eX509CertError, NULL); - - if (!i2a_ASN1_OBJECT(out, X509_get0_tbs_sigalg(x509)->algorithm)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); - } - str = ossl_membio2str(out); - - return str; + X509_ALGOR_get0(&obj, NULL, NULL, X509_get0_tbs_sigalg(x509)); + return ossl_asn1obj_to_string_long_name(obj); } /* @@ -355,7 +349,7 @@ ossl_x509_get_subject(VALUE self) GetX509(self, x509); if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return ossl_x509name_new(name); @@ -372,7 +366,7 @@ ossl_x509_set_subject(VALUE self, VALUE subject) GetX509(self, x509); if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return subject; @@ -390,7 +384,7 @@ ossl_x509_get_issuer(VALUE self) GetX509(self, x509); if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return ossl_x509name_new(name); @@ -407,7 +401,7 @@ ossl_x509_set_issuer(VALUE self, VALUE issuer) GetX509(self, x509); if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return issuer; @@ -425,7 +419,7 @@ ossl_x509_get_not_before(VALUE self) GetX509(self, x509); if (!(asn1time = X509_get0_notBefore(x509))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return asn1time_to_time(asn1time); @@ -444,8 +438,8 @@ ossl_x509_set_not_before(VALUE self, VALUE time) GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notBefore(x509, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CertError, "X509_set_notBefore"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CertError, "X509_set_notBefore"); } ASN1_TIME_free(asn1time); @@ -464,7 +458,7 @@ ossl_x509_get_not_after(VALUE self) GetX509(self, x509); if (!(asn1time = X509_get0_notAfter(x509))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return asn1time_to_time(asn1time); @@ -483,8 +477,8 @@ ossl_x509_set_not_after(VALUE self, VALUE time) GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notAfter(x509, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CertError, "X509_set_notAfter"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CertError, "X509_set_notAfter"); } ASN1_TIME_free(asn1time); @@ -503,10 +497,10 @@ ossl_x509_get_public_key(VALUE self) GetX509(self, x509); if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } /* @@ -523,7 +517,7 @@ ossl_x509_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!X509_set_pubkey(x509, pkey)) - ossl_raise(eX509CertError, "X509_set_pubkey"); + ossl_raise(eX509CertError, "X509_set_pubkey"); return key; } @@ -537,13 +531,14 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest) X509 *x509; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); GetX509(self, x509); - if (!X509_sign(x509, pkey, md)) { - ossl_raise(eX509CertError, NULL); - } + if (!X509_sign(x509, pkey, md)) + ossl_raise(eX509CertError, "X509_sign"); return self; } @@ -566,12 +561,12 @@ ossl_x509_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_verify(x509, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } } @@ -592,8 +587,8 @@ ossl_x509_check_private_key(VALUE self, VALUE key) pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ GetX509(self, x509); if (!X509_check_private_key(x509, pkey)) { - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; } return Qtrue; @@ -613,13 +608,10 @@ ossl_x509_get_extensions(VALUE self) GetX509(self, x509); count = X509_get_ext_count(x509); - if (count < 0) { - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -639,16 +631,16 @@ ossl_x509_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary's members should be X509Extension */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509(self, x509); - while ((ext = X509_delete_ext(x509, 0))) - X509_EXTENSION_free(ext); + for (i = X509_get_ext_count(x509); i > 0; i--) + X509_EXTENSION_free(X509_delete_ext(x509, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); - if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */ - ossl_raise(eX509CertError, NULL); - } + ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); + if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */ + ossl_raise(eX509CertError, "X509_add_ext"); + } } return ary; @@ -667,32 +659,24 @@ ossl_x509_add_extension(VALUE self, VALUE extension) GetX509(self, x509); ext = GetX509ExtPtr(extension); if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return extension; } -static VALUE -ossl_x509_inspect(VALUE self) -{ - return rb_sprintf("#<%"PRIsVALUE": subject=%+"PRIsVALUE", " - "issuer=%+"PRIsVALUE", serial=%+"PRIsVALUE", " - "not_before=%+"PRIsVALUE", not_after=%+"PRIsVALUE">", - rb_obj_class(self), - ossl_x509_get_subject(self), - ossl_x509_get_issuer(self), - ossl_x509_get_serial(self), - ossl_x509_get_not_before(self), - ossl_x509_get_not_after(self)); -} - /* * call-seq: * cert1 == cert2 -> true | false * * Compares the two certificates. Note that this takes into account all fields, * not just the issuer name and the serial number. + * + * This method uses X509_cmp() from OpenSSL, which compares certificates based + * on their cached DER encodings. The comparison can be unreliable if a + * certificate is incomplete. + * + * See also the man page X509_cmp(3). */ static VALUE ossl_x509_eq(VALUE self, VALUE other) @@ -701,12 +685,42 @@ ossl_x509_eq(VALUE self, VALUE other) GetX509(self, a); if (!rb_obj_is_kind_of(other, cX509Cert)) - return Qfalse; + return Qfalse; GetX509(other, b); return !X509_cmp(a, b) ? Qtrue : Qfalse; } +/* + * call-seq: + * cert.tbs_bytes => string + * + * Returns the DER-encoded bytes of the certificate's to be signed certificate. + * This is mainly useful for validating embedded certificate transparency signatures. + */ +static VALUE +ossl_x509_tbs_bytes(VALUE self) +{ + X509 *x509; + int len; + unsigned char *p0; + VALUE str; + + GetX509(self, x509); + len = i2d_re_X509_tbs(x509, NULL); + if (len <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + str = rb_str_new(NULL, len); + p0 = (unsigned char *)RSTRING_PTR(str); + if (i2d_re_X509_tbs(x509, &p0) <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + ossl_str_adjust(str, p0); + + return str; +} + struct load_chained_certificates_arguments { VALUE certificates; X509 *certificate; @@ -766,7 +780,7 @@ load_chained_certificates_PEM(BIO *in) { certificates = load_chained_certificates_append(Qnil, certificate); while ((certificate = PEM_read_bio_X509(in, NULL, NULL, NULL))) { - load_chained_certificates_append(certificates, certificate); + load_chained_certificates_append(certificates, certificate); } /* We tried to read one more certificate but could not read start line: */ @@ -864,12 +878,6 @@ ossl_x509_load(VALUE klass, VALUE buffer) void Init_ossl_x509cert(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); /* Document-class: OpenSSL::X509::Certificate @@ -997,6 +1005,6 @@ Init_ossl_x509cert(void) rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0); rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1); rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1); - rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0); rb_define_method(cX509Cert, "==", ossl_x509_eq, 1); + rb_define_method(cX509Cert, "tbs_bytes", ossl_x509_tbs_bytes, 0); } diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index 863f0286c0..a221429c34 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,22 +13,22 @@ TypedData_Wrap_Struct((klass), &ossl_x509crl_type, 0) #define SetX509CRL(obj, crl) do { \ if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (crl); \ } while (0) #define GetX509CRL(obj, crl) do { \ TypedData_Get_Struct((obj), X509_CRL, &ossl_x509crl_type, (crl)); \ if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cX509CRL; -VALUE eX509CRLError; +static VALUE cX509CRL; +static VALUE eX509CRLError; static void ossl_x509crl_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509crl_free(void *ptr) static const rb_data_type_t ossl_x509crl_type = { "OpenSSL/X509/CRL", { - 0, ossl_x509crl_free, + 0, ossl_x509crl_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -64,8 +64,9 @@ ossl_x509crl_new(X509_CRL *crl) VALUE obj; obj = NewX509CRL(cX509CRL); - tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new(); - if(!tmp) ossl_raise(eX509CRLError, NULL); + tmp = X509_CRL_dup(crl); + if (!tmp) + ossl_raise(eX509CRLError, "X509_CRL_dup"); SetX509CRL(obj, tmp); return obj; @@ -82,7 +83,7 @@ ossl_x509crl_alloc(VALUE klass) obj = NewX509CRL(klass); if (!(crl = X509_CRL_new())) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } SetX509CRL(obj, crl); @@ -98,7 +99,7 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); @@ -117,6 +118,7 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509crl_copy(VALUE self, VALUE other) { @@ -127,7 +129,7 @@ ossl_x509crl_copy(VALUE self, VALUE other) GetX509CRL(self, a); GetX509CRL(other, b); if (!(crl = X509_CRL_dup(b))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } X509_CRL_free(a); DATA_PTR(self) = crl; @@ -154,34 +156,36 @@ ossl_x509crl_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CRLError, "version must be >= 0!"); + ossl_raise(eX509CRLError, "version must be >= 0!"); } GetX509CRL(self, crl); if (!X509_CRL_set_version(crl, ver)) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return version; } +/* + * call-seq: + * crl.signature_algorithm -> string + * + * Returns the signature algorithm used to sign this CRL. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. + */ static VALUE ossl_x509crl_get_signature_algorithm(VALUE self) { X509_CRL *crl; const X509_ALGOR *alg; - BIO *out; + const ASN1_OBJECT *obj; GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } X509_CRL_get0_signature(crl, NULL, &alg); - if (!i2a_ASN1_OBJECT(out, alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - - return ossl_membio2str(out); + X509_ALGOR_get0(&obj, NULL, NULL, alg); + return ossl_asn1obj_to_string_long_name(obj); } static VALUE @@ -202,7 +206,7 @@ ossl_x509crl_set_issuer(VALUE self, VALUE issuer) GetX509CRL(self, crl); if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return issuer; } @@ -216,7 +220,7 @@ ossl_x509crl_get_last_update(VALUE self) GetX509CRL(self, crl); time = X509_CRL_get0_lastUpdate(crl); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -230,8 +234,8 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time) GetX509CRL(self, crl); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_CRL_set1_lastUpdate(crl, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate"); } ASN1_TIME_free(asn1time); @@ -247,7 +251,7 @@ ossl_x509crl_get_next_update(VALUE self) GetX509CRL(self, crl); time = X509_CRL_get0_nextUpdate(crl); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -261,8 +265,8 @@ ossl_x509crl_set_next_update(VALUE self, VALUE time) GetX509CRL(self, crl); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_CRL_set1_nextUpdate(crl, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate"); } ASN1_TIME_free(asn1time); @@ -274,21 +278,19 @@ ossl_x509crl_get_revoked(VALUE self) { X509_CRL *crl; int i, num; - X509_REVOKED *rev; - VALUE ary, revoked; + STACK_OF(X509_REVOKED) *sk; + VALUE ary; GetX509CRL(self, crl); - num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); - if (num < 0) { - OSSL_Debug("num < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(num); + sk = X509_CRL_get_REVOKED(crl); + if (!sk) + return rb_ary_new(); + + num = sk_X509_REVOKED_num(sk); + ary = rb_ary_new_capa(num); for(i=0; i<num; i++) { - /* NO DUP - don't free! */ - rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); - revoked = ossl_x509revoked_new(rev); - rb_ary_push(ary, revoked); + X509_REVOKED *rev = sk_X509_REVOKED_value(sk, i); + rb_ary_push(ary, ossl_x509revoked_new(rev)); } return ary; @@ -305,19 +307,19 @@ ossl_x509crl_set_revoked(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary members should be X509 Revoked */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev); } GetX509CRL(self, crl); if ((sk = X509_CRL_get_REVOKED(crl))) { - while ((rev = sk_X509_REVOKED_pop(sk))) - X509_REVOKED_free(rev); + while ((rev = sk_X509_REVOKED_pop(sk))) + X509_REVOKED_free(rev); } for (i=0; i<RARRAY_LEN(ary); i++) { - rev = DupX509RevokedPtr(RARRAY_AREF(ary, i)); - if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - X509_REVOKED_free(rev); - ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); - } + rev = DupX509RevokedPtr(RARRAY_AREF(ary, i)); + if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ + X509_REVOKED_free(rev); + ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); + } } X509_CRL_sort(crl); @@ -333,8 +335,8 @@ ossl_x509crl_add_revoked(VALUE self, VALUE revoked) GetX509CRL(self, crl); rev = DupX509RevokedPtr(revoked); if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - X509_REVOKED_free(rev); - ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); + X509_REVOKED_free(rev); + ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); } X509_CRL_sort(crl); @@ -347,13 +349,14 @@ ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest) X509_CRL *crl; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; GetX509CRL(self, crl); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); - if (!X509_CRL_sign(crl, pkey, md)) { - ossl_raise(eX509CRLError, NULL); - } + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); + if (!X509_CRL_sign(crl, pkey, md)) + ossl_raise(eX509CRLError, "X509_CRL_sign"); return self; } @@ -369,12 +372,12 @@ ossl_x509crl_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_CRL_verify(crl, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } } @@ -386,11 +389,11 @@ ossl_x509crl_to_der(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!i2d_X509_CRL_bio(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -404,11 +407,11 @@ ossl_x509crl_to_pem(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!PEM_write_bio_X509_CRL(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -422,11 +425,11 @@ ossl_x509crl_to_text(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!X509_CRL_print(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -445,14 +448,10 @@ ossl_x509crl_get_extensions(VALUE self) GetX509CRL(self, crl); count = X509_CRL_get_ext_count(crl); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */ + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -471,16 +470,16 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary members should be X509 Extensions */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509CRL(self, crl); - while ((ext = X509_CRL_delete_ext(crl, 0))) - X509_EXTENSION_free(ext); + for (i = X509_CRL_get_ext_count(crl); i > 0; i--) + X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */ - if (!X509_CRL_add_ext(crl, ext, -1)) { - ossl_raise(eX509CRLError, NULL); - } + ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */ + if (!X509_CRL_add_ext(crl, ext, -1)) { + ossl_raise(eX509CRLError, "X509_CRL_add_ext"); + } } return ary; @@ -495,7 +494,7 @@ ossl_x509crl_add_extension(VALUE self, VALUE extension) GetX509CRL(self, crl); ext = GetX509ExtPtr(extension); if (!X509_CRL_add_ext(crl, ext, -1)) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return extension; @@ -507,12 +506,6 @@ ossl_x509crl_add_extension(VALUE self, VALUE extension) void Init_ossl_x509crl(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError); cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject); diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index e54102c771..ef66ecc3fe 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509ext_type, 0) #define SetX509Ext(obj, ext) do { \ if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (ext); \ } while (0) #define GetX509Ext(obj, ext) do { \ TypedData_Get_Struct((obj), X509_EXTENSION, &ossl_x509ext_type, (ext)); \ if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ } while (0) #define MakeX509ExtFactory(klass, obj, ctx) do { \ @@ -33,7 +33,7 @@ #define GetX509ExtFactory(obj, ctx) do { \ TypedData_Get_Struct((obj), X509V3_CTX, &ossl_x509extfactory_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ } \ } while (0) @@ -41,8 +41,8 @@ * Classes */ VALUE cX509Ext; -VALUE cX509ExtFactory; -VALUE eX509ExtError; +static VALUE cX509ExtFactory; +static VALUE eX509ExtError; static void ossl_x509ext_free(void *ptr) @@ -53,9 +53,9 @@ ossl_x509ext_free(void *ptr) static const rb_data_type_t ossl_x509ext_type = { "OpenSSL/X509/EXTENSION", { - 0, ossl_x509ext_free, + 0, ossl_x509ext_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -68,14 +68,9 @@ ossl_x509ext_new(X509_EXTENSION *ext) VALUE obj; obj = NewX509Ext(cX509Ext); - if (!ext) { - new = X509_EXTENSION_new(); - } else { - new = X509_EXTENSION_dup(ext); - } - if (!new) { - ossl_raise(eX509ExtError, NULL); - } + new = X509_EXTENSION_dup(ext); + if (!new) + ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); SetX509Ext(obj, new); return obj; @@ -106,9 +101,9 @@ ossl_x509extfactory_free(void *ctx) static const rb_data_type_t ossl_x509extfactory_type = { "OpenSSL/X509/EXTENSION/Factory", { - 0, ossl_x509extfactory_free, + 0, ossl_x509extfactory_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -180,15 +175,15 @@ ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self) /*GetX509ExtFactory(self, ctx);*/ rb_scan_args(argc, argv, "04", - &issuer_cert, &subject_cert, &subject_req, &crl); + &issuer_cert, &subject_cert, &subject_req, &crl); if (!NIL_P(issuer_cert)) - ossl_x509extfactory_set_issuer_cert(self, issuer_cert); + ossl_x509extfactory_set_issuer_cert(self, issuer_cert); if (!NIL_P(subject_cert)) - ossl_x509extfactory_set_subject_cert(self, subject_cert); + ossl_x509extfactory_set_subject_cert(self, subject_cert); if (!NIL_P(subject_req)) - ossl_x509extfactory_set_subject_req(self, subject_req); + ossl_x509extfactory_set_subject_req(self, subject_req); if (!NIL_P(crl)) - ossl_x509extfactory_set_crl(self, crl); + ossl_x509extfactory_set_crl(self, crl); return self; } @@ -209,15 +204,16 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) int nid; VALUE rconf; CONF *conf; + const char *oid_cstr = NULL; rb_scan_args(argc, argv, "21", &oid, &value, &critical); - StringValueCStr(oid); StringValue(value); if(NIL_P(critical)) critical = Qfalse; - nid = OBJ_ln2nid(RSTRING_PTR(oid)); - if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid)); - if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid); + oid_cstr = StringValueCStr(oid); + nid = OBJ_ln2nid(oid_cstr); + if (nid != NID_undef) + oid_cstr = OBJ_nid2sn(nid); valstr = rb_str_new2(RTEST(critical) ? "critical," : ""); rb_str_append(valstr, value); @@ -228,10 +224,11 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) rconf = rb_iv_get(self, "@config"); conf = NIL_P(rconf) ? NULL : GetConfig(rconf); X509V3_set_nconf(ctx, conf); - ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr)); + + ext = X509V3_EXT_nconf(conf, ctx, oid_cstr, RSTRING_PTR(valstr)); X509V3_set_ctx_nodb(ctx); if (!ext){ - ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); + ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); } SetX509Ext(obj, ext); @@ -249,7 +246,7 @@ ossl_x509ext_alloc(VALUE klass) obj = NewX509Ext(klass); if(!(ext = X509_EXTENSION_new())){ - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); } SetX509Ext(obj, ext); @@ -277,14 +274,14 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) GetX509Ext(self, ext); if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = ext; - if(!x) - ossl_raise(eX509ExtError, NULL); - return self; + oid = ossl_to_der_if_possible(oid); + StringValue(oid); + p = (unsigned char *)RSTRING_PTR(oid); + x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); + DATA_PTR(self) = ext; + if(!x) + ossl_raise(eX509ExtError, NULL); + return self; } rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); @@ -293,6 +290,7 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509ext_initialize_copy(VALUE self, VALUE other) { @@ -304,7 +302,7 @@ ossl_x509ext_initialize_copy(VALUE self, VALUE other) ext_new = X509_EXTENSION_dup(ext_other); if (!ext_new) - ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); + ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); SetX509Ext(self, ext_new); X509_EXTENSION_free(ext); @@ -321,10 +319,10 @@ ossl_x509ext_set_oid(VALUE self, VALUE oid) GetX509Ext(self, ext); obj = OBJ_txt2obj(StringValueCStr(oid), 0); if (!obj) - ossl_raise(eX509ExtError, "OBJ_txt2obj"); + ossl_raise(eX509ExtError, "OBJ_txt2obj"); if (!X509_EXTENSION_set_object(ext, obj)) { - ASN1_OBJECT_free(obj); - ossl_raise(eX509ExtError, "X509_EXTENSION_set_object"); + ASN1_OBJECT_free(obj); + ossl_raise(eX509ExtError, "X509_EXTENSION_set_object"); } ASN1_OBJECT_free(obj); @@ -343,8 +341,8 @@ ossl_x509ext_set_value(VALUE self, VALUE data) asn1s = X509_EXTENSION_get_data(ext); if (!ASN1_OCTET_STRING_set(asn1s, (unsigned char *)RSTRING_PTR(data), - RSTRING_LENINT(data))) { - ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set"); + RSTRING_LENINT(data))) { + ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set"); } return data; @@ -361,27 +359,20 @@ ossl_x509ext_set_critical(VALUE self, VALUE flag) return flag; } +/* + * call-seq: + * ext.oid -> string + * + * Returns the OID of the extension. Returns the short name or the dotted + * decimal notation. + */ static VALUE ossl_x509ext_get_oid(VALUE obj) { X509_EXTENSION *ext; - ASN1_OBJECT *extobj; - BIO *out; - VALUE ret; - int nid; GetX509Ext(obj, ext); - extobj = X509_EXTENSION_get_object(ext); - if ((nid = OBJ_obj2nid(extobj)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); - i2a_ASN1_OBJECT(out, extobj); - ret = ossl_membio2str(out); - } - - return ret; + return ossl_asn1obj_to_string(X509_EXTENSION_get_object(ext)); } static VALUE @@ -393,9 +384,9 @@ ossl_x509ext_get_value(VALUE obj) GetX509Ext(obj, ext); if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); if (!X509V3_EXT_print(out, ext, 0, 0)) - ASN1_STRING_print(out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); + ASN1_STRING_print(out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); ret = ossl_membio2str(out); return ret; @@ -409,9 +400,9 @@ ossl_x509ext_get_value_der(VALUE obj) GetX509Ext(obj, ext); if ((value = X509_EXTENSION_get_data(ext)) == NULL) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); - return rb_str_new((const char *)value->data, value->length); + return asn1str_to_str(value); } static VALUE @@ -433,11 +424,11 @@ ossl_x509ext_to_der(VALUE obj) GetX509Ext(obj, ext); if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_EXTENSION(ext, &p) < 0) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); ossl_str_adjust(str, p); return str; @@ -450,12 +441,6 @@ void Init_ossl_x509ext(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509ExtError = rb_define_class_under(mX509, "ExtensionError", eOSSLError); cX509ExtFactory = rb_define_class_under(mX509, "ExtensionFactory", rb_cObject); diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 1522c3d897..5b3c3f7261 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,27 +13,27 @@ TypedData_Wrap_Struct((klass), &ossl_x509name_type, 0) #define SetX509Name(obj, name) do { \ if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (name); \ } while (0) #define GetX509Name(obj, name) do { \ TypedData_Get_Struct((obj), X509_NAME, &ossl_x509name_type, (name)); \ if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ } while (0) #define OBJECT_TYPE_TEMPLATE \ - rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE")) + rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE")) #define DEFAULT_OBJECT_TYPE \ - rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE")) + rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE")) /* * Classes */ -VALUE cX509Name; -VALUE eX509NameError; +static VALUE cX509Name; +static VALUE eX509NameError; static void ossl_x509name_free(void *ptr) @@ -44,9 +44,9 @@ ossl_x509name_free(void *ptr) static const rb_data_type_t ossl_x509name_type = { "OpenSSL/X509/NAME", { - 0, ossl_x509name_free, + 0, ossl_x509name_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -59,14 +59,9 @@ ossl_x509name_new(X509_NAME *name) VALUE obj; obj = NewX509Name(cX509Name); - if (!name) { - new = X509_NAME_new(); - } else { - new = X509_NAME_dup(name); - } - if (!new) { - ossl_raise(eX509NameError, NULL); - } + new = X509_NAME_dup(name); + if (!new) + ossl_raise(eX509NameError, "X509_NAME_dup"); SetX509Name(obj, new); return obj; @@ -93,7 +88,7 @@ ossl_x509name_alloc(VALUE klass) obj = NewX509Name(klass); if (!(name = X509_NAME_new())) { - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); } SetX509Name(obj, name); @@ -150,33 +145,34 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) GetX509Name(self, name); if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) { - return self; + return self; } else { - VALUE tmp = rb_check_array_type(arg); - if (!NIL_P(tmp)) { - VALUE args; - if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; - args = rb_ary_new3(2, self, template); - rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); - } - else{ - const unsigned char *p; - VALUE str = ossl_to_der_if_possible(arg); - X509_NAME *x; - StringValue(str); - p = (unsigned char *)RSTRING_PTR(str); - x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); - DATA_PTR(self) = name; - if(!x){ - ossl_raise(eX509NameError, NULL); - } - } + VALUE tmp = rb_check_array_type(arg); + if (!NIL_P(tmp)) { + VALUE args; + if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; + args = rb_ary_new3(2, self, template); + rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); + } + else{ + const unsigned char *p; + VALUE str = ossl_to_der_if_possible(arg); + X509_NAME *x; + StringValue(str); + p = (unsigned char *)RSTRING_PTR(str); + x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); + DATA_PTR(self) = name; + if(!x){ + ossl_raise(eX509NameError, NULL); + } + } } return self; } +/* :nodoc: */ static VALUE ossl_x509name_initialize_copy(VALUE self, VALUE other) { @@ -188,7 +184,7 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other) name_new = X509_NAME_dup(name_other); if (!name_new) - ossl_raise(eX509NameError, "X509_NAME_dup"); + ossl_raise(eX509NameError, "X509_NAME_dup"); SetX509Name(self, name_new); X509_NAME_free(name); @@ -225,8 +221,8 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) int loc = -1, set = 0; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("loc"); - kwargs_ids[1] = rb_intern_const("set"); + kwargs_ids[0] = rb_intern_const("loc"); + kwargs_ids[1] = rb_intern_const("set"); } rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts); rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs); @@ -234,14 +230,14 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) StringValue(value); if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid); if (kwargs[0] != Qundef) - loc = NUM2INT(kwargs[0]); + loc = NUM2INT(kwargs[0]); if (kwargs[1] != Qundef) - set = NUM2INT(kwargs[1]); + set = NUM2INT(kwargs[1]); GetX509Name(self, name); if (!X509_NAME_add_entry_by_txt(name, oid_name, NUM2INT(type), - (unsigned char *)RSTRING_PTR(value), - RSTRING_LENINT(value), loc, set)) - ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt"); + (unsigned char *)RSTRING_PTR(value), + RSTRING_LENINT(value), loc, set)) + ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt"); return self; } @@ -254,7 +250,7 @@ ossl_x509name_to_s_old(VALUE self) GetX509Name(self, name); buf = X509_NAME_oneline(name, NULL, 0); if (!buf) - ossl_raise(eX509NameError, "X509_NAME_oneline"); + ossl_raise(eX509NameError, "X509_NAME_oneline"); return ossl_buf2str(buf, rb_long2int(strlen(buf))); } @@ -268,11 +264,11 @@ x509name_print(VALUE self, unsigned long iflag) GetX509Name(self, name); out = BIO_new(BIO_s_mem()); if (!out) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); ret = X509_NAME_print_ex(out, name, 0, iflag); if (ret < 0 || (iflag == XN_FLAG_COMPAT && ret == 0)) { - BIO_free(out); - ossl_raise(eX509NameError, "X509_NAME_print_ex"); + BIO_free(out); + ossl_raise(eX509NameError, "X509_NAME_print_ex"); } return ossl_membio2str(out); } @@ -291,7 +287,14 @@ x509name_print(VALUE self, unsigned long iflag) * * OpenSSL::X509::Name::MULTILINE * * If _format_ is omitted, the largely broken and traditional OpenSSL format - * is used. + * (<tt>X509_NAME_oneline()</tt> format) is chosen. + * + * <b>Use of this method is discouraged.</b> None of the formats other than + * OpenSSL::X509::Name::RFC2253 is standardized and may show an inconsistent + * behavior through \OpenSSL versions. + * + * It is recommended to use #to_utf8 instead, which is equivalent to calling + * <tt>name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")</tt>. */ static VALUE ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) @@ -299,9 +302,9 @@ ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) rb_check_arity(argc, 0, 1); /* name.to_s(nil) was allowed */ if (!argc || NIL_P(argv[0])) - return ossl_x509name_to_s_old(self); + return ossl_x509name_to_s_old(self); else - return x509name_print(self, NUM2ULONG(argv[0])); + return x509name_print(self, NUM2ULONG(argv[0])); } /* @@ -324,7 +327,7 @@ static VALUE ossl_x509name_inspect(VALUE self) { return rb_enc_sprintf(rb_utf8_encoding(), "#<%"PRIsVALUE" %"PRIsVALUE">", - rb_obj_class(self), ossl_x509name_to_utf8(self)); + rb_obj_class(self), ossl_x509name_to_utf8(self)); } /* @@ -338,38 +341,22 @@ static VALUE ossl_x509name_to_a(VALUE self) { X509_NAME *name; - X509_NAME_ENTRY *entry; - int i,entries,nid; - char long_name[512]; - const char *short_name; - VALUE ary, vname, ret; - ASN1_STRING *value; + int entries; + VALUE ret; GetX509Name(self, name); entries = X509_NAME_entry_count(name); - if (entries < 0) { - OSSL_Debug("name entries < 0!"); - return rb_ary_new(); - } - ret = rb_ary_new2(entries); - for (i=0; i<entries; i++) { - if (!(entry = X509_NAME_get_entry(name, i))) { - ossl_raise(eX509NameError, NULL); - } - if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), - X509_NAME_ENTRY_get_object(entry))) { - ossl_raise(eX509NameError, NULL); - } - nid = OBJ_ln2nid(long_name); - if (nid == NID_undef) { - vname = rb_str_new2((const char *) &long_name); - } else { - short_name = OBJ_nid2sn(nid); - vname = rb_str_new2(short_name); /*do not free*/ - } - value = X509_NAME_ENTRY_get_data(entry); - ary = rb_ary_new3(3, vname, asn1str_to_str(value), INT2NUM(value->type)); - rb_ary_push(ret, ary); + ret = rb_ary_new_capa(entries); + for (int i = 0; i < entries; i++) { + const X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); + if (!entry) + ossl_raise(eX509NameError, "X509_NAME_get_entry"); + const ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(entry); + VALUE vname = ossl_asn1obj_to_string(obj); + const ASN1_STRING *data = X509_NAME_ENTRY_get_data(entry); + VALUE vdata = asn1str_to_str(data); + VALUE type = INT2NUM(ASN1_STRING_type(data)); + rb_ary_push(ret, rb_ary_new_from_args(3, vname, vdata, type)); } return ret; } @@ -400,7 +387,7 @@ ossl_x509name_cmp(VALUE self, VALUE other) int result; if (!rb_obj_is_kind_of(other, cX509Name)) - return Qnil; + return Qnil; result = ossl_x509name_cmp0(self, other); if (result < 0) return INT2FIX(-1); @@ -419,7 +406,7 @@ static VALUE ossl_x509name_eql(VALUE self, VALUE other) { if (!rb_obj_is_kind_of(other, cX509Name)) - return Qfalse; + return Qfalse; return ossl_x509name_cmp0(self, other) == 0 ? Qtrue : Qfalse; } @@ -479,11 +466,11 @@ ossl_x509name_to_der(VALUE self) GetX509Name(self, name); if((len = i2d_X509_NAME(name, NULL)) <= 0) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_NAME(name, &p) <= 0) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); ossl_str_adjust(str, p); return str; @@ -498,7 +485,7 @@ ossl_x509name_to_der(VALUE self) * You can create a Name by parsing a distinguished name String or by * supplying the distinguished name as an Array. * - * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example' + * name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody' * * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']] */ @@ -509,12 +496,6 @@ Init_ossl_x509name(void) #undef rb_intern VALUE utf8str, ptrstr, ia5str, hash; -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - id_aref = rb_intern("[]"); eX509NameError = rb_define_class_under(mX509, "NameError", eOSSLError); cX509Name = rb_define_class_under(mX509, "Name", rb_cObject); @@ -553,6 +534,7 @@ Init_ossl_x509name(void) rb_hash_aset(hash, rb_str_new2("DC"), ia5str); rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str); rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str); + rb_obj_freeze(hash); /* * The default object type template for name entries. diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index 6eb91e9c2f..433cc461a9 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,22 +13,22 @@ TypedData_Wrap_Struct((klass), &ossl_x509req_type, 0) #define SetX509Req(obj, req) do { \ if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (req); \ } while (0) #define GetX509Req(obj, req) do { \ TypedData_Get_Struct((obj), X509_REQ, &ossl_x509req_type, (req)); \ if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cX509Req; -VALUE eX509ReqError; +static VALUE cX509Req; +static VALUE eX509ReqError; static void ossl_x509req_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509req_free(void *ptr) static const rb_data_type_t ossl_x509req_type = { "OpenSSL/X509/REQ", { - 0, ossl_x509req_free, + 0, ossl_x509req_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -68,7 +68,7 @@ ossl_x509req_alloc(VALUE klass) obj = NewX509Req(klass); if (!(req = X509_REQ_new())) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } SetX509Req(obj, req); @@ -84,7 +84,7 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); @@ -103,6 +103,7 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509req_copy(VALUE self, VALUE other) { @@ -113,7 +114,7 @@ ossl_x509req_copy(VALUE self, VALUE other) GetX509Req(self, a); GetX509Req(other, b); if (!(req = X509_REQ_dup(b))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } X509_REQ_free(a); DATA_PTR(self) = req; @@ -129,11 +130,11 @@ ossl_x509req_to_pem(VALUE self) GetX509Req(self, req); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } if (!PEM_write_bio_X509_REQ(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); + BIO_free(out); + ossl_raise(eX509ReqError, NULL); } return ossl_membio2str(out); @@ -149,11 +150,11 @@ ossl_x509req_to_der(VALUE self) GetX509Req(self, req); if ((len = i2d_X509_REQ(req, NULL)) <= 0) - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509_REQ(req, &p) <= 0) - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); ossl_str_adjust(str, p); return str; @@ -167,11 +168,11 @@ ossl_x509req_to_text(VALUE self) GetX509Req(self, req); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } if (!X509_REQ_print(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); + BIO_free(out); + ossl_raise(eX509ReqError, NULL); } return ossl_membio2str(out); @@ -190,7 +191,7 @@ ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key) GetX509Req(self, req); ... if (!(x509 = X509_REQ_to_X509(req, d, pkey))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return ossl_x509_new(x509); @@ -216,11 +217,11 @@ ossl_x509req_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509ReqError, "version must be >= 0!"); + ossl_raise(eX509ReqError, "version must be >= 0!"); } GetX509Req(self, req); if (!X509_REQ_set_version(req, ver)) { - ossl_raise(eX509ReqError, "X509_REQ_set_version"); + ossl_raise(eX509ReqError, "X509_REQ_set_version"); } return version; @@ -234,7 +235,7 @@ ossl_x509req_get_subject(VALUE self) GetX509Req(self, req); if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */ - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return ossl_x509name_new(name); @@ -248,31 +249,32 @@ ossl_x509req_set_subject(VALUE self, VALUE subject) GetX509Req(self, req); /* DUPs name */ if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return subject; } +/* + * call-seq: + * req.signature_algorithm -> string + * + * Returns the signature algorithm used to sign this request. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. + */ static VALUE ossl_x509req_get_signature_algorithm(VALUE self) { X509_REQ *req; const X509_ALGOR *alg; - BIO *out; + const ASN1_OBJECT *obj; GetX509Req(self, req); - - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); - } X509_REQ_get0_signature(req, NULL, &alg); - if (!i2a_ASN1_OBJECT(out, alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); - } - - return ossl_membio2str(out); + X509_ALGOR_get0(&obj, NULL, NULL, alg); + return ossl_asn1obj_to_string_long_name(obj); } static VALUE @@ -283,10 +285,10 @@ ossl_x509req_get_public_key(VALUE self) GetX509Req(self, req); if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */ - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } static VALUE @@ -299,7 +301,7 @@ ossl_x509req_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!X509_REQ_set_pubkey(req, pkey)) - ossl_raise(eX509ReqError, "X509_REQ_set_pubkey"); + ossl_raise(eX509ReqError, "X509_REQ_set_pubkey"); return key; } @@ -309,13 +311,14 @@ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest) X509_REQ *req; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; GetX509Req(self, req); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); - if (!X509_REQ_sign(req, pkey, md)) { - ossl_raise(eX509ReqError, NULL); - } + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); + if (!X509_REQ_sign(req, pkey, md)) + ossl_raise(eX509ReqError, "X509_REQ_sign"); return self; } @@ -334,12 +337,12 @@ ossl_x509req_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_REQ_verify(req, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } } @@ -355,13 +358,13 @@ ossl_x509req_get_attributes(VALUE self) count = X509_REQ_get_attr_count(req); if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); + OSSL_Debug("count < 0???"); + return rb_ary_new(); } ary = rb_ary_new2(count); for (i=0; i<count; i++) { - attr = X509_REQ_get_attr(req, i); - rb_ary_push(ary, ossl_x509attr_new(attr)); + attr = X509_REQ_get_attr(req, i); + rb_ary_push(ary, ossl_x509attr_new(attr)); } return ary; @@ -377,17 +380,17 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); for (i=0;i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr); } GetX509Req(self, req); - while ((attr = X509_REQ_delete_attr(req, 0))) - X509_ATTRIBUTE_free(attr); + for (i = X509_REQ_get_attr_count(req); i > 0; i--) + X509_ATTRIBUTE_free(X509_REQ_delete_attr(req, 0)); for (i=0;i<RARRAY_LEN(ary); i++) { - item = RARRAY_AREF(ary, i); - attr = GetX509AttrPtr(item); - if (!X509_REQ_add1_attr(req, attr)) { - ossl_raise(eX509ReqError, NULL); - } + item = RARRAY_AREF(ary, i); + attr = GetX509AttrPtr(item); + if (!X509_REQ_add1_attr(req, attr)) { + ossl_raise(eX509ReqError, "X509_REQ_add1_attr"); + } } return ary; } @@ -399,7 +402,7 @@ ossl_x509req_add_attribute(VALUE self, VALUE attr) GetX509Req(self, req); if (!X509_REQ_add1_attr(req, GetX509AttrPtr(attr))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return attr; @@ -411,12 +414,6 @@ ossl_x509req_add_attribute(VALUE self, VALUE attr) void Init_ossl_x509req(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509ReqError = rb_define_class_under(mX509, "RequestError", eOSSLError); cX509Req = rb_define_class_under(mX509, "Request", rb_cObject); diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 5fe6853430..b88c390c72 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509rev_type, 0) #define SetX509Rev(obj, rev) do { \ if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (rev); \ } while (0) #define GetX509Rev(obj, rev) do { \ TypedData_Get_Struct((obj), X509_REVOKED, &ossl_x509rev_type, (rev)); \ if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Rev; -VALUE eX509RevError; +static VALUE eX509RevError; static void ossl_x509rev_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509rev_free(void *ptr) static const rb_data_type_t ossl_x509rev_type = { "OpenSSL/X509/REV", { - 0, ossl_x509rev_free, + 0, ossl_x509rev_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509revoked_new(X509_REVOKED *rev) VALUE obj; obj = NewX509Rev(cX509Rev); - if (!rev) { - new = X509_REVOKED_new(); - } else { - new = X509_REVOKED_dup(rev); - } - if (!new) { - ossl_raise(eX509RevError, NULL); - } + new = X509_REVOKED_dup(rev); + if (!new) + ossl_raise(eX509RevError, "X509_REVOKED_dup"); SetX509Rev(obj, new); return obj; @@ -74,7 +69,7 @@ DupX509RevokedPtr(VALUE obj) GetX509Rev(obj, rev); if (!(new = X509_REVOKED_dup(rev))) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } return new; @@ -91,7 +86,7 @@ ossl_x509revoked_alloc(VALUE klass) obj = NewX509Rev(klass); if (!(rev = X509_REVOKED_new())) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } SetX509Rev(obj, rev); @@ -105,6 +100,7 @@ ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509revoked_initialize_copy(VALUE self, VALUE other) { @@ -116,7 +112,7 @@ ossl_x509revoked_initialize_copy(VALUE self, VALUE other) rev_new = X509_REVOKED_dup(rev_other); if (!rev_new) - ossl_raise(eX509RevError, "X509_REVOKED_dup"); + ossl_raise(eX509RevError, "X509_REVOKED_dup"); SetX509Rev(self, rev_new); X509_REVOKED_free(rev); @@ -143,8 +139,8 @@ ossl_x509revoked_set_serial(VALUE self, VALUE num) GetX509Rev(self, rev); asn1int = num_to_asn1integer(num, NULL); if (!X509_REVOKED_set_serialNumber(rev, asn1int)) { - ASN1_INTEGER_free(asn1int); - ossl_raise(eX509RevError, "X509_REVOKED_set_serialNumber"); + ASN1_INTEGER_free(asn1int); + ossl_raise(eX509RevError, "X509_REVOKED_set_serialNumber"); } ASN1_INTEGER_free(asn1int); @@ -160,7 +156,7 @@ ossl_x509revoked_get_time(VALUE self) GetX509Rev(self, rev); time = X509_REVOKED_get0_revocationDate(rev); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -174,8 +170,8 @@ ossl_x509revoked_set_time(VALUE self, VALUE time) GetX509Rev(self, rev); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_REVOKED_set_revocationDate(rev, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509RevError, "X509_REVOKED_set_revocationDate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509RevError, "X509_REVOKED_set_revocationDate"); } ASN1_TIME_free(asn1time); @@ -194,14 +190,10 @@ ossl_x509revoked_get_extensions(VALUE self) GetX509Rev(self, rev); count = X509_REVOKED_get_ext_count(rev); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_REVOKED_get_ext(rev, i); - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_REVOKED_get_ext(rev, i); + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -220,17 +212,17 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509Rev(self, rev); - while ((ext = X509_REVOKED_delete_ext(rev, 0))) - X509_EXTENSION_free(ext); + for (i = X509_REVOKED_get_ext_count(rev); i > 0; i--) + X509_EXTENSION_free(X509_REVOKED_delete_ext(rev, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - item = RARRAY_AREF(ary, i); - ext = GetX509ExtPtr(item); - if(!X509_REVOKED_add_ext(rev, ext, -1)) { - ossl_raise(eX509RevError, NULL); - } + item = RARRAY_AREF(ary, i); + ext = GetX509ExtPtr(item); + if(!X509_REVOKED_add_ext(rev, ext, -1)) { + ossl_raise(eX509RevError, "X509_REVOKED_add_ext"); + } } return ary; @@ -243,7 +235,7 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext) GetX509Rev(self, rev); if (!X509_REVOKED_add_ext(rev, GetX509ExtPtr(ext), -1)) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } return ext; @@ -260,11 +252,11 @@ ossl_x509revoked_to_der(VALUE self) GetX509Rev(self, rev); len = i2d_X509_REVOKED(rev, NULL); if (len <= 0) - ossl_raise(eX509RevError, "i2d_X509_REVOKED"); + ossl_raise(eX509RevError, "i2d_X509_REVOKED"); str = rb_str_new(NULL, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509_REVOKED(rev, &p) <= 0) - ossl_raise(eX509RevError, "i2d_X509_REVOKED"); + ossl_raise(eX509RevError, "i2d_X509_REVOKED"); ossl_str_adjust(str, p); return str; } @@ -275,12 +267,6 @@ ossl_x509revoked_to_der(VALUE self) void Init_ossl_x509revoked(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509RevError = rb_define_class_under(mX509, "RevokedError", eOSSLError); cX509Rev = rb_define_class_under(mX509, "Revoked", rb_cObject); diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index 7c546187c3..be1458cec5 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509store_type, 0) #define SetX509Store(obj, st) do { \ if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (st); \ } while (0) #define GetX509Store(obj, st) do { \ TypedData_Get_Struct((obj), X509_STORE, &ossl_x509store_type, (st)); \ if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ } while (0) @@ -28,14 +28,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, 0) #define SetX509StCtx(obj, ctx) do { \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (ctx); \ } while (0) #define GetX509StCtx(obj, ctx) do { \ TypedData_Get_Struct((obj), X509_STORE_CTX, &ossl_x509stctx_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ + ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ } \ } while (0) @@ -62,7 +62,7 @@ call_verify_cb_proc(VALUE arg) { struct ossl_verify_cb_args *args = (struct ossl_verify_cb_args *)arg; return rb_funcall(args->proc, rb_intern("call"), 2, - args->preverify_ok, args->store_ctx); + args->preverify_ok, args->store_ctx); } int @@ -73,33 +73,33 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) int state; if (NIL_P(proc)) - return ok; + return ok; ret = Qfalse; rctx = rb_protect(ossl_x509stctx_new_i, (VALUE)ctx, &state); if (state) { - rb_set_errinfo(Qnil); - rb_warn("StoreContext initialization failure"); + rb_set_errinfo(Qnil); + rb_warn("StoreContext initialization failure"); } else { - args.proc = proc; - args.preverify_ok = ok ? Qtrue : Qfalse; - args.store_ctx = rctx; - ret = rb_protect(call_verify_cb_proc, (VALUE)&args, &state); - if (state) { - rb_set_errinfo(Qnil); - rb_warn("exception in verify_callback is ignored"); - } - RTYPEDDATA_DATA(rctx) = NULL; + args.proc = proc; + args.preverify_ok = ok ? Qtrue : Qfalse; + args.store_ctx = rctx; + ret = rb_protect(call_verify_cb_proc, (VALUE)&args, &state); + if (state) { + rb_set_errinfo(Qnil); + rb_warn("exception in verify_callback is ignored"); + } + RTYPEDDATA_DATA(rctx) = NULL; } if (ret == Qtrue) { - X509_STORE_CTX_set_error(ctx, X509_V_OK); - ok = 1; + X509_STORE_CTX_set_error(ctx, X509_V_OK); + ok = 1; } else { - if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) - X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); - ok = 0; + if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); + ok = 0; } return ok; @@ -108,14 +108,17 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) /* * Classes */ -VALUE cX509Store; -VALUE cX509StoreContext; -VALUE eX509StoreError; +static VALUE cX509Store; +static VALUE cX509StoreContext; +static VALUE eX509StoreError; static void ossl_x509store_mark(void *ptr) { X509_STORE *store = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx)); } @@ -130,7 +133,7 @@ static const rb_data_type_t ossl_x509store_type = { { ossl_x509store_mark, ossl_x509store_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -156,10 +159,10 @@ x509store_verify_cb(int ok, X509_STORE_CTX *ctx) proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx); if (!proc) - proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), - store_ex_verify_cb_idx); + proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), + store_ex_verify_cb_idx); if (!proc) - return ok; + return ok; return ossl_verify_cb_call(proc, ok, ctx); } @@ -187,8 +190,9 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb) X509_STORE *store; GetX509Store(self, store); - X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); rb_iv_set(self, "@verify_callback", cb); + X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); + RB_OBJ_WRITTEN(self, Qundef, cb); return cb; } @@ -208,10 +212,6 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) GetX509Store(self, store); if (argc != 0) rb_warn("OpenSSL::X509::Store.new does not take any arguments"); -#if !defined(HAVE_OPAQUE_OPENSSL) - /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */ - store->ex_data.sk = NULL; -#endif X509_STORE_set_verify_cb(store, x509store_verify_cb); ossl_x509store_set_vfy_cb(self, Qnil); @@ -219,7 +219,6 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) rb_iv_set(self, "@error", Qnil); rb_iv_set(self, "@error_string", Qnil); rb_iv_set(self, "@chain", Qnil); - rb_iv_set(self, "@time", Qnil); return self; } @@ -325,7 +324,12 @@ ossl_x509store_set_trust(VALUE self, VALUE trust) static VALUE ossl_x509store_set_time(VALUE self, VALUE time) { - rb_iv_set(self, "@time", time); + X509_STORE *store; + X509_VERIFY_PARAM *param; + + GetX509Store(self, store); + param = X509_STORE_get0_param(store); + X509_VERIFY_PARAM_set_time(param, NUM2LONG(rb_Integer(time))); return time; } @@ -353,15 +357,6 @@ ossl_x509store_add_file(VALUE self, VALUE file) ossl_raise(eX509StoreError, "X509_STORE_add_lookup"); if (X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1) ossl_raise(eX509StoreError, "X509_LOOKUP_load_file"); -#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER) - /* - * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file() - * did not check the return value of X509_STORE_add_{cert,crl}(), leaking - * "cert already in hash table" errors on the error queue, if duplicate - * certificates are found. This will be fixed by OpenSSL 1.1.1. - */ - ossl_clear_error(); -#endif return self; } @@ -489,7 +484,7 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &cert, &chain); ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain); proc = rb_block_given_p() ? rb_block_proc() : - rb_iv_get(self, "@verify_callback"); + rb_iv_get(self, "@verify_callback"); rb_iv_set(ctx, "@verify_callback", proc); result = rb_funcall(ctx, rb_intern("verify"), 0); @@ -507,6 +502,9 @@ static void ossl_x509stctx_mark(void *ptr) { X509_STORE_CTX *ctx = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx)); } @@ -515,9 +513,9 @@ ossl_x509stctx_free(void *ptr) { X509_STORE_CTX *ctx = ptr; if (X509_STORE_CTX_get0_untrusted(ctx)) - sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); + sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); if (X509_STORE_CTX_get0_cert(ctx)) - X509_free(X509_STORE_CTX_get0_cert(ctx)); + X509_free(X509_STORE_CTX_get0_cert(ctx)); X509_STORE_CTX_free(ctx); } @@ -526,7 +524,7 @@ static const rb_data_type_t ossl_x509stctx_type = { { ossl_x509stctx_mark, ossl_x509stctx_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -557,7 +555,6 @@ ossl_x509stctx_new(X509_STORE_CTX *ctx) static VALUE ossl_x509stctx_set_flags(VALUE, VALUE); static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE); static VALUE ossl_x509stctx_set_trust(VALUE, VALUE); -static VALUE ossl_x509stctx_set_time(VALUE, VALUE); /* * call-seq: @@ -568,7 +565,7 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE); static VALUE ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) { - VALUE store, cert, chain, t; + VALUE store, cert, chain; X509_STORE_CTX *ctx; X509_STORE *x509st; X509 *x509 = NULL; @@ -592,8 +589,6 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) sk_X509_pop_free(x509s, X509_free); ossl_raise(eX509StoreError, "X509_STORE_CTX_init"); } - if (!NIL_P(t = rb_iv_get(store, "@time"))) - ossl_x509stctx_set_time(self, t); rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback")); rb_iv_set(self, "@cert", cert); @@ -614,8 +609,9 @@ ossl_x509stctx_verify(VALUE self) X509_STORE_CTX *ctx; GetX509StCtx(self, ctx); - X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, - (void *)rb_iv_get(self, "@verify_callback")); + VALUE cb = rb_iv_get(self, "@verify_callback"); + X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, (void *)cb); + RB_OBJ_WRITTEN(self, Qundef, cb); switch (X509_verify_cert(ctx)) { case 1: @@ -624,7 +620,7 @@ ossl_x509stctx_verify(VALUE self) ossl_clear_error(); return Qfalse; default: - ossl_raise(eX509CertError, "X509_verify_cert"); + ossl_raise(eX509StoreError, "X509_verify_cert"); } } @@ -740,10 +736,14 @@ static VALUE ossl_x509stctx_get_curr_cert(VALUE self) { X509_STORE_CTX *ctx; + X509 *x509; GetX509StCtx(self, ctx); + x509 = X509_STORE_CTX_get_current_cert(ctx); + if (!x509) + return Qnil; - return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); + return ossl_x509_new(x509); } /* @@ -763,7 +763,7 @@ ossl_x509stctx_get_curr_crl(VALUE self) GetX509StCtx(self, ctx); crl = X509_STORE_CTX_get0_current_crl(ctx); if (!crl) - return Qnil; + return Qnil; return ossl_x509crl_new(crl); } @@ -859,19 +859,13 @@ void Init_ossl_x509store(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - /* Register ext_data slot for verify callback Proc */ stctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"stctx_ex_verify_cb_idx", 0, 0, 0); if (stctx_ex_verify_cb_idx < 0) - ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index"); + ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index"); store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"store_ex_verify_cb_idx", 0, 0, 0); if (store_ex_verify_cb_idx < 0) - ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index"); + ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index"); eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError); diff --git a/ext/pathname/depend b/ext/pathname/depend deleted file mode 100644 index 0860334b7f..0000000000 --- a/ext/pathname/depend +++ /dev/null @@ -1,174 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -pathname.o: $(RUBY_EXTCONF_H) -pathname.o: $(arch_hdrdir)/ruby/config.h -pathname.o: $(hdrdir)/ruby.h -pathname.o: $(hdrdir)/ruby/assert.h -pathname.o: $(hdrdir)/ruby/backward.h -pathname.o: $(hdrdir)/ruby/backward/2/assume.h -pathname.o: $(hdrdir)/ruby/backward/2/attributes.h -pathname.o: $(hdrdir)/ruby/backward/2/bool.h -pathname.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -pathname.o: $(hdrdir)/ruby/backward/2/inttypes.h -pathname.o: $(hdrdir)/ruby/backward/2/limits.h -pathname.o: $(hdrdir)/ruby/backward/2/long_long.h -pathname.o: $(hdrdir)/ruby/backward/2/stdalign.h -pathname.o: $(hdrdir)/ruby/backward/2/stdarg.h -pathname.o: $(hdrdir)/ruby/defines.h -pathname.o: $(hdrdir)/ruby/encoding.h -pathname.o: $(hdrdir)/ruby/intern.h -pathname.o: $(hdrdir)/ruby/internal/anyargs.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/char.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/double.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/int.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/long.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/short.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -pathname.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -pathname.o: $(hdrdir)/ruby/internal/assume.h -pathname.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -pathname.o: $(hdrdir)/ruby/internal/attr/artificial.h -pathname.o: $(hdrdir)/ruby/internal/attr/cold.h -pathname.o: $(hdrdir)/ruby/internal/attr/const.h -pathname.o: $(hdrdir)/ruby/internal/attr/constexpr.h -pathname.o: $(hdrdir)/ruby/internal/attr/deprecated.h -pathname.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -pathname.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -pathname.o: $(hdrdir)/ruby/internal/attr/error.h -pathname.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -pathname.o: $(hdrdir)/ruby/internal/attr/forceinline.h -pathname.o: $(hdrdir)/ruby/internal/attr/format.h -pathname.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -pathname.o: $(hdrdir)/ruby/internal/attr/noalias.h -pathname.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -pathname.o: $(hdrdir)/ruby/internal/attr/noexcept.h -pathname.o: $(hdrdir)/ruby/internal/attr/noinline.h -pathname.o: $(hdrdir)/ruby/internal/attr/nonnull.h -pathname.o: $(hdrdir)/ruby/internal/attr/noreturn.h -pathname.o: $(hdrdir)/ruby/internal/attr/pure.h -pathname.o: $(hdrdir)/ruby/internal/attr/restrict.h -pathname.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -pathname.o: $(hdrdir)/ruby/internal/attr/warning.h -pathname.o: $(hdrdir)/ruby/internal/attr/weakref.h -pathname.o: $(hdrdir)/ruby/internal/cast.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -pathname.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -pathname.o: $(hdrdir)/ruby/internal/compiler_since.h -pathname.o: $(hdrdir)/ruby/internal/config.h -pathname.o: $(hdrdir)/ruby/internal/constant_p.h -pathname.o: $(hdrdir)/ruby/internal/core.h -pathname.o: $(hdrdir)/ruby/internal/core/rarray.h -pathname.o: $(hdrdir)/ruby/internal/core/rbasic.h -pathname.o: $(hdrdir)/ruby/internal/core/rbignum.h -pathname.o: $(hdrdir)/ruby/internal/core/rclass.h -pathname.o: $(hdrdir)/ruby/internal/core/rdata.h -pathname.o: $(hdrdir)/ruby/internal/core/rfile.h -pathname.o: $(hdrdir)/ruby/internal/core/rhash.h -pathname.o: $(hdrdir)/ruby/internal/core/robject.h -pathname.o: $(hdrdir)/ruby/internal/core/rregexp.h -pathname.o: $(hdrdir)/ruby/internal/core/rstring.h -pathname.o: $(hdrdir)/ruby/internal/core/rstruct.h -pathname.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -pathname.o: $(hdrdir)/ruby/internal/ctype.h -pathname.o: $(hdrdir)/ruby/internal/dllexport.h -pathname.o: $(hdrdir)/ruby/internal/dosish.h -pathname.o: $(hdrdir)/ruby/internal/encoding/coderange.h -pathname.o: $(hdrdir)/ruby/internal/encoding/ctype.h -pathname.o: $(hdrdir)/ruby/internal/encoding/encoding.h -pathname.o: $(hdrdir)/ruby/internal/encoding/pathname.h -pathname.o: $(hdrdir)/ruby/internal/encoding/re.h -pathname.o: $(hdrdir)/ruby/internal/encoding/sprintf.h -pathname.o: $(hdrdir)/ruby/internal/encoding/string.h -pathname.o: $(hdrdir)/ruby/internal/encoding/symbol.h -pathname.o: $(hdrdir)/ruby/internal/encoding/transcode.h -pathname.o: $(hdrdir)/ruby/internal/error.h -pathname.o: $(hdrdir)/ruby/internal/eval.h -pathname.o: $(hdrdir)/ruby/internal/event.h -pathname.o: $(hdrdir)/ruby/internal/fl_type.h -pathname.o: $(hdrdir)/ruby/internal/gc.h -pathname.o: $(hdrdir)/ruby/internal/glob.h -pathname.o: $(hdrdir)/ruby/internal/globals.h -pathname.o: $(hdrdir)/ruby/internal/has/attribute.h -pathname.o: $(hdrdir)/ruby/internal/has/builtin.h -pathname.o: $(hdrdir)/ruby/internal/has/c_attribute.h -pathname.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -pathname.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -pathname.o: $(hdrdir)/ruby/internal/has/extension.h -pathname.o: $(hdrdir)/ruby/internal/has/feature.h -pathname.o: $(hdrdir)/ruby/internal/has/warning.h -pathname.o: $(hdrdir)/ruby/internal/intern/array.h -pathname.o: $(hdrdir)/ruby/internal/intern/bignum.h -pathname.o: $(hdrdir)/ruby/internal/intern/class.h -pathname.o: $(hdrdir)/ruby/internal/intern/compar.h -pathname.o: $(hdrdir)/ruby/internal/intern/complex.h -pathname.o: $(hdrdir)/ruby/internal/intern/cont.h -pathname.o: $(hdrdir)/ruby/internal/intern/dir.h -pathname.o: $(hdrdir)/ruby/internal/intern/enum.h -pathname.o: $(hdrdir)/ruby/internal/intern/enumerator.h -pathname.o: $(hdrdir)/ruby/internal/intern/error.h -pathname.o: $(hdrdir)/ruby/internal/intern/eval.h -pathname.o: $(hdrdir)/ruby/internal/intern/file.h -pathname.o: $(hdrdir)/ruby/internal/intern/gc.h -pathname.o: $(hdrdir)/ruby/internal/intern/hash.h -pathname.o: $(hdrdir)/ruby/internal/intern/io.h -pathname.o: $(hdrdir)/ruby/internal/intern/load.h -pathname.o: $(hdrdir)/ruby/internal/intern/marshal.h -pathname.o: $(hdrdir)/ruby/internal/intern/numeric.h -pathname.o: $(hdrdir)/ruby/internal/intern/object.h -pathname.o: $(hdrdir)/ruby/internal/intern/parse.h -pathname.o: $(hdrdir)/ruby/internal/intern/proc.h -pathname.o: $(hdrdir)/ruby/internal/intern/process.h -pathname.o: $(hdrdir)/ruby/internal/intern/random.h -pathname.o: $(hdrdir)/ruby/internal/intern/range.h -pathname.o: $(hdrdir)/ruby/internal/intern/rational.h -pathname.o: $(hdrdir)/ruby/internal/intern/re.h -pathname.o: $(hdrdir)/ruby/internal/intern/ruby.h -pathname.o: $(hdrdir)/ruby/internal/intern/select.h -pathname.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -pathname.o: $(hdrdir)/ruby/internal/intern/signal.h -pathname.o: $(hdrdir)/ruby/internal/intern/sprintf.h -pathname.o: $(hdrdir)/ruby/internal/intern/string.h -pathname.o: $(hdrdir)/ruby/internal/intern/struct.h -pathname.o: $(hdrdir)/ruby/internal/intern/thread.h -pathname.o: $(hdrdir)/ruby/internal/intern/time.h -pathname.o: $(hdrdir)/ruby/internal/intern/variable.h -pathname.o: $(hdrdir)/ruby/internal/intern/vm.h -pathname.o: $(hdrdir)/ruby/internal/interpreter.h -pathname.o: $(hdrdir)/ruby/internal/iterator.h -pathname.o: $(hdrdir)/ruby/internal/memory.h -pathname.o: $(hdrdir)/ruby/internal/method.h -pathname.o: $(hdrdir)/ruby/internal/module.h -pathname.o: $(hdrdir)/ruby/internal/newobj.h -pathname.o: $(hdrdir)/ruby/internal/rgengc.h -pathname.o: $(hdrdir)/ruby/internal/scan_args.h -pathname.o: $(hdrdir)/ruby/internal/special_consts.h -pathname.o: $(hdrdir)/ruby/internal/static_assert.h -pathname.o: $(hdrdir)/ruby/internal/stdalign.h -pathname.o: $(hdrdir)/ruby/internal/stdbool.h -pathname.o: $(hdrdir)/ruby/internal/symbol.h -pathname.o: $(hdrdir)/ruby/internal/value.h -pathname.o: $(hdrdir)/ruby/internal/value_type.h -pathname.o: $(hdrdir)/ruby/internal/variable.h -pathname.o: $(hdrdir)/ruby/internal/warning_push.h -pathname.o: $(hdrdir)/ruby/internal/xmalloc.h -pathname.o: $(hdrdir)/ruby/missing.h -pathname.o: $(hdrdir)/ruby/onigmo.h -pathname.o: $(hdrdir)/ruby/oniguruma.h -pathname.o: $(hdrdir)/ruby/ruby.h -pathname.o: $(hdrdir)/ruby/st.h -pathname.o: $(hdrdir)/ruby/subst.h -pathname.o: pathname.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/pathname/extconf.rb b/ext/pathname/extconf.rb deleted file mode 100644 index 84e68277aa..0000000000 --- a/ext/pathname/extconf.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: false -require 'mkmf' -have_func("rb_file_s_birthtime") -create_makefile('pathname') diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb deleted file mode 100644 index 3799d589d5..0000000000 --- a/ext/pathname/lib/pathname.rb +++ /dev/null @@ -1,599 +0,0 @@ -# frozen_string_literal: true -# -# = pathname.rb -# -# Object-Oriented Pathname Class -# -# Author:: Tanaka Akira <akr@m17n.org> -# Documentation:: Author and Gavin Sinclair -# -# For documentation, see class Pathname. -# - -require 'pathname.so' - -class Pathname - - # :stopdoc: - - # to_path is implemented so Pathname objects are usable with File.open, etc. - TO_PATH = :to_path - - SAME_PATHS = if File::FNM_SYSCASE.nonzero? - # Avoid #zero? here because #casecmp can return nil. - proc {|a, b| a.casecmp(b) == 0} - else - proc {|a, b| a == b} - end - - - if File::ALT_SEPARATOR - SEPARATOR_LIST = "#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}" - SEPARATOR_PAT = /[#{SEPARATOR_LIST}]/ - else - SEPARATOR_LIST = "#{Regexp.quote File::SEPARATOR}" - SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/ - end - - if File.dirname('A:') == 'A:.' # DOSish drive letter - ABSOLUTE_PATH = /\A(?:[A-Za-z]:|#{SEPARATOR_PAT})/o - else - ABSOLUTE_PATH = /\A#{SEPARATOR_PAT}/o - end - private_constant :ABSOLUTE_PATH - - # :startdoc: - - # chop_basename(path) -> [pre-basename, basename] or nil - def chop_basename(path) # :nodoc: - base = File.basename(path) - if /\A#{SEPARATOR_PAT}?\z/o.match?(base) - return nil - else - return path[0, path.rindex(base)], base - end - end - private :chop_basename - - # split_names(path) -> prefix, [name, ...] - def split_names(path) # :nodoc: - names = [] - while r = chop_basename(path) - path, basename = r - names.unshift basename - end - return path, names - end - private :split_names - - def prepend_prefix(prefix, relpath) # :nodoc: - if relpath.empty? - File.dirname(prefix) - elsif /#{SEPARATOR_PAT}/o.match?(prefix) - prefix = File.dirname(prefix) - prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a' - prefix + relpath - else - prefix + relpath - end - end - private :prepend_prefix - - # Returns clean pathname of +self+ with consecutive slashes and useless dots - # removed. The filesystem is not accessed. - # - # If +consider_symlink+ is +true+, then a more conservative algorithm is used - # to avoid breaking symbolic linkages. This may retain more +..+ - # entries than absolutely necessary, but without accessing the filesystem, - # this can't be avoided. - # - # See Pathname#realpath. - # - def cleanpath(consider_symlink=false) - if consider_symlink - cleanpath_conservative - else - cleanpath_aggressive - end - end - - # - # Clean the path simply by resolving and removing excess +.+ and +..+ entries. - # Nothing more, nothing less. - # - def cleanpath_aggressive # :nodoc: - path = @path - names = [] - pre = path - while r = chop_basename(pre) - pre, base = r - case base - when '.' - when '..' - names.unshift base - else - if names[0] == '..' - names.shift - else - names.unshift base - end - end - end - pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR - if /#{SEPARATOR_PAT}/o.match?(File.basename(pre)) - names.shift while names[0] == '..' - end - self.class.new(prepend_prefix(pre, File.join(*names))) - end - private :cleanpath_aggressive - - # has_trailing_separator?(path) -> bool - def has_trailing_separator?(path) # :nodoc: - if r = chop_basename(path) - pre, basename = r - pre.length + basename.length < path.length - else - false - end - end - private :has_trailing_separator? - - # add_trailing_separator(path) -> path - def add_trailing_separator(path) # :nodoc: - if File.basename(path + 'a') == 'a' - path - else - File.join(path, "") # xxx: Is File.join is appropriate to add separator? - end - end - private :add_trailing_separator - - def del_trailing_separator(path) # :nodoc: - if r = chop_basename(path) - pre, basename = r - pre + basename - elsif /#{SEPARATOR_PAT}+\z/o =~ path - $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o] - else - path - end - end - private :del_trailing_separator - - def cleanpath_conservative # :nodoc: - path = @path - names = [] - pre = path - while r = chop_basename(pre) - pre, base = r - names.unshift base if base != '.' - end - pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR - if /#{SEPARATOR_PAT}/o.match?(File.basename(pre)) - names.shift while names[0] == '..' - end - if names.empty? - self.class.new(File.dirname(pre)) - else - if names.last != '..' && File.basename(path) == '.' - names << '.' - end - result = prepend_prefix(pre, File.join(*names)) - if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path) - self.class.new(add_trailing_separator(result)) - else - self.class.new(result) - end - end - end - private :cleanpath_conservative - - # Returns the parent directory. - # - # This is same as <code>self + '..'</code>. - def parent - self + '..' - end - - # Returns +true+ if +self+ points to a mountpoint. - def mountpoint? - begin - stat1 = self.lstat - stat2 = self.parent.lstat - stat1.dev != stat2.dev || stat1.ino == stat2.ino - rescue Errno::ENOENT - false - end - end - - # - # Predicate method for root directories. Returns +true+ if the - # pathname consists of consecutive slashes. - # - # It doesn't access the filesystem. So it may return +false+ for some - # pathnames which points to roots such as <tt>/usr/..</tt>. - # - def root? - chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o.match?(@path) - end - - # Predicate method for testing whether a path is absolute. - # - # It returns +true+ if the pathname begins with a slash. - # - # p = Pathname.new('/im/sure') - # p.absolute? - # #=> true - # - # p = Pathname.new('not/so/sure') - # p.absolute? - # #=> false - def absolute? - ABSOLUTE_PATH.match? @path - end - - # The opposite of Pathname#absolute? - # - # It returns +false+ if the pathname begins with a slash. - # - # p = Pathname.new('/im/sure') - # p.relative? - # #=> false - # - # p = Pathname.new('not/so/sure') - # p.relative? - # #=> true - def relative? - !absolute? - end - - # - # Iterates over each component of the path. - # - # Pathname.new("/usr/bin/ruby").each_filename {|filename| ... } - # # yields "usr", "bin", and "ruby". - # - # Returns an Enumerator if no block was given. - # - # enum = Pathname.new("/usr/bin/ruby").each_filename - # # ... do stuff ... - # enum.each { |e| ... } - # # yields "usr", "bin", and "ruby". - # - def each_filename # :yield: filename - return to_enum(__method__) unless block_given? - _, names = split_names(@path) - names.each {|filename| yield filename } - nil - end - - # Iterates over and yields a new Pathname object - # for each element in the given path in descending order. - # - # Pathname.new('/path/to/some/file.rb').descend {|v| p v} - # #<Pathname:/> - # #<Pathname:/path> - # #<Pathname:/path/to> - # #<Pathname:/path/to/some> - # #<Pathname:/path/to/some/file.rb> - # - # Pathname.new('path/to/some/file.rb').descend {|v| p v} - # #<Pathname:path> - # #<Pathname:path/to> - # #<Pathname:path/to/some> - # #<Pathname:path/to/some/file.rb> - # - # Returns an Enumerator if no block was given. - # - # enum = Pathname.new("/usr/bin/ruby").descend - # # ... do stuff ... - # enum.each { |e| ... } - # # yields Pathnames /, /usr, /usr/bin, and /usr/bin/ruby. - # - # It doesn't access the filesystem. - # - def descend - return to_enum(__method__) unless block_given? - vs = [] - ascend {|v| vs << v } - vs.reverse_each {|v| yield v } - nil - end - - # Iterates over and yields a new Pathname object - # for each element in the given path in ascending order. - # - # Pathname.new('/path/to/some/file.rb').ascend {|v| p v} - # #<Pathname:/path/to/some/file.rb> - # #<Pathname:/path/to/some> - # #<Pathname:/path/to> - # #<Pathname:/path> - # #<Pathname:/> - # - # Pathname.new('path/to/some/file.rb').ascend {|v| p v} - # #<Pathname:path/to/some/file.rb> - # #<Pathname:path/to/some> - # #<Pathname:path/to> - # #<Pathname:path> - # - # Returns an Enumerator if no block was given. - # - # enum = Pathname.new("/usr/bin/ruby").ascend - # # ... do stuff ... - # enum.each { |e| ... } - # # yields Pathnames /usr/bin/ruby, /usr/bin, /usr, and /. - # - # It doesn't access the filesystem. - # - def ascend - return to_enum(__method__) unless block_given? - path = @path - yield self - while r = chop_basename(path) - path, = r - break if path.empty? - yield self.class.new(del_trailing_separator(path)) - end - end - - # - # Appends a pathname fragment to +self+ to produce a new Pathname object. - # - # p1 = Pathname.new("/usr") # Pathname:/usr - # p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby - # p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd - # - # # / is aliased to +. - # p4 = p1 / "bin/ruby" # Pathname:/usr/bin/ruby - # p5 = p1 / "/etc/passwd" # Pathname:/etc/passwd - # - # This method doesn't access the file system; it is pure string manipulation. - # - def +(other) - other = Pathname.new(other) unless Pathname === other - Pathname.new(plus(@path, other.to_s)) - end - alias / + - - def plus(path1, path2) # -> path # :nodoc: - prefix2 = path2 - index_list2 = [] - basename_list2 = [] - while r2 = chop_basename(prefix2) - prefix2, basename2 = r2 - index_list2.unshift prefix2.length - basename_list2.unshift basename2 - end - return path2 if prefix2 != '' - prefix1 = path1 - while true - while !basename_list2.empty? && basename_list2.first == '.' - index_list2.shift - basename_list2.shift - end - break unless r1 = chop_basename(prefix1) - prefix1, basename1 = r1 - next if basename1 == '.' - if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..' - prefix1 = prefix1 + basename1 - break - end - index_list2.shift - basename_list2.shift - end - r1 = chop_basename(prefix1) - if !r1 && (r1 = /#{SEPARATOR_PAT}/o.match?(File.basename(prefix1))) - while !basename_list2.empty? && basename_list2.first == '..' - index_list2.shift - basename_list2.shift - end - end - if !basename_list2.empty? - suffix2 = path2[index_list2.first..-1] - r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2 - else - r1 ? prefix1 : File.dirname(prefix1) - end - end - private :plus - - # - # Joins the given pathnames onto +self+ to create a new Pathname object. - # - # path0 = Pathname.new("/usr") # Pathname:/usr - # path0 = path0.join("bin/ruby") # Pathname:/usr/bin/ruby - # # is the same as - # path1 = Pathname.new("/usr") + "bin/ruby" # Pathname:/usr/bin/ruby - # path0 == path1 - # #=> true - # - def join(*args) - return self if args.empty? - result = args.pop - result = Pathname.new(result) unless Pathname === result - return result if result.absolute? - args.reverse_each {|arg| - arg = Pathname.new(arg) unless Pathname === arg - result = arg + result - return result if result.absolute? - } - self + result - end - - # - # Returns the children of the directory (files and subdirectories, not - # recursive) as an array of Pathname objects. - # - # By default, the returned pathnames will have enough information to access - # the files. If you set +with_directory+ to +false+, then the returned - # pathnames will contain the filename only. - # - # For example: - # pn = Pathname("/usr/lib/ruby/1.8") - # pn.children - # # -> [ Pathname:/usr/lib/ruby/1.8/English.rb, - # Pathname:/usr/lib/ruby/1.8/Env.rb, - # Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ] - # pn.children(false) - # # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ] - # - # Note that the results never contain the entries +.+ and +..+ in - # the directory because they are not children. - # - def children(with_directory=true) - with_directory = false if @path == '.' - result = [] - Dir.foreach(@path) {|e| - next if e == '.' || e == '..' - if with_directory - result << self.class.new(File.join(@path, e)) - else - result << self.class.new(e) - end - } - result - end - - # Iterates over the children of the directory - # (files and subdirectories, not recursive). - # - # It yields Pathname object for each child. - # - # By default, the yielded pathnames will have enough information to access - # the files. - # - # If you set +with_directory+ to +false+, then the returned pathnames will - # contain the filename only. - # - # Pathname("/usr/local").each_child {|f| p f } - # #=> #<Pathname:/usr/local/share> - # # #<Pathname:/usr/local/bin> - # # #<Pathname:/usr/local/games> - # # #<Pathname:/usr/local/lib> - # # #<Pathname:/usr/local/include> - # # #<Pathname:/usr/local/sbin> - # # #<Pathname:/usr/local/src> - # # #<Pathname:/usr/local/man> - # - # Pathname("/usr/local").each_child(false) {|f| p f } - # #=> #<Pathname:share> - # # #<Pathname:bin> - # # #<Pathname:games> - # # #<Pathname:lib> - # # #<Pathname:include> - # # #<Pathname:sbin> - # # #<Pathname:src> - # # #<Pathname:man> - # - # Note that the results never contain the entries +.+ and +..+ in - # the directory because they are not children. - # - # See Pathname#children - # - def each_child(with_directory=true, &b) - children(with_directory).each(&b) - end - - # - # Returns a relative path from the given +base_directory+ to the receiver. - # - # If +self+ is absolute, then +base_directory+ must be absolute too. - # - # If +self+ is relative, then +base_directory+ must be relative too. - # - # This method doesn't access the filesystem. It assumes no symlinks. - # - # ArgumentError is raised when it cannot find a relative path. - # - # Note that this method does not handle situations where the case sensitivity - # of the filesystem in use differs from the operating system default. - # - def relative_path_from(base_directory) - base_directory = Pathname.new(base_directory) unless base_directory.is_a? Pathname - dest_directory = self.cleanpath.to_s - base_directory = base_directory.cleanpath.to_s - dest_prefix = dest_directory - dest_names = [] - while r = chop_basename(dest_prefix) - dest_prefix, basename = r - dest_names.unshift basename if basename != '.' - end - base_prefix = base_directory - base_names = [] - while r = chop_basename(base_prefix) - base_prefix, basename = r - base_names.unshift basename if basename != '.' - end - unless SAME_PATHS[dest_prefix, base_prefix] - raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}" - end - while !dest_names.empty? && - !base_names.empty? && - SAME_PATHS[dest_names.first, base_names.first] - dest_names.shift - base_names.shift - end - if base_names.include? '..' - raise ArgumentError, "base_directory has ..: #{base_directory.inspect}" - end - base_names.fill('..') - relpath_names = base_names + dest_names - if relpath_names.empty? - Pathname.new('.') - else - Pathname.new(File.join(*relpath_names)) - end - end -end - - -class Pathname # * Find * - # - # Iterates over the directory tree in a depth first manner, yielding a - # Pathname for each file under "this" directory. - # - # Returns an Enumerator if no block is given. - # - # Since it is implemented by the standard library module Find, Find.prune can - # be used to control the traversal. - # - # If +self+ is +.+, yielded pathnames begin with a filename in the - # current directory, not +./+. - # - # See Find.find - # - def find(ignore_error: true) # :yield: pathname - return to_enum(__method__, ignore_error: ignore_error) unless block_given? - require 'find' - if @path == '.' - Find.find(@path, ignore_error: ignore_error) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) } - else - Find.find(@path, ignore_error: ignore_error) {|f| yield self.class.new(f) } - end - end -end - - -class Pathname # * FileUtils * - autoload(:FileUtils, 'fileutils') - - # Creates a full path, including any intermediate directories that don't yet - # exist. - # - # See FileUtils.mkpath and FileUtils.mkdir_p - def mkpath(mode: nil) - FileUtils.mkpath(@path, mode: mode) - nil - end - - # Recursively deletes a directory, including all directories beneath it. - # - # See FileUtils.rm_r - def rmtree - # The name "rmtree" is borrowed from File::Path of Perl. - # File::Path provides "mkpath" and "rmtree". - FileUtils.rm_r(@path) - nil - end -end - diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c deleted file mode 100644 index 1d4ed2814b..0000000000 --- a/ext/pathname/pathname.c +++ /dev/null @@ -1,1683 +0,0 @@ -#include "ruby.h" -#include "ruby/encoding.h" - -static VALUE rb_cPathname; -static ID id_ENOTDIR; -static ID id_at_path; -static ID id_atime; -static ID id_base; -static ID id_basename; -static ID id_binread; -static ID id_binwrite; -static ID id_birthtime; -static ID id_blockdev_p; -static ID id_chardev_p; -static ID id_chmod; -static ID id_chown; -static ID id_ctime; -static ID id_directory_p; -static ID id_dirname; -static ID id_empty_p; -static ID id_entries; -static ID id_executable_p; -static ID id_executable_real_p; -static ID id_exist_p; -static ID id_expand_path; -static ID id_extname; -static ID id_file_p; -static ID id_fnmatch; -static ID id_foreach; -static ID id_ftype; -static ID id_getwd; -static ID id_glob; -static ID id_grpowned_p; -static ID id_lchmod; -static ID id_lchown; -static ID id_link; -static ID id_lstat; -static ID id_mkdir; -static ID id_mtime; -static ID id_open; -static ID id_owned_p; -static ID id_pipe_p; -static ID id_read; -static ID id_readable_p; -static ID id_readable_real_p; -static ID id_readlines; -static ID id_readlink; -static ID id_realdirpath; -static ID id_realpath; -static ID id_rename; -static ID id_rmdir; -static ID id_setgid_p; -static ID id_setuid_p; -static ID id_size; -static ID id_size_p; -static ID id_socket_p; -static ID id_split; -static ID id_stat; -static ID id_sticky_p; -static ID id_sub; -static ID id_symlink; -static ID id_symlink_p; -static ID id_sysopen; -static ID id_to_path; -static ID id_truncate; -static ID id_unlink; -static ID id_utime; -static ID id_world_readable_p; -static ID id_world_writable_p; -static ID id_writable_p; -static ID id_writable_real_p; -static ID id_write; -static ID id_zero_p; - -static VALUE -get_strpath(VALUE obj) -{ - VALUE strpath; - strpath = rb_ivar_get(obj, id_at_path); - if (!RB_TYPE_P(strpath, T_STRING)) - rb_raise(rb_eTypeError, "unexpected @path"); - return strpath; -} - -static void -set_strpath(VALUE obj, VALUE val) -{ - rb_ivar_set(obj, id_at_path, val); -} - -/* - * Create a Pathname object from the given String (or String-like object). - * If +path+ contains a NULL character (<tt>\0</tt>), an ArgumentError is raised. - */ -static VALUE -path_initialize(VALUE self, VALUE arg) -{ - VALUE str; - if (RB_TYPE_P(arg, T_STRING)) { - str = arg; - } - else { - str = rb_check_funcall(arg, id_to_path, 0, NULL); - if (str == Qundef) - str = arg; - StringValue(str); - } - if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) - rb_raise(rb_eArgError, "pathname contains null byte"); - str = rb_obj_dup(str); - - set_strpath(self, str); - return self; -} - -/* - * call-seq: - * pathname.freeze -> obj - * - * Freezes this Pathname. - * - * See Object.freeze. - */ -static VALUE -path_freeze(VALUE self) -{ - rb_call_super(0, 0); - rb_str_freeze(get_strpath(self)); - return self; -} - -/* - * call-seq: - * pathname.taint -> obj - * - * Returns pathname. This method is deprecated and will be removed in Ruby 3.2. - */ -static VALUE -path_taint(VALUE self) -{ - rb_warn("Pathname#taint is deprecated and will be removed in Ruby 3.2."); - return self; -} - -/* - * call-seq: - * pathname.untaint -> obj - * - * Returns pathname. This method is deprecated and will be removed in Ruby 3.2. - */ -static VALUE -path_untaint(VALUE self) -{ - rb_warn("Pathname#untaint is deprecated and will be removed in Ruby 3.2."); - return self; -} - -/* - * Compare this pathname with +other+. The comparison is string-based. - * Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>) - * can refer to the same file. - */ -static VALUE -path_eq(VALUE self, VALUE other) -{ - if (!rb_obj_is_kind_of(other, rb_cPathname)) - return Qfalse; - return rb_str_equal(get_strpath(self), get_strpath(other)); -} - -/* - * Provides a case-sensitive comparison operator for pathnames. - * - * Pathname.new('/usr') <=> Pathname.new('/usr/bin') - * #=> -1 - * Pathname.new('/usr/bin') <=> Pathname.new('/usr/bin') - * #=> 0 - * Pathname.new('/usr/bin') <=> Pathname.new('/USR/BIN') - * #=> 1 - * - * It will return +-1+, +0+ or +1+ depending on the value of the left argument - * relative to the right argument. Or it will return +nil+ if the arguments - * are not comparable. - */ -static VALUE -path_cmp(VALUE self, VALUE other) -{ - VALUE s1, s2; - char *p1, *p2; - char *e1, *e2; - if (!rb_obj_is_kind_of(other, rb_cPathname)) - return Qnil; - s1 = get_strpath(self); - s2 = get_strpath(other); - p1 = RSTRING_PTR(s1); - p2 = RSTRING_PTR(s2); - e1 = p1 + RSTRING_LEN(s1); - e2 = p2 + RSTRING_LEN(s2); - while (p1 < e1 && p2 < e2) { - int c1, c2; - c1 = (unsigned char)*p1++; - c2 = (unsigned char)*p2++; - if (c1 == '/') c1 = '\0'; - if (c2 == '/') c2 = '\0'; - if (c1 != c2) { - if (c1 < c2) - return INT2FIX(-1); - else - return INT2FIX(1); - } - } - if (p1 < e1) - return INT2FIX(1); - if (p2 < e2) - return INT2FIX(-1); - return INT2FIX(0); -} - -#ifndef ST2FIX -#define ST2FIX(h) LONG2FIX((long)(h)) -#endif - -/* :nodoc: */ -static VALUE -path_hash(VALUE self) -{ - return ST2FIX(rb_str_hash(get_strpath(self))); -} - -/* - * call-seq: - * pathname.to_s -> string - * pathname.to_path -> string - * - * Return the path as a String. - * - * to_path is implemented so Pathname objects are usable with File.open, etc. - */ -static VALUE -path_to_s(VALUE self) -{ - return rb_obj_dup(get_strpath(self)); -} - -/* :nodoc: */ -static VALUE -path_inspect(VALUE self) -{ - const char *c = rb_obj_classname(self); - VALUE str = get_strpath(self); - return rb_sprintf("#<%s:%"PRIsVALUE">", c, str); -} - -/* - * Return a pathname which is substituted by String#sub. - * - * path1 = Pathname.new('/usr/bin/perl') - * path1.sub('perl', 'ruby') - * #=> #<Pathname:/usr/bin/ruby> - */ -static VALUE -path_sub(int argc, VALUE *argv, VALUE self) -{ - VALUE str = get_strpath(self); - - if (rb_block_given_p()) { - str = rb_block_call(str, id_sub, argc, argv, 0, 0); - } - else { - str = rb_funcallv(str, id_sub, argc, argv); - } - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Return a pathname with +repl+ added as a suffix to the basename. - * - * If self has no extension part, +repl+ is appended. - * - * Pathname.new('/usr/bin/shutdown').sub_ext('.rb') - * #=> #<Pathname:/usr/bin/shutdown.rb> - */ -static VALUE -path_sub_ext(VALUE self, VALUE repl) -{ - VALUE str = get_strpath(self); - VALUE str2; - long extlen; - const char *ext; - const char *p; - - StringValue(repl); - p = RSTRING_PTR(str); - extlen = RSTRING_LEN(str); - ext = ruby_enc_find_extname(p, &extlen, rb_enc_get(str)); - if (ext == NULL) { - ext = p + RSTRING_LEN(str); - } - else if (extlen <= 1) { - ext += extlen; - } - str2 = rb_str_subseq(str, 0, ext-p); - rb_str_append(str2, repl); - return rb_class_new_instance(1, &str2, rb_obj_class(self)); -} - -/* Facade for File */ - -/* - * Returns the real (absolute) pathname for +self+ in the actual - * filesystem. - * - * Does not contain symlinks or useless dots, +..+ and +.+. - * - * All components of the pathname must exist when this method is - * called. - * - */ -static VALUE -path_realpath(int argc, VALUE *argv, VALUE self) -{ - VALUE basedir, str; - rb_scan_args(argc, argv, "01", &basedir); - str = rb_funcall(rb_cFile, id_realpath, 2, get_strpath(self), basedir); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Returns the real (absolute) pathname of +self+ in the actual filesystem. - * - * Does not contain symlinks or useless dots, +..+ and +.+. - * - * The last component of the real pathname can be nonexistent. - */ -static VALUE -path_realdirpath(int argc, VALUE *argv, VALUE self) -{ - VALUE basedir, str; - rb_scan_args(argc, argv, "01", &basedir); - str = rb_funcall(rb_cFile, id_realdirpath, 2, get_strpath(self), basedir); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * call-seq: - * pathname.each_line {|line| ... } - * pathname.each_line(sep=$/ [, open_args]) {|line| block } -> nil - * pathname.each_line(limit [, open_args]) {|line| block } -> nil - * pathname.each_line(sep, limit [, open_args]) {|line| block } -> nil - * pathname.each_line(...) -> an_enumerator - * - * Iterates over each line in the file and yields a String object for each. - */ -static VALUE -path_each_line(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - if (rb_block_given_p()) { - return rb_block_call_kw(rb_cFile, id_foreach, 1+n, args, 0, 0, RB_PASS_CALLED_KEYWORDS); - } - else { - return rb_funcallv_kw(rb_cFile, id_foreach, 1+n, args, RB_PASS_CALLED_KEYWORDS); - } -} - -/* - * call-seq: - * pathname.read([length [, offset]]) -> string - * pathname.read([length [, offset]], open_args) -> string - * - * Returns all data from the file, or the first +N+ bytes if specified. - * - * See File.read. - * - */ -static VALUE -path_read(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - return rb_funcallv_kw(rb_cFile, id_read, 1+n, args, RB_PASS_CALLED_KEYWORDS); -} - -/* - * call-seq: - * pathname.binread([length [, offset]]) -> string - * - * Returns all the bytes from the file, or the first +N+ if specified. - * - * See File.binread. - * - */ -static VALUE -path_binread(int argc, VALUE *argv, VALUE self) -{ - VALUE args[3]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "02", &args[1], &args[2]); - return rb_funcallv(rb_cFile, id_binread, 1+n, args); -} - -/* - * call-seq: - * pathname.write(string, [offset] ) => fixnum - * pathname.write(string, [offset], open_args ) => fixnum - * - * Writes +contents+ to the file. - * - * See File.write. - * - */ -static VALUE -path_write(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - return rb_funcallv_kw(rb_cFile, id_write, 1+n, args, RB_PASS_CALLED_KEYWORDS); -} - -/* - * call-seq: - * pathname.binwrite(string, [offset] ) => fixnum - * pathname.binwrite(string, [offset], open_args ) => fixnum - * - * Writes +contents+ to the file, opening it in binary mode. - * - * See File.binwrite. - * - */ -static VALUE -path_binwrite(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - return rb_funcallv_kw(rb_cFile, id_binwrite, 1+n, args, RB_PASS_CALLED_KEYWORDS); -} - -/* - * call-seq: - * pathname.readlines(sep=$/ [, open_args]) -> array - * pathname.readlines(limit [, open_args]) -> array - * pathname.readlines(sep, limit [, open_args]) -> array - * - * Returns all the lines from the file. - * - * See File.readlines. - * - */ -static VALUE -path_readlines(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - return rb_funcallv_kw(rb_cFile, id_readlines, 1+n, args, RB_PASS_CALLED_KEYWORDS); -} - -/* - * call-seq: - * pathname.sysopen([mode, [perm]]) -> fixnum - * - * See IO.sysopen. - * - */ -static VALUE -path_sysopen(int argc, VALUE *argv, VALUE self) -{ - VALUE args[3]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "02", &args[1], &args[2]); - return rb_funcallv(rb_cIO, id_sysopen, 1+n, args); -} - -/* - * call-seq: - * pathname.atime -> time - * - * Returns the last access time for the file. - * - * See File.atime. - */ -static VALUE -path_atime(VALUE self) -{ - return rb_funcall(rb_cFile, id_atime, 1, get_strpath(self)); -} - -#if defined(HAVE_RB_FILE_S_BIRTHTIME) -/* - * call-seq: - * pathname.birthtime -> time - * - * Returns the birth time for the file. - * If the platform doesn't have birthtime, raises NotImplementedError. - * - * See File.birthtime. - */ -static VALUE -path_birthtime(VALUE self) -{ - return rb_funcall(rb_cFile, id_birthtime, 1, get_strpath(self)); -} -#else -/* check at compilation time for `respond_to?` */ -# define path_birthtime rb_f_notimplement -#endif - -/* - * call-seq: - * pathname.ctime -> time - * - * Returns the last change time, using directory information, not the file itself. - * - * See File.ctime. - */ -static VALUE -path_ctime(VALUE self) -{ - return rb_funcall(rb_cFile, id_ctime, 1, get_strpath(self)); -} - -/* - * call-seq: - * pathname.mtime -> time - * - * Returns the last modified time of the file. - * - * See File.mtime. - */ -static VALUE -path_mtime(VALUE self) -{ - return rb_funcall(rb_cFile, id_mtime, 1, get_strpath(self)); -} - -/* - * call-seq: - * pathname.chmod(mode_int) -> integer - * - * Changes file permissions. - * - * See File.chmod. - */ -static VALUE -path_chmod(VALUE self, VALUE mode) -{ - return rb_funcall(rb_cFile, id_chmod, 2, mode, get_strpath(self)); -} - -/* - * call-seq: - * pathname.lchmod(mode_int) -> integer - * - * Same as Pathname.chmod, but does not follow symbolic links. - * - * See File.lchmod. - */ -static VALUE -path_lchmod(VALUE self, VALUE mode) -{ - return rb_funcall(rb_cFile, id_lchmod, 2, mode, get_strpath(self)); -} - -/* - * call-seq: - * pathname.chown(owner_int, group_int) -> integer - * - * Change owner and group of the file. - * - * See File.chown. - */ -static VALUE -path_chown(VALUE self, VALUE owner, VALUE group) -{ - return rb_funcall(rb_cFile, id_chown, 3, owner, group, get_strpath(self)); -} - -/* - * call-seq: - * pathname.lchown(owner_int, group_int) -> integer - * - * Same as Pathname.chown, but does not follow symbolic links. - * - * See File.lchown. - */ -static VALUE -path_lchown(VALUE self, VALUE owner, VALUE group) -{ - return rb_funcall(rb_cFile, id_lchown, 3, owner, group, get_strpath(self)); -} - -/* - * call-seq: - * pathname.fnmatch(pattern, [flags]) -> true or false - * pathname.fnmatch?(pattern, [flags]) -> true or false - * - * Return +true+ if the receiver matches the given pattern. - * - * See File.fnmatch. - */ -static VALUE -path_fnmatch(int argc, VALUE *argv, VALUE self) -{ - VALUE str = get_strpath(self); - VALUE pattern, flags; - if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1) - return rb_funcall(rb_cFile, id_fnmatch, 2, pattern, str); - else - return rb_funcall(rb_cFile, id_fnmatch, 3, pattern, str, flags); -} - -/* - * call-seq: - * pathname.ftype -> string - * - * Returns "type" of file ("file", "directory", etc). - * - * See File.ftype. - */ -static VALUE -path_ftype(VALUE self) -{ - return rb_funcall(rb_cFile, id_ftype, 1, get_strpath(self)); -} - -/* - * call-seq: - * pathname.make_link(old) - * - * Creates a hard link at _pathname_. - * - * See File.link. - */ -static VALUE -path_make_link(VALUE self, VALUE old) -{ - return rb_funcall(rb_cFile, id_link, 2, old, get_strpath(self)); -} - -/* - * call-seq: - * pathname.open() - * pathname.open(mode="r" [, opt]) -> file - * pathname.open([mode [, perm]] [, opt]) -> file - * pathname.open(mode="r" [, opt]) {|file| block } -> obj - * pathname.open([mode [, perm]] [, opt]) {|file| block } -> obj - * - * Opens the file for reading or writing. - * - * See File.open. - */ -static VALUE -path_open(int argc, VALUE *argv, VALUE self) -{ - VALUE args[4]; - int n; - - args[0] = get_strpath(self); - n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); - if (rb_block_given_p()) { - return rb_block_call_kw(rb_cFile, id_open, 1+n, args, 0, 0, RB_PASS_CALLED_KEYWORDS); - } - else { - return rb_funcallv_kw(rb_cFile, id_open, 1+n, args, RB_PASS_CALLED_KEYWORDS); - } -} - -/* - * Read symbolic link. - * - * See File.readlink. - */ -static VALUE -path_readlink(VALUE self) -{ - VALUE str; - str = rb_funcall(rb_cFile, id_readlink, 1, get_strpath(self)); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Rename the file. - * - * See File.rename. - */ -static VALUE -path_rename(VALUE self, VALUE to) -{ - return rb_funcall(rb_cFile, id_rename, 2, get_strpath(self), to); -} - -/* - * Returns a File::Stat object. - * - * See File.stat. - */ -static VALUE -path_stat(VALUE self) -{ - return rb_funcall(rb_cFile, id_stat, 1, get_strpath(self)); -} - -/* - * See File.lstat. - */ -static VALUE -path_lstat(VALUE self) -{ - return rb_funcall(rb_cFile, id_lstat, 1, get_strpath(self)); -} - -/* - * call-seq: - * pathname.make_symlink(old) - * - * Creates a symbolic link. - * - * See File.symlink. - */ -static VALUE -path_make_symlink(VALUE self, VALUE old) -{ - return rb_funcall(rb_cFile, id_symlink, 2, old, get_strpath(self)); -} - -/* - * Truncates the file to +length+ bytes. - * - * See File.truncate. - */ -static VALUE -path_truncate(VALUE self, VALUE length) -{ - return rb_funcall(rb_cFile, id_truncate, 2, get_strpath(self), length); -} - -/* - * Update the access and modification times of the file. - * - * See File.utime. - */ -static VALUE -path_utime(VALUE self, VALUE atime, VALUE mtime) -{ - return rb_funcall(rb_cFile, id_utime, 3, atime, mtime, get_strpath(self)); -} - -/* - * Returns the last component of the path. - * - * See File.basename. - */ -static VALUE -path_basename(int argc, VALUE *argv, VALUE self) -{ - VALUE str = get_strpath(self); - VALUE fext; - if (rb_scan_args(argc, argv, "01", &fext) == 0) - str = rb_funcall(rb_cFile, id_basename, 1, str); - else - str = rb_funcall(rb_cFile, id_basename, 2, str, fext); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Returns all but the last component of the path. - * - * See File.dirname. - */ -static VALUE -path_dirname(VALUE self) -{ - VALUE str = get_strpath(self); - str = rb_funcall(rb_cFile, id_dirname, 1, str); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Returns the file's extension. - * - * See File.extname. - */ -static VALUE -path_extname(VALUE self) -{ - VALUE str = get_strpath(self); - return rb_funcall(rb_cFile, id_extname, 1, str); -} - -/* - * Returns the absolute path for the file. - * - * See File.expand_path. - */ -static VALUE -path_expand_path(int argc, VALUE *argv, VALUE self) -{ - VALUE str = get_strpath(self); - VALUE dname; - if (rb_scan_args(argc, argv, "01", &dname) == 0) - str = rb_funcall(rb_cFile, id_expand_path, 1, str); - else - str = rb_funcall(rb_cFile, id_expand_path, 2, str, dname); - return rb_class_new_instance(1, &str, rb_obj_class(self)); -} - -/* - * Returns the #dirname and the #basename in an Array. - * - * See File.split. - */ -static VALUE -path_split(VALUE self) -{ - VALUE str = get_strpath(self); - VALUE ary, dirname, basename; - ary = rb_funcall(rb_cFile, id_split, 1, str); - Check_Type(ary, T_ARRAY); - dirname = rb_ary_entry(ary, 0); - basename = rb_ary_entry(ary, 1); - dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self)); - basename = rb_class_new_instance(1, &basename, rb_obj_class(self)); - return rb_ary_new3(2, dirname, basename); -} - -/* - * See FileTest.blockdev?. - */ -static VALUE -path_blockdev_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_blockdev_p, 1, get_strpath(self)); -} - -/* - * See FileTest.chardev?. - */ -static VALUE -path_chardev_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_chardev_p, 1, get_strpath(self)); -} - -/* - * See FileTest.executable?. - */ -static VALUE -path_executable_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_executable_p, 1, get_strpath(self)); -} - -/* - * See FileTest.executable_real?. - */ -static VALUE -path_executable_real_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_executable_real_p, 1, get_strpath(self)); -} - -/* - * See FileTest.exist?. - */ -static VALUE -path_exist_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_exist_p, 1, get_strpath(self)); -} - -/* - * See FileTest.grpowned?. - */ -static VALUE -path_grpowned_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_grpowned_p, 1, get_strpath(self)); -} - -/* - * See FileTest.directory?. - */ -static VALUE -path_directory_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_directory_p, 1, get_strpath(self)); -} - -/* - * See FileTest.file?. - */ -static VALUE -path_file_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_file_p, 1, get_strpath(self)); -} - -/* - * See FileTest.pipe?. - */ -static VALUE -path_pipe_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_pipe_p, 1, get_strpath(self)); -} - -/* - * See FileTest.socket?. - */ -static VALUE -path_socket_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_socket_p, 1, get_strpath(self)); -} - -/* - * See FileTest.owned?. - */ -static VALUE -path_owned_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_owned_p, 1, get_strpath(self)); -} - -/* - * See FileTest.readable?. - */ -static VALUE -path_readable_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_readable_p, 1, get_strpath(self)); -} - -/* - * See FileTest.world_readable?. - */ -static VALUE -path_world_readable_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_world_readable_p, 1, get_strpath(self)); -} - -/* - * See FileTest.readable_real?. - */ -static VALUE -path_readable_real_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_readable_real_p, 1, get_strpath(self)); -} - -/* - * See FileTest.setuid?. - */ -static VALUE -path_setuid_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_setuid_p, 1, get_strpath(self)); -} - -/* - * See FileTest.setgid?. - */ -static VALUE -path_setgid_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_setgid_p, 1, get_strpath(self)); -} - -/* - * See FileTest.size. - */ -static VALUE -path_size(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_size, 1, get_strpath(self)); -} - -/* - * See FileTest.size?. - */ -static VALUE -path_size_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_size_p, 1, get_strpath(self)); -} - -/* - * See FileTest.sticky?. - */ -static VALUE -path_sticky_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_sticky_p, 1, get_strpath(self)); -} - -/* - * See FileTest.symlink?. - */ -static VALUE -path_symlink_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_symlink_p, 1, get_strpath(self)); -} - -/* - * See FileTest.writable?. - */ -static VALUE -path_writable_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_writable_p, 1, get_strpath(self)); -} - -/* - * See FileTest.world_writable?. - */ -static VALUE -path_world_writable_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_world_writable_p, 1, get_strpath(self)); -} - -/* - * See FileTest.writable_real?. - */ -static VALUE -path_writable_real_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_writable_real_p, 1, get_strpath(self)); -} - -/* - * See FileTest.zero?. - */ -static VALUE -path_zero_p(VALUE self) -{ - return rb_funcall(rb_mFileTest, id_zero_p, 1, get_strpath(self)); -} - -/* - * Tests the file is empty. - * - * See Dir#empty? and FileTest.empty?. - */ -static VALUE -path_empty_p(VALUE self) -{ - - VALUE path = get_strpath(self); - if (RTEST(rb_funcall(rb_mFileTest, id_directory_p, 1, path))) - return rb_funcall(rb_cDir, id_empty_p, 1, path); - else - return rb_funcall(rb_mFileTest, id_empty_p, 1, path); -} - -static VALUE -s_glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass)) -{ - return rb_yield(rb_class_new_instance(1, &elt, klass)); -} - -/* - * Returns or yields Pathname objects. - * - * Pathname.glob("lib/i*.rb") - * #=> [#<Pathname:lib/ipaddr.rb>, #<Pathname:lib/irb.rb>] - * - * See Dir.glob. - */ -static VALUE -path_s_glob(int argc, VALUE *argv, VALUE klass) -{ - VALUE args[3]; - int n; - - n = rb_scan_args(argc, argv, "12", &args[0], &args[1], &args[2]); - if (rb_block_given_p()) { - return rb_block_call_kw(rb_cDir, id_glob, n, args, s_glob_i, klass, RB_PASS_CALLED_KEYWORDS); - } - else { - VALUE ary; - long i; - ary = rb_funcallv_kw(rb_cDir, id_glob, n, args, RB_PASS_CALLED_KEYWORDS); - ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); - for (i = 0; i < RARRAY_LEN(ary); i++) { - VALUE elt = RARRAY_AREF(ary, i); - elt = rb_class_new_instance(1, &elt, klass); - rb_ary_store(ary, i, elt); - } - return ary; - } -} - -static VALUE -glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, self)) -{ - elt = rb_funcall(self, '+', 1, elt); - return rb_yield(elt); -} - -/* - * Returns or yields Pathname objects. - * - * Pathname("ruby-2.4.2").glob("R*.md") - * #=> [#<Pathname:ruby-2.4.2/README.md>, #<Pathname:ruby-2.4.2/README.ja.md>] - * - * See Dir.glob. - * This method uses the +base+ keyword argument of Dir.glob. - */ -static VALUE -path_glob(int argc, VALUE *argv, VALUE self) -{ - VALUE args[3]; - int n; - - n = rb_scan_args(argc, argv, "11", &args[0], &args[1]); - if (n == 1) - args[1] = INT2FIX(0); - - args[2] = rb_hash_new(); - rb_hash_aset(args[2], ID2SYM(id_base), get_strpath(self)); - - n = 3; - - if (rb_block_given_p()) { - return rb_block_call_kw(rb_cDir, id_glob, n, args, glob_i, self, RB_PASS_KEYWORDS); - } - else { - VALUE ary; - long i; - ary = rb_funcallv_kw(rb_cDir, id_glob, n, args, RB_PASS_KEYWORDS); - ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); - for (i = 0; i < RARRAY_LEN(ary); i++) { - VALUE elt = RARRAY_AREF(ary, i); - elt = rb_funcall(self, '+', 1, elt); - rb_ary_store(ary, i, elt); - } - return ary; - } -} - -/* - * Returns the current working directory as a Pathname. - * - * Pathname.getwd - * #=> #<Pathname:/home/zzak/projects/ruby> - * - * See Dir.getwd. - */ -static VALUE -path_s_getwd(VALUE klass) -{ - VALUE str; - str = rb_funcall(rb_cDir, id_getwd, 0); - return rb_class_new_instance(1, &str, klass); -} - -/* - * Return the entries (files and subdirectories) in the directory, each as a - * Pathname object. - * - * The results contains just the names in the directory, without any trailing - * slashes or recursive look-up. - * - * pp Pathname.new('/usr/local').entries - * #=> [#<Pathname:share>, - * # #<Pathname:lib>, - * # #<Pathname:..>, - * # #<Pathname:include>, - * # #<Pathname:etc>, - * # #<Pathname:bin>, - * # #<Pathname:man>, - * # #<Pathname:games>, - * # #<Pathname:.>, - * # #<Pathname:sbin>, - * # #<Pathname:src>] - * - * The result may contain the current directory <code>#<Pathname:.></code> and - * the parent directory <code>#<Pathname:..></code>. - * - * If you don't want +.+ and +..+ and - * want directories, consider Pathname#children. - */ -static VALUE -path_entries(VALUE self) -{ - VALUE klass, str, ary; - long i; - klass = rb_obj_class(self); - str = get_strpath(self); - ary = rb_funcall(rb_cDir, id_entries, 1, str); - ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); - for (i = 0; i < RARRAY_LEN(ary); i++) { - VALUE elt = RARRAY_AREF(ary, i); - elt = rb_class_new_instance(1, &elt, klass); - rb_ary_store(ary, i, elt); - } - return ary; -} - -/* - * Create the referenced directory. - * - * See Dir.mkdir. - */ -static VALUE -path_mkdir(int argc, VALUE *argv, VALUE self) -{ - VALUE str = get_strpath(self); - VALUE vmode; - if (rb_scan_args(argc, argv, "01", &vmode) == 0) - return rb_funcall(rb_cDir, id_mkdir, 1, str); - else - return rb_funcall(rb_cDir, id_mkdir, 2, str, vmode); -} - -/* - * Remove the referenced directory. - * - * See Dir.rmdir. - */ -static VALUE -path_rmdir(VALUE self) -{ - return rb_funcall(rb_cDir, id_rmdir, 1, get_strpath(self)); -} - -/* - * Opens the referenced directory. - * - * See Dir.open. - */ -static VALUE -path_opendir(VALUE self) -{ - VALUE args[1]; - - args[0] = get_strpath(self); - return rb_block_call(rb_cDir, id_open, 1, args, 0, 0); -} - -static VALUE -each_entry_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass)) -{ - return rb_yield(rb_class_new_instance(1, &elt, klass)); -} - -/* - * Iterates over the entries (files and subdirectories) in the directory, - * yielding a Pathname object for each entry. - */ -static VALUE -path_each_entry(VALUE self) -{ - VALUE args[1]; - - args[0] = get_strpath(self); - return rb_block_call(rb_cDir, id_foreach, 1, args, each_entry_i, rb_obj_class(self)); -} - -static VALUE -unlink_body(VALUE str) -{ - return rb_funcall(rb_cDir, id_unlink, 1, str); -} - -static VALUE -unlink_rescue(VALUE str, VALUE errinfo) -{ - return rb_funcall(rb_cFile, id_unlink, 1, str); -} - -/* - * Removes a file or directory, using File.unlink if +self+ is a file, or - * Dir.unlink as necessary. - */ -static VALUE -path_unlink(VALUE self) -{ - VALUE eENOTDIR = rb_const_get_at(rb_mErrno, id_ENOTDIR); - VALUE str = get_strpath(self); - return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0); -} - -/* - * :call-seq: - * Pathname(path) -> pathname - * - * Creates a new Pathname object from the given string, +path+, and returns - * pathname object. - * - * In order to use this constructor, you must first require the Pathname - * standard library extension. - * - * require 'pathname' - * Pathname("/home/zzak") - * #=> #<Pathname:/home/zzak> - * - * See also Pathname::new for more information. - */ -static VALUE -path_f_pathname(VALUE self, VALUE str) -{ - if (CLASS_OF(str) == rb_cPathname) - return str; - return rb_class_new_instance(1, &str, rb_cPathname); -} - -/* - * - * Pathname represents the name of a file or directory on the filesystem, - * but not the file itself. - * - * The pathname depends on the Operating System: Unix, Windows, etc. - * This library works with pathnames of local OS, however non-Unix pathnames - * are supported experimentally. - * - * A Pathname can be relative or absolute. It's not until you try to - * reference the file that it even matters whether the file exists or not. - * - * Pathname is immutable. It has no method for destructive update. - * - * The goal of this class is to manipulate file path information in a neater - * way than standard Ruby provides. The examples below demonstrate the - * difference. - * - * *All* functionality from File, FileTest, and some from Dir and FileUtils is - * included, in an unsurprising way. It is essentially a facade for all of - * these, and more. - * - * == Examples - * - * === Example 1: Using Pathname - * - * require 'pathname' - * pn = Pathname.new("/usr/bin/ruby") - * size = pn.size # 27662 - * isdir = pn.directory? # false - * dir = pn.dirname # Pathname:/usr/bin - * base = pn.basename # Pathname:ruby - * dir, base = pn.split # [Pathname:/usr/bin, Pathname:ruby] - * data = pn.read - * pn.open { |f| _ } - * pn.each_line { |line| _ } - * - * === Example 2: Using standard Ruby - * - * pn = "/usr/bin/ruby" - * size = File.size(pn) # 27662 - * isdir = File.directory?(pn) # false - * dir = File.dirname(pn) # "/usr/bin" - * base = File.basename(pn) # "ruby" - * dir, base = File.split(pn) # ["/usr/bin", "ruby"] - * data = File.read(pn) - * File.open(pn) { |f| _ } - * File.foreach(pn) { |line| _ } - * - * === Example 3: Special features - * - * p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib - * p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8 - * p3 = p1.parent # Pathname:/usr - * p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8 - * pwd = Pathname.pwd # Pathname:/home/gavin - * pwd.absolute? # true - * p5 = Pathname.new "." # Pathname:. - * p5 = p5 + "music/../articles" # Pathname:music/../articles - * p5.cleanpath # Pathname:articles - * p5.realpath # Pathname:/home/gavin/articles - * p5.children # [Pathname:/home/gavin/articles/linux, ...] - * - * == Breakdown of functionality - * - * === Core methods - * - * These methods are effectively manipulating a String, because that's - * all a path is. None of these access the file system except for - * #mountpoint?, #children, #each_child, #realdirpath and #realpath. - * - * - + - * - #join - * - #parent - * - #root? - * - #absolute? - * - #relative? - * - #relative_path_from - * - #each_filename - * - #cleanpath - * - #realpath - * - #realdirpath - * - #children - * - #each_child - * - #mountpoint? - * - * === File status predicate methods - * - * These methods are a facade for FileTest: - * - #blockdev? - * - #chardev? - * - #directory? - * - #executable? - * - #executable_real? - * - #exist? - * - #file? - * - #grpowned? - * - #owned? - * - #pipe? - * - #readable? - * - #world_readable? - * - #readable_real? - * - #setgid? - * - #setuid? - * - #size - * - #size? - * - #socket? - * - #sticky? - * - #symlink? - * - #writable? - * - #world_writable? - * - #writable_real? - * - #zero? - * - * === File property and manipulation methods - * - * These methods are a facade for File: - * - #atime - * - #birthtime - * - #ctime - * - #mtime - * - #chmod(mode) - * - #lchmod(mode) - * - #chown(owner, group) - * - #lchown(owner, group) - * - #fnmatch(pattern, *args) - * - #fnmatch?(pattern, *args) - * - #ftype - * - #make_link(old) - * - #open(*args, &block) - * - #readlink - * - #rename(to) - * - #stat - * - #lstat - * - #make_symlink(old) - * - #truncate(length) - * - #utime(atime, mtime) - * - #basename(*args) - * - #dirname - * - #extname - * - #expand_path(*args) - * - #split - * - * === Directory methods - * - * These methods are a facade for Dir: - * - Pathname.glob(*args) - * - Pathname.getwd / Pathname.pwd - * - #rmdir - * - #entries - * - #each_entry(&block) - * - #mkdir(*args) - * - #opendir(*args) - * - * === IO - * - * These methods are a facade for IO: - * - #each_line(*args, &block) - * - #read(*args) - * - #binread(*args) - * - #readlines(*args) - * - #sysopen(*args) - * - #write(*args) - * - #binwrite(*args) - * - * === Utilities - * - * These methods are a mixture of Find, FileUtils, and others: - * - #find(&block) - * - #mkpath - * - #rmtree - * - #unlink / #delete - * - * - * == Method documentation - * - * As the above section shows, most of the methods in Pathname are facades. The - * documentation for these methods generally just says, for instance, "See - * FileTest.writable?", as you should be familiar with the original method - * anyway, and its documentation (e.g. through +ri+) will contain more - * information. In some cases, a brief description will follow. - */ -void -Init_pathname(void) -{ -#ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); -#endif - - InitVM(pathname); - - rb_cPathname = rb_define_class("Pathname", rb_cObject); - rb_define_method(rb_cPathname, "initialize", path_initialize, 1); - rb_define_method(rb_cPathname, "freeze", path_freeze, 0); - rb_define_method(rb_cPathname, "taint", path_taint, 0); - rb_define_method(rb_cPathname, "untaint", path_untaint, 0); - rb_define_method(rb_cPathname, "==", path_eq, 1); - rb_define_method(rb_cPathname, "===", path_eq, 1); - rb_define_method(rb_cPathname, "eql?", path_eq, 1); - rb_define_method(rb_cPathname, "<=>", path_cmp, 1); - rb_define_method(rb_cPathname, "hash", path_hash, 0); - rb_define_method(rb_cPathname, "to_s", path_to_s, 0); - rb_define_method(rb_cPathname, "to_path", path_to_s, 0); - rb_define_method(rb_cPathname, "inspect", path_inspect, 0); - rb_define_method(rb_cPathname, "sub", path_sub, -1); - rb_define_method(rb_cPathname, "sub_ext", path_sub_ext, 1); - rb_define_method(rb_cPathname, "realpath", path_realpath, -1); - rb_define_method(rb_cPathname, "realdirpath", path_realdirpath, -1); - rb_define_method(rb_cPathname, "each_line", path_each_line, -1); - rb_define_method(rb_cPathname, "read", path_read, -1); - rb_define_method(rb_cPathname, "binread", path_binread, -1); - rb_define_method(rb_cPathname, "readlines", path_readlines, -1); - rb_define_method(rb_cPathname, "write", path_write, -1); - rb_define_method(rb_cPathname, "binwrite", path_binwrite, -1); - rb_define_method(rb_cPathname, "sysopen", path_sysopen, -1); - rb_define_method(rb_cPathname, "atime", path_atime, 0); - rb_define_method(rb_cPathname, "birthtime", path_birthtime, 0); - rb_define_method(rb_cPathname, "ctime", path_ctime, 0); - rb_define_method(rb_cPathname, "mtime", path_mtime, 0); - rb_define_method(rb_cPathname, "chmod", path_chmod, 1); - rb_define_method(rb_cPathname, "lchmod", path_lchmod, 1); - rb_define_method(rb_cPathname, "chown", path_chown, 2); - rb_define_method(rb_cPathname, "lchown", path_lchown, 2); - rb_define_method(rb_cPathname, "fnmatch", path_fnmatch, -1); - rb_define_method(rb_cPathname, "fnmatch?", path_fnmatch, -1); - rb_define_method(rb_cPathname, "ftype", path_ftype, 0); - rb_define_method(rb_cPathname, "make_link", path_make_link, 1); - rb_define_method(rb_cPathname, "open", path_open, -1); - rb_define_method(rb_cPathname, "readlink", path_readlink, 0); - rb_define_method(rb_cPathname, "rename", path_rename, 1); - rb_define_method(rb_cPathname, "stat", path_stat, 0); - rb_define_method(rb_cPathname, "lstat", path_lstat, 0); - rb_define_method(rb_cPathname, "make_symlink", path_make_symlink, 1); - rb_define_method(rb_cPathname, "truncate", path_truncate, 1); - rb_define_method(rb_cPathname, "utime", path_utime, 2); - rb_define_method(rb_cPathname, "basename", path_basename, -1); - rb_define_method(rb_cPathname, "dirname", path_dirname, 0); - rb_define_method(rb_cPathname, "extname", path_extname, 0); - rb_define_method(rb_cPathname, "expand_path", path_expand_path, -1); - rb_define_method(rb_cPathname, "split", path_split, 0); - rb_define_method(rb_cPathname, "blockdev?", path_blockdev_p, 0); - rb_define_method(rb_cPathname, "chardev?", path_chardev_p, 0); - rb_define_method(rb_cPathname, "executable?", path_executable_p, 0); - rb_define_method(rb_cPathname, "executable_real?", path_executable_real_p, 0); - rb_define_method(rb_cPathname, "exist?", path_exist_p, 0); - rb_define_method(rb_cPathname, "grpowned?", path_grpowned_p, 0); - rb_define_method(rb_cPathname, "directory?", path_directory_p, 0); - rb_define_method(rb_cPathname, "file?", path_file_p, 0); - rb_define_method(rb_cPathname, "pipe?", path_pipe_p, 0); - rb_define_method(rb_cPathname, "socket?", path_socket_p, 0); - rb_define_method(rb_cPathname, "owned?", path_owned_p, 0); - rb_define_method(rb_cPathname, "readable?", path_readable_p, 0); - rb_define_method(rb_cPathname, "world_readable?", path_world_readable_p, 0); - rb_define_method(rb_cPathname, "readable_real?", path_readable_real_p, 0); - rb_define_method(rb_cPathname, "setuid?", path_setuid_p, 0); - rb_define_method(rb_cPathname, "setgid?", path_setgid_p, 0); - rb_define_method(rb_cPathname, "size", path_size, 0); - rb_define_method(rb_cPathname, "size?", path_size_p, 0); - rb_define_method(rb_cPathname, "sticky?", path_sticky_p, 0); - rb_define_method(rb_cPathname, "symlink?", path_symlink_p, 0); - rb_define_method(rb_cPathname, "writable?", path_writable_p, 0); - rb_define_method(rb_cPathname, "world_writable?", path_world_writable_p, 0); - rb_define_method(rb_cPathname, "writable_real?", path_writable_real_p, 0); - rb_define_method(rb_cPathname, "zero?", path_zero_p, 0); - rb_define_method(rb_cPathname, "empty?", path_empty_p, 0); - rb_define_singleton_method(rb_cPathname, "glob", path_s_glob, -1); - rb_define_singleton_method(rb_cPathname, "getwd", path_s_getwd, 0); - rb_define_singleton_method(rb_cPathname, "pwd", path_s_getwd, 0); - rb_define_method(rb_cPathname, "glob", path_glob, -1); - rb_define_method(rb_cPathname, "entries", path_entries, 0); - rb_define_method(rb_cPathname, "mkdir", path_mkdir, -1); - rb_define_method(rb_cPathname, "rmdir", path_rmdir, 0); - rb_define_method(rb_cPathname, "opendir", path_opendir, 0); - rb_define_method(rb_cPathname, "each_entry", path_each_entry, 0); - rb_define_method(rb_cPathname, "unlink", path_unlink, 0); - rb_define_method(rb_cPathname, "delete", path_unlink, 0); - rb_undef_method(rb_cPathname, "=~"); - rb_define_global_function("Pathname", path_f_pathname, 1); -} - -void -InitVM_pathname(void) -{ -#undef rb_intern - id_at_path = rb_intern("@path"); - id_to_path = rb_intern("to_path"); - id_ENOTDIR = rb_intern("ENOTDIR"); - id_atime = rb_intern("atime"); - id_basename = rb_intern("basename"); - id_base = rb_intern("base"); - id_binread = rb_intern("binread"); - id_binwrite = rb_intern("binwrite"); - id_birthtime = rb_intern("birthtime"); - id_blockdev_p = rb_intern("blockdev?"); - id_chardev_p = rb_intern("chardev?"); - id_chmod = rb_intern("chmod"); - id_chown = rb_intern("chown"); - id_ctime = rb_intern("ctime"); - id_directory_p = rb_intern("directory?"); - id_dirname = rb_intern("dirname"); - id_empty_p = rb_intern("empty?"); - id_entries = rb_intern("entries"); - id_executable_p = rb_intern("executable?"); - id_executable_real_p = rb_intern("executable_real?"); - id_exist_p = rb_intern("exist?"); - id_expand_path = rb_intern("expand_path"); - id_extname = rb_intern("extname"); - id_file_p = rb_intern("file?"); - id_fnmatch = rb_intern("fnmatch"); - id_foreach = rb_intern("foreach"); - id_ftype = rb_intern("ftype"); - id_getwd = rb_intern("getwd"); - id_glob = rb_intern("glob"); - id_grpowned_p = rb_intern("grpowned?"); - id_lchmod = rb_intern("lchmod"); - id_lchown = rb_intern("lchown"); - id_link = rb_intern("link"); - id_lstat = rb_intern("lstat"); - id_mkdir = rb_intern("mkdir"); - id_mtime = rb_intern("mtime"); - id_open = rb_intern("open"); - id_owned_p = rb_intern("owned?"); - id_pipe_p = rb_intern("pipe?"); - id_read = rb_intern("read"); - id_readable_p = rb_intern("readable?"); - id_readable_real_p = rb_intern("readable_real?"); - id_readlines = rb_intern("readlines"); - id_readlink = rb_intern("readlink"); - id_realdirpath = rb_intern("realdirpath"); - id_realpath = rb_intern("realpath"); - id_rename = rb_intern("rename"); - id_rmdir = rb_intern("rmdir"); - id_setgid_p = rb_intern("setgid?"); - id_setuid_p = rb_intern("setuid?"); - id_size = rb_intern("size"); - id_size_p = rb_intern("size?"); - id_socket_p = rb_intern("socket?"); - id_split = rb_intern("split"); - id_stat = rb_intern("stat"); - id_sticky_p = rb_intern("sticky?"); - id_sub = rb_intern("sub"); - id_symlink = rb_intern("symlink"); - id_symlink_p = rb_intern("symlink?"); - id_sysopen = rb_intern("sysopen"); - id_truncate = rb_intern("truncate"); - id_unlink = rb_intern("unlink"); - id_utime = rb_intern("utime"); - id_world_readable_p = rb_intern("world_readable?"); - id_world_writable_p = rb_intern("world_writable?"); - id_writable_p = rb_intern("writable?"); - id_writable_real_p = rb_intern("writable_real?"); - id_write = rb_intern("write"); - id_zero_p = rb_intern("zero?"); -} diff --git a/ext/pathname/pathname.gemspec b/ext/pathname/pathname.gemspec deleted file mode 100644 index 5aaa8f8dd7..0000000000 --- a/ext/pathname/pathname.gemspec +++ /dev/null @@ -1,25 +0,0 @@ -Gem::Specification.new do |spec| - spec.name = "pathname" - spec.version = "0.2.0" - spec.authors = ["Tanaka Akira"] - spec.email = ["akr@fsij.org"] - - spec.summary = %q{Representation of the name of a file or directory on the filesystem} - spec.description = %q{Representation of the name of a file or directory on the filesystem} - spec.homepage = "https://github.com/ruby/pathname" - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") - spec.licenses = ["Ruby", "BSD-2-Clause"] - - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = spec.homepage - - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.bindir = "exe" - spec.executables = [] - spec.require_paths = ["lib"] - spec.extensions = %w[ext/pathname/extconf.rb] -end diff --git a/ext/psych/.gitignore b/ext/psych/.gitignore new file mode 100644 index 0000000000..92946455b0 --- /dev/null +++ b/ext/psych/.gitignore @@ -0,0 +1 @@ +/yaml-[0-9]*.*.* diff --git a/ext/psych/depend b/ext/psych/depend index ef55b78c33..95175841a2 100644 --- a/ext/psych/depend +++ b/ext/psych/depend @@ -1,31 +1,18 @@ -$(OBJS): $(YAML_H) +$(TARGET_SO): $(LIBYAML) + +libyaml $(LIBYAML): + cd libyaml && $(MAKE) + $(AR) $(ARFLAGS) $(LIBYAML) $(LIBYAML_OBJDIR)/*.$(OBJEXT) + $(RANLIB) $(LIBYAML) + +clean-so:: + -cd libyaml && $(MAKE) clean + +distclean-so:: + -cd libyaml && $(MAKE) distclean + -$(Q)$(RMDIRS) libyaml/* libyaml # AUTOGENERATED DEPENDENCIES START -api.o: $(RUBY_EXTCONF_H) -api.o: yaml/api.c -api.o: yaml/config.h -api.o: yaml/yaml.h -api.o: yaml/yaml_private.h -dumper.o: $(RUBY_EXTCONF_H) -dumper.o: yaml/config.h -dumper.o: yaml/dumper.c -dumper.o: yaml/yaml.h -dumper.o: yaml/yaml_private.h -emitter.o: $(RUBY_EXTCONF_H) -emitter.o: yaml/config.h -emitter.o: yaml/emitter.c -emitter.o: yaml/yaml.h -emitter.o: yaml/yaml_private.h -loader.o: $(RUBY_EXTCONF_H) -loader.o: yaml/config.h -loader.o: yaml/loader.c -loader.o: yaml/yaml.h -loader.o: yaml/yaml_private.h -parser.o: $(RUBY_EXTCONF_H) -parser.o: yaml/config.h -parser.o: yaml/parser.c -parser.o: yaml/yaml.h -parser.o: yaml/yaml_private.h psych.o: $(RUBY_EXTCONF_H) psych.o: $(arch_hdrdir)/ruby/config.h psych.o: $(hdrdir)/ruby.h @@ -34,7 +21,6 @@ psych.o: $(hdrdir)/ruby/backward.h psych.o: $(hdrdir)/ruby/backward/2/assume.h psych.o: $(hdrdir)/ruby/backward/2/attributes.h psych.o: $(hdrdir)/ruby/backward/2/bool.h -psych.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h psych.o: $(hdrdir)/ruby/backward/2/inttypes.h psych.o: $(hdrdir)/ruby/backward/2/limits.h psych.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -43,6 +29,7 @@ psych.o: $(hdrdir)/ruby/backward/2/stdarg.h psych.o: $(hdrdir)/ruby/defines.h psych.o: $(hdrdir)/ruby/encoding.h psych.o: $(hdrdir)/ruby/intern.h +psych.o: $(hdrdir)/ruby/internal/abi.h psych.o: $(hdrdir)/ruby/internal/anyargs.h psych.o: $(hdrdir)/ruby/internal/arithmetic.h psych.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -80,6 +67,7 @@ psych.o: $(hdrdir)/ruby/internal/attr/noexcept.h psych.o: $(hdrdir)/ruby/internal/attr/noinline.h psych.o: $(hdrdir)/ruby/internal/attr/nonnull.h psych.o: $(hdrdir)/ruby/internal/attr/noreturn.h +psych.o: $(hdrdir)/ruby/internal/attr/packed_struct.h psych.o: $(hdrdir)/ruby/internal/attr/pure.h psych.o: $(hdrdir)/ruby/internal/attr/restrict.h psych.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -148,7 +136,6 @@ psych.o: $(hdrdir)/ruby/internal/intern/enumerator.h psych.o: $(hdrdir)/ruby/internal/intern/error.h psych.o: $(hdrdir)/ruby/internal/intern/eval.h psych.o: $(hdrdir)/ruby/internal/intern/file.h -psych.o: $(hdrdir)/ruby/internal/intern/gc.h psych.o: $(hdrdir)/ruby/internal/intern/hash.h psych.o: $(hdrdir)/ruby/internal/intern/io.h psych.o: $(hdrdir)/ruby/internal/intern/load.h @@ -165,6 +152,7 @@ psych.o: $(hdrdir)/ruby/internal/intern/re.h psych.o: $(hdrdir)/ruby/internal/intern/ruby.h psych.o: $(hdrdir)/ruby/internal/intern/select.h psych.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych.o: $(hdrdir)/ruby/internal/intern/set.h psych.o: $(hdrdir)/ruby/internal/intern/signal.h psych.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych.o: $(hdrdir)/ruby/internal/intern/string.h @@ -179,12 +167,12 @@ psych.o: $(hdrdir)/ruby/internal/memory.h psych.o: $(hdrdir)/ruby/internal/method.h psych.o: $(hdrdir)/ruby/internal/module.h psych.o: $(hdrdir)/ruby/internal/newobj.h -psych.o: $(hdrdir)/ruby/internal/rgengc.h psych.o: $(hdrdir)/ruby/internal/scan_args.h psych.o: $(hdrdir)/ruby/internal/special_consts.h psych.o: $(hdrdir)/ruby/internal/static_assert.h psych.o: $(hdrdir)/ruby/internal/stdalign.h psych.o: $(hdrdir)/ruby/internal/stdbool.h +psych.o: $(hdrdir)/ruby/internal/stdckdint.h psych.o: $(hdrdir)/ruby/internal/symbol.h psych.o: $(hdrdir)/ruby/internal/value.h psych.o: $(hdrdir)/ruby/internal/value_type.h @@ -203,7 +191,6 @@ psych.o: psych_emitter.h psych.o: psych_parser.h psych.o: psych_to_ruby.h psych.o: psych_yaml_tree.h -psych.o: yaml/yaml.h psych_emitter.o: $(RUBY_EXTCONF_H) psych_emitter.o: $(arch_hdrdir)/ruby/config.h psych_emitter.o: $(hdrdir)/ruby.h @@ -212,7 +199,6 @@ psych_emitter.o: $(hdrdir)/ruby/backward.h psych_emitter.o: $(hdrdir)/ruby/backward/2/assume.h psych_emitter.o: $(hdrdir)/ruby/backward/2/attributes.h psych_emitter.o: $(hdrdir)/ruby/backward/2/bool.h -psych_emitter.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h psych_emitter.o: $(hdrdir)/ruby/backward/2/inttypes.h psych_emitter.o: $(hdrdir)/ruby/backward/2/limits.h psych_emitter.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -221,6 +207,7 @@ psych_emitter.o: $(hdrdir)/ruby/backward/2/stdarg.h psych_emitter.o: $(hdrdir)/ruby/defines.h psych_emitter.o: $(hdrdir)/ruby/encoding.h psych_emitter.o: $(hdrdir)/ruby/intern.h +psych_emitter.o: $(hdrdir)/ruby/internal/abi.h psych_emitter.o: $(hdrdir)/ruby/internal/anyargs.h psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic.h psych_emitter.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -258,6 +245,7 @@ psych_emitter.o: $(hdrdir)/ruby/internal/attr/noexcept.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/noinline.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/nonnull.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/noreturn.h +psych_emitter.o: $(hdrdir)/ruby/internal/attr/packed_struct.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/pure.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/restrict.h psych_emitter.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -326,7 +314,6 @@ psych_emitter.o: $(hdrdir)/ruby/internal/intern/enumerator.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/error.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/eval.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/file.h -psych_emitter.o: $(hdrdir)/ruby/internal/intern/gc.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/hash.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/io.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/load.h @@ -343,6 +330,7 @@ psych_emitter.o: $(hdrdir)/ruby/internal/intern/re.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/select.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_emitter.o: $(hdrdir)/ruby/internal/intern/set.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/signal.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_emitter.o: $(hdrdir)/ruby/internal/intern/string.h @@ -357,12 +345,12 @@ psych_emitter.o: $(hdrdir)/ruby/internal/memory.h psych_emitter.o: $(hdrdir)/ruby/internal/method.h psych_emitter.o: $(hdrdir)/ruby/internal/module.h psych_emitter.o: $(hdrdir)/ruby/internal/newobj.h -psych_emitter.o: $(hdrdir)/ruby/internal/rgengc.h psych_emitter.o: $(hdrdir)/ruby/internal/scan_args.h psych_emitter.o: $(hdrdir)/ruby/internal/special_consts.h psych_emitter.o: $(hdrdir)/ruby/internal/static_assert.h psych_emitter.o: $(hdrdir)/ruby/internal/stdalign.h psych_emitter.o: $(hdrdir)/ruby/internal/stdbool.h +psych_emitter.o: $(hdrdir)/ruby/internal/stdckdint.h psych_emitter.o: $(hdrdir)/ruby/internal/symbol.h psych_emitter.o: $(hdrdir)/ruby/internal/value.h psych_emitter.o: $(hdrdir)/ruby/internal/value_type.h @@ -381,7 +369,6 @@ psych_emitter.o: psych_emitter.h psych_emitter.o: psych_parser.h psych_emitter.o: psych_to_ruby.h psych_emitter.o: psych_yaml_tree.h -psych_emitter.o: yaml/yaml.h psych_parser.o: $(RUBY_EXTCONF_H) psych_parser.o: $(arch_hdrdir)/ruby/config.h psych_parser.o: $(hdrdir)/ruby.h @@ -390,7 +377,6 @@ psych_parser.o: $(hdrdir)/ruby/backward.h psych_parser.o: $(hdrdir)/ruby/backward/2/assume.h psych_parser.o: $(hdrdir)/ruby/backward/2/attributes.h psych_parser.o: $(hdrdir)/ruby/backward/2/bool.h -psych_parser.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h psych_parser.o: $(hdrdir)/ruby/backward/2/inttypes.h psych_parser.o: $(hdrdir)/ruby/backward/2/limits.h psych_parser.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -399,6 +385,7 @@ psych_parser.o: $(hdrdir)/ruby/backward/2/stdarg.h psych_parser.o: $(hdrdir)/ruby/defines.h psych_parser.o: $(hdrdir)/ruby/encoding.h psych_parser.o: $(hdrdir)/ruby/intern.h +psych_parser.o: $(hdrdir)/ruby/internal/abi.h psych_parser.o: $(hdrdir)/ruby/internal/anyargs.h psych_parser.o: $(hdrdir)/ruby/internal/arithmetic.h psych_parser.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -436,6 +423,7 @@ psych_parser.o: $(hdrdir)/ruby/internal/attr/noexcept.h psych_parser.o: $(hdrdir)/ruby/internal/attr/noinline.h psych_parser.o: $(hdrdir)/ruby/internal/attr/nonnull.h psych_parser.o: $(hdrdir)/ruby/internal/attr/noreturn.h +psych_parser.o: $(hdrdir)/ruby/internal/attr/packed_struct.h psych_parser.o: $(hdrdir)/ruby/internal/attr/pure.h psych_parser.o: $(hdrdir)/ruby/internal/attr/restrict.h psych_parser.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -504,7 +492,6 @@ psych_parser.o: $(hdrdir)/ruby/internal/intern/enumerator.h psych_parser.o: $(hdrdir)/ruby/internal/intern/error.h psych_parser.o: $(hdrdir)/ruby/internal/intern/eval.h psych_parser.o: $(hdrdir)/ruby/internal/intern/file.h -psych_parser.o: $(hdrdir)/ruby/internal/intern/gc.h psych_parser.o: $(hdrdir)/ruby/internal/intern/hash.h psych_parser.o: $(hdrdir)/ruby/internal/intern/io.h psych_parser.o: $(hdrdir)/ruby/internal/intern/load.h @@ -521,6 +508,7 @@ psych_parser.o: $(hdrdir)/ruby/internal/intern/re.h psych_parser.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_parser.o: $(hdrdir)/ruby/internal/intern/select.h psych_parser.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_parser.o: $(hdrdir)/ruby/internal/intern/set.h psych_parser.o: $(hdrdir)/ruby/internal/intern/signal.h psych_parser.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_parser.o: $(hdrdir)/ruby/internal/intern/string.h @@ -535,12 +523,12 @@ psych_parser.o: $(hdrdir)/ruby/internal/memory.h psych_parser.o: $(hdrdir)/ruby/internal/method.h psych_parser.o: $(hdrdir)/ruby/internal/module.h psych_parser.o: $(hdrdir)/ruby/internal/newobj.h -psych_parser.o: $(hdrdir)/ruby/internal/rgengc.h psych_parser.o: $(hdrdir)/ruby/internal/scan_args.h psych_parser.o: $(hdrdir)/ruby/internal/special_consts.h psych_parser.o: $(hdrdir)/ruby/internal/static_assert.h psych_parser.o: $(hdrdir)/ruby/internal/stdalign.h psych_parser.o: $(hdrdir)/ruby/internal/stdbool.h +psych_parser.o: $(hdrdir)/ruby/internal/stdckdint.h psych_parser.o: $(hdrdir)/ruby/internal/symbol.h psych_parser.o: $(hdrdir)/ruby/internal/value.h psych_parser.o: $(hdrdir)/ruby/internal/value_type.h @@ -559,7 +547,6 @@ psych_parser.o: psych_parser.c psych_parser.o: psych_parser.h psych_parser.o: psych_to_ruby.h psych_parser.o: psych_yaml_tree.h -psych_parser.o: yaml/yaml.h psych_to_ruby.o: $(RUBY_EXTCONF_H) psych_to_ruby.o: $(arch_hdrdir)/ruby/config.h psych_to_ruby.o: $(hdrdir)/ruby.h @@ -568,7 +555,6 @@ psych_to_ruby.o: $(hdrdir)/ruby/backward.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/assume.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/attributes.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/bool.h -psych_to_ruby.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/inttypes.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/limits.h psych_to_ruby.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -577,6 +563,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/backward/2/stdarg.h psych_to_ruby.o: $(hdrdir)/ruby/defines.h psych_to_ruby.o: $(hdrdir)/ruby/encoding.h psych_to_ruby.o: $(hdrdir)/ruby/intern.h +psych_to_ruby.o: $(hdrdir)/ruby/internal/abi.h psych_to_ruby.o: $(hdrdir)/ruby/internal/anyargs.h psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic.h psych_to_ruby.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -614,6 +601,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noexcept.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noinline.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/nonnull.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/noreturn.h +psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/packed_struct.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/pure.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/restrict.h psych_to_ruby.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -682,7 +670,6 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/enumerator.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/error.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/eval.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/file.h -psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/gc.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/hash.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/io.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/load.h @@ -699,6 +686,7 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/re.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/set.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/signal.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_to_ruby.o: $(hdrdir)/ruby/internal/intern/string.h @@ -713,12 +701,12 @@ psych_to_ruby.o: $(hdrdir)/ruby/internal/memory.h psych_to_ruby.o: $(hdrdir)/ruby/internal/method.h psych_to_ruby.o: $(hdrdir)/ruby/internal/module.h psych_to_ruby.o: $(hdrdir)/ruby/internal/newobj.h -psych_to_ruby.o: $(hdrdir)/ruby/internal/rgengc.h psych_to_ruby.o: $(hdrdir)/ruby/internal/scan_args.h psych_to_ruby.o: $(hdrdir)/ruby/internal/special_consts.h psych_to_ruby.o: $(hdrdir)/ruby/internal/static_assert.h psych_to_ruby.o: $(hdrdir)/ruby/internal/stdalign.h psych_to_ruby.o: $(hdrdir)/ruby/internal/stdbool.h +psych_to_ruby.o: $(hdrdir)/ruby/internal/stdckdint.h psych_to_ruby.o: $(hdrdir)/ruby/internal/symbol.h psych_to_ruby.o: $(hdrdir)/ruby/internal/value.h psych_to_ruby.o: $(hdrdir)/ruby/internal/value_type.h @@ -737,7 +725,6 @@ psych_to_ruby.o: psych_parser.h psych_to_ruby.o: psych_to_ruby.c psych_to_ruby.o: psych_to_ruby.h psych_to_ruby.o: psych_yaml_tree.h -psych_to_ruby.o: yaml/yaml.h psych_yaml_tree.o: $(RUBY_EXTCONF_H) psych_yaml_tree.o: $(arch_hdrdir)/ruby/config.h psych_yaml_tree.o: $(hdrdir)/ruby.h @@ -746,7 +733,6 @@ psych_yaml_tree.o: $(hdrdir)/ruby/backward.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/assume.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/attributes.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/bool.h -psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/inttypes.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/limits.h psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -755,6 +741,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/backward/2/stdarg.h psych_yaml_tree.o: $(hdrdir)/ruby/defines.h psych_yaml_tree.o: $(hdrdir)/ruby/encoding.h psych_yaml_tree.o: $(hdrdir)/ruby/intern.h +psych_yaml_tree.o: $(hdrdir)/ruby/internal/abi.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/anyargs.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -792,6 +779,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noexcept.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noinline.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/nonnull.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/noreturn.h +psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/packed_struct.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/pure.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/restrict.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -860,7 +848,6 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/enumerator.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/error.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/eval.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/file.h -psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/gc.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/hash.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/io.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/load.h @@ -877,6 +864,7 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/re.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/ruby.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/set.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/signal.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/sprintf.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/intern/string.h @@ -891,12 +879,12 @@ psych_yaml_tree.o: $(hdrdir)/ruby/internal/memory.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/method.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/module.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/newobj.h -psych_yaml_tree.o: $(hdrdir)/ruby/internal/rgengc.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/scan_args.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/special_consts.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/static_assert.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/stdalign.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/stdbool.h +psych_yaml_tree.o: $(hdrdir)/ruby/internal/stdckdint.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/symbol.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/value.h psych_yaml_tree.o: $(hdrdir)/ruby/internal/value_type.h @@ -915,20 +903,4 @@ psych_yaml_tree.o: psych_parser.h psych_yaml_tree.o: psych_to_ruby.h psych_yaml_tree.o: psych_yaml_tree.c psych_yaml_tree.o: psych_yaml_tree.h -psych_yaml_tree.o: yaml/yaml.h -reader.o: $(RUBY_EXTCONF_H) -reader.o: yaml/config.h -reader.o: yaml/reader.c -reader.o: yaml/yaml.h -reader.o: yaml/yaml_private.h -scanner.o: $(RUBY_EXTCONF_H) -scanner.o: yaml/config.h -scanner.o: yaml/scanner.c -scanner.o: yaml/yaml.h -scanner.o: yaml/yaml_private.h -writer.o: $(RUBY_EXTCONF_H) -writer.o: yaml/config.h -writer.o: yaml/writer.c -writer.o: yaml/yaml.h -writer.o: yaml/yaml_private.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/psych/extconf.rb b/ext/psych/extconf.rb index 857f8e68c4..589e201c1c 100644 --- a/ext/psych/extconf.rb +++ b/ext/psych/extconf.rb @@ -1,43 +1,56 @@ # -*- coding: us-ascii -*- # frozen_string_literal: true require 'mkmf' -require 'fileutils' -# :stopdoc: - -dir_config 'libyaml' - -if enable_config("bundled-libyaml", false) || !(find_header('yaml.h') && find_library('yaml', 'yaml_get_version')) - # Embed libyaml since we could not find it. - - $VPATH << "$(srcdir)/yaml" - $INCFLAGS << " -I$(srcdir)/yaml" - - $srcs = Dir.glob("#{$srcdir}/{,yaml/}*.c").map {|n| File.basename(n)}.sort +if $mswin or $mingw or $cygwin + $CPPFLAGS << " -DYAML_DECLARE_STATIC" +end - header = 'yaml/yaml.h' - header = "{$(VPATH)}#{header}" if $nmake - if have_macro("_WIN32") - $CPPFLAGS << " -DYAML_DECLARE_STATIC -DHAVE_CONFIG_H" +yaml_source = with_config("libyaml-source-dir") +if yaml_source + yaml_source = yaml_source.gsub(/\$\((\w+)\)|\$\{(\w+)\}/) {ENV[$1||$2]} + yaml_source = yaml_source.chomp("/") + yaml_configure = "#{File.expand_path(yaml_source)}/configure" + unless File.exist?(yaml_configure) + raise "Configure script not found in #{yaml_source.quote}" end - have_header 'dlfcn.h' - have_header 'inttypes.h' - have_header 'memory.h' - have_header 'stdint.h' - have_header 'stdlib.h' - have_header 'strings.h' - have_header 'string.h' - have_header 'sys/stat.h' - have_header 'sys/types.h' - have_header 'unistd.h' - - find_header 'yaml.h' - have_header 'config.h' + puts("Configuring libyaml source in #{yaml_source.quote}") + yaml = "libyaml" + Dir.mkdir(yaml) unless File.directory?(yaml) + shared = $enable_shared || !$static + args = [ + yaml_configure, + "--enable-#{shared ? 'shared' : 'static'}", + "--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-').sub(/arm64/, 'arm')}", + "CC=#{RbConfig::CONFIG['CC']}", + *(["CFLAGS=-w"] if RbConfig::CONFIG["GCC"] == "yes"), + ] + puts(args.quote.join(' ')) + unless system(*args, chdir: yaml) + raise "failed to configure libyaml" + end + inc = yaml_source.start_with?("#$srcdir/") ? "$(srcdir)#{yaml_source[$srcdir.size..-1]}" : yaml_source + $INCFLAGS << " -I#{yaml}/include -I#{inc}/include" + puts("INCFLAGS=#$INCFLAGS") + libyaml = "libyaml.#$LIBEXT" + $cleanfiles << libyaml + $LOCAL_LIBS.prepend("$(LIBYAML) ") + + # default to pre-installed libyaml +elsif pkg_config('yaml-0.1') + # found with pkg-config +else + dir_config('libyaml') + find_header('yaml.h') or abort "yaml.h not found" + find_library('yaml', 'yaml_get_version') or abort "libyaml not found" end create_makefile 'psych' do |mk| - mk << "YAML_H = #{header}".strip << "\n" + mk << "LIBYAML = #{libyaml}".strip << "\n" + mk << "LIBYAML_OBJDIR = libyaml/src#{shared ? '/.libs' : ''}\n" + mk << "OBJEXT = #$OBJEXT" + mk << "RANLIB = #{config_string('RANLIB') || config_string('NULLCMD')}\n" end # :startdoc: diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index ecf3b3927e..850a6d1937 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true -require 'psych/versions' +require 'date' + +require_relative 'psych/versions' case RUBY_ENGINE when 'jruby' - require 'psych_jars' + require_relative 'psych_jars' if JRuby::Util.respond_to?(:load_ext) JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary') else @@ -12,21 +14,20 @@ when 'jruby' else require 'psych.so' end -require 'psych/nodes' -require 'psych/streaming' -require 'psych/visitors' -require 'psych/handler' -require 'psych/tree_builder' -require 'psych/parser' -require 'psych/omap' -require 'psych/set' -require 'psych/coder' -require 'psych/core_ext' -require 'psych/stream' -require 'psych/json/tree_builder' -require 'psych/json/stream' -require 'psych/handlers/document_stream' -require 'psych/class_loader' +require_relative 'psych/nodes' +require_relative 'psych/streaming' +require_relative 'psych/visitors' +require_relative 'psych/handler' +require_relative 'psych/tree_builder' +require_relative 'psych/parser' +require_relative 'psych/omap' +require_relative 'psych/set' +require_relative 'psych/coder' +require_relative 'psych/stream' +require_relative 'psych/json/tree_builder' +require_relative 'psych/json/stream' +require_relative 'psych/handlers/document_stream' +require_relative 'psych/class_loader' ### # = Overview @@ -84,7 +85,7 @@ require 'psych/class_loader' # Psych.safe_load_file("data.yml", permitted_classes: [Date]) # Psych.load_file("trusted_database.yml") # -# ==== Exception handling +# ==== \Exception handling # # begin # # The second argument changes only the exception contents @@ -148,7 +149,7 @@ require 'psych/class_loader' # # Returns Psych::Nodes::Document # Psych.parse_file('database.yml') # -# ==== Exception handling +# ==== \Exception handling # # begin # # The second argument changes only the exception contents @@ -268,12 +269,11 @@ module Psych # YAML documents that are supplied via user input. Instead, please use the # load method or the safe_load method. # - def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false + def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true result = parse(yaml, filename: filename) return fallback unless result - result.to_ruby(symbolize_names: symbolize_names, freeze: freeze) + result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer, parse_symbols: parse_symbols) end - class << self; alias :load :unsafe_load; end ### # Safely load the yaml string in +yaml+. By default, only the following @@ -308,7 +308,7 @@ module Psych # A Psych::DisallowedClass exception will be raised if the yaml contains a # class that isn't in the +permitted_classes+ list. # - # A Psych::BadAlias exception will be raised if the yaml contains aliases + # A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases # but the +aliases+ keyword argument is set to false. # # +filename+ will be used in the exception message if any exception is raised @@ -320,13 +320,13 @@ module Psych # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"} # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} # - def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false + def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true result = parse(yaml, filename: filename) return fallback unless result class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s), permitted_symbols.map(&:to_s)) - scanner = ScalarScanner.new class_loader + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer, parse_symbols: parse_symbols visitor = if aliases Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze else @@ -341,7 +341,7 @@ module Psych # provided, the object contained in the first document will be returned. # +filename+ will be used in the exception message if any exception # is raised while parsing. If +yaml+ is empty, it returns - # the specified +fallback+ return value, which defaults to +false+. + # the specified +fallback+ return value, which defaults to +nil+. # # Raises a Psych::SyntaxError when a YAML syntax error is detected. # @@ -366,14 +366,16 @@ module Psych # Raises a TypeError when `yaml` parameter is NilClass. This method is # similar to `safe_load` except that `Symbol` objects are allowed by default. # - def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false + def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true safe_load yaml, permitted_classes: permitted_classes, permitted_symbols: permitted_symbols, aliases: aliases, filename: filename, fallback: fallback, symbolize_names: symbolize_names, - freeze: freeze + freeze: freeze, + strict_integer: strict_integer, + parse_symbols: parse_symbols end ### @@ -479,6 +481,7 @@ module Psych # # Default: <tt>2</tt>. # [<tt>:line_width</tt>] Max character to wrap line at. + # For unlimited line width use <tt>-1</tt>. # # Default: <tt>0</tt> (meaning "wrap at 81"). # [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet @@ -489,6 +492,10 @@ module Psych # # Default: <tt>false</tt>. # + # [<tt>:stringify_names</tt>] Dump symbol keys in Hash objects as string. + # + # Default: <tt>false</tt>. + # # Example: # # # Dump an array, get back a YAML string @@ -502,6 +509,9 @@ module Psych # # # Dump an array to an IO with indentation set # Psych.dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" def self.dump o, io = nil, options = {} if Hash === io options = io @@ -552,6 +562,7 @@ module Psych # # Default: <tt>2</tt>. # [<tt>:line_width</tt>] Max character to wrap line at. + # For unlimited line width use <tt>-1</tt>. # # Default: <tt>0</tt> (meaning "wrap at 81"). # [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet @@ -562,6 +573,10 @@ module Psych # # Default: <tt>false</tt>. # + # [<tt>:stringify_names</tt>] Dump symbol keys in Hash objects as string. + # + # Default: <tt>false</tt>. + # # Example: # # # Dump an array, get back a YAML string @@ -575,6 +590,9 @@ module Psych # # # Dump an array to an IO with indentation set # Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" def self.safe_dump o, io = nil, options = {} if Hash === io options = io @@ -637,6 +655,35 @@ module Psych end ### + # Load multiple documents given in +yaml+. Returns the parsed documents + # as a list. + # + # Example: + # + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] + # + # list = [] + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") do |ruby| + # list << ruby + # end + # list # => ['foo', 'bar'] + # + def self.safe_load_stream yaml, filename: nil, permitted_classes: [], aliases: false + documents = parse_stream(yaml, filename: filename).children.map do |child| + stream = Psych::Nodes::Stream.new + stream.children << child + safe_load(stream.to_yaml, permitted_classes: permitted_classes, aliases: aliases) + end + + if block_given? + documents.each { |doc| yield doc } + nil + else + documents + end + end + + ### # Load the document contained in +filename+. Returns the yaml contained in # +filename+ as a Ruby object, or if the file is empty, it returns # the specified +fallback+ return value, which defaults to +false+. @@ -653,7 +700,7 @@ module Psych ### # Safely loads the document contained in +filename+. Returns the yaml contained in # +filename+ as a Ruby object, or if the file is empty, it returns - # the specified +fallback+ return value, which defaults to +false+. + # the specified +fallback+ return value, which defaults to +nil+. # See safe_load for options. def self.safe_load_file filename, **kwargs File.open(filename, 'r:bom|utf-8') { |f| @@ -664,7 +711,7 @@ module Psych ### # Loads the document contained in +filename+. Returns the yaml contained in # +filename+ as a Ruby object, or if the file is empty, it returns - # the specified +fallback+ return value, which defaults to +false+. + # the specified +fallback+ return value, which defaults to +nil+. # See load for options. def self.load_file filename, **kwargs File.open(filename, 'r:bom|utf-8') { |f| @@ -694,26 +741,8 @@ module Psych dump_tags[klass] = tag end - # Workaround for emulating `warn '...', uplevel: 1` in Ruby 2.4 or lower. - def self.warn_with_uplevel(message, uplevel: 1) - at = parse_caller(caller[uplevel]).join(':') - warn "#{at}: #{message}" - end - - def self.parse_caller(at) - if /^(.+?):(\d+)(?::in `.*')?/ =~ at - file = $1 - line = $2.to_i - [file, line] - end - end - private_class_method :warn_with_uplevel, :parse_caller - class << self if defined?(Ractor) - require 'forwardable' - extend Forwardable - class Config attr_accessor :load_tags, :dump_tags, :domain_types def initialize @@ -727,7 +756,29 @@ module Psych Ractor.current[:PsychConfig] ||= Config.new end - def_delegators :config, :load_tags, :dump_tags, :domain_types, :load_tags=, :dump_tags=, :domain_types= + def load_tags + config.load_tags + end + + def dump_tags + config.dump_tags + end + + def domain_types + config.domain_types + end + + def load_tags=(value) + config.load_tags = value + end + + def dump_tags=(value) + config.dump_tags = value + end + + def domain_types=(value) + config.domain_types = value + end else attr_accessor :load_tags attr_accessor :dump_tags @@ -739,3 +790,5 @@ module Psych self.domain_types = {} # :startdoc: end + +require_relative 'psych/core_ext' diff --git a/ext/psych/lib/psych/class_loader.rb b/ext/psych/lib/psych/class_loader.rb index 088373cd66..c8f509720a 100644 --- a/ext/psych/lib/psych/class_loader.rb +++ b/ext/psych/lib/psych/class_loader.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require 'psych/omap' -require 'psych/set' +require_relative 'omap' +require_relative 'set' module Psych class ClassLoader # :nodoc: BIG_DECIMAL = 'BigDecimal' COMPLEX = 'Complex' + DATA = 'Data' unless RUBY_VERSION < "3.2" DATE = 'Date' DATE_TIME = 'DateTime' EXCEPTION = 'Exception' @@ -35,7 +36,7 @@ module Psych constants.each do |const| konst = const_get const - class_eval <<~RUBY + class_eval <<~RUBY, __FILE__, __LINE__ + 1 def #{const.to_s.downcase} load #{konst.inspect} end diff --git a/ext/psych/lib/psych/core_ext.rb b/ext/psych/lib/psych/core_ext.rb index 81055cc501..6dfd0f1696 100644 --- a/ext/psych/lib/psych/core_ext.rb +++ b/ext/psych/lib/psych/core_ext.rb @@ -14,6 +14,23 @@ class Object end end -if defined?(::IRB) - require 'psych/y' +# Up to Ruby 3.4, Set was a regular object and was dumped as such +# by Pysch. +# Starting from Ruby 4.0 it's a core class written in C, so we have to implement +# #encode_with / #init_with to preserve backward compatibility. +if defined?(::Set) && Set.new.instance_variables.empty? + class Set + def encode_with(coder) + hash = {} + each do |m| + hash[m] = true + end + coder["hash"] = hash + coder + end + + def init_with(coder) + replace(coder["hash"].keys) + end + end end diff --git a/ext/psych/lib/psych/exception.rb b/ext/psych/lib/psych/exception.rb index f473b95a3b..d7469a4b30 100644 --- a/ext/psych/lib/psych/exception.rb +++ b/ext/psych/lib/psych/exception.rb @@ -6,6 +6,20 @@ module Psych class BadAlias < Exception end + # Subclasses `BadAlias` for backwards compatibility + class AliasesNotEnabled < BadAlias + def initialize + super "Alias parsing was not enabled. To enable it, pass `aliases: true` to `Psych::load` or `Psych::safe_load`." + end + end + + # Subclasses `BadAlias` for backwards compatibility + class AnchorNotDefined < BadAlias + def initialize anchor_name + super "An alias referenced an unknown anchor: #{anchor_name}" + end + end + class DisallowedClass < Exception def initialize action, klass_name super "Tried to #{action} unspecified class: #{klass_name}" diff --git a/ext/psych/lib/psych/handlers/document_stream.rb b/ext/psych/lib/psych/handlers/document_stream.rb index 67da794093..b77115d074 100644 --- a/ext/psych/lib/psych/handlers/document_stream.rb +++ b/ext/psych/lib/psych/handlers/document_stream.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/tree_builder' +require_relative '../tree_builder' module Psych module Handlers diff --git a/ext/psych/lib/psych/handlers/recorder.rb b/ext/psych/lib/psych/handlers/recorder.rb index a8fc7b1144..c98724cb76 100644 --- a/ext/psych/lib/psych/handlers/recorder.rb +++ b/ext/psych/lib/psych/handlers/recorder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/handler' +require_relative '../handler' module Psych module Handlers diff --git a/ext/psych/lib/psych/json/stream.rb b/ext/psych/lib/psych/json/stream.rb index 2ebd3d7a66..24dd4b9baf 100644 --- a/ext/psych/lib/psych/json/stream.rb +++ b/ext/psych/lib/psych/json/stream.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'psych/json/ruby_events' -require 'psych/json/yaml_events' +require_relative 'ruby_events' +require_relative 'yaml_events' module Psych module JSON diff --git a/ext/psych/lib/psych/json/tree_builder.rb b/ext/psych/lib/psych/json/tree_builder.rb index 5c2ee8ca25..9a45f6b94c 100644 --- a/ext/psych/lib/psych/json/tree_builder.rb +++ b/ext/psych/lib/psych/json/tree_builder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/json/yaml_events' +require_relative 'yaml_events' module Psych module JSON diff --git a/ext/psych/lib/psych/nodes.rb b/ext/psych/lib/psych/nodes.rb index 5842c2e3e5..2fa52e0055 100644 --- a/ext/psych/lib/psych/nodes.rb +++ b/ext/psych/lib/psych/nodes.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -require 'psych/nodes/node' -require 'psych/nodes/stream' -require 'psych/nodes/document' -require 'psych/nodes/sequence' -require 'psych/nodes/scalar' -require 'psych/nodes/mapping' -require 'psych/nodes/alias' +require_relative 'nodes/node' +require_relative 'nodes/stream' +require_relative 'nodes/document' +require_relative 'nodes/sequence' +require_relative 'nodes/scalar' +require_relative 'nodes/mapping' +require_relative 'nodes/alias' module Psych ### diff --git a/ext/psych/lib/psych/nodes/node.rb b/ext/psych/lib/psych/nodes/node.rb index 05cb08dac0..fc27448f2e 100644 --- a/ext/psych/lib/psych/nodes/node.rb +++ b/ext/psych/lib/psych/nodes/node.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true -require 'stringio' -require 'psych/class_loader' -require 'psych/scalar_scanner' +require_relative '../class_loader' +require_relative '../scalar_scanner' module Psych module Nodes @@ -46,8 +45,8 @@ module Psych # Convert this node to Ruby. # # See also Psych::Visitors::ToRuby - def to_ruby(symbolize_names: false, freeze: false) - Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze).accept(self) + def to_ruby(symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true) + Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer, parse_symbols: parse_symbols).accept(self) end alias :transform :to_ruby @@ -56,6 +55,8 @@ module Psych # # See also Psych::Visitors::Emitter def yaml io = nil, options = {} + require "stringio" unless defined?(StringIO) + real_io = io || StringIO.new(''.encode('utf-8')) Visitors::Emitter.new(real_io, options).accept self diff --git a/ext/psych/lib/psych/parser.rb b/ext/psych/lib/psych/parser.rb index 39bc8289be..2181c730e5 100644 --- a/ext/psych/lib/psych/parser.rb +++ b/ext/psych/lib/psych/parser.rb @@ -48,5 +48,18 @@ module Psych @handler = handler @external_encoding = ANY end + + ### + # call-seq: + # parser.parse(yaml) + # + # Parse the YAML document contained in +yaml+. Events will be called on + # the handler set on the parser instance. + # + # See Psych::Parser and Psych::Parser#handler + + def parse yaml, path = yaml.respond_to?(:path) ? yaml.path : "<unknown>" + _native_parse @handler, yaml, path + end end end diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index b66ff9938c..6a556fb3b8 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true -require 'strscan' module Psych ### @@ -12,25 +11,34 @@ module Psych # Base 60, [-+]inf and NaN are handled separately FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x - # Taken from http://yaml.org/type/int.html - INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2) - |[-+]?0[0-7_,]+ (?# base 8) - |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) - |[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x + # Taken from http://yaml.org/type/int.html and modified to ensure at least one numerical symbol exists + INTEGER_STRICT = /^(?:[-+]?0b[_]*[0-1][0-1_]* (?# base 2) + |[-+]?0[_]*[0-7][0-7_]* (?# base 8) + |[-+]?(0|[1-9][0-9_]*) (?# base 10) + |[-+]?0x[_]*[0-9a-fA-F][0-9a-fA-F_]* (?# base 16))$/x + + # Same as above, but allows commas. + # Not to YML spec, but kept for backwards compatibility + INTEGER_LEGACY = /^(?:[-+]?0b[_,]*[0-1][0-1_,]* (?# base 2) + |[-+]?0[_,]*[0-7][0-7_,]* (?# base 8) + |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) + |[-+]?0x[_,]*[0-9a-fA-F][0-9a-fA-F_,]* (?# base 16))$/x attr_reader :class_loader # Create a new scanner - def initialize class_loader + def initialize class_loader, strict_integer: false, parse_symbols: true @symbol_cache = {} @class_loader = class_loader + @strict_integer = strict_integer + @parse_symbols = parse_symbols end # Tokenize +string+ returning the Ruby object def tokenize string return nil if string.empty? return @symbol_cache[string] if @symbol_cache.key?(string) - + integer_regex = @strict_integer ? INTEGER_STRICT : INTEGER_LEGACY # Check for a String type, being careful not to get caught by hash keys, hex values, and # special floats (e.g., -.inf). if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/) @@ -54,9 +62,8 @@ module Psych string end elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/) - require 'date' begin - class_loader.date.strptime(string, '%Y-%m-%d') + class_loader.date.strptime(string, '%F', Date::GREGORIAN) rescue ArgumentError string end @@ -66,7 +73,7 @@ module Psych -Float::INFINITY elsif string.match?(/^\.nan$/i) Float::NAN - elsif string.match?(/^:./) + elsif @parse_symbols && string.match?(/^:./) if string =~ /^:(["'])(.*)\1/ @symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, '')) else @@ -88,9 +95,9 @@ module Psych if string.match?(/\A[-+]?\.\Z/) string else - Float(string.gsub(/[,_]|\.([Ee]|$)/, '\1')) + Float(string.delete(',_').gsub(/\.([Ee]|$)/, '\1')) end - elsif string.match?(INTEGER) + elsif string.match?(integer_regex) parse_int string else string @@ -100,7 +107,7 @@ module Psych ### # Parse and return an int from +string+ def parse_int string - Integer(string.gsub(/[,_]/, '')) + Integer(string.delete(',_')) end ### diff --git a/ext/psych/lib/psych/syntax_error.rb b/ext/psych/lib/psych/syntax_error.rb index 1598e6ff36..a4c9c4a376 100644 --- a/ext/psych/lib/psych/syntax_error.rb +++ b/ext/psych/lib/psych/syntax_error.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/exception' +require_relative 'exception' module Psych class SyntaxError < Psych::Exception diff --git a/ext/psych/lib/psych/tree_builder.rb b/ext/psych/lib/psych/tree_builder.rb index 47a1695643..83115bd721 100644 --- a/ext/psych/lib/psych/tree_builder.rb +++ b/ext/psych/lib/psych/tree_builder.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/handler' +require_relative 'handler' module Psych ### @@ -41,7 +41,7 @@ module Psych Sequence Mapping }.each do |node| - class_eval %{ + class_eval <<~RUBY, __FILE__, __LINE__ + 1 def start_#{node.downcase}(anchor, tag, implicit, style) n = Nodes::#{node}.new(anchor, tag, implicit, style) set_start_location(n) @@ -54,7 +54,7 @@ module Psych set_end_location(n) n end - } + RUBY end ### diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb index 513d010903..4c7a80d5c8 100644 --- a/ext/psych/lib/psych/versions.rb +++ b/ext/psych/lib/psych/versions.rb @@ -2,9 +2,9 @@ module Psych # The version of Psych you are using - VERSION = '4.0.1' + VERSION = '5.3.1' if RUBY_ENGINE == 'jruby' - DEFAULT_SNAKEYAML_VERSION = '1.28'.freeze + DEFAULT_SNAKEYAML_VERSION = '2.10'.freeze end end diff --git a/ext/psych/lib/psych/visitors.rb b/ext/psych/lib/psych/visitors.rb index e2b084daee..508290d862 100644 --- a/ext/psych/lib/psych/visitors.rb +++ b/ext/psych/lib/psych/visitors.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/visitors/visitor' -require 'psych/visitors/to_ruby' -require 'psych/visitors/emitter' -require 'psych/visitors/yaml_tree' -require 'psych/visitors/json_tree' -require 'psych/visitors/depth_first' +require_relative 'visitors/visitor' +require_relative 'visitors/to_ruby' +require_relative 'visitors/emitter' +require_relative 'visitors/yaml_tree' +require_relative 'visitors/json_tree' +require_relative 'visitors/depth_first' diff --git a/ext/psych/lib/psych/visitors/json_tree.rb b/ext/psych/lib/psych/visitors/json_tree.rb index 9912cb1362..979fc100bd 100644 --- a/ext/psych/lib/psych/visitors/json_tree.rb +++ b/ext/psych/lib/psych/visitors/json_tree.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'psych/json/ruby_events' +require_relative '../json/ruby_events' module Psych module Visitors diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index 4de7f80d33..475444e589 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/scalar_scanner' -require 'psych/class_loader' -require 'psych/exception' +require_relative '../scalar_scanner' +require_relative '../class_loader' +require_relative '../exception' unless defined?(Regexp::NOENCODING) Regexp::NOENCODING = 32 @@ -12,9 +12,13 @@ module Psych ### # This class walks a YAML AST, converting each node to Ruby class ToRuby < Psych::Visitors::Visitor - def self.create(symbolize_names: false, freeze: false) + unless RUBY_VERSION < "3.2" + DATA_INITIALIZE = Data.instance_method(:initialize) + end + + def self.create(symbolize_names: false, freeze: false, strict_integer: false, parse_symbols: true) class_loader = ClassLoader.new - scanner = ScalarScanner.new class_loader + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer, parse_symbols: parse_symbols new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze) end @@ -36,7 +40,7 @@ module Psych unless @domain_types.empty? || !target.tag key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') - key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/ + key = "tag:#{key}" unless key.match?(/^(?:tag:|x-private)/) if @domain_types.key? key value, block = @domain_types[key] @@ -79,8 +83,9 @@ module Psych class_loader.big_decimal._load o.value when "!ruby/object:DateTime" class_loader.date_time - require 'date' unless defined? DateTime - @ss.parse_time(o.value).to_datetime + t = @ss.parse_time(o.value) + DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) + + (t.subsec/86400) when '!ruby/encoding' ::Encoding.find o.value when "!ruby/object:Complex" @@ -95,11 +100,11 @@ module Psych Float(@ss.tokenize(o.value)) when "!ruby/regexp" klass = class_loader.regexp - o.value =~ /^\/(.*)\/([mixn]*)$/m - source = $1 + matches = /^\/(?<string>.*)\/(?<options>[mixn]*)$/m.match(o.value) + source = matches[:string].gsub('\/', '/') options = 0 lang = nil - ($2 || '').split('').each do |option| + matches[:options].each_char do |option| case option when 'x' then options |= Regexp::EXTENDED when 'i' then options |= Regexp::IGNORECASE @@ -196,6 +201,32 @@ module Psych s end + when /^!ruby\/data(-with-ivars)?(?::(.*))?$/ + data = register(o, resolve_class($2).allocate) if $2 + members = {} + + if $1 # data-with-ivars + ivars = {} + o.children.each_slice(2) do |type, vars| + case accept(type) + when 'members' + revive_data_members(members, vars) + data ||= allocate_anon_data(o, members) + when 'ivars' + revive_hash(ivars, vars) + end + end + ivars.each do |ivar, v| + data.instance_variable_set ivar, v + end + else + revive_data_members(members, o) + end + data ||= allocate_anon_data(o, members) + DATA_INITIALIZE.bind_call(data, **members) + data.freeze + data + when /^!ruby\/object:?(.*)?$/ name = $1 || 'Object' @@ -323,7 +354,7 @@ module Psych end def visit_Psych_Nodes_Alias o - @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" } + @st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor } end private @@ -339,6 +370,20 @@ module Psych list end + def allocate_anon_data node, members + klass = class_loader.data.define(*members.keys) + register(node, klass.allocate) + end + + def revive_data_members hash, o + o.children.each_slice(2) do |k,v| + name = accept(k) + value = accept(v) + hash[class_loader.symbolize(name)] = value + end + hash + end + def revive_hash hash, o, tagged= false o.children.each_slice(2) { |k,v| key = accept(k) @@ -427,7 +472,7 @@ module Psych class NoAliasRuby < ToRuby def visit_Psych_Nodes_Alias o - raise BadAlias, "Unknown alias: #{o.anchor}" + raise AliasesNotEnabled end end end diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 2eee4d3457..b6c86f4c94 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'psych/tree_builder' -require 'psych/scalar_scanner' -require 'psych/class_loader' +require_relative '../tree_builder' +require_relative '../scalar_scanner' +require_relative '../class_loader' module Psych module Visitors @@ -15,30 +15,25 @@ module Psych class YAMLTree < Psych::Visitors::Visitor class Registrar # :nodoc: def initialize - @obj_to_id = {} - @obj_to_node = {} - @targets = [] + @obj_to_id = {}.compare_by_identity + @obj_to_node = {}.compare_by_identity @counter = 0 end def register target, node - return unless target.respond_to? :object_id - @targets << target - @obj_to_node[target.object_id] = node + @obj_to_node[target] = node end def key? target - @obj_to_node.key? target.object_id - rescue NoMethodError - false + @obj_to_node.key? target end def id_for target - @obj_to_id[target.object_id] ||= (@counter += 1) + @obj_to_id[target] ||= (@counter += 1) end def node_for target - @obj_to_node[target.object_id] + @obj_to_node[target] end end @@ -70,6 +65,7 @@ module Psych fail(ArgumentError, "Invalid line_width #{@line_width}, must be non-negative or -1 for unlimited.") end end + @stringify_names = options[:stringify_names] @coders = [] @dispatch_cache = Hash.new do |h,klass| @@ -77,7 +73,7 @@ module Psych method = respond_to?(method) ? method : h[klass.superclass] - raise(TypeError, "Can't dump #{target.class}") unless method + raise(TypeError, "can't dump #{klass.name}") unless method h[klass] = method end.compare_by_identity @@ -166,6 +162,44 @@ module Psych alias :visit_Delegator :visit_Object + def visit_Data o + ivars = o.instance_variables + if ivars.empty? + tag = ['!ruby/data', o.class.name].compact.join(':') + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + else + tag = ['!ruby/data-with-ivars', o.class.name].compact.join(':') + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + + # Dump the members + accept 'members' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + ivars.each do |ivar| + accept ivar.to_s + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end unless RUBY_VERSION < "3.2" + def visit_Struct o tag = ['!ruby/struct', o.class.name].compact.join(':') @@ -192,12 +226,14 @@ module Psych register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY) end + def visit_Date o + formatted = format_date o + register o, @emitter.scalar(formatted, nil, nil, true, false, Nodes::Scalar::ANY) + end + def visit_DateTime o - formatted = if o.offset.zero? - o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze) - else - o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze) - end + t = o.italy + formatted = format_time t, t.offset.zero? tag = '!ruby/object:DateTime' register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY) end @@ -235,7 +271,6 @@ module Psych end alias :visit_TrueClass :visit_Integer alias :visit_FalseClass :visit_Integer - alias :visit_Date :visit_Integer def visit_Float o if o.nan? @@ -265,20 +300,20 @@ module Psych style = Nodes::Scalar::LITERAL plain = false quote = false - elsif o =~ /\n(?!\Z)/ # match \n except blank line at the end of string + elsif o.match?(/\n(?!\Z)/) # match \n except blank line at the end of string style = Nodes::Scalar::LITERAL elsif o == '<<' style = Nodes::Scalar::SINGLE_QUOTED tag = 'tag:yaml.org,2002:str' plain = false quote = false - elsif o == 'y' || o == 'n' + elsif o == 'y' || o == 'Y' || o == 'n' || o == 'N' style = Nodes::Scalar::DOUBLE_QUOTED elsif @line_width && o.length > @line_width style = Nodes::Scalar::FOLDED - elsif o =~ /^[^[:word:]][^"]*$/ + elsif o.match?(/^[^[:word:]][^"]*$/) style = Nodes::Scalar::DOUBLE_QUOTED - elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/ =~ o + elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o) style = Nodes::Scalar::SINGLE_QUOTED end @@ -328,7 +363,7 @@ module Psych if o.class == ::Hash register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @emitter.end_mapping @@ -341,7 +376,7 @@ module Psych register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @@ -482,14 +517,18 @@ module Psych @emitter.end_mapping end - def format_time time - if time.utc? + def format_time time, utc = time.utc? + if utc time.strftime("%Y-%m-%d %H:%M:%S.%9N Z") else time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z") end end + def format_date date + date.strftime("%Y-%m-%d") + end + def register target, yaml_obj @st.register target, yaml_obj yaml_obj @@ -568,7 +607,7 @@ module Psych raise BadAlias, "Tried to dump an aliased object" end - unless @permitted_classes[target.class] + unless Symbol === target || @permitted_classes[target.class] raise DisallowedClass.new('dump', target.class.name || target.class.inspect) end @@ -576,7 +615,7 @@ module Psych end def visit_Symbol sym - unless @permitted_symbols[sym] + unless @permitted_classes[Symbol] || @permitted_symbols[sym] raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})") end diff --git a/ext/psych/psych.c b/ext/psych/psych.c index 8af0bb6a5a..afbd7a3571 100644 --- a/ext/psych/psych.c +++ b/ext/psych/psych.c @@ -23,7 +23,7 @@ VALUE mPsych; void Init_psych(void) { #ifdef HAVE_RB_EXT_RACTOR_SAFE - RB_EXT_RACTOR_SAFE(true); + RB_EXT_RACTOR_SAFE(true); #endif mPsych = rb_define_module("Psych"); @@ -34,4 +34,3 @@ void Init_psych(void) Init_psych_to_ruby(); Init_psych_yaml_tree(); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec index e9e36e6633..a32f79bc16 100644 --- a/ext/psych/psych.gemspec +++ b/ext/psych/psych.gemspec @@ -21,31 +21,41 @@ DESCRIPTION s.licenses = ["MIT"] s.require_paths = ["lib"] - # for ruby core repository. It was generated by `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + # for ruby core repository. + # It was generated by + # `git ls-files -z`.split("\x0").reject { |f| + # f.match(%r{^\.git|^(test|spec|features|bin|tool)/|^[A-Z]\w+file$|/extlibs$|\.(gemspec|java)$|jar}) + # } s.files = [ - ".gitignore", "Gemfile", "LICENSE", "Mavenfile", "README.md", "Rakefile", "bin/console", - "bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h", - "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h", - "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h", - "ext/psych/yaml/LICENSE", "ext/psych/yaml/api.c", "ext/psych/yaml/config.h", "ext/psych/yaml/dumper.c", - "ext/psych/yaml/emitter.c", "ext/psych/yaml/loader.c", "ext/psych/yaml/parser.c", "ext/psych/yaml/reader.c", - "ext/psych/yaml/scanner.c", "ext/psych/yaml/writer.c", "ext/psych/yaml/yaml.h", "ext/psych/yaml/yaml_private.h", - "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", "lib/psych/core_ext.rb", "lib/psych/exception.rb", - "lib/psych/handler.rb", "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb", - "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", "lib/psych/json/tree_builder.rb", - "lib/psych/json/yaml_events.rb", "lib/psych/nodes.rb", "lib/psych/nodes/alias.rb", "lib/psych/nodes/document.rb", - "lib/psych/nodes/mapping.rb", "lib/psych/nodes/node.rb", "lib/psych/nodes/scalar.rb", "lib/psych/nodes/sequence.rb", - "lib/psych/nodes/stream.rb", "lib/psych/omap.rb", "lib/psych/parser.rb", "lib/psych/scalar_scanner.rb", - "lib/psych/set.rb", "lib/psych/stream.rb", "lib/psych/streaming.rb", "lib/psych/syntax_error.rb", - "lib/psych/tree_builder.rb", "lib/psych/versions.rb", "lib/psych/visitors.rb","lib/psych/visitors/depth_first.rb", - "lib/psych/visitors/emitter.rb", "lib/psych/visitors/json_tree.rb", "lib/psych/visitors/to_ruby.rb", - "lib/psych/visitors/visitor.rb", "lib/psych/visitors/yaml_tree.rb", "lib/psych/y.rb", "psych.gemspec" + "CONTRIBUTING.md", "LICENSE", "README.md", "ext/psych/depend", + "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h", + "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", + "ext/psych/psych_parser.c", "ext/psych/psych_parser.h", + "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", + "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h", + "lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", + "lib/psych/core_ext.rb", "lib/psych/exception.rb", "lib/psych/handler.rb", + "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb", + "lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", + "lib/psych/json/tree_builder.rb", "lib/psych/json/yaml_events.rb", + "lib/psych/nodes.rb", "lib/psych/nodes/alias.rb", + "lib/psych/nodes/document.rb", "lib/psych/nodes/mapping.rb", + "lib/psych/nodes/node.rb", "lib/psych/nodes/scalar.rb", + "lib/psych/nodes/sequence.rb", "lib/psych/nodes/stream.rb", + "lib/psych/omap.rb", "lib/psych/parser.rb", "lib/psych/scalar_scanner.rb", + "lib/psych/set.rb", "lib/psych/stream.rb", "lib/psych/streaming.rb", + "lib/psych/syntax_error.rb", "lib/psych/tree_builder.rb", + "lib/psych/versions.rb", "lib/psych/visitors.rb", + "lib/psych/visitors/depth_first.rb", "lib/psych/visitors/emitter.rb", + "lib/psych/visitors/json_tree.rb", "lib/psych/visitors/to_ruby.rb", + "lib/psych/visitors/visitor.rb", "lib/psych/visitors/yaml_tree.rb", + "lib/psych/y.rb" ] s.rdoc_options = ["--main", "README.md"] s.extra_rdoc_files = ["README.md"] - s.required_ruby_version = Gem::Requirement.new(">= 2.4.0") + s.required_ruby_version = Gem::Requirement.new(">= 2.5.0") s.required_rubygems_version = Gem::Requirement.new(">= 0") if RUBY_ENGINE == 'jruby' @@ -55,13 +65,18 @@ DESCRIPTION "ext/java/org/jruby/ext/psych/PsychLibrary.java", "ext/java/org/jruby/ext/psych/PsychParser.java", "ext/java/org/jruby/ext/psych/PsychToRuby.java", - "ext/java/org/jruby/ext/psych/PsychYamlTree.java", "lib/psych_jars.rb", "lib/psych.jar" ] - s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}" + s.requirements = "jar org.snakeyaml:snakeyaml-engine, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}" s.add_dependency 'jar-dependencies', '>= 0.1.7' else s.extensions = ["ext/psych/extconf.rb"] + s.add_dependency 'stringio' end + + s.add_dependency 'date' + + s.metadata['msys2_mingw_dependencies'] = 'libyaml' + s.metadata['changelog_uri'] = s.homepage + '/releases' end diff --git a/ext/psych/psych_emitter.c b/ext/psych/psych_emitter.c index 022ffa0946..624ab7c528 100644 --- a/ext/psych/psych_emitter.c +++ b/ext/psych/psych_emitter.c @@ -17,7 +17,7 @@ static ID id_canonical; static void emit(yaml_emitter_t * emitter, yaml_event_t * event) { if(!yaml_emitter_emit(emitter, event)) - rb_raise(rb_eRuntimeError, "%s", emitter->problem); + rb_raise(rb_eRuntimeError, "%s", emitter->problem); } static int writer(void *ctx, unsigned char *buffer, size_t size) @@ -82,13 +82,13 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self) TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); if (rb_scan_args(argc, argv, "11", &io, &options) == 2) { - line_width = rb_funcall(options, id_line_width, 0); - indent = rb_funcall(options, id_indentation, 0); - canonical = rb_funcall(options, id_canonical, 0); + line_width = rb_funcall(options, id_line_width, 0); + indent = rb_funcall(options, id_indentation, 0); + canonical = rb_funcall(options, id_canonical, 0); - yaml_emitter_set_width(emitter, NUM2INT(line_width)); - yaml_emitter_set_indent(emitter, NUM2INT(indent)); - yaml_emitter_set_canonical(emitter, Qtrue == canonical ? 1 : 0); + yaml_emitter_set_width(emitter, NUM2INT(line_width)); + yaml_emitter_set_indent(emitter, NUM2INT(indent)); + yaml_emitter_set_canonical(emitter, Qtrue == canonical ? 1 : 0); } rb_ivar_set(self, id_io, io); @@ -136,84 +136,118 @@ static VALUE end_stream(VALUE self) return self; } -/* call-seq: emitter.start_document(version, tags, implicit) - * - * Start a document emission with YAML +version+, +tags+, and an +implicit+ - * start. - * - * See Psych::Handler#start_document - */ -static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) +struct start_document_data { + VALUE self; + VALUE version; + VALUE tags; + VALUE imp; + + yaml_tag_directive_t * head; +}; + +static VALUE start_document_try(VALUE d) { + struct start_document_data * data = (struct start_document_data *)d; + VALUE self = data->self; + VALUE version = data->version; + VALUE tags = data->tags; + VALUE imp = data->imp; + yaml_emitter_t * emitter; - yaml_tag_directive_t * head = NULL; yaml_tag_directive_t * tail = NULL; yaml_event_t event; yaml_version_directive_t version_directive; TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); - Check_Type(version, T_ARRAY); if(RARRAY_LEN(version) > 0) { - VALUE major = rb_ary_entry(version, (long)0); - VALUE minor = rb_ary_entry(version, (long)1); + VALUE major = rb_ary_entry(version, (long)0); + VALUE minor = rb_ary_entry(version, (long)1); - version_directive.major = NUM2INT(major); - version_directive.minor = NUM2INT(minor); + version_directive.major = NUM2INT(major); + version_directive.minor = NUM2INT(minor); } if(RTEST(tags)) { - long i = 0; - long len; - rb_encoding * encoding = rb_utf8_encoding(); - - Check_Type(tags, T_ARRAY); - - len = RARRAY_LEN(tags); - head = xcalloc((size_t)len, sizeof(yaml_tag_directive_t)); - tail = head; - - for(i = 0; i < len && i < RARRAY_LEN(tags); i++) { - VALUE tuple = RARRAY_AREF(tags, i); - VALUE name; - VALUE value; - - Check_Type(tuple, T_ARRAY); - - if(RARRAY_LEN(tuple) < 2) { - xfree(head); - rb_raise(rb_eRuntimeError, "tag tuple must be of length 2"); - } - name = RARRAY_AREF(tuple, 0); - value = RARRAY_AREF(tuple, 1); - StringValue(name); - StringValue(value); - name = rb_str_export_to_enc(name, encoding); - value = rb_str_export_to_enc(value, encoding); - - tail->handle = (yaml_char_t *)StringValueCStr(name); - tail->prefix = (yaml_char_t *)StringValueCStr(value); - - tail++; - } + long i = 0; + long len; + rb_encoding * encoding = rb_utf8_encoding(); + + Check_Type(tags, T_ARRAY); + + len = RARRAY_LEN(tags); + data->head = xcalloc((size_t)len, sizeof(yaml_tag_directive_t)); + tail = data->head; + + for(i = 0; i < len && i < RARRAY_LEN(tags); i++) { + VALUE tuple = RARRAY_AREF(tags, i); + VALUE name; + VALUE value; + + Check_Type(tuple, T_ARRAY); + + if(RARRAY_LEN(tuple) < 2) { + rb_raise(rb_eRuntimeError, "tag tuple must be of length 2"); + } + + name = RARRAY_AREF(tuple, 0); + value = RARRAY_AREF(tuple, 1); + StringValue(name); + StringValue(value); + name = rb_str_export_to_enc(name, encoding); + value = rb_str_export_to_enc(value, encoding); + + tail->handle = (yaml_char_t *)StringValueCStr(name); + tail->prefix = (yaml_char_t *)StringValueCStr(value); + + tail++; + } } yaml_document_start_event_initialize( - &event, - (RARRAY_LEN(version) > 0) ? &version_directive : NULL, - head, - tail, - imp ? 1 : 0 - ); + &event, + (RARRAY_LEN(version) > 0) ? &version_directive : NULL, + data->head, + tail, + imp ? 1 : 0 + ); emit(emitter, &event); - if(head) xfree(head); - return self; } +static VALUE start_document_ensure(VALUE d) +{ + struct start_document_data * data = (struct start_document_data *)d; + + xfree(data->head); + + return Qnil; +} + +/* call-seq: emitter.start_document(version, tags, implicit) + * + * Start a document emission with YAML +version+, +tags+, and an +implicit+ + * start. + * + * See Psych::Handler#start_document + */ +static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) +{ + struct start_document_data data = { + .self = self, + .version = version, + .tags = tags, + .imp = imp, + + .head = NULL, + }; + + return rb_ensure(start_document_try, (VALUE)&data, start_document_ensure, (VALUE)&data); +} + /* call-seq: emitter.end_document(implicit) * * End a document emission with an +implicit+ ending. @@ -241,14 +275,14 @@ static VALUE end_document(VALUE self, VALUE imp) * See Psych::Handler#scalar */ static VALUE scalar( - VALUE self, - VALUE value, - VALUE anchor, - VALUE tag, - VALUE plain, - VALUE quoted, - VALUE style - ) { + VALUE self, + VALUE value, + VALUE anchor, + VALUE tag, + VALUE plain, + VALUE quoted, + VALUE style + ) { yaml_emitter_t * emitter; yaml_event_t event; rb_encoding *encoding; @@ -261,25 +295,26 @@ static VALUE scalar( value = rb_str_export_to_enc(value, encoding); if(!NIL_P(anchor)) { - Check_Type(anchor, T_STRING); - anchor = rb_str_export_to_enc(anchor, encoding); + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); } if(!NIL_P(tag)) { - Check_Type(tag, T_STRING); - tag = rb_str_export_to_enc(tag, encoding); + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); } + const char *value_ptr = StringValuePtr(value); yaml_scalar_event_initialize( - &event, - (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), - (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), - (yaml_char_t*)StringValuePtr(value), - (int)RSTRING_LEN(value), - plain ? 1 : 0, - quoted ? 1 : 0, - (yaml_scalar_style_t)NUM2INT(style) - ); + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + (yaml_char_t*)value_ptr, + (int)RSTRING_LEN(value), + plain ? 1 : 0, + quoted ? 1 : 0, + (yaml_scalar_style_t)NUM2INT(style) + ); emit(emitter, &event); @@ -294,36 +329,36 @@ static VALUE scalar( * See Psych::Handler#start_sequence */ static VALUE start_sequence( - VALUE self, - VALUE anchor, - VALUE tag, - VALUE implicit, - VALUE style - ) { + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { yaml_emitter_t * emitter; yaml_event_t event; rb_encoding * encoding = rb_utf8_encoding(); if(!NIL_P(anchor)) { - Check_Type(anchor, T_STRING); - anchor = rb_str_export_to_enc(anchor, encoding); + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); } if(!NIL_P(tag)) { - Check_Type(tag, T_STRING); - tag = rb_str_export_to_enc(tag, encoding); + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); } TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); yaml_sequence_start_event_initialize( - &event, - (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), - (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), - implicit ? 1 : 0, - (yaml_sequence_style_t)NUM2INT(style) - ); + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + implicit ? 1 : 0, + (yaml_sequence_style_t)NUM2INT(style) + ); emit(emitter, &event); @@ -357,12 +392,12 @@ static VALUE end_sequence(VALUE self) * See Psych::Handler#start_mapping */ static VALUE start_mapping( - VALUE self, - VALUE anchor, - VALUE tag, - VALUE implicit, - VALUE style - ) { + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { yaml_emitter_t * emitter; yaml_event_t event; rb_encoding *encoding; @@ -372,22 +407,22 @@ static VALUE start_mapping( encoding = rb_utf8_encoding(); if(!NIL_P(anchor)) { - Check_Type(anchor, T_STRING); - anchor = rb_str_export_to_enc(anchor, encoding); + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); } if(!NIL_P(tag)) { - Check_Type(tag, T_STRING); - tag = rb_str_export_to_enc(tag, encoding); + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); } yaml_mapping_start_event_initialize( - &event, - (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), - (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), - implicit ? 1 : 0, - (yaml_mapping_style_t)NUM2INT(style) - ); + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + implicit ? 1 : 0, + (yaml_mapping_style_t)NUM2INT(style) + ); emit(emitter, &event); @@ -426,14 +461,14 @@ static VALUE alias(VALUE self, VALUE anchor) TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); if(!NIL_P(anchor)) { - Check_Type(anchor, T_STRING); - anchor = rb_str_export_to_enc(anchor, rb_utf8_encoding()); + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, rb_utf8_encoding()); } yaml_alias_event_initialize( - &event, - (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)) - ); + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)) + ); emit(emitter, &event); @@ -552,4 +587,3 @@ void Init_psych_emitter(void) id_indentation = rb_intern("indentation"); id_canonical = rb_intern("canonical"); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_parser.c b/ext/psych/psych_parser.c index fd550b671a..d973496284 100644 --- a/ext/psych/psych_parser.c +++ b/ext/psych/psych_parser.c @@ -32,9 +32,9 @@ static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read) *read = 0; if(! NIL_P(string)) { - void * str = (void *)StringValuePtr(string); - *read = (size_t)RSTRING_LEN(string); - memcpy(buf, str, *read); + void * str = (void *)StringValuePtr(string); + *read = (size_t)RSTRING_LEN(string); + memcpy(buf, str, *read); } return 1; @@ -79,21 +79,25 @@ static VALUE allocate(VALUE klass) static VALUE make_exception(yaml_parser_t * parser, VALUE path) { - size_t line, column; - VALUE ePsychSyntaxError; + if (parser->error == YAML_MEMORY_ERROR) { + return rb_eNoMemError; + } else { + size_t line, column; + VALUE ePsychSyntaxError; - line = parser->context_mark.line + 1; - column = parser->context_mark.column + 1; + line = parser->context_mark.line + 1; + column = parser->context_mark.column + 1; - ePsychSyntaxError = rb_const_get(mPsych, rb_intern("SyntaxError")); + ePsychSyntaxError = rb_const_get(mPsych, rb_intern("SyntaxError")); - return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6, - path, - SIZET2NUM(line), - SIZET2NUM(column), - SIZET2NUM(parser->problem_offset), - parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil, - parser->context ? rb_usascii_str_new2(parser->context) : Qnil); + return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6, + path, + SIZET2NUM(line), + SIZET2NUM(column), + SIZET2NUM(parser->problem_offset), + parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil, + parser->context ? rb_usascii_str_new2(parser->context) : Qnil); + } } static VALUE transcode_string(VALUE src, int * parser_encoding) @@ -104,18 +108,18 @@ static VALUE transcode_string(VALUE src, int * parser_encoding) int source_encoding = rb_enc_get_index(src); if (source_encoding == utf8) { - *parser_encoding = YAML_UTF8_ENCODING; - return src; + *parser_encoding = YAML_UTF8_ENCODING; + return src; } if (source_encoding == utf16le) { - *parser_encoding = YAML_UTF16LE_ENCODING; - return src; + *parser_encoding = YAML_UTF16LE_ENCODING; + return src; } if (source_encoding == utf16be) { - *parser_encoding = YAML_UTF16BE_ENCODING; - return src; + *parser_encoding = YAML_UTF16BE_ENCODING; + return src; } src = rb_str_export_to_enc(src, rb_utf8_encoding()); @@ -134,36 +138,36 @@ static VALUE transcode_io(VALUE src, int * parser_encoding) /* if no encoding is returned, assume ascii8bit. */ if (NIL_P(io_external_encoding)) { - io_external_enc_index = rb_ascii8bit_encindex(); + io_external_enc_index = rb_ascii8bit_encindex(); } else { - io_external_enc_index = rb_to_encoding_index(io_external_encoding); + io_external_enc_index = rb_to_encoding_index(io_external_encoding); } /* Treat US-ASCII as utf_8 */ if (io_external_enc_index == rb_usascii_encindex()) { - *parser_encoding = YAML_UTF8_ENCODING; - return src; + *parser_encoding = YAML_UTF8_ENCODING; + return src; } if (io_external_enc_index == rb_utf8_encindex()) { - *parser_encoding = YAML_UTF8_ENCODING; - return src; + *parser_encoding = YAML_UTF8_ENCODING; + return src; } if (io_external_enc_index == rb_enc_find_index("UTF-16LE")) { - *parser_encoding = YAML_UTF16LE_ENCODING; - return src; + *parser_encoding = YAML_UTF16LE_ENCODING; + return src; } if (io_external_enc_index == rb_enc_find_index("UTF-16BE")) { - *parser_encoding = YAML_UTF16BE_ENCODING; - return src; + *parser_encoding = YAML_UTF16BE_ENCODING; + return src; } /* Just guess on ASCII-8BIT */ if (io_external_enc_index == rb_ascii8bit_encindex()) { - *parser_encoding = YAML_ANY_ENCODING; - return src; + *parser_encoding = YAML_ANY_ENCODING; + return src; } /* If the external encoding is something we don't know how to handle, @@ -241,18 +245,8 @@ static VALUE protected_event_location(VALUE pointer) return rb_funcall3(args[0], id_event_location, 4, args + 1); } -/* - * call-seq: - * parser.parse(yaml) - * - * Parse the YAML document contained in +yaml+. Events will be called on - * the handler set on the parser instance. - * - * See Psych::Parser and Psych::Parser#handler - */ -static VALUE parse(int argc, VALUE *argv, VALUE self) +static VALUE parse(VALUE self, VALUE handler, VALUE yaml, VALUE path) { - VALUE yaml, path; yaml_parser_t * parser; yaml_event_t event; int done = 0; @@ -260,14 +254,6 @@ static VALUE parse(int argc, VALUE *argv, VALUE self) int parser_encoding = YAML_ANY_ENCODING; int encoding = rb_utf8_encindex(); rb_encoding * internal_enc = rb_default_internal_encoding(); - VALUE handler = rb_iv_get(self, "@handler"); - - if (rb_scan_args(argc, argv, "11", &yaml, &path) == 1) { - if(rb_respond_to(yaml, id_path)) - path = rb_funcall(yaml, id_path, 0); - else - path = rb_str_new2("<unknown>"); - } TypedData_Get_Struct(self, yaml_parser_t, &psych_parser_type, parser); @@ -275,238 +261,238 @@ static VALUE parse(int argc, VALUE *argv, VALUE self) yaml_parser_initialize(parser); if (rb_respond_to(yaml, id_read)) { - yaml = transcode_io(yaml, &parser_encoding); - yaml_parser_set_encoding(parser, parser_encoding); - yaml_parser_set_input(parser, io_reader, (void *)yaml); + yaml = transcode_io(yaml, &parser_encoding); + yaml_parser_set_encoding(parser, parser_encoding); + yaml_parser_set_input(parser, io_reader, (void *)yaml); } else { - StringValue(yaml); - yaml = transcode_string(yaml, &parser_encoding); - yaml_parser_set_encoding(parser, parser_encoding); - yaml_parser_set_input_string( - parser, - (const unsigned char *)RSTRING_PTR(yaml), - (size_t)RSTRING_LEN(yaml) - ); + StringValue(yaml); + yaml = transcode_string(yaml, &parser_encoding); + yaml_parser_set_encoding(parser, parser_encoding); + yaml_parser_set_input_string( + parser, + (const unsigned char *)RSTRING_PTR(yaml), + (size_t)RSTRING_LEN(yaml) + ); } while(!done) { - VALUE event_args[5]; - VALUE start_line, start_column, end_line, end_column; - - if(!yaml_parser_parse(parser, &event)) { - VALUE exception; - - exception = make_exception(parser, path); - yaml_parser_delete(parser); - yaml_parser_initialize(parser); - - rb_exc_raise(exception); - } - - start_line = SIZET2NUM(event.start_mark.line); - start_column = SIZET2NUM(event.start_mark.column); - end_line = SIZET2NUM(event.end_mark.line); - end_column = SIZET2NUM(event.end_mark.column); - - event_args[0] = handler; - event_args[1] = start_line; - event_args[2] = start_column; - event_args[3] = end_line; - event_args[4] = end_column; - rb_protect(protected_event_location, (VALUE)event_args, &state); - - switch(event.type) { - case YAML_STREAM_START_EVENT: - { - VALUE args[2]; - - args[0] = handler; - args[1] = INT2NUM(event.data.stream_start.encoding); - rb_protect(protected_start_stream, (VALUE)args, &state); - } - break; - case YAML_DOCUMENT_START_EVENT: - { - VALUE args[4]; - /* Get a list of tag directives (if any) */ - VALUE tag_directives = rb_ary_new(); - /* Grab the document version */ - VALUE version = event.data.document_start.version_directive ? - rb_ary_new3( - (long)2, - INT2NUM(event.data.document_start.version_directive->major), - INT2NUM(event.data.document_start.version_directive->minor) - ) : rb_ary_new(); - - if(event.data.document_start.tag_directives.start) { - yaml_tag_directive_t *start = - event.data.document_start.tag_directives.start; - yaml_tag_directive_t *end = - event.data.document_start.tag_directives.end; - for(; start != end; start++) { - VALUE handle = Qnil; - VALUE prefix = Qnil; - if(start->handle) { - handle = rb_str_new2((const char *)start->handle); - PSYCH_TRANSCODE(handle, encoding, internal_enc); - } - - if(start->prefix) { - prefix = rb_str_new2((const char *)start->prefix); - PSYCH_TRANSCODE(prefix, encoding, internal_enc); - } - - rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); - } - } - args[0] = handler; - args[1] = version; - args[2] = tag_directives; - args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse; - rb_protect(protected_start_document, (VALUE)args, &state); - } - break; - case YAML_DOCUMENT_END_EVENT: - { - VALUE args[2]; - - args[0] = handler; - args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse; - rb_protect(protected_end_document, (VALUE)args, &state); - } - break; - case YAML_ALIAS_EVENT: - { - VALUE args[2]; - VALUE alias = Qnil; - if(event.data.alias.anchor) { - alias = rb_str_new2((const char *)event.data.alias.anchor); - PSYCH_TRANSCODE(alias, encoding, internal_enc); - } - - args[0] = handler; - args[1] = alias; - rb_protect(protected_alias, (VALUE)args, &state); - } - break; - case YAML_SCALAR_EVENT: - { - VALUE args[7]; - VALUE anchor = Qnil; - VALUE tag = Qnil; - VALUE plain_implicit, quoted_implicit, style; - VALUE val = rb_str_new( - (const char *)event.data.scalar.value, - (long)event.data.scalar.length - ); - - PSYCH_TRANSCODE(val, encoding, internal_enc); - - if(event.data.scalar.anchor) { - anchor = rb_str_new2((const char *)event.data.scalar.anchor); - PSYCH_TRANSCODE(anchor, encoding, internal_enc); - } - - if(event.data.scalar.tag) { - tag = rb_str_new2((const char *)event.data.scalar.tag); - PSYCH_TRANSCODE(tag, encoding, internal_enc); - } - - plain_implicit = - event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; - - quoted_implicit = - event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; - - style = INT2NUM(event.data.scalar.style); - - args[0] = handler; - args[1] = val; - args[2] = anchor; - args[3] = tag; - args[4] = plain_implicit; - args[5] = quoted_implicit; - args[6] = style; - rb_protect(protected_scalar, (VALUE)args, &state); - } - break; - case YAML_SEQUENCE_START_EVENT: - { - VALUE args[5]; - VALUE anchor = Qnil; - VALUE tag = Qnil; - VALUE implicit, style; - if(event.data.sequence_start.anchor) { - anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); - PSYCH_TRANSCODE(anchor, encoding, internal_enc); - } - - tag = Qnil; - if(event.data.sequence_start.tag) { - tag = rb_str_new2((const char *)event.data.sequence_start.tag); - PSYCH_TRANSCODE(tag, encoding, internal_enc); - } - - implicit = - event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; - - style = INT2NUM(event.data.sequence_start.style); - - args[0] = handler; - args[1] = anchor; - args[2] = tag; - args[3] = implicit; - args[4] = style; - - rb_protect(protected_start_sequence, (VALUE)args, &state); - } - break; - case YAML_SEQUENCE_END_EVENT: - rb_protect(protected_end_sequence, handler, &state); - break; - case YAML_MAPPING_START_EVENT: - { - VALUE args[5]; - VALUE anchor = Qnil; - VALUE tag = Qnil; - VALUE implicit, style; - if(event.data.mapping_start.anchor) { - anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); - PSYCH_TRANSCODE(anchor, encoding, internal_enc); - } - - if(event.data.mapping_start.tag) { - tag = rb_str_new2((const char *)event.data.mapping_start.tag); - PSYCH_TRANSCODE(tag, encoding, internal_enc); - } - - implicit = - event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; - - style = INT2NUM(event.data.mapping_start.style); - - args[0] = handler; - args[1] = anchor; - args[2] = tag; - args[3] = implicit; - args[4] = style; - - rb_protect(protected_start_mapping, (VALUE)args, &state); - } - break; - case YAML_MAPPING_END_EVENT: - rb_protect(protected_end_mapping, handler, &state); - break; - case YAML_NO_EVENT: - rb_protect(protected_empty, handler, &state); - break; - case YAML_STREAM_END_EVENT: - rb_protect(protected_end_stream, handler, &state); - done = 1; - break; - } - yaml_event_delete(&event); - if (state) rb_jump_tag(state); + VALUE event_args[5]; + VALUE start_line, start_column, end_line, end_column; + + if(parser->error || !yaml_parser_parse(parser, &event)) { + VALUE exception; + + exception = make_exception(parser, path); + yaml_parser_delete(parser); + yaml_parser_initialize(parser); + + rb_exc_raise(exception); + } + + start_line = SIZET2NUM(event.start_mark.line); + start_column = SIZET2NUM(event.start_mark.column); + end_line = SIZET2NUM(event.end_mark.line); + end_column = SIZET2NUM(event.end_mark.column); + + event_args[0] = handler; + event_args[1] = start_line; + event_args[2] = start_column; + event_args[3] = end_line; + event_args[4] = end_column; + rb_protect(protected_event_location, (VALUE)event_args, &state); + + switch(event.type) { + case YAML_STREAM_START_EVENT: + { + VALUE args[2]; + + args[0] = handler; + args[1] = INT2NUM(event.data.stream_start.encoding); + rb_protect(protected_start_stream, (VALUE)args, &state); + } + break; + case YAML_DOCUMENT_START_EVENT: + { + VALUE args[4]; + /* Get a list of tag directives (if any) */ + VALUE tag_directives = rb_ary_new(); + /* Grab the document version */ + VALUE version = event.data.document_start.version_directive ? + rb_ary_new3( + (long)2, + INT2NUM(event.data.document_start.version_directive->major), + INT2NUM(event.data.document_start.version_directive->minor) + ) : rb_ary_new(); + + if(event.data.document_start.tag_directives.start) { + yaml_tag_directive_t *start = + event.data.document_start.tag_directives.start; + yaml_tag_directive_t *end = + event.data.document_start.tag_directives.end; + for(; start != end; start++) { + VALUE handle = Qnil; + VALUE prefix = Qnil; + if(start->handle) { + handle = rb_str_new2((const char *)start->handle); + PSYCH_TRANSCODE(handle, encoding, internal_enc); + } + + if(start->prefix) { + prefix = rb_str_new2((const char *)start->prefix); + PSYCH_TRANSCODE(prefix, encoding, internal_enc); + } + + rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); + } + } + args[0] = handler; + args[1] = version; + args[2] = tag_directives; + args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse; + rb_protect(protected_start_document, (VALUE)args, &state); + } + break; + case YAML_DOCUMENT_END_EVENT: + { + VALUE args[2]; + + args[0] = handler; + args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse; + rb_protect(protected_end_document, (VALUE)args, &state); + } + break; + case YAML_ALIAS_EVENT: + { + VALUE args[2]; + VALUE alias = Qnil; + if(event.data.alias.anchor) { + alias = rb_str_new2((const char *)event.data.alias.anchor); + PSYCH_TRANSCODE(alias, encoding, internal_enc); + } + + args[0] = handler; + args[1] = alias; + rb_protect(protected_alias, (VALUE)args, &state); + } + break; + case YAML_SCALAR_EVENT: + { + VALUE args[7]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE plain_implicit, quoted_implicit, style; + VALUE val = rb_str_new( + (const char *)event.data.scalar.value, + (long)event.data.scalar.length + ); + + PSYCH_TRANSCODE(val, encoding, internal_enc); + + if(event.data.scalar.anchor) { + anchor = rb_str_new2((const char *)event.data.scalar.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + if(event.data.scalar.tag) { + tag = rb_str_new2((const char *)event.data.scalar.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + plain_implicit = + event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; + + quoted_implicit = + event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.scalar.style); + + args[0] = handler; + args[1] = val; + args[2] = anchor; + args[3] = tag; + args[4] = plain_implicit; + args[5] = quoted_implicit; + args[6] = style; + rb_protect(protected_scalar, (VALUE)args, &state); + } + break; + case YAML_SEQUENCE_START_EVENT: + { + VALUE args[5]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.sequence_start.anchor) { + anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + tag = Qnil; + if(event.data.sequence_start.tag) { + tag = rb_str_new2((const char *)event.data.sequence_start.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + implicit = + event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.sequence_start.style); + + args[0] = handler; + args[1] = anchor; + args[2] = tag; + args[3] = implicit; + args[4] = style; + + rb_protect(protected_start_sequence, (VALUE)args, &state); + } + break; + case YAML_SEQUENCE_END_EVENT: + rb_protect(protected_end_sequence, handler, &state); + break; + case YAML_MAPPING_START_EVENT: + { + VALUE args[5]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.mapping_start.anchor) { + anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + if(event.data.mapping_start.tag) { + tag = rb_str_new2((const char *)event.data.mapping_start.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + implicit = + event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.mapping_start.style); + + args[0] = handler; + args[1] = anchor; + args[2] = tag; + args[3] = implicit; + args[4] = style; + + rb_protect(protected_start_mapping, (VALUE)args, &state); + } + break; + case YAML_MAPPING_END_EVENT: + rb_protect(protected_end_mapping, handler, &state); + break; + case YAML_NO_EVENT: + rb_protect(protected_empty, handler, &state); + break; + case YAML_STREAM_END_EVENT: + rb_protect(protected_end_stream, handler, &state); + done = 1; + break; + } + yaml_event_delete(&event); + if (state) rb_jump_tag(state); } return self; @@ -558,7 +544,7 @@ void Init_psych_parser(void) rb_require("psych/syntax_error"); - rb_define_method(cPsychParser, "parse", parse, -1); + rb_define_private_method(cPsychParser, "_native_parse", parse, 3); rb_define_method(cPsychParser, "mark", mark, 0); id_read = rb_intern("read"); @@ -576,4 +562,3 @@ void Init_psych_parser(void) id_end_mapping = rb_intern("end_mapping"); id_event_location = rb_intern("event_location"); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_to_ruby.c b/ext/psych/psych_to_ruby.c index b388ff7754..3ab0138b52 100644 --- a/ext/psych/psych_to_ruby.c +++ b/ext/psych/psych_to_ruby.c @@ -10,7 +10,11 @@ static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg) { VALUE e = rb_obj_alloc(klass); +#ifdef TRUFFLERUBY + rb_exc_set_message(e, mesg); +#else rb_iv_set(e, "mesg", mesg); +#endif return e; } @@ -36,4 +40,3 @@ void Init_psych_to_ruby(void) rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); rb_define_private_method(class_loader, "path2class", path2class, 1); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/psych_yaml_tree.c b/ext/psych/psych_yaml_tree.c index 225655d127..bbd93f874d 100644 --- a/ext/psych/psych_yaml_tree.c +++ b/ext/psych/psych_yaml_tree.c @@ -9,4 +9,3 @@ void Init_psych_yaml_tree(void) VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/psych/yaml/api.c b/ext/psych/yaml/api.c deleted file mode 100644 index 6add8b2661..0000000000 --- a/ext/psych/yaml/api.c +++ /dev/null @@ -1,1393 +0,0 @@ - -#include "yaml_private.h" - -/* - * Get the library version. - */ - -YAML_DECLARE(const char *) -yaml_get_version_string(void) -{ - return YAML_VERSION_STRING; -} - -/* - * Get the library version numbers. - */ - -YAML_DECLARE(void) -yaml_get_version(int *major, int *minor, int *patch) -{ - *major = YAML_VERSION_MAJOR; - *minor = YAML_VERSION_MINOR; - *patch = YAML_VERSION_PATCH; -} - -/* - * Allocate a dynamic memory block. - */ - -YAML_DECLARE(void *) -yaml_malloc(size_t size) -{ - return malloc(size ? size : 1); -} - -/* - * Reallocate a dynamic memory block. - */ - -YAML_DECLARE(void *) -yaml_realloc(void *ptr, size_t size) -{ - return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1); -} - -/* - * Free a dynamic memory block. - */ - -YAML_DECLARE(void) -yaml_free(void *ptr) -{ - if (ptr) free(ptr); -} - -/* - * Duplicate a string. - */ - -YAML_DECLARE(yaml_char_t *) -yaml_strdup(const yaml_char_t *str) -{ - if (!str) - return NULL; - - return (yaml_char_t *)strdup((char *)str); -} - -/* - * Extend a string. - */ - -YAML_DECLARE(int) -yaml_string_extend(yaml_char_t **start, - yaml_char_t **pointer, yaml_char_t **end) -{ - yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2); - - if (!new_start) return 0; - - memset(new_start + (*end - *start), 0, *end - *start); - - *pointer = new_start + (*pointer - *start); - *end = new_start + (*end - *start)*2; - *start = new_start; - - return 1; -} - -/* - * Append a string B to a string A. - */ - -YAML_DECLARE(int) -yaml_string_join( - yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, - yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end)) -{ - UNUSED_PARAM(b_end) - if (*b_start == *b_pointer) - return 1; - - while (*a_end - *a_pointer <= *b_pointer - *b_start) { - if (!yaml_string_extend(a_start, a_pointer, a_end)) - return 0; - } - - memcpy(*a_pointer, *b_start, *b_pointer - *b_start); - *a_pointer += *b_pointer - *b_start; - - return 1; -} - -/* - * Extend a stack. - */ - -YAML_DECLARE(int) -yaml_stack_extend(void **start, void **top, void **end) -{ - void *new_start; - - if ((char *)*end - (char *)*start >= INT_MAX / 2) - return 0; - - new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2); - - if (!new_start) return 0; - - *top = (char *)new_start + ((char *)*top - (char *)*start); - *end = (char *)new_start + ((char *)*end - (char *)*start)*2; - *start = new_start; - - return 1; -} - -/* - * Extend or move a queue. - */ - -YAML_DECLARE(int) -yaml_queue_extend(void **start, void **head, void **tail, void **end) -{ - /* Check if we need to resize the queue. */ - - if (*start == *head && *tail == *end) { - void *new_start = yaml_realloc(*start, - ((char *)*end - (char *)*start)*2); - - if (!new_start) return 0; - - *head = (char *)new_start + ((char *)*head - (char *)*start); - *tail = (char *)new_start + ((char *)*tail - (char *)*start); - *end = (char *)new_start + ((char *)*end - (char *)*start)*2; - *start = new_start; - } - - /* Check if we need to move the queue at the beginning of the buffer. */ - - if (*tail == *end) { - if (*head != *tail) { - memmove(*start, *head, (char *)*tail - (char *)*head); - } - *tail = (char *)*tail - (char *)*head + (char *)*start; - *head = *start; - } - - return 1; -} - - -/* - * Create a new parser object. - */ - -YAML_DECLARE(int) -yaml_parser_initialize(yaml_parser_t *parser) -{ - assert(parser); /* Non-NULL parser object expected. */ - - memset(parser, 0, sizeof(yaml_parser_t)); - if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE)) - goto error; - if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE)) - goto error; - if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*)) - goto error; - if (!STACK_INIT(parser, parser->indents, int*)) - goto error; - if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*)) - goto error; - if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*)) - goto error; - if (!STACK_INIT(parser, parser->marks, yaml_mark_t*)) - goto error; - if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*)) - goto error; - - return 1; - -error: - - BUFFER_DEL(parser, parser->raw_buffer); - BUFFER_DEL(parser, parser->buffer); - QUEUE_DEL(parser, parser->tokens); - STACK_DEL(parser, parser->indents); - STACK_DEL(parser, parser->simple_keys); - STACK_DEL(parser, parser->states); - STACK_DEL(parser, parser->marks); - STACK_DEL(parser, parser->tag_directives); - - return 0; -} - -/* - * Destroy a parser object. - */ - -YAML_DECLARE(void) -yaml_parser_delete(yaml_parser_t *parser) -{ - assert(parser); /* Non-NULL parser object expected. */ - - BUFFER_DEL(parser, parser->raw_buffer); - BUFFER_DEL(parser, parser->buffer); - while (!QUEUE_EMPTY(parser, parser->tokens)) { - yaml_token_delete(&DEQUEUE(parser, parser->tokens)); - } - QUEUE_DEL(parser, parser->tokens); - STACK_DEL(parser, parser->indents); - STACK_DEL(parser, parser->simple_keys); - STACK_DEL(parser, parser->states); - STACK_DEL(parser, parser->marks); - while (!STACK_EMPTY(parser, parser->tag_directives)) { - yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); - yaml_free(tag_directive.handle); - yaml_free(tag_directive.prefix); - } - STACK_DEL(parser, parser->tag_directives); - - memset(parser, 0, sizeof(yaml_parser_t)); -} - -/* - * String read handler. - */ - -static int -yaml_string_read_handler(void *data, unsigned char *buffer, size_t size, - size_t *size_read) -{ - yaml_parser_t *parser = (yaml_parser_t *)data; - - if (parser->input.string.current == parser->input.string.end) { - *size_read = 0; - return 1; - } - - if (size > (size_t)(parser->input.string.end - - parser->input.string.current)) { - size = parser->input.string.end - parser->input.string.current; - } - - memcpy(buffer, parser->input.string.current, size); - parser->input.string.current += size; - *size_read = size; - return 1; -} - -/* - * File read handler. - */ - -static int -yaml_file_read_handler(void *data, unsigned char *buffer, size_t size, - size_t *size_read) -{ - yaml_parser_t *parser = (yaml_parser_t *)data; - - *size_read = fread(buffer, 1, size, parser->input.file); - return !ferror(parser->input.file); -} - -/* - * Set a string input. - */ - -YAML_DECLARE(void) -yaml_parser_set_input_string(yaml_parser_t *parser, - const unsigned char *input, size_t size) -{ - assert(parser); /* Non-NULL parser object expected. */ - assert(!parser->read_handler); /* You can set the source only once. */ - assert(input); /* Non-NULL input string expected. */ - - parser->read_handler = yaml_string_read_handler; - parser->read_handler_data = parser; - - parser->input.string.start = input; - parser->input.string.current = input; - parser->input.string.end = input+size; -} - -/* - * Set a file input. - */ - -YAML_DECLARE(void) -yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file) -{ - assert(parser); /* Non-NULL parser object expected. */ - assert(!parser->read_handler); /* You can set the source only once. */ - assert(file); /* Non-NULL file object expected. */ - - parser->read_handler = yaml_file_read_handler; - parser->read_handler_data = parser; - - parser->input.file = file; -} - -/* - * Set a generic input. - */ - -YAML_DECLARE(void) -yaml_parser_set_input(yaml_parser_t *parser, - yaml_read_handler_t *handler, void *data) -{ - assert(parser); /* Non-NULL parser object expected. */ - assert(!parser->read_handler); /* You can set the source only once. */ - assert(handler); /* Non-NULL read handler expected. */ - - parser->read_handler = handler; - parser->read_handler_data = data; -} - -/* - * Set the source encoding. - */ - -YAML_DECLARE(void) -yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) -{ - assert(parser); /* Non-NULL parser object expected. */ - assert(!parser->encoding); /* Encoding is already set or detected. */ - - parser->encoding = encoding; -} - -/* - * Create a new emitter object. - */ - -YAML_DECLARE(int) -yaml_emitter_initialize(yaml_emitter_t *emitter) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - memset(emitter, 0, sizeof(yaml_emitter_t)); - if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE)) - goto error; - if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE)) - goto error; - if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*)) - goto error; - if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*)) - goto error; - if (!STACK_INIT(emitter, emitter->indents, int*)) - goto error; - if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*)) - goto error; - - return 1; - -error: - - BUFFER_DEL(emitter, emitter->buffer); - BUFFER_DEL(emitter, emitter->raw_buffer); - STACK_DEL(emitter, emitter->states); - QUEUE_DEL(emitter, emitter->events); - STACK_DEL(emitter, emitter->indents); - STACK_DEL(emitter, emitter->tag_directives); - - return 0; -} - -/* - * Destroy an emitter object. - */ - -YAML_DECLARE(void) -yaml_emitter_delete(yaml_emitter_t *emitter) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - BUFFER_DEL(emitter, emitter->buffer); - BUFFER_DEL(emitter, emitter->raw_buffer); - STACK_DEL(emitter, emitter->states); - while (!QUEUE_EMPTY(emitter, emitter->events)) { - yaml_event_delete(&DEQUEUE(emitter, emitter->events)); - } - QUEUE_DEL(emitter, emitter->events); - STACK_DEL(emitter, emitter->indents); - while (!STACK_EMPTY(empty, emitter->tag_directives)) { - yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); - yaml_free(tag_directive.handle); - yaml_free(tag_directive.prefix); - } - STACK_DEL(emitter, emitter->tag_directives); - yaml_free(emitter->anchors); - - memset(emitter, 0, sizeof(yaml_emitter_t)); -} - -/* - * String write handler. - */ - -static int -yaml_string_write_handler(void *data, unsigned char *buffer, size_t size) -{ - yaml_emitter_t *emitter = (yaml_emitter_t *)data; - - if (emitter->output.string.size - *emitter->output.string.size_written - < size) { - memcpy(emitter->output.string.buffer - + *emitter->output.string.size_written, - buffer, - emitter->output.string.size - - *emitter->output.string.size_written); - *emitter->output.string.size_written = emitter->output.string.size; - return 0; - } - - memcpy(emitter->output.string.buffer - + *emitter->output.string.size_written, buffer, size); - *emitter->output.string.size_written += size; - return 1; -} - -/* - * File write handler. - */ - -static int -yaml_file_write_handler(void *data, unsigned char *buffer, size_t size) -{ - yaml_emitter_t *emitter = (yaml_emitter_t *)data; - - return (fwrite(buffer, 1, size, emitter->output.file) == size); -} -/* - * Set a string output. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output_string(yaml_emitter_t *emitter, - unsigned char *output, size_t size, size_t *size_written) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - assert(!emitter->write_handler); /* You can set the output only once. */ - assert(output); /* Non-NULL output string expected. */ - - emitter->write_handler = yaml_string_write_handler; - emitter->write_handler_data = emitter; - - emitter->output.string.buffer = output; - emitter->output.string.size = size; - emitter->output.string.size_written = size_written; - *size_written = 0; -} - -/* - * Set a file output. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - assert(!emitter->write_handler); /* You can set the output only once. */ - assert(file); /* Non-NULL file object expected. */ - - emitter->write_handler = yaml_file_write_handler; - emitter->write_handler_data = emitter; - - emitter->output.file = file; -} - -/* - * Set a generic output handler. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output(yaml_emitter_t *emitter, - yaml_write_handler_t *handler, void *data) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - assert(!emitter->write_handler); /* You can set the output only once. */ - assert(handler); /* Non-NULL handler object expected. */ - - emitter->write_handler = handler; - emitter->write_handler_data = data; -} - -/* - * Set the output encoding. - */ - -YAML_DECLARE(void) -yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - assert(!emitter->encoding); /* You can set encoding only once. */ - - emitter->encoding = encoding; -} - -/* - * Set the canonical output style. - */ - -YAML_DECLARE(void) -yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - emitter->canonical = (canonical != 0); -} - -/* - * Set the indentation increment. - */ - -YAML_DECLARE(void) -yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; -} - -/* - * Set the preferred line width. - */ - -YAML_DECLARE(void) -yaml_emitter_set_width(yaml_emitter_t *emitter, int width) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - emitter->best_width = (width >= 0) ? width : -1; -} - -/* - * Set if unescaped non-ASCII characters are allowed. - */ - -YAML_DECLARE(void) -yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - emitter->unicode = (unicode != 0); -} - -/* - * Set the preferred line break character. - */ - -YAML_DECLARE(void) -yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) -{ - assert(emitter); /* Non-NULL emitter object expected. */ - - emitter->line_break = line_break; -} - -/* - * Destroy a token object. - */ - -YAML_DECLARE(void) -yaml_token_delete(yaml_token_t *token) -{ - assert(token); /* Non-NULL token object expected. */ - - switch (token->type) - { - case YAML_TAG_DIRECTIVE_TOKEN: - yaml_free(token->data.tag_directive.handle); - yaml_free(token->data.tag_directive.prefix); - break; - - case YAML_ALIAS_TOKEN: - yaml_free(token->data.alias.value); - break; - - case YAML_ANCHOR_TOKEN: - yaml_free(token->data.anchor.value); - break; - - case YAML_TAG_TOKEN: - yaml_free(token->data.tag.handle); - yaml_free(token->data.tag.suffix); - break; - - case YAML_SCALAR_TOKEN: - yaml_free(token->data.scalar.value); - break; - - default: - break; - } - - memset(token, 0, sizeof(yaml_token_t)); -} - -/* - * Check if a string is a valid UTF-8 sequence. - * - * Check 'reader.c' for more details on UTF-8 encoding. - */ - -static int -yaml_check_utf8(const yaml_char_t *start, size_t length) -{ - const yaml_char_t *end = start+length; - const yaml_char_t *pointer = start; - - while (pointer < end) { - unsigned char octet; - unsigned int width; - unsigned int value; - size_t k; - - octet = pointer[0]; - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; - value = (octet & 0x80) == 0x00 ? octet & 0x7F : - (octet & 0xE0) == 0xC0 ? octet & 0x1F : - (octet & 0xF0) == 0xE0 ? octet & 0x0F : - (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; - if (!width) return 0; - if (pointer+width > end) return 0; - for (k = 1; k < width; k ++) { - octet = pointer[k]; - if ((octet & 0xC0) != 0x80) return 0; - value = (value << 6) + (octet & 0x3F); - } - if (!((width == 1) || - (width == 2 && value >= 0x80) || - (width == 3 && value >= 0x800) || - (width == 4 && value >= 0x10000))) return 0; - - pointer += width; - } - - return 1; -} - -/* - * Create STREAM-START. - */ - -YAML_DECLARE(int) -yaml_stream_start_event_initialize(yaml_event_t *event, - yaml_encoding_t encoding) -{ - yaml_mark_t mark = { 0, 0, 0 }; - - assert(event); /* Non-NULL event object is expected. */ - - STREAM_START_EVENT_INIT(*event, encoding, mark, mark); - - return 1; -} - -/* - * Create STREAM-END. - */ - -YAML_DECLARE(int) -yaml_stream_end_event_initialize(yaml_event_t *event) -{ - yaml_mark_t mark = { 0, 0, 0 }; - - assert(event); /* Non-NULL event object is expected. */ - - STREAM_END_EVENT_INIT(*event, mark, mark); - - return 1; -} - -/* - * Create DOCUMENT-START. - */ - -YAML_DECLARE(int) -yaml_document_start_event_initialize(yaml_event_t *event, - yaml_version_directive_t *version_directive, - yaml_tag_directive_t *tag_directives_start, - yaml_tag_directive_t *tag_directives_end, - int implicit) -{ - struct { - yaml_error_type_t error; - } context; - yaml_mark_t mark = { 0, 0, 0 }; - yaml_version_directive_t *version_directive_copy = NULL; - struct { - yaml_tag_directive_t *start; - yaml_tag_directive_t *end; - yaml_tag_directive_t *top; - } tag_directives_copy = { NULL, NULL, NULL }; - yaml_tag_directive_t value = { NULL, NULL }; - - assert(event); /* Non-NULL event object is expected. */ - assert((tag_directives_start && tag_directives_end) || - (tag_directives_start == tag_directives_end)); - /* Valid tag directives are expected. */ - - if (version_directive) { - version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t); - if (!version_directive_copy) goto error; - version_directive_copy->major = version_directive->major; - version_directive_copy->minor = version_directive->minor; - } - - if (tag_directives_start != tag_directives_end) { - yaml_tag_directive_t *tag_directive; - if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*)) - goto error; - for (tag_directive = tag_directives_start; - tag_directive != tag_directives_end; tag_directive ++) { - assert(tag_directive->handle); - assert(tag_directive->prefix); - if (!yaml_check_utf8(tag_directive->handle, - strlen((char *)tag_directive->handle))) - goto error; - if (!yaml_check_utf8(tag_directive->prefix, - strlen((char *)tag_directive->prefix))) - goto error; - value.handle = yaml_strdup(tag_directive->handle); - value.prefix = yaml_strdup(tag_directive->prefix); - if (!value.handle || !value.prefix) goto error; - if (!PUSH(&context, tag_directives_copy, value)) - goto error; - value.handle = NULL; - value.prefix = NULL; - } - } - - DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, - tag_directives_copy.start, tag_directives_copy.top, - implicit, mark, mark); - - return 1; - -error: - yaml_free(version_directive_copy); - while (!STACK_EMPTY(context, tag_directives_copy)) { - yaml_tag_directive_t value = POP(context, tag_directives_copy); - yaml_free(value.handle); - yaml_free(value.prefix); - } - STACK_DEL(context, tag_directives_copy); - yaml_free(value.handle); - yaml_free(value.prefix); - - return 0; -} - -/* - * Create DOCUMENT-END. - */ - -YAML_DECLARE(int) -yaml_document_end_event_initialize(yaml_event_t *event, int implicit) -{ - yaml_mark_t mark = { 0, 0, 0 }; - - assert(event); /* Non-NULL emitter object is expected. */ - - DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark); - - return 1; -} - -/* - * Create ALIAS. - */ - -YAML_DECLARE(int) -yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor) -{ - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *anchor_copy = NULL; - - assert(event); /* Non-NULL event object is expected. */ - assert(anchor); /* Non-NULL anchor is expected. */ - - if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0; - - anchor_copy = yaml_strdup(anchor); - if (!anchor_copy) - return 0; - - ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); - - return 1; -} - -/* - * Create SCALAR. - */ - -YAML_DECLARE(int) -yaml_scalar_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, - const yaml_char_t *value, int length, - int plain_implicit, int quoted_implicit, - yaml_scalar_style_t style) -{ - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *anchor_copy = NULL; - yaml_char_t *tag_copy = NULL; - yaml_char_t *value_copy = NULL; - - assert(event); /* Non-NULL event object is expected. */ - assert(value); /* Non-NULL anchor is expected. */ - - if (anchor) { - if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; - anchor_copy = yaml_strdup(anchor); - if (!anchor_copy) goto error; - } - - if (tag) { - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - } - - if (length < 0) { - length = (int)strlen((char *)value); - } - - if (!yaml_check_utf8(value, length)) goto error; - value_copy = YAML_MALLOC(length+1); - if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; - - SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, - plain_implicit, quoted_implicit, style, mark, mark); - - return 1; - -error: - yaml_free(anchor_copy); - yaml_free(tag_copy); - yaml_free(value_copy); - - return 0; -} - -/* - * Create SEQUENCE-START. - */ - -YAML_DECLARE(int) -yaml_sequence_start_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, int implicit, - yaml_sequence_style_t style) -{ - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *anchor_copy = NULL; - yaml_char_t *tag_copy = NULL; - - assert(event); /* Non-NULL event object is expected. */ - - if (anchor) { - if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; - anchor_copy = yaml_strdup(anchor); - if (!anchor_copy) goto error; - } - - if (tag) { - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - } - - SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, - implicit, style, mark, mark); - - return 1; - -error: - yaml_free(anchor_copy); - yaml_free(tag_copy); - - return 0; -} - -/* - * Create SEQUENCE-END. - */ - -YAML_DECLARE(int) -yaml_sequence_end_event_initialize(yaml_event_t *event) -{ - yaml_mark_t mark = { 0, 0, 0 }; - - assert(event); /* Non-NULL event object is expected. */ - - SEQUENCE_END_EVENT_INIT(*event, mark, mark); - - return 1; -} - -/* - * Create MAPPING-START. - */ - -YAML_DECLARE(int) -yaml_mapping_start_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, int implicit, - yaml_mapping_style_t style) -{ - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *anchor_copy = NULL; - yaml_char_t *tag_copy = NULL; - - assert(event); /* Non-NULL event object is expected. */ - - if (anchor) { - if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; - anchor_copy = yaml_strdup(anchor); - if (!anchor_copy) goto error; - } - - if (tag) { - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - } - - MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, - implicit, style, mark, mark); - - return 1; - -error: - yaml_free(anchor_copy); - yaml_free(tag_copy); - - return 0; -} - -/* - * Create MAPPING-END. - */ - -YAML_DECLARE(int) -yaml_mapping_end_event_initialize(yaml_event_t *event) -{ - yaml_mark_t mark = { 0, 0, 0 }; - - assert(event); /* Non-NULL event object is expected. */ - - MAPPING_END_EVENT_INIT(*event, mark, mark); - - return 1; -} - -/* - * Destroy an event object. - */ - -YAML_DECLARE(void) -yaml_event_delete(yaml_event_t *event) -{ - yaml_tag_directive_t *tag_directive; - - assert(event); /* Non-NULL event object expected. */ - - switch (event->type) - { - case YAML_DOCUMENT_START_EVENT: - yaml_free(event->data.document_start.version_directive); - for (tag_directive = event->data.document_start.tag_directives.start; - tag_directive != event->data.document_start.tag_directives.end; - tag_directive++) { - yaml_free(tag_directive->handle); - yaml_free(tag_directive->prefix); - } - yaml_free(event->data.document_start.tag_directives.start); - break; - - case YAML_ALIAS_EVENT: - yaml_free(event->data.alias.anchor); - break; - - case YAML_SCALAR_EVENT: - yaml_free(event->data.scalar.anchor); - yaml_free(event->data.scalar.tag); - yaml_free(event->data.scalar.value); - break; - - case YAML_SEQUENCE_START_EVENT: - yaml_free(event->data.sequence_start.anchor); - yaml_free(event->data.sequence_start.tag); - break; - - case YAML_MAPPING_START_EVENT: - yaml_free(event->data.mapping_start.anchor); - yaml_free(event->data.mapping_start.tag); - break; - - default: - break; - } - - memset(event, 0, sizeof(yaml_event_t)); -} - -/* - * Create a document object. - */ - -YAML_DECLARE(int) -yaml_document_initialize(yaml_document_t *document, - yaml_version_directive_t *version_directive, - yaml_tag_directive_t *tag_directives_start, - yaml_tag_directive_t *tag_directives_end, - int start_implicit, int end_implicit) -{ - struct { - yaml_error_type_t error; - } context; - struct { - yaml_node_t *start; - yaml_node_t *end; - yaml_node_t *top; - } nodes = { NULL, NULL, NULL }; - yaml_version_directive_t *version_directive_copy = NULL; - struct { - yaml_tag_directive_t *start; - yaml_tag_directive_t *end; - yaml_tag_directive_t *top; - } tag_directives_copy = { NULL, NULL, NULL }; - yaml_tag_directive_t value = { NULL, NULL }; - yaml_mark_t mark = { 0, 0, 0 }; - - assert(document); /* Non-NULL document object is expected. */ - assert((tag_directives_start && tag_directives_end) || - (tag_directives_start == tag_directives_end)); - /* Valid tag directives are expected. */ - - if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error; - - if (version_directive) { - version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t); - if (!version_directive_copy) goto error; - version_directive_copy->major = version_directive->major; - version_directive_copy->minor = version_directive->minor; - } - - if (tag_directives_start != tag_directives_end) { - yaml_tag_directive_t *tag_directive; - if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*)) - goto error; - for (tag_directive = tag_directives_start; - tag_directive != tag_directives_end; tag_directive ++) { - assert(tag_directive->handle); - assert(tag_directive->prefix); - if (!yaml_check_utf8(tag_directive->handle, - strlen((char *)tag_directive->handle))) - goto error; - if (!yaml_check_utf8(tag_directive->prefix, - strlen((char *)tag_directive->prefix))) - goto error; - value.handle = yaml_strdup(tag_directive->handle); - value.prefix = yaml_strdup(tag_directive->prefix); - if (!value.handle || !value.prefix) goto error; - if (!PUSH(&context, tag_directives_copy, value)) - goto error; - value.handle = NULL; - value.prefix = NULL; - } - } - - DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, - tag_directives_copy.start, tag_directives_copy.top, - start_implicit, end_implicit, mark, mark); - - return 1; - -error: - STACK_DEL(&context, nodes); - yaml_free(version_directive_copy); - while (!STACK_EMPTY(&context, tag_directives_copy)) { - yaml_tag_directive_t value = POP(&context, tag_directives_copy); - yaml_free(value.handle); - yaml_free(value.prefix); - } - STACK_DEL(&context, tag_directives_copy); - yaml_free(value.handle); - yaml_free(value.prefix); - - return 0; -} - -/* - * Destroy a document object. - */ - -YAML_DECLARE(void) -yaml_document_delete(yaml_document_t *document) -{ - yaml_tag_directive_t *tag_directive; - - assert(document); /* Non-NULL document object is expected. */ - - while (!STACK_EMPTY(&context, document->nodes)) { - yaml_node_t node = POP(&context, document->nodes); - yaml_free(node.tag); - switch (node.type) { - case YAML_SCALAR_NODE: - yaml_free(node.data.scalar.value); - break; - case YAML_SEQUENCE_NODE: - STACK_DEL(&context, node.data.sequence.items); - break; - case YAML_MAPPING_NODE: - STACK_DEL(&context, node.data.mapping.pairs); - break; - default: - assert(0); /* Should not happen. */ - } - } - STACK_DEL(&context, document->nodes); - - yaml_free(document->version_directive); - for (tag_directive = document->tag_directives.start; - tag_directive != document->tag_directives.end; - tag_directive++) { - yaml_free(tag_directive->handle); - yaml_free(tag_directive->prefix); - } - yaml_free(document->tag_directives.start); - - memset(document, 0, sizeof(yaml_document_t)); -} - -/** - * Get a document node. - */ - -YAML_DECLARE(yaml_node_t *) -yaml_document_get_node(yaml_document_t *document, int index) -{ - assert(document); /* Non-NULL document object is expected. */ - - if (index > 0 && document->nodes.start + index <= document->nodes.top) { - return document->nodes.start + index - 1; - } - return NULL; -} - -/** - * Get the root object. - */ - -YAML_DECLARE(yaml_node_t *) -yaml_document_get_root_node(yaml_document_t *document) -{ - assert(document); /* Non-NULL document object is expected. */ - - if (document->nodes.top != document->nodes.start) { - return document->nodes.start; - } - return NULL; -} - -/* - * Add a scalar node to a document. - */ - -YAML_DECLARE(int) -yaml_document_add_scalar(yaml_document_t *document, - const yaml_char_t *tag, const yaml_char_t *value, int length, - yaml_scalar_style_t style) -{ - struct { - yaml_error_type_t error; - } context; - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *tag_copy = NULL; - yaml_char_t *value_copy = NULL; - yaml_node_t node; - - assert(document); /* Non-NULL document object is expected. */ - assert(value); /* Non-NULL value is expected. */ - - if (!tag) { - tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; - } - - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - - if (length < 0) { - length = (int)strlen((char *)value); - } - - if (!yaml_check_utf8(value, length)) goto error; - value_copy = YAML_MALLOC(length+1); - if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; - - SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); - if (!PUSH(&context, document->nodes, node)) goto error; - - return (int)(document->nodes.top - document->nodes.start); - -error: - yaml_free(tag_copy); - yaml_free(value_copy); - - return 0; -} - -/* - * Add a sequence node to a document. - */ - -YAML_DECLARE(int) -yaml_document_add_sequence(yaml_document_t *document, - const yaml_char_t *tag, yaml_sequence_style_t style) -{ - struct { - yaml_error_type_t error; - } context; - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *tag_copy = NULL; - struct { - yaml_node_item_t *start; - yaml_node_item_t *end; - yaml_node_item_t *top; - } items = { NULL, NULL, NULL }; - yaml_node_t node; - - assert(document); /* Non-NULL document object is expected. */ - - if (!tag) { - tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; - } - - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - - if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error; - - SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, - style, mark, mark); - if (!PUSH(&context, document->nodes, node)) goto error; - - return (int)(document->nodes.top - document->nodes.start); - -error: - STACK_DEL(&context, items); - yaml_free(tag_copy); - - return 0; -} - -/* - * Add a mapping node to a document. - */ - -YAML_DECLARE(int) -yaml_document_add_mapping(yaml_document_t *document, - const yaml_char_t *tag, yaml_mapping_style_t style) -{ - struct { - yaml_error_type_t error; - } context; - yaml_mark_t mark = { 0, 0, 0 }; - yaml_char_t *tag_copy = NULL; - struct { - yaml_node_pair_t *start; - yaml_node_pair_t *end; - yaml_node_pair_t *top; - } pairs = { NULL, NULL, NULL }; - yaml_node_t node; - - assert(document); /* Non-NULL document object is expected. */ - - if (!tag) { - tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; - } - - if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; - tag_copy = yaml_strdup(tag); - if (!tag_copy) goto error; - - if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error; - - MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, - style, mark, mark); - if (!PUSH(&context, document->nodes, node)) goto error; - - return (int)(document->nodes.top - document->nodes.start); - -error: - STACK_DEL(&context, pairs); - yaml_free(tag_copy); - - return 0; -} - -/* - * Append an item to a sequence node. - */ - -YAML_DECLARE(int) -yaml_document_append_sequence_item(yaml_document_t *document, - int sequence, int item) -{ - struct { - yaml_error_type_t error; - } context; - - assert(document); /* Non-NULL document is required. */ - assert(sequence > 0 - && document->nodes.start + sequence <= document->nodes.top); - /* Valid sequence id is required. */ - assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); - /* A sequence node is required. */ - assert(item > 0 && document->nodes.start + item <= document->nodes.top); - /* Valid item id is required. */ - - if (!PUSH(&context, - document->nodes.start[sequence-1].data.sequence.items, item)) - return 0; - - return 1; -} - -/* - * Append a pair of a key and a value to a mapping node. - */ - -YAML_DECLARE(int) -yaml_document_append_mapping_pair(yaml_document_t *document, - int mapping, int key, int value) -{ - struct { - yaml_error_type_t error; - } context; - - yaml_node_pair_t pair; - - assert(document); /* Non-NULL document is required. */ - assert(mapping > 0 - && document->nodes.start + mapping <= document->nodes.top); - /* Valid mapping id is required. */ - assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); - /* A mapping node is required. */ - assert(key > 0 && document->nodes.start + key <= document->nodes.top); - /* Valid key id is required. */ - assert(value > 0 && document->nodes.start + value <= document->nodes.top); - /* Valid value id is required. */ - - pair.key = key; - pair.value = value; - - if (!PUSH(&context, - document->nodes.start[mapping-1].data.mapping.pairs, pair)) - return 0; - - return 1; -} - - diff --git a/ext/psych/yaml/config.h b/ext/psych/yaml/config.h deleted file mode 100644 index 4b1150f5e4..0000000000 --- a/ext/psych/yaml/config.h +++ /dev/null @@ -1,80 +0,0 @@ -/* include/config.h. Generated from config.h.in by configure. */ -/* include/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "yaml" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "https://github.com/yaml/libyaml/issues/new" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "yaml" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "yaml 0.2.5" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "yaml" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.2.5" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.2.5" - -/* Define the major version number. */ -#define YAML_VERSION_MAJOR 0 - -/* Define the minor version number. */ -#define YAML_VERSION_MINOR 2 - -/* Define the patch version number. */ -#define YAML_VERSION_PATCH 5 - -/* Define the version string. */ -#define YAML_VERSION_STRING "0.2.5" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ diff --git a/ext/psych/yaml/dumper.c b/ext/psych/yaml/dumper.c deleted file mode 100644 index 1fe940b674..0000000000 --- a/ext/psych/yaml/dumper.c +++ /dev/null @@ -1,394 +0,0 @@ - -#include "yaml_private.h" - -/* - * API functions. - */ - -YAML_DECLARE(int) -yaml_emitter_open(yaml_emitter_t *emitter); - -YAML_DECLARE(int) -yaml_emitter_close(yaml_emitter_t *emitter); - -YAML_DECLARE(int) -yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); - -/* - * Clean up functions. - */ - -static void -yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter); - -/* - * Anchor functions. - */ - -static void -yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index); - -static yaml_char_t * -yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id); - - -/* - * Serialize functions. - */ - -static int -yaml_emitter_dump_node(yaml_emitter_t *emitter, int index); - -static int -yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor); - -static int -yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor); - -static int -yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor); - -static int -yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor); - -/* - * Issue a STREAM-START event. - */ - -YAML_DECLARE(int) -yaml_emitter_open(yaml_emitter_t *emitter) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - assert(emitter); /* Non-NULL emitter object is required. */ - assert(!emitter->opened); /* Emitter should not be opened yet. */ - - STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark); - - if (!yaml_emitter_emit(emitter, &event)) { - return 0; - } - - emitter->opened = 1; - - return 1; -} - -/* - * Issue a STREAM-END event. - */ - -YAML_DECLARE(int) -yaml_emitter_close(yaml_emitter_t *emitter) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - assert(emitter); /* Non-NULL emitter object is required. */ - assert(emitter->opened); /* Emitter should be opened. */ - - if (emitter->closed) return 1; - - STREAM_END_EVENT_INIT(event, mark, mark); - - if (!yaml_emitter_emit(emitter, &event)) { - return 0; - } - - emitter->closed = 1; - - return 1; -} - -/* - * Dump a YAML document. - */ - -YAML_DECLARE(int) -yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - assert(emitter); /* Non-NULL emitter object is required. */ - assert(document); /* Non-NULL emitter object is expected. */ - - emitter->document = document; - - if (!emitter->opened) { - if (!yaml_emitter_open(emitter)) goto error; - } - - if (STACK_EMPTY(emitter, document->nodes)) { - if (!yaml_emitter_close(emitter)) goto error; - yaml_emitter_delete_document_and_anchors(emitter); - return 1; - } - - assert(emitter->opened); /* Emitter should be opened. */ - - emitter->anchors = (yaml_anchors_t*)yaml_malloc(sizeof(*(emitter->anchors)) - * (document->nodes.top - document->nodes.start)); - if (!emitter->anchors) goto error; - memset(emitter->anchors, 0, sizeof(*(emitter->anchors)) - * (document->nodes.top - document->nodes.start)); - - DOCUMENT_START_EVENT_INIT(event, document->version_directive, - document->tag_directives.start, document->tag_directives.end, - document->start_implicit, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) goto error; - - yaml_emitter_anchor_node(emitter, 1); - if (!yaml_emitter_dump_node(emitter, 1)) goto error; - - DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) goto error; - - yaml_emitter_delete_document_and_anchors(emitter); - - return 1; - -error: - - yaml_emitter_delete_document_and_anchors(emitter); - - return 0; -} - -/* - * Clean up the emitter object after a document is dumped. - */ - -static void -yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter) -{ - int index; - - if (!emitter->anchors) { - yaml_document_delete(emitter->document); - emitter->document = NULL; - return; - } - - for (index = 0; emitter->document->nodes.start + index - < emitter->document->nodes.top; index ++) { - yaml_node_t node = emitter->document->nodes.start[index]; - if (!emitter->anchors[index].serialized) { - yaml_free(node.tag); - if (node.type == YAML_SCALAR_NODE) { - yaml_free(node.data.scalar.value); - } - } - if (node.type == YAML_SEQUENCE_NODE) { - STACK_DEL(emitter, node.data.sequence.items); - } - if (node.type == YAML_MAPPING_NODE) { - STACK_DEL(emitter, node.data.mapping.pairs); - } - } - - STACK_DEL(emitter, emitter->document->nodes); - yaml_free(emitter->anchors); - - emitter->anchors = NULL; - emitter->last_anchor_id = 0; - emitter->document = NULL; -} - -/* - * Check the references of a node and assign the anchor id if needed. - */ - -static void -yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index) -{ - yaml_node_t *node = emitter->document->nodes.start + index - 1; - yaml_node_item_t *item; - yaml_node_pair_t *pair; - - emitter->anchors[index-1].references ++; - - if (emitter->anchors[index-1].references == 1) { - switch (node->type) { - case YAML_SEQUENCE_NODE: - for (item = node->data.sequence.items.start; - item < node->data.sequence.items.top; item ++) { - yaml_emitter_anchor_node(emitter, *item); - } - break; - case YAML_MAPPING_NODE: - for (pair = node->data.mapping.pairs.start; - pair < node->data.mapping.pairs.top; pair ++) { - yaml_emitter_anchor_node(emitter, pair->key); - yaml_emitter_anchor_node(emitter, pair->value); - } - break; - default: - break; - } - } - - else if (emitter->anchors[index-1].references == 2) { - emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id); - } -} - -/* - * Generate a textual representation for an anchor. - */ - -#define ANCHOR_TEMPLATE "id%03d" -#define ANCHOR_TEMPLATE_LENGTH 16 - -static yaml_char_t * -yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id) -{ - yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH); - - if (!anchor) return NULL; - - sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id); - - return anchor; -} - -/* - * Serialize a node. - */ - -static int -yaml_emitter_dump_node(yaml_emitter_t *emitter, int index) -{ - yaml_node_t *node = emitter->document->nodes.start + index - 1; - int anchor_id = emitter->anchors[index-1].anchor; - yaml_char_t *anchor = NULL; - - if (anchor_id) { - anchor = yaml_emitter_generate_anchor(emitter, anchor_id); - if (!anchor) return 0; - } - - if (emitter->anchors[index-1].serialized) { - return yaml_emitter_dump_alias(emitter, anchor); - } - - emitter->anchors[index-1].serialized = 1; - - switch (node->type) { - case YAML_SCALAR_NODE: - return yaml_emitter_dump_scalar(emitter, node, anchor); - case YAML_SEQUENCE_NODE: - return yaml_emitter_dump_sequence(emitter, node, anchor); - case YAML_MAPPING_NODE: - return yaml_emitter_dump_mapping(emitter, node, anchor); - default: - assert(0); /* Could not happen. */ - break; - } - - return 0; /* Could not happen. */ -} - -/* - * Serialize an alias. - */ - -static int -yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - ALIAS_EVENT_INIT(event, anchor, mark, mark); - - return yaml_emitter_emit(emitter, &event); -} - -/* - * Serialize a scalar. - */ - -static int -yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - int plain_implicit = (strcmp((char *)node->tag, - YAML_DEFAULT_SCALAR_TAG) == 0); - int quoted_implicit = (strcmp((char *)node->tag, - YAML_DEFAULT_SCALAR_TAG) == 0); - - SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value, - node->data.scalar.length, plain_implicit, quoted_implicit, - node->data.scalar.style, mark, mark); - - return yaml_emitter_emit(emitter, &event); -} - -/* - * Serialize a sequence. - */ - -static int -yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0); - - yaml_node_item_t *item; - - SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit, - node->data.sequence.style, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) return 0; - - for (item = node->data.sequence.items.start; - item < node->data.sequence.items.top; item ++) { - if (!yaml_emitter_dump_node(emitter, *item)) return 0; - } - - SEQUENCE_END_EVENT_INIT(event, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) return 0; - - return 1; -} - -/* - * Serialize a mapping. - */ - -static int -yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, - yaml_char_t *anchor) -{ - yaml_event_t event; - yaml_mark_t mark = { 0, 0, 0 }; - - int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0); - - yaml_node_pair_t *pair; - - MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit, - node->data.mapping.style, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) return 0; - - for (pair = node->data.mapping.pairs.start; - pair < node->data.mapping.pairs.top; pair ++) { - if (!yaml_emitter_dump_node(emitter, pair->key)) return 0; - if (!yaml_emitter_dump_node(emitter, pair->value)) return 0; - } - - MAPPING_END_EVENT_INIT(event, mark, mark); - if (!yaml_emitter_emit(emitter, &event)) return 0; - - return 1; -} - diff --git a/ext/psych/yaml/emitter.c b/ext/psych/yaml/emitter.c deleted file mode 100644 index 796294ccdf..0000000000 --- a/ext/psych/yaml/emitter.c +++ /dev/null @@ -1,2358 +0,0 @@ - -#include "yaml_private.h" - -/* - * Flush the buffer if needed. - */ - -#define FLUSH(emitter) \ - ((emitter->buffer.pointer+5 < emitter->buffer.end) \ - || yaml_emitter_flush(emitter)) - -/* - * Put a character to the output buffer. - */ - -#define PUT(emitter,value) \ - (FLUSH(emitter) \ - && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \ - emitter->column++, \ - 1)) - -/* - * Put a line break to the output buffer. - */ - -#define PUT_BREAK(emitter) \ - (FLUSH(emitter) ? \ - ((emitter->line_break == YAML_CR_BREAK ? \ - (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \ - emitter->line_break == YAML_LN_BREAK ? \ - (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \ - emitter->line_break == YAML_CRLN_BREAK ? \ - (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \ - *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \ - emitter->column = 0, \ - emitter->line ++, \ - 1) : 0) - -/* - * Copy a character from a string into buffer. - */ - -#define WRITE(emitter,string) \ - (FLUSH(emitter) \ - && (COPY(emitter->buffer,string), \ - emitter->column ++, \ - 1)) - -/* - * Copy a line break character from a string into buffer. - */ - -#define WRITE_BREAK(emitter,string) \ - (FLUSH(emitter) \ - && (CHECK(string,'\n') ? \ - (PUT_BREAK(emitter), \ - string.pointer ++, \ - 1) : \ - (COPY(emitter->buffer,string), \ - emitter->column = 0, \ - emitter->line ++, \ - 1))) - -/* - * API functions. - */ - -YAML_DECLARE(int) -yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); - -/* - * Utility functions. - */ - -static int -yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem); - -static int -yaml_emitter_need_more_events(yaml_emitter_t *emitter); - -static int -yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, - yaml_tag_directive_t value, int allow_duplicates); - -static int -yaml_emitter_increase_indent(yaml_emitter_t *emitter, - int flow, int indentless); - -/* - * State functions. - */ - -static int -yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event); - -static int -yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, - yaml_event_t *event); - -static int -yaml_emitter_emit_document_start(yaml_emitter_t *emitter, - yaml_event_t *event, int first); - -static int -yaml_emitter_emit_document_content(yaml_emitter_t *emitter, - yaml_event_t *event); - -static int -yaml_emitter_emit_document_end(yaml_emitter_t *emitter, - yaml_event_t *event); - -static int -yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, - yaml_event_t *event, int first); - -static int -yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, - yaml_event_t *event, int first); - -static int -yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, - yaml_event_t *event, int simple); - -static int -yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, - yaml_event_t *event, int first); - -static int -yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, - yaml_event_t *event, int first); - -static int -yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, - yaml_event_t *event, int simple); - -static int -yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, - int root, int sequence, int mapping, int simple_key); - -static int -yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event); - -static int -yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event); - -static int -yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event); - -static int -yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event); - -/* - * Checkers. - */ - -static int -yaml_emitter_check_empty_document(yaml_emitter_t *emitter); - -static int -yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter); - -static int -yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter); - -static int -yaml_emitter_check_simple_key(yaml_emitter_t *emitter); - -static int -yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event); - -/* - * Processors. - */ - -static int -yaml_emitter_process_anchor(yaml_emitter_t *emitter); - -static int -yaml_emitter_process_tag(yaml_emitter_t *emitter); - -static int -yaml_emitter_process_scalar(yaml_emitter_t *emitter); - -/* - * Analyzers. - */ - -static int -yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, - yaml_version_directive_t version_directive); - -static int -yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, - yaml_tag_directive_t tag_directive); - -static int -yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, - yaml_char_t *anchor, int alias); - -static int -yaml_emitter_analyze_tag(yaml_emitter_t *emitter, - yaml_char_t *tag); - -static int -yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length); - -static int -yaml_emitter_analyze_event(yaml_emitter_t *emitter, - yaml_event_t *event); - -/* - * Writers. - */ - -static int -yaml_emitter_write_bom(yaml_emitter_t *emitter); - -static int -yaml_emitter_write_indent(yaml_emitter_t *emitter); - -static int -yaml_emitter_write_indicator(yaml_emitter_t *emitter, - const char *indicator, int need_whitespace, - int is_whitespace, int is_indention); - -static int -yaml_emitter_write_anchor(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length); - -static int -yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length); - -static int -yaml_emitter_write_tag_content(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int need_whitespace); - -static int -yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks); - -static int -yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks); - -static int -yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks); - -static int -yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, - yaml_string_t string); - -static int -yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length); - -static int -yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length); - -/* - * Set an emitter error and return 0. - */ - -static int -yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem) -{ - emitter->error = YAML_EMITTER_ERROR; - emitter->problem = problem; - - return 0; -} - -/* - * Emit an event. - */ - -YAML_DECLARE(int) -yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) -{ - if (!ENQUEUE(emitter, emitter->events, *event)) { - yaml_event_delete(event); - return 0; - } - - while (!yaml_emitter_need_more_events(emitter)) { - if (!yaml_emitter_analyze_event(emitter, emitter->events.head)) - return 0; - if (!yaml_emitter_state_machine(emitter, emitter->events.head)) - return 0; - yaml_event_delete(&DEQUEUE(emitter, emitter->events)); - } - - return 1; -} - -/* - * Check if we need to accumulate more events before emitting. - * - * We accumulate extra - * - 1 event for DOCUMENT-START - * - 2 events for SEQUENCE-START - * - 3 events for MAPPING-START - */ - -static int -yaml_emitter_need_more_events(yaml_emitter_t *emitter) -{ - int level = 0; - int accumulate = 0; - yaml_event_t *event; - - if (QUEUE_EMPTY(emitter, emitter->events)) - return 1; - - switch (emitter->events.head->type) { - case YAML_DOCUMENT_START_EVENT: - accumulate = 1; - break; - case YAML_SEQUENCE_START_EVENT: - accumulate = 2; - break; - case YAML_MAPPING_START_EVENT: - accumulate = 3; - break; - default: - return 0; - } - - if (emitter->events.tail - emitter->events.head > accumulate) - return 0; - - for (event = emitter->events.head; event != emitter->events.tail; event ++) { - switch (event->type) { - case YAML_STREAM_START_EVENT: - case YAML_DOCUMENT_START_EVENT: - case YAML_SEQUENCE_START_EVENT: - case YAML_MAPPING_START_EVENT: - level += 1; - break; - case YAML_STREAM_END_EVENT: - case YAML_DOCUMENT_END_EVENT: - case YAML_SEQUENCE_END_EVENT: - case YAML_MAPPING_END_EVENT: - level -= 1; - break; - default: - break; - } - if (!level) - return 0; - } - - return 1; -} - -/* - * Append a directive to the directives stack. - */ - -static int -yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, - yaml_tag_directive_t value, int allow_duplicates) -{ - yaml_tag_directive_t *tag_directive; - yaml_tag_directive_t copy = { NULL, NULL }; - - for (tag_directive = emitter->tag_directives.start; - tag_directive != emitter->tag_directives.top; tag_directive ++) { - if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { - if (allow_duplicates) - return 1; - return yaml_emitter_set_emitter_error(emitter, - "duplicate %TAG directive"); - } - } - - copy.handle = yaml_strdup(value.handle); - copy.prefix = yaml_strdup(value.prefix); - if (!copy.handle || !copy.prefix) { - emitter->error = YAML_MEMORY_ERROR; - goto error; - } - - if (!PUSH(emitter, emitter->tag_directives, copy)) - goto error; - - return 1; - -error: - yaml_free(copy.handle); - yaml_free(copy.prefix); - return 0; -} - -/* - * Increase the indentation level. - */ - -static int -yaml_emitter_increase_indent(yaml_emitter_t *emitter, - int flow, int indentless) -{ - if (!PUSH(emitter, emitter->indents, emitter->indent)) - return 0; - - if (emitter->indent < 0) { - emitter->indent = flow ? emitter->best_indent : 0; - } - else if (!indentless) { - emitter->indent += emitter->best_indent; - } - - return 1; -} - -/* - * State dispatcher. - */ - -static int -yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event) -{ - switch (emitter->state) - { - case YAML_EMIT_STREAM_START_STATE: - return yaml_emitter_emit_stream_start(emitter, event); - - case YAML_EMIT_FIRST_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, 1); - - case YAML_EMIT_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, 0); - - case YAML_EMIT_DOCUMENT_CONTENT_STATE: - return yaml_emitter_emit_document_content(emitter, event); - - case YAML_EMIT_DOCUMENT_END_STATE: - return yaml_emitter_emit_document_end(emitter, event); - - case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, 1); - - case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, 0); - - case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, 1); - - case YAML_EMIT_FLOW_MAPPING_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, 0); - - case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, 1); - - case YAML_EMIT_FLOW_MAPPING_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, 0); - - case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, 1); - - case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, 0); - - case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, 1); - - case YAML_EMIT_BLOCK_MAPPING_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, 0); - - case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, 1); - - case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, 0); - - case YAML_EMIT_END_STATE: - return yaml_emitter_set_emitter_error(emitter, - "expected nothing after STREAM-END"); - - default: - assert(1); /* Invalid state. */ - } - - return 0; -} - -/* - * Expect STREAM-START. - */ - -static int -yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, - yaml_event_t *event) -{ - emitter->open_ended = 0; - if (event->type == YAML_STREAM_START_EVENT) - { - if (!emitter->encoding) { - emitter->encoding = event->data.stream_start.encoding; - } - - if (!emitter->encoding) { - emitter->encoding = YAML_UTF8_ENCODING; - } - - if (emitter->best_indent < 2 || emitter->best_indent > 9) { - emitter->best_indent = 2; - } - - if (emitter->best_width >= 0 - && emitter->best_width <= emitter->best_indent*2) { - emitter->best_width = 80; - } - - if (emitter->best_width < 0) { - emitter->best_width = INT_MAX; - } - - if (!emitter->line_break) { - emitter->line_break = YAML_LN_BREAK; - } - - emitter->indent = -1; - - emitter->line = 0; - emitter->column = 0; - emitter->whitespace = 1; - emitter->indention = 1; - - if (emitter->encoding != YAML_UTF8_ENCODING) { - if (!yaml_emitter_write_bom(emitter)) - return 0; - } - - emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE; - - return 1; - } - - return yaml_emitter_set_emitter_error(emitter, - "expected STREAM-START"); -} - -/* - * Expect DOCUMENT-START or STREAM-END. - */ - -static int -yaml_emitter_emit_document_start(yaml_emitter_t *emitter, - yaml_event_t *event, int first) -{ - if (event->type == YAML_DOCUMENT_START_EVENT) - { - yaml_tag_directive_t default_tag_directives[] = { - {(yaml_char_t *)"!", (yaml_char_t *)"!"}, - {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, - {NULL, NULL} - }; - yaml_tag_directive_t *tag_directive; - int implicit; - - if (event->data.document_start.version_directive) { - if (!yaml_emitter_analyze_version_directive(emitter, - *event->data.document_start.version_directive)) - return 0; - } - - for (tag_directive = event->data.document_start.tag_directives.start; - tag_directive != event->data.document_start.tag_directives.end; - tag_directive ++) { - if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive)) - return 0; - if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0)) - return 0; - } - - for (tag_directive = default_tag_directives; - tag_directive->handle; tag_directive ++) { - if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1)) - return 0; - } - - implicit = event->data.document_start.implicit; - if (!first || emitter->canonical) { - implicit = 0; - } - - if ((event->data.document_start.version_directive || - (event->data.document_start.tag_directives.start - != event->data.document_start.tag_directives.end)) && - emitter->open_ended) - { - if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) - return 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - emitter->open_ended = 0; - - if (event->data.document_start.version_directive) { - implicit = 0; - if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0)) - return 0; - if (event->data.document_start.version_directive->minor == 1) { - if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0)) - return 0; - } - else { - if (!yaml_emitter_write_indicator(emitter, "1.2", 1, 0, 0)) - return 0; - } - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - - if (event->data.document_start.tag_directives.start - != event->data.document_start.tag_directives.end) { - implicit = 0; - for (tag_directive = event->data.document_start.tag_directives.start; - tag_directive != event->data.document_start.tag_directives.end; - tag_directive ++) { - if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0)) - return 0; - if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle, - strlen((char *)tag_directive->handle))) - return 0; - if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix, - strlen((char *)tag_directive->prefix), 1)) - return 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - } - - if (yaml_emitter_check_empty_document(emitter)) { - implicit = 0; - } - - if (!implicit) { - if (!yaml_emitter_write_indent(emitter)) - return 0; - if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0)) - return 0; - if (emitter->canonical) { - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - } - - emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE; - - emitter->open_ended = 0; - return 1; - } - - else if (event->type == YAML_STREAM_END_EVENT) - { - - /** - * This can happen if a block scalar with trailing empty lines - * is at the end of the stream - */ - if (emitter->open_ended == 2) - { - if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) - return 0; - emitter->open_ended = 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - if (!yaml_emitter_flush(emitter)) - return 0; - - emitter->state = YAML_EMIT_END_STATE; - - return 1; - } - - return yaml_emitter_set_emitter_error(emitter, - "expected DOCUMENT-START or STREAM-END"); -} - -/* - * Expect the root node. - */ - -static int -yaml_emitter_emit_document_content(yaml_emitter_t *emitter, - yaml_event_t *event) -{ - if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0); -} - -/* - * Expect DOCUMENT-END. - */ - -static int -yaml_emitter_emit_document_end(yaml_emitter_t *emitter, - yaml_event_t *event) -{ - if (event->type == YAML_DOCUMENT_END_EVENT) - { - if (!yaml_emitter_write_indent(emitter)) - return 0; - if (!event->data.document_end.implicit) { - if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) - return 0; - emitter->open_ended = 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - else if (!emitter->open_ended) - emitter->open_ended = 1; - if (!yaml_emitter_flush(emitter)) - return 0; - - emitter->state = YAML_EMIT_DOCUMENT_START_STATE; - - while (!STACK_EMPTY(emitter, emitter->tag_directives)) { - yaml_tag_directive_t tag_directive = POP(emitter, - emitter->tag_directives); - yaml_free(tag_directive.handle); - yaml_free(tag_directive.prefix); - } - - return 1; - } - - return yaml_emitter_set_emitter_error(emitter, - "expected DOCUMENT-END"); -} - -/* - * - * Expect a flow item node. - */ - -static int -yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, - yaml_event_t *event, int first) -{ - if (first) - { - if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0)) - return 0; - if (!yaml_emitter_increase_indent(emitter, 1, 0)) - return 0; - emitter->flow_level ++; - } - - if (event->type == YAML_SEQUENCE_END_EVENT) - { - emitter->flow_level --; - emitter->indent = POP(emitter, emitter->indents); - if (emitter->canonical && !first) { - if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) - return 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0)) - return 0; - emitter->state = POP(emitter, emitter->states); - - return 1; - } - - if (!first) { - if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) - return 0; - } - - if (emitter->canonical || emitter->column > emitter->best_width) { - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); -} - -/* - * Expect a flow key node. - */ - -static int -yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, - yaml_event_t *event, int first) -{ - if (first) - { - if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0)) - return 0; - if (!yaml_emitter_increase_indent(emitter, 1, 0)) - return 0; - emitter->flow_level ++; - } - - if (event->type == YAML_MAPPING_END_EVENT) - { - emitter->flow_level --; - emitter->indent = POP(emitter, emitter->indents); - if (emitter->canonical && !first) { - if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) - return 0; - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0)) - return 0; - emitter->state = POP(emitter, emitter->states); - - return 1; - } - - if (!first) { - if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) - return 0; - } - if (emitter->canonical || emitter->column > emitter->best_width) { - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - - if (!emitter->canonical && yaml_emitter_check_simple_key(emitter)) - { - if (!PUSH(emitter, emitter->states, - YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); - } - else - { - if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0)) - return 0; - if (!PUSH(emitter, emitter->states, - YAML_EMIT_FLOW_MAPPING_VALUE_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); - } -} - -/* - * Expect a flow value node. - */ - -static int -yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, - yaml_event_t *event, int simple) -{ - if (simple) { - if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) - return 0; - } - else { - if (emitter->canonical || emitter->column > emitter->best_width) { - if (!yaml_emitter_write_indent(emitter)) - return 0; - } - if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0)) - return 0; - } - if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE)) - return 0; - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); -} - -/* - * Expect a block item node. - */ - -static int -yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, - yaml_event_t *event, int first) -{ - if (first) - { - if (!yaml_emitter_increase_indent(emitter, 0, - (emitter->mapping_context && !emitter->indention))) - return 0; - } - - if (event->type == YAML_SEQUENCE_END_EVENT) - { - emitter->indent = POP(emitter, emitter->indents); - emitter->state = POP(emitter, emitter->states); - - return 1; - } - - if (!yaml_emitter_write_indent(emitter)) - return 0; - if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1)) - return 0; - if (!PUSH(emitter, emitter->states, - YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); -} - -/* - * Expect a block key node. - */ - -static int -yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, - yaml_event_t *event, int first) -{ - if (first) - { - if (!yaml_emitter_increase_indent(emitter, 0, 0)) - return 0; - } - - if (event->type == YAML_MAPPING_END_EVENT) - { - emitter->indent = POP(emitter, emitter->indents); - emitter->state = POP(emitter, emitter->states); - - return 1; - } - - if (!yaml_emitter_write_indent(emitter)) - return 0; - - if (yaml_emitter_check_simple_key(emitter)) - { - if (!PUSH(emitter, emitter->states, - YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); - } - else - { - if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1)) - return 0; - if (!PUSH(emitter, emitter->states, - YAML_EMIT_BLOCK_MAPPING_VALUE_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); - } -} - -/* - * Expect a block value node. - */ - -static int -yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, - yaml_event_t *event, int simple) -{ - if (simple) { - if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) - return 0; - } - else { - if (!yaml_emitter_write_indent(emitter)) - return 0; - if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1)) - return 0; - } - if (!PUSH(emitter, emitter->states, - YAML_EMIT_BLOCK_MAPPING_KEY_STATE)) - return 0; - - return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); -} - -/* - * Expect a node. - */ - -static int -yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, - int root, int sequence, int mapping, int simple_key) -{ - emitter->root_context = root; - emitter->sequence_context = sequence; - emitter->mapping_context = mapping; - emitter->simple_key_context = simple_key; - - switch (event->type) - { - case YAML_ALIAS_EVENT: - return yaml_emitter_emit_alias(emitter, event); - - case YAML_SCALAR_EVENT: - return yaml_emitter_emit_scalar(emitter, event); - - case YAML_SEQUENCE_START_EVENT: - return yaml_emitter_emit_sequence_start(emitter, event); - - case YAML_MAPPING_START_EVENT: - return yaml_emitter_emit_mapping_start(emitter, event); - - default: - return yaml_emitter_set_emitter_error(emitter, - "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS"); - } - - return 0; -} - -/* - * Expect ALIAS. - */ - -static int -yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event)) -{ - if (!yaml_emitter_process_anchor(emitter)) - return 0; - if (emitter->simple_key_context) - if (!PUT(emitter, ' ')) return 0; - emitter->state = POP(emitter, emitter->states); - - return 1; -} - -/* - * Expect SCALAR. - */ - -static int -yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event) -{ - if (!yaml_emitter_select_scalar_style(emitter, event)) - return 0; - if (!yaml_emitter_process_anchor(emitter)) - return 0; - if (!yaml_emitter_process_tag(emitter)) - return 0; - if (!yaml_emitter_increase_indent(emitter, 1, 0)) - return 0; - if (!yaml_emitter_process_scalar(emitter)) - return 0; - emitter->indent = POP(emitter, emitter->indents); - emitter->state = POP(emitter, emitter->states); - - return 1; -} - -/* - * Expect SEQUENCE-START. - */ - -static int -yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event) -{ - if (!yaml_emitter_process_anchor(emitter)) - return 0; - if (!yaml_emitter_process_tag(emitter)) - return 0; - - if (emitter->flow_level || emitter->canonical - || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE - || yaml_emitter_check_empty_sequence(emitter)) { - emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; - } - else { - emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; - } - - return 1; -} - -/* - * Expect MAPPING-START. - */ - -static int -yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event) -{ - if (!yaml_emitter_process_anchor(emitter)) - return 0; - if (!yaml_emitter_process_tag(emitter)) - return 0; - - if (emitter->flow_level || emitter->canonical - || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE - || yaml_emitter_check_empty_mapping(emitter)) { - emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; - } - else { - emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; - } - - return 1; -} - -/* - * Check if the document content is an empty scalar. - */ - -static int -yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter)) -{ - return 0; -} - -/* - * Check if the next events represent an empty sequence. - */ - -static int -yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter) -{ - if (emitter->events.tail - emitter->events.head < 2) - return 0; - - return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT - && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT); -} - -/* - * Check if the next events represent an empty mapping. - */ - -static int -yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter) -{ - if (emitter->events.tail - emitter->events.head < 2) - return 0; - - return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT - && emitter->events.head[1].type == YAML_MAPPING_END_EVENT); -} - -/* - * Check if the next node can be expressed as a simple key. - */ - -static int -yaml_emitter_check_simple_key(yaml_emitter_t *emitter) -{ - yaml_event_t *event = emitter->events.head; - size_t length = 0; - - switch (event->type) - { - case YAML_ALIAS_EVENT: - length += emitter->anchor_data.anchor_length; - break; - - case YAML_SCALAR_EVENT: - if (emitter->scalar_data.multiline) - return 0; - length += emitter->anchor_data.anchor_length - + emitter->tag_data.handle_length - + emitter->tag_data.suffix_length - + emitter->scalar_data.length; - break; - - case YAML_SEQUENCE_START_EVENT: - if (!yaml_emitter_check_empty_sequence(emitter)) - return 0; - length += emitter->anchor_data.anchor_length - + emitter->tag_data.handle_length - + emitter->tag_data.suffix_length; - break; - - case YAML_MAPPING_START_EVENT: - if (!yaml_emitter_check_empty_mapping(emitter)) - return 0; - length += emitter->anchor_data.anchor_length - + emitter->tag_data.handle_length - + emitter->tag_data.suffix_length; - break; - - default: - return 0; - } - - if (length > 128) - return 0; - - return 1; -} - -/* - * Determine an acceptable scalar style. - */ - -static int -yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event) -{ - yaml_scalar_style_t style = event->data.scalar.style; - int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); - - if (no_tag && !event->data.scalar.plain_implicit - && !event->data.scalar.quoted_implicit) { - return yaml_emitter_set_emitter_error(emitter, - "neither tag nor implicit flags are specified"); - } - - if (style == YAML_ANY_SCALAR_STYLE) - style = YAML_PLAIN_SCALAR_STYLE; - - if (emitter->canonical) - style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; - - if (emitter->simple_key_context && emitter->scalar_data.multiline) - style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; - - if (style == YAML_PLAIN_SCALAR_STYLE) - { - if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed) - || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed)) - style = YAML_SINGLE_QUOTED_SCALAR_STYLE; - if (!emitter->scalar_data.length - && (emitter->flow_level || emitter->simple_key_context)) - style = YAML_SINGLE_QUOTED_SCALAR_STYLE; - if (no_tag && !event->data.scalar.plain_implicit) - style = YAML_SINGLE_QUOTED_SCALAR_STYLE; - } - - if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE) - { - if (!emitter->scalar_data.single_quoted_allowed) - style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; - } - - if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE) - { - if (!emitter->scalar_data.block_allowed - || emitter->flow_level || emitter->simple_key_context) - style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; - } - - if (no_tag && !event->data.scalar.quoted_implicit - && style != YAML_PLAIN_SCALAR_STYLE) - { - emitter->tag_data.handle = (yaml_char_t *)"!"; - emitter->tag_data.handle_length = 1; - } - - emitter->scalar_data.style = style; - - return 1; -} - -/* - * Write an anchor. - */ - -static int -yaml_emitter_process_anchor(yaml_emitter_t *emitter) -{ - if (!emitter->anchor_data.anchor) - return 1; - - if (!yaml_emitter_write_indicator(emitter, - (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0)) - return 0; - - return yaml_emitter_write_anchor(emitter, - emitter->anchor_data.anchor, emitter->anchor_data.anchor_length); -} - -/* - * Write a tag. - */ - -static int -yaml_emitter_process_tag(yaml_emitter_t *emitter) -{ - if (!emitter->tag_data.handle && !emitter->tag_data.suffix) - return 1; - - if (emitter->tag_data.handle) - { - if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle, - emitter->tag_data.handle_length)) - return 0; - if (emitter->tag_data.suffix) { - if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, - emitter->tag_data.suffix_length, 0)) - return 0; - } - } - else - { - if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0)) - return 0; - if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, - emitter->tag_data.suffix_length, 0)) - return 0; - if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0)) - return 0; - } - - return 1; -} - -/* - * Write a scalar. - */ - -static int -yaml_emitter_process_scalar(yaml_emitter_t *emitter) -{ - switch (emitter->scalar_data.style) - { - case YAML_PLAIN_SCALAR_STYLE: - return yaml_emitter_write_plain_scalar(emitter, - emitter->scalar_data.value, emitter->scalar_data.length, - !emitter->simple_key_context); - - case YAML_SINGLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_single_quoted_scalar(emitter, - emitter->scalar_data.value, emitter->scalar_data.length, - !emitter->simple_key_context); - - case YAML_DOUBLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_double_quoted_scalar(emitter, - emitter->scalar_data.value, emitter->scalar_data.length, - !emitter->simple_key_context); - - case YAML_LITERAL_SCALAR_STYLE: - return yaml_emitter_write_literal_scalar(emitter, - emitter->scalar_data.value, emitter->scalar_data.length); - - case YAML_FOLDED_SCALAR_STYLE: - return yaml_emitter_write_folded_scalar(emitter, - emitter->scalar_data.value, emitter->scalar_data.length); - - default: - assert(1); /* Impossible. */ - } - - return 0; -} - -/* - * Check if a %YAML directive is valid. - */ - -static int -yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, - yaml_version_directive_t version_directive) -{ - if (version_directive.major != 1 || ( - version_directive.minor != 1 - && version_directive.minor != 2 - )) { - return yaml_emitter_set_emitter_error(emitter, - "incompatible %YAML directive"); - } - - return 1; -} - -/* - * Check if a %TAG directive is valid. - */ - -static int -yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, - yaml_tag_directive_t tag_directive) -{ - yaml_string_t handle; - yaml_string_t prefix; - size_t handle_length; - size_t prefix_length; - - handle_length = strlen((char *)tag_directive.handle); - prefix_length = strlen((char *)tag_directive.prefix); - STRING_ASSIGN(handle, tag_directive.handle, handle_length); - STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length); - - if (handle.start == handle.end) { - return yaml_emitter_set_emitter_error(emitter, - "tag handle must not be empty"); - } - - if (handle.start[0] != '!') { - return yaml_emitter_set_emitter_error(emitter, - "tag handle must start with '!'"); - } - - if (handle.end[-1] != '!') { - return yaml_emitter_set_emitter_error(emitter, - "tag handle must end with '!'"); - } - - handle.pointer ++; - - while (handle.pointer < handle.end-1) { - if (!IS_ALPHA(handle)) { - return yaml_emitter_set_emitter_error(emitter, - "tag handle must contain alphanumerical characters only"); - } - MOVE(handle); - } - - if (prefix.start == prefix.end) { - return yaml_emitter_set_emitter_error(emitter, - "tag prefix must not be empty"); - } - - return 1; -} - -/* - * Check if an anchor is valid. - */ - -static int -yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, - yaml_char_t *anchor, int alias) -{ - size_t anchor_length; - yaml_string_t string; - - anchor_length = strlen((char *)anchor); - STRING_ASSIGN(string, anchor, anchor_length); - - if (string.start == string.end) { - return yaml_emitter_set_emitter_error(emitter, alias ? - "alias value must not be empty" : - "anchor value must not be empty"); - } - - while (string.pointer != string.end) { - if (!IS_ALPHA(string)) { - return yaml_emitter_set_emitter_error(emitter, alias ? - "alias value must contain alphanumerical characters only" : - "anchor value must contain alphanumerical characters only"); - } - MOVE(string); - } - - emitter->anchor_data.anchor = string.start; - emitter->anchor_data.anchor_length = string.end - string.start; - emitter->anchor_data.alias = alias; - - return 1; -} - -/* - * Check if a tag is valid. - */ - -static int -yaml_emitter_analyze_tag(yaml_emitter_t *emitter, - yaml_char_t *tag) -{ - size_t tag_length; - yaml_string_t string; - yaml_tag_directive_t *tag_directive; - - tag_length = strlen((char *)tag); - STRING_ASSIGN(string, tag, tag_length); - - if (string.start == string.end) { - return yaml_emitter_set_emitter_error(emitter, - "tag value must not be empty"); - } - - for (tag_directive = emitter->tag_directives.start; - tag_directive != emitter->tag_directives.top; tag_directive ++) { - size_t prefix_length = strlen((char *)tag_directive->prefix); - if (prefix_length < (size_t)(string.end - string.start) - && strncmp((char *)tag_directive->prefix, (char *)string.start, - prefix_length) == 0) - { - emitter->tag_data.handle = tag_directive->handle; - emitter->tag_data.handle_length = - strlen((char *)tag_directive->handle); - emitter->tag_data.suffix = string.start + prefix_length; - emitter->tag_data.suffix_length = - (string.end - string.start) - prefix_length; - return 1; - } - } - - emitter->tag_data.suffix = string.start; - emitter->tag_data.suffix_length = string.end - string.start; - - return 1; -} - -/* - * Check if a scalar is valid. - */ - -static int -yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length) -{ - yaml_string_t string; - - int block_indicators = 0; - int flow_indicators = 0; - int line_breaks = 0; - int special_characters = 0; - - int leading_space = 0; - int leading_break = 0; - int trailing_space = 0; - int trailing_break = 0; - int break_space = 0; - int space_break = 0; - - int preceded_by_whitespace = 0; - int followed_by_whitespace = 0; - int previous_space = 0; - int previous_break = 0; - - STRING_ASSIGN(string, value, length); - - emitter->scalar_data.value = value; - emitter->scalar_data.length = length; - - if (string.start == string.end) - { - emitter->scalar_data.multiline = 0; - emitter->scalar_data.flow_plain_allowed = 0; - emitter->scalar_data.block_plain_allowed = 1; - emitter->scalar_data.single_quoted_allowed = 1; - emitter->scalar_data.block_allowed = 0; - - return 1; - } - - if ((CHECK_AT(string, '-', 0) - && CHECK_AT(string, '-', 1) - && CHECK_AT(string, '-', 2)) - || (CHECK_AT(string, '.', 0) - && CHECK_AT(string, '.', 1) - && CHECK_AT(string, '.', 2))) { - block_indicators = 1; - flow_indicators = 1; - } - - preceded_by_whitespace = 1; - followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); - - while (string.pointer != string.end) - { - if (string.start == string.pointer) - { - if (CHECK(string, '#') || CHECK(string, ',') - || CHECK(string, '[') || CHECK(string, ']') - || CHECK(string, '{') || CHECK(string, '}') - || CHECK(string, '&') || CHECK(string, '*') - || CHECK(string, '!') || CHECK(string, '|') - || CHECK(string, '>') || CHECK(string, '\'') - || CHECK(string, '"') || CHECK(string, '%') - || CHECK(string, '@') || CHECK(string, '`')) { - flow_indicators = 1; - block_indicators = 1; - } - - if (CHECK(string, '?') || CHECK(string, ':')) { - flow_indicators = 1; - if (followed_by_whitespace) { - block_indicators = 1; - } - } - - if (CHECK(string, '-') && followed_by_whitespace) { - flow_indicators = 1; - block_indicators = 1; - } - } - else - { - if (CHECK(string, ',') || CHECK(string, '?') - || CHECK(string, '[') || CHECK(string, ']') - || CHECK(string, '{') || CHECK(string, '}')) { - flow_indicators = 1; - } - - if (CHECK(string, ':')) { - flow_indicators = 1; - if (followed_by_whitespace) { - block_indicators = 1; - } - } - - if (CHECK(string, '#') && preceded_by_whitespace) { - flow_indicators = 1; - block_indicators = 1; - } - } - - if (!IS_PRINTABLE(string) - || (!IS_ASCII(string) && !emitter->unicode)) { - special_characters = 1; - } - - if (IS_BREAK(string)) { - line_breaks = 1; - } - - if (IS_SPACE(string)) - { - if (string.start == string.pointer) { - leading_space = 1; - } - if (string.pointer+WIDTH(string) == string.end) { - trailing_space = 1; - } - if (previous_break) { - break_space = 1; - } - previous_space = 1; - previous_break = 0; - } - else if (IS_BREAK(string)) - { - if (string.start == string.pointer) { - leading_break = 1; - } - if (string.pointer+WIDTH(string) == string.end) { - trailing_break = 1; - } - if (previous_space) { - space_break = 1; - } - previous_space = 0; - previous_break = 1; - } - else - { - previous_space = 0; - previous_break = 0; - } - - preceded_by_whitespace = IS_BLANKZ(string); - MOVE(string); - if (string.pointer != string.end) { - followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); - } - } - - emitter->scalar_data.multiline = line_breaks; - - emitter->scalar_data.flow_plain_allowed = 1; - emitter->scalar_data.block_plain_allowed = 1; - emitter->scalar_data.single_quoted_allowed = 1; - emitter->scalar_data.block_allowed = 1; - - if (leading_space || leading_break || trailing_space || trailing_break) { - emitter->scalar_data.flow_plain_allowed = 0; - emitter->scalar_data.block_plain_allowed = 0; - } - - if (trailing_space) { - emitter->scalar_data.block_allowed = 0; - } - - if (break_space) { - emitter->scalar_data.flow_plain_allowed = 0; - emitter->scalar_data.block_plain_allowed = 0; - emitter->scalar_data.single_quoted_allowed = 0; - } - - if (space_break || special_characters) { - emitter->scalar_data.flow_plain_allowed = 0; - emitter->scalar_data.block_plain_allowed = 0; - emitter->scalar_data.single_quoted_allowed = 0; - emitter->scalar_data.block_allowed = 0; - } - - if (line_breaks) { - emitter->scalar_data.flow_plain_allowed = 0; - emitter->scalar_data.block_plain_allowed = 0; - } - - if (flow_indicators) { - emitter->scalar_data.flow_plain_allowed = 0; - } - - if (block_indicators) { - emitter->scalar_data.block_plain_allowed = 0; - } - - return 1; -} - -/* - * Check if the event data is valid. - */ - -static int -yaml_emitter_analyze_event(yaml_emitter_t *emitter, - yaml_event_t *event) -{ - emitter->anchor_data.anchor = NULL; - emitter->anchor_data.anchor_length = 0; - emitter->tag_data.handle = NULL; - emitter->tag_data.handle_length = 0; - emitter->tag_data.suffix = NULL; - emitter->tag_data.suffix_length = 0; - emitter->scalar_data.value = NULL; - emitter->scalar_data.length = 0; - - switch (event->type) - { - case YAML_ALIAS_EVENT: - if (!yaml_emitter_analyze_anchor(emitter, - event->data.alias.anchor, 1)) - return 0; - return 1; - - case YAML_SCALAR_EVENT: - if (event->data.scalar.anchor) { - if (!yaml_emitter_analyze_anchor(emitter, - event->data.scalar.anchor, 0)) - return 0; - } - if (event->data.scalar.tag && (emitter->canonical || - (!event->data.scalar.plain_implicit - && !event->data.scalar.quoted_implicit))) { - if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) - return 0; - } - if (!yaml_emitter_analyze_scalar(emitter, - event->data.scalar.value, event->data.scalar.length)) - return 0; - return 1; - - case YAML_SEQUENCE_START_EVENT: - if (event->data.sequence_start.anchor) { - if (!yaml_emitter_analyze_anchor(emitter, - event->data.sequence_start.anchor, 0)) - return 0; - } - if (event->data.sequence_start.tag && (emitter->canonical || - !event->data.sequence_start.implicit)) { - if (!yaml_emitter_analyze_tag(emitter, - event->data.sequence_start.tag)) - return 0; - } - return 1; - - case YAML_MAPPING_START_EVENT: - if (event->data.mapping_start.anchor) { - if (!yaml_emitter_analyze_anchor(emitter, - event->data.mapping_start.anchor, 0)) - return 0; - } - if (event->data.mapping_start.tag && (emitter->canonical || - !event->data.mapping_start.implicit)) { - if (!yaml_emitter_analyze_tag(emitter, - event->data.mapping_start.tag)) - return 0; - } - return 1; - - default: - return 1; - } -} - -/* - * Write the BOM character. - */ - -static int -yaml_emitter_write_bom(yaml_emitter_t *emitter) -{ - if (!FLUSH(emitter)) return 0; - - *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF'; - *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB'; - *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF'; - - return 1; -} - -static int -yaml_emitter_write_indent(yaml_emitter_t *emitter) -{ - int indent = (emitter->indent >= 0) ? emitter->indent : 0; - - if (!emitter->indention || emitter->column > indent - || (emitter->column == indent && !emitter->whitespace)) { - if (!PUT_BREAK(emitter)) return 0; - } - - while (emitter->column < indent) { - if (!PUT(emitter, ' ')) return 0; - } - - emitter->whitespace = 1; - emitter->indention = 1; - - return 1; -} - -static int -yaml_emitter_write_indicator(yaml_emitter_t *emitter, - const char *indicator, int need_whitespace, - int is_whitespace, int is_indention) -{ - size_t indicator_length; - yaml_string_t string; - - indicator_length = strlen(indicator); - STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length); - - if (need_whitespace && !emitter->whitespace) { - if (!PUT(emitter, ' ')) return 0; - } - - while (string.pointer != string.end) { - if (!WRITE(emitter, string)) return 0; - } - - emitter->whitespace = is_whitespace; - emitter->indention = (emitter->indention && is_indention); - - return 1; -} - -static int -yaml_emitter_write_anchor(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length) -{ - yaml_string_t string; - STRING_ASSIGN(string, value, length); - - while (string.pointer != string.end) { - if (!WRITE(emitter, string)) return 0; - } - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length) -{ - yaml_string_t string; - STRING_ASSIGN(string, value, length); - - if (!emitter->whitespace) { - if (!PUT(emitter, ' ')) return 0; - } - - while (string.pointer != string.end) { - if (!WRITE(emitter, string)) return 0; - } - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_tag_content(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, - int need_whitespace) -{ - yaml_string_t string; - STRING_ASSIGN(string, value, length); - - if (need_whitespace && !emitter->whitespace) { - if (!PUT(emitter, ' ')) return 0; - } - - while (string.pointer != string.end) { - if (IS_ALPHA(string) - || CHECK(string, ';') || CHECK(string, '/') - || CHECK(string, '?') || CHECK(string, ':') - || CHECK(string, '@') || CHECK(string, '&') - || CHECK(string, '=') || CHECK(string, '+') - || CHECK(string, '$') || CHECK(string, ',') - || CHECK(string, '_') || CHECK(string, '.') - || CHECK(string, '~') || CHECK(string, '*') - || CHECK(string, '\'') || CHECK(string, '(') - || CHECK(string, ')') || CHECK(string, '[') - || CHECK(string, ']')) { - if (!WRITE(emitter, string)) return 0; - } - else { - int width = WIDTH(string); - unsigned int value; - while (width --) { - value = *(string.pointer++); - if (!PUT(emitter, '%')) return 0; - if (!PUT(emitter, (value >> 4) - + ((value >> 4) < 10 ? '0' : 'A' - 10))) - return 0; - if (!PUT(emitter, (value & 0x0F) - + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) - return 0; - } - } - } - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks) -{ - yaml_string_t string; - int spaces = 0; - int breaks = 0; - - STRING_ASSIGN(string, value, length); - - /** - * Avoid trailing spaces for empty values in block mode. - * In flow mode, we still want the space to prevent ambiguous things - * like {a:}. - * Currently, the emitter forbids any plain empty scalar in flow mode - * (e.g. it outputs {a: ''} instead), so emitter->flow_level will - * never be true here. - * But if the emitter is ever changed to allow emitting empty values, - * the check for flow_level is already here. - */ - if (!emitter->whitespace && (length || emitter->flow_level)) { - if (!PUT(emitter, ' ')) return 0; - } - - while (string.pointer != string.end) - { - if (IS_SPACE(string)) - { - if (allow_breaks && !spaces - && emitter->column > emitter->best_width - && !IS_SPACE_AT(string, 1)) { - if (!yaml_emitter_write_indent(emitter)) return 0; - MOVE(string); - } - else { - if (!WRITE(emitter, string)) return 0; - } - spaces = 1; - } - else if (IS_BREAK(string)) - { - if (!breaks && CHECK(string, '\n')) { - if (!PUT_BREAK(emitter)) return 0; - } - if (!WRITE_BREAK(emitter, string)) return 0; - emitter->indention = 1; - breaks = 1; - } - else - { - if (breaks) { - if (!yaml_emitter_write_indent(emitter)) return 0; - } - if (!WRITE(emitter, string)) return 0; - emitter->indention = 0; - spaces = 0; - breaks = 0; - } - } - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks) -{ - yaml_string_t string; - int spaces = 0; - int breaks = 0; - - STRING_ASSIGN(string, value, length); - - if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0)) - return 0; - - while (string.pointer != string.end) - { - if (IS_SPACE(string)) - { - if (allow_breaks && !spaces - && emitter->column > emitter->best_width - && string.pointer != string.start - && string.pointer != string.end - 1 - && !IS_SPACE_AT(string, 1)) { - if (!yaml_emitter_write_indent(emitter)) return 0; - MOVE(string); - } - else { - if (!WRITE(emitter, string)) return 0; - } - spaces = 1; - } - else if (IS_BREAK(string)) - { - if (!breaks && CHECK(string, '\n')) { - if (!PUT_BREAK(emitter)) return 0; - } - if (!WRITE_BREAK(emitter, string)) return 0; - emitter->indention = 1; - breaks = 1; - } - else - { - if (breaks) { - if (!yaml_emitter_write_indent(emitter)) return 0; - } - if (CHECK(string, '\'')) { - if (!PUT(emitter, '\'')) return 0; - } - if (!WRITE(emitter, string)) return 0; - emitter->indention = 0; - spaces = 0; - breaks = 0; - } - } - - if (breaks) - if (!yaml_emitter_write_indent(emitter)) return 0; - - if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0)) - return 0; - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length, int allow_breaks) -{ - yaml_string_t string; - int spaces = 0; - - STRING_ASSIGN(string, value, length); - - if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0)) - return 0; - - while (string.pointer != string.end) - { - if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string)) - || IS_BOM(string) || IS_BREAK(string) - || CHECK(string, '"') || CHECK(string, '\\')) - { - unsigned char octet; - unsigned int width; - unsigned int value; - int k; - - octet = string.pointer[0]; - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; - value = (octet & 0x80) == 0x00 ? octet & 0x7F : - (octet & 0xE0) == 0xC0 ? octet & 0x1F : - (octet & 0xF0) == 0xE0 ? octet & 0x0F : - (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; - for (k = 1; k < (int)width; k ++) { - octet = string.pointer[k]; - value = (value << 6) + (octet & 0x3F); - } - string.pointer += width; - - if (!PUT(emitter, '\\')) return 0; - - switch (value) - { - case 0x00: - if (!PUT(emitter, '0')) return 0; - break; - - case 0x07: - if (!PUT(emitter, 'a')) return 0; - break; - - case 0x08: - if (!PUT(emitter, 'b')) return 0; - break; - - case 0x09: - if (!PUT(emitter, 't')) return 0; - break; - - case 0x0A: - if (!PUT(emitter, 'n')) return 0; - break; - - case 0x0B: - if (!PUT(emitter, 'v')) return 0; - break; - - case 0x0C: - if (!PUT(emitter, 'f')) return 0; - break; - - case 0x0D: - if (!PUT(emitter, 'r')) return 0; - break; - - case 0x1B: - if (!PUT(emitter, 'e')) return 0; - break; - - case 0x22: - if (!PUT(emitter, '\"')) return 0; - break; - - case 0x5C: - if (!PUT(emitter, '\\')) return 0; - break; - - case 0x85: - if (!PUT(emitter, 'N')) return 0; - break; - - case 0xA0: - if (!PUT(emitter, '_')) return 0; - break; - - case 0x2028: - if (!PUT(emitter, 'L')) return 0; - break; - - case 0x2029: - if (!PUT(emitter, 'P')) return 0; - break; - - default: - if (value <= 0xFF) { - if (!PUT(emitter, 'x')) return 0; - width = 2; - } - else if (value <= 0xFFFF) { - if (!PUT(emitter, 'u')) return 0; - width = 4; - } - else { - if (!PUT(emitter, 'U')) return 0; - width = 8; - } - for (k = (width-1)*4; k >= 0; k -= 4) { - int digit = (value >> k) & 0x0F; - if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) - return 0; - } - } - spaces = 0; - } - else if (IS_SPACE(string)) - { - if (allow_breaks && !spaces - && emitter->column > emitter->best_width - && string.pointer != string.start - && string.pointer != string.end - 1) { - if (!yaml_emitter_write_indent(emitter)) return 0; - if (IS_SPACE_AT(string, 1)) { - if (!PUT(emitter, '\\')) return 0; - } - MOVE(string); - } - else { - if (!WRITE(emitter, string)) return 0; - } - spaces = 1; - } - else - { - if (!WRITE(emitter, string)) return 0; - spaces = 0; - } - } - - if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0)) - return 0; - - emitter->whitespace = 0; - emitter->indention = 0; - - return 1; -} - -static int -yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, - yaml_string_t string) -{ - char indent_hint[2]; - const char *chomp_hint = NULL; - - if (IS_SPACE(string) || IS_BREAK(string)) - { - indent_hint[0] = '0' + (char)emitter->best_indent; - indent_hint[1] = '\0'; - if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0)) - return 0; - } - - emitter->open_ended = 0; - - string.pointer = string.end; - if (string.start == string.pointer) - { - chomp_hint = "-"; - } - else - { - do { - string.pointer --; - } while ((*string.pointer & 0xC0) == 0x80); - if (!IS_BREAK(string)) - { - chomp_hint = "-"; - } - else if (string.start == string.pointer) - { - chomp_hint = "+"; - emitter->open_ended = 2; - } - else - { - do { - string.pointer --; - } while ((*string.pointer & 0xC0) == 0x80); - if (IS_BREAK(string)) - { - chomp_hint = "+"; - emitter->open_ended = 2; - } - } - } - - if (chomp_hint) - { - if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0)) - return 0; - } - - return 1; -} - -static int -yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length) -{ - yaml_string_t string; - int breaks = 1; - - STRING_ASSIGN(string, value, length); - - if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0)) - return 0; - if (!yaml_emitter_write_block_scalar_hints(emitter, string)) - return 0; - if (!PUT_BREAK(emitter)) return 0; - emitter->indention = 1; - emitter->whitespace = 1; - - while (string.pointer != string.end) - { - if (IS_BREAK(string)) - { - if (!WRITE_BREAK(emitter, string)) return 0; - emitter->indention = 1; - breaks = 1; - } - else - { - if (breaks) { - if (!yaml_emitter_write_indent(emitter)) return 0; - } - if (!WRITE(emitter, string)) return 0; - emitter->indention = 0; - breaks = 0; - } - } - - return 1; -} - -static int -yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, - yaml_char_t *value, size_t length) -{ - yaml_string_t string; - int breaks = 1; - int leading_spaces = 1; - - STRING_ASSIGN(string, value, length); - - if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0)) - return 0; - if (!yaml_emitter_write_block_scalar_hints(emitter, string)) - return 0; - if (!PUT_BREAK(emitter)) return 0; - emitter->indention = 1; - emitter->whitespace = 1; - - while (string.pointer != string.end) - { - if (IS_BREAK(string)) - { - if (!breaks && !leading_spaces && CHECK(string, '\n')) { - int k = 0; - while (IS_BREAK_AT(string, k)) { - k += WIDTH_AT(string, k); - } - if (!IS_BLANKZ_AT(string, k)) { - if (!PUT_BREAK(emitter)) return 0; - } - } - if (!WRITE_BREAK(emitter, string)) return 0; - emitter->indention = 1; - breaks = 1; - } - else - { - if (breaks) { - if (!yaml_emitter_write_indent(emitter)) return 0; - leading_spaces = IS_BLANK(string); - } - if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1) - && emitter->column > emitter->best_width) { - if (!yaml_emitter_write_indent(emitter)) return 0; - MOVE(string); - } - else { - if (!WRITE(emitter, string)) return 0; - } - emitter->indention = 0; - breaks = 0; - } - } - - return 1; -} diff --git a/ext/psych/yaml/loader.c b/ext/psych/yaml/loader.c deleted file mode 100644 index bcf3aee8cb..0000000000 --- a/ext/psych/yaml/loader.c +++ /dev/null @@ -1,544 +0,0 @@ - -#include "yaml_private.h" - -/* - * API functions. - */ - -YAML_DECLARE(int) -yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); - -/* - * Error handling. - */ - -static int -yaml_parser_set_composer_error(yaml_parser_t *parser, - const char *problem, yaml_mark_t problem_mark); - -static int -yaml_parser_set_composer_error_context(yaml_parser_t *parser, - const char *context, yaml_mark_t context_mark, - const char *problem, yaml_mark_t problem_mark); - - -/* - * Alias handling. - */ - -static int -yaml_parser_register_anchor(yaml_parser_t *parser, - int index, yaml_char_t *anchor); - -/* - * Clean up functions. - */ - -static void -yaml_parser_delete_aliases(yaml_parser_t *parser); - -/* - * Document loading context. - */ -struct loader_ctx { - int *start; - int *end; - int *top; -}; - -/* - * Composer functions. - */ -static int -yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx); - -static int -yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event); - -static int -yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -static int -yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -static int -yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -static int -yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -static int -yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -static int -yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx); - -/* - * Load the next document of the stream. - */ - -YAML_DECLARE(int) -yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document) -{ - yaml_event_t event; - - assert(parser); /* Non-NULL parser object is expected. */ - assert(document); /* Non-NULL document object is expected. */ - - memset(document, 0, sizeof(yaml_document_t)); - if (!STACK_INIT(parser, document->nodes, yaml_node_t*)) - goto error; - - if (!parser->stream_start_produced) { - if (!yaml_parser_parse(parser, &event)) goto error; - assert(event.type == YAML_STREAM_START_EVENT); - /* STREAM-START is expected. */ - } - - if (parser->stream_end_produced) { - return 1; - } - - if (!yaml_parser_parse(parser, &event)) goto error; - if (event.type == YAML_STREAM_END_EVENT) { - return 1; - } - - if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*)) - goto error; - - parser->document = document; - - if (!yaml_parser_load_document(parser, &event)) goto error; - - yaml_parser_delete_aliases(parser); - parser->document = NULL; - - return 1; - -error: - - yaml_parser_delete_aliases(parser); - yaml_document_delete(document); - parser->document = NULL; - - return 0; -} - -/* - * Set composer error. - */ - -static int -yaml_parser_set_composer_error(yaml_parser_t *parser, - const char *problem, yaml_mark_t problem_mark) -{ - parser->error = YAML_COMPOSER_ERROR; - parser->problem = problem; - parser->problem_mark = problem_mark; - - return 0; -} - -/* - * Set composer error with context. - */ - -static int -yaml_parser_set_composer_error_context(yaml_parser_t *parser, - const char *context, yaml_mark_t context_mark, - const char *problem, yaml_mark_t problem_mark) -{ - parser->error = YAML_COMPOSER_ERROR; - parser->context = context; - parser->context_mark = context_mark; - parser->problem = problem; - parser->problem_mark = problem_mark; - - return 0; -} - -/* - * Delete the stack of aliases. - */ - -static void -yaml_parser_delete_aliases(yaml_parser_t *parser) -{ - while (!STACK_EMPTY(parser, parser->aliases)) { - yaml_free(POP(parser, parser->aliases).anchor); - } - STACK_DEL(parser, parser->aliases); -} - -/* - * Compose a document object. - */ - -static int -yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event) -{ - struct loader_ctx ctx = { NULL, NULL, NULL }; - - assert(event->type == YAML_DOCUMENT_START_EVENT); - /* DOCUMENT-START is expected. */ - - parser->document->version_directive - = event->data.document_start.version_directive; - parser->document->tag_directives.start - = event->data.document_start.tag_directives.start; - parser->document->tag_directives.end - = event->data.document_start.tag_directives.end; - parser->document->start_implicit - = event->data.document_start.implicit; - parser->document->start_mark = event->start_mark; - - if (!STACK_INIT(parser, ctx, int*)) return 0; - if (!yaml_parser_load_nodes(parser, &ctx)) { - STACK_DEL(parser, ctx); - return 0; - } - STACK_DEL(parser, ctx); - - return 1; -} - -/* - * Compose a node tree. - */ - -static int -yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx) -{ - yaml_event_t event; - - do { - if (!yaml_parser_parse(parser, &event)) return 0; - - switch (event.type) { - case YAML_ALIAS_EVENT: - if (!yaml_parser_load_alias(parser, &event, ctx)) return 0; - break; - case YAML_SCALAR_EVENT: - if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0; - break; - case YAML_SEQUENCE_START_EVENT: - if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0; - break; - case YAML_SEQUENCE_END_EVENT: - if (!yaml_parser_load_sequence_end(parser, &event, ctx)) - return 0; - break; - case YAML_MAPPING_START_EVENT: - if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0; - break; - case YAML_MAPPING_END_EVENT: - if (!yaml_parser_load_mapping_end(parser, &event, ctx)) - return 0; - break; - default: - assert(0); /* Could not happen. */ - return 0; - case YAML_DOCUMENT_END_EVENT: - break; - } - } while (event.type != YAML_DOCUMENT_END_EVENT); - - parser->document->end_implicit = event.data.document_end.implicit; - parser->document->end_mark = event.end_mark; - - return 1; -} - -/* - * Add an anchor. - */ - -static int -yaml_parser_register_anchor(yaml_parser_t *parser, - int index, yaml_char_t *anchor) -{ - yaml_alias_data_t data; - yaml_alias_data_t *alias_data; - - if (!anchor) return 1; - - data.anchor = anchor; - data.index = index; - data.mark = parser->document->nodes.start[index-1].start_mark; - - for (alias_data = parser->aliases.start; - alias_data != parser->aliases.top; alias_data ++) { - if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { - yaml_free(anchor); - return yaml_parser_set_composer_error_context(parser, - "found duplicate anchor; first occurrence", - alias_data->mark, "second occurrence", data.mark); - } - } - - if (!PUSH(parser, parser->aliases, data)) { - yaml_free(anchor); - return 0; - } - - return 1; -} - -/* - * Compose node into its parent in the stree. - */ - -static int -yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx, - int index) -{ - struct yaml_node_s *parent; - int parent_index; - - if (STACK_EMPTY(parser, *ctx)) { - /* This is the root node, there's no tree to add it to. */ - return 1; - } - - parent_index = *((*ctx).top - 1); - parent = &parser->document->nodes.start[parent_index-1]; - - switch (parent->type) { - case YAML_SEQUENCE_NODE: - if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1)) - return 0; - if (!PUSH(parser, parent->data.sequence.items, index)) - return 0; - break; - case YAML_MAPPING_NODE: { - yaml_node_pair_t pair; - if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) { - yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1; - if (p->key != 0 && p->value == 0) { - p->value = index; - break; - } - } - - pair.key = index; - pair.value = 0; - if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1)) - return 0; - if (!PUSH(parser, parent->data.mapping.pairs, pair)) - return 0; - - break; - } - default: - assert(0); /* Could not happen. */ - return 0; - } - return 1; -} - -/* - * Compose a node corresponding to an alias. - */ - -static int -yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - yaml_char_t *anchor = event->data.alias.anchor; - yaml_alias_data_t *alias_data; - - for (alias_data = parser->aliases.start; - alias_data != parser->aliases.top; alias_data ++) { - if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { - yaml_free(anchor); - return yaml_parser_load_node_add(parser, ctx, alias_data->index); - } - } - - yaml_free(anchor); - return yaml_parser_set_composer_error(parser, "found undefined alias", - event->start_mark); -} - -/* - * Compose a scalar node. - */ - -static int -yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - yaml_node_t node; - int index; - yaml_char_t *tag = event->data.scalar.tag; - - if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; - - if (!tag || strcmp((char *)tag, "!") == 0) { - yaml_free(tag); - tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); - if (!tag) goto error; - } - - SCALAR_NODE_INIT(node, tag, event->data.scalar.value, - event->data.scalar.length, event->data.scalar.style, - event->start_mark, event->end_mark); - - if (!PUSH(parser, parser->document->nodes, node)) goto error; - - index = (int)(parser->document->nodes.top - parser->document->nodes.start); - - if (!yaml_parser_register_anchor(parser, index, - event->data.scalar.anchor)) return 0; - - return yaml_parser_load_node_add(parser, ctx, index); - -error: - yaml_free(tag); - yaml_free(event->data.scalar.anchor); - yaml_free(event->data.scalar.value); - return 0; -} - -/* - * Compose a sequence node. - */ - -static int -yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - yaml_node_t node; - struct { - yaml_node_item_t *start; - yaml_node_item_t *end; - yaml_node_item_t *top; - } items = { NULL, NULL, NULL }; - int index; - yaml_char_t *tag = event->data.sequence_start.tag; - - if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; - - if (!tag || strcmp((char *)tag, "!") == 0) { - yaml_free(tag); - tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); - if (!tag) goto error; - } - - if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error; - - SEQUENCE_NODE_INIT(node, tag, items.start, items.end, - event->data.sequence_start.style, - event->start_mark, event->end_mark); - - if (!PUSH(parser, parser->document->nodes, node)) goto error; - - index = (int)(parser->document->nodes.top - parser->document->nodes.start); - - if (!yaml_parser_register_anchor(parser, index, - event->data.sequence_start.anchor)) return 0; - - if (!yaml_parser_load_node_add(parser, ctx, index)) return 0; - - if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0; - if (!PUSH(parser, *ctx, index)) return 0; - - return 1; - -error: - yaml_free(tag); - yaml_free(event->data.sequence_start.anchor); - return 0; -} - -static int -yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - int index; - - assert(((*ctx).top - (*ctx).start) > 0); - - index = *((*ctx).top - 1); - assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE); - parser->document->nodes.start[index-1].end_mark = event->end_mark; - - (void)POP(parser, *ctx); - - return 1; -} - -/* - * Compose a mapping node. - */ - -static int -yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - yaml_node_t node; - struct { - yaml_node_pair_t *start; - yaml_node_pair_t *end; - yaml_node_pair_t *top; - } pairs = { NULL, NULL, NULL }; - int index; - yaml_char_t *tag = event->data.mapping_start.tag; - - if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; - - if (!tag || strcmp((char *)tag, "!") == 0) { - yaml_free(tag); - tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); - if (!tag) goto error; - } - - if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error; - - MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end, - event->data.mapping_start.style, - event->start_mark, event->end_mark); - - if (!PUSH(parser, parser->document->nodes, node)) goto error; - - index = (int)(parser->document->nodes.top - parser->document->nodes.start); - - if (!yaml_parser_register_anchor(parser, index, - event->data.mapping_start.anchor)) return 0; - - if (!yaml_parser_load_node_add(parser, ctx, index)) return 0; - - if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0; - if (!PUSH(parser, *ctx, index)) return 0; - - return 1; - -error: - yaml_free(tag); - yaml_free(event->data.mapping_start.anchor); - return 0; -} - -static int -yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event, - struct loader_ctx *ctx) -{ - int index; - - assert(((*ctx).top - (*ctx).start) > 0); - - index = *((*ctx).top - 1); - assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE); - parser->document->nodes.start[index-1].end_mark = event->end_mark; - - (void)POP(parser, *ctx); - - return 1; -} diff --git a/ext/psych/yaml/parser.c b/ext/psych/yaml/parser.c deleted file mode 100644 index ec2f8d3e05..0000000000 --- a/ext/psych/yaml/parser.c +++ /dev/null @@ -1,1375 +0,0 @@ - -/* - * The parser implements the following grammar: - * - * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END - * implicit_document ::= block_node DOCUMENT-END* - * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - * block_node_or_indentless_sequence ::= - * ALIAS - * | properties (block_content | indentless_block_sequence)? - * | block_content - * | indentless_block_sequence - * block_node ::= ALIAS - * | properties block_content? - * | block_content - * flow_node ::= ALIAS - * | properties flow_content? - * | flow_content - * properties ::= TAG ANCHOR? | ANCHOR TAG? - * block_content ::= block_collection | flow_collection | SCALAR - * flow_content ::= flow_collection | SCALAR - * block_collection ::= block_sequence | block_mapping - * flow_collection ::= flow_sequence | flow_mapping - * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END - * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ - * block_mapping ::= BLOCK-MAPPING_START - * ((KEY block_node_or_indentless_sequence?)? - * (VALUE block_node_or_indentless_sequence?)?)* - * BLOCK-END - * flow_sequence ::= FLOW-SEQUENCE-START - * (flow_sequence_entry FLOW-ENTRY)* - * flow_sequence_entry? - * FLOW-SEQUENCE-END - * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * flow_mapping ::= FLOW-MAPPING-START - * (flow_mapping_entry FLOW-ENTRY)* - * flow_mapping_entry? - * FLOW-MAPPING-END - * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - */ - -#include "yaml_private.h" - -/* - * Peek the next token in the token queue. - */ - -#define PEEK_TOKEN(parser) \ - ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \ - parser->tokens.head : NULL) - -/* - * Remove the next token from the queue (must be called after PEEK_TOKEN). - */ - -#define SKIP_TOKEN(parser) \ - (parser->token_available = 0, \ - parser->tokens_parsed ++, \ - parser->stream_end_produced = \ - (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \ - parser->tokens.head ++) - -/* - * Public API declarations. - */ - -YAML_DECLARE(int) -yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); - -/* - * Error handling. - */ - -static int -yaml_parser_set_parser_error(yaml_parser_t *parser, - const char *problem, yaml_mark_t problem_mark); - -static int -yaml_parser_set_parser_error_context(yaml_parser_t *parser, - const char *context, yaml_mark_t context_mark, - const char *problem, yaml_mark_t problem_mark); - -/* - * State functions. - */ - -static int -yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event); - -static int -yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event); - -static int -yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, - int implicit); - -static int -yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event); - -static int -yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event); - -static int -yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, - int block, int indentless_sequence); - -static int -yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event, int first); - -static int -yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event); - -static int -yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, - yaml_event_t *event, int first); - -static int -yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, - yaml_event_t *event); - -static int -yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event, int first); - -static int -yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, - yaml_event_t *event); - -static int -yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, - yaml_event_t *event); - -static int -yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, - yaml_event_t *event); - -static int -yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, - yaml_event_t *event, int first); - -static int -yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, - yaml_event_t *event, int empty); - -/* - * Utility functions. - */ - -static int -yaml_parser_process_empty_scalar(yaml_parser_t *parser, - yaml_event_t *event, yaml_mark_t mark); - -static int -yaml_parser_process_directives(yaml_parser_t *parser, - yaml_version_directive_t **version_directive_ref, - yaml_tag_directive_t **tag_directives_start_ref, - yaml_tag_directive_t **tag_directives_end_ref); - -static int -yaml_parser_append_tag_directive(yaml_parser_t *parser, - yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark); - -/* - * Get the next event. - */ - -YAML_DECLARE(int) -yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event) -{ - assert(parser); /* Non-NULL parser object is expected. */ - assert(event); /* Non-NULL event object is expected. */ - - /* Erase the event object. */ - - memset(event, 0, sizeof(yaml_event_t)); - - /* No events after the end of the stream or error. */ - - if (parser->stream_end_produced || parser->error || - parser->state == YAML_PARSE_END_STATE) { - return 1; - } - - /* Generate the next event. */ - - return yaml_parser_state_machine(parser, event); -} - -/* - * Set parser error. - */ - -static int -yaml_parser_set_parser_error(yaml_parser_t *parser, - const char *problem, yaml_mark_t problem_mark) -{ - parser->error = YAML_PARSER_ERROR; - parser->problem = problem; - parser->problem_mark = problem_mark; - - return 0; -} - -static int -yaml_parser_set_parser_error_context(yaml_parser_t *parser, - const char *context, yaml_mark_t context_mark, - const char *problem, yaml_mark_t problem_mark) -{ - parser->error = YAML_PARSER_ERROR; - parser->context = context; - parser->context_mark = context_mark; - parser->problem = problem; - parser->problem_mark = problem_mark; - - return 0; -} - - -/* - * State dispatcher. - */ - -static int -yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event) -{ - switch (parser->state) - { - case YAML_PARSE_STREAM_START_STATE: - return yaml_parser_parse_stream_start(parser, event); - - case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, 1); - - case YAML_PARSE_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, 0); - - case YAML_PARSE_DOCUMENT_CONTENT_STATE: - return yaml_parser_parse_document_content(parser, event); - - case YAML_PARSE_DOCUMENT_END_STATE: - return yaml_parser_parse_document_end(parser, event); - - case YAML_PARSE_BLOCK_NODE_STATE: - return yaml_parser_parse_node(parser, event, 1, 0); - - case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return yaml_parser_parse_node(parser, event, 1, 1); - - case YAML_PARSE_FLOW_NODE_STATE: - return yaml_parser_parse_node(parser, event, 0, 0); - - case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, 1); - - case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, 0); - - case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_indentless_sequence_entry(parser, event); - - case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, 1); - - case YAML_PARSE_BLOCK_MAPPING_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, 0); - - case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: - return yaml_parser_parse_block_mapping_value(parser, event); - - case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, 1); - - case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, 0); - - case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event); - - case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event); - - case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event); - - case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, 1); - - case YAML_PARSE_FLOW_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, 0); - - case YAML_PARSE_FLOW_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, 0); - - case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, 1); - - default: - assert(1); /* Invalid state. */ - } - - return 0; -} - -/* - * Parse the production: - * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END - * ************ - */ - -static int -yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type != YAML_STREAM_START_TOKEN) { - return yaml_parser_set_parser_error(parser, - "did not find expected <stream-start>", token->start_mark); - } - - parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; - STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding, - token->start_mark, token->start_mark); - SKIP_TOKEN(parser); - - return 1; -} - -/* - * Parse the productions: - * implicit_document ::= block_node DOCUMENT-END* - * * - * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - * ************************* - */ - -static int -yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, - int implicit) -{ - yaml_token_t *token; - yaml_version_directive_t *version_directive = NULL; - struct { - yaml_tag_directive_t *start; - yaml_tag_directive_t *end; - } tag_directives = { NULL, NULL }; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - /* Parse extra document end indicators. */ - - if (!implicit) - { - while (token->type == YAML_DOCUMENT_END_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - } - } - - /* Parse an implicit document. */ - - if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN && - token->type != YAML_TAG_DIRECTIVE_TOKEN && - token->type != YAML_DOCUMENT_START_TOKEN && - token->type != YAML_STREAM_END_TOKEN) - { - if (!yaml_parser_process_directives(parser, NULL, NULL, NULL)) - return 0; - if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) - return 0; - parser->state = YAML_PARSE_BLOCK_NODE_STATE; - DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1, - token->start_mark, token->start_mark); - return 1; - } - - /* Parse an explicit document. */ - - else if (token->type != YAML_STREAM_END_TOKEN) - { - yaml_mark_t start_mark, end_mark; - start_mark = token->start_mark; - if (!yaml_parser_process_directives(parser, &version_directive, - &tag_directives.start, &tag_directives.end)) - return 0; - token = PEEK_TOKEN(parser); - if (!token) goto error; - if (token->type != YAML_DOCUMENT_START_TOKEN) { - yaml_parser_set_parser_error(parser, - "did not find expected <document start>", token->start_mark); - goto error; - } - if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) - goto error; - parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE; - end_mark = token->end_mark; - DOCUMENT_START_EVENT_INIT(*event, version_directive, - tag_directives.start, tag_directives.end, 0, - start_mark, end_mark); - SKIP_TOKEN(parser); - version_directive = NULL; - tag_directives.start = tag_directives.end = NULL; - return 1; - } - - /* Parse the stream end. */ - - else - { - parser->state = YAML_PARSE_END_STATE; - STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; - } - -error: - yaml_free(version_directive); - while (tag_directives.start != tag_directives.end) { - yaml_free(tag_directives.end[-1].handle); - yaml_free(tag_directives.end[-1].prefix); - tag_directives.end --; - } - yaml_free(tag_directives.start); - return 0; -} - -/* - * Parse the productions: - * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - * *********** - */ - -static int -yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_VERSION_DIRECTIVE_TOKEN || - token->type == YAML_TAG_DIRECTIVE_TOKEN || - token->type == YAML_DOCUMENT_START_TOKEN || - token->type == YAML_DOCUMENT_END_TOKEN || - token->type == YAML_STREAM_END_TOKEN) { - parser->state = POP(parser, parser->states); - return yaml_parser_process_empty_scalar(parser, event, - token->start_mark); - } - else { - return yaml_parser_parse_node(parser, event, 1, 0); - } -} - -/* - * Parse the productions: - * implicit_document ::= block_node DOCUMENT-END* - * ************* - * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - * ************* - */ - -static int -yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event) -{ - yaml_token_t *token; - yaml_mark_t start_mark, end_mark; - int implicit = 1; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - start_mark = end_mark = token->start_mark; - - if (token->type == YAML_DOCUMENT_END_TOKEN) { - end_mark = token->end_mark; - SKIP_TOKEN(parser); - implicit = 0; - } - - while (!STACK_EMPTY(parser, parser->tag_directives)) { - yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); - yaml_free(tag_directive.handle); - yaml_free(tag_directive.prefix); - } - - parser->state = YAML_PARSE_DOCUMENT_START_STATE; - DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark); - - return 1; -} - -/* - * Parse the productions: - * block_node_or_indentless_sequence ::= - * ALIAS - * ***** - * | properties (block_content | indentless_block_sequence)? - * ********** * - * | block_content | indentless_block_sequence - * * - * block_node ::= ALIAS - * ***** - * | properties block_content? - * ********** * - * | block_content - * * - * flow_node ::= ALIAS - * ***** - * | properties flow_content? - * ********** * - * | flow_content - * * - * properties ::= TAG ANCHOR? | ANCHOR TAG? - * ************************* - * block_content ::= block_collection | flow_collection | SCALAR - * ****** - * flow_content ::= flow_collection | SCALAR - * ****** - */ - -static int -yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, - int block, int indentless_sequence) -{ - yaml_token_t *token; - yaml_char_t *anchor = NULL; - yaml_char_t *tag_handle = NULL; - yaml_char_t *tag_suffix = NULL; - yaml_char_t *tag = NULL; - yaml_mark_t start_mark, end_mark, tag_mark; - int implicit; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_ALIAS_TOKEN) - { - parser->state = POP(parser, parser->states); - ALIAS_EVENT_INIT(*event, token->data.alias.value, - token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; - } - - else - { - start_mark = end_mark = token->start_mark; - - if (token->type == YAML_ANCHOR_TOKEN) - { - anchor = token->data.anchor.value; - start_mark = token->start_mark; - end_mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) goto error; - if (token->type == YAML_TAG_TOKEN) - { - tag_handle = token->data.tag.handle; - tag_suffix = token->data.tag.suffix; - tag_mark = token->start_mark; - end_mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) goto error; - } - } - else if (token->type == YAML_TAG_TOKEN) - { - tag_handle = token->data.tag.handle; - tag_suffix = token->data.tag.suffix; - start_mark = tag_mark = token->start_mark; - end_mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) goto error; - if (token->type == YAML_ANCHOR_TOKEN) - { - anchor = token->data.anchor.value; - end_mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) goto error; - } - } - - if (tag_handle) { - if (!*tag_handle) { - tag = tag_suffix; - yaml_free(tag_handle); - tag_handle = tag_suffix = NULL; - } - else { - yaml_tag_directive_t *tag_directive; - for (tag_directive = parser->tag_directives.start; - tag_directive != parser->tag_directives.top; - tag_directive ++) { - if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) { - size_t prefix_len = strlen((char *)tag_directive->prefix); - size_t suffix_len = strlen((char *)tag_suffix); - tag = YAML_MALLOC(prefix_len+suffix_len+1); - if (!tag) { - parser->error = YAML_MEMORY_ERROR; - goto error; - } - memcpy(tag, tag_directive->prefix, prefix_len); - memcpy(tag+prefix_len, tag_suffix, suffix_len); - tag[prefix_len+suffix_len] = '\0'; - yaml_free(tag_handle); - yaml_free(tag_suffix); - tag_handle = tag_suffix = NULL; - break; - } - } - if (!tag) { - yaml_parser_set_parser_error_context(parser, - "while parsing a node", start_mark, - "found undefined tag handle", tag_mark); - goto error; - } - } - } - - implicit = (!tag || !*tag); - if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) { - end_mark = token->end_mark; - parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; - SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, - YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); - return 1; - } - else { - if (token->type == YAML_SCALAR_TOKEN) { - int plain_implicit = 0; - int quoted_implicit = 0; - end_mark = token->end_mark; - if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag) - || (tag && strcmp((char *)tag, "!") == 0)) { - plain_implicit = 1; - } - else if (!tag) { - quoted_implicit = 1; - } - parser->state = POP(parser, parser->states); - SCALAR_EVENT_INIT(*event, anchor, tag, - token->data.scalar.value, token->data.scalar.length, - plain_implicit, quoted_implicit, - token->data.scalar.style, start_mark, end_mark); - SKIP_TOKEN(parser); - return 1; - } - else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) { - end_mark = token->end_mark; - parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; - SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, - YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark); - return 1; - } - else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) { - end_mark = token->end_mark; - parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; - MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, - YAML_FLOW_MAPPING_STYLE, start_mark, end_mark); - return 1; - } - else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) { - end_mark = token->end_mark; - parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; - SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, - YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); - return 1; - } - else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) { - end_mark = token->end_mark; - parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; - MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, - YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark); - return 1; - } - else if (anchor || tag) { - yaml_char_t *value = YAML_MALLOC(1); - if (!value) { - parser->error = YAML_MEMORY_ERROR; - goto error; - } - value[0] = '\0'; - parser->state = POP(parser, parser->states); - SCALAR_EVENT_INIT(*event, anchor, tag, value, 0, - implicit, 0, YAML_PLAIN_SCALAR_STYLE, - start_mark, end_mark); - return 1; - } - else { - yaml_parser_set_parser_error_context(parser, - (block ? "while parsing a block node" - : "while parsing a flow node"), start_mark, - "did not find expected node content", token->start_mark); - goto error; - } - } - } - -error: - yaml_free(anchor); - yaml_free(tag_handle); - yaml_free(tag_suffix); - yaml_free(tag); - - return 0; -} - -/* - * Parse the productions: - * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END - * ******************** *********** * ********* - */ - -static int -yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event, int first) -{ - yaml_token_t *token; - - if (first) { - token = PEEK_TOKEN(parser); - if (!PUSH(parser, parser->marks, token->start_mark)) - return 0; - SKIP_TOKEN(parser); - } - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_BLOCK_ENTRY_TOKEN) - { - yaml_mark_t mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_BLOCK_ENTRY_TOKEN && - token->type != YAML_BLOCK_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 1, 0); - } - else { - parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; - return yaml_parser_process_empty_scalar(parser, event, mark); - } - } - - else if (token->type == YAML_BLOCK_END_TOKEN) - { - parser->state = POP(parser, parser->states); - (void)POP(parser, parser->marks); - SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; - } - - else - { - return yaml_parser_set_parser_error_context(parser, - "while parsing a block collection", POP(parser, parser->marks), - "did not find expected '-' indicator", token->start_mark); - } -} - -/* - * Parse the productions: - * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ - * *********** * - */ - -static int -yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_BLOCK_ENTRY_TOKEN) - { - yaml_mark_t mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_BLOCK_ENTRY_TOKEN && - token->type != YAML_KEY_TOKEN && - token->type != YAML_VALUE_TOKEN && - token->type != YAML_BLOCK_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 1, 0); - } - else { - parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; - return yaml_parser_process_empty_scalar(parser, event, mark); - } - } - - else - { - parser->state = POP(parser, parser->states); - SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark); - return 1; - } -} - -/* - * Parse the productions: - * block_mapping ::= BLOCK-MAPPING_START - * ******************* - * ((KEY block_node_or_indentless_sequence?)? - * *** * - * (VALUE block_node_or_indentless_sequence?)?)* - * - * BLOCK-END - * ********* - */ - -static int -yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, - yaml_event_t *event, int first) -{ - yaml_token_t *token; - - if (first) { - token = PEEK_TOKEN(parser); - if (!PUSH(parser, parser->marks, token->start_mark)) - return 0; - SKIP_TOKEN(parser); - } - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_KEY_TOKEN) - { - yaml_mark_t mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_KEY_TOKEN && - token->type != YAML_VALUE_TOKEN && - token->type != YAML_BLOCK_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_BLOCK_MAPPING_VALUE_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 1, 1); - } - else { - parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; - return yaml_parser_process_empty_scalar(parser, event, mark); - } - } - - else if (token->type == YAML_BLOCK_END_TOKEN) - { - parser->state = POP(parser, parser->states); - (void)POP(parser, parser->marks); - MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; - } - - else - { - return yaml_parser_set_parser_error_context(parser, - "while parsing a block mapping", POP(parser, parser->marks), - "did not find expected key", token->start_mark); - } -} - -/* - * Parse the productions: - * block_mapping ::= BLOCK-MAPPING_START - * - * ((KEY block_node_or_indentless_sequence?)? - * - * (VALUE block_node_or_indentless_sequence?)?)* - * ***** * - * BLOCK-END - * - */ - -static int -yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, - yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_VALUE_TOKEN) - { - yaml_mark_t mark = token->end_mark; - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_KEY_TOKEN && - token->type != YAML_VALUE_TOKEN && - token->type != YAML_BLOCK_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_BLOCK_MAPPING_KEY_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 1, 1); - } - else { - parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; - return yaml_parser_process_empty_scalar(parser, event, mark); - } - } - - else - { - parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; - return yaml_parser_process_empty_scalar(parser, event, token->start_mark); - } -} - -/* - * Parse the productions: - * flow_sequence ::= FLOW-SEQUENCE-START - * ******************* - * (flow_sequence_entry FLOW-ENTRY)* - * * ********** - * flow_sequence_entry? - * * - * FLOW-SEQUENCE-END - * ***************** - * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * * - */ - -static int -yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, - yaml_event_t *event, int first) -{ - yaml_token_t *token; - - if (first) { - token = PEEK_TOKEN(parser); - if (!PUSH(parser, parser->marks, token->start_mark)) - return 0; - SKIP_TOKEN(parser); - } - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) - { - if (!first) { - if (token->type == YAML_FLOW_ENTRY_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - } - else { - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow sequence", POP(parser, parser->marks), - "did not find expected ',' or ']'", token->start_mark); - } - } - - if (token->type == YAML_KEY_TOKEN) { - parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; - MAPPING_START_EVENT_INIT(*event, NULL, NULL, - 1, YAML_FLOW_MAPPING_STYLE, - token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; - } - - else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - } - - parser->state = POP(parser, parser->states); - (void)POP(parser, parser->marks); - SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; -} - -/* - * Parse the productions: - * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * *** * - */ - -static int -yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, - yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN - && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - else { - yaml_mark_t mark = token->end_mark; - SKIP_TOKEN(parser); - parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; - return yaml_parser_process_empty_scalar(parser, event, mark); - } -} - -/* - * Parse the productions: - * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * ***** * - */ - -static int -yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, - yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type == YAML_VALUE_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_FLOW_ENTRY_TOKEN - && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - } - parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; - return yaml_parser_process_empty_scalar(parser, event, token->start_mark); -} - -/* - * Parse the productions: - * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * * - */ - -static int -yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, - yaml_event_t *event) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; - - MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark); - return 1; -} - -/* - * Parse the productions: - * flow_mapping ::= FLOW-MAPPING-START - * ****************** - * (flow_mapping_entry FLOW-ENTRY)* - * * ********** - * flow_mapping_entry? - * ****************** - * FLOW-MAPPING-END - * **************** - * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * * *** * - */ - -static int -yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, - yaml_event_t *event, int first) -{ - yaml_token_t *token; - - if (first) { - token = PEEK_TOKEN(parser); - if (!PUSH(parser, parser->marks, token->start_mark)) - return 0; - SKIP_TOKEN(parser); - } - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (token->type != YAML_FLOW_MAPPING_END_TOKEN) - { - if (!first) { - if (token->type == YAML_FLOW_ENTRY_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - } - else { - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow mapping", POP(parser, parser->marks), - "did not find expected ',' or '}'", token->start_mark); - } - } - - if (token->type == YAML_KEY_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_VALUE_TOKEN - && token->type != YAML_FLOW_ENTRY_TOKEN - && token->type != YAML_FLOW_MAPPING_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_MAPPING_VALUE_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - else { - parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE; - return yaml_parser_process_empty_scalar(parser, event, - token->start_mark); - } - } - else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - } - - parser->state = POP(parser, parser->states); - (void)POP(parser, parser->marks); - MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); - SKIP_TOKEN(parser); - return 1; -} - -/* - * Parse the productions: - * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - * * ***** * - */ - -static int -yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, - yaml_event_t *event, int empty) -{ - yaml_token_t *token; - - token = PEEK_TOKEN(parser); - if (!token) return 0; - - if (empty) { - parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; - return yaml_parser_process_empty_scalar(parser, event, - token->start_mark); - } - - if (token->type == YAML_VALUE_TOKEN) { - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; - if (token->type != YAML_FLOW_ENTRY_TOKEN - && token->type != YAML_FLOW_MAPPING_END_TOKEN) { - if (!PUSH(parser, parser->states, - YAML_PARSE_FLOW_MAPPING_KEY_STATE)) - return 0; - return yaml_parser_parse_node(parser, event, 0, 0); - } - } - - parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; - return yaml_parser_process_empty_scalar(parser, event, token->start_mark); -} - -/* - * Generate an empty scalar event. - */ - -static int -yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, - yaml_mark_t mark) -{ - yaml_char_t *value; - - value = YAML_MALLOC(1); - if (!value) { - parser->error = YAML_MEMORY_ERROR; - return 0; - } - value[0] = '\0'; - - SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0, - 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark); - - return 1; -} - -/* - * Parse directives. - */ - -static int -yaml_parser_process_directives(yaml_parser_t *parser, - yaml_version_directive_t **version_directive_ref, - yaml_tag_directive_t **tag_directives_start_ref, - yaml_tag_directive_t **tag_directives_end_ref) -{ - yaml_tag_directive_t default_tag_directives[] = { - {(yaml_char_t *)"!", (yaml_char_t *)"!"}, - {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, - {NULL, NULL} - }; - yaml_tag_directive_t *default_tag_directive; - yaml_version_directive_t *version_directive = NULL; - struct { - yaml_tag_directive_t *start; - yaml_tag_directive_t *end; - yaml_tag_directive_t *top; - } tag_directives = { NULL, NULL, NULL }; - yaml_token_t *token; - - if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*)) - goto error; - - token = PEEK_TOKEN(parser); - if (!token) goto error; - - while (token->type == YAML_VERSION_DIRECTIVE_TOKEN || - token->type == YAML_TAG_DIRECTIVE_TOKEN) - { - if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) { - if (version_directive) { - yaml_parser_set_parser_error(parser, - "found duplicate %YAML directive", token->start_mark); - goto error; - } - if (token->data.version_directive.major != 1 - || ( - token->data.version_directive.minor != 1 - && token->data.version_directive.minor != 2 - )) { - yaml_parser_set_parser_error(parser, - "found incompatible YAML document", token->start_mark); - goto error; - } - version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t); - if (!version_directive) { - parser->error = YAML_MEMORY_ERROR; - goto error; - } - version_directive->major = token->data.version_directive.major; - version_directive->minor = token->data.version_directive.minor; - } - - else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { - yaml_tag_directive_t value; - value.handle = token->data.tag_directive.handle; - value.prefix = token->data.tag_directive.prefix; - - if (!yaml_parser_append_tag_directive(parser, value, 0, - token->start_mark)) - goto error; - if (!PUSH(parser, tag_directives, value)) - goto error; - } - - SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) goto error; - } - - for (default_tag_directive = default_tag_directives; - default_tag_directive->handle; default_tag_directive++) { - if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, - token->start_mark)) - goto error; - } - - if (version_directive_ref) { - *version_directive_ref = version_directive; - } - if (tag_directives_start_ref) { - if (STACK_EMPTY(parser, tag_directives)) { - *tag_directives_start_ref = *tag_directives_end_ref = NULL; - STACK_DEL(parser, tag_directives); - } - else { - *tag_directives_start_ref = tag_directives.start; - *tag_directives_end_ref = tag_directives.top; - } - } - else { - STACK_DEL(parser, tag_directives); - } - - if (!version_directive_ref) - yaml_free(version_directive); - return 1; - -error: - yaml_free(version_directive); - while (!STACK_EMPTY(parser, tag_directives)) { - yaml_tag_directive_t tag_directive = POP(parser, tag_directives); - yaml_free(tag_directive.handle); - yaml_free(tag_directive.prefix); - } - STACK_DEL(parser, tag_directives); - return 0; -} - -/* - * Append a tag directive to the directives stack. - */ - -static int -yaml_parser_append_tag_directive(yaml_parser_t *parser, - yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) -{ - yaml_tag_directive_t *tag_directive; - yaml_tag_directive_t copy = { NULL, NULL }; - - for (tag_directive = parser->tag_directives.start; - tag_directive != parser->tag_directives.top; tag_directive ++) { - if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { - if (allow_duplicates) - return 1; - return yaml_parser_set_parser_error(parser, - "found duplicate %TAG directive", mark); - } - } - - copy.handle = yaml_strdup(value.handle); - copy.prefix = yaml_strdup(value.prefix); - if (!copy.handle || !copy.prefix) { - parser->error = YAML_MEMORY_ERROR; - goto error; - } - - if (!PUSH(parser, parser->tag_directives, copy)) - goto error; - - return 1; - -error: - yaml_free(copy.handle); - yaml_free(copy.prefix); - return 0; -} - diff --git a/ext/psych/yaml/reader.c b/ext/psych/yaml/reader.c deleted file mode 100644 index f3ac54c251..0000000000 --- a/ext/psych/yaml/reader.c +++ /dev/null @@ -1,469 +0,0 @@ - -#include "yaml_private.h" - -/* - * Declarations. - */ - -static int -yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, - size_t offset, int value); - -static int -yaml_parser_update_raw_buffer(yaml_parser_t *parser); - -static int -yaml_parser_determine_encoding(yaml_parser_t *parser); - -YAML_DECLARE(int) -yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); - -/* - * Set the reader error and return 0. - */ - -static int -yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, - size_t offset, int value) -{ - parser->error = YAML_READER_ERROR; - parser->problem = problem; - parser->problem_offset = offset; - parser->problem_value = value; - - return 0; -} - -/* - * Byte order marks. - */ - -#define BOM_UTF8 "\xef\xbb\xbf" -#define BOM_UTF16LE "\xff\xfe" -#define BOM_UTF16BE "\xfe\xff" - -/* - * Determine the input stream encoding by checking the BOM symbol. If no BOM is - * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. - */ - -static int -yaml_parser_determine_encoding(yaml_parser_t *parser) -{ - /* Ensure that we had enough bytes in the raw buffer. */ - - while (!parser->eof - && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) { - if (!yaml_parser_update_raw_buffer(parser)) { - return 0; - } - } - - /* Determine the encoding. */ - - if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 - && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) { - parser->encoding = YAML_UTF16LE_ENCODING; - parser->raw_buffer.pointer += 2; - parser->offset += 2; - } - else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 - && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) { - parser->encoding = YAML_UTF16BE_ENCODING; - parser->raw_buffer.pointer += 2; - parser->offset += 2; - } - else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3 - && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) { - parser->encoding = YAML_UTF8_ENCODING; - parser->raw_buffer.pointer += 3; - parser->offset += 3; - } - else { - parser->encoding = YAML_UTF8_ENCODING; - } - - return 1; -} - -/* - * Update the raw buffer. - */ - -static int -yaml_parser_update_raw_buffer(yaml_parser_t *parser) -{ - size_t size_read = 0; - - /* Return if the raw buffer is full. */ - - if (parser->raw_buffer.start == parser->raw_buffer.pointer - && parser->raw_buffer.last == parser->raw_buffer.end) - return 1; - - /* Return on EOF. */ - - if (parser->eof) return 1; - - /* Move the remaining bytes in the raw buffer to the beginning. */ - - if (parser->raw_buffer.start < parser->raw_buffer.pointer - && parser->raw_buffer.pointer < parser->raw_buffer.last) { - memmove(parser->raw_buffer.start, parser->raw_buffer.pointer, - parser->raw_buffer.last - parser->raw_buffer.pointer); - } - parser->raw_buffer.last -= - parser->raw_buffer.pointer - parser->raw_buffer.start; - parser->raw_buffer.pointer = parser->raw_buffer.start; - - /* Call the read handler to fill the buffer. */ - - if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last, - parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) { - return yaml_parser_set_reader_error(parser, "input error", - parser->offset, -1); - } - parser->raw_buffer.last += size_read; - if (!size_read) { - parser->eof = 1; - } - - return 1; -} - -/* - * Ensure that the buffer contains at least `length` characters. - * Return 1 on success, 0 on failure. - * - * The length is supposed to be significantly less that the buffer size. - */ - -YAML_DECLARE(int) -yaml_parser_update_buffer(yaml_parser_t *parser, size_t length) -{ - int first = 1; - - assert(parser->read_handler); /* Read handler must be set. */ - - /* If the EOF flag is set and the raw buffer is empty, do nothing. */ - - if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last) - return 1; - - /* Return if the buffer contains enough characters. */ - - if (parser->unread >= length) - return 1; - - /* Determine the input encoding if it is not known yet. */ - - if (!parser->encoding) { - if (!yaml_parser_determine_encoding(parser)) - return 0; - } - - /* Move the unread characters to the beginning of the buffer. */ - - if (parser->buffer.start < parser->buffer.pointer - && parser->buffer.pointer < parser->buffer.last) { - size_t size = parser->buffer.last - parser->buffer.pointer; - memmove(parser->buffer.start, parser->buffer.pointer, size); - parser->buffer.pointer = parser->buffer.start; - parser->buffer.last = parser->buffer.start + size; - } - else if (parser->buffer.pointer == parser->buffer.last) { - parser->buffer.pointer = parser->buffer.start; - parser->buffer.last = parser->buffer.start; - } - - /* Fill the buffer until it has enough characters. */ - - while (parser->unread < length) - { - /* Fill the raw buffer if necessary. */ - - if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) { - if (!yaml_parser_update_raw_buffer(parser)) return 0; - } - first = 0; - - /* Decode the raw buffer. */ - - while (parser->raw_buffer.pointer != parser->raw_buffer.last) - { - unsigned int value = 0, value2 = 0; - int incomplete = 0; - unsigned char octet; - unsigned int width = 0; - int low, high; - size_t k; - size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer; - - /* Decode the next character. */ - - switch (parser->encoding) - { - case YAML_UTF8_ENCODING: - - /* - * Decode a UTF-8 character. Check RFC 3629 - * (http://www.ietf.org/rfc/rfc3629.txt) for more details. - * - * The following table (taken from the RFC) is used for - * decoding. - * - * Char. number range | UTF-8 octet sequence - * (hexadecimal) | (binary) - * --------------------+------------------------------------ - * 0000 0000-0000 007F | 0xxxxxxx - * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx - * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx - * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - * - * Additionally, the characters in the range 0xD800-0xDFFF - * are prohibited as they are reserved for use with UTF-16 - * surrogate pairs. - */ - - /* Determine the length of the UTF-8 sequence. */ - - octet = parser->raw_buffer.pointer[0]; - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; - - /* Check if the leading octet is valid. */ - - if (!width) - return yaml_parser_set_reader_error(parser, - "invalid leading UTF-8 octet", - parser->offset, octet); - - /* Check if the raw buffer contains an incomplete character. */ - - if (width > raw_unread) { - if (parser->eof) { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-8 octet sequence", - parser->offset, -1); - } - incomplete = 1; - break; - } - - /* Decode the leading octet. */ - - value = (octet & 0x80) == 0x00 ? octet & 0x7F : - (octet & 0xE0) == 0xC0 ? octet & 0x1F : - (octet & 0xF0) == 0xE0 ? octet & 0x0F : - (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; - - /* Check and decode the trailing octets. */ - - for (k = 1; k < width; k ++) - { - octet = parser->raw_buffer.pointer[k]; - - /* Check if the octet is valid. */ - - if ((octet & 0xC0) != 0x80) - return yaml_parser_set_reader_error(parser, - "invalid trailing UTF-8 octet", - parser->offset+k, octet); - - /* Decode the octet. */ - - value = (value << 6) + (octet & 0x3F); - } - - /* Check the length of the sequence against the value. */ - - if (!((width == 1) || - (width == 2 && value >= 0x80) || - (width == 3 && value >= 0x800) || - (width == 4 && value >= 0x10000))) - return yaml_parser_set_reader_error(parser, - "invalid length of a UTF-8 sequence", - parser->offset, -1); - - /* Check the range of the value. */ - - if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) - return yaml_parser_set_reader_error(parser, - "invalid Unicode character", - parser->offset, value); - - break; - - case YAML_UTF16LE_ENCODING: - case YAML_UTF16BE_ENCODING: - - low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); - high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); - - /* - * The UTF-16 encoding is not as simple as one might - * naively think. Check RFC 2781 - * (http://www.ietf.org/rfc/rfc2781.txt). - * - * Normally, two subsequent bytes describe a Unicode - * character. However a special technique (called a - * surrogate pair) is used for specifying character - * values larger than 0xFFFF. - * - * A surrogate pair consists of two pseudo-characters: - * high surrogate area (0xD800-0xDBFF) - * low surrogate area (0xDC00-0xDFFF) - * - * The following formulas are used for decoding - * and encoding characters using surrogate pairs: - * - * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) - * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) - * W1 = 110110yyyyyyyyyy - * W2 = 110111xxxxxxxxxx - * - * where U is the character value, W1 is the high surrogate - * area, W2 is the low surrogate area. - */ - - /* Check for incomplete UTF-16 character. */ - - if (raw_unread < 2) { - if (parser->eof) { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 character", - parser->offset, -1); - } - incomplete = 1; - break; - } - - /* Get the character. */ - - value = parser->raw_buffer.pointer[low] - + (parser->raw_buffer.pointer[high] << 8); - - /* Check for unexpected low surrogate area. */ - - if ((value & 0xFC00) == 0xDC00) - return yaml_parser_set_reader_error(parser, - "unexpected low surrogate area", - parser->offset, value); - - /* Check for a high surrogate area. */ - - if ((value & 0xFC00) == 0xD800) { - - width = 4; - - /* Check for incomplete surrogate pair. */ - - if (raw_unread < 4) { - if (parser->eof) { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 surrogate pair", - parser->offset, -1); - } - incomplete = 1; - break; - } - - /* Get the next character. */ - - value2 = parser->raw_buffer.pointer[low+2] - + (parser->raw_buffer.pointer[high+2] << 8); - - /* Check for a low surrogate area. */ - - if ((value2 & 0xFC00) != 0xDC00) - return yaml_parser_set_reader_error(parser, - "expected low surrogate area", - parser->offset+2, value2); - - /* Generate the value of the surrogate pair. */ - - value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF); - } - - else { - width = 2; - } - - break; - - default: - assert(1); /* Impossible. */ - } - - /* Check if the raw buffer contains enough bytes to form a character. */ - - if (incomplete) break; - - /* - * Check if the character is in the allowed range: - * #x9 | #xA | #xD | [#x20-#x7E] (8 bit) - * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) - * | [#x10000-#x10FFFF] (32 bit) - */ - - if (! (value == 0x09 || value == 0x0A || value == 0x0D - || (value >= 0x20 && value <= 0x7E) - || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF) - || (value >= 0xE000 && value <= 0xFFFD) - || (value >= 0x10000 && value <= 0x10FFFF))) - return yaml_parser_set_reader_error(parser, - "control characters are not allowed", - parser->offset, value); - - /* Move the raw pointers. */ - - parser->raw_buffer.pointer += width; - parser->offset += width; - - /* Finally put the character into the buffer. */ - - /* 0000 0000-0000 007F -> 0xxxxxxx */ - if (value <= 0x7F) { - *(parser->buffer.last++) = value; - } - /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */ - else if (value <= 0x7FF) { - *(parser->buffer.last++) = 0xC0 + (value >> 6); - *(parser->buffer.last++) = 0x80 + (value & 0x3F); - } - /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */ - else if (value <= 0xFFFF) { - *(parser->buffer.last++) = 0xE0 + (value >> 12); - *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); - *(parser->buffer.last++) = 0x80 + (value & 0x3F); - } - /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - else { - *(parser->buffer.last++) = 0xF0 + (value >> 18); - *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F); - *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); - *(parser->buffer.last++) = 0x80 + (value & 0x3F); - } - - parser->unread ++; - } - - /* On EOF, put NUL into the buffer and return. */ - - if (parser->eof) { - *(parser->buffer.last++) = '\0'; - parser->unread ++; - return 1; - } - - } - - if (parser->offset >= MAX_FILE_SIZE) { - return yaml_parser_set_reader_error(parser, "input is too long", - parser->offset, -1); - } - - return 1; -} diff --git a/ext/psych/yaml/scanner.c b/ext/psych/yaml/scanner.c deleted file mode 100644 index bb5d201274..0000000000 --- a/ext/psych/yaml/scanner.c +++ /dev/null @@ -1,3598 +0,0 @@ - -/* - * Introduction - * ************ - * - * The following notes assume that you are familiar with the YAML specification - * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in - * some cases we are less restrictive that it requires. - * - * The process of transforming a YAML stream into a sequence of events is - * divided on two steps: Scanning and Parsing. - * - * The Scanner transforms the input stream into a sequence of tokens, while the - * parser transform the sequence of tokens produced by the Scanner into a - * sequence of parsing events. - * - * The Scanner is rather clever and complicated. The Parser, on the contrary, - * is a straightforward implementation of a recursive-descendant parser (or, - * LL(1) parser, as it is usually called). - * - * Actually there are two issues of Scanning that might be called "clever", the - * rest is quite straightforward. The issues are "block collection start" and - * "simple keys". Both issues are explained below in details. - * - * Here the Scanning step is explained and implemented. We start with the list - * of all the tokens produced by the Scanner together with short descriptions. - * - * Now, tokens: - * - * STREAM-START(encoding) # The stream start. - * STREAM-END # The stream end. - * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. - * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. - * DOCUMENT-START # '---' - * DOCUMENT-END # '...' - * BLOCK-SEQUENCE-START # Indentation increase denoting a block - * BLOCK-MAPPING-START # sequence or a block mapping. - * BLOCK-END # Indentation decrease. - * FLOW-SEQUENCE-START # '[' - * FLOW-SEQUENCE-END # ']' - * FLOW-MAPPING-START # '{' - * FLOW-MAPPING-END # '}' - * BLOCK-ENTRY # '-' - * FLOW-ENTRY # ',' - * KEY # '?' or nothing (simple keys). - * VALUE # ':' - * ALIAS(anchor) # '*anchor' - * ANCHOR(anchor) # '&anchor' - * TAG(handle,suffix) # '!handle!suffix' - * SCALAR(value,style) # A scalar. - * - * The following two tokens are "virtual" tokens denoting the beginning and the - * end of the stream: - * - * STREAM-START(encoding) - * STREAM-END - * - * We pass the information about the input stream encoding with the - * STREAM-START token. - * - * The next two tokens are responsible for tags: - * - * VERSION-DIRECTIVE(major,minor) - * TAG-DIRECTIVE(handle,prefix) - * - * Example: - * - * %YAML 1.1 - * %TAG ! !foo - * %TAG !yaml! tag:yaml.org,2002: - * --- - * - * The corresponding sequence of tokens: - * - * STREAM-START(utf-8) - * VERSION-DIRECTIVE(1,1) - * TAG-DIRECTIVE("!","!foo") - * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") - * DOCUMENT-START - * STREAM-END - * - * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole - * line. - * - * The document start and end indicators are represented by: - * - * DOCUMENT-START - * DOCUMENT-END - * - * Note that if a YAML stream contains an implicit document (without '---' - * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be - * produced. - * - * In the following examples, we present whole documents together with the - * produced tokens. - * - * 1. An implicit document: - * - * 'a scalar' - * - * Tokens: - * - * STREAM-START(utf-8) - * SCALAR("a scalar",single-quoted) - * STREAM-END - * - * 2. An explicit document: - * - * --- - * 'a scalar' - * ... - * - * Tokens: - * - * STREAM-START(utf-8) - * DOCUMENT-START - * SCALAR("a scalar",single-quoted) - * DOCUMENT-END - * STREAM-END - * - * 3. Several documents in a stream: - * - * 'a scalar' - * --- - * 'another scalar' - * --- - * 'yet another scalar' - * - * Tokens: - * - * STREAM-START(utf-8) - * SCALAR("a scalar",single-quoted) - * DOCUMENT-START - * SCALAR("another scalar",single-quoted) - * DOCUMENT-START - * SCALAR("yet another scalar",single-quoted) - * STREAM-END - * - * We have already introduced the SCALAR token above. The following tokens are - * used to describe aliases, anchors, tag, and scalars: - * - * ALIAS(anchor) - * ANCHOR(anchor) - * TAG(handle,suffix) - * SCALAR(value,style) - * - * The following series of examples illustrate the usage of these tokens: - * - * 1. A recursive sequence: - * - * &A [ *A ] - * - * Tokens: - * - * STREAM-START(utf-8) - * ANCHOR("A") - * FLOW-SEQUENCE-START - * ALIAS("A") - * FLOW-SEQUENCE-END - * STREAM-END - * - * 2. A tagged scalar: - * - * !!float "3.14" # A good approximation. - * - * Tokens: - * - * STREAM-START(utf-8) - * TAG("!!","float") - * SCALAR("3.14",double-quoted) - * STREAM-END - * - * 3. Various scalar styles: - * - * --- # Implicit empty plain scalars do not produce tokens. - * --- a plain scalar - * --- 'a single-quoted scalar' - * --- "a double-quoted scalar" - * --- |- - * a literal scalar - * --- >- - * a folded - * scalar - * - * Tokens: - * - * STREAM-START(utf-8) - * DOCUMENT-START - * DOCUMENT-START - * SCALAR("a plain scalar",plain) - * DOCUMENT-START - * SCALAR("a single-quoted scalar",single-quoted) - * DOCUMENT-START - * SCALAR("a double-quoted scalar",double-quoted) - * DOCUMENT-START - * SCALAR("a literal scalar",literal) - * DOCUMENT-START - * SCALAR("a folded scalar",folded) - * STREAM-END - * - * Now it's time to review collection-related tokens. We will start with - * flow collections: - * - * FLOW-SEQUENCE-START - * FLOW-SEQUENCE-END - * FLOW-MAPPING-START - * FLOW-MAPPING-END - * FLOW-ENTRY - * KEY - * VALUE - * - * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and - * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' - * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the - * indicators '?' and ':', which are used for denoting mapping keys and values, - * are represented by the KEY and VALUE tokens. - * - * The following examples show flow collections: - * - * 1. A flow sequence: - * - * [item 1, item 2, item 3] - * - * Tokens: - * - * STREAM-START(utf-8) - * FLOW-SEQUENCE-START - * SCALAR("item 1",plain) - * FLOW-ENTRY - * SCALAR("item 2",plain) - * FLOW-ENTRY - * SCALAR("item 3",plain) - * FLOW-SEQUENCE-END - * STREAM-END - * - * 2. A flow mapping: - * - * { - * a simple key: a value, # Note that the KEY token is produced. - * ? a complex key: another value, - * } - * - * Tokens: - * - * STREAM-START(utf-8) - * FLOW-MAPPING-START - * KEY - * SCALAR("a simple key",plain) - * VALUE - * SCALAR("a value",plain) - * FLOW-ENTRY - * KEY - * SCALAR("a complex key",plain) - * VALUE - * SCALAR("another value",plain) - * FLOW-ENTRY - * FLOW-MAPPING-END - * STREAM-END - * - * A simple key is a key which is not denoted by the '?' indicator. Note that - * the Scanner still produce the KEY token whenever it encounters a simple key. - * - * For scanning block collections, the following tokens are used (note that we - * repeat KEY and VALUE here): - * - * BLOCK-SEQUENCE-START - * BLOCK-MAPPING-START - * BLOCK-END - * BLOCK-ENTRY - * KEY - * VALUE - * - * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation - * increase that precedes a block collection (cf. the INDENT token in Python). - * The token BLOCK-END denote indentation decrease that ends a block collection - * (cf. the DEDENT token in Python). However YAML has some syntax peculiarities - * that makes detections of these tokens more complex. - * - * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators - * '-', '?', and ':' correspondingly. - * - * The following examples show how the tokens BLOCK-SEQUENCE-START, - * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: - * - * 1. Block sequences: - * - * - item 1 - * - item 2 - * - - * - item 3.1 - * - item 3.2 - * - - * key 1: value 1 - * key 2: value 2 - * - * Tokens: - * - * STREAM-START(utf-8) - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * SCALAR("item 1",plain) - * BLOCK-ENTRY - * SCALAR("item 2",plain) - * BLOCK-ENTRY - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * SCALAR("item 3.1",plain) - * BLOCK-ENTRY - * SCALAR("item 3.2",plain) - * BLOCK-END - * BLOCK-ENTRY - * BLOCK-MAPPING-START - * KEY - * SCALAR("key 1",plain) - * VALUE - * SCALAR("value 1",plain) - * KEY - * SCALAR("key 2",plain) - * VALUE - * SCALAR("value 2",plain) - * BLOCK-END - * BLOCK-END - * STREAM-END - * - * 2. Block mappings: - * - * a simple key: a value # The KEY token is produced here. - * ? a complex key - * : another value - * a mapping: - * key 1: value 1 - * key 2: value 2 - * a sequence: - * - item 1 - * - item 2 - * - * Tokens: - * - * STREAM-START(utf-8) - * BLOCK-MAPPING-START - * KEY - * SCALAR("a simple key",plain) - * VALUE - * SCALAR("a value",plain) - * KEY - * SCALAR("a complex key",plain) - * VALUE - * SCALAR("another value",plain) - * KEY - * SCALAR("a mapping",plain) - * VALUE - * BLOCK-MAPPING-START - * KEY - * SCALAR("key 1",plain) - * VALUE - * SCALAR("value 1",plain) - * KEY - * SCALAR("key 2",plain) - * VALUE - * SCALAR("value 2",plain) - * BLOCK-END - * KEY - * SCALAR("a sequence",plain) - * VALUE - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * SCALAR("item 1",plain) - * BLOCK-ENTRY - * SCALAR("item 2",plain) - * BLOCK-END - * BLOCK-END - * STREAM-END - * - * YAML does not always require to start a new block collection from a new - * line. If the current line contains only '-', '?', and ':' indicators, a new - * block collection may start at the current line. The following examples - * illustrate this case: - * - * 1. Collections in a sequence: - * - * - - item 1 - * - item 2 - * - key 1: value 1 - * key 2: value 2 - * - ? complex key - * : complex value - * - * Tokens: - * - * STREAM-START(utf-8) - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * SCALAR("item 1",plain) - * BLOCK-ENTRY - * SCALAR("item 2",plain) - * BLOCK-END - * BLOCK-ENTRY - * BLOCK-MAPPING-START - * KEY - * SCALAR("key 1",plain) - * VALUE - * SCALAR("value 1",plain) - * KEY - * SCALAR("key 2",plain) - * VALUE - * SCALAR("value 2",plain) - * BLOCK-END - * BLOCK-ENTRY - * BLOCK-MAPPING-START - * KEY - * SCALAR("complex key") - * VALUE - * SCALAR("complex value") - * BLOCK-END - * BLOCK-END - * STREAM-END - * - * 2. Collections in a mapping: - * - * ? a sequence - * : - item 1 - * - item 2 - * ? a mapping - * : key 1: value 1 - * key 2: value 2 - * - * Tokens: - * - * STREAM-START(utf-8) - * BLOCK-MAPPING-START - * KEY - * SCALAR("a sequence",plain) - * VALUE - * BLOCK-SEQUENCE-START - * BLOCK-ENTRY - * SCALAR("item 1",plain) - * BLOCK-ENTRY - * SCALAR("item 2",plain) - * BLOCK-END - * KEY - * SCALAR("a mapping",plain) - * VALUE - * BLOCK-MAPPING-START - * KEY - * SCALAR("key 1",plain) - * VALUE - * SCALAR("value 1",plain) - * KEY - * SCALAR("key 2",plain) - * VALUE - * SCALAR("value 2",plain) - * BLOCK-END - * BLOCK-END - * STREAM-END - * - * YAML also permits non-indented sequences if they are included into a block - * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: - * - * key: - * - item 1 # BLOCK-SEQUENCE-START is NOT produced here. - * - item 2 - * - * Tokens: - * - * STREAM-START(utf-8) - * BLOCK-MAPPING-START - * KEY - * SCALAR("key",plain) - * VALUE - * BLOCK-ENTRY - * SCALAR("item 1",plain) - * BLOCK-ENTRY - * SCALAR("item 2",plain) - * BLOCK-END - */ - -#include "yaml_private.h" - -/* - * Ensure that the buffer contains the required number of characters. - * Return 1 on success, 0 on failure (reader error or memory error). - */ - -#define CACHE(parser,length) \ - (parser->unread >= (length) \ - ? 1 \ - : yaml_parser_update_buffer(parser, (length))) - -/* - * Advance the buffer pointer. - */ - -#define SKIP(parser) \ - (parser->mark.index ++, \ - parser->mark.column ++, \ - parser->unread --, \ - parser->buffer.pointer += WIDTH(parser->buffer)) - -#define SKIP_LINE(parser) \ - (IS_CRLF(parser->buffer) ? \ - (parser->mark.index += 2, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread -= 2, \ - parser->buffer.pointer += 2) : \ - IS_BREAK(parser->buffer) ? \ - (parser->mark.index ++, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread --, \ - parser->buffer.pointer += WIDTH(parser->buffer)) : 0) - -/* - * Copy a character to a string buffer and advance pointers. - */ - -#define READ(parser,string) \ - (STRING_EXTEND(parser,string) ? \ - (COPY(string,parser->buffer), \ - parser->mark.index ++, \ - parser->mark.column ++, \ - parser->unread --, \ - 1) : 0) - -/* - * Copy a line break character to a string buffer and advance pointers. - */ - -#define READ_LINE(parser,string) \ - (STRING_EXTEND(parser,string) ? \ - (((CHECK_AT(parser->buffer,'\r',0) \ - && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \ - (*((string).pointer++) = (yaml_char_t) '\n', \ - parser->buffer.pointer += 2, \ - parser->mark.index += 2, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread -= 2) : \ - (CHECK_AT(parser->buffer,'\r',0) \ - || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \ - (*((string).pointer++) = (yaml_char_t) '\n', \ - parser->buffer.pointer ++, \ - parser->mark.index ++, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread --) : \ - (CHECK_AT(parser->buffer,'\xC2',0) \ - && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \ - (*((string).pointer++) = (yaml_char_t) '\n', \ - parser->buffer.pointer += 2, \ - parser->mark.index ++, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread --) : \ - (CHECK_AT(parser->buffer,'\xE2',0) && \ - CHECK_AT(parser->buffer,'\x80',1) && \ - (CHECK_AT(parser->buffer,'\xA8',2) || \ - CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \ - (*((string).pointer++) = *(parser->buffer.pointer++), \ - *((string).pointer++) = *(parser->buffer.pointer++), \ - *((string).pointer++) = *(parser->buffer.pointer++), \ - parser->mark.index ++, \ - parser->mark.column = 0, \ - parser->mark.line ++, \ - parser->unread --) : 0), \ - 1) : 0) - -/* - * Public API declarations. - */ - -YAML_DECLARE(int) -yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); - -/* - * Error handling. - */ - -static int -yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, - yaml_mark_t context_mark, const char *problem); - -/* - * High-level token API. - */ - -YAML_DECLARE(int) -yaml_parser_fetch_more_tokens(yaml_parser_t *parser); - -static int -yaml_parser_fetch_next_token(yaml_parser_t *parser); - -/* - * Potential simple keys. - */ - -static int -yaml_parser_stale_simple_keys(yaml_parser_t *parser); - -static int -yaml_parser_save_simple_key(yaml_parser_t *parser); - -static int -yaml_parser_remove_simple_key(yaml_parser_t *parser); - -static int -yaml_parser_increase_flow_level(yaml_parser_t *parser); - -static int -yaml_parser_decrease_flow_level(yaml_parser_t *parser); - -/* - * Indentation treatment. - */ - -static int -yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, - ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark); - -static int -yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column); - -/* - * Token fetchers. - */ - -static int -yaml_parser_fetch_stream_start(yaml_parser_t *parser); - -static int -yaml_parser_fetch_stream_end(yaml_parser_t *parser); - -static int -yaml_parser_fetch_directive(yaml_parser_t *parser); - -static int -yaml_parser_fetch_document_indicator(yaml_parser_t *parser, - yaml_token_type_t type); - -static int -yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, - yaml_token_type_t type); - -static int -yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, - yaml_token_type_t type); - -static int -yaml_parser_fetch_flow_entry(yaml_parser_t *parser); - -static int -yaml_parser_fetch_block_entry(yaml_parser_t *parser); - -static int -yaml_parser_fetch_key(yaml_parser_t *parser); - -static int -yaml_parser_fetch_value(yaml_parser_t *parser); - -static int -yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type); - -static int -yaml_parser_fetch_tag(yaml_parser_t *parser); - -static int -yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal); - -static int -yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single); - -static int -yaml_parser_fetch_plain_scalar(yaml_parser_t *parser); - -/* - * Token scanners. - */ - -static int -yaml_parser_scan_to_next_token(yaml_parser_t *parser); - -static int -yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token); - -static int -yaml_parser_scan_directive_name(yaml_parser_t *parser, - yaml_mark_t start_mark, yaml_char_t **name); - -static int -yaml_parser_scan_version_directive_value(yaml_parser_t *parser, - yaml_mark_t start_mark, int *major, int *minor); - -static int -yaml_parser_scan_version_directive_number(yaml_parser_t *parser, - yaml_mark_t start_mark, int *number); - -static int -yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, - yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix); - -static int -yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, - yaml_token_type_t type); - -static int -yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token); - -static int -yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, - yaml_mark_t start_mark, yaml_char_t **handle); - -static int -yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive, - yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri); - -static int -yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, - yaml_mark_t start_mark, yaml_string_t *string); - -static int -yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, - int literal); - -static int -yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, - int *indent, yaml_string_t *breaks, - yaml_mark_t start_mark, yaml_mark_t *end_mark); - -static int -yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, - int single); - -static int -yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token); - -/* - * Get the next token. - */ - -YAML_DECLARE(int) -yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token) -{ - assert(parser); /* Non-NULL parser object is expected. */ - assert(token); /* Non-NULL token object is expected. */ - - /* Erase the token object. */ - - memset(token, 0, sizeof(yaml_token_t)); - - /* No tokens after STREAM-END or error. */ - - if (parser->stream_end_produced || parser->error) { - return 1; - } - - /* Ensure that the tokens queue contains enough tokens. */ - - if (!parser->token_available) { - if (!yaml_parser_fetch_more_tokens(parser)) - return 0; - } - - /* Fetch the next token from the queue. */ - - *token = DEQUEUE(parser, parser->tokens); - parser->token_available = 0; - parser->tokens_parsed ++; - - if (token->type == YAML_STREAM_END_TOKEN) { - parser->stream_end_produced = 1; - } - - return 1; -} - -/* - * Set the scanner error and return 0. - */ - -static int -yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, - yaml_mark_t context_mark, const char *problem) -{ - parser->error = YAML_SCANNER_ERROR; - parser->context = context; - parser->context_mark = context_mark; - parser->problem = problem; - parser->problem_mark = parser->mark; - - return 0; -} - -/* - * Ensure that the tokens queue contains at least one token which can be - * returned to the Parser. - */ - -YAML_DECLARE(int) -yaml_parser_fetch_more_tokens(yaml_parser_t *parser) -{ - int need_more_tokens; - - /* While we need more tokens to fetch, do it. */ - - while (1) - { - /* - * Check if we really need to fetch more tokens. - */ - - need_more_tokens = 0; - - if (parser->tokens.head == parser->tokens.tail) - { - /* Queue is empty. */ - - need_more_tokens = 1; - } - else - { - yaml_simple_key_t *simple_key; - - /* Check if any potential simple key may occupy the head position. */ - - if (!yaml_parser_stale_simple_keys(parser)) - return 0; - - for (simple_key = parser->simple_keys.start; - simple_key != parser->simple_keys.top; simple_key++) { - if (simple_key->possible - && simple_key->token_number == parser->tokens_parsed) { - need_more_tokens = 1; - break; - } - } - } - - /* We are finished. */ - - if (!need_more_tokens) - break; - - /* Fetch the next token. */ - - if (!yaml_parser_fetch_next_token(parser)) - return 0; - } - - parser->token_available = 1; - - return 1; -} - -/* - * The dispatcher for token fetchers. - */ - -static int -yaml_parser_fetch_next_token(yaml_parser_t *parser) -{ - /* Ensure that the buffer is initialized. */ - - if (!CACHE(parser, 1)) - return 0; - - /* Check if we just started scanning. Fetch STREAM-START then. */ - - if (!parser->stream_start_produced) - return yaml_parser_fetch_stream_start(parser); - - /* Eat whitespaces and comments until we reach the next token. */ - - if (!yaml_parser_scan_to_next_token(parser)) - return 0; - - /* Remove obsolete potential simple keys. */ - - if (!yaml_parser_stale_simple_keys(parser)) - return 0; - - /* Check the indentation level against the current column. */ - - if (!yaml_parser_unroll_indent(parser, parser->mark.column)) - return 0; - - /* - * Ensure that the buffer contains at least 4 characters. 4 is the length - * of the longest indicators ('--- ' and '... '). - */ - - if (!CACHE(parser, 4)) - return 0; - - /* Is it the end of the stream? */ - - if (IS_Z(parser->buffer)) - return yaml_parser_fetch_stream_end(parser); - - /* Is it a directive? */ - - if (parser->mark.column == 0 && CHECK(parser->buffer, '%')) - return yaml_parser_fetch_directive(parser); - - /* Is it the document start indicator? */ - - if (parser->mark.column == 0 - && CHECK_AT(parser->buffer, '-', 0) - && CHECK_AT(parser->buffer, '-', 1) - && CHECK_AT(parser->buffer, '-', 2) - && IS_BLANKZ_AT(parser->buffer, 3)) - return yaml_parser_fetch_document_indicator(parser, - YAML_DOCUMENT_START_TOKEN); - - /* Is it the document end indicator? */ - - if (parser->mark.column == 0 - && CHECK_AT(parser->buffer, '.', 0) - && CHECK_AT(parser->buffer, '.', 1) - && CHECK_AT(parser->buffer, '.', 2) - && IS_BLANKZ_AT(parser->buffer, 3)) - return yaml_parser_fetch_document_indicator(parser, - YAML_DOCUMENT_END_TOKEN); - - /* Is it the flow sequence start indicator? */ - - if (CHECK(parser->buffer, '[')) - return yaml_parser_fetch_flow_collection_start(parser, - YAML_FLOW_SEQUENCE_START_TOKEN); - - /* Is it the flow mapping start indicator? */ - - if (CHECK(parser->buffer, '{')) - return yaml_parser_fetch_flow_collection_start(parser, - YAML_FLOW_MAPPING_START_TOKEN); - - /* Is it the flow sequence end indicator? */ - - if (CHECK(parser->buffer, ']')) - return yaml_parser_fetch_flow_collection_end(parser, - YAML_FLOW_SEQUENCE_END_TOKEN); - - /* Is it the flow mapping end indicator? */ - - if (CHECK(parser->buffer, '}')) - return yaml_parser_fetch_flow_collection_end(parser, - YAML_FLOW_MAPPING_END_TOKEN); - - /* Is it the flow entry indicator? */ - - if (CHECK(parser->buffer, ',')) - return yaml_parser_fetch_flow_entry(parser); - - /* Is it the block entry indicator? */ - - if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1)) - return yaml_parser_fetch_block_entry(parser); - - /* Is it the key indicator? */ - - if (CHECK(parser->buffer, '?') - && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) - return yaml_parser_fetch_key(parser); - - /* Is it the value indicator? */ - - if (CHECK(parser->buffer, ':') - && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) - return yaml_parser_fetch_value(parser); - - /* Is it an alias? */ - - if (CHECK(parser->buffer, '*')) - return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN); - - /* Is it an anchor? */ - - if (CHECK(parser->buffer, '&')) - return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN); - - /* Is it a tag? */ - - if (CHECK(parser->buffer, '!')) - return yaml_parser_fetch_tag(parser); - - /* Is it a literal scalar? */ - - if (CHECK(parser->buffer, '|') && !parser->flow_level) - return yaml_parser_fetch_block_scalar(parser, 1); - - /* Is it a folded scalar? */ - - if (CHECK(parser->buffer, '>') && !parser->flow_level) - return yaml_parser_fetch_block_scalar(parser, 0); - - /* Is it a single-quoted scalar? */ - - if (CHECK(parser->buffer, '\'')) - return yaml_parser_fetch_flow_scalar(parser, 1); - - /* Is it a double-quoted scalar? */ - - if (CHECK(parser->buffer, '"')) - return yaml_parser_fetch_flow_scalar(parser, 0); - - /* - * Is it a plain scalar? - * - * A plain scalar may start with any non-blank characters except - * - * '-', '?', ':', ',', '[', ']', '{', '}', - * '#', '&', '*', '!', '|', '>', '\'', '\"', - * '%', '@', '`'. - * - * In the block context (and, for the '-' indicator, in the flow context - * too), it may also start with the characters - * - * '-', '?', ':' - * - * if it is followed by a non-space character. - * - * The last rule is more restrictive than the specification requires. - */ - - if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-') - || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':') - || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[') - || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') - || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#') - || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*') - || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|') - || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'') - || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%') - || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) || - (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) || - (!parser->flow_level && - (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')) - && !IS_BLANKZ_AT(parser->buffer, 1))) - return yaml_parser_fetch_plain_scalar(parser); - - /* - * If we don't determine the token type so far, it is an error. - */ - - return yaml_parser_set_scanner_error(parser, - "while scanning for the next token", parser->mark, - "found character that cannot start any token"); -} - -/* - * Check the list of potential simple keys and remove the positions that - * cannot contain simple keys anymore. - */ - -static int -yaml_parser_stale_simple_keys(yaml_parser_t *parser) -{ - yaml_simple_key_t *simple_key; - - /* Check for a potential simple key for each flow level. */ - - for (simple_key = parser->simple_keys.start; - simple_key != parser->simple_keys.top; simple_key ++) - { - /* - * The specification requires that a simple key - * - * - is limited to a single line, - * - is shorter than 1024 characters. - */ - - if (simple_key->possible - && (simple_key->mark.line < parser->mark.line - || simple_key->mark.index+1024 < parser->mark.index)) { - - /* Check if the potential simple key to be removed is required. */ - - if (simple_key->required) { - return yaml_parser_set_scanner_error(parser, - "while scanning a simple key", simple_key->mark, - "could not find expected ':'"); - } - - simple_key->possible = 0; - } - } - - return 1; -} - -/* - * Check if a simple key may start at the current position and add it if - * needed. - */ - -static int -yaml_parser_save_simple_key(yaml_parser_t *parser) -{ - /* - * A simple key is required at the current position if the scanner is in - * the block context and the current column coincides with the indentation - * level. - */ - - int required = (!parser->flow_level - && parser->indent == (ptrdiff_t)parser->mark.column); - - /* - * If the current position may start a simple key, save it. - */ - - if (parser->simple_key_allowed) - { - yaml_simple_key_t simple_key; - simple_key.possible = 1; - simple_key.required = required; - simple_key.token_number = - parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head); - simple_key.mark = parser->mark; - - if (!yaml_parser_remove_simple_key(parser)) return 0; - - *(parser->simple_keys.top-1) = simple_key; - } - - return 1; -} - -/* - * Remove a potential simple key at the current flow level. - */ - -static int -yaml_parser_remove_simple_key(yaml_parser_t *parser) -{ - yaml_simple_key_t *simple_key = parser->simple_keys.top-1; - - if (simple_key->possible) - { - /* If the key is required, it is an error. */ - - if (simple_key->required) { - return yaml_parser_set_scanner_error(parser, - "while scanning a simple key", simple_key->mark, - "could not find expected ':'"); - } - } - - /* Remove the key from the stack. */ - - simple_key->possible = 0; - - return 1; -} - -/* - * Increase the flow level and resize the simple key list if needed. - */ - -static int -yaml_parser_increase_flow_level(yaml_parser_t *parser) -{ - yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } }; - - /* Reset the simple key on the next level. */ - - if (!PUSH(parser, parser->simple_keys, empty_simple_key)) - return 0; - - /* Increase the flow level. */ - - if (parser->flow_level == INT_MAX) { - parser->error = YAML_MEMORY_ERROR; - return 0; - } - - parser->flow_level++; - - return 1; -} - -/* - * Decrease the flow level. - */ - -static int -yaml_parser_decrease_flow_level(yaml_parser_t *parser) -{ - if (parser->flow_level) { - parser->flow_level --; - (void)POP(parser, parser->simple_keys); - } - - return 1; -} - -/* - * Push the current indentation level to the stack and set the new level - * the current column is greater than the indentation level. In this case, - * append or insert the specified token into the token queue. - * - */ - -static int -yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, - ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark) -{ - yaml_token_t token; - - /* In the flow context, do nothing. */ - - if (parser->flow_level) - return 1; - - if (parser->indent < column) - { - /* - * Push the current indentation level to the stack and set the new - * indentation level. - */ - - if (!PUSH(parser, parser->indents, parser->indent)) - return 0; - - if (column > INT_MAX) { - parser->error = YAML_MEMORY_ERROR; - return 0; - } - - parser->indent = (int)column; - - /* Create a token and insert it into the queue. */ - - TOKEN_INIT(token, type, mark, mark); - - if (number == -1) { - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - } - else { - if (!QUEUE_INSERT(parser, - parser->tokens, number - parser->tokens_parsed, token)) - return 0; - } - } - - return 1; -} - -/* - * Pop indentation levels from the indents stack until the current level - * becomes less or equal to the column. For each indentation level, append - * the BLOCK-END token. - */ - - -static int -yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column) -{ - yaml_token_t token; - - /* In the flow context, do nothing. */ - - if (parser->flow_level) - return 1; - - /* Loop through the indentation levels in the stack. */ - - while (parser->indent > column) - { - /* Create a token and append it to the queue. */ - - TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - /* Pop the indentation level. */ - - parser->indent = POP(parser, parser->indents); - } - - return 1; -} - -/* - * Initialize the scanner and produce the STREAM-START token. - */ - -static int -yaml_parser_fetch_stream_start(yaml_parser_t *parser) -{ - yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } }; - yaml_token_t token; - - /* Set the initial indentation. */ - - parser->indent = -1; - - /* Initialize the simple key stack. */ - - if (!PUSH(parser, parser->simple_keys, simple_key)) - return 0; - - /* A simple key is allowed at the beginning of the stream. */ - - parser->simple_key_allowed = 1; - - /* We have started. */ - - parser->stream_start_produced = 1; - - /* Create the STREAM-START token and append it to the queue. */ - - STREAM_START_TOKEN_INIT(token, parser->encoding, - parser->mark, parser->mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the STREAM-END token and shut down the scanner. - */ - -static int -yaml_parser_fetch_stream_end(yaml_parser_t *parser) -{ - yaml_token_t token; - - /* Force new line. */ - - if (parser->mark.column != 0) { - parser->mark.column = 0; - parser->mark.line ++; - } - - /* Reset the indentation level. */ - - if (!yaml_parser_unroll_indent(parser, -1)) - return 0; - - /* Reset simple keys. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - parser->simple_key_allowed = 0; - - /* Create the STREAM-END token and append it to the queue. */ - - STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. - */ - -static int -yaml_parser_fetch_directive(yaml_parser_t *parser) -{ - yaml_token_t token; - - /* Reset the indentation level. */ - - if (!yaml_parser_unroll_indent(parser, -1)) - return 0; - - /* Reset simple keys. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - parser->simple_key_allowed = 0; - - /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */ - - if (!yaml_parser_scan_directive(parser, &token)) - return 0; - - /* Append the token to the queue. */ - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - - return 1; -} - -/* - * Produce the DOCUMENT-START or DOCUMENT-END token. - */ - -static int -yaml_parser_fetch_document_indicator(yaml_parser_t *parser, - yaml_token_type_t type) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* Reset the indentation level. */ - - if (!yaml_parser_unroll_indent(parser, -1)) - return 0; - - /* Reset simple keys. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - parser->simple_key_allowed = 0; - - /* Consume the token. */ - - start_mark = parser->mark; - - SKIP(parser); - SKIP(parser); - SKIP(parser); - - end_mark = parser->mark; - - /* Create the DOCUMENT-START or DOCUMENT-END token. */ - - TOKEN_INIT(token, type, start_mark, end_mark); - - /* Append the token to the queue. */ - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. - */ - -static int -yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, - yaml_token_type_t type) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* The indicators '[' and '{' may start a simple key. */ - - if (!yaml_parser_save_simple_key(parser)) - return 0; - - /* Increase the flow level. */ - - if (!yaml_parser_increase_flow_level(parser)) - return 0; - - /* A simple key may follow the indicators '[' and '{'. */ - - parser->simple_key_allowed = 1; - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */ - - TOKEN_INIT(token, type, start_mark, end_mark); - - /* Append the token to the queue. */ - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. - */ - -static int -yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, - yaml_token_type_t type) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* Reset any potential simple key on the current flow level. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - /* Decrease the flow level. */ - - if (!yaml_parser_decrease_flow_level(parser)) - return 0; - - /* No simple keys after the indicators ']' and '}'. */ - - parser->simple_key_allowed = 0; - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */ - - TOKEN_INIT(token, type, start_mark, end_mark); - - /* Append the token to the queue. */ - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the FLOW-ENTRY token. - */ - -static int -yaml_parser_fetch_flow_entry(yaml_parser_t *parser) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* Reset any potential simple keys on the current flow level. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - /* Simple keys are allowed after ','. */ - - parser->simple_key_allowed = 1; - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the FLOW-ENTRY token and append it to the queue. */ - - TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the BLOCK-ENTRY token. - */ - -static int -yaml_parser_fetch_block_entry(yaml_parser_t *parser) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* Check if the scanner is in the block context. */ - - if (!parser->flow_level) - { - /* Check if we are allowed to start a new entry. */ - - if (!parser->simple_key_allowed) { - return yaml_parser_set_scanner_error(parser, NULL, parser->mark, - "block sequence entries are not allowed in this context"); - } - - /* Add the BLOCK-SEQUENCE-START token if needed. */ - - if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, - YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark)) - return 0; - } - else - { - /* - * It is an error for the '-' indicator to occur in the flow context, - * but we let the Parser detect and report about it because the Parser - * is able to point to the context. - */ - } - - /* Reset any potential simple keys on the current flow level. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - /* Simple keys are allowed after '-'. */ - - parser->simple_key_allowed = 1; - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the BLOCK-ENTRY token and append it to the queue. */ - - TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the KEY token. - */ - -static int -yaml_parser_fetch_key(yaml_parser_t *parser) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - - /* In the block context, additional checks are required. */ - - if (!parser->flow_level) - { - /* Check if we are allowed to start a new key (not necessary simple). */ - - if (!parser->simple_key_allowed) { - return yaml_parser_set_scanner_error(parser, NULL, parser->mark, - "mapping keys are not allowed in this context"); - } - - /* Add the BLOCK-MAPPING-START token if needed. */ - - if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, - YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) - return 0; - } - - /* Reset any potential simple keys on the current flow level. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - /* Simple keys are allowed after '?' in the block context. */ - - parser->simple_key_allowed = (!parser->flow_level); - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the KEY token and append it to the queue. */ - - TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the VALUE token. - */ - -static int -yaml_parser_fetch_value(yaml_parser_t *parser) -{ - yaml_mark_t start_mark, end_mark; - yaml_token_t token; - yaml_simple_key_t *simple_key = parser->simple_keys.top-1; - - /* Have we found a simple key? */ - - if (simple_key->possible) - { - - /* Create the KEY token and insert it into the queue. */ - - TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark); - - if (!QUEUE_INSERT(parser, parser->tokens, - simple_key->token_number - parser->tokens_parsed, token)) - return 0; - - /* In the block context, we may need to add the BLOCK-MAPPING-START token. */ - - if (!yaml_parser_roll_indent(parser, simple_key->mark.column, - simple_key->token_number, - YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark)) - return 0; - - /* Remove the simple key. */ - - simple_key->possible = 0; - - /* A simple key cannot follow another simple key. */ - - parser->simple_key_allowed = 0; - } - else - { - /* The ':' indicator follows a complex key. */ - - /* In the block context, extra checks are required. */ - - if (!parser->flow_level) - { - /* Check if we are allowed to start a complex value. */ - - if (!parser->simple_key_allowed) { - return yaml_parser_set_scanner_error(parser, NULL, parser->mark, - "mapping values are not allowed in this context"); - } - - /* Add the BLOCK-MAPPING-START token if needed. */ - - if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, - YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) - return 0; - } - - /* Simple keys after ':' are allowed in the block context. */ - - parser->simple_key_allowed = (!parser->flow_level); - } - - /* Consume the token. */ - - start_mark = parser->mark; - SKIP(parser); - end_mark = parser->mark; - - /* Create the VALUE token and append it to the queue. */ - - TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark); - - if (!ENQUEUE(parser, parser->tokens, token)) - return 0; - - return 1; -} - -/* - * Produce the ALIAS or ANCHOR token. - */ - -static int -yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type) -{ - yaml_token_t token; - - /* An anchor or an alias could be a simple key. */ - - if (!yaml_parser_save_simple_key(parser)) - return 0; - - /* A simple key cannot follow an anchor or an alias. */ - - parser->simple_key_allowed = 0; - - /* Create the ALIAS or ANCHOR token and append it to the queue. */ - - if (!yaml_parser_scan_anchor(parser, &token, type)) - return 0; - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - return 1; -} - -/* - * Produce the TAG token. - */ - -static int -yaml_parser_fetch_tag(yaml_parser_t *parser) -{ - yaml_token_t token; - - /* A tag could be a simple key. */ - - if (!yaml_parser_save_simple_key(parser)) - return 0; - - /* A simple key cannot follow a tag. */ - - parser->simple_key_allowed = 0; - - /* Create the TAG token and append it to the queue. */ - - if (!yaml_parser_scan_tag(parser, &token)) - return 0; - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - - return 1; -} - -/* - * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. - */ - -static int -yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal) -{ - yaml_token_t token; - - /* Remove any potential simple keys. */ - - if (!yaml_parser_remove_simple_key(parser)) - return 0; - - /* A simple key may follow a block scalar. */ - - parser->simple_key_allowed = 1; - - /* Create the SCALAR token and append it to the queue. */ - - if (!yaml_parser_scan_block_scalar(parser, &token, literal)) - return 0; - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - - return 1; -} - -/* - * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. - */ - -static int -yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single) -{ - yaml_token_t token; - - /* A plain scalar could be a simple key. */ - - if (!yaml_parser_save_simple_key(parser)) - return 0; - - /* A simple key cannot follow a flow scalar. */ - - parser->simple_key_allowed = 0; - - /* Create the SCALAR token and append it to the queue. */ - - if (!yaml_parser_scan_flow_scalar(parser, &token, single)) - return 0; - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - - return 1; -} - -/* - * Produce the SCALAR(...,plain) token. - */ - -static int -yaml_parser_fetch_plain_scalar(yaml_parser_t *parser) -{ - yaml_token_t token; - - /* A plain scalar could be a simple key. */ - - if (!yaml_parser_save_simple_key(parser)) - return 0; - - /* A simple key cannot follow a flow scalar. */ - - parser->simple_key_allowed = 0; - - /* Create the SCALAR token and append it to the queue. */ - - if (!yaml_parser_scan_plain_scalar(parser, &token)) - return 0; - - if (!ENQUEUE(parser, parser->tokens, token)) { - yaml_token_delete(&token); - return 0; - } - - return 1; -} - -/* - * Eat whitespaces and comments until the next token is found. - */ - -static int -yaml_parser_scan_to_next_token(yaml_parser_t *parser) -{ - /* Until the next token is not found. */ - - while (1) - { - /* Allow the BOM mark to start a line. */ - - if (!CACHE(parser, 1)) return 0; - - if (parser->mark.column == 0 && IS_BOM(parser->buffer)) - SKIP(parser); - - /* - * Eat whitespaces. - * - * Tabs are allowed: - * - * - in the flow context; - * - in the block context, but not at the beginning of the line or - * after '-', '?', or ':' (complex value). - */ - - if (!CACHE(parser, 1)) return 0; - - while (CHECK(parser->buffer,' ') || - ((parser->flow_level || !parser->simple_key_allowed) && - CHECK(parser->buffer, '\t'))) { - SKIP(parser); - if (!CACHE(parser, 1)) return 0; - } - - /* Eat a comment until a line break. */ - - if (CHECK(parser->buffer, '#')) { - while (!IS_BREAKZ(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) return 0; - } - } - - /* If it is a line break, eat it. */ - - if (IS_BREAK(parser->buffer)) - { - if (!CACHE(parser, 2)) return 0; - SKIP_LINE(parser); - - /* In the block context, a new line may start a simple key. */ - - if (!parser->flow_level) { - parser->simple_key_allowed = 1; - } - } - else - { - /* We have found a token. */ - - break; - } - } - - return 1; -} - -/* - * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. - * - * Scope: - * %YAML 1.1 # a comment \n - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * %TAG !yaml! tag:yaml.org,2002: \n - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - -int -yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token) -{ - yaml_mark_t start_mark, end_mark; - yaml_char_t *name = NULL; - int major, minor; - yaml_char_t *handle = NULL, *prefix = NULL; - - /* Eat '%'. */ - - start_mark = parser->mark; - - SKIP(parser); - - /* Scan the directive name. */ - - if (!yaml_parser_scan_directive_name(parser, start_mark, &name)) - goto error; - - /* Is it a YAML directive? */ - - if (strcmp((char *)name, "YAML") == 0) - { - /* Scan the VERSION directive value. */ - - if (!yaml_parser_scan_version_directive_value(parser, start_mark, - &major, &minor)) - goto error; - - end_mark = parser->mark; - - /* Create a VERSION-DIRECTIVE token. */ - - VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor, - start_mark, end_mark); - } - - /* Is it a TAG directive? */ - - else if (strcmp((char *)name, "TAG") == 0) - { - /* Scan the TAG directive value. */ - - if (!yaml_parser_scan_tag_directive_value(parser, start_mark, - &handle, &prefix)) - goto error; - - end_mark = parser->mark; - - /* Create a TAG-DIRECTIVE token. */ - - TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix, - start_mark, end_mark); - } - - /* Unknown directive. */ - - else - { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unknown directive name"); - goto error; - } - - /* Eat the rest of the line including any comments. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_BLANK(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - - if (CHECK(parser->buffer, '#')) { - while (!IS_BREAKZ(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - } - - /* Check if we are at the end of the line. */ - - if (!IS_BREAKZ(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "did not find expected comment or line break"); - goto error; - } - - /* Eat a line break. */ - - if (IS_BREAK(parser->buffer)) { - if (!CACHE(parser, 2)) goto error; - SKIP_LINE(parser); - } - - yaml_free(name); - - return 1; - -error: - yaml_free(prefix); - yaml_free(handle); - yaml_free(name); - return 0; -} - -/* - * Scan the directive name. - * - * Scope: - * %YAML 1.1 # a comment \n - * ^^^^ - * %TAG !yaml! tag:yaml.org,2002: \n - * ^^^ - */ - -static int -yaml_parser_scan_directive_name(yaml_parser_t *parser, - yaml_mark_t start_mark, yaml_char_t **name) -{ - yaml_string_t string = NULL_STRING; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - - /* Consume the directive name. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_ALPHA(parser->buffer)) - { - if (!READ(parser, string)) goto error; - if (!CACHE(parser, 1)) goto error; - } - - /* Check if the name is empty. */ - - if (string.start == string.pointer) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "could not find expected directive name"); - goto error; - } - - /* Check for an blank character after the name. */ - - if (!IS_BLANKZ(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unexpected non-alphabetical character"); - goto error; - } - - *name = string.start; - - return 1; - -error: - STRING_DEL(parser, string); - return 0; -} - -/* - * Scan the value of VERSION-DIRECTIVE. - * - * Scope: - * %YAML 1.1 # a comment \n - * ^^^^^^ - */ - -static int -yaml_parser_scan_version_directive_value(yaml_parser_t *parser, - yaml_mark_t start_mark, int *major, int *minor) -{ - /* Eat whitespaces. */ - - if (!CACHE(parser, 1)) return 0; - - while (IS_BLANK(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) return 0; - } - - /* Consume the major version number. */ - - if (!yaml_parser_scan_version_directive_number(parser, start_mark, major)) - return 0; - - /* Eat '.'. */ - - if (!CHECK(parser->buffer, '.')) { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected digit or '.' character"); - } - - SKIP(parser); - - /* Consume the minor version number. */ - - if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor)) - return 0; - - return 1; -} - -#define MAX_NUMBER_LENGTH 9 - -/* - * Scan the version number of VERSION-DIRECTIVE. - * - * Scope: - * %YAML 1.1 # a comment \n - * ^ - * %YAML 1.1 # a comment \n - * ^ - */ - -static int -yaml_parser_scan_version_directive_number(yaml_parser_t *parser, - yaml_mark_t start_mark, int *number) -{ - int value = 0; - size_t length = 0; - - /* Repeat while the next character is digit. */ - - if (!CACHE(parser, 1)) return 0; - - while (IS_DIGIT(parser->buffer)) - { - /* Check if the number is too long. */ - - if (++length > MAX_NUMBER_LENGTH) { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "found extremely long version number"); - } - - value = value*10 + AS_DIGIT(parser->buffer); - - SKIP(parser); - - if (!CACHE(parser, 1)) return 0; - } - - /* Check if the number was present. */ - - if (!length) { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected version number"); - } - - *number = value; - - return 1; -} - -/* - * Scan the value of a TAG-DIRECTIVE token. - * - * Scope: - * %TAG !yaml! tag:yaml.org,2002: \n - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - -static int -yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, - yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix) -{ - yaml_char_t *handle_value = NULL; - yaml_char_t *prefix_value = NULL; - - /* Eat whitespaces. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_BLANK(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - - /* Scan a handle. */ - - if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value)) - goto error; - - /* Expect a whitespace. */ - - if (!CACHE(parser, 1)) goto error; - - if (!IS_BLANK(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace"); - goto error; - } - - /* Eat whitespaces. */ - - while (IS_BLANK(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - - /* Scan a prefix. */ - - if (!yaml_parser_scan_tag_uri(parser, 1, 1, NULL, start_mark, &prefix_value)) - goto error; - - /* Expect a whitespace or line break. */ - - if (!CACHE(parser, 1)) goto error; - - if (!IS_BLANKZ(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace or line break"); - goto error; - } - - *handle = handle_value; - *prefix = prefix_value; - - return 1; - -error: - yaml_free(handle_value); - yaml_free(prefix_value); - return 0; -} - -static int -yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, - yaml_token_type_t type) -{ - int length = 0; - yaml_mark_t start_mark, end_mark; - yaml_string_t string = NULL_STRING; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - - /* Eat the indicator character. */ - - start_mark = parser->mark; - - SKIP(parser); - - /* Consume the value. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_ALPHA(parser->buffer)) { - if (!READ(parser, string)) goto error; - if (!CACHE(parser, 1)) goto error; - length ++; - } - - end_mark = parser->mark; - - /* - * Check if length of the anchor is greater than 0 and it is followed by - * a whitespace character or one of the indicators: - * - * '?', ':', ',', ']', '}', '%', '@', '`'. - */ - - if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?') - || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',') - || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}') - || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@') - || CHECK(parser->buffer, '`'))) { - yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ? - "while scanning an anchor" : "while scanning an alias", start_mark, - "did not find expected alphabetic or numeric character"); - goto error; - } - - /* Create a token. */ - - if (type == YAML_ANCHOR_TOKEN) { - ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark); - } - else { - ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark); - } - - return 1; - -error: - STRING_DEL(parser, string); - return 0; -} - -/* - * Scan a TAG token. - */ - -static int -yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token) -{ - yaml_char_t *handle = NULL; - yaml_char_t *suffix = NULL; - yaml_mark_t start_mark, end_mark; - - start_mark = parser->mark; - - /* Check if the tag is in the canonical form. */ - - if (!CACHE(parser, 2)) goto error; - - if (CHECK_AT(parser->buffer, '<', 1)) - { - /* Set the handle to '' */ - - handle = YAML_MALLOC(1); - if (!handle) goto error; - handle[0] = '\0'; - - /* Eat '!<' */ - - SKIP(parser); - SKIP(parser); - - /* Consume the tag value. */ - - if (!yaml_parser_scan_tag_uri(parser, 1, 0, NULL, start_mark, &suffix)) - goto error; - - /* Check for '>' and eat it. */ - - if (!CHECK(parser->buffer, '>')) { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find the expected '>'"); - goto error; - } - - SKIP(parser); - } - else - { - /* The tag has either the '!suffix' or the '!handle!suffix' form. */ - - /* First, try to scan a handle. */ - - if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle)) - goto error; - - /* Check if it is, indeed, handle. */ - - if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!') - { - /* Scan the suffix now. */ - - if (!yaml_parser_scan_tag_uri(parser, 0, 0, NULL, start_mark, &suffix)) - goto error; - } - else - { - /* It wasn't a handle after all. Scan the rest of the tag. */ - - if (!yaml_parser_scan_tag_uri(parser, 0, 0, handle, start_mark, &suffix)) - goto error; - - /* Set the handle to '!'. */ - - yaml_free(handle); - handle = YAML_MALLOC(2); - if (!handle) goto error; - handle[0] = '!'; - handle[1] = '\0'; - - /* - * A special case: the '!' tag. Set the handle to '' and the - * suffix to '!'. - */ - - if (suffix[0] == '\0') { - yaml_char_t *tmp = handle; - handle = suffix; - suffix = tmp; - } - } - } - - /* Check the character which ends the tag. */ - - if (!CACHE(parser, 1)) goto error; - - if (!IS_BLANKZ(parser->buffer)) { - if (!parser->flow_level || !CHECK(parser->buffer, ',') ) { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find expected whitespace or line break"); - goto error; - } - } - - end_mark = parser->mark; - - /* Create a token. */ - - TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark); - - return 1; - -error: - yaml_free(handle); - yaml_free(suffix); - return 0; -} - -/* - * Scan a tag handle. - */ - -static int -yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, - yaml_mark_t start_mark, yaml_char_t **handle) -{ - yaml_string_t string = NULL_STRING; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - - /* Check the initial '!' character. */ - - if (!CACHE(parser, 1)) goto error; - - if (!CHECK(parser->buffer, '!')) { - yaml_parser_set_scanner_error(parser, directive ? - "while scanning a tag directive" : "while scanning a tag", - start_mark, "did not find expected '!'"); - goto error; - } - - /* Copy the '!' character. */ - - if (!READ(parser, string)) goto error; - - /* Copy all subsequent alphabetical and numerical characters. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_ALPHA(parser->buffer)) - { - if (!READ(parser, string)) goto error; - if (!CACHE(parser, 1)) goto error; - } - - /* Check if the trailing character is '!' and copy it. */ - - if (CHECK(parser->buffer, '!')) - { - if (!READ(parser, string)) goto error; - } - else - { - /* - * It's either the '!' tag or not really a tag handle. If it's a %TAG - * directive, it's an error. If it's a tag token, it must be a part of - * URI. - */ - - if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) { - yaml_parser_set_scanner_error(parser, "while parsing a tag directive", - start_mark, "did not find expected '!'"); - goto error; - } - } - - *handle = string.start; - - return 1; - -error: - STRING_DEL(parser, string); - return 0; -} - -/* - * Scan a tag. - */ - -static int -yaml_parser_scan_tag_uri(yaml_parser_t *parser, int uri_char, int directive, - yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri) -{ - size_t length = head ? strlen((char *)head) : 0; - yaml_string_t string = NULL_STRING; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - - /* Resize the string to include the head. */ - - while ((size_t)(string.end - string.start) <= length) { - if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) { - parser->error = YAML_MEMORY_ERROR; - goto error; - } - } - - /* - * Copy the head if needed. - * - * Note that we don't copy the leading '!' character. - */ - - if (length > 1) { - memcpy(string.start, head+1, length-1); - string.pointer += length-1; - } - - /* Scan the tag. */ - - if (!CACHE(parser, 1)) goto error; - - /* - * The set of characters that may appear in URI is as follows: - * - * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', - * '=', '+', '$', '.', '!', '~', '*', '\'', '(', ')', '%'. - * - * If we are inside a verbatim tag <...> (parameter uri_char is true) - * then also the following flow indicators are allowed: - * ',', '[', ']' - */ - - while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';') - || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?') - || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@') - || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=') - || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$') - || CHECK(parser->buffer, '.') || CHECK(parser->buffer, '%') - || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~') - || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'') - || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')') - || (uri_char && ( - CHECK(parser->buffer, ',') - || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']') - ) - )) - { - /* Check if it is a URI-escape sequence. */ - - if (CHECK(parser->buffer, '%')) { - if (!STRING_EXTEND(parser, string)) - goto error; - - if (!yaml_parser_scan_uri_escapes(parser, - directive, start_mark, &string)) goto error; - } - else { - if (!READ(parser, string)) goto error; - } - - length ++; - if (!CACHE(parser, 1)) goto error; - } - - /* Check if the tag is non-empty. */ - - if (!length) { - if (!STRING_EXTEND(parser, string)) - goto error; - - yaml_parser_set_scanner_error(parser, directive ? - "while parsing a %TAG directive" : "while parsing a tag", - start_mark, "did not find expected tag URI"); - goto error; - } - - *uri = string.start; - - return 1; - -error: - STRING_DEL(parser, string); - return 0; -} - -/* - * Decode an URI-escape sequence corresponding to a single UTF-8 character. - */ - -static int -yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, - yaml_mark_t start_mark, yaml_string_t *string) -{ - int width = 0; - - /* Decode the required number of characters. */ - - do { - - unsigned char octet = 0; - - /* Check for a URI-escaped octet. */ - - if (!CACHE(parser, 3)) return 0; - - if (!(CHECK(parser->buffer, '%') - && IS_HEX_AT(parser->buffer, 1) - && IS_HEX_AT(parser->buffer, 2))) { - return yaml_parser_set_scanner_error(parser, directive ? - "while parsing a %TAG directive" : "while parsing a tag", - start_mark, "did not find URI escaped octet"); - } - - /* Get the octet. */ - - octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2); - - /* If it is the leading octet, determine the length of the UTF-8 sequence. */ - - if (!width) - { - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; - if (!width) { - return yaml_parser_set_scanner_error(parser, directive ? - "while parsing a %TAG directive" : "while parsing a tag", - start_mark, "found an incorrect leading UTF-8 octet"); - } - } - else - { - /* Check if the trailing octet is correct. */ - - if ((octet & 0xC0) != 0x80) { - return yaml_parser_set_scanner_error(parser, directive ? - "while parsing a %TAG directive" : "while parsing a tag", - start_mark, "found an incorrect trailing UTF-8 octet"); - } - } - - /* Copy the octet and move the pointers. */ - - *(string->pointer++) = octet; - SKIP(parser); - SKIP(parser); - SKIP(parser); - - } while (--width); - - return 1; -} - -/* - * Scan a block scalar. - */ - -static int -yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, - int literal) -{ - yaml_mark_t start_mark; - yaml_mark_t end_mark; - yaml_string_t string = NULL_STRING; - yaml_string_t leading_break = NULL_STRING; - yaml_string_t trailing_breaks = NULL_STRING; - int chomping = 0; - int increment = 0; - int indent = 0; - int leading_blank = 0; - int trailing_blank = 0; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; - - /* Eat the indicator '|' or '>'. */ - - start_mark = parser->mark; - - SKIP(parser); - - /* Scan the additional block scalar indicators. */ - - if (!CACHE(parser, 1)) goto error; - - /* Check for a chomping indicator. */ - - if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) - { - /* Set the chomping method and eat the indicator. */ - - chomping = CHECK(parser->buffer, '+') ? +1 : -1; - - SKIP(parser); - - /* Check for an indentation indicator. */ - - if (!CACHE(parser, 1)) goto error; - - if (IS_DIGIT(parser->buffer)) - { - /* Check that the indentation is greater than 0. */ - - if (CHECK(parser->buffer, '0')) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0"); - goto error; - } - - /* Get the indentation level and eat the indicator. */ - - increment = AS_DIGIT(parser->buffer); - - SKIP(parser); - } - } - - /* Do the same as above, but in the opposite order. */ - - else if (IS_DIGIT(parser->buffer)) - { - if (CHECK(parser->buffer, '0')) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0"); - goto error; - } - - increment = AS_DIGIT(parser->buffer); - - SKIP(parser); - - if (!CACHE(parser, 1)) goto error; - - if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) { - chomping = CHECK(parser->buffer, '+') ? +1 : -1; - - SKIP(parser); - } - } - - /* Eat whitespaces and comments to the end of the line. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_BLANK(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - - if (CHECK(parser->buffer, '#')) { - while (!IS_BREAKZ(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) goto error; - } - } - - /* Check if we are at the end of the line. */ - - if (!IS_BREAKZ(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "did not find expected comment or line break"); - goto error; - } - - /* Eat a line break. */ - - if (IS_BREAK(parser->buffer)) { - if (!CACHE(parser, 2)) goto error; - SKIP_LINE(parser); - } - - end_mark = parser->mark; - - /* Set the indentation level if it was specified. */ - - if (increment) { - indent = parser->indent >= 0 ? parser->indent+increment : increment; - } - - /* Scan the leading line breaks and determine the indentation level if needed. */ - - if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, - start_mark, &end_mark)) goto error; - - /* Scan the block scalar content. */ - - if (!CACHE(parser, 1)) goto error; - - while ((int)parser->mark.column == indent && !(IS_Z(parser->buffer))) - { - /* - * We are at the beginning of a non-empty line. - */ - - /* Is it a trailing whitespace? */ - - trailing_blank = IS_BLANK(parser->buffer); - - /* Check if we need to fold the leading line break. */ - - if (!literal && (*leading_break.start == '\n') - && !leading_blank && !trailing_blank) - { - /* Do we need to join the lines by space? */ - - if (*trailing_breaks.start == '\0') { - if (!STRING_EXTEND(parser, string)) goto error; - *(string.pointer ++) = ' '; - } - - CLEAR(parser, leading_break); - } - else { - if (!JOIN(parser, string, leading_break)) goto error; - CLEAR(parser, leading_break); - } - - /* Append the remaining line breaks. */ - - if (!JOIN(parser, string, trailing_breaks)) goto error; - CLEAR(parser, trailing_breaks); - - /* Is it a leading whitespace? */ - - leading_blank = IS_BLANK(parser->buffer); - - /* Consume the current line. */ - - while (!IS_BREAKZ(parser->buffer)) { - if (!READ(parser, string)) goto error; - if (!CACHE(parser, 1)) goto error; - } - - /* Consume the line break. */ - - if (!CACHE(parser, 2)) goto error; - - if (!READ_LINE(parser, leading_break)) goto error; - - /* Eat the following indentation spaces and line breaks. */ - - if (!yaml_parser_scan_block_scalar_breaks(parser, - &indent, &trailing_breaks, start_mark, &end_mark)) goto error; - } - - /* Chomp the tail. */ - - if (chomping != -1) { - if (!JOIN(parser, string, leading_break)) goto error; - } - if (chomping == 1) { - if (!JOIN(parser, string, trailing_breaks)) goto error; - } - - /* Create a token. */ - - SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, - literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE, - start_mark, end_mark); - - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - - return 1; - -error: - STRING_DEL(parser, string); - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - - return 0; -} - -/* - * Scan indentation spaces and line breaks for a block scalar. Determine the - * indentation level if needed. - */ - -static int -yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, - int *indent, yaml_string_t *breaks, - yaml_mark_t start_mark, yaml_mark_t *end_mark) -{ - int max_indent = 0; - - *end_mark = parser->mark; - - /* Eat the indentation spaces and line breaks. */ - - while (1) - { - /* Eat the indentation spaces. */ - - if (!CACHE(parser, 1)) return 0; - - while ((!*indent || (int)parser->mark.column < *indent) - && IS_SPACE(parser->buffer)) { - SKIP(parser); - if (!CACHE(parser, 1)) return 0; - } - - if ((int)parser->mark.column > max_indent) - max_indent = (int)parser->mark.column; - - /* Check for a tab character messing the indentation. */ - - if ((!*indent || (int)parser->mark.column < *indent) - && IS_TAB(parser->buffer)) { - return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found a tab character where an indentation space is expected"); - } - - /* Have we found a non-empty line? */ - - if (!IS_BREAK(parser->buffer)) break; - - /* Consume the line break. */ - - if (!CACHE(parser, 2)) return 0; - if (!READ_LINE(parser, *breaks)) return 0; - *end_mark = parser->mark; - } - - /* Determine the indentation level if needed. */ - - if (!*indent) { - *indent = max_indent; - if (*indent < parser->indent + 1) - *indent = parser->indent + 1; - if (*indent < 1) - *indent = 1; - } - - return 1; -} - -/* - * Scan a quoted scalar. - */ - -static int -yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, - int single) -{ - yaml_mark_t start_mark; - yaml_mark_t end_mark; - yaml_string_t string = NULL_STRING; - yaml_string_t leading_break = NULL_STRING; - yaml_string_t trailing_breaks = NULL_STRING; - yaml_string_t whitespaces = NULL_STRING; - int leading_blanks; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; - - /* Eat the left quote. */ - - start_mark = parser->mark; - - SKIP(parser); - - /* Consume the content of the quoted scalar. */ - - while (1) - { - /* Check that there are no document indicators at the beginning of the line. */ - - if (!CACHE(parser, 4)) goto error; - - if (parser->mark.column == 0 && - ((CHECK_AT(parser->buffer, '-', 0) && - CHECK_AT(parser->buffer, '-', 1) && - CHECK_AT(parser->buffer, '-', 2)) || - (CHECK_AT(parser->buffer, '.', 0) && - CHECK_AT(parser->buffer, '.', 1) && - CHECK_AT(parser->buffer, '.', 2))) && - IS_BLANKZ_AT(parser->buffer, 3)) - { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected document indicator"); - goto error; - } - - /* Check for EOF. */ - - if (IS_Z(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected end of stream"); - goto error; - } - - /* Consume non-blank characters. */ - - if (!CACHE(parser, 2)) goto error; - - leading_blanks = 0; - - while (!IS_BLANKZ(parser->buffer)) - { - /* Check for an escaped single quote. */ - - if (single && CHECK_AT(parser->buffer, '\'', 0) - && CHECK_AT(parser->buffer, '\'', 1)) - { - if (!STRING_EXTEND(parser, string)) goto error; - *(string.pointer++) = '\''; - SKIP(parser); - SKIP(parser); - } - - /* Check for the right quote. */ - - else if (CHECK(parser->buffer, single ? '\'' : '"')) - { - break; - } - - /* Check for an escaped line break. */ - - else if (!single && CHECK(parser->buffer, '\\') - && IS_BREAK_AT(parser->buffer, 1)) - { - if (!CACHE(parser, 3)) goto error; - SKIP(parser); - SKIP_LINE(parser); - leading_blanks = 1; - break; - } - - /* Check for an escape sequence. */ - - else if (!single && CHECK(parser->buffer, '\\')) - { - size_t code_length = 0; - - if (!STRING_EXTEND(parser, string)) goto error; - - /* Check the escape character. */ - - switch (parser->buffer.pointer[1]) - { - case '0': - *(string.pointer++) = '\0'; - break; - - case 'a': - *(string.pointer++) = '\x07'; - break; - - case 'b': - *(string.pointer++) = '\x08'; - break; - - case 't': - case '\t': - *(string.pointer++) = '\x09'; - break; - - case 'n': - *(string.pointer++) = '\x0A'; - break; - - case 'v': - *(string.pointer++) = '\x0B'; - break; - - case 'f': - *(string.pointer++) = '\x0C'; - break; - - case 'r': - *(string.pointer++) = '\x0D'; - break; - - case 'e': - *(string.pointer++) = '\x1B'; - break; - - case ' ': - *(string.pointer++) = '\x20'; - break; - - case '"': - *(string.pointer++) = '"'; - break; - - case '/': - *(string.pointer++) = '/'; - break; - - case '\\': - *(string.pointer++) = '\\'; - break; - - case 'N': /* NEL (#x85) */ - *(string.pointer++) = '\xC2'; - *(string.pointer++) = '\x85'; - break; - - case '_': /* #xA0 */ - *(string.pointer++) = '\xC2'; - *(string.pointer++) = '\xA0'; - break; - - case 'L': /* LS (#x2028) */ - *(string.pointer++) = '\xE2'; - *(string.pointer++) = '\x80'; - *(string.pointer++) = '\xA8'; - break; - - case 'P': /* PS (#x2029) */ - *(string.pointer++) = '\xE2'; - *(string.pointer++) = '\x80'; - *(string.pointer++) = '\xA9'; - break; - - case 'x': - code_length = 2; - break; - - case 'u': - code_length = 4; - break; - - case 'U': - code_length = 8; - break; - - default: - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found unknown escape character"); - goto error; - } - - SKIP(parser); - SKIP(parser); - - /* Consume an arbitrary escape code. */ - - if (code_length) - { - unsigned int value = 0; - size_t k; - - /* Scan the character value. */ - - if (!CACHE(parser, code_length)) goto error; - - for (k = 0; k < code_length; k ++) { - if (!IS_HEX_AT(parser->buffer, k)) { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "did not find expected hexdecimal number"); - goto error; - } - value = (value << 4) + AS_HEX_AT(parser->buffer, k); - } - - /* Check the value and write the character. */ - - if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found invalid Unicode character escape code"); - goto error; - } - - if (value <= 0x7F) { - *(string.pointer++) = value; - } - else if (value <= 0x7FF) { - *(string.pointer++) = 0xC0 + (value >> 6); - *(string.pointer++) = 0x80 + (value & 0x3F); - } - else if (value <= 0xFFFF) { - *(string.pointer++) = 0xE0 + (value >> 12); - *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); - *(string.pointer++) = 0x80 + (value & 0x3F); - } - else { - *(string.pointer++) = 0xF0 + (value >> 18); - *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F); - *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); - *(string.pointer++) = 0x80 + (value & 0x3F); - } - - /* Advance the pointer. */ - - for (k = 0; k < code_length; k ++) { - SKIP(parser); - } - } - } - - else - { - /* It is a non-escaped non-blank character. */ - - if (!READ(parser, string)) goto error; - } - - if (!CACHE(parser, 2)) goto error; - } - - /* Check if we are at the end of the scalar. */ - - /* Fix for crash uninitialized value crash - * Credit for the bug and input is to OSS Fuzz - * Credit for the fix to Alex Gaynor - */ - if (!CACHE(parser, 1)) goto error; - if (CHECK(parser->buffer, single ? '\'' : '"')) - break; - - /* Consume blank characters. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) - { - if (IS_BLANK(parser->buffer)) - { - /* Consume a space or a tab character. */ - - if (!leading_blanks) { - if (!READ(parser, whitespaces)) goto error; - } - else { - SKIP(parser); - } - } - else - { - if (!CACHE(parser, 2)) goto error; - - /* Check if it is a first line break. */ - - if (!leading_blanks) - { - CLEAR(parser, whitespaces); - if (!READ_LINE(parser, leading_break)) goto error; - leading_blanks = 1; - } - else - { - if (!READ_LINE(parser, trailing_breaks)) goto error; - } - } - if (!CACHE(parser, 1)) goto error; - } - - /* Join the whitespaces or fold line breaks. */ - - if (leading_blanks) - { - /* Do we need to fold line breaks? */ - - if (leading_break.start[0] == '\n') { - if (trailing_breaks.start[0] == '\0') { - if (!STRING_EXTEND(parser, string)) goto error; - *(string.pointer++) = ' '; - } - else { - if (!JOIN(parser, string, trailing_breaks)) goto error; - CLEAR(parser, trailing_breaks); - } - CLEAR(parser, leading_break); - } - else { - if (!JOIN(parser, string, leading_break)) goto error; - if (!JOIN(parser, string, trailing_breaks)) goto error; - CLEAR(parser, leading_break); - CLEAR(parser, trailing_breaks); - } - } - else - { - if (!JOIN(parser, string, whitespaces)) goto error; - CLEAR(parser, whitespaces); - } - } - - /* Eat the right quote. */ - - SKIP(parser); - - end_mark = parser->mark; - - /* Create a token. */ - - SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, - single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE, - start_mark, end_mark); - - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - STRING_DEL(parser, whitespaces); - - return 1; - -error: - STRING_DEL(parser, string); - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - STRING_DEL(parser, whitespaces); - - return 0; -} - -/* - * Scan a plain scalar. - */ - -static int -yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token) -{ - yaml_mark_t start_mark; - yaml_mark_t end_mark; - yaml_string_t string = NULL_STRING; - yaml_string_t leading_break = NULL_STRING; - yaml_string_t trailing_breaks = NULL_STRING; - yaml_string_t whitespaces = NULL_STRING; - int leading_blanks = 0; - int indent = parser->indent+1; - - if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; - if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; - - start_mark = end_mark = parser->mark; - - /* Consume the content of the plain scalar. */ - - while (1) - { - /* Check for a document indicator. */ - - if (!CACHE(parser, 4)) goto error; - - if (parser->mark.column == 0 && - ((CHECK_AT(parser->buffer, '-', 0) && - CHECK_AT(parser->buffer, '-', 1) && - CHECK_AT(parser->buffer, '-', 2)) || - (CHECK_AT(parser->buffer, '.', 0) && - CHECK_AT(parser->buffer, '.', 1) && - CHECK_AT(parser->buffer, '.', 2))) && - IS_BLANKZ_AT(parser->buffer, 3)) break; - - /* Check for a comment. */ - - if (CHECK(parser->buffer, '#')) - break; - - /* Consume non-blank characters. */ - - while (!IS_BLANKZ(parser->buffer)) - { - /* Check for "x:" + one of ',?[]{}' in the flow context. TODO: Fix the test "spec-08-13". - * This is not completely according to the spec - * See http://yaml.org/spec/1.1/#id907281 9.1.3. Plain - */ - - if (parser->flow_level - && CHECK(parser->buffer, ':') - && ( - CHECK_AT(parser->buffer, ',', 1) - || CHECK_AT(parser->buffer, '?', 1) - || CHECK_AT(parser->buffer, '[', 1) - || CHECK_AT(parser->buffer, ']', 1) - || CHECK_AT(parser->buffer, '{', 1) - || CHECK_AT(parser->buffer, '}', 1) - ) - ) { - yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found unexpected ':'"); - goto error; - } - - /* Check for indicators that may end a plain scalar. */ - - if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1)) - || (parser->flow_level && - (CHECK(parser->buffer, ',') - || CHECK(parser->buffer, '[') - || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') - || CHECK(parser->buffer, '}')))) - break; - - /* Check if we need to join whitespaces and breaks. */ - - if (leading_blanks || whitespaces.start != whitespaces.pointer) - { - if (leading_blanks) - { - /* Do we need to fold line breaks? */ - - if (leading_break.start[0] == '\n') { - if (trailing_breaks.start[0] == '\0') { - if (!STRING_EXTEND(parser, string)) goto error; - *(string.pointer++) = ' '; - } - else { - if (!JOIN(parser, string, trailing_breaks)) goto error; - CLEAR(parser, trailing_breaks); - } - CLEAR(parser, leading_break); - } - else { - if (!JOIN(parser, string, leading_break)) goto error; - if (!JOIN(parser, string, trailing_breaks)) goto error; - CLEAR(parser, leading_break); - CLEAR(parser, trailing_breaks); - } - - leading_blanks = 0; - } - else - { - if (!JOIN(parser, string, whitespaces)) goto error; - CLEAR(parser, whitespaces); - } - } - - /* Copy the character. */ - - if (!READ(parser, string)) goto error; - - end_mark = parser->mark; - - if (!CACHE(parser, 2)) goto error; - } - - /* Is it the end? */ - - if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))) - break; - - /* Consume blank characters. */ - - if (!CACHE(parser, 1)) goto error; - - while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) - { - if (IS_BLANK(parser->buffer)) - { - /* Check for tab characters that abuse indentation. */ - - if (leading_blanks && (int)parser->mark.column < indent - && IS_TAB(parser->buffer)) { - yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found a tab character that violates indentation"); - goto error; - } - - /* Consume a space or a tab character. */ - - if (!leading_blanks) { - if (!READ(parser, whitespaces)) goto error; - } - else { - SKIP(parser); - } - } - else - { - if (!CACHE(parser, 2)) goto error; - - /* Check if it is a first line break. */ - - if (!leading_blanks) - { - CLEAR(parser, whitespaces); - if (!READ_LINE(parser, leading_break)) goto error; - leading_blanks = 1; - } - else - { - if (!READ_LINE(parser, trailing_breaks)) goto error; - } - } - if (!CACHE(parser, 1)) goto error; - } - - /* Check indentation level. */ - - if (!parser->flow_level && (int)parser->mark.column < indent) - break; - } - - /* Create a token. */ - - SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, - YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark); - - /* Note that we change the 'simple_key_allowed' flag. */ - - if (leading_blanks) { - parser->simple_key_allowed = 1; - } - - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - STRING_DEL(parser, whitespaces); - - return 1; - -error: - STRING_DEL(parser, string); - STRING_DEL(parser, leading_break); - STRING_DEL(parser, trailing_breaks); - STRING_DEL(parser, whitespaces); - - return 0; -} diff --git a/ext/psych/yaml/writer.c b/ext/psych/yaml/writer.c deleted file mode 100644 index 5d57f392f1..0000000000 --- a/ext/psych/yaml/writer.c +++ /dev/null @@ -1,141 +0,0 @@ - -#include "yaml_private.h" - -/* - * Declarations. - */ - -static int -yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); - -YAML_DECLARE(int) -yaml_emitter_flush(yaml_emitter_t *emitter); - -/* - * Set the writer error and return 0. - */ - -static int -yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) -{ - emitter->error = YAML_WRITER_ERROR; - emitter->problem = problem; - - return 0; -} - -/* - * Flush the output buffer. - */ - -YAML_DECLARE(int) -yaml_emitter_flush(yaml_emitter_t *emitter) -{ - int low, high; - - assert(emitter); /* Non-NULL emitter object is expected. */ - assert(emitter->write_handler); /* Write handler must be set. */ - assert(emitter->encoding); /* Output encoding must be set. */ - - emitter->buffer.last = emitter->buffer.pointer; - emitter->buffer.pointer = emitter->buffer.start; - - /* Check if the buffer is empty. */ - - if (emitter->buffer.start == emitter->buffer.last) { - return 1; - } - - /* If the output encoding is UTF-8, we don't need to recode the buffer. */ - - if (emitter->encoding == YAML_UTF8_ENCODING) - { - if (emitter->write_handler(emitter->write_handler_data, - emitter->buffer.start, - emitter->buffer.last - emitter->buffer.start)) { - emitter->buffer.last = emitter->buffer.start; - emitter->buffer.pointer = emitter->buffer.start; - return 1; - } - else { - return yaml_emitter_set_writer_error(emitter, "write error"); - } - } - - /* Recode the buffer into the raw buffer. */ - - low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); - high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); - - while (emitter->buffer.pointer != emitter->buffer.last) - { - unsigned char octet; - unsigned int width; - unsigned int value; - size_t k; - - /* - * See the "reader.c" code for more details on UTF-8 encoding. Note - * that we assume that the buffer contains a valid UTF-8 sequence. - */ - - /* Read the next UTF-8 character. */ - - octet = emitter->buffer.pointer[0]; - - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; - - value = (octet & 0x80) == 0x00 ? octet & 0x7F : - (octet & 0xE0) == 0xC0 ? octet & 0x1F : - (octet & 0xF0) == 0xE0 ? octet & 0x0F : - (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; - - for (k = 1; k < width; k ++) { - octet = emitter->buffer.pointer[k]; - value = (value << 6) + (octet & 0x3F); - } - - emitter->buffer.pointer += width; - - /* Write the character. */ - - if (value < 0x10000) - { - emitter->raw_buffer.last[high] = value >> 8; - emitter->raw_buffer.last[low] = value & 0xFF; - - emitter->raw_buffer.last += 2; - } - else - { - /* Write the character using a surrogate pair (check "reader.c"). */ - - value -= 0x10000; - emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); - emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; - emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); - emitter->raw_buffer.last[low+2] = value & 0xFF; - - emitter->raw_buffer.last += 4; - } - } - - /* Write the raw buffer. */ - - if (emitter->write_handler(emitter->write_handler_data, - emitter->raw_buffer.start, - emitter->raw_buffer.last - emitter->raw_buffer.start)) { - emitter->buffer.last = emitter->buffer.start; - emitter->buffer.pointer = emitter->buffer.start; - emitter->raw_buffer.last = emitter->raw_buffer.start; - emitter->raw_buffer.pointer = emitter->raw_buffer.start; - return 1; - } - else { - return yaml_emitter_set_writer_error(emitter, "write error"); - } -} - diff --git a/ext/psych/yaml/yaml.h b/ext/psych/yaml/yaml.h deleted file mode 100644 index f1b7bfde20..0000000000 --- a/ext/psych/yaml/yaml.h +++ /dev/null @@ -1,1985 +0,0 @@ -/** - * @file yaml.h - * @brief Public interface for libyaml. - * - * Include the header file with the code: - * @code - * #include <yaml.h> - * @endcode - */ - -#ifndef YAML_H -#define YAML_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -/** - * @defgroup export Export Definitions - * @{ - */ - -/** The public API declaration. */ - -#if defined(__MINGW32__) -# define YAML_DECLARE(type) type -#elif defined(_WIN32) -# if defined(YAML_DECLARE_STATIC) -# define YAML_DECLARE(type) type -# elif defined(YAML_DECLARE_EXPORT) -# define YAML_DECLARE(type) __declspec(dllexport) type -# else -# define YAML_DECLARE(type) __declspec(dllimport) type -# endif -#else -# define YAML_DECLARE(type) type -#endif - -/** @} */ - -/** - * @defgroup version Version Information - * @{ - */ - -/** - * Get the library version as a string. - * - * @returns The function returns the pointer to a static string of the form - * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version - * number, and @c Z is the patch version number. - */ - -YAML_DECLARE(const char *) -yaml_get_version_string(void); - -/** - * Get the library version numbers. - * - * @param[out] major Major version number. - * @param[out] minor Minor version number. - * @param[out] patch Patch version number. - */ - -YAML_DECLARE(void) -yaml_get_version(int *major, int *minor, int *patch); - -/** @} */ - -/** - * @defgroup basic Basic Types - * @{ - */ - -/** The character type (UTF-8 octet). */ -typedef unsigned char yaml_char_t; - -/** The version directive data. */ -typedef struct yaml_version_directive_s { - /** The major version number. */ - int major; - /** The minor version number. */ - int minor; -} yaml_version_directive_t; - -/** The tag directive data. */ -typedef struct yaml_tag_directive_s { - /** The tag handle. */ - yaml_char_t *handle; - /** The tag prefix. */ - yaml_char_t *prefix; -} yaml_tag_directive_t; - -/** The stream encoding. */ -typedef enum yaml_encoding_e { - /** Let the parser choose the encoding. */ - YAML_ANY_ENCODING, - /** The default UTF-8 encoding. */ - YAML_UTF8_ENCODING, - /** The UTF-16-LE encoding with BOM. */ - YAML_UTF16LE_ENCODING, - /** The UTF-16-BE encoding with BOM. */ - YAML_UTF16BE_ENCODING -} yaml_encoding_t; - -/** Line break types. */ - -typedef enum yaml_break_e { - /** Let the parser choose the break type. */ - YAML_ANY_BREAK, - /** Use CR for line breaks (Mac style). */ - YAML_CR_BREAK, - /** Use LN for line breaks (Unix style). */ - YAML_LN_BREAK, - /** Use CR LN for line breaks (DOS style). */ - YAML_CRLN_BREAK -} yaml_break_t; - -/** Many bad things could happen with the parser and emitter. */ -typedef enum yaml_error_type_e { - /** No error is produced. */ - YAML_NO_ERROR, - - /** Cannot allocate or reallocate a block of memory. */ - YAML_MEMORY_ERROR, - - /** Cannot read or decode the input stream. */ - YAML_READER_ERROR, - /** Cannot scan the input stream. */ - YAML_SCANNER_ERROR, - /** Cannot parse the input stream. */ - YAML_PARSER_ERROR, - /** Cannot compose a YAML document. */ - YAML_COMPOSER_ERROR, - - /** Cannot write to the output stream. */ - YAML_WRITER_ERROR, - /** Cannot emit a YAML stream. */ - YAML_EMITTER_ERROR -} yaml_error_type_t; - -/** The pointer position. */ -typedef struct yaml_mark_s { - /** The position index. */ - size_t index; - - /** The position line. */ - size_t line; - - /** The position column. */ - size_t column; -} yaml_mark_t; - -/** @} */ - -/** - * @defgroup styles Node Styles - * @{ - */ - -/** Scalar styles. */ -typedef enum yaml_scalar_style_e { - /** Let the emitter choose the style. */ - YAML_ANY_SCALAR_STYLE, - - /** The plain scalar style. */ - YAML_PLAIN_SCALAR_STYLE, - - /** The single-quoted scalar style. */ - YAML_SINGLE_QUOTED_SCALAR_STYLE, - /** The double-quoted scalar style. */ - YAML_DOUBLE_QUOTED_SCALAR_STYLE, - - /** The literal scalar style. */ - YAML_LITERAL_SCALAR_STYLE, - /** The folded scalar style. */ - YAML_FOLDED_SCALAR_STYLE -} yaml_scalar_style_t; - -/** Sequence styles. */ -typedef enum yaml_sequence_style_e { - /** Let the emitter choose the style. */ - YAML_ANY_SEQUENCE_STYLE, - - /** The block sequence style. */ - YAML_BLOCK_SEQUENCE_STYLE, - /** The flow sequence style. */ - YAML_FLOW_SEQUENCE_STYLE -} yaml_sequence_style_t; - -/** Mapping styles. */ -typedef enum yaml_mapping_style_e { - /** Let the emitter choose the style. */ - YAML_ANY_MAPPING_STYLE, - - /** The block mapping style. */ - YAML_BLOCK_MAPPING_STYLE, - /** The flow mapping style. */ - YAML_FLOW_MAPPING_STYLE -/* YAML_FLOW_SET_MAPPING_STYLE */ -} yaml_mapping_style_t; - -/** @} */ - -/** - * @defgroup tokens Tokens - * @{ - */ - -/** Token types. */ -typedef enum yaml_token_type_e { - /** An empty token. */ - YAML_NO_TOKEN, - - /** A STREAM-START token. */ - YAML_STREAM_START_TOKEN, - /** A STREAM-END token. */ - YAML_STREAM_END_TOKEN, - - /** A VERSION-DIRECTIVE token. */ - YAML_VERSION_DIRECTIVE_TOKEN, - /** A TAG-DIRECTIVE token. */ - YAML_TAG_DIRECTIVE_TOKEN, - /** A DOCUMENT-START token. */ - YAML_DOCUMENT_START_TOKEN, - /** A DOCUMENT-END token. */ - YAML_DOCUMENT_END_TOKEN, - - /** A BLOCK-SEQUENCE-START token. */ - YAML_BLOCK_SEQUENCE_START_TOKEN, - /** A BLOCK-MAPPING-START token. */ - YAML_BLOCK_MAPPING_START_TOKEN, - /** A BLOCK-END token. */ - YAML_BLOCK_END_TOKEN, - - /** A FLOW-SEQUENCE-START token. */ - YAML_FLOW_SEQUENCE_START_TOKEN, - /** A FLOW-SEQUENCE-END token. */ - YAML_FLOW_SEQUENCE_END_TOKEN, - /** A FLOW-MAPPING-START token. */ - YAML_FLOW_MAPPING_START_TOKEN, - /** A FLOW-MAPPING-END token. */ - YAML_FLOW_MAPPING_END_TOKEN, - - /** A BLOCK-ENTRY token. */ - YAML_BLOCK_ENTRY_TOKEN, - /** A FLOW-ENTRY token. */ - YAML_FLOW_ENTRY_TOKEN, - /** A KEY token. */ - YAML_KEY_TOKEN, - /** A VALUE token. */ - YAML_VALUE_TOKEN, - - /** An ALIAS token. */ - YAML_ALIAS_TOKEN, - /** An ANCHOR token. */ - YAML_ANCHOR_TOKEN, - /** A TAG token. */ - YAML_TAG_TOKEN, - /** A SCALAR token. */ - YAML_SCALAR_TOKEN -} yaml_token_type_t; - -/** The token structure. */ -typedef struct yaml_token_s { - - /** The token type. */ - yaml_token_type_t type; - - /** The token data. */ - union { - - /** The stream start (for @c YAML_STREAM_START_TOKEN). */ - struct { - /** The stream encoding. */ - yaml_encoding_t encoding; - } stream_start; - - /** The alias (for @c YAML_ALIAS_TOKEN). */ - struct { - /** The alias value. */ - yaml_char_t *value; - } alias; - - /** The anchor (for @c YAML_ANCHOR_TOKEN). */ - struct { - /** The anchor value. */ - yaml_char_t *value; - } anchor; - - /** The tag (for @c YAML_TAG_TOKEN). */ - struct { - /** The tag handle. */ - yaml_char_t *handle; - /** The tag suffix. */ - yaml_char_t *suffix; - } tag; - - /** The scalar value (for @c YAML_SCALAR_TOKEN). */ - struct { - /** The scalar value. */ - yaml_char_t *value; - /** The length of the scalar value. */ - size_t length; - /** The scalar style. */ - yaml_scalar_style_t style; - } scalar; - - /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */ - struct { - /** The major version number. */ - int major; - /** The minor version number. */ - int minor; - } version_directive; - - /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */ - struct { - /** The tag handle. */ - yaml_char_t *handle; - /** The tag prefix. */ - yaml_char_t *prefix; - } tag_directive; - - } data; - - /** The beginning of the token. */ - yaml_mark_t start_mark; - /** The end of the token. */ - yaml_mark_t end_mark; - -} yaml_token_t; - -/** - * Free any memory allocated for a token object. - * - * @param[in,out] token A token object. - */ - -YAML_DECLARE(void) -yaml_token_delete(yaml_token_t *token); - -/** @} */ - -/** - * @defgroup events Events - * @{ - */ - -/** Event types. */ -typedef enum yaml_event_type_e { - /** An empty event. */ - YAML_NO_EVENT, - - /** A STREAM-START event. */ - YAML_STREAM_START_EVENT, - /** A STREAM-END event. */ - YAML_STREAM_END_EVENT, - - /** A DOCUMENT-START event. */ - YAML_DOCUMENT_START_EVENT, - /** A DOCUMENT-END event. */ - YAML_DOCUMENT_END_EVENT, - - /** An ALIAS event. */ - YAML_ALIAS_EVENT, - /** A SCALAR event. */ - YAML_SCALAR_EVENT, - - /** A SEQUENCE-START event. */ - YAML_SEQUENCE_START_EVENT, - /** A SEQUENCE-END event. */ - YAML_SEQUENCE_END_EVENT, - - /** A MAPPING-START event. */ - YAML_MAPPING_START_EVENT, - /** A MAPPING-END event. */ - YAML_MAPPING_END_EVENT -} yaml_event_type_t; - -/** The event structure. */ -typedef struct yaml_event_s { - - /** The event type. */ - yaml_event_type_t type; - - /** The event data. */ - union { - - /** The stream parameters (for @c YAML_STREAM_START_EVENT). */ - struct { - /** The document encoding. */ - yaml_encoding_t encoding; - } stream_start; - - /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */ - struct { - /** The version directive. */ - yaml_version_directive_t *version_directive; - - /** The list of tag directives. */ - struct { - /** The beginning of the tag directives list. */ - yaml_tag_directive_t *start; - /** The end of the tag directives list. */ - yaml_tag_directive_t *end; - } tag_directives; - - /** Is the document indicator implicit? */ - int implicit; - } document_start; - - /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */ - struct { - /** Is the document end indicator implicit? */ - int implicit; - } document_end; - - /** The alias parameters (for @c YAML_ALIAS_EVENT). */ - struct { - /** The anchor. */ - yaml_char_t *anchor; - } alias; - - /** The scalar parameters (for @c YAML_SCALAR_EVENT). */ - struct { - /** The anchor. */ - yaml_char_t *anchor; - /** The tag. */ - yaml_char_t *tag; - /** The scalar value. */ - yaml_char_t *value; - /** The length of the scalar value. */ - size_t length; - /** Is the tag optional for the plain style? */ - int plain_implicit; - /** Is the tag optional for any non-plain style? */ - int quoted_implicit; - /** The scalar style. */ - yaml_scalar_style_t style; - } scalar; - - /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */ - struct { - /** The anchor. */ - yaml_char_t *anchor; - /** The tag. */ - yaml_char_t *tag; - /** Is the tag optional? */ - int implicit; - /** The sequence style. */ - yaml_sequence_style_t style; - } sequence_start; - - /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */ - struct { - /** The anchor. */ - yaml_char_t *anchor; - /** The tag. */ - yaml_char_t *tag; - /** Is the tag optional? */ - int implicit; - /** The mapping style. */ - yaml_mapping_style_t style; - } mapping_start; - - } data; - - /** The beginning of the event. */ - yaml_mark_t start_mark; - /** The end of the event. */ - yaml_mark_t end_mark; - -} yaml_event_t; - -/** - * Create the STREAM-START event. - * - * @param[out] event An empty event object. - * @param[in] encoding The stream encoding. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_stream_start_event_initialize(yaml_event_t *event, - yaml_encoding_t encoding); - -/** - * Create the STREAM-END event. - * - * @param[out] event An empty event object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_stream_end_event_initialize(yaml_event_t *event); - -/** - * Create the DOCUMENT-START event. - * - * The @a implicit argument is considered as a stylistic parameter and may be - * ignored by the emitter. - * - * @param[out] event An empty event object. - * @param[in] version_directive The %YAML directive value or - * @c NULL. - * @param[in] tag_directives_start The beginning of the %TAG - * directives list. - * @param[in] tag_directives_end The end of the %TAG directives - * list. - * @param[in] implicit If the document start indicator is - * implicit. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_start_event_initialize(yaml_event_t *event, - yaml_version_directive_t *version_directive, - yaml_tag_directive_t *tag_directives_start, - yaml_tag_directive_t *tag_directives_end, - int implicit); - -/** - * Create the DOCUMENT-END event. - * - * The @a implicit argument is considered as a stylistic parameter and may be - * ignored by the emitter. - * - * @param[out] event An empty event object. - * @param[in] implicit If the document end indicator is implicit. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_end_event_initialize(yaml_event_t *event, int implicit); - -/** - * Create an ALIAS event. - * - * @param[out] event An empty event object. - * @param[in] anchor The anchor value. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_alias_event_initialize(yaml_event_t *event, const yaml_char_t *anchor); - -/** - * Create a SCALAR event. - * - * The @a style argument may be ignored by the emitter. - * - * Either the @a tag attribute or one of the @a plain_implicit and - * @a quoted_implicit flags must be set. - * - * @param[out] event An empty event object. - * @param[in] anchor The scalar anchor or @c NULL. - * @param[in] tag The scalar tag or @c NULL. - * @param[in] value The scalar value. - * @param[in] length The length of the scalar value. - * @param[in] plain_implicit If the tag may be omitted for the plain - * style. - * @param[in] quoted_implicit If the tag may be omitted for any - * non-plain style. - * @param[in] style The scalar style. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_scalar_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, - const yaml_char_t *value, int length, - int plain_implicit, int quoted_implicit, - yaml_scalar_style_t style); - -/** - * Create a SEQUENCE-START event. - * - * The @a style argument may be ignored by the emitter. - * - * Either the @a tag attribute or the @a implicit flag must be set. - * - * @param[out] event An empty event object. - * @param[in] anchor The sequence anchor or @c NULL. - * @param[in] tag The sequence tag or @c NULL. - * @param[in] implicit If the tag may be omitted. - * @param[in] style The sequence style. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_sequence_start_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, int implicit, - yaml_sequence_style_t style); - -/** - * Create a SEQUENCE-END event. - * - * @param[out] event An empty event object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_sequence_end_event_initialize(yaml_event_t *event); - -/** - * Create a MAPPING-START event. - * - * The @a style argument may be ignored by the emitter. - * - * Either the @a tag attribute or the @a implicit flag must be set. - * - * @param[out] event An empty event object. - * @param[in] anchor The mapping anchor or @c NULL. - * @param[in] tag The mapping tag or @c NULL. - * @param[in] implicit If the tag may be omitted. - * @param[in] style The mapping style. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_mapping_start_event_initialize(yaml_event_t *event, - const yaml_char_t *anchor, const yaml_char_t *tag, int implicit, - yaml_mapping_style_t style); - -/** - * Create a MAPPING-END event. - * - * @param[out] event An empty event object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_mapping_end_event_initialize(yaml_event_t *event); - -/** - * Free any memory allocated for an event object. - * - * @param[in,out] event An event object. - */ - -YAML_DECLARE(void) -yaml_event_delete(yaml_event_t *event); - -/** @} */ - -/** - * @defgroup nodes Nodes - * @{ - */ - -/** The tag @c !!null with the only possible value: @c null. */ -#define YAML_NULL_TAG "tag:yaml.org,2002:null" -/** The tag @c !!bool with the values: @c true and @c false. */ -#define YAML_BOOL_TAG "tag:yaml.org,2002:bool" -/** The tag @c !!str for string values. */ -#define YAML_STR_TAG "tag:yaml.org,2002:str" -/** The tag @c !!int for integer values. */ -#define YAML_INT_TAG "tag:yaml.org,2002:int" -/** The tag @c !!float for float values. */ -#define YAML_FLOAT_TAG "tag:yaml.org,2002:float" -/** The tag @c !!timestamp for date and time values. */ -#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp" - -/** The tag @c !!seq is used to denote sequences. */ -#define YAML_SEQ_TAG "tag:yaml.org,2002:seq" -/** The tag @c !!map is used to denote mapping. */ -#define YAML_MAP_TAG "tag:yaml.org,2002:map" - -/** The default scalar tag is @c !!str. */ -#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG -/** The default sequence tag is @c !!seq. */ -#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG -/** The default mapping tag is @c !!map. */ -#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG - -/** Node types. */ -typedef enum yaml_node_type_e { - /** An empty node. */ - YAML_NO_NODE, - - /** A scalar node. */ - YAML_SCALAR_NODE, - /** A sequence node. */ - YAML_SEQUENCE_NODE, - /** A mapping node. */ - YAML_MAPPING_NODE -} yaml_node_type_t; - -/** The forward definition of a document node structure. */ -typedef struct yaml_node_s yaml_node_t; - -/** An element of a sequence node. */ -typedef int yaml_node_item_t; - -/** An element of a mapping node. */ -typedef struct yaml_node_pair_s { - /** The key of the element. */ - int key; - /** The value of the element. */ - int value; -} yaml_node_pair_t; - -/** The node structure. */ -struct yaml_node_s { - - /** The node type. */ - yaml_node_type_t type; - - /** The node tag. */ - yaml_char_t *tag; - - /** The node data. */ - union { - - /** The scalar parameters (for @c YAML_SCALAR_NODE). */ - struct { - /** The scalar value. */ - yaml_char_t *value; - /** The length of the scalar value. */ - size_t length; - /** The scalar style. */ - yaml_scalar_style_t style; - } scalar; - - /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */ - struct { - /** The stack of sequence items. */ - struct { - /** The beginning of the stack. */ - yaml_node_item_t *start; - /** The end of the stack. */ - yaml_node_item_t *end; - /** The top of the stack. */ - yaml_node_item_t *top; - } items; - /** The sequence style. */ - yaml_sequence_style_t style; - } sequence; - - /** The mapping parameters (for @c YAML_MAPPING_NODE). */ - struct { - /** The stack of mapping pairs (key, value). */ - struct { - /** The beginning of the stack. */ - yaml_node_pair_t *start; - /** The end of the stack. */ - yaml_node_pair_t *end; - /** The top of the stack. */ - yaml_node_pair_t *top; - } pairs; - /** The mapping style. */ - yaml_mapping_style_t style; - } mapping; - - } data; - - /** The beginning of the node. */ - yaml_mark_t start_mark; - /** The end of the node. */ - yaml_mark_t end_mark; - -}; - -/** The document structure. */ -typedef struct yaml_document_s { - - /** The document nodes. */ - struct { - /** The beginning of the stack. */ - yaml_node_t *start; - /** The end of the stack. */ - yaml_node_t *end; - /** The top of the stack. */ - yaml_node_t *top; - } nodes; - - /** The version directive. */ - yaml_version_directive_t *version_directive; - - /** The list of tag directives. */ - struct { - /** The beginning of the tag directives list. */ - yaml_tag_directive_t *start; - /** The end of the tag directives list. */ - yaml_tag_directive_t *end; - } tag_directives; - - /** Is the document start indicator implicit? */ - int start_implicit; - /** Is the document end indicator implicit? */ - int end_implicit; - - /** The beginning of the document. */ - yaml_mark_t start_mark; - /** The end of the document. */ - yaml_mark_t end_mark; - -} yaml_document_t; - -/** - * Create a YAML document. - * - * @param[out] document An empty document object. - * @param[in] version_directive The %YAML directive value or - * @c NULL. - * @param[in] tag_directives_start The beginning of the %TAG - * directives list. - * @param[in] tag_directives_end The end of the %TAG directives - * list. - * @param[in] start_implicit If the document start indicator is - * implicit. - * @param[in] end_implicit If the document end indicator is - * implicit. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_initialize(yaml_document_t *document, - yaml_version_directive_t *version_directive, - yaml_tag_directive_t *tag_directives_start, - yaml_tag_directive_t *tag_directives_end, - int start_implicit, int end_implicit); - -/** - * Delete a YAML document and all its nodes. - * - * @param[in,out] document A document object. - */ - -YAML_DECLARE(void) -yaml_document_delete(yaml_document_t *document); - -/** - * Get a node of a YAML document. - * - * The pointer returned by this function is valid until any of the functions - * modifying the documents are called. - * - * @param[in] document A document object. - * @param[in] index The node id. - * - * @returns the node objct or @c NULL if @c node_id is out of range. - */ - -YAML_DECLARE(yaml_node_t *) -yaml_document_get_node(yaml_document_t *document, int index); - -/** - * Get the root of a YAML document node. - * - * The root object is the first object added to the document. - * - * The pointer returned by this function is valid until any of the functions - * modifying the documents are called. - * - * An empty document produced by the parser signifies the end of a YAML - * stream. - * - * @param[in] document A document object. - * - * @returns the node object or @c NULL if the document is empty. - */ - -YAML_DECLARE(yaml_node_t *) -yaml_document_get_root_node(yaml_document_t *document); - -/** - * Create a SCALAR node and attach it to the document. - * - * The @a style argument may be ignored by the emitter. - * - * @param[in,out] document A document object. - * @param[in] tag The scalar tag. - * @param[in] value The scalar value. - * @param[in] length The length of the scalar value. - * @param[in] style The scalar style. - * - * @returns the node id or @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_add_scalar(yaml_document_t *document, - const yaml_char_t *tag, const yaml_char_t *value, int length, - yaml_scalar_style_t style); - -/** - * Create a SEQUENCE node and attach it to the document. - * - * The @a style argument may be ignored by the emitter. - * - * @param[in,out] document A document object. - * @param[in] tag The sequence tag. - * @param[in] style The sequence style. - * - * @returns the node id or @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_add_sequence(yaml_document_t *document, - const yaml_char_t *tag, yaml_sequence_style_t style); - -/** - * Create a MAPPING node and attach it to the document. - * - * The @a style argument may be ignored by the emitter. - * - * @param[in,out] document A document object. - * @param[in] tag The sequence tag. - * @param[in] style The sequence style. - * - * @returns the node id or @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_add_mapping(yaml_document_t *document, - const yaml_char_t *tag, yaml_mapping_style_t style); - -/** - * Add an item to a SEQUENCE node. - * - * @param[in,out] document A document object. - * @param[in] sequence The sequence node id. - * @param[in] item The item node id. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_append_sequence_item(yaml_document_t *document, - int sequence, int item); - -/** - * Add a pair of a key and a value to a MAPPING node. - * - * @param[in,out] document A document object. - * @param[in] mapping The mapping node id. - * @param[in] key The key node id. - * @param[in] value The value node id. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_document_append_mapping_pair(yaml_document_t *document, - int mapping, int key, int value); - -/** @} */ - -/** - * @defgroup parser Parser Definitions - * @{ - */ - -/** - * The prototype of a read handler. - * - * The read handler is called when the parser needs to read more bytes from the - * source. The handler should write not more than @a size bytes to the @a - * buffer. The number of written bytes should be set to the @a length variable. - * - * @param[in,out] data A pointer to an application data specified by - * yaml_parser_set_input(). - * @param[out] buffer The buffer to write the data from the source. - * @param[in] size The size of the buffer. - * @param[out] size_read The actual number of bytes read from the source. - * - * @returns On success, the handler should return @c 1. If the handler failed, - * the returned value should be @c 0. On EOF, the handler should set the - * @a size_read to @c 0 and return @c 1. - */ - -typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, - size_t *size_read); - -/** - * This structure holds information about a potential simple key. - */ - -typedef struct yaml_simple_key_s { - /** Is a simple key possible? */ - int possible; - - /** Is a simple key required? */ - int required; - - /** The number of the token. */ - size_t token_number; - - /** The position mark. */ - yaml_mark_t mark; -} yaml_simple_key_t; - -/** - * The states of the parser. - */ -typedef enum yaml_parser_state_e { - /** Expect STREAM-START. */ - YAML_PARSE_STREAM_START_STATE, - /** Expect the beginning of an implicit document. */ - YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, - /** Expect DOCUMENT-START. */ - YAML_PARSE_DOCUMENT_START_STATE, - /** Expect the content of a document. */ - YAML_PARSE_DOCUMENT_CONTENT_STATE, - /** Expect DOCUMENT-END. */ - YAML_PARSE_DOCUMENT_END_STATE, - - /** Expect a block node. */ - YAML_PARSE_BLOCK_NODE_STATE, - /** Expect a block node or indentless sequence. */ - YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, - /** Expect a flow node. */ - YAML_PARSE_FLOW_NODE_STATE, - /** Expect the first entry of a block sequence. */ - YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, - /** Expect an entry of a block sequence. */ - YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, - - /** Expect an entry of an indentless sequence. */ - YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, - /** Expect the first key of a block mapping. */ - YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, - /** Expect a block mapping key. */ - YAML_PARSE_BLOCK_MAPPING_KEY_STATE, - /** Expect a block mapping value. */ - YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, - /** Expect the first entry of a flow sequence. */ - YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, - - /** Expect an entry of a flow sequence. */ - YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, - /** Expect a key of an ordered mapping. */ - YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, - /** Expect a value of an ordered mapping. */ - YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, - /** Expect the and of an ordered mapping entry. */ - YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, - /** Expect the first key of a flow mapping. */ - YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, - /** Expect a key of a flow mapping. */ - - YAML_PARSE_FLOW_MAPPING_KEY_STATE, - /** Expect a value of a flow mapping. */ - YAML_PARSE_FLOW_MAPPING_VALUE_STATE, - /** Expect an empty value of a flow mapping. */ - YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, - /** Expect nothing. */ - YAML_PARSE_END_STATE -} yaml_parser_state_t; - -/** - * This structure holds aliases data. - */ - -typedef struct yaml_alias_data_s { - /** The anchor. */ - yaml_char_t *anchor; - /** The node id. */ - int index; - /** The anchor mark. */ - yaml_mark_t mark; -} yaml_alias_data_t; - -/** - * The parser structure. - * - * All members are internal. Manage the structure using the @c yaml_parser_ - * family of functions. - */ - -typedef struct yaml_parser_s { - - /** - * @name Error handling - * @{ - */ - - /** Error type. */ - yaml_error_type_t error; - /** Error description. */ - const char *problem; - /** The byte about which the problem occurred. */ - size_t problem_offset; - /** The problematic value (@c -1 is none). */ - int problem_value; - /** The problem position. */ - yaml_mark_t problem_mark; - /** The error context. */ - const char *context; - /** The context position. */ - yaml_mark_t context_mark; - - /** - * @} - */ - - /** - * @name Reader stuff - * @{ - */ - - /** Read handler. */ - yaml_read_handler_t *read_handler; - - /** A pointer for passing to the read handler. */ - void *read_handler_data; - - /** Standard (string or file) input data. */ - union { - /** String input data. */ - struct { - /** The string start pointer. */ - const unsigned char *start; - /** The string end pointer. */ - const unsigned char *end; - /** The string current position. */ - const unsigned char *current; - } string; - - /** File input data. */ - FILE *file; - } input; - - /** EOF flag */ - int eof; - - /** The working buffer. */ - struct { - /** The beginning of the buffer. */ - yaml_char_t *start; - /** The end of the buffer. */ - yaml_char_t *end; - /** The current position of the buffer. */ - yaml_char_t *pointer; - /** The last filled position of the buffer. */ - yaml_char_t *last; - } buffer; - - /* The number of unread characters in the buffer. */ - size_t unread; - - /** The raw buffer. */ - struct { - /** The beginning of the buffer. */ - unsigned char *start; - /** The end of the buffer. */ - unsigned char *end; - /** The current position of the buffer. */ - unsigned char *pointer; - /** The last filled position of the buffer. */ - unsigned char *last; - } raw_buffer; - - /** The input encoding. */ - yaml_encoding_t encoding; - - /** The offset of the current position (in bytes). */ - size_t offset; - - /** The mark of the current position. */ - yaml_mark_t mark; - - /** - * @} - */ - - /** - * @name Scanner stuff - * @{ - */ - - /** Have we started to scan the input stream? */ - int stream_start_produced; - - /** Have we reached the end of the input stream? */ - int stream_end_produced; - - /** The number of unclosed '[' and '{' indicators. */ - int flow_level; - - /** The tokens queue. */ - struct { - /** The beginning of the tokens queue. */ - yaml_token_t *start; - /** The end of the tokens queue. */ - yaml_token_t *end; - /** The head of the tokens queue. */ - yaml_token_t *head; - /** The tail of the tokens queue. */ - yaml_token_t *tail; - } tokens; - - /** The number of tokens fetched from the queue. */ - size_t tokens_parsed; - - /** Does the tokens queue contain a token ready for dequeueing. */ - int token_available; - - /** The indentation levels stack. */ - struct { - /** The beginning of the stack. */ - int *start; - /** The end of the stack. */ - int *end; - /** The top of the stack. */ - int *top; - } indents; - - /** The current indentation level. */ - int indent; - - /** May a simple key occur at the current position? */ - int simple_key_allowed; - - /** The stack of simple keys. */ - struct { - /** The beginning of the stack. */ - yaml_simple_key_t *start; - /** The end of the stack. */ - yaml_simple_key_t *end; - /** The top of the stack. */ - yaml_simple_key_t *top; - } simple_keys; - - /** - * @} - */ - - /** - * @name Parser stuff - * @{ - */ - - /** The parser states stack. */ - struct { - /** The beginning of the stack. */ - yaml_parser_state_t *start; - /** The end of the stack. */ - yaml_parser_state_t *end; - /** The top of the stack. */ - yaml_parser_state_t *top; - } states; - - /** The current parser state. */ - yaml_parser_state_t state; - - /** The stack of marks. */ - struct { - /** The beginning of the stack. */ - yaml_mark_t *start; - /** The end of the stack. */ - yaml_mark_t *end; - /** The top of the stack. */ - yaml_mark_t *top; - } marks; - - /** The list of TAG directives. */ - struct { - /** The beginning of the list. */ - yaml_tag_directive_t *start; - /** The end of the list. */ - yaml_tag_directive_t *end; - /** The top of the list. */ - yaml_tag_directive_t *top; - } tag_directives; - - /** - * @} - */ - - /** - * @name Dumper stuff - * @{ - */ - - /** The alias data. */ - struct { - /** The beginning of the list. */ - yaml_alias_data_t *start; - /** The end of the list. */ - yaml_alias_data_t *end; - /** The top of the list. */ - yaml_alias_data_t *top; - } aliases; - - /** The currently parsed document. */ - yaml_document_t *document; - - /** - * @} - */ - -} yaml_parser_t; - -/** - * Initialize a parser. - * - * This function creates a new parser object. An application is responsible - * for destroying the object using the yaml_parser_delete() function. - * - * @param[out] parser An empty parser object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_parser_initialize(yaml_parser_t *parser); - -/** - * Destroy a parser. - * - * @param[in,out] parser A parser object. - */ - -YAML_DECLARE(void) -yaml_parser_delete(yaml_parser_t *parser); - -/** - * Set a string input. - * - * Note that the @a input pointer must be valid while the @a parser object - * exists. The application is responsible for destroying @a input after - * destroying the @a parser. - * - * @param[in,out] parser A parser object. - * @param[in] input A source data. - * @param[in] size The length of the source data in bytes. - */ - -YAML_DECLARE(void) -yaml_parser_set_input_string(yaml_parser_t *parser, - const unsigned char *input, size_t size); - -/** - * Set a file input. - * - * @a file should be a file object open for reading. The application is - * responsible for closing the @a file. - * - * @param[in,out] parser A parser object. - * @param[in] file An open file. - */ - -YAML_DECLARE(void) -yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); - -/** - * Set a generic input handler. - * - * @param[in,out] parser A parser object. - * @param[in] handler A read handler. - * @param[in] data Any application data for passing to the read - * handler. - */ - -YAML_DECLARE(void) -yaml_parser_set_input(yaml_parser_t *parser, - yaml_read_handler_t *handler, void *data); - -/** - * Set the source encoding. - * - * @param[in,out] parser A parser object. - * @param[in] encoding The source encoding. - */ - -YAML_DECLARE(void) -yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); - -/** - * Scan the input stream and produce the next token. - * - * Call the function subsequently to produce a sequence of tokens corresponding - * to the input stream. The initial token has the type - * @c YAML_STREAM_START_TOKEN while the ending token has the type - * @c YAML_STREAM_END_TOKEN. - * - * An application is responsible for freeing any buffers associated with the - * produced token object using the @c yaml_token_delete function. - * - * An application must not alternate the calls of yaml_parser_scan() with the - * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break - * the parser. - * - * @param[in,out] parser A parser object. - * @param[out] token An empty token object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); - -/** - * Parse the input stream and produce the next parsing event. - * - * Call the function subsequently to produce a sequence of events corresponding - * to the input stream. The initial event has the type - * @c YAML_STREAM_START_EVENT while the ending event has the type - * @c YAML_STREAM_END_EVENT. - * - * An application is responsible for freeing any buffers associated with the - * produced event object using the yaml_event_delete() function. - * - * An application must not alternate the calls of yaml_parser_parse() with the - * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the - * parser. - * - * @param[in,out] parser A parser object. - * @param[out] event An empty event object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); - -/** - * Parse the input stream and produce the next YAML document. - * - * Call this function subsequently to produce a sequence of documents - * constituting the input stream. - * - * If the produced document has no root node, it means that the document - * end has been reached. - * - * An application is responsible for freeing any data associated with the - * produced document object using the yaml_document_delete() function. - * - * An application must not alternate the calls of yaml_parser_load() with the - * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break - * the parser. - * - * @param[in,out] parser A parser object. - * @param[out] document An empty document object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); - -/** @} */ - -/** - * @defgroup emitter Emitter Definitions - * @{ - */ - -/** - * The prototype of a write handler. - * - * The write handler is called when the emitter needs to flush the accumulated - * characters to the output. The handler should write @a size bytes of the - * @a buffer to the output. - * - * @param[in,out] data A pointer to an application data specified by - * yaml_emitter_set_output(). - * @param[in] buffer The buffer with bytes to be written. - * @param[in] size The size of the buffer. - * - * @returns On success, the handler should return @c 1. If the handler failed, - * the returned value should be @c 0. - */ - -typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size); - -/** The emitter states. */ -typedef enum yaml_emitter_state_e { - /** Expect STREAM-START. */ - YAML_EMIT_STREAM_START_STATE, - /** Expect the first DOCUMENT-START or STREAM-END. */ - YAML_EMIT_FIRST_DOCUMENT_START_STATE, - /** Expect DOCUMENT-START or STREAM-END. */ - YAML_EMIT_DOCUMENT_START_STATE, - /** Expect the content of a document. */ - YAML_EMIT_DOCUMENT_CONTENT_STATE, - /** Expect DOCUMENT-END. */ - YAML_EMIT_DOCUMENT_END_STATE, - - /** Expect the first item of a flow sequence. */ - YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, - /** Expect an item of a flow sequence. */ - YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, - /** Expect the first key of a flow mapping. */ - YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, - /** Expect a key of a flow mapping. */ - YAML_EMIT_FLOW_MAPPING_KEY_STATE, - /** Expect a value for a simple key of a flow mapping. */ - YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, - - /** Expect a value of a flow mapping. */ - YAML_EMIT_FLOW_MAPPING_VALUE_STATE, - /** Expect the first item of a block sequence. */ - YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, - /** Expect an item of a block sequence. */ - YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, - /** Expect the first key of a block mapping. */ - YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, - /** Expect the key of a block mapping. */ - YAML_EMIT_BLOCK_MAPPING_KEY_STATE, - - /** Expect a value for a simple key of a block mapping. */ - YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, - /** Expect a value of a block mapping. */ - YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, - /** Expect nothing. */ - YAML_EMIT_END_STATE -} yaml_emitter_state_t; - - -/* This is needed for C++ */ - -typedef struct yaml_anchors_s { - /** The number of references. */ - int references; - /** The anchor id. */ - int anchor; - /** If the node has been emitted? */ - int serialized; -} yaml_anchors_t; - -/** - * The emitter structure. - * - * All members are internal. Manage the structure using the @c yaml_emitter_ - * family of functions. - */ - -typedef struct yaml_emitter_s { - - /** - * @name Error handling - * @{ - */ - - /** Error type. */ - yaml_error_type_t error; - /** Error description. */ - const char *problem; - - /** - * @} - */ - - /** - * @name Writer stuff - * @{ - */ - - /** Write handler. */ - yaml_write_handler_t *write_handler; - - /** A pointer for passing to the write handler. */ - void *write_handler_data; - - /** Standard (string or file) output data. */ - union { - /** String output data. */ - struct { - /** The buffer pointer. */ - unsigned char *buffer; - /** The buffer size. */ - size_t size; - /** The number of written bytes. */ - size_t *size_written; - } string; - - /** File output data. */ - FILE *file; - } output; - - /** The working buffer. */ - struct { - /** The beginning of the buffer. */ - yaml_char_t *start; - /** The end of the buffer. */ - yaml_char_t *end; - /** The current position of the buffer. */ - yaml_char_t *pointer; - /** The last filled position of the buffer. */ - yaml_char_t *last; - } buffer; - - /** The raw buffer. */ - struct { - /** The beginning of the buffer. */ - unsigned char *start; - /** The end of the buffer. */ - unsigned char *end; - /** The current position of the buffer. */ - unsigned char *pointer; - /** The last filled position of the buffer. */ - unsigned char *last; - } raw_buffer; - - /** The stream encoding. */ - yaml_encoding_t encoding; - - /** - * @} - */ - - /** - * @name Emitter stuff - * @{ - */ - - /** If the output is in the canonical style? */ - int canonical; - /** The number of indentation spaces. */ - int best_indent; - /** The preferred width of the output lines. */ - int best_width; - /** Allow unescaped non-ASCII characters? */ - int unicode; - /** The preferred line break. */ - yaml_break_t line_break; - - /** The stack of states. */ - struct { - /** The beginning of the stack. */ - yaml_emitter_state_t *start; - /** The end of the stack. */ - yaml_emitter_state_t *end; - /** The top of the stack. */ - yaml_emitter_state_t *top; - } states; - - /** The current emitter state. */ - yaml_emitter_state_t state; - - /** The event queue. */ - struct { - /** The beginning of the event queue. */ - yaml_event_t *start; - /** The end of the event queue. */ - yaml_event_t *end; - /** The head of the event queue. */ - yaml_event_t *head; - /** The tail of the event queue. */ - yaml_event_t *tail; - } events; - - /** The stack of indentation levels. */ - struct { - /** The beginning of the stack. */ - int *start; - /** The end of the stack. */ - int *end; - /** The top of the stack. */ - int *top; - } indents; - - /** The list of tag directives. */ - struct { - /** The beginning of the list. */ - yaml_tag_directive_t *start; - /** The end of the list. */ - yaml_tag_directive_t *end; - /** The top of the list. */ - yaml_tag_directive_t *top; - } tag_directives; - - /** The current indentation level. */ - int indent; - - /** The current flow level. */ - int flow_level; - - /** Is it the document root context? */ - int root_context; - /** Is it a sequence context? */ - int sequence_context; - /** Is it a mapping context? */ - int mapping_context; - /** Is it a simple mapping key context? */ - int simple_key_context; - - /** The current line. */ - int line; - /** The current column. */ - int column; - /** If the last character was a whitespace? */ - int whitespace; - /** If the last character was an indentation character (' ', '-', '?', ':')? */ - int indention; - /** If an explicit document end is required? */ - int open_ended; - - /** Anchor analysis. */ - struct { - /** The anchor value. */ - yaml_char_t *anchor; - /** The anchor length. */ - size_t anchor_length; - /** Is it an alias? */ - int alias; - } anchor_data; - - /** Tag analysis. */ - struct { - /** The tag handle. */ - yaml_char_t *handle; - /** The tag handle length. */ - size_t handle_length; - /** The tag suffix. */ - yaml_char_t *suffix; - /** The tag suffix length. */ - size_t suffix_length; - } tag_data; - - /** Scalar analysis. */ - struct { - /** The scalar value. */ - yaml_char_t *value; - /** The scalar length. */ - size_t length; - /** Does the scalar contain line breaks? */ - int multiline; - /** Can the scalar be expressed in the flow plain style? */ - int flow_plain_allowed; - /** Can the scalar be expressed in the block plain style? */ - int block_plain_allowed; - /** Can the scalar be expressed in the single quoted style? */ - int single_quoted_allowed; - /** Can the scalar be expressed in the literal or folded styles? */ - int block_allowed; - /** The output style. */ - yaml_scalar_style_t style; - } scalar_data; - - /** - * @} - */ - - /** - * @name Dumper stuff - * @{ - */ - - /** If the stream was already opened? */ - int opened; - /** If the stream was already closed? */ - int closed; - - /** The information associated with the document nodes. */ - yaml_anchors_t *anchors; - - /** The last assigned anchor id. */ - int last_anchor_id; - - /** The currently emitted document. */ - yaml_document_t *document; - - /** - * @} - */ - -} yaml_emitter_t; - -/** - * Initialize an emitter. - * - * This function creates a new emitter object. An application is responsible - * for destroying the object using the yaml_emitter_delete() function. - * - * @param[out] emitter An empty parser object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_initialize(yaml_emitter_t *emitter); - -/** - * Destroy an emitter. - * - * @param[in,out] emitter An emitter object. - */ - -YAML_DECLARE(void) -yaml_emitter_delete(yaml_emitter_t *emitter); - -/** - * Set a string output. - * - * The emitter will write the output characters to the @a output buffer of the - * size @a size. The emitter will set @a size_written to the number of written - * bytes. If the buffer is smaller than required, the emitter produces the - * YAML_WRITE_ERROR error. - * - * @param[in,out] emitter An emitter object. - * @param[in] output An output buffer. - * @param[in] size The buffer size. - * @param[in] size_written The pointer to save the number of written - * bytes. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output_string(yaml_emitter_t *emitter, - unsigned char *output, size_t size, size_t *size_written); - -/** - * Set a file output. - * - * @a file should be a file object open for writing. The application is - * responsible for closing the @a file. - * - * @param[in,out] emitter An emitter object. - * @param[in] file An open file. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file); - -/** - * Set a generic output handler. - * - * @param[in,out] emitter An emitter object. - * @param[in] handler A write handler. - * @param[in] data Any application data for passing to the write - * handler. - */ - -YAML_DECLARE(void) -yaml_emitter_set_output(yaml_emitter_t *emitter, - yaml_write_handler_t *handler, void *data); - -/** - * Set the output encoding. - * - * @param[in,out] emitter An emitter object. - * @param[in] encoding The output encoding. - */ - -YAML_DECLARE(void) -yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding); - -/** - * Set if the output should be in the "canonical" format as in the YAML - * specification. - * - * @param[in,out] emitter An emitter object. - * @param[in] canonical If the output is canonical. - */ - -YAML_DECLARE(void) -yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical); - -/** - * Set the indentation increment. - * - * @param[in,out] emitter An emitter object. - * @param[in] indent The indentation increment (1 < . < 10). - */ - -YAML_DECLARE(void) -yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent); - -/** - * Set the preferred line width. @c -1 means unlimited. - * - * @param[in,out] emitter An emitter object. - * @param[in] width The preferred line width. - */ - -YAML_DECLARE(void) -yaml_emitter_set_width(yaml_emitter_t *emitter, int width); - -/** - * Set if unescaped non-ASCII characters are allowed. - * - * @param[in,out] emitter An emitter object. - * @param[in] unicode If unescaped Unicode characters are allowed. - */ - -YAML_DECLARE(void) -yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode); - -/** - * Set the preferred line break. - * - * @param[in,out] emitter An emitter object. - * @param[in] line_break The preferred line break. - */ - -YAML_DECLARE(void) -yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); - -/** - * Emit an event. - * - * The event object may be generated using the yaml_parser_parse() function. - * The emitter takes the responsibility for the event object and destroys its - * content after it is emitted. The event object is destroyed even if the - * function fails. - * - * @param[in,out] emitter An emitter object. - * @param[in,out] event An event object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); - -/** - * Start a YAML stream. - * - * This function should be used before yaml_emitter_dump() is called. - * - * @param[in,out] emitter An emitter object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_open(yaml_emitter_t *emitter); - -/** - * Finish a YAML stream. - * - * This function should be used after yaml_emitter_dump() is called. - * - * @param[in,out] emitter An emitter object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_close(yaml_emitter_t *emitter); - -/** - * Emit a YAML document. - * - * The document object may be generated using the yaml_parser_load() function - * or the yaml_document_initialize() function. The emitter takes the - * responsibility for the document object and destroys its content after - * it is emitted. The document object is destroyed even if the function fails. - * - * @param[in,out] emitter An emitter object. - * @param[in,out] document A document object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); - -/** - * Flush the accumulated characters to the output. - * - * @param[in,out] emitter An emitter object. - * - * @returns @c 1 if the function succeeded, @c 0 on error. - */ - -YAML_DECLARE(int) -yaml_emitter_flush(yaml_emitter_t *emitter); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* #ifndef YAML_H */ - diff --git a/ext/psych/yaml/yaml_private.h b/ext/psych/yaml/yaml_private.h deleted file mode 100644 index 266a6bd3a7..0000000000 --- a/ext/psych/yaml/yaml_private.h +++ /dev/null @@ -1,688 +0,0 @@ -#ifdef RUBY_EXTCONF_H -#include RUBY_EXTCONF_H -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <yaml.h> - -#include <assert.h> -#include <limits.h> -#include <stddef.h> - -/* - * Memory management. - */ - -YAML_DECLARE(void *) -yaml_malloc(size_t size); - -YAML_DECLARE(void *) -yaml_realloc(void *ptr, size_t size); - -YAML_DECLARE(void) -yaml_free(void *ptr); - -YAML_DECLARE(yaml_char_t *) -yaml_strdup(const yaml_char_t *); - -/* - * Reader: Ensure that the buffer contains at least `length` characters. - */ - -YAML_DECLARE(int) -yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); - -/* - * Scanner: Ensure that the token stack contains at least one token ready. - */ - -YAML_DECLARE(int) -yaml_parser_fetch_more_tokens(yaml_parser_t *parser); - -/* - * The size of the input raw buffer. - */ - -#define INPUT_RAW_BUFFER_SIZE 16384 - -/* - * The size of the input buffer. - * - * It should be possible to decode the whole raw buffer. - */ - -#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3) - -/* - * The size of the output buffer. - */ - -#define OUTPUT_BUFFER_SIZE 16384 - -/* - * The size of the output raw buffer. - * - * It should be possible to encode the whole output buffer. - */ - -#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2) - -/* - * The maximum size of a YAML input file. - * This used to be PTRDIFF_MAX, but that's not entirely portable - * because stdint.h isn't available on all platforms. - * It is not entirely clear why this isn't the maximum value - * that can fit into the parser->offset field. - */ - -#define MAX_FILE_SIZE (~(size_t)0 / 2) - - -/* - * The size of other stacks and queues. - */ - -#define INITIAL_STACK_SIZE 16 -#define INITIAL_QUEUE_SIZE 16 -#define INITIAL_STRING_SIZE 16 - -/* - * Buffer management. - */ - -#define BUFFER_INIT(context,buffer,size) \ - (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ? \ - ((buffer).last = (buffer).pointer = (buffer).start, \ - (buffer).end = (buffer).start+(size), \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define BUFFER_DEL(context,buffer) \ - (yaml_free((buffer).start), \ - (buffer).start = (buffer).pointer = (buffer).end = 0) - -/* - * String management. - */ - -typedef struct { - yaml_char_t *start; - yaml_char_t *end; - yaml_char_t *pointer; -} yaml_string_t; - -YAML_DECLARE(int) -yaml_string_extend(yaml_char_t **start, - yaml_char_t **pointer, yaml_char_t **end); - -YAML_DECLARE(int) -yaml_string_join( - yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, - yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end); - -#define NULL_STRING { NULL, NULL, NULL } - -#define STRING(string,length) { (string), (string)+(length), (string) } - -#define STRING_ASSIGN(value,string,length) \ - ((value).start = (string), \ - (value).end = (string)+(length), \ - (value).pointer = (string)) - -#define STRING_INIT(context,string,size) \ - (((string).start = YAML_MALLOC(size)) ? \ - ((string).pointer = (string).start, \ - (string).end = (string).start+(size), \ - memset((string).start, 0, (size)), \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define STRING_DEL(context,string) \ - (yaml_free((string).start), \ - (string).start = (string).pointer = (string).end = 0) - -#define STRING_EXTEND(context,string) \ - ((((string).pointer+5 < (string).end) \ - || yaml_string_extend(&(string).start, \ - &(string).pointer, &(string).end)) ? \ - 1 : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define CLEAR(context,string) \ - ((string).pointer = (string).start, \ - memset((string).start, 0, (string).end-(string).start)) - -#define JOIN(context,string_a,string_b) \ - ((yaml_string_join(&(string_a).start, &(string_a).pointer, \ - &(string_a).end, &(string_b).start, \ - &(string_b).pointer, &(string_b).end)) ? \ - ((string_b).pointer = (string_b).start, \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -/* - * String check operations. - */ - -/* - * Check the octet at the specified position. - */ - -#define CHECK_AT(string,octet,offset) \ - ((string).pointer[offset] == (yaml_char_t)(octet)) - -/* - * Check the current octet in the buffer. - */ - -#define CHECK(string,octet) (CHECK_AT((string),(octet),0)) - -/* - * Check if the character at the specified position is an alphabetical - * character, a digit, '_', or '-'. - */ - -#define IS_ALPHA_AT(string,offset) \ - (((string).pointer[offset] >= (yaml_char_t) '0' && \ - (string).pointer[offset] <= (yaml_char_t) '9') || \ - ((string).pointer[offset] >= (yaml_char_t) 'A' && \ - (string).pointer[offset] <= (yaml_char_t) 'Z') || \ - ((string).pointer[offset] >= (yaml_char_t) 'a' && \ - (string).pointer[offset] <= (yaml_char_t) 'z') || \ - (string).pointer[offset] == '_' || \ - (string).pointer[offset] == '-') - -#define IS_ALPHA(string) IS_ALPHA_AT((string),0) - -/* - * Check if the character at the specified position is a digit. - */ - -#define IS_DIGIT_AT(string,offset) \ - (((string).pointer[offset] >= (yaml_char_t) '0' && \ - (string).pointer[offset] <= (yaml_char_t) '9')) - -#define IS_DIGIT(string) IS_DIGIT_AT((string),0) - -/* - * Get the value of a digit. - */ - -#define AS_DIGIT_AT(string,offset) \ - ((string).pointer[offset] - (yaml_char_t) '0') - -#define AS_DIGIT(string) AS_DIGIT_AT((string),0) - -/* - * Check if the character at the specified position is a hex-digit. - */ - -#define IS_HEX_AT(string,offset) \ - (((string).pointer[offset] >= (yaml_char_t) '0' && \ - (string).pointer[offset] <= (yaml_char_t) '9') || \ - ((string).pointer[offset] >= (yaml_char_t) 'A' && \ - (string).pointer[offset] <= (yaml_char_t) 'F') || \ - ((string).pointer[offset] >= (yaml_char_t) 'a' && \ - (string).pointer[offset] <= (yaml_char_t) 'f')) - -#define IS_HEX(string) IS_HEX_AT((string),0) - -/* - * Get the value of a hex-digit. - */ - -#define AS_HEX_AT(string,offset) \ - (((string).pointer[offset] >= (yaml_char_t) 'A' && \ - (string).pointer[offset] <= (yaml_char_t) 'F') ? \ - ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \ - ((string).pointer[offset] >= (yaml_char_t) 'a' && \ - (string).pointer[offset] <= (yaml_char_t) 'f') ? \ - ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \ - ((string).pointer[offset] - (yaml_char_t) '0')) - -#define AS_HEX(string) AS_HEX_AT((string),0) - -/* - * Check if the character is ASCII. - */ - -#define IS_ASCII_AT(string,offset) \ - ((string).pointer[offset] <= (yaml_char_t) '\x7F') - -#define IS_ASCII(string) IS_ASCII_AT((string),0) - -/* - * Check if the character can be printed unescaped. - */ - -#define IS_PRINTABLE_AT(string,offset) \ - (((string).pointer[offset] == 0x0A) /* . == #x0A */ \ - || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \ - && (string).pointer[offset] <= 0x7E) \ - || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \ - && (string).pointer[offset+1] >= 0xA0) \ - || ((string).pointer[offset] > 0xC2 \ - && (string).pointer[offset] < 0xED) \ - || ((string).pointer[offset] == 0xED \ - && (string).pointer[offset+1] < 0xA0) \ - || ((string).pointer[offset] == 0xEE) \ - || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \ - && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \ - && (string).pointer[offset+2] == 0xBF) \ - && !((string).pointer[offset+1] == 0xBF \ - && ((string).pointer[offset+2] == 0xBE \ - || (string).pointer[offset+2] == 0xBF)))) - -#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0) - -/* - * Check if the character at the specified position is NUL. - */ - -#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset)) - -#define IS_Z(string) IS_Z_AT((string),0) - -/* - * Check if the character at the specified position is BOM. - */ - -#define IS_BOM_AT(string,offset) \ - (CHECK_AT((string),'\xEF',(offset)) \ - && CHECK_AT((string),'\xBB',(offset)+1) \ - && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */ - -#define IS_BOM(string) IS_BOM_AT(string,0) - -/* - * Check if the character at the specified position is space. - */ - -#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset)) - -#define IS_SPACE(string) IS_SPACE_AT((string),0) - -/* - * Check if the character at the specified position is tab. - */ - -#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset)) - -#define IS_TAB(string) IS_TAB_AT((string),0) - -/* - * Check if the character at the specified position is blank (space or tab). - */ - -#define IS_BLANK_AT(string,offset) \ - (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset))) - -#define IS_BLANK(string) IS_BLANK_AT((string),0) - -/* - * Check if the character at the specified position is a line break. - */ - -#define IS_BREAK_AT(string,offset) \ - (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \ - || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \ - || (CHECK_AT((string),'\xC2',(offset)) \ - && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \ - || (CHECK_AT((string),'\xE2',(offset)) \ - && CHECK_AT((string),'\x80',(offset)+1) \ - && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \ - || (CHECK_AT((string),'\xE2',(offset)) \ - && CHECK_AT((string),'\x80',(offset)+1) \ - && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */ - -#define IS_BREAK(string) IS_BREAK_AT((string),0) - -#define IS_CRLF_AT(string,offset) \ - (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1)) - -#define IS_CRLF(string) IS_CRLF_AT((string),0) - -/* - * Check if the character is a line break or NUL. - */ - -#define IS_BREAKZ_AT(string,offset) \ - (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset))) - -#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0) - -/* - * Check if the character is a line break, space, or NUL. - */ - -#define IS_SPACEZ_AT(string,offset) \ - (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) - -#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0) - -/* - * Check if the character is a line break, space, tab, or NUL. - */ - -#define IS_BLANKZ_AT(string,offset) \ - (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) - -#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0) - -/* - * Determine the width of the character. - */ - -#define WIDTH_AT(string,offset) \ - (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \ - ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \ - ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \ - ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0) - -#define WIDTH(string) WIDTH_AT((string),0) - -/* - * Move the string pointer to the next character. - */ - -#define MOVE(string) ((string).pointer += WIDTH((string))) - -/* - * Copy a character and move the pointers of both strings. - */ - -#define COPY(string_a,string_b) \ - ((*(string_b).pointer & 0x80) == 0x00 ? \ - (*((string_a).pointer++) = *((string_b).pointer++)) : \ - (*(string_b).pointer & 0xE0) == 0xC0 ? \ - (*((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++)) : \ - (*(string_b).pointer & 0xF0) == 0xE0 ? \ - (*((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++)) : \ - (*(string_b).pointer & 0xF8) == 0xF0 ? \ - (*((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++), \ - *((string_a).pointer++) = *((string_b).pointer++)) : 0) - -/* - * Stack and queue management. - */ - -YAML_DECLARE(int) -yaml_stack_extend(void **start, void **top, void **end); - -YAML_DECLARE(int) -yaml_queue_extend(void **start, void **head, void **tail, void **end); - -#define STACK_INIT(context,stack,type) \ - (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \ - ((stack).top = (stack).start, \ - (stack).end = (stack).start+INITIAL_STACK_SIZE, \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define STACK_DEL(context,stack) \ - (yaml_free((stack).start), \ - (stack).start = (stack).top = (stack).end = 0) - -#define STACK_EMPTY(context,stack) \ - ((stack).start == (stack).top) - -#define STACK_LIMIT(context,stack,size) \ - ((stack).top - (stack).start < (size) ? \ - 1 : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define PUSH(context,stack,value) \ - (((stack).top != (stack).end \ - || yaml_stack_extend((void **)&(stack).start, \ - (void **)&(stack).top, (void **)&(stack).end)) ? \ - (*((stack).top++) = value, \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define POP(context,stack) \ - (*(--(stack).top)) - -#define QUEUE_INIT(context,queue,size,type) \ - (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ? \ - ((queue).head = (queue).tail = (queue).start, \ - (queue).end = (queue).start+(size), \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define QUEUE_DEL(context,queue) \ - (yaml_free((queue).start), \ - (queue).start = (queue).head = (queue).tail = (queue).end = 0) - -#define QUEUE_EMPTY(context,queue) \ - ((queue).head == (queue).tail) - -#define ENQUEUE(context,queue,value) \ - (((queue).tail != (queue).end \ - || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ - (void **)&(queue).tail, (void **)&(queue).end)) ? \ - (*((queue).tail++) = value, \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -#define DEQUEUE(context,queue) \ - (*((queue).head++)) - -#define QUEUE_INSERT(context,queue,index,value) \ - (((queue).tail != (queue).end \ - || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ - (void **)&(queue).tail, (void **)&(queue).end)) ? \ - (memmove((queue).head+(index)+1,(queue).head+(index), \ - ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \ - *((queue).head+(index)) = value, \ - (queue).tail++, \ - 1) : \ - ((context)->error = YAML_MEMORY_ERROR, \ - 0)) - -/* - * Token initializers. - */ - -#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \ - (memset(&(token), 0, sizeof(yaml_token_t)), \ - (token).type = (token_type), \ - (token).start_mark = (token_start_mark), \ - (token).end_mark = (token_end_mark)) - -#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \ - (token).data.stream_start.encoding = (token_encoding)) - -#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark))) - -#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \ - (token).data.alias.value = (token_value)) - -#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \ - (token).data.anchor.value = (token_value)) - -#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \ - (token).data.tag.handle = (token_handle), \ - (token).data.tag.suffix = (token_suffix)) - -#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \ - (token).data.scalar.value = (token_value), \ - (token).data.scalar.length = (token_length), \ - (token).data.scalar.style = (token_style)) - -#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ - (token).data.version_directive.major = (token_major), \ - (token).data.version_directive.minor = (token_minor)) - -#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \ - (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ - (token).data.tag_directive.handle = (token_handle), \ - (token).data.tag_directive.prefix = (token_prefix)) - -/* - * Event initializers. - */ - -#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \ - (memset(&(event), 0, sizeof(yaml_event_t)), \ - (event).type = (event_type), \ - (event).start_mark = (event_start_mark), \ - (event).end_mark = (event_end_mark)) - -#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \ - (event).data.stream_start.encoding = (event_encoding)) - -#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark))) - -#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \ - event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \ - (event).data.document_start.version_directive = (event_version_directive), \ - (event).data.document_start.tag_directives.start = (event_tag_directives_start), \ - (event).data.document_start.tag_directives.end = (event_tag_directives_end), \ - (event).data.document_start.implicit = (event_implicit)) - -#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \ - (event).data.document_end.implicit = (event_implicit)) - -#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \ - (event).data.alias.anchor = (event_anchor)) - -#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \ - event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \ - (event).data.scalar.anchor = (event_anchor), \ - (event).data.scalar.tag = (event_tag), \ - (event).data.scalar.value = (event_value), \ - (event).data.scalar.length = (event_length), \ - (event).data.scalar.plain_implicit = (event_plain_implicit), \ - (event).data.scalar.quoted_implicit = (event_quoted_implicit), \ - (event).data.scalar.style = (event_style)) - -#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \ - event_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \ - (event).data.sequence_start.anchor = (event_anchor), \ - (event).data.sequence_start.tag = (event_tag), \ - (event).data.sequence_start.implicit = (event_implicit), \ - (event).data.sequence_start.style = (event_style)) - -#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark))) - -#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \ - event_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \ - (event).data.mapping_start.anchor = (event_anchor), \ - (event).data.mapping_start.tag = (event_tag), \ - (event).data.mapping_start.implicit = (event_implicit), \ - (event).data.mapping_start.style = (event_style)) - -#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark))) - -/* - * Document initializer. - */ - -#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \ - document_version_directive,document_tag_directives_start, \ - document_tag_directives_end,document_start_implicit, \ - document_end_implicit,document_start_mark,document_end_mark) \ - (memset(&(document), 0, sizeof(yaml_document_t)), \ - (document).nodes.start = (document_nodes_start), \ - (document).nodes.end = (document_nodes_end), \ - (document).nodes.top = (document_nodes_start), \ - (document).version_directive = (document_version_directive), \ - (document).tag_directives.start = (document_tag_directives_start), \ - (document).tag_directives.end = (document_tag_directives_end), \ - (document).start_implicit = (document_start_implicit), \ - (document).end_implicit = (document_end_implicit), \ - (document).start_mark = (document_start_mark), \ - (document).end_mark = (document_end_mark)) - -/* - * Node initializers. - */ - -#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \ - (memset(&(node), 0, sizeof(yaml_node_t)), \ - (node).type = (node_type), \ - (node).tag = (node_tag), \ - (node).start_mark = (node_start_mark), \ - (node).end_mark = (node_end_mark)) - -#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \ - node_style,start_mark,end_mark) \ - (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \ - (node).data.scalar.value = (node_value), \ - (node).data.scalar.length = (node_length), \ - (node).data.scalar.style = (node_style)) - -#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \ - node_style,start_mark,end_mark) \ - (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \ - (node).data.sequence.items.start = (node_items_start), \ - (node).data.sequence.items.end = (node_items_end), \ - (node).data.sequence.items.top = (node_items_start), \ - (node).data.sequence.style = (node_style)) - -#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \ - node_style,start_mark,end_mark) \ - (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \ - (node).data.mapping.pairs.start = (node_pairs_start), \ - (node).data.mapping.pairs.end = (node_pairs_end), \ - (node).data.mapping.pairs.top = (node_pairs_start), \ - (node).data.mapping.style = (node_style)) - -/* Strict C compiler warning helpers */ - -#if defined(__clang__) || defined(__GNUC__) -# define HASATTRIBUTE_UNUSED -#endif -#ifdef HASATTRIBUTE_UNUSED -# define __attribute__unused__ __attribute__((__unused__)) -#else -# define __attribute__unused__ -#endif - -/* Shim arguments are arguments that must be included in your function, - * but serve no purpose inside. Silence compiler warnings. */ -#define SHIM(a) /*@unused@*/ a __attribute__unused__ - -/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */ -#ifdef __clang__ -# define UNUSED_PARAM(a) (void)(a); -#else -# define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/; -#endif - -#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type)) -#define YAML_MALLOC(size) (yaml_char_t *)yaml_malloc(size) diff --git a/ext/pty/depend b/ext/pty/depend index 984314c870..8fa018d084 100644 --- a/ext/pty/depend +++ b/ext/pty/depend @@ -1,7 +1,6 @@ # AUTOGENERATED DEPENDENCIES START pty.o: $(RUBY_EXTCONF_H) pty.o: $(arch_hdrdir)/ruby/config.h -pty.o: $(hdrdir)/ruby.h pty.o: $(hdrdir)/ruby/assert.h pty.o: $(hdrdir)/ruby/backward.h pty.o: $(hdrdir)/ruby/backward/2/assume.h @@ -16,6 +15,7 @@ pty.o: $(hdrdir)/ruby/backward/2/stdarg.h pty.o: $(hdrdir)/ruby/defines.h pty.o: $(hdrdir)/ruby/encoding.h pty.o: $(hdrdir)/ruby/intern.h +pty.o: $(hdrdir)/ruby/internal/abi.h pty.o: $(hdrdir)/ruby/internal/anyargs.h pty.o: $(hdrdir)/ruby/internal/arithmetic.h pty.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ pty.o: $(hdrdir)/ruby/internal/attr/noexcept.h pty.o: $(hdrdir)/ruby/internal/attr/noinline.h pty.o: $(hdrdir)/ruby/internal/attr/nonnull.h pty.o: $(hdrdir)/ruby/internal/attr/noreturn.h +pty.o: $(hdrdir)/ruby/internal/attr/packed_struct.h pty.o: $(hdrdir)/ruby/internal/attr/pure.h pty.o: $(hdrdir)/ruby/internal/attr/restrict.h pty.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ pty.o: $(hdrdir)/ruby/internal/intern/enumerator.h pty.o: $(hdrdir)/ruby/internal/intern/error.h pty.o: $(hdrdir)/ruby/internal/intern/eval.h pty.o: $(hdrdir)/ruby/internal/intern/file.h -pty.o: $(hdrdir)/ruby/internal/intern/gc.h pty.o: $(hdrdir)/ruby/internal/intern/hash.h pty.o: $(hdrdir)/ruby/internal/intern/io.h pty.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ pty.o: $(hdrdir)/ruby/internal/intern/re.h pty.o: $(hdrdir)/ruby/internal/intern/ruby.h pty.o: $(hdrdir)/ruby/internal/intern/select.h pty.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +pty.o: $(hdrdir)/ruby/internal/intern/set.h pty.o: $(hdrdir)/ruby/internal/intern/signal.h pty.o: $(hdrdir)/ruby/internal/intern/sprintf.h pty.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ pty.o: $(hdrdir)/ruby/internal/memory.h pty.o: $(hdrdir)/ruby/internal/method.h pty.o: $(hdrdir)/ruby/internal/module.h pty.o: $(hdrdir)/ruby/internal/newobj.h -pty.o: $(hdrdir)/ruby/internal/rgengc.h pty.o: $(hdrdir)/ruby/internal/scan_args.h pty.o: $(hdrdir)/ruby/internal/special_consts.h pty.o: $(hdrdir)/ruby/internal/static_assert.h pty.o: $(hdrdir)/ruby/internal/stdalign.h pty.o: $(hdrdir)/ruby/internal/stdbool.h +pty.o: $(hdrdir)/ruby/internal/stdckdint.h pty.o: $(hdrdir)/ruby/internal/symbol.h pty.o: $(hdrdir)/ruby/internal/value.h pty.o: $(hdrdir)/ruby/internal/value_type.h @@ -172,6 +173,7 @@ pty.o: $(hdrdir)/ruby/ruby.h pty.o: $(hdrdir)/ruby/st.h pty.o: $(hdrdir)/ruby/subst.h pty.o: $(hdrdir)/ruby/util.h +pty.o: $(top_srcdir)/id_table.h pty.o: $(top_srcdir)/internal.h pty.o: $(top_srcdir)/internal/array.h pty.o: $(top_srcdir)/internal/compilers.h @@ -181,5 +183,6 @@ pty.o: $(top_srcdir)/internal/process.h pty.o: $(top_srcdir)/internal/signal.h pty.o: $(top_srcdir)/internal/static_assert.h pty.o: $(top_srcdir)/internal/warnings.h +pty.o: $(top_srcdir)/shape.h pty.o: pty.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb index 038bdf4d2c..da3655cf4d 100644 --- a/ext/pty/extconf.rb +++ b/ext/pty/extconf.rb @@ -7,14 +7,19 @@ if /mswin|mingw|bccwin/ !~ RUBY_PLATFORM have_header("sys/stropts.h") have_func("setresuid") have_header("libutil.h") - have_header("util.h") # OpenBSD openpty have_header("pty.h") have_header("pwd.h") - util = have_library("util", "openpty") - if have_func("posix_openpt") or + if /openbsd/ =~ RUBY_PLATFORM + have_header("util.h") # OpenBSD openpty + util = have_library("util", "openpty") + end + openpt = have_func("posix_openpt") + if openpt + have_func("ptsname_r") or have_func("ptsname") + end + if openpt or (util or have_func("openpty")) or have_func("_getpty") or - have_func("ptsname") or have_func("ioctl") create_makefile('pty') end diff --git a/ext/pty/lib/expect.rb b/ext/pty/lib/expect.rb index 5dbfa09ae9..22cbf54115 100644 --- a/ext/pty/lib/expect.rb +++ b/ext/pty/lib/expect.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true $expect_verbose = false -# Expect library adds the IO instance method #expect, which does similar act to -# tcl's expect extension. -# -# In order to use this method, you must require expect: -# -# require 'expect' -# -# Please see #expect for usage. class IO # call-seq: # IO#expect(pattern,timeout=9999999) -> Array # IO#expect(pattern,timeout=9999999) { |result| ... } -> nil # + # The +expect+ library adds instance method IO#expect, + # which is similar to the + # {TCL expect extension}[https://www.tcl.tk/man/expect5.31/expect.1.html]. + # + # To use this method, you must require +expect+: + # + # require 'expect' + # # Reads from the IO until the given +pattern+ matches or the +timeout+ is over. # # It returns an array with the read buffer, followed by the matches. diff --git a/ext/pty/pty.c b/ext/pty/pty.c index 72074f7421..7c79f81e33 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -92,9 +92,13 @@ struct pty_info { static void getDevice(int*, int*, char [DEVICELEN], int); +static int start_new_session(char *errbuf, size_t errbuf_len); +static int obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len); +static int drop_privilege(char *errbuf, size_t errbuf_len); + struct child_info { int master, slave; - char *slavename; + const char *slavename; VALUE execarg_obj; struct rb_execarg *eargp; }; @@ -102,26 +106,42 @@ struct child_info { static int chfunc(void *data, char *errbuf, size_t errbuf_len) { - struct child_info *carg = data; + const struct child_info *carg = data; int master = carg->master; int slave = carg->slave; + const char *slavename = carg->slavename; + + if (start_new_session(errbuf, errbuf_len)) + return -1; + + if (obtain_ctty(master, slave, slavename, errbuf, errbuf_len)) + return -1; + + if (drop_privilege(errbuf, errbuf_len)) + return -1; + + return rb_exec_async_signal_safe(carg->eargp, errbuf, errbuf_len); +} #define ERROR_EXIT(str) do { \ - strlcpy(errbuf, (str), errbuf_len); \ - return -1; \ + strlcpy(errbuf, (str), errbuf_len); \ + return -1; \ } while (0) - /* - * Set free from process group and controlling terminal - */ +/* + * Set free from process group and controlling terminal + */ +static int +start_new_session(char *errbuf, size_t errbuf_len) +{ #ifdef HAVE_SETSID (void) setsid(); #else /* HAS_SETSID */ # ifdef HAVE_SETPGRP -# ifdef SETGRP_VOID +# ifdef SETPGRP_VOID if (setpgrp() == -1) ERROR_EXIT("setpgrp()"); -# else /* SETGRP_VOID */ +# else /* SETPGRP_VOID */ if (setpgrp(0, getpid()) == -1) ERROR_EXIT("setpgrp()"); { @@ -132,20 +152,25 @@ chfunc(void *data, char *errbuf, size_t errbuf_len) ERROR_EXIT("ioctl(TIOCNOTTY)"); close(i); } -# endif /* SETGRP_VOID */ +# endif /* SETPGRP_VOID */ # endif /* HAVE_SETPGRP */ #endif /* HAS_SETSID */ + return 0; +} - /* - * obtain new controlling terminal - */ +/* + * obtain new controlling terminal + */ +static int +obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len) +{ #if defined(TIOCSCTTY) close(master); (void) ioctl(slave, TIOCSCTTY, (char *)0); /* errors ignored for sun */ #else close(slave); - slave = rb_cloexec_open(carg->slavename, O_RDWR, 0); + slave = rb_cloexec_open(slavename, O_RDWR, 0); if (slave < 0) { ERROR_EXIT("open: pty slave"); } @@ -155,43 +180,53 @@ chfunc(void *data, char *errbuf, size_t errbuf_len) dup2(slave,0); dup2(slave,1); dup2(slave,2); - if (slave < 0 || slave > 2) (void)!close(slave); + if (slave > 2) (void)!close(slave); + return 0; +} + +static int +drop_privilege(char *errbuf, size_t errbuf_len) +{ #if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID) if (seteuid(getuid())) ERROR_EXIT("seteuid()"); #endif + return 0; +} - return rb_exec_async_signal_safe(carg->eargp, errbuf, sizeof(errbuf_len)); #undef ERROR_EXIT -} static void establishShell(int argc, VALUE *argv, struct pty_info *info, - char SlaveName[DEVICELEN]) + char SlaveName[DEVICELEN]) { int master, slave, status = 0; rb_pid_t pid; - char *p, *getenv(); + char *p; VALUE v; struct child_info carg; char errbuf[32]; if (argc == 0) { - const char *shellname = "/bin/sh"; + const char *shellname = "/bin/sh"; - if ((p = getenv("SHELL")) != NULL) { - shellname = p; - } - else { + if ((p = getenv("SHELL")) != NULL) { + shellname = p; + } + else { #if defined HAVE_PWD_H - const char *username = getenv("USER"); - struct passwd *pwent = getpwnam(username ? username : getlogin()); - if (pwent && pwent->pw_shell) - shellname = pwent->pw_shell; + const char *username = getenv("USER"); + if (username == NULL) + username = getlogin(); + if (username != NULL) { + struct passwd *pwent = getpwnam(username); + if (pwent && pwent->pw_shell) + shellname = pwent->pw_shell; + } #endif - } - v = rb_str_new2(shellname); - argc = 1; - argv = &v; + } + v = rb_str_new2(shellname); + argc = 1; + argv = &v; } carg.execarg_obj = rb_execarg_new(argc, argv, 1, 0); @@ -207,13 +242,13 @@ establishShell(int argc, VALUE *argv, struct pty_info *info, pid = rb_fork_async_signal_safe(&status, chfunc, &carg, Qnil, errbuf, sizeof(errbuf)); if (pid < 0) { - int e = errno; - close(master); - close(slave); + int e = errno; + close(master); + close(slave); rb_execarg_parent_end(carg.execarg_obj); - errno = e; - if (status) rb_jump_tag(status); - rb_sys_fail(errbuf[0] ? errbuf : "fork failed"); + errno = e; + if (status) rb_jump_tag(status); + rb_sys_fail(errbuf[0] ? errbuf : "fork failed"); } close(slave); @@ -225,7 +260,21 @@ establishShell(int argc, VALUE *argv, struct pty_info *info, RB_GC_GUARD(carg.execarg_obj); } -#if defined(HAVE_POSIX_OPENPT) || defined(HAVE_OPENPTY) || defined(HAVE_PTSNAME) +#if (defined(HAVE_POSIX_OPENPT) || defined(HAVE_PTSNAME)) && !defined(HAVE_PTSNAME_R) +/* glibc only, not obsolete interface on Tru64 or HP-UX */ +static int +ptsname_r(int fd, char *buf, size_t buflen) +{ + extern char *ptsname(int); + char *name = ptsname(fd); + if (!name) return -1; + strlcpy(buf, name, buflen); + return 0; +} +# define HAVE_PTSNAME_R 1 +#endif + +#if defined(HAVE_POSIX_OPENPT) || defined(HAVE_OPENPTY) || defined(HAVE_PTSNAME_R) static int no_mesg(char *slavedevice, int nomesg) { @@ -258,30 +307,39 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, /* Unix98 PTY */ int masterfd = -1, slavefd = -1; char *slavedevice; + struct sigaction dfl, old; + + dfl.sa_handler = SIG_DFL; + dfl.sa_flags = 0; + sigemptyset(&dfl.sa_mask); #if defined(__sun) || defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD_version < 902000) /* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */ /* FreeBSD 9.2 or later supports O_CLOEXEC * http://www.freebsd.org/cgi/query-pr.cgi?pr=162374 */ if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error; - if (rb_grantpt(masterfd) == -1) goto error; + if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error; + if (grantpt(masterfd) == -1) goto grantpt_error; rb_fd_fix_cloexec(masterfd); #else { - int flags = O_RDWR|O_NOCTTY; + int flags = O_RDWR|O_NOCTTY; # if defined(O_CLOEXEC) - /* glibc posix_openpt() in GNU/Linux calls open("/dev/ptmx", flags) internally. - * So version dependency on GNU/Linux is the same as O_CLOEXEC with open(). - * O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */ - flags |= O_CLOEXEC; + /* glibc posix_openpt() in GNU/Linux calls open("/dev/ptmx", flags) internally. + * So version dependency on GNU/Linux is the same as O_CLOEXEC with open(). + * O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */ + flags |= O_CLOEXEC; # endif - if ((masterfd = posix_openpt(flags)) == -1) goto error; + if ((masterfd = posix_openpt(flags)) == -1) goto error; } rb_fd_fix_cloexec(masterfd); - if (rb_grantpt(masterfd) == -1) goto error; + if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error; + if (grantpt(masterfd) == -1) goto grantpt_error; #endif + if (sigaction(SIGCHLD, &old, NULL) == -1) goto error; if (unlockpt(masterfd) == -1) goto error; - if ((slavedevice = ptsname(masterfd)) == NULL) goto error; + if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error; + slavedevice = SlaveName; if (no_mesg(slavedevice, nomesg) == -1) goto error; if ((slavefd = rb_cloexec_open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error; rb_update_max_fd(slavefd); @@ -294,9 +352,10 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, *master = masterfd; *slave = slavefd; - strlcpy(SlaveName, slavedevice, DEVICELEN); return 0; + grantpt_error: + sigaction(SIGCHLD, &old, NULL); error: if (slavefd != -1) close(slavefd); if (masterfd != -1) close(masterfd); @@ -310,15 +369,15 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, * or the same interface function. */ if (openpty(master, slave, SlaveName, - (struct termios *)0, (struct winsize *)0) == -1) { - if (!fail) return -1; - rb_raise(rb_eRuntimeError, "openpty() failed"); + (struct termios *)0, (struct winsize *)0) == -1) { + if (!fail) return -1; + rb_raise(rb_eRuntimeError, "openpty() failed"); } rb_fd_fix_cloexec(*master); rb_fd_fix_cloexec(*slave); if (no_mesg(SlaveName, nomesg) == -1) { - if (!fail) return -1; - rb_raise(rb_eRuntimeError, "can't chmod slave pty"); + if (!fail) return -1; + rb_raise(rb_eRuntimeError, "can't chmod slave pty"); } return 0; @@ -329,8 +388,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, mode_t mode = nomesg ? 0600 : 0622; if (!(name = _getpty(master, O_RDWR, mode, 0))) { - if (!fail) return -1; - rb_raise(rb_eRuntimeError, "_getpty() failed"); + if (!fail) return -1; + rb_raise(rb_eRuntimeError, "_getpty() failed"); } rb_fd_fix_cloexec(*master); @@ -346,21 +405,25 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, char *slavedevice; void (*s)(); - extern char *ptsname(int); extern int unlockpt(int); + extern int grantpt(int); #if defined(__sun) /* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */ if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error; - if(rb_grantpt(masterfd) == -1) goto error; + s = signal(SIGCHLD, SIG_DFL); + if(grantpt(masterfd) == -1) goto error; rb_fd_fix_cloexec(masterfd); #else if((masterfd = rb_cloexec_open("/dev/ptmx", O_RDWR, 0)) == -1) goto error; rb_update_max_fd(masterfd); - if(rb_grantpt(masterfd) == -1) goto error; + s = signal(SIGCHLD, SIG_DFL); + if(grantpt(masterfd) == -1) goto error; #endif + signal(SIGCHLD, s); if(unlockpt(masterfd) == -1) goto error; - if((slavedevice = ptsname(masterfd)) == NULL) goto error; + if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error; + slavedevice = SlaveName; if (no_mesg(slavedevice, nomesg) == -1) goto error; if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error; rb_update_max_fd(slavefd); @@ -371,7 +434,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, #endif *master = masterfd; *slave = slavefd; - strlcpy(SlaveName, slavedevice, DEVICELEN); return 0; error: @@ -386,49 +448,42 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, char MasterName[DEVICELEN]; #define HEX1(c) \ - c"0",c"1",c"2",c"3",c"4",c"5",c"6",c"7", \ - c"8",c"9",c"a",c"b",c"c",c"d",c"e",c"f" + c"0",c"1",c"2",c"3",c"4",c"5",c"6",c"7", \ + c"8",c"9",c"a",c"b",c"c",c"d",c"e",c"f" -#if defined(__hpux) - static const char MasterDevice[] = "/dev/ptym/pty%s"; - static const char SlaveDevice[] = "/dev/pty/tty%s"; - static const char deviceNo[][3] = { - HEX1("p"), HEX1("q"), HEX1("r"), HEX1("s"), - HEX1("t"), HEX1("u"), HEX1("v"), HEX1("w"), - }; -#elif defined(_IBMESA) /* AIX/ESA */ +#if defined(_IBMESA) /* AIX/ESA */ static const char MasterDevice[] = "/dev/ptyp%s"; static const char SlaveDevice[] = "/dev/ttyp%s"; static const char deviceNo[][3] = { - HEX1("0"), HEX1("1"), HEX1("2"), HEX1("3"), - HEX1("4"), HEX1("5"), HEX1("6"), HEX1("7"), - HEX1("8"), HEX1("9"), HEX1("a"), HEX1("b"), - HEX1("c"), HEX1("d"), HEX1("e"), HEX1("f"), + HEX1("0"), HEX1("1"), HEX1("2"), HEX1("3"), + HEX1("4"), HEX1("5"), HEX1("6"), HEX1("7"), + HEX1("8"), HEX1("9"), HEX1("a"), HEX1("b"), + HEX1("c"), HEX1("d"), HEX1("e"), HEX1("f"), }; #else /* 4.2BSD */ static const char MasterDevice[] = "/dev/pty%s"; static const char SlaveDevice[] = "/dev/tty%s"; static const char deviceNo[][3] = { - HEX1("p"), HEX1("q"), HEX1("r"), HEX1("s"), + HEX1("p"), HEX1("q"), HEX1("r"), HEX1("s"), }; #endif #undef HEX1 for (i = 0; i < numberof(deviceNo); i++) { - const char *const devno = deviceNo[i]; - snprintf(MasterName, sizeof MasterName, MasterDevice, devno); - if ((masterfd = rb_cloexec_open(MasterName,O_RDWR,0)) >= 0) { + const char *const devno = deviceNo[i]; + snprintf(MasterName, sizeof MasterName, MasterDevice, devno); + if ((masterfd = rb_cloexec_open(MasterName,O_RDWR,0)) >= 0) { rb_update_max_fd(masterfd); - *master = masterfd; - snprintf(SlaveName, DEVICELEN, SlaveDevice, devno); - if ((slavefd = rb_cloexec_open(SlaveName,O_RDWR,0)) >= 0) { + *master = masterfd; + snprintf(SlaveName, DEVICELEN, SlaveDevice, devno); + if ((slavefd = rb_cloexec_open(SlaveName,O_RDWR,0)) >= 0) { rb_update_max_fd(slavefd); - *slave = slavefd; - if (chown(SlaveName, getuid(), getgid()) != 0) goto error; - if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error; - return 0; - } - close(masterfd); - } + *slave = slavefd; + if (chown(SlaveName, getuid(), getgid()) != 0) goto error; + if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error; + return 0; + } + close(masterfd); + } } error: if (slavefd != -1) close(slavefd); @@ -442,8 +497,8 @@ static void getDevice(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg) { if (get_device_once(master, slave, SlaveName, nomesg, 0)) { - rb_gc(); - get_device_once(master, slave, SlaveName, nomesg, 1); + rb_gc(); + get_device_once(master, slave, SlaveName, nomesg, 1); } } @@ -455,8 +510,10 @@ pty_close_pty(VALUE assoc) for (i = 0; i < 2; i++) { io = rb_ary_entry(assoc, i); - if (RB_TYPE_P(io, T_FILE) && 0 <= RFILE(io)->fptr->fd) + if (RB_TYPE_P(io, T_FILE)) { + /* it's OK to call rb_io_close again even if it's already closed */ rb_io_close(io); + } } return Qnil; } @@ -506,28 +563,21 @@ pty_open(VALUE klass) { int master_fd, slave_fd; char slavename[DEVICELEN]; - VALUE master_io, slave_file; - rb_io_t *master_fptr, *slave_fptr; - VALUE assoc; getDevice(&master_fd, &slave_fd, slavename, 1); - master_io = rb_obj_alloc(rb_cIO); - MakeOpenFile(master_io, master_fptr); - master_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX; - master_fptr->fd = master_fd; - master_fptr->pathv = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename)); + VALUE master_path = rb_obj_freeze(rb_sprintf("masterpty:%s", slavename)); + VALUE master_io = rb_io_open_descriptor(rb_cIO, master_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX, master_path, RUBY_IO_TIMEOUT_DEFAULT, NULL); + + VALUE slave_path = rb_obj_freeze(rb_str_new_cstr(slavename)); + VALUE slave_file = rb_io_open_descriptor(rb_cFile, slave_fd, FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY, slave_path, RUBY_IO_TIMEOUT_DEFAULT, NULL); - slave_file = rb_obj_alloc(rb_cFile); - MakeOpenFile(slave_file, slave_fptr); - slave_fptr->mode = FMODE_READWRITE | FMODE_SYNC | FMODE_DUPLEX | FMODE_TTY; - slave_fptr->fd = slave_fd; - slave_fptr->pathv = rb_obj_freeze(rb_str_new_cstr(slavename)); + VALUE assoc = rb_assoc_new(master_io, slave_file); - assoc = rb_assoc_new(master_io, slave_file); if (rb_block_given_p()) { - return rb_ensure(rb_yield, assoc, pty_close_pty, assoc); + return rb_ensure(rb_yield, assoc, pty_close_pty, assoc); } + return assoc; } @@ -538,7 +588,7 @@ pty_detach_process(VALUE v) #ifdef WNOHANG int st; if (rb_waitpid(info->child_pid, &st, WNOHANG) <= 0) - return Qnil; + return Qnil; #endif rb_detach_process(info->child_pid); return Qnil; @@ -546,10 +596,10 @@ pty_detach_process(VALUE v) /* * call-seq: - * PTY.spawn(command_line) { |r, w, pid| ... } - * PTY.spawn(command_line) => [r, w, pid] - * PTY.spawn(command, arguments, ...) { |r, w, pid| ... } - * PTY.spawn(command, arguments, ...) => [r, w, pid] + * PTY.spawn([env,] command_line) { |r, w, pid| ... } + * PTY.spawn([env,] command_line) => [r, w, pid] + * PTY.spawn([env,] command, arguments, ...) { |r, w, pid| ... } + * PTY.spawn([env,] command, arguments, ...) => [r, w, pid] * * Spawns the specified command on a newly allocated pty. You can also use the * alias ::getpty. @@ -557,6 +607,21 @@ pty_detach_process(VALUE v) * The command's controlling tty is set to the slave device of the pty * and its standard input/output/error is redirected to the slave device. * + * +env+ is an optional hash that provides additional environment variables to the spawned pty. + * + * # sets FOO to "bar" + * PTY.spawn({"FOO"=>"bar"}, "printenv", "FOO") do |r, w, pid| + * p r.read #=> "bar\r\n" + * ensure + * r.close; w.close; Process.wait(pid) + * end + * # unsets FOO + * PTY.spawn({"FOO"=>nil}, "printenv", "FOO") do |r, w, pid| + * p r.read #=> "" + * ensure + * r.close; w.close; Process.wait(pid) + * end + * * +command+ and +command_line+ are the full commands to run, given a String. * Any additional +arguments+ will be passed to the command. * @@ -571,41 +636,47 @@ pty_detach_process(VALUE v) * standard output and standard error * +w+:: A writable IO that is the command's standard input * +pid+:: The process identifier for the command. + * + * === Clean up + * + * This method does not clean up like closing IOs or waiting for child + * process, except that the process is detached in the block form to + * prevent it from becoming a zombie (see Process.detach). Any other + * cleanup is the responsibility of the caller. If waiting for +pid+, + * be sure to close both +r+ and +w+ before doing so; doing it in the + * reverse order may cause deadlock on some OSes. */ static VALUE pty_getpty(int argc, VALUE *argv, VALUE self) { VALUE res; struct pty_info info; - rb_io_t *wfptr,*rfptr; - VALUE rport = rb_obj_alloc(rb_cFile); - VALUE wport = rb_obj_alloc(rb_cFile); char SlaveName[DEVICELEN]; - MakeOpenFile(rport, rfptr); - MakeOpenFile(wport, wfptr); - establishShell(argc, argv, &info, SlaveName); - rfptr->mode = rb_io_modestr_fmode("r"); - rfptr->fd = info.fd; - rfptr->pathv = rb_obj_freeze(rb_str_new_cstr(SlaveName)); + VALUE pty_path = rb_obj_freeze(rb_str_new_cstr(SlaveName)); + VALUE rport = rb_io_open_descriptor( + rb_cFile, info.fd, FMODE_READABLE, pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL + ); - wfptr->mode = rb_io_modestr_fmode("w") | FMODE_SYNC; - wfptr->fd = rb_cloexec_dup(info.fd); - if (wfptr->fd == -1) + int wpty_fd = rb_cloexec_dup(info.fd); + if (wpty_fd == -1) { rb_sys_fail("dup()"); - rb_update_max_fd(wfptr->fd); - wfptr->pathv = rfptr->pathv; + } + VALUE wport = rb_io_open_descriptor( + rb_cFile, wpty_fd, FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE | FMODE_SYNC, + pty_path, RUBY_IO_TIMEOUT_DEFAULT, NULL + ); res = rb_ary_new2(3); - rb_ary_store(res,0,(VALUE)rport); - rb_ary_store(res,1,(VALUE)wport); + rb_ary_store(res, 0, rport); + rb_ary_store(res, 1, wport); rb_ary_store(res,2,PIDT2NUM(info.child_pid)); if (rb_block_given_p()) { - rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info); - return Qnil; + rb_ensure(rb_yield, res, pty_detach_process, (VALUE)&info); + return Qnil; } return res; } @@ -625,13 +696,13 @@ raise_from_check(rb_pid_t pid, int status) ---->> Either IF_STOPPED or WIFSTOPPED is needed <<---- #endif /* WIFSTOPPED | IF_STOPPED */ if (WIFSTOPPED(status)) { /* suspend */ - state = "stopped"; + state = "stopped"; } else if (kill(pid, 0) == 0) { - state = "changed"; + state = "changed"; } else { - state = "exited"; + state = "exited"; } msg = rb_sprintf("pty - %s: %ld", state, (long)pid); exc = rb_exc_new_str(eChildExited, msg); @@ -664,12 +735,12 @@ pty_check(int argc, VALUE *argv, VALUE self) int status; const int flag = #ifdef WNOHANG - WNOHANG| + WNOHANG| #endif #ifdef WUNTRACED - WUNTRACED| + WUNTRACED| #endif - 0; + 0; rb_scan_args(argc, argv, "11", &pid, &exc); cpid = rb_waitpid(NUM2PIDT(pid), &status, flag); @@ -753,8 +824,13 @@ void Init_pty(void) { cPTY = rb_define_module("PTY"); - /* :nodoc: */ - rb_define_module_function(cPTY,"getpty",pty_getpty,-1); +#if 1 + rb_define_module_function(cPTY,"get""pty",pty_getpty,-1); +#else /* for RDoc */ + /* show getpty as an alias of spawn */ + VALUE sPTY = rb_singleton_class(cPTY); + rb_define_alias(sPTY, "getpty", "spawn"); +#endif rb_define_module_function(cPTY,"spawn",pty_getpty,-1); rb_define_singleton_method(cPTY,"check",pty_check,-1); rb_define_singleton_method(cPTY,"open",pty_open,0); diff --git a/ext/racc/cparse/README b/ext/racc/cparse/README deleted file mode 100644 index 550e8d49fe..0000000000 --- a/ext/racc/cparse/README +++ /dev/null @@ -1,11 +0,0 @@ -Racc Runtime README -=================== - -This directory contains a runtime library of -Racc parser generator. If you want to generate -your own parser, you must get Racc full package. -Get it from: - - - http://i.loveruby.net/en/projects/racc - - https://github.com/ruby/racc - diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c deleted file mode 100644 index f71ed2bba9..0000000000 --- a/ext/racc/cparse/cparse.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - - cparse.c -- Racc Runtime Core - - Copyright (c) 1999-2006 Minero Aoki - - This library is free software. - You can distribute/modify this program under the same terms of ruby. - - $originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $ - -*/ - -#include <ruby.h> - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -/* ----------------------------------------------------------------------- - Important Constants ------------------------------------------------------------------------ */ - -#define RACC_VERSION "1.4.15" - -#define DEFAULT_TOKEN -1 -#define ERROR_TOKEN 1 -#define FINAL_TOKEN 0 - -#define vDEFAULT_TOKEN INT2FIX(DEFAULT_TOKEN) -#define vERROR_TOKEN INT2FIX(ERROR_TOKEN) -#define vFINAL_TOKEN INT2FIX(FINAL_TOKEN) - -/* ----------------------------------------------------------------------- - File Local Variables ------------------------------------------------------------------------ */ - -static VALUE RaccBug; -static VALUE CparseParams; - -static ID id_yydebug; -static ID id_nexttoken; -static ID id_onerror; -static ID id_noreduce; -static ID id_errstatus; - -static ID id_d_shift; -static ID id_d_reduce; -static ID id_d_accept; -static ID id_d_read_token; -static ID id_d_next_state; -static ID id_d_e_pop; - -/* ----------------------------------------------------------------------- - Utils ------------------------------------------------------------------------ */ - -/* For backward compatibility */ -#ifndef ID2SYM -# define ID2SYM(i) ULONG2NUM(i) -#endif -#ifndef SYM2ID -# define SYM2ID(v) ((ID)NUM2ULONG(v)) -#endif -#ifndef SYMBOL_P -# define SYMBOL_P(v) FIXNUM_P(v) -#endif -#ifndef LONG2NUM -# define LONG2NUM(i) INT2NUM(i) -#endif - -#ifndef HAVE_RB_ARY_SUBSEQ -# define rb_ary_subseq(ary, beg, len) rb_ary_new4(len, RARRAY_PTR(ary) + beg) -#endif - -static ID value_to_id _((VALUE v)); -static inline long num_to_long _((VALUE n)); - -static ID -value_to_id(VALUE v) -{ - if (! SYMBOL_P(v)) { - rb_raise(rb_eTypeError, "not symbol"); - } - return SYM2ID(v); -} - -static inline long -num_to_long(VALUE n) -{ - return NUM2LONG(n); -} - -#define AREF(s, idx) \ - ((0 <= idx && idx < RARRAY_LEN(s)) ? rb_ary_entry(s, idx) : Qnil) - -/* ----------------------------------------------------------------------- - Parser Stack Interfaces ------------------------------------------------------------------------ */ - -static VALUE get_stack_tail _((VALUE stack, long len)); -static void cut_stack_tail _((VALUE stack, long len)); - -static VALUE -get_stack_tail(VALUE stack, long len) -{ - if (len < 0) return Qnil; /* system error */ - if (len > RARRAY_LEN(stack)) len = RARRAY_LEN(stack); - return rb_ary_subseq(stack, RARRAY_LEN(stack) - len, len); -} - -static void -cut_stack_tail(VALUE stack, long len) -{ - while (len > 0) { - rb_ary_pop(stack); - len--; - } -} - -#define STACK_INIT_LEN 64 -#define NEW_STACK() rb_ary_new2(STACK_INIT_LEN) -#define PUSH(s, i) rb_ary_store(s, RARRAY_LEN(s), i) -#define POP(s) rb_ary_pop(s) -#define LAST_I(s) \ - ((RARRAY_LEN(s) > 0) ? rb_ary_entry(s, RARRAY_LEN(s) - 1) : Qnil) -#define GET_TAIL(s, len) get_stack_tail(s, len) -#define CUT_TAIL(s, len) cut_stack_tail(s, len) - -/* ----------------------------------------------------------------------- - struct cparse_params ------------------------------------------------------------------------ */ - -struct cparse_params { - VALUE value_v; /* VALUE version of this struct */ - - VALUE parser; /* parser object */ - - int lex_is_iterator; - VALUE lexer; /* scanner object */ - ID lexmid; /* name of scanner method (must be an iterator) */ - - /* State transition tables (immutable) - Data structure is from Dragon Book 4.9 */ - /* action table */ - VALUE action_table; - VALUE action_check; - VALUE action_default; - VALUE action_pointer; - /* goto table */ - VALUE goto_table; - VALUE goto_check; - VALUE goto_default; - VALUE goto_pointer; - - long nt_base; /* NonTerminal BASE index */ - VALUE reduce_table; /* reduce data table */ - VALUE token_table; /* token conversion table */ - - /* parser stacks and parameters */ - VALUE state; - long curstate; - VALUE vstack; - VALUE tstack; - VALUE t; - long shift_n; - long reduce_n; - long ruleno; - - long errstatus; /* nonzero in error recovering mode */ - long nerr; /* number of error */ - - int use_result_var; - - VALUE retval; /* return value of parser routine */ - long fin; /* parse result status */ -#define CP_FIN_ACCEPT 1 -#define CP_FIN_EOT 2 -#define CP_FIN_CANTPOP 3 - - int debug; /* user level debug */ - int sys_debug; /* system level debug */ - - long i; /* table index */ -}; - -/* ----------------------------------------------------------------------- - Parser Main Routines ------------------------------------------------------------------------ */ - -static VALUE racc_cparse _((VALUE parser, VALUE arg, VALUE sysdebug)); -static VALUE racc_yyparse _((VALUE parser, VALUE lexer, VALUE lexmid, - VALUE arg, VALUE sysdebug)); - -static void call_lexer _((struct cparse_params *v)); -static VALUE lexer_i _((RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data))); - -static VALUE assert_array _((VALUE a)); -static long assert_integer _((VALUE n)); -static VALUE assert_hash _((VALUE h)); -static VALUE initialize_params _((VALUE vparams, VALUE parser, VALUE arg, - VALUE lexer, VALUE lexmid)); -static void cparse_params_mark _((void *ptr)); -static size_t cparse_params_memsize _((const void *ptr)); - -static void parse_main _((struct cparse_params *v, - VALUE tok, VALUE val, int resume)); -static void extract_user_token _((struct cparse_params *v, - VALUE block_args, VALUE *tok, VALUE *val)); -static void shift _((struct cparse_params* v, long act, VALUE tok, VALUE val)); -static int reduce _((struct cparse_params* v, long act)); -static rb_block_call_func reduce0; - -#ifdef DEBUG -# define D_puts(msg) if (v->sys_debug) puts(msg) -# define D_printf(fmt,arg) if (v->sys_debug) printf(fmt,arg) -#else -# define D_puts(msg) -# define D_printf(fmt,arg) -#endif - -#undef RUBY_UNTYPED_DATA_WARNING -#define RUBY_UNTYPED_DATA_WARNING 1 - -static const rb_data_type_t cparse_params_type = { - "racc/cparse", - { - cparse_params_mark, - RUBY_TYPED_DEFAULT_FREE, - cparse_params_memsize, - }, -#ifdef RUBY_TYPED_FREE_IMMEDIATELY - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, -#endif -}; - -static VALUE -racc_cparse(VALUE parser, VALUE arg, VALUE sysdebug) -{ - VALUE vparams; - struct cparse_params *v; - - vparams = TypedData_Make_Struct(CparseParams, struct cparse_params, - &cparse_params_type, v); - D_puts("starting cparse"); - v->sys_debug = RTEST(sysdebug); - vparams = initialize_params(vparams, parser, arg, Qnil, Qnil); - v->lex_is_iterator = FALSE; - parse_main(v, Qnil, Qnil, 0); - - RB_GC_GUARD(vparams); - return v->retval; -} - -static VALUE -racc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, VALUE arg, VALUE sysdebug) -{ - VALUE vparams; - struct cparse_params *v; - - vparams = TypedData_Make_Struct(CparseParams, struct cparse_params, - &cparse_params_type, v); - v->sys_debug = RTEST(sysdebug); - D_puts("start C yyparse"); - vparams = initialize_params(vparams, parser, arg, lexer, lexmid); - v->lex_is_iterator = TRUE; - D_puts("params initialized"); - parse_main(v, Qnil, Qnil, 0); - call_lexer(v); - if (!v->fin) { - rb_raise(rb_eArgError, "%s() is finished before EndOfToken", - rb_id2name(v->lexmid)); - } - - RB_GC_GUARD(vparams); - return v->retval; -} - -#ifdef HAVE_RB_BLOCK_CALL -static void -call_lexer(struct cparse_params *v) -{ - rb_block_call(v->lexer, v->lexmid, 0, NULL, lexer_i, v->value_v); -} -#else -static VALUE -lexer_iter(VALUE data) -{ - struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type); - - rb_funcall(v->lexer, v->lexmid, 0); - return Qnil; -} - -static void -call_lexer(struct cparse_params *v) -{ - rb_iterate(lexer_iter, v->value_v, lexer_i, v->value_v); -} -#endif - -static VALUE -lexer_i(RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data)) -{ - struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type); - VALUE tok, val; - - if (v->fin) - rb_raise(rb_eArgError, "extra token after EndOfToken"); - extract_user_token(v, block_args, &tok, &val); - parse_main(v, tok, val, 1); - if (v->fin && v->fin != CP_FIN_ACCEPT) - rb_iter_break(); - return Qnil; -} - -static VALUE -assert_array(VALUE a) -{ - Check_Type(a, T_ARRAY); - return a; -} - -static VALUE -assert_hash(VALUE h) -{ - Check_Type(h, T_HASH); - return h; -} - -static long -assert_integer(VALUE n) -{ - return NUM2LONG(n); -} - -static VALUE -initialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lexmid) -{ - struct cparse_params *v = rb_check_typeddata(vparams, &cparse_params_type); - - v->value_v = vparams; - v->parser = parser; - v->lexer = lexer; - if (! NIL_P(lexmid)) - v->lexmid = value_to_id(lexmid); - - v->debug = RTEST(rb_ivar_get(parser, id_yydebug)); - - Check_Type(arg, T_ARRAY); - if (!(13 <= RARRAY_LEN(arg) && RARRAY_LEN(arg) <= 14)) - rb_raise(RaccBug, "[Racc Bug] wrong arg.size %ld", RARRAY_LEN(arg)); - v->action_table = assert_array (rb_ary_entry(arg, 0)); - v->action_check = assert_array (rb_ary_entry(arg, 1)); - v->action_default = assert_array (rb_ary_entry(arg, 2)); - v->action_pointer = assert_array (rb_ary_entry(arg, 3)); - v->goto_table = assert_array (rb_ary_entry(arg, 4)); - v->goto_check = assert_array (rb_ary_entry(arg, 5)); - v->goto_default = assert_array (rb_ary_entry(arg, 6)); - v->goto_pointer = assert_array (rb_ary_entry(arg, 7)); - v->nt_base = assert_integer(rb_ary_entry(arg, 8)); - v->reduce_table = assert_array (rb_ary_entry(arg, 9)); - v->token_table = assert_hash (rb_ary_entry(arg, 10)); - v->shift_n = assert_integer(rb_ary_entry(arg, 11)); - v->reduce_n = assert_integer(rb_ary_entry(arg, 12)); - if (RARRAY_LEN(arg) > 13) { - v->use_result_var = RTEST(rb_ary_entry(arg, 13)); - } - else { - v->use_result_var = TRUE; - } - - v->tstack = v->debug ? NEW_STACK() : Qnil; - v->vstack = NEW_STACK(); - v->state = NEW_STACK(); - v->curstate = 0; - PUSH(v->state, INT2FIX(0)); - v->t = INT2FIX(FINAL_TOKEN + 1); /* must not init to FINAL_TOKEN */ - v->nerr = 0; - v->errstatus = 0; - rb_ivar_set(parser, id_errstatus, LONG2NUM(v->errstatus)); - - v->retval = Qnil; - v->fin = 0; - - v->lex_is_iterator = FALSE; - - rb_iv_set(parser, "@vstack", v->vstack); - if (v->debug) { - rb_iv_set(parser, "@tstack", v->tstack); - } - else { - rb_iv_set(parser, "@tstack", Qnil); - } - - return vparams; -} - -static void -cparse_params_mark(void *ptr) -{ - struct cparse_params *v = (struct cparse_params*)ptr; - - rb_gc_mark(v->value_v); - rb_gc_mark(v->parser); - rb_gc_mark(v->lexer); - rb_gc_mark(v->action_table); - rb_gc_mark(v->action_check); - rb_gc_mark(v->action_default); - rb_gc_mark(v->action_pointer); - rb_gc_mark(v->goto_table); - rb_gc_mark(v->goto_check); - rb_gc_mark(v->goto_default); - rb_gc_mark(v->goto_pointer); - rb_gc_mark(v->reduce_table); - rb_gc_mark(v->token_table); - rb_gc_mark(v->state); - rb_gc_mark(v->vstack); - rb_gc_mark(v->tstack); - rb_gc_mark(v->t); - rb_gc_mark(v->retval); -} - -static size_t -cparse_params_memsize(const void *ptr) -{ - return sizeof(struct cparse_params); -} - -static void -extract_user_token(struct cparse_params *v, VALUE block_args, - VALUE *tok, VALUE *val) -{ - if (NIL_P(block_args)) { - /* EOF */ - *tok = Qfalse; - *val = rb_str_new("$", 1); - return; - } - - if (!RB_TYPE_P(block_args, T_ARRAY)) { - rb_raise(rb_eTypeError, - "%s() %s %"PRIsVALUE" (must be Array[2])", - v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token", - v->lex_is_iterator ? "yielded" : "returned", - rb_obj_class(block_args)); - } - if (RARRAY_LEN(block_args) != 2) { - rb_raise(rb_eArgError, - "%s() %s wrong size of array (%ld for 2)", - v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token", - v->lex_is_iterator ? "yielded" : "returned", - RARRAY_LEN(block_args)); - } - *tok = AREF(block_args, 0); - *val = AREF(block_args, 1); -} - -#define SHIFT(v,act,tok,val) shift(v,act,tok,val) -#define REDUCE(v,act) do {\ - switch (reduce(v,act)) { \ - case 0: /* normal */ \ - break; \ - case 1: /* yyerror */ \ - goto user_yyerror; \ - case 2: /* yyaccept */ \ - D_puts("u accept"); \ - goto accept; \ - default: \ - break; \ - } \ -} while (0) - -static void -parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume) -{ - long i; /* table index */ - long act; /* action type */ - VALUE act_value; /* action type, VALUE version */ - int read_next = 1; /* true if we need to read next token */ - VALUE tmp; - - if (resume) - goto resume; - - while (1) { - D_puts(""); - D_puts("---- enter new loop ----"); - D_puts(""); - - D_printf("(act) k1=%ld\n", v->curstate); - tmp = AREF(v->action_pointer, v->curstate); - if (NIL_P(tmp)) goto notfound; - D_puts("(act) pointer[k1] ok"); - i = NUM2LONG(tmp); - - D_printf("read_next=%d\n", read_next); - if (read_next && (v->t != vFINAL_TOKEN)) { - if (v->lex_is_iterator) { - D_puts("resuming..."); - if (v->fin) rb_raise(rb_eArgError, "token given after EOF"); - v->i = i; /* save i */ - return; - resume: - D_puts("resumed"); - i = v->i; /* load i */ - } - else { - D_puts("next_token"); - tmp = rb_funcall(v->parser, id_nexttoken, 0); - extract_user_token(v, tmp, &tok, &val); - } - /* convert token */ - v->t = rb_hash_aref(v->token_table, tok); - if (NIL_P(v->t)) { - v->t = vERROR_TOKEN; - } - D_printf("(act) t(k2)=%ld\n", NUM2LONG(v->t)); - if (v->debug) { - rb_funcall(v->parser, id_d_read_token, - 3, v->t, tok, val); - } - } - read_next = 0; - - i += NUM2LONG(v->t); - D_printf("(act) i=%ld\n", i); - if (i < 0) goto notfound; - - act_value = AREF(v->action_table, i); - if (NIL_P(act_value)) goto notfound; - act = NUM2LONG(act_value); - D_printf("(act) table[i]=%ld\n", act); - - tmp = AREF(v->action_check, i); - if (NIL_P(tmp)) goto notfound; - if (NUM2LONG(tmp) != v->curstate) goto notfound; - D_printf("(act) check[i]=%ld\n", NUM2LONG(tmp)); - - D_puts("(act) found"); - act_fixed: - D_printf("act=%ld\n", act); - goto handle_act; - - notfound: - D_puts("(act) not found: use default"); - act_value = AREF(v->action_default, v->curstate); - act = NUM2LONG(act_value); - goto act_fixed; - - - handle_act: - if (act > 0 && act < v->shift_n) { - D_puts("shift"); - if (v->errstatus > 0) { - v->errstatus--; - rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus)); - } - SHIFT(v, act, v->t, val); - read_next = 1; - } - else if (act < 0 && act > -(v->reduce_n)) { - D_puts("reduce"); - REDUCE(v, act); - } - else if (act == -(v->reduce_n)) { - goto error; - error_recovered: - ; /* goto label requires stmt */ - } - else if (act == v->shift_n) { - D_puts("accept"); - goto accept; - } - else { - rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act); - } - - if (v->debug) { - rb_funcall(v->parser, id_d_next_state, - 2, LONG2NUM(v->curstate), v->state); - } - } - /* not reach */ - - - accept: - if (v->debug) rb_funcall(v->parser, id_d_accept, 0); - v->retval = rb_ary_entry(v->vstack, 0); - v->fin = CP_FIN_ACCEPT; - return; - - - error: - D_printf("error detected, status=%ld\n", v->errstatus); - if (v->errstatus == 0) { - v->nerr++; - rb_funcall(v->parser, id_onerror, - 3, v->t, val, v->vstack); - } - user_yyerror: - if (v->errstatus == 3) { - if (v->t == vFINAL_TOKEN) { - v->retval = Qnil; - v->fin = CP_FIN_EOT; - return; - } - read_next = 1; - } - v->errstatus = 3; - rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus)); - - /* check if we can shift/reduce error token */ - D_printf("(err) k1=%ld\n", v->curstate); - D_printf("(err) k2=%d (error)\n", ERROR_TOKEN); - while (1) { - tmp = AREF(v->action_pointer, v->curstate); - if (NIL_P(tmp)) goto error_pop; - D_puts("(err) pointer[k1] ok"); - - i = NUM2LONG(tmp) + ERROR_TOKEN; - D_printf("(err) i=%ld\n", i); - if (i < 0) goto error_pop; - - act_value = AREF(v->action_table, i); - if (NIL_P(act_value)) { - D_puts("(err) table[i] == nil"); - goto error_pop; - } - act = NUM2LONG(act_value); - D_printf("(err) table[i]=%ld\n", act); - - tmp = AREF(v->action_check, i); - if (NIL_P(tmp)) { - D_puts("(err) check[i] == nil"); - goto error_pop; - } - if (NUM2LONG(tmp) != v->curstate) { - D_puts("(err) check[i] != k1"); - goto error_pop; - } - - D_puts("(err) found: can handle error token"); - break; - - error_pop: - D_puts("(err) act not found: can't handle error token; pop"); - - if (RARRAY_LEN(v->state) <= 1) { - v->retval = Qnil; - v->fin = CP_FIN_CANTPOP; - return; - } - POP(v->state); - POP(v->vstack); - v->curstate = num_to_long(LAST_I(v->state)); - if (v->debug) { - POP(v->tstack); - rb_funcall(v->parser, id_d_e_pop, - 3, v->state, v->tstack, v->vstack); - } - } - - /* shift/reduce error token */ - if (act > 0 && act < v->shift_n) { - D_puts("e shift"); - SHIFT(v, act, ERROR_TOKEN, val); - } - else if (act < 0 && act > -(v->reduce_n)) { - D_puts("e reduce"); - REDUCE(v, act); - } - else if (act == v->shift_n) { - D_puts("e accept"); - goto accept; - } - else { - rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act); - } - goto error_recovered; -} - -static void -shift(struct cparse_params *v, long act, VALUE tok, VALUE val) -{ - PUSH(v->vstack, val); - if (v->debug) { - PUSH(v->tstack, tok); - rb_funcall(v->parser, id_d_shift, - 3, tok, v->tstack, v->vstack); - } - v->curstate = act; - PUSH(v->state, LONG2NUM(v->curstate)); -} - -static int -reduce(struct cparse_params *v, long act) -{ - VALUE code; - v->ruleno = -act * 3; - code = rb_catch("racc_jump", reduce0, v->value_v); - v->errstatus = num_to_long(rb_ivar_get(v->parser, id_errstatus)); - return NUM2INT(code); -} - -static VALUE -reduce0(RB_BLOCK_CALL_FUNC_ARGLIST(_, data)) -{ - struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type); - VALUE reduce_to, reduce_len, method_id; - long len; - ID mid; - VALUE tmp, tmp_t = Qundef, tmp_v = Qundef; - long i, k1, k2; - VALUE goto_state; - - reduce_len = rb_ary_entry(v->reduce_table, v->ruleno); - reduce_to = rb_ary_entry(v->reduce_table, v->ruleno+1); - method_id = rb_ary_entry(v->reduce_table, v->ruleno+2); - len = NUM2LONG(reduce_len); - mid = value_to_id(method_id); - - /* call action */ - if (len == 0) { - tmp = Qnil; - if (mid != id_noreduce) - tmp_v = rb_ary_new(); - if (v->debug) - tmp_t = rb_ary_new(); - } - else { - if (mid != id_noreduce) { - tmp_v = GET_TAIL(v->vstack, len); - tmp = rb_ary_entry(tmp_v, 0); - } - else { - tmp = rb_ary_entry(v->vstack, RARRAY_LEN(v->vstack) - len); - } - CUT_TAIL(v->vstack, len); - if (v->debug) { - tmp_t = GET_TAIL(v->tstack, len); - CUT_TAIL(v->tstack, len); - } - CUT_TAIL(v->state, len); - } - if (mid != id_noreduce) { - if (v->use_result_var) { - tmp = rb_funcall(v->parser, mid, - 3, tmp_v, v->vstack, tmp); - } - else { - tmp = rb_funcall(v->parser, mid, - 2, tmp_v, v->vstack); - } - } - - /* then push result */ - PUSH(v->vstack, tmp); - if (v->debug) { - PUSH(v->tstack, reduce_to); - rb_funcall(v->parser, id_d_reduce, - 4, tmp_t, reduce_to, v->tstack, v->vstack); - } - - /* calculate transition state */ - if (RARRAY_LEN(v->state) == 0) - rb_raise(RaccBug, "state stack unexpectedly empty"); - k2 = num_to_long(LAST_I(v->state)); - k1 = num_to_long(reduce_to) - v->nt_base; - D_printf("(goto) k1=%ld\n", k1); - D_printf("(goto) k2=%ld\n", k2); - - tmp = AREF(v->goto_pointer, k1); - if (NIL_P(tmp)) goto notfound; - - i = NUM2LONG(tmp) + k2; - D_printf("(goto) i=%ld\n", i); - if (i < 0) goto notfound; - - goto_state = AREF(v->goto_table, i); - if (NIL_P(goto_state)) { - D_puts("(goto) table[i] == nil"); - goto notfound; - } - D_printf("(goto) table[i]=%ld (goto_state)\n", NUM2LONG(goto_state)); - - tmp = AREF(v->goto_check, i); - if (NIL_P(tmp)) { - D_puts("(goto) check[i] == nil"); - goto notfound; - } - if (tmp != LONG2NUM(k1)) { - D_puts("(goto) check[i] != table[i]"); - goto notfound; - } - D_printf("(goto) check[i]=%ld\n", NUM2LONG(tmp)); - - D_puts("(goto) found"); - transit: - PUSH(v->state, goto_state); - v->curstate = NUM2LONG(goto_state); - return INT2FIX(0); - - notfound: - D_puts("(goto) not found: use default"); - /* overwrite `goto-state' by default value */ - goto_state = AREF(v->goto_default, k1); - goto transit; -} - -/* ----------------------------------------------------------------------- - Ruby Interface ------------------------------------------------------------------------ */ - -void -Init_cparse(void) -{ -#ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); -#endif - - VALUE Racc, Parser; - ID id_racc = rb_intern_const("Racc"); - - if (rb_const_defined(rb_cObject, id_racc)) { - Racc = rb_const_get(rb_cObject, id_racc); - Parser = rb_const_get_at(Racc, rb_intern_const("Parser")); - } - else { - Racc = rb_define_module("Racc"); - Parser = rb_define_class_under(Racc, "Parser", rb_cObject); - } - rb_define_private_method(Parser, "_racc_do_parse_c", racc_cparse, 2); - rb_define_private_method(Parser, "_racc_yyparse_c", racc_yyparse, 4); - rb_define_const(Parser, "Racc_Runtime_Core_Version_C", - rb_str_new2(RACC_VERSION)); - rb_define_const(Parser, "Racc_Runtime_Core_Id_C", - rb_str_new2("$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $")); - - CparseParams = rb_define_class_under(Racc, "CparseParams", rb_cObject); - rb_undef_alloc_func(CparseParams); - rb_undef_method(CparseParams, "initialize"); - rb_undef_method(CparseParams, "initialize_copy"); - - RaccBug = rb_eRuntimeError; - - id_yydebug = rb_intern_const("@yydebug"); - id_nexttoken = rb_intern_const("next_token"); - id_onerror = rb_intern_const("on_error"); - id_noreduce = rb_intern_const("_reduce_none"); - id_errstatus = rb_intern_const("@racc_error_status"); - - id_d_shift = rb_intern_const("racc_shift"); - id_d_reduce = rb_intern_const("racc_reduce"); - id_d_accept = rb_intern_const("racc_accept"); - id_d_read_token = rb_intern_const("racc_read_token"); - id_d_next_state = rb_intern_const("racc_next_state"); - id_d_e_pop = rb_intern_const("racc_e_pop"); -} diff --git a/ext/racc/cparse/depend b/ext/racc/cparse/depend deleted file mode 100644 index 556c47fbd5..0000000000 --- a/ext/racc/cparse/depend +++ /dev/null @@ -1,162 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -cparse.o: $(RUBY_EXTCONF_H) -cparse.o: $(arch_hdrdir)/ruby/config.h -cparse.o: $(hdrdir)/ruby.h -cparse.o: $(hdrdir)/ruby/internal/anyargs.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/char.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/double.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/int.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/long.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/short.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -cparse.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -cparse.o: $(hdrdir)/ruby/internal/assume.h -cparse.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -cparse.o: $(hdrdir)/ruby/internal/attr/artificial.h -cparse.o: $(hdrdir)/ruby/internal/attr/cold.h -cparse.o: $(hdrdir)/ruby/internal/attr/const.h -cparse.o: $(hdrdir)/ruby/internal/attr/constexpr.h -cparse.o: $(hdrdir)/ruby/internal/attr/deprecated.h -cparse.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -cparse.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -cparse.o: $(hdrdir)/ruby/internal/attr/error.h -cparse.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -cparse.o: $(hdrdir)/ruby/internal/attr/forceinline.h -cparse.o: $(hdrdir)/ruby/internal/attr/format.h -cparse.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -cparse.o: $(hdrdir)/ruby/internal/attr/noalias.h -cparse.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -cparse.o: $(hdrdir)/ruby/internal/attr/noexcept.h -cparse.o: $(hdrdir)/ruby/internal/attr/noinline.h -cparse.o: $(hdrdir)/ruby/internal/attr/nonnull.h -cparse.o: $(hdrdir)/ruby/internal/attr/noreturn.h -cparse.o: $(hdrdir)/ruby/internal/attr/pure.h -cparse.o: $(hdrdir)/ruby/internal/attr/restrict.h -cparse.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -cparse.o: $(hdrdir)/ruby/internal/attr/warning.h -cparse.o: $(hdrdir)/ruby/internal/attr/weakref.h -cparse.o: $(hdrdir)/ruby/internal/cast.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -cparse.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -cparse.o: $(hdrdir)/ruby/internal/compiler_since.h -cparse.o: $(hdrdir)/ruby/internal/config.h -cparse.o: $(hdrdir)/ruby/internal/constant_p.h -cparse.o: $(hdrdir)/ruby/internal/core.h -cparse.o: $(hdrdir)/ruby/internal/core/rarray.h -cparse.o: $(hdrdir)/ruby/internal/core/rbasic.h -cparse.o: $(hdrdir)/ruby/internal/core/rbignum.h -cparse.o: $(hdrdir)/ruby/internal/core/rclass.h -cparse.o: $(hdrdir)/ruby/internal/core/rdata.h -cparse.o: $(hdrdir)/ruby/internal/core/rfile.h -cparse.o: $(hdrdir)/ruby/internal/core/rhash.h -cparse.o: $(hdrdir)/ruby/internal/core/robject.h -cparse.o: $(hdrdir)/ruby/internal/core/rregexp.h -cparse.o: $(hdrdir)/ruby/internal/core/rstring.h -cparse.o: $(hdrdir)/ruby/internal/core/rstruct.h -cparse.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -cparse.o: $(hdrdir)/ruby/internal/ctype.h -cparse.o: $(hdrdir)/ruby/internal/dllexport.h -cparse.o: $(hdrdir)/ruby/internal/dosish.h -cparse.o: $(hdrdir)/ruby/internal/error.h -cparse.o: $(hdrdir)/ruby/internal/eval.h -cparse.o: $(hdrdir)/ruby/internal/event.h -cparse.o: $(hdrdir)/ruby/internal/fl_type.h -cparse.o: $(hdrdir)/ruby/internal/gc.h -cparse.o: $(hdrdir)/ruby/internal/glob.h -cparse.o: $(hdrdir)/ruby/internal/globals.h -cparse.o: $(hdrdir)/ruby/internal/has/attribute.h -cparse.o: $(hdrdir)/ruby/internal/has/builtin.h -cparse.o: $(hdrdir)/ruby/internal/has/c_attribute.h -cparse.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -cparse.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -cparse.o: $(hdrdir)/ruby/internal/has/extension.h -cparse.o: $(hdrdir)/ruby/internal/has/feature.h -cparse.o: $(hdrdir)/ruby/internal/has/warning.h -cparse.o: $(hdrdir)/ruby/internal/intern/array.h -cparse.o: $(hdrdir)/ruby/internal/intern/bignum.h -cparse.o: $(hdrdir)/ruby/internal/intern/class.h -cparse.o: $(hdrdir)/ruby/internal/intern/compar.h -cparse.o: $(hdrdir)/ruby/internal/intern/complex.h -cparse.o: $(hdrdir)/ruby/internal/intern/cont.h -cparse.o: $(hdrdir)/ruby/internal/intern/dir.h -cparse.o: $(hdrdir)/ruby/internal/intern/enum.h -cparse.o: $(hdrdir)/ruby/internal/intern/enumerator.h -cparse.o: $(hdrdir)/ruby/internal/intern/error.h -cparse.o: $(hdrdir)/ruby/internal/intern/eval.h -cparse.o: $(hdrdir)/ruby/internal/intern/file.h -cparse.o: $(hdrdir)/ruby/internal/intern/gc.h -cparse.o: $(hdrdir)/ruby/internal/intern/hash.h -cparse.o: $(hdrdir)/ruby/internal/intern/io.h -cparse.o: $(hdrdir)/ruby/internal/intern/load.h -cparse.o: $(hdrdir)/ruby/internal/intern/marshal.h -cparse.o: $(hdrdir)/ruby/internal/intern/numeric.h -cparse.o: $(hdrdir)/ruby/internal/intern/object.h -cparse.o: $(hdrdir)/ruby/internal/intern/parse.h -cparse.o: $(hdrdir)/ruby/internal/intern/proc.h -cparse.o: $(hdrdir)/ruby/internal/intern/process.h -cparse.o: $(hdrdir)/ruby/internal/intern/random.h -cparse.o: $(hdrdir)/ruby/internal/intern/range.h -cparse.o: $(hdrdir)/ruby/internal/intern/rational.h -cparse.o: $(hdrdir)/ruby/internal/intern/re.h -cparse.o: $(hdrdir)/ruby/internal/intern/ruby.h -cparse.o: $(hdrdir)/ruby/internal/intern/select.h -cparse.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -cparse.o: $(hdrdir)/ruby/internal/intern/signal.h -cparse.o: $(hdrdir)/ruby/internal/intern/sprintf.h -cparse.o: $(hdrdir)/ruby/internal/intern/string.h -cparse.o: $(hdrdir)/ruby/internal/intern/struct.h -cparse.o: $(hdrdir)/ruby/internal/intern/thread.h -cparse.o: $(hdrdir)/ruby/internal/intern/time.h -cparse.o: $(hdrdir)/ruby/internal/intern/variable.h -cparse.o: $(hdrdir)/ruby/internal/intern/vm.h -cparse.o: $(hdrdir)/ruby/internal/interpreter.h -cparse.o: $(hdrdir)/ruby/internal/iterator.h -cparse.o: $(hdrdir)/ruby/internal/memory.h -cparse.o: $(hdrdir)/ruby/internal/method.h -cparse.o: $(hdrdir)/ruby/internal/module.h -cparse.o: $(hdrdir)/ruby/internal/newobj.h -cparse.o: $(hdrdir)/ruby/internal/rgengc.h -cparse.o: $(hdrdir)/ruby/internal/scan_args.h -cparse.o: $(hdrdir)/ruby/internal/special_consts.h -cparse.o: $(hdrdir)/ruby/internal/static_assert.h -cparse.o: $(hdrdir)/ruby/internal/stdalign.h -cparse.o: $(hdrdir)/ruby/internal/stdbool.h -cparse.o: $(hdrdir)/ruby/internal/symbol.h -cparse.o: $(hdrdir)/ruby/internal/value.h -cparse.o: $(hdrdir)/ruby/internal/value_type.h -cparse.o: $(hdrdir)/ruby/internal/variable.h -cparse.o: $(hdrdir)/ruby/internal/warning_push.h -cparse.o: $(hdrdir)/ruby/internal/xmalloc.h -cparse.o: $(hdrdir)/ruby/assert.h -cparse.o: $(hdrdir)/ruby/backward.h -cparse.o: $(hdrdir)/ruby/backward/2/assume.h -cparse.o: $(hdrdir)/ruby/backward/2/attributes.h -cparse.o: $(hdrdir)/ruby/backward/2/bool.h -cparse.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -cparse.o: $(hdrdir)/ruby/backward/2/inttypes.h -cparse.o: $(hdrdir)/ruby/backward/2/limits.h -cparse.o: $(hdrdir)/ruby/backward/2/long_long.h -cparse.o: $(hdrdir)/ruby/backward/2/stdalign.h -cparse.o: $(hdrdir)/ruby/backward/2/stdarg.h -cparse.o: $(hdrdir)/ruby/defines.h -cparse.o: $(hdrdir)/ruby/intern.h -cparse.o: $(hdrdir)/ruby/missing.h -cparse.o: $(hdrdir)/ruby/ruby.h -cparse.o: $(hdrdir)/ruby/st.h -cparse.o: $(hdrdir)/ruby/subst.h -cparse.o: cparse.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/racc/cparse/extconf.rb b/ext/racc/cparse/extconf.rb deleted file mode 100644 index 18c5689ad8..0000000000 --- a/ext/racc/cparse/extconf.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: false -# - -require 'mkmf' - -have_func('rb_block_call') -have_func('rb_ary_subseq') - -create_makefile 'racc/cparse' diff --git a/ext/rbconfig/sizeof/depend b/ext/rbconfig/sizeof/depend index b1774d6c62..7e6c950769 100644 --- a/ext/rbconfig/sizeof/depend +++ b/ext/rbconfig/sizeof/depend @@ -16,6 +16,19 @@ sizes.c: $(top_srcdir)/tool/generic_erb.rb \ # AUTOGENERATED DEPENDENCIES START limits.o: $(RUBY_EXTCONF_H) limits.o: $(arch_hdrdir)/ruby/config.h +limits.o: $(hdrdir)/ruby/assert.h +limits.o: $(hdrdir)/ruby/backward.h +limits.o: $(hdrdir)/ruby/backward/2/assume.h +limits.o: $(hdrdir)/ruby/backward/2/attributes.h +limits.o: $(hdrdir)/ruby/backward/2/bool.h +limits.o: $(hdrdir)/ruby/backward/2/inttypes.h +limits.o: $(hdrdir)/ruby/backward/2/limits.h +limits.o: $(hdrdir)/ruby/backward/2/long_long.h +limits.o: $(hdrdir)/ruby/backward/2/stdalign.h +limits.o: $(hdrdir)/ruby/backward/2/stdarg.h +limits.o: $(hdrdir)/ruby/defines.h +limits.o: $(hdrdir)/ruby/intern.h +limits.o: $(hdrdir)/ruby/internal/abi.h limits.o: $(hdrdir)/ruby/internal/anyargs.h limits.o: $(hdrdir)/ruby/internal/arithmetic.h limits.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +66,7 @@ limits.o: $(hdrdir)/ruby/internal/attr/noexcept.h limits.o: $(hdrdir)/ruby/internal/attr/noinline.h limits.o: $(hdrdir)/ruby/internal/attr/nonnull.h limits.o: $(hdrdir)/ruby/internal/attr/noreturn.h +limits.o: $(hdrdir)/ruby/internal/attr/packed_struct.h limits.o: $(hdrdir)/ruby/internal/attr/pure.h limits.o: $(hdrdir)/ruby/internal/attr/restrict.h limits.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -112,7 +126,6 @@ limits.o: $(hdrdir)/ruby/internal/intern/enumerator.h limits.o: $(hdrdir)/ruby/internal/intern/error.h limits.o: $(hdrdir)/ruby/internal/intern/eval.h limits.o: $(hdrdir)/ruby/internal/intern/file.h -limits.o: $(hdrdir)/ruby/internal/intern/gc.h limits.o: $(hdrdir)/ruby/internal/intern/hash.h limits.o: $(hdrdir)/ruby/internal/intern/io.h limits.o: $(hdrdir)/ruby/internal/intern/load.h @@ -129,6 +142,7 @@ limits.o: $(hdrdir)/ruby/internal/intern/re.h limits.o: $(hdrdir)/ruby/internal/intern/ruby.h limits.o: $(hdrdir)/ruby/internal/intern/select.h limits.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +limits.o: $(hdrdir)/ruby/internal/intern/set.h limits.o: $(hdrdir)/ruby/internal/intern/signal.h limits.o: $(hdrdir)/ruby/internal/intern/sprintf.h limits.o: $(hdrdir)/ruby/internal/intern/string.h @@ -143,31 +157,18 @@ limits.o: $(hdrdir)/ruby/internal/memory.h limits.o: $(hdrdir)/ruby/internal/method.h limits.o: $(hdrdir)/ruby/internal/module.h limits.o: $(hdrdir)/ruby/internal/newobj.h -limits.o: $(hdrdir)/ruby/internal/rgengc.h limits.o: $(hdrdir)/ruby/internal/scan_args.h limits.o: $(hdrdir)/ruby/internal/special_consts.h limits.o: $(hdrdir)/ruby/internal/static_assert.h limits.o: $(hdrdir)/ruby/internal/stdalign.h limits.o: $(hdrdir)/ruby/internal/stdbool.h +limits.o: $(hdrdir)/ruby/internal/stdckdint.h limits.o: $(hdrdir)/ruby/internal/symbol.h limits.o: $(hdrdir)/ruby/internal/value.h limits.o: $(hdrdir)/ruby/internal/value_type.h limits.o: $(hdrdir)/ruby/internal/variable.h limits.o: $(hdrdir)/ruby/internal/warning_push.h limits.o: $(hdrdir)/ruby/internal/xmalloc.h -limits.o: $(hdrdir)/ruby/assert.h -limits.o: $(hdrdir)/ruby/backward.h -limits.o: $(hdrdir)/ruby/backward/2/assume.h -limits.o: $(hdrdir)/ruby/backward/2/attributes.h -limits.o: $(hdrdir)/ruby/backward/2/bool.h -limits.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -limits.o: $(hdrdir)/ruby/backward/2/inttypes.h -limits.o: $(hdrdir)/ruby/backward/2/limits.h -limits.o: $(hdrdir)/ruby/backward/2/long_long.h -limits.o: $(hdrdir)/ruby/backward/2/stdalign.h -limits.o: $(hdrdir)/ruby/backward/2/stdarg.h -limits.o: $(hdrdir)/ruby/defines.h -limits.o: $(hdrdir)/ruby/intern.h limits.o: $(hdrdir)/ruby/missing.h limits.o: $(hdrdir)/ruby/ruby.h limits.o: $(hdrdir)/ruby/st.h @@ -175,6 +176,19 @@ limits.o: $(hdrdir)/ruby/subst.h limits.o: limits.c sizes.o: $(RUBY_EXTCONF_H) sizes.o: $(arch_hdrdir)/ruby/config.h +sizes.o: $(hdrdir)/ruby/assert.h +sizes.o: $(hdrdir)/ruby/backward.h +sizes.o: $(hdrdir)/ruby/backward/2/assume.h +sizes.o: $(hdrdir)/ruby/backward/2/attributes.h +sizes.o: $(hdrdir)/ruby/backward/2/bool.h +sizes.o: $(hdrdir)/ruby/backward/2/inttypes.h +sizes.o: $(hdrdir)/ruby/backward/2/limits.h +sizes.o: $(hdrdir)/ruby/backward/2/long_long.h +sizes.o: $(hdrdir)/ruby/backward/2/stdalign.h +sizes.o: $(hdrdir)/ruby/backward/2/stdarg.h +sizes.o: $(hdrdir)/ruby/defines.h +sizes.o: $(hdrdir)/ruby/intern.h +sizes.o: $(hdrdir)/ruby/internal/abi.h sizes.o: $(hdrdir)/ruby/internal/anyargs.h sizes.o: $(hdrdir)/ruby/internal/arithmetic.h sizes.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -212,6 +226,7 @@ sizes.o: $(hdrdir)/ruby/internal/attr/noexcept.h sizes.o: $(hdrdir)/ruby/internal/attr/noinline.h sizes.o: $(hdrdir)/ruby/internal/attr/nonnull.h sizes.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sizes.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sizes.o: $(hdrdir)/ruby/internal/attr/pure.h sizes.o: $(hdrdir)/ruby/internal/attr/restrict.h sizes.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -271,7 +286,6 @@ sizes.o: $(hdrdir)/ruby/internal/intern/enumerator.h sizes.o: $(hdrdir)/ruby/internal/intern/error.h sizes.o: $(hdrdir)/ruby/internal/intern/eval.h sizes.o: $(hdrdir)/ruby/internal/intern/file.h -sizes.o: $(hdrdir)/ruby/internal/intern/gc.h sizes.o: $(hdrdir)/ruby/internal/intern/hash.h sizes.o: $(hdrdir)/ruby/internal/intern/io.h sizes.o: $(hdrdir)/ruby/internal/intern/load.h @@ -288,6 +302,7 @@ sizes.o: $(hdrdir)/ruby/internal/intern/re.h sizes.o: $(hdrdir)/ruby/internal/intern/ruby.h sizes.o: $(hdrdir)/ruby/internal/intern/select.h sizes.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sizes.o: $(hdrdir)/ruby/internal/intern/set.h sizes.o: $(hdrdir)/ruby/internal/intern/signal.h sizes.o: $(hdrdir)/ruby/internal/intern/sprintf.h sizes.o: $(hdrdir)/ruby/internal/intern/string.h @@ -302,31 +317,18 @@ sizes.o: $(hdrdir)/ruby/internal/memory.h sizes.o: $(hdrdir)/ruby/internal/method.h sizes.o: $(hdrdir)/ruby/internal/module.h sizes.o: $(hdrdir)/ruby/internal/newobj.h -sizes.o: $(hdrdir)/ruby/internal/rgengc.h sizes.o: $(hdrdir)/ruby/internal/scan_args.h sizes.o: $(hdrdir)/ruby/internal/special_consts.h sizes.o: $(hdrdir)/ruby/internal/static_assert.h sizes.o: $(hdrdir)/ruby/internal/stdalign.h sizes.o: $(hdrdir)/ruby/internal/stdbool.h +sizes.o: $(hdrdir)/ruby/internal/stdckdint.h sizes.o: $(hdrdir)/ruby/internal/symbol.h sizes.o: $(hdrdir)/ruby/internal/value.h sizes.o: $(hdrdir)/ruby/internal/value_type.h sizes.o: $(hdrdir)/ruby/internal/variable.h sizes.o: $(hdrdir)/ruby/internal/warning_push.h sizes.o: $(hdrdir)/ruby/internal/xmalloc.h -sizes.o: $(hdrdir)/ruby/assert.h -sizes.o: $(hdrdir)/ruby/backward.h -sizes.o: $(hdrdir)/ruby/backward/2/assume.h -sizes.o: $(hdrdir)/ruby/backward/2/attributes.h -sizes.o: $(hdrdir)/ruby/backward/2/bool.h -sizes.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -sizes.o: $(hdrdir)/ruby/backward/2/inttypes.h -sizes.o: $(hdrdir)/ruby/backward/2/limits.h -sizes.o: $(hdrdir)/ruby/backward/2/long_long.h -sizes.o: $(hdrdir)/ruby/backward/2/stdalign.h -sizes.o: $(hdrdir)/ruby/backward/2/stdarg.h -sizes.o: $(hdrdir)/ruby/defines.h -sizes.o: $(hdrdir)/ruby/intern.h sizes.o: $(hdrdir)/ruby/missing.h sizes.o: $(hdrdir)/ruby/ruby.h sizes.o: $(hdrdir)/ruby/st.h diff --git a/ext/readline/.gitignore b/ext/readline/.gitignore deleted file mode 100644 index 3d372989ae..0000000000 --- a/ext/readline/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/readline-[1-9]*.* diff --git a/ext/readline/README b/ext/readline/README deleted file mode 100644 index 57c51b5f5d..0000000000 --- a/ext/readline/README +++ /dev/null @@ -1,10 +0,0 @@ -The Readline module provides interface for GNU Readline. -This module defines a number of methods to facilitate completion -and accesses input history from the Ruby interpreter. -This module supported Edit Line(libedit) too. -libedit is compatible with GNU Readline. - -GNU Readline:: http://www.gnu.org/directory/readline.html -libedit:: http://www.thrysoee.dk/editline/ - -See RDoc for Readline module. diff --git a/ext/readline/README.ja b/ext/readline/README.ja deleted file mode 100644 index 57a6ee4126..0000000000 --- a/ext/readline/README.ja +++ /dev/null @@ -1,386 +0,0 @@ -GNU Readline によるコマンドライン入力インタフェースを提供するモジュール -です。GNU Readline の互換ライブラリのひとつである Edit Line(libedit) も -サポートしています。 - -GNU Readline:: http://www.gnu.org/directory/readline.html -libedit:: http://www.thrysoee.dk/editline/ - -Readline.readline を使用してユーザからの入力を取得できます。このとき、 -GNU Readline のように入力の補完やEmacs のようなキー操作などができます。 - - require "readline" - while buf = Readline.readline("> ", true) - p buf - end - -ユーザが入力した内容を履歴(以下、ヒストリ)として記録することができます。 -定数 Readline::HISTORY を使用してヒストリにアクセスできます。 - - require "readline" - while buf = Readline.readline("> ", true) - p Readline::HISTORY.to_a - print("-> ", buf, "\n") - end - -使用するライブラリにより、いくつかのメソッドで例外 NotImplementedError -が発生します。 - -== Readline モジュール - -=== モジュール関数 - -readline([prompt, [add_hist]]) -> String | nil - - prompt を出力し、ユーザからのキー入力を待ちます。 - エンターキーの押下などでユーザが文字列を入力し終えると、 - 入力した文字列を返します。 - このとき、add_hist が true であれば、入力した文字列をヒストリに追加します。 - - 何も入力していない状態で EOF(UNIX では ^D) を入力するなどで、 - ユーザからの入力がない場合は nil を返します。 - - 次の条件を全て満たす場合、例外 IOError が発生します。 - 1. 標準入力が tty でない。 - 2. 標準入力をクローズしている。(isatty(2) の errno が EBADF である。) - - 本メソッドはスレッドに対応しています。 - 入力待ち状態のときはスレッドコンテキストの切替えが発生します。 - - 入力時には行内編集が可能で、vi モードと Emacs モードが用意されています。 - デフォルトは Emacs モードです。 - - 本メソッドには注意事項があります。 - 入力待ちの状態で ^C すると ruby インタプリタが終了し、端末状態を復帰しません。 - これを回避するための例を3つ挙げます。 - - * ^CによるInterrupt例外を補足して、端末状態を復帰します: - - require "readline" - - stty_save = `stty -g`.chomp - begin - while buf = Readline.readline - p buf - end - rescue Interrupt - system("stty", stty_save) - exit - end - end - end - - * INTシグナルを補足して、端末状態を復帰します: - - require "readline" - - stty_save = `stty -g`.chomp - trap("INT") { system "stty", stty_save; exit } - - while buf = Readline.readline - p buf - end - - * 単に ^C を無視する方法もあります: - - require "readline" - - trap("INT", "SIG_IGN") - - while buf = Readline.readline - p buf - end - - 入力履歴 Readline::HISTORY を使用して、空行や直前の入力と同じ内容は入力 - 履歴に残さないということもできます。 - - require "readline" - - while buf = Readline.readline("> ", true) - # p Readline::HISTORY.to_a - Readline::HISTORY.pop if /^\s*$/ =~ buf - - begin - if Readline::HISTORY[Readline::HISTORY.length-2] == buf - Readline::HISTORY.pop - end - rescue IndexError - end - - # p Readline::HISTORY.to_a - print "-> ", buf, "\n" - end - -=== クラスメソッド - -Readline.input = input - - Readline.readline メソッドで使用する入力用の File オブジェクト input - を指定します。 - -Readline.output = output - - Readline.readline メソッドで使用する出力用の File オブジェクト - output を指定します。 - -Readline.completion_proc = proc - - ユーザからの入力を補完する時の候補を取得する Proc オブジェクト proc を - 指定します。proc は、次のものを想定しています。 - 1. call メソッドを持ちます。 - call メソッドを持たない場合、例外 ArgumentError が発生します。 - 2. 引数にユーザからの入力文字列(注1)を取ります。 - 3. 候補の文字列の配列を返します。 - - 注1:「/var/lib /v」の後で補完を行うと、 - デフォルトでは proc の引数に「/v」が渡されます。 - このように、ユーザが入力した文字列を - Readline.completer_word_break_characters に含まれる文字で区切ったも - のを単語とすると、カーソルがある単語の最初の文字から現在のカーソル位 - 置までの文字列が proc の引数に渡されます。 - -Readline.completion_proc -> proc - - ユーザからの入力を補完する時の候補を取得する Proc オブジェクト proc - を取得します。 - -Readline.completion_case_fold = bool - - ユーザの入力を補完する際、大文字と小文字を区別する/しないを指定します。 - bool が真ならば区別しません。bool が偽ならば区別します。 - -Readline.completion_case_fold -> bool - - ユーザの入力を補完する際、大文字と小文字を区別する/しないを取得します。 - bool が真ならば区別しません。bool が偽ならば区別します。 - - なお、Readline.completion_case_fold= メソッドで指定したオブジェクトを - そのまま取得するので、次のような動作をします。 - - require "readline" - - Readline.completion_case_fold = "This is a String." - p Readline.completion_case_fold # => "This is a String." - -Readline.line_buffer -> string - - 入力中の行全体を返します。complete_proc の中で使用することを想定し - ています。Readline.line_buffer の長さは GNU Readline の rl_end 変数の - 値と一致します。 - -Readline.point -> int - - 現在のカーソルの位置を返します。 - Readline モジュールは補完対象の単語の開始位置の情報を提供していません。 - しかしながら、 completion_proc の中で入力した単語 text と - Readline.point を使用することで開始位置を導くことができます。 - - 開始位置 = 入力した単語の長さ - Readline.point - -Readline.vi_editing_mode -> nil - - 編集モードを vi モードにします。 - vi モードの詳細は、GNU Readline のマニュアルを参照してください。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.vi_editing_mode? -> bool - - 編集モードが vi モードの場合、true を返します。そうでなければ false - を返します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.emacs_editing_mode -> nil - - 編集モードを Emacs モードにします。 - デフォルトは Emacs モードです。 - Emacs モードの詳細は、GNU Readline のマニュアルを参照してください。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.emacs_editing_mode? -> bool - - 編集モードが Emacs モードの場合、true を返します。そうでなければ false - を返します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completion_append_character = char - - ユーザの入力の補完が完了した場合に、最後に付加する文字 char を指定し - ます。半角スペース「" "」などの単語を区切る文字を指定すれば、連続して - 入力する際に便利です。 - - 使用例: - - require "readline" - - Readline.readline("> ", true) - Readline.completion_append_character = " " - - 実行例: - - > - ここで "/var/li" を入力します。 - - > /var/li - ここで TAB キーを入力します。 - - > /var/lib - "b" が補完され、最後に " " が追加されるので、"/usr" を連続して入力できます。 - - > /var/lib /usr - - なお、1文字しか指定することはできません。 - 例えば、"string"を指定した場合は最初の文字である"s"だけを使用します。 - - require "readline" - - Readline.completion_append_character = "string" - p Readline.completion_append_character # => "s" - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completion_append_character -> char - - ユーザの入力の補完が完了した場合に、最後に付加する文字を取得します。 - デフォルトは空白 (" ") です。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.basic_word_break_characters = string - - ユーザの入力の補完を行う際、単語の区切りを示す複数の文字で構成される - 文字列 string を指定します。 - - GNU Readline のデフォルトの値は、Bash の補完処理で使用している文字列 - " \t\n\"\\'`@$><=;|&{(" (スペースを含む) になっています。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.basic_word_break_characters -> string - - ユーザの入力の補完を行う際、単語の区切りを示す複数の文字で構成される - 文字列を取得します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completer_word_break_characters = string - - ユーザの入力の補完を行う際、単語の区切りを示す複数の文字で構成される - 文字列 string を指定します。 - Readline.basic_word_break_characters= との違いは、 - GNU Readline の rl_complete_internal 関数で使用されることです。 - - GNU Readline のデフォルトの値は、 - Readline.basic_word_break_characters と同じです。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completer_word_break_characters -> string - - ユーザの入力の補完を行う際、単語の区切りを示す複数の文字で構成された - 文字列を取得します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.basic_quote_characters = string - - スペースなどの単語の区切りをクオートするための複数の文字で構成される - 文字列 string を指定します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.basic_quote_characters -> string - - スペースなどの単語の区切りをクオートするための複数の文字で構成される - 文字列を取得します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completer_quote_characters = string - - ユーザの入力の補完を行う際、スペースなどの単語の区切りを - クオートするための複数の文字で構成される文字列 string を指定します。 - 指定した文字の間では、Readline.completer_word_break_characters= - で指定した文字列に含まれる文字も、普通の文字列として扱われます。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.completer_quote_characters -> string - - ユーザの入力の補完を行う際、スペースなどの単語の区切りを - クオートするための複数の文字で構成される文字列を取得します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.filename_quote_characters = string - - ユーザの入力時にファイル名の補完を行う際、スペースなどの単語の区切りを - クオートするための複数の文字で構成される文字列 string を指定します。 - - GNU Readline のデフォルト値は nil です。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -Readline.filename_quote_characters -> string - - ユーザの入力時にファイル名の補完を行う際、スペースなどの単語の区切りを - クオートするための複数の文字で構成される文字列を取得します。 - - サポートしていない環境では、例外 NotImplementedError が発生します。 - -=== クラス定数 - -HISTORY - - 定数 HISTORY を使用してヒストリにアクセスできます。 - Enumerable モジュールを extend しており、 - 配列のように振る舞うことができます。 - 例えば、HISTORY[4] により 5 番目に入力した内容を取り出すことができます。 - - require "readline" - - Readline::HISTORY.push("a", "b", "c", "d", "e") - p Readline::HISTORY[4] # => "e" - - 実装しているメソッドを次に挙げます。 - * HISTORY.to_s -> "HISTORY" - * HISTORY[index] -> string - * HISTORY[index] = string - * HISTORY.push(string[, string, ...]) -> self - * HISTORY << string -> self - * HISTORY.pop -> string - * HISTORY.shift -> string - * HISTORY.each -> Enumerator - * HISTORY.each { |i| } -> [string] - * HISTORY.length -> Integer - * HISTORY.empty? -> true or false - * HISTORY.delete_at(index) -> string - * HISTORY.clear -> self - - サポートしていない環境では、次のメソッドで例外 NotImplementedError が - 発生します。 - * HISTORY[index] = string - * HISTORY.pop -> string - * HISTORY.shift -> string - * HISTORY.delete_at(index) -> string - * HISTORY.clear -> self - -FILENAME_COMPLETION_PROC - - ファイル名の補完を行う call メソッドを持つオブジェクトです。 - - Readline.completion_proc= により、ユーザの入力時にファイル名の補完を - 行うように設定するために使用することを想定してます。 - -USERNAME_COMPLETION_PROC - - ユーザ名の補完を行う call メソッドを持つオブジェクトです。 - - Readline.completion_proc= により、ユーザの入力時にユーザ名の補完を行 - うように設定するために使用することを想定してます。 - -VERSION - - 使用している GNU Readline または libedit のバージョンです。 diff --git a/ext/readline/depend b/ext/readline/depend deleted file mode 100644 index a95a9dc8bb..0000000000 --- a/ext/readline/depend +++ /dev/null @@ -1,175 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -readline.o: $(RUBY_EXTCONF_H) -readline.o: $(arch_hdrdir)/ruby/config.h -readline.o: $(hdrdir)/ruby/assert.h -readline.o: $(hdrdir)/ruby/backward.h -readline.o: $(hdrdir)/ruby/backward/2/assume.h -readline.o: $(hdrdir)/ruby/backward/2/attributes.h -readline.o: $(hdrdir)/ruby/backward/2/bool.h -readline.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -readline.o: $(hdrdir)/ruby/backward/2/inttypes.h -readline.o: $(hdrdir)/ruby/backward/2/limits.h -readline.o: $(hdrdir)/ruby/backward/2/long_long.h -readline.o: $(hdrdir)/ruby/backward/2/stdalign.h -readline.o: $(hdrdir)/ruby/backward/2/stdarg.h -readline.o: $(hdrdir)/ruby/defines.h -readline.o: $(hdrdir)/ruby/encoding.h -readline.o: $(hdrdir)/ruby/intern.h -readline.o: $(hdrdir)/ruby/internal/anyargs.h -readline.o: $(hdrdir)/ruby/internal/arithmetic.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/char.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/double.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/int.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/long.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/short.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -readline.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -readline.o: $(hdrdir)/ruby/internal/assume.h -readline.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -readline.o: $(hdrdir)/ruby/internal/attr/artificial.h -readline.o: $(hdrdir)/ruby/internal/attr/cold.h -readline.o: $(hdrdir)/ruby/internal/attr/const.h -readline.o: $(hdrdir)/ruby/internal/attr/constexpr.h -readline.o: $(hdrdir)/ruby/internal/attr/deprecated.h -readline.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -readline.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -readline.o: $(hdrdir)/ruby/internal/attr/error.h -readline.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -readline.o: $(hdrdir)/ruby/internal/attr/forceinline.h -readline.o: $(hdrdir)/ruby/internal/attr/format.h -readline.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -readline.o: $(hdrdir)/ruby/internal/attr/noalias.h -readline.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -readline.o: $(hdrdir)/ruby/internal/attr/noexcept.h -readline.o: $(hdrdir)/ruby/internal/attr/noinline.h -readline.o: $(hdrdir)/ruby/internal/attr/nonnull.h -readline.o: $(hdrdir)/ruby/internal/attr/noreturn.h -readline.o: $(hdrdir)/ruby/internal/attr/pure.h -readline.o: $(hdrdir)/ruby/internal/attr/restrict.h -readline.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -readline.o: $(hdrdir)/ruby/internal/attr/warning.h -readline.o: $(hdrdir)/ruby/internal/attr/weakref.h -readline.o: $(hdrdir)/ruby/internal/cast.h -readline.o: $(hdrdir)/ruby/internal/compiler_is.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -readline.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -readline.o: $(hdrdir)/ruby/internal/compiler_since.h -readline.o: $(hdrdir)/ruby/internal/config.h -readline.o: $(hdrdir)/ruby/internal/constant_p.h -readline.o: $(hdrdir)/ruby/internal/core.h -readline.o: $(hdrdir)/ruby/internal/core/rarray.h -readline.o: $(hdrdir)/ruby/internal/core/rbasic.h -readline.o: $(hdrdir)/ruby/internal/core/rbignum.h -readline.o: $(hdrdir)/ruby/internal/core/rclass.h -readline.o: $(hdrdir)/ruby/internal/core/rdata.h -readline.o: $(hdrdir)/ruby/internal/core/rfile.h -readline.o: $(hdrdir)/ruby/internal/core/rhash.h -readline.o: $(hdrdir)/ruby/internal/core/robject.h -readline.o: $(hdrdir)/ruby/internal/core/rregexp.h -readline.o: $(hdrdir)/ruby/internal/core/rstring.h -readline.o: $(hdrdir)/ruby/internal/core/rstruct.h -readline.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -readline.o: $(hdrdir)/ruby/internal/ctype.h -readline.o: $(hdrdir)/ruby/internal/dllexport.h -readline.o: $(hdrdir)/ruby/internal/dosish.h -readline.o: $(hdrdir)/ruby/internal/encoding/coderange.h -readline.o: $(hdrdir)/ruby/internal/encoding/ctype.h -readline.o: $(hdrdir)/ruby/internal/encoding/encoding.h -readline.o: $(hdrdir)/ruby/internal/encoding/pathname.h -readline.o: $(hdrdir)/ruby/internal/encoding/re.h -readline.o: $(hdrdir)/ruby/internal/encoding/sprintf.h -readline.o: $(hdrdir)/ruby/internal/encoding/string.h -readline.o: $(hdrdir)/ruby/internal/encoding/symbol.h -readline.o: $(hdrdir)/ruby/internal/encoding/transcode.h -readline.o: $(hdrdir)/ruby/internal/error.h -readline.o: $(hdrdir)/ruby/internal/eval.h -readline.o: $(hdrdir)/ruby/internal/event.h -readline.o: $(hdrdir)/ruby/internal/fl_type.h -readline.o: $(hdrdir)/ruby/internal/gc.h -readline.o: $(hdrdir)/ruby/internal/glob.h -readline.o: $(hdrdir)/ruby/internal/globals.h -readline.o: $(hdrdir)/ruby/internal/has/attribute.h -readline.o: $(hdrdir)/ruby/internal/has/builtin.h -readline.o: $(hdrdir)/ruby/internal/has/c_attribute.h -readline.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -readline.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -readline.o: $(hdrdir)/ruby/internal/has/extension.h -readline.o: $(hdrdir)/ruby/internal/has/feature.h -readline.o: $(hdrdir)/ruby/internal/has/warning.h -readline.o: $(hdrdir)/ruby/internal/intern/array.h -readline.o: $(hdrdir)/ruby/internal/intern/bignum.h -readline.o: $(hdrdir)/ruby/internal/intern/class.h -readline.o: $(hdrdir)/ruby/internal/intern/compar.h -readline.o: $(hdrdir)/ruby/internal/intern/complex.h -readline.o: $(hdrdir)/ruby/internal/intern/cont.h -readline.o: $(hdrdir)/ruby/internal/intern/dir.h -readline.o: $(hdrdir)/ruby/internal/intern/enum.h -readline.o: $(hdrdir)/ruby/internal/intern/enumerator.h -readline.o: $(hdrdir)/ruby/internal/intern/error.h -readline.o: $(hdrdir)/ruby/internal/intern/eval.h -readline.o: $(hdrdir)/ruby/internal/intern/file.h -readline.o: $(hdrdir)/ruby/internal/intern/gc.h -readline.o: $(hdrdir)/ruby/internal/intern/hash.h -readline.o: $(hdrdir)/ruby/internal/intern/io.h -readline.o: $(hdrdir)/ruby/internal/intern/load.h -readline.o: $(hdrdir)/ruby/internal/intern/marshal.h -readline.o: $(hdrdir)/ruby/internal/intern/numeric.h -readline.o: $(hdrdir)/ruby/internal/intern/object.h -readline.o: $(hdrdir)/ruby/internal/intern/parse.h -readline.o: $(hdrdir)/ruby/internal/intern/proc.h -readline.o: $(hdrdir)/ruby/internal/intern/process.h -readline.o: $(hdrdir)/ruby/internal/intern/random.h -readline.o: $(hdrdir)/ruby/internal/intern/range.h -readline.o: $(hdrdir)/ruby/internal/intern/rational.h -readline.o: $(hdrdir)/ruby/internal/intern/re.h -readline.o: $(hdrdir)/ruby/internal/intern/ruby.h -readline.o: $(hdrdir)/ruby/internal/intern/select.h -readline.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -readline.o: $(hdrdir)/ruby/internal/intern/signal.h -readline.o: $(hdrdir)/ruby/internal/intern/sprintf.h -readline.o: $(hdrdir)/ruby/internal/intern/string.h -readline.o: $(hdrdir)/ruby/internal/intern/struct.h -readline.o: $(hdrdir)/ruby/internal/intern/thread.h -readline.o: $(hdrdir)/ruby/internal/intern/time.h -readline.o: $(hdrdir)/ruby/internal/intern/variable.h -readline.o: $(hdrdir)/ruby/internal/intern/vm.h -readline.o: $(hdrdir)/ruby/internal/interpreter.h -readline.o: $(hdrdir)/ruby/internal/iterator.h -readline.o: $(hdrdir)/ruby/internal/memory.h -readline.o: $(hdrdir)/ruby/internal/method.h -readline.o: $(hdrdir)/ruby/internal/module.h -readline.o: $(hdrdir)/ruby/internal/newobj.h -readline.o: $(hdrdir)/ruby/internal/rgengc.h -readline.o: $(hdrdir)/ruby/internal/scan_args.h -readline.o: $(hdrdir)/ruby/internal/special_consts.h -readline.o: $(hdrdir)/ruby/internal/static_assert.h -readline.o: $(hdrdir)/ruby/internal/stdalign.h -readline.o: $(hdrdir)/ruby/internal/stdbool.h -readline.o: $(hdrdir)/ruby/internal/symbol.h -readline.o: $(hdrdir)/ruby/internal/value.h -readline.o: $(hdrdir)/ruby/internal/value_type.h -readline.o: $(hdrdir)/ruby/internal/variable.h -readline.o: $(hdrdir)/ruby/internal/warning_push.h -readline.o: $(hdrdir)/ruby/internal/xmalloc.h -readline.o: $(hdrdir)/ruby/io.h -readline.o: $(hdrdir)/ruby/missing.h -readline.o: $(hdrdir)/ruby/onigmo.h -readline.o: $(hdrdir)/ruby/oniguruma.h -readline.o: $(hdrdir)/ruby/ruby.h -readline.o: $(hdrdir)/ruby/st.h -readline.o: $(hdrdir)/ruby/subst.h -readline.o: $(hdrdir)/ruby/thread.h -readline.o: readline.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb deleted file mode 100644 index d3e7872e65..0000000000 --- a/ext/readline/extconf.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: false -require "mkmf" - -readline = Struct.new(:headers, :extra_check).new(["stdio.h"]) - -def readline.have_header(header) - if super(header, &extra_check) - headers.push(header) - return true - else - return false - end -end - -def readline.have_var(var) - return super(var, headers) -end - -def readline.have_func(func) - return super(func, headers) -end - -def readline.have_type(type) - return super(type, headers) -end - -dir_config('curses') -dir_config('ncurses') -dir_config('termcap') -dir_config("readline") -enable_libedit = enable_config("libedit") - -have_library("user32", nil) if /cygwin/ === RUBY_PLATFORM -have_library("ncurses", "tgetnum") || - have_library("termcap", "tgetnum") || - have_library("curses", "tgetnum") - -case enable_libedit -when true - # --enable-libedit - dir_config("libedit") - unless (readline.have_header("editline/readline.h") || - readline.have_header("readline/readline.h")) && - have_library("edit", "readline") - raise "libedit not found" - end -when false - # --disable-libedit - unless ((readline.have_header("readline/readline.h") && - readline.have_header("readline/history.h")) && - have_library("readline", "readline")) - raise "readline not found" - end -else - # does not specify - unless ((readline.have_header("readline/readline.h") && - readline.have_header("readline/history.h")) && - (have_library("readline", "readline") || - have_library("edit", "readline"))) || - (readline.have_header("editline/readline.h") && - have_library("edit", "readline")) - raise "Neither readline nor libedit was found" - end -end - -readline.have_func("rl_getc") -readline.have_func("rl_getc_function") -readline.have_func("rl_filename_completion_function") -readline.have_func("rl_username_completion_function") -readline.have_func("rl_completion_matches") -readline.have_func("rl_refresh_line") -readline.have_var("rl_deprep_term_function") -readline.have_var("rl_completion_append_character") -readline.have_var("rl_completion_quote_character") -readline.have_var("rl_basic_word_break_characters") -readline.have_var("rl_completer_word_break_characters") -readline.have_var("rl_basic_quote_characters") -readline.have_var("rl_completer_quote_characters") -readline.have_var("rl_filename_quote_characters") -readline.have_var("rl_attempted_completion_over") -readline.have_var("rl_library_version") -readline.have_var("rl_editing_mode") -readline.have_var("rl_line_buffer") -readline.have_var("rl_point") -readline.have_var("rl_char_is_quoted_p") -# workaround for native windows. -/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_event_hook") -/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_sigwinch") -/mswin|bccwin/ !~ RUBY_PLATFORM && readline.have_var("rl_catch_signals") -readline.have_var("rl_pre_input_hook") -readline.have_var("rl_special_prefixes") -readline.have_func("rl_cleanup_after_signal") -readline.have_func("rl_free_line_state") -readline.have_func("rl_clear_signals") -readline.have_func("rl_set_screen_size") -readline.have_func("rl_get_screen_size") -readline.have_func("rl_vi_editing_mode") -readline.have_func("rl_emacs_editing_mode") -readline.have_func("replace_history_entry") -readline.have_func("remove_history") -readline.have_func("clear_history") -readline.have_func("rl_redisplay") -readline.have_func("rl_insert_text") -readline.have_func("rl_delete_text") -unless readline.have_type("rl_hook_func_t*") - # rl_hook_func_t is available since readline-4.2 (2001). - # Function is removed at readline-6.3 (2014). - # However, editline (NetBSD 6.1.3, 2014) doesn't have rl_hook_func_t. - $defs << "-Drl_hook_func_t=Function" -end - -create_makefile("readline") diff --git a/ext/readline/readline-ext.gemspec b/ext/readline/readline-ext.gemspec deleted file mode 100644 index 68a34ff9ce..0000000000 --- a/ext/readline/readline-ext.gemspec +++ /dev/null @@ -1,26 +0,0 @@ -Gem::Specification.new do |spec| - spec.name = "readline-ext" - spec.version = "0.1.2" - spec.authors = ["Yukihiro Matsumoto"] - spec.email = ["matz@ruby-lang.org"] - - spec.summary = %q{Provides an interface for GNU Readline and Edit Line (libedit).} - spec.description = %q{Provides an interface for GNU Readline and Edit Line (libedit).} - spec.homepage = "https://github.com/ruby/readline-ext" - spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.extensions = %w[ext/readline/extconf.rb] - - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = spec.homepage - - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] - - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake" - spec.add_development_dependency "rake-compiler" -end diff --git a/ext/readline/readline.c b/ext/readline/readline.c deleted file mode 100644 index 8d635fce89..0000000000 --- a/ext/readline/readline.c +++ /dev/null @@ -1,2145 +0,0 @@ -/************************************************ - - readline.c - GNU Readline module - - $Author$ - created at: Wed Jan 20 13:59:32 JST 1999 - - Copyright (C) 1997-2008 Shugo Maeda - Copyright (C) 2008-2013 Kouji Takao - - $Id$ - - Contact: - - Kouji Takao <kouji dot takao at gmail dot com> (current maintainer) - -************************************************/ - -#ifdef RUBY_EXTCONF_H -#include RUBY_EXTCONF_H -#endif - -#include "ruby/config.h" -#include <errno.h> -#include <stdio.h> -#include <string.h> -#ifdef HAVE_READLINE_READLINE_H -#include <readline/readline.h> -#endif -#ifdef HAVE_READLINE_HISTORY_H -#include <readline/history.h> -#endif -#ifdef HAVE_EDITLINE_READLINE_H -#include <editline/readline.h> -#endif - -#include "ruby/io.h" -#include "ruby/thread.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -static VALUE mReadline; - -#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper" -#ifndef USE_INSERT_IGNORE_ESCAPE -# if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE) -# define USE_INSERT_IGNORE_ESCAPE 1 -# else -# define USE_INSERT_IGNORE_ESCAPE 0 -# endif -#endif - -#define COMPLETION_PROC "completion_proc" -#define COMPLETION_CASE_FOLD "completion_case_fold" -static ID id_call, completion_proc, completion_case_fold; -#if defined HAVE_RL_CHAR_IS_QUOTED_P -#define QUOTING_DETECTION_PROC "quoting_detection_proc" -static ID quoting_detection_proc; -#endif -#if USE_INSERT_IGNORE_ESCAPE -static ID id_orig_prompt, id_last_prompt; -#endif -#if defined(HAVE_RL_PRE_INPUT_HOOK) -static ID id_pre_input_hook; -#endif -#if defined(HAVE_RL_SPECIAL_PREFIXES) -static ID id_special_prefixes; -#endif - -#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION -# define rl_filename_completion_function filename_completion_function -#endif -#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION -# define rl_username_completion_function username_completion_function -#else -RUBY_EXTERN char *rl_username_completion_function(const char *, int); -#endif -#ifndef HAVE_RL_COMPLETION_MATCHES -# define rl_completion_matches completion_matches -#endif - -static int (*history_get_offset_func)(int); -static int (*history_replace_offset_func)(int); -#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER -static int readline_completion_append_character; -#endif - -static char **readline_attempted_completion_function(const char *text, - int start, int end); - -#define OutputStringValue(str) do {\ - StringValueCStr(str);\ - (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\ -} while (0)\ - - -/* - * Document-class: Readline - * - * The Readline module provides interface for GNU Readline. - * This module defines a number of methods to facilitate completion - * and accesses input history from the Ruby interpreter. - * This module supported Edit Line(libedit) too. - * libedit is compatible with GNU Readline. - * - * GNU Readline:: http://www.gnu.org/directory/readline.html - * libedit:: http://www.thrysoee.dk/editline/ - * - * Reads one inputted line with line edit by Readline.readline method. - * At this time, the facilitatation completion and the key - * bind like Emacs can be operated like GNU Readline. - * - * require "readline" - * while buf = Readline.readline("> ", true) - * p buf - * end - * - * The content that the user input can be recorded to the history. - * The history can be accessed by Readline::HISTORY constant. - * - * require "readline" - * while buf = Readline.readline("> ", true) - * p Readline::HISTORY.to_a - * print("-> ", buf, "\n") - * end - * - * Documented by Kouji Takao <kouji dot takao at gmail dot com>. - */ - -static VALUE readline_instream; -static VALUE readline_outstream; -static FILE *readline_rl_instream; -static FILE *readline_rl_outstream; - -static void -mustbe_callable(VALUE proc) -{ - if (!NIL_P(proc) && !rb_respond_to(proc, id_call)) - rb_raise(rb_eArgError, "argument must respond to `call'"); -} - -#if defined HAVE_RL_GETC_FUNCTION - -#ifndef HAVE_RL_GETC -#define rl_getc(f) EOF -#endif - -struct getc_struct { - FILE *input; - int fd; - int ret; - int err; -}; - -static int -getc_body(struct getc_struct *p) -{ - char ch; - ssize_t ss; - -#if defined(_WIN32) - { - INPUT_RECORD ir; - DWORD n; - static int prior_key = '0'; - for (;;) { - HANDLE h; - if (prior_key > 0xff) { - prior_key = rl_getc(p->input); - return prior_key; - } - h = (HANDLE)_get_osfhandle(p->fd); - if (PeekConsoleInput(h, &ir, 1, &n)) { - if (n == 1) { - if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { - prior_key = rl_getc(p->input); - return prior_key; - } else { - ReadConsoleInput(h, &ir, 1, &n); - } - } else { - rb_w32_wait_events_blocking(&h, 1, INFINITE); - } - } else { - break; - } - } - } -#endif - - ss = read(p->fd, &ch, 1); - if (ss == 0) { - errno = 0; - return EOF; - } - if (ss != 1) - return EOF; - return (unsigned char)ch; -} - -static void * -getc_func(void *data1) -{ - struct getc_struct *p = data1; - errno = 0; - p->ret = getc_body(p); - p->err = errno; - return NULL; -} - -static int -readline_getc(FILE *input) -{ - struct getc_struct data; - if (input == NULL) /* editline may give NULL as input. */ - input = stdin; - data.input = input; - data.fd = fileno(input); - again: - data.ret = EOF; - data.err = EINTR; /* getc_func is not called if already interrupted. */ - rb_thread_call_without_gvl2(getc_func, &data, RUBY_UBF_IO, NULL); - if (data.ret == EOF) { - if (data.err == 0) { - return EOF; - } - if (data.err == EINTR) { - rb_thread_check_ints(); - goto again; - } - if (data.err == EWOULDBLOCK || data.err == EAGAIN) { - int ret; - if (fileno(input) != data.fd) - rb_bug("readline_getc: input closed unexpectedly or memory corrupted"); - ret = rb_wait_for_single_fd(data.fd, RB_WAITFD_IN, NULL); - if (ret != -1 || errno == EINTR) - goto again; - rb_sys_fail("rb_wait_for_single_fd"); - } - rb_syserr_fail(data.err, "read"); - } - return data.ret; -} - -#elif defined HAVE_RL_EVENT_HOOK -#define BUSY_WAIT 0 - -static int readline_event(void); -static int -readline_event(void) -{ -#if BUSY_WAIT - rb_thread_schedule(); -#else - rb_wait_for_single_fd(fileno(rl_instream), RB_WAITFD_IN, NULL); - return 0; -#endif -} -#endif - -#if USE_INSERT_IGNORE_ESCAPE -static VALUE -insert_ignore_escape(VALUE self, VALUE prompt) -{ - VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt); - int ignoring = 0; - const char *s0, *s, *e; - long len; - static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE}; - - prompt = rb_str_new_shared(prompt); - last_prompt = rb_attr_get(self, id_last_prompt); - if (orig_prompt == prompt) return last_prompt; - len = RSTRING_LEN(prompt); - if (NIL_P(last_prompt)) { - last_prompt = rb_str_tmp_new(len); - } - - s = s0 = RSTRING_PTR(prompt); - e = s0 + len; - rb_str_set_len(last_prompt, 0); - while (s < e && *s) { - switch (*s) { - case RL_PROMPT_START_IGNORE: - ignoring = -1; - rb_str_cat(last_prompt, s0, ++s - s0); - s0 = s; - break; - case RL_PROMPT_END_IGNORE: - ignoring = 0; - rb_str_cat(last_prompt, s0, ++s - s0); - s0 = s; - break; - case '\033': - if (++s < e && *s == '[') { - rb_str_cat(last_prompt, s0, s - s0 - 1); - s0 = s - 1; - while (++s < e && *s) { - if (ISALPHA(*(unsigned char *)s)) { - if (!ignoring) { - ignoring = 1; - rb_str_cat(last_prompt, ignore_code+0, 1); - } - rb_str_cat(last_prompt, s0, ++s - s0); - s0 = s; - break; - } - else if (!(('0' <= *s && *s <= '9') || *s == ';')) { - break; - } - } - } - break; - default: - if (ignoring > 0) { - ignoring = 0; - rb_str_cat(last_prompt, ignore_code+1, 1); - } - s++; - break; - } - } - if (ignoring > 0) { - ignoring = 0; - rb_str_cat(last_prompt, ignore_code+1, 1); - } - rb_str_cat(last_prompt, s0, s - s0); - - rb_ivar_set(self, id_orig_prompt, prompt); - rb_ivar_set(self, id_last_prompt, last_prompt); - - return last_prompt; -} -#endif - -static VALUE -readline_get(VALUE prompt) -{ -#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - readline_completion_append_character = rl_completion_append_character; -#endif - return (VALUE)readline((char *)prompt); -} - -static void -clear_rl_instream(void) -{ - if (readline_rl_instream) { - fclose(readline_rl_instream); - if (rl_instream == readline_rl_instream) - rl_instream = NULL; - readline_rl_instream = NULL; - } - readline_instream = Qfalse; -} - -static void -clear_rl_outstream(void) -{ - if (readline_rl_outstream) { - fclose(readline_rl_outstream); - if (rl_outstream == readline_rl_outstream) - rl_outstream = NULL; - readline_rl_outstream = NULL; - } - readline_outstream = Qfalse; -} - -static void -prepare_readline(void) -{ - static int initialized = 0; - if (!initialized) { - rl_initialize(); - initialized = 1; - } - - if (readline_instream) { - rb_io_t *ifp; - rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr); - if (ifp->fd < 0) { - clear_rl_instream(); - rb_raise(rb_eIOError, "closed readline input"); - } - } - - if (readline_outstream) { - rb_io_t *ofp; - rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr); - if (ofp->fd < 0) { - clear_rl_outstream(); - rb_raise(rb_eIOError, "closed readline output"); - } - } -} - -/* - * call-seq: - * Readline.readline(prompt = "", add_hist = false) -> string or nil - * - * Shows the +prompt+ and reads the inputted line with line editing. - * The inputted line is added to the history if +add_hist+ is true. - * - * Returns nil when the inputted line is empty and user inputs EOF - * (Presses ^D on UNIX). - * - * Raises IOError exception if one of below conditions are satisfied. - * 1. stdin was closed. - * 2. stdout was closed. - * - * This method supports thread. Switches the thread context when waits - * inputting line. - * - * Supports line edit when inputs line. Provides VI and Emacs editing mode. - * Default is Emacs editing mode. - * - * NOTE: Terminates ruby interpreter and does not return the terminal - * status after user pressed '^C' when wait inputting line. - * Give 3 examples that avoid it. - * - * * Catches the Interrupt exception by pressed ^C after returns - * terminal status: - * - * require "readline" - * - * stty_save = `stty -g`.chomp - * begin - * while buf = Readline.readline - * p buf - * end - * rescue Interrupt - * system("stty", stty_save) - * exit - * end - * end - * end - * - * * Catches the INT signal by pressed ^C after returns terminal - * status: - * - * require "readline" - * - * stty_save = `stty -g`.chomp - * trap("INT") { system "stty", stty_save; exit } - * - * while buf = Readline.readline - * p buf - * end - * - * * Ignores pressing ^C: - * - * require "readline" - * - * trap("INT", "SIG_IGN") - * - * while buf = Readline.readline - * p buf - * end - * - * Can make as follows with Readline::HISTORY constant. - * It does not record to the history if the inputted line is empty or - * the same it as last one. - * - * require "readline" - * - * while buf = Readline.readline("> ", true) - * # p Readline::HISTORY.to_a - * Readline::HISTORY.pop if /^\s*$/ =~ buf - * - * begin - * if Readline::HISTORY[Readline::HISTORY.length-2] == buf - * Readline::HISTORY.pop - * end - * rescue IndexError - * end - * - * # p Readline::HISTORY.to_a - * print "-> ", buf, "\n" - * end - */ -static VALUE -readline_readline(int argc, VALUE *argv, VALUE self) -{ - VALUE tmp, add_hist, result; - char *prompt = NULL; - char *buff; - int status; - - if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) { - OutputStringValue(tmp); -#if USE_INSERT_IGNORE_ESCAPE - tmp = insert_ignore_escape(self, tmp); - rb_str_locktmp(tmp); -#endif - prompt = RSTRING_PTR(tmp); - } - - prepare_readline(); - -#ifdef _WIN32 - rl_prep_terminal(1); -#endif - buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status); -#if USE_INSERT_IGNORE_ESCAPE - if (prompt) { - rb_str_unlocktmp(tmp); - } -#endif - if (status) { -#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL - /* restore terminal mode and signal handler*/ -#if defined HAVE_RL_FREE_LINE_STATE - rl_free_line_state(); -#endif - rl_cleanup_after_signal(); -#elif defined HAVE_RL_DEPREP_TERM_FUNCTION - /* restore terminal mode */ - if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */ - (*rl_deprep_term_function)(); - else -#else - rl_deprep_terminal(); -#endif - rb_jump_tag(status); - } - - if (RTEST(add_hist) && buff) { - add_history(buff); - } - if (buff) { - result = rb_locale_str_new_cstr(buff); - } - else - result = Qnil; - if (buff) free(buff); - return result; -} - -/* - * call-seq: - * Readline.input = input - * - * Specifies a File object +input+ that is input stream for - * Readline.readline method. - */ -static VALUE -readline_s_set_input(VALUE self, VALUE input) -{ - rb_io_t *ifp; - int fd; - FILE *f; - - if (NIL_P(input)) { - clear_rl_instream(); - } - else { - Check_Type(input, T_FILE); - GetOpenFile(input, ifp); - clear_rl_instream(); - fd = rb_cloexec_dup(ifp->fd); - if (fd == -1) - rb_sys_fail("dup"); - f = fdopen(fd, "r"); - if (f == NULL) { - int save_errno = errno; - close(fd); - rb_syserr_fail(save_errno, "fdopen"); - } - rl_instream = readline_rl_instream = f; - readline_instream = input; - } - return input; -} - -/* - * call-seq: - * Readline.output = output - * - * Specifies a File object +output+ that is output stream for - * Readline.readline method. - */ -static VALUE -readline_s_set_output(VALUE self, VALUE output) -{ - rb_io_t *ofp; - int fd; - FILE *f; - - if (NIL_P(output)) { - clear_rl_outstream(); - } - else { - Check_Type(output, T_FILE); - GetOpenFile(output, ofp); - clear_rl_outstream(); - fd = rb_cloexec_dup(ofp->fd); - if (fd == -1) - rb_sys_fail("dup"); - f = fdopen(fd, "w"); - if (f == NULL) { - int save_errno = errno; - close(fd); - rb_syserr_fail(save_errno, "fdopen"); - } - rl_outstream = readline_rl_outstream = f; - readline_outstream = output; - } - return output; -} - -#if defined(HAVE_RL_PRE_INPUT_HOOK) -/* - * call-seq: - * Readline.pre_input_hook = proc - * - * Specifies a Proc object +proc+ to call after the first prompt has - * been printed and just before readline starts reading input - * characters. - * - * See GNU Readline's rl_pre_input_hook variable. - * - * Raises ArgumentError if +proc+ does not respond to the call method. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_pre_input_hook(VALUE self, VALUE proc) -{ - mustbe_callable(proc); - return rb_ivar_set(mReadline, id_pre_input_hook, proc); -} - -/* - * call-seq: - * Readline.pre_input_hook -> proc - * - * Returns a Proc object +proc+ to call after the first prompt has - * been printed and just before readline starts reading input - * characters. The default is nil. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_pre_input_hook(VALUE self) -{ - return rb_attr_get(mReadline, id_pre_input_hook); -} - -static int -readline_pre_input_hook(void) -{ - VALUE proc; - - proc = rb_attr_get(mReadline, id_pre_input_hook); - if (!NIL_P(proc)) - rb_funcall(proc, id_call, 0); - return 0; -} -#else -#define readline_s_set_pre_input_hook rb_f_notimplement -#define readline_s_get_pre_input_hook rb_f_notimplement -#endif - -#if defined(HAVE_RL_INSERT_TEXT) -/* - * call-seq: - * Readline.insert_text(string) -> self - * - * Insert text into the line at the current cursor position. - * - * See GNU Readline's rl_insert_text function. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_insert_text(VALUE self, VALUE str) -{ - OutputStringValue(str); - rl_insert_text(RSTRING_PTR(str)); - return self; -} -#else -#define readline_s_insert_text rb_f_notimplement -#endif - -#if defined(HAVE_RL_DELETE_TEXT) -RUBY_EXTERN int rl_delete_text(int, int); -static const char * -str_subpos(const char *ptr, const char *end, long beg, long *sublen, rb_encoding *enc) -{ - VALUE str = rb_enc_str_new_static(ptr, end-ptr, enc); - OBJ_FREEZE(str); - ptr = rb_str_subpos(str, beg, sublen); - rb_gc_force_recycle(str); - return ptr; -} - -/* - * call-seq: - * Readline.delete_text([start[, length]]) -> self - * Readline.delete_text(start..end) -> self - * Readline.delete_text() -> self - * - * Delete text between start and end in the current line. - * - * See GNU Readline's rl_delete_text function. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_delete_text(int argc, VALUE *argv, VALUE self) -{ - rb_check_arity(argc, 0, 2); - if (rl_line_buffer) { - const char *p, *ptr = rl_line_buffer; - long beg = 0, len = strlen(ptr); - const char *end = ptr + len; - rb_encoding *enc = rb_locale_encoding(); - if (argc == 2) { - beg = NUM2LONG(argv[0]); - len = NUM2LONG(argv[1]); - num_pos: - p = str_subpos(ptr, end, beg, &len, enc); - if (!p) rb_raise(rb_eArgError, "invalid index"); - beg = p - ptr; - } - else if (argc == 1) { - len = rb_enc_strlen(ptr, ptr + len, enc); - if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) { - beg = NUM2LONG(argv[0]); - goto num_pos; - } - } - rl_delete_text(rb_long2int(beg), rb_long2int(beg + len)); - } - return self; -} -#else -#define readline_s_delete_text rb_f_notimplement -#endif - -#if defined(HAVE_RL_REDISPLAY) -/* - * call-seq: - * Readline.redisplay -> self - * - * Change what's displayed on the screen to reflect the current - * contents. - * - * See GNU Readline's rl_redisplay function. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_redisplay(VALUE self) -{ - rl_redisplay(); - return self; -} -#else -#define readline_s_redisplay rb_f_notimplement -#endif - -/* - * call-seq: - * Readline.completion_proc = proc - * - * Specifies a Proc object +proc+ to determine completion behavior. It - * should take input string and return an array of completion candidates. - * - * The default completion is used if +proc+ is nil. - * - * The String that is passed to the Proc depends on the - * Readline.completer_word_break_characters property. By default the word - * under the cursor is passed to the Proc. For example, if the input is "foo - * bar" then only "bar" would be passed to the completion Proc. - * - * Upon successful completion the Readline.completion_append_character will be - * appended to the input so the user can start working on their next argument. - * - * = Examples - * - * == Completion for a Static List - * - * require 'readline' - * - * LIST = [ - * 'search', 'download', 'open', - * 'help', 'history', 'quit', - * 'url', 'next', 'clear', - * 'prev', 'past' - * ].sort - * - * comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) } - * - * Readline.completion_append_character = " " - * Readline.completion_proc = comp - * - * while line = Readline.readline('> ', true) - * p line - * end - * - * == Completion For Directory Contents - * - * require 'readline' - * - * Readline.completion_append_character = " " - * Readline.completion_proc = Proc.new do |str| - * Dir[str+'*'].grep(/^#{Regexp.escape(str)}/) - * end - * - * while line = Readline.readline('> ', true) - * p line - * end - * - * = Autocomplete strategies - * - * When working with auto-complete there are some strategies that work well. - * To get some ideas you can take a look at the - * completion.rb[https://git.ruby-lang.org/ruby.git/tree/lib/irb/completion.rb] - * file for irb. - * - * The common strategy is to take a list of possible completions and filter it - * down to those completions that start with the user input. In the above - * examples Enumerator.grep is used. The input is escaped to prevent Regexp - * special characters from interfering with the matching. - * - * It may also be helpful to use the Abbrev library to generate completions. - * - * Raises ArgumentError if +proc+ does not respond to the call method. - */ -static VALUE -readline_s_set_completion_proc(VALUE self, VALUE proc) -{ - mustbe_callable(proc); - return rb_ivar_set(mReadline, completion_proc, proc); -} - -/* - * call-seq: - * Readline.completion_proc -> proc - * - * Returns the completion Proc object. - */ -static VALUE -readline_s_get_completion_proc(VALUE self) -{ - return rb_attr_get(mReadline, completion_proc); -} - -#ifdef HAVE_RL_CHAR_IS_QUOTED_P -/* - * call-seq: - * Readline.quoting_detection_proc = proc - * - * Specifies a Proc object +proc+ to determine if a character in the user's - * input is escaped. It should take the user's input and the index of the - * character in question as input, and return a boolean (true if the specified - * character is escaped). - * - * Readline will only call this proc with characters specified in - * +completer_quote_characters+, to discover if they indicate the end of a - * quoted argument, or characters specified in - * +completer_word_break_characters+, to discover if they indicate a break - * between arguments. - * - * If +completer_quote_characters+ is not set, or if the user input doesn't - * contain one of the +completer_quote_characters+ or a +\+ character, - * Readline will not attempt to use this proc at all. - * - * Raises ArgumentError if +proc+ does not respond to the call method. - */ -static VALUE -readline_s_set_quoting_detection_proc(VALUE self, VALUE proc) -{ - mustbe_callable(proc); - return rb_ivar_set(mReadline, quoting_detection_proc, proc); -} - -/* - * call-seq: - * Readline.quoting_detection_proc -> proc - * - * Returns the quoting detection Proc object. - */ -static VALUE -readline_s_get_quoting_detection_proc(VALUE self) -{ - return rb_attr_get(mReadline, quoting_detection_proc); -} -#else -#define readline_s_set_quoting_detection_proc rb_f_notimplement -#define readline_s_get_quoting_detection_proc rb_f_notimplement -#endif - -/* - * call-seq: - * Readline.completion_case_fold = bool - * - * Sets whether or not to ignore case on completion. - */ -static VALUE -readline_s_set_completion_case_fold(VALUE self, VALUE val) -{ - return rb_ivar_set(mReadline, completion_case_fold, val); -} - -/* - * call-seq: - * Readline.completion_case_fold -> bool - * - * Returns true if completion ignores case. If no, returns false. - * - * NOTE: Returns the same object that is specified by - * Readline.completion_case_fold= method. - * - * require "readline" - * - * Readline.completion_case_fold = "This is a String." - * p Readline.completion_case_fold # => "This is a String." - */ -static VALUE -readline_s_get_completion_case_fold(VALUE self) -{ - return rb_attr_get(mReadline, completion_case_fold); -} - -#ifdef HAVE_RL_LINE_BUFFER -/* - * call-seq: - * Readline.line_buffer -> string - * - * Returns the full line that is being edited. This is useful from - * within the complete_proc for determining the context of the - * completion request. - * - * The length of +Readline.line_buffer+ and GNU Readline's rl_end are - * same. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_line_buffer(VALUE self) -{ - if (rl_line_buffer == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_line_buffer); -} -#else -#define readline_s_get_line_buffer rb_f_notimplement -#endif - -#ifdef HAVE_RL_POINT -/* - * call-seq: - * Readline.point -> int - * - * Returns the index of the current cursor position in - * +Readline.line_buffer+. - * - * The index in +Readline.line_buffer+ which matches the start of - * input-string passed to completion_proc is computed by subtracting - * the length of input-string from +Readline.point+. - * - * start = (the length of input-string) - Readline.point - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_point(VALUE self) -{ - return INT2NUM(rl_point); -} - -/* - * call-seq: - * Readline.point = int - * - * Set the index of the current cursor position in - * +Readline.line_buffer+. - * - * Raises NotImplementedError if the using readline library does not support. - * - * See +Readline.point+. - */ -static VALUE -readline_s_set_point(VALUE self, VALUE pos) -{ - rl_point = NUM2INT(pos); - return pos; -} -#else -#define readline_s_get_point rb_f_notimplement -#define readline_s_set_point rb_f_notimplement -#endif - -static char ** -readline_attempted_completion_function(const char *text, int start, int end) -{ - VALUE proc, ary, temp; - char **result; - int case_fold; - long i, matches; - rb_encoding *enc; - VALUE encobj; - - proc = rb_attr_get(mReadline, completion_proc); - if (NIL_P(proc)) - return NULL; -#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - rl_completion_append_character = readline_completion_append_character; -#endif -#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER - rl_attempted_completion_over = 1; -#endif - case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold)); - ary = rb_funcall(proc, id_call, 1, rb_locale_str_new_cstr(text)); - if (!RB_TYPE_P(ary, T_ARRAY)) - ary = rb_Array(ary); - matches = RARRAY_LEN(ary); - if (matches == 0) return NULL; - result = (char**)malloc((matches + 2)*sizeof(char*)); - if (result == NULL) rb_memerror(); - enc = rb_locale_encoding(); - encobj = rb_enc_from_encoding(enc); - for (i = 0; i < matches; i++) { - temp = rb_obj_as_string(RARRAY_AREF(ary, i)); - StringValueCStr(temp); /* must be NUL-terminated */ - rb_enc_check(encobj, temp); - result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1); - if (result[i + 1] == NULL) rb_memerror(); - strcpy(result[i + 1], RSTRING_PTR(temp)); - } - result[matches + 1] = NULL; - - if (matches == 1) { - result[0] = strdup(result[1]); - } - else { - const char *result1 = result[1]; - long low = strlen(result1); - - for (i = 1; i < matches; ++i) { - register int c1, c2; - long i1, i2, l2; - int n1, n2; - const char *p2 = result[i + 1]; - - l2 = strlen(p2); - for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) { - c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc); - c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc); - if (case_fold) { - c1 = rb_tolower(c1); - c2 = rb_tolower(c2); - } - if (c1 != c2) break; - } - - low = i1; - } - result[0] = (char*)malloc(low + 1); - if (result[0] == NULL) rb_memerror(); - strncpy(result[0], result[1], low); - result[0][low] = '\0'; - } - - return result; -} - -#ifdef HAVE_RL_CHAR_IS_QUOTED_P -static int -readline_char_is_quoted(char *text, int byte_index) -{ - VALUE proc, result, str; - long char_index; - size_t len; - - proc = rb_attr_get(mReadline, quoting_detection_proc); - if (NIL_P(proc)) { - return 0; - } - - len = strlen(text); - if (byte_index < 0 || len < (size_t)byte_index) { - rb_raise(rb_eIndexError, "invalid byte index (%d in %"PRIdSIZE")", - byte_index, len); - } - - str = rb_locale_str_new(text, len); - char_index = rb_str_sublen(str, byte_index); - result = rb_funcall(proc, id_call, 2, str, LONG2FIX(char_index)); - return RTEST(result); -} -#endif - -#ifdef HAVE_RL_SET_SCREEN_SIZE -/* - * call-seq: - * Readline.set_screen_size(rows, columns) -> self - * - * Set terminal size to +rows+ and +columns+. - * - * See GNU Readline's rl_set_screen_size function. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns) -{ - rl_set_screen_size(NUM2INT(rows), NUM2INT(columns)); - return self; -} -#else -#define readline_s_set_screen_size rb_f_notimplement -#endif - -#ifdef HAVE_RL_GET_SCREEN_SIZE -/* - * call-seq: - * Readline.get_screen_size -> [rows, columns] - * - * Returns the terminal's rows and columns. - * - * See GNU Readline's rl_get_screen_size function. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_screen_size(VALUE self) -{ - int rows, columns; - VALUE res; - - rl_get_screen_size(&rows, &columns); - res = rb_ary_new(); - rb_ary_push(res, INT2NUM(rows)); - rb_ary_push(res, INT2NUM(columns)); - return res; -} -#else -#define readline_s_get_screen_size rb_f_notimplement -#endif - -#ifdef HAVE_RL_VI_EDITING_MODE -RUBY_EXTERN int rl_vi_editing_mode(int, int); -/* - * call-seq: - * Readline.vi_editing_mode -> nil - * - * Specifies VI editing mode. See the manual of GNU Readline for - * details of VI editing mode. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_vi_editing_mode(VALUE self) -{ - rl_vi_editing_mode(1,0); - return Qnil; -} -#else -#define readline_s_vi_editing_mode rb_f_notimplement -#endif - -#ifdef HAVE_RL_EDITING_MODE -/* - * call-seq: - * Readline.vi_editing_mode? -> bool - * - * Returns true if vi mode is active. Returns false if not. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_vi_editing_mode_p(VALUE self) -{ - return rl_editing_mode == 0 ? Qtrue : Qfalse; -} -#else -#define readline_s_vi_editing_mode_p rb_f_notimplement -#endif - -#ifdef HAVE_RL_EMACS_EDITING_MODE -RUBY_EXTERN int rl_emacs_editing_mode(int, int); -/* - * call-seq: - * Readline.emacs_editing_mode -> nil - * - * Specifies Emacs editing mode. The default is this mode. See the - * manual of GNU Readline for details of Emacs editing mode. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_emacs_editing_mode(VALUE self) -{ - rl_emacs_editing_mode(1,0); - return Qnil; -} -#else -#define readline_s_emacs_editing_mode rb_f_notimplement -#endif - -#ifdef HAVE_RL_EDITING_MODE -/* - * call-seq: - * Readline.emacs_editing_mode? -> bool - * - * Returns true if emacs mode is active. Returns false if not. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_emacs_editing_mode_p(VALUE self) -{ - return rl_editing_mode == 1 ? Qtrue : Qfalse; -} -#else -#define readline_s_emacs_editing_mode_p rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER -/* - * call-seq: - * Readline.completion_append_character = char - * - * Specifies a character to be appended on completion. - * Nothing will be appended if an empty string ("") or nil is - * specified. - * - * For example: - * require "readline" - * - * Readline.readline("> ", true) - * Readline.completion_append_character = " " - * - * Result: - * > - * Input "/var/li". - * - * > /var/li - * Press TAB key. - * - * > /var/lib - * Completes "b" and appends " ". So, you can continuously input "/usr". - * - * > /var/lib /usr - * - * NOTE: Only one character can be specified. When "string" is - * specified, sets only "s" that is the first. - * - * require "readline" - * - * Readline.completion_append_character = "string" - * p Readline.completion_append_character # => "s" - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_completion_append_character(VALUE self, VALUE str) -{ - if (NIL_P(str)) { - rl_completion_append_character = '\0'; - } - else { - OutputStringValue(str); - if (RSTRING_LEN(str) == 0) { - rl_completion_append_character = '\0'; - } else { - rl_completion_append_character = RSTRING_PTR(str)[0]; - } - } - return self; -} -#else -#define readline_s_set_completion_append_character rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER -/* - * call-seq: - * Readline.completion_append_character -> char - * - * Returns a string containing a character to be appended on - * completion. The default is a space (" "). - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_completion_append_character(VALUE self) -{ - char buf[1]; - - if (rl_completion_append_character == '\0') - return Qnil; - - buf[0] = (char) rl_completion_append_character; - return rb_locale_str_new(buf, 1); -} -#else -#define readline_s_get_completion_append_character rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETION_QUOTE_CHARACTER -/* - * call-seq: - * Readline.completion_quote_character -> char - * - * When called during a completion (e.g. from within your completion_proc), - * it will return a string containing the character used to quote the - * argument being completed, or nil if the argument is unquoted. - * - * When called at other times, it will always return nil. - * - * Note that Readline.completer_quote_characters must be set, - * or this method will always return nil. - */ -static VALUE -readline_s_get_completion_quote_character(VALUE self) -{ - char buf[1]; - - if (rl_completion_quote_character == '\0') - return Qnil; - - buf[0] = (char) rl_completion_quote_character; - return rb_locale_str_new(buf, 1); -} -#else -#define readline_s_get_completion_quote_character rb_f_notimplement -#endif - -#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS -/* - * call-seq: - * Readline.basic_word_break_characters = string - * - * Sets the basic list of characters that signal a break between words - * for the completer routine. The default is the characters which - * break words for completion in Bash: " \t\n\"\\'`@$><=;|&{(". - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_basic_word_break_characters(VALUE self, VALUE str) -{ - static char *basic_word_break_characters = NULL; - - OutputStringValue(str); - if (basic_word_break_characters == NULL) { - basic_word_break_characters = - ALLOC_N(char, RSTRING_LEN(str) + 1); - } - else { - REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1); - } - strncpy(basic_word_break_characters, - RSTRING_PTR(str), RSTRING_LEN(str)); - basic_word_break_characters[RSTRING_LEN(str)] = '\0'; - rl_basic_word_break_characters = basic_word_break_characters; - return self; -} -#else -#define readline_s_set_basic_word_break_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS -/* - * call-seq: - * Readline.basic_word_break_characters -> string - * - * Gets the basic list of characters that signal a break between words - * for the completer routine. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_basic_word_break_characters(VALUE self) -{ - if (rl_basic_word_break_characters == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_basic_word_break_characters); -} -#else -#define readline_s_get_basic_word_break_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS -/* - * call-seq: - * Readline.completer_word_break_characters = string - * - * Sets the basic list of characters that signal a break between words - * for rl_complete_internal(). The default is the value of - * Readline.basic_word_break_characters. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_completer_word_break_characters(VALUE self, VALUE str) -{ - static char *completer_word_break_characters = NULL; - - OutputStringValue(str); - if (completer_word_break_characters == NULL) { - completer_word_break_characters = - ALLOC_N(char, RSTRING_LEN(str) + 1); - } - else { - REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1); - } - strncpy(completer_word_break_characters, - RSTRING_PTR(str), RSTRING_LEN(str)); - completer_word_break_characters[RSTRING_LEN(str)] = '\0'; - rl_completer_word_break_characters = completer_word_break_characters; - return self; -} -#else -#define readline_s_set_completer_word_break_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS -/* - * call-seq: - * Readline.completer_word_break_characters -> string - * - * Gets the basic list of characters that signal a break between words - * for rl_complete_internal(). - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_completer_word_break_characters(VALUE self) -{ - if (rl_completer_word_break_characters == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_completer_word_break_characters); -} -#else -#define readline_s_get_completer_word_break_characters rb_f_notimplement -#endif - -#if defined(HAVE_RL_SPECIAL_PREFIXES) -/* - * call-seq: - * Readline.special_prefixes = string - * - * Sets the list of characters that are word break characters, but - * should be left in text when it is passed to the completion - * function. Programs can use this to help determine what kind of - * completing to do. For instance, Bash sets this variable to "$@" so - * that it can complete shell variables and hostnames. - * - * See GNU Readline's rl_special_prefixes variable. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_special_prefixes(VALUE self, VALUE str) -{ - if (!NIL_P(str)) { - OutputStringValue(str); - str = rb_str_dup_frozen(str); - rb_obj_hide(str); - } - rb_ivar_set(mReadline, id_special_prefixes, str); - if (NIL_P(str)) { - rl_special_prefixes = NULL; - } - else { - rl_special_prefixes = RSTRING_PTR(str); - } - return self; -} - -/* - * call-seq: - * Readline.special_prefixes -> string - * - * Gets the list of characters that are word break characters, but - * should be left in text when it is passed to the completion - * function. - * - * See GNU Readline's rl_special_prefixes variable. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_special_prefixes(VALUE self) -{ - VALUE str; - if (rl_special_prefixes == NULL) return Qnil; - str = rb_ivar_get(mReadline, id_special_prefixes); - if (!NIL_P(str)) { - str = rb_str_dup_frozen(str); - rb_obj_reveal(str, rb_cString); - } - return str; -} -#else -#define readline_s_set_special_prefixes rb_f_notimplement -#define readline_s_get_special_prefixes rb_f_notimplement -#endif - -#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.basic_quote_characters = string - * - * Sets a list of quote characters which can cause a word break. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_basic_quote_characters(VALUE self, VALUE str) -{ - static char *basic_quote_characters = NULL; - - OutputStringValue(str); - if (basic_quote_characters == NULL) { - basic_quote_characters = - ALLOC_N(char, RSTRING_LEN(str) + 1); - } - else { - REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1); - } - strncpy(basic_quote_characters, - RSTRING_PTR(str), RSTRING_LEN(str)); - basic_quote_characters[RSTRING_LEN(str)] = '\0'; - rl_basic_quote_characters = basic_quote_characters; - - return self; -} -#else -#define readline_s_set_basic_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.basic_quote_characters -> string - * - * Gets a list of quote characters which can cause a word break. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_basic_quote_characters(VALUE self) -{ - if (rl_basic_quote_characters == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_basic_quote_characters); -} -#else -#define readline_s_get_basic_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.completer_quote_characters = string - * - * Sets a list of characters which can be used to quote a substring of - * the line. Completion occurs on the entire substring, and within - * the substring Readline.completer_word_break_characters are treated - * as any other character, unless they also appear within this list. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_completer_quote_characters(VALUE self, VALUE str) -{ - static char *completer_quote_characters = NULL; - - OutputStringValue(str); - if (completer_quote_characters == NULL) { - completer_quote_characters = - ALLOC_N(char, RSTRING_LEN(str) + 1); - } - else { - REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1); - } - strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str)); - completer_quote_characters[RSTRING_LEN(str)] = '\0'; - rl_completer_quote_characters = completer_quote_characters; - - return self; -} -#else -#define readline_s_set_completer_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.completer_quote_characters -> string - * - * Gets a list of characters which can be used to quote a substring of - * the line. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_completer_quote_characters(VALUE self) -{ - if (rl_completer_quote_characters == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_completer_quote_characters); -} -#else -#define readline_s_get_completer_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.filename_quote_characters = string - * - * Sets a list of characters that cause a filename to be quoted by the completer - * when they appear in a completed filename. The default is nil. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_set_filename_quote_characters(VALUE self, VALUE str) -{ - static char *filename_quote_characters = NULL; - - OutputStringValue(str); - if (filename_quote_characters == NULL) { - filename_quote_characters = - ALLOC_N(char, RSTRING_LEN(str) + 1); - } - else { - REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1); - } - strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str)); - filename_quote_characters[RSTRING_LEN(str)] = '\0'; - rl_filename_quote_characters = filename_quote_characters; - - return self; -} -#else -#define readline_s_set_filename_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS -/* - * call-seq: - * Readline.filename_quote_characters -> string - * - * Gets a list of characters that cause a filename to be quoted by the completer - * when they appear in a completed filename. - * - * Raises NotImplementedError if the using readline library does not support. - */ -static VALUE -readline_s_get_filename_quote_characters(VALUE self) -{ - if (rl_filename_quote_characters == NULL) - return Qnil; - return rb_locale_str_new_cstr(rl_filename_quote_characters); -} -#else -#define readline_s_get_filename_quote_characters rb_f_notimplement -#endif - -#ifdef HAVE_RL_REFRESH_LINE -RUBY_EXTERN int rl_refresh_line(int, int); -/* - * call-seq: - * Readline.refresh_line -> nil - * - * Clear the current input line. - */ -static VALUE -readline_s_refresh_line(VALUE self) -{ - prepare_readline(); - rl_refresh_line(0, 0); - return Qnil; -} -#else -#define readline_s_refresh_line rb_f_notimplement -#endif - -static VALUE -hist_to_s(VALUE self) -{ - return rb_str_new_cstr("HISTORY"); -} - -static int -history_get_offset_history_base(int offset) -{ - return history_base + offset; -} - -static int -history_get_offset_0(int offset) -{ - return offset; -} - -static VALUE -hist_get(VALUE self, VALUE index) -{ - HIST_ENTRY *entry = NULL; - int i; - - i = NUM2INT(index); - if (i < 0) { - i += history_length; - } - if (i >= 0) { - entry = history_get(history_get_offset_func(i)); - } - if (entry == NULL) { - rb_raise(rb_eIndexError, "invalid index"); - } - return rb_locale_str_new_cstr(entry->line); -} - -#ifdef HAVE_REPLACE_HISTORY_ENTRY -static VALUE -hist_set(VALUE self, VALUE index, VALUE str) -{ - HIST_ENTRY *entry = NULL; - int i; - - i = NUM2INT(index); - OutputStringValue(str); - if (i < 0) { - i += history_length; - } - if (i >= 0) { - entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL); - } - if (entry == NULL) { - rb_raise(rb_eIndexError, "invalid index"); - } - return str; -} -#else -#define hist_set rb_f_notimplement -#endif - -static VALUE -hist_push(VALUE self, VALUE str) -{ - OutputStringValue(str); - add_history(RSTRING_PTR(str)); - return self; -} - -static VALUE -hist_push_method(int argc, VALUE *argv, VALUE self) -{ - VALUE str; - - while (argc--) { - str = *argv++; - OutputStringValue(str); - add_history(RSTRING_PTR(str)); - } - return self; -} - -static VALUE -rb_remove_history(int index) -{ -#ifdef HAVE_REMOVE_HISTORY - HIST_ENTRY *entry; - VALUE val; - - entry = remove_history(index); - if (entry) { - val = rb_locale_str_new_cstr(entry->line); - free((void *) entry->line); - free(entry); - return val; - } - return Qnil; -#else - rb_notimplement(); - - UNREACHABLE_RETURN(Qnil); -#endif -} - -static VALUE -hist_pop(VALUE self) -{ - if (history_length > 0) { - return rb_remove_history(history_length - 1); - } else { - return Qnil; - } -} - -static VALUE -hist_shift(VALUE self) -{ - if (history_length > 0) { - return rb_remove_history(0); - } else { - return Qnil; - } -} - -static VALUE -hist_each(VALUE self) -{ - HIST_ENTRY *entry; - int i; - - RETURN_ENUMERATOR(self, 0, 0); - - for (i = 0; i < history_length; i++) { - entry = history_get(history_get_offset_func(i)); - if (entry == NULL) - break; - rb_yield(rb_locale_str_new_cstr(entry->line)); - } - return self; -} - -static VALUE -hist_length(VALUE self) -{ - return INT2NUM(history_length); -} - -static VALUE -hist_empty_p(VALUE self) -{ - return history_length == 0 ? Qtrue : Qfalse; -} - -static VALUE -hist_delete_at(VALUE self, VALUE index) -{ - int i; - - i = NUM2INT(index); - if (i < 0) - i += history_length; - if (i < 0 || i > history_length - 1) { - rb_raise(rb_eIndexError, "invalid index"); - } - return rb_remove_history(i); -} - -#ifdef HAVE_CLEAR_HISTORY -static VALUE -hist_clear(VALUE self) -{ - clear_history(); - return self; -} -#else -#define hist_clear rb_f_notimplement -#endif - -static VALUE -filename_completion_proc_call(VALUE self, VALUE str) -{ - VALUE result; - char **matches; - int i; - - matches = rl_completion_matches(StringValuePtr(str), - rl_filename_completion_function); - if (matches) { - result = rb_ary_new(); - for (i = 0; matches[i]; i++) { - rb_ary_push(result, rb_locale_str_new_cstr(matches[i])); - free(matches[i]); - } - free(matches); - if (RARRAY_LEN(result) >= 2) - rb_ary_shift(result); - } - else { - result = Qnil; - } - return result; -} - -static VALUE -username_completion_proc_call(VALUE self, VALUE str) -{ - VALUE result; - char **matches; - int i; - - matches = rl_completion_matches(StringValuePtr(str), - rl_username_completion_function); - if (matches) { - result = rb_ary_new(); - for (i = 0; matches[i]; i++) { - rb_ary_push(result, rb_locale_str_new_cstr(matches[i])); - free(matches[i]); - } - free(matches); - if (RARRAY_LEN(result) >= 2) - rb_ary_shift(result); - } - else { - result = Qnil; - } - return result; -} - -#ifdef HAVE_RL_CATCH_SIGNALS -RUBY_EXTERN int rl_catch_signals; -#endif -#ifdef HAVE_RL_CLEAR_SIGNALS -RUBY_EXTERN int rl_clear_signals(void); -#endif - -#undef rb_intern -void -Init_readline(void) -{ - VALUE history, fcomp, ucomp, version; - - /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = (char *)"Ruby"; - -#if defined HAVE_RL_GETC_FUNCTION - /* libedit check rl_getc_function only when rl_initialize() is called, */ - /* and using_history() call rl_initialize(). */ - /* This assignment should be placed before using_history() */ - rl_getc_function = readline_getc; -#elif defined HAVE_RL_EVENT_HOOK - rl_event_hook = readline_event; -#endif - - using_history(); - - id_call = rb_intern("call"); - completion_proc = rb_intern(COMPLETION_PROC); - completion_case_fold = rb_intern(COMPLETION_CASE_FOLD); -#if defined(HAVE_RL_PRE_INPUT_HOOK) - id_pre_input_hook = rb_intern("pre_input_hook"); -#endif -#if defined(HAVE_RL_SPECIAL_PREFIXES) - id_special_prefixes = rb_intern("special_prefixes"); -#endif -#if defined HAVE_RL_CHAR_IS_QUOTED_P - quoting_detection_proc = rb_intern(QUOTING_DETECTION_PROC); -#endif - - mReadline = rb_define_module("Readline"); - rb_define_module_function(mReadline, "readline", - readline_readline, -1); - rb_define_singleton_method(mReadline, "input=", - readline_s_set_input, 1); - rb_define_singleton_method(mReadline, "output=", - readline_s_set_output, 1); - rb_define_singleton_method(mReadline, "completion_proc=", - readline_s_set_completion_proc, 1); - rb_define_singleton_method(mReadline, "completion_proc", - readline_s_get_completion_proc, 0); - rb_define_singleton_method(mReadline, "quoting_detection_proc=", - readline_s_set_quoting_detection_proc, 1); - rb_define_singleton_method(mReadline, "quoting_detection_proc", - readline_s_get_quoting_detection_proc, 0); - rb_define_singleton_method(mReadline, "completion_case_fold=", - readline_s_set_completion_case_fold, 1); - rb_define_singleton_method(mReadline, "completion_case_fold", - readline_s_get_completion_case_fold, 0); - rb_define_singleton_method(mReadline, "line_buffer", - readline_s_get_line_buffer, 0); - rb_define_singleton_method(mReadline, "point", - readline_s_get_point, 0); - rb_define_singleton_method(mReadline, "point=", - readline_s_set_point, 1); - rb_define_singleton_method(mReadline, "set_screen_size", - readline_s_set_screen_size, 2); - rb_define_singleton_method(mReadline, "get_screen_size", - readline_s_get_screen_size, 0); - rb_define_singleton_method(mReadline, "vi_editing_mode", - readline_s_vi_editing_mode, 0); - rb_define_singleton_method(mReadline, "vi_editing_mode?", - readline_s_vi_editing_mode_p, 0); - rb_define_singleton_method(mReadline, "emacs_editing_mode", - readline_s_emacs_editing_mode, 0); - rb_define_singleton_method(mReadline, "emacs_editing_mode?", - readline_s_emacs_editing_mode_p, 0); - rb_define_singleton_method(mReadline, "completion_append_character=", - readline_s_set_completion_append_character, 1); - rb_define_singleton_method(mReadline, "completion_append_character", - readline_s_get_completion_append_character, 0); - rb_define_singleton_method(mReadline, "completion_quote_character", - readline_s_get_completion_quote_character, 0); - rb_define_singleton_method(mReadline, "basic_word_break_characters=", - readline_s_set_basic_word_break_characters, 1); - rb_define_singleton_method(mReadline, "basic_word_break_characters", - readline_s_get_basic_word_break_characters, 0); - rb_define_singleton_method(mReadline, "completer_word_break_characters=", - readline_s_set_completer_word_break_characters, 1); - rb_define_singleton_method(mReadline, "completer_word_break_characters", - readline_s_get_completer_word_break_characters, 0); - rb_define_singleton_method(mReadline, "basic_quote_characters=", - readline_s_set_basic_quote_characters, 1); - rb_define_singleton_method(mReadline, "basic_quote_characters", - readline_s_get_basic_quote_characters, 0); - rb_define_singleton_method(mReadline, "completer_quote_characters=", - readline_s_set_completer_quote_characters, 1); - rb_define_singleton_method(mReadline, "completer_quote_characters", - readline_s_get_completer_quote_characters, 0); - rb_define_singleton_method(mReadline, "filename_quote_characters=", - readline_s_set_filename_quote_characters, 1); - rb_define_singleton_method(mReadline, "filename_quote_characters", - readline_s_get_filename_quote_characters, 0); - rb_define_singleton_method(mReadline, "refresh_line", - readline_s_refresh_line, 0); - rb_define_singleton_method(mReadline, "pre_input_hook=", - readline_s_set_pre_input_hook, 1); - rb_define_singleton_method(mReadline, "pre_input_hook", - readline_s_get_pre_input_hook, 0); - rb_define_singleton_method(mReadline, "insert_text", - readline_s_insert_text, 1); - rb_define_singleton_method(mReadline, "delete_text", - readline_s_delete_text, -1); - rb_define_singleton_method(mReadline, "redisplay", - readline_s_redisplay, 0); - rb_define_singleton_method(mReadline, "special_prefixes=", - readline_s_set_special_prefixes, 1); - rb_define_singleton_method(mReadline, "special_prefixes", - readline_s_get_special_prefixes, 0); - -#if USE_INSERT_IGNORE_ESCAPE - id_orig_prompt = rb_intern("orig_prompt"); - id_last_prompt = rb_intern("last_prompt"); -#endif - - history = rb_obj_alloc(rb_cObject); - rb_extend_object(history, rb_mEnumerable); - rb_define_singleton_method(history,"to_s", hist_to_s, 0); - rb_define_singleton_method(history,"[]", hist_get, 1); - rb_define_singleton_method(history,"[]=", hist_set, 2); - rb_define_singleton_method(history,"<<", hist_push, 1); - rb_define_singleton_method(history,"push", hist_push_method, -1); - rb_define_singleton_method(history,"pop", hist_pop, 0); - rb_define_singleton_method(history,"shift", hist_shift, 0); - rb_define_singleton_method(history,"each", hist_each, 0); - rb_define_singleton_method(history,"length", hist_length, 0); - rb_define_singleton_method(history,"size", hist_length, 0); - rb_define_singleton_method(history,"empty?", hist_empty_p, 0); - rb_define_singleton_method(history,"delete_at", hist_delete_at, 1); - rb_define_singleton_method(history,"clear", hist_clear, 0); - - /* - * The history buffer. It extends Enumerable module, so it behaves - * just like an array. - * For example, gets the fifth content that the user input by - * <code>HISTORY[4]</code>. - */ - rb_define_const(mReadline, "HISTORY", history); - - fcomp = rb_obj_alloc(rb_cObject); - rb_define_singleton_method(fcomp, "call", - filename_completion_proc_call, 1); - /* - * The Object with the call method that is a completion for filename. - * This is sets by Readline.completion_proc= method. - */ - rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp); - - ucomp = rb_obj_alloc(rb_cObject); - rb_define_singleton_method(ucomp, "call", - username_completion_proc_call, 1); - /* - * The Object with the call method that is a completion for usernames. - * This is sets by Readline.completion_proc= method. - */ - rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp); - history_get_offset_func = history_get_offset_history_base; - history_replace_offset_func = history_get_offset_0; -#if defined HAVE_RL_LIBRARY_VERSION - version = rb_str_new_cstr(rl_library_version); -#if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY - if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION, - strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) { - prepare_readline(); - add_history("1"); - if (history_get(history_get_offset_func(0)) == NULL) { - history_get_offset_func = history_get_offset_0; - } -#ifdef HAVE_REPLACE_HISTORY_ENTRY - if (replace_history_entry(0, "a", NULL) == NULL) { - history_replace_offset_func = history_get_offset_history_base; - } -#endif -#ifdef HAVE_CLEAR_HISTORY - clear_history(); -#else - { - HIST_ENTRY *entry = remove_history(0); - if (entry) { - free((char *)entry->line); - free(entry); - } - } -#endif - } -#endif -#else - version = rb_str_new_cstr("2.0 or prior version"); -#endif - /* Version string of GNU Readline or libedit. */ - rb_define_const(mReadline, "VERSION", version); - - rl_attempted_completion_function = readline_attempted_completion_function; -#if defined(HAVE_RL_PRE_INPUT_HOOK) - rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; -#endif -#if defined HAVE_RL_CHAR_IS_QUOTED_P - rl_char_is_quoted_p = &readline_char_is_quoted; -#endif -#ifdef HAVE_RL_CATCH_SIGNALS - rl_catch_signals = 0; -#endif -#ifdef HAVE_RL_CLEAR_SIGNALS - rl_clear_signals(); -#endif - - rb_gc_register_address(&readline_instream); - rb_gc_register_address(&readline_outstream); -} - -/* - * Local variables: - * indent-tabs-mode: nil - * end: - */ diff --git a/ext/ripper/README b/ext/ripper/README index 2ae2470e13..70fa208920 100644 --- a/ext/ripper/README +++ b/ext/ripper/README @@ -13,7 +13,6 @@ Requirements ------------ * ruby 1.9 (support CVS HEAD only) - * bison 1.28 or later (Other yaccs do not work) Usage ----- diff --git a/ext/ripper/depend b/ext/ripper/depend index 6513ab107f..944da25ee9 100644 --- a/ext/ripper/depend +++ b/ext/ripper/depend @@ -1,30 +1,26 @@ GEN = $(srcdir)/tools/generate.rb SRC1 = $(top_srcdir)/parse.y SRC2 = $(srcdir)/eventids2.c +LRAMA = $(BASERUBY) $(top_srcdir)/tool/lrama/exe/lrama .SUFFIXES: .y -src: ripper.c eventids1.c eventids2table.c +src: ripper.c ripper_init.c eventids1.c eventids1.h eventids2table.c +ripper.c ripper_init.c eventids1.c eventids1.h eventids2table.c: depend ripper.o: ripper.c .y.c: $(ECHO) compiling compiler $< - $(Q) $(BISON) -t -v -oy.tab.c $< - $(Q) sed -e "/^#/s!y\.tab\.c!$@!" -f $(top_srcdir)/tool/ytab.sed y.tab.c > $@ - @$(RM) y.tab.c + $(Q) $(LRAMA) -o$@ - $< < $< all: check static: check -ripper.y: $(srcdir)/tools/preproc.rb $(srcdir)/tools/dsl.rb $(top_srcdir)/parse.y {$(VPATH)}id.h +ripper.y: $(srcdir)/tools/preproc.rb $(srcdir)/tools/dsl.rb $(top_srcdir)/parse.y $(top_srcdir)/defs/id.def $(ECHO) extracting $@ from $(top_srcdir)/parse.y - $(Q) $(RUBY) $(top_srcdir)/tool/id2token.rb --path-separator=.$(PATH_SEPARATOR)./ \ - --vpath=$(VPATH)$(PATH_SEPARATOR)$(top_srcdir) id.h $(top_srcdir)/parse.y > ripper.tmp.y - $(Q) $(RUBY) $(top_srcdir)/tool/pure_parser.rb ripper.tmp.y $(BISON) - $(Q) $(RM) ripper.tmp.y.bak - $(Q) $(RUBY) $(srcdir)/tools/preproc.rb ripper.tmp.y --output=$@ - $(Q) $(RM) ripper.tmp.y + $(Q) $(RUBY) $(top_srcdir)/tool/id2token.rb $(top_srcdir)/parse.y | \ + $(RUBY) $(srcdir)/tools/preproc.rb --output=$@ - ripper.y check: .eventids2-check @@ -33,6 +29,10 @@ check: .eventids2-check $(Q) $(RUBY) $(GEN) --mode=check --ids1src=$(SRC1) --ids2src=$(SRC2) @exit > $@ +eventids1.h: $(GEN) $(srcdir)/tools/dsl.rb $(SRC1) + $(ECHO) generating $@ from $(SRC1) + $(Q) $(RUBY) $(GEN) --mode=eventids1_h --ids1src=$(SRC1) --output=$@ + eventids1.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC1) $(ECHO) generating $@ from $(SRC1) $(Q) $(RUBY) $(GEN) --mode=eventids1 --ids1src=$(SRC1) --output=$@ @@ -41,6 +41,10 @@ eventids2table.c: $(GEN) $(srcdir)/tools/dsl.rb $(SRC2) $(ECHO) generating $@ from $(SRC2) $(Q) $(RUBY) $(GEN) --mode=eventids2table --ids2src=$(SRC2) --output=$@ +ripper_init.c: $(srcdir)/ripper_init.c.tmpl ripper.y $(srcdir)/tools/preproc.rb $(top_srcdir)/internal/ruby_parser.h + $(ECHO) generating $@ from $(srcdir)/ripper_init.c.tmpl + $(Q) $(RUBY) $(srcdir)/tools/preproc.rb --output=$@ --template=$(srcdir)/ripper_init.c.tmpl $(top_srcdir)/internal/ruby_parser.h + # Entries for Ripper maintainer preproc: ripper.E @@ -49,10 +53,351 @@ ripper.E: ripper.c $(Q) $(CC) -E $(INCFLAGS) $(CPPFLAGS) $< | $(RUBY) $(srcdir)/tools/strip.rb > $@ # AUTOGENERATED DEPENDENCIES START +eventids1.o: $(RUBY_EXTCONF_H) +eventids1.o: $(arch_hdrdir)/ruby/config.h +eventids1.o: $(hdrdir)/ruby/assert.h +eventids1.o: $(hdrdir)/ruby/backward.h +eventids1.o: $(hdrdir)/ruby/backward/2/assume.h +eventids1.o: $(hdrdir)/ruby/backward/2/attributes.h +eventids1.o: $(hdrdir)/ruby/backward/2/bool.h +eventids1.o: $(hdrdir)/ruby/backward/2/inttypes.h +eventids1.o: $(hdrdir)/ruby/backward/2/limits.h +eventids1.o: $(hdrdir)/ruby/backward/2/long_long.h +eventids1.o: $(hdrdir)/ruby/backward/2/stdalign.h +eventids1.o: $(hdrdir)/ruby/backward/2/stdarg.h +eventids1.o: $(hdrdir)/ruby/defines.h +eventids1.o: $(hdrdir)/ruby/intern.h +eventids1.o: $(hdrdir)/ruby/internal/abi.h +eventids1.o: $(hdrdir)/ruby/internal/anyargs.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/char.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/double.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/int.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/long.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/short.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +eventids1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +eventids1.o: $(hdrdir)/ruby/internal/assume.h +eventids1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +eventids1.o: $(hdrdir)/ruby/internal/attr/artificial.h +eventids1.o: $(hdrdir)/ruby/internal/attr/cold.h +eventids1.o: $(hdrdir)/ruby/internal/attr/const.h +eventids1.o: $(hdrdir)/ruby/internal/attr/constexpr.h +eventids1.o: $(hdrdir)/ruby/internal/attr/deprecated.h +eventids1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +eventids1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +eventids1.o: $(hdrdir)/ruby/internal/attr/error.h +eventids1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +eventids1.o: $(hdrdir)/ruby/internal/attr/forceinline.h +eventids1.o: $(hdrdir)/ruby/internal/attr/format.h +eventids1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +eventids1.o: $(hdrdir)/ruby/internal/attr/noalias.h +eventids1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +eventids1.o: $(hdrdir)/ruby/internal/attr/noexcept.h +eventids1.o: $(hdrdir)/ruby/internal/attr/noinline.h +eventids1.o: $(hdrdir)/ruby/internal/attr/nonnull.h +eventids1.o: $(hdrdir)/ruby/internal/attr/noreturn.h +eventids1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +eventids1.o: $(hdrdir)/ruby/internal/attr/pure.h +eventids1.o: $(hdrdir)/ruby/internal/attr/restrict.h +eventids1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +eventids1.o: $(hdrdir)/ruby/internal/attr/warning.h +eventids1.o: $(hdrdir)/ruby/internal/attr/weakref.h +eventids1.o: $(hdrdir)/ruby/internal/cast.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +eventids1.o: $(hdrdir)/ruby/internal/compiler_since.h +eventids1.o: $(hdrdir)/ruby/internal/config.h +eventids1.o: $(hdrdir)/ruby/internal/constant_p.h +eventids1.o: $(hdrdir)/ruby/internal/core.h +eventids1.o: $(hdrdir)/ruby/internal/core/rarray.h +eventids1.o: $(hdrdir)/ruby/internal/core/rbasic.h +eventids1.o: $(hdrdir)/ruby/internal/core/rbignum.h +eventids1.o: $(hdrdir)/ruby/internal/core/rclass.h +eventids1.o: $(hdrdir)/ruby/internal/core/rdata.h +eventids1.o: $(hdrdir)/ruby/internal/core/rfile.h +eventids1.o: $(hdrdir)/ruby/internal/core/rhash.h +eventids1.o: $(hdrdir)/ruby/internal/core/robject.h +eventids1.o: $(hdrdir)/ruby/internal/core/rregexp.h +eventids1.o: $(hdrdir)/ruby/internal/core/rstring.h +eventids1.o: $(hdrdir)/ruby/internal/core/rstruct.h +eventids1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +eventids1.o: $(hdrdir)/ruby/internal/ctype.h +eventids1.o: $(hdrdir)/ruby/internal/dllexport.h +eventids1.o: $(hdrdir)/ruby/internal/dosish.h +eventids1.o: $(hdrdir)/ruby/internal/error.h +eventids1.o: $(hdrdir)/ruby/internal/eval.h +eventids1.o: $(hdrdir)/ruby/internal/event.h +eventids1.o: $(hdrdir)/ruby/internal/fl_type.h +eventids1.o: $(hdrdir)/ruby/internal/gc.h +eventids1.o: $(hdrdir)/ruby/internal/glob.h +eventids1.o: $(hdrdir)/ruby/internal/globals.h +eventids1.o: $(hdrdir)/ruby/internal/has/attribute.h +eventids1.o: $(hdrdir)/ruby/internal/has/builtin.h +eventids1.o: $(hdrdir)/ruby/internal/has/c_attribute.h +eventids1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +eventids1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +eventids1.o: $(hdrdir)/ruby/internal/has/extension.h +eventids1.o: $(hdrdir)/ruby/internal/has/feature.h +eventids1.o: $(hdrdir)/ruby/internal/has/warning.h +eventids1.o: $(hdrdir)/ruby/internal/intern/array.h +eventids1.o: $(hdrdir)/ruby/internal/intern/bignum.h +eventids1.o: $(hdrdir)/ruby/internal/intern/class.h +eventids1.o: $(hdrdir)/ruby/internal/intern/compar.h +eventids1.o: $(hdrdir)/ruby/internal/intern/complex.h +eventids1.o: $(hdrdir)/ruby/internal/intern/cont.h +eventids1.o: $(hdrdir)/ruby/internal/intern/dir.h +eventids1.o: $(hdrdir)/ruby/internal/intern/enum.h +eventids1.o: $(hdrdir)/ruby/internal/intern/enumerator.h +eventids1.o: $(hdrdir)/ruby/internal/intern/error.h +eventids1.o: $(hdrdir)/ruby/internal/intern/eval.h +eventids1.o: $(hdrdir)/ruby/internal/intern/file.h +eventids1.o: $(hdrdir)/ruby/internal/intern/hash.h +eventids1.o: $(hdrdir)/ruby/internal/intern/io.h +eventids1.o: $(hdrdir)/ruby/internal/intern/load.h +eventids1.o: $(hdrdir)/ruby/internal/intern/marshal.h +eventids1.o: $(hdrdir)/ruby/internal/intern/numeric.h +eventids1.o: $(hdrdir)/ruby/internal/intern/object.h +eventids1.o: $(hdrdir)/ruby/internal/intern/parse.h +eventids1.o: $(hdrdir)/ruby/internal/intern/proc.h +eventids1.o: $(hdrdir)/ruby/internal/intern/process.h +eventids1.o: $(hdrdir)/ruby/internal/intern/random.h +eventids1.o: $(hdrdir)/ruby/internal/intern/range.h +eventids1.o: $(hdrdir)/ruby/internal/intern/rational.h +eventids1.o: $(hdrdir)/ruby/internal/intern/re.h +eventids1.o: $(hdrdir)/ruby/internal/intern/ruby.h +eventids1.o: $(hdrdir)/ruby/internal/intern/select.h +eventids1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +eventids1.o: $(hdrdir)/ruby/internal/intern/set.h +eventids1.o: $(hdrdir)/ruby/internal/intern/signal.h +eventids1.o: $(hdrdir)/ruby/internal/intern/sprintf.h +eventids1.o: $(hdrdir)/ruby/internal/intern/string.h +eventids1.o: $(hdrdir)/ruby/internal/intern/struct.h +eventids1.o: $(hdrdir)/ruby/internal/intern/thread.h +eventids1.o: $(hdrdir)/ruby/internal/intern/time.h +eventids1.o: $(hdrdir)/ruby/internal/intern/variable.h +eventids1.o: $(hdrdir)/ruby/internal/intern/vm.h +eventids1.o: $(hdrdir)/ruby/internal/interpreter.h +eventids1.o: $(hdrdir)/ruby/internal/iterator.h +eventids1.o: $(hdrdir)/ruby/internal/memory.h +eventids1.o: $(hdrdir)/ruby/internal/method.h +eventids1.o: $(hdrdir)/ruby/internal/module.h +eventids1.o: $(hdrdir)/ruby/internal/newobj.h +eventids1.o: $(hdrdir)/ruby/internal/scan_args.h +eventids1.o: $(hdrdir)/ruby/internal/special_consts.h +eventids1.o: $(hdrdir)/ruby/internal/static_assert.h +eventids1.o: $(hdrdir)/ruby/internal/stdalign.h +eventids1.o: $(hdrdir)/ruby/internal/stdbool.h +eventids1.o: $(hdrdir)/ruby/internal/stdckdint.h +eventids1.o: $(hdrdir)/ruby/internal/symbol.h +eventids1.o: $(hdrdir)/ruby/internal/value.h +eventids1.o: $(hdrdir)/ruby/internal/value_type.h +eventids1.o: $(hdrdir)/ruby/internal/variable.h +eventids1.o: $(hdrdir)/ruby/internal/warning_push.h +eventids1.o: $(hdrdir)/ruby/internal/xmalloc.h +eventids1.o: $(hdrdir)/ruby/missing.h +eventids1.o: $(hdrdir)/ruby/ruby.h +eventids1.o: $(hdrdir)/ruby/st.h +eventids1.o: $(hdrdir)/ruby/subst.h +eventids1.o: eventids1.h +eventids1.o: {$(VPATH)}eventids1.c +eventids1.o: {$(VPATH)}eventids1.h +eventids2.o: $(RUBY_EXTCONF_H) +eventids2.o: $(arch_hdrdir)/ruby/config.h +eventids2.o: $(hdrdir)/ruby/assert.h +eventids2.o: $(hdrdir)/ruby/backward.h +eventids2.o: $(hdrdir)/ruby/backward/2/assume.h +eventids2.o: $(hdrdir)/ruby/backward/2/attributes.h +eventids2.o: $(hdrdir)/ruby/backward/2/bool.h +eventids2.o: $(hdrdir)/ruby/backward/2/inttypes.h +eventids2.o: $(hdrdir)/ruby/backward/2/limits.h +eventids2.o: $(hdrdir)/ruby/backward/2/long_long.h +eventids2.o: $(hdrdir)/ruby/backward/2/stdalign.h +eventids2.o: $(hdrdir)/ruby/backward/2/stdarg.h +eventids2.o: $(hdrdir)/ruby/defines.h +eventids2.o: $(hdrdir)/ruby/encoding.h +eventids2.o: $(hdrdir)/ruby/intern.h +eventids2.o: $(hdrdir)/ruby/internal/abi.h +eventids2.o: $(hdrdir)/ruby/internal/anyargs.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/char.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/double.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/int.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/long.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/short.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +eventids2.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +eventids2.o: $(hdrdir)/ruby/internal/assume.h +eventids2.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +eventids2.o: $(hdrdir)/ruby/internal/attr/artificial.h +eventids2.o: $(hdrdir)/ruby/internal/attr/cold.h +eventids2.o: $(hdrdir)/ruby/internal/attr/const.h +eventids2.o: $(hdrdir)/ruby/internal/attr/constexpr.h +eventids2.o: $(hdrdir)/ruby/internal/attr/deprecated.h +eventids2.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +eventids2.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +eventids2.o: $(hdrdir)/ruby/internal/attr/error.h +eventids2.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +eventids2.o: $(hdrdir)/ruby/internal/attr/forceinline.h +eventids2.o: $(hdrdir)/ruby/internal/attr/format.h +eventids2.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +eventids2.o: $(hdrdir)/ruby/internal/attr/noalias.h +eventids2.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +eventids2.o: $(hdrdir)/ruby/internal/attr/noexcept.h +eventids2.o: $(hdrdir)/ruby/internal/attr/noinline.h +eventids2.o: $(hdrdir)/ruby/internal/attr/nonnull.h +eventids2.o: $(hdrdir)/ruby/internal/attr/noreturn.h +eventids2.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +eventids2.o: $(hdrdir)/ruby/internal/attr/pure.h +eventids2.o: $(hdrdir)/ruby/internal/attr/restrict.h +eventids2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +eventids2.o: $(hdrdir)/ruby/internal/attr/warning.h +eventids2.o: $(hdrdir)/ruby/internal/attr/weakref.h +eventids2.o: $(hdrdir)/ruby/internal/cast.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +eventids2.o: $(hdrdir)/ruby/internal/compiler_since.h +eventids2.o: $(hdrdir)/ruby/internal/config.h +eventids2.o: $(hdrdir)/ruby/internal/constant_p.h +eventids2.o: $(hdrdir)/ruby/internal/core.h +eventids2.o: $(hdrdir)/ruby/internal/core/rarray.h +eventids2.o: $(hdrdir)/ruby/internal/core/rbasic.h +eventids2.o: $(hdrdir)/ruby/internal/core/rbignum.h +eventids2.o: $(hdrdir)/ruby/internal/core/rclass.h +eventids2.o: $(hdrdir)/ruby/internal/core/rdata.h +eventids2.o: $(hdrdir)/ruby/internal/core/rfile.h +eventids2.o: $(hdrdir)/ruby/internal/core/rhash.h +eventids2.o: $(hdrdir)/ruby/internal/core/robject.h +eventids2.o: $(hdrdir)/ruby/internal/core/rregexp.h +eventids2.o: $(hdrdir)/ruby/internal/core/rstring.h +eventids2.o: $(hdrdir)/ruby/internal/core/rstruct.h +eventids2.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +eventids2.o: $(hdrdir)/ruby/internal/ctype.h +eventids2.o: $(hdrdir)/ruby/internal/dllexport.h +eventids2.o: $(hdrdir)/ruby/internal/dosish.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/coderange.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/ctype.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/encoding.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/pathname.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/re.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/string.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/symbol.h +eventids2.o: $(hdrdir)/ruby/internal/encoding/transcode.h +eventids2.o: $(hdrdir)/ruby/internal/error.h +eventids2.o: $(hdrdir)/ruby/internal/eval.h +eventids2.o: $(hdrdir)/ruby/internal/event.h +eventids2.o: $(hdrdir)/ruby/internal/fl_type.h +eventids2.o: $(hdrdir)/ruby/internal/gc.h +eventids2.o: $(hdrdir)/ruby/internal/glob.h +eventids2.o: $(hdrdir)/ruby/internal/globals.h +eventids2.o: $(hdrdir)/ruby/internal/has/attribute.h +eventids2.o: $(hdrdir)/ruby/internal/has/builtin.h +eventids2.o: $(hdrdir)/ruby/internal/has/c_attribute.h +eventids2.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +eventids2.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +eventids2.o: $(hdrdir)/ruby/internal/has/extension.h +eventids2.o: $(hdrdir)/ruby/internal/has/feature.h +eventids2.o: $(hdrdir)/ruby/internal/has/warning.h +eventids2.o: $(hdrdir)/ruby/internal/intern/array.h +eventids2.o: $(hdrdir)/ruby/internal/intern/bignum.h +eventids2.o: $(hdrdir)/ruby/internal/intern/class.h +eventids2.o: $(hdrdir)/ruby/internal/intern/compar.h +eventids2.o: $(hdrdir)/ruby/internal/intern/complex.h +eventids2.o: $(hdrdir)/ruby/internal/intern/cont.h +eventids2.o: $(hdrdir)/ruby/internal/intern/dir.h +eventids2.o: $(hdrdir)/ruby/internal/intern/enum.h +eventids2.o: $(hdrdir)/ruby/internal/intern/enumerator.h +eventids2.o: $(hdrdir)/ruby/internal/intern/error.h +eventids2.o: $(hdrdir)/ruby/internal/intern/eval.h +eventids2.o: $(hdrdir)/ruby/internal/intern/file.h +eventids2.o: $(hdrdir)/ruby/internal/intern/hash.h +eventids2.o: $(hdrdir)/ruby/internal/intern/io.h +eventids2.o: $(hdrdir)/ruby/internal/intern/load.h +eventids2.o: $(hdrdir)/ruby/internal/intern/marshal.h +eventids2.o: $(hdrdir)/ruby/internal/intern/numeric.h +eventids2.o: $(hdrdir)/ruby/internal/intern/object.h +eventids2.o: $(hdrdir)/ruby/internal/intern/parse.h +eventids2.o: $(hdrdir)/ruby/internal/intern/proc.h +eventids2.o: $(hdrdir)/ruby/internal/intern/process.h +eventids2.o: $(hdrdir)/ruby/internal/intern/random.h +eventids2.o: $(hdrdir)/ruby/internal/intern/range.h +eventids2.o: $(hdrdir)/ruby/internal/intern/rational.h +eventids2.o: $(hdrdir)/ruby/internal/intern/re.h +eventids2.o: $(hdrdir)/ruby/internal/intern/ruby.h +eventids2.o: $(hdrdir)/ruby/internal/intern/select.h +eventids2.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +eventids2.o: $(hdrdir)/ruby/internal/intern/set.h +eventids2.o: $(hdrdir)/ruby/internal/intern/signal.h +eventids2.o: $(hdrdir)/ruby/internal/intern/sprintf.h +eventids2.o: $(hdrdir)/ruby/internal/intern/string.h +eventids2.o: $(hdrdir)/ruby/internal/intern/struct.h +eventids2.o: $(hdrdir)/ruby/internal/intern/thread.h +eventids2.o: $(hdrdir)/ruby/internal/intern/time.h +eventids2.o: $(hdrdir)/ruby/internal/intern/variable.h +eventids2.o: $(hdrdir)/ruby/internal/intern/vm.h +eventids2.o: $(hdrdir)/ruby/internal/interpreter.h +eventids2.o: $(hdrdir)/ruby/internal/iterator.h +eventids2.o: $(hdrdir)/ruby/internal/memory.h +eventids2.o: $(hdrdir)/ruby/internal/method.h +eventids2.o: $(hdrdir)/ruby/internal/module.h +eventids2.o: $(hdrdir)/ruby/internal/newobj.h +eventids2.o: $(hdrdir)/ruby/internal/scan_args.h +eventids2.o: $(hdrdir)/ruby/internal/special_consts.h +eventids2.o: $(hdrdir)/ruby/internal/static_assert.h +eventids2.o: $(hdrdir)/ruby/internal/stdalign.h +eventids2.o: $(hdrdir)/ruby/internal/stdbool.h +eventids2.o: $(hdrdir)/ruby/internal/stdckdint.h +eventids2.o: $(hdrdir)/ruby/internal/symbol.h +eventids2.o: $(hdrdir)/ruby/internal/value.h +eventids2.o: $(hdrdir)/ruby/internal/value_type.h +eventids2.o: $(hdrdir)/ruby/internal/variable.h +eventids2.o: $(hdrdir)/ruby/internal/warning_push.h +eventids2.o: $(hdrdir)/ruby/internal/xmalloc.h +eventids2.o: $(hdrdir)/ruby/missing.h +eventids2.o: $(hdrdir)/ruby/onigmo.h +eventids2.o: $(hdrdir)/ruby/oniguruma.h +eventids2.o: $(hdrdir)/ruby/ruby.h +eventids2.o: $(hdrdir)/ruby/st.h +eventids2.o: $(hdrdir)/ruby/subst.h +eventids2.o: $(top_srcdir)/internal.h +eventids2.o: $(top_srcdir)/internal/static_assert.h +eventids2.o: $(top_srcdir)/rubyparser.h +eventids2.o: eventids2.c +eventids2.o: eventids2.h +eventids2.o: {$(VPATH)}eventids2table.c +eventids2.o: {$(VPATH)}parse.h ripper.o: $(RUBY_EXTCONF_H) ripper.o: $(arch_hdrdir)/ruby/config.h ripper.o: $(hdrdir)/ruby.h ripper.o: $(hdrdir)/ruby/assert.h +ripper.o: $(hdrdir)/ruby/atomic.h ripper.o: $(hdrdir)/ruby/backward.h ripper.o: $(hdrdir)/ruby/backward/2/assume.h ripper.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -66,6 +411,7 @@ ripper.o: $(hdrdir)/ruby/backward/2/stdarg.h ripper.o: $(hdrdir)/ruby/defines.h ripper.o: $(hdrdir)/ruby/encoding.h ripper.o: $(hdrdir)/ruby/intern.h +ripper.o: $(hdrdir)/ruby/internal/abi.h ripper.o: $(hdrdir)/ruby/internal/anyargs.h ripper.o: $(hdrdir)/ruby/internal/arithmetic.h ripper.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -103,6 +449,7 @@ ripper.o: $(hdrdir)/ruby/internal/attr/noexcept.h ripper.o: $(hdrdir)/ruby/internal/attr/noinline.h ripper.o: $(hdrdir)/ruby/internal/attr/nonnull.h ripper.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ripper.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ripper.o: $(hdrdir)/ruby/internal/attr/pure.h ripper.o: $(hdrdir)/ruby/internal/attr/restrict.h ripper.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -171,7 +518,6 @@ ripper.o: $(hdrdir)/ruby/internal/intern/enumerator.h ripper.o: $(hdrdir)/ruby/internal/intern/error.h ripper.o: $(hdrdir)/ruby/internal/intern/eval.h ripper.o: $(hdrdir)/ruby/internal/intern/file.h -ripper.o: $(hdrdir)/ruby/internal/intern/gc.h ripper.o: $(hdrdir)/ruby/internal/intern/hash.h ripper.o: $(hdrdir)/ruby/internal/intern/io.h ripper.o: $(hdrdir)/ruby/internal/intern/load.h @@ -188,6 +534,7 @@ ripper.o: $(hdrdir)/ruby/internal/intern/re.h ripper.o: $(hdrdir)/ruby/internal/intern/ruby.h ripper.o: $(hdrdir)/ruby/internal/intern/select.h ripper.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ripper.o: $(hdrdir)/ruby/internal/intern/set.h ripper.o: $(hdrdir)/ruby/internal/intern/signal.h ripper.o: $(hdrdir)/ruby/internal/intern/sprintf.h ripper.o: $(hdrdir)/ruby/internal/intern/string.h @@ -202,12 +549,12 @@ ripper.o: $(hdrdir)/ruby/internal/memory.h ripper.o: $(hdrdir)/ruby/internal/method.h ripper.o: $(hdrdir)/ruby/internal/module.h ripper.o: $(hdrdir)/ruby/internal/newobj.h -ripper.o: $(hdrdir)/ruby/internal/rgengc.h ripper.o: $(hdrdir)/ruby/internal/scan_args.h ripper.o: $(hdrdir)/ruby/internal/special_consts.h ripper.o: $(hdrdir)/ruby/internal/static_assert.h ripper.o: $(hdrdir)/ruby/internal/stdalign.h ripper.o: $(hdrdir)/ruby/internal/stdbool.h +ripper.o: $(hdrdir)/ruby/internal/stdckdint.h ripper.o: $(hdrdir)/ruby/internal/symbol.h ripper.o: $(hdrdir)/ruby/internal/value.h ripper.o: $(hdrdir)/ruby/internal/value_type.h @@ -223,16 +570,26 @@ ripper.o: $(hdrdir)/ruby/regex.h ripper.o: $(hdrdir)/ruby/ruby.h ripper.o: $(hdrdir)/ruby/st.h ripper.o: $(hdrdir)/ruby/subst.h +ripper.o: $(hdrdir)/ruby/thread_native.h ripper.o: $(hdrdir)/ruby/util.h +ripper.o: $(hdrdir)/ruby/version.h +ripper.o: $(top_srcdir)/ccan/check_type/check_type.h +ripper.o: $(top_srcdir)/ccan/container_of/container_of.h +ripper.o: $(top_srcdir)/ccan/list/list.h +ripper.o: $(top_srcdir)/ccan/str/str.h ripper.o: $(top_srcdir)/constant.h +ripper.o: $(top_srcdir)/encindex.h ripper.o: $(top_srcdir)/id_table.h ripper.o: $(top_srcdir)/internal.h ripper.o: $(top_srcdir)/internal/array.h +ripper.o: $(top_srcdir)/internal/basic_operators.h ripper.o: $(top_srcdir)/internal/bignum.h ripper.o: $(top_srcdir)/internal/bits.h +ripper.o: $(top_srcdir)/internal/box.h ripper.o: $(top_srcdir)/internal/compile.h ripper.o: $(top_srcdir)/internal/compilers.h ripper.o: $(top_srcdir)/internal/complex.h +ripper.o: $(top_srcdir)/internal/encoding.h ripper.o: $(top_srcdir)/internal/error.h ripper.o: $(top_srcdir)/internal/fixnum.h ripper.o: $(top_srcdir)/internal/gc.h @@ -243,22 +600,37 @@ ripper.o: $(top_srcdir)/internal/numeric.h ripper.o: $(top_srcdir)/internal/parse.h ripper.o: $(top_srcdir)/internal/rational.h ripper.o: $(top_srcdir)/internal/re.h +ripper.o: $(top_srcdir)/internal/ruby_parser.h +ripper.o: $(top_srcdir)/internal/sanitizers.h ripper.o: $(top_srcdir)/internal/serial.h +ripper.o: $(top_srcdir)/internal/set_table.h ripper.o: $(top_srcdir)/internal/static_assert.h ripper.o: $(top_srcdir)/internal/string.h +ripper.o: $(top_srcdir)/internal/struct.h ripper.o: $(top_srcdir)/internal/symbol.h ripper.o: $(top_srcdir)/internal/thread.h -ripper.o: $(top_srcdir)/internal/util.h ripper.o: $(top_srcdir)/internal/variable.h ripper.o: $(top_srcdir)/internal/vm.h ripper.o: $(top_srcdir)/internal/warnings.h +ripper.o: $(top_srcdir)/method.h ripper.o: $(top_srcdir)/node.h +ripper.o: $(top_srcdir)/parser_node.h +ripper.o: $(top_srcdir)/parser_st.h ripper.o: $(top_srcdir)/regenc.h ripper.o: $(top_srcdir)/ruby_assert.h +ripper.o: $(top_srcdir)/ruby_atomic.h +ripper.o: $(top_srcdir)/rubyparser.h +ripper.o: $(top_srcdir)/shape.h ripper.o: $(top_srcdir)/symbol.h +ripper.o: $(top_srcdir)/thread_pthread.h +ripper.o: $(top_srcdir)/vm_core.h +ripper.o: $(top_srcdir)/vm_opts.h ripper.o: ../../probes.h +ripper.o: eventids1.h ripper.o: eventids2.c +ripper.o: eventids2.h ripper.o: ripper.y +ripper.o: ripper_init.h ripper.o: {$(VPATH)}eventids1.c ripper.o: {$(VPATH)}eventids2table.c ripper.o: {$(VPATH)}id.h @@ -266,4 +638,199 @@ ripper.o: {$(VPATH)}lex.c ripper.o: {$(VPATH)}parse.h ripper.o: {$(VPATH)}probes.dmyh ripper.o: {$(VPATH)}ripper.c +ripper_init.o: $(RUBY_EXTCONF_H) +ripper_init.o: $(arch_hdrdir)/ruby/config.h +ripper_init.o: $(hdrdir)/ruby/assert.h +ripper_init.o: $(hdrdir)/ruby/backward.h +ripper_init.o: $(hdrdir)/ruby/backward/2/assume.h +ripper_init.o: $(hdrdir)/ruby/backward/2/attributes.h +ripper_init.o: $(hdrdir)/ruby/backward/2/bool.h +ripper_init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +ripper_init.o: $(hdrdir)/ruby/backward/2/inttypes.h +ripper_init.o: $(hdrdir)/ruby/backward/2/limits.h +ripper_init.o: $(hdrdir)/ruby/backward/2/long_long.h +ripper_init.o: $(hdrdir)/ruby/backward/2/stdalign.h +ripper_init.o: $(hdrdir)/ruby/backward/2/stdarg.h +ripper_init.o: $(hdrdir)/ruby/defines.h +ripper_init.o: $(hdrdir)/ruby/encoding.h +ripper_init.o: $(hdrdir)/ruby/intern.h +ripper_init.o: $(hdrdir)/ruby/internal/abi.h +ripper_init.o: $(hdrdir)/ruby/internal/anyargs.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ripper_init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ripper_init.o: $(hdrdir)/ruby/internal/assume.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/artificial.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/cold.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/const.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/error.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/format.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/noalias.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/noinline.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/pure.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/restrict.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/warning.h +ripper_init.o: $(hdrdir)/ruby/internal/attr/weakref.h +ripper_init.o: $(hdrdir)/ruby/internal/cast.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ripper_init.o: $(hdrdir)/ruby/internal/compiler_since.h +ripper_init.o: $(hdrdir)/ruby/internal/config.h +ripper_init.o: $(hdrdir)/ruby/internal/constant_p.h +ripper_init.o: $(hdrdir)/ruby/internal/core.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rarray.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rbasic.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rbignum.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rclass.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rdata.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rfile.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rhash.h +ripper_init.o: $(hdrdir)/ruby/internal/core/robject.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rregexp.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rstring.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rstruct.h +ripper_init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ripper_init.o: $(hdrdir)/ruby/internal/ctype.h +ripper_init.o: $(hdrdir)/ruby/internal/dllexport.h +ripper_init.o: $(hdrdir)/ruby/internal/dosish.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/re.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/string.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ripper_init.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ripper_init.o: $(hdrdir)/ruby/internal/error.h +ripper_init.o: $(hdrdir)/ruby/internal/eval.h +ripper_init.o: $(hdrdir)/ruby/internal/event.h +ripper_init.o: $(hdrdir)/ruby/internal/fl_type.h +ripper_init.o: $(hdrdir)/ruby/internal/gc.h +ripper_init.o: $(hdrdir)/ruby/internal/glob.h +ripper_init.o: $(hdrdir)/ruby/internal/globals.h +ripper_init.o: $(hdrdir)/ruby/internal/has/attribute.h +ripper_init.o: $(hdrdir)/ruby/internal/has/builtin.h +ripper_init.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ripper_init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ripper_init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ripper_init.o: $(hdrdir)/ruby/internal/has/extension.h +ripper_init.o: $(hdrdir)/ruby/internal/has/feature.h +ripper_init.o: $(hdrdir)/ruby/internal/has/warning.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/array.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/bignum.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/class.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/compar.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/complex.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/cont.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/dir.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/enum.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/error.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/eval.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/file.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/hash.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/io.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/load.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/marshal.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/numeric.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/object.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/parse.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/proc.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/process.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/random.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/range.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/rational.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/re.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/ruby.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/select.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/set.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/signal.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/string.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/struct.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/thread.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/time.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/variable.h +ripper_init.o: $(hdrdir)/ruby/internal/intern/vm.h +ripper_init.o: $(hdrdir)/ruby/internal/interpreter.h +ripper_init.o: $(hdrdir)/ruby/internal/iterator.h +ripper_init.o: $(hdrdir)/ruby/internal/memory.h +ripper_init.o: $(hdrdir)/ruby/internal/method.h +ripper_init.o: $(hdrdir)/ruby/internal/module.h +ripper_init.o: $(hdrdir)/ruby/internal/newobj.h +ripper_init.o: $(hdrdir)/ruby/internal/scan_args.h +ripper_init.o: $(hdrdir)/ruby/internal/special_consts.h +ripper_init.o: $(hdrdir)/ruby/internal/static_assert.h +ripper_init.o: $(hdrdir)/ruby/internal/stdalign.h +ripper_init.o: $(hdrdir)/ruby/internal/stdbool.h +ripper_init.o: $(hdrdir)/ruby/internal/stdckdint.h +ripper_init.o: $(hdrdir)/ruby/internal/symbol.h +ripper_init.o: $(hdrdir)/ruby/internal/value.h +ripper_init.o: $(hdrdir)/ruby/internal/value_type.h +ripper_init.o: $(hdrdir)/ruby/internal/variable.h +ripper_init.o: $(hdrdir)/ruby/internal/warning_push.h +ripper_init.o: $(hdrdir)/ruby/internal/xmalloc.h +ripper_init.o: $(hdrdir)/ruby/missing.h +ripper_init.o: $(hdrdir)/ruby/onigmo.h +ripper_init.o: $(hdrdir)/ruby/oniguruma.h +ripper_init.o: $(hdrdir)/ruby/ruby.h +ripper_init.o: $(hdrdir)/ruby/st.h +ripper_init.o: $(hdrdir)/ruby/subst.h +ripper_init.o: $(top_srcdir)/internal.h +ripper_init.o: $(top_srcdir)/internal/array.h +ripper_init.o: $(top_srcdir)/internal/bignum.h +ripper_init.o: $(top_srcdir)/internal/bits.h +ripper_init.o: $(top_srcdir)/internal/compilers.h +ripper_init.o: $(top_srcdir)/internal/complex.h +ripper_init.o: $(top_srcdir)/internal/fixnum.h +ripper_init.o: $(top_srcdir)/internal/imemo.h +ripper_init.o: $(top_srcdir)/internal/numeric.h +ripper_init.o: $(top_srcdir)/internal/parse.h +ripper_init.o: $(top_srcdir)/internal/rational.h +ripper_init.o: $(top_srcdir)/internal/ruby_parser.h +ripper_init.o: $(top_srcdir)/internal/serial.h +ripper_init.o: $(top_srcdir)/internal/static_assert.h +ripper_init.o: $(top_srcdir)/internal/vm.h +ripper_init.o: $(top_srcdir)/node.h +ripper_init.o: $(top_srcdir)/ruby_assert.h +ripper_init.o: $(top_srcdir)/rubyparser.h +ripper_init.o: eventids1.h +ripper_init.o: eventids2.h +ripper_init.o: ripper_init.h +ripper_init.o: {$(VPATH)}parse.h +ripper_init.o: {$(VPATH)}ripper_init.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/ripper/eventids2.c b/ext/ripper/eventids2.c index ac38663f2d..87f2f588ec 100644 --- a/ext/ripper/eventids2.c +++ b/ext/ripper/eventids2.c @@ -1,21 +1,10 @@ -enum { - tIGNORED_NL = tLAST_TOKEN + 1, -# define tIGNORED_NL ((enum yytokentype)tIGNORED_NL) - tCOMMENT, -# define tCOMMENT ((enum yytokentype)tCOMMENT) - tEMBDOC_BEG, -# define tEMBDOC_BEG ((enum yytokentype)tEMBDOC_BEG) - tEMBDOC, -# define tEMBDOC ((enum yytokentype)tEMBDOC) - tEMBDOC_END, -# define tEMBDOC_END ((enum yytokentype)tEMBDOC_END) - tHEREDOC_BEG, -# define tHEREDOC_BEG ((enum yytokentype)tHEREDOC_BEG) - tHEREDOC_END, -# define tHEREDOC_END ((enum yytokentype)tHEREDOC_END) - k__END__, -# define k__END__ ((enum yytokentype)k__END__) -}; +#include "ruby/ruby.h" +#include "rubyparser.h" +#define YYSTYPE_IS_DECLARED +#include "parse.h" +#include "eventids2.h" +#include "internal.h" +#include "internal/static_assert.h" typedef struct { ID ripper_id_backref; @@ -76,7 +65,9 @@ static ripper_scanner_ids_t ripper_scanner_ids; #include "eventids2table.c" -static void +STATIC_ASSERT(eventids2_table_size, RIPPER_EVENTIDS2_TABLE_SIZE == sizeof(ripper_scanner_ids)/sizeof(ID)); + +void ripper_init_eventids2(void) { #define set_id2(name) ripper_scanner_ids.ripper_id_##name = rb_intern_const("on_"#name) @@ -137,7 +128,7 @@ ripper_init_eventids2(void) STATIC_ASSERT(k__END___range, k__END__ < SHRT_MAX); STATIC_ASSERT(ripper_scanner_ids_size, sizeof(ripper_scanner_ids) < SHRT_MAX); -static ID +ID ripper_token2eventid(enum yytokentype tok) { #define O(member) (int)offsetof(ripper_scanner_ids_t, ripper_id_##member)+1 @@ -264,7 +255,6 @@ ripper_token2eventid(enum yytokentype tok) [tRATIONAL] = O(rational), [tREGEXP_BEG] = O(regexp_beg), [tREGEXP_END] = O(regexp_end), - [tRPAREN] = O(rparen), [tRSHFT] = O(op), [tSTAR] = O(op), [tDSTAR] = O(op), diff --git a/ext/ripper/eventids2.h b/ext/ripper/eventids2.h new file mode 100644 index 0000000000..49e46432b9 --- /dev/null +++ b/ext/ripper/eventids2.h @@ -0,0 +1,8 @@ +#ifndef RIPPER_EVENTIDS2 +#define RIPPER_EVENTIDS2 + +void ripper_init_eventids2(void); +void ripper_init_eventids2_table(VALUE self); +ID ripper_token2eventid(enum yytokentype tok); + +#endif /* RIPPER_EVENTIDS2 */ diff --git a/ext/ripper/extconf.rb b/ext/ripper/extconf.rb index 2dde565bd9..c3c56c27c5 100644 --- a/ext/ripper/extconf.rb +++ b/ext/ripper/extconf.rb @@ -5,22 +5,14 @@ require 'mkmf' require 'rbconfig' def main - yacc = ENV["YACC"] || "bison" - - unless find_executable(yacc) - unless File.exist?('ripper.c') or File.exist?("#{$srcdir}/ripper.c") - raise 'missing bison; abort' - end - end - $objs = %w(ripper.o) - $cleanfiles.concat %w(ripper.y ripper.c ripper.E ripper.output y.output eventids1.c eventids2table.c .eventids2-check) + $objs = %w(eventids1.o eventids2.o ripper.o ripper_init.o) + $distcleanfiles.concat %w(ripper.y ripper.c eventids1.c eventids1.h eventids2table.c ripper_init.c) + $cleanfiles.concat %w(ripper.E ripper.output y.output .eventids2-check) $defs << '-DRIPPER' $defs << '-DRIPPER_DEBUG' if $debug $VPATH << '$(topdir)' << '$(top_srcdir)' $INCFLAGS << ' -I$(topdir) -I$(top_srcdir)' - create_makefile 'ripper' do |conf| - conf << "BISON = #{yacc}" - end + create_makefile 'ripper' end main diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index f6051c6341..9b849dfeae 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -53,10 +53,28 @@ class Ripper end class Lexer < ::Ripper #:nodoc: internal use only - State = Struct.new(:to_int, :to_s) do + # :stopdoc: + class State + attr_reader :to_int, :to_s + + def initialize(i) + @to_int = i + @to_s = Ripper.lex_state_name(i) + freeze + end + + def [](index) + case index + when 0, :to_int + @to_int + when 1, :to_s + @to_s + else + nil + end + end + alias to_i to_int - def initialize(i) super(i, Ripper.lex_state_name(i)).freeze end - # def inspect; "#<#{self.class}: #{self}>" end alias inspect to_s def pretty_print(q) q.text(to_s) end def ==(i) super or to_int == i end @@ -67,15 +85,40 @@ class Ripper def nobits?(i) to_int.nobits?(i) end end - Elem = Struct.new(:pos, :event, :tok, :state, :message) do + class Elem + attr_accessor :pos, :event, :tok, :state, :message + def initialize(pos, event, tok, state, message = nil) - super(pos, event, tok, State.new(state), message) + @pos = pos + @event = event + @tok = tok + @state = State.new(state) + @message = message + end + + def [](index) + case index + when 0, :pos + @pos + when 1, :event + @event + when 2, :tok + @tok + when 3, :state + @state + when 4, :message + @message + else + nil + end end def inspect "#<#{self.class}: #{event}@#{pos[0]}:#{pos[1]}:#{state}: #{tok.inspect}#{": " if message}#{message}>" end + alias to_s inspect + def pretty_print(q) q.group(2, "#<#{self.class}:", ">") { q.breakable @@ -94,9 +137,11 @@ class Ripper end def to_a - a = super - a.pop unless a.last - a + if @message + [@pos, @event, @tok, @state, @message] + else + [@pos, @event, @tok, @state] + end end end @@ -152,17 +197,19 @@ class Ripper def on_heredoc_dedent(v, w) ignored_sp = [] heredoc = @buf.last - heredoc.each_with_index do |e, i| - if Elem === e and e.event == :on_tstring_content and e.pos[1].zero? - tok = e.tok.dup if w > 0 and /\A\s/ =~ e.tok - if (n = dedent_string(e.tok, w)) > 0 - if e.tok.empty? - e.tok = tok[0, n] - e.event = :on_ignored_sp - next + if Array === heredoc + heredoc.each_with_index do |e, i| + if Elem === e and e.event == :on_tstring_content and e.pos[1].zero? + tok = e.tok.dup if w > 0 and /\A\s/ =~ e.tok + if (n = dedent_string(e.tok, w)) > 0 + if e.tok.empty? + e.tok = tok[0, n] + e.event = :on_ignored_sp + next + end + ignored_sp << [i, Elem.new(e.pos.dup, :on_ignored_sp, tok[0, n], e.state)] + e.pos[1] += n end - ignored_sp << [i, Elem.new(e.pos.dup, :on_ignored_sp, tok[0, n], e.state)] - e.pos[1] += n end end end @@ -182,7 +229,7 @@ class Ripper def on_heredoc_end(tok) @buf.push Elem.new([lineno(), column()], __callee__, tok, state()) - @buf = @stack.pop + @buf = @stack.pop unless @stack.empty? end def _push_token(tok) @@ -196,7 +243,12 @@ class Ripper end def on_error2(mesg, elem) - @errors.push Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg) + if elem + elem = Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg) + else + elem = Elem.new([lineno(), column()], __callee__, token(), state(), mesg) + end + @errors.push elem end PARSER_EVENTS.grep(/_error\z/) do |e| arity = PARSER_EVENT_TABLE.fetch(e) @@ -207,6 +259,7 @@ class Ripper (SCANNER_EVENTS.map {|event|:"on_#{event}"} - private_instance_methods(false)).each do |event| alias_method event, :_push_token end + # :startdoc: end # [EXPERIMENTAL] diff --git a/ext/ripper/ripper_init.c.tmpl b/ext/ripper/ripper_init.c.tmpl new file mode 100644 index 0000000000..11e432423d --- /dev/null +++ b/ext/ripper/ripper_init.c.tmpl @@ -0,0 +1,680 @@ +%# -*- c -*- +#include "ruby/ruby.h" +#include "ruby/encoding.h" +#include "internal.h" +#include "rubyparser.h" +#define YYSTYPE_IS_DECLARED +#include "parse.h" +#include "internal/parse.h" +#include "internal/ruby_parser.h" +#include "node.h" +#include "eventids1.h" +#include "eventids2.h" +#include "ripper_init.h" + +#define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),rb_ruby_parser_enc(p)) +#define RIPPER_VERSION "0.1.0" + +ID id_warn, id_warning, id_gets, id_assoc; + +enum lex_type { + lex_type_str, + lex_type_io, + lex_type_generic, +}; + +struct ripper { + rb_parser_t *p; + enum lex_type type; + union { + struct lex_pointer_string ptr_str; + VALUE val; + } data; +}; + +static void +ripper_parser_mark2(void *ptr) +{ + struct ripper *r = (struct ripper*)ptr; + if (r->p) { + ripper_parser_mark(r->p); + + switch (r->type) { + case lex_type_str: + rb_gc_mark(r->data.ptr_str.str); + break; + case lex_type_io: + rb_gc_mark(r->data.val); + break; + case lex_type_generic: + rb_gc_mark(r->data.val); + break; + } + } +} + +static void +ripper_parser_free2(void *ptr) +{ + struct ripper *r = (struct ripper*)ptr; + if (r->p) ripper_parser_free(r->p); + xfree(r); +} + +static size_t +ripper_parser_memsize2(const void *ptr) +{ + struct ripper *r = (struct ripper*)ptr; + return (r->p) ? ripper_parser_memsize(r->p) : 0; +} + +static const rb_data_type_t parser_data_type = { + "ripper", + { + ripper_parser_mark2, + ripper_parser_free2, + ripper_parser_memsize2, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + +static rb_parser_string_t * +ripper_lex_get_generic(struct parser_params *p, rb_parser_input_data input, int line_count) +{ + VALUE src = (VALUE)input; + VALUE line = rb_funcallv_public(src, id_gets, 0, 0); + if (NIL_P(line)) return 0; + if (!RB_TYPE_P(line, T_STRING)) { + rb_raise(rb_eTypeError, + "gets returned %"PRIsVALUE" (expected String or nil)", + rb_obj_class(line)); + } + return rb_str_to_parser_string(p, line); +} + +void +ripper_compile_error(struct parser_params *p, const char *fmt, ...) +{ + VALUE str; + va_list args; + + va_start(args, fmt); + str = rb_vsprintf(fmt, args); + va_end(args); + rb_funcall(ripper_value(p), rb_intern("compile_error"), 1, str); + ripper_error(p); +} + +static rb_parser_string_t * +ripper_lex_io_get(struct parser_params *p, rb_parser_input_data input, int line_count) +{ + VALUE src = (VALUE)input; + VALUE line = rb_io_gets(src); + if (NIL_P(line)) return 0; + return rb_str_to_parser_string(p, line); +} + +static rb_parser_string_t * +ripper_lex_get_str(struct parser_params *p, rb_parser_input_data input, int line_count) +{ + return rb_parser_lex_get_str(p, (struct lex_pointer_string *)input); +} + +static VALUE +ripper_s_allocate(VALUE klass) +{ + struct ripper *r; + + VALUE self = TypedData_Make_Struct(klass, struct ripper, + &parser_data_type, r); + +#ifdef UNIVERSAL_PARSER + const rb_parser_config_t *config = rb_ruby_parser_config(); + r->p = rb_ripper_parser_params_allocate(config); +#else + r->p = rb_ruby_ripper_parser_allocate(); +#endif + rb_ruby_parser_set_value(r->p, self); + return self; +} + +static struct parser_params * +ripper_parser_params(VALUE self, bool initialized) +{ + struct ripper *r; + struct parser_params *p; + + TypedData_Get_Struct(self, struct ripper, &parser_data_type, r); + p = r->p; + if (initialized && !rb_ruby_ripper_initialized_p(p)) { + rb_raise(rb_eArgError, "method called for uninitialized object"); + } + return p; +} + +/* + * call-seq: + * ripper.error? -> Boolean + * + * Return true if parsed source has errors. + */ +static VALUE +ripper_error_p(VALUE vparser) +{ + struct parser_params *p = ripper_parser_params(vparser, false); + + return RBOOL(rb_ruby_parser_error_p(p)); +} + +/* + * call-seq: + * ripper.end_seen? -> Boolean + * + * Return true if parsed source ended by +\_\_END\_\_+. + */ +static VALUE +ripper_parser_end_seen_p(VALUE vparser) +{ + struct parser_params *p = ripper_parser_params(vparser, false); + + return RBOOL(rb_ruby_parser_end_seen_p(p)); +} + +/* + * call-seq: + * ripper.encoding -> encoding + * + * Return encoding of the source. + */ +static VALUE +ripper_parser_encoding(VALUE vparser) +{ + struct parser_params *p = ripper_parser_params(vparser, false); + + return rb_enc_from_encoding(rb_ruby_parser_encoding(p)); +} + +/* + * call-seq: + * ripper.yydebug -> true or false + * + * Get yydebug. + */ +static VALUE +ripper_parser_get_yydebug(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, false); + + return RBOOL(rb_ruby_parser_get_yydebug(p)); +} + +/* + * call-seq: + * ripper.yydebug = flag + * + * Set yydebug. + */ +static VALUE +ripper_parser_set_yydebug(VALUE self, VALUE flag) +{ + struct parser_params *p = ripper_parser_params(self, false); + + rb_ruby_parser_set_yydebug(p, RTEST(flag)); + return flag; +} + +/* + * call-seq: + * ripper.debug_output -> obj + * + * Get debug output. + */ +static VALUE +ripper_parser_get_debug_output(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, false); + + return rb_ruby_parser_debug_output(p); +} + +/* + * call-seq: + * ripper.debug_output = obj + * + * Set debug output. + */ +static VALUE +ripper_parser_set_debug_output(VALUE self, VALUE output) +{ + struct parser_params *p = ripper_parser_params(self, false); + + rb_ruby_parser_set_debug_output(p, output); + return output; +} + +static int +ripper_parser_dedent_string(struct parser_params *p, VALUE string, int width) +{ + int col; + rb_parser_string_t *str; + str = rb_str_to_parser_string(p, string); + col = rb_ruby_ripper_dedent_string(p, str, width); + rb_str_replace(string, rb_str_new_parser_string(str)); + rb_parser_string_free(p, str); + return col; +} + +#ifdef UNIVERSAL_PARSER +struct dedent_string_arg { + struct parser_params *p; + VALUE input; + VALUE width; +}; + +static VALUE +parser_dedent_string0(VALUE a) +{ + struct dedent_string_arg *arg = (void *)a; + int wid, col; + + StringValue(arg->input); + wid = NUM2UINT(arg->width); + col = ripper_parser_dedent_string(arg->p, arg->input, wid); + return INT2NUM(col); +} + +static VALUE +parser_free(VALUE a) +{ + struct parser_params *p = (void *)a; + + rb_ruby_parser_free(p); + return Qnil; +} +#endif + +/* + * call-seq: + * Ripper.dedent_string(input, width) -> Integer + * + * USE OF RIPPER LIBRARY ONLY. + * + * Strips up to +width+ leading whitespaces from +input+, + * and returns the stripped column width. + */ +#ifdef UNIVERSAL_PARSER +static VALUE +parser_dedent_string(VALUE self, VALUE input, VALUE width) +{ + struct parser_params *p; + struct dedent_string_arg args; + + p = rb_parser_params_new(); + + args.p = p; + args.input = input; + args.width = width; + return rb_ensure(parser_dedent_string0, (VALUE)&args, parser_free, (VALUE)p); +} +#else +static VALUE +parser_dedent_string(VALUE self, VALUE input, VALUE width) +{ + int wid, col; + + StringValue(input); + wid = NUM2UINT(width); + col = ripper_parser_dedent_string(0, input, wid); + return INT2NUM(col); +} +#endif + +/* + * call-seq: + * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper + * + * Create a new Ripper object. + * _src_ must be a String, an IO, or an Object which has #gets method. + * + * This method does not starts parsing. + * See also Ripper#parse and Ripper.parse. + */ +static VALUE +ripper_initialize(int argc, VALUE *argv, VALUE self) +{ + struct ripper *r; + struct parser_params *p; + VALUE src, fname, lineno; + rb_parser_lex_gets_func *gets; + VALUE sourcefile_string; + const char *sourcefile; + int sourceline; + rb_parser_input_data input; + + p = ripper_parser_params(self, false); + TypedData_Get_Struct(self, struct ripper, &parser_data_type, r); + rb_scan_args(argc, argv, "12", &src, &fname, &lineno); + if (RB_TYPE_P(src, T_FILE)) { + gets = ripper_lex_io_get; + r->type = lex_type_io; + r->data.val = src; + input = (rb_parser_input_data)src; + } + else if (rb_respond_to(src, id_gets)) { + gets = ripper_lex_get_generic; + r->type = lex_type_generic; + r->data.val = src; + input = (rb_parser_input_data)src; + } + else { + StringValue(src); + gets = ripper_lex_get_str; + r->type = lex_type_str; + r->data.ptr_str.str = src; + r->data.ptr_str.ptr = 0; + input = (rb_parser_input_data)&r->data.ptr_str; + } + if (NIL_P(fname)) { + fname = STR_NEW2("(ripper)"); + OBJ_FREEZE(fname); + } + else { + StringValueCStr(fname); + fname = rb_str_new_frozen(fname); + } + rb_ruby_ripper_parser_initialize(p); + + sourcefile_string = fname; + sourcefile = RSTRING_PTR(fname); + sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1; + + rb_ruby_parser_ripper_initialize(p, gets, input, sourcefile_string, sourcefile, sourceline); + + return Qnil; +} + +static VALUE +ripper_parse0(VALUE vparser) +{ + struct parser_params *p = ripper_parser_params(vparser, false); + + rb_ruby_ripper_parse0(p); + return rb_ruby_parser_result(p); +} + +static VALUE +ripper_ensure(VALUE vparser) +{ + struct parser_params *p = ripper_parser_params(vparser, false); + + rb_ruby_parser_set_parsing_thread(p, Qnil); + return Qnil; +} + +/* + * call-seq: + * ripper.parse + * + * Start parsing and returns the value of the root action. + */ +static VALUE +ripper_parse(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + VALUE result; + + if (!NIL_P(rb_ruby_parser_parsing_thread(p))) { + if (rb_ruby_parser_parsing_thread(p) == rb_thread_current()) + rb_raise(rb_eArgError, "Ripper#parse is not reentrant"); + else + rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe"); + } + rb_ruby_parser_set_parsing_thread(p, rb_thread_current()); + result = rb_ensure(ripper_parse0, self, ripper_ensure, self); + RB_GC_GUARD(self); + + return result; +} + +/* + * call-seq: + * ripper.column -> Integer + * + * Return column number of current parsing line. + * This number starts from 0. + */ +static VALUE +ripper_column(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + long col; + + if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil; + col = rb_ruby_ripper_column(p); + return LONG2NUM(col); +} + +/* + * call-seq: + * ripper.filename -> String + * + * Return current parsing filename. + */ +static VALUE +ripper_filename(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + + return rb_ruby_parser_ruby_sourcefile_string(p); +} + +/* + * call-seq: + * ripper.lineno -> Integer + * + * Return line number of current parsing line. + * This number starts from 1. + */ +static VALUE +ripper_lineno(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + + if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil; + return INT2NUM(rb_ruby_parser_ruby_sourceline(p)); +} + +/* + * call-seq: + * ripper.state -> Integer + * + * Return scanner state of current token. + */ +static VALUE +ripper_state(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + + if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil; + return INT2NUM(rb_ruby_parser_lex_state(p)); +} + +/* + * call-seq: + * ripper.token -> String + * + * Return the current token string. + */ +static VALUE +ripper_token(VALUE self) +{ + struct parser_params *p = ripper_parser_params(self, true); + long pos, len; + VALUE str; + + if (NIL_P(rb_ruby_parser_parsing_thread(p))) return Qnil; + pos = rb_ruby_ripper_column(p); + len = rb_ruby_ripper_token_len(p); + str = rb_str_new_parser_string(rb_ruby_ripper_lex_lastline(p)); + return rb_str_subseq(str, pos, len); +} + +#ifdef RIPPER_DEBUG +/* :nodoc: */ +static VALUE +ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg) +{ + StringValue(msg); + if (UNDEF_P(obj)) { + rb_raise(rb_eArgError, "%"PRIsVALUE, msg); + } + return Qnil; +} + +/* :nodoc: */ +static VALUE +ripper_raw_value(VALUE self, VALUE obj) +{ + return ULONG2NUM(obj); +} + +/* :nodoc: */ +static VALUE +ripper_validate_object(VALUE self, VALUE x) +{ + if (x == Qfalse) return x; + if (x == Qtrue) return x; + if (NIL_P(x)) return x; + if (UNDEF_P(x)) + rb_raise(rb_eArgError, "Qundef given"); + if (FIXNUM_P(x)) return x; + if (SYMBOL_P(x)) return x; + switch (BUILTIN_TYPE(x)) { + case T_STRING: + case T_OBJECT: + case T_ARRAY: + case T_BIGNUM: + case T_FLOAT: + case T_COMPLEX: + case T_RATIONAL: + break; + default: + rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)", + (void *)x, rb_obj_classname(x)); + } + if (!RBASIC_CLASS(x)) { + rb_raise(rb_eArgError, "hidden ruby object: %p (%s)", + (void *)x, rb_builtin_type_name(TYPE(x))); + } + return x; +} +#endif + +#ifdef UNIVERSAL_PARSER +struct lex_state_name_arg { + struct parser_params *p; + VALUE state; +}; + +static VALUE +lex_state_name0(VALUE a) +{ + struct lex_state_name_arg *arg = (void *)a; + + return rb_ruby_ripper_lex_state_name(arg->p, NUM2INT(arg->state)); +} +#endif + +/* + * call-seq: + * Ripper.lex_state_name(integer) -> string + * + * Returns a string representation of lex_state. + */ +#ifdef UNIVERSAL_PARSER +static VALUE +ripper_lex_state_name(VALUE self, VALUE state) +{ + struct parser_params *p; + struct lex_state_name_arg args; + + p = rb_parser_params_new(); + + args.p = p; + args.state = state; + + return rb_ensure(lex_state_name0, (VALUE)&args, parser_free, (VALUE)p); +} +#else +static VALUE +ripper_lex_state_name(VALUE self, VALUE state) +{ + return rb_ruby_ripper_lex_state_name(0, NUM2INT(state)); +} +#endif + +void +Init_ripper(void) +{ + ripper_init_eventids1(); + ripper_init_eventids2(); + id_warn = rb_intern_const("warn"); + id_warning = rb_intern_const("warning"); + id_gets = rb_intern_const("gets"); + id_assoc = rb_intern_const("=>"); + + InitVM(ripper); +} + +void +InitVM_ripper(void) +{ + VALUE Ripper; + + Ripper = rb_define_class("Ripper", rb_cObject); + /* version of Ripper */ + rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION)); + rb_define_alloc_func(Ripper, ripper_s_allocate); + rb_define_method(Ripper, "initialize", ripper_initialize, -1); + rb_define_method(Ripper, "parse", ripper_parse, 0); + rb_define_method(Ripper, "column", ripper_column, 0); + rb_define_method(Ripper, "filename", ripper_filename, 0); + rb_define_method(Ripper, "lineno", ripper_lineno, 0); + rb_define_method(Ripper, "state", ripper_state, 0); + rb_define_method(Ripper, "token", ripper_token, 0); + rb_define_method(Ripper, "end_seen?", ripper_parser_end_seen_p, 0); + rb_define_method(Ripper, "encoding", ripper_parser_encoding, 0); + rb_define_method(Ripper, "yydebug", ripper_parser_get_yydebug, 0); + rb_define_method(Ripper, "yydebug=", ripper_parser_set_yydebug, 1); + rb_define_method(Ripper, "debug_output", ripper_parser_get_debug_output, 0); + rb_define_method(Ripper, "debug_output=", ripper_parser_set_debug_output, 1); + rb_define_method(Ripper, "error?", ripper_error_p, 0); +#ifdef RIPPER_DEBUG + rb_define_method(Ripper, "assert_Qundef", ripper_assert_Qundef, 2); + rb_define_method(Ripper, "rawVALUE", ripper_raw_value, 1); + rb_define_method(Ripper, "validate_object", ripper_validate_object, 1); +#endif + + rb_define_singleton_method(Ripper, "dedent_string", parser_dedent_string, 2); + rb_define_private_method(Ripper, "dedent_string", parser_dedent_string, 2); + + rb_define_singleton_method(Ripper, "lex_state_name", ripper_lex_state_name, 1); + +<% @exprs.each do |expr, desc| -%> + /* <%=desc%> */ + rb_define_const(Ripper, "<%=expr%>", INT2NUM(<%=expr%>)); +<% end %> + ripper_init_eventids1_table(Ripper); + ripper_init_eventids2_table(Ripper); + +# if 0 + /* Hack to let RDoc document SCRIPT_LINES__ */ + + /* + * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded + * after the assignment will be added as an Array of lines with the file + * name as the key. + */ + rb_define_global_const("SCRIPT_LINES__", Qnil); +#endif +} diff --git a/ext/ripper/ripper_init.h b/ext/ripper/ripper_init.h new file mode 100644 index 0000000000..9d228107d1 --- /dev/null +++ b/ext/ripper/ripper_init.h @@ -0,0 +1,6 @@ +#ifndef RIPPER_INIT_H +#define RIPPER_INIT_H + +PRINTF_ARGS(void ripper_compile_error(struct parser_params*, const char *fmt, ...), 2, 3); + +#endif /* RIPPER_INIT_H */ diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb index 49ff51711f..38f859dd97 100644 --- a/ext/ripper/tools/dsl.rb +++ b/ext/ripper/tools/dsl.rb @@ -1,83 +1,177 @@ +# frozen_string_literal: true + # Simple DSL implementation for Ripper code generation # -# input: /*% ripper: stmts_add(stmts_new, void_stmt) %*/ +# input: /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/ # output: # VALUE v1, v2; # v1 = dispatch0(stmts_new); # v2 = dispatch0(void_stmt); # $$ = dispatch2(stmts_add, v1, v2); - -$dollar = "$$" -alias $$ $dollar +# +# - The code must be a single line. +# +# - The code is basically Ruby code, even if it appears like in C and +# the result will be processed as C. e.g., comments need to be in +# Ruby style. class DSL - def initialize(code, options) + TAG_PATTERN = /(?><[a-zA-Z0-9_]+>)/.source + NAME_PATTERN = /(?>\$|\d+|[a-zA-Z_][a-zA-Z0-9_]*|\[[a-zA-Z_.][-a-zA-Z0-9_.]*\])(?>(?:\.|->)[a-zA-Z_][a-zA-Z0-9_]*)*/.source + NOT_REF_PATTERN = /(?>\#.*|[^\"$@]*|"(?>\\.|[^\"])*")/.source + + def self.line?(line, lineno = nil, indent: nil) + if %r<(?<space>\s*)/\*% *ripper(?:\[(?<option>.*?)\])?: *(?<code>.*?) *%\*/> =~ line + new(code, comma_split(option), lineno, indent: indent || space) + end + end + + def self.comma_split(str) + str or return [] + str.scan(/(([^(,)]+|\((?:,|\g<0>)*\))+)/).map(&:first) + end + + using Module.new { + refine Array do + def to_s + if empty? + "rb_ary_new()" + else + "rb_ary_new_from_args(#{size}, #{map(&:to_s).join(', ')})" + end + end + end + } + + class Var + class Table < Hash + def initialize(&block) + super() {|tbl, arg| + tbl.fetch(arg, &block) + } + end + + def fetch(arg, &block) + super { + self[arg] = Var.new(self, arg, &block) + } + end + + def add(&block) + v = new_var + self[v] = Var.new(self, v, &block) + end + + def defined?(name) + name = name.to_s + any? {|_, v| v.var == name} + end + + def new_var + "v#{size+1}" + end + end + + attr_reader :var, :value + + PRETTY_PRINT_INSTANCE_VARIABLES = instance_methods(false).freeze + + def pretty_print_instance_variables + PRETTY_PRINT_INSTANCE_VARIABLES + end + + alias to_s var + + def initialize(table, arg, &block) + @var = table.new_var + @value = yield arg + @table = table + end + + # Indexing. + # + # $:1 -> v1=get_value($:1) + # $:1[0] -> rb_ary_entry(v1, 0) + # $:1[0..1] -> [rb_ary_entry(v1, 0), rb_ary_entry(v1, 1)] + # *$:1[0..1] -> rb_ary_entry(v1, 0), rb_ary_entry(v1, 1) + # + # Splat needs `[range]` because `Var` does not have the length info. + def [](idx) + if ::Range === idx + idx.map {|i| self[i]} + else + @table.fetch("#@var[#{idx}]") {"rb_ary_entry(#{@var}, #{idx})"} + end + end + end + + def initialize(code, options, lineno = nil, indent: "\t\t\t") + @lineno = lineno + @indent = indent @events = {} @error = options.include?("error") - @brace = options.include?("brace") if options.include?("final") @final = "p->result" else - @final = (options.grep(/\A\$(?:\$|\d+)\z/)[0] || "$$") + @final = (options.grep(/\A\$#{NAME_PATTERN}\z/o)[0] || "p->s_lvalue") end - @vars = 0 - # create $1 == "$1", $2 == "$2", ... - s = (1..20).map {|n| "$#{n}"} - re = Array.new(s.size, "([^\0]+)") - /#{re.join("\0")}/ =~ s.join("\0") + bind = dsl_binding + @var_table = Var::Table.new {|arg| "get_value(#{arg})"} + code = code.gsub(%r[\G#{NOT_REF_PATTERN}\K(\$|\$:|@)#{TAG_PATTERN}?#{NAME_PATTERN}]o) { + if (arg = $&) == "$:$" + '"p->s_lvalue"' + elsif arg.start_with?("$:") + "(#{@var_table[arg]}=@var_table[#{arg.dump}])" + else + arg.dump + end + } + @last_value = bind.eval(code) + rescue SyntaxError + $stderr.puts "error on line #{@lineno}" if @lineno + raise + end + def dsl_binding(p = "p") # struct parser_params *p - p = p = "p" - - @code = "" - @last_value = eval(code) + binding end attr_reader :events undef lambda undef hash - undef class + undef :class def generate - s = "#@code#@final=#@last_value;" - s = "{VALUE #{ (1..@vars).map {|v| "v#{ v }" }.join(",") };#{ s }}" if @vars > 0 + s = "#@final=#@last_value;" s << "ripper_error(p);" if @error - s = "{#{ s }}" if @brace - "\t\t\t#{s}" - end - - def new_var - "v#{ @vars += 1 }" - end - - def opt_event(event, default, addend) - add_event(event, [default, addend], true) + unless @var_table.empty? + vars = @var_table.map {|_, v| "#{v.var}=#{v.value}"}.join(", ") + s = "VALUE #{ vars }; #{ s }" + end + "#{@indent}{#{s}}" end - def add_event(event, args, qundef_check = false) + def add_event(event, args) event = event.to_s.sub(/!\z/, "") @events[event] = args.size vars = [] args.each do |arg| - vars << v = new_var - @code << "#{ v }=#{ arg };" + arg = @var_table.add {arg} unless Var === arg + vars << arg end - v = new_var - d = "dispatch#{ args.size }(#{ [event, *vars].join(",") })" - d = "#{ vars.last }==Qundef ? #{ vars.first } : #{ d }" if qundef_check - @code << "#{ v }=#{ d };" - v + @var_table.add {"dispatch#{ args.size }(#{ [event, *vars].join(",") })"} end def method_missing(event, *args) if event.to_s =~ /!\z/ add_event(event, args) - elsif args.empty? and /\Aid[A-Z_]/ =~ event.to_s + elsif args.empty? and (/\Aid[A-Z_]/ =~ event or @var_table.defined?(event)) event else - "#{ event }(#{ args.join(", ") })" + "#{ event }(#{ args.map(&:to_s).join(", ") })" end end @@ -85,4 +179,3 @@ class DSL name end end - diff --git a/ext/ripper/tools/generate.rb b/ext/ripper/tools/generate.rb index 883e6ef2df..57ecac0b39 100644 --- a/ext/ripper/tools/generate.rb +++ b/ext/ripper/tools/generate.rb @@ -11,7 +11,7 @@ def main parser = @parser = OptionParser.new parser.banner = "Usage: #{File.basename($0)} --mode=MODE [--ids1src=PATH] [--ids2src=PATH] [--output=PATH]" - parser.on('--mode=MODE', 'check, eventids1, or eventids2table.') {|m| + parser.on('--mode=MODE', 'check, eventids1_h, eventids1, or eventids2table.') {|m| mode = m } parser.on('--ids1src=PATH', 'A source file of event-IDs 1 (parse.y).') {|path| @@ -45,6 +45,9 @@ def main abort "event crash: #{common.join(' ')}" end exit 0 + when 'eventids1_h' + usage 'no --ids1src' unless ids1src + result = generate_eventids1_h(read_ids1(ids1src)) when 'eventids1' usage 'no --ids1src' unless ids1src result = generate_eventids1(read_ids1(ids1src)) @@ -67,28 +70,44 @@ def usage(msg) exit false end -def generate_eventids1(ids) +def generate_eventids1_h(ids) buf = "".dup - buf << %Q[static struct {\n] + buf << %Q[#ifndef RIPPER_EVENTIDS1\n] + buf << %Q[#define RIPPER_EVENTIDS1\n] + buf << %Q[\n] + buf << %Q[#define RIPPER_ID(n) ripper_parser_ids.id_ ## n\n] + buf << %Q[void ripper_init_eventids1(void);\n] + buf << %Q[void ripper_init_eventids1_table(VALUE self);\n] + buf << %Q[\n] + buf << %Q[struct ripper_parser_ids {\n] ids.each do |id, arity| buf << %Q[ ID id_#{id};\n] end - buf << %Q[} ripper_parser_ids;\n] + buf << %Q[};\n] buf << %Q[\n] - ids.each do |id, arity| - buf << %Q[#define ripper_id_#{id} ripper_parser_ids.id_#{id}\n] - end + buf << %Q[#endif /* RIPPER_EVENTIDS1 */\n] + buf << %Q[\n] +end + +def generate_eventids1(ids) + buf = "".dup + buf << %Q[#include "ruby/ruby.h"\n] + buf << %Q[#include "eventids1.h"\n] + buf << %Q[\n] + buf << %Q[struct ripper_parser_ids ripper_parser_ids;\n] buf << %Q[\n] - buf << %Q[static void\n] + buf << %Q[void\n] buf << %Q[ripper_init_eventids1(void)\n] buf << %Q[{\n] - buf << %Q[#define set_id1(name) ripper_id_##name = rb_intern_const("on_"#name)\n] + buf << %Q[#define set_id1(name) RIPPER_ID(name) = rb_intern_const("on_"#name)\n] ids.each do |id, arity| buf << %Q[ set_id1(#{id});\n] end buf << %Q[}\n] buf << %Q[\n] - buf << %Q[static void\n] + buf << %Q[#define intern_sym(name) ID2SYM(rb_intern_const(name))\n] + buf << %Q[\n] + buf << %Q[void\n] buf << %Q[ripper_init_eventids1_table(VALUE self)\n] buf << %Q[{\n] buf << %Q[ VALUE h = rb_hash_new();\n] @@ -102,7 +121,11 @@ end def generate_eventids2_table(ids) buf = "".dup - buf << %Q[static void\n] + buf << %Q[#include "ruby/ruby.h"\n] + buf << %Q[\n] + buf << %Q[#define intern_sym(name) ID2SYM(rb_intern_const(name))\n] + buf << %Q[\n] + buf << %Q[void\n] buf << %Q[ripper_init_eventids2_table(VALUE self)\n] buf << %Q[{\n] buf << %Q[ VALUE h = rb_hash_new();\n] @@ -111,6 +134,8 @@ def generate_eventids2_table(ids) buf << %Q[ rb_hash_aset(h, intern_sym("#{id}"), INT2FIX(1));\n] end buf << %Q[}\n] + buf << %Q[\n] + buf << %Q[#define RIPPER_EVENTIDS2_TABLE_SIZE #{ids.size}\n] buf end @@ -146,9 +171,7 @@ def read_ids1_with_locations(path) line.scan(/\bdispatch(\d)\((\w+)/) do |arity, event| (h[event] ||= []).push [f.lineno, arity.to_i] end - if line =~ %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/> - gen = DSL.new($2, ($1 || "").split(",")) - gen.generate + if gen = DSL.line?(line, f.lineno) gen.events.each do |event, arity| (h[event] ||= []).push [f.lineno, arity.to_i] end diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb index b838a78db7..5e8a6e0cb5 100644 --- a/ext/ripper/tools/preproc.rb +++ b/ext/ripper/tools/preproc.rb @@ -5,11 +5,15 @@ require 'optparse' def main output = nil + template = nil parser = OptionParser.new - parser.banner = "Usage: #{File.basename($0)} [--output=PATH] <parse.y>" + parser.banner = "Usage: #{File.basename($0)} [--output=PATH] [--template=PATH] <parse.y>" parser.on('--output=PATH', 'An output file.') {|path| output = path } + parser.on('--template=PATH', 'An template file.') {|path| + template = path + } parser.on('--help', 'Prints this message and quit.') { puts parser.help exit true @@ -17,50 +21,56 @@ def main begin parser.parse! rescue OptionParser::ParseError => err - $stderr.puts err.message - $stderr.puts parser.help - exit false - end - unless ARGV.size == 1 - abort "wrong number of arguments (#{ARGV.size} for 1)" + warn err.message + abort parser.help end out = "".dup - File.open(ARGV[0]) {|f| - prelude f, out - grammar f, out - usercode f, out - } - if output - File.open(output, 'w') {|f| - f.write out + if ARGV[0] == "-" + unless ARGV.size == 2 + abort "wrong number of arguments (#{ARGV.size} for 2)" + end + process STDIN, out, ARGV[1], template + else + unless ARGV.size == 1 + abort "wrong number of arguments (#{ARGV.size} for 1)" + end + File.open(ARGV[0]) {|f| + process f, out, ARGV[0], template } + end + if output + File.write(output, out) else print out end end -def prelude(f, out) - @exprs = {} - lex_state_def = false +def process(f, out, path, template) + prelude f, out + grammar f, out + usercode f, out, path, template +end + +require_relative 'dsl' + +def generate_line(f, out) while line = f.gets - case line - when /\A%%/ + case + when gen = DSL.line?(line, f.lineno) + out << gen.generate << "\n" + when line.start_with?("%%") out << "%%\n" - return - when /\A%token/ - out << line.sub(/<\w+>/, '<val>') - when /\A%type/ - out << line.sub(/<\w+>/, '<val>') - when /^enum lex_state_(?:bits|e) \{/ - lex_state_def = true - out << line - when /^\}/ - lex_state_def = false - out << line + break else - out << line + out << yield(line) end - if lex_state_def + end +end + +def prelude(f, out) + @exprs = {} + generate_line(f, out) do |line| + if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line) case line when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\// @exprs[$1.chomp("_bit")] = $2.strip @@ -70,38 +80,45 @@ def prelude(f, out) @exprs[name] = "equals to " + (val.start_with?("(") ? "<tt>#{val}</tt>" : "+#{val}+") end end + line end end -require_relative "dsl" - def grammar(f, out) - while line = f.gets + generate_line(f, out) do |line| case line - when %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/> - out << DSL.new($2, ($1 || "").split(",")).generate << "\n" when %r</\*%%%\*/> - out << "#if 0\n" + "#if 0\n" when %r</\*%> - out << "#endif\n" + "#endif\n" when %r<%\*/> - out << "\n" - when /\A%%/ - out << "%%\n" - return + "\n" else - out << line + line end end end -def usercode(f, out) +def usercode(f, out, path, template) require 'erb' + lineno = nil + src = nil compiler = ERB::Compiler.new('%-') compiler.put_cmd = compiler.insert_cmd = "out.<<" - lineno = f.lineno - src, = compiler.compile(f.read) - eval(src, binding, f.path, lineno) + + if template + File.open(template) do |f| + out.clear + lineno = f.lineno + src, = compiler.compile(f.read) + path = template + end + else + lineno = f.lineno + src, = compiler.compile(f.read) + end + + eval(src, binding, path, lineno) end main diff --git a/ext/socket/addrinfo.h b/ext/socket/addrinfo.h index f0b977d79c..eb9eb8ae0e 100644 --- a/ext/socket/addrinfo.h +++ b/ext/socket/addrinfo.h @@ -129,14 +129,14 @@ #ifndef HAVE_TYPE_STRUCT_ADDRINFO struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ }; #endif @@ -158,18 +158,18 @@ struct addrinfo { #endif extern int getaddrinfo __P(( - const char *hostname, const char *servname, - const struct addrinfo *hints, - struct addrinfo **res)); + const char *hostname, const char *servname, + const struct addrinfo *hints, + struct addrinfo **res)); extern int getnameinfo __P(( - const struct sockaddr *sa, - socklen_t salen, - char *host, - socklen_t hostlen, - char *serv, - socklen_t servlen, - int flags)); + const struct sockaddr *sa, + socklen_t salen, + char *host, + socklen_t hostlen, + char *serv, + socklen_t servlen, + int flags)); extern void freehostent __P((struct hostent *)); extern void freeaddrinfo __P((struct addrinfo *)); diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index aa62cab0ec..f1e9e42524 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -333,11 +333,11 @@ ancillary_timestamp(VALUE self) if (level == SOL_SOCKET && type == SCM_BINTIME && RSTRING_LEN(data) == sizeof(struct bintime)) { struct bintime bt; - VALUE d, timev; + VALUE d, timev; memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt)); - d = ULL2NUM(0x100000000ULL); - d = mul(d,d); - timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d)); + d = ULL2NUM(0x100000000ULL); + d = mul(d,d); + timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d)); result = rb_time_num_new(timev, Qnil); } # endif @@ -697,7 +697,7 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret) struct ucred cred; memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred)); rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid); - rb_str_cat2(ret, " (ucred)"); + rb_str_cat2(ret, " (ucred)"); return 1; } else { @@ -712,7 +712,7 @@ static int anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret) { if (level != SOL_SOCKET && type != SCM_CREDS) - return 0; + return 0; /* * FreeBSD has struct cmsgcred and struct sockcred. @@ -727,46 +727,46 @@ anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret) #if defined(HAVE_TYPE_STRUCT_CMSGCRED) /* FreeBSD */ if (RSTRING_LEN(data) == sizeof(struct cmsgcred)) { - struct cmsgcred cred; + struct cmsgcred cred; memcpy(&cred, RSTRING_PTR(data), sizeof(struct cmsgcred)); rb_str_catf(ret, " pid=%u", cred.cmcred_pid); rb_str_catf(ret, " uid=%u", cred.cmcred_uid); rb_str_catf(ret, " euid=%u", cred.cmcred_euid); rb_str_catf(ret, " gid=%u", cred.cmcred_gid); - if (cred.cmcred_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred.cmcred_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]); - sep = ","; - } - } - rb_str_cat2(ret, " (cmsgcred)"); + if (cred.cmcred_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred.cmcred_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]); + sep = ","; + } + } + rb_str_cat2(ret, " (cmsgcred)"); return 1; } #endif #if defined(HAVE_TYPE_STRUCT_SOCKCRED) /* FreeBSD, NetBSD */ if ((size_t)RSTRING_LEN(data) >= SOCKCREDSIZE(0)) { - struct sockcred cred0, *cred; + struct sockcred cred0, *cred; memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0)); - if ((size_t)RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) { - cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups)); - memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups)); - rb_str_catf(ret, " uid=%u", cred->sc_uid); - rb_str_catf(ret, " euid=%u", cred->sc_euid); - rb_str_catf(ret, " gid=%u", cred->sc_gid); - rb_str_catf(ret, " egid=%u", cred->sc_egid); - if (cred0.sc_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred0.sc_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]); - sep = ","; - } - } - rb_str_cat2(ret, " (sockcred)"); - return 1; - } + if ((size_t)RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) { + cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups)); + memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups)); + rb_str_catf(ret, " uid=%u", cred->sc_uid); + rb_str_catf(ret, " euid=%u", cred->sc_euid); + rb_str_catf(ret, " gid=%u", cred->sc_gid); + rb_str_catf(ret, " egid=%u", cred->sc_egid); + if (cred0.sc_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred0.sc_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]); + sep = ","; + } + } + rb_str_cat2(ret, " (sockcred)"); + return 1; + } } #endif return 0; @@ -906,37 +906,37 @@ inspect_bintime_as_abstime(int level, int optname, VALUE data, VALUE ret) if (RSTRING_LEN(data) == sizeof(struct bintime)) { struct bintime bt; struct tm tm; - uint64_t frac_h, frac_l; - uint64_t scale_h, scale_l; - uint64_t tmp1, tmp2; - uint64_t res_h, res_l; + uint64_t frac_h, frac_l; + uint64_t scale_h, scale_l; + uint64_t tmp1, tmp2; + uint64_t res_h, res_l; char buf[32]; memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt)); LOCALTIME(bt.sec, tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); - /* res_h = frac * 10**19 / 2**64 */ + /* res_h = frac * 10**19 / 2**64 */ - frac_h = bt.frac >> 32; - frac_l = bt.frac & 0xffffffff; + frac_h = bt.frac >> 32; + frac_l = bt.frac & 0xffffffff; - scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */ - scale_l = 0x89e80000; + scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */ + scale_l = 0x89e80000; - res_h = frac_h * scale_h; - res_l = frac_l * scale_l; + res_h = frac_h * scale_h; + res_l = frac_l * scale_l; - tmp1 = frac_h * scale_l; - res_h += tmp1 >> 32; - tmp2 = res_l; - res_l += tmp1 & 0xffffffff; - if (res_l < tmp2) res_h++; + tmp1 = frac_h * scale_l; + res_h += tmp1 >> 32; + tmp2 = res_l; + res_l += tmp1 & 0xffffffff; + if (res_l < tmp2) res_h++; - tmp1 = frac_l * scale_h; - res_h += tmp1 >> 32; - tmp2 = res_l; - res_l += tmp1 & 0xffffffff; - if (res_l < tmp2) res_h++; + tmp1 = frac_l * scale_h; + res_h += tmp1 >> 32; + tmp2 = res_l; + res_l += tmp1 & 0xffffffff; + if (res_l < tmp2) res_h++; rb_str_catf(ret, " %s.%019"PRIu64, buf, res_h); return 1; @@ -1136,8 +1136,8 @@ rb_sendmsg(int fd, const struct msghdr *msg, int flags) static VALUE bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, - VALUE dest_sockaddr, VALUE controls, VALUE ex, - int nonblock) + VALUE dest_sockaddr, VALUE controls, VALUE ex, + int nonblock) { rb_io_t *fptr; struct msghdr mh; @@ -1160,15 +1160,15 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, tmp = rb_str_tmp_frozen_acquire(data); if (!RB_TYPE_P(controls, T_ARRAY)) { - controls = rb_ary_new(); + controls = rb_ary_new(); } controls_num = RARRAY_LENINT(controls); if (controls_num) { #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - int i; - size_t last_pad = 0; - const VALUE *controls_ptr = RARRAY_CONST_PTR(controls); + int i; + size_t last_pad = 0; + const VALUE *controls_ptr = RARRAY_CONST_PTR(controls); #if defined(__NetBSD__) int last_level = 0; int last_type = 0; @@ -1215,9 +1215,9 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, last_level = cmh.cmsg_level; last_type = cmh.cmsg_type; #endif - last_pad = cspace - cmh.cmsg_len; + last_pad = cspace - cmh.cmsg_len; } - if (last_pad) { + if (last_pad) { /* * This code removes the last padding from msg_controllen. * @@ -1242,10 +1242,10 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS) rb_str_set_len(controls_str, RSTRING_LEN(controls_str)-last_pad); #endif - } - RB_GC_GUARD(controls); + } + RB_GC_GUARD(controls); #else - rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented"); + rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented"); #endif } @@ -1256,7 +1256,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, #endif if (!NIL_P(dest_sockaddr)) - SockAddrStringValue(dest_sockaddr); + SockAddrStringValue(dest_sockaddr); rb_io_check_closed(fptr); @@ -1284,20 +1284,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, ss = rb_sendmsg(fptr->fd, &mh, flags); if (ss == -1) { - int e; - if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + int e; + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); goto retry; } - e = errno; - if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { - if (ex == Qfalse) { - return sym_wait_writable; - } - rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, - "sendmsg(2) would block"); - } - rb_syserr_fail(e, "sendmsg(2)"); + e = errno; + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { + if (ex == Qfalse) { + return sym_wait_writable; + } + rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, + "sendmsg(2) would block"); + } + rb_syserr_fail(e, "sendmsg(2)"); } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) RB_GC_GUARD(controls_str); @@ -1311,20 +1311,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, VALUE dest_sockaddr, - VALUE controls) + VALUE controls) { return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls, - Qtrue, 0); + Qtrue, 0); } #endif #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls, VALUE ex) + VALUE dest_sockaddr, VALUE controls, VALUE ex) { return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, - controls, ex, 1); + controls, ex, 1); } #endif @@ -1422,12 +1422,12 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) { if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) { int *fdp, *end; - VALUE ary = rb_ary_new(); - rb_ivar_set(ctl, rb_intern("unix_rights"), ary); + VALUE ary = rb_ary_new(); + rb_ivar_set(ctl, rb_intern("unix_rights"), ary); fdp = (int *)CMSG_DATA(cmh); end = (int *)((char *)cmh + cmh->cmsg_len); while ((char *)fdp + sizeof(int) <= (char *)end && - (char *)fdp + sizeof(int) <= msg_end) { + (char *)fdp + sizeof(int) <= msg_end) { int fd = *fdp; struct stat stbuf; VALUE io; @@ -1443,15 +1443,15 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) rb_ary_push(ary, io); fdp++; } - OBJ_FREEZE(ary); + OBJ_FREEZE(ary); } } #endif static VALUE bsock_recvmsg_internal(VALUE sock, - VALUE vmaxdatlen, VALUE vflags, VALUE vmaxctllen, - VALUE scm_rights, VALUE ex, int nonblock) + VALUE vmaxdatlen, VALUE vflags, VALUE vmaxctllen, + VALUE scm_rights, VALUE ex, int nonblock) { rb_io_t *fptr; int grow_buffer; @@ -1505,28 +1505,28 @@ bsock_recvmsg_internal(VALUE sock, #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (grow_buffer) { - int socktype; - socklen_t optlen = (socklen_t)sizeof(socktype); + int socktype; + socklen_t optlen = (socklen_t)sizeof(socktype); if (getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen) == -1) { - rb_sys_fail("getsockopt(SO_TYPE)"); - } - if (socktype == SOCK_STREAM) - grow_buffer = 0; + rb_sys_fail("getsockopt(SO_TYPE)"); + } + if (socktype == SOCK_STREAM) + grow_buffer = 0; } #endif retry: if (NIL_P(dat_str)) - dat_str = rb_str_tmp_new(maxdatlen); + dat_str = rb_str_tmp_new(maxdatlen); else - rb_str_resize(dat_str, maxdatlen); + rb_str_resize(dat_str, maxdatlen); datbuf = RSTRING_PTR(dat_str); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (NIL_P(ctl_str)) - ctl_str = rb_str_tmp_new(maxctllen); + ctl_str = rb_str_tmp_new(maxctllen); else - rb_str_resize(ctl_str, maxctllen); + rb_str_resize(ctl_str, maxctllen); ctlbuf = RSTRING_PTR(ctl_str); #endif @@ -1555,21 +1555,25 @@ bsock_recvmsg_internal(VALUE sock, ss = rb_recvmsg(fptr->fd, &mh, flags); + if (ss == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } + if (ss == -1) { - int e; - if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, Qnil)) { + int e; + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); goto retry; } - e = errno; - if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { + e = errno; + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { if (ex == Qfalse) { return sym_wait_readable; } - rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvmsg(2) would block"); + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvmsg(2) would block"); } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (!gc_done && (e == EMFILE || e == EMSGSIZE)) { + if (!gc_done && (e == EMFILE || e == EMSGSIZE)) { /* * When SCM_RIGHTS hit the file descriptors limit: * - Linux 2.6.18 causes success with MSG_CTRUNC @@ -1579,24 +1583,24 @@ bsock_recvmsg_internal(VALUE sock, gc_and_retry: rb_gc(); gc_done = 1; - goto retry; + goto retry; } #else - if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE) - ss = (ssize_t)iov.iov_len; - else + if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE) + ss = (ssize_t)iov.iov_len; + else #endif - rb_syserr_fail(e, "recvmsg(2)"); + rb_syserr_fail(e, "recvmsg(2)"); } if (grow_buffer) { - int grown = 0; - if (NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) { + int grown = 0; + if (NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) { if (SIZE_MAX/2 < maxdatlen) rb_raise(rb_eArgError, "max data length too big"); - maxdatlen *= 2; - grown = 1; - } + maxdatlen *= 2; + grown = 1; + } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (NIL_P(vmaxctllen) && (mh.msg_flags & MSG_CTRUNC)) { #define BIG_ENOUGH_SPACE 65536 @@ -1605,9 +1609,9 @@ bsock_recvmsg_internal(VALUE sock, /* there are big space bug truncated. * file descriptors limit? */ if (!gc_done) { - rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto gc_and_retry; - } + } } else { if (SIZE_MAX/2 < maxctllen) @@ -1616,13 +1620,13 @@ bsock_recvmsg_internal(VALUE sock, grown = 1; } #undef BIG_ENOUGH_SPACE - } + } #endif - if (grown) { + if (grown) { rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); - goto retry; - } - else { + goto retry; + } + else { grow_buffer = 0; if (flags != orig_flags) { rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); @@ -1636,31 +1640,31 @@ bsock_recvmsg_internal(VALUE sock, dat_str = rb_str_new(datbuf, ss); else { rb_str_resize(dat_str, ss); - rb_obj_reveal(dat_str, rb_cString); + rb_obj_reveal(dat_str, rb_cString); } - ret = rb_ary_new3(3, dat_str, - rsock_io_socket_addrinfo(sock, mh.msg_name, mh.msg_namelen), #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - INT2NUM(mh.msg_flags) + VALUE msg_flags = INT2NUM(mh.msg_flags); #else - Qnil + VALUE msg_flags = Qnil; #endif - ); + ret = rb_ary_new3(3, dat_str, + rsock_io_socket_addrinfo(sock, mh.msg_name, mh.msg_namelen), + msg_flags); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) family = rsock_getfamily(fptr); if (mh.msg_controllen) { - char *msg_end = (char *)mh.msg_control + mh.msg_controllen; + char *msg_end = (char *)mh.msg_control + mh.msg_controllen; for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) { VALUE ctl; - char *ctl_end; + char *ctl_end; size_t clen; if (cmh->cmsg_len == 0) { rb_raise(rb_eTypeError, "invalid control message (cmsg_len == 0)"); } ctl_end = (char*)cmh + cmh->cmsg_len; - clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); + clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_str_new((char*)CMSG_DATA(cmh), clen)); if (request_scm_rights) make_io_for_unix_rights(ctl, cmh, msg_end); @@ -1679,7 +1683,7 @@ bsock_recvmsg_internal(VALUE sock, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, - VALUE scm_rights) + VALUE scm_rights) { VALUE ex = Qtrue; return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0); @@ -1689,7 +1693,7 @@ rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, - VALUE scm_rights, VALUE ex) + VALUE scm_rights, VALUE ex) { return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1); } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 44fb7a4eb7..2fcae8eb54 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -94,16 +94,16 @@ bsock_shutdown(int argc, VALUE *argv, VALUE sock) rb_scan_args(argc, argv, "01", &howto); if (howto == Qnil) - how = SHUT_RDWR; + how = SHUT_RDWR; else { - how = rsock_shutdown_how_arg(howto); + how = rsock_shutdown_how_arg(howto); if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) { - rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR"); - } + rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR"); + } } GetOpenFile(sock, fptr); if (shutdown(fptr->fd, how) == -1) - rb_sys_fail("shutdown(2)"); + rb_sys_fail("shutdown(2)"); return INT2FIX(0); } @@ -124,9 +124,9 @@ bsock_close_read(VALUE sock) rb_io_t *fptr; GetOpenFile(sock, fptr); - shutdown(fptr->fd, 0); + shutdown(fptr->fd, SHUT_RD); if (!(fptr->mode & FMODE_WRITABLE)) { - return rb_io_close(sock); + return rb_io_close(sock); } fptr->mode &= ~FMODE_READABLE; @@ -155,9 +155,9 @@ bsock_close_write(VALUE sock) GetOpenFile(sock, fptr); if (!(fptr->mode & FMODE_READABLE)) { - return rb_io_close(sock); + return rb_io_close(sock); } - shutdown(fptr->fd, 1); + shutdown(fptr->fd, SHUT_WR); fptr->mode &= ~FMODE_WRITABLE; return Qnil; @@ -246,21 +246,21 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock) switch (TYPE(val)) { case T_FIXNUM: - i = FIX2INT(val); - goto numval; + i = FIX2INT(val); + goto numval; case T_FALSE: - i = 0; - goto numval; + i = 0; + goto numval; case T_TRUE: - i = 1; + i = 1; numval: - v = (char*)&i; vlen = (int)sizeof(i); - break; + v = (char*)&i; vlen = (int)sizeof(i); + break; default: - StringValue(val); - v = RSTRING_PTR(val); - vlen = RSTRING_SOCKLEN(val); - break; + StringValue(val); + v = RSTRING_PTR(val); + vlen = RSTRING_SOCKLEN(val); + break; } rb_io_check_closed(fptr); @@ -357,7 +357,7 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname) rb_io_check_closed(fptr); if (getsockopt(fptr->fd, level, option, buf, &len) < 0) - rsock_sys_fail_path("getsockopt(2)", fptr->pathv); + rsock_sys_fail_path("getsockopt(2)", fptr->pathv); return rsock_sockopt_new(family, level, option, rb_str_new(buf, len)); } @@ -385,7 +385,7 @@ bsock_getsockname(VALUE sock) GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); } @@ -416,7 +416,7 @@ bsock_getpeername(VALUE sock) GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); } @@ -453,7 +453,7 @@ bsock_getpeereid(VALUE self) gid_t egid; GetOpenFile(self, fptr); if (getpeereid(fptr->fd, &euid, &egid) == -1) - rb_sys_fail("getpeereid(3)"); + rb_sys_fail("getpeereid(3)"); return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid)); #elif defined(SO_PEERCRED) /* GNU/Linux */ rb_io_t *fptr; @@ -461,7 +461,7 @@ bsock_getpeereid(VALUE self) socklen_t len = sizeof(cred); GetOpenFile(self, fptr); if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) - rb_sys_fail("getsockopt(SO_PEERCRED)"); + rb_sys_fail("getsockopt(SO_PEERCRED)"); return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid)); #elif defined(HAVE_GETPEERUCRED) /* Solaris */ rb_io_t *fptr; @@ -469,7 +469,7 @@ bsock_getpeereid(VALUE self) VALUE ret; GetOpenFile(self, fptr); if (getpeerucred(fptr->fd, &uc) == -1) - rb_sys_fail("getpeerucred(3C)"); + rb_sys_fail("getpeerucred(3C)"); ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc))); ucred_free(uc); return ret; @@ -506,7 +506,7 @@ bsock_local_address(VALUE sock) GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); } @@ -540,7 +540,7 @@ bsock_remote_address(VALUE sock) GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); } @@ -597,11 +597,11 @@ rsock_bsock_send(int argc, VALUE *argv, VALUE socket) rb_io_wait(socket, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); #endif - ssize_t n = (ssize_t)BLOCKING_REGION_FD(func, &arg); + ssize_t n = (ssize_t)rb_io_blocking_region(fptr, func, &arg); if (n >= 0) return SSIZET2NUM(n); - if (rb_io_maybe_wait_writable(errno, socket, Qnil)) { + if (rb_io_maybe_wait_writable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) { continue; } @@ -656,10 +656,10 @@ bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) GetOpenFile(sock, fptr); if (RTEST(state)) { - fptr->mode |= FMODE_NOREVLOOKUP; + fptr->mode |= FMODE_NOREVLOOKUP; } else { - fptr->mode &= ~FMODE_NOREVLOOKUP; + fptr->mode &= ~FMODE_NOREVLOOKUP; } return sock; } @@ -747,9 +747,9 @@ rsock_init_basicsocket(void) rb_undef_method(rb_cBasicSocket, "initialize"); rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup", - bsock_do_not_rev_lookup, 0); + bsock_do_not_rev_lookup, 0); rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=", - bsock_do_not_rev_lookup_set, 1); + bsock_do_not_rev_lookup_set, 1); rb_define_singleton_method(rb_cBasicSocket, "for_fd", bsock_s_for_fd, 1); rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0); @@ -770,23 +770,23 @@ rsock_init_basicsocket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cBasicSocket, - "__recv_nonblock", bsock_recv_nonblock, 4); + "__recv_nonblock", bsock_recv_nonblock, 4); #if MSG_DONTWAIT_RELIABLE rb_define_private_method(rb_cBasicSocket, - "__read_nonblock", rsock_read_nonblock, 3); + "__read_nonblock", rsock_read_nonblock, 3); rb_define_private_method(rb_cBasicSocket, - "__write_nonblock", rsock_write_nonblock, 2); + "__write_nonblock", rsock_write_nonblock, 2); #endif /* in ancdata.c */ rb_define_private_method(rb_cBasicSocket, "__sendmsg", - rsock_bsock_sendmsg, 4); + rsock_bsock_sendmsg, 4); rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock", - rsock_bsock_sendmsg_nonblock, 5); + rsock_bsock_sendmsg_nonblock, 5); rb_define_private_method(rb_cBasicSocket, "__recvmsg", - rsock_bsock_recvmsg, 4); + rsock_bsock_recvmsg, 4); rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock", - rsock_bsock_recvmsg_nonblock, 5); + rsock_bsock_recvmsg_nonblock, 5); } diff --git a/ext/socket/constants.c b/ext/socket/constants.c index 1bbb53b173..1213f2ae17 100644 --- a/ext/socket/constants.c +++ b/ext/socket/constants.c @@ -26,14 +26,14 @@ constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char * goto str; } else if (!NIL_P(tmp = rb_check_string_type(arg))) { - arg = tmp; + arg = tmp; str: ptr = RSTRING_PTR(arg); if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1) - rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); + rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); } else { - ret = NUM2INT(arg); + ret = NUM2INT(arg); } return ret; } diff --git a/ext/socket/depend b/ext/socket/depend index f2d7a67bcb..77f6239a3d 100644 --- a/ext/socket/depend +++ b/ext/socket/depend @@ -12,8 +12,8 @@ constdefs.c: constdefs.h # AUTOGENERATED DEPENDENCIES START ancdata.o: $(RUBY_EXTCONF_H) ancdata.o: $(arch_hdrdir)/ruby/config.h -ancdata.o: $(hdrdir)/ruby.h ancdata.o: $(hdrdir)/ruby/assert.h +ancdata.o: $(hdrdir)/ruby/atomic.h ancdata.o: $(hdrdir)/ruby/backward.h ancdata.o: $(hdrdir)/ruby/backward/2/assume.h ancdata.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -28,6 +28,7 @@ ancdata.o: $(hdrdir)/ruby/defines.h ancdata.o: $(hdrdir)/ruby/encoding.h ancdata.o: $(hdrdir)/ruby/fiber/scheduler.h ancdata.o: $(hdrdir)/ruby/intern.h +ancdata.o: $(hdrdir)/ruby/internal/abi.h ancdata.o: $(hdrdir)/ruby/internal/anyargs.h ancdata.o: $(hdrdir)/ruby/internal/arithmetic.h ancdata.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -65,6 +66,7 @@ ancdata.o: $(hdrdir)/ruby/internal/attr/noexcept.h ancdata.o: $(hdrdir)/ruby/internal/attr/noinline.h ancdata.o: $(hdrdir)/ruby/internal/attr/nonnull.h ancdata.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ancdata.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ancdata.o: $(hdrdir)/ruby/internal/attr/pure.h ancdata.o: $(hdrdir)/ruby/internal/attr/restrict.h ancdata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -133,7 +135,6 @@ ancdata.o: $(hdrdir)/ruby/internal/intern/enumerator.h ancdata.o: $(hdrdir)/ruby/internal/intern/error.h ancdata.o: $(hdrdir)/ruby/internal/intern/eval.h ancdata.o: $(hdrdir)/ruby/internal/intern/file.h -ancdata.o: $(hdrdir)/ruby/internal/intern/gc.h ancdata.o: $(hdrdir)/ruby/internal/intern/hash.h ancdata.o: $(hdrdir)/ruby/internal/intern/io.h ancdata.o: $(hdrdir)/ruby/internal/intern/load.h @@ -150,6 +151,7 @@ ancdata.o: $(hdrdir)/ruby/internal/intern/re.h ancdata.o: $(hdrdir)/ruby/internal/intern/ruby.h ancdata.o: $(hdrdir)/ruby/internal/intern/select.h ancdata.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ancdata.o: $(hdrdir)/ruby/internal/intern/set.h ancdata.o: $(hdrdir)/ruby/internal/intern/signal.h ancdata.o: $(hdrdir)/ruby/internal/intern/sprintf.h ancdata.o: $(hdrdir)/ruby/internal/intern/string.h @@ -164,12 +166,12 @@ ancdata.o: $(hdrdir)/ruby/internal/memory.h ancdata.o: $(hdrdir)/ruby/internal/method.h ancdata.o: $(hdrdir)/ruby/internal/module.h ancdata.o: $(hdrdir)/ruby/internal/newobj.h -ancdata.o: $(hdrdir)/ruby/internal/rgengc.h ancdata.o: $(hdrdir)/ruby/internal/scan_args.h ancdata.o: $(hdrdir)/ruby/internal/special_consts.h ancdata.o: $(hdrdir)/ruby/internal/static_assert.h ancdata.o: $(hdrdir)/ruby/internal/stdalign.h ancdata.o: $(hdrdir)/ruby/internal/stdbool.h +ancdata.o: $(hdrdir)/ruby/internal/stdckdint.h ancdata.o: $(hdrdir)/ruby/internal/symbol.h ancdata.o: $(hdrdir)/ruby/internal/value.h ancdata.o: $(hdrdir)/ruby/internal/value_type.h @@ -184,27 +186,50 @@ ancdata.o: $(hdrdir)/ruby/ruby.h ancdata.o: $(hdrdir)/ruby/st.h ancdata.o: $(hdrdir)/ruby/subst.h ancdata.o: $(hdrdir)/ruby/thread.h +ancdata.o: $(hdrdir)/ruby/thread_native.h ancdata.o: $(hdrdir)/ruby/util.h +ancdata.o: $(hdrdir)/ruby/version.h +ancdata.o: $(top_srcdir)/ccan/check_type/check_type.h +ancdata.o: $(top_srcdir)/ccan/container_of/container_of.h +ancdata.o: $(top_srcdir)/ccan/list/list.h +ancdata.o: $(top_srcdir)/ccan/str/str.h +ancdata.o: $(top_srcdir)/encindex.h +ancdata.o: $(top_srcdir)/id_table.h ancdata.o: $(top_srcdir)/internal.h ancdata.o: $(top_srcdir)/internal/array.h +ancdata.o: $(top_srcdir)/internal/basic_operators.h +ancdata.o: $(top_srcdir)/internal/box.h ancdata.o: $(top_srcdir)/internal/compilers.h ancdata.o: $(top_srcdir)/internal/error.h ancdata.o: $(top_srcdir)/internal/gc.h +ancdata.o: $(top_srcdir)/internal/imemo.h ancdata.o: $(top_srcdir)/internal/io.h +ancdata.o: $(top_srcdir)/internal/sanitizers.h ancdata.o: $(top_srcdir)/internal/serial.h +ancdata.o: $(top_srcdir)/internal/set_table.h ancdata.o: $(top_srcdir)/internal/static_assert.h ancdata.o: $(top_srcdir)/internal/string.h ancdata.o: $(top_srcdir)/internal/thread.h ancdata.o: $(top_srcdir)/internal/vm.h ancdata.o: $(top_srcdir)/internal/warnings.h +ancdata.o: $(top_srcdir)/method.h +ancdata.o: $(top_srcdir)/node.h +ancdata.o: $(top_srcdir)/ruby_assert.h +ancdata.o: $(top_srcdir)/ruby_atomic.h +ancdata.o: $(top_srcdir)/rubyparser.h +ancdata.o: $(top_srcdir)/shape.h +ancdata.o: $(top_srcdir)/thread_pthread.h +ancdata.o: $(top_srcdir)/vm_core.h +ancdata.o: $(top_srcdir)/vm_opts.h ancdata.o: ancdata.c ancdata.o: constdefs.h ancdata.o: rubysocket.h ancdata.o: sockport.h +ancdata.o: {$(VPATH)}id.h basicsocket.o: $(RUBY_EXTCONF_H) basicsocket.o: $(arch_hdrdir)/ruby/config.h -basicsocket.o: $(hdrdir)/ruby.h basicsocket.o: $(hdrdir)/ruby/assert.h +basicsocket.o: $(hdrdir)/ruby/atomic.h basicsocket.o: $(hdrdir)/ruby/backward.h basicsocket.o: $(hdrdir)/ruby/backward/2/assume.h basicsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -219,6 +244,7 @@ basicsocket.o: $(hdrdir)/ruby/defines.h basicsocket.o: $(hdrdir)/ruby/encoding.h basicsocket.o: $(hdrdir)/ruby/fiber/scheduler.h basicsocket.o: $(hdrdir)/ruby/intern.h +basicsocket.o: $(hdrdir)/ruby/internal/abi.h basicsocket.o: $(hdrdir)/ruby/internal/anyargs.h basicsocket.o: $(hdrdir)/ruby/internal/arithmetic.h basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -256,6 +282,7 @@ basicsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h basicsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h basicsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h basicsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h basicsocket.o: $(hdrdir)/ruby/internal/attr/pure.h basicsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h basicsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -324,7 +351,6 @@ basicsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h basicsocket.o: $(hdrdir)/ruby/internal/intern/error.h basicsocket.o: $(hdrdir)/ruby/internal/intern/eval.h basicsocket.o: $(hdrdir)/ruby/internal/intern/file.h -basicsocket.o: $(hdrdir)/ruby/internal/intern/gc.h basicsocket.o: $(hdrdir)/ruby/internal/intern/hash.h basicsocket.o: $(hdrdir)/ruby/internal/intern/io.h basicsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -341,6 +367,7 @@ basicsocket.o: $(hdrdir)/ruby/internal/intern/re.h basicsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h basicsocket.o: $(hdrdir)/ruby/internal/intern/select.h basicsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/set.h basicsocket.o: $(hdrdir)/ruby/internal/intern/signal.h basicsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h basicsocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -355,12 +382,12 @@ basicsocket.o: $(hdrdir)/ruby/internal/memory.h basicsocket.o: $(hdrdir)/ruby/internal/method.h basicsocket.o: $(hdrdir)/ruby/internal/module.h basicsocket.o: $(hdrdir)/ruby/internal/newobj.h -basicsocket.o: $(hdrdir)/ruby/internal/rgengc.h basicsocket.o: $(hdrdir)/ruby/internal/scan_args.h basicsocket.o: $(hdrdir)/ruby/internal/special_consts.h basicsocket.o: $(hdrdir)/ruby/internal/static_assert.h basicsocket.o: $(hdrdir)/ruby/internal/stdalign.h basicsocket.o: $(hdrdir)/ruby/internal/stdbool.h +basicsocket.o: $(hdrdir)/ruby/internal/stdckdint.h basicsocket.o: $(hdrdir)/ruby/internal/symbol.h basicsocket.o: $(hdrdir)/ruby/internal/value.h basicsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -375,27 +402,50 @@ basicsocket.o: $(hdrdir)/ruby/ruby.h basicsocket.o: $(hdrdir)/ruby/st.h basicsocket.o: $(hdrdir)/ruby/subst.h basicsocket.o: $(hdrdir)/ruby/thread.h +basicsocket.o: $(hdrdir)/ruby/thread_native.h basicsocket.o: $(hdrdir)/ruby/util.h +basicsocket.o: $(hdrdir)/ruby/version.h +basicsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +basicsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +basicsocket.o: $(top_srcdir)/ccan/list/list.h +basicsocket.o: $(top_srcdir)/ccan/str/str.h +basicsocket.o: $(top_srcdir)/encindex.h +basicsocket.o: $(top_srcdir)/id_table.h basicsocket.o: $(top_srcdir)/internal.h basicsocket.o: $(top_srcdir)/internal/array.h +basicsocket.o: $(top_srcdir)/internal/basic_operators.h +basicsocket.o: $(top_srcdir)/internal/box.h basicsocket.o: $(top_srcdir)/internal/compilers.h basicsocket.o: $(top_srcdir)/internal/error.h basicsocket.o: $(top_srcdir)/internal/gc.h +basicsocket.o: $(top_srcdir)/internal/imemo.h basicsocket.o: $(top_srcdir)/internal/io.h +basicsocket.o: $(top_srcdir)/internal/sanitizers.h basicsocket.o: $(top_srcdir)/internal/serial.h +basicsocket.o: $(top_srcdir)/internal/set_table.h basicsocket.o: $(top_srcdir)/internal/static_assert.h basicsocket.o: $(top_srcdir)/internal/string.h basicsocket.o: $(top_srcdir)/internal/thread.h basicsocket.o: $(top_srcdir)/internal/vm.h basicsocket.o: $(top_srcdir)/internal/warnings.h +basicsocket.o: $(top_srcdir)/method.h +basicsocket.o: $(top_srcdir)/node.h +basicsocket.o: $(top_srcdir)/ruby_assert.h +basicsocket.o: $(top_srcdir)/ruby_atomic.h +basicsocket.o: $(top_srcdir)/rubyparser.h +basicsocket.o: $(top_srcdir)/shape.h +basicsocket.o: $(top_srcdir)/thread_pthread.h +basicsocket.o: $(top_srcdir)/vm_core.h +basicsocket.o: $(top_srcdir)/vm_opts.h basicsocket.o: basicsocket.c basicsocket.o: constdefs.h basicsocket.o: rubysocket.h basicsocket.o: sockport.h +basicsocket.o: {$(VPATH)}id.h constants.o: $(RUBY_EXTCONF_H) constants.o: $(arch_hdrdir)/ruby/config.h -constants.o: $(hdrdir)/ruby.h constants.o: $(hdrdir)/ruby/assert.h +constants.o: $(hdrdir)/ruby/atomic.h constants.o: $(hdrdir)/ruby/backward.h constants.o: $(hdrdir)/ruby/backward/2/assume.h constants.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -410,6 +460,7 @@ constants.o: $(hdrdir)/ruby/defines.h constants.o: $(hdrdir)/ruby/encoding.h constants.o: $(hdrdir)/ruby/fiber/scheduler.h constants.o: $(hdrdir)/ruby/intern.h +constants.o: $(hdrdir)/ruby/internal/abi.h constants.o: $(hdrdir)/ruby/internal/anyargs.h constants.o: $(hdrdir)/ruby/internal/arithmetic.h constants.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -447,6 +498,7 @@ constants.o: $(hdrdir)/ruby/internal/attr/noexcept.h constants.o: $(hdrdir)/ruby/internal/attr/noinline.h constants.o: $(hdrdir)/ruby/internal/attr/nonnull.h constants.o: $(hdrdir)/ruby/internal/attr/noreturn.h +constants.o: $(hdrdir)/ruby/internal/attr/packed_struct.h constants.o: $(hdrdir)/ruby/internal/attr/pure.h constants.o: $(hdrdir)/ruby/internal/attr/restrict.h constants.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -515,7 +567,6 @@ constants.o: $(hdrdir)/ruby/internal/intern/enumerator.h constants.o: $(hdrdir)/ruby/internal/intern/error.h constants.o: $(hdrdir)/ruby/internal/intern/eval.h constants.o: $(hdrdir)/ruby/internal/intern/file.h -constants.o: $(hdrdir)/ruby/internal/intern/gc.h constants.o: $(hdrdir)/ruby/internal/intern/hash.h constants.o: $(hdrdir)/ruby/internal/intern/io.h constants.o: $(hdrdir)/ruby/internal/intern/load.h @@ -532,6 +583,7 @@ constants.o: $(hdrdir)/ruby/internal/intern/re.h constants.o: $(hdrdir)/ruby/internal/intern/ruby.h constants.o: $(hdrdir)/ruby/internal/intern/select.h constants.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +constants.o: $(hdrdir)/ruby/internal/intern/set.h constants.o: $(hdrdir)/ruby/internal/intern/signal.h constants.o: $(hdrdir)/ruby/internal/intern/sprintf.h constants.o: $(hdrdir)/ruby/internal/intern/string.h @@ -546,12 +598,12 @@ constants.o: $(hdrdir)/ruby/internal/memory.h constants.o: $(hdrdir)/ruby/internal/method.h constants.o: $(hdrdir)/ruby/internal/module.h constants.o: $(hdrdir)/ruby/internal/newobj.h -constants.o: $(hdrdir)/ruby/internal/rgengc.h constants.o: $(hdrdir)/ruby/internal/scan_args.h constants.o: $(hdrdir)/ruby/internal/special_consts.h constants.o: $(hdrdir)/ruby/internal/static_assert.h constants.o: $(hdrdir)/ruby/internal/stdalign.h constants.o: $(hdrdir)/ruby/internal/stdbool.h +constants.o: $(hdrdir)/ruby/internal/stdckdint.h constants.o: $(hdrdir)/ruby/internal/symbol.h constants.o: $(hdrdir)/ruby/internal/value.h constants.o: $(hdrdir)/ruby/internal/value_type.h @@ -566,28 +618,51 @@ constants.o: $(hdrdir)/ruby/ruby.h constants.o: $(hdrdir)/ruby/st.h constants.o: $(hdrdir)/ruby/subst.h constants.o: $(hdrdir)/ruby/thread.h +constants.o: $(hdrdir)/ruby/thread_native.h constants.o: $(hdrdir)/ruby/util.h +constants.o: $(hdrdir)/ruby/version.h +constants.o: $(top_srcdir)/ccan/check_type/check_type.h +constants.o: $(top_srcdir)/ccan/container_of/container_of.h +constants.o: $(top_srcdir)/ccan/list/list.h +constants.o: $(top_srcdir)/ccan/str/str.h +constants.o: $(top_srcdir)/encindex.h +constants.o: $(top_srcdir)/id_table.h constants.o: $(top_srcdir)/internal.h constants.o: $(top_srcdir)/internal/array.h +constants.o: $(top_srcdir)/internal/basic_operators.h +constants.o: $(top_srcdir)/internal/box.h constants.o: $(top_srcdir)/internal/compilers.h constants.o: $(top_srcdir)/internal/error.h constants.o: $(top_srcdir)/internal/gc.h +constants.o: $(top_srcdir)/internal/imemo.h constants.o: $(top_srcdir)/internal/io.h +constants.o: $(top_srcdir)/internal/sanitizers.h constants.o: $(top_srcdir)/internal/serial.h +constants.o: $(top_srcdir)/internal/set_table.h constants.o: $(top_srcdir)/internal/static_assert.h constants.o: $(top_srcdir)/internal/string.h constants.o: $(top_srcdir)/internal/thread.h constants.o: $(top_srcdir)/internal/vm.h constants.o: $(top_srcdir)/internal/warnings.h +constants.o: $(top_srcdir)/method.h +constants.o: $(top_srcdir)/node.h +constants.o: $(top_srcdir)/ruby_assert.h +constants.o: $(top_srcdir)/ruby_atomic.h +constants.o: $(top_srcdir)/rubyparser.h +constants.o: $(top_srcdir)/shape.h +constants.o: $(top_srcdir)/thread_pthread.h +constants.o: $(top_srcdir)/vm_core.h +constants.o: $(top_srcdir)/vm_opts.h constants.o: constants.c constants.o: constdefs.c constants.o: constdefs.h constants.o: rubysocket.h constants.o: sockport.h +constants.o: {$(VPATH)}id.h ifaddr.o: $(RUBY_EXTCONF_H) ifaddr.o: $(arch_hdrdir)/ruby/config.h -ifaddr.o: $(hdrdir)/ruby.h ifaddr.o: $(hdrdir)/ruby/assert.h +ifaddr.o: $(hdrdir)/ruby/atomic.h ifaddr.o: $(hdrdir)/ruby/backward.h ifaddr.o: $(hdrdir)/ruby/backward/2/assume.h ifaddr.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -602,6 +677,7 @@ ifaddr.o: $(hdrdir)/ruby/defines.h ifaddr.o: $(hdrdir)/ruby/encoding.h ifaddr.o: $(hdrdir)/ruby/fiber/scheduler.h ifaddr.o: $(hdrdir)/ruby/intern.h +ifaddr.o: $(hdrdir)/ruby/internal/abi.h ifaddr.o: $(hdrdir)/ruby/internal/anyargs.h ifaddr.o: $(hdrdir)/ruby/internal/arithmetic.h ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -639,6 +715,7 @@ ifaddr.o: $(hdrdir)/ruby/internal/attr/noexcept.h ifaddr.o: $(hdrdir)/ruby/internal/attr/noinline.h ifaddr.o: $(hdrdir)/ruby/internal/attr/nonnull.h ifaddr.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ifaddr.o: $(hdrdir)/ruby/internal/attr/pure.h ifaddr.o: $(hdrdir)/ruby/internal/attr/restrict.h ifaddr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -707,7 +784,6 @@ ifaddr.o: $(hdrdir)/ruby/internal/intern/enumerator.h ifaddr.o: $(hdrdir)/ruby/internal/intern/error.h ifaddr.o: $(hdrdir)/ruby/internal/intern/eval.h ifaddr.o: $(hdrdir)/ruby/internal/intern/file.h -ifaddr.o: $(hdrdir)/ruby/internal/intern/gc.h ifaddr.o: $(hdrdir)/ruby/internal/intern/hash.h ifaddr.o: $(hdrdir)/ruby/internal/intern/io.h ifaddr.o: $(hdrdir)/ruby/internal/intern/load.h @@ -724,6 +800,7 @@ ifaddr.o: $(hdrdir)/ruby/internal/intern/re.h ifaddr.o: $(hdrdir)/ruby/internal/intern/ruby.h ifaddr.o: $(hdrdir)/ruby/internal/intern/select.h ifaddr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/set.h ifaddr.o: $(hdrdir)/ruby/internal/intern/signal.h ifaddr.o: $(hdrdir)/ruby/internal/intern/sprintf.h ifaddr.o: $(hdrdir)/ruby/internal/intern/string.h @@ -738,12 +815,12 @@ ifaddr.o: $(hdrdir)/ruby/internal/memory.h ifaddr.o: $(hdrdir)/ruby/internal/method.h ifaddr.o: $(hdrdir)/ruby/internal/module.h ifaddr.o: $(hdrdir)/ruby/internal/newobj.h -ifaddr.o: $(hdrdir)/ruby/internal/rgengc.h ifaddr.o: $(hdrdir)/ruby/internal/scan_args.h ifaddr.o: $(hdrdir)/ruby/internal/special_consts.h ifaddr.o: $(hdrdir)/ruby/internal/static_assert.h ifaddr.o: $(hdrdir)/ruby/internal/stdalign.h ifaddr.o: $(hdrdir)/ruby/internal/stdbool.h +ifaddr.o: $(hdrdir)/ruby/internal/stdckdint.h ifaddr.o: $(hdrdir)/ruby/internal/symbol.h ifaddr.o: $(hdrdir)/ruby/internal/value.h ifaddr.o: $(hdrdir)/ruby/internal/value_type.h @@ -758,27 +835,50 @@ ifaddr.o: $(hdrdir)/ruby/ruby.h ifaddr.o: $(hdrdir)/ruby/st.h ifaddr.o: $(hdrdir)/ruby/subst.h ifaddr.o: $(hdrdir)/ruby/thread.h +ifaddr.o: $(hdrdir)/ruby/thread_native.h ifaddr.o: $(hdrdir)/ruby/util.h +ifaddr.o: $(hdrdir)/ruby/version.h +ifaddr.o: $(top_srcdir)/ccan/check_type/check_type.h +ifaddr.o: $(top_srcdir)/ccan/container_of/container_of.h +ifaddr.o: $(top_srcdir)/ccan/list/list.h +ifaddr.o: $(top_srcdir)/ccan/str/str.h +ifaddr.o: $(top_srcdir)/encindex.h +ifaddr.o: $(top_srcdir)/id_table.h ifaddr.o: $(top_srcdir)/internal.h ifaddr.o: $(top_srcdir)/internal/array.h +ifaddr.o: $(top_srcdir)/internal/basic_operators.h +ifaddr.o: $(top_srcdir)/internal/box.h ifaddr.o: $(top_srcdir)/internal/compilers.h ifaddr.o: $(top_srcdir)/internal/error.h ifaddr.o: $(top_srcdir)/internal/gc.h +ifaddr.o: $(top_srcdir)/internal/imemo.h ifaddr.o: $(top_srcdir)/internal/io.h +ifaddr.o: $(top_srcdir)/internal/sanitizers.h ifaddr.o: $(top_srcdir)/internal/serial.h +ifaddr.o: $(top_srcdir)/internal/set_table.h ifaddr.o: $(top_srcdir)/internal/static_assert.h ifaddr.o: $(top_srcdir)/internal/string.h ifaddr.o: $(top_srcdir)/internal/thread.h ifaddr.o: $(top_srcdir)/internal/vm.h ifaddr.o: $(top_srcdir)/internal/warnings.h +ifaddr.o: $(top_srcdir)/method.h +ifaddr.o: $(top_srcdir)/node.h +ifaddr.o: $(top_srcdir)/ruby_assert.h +ifaddr.o: $(top_srcdir)/ruby_atomic.h +ifaddr.o: $(top_srcdir)/rubyparser.h +ifaddr.o: $(top_srcdir)/shape.h +ifaddr.o: $(top_srcdir)/thread_pthread.h +ifaddr.o: $(top_srcdir)/vm_core.h +ifaddr.o: $(top_srcdir)/vm_opts.h ifaddr.o: constdefs.h ifaddr.o: ifaddr.c ifaddr.o: rubysocket.h ifaddr.o: sockport.h +ifaddr.o: {$(VPATH)}id.h init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h -init.o: $(hdrdir)/ruby.h init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/atomic.h init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -793,6 +893,7 @@ init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/encoding.h init.o: $(hdrdir)/ruby/fiber/scheduler.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -830,6 +931,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -898,7 +1000,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -915,6 +1016,7 @@ init.o: $(hdrdir)/ruby/internal/intern/re.h init.o: $(hdrdir)/ruby/internal/intern/ruby.h init.o: $(hdrdir)/ruby/internal/intern/select.h init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/set.h init.o: $(hdrdir)/ruby/internal/intern/signal.h init.o: $(hdrdir)/ruby/internal/intern/sprintf.h init.o: $(hdrdir)/ruby/internal/intern/string.h @@ -929,12 +1031,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h @@ -949,27 +1051,50 @@ init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h init.o: $(hdrdir)/ruby/subst.h init.o: $(hdrdir)/ruby/thread.h +init.o: $(hdrdir)/ruby/thread_native.h init.o: $(hdrdir)/ruby/util.h +init.o: $(hdrdir)/ruby/version.h +init.o: $(top_srcdir)/ccan/check_type/check_type.h +init.o: $(top_srcdir)/ccan/container_of/container_of.h +init.o: $(top_srcdir)/ccan/list/list.h +init.o: $(top_srcdir)/ccan/str/str.h +init.o: $(top_srcdir)/encindex.h +init.o: $(top_srcdir)/id_table.h init.o: $(top_srcdir)/internal.h init.o: $(top_srcdir)/internal/array.h +init.o: $(top_srcdir)/internal/basic_operators.h +init.o: $(top_srcdir)/internal/box.h init.o: $(top_srcdir)/internal/compilers.h init.o: $(top_srcdir)/internal/error.h init.o: $(top_srcdir)/internal/gc.h +init.o: $(top_srcdir)/internal/imemo.h init.o: $(top_srcdir)/internal/io.h +init.o: $(top_srcdir)/internal/sanitizers.h init.o: $(top_srcdir)/internal/serial.h +init.o: $(top_srcdir)/internal/set_table.h init.o: $(top_srcdir)/internal/static_assert.h init.o: $(top_srcdir)/internal/string.h init.o: $(top_srcdir)/internal/thread.h init.o: $(top_srcdir)/internal/vm.h init.o: $(top_srcdir)/internal/warnings.h +init.o: $(top_srcdir)/method.h +init.o: $(top_srcdir)/node.h +init.o: $(top_srcdir)/ruby_assert.h +init.o: $(top_srcdir)/ruby_atomic.h +init.o: $(top_srcdir)/rubyparser.h +init.o: $(top_srcdir)/shape.h +init.o: $(top_srcdir)/thread_pthread.h +init.o: $(top_srcdir)/vm_core.h +init.o: $(top_srcdir)/vm_opts.h init.o: constdefs.h init.o: init.c init.o: rubysocket.h init.o: sockport.h +init.o: {$(VPATH)}id.h ipsocket.o: $(RUBY_EXTCONF_H) ipsocket.o: $(arch_hdrdir)/ruby/config.h -ipsocket.o: $(hdrdir)/ruby.h ipsocket.o: $(hdrdir)/ruby/assert.h +ipsocket.o: $(hdrdir)/ruby/atomic.h ipsocket.o: $(hdrdir)/ruby/backward.h ipsocket.o: $(hdrdir)/ruby/backward/2/assume.h ipsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -984,6 +1109,7 @@ ipsocket.o: $(hdrdir)/ruby/defines.h ipsocket.o: $(hdrdir)/ruby/encoding.h ipsocket.o: $(hdrdir)/ruby/fiber/scheduler.h ipsocket.o: $(hdrdir)/ruby/intern.h +ipsocket.o: $(hdrdir)/ruby/internal/abi.h ipsocket.o: $(hdrdir)/ruby/internal/anyargs.h ipsocket.o: $(hdrdir)/ruby/internal/arithmetic.h ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1021,6 +1147,7 @@ ipsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h ipsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h ipsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h ipsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ipsocket.o: $(hdrdir)/ruby/internal/attr/pure.h ipsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h ipsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1089,7 +1216,6 @@ ipsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h ipsocket.o: $(hdrdir)/ruby/internal/intern/error.h ipsocket.o: $(hdrdir)/ruby/internal/intern/eval.h ipsocket.o: $(hdrdir)/ruby/internal/intern/file.h -ipsocket.o: $(hdrdir)/ruby/internal/intern/gc.h ipsocket.o: $(hdrdir)/ruby/internal/intern/hash.h ipsocket.o: $(hdrdir)/ruby/internal/intern/io.h ipsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1106,6 +1232,7 @@ ipsocket.o: $(hdrdir)/ruby/internal/intern/re.h ipsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h ipsocket.o: $(hdrdir)/ruby/internal/intern/select.h ipsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/set.h ipsocket.o: $(hdrdir)/ruby/internal/intern/signal.h ipsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h ipsocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1120,12 +1247,12 @@ ipsocket.o: $(hdrdir)/ruby/internal/memory.h ipsocket.o: $(hdrdir)/ruby/internal/method.h ipsocket.o: $(hdrdir)/ruby/internal/module.h ipsocket.o: $(hdrdir)/ruby/internal/newobj.h -ipsocket.o: $(hdrdir)/ruby/internal/rgengc.h ipsocket.o: $(hdrdir)/ruby/internal/scan_args.h ipsocket.o: $(hdrdir)/ruby/internal/special_consts.h ipsocket.o: $(hdrdir)/ruby/internal/static_assert.h ipsocket.o: $(hdrdir)/ruby/internal/stdalign.h ipsocket.o: $(hdrdir)/ruby/internal/stdbool.h +ipsocket.o: $(hdrdir)/ruby/internal/stdckdint.h ipsocket.o: $(hdrdir)/ruby/internal/symbol.h ipsocket.o: $(hdrdir)/ruby/internal/value.h ipsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1140,27 +1267,50 @@ ipsocket.o: $(hdrdir)/ruby/ruby.h ipsocket.o: $(hdrdir)/ruby/st.h ipsocket.o: $(hdrdir)/ruby/subst.h ipsocket.o: $(hdrdir)/ruby/thread.h +ipsocket.o: $(hdrdir)/ruby/thread_native.h ipsocket.o: $(hdrdir)/ruby/util.h +ipsocket.o: $(hdrdir)/ruby/version.h +ipsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +ipsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +ipsocket.o: $(top_srcdir)/ccan/list/list.h +ipsocket.o: $(top_srcdir)/ccan/str/str.h +ipsocket.o: $(top_srcdir)/encindex.h +ipsocket.o: $(top_srcdir)/id_table.h ipsocket.o: $(top_srcdir)/internal.h ipsocket.o: $(top_srcdir)/internal/array.h +ipsocket.o: $(top_srcdir)/internal/basic_operators.h +ipsocket.o: $(top_srcdir)/internal/box.h ipsocket.o: $(top_srcdir)/internal/compilers.h ipsocket.o: $(top_srcdir)/internal/error.h ipsocket.o: $(top_srcdir)/internal/gc.h +ipsocket.o: $(top_srcdir)/internal/imemo.h ipsocket.o: $(top_srcdir)/internal/io.h +ipsocket.o: $(top_srcdir)/internal/sanitizers.h ipsocket.o: $(top_srcdir)/internal/serial.h +ipsocket.o: $(top_srcdir)/internal/set_table.h ipsocket.o: $(top_srcdir)/internal/static_assert.h ipsocket.o: $(top_srcdir)/internal/string.h ipsocket.o: $(top_srcdir)/internal/thread.h ipsocket.o: $(top_srcdir)/internal/vm.h ipsocket.o: $(top_srcdir)/internal/warnings.h +ipsocket.o: $(top_srcdir)/method.h +ipsocket.o: $(top_srcdir)/node.h +ipsocket.o: $(top_srcdir)/ruby_assert.h +ipsocket.o: $(top_srcdir)/ruby_atomic.h +ipsocket.o: $(top_srcdir)/rubyparser.h +ipsocket.o: $(top_srcdir)/shape.h +ipsocket.o: $(top_srcdir)/thread_pthread.h +ipsocket.o: $(top_srcdir)/vm_core.h +ipsocket.o: $(top_srcdir)/vm_opts.h ipsocket.o: constdefs.h ipsocket.o: ipsocket.c ipsocket.o: rubysocket.h ipsocket.o: sockport.h +ipsocket.o: {$(VPATH)}id.h option.o: $(RUBY_EXTCONF_H) option.o: $(arch_hdrdir)/ruby/config.h -option.o: $(hdrdir)/ruby.h option.o: $(hdrdir)/ruby/assert.h +option.o: $(hdrdir)/ruby/atomic.h option.o: $(hdrdir)/ruby/backward.h option.o: $(hdrdir)/ruby/backward/2/assume.h option.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1175,6 +1325,7 @@ option.o: $(hdrdir)/ruby/defines.h option.o: $(hdrdir)/ruby/encoding.h option.o: $(hdrdir)/ruby/fiber/scheduler.h option.o: $(hdrdir)/ruby/intern.h +option.o: $(hdrdir)/ruby/internal/abi.h option.o: $(hdrdir)/ruby/internal/anyargs.h option.o: $(hdrdir)/ruby/internal/arithmetic.h option.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1212,6 +1363,7 @@ option.o: $(hdrdir)/ruby/internal/attr/noexcept.h option.o: $(hdrdir)/ruby/internal/attr/noinline.h option.o: $(hdrdir)/ruby/internal/attr/nonnull.h option.o: $(hdrdir)/ruby/internal/attr/noreturn.h +option.o: $(hdrdir)/ruby/internal/attr/packed_struct.h option.o: $(hdrdir)/ruby/internal/attr/pure.h option.o: $(hdrdir)/ruby/internal/attr/restrict.h option.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1280,7 +1432,6 @@ option.o: $(hdrdir)/ruby/internal/intern/enumerator.h option.o: $(hdrdir)/ruby/internal/intern/error.h option.o: $(hdrdir)/ruby/internal/intern/eval.h option.o: $(hdrdir)/ruby/internal/intern/file.h -option.o: $(hdrdir)/ruby/internal/intern/gc.h option.o: $(hdrdir)/ruby/internal/intern/hash.h option.o: $(hdrdir)/ruby/internal/intern/io.h option.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1297,6 +1448,7 @@ option.o: $(hdrdir)/ruby/internal/intern/re.h option.o: $(hdrdir)/ruby/internal/intern/ruby.h option.o: $(hdrdir)/ruby/internal/intern/select.h option.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +option.o: $(hdrdir)/ruby/internal/intern/set.h option.o: $(hdrdir)/ruby/internal/intern/signal.h option.o: $(hdrdir)/ruby/internal/intern/sprintf.h option.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1311,12 +1463,12 @@ option.o: $(hdrdir)/ruby/internal/memory.h option.o: $(hdrdir)/ruby/internal/method.h option.o: $(hdrdir)/ruby/internal/module.h option.o: $(hdrdir)/ruby/internal/newobj.h -option.o: $(hdrdir)/ruby/internal/rgengc.h option.o: $(hdrdir)/ruby/internal/scan_args.h option.o: $(hdrdir)/ruby/internal/special_consts.h option.o: $(hdrdir)/ruby/internal/static_assert.h option.o: $(hdrdir)/ruby/internal/stdalign.h option.o: $(hdrdir)/ruby/internal/stdbool.h +option.o: $(hdrdir)/ruby/internal/stdckdint.h option.o: $(hdrdir)/ruby/internal/symbol.h option.o: $(hdrdir)/ruby/internal/value.h option.o: $(hdrdir)/ruby/internal/value_type.h @@ -1331,27 +1483,50 @@ option.o: $(hdrdir)/ruby/ruby.h option.o: $(hdrdir)/ruby/st.h option.o: $(hdrdir)/ruby/subst.h option.o: $(hdrdir)/ruby/thread.h +option.o: $(hdrdir)/ruby/thread_native.h option.o: $(hdrdir)/ruby/util.h +option.o: $(hdrdir)/ruby/version.h +option.o: $(top_srcdir)/ccan/check_type/check_type.h +option.o: $(top_srcdir)/ccan/container_of/container_of.h +option.o: $(top_srcdir)/ccan/list/list.h +option.o: $(top_srcdir)/ccan/str/str.h +option.o: $(top_srcdir)/encindex.h +option.o: $(top_srcdir)/id_table.h option.o: $(top_srcdir)/internal.h option.o: $(top_srcdir)/internal/array.h +option.o: $(top_srcdir)/internal/basic_operators.h +option.o: $(top_srcdir)/internal/box.h option.o: $(top_srcdir)/internal/compilers.h option.o: $(top_srcdir)/internal/error.h option.o: $(top_srcdir)/internal/gc.h +option.o: $(top_srcdir)/internal/imemo.h option.o: $(top_srcdir)/internal/io.h +option.o: $(top_srcdir)/internal/sanitizers.h option.o: $(top_srcdir)/internal/serial.h +option.o: $(top_srcdir)/internal/set_table.h option.o: $(top_srcdir)/internal/static_assert.h option.o: $(top_srcdir)/internal/string.h option.o: $(top_srcdir)/internal/thread.h option.o: $(top_srcdir)/internal/vm.h option.o: $(top_srcdir)/internal/warnings.h +option.o: $(top_srcdir)/method.h +option.o: $(top_srcdir)/node.h +option.o: $(top_srcdir)/ruby_assert.h +option.o: $(top_srcdir)/ruby_atomic.h +option.o: $(top_srcdir)/rubyparser.h +option.o: $(top_srcdir)/shape.h +option.o: $(top_srcdir)/thread_pthread.h +option.o: $(top_srcdir)/vm_core.h +option.o: $(top_srcdir)/vm_opts.h option.o: constdefs.h option.o: option.c option.o: rubysocket.h option.o: sockport.h +option.o: {$(VPATH)}id.h raddrinfo.o: $(RUBY_EXTCONF_H) raddrinfo.o: $(arch_hdrdir)/ruby/config.h -raddrinfo.o: $(hdrdir)/ruby.h raddrinfo.o: $(hdrdir)/ruby/assert.h +raddrinfo.o: $(hdrdir)/ruby/atomic.h raddrinfo.o: $(hdrdir)/ruby/backward.h raddrinfo.o: $(hdrdir)/ruby/backward/2/assume.h raddrinfo.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1366,6 +1541,7 @@ raddrinfo.o: $(hdrdir)/ruby/defines.h raddrinfo.o: $(hdrdir)/ruby/encoding.h raddrinfo.o: $(hdrdir)/ruby/fiber/scheduler.h raddrinfo.o: $(hdrdir)/ruby/intern.h +raddrinfo.o: $(hdrdir)/ruby/internal/abi.h raddrinfo.o: $(hdrdir)/ruby/internal/anyargs.h raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic.h raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1403,6 +1579,7 @@ raddrinfo.o: $(hdrdir)/ruby/internal/attr/noexcept.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/noinline.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/nonnull.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/noreturn.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/packed_struct.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/pure.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/restrict.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1471,7 +1648,6 @@ raddrinfo.o: $(hdrdir)/ruby/internal/intern/enumerator.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/error.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/eval.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/file.h -raddrinfo.o: $(hdrdir)/ruby/internal/intern/gc.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/hash.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/io.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1488,6 +1664,7 @@ raddrinfo.o: $(hdrdir)/ruby/internal/intern/re.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/ruby.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/select.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/set.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/signal.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/sprintf.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1502,12 +1679,12 @@ raddrinfo.o: $(hdrdir)/ruby/internal/memory.h raddrinfo.o: $(hdrdir)/ruby/internal/method.h raddrinfo.o: $(hdrdir)/ruby/internal/module.h raddrinfo.o: $(hdrdir)/ruby/internal/newobj.h -raddrinfo.o: $(hdrdir)/ruby/internal/rgengc.h raddrinfo.o: $(hdrdir)/ruby/internal/scan_args.h raddrinfo.o: $(hdrdir)/ruby/internal/special_consts.h raddrinfo.o: $(hdrdir)/ruby/internal/static_assert.h raddrinfo.o: $(hdrdir)/ruby/internal/stdalign.h raddrinfo.o: $(hdrdir)/ruby/internal/stdbool.h +raddrinfo.o: $(hdrdir)/ruby/internal/stdckdint.h raddrinfo.o: $(hdrdir)/ruby/internal/symbol.h raddrinfo.o: $(hdrdir)/ruby/internal/value.h raddrinfo.o: $(hdrdir)/ruby/internal/value_type.h @@ -1522,27 +1699,50 @@ raddrinfo.o: $(hdrdir)/ruby/ruby.h raddrinfo.o: $(hdrdir)/ruby/st.h raddrinfo.o: $(hdrdir)/ruby/subst.h raddrinfo.o: $(hdrdir)/ruby/thread.h +raddrinfo.o: $(hdrdir)/ruby/thread_native.h raddrinfo.o: $(hdrdir)/ruby/util.h +raddrinfo.o: $(hdrdir)/ruby/version.h +raddrinfo.o: $(top_srcdir)/ccan/check_type/check_type.h +raddrinfo.o: $(top_srcdir)/ccan/container_of/container_of.h +raddrinfo.o: $(top_srcdir)/ccan/list/list.h +raddrinfo.o: $(top_srcdir)/ccan/str/str.h +raddrinfo.o: $(top_srcdir)/encindex.h +raddrinfo.o: $(top_srcdir)/id_table.h raddrinfo.o: $(top_srcdir)/internal.h raddrinfo.o: $(top_srcdir)/internal/array.h +raddrinfo.o: $(top_srcdir)/internal/basic_operators.h +raddrinfo.o: $(top_srcdir)/internal/box.h raddrinfo.o: $(top_srcdir)/internal/compilers.h raddrinfo.o: $(top_srcdir)/internal/error.h raddrinfo.o: $(top_srcdir)/internal/gc.h +raddrinfo.o: $(top_srcdir)/internal/imemo.h raddrinfo.o: $(top_srcdir)/internal/io.h +raddrinfo.o: $(top_srcdir)/internal/sanitizers.h raddrinfo.o: $(top_srcdir)/internal/serial.h +raddrinfo.o: $(top_srcdir)/internal/set_table.h raddrinfo.o: $(top_srcdir)/internal/static_assert.h raddrinfo.o: $(top_srcdir)/internal/string.h raddrinfo.o: $(top_srcdir)/internal/thread.h raddrinfo.o: $(top_srcdir)/internal/vm.h raddrinfo.o: $(top_srcdir)/internal/warnings.h +raddrinfo.o: $(top_srcdir)/method.h +raddrinfo.o: $(top_srcdir)/node.h +raddrinfo.o: $(top_srcdir)/ruby_assert.h +raddrinfo.o: $(top_srcdir)/ruby_atomic.h +raddrinfo.o: $(top_srcdir)/rubyparser.h +raddrinfo.o: $(top_srcdir)/shape.h +raddrinfo.o: $(top_srcdir)/thread_pthread.h +raddrinfo.o: $(top_srcdir)/vm_core.h +raddrinfo.o: $(top_srcdir)/vm_opts.h raddrinfo.o: constdefs.h raddrinfo.o: raddrinfo.c raddrinfo.o: rubysocket.h raddrinfo.o: sockport.h +raddrinfo.o: {$(VPATH)}id.h socket.o: $(RUBY_EXTCONF_H) socket.o: $(arch_hdrdir)/ruby/config.h -socket.o: $(hdrdir)/ruby.h socket.o: $(hdrdir)/ruby/assert.h +socket.o: $(hdrdir)/ruby/atomic.h socket.o: $(hdrdir)/ruby/backward.h socket.o: $(hdrdir)/ruby/backward/2/assume.h socket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1557,6 +1757,7 @@ socket.o: $(hdrdir)/ruby/defines.h socket.o: $(hdrdir)/ruby/encoding.h socket.o: $(hdrdir)/ruby/fiber/scheduler.h socket.o: $(hdrdir)/ruby/intern.h +socket.o: $(hdrdir)/ruby/internal/abi.h socket.o: $(hdrdir)/ruby/internal/anyargs.h socket.o: $(hdrdir)/ruby/internal/arithmetic.h socket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1594,6 +1795,7 @@ socket.o: $(hdrdir)/ruby/internal/attr/noexcept.h socket.o: $(hdrdir)/ruby/internal/attr/noinline.h socket.o: $(hdrdir)/ruby/internal/attr/nonnull.h socket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +socket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h socket.o: $(hdrdir)/ruby/internal/attr/pure.h socket.o: $(hdrdir)/ruby/internal/attr/restrict.h socket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1662,7 +1864,6 @@ socket.o: $(hdrdir)/ruby/internal/intern/enumerator.h socket.o: $(hdrdir)/ruby/internal/intern/error.h socket.o: $(hdrdir)/ruby/internal/intern/eval.h socket.o: $(hdrdir)/ruby/internal/intern/file.h -socket.o: $(hdrdir)/ruby/internal/intern/gc.h socket.o: $(hdrdir)/ruby/internal/intern/hash.h socket.o: $(hdrdir)/ruby/internal/intern/io.h socket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1679,6 +1880,7 @@ socket.o: $(hdrdir)/ruby/internal/intern/re.h socket.o: $(hdrdir)/ruby/internal/intern/ruby.h socket.o: $(hdrdir)/ruby/internal/intern/select.h socket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +socket.o: $(hdrdir)/ruby/internal/intern/set.h socket.o: $(hdrdir)/ruby/internal/intern/signal.h socket.o: $(hdrdir)/ruby/internal/intern/sprintf.h socket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1693,12 +1895,12 @@ socket.o: $(hdrdir)/ruby/internal/memory.h socket.o: $(hdrdir)/ruby/internal/method.h socket.o: $(hdrdir)/ruby/internal/module.h socket.o: $(hdrdir)/ruby/internal/newobj.h -socket.o: $(hdrdir)/ruby/internal/rgengc.h socket.o: $(hdrdir)/ruby/internal/scan_args.h socket.o: $(hdrdir)/ruby/internal/special_consts.h socket.o: $(hdrdir)/ruby/internal/static_assert.h socket.o: $(hdrdir)/ruby/internal/stdalign.h socket.o: $(hdrdir)/ruby/internal/stdbool.h +socket.o: $(hdrdir)/ruby/internal/stdckdint.h socket.o: $(hdrdir)/ruby/internal/symbol.h socket.o: $(hdrdir)/ruby/internal/value.h socket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1713,27 +1915,50 @@ socket.o: $(hdrdir)/ruby/ruby.h socket.o: $(hdrdir)/ruby/st.h socket.o: $(hdrdir)/ruby/subst.h socket.o: $(hdrdir)/ruby/thread.h +socket.o: $(hdrdir)/ruby/thread_native.h socket.o: $(hdrdir)/ruby/util.h +socket.o: $(hdrdir)/ruby/version.h +socket.o: $(top_srcdir)/ccan/check_type/check_type.h +socket.o: $(top_srcdir)/ccan/container_of/container_of.h +socket.o: $(top_srcdir)/ccan/list/list.h +socket.o: $(top_srcdir)/ccan/str/str.h +socket.o: $(top_srcdir)/encindex.h +socket.o: $(top_srcdir)/id_table.h socket.o: $(top_srcdir)/internal.h socket.o: $(top_srcdir)/internal/array.h +socket.o: $(top_srcdir)/internal/basic_operators.h +socket.o: $(top_srcdir)/internal/box.h socket.o: $(top_srcdir)/internal/compilers.h socket.o: $(top_srcdir)/internal/error.h socket.o: $(top_srcdir)/internal/gc.h +socket.o: $(top_srcdir)/internal/imemo.h socket.o: $(top_srcdir)/internal/io.h +socket.o: $(top_srcdir)/internal/sanitizers.h socket.o: $(top_srcdir)/internal/serial.h +socket.o: $(top_srcdir)/internal/set_table.h socket.o: $(top_srcdir)/internal/static_assert.h socket.o: $(top_srcdir)/internal/string.h socket.o: $(top_srcdir)/internal/thread.h socket.o: $(top_srcdir)/internal/vm.h socket.o: $(top_srcdir)/internal/warnings.h +socket.o: $(top_srcdir)/method.h +socket.o: $(top_srcdir)/node.h +socket.o: $(top_srcdir)/ruby_assert.h +socket.o: $(top_srcdir)/ruby_atomic.h +socket.o: $(top_srcdir)/rubyparser.h +socket.o: $(top_srcdir)/shape.h +socket.o: $(top_srcdir)/thread_pthread.h +socket.o: $(top_srcdir)/vm_core.h +socket.o: $(top_srcdir)/vm_opts.h socket.o: constdefs.h socket.o: rubysocket.h socket.o: socket.c socket.o: sockport.h +socket.o: {$(VPATH)}id.h sockssocket.o: $(RUBY_EXTCONF_H) sockssocket.o: $(arch_hdrdir)/ruby/config.h -sockssocket.o: $(hdrdir)/ruby.h sockssocket.o: $(hdrdir)/ruby/assert.h +sockssocket.o: $(hdrdir)/ruby/atomic.h sockssocket.o: $(hdrdir)/ruby/backward.h sockssocket.o: $(hdrdir)/ruby/backward/2/assume.h sockssocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1748,6 +1973,7 @@ sockssocket.o: $(hdrdir)/ruby/defines.h sockssocket.o: $(hdrdir)/ruby/encoding.h sockssocket.o: $(hdrdir)/ruby/fiber/scheduler.h sockssocket.o: $(hdrdir)/ruby/intern.h +sockssocket.o: $(hdrdir)/ruby/internal/abi.h sockssocket.o: $(hdrdir)/ruby/internal/anyargs.h sockssocket.o: $(hdrdir)/ruby/internal/arithmetic.h sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1785,6 +2011,7 @@ sockssocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h sockssocket.o: $(hdrdir)/ruby/internal/attr/noinline.h sockssocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h sockssocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sockssocket.o: $(hdrdir)/ruby/internal/attr/pure.h sockssocket.o: $(hdrdir)/ruby/internal/attr/restrict.h sockssocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1853,7 +2080,6 @@ sockssocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h sockssocket.o: $(hdrdir)/ruby/internal/intern/error.h sockssocket.o: $(hdrdir)/ruby/internal/intern/eval.h sockssocket.o: $(hdrdir)/ruby/internal/intern/file.h -sockssocket.o: $(hdrdir)/ruby/internal/intern/gc.h sockssocket.o: $(hdrdir)/ruby/internal/intern/hash.h sockssocket.o: $(hdrdir)/ruby/internal/intern/io.h sockssocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1870,6 +2096,7 @@ sockssocket.o: $(hdrdir)/ruby/internal/intern/re.h sockssocket.o: $(hdrdir)/ruby/internal/intern/ruby.h sockssocket.o: $(hdrdir)/ruby/internal/intern/select.h sockssocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/set.h sockssocket.o: $(hdrdir)/ruby/internal/intern/signal.h sockssocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h sockssocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -1884,12 +2111,12 @@ sockssocket.o: $(hdrdir)/ruby/internal/memory.h sockssocket.o: $(hdrdir)/ruby/internal/method.h sockssocket.o: $(hdrdir)/ruby/internal/module.h sockssocket.o: $(hdrdir)/ruby/internal/newobj.h -sockssocket.o: $(hdrdir)/ruby/internal/rgengc.h sockssocket.o: $(hdrdir)/ruby/internal/scan_args.h sockssocket.o: $(hdrdir)/ruby/internal/special_consts.h sockssocket.o: $(hdrdir)/ruby/internal/static_assert.h sockssocket.o: $(hdrdir)/ruby/internal/stdalign.h sockssocket.o: $(hdrdir)/ruby/internal/stdbool.h +sockssocket.o: $(hdrdir)/ruby/internal/stdckdint.h sockssocket.o: $(hdrdir)/ruby/internal/symbol.h sockssocket.o: $(hdrdir)/ruby/internal/value.h sockssocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1904,27 +2131,50 @@ sockssocket.o: $(hdrdir)/ruby/ruby.h sockssocket.o: $(hdrdir)/ruby/st.h sockssocket.o: $(hdrdir)/ruby/subst.h sockssocket.o: $(hdrdir)/ruby/thread.h +sockssocket.o: $(hdrdir)/ruby/thread_native.h sockssocket.o: $(hdrdir)/ruby/util.h +sockssocket.o: $(hdrdir)/ruby/version.h +sockssocket.o: $(top_srcdir)/ccan/check_type/check_type.h +sockssocket.o: $(top_srcdir)/ccan/container_of/container_of.h +sockssocket.o: $(top_srcdir)/ccan/list/list.h +sockssocket.o: $(top_srcdir)/ccan/str/str.h +sockssocket.o: $(top_srcdir)/encindex.h +sockssocket.o: $(top_srcdir)/id_table.h sockssocket.o: $(top_srcdir)/internal.h sockssocket.o: $(top_srcdir)/internal/array.h +sockssocket.o: $(top_srcdir)/internal/basic_operators.h +sockssocket.o: $(top_srcdir)/internal/box.h sockssocket.o: $(top_srcdir)/internal/compilers.h sockssocket.o: $(top_srcdir)/internal/error.h sockssocket.o: $(top_srcdir)/internal/gc.h +sockssocket.o: $(top_srcdir)/internal/imemo.h sockssocket.o: $(top_srcdir)/internal/io.h +sockssocket.o: $(top_srcdir)/internal/sanitizers.h sockssocket.o: $(top_srcdir)/internal/serial.h +sockssocket.o: $(top_srcdir)/internal/set_table.h sockssocket.o: $(top_srcdir)/internal/static_assert.h sockssocket.o: $(top_srcdir)/internal/string.h sockssocket.o: $(top_srcdir)/internal/thread.h sockssocket.o: $(top_srcdir)/internal/vm.h sockssocket.o: $(top_srcdir)/internal/warnings.h +sockssocket.o: $(top_srcdir)/method.h +sockssocket.o: $(top_srcdir)/node.h +sockssocket.o: $(top_srcdir)/ruby_assert.h +sockssocket.o: $(top_srcdir)/ruby_atomic.h +sockssocket.o: $(top_srcdir)/rubyparser.h +sockssocket.o: $(top_srcdir)/shape.h +sockssocket.o: $(top_srcdir)/thread_pthread.h +sockssocket.o: $(top_srcdir)/vm_core.h +sockssocket.o: $(top_srcdir)/vm_opts.h sockssocket.o: constdefs.h sockssocket.o: rubysocket.h sockssocket.o: sockport.h sockssocket.o: sockssocket.c +sockssocket.o: {$(VPATH)}id.h tcpserver.o: $(RUBY_EXTCONF_H) tcpserver.o: $(arch_hdrdir)/ruby/config.h -tcpserver.o: $(hdrdir)/ruby.h tcpserver.o: $(hdrdir)/ruby/assert.h +tcpserver.o: $(hdrdir)/ruby/atomic.h tcpserver.o: $(hdrdir)/ruby/backward.h tcpserver.o: $(hdrdir)/ruby/backward/2/assume.h tcpserver.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1939,6 +2189,7 @@ tcpserver.o: $(hdrdir)/ruby/defines.h tcpserver.o: $(hdrdir)/ruby/encoding.h tcpserver.o: $(hdrdir)/ruby/fiber/scheduler.h tcpserver.o: $(hdrdir)/ruby/intern.h +tcpserver.o: $(hdrdir)/ruby/internal/abi.h tcpserver.o: $(hdrdir)/ruby/internal/anyargs.h tcpserver.o: $(hdrdir)/ruby/internal/arithmetic.h tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1976,6 +2227,7 @@ tcpserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h tcpserver.o: $(hdrdir)/ruby/internal/attr/noinline.h tcpserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h tcpserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h tcpserver.o: $(hdrdir)/ruby/internal/attr/pure.h tcpserver.o: $(hdrdir)/ruby/internal/attr/restrict.h tcpserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2044,7 +2296,6 @@ tcpserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h tcpserver.o: $(hdrdir)/ruby/internal/intern/error.h tcpserver.o: $(hdrdir)/ruby/internal/intern/eval.h tcpserver.o: $(hdrdir)/ruby/internal/intern/file.h -tcpserver.o: $(hdrdir)/ruby/internal/intern/gc.h tcpserver.o: $(hdrdir)/ruby/internal/intern/hash.h tcpserver.o: $(hdrdir)/ruby/internal/intern/io.h tcpserver.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2061,6 +2312,7 @@ tcpserver.o: $(hdrdir)/ruby/internal/intern/re.h tcpserver.o: $(hdrdir)/ruby/internal/intern/ruby.h tcpserver.o: $(hdrdir)/ruby/internal/intern/select.h tcpserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/set.h tcpserver.o: $(hdrdir)/ruby/internal/intern/signal.h tcpserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h tcpserver.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2075,12 +2327,12 @@ tcpserver.o: $(hdrdir)/ruby/internal/memory.h tcpserver.o: $(hdrdir)/ruby/internal/method.h tcpserver.o: $(hdrdir)/ruby/internal/module.h tcpserver.o: $(hdrdir)/ruby/internal/newobj.h -tcpserver.o: $(hdrdir)/ruby/internal/rgengc.h tcpserver.o: $(hdrdir)/ruby/internal/scan_args.h tcpserver.o: $(hdrdir)/ruby/internal/special_consts.h tcpserver.o: $(hdrdir)/ruby/internal/static_assert.h tcpserver.o: $(hdrdir)/ruby/internal/stdalign.h tcpserver.o: $(hdrdir)/ruby/internal/stdbool.h +tcpserver.o: $(hdrdir)/ruby/internal/stdckdint.h tcpserver.o: $(hdrdir)/ruby/internal/symbol.h tcpserver.o: $(hdrdir)/ruby/internal/value.h tcpserver.o: $(hdrdir)/ruby/internal/value_type.h @@ -2095,27 +2347,50 @@ tcpserver.o: $(hdrdir)/ruby/ruby.h tcpserver.o: $(hdrdir)/ruby/st.h tcpserver.o: $(hdrdir)/ruby/subst.h tcpserver.o: $(hdrdir)/ruby/thread.h +tcpserver.o: $(hdrdir)/ruby/thread_native.h tcpserver.o: $(hdrdir)/ruby/util.h +tcpserver.o: $(hdrdir)/ruby/version.h +tcpserver.o: $(top_srcdir)/ccan/check_type/check_type.h +tcpserver.o: $(top_srcdir)/ccan/container_of/container_of.h +tcpserver.o: $(top_srcdir)/ccan/list/list.h +tcpserver.o: $(top_srcdir)/ccan/str/str.h +tcpserver.o: $(top_srcdir)/encindex.h +tcpserver.o: $(top_srcdir)/id_table.h tcpserver.o: $(top_srcdir)/internal.h tcpserver.o: $(top_srcdir)/internal/array.h +tcpserver.o: $(top_srcdir)/internal/basic_operators.h +tcpserver.o: $(top_srcdir)/internal/box.h tcpserver.o: $(top_srcdir)/internal/compilers.h tcpserver.o: $(top_srcdir)/internal/error.h tcpserver.o: $(top_srcdir)/internal/gc.h +tcpserver.o: $(top_srcdir)/internal/imemo.h tcpserver.o: $(top_srcdir)/internal/io.h +tcpserver.o: $(top_srcdir)/internal/sanitizers.h tcpserver.o: $(top_srcdir)/internal/serial.h +tcpserver.o: $(top_srcdir)/internal/set_table.h tcpserver.o: $(top_srcdir)/internal/static_assert.h tcpserver.o: $(top_srcdir)/internal/string.h tcpserver.o: $(top_srcdir)/internal/thread.h tcpserver.o: $(top_srcdir)/internal/vm.h tcpserver.o: $(top_srcdir)/internal/warnings.h +tcpserver.o: $(top_srcdir)/method.h +tcpserver.o: $(top_srcdir)/node.h +tcpserver.o: $(top_srcdir)/ruby_assert.h +tcpserver.o: $(top_srcdir)/ruby_atomic.h +tcpserver.o: $(top_srcdir)/rubyparser.h +tcpserver.o: $(top_srcdir)/shape.h +tcpserver.o: $(top_srcdir)/thread_pthread.h +tcpserver.o: $(top_srcdir)/vm_core.h +tcpserver.o: $(top_srcdir)/vm_opts.h tcpserver.o: constdefs.h tcpserver.o: rubysocket.h tcpserver.o: sockport.h tcpserver.o: tcpserver.c +tcpserver.o: {$(VPATH)}id.h tcpsocket.o: $(RUBY_EXTCONF_H) tcpsocket.o: $(arch_hdrdir)/ruby/config.h -tcpsocket.o: $(hdrdir)/ruby.h tcpsocket.o: $(hdrdir)/ruby/assert.h +tcpsocket.o: $(hdrdir)/ruby/atomic.h tcpsocket.o: $(hdrdir)/ruby/backward.h tcpsocket.o: $(hdrdir)/ruby/backward/2/assume.h tcpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2130,6 +2405,7 @@ tcpsocket.o: $(hdrdir)/ruby/defines.h tcpsocket.o: $(hdrdir)/ruby/encoding.h tcpsocket.o: $(hdrdir)/ruby/fiber/scheduler.h tcpsocket.o: $(hdrdir)/ruby/intern.h +tcpsocket.o: $(hdrdir)/ruby/internal/abi.h tcpsocket.o: $(hdrdir)/ruby/internal/anyargs.h tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2167,6 +2443,7 @@ tcpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2235,7 +2512,6 @@ tcpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/error.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/file.h -tcpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/io.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2252,6 +2528,7 @@ tcpsocket.o: $(hdrdir)/ruby/internal/intern/re.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/select.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/set.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2266,12 +2543,12 @@ tcpsocket.o: $(hdrdir)/ruby/internal/memory.h tcpsocket.o: $(hdrdir)/ruby/internal/method.h tcpsocket.o: $(hdrdir)/ruby/internal/module.h tcpsocket.o: $(hdrdir)/ruby/internal/newobj.h -tcpsocket.o: $(hdrdir)/ruby/internal/rgengc.h tcpsocket.o: $(hdrdir)/ruby/internal/scan_args.h tcpsocket.o: $(hdrdir)/ruby/internal/special_consts.h tcpsocket.o: $(hdrdir)/ruby/internal/static_assert.h tcpsocket.o: $(hdrdir)/ruby/internal/stdalign.h tcpsocket.o: $(hdrdir)/ruby/internal/stdbool.h +tcpsocket.o: $(hdrdir)/ruby/internal/stdckdint.h tcpsocket.o: $(hdrdir)/ruby/internal/symbol.h tcpsocket.o: $(hdrdir)/ruby/internal/value.h tcpsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2286,27 +2563,50 @@ tcpsocket.o: $(hdrdir)/ruby/ruby.h tcpsocket.o: $(hdrdir)/ruby/st.h tcpsocket.o: $(hdrdir)/ruby/subst.h tcpsocket.o: $(hdrdir)/ruby/thread.h +tcpsocket.o: $(hdrdir)/ruby/thread_native.h tcpsocket.o: $(hdrdir)/ruby/util.h +tcpsocket.o: $(hdrdir)/ruby/version.h +tcpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +tcpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +tcpsocket.o: $(top_srcdir)/ccan/list/list.h +tcpsocket.o: $(top_srcdir)/ccan/str/str.h +tcpsocket.o: $(top_srcdir)/encindex.h +tcpsocket.o: $(top_srcdir)/id_table.h tcpsocket.o: $(top_srcdir)/internal.h tcpsocket.o: $(top_srcdir)/internal/array.h +tcpsocket.o: $(top_srcdir)/internal/basic_operators.h +tcpsocket.o: $(top_srcdir)/internal/box.h tcpsocket.o: $(top_srcdir)/internal/compilers.h tcpsocket.o: $(top_srcdir)/internal/error.h tcpsocket.o: $(top_srcdir)/internal/gc.h +tcpsocket.o: $(top_srcdir)/internal/imemo.h tcpsocket.o: $(top_srcdir)/internal/io.h +tcpsocket.o: $(top_srcdir)/internal/sanitizers.h tcpsocket.o: $(top_srcdir)/internal/serial.h +tcpsocket.o: $(top_srcdir)/internal/set_table.h tcpsocket.o: $(top_srcdir)/internal/static_assert.h tcpsocket.o: $(top_srcdir)/internal/string.h tcpsocket.o: $(top_srcdir)/internal/thread.h tcpsocket.o: $(top_srcdir)/internal/vm.h tcpsocket.o: $(top_srcdir)/internal/warnings.h +tcpsocket.o: $(top_srcdir)/method.h +tcpsocket.o: $(top_srcdir)/node.h +tcpsocket.o: $(top_srcdir)/ruby_assert.h +tcpsocket.o: $(top_srcdir)/ruby_atomic.h +tcpsocket.o: $(top_srcdir)/rubyparser.h +tcpsocket.o: $(top_srcdir)/shape.h +tcpsocket.o: $(top_srcdir)/thread_pthread.h +tcpsocket.o: $(top_srcdir)/vm_core.h +tcpsocket.o: $(top_srcdir)/vm_opts.h tcpsocket.o: constdefs.h tcpsocket.o: rubysocket.h tcpsocket.o: sockport.h tcpsocket.o: tcpsocket.c +tcpsocket.o: {$(VPATH)}id.h udpsocket.o: $(RUBY_EXTCONF_H) udpsocket.o: $(arch_hdrdir)/ruby/config.h -udpsocket.o: $(hdrdir)/ruby.h udpsocket.o: $(hdrdir)/ruby/assert.h +udpsocket.o: $(hdrdir)/ruby/atomic.h udpsocket.o: $(hdrdir)/ruby/backward.h udpsocket.o: $(hdrdir)/ruby/backward/2/assume.h udpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2321,6 +2621,7 @@ udpsocket.o: $(hdrdir)/ruby/defines.h udpsocket.o: $(hdrdir)/ruby/encoding.h udpsocket.o: $(hdrdir)/ruby/fiber/scheduler.h udpsocket.o: $(hdrdir)/ruby/intern.h +udpsocket.o: $(hdrdir)/ruby/internal/abi.h udpsocket.o: $(hdrdir)/ruby/internal/anyargs.h udpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2358,6 +2659,7 @@ udpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h udpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h udpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h udpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h udpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h udpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h udpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2426,7 +2728,6 @@ udpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h udpsocket.o: $(hdrdir)/ruby/internal/intern/error.h udpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h udpsocket.o: $(hdrdir)/ruby/internal/intern/file.h -udpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h udpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h udpsocket.o: $(hdrdir)/ruby/internal/intern/io.h udpsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2443,6 +2744,7 @@ udpsocket.o: $(hdrdir)/ruby/internal/intern/re.h udpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h udpsocket.o: $(hdrdir)/ruby/internal/intern/select.h udpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/set.h udpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h udpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h udpsocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2457,12 +2759,12 @@ udpsocket.o: $(hdrdir)/ruby/internal/memory.h udpsocket.o: $(hdrdir)/ruby/internal/method.h udpsocket.o: $(hdrdir)/ruby/internal/module.h udpsocket.o: $(hdrdir)/ruby/internal/newobj.h -udpsocket.o: $(hdrdir)/ruby/internal/rgengc.h udpsocket.o: $(hdrdir)/ruby/internal/scan_args.h udpsocket.o: $(hdrdir)/ruby/internal/special_consts.h udpsocket.o: $(hdrdir)/ruby/internal/static_assert.h udpsocket.o: $(hdrdir)/ruby/internal/stdalign.h udpsocket.o: $(hdrdir)/ruby/internal/stdbool.h +udpsocket.o: $(hdrdir)/ruby/internal/stdckdint.h udpsocket.o: $(hdrdir)/ruby/internal/symbol.h udpsocket.o: $(hdrdir)/ruby/internal/value.h udpsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2477,27 +2779,50 @@ udpsocket.o: $(hdrdir)/ruby/ruby.h udpsocket.o: $(hdrdir)/ruby/st.h udpsocket.o: $(hdrdir)/ruby/subst.h udpsocket.o: $(hdrdir)/ruby/thread.h +udpsocket.o: $(hdrdir)/ruby/thread_native.h udpsocket.o: $(hdrdir)/ruby/util.h +udpsocket.o: $(hdrdir)/ruby/version.h +udpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +udpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +udpsocket.o: $(top_srcdir)/ccan/list/list.h +udpsocket.o: $(top_srcdir)/ccan/str/str.h +udpsocket.o: $(top_srcdir)/encindex.h +udpsocket.o: $(top_srcdir)/id_table.h udpsocket.o: $(top_srcdir)/internal.h udpsocket.o: $(top_srcdir)/internal/array.h +udpsocket.o: $(top_srcdir)/internal/basic_operators.h +udpsocket.o: $(top_srcdir)/internal/box.h udpsocket.o: $(top_srcdir)/internal/compilers.h udpsocket.o: $(top_srcdir)/internal/error.h udpsocket.o: $(top_srcdir)/internal/gc.h +udpsocket.o: $(top_srcdir)/internal/imemo.h udpsocket.o: $(top_srcdir)/internal/io.h +udpsocket.o: $(top_srcdir)/internal/sanitizers.h udpsocket.o: $(top_srcdir)/internal/serial.h +udpsocket.o: $(top_srcdir)/internal/set_table.h udpsocket.o: $(top_srcdir)/internal/static_assert.h udpsocket.o: $(top_srcdir)/internal/string.h udpsocket.o: $(top_srcdir)/internal/thread.h udpsocket.o: $(top_srcdir)/internal/vm.h udpsocket.o: $(top_srcdir)/internal/warnings.h +udpsocket.o: $(top_srcdir)/method.h +udpsocket.o: $(top_srcdir)/node.h +udpsocket.o: $(top_srcdir)/ruby_assert.h +udpsocket.o: $(top_srcdir)/ruby_atomic.h +udpsocket.o: $(top_srcdir)/rubyparser.h +udpsocket.o: $(top_srcdir)/shape.h +udpsocket.o: $(top_srcdir)/thread_pthread.h +udpsocket.o: $(top_srcdir)/vm_core.h +udpsocket.o: $(top_srcdir)/vm_opts.h udpsocket.o: constdefs.h udpsocket.o: rubysocket.h udpsocket.o: sockport.h udpsocket.o: udpsocket.c +udpsocket.o: {$(VPATH)}id.h unixserver.o: $(RUBY_EXTCONF_H) unixserver.o: $(arch_hdrdir)/ruby/config.h -unixserver.o: $(hdrdir)/ruby.h unixserver.o: $(hdrdir)/ruby/assert.h +unixserver.o: $(hdrdir)/ruby/atomic.h unixserver.o: $(hdrdir)/ruby/backward.h unixserver.o: $(hdrdir)/ruby/backward/2/assume.h unixserver.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2512,6 +2837,7 @@ unixserver.o: $(hdrdir)/ruby/defines.h unixserver.o: $(hdrdir)/ruby/encoding.h unixserver.o: $(hdrdir)/ruby/fiber/scheduler.h unixserver.o: $(hdrdir)/ruby/intern.h +unixserver.o: $(hdrdir)/ruby/internal/abi.h unixserver.o: $(hdrdir)/ruby/internal/anyargs.h unixserver.o: $(hdrdir)/ruby/internal/arithmetic.h unixserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2549,6 +2875,7 @@ unixserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h unixserver.o: $(hdrdir)/ruby/internal/attr/noinline.h unixserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h unixserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +unixserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h unixserver.o: $(hdrdir)/ruby/internal/attr/pure.h unixserver.o: $(hdrdir)/ruby/internal/attr/restrict.h unixserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2617,7 +2944,6 @@ unixserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h unixserver.o: $(hdrdir)/ruby/internal/intern/error.h unixserver.o: $(hdrdir)/ruby/internal/intern/eval.h unixserver.o: $(hdrdir)/ruby/internal/intern/file.h -unixserver.o: $(hdrdir)/ruby/internal/intern/gc.h unixserver.o: $(hdrdir)/ruby/internal/intern/hash.h unixserver.o: $(hdrdir)/ruby/internal/intern/io.h unixserver.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2634,6 +2960,7 @@ unixserver.o: $(hdrdir)/ruby/internal/intern/re.h unixserver.o: $(hdrdir)/ruby/internal/intern/ruby.h unixserver.o: $(hdrdir)/ruby/internal/intern/select.h unixserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +unixserver.o: $(hdrdir)/ruby/internal/intern/set.h unixserver.o: $(hdrdir)/ruby/internal/intern/signal.h unixserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h unixserver.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2648,12 +2975,12 @@ unixserver.o: $(hdrdir)/ruby/internal/memory.h unixserver.o: $(hdrdir)/ruby/internal/method.h unixserver.o: $(hdrdir)/ruby/internal/module.h unixserver.o: $(hdrdir)/ruby/internal/newobj.h -unixserver.o: $(hdrdir)/ruby/internal/rgengc.h unixserver.o: $(hdrdir)/ruby/internal/scan_args.h unixserver.o: $(hdrdir)/ruby/internal/special_consts.h unixserver.o: $(hdrdir)/ruby/internal/static_assert.h unixserver.o: $(hdrdir)/ruby/internal/stdalign.h unixserver.o: $(hdrdir)/ruby/internal/stdbool.h +unixserver.o: $(hdrdir)/ruby/internal/stdckdint.h unixserver.o: $(hdrdir)/ruby/internal/symbol.h unixserver.o: $(hdrdir)/ruby/internal/value.h unixserver.o: $(hdrdir)/ruby/internal/value_type.h @@ -2668,27 +2995,50 @@ unixserver.o: $(hdrdir)/ruby/ruby.h unixserver.o: $(hdrdir)/ruby/st.h unixserver.o: $(hdrdir)/ruby/subst.h unixserver.o: $(hdrdir)/ruby/thread.h +unixserver.o: $(hdrdir)/ruby/thread_native.h unixserver.o: $(hdrdir)/ruby/util.h +unixserver.o: $(hdrdir)/ruby/version.h +unixserver.o: $(top_srcdir)/ccan/check_type/check_type.h +unixserver.o: $(top_srcdir)/ccan/container_of/container_of.h +unixserver.o: $(top_srcdir)/ccan/list/list.h +unixserver.o: $(top_srcdir)/ccan/str/str.h +unixserver.o: $(top_srcdir)/encindex.h +unixserver.o: $(top_srcdir)/id_table.h unixserver.o: $(top_srcdir)/internal.h unixserver.o: $(top_srcdir)/internal/array.h +unixserver.o: $(top_srcdir)/internal/basic_operators.h +unixserver.o: $(top_srcdir)/internal/box.h unixserver.o: $(top_srcdir)/internal/compilers.h unixserver.o: $(top_srcdir)/internal/error.h unixserver.o: $(top_srcdir)/internal/gc.h +unixserver.o: $(top_srcdir)/internal/imemo.h unixserver.o: $(top_srcdir)/internal/io.h +unixserver.o: $(top_srcdir)/internal/sanitizers.h unixserver.o: $(top_srcdir)/internal/serial.h +unixserver.o: $(top_srcdir)/internal/set_table.h unixserver.o: $(top_srcdir)/internal/static_assert.h unixserver.o: $(top_srcdir)/internal/string.h unixserver.o: $(top_srcdir)/internal/thread.h unixserver.o: $(top_srcdir)/internal/vm.h unixserver.o: $(top_srcdir)/internal/warnings.h +unixserver.o: $(top_srcdir)/method.h +unixserver.o: $(top_srcdir)/node.h +unixserver.o: $(top_srcdir)/ruby_assert.h +unixserver.o: $(top_srcdir)/ruby_atomic.h +unixserver.o: $(top_srcdir)/rubyparser.h +unixserver.o: $(top_srcdir)/shape.h +unixserver.o: $(top_srcdir)/thread_pthread.h +unixserver.o: $(top_srcdir)/vm_core.h +unixserver.o: $(top_srcdir)/vm_opts.h unixserver.o: constdefs.h unixserver.o: rubysocket.h unixserver.o: sockport.h unixserver.o: unixserver.c +unixserver.o: {$(VPATH)}id.h unixsocket.o: $(RUBY_EXTCONF_H) unixsocket.o: $(arch_hdrdir)/ruby/config.h -unixsocket.o: $(hdrdir)/ruby.h unixsocket.o: $(hdrdir)/ruby/assert.h +unixsocket.o: $(hdrdir)/ruby/atomic.h unixsocket.o: $(hdrdir)/ruby/backward.h unixsocket.o: $(hdrdir)/ruby/backward/2/assume.h unixsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2703,6 +3053,7 @@ unixsocket.o: $(hdrdir)/ruby/defines.h unixsocket.o: $(hdrdir)/ruby/encoding.h unixsocket.o: $(hdrdir)/ruby/fiber/scheduler.h unixsocket.o: $(hdrdir)/ruby/intern.h +unixsocket.o: $(hdrdir)/ruby/internal/abi.h unixsocket.o: $(hdrdir)/ruby/internal/anyargs.h unixsocket.o: $(hdrdir)/ruby/internal/arithmetic.h unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2740,6 +3091,7 @@ unixsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h unixsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h unixsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h unixsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h unixsocket.o: $(hdrdir)/ruby/internal/attr/pure.h unixsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h unixsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2808,7 +3160,6 @@ unixsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h unixsocket.o: $(hdrdir)/ruby/internal/intern/error.h unixsocket.o: $(hdrdir)/ruby/internal/intern/eval.h unixsocket.o: $(hdrdir)/ruby/internal/intern/file.h -unixsocket.o: $(hdrdir)/ruby/internal/intern/gc.h unixsocket.o: $(hdrdir)/ruby/internal/intern/hash.h unixsocket.o: $(hdrdir)/ruby/internal/intern/io.h unixsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2825,6 +3176,7 @@ unixsocket.o: $(hdrdir)/ruby/internal/intern/re.h unixsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h unixsocket.o: $(hdrdir)/ruby/internal/intern/select.h unixsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/set.h unixsocket.o: $(hdrdir)/ruby/internal/intern/signal.h unixsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h unixsocket.o: $(hdrdir)/ruby/internal/intern/string.h @@ -2839,12 +3191,12 @@ unixsocket.o: $(hdrdir)/ruby/internal/memory.h unixsocket.o: $(hdrdir)/ruby/internal/method.h unixsocket.o: $(hdrdir)/ruby/internal/module.h unixsocket.o: $(hdrdir)/ruby/internal/newobj.h -unixsocket.o: $(hdrdir)/ruby/internal/rgengc.h unixsocket.o: $(hdrdir)/ruby/internal/scan_args.h unixsocket.o: $(hdrdir)/ruby/internal/special_consts.h unixsocket.o: $(hdrdir)/ruby/internal/static_assert.h unixsocket.o: $(hdrdir)/ruby/internal/stdalign.h unixsocket.o: $(hdrdir)/ruby/internal/stdbool.h +unixsocket.o: $(hdrdir)/ruby/internal/stdckdint.h unixsocket.o: $(hdrdir)/ruby/internal/symbol.h unixsocket.o: $(hdrdir)/ruby/internal/value.h unixsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2859,21 +3211,44 @@ unixsocket.o: $(hdrdir)/ruby/ruby.h unixsocket.o: $(hdrdir)/ruby/st.h unixsocket.o: $(hdrdir)/ruby/subst.h unixsocket.o: $(hdrdir)/ruby/thread.h +unixsocket.o: $(hdrdir)/ruby/thread_native.h unixsocket.o: $(hdrdir)/ruby/util.h +unixsocket.o: $(hdrdir)/ruby/version.h +unixsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +unixsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +unixsocket.o: $(top_srcdir)/ccan/list/list.h +unixsocket.o: $(top_srcdir)/ccan/str/str.h +unixsocket.o: $(top_srcdir)/encindex.h +unixsocket.o: $(top_srcdir)/id_table.h unixsocket.o: $(top_srcdir)/internal.h unixsocket.o: $(top_srcdir)/internal/array.h +unixsocket.o: $(top_srcdir)/internal/basic_operators.h +unixsocket.o: $(top_srcdir)/internal/box.h unixsocket.o: $(top_srcdir)/internal/compilers.h unixsocket.o: $(top_srcdir)/internal/error.h unixsocket.o: $(top_srcdir)/internal/gc.h +unixsocket.o: $(top_srcdir)/internal/imemo.h unixsocket.o: $(top_srcdir)/internal/io.h +unixsocket.o: $(top_srcdir)/internal/sanitizers.h unixsocket.o: $(top_srcdir)/internal/serial.h +unixsocket.o: $(top_srcdir)/internal/set_table.h unixsocket.o: $(top_srcdir)/internal/static_assert.h unixsocket.o: $(top_srcdir)/internal/string.h unixsocket.o: $(top_srcdir)/internal/thread.h unixsocket.o: $(top_srcdir)/internal/vm.h unixsocket.o: $(top_srcdir)/internal/warnings.h +unixsocket.o: $(top_srcdir)/method.h +unixsocket.o: $(top_srcdir)/node.h +unixsocket.o: $(top_srcdir)/ruby_assert.h +unixsocket.o: $(top_srcdir)/ruby_atomic.h +unixsocket.o: $(top_srcdir)/rubyparser.h +unixsocket.o: $(top_srcdir)/shape.h +unixsocket.o: $(top_srcdir)/thread_pthread.h +unixsocket.o: $(top_srcdir)/vm_core.h +unixsocket.o: $(top_srcdir)/vm_opts.h unixsocket.o: constdefs.h unixsocket.o: rubysocket.h unixsocket.o: sockport.h unixsocket.o: unixsocket.c +unixsocket.o: {$(VPATH)}id.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index c86cc8f8c0..a814e21c3a 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -316,6 +316,7 @@ end netpacket/packet.h net/ethernet.h sys/un.h + afunix.h ifaddrs.h sys/ioctl.h sys/sockio.h @@ -326,6 +327,8 @@ end net/if_dl.h arpa/nameser.h resolv.h + pthread.h + sched.h ].each {|h| if have_header(h, headers) headers << h @@ -346,10 +349,22 @@ have_type("struct sockaddr_storage", headers) have_type("struct addrinfo", headers) -if have_type("socklen_t", headers) - if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers) - $defs << "-DRSTRING_SOCKLEN=(socklen_t)RSTRING_LEN" +def check_socklen(headers) + def (fmt = "none").%(x) + x || self + end + s = checking_for("RSTRING_SOCKLEN", fmt) do + if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers) + "RSTRING_LEN" + else + "RSTRING_LENINT" + end end + $defs << "-DRSTRING_SOCKLEN=(socklen_t)"+s +end + +if have_type("socklen_t", headers) + check_socklen(headers) end have_type("struct in_pktinfo", headers) {|src| @@ -484,6 +499,9 @@ EOF have_func("getpeerucred(0, (ucred_t **)NULL)", headers) # SunOS have_func_decl = proc do |name, headers| + # check if there is a declaration of <name> by trying to declare + # both "int <name>(void)" and "void <name>(void)" + # (at least one attempt should fail if there is a declaration) if !checking_for("declaration of #{name}()") {!%w[int void].all? {|ret| try_compile(<<EOF)}} #{cpp_include(headers)} #{ret} #{name}(void); @@ -492,10 +510,10 @@ EOF end end if have_func('if_indextoname(0, "")', headers) - have_func_decl["if_indextoname"] + have_func_decl["if_indextoname", headers] end if have_func('if_nametoindex("")', headers) - have_func_decl["if_nametoindex"] + have_func_decl["if_nametoindex", headers] end have_func("hsterror", headers) @@ -548,7 +566,7 @@ EOS end if !have_macro("IPPROTO_IPV6", headers) && have_const("IPPROTO_IPV6", headers) - IO.read(File.join(File.dirname(__FILE__), "mkconstants.rb")).sub(/\A.*^__END__$/m, '').split(/\r?\n/).grep(/\AIPPROTO_\w*/){$&}.each {|name| + File.read(File.join(File.dirname(__FILE__), "mkconstants.rb")).sub(/\A.*^__END__$/m, '').split(/\r?\n/).grep(/\AIPPROTO_\w*/){$&}.each {|name| have_const(name, headers) unless $defs.include?("-DHAVE_CONST_#{name.upcase}") } end @@ -652,12 +670,20 @@ EOS end hdr = "netinet6/in6.h" - if /darwin/ =~ RUBY_PLATFORM and !try_compile(<<"SRC", nil, :werror=>true) + /darwin/ =~ RUBY_PLATFORM and + checking_for("if apple's #{hdr} needs s6_addr patch") {!try_compile(<<"SRC", nil, :werror=>true)} and #include <netinet/in.h> int t(struct in6_addr *addr) {return IN6_IS_ADDR_UNSPECIFIED(addr);} SRC - print "fixing apple's netinet6/in6.h ..."; $stdout.flush - in6 = File.read("/usr/include/#{hdr}") + checking_for("fixing apple's #{hdr}", "%s") do + file = xpopen(%w"clang -include netinet/in.h -E -xc -", in: IO::NULL) do |f| + re = %r[^# *\d+ *"(.*/netinet/in\.h)"] + Logging.message " grep(#{re})\n" + f.read[re, 1] + end + Logging.message "Substitute from #{file}\n" + + in6 = File.read(file) if in6.gsub!(/\*\(const\s+__uint32_t\s+\*\)\(const\s+void\s+\*\)\(&(\(\w+\))->s6_addr\[(\d+)\]\)/) do i, r = $2.to_i.divmod(4) if r.zero? @@ -667,13 +693,19 @@ SRC end end FileUtils.mkdir_p(File.dirname(hdr)) - open(hdr, "w") {|f| f.write(in6)} + File.write(hdr, in6) $distcleanfiles << hdr $distcleandirs << File.dirname(hdr) - puts "done" + "done" else - puts "not needed" + "not needed" end end + + have_func("pthread_create") + have_func("pthread_detach") + have_func("pthread_attr_setdetachstate") + + $VPATH << '$(topdir)' << '$(top_srcdir)' create_makefile("socket") end diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c index ce6dc40478..9a65490b1d 100644 --- a/ext/socket/getaddrinfo.c +++ b/ext/socket/getaddrinfo.c @@ -62,9 +62,6 @@ #endif #include <unistd.h> #else -#if defined(_MSC_VER) && _MSC_VER <= 1200 -#include <windows.h> -#endif #include <winsock2.h> #include <ws2tcpip.h> #include <io.h> @@ -98,42 +95,42 @@ static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; static const char in_addrany[] = { 0, 0, 0, 0 }; static const char in6_addrany[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char in_loopback[] = { 127, 0, 0, 1 }; static const char in6_loopback[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; + u_char si_len; + u_char si_family; + u_short si_port; }; static const struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; - const char *a_addrany; - const char *a_loopback; + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; } afdl [] = { #ifdef INET6 #define N_INET6 0 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr), - in6_addrany, in6_loopback}, + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback}, #define N_INET 1 #else #define N_INET 0 #endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr), - in_addrany, in_loopback}, - {0, 0, 0, 0, NULL, NULL}, + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback}, + {0, 0, 0, 0, NULL, NULL}, }; #ifdef INET6 @@ -143,58 +140,56 @@ static const struct afd { #endif static int get_name __P((const char *, const struct afd *, - struct addrinfo **, char *, struct addrinfo *, - int)); + struct addrinfo **, char *, struct addrinfo *, + int)); static int get_addr __P((const char *, int, struct addrinfo **, - struct addrinfo *, int)); + struct addrinfo *, int)); static int str_isnumber __P((const char *)); #ifndef HAVE_GAI_STRERROR static const char *const ai_errlist[] = { - "success.", - "address family for hostname not supported.", /* EAI_ADDRFAMILY */ - "temporary failure in name resolution.", /* EAI_AGAIN */ - "invalid value for ai_flags.", /* EAI_BADFLAGS */ - "non-recoverable failure in name resolution.", /* EAI_FAIL */ - "ai_family not supported.", /* EAI_FAMILY */ - "memory allocation failure.", /* EAI_MEMORY */ - "no address associated with hostname.", /* EAI_NODATA */ - "hostname nor servname provided, or not known.",/* EAI_NONAME */ - "servname not supported for ai_socktype.", /* EAI_SERVICE */ - "ai_socktype not supported.", /* EAI_SOCKTYPE */ - "system error returned in errno.", /* EAI_SYSTEM */ - "invalid value for hints.", /* EAI_BADHINTS */ - "resolved protocol is unknown.", /* EAI_PROTOCOL */ - "unknown error.", /* EAI_MAX */ + "success.", + "address family for hostname not supported.", /* EAI_ADDRFAMILY */ + "temporary failure in name resolution.", /* EAI_AGAIN */ + "invalid value for ai_flags.", /* EAI_BADFLAGS */ + "non-recoverable failure in name resolution.", /* EAI_FAIL */ + "ai_family not supported.", /* EAI_FAMILY */ + "memory allocation failure.", /* EAI_MEMORY */ + "no address associated with hostname.", /* EAI_NODATA */ + "hostname nor servname provided, or not known.",/* EAI_NONAME */ + "servname not supported for ai_socktype.", /* EAI_SERVICE */ + "ai_socktype not supported.", /* EAI_SOCKTYPE */ + "system error returned in errno.", /* EAI_SYSTEM */ + "invalid value for hints.", /* EAI_BADHINTS */ + "resolved protocol is unknown.", /* EAI_PROTOCOL */ + "unknown error.", /* EAI_MAX */ }; #endif #define GET_CANONNAME(ai, str) \ if (pai->ai_flags & AI_CANONNAME) {\ - if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ - strcpy((ai)->ai_canonname, (str));\ - } else {\ - error = EAI_MEMORY;\ - goto free;\ - }\ + if (((ai)->ai_canonname = strdup(str)) == NULL) {\ + error = EAI_MEMORY;\ + goto free;\ + }\ } #define GET_AI(ai, afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((afd)->a_socklen)))\ - == NULL) {\ - error = EAI_MEMORY;\ - goto free;\ - }\ - memcpy((ai), pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - (ai)->ai_family = (afd)->a_af;\ - (ai)->ai_addrlen = (afd)->a_socklen;\ - INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\ - ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((afd)->a_socklen)))\ + == NULL) {\ + error = EAI_MEMORY;\ + goto free;\ + }\ + memcpy((ai), pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + (ai)->ai_family = (afd)->a_af;\ + (ai)->ai_addrlen = (afd)->a_socklen;\ + INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\ + ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\ } #define ERR(err) { error = (err); goto bad; } @@ -206,36 +201,35 @@ const char * gai_strerror(int ecode) { - if (ecode < 0 || ecode > EAI_MAX) - ecode = EAI_MAX; - return (char *)ai_errlist[ecode]; + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return (char *)ai_errlist[ecode]; } #endif void freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *next; - - do { - next = ai->ai_next; - if (ai->ai_canonname) - free(ai->ai_canonname); - /* no need to free(ai->ai_addr) */ - free(ai); - } while ((ai = next) != NULL); + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + } while ((ai = next) != NULL); } static int str_isnumber(const char *p) { - char *q = (char *)p; - while (*q) { - if (! isdigit(*q)) - return NO; - q++; - } - return YES; + char *q = (char *)p; + while (*q) { + if (! isdigit(*q)) + return NO; + q++; + } + return YES; } #ifndef HAVE_INET_PTON @@ -243,435 +237,435 @@ str_isnumber(const char *p) static int inet_pton(int af, const char *hostname, void *pton) { - struct in_addr in; + struct in_addr in; #ifdef HAVE_INET_ATON - if (!inet_aton(hostname, &in)) - return 0; + if (!inet_aton(hostname, &in)) + return 0; #else - int d1, d2, d3, d4; - char ch; - - if (sscanf(hostname, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 && - 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 && - 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) { - in.s_addr = htonl( - ((long) d1 << 24) | ((long) d2 << 16) | - ((long) d3 << 8) | ((long) d4 << 0)); - } - else { - return 0; - } -#endif - memcpy(pton, &in, sizeof(in)); - return 1; + int d1, d2, d3, d4; + char ch; + + if (sscanf(hostname, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 && + 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 && + 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) { + in.s_addr = htonl( + ((long) d1 << 24) | ((long) d2 << 16) | + ((long) d3 << 8) | ((long) d4 << 0)); + } + else { + return 0; + } +#endif + memcpy(pton, &in, sizeof(in)); + return 1; } #endif int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { - struct addrinfo sentinel; - struct addrinfo *top = NULL; - struct addrinfo *cur; - int i, error = 0; - char pton[PTON_MAX]; - struct addrinfo ai; - struct addrinfo *pai; - u_short port; + struct addrinfo sentinel; + struct addrinfo *top = NULL; + struct addrinfo *cur; + int i, error = 0; + char pton[PTON_MAX]; + struct addrinfo ai; + struct addrinfo *pai; + u_short port; #ifdef FAITH - static int firsttime = 1; - - if (firsttime) { - /* translator hack */ - { - char *q = getenv("GAI"); - if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) - translate = YES; - } - firsttime = 0; - } -#endif - - /* initialize file static vars */ - sentinel.ai_next = NULL; - cur = &sentinel; - pai = &ai; - pai->ai_flags = 0; - pai->ai_family = PF_UNSPEC; - pai->ai_socktype = ANY; - pai->ai_protocol = ANY; - pai->ai_addrlen = 0; - pai->ai_canonname = NULL; - pai->ai_addr = NULL; - pai->ai_next = NULL; - port = ANY; - - if (hostname == NULL && servname == NULL) - return EAI_NONAME; - if (hints) { - /* error check for hints */ - if (hints->ai_addrlen || hints->ai_canonname || - hints->ai_addr || hints->ai_next) - ERR(EAI_BADHINTS); /* xxx */ - if (hints->ai_flags & ~AI_MASK) - ERR(EAI_BADFLAGS); - switch (hints->ai_family) { - case PF_UNSPEC: - case PF_INET: + static int firsttime = 1; + + if (firsttime) { + /* translator hack */ + { + char *q = getenv("GAI"); + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) + translate = YES; + } + firsttime = 0; + } +#endif + + /* initialize file static vars */ + sentinel.ai_next = NULL; + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = ANY; + pai->ai_protocol = ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; + port = ANY; + + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ + if (hints->ai_addrlen || hints->ai_canonname || + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: #ifdef INET6 - case PF_INET6: -#endif - break; - default: - ERR(EAI_FAMILY); - } - memcpy(pai, hints, sizeof(*pai)); - switch (pai->ai_socktype) { - case ANY: - switch (pai->ai_protocol) { - case ANY: - break; - case IPPROTO_UDP: - pai->ai_socktype = SOCK_DGRAM; - break; - case IPPROTO_TCP: - pai->ai_socktype = SOCK_STREAM; - break; - default: + case PF_INET6: +#endif + break; + default: + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + switch (pai->ai_socktype) { + case ANY: + switch (pai->ai_protocol) { + case ANY: + break; + case IPPROTO_UDP: + pai->ai_socktype = SOCK_DGRAM; + break; + case IPPROTO_TCP: + pai->ai_socktype = SOCK_STREAM; + break; + default: #if defined(SOCK_RAW) - pai->ai_socktype = SOCK_RAW; + pai->ai_socktype = SOCK_RAW; #endif - break; - } - break; + break; + } + break; #if defined(SOCK_RAW) - case SOCK_RAW: - break; -#endif - case SOCK_DGRAM: - if (pai->ai_protocol != IPPROTO_UDP && - pai->ai_protocol != ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_UDP; - break; - case SOCK_STREAM: - if (pai->ai_protocol != IPPROTO_TCP && - pai->ai_protocol != ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_TCP; - break; - default: - ERR(EAI_SOCKTYPE); - break; - } - } - - /* - * service port - */ - if (servname) { - if (str_isnumber(servname)) { - if (pai->ai_socktype == ANY) { - /* caller accept *ANY* socktype */ - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } - port = htons((unsigned short)atoi(servname)); + case SOCK_RAW: + break; +#endif + case SOCK_DGRAM: + if (pai->ai_protocol != IPPROTO_UDP && + pai->ai_protocol != ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_UDP; + break; + case SOCK_STREAM: + if (pai->ai_protocol != IPPROTO_TCP && + pai->ai_protocol != ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_TCP; + break; + default: + ERR(EAI_SOCKTYPE); + break; + } + } + + /* + * service port + */ + if (servname) { + if (str_isnumber(servname)) { + if (pai->ai_socktype == ANY) { + /* caller accept *ANY* socktype */ + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } + port = htons((unsigned short)atoi(servname)); } else if (pai->ai_flags & AI_NUMERICSERV) { ERR(EAI_NONAME); - } else { - struct servent *sp; - const char *proto; - - proto = NULL; - switch (pai->ai_socktype) { - case ANY: - proto = NULL; - break; - case SOCK_DGRAM: - proto = "udp"; - break; - case SOCK_STREAM: - proto = "tcp"; - break; - default: - fprintf(stderr, "panic!\n"); - break; - } - if ((sp = getservbyname((char*)servname, proto)) == NULL) - ERR(EAI_SERVICE); - port = sp->s_port; - if (pai->ai_socktype == ANY) - if (strcmp(sp->s_proto, "udp") == 0) { - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } else if (strcmp(sp->s_proto, "tcp") == 0) { - pai->ai_socktype = SOCK_STREAM; - pai->ai_protocol = IPPROTO_TCP; - } else - ERR(EAI_PROTOCOL); /*xxx*/ - } - } - - /* - * hostname == NULL. - * passive socket -> anyaddr (0.0.0.0 or ::) - * non-passive socket -> localhost (127.0.0.1 or ::1) - */ - if (hostname == NULL) { - const struct afd *afd; - int s; - - for (afd = &afdl[0]; afd->a_af; afd++) { - if (!(pai->ai_family == PF_UNSPEC - || pai->ai_family == afd->a_af)) { - continue; - } - - /* - * filter out AFs that are not supported by the kernel - * XXX errno? - */ - s = socket(afd->a_af, SOCK_DGRAM, 0); - if (s < 0) - continue; - - close(s); - - if (pai->ai_flags & AI_PASSIVE) { - GET_AI(cur->ai_next, afd, afd->a_addrany, port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "anyaddr"); - */ - } else { - GET_AI(cur->ai_next, afd, afd->a_loopback, - port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "localhost"); - */ - } - cur = cur->ai_next; - } - top = sentinel.ai_next; - if (top) - goto good; - else - ERR(EAI_FAMILY); - } - - /* hostname as numeric name */ - for (i = 0; afdl[i].a_af; i++) { - if (inet_pton(afdl[i].a_af, hostname, pton)) { - u_long v4a; + } else { + struct servent *sp; + const char *proto; + + proto = NULL; + switch (pai->ai_socktype) { + case ANY: + proto = NULL; + break; + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + fprintf(stderr, "panic!\n"); + break; + } + if ((sp = getservbyname((char*)servname, proto)) == NULL) + ERR(EAI_SERVICE); + port = sp->s_port; + if (pai->ai_socktype == ANY) + if (strcmp(sp->s_proto, "udp") == 0) { + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } else if (strcmp(sp->s_proto, "tcp") == 0) { + pai->ai_socktype = SOCK_STREAM; + pai->ai_protocol = IPPROTO_TCP; + } else + ERR(EAI_PROTOCOL); /*xxx*/ + } + } + + /* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ + if (hostname == NULL) { + const struct afd *afd; + int s; + + for (afd = &afdl[0]; afd->a_af; afd++) { + if (!(pai->ai_family == PF_UNSPEC + || pai->ai_family == afd->a_af)) { + continue; + } + + /* + * filter out AFs that are not supported by the kernel + * XXX errno? + */ + s = socket(afd->a_af, SOCK_DGRAM, 0); + if (s < 0) + continue; + + close(s); + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, afd, afd->a_addrany, port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + } else { + GET_AI(cur->ai_next, afd, afd->a_loopback, + port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + } + cur = cur->ai_next; + } + top = sentinel.ai_next; + if (top) + goto good; + else + ERR(EAI_FAMILY); + } + + /* hostname as numeric name */ + for (i = 0; afdl[i].a_af; i++) { + if (inet_pton(afdl[i].a_af, hostname, pton)) { + u_long v4a; #ifdef INET6 - u_char pfx; -#endif - - switch (afdl[i].a_af) { - case AF_INET: - v4a = ((struct in_addr *)pton)->s_addr; - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - pai->ai_flags &= ~AI_CANONNAME; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) - pai->ai_flags &= ~AI_CANONNAME; - break; + u_char pfx; +#endif + + switch (afdl[i].a_af) { + case AF_INET: + v4a = ((struct in_addr *)pton)->s_addr; + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + pai->ai_flags &= ~AI_CANONNAME; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + pai->ai_flags &= ~AI_CANONNAME; + break; #ifdef INET6 - case AF_INET6: - pfx = ((struct in6_addr *)pton)->s6_addr[0]; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - pai->ai_flags &= ~AI_CANONNAME; - break; -#endif - } - - if (pai->ai_family == afdl[i].a_af || - pai->ai_family == PF_UNSPEC) { - if (! (pai->ai_flags & AI_CANONNAME)) { - GET_AI(top, &afdl[i], pton, port); - goto good; - } - /* - * if AI_CANONNAME and if reverse lookup - * fail, return ai anyway to pacify - * calling application. - * - * XXX getaddrinfo() is a name->address - * translation function, and it looks strange - * that we do addr->name translation here. - */ - get_name(pton, &afdl[i], &top, pton, pai, port); - goto good; - } else - ERR(EAI_FAMILY); /*xxx*/ - } - } - - if (pai->ai_flags & AI_NUMERICHOST) - ERR(EAI_NONAME); - - /* hostname as alphabetical name */ - error = get_addr(hostname, pai->ai_family, &top, pai, port); - if (error == 0) { - if (top) { + case AF_INET6: + pfx = ((struct in6_addr *)pton)->s6_addr[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + pai->ai_flags &= ~AI_CANONNAME; + break; +#endif + } + + if (pai->ai_family == afdl[i].a_af || + pai->ai_family == PF_UNSPEC) { + if (! (pai->ai_flags & AI_CANONNAME)) { + GET_AI(top, &afdl[i], pton, port); + goto good; + } + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks strange + * that we do addr->name translation here. + */ + get_name(pton, &afdl[i], &top, pton, pai, port); + goto good; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + } + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + + /* hostname as alphabetical name */ + error = get_addr(hostname, pai->ai_family, &top, pai, port); + if (error == 0) { + if (top) { good: - *res = top; - return SUCCESS; - } else - error = EAI_FAIL; - } + *res = top; + return SUCCESS; + } else + error = EAI_FAIL; + } free: - if (top) - freeaddrinfo(top); + if (top) + freeaddrinfo(top); bad: - *res = NULL; - return error; + *res = NULL; + return error; } static int get_name(const char *addr, const struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0) { - u_short port = port0 & 0xffff; - struct hostent *hp; - struct addrinfo *cur; - int error = 0; + u_short port = port0 & 0xffff; + struct hostent *hp; + struct addrinfo *cur; + int error = 0; #ifdef INET6 - int h_error; + int h_error; #endif #ifdef INET6 - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); #else - hp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET); + hp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET); #endif - if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { - GET_AI(cur, afd, hp->h_addr_list[0], port); - GET_CANONNAME(cur, hp->h_name); - } else - GET_AI(cur, afd, numaddr, port); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + GET_AI(cur, afd, hp->h_addr_list[0], port); + GET_CANONNAME(cur, hp->h_name); + } else + GET_AI(cur, afd, numaddr, port); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif - *res = cur; - return SUCCESS; + *res = cur; + return SUCCESS; free: - if (cur) - freeaddrinfo(cur); + if (cur) + freeaddrinfo(cur); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif /* bad: */ - *res = NULL; - return error; + *res = NULL; + return error; } static int get_addr(const char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0) { - u_short port = port0 & 0xffff; - struct addrinfo sentinel; - struct hostent *hp; - struct addrinfo *top, *cur; - const struct afd *afd; - int i, error = 0, h_error; - char *ap; - - top = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; + u_short port = port0 & 0xffff; + struct addrinfo sentinel; + struct hostent *hp; + struct addrinfo *top, *cur; + const struct afd *afd; + int i, error = 0, h_error; + char *ap; + + top = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; #ifdef INET6 - if (af == AF_UNSPEC) { - hp = getipnodebyname(hostname, AF_INET6, - AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); - } else - hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); + if (af == AF_UNSPEC) { + hp = getipnodebyname(hostname, AF_INET6, + AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); + } else + hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); #else - if (strlen(hostname) >= NI_MAXHOST) ERR(EAI_NODATA); - hp = gethostbyname((char*)hostname); - h_error = h_errno; -#endif - if (hp == NULL) { - switch (h_error) { - case HOST_NOT_FOUND: - case NO_DATA: - error = EAI_NODATA; - break; - case TRY_AGAIN: - error = EAI_AGAIN; - break; - case NO_RECOVERY: - default: - error = EAI_FAIL; - break; - } - goto bad; - } - - if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || - (hp->h_addr_list[0] == NULL)) - ERR(EAI_FAIL); - - for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { - switch (af) { + if (strlen(hostname) >= NI_MAXHOST) ERR(EAI_NODATA); + hp = gethostbyname((char*)hostname); + h_error = h_errno; +#endif + if (hp == NULL) { + switch (h_error) { + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NODATA; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + default: + error = EAI_FAIL; + break; + } + goto bad; + } + + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) + ERR(EAI_FAIL); + + for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { + switch (af) { #ifdef INET6 - case AF_INET6: - afd = &afdl[N_INET6]; - break; + case AF_INET6: + afd = &afdl[N_INET6]; + break; #endif #ifndef INET6 - default: /* AF_UNSPEC */ + default: /* AF_UNSPEC */ #endif - case AF_INET: - afd = &afdl[N_INET]; - break; + case AF_INET: + afd = &afdl[N_INET]; + break; #ifdef INET6 - default: /* AF_UNSPEC */ - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { - ap += sizeof(struct in6_addr) - - sizeof(struct in_addr); - afd = &afdl[N_INET]; - } else - afd = &afdl[N_INET6]; - break; -#endif - } + default: /* AF_UNSPEC */ + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + ap += sizeof(struct in6_addr) - + sizeof(struct in_addr); + afd = &afdl[N_INET]; + } else + afd = &afdl[N_INET6]; + break; +#endif + } #ifdef FAITH - if (translate && afd->a_af == AF_INET) { - struct in6_addr *in6; - - GET_AI(cur->ai_next, &afdl[N_INET6], ap, port); - in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; - memcpy(&in6->s6_addr, &faith_prefix, - sizeof(struct in6_addr) - sizeof(struct in_addr)); - memcpy(&in6->s6_addr + sizeof(struct in_addr), ap, - sizeof(struct in_addr)); - } else + if (translate && afd->a_af == AF_INET) { + struct in6_addr *in6; + + GET_AI(cur->ai_next, &afdl[N_INET6], ap, port); + in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; + memcpy(&in6->s6_addr, &faith_prefix, + sizeof(struct in6_addr) - sizeof(struct in_addr)); + memcpy(&in6->s6_addr + sizeof(struct in_addr), ap, + sizeof(struct in_addr)); + } else #endif /* FAITH */ - GET_AI(cur->ai_next, afd, ap, port); - if (cur == &sentinel) { - top = cur->ai_next; - GET_CANONNAME(top, hp->h_name); - } - cur = cur->ai_next; - } + GET_AI(cur->ai_next, afd, ap, port); + if (cur == &sentinel) { + top = cur->ai_next; + GET_CANONNAME(top, hp->h_name); + } + cur = cur->ai_next; + } #ifdef INET6 - freehostent(hp); + freehostent(hp); #endif - *res = top; - return SUCCESS; + *res = top; + return SUCCESS; free: - if (top) - freeaddrinfo(top); + if (top) + freeaddrinfo(top); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif bad: - *res = NULL; - return error; + *res = NULL; + return error; } diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c index 94a5eb9439..98da8c1647 100644 --- a/ext/socket/getnameinfo.c +++ b/ext/socket/getnameinfo.c @@ -55,9 +55,6 @@ #endif #endif #ifdef _WIN32 -#if defined(_MSC_VER) && _MSC_VER <= 1200 -#include <windows.h> -#endif #include <winsock2.h> #include <ws2tcpip.h> #define snprintf _snprintf @@ -84,30 +81,30 @@ typedef int socklen_t; #define NO 0 struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; + u_char si_len; + u_char si_family; + u_short si_port; }; static struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; + int a_af; + int a_addrlen; + int a_socklen; + int a_off; } afdl [] = { #ifdef INET6 #define N_INET6 0 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr)}, + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr)}, #define N_INET 1 #else #define N_INET 0 #endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr)}, - {0, 0, 0, 0}, + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr)}, + {0, 0, 0, 0}, }; #define ENI_NOSOCKET 0 @@ -121,123 +118,118 @@ static struct afd { int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) { - struct afd *afd; - struct hostent *hp; - u_short port; - int family, len, i; - char *addr, *p; - u_long v4a; + struct afd *afd; + struct hostent *hp; + u_short port; + int family, len, i; + char *addr, *p; + u_long v4a; #ifdef INET6 - u_char pfx; + u_char pfx; #endif - int h_error; - char numserv[512]; - char numaddr[512]; + int h_error; + char numserv[512]; + char numaddr[512]; - if (sa == NULL) - return ENI_NOSOCKET; + if (sa == NULL) + return ENI_NOSOCKET; - if (!VALIDATE_SOCKLEN(sa, salen)) return ENI_SALEN; + if (!VALIDATE_SOCKLEN(sa, salen)) return ENI_SALEN; len = salen; - family = sa->sa_family; - for (i = 0; afdl[i].a_af; i++) - if (afdl[i].a_af == family) { - afd = &afdl[i]; - goto found; - } - return ENI_FAMILY; + family = sa->sa_family; + for (i = 0; afdl[i].a_af; i++) + if (afdl[i].a_af == family) { + afd = &afdl[i]; + goto found; + } + return ENI_FAMILY; found: - if (len != afd->a_socklen) return ENI_SALEN; - - port = ((struct sockinet *)sa)->si_port; /* network byte order */ - addr = (char *)sa + afd->a_off; - - if (serv == NULL || servlen == 0) { - /* what we should do? */ - } else if (flags & NI_NUMERICSERV) { - snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); - if (strlen(numserv) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, numserv); - } else { + if (len != afd->a_socklen) return ENI_SALEN; + + port = ((struct sockinet *)sa)->si_port; /* network byte order */ + addr = (char *)sa + afd->a_off; + + if (serv == NULL || servlen == 0) { + /* what we should do? */ + } else if (flags & NI_NUMERICSERV) { + snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); + if (strlcpy(serv, numserv, servlen) >= servlen) + return ENI_MEMORY; + } else { #if defined(HAVE_GETSERVBYPORT) - struct servent *sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); - if (sp) { - if (strlen(sp->s_name) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, sp->s_name); - } else - return ENI_NOSERVNAME; + struct servent *sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); + if (sp) { + if (strlcpy(serv, sp->s_name, servlen) >= servlen) + return ENI_MEMORY; + } else + return ENI_NOSERVNAME; #else - return ENI_NOSERVNAME; -#endif - } - - switch (sa->sa_family) { - case AF_INET: - v4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags |= NI_NUMERICHOST; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0) - flags |= NI_NUMERICHOST; - break; + return ENI_NOSERVNAME; +#endif + } + + switch (sa->sa_family) { + case AF_INET: + v4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + flags |= NI_NUMERICHOST; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0) + flags |= NI_NUMERICHOST; + break; #ifdef INET6 - case AF_INET6: + case AF_INET6: #ifdef HAVE_ADDR8 - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; #else - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; -#endif - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - flags |= NI_NUMERICHOST; - break; -#endif - } - if (host == NULL || hostlen == 0) { - /* what should we do? */ - } else if (flags & NI_NUMERICHOST) { - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_SYSTEM; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } else { + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; +#endif + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + flags |= NI_NUMERICHOST; + break; +#endif + } + if (host == NULL || hostlen == 0) { + /* what should we do? */ + } else if (flags & NI_NUMERICHOST) { + if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_SYSTEM; + if (strlcpy(host, numaddr, hostlen) >= hostlen) + return ENI_MEMORY; + } else { #ifdef INET6 - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); #else - hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); - h_error = h_errno; + hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); + h_error = h_errno; #endif - if (hp) { - if (flags & NI_NOFQDN) { - p = strchr(hp->h_name, '.'); - if (p) *p = '\0'; - } - if (strlen(hp->h_name) + 1 > hostlen) { + if (hp) { + if (flags & NI_NOFQDN) { + p = strchr(hp->h_name, '.'); + if (p) *p = '\0'; + } + if (strlcpy(host, hp->h_name, hostlen) >= hostlen) { #ifdef INET6 - freehostent(hp); + freehostent(hp); #endif - return ENI_MEMORY; - } - strcpy(host, hp->h_name); + return ENI_MEMORY; + } #ifdef INET6 - freehostent(hp); -#endif - } else { - if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_NOHOSTNAME; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } - } - return SUCCESS; + freehostent(hp); +#endif + } else { + if (flags & NI_NAMEREQD) + return ENI_NOHOSTNAME; + if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_NOHOSTNAME; + if (strlcpy(host, numaddr, hostlen) >= hostlen) + return ENI_MEMORY; + } + } + return SUCCESS; } diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c index 1da259bd6f..3596c40a11 100644 --- a/ext/socket/ifaddr.c +++ b/ext/socket/ifaddr.c @@ -104,7 +104,7 @@ rsock_getifaddrs(void) rb_sys_fail("getifaddrs"); if (!ifaddrs) { - return rb_ary_new(); + return rb_ary_new(); } numifaddrs = 0; @@ -128,9 +128,9 @@ rsock_getifaddrs(void) result = rb_ary_new2(numifaddrs); rb_ary_push(result, addr); for (i = 1; i < numifaddrs; i++) { - addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]); - root->refcount++; - rb_ary_push(result, addr); + addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]); + root->refcount++; + rb_ary_push(result, addr); } return result; @@ -177,6 +177,8 @@ ifaddr_ifindex(VALUE self) * ifaddr.flags => integer * * Returns the flags of _ifaddr_. + * + * The value is bitwise-or of Socket::IFF_* constants such as Socket::IFF_LOOPBACK. */ static VALUE diff --git a/ext/socket/init.c b/ext/socket/init.c index 359696e626..b761d601c3 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -27,6 +27,7 @@ VALUE rb_cSocket; VALUE rb_cAddrinfo; VALUE rb_eSocket; +VALUE rb_eResolution; #ifdef SOCKS VALUE rb_cSOCKSSocket; @@ -34,24 +35,29 @@ VALUE rb_cSOCKSSocket; int rsock_do_not_reverse_lookup = 1; static VALUE sym_wait_readable; +static ID id_error_code; void -rsock_raise_socket_error(const char *reason, int error) +rsock_raise_resolution_error(const char *reason, int error) { #ifdef EAI_SYSTEM int e; if (error == EAI_SYSTEM && (e = errno) != 0) - rb_syserr_fail(e, reason); + rb_syserr_fail(e, reason); #endif #ifdef _WIN32 rb_encoding *enc = rb_default_internal_encoding(); VALUE msg = rb_sprintf("%s: ", reason); if (!enc) enc = rb_default_internal_encoding(); rb_str_concat(msg, rb_w32_conv_from_wchar(gai_strerrorW(error), enc)); - rb_exc_raise(rb_exc_new_str(rb_eSocket, msg)); #else - rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error)); + VALUE msg = rb_sprintf("%s: %s", reason, gai_strerror(error)); #endif + + StringValue(msg); + VALUE self = rb_class_new_instance(1, &msg, rb_eResolution); + rb_ivar_set(self, id_error_code, INT2NUM(error)); + rb_exc_raise(self); } #if defined __APPLE__ @@ -71,7 +77,7 @@ rsock_init_sock(VALUE sock, int fd) fp->mode = FMODE_READWRITE|FMODE_DUPLEX; rb_io_ascii8bit_binmode(sock); if (rsock_do_not_reverse_lookup) { - fp->mode |= FMODE_NOREVLOOKUP; + fp->mode |= FMODE_NOREVLOOKUP; } rb_io_synchronized(fp); @@ -85,7 +91,7 @@ rsock_sendto_blocking(void *data) VALUE mesg = arg->mesg; ssize_t ret; do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags, arg->to, arg->tolen)); + arg->flags, arg->to, arg->tolen)); return (VALUE)ret; } @@ -96,11 +102,12 @@ rsock_send_blocking(void *data) VALUE mesg = arg->mesg; ssize_t ret; do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags)); + arg->flags)); return (VALUE)ret; } struct recvfrom_arg { + rb_io_t *fptr; int fd, flags; VALUE str; size_t length; @@ -116,6 +123,7 @@ recvfrom_blocking(void *data) ssize_t ret; ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), arg->length, arg->flags, &arg->buf.addr, &arg->alen); + if (ret != -1 && len0 < arg->alen) arg->alen = len0; @@ -132,9 +140,9 @@ rsock_strbuf(VALUE str, long buflen) StringValue(str); len = RSTRING_LEN(str); if (len >= buflen) { - rb_str_modify(str); + rb_str_modify(str); } else { - rb_str_modify_expand(str, buflen - len); + rb_str_modify_expand(str, buflen - len); } return str; } @@ -144,7 +152,19 @@ recvfrom_locktmp(VALUE v) { struct recvfrom_arg *arg = (struct recvfrom_arg *)v; - return rb_thread_io_blocking_region(recvfrom_blocking, arg, arg->fd); + return rb_io_blocking_region(arg->fptr, recvfrom_blocking, arg); +} + +int +rsock_is_dgram(rb_io_t *fptr) +{ + int socktype; + socklen_t optlen = (socklen_t)sizeof(socktype); + int ret = getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen); + if (ret == -1) { + rb_sys_fail("getsockopt(SO_TYPE)"); + } + return socktype == SOCK_DGRAM; } VALUE @@ -173,6 +193,7 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) rb_raise(rb_eIOError, "recv for buffered IO"); } + arg.fptr = fptr; arg.fd = fptr->fd; arg.alen = (socklen_t)sizeof(arg.buf); arg.str = str; @@ -185,11 +206,15 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); #endif - slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp, (VALUE)&arg); + rb_str_locktmp(str); + slen = (long)rb_ensure(recvfrom_locktmp, (VALUE)&arg, rb_str_unlocktmp, str); + if (slen == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } if (slen >= 0) break; - if (!rb_io_maybe_wait_readable(errno, socket, Qnil)) + if (!rb_io_maybe_wait_readable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) rb_sys_fail("recvfrom(2)"); } @@ -197,32 +222,32 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) rb_str_set_len(str, slen); switch (from) { case RECV_RECV: - return str; + return str; case RECV_IP: #if 0 - if (arg.alen != sizeof(struct sockaddr_in)) { - rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); - } + if (arg.alen != sizeof(struct sockaddr_in)) { + rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); + } #endif - if (arg.alen && arg.alen != sizeof(arg.buf)) /* OSX doesn't return a from result for connection-oriented sockets */ - return rb_assoc_new(str, rsock_ipaddr(&arg.buf.addr, arg.alen, fptr->mode & FMODE_NOREVLOOKUP)); - else - return rb_assoc_new(str, Qnil); + if (arg.alen && arg.alen != sizeof(arg.buf)) /* OSX doesn't return a from result for connection-oriented sockets */ + return rb_assoc_new(str, rsock_ipaddr(&arg.buf.addr, arg.alen, fptr->mode & FMODE_NOREVLOOKUP)); + else + return rb_assoc_new(str, Qnil); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case RECV_UNIX: return rb_assoc_new(str, rsock_unixaddr(&arg.buf.un, arg.alen)); #endif case RECV_SOCKET: - return rb_assoc_new(str, rsock_io_socket_addrinfo(socket, &arg.buf.addr, arg.alen)); + return rb_assoc_new(str, rsock_io_socket_addrinfo(socket, &arg.buf.addr, arg.alen)); default: - rb_bug("rsock_s_recvfrom called with bad value"); + rb_bug("rsock_s_recvfrom called with bad value"); } } VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, - VALUE ex, enum sock_recv_type from) + VALUE ex, enum sock_recv_type from) { rb_io_t *fptr; union_sockaddr buf; @@ -245,35 +270,39 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, GetOpenFile(sock, fptr); if (rb_io_read_pending(fptr)) { - rb_raise(rb_eIOError, "recvfrom for buffered IO"); + rb_raise(rb_eIOError, "recvfrom for buffered IO"); } fd = fptr->fd; rb_io_check_closed(fptr); if (!MSG_DONTWAIT_RELIABLE) - rb_io_set_nonblock(fptr); + rb_io_set_nonblock(fptr); len0 = alen; slen = recvfrom(fd, RSTRING_PTR(str), buflen, flags, &buf.addr, &alen); if (slen != -1 && len0 < alen) alen = len0; + if (slen == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } + if (slen < 0) { - int e = errno; - switch (e) { - case EAGAIN: + int e = errno; + switch (e) { + case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: + case EWOULDBLOCK: #endif if (ex == Qfalse) - return sym_wait_readable; + return sym_wait_readable; rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvfrom(2) would block"); - } - rb_syserr_fail(e, "recvfrom(2)"); + } + rb_syserr_fail(e, "recvfrom(2)"); } if (slen != RSTRING_LEN(str)) { - rb_str_set_len(str, slen); + rb_str_set_len(str, slen); } switch (from) { case RECV_RECV: @@ -324,31 +353,31 @@ rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex) GetOpenFile(sock, fptr); if (len == 0) { - rb_str_set_len(str, 0); - return str; + rb_str_set_len(str, 0); + return str; } ptr = RSTRING_PTR(str); n = read_buffered_data(ptr, len, fptr); if (n <= 0) { - n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT); - if (n < 0) { - int e = errno; - if ((e == EWOULDBLOCK || e == EAGAIN)) { - if (ex == Qfalse) return sym_wait_readable; - rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, - e, "read would block"); - } - rb_syserr_fail_path(e, fptr->pathv); - } + n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT); + if (n < 0) { + int e = errno; + if ((e == EWOULDBLOCK || e == EAGAIN)) { + if (ex == Qfalse) return sym_wait_readable; + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, + e, "read would block"); + } + rb_syserr_fail_path(e, fptr->pathv); + } } if (n != RSTRING_LEN(str)) { - rb_str_modify(str); - rb_str_set_len(str, n); + rb_str_modify(str); + rb_str_set_len(str, n); } if (n == 0) { - if (ex == Qfalse) return Qnil; - rb_eof_error(); + if (ex == Qfalse) return Qnil; + rb_eof_error(); } return str; @@ -362,7 +391,7 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) long n; if (!RB_TYPE_P(str, T_STRING)) - str = rb_obj_as_string(str); + str = rb_obj_as_string(str); sock = rb_io_get_write_io(sock); GetOpenFile(sock, fptr); @@ -374,7 +403,7 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) * are not userspace-buffered in Ruby by default. */ if (fptr->wbuf.len > 0) { - rb_io_flush(sock); + rb_io_flush(sock); } #ifdef __APPLE__ @@ -382,19 +411,19 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) #endif n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT); if (n < 0) { - int e = errno; + int e = errno; #ifdef __APPLE__ - if (e == EPROTOTYPE) { - goto again; - } -#endif - if (e == EWOULDBLOCK || e == EAGAIN) { - if (ex == Qfalse) return sym_wait_writable; - rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, - "write would block"); - } - rb_syserr_fail_path(e, fptr->pathv); + if (e == EPROTOTYPE) { + goto again; + } +#endif + if (e == EWOULDBLOCK || e == EAGAIN) { + if (ex == Qfalse) return sym_wait_writable; + rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, + "write would block"); + } + rb_syserr_fail_path(e, fptr->pathv); } return LONG2FIX(n); @@ -433,9 +462,9 @@ rsock_socket(int domain, int type, int proto) fd = rsock_socket0(domain, type, proto); if (fd < 0) { - if (rb_gc_for_fd(errno)) { - fd = rsock_socket0(domain, type, proto); - } + if (rb_gc_for_fd(errno)) { + fd = rsock_socket0(domain, type, proto); + } } if (0 <= fd) rb_update_max_fd(fd); @@ -444,10 +473,11 @@ rsock_socket(int domain, int type, int proto) /* emulate blocking connect behavior on EINTR or non-blocking socket */ static int -wait_connectable(int fd, struct timeval *timeout) +wait_connectable(VALUE self, VALUE timeout, const struct sockaddr *sockaddr, int len) { - int sockerr, revents; + int sockerr; socklen_t sockerrlen; + int fd = rb_io_descriptor(self); sockerrlen = (socklen_t)sizeof(sockerr); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0) @@ -481,7 +511,16 @@ wait_connectable(int fd, struct timeval *timeout) * * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART */ - revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, timeout); + VALUE result = rb_io_wait(self, RB_INT2NUM(RUBY_IO_READABLE|RUBY_IO_WRITABLE), timeout); + + if (result == Qfalse) { + VALUE rai = rsock_addrinfo_new((struct sockaddr *)sockaddr, len, PF_UNSPEC, 0, 0, Qnil, Qnil); + VALUE addr_str = rsock_addrinfo_inspect_sockaddr(rai); + VALUE message = rb_sprintf("user specified timeout for %" PRIsVALUE, addr_str); + rb_raise(rb_eIOTimeoutError, "%" PRIsVALUE, message); + } + + int revents = RB_NUM2INT(result); if (revents < 0) return -1; @@ -492,16 +531,10 @@ wait_connectable(int fd, struct timeval *timeout) switch (sockerr) { case 0: - /* - * be defensive in case some platforms set SO_ERROR on the original, - * interrupted connect() - */ - - /* when the connection timed out, no errno is set and revents is 0. */ - if (timeout && revents == 0) { - errno = ETIMEDOUT; - return -1; - } + /* + * be defensive in case some platforms set SO_ERROR on the original, + * interrupted connect() + */ case EINTR: #ifdef ERESTART case ERESTART: @@ -516,7 +549,7 @@ wait_connectable(int fd, struct timeval *timeout) #ifdef EISCONN case EISCONN: #endif - return 0; /* success */ + return 0; /* success */ default: /* likely (but not limited to): ECONNREFUSED, ETIMEDOUT, EHOSTUNREACH */ errno = sockerr; @@ -549,19 +582,19 @@ socks_connect_blocking(void *data) #endif int -rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout) +rsock_connect(VALUE self, const struct sockaddr *sockaddr, int len, int socks, VALUE timeout) { - int status; + int descriptor = rb_io_descriptor(self); rb_blocking_function_t *func = connect_blocking; - struct connect_arg arg; + struct connect_arg arg = {.fd = descriptor, .sockaddr = sockaddr, .len = len}; + + rb_io_t *fptr; + RB_IO_POINTER(self, fptr); - arg.fd = fd; - arg.sockaddr = sockaddr; - arg.len = len; #if defined(SOCKS) && !defined(SOCKS5) if (socks) func = socks_connect_blocking; #endif - status = (int)BLOCKING_REGION_FD(func, &arg); + int status = (int)rb_io_blocking_region(fptr, func, &arg); if (status < 0) { switch (errno) { @@ -573,7 +606,7 @@ rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struc #ifdef EINPROGRESS case EINPROGRESS: #endif - return wait_connectable(fd, timeout); + return wait_connectable(self, timeout, sockaddr, len); } } return status; @@ -634,27 +667,27 @@ cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, - struct sockaddr *sockaddr, socklen_t *len) + struct sockaddr *sockaddr, socklen_t *len) { int fd2; rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len); if (fd2 < 0) { - int e = errno; - switch (e) { - case EAGAIN: + int e = errno; + switch (e) { + case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: + case EWOULDBLOCK: #endif - case ECONNABORTED: + case ECONNABORTED: #if defined EPROTO - case EPROTO: + case EPROTO: #endif if (ex == Qfalse) - return sym_wait_readable; + return sym_wait_readable; rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "accept(2) would block"); - } + } rb_syserr_fail(e, "accept(2)"); } rb_update_max_fd(fd2); @@ -681,9 +714,9 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) RB_IO_POINTER(io, fptr); struct accept_arg accept_arg = { - .fd = fptr->fd, - .sockaddr = sockaddr, - .len = len + .fd = fptr->fd, + .sockaddr = sockaddr, + .len = len }; int retry = 0, peer; @@ -692,7 +725,7 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) #ifdef RSOCK_WAIT_BEFORE_BLOCKING rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); #endif - peer = (int)BLOCKING_REGION_FD(accept_blocking, &accept_arg); + peer = (int)rb_io_blocking_region(fptr, accept_blocking, &accept_arg); if (peer < 0) { int error = errno; @@ -705,7 +738,7 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) retry = 1; goto retry; default: - if (!rb_io_maybe_wait_readable(error, io, Qnil)) break; + if (!rb_io_maybe_wait_readable(error, io, RUBY_IO_TIMEOUT_DEFAULT)) break; retry = 0; goto retry; } @@ -730,11 +763,11 @@ rsock_getfamily(rb_io_t *fptr) if (cached) { switch (cached) { #ifdef AF_UNIX - case FMODE_UNIX: return AF_UNIX; + case FMODE_UNIX: return AF_UNIX; #endif - case FMODE_INET: return AF_INET; - case FMODE_INET6: return AF_INET6; - } + case FMODE_INET: return AF_INET; + case FMODE_INET6: return AF_INET6; + } } ss.addr.sa_family = AF_UNSPEC; @@ -752,6 +785,28 @@ rsock_getfamily(rb_io_t *fptr) return ss.addr.sa_family; } +/* + * call-seq: + * error_code -> integer + * + * Returns the raw error code indicating the cause of the hostname resolution failure. + * + * begin + * Addrinfo.getaddrinfo("ruby-lang.org", nil) + * rescue Socket::ResolutionError => e + * if e.error_code == Socket::EAI_AGAIN + * puts "Temporary failure in name resolution." + * end + * end + * + * Note that error codes depend on the operating system. + */ +static VALUE +sock_resolv_error_code(VALUE self) +{ + return rb_attr_get(self, id_error_code); +} + void rsock_init_socket_init(void) { @@ -759,6 +814,11 @@ rsock_init_socket_init(void) * SocketError is the error class for socket. */ rb_eSocket = rb_define_class("SocketError", rb_eStandardError); + /* + * Socket::ResolutionError is the error class for hostname resolution. + */ + rb_eResolution = rb_define_class_under(rb_cSocket, "ResolutionError", rb_eSocket); + rb_define_method(rb_eResolution, "error_code", sock_resolv_error_code, 0); rsock_init_ipsocket(); rsock_init_tcpsocket(); rsock_init_tcpserver(); @@ -772,6 +832,8 @@ rsock_init_socket_init(void) rsock_init_sockifaddr(); rsock_init_socket_constants(); + id_error_code = rb_intern_const("error_code"); + #undef rb_intern sym_wait_readable = ID2SYM(rb_intern("wait_readable")); diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index b5cdc60080..931a1a629c 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -9,76 +9,103 @@ ************************************************/ #include "rubysocket.h" +#include <stdio.h> struct inetsock_arg { - VALUE sock; + VALUE self; + VALUE io; + struct { - VALUE host, serv; - struct rb_addrinfo *res; + VALUE host, serv; + struct rb_addrinfo *res; } remote, local; int type; - int fd; VALUE resolv_timeout; VALUE connect_timeout; + VALUE open_timeout; }; +void +rsock_raise_user_specified_timeout(struct addrinfo *ai, VALUE host, VALUE port) +{ + VALUE message; + + if (ai && ai->ai_addr) { + VALUE rai = rsock_addrinfo_new((struct sockaddr *)ai->ai_addr, (socklen_t)ai->ai_addrlen, PF_UNSPEC, 0, 0, Qnil, Qnil); + VALUE addr_str = rsock_addrinfo_inspect_sockaddr(rai); + message = rb_sprintf("user specified timeout for %" PRIsVALUE, addr_str); + } else { + message = rb_sprintf("user specified timeout for %" PRIsVALUE " port %" PRIsVALUE, host, port); + } + + rb_raise(rb_eIOTimeoutError, "%" PRIsVALUE, message); +} + static VALUE inetsock_cleanup(VALUE v) { struct inetsock_arg *arg = (void *)v; if (arg->remote.res) { - rb_freeaddrinfo(arg->remote.res); - arg->remote.res = 0; + rb_freeaddrinfo(arg->remote.res); + arg->remote.res = 0; } if (arg->local.res) { - rb_freeaddrinfo(arg->local.res); - arg->local.res = 0; + rb_freeaddrinfo(arg->local.res); + arg->local.res = 0; } - if (arg->fd >= 0) { - close(arg->fd); + if (arg->io != Qnil) { + rb_io_close(arg->io); + arg->io = Qnil; } return Qnil; } static VALUE +current_clocktime(void) +{ + VALUE clock_monotnic_const = rb_const_get(rb_mProcess, rb_intern("CLOCK_MONOTONIC")); + return rb_funcall(rb_mProcess, rb_intern("clock_gettime"), 1, clock_monotnic_const); +} + +static VALUE init_inetsock_internal(VALUE v) { struct inetsock_arg *arg = (void *)v; int error = 0; int type = arg->type; struct addrinfo *res, *lres; - int fd, status = 0, local = 0; + int status = 0, local = 0; int family = AF_UNSPEC; const char *syscall = 0; + VALUE resolv_timeout = arg->resolv_timeout; VALUE connect_timeout = arg->connect_timeout; - struct timeval tv_storage; - struct timeval *tv = NULL; + VALUE open_timeout = arg->open_timeout; + VALUE timeout; + VALUE starts_at; - if (!NIL_P(connect_timeout)) { - tv_storage = rb_time_interval(connect_timeout); - tv = &tv_storage; - } + timeout = NIL_P(open_timeout) ? resolv_timeout : open_timeout; + starts_at = current_clocktime(); arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, - family, SOCK_STREAM, - (type == INET_SERVER) ? AI_PASSIVE : 0); - + family, SOCK_STREAM, + (type == INET_SERVER) ? AI_PASSIVE : 0, timeout); /* * Maybe also accept a local address */ if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { - arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, - family, SOCK_STREAM, 0); + arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, + family, SOCK_STREAM, 0, timeout); } - arg->fd = fd = -1; + VALUE io = Qnil; + for (res = arg->remote.res->ai; res; res = res->ai_next) { #if !defined(INET6) && defined(AF_INET6) - if (res->ai_family == AF_INET6) - continue; + if (res->ai_family == AF_INET6) + continue; #endif lres = NULL; if (arg->local.res) { @@ -94,86 +121,1299 @@ init_inetsock_internal(VALUE v) lres = arg->local.res->ai; } } - status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); - syscall = "socket(2)"; - fd = status; - if (fd < 0) { - error = errno; - continue; - } - arg->fd = fd; - if (type == INET_SERVER) { + status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); + syscall = "socket(2)"; + if (status < 0) { + error = errno; + continue; + } + + int fd = status; + io = arg->io = rsock_init_sock(arg->self, fd); + + if (type == INET_SERVER) { #if !defined(_WIN32) && !defined(__CYGWIN__) - status = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char*)&status, (socklen_t)sizeof(status)); + status = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char*)&status, (socklen_t)sizeof(status)); #endif - status = bind(fd, res->ai_addr, res->ai_addrlen); - syscall = "bind(2)"; - } - else { - if (lres) { + status = bind(fd, res->ai_addr, res->ai_addrlen); + syscall = "bind(2)"; + } + else { + if (lres) { #if !defined(_WIN32) && !defined(__CYGWIN__) status = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&status, (socklen_t)sizeof(status)); #endif - status = bind(fd, lres->ai_addr, lres->ai_addrlen); - local = status; - syscall = "bind(2)"; - } - - if (status >= 0) { - status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, - (type == INET_SOCKS), tv); - syscall = "connect(2)"; - } - } - - if (status < 0) { - error = errno; - close(fd); - arg->fd = fd = -1; - continue; - } else - break; + status = bind(fd, lres->ai_addr, lres->ai_addrlen); + local = status; + syscall = "bind(2)"; + } + + if (NIL_P(open_timeout)) { + timeout = connect_timeout; + } else { + VALUE elapsed = rb_funcall(current_clocktime(), '-', 1, starts_at); + timeout = rb_funcall(open_timeout, '-', 1, elapsed); + if (rb_funcall(timeout, '<', 1, INT2FIX(0)) == Qtrue) { + rsock_raise_user_specified_timeout(res, arg->remote.host, arg->remote.serv); + } + } + + if (status >= 0) { + status = rsock_connect(io, res->ai_addr, res->ai_addrlen, (type == INET_SOCKS), timeout); + syscall = "connect(2)"; + } + } + + if (status < 0) { + error = errno; + arg->io = Qnil; + rb_io_close(io); + io = Qnil; + continue; + } else { + break; + } } + if (status < 0) { - VALUE host, port; + VALUE host, port; - if (local < 0) { - host = arg->local.host; - port = arg->local.serv; - } else { - host = arg->remote.host; - port = arg->remote.serv; - } + if (local < 0) { + host = arg->local.host; + port = arg->local.serv; + } else { + host = arg->remote.host; + port = arg->remote.serv; + } - rsock_syserr_fail_host_port(error, syscall, host, port); + rsock_syserr_fail_host_port(error, syscall, host, port); } - arg->fd = -1; + // Don't close the socket in `inetsock_cleanup` if we are returning it: + arg->io = Qnil; - if (type == INET_SERVER) { - status = listen(fd, SOMAXCONN); - if (status < 0) { - error = errno; - close(fd); - rb_syserr_fail(error, "listen(2)"); - } + if (type == INET_SERVER && io != Qnil) { + status = listen(rb_io_descriptor(io), SOMAXCONN); + if (status < 0) { + error = errno; + rb_io_close(io); + rb_syserr_fail(error, "listen(2)"); + } } /* create new instance */ - return rsock_init_sock(arg->sock, fd); + return io; +} + +#if FAST_FALLBACK_INIT_INETSOCK_IMPL == 0 + +VALUE +rsock_init_inetsock( + VALUE self, VALUE remote_host, VALUE remote_serv, + VALUE local_host, VALUE local_serv, int type, + VALUE resolv_timeout, VALUE connect_timeout, VALUE open_timeout, + VALUE _fast_fallback, VALUE _test_mode_settings) +{ + if (!NIL_P(open_timeout) && (!NIL_P(resolv_timeout) || !NIL_P(connect_timeout))) { + rb_raise(rb_eArgError, "Cannot specify open_timeout along with connect_timeout or resolv_timeout"); + } + + struct inetsock_arg arg; + arg.self = self; + arg.io = Qnil; + arg.remote.host = remote_host; + arg.remote.serv = remote_serv; + arg.remote.res = 0; + arg.local.host = local_host; + arg.local.serv = local_serv; + arg.local.res = 0; + arg.type = type; + arg.resolv_timeout = resolv_timeout; + arg.connect_timeout = connect_timeout; + arg.open_timeout = open_timeout; + return rb_ensure(init_inetsock_internal, (VALUE)&arg, + inetsock_cleanup, (VALUE)&arg); +} + +#elif FAST_FALLBACK_INIT_INETSOCK_IMPL == 1 + +#define IPV6_ENTRY_POS 0 +#define IPV4_ENTRY_POS 1 +#define RESOLUTION_ERROR 0 +#define SYSCALL_ERROR 1 + +static int +is_specified_ip_address(const char *hostname) +{ + if (!hostname) return false; + + struct in_addr ipv4addr; + struct in6_addr ipv6addr; + + return (inet_pton(AF_INET6, hostname, &ipv6addr) == 1 || + inet_pton(AF_INET, hostname, &ipv4addr) == 1); +} + +static int +is_local_port_fixed(const char *portp) +{ + if (!portp) return 0; + + char *endp; + errno = 0; + long port = strtol(portp, &endp, 10); + + if (endp == portp) return 0; + if (errno == ERANGE) return 0; + + return port > 0; +} + +struct fast_fallback_inetsock_arg +{ + VALUE self; + VALUE io; + + struct { + VALUE host, serv; + struct rb_addrinfo *res; + } remote, local; + int type; + VALUE resolv_timeout; + VALUE connect_timeout; + VALUE open_timeout; + + const char *hostp, *portp; + int *families; + int family_size; + int additional_flags; + struct fast_fallback_getaddrinfo_entry *getaddrinfo_entries[2]; + struct fast_fallback_getaddrinfo_shared *getaddrinfo_shared; + rb_fdset_t readfds, writefds; + int wait; + int connection_attempt_fds_size; + int *connection_attempt_fds; + VALUE test_mode_settings; +}; + +static struct fast_fallback_getaddrinfo_shared * +allocate_fast_fallback_getaddrinfo_shared(int family_size) +{ + struct fast_fallback_getaddrinfo_shared *shared; + + shared = (struct fast_fallback_getaddrinfo_shared *)calloc( + 1, + sizeof(struct fast_fallback_getaddrinfo_shared) + (family_size == 1 ? 0 : 2) * sizeof(struct fast_fallback_getaddrinfo_entry) + ); + + return shared; +} + +static void +allocate_fast_fallback_getaddrinfo_hints(struct addrinfo *hints, int family, int remote_addrinfo_hints, int additional_flags) +{ + MEMZERO(hints, struct addrinfo, 1); + hints->ai_family = family; + hints->ai_socktype = SOCK_STREAM; + hints->ai_protocol = IPPROTO_TCP; + hints->ai_flags = remote_addrinfo_hints; + hints->ai_flags |= additional_flags; +} + +static int* +allocate_connection_attempt_fds(int additional_capacity) +{ + int *fds = (int *)malloc(additional_capacity * sizeof(int)); + if (!fds) rb_syserr_fail(errno, "malloc(3)"); + for (int i = 0; i < additional_capacity; i++) fds[i] = -1; + return fds; +} + +static int +reallocate_connection_attempt_fds(int **fds, int current_capacity, int additional_capacity) +{ + int new_capacity = current_capacity + additional_capacity; + int *new_fds; + + new_fds = realloc(*fds, new_capacity * sizeof(int)); + if (new_fds == NULL) { + rb_syserr_fail(errno, "realloc(3)"); + } + *fds = new_fds; + + for (int i = current_capacity; i < new_capacity; i++) (*fds)[i] = -1; + return new_capacity; +} + +struct hostname_resolution_result +{ + struct addrinfo *ai; + int finished; + int has_error; +}; + +struct hostname_resolution_store +{ + struct hostname_resolution_result v6; + struct hostname_resolution_result v4; + int is_all_finished; +}; + +static int +any_addrinfos(struct hostname_resolution_store *resolution_store) +{ + return resolution_store->v6.ai || resolution_store->v4.ai; +} + +static struct timespec +current_clocktime_ts(void) +{ + struct timespec ts; + if ((clock_gettime(CLOCK_MONOTONIC, &ts)) < 0) { + rb_syserr_fail(errno, "clock_gettime(2)"); + } + return ts; +} + +static void +set_timeout_tv(struct timeval *tv, long ms, struct timespec from) +{ + long sec = ms / 1000; + long nsec = (ms % 1000) * 1000000; + long result_sec = from.tv_sec + sec; + long result_nsec = from.tv_nsec + nsec; + + result_sec += result_nsec / 1000000000; + result_nsec = result_nsec % 1000000000; + + tv->tv_sec = result_sec; + tv->tv_usec = (int)(result_nsec / 1000); +} + +static struct timeval +add_ts_to_tv(struct timeval tv, struct timespec ts) +{ + long ts_usec = ts.tv_nsec / 1000; + tv.tv_sec += ts.tv_sec; + tv.tv_usec += ts_usec; + + if (tv.tv_usec >= 1000000) { + tv.tv_sec += tv.tv_usec / 1000000; + tv.tv_usec = tv.tv_usec % 1000000; + } + + return tv; +} + +static VALUE +tv_to_seconds(struct timeval *timeout) { + if (timeout == NULL) return Qnil; + + double seconds = (double)timeout->tv_sec + (double)timeout->tv_usec / 1000000.0; + + return DBL2NUM(seconds); +} + +static int +is_infinity(struct timeval tv) +{ + // { -1, -1 } as infinity + return tv.tv_sec == -1 || tv.tv_usec == -1; +} + +static int +is_timeout_tv(struct timeval *timeout_tv, struct timespec now) { + if (!timeout_tv) return false; + if (timeout_tv->tv_sec == -1 && timeout_tv->tv_usec == -1) return false; + + struct timespec ts; + ts.tv_sec = timeout_tv->tv_sec; + ts.tv_nsec = timeout_tv->tv_usec * 1000; + + if (now.tv_sec > ts.tv_sec) return true; + if (now.tv_sec == ts.tv_sec && now.tv_nsec >= ts.tv_nsec) return true; + return false; +} + +static struct timeval * +select_expires_at( + struct hostname_resolution_store *resolution_store, + struct timeval *resolution_delay, + struct timeval *connection_attempt_delay, + struct timeval *user_specified_resolv_timeout_at, + struct timeval *user_specified_connect_timeout_at, + struct timeval *user_specified_open_timeout_at) +{ + if (any_addrinfos(resolution_store)) { + struct timeval *delay; + delay = resolution_delay ? resolution_delay : connection_attempt_delay; + + if (user_specified_open_timeout_at && + timercmp(user_specified_open_timeout_at, delay, <)) { + return user_specified_open_timeout_at; + } + return delay; + } + + if (user_specified_open_timeout_at) return user_specified_open_timeout_at; + + struct timeval *timeout = NULL; + + if (user_specified_resolv_timeout_at) { + if (is_infinity(*user_specified_resolv_timeout_at)) return NULL; + timeout = user_specified_resolv_timeout_at; + } + + if (user_specified_connect_timeout_at) { + if (is_infinity(*user_specified_connect_timeout_at)) return NULL; + if (!timeout || timercmp(user_specified_connect_timeout_at, timeout, >)) { + return user_specified_connect_timeout_at; + } + } + + return timeout; +} + +static struct timeval +tv_to_timeout(struct timeval *ends_at, struct timespec now) +{ + struct timeval delay; + struct timespec expires_at; + expires_at.tv_sec = ends_at->tv_sec; + expires_at.tv_nsec = ends_at->tv_usec * 1000; + + struct timespec diff; + diff.tv_sec = expires_at.tv_sec - now.tv_sec; + + if (expires_at.tv_nsec >= now.tv_nsec) { + diff.tv_nsec = expires_at.tv_nsec - now.tv_nsec; + } else { + diff.tv_sec -= 1; + diff.tv_nsec = (1000000000 + expires_at.tv_nsec) - now.tv_nsec; + } + + delay.tv_sec = diff.tv_sec; + delay.tv_usec = (int)diff.tv_nsec / 1000; + + return delay; +} + +static struct addrinfo * +pick_addrinfo(struct hostname_resolution_store *resolution_store, int last_family) +{ + int priority_on_v6[2] = { AF_INET6, AF_INET }; + int priority_on_v4[2] = { AF_INET, AF_INET6 }; + int *precedences = last_family == AF_INET6 ? priority_on_v4 : priority_on_v6; + struct addrinfo *selected_ai = NULL; + + for (int i = 0; i < 2; i++) { + if (precedences[i] == AF_INET6) { + selected_ai = resolution_store->v6.ai; + if (selected_ai) { + resolution_store->v6.ai = selected_ai->ai_next; + break; + } + } else { + selected_ai = resolution_store->v4.ai; + if (selected_ai) { + resolution_store->v4.ai = selected_ai->ai_next; + break; + } + } + } + return selected_ai; +} + +static void +socket_nonblock_set(int fd) +{ + int flags = fcntl(fd, F_GETFL); + + if (flags < 0) rb_syserr_fail(errno, "fcntl(2)"); + if ((flags & O_NONBLOCK) != 0) return; + + flags |= O_NONBLOCK; + + if (fcntl(fd, F_SETFL, flags) < 0) rb_syserr_fail(errno, "fcntl(2)"); + return; +} + +static int +in_progress_fds(int fds_size) +{ + return fds_size > 0; +} + +static void +remove_connection_attempt_fd(int *fds, int *fds_size, int removing_fd) +{ + int i, j; + + for (i = 0; i < *fds_size; i++) { + if (fds[i] != removing_fd) continue; + + for (j = i; j < *fds_size - 1; j++) { + fds[j] = fds[j + 1]; + } + + (*fds_size)--; + fds[*fds_size] = -1; + break; + } +} + +struct fast_fallback_error +{ + int type; + int ecode; +}; + +static VALUE +init_fast_fallback_inetsock_internal(VALUE v) +{ + struct fast_fallback_inetsock_arg *arg = (void *)v; + VALUE io = arg->io; + VALUE resolv_timeout = arg->resolv_timeout; + VALUE connect_timeout = arg->connect_timeout; + VALUE open_timeout = arg->open_timeout; + VALUE test_mode_settings = arg->test_mode_settings; + struct addrinfo *remote_ai = NULL, *local_ai = NULL; + int connected_fd = -1, status = 0, local_status = 0; + int remote_addrinfo_hints = 0; + struct fast_fallback_error last_error = { 0, 0 }; + const char *syscall = 0; + VALUE host, serv; + + #ifdef HAVE_CONST_AI_ADDRCONFIG + remote_addrinfo_hints |= AI_ADDRCONFIG; + #endif + + pthread_t threads[arg->family_size]; + char resolved_type[2]; + ssize_t resolved_type_size; + int hostname_resolution_waiter = -1, hostname_resolution_notifier = -1; + int pipefd[2]; + + int nfds = 0; + struct timeval *ends_at = NULL; + struct timeval delay = (struct timeval){ -1, -1 }; + struct timeval *delay_p = NULL; + + struct hostname_resolution_store resolution_store; + resolution_store.is_all_finished = false; + resolution_store.v6.ai = NULL; + resolution_store.v6.finished = false; + resolution_store.v6.has_error = false; + resolution_store.v4.ai = NULL; + resolution_store.v4.finished = false; + resolution_store.v4.has_error = false; + + int last_family = 0; + int additional_capacity = 10; + int current_capacity = additional_capacity; + arg->connection_attempt_fds = allocate_connection_attempt_fds(additional_capacity); + arg->connection_attempt_fds_size = 0; + + struct timeval resolution_delay_storage; + struct timeval *resolution_delay_expires_at = NULL; + struct timeval connection_attempt_delay_strage; + struct timeval *connection_attempt_delay_expires_at = NULL; + struct timeval user_specified_resolv_timeout_storage; + struct timeval *user_specified_resolv_timeout_at = NULL; + struct timeval user_specified_connect_timeout_storage; + struct timeval *user_specified_connect_timeout_at = NULL; + struct timeval user_specified_open_timeout_storage; + struct timeval *user_specified_open_timeout_at = NULL; + struct timespec now = current_clocktime_ts(); + VALUE starts_at = current_clocktime(); + + if (!NIL_P(open_timeout)) { + struct timeval open_timeout_tv = rb_time_interval(open_timeout); + user_specified_open_timeout_storage = add_ts_to_tv(open_timeout_tv, now); + user_specified_open_timeout_at = &user_specified_open_timeout_storage; + } + + /* start of hostname resolution */ + if (arg->family_size == 1) { + arg->wait = -1; + arg->getaddrinfo_shared = NULL; + + int family = arg->families[0]; + VALUE t = NIL_P(open_timeout) ? resolv_timeout : open_timeout; + + arg->remote.res = rsock_addrinfo( + arg->remote.host, + arg->remote.serv, + family, + SOCK_STREAM, + 0, + t + ); + + if (family == AF_INET6) { + resolution_store.v6.ai = arg->remote.res->ai; + resolution_store.v6.finished = true; + resolution_store.v4.finished = true; + } else if (family == AF_INET) { + resolution_store.v4.ai = arg->remote.res->ai; + resolution_store.v4.finished = true; + resolution_store.v6.finished = true; + } + resolution_store.is_all_finished = true; + } else { + if (pipe(pipefd) != 0) rb_syserr_fail(errno, "pipe(2)"); + hostname_resolution_waiter = pipefd[0]; + int waiter_flags = fcntl(hostname_resolution_waiter, F_GETFL, 0); + if (waiter_flags < 0) rb_syserr_fail(errno, "fcntl(2)"); + if ((fcntl(hostname_resolution_waiter, F_SETFL, waiter_flags | O_NONBLOCK)) < 0) { + rb_syserr_fail(errno, "fcntl(2)"); + } + arg->wait = hostname_resolution_waiter; + hostname_resolution_notifier = pipefd[1]; + + arg->getaddrinfo_shared = allocate_fast_fallback_getaddrinfo_shared(arg->family_size); + if (!arg->getaddrinfo_shared) rb_syserr_fail(errno, "calloc(3)"); + + rb_nativethread_lock_initialize(&arg->getaddrinfo_shared->lock); + arg->getaddrinfo_shared->notify = hostname_resolution_notifier; + + arg->getaddrinfo_shared->node = arg->hostp ? ruby_strdup(arg->hostp) : NULL; + arg->getaddrinfo_shared->service = arg->portp ? ruby_strdup(arg->portp) : NULL; + arg->getaddrinfo_shared->refcount = arg->family_size + 1; + + for (int i = 0; i < arg->family_size; i++) { + arg->getaddrinfo_entries[i] = &arg->getaddrinfo_shared->getaddrinfo_entries[i]; + arg->getaddrinfo_entries[i]->shared = arg->getaddrinfo_shared; + + struct addrinfo getaddrinfo_hints[arg->family_size]; + + allocate_fast_fallback_getaddrinfo_hints( + &getaddrinfo_hints[i], + arg->families[i], + remote_addrinfo_hints, + arg->additional_flags + ); + + arg->getaddrinfo_entries[i]->hints = getaddrinfo_hints[i]; + arg->getaddrinfo_entries[i]->ai = NULL; + arg->getaddrinfo_entries[i]->family = arg->families[i]; + arg->getaddrinfo_entries[i]->refcount = 2; + arg->getaddrinfo_entries[i]->has_syserr = false; + arg->getaddrinfo_entries[i]->test_sleep_ms = 0; + arg->getaddrinfo_entries[i]->test_ecode = 0; + + /* for testing HEv2 */ + if (!NIL_P(test_mode_settings) && RB_TYPE_P(test_mode_settings, T_HASH)) { + const char *family_sym = arg->families[i] == AF_INET6 ? "ipv6" : "ipv4"; + + VALUE test_delay_setting = rb_hash_aref(test_mode_settings, ID2SYM(rb_intern("delay"))); + if (!NIL_P(test_delay_setting)) { + VALUE rb_test_delay_ms = rb_hash_aref(test_delay_setting, ID2SYM(rb_intern(family_sym))); + long test_delay_ms = NIL_P(rb_test_delay_ms) ? 0 : rb_test_delay_ms; + arg->getaddrinfo_entries[i]->test_sleep_ms = test_delay_ms; + } + + VALUE test_error_setting = rb_hash_aref(test_mode_settings, ID2SYM(rb_intern("error"))); + if (!NIL_P(test_error_setting)) { + VALUE rb_test_ecode = rb_hash_aref(test_error_setting, ID2SYM(rb_intern(family_sym))); + if (!NIL_P(rb_test_ecode)) { + arg->getaddrinfo_entries[i]->test_ecode = NUM2INT(rb_test_ecode); + } + } + } + + if (raddrinfo_pthread_create(&threads[i], fork_safe_do_fast_fallback_getaddrinfo, arg->getaddrinfo_entries[i]) != 0) { + rsock_raise_resolution_error("getaddrinfo(3)", EAI_AGAIN); + } + } + + if (NIL_P(resolv_timeout)) { + user_specified_resolv_timeout_storage = (struct timeval){ -1, -1 }; + } else { + struct timeval resolv_timeout_tv = rb_time_interval(resolv_timeout); + user_specified_resolv_timeout_storage = add_ts_to_tv(resolv_timeout_tv, now); + } + user_specified_resolv_timeout_at = &user_specified_resolv_timeout_storage; + } + + while (true) { + /* start of connection */ + if (any_addrinfos(&resolution_store) && + !resolution_delay_expires_at && + !connection_attempt_delay_expires_at) { + while ((remote_ai = pick_addrinfo(&resolution_store, last_family))) { + int fd = -1; + + #if !defined(INET6) && defined(AF_INET6) + if (remote_ai->ai_family == AF_INET6) { + if (any_addrinfos(&resolution_store)) continue; + if (!in_progress_fds(arg->connection_attempt_fds_size)) break; + if (resolution_store.is_all_finished) break; + + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + #endif + + local_ai = NULL; + + if (arg->local.res) { + for (local_ai = arg->local.res->ai; local_ai; local_ai = local_ai->ai_next) { + if (local_ai->ai_family == remote_ai->ai_family) break; + } + if (!local_ai) { + if (any_addrinfos(&resolution_store)) continue; + if (in_progress_fds(arg->connection_attempt_fds_size)) break; + if (!resolution_store.is_all_finished) break; + + /* Use a different family local address if no choice, this + * will cause EAFNOSUPPORT. */ + rsock_syserr_fail_host_port(EAFNOSUPPORT, syscall, arg->local.host, arg->local.serv); + } + } + + status = rsock_socket(remote_ai->ai_family, remote_ai->ai_socktype, remote_ai->ai_protocol); + syscall = "socket(2)"; + + if (status < 0) { + last_error.type = SYSCALL_ERROR; + last_error.ecode = errno; + + if (any_addrinfos(&resolution_store)) continue; + if (in_progress_fds(arg->connection_attempt_fds_size)) break; + if (!resolution_store.is_all_finished) break; + + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + + fd = status; + + if (local_ai) { + #if !defined(_WIN32) && !defined(__CYGWIN__) + status = 1; + if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&status, (socklen_t)sizeof(status))) < 0) { + rb_syserr_fail(errno, "setsockopt(2)"); + } + #endif + status = bind(fd, local_ai->ai_addr, local_ai->ai_addrlen); + local_status = status; + syscall = "bind(2)"; + + if (status < 0) { + last_error.type = SYSCALL_ERROR; + last_error.ecode = errno; + close(fd); + + if (any_addrinfos(&resolution_store)) continue; + if (in_progress_fds(arg->connection_attempt_fds_size)) break; + if (!resolution_store.is_all_finished) break; + + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + } + + syscall = "connect(2)"; + + if (any_addrinfos(&resolution_store) || + in_progress_fds(arg->connection_attempt_fds_size) || + !resolution_store.is_all_finished) { + socket_nonblock_set(fd); + status = connect(fd, remote_ai->ai_addr, remote_ai->ai_addrlen); + last_family = remote_ai->ai_family; + } else { + VALUE timeout = Qnil; + + if (!NIL_P(open_timeout)) { + VALUE elapsed = rb_funcall(current_clocktime(), '-', 1, starts_at); + timeout = rb_funcall(open_timeout, '-', 1, elapsed); + + if (rb_funcall(timeout, '<', 1, INT2FIX(0)) == Qtrue) { + rsock_raise_user_specified_timeout(NULL, arg->remote.host, arg->remote.serv); + } + } + if (NIL_P(timeout)) { + if (!NIL_P(connect_timeout)) { + user_specified_connect_timeout_storage = rb_time_interval(connect_timeout); + user_specified_connect_timeout_at = &user_specified_connect_timeout_storage; + } + timeout = + (user_specified_connect_timeout_at && is_infinity(*user_specified_connect_timeout_at)) ? + Qnil : tv_to_seconds(user_specified_connect_timeout_at); + } + + io = arg->io = rsock_init_sock(arg->self, fd); + status = rsock_connect(io, remote_ai->ai_addr, remote_ai->ai_addrlen, 0, timeout); + } + + if (status == 0) { + connected_fd = fd; + break; + } + + if (errno == EINPROGRESS) { + if (current_capacity == arg->connection_attempt_fds_size) { + current_capacity = reallocate_connection_attempt_fds( + &arg->connection_attempt_fds, + current_capacity, + additional_capacity + ); + } + arg->connection_attempt_fds[arg->connection_attempt_fds_size] = fd; + (arg->connection_attempt_fds_size)++; + + set_timeout_tv(&connection_attempt_delay_strage, 250, now); + connection_attempt_delay_expires_at = &connection_attempt_delay_strage; + + if (!any_addrinfos(&resolution_store)) { + if (NIL_P(connect_timeout)) { + user_specified_connect_timeout_storage = (struct timeval){ -1, -1 }; + } else { + struct timeval connect_timeout_tv = rb_time_interval(connect_timeout); + user_specified_connect_timeout_storage = add_ts_to_tv(connect_timeout_tv, now); + } + user_specified_connect_timeout_at = &user_specified_connect_timeout_storage; + } + + break; + } + + last_error.type = SYSCALL_ERROR; + last_error.ecode = errno; + + if (NIL_P(io)) { + close(fd); + } else { + rb_io_close(io); + } + + if (any_addrinfos(&resolution_store)) continue; + if (in_progress_fds(arg->connection_attempt_fds_size)) break; + if (!resolution_store.is_all_finished) break; + + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + } + + if (connected_fd >= 0) break; + + ends_at = select_expires_at( + &resolution_store, + resolution_delay_expires_at, + connection_attempt_delay_expires_at, + user_specified_resolv_timeout_at, + user_specified_connect_timeout_at, + user_specified_open_timeout_at + ); + if (ends_at) { + delay = tv_to_timeout(ends_at, now); + delay_p = &delay; + } else { + if (((resolution_store.v6.finished && !resolution_store.v4.finished) || + (resolution_store.v4.finished && !resolution_store.v6.finished)) && + !any_addrinfos(&resolution_store) && + !in_progress_fds(arg->connection_attempt_fds_size)) { + /* A limited timeout is introduced to prevent select(2) from hanging when it is exclusively + * waiting for name resolution and write(2) failure occurs in a child thread. */ + delay.tv_sec = 0; + delay.tv_usec = 50000; + delay_p = &delay; + } else { + delay_p = NULL; + } + } + + nfds = 0; + rb_fd_zero(&arg->writefds); + if (in_progress_fds(arg->connection_attempt_fds_size)) { + int n = 0; + for (int i = 0; i < arg->connection_attempt_fds_size; i++) { + int cfd = arg->connection_attempt_fds[i]; + if (cfd < 0) continue; + if (cfd > n) n = cfd; + rb_fd_set(cfd, &arg->writefds); + } + if (n > 0) n++; + nfds = n; + } + + rb_fd_zero(&arg->readfds); + if (arg->family_size > 1) { + rb_fd_set(hostname_resolution_waiter, &arg->readfds); + + if ((hostname_resolution_waiter + 1) > nfds) { + nfds = hostname_resolution_waiter + 1; + } + } + + status = rb_thread_fd_select(nfds, &arg->readfds, &arg->writefds, NULL, delay_p); + + now = current_clocktime_ts(); + if (is_timeout_tv(resolution_delay_expires_at, now)) { + resolution_delay_expires_at = NULL; + } + if (is_timeout_tv(connection_attempt_delay_expires_at, now)) { + connection_attempt_delay_expires_at = NULL; + } + + if (status < 0 && (errno && errno != EINTR)) rb_syserr_fail(errno, "select(2)"); + + if (status > 0) { + /* check for connection */ + if (in_progress_fds(arg->connection_attempt_fds_size)) { + for (int i = 0; i < arg->connection_attempt_fds_size; i++) { + int fd = arg->connection_attempt_fds[i]; + if (fd < 0 || !rb_fd_isset(fd, &arg->writefds)) continue; + + int err; + socklen_t len = sizeof(err); + + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len); + + if (status < 0) { + last_error.type = SYSCALL_ERROR; + last_error.ecode = errno; + close(fd); + + if (any_addrinfos(&resolution_store)) continue; + if (in_progress_fds(arg->connection_attempt_fds_size)) break; + if (!resolution_store.is_all_finished) break; + + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + + if (err == 0) { /* success */ + remove_connection_attempt_fd( + arg->connection_attempt_fds, + &arg->connection_attempt_fds_size, + fd + ); + connected_fd = fd; + break; + } else { /* fail */ + close(fd); + remove_connection_attempt_fd( + arg->connection_attempt_fds, + &arg->connection_attempt_fds_size, + fd + ); + last_error.type = SYSCALL_ERROR; + last_error.ecode = err; + } + } + + if (connected_fd >= 0) break; + + if (!in_progress_fds(arg->connection_attempt_fds_size)) { + if (!any_addrinfos(&resolution_store) && resolution_store.is_all_finished) { + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + connection_attempt_delay_expires_at = NULL; + user_specified_connect_timeout_at = NULL; + } + } + + /* check for hostname resolution */ + if (!resolution_store.is_all_finished && rb_fd_isset(hostname_resolution_waiter, &arg->readfds)) { + while (true) { + resolved_type_size = read( + hostname_resolution_waiter, + resolved_type, + sizeof(resolved_type) - 1 + ); + + if (resolved_type_size > 0) { + resolved_type[resolved_type_size] = '\0'; + + if (resolved_type[0] == IPV6_HOSTNAME_RESOLVED) { + resolution_store.v6.finished = true; + + if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err && + arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err != EAI_ADDRFAMILY) { + if (!resolution_store.v4.finished || resolution_store.v4.has_error) { + last_error.type = RESOLUTION_ERROR; + last_error.ecode = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err; + syscall = "getaddrinfo(3)"; + } + resolution_store.v6.has_error = true; + } else { + resolution_store.v6.ai = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->ai; + } + if (resolution_store.v4.finished) { + resolution_store.is_all_finished = true; + resolution_delay_expires_at = NULL; + user_specified_resolv_timeout_at = NULL; + break; + } + } else if (resolved_type[0] == IPV4_HOSTNAME_RESOLVED) { + resolution_store.v4.finished = true; + + if (arg->getaddrinfo_entries[IPV4_ENTRY_POS]->err) { + if (!resolution_store.v6.finished || resolution_store.v6.has_error) { + last_error.type = RESOLUTION_ERROR; + last_error.ecode = arg->getaddrinfo_entries[IPV4_ENTRY_POS]->err; + syscall = "getaddrinfo(3)"; + } + resolution_store.v4.has_error = true; + } else { + resolution_store.v4.ai = arg->getaddrinfo_entries[IPV4_ENTRY_POS]->ai; + } + + if (resolution_store.v6.finished) { + resolution_store.is_all_finished = true; + resolution_delay_expires_at = NULL; + user_specified_resolv_timeout_at = NULL; + break; + } + } else { + /* Retry to read from hostname_resolution_waiter */ + } + } else if (resolved_type_size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + errno = 0; + break; + } else { + /* Retry to read from hostname_resolution_waiter */ + } + + if (!resolution_store.v6.finished && + resolution_store.v4.finished && + !resolution_store.v4.has_error) { + set_timeout_tv(&resolution_delay_storage, 50, now); + resolution_delay_expires_at = &resolution_delay_storage; + } + } + } + + status = 0; + } + + /* For cases where write(2) fails in child threads */ + if (!resolution_store.is_all_finished) { + if (!resolution_store.v6.finished && arg->getaddrinfo_entries[IPV6_ENTRY_POS]->has_syserr) { + resolution_store.v6.finished = true; + + if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err) { + if (!resolution_store.v4.finished || resolution_store.v4.has_error) { + last_error.type = RESOLUTION_ERROR; + last_error.ecode = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err; + syscall = "getaddrinfo(3)"; + } + resolution_store.v6.has_error = true; + } else { + resolution_store.v6.ai = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->ai; + } + + if (resolution_store.v4.finished) { + resolution_store.is_all_finished = true; + resolution_delay_expires_at = NULL; + user_specified_resolv_timeout_at = NULL; + } + } + if (!resolution_store.v4.finished && arg->getaddrinfo_entries[IPV4_ENTRY_POS]->has_syserr) { + resolution_store.v4.finished = true; + + if (arg->getaddrinfo_entries[IPV4_ENTRY_POS]->err) { + if (!resolution_store.v6.finished || resolution_store.v6.has_error) { + last_error.type = RESOLUTION_ERROR; + last_error.ecode = arg->getaddrinfo_entries[IPV4_ENTRY_POS]->err; + syscall = "getaddrinfo(3)"; + } + resolution_store.v4.has_error = true; + } else { + resolution_store.v4.ai = arg->getaddrinfo_entries[IPV4_ENTRY_POS]->ai; + } + + if (resolution_store.v6.finished) { + resolution_store.is_all_finished = true; + resolution_delay_expires_at = NULL; + user_specified_resolv_timeout_at = NULL; + } else { + set_timeout_tv(&resolution_delay_storage, 50, now); + resolution_delay_expires_at = &resolution_delay_storage; + } + } + } + + if (is_timeout_tv(user_specified_open_timeout_at, now)) { + rsock_raise_user_specified_timeout(NULL, arg->remote.host, arg->remote.serv); + } + + if (!any_addrinfos(&resolution_store)) { + if (!in_progress_fds(arg->connection_attempt_fds_size) && + resolution_store.is_all_finished) { + if (local_status < 0) { + host = arg->local.host; + serv = arg->local.serv; + } else { + host = arg->remote.host; + serv = arg->remote.serv; + } + if (last_error.type == RESOLUTION_ERROR) { + rsock_raise_resolution_error(syscall, last_error.ecode); + } else { + rsock_syserr_fail_host_port(last_error.ecode, syscall, host, serv); + } + } + + if ((is_timeout_tv(user_specified_resolv_timeout_at, now) || + resolution_store.is_all_finished) && + (is_timeout_tv(user_specified_connect_timeout_at, now) || + !in_progress_fds(arg->connection_attempt_fds_size))) { + rsock_raise_user_specified_timeout(NULL, arg->remote.host, arg->remote.serv); + } + } + } + + if (NIL_P(arg->io)) { + /* create new instance */ + arg->io = rsock_init_sock(arg->self, connected_fd); + } + + return arg->io; +} + +static VALUE +fast_fallback_inetsock_cleanup(VALUE v) +{ + struct fast_fallback_inetsock_arg *arg = (void *)v; + struct fast_fallback_getaddrinfo_shared *getaddrinfo_shared = arg->getaddrinfo_shared; + + if (arg->remote.res) { + rb_freeaddrinfo(arg->remote.res); + arg->remote.res = 0; + } + if (arg->local.res) { + rb_freeaddrinfo(arg->local.res); + arg->local.res = 0; + } + + if (arg->wait != -1) close(arg->wait); + + if (getaddrinfo_shared) { + if (getaddrinfo_shared->notify != -1) close(getaddrinfo_shared->notify); + getaddrinfo_shared->notify = -1; + + int shared_need_free = 0; + struct addrinfo *ais[arg->family_size]; + for (int i = 0; i < arg->family_size; i++) ais[i] = NULL; + + rb_nativethread_lock_lock(&getaddrinfo_shared->lock); + { + for (int i = 0; i < arg->family_size; i++) { + struct fast_fallback_getaddrinfo_entry *getaddrinfo_entry = arg->getaddrinfo_entries[i]; + + if (!getaddrinfo_entry) continue; + + if (--(getaddrinfo_entry->refcount) == 0) { + ais[i] = getaddrinfo_entry->ai; + getaddrinfo_entry->ai = NULL; + } + } + if (--(getaddrinfo_shared->refcount) == 0) { + shared_need_free = 1; + } + } + rb_nativethread_lock_unlock(&getaddrinfo_shared->lock); + + for (int i = 0; i < arg->family_size; i++) { + if (ais[i]) freeaddrinfo(ais[i]); + } + if (getaddrinfo_shared && shared_need_free) { + free_fast_fallback_getaddrinfo_shared(&getaddrinfo_shared); + } + } + + int connection_attempt_fd; + + for (int i = 0; i < arg->connection_attempt_fds_size; i++) { + connection_attempt_fd = arg->connection_attempt_fds[i]; + + if (connection_attempt_fd >= 0) { + int error = 0; + socklen_t len = sizeof(error); + getsockopt(connection_attempt_fd, SOL_SOCKET, SO_ERROR, &error, &len); + if (error == 0) shutdown(connection_attempt_fd, SHUT_RDWR); + close(connection_attempt_fd); + } + } + + if (arg->readfds.fdset) rb_fd_term(&arg->readfds); + if (arg->writefds.fdset) rb_fd_term(&arg->writefds); + + if (arg->connection_attempt_fds) { + free(arg->connection_attempt_fds); + arg->connection_attempt_fds = NULL; + } + + return Qnil; } VALUE -rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, - VALUE local_host, VALUE local_serv, int type, - VALUE resolv_timeout, VALUE connect_timeout) +rsock_init_inetsock( + VALUE self, VALUE remote_host, VALUE remote_serv, + VALUE local_host, VALUE local_serv, int type, + VALUE resolv_timeout, VALUE connect_timeout, VALUE open_timeout, + VALUE fast_fallback, VALUE test_mode_settings) { + if (!NIL_P(open_timeout) && (!NIL_P(resolv_timeout) || !NIL_P(connect_timeout))) { + rb_raise(rb_eArgError, "Cannot specify open_timeout along with connect_timeout or resolv_timeout"); + } + + if (type == INET_CLIENT && FAST_FALLBACK_INIT_INETSOCK_IMPL == 1 && RTEST(fast_fallback)) { + struct rb_addrinfo *local_res = NULL; + char *hostp, *portp, *local_portp; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV], local_pbuf[NI_MAXSERV]; + int additional_flags = 0; + int local_flags = 0; + hostp = raddrinfo_host_str(remote_host, hbuf, sizeof(hbuf), &additional_flags); + portp = raddrinfo_port_str(remote_serv, pbuf, sizeof(pbuf), &additional_flags); + local_portp = raddrinfo_port_str(local_serv, local_pbuf, sizeof(local_pbuf), &local_flags); + + if (!is_specified_ip_address(hostp) && !is_local_port_fixed(local_portp)) { + int target_families[2] = { 0, 0 }; + int resolving_family_size = 0; + + /* + * Maybe also accept a local address + */ + if (!NIL_P(local_host) || !NIL_P(local_serv)) { + VALUE t = NIL_P(open_timeout) ? resolv_timeout : open_timeout; + local_res = rsock_addrinfo( + local_host, + local_serv, + AF_UNSPEC, + SOCK_STREAM, + 0, + t + ); + + struct addrinfo *tmp_p = local_res->ai; + for (; tmp_p != NULL; tmp_p = tmp_p->ai_next) { + if (target_families[0] == 0 && tmp_p->ai_family == AF_INET6) { + target_families[0] = AF_INET6; + resolving_family_size++; + } + if (target_families[1] == 0 && tmp_p->ai_family == AF_INET) { + target_families[1] = AF_INET; + resolving_family_size++; + } + } + } else { + resolving_family_size = 2; + target_families[0] = AF_INET6; + target_families[1] = AF_INET; + } + + struct fast_fallback_inetsock_arg fast_fallback_arg; + memset(&fast_fallback_arg, 0, sizeof(fast_fallback_arg)); + + fast_fallback_arg.self = self; + fast_fallback_arg.io = Qnil; + fast_fallback_arg.remote.host = remote_host; + fast_fallback_arg.remote.serv = remote_serv; + fast_fallback_arg.remote.res = 0; + fast_fallback_arg.local.host = local_host; + fast_fallback_arg.local.serv = local_serv; + fast_fallback_arg.local.res = local_res; + fast_fallback_arg.type = type; + fast_fallback_arg.resolv_timeout = resolv_timeout; + fast_fallback_arg.connect_timeout = connect_timeout; + fast_fallback_arg.open_timeout = open_timeout; + fast_fallback_arg.hostp = hostp; + fast_fallback_arg.portp = portp; + fast_fallback_arg.additional_flags = additional_flags; + + int resolving_families[resolving_family_size]; + int resolving_family_index = 0; + for (int i = 0; 2 > i; i++) { + if (target_families[i] != 0) { + resolving_families[resolving_family_index] = target_families[i]; + resolving_family_index++; + } + } + fast_fallback_arg.families = resolving_families; + fast_fallback_arg.family_size = resolving_family_size; + fast_fallback_arg.test_mode_settings = test_mode_settings; + + rb_fd_init(&fast_fallback_arg.readfds); + rb_fd_init(&fast_fallback_arg.writefds); + + return rb_ensure(init_fast_fallback_inetsock_internal, (VALUE)&fast_fallback_arg, + fast_fallback_inetsock_cleanup, (VALUE)&fast_fallback_arg); + } + } + struct inetsock_arg arg; - arg.sock = sock; + arg.self = self; + arg.io = Qnil; arg.remote.host = remote_host; arg.remote.serv = remote_serv; arg.remote.res = 0; @@ -181,13 +1421,16 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, arg.local.serv = local_serv; arg.local.res = 0; arg.type = type; - arg.fd = -1; arg.resolv_timeout = resolv_timeout; arg.connect_timeout = connect_timeout; + arg.open_timeout = open_timeout; + return rb_ensure(init_inetsock_internal, (VALUE)&arg, - inetsock_cleanup, (VALUE)&arg); + inetsock_cleanup, (VALUE)&arg); } +#endif + static ID id_numeric, id_hostname; int @@ -201,11 +1444,11 @@ rsock_revlookup_flag(VALUE revlookup, int *norevlookup) case Qfalse: return_norevlookup(1); case Qnil: break; default: - Check_Type(revlookup, T_SYMBOL); - id = SYM2ID(revlookup); - if (id == id_numeric) return_norevlookup(1); - if (id == id_hostname) return_norevlookup(0); - rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id)); + Check_Type(revlookup, T_SYMBOL); + id = SYM2ID(revlookup); + if (id == id_numeric) return_norevlookup(1); + if (id == id_hostname) return_norevlookup(0); + rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id)); } return 0; #undef return_norevlookup @@ -226,24 +1469,24 @@ ip_inspect(VALUE sock) socklen_t len = (socklen_t)sizeof addr; ID id; if (fptr && fptr->fd >= 0 && - getsockname(fptr->fd, &addr.addr, &len) >= 0 && - (id = rsock_intern_family(addr.addr.sa_family)) != 0) { - VALUE family = rb_id2str(id); - char hbuf[1024], pbuf[1024]; - long slen = RSTRING_LEN(str); - const char last = (slen > 1 && RSTRING_PTR(str)[slen - 1] == '>') ? - (--slen, '>') : 0; - str = rb_str_subseq(str, 0, slen); - rb_str_cat_cstr(str, ", "); - rb_str_append(str, family); - if (!rb_getnameinfo(&addr.addr, len, hbuf, sizeof(hbuf), - pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { - rb_str_cat_cstr(str, ", "); - rb_str_cat_cstr(str, hbuf); - rb_str_cat_cstr(str, ", "); - rb_str_cat_cstr(str, pbuf); - } - if (last) rb_str_cat(str, &last, 1); + getsockname(fptr->fd, &addr.addr, &len) >= 0 && + (id = rsock_intern_family(addr.addr.sa_family)) != 0) { + VALUE family = rb_id2str(id); + char hbuf[1024], pbuf[1024]; + long slen = RSTRING_LEN(str); + const char last = (slen > 1 && RSTRING_PTR(str)[slen - 1] == '>') ? + (--slen, '>') : 0; + str = rb_str_subseq(str, 0, slen); + rb_str_cat_cstr(str, ", "); + rb_str_append(str, family); + if (!rb_getnameinfo(&addr.addr, len, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + rb_str_cat_cstr(str, ", "); + rb_str_cat_cstr(str, hbuf); + rb_str_cat_cstr(str, ", "); + rb_str_cat_cstr(str, pbuf); + } + if (last) rb_str_cat(str, &last, 1); } return str; } @@ -274,17 +1517,14 @@ ip_inspect(VALUE sock) static VALUE ip_addr(int argc, VALUE *argv, VALUE sock) { - rb_io_t *fptr; union_sockaddr addr; socklen_t len = (socklen_t)sizeof addr; int norevlookup; - GetOpenFile(sock, fptr); - if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; - if (getsockname(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + norevlookup = rb_io_mode(sock) & FMODE_NOREVLOOKUP; + if (getsockname(rb_io_descriptor(sock), &addr.addr, &len) < 0) + rb_sys_fail("getsockname(2)"); return rsock_ipaddr(&addr.addr, len, norevlookup); } @@ -315,17 +1555,14 @@ ip_addr(int argc, VALUE *argv, VALUE sock) static VALUE ip_peeraddr(int argc, VALUE *argv, VALUE sock) { - rb_io_t *fptr; union_sockaddr addr; socklen_t len = (socklen_t)sizeof addr; int norevlookup; - GetOpenFile(sock, fptr); - if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; - if (getpeername(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + norevlookup = rb_io_mode(sock) & FMODE_NOREVLOOKUP; + if (getpeername(rb_io_descriptor(sock), &addr.addr, &len) < 0) + rb_sys_fail("getpeername(2)"); return rsock_ipaddr(&addr.addr, len, norevlookup); } @@ -372,7 +1609,7 @@ static VALUE ip_s_getaddress(VALUE obj, VALUE host) { union_sockaddr addr; - struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, 0, Qnil); socklen_t len = res->ai->ai_addrlen; /* just take the first one */ diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index d756a32a5a..36fcceaee9 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -1,7 +1,11 @@ # frozen_string_literal: true require 'socket.so' -require 'io/wait' + +unless IO.method_defined?(:wait_writable, false) + # It's only required on older Rubies < v3.2: + require 'io/wait' +end class Addrinfo # creates an Addrinfo object from the arguments. @@ -58,7 +62,7 @@ class Addrinfo break when :wait_writable sock.wait_writable(timeout) or - raise Errno::ETIMEDOUT, 'user specified timeout' + raise Errno::ETIMEDOUT, "user specified timeout for #{self.ip_address}:#{self.ip_port}" end while true else sock.connect(self) @@ -197,7 +201,7 @@ class Addrinfo sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? - sock.setsockopt(:SOCKET, :REUSEADDR, 1) + sock.setsockopt(:SOCKET, :REUSEADDR, 1) unless self.pfamily == Socket::PF_UNIX sock.bind(self) sock.listen(backlog) rescue Exception @@ -329,9 +333,10 @@ class BasicSocket < IO # _flags_ is zero or more of the +MSG_+ options. # The result, _mesg_, is the data received. # - # When recvfrom(2) returns 0, Socket#recv_nonblock returns - # an empty string as data. - # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but for UDP connections + # it may mean an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the number of bytes to receive from the socket @@ -476,9 +481,10 @@ class Socket < BasicSocket # The second element, _sender_addrinfo_, contains protocol-specific address # information of the sender. # - # When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns - # an empty string as data. - # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but for UDP connections + # it may mean an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the maximum number of bytes to receive from the socket @@ -593,20 +599,54 @@ class Socket < BasicSocket __accept_nonblock(exception) end + # :stopdoc: + RESOLUTION_DELAY = 0.05 + private_constant :RESOLUTION_DELAY + + CONNECTION_ATTEMPT_DELAY = 0.25 + private_constant :CONNECTION_ATTEMPT_DELAY + + ADDRESS_FAMILIES = { + ipv6: Socket::AF_INET6, + ipv4: Socket::AF_INET + }.freeze + private_constant :ADDRESS_FAMILIES + + HOSTNAME_RESOLUTION_QUEUE_UPDATED = 0 + private_constant :HOSTNAME_RESOLUTION_QUEUE_UPDATED + + IPV6_ADDRESS_FORMAT = /\A(?i:(?:(?:[0-9A-F]{1,4}:){7}(?:[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){6}(?:[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,5}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){5}(?:(?::[0-9A-F]{1,4}){1,2}|:(?:[0-9A-F]{1,4}:){1,4}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){4}(?:(?::[0-9A-F]{1,4}){1,3}|:(?:[0-9A-F]{1,4}:){1,3}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){3}(?:(?::[0-9A-F]{1,4}){1,4}|:(?:[0-9A-F]{1,4}:){1,2}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){2}(?:(?::[0-9A-F]{1,4}){1,5}|:(?:[0-9A-F]{1,4}:)[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){1}(?:(?::[0-9A-F]{1,4}){1,6}|:(?:[0-9A-F]{1,4}:){0,5}[0-9A-F]{1,4}|:)|(?:::(?:[0-9A-F]{1,4}:){0,7}[0-9A-F]{1,4}|::)))(?:%.+)?\z/ + private_constant :IPV6_ADDRESS_FORMAT + # :startdoc: + # :call-seq: # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) {|socket| ... } # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) # # creates a new socket object connected to host:port using TCP/IP. # + # Starting from Ruby 3.4, this method operates according to the + # Happy Eyeballs Version 2 ({RFC 8305}[https://datatracker.ietf.org/doc/html/rfc8305]) + # algorithm by default. + # + # For details on Happy Eyeballs Version 2, + # see {Socket.tcp_fast_fallback=}[rdoc-ref:Socket.tcp_fast_fallback=]. + # + # To make it behave the same as in Ruby 3.3 and earlier, + # explicitly specify the option fast_fallback:false. + # Or, setting Socket.tcp_fast_fallback=false will disable + # Happy Eyeballs Version 2 not only for this method but for all Socket globally. + # # If local_host:local_port is given, # the socket is bound to it. # # The optional last argument _opts_ is options represented by a hash. # _opts_ may have following options: # - # [:connect_timeout] specify the timeout in seconds. - # [:resolv_timeout] specify the name resolution timeout in seconds. + # [:resolv_timeout] Specifies the timeout in seconds from when the hostname resolution starts. + # [:connect_timeout] This method sequentially attempts connecting to all candidate destination addresses.<br>The +connect_timeout+ specifies the timeout in seconds from the start of the connection attempt to the last candidate.<br>By default, all connection attempts continue until the timeout occurs.<br>When +fast_fallback:false+ is explicitly specified,<br>a timeout is set for each connection attempt and any connection attempt that exceeds its timeout will be canceled. + # [:open_timeout] Specifies the timeout in seconds from the start of the method execution.<br>If this timeout is reached while there are still addresses that have not yet been attempted for connection, no further attempts will be made.<br>If this option is specified together with other timeout options, an +ArgumentError+ will be raised. + # [:fast_fallback] Enables the Happy Eyeballs Version 2 algorithm (enabled by default). # # If a block is given, the block is called with the socket. # The value of the block is returned. @@ -619,17 +659,296 @@ class Socket < BasicSocket # sock.close_write # puts sock.read # } - # - def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil) # :yield: socket + def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil, open_timeout: nil, fast_fallback: tcp_fast_fallback, &) # :yield: socket + if open_timeout && (connect_timeout || resolv_timeout) + raise ArgumentError, "Cannot specify open_timeout along with connect_timeout or resolv_timeout" + end + + sock = if fast_fallback && !(host && ip_address?(host)) && !(local_port && local_port.to_i != 0) + tcp_with_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, open_timeout:) + else + tcp_without_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, open_timeout:) + end + + if block_given? + begin + yield sock + ensure + sock.close + end + else + sock + end + end + + # :stopdoc: + def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil, open_timeout: nil) + if local_host || local_port + local_addrinfos = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, timeout: open_timeout || resolv_timeout) + resolving_family_names = local_addrinfos.map { |lai| ADDRESS_FAMILIES.key(lai.afamily) }.uniq + else + local_addrinfos = [] + resolving_family_names = ADDRESS_FAMILIES.keys + end + + hostname_resolution_threads = [] + resolution_store = HostnameResolutionStore.new(resolving_family_names) + connecting_sockets = {} + is_windows_environment ||= (RUBY_PLATFORM =~ /mswin|mingw|cygwin/) + + now = current_clock_time + starts_at = now + resolution_delay_expires_at = nil + connection_attempt_delay_expires_at = nil + user_specified_connect_timeout_at = nil + user_specified_open_timeout_at = open_timeout ? now + open_timeout : nil + last_error = nil + last_error_from_thread = false + + if resolving_family_names.size == 1 + family_name = resolving_family_names.first + addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[:family_name], :STREAM, timeout: open_timeout || resolv_timeout) + resolution_store.add_resolved(family_name, addrinfos) + hostname_resolution_result = nil + hostname_resolution_notifier = nil + user_specified_resolv_timeout_at = nil + else + hostname_resolution_result = HostnameResolutionResult.new(resolving_family_names.size) + hostname_resolution_notifier = hostname_resolution_result.notifier + + hostname_resolution_threads.concat( + resolving_family_names.map { |family| + thread_args = [family, host, port, hostname_resolution_result] + thread = Thread.new(*thread_args) { |*thread_args| resolve_hostname(*thread_args) } + Thread.pass + thread + } + ) + user_specified_resolv_timeout_at = resolv_timeout ? now + resolv_timeout : Float::INFINITY + end + + loop do + if resolution_store.any_addrinfos? && + !resolution_delay_expires_at && + !connection_attempt_delay_expires_at + while (addrinfo = resolution_store.get_addrinfo) + if local_addrinfos.any? + local_addrinfo = local_addrinfos.find { |lai| lai.afamily == addrinfo.afamily } + + if local_addrinfo.nil? + if resolution_store.any_addrinfos? + # Try other Addrinfo in next "while" + next + elsif connecting_sockets.any? || resolution_store.any_unresolved_family? + # Exit this "while" and wait for connections to be established or hostname resolution in next loop + # Or exit this "while" and wait for hostname resolution in next loop + break + else + raise SocketError.new 'no appropriate local address' + end + end + end + + begin + if resolution_store.any_addrinfos? || + connecting_sockets.any? || + resolution_store.any_unresolved_family? + socket = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) + socket.bind(local_addrinfo) if local_addrinfo + result = socket.connect_nonblock(addrinfo, exception: false) + else + timeout = + if open_timeout + t = open_timeout - (current_clock_time - starts_at) + t.negative? ? 0 : t + else + connect_timeout + end + result = socket = local_addrinfo ? + addrinfo.connect_from(local_addrinfo, timeout:) : + addrinfo.connect(timeout:) + end + + if result == :wait_writable + connection_attempt_delay_expires_at = now + CONNECTION_ATTEMPT_DELAY + if resolution_store.empty_addrinfos? + user_specified_connect_timeout_at = connect_timeout ? now + connect_timeout : Float::INFINITY + end + + connecting_sockets[socket] = addrinfo + break + else + return socket # connection established + end + rescue SystemCallError => e + socket&.close + last_error = e + + if resolution_store.any_addrinfos? + # Try other Addrinfo in next "while" + next + elsif connecting_sockets.any? || resolution_store.any_unresolved_family? + # Exit this "while" and wait for connections to be established or hostname resolution in next loop + # Or exit this "while" and wait for hostname resolution in next loop + break + else + raise last_error + end + end + end + end + + ends_at = + if resolution_store.any_addrinfos? + [(resolution_delay_expires_at || connection_attempt_delay_expires_at), + user_specified_open_timeout_at].compact.min + elsif user_specified_open_timeout_at + user_specified_open_timeout_at + else + [user_specified_resolv_timeout_at, user_specified_connect_timeout_at].compact.max + end + + hostname_resolved, writable_sockets, except_sockets = IO.select( + hostname_resolution_notifier, + connecting_sockets.keys, + # Use errorfds to wait for non-blocking connect failures on Windows + is_windows_environment ? connecting_sockets.keys : nil, + second_to_timeout(current_clock_time, ends_at), + ) + now = current_clock_time + resolution_delay_expires_at = nil if expired?(now, resolution_delay_expires_at) + connection_attempt_delay_expires_at = nil if expired?(now, connection_attempt_delay_expires_at) + + if writable_sockets&.any? + while (writable_socket = writable_sockets.pop) + is_connected = is_windows_environment || ( + sockopt = writable_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) + sockopt.int.zero? + ) + + if is_connected + connecting_sockets.delete writable_socket + return writable_socket + else + failed_ai = connecting_sockets.delete writable_socket + writable_socket.close + ip_address = failed_ai.ipv6? ? "[#{failed_ai.ip_address}]" : failed_ai.ip_address + last_error = SystemCallError.new("connect(2) for #{ip_address}:#{failed_ai.ip_port}", sockopt.int) + + if writable_sockets.any? || connecting_sockets.any? + # Try other writable socket in next "while" + # Or exit this "while" and wait for connections to be established or hostname resolution in next loop + elsif resolution_store.any_addrinfos? || resolution_store.any_unresolved_family? + # Exit this "while" and try other connection attempt + # Or exit this "while" and wait for hostname resolution in next loop + connection_attempt_delay_expires_at = nil + user_specified_connect_timeout_at = nil + else + raise last_error + end + end + end + end + + if except_sockets&.any? + except_sockets.each do |except_socket| + failed_ai = connecting_sockets.delete except_socket + sockopt = except_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) + except_socket.close + ip_address = failed_ai.ipv6? ? "[#{failed_ai.ip_address}]" : failed_ai.ip_address + last_error = SystemCallError.new("connect(2) for #{ip_address}:#{failed_ai.ip_port}", sockopt.int) + + if except_sockets.any? || connecting_sockets.any? + # Cleanup other except socket in next "each" + # Or exit this "while" and wait for connections to be established or hostname resolution in next loop + elsif resolution_store.any_addrinfos? || resolution_store.any_unresolved_family? + # Exit this "while" and try other connection attempt + # Or exit this "while" and wait for hostname resolution in next loop + connection_attempt_delay_expires_at = nil + user_specified_connect_timeout_at = nil + else + raise last_error + end + end + end + + if hostname_resolved&.any? + while (family_and_result = hostname_resolution_result.get) + family_name, result = family_and_result + + if result.is_a? Exception + resolution_store.add_error(family_name, result) + + unless (Socket.const_defined?(:EAI_ADDRFAMILY)) && + (result.is_a?(Socket::ResolutionError)) && + (result.error_code == Socket::EAI_ADDRFAMILY) + other = family_name == :ipv6 ? :ipv4 : :ipv6 + if !resolution_store.resolved?(other) || !resolution_store.resolved_successfully?(other) + last_error = result + last_error_from_thread = true + end + end + else + resolution_store.add_resolved(family_name, result) + end + end + + if resolution_store.resolved?(:ipv4) + if resolution_store.resolved?(:ipv6) + hostname_resolution_notifier = nil + resolution_delay_expires_at = nil + user_specified_resolv_timeout_at = nil + elsif resolution_store.resolved_successfully?(:ipv4) + resolution_delay_expires_at = now + RESOLUTION_DELAY + end + end + end + + if expired?(now, user_specified_open_timeout_at) + raise(IO::TimeoutError, "user specified timeout for #{host}:#{port}") + end + + if resolution_store.empty_addrinfos? + if connecting_sockets.empty? && resolution_store.resolved_all_families? + if last_error_from_thread + raise last_error.class, last_error.message, cause: last_error + else + raise last_error + end + end + + if (expired?(now, user_specified_resolv_timeout_at) || resolution_store.resolved_all_families?) && + (expired?(now, user_specified_connect_timeout_at) || connecting_sockets.empty?) + raise(IO::TimeoutError, "user specified timeout for #{host}:#{port}") + end + end + end + ensure + hostname_resolution_threads.each do |thread| + thread.exit + end + + hostname_resolution_result&.close + + connecting_sockets.each_key do |connecting_socket| + connecting_socket.close + end + end + private_class_method :tcp_with_fast_fallback + + def self.tcp_without_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, open_timeout:) last_error = nil ret = nil local_addr_list = nil if local_host != nil || local_port != nil - local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil) + local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil, timeout: open_timeout || resolv_timeout) end - Addrinfo.foreach(host, port, nil, :STREAM, timeout: resolv_timeout) {|ai| + timeout = open_timeout ? open_timeout : resolv_timeout + starts_at = current_clock_time + + Addrinfo.foreach(host, port, nil, :STREAM, timeout:) {|ai| if local_addr_list local_addr = local_addr_list.find {|local_ai| local_ai.afamily == ai.afamily } next unless local_addr @@ -637,9 +956,17 @@ class Socket < BasicSocket local_addr = nil end begin + timeout = + if open_timeout + t = open_timeout - (current_clock_time - starts_at) + t.negative? ? 0 : t + else + connect_timeout + end + sock = local_addr ? - ai.connect_from(local_addr, timeout: connect_timeout) : - ai.connect(timeout: connect_timeout) + ai.connect_from(local_addr, timeout:) : + ai.connect(timeout:) rescue SystemCallError last_error = $! next @@ -654,18 +981,150 @@ class Socket < BasicSocket raise SocketError, "no appropriate local address" end end - if block_given? - begin - yield ret - ensure - ret.close + + ret + end + private_class_method :tcp_without_fast_fallback + + def self.ip_address?(hostname) + hostname.match?(IPV6_ADDRESS_FORMAT) || hostname.match?(/\A([0-9]{1,3}\.){3}[0-9]{1,3}\z/) + end + private_class_method :ip_address? + + def self.resolve_hostname(family, host, port, hostname_resolution_result) + begin + resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) + hostname_resolution_result.add(family, resolved_addrinfos) + rescue => e + hostname_resolution_result.add(family, e) + end + end + private_class_method :resolve_hostname + + def self.current_clock_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + private_class_method :current_clock_time + + def self.second_to_timeout(started_at, ends_at) + return nil if ends_at == Float::INFINITY || ends_at.nil? + + remaining = (ends_at - started_at) + remaining.negative? ? 0 : remaining + end + private_class_method :second_to_timeout + + def self.expired?(started_at, ends_at) + second_to_timeout(started_at, ends_at)&.zero? + end + private_class_method :expired? + + class HostnameResolutionResult + def initialize(size) + @size = size + @taken_count = 0 + @rpipe, @wpipe = IO.pipe + @results = [] + @mutex = Mutex.new + end + + def notifier + [@rpipe] + end + + def add(family, result) + @mutex.synchronize do + @results.push [family, result] + @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED end - else - ret + end + + def get + return nil if @results.empty? + + res = nil + + @mutex.synchronize do + @rpipe.getbyte + res = @results.shift + end + + @taken_count += 1 + close if @taken_count == @size + res + end + + def close + @rpipe.close + @wpipe.close end end + private_constant :HostnameResolutionResult + + class HostnameResolutionStore + PRIORITY_ON_V6 = [:ipv6, :ipv4].freeze + PRIORITY_ON_V4 = [:ipv4, :ipv6].freeze + + def initialize(family_names) + @family_names = family_names + @addrinfo_dict = {} + @error_dict = {} + @last_family = nil + end + + def add_resolved(family_name, addrinfos) + @addrinfo_dict[family_name] = addrinfos + end + + def add_error(family_name, error) + @addrinfo_dict[family_name] = [] + @error_dict[family_name] = error + end + + def get_addrinfo + precedences = + case @last_family + when :ipv4, nil then PRIORITY_ON_V6 + when :ipv6 then PRIORITY_ON_V4 + end + + precedences.each do |family_name| + addrinfo = @addrinfo_dict[family_name]&.shift + next unless addrinfo + + @last_family = family_name + return addrinfo + end + + nil + end + + def empty_addrinfos? + @addrinfo_dict.all? { |_, addrinfos| addrinfos.empty? } + end + + def any_addrinfos? + !empty_addrinfos? + end + + def resolved?(family) + @addrinfo_dict.has_key? family + end + + def resolved_successfully?(family) + resolved?(family) && !@error_dict[family] + end + + def resolved_all_families? + (@family_names - @addrinfo_dict.keys).empty? + end + + def any_unresolved_family? + !resolved_all_families? + end + end + private_constant :HostnameResolutionStore - # :stopdoc: def self.ip_sockets_port0(ai_list, reuseaddr) sockets = [] begin @@ -698,9 +1157,7 @@ class Socket < BasicSocket end sockets end - class << self - private :ip_sockets_port0 - end + private_class_method :ip_sockets_port0 def self.tcp_server_sockets_port0(host) ai_list = Addrinfo.getaddrinfo(host, 0, nil, :STREAM, nil, Socket::AI_PASSIVE) @@ -1128,13 +1585,18 @@ class Socket < BasicSocket end end - class << self - private - - def unix_socket_abstract_name?(path) - /linux/ =~ RUBY_PLATFORM && /\A(\0|\z)/ =~ path + # :stopdoc: + if RUBY_PLATFORM.include?("linux") + def self.unix_socket_abstract_name?(path) + path.empty? or path.start_with?("\0") + end + else + def self.unix_socket_abstract_name?(path) + false end end + private_class_method :unix_socket_abstract_name? + # :startdoc: # creates a UNIX socket server on _path_. # It calls the block for each socket accepted. @@ -1174,7 +1636,7 @@ class Socket < BasicSocket # Returns 0 if successful, otherwise an exception is raised. # # === Parameter - # # +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object + # * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object # # === Example: # # Pull down Google's web page @@ -1209,7 +1671,7 @@ class Socket < BasicSocket # return the symbol +:wait_writable+ instead. # # === See - # # Socket#connect + # * Socket#connect def connect_nonblock(addr, exception: true) __connect_nonblock(addr, exception) end @@ -1226,9 +1688,10 @@ class UDPSocket < IPSocket # The first element of the results, _mesg_, is the data received. # The second element, _sender_inet_addr_, is an array to represent the sender address. # - # When recvfrom(2) returns 0, - # Socket#recvfrom_nonblock returns an empty string as data. - # It means an empty packet. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but it may also mean + # an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the number of bytes to receive from the socket diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb index 577958a358..4271e40cd8 100644 --- a/ext/socket/mkconstants.rb +++ b/ext/socket/mkconstants.rb @@ -51,7 +51,10 @@ DATA.each_line {|s| next end h[name] = default_value - COMMENTS[name] = comment + if comment + # Stop unintentional references + COMMENTS[name] = comment.gsub(/\b(Data|Kernel|Process|Set|Socket|Time)\b/, '\\\\\\&') + end } DEFS = h.to_a @@ -73,15 +76,11 @@ def each_name(pat) } end -erb_new = lambda do |src, safe, trim| - if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - ERB.new(src, trim_mode: trim) - else - ERB.new(src, safe, trim) - end +erb_new = lambda do |src, trim| + ERB.new(src, trim_mode: trim) end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_decls") % each_const {|guard, name, default_value| #if !defined(<%=name%>) # if defined(HAVE_CONST_<%=name.upcase%>) @@ -95,7 +94,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)") #if defined(<%=name%>) /* <%= COMMENTS[name] %> */ rb_define_const(rb_cSocket, <%=c_str name%>, INTEGER2NUM(<%=name%>)); @@ -104,7 +103,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name #endif EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs") % each_const {|guard, name, default_value| % if guard #if <%=guard%> @@ -154,7 +153,7 @@ def each_names_with_len(pat, prefix_optional=nil) } end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)") %if guard #ifdef <%=guard%> int <%=funcname%>(const char *str, long len, int *valp); @@ -164,7 +163,7 @@ int <%=funcname%>(const char *str, long len, int *valp); %end EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)") int <%=funcname%>(const char *str, long len, int *valp) { @@ -186,7 +185,7 @@ int } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)") %if guard #ifdef <%=guard%> <%=gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard)%> @@ -215,7 +214,7 @@ def reverse_each_name_with_prefix_optional(pat, prefix_pat) end end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)") <%=hash_var%> = st_init_numtable(); % reverse_each_name_with_prefix_optional(pat, prefix_pat) {|n,s| #ifdef <%=n%> @@ -224,7 +223,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_va % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") ID <%=func_name%>(int val) { @@ -235,7 +234,7 @@ ID } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") ID <%=func_name%>(int val); EOS @@ -284,7 +283,7 @@ def_intern('rsock_intern_udp_optname', /\AUDP_/, "UDP_") def_intern('rsock_intern_scm_optname', /\ASCM_/, "SCM_") def_intern('rsock_intern_local_optname', /\ALOCAL_/, "LOCAL_") -result = erb_new.call(<<'EOS', nil, '%').result(binding) +result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %> @@ -327,7 +326,7 @@ init_constants(void) EOS -header_result = erb_new.call(<<'EOS', nil, '%').result(binding) +header_result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= gen_const_decls %> <%= NAME_TO_INT_DEFS.map {|decl, func| decl }.join("\n") %> @@ -423,8 +422,8 @@ AF_ISDN nil Integrated Services Digital Network PF_ISDN nil Integrated Services Digital Network AF_NATM nil Native ATM access PF_NATM nil Native ATM access -AF_SYSTEM -PF_SYSTEM +AF_SYSTEM nil Kernel event messages +PF_SYSTEM nil Kernel event messages AF_NETBIOS nil NetBIOS PF_NETBIOS nil NetBIOS AF_PPP nil Point-to-Point Protocol @@ -440,8 +439,8 @@ PF_PACKET nil Direct link-layer access AF_E164 nil CCITT (ITU-T) E.164 recommendation PF_XTP nil eXpress Transfer Protocol -PF_RTIP -PF_PIP +PF_RTIP nil Help Identify RTIP packets +PF_PIP nil Help Identify PIP packets AF_KEY nil Key management protocol, originally developed for usage with IPsec PF_KEY nil Key management protocol, originally developed for usage with IPsec AF_NETLINK nil Kernel user interface device @@ -626,6 +625,7 @@ SO_SNDTIMEO nil Send timeout SO_ACCEPTCONN nil Socket has had listen() called on it SO_USELOOPBACK nil Bypass hardware when possible SO_ACCEPTFILTER nil There is an accept filter +SO_USER_COOKIE nil Setting an identifier for ipfw purpose mainly SO_DONTTRUNC nil Retain unread data SO_WANTMORE nil Give a hint when more data is ready SO_WANTOOBFLAG nil OOB data is wanted in MSG_FLAG on receive @@ -661,6 +661,11 @@ SO_SELECT_ERR_QUEUE nil Make select() detect socket error queue with err SO_BUSY_POLL nil Set the threshold in microseconds for low latency polling (Linux 3.11) SO_MAX_PACING_RATE nil Cap the rate computed by transport layer. [bytes per second] (Linux 3.13) SO_BPF_EXTENSIONS nil Query supported BPF extensions (Linux 3.14) +SO_SETFIB nil Set the associated routing table for the socket (FreeBSD) +SO_RTABLE nil Set the routing table for this socket (OpenBSD) +SO_INCOMING_CPU nil Receive the cpu attached to the socket (Linux 3.19) +SO_INCOMING_NAPI_ID nil Receive the napi ID attached to a RX queue (Linux 4.12) +SO_CONNECT_TIME nil Returns the number of seconds a socket has been connected. This option is only valid for connection-oriented protocols (Windows) SOPRI_INTERACTIVE nil Interactive socket priority SOPRI_NORMAL nil Normal socket priority @@ -670,9 +675,11 @@ IPX_TYPE TCP_NODELAY nil Don't delay sending to coalesce packets TCP_MAXSEG nil Set maximum segment size +TCP_CONNECTION_INFO nil Retrieve information about this socket (macOS) TCP_CORK nil Don't send partial frames (Linux 2.2, glibc 2.2) TCP_DEFER_ACCEPT nil Don't notify a listening socket until data is ready (Linux 2.4, glibc 2.2) TCP_INFO nil Retrieve information about this socket (Linux 2.4, glibc 2.2) +TCP_KEEPALIVE nil Idle time before keepalive probes are sent (macOS) TCP_KEEPCNT nil Maximum number of keepalive probes allowed before dropping a connection (Linux 2.4, glibc 2.2) TCP_KEEPIDLE nil Idle time before keepalive probes are sent (Linux 2.4, glibc 2.2) TCP_KEEPINTVL nil Time between keepalive probes (Linux 2.4, glibc 2.2) @@ -738,6 +745,7 @@ SHUT_RDWR 2 Shut down the both sides of the socket IPV6_JOIN_GROUP nil Join a group membership IPV6_LEAVE_GROUP nil Leave a group membership +IPV6_MTU_DISCOVER nil Path MTU discovery IPV6_MULTICAST_HOPS nil IP6 multicast hops IPV6_MULTICAST_IF nil IP6 multicast interface IPV6_MULTICAST_LOOP nil IP6 multicast loopback @@ -752,6 +760,7 @@ IPV6_NEXTHOP nil Next hop address IPV6_PATHMTU nil Retrieve current path MTU IPV6_PKTINFO nil Receive packet information with datagram IPV6_RECVDSTOPTS nil Receive all IP6 options for response +IPV6_RECVERR nil Enable extended reliable error message passing IPV6_RECVHOPLIMIT nil Receive hop limit with datagram IPV6_RECVHOPOPTS nil Receive hop-by-hop options IPV6_RECVPKTINFO nil Receive destination IP address and incoming interface diff --git a/ext/socket/option.c b/ext/socket/option.c index 4b33b3f1d3..0d818d0c70 100644 --- a/ext/socket/option.c +++ b/ext/socket/option.c @@ -31,7 +31,7 @@ VALUE rb_cSockOpt; ((len) == (size) ? \ (void)0 : \ rb_raise(rb_eTypeError, "size differ. expected as "#size"=%d but %ld", \ - (int)size, (long)(len))) + (int)size, (long)(len))) static VALUE sockopt_pack_byte(VALUE value) @@ -309,7 +309,7 @@ sockopt_bool(VALUE self) StringValue(data); len = RSTRING_LEN(data); if (len == 1) { - return *RSTRING_PTR(data) == 0 ? Qfalse : Qtrue; + return *RSTRING_PTR(data) == 0 ? Qfalse : Qtrue; } check_size(len, sizeof(int)); memcpy((char*)&i, RSTRING_PTR(data), len); @@ -420,7 +420,7 @@ sockopt_ipv4_multicast_loop(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) { - return XCAT(sockopt_,TYPE_IP_MULTICAST_LOOP)(self); + return XCAT(sockopt_,TYPE_IP_MULTICAST_LOOP)(self); } #endif rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected"); @@ -471,7 +471,7 @@ sockopt_ipv4_multicast_ttl(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) { - return XCAT(sockopt_,TYPE_IP_MULTICAST_TTL)(self); + return XCAT(sockopt_,TYPE_IP_MULTICAST_TTL)(self); } #endif rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected"); @@ -657,8 +657,8 @@ inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len) #else unsigned long x = ntohl(*(unsigned long*)addr); snprintf(numaddr, numaddr_len, "%d.%d.%d.%d", - (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, - (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff); + (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, + (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff); #endif return numaddr; } @@ -670,10 +670,10 @@ rb_if_indextoname(const char *succ_prefix, const char *fail_prefix, unsigned int { #if defined(HAVE_IF_INDEXTONAME) char ifbuf[IFNAMSIZ]; - if (if_indextoname(ifindex, ifbuf) == NULL) - return snprintf(buf, len, "%s%u", fail_prefix, ifindex); - else + if (if_indextoname(ifindex, ifbuf)) return snprintf(buf, len, "%s%s", succ_prefix, ifbuf); + else + return snprintf(buf, len, "%s%u", fail_prefix, ifindex); #else # ifndef IFNAMSIZ # define IFNAMSIZ (sizeof(unsigned int)*3+1) @@ -1059,16 +1059,16 @@ inspect_tcp_info(int level, int optname, VALUE data, VALUE ret) rb_str_catf(ret, " fackets=%u", s.tcpi_fackets); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_DATA_SENT - inspect_tcpi_last_data_sent(ret, s.tcpi_last_data_sent); + inspect_tcpi_last_data_sent(ret, s.tcpi_last_data_sent); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_ACK_SENT - inspect_tcpi_last_ack_sent(ret, s.tcpi_last_ack_sent); + inspect_tcpi_last_ack_sent(ret, s.tcpi_last_ack_sent); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_DATA_RECV - inspect_tcpi_last_data_recv(ret, s.tcpi_last_data_recv); + inspect_tcpi_last_data_recv(ret, s.tcpi_last_data_recv); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_ACK_RECV - inspect_tcpi_last_ack_recv(ret, s.tcpi_last_ack_recv); + inspect_tcpi_last_ack_recv(ret, s.tcpi_last_ack_recv); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_PMTU rb_str_catf(ret, " pmtu=%u", s.tcpi_pmtu); @@ -1077,10 +1077,10 @@ inspect_tcp_info(int level, int optname, VALUE data, VALUE ret) rb_str_catf(ret, " rcv_ssthresh=%u", s.tcpi_rcv_ssthresh); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_RTT - inspect_tcpi_rtt(ret, s.tcpi_rtt); + inspect_tcpi_rtt(ret, s.tcpi_rtt); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_RTTVAR - inspect_tcpi_rttvar(ret, s.tcpi_rttvar); + inspect_tcpi_rttvar(ret, s.tcpi_rttvar); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_SND_SSTHRESH rb_str_catf(ret, " snd_ssthresh=%u", s.tcpi_snd_ssthresh); @@ -1150,7 +1150,7 @@ inspect_peercred(int level, int optname, VALUE data, VALUE ret) RUBY_SOCK_PEERCRED cred; memcpy(&cred, RSTRING_PTR(data), sizeof(RUBY_SOCK_PEERCRED)); rb_str_catf(ret, " pid=%u euid=%u egid=%u", - (unsigned)cred.pid, (unsigned)cred.uid, (unsigned)cred.gid); + (unsigned)cred.pid, (unsigned)cred.uid, (unsigned)cred.gid); rb_str_cat2(ret, " (ucred)"); return 1; } @@ -1171,14 +1171,14 @@ inspect_local_peercred(int level, int optname, VALUE data, VALUE ret) return 0; rb_str_catf(ret, " version=%u", cred.cr_version); rb_str_catf(ret, " euid=%u", cred.cr_uid); - if (cred.cr_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred.cr_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]); - sep = ","; - } - } + if (cred.cr_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred.cr_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]); + sep = ","; + } + } rb_str_cat2(ret, " (xucred)"); return 1; } @@ -1216,42 +1216,42 @@ sockopt_inspect(VALUE self) family_id = rsock_intern_family_noprefix(family); if (family_id) - rb_str_catf(ret, " %s", rb_id2name(family_id)); + rb_str_catf(ret, " %s", rb_id2name(family_id)); else rb_str_catf(ret, " family:%d", family); if (level == SOL_SOCKET) { rb_str_cat2(ret, " SOCKET"); - optname_id = rsock_intern_so_optname(optname); - if (optname_id) - rb_str_catf(ret, " %s", rb_id2name(optname_id)); - else - rb_str_catf(ret, " optname:%d", optname); + optname_id = rsock_intern_so_optname(optname); + if (optname_id) + rb_str_catf(ret, " %s", rb_id2name(optname_id)); + else + rb_str_catf(ret, " optname:%d", optname); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN else if (family == AF_UNIX) { - rb_str_catf(ret, " level:%d", level); + rb_str_catf(ret, " level:%d", level); - optname_id = rsock_intern_local_optname(optname); - if (optname_id) - rb_str_catf(ret, " %s", rb_id2name(optname_id)); - else - rb_str_catf(ret, " optname:%d", optname); + optname_id = rsock_intern_local_optname(optname); + if (optname_id) + rb_str_catf(ret, " %s", rb_id2name(optname_id)); + else + rb_str_catf(ret, " optname:%d", optname); } #endif else if (IS_IP_FAMILY(family)) { - level_id = rsock_intern_iplevel(level); - if (level_id) - rb_str_catf(ret, " %s", rb_id2name(level_id)); - else - rb_str_catf(ret, " level:%d", level); - - v = optname_to_sym(level, optname); - if (SYMBOL_P(v)) - rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v)); - else - rb_str_catf(ret, " optname:%d", optname); + level_id = rsock_intern_iplevel(level); + if (level_id) + rb_str_catf(ret, " %s", rb_id2name(level_id)); + else + rb_str_catf(ret, " level:%d", level); + + v = optname_to_sym(level, optname); + if (SYMBOL_P(v)) + rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v)); + else + rb_str_catf(ret, " optname:%d", optname); } else { rb_str_catf(ret, " level:%d", level); @@ -1393,7 +1393,7 @@ sockopt_inspect(VALUE self) } break; -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: switch (level) { case 0: diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index d94e96a2bc..6cdf5c6abc 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -10,6 +10,22 @@ #include "rubysocket.h" +// GETADDRINFO_IMPL == 0 : call getaddrinfo/getnameinfo directly +// GETADDRINFO_IMPL == 1 : call getaddrinfo/getnameinfo without gvl (but uncancellable) +// GETADDRINFO_IMPL == 2 : call getaddrinfo/getnameinfo in a dedicated pthread +// (and if the call is interrupted, the pthread is detached) + +#ifndef GETADDRINFO_IMPL +# ifdef GETADDRINFO_EMU +# define GETADDRINFO_IMPL 0 +# elif !defined(HAVE_PTHREAD_CREATE) || !defined(HAVE_PTHREAD_DETACH) || defined(__MINGW32__) || defined(__MINGW64__) +# define GETADDRINFO_IMPL 1 +# else +# define GETADDRINFO_IMPL 2 +# include "ruby/thread_native.h" +# endif +#endif + #if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6)) #define LOOKUP_ORDERS (sizeof(lookup_order_table) / sizeof(lookup_order_table[0])) static const int lookup_order_table[] = { @@ -24,28 +40,28 @@ static const int lookup_order_table[] = { static int ruby_getaddrinfo(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo tmp_hints; int i, af, error; if (hints->ai_family != PF_UNSPEC) { - return getaddrinfo(nodename, servname, hints, res); + return getaddrinfo(nodename, servname, hints, res); } for (i = 0; i < LOOKUP_ORDERS; i++) { - af = lookup_order_table[i]; - MEMCPY(&tmp_hints, hints, struct addrinfo, 1); - tmp_hints.ai_family = af; - error = getaddrinfo(nodename, servname, &tmp_hints, res); - if (error) { - if (tmp_hints.ai_family == PF_UNSPEC) { - break; - } - } - else { - break; - } + af = lookup_order_table[i]; + MEMCPY(&tmp_hints, hints, struct addrinfo, 1); + tmp_hints.ai_family = af; + error = getaddrinfo(nodename, servname, &tmp_hints, res); + if (error) { + if (tmp_hints.ai_family == PF_UNSPEC) { + break; + } + } + else { + break; + } } return error; @@ -56,17 +72,17 @@ ruby_getaddrinfo(const char *nodename, const char *servname, #if defined(_AIX) static int ruby_getaddrinfo__aix(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { int error = getaddrinfo(nodename, servname, hints, res); struct addrinfo *r; if (error) - return error; + return error; for (r = *res; r != NULL; r = r->ai_next) { - if (r->ai_addr->sa_family == 0) - r->ai_addr->sa_family = r->ai_family; - if (r->ai_addr->sa_len == 0) - r->ai_addr->sa_len = r->ai_addrlen; + if (r->ai_addr->sa_family == 0) + r->ai_addr->sa_family = r->ai_family; + if (r->ai_addr->sa_len == 0) + r->ai_addr->sa_len = r->ai_addrlen; } return 0; } @@ -74,21 +90,21 @@ ruby_getaddrinfo__aix(const char *nodename, const char *servname, #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res)) static int ruby_getnameinfo__aix(const struct sockaddr *sa, size_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags) + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) { struct sockaddr_in6 *sa6; u_int32_t *a6; if (sa->sa_family == AF_INET6) { - sa6 = (struct sockaddr_in6 *)sa; - a6 = sa6->sin6_addr.u6_addr.u6_addr32; + sa6 = (struct sockaddr_in6 *)sa; + a6 = sa6->sin6_addr.u6_addr.u6_addr32; - if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { - strncpy(host, "::", hostlen); - snprintf(serv, servlen, "%d", sa6->sin6_port); - return 0; - } + if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { + strncpy(host, "::", hostlen); + snprintf(serv, servlen, "%d", sa6->sin6_port); + return 0; + } } return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } @@ -102,7 +118,7 @@ static int str_is_number(const char *); #if defined(__APPLE__) static int ruby_getaddrinfo__darwin(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { /* fix [ruby-core:29427] */ const char *tmp_servname; @@ -112,12 +128,12 @@ ruby_getaddrinfo__darwin(const char *nodename, const char *servname, tmp_servname = servname; MEMCPY(&tmp_hints, hints, struct addrinfo, 1); if (nodename && servname) { - if (str_is_number(tmp_servname) && atoi(servname) == 0) { - tmp_servname = NULL; + if (str_is_number(tmp_servname) && atoi(servname) == 0) { + tmp_servname = NULL; #ifdef AI_NUMERICSERV - if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV; + if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV; #endif - } + } } error = getaddrinfo(nodename, tmp_servname, &tmp_hints, res); @@ -173,32 +189,6 @@ parse_numeric_port(const char *service, int *portp) } #endif -#ifndef GETADDRINFO_EMU -struct getaddrinfo_arg -{ - const char *node; - const char *service; - const struct addrinfo *hints; - struct addrinfo **res; -}; - -static void * -nogvl_getaddrinfo(void *arg) -{ - int ret; - struct getaddrinfo_arg *ptr = arg; - ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res); -#ifdef __linux__ - /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and - * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] - */ - if (ret == EAI_SYSTEM && errno == ENOENT) - ret = EAI_NONAME; -#endif - return (void *)(VALUE)ret; -} -#endif - static int numeric_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, @@ -212,15 +202,15 @@ numeric_getaddrinfo(const char *node, const char *service, int port; if (node && parse_numeric_port(service, &port)) { - static const struct { - int socktype; - int protocol; - } list[] = { - { SOCK_STREAM, IPPROTO_TCP }, - { SOCK_DGRAM, IPPROTO_UDP }, - { SOCK_RAW, 0 } - }; - struct addrinfo *ai = NULL; + static const struct { + int socktype; + int protocol; + } list[] = { + { SOCK_STREAM, IPPROTO_TCP }, + { SOCK_DGRAM, IPPROTO_UDP }, + { SOCK_RAW, 0 } + }; + struct addrinfo *ai = NULL; int hint_family = hints ? hints->ai_family : PF_UNSPEC; int hint_socktype = hints ? hints->ai_socktype : 0; int hint_protocol = hints ? hints->ai_protocol : 0; @@ -287,8 +277,9 @@ numeric_getaddrinfo(const char *node, const char *service, void rb_freeaddrinfo(struct rb_addrinfo *ai) { - if (!ai->allocated_by_malloc) - freeaddrinfo(ai->ai); + if (!ai->allocated_by_malloc) { + if (ai->ai) freeaddrinfo(ai->ai); + } else { struct addrinfo *ai1, *ai2; ai1 = ai->ai; @@ -302,7 +293,353 @@ rb_freeaddrinfo(struct rb_addrinfo *ai) xfree(ai); } -#ifndef GETADDRINFO_EMU +static int +rsock_value_timeout_to_msec(VALUE timeout) +{ + double seconds = NUM2DBL(timeout); + if (seconds < 0) rb_raise(rb_eArgError, "timeout must not be negative"); + + double msec = seconds * 1000.0; + if (msec > UINT_MAX) rb_raise(rb_eArgError, "timeout too large"); + + return (unsigned int)(msec + 0.5); +} + +#if GETADDRINFO_IMPL == 0 + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai, int _timeout) +{ + return getaddrinfo(hostp, portp, hints, ai); +} + +#elif GETADDRINFO_IMPL == 1 + +struct getaddrinfo_arg +{ + const char *node; + const char *service; + const struct addrinfo *hints; + struct addrinfo **res; +}; + +static void * +nogvl_getaddrinfo(void *arg) +{ + int ret; + struct getaddrinfo_arg *ptr = arg; + ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res); +#ifdef __linux__ + /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and + * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] + */ + if (ret == EAI_SYSTEM && errno == ENOENT) + ret = EAI_NONAME; +#endif + return (void *)(VALUE)ret; +} + +static void * +fork_safe_getaddrinfo(void *arg) +{ + return rb_thread_prevent_fork(nogvl_getaddrinfo, arg); +} + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai, int _timeout) +{ + struct getaddrinfo_arg arg; + MEMZERO(&arg, struct getaddrinfo_arg, 1); + arg.node = hostp; + arg.service = portp; + arg.hints = hints; + arg.res = ai; + return (int)(VALUE)rb_thread_call_without_gvl(fork_safe_getaddrinfo, &arg, RUBY_UBF_IO, 0); +} + +#elif GETADDRINFO_IMPL == 2 + +struct getaddrinfo_arg +{ + char *node, *service; + struct addrinfo hints; + struct addrinfo *ai; + int err, gai_errno, refcount, done, cancelled, timedout; + rb_nativethread_lock_t lock; + rb_nativethread_cond_t cond; + int timeout; +}; + +static struct getaddrinfo_arg * +allocate_getaddrinfo_arg(const char *hostp, const char *portp, const struct addrinfo *hints, int timeout) +{ + size_t hostp_offset = sizeof(struct getaddrinfo_arg); + size_t portp_offset = hostp_offset + (hostp ? strlen(hostp) + 1 : 0); + size_t bufsize = portp_offset + (portp ? strlen(portp) + 1 : 0); + + char *buf = malloc(bufsize); + if (!buf) { + rb_gc(); + buf = malloc(bufsize); + if (!buf) return NULL; + } + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)buf; + + if (hostp) { + arg->node = buf + hostp_offset; + memcpy(arg->node, hostp, portp_offset - hostp_offset); + } + else { + arg->node = NULL; + } + + if (portp) { + arg->service = buf + portp_offset; + memcpy(arg->service, portp, bufsize - portp_offset); + } + else { + arg->service = NULL; + } + + arg->hints = *hints; + arg->ai = NULL; + + arg->refcount = 2; + arg->done = arg->cancelled = arg->timedout = 0; + arg->timeout = timeout; + + rb_nativethread_lock_initialize(&arg->lock); + rb_native_cond_initialize(&arg->cond); + + return arg; +} + +static void +free_getaddrinfo_arg(struct getaddrinfo_arg *arg) +{ + rb_native_cond_destroy(&arg->cond); + rb_nativethread_lock_destroy(&arg->lock); + free(arg); +} + +static void * +do_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + + int err, gai_errno; + err = getaddrinfo(arg->node, arg->service, &arg->hints, &arg->ai); + gai_errno = errno; +#ifdef __linux__ + /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and + * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] + */ + if (err == EAI_SYSTEM && errno == ENOENT) + err = EAI_NONAME; +#endif + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + { + arg->err = err; + arg->gai_errno = gai_errno; + if (arg->cancelled) { + if (arg->ai) freeaddrinfo(arg->ai); + } + else { + arg->done = 1; + rb_native_cond_signal(&arg->cond); + } + if (--arg->refcount == 0) need_free = 1; + } + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getaddrinfo_arg(arg); + + return 0; +} + +static void * +wait_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + while (!arg->done && !arg->cancelled) { + long msec = arg->timeout; + if (msec == 0) { + arg->cancelled = 1; + arg->timedout = 1; + } else if (msec > 0) { + rb_native_cond_timedwait(&arg->cond, &arg->lock, msec); + if (!arg->done) { + arg->cancelled = 1; + arg->timedout = 1; + } + } else { + rb_native_cond_wait(&arg->cond, &arg->lock); + } + } + rb_nativethread_lock_unlock(&arg->lock); + return 0; +} + +static void +cancel_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + { + arg->cancelled = 1; + rb_native_cond_signal(&arg->cond); + } + rb_nativethread_lock_unlock(&arg->lock); +} + +int +raddrinfo_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg) +{ + int limit = 3, ret; + int saved_errno; +#ifdef HAVE_PTHREAD_ATTR_SETDETACHSTATE + pthread_attr_t attr; + pthread_attr_t *attr_p = &attr; + int err; + int init_retries = 0; + int init_retries_max = 3; +retry_attr_init: + if ((err = pthread_attr_init(attr_p)) != 0) { + if (err == ENOMEM && init_retries < init_retries_max) { + init_retries++; + rb_gc(); + goto retry_attr_init; + } + return err; + } + if ((err = pthread_attr_setdetachstate(attr_p, PTHREAD_CREATE_DETACHED)) != 0) { + saved_errno = errno; + pthread_attr_destroy(attr_p); + errno = saved_errno; + return err; // EINVAL - shouldn't happen + } +#else + pthread_attr_t *attr_p = NULL; +#endif + do { + // It is said that pthread_create may fail spuriously, so we follow the JDK and retry several times. + // + // https://bugs.openjdk.org/browse/JDK-8268605 + // https://github.com/openjdk/jdk/commit/e35005d5ce383ddd108096a3079b17cb0bcf76f1 + ret = pthread_create(th, attr_p, start_routine, arg); + } while (ret == EAGAIN && limit-- > 0); +#ifdef HAVE_PTHREAD_ATTR_SETDETACHSTATE + saved_errno = errno; + pthread_attr_destroy(attr_p); + if (ret != 0) { + errno = saved_errno; + } +#else + if (ret == 0) { + pthread_detach(th); // this can race with shutdown routine of thread in some glibc versions + } +#endif + return ret; +} + +static void * +fork_safe_do_getaddrinfo(void *ptr) +{ + return rb_thread_prevent_fork(do_getaddrinfo, ptr); +} + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai, int timeout) +{ + int retry; + struct getaddrinfo_arg *arg; + int err = 0, gai_errno = 0, timedout = 0; + +start: + retry = 0; + + arg = allocate_getaddrinfo_arg(hostp, portp, hints, timeout); + if (!arg) { + return EAI_MEMORY; + } + + pthread_t th; + if (raddrinfo_pthread_create(&th, fork_safe_do_getaddrinfo, arg) != 0) { + int err = errno; + free_getaddrinfo_arg(arg); + errno = err; + return EAI_SYSTEM; + } + + rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + { + if (arg->done) { + err = arg->err; + gai_errno = arg->gai_errno; + if (err == 0) *ai = arg->ai; + } + else if (arg->cancelled) { + retry = 1; + timedout = arg->timedout; + } + else { + // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getaddrinfo. + // In this case, it could be !arg->done && !arg->cancelled. + arg->cancelled = 1; // to make do_getaddrinfo call freeaddrinfo + retry = 1; + } + if (--arg->refcount == 0) need_free = 1; + } + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getaddrinfo_arg(arg); + + if (timedout) { + if (arg->ai) { + rsock_raise_user_specified_timeout(arg->ai, Qnil, Qnil); + } else { + VALUE host = rb_str_new_cstr(hostp); + VALUE port = rb_str_new_cstr(portp); + rsock_raise_user_specified_timeout(NULL, host, port); + } + } + + // If the current thread is interrupted by asynchronous exception, the following raises the exception. + // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry. + rb_thread_check_ints(); + if (retry) goto start; + + /* Because errno is threadlocal, the errno value we got from the call to getaddrinfo() in the thread + * (in case of EAI_SYSTEM return value) is not propagated to the caller of _this_ function. Set errno + * explicitly, as round-tripped through struct getaddrinfo_arg, to deal with that */ + if (gai_errno) errno = gai_errno; + return err; +} + +#endif + +#define GETNAMEINFO_WONT_BLOCK(host, serv, flags) \ + ((!(host) || ((flags) & NI_NUMERICHOST)) && \ + (!(serv) || ((flags) & NI_NUMERICSERV))) + +#if GETADDRINFO_IMPL == 0 + +int +rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) +{ + return getnameinfo(sa, salen, host, (socklen_t)hostlen, serv, (socklen_t)servlen, flags); +} + +#elif GETADDRINFO_IMPL == 1 + struct getnameinfo_arg { const struct sockaddr *sa; @@ -319,20 +656,19 @@ nogvl_getnameinfo(void *arg) { struct getnameinfo_arg *ptr = arg; return (void *)(VALUE)getnameinfo(ptr->sa, ptr->salen, - ptr->host, (socklen_t)ptr->hostlen, - ptr->serv, (socklen_t)ptr->servlen, - ptr->flags); + ptr->host, (socklen_t)ptr->hostlen, + ptr->serv, (socklen_t)ptr->servlen, + ptr->flags); } -#endif - int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags) + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) { -#ifdef GETADDRINFO_EMU - return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); -#else + if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) { + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); + } + struct getnameinfo_arg arg; int ret; arg.sa = sa; @@ -344,17 +680,190 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, arg.flags = flags; ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0); return ret; -#endif +} + +#elif GETADDRINFO_IMPL == 2 + +struct getnameinfo_arg +{ + struct sockaddr *sa; + socklen_t salen; + int flags; + char *host; + size_t hostlen; + char *serv; + size_t servlen; + int err, gni_errno, refcount, done, cancelled; + rb_nativethread_lock_t lock; + rb_nativethread_cond_t cond; +}; + +static struct getnameinfo_arg * +allocate_getnameinfo_arg(const struct sockaddr *sa, socklen_t salen, size_t hostlen, size_t servlen, int flags) +{ + size_t sa_offset = sizeof(struct getnameinfo_arg); + size_t host_offset = sa_offset + salen; + size_t serv_offset = host_offset + hostlen; + size_t bufsize = serv_offset + servlen; + + char *buf = malloc(bufsize); + if (!buf) { + rb_gc(); + buf = malloc(bufsize); + if (!buf) return NULL; + } + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)buf; + + arg->sa = (struct sockaddr *)(buf + sa_offset); + memcpy(arg->sa, sa, salen); + arg->salen = salen; + arg->host = buf + host_offset; + arg->hostlen = hostlen; + arg->serv = buf + serv_offset; + arg->servlen = servlen; + arg->flags = flags; + + arg->refcount = 2; + arg->done = arg->cancelled = 0; + + rb_nativethread_lock_initialize(&arg->lock); + rb_native_cond_initialize(&arg->cond); + + return arg; } static void +free_getnameinfo_arg(struct getnameinfo_arg *arg) +{ + rb_native_cond_destroy(&arg->cond); + rb_nativethread_lock_destroy(&arg->lock); + + free(arg); +} + +static void * +do_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + + int err, gni_errno; + err = getnameinfo(arg->sa, arg->salen, arg->host, (socklen_t)arg->hostlen, arg->serv, (socklen_t)arg->servlen, arg->flags); + gni_errno = errno; + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + arg->err = err; + arg->gni_errno = gni_errno; + if (!arg->cancelled) { + arg->done = 1; + rb_native_cond_signal(&arg->cond); + } + if (--arg->refcount == 0) need_free = 1; + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getnameinfo_arg(arg); + + return 0; +} + +static void * +wait_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + while (!arg->done && !arg->cancelled) { + rb_native_cond_wait(&arg->cond, &arg->lock); + } + rb_nativethread_lock_unlock(&arg->lock); + return 0; +} + +static void +cancel_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + arg->cancelled = 1; + rb_native_cond_signal(&arg->cond); + rb_nativethread_lock_unlock(&arg->lock); +} + +int +rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) +{ + int retry; + struct getnameinfo_arg *arg; + int err = 0, gni_errno = 0; + + if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) { + return getnameinfo(sa, salen, host, (socklen_t)hostlen, serv, (socklen_t)servlen, flags); + } + +start: + retry = 0; + + arg = allocate_getnameinfo_arg(sa, salen, hostlen, servlen, flags); + if (!arg) { + return EAI_MEMORY; + } + + pthread_t th; + if (raddrinfo_pthread_create(&th, do_getnameinfo, arg) != 0) { + int err = errno; + free_getnameinfo_arg(arg); + errno = err; + return EAI_SYSTEM; + } + + rb_thread_call_without_gvl2(wait_getnameinfo, arg, cancel_getnameinfo, arg); + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + if (arg->done) { + err = arg->err; + gni_errno = arg->gni_errno; + if (err == 0) { + if (host) memcpy(host, arg->host, hostlen); + if (serv) memcpy(serv, arg->serv, servlen); + } + } + else if (arg->cancelled) { + retry = 1; + } + else { + // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getnameinfo. + // In this case, it could be !arg->done && !arg->cancelled. + arg->cancelled = 1; + retry = 1; + } + if (--arg->refcount == 0) need_free = 1; + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getnameinfo_arg(arg); + + // If the current thread is interrupted by asynchronous exception, the following raises the exception. + // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry. + rb_thread_check_ints(); + if (retry) goto start; + + /* Make sure we copy the thread-local errno value from the getnameinfo thread back to this thread, so + * calling code sees the correct errno */ + if (gni_errno) errno = gni_errno; + return err; +} + +#endif + +static void make_ipaddr0(struct sockaddr *addr, socklen_t addrlen, char *buf, size_t buflen) { int error; error = rb_getnameinfo(addr, addrlen, buf, buflen, NULL, 0, NI_NUMERICHOST); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } } @@ -396,8 +905,8 @@ str_is_number(const char *p) ((ptr)[0] == name[0] && \ rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0) -static char* -host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) +char* +raddrinfo_host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) { if (NIL_P(host)) { return NULL; @@ -435,8 +944,8 @@ host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) } } -static char* -port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr) +char* +raddrinfo_port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr) { if (NIL_P(port)) { return 0; @@ -488,7 +997,7 @@ rb_scheduler_getaddrinfo(VALUE scheduler, VALUE host, const char *service, for(i=0; i<len; i++) { ip_address = rb_ary_entry(ip_addresses_array, i); - hostp = host_str(ip_address, _hbuf, sizeof(_hbuf), &_additional_flags); + hostp = raddrinfo_host_str(ip_address, _hbuf, sizeof(_hbuf), &_additional_flags); error = numeric_getaddrinfo(hostp, service, hints, &ai); if (error == 0) { if (!res_allocated) { @@ -515,7 +1024,7 @@ rb_scheduler_getaddrinfo(VALUE scheduler, VALUE host, const char *service, } struct rb_addrinfo* -rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack) +rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack, VALUE timeout) { struct rb_addrinfo* res = NULL; struct addrinfo *ai; @@ -524,8 +1033,8 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; int additional_flags = 0; - hostp = host_str(host, hbuf, sizeof(hbuf), &additional_flags); - portp = port_str(port, pbuf, sizeof(pbuf), &additional_flags); + hostp = raddrinfo_host_str(host, hbuf, sizeof(hbuf), &additional_flags); + portp = raddrinfo_port_str(port, pbuf, sizeof(pbuf), &additional_flags); if (socktype_hack && hints->ai_socktype == 0 && str_is_number(portp)) { hints->ai_socktype = SOCK_DGRAM; @@ -550,17 +1059,8 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h } if (!resolved) { -#ifdef GETADDRINFO_EMU - error = getaddrinfo(hostp, portp, hints, &ai); -#else - struct getaddrinfo_arg arg; - MEMZERO(&arg, struct getaddrinfo_arg, 1); - arg.node = hostp; - arg.service = portp; - arg.hints = hints; - arg.res = &ai; - error = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0); -#endif + int t = NIL_P(timeout) ? -1 : rsock_value_timeout_to_msec(timeout); + error = rb_getaddrinfo(hostp, portp, hints, &ai, t); if (error == 0) { res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); res->allocated_by_malloc = 0; @@ -573,7 +1073,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); } - rsock_raise_socket_error("getaddrinfo", error); + rsock_raise_resolution_error("getaddrinfo", error); } return res; @@ -587,13 +1087,13 @@ rsock_fd_family(int fd) if (fd < 0 || getsockname(fd, &sa, &sa_len) != 0 || (size_t)sa_len < offsetof(struct sockaddr, sa_family) + sizeof(sa.sa_family)) { - return AF_UNSPEC; + return AF_UNSPEC; } return sa.sa_family; } struct rb_addrinfo* -rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags) +rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags, VALUE timeout) { struct addrinfo hints; @@ -601,7 +1101,7 @@ rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags) hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_flags = flags; - return rsock_getaddrinfo(host, port, &hints, 1); + return rsock_getaddrinfo(host, port, &hints, 1, timeout); } VALUE @@ -618,8 +1118,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) family = rb_str_dup(rb_id2str(id)); } else { - sprintf(pbuf, "unknown:%d", sockaddr->sa_family); - family = rb_str_new2(pbuf); + family = rb_sprintf("unknown:%d", sockaddr->sa_family); } addr1 = Qnil; @@ -633,7 +1132,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) error = rb_getnameinfo(sockaddr, sockaddrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } addr2 = rb_str_new2(hbuf); if (addr1 == Qnil) { @@ -645,7 +1144,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) return ary; } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN static long unixsocket_len(const struct sockaddr_un *su, socklen_t socklen) { @@ -677,19 +1176,19 @@ rsock_unix_sockaddr_len(VALUE path) { #ifdef __linux__ if (RSTRING_LEN(path) == 0) { - /* autobind; see unix(7) for details. */ - return (socklen_t) sizeof(sa_family_t); + /* autobind; see unix(7) for details. */ + return (socklen_t) sizeof(sa_family_t); } else if (RSTRING_PTR(path)[0] == '\0') { - /* abstract namespace; see unix(7) for details. */ + /* abstract namespace; see unix(7) for details. */ if (SOCKLEN_MAX - offsetof(struct sockaddr_un, sun_path) < (size_t)RSTRING_LEN(path)) rb_raise(rb_eArgError, "Linux abstract socket too long"); - return (socklen_t) offsetof(struct sockaddr_un, sun_path) + - RSTRING_SOCKLEN(path); + return (socklen_t) offsetof(struct sockaddr_un, sun_path) + + RSTRING_SOCKLEN(path); } else { #endif - return (socklen_t) sizeof(struct sockaddr_un); + return (socklen_t) sizeof(struct sockaddr_un); #ifdef __linux__ } #endif @@ -722,12 +1221,12 @@ make_hostent_internal(VALUE v) hostp = addr->ai_canonname; } else { - hostp = host_str(host, hbuf, sizeof(hbuf), NULL); + hostp = raddrinfo_host_str(host, hbuf, sizeof(hbuf), NULL); } rb_ary_push(ary, rb_str_new2(hostp)); if (addr->ai_canonname && strlen(addr->ai_canonname) < NI_MAXHOST && - (h = gethostbyname(addr->ai_canonname))) { + (h = gethostbyname(addr->ai_canonname))) { names = rb_ary_new(); if (h->h_aliases != NULL) { for (pch = h->h_aliases; *pch; pch++) { @@ -796,6 +1295,7 @@ addrinfo_memsize(const void *ptr) static const rb_data_type_t addrinfo_type = { "socket/addrinfo", {addrinfo_mark, addrinfo_free, addrinfo_memsize,}, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -833,7 +1333,7 @@ alloc_addrinfo(void) } static void -init_addrinfo(rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len, +init_addrinfo(VALUE self, rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len, int pfamily, int socktype, int protocol, VALUE canonname, VALUE inspectname) { @@ -845,8 +1345,8 @@ init_addrinfo(rb_addrinfo_t *rai, struct sockaddr *sa, socklen_t len, rai->pfamily = pfamily; rai->socktype = socktype; rai->protocol = protocol; - rai->canonname = canonname; - rai->inspectname = inspectname; + RB_OBJ_WRITE(self, &rai->canonname, canonname); + RB_OBJ_WRITE(self, &rai->inspectname, inspectname); } VALUE @@ -859,7 +1359,7 @@ rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, a = addrinfo_s_allocate(rb_cAddrinfo); DATA_PTR(a) = rai = alloc_addrinfo(); - init_addrinfo(rai, addr, len, family, socktype, protocol, canonname, inspectname); + init_addrinfo(a, rai, addr, len, family, socktype, protocol, canonname, inspectname); return a; } @@ -875,26 +1375,26 @@ call_getaddrinfo(VALUE node, VALUE service, hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family); if (!NIL_P(socktype)) { - hints.ai_socktype = rsock_socktype_arg(socktype); + hints.ai_socktype = rsock_socktype_arg(socktype); } if (!NIL_P(protocol)) { - hints.ai_protocol = NUM2INT(protocol); + hints.ai_protocol = NUM2INT(protocol); } if (!NIL_P(flags)) { - hints.ai_flags = NUM2INT(flags); + hints.ai_flags = NUM2INT(flags); } - res = rsock_getaddrinfo(node, service, &hints, socktype_hack); + res = rsock_getaddrinfo(node, service, &hints, socktype_hack, timeout); if (res == NULL) - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); return res; } static VALUE make_inspectname(VALUE node, VALUE service, struct addrinfo *res); static void -init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service, +init_addrinfo_getaddrinfo(VALUE self, rb_addrinfo_t *rai, VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, VALUE inspectnode, VALUE inspectservice) { @@ -908,7 +1408,7 @@ init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service, OBJ_FREEZE(canonname); } - init_addrinfo(rai, res->ai->ai_addr, res->ai->ai_addrlen, + init_addrinfo(self, rai, res->ai->ai_addr, res->ai->ai_addrlen, NUM2INT(family), NUM2INT(socktype), NUM2INT(protocol), canonname, inspectname); @@ -1018,9 +1518,9 @@ addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN static void -init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) +init_unix_addrinfo(VALUE self, rb_addrinfo_t *rai, VALUE path, int socktype) { struct sockaddr_un un; socklen_t len; @@ -1036,8 +1536,8 @@ init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) memcpy((void*)&un.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); len = rsock_unix_sockaddr_len(path); - init_addrinfo(rai, (struct sockaddr *)&un, len, - PF_UNIX, socktype, 0, Qnil, Qnil); + init_addrinfo(self, rai, (struct sockaddr *)&un, len, + PF_UNIX, socktype, 0, Qnil, Qnil); } static long @@ -1065,13 +1565,13 @@ rai_unixsocket_len(const rb_addrinfo_t *rai) * Socket.sockaddr_in or Socket.unpack_sockaddr_un. * * sockaddr examples: - * - ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] - * - ["AF_INET6", 42304, "ip6-localhost", "::1"] - * - ["AF_UNIX", "/tmp/sock"] - * - Socket.sockaddr_in("smtp", "2001:DB8::1") - * - Socket.sockaddr_in(80, "172.18.22.42") - * - Socket.sockaddr_in(80, "www.ruby-lang.org") - * - Socket.sockaddr_un("/tmp/sock") + * - <code>["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"]</code> + * - <code>["AF_INET6", 42304, "ip6-localhost", "::1"]</code> + * - <code>["AF_UNIX", "/tmp/sock"]</code> + * - <code>Socket.sockaddr_in("smtp", "2001:DB8::1")</code> + * - <code>Socket.sockaddr_in(80, "172.18.22.42")</code> + * - <code>Socket.sockaddr_in(80, "www.ruby-lang.org")</code> + * - <code>Socket.sockaddr_un("/tmp/sock")</code> * * In an AF_INET/AF_INET6 sockaddr array, the 4th element, * numeric IP address, is used to construct socket address in the Addrinfo instance. @@ -1119,7 +1619,7 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) int af; StringValue(afamily); if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1) - rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily)); + rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily)); switch (af) { case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */ #ifdef INET6 @@ -1140,19 +1640,19 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) flags |= AI_NUMERICSERV; #endif - init_addrinfo_getaddrinfo(rai, numericnode, service, + init_addrinfo_getaddrinfo(self, rai, numericnode, service, INT2NUM(i_pfamily ? i_pfamily : af), INT2NUM(i_socktype), INT2NUM(i_protocol), INT2NUM(flags), nodename, service); break; } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */ { VALUE path = rb_ary_entry(sockaddr_ary, 1); StringValue(path); - init_unix_addrinfo(rai, path, SOCK_STREAM); + init_unix_addrinfo(self, rai, path, SOCK_STREAM); break; } #endif @@ -1165,7 +1665,7 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) StringValue(sockaddr_arg); sockaddr_ptr = (struct sockaddr *)RSTRING_PTR(sockaddr_arg); sockaddr_len = RSTRING_SOCKLEN(sockaddr_arg); - init_addrinfo(rai, sockaddr_ptr, sockaddr_len, + init_addrinfo(self, rai, sockaddr_ptr, sockaddr_len, i_pfamily, i_socktype, i_protocol, canonname, inspectname); } @@ -1209,45 +1709,45 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r else { switch (sockaddr->addr.sa_family) { case AF_UNSPEC: - { - rb_str_cat2(ret, "UNSPEC"); + { + rb_str_cat2(ret, "UNSPEC"); break; - } + } case AF_INET: { struct sockaddr_in *addr; int port; - addr = &sockaddr->in; - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+0+1) <= socklen) - rb_str_catf(ret, "%d", ((unsigned char*)&addr->sin_addr)[0]); - else - rb_str_cat2(ret, "?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+1+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[1]); - else - rb_str_cat2(ret, ".?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+2+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[2]); - else - rb_str_cat2(ret, ".?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+3+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[3]); - else - rb_str_cat2(ret, ".?"); - - if ((socklen_t)(((char*)&addr->sin_port)-(char*)addr+(int)sizeof(addr->sin_port)) < socklen) { - port = ntohs(addr->sin_port); - if (port) - rb_str_catf(ret, ":%d", port); - } - else { - rb_str_cat2(ret, ":?"); - } - if ((socklen_t)sizeof(struct sockaddr_in) != socklen) - rb_str_catf(ret, " (%d bytes for %d bytes sockaddr_in)", - (int)socklen, - (int)sizeof(struct sockaddr_in)); + addr = &sockaddr->in; + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+0+1) <= socklen) + rb_str_catf(ret, "%d", ((unsigned char*)&addr->sin_addr)[0]); + else + rb_str_cat2(ret, "?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+1+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[1]); + else + rb_str_cat2(ret, ".?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+2+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[2]); + else + rb_str_cat2(ret, ".?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+3+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[3]); + else + rb_str_cat2(ret, ".?"); + + if ((socklen_t)(((char*)&addr->sin_port)-(char*)addr+(int)sizeof(addr->sin_port)) < socklen) { + port = ntohs(addr->sin_port); + if (port) + rb_str_catf(ret, ":%d", port); + } + else { + rb_str_cat2(ret, ":?"); + } + if ((socklen_t)sizeof(struct sockaddr_in) != socklen) + rb_str_catf(ret, " (%d bytes for %d bytes sockaddr_in)", + (int)socklen, + (int)sizeof(struct sockaddr_in)); break; } @@ -1267,11 +1767,11 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r * RFC 4007: IPv6 Scoped Address Architecture * draft-ietf-ipv6-scope-api-00.txt: Scoped Address Extensions to the IPv6 Basic Socket API */ - error = getnameinfo(&sockaddr->addr, socklen, - hbuf, (socklen_t)sizeof(hbuf), NULL, 0, - NI_NUMERICHOST|NI_NUMERICSERV); + error = rb_getnameinfo(&sockaddr->addr, socklen, + hbuf, (socklen_t)sizeof(hbuf), NULL, 0, + NI_NUMERICHOST|NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } if (addr->sin6_port == 0) { rb_str_cat2(ret, hbuf); @@ -1287,7 +1787,7 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r } #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { struct sockaddr_un *addr = &sockaddr->un; @@ -1398,20 +1898,20 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r #endif #if defined(AF_LINK) && defined(HAVE_TYPE_STRUCT_SOCKADDR_DL) - /* AF_LINK is defined in 4.4BSD derivations since Net2. - link_ntoa is also defined at Net2. + /* AF_LINK is defined in 4.4BSD derivations since Net2. + link_ntoa is also defined at Net2. However Debian GNU/kFreeBSD defines AF_LINK but don't have link_ntoa. */ case AF_LINK: - { - /* - * Simple implementation using link_ntoa(): - * This doesn't work on Debian GNU/kFreeBSD 6.0.7 (squeeze). + { + /* + * Simple implementation using link_ntoa(): + * This doesn't work on Debian GNU/kFreeBSD 6.0.7 (squeeze). * Also, the format is bit different. - * - * rb_str_catf(ret, "LINK %s", link_ntoa(&sockaddr->dl)); - * break; - */ + * + * rb_str_catf(ret, "LINK %s", link_ntoa(&sockaddr->dl)); + * break; + */ struct sockaddr_dl *addr = &sockaddr->dl; char *np = NULL, *ap = NULL, *endp; int nlen = 0, alen = 0; @@ -1438,14 +1938,14 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r alen = (int)(endp - ap); } - CATSEP; + CATSEP; if (np) rb_str_catf(ret, "%.*s", nlen, np); else rb_str_cat2(ret, "?"); if (ap && 0 < alen) { - CATSEP; + CATSEP; for (i = 0; i < alen; i++) rb_str_catf(ret, "%s%02x", i == 0 ? "" : ":", (unsigned char)ap[i]); } @@ -1456,10 +1956,10 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r /* longer length is possible behavior because struct sockaddr_dl has "minimum work area, can be larger" as the last field. * cf. Net2:/usr/src/sys/net/if_dl.h. */ socklen < (socklen_t)(offsetof(struct sockaddr_dl, sdl_data) + addr->sdl_nlen + addr->sdl_alen + addr->sdl_slen)) { - CATSEP; + CATSEP; rb_str_catf(ret, "(%d bytes for %d bytes sockaddr_dl)", (int)socklen, (int)sizeof(struct sockaddr_dl)); - } + } rb_str_cat2(ret, "]"); #undef CATSEP @@ -1623,7 +2123,7 @@ addrinfo_mdump(VALUE self) afamily = rb_id2str(id); switch(afamily_int) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { sockaddr = rb_str_new(rai->addr.un.sun_path, rai_unixsocket_len(rai)); @@ -1635,11 +2135,11 @@ addrinfo_mdump(VALUE self) { char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; int error; - error = getnameinfo(&rai->addr.addr, rai->sockaddr_len, - hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), - NI_NUMERICHOST|NI_NUMERICSERV); + error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len, + hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), + NI_NUMERICHOST|NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } sockaddr = rb_assoc_new(rb_str_new_cstr(hbuf), rb_str_new_cstr(pbuf)); break; @@ -1716,7 +2216,7 @@ addrinfo_mload(VALUE self, VALUE ary) v = rb_ary_entry(ary, 1); switch(afamily) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { struct sockaddr_un uaddr; @@ -1754,7 +2254,7 @@ addrinfo_mload(VALUE self, VALUE ary) } DATA_PTR(self) = rai = alloc_addrinfo(); - init_addrinfo(rai, &ss.addr, len, + init_addrinfo(self, rai, &ss.addr, len, pfamily, socktype, protocol, canonname, inspectname); return self; @@ -1981,11 +2481,11 @@ addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self) if (rai->socktype == SOCK_DGRAM) flags |= NI_DGRAM; - error = getnameinfo(&rai->addr.addr, rai->sockaddr_len, - hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), - flags); + error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len, + hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), + flags); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); @@ -2009,7 +2509,7 @@ addrinfo_ip_unpack(VALUE self) VALUE ret, portstr; if (!IS_IP_FAMILY(family)) - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV); ret = addrinfo_getnameinfo(1, &vflags, self); @@ -2036,7 +2536,7 @@ addrinfo_ip_address(VALUE self) VALUE ret; if (!IS_IP_FAMILY(family)) - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV); ret = addrinfo_getnameinfo(1, &vflags, self); @@ -2062,9 +2562,9 @@ addrinfo_ip_port(VALUE self) if (!IS_IP_FAMILY(family)) { bad_family: #ifdef AF_INET6 - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); #else - rb_raise(rb_eSocket, "need IPv4 address"); + rb_raise(rb_eSocket, "need IPv4 address"); #endif } @@ -2084,7 +2584,7 @@ addrinfo_ip_port(VALUE self) #endif default: - goto bad_family; + goto bad_family; } return INT2NUM(port); @@ -2192,7 +2692,7 @@ addrinfo_ipv6_multicast_p(VALUE self) } /* - * Returns true for IPv6 link local address (ff80::/10). + * Returns true for IPv6 link local address (fe80::/10). * It returns false otherwise. */ static VALUE @@ -2204,7 +2704,7 @@ addrinfo_ipv6_linklocal_p(VALUE self) } /* - * Returns true for IPv6 site local address (ffc0::/10). + * Returns true for IPv6 site local address (fec0::/10). * It returns false otherwise. */ static VALUE @@ -2344,7 +2844,7 @@ addrinfo_ipv6_to_ipv4(VALUE self) #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: * addrinfo.unix_path => path @@ -2362,7 +2862,7 @@ addrinfo_unix_path(VALUE self) long n; if (family != AF_UNIX) - rb_raise(rb_eSocket, "need AF_UNIX address"); + rb_raise(rb_eSocket, "need AF_UNIX address"); addr = &rai->addr.un; @@ -2429,10 +2929,10 @@ addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self) VALUE node, service, family, socktype, protocol, flags, opts, timeout; rb_scan_args(argc, argv, "24:", &node, &service, &family, &socktype, - &protocol, &flags, &opts); + &protocol, &flags, &opts); rb_get_kwargs(opts, &id_timeout, 0, 1, &timeout); if (timeout == Qundef) { - timeout = Qnil; + timeout = Qnil; } return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout); @@ -2492,7 +2992,7 @@ addrinfo_s_udp(VALUE self, VALUE host, VALUE port) INT2NUM(PF_UNSPEC), INT2NUM(SOCK_DGRAM), INT2NUM(IPPROTO_UDP), INT2FIX(0)); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: @@ -2522,7 +3022,7 @@ addrinfo_s_unix(int argc, VALUE *argv, VALUE self) addr = addrinfo_s_allocate(rb_cAddrinfo); DATA_PTR(addr) = rai = alloc_addrinfo(); - init_unix_addrinfo(rai, path, socktype); + init_unix_addrinfo(self, rai, path, socktype); return addr; } @@ -2609,18 +3109,111 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len) UNREACHABLE_RETURN(Qnil); } +#if FAST_FALLBACK_INIT_INETSOCK_IMPL == 1 + +void +free_fast_fallback_getaddrinfo_shared(struct fast_fallback_getaddrinfo_shared **shared) +{ + xfree((*shared)->node); + (*shared)->node = NULL; + xfree((*shared)->service); + (*shared)->service = NULL; + rb_nativethread_lock_destroy(&(*shared)->lock); + free(*shared); + *shared = NULL; +} + +static void * +do_fast_fallback_getaddrinfo(void *ptr) +{ + struct fast_fallback_getaddrinfo_entry *entry = (struct fast_fallback_getaddrinfo_entry *)ptr; + struct fast_fallback_getaddrinfo_shared *shared = entry->shared; + int err = 0, shared_need_free = 0; + struct addrinfo *ai = NULL; + + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + err = numeric_getaddrinfo(shared->node, shared->service, &entry->hints, &entry->ai); + + if (err != 0) { + err = getaddrinfo(shared->node, shared->service, &entry->hints, &entry->ai); + #ifdef __linux__ + /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and + * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] + */ + if (err == EAI_SYSTEM && errno == ENOENT) + err = EAI_NONAME; + #endif + } + + /* for testing HEv2 */ + if (entry->test_sleep_ms > 0) { + struct timespec sleep_ts; + sleep_ts.tv_sec = entry->test_sleep_ms / 1000; + sleep_ts.tv_nsec = (entry->test_sleep_ms % 1000) * 1000000L; + if (sleep_ts.tv_nsec >= 1000000000L) { + sleep_ts.tv_sec += sleep_ts.tv_nsec / 1000000000L; + sleep_ts.tv_nsec = sleep_ts.tv_nsec % 1000000000L; + } + nanosleep(&sleep_ts, NULL); + } + if (entry->test_ecode != 0) { + err = entry->test_ecode; + if (entry->ai) { + freeaddrinfo(entry->ai); + entry->ai = NULL; + } + } + + rb_nativethread_lock_lock(&shared->lock); + { + entry->err = err; + const char notification = entry->family == AF_INET6 ? + IPV6_HOSTNAME_RESOLVED : IPV4_HOSTNAME_RESOLVED; + + if (shared->notify != -1 && (write(shared->notify, ¬ification, 1)) < 0) { + entry->err = errno; + entry->has_syserr = true; + } + if (--(entry->refcount) == 0) { + ai = entry->ai; + entry->ai = NULL; + } + if (--(shared->refcount) == 0) shared_need_free = 1; + } + rb_nativethread_lock_unlock(&shared->lock); + + if (ai) freeaddrinfo(ai); + if (shared_need_free && shared) { + free_fast_fallback_getaddrinfo_shared(&shared); + } + + return 0; +} + +void * +fork_safe_do_fast_fallback_getaddrinfo(void *ptr) +{ + return rb_thread_prevent_fork(do_fast_fallback_getaddrinfo, ptr); +} + +#endif + /* * Addrinfo class */ void rsock_init_addrinfo(void) { + id_timeout = rb_intern("timeout"); + /* * The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This * structure identifies an Internet host and a service. */ - id_timeout = rb_intern("timeout"); - rb_cAddrinfo = rb_define_class("Addrinfo", rb_cObject); rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate); rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1); @@ -2630,7 +3223,7 @@ rsock_init_addrinfo(void) rb_define_singleton_method(rb_cAddrinfo, "ip", addrinfo_s_ip, 1); rb_define_singleton_method(rb_cAddrinfo, "tcp", addrinfo_s_tcp, 2); rb_define_singleton_method(rb_cAddrinfo, "udp", addrinfo_s_udp, 2); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_singleton_method(rb_cAddrinfo, "unix", addrinfo_s_unix, -1); #endif @@ -2671,7 +3264,7 @@ rsock_init_addrinfo(void) rb_define_method(rb_cAddrinfo, "ipv6_to_ipv4", addrinfo_ipv6_to_ipv4, 0); #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_method(rb_cAddrinfo, "unix_path", addrinfo_unix_path, 0); #endif diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h index c0d40addca..2ec3ab335a 100644 --- a/ext/socket/rubysocket.h +++ b/ext/socket/rubysocket.h @@ -33,6 +33,10 @@ #endif #ifdef _WIN32 +# include <winsock2.h> +# include <ws2tcpip.h> +# include <mswsock.h> +# include <iphlpapi.h> # if defined(_MSC_VER) # undef HAVE_TYPE_STRUCT_SOCKADDR_DL # endif @@ -69,6 +73,11 @@ # include <sys/un.h> #endif +#ifdef HAVE_AFUNIX_H +// Windows doesn't have sys/un.h, but it does have afunix.h just to be special: +# include <afunix.h> +#endif + #if defined(HAVE_FCNTL) # ifdef HAVE_SYS_SELECT_H # include <sys/select.h> @@ -129,6 +138,7 @@ #include "internal.h" #include "internal/array.h" +#include "internal/compilers.h" #include "internal/error.h" #include "internal/gc.h" #include "internal/io.h" @@ -268,7 +278,7 @@ extern VALUE rb_cIPSocket; extern VALUE rb_cTCPSocket; extern VALUE rb_cTCPServer; extern VALUE rb_cUDPSocket; -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN extern VALUE rb_cUNIXSocket; extern VALUE rb_cUNIXServer; #endif @@ -277,19 +287,18 @@ extern VALUE rb_cAddrinfo; extern VALUE rb_cSockOpt; extern VALUE rb_eSocket; +extern VALUE rb_eResolution; #ifdef SOCKS extern VALUE rb_cSOCKSSocket; # ifndef SOCKS5 -void SOCKSinit(); -int Rconnect(); +void SOCKSinit(char *); +int Rconnect(int, const struct sockaddr *, socklen_t); # endif #endif #include "constdefs.h" -#define BLOCKING_REGION_FD(func, arg) (long)rb_thread_io_blocking_region((func), (arg), (arg)->fd) - #define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v)) #define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v)) #define SockAddrStringValueWithAddrinfo(v, rai_ret) rsock_sockaddr_string_value_with_addrinfo(&(v), &(rai_ret)) @@ -299,7 +308,7 @@ VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret VALUE rb_check_sockaddr_string_type(VALUE); -NORETURN(void rsock_raise_socket_error(const char *, int)); +NORETURN(void rsock_raise_resolution_error(const char *, int)); int rsock_family_arg(VALUE domain); int rsock_socktype_arg(VALUE type); @@ -318,8 +327,8 @@ void rb_freeaddrinfo(struct rb_addrinfo *ai); VALUE rsock_freeaddrinfo(VALUE arg); int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); int rsock_fd_family(int fd); -struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags); -struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack); +struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags, VALUE timeout); +struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack, VALUE timeout); VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len); VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len); @@ -336,7 +345,7 @@ VALUE rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len); int rsock_revlookup_flag(VALUE revlookup, int *norevlookup); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len); VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len); socklen_t rsock_unix_sockaddr_len(VALUE path); @@ -346,7 +355,7 @@ int rsock_socket(int domain, int type, int proto); int rsock_detect_cloexec(int fd); VALUE rsock_init_sock(VALUE sock, int fd); VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass); -VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type, VALUE resolv_timeout, VALUE connect_timeout); +VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type, VALUE resolv_timeout, VALUE connect_timeout, VALUE open_timeout, VALUE fast_fallback, VALUE test_mode_settings); VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server); struct rsock_send_arg { @@ -368,23 +377,23 @@ enum sock_recv_type { }; VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, - VALUE ex, enum sock_recv_type from); + VALUE ex, enum sock_recv_type from); VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from); -int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout); +int rsock_connect(VALUE self, const struct sockaddr *sockaddr, int len, int socks, VALUE timeout); VALUE rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len); VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, - struct sockaddr *sockaddr, socklen_t *len); + struct sockaddr *sockaddr, socklen_t *len); VALUE rsock_sock_listen(VALUE sock, VALUE log); VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data); #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls); + VALUE dest_sockaddr, VALUE controls); VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls, VALUE ex); + VALUE dest_sockaddr, VALUE controls, VALUE ex); #else #define rsock_bsock_sendmsg rb_f_notimplement #define rsock_bsock_sendmsg_nonblock rb_f_notimplement @@ -392,9 +401,9 @@ VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE clen, VALUE flags, - VALUE scm_rights); + VALUE scm_rights); VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE clen, - VALUE flags, VALUE scm_rights, VALUE ex); + VALUE flags, VALUE scm_rights, VALUE ex); ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags); #else #define rsock_bsock_recvmsg rb_f_notimplement @@ -405,6 +414,47 @@ ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags); void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p); #endif +char *raddrinfo_host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr); +char *raddrinfo_port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr); + +#ifndef FAST_FALLBACK_INIT_INETSOCK_IMPL +# if !defined(HAVE_PTHREAD_CREATE) || !defined(HAVE_PTHREAD_DETACH) || defined(__MINGW32__) || defined(__MINGW64__) +# define FAST_FALLBACK_INIT_INETSOCK_IMPL 0 +# else +# include "ruby/thread_native.h" +# define FAST_FALLBACK_INIT_INETSOCK_IMPL 1 +# define IPV6_HOSTNAME_RESOLVED '1' +# define IPV4_HOSTNAME_RESOLVED '2' +# define SELECT_CANCELLED '3' + +struct fast_fallback_getaddrinfo_entry +{ + int family, err, refcount; + struct addrinfo hints; + struct addrinfo *ai; + struct fast_fallback_getaddrinfo_shared *shared; + int has_syserr; + long test_sleep_ms; + int test_ecode; +}; + +struct fast_fallback_getaddrinfo_shared +{ + int notify, refcount; + char *node, *service; + rb_nativethread_lock_t lock; + struct fast_fallback_getaddrinfo_entry getaddrinfo_entries[FLEX_ARY_LEN]; +}; + +int raddrinfo_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg); +void *fork_safe_do_fast_fallback_getaddrinfo(void *ptr); +void free_fast_fallback_getaddrinfo_entry(struct fast_fallback_getaddrinfo_entry **entry); +void free_fast_fallback_getaddrinfo_shared(struct fast_fallback_getaddrinfo_shared **shared); +# endif +#endif + +NORETURN(void rsock_raise_user_specified_timeout(struct addrinfo *ai, VALUE host, VALUE port)); + void rsock_init_basicsocket(void); void rsock_init_ipsocket(void); void rsock_init_tcpsocket(void); @@ -451,12 +501,14 @@ VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex); void rsock_make_fd_nonblock(int fd); +int rsock_is_dgram(rb_io_t *fptr); + +extern ID tcp_fast_fallback; + #if !defined HAVE_INET_NTOP && ! defined _WIN32 const char *inet_ntop(int, const void *, char *, size_t); #elif defined __MINGW32__ # define inet_ntop(f,a,n,l) rb_w32_inet_ntop(f,a,n,l) -#elif defined _MSC_VER && RUBY_MSVCRT_VERSION < 90 -const char *WSAAPI inet_ntop(int, const void *, char *, size_t); #endif #endif diff --git a/ext/socket/socket.c b/ext/socket/socket.c index ccf990d11f..a8e5ae8119 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -14,6 +14,8 @@ static VALUE sym_wait_writable; static VALUE sock_s_unpack_sockaddr_in(VALUE, VALUE); +ID tcp_fast_fallback; + void rsock_sys_fail_host_port(const char *mesg, VALUE host, VALUE port) { @@ -26,7 +28,11 @@ rsock_syserr_fail_host_port(int err, const char *mesg, VALUE host, VALUE port) VALUE message; message = rb_sprintf("%s for %+"PRIsVALUE" port % "PRIsVALUE"", - mesg, host, port); + mesg, host, port); + + if (err == ETIMEDOUT) { + rb_exc_raise(rb_exc_new3(rb_eIOTimeoutError, message)); + } rb_syserr_fail_str(err, message); } @@ -43,11 +49,11 @@ rsock_syserr_fail_path(int err, const char *mesg, VALUE path) VALUE message; if (RB_TYPE_P(path, T_STRING)) { - message = rb_sprintf("%s for % "PRIsVALUE"", mesg, path); - rb_syserr_fail_str(err, message); + message = rb_sprintf("%s for % "PRIsVALUE"", mesg, path); + rb_syserr_fail_str(err, message); } else { - rb_syserr_fail(err, mesg); + rb_syserr_fail(err, mesg); } } @@ -96,12 +102,12 @@ rsock_syserr_fail_raddrinfo_or_sockaddr(int err, const char *mesg, VALUE addr, V if (NIL_P(rai)) { StringValue(addr); - rsock_syserr_fail_sockaddr(err, mesg, + rsock_syserr_fail_sockaddr(err, mesg, (struct sockaddr *)RSTRING_PTR(addr), (socklen_t)RSTRING_LEN(addr)); /* overflow should be checked already */ } else - rsock_syserr_fail_raddrinfo(err, mesg, rai); + rsock_syserr_fail_raddrinfo(err, mesg, rai); } static void @@ -256,7 +262,7 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) p = NUM2INT(protocol); ret = rsock_socketpair(d, t, p, sp); if (ret < 0) { - rb_sys_fail("socketpair(2)"); + rb_sys_fail("socketpair(2)"); } s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]); @@ -383,22 +389,20 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) * * connect function in Microsoft's Winsock functions reference */ static VALUE -sock_connect(VALUE sock, VALUE addr) +sock_connect(VALUE self, VALUE addr) { VALUE rai; - rb_io_t *fptr; - int fd, n; SockAddrStringValueWithAddrinfo(addr, rai); addr = rb_str_new4(addr); - GetOpenFile(sock, fptr); - fd = fptr->fd; - n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, NULL); - if (n < 0) { - rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); + + int result = rsock_connect(self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT); + + if (result < 0) { + rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); } - return INT2FIX(n); + return INT2FIX(result); } /* :nodoc: */ @@ -415,19 +419,19 @@ sock_connect_nonblock(VALUE sock, VALUE addr, VALUE ex) rb_io_set_nonblock(fptr); n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)); if (n < 0) { - int e = errno; - if (e == EINPROGRESS) { + int e = errno; + if (e == EINPROGRESS) { if (ex == Qfalse) { return sym_wait_writable; } rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, "connect(2) would block"); - } - if (e == EISCONN) { + } + if (e == EISCONN) { if (ex == Qfalse) { return INT2FIX(0); } - } - rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); + } + rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); } return INT2FIX(n); @@ -528,7 +532,7 @@ sock_bind(VALUE sock, VALUE addr) SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) - rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); + rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); return INT2FIX(0); } @@ -612,7 +616,7 @@ rsock_sock_listen(VALUE sock, VALUE log) backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) - rb_sys_fail("listen(2)"); + rb_sys_fail("listen(2)"); return INT2FIX(0); } @@ -774,7 +778,7 @@ sock_accept_nonblock(VALUE sock, VALUE ex) sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) /* :wait_readable */ - return sock2; + return sock2; return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } @@ -855,19 +859,19 @@ sock_gethostname(VALUE obj) name = rb_str_new(0, len); while (gethostname(RSTRING_PTR(name), len) < 0) { - int e = errno; - switch (e) { - case ENAMETOOLONG: + int e = errno; + switch (e) { + case ENAMETOOLONG: #ifdef __linux__ - case EINVAL: - /* glibc before version 2.1 uses EINVAL instead of ENAMETOOLONG */ + case EINVAL: + /* glibc before version 2.1 uses EINVAL instead of ENAMETOOLONG */ #endif - break; - default: - rb_syserr_fail(e, "gethostname(3)"); - } - rb_str_modify_expand(name, len); - len += len; + break; + default: + rb_syserr_fail(e, "gethostname(3)"); + } + rb_str_modify_expand(name, len); + len += len; } rb_str_resize(name, strlen(RSTRING_PTR(name))); return name; @@ -897,18 +901,18 @@ make_addrinfo(struct rb_addrinfo *res0, int norevlookup) struct addrinfo *res; if (res0 == NULL) { - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); } base = rb_ary_new(); for (res = res0->ai; res; res = res->ai_next) { - ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); - if (res->ai_canonname) { - RARRAY_ASET(ary, 2, rb_str_new2(res->ai_canonname)); - } - rb_ary_push(ary, INT2FIX(res->ai_family)); - rb_ary_push(ary, INT2FIX(res->ai_socktype)); - rb_ary_push(ary, INT2FIX(res->ai_protocol)); - rb_ary_push(base, ary); + ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); + if (res->ai_canonname) { + RARRAY_ASET(ary, 2, rb_str_new2(res->ai_canonname)); + } + rb_ary_push(ary, INT2FIX(res->ai_family)); + rb_ary_push(ary, INT2FIX(res->ai_socktype)); + rb_ary_push(ary, INT2FIX(res->ai_protocol)); + rb_ary_push(base, ary); } return base; } @@ -920,18 +924,18 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len) switch (addr->sa_family) { case AF_INET: - ptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr; - len = (socklen_t)sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr); - break; + ptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr; + len = (socklen_t)sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr); + break; #ifdef AF_INET6 case AF_INET6: - ptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr; - len = (socklen_t)sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr); - break; + ptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr; + len = (socklen_t)sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr); + break; #endif default: rb_raise(rb_eSocket, "unknown socket family:%d", addr->sa_family); - break; + break; } return rb_str_new(ptr, len); } @@ -961,7 +965,7 @@ sock_s_gethostbyname(VALUE obj, VALUE host) { rb_warn("Socket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); struct rb_addrinfo *res = - rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME, Qnil); return rsock_make_hostent(host, res, sock_sockaddr); } @@ -1004,20 +1008,20 @@ sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _) rb_scan_args(argc, argv, "11", &addr, &family); StringValue(addr); if (!NIL_P(family)) { - t = rsock_family_arg(family); + t = rsock_family_arg(family); } #ifdef AF_INET6 else if (RSTRING_LEN(addr) == 16) { - t = AF_INET6; + t = AF_INET6; } #endif h = gethostbyaddr(RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), t); if (h == NULL) { #ifdef HAVE_HSTRERROR - extern int h_errno; - rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno)); + extern int h_errno; + rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno)); #else - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); #endif } ary = rb_ary_new(); @@ -1025,14 +1029,14 @@ sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _) names = rb_ary_new(); rb_ary_push(ary, names); if (h->h_aliases != NULL) { - for (pch = h->h_aliases; *pch; pch++) { - rb_ary_push(names, rb_str_new2(*pch)); - } + for (pch = h->h_aliases; *pch; pch++) { + rb_ary_push(names, rb_str_new2(*pch)); + } } rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { - rb_ary_push(ary, rb_str_new(*pch, h->h_length)); + rb_ary_push(ary, rb_str_new(*pch, h->h_length)); } #else rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length)); @@ -1069,15 +1073,15 @@ sock_s_getservbyname(int argc, VALUE *argv, VALUE _) if (!NIL_P(proto)) protoname = StringValueCStr(proto); sp = getservbyname(servicename, protoname); if (sp) { - port = ntohs(sp->s_port); + port = ntohs(sp->s_port); } else { - char *end; + char *end; - port = STRTOUL(servicename, &end, 0); - if (*end != '\0') { - rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname); - } + port = STRTOUL(servicename, &end, 0); + if (*end != '\0') { + rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname); + } } return INT2FIX(port); } @@ -1106,14 +1110,14 @@ sock_s_getservbyport(int argc, VALUE *argv, VALUE _) rb_scan_args(argc, argv, "11", &port, &proto); portnum = NUM2LONG(port); if (portnum != (uint16_t)portnum) { - const char *s = portnum > 0 ? "big" : "small"; - rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s); + const char *s = portnum > 0 ? "big" : "small"; + rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s); } if (!NIL_P(proto)) protoname = StringValueCStr(proto); sp = getservbyport((int)htons((uint16_t)portnum), protoname); if (!sp) { - rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); + rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); } return rb_str_new2(sp->s_name); } @@ -1167,19 +1171,19 @@ sock_s_getaddrinfo(int argc, VALUE *argv, VALUE _) hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family); if (!NIL_P(socktype)) { - hints.ai_socktype = rsock_socktype_arg(socktype); + hints.ai_socktype = rsock_socktype_arg(socktype); } if (!NIL_P(protocol)) { - hints.ai_protocol = NUM2INT(protocol); + hints.ai_protocol = NUM2INT(protocol); } if (!NIL_P(flags)) { - hints.ai_flags = NUM2INT(flags); + hints.ai_flags = NUM2INT(flags); } if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) { - norevlookup = rsock_do_not_reverse_lookup; + norevlookup = rsock_do_not_reverse_lookup; } - res = rsock_getaddrinfo(host, port, &hints, 0); + res = rsock_getaddrinfo(host, port, &hints, 0, Qnil); ret = make_addrinfo(res, norevlookup); rb_freeaddrinfo(res); @@ -1226,82 +1230,82 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) fl = 0; if (!NIL_P(flags)) { - fl = NUM2INT(flags); + fl = NUM2INT(flags); } tmp = rb_check_sockaddr_string_type(sa); if (!NIL_P(tmp)) { - sa = tmp; - if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) { - rb_raise(rb_eTypeError, "sockaddr length too big"); - } - memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa)); + sa = tmp; + if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) { + rb_raise(rb_eTypeError, "sockaddr length too big"); + } + memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa)); if (!VALIDATE_SOCKLEN(&ss.addr, RSTRING_LEN(sa))) { - rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); - } - sap = &ss.addr; + rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); + } + sap = &ss.addr; salen = RSTRING_SOCKLEN(sa); - goto call_nameinfo; + goto call_nameinfo; } tmp = rb_check_array_type(sa); if (!NIL_P(tmp)) { - sa = tmp; - MEMZERO(&hints, struct addrinfo, 1); - if (RARRAY_LEN(sa) == 3) { - af = RARRAY_AREF(sa, 0); - port = RARRAY_AREF(sa, 1); - host = RARRAY_AREF(sa, 2); - } - else if (RARRAY_LEN(sa) >= 4) { - af = RARRAY_AREF(sa, 0); - port = RARRAY_AREF(sa, 1); - host = RARRAY_AREF(sa, 3); - if (NIL_P(host)) { - host = RARRAY_AREF(sa, 2); - } - else { - /* - * 4th element holds numeric form, don't resolve. - * see rsock_ipaddr(). - */ + sa = tmp; + MEMZERO(&hints, struct addrinfo, 1); + if (RARRAY_LEN(sa) == 3) { + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 2); + } + else if (RARRAY_LEN(sa) >= 4) { + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 3); + if (NIL_P(host)) { + host = RARRAY_AREF(sa, 2); + } + else { + /* + * 4th element holds numeric form, don't resolve. + * see rsock_ipaddr(). + */ #ifdef AI_NUMERICHOST /* AIX 4.3.3 doesn't have AI_NUMERICHOST. */ - hints.ai_flags |= AI_NUMERICHOST; + hints.ai_flags |= AI_NUMERICHOST; #endif - } - } - else { - rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given", - RARRAY_LEN(sa)); - } - hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; - /* af */ + } + } + else { + rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given", + RARRAY_LEN(sa)); + } + hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; + /* af */ hints.ai_family = NIL_P(af) ? PF_UNSPEC : rsock_family_arg(af); - res = rsock_getaddrinfo(host, port, &hints, 0); - sap = res->ai->ai_addr; + res = rsock_getaddrinfo(host, port, &hints, 0, Qnil); + sap = res->ai->ai_addr; salen = res->ai->ai_addrlen; } else { - rb_raise(rb_eTypeError, "expecting String or Array"); + rb_raise(rb_eTypeError, "expecting String or Array"); } call_nameinfo: error = rb_getnameinfo(sap, salen, hbuf, sizeof(hbuf), - pbuf, sizeof(pbuf), fl); + pbuf, sizeof(pbuf), fl); if (error) goto error_exit_name; if (res) { - for (r = res->ai->ai_next; r; r = r->ai_next) { - char hbuf2[1024], pbuf2[1024]; + for (r = res->ai->ai_next; r; r = r->ai_next) { + char hbuf2[1024], pbuf2[1024]; - sap = r->ai_addr; + sap = r->ai_addr; salen = r->ai_addrlen; - error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2), - pbuf2, sizeof(pbuf2), fl); - if (error) goto error_exit_name; - if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { - rb_freeaddrinfo(res); - rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename"); - } - } - rb_freeaddrinfo(res); + error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2), + pbuf2, sizeof(pbuf2), fl); + if (error) goto error_exit_name; + if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { + rb_freeaddrinfo(res); + rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename"); + } + } + rb_freeaddrinfo(res); } return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); @@ -1309,7 +1313,7 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) saved_errno = errno; if (res) rb_freeaddrinfo(res); errno = saved_errno; - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); UNREACHABLE_RETURN(Qnil); } @@ -1331,7 +1335,7 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) static VALUE sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host) { - struct rb_addrinfo *res = rsock_addrinfo(host, port, AF_UNSPEC, 0, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, port, AF_UNSPEC, 0, 0, Qnil); VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen); rb_freeaddrinfo(res); @@ -1379,7 +1383,7 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr) return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: @@ -1437,8 +1441,8 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr) rb_raise(rb_eArgError, "not an AF_UNIX sockaddr"); } if (sizeof(struct sockaddr_un) < (size_t)RSTRING_LEN(addr)) { - rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d", - RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); + rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d", + RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); } path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr)); return path; @@ -1467,7 +1471,7 @@ sockaddr_len(struct sockaddr *addr) return (socklen_t)sizeof(struct sockaddr_in6); #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: return (socklen_t)sizeof(struct sockaddr_un); #endif @@ -1502,19 +1506,19 @@ sockaddr_obj(struct sockaddr *addr, socklen_t len) #if defined(__KAME__) && defined(AF_INET6) if (addr->sa_family == AF_INET6) { - /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */ + /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */ /* http://orange.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION */ - /* convert fe80:1::1 to fe80::1%1 */ + /* convert fe80:1::1 to fe80::1%1 */ len = (socklen_t)sizeof(struct sockaddr_in6); - memcpy(&addr6, addr, len); - addr = (struct sockaddr *)&addr6; - if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) && - addr6.sin6_scope_id == 0 && - (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) { - addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3]; - addr6.sin6_addr.s6_addr[2] = 0; - addr6.sin6_addr.s6_addr[3] = 0; - } + memcpy(&addr6, addr, len); + addr = (struct sockaddr *)&addr6; + if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) && + addr6.sin6_scope_id == 0 && + (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) { + addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3]; + addr6.sin6_addr.s6_addr[2] = 0; + addr6.sin6_addr.s6_addr[3] = 0; + } } #endif @@ -1529,7 +1533,7 @@ rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len) #endif -#if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32) +#if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM)) || defined(SIOCGIFCONF) || defined(_WIN32) /* * call-seq: * Socket.ip_address_list => array @@ -1590,9 +1594,8 @@ socket_s_ip_address_list(VALUE self) freeifaddrs(ifp); return list; -#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux) +#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) /* Solaris if_tcp(7P) */ - /* HP-UX has SIOCGLIFCONF too. But it uses different struct */ int fd = -1; int ret; struct lifnum ln; @@ -1613,8 +1616,8 @@ socket_s_ip_address_list(VALUE self) ret = ioctl(fd, SIOCGLIFNUM, &ln); if (ret == -1) { - reason = "SIOCGLIFNUM"; - goto finish; + reason = "SIOCGLIFNUM"; + goto finish; } memset(&lc, 0, sizeof(lc)); @@ -1625,13 +1628,13 @@ socket_s_ip_address_list(VALUE self) ret = ioctl(fd, SIOCGLIFCONF, &lc); if (ret == -1) { - reason = "SIOCGLIFCONF"; - goto finish; + reason = "SIOCGLIFCONF"; + goto finish; } list = rb_ary_new(); for (i = 0; i < ln.lifn_count; i++) { - struct lifreq *req = &lc.lifc_req[i]; + struct lifreq *req = &lc.lifc_req[i]; if (IS_IP_FAMILY(req->lifr_addr.ss_family)) { if (req->lifr_addr.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) && @@ -1651,14 +1654,13 @@ socket_s_ip_address_list(VALUE self) finish: save_errno = errno; - if (lc.lifc_buf != NULL) - xfree(lc.lifc_req); + xfree(lc.lifc_req); if (fd != -1) - close(fd); + close(fd); errno = save_errno; if (reason) - rb_syserr_fail(save_errno, reason); + rb_syserr_fail(save_errno, reason); return list; #elif defined(SIOCGIFCONF) @@ -1696,17 +1698,17 @@ socket_s_ip_address_list(VALUE self) /* fprintf(stderr, "conf.ifc_len: %d\n", conf.ifc_len); */ if (bufsize - EXTRA_SPACE < conf.ifc_len) { - if (bufsize < conf.ifc_len) { - /* NetBSD returns required size for all interfaces. */ - bufsize = conf.ifc_len + EXTRA_SPACE; - } - else { - bufsize = bufsize << 1; - } - if (buf == initbuf) - buf = NULL; - buf = xrealloc(buf, bufsize); - goto retry; + if (bufsize < conf.ifc_len) { + /* NetBSD returns required size for all interfaces. */ + bufsize = conf.ifc_len + EXTRA_SPACE; + } + else { + bufsize = bufsize << 1; + } + if (buf == initbuf) + buf = NULL; + buf = xrealloc(buf, bufsize); + goto retry; } close(fd); @@ -1715,10 +1717,10 @@ socket_s_ip_address_list(VALUE self) list = rb_ary_new(); req = conf.ifc_req; while ((char*)req < (char*)conf.ifc_req + conf.ifc_len) { - struct sockaddr *addr = &req->ifr_addr; + struct sockaddr *addr = &req->ifr_addr; if (IS_IP_FAMILY(addr->sa_family)) { - rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr))); - } + rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr))); + } #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN # ifndef _SIZEOF_ADDR_IFREQ # define _SIZEOF_ADDR_IFREQ(r) \ @@ -1727,9 +1729,9 @@ socket_s_ip_address_list(VALUE self) (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \ 0)) # endif - req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req)); + req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req)); #else - req = (struct ifreq *)((char*)req + sizeof(struct ifreq)); + req = (struct ifreq *)((char*)req + sizeof(struct ifreq)); #endif } @@ -1739,57 +1741,57 @@ socket_s_ip_address_list(VALUE self) if (buf != initbuf) xfree(buf); if (fd != -1) - close(fd); + close(fd); errno = save_errno; if (reason) - rb_syserr_fail(save_errno, reason); + rb_syserr_fail(save_errno, reason); return list; #undef EXTRA_SPACE #elif defined(_WIN32) typedef struct ip_adapter_unicast_address_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_unicast_address_st *Next; - struct { - struct sockaddr *lpSockaddr; - int iSockaddrLength; - } Address; - int dummy1; - int dummy2; - int dummy3; - long dummy4; - long dummy5; - long dummy6; + unsigned LONG_LONG dummy0; + struct ip_adapter_unicast_address_st *Next; + struct { + struct sockaddr *lpSockaddr; + int iSockaddrLength; + } Address; + int dummy1; + int dummy2; + int dummy3; + long dummy4; + long dummy5; + long dummy6; } ip_adapter_unicast_address_t; typedef struct ip_adapter_anycast_address_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_anycast_address_st *Next; - struct { - struct sockaddr *lpSockaddr; - int iSockaddrLength; - } Address; + unsigned LONG_LONG dummy0; + struct ip_adapter_anycast_address_st *Next; + struct { + struct sockaddr *lpSockaddr; + int iSockaddrLength; + } Address; } ip_adapter_anycast_address_t; typedef struct ip_adapter_addresses_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_addresses_st *Next; - void *dummy1; - ip_adapter_unicast_address_t *FirstUnicastAddress; - ip_adapter_anycast_address_t *FirstAnycastAddress; - void *dummy2; - void *dummy3; - void *dummy4; - void *dummy5; - void *dummy6; - BYTE dummy7[8]; - DWORD dummy8; - DWORD dummy9; - DWORD dummy10; - DWORD IfType; - int OperStatus; - DWORD dummy12; - DWORD dummy13[16]; - void *dummy14; + unsigned LONG_LONG dummy0; + struct ip_adapter_addresses_st *Next; + void *dummy1; + ip_adapter_unicast_address_t *FirstUnicastAddress; + ip_adapter_anycast_address_t *FirstAnycastAddress; + void *dummy2; + void *dummy3; + void *dummy4; + void *dummy5; + void *dummy6; + BYTE dummy7[8]; + DWORD dummy8; + DWORD dummy9; + DWORD dummy10; + DWORD IfType; + int OperStatus; + DWORD dummy12; + DWORD dummy13[16]; + void *dummy14; } ip_adapter_addresses_t; typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG); HMODULE h; @@ -1801,49 +1803,49 @@ socket_s_ip_address_list(VALUE self) h = LoadLibrary("iphlpapi.dll"); if (!h) - rb_notimplement(); + rb_notimplement(); pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h, "GetAdaptersAddresses"); if (!pGetAdaptersAddresses) { - FreeLibrary(h); - rb_notimplement(); + FreeLibrary(h); + rb_notimplement(); } ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len); if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) { - errno = rb_w32_map_errno(ret); - FreeLibrary(h); - rb_sys_fail("GetAdaptersAddresses"); + errno = rb_w32_map_errno(ret); + FreeLibrary(h); + rb_sys_fail("GetAdaptersAddresses"); } adapters = (ip_adapter_addresses_t *)ALLOCA_N(BYTE, len); ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len); if (ret != ERROR_SUCCESS) { - errno = rb_w32_map_errno(ret); - FreeLibrary(h); - rb_sys_fail("GetAdaptersAddresses"); + errno = rb_w32_map_errno(ret); + FreeLibrary(h); + rb_sys_fail("GetAdaptersAddresses"); } list = rb_ary_new(); for (; adapters; adapters = adapters->Next) { - ip_adapter_unicast_address_t *uni; - ip_adapter_anycast_address_t *any; - if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */ - continue; - for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) { + ip_adapter_unicast_address_t *uni; + ip_adapter_anycast_address_t *any; + if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */ + continue; + for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) { #ifndef INET6 - if (uni->Address.lpSockaddr->sa_family == AF_INET) + if (uni->Address.lpSockaddr->sa_family == AF_INET) #else - if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family)) + if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family)) #endif - rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength)); - } - for (any = adapters->FirstAnycastAddress; any; any = any->Next) { + rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength)); + } + for (any = adapters->FirstAnycastAddress; any; any = any->Next) { #ifndef INET6 - if (any->Address.lpSockaddr->sa_family == AF_INET) + if (any->Address.lpSockaddr->sa_family == AF_INET) #else - if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family)) + if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family)) #endif - rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength)); - } + rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength)); + } } FreeLibrary(h); @@ -1854,6 +1856,67 @@ socket_s_ip_address_list(VALUE self) #define socket_s_ip_address_list rb_f_notimplement #endif +/* + * call-seq: + * Socket.tcp_fast_fallback -> true or false + * + * Returns whether Happy Eyeballs Version 2 ({RFC 8305}[https://datatracker.ietf.org/doc/html/rfc8305]), + * which is provided starting from Ruby 3.4 when using TCPSocket.new and Socket.tcp, + * is enabled or disabled. + * + * If true, it is enabled for TCPSocket.new and Socket.tcp. + * (Note: Happy Eyeballs Version 2 is not provided when using TCPSocket.new on Windows.) + * + * If false, Happy Eyeballs Version 2 is disabled. + * + * For details on Happy Eyeballs Version 2, + * see {Socket.tcp_fast_fallback=}[rdoc-ref:Socket.tcp_fast_fallback=]. + */ +VALUE socket_s_tcp_fast_fallback(VALUE self) { + return rb_ivar_get(rb_cSocket, tcp_fast_fallback); +} + +/* + * call-seq: + * Socket.tcp_fast_fallback= -> true or false + * + * Enable or disable Happy Eyeballs Version 2 ({RFC 8305}[https://datatracker.ietf.org/doc/html/rfc8305]) + * globally, which is provided starting from Ruby 3.4 when using TCPSocket.new and Socket.tcp. + * + * When set to true, the feature is enabled for both `TCPSocket.new` and `Socket.tcp`. + * (Note: This feature is not available when using TCPSocket.new on Windows.) + * + * When set to false, the behavior reverts to that of Ruby 3.3 or earlier. + * + * The default value is true if no value is explicitly set by calling this method. + * However, when the environment variable RUBY_TCP_NO_FAST_FALLBACK=1 is set, + * the default is false. + * + * To control the setting on a per-method basis, use the fast_fallback keyword argument for each method. + * + * === Happy Eyeballs Version 2 + * Happy Eyeballs Version 2 ({RFC 8305}[https://datatracker.ietf.org/doc/html/rfc8305]) + * is an algorithm designed to improve client socket connectivity.<br> + * It aims for more reliable and efficient connections by performing hostname resolution + * and connection attempts in parallel, instead of serially. + * + * Starting from Ruby 3.4, this method operates as follows with this algorithm: + * + * 1. Start resolving both IPv6 and IPv4 addresses concurrently. + * 2. Start connecting to the one of the addresses that are obtained first.<br>If IPv4 addresses are obtained first, + * the method waits 50 ms for IPv6 name resolution to prioritize IPv6 connections. + * 3. After starting a connection attempt, wait 250 ms for the connection to be established.<br> + * If no connection is established within this time, a new connection is started every 250 ms<br> + * until a connection is established or there are no more candidate addresses.<br> + * (Although RFC 8305 strictly specifies sorting addresses,<br> + * this method only alternates between IPv6 / IPv4 addresses due to the performance concerns) + * 4. Once a connection is established, all remaining connection attempts are canceled. + */ +VALUE socket_s_tcp_fast_fallback_set(VALUE self, VALUE value) { + rb_ivar_set(rb_cSocket, tcp_fast_fallback, value); + return value; +} + void Init_socket(void) { @@ -1982,12 +2045,22 @@ Init_socket(void) rsock_init_socket_init(); + const char *tcp_no_fast_fallback_config = getenv("RUBY_TCP_NO_FAST_FALLBACK"); + VALUE fast_fallback_default; + if (tcp_no_fast_fallback_config == NULL || strcmp(tcp_no_fast_fallback_config, "0") == 0) { + fast_fallback_default = Qtrue; + } else { + fast_fallback_default = Qfalse; + } + tcp_fast_fallback = rb_intern_const("tcp_fast_fallback"); + rb_ivar_set(rb_cSocket, tcp_fast_fallback, fast_fallback_default); + rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); rb_define_method(rb_cSocket, "connect", sock_connect, 1); /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__connect_nonblock", sock_connect_nonblock, 2); + "__connect_nonblock", sock_connect_nonblock, 2); rb_define_method(rb_cSocket, "bind", sock_bind, 1); rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1); @@ -1995,7 +2068,7 @@ Init_socket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__accept_nonblock", sock_accept_nonblock, 1); + "__accept_nonblock", sock_accept_nonblock, 1); rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0); @@ -2003,7 +2076,7 @@ Init_socket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__recvfrom_nonblock", sock_recvfrom_nonblock, 4); + "__recvfrom_nonblock", sock_recvfrom_nonblock, 4); rb_define_singleton_method(rb_cSocket, "socketpair", rsock_sock_s_socketpair, -1); rb_define_singleton_method(rb_cSocket, "pair", rsock_sock_s_socketpair, -1); @@ -2017,7 +2090,7 @@ Init_socket(void) rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2); rb_define_singleton_method(rb_cSocket, "pack_sockaddr_in", sock_s_pack_sockaddr_in, 2); rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_in", sock_s_unpack_sockaddr_in, 1); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_singleton_method(rb_cSocket, "sockaddr_un", sock_s_pack_sockaddr_un, 1); rb_define_singleton_method(rb_cSocket, "pack_sockaddr_un", sock_s_pack_sockaddr_un, 1); rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_un", sock_s_unpack_sockaddr_un, 1); @@ -2025,6 +2098,9 @@ Init_socket(void) rb_define_singleton_method(rb_cSocket, "ip_address_list", socket_s_ip_address_list, 0); + rb_define_singleton_method(rb_cSocket, "tcp_fast_fallback", socket_s_tcp_fast_fallback, 0); + rb_define_singleton_method(rb_cSocket, "tcp_fast_fallback=", socket_s_tcp_fast_fallback_set, 1); + #undef rb_intern sym_wait_writable = ID2SYM(rb_intern("wait_writable")); } diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c index b8b7e12998..30860ea257 100644 --- a/ext/socket/sockssocket.c +++ b/ext/socket/sockssocket.c @@ -30,11 +30,12 @@ socks_init(VALUE sock, VALUE host, VALUE port) static int init = 0; if (init == 0) { - SOCKSinit("ruby"); - init = 1; + char progname[] = "ruby"; + SOCKSinit(progname); + init = 1; } - return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil, Qnil); + return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil, Qnil, Qnil, Qfalse, Qnil); } #ifdef SOCKS5 @@ -48,7 +49,7 @@ socks_s_close(VALUE sock) rb_io_t *fptr; GetOpenFile(sock, fptr); - shutdown(fptr->fd, 2); + shutdown(fptr->fd, SHUT_RDWR); return rb_io_close(sock); } #endif diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c index 675733c6f9..0069f3c703 100644 --- a/ext/socket/tcpserver.c +++ b/ext/socket/tcpserver.c @@ -36,7 +36,7 @@ tcp_svr_init(int argc, VALUE *argv, VALUE sock) VALUE hostname, port; rb_scan_args(argc, argv, "011", &hostname, &port); - return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER, Qnil, Qnil); + return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER, Qnil, Qnil, Qnil, Qfalse, Qnil); } /* @@ -133,7 +133,7 @@ rsock_init_tcpserver(void) rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); rb_define_private_method(rb_cTCPServer, - "__accept_nonblock", tcp_accept_nonblock, 1); + "__accept_nonblock", tcp_accept_nonblock, 1); rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0); rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1); rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */ diff --git a/ext/socket/tcpsocket.c b/ext/socket/tcpsocket.c index 51e77a0de9..7ce536e0af 100644 --- a/ext/socket/tcpsocket.c +++ b/ext/socket/tcpsocket.c @@ -12,13 +12,31 @@ /* * call-seq: - * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil, connect_timeout: nil) + * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil, resolv_timeout: nil, connect_timeout: nil, open_timeout: nil, fast_fallback: true) * * Opens a TCP connection to +remote_host+ on +remote_port+. If +local_host+ * and +local_port+ are specified, then those parameters are used on the local * end to establish the connection. * - * [:connect_timeout] specify the timeout in seconds. + * Starting from Ruby 3.4, this method operates according to the + * Happy Eyeballs Version 2 ({RFC 8305}[https://datatracker.ietf.org/doc/html/rfc8305]) + * algorithm by default, except on Windows. + * + * For details on Happy Eyeballs Version 2, + * see {Socket.tcp_fast_fallback=}[rdoc-ref:Socket.tcp_fast_fallback=]. + * + * To make it behave the same as in Ruby 3.3 and earlier, + * explicitly specify the option fast_fallback:false. + * Or, setting Socket.tcp_fast_fallback=false will disable + * Happy Eyeballs Version 2 not only for this method but for all Socket globally. + * + * When using TCPSocket.new on Windows, Happy Eyeballs Version 2 is not provided, + * and it behaves the same as in Ruby 3.3 and earlier. + * + * [:resolv_timeout] Specifies the timeout in seconds from when the hostname resolution starts. + * [:connect_timeout] This method sequentially attempts connecting to all candidate destination addresses.<br>The +connect_timeout+ specifies the timeout in seconds from the start of the connection attempt to the last candidate.<br>By default, all connection attempts continue until the timeout occurs.<br>When +fast_fallback:false+ is explicitly specified,<br>a timeout is set for each connection attempt and any connection attempt that exceeds its timeout will be canceled. + * [:open_timeout] Specifies the timeout in seconds from the start of the method execution.<br>If this timeout is reached while there are still addresses that have not yet been attempted for connection, no further attempts will be made.<br>If this option is specified together with other timeout options, an +ArgumentError+ will be raised. + * [:fast_fallback] Enables the Happy Eyeballs Version 2 algorithm (enabled by default). */ static VALUE tcp_init(int argc, VALUE *argv, VALUE sock) @@ -26,28 +44,43 @@ tcp_init(int argc, VALUE *argv, VALUE sock) VALUE remote_host, remote_serv; VALUE local_host, local_serv; VALUE opt; - static ID keyword_ids[2]; - VALUE kwargs[2]; + static ID keyword_ids[5]; + VALUE kwargs[5]; VALUE resolv_timeout = Qnil; VALUE connect_timeout = Qnil; + VALUE open_timeout = Qnil; + VALUE fast_fallback = Qnil; + VALUE test_mode_settings = Qnil; if (!keyword_ids[0]) { - CONST_ID(keyword_ids[0], "resolv_timeout"); - CONST_ID(keyword_ids[1], "connect_timeout"); + CONST_ID(keyword_ids[0], "resolv_timeout"); + CONST_ID(keyword_ids[1], "connect_timeout"); + CONST_ID(keyword_ids[2], "open_timeout"); + CONST_ID(keyword_ids[3], "fast_fallback"); + CONST_ID(keyword_ids[4], "test_mode_settings"); } rb_scan_args(argc, argv, "22:", &remote_host, &remote_serv, - &local_host, &local_serv, &opt); + &local_host, &local_serv, &opt); if (!NIL_P(opt)) { - rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs); - if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; } - if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; } + rb_get_kwargs(opt, keyword_ids, 0, 5, kwargs); + if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; } + if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; } + if (kwargs[2] != Qundef) { open_timeout = kwargs[2]; } + if (kwargs[3] != Qundef) { fast_fallback = kwargs[3]; } + if (kwargs[4] != Qundef) { test_mode_settings = kwargs[4]; } + } + + if (fast_fallback == Qnil) { + fast_fallback = rb_ivar_get(rb_cSocket, tcp_fast_fallback); + if (fast_fallback == Qnil) fast_fallback = Qtrue; } return rsock_init_inetsock(sock, remote_host, remote_serv, - local_host, local_serv, INET_CLIENT, - resolv_timeout, connect_timeout); + local_host, local_serv, INET_CLIENT, + resolv_timeout, connect_timeout, open_timeout, + fast_fallback, test_mode_settings); } static VALUE @@ -80,7 +113,7 @@ tcp_s_gethostbyname(VALUE obj, VALUE host) { rb_warn("TCPSocket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); struct rb_addrinfo *res = - rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME, Qnil); return rsock_make_hostent(host, res, tcp_sockaddr); } diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index 2bfd7c8560..b2bc925538 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -33,11 +33,11 @@ udp_init(int argc, VALUE *argv, VALUE sock) int fd; if (rb_scan_args(argc, argv, "01", &arg) == 1) { - family = rsock_family_arg(arg); + family = rsock_family_arg(arg); } fd = rsock_socket(family, SOCK_DGRAM, 0); if (fd < 0) { - rb_sys_fail("socket(2) - udp"); + rb_sys_fail("socket(2) - udp"); } return rsock_init_sock(sock, fd); @@ -45,24 +45,20 @@ udp_init(int argc, VALUE *argv, VALUE sock) struct udp_arg { + VALUE io; struct rb_addrinfo *res; - rb_io_t *fptr; }; static VALUE udp_connect_internal(VALUE v) { struct udp_arg *arg = (void *)v; - rb_io_t *fptr; - int fd; struct addrinfo *res; - rb_io_check_closed(fptr = arg->fptr); - fd = fptr->fd; for (res = arg->res->ai; res; res = res->ai_next) { - if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0, NULL) >= 0) { - return Qtrue; - } + if (rsock_connect(arg->io, res->ai_addr, res->ai_addrlen, 0, RUBY_IO_TIMEOUT_DEFAULT) >= 0) { + return Qtrue; + } } return Qfalse; } @@ -84,16 +80,17 @@ udp_connect_internal(VALUE v) * */ static VALUE -udp_connect(VALUE sock, VALUE host, VALUE port) +udp_connect(VALUE self, VALUE host, VALUE port) { - struct udp_arg arg; - VALUE ret; + struct udp_arg arg = {.io = self}; + + arg.res = rsock_addrinfo(host, port, rsock_fd_family(rb_io_descriptor(self)), SOCK_DGRAM, 0, Qnil); + + int result = (int)rb_ensure(udp_connect_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); + if (!result) { + rsock_sys_fail_host_port("connect(2)", host, port); + } - GetOpenFile(sock, arg.fptr); - arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); - ret = rb_ensure(udp_connect_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); - if (!ret) rsock_sys_fail_host_port("connect(2)", host, port); return INT2FIX(0); } @@ -101,17 +98,16 @@ static VALUE udp_bind_internal(VALUE v) { struct udp_arg *arg = (void *)v; - rb_io_t *fptr; - int fd; struct addrinfo *res; - rb_io_check_closed(fptr = arg->fptr); - fd = fptr->fd; + rb_io_t *fptr; + RB_IO_POINTER(arg->io, fptr); + for (res = arg->res->ai; res; res = res->ai_next) { - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { - continue; - } - return Qtrue; + if (bind(fptr->fd, res->ai_addr, res->ai_addrlen) < 0) { + continue; + } + return Qtrue; } return Qfalse; } @@ -129,22 +125,23 @@ udp_bind_internal(VALUE v) * */ static VALUE -udp_bind(VALUE sock, VALUE host, VALUE port) +udp_bind(VALUE self, VALUE host, VALUE port) { - struct udp_arg arg; - VALUE ret; + struct udp_arg arg = {.io = self}; + + arg.res = rsock_addrinfo(host, port, rsock_fd_family(rb_io_descriptor(self)), SOCK_DGRAM, 0, Qnil); + + VALUE result = rb_ensure(udp_bind_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res); + if (!result) { + rsock_sys_fail_host_port("bind(2)", host, port); + } - GetOpenFile(sock, arg.fptr); - arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); - ret = rb_ensure(udp_bind_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); - if (!ret) rsock_sys_fail_host_port("bind(2)", host, port); return INT2FIX(0); } struct udp_send_arg { - struct rb_addrinfo *res; rb_io_t *fptr; + struct rb_addrinfo *res; struct rsock_send_arg sarg; }; @@ -166,11 +163,11 @@ udp_send_internal(VALUE v) rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); #endif - ssize_t n = (ssize_t)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg->sarg); + ssize_t n = (ssize_t)rb_io_blocking_region(fptr, rsock_sendto_blocking, &arg->sarg); if (n >= 0) return RB_SSIZE2NUM(n); - if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + if (rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { goto retry; } } @@ -207,7 +204,7 @@ udp_send(int argc, VALUE *argv, VALUE sock) VALUE ret; if (argc == 2 || argc == 3) { - return rsock_bsock_send(argc, argv, sock); + return rsock_bsock_send(argc, argv, sock); } rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port); @@ -215,9 +212,9 @@ udp_send(int argc, VALUE *argv, VALUE sock) GetOpenFile(sock, arg.fptr); arg.sarg.fd = arg.fptr->fd; arg.sarg.flags = NUM2INT(flags); - arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); + arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0, Qnil); ret = rb_ensure(udp_send_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); + rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port); return ret; } @@ -246,5 +243,5 @@ rsock_init_udpsocket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cUDPSocket, - "__recvfrom_nonblock", udp_recvfrom_nonblock, 4); + "__recvfrom_nonblock", udp_recvfrom_nonblock, 4); } diff --git a/ext/socket/unixserver.c b/ext/socket/unixserver.c index 890f9d3fae..0ea5ac083c 100644 --- a/ext/socket/unixserver.c +++ b/ext/socket/unixserver.c @@ -10,7 +10,7 @@ #include "rubysocket.h" -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: * UNIXServer.new(path) => unixserver @@ -66,7 +66,7 @@ unix_accept_nonblock(VALUE sock, VALUE ex) GetOpenFile(sock, fptr); fromlen = (socklen_t)sizeof(from); return rsock_s_accept_nonblock(rb_cUNIXSocket, ex, fptr, - (struct sockaddr *)&from, &fromlen); + (struct sockaddr *)&from, &fromlen); } /* @@ -101,7 +101,7 @@ unix_sysaccept(VALUE server) void rsock_init_unixserver(void) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * Document-class: UNIXServer < UNIXSocket * @@ -113,7 +113,7 @@ rsock_init_unixserver(void) rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); rb_define_private_method(rb_cUNIXServer, - "__accept_nonblock", unix_accept_nonblock, 1); + "__accept_nonblock", unix_accept_nonblock, 1); rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0); rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */ diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index 857cfa6002..2ec9376074 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -10,19 +10,18 @@ #include "rubysocket.h" -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN struct unixsock_arg { struct sockaddr_un *sockaddr; socklen_t sockaddrlen; - int fd; + VALUE io; }; static VALUE unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; - return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, - arg->sockaddrlen, 0, NULL); + return (VALUE)rsock_connect(arg->io, (struct sockaddr*)arg->sockaddr, arg->sockaddrlen, 0, RUBY_IO_TIMEOUT_DEFAULT); } static VALUE @@ -43,11 +42,16 @@ unixsock_path_value(VALUE path) } } #endif - return rb_get_path(path); + path = rb_get_path(path); +#ifdef _WIN32 + /* UNIXSocket requires UTF-8 per spec. */ + path = rb_str_export_to_enc(path, rb_utf8_encoding()); +#endif + return path; } VALUE -rsock_init_unixsock(VALUE sock, VALUE path, int server) +rsock_init_unixsock(VALUE self, VALUE path, int server) { struct sockaddr_un sockaddr; socklen_t sockaddrlen; @@ -66,46 +70,49 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { - rsock_sys_fail_path("socket(2)", path); + rsock_sys_fail_path("socket(2)", path); } + VALUE io = rsock_init_sock(self, fd); + RB_IO_POINTER(io, fptr); + if (server) { status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen); } else { - int prot; - struct unixsock_arg arg; - arg.sockaddr = &sockaddr; - arg.sockaddrlen = sockaddrlen; - arg.fd = fd; - status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot); - if (prot) { - close(fd); - rb_jump_tag(prot); - } + int error_tag; + struct unixsock_arg arg; + arg.sockaddr = &sockaddr; + arg.sockaddrlen = sockaddrlen; + arg.io = io; + + status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &error_tag); + + if (error_tag) { + rb_io_close(io); + rb_jump_tag(error_tag); + } } if (status < 0) { - int e = errno; - close(fd); - rsock_syserr_fail_path(e, "connect(2)", path); + int e = errno; + rb_io_close(io); + rsock_syserr_fail_path(e, "connect(2)", path); } if (server) { - if (listen(fd, SOMAXCONN) < 0) { - int e = errno; - close(fd); - rsock_syserr_fail_path(e, "listen(2)", path); - } + if (listen(fd, SOMAXCONN) < 0) { + int e = errno; + rb_io_close(io); + rsock_syserr_fail_path(e, "listen(2)", path); + } } - rsock_init_sock(sock, fd); if (server) { - GetOpenFile(sock, fptr); fptr->pathv = rb_str_new_frozen(path); } - return sock; + return io; } /* @@ -121,9 +128,9 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) * */ static VALUE -unix_init(VALUE sock, VALUE path) +unix_init(VALUE self, VALUE path) { - return rsock_init_unixsock(sock, path, 0); + return rsock_init_unixsock(self, path, 0); } /* @@ -143,13 +150,13 @@ unix_path(VALUE sock) GetOpenFile(sock, fptr); if (NIL_P(fptr->pathv)) { - struct sockaddr_un addr; - socklen_t len = (socklen_t)sizeof(addr); - socklen_t len0 = len; - if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) + struct sockaddr_un addr; + socklen_t len = (socklen_t)sizeof(addr); + socklen_t len0 = len; + if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rsock_sys_fail_path("getsockname(2)", fptr->pathv); if (len0 < len) len = len0; - fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len)); + fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len)); } return rb_str_dup(fptr->pathv); } @@ -240,21 +247,21 @@ unix_send_io(VALUE sock, VALUE val) #if FD_PASSING_BY_MSG_CONTROL union { - struct cmsghdr hdr; - char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; + struct cmsghdr hdr; + char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; } cmsg; #endif if (rb_obj_is_kind_of(val, rb_cIO)) { rb_io_t *valfptr; - GetOpenFile(val, valfptr); - fd = valfptr->fd; + GetOpenFile(val, valfptr); + fd = valfptr->fd; } else if (FIXNUM_P(val)) { fd = FIX2INT(val); } else { - rb_raise(rb_eTypeError, "neither IO nor file descriptor"); + rb_raise(rb_eTypeError, "neither IO nor file descriptor"); } GetOpenFile(sock, fptr); @@ -284,9 +291,9 @@ unix_send_io(VALUE sock, VALUE val) #endif arg.fd = fptr->fd; - while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) { - if (!rb_io_wait_writable(arg.fd)) - rsock_sys_fail_path("sendmsg(2)", fptr->pathv); + while ((int)rb_io_blocking_region(fptr, sendmsg_blocking, &arg) == -1) { + if (!rb_io_wait_writable(arg.fd)) + rsock_sys_fail_path("sendmsg(2)", fptr->pathv); } return Qnil; @@ -348,16 +355,16 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) int fd; #if FD_PASSING_BY_MSG_CONTROL union { - struct cmsghdr hdr; - char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; + struct cmsghdr hdr; + char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; } cmsg; #endif rb_scan_args(argc, argv, "02", &klass, &mode); if (argc == 0) - klass = rb_cIO; + klass = rb_cIO; if (argc <= 1) - mode = Qnil; + mode = Qnil; retry: GetOpenFile(sock, fptr); @@ -386,7 +393,7 @@ retry: #endif arg.fd = fptr->fd; - while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) { + while ((int)rb_io_blocking_region(fptr, recvmsg_blocking, &arg) == -1) { int e = errno; if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) { /* FreeBSD gets here when we're out of FDs */ @@ -400,8 +407,8 @@ retry: rb_gc_for_fd(e); goto retry; } - if (!rb_io_wait_readable(arg.fd)) - rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv); + if (!rb_io_wait_readable(arg.fd)) + rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv); } #if FD_PASSING_BY_MSG_CONTROL @@ -412,41 +419,41 @@ retry: rb_gc_for_fd(EMFILE); goto retry; } - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)", - (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr)); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)", + (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr)); } if (cmsg.hdr.cmsg_level != SOL_SOCKET) { - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_level=%d, %d expected)", - cmsg.hdr.cmsg_level, SOL_SOCKET); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_level=%d, %d expected)", + cmsg.hdr.cmsg_level, SOL_SOCKET); } if (cmsg.hdr.cmsg_type != SCM_RIGHTS) { - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_type=%d, %d expected)", - cmsg.hdr.cmsg_type, SCM_RIGHTS); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_type=%d, %d expected)", + cmsg.hdr.cmsg_type, SCM_RIGHTS); } if (arg.msg.msg_controllen < (socklen_t)CMSG_LEN(sizeof(int))) { - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", - (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", + (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); } if ((socklen_t)CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) { - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", - (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", + (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); } if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) { - rsock_discard_cmsg_resource(&arg.msg, 0); - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_len=%d, %d expected)", - (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); + rsock_discard_cmsg_resource(&arg.msg, 0); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_len=%d, %d expected)", + (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); } #else if (arg.msg.msg_accrightslen != sizeof(fd)) { - rb_raise(rb_eSocket, - "file descriptor was not passed (accrightslen=%d, %d expected)", - arg.msg.msg_accrightslen, (int)sizeof(fd)); + rb_raise(rb_eSocket, + "file descriptor was not passed (accrightslen=%d, %d expected)", + arg.msg.msg_accrightslen, (int)sizeof(fd)); } #endif @@ -458,15 +465,15 @@ retry: rb_maygvl_fd_fix_cloexec(fd); if (klass == Qnil) - return INT2FIX(fd); + return INT2FIX(fd); else { - ID for_fd; - int ff_argc; - VALUE ff_argv[2]; - CONST_ID(for_fd, "for_fd"); - ff_argc = mode == Qnil ? 1 : 2; - ff_argv[0] = INT2FIX(fd); - ff_argv[1] = mode; + ID for_fd; + int ff_argc; + VALUE ff_argv[2]; + CONST_ID(for_fd, "for_fd"); + ff_argc = mode == Qnil ? 1 : 2; + ff_argv[0] = INT2FIX(fd); + ff_argv[1] = mode; return rb_funcallv(klass, for_fd, ff_argc, ff_argv); } } @@ -536,7 +543,7 @@ unix_peeraddr(VALUE sock) * * Creates a pair of sockets connected to each other. * - * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. + * _type_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. * * _protocol_ should be a protocol defined in the domain. * 0 is default protocol for the domain. @@ -556,9 +563,9 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) domain = INT2FIX(PF_UNIX); rb_scan_args(argc, argv, "02", &type, &protocol); if (argc == 0) - type = INT2FIX(SOCK_STREAM); + type = INT2FIX(SOCK_STREAM); if (argc <= 1) - protocol = INT2FIX(0); + protocol = INT2FIX(0); args[0] = domain; args[1] = type; @@ -571,7 +578,7 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) void rsock_init_unixsocket(void) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * Document-class: UNIXSocket < BasicSocket * diff --git a/ext/stringio/.document b/ext/stringio/.document new file mode 100644 index 0000000000..decba0135a --- /dev/null +++ b/ext/stringio/.document @@ -0,0 +1 @@ +*.[ch] diff --git a/ext/stringio/depend b/ext/stringio/depend index da20efe131..3a82ad0a11 100644 --- a/ext/stringio/depend +++ b/ext/stringio/depend @@ -7,7 +7,6 @@ stringio.o: $(hdrdir)/ruby/backward.h stringio.o: $(hdrdir)/ruby/backward/2/assume.h stringio.o: $(hdrdir)/ruby/backward/2/attributes.h stringio.o: $(hdrdir)/ruby/backward/2/bool.h -stringio.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h stringio.o: $(hdrdir)/ruby/backward/2/inttypes.h stringio.o: $(hdrdir)/ruby/backward/2/limits.h stringio.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ stringio.o: $(hdrdir)/ruby/backward/2/stdarg.h stringio.o: $(hdrdir)/ruby/defines.h stringio.o: $(hdrdir)/ruby/encoding.h stringio.o: $(hdrdir)/ruby/intern.h +stringio.o: $(hdrdir)/ruby/internal/abi.h stringio.o: $(hdrdir)/ruby/internal/anyargs.h stringio.o: $(hdrdir)/ruby/internal/arithmetic.h stringio.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ stringio.o: $(hdrdir)/ruby/internal/attr/noexcept.h stringio.o: $(hdrdir)/ruby/internal/attr/noinline.h stringio.o: $(hdrdir)/ruby/internal/attr/nonnull.h stringio.o: $(hdrdir)/ruby/internal/attr/noreturn.h +stringio.o: $(hdrdir)/ruby/internal/attr/packed_struct.h stringio.o: $(hdrdir)/ruby/internal/attr/pure.h stringio.o: $(hdrdir)/ruby/internal/attr/restrict.h stringio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ stringio.o: $(hdrdir)/ruby/internal/intern/enumerator.h stringio.o: $(hdrdir)/ruby/internal/intern/error.h stringio.o: $(hdrdir)/ruby/internal/intern/eval.h stringio.o: $(hdrdir)/ruby/internal/intern/file.h -stringio.o: $(hdrdir)/ruby/internal/intern/gc.h stringio.o: $(hdrdir)/ruby/internal/intern/hash.h stringio.o: $(hdrdir)/ruby/internal/intern/io.h stringio.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ stringio.o: $(hdrdir)/ruby/internal/intern/re.h stringio.o: $(hdrdir)/ruby/internal/intern/ruby.h stringio.o: $(hdrdir)/ruby/internal/intern/select.h stringio.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +stringio.o: $(hdrdir)/ruby/internal/intern/set.h stringio.o: $(hdrdir)/ruby/internal/intern/signal.h stringio.o: $(hdrdir)/ruby/internal/intern/sprintf.h stringio.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ stringio.o: $(hdrdir)/ruby/internal/memory.h stringio.o: $(hdrdir)/ruby/internal/method.h stringio.o: $(hdrdir)/ruby/internal/module.h stringio.o: $(hdrdir)/ruby/internal/newobj.h -stringio.o: $(hdrdir)/ruby/internal/rgengc.h stringio.o: $(hdrdir)/ruby/internal/scan_args.h stringio.o: $(hdrdir)/ruby/internal/special_consts.h stringio.o: $(hdrdir)/ruby/internal/static_assert.h stringio.o: $(hdrdir)/ruby/internal/stdalign.h stringio.o: $(hdrdir)/ruby/internal/stdbool.h +stringio.o: $(hdrdir)/ruby/internal/stdckdint.h stringio.o: $(hdrdir)/ruby/internal/symbol.h stringio.o: $(hdrdir)/ruby/internal/value.h stringio.o: $(hdrdir)/ruby/internal/value_type.h @@ -171,5 +172,6 @@ stringio.o: $(hdrdir)/ruby/oniguruma.h stringio.o: $(hdrdir)/ruby/ruby.h stringio.o: $(hdrdir)/ruby/st.h stringio.o: $(hdrdir)/ruby/subst.h +stringio.o: $(hdrdir)/ruby/version.h stringio.o: stringio.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/stringio/extconf.rb b/ext/stringio/extconf.rb index a933159766..0089766983 100644 --- a/ext/stringio/extconf.rb +++ b/ext/stringio/extconf.rb @@ -1,4 +1,9 @@ # frozen_string_literal: false require 'mkmf' -have_func("rb_io_extract_modeenc", "ruby/io.h") -create_makefile('stringio') +if RUBY_ENGINE == 'ruby' + have_type("rb_io_mode_t", "ruby/io.h") + + create_makefile('stringio') +else + File.write('Makefile', dummy_makefile("").join) +end diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 295650e89e..cc2294a795 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -12,11 +12,15 @@ **********************************************************************/ -#define STRINGIO_VERSION "3.0.0" +static const char *const +STRINGIO_VERSION = "3.2.1.dev"; + +#include <stdbool.h> #include "ruby.h" #include "ruby/io.h" #include "ruby/encoding.h" +#include "ruby/version.h" #if defined(HAVE_FCNTL_H) || defined(_WIN32) #include <fcntl.h> #elif defined(HAVE_SYS_FCNTL_H) @@ -32,79 +36,21 @@ # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass) #endif -#ifndef HAVE_RB_IO_EXTRACT_MODEENC -#define rb_io_extract_modeenc strio_extract_modeenc -static void -strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, - int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p) +static inline bool +str_chilled_p(VALUE str) { - VALUE mode = *vmode_p; - VALUE intmode; - int fmode; - int has_enc = 0, has_vmode = 0; - - convconfig_p->enc = convconfig_p->enc2 = 0; - - vmode_handle: - if (NIL_P(mode)) { - fmode = FMODE_READABLE; - } - else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) { - int flags = NUM2INT(intmode); - fmode = rb_io_oflags_fmode(flags); - } - else { - const char *m = StringValueCStr(mode), *n, *e; - fmode = rb_io_modestr_fmode(m); - n = strchr(m, ':'); - if (n) { - long len; - char encname[ENCODING_MAXNAMELEN+1]; - has_enc = 1; - if (fmode & FMODE_SETENC_BY_BOM) { - n = strchr(n, '|'); - } - e = strchr(++n, ':'); - len = e ? e - n : (long)strlen(n); - if (len > 0 && len <= ENCODING_MAXNAMELEN) { - if (e) { - memcpy(encname, n, len); - encname[len] = '\0'; - n = encname; - } - convconfig_p->enc = rb_enc_find(n); - } - if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) { - convconfig_p->enc2 = rb_enc_find(e); - } - } - } - - if (!NIL_P(opthash)) { - rb_encoding *extenc = 0, *intenc = 0; - VALUE v; - if (!has_vmode) { - ID id_mode; - CONST_ID(id_mode, "mode"); - v = rb_hash_aref(opthash, ID2SYM(id_mode)); - if (!NIL_P(v)) { - if (!NIL_P(mode)) { - rb_raise(rb_eArgError, "mode specified twice"); - } - has_vmode = 1; - mode = v; - goto vmode_handle; - } - } - - if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) { - if (has_enc) { - rb_raise(rb_eArgError, "encoding specified twice"); - } - } - } - *fmode_p = fmode; +#if (RUBY_API_VERSION_MAJOR == 3 && RUBY_API_VERSION_MINOR >= 4) || RUBY_API_VERSION_MAJOR >= 4 + // Do not attempt to modify chilled strings on Ruby 3.4+ + // RUBY_FL_USER2 == STR_CHILLED_LITERAL + // RUBY_FL_USER3 == STR_CHILLED_SYMBOL_TO_S + return FL_TEST_RAW(str, RUBY_FL_USER2 | RUBY_FL_USER3); +#else + return false; +#endif } + +#ifndef HAVE_TYPE_RB_IO_MODE_T +typedef int rb_io_mode_t; #endif struct StringIO { @@ -112,7 +58,7 @@ struct StringIO { rb_encoding *enc; long pos; long lineno; - int flags; + rb_io_mode_t flags; int count; }; @@ -122,7 +68,13 @@ static long strio_write(VALUE self, VALUE str); #define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type)) #define error_inval(msg) (rb_syserr_fail(EINVAL, msg)) -#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string)) +#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : !NIL_P((ptr)->string) ? rb_enc_get((ptr)->string) : NULL) + +static bool +readonly_string_p(VALUE string) +{ + return OBJ_FROZEN_RAW(string); +} static struct StringIO * strio_alloc(void) @@ -166,7 +118,7 @@ static const rb_data_type_t strio_data_type = { strio_free, strio_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; #define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type)) @@ -240,9 +192,27 @@ writable(VALUE strio) static void check_modifiable(struct StringIO *ptr) { - if (OBJ_FROZEN(ptr->string)) { + if (NIL_P(ptr->string)) { + /* Null device StringIO */ + } + else if (OBJ_FROZEN_RAW(ptr->string)) { rb_raise(rb_eIOError, "not modifiable string"); } + else { + rb_str_modify(ptr->string); + } +} + +static inline bool +outside_p(struct StringIO *ptr, long pos) +{ + return NIL_P(ptr->string) || pos >= RSTRING_LEN(ptr->string); +} + +static inline bool +eos_p(struct StringIO *ptr) +{ + return outside_p(ptr, ptr->pos); } static VALUE @@ -252,9 +222,35 @@ strio_s_allocate(VALUE klass) } /* - * call-seq: StringIO.new(string=""[, mode]) + * call-seq: + * StringIO.new(string = '', mode = 'r+') -> new_stringio + * + * Returns a new \StringIO instance formed from +string+ and +mode+; + * the instance should be closed when no longer needed: + * + * strio = StringIO.new + * strio.string # => "" + * strio.closed_read? # => false + * strio.closed_write? # => false + * strio.close + * + * If +string+ is frozen, the default +mode+ is <tt>'r'</tt>: + * + * strio = StringIO.new('foo'.freeze) + * strio.string # => "foo" + * strio.closed_read? # => false + * strio.closed_write? # => true + * strio.close + * + * Argument +mode+ must be a valid + * {Access Mode}[rdoc-ref:File@Access+Modes], + * which may be a string or an integer constant: + * + * StringIO.new('foo', 'w+') + * StringIO.new('foo', File::RDONLY) * - * Creates new StringIO instance from with _string_ and _mode_. + * Related: StringIO.open + * (passes the \StringIO object to the block; closes the object automatically on block exit). */ static VALUE strio_initialize(int argc, VALUE *argv, VALUE self) @@ -340,17 +336,18 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self) { VALUE string, vmode, opt; int oflags; - struct rb_io_enc_t convconfig; + rb_io_enc_t convconfig; argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt); rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig); - if (argc) { + if (!NIL_P(string)) { StringValue(string); } - else { + else if (!argc) { string = rb_enc_str_new("", 0, rb_default_external_encoding()); } - if (OBJ_FROZEN_RAW(string)) { + + if (!NIL_P(string) && readonly_string_p(string)) { if (ptr->flags & FMODE_WRITABLE) { rb_syserr_fail(EACCES, 0); } @@ -360,11 +357,11 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self) ptr->flags |= FMODE_WRITABLE; } } - if (ptr->flags & FMODE_TRUNC) { + if (!NIL_P(string) && (ptr->flags & FMODE_TRUNC)) { rb_str_resize(string, 0); } - ptr->string = string; - if (argc == 1) { + RB_OBJ_WRITE(self, &ptr->string, string); + if (argc == 1 && !NIL_P(string)) { ptr->enc = rb_enc_get(string); } else { @@ -381,17 +378,29 @@ static VALUE strio_finalize(VALUE self) { struct StringIO *ptr = StringIO(self); - ptr->string = Qnil; + RB_OBJ_WRITE(self, &ptr->string, Qnil); ptr->flags &= ~FMODE_READWRITE; return self; } /* - * call-seq: StringIO.open(string=""[, mode]) {|strio| ...} + * call-seq: + * StringIO.open(string = '', mode = 'r+') -> new_stringio + * StringIO.open(string = '', mode = 'r+') {|strio| ... } -> object + * + * Creates new \StringIO instance by calling <tt>StringIO.new(string, mode)</tt>. + * + * With no block given, returns the new instance: * - * Equivalent to StringIO.new except that when it is called with a block, it - * yields with the new instance and closes it, and returns the result which - * returned from the block. + * strio = StringIO.open # => #<StringIO> + * + * With a block given, calls the block with the new instance + * and returns the block's value; + * closes the instance on block exit: + * + * StringIO.open('foo') {|strio| strio.string.upcase } # => "FOO" + * + * Related: StringIO.new. */ static VALUE strio_s_open(int argc, VALUE *argv, VALUE klass) @@ -415,7 +424,7 @@ strio_s_new(int argc, VALUE *argv, VALUE klass) } /* - * Returns +false+. Just for compatibility to IO. + * Returns +false+; for compatibility with IO. */ static VALUE strio_false(VALUE self) @@ -425,7 +434,7 @@ strio_false(VALUE self) } /* - * Returns +nil+. Just for compatibility to IO. + * Returns +nil+; for compatibility with IO. */ static VALUE strio_nil(VALUE self) @@ -435,7 +444,7 @@ strio_nil(VALUE self) } /* - * Returns an object itself. Just for compatibility to IO. + * Returns +self+; for compatibility with IO. */ static VALUE strio_self(VALUE self) @@ -445,7 +454,7 @@ strio_self(VALUE self) } /* - * Returns 0. Just for compatibility to IO. + * Returns 0; for compatibility with IO. */ static VALUE strio_0(VALUE self) @@ -477,9 +486,23 @@ strio_unimpl(int argc, VALUE *argv, VALUE self) } /* - * call-seq: strio.string -> string + * call-seq: + * string -> string + * + * Returns underlying string: * - * Returns underlying String object, the subject of IO. + * StringIO.open('foo') do |strio| + * p strio.string + * strio.string = 'bar' + * p strio.string + * end + * + * Output: + * + * "foo" + * "bar" + * + * Related: StringIO#string= (assigns the underlying string). */ static VALUE strio_get_string(VALUE self) @@ -489,9 +512,23 @@ strio_get_string(VALUE self) /* * call-seq: - * strio.string = string -> string + * string = other_string -> other_string + * + * Replaces the stored string with +other_string+, and sets the position to zero; + * returns +other_string+: + * + * StringIO.open('foo') do |strio| + * p strio.string + * strio.string = 'bar' + * p strio.string + * end + * + * Output: * - * Changes underlying String object, the subject of IO. + * "foo" + * "bar" + * + * Related: StringIO#string (returns the stored string). */ static VALUE strio_set_string(VALUE self, VALUE string) @@ -501,18 +538,27 @@ strio_set_string(VALUE self, VALUE string) rb_io_taint_check(self); ptr->flags &= ~FMODE_READWRITE; StringValue(string); - ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE; + ptr->flags = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE; ptr->pos = 0; ptr->lineno = 0; - return ptr->string = string; + RB_OBJ_WRITE(self, &ptr->string, string); + return string; } /* * call-seq: - * strio.close -> nil + * close -> nil + * + * Closes +self+ for both reading and writing; returns +nil+: + * + * strio = StringIO.new + * strio.closed? # => false + * strio.close # => nil + * strio.closed? # => true + * strio.read # Raises IOError: not opened for reading + * strio.write # Raises IOError: not opened for writing * - * Closes a StringIO. The stream is unavailable for any further data - * operations; an +IOError+ is raised if such an attempt is made. + * Related: StringIO#close_read, StringIO#close_write, StringIO.closed?. */ static VALUE strio_close(VALUE self) @@ -524,10 +570,20 @@ strio_close(VALUE self) /* * call-seq: - * strio.close_read -> nil + * close_read -> nil + * + * Closes +self+ for reading; + * closed-write setting remains unchanged; + * returns +nil+: + * + * strio = StringIO.new + * strio.closed_read? # => false + * strio.close_read # => nil + * strio.closed_read? # => true + * strio.closed_write? # => false + * strio.read # Raises IOError: not opened for reading * - * Closes the read end of a StringIO. Will raise an +IOError+ if the - * receiver is not readable. + * Related: StringIO#close, StringIO#close_write. */ static VALUE strio_close_read(VALUE self) @@ -542,10 +598,18 @@ strio_close_read(VALUE self) /* * call-seq: - * strio.close_write -> nil + * close_write -> nil * - * Closes the write end of a StringIO. Will raise an +IOError+ if the - * receiver is not writeable. + * Closes +self+ for writing; closed-read setting remains unchanged; returns +nil+: + * + * strio = StringIO.new + * strio.closed_write? # => false + * strio.close_write # => nil + * strio.closed_write? # => true + * strio.closed_read? # => false + * strio.write('foo') # Raises IOError: not opened for writing + * + * Related: StringIO#close, StringIO#close_read, StringIO#closed_write?. */ static VALUE strio_close_write(VALUE self) @@ -560,9 +624,18 @@ strio_close_write(VALUE self) /* * call-seq: - * strio.closed? -> true or false + * closed? -> true or false + * + * Returns whether +self+ is closed for both reading and writing: * - * Returns +true+ if the stream is completely closed, +false+ otherwise. + * strio = StringIO.new + * strio.closed? # => false # Open for reading and writing. + * strio.close_read + * strio.closed? # => false # Still open for writing. + * strio.close_write + * strio.closed? # => true # Now closed for both. + * + * Related: StringIO.closed_read?, StringIO.closed_write?. */ static VALUE strio_closed(VALUE self) @@ -574,9 +647,16 @@ strio_closed(VALUE self) /* * call-seq: - * strio.closed_read? -> true or false + * closed_read? -> true or false + * + * Returns whether +self+ is closed for reading: + * + * strio = StringIO.new + * strio.closed_read? # => false + * strio.close_read + * strio.closed_read? # => true * - * Returns +true+ if the stream is not readable, +false+ otherwise. + * Related: StringIO#closed?, StringIO#closed_write?, StringIO#close_read. */ static VALUE strio_closed_read(VALUE self) @@ -588,9 +668,16 @@ strio_closed_read(VALUE self) /* * call-seq: - * strio.closed_write? -> true or false + * closed_write? -> true or false * - * Returns +true+ if the stream is not writable, +false+ otherwise. + * Returns whether +self+ is closed for writing: + * + * strio = StringIO.new + * strio.closed_write? # => false + * strio.close_write + * strio.closed_write? # => true + * + * Related: StringIO#close_write, StringIO#closed?, StringIO#closed_read?. */ static VALUE strio_closed_write(VALUE self) @@ -604,17 +691,26 @@ static struct StringIO * strio_to_read(VALUE self) { struct StringIO *ptr = readable(self); - if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr; - return NULL; + if (eos_p(ptr)) return NULL; + return ptr; } /* * call-seq: - * strio.eof -> true or false - * strio.eof? -> true or false + * eof? -> true or false + * + * Returns whether +self+ is positioned at end-of-stream: + * + * strio = StringIO.new('foo') + * strio.pos # => 0 + * strio.eof? # => false + * strio.read # => "foo" + * strio.pos # => 3 + * strio.eof? # => true + * strio.close_read + * strio.eof? # Raises IOError: not opened for reading * - * Returns true if the stream is at the end of the data (underlying string). - * The stream must be opened for reading or an +IOError+ will be raised. + * Related: StringIO#pos. */ static VALUE strio_eof(VALUE self) @@ -627,15 +723,19 @@ strio_eof(VALUE self) static VALUE strio_copy(VALUE copy, VALUE orig) { - struct StringIO *ptr; + struct StringIO *ptr, *old_ptr; + VALUE old_string = Qundef; orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio"); if (copy == orig) return copy; ptr = StringIO(orig); - if (check_strio(copy)) { - strio_free(DATA_PTR(copy)); + old_ptr = check_strio(copy); + if (old_ptr) { + old_string = old_ptr->string; + strio_free(old_ptr); } DATA_PTR(copy) = ptr; + RB_OBJ_WRITTEN(copy, old_string, ptr->string); RBASIC(copy)->flags &= ~STRIO_READWRITE; RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE; ++ptr->count; @@ -644,13 +744,10 @@ strio_copy(VALUE copy, VALUE orig) /* * call-seq: - * strio.lineno -> integer + * lineno -> current_line_number * - * Returns the current line number. The stream must be - * opened for reading. +lineno+ counts the number of times +gets+ is - * called, rather than the number of newlines encountered. The two - * values will differ if +gets+ is called with a separator other than - * newline. See also the <code>$.</code> variable. + * Returns the current line number in +self+; + * see {Line Number}[rdoc-ref:StringIO@Line+Number]. */ static VALUE strio_get_lineno(VALUE self) @@ -660,10 +757,10 @@ strio_get_lineno(VALUE self) /* * call-seq: - * strio.lineno = integer -> integer + * lineno = new_line_number -> new_line_number * - * Manually sets the current line number to the given value. - * <code>$.</code> is updated only on the next read. + * Sets the current line number in +self+ to the given +new_line_number+; + * see {Line Number}[rdoc-ref:StringIO@Line+Number]. */ static VALUE strio_set_lineno(VALUE self, VALUE lineno) @@ -674,9 +771,10 @@ strio_set_lineno(VALUE self, VALUE lineno) /* * call-seq: - * strio.binmode -> stringio + * binmode -> self * - * Puts stream into binary mode. See IO#binmode. + * Sets the data mode in +self+ to binary mode; + * see {Data Mode}[rdoc-ref:StringIO@Data+Mode]. * */ static VALUE @@ -700,11 +798,27 @@ strio_binmode(VALUE self) /* * call-seq: - * strio.reopen(other_StrIO) -> strio - * strio.reopen(string, mode) -> strio + * reopen(other, mode = 'r+') -> self + * + * Reinitializes the stream with the given +other+ (string or StringIO) and +mode+; + * see IO.new: + * + * StringIO.open('foo') do |strio| + * p strio.string + * strio.reopen('bar') + * p strio.string + * other_strio = StringIO.new('baz') + * strio.reopen(other_strio) + * p strio.string + * other_strio.close + * end + * + * Output: + * + * "foo" + * "bar" + * "baz" * - * Reinitializes the stream with the given <i>other_StrIO</i> or _string_ - * and _mode_ (see StringIO#new). */ static VALUE strio_reopen(int argc, VALUE *argv, VALUE self) @@ -718,10 +832,10 @@ strio_reopen(int argc, VALUE *argv, VALUE self) /* * call-seq: - * strio.pos -> integer - * strio.tell -> integer + * pos -> stream_position * - * Returns the current offset (in bytes). + * Returns the current position (in bytes); + * see {Position}[rdoc-ref:StringIO@Position]. */ static VALUE strio_get_pos(VALUE self) @@ -731,9 +845,10 @@ strio_get_pos(VALUE self) /* * call-seq: - * strio.pos = integer -> integer + * pos = new_position -> new_position * - * Seeks to the given position (in bytes). + * Sets the current position (in bytes); + * see {Position}[rdoc-ref:StringIO@Position]. */ static VALUE strio_set_pos(VALUE self, VALUE pos) @@ -749,10 +864,11 @@ strio_set_pos(VALUE self, VALUE pos) /* * call-seq: - * strio.rewind -> 0 + * rewind -> 0 * - * Positions the stream to the beginning of input, resetting - * +lineno+ to zero. + * Sets the current position and line number to zero; + * see {Position}[rdoc-ref:IO@Position] + * and {Line Number}[rdoc-ref:IO@Line+Number]. */ static VALUE strio_rewind(VALUE self) @@ -765,10 +881,11 @@ strio_rewind(VALUE self) /* * call-seq: - * strio.seek(amount, whence=SEEK_SET) -> 0 + * seek(offset, whence = SEEK_SET) -> 0 * - * Seeks to a given offset _amount_ in the stream according to - * the value of _whence_ (see IO#seek). + * Sets the position to the given integer +offset+ (in bytes), + * with respect to a given constant +whence+; + * see {IO#seek}[rdoc-ref:IO#seek]. */ static VALUE strio_seek(int argc, VALUE *argv, VALUE self) @@ -790,7 +907,11 @@ strio_seek(int argc, VALUE *argv, VALUE self) offset = ptr->pos; break; case 2: - offset = RSTRING_LEN(ptr->string); + if (NIL_P(ptr->string)) { + offset = 0; + } else { + offset = RSTRING_LEN(ptr->string); + } break; default: error_inval("invalid whence"); @@ -804,9 +925,9 @@ strio_seek(int argc, VALUE *argv, VALUE self) /* * call-seq: - * strio.sync -> true + * sync -> true * - * Returns +true+ always. + * Returns +true+; implemented only for compatibility with other stream classes. */ static VALUE strio_get_sync(VALUE self) @@ -821,10 +942,11 @@ strio_get_sync(VALUE self) /* * call-seq: - * strio.each_byte {|byte| block } -> strio - * strio.each_byte -> anEnumerator + * each_byte {|byte| ... } -> self + * + * :include: stringio/each_byte.rdoc * - * See IO#each_byte. + * Related: StringIO#each_char, StringIO#each_codepoint, StringIO#each_line. */ static VALUE strio_each_byte(VALUE self) @@ -842,9 +964,10 @@ strio_each_byte(VALUE self) /* * call-seq: - * strio.getc -> string or nil + * getc -> character, byte, or nil + * + * :include: stringio/getc.rdoc * - * See IO#getc. */ static VALUE strio_getc(VALUE self) @@ -856,7 +979,7 @@ strio_getc(VALUE self) int len; char *p; - if (pos >= RSTRING_LEN(str)) { + if (eos_p(ptr)) { return Qnil; } p = RSTRING_PTR(str)+pos; @@ -867,16 +990,17 @@ strio_getc(VALUE self) /* * call-seq: - * strio.getbyte -> fixnum or nil + * getbyte -> integer or nil + * + * :include: stringio/getbyte.rdoc * - * See IO#getbyte. */ static VALUE strio_getbyte(VALUE self) { struct StringIO *ptr = readable(self); int c; - if (ptr->pos >= RSTRING_LEN(ptr->string)) { + if (eos_p(ptr)) { return Qnil; } c = RSTRING_PTR(ptr->string)[ptr->pos++]; @@ -898,19 +1022,26 @@ strio_extend(struct StringIO *ptr, long pos, long len) if (pos > olen) MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen); } - else { - rb_str_modify(ptr->string); +} + +static void +strio_unget_string(struct StringIO *ptr, VALUE c) +{ + const char *cp = NULL; + long cl = RSTRING_LEN(c); + if (cl > 0) { + if (c != ptr->string) cp = RSTRING_PTR(c); + strio_unget_bytes(ptr, cp, cl); + RB_GC_GUARD(c); } } /* * call-seq: - * strio.ungetc(string) -> nil + * ungetc(character) -> nil * - * Pushes back one character (passed as a parameter) - * such that a subsequent buffered read will return it. There is no - * limitation for multiple pushbacks including pushing back behind the - * beginning of the buffer string. + * Pushes back ("unshifts") a character or integer onto the stream; + * see {Character IO}[rdoc-ref:IO@Character+IO]. */ static VALUE strio_ungetc(VALUE self, VALUE c) @@ -919,6 +1050,7 @@ strio_ungetc(VALUE self, VALUE c) rb_encoding *enc, *enc2; check_modifiable(ptr); + if (NIL_P(ptr->string)) return Qnil; if (NIL_P(c)) return Qnil; if (RB_INTEGER_TYPE_P(c)) { int len, cc = NUM2INT(c); @@ -926,28 +1058,32 @@ strio_ungetc(VALUE self, VALUE c) enc = rb_enc_get(ptr->string); len = rb_enc_codelen(cc, enc); - if (len <= 0) rb_enc_uint_chr(cc, enc); + if (len <= 0) { + rb_enc_uint_chr(cc, enc); /* to raise an exception */ + UNREACHABLE; + } rb_enc_mbcput(cc, buf, enc); return strio_unget_bytes(ptr, buf, len); } else { - SafeStringValue(c); + StringValue(c); + if (RSTRING_LEN(c) == 0) return Qnil; enc = rb_enc_get(ptr->string); enc2 = rb_enc_get(c); if (enc != enc2 && enc != rb_ascii8bit_encoding()) { c = rb_str_conv_enc(c, enc2, enc); } - strio_unget_bytes(ptr, RSTRING_PTR(c), RSTRING_LEN(c)); - RB_GC_GUARD(c); + strio_unget_string(ptr, c); return Qnil; } } /* * call-seq: - * strio.ungetbyte(fixnum) -> nil + * ungetbyte(byte) -> nil * - * See IO#ungetbyte + * Pushes back ("unshifts") an 8-bit byte onto the stream; + * see {Byte IO}[rdoc-ref:IO@Byte+IO]. */ static VALUE strio_ungetbyte(VALUE self, VALUE c) @@ -955,21 +1091,17 @@ strio_ungetbyte(VALUE self, VALUE c) struct StringIO *ptr = readable(self); check_modifiable(ptr); + if (NIL_P(ptr->string)) return Qnil; if (NIL_P(c)) return Qnil; if (RB_INTEGER_TYPE_P(c)) { - /* rb_int_and() not visible from exts */ - VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff)); - const char cc = NUM2INT(v) & 0xFF; - strio_unget_bytes(ptr, &cc, 1); + /* rb_int_and() not visible from exts */ + VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff)); + const char cc = NUM2INT(v) & 0xFF; + strio_unget_bytes(ptr, &cc, 1); } else { - long cl; - SafeStringValue(c); - cl = RSTRING_LEN(c); - if (cl > 0) { - strio_unget_bytes(ptr, RSTRING_PTR(c), cl); - RB_GC_GUARD(c); - } + StringValue(c); + strio_unget_string(ptr, c); } return Qnil; } @@ -984,7 +1116,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl) len = RSTRING_LEN(str); rest = pos - len; if (cl > pos) { - long ex = (rest < 0 ? cl-pos : cl+rest); + long ex = cl - (rest < 0 ? pos : len); rb_str_modify_expand(str, ex); rb_str_set_len(str, len + ex); s = RSTRING_PTR(str); @@ -1000,16 +1132,17 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl) if (rest > cl) memset(s + len, 0, rest - cl); pos -= cl; } - memcpy(s + pos, cp, cl); + memcpy(s + pos, (cp ? cp : s), cl); ptr->pos = pos; return Qnil; } /* * call-seq: - * strio.readchar -> string + * readchar -> string * - * See IO#readchar. + * Like +getc+, but raises an exception if already at end-of-stream; + * see {Character IO}[rdoc-ref:IO@Character+IO]. */ static VALUE strio_readchar(VALUE self) @@ -1021,9 +1154,10 @@ strio_readchar(VALUE self) /* * call-seq: - * strio.readbyte -> fixnum + * readbyte -> byte * - * See IO#readbyte. + * Like +getbyte+, but raises an exception if already at end-of-stream; + * see {Byte IO}[rdoc-ref:IO@Byte+IO]. */ static VALUE strio_readbyte(VALUE self) @@ -1035,10 +1169,11 @@ strio_readbyte(VALUE self) /* * call-seq: - * strio.each_char {|char| block } -> strio - * strio.each_char -> anEnumerator + * each_char {|char| ... } -> self * - * See IO#each_char. + * :include: stringio/each_char.rdoc + * + * Related: StringIO#each_byte, StringIO#each_codepoint, StringIO#each_line. */ static VALUE strio_each_char(VALUE self) @@ -1055,10 +1190,11 @@ strio_each_char(VALUE self) /* * call-seq: - * strio.each_codepoint {|c| block } -> strio - * strio.each_codepoint -> anEnumerator + * each_codepoint {|codepoint| ... } -> self + * + * :include: stringio/each_codepoint.rdoc * - * See IO#each_codepoint. + * Related: StringIO#each_byte, StringIO#each_char, StringIO#each_line. */ static VALUE strio_each_codepoint(VALUE self) @@ -1121,36 +1257,57 @@ struct getline_arg { }; static struct getline_arg * -prepare_getline_args(struct getline_arg *arg, int argc, VALUE *argv) +prepare_getline_args(struct StringIO *ptr, struct getline_arg *arg, int argc, VALUE *argv) { - VALUE str, lim, opts; + VALUE rs, lim, opts; long limit = -1; + int respect_chomp; - argc = rb_scan_args(argc, argv, "02:", &str, &lim, &opts); + argc = rb_scan_args(argc, argv, "02:", &rs, &lim, &opts); + respect_chomp = argc == 0 || !NIL_P(rs); switch (argc) { case 0: - str = rb_rs; + rs = rb_rs; break; case 1: - if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) { - VALUE tmp = rb_check_string_type(str); + if (!NIL_P(rs) && !RB_TYPE_P(rs, T_STRING)) { + VALUE tmp = rb_check_string_type(rs); if (NIL_P(tmp)) { - limit = NUM2LONG(str); - str = rb_rs; + limit = NUM2LONG(rs); + rs = rb_rs; } else { - str = tmp; + rs = tmp; } } break; case 2: - if (!NIL_P(str)) StringValue(str); + if (!NIL_P(rs)) StringValue(rs); if (!NIL_P(lim)) limit = NUM2LONG(lim); break; } - arg->rs = str; + if (!NIL_P(ptr->string) && !NIL_P(rs)) { + rb_encoding *enc_rs, *enc_io; + enc_rs = rb_enc_get(rs); + enc_io = get_enc(ptr); + if (enc_rs != enc_io && + (rb_enc_str_coderange(rs) != ENC_CODERANGE_7BIT || + (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) { + if (rs == rb_rs) { + rs = rb_enc_str_new(0, 0, enc_io); + rb_str_buf_cat_ascii(rs, "\n"); + rs = rs; + } + else { + rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS", + rb_enc_name(enc_io), + rb_enc_name(enc_rs)); + } + } + } + arg->rs = rs; arg->limit = limit; arg->chomp = 0; if (!NIL_P(opts)) { @@ -1160,7 +1317,9 @@ prepare_getline_args(struct getline_arg *arg, int argc, VALUE *argv) keywords[0] = rb_intern_const("chomp"); } rb_get_kwargs(opts, keywords, 0, 1, &vchomp); - arg->chomp = (vchomp != Qundef) && RTEST(vchomp); + if (respect_chomp) { + arg->chomp = (vchomp != Qundef) && RTEST(vchomp); + } } return arg; } @@ -1181,10 +1340,10 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) const char *s, *e, *p; long n, limit = arg->limit; VALUE str = arg->rs; - int w = 0; + long w = 0; rb_encoding *enc = get_enc(ptr); - if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) { + if (NIL_P(ptr->string) || ptr->pos >= (n = RSTRING_LEN(ptr->string))) { return Qnil; } s = RSTRING_PTR(ptr->string); @@ -1200,6 +1359,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) str = strio_substr(ptr, ptr->pos, e - s - w, enc); } else if ((n = RSTRING_LEN(str)) == 0) { + const char *paragraph_end = NULL; p = s; while (p[(p + 1 < e) && (*p == '\r') && 0] == '\n') { p += *p == '\r'; @@ -1209,19 +1369,21 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) } s = p; while ((p = memchr(p, '\n', e - p)) && (p != e)) { - if (*++p == '\n') { - e = p + 1; - w = (arg->chomp ? 1 : 0); - break; + p++; + if (!((p < e && *p == '\n') || + (p + 1 < e && *p == '\r' && *(p+1) == '\n'))) { + continue; } - else if (*p == '\r' && p < e && p[1] == '\n') { - e = p + 2; - w = (arg->chomp ? 2 : 0); - break; + paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1); + while ((p < e && *p == '\n') || + (p + 1 < e && *p == '\r' && *(p+1) == '\n')) { + p += (*p == '\r') ? 2 : 1; } + e = p; + break; } - if (!w && arg->chomp) { - w = chomp_newline_width(s, e); + if (arg->chomp && paragraph_end) { + w = e - paragraph_end; } str = strio_substr(ptr, s - RSTRING_PTR(ptr->string), e - s - w, enc); } @@ -1233,11 +1395,13 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) str = strio_substr(ptr, ptr->pos, e - s - w, enc); } else { - if (n < e - s) { - if (e - s < 1024) { + if (n < e - s + arg->chomp) { + /* unless chomping, RS at the end does not matter */ + if (e - s < 1024 || n == e - s) { for (p = s; p + n <= e; ++p) { if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) { - e = p + (arg->chomp ? 0 : n); + e = p + n; + w = (arg->chomp ? n : 0); break; } } @@ -1260,35 +1424,38 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) /* * call-seq: - * strio.gets(sep=$/, chomp: false) -> string or nil - * strio.gets(limit, chomp: false) -> string or nil - * strio.gets(sep, limit, chomp: false) -> string or nil + * gets(sep = $/, chomp: false) -> string or nil + * gets(limit, chomp: false) -> string or nil + * gets(sep, limit, chomp: false) -> string or nil + * + * :include: stringio/gets.rdoc * - * See IO#gets. */ static VALUE strio_gets(int argc, VALUE *argv, VALUE self) { + struct StringIO *ptr = readable(self); struct getline_arg arg; VALUE str; - if (prepare_getline_args(&arg, argc, argv)->limit == 0) { - struct StringIO *ptr = readable(self); + if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) { + if (NIL_P(ptr->string)) return Qnil; return rb_enc_str_new(0, 0, get_enc(ptr)); } - str = strio_getline(&arg, readable(self)); + str = strio_getline(&arg, ptr); rb_lastline_set(str); return str; } /* * call-seq: - * strio.readline(sep=$/, chomp: false) -> string - * strio.readline(limit, chomp: false) -> string or nil - * strio.readline(sep, limit, chomp: false) -> string or nil + * readline(sep = $/, chomp: false) -> string + * readline(limit, chomp: false) -> string + * readline(sep, limit, chomp: false) -> string * - * See IO#readline. + * Reads a line as with IO#gets, but raises EOFError if already at end-of-file; + * see {Line IO}[rdoc-ref:IO@Line+IO]. */ static VALUE strio_readline(int argc, VALUE *argv, VALUE self) @@ -1299,33 +1466,30 @@ strio_readline(int argc, VALUE *argv, VALUE self) } /* + * :markup: markdown + * * call-seq: - * strio.each(sep=$/, chomp: false) {|line| block } -> strio - * strio.each(limit, chomp: false) {|line| block } -> strio - * strio.each(sep, limit, chomp: false) {|line| block } -> strio - * strio.each(...) -> anEnumerator + * each_line(sep = $/, chomp: false) {|line| ... } -> self + * each_line(limit, chomp: false) {|line| ... } -> self + * each_line(sep, limit, chomp: false) {|line| ... } -> self * - * strio.each_line(sep=$/, chomp: false) {|line| block } -> strio - * strio.each_line(limit, chomp: false) {|line| block } -> strio - * strio.each_line(sep, limit, chomp: false) {|line| block } -> strio - * strio.each_line(...) -> anEnumerator + * :include: stringio/each_line.md * - * See IO#each. */ static VALUE strio_each(int argc, VALUE *argv, VALUE self) { VALUE line; + struct StringIO *ptr = readable(self); struct getline_arg arg; - StringIO(self); RETURN_ENUMERATOR(self, argc, argv); - if (prepare_getline_args(&arg, argc, argv)->limit == 0) { + if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) { rb_raise(rb_eArgError, "invalid limit: 0 for each_line"); } - while (!NIL_P(line = strio_getline(&arg, readable(self)))) { + while (!NIL_P(line = strio_getline(&arg, ptr))) { rb_yield(line); } return self; @@ -1343,15 +1507,15 @@ static VALUE strio_readlines(int argc, VALUE *argv, VALUE self) { VALUE ary, line; + struct StringIO *ptr = readable(self); struct getline_arg arg; - StringIO(self); - ary = rb_ary_new(); - if (prepare_getline_args(&arg, argc, argv)->limit == 0) { + if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) { rb_raise(rb_eArgError, "invalid limit: 0 for readlines"); } - while (!NIL_P(line = strio_getline(&arg, readable(self)))) { + ary = rb_ary_new(); + while (!NIL_P(line = strio_getline(&arg, ptr))) { rb_ary_push(ary, line); } return ary; @@ -1390,6 +1554,7 @@ strio_write(VALUE self, VALUE str) if (!RB_TYPE_P(str, T_STRING)) str = rb_obj_as_string(str); enc = get_enc(ptr); + if (!enc) return 0; enc2 = rb_enc_get(str); if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) { VALUE converted = rb_str_conv_enc(str, enc2, enc); @@ -1415,6 +1580,7 @@ strio_write(VALUE self, VALUE str) } else { strio_extend(ptr, ptr->pos, len); + rb_str_modify(ptr->string); memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len); } RB_GC_GUARD(str); @@ -1449,9 +1615,10 @@ strio_write(VALUE self, VALUE str) /* * call-seq: - * strio.putc(obj) -> obj + * putc(object) -> object + * + * :include: stringio/putc.rdoc * - * See IO#putc. */ static VALUE strio_putc(VALUE self, VALUE ch) @@ -1461,10 +1628,12 @@ strio_putc(VALUE self, VALUE ch) check_modifiable(ptr); if (RB_TYPE_P(ch, T_STRING)) { + if (NIL_P(ptr->string)) return ch; str = rb_str_substr(ch, 0, 1); } else { char c = NUM2CHR(ch); + if (NIL_P(ptr->string)) return ch; str = rb_str_new(&c, 1); } strio_write(self, str); @@ -1481,9 +1650,10 @@ strio_putc(VALUE self, VALUE ch) /* * call-seq: - * strio.read([length [, outbuf]]) -> string, outbuf, or nil + * read(maxlen = nil, out_string = nil) → new_string, out_string, or nil + * + * :include: stringio/read.rdoc * - * See IO#read. */ static VALUE strio_read(int argc, VALUE *argv, VALUE self) @@ -1507,15 +1677,16 @@ strio_read(int argc, VALUE *argv, VALUE self) if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } - if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) { + if (eos_p(ptr)) { if (!NIL_P(str)) rb_str_resize(str, 0); - return Qnil; + return len > 0 ? Qnil : rb_str_new(0, 0); } binary = 1; break; } /* fall through */ case 0: + if (NIL_P(ptr->string)) return Qnil; len = RSTRING_LEN(ptr->string); if (len <= ptr->pos) { rb_encoding *enc = get_enc(ptr); @@ -1533,7 +1704,7 @@ strio_read(int argc, VALUE *argv, VALUE self) } break; default: - rb_error_arity(argc, 0, 2); + rb_error_arity(argc, 0, 2); } if (NIL_P(str)) { rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr); @@ -1544,16 +1715,64 @@ strio_read(int argc, VALUE *argv, VALUE self) if (len > rest) len = rest; rb_str_resize(str, len); MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len); - if (binary) - rb_enc_associate(str, rb_ascii8bit_encoding()); - else + if (!binary) { rb_enc_copy(str, ptr->string); + } } ptr->pos += RSTRING_LEN(str); return str; } /* + * call-seq: + * pread(maxlen, offset, out_string = nil) -> new_string or out_string + * + * :include: stringio/pread.rdoc + * + */ +static VALUE +strio_pread(int argc, VALUE *argv, VALUE self) +{ + VALUE rb_len, rb_offset, rb_buf; + rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf); + long len = NUM2LONG(rb_len); + long offset = NUM2LONG(rb_offset); + + if (len < 0) { + rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len); + } + + if (len == 0) { + if (NIL_P(rb_buf)) { + return rb_str_new("", 0); + } + return rb_buf; + } + + if (offset < 0) { + rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset)); + } + + struct StringIO *ptr = readable(self); + + if (outside_p(ptr, offset)) { + rb_eof_error(); + } + + if (NIL_P(rb_buf)) { + return strio_substr(ptr, offset, len, rb_ascii8bit_encoding()); + } + + long rest = RSTRING_LEN(ptr->string) - offset; + if (len > rest) len = rest; + rb_str_resize(rb_buf, len); + rb_enc_associate(rb_buf, rb_ascii8bit_encoding()); + MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len); + return rb_buf; +} + + +/* * call-seq: * strio.sysread(integer[, outbuf]) -> string * strio.readpartial(integer[, outbuf]) -> string @@ -1601,8 +1820,14 @@ strio_read_nonblock(int argc, VALUE *argv, VALUE self) return val; } +/* + * See IO#write + */ #define strio_syswrite rb_io_write +/* + * See IO#write_nonblock + */ static VALUE strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self) { @@ -1620,17 +1845,17 @@ strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self) /* * call-seq: - * strio.length -> integer - * strio.size -> integer + * size -> integer + * + * :include: stringio/size.rdoc * - * Returns the size of the buffer string. */ static VALUE strio_size(VALUE self) { VALUE string = StringIO(self)->string; if (NIL_P(string)) { - rb_raise(rb_eIOError, "not opened"); + return INT2FIX(0); } return ULONG2NUM(RSTRING_LEN(string)); } @@ -1647,24 +1872,34 @@ strio_truncate(VALUE self, VALUE len) { VALUE string = writable(self)->string; long l = NUM2LONG(len); - long plen = RSTRING_LEN(string); + long plen; if (l < 0) { error_inval("negative length"); } + if (NIL_P(string)) return 0; + plen = RSTRING_LEN(string); rb_str_resize(string, l); if (plen < l) { MEMZERO(RSTRING_PTR(string) + plen, char, l - plen); } - return len; + return INT2FIX(0); } /* - * call-seq: - * strio.external_encoding => encoding + * call-seq: + * external_encoding -> encoding or nil + * + * Returns an Encoding object that represents the encoding of the string; + * see {Encodings}[rdoc-ref:StringIO@Encodings]: + * + * strio = StringIO.new('foo') + * strio.external_encoding # => #<Encoding:UTF-8> + * + * Returns +nil+ if +self+ has no string and is in write mode: + * + * strio = StringIO.new(nil, 'w+') + * strio.external_encoding # => nil * - * Returns the Encoding object that represents the encoding of the file. - * If the stream is write mode and no encoding is specified, returns - * +nil+. */ static VALUE @@ -1676,10 +1911,9 @@ strio_external_encoding(VALUE self) /* * call-seq: - * strio.internal_encoding => encoding + * internal_encoding -> nil * - * Returns the Encoding of the internal string if conversion is - * specified. Otherwise returns +nil+. + * Returns +nil+; for compatibility with IO. */ static VALUE @@ -1711,16 +1945,33 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self) enc = rb_default_external_encoding(); } else { - enc = rb_to_encoding(ext_enc); + enc = rb_find_encoding(ext_enc); + if (!enc) { + rb_io_enc_t convconfig; + int oflags; + rb_io_mode_t fmode; + VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc); + rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig); + enc = convconfig.enc2; + } } ptr->enc = enc; - if (WRITABLE(self)) { + if (!NIL_P(ptr->string) && WRITABLE(self) && !str_chilled_p(ptr->string)) { rb_enc_associate(ptr->string, enc); } return self; } +/* + * call-seq: + * strio.set_encoding_by_bom => strio or nil + * + * Sets the encoding according to the BOM (Byte Order Mark) in the + * string. + * + * Returns +self+ if the BOM is found, otherwise +nil. + */ static VALUE strio_set_encoding_by_bom(VALUE self) { @@ -1731,24 +1982,9 @@ strio_set_encoding_by_bom(VALUE self) } /* - * Pseudo I/O on String object, with interface corresponding to IO. - * - * Commonly used to simulate <code>$stdio</code> or <code>$stderr</code> + * :markup: markdown * - * === Examples - * - * require 'stringio' - * - * # Writing stream emulation - * io = StringIO.new - * io.puts "Hello World" - * io.string #=> "Hello World\n" - * - * # Reading stream emulation - * io = StringIO.new "first\nsecond\nlast\n" - * io.getc #=> "f" - * io.gets #=> "irst\n" - * io.read #=> "second\nlast\n" + * :include: stringio/stringio.md */ void Init_stringio(void) @@ -1756,15 +1992,20 @@ Init_stringio(void) #undef rb_intern #ifdef HAVE_RB_EXT_RACTOR_SAFE - rb_ext_ractor_safe(true); + rb_ext_ractor_safe(true); #endif VALUE StringIO = rb_define_class("StringIO", rb_cObject); + /* The version string */ rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION)); rb_include_module(StringIO, rb_mEnumerable); rb_define_alloc_func(StringIO, strio_s_allocate); + + /* Maximum length that a StringIO instance can hold */ + rb_define_const(StringIO, "MAX_LENGTH", LONG2NUM(LONG_MAX)); + rb_define_singleton_method(StringIO, "new", strio_s_new, -1); rb_define_singleton_method(StringIO, "open", strio_s_open, -1); rb_define_method(StringIO, "initialize", strio_initialize, -1); @@ -1814,6 +2055,7 @@ Init_stringio(void) rb_define_method(StringIO, "gets", strio_gets, -1); rb_define_method(StringIO, "readlines", strio_readlines, -1); rb_define_method(StringIO, "read", strio_read, -1); + rb_define_method(StringIO, "pread", strio_pread, -1); rb_define_method(StringIO, "write", strio_write_m, -1); rb_define_method(StringIO, "putc", strio_putc, 1); @@ -1842,7 +2084,9 @@ Init_stringio(void) rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0); { + /* :stopdoc: */ VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable"); + /* :startdoc: */ rb_define_method(mReadable, "readchar", strio_readchar, 0); rb_define_method(mReadable, "readbyte", strio_readbyte, 0); rb_define_method(mReadable, "readline", strio_readline, -1); @@ -1852,7 +2096,9 @@ Init_stringio(void) rb_include_module(StringIO, mReadable); } { + /* :stopdoc: */ VALUE mWritable = rb_define_module_under(rb_cIO, "generic_writable"); + /* :startdoc: */ rb_define_method(mWritable, "<<", strio_addstr, 1); rb_define_method(mWritable, "print", strio_print, -1); rb_define_method(mWritable, "printf", strio_printf, -1); diff --git a/ext/stringio/stringio.gemspec b/ext/stringio/stringio.gemspec index 524d976cfb..f9a0742049 100644 --- a/ext/stringio/stringio.gemspec +++ b/ext/stringio/stringio.gemspec @@ -1,10 +1,10 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- # frozen_string_literal: true source_version = ["", "ext/stringio/"].find do |dir| begin break File.open(File.join(__dir__, "#{dir}stringio.c")) {|f| - f.gets("\n#define STRINGIO_VERSION ") + f.gets("\nSTRINGIO_VERSION ") f.gets[/\s*"(.+)"/, 1] } rescue Errno::ENOENT @@ -14,18 +14,33 @@ Gem::Specification.new do |s| s.name = "stringio" s.version = source_version - s.required_rubygems_version = Gem::Requirement.new(">= 2.6") s.require_paths = ["lib"] - s.authors = ["Nobu Nakada"] + s.authors = ["Nobu Nakada", "Charles Oliver Nutter"] s.description = "Pseudo `IO` class from/to `String`." - s.email = "nobu@ruby-lang.org" - s.extensions = ["ext/stringio/extconf.rb"] - s.files = ["README.md", "ext/stringio/extconf.rb", "ext/stringio/stringio.c"] + s.email = ["nobu@ruby-lang.org", "headius@headius.com"] + s.files = ["README.md"] + jruby = true if Gem::Platform.new('java') =~ s.platform or RUBY_ENGINE == 'jruby' + if jruby + s.require_paths = "lib/java" + s.files += ["lib/java/stringio.rb", "lib/java/stringio.jar"] + s.platform = "java" + else + s.extensions = ["ext/stringio/extconf.rb"] + s.files += ["ext/stringio/extconf.rb", "ext/stringio/stringio.c"] + end + + s.extra_rdoc_files = [ + ".document", ".rdoc_options", "COPYING", "LICENSE.txt", + "NEWS.md", "README.md", "docs/io.rb", "ext/stringio/.document", + ] + s.homepage = "https://github.com/ruby/stringio" s.licenses = ["Ruby", "BSD-2-Clause"] - s.required_ruby_version = ">= 2.5" + s.required_ruby_version = ">= 2.7" s.summary = "Pseudo IO on String" + s.metadata["changelog_uri"] = "#{s.homepage}/releases/tag/v#{s.version}" + # s.cert_chain = %w[certs/nobu.pem] # s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/ end diff --git a/ext/strscan/depend b/ext/strscan/depend index 5605a72359..b40a025230 100644 --- a/ext/strscan/depend +++ b/ext/strscan/depend @@ -6,7 +6,6 @@ strscan.o: $(hdrdir)/ruby/backward.h strscan.o: $(hdrdir)/ruby/backward/2/assume.h strscan.o: $(hdrdir)/ruby/backward/2/attributes.h strscan.o: $(hdrdir)/ruby/backward/2/bool.h -strscan.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h strscan.o: $(hdrdir)/ruby/backward/2/inttypes.h strscan.o: $(hdrdir)/ruby/backward/2/limits.h strscan.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -15,6 +14,7 @@ strscan.o: $(hdrdir)/ruby/backward/2/stdarg.h strscan.o: $(hdrdir)/ruby/defines.h strscan.o: $(hdrdir)/ruby/encoding.h strscan.o: $(hdrdir)/ruby/intern.h +strscan.o: $(hdrdir)/ruby/internal/abi.h strscan.o: $(hdrdir)/ruby/internal/anyargs.h strscan.o: $(hdrdir)/ruby/internal/arithmetic.h strscan.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -52,6 +52,7 @@ strscan.o: $(hdrdir)/ruby/internal/attr/noexcept.h strscan.o: $(hdrdir)/ruby/internal/attr/noinline.h strscan.o: $(hdrdir)/ruby/internal/attr/nonnull.h strscan.o: $(hdrdir)/ruby/internal/attr/noreturn.h +strscan.o: $(hdrdir)/ruby/internal/attr/packed_struct.h strscan.o: $(hdrdir)/ruby/internal/attr/pure.h strscan.o: $(hdrdir)/ruby/internal/attr/restrict.h strscan.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ strscan.o: $(hdrdir)/ruby/internal/intern/enumerator.h strscan.o: $(hdrdir)/ruby/internal/intern/error.h strscan.o: $(hdrdir)/ruby/internal/intern/eval.h strscan.o: $(hdrdir)/ruby/internal/intern/file.h -strscan.o: $(hdrdir)/ruby/internal/intern/gc.h strscan.o: $(hdrdir)/ruby/internal/intern/hash.h strscan.o: $(hdrdir)/ruby/internal/intern/io.h strscan.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ strscan.o: $(hdrdir)/ruby/internal/intern/re.h strscan.o: $(hdrdir)/ruby/internal/intern/ruby.h strscan.o: $(hdrdir)/ruby/internal/intern/select.h strscan.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +strscan.o: $(hdrdir)/ruby/internal/intern/set.h strscan.o: $(hdrdir)/ruby/internal/intern/signal.h strscan.o: $(hdrdir)/ruby/internal/intern/sprintf.h strscan.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ strscan.o: $(hdrdir)/ruby/internal/memory.h strscan.o: $(hdrdir)/ruby/internal/method.h strscan.o: $(hdrdir)/ruby/internal/module.h strscan.o: $(hdrdir)/ruby/internal/newobj.h -strscan.o: $(hdrdir)/ruby/internal/rgengc.h strscan.o: $(hdrdir)/ruby/internal/scan_args.h strscan.o: $(hdrdir)/ruby/internal/special_consts.h strscan.o: $(hdrdir)/ruby/internal/static_assert.h strscan.o: $(hdrdir)/ruby/internal/stdalign.h strscan.o: $(hdrdir)/ruby/internal/stdbool.h +strscan.o: $(hdrdir)/ruby/internal/stdckdint.h strscan.o: $(hdrdir)/ruby/internal/symbol.h strscan.o: $(hdrdir)/ruby/internal/value.h strscan.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/strscan/extconf.rb b/ext/strscan/extconf.rb index f0ecbf85d8..d2e9343cbc 100644 --- a/ext/strscan/extconf.rb +++ b/ext/strscan/extconf.rb @@ -1,5 +1,11 @@ # frozen_string_literal: true require 'mkmf' -$INCFLAGS << " -I$(top_srcdir)" if $extmk -have_func("onig_region_memsize", "ruby.h") -create_makefile 'strscan' +if RUBY_ENGINE == 'ruby' + $INCFLAGS << " -I$(top_srcdir)" if $extmk + have_func("onig_region_memsize(NULL)") + have_func("rb_reg_onig_match", "ruby/re.h") + have_func("rb_deprecate_constant") + create_makefile 'strscan' +else + File.write('Makefile', dummy_makefile("").join) +end diff --git a/ext/strscan/lib/strscan/strscan.rb b/ext/strscan/lib/strscan/strscan.rb new file mode 100644 index 0000000000..46acc7ea82 --- /dev/null +++ b/ext/strscan/lib/strscan/strscan.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class StringScanner + # call-seq: + # scan_integer(base: 10) + # + # If `base` isn't provided or is `10`, then it is equivalent to calling `#scan` with a `[+-]?\d+` pattern, + # and returns an Integer or nil. + # + # If `base` is `16`, then it is equivalent to calling `#scan` with a `[+-]?(0x)?[0-9a-fA-F]+` pattern, + # and returns an Integer or nil. + # + # The scanned string must be encoded with an ASCII compatible encoding, otherwise + # Encoding::CompatibilityError will be raised. + def scan_integer(base: 10) + case base + when 10 + scan_base10_integer + when 16 + scan_base16_integer + else + raise ArgumentError, "Unsupported integer base: #{base.inspect}, expected 10 or 16" + end + end +end diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index 42027cd8d2..935fce19df 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -22,7 +22,15 @@ extern size_t onig_region_memsize(const struct re_registers *regs); #include <stdbool.h> -#define STRSCAN_VERSION "3.0.0" +#define STRSCAN_VERSION "3.1.7.dev" + + +#ifdef HAVE_RB_DEPRECATE_CONSTANT +/* In ruby 3.0, defined but exposed in external headers */ +extern void rb_deprecate_constant(VALUE mod, const char *name); +#else +# define rb_deprecate_constant(mod, name) ((void)0) +#endif /* ======================================================================= Data Type Definitions @@ -30,7 +38,8 @@ extern size_t onig_region_memsize(const struct re_registers *regs); static VALUE StringScanner; static VALUE ScanError; -static ID id_byteslice; + +static int usascii_encindex, utf8_encindex, binary_encindex; struct strscanner { @@ -56,8 +65,13 @@ struct strscanner }; #define MATCHED_P(s) ((s)->flags & FLAG_MATCHED) -#define MATCHED(s) (s)->flags |= FLAG_MATCHED -#define CLEAR_MATCH_STATUS(s) (s)->flags &= ~FLAG_MATCHED +#define MATCHED(s) ((s)->flags |= FLAG_MATCHED) +#define CLEAR_MATCHED(s) ((s)->flags &= ~FLAG_MATCHED) +#define CLEAR_NAMED_CAPTURES(s) ((s)->regex = Qnil) +#define CLEAR_MATCH_STATUS(s) do {\ + CLEAR_MATCHED(s);\ + CLEAR_NAMED_CAPTURES(s);\ +} while (0) #define S_PBEG(s) (RSTRING_PTR((s)->str)) #define S_LEN(s) (RSTRING_LEN((s)->str)) @@ -90,7 +104,6 @@ static VALUE strscan_init_copy _((VALUE vself, VALUE vorig)); static VALUE strscan_s_mustc _((VALUE self)); static VALUE strscan_terminate _((VALUE self)); -static VALUE strscan_clear _((VALUE self)); static VALUE strscan_get_string _((VALUE self)); static VALUE strscan_set_string _((VALUE self, VALUE str)); static VALUE strscan_concat _((VALUE self, VALUE str)); @@ -112,13 +125,11 @@ static VALUE strscan_search_full _((VALUE self, VALUE re, static void adjust_registers_to_matched _((struct strscanner *p)); static VALUE strscan_getch _((VALUE self)); static VALUE strscan_get_byte _((VALUE self)); -static VALUE strscan_getbyte _((VALUE self)); static VALUE strscan_peek _((VALUE self, VALUE len)); -static VALUE strscan_peep _((VALUE self, VALUE len)); +static VALUE strscan_scan_base10_integer _((VALUE self)); static VALUE strscan_unscan _((VALUE self)); static VALUE strscan_bol_p _((VALUE self)); static VALUE strscan_eos_p _((VALUE self)); -static VALUE strscan_empty_p _((VALUE self)); static VALUE strscan_rest_p _((VALUE self)); static VALUE strscan_matched_p _((VALUE self)); static VALUE strscan_matched _((VALUE self)); @@ -201,7 +212,7 @@ strscan_memsize(const void *ptr) static const rb_data_type_t strscanner_type = { "StringScanner", {strscan_mark, strscan_free, strscan_memsize}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; static VALUE @@ -213,21 +224,32 @@ strscan_s_allocate(VALUE klass) CLEAR_MATCH_STATUS(p); onig_region_init(&(p->regs)); p->str = Qnil; - p->regex = Qnil; return obj; } /* - * call-seq: - * StringScanner.new(string, fixed_anchor: false) - * StringScanner.new(string, dup = false) - * - * Creates a new StringScanner object to scan over the given +string+. + * :markup: markdown + * :include: strscan/link_refs.txt * - * If +fixed_anchor+ is +true+, +\A+ always matches the beginning of - * the string. Otherwise, +\A+ always matches the current position. + * call-seq: + * StringScanner.new(string, fixed_anchor: false) -> string_scanner + * + * Returns a new `StringScanner` object whose [stored string][1] + * is the given `string`; + * sets the [fixed-anchor property][10]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.string # => "foobarbaz" + * scanner.fixed_anchor? # => false + * put_situation(scanner) + * # Situation: + * # pos: 0 + * # charpos: 0 + * # rest: "foobarbaz" + * # rest_size: 9 + * ``` * - * +dup+ argument is obsolete and not used now. */ static VALUE strscan_initialize(int argc, VALUE *argv, VALUE self) @@ -254,7 +276,7 @@ strscan_initialize(int argc, VALUE *argv, VALUE self) p->fixed_anchor_p = false; } StringValue(str); - p->str = str; + RB_OBJ_WRITE(self, &p->str, str); return self; } @@ -266,11 +288,14 @@ check_strscan(VALUE obj) } /* + * :markup: markdown + * :include: strscan/link_refs.txt + * * call-seq: - * dup - * clone + * dup -> shallow_copy * - * Duplicates a StringScanner object. + * Returns a shallow copy of `self`; + * the [stored string][1] in the copy is the same string as in `self`. */ static VALUE strscan_init_copy(VALUE vself, VALUE vorig) @@ -281,7 +306,7 @@ strscan_init_copy(VALUE vself, VALUE vorig) orig = check_strscan(vorig); if (self != orig) { self->flags = orig->flags; - self->str = orig->str; + RB_OBJ_WRITE(vself, &self->str, orig->str); self->prev = orig->prev; self->curr = orig->curr; if (rb_reg_region_copy(&self->regs, &orig->regs)) @@ -297,10 +322,13 @@ strscan_init_copy(VALUE vself, VALUE vorig) ======================================================================= */ /* - * call-seq: StringScanner.must_C_version + * call-seq: + * StringScanner.must_C_version -> self * - * This method is defined for backward compatibility. + * Returns +self+; defined for backward compatibility. */ + + /* :nodoc: */ static VALUE strscan_s_mustc(VALUE self) { @@ -308,7 +336,30 @@ strscan_s_mustc(VALUE self) } /* - * Reset the scan pointer (index 0) and clear matching data. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * reset -> self + * + * Sets both [byte position][2] and [character position][7] to zero, + * and clears [match values][9]; + * returns +self+: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.exist?(/bar/) # => 6 + * scanner.reset # => #<StringScanner 0/9 @ "fooba..."> + * put_situation(scanner) + * # Situation: + * # pos: 0 + * # charpos: 0 + * # rest: "foobarbaz" + * # rest_size: 9 + * # => nil + * match_values_cleared?(scanner) # => true + * ``` + * */ static VALUE strscan_reset(VALUE self) @@ -322,11 +373,9 @@ strscan_reset(VALUE self) } /* - * call-seq: - * terminate - * clear - * - * Sets the scan pointer to the end of the string and clear matching data. + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/terminate.md */ static VALUE strscan_terminate(VALUE self) @@ -340,18 +389,21 @@ strscan_terminate(VALUE self) } /* - * Equivalent to #terminate. - * This method is obsolete; use #terminate instead. - */ -static VALUE -strscan_clear(VALUE self) -{ - rb_warning("StringScanner#clear is obsolete; use #terminate instead"); - return strscan_terminate(self); -} - -/* - * Returns the string being scanned. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * string -> stored_string + * + * Returns the [stored string][1]: + * + * ```rb + * scanner = StringScanner.new('foobar') + * scanner.string # => "foobar" + * scanner.concat('baz') + * scanner.string # => "foobarbaz" + * ``` + * */ static VALUE strscan_get_string(VALUE self) @@ -363,10 +415,39 @@ strscan_get_string(VALUE self) } /* - * call-seq: string=(str) + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * string = other_string -> other_string + * + * Replaces the [stored string][1] with the given `other_string`: + * + * - Sets both [positions][11] to zero. + * - Clears [match values][9]. + * - Returns `other_string`. + * + * ```rb + * scanner = StringScanner.new('foobar') + * scanner.scan(/foo/) + * put_situation(scanner) + * # Situation: + * # pos: 3 + * # charpos: 3 + * # rest: "bar" + * # rest_size: 3 + * match_values_cleared?(scanner) # => false + * + * scanner.string = 'baz' # => "baz" + * put_situation(scanner) + * # Situation: + * # pos: 0 + * # charpos: 0 + * # rest: "baz" + * # rest_size: 3 + * match_values_cleared?(scanner) # => true + * ``` * - * Changes the string being scanned to +str+ and resets the scanner. - * Returns +str+. */ static VALUE strscan_set_string(VALUE self, VALUE str) @@ -374,25 +455,40 @@ strscan_set_string(VALUE self, VALUE str) struct strscanner *p = check_strscan(self); StringValue(str); - p->str = str; + RB_OBJ_WRITE(self, &p->str, str); p->curr = 0; CLEAR_MATCH_STATUS(p); return str; } /* - * call-seq: - * concat(str) - * <<(str) + * :markup: markdown + * :include: strscan/link_refs.txt * - * Appends +str+ to the string being scanned. - * This method does not affect scan pointer. + * call-seq: + * concat(more_string) -> self + * + * - Appends the given `more_string` + * to the [stored string][1]. + * - Returns `self`. + * - Does not affect the [positions][11] + * or [match values][9]. + * + * + * ```rb + * scanner = StringScanner.new('foo') + * scanner.string # => "foo" + * scanner.terminate + * scanner.concat('barbaz') # => #<StringScanner 3/9 "foo" @ "barba..."> + * scanner.string # => "foobarbaz" + * put_situation(scanner) + * # Situation: + * # pos: 3 + * # charpos: 3 + * # rest: "barbaz" + * # rest_size: 6 + * ``` * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan(/Fri /) - * s << " +1000 GMT" - * s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT" - * s.scan(/Dec/) # -> "Dec" */ static VALUE strscan_concat(VALUE self, VALUE str) @@ -406,18 +502,9 @@ strscan_concat(VALUE self, VALUE str) } /* - * Returns the byte position of the scan pointer. In the 'reset' position, this - * value is zero. In the 'terminated' position (i.e. the string is exhausted), - * this value is the bytesize of the string. - * - * In short, it's a 0-based index into bytes of the string. - * - * s = StringScanner.new('test string') - * s.pos # -> 0 - * s.scan_until /str/ # -> "test str" - * s.pos # -> 8 - * s.terminate # -> #<StringScanner fin> - * s.pos # -> 11 + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/get_pos.md */ static VALUE strscan_get_pos(VALUE self) @@ -425,21 +512,13 @@ strscan_get_pos(VALUE self) struct strscanner *p; GET_SCANNER(self, p); - return INT2FIX(p->curr); + return LONG2NUM(p->curr); } /* - * Returns the character position of the scan pointer. In the 'reset' position, this - * value is zero. In the 'terminated' position (i.e. the string is exhausted), - * this value is the size of the string. - * - * In short, it's a 0-based index into the string. - * - * s = StringScanner.new("abcädeföghi") - * s.charpos # -> 0 - * s.scan_until(/ä/) # -> "abcä" - * s.pos # -> 5 - * s.charpos # -> 4 + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/get_charpos.md */ static VALUE strscan_get_charpos(VALUE self) @@ -452,13 +531,9 @@ strscan_get_charpos(VALUE self) } /* - * call-seq: pos=(n) - * - * Sets the byte position of the scan pointer. - * - * s = StringScanner.new('test string') - * s.pos = 7 # -> 7 - * s.rest # -> "ring" + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/set_pos.md */ static VALUE strscan_set_pos(VALUE self, VALUE v) @@ -467,7 +542,7 @@ strscan_set_pos(VALUE self, VALUE v) long i; GET_SCANNER(self, p); - i = NUM2INT(v); + i = NUM2LONG(v); if (i < 0) i += S_LEN(p); if (i < 0) rb_raise(rb_eRangeError, "index out of range"); if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range"); @@ -488,19 +563,20 @@ match_target(struct strscanner *p) } static inline void -set_registers(struct strscanner *p, size_t length) +set_registers(struct strscanner *p, size_t pos, size_t length) { const int at = 0; OnigRegion *regs = &(p->regs); onig_region_clear(regs); if (onig_region_set(regs, at, 0, 0)) return; if (p->fixed_anchor_p) { - regs->beg[at] = p->curr; - regs->end[at] = p->curr + length; + regs->beg[at] = pos + p->curr; + regs->end[at] = pos + p->curr + length; } else { - regs->end[at] = length; + regs->beg[at] = pos; + regs->end[at] = pos + length; } } @@ -539,19 +615,82 @@ adjust_register_position(struct strscanner *p, long position) } } -static VALUE -strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly) +/* rb_reg_onig_match is available in Ruby 3.3 and later. */ +#ifndef HAVE_RB_REG_ONIG_MATCH +static OnigPosition +rb_reg_onig_match(VALUE re, VALUE str, + OnigPosition (*match)(regex_t *reg, VALUE str, struct re_registers *regs, void *args), + void *args, struct re_registers *regs) { - struct strscanner *p; + OnigPosition result; + regex_t *reg = rb_reg_prepare_re(re, str); + + bool tmpreg = reg != RREGEXP_PTR(re); + if (!tmpreg) RREGEXP(re)->usecnt++; - if (headonly) { - if (!RB_TYPE_P(pattern, T_REGEXP)) { - StringValue(pattern); + result = match(reg, str, regs, args); + + if (!tmpreg) RREGEXP(re)->usecnt--; + if (tmpreg) { + if (RREGEXP(re)->usecnt) { + onig_free(reg); + } + else { + onig_free(RREGEXP_PTR(re)); + RREGEXP_PTR(re) = reg; } } - else { - Check_Type(pattern, T_REGEXP); + + if (result < 0) { + if (result != ONIG_MISMATCH) { + rb_raise(ScanError, "regexp buffer overflow"); + } } + + return result; +} +#endif + +static OnigPosition +strscan_match(regex_t *reg, VALUE str, struct re_registers *regs, void *args_ptr) +{ + struct strscanner *p = (struct strscanner *)args_ptr; + + return onig_match(reg, + match_target(p), + (UChar* )(CURPTR(p) + S_RESTLEN(p)), + (UChar* )CURPTR(p), + regs, + ONIG_OPTION_NONE); +} + +static OnigPosition +strscan_search(regex_t *reg, VALUE str, struct re_registers *regs, void *args_ptr) +{ + struct strscanner *p = (struct strscanner *)args_ptr; + + return onig_search(reg, + match_target(p), + (UChar *)(CURPTR(p) + S_RESTLEN(p)), + (UChar *)CURPTR(p), + (UChar *)(CURPTR(p) + S_RESTLEN(p)), + regs, + ONIG_OPTION_NONE); +} + +static void +strscan_enc_check(VALUE str1, VALUE str2) +{ + if (RB_ENCODING_GET(str1) != RB_ENCODING_GET(str2)) { + rb_enc_check(str1, str2); + } +} + +static VALUE +strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly) +{ + struct strscanner *p; + GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); @@ -560,59 +699,42 @@ strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly } if (RB_TYPE_P(pattern, T_REGEXP)) { - regex_t *rb_reg_prepare_re(VALUE re, VALUE str); - regex_t *re; - long ret; - int tmpreg; - - p->regex = pattern; - re = rb_reg_prepare_re(pattern, p->str); - tmpreg = re != RREGEXP_PTR(pattern); - if (!tmpreg) RREGEXP(pattern)->usecnt++; - - if (headonly) { - ret = onig_match(re, - match_target(p), - (UChar* )(CURPTR(p) + S_RESTLEN(p)), - (UChar* )CURPTR(p), - &(p->regs), - ONIG_OPTION_NONE); - } - else { - ret = onig_search(re, - match_target(p), - (UChar* )(CURPTR(p) + S_RESTLEN(p)), - (UChar* )CURPTR(p), - (UChar* )(CURPTR(p) + S_RESTLEN(p)), - &(p->regs), - ONIG_OPTION_NONE); - } - if (!tmpreg) RREGEXP(pattern)->usecnt--; - if (tmpreg) { - if (RREGEXP(pattern)->usecnt) { - onig_free(re); - } - else { - onig_free(RREGEXP_PTR(pattern)); - RREGEXP_PTR(pattern) = re; - } - } - - if (ret == -2) rb_raise(ScanError, "regexp buffer overflow"); - if (ret < 0) { - /* not matched */ + OnigPosition ret; + RB_OBJ_WRITE(self, &p->regex, pattern); + ret = rb_reg_onig_match(p->regex, + p->str, + headonly ? strscan_match : strscan_search, + (void *)p, + &(p->regs)); + + if (ret == ONIG_MISMATCH) { return Qnil; } } else { - rb_enc_check(p->str, pattern); + StringValue(pattern); if (S_RESTLEN(p) < RSTRING_LEN(pattern)) { + strscan_enc_check(p->str, pattern); return Qnil; } - if (memcmp(CURPTR(p), RSTRING_PTR(pattern), RSTRING_LEN(pattern)) != 0) { - return Qnil; + + if (headonly) { + strscan_enc_check(p->str, pattern); + + if (memcmp(CURPTR(p), RSTRING_PTR(pattern), RSTRING_LEN(pattern)) != 0) { + return Qnil; + } + set_registers(p, 0, RSTRING_LEN(pattern)); + } + else { + rb_encoding *enc = rb_enc_check(p->str, pattern); + long pos = rb_memsearch(RSTRING_PTR(pattern), RSTRING_LEN(pattern), + CURPTR(p), S_RESTLEN(p), enc); + if (pos == -1) { + return Qnil; + } + set_registers(p, pos, RSTRING_LEN(pattern)); } - set_registers(p, RSTRING_LEN(pattern)); } MATCHED(p); @@ -633,20 +755,9 @@ strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly } /* - * call-seq: scan(pattern) => String - * - * Tries to match with +pattern+ at the current position. If there's a match, - * the scanner advances the "scan pointer" and returns the matched string. - * Otherwise, the scanner returns +nil+. - * - * s = StringScanner.new('test string') - * p s.scan(/\w+/) # -> "test" - * p s.scan(/\w+/) # -> nil - * p s.scan(/\s+/) # -> " " - * p s.scan("str") # -> "str" - * p s.scan(/\w+/) # -> "ing" - * p s.scan(/./) # -> nil - * + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/scan.md */ static VALUE strscan_scan(VALUE self, VALUE re) @@ -655,16 +766,60 @@ strscan_scan(VALUE self, VALUE re) } /* - * call-seq: match?(pattern) + * :markup: markdown + * :include: strscan/link_refs.txt * - * Tests whether the given +pattern+ is matched from the current scan pointer. - * Returns the length of the match, or +nil+. The scan pointer is not advanced. + * call-seq: + * match?(pattern) -> updated_position or nil + * + * Attempts to [match][17] the given `pattern` + * at the beginning of the [target substring][3]; + * does not modify the [positions][11]. + * + * If the match succeeds: + * + * - Sets [match values][9]. + * - Returns the size in bytes of the matched substring. + * + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.pos = 3 + * scanner.match?(/bar/) => 3 + * put_match_values(scanner) + * # Basic match values: + * # matched?: true + * # matched_size: 3 + * # pre_match: "foo" + * # matched : "bar" + * # post_match: "baz" + * # Captured match values: + * # size: 1 + * # captures: [] + * # named_captures: {} + * # values_at: ["bar", nil] + * # []: + * # [0]: "bar" + * # [1]: nil + * put_situation(scanner) + * # Situation: + * # pos: 3 + * # charpos: 3 + * # rest: "barbaz" + * # rest_size: 6 + * ``` + * + * If the match fails: + * + * - Clears match values. + * - Returns `nil`. + * - Does not increment positions. + * + * ```rb + * scanner.match?(/nope/) # => nil + * match_values_cleared?(scanner) # => true + * ``` * - * s = StringScanner.new('test string') - * p s.match?(/\w+/) # -> 4 - * p s.match?(/\w+/) # -> 4 - * p s.match?("test") # -> 4 - * p s.match?(/\s+/) # -> nil */ static VALUE strscan_match_p(VALUE self, VALUE re) @@ -673,22 +828,9 @@ strscan_match_p(VALUE self, VALUE re) } /* - * call-seq: skip(pattern) - * - * Attempts to skip over the given +pattern+ beginning with the scan pointer. - * If it matches, the scan pointer is advanced to the end of the match, and the - * length of the match is returned. Otherwise, +nil+ is returned. - * - * It's similar to #scan, but without returning the matched string. - * - * s = StringScanner.new('test string') - * p s.skip(/\w+/) # -> 4 - * p s.skip(/\w+/) # -> nil - * p s.skip(/\s+/) # -> 1 - * p s.skip("st") # -> 2 - * p s.skip(/\w+/) # -> 4 - * p s.skip(/./) # -> nil - * + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/skip.md */ static VALUE strscan_skip(VALUE self, VALUE re) @@ -697,19 +839,59 @@ strscan_skip(VALUE self, VALUE re) } /* - * call-seq: check(pattern) + * :markup: markdown + * :include: strscan/link_refs.txt * - * This returns the value that #scan would return, without advancing the scan - * pointer. The match register is affected, though. - * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.check /Fri/ # -> "Fri" - * s.pos # -> 0 - * s.matched # -> "Fri" - * s.check /12/ # -> nil - * s.matched # -> nil + * call-seq: + * check(pattern) -> matched_substring or nil + * + * Attempts to [match][17] the given `pattern` + * at the beginning of the [target substring][3]; + * does not modify the [positions][11]. + * + * If the match succeeds: + * + * - Returns the matched substring. + * - Sets all [match values][9]. + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.pos = 3 + * scanner.check('bar') # => "bar" + * put_match_values(scanner) + * # Basic match values: + * # matched?: true + * # matched_size: 3 + * # pre_match: "foo" + * # matched : "bar" + * # post_match: "baz" + * # Captured match values: + * # size: 1 + * # captures: [] + * # named_captures: {} + * # values_at: ["bar", nil] + * # []: + * # [0]: "bar" + * # [1]: nil + * # => 0..1 + * put_situation(scanner) + * # Situation: + * # pos: 3 + * # charpos: 3 + * # rest: "barbaz" + * # rest_size: 6 + * ``` + * + * If the match fails: + * + * - Returns `nil`. + * - Clears all [match values][9]. + * + * ```rb + * scanner.check(/nope/) # => nil + * match_values_cleared?(scanner) # => true + * ``` * - * Mnemonic: it "checks" to see whether a #scan will return a value. */ static VALUE strscan_check(VALUE self, VALUE re) @@ -718,15 +900,24 @@ strscan_check(VALUE self, VALUE re) } /* - * call-seq: scan_full(pattern, advance_pointer_p, return_string_p) + * call-seq: + * scan_full(pattern, advance_pointer_p, return_string_p) -> matched_substring or nil * - * Tests whether the given +pattern+ is matched from the current scan pointer. - * Advances the scan pointer if +advance_pointer_p+ is true. - * Returns the matched string if +return_string_p+ is true. - * The match register is affected. + * Equivalent to one of the following: + * + * - +advance_pointer_p+ +true+: + * + * - +return_string_p+ +true+: StringScanner#scan(pattern). + * - +return_string_p+ +false+: StringScanner#skip(pattern). + * + * - +advance_pointer_p+ +false+: + * + * - +return_string_p+ +true+: StringScanner#check(pattern). + * - +return_string_p+ +false+: StringScanner#match?(pattern). * - * "full" means "#scan with full parameters". */ + + /* :nodoc: */ static VALUE strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f) { @@ -734,16 +925,9 @@ strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f) } /* - * call-seq: scan_until(pattern) - * - * Scans the string _until_ the +pattern+ is matched. Returns the substring up - * to and including the end of the match, advancing the scan pointer to that - * location. If there is no match, +nil+ is returned. - * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan_until(/1/) # -> "Fri Dec 1" - * s.pre_match # -> "Fri Dec " - * s.scan_until(/XYZ/) # -> nil + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/scan_until.md */ static VALUE strscan_scan_until(VALUE self, VALUE re) @@ -752,17 +936,61 @@ strscan_scan_until(VALUE self, VALUE re) } /* - * call-seq: exist?(pattern) + * :markup: markdown + * :include: strscan/link_refs.txt * - * Looks _ahead_ to see if the +pattern+ exists _anywhere_ in the string, - * without advancing the scan pointer. This predicates whether a #scan_until - * will return a value. + * call-seq: + * exist?(pattern) -> byte_offset or nil + * + * Attempts to [match][17] the given `pattern` + * anywhere (at any [position][2]) + * n the [target substring][3]; + * does not modify the [positions][11]. + * + * If the match succeeds: + * + * - Returns a byte offset: + * the distance in bytes between the current [position][2] + * and the end of the matched substring. + * - Sets all [match values][9]. + * + * ```rb + * scanner = StringScanner.new('foobarbazbatbam') + * scanner.pos = 6 + * scanner.exist?(/bat/) # => 6 + * put_match_values(scanner) + * # Basic match values: + * # matched?: true + * # matched_size: 3 + * # pre_match: "foobarbaz" + * # matched : "bat" + * # post_match: "bam" + * # Captured match values: + * # size: 1 + * # captures: [] + * # named_captures: {} + * # values_at: ["bat", nil] + * # []: + * # [0]: "bat" + * # [1]: nil + * put_situation(scanner) + * # Situation: + * # pos: 6 + * # charpos: 6 + * # rest: "bazbatbam" + * # rest_size: 9 + * ``` + * + * If the match fails: + * + * - Returns `nil`. + * - Clears all [match values][9]. + * + * ```rb + * scanner.exist?(/nope/) # => nil + * match_values_cleared?(scanner) # => true + * ``` * - * s = StringScanner.new('test string') - * s.exist? /s/ # -> 3 - * s.scan /test/ # -> "test" - * s.exist? /s/ # -> 2 - * s.exist? /e/ # -> nil */ static VALUE strscan_exist_p(VALUE self, VALUE re) @@ -771,20 +999,9 @@ strscan_exist_p(VALUE self, VALUE re) } /* - * call-seq: skip_until(pattern) - * - * Advances the scan pointer until +pattern+ is matched and consumed. Returns - * the number of bytes advanced, or +nil+ if no match was found. - * - * Look ahead to match +pattern+, and advance the scan pointer to the _end_ - * of the match. Return the number of characters advanced, or +nil+ if the - * match was unsuccessful. - * - * It's similar to #scan_until, but without returning the intervening string. - * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.skip_until /12/ # -> 10 - * s # + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/skip_until.md */ static VALUE strscan_skip_until(VALUE self, VALUE re) @@ -793,17 +1010,61 @@ strscan_skip_until(VALUE self, VALUE re) } /* - * call-seq: check_until(pattern) - * - * This returns the value that #scan_until would return, without advancing the - * scan pointer. The match register is affected, though. + * :markup: markdown + * :include: strscan/link_refs.txt * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.check_until /12/ # -> "Fri Dec 12" - * s.pos # -> 0 - * s.matched # -> 12 + * call-seq: + * check_until(pattern) -> substring or nil + * + * Attempts to [match][17] the given `pattern` + * anywhere (at any [position][2]) + * in the [target substring][3]; + * does not modify the [positions][11]. + * + * If the match succeeds: + * + * - Sets all [match values][9]. + * - Returns the matched substring, + * which extends from the current [position][2] + * to the end of the matched substring. + * + * ```rb + * scanner = StringScanner.new('foobarbazbatbam') + * scanner.pos = 6 + * scanner.check_until(/bat/) # => "bazbat" + * put_match_values(scanner) + * # Basic match values: + * # matched?: true + * # matched_size: 3 + * # pre_match: "foobarbaz" + * # matched : "bat" + * # post_match: "bam" + * # Captured match values: + * # size: 1 + * # captures: [] + * # named_captures: {} + * # values_at: ["bat", nil] + * # []: + * # [0]: "bat" + * # [1]: nil + * put_situation(scanner) + * # Situation: + * # pos: 6 + * # charpos: 6 + * # rest: "bazbatbam" + * # rest_size: 9 + * ``` + * + * If the match fails: + * + * - Clears all [match values][9]. + * - Returns `nil`. + * + * ```rb + * scanner.check_until(/nope/) # => nil + * match_values_cleared?(scanner) # => true + * ``` * - * Mnemonic: it "checks" to see whether a #scan_until will return a value. */ static VALUE strscan_check_until(VALUE self, VALUE re) @@ -812,14 +1073,24 @@ strscan_check_until(VALUE self, VALUE re) } /* - * call-seq: search_full(pattern, advance_pointer_p, return_string_p) + * call-seq: + * search_full(pattern, advance_pointer_p, return_string_p) -> matched_substring or position_delta or nil + * + * Equivalent to one of the following: + * + * - +advance_pointer_p+ +true+: + * + * - +return_string_p+ +true+: StringScanner#scan_until(pattern). + * - +return_string_p+ +false+: StringScanner#skip_until(pattern). + * + * - +advance_pointer_p+ +false+: + * + * - +return_string_p+ +true+: StringScanner#check_until(pattern). + * - +return_string_p+ +false+: StringScanner#exist?(pattern). * - * Scans the string _until_ the +pattern+ is matched. - * Advances the scan pointer if +advance_pointer_p+, otherwise not. - * Returns the matched string if +return_string_p+ is true, otherwise - * returns the number of bytes advanced. - * This method does affect the match register. */ + + /* :nodoc: */ static VALUE strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f) { @@ -839,17 +1110,9 @@ adjust_registers_to_matched(struct strscanner *p) } /* - * Scans one character and returns it. - * This method is multibyte character sensitive. - * - * s = StringScanner.new("ab") - * s.getch # => "a" - * s.getch # => "b" - * s.getch # => nil - * - * s = StringScanner.new("\244\242".force_encoding("euc-jp")) - * s.getch # => "\x{A4A2}" # Japanese hira-kana "A" in EUC-JP - * s.getch # => nil + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/getch.md */ static VALUE strscan_getch(VALUE self) @@ -874,59 +1137,92 @@ strscan_getch(VALUE self) } /* - * Scans one byte and returns it. + * call-seq: + * scan_byte -> integer_byte + * + * Scans one byte and returns it as an integer. * This method is not multibyte character sensitive. * See also: #getch. * - * s = StringScanner.new('ab') - * s.get_byte # => "a" - * s.get_byte # => "b" - * s.get_byte # => nil - * - * s = StringScanner.new("\244\242".force_encoding("euc-jp")) - * s.get_byte # => "\xA4" - * s.get_byte # => "\xA2" - * s.get_byte # => nil */ static VALUE -strscan_get_byte(VALUE self) +strscan_scan_byte(VALUE self) { struct strscanner *p; + VALUE byte; GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); if (EOS_P(p)) return Qnil; + byte = INT2FIX((unsigned char)*CURPTR(p)); p->prev = p->curr; p->curr++; MATCHED(p); adjust_registers_to_matched(p); - return extract_range(p, - adjust_register_position(p, p->regs.beg[0]), - adjust_register_position(p, p->regs.end[0])); + return byte; +} + +/* + * Peeks at the current byte and returns it as an integer. + * + * s = StringScanner.new('ab') + * s.peek_byte # => 97 + */ +static VALUE +strscan_peek_byte(VALUE self) +{ + struct strscanner *p; + + GET_SCANNER(self, p); + if (EOS_P(p)) + return Qnil; + + return INT2FIX((unsigned char)*CURPTR(p)); } /* - * Equivalent to #get_byte. - * This method is obsolete; use #get_byte instead. + * :markup: markdown + * :include: strscan/link_refs.txt + * :include: strscan/methods/get_byte.md */ static VALUE -strscan_getbyte(VALUE self) +strscan_get_byte(VALUE self) { - rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead"); - return strscan_get_byte(self); + struct strscanner *p; + + GET_SCANNER(self, p); + CLEAR_MATCH_STATUS(p); + if (EOS_P(p)) + return Qnil; + + p->prev = p->curr; + p->curr++; + MATCHED(p); + adjust_registers_to_matched(p); + return extract_range(p, + adjust_register_position(p, p->regs.beg[0]), + adjust_register_position(p, p->regs.end[0])); } /* - * call-seq: peek(len) + * :markup: markdown + * :include: strscan/link_refs.txt * - * Extracts a string corresponding to <tt>string[pos,len]</tt>, without - * advancing the scan pointer. + * call-seq: + * peek(length) -> substring * - * s = StringScanner.new('test string') - * s.peek(7) # => "test st" - * s.peek(7) # => "test st" + * Returns the substring `string[pos, length]`; + * does not update [match values][9] or [positions][11]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.pos = 3 + * scanner.peek(3) # => "bar" + * scanner.terminate + * scanner.peek(3) # => "" + * ``` * */ static VALUE @@ -945,27 +1241,160 @@ strscan_peek(VALUE self, VALUE vlen) return extract_beg_len(p, p->curr, len); } -/* - * Equivalent to #peek. - * This method is obsolete; use #peek instead. - */ static VALUE -strscan_peep(VALUE self, VALUE vlen) +strscan_parse_integer(struct strscanner *p, int base, long len) +{ + VALUE buffer_v, integer; + + char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1); + + MEMCPY(buffer, CURPTR(p), char, len); + buffer[len] = '\0'; + integer = rb_cstr2inum(buffer, base); + RB_ALLOCV_END(buffer_v); + p->curr += len; + + MATCHED(p); + adjust_registers_to_matched(p); + + return integer; +} + +static inline bool +strscan_ascii_compat_fastpath(VALUE str) { + int encindex = ENCODING_GET_INLINED(str); + // The overwhelming majority of strings are in one of these 3 encodings. + return encindex == utf8_encindex || encindex == binary_encindex || encindex == usascii_encindex; +} + +static inline void +strscan_must_ascii_compat(VALUE str) { - rb_warning("StringScanner#peep is obsolete; use #peek instead"); - return strscan_peek(self, vlen); + // The overwhelming majority of strings are in one of these 3 encodings. + if (RB_LIKELY(strscan_ascii_compat_fastpath(str))) { + return; + } + + rb_must_asciicompat(str); +} + +/* :nodoc: */ +static VALUE +strscan_scan_base10_integer(VALUE self) +{ + char *ptr; + long len = 0, remaining_len; + struct strscanner *p; + + GET_SCANNER(self, p); + CLEAR_MATCH_STATUS(p); + + strscan_must_ascii_compat(p->str); + + ptr = CURPTR(p); + + remaining_len = S_RESTLEN(p); + + if (remaining_len <= 0) { + return Qnil; + } + + if (ptr[len] == '-' || ptr[len] == '+') { + len++; + } + + if (!rb_isdigit(ptr[len])) { + return Qnil; + } + + p->prev = p->curr; + + while (len < remaining_len && rb_isdigit(ptr[len])) { + len++; + } + + return strscan_parse_integer(p, 10, len); +} + +/* :nodoc: */ +static VALUE +strscan_scan_base16_integer(VALUE self) +{ + char *ptr; + long len = 0, remaining_len; + struct strscanner *p; + + GET_SCANNER(self, p); + CLEAR_MATCH_STATUS(p); + + strscan_must_ascii_compat(p->str); + + ptr = CURPTR(p); + + remaining_len = S_RESTLEN(p); + + if (remaining_len <= 0) { + return Qnil; + } + + if (ptr[len] == '-' || ptr[len] == '+') { + len++; + } + + if ((remaining_len >= (len + 3)) && ptr[len] == '0' && ptr[len + 1] == 'x' && rb_isxdigit(ptr[len + 2])) { + len += 2; + } + + if (len >= remaining_len || !rb_isxdigit(ptr[len])) { + return Qnil; + } + + p->prev = p->curr; + + while (len < remaining_len && rb_isxdigit(ptr[len])) { + len++; + } + + return strscan_parse_integer(p, 16, len); } /* - * Sets the scan pointer to the previous position. Only one previous position is - * remembered, and it changes with each scanning operation. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * unscan -> self + * + * Sets the [position][2] to its value previous to the recent successful + * [match][17] attempt: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.scan(/foo/) + * put_situation(scanner) + * # Situation: + * # pos: 3 + * # charpos: 3 + * # rest: "barbaz" + * # rest_size: 6 + * scanner.unscan + * # => #<StringScanner 0/9 @ "fooba..."> + * put_situation(scanner) + * # Situation: + * # pos: 0 + * # charpos: 0 + * # rest: "foobarbaz" + * # rest_size: 9 + * ``` + * + * Raises an exception if match values are clear: + * + * ```rb + * scanner.scan(/nope/) # => nil + * match_values_cleared?(scanner) # => true + * scanner.unscan # Raises StringScanner::Error. + * ``` * - * s = StringScanner.new('test string') - * s.scan(/\w+/) # => "test" - * s.unscan - * s.scan(/../) # => "te" - * s.scan(/\d/) # => nil - * s.unscan # ScanError: unscan failed: previous match record not exist */ static VALUE strscan_unscan(VALUE self) @@ -981,16 +1410,37 @@ strscan_unscan(VALUE self) } /* - * Returns +true+ if and only if the scan pointer is at the beginning of the line. - * - * s = StringScanner.new("test\ntest\n") - * s.bol? # => true - * s.scan(/te/) - * s.bol? # => false - * s.scan(/st\n/) - * s.bol? # => true - * s.terminate - * s.bol? # => true + * + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * beginning_of_line? -> true or false + * + * Returns whether the [position][2] is at the beginning of a line; + * that is, at the beginning of the [stored string][1] + * or immediately after a newline: + * + * scanner = StringScanner.new(MULTILINE_TEXT) + * scanner.string + * # => "Go placidly amid the noise and haste,\nand remember what peace there may be in silence.\n" + * scanner.pos # => 0 + * scanner.beginning_of_line? # => true + * + * scanner.scan_until(/,/) # => "Go placidly amid the noise and haste," + * scanner.beginning_of_line? # => false + * + * scanner.scan(/\n/) # => "\n" + * scanner.beginning_of_line? # => true + * + * scanner.terminate + * scanner.beginning_of_line? # => true + * + * scanner.concat('x') + * scanner.terminate + * scanner.beginning_of_line? # => false + * + * StringScanner#bol? is an alias for StringScanner#beginning_of_line?. */ static VALUE strscan_bol_p(VALUE self) @@ -1004,14 +1454,24 @@ strscan_bol_p(VALUE self) } /* - * Returns +true+ if the scan pointer is at the end of the string. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * eos? -> true or false + * + * Returns whether the [position][2] + * is at the end of the [stored string][1]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.eos? # => false + * pos = 3 + * scanner.eos? # => false + * scanner.terminate + * scanner.eos? # => true + * ``` * - * s = StringScanner.new('test string') - * p s.eos? # => false - * s.scan(/test/) - * p s.eos? # => false - * s.terminate - * p s.eos? # => true */ static VALUE strscan_eos_p(VALUE self) @@ -1023,24 +1483,18 @@ strscan_eos_p(VALUE self) } /* - * Equivalent to #eos?. - * This method is obsolete, use #eos? instead. - */ -static VALUE -strscan_empty_p(VALUE self) -{ - rb_warning("StringScanner#empty? is obsolete; use #eos? instead"); - return strscan_eos_p(self); -} - -/* + * call-seq: + * rest? + * * Returns true if and only if there is more data in the string. See #eos?. - * This method is obsolete; use #eos? instead. * * s = StringScanner.new('test string') - * s.eos? # These two - * s.rest? # are opposites. + * # These two are opposites + * s.eos? # => false + * s.rest? # => true */ + + /* :nodoc: */ static VALUE strscan_rest_p(VALUE self) { @@ -1051,13 +1505,26 @@ strscan_rest_p(VALUE self) } /* - * Returns +true+ if and only if the last match was successful. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * matched? -> true or false + * + * Returns `true` of the most recent [match attempt][17] was successful, + * `false` otherwise; + * see [Basic Matched Values][18]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.matched? # => false + * scanner.pos = 3 + * scanner.exist?(/baz/) # => 6 + * scanner.matched? # => true + * scanner.exist?(/nope/) # => nil + * scanner.matched? # => false + * ``` * - * s = StringScanner.new('test string') - * s.match?(/\w+/) # => 4 - * s.matched? # => true - * s.match?(/\d+/) # => nil - * s.matched? # => false */ static VALUE strscan_matched_p(VALUE self) @@ -1069,11 +1536,27 @@ strscan_matched_p(VALUE self) } /* - * Returns the last matched string. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * matched -> matched_substring or nil + * + * Returns the matched substring from the most recent [match][17] attempt + * if it was successful, + * or `nil` otherwise; + * see [Basic Matched Values][18]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.matched # => nil + * scanner.pos = 3 + * scanner.match?(/bar/) # => 3 + * scanner.matched # => "bar" + * scanner.match?(/nope/) # => nil + * scanner.matched # => nil + * ``` * - * s = StringScanner.new('test string') - * s.match?(/\w+/) # -> 4 - * s.matched # -> "test" */ static VALUE strscan_matched(VALUE self) @@ -1088,15 +1571,29 @@ strscan_matched(VALUE self) } /* - * Returns the size of the most recent match in bytes, or +nil+ if there - * was no recent match. This is different than <tt>matched.size</tt>, - * which will return the size in characters. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * matched_size -> substring_size or nil + * + * Returns the size (in bytes) of the matched substring + * from the most recent match [match attempt][17] if it was successful, + * or `nil` otherwise; + * see [Basic Matched Values][18]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.matched_size # => nil + * + * pos = 3 + * scanner.exist?(/baz/) # => 9 + * scanner.matched_size # => 3 + * + * scanner.exist?(/nope/) # => nil + * scanner.matched_size # => nil + * ``` * - * s = StringScanner.new('test string') - * s.check /\w+/ # -> "test" - * s.matched_size # -> 4 - * s.check /\d+/ # -> nil - * s.matched_size # -> nil */ static VALUE strscan_matched_size(VALUE self) @@ -1111,46 +1608,89 @@ strscan_matched_size(VALUE self) static int name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end, rb_encoding *enc) { - int num; - - num = onig_name_to_backref_number(RREGEXP_PTR(regexp), - (const unsigned char* )name, (const unsigned char* )name_end, regs); - if (num >= 1) { - return num; - } - else { - rb_enc_raise(enc, rb_eIndexError, "undefined group name reference: %.*s", - rb_long2int(name_end - name), name); + if (RTEST(regexp)) { + int num = onig_name_to_backref_number(RREGEXP_PTR(regexp), + (const unsigned char* )name, + (const unsigned char* )name_end, + regs); + if (num >= 1) { + return num; + } } - - UNREACHABLE; + rb_enc_raise(enc, rb_eIndexError, "undefined group name reference: %.*s", + rb_long2int(name_end - name), name); } /* - * call-seq: [](n) - * - * Returns the n-th subgroup in the most recent match. - * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - * s[0] # -> "Fri Dec 12 " - * s[1] # -> "Fri" - * s[2] # -> "Dec" - * s[3] # -> "12" - * s.post_match # -> "1975 14:39" - * s.pre_match # -> "" - * - * s.reset - * s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) # -> "Fri Dec 12 " - * s[0] # -> "Fri Dec 12 " - * s[1] # -> "Fri" - * s[2] # -> "Dec" - * s[3] # -> "12" - * s[:wday] # -> "Fri" - * s[:month] # -> "Dec" - * s[:day] # -> "12" - * s.post_match # -> "1975 14:39" - * s.pre_match # -> "" + * + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * [](specifier) -> substring or nil + * + * Returns a captured substring or `nil`; + * see [Captured Match Values][13]. + * + * When there are captures: + * + * ```rb + * scanner = StringScanner.new('Fri Dec 12 1975 14:39') + * scanner.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) + * ``` + * + * - `specifier` zero: returns the entire matched substring: + * + * ```rb + * scanner[0] # => "Fri Dec 12 " + * scanner.pre_match # => "" + * scanner.post_match # => "1975 14:39" + * ``` + * + * - `specifier` positive integer. returns the `n`th capture, or `nil` if out of range: + * + * ```rb + * scanner[1] # => "Fri" + * scanner[2] # => "Dec" + * scanner[3] # => "12" + * scanner[4] # => nil + * ``` + * + * - `specifier` negative integer. counts backward from the last subgroup: + * + * ```rb + * scanner[-1] # => "12" + * scanner[-4] # => "Fri Dec 12 " + * scanner[-5] # => nil + * ``` + * + * - `specifier` symbol or string. returns the named subgroup, or `nil` if no such: + * + * ```rb + * scanner[:wday] # => "Fri" + * scanner['wday'] # => "Fri" + * scanner[:month] # => "Dec" + * scanner[:day] # => "12" + * scanner[:nope] # => nil + * ``` + * + * When there are no captures, only `[0]` returns non-`nil`: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.exist?(/bar/) + * scanner[0] # => "bar" + * scanner[1] # => nil + * ``` + * + * For a failed match, even `[0]` returns `nil`: + * + * ```rb + * scanner.scan(/nope/) # => nil + * scanner[0] # => nil + * scanner[1] # => nil + * ``` + * */ static VALUE strscan_aref(VALUE self, VALUE idx) @@ -1167,7 +1707,6 @@ strscan_aref(VALUE self, VALUE idx) idx = rb_sym2str(idx); /* fall through */ case T_STRING: - if (!RTEST(p->regex)) return Qnil; RSTRING_GETMEM(idx, name, i); i = name_to_backref_number(&(p->regs), p->regex, name, name + i, rb_enc_get(idx)); break; @@ -1187,14 +1726,28 @@ strscan_aref(VALUE self, VALUE idx) } /* - * call-seq: size + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * size -> captures_count + * + * Returns the count of captures if the most recent match attempt succeeded, `nil` otherwise; + * see [Captures Match Values][13]: + * + * ```rb + * scanner = StringScanner.new('Fri Dec 12 1975 14:39') + * scanner.size # => nil * - * Returns the amount of subgroups in the most recent match. - * The full match counts as a subgroup. + * pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) / + * scanner.match?(pattern) + * scanner.values_at(*0..scanner.size) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil] + * scanner.size # => 4 + * + * scanner.match?(/nope/) # => nil + * scanner.size # => nil + * ``` * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - * s.size # -> 4 */ static VALUE strscan_size(VALUE self) @@ -1207,16 +1760,30 @@ strscan_size(VALUE self) } /* - * call-seq: captures + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * captures -> substring_array or nil + * + * Returns the array of [captured match values][13] at indexes `(1..)` + * if the most recent match attempt succeeded, or `nil` otherwise: + * + * ```rb + * scanner = StringScanner.new('Fri Dec 12 1975 14:39') + * scanner.captures # => nil + * + * scanner.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) + * scanner.captures # => ["Fri", "Dec", "12"] + * scanner.values_at(*0..4) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil] * - * Returns the subgroups in the most recent match (not including the full match). - * If nothing was priorly matched, it returns nil. + * scanner.exist?(/Fri/) + * scanner.captures # => [] + * + * scanner.scan(/nope/) + * scanner.captures # => nil + * ``` * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - * s.captures # -> ["Fri", "Dec", "12"] - * s.scan(/(\w+) (\w+) (\d+) /) # -> nil - * s.captures # -> nil */ static VALUE strscan_captures(VALUE self) @@ -1232,9 +1799,13 @@ strscan_captures(VALUE self) new_ary = rb_ary_new2(num_regs); for (i = 1; i < num_regs; i++) { - VALUE str = extract_range(p, - adjust_register_position(p, p->regs.beg[i]), - adjust_register_position(p, p->regs.end[i])); + VALUE str; + if (p->regs.beg[i] == -1) + str = Qnil; + else + str = extract_range(p, + adjust_register_position(p, p->regs.beg[i]), + adjust_register_position(p, p->regs.end[i])); rb_ary_push(new_ary, str); } @@ -1242,17 +1813,25 @@ strscan_captures(VALUE self) } /* - * call-seq: - * scanner.values_at( i1, i2, ... iN ) -> an_array + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * values_at(*specifiers) -> array_of_captures or nil * - * Returns the subgroups in the most recent match at the given indices. - * If nothing was priorly matched, it returns nil. + * Returns an array of captured substrings, or `nil` of none. + * + * For each `specifier`, the returned substring is `[specifier]`; + * see #[]. + * + * ```rb + * scanner = StringScanner.new('Fri Dec 12 1975 14:39') + * pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) / + * scanner.match?(pattern) + * scanner.values_at(*0..3) # => ["Fri Dec 12 ", "Fri", "Dec", "12"] + * scanner.values_at(*%i[wday month day]) # => ["Fri", "Dec", "12"] + * ``` * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - * s.values_at 0, -1, 5, 2 # -> ["Fri Dec 12 ", "12", nil, "Dec"] - * s.scan(/(\w+) (\w+) (\d+) /) # -> nil - * s.values_at 0, -1, 5, 2 # -> nil */ static VALUE @@ -1274,13 +1853,29 @@ strscan_values_at(int argc, VALUE *argv, VALUE self) } /* - * Returns the <i><b>pre</b>-match</i> (in the regular expression sense) of the last scan. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * pre_match -> substring + * + * Returns the substring that precedes the matched substring + * from the most recent match attempt if it was successful, + * or `nil` otherwise; + * see [Basic Match Values][18]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.pre_match # => nil + * + * scanner.pos = 3 + * scanner.exist?(/baz/) # => 6 + * scanner.pre_match # => "foobar" # Substring of entire string, not just target string. + * + * scanner.exist?(/nope/) # => nil + * scanner.pre_match # => nil + * ``` * - * s = StringScanner.new('test string') - * s.scan(/\w+/) # -> "test" - * s.scan(/\s+/) # -> " " - * s.pre_match # -> "test" - * s.post_match # -> "string" */ static VALUE strscan_pre_match(VALUE self) @@ -1295,13 +1890,29 @@ strscan_pre_match(VALUE self) } /* - * Returns the <i><b>post</b>-match</i> (in the regular expression sense) of the last scan. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * post_match -> substring + * + * Returns the substring that follows the matched substring + * from the most recent match attempt if it was successful, + * or `nil` otherwise; + * see [Basic Match Values][18]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.post_match # => nil + * + * scanner.pos = 3 + * scanner.match?(/bar/) # => 3 + * scanner.post_match # => "baz" + * + * scanner.match?(/nope/) # => nil + * scanner.post_match # => nil + * ``` * - * s = StringScanner.new('test string') - * s.scan(/\w+/) # -> "test" - * s.scan(/\s+/) # -> " " - * s.pre_match # -> "test" - * s.post_match # -> "string" */ static VALUE strscan_post_match(VALUE self) @@ -1316,8 +1927,24 @@ strscan_post_match(VALUE self) } /* - * Returns the "rest" of the string (i.e. everything after the scan pointer). - * If there is no more data (eos? = true), it returns <tt>""</tt>. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * rest -> target_substring + * + * Returns the 'rest' of the [stored string][1] (all after the current [position][2]), + * which is the [target substring][3]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.rest # => "foobarbaz" + * scanner.pos = 3 + * scanner.rest # => "barbaz" + * scanner.terminate + * scanner.rest # => "" + * ``` + * */ static VALUE strscan_rest(VALUE self) @@ -1332,7 +1959,26 @@ strscan_rest(VALUE self) } /* - * <tt>s.rest_size</tt> is equivalent to <tt>s.rest.size</tt>. + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * rest_size -> integer + * + * Returns the size (in bytes) of the #rest of the [stored string][1]: + * + * ```rb + * scanner = StringScanner.new('foobarbaz') + * scanner.rest # => "foobarbaz" + * scanner.rest_size # => 9 + * scanner.pos = 3 + * scanner.rest # => "barbaz" + * scanner.rest_size # => 6 + * scanner.terminate + * scanner.rest # => "" + * scanner.rest_size # => 0 + * ``` + * */ static VALUE strscan_rest_size(VALUE self) @@ -1348,29 +1994,42 @@ strscan_rest_size(VALUE self) return INT2FIX(i); } -/* - * <tt>s.restsize</tt> is equivalent to <tt>s.rest_size</tt>. - * This method is obsolete; use #rest_size instead. - */ -static VALUE -strscan_restsize(VALUE self) -{ - rb_warning("StringScanner#restsize is obsolete; use #rest_size instead"); - return strscan_rest_size(self); -} - #define INSPECT_LENGTH 5 /* - * Returns a string that represents the StringScanner object, showing: - * - the current position - * - the size of the string - * - the characters surrounding the scan pointer - * - * s = StringScanner.new("Fri Dec 12 1975 14:39") - * s.inspect # -> '#<StringScanner 0/21 @ "Fri D...">' - * s.scan_until /12/ # -> "Fri Dec 12" - * s.inspect # -> '#<StringScanner 10/21 "...ec 12" @ " 1975...">' + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * inspect -> string + * + * Returns a string representation of `self` that may show: + * + * 1. The current [position][2]. + * 2. The size (in bytes) of the [stored string][1]. + * 3. The substring preceding the current position. + * 4. The substring following the current position (which is also the [target substring][3]). + * + * ```rb + * scanner = StringScanner.new("Fri Dec 12 1975 14:39") + * scanner.pos = 11 + * scanner.inspect # => "#<StringScanner 11/21 \"...c 12 \" @ \"1975 ...\">" + * ``` + * + * If at beginning-of-string, item 4 above (following substring) is omitted: + * + * ```rb + * scanner.reset + * scanner.inspect # => "#<StringScanner 0/21 @ \"Fri D...\">" + * ``` + * + * If at end-of-string, all items above are omitted: + * + * ```rb + * scanner.terminate + * scanner.inspect # => "#<StringScanner fin>" + * ``` + * */ static VALUE strscan_inspect(VALUE self) @@ -1442,13 +2101,13 @@ inspect2(struct strscanner *p) } /* - * call-seq: - * scanner.fixed_anchor? -> true or false + * :markup: markdown + * :include: strscan/link_refs.txt * - * Whether +scanner+ uses fixed anchor mode or not. + * call-seq: + * fixed_anchor? -> true or false * - * If fixed anchor mode is used, +\A+ always matches the beginning of - * the string. Otherwise, +\A+ always matches the current position. + * Returns whether the [fixed-anchor property][10] is set. */ static VALUE strscan_fixed_anchor_p(VALUE self) @@ -1458,112 +2117,96 @@ strscan_fixed_anchor_p(VALUE self) return p->fixed_anchor_p ? Qtrue : Qfalse; } +typedef struct { + VALUE self; + VALUE captures; +} named_captures_data; + +static int +named_captures_iter(const OnigUChar *name, + const OnigUChar *name_end, + int back_num, + int *back_refs, + OnigRegex regex, + void *arg) +{ + named_captures_data *data = arg; + + VALUE key = rb_str_new((const char *)name, name_end - name); + VALUE value = RUBY_Qnil; + int i; + for (i = 0; i < back_num; i++) { + VALUE v = strscan_aref(data->self, INT2NUM(back_refs[i])); + if (!RB_NIL_P(v)) { + value = v; + } + } + rb_hash_aset(data->captures, key, value); + return 0; +} + +/* + * :markup: markdown + * :include: strscan/link_refs.txt + * + * call-seq: + * named_captures -> hash + * + * Returns the array of captured match values at indexes (1..) + * if the most recent match attempt succeeded, or nil otherwise; + * see [Captured Match Values][13]: + * + * ```rb + * scanner = StringScanner.new('Fri Dec 12 1975 14:39') + * scanner.named_captures # => {} + * + * pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) / + * scanner.match?(pattern) + * scanner.named_captures # => {"wday"=>"Fri", "month"=>"Dec", "day"=>"12"} + * + * scanner.string = 'nope' + * scanner.match?(pattern) + * scanner.named_captures # => {"wday"=>nil, "month"=>nil, "day"=>nil} + * + * scanner.match?(/nosuch/) + * scanner.named_captures # => {} + * ``` + * + */ +static VALUE +strscan_named_captures(VALUE self) +{ + struct strscanner *p; + named_captures_data data; + GET_SCANNER(self, p); + data.self = self; + data.captures = rb_hash_new(); + if (!RB_NIL_P(p->regex)) { + onig_foreach_name(RREGEXP_PTR(p->regex), named_captures_iter, &data); + } + + return data.captures; +} + /* ======================================================================= Ruby Interface ======================================================================= */ /* + * Document-class: StringScanner::Error + * + * The error class for StringScanner. + * See StringScanner#unscan. + */ + +/* * Document-class: StringScanner * - * StringScanner provides for lexical scanning operations on a String. Here is - * an example of its usage: - * - * s = StringScanner.new('This is an example string') - * s.eos? # -> false - * - * p s.scan(/\w+/) # -> "This" - * p s.scan(/\w+/) # -> nil - * p s.scan(/\s+/) # -> " " - * p s.scan(/\s+/) # -> nil - * p s.scan(/\w+/) # -> "is" - * s.eos? # -> false - * - * p s.scan(/\s+/) # -> " " - * p s.scan(/\w+/) # -> "an" - * p s.scan(/\s+/) # -> " " - * p s.scan(/\w+/) # -> "example" - * p s.scan(/\s+/) # -> " " - * p s.scan(/\w+/) # -> "string" - * s.eos? # -> true - * - * p s.scan(/\s+/) # -> nil - * p s.scan(/\w+/) # -> nil - * - * Scanning a string means remembering the position of a <i>scan pointer</i>, - * which is just an index. The point of scanning is to move forward a bit at - * a time, so matches are sought after the scan pointer; usually immediately - * after it. - * - * Given the string "test string", here are the pertinent scan pointer - * positions: - * - * t e s t s t r i n g - * 0 1 2 ... 1 - * 0 - * - * When you #scan for a pattern (a regular expression), the match must occur - * at the character after the scan pointer. If you use #scan_until, then the - * match can occur anywhere after the scan pointer. In both cases, the scan - * pointer moves <i>just beyond</i> the last character of the match, ready to - * scan again from the next character onwards. This is demonstrated by the - * example above. - * - * == Method Categories - * - * There are other methods besides the plain scanners. You can look ahead in - * the string without actually scanning. You can access the most recent match. - * You can modify the string being scanned, reset or terminate the scanner, - * find out or change the position of the scan pointer, skip ahead, and so on. - * - * === Advancing the Scan Pointer - * - * - #getch - * - #get_byte - * - #scan - * - #scan_until - * - #skip - * - #skip_until - * - * === Looking Ahead - * - * - #check - * - #check_until - * - #exist? - * - #match? - * - #peek - * - * === Finding Where we Are - * - * - #beginning_of_line? (<tt>#bol?</tt>) - * - #eos? - * - #rest? - * - #rest_size - * - #pos - * - * === Setting Where we Are - * - * - #reset - * - #terminate - * - #pos= - * - * === Match Data - * - * - #matched - * - #matched? - * - #matched_size - * - <tt>#[]</tt> - * - #pre_match - * - #post_match - * - * === Miscellaneous - * - * - <tt><<</tt> - * - #concat - * - #string - * - #string= - * - #unscan - * - * There are aliases to several of the methods. + * :markup: markdown + * + * :include: strscan/link_refs.txt + * :include: strscan/strscan.md + * */ void Init_strscan(void) @@ -1576,12 +2219,15 @@ Init_strscan(void) ID id_scanerr = rb_intern("ScanError"); VALUE tmp; - id_byteslice = rb_intern("byteslice"); + usascii_encindex = rb_usascii_encindex(); + utf8_encindex = rb_utf8_encindex(); + binary_encindex = rb_ascii8bit_encindex(); StringScanner = rb_define_class("StringScanner", rb_cObject); ScanError = rb_define_class_under(StringScanner, "Error", rb_eStandardError); if (!rb_const_defined(rb_cObject, id_scanerr)) { rb_const_set(rb_cObject, id_scanerr, ScanError); + rb_deprecate_constant(rb_cObject, "ScanError"); } tmp = rb_str_new2(STRSCAN_VERSION); rb_obj_freeze(tmp); @@ -1589,6 +2235,7 @@ Init_strscan(void) tmp = rb_str_new2("$Id$"); rb_obj_freeze(tmp); rb_const_set(StringScanner, rb_intern("Id"), tmp); + rb_deprecate_constant(StringScanner, "Id"); rb_define_alloc_func(StringScanner, strscan_s_allocate); rb_define_private_method(StringScanner, "initialize", strscan_initialize, -1); @@ -1596,7 +2243,6 @@ Init_strscan(void) rb_define_singleton_method(StringScanner, "must_C_version", strscan_s_mustc, 0); rb_define_method(StringScanner, "reset", strscan_reset, 0); rb_define_method(StringScanner, "terminate", strscan_terminate, 0); - rb_define_method(StringScanner, "clear", strscan_clear, 0); rb_define_method(StringScanner, "string", strscan_get_string, 0); rb_define_method(StringScanner, "string=", strscan_set_string, 1); rb_define_method(StringScanner, "concat", strscan_concat, 1); @@ -1621,16 +2267,18 @@ Init_strscan(void) rb_define_method(StringScanner, "getch", strscan_getch, 0); rb_define_method(StringScanner, "get_byte", strscan_get_byte, 0); - rb_define_method(StringScanner, "getbyte", strscan_getbyte, 0); + rb_define_method(StringScanner, "scan_byte", strscan_scan_byte, 0); rb_define_method(StringScanner, "peek", strscan_peek, 1); - rb_define_method(StringScanner, "peep", strscan_peep, 1); + rb_define_method(StringScanner, "peek_byte", strscan_peek_byte, 0); + + rb_define_private_method(StringScanner, "scan_base10_integer", strscan_scan_base10_integer, 0); + rb_define_private_method(StringScanner, "scan_base16_integer", strscan_scan_base16_integer, 0); rb_define_method(StringScanner, "unscan", strscan_unscan, 0); rb_define_method(StringScanner, "beginning_of_line?", strscan_bol_p, 0); rb_alias(StringScanner, rb_intern("bol?"), rb_intern("beginning_of_line?")); rb_define_method(StringScanner, "eos?", strscan_eos_p, 0); - rb_define_method(StringScanner, "empty?", strscan_empty_p, 0); rb_define_method(StringScanner, "rest?", strscan_rest_p, 0); rb_define_method(StringScanner, "matched?", strscan_matched_p, 0); @@ -1645,9 +2293,12 @@ Init_strscan(void) rb_define_method(StringScanner, "rest", strscan_rest, 0); rb_define_method(StringScanner, "rest_size", strscan_rest_size, 0); - rb_define_method(StringScanner, "restsize", strscan_restsize, 0); rb_define_method(StringScanner, "inspect", strscan_inspect, 0); rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0); + + rb_define_method(StringScanner, "named_captures", strscan_named_captures, 0); + + rb_require("strscan/strscan"); } diff --git a/ext/strscan/strscan.gemspec b/ext/strscan/strscan.gemspec index 5d8119ea4c..47180bb8d8 100644 --- a/ext/strscan/strscan.gemspec +++ b/ext/strscan/strscan.gemspec @@ -16,13 +16,34 @@ Gem::Specification.new do |s| s.summary = "Provides lexical scanning operations on a String." s.description = "Provides lexical scanning operations on a String." - s.require_path = %w{lib} - s.files = %w{ext/strscan/extconf.rb ext/strscan/strscan.c} - s.extensions = %w{ext/strscan/extconf.rb} + files = [ + "COPYING", + "LICENSE.txt", + "lib/strscan/strscan.rb" + ] + + s.require_paths = %w{lib} + + if RUBY_ENGINE == "jruby" + files << "lib/strscan.jar" + files << "ext/jruby/lib/strscan.rb" + s.require_paths += %w{ext/jruby/lib} + s.platform = "java" + else + files << "ext/strscan/extconf.rb" + files << "ext/strscan/strscan.c" + s.rdoc_options << "-idoc" + s.extra_rdoc_files = [ + ".rdoc_options", + *Dir.glob("doc/strscan/**/*") + ] + s.extensions = %w{ext/strscan/extconf.rb} + end + s.files = files s.required_ruby_version = ">= 2.4.0" - s.authors = ["Minero Aoki", "Sutou Kouhei"] - s.email = [nil, "kou@cozmixng.org"] + s.authors = ["Minero Aoki", "Sutou Kouhei", "Charles Oliver Nutter"] + s.email = [nil, "kou@cozmixng.org", "headius@headius.com"] s.homepage = "https://github.com/ruby/strscan" s.licenses = ["Ruby", "BSD-2-Clause"] end diff --git a/ext/syslog/depend b/ext/syslog/depend deleted file mode 100644 index fb98401e52..0000000000 --- a/ext/syslog/depend +++ /dev/null @@ -1,162 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -syslog.o: $(RUBY_EXTCONF_H) -syslog.o: $(arch_hdrdir)/ruby/config.h -syslog.o: $(hdrdir)/ruby/internal/anyargs.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/char.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/double.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/int.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/long.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/short.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -syslog.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -syslog.o: $(hdrdir)/ruby/internal/assume.h -syslog.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -syslog.o: $(hdrdir)/ruby/internal/attr/artificial.h -syslog.o: $(hdrdir)/ruby/internal/attr/cold.h -syslog.o: $(hdrdir)/ruby/internal/attr/const.h -syslog.o: $(hdrdir)/ruby/internal/attr/constexpr.h -syslog.o: $(hdrdir)/ruby/internal/attr/deprecated.h -syslog.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -syslog.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -syslog.o: $(hdrdir)/ruby/internal/attr/error.h -syslog.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -syslog.o: $(hdrdir)/ruby/internal/attr/forceinline.h -syslog.o: $(hdrdir)/ruby/internal/attr/format.h -syslog.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -syslog.o: $(hdrdir)/ruby/internal/attr/noalias.h -syslog.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -syslog.o: $(hdrdir)/ruby/internal/attr/noexcept.h -syslog.o: $(hdrdir)/ruby/internal/attr/noinline.h -syslog.o: $(hdrdir)/ruby/internal/attr/nonnull.h -syslog.o: $(hdrdir)/ruby/internal/attr/noreturn.h -syslog.o: $(hdrdir)/ruby/internal/attr/pure.h -syslog.o: $(hdrdir)/ruby/internal/attr/restrict.h -syslog.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -syslog.o: $(hdrdir)/ruby/internal/attr/warning.h -syslog.o: $(hdrdir)/ruby/internal/attr/weakref.h -syslog.o: $(hdrdir)/ruby/internal/cast.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -syslog.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -syslog.o: $(hdrdir)/ruby/internal/compiler_since.h -syslog.o: $(hdrdir)/ruby/internal/config.h -syslog.o: $(hdrdir)/ruby/internal/constant_p.h -syslog.o: $(hdrdir)/ruby/internal/core.h -syslog.o: $(hdrdir)/ruby/internal/core/rarray.h -syslog.o: $(hdrdir)/ruby/internal/core/rbasic.h -syslog.o: $(hdrdir)/ruby/internal/core/rbignum.h -syslog.o: $(hdrdir)/ruby/internal/core/rclass.h -syslog.o: $(hdrdir)/ruby/internal/core/rdata.h -syslog.o: $(hdrdir)/ruby/internal/core/rfile.h -syslog.o: $(hdrdir)/ruby/internal/core/rhash.h -syslog.o: $(hdrdir)/ruby/internal/core/robject.h -syslog.o: $(hdrdir)/ruby/internal/core/rregexp.h -syslog.o: $(hdrdir)/ruby/internal/core/rstring.h -syslog.o: $(hdrdir)/ruby/internal/core/rstruct.h -syslog.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -syslog.o: $(hdrdir)/ruby/internal/ctype.h -syslog.o: $(hdrdir)/ruby/internal/dllexport.h -syslog.o: $(hdrdir)/ruby/internal/dosish.h -syslog.o: $(hdrdir)/ruby/internal/error.h -syslog.o: $(hdrdir)/ruby/internal/eval.h -syslog.o: $(hdrdir)/ruby/internal/event.h -syslog.o: $(hdrdir)/ruby/internal/fl_type.h -syslog.o: $(hdrdir)/ruby/internal/gc.h -syslog.o: $(hdrdir)/ruby/internal/glob.h -syslog.o: $(hdrdir)/ruby/internal/globals.h -syslog.o: $(hdrdir)/ruby/internal/has/attribute.h -syslog.o: $(hdrdir)/ruby/internal/has/builtin.h -syslog.o: $(hdrdir)/ruby/internal/has/c_attribute.h -syslog.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -syslog.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -syslog.o: $(hdrdir)/ruby/internal/has/extension.h -syslog.o: $(hdrdir)/ruby/internal/has/feature.h -syslog.o: $(hdrdir)/ruby/internal/has/warning.h -syslog.o: $(hdrdir)/ruby/internal/intern/array.h -syslog.o: $(hdrdir)/ruby/internal/intern/bignum.h -syslog.o: $(hdrdir)/ruby/internal/intern/class.h -syslog.o: $(hdrdir)/ruby/internal/intern/compar.h -syslog.o: $(hdrdir)/ruby/internal/intern/complex.h -syslog.o: $(hdrdir)/ruby/internal/intern/cont.h -syslog.o: $(hdrdir)/ruby/internal/intern/dir.h -syslog.o: $(hdrdir)/ruby/internal/intern/enum.h -syslog.o: $(hdrdir)/ruby/internal/intern/enumerator.h -syslog.o: $(hdrdir)/ruby/internal/intern/error.h -syslog.o: $(hdrdir)/ruby/internal/intern/eval.h -syslog.o: $(hdrdir)/ruby/internal/intern/file.h -syslog.o: $(hdrdir)/ruby/internal/intern/gc.h -syslog.o: $(hdrdir)/ruby/internal/intern/hash.h -syslog.o: $(hdrdir)/ruby/internal/intern/io.h -syslog.o: $(hdrdir)/ruby/internal/intern/load.h -syslog.o: $(hdrdir)/ruby/internal/intern/marshal.h -syslog.o: $(hdrdir)/ruby/internal/intern/numeric.h -syslog.o: $(hdrdir)/ruby/internal/intern/object.h -syslog.o: $(hdrdir)/ruby/internal/intern/parse.h -syslog.o: $(hdrdir)/ruby/internal/intern/proc.h -syslog.o: $(hdrdir)/ruby/internal/intern/process.h -syslog.o: $(hdrdir)/ruby/internal/intern/random.h -syslog.o: $(hdrdir)/ruby/internal/intern/range.h -syslog.o: $(hdrdir)/ruby/internal/intern/rational.h -syslog.o: $(hdrdir)/ruby/internal/intern/re.h -syslog.o: $(hdrdir)/ruby/internal/intern/ruby.h -syslog.o: $(hdrdir)/ruby/internal/intern/select.h -syslog.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -syslog.o: $(hdrdir)/ruby/internal/intern/signal.h -syslog.o: $(hdrdir)/ruby/internal/intern/sprintf.h -syslog.o: $(hdrdir)/ruby/internal/intern/string.h -syslog.o: $(hdrdir)/ruby/internal/intern/struct.h -syslog.o: $(hdrdir)/ruby/internal/intern/thread.h -syslog.o: $(hdrdir)/ruby/internal/intern/time.h -syslog.o: $(hdrdir)/ruby/internal/intern/variable.h -syslog.o: $(hdrdir)/ruby/internal/intern/vm.h -syslog.o: $(hdrdir)/ruby/internal/interpreter.h -syslog.o: $(hdrdir)/ruby/internal/iterator.h -syslog.o: $(hdrdir)/ruby/internal/memory.h -syslog.o: $(hdrdir)/ruby/internal/method.h -syslog.o: $(hdrdir)/ruby/internal/module.h -syslog.o: $(hdrdir)/ruby/internal/newobj.h -syslog.o: $(hdrdir)/ruby/internal/rgengc.h -syslog.o: $(hdrdir)/ruby/internal/scan_args.h -syslog.o: $(hdrdir)/ruby/internal/special_consts.h -syslog.o: $(hdrdir)/ruby/internal/static_assert.h -syslog.o: $(hdrdir)/ruby/internal/stdalign.h -syslog.o: $(hdrdir)/ruby/internal/stdbool.h -syslog.o: $(hdrdir)/ruby/internal/symbol.h -syslog.o: $(hdrdir)/ruby/internal/value.h -syslog.o: $(hdrdir)/ruby/internal/value_type.h -syslog.o: $(hdrdir)/ruby/internal/variable.h -syslog.o: $(hdrdir)/ruby/internal/warning_push.h -syslog.o: $(hdrdir)/ruby/internal/xmalloc.h -syslog.o: $(hdrdir)/ruby/assert.h -syslog.o: $(hdrdir)/ruby/backward.h -syslog.o: $(hdrdir)/ruby/backward/2/assume.h -syslog.o: $(hdrdir)/ruby/backward/2/attributes.h -syslog.o: $(hdrdir)/ruby/backward/2/bool.h -syslog.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -syslog.o: $(hdrdir)/ruby/backward/2/inttypes.h -syslog.o: $(hdrdir)/ruby/backward/2/limits.h -syslog.o: $(hdrdir)/ruby/backward/2/long_long.h -syslog.o: $(hdrdir)/ruby/backward/2/stdalign.h -syslog.o: $(hdrdir)/ruby/backward/2/stdarg.h -syslog.o: $(hdrdir)/ruby/defines.h -syslog.o: $(hdrdir)/ruby/intern.h -syslog.o: $(hdrdir)/ruby/missing.h -syslog.o: $(hdrdir)/ruby/ruby.h -syslog.o: $(hdrdir)/ruby/st.h -syslog.o: $(hdrdir)/ruby/subst.h -syslog.o: $(hdrdir)/ruby/util.h -syslog.o: syslog.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/syslog/extconf.rb b/ext/syslog/extconf.rb deleted file mode 100644 index 1230a4d52e..0000000000 --- a/ext/syslog/extconf.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: false -# $RoughId: extconf.rb,v 1.3 2001/11/24 17:49:26 knu Exp $ -# $Id$ - -require 'mkmf' - -have_library("log") # for Android - -have_header("syslog.h") && - have_func("openlog") && - have_func("setlogmask") && - create_makefile("syslog") - diff --git a/ext/syslog/lib/syslog/logger.rb b/ext/syslog/lib/syslog/logger.rb deleted file mode 100644 index 453ca2785c..0000000000 --- a/ext/syslog/lib/syslog/logger.rb +++ /dev/null @@ -1,209 +0,0 @@ -# frozen_string_literal: false -require 'syslog' -require 'logger' - -## -# Syslog::Logger is a Logger work-alike that logs via syslog instead of to a -# file. You can use Syslog::Logger to aggregate logs between multiple -# machines. -# -# By default, Syslog::Logger uses the program name 'ruby', but this can be -# changed via the first argument to Syslog::Logger.new. -# -# NOTE! You can only set the Syslog::Logger program name when you initialize -# Syslog::Logger for the first time. This is a limitation of the way -# Syslog::Logger uses syslog (and in some ways, a limitation of the way -# syslog(3) works). Attempts to change Syslog::Logger's program name after -# the first initialization will be ignored. -# -# === Example -# -# The following will log to syslogd on your local machine: -# -# require 'syslog/logger' -# -# log = Syslog::Logger.new 'my_program' -# log.info 'this line will be logged via syslog(3)' -# -# Also the facility may be set to specify the facility level which will be used: -# -# log.info 'this line will be logged using Syslog default facility level' -# -# log_local1 = Syslog::Logger.new 'my_program', Syslog::LOG_LOCAL1 -# log_local1.info 'this line will be logged using local1 facility level' -# -# -# You may need to perform some syslog.conf setup first. For a BSD machine add -# the following lines to /etc/syslog.conf: -# -# !my_program -# *.* /var/log/my_program.log -# -# Then touch /var/log/my_program.log and signal syslogd with a HUP -# (killall -HUP syslogd, on FreeBSD). -# -# If you wish to have logs automatically roll over and archive, see the -# newsyslog.conf(5) and newsyslog(8) man pages. - -class Syslog::Logger - # Default formatter for log messages. - class Formatter - def call severity, time, progname, msg - clean msg - end - - private - - ## - # Clean up messages so they're nice and pretty. - - def clean message - message = message.to_s.strip - message.gsub!(/\e\[[0-9;]*m/, '') # remove useless ansi color codes - return message - end - end - - ## - # The version of Syslog::Logger you are using. - - VERSION = '2.1.0' - - ## - # Maps Logger warning types to syslog(3) warning types. - # - # Messages from Ruby applications are not considered as critical as messages - # from other system daemons using syslog(3), so most messages are reduced by - # one level. For example, a fatal message for Ruby's Logger is considered - # an error for syslog(3). - - LEVEL_MAP = { - ::Logger::UNKNOWN => Syslog::LOG_ALERT, - ::Logger::FATAL => Syslog::LOG_ERR, - ::Logger::ERROR => Syslog::LOG_WARNING, - ::Logger::WARN => Syslog::LOG_NOTICE, - ::Logger::INFO => Syslog::LOG_INFO, - ::Logger::DEBUG => Syslog::LOG_DEBUG, - } - - ## - # Returns the internal Syslog object that is initialized when the - # first instance is created. - - def self.syslog - @@syslog - end - - ## - # Specifies the internal Syslog object to be used. - - def self.syslog= syslog - @@syslog = syslog - end - - ## - # Builds a methods for level +meth+. - - def self.make_methods meth - level = ::Logger.const_get(meth.upcase) - eval <<-EOM, nil, __FILE__, __LINE__ + 1 - def #{meth}(message = nil, &block) - add(#{level}, message, &block) - end - - def #{meth}? - level <= #{level} - end - EOM - end - - ## - # :method: unknown - # - # Logs a +message+ at the unknown (syslog alert) log level, or logs the - # message returned from the block. - - ## - # :method: fatal - # - # Logs a +message+ at the fatal (syslog err) log level, or logs the message - # returned from the block. - - ## - # :method: error - # - # Logs a +message+ at the error (syslog warning) log level, or logs the - # message returned from the block. - - ## - # :method: warn - # - # Logs a +message+ at the warn (syslog notice) log level, or logs the - # message returned from the block. - - ## - # :method: info - # - # Logs a +message+ at the info (syslog info) log level, or logs the message - # returned from the block. - - ## - # :method: debug - # - # Logs a +message+ at the debug (syslog debug) log level, or logs the - # message returned from the block. - - Logger::Severity::constants.each do |severity| - make_methods severity.downcase - end - - ## - # Log level for Logger compatibility. - - attr_accessor :level - - # Logging formatter, as a +Proc+ that will take four arguments and - # return the formatted message. The arguments are: - # - # +severity+:: The Severity of the log message. - # +time+:: A Time instance representing when the message was logged. - # +progname+:: The #progname configured, or passed to the logger method. - # +msg+:: The _Object_ the user passed to the log message; not necessarily a - # String. - # - # The block should return an Object that can be written to the logging - # device via +write+. The default formatter is used when no formatter is - # set. - attr_accessor :formatter - - ## - # The facility argument is used to specify what type of program is logging the message. - - attr_accessor :facility - - ## - # Fills in variables for Logger compatibility. If this is the first - # instance of Syslog::Logger, +program_name+ may be set to change the logged - # program name. The +facility+ may be set to specify the facility level which will be used. - # - # Due to the way syslog works, only one program name may be chosen. - - def initialize program_name = 'ruby', facility = nil - @level = ::Logger::DEBUG - @formatter = Formatter.new - - @@syslog ||= Syslog.open(program_name) - - @facility = (facility || @@syslog.facility) - end - - ## - # Almost duplicates Logger#add. +progname+ is ignored. - - def add severity, message = nil, progname = nil, &block - severity ||= ::Logger::UNKNOWN - level <= severity and - @@syslog.log( (LEVEL_MAP[severity] | @facility), '%s', formatter.call(severity, Time.now, progname, (message || block.call)) ) - true - end -end diff --git a/ext/syslog/syslog.c b/ext/syslog/syslog.c deleted file mode 100644 index 4c540fc9c7..0000000000 --- a/ext/syslog/syslog.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * UNIX Syslog extension for Ruby - * Amos Gouaux, University of Texas at Dallas - * <amos+ruby@utdallas.edu> - * Documented by mathew <meta@pobox.com> - * - * $RoughId: syslog.c,v 1.21 2002/02/25 12:21:17 knu Exp $ - * $Id$ - */ - -#include "ruby/ruby.h" -#include "ruby/util.h" -#include <syslog.h> - -/* Syslog class */ -static VALUE mSyslog; -/* - * Module holding all Syslog constants. See Syslog::log and - * Syslog::open for constant descriptions. - */ -static VALUE mSyslogConstants; -/* Module holding Syslog option constants */ -static VALUE mSyslogOption; -/* Module holding Syslog facility constants */ -static VALUE mSyslogFacility; -/* Module holding Syslog level constants */ -static VALUE mSyslogLevel; -/* Module holding Syslog utility macros */ -static VALUE mSyslogMacros; - -static const char *syslog_ident = NULL; -static int syslog_options = -1, syslog_facility = -1, syslog_mask = -1; -static int syslog_opened = 0; - -/* Package helper routines */ -static void syslog_write(int pri, int argc, VALUE *argv) -{ - VALUE str; - - if (argc < 1) { - rb_raise(rb_eArgError, "no log message supplied"); - } - - if (!syslog_opened) { - rb_raise(rb_eRuntimeError, "must open syslog before write"); - } - - str = rb_f_sprintf(argc, argv); - - syslog(pri, "%s", RSTRING_PTR(str)); -} - -/* Closes the syslog facility. - * Raises a runtime exception if it is not open. - */ -static VALUE mSyslog_close(VALUE self) -{ - if (!syslog_opened) { - rb_raise(rb_eRuntimeError, "syslog not opened"); - } - - closelog(); - - xfree((void *)syslog_ident); - syslog_ident = NULL; - syslog_options = syslog_facility = syslog_mask = -1; - syslog_opened = 0; - - return Qnil; -} - -/* call-seq: - * open(ident, options, facility) => syslog - * - * :yields: syslog - * - * Open the syslog facility. - * Raises a runtime exception if it is already open. - * - * Can be called with or without a code block. If called with a block, the - * Syslog object created is passed to the block. - * - * If the syslog is already open, raises a RuntimeError. - * - * +ident+ is a String which identifies the calling program. - * - * +options+ is the logical OR of any of the following: - * - * LOG_CONS:: If there is an error while sending to the system logger, - * write directly to the console instead. - * - * LOG_NDELAY:: Open the connection now, rather than waiting for the first - * message to be written. - * - * LOG_NOWAIT:: Don't wait for any child processes created while logging - * messages. (Has no effect on Linux.) - * - * LOG_ODELAY:: Opposite of LOG_NDELAY; wait until a message is sent before - * opening the connection. (This is the default.) - * - * LOG_PERROR:: Print the message to stderr as well as sending it to syslog. - * (Not in POSIX.1-2001.) - * - * LOG_PID:: Include the current process ID with each message. - * - * +facility+ describes the type of program opening the syslog, and is - * the logical OR of any of the following which are defined for the host OS: - * - * LOG_AUTH:: Security or authorization. Deprecated, use LOG_AUTHPRIV - * instead. - * - * LOG_AUTHPRIV:: Security or authorization messages which should be kept - * private. - * - * LOG_CONSOLE:: System console message. - * - * LOG_CRON:: System task scheduler (cron or at). - * - * LOG_DAEMON:: A system daemon which has no facility value of its own. - * - * LOG_FTP:: An FTP server. - * - * LOG_KERN:: A kernel message (not sendable by user processes, so not of - * much use to Ruby, but listed here for completeness). - * - * LOG_LPR:: Line printer subsystem. - * - * LOG_MAIL:: Mail delivery or transport subsystem. - * - * LOG_NEWS:: Usenet news system. - * - * LOG_NTP:: Network Time Protocol server. - * - * LOG_SECURITY:: General security message. - * - * LOG_SYSLOG:: Messages generated internally by syslog. - * - * LOG_USER:: Generic user-level message. - * - * LOG_UUCP:: UUCP subsystem. - * - * LOG_LOCAL0 to LOG_LOCAL7:: Locally-defined facilities. - * - * Example: - * - * Syslog.open("webrick", Syslog::LOG_PID, - * Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3) - * - */ -static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self) -{ - VALUE ident, opt, fac; - const char *ident_ptr; - - if (syslog_opened) { - rb_raise(rb_eRuntimeError, "syslog already open"); - } - - rb_scan_args(argc, argv, "03", &ident, &opt, &fac); - - if (NIL_P(ident)) { - ident = rb_gv_get("$0"); - } - ident_ptr = StringValueCStr(ident); - syslog_ident = strdup(ident_ptr); - - if (NIL_P(opt)) { - syslog_options = LOG_PID | LOG_CONS; - } else { - syslog_options = NUM2INT(opt); - } - - if (NIL_P(fac)) { - syslog_facility = LOG_USER; - } else { - syslog_facility = NUM2INT(fac); - } - - openlog(syslog_ident, syslog_options, syslog_facility); - - syslog_opened = 1; - - setlogmask(syslog_mask = setlogmask(0)); - - /* be like File.new.open {...} */ - if (rb_block_given_p()) { - rb_ensure(rb_yield, self, mSyslog_close, self); - } - - return self; -} - -/* call-seq: - * reopen(ident, options, facility) => syslog - * - * :yields: syslog - * - * Closes and then reopens the syslog. - * - * Arguments are the same as for open(). - */ -static VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self) -{ - mSyslog_close(self); - - return mSyslog_open(argc, argv, self); -} - -/* call-seq: - * opened? - * - * Returns true if the syslog is open. - */ -static VALUE mSyslog_isopen(VALUE self) -{ - return syslog_opened ? Qtrue : Qfalse; -} - -/* Returns the identity string used in the last call to open() - */ -static VALUE mSyslog_ident(VALUE self) -{ - return syslog_opened ? rb_str_new2(syslog_ident) : Qnil; -} - -/* Returns the options bitmask used in the last call to open() - */ -static VALUE mSyslog_options(VALUE self) -{ - return syslog_opened ? INT2NUM(syslog_options) : Qnil; -} - -/* Returns the facility number used in the last call to open() - */ -static VALUE mSyslog_facility(VALUE self) -{ - return syslog_opened ? INT2NUM(syslog_facility) : Qnil; -} - -/* Returns the log priority mask in effect. The mask is not reset by opening - * or closing syslog. - */ -static VALUE mSyslog_get_mask(VALUE self) -{ - return syslog_opened ? INT2NUM(syslog_mask) : Qnil; -} - -/* call-seq: - * mask=(priority_mask) - * - * Sets the log priority mask. A method LOG_UPTO is defined to make it easier - * to set mask values. Example: - * - * Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR) - * - * Alternatively, specific priorities can be selected and added together using - * binary OR. Example: - * - * Syslog.mask = Syslog::LOG_MASK(Syslog::LOG_ERR) | Syslog::LOG_MASK(Syslog::LOG_CRIT) - * - * The priority mask persists through calls to open() and close(). - */ -static VALUE mSyslog_set_mask(VALUE self, VALUE mask) -{ - if (!syslog_opened) { - rb_raise(rb_eRuntimeError, "must open syslog before setting log mask"); - } - - setlogmask(syslog_mask = NUM2INT(mask)); - - return mask; -} - -/* call-seq: - * log(priority, format_string, *format_args) - * - * Log a message with the specified priority. Example: - * - * Syslog.log(Syslog::LOG_CRIT, "Out of disk space") - * Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER']) - * - * The priority levels, in descending order, are: - * - * LOG_EMERG:: System is unusable - * LOG_ALERT:: Action needs to be taken immediately - * LOG_CRIT:: A critical condition has occurred - * LOG_ERR:: An error occurred - * LOG_WARNING:: Warning of a possible problem - * LOG_NOTICE:: A normal but significant condition occurred - * LOG_INFO:: Informational message - * LOG_DEBUG:: Debugging information - * - * Each priority level also has a shortcut method that logs with it's named priority. - * As an example, the two following statements would produce the same result: - * - * Syslog.log(Syslog::LOG_ALERT, "Out of memory") - * Syslog.alert("Out of memory") - * - */ -static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self) -{ - VALUE pri; - - rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); - - argc--; - pri = *argv++; - - if (!FIXNUM_P(pri)) { - rb_raise(rb_eTypeError, "type mismatch: %"PRIsVALUE" given", rb_obj_class(pri)); - } - - syslog_write(FIX2INT(pri), argc, argv); - - return self; -} - -/* Returns an inspect() string summarizing the object state. - */ -static VALUE mSyslog_inspect(VALUE self) -{ - Check_Type(self, T_MODULE); - - if (!syslog_opened) - return rb_sprintf("<#%"PRIsVALUE": opened=false>", self); - - return rb_sprintf("<#%"PRIsVALUE": opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>", - self, - syslog_ident, - syslog_options, - syslog_facility, - syslog_mask); -} - -/* Returns self, for backward compatibility. - */ -static VALUE mSyslog_instance(VALUE self) -{ - return self; -} - -#define define_syslog_shortcut_method(pri, name) \ -static VALUE mSyslog_##name(int argc, VALUE *argv, VALUE self) \ -{ \ - syslog_write((pri), argc, argv); \ -\ - return self; \ -} - -#ifdef LOG_EMERG -define_syslog_shortcut_method(LOG_EMERG, emerg) -#endif -#ifdef LOG_ALERT -define_syslog_shortcut_method(LOG_ALERT, alert) -#endif -#ifdef LOG_CRIT -define_syslog_shortcut_method(LOG_CRIT, crit) -#endif -#ifdef LOG_ERR -define_syslog_shortcut_method(LOG_ERR, err) -#endif -#ifdef LOG_WARNING -define_syslog_shortcut_method(LOG_WARNING, warning) -#endif -#ifdef LOG_NOTICE -define_syslog_shortcut_method(LOG_NOTICE, notice) -#endif -#ifdef LOG_INFO -define_syslog_shortcut_method(LOG_INFO, info) -#endif -#ifdef LOG_DEBUG -define_syslog_shortcut_method(LOG_DEBUG, debug) -#endif - -/* call-seq: - * LOG_MASK(priority_level) => priority_mask - * - * Generates a mask bit for a priority level. See #mask= - */ -static VALUE mSyslogMacros_LOG_MASK(VALUE mod, VALUE pri) -{ - return INT2FIX(LOG_MASK(NUM2INT(pri))); -} - -/* call-seq: - * LOG_UPTO(priority_level) => priority_mask - * - * Generates a mask value for priority levels at or below the level specified. - * See #mask= - */ -static VALUE mSyslogMacros_LOG_UPTO(VALUE mod, VALUE pri) -{ - return INT2FIX(LOG_UPTO(NUM2INT(pri))); -} - -static VALUE mSyslogMacros_included(VALUE mod, VALUE target) -{ - rb_extend_object(target, mSyslogMacros); - return mod; -} - -/* The syslog package provides a Ruby interface to the POSIX system logging - * facility. - * - * Syslog messages are typically passed to a central logging daemon. - * The daemon may filter them; route them into different files (usually - * found under /var/log); place them in SQL databases; forward - * them to centralized logging servers via TCP or UDP; or even alert the - * system administrator via email, pager or text message. - * - * Unlike application-level logging via Logger or Log4r, syslog is designed - * to allow secure tamper-proof logging. - * - * The syslog protocol is standardized in RFC 5424. - */ -void Init_syslog(void) -{ -#undef rb_intern - mSyslog = rb_define_module("Syslog"); - - mSyslogConstants = rb_define_module_under(mSyslog, "Constants"); - - mSyslogOption = rb_define_module_under(mSyslog, "Option"); - mSyslogFacility = rb_define_module_under(mSyslog, "Facility"); - mSyslogLevel = rb_define_module_under(mSyslog, "Level"); - mSyslogMacros = rb_define_module_under(mSyslog, "Macros"); - - rb_define_module_function(mSyslog, "open", mSyslog_open, -1); - rb_define_module_function(mSyslog, "reopen", mSyslog_reopen, -1); - rb_define_module_function(mSyslog, "open!", mSyslog_reopen, -1); - rb_define_module_function(mSyslog, "opened?", mSyslog_isopen, 0); - - rb_define_module_function(mSyslog, "ident", mSyslog_ident, 0); - rb_define_module_function(mSyslog, "options", mSyslog_options, 0); - rb_define_module_function(mSyslog, "facility", mSyslog_facility, 0); - - rb_define_module_function(mSyslog, "log", mSyslog_log, -1); - rb_define_module_function(mSyslog, "close", mSyslog_close, 0); - rb_define_module_function(mSyslog, "mask", mSyslog_get_mask, 0); - rb_define_module_function(mSyslog, "mask=", mSyslog_set_mask, 1); - - rb_define_singleton_method(mSyslog, "inspect", mSyslog_inspect, 0); - rb_define_module_function(mSyslog, "instance", mSyslog_instance, 0); - - /* Syslog options */ - -#define rb_define_syslog_option(c) \ - rb_define_const(mSyslogOption, #c, INT2NUM(c)) - -#ifdef LOG_PID - rb_define_syslog_option(LOG_PID); -#endif -#ifdef LOG_CONS - rb_define_syslog_option(LOG_CONS); -#endif -#ifdef LOG_ODELAY - rb_define_syslog_option(LOG_ODELAY); /* deprecated */ -#endif -#ifdef LOG_NDELAY - rb_define_syslog_option(LOG_NDELAY); -#endif -#ifdef LOG_NOWAIT - rb_define_syslog_option(LOG_NOWAIT); /* deprecated */ -#endif -#ifdef LOG_PERROR - rb_define_syslog_option(LOG_PERROR); -#endif - - /* Syslog facilities */ - -#define rb_define_syslog_facility(c) \ - rb_define_const(mSyslogFacility, #c, INT2NUM(c)) - -#ifdef LOG_AUTH - rb_define_syslog_facility(LOG_AUTH); -#endif -#ifdef LOG_AUTHPRIV - rb_define_syslog_facility(LOG_AUTHPRIV); -#endif -#ifdef LOG_CONSOLE - rb_define_syslog_facility(LOG_CONSOLE); -#endif -#ifdef LOG_CRON - rb_define_syslog_facility(LOG_CRON); -#endif -#ifdef LOG_DAEMON - rb_define_syslog_facility(LOG_DAEMON); -#endif -#ifdef LOG_FTP - rb_define_syslog_facility(LOG_FTP); -#endif -#ifdef LOG_KERN - rb_define_syslog_facility(LOG_KERN); -#endif -#ifdef LOG_LPR - rb_define_syslog_facility(LOG_LPR); -#endif -#ifdef LOG_MAIL - rb_define_syslog_facility(LOG_MAIL); -#endif -#ifdef LOG_NEWS - rb_define_syslog_facility(LOG_NEWS); -#endif -#ifdef LOG_NTP - rb_define_syslog_facility(LOG_NTP); -#endif -#ifdef LOG_SECURITY - rb_define_syslog_facility(LOG_SECURITY); -#endif -#ifdef LOG_SYSLOG - rb_define_syslog_facility(LOG_SYSLOG); -#endif -#ifdef LOG_USER - rb_define_syslog_facility(LOG_USER); -#endif -#ifdef LOG_UUCP - rb_define_syslog_facility(LOG_UUCP); -#endif -#ifdef LOG_LOCAL0 - rb_define_syslog_facility(LOG_LOCAL0); -#endif -#ifdef LOG_LOCAL1 - rb_define_syslog_facility(LOG_LOCAL1); -#endif -#ifdef LOG_LOCAL2 - rb_define_syslog_facility(LOG_LOCAL2); -#endif -#ifdef LOG_LOCAL3 - rb_define_syslog_facility(LOG_LOCAL3); -#endif -#ifdef LOG_LOCAL4 - rb_define_syslog_facility(LOG_LOCAL4); -#endif -#ifdef LOG_LOCAL5 - rb_define_syslog_facility(LOG_LOCAL5); -#endif -#ifdef LOG_LOCAL6 - rb_define_syslog_facility(LOG_LOCAL6); -#endif -#ifdef LOG_LOCAL7 - rb_define_syslog_facility(LOG_LOCAL7); -#endif - - /* Syslog levels and the shortcut methods */ - -#define rb_define_syslog_level(c, m) \ - rb_define_const(mSyslogLevel, #c, INT2NUM(c)); \ - rb_define_module_function(mSyslog, #m, mSyslog_##m, -1) - -#ifdef LOG_EMERG - rb_define_syslog_level(LOG_EMERG, emerg); -#endif -#ifdef LOG_ALERT - rb_define_syslog_level(LOG_ALERT, alert); -#endif -#ifdef LOG_CRIT - rb_define_syslog_level(LOG_CRIT, crit); -#endif -#ifdef LOG_ERR - rb_define_syslog_level(LOG_ERR, err); -#endif -#ifdef LOG_WARNING - rb_define_syslog_level(LOG_WARNING, warning); -#endif -#ifdef LOG_NOTICE - rb_define_syslog_level(LOG_NOTICE, notice); -#endif -#ifdef LOG_INFO - rb_define_syslog_level(LOG_INFO, info); -#endif -#ifdef LOG_DEBUG - rb_define_syslog_level(LOG_DEBUG, debug); -#endif - - /* Syslog macros */ - - rb_define_method(mSyslogMacros, "LOG_MASK", mSyslogMacros_LOG_MASK, 1); - rb_define_method(mSyslogMacros, "LOG_UPTO", mSyslogMacros_LOG_UPTO, 1); - rb_define_singleton_method(mSyslogMacros, "included", mSyslogMacros_included, 1); - - rb_include_module(mSyslogConstants, mSyslogOption); - rb_include_module(mSyslogConstants, mSyslogFacility); - rb_include_module(mSyslogConstants, mSyslogLevel); - rb_funcall(mSyslogConstants, rb_intern("include"), 1, mSyslogMacros); - - rb_define_singleton_method(mSyslogConstants, "included", mSyslogMacros_included, 1); - rb_funcall(mSyslog, rb_intern("include"), 1, mSyslogConstants); -} diff --git a/ext/syslog/syslog.gemspec b/ext/syslog/syslog.gemspec deleted file mode 100644 index 8f73f5ad0d..0000000000 --- a/ext/syslog/syslog.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -Gem::Specification.new do |spec| - spec.name = "syslog" - spec.version = "0.1.0" - spec.authors = ["Akinori MUSHA"] - spec.email = ["knu@idaemons.org"] - - spec.summary = %q{Ruby interface for the POSIX system logging facility.} - spec.description = %q{Ruby interface for the POSIX system logging facility.} - spec.homepage = "https://github.com/ruby/syslog" - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") - spec.licenses = ["Ruby", "BSD-2-Clause"] - - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = spec.homepage - - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.extensions = ["ext/syslog/extconf.rb"] - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] -end diff --git a/ext/syslog/syslog.txt b/ext/syslog/syslog.txt deleted file mode 100644 index 1507a87924..0000000000 --- a/ext/syslog/syslog.txt +++ /dev/null @@ -1,124 +0,0 @@ -.\" syslog.txt - -*- Indented-Text -*- -$RoughId: syslog.txt,v 1.18 2002/02/25 08:20:14 knu Exp $ -$Id$ - -UNIX Syslog extension for Ruby -Amos Gouaux, University of Texas at Dallas -<amos+ruby@utdallas.edu> -& -Akinori MUSHA -<knu@iDaemons.org> - -Contact: - - Akinori MUSHA <knu@iDaemons.org> (current maintainer) - -** Syslog(Module) - -Included Modules: Syslog::Constants - -require 'syslog' - -A Simple wrapper for the UNIX syslog system calls that might be handy -if you're writing a server in Ruby. For the details of the syslog(8) -architecture and constants, see the syslog(3) manual page of your -platform. - -Module Methods: - - open(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, - facility = Syslog::LOG_USER) [{ |syslog| ... }] - - Opens syslog with the given options and returns the module - itself. If a block is given, calls it with an argument of - itself. If syslog is already opened, raises RuntimeError. - - Example: - Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY, - Syslog::LOG_FTP) - - open!(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, - facility = Syslog::LOG_USER) - reopen(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, - facility = Syslog::LOG_USER) - - Same as open, but does a close first. - - opened? - - Returns true if syslog opened, otherwise false. - - ident - options - facility - - Returns the parameters given in the last open, respectively. - Every call of Syslog::open resets these values. - - log(pri, message, ...) - - Writes message to syslog. - - Example: - Syslog.log(Syslog::LOG_CRIT, "the sky is falling in %d seconds!", 10) - - crit(message, ...) - emerg(message, ...) - alert(message, ...) - err(message, ...) - warning(message, ...) - notice(message, ...) - info(message, ...) - debug(message, ...) - - These are shortcut methods of Syslog::log(). The lineup may - vary depending on what priorities are defined on your system. - - Example: - Syslog.crit("the sky is falling in %d seconds!", 5) - - mask - mask=(mask) - - Returns or sets the log priority mask. The value of the mask - is persistent and will not be reset by Syslog::open or - Syslog::close. - - Example: - Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR) - - close - - Closes syslog. - - inspect - - Returns the "inspect" string of the Syslog module. - - instance - - Returns the module itself. (Just for backward compatibility) - - LOG_MASK(pri) - - Creates a mask for one priority. - - LOG_UPTO(pri) - - Creates a mask for all priorities up to pri. - -** Syslog::Constants(Module) - -require 'syslog' -include Syslog::Constants - -This module includes the LOG_* constants available on the system. - -Module Methods: - - LOG_MASK(pri) - - Creates a mask for one priority. - - LOG_UPTO(pri) - - Creates a mask for all priorities up to pri. diff --git a/ext/win32/lib/win32/registry.rb b/ext/win32/lib/win32/registry.rb index b5b99ff684..734d6987a2 100644 --- a/ext/win32/lib/win32/registry.rb +++ b/ext/win32/lib/win32/registry.rb @@ -1,84 +1,75 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'fiddle/import' module Win32 - -=begin rdoc -= Win32 Registry - -win32/registry is registry accessor library for Win32 platform. -It uses importer to call Win32 Registry APIs. - -== example - Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg| - value = reg['foo'] # read a value - value = reg['foo', Win32::Registry::REG_SZ] # read a value with type - type, value = reg.read('foo') # read a value - reg['foo'] = 'bar' # write a value - reg['foo', Win32::Registry::REG_SZ] = 'bar' # write a value with type - reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value - - reg.each_value { |name, type, data| ... } # Enumerate values - reg.each_key { |key, wtime| ... } # Enumerate subkeys - - reg.delete_value(name) # Delete a value - reg.delete_key(name) # Delete a subkey - reg.delete_key(name, true) # Delete a subkey recursively - end - -= Reference - -== Win32::Registry class - ---- info - ---- num_keys - ---- max_key_length - ---- num_values - ---- max_value_name_length - ---- max_value_length - ---- descriptor_length - ---- wtime - Returns an item of key information. - -=== constants ---- HKEY_CLASSES_ROOT - ---- HKEY_CURRENT_USER - ---- HKEY_LOCAL_MACHINE - ---- HKEY_PERFORMANCE_DATA - ---- HKEY_CURRENT_CONFIG - ---- HKEY_DYN_DATA - - Win32::Registry object whose key is predefined key. -For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/predefined_keys.asp] article. - -=end rdoc - + # :stopdoc: WCHAR = Encoding::UTF_16LE WCHAR_NUL = "\0".encode(WCHAR).freeze WCHAR_CR = "\r".encode(WCHAR).freeze WCHAR_SIZE = WCHAR_NUL.bytesize - LOCALE = Encoding.find(Encoding.locale_charmap) - + LOCALE = Encoding::UTF_8 + + # :startdoc: + + # win32/registry is registry accessor library for Win32 platform. + # It uses importer to call Win32 Registry APIs. + # + # == example + # Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg| + # value = reg['foo'] # read a value + # value = reg['foo', Win32::Registry::REG_SZ] # read a value with type + # type, value = reg.read('foo') # read a value + # reg['foo'] = 'bar' # write a value + # reg['foo', Win32::Registry::REG_SZ] = 'bar' # write a value with type + # reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value + # + # reg.each_value { |name, type, data| ... } # Enumerate values + # reg.each_key { |key, wtime| ... } # Enumerate subkeys + # + # reg.delete_value(name) # Delete a value + # reg.delete_key(name) # Delete a subkey + # reg.delete_key(name, true) # Delete a subkey recursively + # end + # + # == Predefined keys + # + # * +HKEY_CLASSES_ROOT+ + # * +HKEY_CURRENT_USER+ + # * +HKEY_LOCAL_MACHINE+ + # * +HKEY_PERFORMANCE_DATA+ + # * +HKEY_CURRENT_CONFIG+ + # * +HKEY_DYN_DATA+ + # + # Win32::Registry object whose key is predefined key. + # For detail, see the article[https://learn.microsoft.com/en-us/windows/win32/sysinfo/predefined-keys]. + # + # == Value types + # + # * +REG_NONE+ + # * +REG_SZ+ + # * +REG_EXPAND_SZ+ + # * +REG_BINARY+ + # * +REG_DWORD+ + # * +REG_DWORD_BIG_ENDIAN+ + # * +REG_LINK+ + # * +REG_MULTI_SZ+ + # * +REG_RESOURCE_LIST+ + # * +REG_FULL_RESOURCE_DESCRIPTOR+ + # * +REG_RESOURCE_REQUIREMENTS_LIST+ + # * +REG_QWORD+ + # + # For detail, see the article[https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-value-types]. + # class Registry + # :stopdoc: + # # For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/registry.asp]. # # --- HKEY_* # - # Predefined key ((*handle*)). + # Predefined key *handle*. # These are Integer, not Win32::Registry. # # --- REG_* @@ -100,6 +91,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # If the key is created newly or opened existing key. # See also Registry#disposition method. module Constants + # :stopdoc: HKEY_CLASSES_ROOT = 0x80000000 HKEY_CURRENT_USER = 0x80000001 HKEY_LOCAL_MACHINE = 0x80000002 @@ -115,7 +107,6 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr REG_EXPAND_SZ = 2 REG_BINARY = 3 REG_DWORD = 4 - REG_DWORD_LITTLE_ENDIAN = 4 REG_DWORD_BIG_ENDIAN = 5 REG_LINK = 6 REG_MULTI_SZ = 7 @@ -163,22 +154,29 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end include Constants include Enumerable + # :startdoc: # # Error # class Error < ::StandardError + # :stopdoc: module Kernel32 extend Fiddle::Importer dlload "kernel32.dll" end FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall + # :startdoc: + + # new(code) -> error object + # + # Initializes the message for Win32 API error +code+. def initialize(code) @code = code buff = WCHAR_NUL * 1024 lang = 0 begin - len = FormatMessageW.call(0x1200, 0, code, lang, buff, 1024, 0) + len = FormatMessageW.call(0x1200, nil, code, lang, buff, 1024, nil) msg = buff.byteslice(0, len * WCHAR_SIZE) msg.delete!(WCHAR_CR) msg.chomp! @@ -190,6 +188,8 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end super msg end + + # Win32 API error code. attr_reader :code end @@ -197,8 +197,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Predefined Keys # class PredefinedKey < Registry + # :stopdoc: def initialize(hkey, keyname) - @hkey = hkey + @hkey = Fiddle::Pointer.new(hkey) @parent = nil @keyname = keyname @disposition = REG_OPENED_EXISTING_KEY @@ -224,6 +225,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Win32 APIs # module API + # :stopdoc: include Constants extend Fiddle::Importer dlload "advapi32.dll" @@ -238,7 +240,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr "long RegDeleteKeyW(void *, void *)", "long RegFlushKey(void *)", "long RegCloseKey(void *)", - "long RegQueryInfoKey(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)", + "long RegQueryInfoKeyW(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)", ].each do |fn| cfunc = extern fn, :stdcall const_set cfunc.name.intern, cfunc @@ -254,34 +256,38 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr /^(?:x64|x86_64)/ =~ RUBY_PLATFORM end + TEMPLATE_HANDLE = 'J<' + def packhandle(h) - win64? ? packqw(h) : packdw(h) + [h].pack(TEMPLATE_HANDLE) end def unpackhandle(h) - win64? ? unpackqw(h) : unpackdw(h) + (h + [0].pack(TEMPLATE_HANDLE)).unpack1(TEMPLATE_HANDLE) end + TEMPLATE_DWORD = 'V' + def packdw(dw) - [dw].pack('V') + [dw].pack(TEMPLATE_DWORD) end def unpackdw(dw) - dw += [0].pack('V') - dw.unpack('V')[0] + (dw + [0].pack(TEMPLATE_DWORD)).unpack1(TEMPLATE_DWORD) end + TEMPLATE_QWORD = 'Q<' + def packqw(qw) - [ qw & 0xFFFFFFFF, qw >> 32 ].pack('VV') + [qw].pack(TEMPLATE_QWORD) end def unpackqw(qw) - qw = qw.unpack('VV') - (qw[1] << 32) | qw[0] + (qw + [0].pack(TEMPLATE_QWORD)).unpack1(TEMPLATE_QWORD) end def make_wstr(str) - str.encode(WCHAR) + (str+"\0").encode(WCHAR) end def OpenKey(hkey, name, opt, desired) @@ -294,14 +300,14 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr result = packhandle(0) disp = packdw(0) check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired, - 0, result, disp) + nil, result, disp) [ unpackhandle(result), unpackdw(disp) ] end def EnumValue(hkey, index) name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) - check RegEnumValueW.call(hkey, index, name, size, 0, 0, 0, 0) + check RegEnumValueW.call(hkey, index, name, size, nil, nil, nil, nil) name.byteslice(0, unpackdw(size) * WCHAR_SIZE) end @@ -309,7 +315,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) wtime = ' ' * 8 - check RegEnumKeyExW.call(hkey, index, name, size, 0, 0, 0, wtime) + check RegEnumKeyExW.call(hkey, index, name, size, nil, nil, nil, wtime) [ name.byteslice(0, unpackdw(size) * WCHAR_SIZE), unpackqw(wtime) ] end @@ -317,9 +323,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr type = packdw(0) size = packdw(0) name = make_wstr(name) - check RegQueryValueExW.call(hkey, name, 0, type, 0, size) - data = "\0".force_encoding('ASCII-8BIT') * unpackdw(size) - check RegQueryValueExW.call(hkey, name, 0, type, data, size) + check RegQueryValueExW.call(hkey, name, nil, type, nil, size) + data = "\0".b * unpackdw(size) + check RegQueryValueExW.call(hkey, name, nil, type, data, size) [ unpackdw(type), data[0, unpackdw(size)] ] end @@ -356,25 +362,26 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr maxvaluelen = packdw(0) secdescs = packdw(0) wtime = ' ' * 8 - check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0, + check RegQueryInfoKeyW.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0, values, maxvaluenamelen, maxvaluelen, secdescs, wtime) [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values), unpackdw(maxvaluenamelen), unpackdw(maxvaluelen), unpackdw(secdescs), unpackqw(wtime) ] end end + # :startdoc: # - # Replace %\w+% into the environment value of what is contained between the %'s + # Replace <tt>%</tt>-enclosed substrings in +str+ into the + # environment value of what is contained between the <tt>%</tt>s. # This method is used for REG_EXPAND_SZ. # - # For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API. + # For detail, see ExpandEnvironmentStrings[https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsw] \Win32 \API. # def self.expand_environ(str) str.gsub(Regexp.compile("%([^%]+)%".encode(str.encoding))) { v = $1.encode(LOCALE) - (e = ENV[v] || ENV[v.upcase]; e.encode(str.encoding) if e) || - $& + (ENV[v] || ENV[v.upcase])&.encode(str.encoding) || $& } end @@ -384,27 +391,26 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR REG_RESOURCE_REQUIREMENTS_LIST REG_QWORD ].inject([]) do |ary, type| - type.freeze ary[Constants.const_get(type)] = type ary end.freeze # - # Convert registry type value to readable string. + # Convert registry type value +type+ to readable string. # def self.type2name(type) @@type2name[type] || type.to_s end # - # Convert 64-bit FILETIME integer into Time object. + # Convert 64-bit FILETIME integer +wtime+ into Time object. # def self.wtime2time(wtime) Time.at((wtime - 116444736000000000) / 10000000) end # - # Convert Time object or Integer object into 64-bit FILETIME. + # Convert Time object or Integer object +time+ into 64-bit FILETIME. # def self.time2wtime(time) time.to_i * 10000000 + 116444736000000000 @@ -416,19 +422,22 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr private_class_method :new # - # --- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) + # call-seq: + # open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) + # open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| ... } # - # --- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| ... } + # Open the registry key +subkey+ under +key+. + # +key+ is Win32::Registry object of parent key. + # You can use {predefined key}[rdoc-ref:Win32::Registry@Predefined+keys] +HKEY_+*. + # +desired+ and +opt+ is access mask and key option. # - # Open the registry key subkey under key. - # key is Win32::Registry object of parent key. - # You can use predefined key HKEY_* (see Constants) - # desired and opt is access mask and key option. # For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/regopenkeyex.asp]. - # If block is given, the key is closed automatically. + # + # If block is given, the key +reg+ is yielded and closed + # automatically after the block exists. def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) subkey = subkey.chomp('\\') - newkey = API.OpenKey(hkey.hkey, subkey, opt, desired) + newkey = API.OpenKey(hkey.instance_variable_get(:@hkey), subkey, opt, desired) obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY) if block_given? begin @@ -442,20 +451,22 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # - # --- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) + # call-seq: + # create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) + # create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| ... } # - # --- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| ... } + # Create or open the registry key +subkey+ under +key+. + # You can use {predefined key}[rdoc-ref:Win32::Registry@Predefined+keys] +HKEY_+*. + # +desired+ and +opt+ is access mask and key option. # - # Create or open the registry key subkey under key. - # You can use predefined key HKEY_* (see Constants) - # - # If subkey is already exists, key is opened and Registry#created? + # If +subkey+ is already exists, key is opened and Registry#created? # method will return false. # - # If block is given, the key is closed automatically. + # If block is given, the key +reg+ is yielded and closed + # automatically after the block exists. # def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) - newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired) + newkey, disp = API.CreateKey(hkey.instance_variable_get(:@hkey), subkey, opt, desired) obj = new(newkey, hkey, subkey, disp) if block_given? begin @@ -474,10 +485,12 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr @@final = proc { |hkey| proc { API.CloseKey(hkey[0]) if hkey[0] } } # - # initialize + # :nodoc: + # + # Use self.open, self.create, #open and #create. # def initialize(hkey, parent, keyname, disposition) - @hkey = hkey + @hkey = Fiddle::Pointer.new(hkey) @parent = parent @keyname = keyname @disposition = disposition @@ -485,9 +498,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal) end - # Returns key handle value. - attr_reader :hkey - # Win32::Registry object of parent key, or nil if predefeined key. + # Win32::Registry object of parent key, or nil if predefined key. attr_reader :parent # Same as subkey value of Registry.open or # Registry.create method. @@ -495,8 +506,13 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY). attr_reader :disposition + # Returns key handle value. + def hkey + @hkey.to_i + end + # - # Returns if key is created ((*newly*)). + # Returns +true+ if key is created *newly*. # (see Registry.create) -- basically you call create # then when you call created? on the instance returned # it will tell if it was successful or not @@ -513,7 +529,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # - # Full path of key such as 'HKEY_CURRENT_USER\SOFTWARE\foo\bar'. + # Full path of key such as <tt>'HKEY_CURRENT_USER\SOFTWARE\foo\bar'</tt>. # def name parent = self @@ -524,6 +540,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr name end + # + # Retruns inspected string + # def inspect "\#<Win32::Registry key=#{name.inspect}>" end @@ -536,14 +555,14 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # - # Same as Win32::Registry.open (self, subkey, desired, opt) + # Same as Win32::Registry.open(self, subkey, desired, opt) # def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk) self.class.open(self, subkey, desired, opt, &blk) end # - # Same as Win32::Registry.create (self, subkey, desired, opt) + # Same as Win32::Registry.create(self, subkey, desired, opt) # def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk) self.class.create(self, subkey, desired, opt, &blk) @@ -561,9 +580,16 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # - # Enumerate values. + # Enumerate all values in this registry path. + # + # For each value it yields key, type and data. + # + # key is a String which contains name of key. + # type is a type constant kind of +Win32::Registry::REG_+* + # data is the value of this key. # def each_value + return enum_for(:each_value) unless block_given? index = 0 while true begin @@ -594,13 +620,16 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # - # Enumerate subkeys. + # Enumerate all subkeys. + # + # For each subkey it yields subkey and wtime. # # subkey is String which contains name of subkey. # wtime is last write time as FILETIME (64-bit integer). # (see Registry.wtime2time) # def each_key + return enum_for(:each_key) unless block_given? index = 0 while true begin @@ -625,21 +654,23 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr end # Read a registry value named name and return array of - # [ type, data ]. - # When name is nil, the `default' value is read. - # type is value type. (see Win32::Registry::Constants module) - # data is value data, its class is: - # :REG_SZ, REG_EXPAND_SZ + # <tt>[ type, data ]</tt>. + # When name is +nil+, the `default' value is read. + # + # +type+ is {value type}[rdoc-ref:Win32::Registry@Value+types]. + # + # +data+ is value data, its class is: + # REG_SZ, REG_EXPAND_SZ:: # String - # :REG_MULTI_SZ + # REG_MULTI_SZ:: # Array of String - # :REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD + # REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD:: # Integer - # :REG_BINARY, REG_NONE + # REG_BINARY, REG_NONE:: # String (contains binary data) # - # When rtype is specified, the value type must be included by - # rtype array, or TypeError is raised. + # When _rtype_ is specified, the value type must be included by + # _rtype_ array, or +TypeError+ is raised. def read(name, *rtype) type, data = API.QueryValue(@hkey, name) unless rtype.empty? or rtype.include?(type) @@ -657,7 +688,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr when REG_DWORD [ type, API.unpackdw(data) ] when REG_DWORD_BIG_ENDIAN - [ type, data.unpack('N')[0] ] + [ type, data.unpack1('N') ] when REG_QWORD [ type, API.unpackqw(data) ] else @@ -672,9 +703,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # If the value type is REG_EXPAND_SZ, returns value data whose environment # variables are replaced. # If the value type is neither REG_SZ, REG_MULTI_SZ, REG_DWORD, - # REG_DWORD_BIG_ENDIAN, nor REG_QWORD, TypeError is raised. + # REG_DWORD_BIG_ENDIAN, nor REG_QWORD, +TypeError+ is raised. # - # The meaning of rtype is the same as for the #read method. + # The meaning of _rtype_ is the same as for the #read method. # def [](name, *rtype) type, data = read(name, *rtype) @@ -691,7 +722,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) # registry value named name. # - # If the values type does not match, TypeError is raised. + # If the values type does not match, +TypeError+ is raised. def read_s(name) read(name, REG_SZ)[1] end @@ -700,7 +731,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Read a REG_SZ or REG_EXPAND_SZ registry value named name. # # If the value type is REG_EXPAND_SZ, environment variables are replaced. - # Unless the value type is REG_SZ or REG_EXPAND_SZ, TypeError is raised. + # Unless the value type is REG_SZ or REG_EXPAND_SZ, +TypeError+ is raised. # def read_s_expand(name) type, data = read(name, REG_SZ, REG_EXPAND_SZ) @@ -715,7 +746,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) # registry value named name. # - # If the values type does not match, TypeError is raised. + # If the values type does not match, +TypeError+ is raised. # def read_i(name) read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1] @@ -725,7 +756,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) # registry value named name. # - # If the values type does not match, TypeError is raised. + # If the values type does not match, +TypeError+ is raised. # def read_bin(name) read(name, REG_BINARY)[1] @@ -735,19 +766,16 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # Write data to a registry value named name. # When name is nil, write to the `default' value. # - # type is type value. (see Registry::Constants module) + # +type+ is {value type}[rdoc-ref:Win32::Registry@Value+types]. # Class of data must be same as which #read # method returns. # def write(name, type, data) - termsize = 0 case type when REG_SZ, REG_EXPAND_SZ - data = data.encode(WCHAR) - termsize = WCHAR_SIZE + data = data.encode(WCHAR) << WCHAR_NUL when REG_MULTI_SZ data = data.to_a.map {|s| s.encode(WCHAR)}.join(WCHAR_NUL) << WCHAR_NUL - termsize = WCHAR_SIZE when REG_BINARY, REG_NONE data = data.to_s when REG_DWORD @@ -759,7 +787,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr else raise TypeError, "Unsupported type #{Registry.type2name(type)}" end - API.SetValue(@hkey, name, type, data, data.bytesize + termsize) + API.SetValue(@hkey, name, type, data, data.bytesize) end # @@ -767,11 +795,12 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # # If wtype is specified, the value type is it. # Otherwise, the value type is depend on class of value: - # :Integer + # + # Integer:: # REG_DWORD - # :String + # String:: # REG_SZ - # :Array + # Array:: # REG_MULTI_SZ # def []=(name, rtype, value = nil) @@ -868,19 +897,19 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr # # Returns key information as Array of: - # :num_keys + # num_keys:: # The number of subkeys. - # :max_key_length + # max_key_length:: # Maximum length of name of subkeys. - # :num_values + # num_values:: # The number of values. - # :max_value_name_length + # max_value_name_length:: # Maximum length of name of values. - # :max_value_length + # max_value_length:: # Maximum length of value of values. - # :descriptor_length + # descriptor_length:: # Length of security descriptor. - # :wtime + # wtime:: # Last write time as FILETIME(64-bit integer) # # For detail, see RegQueryInfoKey[http://msdn.microsoft.com/library/en-us/sysinfo/base/regqueryinfokey.asp] Win32 API. diff --git a/ext/win32/lib/win32/resolv.rb b/ext/win32/lib/win32/resolv.rb index d06658f0aa..8d631a2140 100644 --- a/ext/win32/lib/win32/resolv.rb +++ b/ext/win32/lib/win32/resolv.rb @@ -4,12 +4,22 @@ =end -require 'win32/registry' +require 'win32/resolv.so' module Win32 module Resolv - API = Registry::API - Error = Registry::Error + # Error at Win32 API + class Error < StandardError + # +code+ Win32 Error code + # +message+ Formatted message for +code+ + def initialize(code, message) + super(message) + @code = code + end + + # Win32 error code + attr_reader :code + end def self.get_hosts_path path = get_hosts_dir @@ -34,98 +44,59 @@ module Win32 end [ search, nameserver ] end - end -end - -begin - require 'win32/resolv.so' -rescue LoadError -end - -module Win32 -#==================================================================== -# Windows NT -#==================================================================== - module Resolv - module SZ - refine Registry do - # ad hoc workaround for broken registry - def read_s(key) - type, str = read(key) - unless type == Registry::REG_SZ - warn "Broken registry, #{name}\\#{key} was #{Registry.type2name(type)}, ignored" - return String.new - end - str - end - end - end - using SZ - - TCPIP_NT = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' class << self private def get_hosts_dir - Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg| - reg.read_s_expand('DataBasePath') + tcpip_params do |params| + params.value('DataBasePath') end end def get_info search = nil nameserver = get_dns_server_list - Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg| - begin - slist = reg.read_s('SearchList') - search = slist.split(/,\s*/) unless slist.empty? - rescue Registry::Error - end + + tcpip_params do |params| + slist = params.value('SearchList') + search = slist.split(/,\s*/) if slist and !slist.empty? if add_search = search.nil? search = [] - begin - nvdom = reg.read_s('NV Domain') - unless nvdom.empty? - @search = [ nvdom ] - if reg.read_i('UseDomainNameDevolution') != 0 - if /^\w+\./ =~ nvdom - devo = $' - end + domain = params.value('Domain') + + if domain and !domain.empty? + search = [ domain ] + udmnd = params.value('UseDomainNameDevolution') + if udmnd&.nonzero? + if /^\w+\./ =~ domain + devo = $' end end - rescue Registry::Error end end - reg.open('Interfaces') do |h| - h.each_key do |iface, | - h.open(iface) do |regif| - next unless ns = %w[NameServer DhcpNameServer].find do |key| - begin - ns = regif.read_s(key) - rescue Registry::Error - else - break ns.split(/[,\s]\s*/) unless ns.empty? - end - end - next if (nameserver & ns).empty? + params.open('Interfaces') do |reg| + reg.each_key do |iface| + next unless ns = %w[NameServer DhcpNameServer].find do |key| + ns = iface.value(key) + break ns.split(/[,\s]\s*/) if ns and !ns.empty? + end + + next if (nameserver & ns).empty? - if add_search - begin - [ 'Domain', 'DhcpDomain' ].each do |key| - dom = regif.read_s(key) - unless dom.empty? - search.concat(dom.split(/,\s*/)) - break - end - end - rescue Registry::Error + if add_search + [ 'Domain', 'DhcpDomain' ].each do |key| + dom = iface.value(key) + if dom and !dom.empty? + search.concat(dom.split(/,\s*/)) + break end end end end end + search << devo if add_search and devo end [ search.uniq, nameserver.uniq ] diff --git a/ext/win32/lib/win32/sspi.rb b/ext/win32/lib/win32/sspi.rb deleted file mode 100644 index 20205fd4d6..0000000000 --- a/ext/win32/lib/win32/sspi.rb +++ /dev/null @@ -1,338 +0,0 @@ -# frozen_string_literal: false -# -# = win32/sspi.rb -# -# Copyright (c) 2006-2007 Justin Bailey -# -# Written and maintained by Justin Bailey <jgbailey@gmail.com>. -# -# This program is free software. You can re-distribute and/or -# modify this program under the same terms of ruby itself --- -# Ruby Distribution License or GNU General Public License. -# - -require 'fiddle/import' - -# Implements bindings to Win32 SSPI functions, focused on authentication to a proxy server over HTTP. -module Win32 - module SSPI - # Specifies how credential structure requested will be used. Only SECPKG_CRED_OUTBOUND is used - # here. - SECPKG_CRED_INBOUND = 0x00000001 - SECPKG_CRED_OUTBOUND = 0x00000002 - SECPKG_CRED_BOTH = 0x00000003 - - # Format of token. NETWORK format is used here. - SECURITY_NATIVE_DREP = 0x00000010 - SECURITY_NETWORK_DREP = 0x00000000 - - # InitializeSecurityContext Requirement flags - ISC_REQ_REPLAY_DETECT = 0x00000004 - ISC_REQ_SEQUENCE_DETECT = 0x00000008 - ISC_REQ_CONFIDENTIALITY = 0x00000010 - ISC_REQ_USE_SESSION_KEY = 0x00000020 - ISC_REQ_PROMPT_FOR_CREDS = 0x00000040 - ISC_REQ_CONNECTION = 0x00000800 - - # Win32 API Functions. Uses Win32API to bind methods to constants contained in class. - module API - extend Fiddle::Importer - dlload "secur32.dll" - [ - # Can be called with AcquireCredentialsHandleA.call() - "unsigned long AcquireCredentialsHandleA(void *, void *, unsigned long, void *, void *, void *, void *, void *, void *)", - # Can be called with InitializeSecurityContextA.call() - "unsigned long InitializeSecurityContextA(void *, void *, void *, unsigned long, unsigned long, unsigned long, void *, unsigned long, void *, void *, void *, void *)", - # Can be called with DeleteSecurityContext.call() - "unsigned long DeleteSecurityContext(void *)", - # Can be called with FreeCredentialsHandle.call() - "unsigned long FreeCredentialsHandle(void *)" - ].each do |fn| - cfunc = extern fn, :stdcall - const_set cfunc.name.intern, cfunc - end - end - - # SecHandle struct - class SecurityHandle - def upper - @struct.unpack("LL")[1] - end - - def lower - @struct.unpack("LL")[0] - end - - def to_p - @struct ||= "\0" * 8 - end - end - - # Some familiar aliases for the SecHandle structure - CredHandle = CtxtHandle = SecurityHandle - - # TimeStamp struct - class TimeStamp - attr_reader :struct - - def to_p - @struct ||= "\0" * 8 - end - end - - # Creates binary representations of a SecBufferDesc structure, - # including the SecBuffer contained inside. - class SecurityBuffer - - SECBUFFER_TOKEN = 2 # Security token - - TOKENBUFSIZE = 12288 - SECBUFFER_VERSION = 0 - - def initialize(buffer = nil) - @buffer = buffer || "\0" * TOKENBUFSIZE - @bufferSize = @buffer.length - @type = SECBUFFER_TOKEN - end - - def bufferSize - unpack - @bufferSize - end - - def bufferType - unpack - @type - end - - def token - unpack - @buffer - end - - def to_p - # Assumption is that when to_p is called we are going to get a packed structure. Therefore, - # set @unpacked back to nil so we know to unpack when accessors are next accessed. - @unpacked = nil - # Assignment of inner structure to variable is very important here. Without it, - # will not be able to unpack changes to the structure. Alternative, nested unpacks, - # does not work (i.e. @struct.unpack("LLP12")[2].unpack("LLP12") results in "no associated pointer") - @sec_buffer ||= [@bufferSize, @type, @buffer].pack("LLP") - @struct ||= [SECBUFFER_VERSION, 1, @sec_buffer].pack("LLP") - end - - private - - # Unpacks the SecurityBufferDesc structure into member variables. We - # only want to do this once per struct, so the struct is deleted - # after unpacking. - def unpack - if ! @unpacked && @sec_buffer && @struct - @bufferSize, @type = @sec_buffer.unpack("LL") - @buffer = @sec_buffer.unpack("LLP#{@bufferSize}")[2] - @struct = nil - @sec_buffer = nil - @unpacked = true - end - end - end - - # SEC_WINNT_AUTH_IDENTITY structure - class Identity - SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1 - - attr_accessor :user, :domain, :password - - def initialize(user = nil, domain = nil, password = nil) - @user = user - @domain = domain - @password = password - @flags = SEC_WINNT_AUTH_IDENTITY_ANSI - end - - def to_p - [@user, @user ? @user.length : 0, - @domain, @domain ? @domain.length : 0, - @password, @password ? @password.length : 0, - @flags].pack("PLPLPLL") - end - end - - # Takes a return result from an SSPI function and interprets the value. - class SSPIResult - # Good results - SEC_E_OK = 0x00000000 - SEC_I_CONTINUE_NEEDED = 0x00090312 - - # These are generally returned by InitializeSecurityContext - SEC_E_INSUFFICIENT_MEMORY = 0x80090300 - SEC_E_INTERNAL_ERROR = 0x80090304 - SEC_E_INVALID_HANDLE = 0x80090301 - SEC_E_INVALID_TOKEN = 0x80090308 - SEC_E_LOGON_DENIED = 0x8009030C - SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311 - SEC_E_NO_CREDENTIALS = 0x8009030E - SEC_E_TARGET_UNKNOWN = 0x80090303 - SEC_E_UNSUPPORTED_FUNCTION = 0x80090302 - SEC_E_WRONG_PRINCIPAL = 0x80090322 - - # These are generally returned by AcquireCredentialsHandle - SEC_E_NOT_OWNER = 0x80090306 - SEC_E_SECPKG_NOT_FOUND = 0x80090305 - SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D - - @@map = {} - constants.each { |v| @@map[self.const_get(v.to_s)] = v } - - attr_reader :value - - def initialize(value) - # convert to unsigned long - value = [value].pack("L").unpack("L").first - raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value - @value = value - end - - def to_s - @@map[@value].to_s - end - - def ok? - @value == SEC_I_CONTINUE_NEEDED || @value == SEC_E_OK - end - - def ==(other) - if other.is_a?(SSPIResult) - @value == other.value - elsif other.is_a?(Fixnum) - @value == @@map[other] - else - false - end - end - end - - # Handles "Negotiate" type authentication. Geared towards authenticating with a proxy server over HTTP - class NegotiateAuth - attr_accessor :credentials, :context, :contextAttributes, :user, :domain - - # Default request flags for SSPI functions - REQUEST_FLAGS = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION - - # NTLM tokens start with this header always. Encoding alone adds "==" and newline, so remove those - B64_TOKEN_PREFIX = ["NTLMSSP"].pack("m").delete("=\n") - - # Given a connection and a request path, performs authentication as the current user and returns - # the response from a GET request. The connection should be a Net::HTTP object, and it should - # have been constructed using the Net::HTTP.Proxy method, but anything that responds to "get" will work. - # If a user and domain are given, will authenticate as the given user. - # Returns the response received from the get method (usually Net::HTTPResponse) - def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil) - raise "http must respond to :get" unless http.respond_to?(:get) - nego_auth = self.new user, domain - - resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token } - if resp["Proxy-Authenticate"] - resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) } - end - - resp - end - - # Creates a new instance ready for authentication as the given user in the given domain. - # Defaults to current user and domain as defined by ENV["USERDOMAIN"] and ENV["USERNAME"] if - # no arguments are supplied. - def initialize(user = nil, domain = nil) - if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil? - raise "A username or domain must be supplied since they cannot be retrieved from the environment" - end - - @user = user || ENV["USERNAME"] - @domain = domain || ENV["USERDOMAIN"] - end - - # Gets the initial Negotiate token. Returns it as a base64 encoded string suitable for use in HTTP. Can - # be easily decoded, however. - def get_initial_token - raise "This object is no longer usable because its resources have been freed." if @cleaned_up - get_credentials - - outputBuffer = SecurityBuffer.new - @context = CtxtHandle.new - @contextAttributes = "\0" * 4 - - result = SSPIResult.new(API::InitializeSecurityContextA.call(@credentials.to_p, nil, nil, - REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p)) - - if result.ok? then - return encode_token(outputBuffer.token) - else - raise "Error: #{result.to_s}" - end - end - - # Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64 encoded or not. - # The token can include the "Negotiate" header and it will be stripped. - # Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned. - # Token returned is Base64 encoded w/ all new lines removed. - def complete_authentication(token) - raise "This object is no longer usable because its resources have been freed." if @cleaned_up - - # Nil token OK, just set it to empty string - token = "" if token.nil? - - if token.include? "Negotiate" - # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token. - token = token.split(" ").last - end - - if token.include? B64_TOKEN_PREFIX - # indicates base64 encoded token - token = token.strip.unpack("m")[0] - end - - outputBuffer = SecurityBuffer.new - result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil, - REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0, - @context.to_p, - outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p)) - - if result.ok? then - return encode_token(outputBuffer.token) - else - raise "Error: #{result.to_s}" - end - ensure - # need to make sure we don't clean up if we've already cleaned up. - clean_up unless @cleaned_up - end - - private - - def clean_up - # free structures allocated - @cleaned_up = true - API::FreeCredentialsHandle.call(@credentials.to_p) - API::DeleteSecurityContext.call(@context.to_p) - @context = nil - @credentials = nil - @contextAttributes = nil - end - - # Gets credentials based on user, domain or both. If both are nil, an error occurs - def get_credentials - @credentials = CredHandle.new - ts = TimeStamp.new - @identity = Identity.new @user, @domain - result = SSPIResult.new(API::AcquireCredentialsHandleA.call(nil, "Negotiate", SECPKG_CRED_OUTBOUND, nil, @identity.to_p, - nil, nil, @credentials.to_p, ts.to_p)) - raise "Error acquire credentials: #{result}" unless result.ok? - end - - def encode_token(t) - # encode64 will add newlines every 60 characters so we need to remove those. - [t].pack("m").delete("\n") - end - end - end -end diff --git a/ext/win32/resolv/extconf.rb b/ext/win32/resolv/extconf.rb index 01f3df730a..5ee4c0d7c4 100644 --- a/ext/win32/resolv/extconf.rb +++ b/ext/win32/resolv/extconf.rb @@ -1,3 +1,7 @@ -if have_library('iphlpapi', 'GetNetworkParams') +require 'mkmf' +if RUBY_ENGINE == "ruby" and have_library('iphlpapi', 'GetNetworkParams', ['windows.h', 'iphlpapi.h']) + have_library('advapi32', 'RegGetValueW', ['windows.h']) create_makefile('win32/resolv') +else + File.write('Makefile', "all clean install:\n\t@echo Done: $(@)\n") end diff --git a/ext/win32/resolv/resolv.c b/ext/win32/resolv/resolv.c index f19243ccc1..b2d377df9f 100644 --- a/ext/win32/resolv/resolv.c +++ b/ext/win32/resolv/resolv.c @@ -1,22 +1,56 @@ #include <ruby.h> #include <ruby/encoding.h> #include <windows.h> +#include <windns.h> #ifndef NTDDI_VERSION #define NTDDI_VERSION 0x06000000 #endif #include <iphlpapi.h> +#ifndef numberof +#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0]))) +#endif + static VALUE w32error_make_error(DWORD e) { - VALUE code = ULONG2NUM(e); - return rb_class_new_instance(1, &code, rb_path2class("Win32::Resolv::Error")); + char buffer[512], *p; + DWORD source = 0; + VALUE args[2]; + if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, &source, e, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + buffer, sizeof(buffer), NULL)) { + snprintf(buffer, sizeof(buffer), "Unknown Error %lu", (unsigned long)e); + } + p = buffer; + while ((p = strpbrk(p, "\r\n")) != NULL) { + memmove(p, p + 1, strlen(p)); + if (!p[1]) { + p[0] = '\0'; + break; + } + } + args[0] = ULONG2NUM(e); + args[1] = rb_str_new_cstr(buffer); + return rb_class_new_instance(2, args, rb_path2class("Win32::Resolv::Error")); } static void -w32error_raise(DWORD e) +w32error_check(DWORD e) +{ + if (e != NO_ERROR) { + rb_exc_raise(w32error_make_error(e)); + } +} + +static VALUE +wchar_to_utf8(const WCHAR *w, int n) { - rb_exc_raise(w32error_make_error(e)); + int clen = WideCharToMultiByte(CP_UTF8, 0, w, n, NULL, 0, NULL, NULL); + VALUE str = rb_enc_str_new(NULL, clen, rb_utf8_encoding()); + WideCharToMultiByte(CP_UTF8, 0, w, n, RSTRING_PTR(str), clen, NULL, NULL); + return str; } static VALUE @@ -28,34 +62,195 @@ get_dns_server_list(VALUE self) VALUE buf, nameservers = Qnil; ret = GetNetworkParams(NULL, &buflen); - if (ret != NO_ERROR && ret != ERROR_BUFFER_OVERFLOW) { - w32error_raise(ret); - } + if (ret != ERROR_BUFFER_OVERFLOW) w32error_check(ret); fixedinfo = ALLOCV(buf, buflen); ret = GetNetworkParams(fixedinfo, &buflen); if (ret == NO_ERROR) { - const IP_ADDR_STRING *ipaddr = &fixedinfo->DnsServerList; - nameservers = rb_ary_new(); - do { - const char *s = ipaddr->IpAddress.String; - if (!*s) continue; - if (strcmp(s, "0.0.0.0") == 0) continue; - rb_ary_push(nameservers, rb_str_new_cstr(s)); - } while ((ipaddr = ipaddr->Next) != NULL); + const IP_ADDR_STRING *ipaddr = &fixedinfo->DnsServerList; + nameservers = rb_ary_new(); + do { + const char *s = ipaddr->IpAddress.String; + if (!*s) continue; + if (strcmp(s, "0.0.0.0") == 0) continue; + rb_ary_push(nameservers, rb_str_new_cstr(s)); + } while ((ipaddr = ipaddr->Next) != NULL); } ALLOCV_END(buf); - if (ret != NO_ERROR) w32error_raise(ret); + w32error_check(ret); return nameservers; } + +static const WCHAR TCPIP_Params[] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; + +static void +hkey_finalize(void *p) +{ + RegCloseKey((HKEY)p); +} + +static const rb_data_type_t hkey_type = { + "RegKey", + {0, hkey_finalize}, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static VALUE +hkey_close(VALUE self) +{ + RegCloseKey((HKEY)DATA_PTR(self)); + DATA_PTR(self) = 0; + return self; +} + +static VALUE reg_key_class; + +static VALUE +reg_open_key(VALUE klass, HKEY hkey, const WCHAR *wname) +{ + VALUE k = TypedData_Wrap_Struct(klass, &hkey_type, NULL); + DWORD e = RegOpenKeyExW(hkey, wname, 0, KEY_READ, (HKEY *)&DATA_PTR(k)); + if (e == ERROR_FILE_NOT_FOUND) return Qnil; + w32error_check(e); + return rb_ensure(rb_yield, k, hkey_close, k); +} + +static VALUE +tcpip_params_open(VALUE klass) +{ + return reg_open_key(reg_key_class, HKEY_LOCAL_MACHINE, TCPIP_Params); +} + +static int +to_wname(VALUE *name, WCHAR *wname, int wlen) +{ + const char *n = StringValueCStr(*name); + int nlen = RSTRING_LEN(*name); + int len = MultiByteToWideChar(CP_UTF8, 0, n, nlen, wname, wlen - 1); + if (len == 0) w32error_check(GetLastError()); + if (len >= wlen) rb_raise(rb_eArgError, "too long name"); + wname[len] = L'\0'; + return len; +} + +static VALUE +reg_open(VALUE self, VALUE name) +{ + HKEY hkey = DATA_PTR(self); + WCHAR wname[256]; + to_wname(&name, wname, numberof(wname)); + return reg_open_key(CLASS_OF(self), hkey, wname); +} + + +static VALUE +reg_each_key(VALUE self) +{ + WCHAR wname[256]; + HKEY hkey = DATA_PTR(self); + VALUE k = TypedData_Wrap_Struct(CLASS_OF(self), &hkey_type, NULL); + DWORD i, e, n; + for (i = 0; n = numberof(wname), (e = RegEnumKeyExW(hkey, i, wname, &n, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS; i++) { + e = RegOpenKeyExW(hkey, wname, 0, KEY_READ, (HKEY *)&DATA_PTR(k)); + w32error_check(e); + rb_ensure(rb_yield, k, hkey_close, k); + } + if (e != ERROR_NO_MORE_ITEMS) w32error_check(e); + return self; +} + +static inline DWORD +swap_dw(DWORD x) +{ +#if defined(_MSC_VER) + return _byteswap_ulong(x); +#else + return __builtin_bswap32(x); +#endif +} + +static VALUE +reg_value(VALUE self, VALUE name) +{ + HKEY hkey = DATA_PTR(self); + DWORD type = 0, size = 0, e; + VALUE result, value_buffer; + void *buffer; + WCHAR wname[256]; + to_wname(&name, wname, numberof(wname)); + e = RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type, NULL, &size); + if (e == ERROR_FILE_NOT_FOUND) return Qnil; + w32error_check(e); +# define get_value_2nd(data, dsize) do { \ + DWORD type2 = type; \ + w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type2, data, dsize)); \ + if (type != type2) { \ + rb_raise(rb_eRuntimeError, "registry value type changed %lu -> %lu", \ + (unsigned long)type, (unsigned long)type2); \ + } \ + } while (0) + + switch (type) { + case REG_DWORD: case REG_DWORD_BIG_ENDIAN: + { + DWORD d; + if (size != sizeof(d)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size); + w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_DWORD, &type, &d, &size)); + if (type == REG_DWORD_BIG_ENDIAN) d = swap_dw(d); + return ULONG2NUM(d); + } + case REG_QWORD: + { + QWORD q; + if (size != sizeof(q)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size); + w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_QWORD, &type, &q, &size)); + return ULL2NUM(q); + } + case REG_SZ: case REG_MULTI_SZ: case REG_EXPAND_SZ: + if (size % sizeof(WCHAR)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size); + buffer = ALLOCV_N(char, value_buffer, size); + get_value_2nd(buffer, &size); + if (type == REG_MULTI_SZ) { + const WCHAR *w = (WCHAR *)buffer; + result = rb_ary_new(); + size /= sizeof(WCHAR); + size -= 1; + for (size_t i = 0; i < size; ++i) { + int n = lstrlenW(w+i); + rb_ary_push(result, wchar_to_utf8(w+i, n)); + i += n; + } + } + else { + result = wchar_to_utf8((WCHAR *)buffer, lstrlenW((WCHAR *)buffer)); + } + ALLOCV_END(value_buffer); + break; + default: + result = rb_str_new(0, size); + get_value_2nd(RSTRING_PTR(result), &size); + rb_str_set_len(result, size); + break; + } + return result; +} + void InitVM_resolv(void) { VALUE mWin32 = rb_define_module("Win32"); VALUE resolv = rb_define_module_under(mWin32, "Resolv"); VALUE singl = rb_singleton_class(resolv); + VALUE regkey = rb_define_class_under(resolv, "registry key", rb_cObject); + + reg_key_class = regkey; + rb_undef_alloc_func(regkey); rb_define_private_method(singl, "get_dns_server_list", get_dns_server_list, 0); + rb_define_private_method(singl, "tcpip_params", tcpip_params_open, 0); + rb_define_method(regkey, "open", reg_open, 1); + rb_define_method(regkey, "each_key", reg_each_key, 0); + rb_define_method(regkey, "value", reg_value, 1); } void diff --git a/ext/win32/win32-registry.gemspec b/ext/win32/win32-registry.gemspec new file mode 100644 index 0000000000..9bd57bd7d1 --- /dev/null +++ b/ext/win32/win32-registry.gemspec @@ -0,0 +1,29 @@ +# frozen_string_literal: true +Gem::Specification.new do |spec| + spec.name = "win32-registry" + spec.version = "0.1.2" + spec.authors = ["U.Nakamura"] + spec.email = ["usa@garbagecollect.jp"] + + spec.summary = %q{Provides an interface to the Windows Registry in Ruby} + spec.description = spec.summary + spec.homepage = "https://github.com/ruby/win32-registry" + spec.required_ruby_version = ">= 2.6.0" + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + excludes = %w[ + bin/ test/ spec/ features/ rakelib/ + .git* .mailmap appveyor Rakefile Gemfile + ] + git_files = %w[git ls-files -z --] + excludes.map {|x| ":^/#{x}"} + spec.files = IO.popen(git_files, chdir: __dir__, &:read).split("\x0") + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.add_dependency "fiddle", "~> 1.0" +end diff --git a/ext/win32ole/depend b/ext/win32ole/depend deleted file mode 100644 index c8445ad5fa..0000000000 --- a/ext/win32ole/depend +++ /dev/null @@ -1,12 +0,0 @@ -WIN32OLE_HEADERS = $(HDRS) $(ruby_headers) -win32ole.o : win32ole.c $(WIN32OLE_HEADERS) -win32ole_variant_m.o : win32ole_variant_m.c $(WIN32OLE_HEADERS) -win32ole_typelib.o : win32ole_typelib.c $(WIN32OLE_HEADERS) -win32ole_type.o : win32ole_type.c $(WIN32OLE_HEADERS) -win32ole_variable.o : win32ole_variable.c $(WIN32OLE_HEADERS) -win32ole_method.o : win32ole_method.c $(WIN32OLE_HEADERS) -win32ole_param.o : win32ole_param.c $(WIN32OLE_HEADERS) -win32ole_variant.o : win32ole_variant.c $(WIN32OLE_HEADERS) -win32ole_event.o : win32ole_event.c $(WIN32OLE_HEADERS) -win32ole_record.o : win32ole_record.c $(WIN32OLE_HEADERS) -win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS) diff --git a/ext/win32ole/extconf.rb b/ext/win32ole/extconf.rb deleted file mode 100644 index d2044663a9..0000000000 --- a/ext/win32ole/extconf.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: false -#---------------------------------- -# extconf.rb -# $Revision$ -#---------------------------------- -require 'mkmf' - -case RUBY_PLATFORM -when /cygwin/ - inc = nil - lib = '/usr/lib/w32api' -end - -dir_config("win32", inc, lib) - -def create_win32ole_makefile - if have_library("ole32") and - have_library("oleaut32") and - have_library("uuid", "&CLSID_CMultiLanguage", "mlang.h") and - have_library("user32") and - have_library("kernel32") and - have_library("advapi32") and - have_header("windows.h") - unless have_type("IMultiLanguage2", "mlang.h") - have_type("IMultiLanguage", "mlang.h") - end - spec = nil - checking_for('thread_specific', '%s') do - spec = %w[__declspec(thread) __thread].find {|th| - try_compile("#{th} int foo;", "", :werror => true) - } - spec or 'no' - end - $defs << "-DRB_THREAD_SPECIFIC=#{spec}" if spec - create_makefile("win32ole") - end -end - - -case RUBY_PLATFORM -when /mswin/ - $CFLAGS.sub!(/((?:\A|\s)[-\/])W\d(?=\z|\s)/, '\1W3') or - $CFLAGS += ' -W3' -end -create_win32ole_makefile diff --git a/ext/win32ole/lib/win32ole.rb b/ext/win32ole/lib/win32ole.rb deleted file mode 100644 index d7034f7845..0000000000 --- a/ext/win32ole/lib/win32ole.rb +++ /dev/null @@ -1,33 +0,0 @@ -begin - require 'win32ole.so' -rescue LoadError - # do nothing -end - -if defined?(WIN32OLE) - # WIN32OLE - class WIN32OLE - - # - # By overriding Object#methods, WIN32OLE might - # work well with did_you_mean gem. - # This is experimental. - # - # require 'win32ole' - # dict = WIN32OLE.new('Scripting.Dictionary') - # dict.Ade('a', 1) - # #=> Did you mean? Add - # - def methods(*args) - super + ole_methods_safely.map(&:name).map(&:to_sym) - end - - private - - def ole_methods_safely - ole_methods - rescue WIN32OLEQueryInterfaceError - [] - end - end -end diff --git a/ext/win32ole/lib/win32ole/property.rb b/ext/win32ole/lib/win32ole/property.rb deleted file mode 100644 index fea047cd19..0000000000 --- a/ext/win32ole/lib/win32ole/property.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: false -# OLEProperty -# helper class of Property with arguments. -class OLEProperty - def initialize(obj, dispid, gettypes, settypes) - @obj = obj - @dispid = dispid - @gettypes = gettypes - @settypes = settypes - end - def [](*args) - @obj._getproperty(@dispid, args, @gettypes) - end - def []=(*args) - @obj._setproperty(@dispid, args, @settypes) - end -end diff --git a/ext/win32ole/sample/excel1.rb b/ext/win32ole/sample/excel1.rb deleted file mode 100644 index 4fe1d0c2a9..0000000000 --- a/ext/win32ole/sample/excel1.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -application = WIN32OLE.new('Excel.Application') - -application.visible = true -workbook = application.Workbooks.Add(); -worksheet = workbook.Worksheets(1); - -=begin -worksheet.Range("A1:D1").value = ["North","South","East","West"]; -worksheet.Range("A2:B2").value = [5.2, 10]; - -worksheet.Range("C2").value = 8; -worksheet.Range("D2").value = 20; -=end - -worksheet.Range("A1:B2").value = [["North","South"], - [5.2, 10]]; - -vals = WIN32OLE_VARIANT.new([["East","West"], - [8, 20]], - WIN32OLE::VARIANT::VT_ARRAY) -worksheet.Range("C1:D2").value = vals - -range = worksheet.Range("A1:D2"); -range.Select -chart = workbook.Charts.Add; - -workbook.saved = true; - -print "Now quit Excel... Please enter." -gets - -application.ActiveWorkbook.Close(0); -application.Quit(); - diff --git a/ext/win32ole/sample/excel2.rb b/ext/win32ole/sample/excel2.rb deleted file mode 100644 index 47a5715f84..0000000000 --- a/ext/win32ole/sample/excel2.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -# -4100 is the value for the Excel constant xl3DColumn. -ChartTypeVal = -4100; - -# Creates OLE object to Excel -excel = WIN32OLE.new("excel.application") - -# Create and rotate the chart -excel.visible = true; -excel.Workbooks.Add(); -excel.Range("a1").value = 3; -excel.Range("a2").value = 2; -excel.Range("a3").value = 1; -excel.Range("a1:a3").Select(); -excelchart = excel.Charts.Add(); -excelchart.type = ChartTypeVal; - -i = 0 -i.step(180, 10) do |rot| - excelchart.rotation=rot; - sleep 0.1 -end -# Done, bye - -print "Now quit Excel... Please enter." -gets - -excel.ActiveWorkbook.Close(0); -excel.Quit(); diff --git a/ext/win32ole/sample/excel3.rb b/ext/win32ole/sample/excel3.rb deleted file mode 100644 index 72aee2a929..0000000000 --- a/ext/win32ole/sample/excel3.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -#application = WIN32OLE.new('Excel.Application.5') -application = WIN32OLE.new('Excel.Application') - -application.visible = true -workbook = application.Workbooks.Add(); -sheet = workbook.Worksheets(1); -sheetS = workbook.Worksheets -puts "The number of sheets is #{sheetS.count}" -puts "Now add 2 sheets after of `#{sheet.name}`" -sheetS.add({'count'=>2, 'after'=>sheet}) -puts "The number of sheets is #{sheetS.count}" - -print "Now quit Excel... Please enter." -gets - -application.ActiveWorkbook.Close(0); -application.Quit(); - diff --git a/ext/win32ole/sample/ie.rb b/ext/win32ole/sample/ie.rb deleted file mode 100644 index 4db64eed30..0000000000 --- a/ext/win32ole/sample/ie.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' -url = 'http://www.ruby-lang.org/' -ie = WIN32OLE.new('InternetExplorer.Application') -ie.visible = true -ie.gohome -print "Now navigate Ruby home page... Please enter." -gets -ie.navigate(url) -print "Now quit Internet Explorer... Please enter." -gets -ie.Quit() diff --git a/ext/win32ole/sample/ieconst.rb b/ext/win32ole/sample/ieconst.rb deleted file mode 100644 index 363a4f8153..0000000000 --- a/ext/win32ole/sample/ieconst.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -ie = WIN32OLE.new('InternetExplorer.Application') -=begin -WIN32OLE.const_load(ie) -WIN32OLE.constants.sort.each do |c| - puts "#{c} = #{WIN32OLE.const_get(c)}" -end -=end - -module IE_CONST -end - -WIN32OLE.const_load(ie, IE_CONST) -IE_CONST.constants.sort.each do |c| - puts "#{c} = #{IE_CONST.const_get(c)}" -end - -#------------------------------------------------------------ -# Remark!!! CONSTANTS has not tested enoughly!!! -# CONSTANTS is alpha release. -# If there are constants which first letter is not [a-zA-Z], -# like a '_Foo', then maybe you can access the value by -# using CONSTANTS['_Foo'] -#------------------------------------------------------------ -IE_CONST::CONSTANTS.each do |k, v| - puts "#{k} = #{v}" -end - -puts WIN32OLE::VERSION -ie.quit - diff --git a/ext/win32ole/sample/ienavi.rb b/ext/win32ole/sample/ienavi.rb deleted file mode 100644 index 5d0536028b..0000000000 --- a/ext/win32ole/sample/ienavi.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -$urls = [] - -def navigate(url) - $urls << url -end - -def stop_msg_loop - puts "Now Stop IE..." - $LOOP = false; -end - -def default_handler(event, *args) - case event - when "BeforeNavigate" - puts "Now Navigate #{args[0]}..." - end -end - -ie = WIN32OLE.new('InternetExplorer.Application') -ie.visible = true -ie.gohome - -ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents') - -ev.on_event {|*args| default_handler(*args)} -ev.on_event("NavigateComplete") {|url| navigate(url)} -ev.on_event("Quit") {|*args| stop_msg_loop} - -$LOOP = true -while ($LOOP) - WIN32OLE_EVENT.message_loop -end - -puts "You Navigated the URLs ..." -$urls.each_with_index do |url, i| - puts "(#{i+1}) #{url}" -end - diff --git a/ext/win32ole/sample/ienavi2.rb b/ext/win32ole/sample/ienavi2.rb deleted file mode 100644 index 3248393077..0000000000 --- a/ext/win32ole/sample/ienavi2.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: false -require 'win32ole' - -class IEHandler - attr_reader :loop - def initialize - @urls = [] - @loop = true - end - def method_missing(event, *args) - case event - when "BeforeNavigate2" - puts "Now Navigate #{args[1]}..." - end - end - def onNavigateComplete2(pdisp, url) - @urls << url - end - def onOnQuit - puts "Now Stop IE..." - @loop = false - end - def put_urls - puts "You Navigated the URLs ..." - @urls.each_with_index do |url, i| - puts "(#{i+1}) #{url}" - end - end -end - -ie = WIN32OLE.new('InternetExplorer.Application') -ie.visible = true -ie.gohome - -ev = WIN32OLE_EVENT.new(ie) -ev.handler = IEHandler.new - -while (ev.handler.loop) - WIN32OLE_EVENT.message_loop -end -ev.handler.put_urls diff --git a/ext/win32ole/sample/oledirs.rb b/ext/win32ole/sample/oledirs.rb deleted file mode 100644 index e52a0fd7ac..0000000000 --- a/ext/win32ole/sample/oledirs.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: false -# -# You need WSH(Windows Scripting Host) to run this script. -# - -require "win32ole" - -def listup(items) -# items.each do |i| - for i in items - puts i.name - end -end - -fs = WIN32OLE.new("Scripting.FileSystemObject") - -folder = fs.GetFolder(".") - -puts "--- folder of #{folder.path} ---" -listup(folder.SubFolders) - -puts "--- files of #{folder.path} ---" -listup(folder.Files) - diff --git a/ext/win32ole/sample/olegen.rb b/ext/win32ole/sample/olegen.rb deleted file mode 100644 index 4b088a774f..0000000000 --- a/ext/win32ole/sample/olegen.rb +++ /dev/null @@ -1,348 +0,0 @@ -# frozen_string_literal: false -#----------------------------- -# olegen.rb -# $Revision$ -#----------------------------- - -require 'win32ole' - -class WIN32COMGen - def initialize(typelib) - @typelib = typelib - @receiver = "" - end - attr_reader :typelib - - def ole_classes(typelib) - begin - @ole = WIN32OLE.new(typelib) - [@ole.ole_obj_help] - rescue - WIN32OLE_TYPE.ole_classes(typelib) - end - end - - def generate_args(method) - args = [] - if method.size_opt_params >= 0 - size_required_params = method.size_params - method.size_opt_params - else - size_required_params = method.size_params - 1 - end - size_required_params.times do |i| - if method.params[i] && method.params[i].optional? - args.push "arg#{i}=nil" - else - args.push "arg#{i}" - end - end - if method.size_opt_params >= 0 - method.size_opt_params.times do |i| - args.push "arg#{i + size_required_params}=nil" - end - else - args.push "*arg" - end - args.join(", ") - end - - def generate_argtype(typedetails) - ts = '' - typedetails.each do |t| - case t - when 'CARRAY', 'VOID', 'UINT', 'RESULT', 'DECIMAL', 'I8', 'UI8' -# raise "Sorry type\"" + t + "\" not supported" - ts << "\"??? NOT SUPPORTED TYPE:`#{t}'\"" - when 'USERDEFINED', 'Unknown Type 9' - ts << 'VT_DISPATCH' - break; - when 'SAFEARRAY' - ts << 'VT_ARRAY|' - when 'PTR' - ts << 'VT_BYREF|' - when 'INT' - ts << 'VT_I4' - else - if String === t - ts << 'VT_' + t - end - end - end - if ts.empty? - ts = 'VT_VARIANT' - elsif ts[-1] == ?| - ts += 'VT_VARIANT' - end - ts - end - - def generate_argtypes(method, proptypes) - types = method.params.collect{|param| - generate_argtype(param.ole_type_detail) - }.join(", ") - if proptypes - types += ", " if types.size > 0 - types += generate_argtype(proptypes) - end - types - end - - def generate_method_body(method, disptype, types=nil) - " ret = #{@receiver}#{disptype}(#{method.dispid}, [" + - generate_args(method).gsub("=nil", "") + - "], [" + - generate_argtypes(method, types) + - "])\n" + - " @lastargs = WIN32OLE::ARGV\n" + - " ret" - end - - def generate_method_help(method, type = nil) - str = " # " - if type - str += type - else - str += method.return_type - end - str += " #{method.name}" - if method.event? - str += " EVENT" - str += " in #{method.event_interface}" - end - if method.helpstring && method.helpstring != "" - str += "\n # " - str += method.helpstring - end - args_help = generate_method_args_help(method) - if args_help - str += "\n" - str += args_help - end - str - end - - def generate_method_args_help(method) - args = [] - method.params.each_with_index {|param, i| - h = " # #{param.ole_type} arg#{i} --- #{param.name}" - inout = [] - inout.push "IN" if param.input? - inout.push "OUT" if param.output? - h += " [#{inout.join('/')}]" - h += " ( = #{param.default})" if param.default - args.push h - } - if args.size > 0 - args.join("\n") - else - nil - end - end - - def generate_method(method, disptype, io = STDOUT, types = nil) - io.puts "\n" - io.puts generate_method_help(method) - if method.invoke_kind == 'PROPERTYPUT' - io.print " def #{method.name}=(" - else - io.print " def #{method.name}(" - end - io.print generate_args(method) - io.puts ")" - io.puts generate_method_body(method, disptype, types) - io.puts " end" - end - - def generate_propputref_methods(klass, io = STDOUT) - klass.ole_methods.select {|method| - method.invoke_kind == 'PROPERTYPUTREF' && method.visible? - }.each do |method| - generate_method(method, io) - end - end - - def generate_properties_with_args(klass, io = STDOUT) - klass.ole_methods.select {|method| - method.invoke_kind == 'PROPERTYGET' && - method.visible? && - method.size_params > 0 - }.each do |method| - types = method.return_type_detail - io.puts "\n" - io.puts generate_method_help(method, types[0]) - io.puts " def #{method.name}" - if klass.ole_type == "Class" - io.print " OLEProperty.new(@dispatch, #{method.dispid}, [" - else - io.print " OLEProperty.new(self, #{method.dispid}, [" - end - io.print generate_argtypes(method, nil) - io.print "], [" - io.print generate_argtypes(method, types) - io.puts "])" - io.puts " end" - end - end - - def generate_propput_methods(klass, io = STDOUT) - klass.ole_methods.select {|method| - method.invoke_kind == 'PROPERTYPUT' && method.visible? && - method.size_params == 1 - }.each do |method| - ms = klass.ole_methods.select {|m| - m.invoke_kind == 'PROPERTYGET' && - m.dispid == method.dispid - } - types = [] - if ms.size == 1 - types = ms[0].return_type_detail - end - generate_method(method, '_setproperty', io, types) - end - end - - def generate_propget_methods(klass, io = STDOUT) - klass.ole_methods.select {|method| - method.invoke_kind == 'PROPERTYGET' && method.visible? && - method.size_params == 0 - }.each do |method| - generate_method(method, '_getproperty', io) - end - end - - def generate_func_methods(klass, io = STDOUT) - klass.ole_methods.select {|method| - method.invoke_kind == "FUNC" && method.visible? - }.each do |method| - generate_method(method, '_invoke', io) - end - end - - def generate_methods(klass, io = STDOUT) - generate_propget_methods(klass, io) - generate_propput_methods(klass, io) - generate_properties_with_args(klass, io) - generate_func_methods(klass, io) -# generate_propputref_methods(klass, io) - end - - def generate_constants(klass, io = STDOUT) - klass.variables.select {|v| - v.visible? && v.variable_kind == 'CONSTANT' - }.each do |v| - io.print " " - io.print v.name.sub(/^./){$&.upcase} - io.print " = " - io.puts v.value - end - end - - def class_name(klass) - klass_name = klass.name - if klass.ole_type == "Class" && - klass.guid && - klass.progid - klass_name = klass.progid.gsub(/\./, '_') - end - if /^[A-Z]/ !~ klass_name || Module.constants.include?(klass_name) - klass_name = 'OLE' + klass_name - end - klass_name - end - - def define_initialize(klass) - <<STR - - def initialize(obj = nil) - @clsid = "#{klass.guid}" - @progid = "#{klass.progid}" - if obj.nil? - @dispatch = WIN32OLE.new @progid - else - @dispatch = obj - end - end -STR - end - - def define_include - " include WIN32OLE::VARIANT" - end - - def define_instance_variables - " attr_reader :lastargs" - end - - def define_method_missing - <<STR - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end -STR - end - - def define_class(klass, io = STDOUT) - io.puts "class #{class_name(klass)} # #{klass.name}" - io.puts define_include - io.puts define_instance_variables - io.puts " attr_reader :dispatch" - io.puts " attr_reader :clsid" - io.puts " attr_reader :progid" - io.puts define_initialize(klass) - io.puts define_method_missing - end - - def define_module(klass, io = STDOUT) - io.puts "module #{class_name(klass)}" - io.puts define_include - io.puts define_instance_variables - end - - def generate_class(klass, io = STDOUT) - io.puts "\n# #{klass.helpstring}" - if klass.ole_type == "Class" && - klass.guid && - klass.progid - @receiver = "@dispatch." - define_class(klass, io) - else - @receiver = "" - define_module(klass, io) - end - generate_constants(klass, io) - generate_methods(klass, io) - io.puts "end" - end - - def generate(io = STDOUT) - io.puts "require 'win32ole'" - io.puts "require 'win32ole/property'" - - ole_classes(typelib).select{|klass| - klass.visible? && - (klass.ole_type == "Class" || - klass.ole_type == "Interface" || - klass.ole_type == "Dispatch" || - klass.ole_type == "Enum") - }.each do |klass| - generate_class(klass, io) - end - begin - @ole.quit if @ole - rescue - end - end -end - -require 'win32ole' -if __FILE__ == $0 - if ARGV.size == 0 - $stderr.puts "usage: #{$0} Type Library [...]" - exit 1 - end - ARGV.each do |typelib| - comgen = WIN32COMGen.new(typelib) - comgen.generate - end -end diff --git a/ext/win32ole/sample/xml.rb b/ext/win32ole/sample/xml.rb deleted file mode 100644 index 5a239c9336..0000000000 --- a/ext/win32ole/sample/xml.rb +++ /dev/null @@ -1,7307 +0,0 @@ -# frozen_string_literal: false -# -# This file created by olegen.rb as following. -# ruby olegen.rb 'Microsoft XML, version 2.0' > xml.rb -# -require 'win32ole' -require 'win32ole/property' - -# -module IXMLDOMImplementation - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BOOL hasFeature - # BSTR arg0 --- feature [IN] - # BSTR arg1 --- version [IN] - def hasFeature(arg0, arg1) - ret = _invoke(145, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# Core DOM node interface -module IXMLDOMNode - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# Constants that define a node's type -module OLEtagDOMNodeType - include WIN32OLE::VARIANT - attr_reader :lastargs - NODE_INVALID = 0 - NODE_ELEMENT = 1 - NODE_ATTRIBUTE = 2 - NODE_TEXT = 3 - NODE_CDATA_SECTION = 4 - NODE_ENTITY_REFERENCE = 5 - NODE_ENTITY = 6 - NODE_PROCESSING_INSTRUCTION = 7 - NODE_COMMENT = 8 - NODE_DOCUMENT = 9 - NODE_DOCUMENT_TYPE = 10 - NODE_DOCUMENT_FRAGMENT = 11 - NODE_NOTATION = 12 -end - -# -module IXMLDOMNodeList - include WIN32OLE::VARIANT - attr_reader :lastargs - - # I4 length - # number of nodes in the collection - def length() - ret = _getproperty(74, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # PTR item - # collection of nodes - # I4 arg0 --- index [IN] - def item - OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH]) - end - - # IXMLDOMNode nextNode - # get next node from iterator - def nextNode() - ret = _invoke(76, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID reset - # reset the position of iterator - def reset() - ret = _invoke(77, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMNamedNodeMap - include WIN32OLE::VARIANT - attr_reader :lastargs - - # I4 length - # number of nodes in the collection - def length() - ret = _getproperty(74, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # PTR item - # collection of nodes - # I4 arg0 --- index [IN] - def item - OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH]) - end - - # IXMLDOMNode getNamedItem - # lookup item by name - # BSTR arg0 --- name [IN] - def getNamedItem(arg0) - ret = _invoke(83, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode setNamedItem - # set item by name - # IXMLDOMNode arg0 --- newItem [IN] - def setNamedItem(arg0) - ret = _invoke(84, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeNamedItem - # remove item by name - # BSTR arg0 --- name [IN] - def removeNamedItem(arg0) - ret = _invoke(85, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode getQualifiedItem - # lookup the item by name and namespace - # BSTR arg0 --- baseName [IN] - # BSTR arg1 --- namespaceURI [IN] - def getQualifiedItem(arg0, arg1) - ret = _invoke(87, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeQualifiedItem - # remove the item by name and namespace - # BSTR arg0 --- baseName [IN] - # BSTR arg1 --- namespaceURI [IN] - def removeQualifiedItem(arg0, arg1) - ret = _invoke(88, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextNode - # get next node from iterator - def nextNode() - ret = _invoke(89, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID reset - # reset the position of iterator - def reset() - ret = _invoke(90, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMDocument - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentType doctype - # node corresponding to the DOCTYPE - def doctype() - ret = _getproperty(38, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMImplementation implementation - # info on this DOM implementation - def implementation() - ret = _getproperty(39, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement documentElement - # the root of the tree - def documentElement() - ret = _getproperty(40, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - # get the state of the XML document - def readyState() - ret = _getproperty(-525, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMParseError parseError - # get the last parser error - def parseError() - ret = _getproperty(59, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR url - # get the URL for the loaded XML document - def url() - ret = _getproperty(60, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL async - # flag for asynchronous download - def async() - ret = _getproperty(61, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL validateOnParse - # indicates whether the parser performs validation - def validateOnParse() - ret = _getproperty(65, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals() - ret = _getproperty(66, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace() - ret = _getproperty(67, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID async - # flag for asynchronous download - def async=(arg0) - ret = _setproperty(61, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID validateOnParse - # indicates whether the parser performs validation - def validateOnParse=(arg0) - ret = _setproperty(65, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals=(arg0) - ret = _setproperty(66, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace=(arg0) - ret = _setproperty(67, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID onreadystatechange - # register a readystatechange event handler - def onreadystatechange=(arg0) - ret = _setproperty(68, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ondataavailable - # register an ondataavailable event handler - def ondataavailable=(arg0) - ret = _setproperty(69, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ontransformnode - # register an ontransformnode event handler - def ontransformnode=(arg0) - ret = _setproperty(70, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement createElement - # create an Element node - # BSTR arg0 --- tagName [IN] - def createElement(arg0) - ret = _invoke(41, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentFragment createDocumentFragment - # create a DocumentFragment node - def createDocumentFragment() - ret = _invoke(42, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMText createTextNode - # create a text node - # BSTR arg0 --- data [IN] - def createTextNode(arg0) - ret = _invoke(43, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMComment createComment - # create a comment node - # BSTR arg0 --- data [IN] - def createComment(arg0) - ret = _invoke(44, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMCDATASection createCDATASection - # create a CDATA section node - # BSTR arg0 --- data [IN] - def createCDATASection(arg0) - ret = _invoke(45, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMProcessingInstruction createProcessingInstruction - # create a processing instruction node - # BSTR arg0 --- target [IN] - # BSTR arg1 --- data [IN] - def createProcessingInstruction(arg0, arg1) - ret = _invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute createAttribute - # create an attribute node - # BSTR arg0 --- name [IN] - def createAttribute(arg0) - ret = _invoke(47, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMEntityReference createEntityReference - # create an entity reference node - # BSTR arg0 --- name [IN] - def createEntityReference(arg0) - ret = _invoke(49, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList getElementsByTagName - # build a list of elements by name - # BSTR arg0 --- tagName [IN] - def getElementsByTagName(arg0) - ret = _invoke(50, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode createNode - # create a node of the specified node type and name - # VARIANT arg0 --- type [IN] - # BSTR arg1 --- name [IN] - # BSTR arg2 --- namespaceURI [IN] - def createNode(arg0, arg1, arg2) - ret = _invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nodeFromID - # retrieve node from it's ID - # BSTR arg0 --- idString [IN] - def nodeFromID(arg0) - ret = _invoke(56, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL load - # load document from the specified XML source - # VARIANT arg0 --- xmlSource [IN] - def load(arg0) - ret = _invoke(58, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID abort - # abort an asynchronous download - def abort() - ret = _invoke(62, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL loadXML - # load the document from a string - # BSTR arg0 --- bstrXML [IN] - def loadXML(arg0) - ret = _invoke(63, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID save - # save the document to a specified destination - # VARIANT arg0 --- destination [IN] - def save(arg0) - ret = _invoke(64, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMDocumentType - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR name - # name of the document type (root of the tree) - def name() - ret = _getproperty(131, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap entities - # a list of entities in the document - def entities() - ret = _getproperty(132, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap notations - # a list of notations in the document - def notations() - ret = _getproperty(133, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMElement - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR tagName - # get the tagName of the element - def tagName() - ret = _getproperty(97, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT getAttribute - # look up the string value of an attribute by name - # BSTR arg0 --- name [IN] - def getAttribute(arg0) - ret = _invoke(99, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID setAttribute - # set the string value of an attribute by name - # BSTR arg0 --- name [IN] - # VARIANT arg1 --- value [IN] - def setAttribute(arg0, arg1) - ret = _invoke(100, [arg0, arg1], [VT_BSTR, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID removeAttribute - # remove an attribute by name - # BSTR arg0 --- name [IN] - def removeAttribute(arg0) - ret = _invoke(101, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute getAttributeNode - # look up the attribute node by name - # BSTR arg0 --- name [IN] - def getAttributeNode(arg0) - ret = _invoke(102, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute setAttributeNode - # set the specified attribute on the element - # IXMLDOMAttribute arg0 --- DOMAttribute [IN] - def setAttributeNode(arg0) - ret = _invoke(103, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute removeAttributeNode - # remove the specified attribute - # IXMLDOMAttribute arg0 --- DOMAttribute [IN] - def removeAttributeNode(arg0) - ret = _invoke(104, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList getElementsByTagName - # build a list of elements by name - # BSTR arg0 --- tagName [IN] - def getElementsByTagName(arg0) - ret = _invoke(105, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID normalize - # collapse all adjacent text nodes in sub-tree - def normalize() - ret = _invoke(106, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMAttribute - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR name - # get name of the attribute - def name() - ret = _getproperty(118, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT value - # string value of the attribute - def value() - ret = _getproperty(120, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID value - # string value of the attribute - def value=(arg0) - ret = _setproperty(120, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMDocumentFragment - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMText - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR data - # value of the node - def data() - ret = _getproperty(109, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 length - # number of characters in value - def length() - ret = _getproperty(110, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID data - # value of the node - def data=(arg0) - ret = _setproperty(109, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR substringData - # retrieve substring of value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def substringData(arg0, arg1) - ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID appendData - # append string to value - # BSTR arg0 --- data [IN] - def appendData(arg0) - ret = _invoke(112, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID insertData - # insert string into value - # I4 arg0 --- offset [IN] - # BSTR arg1 --- data [IN] - def insertData(arg0, arg1) - ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID deleteData - # delete string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def deleteData(arg0, arg1) - ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID replaceData - # replace string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - # BSTR arg2 --- data [IN] - def replaceData(arg0, arg1, arg2) - ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMText splitText - # split the text node into two text nodes at the position specified - # I4 arg0 --- offset [IN] - def splitText(arg0) - ret = _invoke(123, [arg0], [VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMCharacterData - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR data - # value of the node - def data() - ret = _getproperty(109, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 length - # number of characters in value - def length() - ret = _getproperty(110, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID data - # value of the node - def data=(arg0) - ret = _setproperty(109, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR substringData - # retrieve substring of value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def substringData(arg0, arg1) - ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID appendData - # append string to value - # BSTR arg0 --- data [IN] - def appendData(arg0) - ret = _invoke(112, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID insertData - # insert string into value - # I4 arg0 --- offset [IN] - # BSTR arg1 --- data [IN] - def insertData(arg0, arg1) - ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID deleteData - # delete string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def deleteData(arg0, arg1) - ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID replaceData - # replace string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - # BSTR arg2 --- data [IN] - def replaceData(arg0, arg1, arg2) - ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMComment - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR data - # value of the node - def data() - ret = _getproperty(109, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 length - # number of characters in value - def length() - ret = _getproperty(110, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID data - # value of the node - def data=(arg0) - ret = _setproperty(109, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR substringData - # retrieve substring of value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def substringData(arg0, arg1) - ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID appendData - # append string to value - # BSTR arg0 --- data [IN] - def appendData(arg0) - ret = _invoke(112, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID insertData - # insert string into value - # I4 arg0 --- offset [IN] - # BSTR arg1 --- data [IN] - def insertData(arg0, arg1) - ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID deleteData - # delete string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def deleteData(arg0, arg1) - ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID replaceData - # replace string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - # BSTR arg2 --- data [IN] - def replaceData(arg0, arg1, arg2) - ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMCDATASection - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR data - # value of the node - def data() - ret = _getproperty(109, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 length - # number of characters in value - def length() - ret = _getproperty(110, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID data - # value of the node - def data=(arg0) - ret = _setproperty(109, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR substringData - # retrieve substring of value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def substringData(arg0, arg1) - ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID appendData - # append string to value - # BSTR arg0 --- data [IN] - def appendData(arg0) - ret = _invoke(112, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID insertData - # insert string into value - # I4 arg0 --- offset [IN] - # BSTR arg1 --- data [IN] - def insertData(arg0, arg1) - ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID deleteData - # delete string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - def deleteData(arg0, arg1) - ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID replaceData - # replace string within the value - # I4 arg0 --- offset [IN] - # I4 arg1 --- count [IN] - # BSTR arg2 --- data [IN] - def replaceData(arg0, arg1, arg2) - ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMText splitText - # split the text node into two text nodes at the position specified - # I4 arg0 --- offset [IN] - def splitText(arg0) - ret = _invoke(123, [arg0], [VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMProcessingInstruction - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR target - # the target - def target() - ret = _getproperty(127, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR data - # the data - def data() - ret = _getproperty(128, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID data - # the data - def data=(arg0) - ret = _setproperty(128, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMEntityReference - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# structure for reporting parser errors -module IXMLDOMParseError - include WIN32OLE::VARIANT - attr_reader :lastargs - - # I4 errorCode - # the error code - def errorCode() - ret = _getproperty(0, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR url - # the URL of the XML document containing the error - def url() - ret = _getproperty(179, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR reason - # the cause of the error - def reason() - ret = _getproperty(180, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR srcText - # the data where the error occurred - def srcText() - ret = _getproperty(181, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 line - # the line number in the XML document where the error occurred - def line() - ret = _getproperty(182, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 linepos - # the character position in the line containing the error - def linepos() - ret = _getproperty(183, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 filepos - # the absolute file position in the XML document containing the error - def filepos() - ret = _getproperty(184, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMNotation - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT publicId - # the public ID - def publicId() - ret = _getproperty(136, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT systemId - # the system ID - def systemId() - ret = _getproperty(137, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# -module IXMLDOMEntity - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT publicId - # the public ID - def publicId() - ret = _getproperty(140, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT systemId - # the system ID - def systemId() - ret = _getproperty(141, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR notationName - # the name of the notation - def notationName() - ret = _getproperty(142, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# XTL runtime object -module IXTLRuntime - include WIN32OLE::VARIANT - attr_reader :lastargs - - # BSTR nodeName - # name of the node - def nodeName() - ret = _getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = _getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = _getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = _getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = _getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = _getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = _getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = _getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = _getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = _getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = _getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = _getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = _getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = _getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = _getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = _getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = _setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = _setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = _setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = _setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = _invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = _invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = _invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = _invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 uniqueID - # IXMLDOMNode arg0 --- pNode [IN] - def uniqueID(arg0) - ret = _invoke(187, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 depth - # IXMLDOMNode arg0 --- pNode [IN] - def depth(arg0) - ret = _invoke(188, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 childNumber - # IXMLDOMNode arg0 --- pNode [IN] - def childNumber(arg0) - ret = _invoke(189, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 ancestorChildNumber - # BSTR arg0 --- bstrNodeName [IN] - # IXMLDOMNode arg1 --- pNode [IN] - def ancestorChildNumber(arg0, arg1) - ret = _invoke(190, [arg0, arg1], [VT_BSTR, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 absoluteChildNumber - # IXMLDOMNode arg0 --- pNode [IN] - def absoluteChildNumber(arg0) - ret = _invoke(191, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR formatIndex - # I4 arg0 --- lIndex [IN] - # BSTR arg1 --- bstrFormat [IN] - def formatIndex(arg0, arg1) - ret = _invoke(192, [arg0, arg1], [VT_I4, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR formatNumber - # R8 arg0 --- dblNumber [IN] - # BSTR arg1 --- bstrFormat [IN] - def formatNumber(arg0, arg1) - ret = _invoke(193, [arg0, arg1], [VT_R8, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR formatDate - # VARIANT arg0 --- varDate [IN] - # BSTR arg1 --- bstrFormat [IN] - # VARIANT arg2 --- varDestLocale [IN] - def formatDate(arg0, arg1, arg2=nil) - ret = _invoke(194, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR formatTime - # VARIANT arg0 --- varTime [IN] - # BSTR arg1 --- bstrFormat [IN] - # VARIANT arg2 --- varDestLocale [IN] - def formatTime(arg0, arg1, arg2=nil) - ret = _invoke(195, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# W3C-DOM XML Document -class Microsoft_XMLDOM_1_0 # DOMDocument - include WIN32OLE::VARIANT - attr_reader :lastargs - attr_reader :dispatch - attr_reader :clsid - attr_reader :progid - - def initialize(obj = nil) - @clsid = "{2933BF90-7B36-11D2-B20E-00C04F983E60}" - @progid = "Microsoft.XMLDOM.1.0" - if obj.nil? - @dispatch = WIN32OLE.new(@progid) - else - @dispatch = obj - end - end - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end - - # BSTR nodeName - # name of the node - def nodeName() - ret = @dispatch._getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = @dispatch._getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = @dispatch._getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = @dispatch._getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = @dispatch._getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = @dispatch._getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = @dispatch._getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = @dispatch._getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = @dispatch._getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = @dispatch._getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = @dispatch._getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = @dispatch._getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = @dispatch._getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = @dispatch._getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = @dispatch._getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = @dispatch._getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = @dispatch._getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = @dispatch._getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = @dispatch._getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = @dispatch._getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = @dispatch._getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = @dispatch._getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentType doctype - # node corresponding to the DOCTYPE - def doctype() - ret = @dispatch._getproperty(38, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMImplementation implementation - # info on this DOM implementation - def implementation() - ret = @dispatch._getproperty(39, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement documentElement - # the root of the tree - def documentElement() - ret = @dispatch._getproperty(40, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - # get the state of the XML document - def readyState() - ret = @dispatch._getproperty(-525, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMParseError parseError - # get the last parser error - def parseError() - ret = @dispatch._getproperty(59, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR url - # get the URL for the loaded XML document - def url() - ret = @dispatch._getproperty(60, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL async - # flag for asynchronous download - def async() - ret = @dispatch._getproperty(61, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL validateOnParse - # indicates whether the parser performs validation - def validateOnParse() - ret = @dispatch._getproperty(65, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals() - ret = @dispatch._getproperty(66, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace() - ret = @dispatch._getproperty(67, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = @dispatch._setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID async - # flag for asynchronous download - def async=(arg0) - ret = @dispatch._setproperty(61, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID validateOnParse - # indicates whether the parser performs validation - def validateOnParse=(arg0) - ret = @dispatch._setproperty(65, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals=(arg0) - ret = @dispatch._setproperty(66, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace=(arg0) - ret = @dispatch._setproperty(67, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID onreadystatechange - # register a readystatechange event handler - def onreadystatechange=(arg0) - ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ondataavailable - # register an ondataavailable event handler - def ondataavailable=(arg0) - ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ontransformnode - # register an ontransformnode event handler - def ontransformnode=(arg0) - ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = @dispatch._invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = @dispatch._invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = @dispatch._invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = @dispatch._invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement createElement - # create an Element node - # BSTR arg0 --- tagName [IN] - def createElement(arg0) - ret = @dispatch._invoke(41, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentFragment createDocumentFragment - # create a DocumentFragment node - def createDocumentFragment() - ret = @dispatch._invoke(42, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMText createTextNode - # create a text node - # BSTR arg0 --- data [IN] - def createTextNode(arg0) - ret = @dispatch._invoke(43, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMComment createComment - # create a comment node - # BSTR arg0 --- data [IN] - def createComment(arg0) - ret = @dispatch._invoke(44, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMCDATASection createCDATASection - # create a CDATA section node - # BSTR arg0 --- data [IN] - def createCDATASection(arg0) - ret = @dispatch._invoke(45, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMProcessingInstruction createProcessingInstruction - # create a processing instruction node - # BSTR arg0 --- target [IN] - # BSTR arg1 --- data [IN] - def createProcessingInstruction(arg0, arg1) - ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute createAttribute - # create an attribute node - # BSTR arg0 --- name [IN] - def createAttribute(arg0) - ret = @dispatch._invoke(47, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMEntityReference createEntityReference - # create an entity reference node - # BSTR arg0 --- name [IN] - def createEntityReference(arg0) - ret = @dispatch._invoke(49, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList getElementsByTagName - # build a list of elements by name - # BSTR arg0 --- tagName [IN] - def getElementsByTagName(arg0) - ret = @dispatch._invoke(50, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode createNode - # create a node of the specified node type and name - # VARIANT arg0 --- type [IN] - # BSTR arg1 --- name [IN] - # BSTR arg2 --- namespaceURI [IN] - def createNode(arg0, arg1, arg2) - ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nodeFromID - # retrieve node from it's ID - # BSTR arg0 --- idString [IN] - def nodeFromID(arg0) - ret = @dispatch._invoke(56, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL load - # load document from the specified XML source - # VARIANT arg0 --- xmlSource [IN] - def load(arg0) - ret = @dispatch._invoke(58, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID abort - # abort an asynchronous download - def abort() - ret = @dispatch._invoke(62, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL loadXML - # load the document from a string - # BSTR arg0 --- bstrXML [IN] - def loadXML(arg0) - ret = @dispatch._invoke(63, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID save - # save the document to a specified destination - # VARIANT arg0 --- destination [IN] - def save(arg0) - ret = @dispatch._invoke(64, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents - def ondataavailable() - ret = @dispatch._invoke(198, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents - def onreadystatechange() - ret = @dispatch._invoke(-609, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# W3C-DOM XML Document (Apartment) -class Microsoft_FreeThreadedXMLDOM_1_0 # DOMFreeThreadedDocument - include WIN32OLE::VARIANT - attr_reader :lastargs - attr_reader :dispatch - attr_reader :clsid - attr_reader :progid - - def initialize(obj = nil) - @clsid = "{2933BF91-7B36-11D2-B20E-00C04F983E60}" - @progid = "Microsoft.FreeThreadedXMLDOM.1.0" - if obj.nil? - @dispatch = WIN32OLE.new(@progid) - else - @dispatch = obj - end - end - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end - - # BSTR nodeName - # name of the node - def nodeName() - ret = @dispatch._getproperty(2, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeValue - # value stored in the node - def nodeValue() - ret = @dispatch._getproperty(3, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DOMNodeType nodeType - # the node's type - def nodeType() - ret = @dispatch._getproperty(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode parentNode - # parent of the node - def parentNode() - ret = @dispatch._getproperty(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList childNodes - # the collection of the node's children - def childNodes() - ret = @dispatch._getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode firstChild - # first child of the node - def firstChild() - ret = @dispatch._getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode lastChild - # first child of the node - def lastChild() - ret = @dispatch._getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode previousSibling - # left sibling of the node - def previousSibling() - ret = @dispatch._getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nextSibling - # right sibling of the node - def nextSibling() - ret = @dispatch._getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNamedNodeMap attributes - # the collection of the node's attributes - def attributes() - ret = @dispatch._getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocument ownerDocument - # document that contains the node - def ownerDocument() - ret = @dispatch._getproperty(18, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR nodeTypeString - # the type of node in string form - def nodeTypeString() - ret = @dispatch._getproperty(21, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR text - # text content of the node and subtree - def text() - ret = @dispatch._getproperty(24, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL specified - # indicates whether node is a default value - def specified() - ret = @dispatch._getproperty(22, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode definition - # pointer to the definition of the node in the DTD or schema - def definition() - ret = @dispatch._getproperty(23, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue() - ret = @dispatch._getproperty(25, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT dataType - # the data type of the node - def dataType() - ret = @dispatch._getproperty(26, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR xml - # return the XML source for the node and each of its descendants - def xml() - ret = @dispatch._getproperty(27, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL parsed - # has sub-tree been completely parsed - def parsed() - ret = @dispatch._getproperty(31, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR namespaceURI - # the URI for the namespace applying to the node - def namespaceURI() - ret = @dispatch._getproperty(32, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR prefix - # the prefix for the namespace applying to the node - def prefix() - ret = @dispatch._getproperty(33, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR baseName - # the base name of the node (nodename with the prefix stripped off) - def baseName() - ret = @dispatch._getproperty(34, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentType doctype - # node corresponding to the DOCTYPE - def doctype() - ret = @dispatch._getproperty(38, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMImplementation implementation - # info on this DOM implementation - def implementation() - ret = @dispatch._getproperty(39, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement documentElement - # the root of the tree - def documentElement() - ret = @dispatch._getproperty(40, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - # get the state of the XML document - def readyState() - ret = @dispatch._getproperty(-525, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMParseError parseError - # get the last parser error - def parseError() - ret = @dispatch._getproperty(59, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR url - # get the URL for the loaded XML document - def url() - ret = @dispatch._getproperty(60, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL async - # flag for asynchronous download - def async() - ret = @dispatch._getproperty(61, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL validateOnParse - # indicates whether the parser performs validation - def validateOnParse() - ret = @dispatch._getproperty(65, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals() - ret = @dispatch._getproperty(66, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace() - ret = @dispatch._getproperty(67, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeValue - # value stored in the node - def nodeValue=(arg0) - ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID text - # text content of the node and subtree - def text=(arg0) - ret = @dispatch._setproperty(24, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID nodeTypedValue - # get the strongly typed value of the node - def nodeTypedValue=(arg0) - ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID dataType - # the data type of the node - def dataType=(arg0) - ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID async - # flag for asynchronous download - def async=(arg0) - ret = @dispatch._setproperty(61, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID validateOnParse - # indicates whether the parser performs validation - def validateOnParse=(arg0) - ret = @dispatch._setproperty(65, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID resolveExternals - # indicates whether the parser resolves references to external DTD/Entities/Schema - def resolveExternals=(arg0) - ret = @dispatch._setproperty(66, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID preserveWhiteSpace - # indicates whether the parser preserves whitespace - def preserveWhiteSpace=(arg0) - ret = @dispatch._setproperty(67, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID onreadystatechange - # register a readystatechange event handler - def onreadystatechange=(arg0) - ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ondataavailable - # register an ondataavailable event handler - def ondataavailable=(arg0) - ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID ontransformnode - # register an ontransformnode event handler - def ontransformnode=(arg0) - ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode insertBefore - # insert a child node - # IXMLDOMNode arg0 --- newChild [IN] - # VARIANT arg1 --- refChild [IN] - def insertBefore(arg0, arg1) - ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode replaceChild - # replace a child node - # IXMLDOMNode arg0 --- newChild [IN] - # IXMLDOMNode arg1 --- oldChild [IN] - def replaceChild(arg0, arg1) - ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode removeChild - # remove a child node - # IXMLDOMNode arg0 --- childNode [IN] - def removeChild(arg0) - ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode appendChild - # append a child node - # IXMLDOMNode arg0 --- newChild [IN] - def appendChild(arg0) - ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL hasChildNodes - def hasChildNodes() - ret = @dispatch._invoke(17, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode cloneNode - # BOOL arg0 --- deep [IN] - def cloneNode(arg0) - ret = @dispatch._invoke(19, [arg0], [VT_BOOL]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR transformNode - # apply the stylesheet to the subtree - # IXMLDOMNode arg0 --- stylesheet [IN] - def transformNode(arg0) - ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList selectNodes - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectNodes(arg0) - ret = @dispatch._invoke(29, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode selectSingleNode - # execute query on the subtree - # BSTR arg0 --- queryString [IN] - def selectSingleNode(arg0) - ret = @dispatch._invoke(30, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID transformNodeToObject - # apply the stylesheet to the subtree, returning the result through a document or a stream - # IXMLDOMNode arg0 --- stylesheet [IN] - # VARIANT arg1 --- outputObject [IN] - def transformNodeToObject(arg0, arg1) - ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMElement createElement - # create an Element node - # BSTR arg0 --- tagName [IN] - def createElement(arg0) - ret = @dispatch._invoke(41, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMDocumentFragment createDocumentFragment - # create a DocumentFragment node - def createDocumentFragment() - ret = @dispatch._invoke(42, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMText createTextNode - # create a text node - # BSTR arg0 --- data [IN] - def createTextNode(arg0) - ret = @dispatch._invoke(43, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMComment createComment - # create a comment node - # BSTR arg0 --- data [IN] - def createComment(arg0) - ret = @dispatch._invoke(44, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMCDATASection createCDATASection - # create a CDATA section node - # BSTR arg0 --- data [IN] - def createCDATASection(arg0) - ret = @dispatch._invoke(45, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMProcessingInstruction createProcessingInstruction - # create a processing instruction node - # BSTR arg0 --- target [IN] - # BSTR arg1 --- data [IN] - def createProcessingInstruction(arg0, arg1) - ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMAttribute createAttribute - # create an attribute node - # BSTR arg0 --- name [IN] - def createAttribute(arg0) - ret = @dispatch._invoke(47, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMEntityReference createEntityReference - # create an entity reference node - # BSTR arg0 --- name [IN] - def createEntityReference(arg0) - ret = @dispatch._invoke(49, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNodeList getElementsByTagName - # build a list of elements by name - # BSTR arg0 --- tagName [IN] - def getElementsByTagName(arg0) - ret = @dispatch._invoke(50, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode createNode - # create a node of the specified node type and name - # VARIANT arg0 --- type [IN] - # BSTR arg1 --- name [IN] - # BSTR arg2 --- namespaceURI [IN] - def createNode(arg0, arg1, arg2) - ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # IXMLDOMNode nodeFromID - # retrieve node from it's ID - # BSTR arg0 --- idString [IN] - def nodeFromID(arg0) - ret = @dispatch._invoke(56, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL load - # load document from the specified XML source - # VARIANT arg0 --- xmlSource [IN] - def load(arg0) - ret = @dispatch._invoke(58, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID abort - # abort an asynchronous download - def abort() - ret = @dispatch._invoke(62, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BOOL loadXML - # load the document from a string - # BSTR arg0 --- bstrXML [IN] - def loadXML(arg0) - ret = @dispatch._invoke(63, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID save - # save the document to a specified destination - # VARIANT arg0 --- destination [IN] - def save(arg0) - ret = @dispatch._invoke(64, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents - def ondataavailable() - ret = @dispatch._invoke(198, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents - def onreadystatechange() - ret = @dispatch._invoke(-609, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# IXMLHttpRequest Interface -module IXMLHttpRequest - include WIN32OLE::VARIANT - attr_reader :lastargs - - # I4 status - # Get HTTP status code - def status() - ret = _getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR statusText - # Get HTTP status text - def statusText() - ret = _getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DISPATCH responseXML - # Get response body - def responseXML() - ret = _getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR responseText - # Get response body - def responseText() - ret = _getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT responseBody - # Get response body - def responseBody() - ret = _getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT responseStream - # Get response body - def responseStream() - ret = _getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - # Get ready state - def readyState() - ret = _getproperty(13, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID onreadystatechange - # Register a complete event handler - def onreadystatechange=(arg0) - ret = _setproperty(14, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID open - # Open HTTP connection - # BSTR arg0 --- bstrMethod [IN] - # BSTR arg1 --- bstrUrl [IN] - # VARIANT arg2 --- varAsync [IN] - # VARIANT arg3 --- bstrUser [IN] - # VARIANT arg4 --- bstrPassword [IN] - def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil) - ret = _invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID setRequestHeader - # Add HTTP request header - # BSTR arg0 --- bstrHeader [IN] - # BSTR arg1 --- bstrValue [IN] - def setRequestHeader(arg0, arg1) - ret = _invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR getResponseHeader - # Get HTTP response header - # BSTR arg0 --- bstrHeader [IN] - def getResponseHeader(arg0) - ret = _invoke(3, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR getAllResponseHeaders - # Get all HTTP response headers - def getAllResponseHeaders() - ret = _invoke(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID send - # Send HTTP request - # VARIANT arg0 --- varBody [IN] - def send(arg0=nil) - ret = _invoke(5, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID abort - # Abort HTTP request - def abort() - ret = _invoke(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# XML HTTP Request class. -class Microsoft_XMLHTTP_1 # XMLHTTPRequest - include WIN32OLE::VARIANT - attr_reader :lastargs - attr_reader :dispatch - attr_reader :clsid - attr_reader :progid - - def initialize(obj = nil) - @clsid = "{ED8C108E-4349-11D2-91A4-00C04F7969E8}" - @progid = "Microsoft.XMLHTTP.1" - if obj.nil? - @dispatch = WIN32OLE.new(@progid) - else - @dispatch = obj - end - end - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end - - # I4 status - # Get HTTP status code - def status() - ret = @dispatch._getproperty(7, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR statusText - # Get HTTP status text - def statusText() - ret = @dispatch._getproperty(8, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # DISPATCH responseXML - # Get response body - def responseXML() - ret = @dispatch._getproperty(9, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR responseText - # Get response body - def responseText() - ret = @dispatch._getproperty(10, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT responseBody - # Get response body - def responseBody() - ret = @dispatch._getproperty(11, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VARIANT responseStream - # Get response body - def responseStream() - ret = @dispatch._getproperty(12, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - # Get ready state - def readyState() - ret = @dispatch._getproperty(13, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID onreadystatechange - # Register a complete event handler - def onreadystatechange=(arg0) - ret = @dispatch._setproperty(14, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID open - # Open HTTP connection - # BSTR arg0 --- bstrMethod [IN] - # BSTR arg1 --- bstrUrl [IN] - # VARIANT arg2 --- varAsync [IN] - # VARIANT arg3 --- bstrUser [IN] - # VARIANT arg4 --- bstrPassword [IN] - def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil) - ret = @dispatch._invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID setRequestHeader - # Add HTTP request header - # BSTR arg0 --- bstrHeader [IN] - # BSTR arg1 --- bstrValue [IN] - def setRequestHeader(arg0, arg1) - ret = @dispatch._invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR getResponseHeader - # Get HTTP response header - # BSTR arg0 --- bstrHeader [IN] - def getResponseHeader(arg0) - ret = @dispatch._invoke(3, [arg0], [VT_BSTR]) - @lastargs = WIN32OLE::ARGV - ret - end - - # BSTR getAllResponseHeaders - # Get all HTTP response headers - def getAllResponseHeaders() - ret = @dispatch._invoke(4, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID send - # Send HTTP request - # VARIANT arg0 --- varBody [IN] - def send(arg0=nil) - ret = @dispatch._invoke(5, [arg0], [VT_VARIANT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID abort - # Abort HTTP request - def abort() - ret = @dispatch._invoke(6, [], []) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# XML Data Source Object -class Microsoft_XMLDSO_1_0 # XMLDSOControl - include WIN32OLE::VARIANT - attr_reader :lastargs - attr_reader :dispatch - attr_reader :clsid - attr_reader :progid - - def initialize(obj = nil) - @clsid = "{550DDA30-0541-11D2-9CA9-0060B0EC3D39}" - @progid = "Microsoft.XMLDSO.1.0" - if obj.nil? - @dispatch = WIN32OLE.new(@progid) - else - @dispatch = obj - end - end - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end - - # IXMLDOMDocument XMLDocument - def XMLDocument() - ret = @dispatch._getproperty(65537, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 JavaDSOCompatible - def JavaDSOCompatible() - ret = @dispatch._getproperty(65538, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # I4 readyState - def readyState() - ret = @dispatch._getproperty(-525, [], []) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID XMLDocument - def XMLDocument=(arg0) - ret = @dispatch._setproperty(65537, [arg0], [VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end - - # VOID JavaDSOCompatible - def JavaDSOCompatible=(arg0) - ret = @dispatch._setproperty(65538, [arg0], [VT_I4]) - @lastargs = WIN32OLE::ARGV - ret - end -end - -# Constants that define types for IXMLElement. -module OLEtagXMLEMEM_TYPE - include WIN32OLE::VARIANT - attr_reader :lastargs - XMLELEMTYPE_ELEMENT = 0 - XMLELEMTYPE_TEXT = 1 - XMLELEMTYPE_COMMENT = 2 - XMLELEMTYPE_DOCUMENT = 3 - XMLELEMTYPE_DTD = 4 - XMLELEMTYPE_PI = 5 - XMLELEMTYPE_OTHER = 6 -end - -# XMLDocument extends IXML Document. It is obsolete. You should use DOMDocument. This object should not be confused with the XMLDocument property on the XML data island. -class Msxml # XMLDocument - include WIN32OLE::VARIANT - attr_reader :lastargs - attr_reader :dispatch - attr_reader :clsid - attr_reader :progid - - def initialize(obj = nil) - @clsid = "{CFC399AF-D876-11D0-9C10-00C04FC99C8E}" - @progid = "Msxml" - if obj.nil? - @dispatch = WIN32OLE.new(@progid) - else - @dispatch = obj - end - end - - def method_missing(cmd, *arg) - @dispatch.method_missing(cmd, *arg) - end - - # HRESULT url - # set URL to load an XML document from the URL. - # BSTR arg0 --- p [IN] - def url=(arg0) - ret = @dispatch._setproperty(65641, [arg0], [VT_BSTR, VT_HRESULT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT charset - # get encoding. - # BSTR arg0 --- p [IN] - def charset=(arg0) - ret = @dispatch._setproperty(65645, [arg0], [VT_BSTR, VT_HRESULT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT async - # get asynchronous loading flag. - # BOOL arg0 --- pf [IN] - def async=(arg0) - ret = @dispatch._setproperty(65649, [arg0], [VT_BOOL, VT_HRESULT]) - @lastargs = WIN32OLE::ARGV - ret - end - - # HRESULT root - # get root IXMLElement of the XML document. - # IXMLElement2,IXMLElement2 arg0 --- p [OUT] - def root - OLEProperty.new(@dispatch, 65637, [VT_BYREF|VT_BYREF|VT_DISPATCH], [VT_BYREF|VT_BYREF|VT_DISPATCH, VT_HRESULT]) - end - - # HRESULT url - # set URL to load an XML document from the URL. - # BSTR arg0 --- p [OUT] - def url - OLEProperty.new(@dispatch, 65641, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT]) - end - - # HRESULT readyState - # get ready state. - # I4 arg0 --- pl [OUT] - def readyState - OLEProperty.new(@dispatch, 65643, [VT_BYREF|VT_I4], [VT_BYREF|VT_I4, VT_HRESULT]) - end - - # HRESULT charset - # get encoding. - # BSTR arg0 --- p [OUT] - def charset - OLEProperty.new(@dispatch, 65645, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT]) - end - - # HRESULT version - # get XML version number. - # BSTR arg0 --- p [OUT] - def version - OLEProperty.new(@dispatch, 65646, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT]) - end - - # HRESULT doctype - # get document type. - # BSTR arg0 --- p [OUT] - def doctype - OLEProperty.new(@dispatch, 65647, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT]) - end - - # HRESULT async - # get asynchronous loading flag. - # BOOL arg0 --- pf [OUT] - def async - OLEProperty.new(@dispatch, 65649, [VT_BYREF|VT_BOOL], [VT_BYREF|VT_BOOL, VT_HRESULT]) - end - - # HRESULT createElement - # create different types of IXMLElements. - # VARIANT arg0 --- vType [IN] - # VARIANT arg1 --- var1 [IN] - # IXMLElement2,IXMLElement2 arg2 --- ppElem [OUT] - def createElement(arg0, arg1=nil, arg2=nil) - ret = @dispatch._invoke(65644, [arg0, arg1, arg2], [VT_VARIANT, VT_VARIANT, VT_BYREF|VT_BYREF|VT_DISPATCH]) - @lastargs = WIN32OLE::ARGV - ret - end -end diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c deleted file mode 100644 index 5ad6a80eb9..0000000000 --- a/ext/win32ole/win32ole.c +++ /dev/null @@ -1,4142 +0,0 @@ -/* - * (c) 1995 Microsoft Corporation. All rights reserved. - * Developed by ActiveWare Internet Corp., now known as - * ActiveState Tool Corp., http://www.ActiveState.com - * - * Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy - * <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net> - * - * 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. - * - */ - -/* - modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp> - */ - -#include "win32ole.h" - -/* - * unfortunately IID_IMultiLanguage2 is not included in any libXXX.a - * in Cygwin(mingw32). - */ -#if defined(__CYGWIN__) || defined(__MINGW32__) -#undef IID_IMultiLanguage2 -const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}}; -#endif - -#define WIN32OLE_VERSION "1.8.8" - -typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) - (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); - -typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile, - UINT uCommand, DWORD dwData); -typedef BOOL (FNENUMSYSEMCODEPAGES) (CODEPAGE_ENUMPROC, DWORD); -VALUE cWIN32OLE; - -#if defined(RB_THREAD_SPECIFIC) && (defined(__CYGWIN__)) -static RB_THREAD_SPECIFIC BOOL g_ole_initialized; -# define g_ole_initialized_init() ((void)0) -# define g_ole_initialized_set(val) (g_ole_initialized = (val)) -#else -static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES; -# define g_ole_initialized (TlsGetValue(g_ole_initialized_key)!=0) -# define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc()) -# define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val)) -#endif - -static BOOL g_uninitialize_hooked = FALSE; -static BOOL g_cp_installed = FALSE; -static BOOL g_lcid_installed = FALSE; -static BOOL g_running_nano = FALSE; -static HINSTANCE ghhctrl = NULL; -static HINSTANCE gole32 = NULL; -static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL; -static VALUE com_hash; -static VALUE enc2cp_hash; -static IDispatchVtbl com_vtbl; -static UINT cWIN32OLE_cp = CP_ACP; -static rb_encoding *cWIN32OLE_enc; -static UINT g_cp_to_check = CP_ACP; -static char g_lcid_to_check[8 + 1]; -static VARTYPE g_nil_to = VT_ERROR; -static IMessageFilterVtbl message_filter; -static IMessageFilter imessage_filter = { &message_filter }; -static IMessageFilter* previous_filter; - -#if defined(HAVE_TYPE_IMULTILANGUAGE2) -static IMultiLanguage2 *pIMultiLanguage = NULL; -#elif defined(HAVE_TYPE_IMULTILANGUAGE) -static IMultiLanguage *pIMultiLanguage = NULL; -#else -#define pIMultiLanguage NULL /* dummy */ -#endif - -struct oleparam { - DISPPARAMS dp; - OLECHAR** pNamedArgs; -}; - -static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); -static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This); -static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This); -static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *pctinfo); -static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo); -static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(IDispatch __RPC_FAR * This, REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId); -static HRESULT ( STDMETHODCALLTYPE Invoke )( IDispatch __RPC_FAR * This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr); -static IDispatch* val2dispatch(VALUE val); -static double rbtime2vtdate(VALUE tmobj); -static VALUE vtdate2rbtime(double date); -static rb_encoding *ole_cp2encoding(UINT cp); -static UINT ole_encoding2cp(rb_encoding *enc); -NORETURN(static void failed_load_conv51932(void)); -#ifndef pIMultiLanguage -static void load_conv_function51932(void); -#endif -static UINT ole_init_cp(void); -static void ole_freeexceptinfo(EXCEPINFO *pExInfo); -static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo); -static void ole_free(void *ptr); -static size_t ole_size(const void *ptr); -static LPWSTR ole_mb2wc(char *pm, int len, UINT cp); -static VALUE ole_ary_m_entry(VALUE val, LONG *pid); -static VALUE is_all_index_under(LONG *pid, long *pub, long dim); -static void * get_ptr_of_variant(VARIANT *pvar); -static void ole_set_safe_array(long n, SAFEARRAY *psa, LONG *pid, long *pub, VALUE val, long dim, VARTYPE vt); -static long dimension(VALUE val); -static long ary_len_of_dim(VALUE ary, long dim); -static VALUE ole_set_member(VALUE self, IDispatch *dispatch); -static VALUE fole_s_allocate(VALUE klass); -static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv); -static VALUE ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim); -static void ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val); -static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self); -static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid); -static VALUE ole_create_dcom(VALUE self, VALUE ole, VALUE host, VALUE others); -static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self); -static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self); -static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self); -static ULONG reference_count(struct oledata * pole); -static VALUE fole_s_reference_count(VALUE self, VALUE obj); -static VALUE fole_s_free(VALUE self, VALUE obj); -static HWND ole_show_help(VALUE helpfile, VALUE helpcontext); -static VALUE fole_s_show_help(int argc, VALUE *argv, VALUE self); -static VALUE fole_s_get_code_page(VALUE self); -static BOOL CALLBACK installed_code_page_proc(LPTSTR str); -static BOOL code_page_installed(UINT cp); -static VALUE fole_s_set_code_page(VALUE self, VALUE vcp); -static VALUE fole_s_get_locale(VALUE self); -static BOOL CALLBACK installed_lcid_proc(LPTSTR str); -static BOOL lcid_installed(LCID lcid); -static VALUE fole_s_set_locale(VALUE self, VALUE vlcid); -static VALUE fole_s_create_guid(VALUE self); -static VALUE fole_s_ole_initialize(VALUE self); -static VALUE fole_s_ole_uninitialize(VALUE self); -static VALUE fole_initialize(int argc, VALUE *argv, VALUE self); -static int hash2named_arg(VALUE key, VALUE val, VALUE pop); -static VALUE set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end); -static VALUE ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket); -static VALUE fole_invoke(int argc, VALUE *argv, VALUE self); -static VALUE ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind); -static VALUE fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types); -static VALUE fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types); -static VALUE fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types); -static VALUE fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self); -static VALUE fole_setproperty(int argc, VALUE *argv, VALUE self); -static VALUE fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self); -static VALUE ole_propertyput(VALUE self, VALUE property, VALUE value); -static VALUE fole_free(VALUE self); -static VALUE ole_each_sub(VALUE pEnumV); -static VALUE ole_ienum_free(VALUE pEnumV); -static VALUE fole_each(VALUE self); -static VALUE fole_missing(int argc, VALUE *argv, VALUE self); -static HRESULT typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti); -static VALUE ole_methods(VALUE self, int mask); -static VALUE fole_methods(VALUE self); -static VALUE fole_get_methods(VALUE self); -static VALUE fole_put_methods(VALUE self); -static VALUE fole_func_methods(VALUE self); -static VALUE fole_type(VALUE self); -static VALUE fole_typelib(VALUE self); -static VALUE fole_query_interface(VALUE self, VALUE str_iid); -static VALUE fole_respond_to(VALUE self, VALUE method); -static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); -static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); -static VALUE fole_method_help(VALUE self, VALUE cmdname); -static VALUE fole_activex_initialize(VALUE self); - -static void com_hash_free(void *ptr); -static void com_hash_mark(void *ptr); -static size_t com_hash_size(const void *ptr); -static void check_nano_server(void); - -static const rb_data_type_t ole_datatype = { - "win32ole", - {NULL, ole_free, ole_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static const rb_data_type_t win32ole_hash_datatype = { - "win32ole_hash", - {com_hash_mark, com_hash_free, com_hash_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)( - IMessageFilter __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) -{ - if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0 - || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0) - { - *ppvObject = &message_filter; - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG (STDMETHODCALLTYPE mf_AddRef)( - IMessageFilter __RPC_FAR * This) -{ - return 1; -} - -static ULONG (STDMETHODCALLTYPE mf_Release)( - IMessageFilter __RPC_FAR * This) -{ - return 1; -} - -static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)( - IMessageFilter __RPC_FAR * pThis, - DWORD dwCallType, //Type of incoming call - HTASK threadIDCaller, //Task handle calling this task - DWORD dwTickCount, //Elapsed tick count - LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure - ) -{ -#ifdef DEBUG_MESSAGEFILTER - printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount); - fflush(stdout); -#endif - switch (dwCallType) - { - case CALLTYPE_ASYNC: - case CALLTYPE_TOPLEVEL_CALLPENDING: - case CALLTYPE_ASYNC_CALLPENDING: - if (rb_during_gc()) { - return SERVERCALL_RETRYLATER; - } - break; - default: - break; - } - if (previous_filter) { - return previous_filter->lpVtbl->HandleInComingCall(previous_filter, - dwCallType, - threadIDCaller, - dwTickCount, - lpInterfaceInfo); - } - return SERVERCALL_ISHANDLED; -} - -static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)( - IMessageFilter* pThis, - HTASK threadIDCallee, //Server task handle - DWORD dwTickCount, //Elapsed tick count - DWORD dwRejectType //Returned rejection message - ) -{ - if (previous_filter) { - return previous_filter->lpVtbl->RetryRejectedCall(previous_filter, - threadIDCallee, - dwTickCount, - dwRejectType); - } - return 1000; -} - -static DWORD (STDMETHODCALLTYPE mf_MessagePending)( - IMessageFilter* pThis, - HTASK threadIDCallee, //Called applications task handle - DWORD dwTickCount, //Elapsed tick count - DWORD dwPendingType //Call type - ) -{ - if (rb_during_gc()) { - return PENDINGMSG_WAITNOPROCESS; - } - if (previous_filter) { - return previous_filter->lpVtbl->MessagePending(previous_filter, - threadIDCallee, - dwTickCount, - dwPendingType); - } - return PENDINGMSG_WAITNOPROCESS; -} - -typedef struct _Win32OLEIDispatch -{ - IDispatch dispatch; - ULONG refcount; - VALUE obj; -} Win32OLEIDispatch; - -static HRESULT ( STDMETHODCALLTYPE QueryInterface )( - IDispatch __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) -{ - if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0 - || MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0) - { - Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; - p->refcount++; - *ppvObject = This; - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG ( STDMETHODCALLTYPE AddRef )( - IDispatch __RPC_FAR * This) -{ - Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; - return ++(p->refcount); -} - -static ULONG ( STDMETHODCALLTYPE Release )( - IDispatch __RPC_FAR * This) -{ - Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; - ULONG u = --(p->refcount); - if (u == 0) { - st_data_t key = p->obj; - st_delete(DATA_PTR(com_hash), &key, 0); - free(p); - } - return u; -} - -static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )( - IDispatch __RPC_FAR * This, - /* [out] */ UINT __RPC_FAR *pctinfo) -{ - return E_NOTIMPL; -} - -static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )( - IDispatch __RPC_FAR * This, - /* [in] */ UINT iTInfo, - /* [in] */ LCID lcid, - /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) -{ - return E_NOTIMPL; -} - - -static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )( - IDispatch __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, - /* [in] */ UINT cNames, - /* [in] */ LCID lcid, - /* [size_is][out] */ DISPID __RPC_FAR *rgDispId) -{ - /* - Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; - */ - char* psz = ole_wc2mb(*rgszNames); // support only one method - ID nameid = rb_check_id_cstr(psz, (long)strlen(psz), cWIN32OLE_enc); - free(psz); - if ((ID)(DISPID)nameid != nameid) return E_NOINTERFACE; - *rgDispId = (DISPID)nameid; - return S_OK; -} - -static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )( - IDispatch __RPC_FAR * This, - /* [in] */ DISPID dispIdMember, - /* [in] */ REFIID riid, - /* [in] */ LCID lcid, - /* [in] */ WORD wFlags, - /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, - /* [out] */ VARIANT __RPC_FAR *pVarResult, - /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, - /* [out] */ UINT __RPC_FAR *puArgErr) -{ - VALUE v; - int i; - int args = pDispParams->cArgs; - Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; - VALUE* parg = ALLOCA_N(VALUE, args); - ID mid = (ID)dispIdMember; - for (i = 0; i < args; i++) { - *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]); - } - if (dispIdMember == DISPID_VALUE) { - if (wFlags == DISPATCH_METHOD) { - mid = rb_intern("call"); - } else if (wFlags & DISPATCH_PROPERTYGET) { - mid = rb_intern("value"); - } - } - v = rb_funcallv(p->obj, mid, args, parg); - ole_val2variant(v, pVarResult); - return S_OK; -} - -BOOL -ole_initialized(void) -{ - return g_ole_initialized; -} - -static IDispatch* -val2dispatch(VALUE val) -{ - struct st_table *tbl = DATA_PTR(com_hash); - Win32OLEIDispatch* pdisp; - st_data_t data; - if (st_lookup(tbl, val, &data)) { - pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG); - pdisp->refcount++; - } - else { - pdisp = ALLOC(Win32OLEIDispatch); - pdisp->dispatch.lpVtbl = &com_vtbl; - pdisp->refcount = 1; - pdisp->obj = val; - st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG); - } - return &pdisp->dispatch; -} - -static double -rbtime2vtdate(VALUE tmobj) -{ - SYSTEMTIME st; - double t; - double nsec; - - st.wYear = RB_FIX2INT(rb_funcall(tmobj, rb_intern("year"), 0)); - st.wMonth = RB_FIX2INT(rb_funcall(tmobj, rb_intern("month"), 0)); - st.wDay = RB_FIX2INT(rb_funcall(tmobj, rb_intern("mday"), 0)); - st.wHour = RB_FIX2INT(rb_funcall(tmobj, rb_intern("hour"), 0)); - st.wMinute = RB_FIX2INT(rb_funcall(tmobj, rb_intern("min"), 0)); - st.wSecond = RB_FIX2INT(rb_funcall(tmobj, rb_intern("sec"), 0)); - st.wMilliseconds = 0; - SystemTimeToVariantTime(&st, &t); - - /* - * Unfortunately SystemTimeToVariantTime function always ignores the - * wMilliseconds of SYSTEMTIME struct. - * So, we need to calculate milliseconds by ourselves. - */ - nsec = RB_FIX2INT(rb_funcall(tmobj, rb_intern("nsec"), 0)); - nsec /= 1000000.0; - nsec /= (24.0 * 3600.0); - nsec /= 1000; - return t + nsec; -} - -static VALUE -vtdate2rbtime(double date) -{ - SYSTEMTIME st; - VALUE v; - double msec; - double sec; - VariantTimeToSystemTime(date, &st); - v = rb_funcall(rb_cTime, rb_intern("new"), 6, - RB_INT2FIX(st.wYear), - RB_INT2FIX(st.wMonth), - RB_INT2FIX(st.wDay), - RB_INT2FIX(st.wHour), - RB_INT2FIX(st.wMinute), - RB_INT2FIX(st.wSecond)); - st.wYear = RB_FIX2INT(rb_funcall(v, rb_intern("year"), 0)); - st.wMonth = RB_FIX2INT(rb_funcall(v, rb_intern("month"), 0)); - st.wDay = RB_FIX2INT(rb_funcall(v, rb_intern("mday"), 0)); - st.wHour = RB_FIX2INT(rb_funcall(v, rb_intern("hour"), 0)); - st.wMinute = RB_FIX2INT(rb_funcall(v, rb_intern("min"), 0)); - st.wSecond = RB_FIX2INT(rb_funcall(v, rb_intern("sec"), 0)); - st.wMilliseconds = 0; - SystemTimeToVariantTime(&st, &sec); - /* - * Unfortunately VariantTimeToSystemTime always ignores the - * wMilliseconds of SYSTEMTIME struct(The wMilliseconds is 0). - * So, we need to calculate milliseconds by ourselves. - */ - msec = date - sec; - msec *= 24 * 60; - msec -= floor(msec); - msec *= 60; - if (msec >= 59) { - msec -= 60; - } - if (msec != 0) { - return rb_funcall(v, rb_intern("+"), 1, rb_float_new(msec)); - } - return v; -} - -#define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp - -static UINT ole_encoding2cp(rb_encoding *enc) -{ - /* - * Is there any better solution to convert - * Ruby encoding to Windows codepage??? - */ - ENC_MACHING_CP(enc, "Big5", 950); - ENC_MACHING_CP(enc, "CP51932", 51932); - ENC_MACHING_CP(enc, "CP850", 850); - ENC_MACHING_CP(enc, "CP852", 852); - ENC_MACHING_CP(enc, "CP855", 855); - ENC_MACHING_CP(enc, "CP949", 949); - ENC_MACHING_CP(enc, "EUC-JP", 20932); - ENC_MACHING_CP(enc, "EUC-KR", 51949); - ENC_MACHING_CP(enc, "EUC-TW", 51950); - ENC_MACHING_CP(enc, "GB18030", 54936); - ENC_MACHING_CP(enc, "GB2312", 20936); - ENC_MACHING_CP(enc, "GBK", 936); - ENC_MACHING_CP(enc, "IBM437", 437); - ENC_MACHING_CP(enc, "IBM720", 720); - ENC_MACHING_CP(enc, "IBM737", 737); - ENC_MACHING_CP(enc, "IBM775", 775); - ENC_MACHING_CP(enc, "IBM852", 852); - ENC_MACHING_CP(enc, "IBM855", 855); - ENC_MACHING_CP(enc, "IBM857", 857); - ENC_MACHING_CP(enc, "IBM860", 860); - ENC_MACHING_CP(enc, "IBM861", 861); - ENC_MACHING_CP(enc, "IBM862", 862); - ENC_MACHING_CP(enc, "IBM863", 863); - ENC_MACHING_CP(enc, "IBM864", 864); - ENC_MACHING_CP(enc, "IBM865", 865); - ENC_MACHING_CP(enc, "IBM866", 866); - ENC_MACHING_CP(enc, "IBM869", 869); - ENC_MACHING_CP(enc, "ISO-2022-JP", 50220); - ENC_MACHING_CP(enc, "ISO-8859-1", 28591); - ENC_MACHING_CP(enc, "ISO-8859-15", 28605); - ENC_MACHING_CP(enc, "ISO-8859-2", 28592); - ENC_MACHING_CP(enc, "ISO-8859-3", 28593); - ENC_MACHING_CP(enc, "ISO-8859-4", 28594); - ENC_MACHING_CP(enc, "ISO-8859-5", 28595); - ENC_MACHING_CP(enc, "ISO-8859-6", 28596); - ENC_MACHING_CP(enc, "ISO-8859-7", 28597); - ENC_MACHING_CP(enc, "ISO-8859-8", 28598); - ENC_MACHING_CP(enc, "ISO-8859-9", 28599); - ENC_MACHING_CP(enc, "KOI8-R", 20866); - ENC_MACHING_CP(enc, "KOI8-U", 21866); - ENC_MACHING_CP(enc, "Shift_JIS", 932); - ENC_MACHING_CP(enc, "UTF-16BE", 1201); - ENC_MACHING_CP(enc, "UTF-16LE", 1200); - ENC_MACHING_CP(enc, "UTF-7", 65000); - ENC_MACHING_CP(enc, "UTF-8", 65001); - ENC_MACHING_CP(enc, "Windows-1250", 1250); - ENC_MACHING_CP(enc, "Windows-1251", 1251); - ENC_MACHING_CP(enc, "Windows-1252", 1252); - ENC_MACHING_CP(enc, "Windows-1253", 1253); - ENC_MACHING_CP(enc, "Windows-1254", 1254); - ENC_MACHING_CP(enc, "Windows-1255", 1255); - ENC_MACHING_CP(enc, "Windows-1256", 1256); - ENC_MACHING_CP(enc, "Windows-1257", 1257); - ENC_MACHING_CP(enc, "Windows-1258", 1258); - ENC_MACHING_CP(enc, "Windows-31J", 932); - ENC_MACHING_CP(enc, "Windows-874", 874); - ENC_MACHING_CP(enc, "eucJP-ms", 20932); - return CP_ACP; -} - -static void -failed_load_conv51932(void) -{ - rb_raise(eWIN32OLERuntimeError, "fail to load convert function for CP51932"); -} - -#ifndef pIMultiLanguage -static void -load_conv_function51932(void) -{ - HRESULT hr = E_NOINTERFACE; - void *p; - if (!pIMultiLanguage) { -#if defined(HAVE_TYPE_IMULTILANGUAGE2) - hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, - &IID_IMultiLanguage2, &p); -#elif defined(HAVE_TYPE_IMULTILANGUAGE) - hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, - &IID_IMultiLanguage, &p); -#endif - if (FAILED(hr)) { - failed_load_conv51932(); - } - pIMultiLanguage = p; - } -} -#define need_conv_function51932() (load_conv_function51932(), 1) -#else -#define load_conv_function51932() failed_load_conv51932() -#define need_conv_function51932() (failed_load_conv51932(), 0) -#endif - -#define conv_51932(cp) ((cp) == 51932 && need_conv_function51932()) - -static void -set_ole_codepage(UINT cp) -{ - if (code_page_installed(cp)) { - cWIN32OLE_cp = cp; - } else { - switch(cp) { - case CP_ACP: - case CP_OEMCP: - case CP_MACCP: - case CP_THREAD_ACP: - case CP_SYMBOL: - case CP_UTF7: - case CP_UTF8: - cWIN32OLE_cp = cp; - break; - case 51932: - cWIN32OLE_cp = cp; - load_conv_function51932(); - break; - default: - rb_raise(eWIN32OLERuntimeError, "codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage."); - break; - } - } - cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp); -} - - -static UINT -ole_init_cp(void) -{ - UINT cp; - rb_encoding *encdef; - encdef = rb_default_internal_encoding(); - if (!encdef) { - encdef = rb_default_external_encoding(); - } - cp = ole_encoding2cp(encdef); - set_ole_codepage(cp); - return cp; -} - -struct myCPINFOEX { - UINT MaxCharSize; - BYTE DefaultChar[2]; - BYTE LeadByte[12]; - WCHAR UnicodeDefaultChar; - UINT CodePage; - char CodePageName[MAX_PATH]; -}; - -static rb_encoding * -ole_cp2encoding(UINT cp) -{ - static BOOL (*pGetCPInfoEx)(UINT, DWORD, struct myCPINFOEX *) = NULL; - struct myCPINFOEX* buf; - VALUE enc_name; - char *enc_cstr; - int idx; - - if (!code_page_installed(cp)) { - switch(cp) { - case CP_ACP: - cp = GetACP(); - break; - case CP_OEMCP: - cp = GetOEMCP(); - break; - case CP_MACCP: - case CP_THREAD_ACP: - if (!pGetCPInfoEx) { - pGetCPInfoEx = (BOOL (*)(UINT, DWORD, struct myCPINFOEX *)) - GetProcAddress(GetModuleHandle("kernel32"), "GetCPInfoEx"); - if (!pGetCPInfoEx) { - pGetCPInfoEx = (void*)-1; - } - } - buf = ALLOCA_N(struct myCPINFOEX, 1); - ZeroMemory(buf, sizeof(struct myCPINFOEX)); - if (pGetCPInfoEx == (void*)-1 || !pGetCPInfoEx(cp, 0, buf)) { - rb_raise(eWIN32OLERuntimeError, "cannot map codepage to encoding."); - break; /* never reach here */ - } - cp = buf->CodePage; - break; - case CP_SYMBOL: - case CP_UTF7: - case CP_UTF8: - break; - case 51932: - load_conv_function51932(); - break; - default: - rb_raise(eWIN32OLERuntimeError, "codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage."); - break; - } - } - - enc_name = rb_sprintf("CP%d", cp); - idx = rb_enc_find_index(enc_cstr = StringValueCStr(enc_name)); - if (idx < 0) - idx = rb_define_dummy_encoding(enc_cstr); - return rb_enc_from_index(idx); -} - -#ifndef pIMultiLanguage -static HRESULT -ole_ml_wc2mb_conv0(LPWSTR pw, LPSTR pm, UINT *size) -{ - DWORD dw = 0; - return pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage, - &dw, cWIN32OLE_cp, pw, NULL, pm, size); -} -#define ole_ml_wc2mb_conv(pw, pm, size, onfailure) do { \ - HRESULT hr = ole_ml_wc2mb_conv0(pw, pm, &size); \ - if (FAILED(hr)) { \ - onfailure; \ - ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp); \ - } \ - } while (0) -#endif - -#define ole_wc2mb_conv(pw, pm, size) WideCharToMultiByte(cWIN32OLE_cp, 0, (pw), -1, (pm), (size), NULL, NULL) - -static char * -ole_wc2mb_alloc(LPWSTR pw, char *(alloc)(UINT size, void *arg), void *arg) -{ - LPSTR pm; - UINT size = 0; - if (conv_51932(cWIN32OLE_cp)) { -#ifndef pIMultiLanguage - ole_ml_wc2mb_conv(pw, NULL, size, {}); - pm = alloc(size, arg); - if (size) ole_ml_wc2mb_conv(pw, pm, size, xfree(pm)); - pm[size] = '\0'; - return pm; -#endif - } - size = ole_wc2mb_conv(pw, NULL, 0); - pm = alloc(size, arg); - if (size) ole_wc2mb_conv(pw, pm, size); - pm[size] = '\0'; - return pm; -} - -static char * -ole_alloc_str(UINT size, void *arg) -{ - return ALLOC_N(char, size + 1); -} - -char * -ole_wc2mb(LPWSTR pw) -{ - return ole_wc2mb_alloc(pw, ole_alloc_str, NULL); -} - -static void -ole_freeexceptinfo(EXCEPINFO *pExInfo) -{ - SysFreeString(pExInfo->bstrDescription); - SysFreeString(pExInfo->bstrSource); - SysFreeString(pExInfo->bstrHelpFile); -} - -static VALUE -ole_excepinfo2msg(EXCEPINFO *pExInfo) -{ - char error_code[40]; - char *pSource = NULL; - char *pDescription = NULL; - VALUE error_msg; - if(pExInfo->pfnDeferredFillIn != NULL) { - (*pExInfo->pfnDeferredFillIn)(pExInfo); - } - if (pExInfo->bstrSource != NULL) { - pSource = ole_wc2mb(pExInfo->bstrSource); - } - if (pExInfo->bstrDescription != NULL) { - pDescription = ole_wc2mb(pExInfo->bstrDescription); - } - if(pExInfo->wCode == 0) { - sprintf(error_code, "\n OLE error code:%lX in ", (unsigned long)pExInfo->scode); - } - else{ - sprintf(error_code, "\n OLE error code:%u in ", pExInfo->wCode); - } - error_msg = rb_str_new2(error_code); - if(pSource != NULL) { - rb_str_cat2(error_msg, pSource); - } - else { - rb_str_cat(error_msg, "<Unknown>", 9); - } - rb_str_cat2(error_msg, "\n "); - if(pDescription != NULL) { - rb_str_cat2(error_msg, pDescription); - } - else { - rb_str_cat2(error_msg, "<No Description>"); - } - if(pSource) free(pSource); - if(pDescription) free(pDescription); - ole_freeexceptinfo(pExInfo); - return error_msg; -} - -void -ole_uninitialize(void) -{ - if (!g_ole_initialized) return; - OleUninitialize(); - g_ole_initialized_set(FALSE); -} - -static void -ole_uninitialize_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass) -{ - ole_uninitialize(); -} - -void -ole_initialize(void) -{ - HRESULT hr; - - if(!g_uninitialize_hooked) { - rb_add_event_hook(ole_uninitialize_hook, RUBY_EVENT_THREAD_END, Qnil); - g_uninitialize_hooked = TRUE; - } - - if(g_ole_initialized == FALSE) { - if(g_running_nano) { - hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - } else { - hr = OleInitialize(NULL); - } - if(FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize"); - } - g_ole_initialized_set(TRUE); - - if (g_running_nano == FALSE) { - hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter); - if(FAILED(hr)) { - previous_filter = NULL; - ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter"); - } - } - } -} - -static void -ole_free(void *ptr) -{ - struct oledata *pole = ptr; - OLE_FREE(pole->pDispatch); - free(pole); -} - -static size_t ole_size(const void *ptr) -{ - return ptr ? sizeof(struct oledata) : 0; -} - -struct oledata * -oledata_get_struct(VALUE ole) -{ - struct oledata *pole; - TypedData_Get_Struct(ole, struct oledata, &ole_datatype, pole); - return pole; -} - -LPWSTR -ole_vstr2wc(VALUE vstr) -{ - rb_encoding *enc; - int cp; - LPWSTR pw; - st_data_t data; - struct st_table *tbl = DATA_PTR(enc2cp_hash); - - /* do not type-conversion here to prevent from other arguments - * changing (if exist) */ - Check_Type(vstr, T_STRING); - if (RSTRING_LEN(vstr) == 0) { - return NULL; - } - - enc = rb_enc_get(vstr); - - if (st_lookup(tbl, (VALUE)enc | FIXNUM_FLAG, &data)) { - cp = RB_FIX2INT((VALUE)data); - } else { - cp = ole_encoding2cp(enc); - if (code_page_installed(cp) || - cp == CP_ACP || - cp == CP_OEMCP || - cp == CP_MACCP || - cp == CP_THREAD_ACP || - cp == CP_SYMBOL || - cp == CP_UTF7 || - cp == CP_UTF8 || - cp == 51932) { - st_insert(tbl, (VALUE)enc | FIXNUM_FLAG, RB_INT2FIX(cp)); - } else { - rb_raise(eWIN32OLERuntimeError, "not installed Windows codepage(%d) according to `%s'", cp, rb_enc_name(enc)); - } - } - pw = ole_mb2wc(RSTRING_PTR(vstr), RSTRING_LENINT(vstr), cp); - RB_GC_GUARD(vstr); - return pw; -} - -static LPWSTR -ole_mb2wc(char *pm, int len, UINT cp) -{ - UINT size = 0; - LPWSTR pw; - - if (conv_51932(cp)) { -#ifndef pIMultiLanguage - DWORD dw = 0; - UINT n = len; - HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage, - &dw, cp, pm, &n, NULL, &size); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp); - } - pw = SysAllocStringLen(NULL, size); - n = len; - hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage, - &dw, cp, pm, &n, pw, &size); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp); - } - return pw; -#endif - } - size = MultiByteToWideChar(cp, 0, pm, len, NULL, 0); - pw = SysAllocStringLen(NULL, size); - pw[size-1] = 0; - MultiByteToWideChar(cp, 0, pm, len, pw, size); - return pw; -} - -static char * -ole_alloc_vstr(UINT size, void *arg) -{ - VALUE str = rb_enc_str_new(NULL, size, cWIN32OLE_enc); - *(VALUE *)arg = str; - return RSTRING_PTR(str); -} - -VALUE -ole_wc2vstr(LPWSTR pw, BOOL isfree) -{ - VALUE vstr; - ole_wc2mb_alloc(pw, ole_alloc_vstr, &vstr); - rb_str_set_len(vstr, (long)strlen(RSTRING_PTR(vstr))); - if(isfree) - SysFreeString(pw); - return vstr; -} - -static VALUE -ole_ary_m_entry(VALUE val, LONG *pid) -{ - VALUE obj = Qnil; - int i = 0; - obj = val; - while(RB_TYPE_P(obj, T_ARRAY)) { - obj = rb_ary_entry(obj, pid[i]); - i++; - } - return obj; -} - -static VALUE -is_all_index_under(LONG *pid, long *pub, long dim) -{ - long i = 0; - for (i = 0; i < dim; i++) { - if (pid[i] > pub[i]) { - return Qfalse; - } - } - return Qtrue; -} - -void -ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt) -{ - if (val == Qnil) { - if (vt == VT_VARIANT) { - ole_val2variant2(val, var); - } else { - V_VT(var) = (vt & ~VT_BYREF); - if (V_VT(var) == VT_DISPATCH) { - V_DISPATCH(var) = NULL; - } else if (V_VT(var) == VT_UNKNOWN) { - V_UNKNOWN(var) = NULL; - } - } - return; - } -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - switch(vt & ~VT_BYREF) { - case VT_I8: - V_VT(var) = VT_I8; - V_I8(var) = NUM2I8 (val); - break; - case VT_UI8: - V_VT(var) = VT_UI8; - V_UI8(var) = NUM2UI8(val); - break; - default: - ole_val2variant2(val, var); - break; - } -#else /* (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) */ - ole_val2variant2(val, var); -#endif -} - -VOID * -val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt) -{ - VOID *p = NULL; - HRESULT hr = S_OK; - ole_val2variant_ex(val, var, vt); - if ((vt & ~VT_BYREF) == VT_VARIANT) { - p = var; - } else { - if ( (vt & ~VT_BYREF) != V_VT(var)) { - hr = VariantChangeTypeEx(var, var, - cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF)); - if (FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "failed to change type"); - } - } - p = get_ptr_of_variant(var); - } - if (p == NULL) { - rb_raise(rb_eRuntimeError, "failed to get pointer of variant"); - } - return p; -} - -static void * -get_ptr_of_variant(VARIANT *pvar) -{ - switch(V_VT(pvar)) { - case VT_UI1: - return &V_UI1(pvar); - break; - case VT_I2: - return &V_I2(pvar); - break; - case VT_UI2: - return &V_UI2(pvar); - break; - case VT_I4: - return &V_I4(pvar); - break; - case VT_UI4: - return &V_UI4(pvar); - break; - case VT_R4: - return &V_R4(pvar); - break; - case VT_R8: - return &V_R8(pvar); - break; -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - case VT_I8: - return &V_I8(pvar); - break; - case VT_UI8: - return &V_UI8(pvar); - break; -#endif - case VT_INT: - return &V_INT(pvar); - break; - case VT_UINT: - return &V_UINT(pvar); - break; - case VT_CY: - return &V_CY(pvar); - break; - case VT_DATE: - return &V_DATE(pvar); - break; - case VT_BSTR: - return V_BSTR(pvar); - break; - case VT_DISPATCH: - return V_DISPATCH(pvar); - break; - case VT_ERROR: - return &V_ERROR(pvar); - break; - case VT_BOOL: - return &V_BOOL(pvar); - break; - case VT_UNKNOWN: - return V_UNKNOWN(pvar); - break; - case VT_ARRAY: - return &V_ARRAY(pvar); - break; - default: - return NULL; - break; - } -} - -static void -ole_set_safe_array(long n, SAFEARRAY *psa, LONG *pid, long *pub, VALUE val, long dim, VARTYPE vt) -{ - VALUE val1; - HRESULT hr = S_OK; - VARIANT var; - VOID *p = NULL; - long i = n; - while(i >= 0) { - val1 = ole_ary_m_entry(val, pid); - VariantInit(&var); - p = val2variant_ptr(val1, &var, vt); - if (is_all_index_under(pid, pub, dim) == Qtrue) { - if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) || - (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) { - rb_raise(eWIN32OLERuntimeError, "element of array does not have IDispatch or IUnknown Interface"); - } - hr = SafeArrayPutElement(psa, pid, p); - } - if (FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayPutElement"); - } - pid[i] += 1; - if (pid[i] > pub[i]) { - pid[i] = 0; - i -= 1; - } else { - i = dim - 1; - } - } -} - -static long -dimension(VALUE val) { - long dim = 0; - long dim1 = 0; - long len = 0; - long i = 0; - if (RB_TYPE_P(val, T_ARRAY)) { - len = RARRAY_LEN(val); - for (i = 0; i < len; i++) { - dim1 = dimension(rb_ary_entry(val, i)); - if (dim < dim1) { - dim = dim1; - } - } - dim += 1; - } - return dim; -} - -static long -ary_len_of_dim(VALUE ary, long dim) { - long ary_len = 0; - long ary_len1 = 0; - long len = 0; - long i = 0; - VALUE val; - if (dim == 0) { - if (RB_TYPE_P(ary, T_ARRAY)) { - ary_len = RARRAY_LEN(ary); - } - } else { - if (RB_TYPE_P(ary, T_ARRAY)) { - len = RARRAY_LEN(ary); - for (i = 0; i < len; i++) { - val = rb_ary_entry(ary, i); - ary_len1 = ary_len_of_dim(val, dim-1); - if (ary_len < ary_len1) { - ary_len = ary_len1; - } - } - } - } - return ary_len; -} - -HRESULT -ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt) -{ - long dim = 0; - int i = 0; - HRESULT hr = S_OK; - - SAFEARRAYBOUND *psab = NULL; - SAFEARRAY *psa = NULL; - long *pub; - LONG *pid; - - Check_Type(val, T_ARRAY); - - dim = dimension(val); - - psab = ALLOC_N(SAFEARRAYBOUND, dim); - pub = ALLOC_N(long, dim); - pid = ALLOC_N(LONG, dim); - - if(!psab || !pub || !pid) { - if(pub) free(pub); - if(psab) free(psab); - if(pid) free(pid); - rb_raise(rb_eRuntimeError, "memory allocation error"); - } - - for (i = 0; i < dim; i++) { - psab[i].cElements = ary_len_of_dim(val, i); - psab[i].lLbound = 0; - pub[i] = psab[i].cElements - 1; - pid[i] = 0; - } - /* Create and fill VARIANT array */ - if ((vt & ~VT_BYREF) == VT_ARRAY) { - vt = (vt | VT_VARIANT); - } - psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab); - if (psa == NULL) - hr = E_OUTOFMEMORY; - else - hr = SafeArrayLock(psa); - if (SUCCEEDED(hr)) { - ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK)); - hr = SafeArrayUnlock(psa); - } - - if(pub) free(pub); - if(psab) free(psab); - if(pid) free(pid); - - if (SUCCEEDED(hr)) { - V_VT(var) = vt; - V_ARRAY(var) = psa; - } - else { - if (psa != NULL) - SafeArrayDestroy(psa); - } - return hr; -} - -void -ole_val2variant(VALUE val, VARIANT *var) -{ - struct oledata *pole = NULL; - if(rb_obj_is_kind_of(val, cWIN32OLE)) { - pole = oledata_get_struct(val); - OLE_ADDREF(pole->pDispatch); - V_VT(var) = VT_DISPATCH; - V_DISPATCH(var) = pole->pDispatch; - return; - } - if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) { - ole_variant2variant(val, var); - return; - } - if (rb_obj_is_kind_of(val, cWIN32OLE_RECORD)) { - ole_rec2variant(val, var); - return; - } - if (rb_obj_is_kind_of(val, rb_cTime)) { - V_VT(var) = VT_DATE; - V_DATE(var) = rbtime2vtdate(val); - return; - } - switch (TYPE(val)) { - case T_ARRAY: - ole_val_ary2variant_ary(val, var, VT_VARIANT|VT_ARRAY); - break; - case T_STRING: - V_VT(var) = VT_BSTR; - V_BSTR(var) = ole_vstr2wc(val); - break; - case T_FIXNUM: - V_VT(var) = VT_I4; - { - long v = RB_NUM2LONG(val); - V_I4(var) = (LONG)v; -#if SIZEOF_LONG > 4 - if (V_I4(var) != v) { - V_I8(var) = v; - V_VT(var) = VT_I8; - } -#endif - } - break; - case T_BIGNUM: - V_VT(var) = VT_R8; - V_R8(var) = rb_big2dbl(val); - break; - case T_FLOAT: - V_VT(var) = VT_R8; - V_R8(var) = NUM2DBL(val); - break; - case T_TRUE: - V_VT(var) = VT_BOOL; - V_BOOL(var) = VARIANT_TRUE; - break; - case T_FALSE: - V_VT(var) = VT_BOOL; - V_BOOL(var) = VARIANT_FALSE; - break; - case T_NIL: - if (g_nil_to == VT_ERROR) { - V_VT(var) = VT_ERROR; - V_ERROR(var) = DISP_E_PARAMNOTFOUND; - }else { - V_VT(var) = VT_EMPTY; - } - break; - default: - V_VT(var) = VT_DISPATCH; - V_DISPATCH(var) = val2dispatch(val); - break; - } -} - -void -ole_val2variant2(VALUE val, VARIANT *var) -{ - g_nil_to = VT_EMPTY; - ole_val2variant(val, var); - g_nil_to = VT_ERROR; -} - -VALUE -make_inspect(const char *class_name, VALUE detail) -{ - VALUE str; - str = rb_str_new2("#<"); - rb_str_cat2(str, class_name); - rb_str_cat2(str, ":"); - rb_str_concat(str, detail); - rb_str_cat2(str, ">"); - return str; -} - -VALUE -default_inspect(VALUE self, const char *class_name) -{ - VALUE detail = rb_funcall(self, rb_intern("to_s"), 0); - return make_inspect(class_name, detail); -} - -static VALUE -ole_set_member(VALUE self, IDispatch *dispatch) -{ - struct oledata *pole = NULL; - pole = oledata_get_struct(self); - if (pole->pDispatch) { - OLE_RELEASE(pole->pDispatch); - pole->pDispatch = NULL; - } - pole->pDispatch = dispatch; - return self; -} - - -static VALUE -fole_s_allocate(VALUE klass) -{ - struct oledata *pole; - VALUE obj; - ole_initialize(); - obj = TypedData_Make_Struct(klass, struct oledata, &ole_datatype, pole); - pole->pDispatch = NULL; - return obj; -} - -static VALUE -create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv) -{ - VALUE obj = fole_s_allocate(klass); - ole_set_member(obj, pDispatch); - return obj; -} - -static VALUE -ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim) { - long i; - VALUE obj = Qnil; - VALUE pobj = Qnil; - long *ids = ALLOC_N(long, dim); - if (!ids) { - rb_raise(rb_eRuntimeError, "memory allocation error"); - } - for(i = 0; i < dim; i++) { - ids[i] = pid[i] - plb[i]; - } - obj = myary; - pobj = myary; - for(i = 0; i < dim-1; i++) { - obj = rb_ary_entry(pobj, ids[i]); - if (obj == Qnil) { - rb_ary_store(pobj, ids[i], rb_ary_new()); - } - obj = rb_ary_entry(pobj, ids[i]); - pobj = obj; - } - if (ids) free(ids); - return obj; -} - -static void -ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val) { - long id = pid[dim - 1] - plb[dim - 1]; - VALUE obj = ary_new_dim(myary, pid, plb, dim); - rb_ary_store(obj, id, val); -} - -VALUE -ole_variant2val(VARIANT *pvar) -{ - VALUE obj = Qnil; - VARTYPE vt = V_VT(pvar); - HRESULT hr; - while ( vt == (VT_BYREF | VT_VARIANT) ) { - pvar = V_VARIANTREF(pvar); - vt = V_VT(pvar); - } - - if(V_ISARRAY(pvar)) { - VARTYPE vt_base = vt & VT_TYPEMASK; - SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar); - UINT i = 0; - LONG *pid, *plb, *pub; - VARIANT variant; - VALUE val; - UINT dim = 0; - if (!psa) { - return obj; - } - dim = SafeArrayGetDim(psa); - pid = ALLOC_N(LONG, dim); - plb = ALLOC_N(LONG, dim); - pub = ALLOC_N(LONG, dim); - - if(!pid || !plb || !pub) { - if(pid) free(pid); - if(plb) free(plb); - if(pub) free(pub); - rb_raise(rb_eRuntimeError, "memory allocation error"); - } - - for(i = 0; i < dim; ++i) { - SafeArrayGetLBound(psa, i+1, &plb[i]); - SafeArrayGetLBound(psa, i+1, &pid[i]); - SafeArrayGetUBound(psa, i+1, &pub[i]); - } - hr = SafeArrayLock(psa); - if (SUCCEEDED(hr)) { - obj = rb_ary_new(); - i = 0; - VariantInit(&variant); - V_VT(&variant) = vt_base | VT_BYREF; - if (vt_base == VT_RECORD) { - hr = SafeArrayGetRecordInfo(psa, &V_RECORDINFO(&variant)); - if (SUCCEEDED(hr)) { - V_VT(&variant) = VT_RECORD; - } - } - while (i < dim) { - ary_new_dim(obj, pid, plb, dim); - if (vt_base == VT_RECORD) - hr = SafeArrayPtrOfIndex(psa, pid, &V_RECORD(&variant)); - else - hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant)); - if (SUCCEEDED(hr)) { - val = ole_variant2val(&variant); - ary_store_dim(obj, pid, plb, dim, val); - } - for (i = 0; i < dim; ++i) { - if (++pid[i] <= pub[i]) - break; - pid[i] = plb[i]; - } - } - SafeArrayUnlock(psa); - } - if(pid) free(pid); - if(plb) free(plb); - if(pub) free(pub); - return obj; - } - switch(V_VT(pvar) & ~VT_BYREF){ - case VT_EMPTY: - break; - case VT_NULL: - break; - case VT_I1: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_I1REF(pvar)); - else - obj = RB_INT2NUM((long)V_I1(pvar)); - break; - - case VT_UI1: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_UI1REF(pvar)); - else - obj = RB_INT2NUM((long)V_UI1(pvar)); - break; - - case VT_I2: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_I2REF(pvar)); - else - obj = RB_INT2NUM((long)V_I2(pvar)); - break; - - case VT_UI2: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_UI2REF(pvar)); - else - obj = RB_INT2NUM((long)V_UI2(pvar)); - break; - - case VT_I4: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_I4REF(pvar)); - else - obj = RB_INT2NUM((long)V_I4(pvar)); - break; - - case VT_UI4: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_UI4REF(pvar)); - else - obj = RB_INT2NUM((long)V_UI4(pvar)); - break; - - case VT_INT: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_INTREF(pvar)); - else - obj = RB_INT2NUM((long)V_INT(pvar)); - break; - - case VT_UINT: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM((long)*V_UINTREF(pvar)); - else - obj = RB_INT2NUM((long)V_UINT(pvar)); - break; - -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - case VT_I8: - if(V_ISBYREF(pvar)) -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) -#ifdef V_I8REF - obj = I8_2_NUM(*V_I8REF(pvar)); -#endif -#else - obj = Qnil; -#endif - else - obj = I8_2_NUM(V_I8(pvar)); - break; - case VT_UI8: - if(V_ISBYREF(pvar)) -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) -#ifdef V_UI8REF - obj = UI8_2_NUM(*V_UI8REF(pvar)); -#endif -#else - obj = Qnil; -#endif - else - obj = UI8_2_NUM(V_UI8(pvar)); - break; -#endif /* (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) */ - - case VT_R4: - if(V_ISBYREF(pvar)) - obj = rb_float_new(*V_R4REF(pvar)); - else - obj = rb_float_new(V_R4(pvar)); - break; - - case VT_R8: - if(V_ISBYREF(pvar)) - obj = rb_float_new(*V_R8REF(pvar)); - else - obj = rb_float_new(V_R8(pvar)); - break; - - case VT_BSTR: - { - BSTR bstr; - if(V_ISBYREF(pvar)) - bstr = *V_BSTRREF(pvar); - else - bstr = V_BSTR(pvar); - obj = (SysStringLen(bstr) == 0) - ? rb_str_new2("") - : ole_wc2vstr(bstr, FALSE); - break; - } - - case VT_ERROR: - if(V_ISBYREF(pvar)) - obj = RB_INT2NUM(*V_ERRORREF(pvar)); - else - obj = RB_INT2NUM(V_ERROR(pvar)); - break; - - case VT_BOOL: - if (V_ISBYREF(pvar)) - obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse); - else - obj = (V_BOOL(pvar) ? Qtrue : Qfalse); - break; - - case VT_DISPATCH: - { - IDispatch *pDispatch; - - if (V_ISBYREF(pvar)) - pDispatch = *V_DISPATCHREF(pvar); - else - pDispatch = V_DISPATCH(pvar); - - if (pDispatch != NULL ) { - OLE_ADDREF(pDispatch); - obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0); - } - break; - } - - case VT_UNKNOWN: - { - /* get IDispatch interface from IUnknown interface */ - IUnknown *punk; - IDispatch *pDispatch; - void *p; - HRESULT hr; - - if (V_ISBYREF(pvar)) - punk = *V_UNKNOWNREF(pvar); - else - punk = V_UNKNOWN(pvar); - - if(punk != NULL) { - hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p); - if(SUCCEEDED(hr)) { - pDispatch = p; - obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0); - } - } - break; - } - - case VT_DATE: - { - DATE date; - if(V_ISBYREF(pvar)) - date = *V_DATEREF(pvar); - else - date = V_DATE(pvar); - - obj = vtdate2rbtime(date); - break; - } - - case VT_RECORD: - { - IRecordInfo *pri = V_RECORDINFO(pvar); - void *prec = V_RECORD(pvar); - obj = create_win32ole_record(pri, prec); - break; - } - - case VT_CY: - default: - { - HRESULT hr; - VARIANT variant; - VariantInit(&variant); - hr = VariantChangeTypeEx(&variant, pvar, - cWIN32OLE_lcid, 0, VT_BSTR); - if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) { - obj = ole_wc2vstr(V_BSTR(&variant), FALSE); - } - VariantClear(&variant); - break; - } - } - return obj; -} - -LONG -reg_open_key(HKEY hkey, const char *name, HKEY *phkey) -{ - return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey); -} - -LONG -reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey) -{ - return reg_open_key(hkey, StringValuePtr(key), phkey); -} - -VALUE -reg_enum_key(HKEY hkey, DWORD i) -{ - char buf[BUFSIZ + 1]; - DWORD size_buf = sizeof(buf); - FILETIME ft; - LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf, - NULL, NULL, NULL, &ft); - if(err == ERROR_SUCCESS) { - buf[BUFSIZ] = '\0'; - return rb_str_new2(buf); - } - return Qnil; -} - -VALUE -reg_get_val(HKEY hkey, const char *subkey) -{ - char *pbuf; - DWORD dwtype = 0; - DWORD size = 0; - VALUE val = Qnil; - LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size); - - if (err == ERROR_SUCCESS) { - pbuf = ALLOC_N(char, size + 1); - err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, (BYTE *)pbuf, &size); - if (err == ERROR_SUCCESS) { - pbuf[size] = '\0'; - if (dwtype == REG_EXPAND_SZ) { - char* pbuf2 = (char *)pbuf; - DWORD len = ExpandEnvironmentStrings(pbuf2, NULL, 0); - pbuf = ALLOC_N(char, len + 1); - ExpandEnvironmentStrings(pbuf2, pbuf, len + 1); - free(pbuf2); - } - val = rb_str_new2((char *)pbuf); - } - free(pbuf); - } - return val; -} - -VALUE -reg_get_val2(HKEY hkey, const char *subkey) -{ - HKEY hsubkey; - LONG err; - VALUE val = Qnil; - err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey); - if (err == ERROR_SUCCESS) { - val = reg_get_val(hsubkey, NULL); - RegCloseKey(hsubkey); - } - if (val == Qnil) { - val = reg_get_val(hkey, subkey); - } - return val; -} - -static void -ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self) -{ - unsigned int count; - unsigned int index; - int iVar; - ITypeInfo *pTypeInfo; - TYPEATTR *pTypeAttr; - VARDESC *pVarDesc; - HRESULT hr; - unsigned int len; - BSTR bstr; - char *pName = NULL; - VALUE val; - VALUE constant; - ID id; - constant = rb_hash_new(); - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (index = 0; index < count; index++) { - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo); - if (FAILED(hr)) - continue; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if(FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - continue; - } - for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) { - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc); - if(FAILED(hr)) - continue; - if(pVarDesc->varkind == VAR_CONST && - !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN | - VARFLAG_FRESTRICTED | - VARFLAG_FNONBROWSABLE))) { - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr, - 1, &len); - if(FAILED(hr) || len == 0 || !bstr) - continue; - pName = ole_wc2mb(bstr); - val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue)); - *pName = toupper((int)*pName); - id = rb_intern(pName); - if (rb_is_const_id(id)) { - if(!rb_const_defined_at(klass, id)) { - rb_define_const(klass, pName, val); - } - } - else { - rb_hash_aset(constant, rb_str_new2(pName), val); - } - SysFreeString(bstr); - if(pName) { - free(pName); - pName = NULL; - } - } - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - } - pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr); - OLE_RELEASE(pTypeInfo); - } - rb_define_const(klass, "CONSTANTS", constant); -} - -static HRESULT -clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid) -{ - HKEY hlm; - HKEY hpid; - VALUE subkey; - LONG err; - char clsid[100]; - OLECHAR *pbuf; - DWORD len; - DWORD dwtype; - HRESULT hr = S_OK; - err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm); - if (err != ERROR_SUCCESS) - return HRESULT_FROM_WIN32(err); - subkey = rb_str_new2("SOFTWARE\\Classes\\"); - rb_str_concat(subkey, com); - rb_str_cat2(subkey, "\\CLSID"); - err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid); - if (err != ERROR_SUCCESS) - hr = HRESULT_FROM_WIN32(err); - else { - len = sizeof(clsid); - err = RegQueryValueEx(hpid, "", NULL, &dwtype, (BYTE *)clsid, &len); - if (err == ERROR_SUCCESS && dwtype == REG_SZ) { - pbuf = ole_mb2wc(clsid, -1, cWIN32OLE_cp); - hr = CLSIDFromString(pbuf, pclsid); - SysFreeString(pbuf); - } - else { - hr = HRESULT_FROM_WIN32(err); - } - RegCloseKey(hpid); - } - RegCloseKey(hlm); - return hr; -} - -static VALUE -ole_create_dcom(VALUE self, VALUE ole, VALUE host, VALUE others) -{ - HRESULT hr; - CLSID clsid; - OLECHAR *pbuf; - - COSERVERINFO serverinfo; - MULTI_QI multi_qi; - DWORD clsctx = CLSCTX_REMOTE_SERVER; - - if (!gole32) - gole32 = LoadLibrary("OLE32"); - if (!gole32) - rb_raise(rb_eRuntimeError, "failed to load OLE32"); - if (!gCoCreateInstanceEx) - gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*) - GetProcAddress(gole32, "CoCreateInstanceEx"); - if (!gCoCreateInstanceEx) - rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment"); - - pbuf = ole_vstr2wc(ole); - hr = CLSIDFromProgID(pbuf, &clsid); - if (FAILED(hr)) - hr = clsid_from_remote(host, ole, &clsid); - if (FAILED(hr)) - hr = CLSIDFromString(pbuf, &clsid); - SysFreeString(pbuf); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, - "unknown OLE server: `%s'", - StringValuePtr(ole)); - memset(&serverinfo, 0, sizeof(COSERVERINFO)); - serverinfo.pwszName = ole_vstr2wc(host); - memset(&multi_qi, 0, sizeof(MULTI_QI)); - multi_qi.pIID = &IID_IDispatch; - hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi); - SysFreeString(serverinfo.pwszName); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, - "failed to create DCOM server `%s' in `%s'", - StringValuePtr(ole), - StringValuePtr(host)); - - ole_set_member(self, (IDispatch*)multi_qi.pItf); - return self; -} - -static VALUE -ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self) -{ - IBindCtx *pBindCtx; - IMoniker *pMoniker; - IDispatch *pDispatch; - void *p; - HRESULT hr; - OLECHAR *pbuf; - ULONG eaten = 0; - - ole_initialize(); - - hr = CreateBindCtx(0, &pBindCtx); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "failed to create bind context"); - } - - pbuf = ole_vstr2wc(moniker); - hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker); - SysFreeString(pbuf); - if(FAILED(hr)) { - OLE_RELEASE(pBindCtx); - ole_raise(hr, eWIN32OLERuntimeError, - "failed to parse display name of moniker `%s'", - StringValuePtr(moniker)); - } - hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL, - &IID_IDispatch, &p); - pDispatch = p; - OLE_RELEASE(pMoniker); - OLE_RELEASE(pBindCtx); - - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "failed to bind moniker `%s'", - StringValuePtr(moniker)); - } - return create_win32ole_object(self, pDispatch, argc, argv); -} - -/* - * call-seq: - * WIN32OLE.connect( ole ) --> aWIN32OLE - * - * Returns running OLE Automation object or WIN32OLE object from moniker. - * 1st argument should be OLE program id or class id or moniker. - * - * WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel. - */ -static VALUE -fole_s_connect(int argc, VALUE *argv, VALUE self) -{ - VALUE svr_name; - VALUE others; - HRESULT hr; - CLSID clsid; - OLECHAR *pBuf; - IDispatch *pDispatch; - void *p; - IUnknown *pUnknown; - - /* initialize to use OLE */ - ole_initialize(); - - rb_scan_args(argc, argv, "1*", &svr_name, &others); - StringValue(svr_name); - - /* get CLSID from OLE server name */ - pBuf = ole_vstr2wc(svr_name); - hr = CLSIDFromProgID(pBuf, &clsid); - if(FAILED(hr)) { - hr = CLSIDFromString(pBuf, &clsid); - } - SysFreeString(pBuf); - if(FAILED(hr)) { - return ole_bind_obj(svr_name, argc, argv, self); - } - - hr = GetActiveObject(&clsid, 0, &pUnknown); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "OLE server `%s' not running", StringValuePtr(svr_name)); - } - hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p); - pDispatch = p; - if(FAILED(hr)) { - OLE_RELEASE(pUnknown); - ole_raise(hr, eWIN32OLERuntimeError, - "failed to create WIN32OLE server `%s'", - StringValuePtr(svr_name)); - } - - OLE_RELEASE(pUnknown); - - return create_win32ole_object(self, pDispatch, argc, argv); -} - -/* - * call-seq: - * WIN32OLE.const_load( ole, mod = WIN32OLE) - * - * Defines the constants of OLE Automation server as mod's constants. - * The first argument is WIN32OLE object or type library name. - * If 2nd argument is omitted, the default is WIN32OLE. - * The first letter of Ruby's constant variable name is upper case, - * so constant variable name of WIN32OLE object is capitalized. - * For example, the 'xlTop' constant of Excel is changed to 'XlTop' - * in WIN32OLE. - * If the first letter of constant variable is not [A-Z], then - * the constant is defined as CONSTANTS hash element. - * - * module EXCEL_CONST - * end - * excel = WIN32OLE.new('Excel.Application') - * WIN32OLE.const_load(excel, EXCEL_CONST) - * puts EXCEL_CONST::XlTop # => -4160 - * puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541 - * - * WIN32OLE.const_load(excel) - * puts WIN32OLE::XlTop # => -4160 - * - * module MSO - * end - * WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO) - * puts MSO::MsoLineSingle # => 1 - */ -static VALUE -fole_s_const_load(int argc, VALUE *argv, VALUE self) -{ - VALUE ole; - VALUE klass; - struct oledata *pole = NULL; - ITypeInfo *pTypeInfo; - ITypeLib *pTypeLib; - unsigned int index; - HRESULT hr; - OLECHAR *pBuf; - VALUE file; - LCID lcid = cWIN32OLE_lcid; - - rb_scan_args(argc, argv, "11", &ole, &klass); - if (!RB_TYPE_P(klass, T_CLASS) && - !RB_TYPE_P(klass, T_MODULE) && - !RB_TYPE_P(klass, T_NIL)) { - rb_raise(rb_eTypeError, "2nd parameter must be Class or Module"); - } - if (rb_obj_is_kind_of(ole, cWIN32OLE)) { - pole = oledata_get_struct(ole); - hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, - 0, lcid, &pTypeInfo); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo"); - } - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index); - if(FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetContainingTypeLib"); - } - OLE_RELEASE(pTypeInfo); - if(!RB_TYPE_P(klass, T_NIL)) { - ole_const_load(pTypeLib, klass, self); - } - else { - ole_const_load(pTypeLib, cWIN32OLE, self); - } - OLE_RELEASE(pTypeLib); - } - else if(RB_TYPE_P(ole, T_STRING)) { - file = typelib_file(ole); - if (file == Qnil) { - file = ole; - } - pBuf = ole_vstr2wc(file); - hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib); - SysFreeString(pBuf); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx"); - if(!RB_TYPE_P(klass, T_NIL)) { - ole_const_load(pTypeLib, klass, self); - } - else { - ole_const_load(pTypeLib, cWIN32OLE, self); - } - OLE_RELEASE(pTypeLib); - } - else { - rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance"); - } - return Qnil; -} - -static ULONG -reference_count(struct oledata * pole) -{ - ULONG n = 0; - if(pole->pDispatch) { - OLE_ADDREF(pole->pDispatch); - n = OLE_RELEASE(pole->pDispatch); - } - return n; -} - -/* - * call-seq: - * WIN32OLE.ole_reference_count(aWIN32OLE) --> number - * - * Returns reference counter of Dispatch interface of WIN32OLE object. - * You should not use this method because this method - * exists only for debugging WIN32OLE. - */ -static VALUE -fole_s_reference_count(VALUE self, VALUE obj) -{ - struct oledata * pole = NULL; - pole = oledata_get_struct(obj); - return RB_INT2NUM(reference_count(pole)); -} - -/* - * call-seq: - * WIN32OLE.ole_free(aWIN32OLE) --> number - * - * Invokes Release method of Dispatch interface of WIN32OLE object. - * You should not use this method because this method - * exists only for debugging WIN32OLE. - * The return value is reference counter of OLE object. - */ -static VALUE -fole_s_free(VALUE self, VALUE obj) -{ - ULONG n = 0; - struct oledata * pole = NULL; - pole = oledata_get_struct(obj); - if(pole->pDispatch) { - if (reference_count(pole) > 0) { - n = OLE_RELEASE(pole->pDispatch); - } - } - return RB_INT2NUM(n); -} - -static HWND -ole_show_help(VALUE helpfile, VALUE helpcontext) -{ - FNHTMLHELP *pfnHtmlHelp; - HWND hwnd = 0; - - if(!ghhctrl) - ghhctrl = LoadLibrary("HHCTRL.OCX"); - if (!ghhctrl) - return hwnd; - pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA"); - if (!pfnHtmlHelp) - return hwnd; - hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile), - 0x0f, RB_NUM2INT(helpcontext)); - if (hwnd == 0) - hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile), - 0, RB_NUM2INT(helpcontext)); - return hwnd; -} - -/* - * call-seq: - * WIN32OLE.ole_show_help(obj [,helpcontext]) - * - * Displays helpfile. The 1st argument specifies WIN32OLE_TYPE - * object or WIN32OLE_METHOD object or helpfile. - * - * excel = WIN32OLE.new('Excel.Application') - * typeobj = excel.ole_type - * WIN32OLE.ole_show_help(typeobj) - */ -static VALUE -fole_s_show_help(int argc, VALUE *argv, VALUE self) -{ - VALUE target; - VALUE helpcontext; - VALUE helpfile; - VALUE name; - HWND hwnd; - rb_scan_args(argc, argv, "11", &target, &helpcontext); - if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) || - rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) { - helpfile = rb_funcall(target, rb_intern("helpfile"), 0); - if(strlen(StringValuePtr(helpfile)) == 0) { - name = rb_ivar_get(target, rb_intern("name")); - rb_raise(rb_eRuntimeError, "no helpfile of `%s'", - StringValuePtr(name)); - } - helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0); - } else { - helpfile = target; - } - if (!RB_TYPE_P(helpfile, T_STRING)) { - rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)"); - } - hwnd = ole_show_help(helpfile, helpcontext); - if(hwnd == 0) { - rb_raise(rb_eRuntimeError, "failed to open help file `%s'", - StringValuePtr(helpfile)); - } - return Qnil; -} - -/* - * call-seq: - * WIN32OLE.codepage - * - * Returns current codepage. - * WIN32OLE.codepage # => WIN32OLE::CP_ACP - */ -static VALUE -fole_s_get_code_page(VALUE self) -{ - return RB_INT2FIX(cWIN32OLE_cp); -} - -static BOOL CALLBACK -installed_code_page_proc(LPTSTR str) { - if (strtoul(str, NULL, 10) == g_cp_to_check) { - g_cp_installed = TRUE; - return FALSE; - } - return TRUE; -} - -static BOOL -code_page_installed(UINT cp) -{ - g_cp_installed = FALSE; - g_cp_to_check = cp; - EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED); - return g_cp_installed; -} - -/* - * call-seq: - * WIN32OLE.codepage = CP - * - * Sets current codepage. - * The WIN32OLE.codepage is initialized according to - * Encoding.default_internal. - * If Encoding.default_internal is nil then WIN32OLE.codepage - * is initialized according to Encoding.default_external. - * - * WIN32OLE.codepage = WIN32OLE::CP_UTF8 - * WIN32OLE.codepage = 65001 - */ -static VALUE -fole_s_set_code_page(VALUE self, VALUE vcp) -{ - UINT cp = RB_FIX2INT(vcp); - set_ole_codepage(cp); - /* - * Should this method return old codepage? - */ - return Qnil; -} - -/* - * call-seq: - * WIN32OLE.locale -> locale id. - * - * Returns current locale id (lcid). The default locale is - * WIN32OLE::LOCALE_SYSTEM_DEFAULT. - * - * lcid = WIN32OLE.locale - */ -static VALUE -fole_s_get_locale(VALUE self) -{ - return RB_INT2FIX(cWIN32OLE_lcid); -} - -static BOOL -CALLBACK installed_lcid_proc(LPTSTR str) -{ - if (strcmp(str, g_lcid_to_check) == 0) { - g_lcid_installed = TRUE; - return FALSE; - } - return TRUE; -} - -static BOOL -lcid_installed(LCID lcid) -{ - g_lcid_installed = FALSE; - snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", (unsigned long)lcid); - EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED); - return g_lcid_installed; -} - -/* - * call-seq: - * WIN32OLE.locale = lcid - * - * Sets current locale id (lcid). - * - * WIN32OLE.locale = 1033 # set locale English(U.S) - * obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY) - * - */ -static VALUE -fole_s_set_locale(VALUE self, VALUE vlcid) -{ - LCID lcid = RB_FIX2INT(vlcid); - if (lcid_installed(lcid)) { - cWIN32OLE_lcid = lcid; - } else { - switch (lcid) { - case LOCALE_SYSTEM_DEFAULT: - case LOCALE_USER_DEFAULT: - cWIN32OLE_lcid = lcid; - break; - default: - rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid); - } - } - return Qnil; -} - -/* - * call-seq: - * WIN32OLE.create_guid - * - * Creates GUID. - * WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8} - */ -static VALUE -fole_s_create_guid(VALUE self) -{ - GUID guid; - HRESULT hr; - OLECHAR bstr[80]; - int len = 0; - hr = CoCreateGuid(&guid); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID"); - } - len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR)); - if (len == 0) { - rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)"); - } - return ole_wc2vstr(bstr, FALSE); -} - -/* - * WIN32OLE.ole_initialize and WIN32OLE.ole_uninitialize - * are used in win32ole.rb to fix the issue bug #2618 (ruby-core:27634). - * You must not use these method. - */ - -/* :nodoc: */ -static VALUE -fole_s_ole_initialize(VALUE self) -{ - ole_initialize(); - return Qnil; -} - -/* :nodoc: */ -static VALUE -fole_s_ole_uninitialize(VALUE self) -{ - ole_uninitialize(); - return Qnil; -} - -/* - * Document-class: WIN32OLE - * - * <code>WIN32OLE</code> objects represent OLE Automation object in Ruby. - * - * By using WIN32OLE, you can access OLE server like VBScript. - * - * Here is sample script. - * - * require 'win32ole' - * - * excel = WIN32OLE.new('Excel.Application') - * excel.visible = true - * workbook = excel.Workbooks.Add(); - * worksheet = workbook.Worksheets(1); - * worksheet.Range("A1:D1").value = ["North","South","East","West"]; - * worksheet.Range("A2:B2").value = [5.2, 10]; - * worksheet.Range("C2").value = 8; - * worksheet.Range("D2").value = 20; - * - * range = worksheet.Range("A1:D2"); - * range.select - * chart = workbook.Charts.Add; - * - * workbook.saved = true; - * - * excel.ActiveWorkbook.Close(0); - * excel.Quit(); - * - * Unfortunately, Win32OLE doesn't support the argument passed by - * reference directly. - * Instead, Win32OLE provides WIN32OLE::ARGV or WIN32OLE_VARIANT object. - * If you want to get the result value of argument passed by reference, - * you can use WIN32OLE::ARGV or WIN32OLE_VARIANT. - * - * oleobj.method(arg1, arg2, refargv3) - * puts WIN32OLE::ARGV[2] # the value of refargv3 after called oleobj.method - * - * or - * - * refargv3 = WIN32OLE_VARIANT.new(XXX, - * WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_XXX) - * oleobj.method(arg1, arg2, refargv3) - * p refargv3.value # the value of refargv3 after called oleobj.method. - * - */ - -/* - * call-seq: - * WIN32OLE.new(server, [host]) -> WIN32OLE object - * WIN32OLE.new(server, license: 'key') -> WIN32OLE object - * - * Returns a new WIN32OLE object(OLE Automation object). - * The first argument server specifies OLE Automation server. - * The first argument should be CLSID or PROGID. - * If second argument host specified, then returns OLE Automation - * object on host. - * If :license keyword argument is provided, - * IClassFactory2::CreateInstanceLic is used to create instance of - * licensed server. - * - * WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object. - * WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object. - */ -static VALUE -fole_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE svr_name; - VALUE host; - VALUE others; - VALUE opts; - HRESULT hr; - CLSID clsid; - OLECHAR *pBuf; - OLECHAR *key_buf; - IDispatch *pDispatch; - IClassFactory2 * pIClassFactory2; - void *p; - static ID keyword_ids[1]; - VALUE kwargs[1]; - - rb_call_super(0, 0); - rb_scan_args(argc, argv, "11*:", &svr_name, &host, &others, &opts); - - StringValue(svr_name); - if (!NIL_P(host)) { - StringValue(host); - return ole_create_dcom(self, svr_name, host, others); - } - - /* get CLSID from OLE server name */ - pBuf = ole_vstr2wc(svr_name); - hr = CLSIDFromProgID(pBuf, &clsid); - if(FAILED(hr)) { - hr = CLSIDFromString(pBuf, &clsid); - } - SysFreeString(pBuf); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "unknown OLE server: `%s'", - StringValuePtr(svr_name)); - } - - if (!keyword_ids[0]) { - keyword_ids[0] = rb_intern_const("license"); - } - rb_get_kwargs(opts, keyword_ids, 0, 1, kwargs); - - if (kwargs[0] == Qundef) { - /* get IDispatch interface */ - hr = CoCreateInstance( - &clsid, - NULL, - CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, - &IID_IDispatch, - &p - ); - } else { - hr = CoGetClassObject( - &clsid, - CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, - NULL, - &IID_IClassFactory2, - (LPVOID)&pIClassFactory2 - ); - if (hr == S_OK) { - key_buf = ole_vstr2wc(kwargs[0]); - hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2, NULL, NULL, &IID_IDispatch, key_buf, &p); - SysFreeString(key_buf); - OLE_RELEASE(pIClassFactory2); - } - } - pDispatch = p; - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "failed to create WIN32OLE object from `%s'", - StringValuePtr(svr_name)); - } - - ole_set_member(self, pDispatch); - return self; -} - -static int -hash2named_arg(VALUE key, VALUE val, VALUE pop) -{ - struct oleparam* pOp = (struct oleparam *)pop; - unsigned int index, i; - index = pOp->dp.cNamedArgs; - /*--------------------------------------------- - the data-type of key must be String or Symbol - -----------------------------------------------*/ - if(!RB_TYPE_P(key, T_STRING) && !RB_TYPE_P(key, T_SYMBOL)) { - /* clear name of dispatch parameters */ - for(i = 1; i < index + 1; i++) { - SysFreeString(pOp->pNamedArgs[i]); - } - /* clear dispatch parameters */ - for(i = 0; i < index; i++ ) { - VariantClear(&(pOp->dp.rgvarg[i])); - } - /* raise an exception */ - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - if (RB_TYPE_P(key, T_SYMBOL)) { - key = rb_sym2str(key); - } - - /* pNamedArgs[0] is <method name>, so "index + 1" */ - pOp->pNamedArgs[index + 1] = ole_vstr2wc(key); - - VariantInit(&(pOp->dp.rgvarg[index])); - ole_val2variant(val, &(pOp->dp.rgvarg[index])); - - pOp->dp.cNamedArgs += 1; - return ST_CONTINUE; -} - -static VALUE -set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end) -{ - VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV")); - - Check_Type(argv, T_ARRAY); - rb_ary_clear(argv); - while (end-- > beg) { - rb_ary_push(argv, ole_variant2val(&realargs[end])); - if (V_VT(&realargs[end]) != VT_RECORD) { - VariantClear(&realargs[end]); - } - } - return argv; -} - -static VALUE -ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket) -{ - LCID lcid = cWIN32OLE_lcid; - struct oledata *pole = NULL; - HRESULT hr; - VALUE cmd; - VALUE paramS; - VALUE param; - VALUE obj; - VALUE v; - - BSTR wcmdname; - - DISPID DispID; - DISPID* pDispID; - EXCEPINFO excepinfo; - VARIANT result; - VARIANTARG* realargs = NULL; - unsigned int argErr = 0; - unsigned int i; - unsigned int cNamedArgs; - int n; - struct oleparam op; - memset(&excepinfo, 0, sizeof(EXCEPINFO)); - - VariantInit(&result); - - op.dp.rgvarg = NULL; - op.dp.rgdispidNamedArgs = NULL; - op.dp.cNamedArgs = 0; - op.dp.cArgs = 0; - - rb_scan_args(argc, argv, "1*", &cmd, ¶mS); - if(!RB_TYPE_P(cmd, T_STRING) && !RB_TYPE_P(cmd, T_SYMBOL) && !is_bracket) { - rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)"); - } - if (RB_TYPE_P(cmd, T_SYMBOL)) { - cmd = rb_sym2str(cmd); - } - pole = oledata_get_struct(self); - if(!pole->pDispatch) { - rb_raise(rb_eRuntimeError, "failed to get dispatch interface"); - } - if (is_bracket) { - DispID = DISPID_VALUE; - argc += 1; - rb_ary_unshift(paramS, cmd); - } else { - wcmdname = ole_vstr2wc(cmd); - hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL, - &wcmdname, 1, lcid, &DispID); - SysFreeString(wcmdname); - if(FAILED(hr)) { - return rb_eNoMethodError; - } - } - - /* pick up last argument of method */ - param = rb_ary_entry(paramS, argc-2); - - op.dp.cNamedArgs = 0; - - /* if last arg is hash object */ - if(RB_TYPE_P(param, T_HASH)) { - /*------------------------------------------ - hash object ==> named dispatch parameters - --------------------------------------------*/ - cNamedArgs = rb_long2int((long)RHASH_SIZE(param)); - op.dp.cArgs = cNamedArgs + argc - 2; - op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1); - op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs); - - rb_hash_foreach(param, hash2named_arg, (VALUE)&op); - - pDispID = ALLOCA_N(DISPID, cNamedArgs + 1); - op.pNamedArgs[0] = ole_vstr2wc(cmd); - hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, - &IID_NULL, - op.pNamedArgs, - op.dp.cNamedArgs + 1, - lcid, pDispID); - for(i = 0; i < op.dp.cNamedArgs + 1; i++) { - SysFreeString(op.pNamedArgs[i]); - op.pNamedArgs[i] = NULL; - } - if(FAILED(hr)) { - /* clear dispatch parameters */ - for(i = 0; i < op.dp.cArgs; i++ ) { - VariantClear(&op.dp.rgvarg[i]); - } - ole_raise(hr, eWIN32OLERuntimeError, - "failed to get named argument info: `%s'", - StringValuePtr(cmd)); - } - op.dp.rgdispidNamedArgs = &(pDispID[1]); - } - else { - cNamedArgs = 0; - op.dp.cArgs = argc - 1; - op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1); - if (op.dp.cArgs > 0) { - op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs); - } - } - /*-------------------------------------- - non hash args ==> dispatch parameters - ----------------------------------------*/ - if(op.dp.cArgs > cNamedArgs) { - realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1); - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - VariantInit(&realargs[n]); - VariantInit(&op.dp.rgvarg[n]); - param = rb_ary_entry(paramS, i-cNamedArgs); - if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) { - ole_variant2variant(param, &op.dp.rgvarg[n]); - } else if (rb_obj_is_kind_of(param, cWIN32OLE_RECORD)) { - ole_val2variant(param, &realargs[n]); - op.dp.rgvarg[n] = realargs[n]; - V_VT(&op.dp.rgvarg[n]) = VT_RECORD | VT_BYREF; - } else { - ole_val2variant(param, &realargs[n]); - V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF; - V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n]; - } - } - } - /* apparent you need to call propput, you need this */ - if (wFlags & DISPATCH_PROPERTYPUT) { - if (op.dp.cArgs == 0) - ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error"); - - op.dp.cNamedArgs = 1; - op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 ); - op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT; - } - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, - &IID_NULL, lcid, wFlags, &op.dp, - &result, &excepinfo, &argErr); - - if (FAILED(hr)) { - /* retry to call args by value */ - if(op.dp.cArgs >= cNamedArgs) { - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - param = rb_ary_entry(paramS, i-cNamedArgs); - ole_val2variant(param, &op.dp.rgvarg[n]); - } - if (hr == DISP_E_EXCEPTION) { - ole_freeexceptinfo(&excepinfo); - } - memset(&excepinfo, 0, sizeof(EXCEPINFO)); - VariantInit(&result); - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, - &IID_NULL, lcid, wFlags, - &op.dp, &result, - &excepinfo, &argErr); - - /* mega kludge. if a method in WORD is called and we ask - * for a result when one is not returned then - * hResult == DISP_E_EXCEPTION. this only happens on - * functions whose DISPID > 0x8000 */ - if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) { - if (hr == DISP_E_EXCEPTION) { - ole_freeexceptinfo(&excepinfo); - } - memset(&excepinfo, 0, sizeof(EXCEPINFO)); - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, - &IID_NULL, lcid, wFlags, - &op.dp, NULL, - &excepinfo, &argErr); - - } - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) { - VariantClear(&op.dp.rgvarg[n]); - } - } - } - - if (FAILED(hr)) { - /* retry after converting nil to VT_EMPTY */ - if (op.dp.cArgs > cNamedArgs) { - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - param = rb_ary_entry(paramS, i-cNamedArgs); - ole_val2variant2(param, &op.dp.rgvarg[n]); - } - if (hr == DISP_E_EXCEPTION) { - ole_freeexceptinfo(&excepinfo); - } - memset(&excepinfo, 0, sizeof(EXCEPINFO)); - VariantInit(&result); - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, - &IID_NULL, lcid, wFlags, - &op.dp, &result, - &excepinfo, &argErr); - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) { - VariantClear(&op.dp.rgvarg[n]); - } - } - } - } - - } - /* clear dispatch parameter */ - if(op.dp.cArgs > cNamedArgs) { - for(i = cNamedArgs; i < op.dp.cArgs; i++) { - n = op.dp.cArgs - i + cNamedArgs - 1; - param = rb_ary_entry(paramS, i-cNamedArgs); - if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) { - ole_val2variant(param, &realargs[n]); - } else if ( rb_obj_is_kind_of(param, cWIN32OLE_RECORD) && - V_VT(&realargs[n]) == VT_RECORD ) { - olerecord_set_ivar(param, V_RECORDINFO(&realargs[n]), V_RECORD(&realargs[n])); - } - } - set_argv(realargs, cNamedArgs, op.dp.cArgs); - } - else { - for(i = 0; i < op.dp.cArgs; i++) { - VariantClear(&op.dp.rgvarg[i]); - } - } - - if (FAILED(hr)) { - v = ole_excepinfo2msg(&excepinfo); - ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s", - StringValuePtr(cmd), - StringValuePtr(v)); - } - obj = ole_variant2val(&result); - VariantClear(&result); - return obj; -} - -/* - * call-seq: - * WIN32OLE#invoke(method, [arg1,...]) => return value of method. - * - * Runs OLE method. - * The first argument specifies the method name of OLE Automation object. - * The others specify argument of the <i>method</i>. - * If you can not execute <i>method</i> directly, then use this method instead. - * - * excel = WIN32OLE.new('Excel.Application') - * excel.invoke('Quit') # => same as excel.Quit - * - */ -static VALUE -fole_invoke(int argc, VALUE *argv, VALUE self) -{ - VALUE v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE); - if (v == rb_eNoMethodError) { - return rb_call_super(argc, argv); - } - return v; -} - -static VALUE -ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind) -{ - HRESULT hr; - struct oledata *pole = NULL; - unsigned int argErr = 0; - EXCEPINFO excepinfo; - VARIANT result; - DISPPARAMS dispParams; - VARIANTARG* realargs = NULL; - int i, j; VALUE obj = Qnil; - VALUE tp, param; - VALUE v; - VARTYPE vt; - - Check_Type(args, T_ARRAY); - Check_Type(types, T_ARRAY); - - memset(&excepinfo, 0, sizeof(EXCEPINFO)); - memset(&dispParams, 0, sizeof(DISPPARAMS)); - VariantInit(&result); - pole = oledata_get_struct(self); - - dispParams.cArgs = RARRAY_LEN(args); - dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs); - realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs); - for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--) - { - VariantInit(&realargs[i]); - VariantInit(&dispParams.rgvarg[i]); - tp = rb_ary_entry(types, j); - vt = (VARTYPE)RB_FIX2INT(tp); - V_VT(&dispParams.rgvarg[i]) = vt; - param = rb_ary_entry(args, j); - if (param == Qnil) - { - - V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR; - V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND; - } - else - { - if (vt & VT_ARRAY) - { - int ent; - LPBYTE pb; - short* ps; - LPLONG pl; - VARIANT* pv; - CY *py; - VARTYPE v; - SAFEARRAYBOUND rgsabound[1]; - Check_Type(param, T_ARRAY); - rgsabound[0].lLbound = 0; - rgsabound[0].cElements = RARRAY_LEN(param); - v = vt & ~(VT_ARRAY | VT_BYREF); - V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound); - V_VT(&realargs[i]) = VT_ARRAY | v; - SafeArrayLock(V_ARRAY(&realargs[i])); - pb = V_ARRAY(&realargs[i])->pvData; - ps = V_ARRAY(&realargs[i])->pvData; - pl = V_ARRAY(&realargs[i])->pvData; - py = V_ARRAY(&realargs[i])->pvData; - pv = V_ARRAY(&realargs[i])->pvData; - for (ent = 0; ent < (int)rgsabound[0].cElements; ent++) - { - VARIANT velem; - VALUE elem = rb_ary_entry(param, ent); - ole_val2variant(elem, &velem); - if (v != VT_VARIANT) - { - VariantChangeTypeEx(&velem, &velem, - cWIN32OLE_lcid, 0, v); - } - switch (v) - { - /* 128 bits */ - case VT_VARIANT: - *pv++ = velem; - break; - /* 64 bits */ - case VT_R8: - case VT_CY: - case VT_DATE: - *py++ = V_CY(&velem); - break; - /* 16 bits */ - case VT_BOOL: - case VT_I2: - case VT_UI2: - *ps++ = V_I2(&velem); - break; - /* 8 bites */ - case VT_UI1: - case VT_I1: - *pb++ = V_UI1(&velem); - break; - /* 32 bits */ - default: - *pl++ = V_I4(&velem); - break; - } - } - SafeArrayUnlock(V_ARRAY(&realargs[i])); - } - else - { - ole_val2variant(param, &realargs[i]); - if ((vt & (~VT_BYREF)) != VT_VARIANT) - { - hr = VariantChangeTypeEx(&realargs[i], &realargs[i], - cWIN32OLE_lcid, 0, - (VARTYPE)(vt & (~VT_BYREF))); - if (hr != S_OK) - { - rb_raise(rb_eTypeError, "not valid value"); - } - } - } - if ((vt & VT_BYREF) || vt == VT_VARIANT) - { - if (vt == VT_VARIANT) - V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF; - switch (vt & (~VT_BYREF)) - { - /* 128 bits */ - case VT_VARIANT: - V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i]; - break; - /* 64 bits */ - case VT_R8: - case VT_CY: - case VT_DATE: - V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]); - break; - /* 16 bits */ - case VT_BOOL: - case VT_I2: - case VT_UI2: - V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]); - break; - /* 8 bites */ - case VT_UI1: - case VT_I1: - V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]); - break; - /* 32 bits */ - default: - V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]); - break; - } - } - else - { - /* copy 64 bits of data */ - V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]); - } - } - } - - if (dispkind & DISPATCH_PROPERTYPUT) { - dispParams.cNamedArgs = 1; - dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 ); - dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT; - } - - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, RB_NUM2INT(dispid), - &IID_NULL, cWIN32OLE_lcid, - dispkind, - &dispParams, &result, - &excepinfo, &argErr); - - if (FAILED(hr)) { - v = ole_excepinfo2msg(&excepinfo); - ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s", - RB_NUM2INT(dispid), - StringValuePtr(v)); - } - - /* clear dispatch parameter */ - if(dispParams.cArgs > 0) { - set_argv(realargs, 0, dispParams.cArgs); - } - - obj = ole_variant2val(&result); - VariantClear(&result); - return obj; -} - -/* - * call-seq: - * WIN32OLE#_invoke(dispid, args, types) - * - * Runs the early binding method. - * The 1st argument specifies dispatch ID, - * the 2nd argument specifies the array of arguments, - * the 3rd argument specifies the array of the type of arguments. - * - * excel = WIN32OLE.new('Excel.Application') - * excel._invoke(302, [], []) # same effect as excel.Quit - */ -static VALUE -fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types) -{ - return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD); -} - -/* - * call-seq: - * WIN32OLE#_getproperty(dispid, args, types) - * - * Runs the early binding method to get property. - * The 1st argument specifies dispatch ID, - * the 2nd argument specifies the array of arguments, - * the 3rd argument specifies the array of the type of arguments. - * - * excel = WIN32OLE.new('Excel.Application') - * puts excel._getproperty(558, [], []) # same effect as puts excel.visible - */ -static VALUE -fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types) -{ - return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET); -} - -/* - * call-seq: - * WIN32OLE#_setproperty(dispid, args, types) - * - * Runs the early binding method to set property. - * The 1st argument specifies dispatch ID, - * the 2nd argument specifies the array of arguments, - * the 3rd argument specifies the array of the type of arguments. - * - * excel = WIN32OLE.new('Excel.Application') - * excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true - */ -static VALUE -fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types) -{ - return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT); -} - -/* - * call-seq: - * WIN32OLE[a1, a2, ...]=val - * - * Sets the value to WIN32OLE object specified by a1, a2, ... - * - * dict = WIN32OLE.new('Scripting.Dictionary') - * dict.add('ruby', 'RUBY') - * dict['ruby'] = 'Ruby' - * puts dict['ruby'] # => 'Ruby' - * - * Remark: You can not use this method to set the property value. - * - * excel = WIN32OLE.new('Excel.Application') - * # excel['Visible'] = true # This is error !!! - * excel.Visible = true # You should to use this style to set the property. - * - */ -static VALUE -fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self) -{ - VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE); - if (v == rb_eNoMethodError) { - return rb_call_super(argc, argv); - } - return v; -} - -/* - * call-seq: - * WIN32OLE.setproperty('property', [arg1, arg2,...] val) - * - * Sets property of OLE object. - * When you want to set property with argument, you can use this method. - * - * excel = WIN32OLE.new('Excel.Application') - * excel.Visible = true - * book = excel.workbooks.add - * sheet = book.worksheets(1) - * sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10. - */ -static VALUE -fole_setproperty(int argc, VALUE *argv, VALUE self) -{ - VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE); - if (v == rb_eNoMethodError) { - return rb_call_super(argc, argv); - } - return v; -} - -/* - * call-seq: - * WIN32OLE[a1,a2,...] - * - * Returns the value of Collection specified by a1, a2,.... - * - * dict = WIN32OLE.new('Scripting.Dictionary') - * dict.add('ruby', 'Ruby') - * puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')') - * - * Remark: You can not use this method to get the property. - * excel = WIN32OLE.new('Excel.Application') - * # puts excel['Visible'] This is error !!! - * puts excel.Visible # You should to use this style to get the property. - * - */ -static VALUE -fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self) -{ - VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE); - if (v == rb_eNoMethodError) { - return rb_call_super(argc, argv); - } - return v; -} - -static VALUE -ole_propertyput(VALUE self, VALUE property, VALUE value) -{ - struct oledata *pole = NULL; - unsigned argErr; - unsigned int index; - HRESULT hr; - EXCEPINFO excepinfo; - DISPID dispID = DISPID_VALUE; - DISPID dispIDParam = DISPID_PROPERTYPUT; - USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF; - DISPPARAMS dispParams; - VARIANTARG propertyValue[2]; - OLECHAR* pBuf[1]; - VALUE v; - LCID lcid = cWIN32OLE_lcid; - dispParams.rgdispidNamedArgs = &dispIDParam; - dispParams.rgvarg = propertyValue; - dispParams.cNamedArgs = 1; - dispParams.cArgs = 1; - - VariantInit(&propertyValue[0]); - VariantInit(&propertyValue[1]); - memset(&excepinfo, 0, sizeof(excepinfo)); - - pole = oledata_get_struct(self); - - /* get ID from property name */ - pBuf[0] = ole_vstr2wc(property); - hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL, - pBuf, 1, lcid, &dispID); - SysFreeString(pBuf[0]); - pBuf[0] = NULL; - - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "unknown property or method: `%s'", - StringValuePtr(property)); - } - /* set property value */ - ole_val2variant(value, &propertyValue[0]); - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL, - lcid, wFlags, &dispParams, - NULL, &excepinfo, &argErr); - - for(index = 0; index < dispParams.cArgs; ++index) { - VariantClear(&propertyValue[index]); - } - if (FAILED(hr)) { - v = ole_excepinfo2msg(&excepinfo); - ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s", - StringValuePtr(property), - StringValuePtr(v)); - } - return Qnil; -} - -/* - * call-seq: - * WIN32OLE#ole_free - * - * invokes Release method of Dispatch interface of WIN32OLE object. - * Usually, you do not need to call this method because Release method - * called automatically when WIN32OLE object garbaged. - * - */ -static VALUE -fole_free(VALUE self) -{ - struct oledata *pole = NULL; - pole = oledata_get_struct(self); - OLE_FREE(pole->pDispatch); - pole->pDispatch = NULL; - return Qnil; -} - -static VALUE -ole_each_sub(VALUE pEnumV) -{ - VARIANT variant; - VALUE obj = Qnil; - IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV; - VariantInit(&variant); - while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) { - obj = ole_variant2val(&variant); - VariantClear(&variant); - VariantInit(&variant); - rb_yield(obj); - } - return Qnil; -} - -static VALUE -ole_ienum_free(VALUE pEnumV) -{ - IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV; - OLE_RELEASE(pEnum); - return Qnil; -} - -/* - * call-seq: - * WIN32OLE#each {|i|...} - * - * Iterates over each item of OLE collection which has IEnumVARIANT interface. - * - * excel = WIN32OLE.new('Excel.Application') - * book = excel.workbooks.add - * sheets = book.worksheets(1) - * cells = sheets.cells("A1:A5") - * cells.each do |cell| - * cell.value = 10 - * end - */ -static VALUE -fole_each(VALUE self) -{ - LCID lcid = cWIN32OLE_lcid; - - struct oledata *pole = NULL; - - unsigned int argErr; - EXCEPINFO excepinfo; - DISPPARAMS dispParams; - VARIANT result; - HRESULT hr; - IEnumVARIANT *pEnum = NULL; - void *p; - - RETURN_ENUMERATOR(self, 0, 0); - - VariantInit(&result); - dispParams.rgvarg = NULL; - dispParams.rgdispidNamedArgs = NULL; - dispParams.cNamedArgs = 0; - dispParams.cArgs = 0; - memset(&excepinfo, 0, sizeof(excepinfo)); - - pole = oledata_get_struct(self); - hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM, - &IID_NULL, lcid, - DISPATCH_METHOD | DISPATCH_PROPERTYGET, - &dispParams, &result, - &excepinfo, &argErr); - - if (FAILED(hr)) { - VariantClear(&result); - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface"); - } - - if (V_VT(&result) == VT_UNKNOWN) { - hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result), - &IID_IEnumVARIANT, - &p); - pEnum = p; - } else if (V_VT(&result) == VT_DISPATCH) { - hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result), - &IID_IEnumVARIANT, - &p); - pEnum = p; - } - if (FAILED(hr) || !pEnum) { - VariantClear(&result); - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface"); - } - - VariantClear(&result); - rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum); - return Qnil; -} - -/* - * call-seq: - * WIN32OLE#method_missing(id [,arg1, arg2, ...]) - * - * Calls WIN32OLE#invoke method. - */ -static VALUE -fole_missing(int argc, VALUE *argv, VALUE self) -{ - VALUE mid, org_mid, sym, v; - const char* mname; - long n; - rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); - mid = org_mid = argv[0]; - sym = rb_check_symbol(&mid); - if (!NIL_P(sym)) mid = rb_sym2str(sym); - mname = StringValueCStr(mid); - if(!mname) { - rb_raise(rb_eRuntimeError, "fail: unknown method or property"); - } - n = RSTRING_LEN(mid); - if(mname[n-1] == '=') { - rb_check_arity(argc, 2, 2); - argv[0] = rb_enc_associate(rb_str_subseq(mid, 0, n-1), cWIN32OLE_enc); - - return ole_propertyput(self, argv[0], argv[1]); - } - else { - argv[0] = rb_enc_associate(rb_str_dup(mid), cWIN32OLE_enc); - v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE); - if (v == rb_eNoMethodError) { - argv[0] = org_mid; - return rb_call_super(argc, argv); - } - return v; - } -} - -static HRESULT -typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti) -{ - ITypeInfo *pTypeInfo; - ITypeLib *pTypeLib; - BSTR bstr; - VALUE type; - UINT i; - UINT count; - LCID lcid = cWIN32OLE_lcid; - HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, - 0, lcid, &pTypeInfo); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo"); - } - hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, - -1, - &bstr, - NULL, NULL, NULL); - type = WC2VSTR(bstr); - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i); - OLE_RELEASE(pTypeInfo); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetContainingTypeLib"); - } - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count; i++) { - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - &bstr, NULL, NULL, NULL); - if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) { - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); - if (SUCCEEDED(hr)) { - *ppti = pTypeInfo; - break; - } - } - } - OLE_RELEASE(pTypeLib); - return hr; -} - -static VALUE -ole_methods(VALUE self, int mask) -{ - ITypeInfo *pTypeInfo; - HRESULT hr; - VALUE methods; - struct oledata *pole = NULL; - - pole = oledata_get_struct(self); - methods = rb_ary_new(); - - hr = typeinfo_from_ole(pole, &pTypeInfo); - if(FAILED(hr)) - return methods; - rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask)); - OLE_RELEASE(pTypeInfo); - return methods; -} - -/* - * call-seq: - * WIN32OLE#ole_methods - * - * Returns the array of WIN32OLE_METHOD object. - * The element is OLE method of WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * methods = excel.ole_methods - * - */ -static VALUE -fole_methods(VALUE self) -{ - return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF); -} - -/* - * call-seq: - * WIN32OLE#ole_get_methods - * - * Returns the array of WIN32OLE_METHOD object . - * The element of the array is property (gettable) of WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * properties = excel.ole_get_methods - */ -static VALUE -fole_get_methods(VALUE self) -{ - return ole_methods( self, INVOKE_PROPERTYGET); -} - -/* - * call-seq: - * WIN32OLE#ole_put_methods - * - * Returns the array of WIN32OLE_METHOD object . - * The element of the array is property (settable) of WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * properties = excel.ole_put_methods - */ -static VALUE -fole_put_methods(VALUE self) -{ - return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF); -} - -/* - * call-seq: - * WIN32OLE#ole_func_methods - * - * Returns the array of WIN32OLE_METHOD object . - * The element of the array is property (settable) of WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * properties = excel.ole_func_methods - * - */ -static VALUE -fole_func_methods(VALUE self) -{ - return ole_methods( self, INVOKE_FUNC); -} - -/* - * call-seq: - * WIN32OLE#ole_type - * - * Returns WIN32OLE_TYPE object. - * - * excel = WIN32OLE.new('Excel.Application') - * tobj = excel.ole_type - */ -static VALUE -fole_type(VALUE self) -{ - ITypeInfo *pTypeInfo; - HRESULT hr; - struct oledata *pole = NULL; - LCID lcid = cWIN32OLE_lcid; - VALUE type = Qnil; - - pole = oledata_get_struct(self); - - hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo ); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo"); - } - type = ole_type_from_itypeinfo(pTypeInfo); - OLE_RELEASE(pTypeInfo); - if (type == Qnil) { - rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo"); - } - return type; -} - -/* - * call-seq: - * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object - * - * Returns the WIN32OLE_TYPELIB object. The object represents the - * type library which contains the WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * tlib = excel.ole_typelib - * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library' - */ -static VALUE -fole_typelib(VALUE self) -{ - struct oledata *pole = NULL; - HRESULT hr; - ITypeInfo *pTypeInfo; - LCID lcid = cWIN32OLE_lcid; - VALUE vtlib = Qnil; - - pole = oledata_get_struct(self); - hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, - 0, lcid, &pTypeInfo); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo"); - } - vtlib = ole_typelib_from_itypeinfo(pTypeInfo); - OLE_RELEASE(pTypeInfo); - if (vtlib == Qnil) { - rb_raise(rb_eRuntimeError, "failed to get type library info."); - } - return vtlib; -} - -/* - * call-seq: - * WIN32OLE#ole_query_interface(iid) -> WIN32OLE object - * - * Returns WIN32OLE object for a specific dispatch or dual - * interface specified by iid. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp - */ -static VALUE -fole_query_interface(VALUE self, VALUE str_iid) -{ - HRESULT hr; - OLECHAR *pBuf; - IID iid; - struct oledata *pole = NULL; - IDispatch *pDispatch; - void *p; - - pBuf = ole_vstr2wc(str_iid); - hr = CLSIDFromString(pBuf, &iid); - SysFreeString(pBuf); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "invalid iid: `%s'", - StringValuePtr(str_iid)); - } - - pole = oledata_get_struct(self); - if(!pole->pDispatch) { - rb_raise(rb_eRuntimeError, "failed to get dispatch interface"); - } - - hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid, - &p); - if(FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, - "failed to get interface `%s'", - StringValuePtr(str_iid)); - } - - pDispatch = p; - return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0); -} - -/* - * call-seq: - * WIN32OLE#ole_respond_to?(method) -> true or false - * - * Returns true when OLE object has OLE method, otherwise returns false. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ie.ole_respond_to?("gohome") => true - */ -static VALUE -fole_respond_to(VALUE self, VALUE method) -{ - struct oledata *pole = NULL; - BSTR wcmdname; - DISPID DispID; - HRESULT hr; - if(!RB_TYPE_P(method, T_STRING) && !RB_TYPE_P(method, T_SYMBOL)) { - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - if (RB_TYPE_P(method, T_SYMBOL)) { - method = rb_sym2str(method); - } - pole = oledata_get_struct(self); - wcmdname = ole_vstr2wc(method); - hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL, - &wcmdname, 1, cWIN32OLE_lcid, &DispID); - SysFreeString(wcmdname); - return SUCCEEDED(hr) ? Qtrue : Qfalse; -} - -HRESULT -ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile) -{ - HRESULT hr; - ITypeLib *pTypeLib; - UINT i; - - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i); - if (FAILED(hr)) { - return hr; - } - - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - name, helpstr, - helpcontext, helpfile); - if (FAILED(hr)) { - OLE_RELEASE(pTypeLib); - return hr; - } - OLE_RELEASE(pTypeLib); - return hr; -} - -static VALUE -ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) -{ - HRESULT hr; - BSTR bstr; - ITypeInfo *pRefTypeInfo; - VALUE type = Qnil; - - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, - V_UNION1(pTypeDesc, hreftype), - &pRefTypeInfo); - if(FAILED(hr)) - return Qnil; - hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL); - if(FAILED(hr)) { - OLE_RELEASE(pRefTypeInfo); - return Qnil; - } - OLE_RELEASE(pRefTypeInfo); - type = WC2VSTR(bstr); - if(typedetails != Qnil) - rb_ary_push(typedetails, type); - return type; -} - -static VALUE -ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) -{ - TYPEDESC *p = pTypeDesc; - VALUE type = rb_str_new2(""); - - if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) { - p = V_UNION1(p, lptdesc); - type = ole_typedesc2val(pTypeInfo, p, typedetails); - } - return type; -} - -VALUE -ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) -{ - VALUE str; - VALUE typestr = Qnil; - switch(pTypeDesc->vt) { - case VT_I2: - typestr = rb_str_new2("I2"); - break; - case VT_I4: - typestr = rb_str_new2("I4"); - break; - case VT_R4: - typestr = rb_str_new2("R4"); - break; - case VT_R8: - typestr = rb_str_new2("R8"); - break; - case VT_CY: - typestr = rb_str_new2("CY"); - break; - case VT_DATE: - typestr = rb_str_new2("DATE"); - break; - case VT_BSTR: - typestr = rb_str_new2("BSTR"); - break; - case VT_BOOL: - typestr = rb_str_new2("BOOL"); - break; - case VT_VARIANT: - typestr = rb_str_new2("VARIANT"); - break; - case VT_DECIMAL: - typestr = rb_str_new2("DECIMAL"); - break; - case VT_I1: - typestr = rb_str_new2("I1"); - break; - case VT_UI1: - typestr = rb_str_new2("UI1"); - break; - case VT_UI2: - typestr = rb_str_new2("UI2"); - break; - case VT_UI4: - typestr = rb_str_new2("UI4"); - break; -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - case VT_I8: - typestr = rb_str_new2("I8"); - break; - case VT_UI8: - typestr = rb_str_new2("UI8"); - break; -#endif - case VT_INT: - typestr = rb_str_new2("INT"); - break; - case VT_UINT: - typestr = rb_str_new2("UINT"); - break; - case VT_VOID: - typestr = rb_str_new2("VOID"); - break; - case VT_HRESULT: - typestr = rb_str_new2("HRESULT"); - break; - case VT_PTR: - typestr = rb_str_new2("PTR"); - if(typedetails != Qnil) - rb_ary_push(typedetails, typestr); - return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails); - case VT_SAFEARRAY: - typestr = rb_str_new2("SAFEARRAY"); - if(typedetails != Qnil) - rb_ary_push(typedetails, typestr); - return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails); - case VT_CARRAY: - typestr = rb_str_new2("CARRAY"); - break; - case VT_USERDEFINED: - typestr = rb_str_new2("USERDEFINED"); - if (typedetails != Qnil) - rb_ary_push(typedetails, typestr); - str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails); - if (str != Qnil) { - return str; - } - return typestr; - case VT_UNKNOWN: - typestr = rb_str_new2("UNKNOWN"); - break; - case VT_DISPATCH: - typestr = rb_str_new2("DISPATCH"); - break; - case VT_ERROR: - typestr = rb_str_new2("ERROR"); - break; - case VT_LPWSTR: - typestr = rb_str_new2("LPWSTR"); - break; - case VT_LPSTR: - typestr = rb_str_new2("LPSTR"); - break; - case VT_RECORD: - typestr = rb_str_new2("RECORD"); - break; - default: - typestr = rb_str_new2("Unknown Type "); - rb_str_concat(typestr, rb_fix2str(RB_INT2FIX(pTypeDesc->vt), 10)); - break; - } - if (typedetails != Qnil) - rb_ary_push(typedetails, typestr); - return typestr; -} - -/* - * call-seq: - * WIN32OLE#ole_method_help(method) - * - * Returns WIN32OLE_METHOD object corresponding with method - * specified by 1st argument. - * - * excel = WIN32OLE.new('Excel.Application') - * method = excel.ole_method_help('Quit') - * - */ -static VALUE -fole_method_help(VALUE self, VALUE cmdname) -{ - ITypeInfo *pTypeInfo; - HRESULT hr; - struct oledata *pole = NULL; - VALUE obj; - - SafeStringValue(cmdname); - pole = oledata_get_struct(self); - hr = typeinfo_from_ole(pole, &pTypeInfo); - if(FAILED(hr)) - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get ITypeInfo"); - - obj = create_win32ole_method(pTypeInfo, cmdname); - - OLE_RELEASE(pTypeInfo); - if (obj == Qnil) - rb_raise(eWIN32OLERuntimeError, "not found %s", - StringValuePtr(cmdname)); - return obj; -} - -/* - * call-seq: - * WIN32OLE#ole_activex_initialize() -> Qnil - * - * Initialize WIN32OLE object(ActiveX Control) by calling - * IPersistMemory::InitNew. - * - * Before calling OLE method, some kind of the ActiveX controls - * created with MFC should be initialized by calling - * IPersistXXX::InitNew. - * - * If and only if you received the exception "HRESULT error code: - * 0x8000ffff catastrophic failure", try this method before - * invoking any ole_method. - * - * obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control") - * obj.ole_activex_initialize - * obj.method(...) - * - */ -static VALUE -fole_activex_initialize(VALUE self) -{ - struct oledata *pole = NULL; - IPersistMemory *pPersistMemory; - void *p; - - HRESULT hr = S_OK; - - pole = oledata_get_struct(self); - - hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p); - pPersistMemory = p; - if (SUCCEEDED(hr)) { - hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory); - OLE_RELEASE(pPersistMemory); - if (SUCCEEDED(hr)) { - return Qnil; - } - } - - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control"); - } - - return Qnil; -} - -HRESULT -typelib_from_val(VALUE obj, ITypeLib **pTypeLib) -{ - LCID lcid = cWIN32OLE_lcid; - HRESULT hr; - struct oledata *pole = NULL; - unsigned int index; - ITypeInfo *pTypeInfo; - pole = oledata_get_struct(obj); - hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, - 0, lcid, &pTypeInfo); - if (FAILED(hr)) { - return hr; - } - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, pTypeLib, &index); - OLE_RELEASE(pTypeInfo); - return hr; -} - -static void -com_hash_free(void *ptr) -{ - st_table *tbl = ptr; - st_free_table(tbl); -} - -static void -com_hash_mark(void *ptr) -{ - st_table *tbl = ptr; - rb_mark_hash(tbl); -} - -static size_t -com_hash_size(const void *ptr) -{ - const st_table *tbl = ptr; - return st_memsize(tbl); -} - -static void -check_nano_server(void) -{ - HKEY hsubkey; - LONG err; - const char * subkey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels"; - const char * regval = "NanoServer"; - - err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hsubkey); - if (err == ERROR_SUCCESS) { - err = RegQueryValueEx(hsubkey, regval, NULL, NULL, NULL, NULL); - if (err == ERROR_SUCCESS) { - g_running_nano = TRUE; - } - RegCloseKey(hsubkey); - } -} - -LCID cWIN32OLE_lcid; - -void -Init_win32ole(void) -{ - cWIN32OLE_lcid = LOCALE_SYSTEM_DEFAULT; - g_ole_initialized_init(); - check_nano_server(); - - com_vtbl.QueryInterface = QueryInterface; - com_vtbl.AddRef = AddRef; - com_vtbl.Release = Release; - com_vtbl.GetTypeInfoCount = GetTypeInfoCount; - com_vtbl.GetTypeInfo = GetTypeInfo; - com_vtbl.GetIDsOfNames = GetIDsOfNames; - com_vtbl.Invoke = Invoke; - - message_filter.QueryInterface = mf_QueryInterface; - message_filter.AddRef = mf_AddRef; - message_filter.Release = mf_Release; - message_filter.HandleInComingCall = mf_HandleInComingCall; - message_filter.RetryRejectedCall = mf_RetryRejectedCall; - message_filter.MessagePending = mf_MessagePending; - - enc2cp_hash = TypedData_Wrap_Struct(0, &win32ole_hash_datatype, 0); - RTYPEDDATA_DATA(enc2cp_hash) = st_init_numtable(); - rb_gc_register_mark_object(enc2cp_hash); - - com_hash = TypedData_Wrap_Struct(0, &win32ole_hash_datatype, 0); - RTYPEDDATA_DATA(com_hash) = st_init_numtable(); - rb_gc_register_mark_object(com_hash); - - cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject); - - rb_define_alloc_func(cWIN32OLE, fole_s_allocate); - - rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1); - - rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1); - rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1); - - rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1); - rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1); - rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1); - rb_define_singleton_method(cWIN32OLE, "codepage", fole_s_get_code_page, 0); - rb_define_singleton_method(cWIN32OLE, "codepage=", fole_s_set_code_page, 1); - rb_define_singleton_method(cWIN32OLE, "locale", fole_s_get_locale, 0); - rb_define_singleton_method(cWIN32OLE, "locale=", fole_s_set_locale, 1); - rb_define_singleton_method(cWIN32OLE, "create_guid", fole_s_create_guid, 0); - rb_define_singleton_method(cWIN32OLE, "ole_initialize", fole_s_ole_initialize, 0); - rb_define_singleton_method(cWIN32OLE, "ole_uninitialize", fole_s_ole_uninitialize, 0); - - rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1); - rb_define_method(cWIN32OLE, "[]", fole_getproperty_with_bracket, -1); - rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3); - rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3); - rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3); - - /* support propput method that takes an argument */ - rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1); - - rb_define_method(cWIN32OLE, "ole_free", fole_free, 0); - - rb_define_method(cWIN32OLE, "each", fole_each, 0); - rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1); - - /* support setproperty method much like Perl ;-) */ - rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1); - - rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0); - rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0); - rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0); - rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0); - - rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1); - rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method"); - rb_define_method(cWIN32OLE, "ole_activex_initialize", fole_activex_initialize, 0); - rb_define_method(cWIN32OLE, "ole_type", fole_type, 0); - rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type"); - rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0); - rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1); - rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1); - - /* Constants definition */ - - /* - * Version string of WIN32OLE. - */ - rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION)); - - /* - * After invoking OLE methods with reference arguments, you can access - * the value of arguments by using ARGV. - * - * If the method of OLE(COM) server written by C#.NET is following: - * - * void calcsum(int a, int b, out int c) { - * c = a + b; - * } - * - * then, the Ruby OLE(COM) client script to retrieve the value of - * argument c after invoking calcsum method is following: - * - * a = 10 - * b = 20 - * c = 0 - * comserver.calcsum(a, b, c) - * p c # => 0 - * p WIN32OLE::ARGV # => [10, 20, 30] - * - * You can use WIN32OLE_VARIANT object to retrieve the value of reference - * arguments instead of referring WIN32OLE::ARGV. - * - */ - rb_define_const(cWIN32OLE, "ARGV", rb_ary_new()); - - /* - * 0: ANSI code page. See WIN32OLE.codepage and WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_ACP", RB_INT2FIX(CP_ACP)); - - /* - * 1: OEM code page. See WIN32OLE.codepage and WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_OEMCP", RB_INT2FIX(CP_OEMCP)); - - /* - * 2 - */ - rb_define_const(cWIN32OLE, "CP_MACCP", RB_INT2FIX(CP_MACCP)); - - /* - * 3: current thread ANSI code page. See WIN32OLE.codepage and - * WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_THREAD_ACP", RB_INT2FIX(CP_THREAD_ACP)); - - /* - * 42: symbol code page. See WIN32OLE.codepage and WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_SYMBOL", RB_INT2FIX(CP_SYMBOL)); - - /* - * 65000: UTF-7 code page. See WIN32OLE.codepage and WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_UTF7", RB_INT2FIX(CP_UTF7)); - - /* - * 65001: UTF-8 code page. See WIN32OLE.codepage and WIN32OLE.codepage=. - */ - rb_define_const(cWIN32OLE, "CP_UTF8", RB_INT2FIX(CP_UTF8)); - - /* - * 0x0800: default locale for the operating system. See WIN32OLE.locale - * and WIN32OLE.locale=. - */ - rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", RB_INT2FIX(LOCALE_SYSTEM_DEFAULT)); - - /* - * 0x0400: default locale for the user or process. See WIN32OLE.locale - * and WIN32OLE.locale=. - */ - rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", RB_INT2FIX(LOCALE_USER_DEFAULT)); - - Init_win32ole_variant_m(); - Init_win32ole_typelib(); - Init_win32ole_type(); - Init_win32ole_variable(); - Init_win32ole_method(); - Init_win32ole_param(); - Init_win32ole_event(); - Init_win32ole_variant(); - Init_win32ole_record(); - Init_win32ole_error(); - - ole_init_cp(); -} diff --git a/ext/win32ole/win32ole.gemspec b/ext/win32ole/win32ole.gemspec deleted file mode 100644 index 021625e44e..0000000000 --- a/ext/win32ole/win32ole.gemspec +++ /dev/null @@ -1,21 +0,0 @@ -Gem::Specification.new do |spec| - spec.name = "win32ole" - spec.version = "1.8.8" - spec.authors = ["Masaki Suketa"] - spec.email = ["suke@ruby-lang.org"] - - spec.summary = %q{Provides an interface for OLE Automation in Ruby} - spec.description = spec.summary - spec.homepage = "https://github.com/ruby/win32ole" - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") - - spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = spec.homepage - - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - end - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] -end diff --git a/ext/win32ole/win32ole.h b/ext/win32ole/win32ole.h deleted file mode 100644 index cd627ef765..0000000000 --- a/ext/win32ole/win32ole.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef WIN32OLE_H -#define WIN32OLE_H 1 -#include "ruby/ruby.h" -#include "ruby/st.h" -#include "ruby/encoding.h" - -#define GNUC_OLDER_3_4_4 \ - ((__GNUC__ < 3) || \ - ((__GNUC__ <= 3) && (__GNUC_MINOR__ < 4)) || \ - ((__GNUC__ <= 3) && (__GNUC_MINOR__ <= 4) && (__GNUC_PATCHLEVEL__ <= 4))) - -#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4) -#ifndef NONAMELESSUNION -#define NONAMELESSUNION 1 -#endif -#endif - -#include <ctype.h> - -#include <windows.h> -#include <ocidl.h> -#include <olectl.h> -#include <ole2.h> -#if defined(HAVE_TYPE_IMULTILANGUAGE2) || defined(HAVE_TYPE_IMULTILANGUAGE) -#include <mlang.h> -#endif -#include <stdlib.h> -#include <math.h> -#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 -#include <objidl.h> - -#define DOUT fprintf(stderr,"%s(%d)\n", __FILE__, __LINE__) -#define DOUTS(x) fprintf(stderr,"%s(%d):" #x "=%s\n",__FILE__, __LINE__,x) -#define DOUTMSG(x) fprintf(stderr, "%s(%d):" #x "\n",__FILE__, __LINE__) -#define DOUTI(x) fprintf(stderr, "%s(%d):" #x "=%d\n",__FILE__, __LINE__,x) -#define DOUTD(x) fprintf(stderr, "%s(%d):" #x "=%f\n",__FILE__, __LINE__,x) - -#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4) -#define V_UNION1(X, Y) ((X)->u.Y) -#else -#define V_UNION1(X, Y) ((X)->Y) -#endif - -#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4) -#undef V_UNION -#define V_UNION(X,Y) ((X)->n1.n2.n3.Y) - -#undef V_VT -#define V_VT(X) ((X)->n1.n2.vt) - -#undef V_BOOL -#define V_BOOL(X) V_UNION(X,boolVal) -#endif - -#ifndef V_I1REF -#define V_I1REF(X) V_UNION(X, pcVal) -#endif - -#ifndef V_UI2REF -#define V_UI2REF(X) V_UNION(X, puiVal) -#endif - -#ifndef V_INT -#define V_INT(X) V_UNION(X, intVal) -#endif - -#ifndef V_INTREF -#define V_INTREF(X) V_UNION(X, pintVal) -#endif - -#ifndef V_UINT -#define V_UINT(X) V_UNION(X, uintVal) -#endif - -#ifndef V_UINTREF -#define V_UINTREF(X) V_UNION(X, puintVal) -#endif - -#ifdef HAVE_LONG_LONG -#define I8_2_NUM LL2NUM -#define UI8_2_NUM ULL2NUM -#define NUM2I8 RB_NUM2LL -#define NUM2UI8 RB_NUM2ULL -#else -#define I8_2_NUM RB_INT2NUM -#define UI8_2_NUM RB_UINT2NUM -#define NUM2I8 RB_NUM2INT -#define NUM2UI8 RB_NUM2UINT -#endif - -#define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0 -#define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0 -#define OLE_FREE(x) {\ - if(ole_initialized() == TRUE) {\ - if(x) {\ - OLE_RELEASE(x);\ - (x) = 0;\ - }\ - }\ -} - -#define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y))) -#define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y))) - -struct oledata { - IDispatch *pDispatch; -}; - -extern VALUE cWIN32OLE; -extern LCID cWIN32OLE_lcid; - -struct oledata *oledata_get_struct(VALUE obj); -LPWSTR ole_vstr2wc(VALUE vstr); -LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey); -LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey); -VALUE reg_enum_key(HKEY hkey, DWORD i); -VALUE reg_get_val(HKEY hkey, const char *subkey); -VALUE reg_get_val2(HKEY hkey, const char *subkey); -void ole_initialize(void); -VALUE default_inspect(VALUE self, const char *class_name); -char *ole_wc2mb(LPWSTR pw); -VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree); - -#define WC2VSTR(x) ole_wc2vstr((x), TRUE) - -BOOL ole_initialized(void); -HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile); -VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); -VALUE make_inspect(const char *class_name, VALUE detail); -void ole_val2variant(VALUE val, VARIANT *var); -void ole_val2variant2(VALUE val, VARIANT *var); -void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt); -VALUE ole_variant2val(VARIANT *pvar); -HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt); -VOID *val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt); -HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib); - -#include "win32ole_variant_m.h" -#include "win32ole_typelib.h" -#include "win32ole_type.h" -#include "win32ole_variable.h" -#include "win32ole_method.h" -#include "win32ole_param.h" -#include "win32ole_event.h" -#include "win32ole_variant.h" -#include "win32ole_record.h" -#include "win32ole_error.h" - -#endif diff --git a/ext/win32ole/win32ole_error.c b/ext/win32ole/win32ole_error.c deleted file mode 100644 index 2bb5156263..0000000000 --- a/ext/win32ole/win32ole_error.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "win32ole.h" - -static VALUE ole_hresult2msg(HRESULT hr); - -static VALUE -ole_hresult2msg(HRESULT hr) -{ - VALUE msg = Qnil; - char *p_msg = NULL; - char *term = NULL; - DWORD dwCount; - - char strhr[100]; - sprintf(strhr, " HRESULT error code:0x%08x\n ", (unsigned)hr); - msg = rb_str_new2(strhr); - dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, hr, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPTSTR)&p_msg, 0, NULL); - if (dwCount == 0) { - dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, hr, cWIN32OLE_lcid, - (LPTSTR)&p_msg, 0, NULL); - } - if (dwCount > 0) { - term = p_msg + strlen(p_msg); - while (p_msg < term) { - term--; - if (*term == '\r' || *term == '\n') - *term = '\0'; - else break; - } - if (p_msg[0] != '\0') { - rb_str_cat2(msg, p_msg); - } - } - LocalFree(p_msg); - return msg; -} - -void -ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...) -{ - va_list args; - VALUE msg; - VALUE err_msg; - va_init_list(args, fmt); - msg = rb_vsprintf(fmt, args); - va_end(args); - - err_msg = ole_hresult2msg(hr); - if(err_msg != Qnil) { - rb_str_cat2(msg, "\n"); - rb_str_append(msg, err_msg); - } - rb_exc_raise(rb_exc_new_str(ecs, msg)); -} - -VALUE eWIN32OLERuntimeError; -VALUE eWIN32OLEQueryInterfaceError; - -void -Init_win32ole_error(void) -{ - /* - * Document-class: WIN32OLERuntimeError - * - * Raised when OLE processing failed. - * - * EX: - * - * obj = WIN32OLE.new("NonExistProgID") - * - * raises the exception: - * - * WIN32OLERuntimeError: unknown OLE server: `NonExistProgID' - * HRESULT error code:0x800401f3 - * Invalid class string - * - */ - eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError); - eWIN32OLEQueryInterfaceError = rb_define_class("WIN32OLEQueryInterfaceError", eWIN32OLERuntimeError); -} diff --git a/ext/win32ole/win32ole_error.h b/ext/win32ole/win32ole_error.h deleted file mode 100644 index a2f329856f..0000000000 --- a/ext/win32ole/win32ole_error.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef WIN32OLE_ERROR_H -#define WIN32OLE_ERROR_H 1 - -extern VALUE eWIN32OLERuntimeError; -extern VALUE eWIN32OLEQueryInterfaceError; -NORETURN(PRINTF_ARGS(void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...), 3, 4)); -void Init_win32ole_error(void); - -#endif diff --git a/ext/win32ole/win32ole_event.c b/ext/win32ole/win32ole_event.c deleted file mode 100644 index 041639af6c..0000000000 --- a/ext/win32ole/win32ole_event.c +++ /dev/null @@ -1,1277 +0,0 @@ -#include "win32ole.h" - -/* - * Document-class: WIN32OLE_EVENT - * - * <code>WIN32OLE_EVENT</code> objects controls OLE event. - */ - -RUBY_EXTERN void rb_write_error_str(VALUE mesg); - -typedef struct { - struct IEventSinkVtbl * lpVtbl; -} IEventSink, *PEVENTSINK; - -typedef struct IEventSinkVtbl IEventSinkVtbl; - -struct IEventSinkVtbl { - STDMETHOD(QueryInterface)( - PEVENTSINK, - REFIID, - LPVOID *); - STDMETHOD_(ULONG, AddRef)(PEVENTSINK); - STDMETHOD_(ULONG, Release)(PEVENTSINK); - - STDMETHOD(GetTypeInfoCount)( - PEVENTSINK, - UINT *); - STDMETHOD(GetTypeInfo)( - PEVENTSINK, - UINT, - LCID, - ITypeInfo **); - STDMETHOD(GetIDsOfNames)( - PEVENTSINK, - REFIID, - OLECHAR **, - UINT, - LCID, - DISPID *); - STDMETHOD(Invoke)( - PEVENTSINK, - DISPID, - REFIID, - LCID, - WORD, - DISPPARAMS *, - VARIANT *, - EXCEPINFO *, - UINT *); -}; - -typedef struct tagIEVENTSINKOBJ { - const IEventSinkVtbl *lpVtbl; - DWORD m_cRef; - IID m_iid; - long m_event_id; - ITypeInfo *pTypeInfo; -}IEVENTSINKOBJ, *PIEVENTSINKOBJ; - -struct oleeventdata { - DWORD dwCookie; - IConnectionPoint *pConnectionPoint; - IDispatch *pDispatch; - long event_id; -}; - -static VALUE ary_ole_event; -static ID id_events; - -VALUE cWIN32OLE_EVENT; - -STDMETHODIMP EVENTSINK_QueryInterface(PEVENTSINK, REFIID, LPVOID*); -STDMETHODIMP_(ULONG) EVENTSINK_AddRef(PEVENTSINK); -STDMETHODIMP_(ULONG) EVENTSINK_Release(PEVENTSINK); -STDMETHODIMP EVENTSINK_GetTypeInfoCount(PEVENTSINK, UINT*); -STDMETHODIMP EVENTSINK_GetTypeInfo(PEVENTSINK, UINT, LCID, ITypeInfo**); -STDMETHODIMP EVENTSINK_GetIDsOfNames(PEVENTSINK, REFIID, OLECHAR**, UINT, LCID, DISPID*); -STDMETHODIMP EVENTSINK_Invoke(PEVENTSINK, DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*); - -static const IEventSinkVtbl vtEventSink = { - EVENTSINK_QueryInterface, - EVENTSINK_AddRef, - EVENTSINK_Release, - EVENTSINK_GetTypeInfoCount, - EVENTSINK_GetTypeInfo, - EVENTSINK_GetIDsOfNames, - EVENTSINK_Invoke, -}; - -void EVENTSINK_Destructor(PIEVENTSINKOBJ); -static void ole_val2ptr_variant(VALUE val, VARIANT *var); -static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams); -static VALUE hash2result(VALUE hash); -static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams); -static VALUE exec_callback(VALUE arg); -static VALUE rescue_callback(VALUE arg); -static HRESULT find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo); -static HRESULT find_coclass(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **pTypeInfo2, TYPEATTR **pTypeAttr2); -static HRESULT find_default_source_from_typeinfo(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **ppTypeInfo); -static HRESULT find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo); -static long ole_search_event_at(VALUE ary, VALUE ev); -static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default); -static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler); -static void ole_delete_event(VALUE ary, VALUE ev); -static void oleevent_free(void *ptr); -static size_t oleevent_size(const void *ptr); -static VALUE fev_s_allocate(VALUE klass); -static VALUE ev_advise(int argc, VALUE *argv, VALUE self); -static VALUE fev_initialize(int argc, VALUE *argv, VALUE self); -static void ole_msg_loop(void); -static VALUE fev_s_msg_loop(VALUE klass); -static void add_event_call_back(VALUE obj, VALUE event, VALUE data); -static VALUE ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg); -static VALUE fev_on_event(int argc, VALUE *argv, VALUE self); -static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self); -static VALUE fev_off_event(int argc, VALUE *argv, VALUE self); -static VALUE fev_unadvise(VALUE self); -static VALUE fev_set_handler(VALUE self, VALUE val); -static VALUE fev_get_handler(VALUE self); -static VALUE evs_push(VALUE ev); -static VALUE evs_delete(long i); -static VALUE evs_entry(long i); -static long evs_length(void); - - -static const rb_data_type_t oleevent_datatype = { - "win32ole_event", - {NULL, oleevent_free, oleevent_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -STDMETHODIMP EVENTSINK_Invoke( - PEVENTSINK pEventSink, - DISPID dispid, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS *pdispparams, - VARIANT *pvarResult, - EXCEPINFO *pexcepinfo, - UINT *puArgErr - ) { - - HRESULT hr; - BSTR bstr; - unsigned int count; - unsigned int i; - ITypeInfo *pTypeInfo; - VARIANT *pvar; - VALUE ary, obj, event, args, outargv, ev, result; - VALUE handler = Qnil; - VALUE arg[3]; - VALUE mid; - VALUE is_outarg = Qfalse; - BOOL is_default_handler = FALSE; - int state; - - PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink; - pTypeInfo = pEV->pTypeInfo; - obj = evs_entry(pEV->m_event_id); - if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) { - return NOERROR; - } - - ary = rb_ivar_get(obj, id_events); - if (NIL_P(ary) || !RB_TYPE_P(ary, T_ARRAY)) { - return NOERROR; - } - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid, - &bstr, 1, &count); - if (FAILED(hr)) { - return NOERROR; - } - ev = WC2VSTR(bstr); - event = ole_search_event(ary, ev, &is_default_handler); - if (RB_TYPE_P(event, T_ARRAY)) { - handler = rb_ary_entry(event, 0); - mid = rb_intern("call"); - is_outarg = rb_ary_entry(event, 3); - } else { - handler = rb_ivar_get(obj, rb_intern("handler")); - if (handler == Qnil) { - return NOERROR; - } - mid = ole_search_handler_method(handler, ev, &is_default_handler); - } - if (handler == Qnil || mid == Qnil) { - return NOERROR; - } - - args = rb_ary_new(); - if (is_default_handler) { - rb_ary_push(args, ev); - } - - /* make argument of event handler */ - for (i = 0; i < pdispparams->cArgs; ++i) { - pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; - rb_ary_push(args, ole_variant2val(pvar)); - } - outargv = Qnil; - if (is_outarg == Qtrue) { - outargv = rb_ary_new(); - rb_ary_push(args, outargv); - } - - /* - * if exception raised in event callback, - * then you receive cfp consistency error. - * to avoid this error we use begin rescue end. - * and the exception raised then error message print - * and exit ruby process by Win32OLE itself. - */ - arg[0] = handler; - arg[1] = mid; - arg[2] = args; - result = rb_protect(exec_callback, (VALUE)arg, &state); - if (state != 0) { - rescue_callback(Qnil); - } - if(RB_TYPE_P(result, T_HASH)) { - hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams); - result = hash2result(result); - }else if (is_outarg == Qtrue && RB_TYPE_P(outargv, T_ARRAY)) { - ary2ptr_dispparams(outargv, pdispparams); - } - - if (pvarResult) { - VariantInit(pvarResult); - ole_val2variant(result, pvarResult); - } - - return NOERROR; -} - -STDMETHODIMP -EVENTSINK_QueryInterface( - PEVENTSINK pEV, - REFIID iid, - LPVOID* ppv - ) { - if (IsEqualIID(iid, &IID_IUnknown) || - IsEqualIID(iid, &IID_IDispatch) || - IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) { - *ppv = pEV; - } - else { - *ppv = NULL; - return E_NOINTERFACE; - } - ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv); - return NOERROR; -} - -STDMETHODIMP_(ULONG) -EVENTSINK_AddRef( - PEVENTSINK pEV - ){ - PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV; - return ++pEVObj->m_cRef; -} - -STDMETHODIMP_(ULONG) EVENTSINK_Release( - PEVENTSINK pEV - ) { - PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV; - --pEVObj->m_cRef; - if(pEVObj->m_cRef != 0) - return pEVObj->m_cRef; - EVENTSINK_Destructor(pEVObj); - return 0; -} - -STDMETHODIMP EVENTSINK_GetTypeInfoCount( - PEVENTSINK pEV, - UINT *pct - ) { - *pct = 0; - return NOERROR; -} - -STDMETHODIMP EVENTSINK_GetTypeInfo( - PEVENTSINK pEV, - UINT info, - LCID lcid, - ITypeInfo **pInfo - ) { - *pInfo = NULL; - return DISP_E_BADINDEX; -} - -STDMETHODIMP EVENTSINK_GetIDsOfNames( - PEVENTSINK pEventSink, - REFIID riid, - OLECHAR **szNames, - UINT cNames, - LCID lcid, - DISPID *pDispID - ) { - ITypeInfo *pTypeInfo; - PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink; - pTypeInfo = pEV->pTypeInfo; - if (pTypeInfo) { - return pTypeInfo->lpVtbl->GetIDsOfNames(pTypeInfo, szNames, cNames, pDispID); - } - return DISP_E_UNKNOWNNAME; -} - -PIEVENTSINKOBJ -EVENTSINK_Constructor(void) -{ - PIEVENTSINKOBJ pEv; - pEv = ALLOC_N(IEVENTSINKOBJ, 1); - if(pEv == NULL) return NULL; - pEv->lpVtbl = &vtEventSink; - pEv->m_cRef = 0; - pEv->m_event_id = 0; - pEv->pTypeInfo = NULL; - return pEv; -} - -void -EVENTSINK_Destructor( - PIEVENTSINKOBJ pEVObj - ) { - if(pEVObj != NULL) { - OLE_RELEASE(pEVObj->pTypeInfo); - free(pEVObj); - pEVObj = NULL; - } -} - -static void -ole_val2ptr_variant(VALUE val, VARIANT *var) -{ - switch (TYPE(val)) { - case T_STRING: - if (V_VT(var) == (VT_BSTR | VT_BYREF)) { - *V_BSTRREF(var) = ole_vstr2wc(val); - } - break; - case T_FIXNUM: - switch(V_VT(var)) { - case (VT_UI1 | VT_BYREF) : - *V_UI1REF(var) = RB_NUM2CHR(val); - break; - case (VT_I2 | VT_BYREF) : - *V_I2REF(var) = (short)RB_NUM2INT(val); - break; - case (VT_I4 | VT_BYREF) : - *V_I4REF(var) = RB_NUM2INT(val); - break; - case (VT_R4 | VT_BYREF) : - *V_R4REF(var) = (float)RB_NUM2INT(val); - break; - case (VT_R8 | VT_BYREF) : - *V_R8REF(var) = RB_NUM2INT(val); - break; - default: - break; - } - break; - case T_FLOAT: - switch(V_VT(var)) { - case (VT_I2 | VT_BYREF) : - *V_I2REF(var) = (short)RB_NUM2INT(val); - break; - case (VT_I4 | VT_BYREF) : - *V_I4REF(var) = RB_NUM2INT(val); - break; - case (VT_R4 | VT_BYREF) : - *V_R4REF(var) = (float)NUM2DBL(val); - break; - case (VT_R8 | VT_BYREF) : - *V_R8REF(var) = NUM2DBL(val); - break; - default: - break; - } - break; - case T_BIGNUM: - if (V_VT(var) == (VT_R8 | VT_BYREF)) { - *V_R8REF(var) = rb_big2dbl(val); - } - break; - case T_TRUE: - if (V_VT(var) == (VT_BOOL | VT_BYREF)) { - *V_BOOLREF(var) = VARIANT_TRUE; - } - break; - case T_FALSE: - if (V_VT(var) == (VT_BOOL | VT_BYREF)) { - *V_BOOLREF(var) = VARIANT_FALSE; - } - break; - default: - break; - } -} - -static void -hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams) -{ - BSTR *bstrs; - HRESULT hr; - UINT len, i; - VARIANT *pvar; - VALUE val; - VALUE key; - len = 0; - bstrs = ALLOCA_N(BSTR, pdispparams->cArgs + 1); - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid, - bstrs, pdispparams->cArgs + 1, - &len); - if (FAILED(hr)) - return; - - for (i = 0; i < len - 1; i++) { - key = WC2VSTR(bstrs[i + 1]); - val = rb_hash_aref(hash, RB_UINT2NUM(i)); - if (val == Qnil) - val = rb_hash_aref(hash, key); - if (val == Qnil) - val = rb_hash_aref(hash, rb_str_intern(key)); - pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; - ole_val2ptr_variant(val, pvar); - } -} - -static VALUE -hash2result(VALUE hash) -{ - VALUE ret = Qnil; - ret = rb_hash_aref(hash, rb_str_new2("return")); - if (ret == Qnil) - ret = rb_hash_aref(hash, rb_str_intern(rb_str_new2("return"))); - return ret; -} - -static void -ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams) -{ - int i; - VALUE v; - VARIANT *pvar; - for(i = 0; i < RARRAY_LEN(ary) && (unsigned int) i < pdispparams->cArgs; i++) { - v = rb_ary_entry(ary, i); - pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; - ole_val2ptr_variant(v, pvar); - } -} - -static VALUE -exec_callback(VALUE arg) -{ - VALUE *parg = (VALUE *)arg; - VALUE handler = parg[0]; - VALUE mid = parg[1]; - VALUE args = parg[2]; - return rb_apply(handler, mid, args); -} - -static VALUE -rescue_callback(VALUE arg) -{ - - VALUE error; - VALUE e = rb_errinfo(); - VALUE bt = rb_funcall(e, rb_intern("backtrace"), 0); - VALUE msg = rb_funcall(e, rb_intern("message"), 0); - bt = rb_ary_entry(bt, 0); - error = rb_sprintf("%"PRIsVALUE": %"PRIsVALUE" (%s)\n", bt, msg, rb_obj_classname(e)); - rb_write_error_str(error); - rb_backtrace(); - ruby_finalize(); - exit(-1); - - return Qnil; -} - -static HRESULT -find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo) -{ - HRESULT hr; - IDispatch *pDispatch; - ITypeInfo *pTypeInfo; - ITypeLib *pTypeLib; - TYPEATTR *pTypeAttr; - HREFTYPE RefType; - ITypeInfo *pImplTypeInfo; - TYPEATTR *pImplTypeAttr; - - struct oledata *pole = NULL; - unsigned int index; - unsigned int count; - int type; - BSTR bstr; - char *pstr; - - BOOL is_found = FALSE; - LCID lcid = cWIN32OLE_lcid; - - pole = oledata_get_struct(ole); - - pDispatch = pole->pDispatch; - - hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo); - if (FAILED(hr)) - return hr; - - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, - &pTypeLib, - &index); - OLE_RELEASE(pTypeInfo); - if (FAILED(hr)) - return hr; - - if (!pitf) { - hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib, - piid, - ppTypeInfo); - OLE_RELEASE(pTypeLib); - return hr; - } - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (index = 0; index < count; index++) { - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, - index, - &pTypeInfo); - if (FAILED(hr)) - break; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - - if(FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - break; - } - if(pTypeAttr->typekind == TKIND_COCLASS) { - for (type = 0; type < pTypeAttr->cImplTypes; type++) { - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, - type, - &RefType); - if (FAILED(hr)) - break; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, - RefType, - &pImplTypeInfo); - if (FAILED(hr)) - break; - - hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo, - -1, - &bstr, - NULL, NULL, NULL); - if (FAILED(hr)) { - OLE_RELEASE(pImplTypeInfo); - break; - } - pstr = ole_wc2mb(bstr); - if (strcmp(pitf, pstr) == 0) { - hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo, - &pImplTypeAttr); - if (SUCCEEDED(hr)) { - is_found = TRUE; - *piid = pImplTypeAttr->guid; - if (ppTypeInfo) { - *ppTypeInfo = pImplTypeInfo; - (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo)); - } - pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo, - pImplTypeAttr); - } - } - free(pstr); - OLE_RELEASE(pImplTypeInfo); - if (is_found || FAILED(hr)) - break; - } - } - - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - OLE_RELEASE(pTypeInfo); - if (is_found || FAILED(hr)) - break; - } - OLE_RELEASE(pTypeLib); - if(!is_found) - return E_NOINTERFACE; - return hr; -} - -static HRESULT -find_coclass( - ITypeInfo *pTypeInfo, - TYPEATTR *pTypeAttr, - ITypeInfo **pCOTypeInfo, - TYPEATTR **pCOTypeAttr) -{ - HRESULT hr = E_NOINTERFACE; - ITypeLib *pTypeLib; - int count; - BOOL found = FALSE; - ITypeInfo *pTypeInfo2; - TYPEATTR *pTypeAttr2; - int flags; - int i,j; - HREFTYPE href; - ITypeInfo *pRefTypeInfo; - TYPEATTR *pRefTypeAttr; - - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL); - if (FAILED(hr)) { - return hr; - } - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count && !found; i++) { - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2); - if (FAILED(hr)) - continue; - hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2); - if (FAILED(hr)) { - OLE_RELEASE(pTypeInfo2); - continue; - } - if (pTypeAttr2->typekind != TKIND_COCLASS) { - OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2); - OLE_RELEASE(pTypeInfo2); - continue; - } - for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) { - hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags); - if (FAILED(hr)) - continue; - if (!(flags & IMPLTYPEFLAG_FDEFAULT)) - continue; - hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href); - if (FAILED(hr)) - continue; - hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo); - if (FAILED(hr)) - continue; - hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr); - if (FAILED(hr)) { - OLE_RELEASE(pRefTypeInfo); - continue; - } - if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) { - found = TRUE; - } - } - if (!found) { - OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2); - OLE_RELEASE(pTypeInfo2); - } - } - OLE_RELEASE(pTypeLib); - if (found) { - *pCOTypeInfo = pTypeInfo2; - *pCOTypeAttr = pTypeAttr2; - hr = S_OK; - } else { - hr = E_NOINTERFACE; - } - return hr; -} - -static HRESULT -find_default_source_from_typeinfo( - ITypeInfo *pTypeInfo, - TYPEATTR *pTypeAttr, - ITypeInfo **ppTypeInfo) -{ - int i = 0; - HRESULT hr = E_NOINTERFACE; - int flags; - HREFTYPE hRefType; - /* Enumerate all implemented types of the COCLASS */ - for (i = 0; i < pTypeAttr->cImplTypes; i++) { - hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags); - if (FAILED(hr)) - continue; - - /* - looking for the [default] [source] - we just hope that it is a dispinterface :-) - */ - if ((flags & IMPLTYPEFLAG_FDEFAULT) && - (flags & IMPLTYPEFLAG_FSOURCE)) { - - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, - i, &hRefType); - if (FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, - hRefType, ppTypeInfo); - if (SUCCEEDED(hr)) - break; - } - } - return hr; -} - -static HRESULT -find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo) -{ - HRESULT hr; - IProvideClassInfo2 *pProvideClassInfo2; - IProvideClassInfo *pProvideClassInfo; - void *p; - - IDispatch *pDispatch; - ITypeInfo *pTypeInfo; - ITypeInfo *pTypeInfo2 = NULL; - TYPEATTR *pTypeAttr; - TYPEATTR *pTypeAttr2 = NULL; - - struct oledata *pole = NULL; - - pole = oledata_get_struct(ole); - pDispatch = pole->pDispatch; - hr = pDispatch->lpVtbl->QueryInterface(pDispatch, - &IID_IProvideClassInfo2, - &p); - if (SUCCEEDED(hr)) { - pProvideClassInfo2 = p; - hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2, - GUIDKIND_DEFAULT_SOURCE_DISP_IID, - piid); - OLE_RELEASE(pProvideClassInfo2); - if (SUCCEEDED(hr)) { - hr = find_iid(ole, NULL, piid, ppTypeInfo); - } - } - if (SUCCEEDED(hr)) { - return hr; - } - hr = pDispatch->lpVtbl->QueryInterface(pDispatch, - &IID_IProvideClassInfo, - &p); - if (SUCCEEDED(hr)) { - pProvideClassInfo = p; - hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo, - &pTypeInfo); - OLE_RELEASE(pProvideClassInfo); - } - if (FAILED(hr)) { - hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, cWIN32OLE_lcid, &pTypeInfo ); - } - if (FAILED(hr)) - return hr; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - return hr; - } - - *ppTypeInfo = 0; - hr = find_default_source_from_typeinfo(pTypeInfo, pTypeAttr, ppTypeInfo); - if (!*ppTypeInfo) { - hr = find_coclass(pTypeInfo, pTypeAttr, &pTypeInfo2, &pTypeAttr2); - if (SUCCEEDED(hr)) { - hr = find_default_source_from_typeinfo(pTypeInfo2, pTypeAttr2, ppTypeInfo); - OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2); - OLE_RELEASE(pTypeInfo2); - } - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - OLE_RELEASE(pTypeInfo); - /* Now that would be a bad surprise, if we didn't find it, wouldn't it? */ - if (!*ppTypeInfo) { - if (SUCCEEDED(hr)) - hr = E_UNEXPECTED; - return hr; - } - - /* Determine IID of default source interface */ - hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr); - if (SUCCEEDED(hr)) { - *piid = pTypeAttr->guid; - (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr); - } - else - OLE_RELEASE(*ppTypeInfo); - - return hr; -} - -static long -ole_search_event_at(VALUE ary, VALUE ev) -{ - VALUE event; - VALUE event_name; - long i, len; - long ret = -1; - len = RARRAY_LEN(ary); - for(i = 0; i < len; i++) { - event = rb_ary_entry(ary, i); - event_name = rb_ary_entry(event, 1); - if(NIL_P(event_name) && NIL_P(ev)) { - ret = i; - break; - } - else if (RB_TYPE_P(ev, T_STRING) && - RB_TYPE_P(event_name, T_STRING) && - rb_str_cmp(ev, event_name) == 0) { - ret = i; - break; - } - } - return ret; -} - -static VALUE -ole_search_event(VALUE ary, VALUE ev, BOOL *is_default) -{ - VALUE event; - VALUE def_event; - VALUE event_name; - int i, len; - *is_default = FALSE; - def_event = Qnil; - len = RARRAY_LEN(ary); - for(i = 0; i < len; i++) { - event = rb_ary_entry(ary, i); - event_name = rb_ary_entry(event, 1); - if(NIL_P(event_name)) { - *is_default = TRUE; - def_event = event; - } - else if (rb_str_cmp(ev, event_name) == 0) { - *is_default = FALSE; - return event; - } - } - return def_event; -} - -static VALUE -ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler) -{ - VALUE mid; - - *is_default_handler = FALSE; - mid = rb_to_id(rb_sprintf("on%"PRIsVALUE, ev)); - if (rb_respond_to(handler, mid)) { - return mid; - } - mid = rb_intern("method_missing"); - if (rb_respond_to(handler, mid)) { - *is_default_handler = TRUE; - return mid; - } - return Qnil; -} - -static void -ole_delete_event(VALUE ary, VALUE ev) -{ - long at = -1; - at = ole_search_event_at(ary, ev); - if (at >= 0) { - rb_ary_delete_at(ary, at); - } -} - - -static void -oleevent_free(void *ptr) -{ - struct oleeventdata *poleev = ptr; - if (poleev->pConnectionPoint) { - poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie); - OLE_RELEASE(poleev->pConnectionPoint); - poleev->pConnectionPoint = NULL; - } - OLE_RELEASE(poleev->pDispatch); - free(poleev); -} - -static size_t -oleevent_size(const void *ptr) -{ - return ptr ? sizeof(struct oleeventdata) : 0; -} - -static VALUE -fev_s_allocate(VALUE klass) -{ - VALUE obj; - struct oleeventdata *poleev; - obj = TypedData_Make_Struct(klass, struct oleeventdata, &oleevent_datatype, poleev); - poleev->dwCookie = 0; - poleev->pConnectionPoint = NULL; - poleev->event_id = 0; - poleev->pDispatch = NULL; - return obj; -} - -static VALUE -ev_advise(int argc, VALUE *argv, VALUE self) -{ - - VALUE ole, itf; - struct oledata *pole = NULL; - char *pitf; - HRESULT hr; - IID iid; - ITypeInfo *pTypeInfo = 0; - IDispatch *pDispatch; - IConnectionPointContainer *pContainer; - IConnectionPoint *pConnectionPoint; - IEVENTSINKOBJ *pIEV; - DWORD dwCookie; - struct oleeventdata *poleev; - void *p; - - rb_scan_args(argc, argv, "11", &ole, &itf); - - if (!rb_obj_is_kind_of(ole, cWIN32OLE)) { - rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE object"); - } - - if(!RB_TYPE_P(itf, T_NIL)) { - pitf = StringValuePtr(itf); - hr = find_iid(ole, pitf, &iid, &pTypeInfo); - } - else { - hr = find_default_source(ole, &iid, &pTypeInfo); - } - if (FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "interface not found"); - } - - pole = oledata_get_struct(ole); - pDispatch = pole->pDispatch; - hr = pDispatch->lpVtbl->QueryInterface(pDispatch, - &IID_IConnectionPointContainer, - &p); - if (FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - ole_raise(hr, eWIN32OLEQueryInterfaceError, - "failed to query IConnectionPointContainer"); - } - pContainer = p; - - hr = pContainer->lpVtbl->FindConnectionPoint(pContainer, - &iid, - &pConnectionPoint); - OLE_RELEASE(pContainer); - if (FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to query IConnectionPoint"); - } - pIEV = EVENTSINK_Constructor(); - pIEV->m_iid = iid; - hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint, - (IUnknown*)pIEV, - &dwCookie); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "Advise Error"); - } - - TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev); - pIEV->m_event_id = evs_length(); - pIEV->pTypeInfo = pTypeInfo; - poleev->dwCookie = dwCookie; - poleev->pConnectionPoint = pConnectionPoint; - poleev->event_id = pIEV->m_event_id; - poleev->pDispatch = pDispatch; - OLE_ADDREF(pDispatch); - - return self; -} - -/* - * call-seq: - * WIN32OLE_EVENT.new(ole, event) #=> WIN32OLE_EVENT object. - * - * Returns OLE event object. - * The first argument specifies WIN32OLE object. - * The second argument specifies OLE event name. - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents') - */ -static VALUE -fev_initialize(int argc, VALUE *argv, VALUE self) -{ - ev_advise(argc, argv, self); - evs_push(self); - rb_ivar_set(self, id_events, rb_ary_new()); - fev_set_handler(self, Qnil); - return self; -} - -static void -ole_msg_loop(void) -{ - MSG msg; - while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -/* - * call-seq: - * WIN32OLE_EVENT.message_loop - * - * Translates and dispatches Windows message. - */ -static VALUE -fev_s_msg_loop(VALUE klass) -{ - ole_msg_loop(); - return Qnil; -} - -static void -add_event_call_back(VALUE obj, VALUE event, VALUE data) -{ - VALUE events = rb_ivar_get(obj, id_events); - if (NIL_P(events) || !RB_TYPE_P(events, T_ARRAY)) { - events = rb_ary_new(); - rb_ivar_set(obj, id_events, events); - } - ole_delete_event(events, event); - rb_ary_push(events, data); -} - -static VALUE -ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg) -{ - struct oleeventdata *poleev; - VALUE event, args, data; - TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev); - if (poleev->pConnectionPoint == NULL) { - rb_raise(eWIN32OLERuntimeError, "IConnectionPoint not found. You must call advise at first."); - } - rb_scan_args(argc, argv, "01*", &event, &args); - if(!NIL_P(event)) { - if(!RB_TYPE_P(event, T_STRING) && !RB_TYPE_P(event, T_SYMBOL)) { - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - if (RB_TYPE_P(event, T_SYMBOL)) { - event = rb_sym2str(event); - } - } - data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg); - add_event_call_back(self, event, data); - return Qnil; -} - -/* - * call-seq: - * WIN32OLE_EVENT#on_event([event]){...} - * - * Defines the callback event. - * If argument is omitted, this method defines the callback of all events. - * If you want to modify reference argument in callback, return hash in - * callback. If you want to return value to OLE server as result of callback - * use `return' or :return. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie) - * ev.on_event("NavigateComplete") {|url| puts url} - * ev.on_event() {|ev, *args| puts "#{ev} fired"} - * - * ev.on_event("BeforeNavigate2") {|*args| - * ... - * # set true to BeforeNavigate reference argument `Cancel'. - * # Cancel is 7-th argument of BeforeNavigate, - * # so you can use 6 as key of hash instead of 'Cancel'. - * # The argument is counted from 0. - * # The hash key of 0 means first argument.) - * {:Cancel => true} # or {'Cancel' => true} or {6 => true} - * } - * - * ev.on_event(...) {|*args| - * {:return => 1, :xxx => yyy} - * } - */ -static VALUE -fev_on_event(int argc, VALUE *argv, VALUE self) -{ - return ev_on_event(argc, argv, self, Qfalse); -} - -/* - * call-seq: - * WIN32OLE_EVENT#on_event_with_outargs([event]){...} - * - * Defines the callback of event. - * If you want modify argument in callback, - * you could use this method instead of WIN32OLE_EVENT#on_event. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie) - * ev.on_event_with_outargs('BeforeNavigate2') {|*args| - * args.last[6] = true - * } - */ -static VALUE -fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self) -{ - return ev_on_event(argc, argv, self, Qtrue); -} - -/* - * call-seq: - * WIN32OLE_EVENT#off_event([event]) - * - * removes the callback of event. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie) - * ev.on_event('BeforeNavigate2') {|*args| - * args.last[6] = true - * } - * ... - * ev.off_event('BeforeNavigate2') - * ... - */ -static VALUE -fev_off_event(int argc, VALUE *argv, VALUE self) -{ - VALUE event = Qnil; - VALUE events; - - rb_scan_args(argc, argv, "01", &event); - if(!NIL_P(event)) { - if(!RB_TYPE_P(event, T_STRING) && !RB_TYPE_P(event, T_SYMBOL)) { - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - if (RB_TYPE_P(event, T_SYMBOL)) { - event = rb_sym2str(event); - } - } - events = rb_ivar_get(self, id_events); - if (NIL_P(events)) { - return Qnil; - } - ole_delete_event(events, event); - return Qnil; -} - -/* - * call-seq: - * WIN32OLE_EVENT#unadvise -> nil - * - * disconnects OLE server. If this method called, then the WIN32OLE_EVENT object - * does not receive the OLE server event any more. - * This method is trial implementation. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie) - * ev.on_event() {...} - * ... - * ev.unadvise - * - */ -static VALUE -fev_unadvise(VALUE self) -{ - struct oleeventdata *poleev; - TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev); - if (poleev->pConnectionPoint) { - ole_msg_loop(); - evs_delete(poleev->event_id); - poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie); - OLE_RELEASE(poleev->pConnectionPoint); - poleev->pConnectionPoint = NULL; - } - OLE_FREE(poleev->pDispatch); - return Qnil; -} - -static VALUE -evs_push(VALUE ev) -{ - return rb_ary_push(ary_ole_event, ev); -} - -static VALUE -evs_delete(long i) -{ - rb_ary_store(ary_ole_event, i, Qnil); - return Qnil; -} - -static VALUE -evs_entry(long i) -{ - return rb_ary_entry(ary_ole_event, i); -} - -static long -evs_length(void) -{ - return RARRAY_LEN(ary_ole_event); -} - -/* - * call-seq: - * WIN32OLE_EVENT#handler= - * - * sets event handler object. If handler object has onXXX - * method according to XXX event, then onXXX method is called - * when XXX event occurs. - * - * If handler object has method_missing and there is no - * method according to the event, then method_missing - * called and 1-st argument is event name. - * - * If handler object has onXXX method and there is block - * defined by WIN32OLE_EVENT#on_event('XXX'){}, - * then block is executed but handler object method is not called - * when XXX event occurs. - * - * class Handler - * def onStatusTextChange(text) - * puts "StatusTextChanged" - * end - * def onPropertyChange(prop) - * puts "PropertyChanged" - * end - * def method_missing(ev, *arg) - * puts "other event #{ev}" - * end - * end - * - * handler = Handler.new - * ie = WIN32OLE.new('InternetExplorer.Application') - * ev = WIN32OLE_EVENT.new(ie) - * ev.on_event("StatusTextChange") {|*args| - * puts "this block executed." - * puts "handler.onStatusTextChange method is not called." - * } - * ev.handler = handler - * - */ -static VALUE -fev_set_handler(VALUE self, VALUE val) -{ - return rb_ivar_set(self, rb_intern("handler"), val); -} - -/* - * call-seq: - * WIN32OLE_EVENT#handler - * - * returns handler object. - * - */ -static VALUE -fev_get_handler(VALUE self) -{ - return rb_ivar_get(self, rb_intern("handler")); -} - -void -Init_win32ole_event(void) -{ -#undef rb_intern - ary_ole_event = rb_ary_new(); - rb_gc_register_mark_object(ary_ole_event); - id_events = rb_intern("events"); - cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject); - rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0); - rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate); - rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1); - rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1); - rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1); - rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1); - rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0); - rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1); - rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0); -} diff --git a/ext/win32ole/win32ole_event.h b/ext/win32ole/win32ole_event.h deleted file mode 100644 index f1a5aa234d..0000000000 --- a/ext/win32ole/win32ole_event.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef WIN32OLE_EVENT_H -#define WIN32OLE_EVENT_H 1 - -void Init_win32ole_event(void); - -#endif diff --git a/ext/win32ole/win32ole_method.c b/ext/win32ole/win32ole_method.c deleted file mode 100644 index bf668300c2..0000000000 --- a/ext/win32ole/win32ole_method.c +++ /dev/null @@ -1,952 +0,0 @@ -#include "win32ole.h" - -static void olemethod_free(void *ptr); -static size_t olemethod_size(const void *ptr); -static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name); -static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name); -static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask); -static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name); -static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method); -static VALUE folemethod_name(VALUE self); -static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_return_type(VALUE self); -static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_return_vtype(VALUE self); -static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_return_type_detail(VALUE self); -static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_invkind(VALUE self); -static VALUE folemethod_invoke_kind(VALUE self); -static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_visible(VALUE self); -static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name); -static VALUE folemethod_event(VALUE self); -static VALUE folemethod_event_interface(VALUE self); -static HRESULT ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile); -static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_helpstring(VALUE self); -static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_helpfile(VALUE self); -static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_helpcontext(VALUE self); -static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_dispid(VALUE self); -static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_offset_vtbl(VALUE self); -static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_size_params(VALUE self); -static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_size_opt_params(VALUE self); -static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index); -static VALUE folemethod_params(VALUE self); -static VALUE folemethod_inspect(VALUE self); - -static const rb_data_type_t olemethod_datatype = { - "win32ole_method", - {NULL, olemethod_free, olemethod_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static void -olemethod_free(void *ptr) -{ - struct olemethoddata *polemethod = ptr; - OLE_FREE(polemethod->pTypeInfo); - OLE_FREE(polemethod->pOwnerTypeInfo); - free(polemethod); -} - -static size_t -olemethod_size(const void *ptr) -{ - return ptr ? sizeof(struct olemethoddata) : 0; -} - -struct olemethoddata * -olemethod_data_get_struct(VALUE obj) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(obj, struct olemethoddata, &olemethod_datatype, pmethod); - return pmethod; -} - -static VALUE -ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - BSTR bstr; - FUNCDESC *pFuncDesc; - WORD i; - VALUE fname; - VALUE method = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr"); - } - for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) { - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc); - if (FAILED(hr)) - continue; - - hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - continue; - } - fname = WC2VSTR(bstr); - if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) { - olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname); - method = self; - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - pFuncDesc=NULL; - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return method; -} - -VALUE -ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - WORD i; - HREFTYPE href; - ITypeInfo *pRefTypeInfo; - VALUE methods = rb_ary_new(); - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr"); - } - - ole_methods_sub(0, pTypeInfo, methods, mask); - for(i=0; i < pTypeAttr->cImplTypes; i++){ - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href); - if(FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo); - if (FAILED(hr)) - continue; - ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask); - OLE_RELEASE(pRefTypeInfo); - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return methods; -} - -static VALUE -olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - WORD i; - HREFTYPE href; - ITypeInfo *pRefTypeInfo; - VALUE method = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr"); - } - method = ole_method_sub(self, 0, pTypeInfo, name); - if (method != Qnil) { - return method; - } - for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){ - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href); - if(FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo); - if (FAILED(hr)) - continue; - method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name); - OLE_RELEASE(pRefTypeInfo); - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return method; -} - -static VALUE -ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - BSTR bstr; - FUNCDESC *pFuncDesc; - VALUE method; - WORD i; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr"); - } - for(i = 0; i < pTypeAttr->cFuncs; i++) { - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc); - if (FAILED(hr)) - continue; - - hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - continue; - } - if(pFuncDesc->invkind & mask) { - method = folemethod_s_allocate(cWIN32OLE_METHOD); - olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo, - i, WC2VSTR(bstr)); - rb_ary_push(methods, method); - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - pFuncDesc=NULL; - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - - return methods; -} - -VALUE -create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name) -{ - - VALUE method = folemethod_s_allocate(cWIN32OLE_METHOD); - VALUE obj = olemethod_from_typeinfo(method, pTypeInfo, name); - return obj; -} - -/* - * Document-class: WIN32OLE_METHOD - * - * <code>WIN32OLE_METHOD</code> objects represent OLE method information. - */ - -static VALUE -olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - pmethod->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pmethod->pOwnerTypeInfo = pOwnerTypeInfo; - OLE_ADDREF(pOwnerTypeInfo); - pmethod->index = index; - rb_ivar_set(self, rb_intern("name"), name); - return self; -} - -VALUE -folemethod_s_allocate(VALUE klass) -{ - struct olemethoddata *pmethod; - VALUE obj; - obj = TypedData_Make_Struct(klass, - struct olemethoddata, - &olemethod_datatype, pmethod); - pmethod->pTypeInfo = NULL; - pmethod->pOwnerTypeInfo = NULL; - pmethod->index = 0; - return obj; -} - -/* - * call-seq: - * WIN32OLE_METHOD.new(ole_type, method) -> WIN32OLE_METHOD object - * - * Returns a new WIN32OLE_METHOD object which represents the information - * about OLE method. - * The first argument <i>ole_type</i> specifies WIN32OLE_TYPE object. - * The second argument <i>method</i> specifies OLE method name defined OLE class - * which represents WIN32OLE_TYPE object. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - */ -static VALUE -folemethod_initialize(VALUE self, VALUE oletype, VALUE method) -{ - VALUE obj = Qnil; - ITypeInfo *pTypeInfo; - if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) { - SafeStringValue(method); - pTypeInfo = itypeinfo(oletype); - obj = olemethod_from_typeinfo(self, pTypeInfo, method); - if (obj == Qnil) { - rb_raise(eWIN32OLERuntimeError, "not found %s", - StringValuePtr(method)); - } - } - else { - rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object"); - } - return obj; -} - -/* - * call-seq: - * WIN32OLE_METHOD#name - * - * Returns the name of the method. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * puts method.name # => SaveAs - * - */ -static VALUE -folemethod_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE type; - - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetFuncDesc"); - - type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_METHOD#return_type - * - * Returns string of return value type of method. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.return_type # => Workbook - * - */ -static VALUE -folemethod_return_type(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_return_type(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE vvt; - - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc"); - - vvt = RB_INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return vvt; -} - -/* - * call-seq: - * WIN32OLE_METHOD#return_vtype - * - * Returns number of return value type of method. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.return_vtype # => 26 - * - */ -static VALUE -folemethod_return_vtype(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE type = rb_ary_new(); - - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return type; - - ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_METHOD#return_type_detail - * - * Returns detail information of return value type of method. - * The information is array. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"] - */ -static VALUE -folemethod_return_type_detail(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE invkind; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if(FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc"); - invkind = RB_INT2FIX(pFuncDesc->invkind); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return invkind; -} - -static VALUE -ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index) -{ - VALUE type = rb_str_new2("UNKNOWN"); - VALUE invkind = ole_method_invkind(pTypeInfo, method_index); - if((RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) && - (RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) { - type = rb_str_new2("PROPERTY"); - } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) { - type = rb_str_new2("PROPERTYGET"); - } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) { - type = rb_str_new2("PROPERTYPUT"); - } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) { - type = rb_str_new2("PROPERTYPUTREF"); - } else if(RB_FIX2INT(invkind) & INVOKE_FUNC) { - type = rb_str_new2("FUNC"); - } - return type; -} - -/* - * call-seq: - * WIN32OLE_MTHOD#invkind - * - * Returns the method invoke kind. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.invkind # => 1 - * - */ -static VALUE -folemethod_invkind(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_invkind(pmethod->pTypeInfo, pmethod->index); -} - -/* - * call-seq: - * WIN32OLE_METHOD#invoke_kind - * - * Returns the method kind string. The string is "UNKNOWN" or "PROPERTY" - * or "PROPERTY" or "PROPERTYGET" or "PROPERTYPUT" or "PROPERTYPPUTREF" - * or "FUNC". - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.invoke_kind # => "FUNC" - */ -static VALUE -folemethod_invoke_kind(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE visible; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if(FAILED(hr)) - return Qfalse; - if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED | - FUNCFLAG_FHIDDEN | - FUNCFLAG_FNONBROWSABLE)) { - visible = Qfalse; - } else { - visible = Qtrue; - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return visible; -} - -/* - * call-seq: - * WIN32OLE_METHOD#visible? - * - * Returns true if the method is public. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.visible? # => true - */ -static VALUE -folemethod_visible(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_visible(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name) -{ - TYPEATTR *pTypeAttr; - HRESULT hr; - WORD i; - int flags; - HREFTYPE href; - ITypeInfo *pRefTypeInfo; - FUNCDESC *pFuncDesc; - BSTR bstr; - VALUE name; - VALUE event = Qfalse; - - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - return event; - if(pTypeAttr->typekind != TKIND_COCLASS) { - pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr); - return event; - } - for (i = 0; i < pTypeAttr->cImplTypes; i++) { - hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags); - if (FAILED(hr)) - continue; - - if (flags & IMPLTYPEFLAG_FSOURCE) { - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, - i, &href); - if (FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, - href, &pRefTypeInfo); - if (FAILED(hr)) - continue; - hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index, - &pFuncDesc); - if (FAILED(hr)) { - OLE_RELEASE(pRefTypeInfo); - continue; - } - - hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo, - pFuncDesc->memid, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) { - pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc); - OLE_RELEASE(pRefTypeInfo); - continue; - } - - name = WC2VSTR(bstr); - pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc); - OLE_RELEASE(pRefTypeInfo); - if (rb_str_cmp(method_name, name) == 0) { - event = Qtrue; - break; - } - } - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return event; -} - -/* - * call-seq: - * WIN32OLE_METHOD#event? - * - * Returns true if the method is event. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate') - * puts method.event? # => true - * - */ -static VALUE -folemethod_event(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - if (!pmethod->pOwnerTypeInfo) - return Qfalse; - return ole_method_event(pmethod->pOwnerTypeInfo, - pmethod->index, - rb_ivar_get(self, rb_intern("name"))); -} - -/* - * call-seq: - * WIN32OLE_METHOD#event_interface - * - * Returns event interface name if the method is event. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate') - * puts method.event_interface # => WorkbookEvents - */ -static VALUE -folemethod_event_interface(VALUE self) -{ - BSTR name; - struct olemethoddata *pmethod; - HRESULT hr; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - if(folemethod_event(self) == Qtrue) { - hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL); - if(SUCCEEDED(hr)) - return WC2VSTR(name); - } - return Qnil; -} - -static HRESULT -ole_method_docinfo_from_type( - ITypeInfo *pTypeInfo, - UINT method_index, - BSTR *name, - BSTR *helpstr, - DWORD *helpcontext, - BSTR *helpfile - ) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return hr; - hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid, - name, helpstr, - helpcontext, helpfile); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return hr; -} - -static VALUE -ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index) -{ - HRESULT hr; - BSTR bhelpstring; - hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring, - NULL, NULL); - if (FAILED(hr)) - return Qnil; - return WC2VSTR(bhelpstring); -} - -/* - * call-seq: - * WIN32OLE_METHOD#helpstring - * - * Returns help string of OLE method. If the help string is not found, - * then the method returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser') - * method = WIN32OLE_METHOD.new(tobj, 'Navigate') - * puts method.helpstring # => Navigates to a URL or file. - * - */ -static VALUE -folemethod_helpstring(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index) -{ - HRESULT hr; - BSTR bhelpfile; - hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL, - NULL, &bhelpfile); - if (FAILED(hr)) - return Qnil; - return WC2VSTR(bhelpfile); -} - -/* - * call-seq: - * WIN32OLE_METHOD#helpfile - * - * Returns help file. If help file is not found, then - * the method returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.helpfile # => C:\...\VBAXL9.CHM - */ -static VALUE -folemethod_helpfile(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - - return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index) -{ - HRESULT hr; - DWORD helpcontext = 0; - hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL, - &helpcontext, NULL); - if (FAILED(hr)) - return Qnil; - return RB_INT2FIX(helpcontext); -} - -/* - * call-seq: - * WIN32OLE_METHOD#helpcontext - * - * Returns help context. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.helpcontext # => 65717 - */ -static VALUE -folemethod_helpcontext(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE dispid = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return dispid; - dispid = RB_INT2NUM(pFuncDesc->memid); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return dispid; -} - -/* - * call-seq: - * WIN32OLE_METHOD#dispid - * - * Returns dispatch ID. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.dispid # => 181 - */ -static VALUE -folemethod_dispid(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_dispid(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE offset_vtbl = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return offset_vtbl; - offset_vtbl = RB_INT2FIX(pFuncDesc->oVft); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return offset_vtbl; -} - -/* - * call-seq: - * WIN32OLE_METHOD#offset_vtbl - * - * Returns the offset ov VTBL. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks') - * method = WIN32OLE_METHOD.new(tobj, 'Add') - * puts method.offset_vtbl # => 40 - */ -static VALUE -folemethod_offset_vtbl(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE size_params = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return size_params; - size_params = RB_INT2FIX(pFuncDesc->cParams); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return size_params; -} - -/* - * call-seq: - * WIN32OLE_METHOD#size_params - * - * Returns the size of arguments of the method. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * puts method.size_params # => 11 - * - */ -static VALUE -folemethod_size_params(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_size_params(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE size_opt_params = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return size_opt_params; - size_opt_params = RB_INT2FIX(pFuncDesc->cParamsOpt); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return size_opt_params; -} - -/* - * call-seq: - * WIN32OLE_METHOD#size_opt_params - * - * Returns the size of optional parameters. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * puts method.size_opt_params # => 4 - */ -static VALUE -folemethod_size_opt_params(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index); -} - -static VALUE -ole_method_params(ITypeInfo *pTypeInfo, UINT method_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - BSTR *bstrs; - UINT len, i; - VALUE param; - VALUE params = rb_ary_new(); - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return params; - - len = 0; - bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1); - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, - bstrs, pFuncDesc->cParams + 1, - &len); - if (FAILED(hr)) { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return params; - } - SysFreeString(bstrs[0]); - if (pFuncDesc->cParams > 0) { - for(i = 1; i < len; i++) { - param = create_win32ole_param(pTypeInfo, method_index, i-1, WC2VSTR(bstrs[i])); - rb_ary_push(params, param); - } - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return params; -} - -/* - * call-seq: - * WIN32OLE_METHOD#params - * - * returns array of WIN32OLE_PARAM object corresponding with method parameters. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * p method.params # => [Filename, FileFormat, Password, WriteResPassword, - * ReadOnlyRecommended, CreateBackup, AccessMode, - * ConflictResolution, AddToMru, TextCodepage, - * TextVisualLayout] - */ -static VALUE -folemethod_params(VALUE self) -{ - struct olemethoddata *pmethod; - TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod); - return ole_method_params(pmethod->pTypeInfo, pmethod->index); -} - -/* - * call-seq: - * WIN32OLE_METHOD#inspect -> String - * - * Returns the method name with class name. - * - */ -static VALUE -folemethod_inspect(VALUE self) -{ - return default_inspect(self, "WIN32OLE_METHOD"); -} - -VALUE cWIN32OLE_METHOD; - -void Init_win32ole_method(void) -{ - cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject); - rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate); - rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2); - rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0); - rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0); - rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0); - rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0); - rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0); - rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0); - rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0); - rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0); - rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0); - rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0); - rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0); - rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0); - rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0); - rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0); - rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0); - rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0); - rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0); - rb_define_alias(cWIN32OLE_METHOD, "to_s", "name"); - rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0); -} diff --git a/ext/win32ole/win32ole_method.h b/ext/win32ole/win32ole_method.h deleted file mode 100644 index ef907d2fac..0000000000 --- a/ext/win32ole/win32ole_method.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef WIN32OLE_METHOD_H -#define WIN32OLE_METHOD_H 1 - -struct olemethoddata { - ITypeInfo *pOwnerTypeInfo; - ITypeInfo *pTypeInfo; - UINT index; -}; - -extern VALUE cWIN32OLE_METHOD; -VALUE folemethod_s_allocate(VALUE klass); -VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask); -VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name); -struct olemethoddata *olemethod_data_get_struct(VALUE obj); -void Init_win32ole_method(void); -#endif diff --git a/ext/win32ole/win32ole_param.c b/ext/win32ole/win32ole_param.c deleted file mode 100644 index 52905b3e8e..0000000000 --- a/ext/win32ole/win32ole_param.c +++ /dev/null @@ -1,438 +0,0 @@ -#include "win32ole.h" - -VALUE cWIN32OLE_PARAM; - -struct oleparamdata { - ITypeInfo *pTypeInfo; - UINT method_index; - UINT index; -}; - -static void oleparam_free(void *ptr); -static size_t oleparam_size(const void *ptr); -static VALUE foleparam_s_allocate(VALUE klass); -static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index); -static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n); -static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n); -static VALUE foleparam_name(VALUE self); -static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_ole_type(VALUE self); -static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_ole_type_detail(VALUE self); -static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask); -static VALUE foleparam_input(VALUE self); -static VALUE foleparam_output(VALUE self); -static VALUE foleparam_optional(VALUE self); -static VALUE foleparam_retval(VALUE self); -static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_default(VALUE self); -static VALUE foleparam_inspect(VALUE self); - -static const rb_data_type_t oleparam_datatype = { - "win32ole_param", - {NULL, oleparam_free, oleparam_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static void -oleparam_free(void *ptr) -{ - struct oleparamdata *pole = ptr; - OLE_FREE(pole->pTypeInfo); - free(pole); -} - -static size_t -oleparam_size(const void *ptr) -{ - return ptr ? sizeof(struct oleparamdata) : 0; -} - -VALUE -create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name) -{ - struct oleparamdata *pparam; - VALUE obj = foleparam_s_allocate(cWIN32OLE_PARAM); - TypedData_Get_Struct(obj, struct oleparamdata, &oleparam_datatype, pparam); - - pparam->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pparam->method_index = method_index; - pparam->index = index; - rb_ivar_set(obj, rb_intern("name"), name); - return obj; -} - -/* - * Document-class: WIN32OLE_PARAM - * - * <code>WIN32OLE_PARAM</code> objects represent param information of - * the OLE method. - */ -static VALUE -foleparam_s_allocate(VALUE klass) -{ - struct oleparamdata *pparam; - VALUE obj; - obj = TypedData_Make_Struct(klass, - struct oleparamdata, - &oleparam_datatype, pparam); - pparam->pTypeInfo = NULL; - pparam->method_index = 0; - pparam->index = 0; - return obj; -} - -static VALUE -oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - BSTR *bstrs; - UINT len; - struct oleparamdata *pparam; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc"); - - len = 0; - bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1); - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, - bstrs, pFuncDesc->cParams + 1, - &len); - if (FAILED(hr)) { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames"); - } - SysFreeString(bstrs[0]); - if (param_index < 1 || len <= (UINT)param_index) - { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - rb_raise(rb_eIndexError, "index of param must be in 1..%d", len); - } - - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - pparam->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pparam->method_index = method_index; - pparam->index = param_index - 1; - rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index])); - - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return self; -} - -static VALUE -oleparam_ole_param(VALUE self, VALUE olemethod, int n) -{ - struct olemethoddata *pmethod = olemethod_data_get_struct(olemethod); - return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n); -} - -/* - * call-seq: - * WIN32OLE_PARAM.new(method, n) -> WIN32OLE_PARAM object - * - * Returns WIN32OLE_PARAM object which represents OLE parameter information. - * 1st argument should be WIN32OLE_METHOD object. - * 2nd argument `n' is n-th parameter of the method specified by 1st argument. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Scripting Runtime', 'IFileSystem') - * method = WIN32OLE_METHOD.new(tobj, 'CreateTextFile') - * param = WIN32OLE_PARAM.new(method, 2) # => #<WIN32OLE_PARAM:Overwrite=true> - * - */ -static VALUE -foleparam_initialize(VALUE self, VALUE olemethod, VALUE n) -{ - int idx; - if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) { - rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object"); - } - idx = RB_FIX2INT(n); - return oleparam_ole_param(self, olemethod, idx); -} - -/* - * call-seq: - * WIN32OLE_PARAM#name - * - * Returns name. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.name # => Filename - */ -static VALUE -foleparam_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE type = rb_str_new2("unknown type"); - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return type; - type = ole_typedesc2val(pTypeInfo, - &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_PARAM#ole_type - * - * Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method). - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.ole_type # => VARIANT - */ -static VALUE -foleparam_ole_type(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -static VALUE -ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE typedetail = rb_ary_new(); - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return typedetail; - ole_typedesc2val(pTypeInfo, - &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return typedetail; -} - -/* - * call-seq: - * WIN32OLE_PARAM#ole_type_detail - * - * Returns detail information of type of argument. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction') - * method = WIN32OLE_METHOD.new(tobj, 'SumIf') - * param1 = method.params[0] - * p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"] - */ -static VALUE -foleparam_ole_type_detail(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -static VALUE -ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE ret = Qfalse; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if(FAILED(hr)) - return ret; - if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask) - ret = Qtrue; - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return ret; -} - -/* - * call-seq: - * WIN32OLE_PARAM#input? - * - * Returns true if the parameter is input. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.input? # => true - */ -static VALUE -foleparam_input(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FIN); -} - -/* - * call-seq: - * WIN32OLE#output? - * - * Returns true if argument is output. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents') - * method = WIN32OLE_METHOD.new(tobj, 'NewWindow') - * method.params.each do |param| - * puts "#{param.name} #{param.output?}" - * end - * - * The result of above script is following: - * URL false - * Flags false - * TargetFrameName false - * PostData false - * Headers false - * Processed true - */ -static VALUE -foleparam_output(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FOUT); -} - -/* - * call-seq: - * WIN32OLE_PARAM#optional? - * - * Returns true if argument is optional. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts "#{param1.name} #{param1.optional?}" # => Filename true - */ -static VALUE -foleparam_optional(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FOPT); -} - -/* - * call-seq: - * WIN32OLE_PARAM#retval? - * - * Returns true if argument is return value. - * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', - * 'DirectPlayLobbyConnection') - * method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName') - * param = method.params[0] - * puts "#{param.name} #{param.retval?}" # => name true - */ -static VALUE -foleparam_retval(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FRETVAL); -} - -static VALUE -ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - ELEMDESC *pElemDesc; - PARAMDESCEX * pParamDescEx; - HRESULT hr; - USHORT wParamFlags; - USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT; - VALUE defval = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return defval; - pElemDesc = &pFuncDesc->lprgelemdescParam[index]; - wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags; - if ((wParamFlags & mask) == mask) { - pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex; - defval = ole_variant2val(&pParamDescEx->varDefaultValue); - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return defval; -} - -/* - * call-seq: - * WIN32OLE_PARAM#default - * - * Returns default value. If the default value does not exist, - * this method returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * method.params.each do |param| - * if param.default - * puts "#{param.name} (= #{param.default})" - * else - * puts "#{param}" - * end - * end - * - * The above script result is following: - * Filename - * FileFormat - * Password - * WriteResPassword - * ReadOnlyRecommended - * CreateBackup - * AccessMode (= 1) - * ConflictResolution - * AddToMru - * TextCodepage - * TextVisualLayout - */ -static VALUE -foleparam_default(VALUE self) -{ - struct oleparamdata *pparam; - TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam); - return ole_param_default(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -/* - * call-seq: - * WIN32OLE_PARAM#inspect -> String - * - * Returns the parameter name with class name. If the parameter has default value, - * then returns name=value string with class name. - * - */ -static VALUE -foleparam_inspect(VALUE self) -{ - VALUE detail = foleparam_name(self); - VALUE defval = foleparam_default(self); - if (defval != Qnil) { - rb_str_cat2(detail, "="); - rb_str_concat(detail, rb_inspect(defval)); - } - return make_inspect("WIN32OLE_PARAM", detail); -} - -void -Init_win32ole_param(void) -{ - cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject); - rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate); - rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2); - rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0); - rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0); - rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0); - rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0); - rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0); - rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0); - rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0); - rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0); - rb_define_alias(cWIN32OLE_PARAM, "to_s", "name"); - rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0); -} diff --git a/ext/win32ole/win32ole_param.h b/ext/win32ole/win32ole_param.h deleted file mode 100644 index 7e2650cb44..0000000000 --- a/ext/win32ole/win32ole_param.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WIN32OLE_PARAM_H -#define WIN32OLE_PARAM_H - -VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name); -void Init_win32ole_param(void); - -#endif - diff --git a/ext/win32ole/win32ole_record.c b/ext/win32ole/win32ole_record.c deleted file mode 100644 index 03523bc47d..0000000000 --- a/ext/win32ole/win32ole_record.c +++ /dev/null @@ -1,606 +0,0 @@ -#include "win32ole.h" - -struct olerecorddata { - IRecordInfo *pri; - void *pdata; -}; - -static HRESULT recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri); -static int hash2olerec(VALUE key, VALUE val, VALUE rec); -static void olerecord_free(void *pvar); -static size_t olerecord_size(const void *ptr); -static VALUE folerecord_s_allocate(VALUE klass); -static VALUE folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj); -static VALUE folerecord_to_h(VALUE self); -static VALUE folerecord_typename(VALUE self); -static VALUE olerecord_ivar_get(VALUE self, VALUE name); -static VALUE olerecord_ivar_set(VALUE self, VALUE name, VALUE val); -static VALUE folerecord_method_missing(int argc, VALUE *argv, VALUE self); -static VALUE folerecord_ole_instance_variable_get(VALUE self, VALUE name); -static VALUE folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val); -static VALUE folerecord_inspect(VALUE self); - -static const rb_data_type_t olerecord_datatype = { - "win32ole_record", - {NULL, olerecord_free, olerecord_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static HRESULT -recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri) -{ - - unsigned int count; - unsigned int i; - ITypeInfo *pTypeInfo; - HRESULT hr = OLE_E_LAST; - BSTR bstr; - - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count; i++) { - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) - continue; - - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); - if (FAILED(hr)) - continue; - - if (rb_str_cmp(WC2VSTR(bstr), name) == 0) { - hr = GetRecordInfoFromTypeInfo(pTypeInfo, ppri); - OLE_RELEASE(pTypeInfo); - return hr; - } - OLE_RELEASE(pTypeInfo); - } - hr = OLE_E_LAST; - return hr; -} - -static int -hash2olerec(VALUE key, VALUE val, VALUE rec) -{ - VARIANT var; - OLECHAR *pbuf; - struct olerecorddata *prec; - IRecordInfo *pri; - HRESULT hr; - - if (val != Qnil) { - TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec); - pri = prec->pri; - VariantInit(&var); - ole_val2variant(val, &var); - pbuf = ole_vstr2wc(key); - hr = pri->lpVtbl->PutField(pri, INVOKE_PROPERTYPUT, prec->pdata, pbuf, &var); - SysFreeString(pbuf); - VariantClear(&var); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to putfield of `%s`", StringValuePtr(key)); - } - } - return ST_CONTINUE; -} - -void -ole_rec2variant(VALUE rec, VARIANT *var) -{ - struct olerecorddata *prec; - ULONG size = 0; - IRecordInfo *pri; - HRESULT hr; - VALUE fields; - TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec); - pri = prec->pri; - if (pri) { - hr = pri->lpVtbl->GetSize(pri, &size); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to get size for allocation of VT_RECORD object"); - } - if (prec->pdata) { - free(prec->pdata); - } - prec->pdata = ALLOC_N(char, size); - if (!prec->pdata) { - rb_raise(rb_eRuntimeError, "failed to memory allocation of %lu bytes", (unsigned long)size); - } - hr = pri->lpVtbl->RecordInit(pri, prec->pdata); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to initialize VT_RECORD object"); - } - fields = folerecord_to_h(rec); - rb_hash_foreach(fields, hash2olerec, rec); - V_RECORDINFO(var) = pri; - V_RECORD(var) = prec->pdata; - V_VT(var) = VT_RECORD; - } else { - rb_raise(eWIN32OLERuntimeError, "failed to retrieve IRecordInfo interface"); - } -} - -void -olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec) -{ - HRESULT hr; - BSTR bstr; - BSTR *bstrs; - ULONG count = 0; - ULONG i; - VALUE fields; - VALUE val; - VARIANT var; - void *pdata = NULL; - struct olerecorddata *pvar; - - TypedData_Get_Struct(obj, struct olerecorddata, &olerecord_datatype, pvar); - OLE_ADDREF(pri); - OLE_RELEASE(pvar->pri); - pvar->pri = pri; - - hr = pri->lpVtbl->GetName(pri, &bstr); - if (SUCCEEDED(hr)) { - rb_ivar_set(obj, rb_intern("typename"), WC2VSTR(bstr)); - } - - hr = pri->lpVtbl->GetFieldNames(pri, &count, NULL); - if (FAILED(hr) || count == 0) - return; - bstrs = ALLOCA_N(BSTR, count); - hr = pri->lpVtbl->GetFieldNames(pri, &count, bstrs); - if (FAILED(hr)) { - return; - } - - fields = rb_hash_new(); - rb_ivar_set(obj, rb_intern("fields"), fields); - for (i = 0; i < count; i++) { - pdata = NULL; - VariantInit(&var); - val = Qnil; - if (prec) { - hr = pri->lpVtbl->GetFieldNoCopy(pri, prec, bstrs[i], &var, &pdata); - if (SUCCEEDED(hr)) { - val = ole_variant2val(&var); - } - } - rb_hash_aset(fields, WC2VSTR(bstrs[i]), val); - } -} - -VALUE -create_win32ole_record(IRecordInfo *pri, void *prec) -{ - VALUE obj = folerecord_s_allocate(cWIN32OLE_RECORD); - olerecord_set_ivar(obj, pri, prec); - return obj; -} - -/* - * Document-class: WIN32OLE_RECORD - * - * <code>WIN32OLE_RECORD</code> objects represents VT_RECORD OLE variant. - * Win32OLE returns WIN32OLE_RECORD object if the result value of invoking - * OLE methods. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure Book - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Structure - * Public Function getBook() As Book - * Dim book As New Book - * book.title = "The Ruby Book" - * book.cost = 20 - * Return book - * End Function - * End Class - * - * then, you can retrieve getBook return value from the following - * Ruby script: - * - * require 'win32ole' - * obj = WIN32OLE.new('ComServer.ComClass') - * book = obj.getBook - * book.class # => WIN32OLE_RECORD - * book.title # => "The Ruby Book" - * book.cost # => 20 - * - */ - -static void -olerecord_free(void *ptr) { - struct olerecorddata *pvar = ptr; - OLE_FREE(pvar->pri); - if (pvar->pdata) { - free(pvar->pdata); - } - free(pvar); -} - -static size_t -olerecord_size(const void *ptr) -{ - const struct olerecorddata *pvar = ptr; - size_t s = 0; - ULONG size = 0; - HRESULT hr; - if (ptr) { - s += sizeof(struct olerecorddata); - if (pvar->pri) { - hr = pvar->pri->lpVtbl->GetSize(pvar->pri, &size); - if (SUCCEEDED(hr)) { - s += size; - } - } - } - return s; -} - -static VALUE -folerecord_s_allocate(VALUE klass) { - VALUE obj = Qnil; - struct olerecorddata *pvar; - obj = TypedData_Make_Struct(klass, struct olerecorddata, &olerecord_datatype, pvar); - pvar->pri = NULL; - pvar->pdata = NULL; - return obj; -} - -/* - * call-seq: - * WIN32OLE_RECORD.new(typename, obj) -> WIN32OLE_RECORD object - * - * Returns WIN32OLE_RECORD object. The first argument is struct name (String - * or Symbol). - * The second parameter obj should be WIN32OLE object or WIN32OLE_TYPELIB object. - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure Book - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Structure - * End Class - * - * then, you can create WIN32OLE_RECORD object is as following: - * - * require 'win32ole' - * obj = WIN32OLE.new('ComServer.ComClass') - * book1 = WIN32OLE_RECORD.new('Book', obj) # => WIN32OLE_RECORD object - * tlib = obj.ole_typelib - * book2 = WIN32OLE_RECORD.new('Book', tlib) # => WIN32OLE_RECORD object - * - */ -static VALUE -folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj) { - HRESULT hr; - ITypeLib *pTypeLib = NULL; - IRecordInfo *pri = NULL; - - if (!RB_TYPE_P(typename, T_STRING) && !RB_TYPE_P(typename, T_SYMBOL)) { - rb_raise(rb_eArgError, "1st argument should be String or Symbol"); - } - if (RB_TYPE_P(typename, T_SYMBOL)) { - typename = rb_sym2str(typename); - } - - hr = S_OK; - if(rb_obj_is_kind_of(oleobj, cWIN32OLE)) { - hr = typelib_from_val(oleobj, &pTypeLib); - } else if (rb_obj_is_kind_of(oleobj, cWIN32OLE_TYPELIB)) { - pTypeLib = itypelib(oleobj); - OLE_ADDREF(pTypeLib); - if (pTypeLib) { - hr = S_OK; - } else { - hr = E_FAIL; - } - } else { - rb_raise(rb_eArgError, "2nd argument should be WIN32OLE object or WIN32OLE_TYPELIB object"); - } - - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "fail to query ITypeLib interface"); - } - - hr = recordinfo_from_itypelib(pTypeLib, typename, &pri); - OLE_RELEASE(pTypeLib); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "fail to query IRecordInfo interface for `%s'", StringValuePtr(typename)); - } - - olerecord_set_ivar(self, pri, NULL); - - return self; -} - -/* - * call-seq: - * WIN32OLE_RECORD#to_h #=> Ruby Hash object. - * - * Returns Ruby Hash object which represents VT_RECORD variable. - * The keys of Hash object are member names of VT_RECORD OLE variable and - * the values of Hash object are values of VT_RECORD OLE variable. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure Book - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Structure - * Public Function getBook() As Book - * Dim book As New Book - * book.title = "The Ruby Book" - * book.cost = 20 - * Return book - * End Function - * End Class - * - * then, the result of WIN32OLE_RECORD#to_h is the following: - * - * require 'win32ole' - * obj = WIN32OLE.new('ComServer.ComClass') - * book = obj.getBook - * book.to_h # => {"title"=>"The Ruby Book", "cost"=>20} - * - */ -static VALUE -folerecord_to_h(VALUE self) -{ - return rb_ivar_get(self, rb_intern("fields")); -} - -/* - * call-seq: - * WIN32OLE_RECORD#typename #=> String object - * - * Returns the type name of VT_RECORD OLE variable. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure Book - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Structure - * Public Function getBook() As Book - * Dim book As New Book - * book.title = "The Ruby Book" - * book.cost = 20 - * Return book - * End Function - * End Class - * - * then, the result of WIN32OLE_RECORD#typename is the following: - * - * require 'win32ole' - * obj = WIN32OLE.new('ComServer.ComClass') - * book = obj.getBook - * book.typename # => "Book" - * - */ -static VALUE -folerecord_typename(VALUE self) -{ - return rb_ivar_get(self, rb_intern("typename")); -} - -static VALUE -olerecord_ivar_get(VALUE self, VALUE name) -{ - VALUE fields; - fields = rb_ivar_get(self, rb_intern("fields")); - return rb_hash_fetch(fields, name); -} - -static VALUE -olerecord_ivar_set(VALUE self, VALUE name, VALUE val) -{ - long len; - char *p; - VALUE fields; - len = RSTRING_LEN(name); - p = RSTRING_PTR(name); - if (p[len-1] == '=') { - name = rb_str_subseq(name, 0, len-1); - } - fields = rb_ivar_get(self, rb_intern("fields")); - rb_hash_fetch(fields, name); - return rb_hash_aset(fields, name, val); -} - -/* - * call-seq: - * WIN32OLE_RECORD#method_missing(name) - * - * Returns value specified by the member name of VT_RECORD OLE variable. - * Or sets value specified by the member name of VT_RECORD OLE variable. - * If the member name is not correct, KeyError exception is raised. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure Book - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Structure - * End Class - * - * Then getting/setting value from Ruby is as the following: - * - * obj = WIN32OLE.new('ComServer.ComClass') - * book = WIN32OLE_RECORD.new('Book', obj) - * book.title # => nil ( book.method_missing(:title) is invoked. ) - * book.title = "Ruby" # ( book.method_missing(:title=, "Ruby") is invoked. ) - */ -static VALUE -folerecord_method_missing(int argc, VALUE *argv, VALUE self) -{ - VALUE name; - rb_check_arity(argc, 1, 2); - name = rb_sym2str(argv[0]); - -#if SIZEOF_SIZE_T > SIZEOF_LONG - { - size_t n = strlen(StringValueCStr(name)); - if (n >= LONG_MAX) { - rb_raise(rb_eRuntimeError, "too long member name"); - } - } -#endif - - if (argc == 1) { - return olerecord_ivar_get(self, name); - } else if (argc == 2) { - return olerecord_ivar_set(self, name, argv[1]); - } - return Qnil; -} - -/* - * call-seq: - * WIN32OLE_RECORD#ole_instance_variable_get(name) - * - * Returns value specified by the member name of VT_RECORD OLE object. - * If the member name is not correct, KeyError exception is raised. - * If you can't access member variable of VT_RECORD OLE object directly, - * use this method. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * Public Structure ComObject - * Public object_id As Ineger - * End Structure - * End Class - * - * and Ruby Object class has title attribute: - * - * then accessing object_id of ComObject from Ruby is as the following: - * - * srver = WIN32OLE.new('ComServer.ComClass') - * obj = WIN32OLE_RECORD.new('ComObject', server) - * # obj.object_id returns Ruby Object#object_id - * obj.ole_instance_variable_get(:object_id) # => nil - * - */ -static VALUE -folerecord_ole_instance_variable_get(VALUE self, VALUE name) -{ - VALUE sname; - if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) { - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - sname = name; - if (RB_TYPE_P(name, T_SYMBOL)) { - sname = rb_sym2str(name); - } - return olerecord_ivar_get(self, sname); -} - -/* - * call-seq: - * WIN32OLE_RECORD#ole_instance_variable_set(name, val) - * - * Sets value specified by the member name of VT_RECORD OLE object. - * If the member name is not correct, KeyError exception is raised. - * If you can't set value of member of VT_RECORD OLE object directly, - * use this method. - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Class - * - * then setting value of the `title' member is as following: - * - * srver = WIN32OLE.new('ComServer.ComClass') - * obj = WIN32OLE_RECORD.new('Book', server) - * obj.ole_instance_variable_set(:title, "The Ruby Book") - * - */ -static VALUE -folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val) -{ - VALUE sname; - if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) { - rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); - } - sname = name; - if (RB_TYPE_P(name, T_SYMBOL)) { - sname = rb_sym2str(name); - } - return olerecord_ivar_set(self, sname, val); -} - -/* - * call-seq: - * WIN32OLE_RECORD#inspect -> String - * - * Returns the OLE struct name and member name and the value of member - * - * If COM server in VB.NET ComServer project is the following: - * - * Imports System.Runtime.InteropServices - * Public Class ComClass - * <MarshalAs(UnmanagedType.BStr)> _ - * Public title As String - * Public cost As Integer - * End Class - * - * then - * - * srver = WIN32OLE.new('ComServer.ComClass') - * obj = WIN32OLE_RECORD.new('Book', server) - * obj.inspect # => <WIN32OLE_RECORD(ComClass) {"title" => nil, "cost" => nil}> - * - */ -static VALUE -folerecord_inspect(VALUE self) -{ - VALUE tname; - VALUE field; - tname = folerecord_typename(self); - if (tname == Qnil) { - tname = rb_inspect(tname); - } - field = rb_inspect(folerecord_to_h(self)); - return rb_sprintf("#<WIN32OLE_RECORD(%"PRIsVALUE") %"PRIsVALUE">", - tname, - field); -} - -VALUE cWIN32OLE_RECORD; - -void -Init_win32ole_record(void) -{ - cWIN32OLE_RECORD = rb_define_class("WIN32OLE_RECORD", rb_cObject); - rb_define_alloc_func(cWIN32OLE_RECORD, folerecord_s_allocate); - rb_define_method(cWIN32OLE_RECORD, "initialize", folerecord_initialize, 2); - rb_define_method(cWIN32OLE_RECORD, "to_h", folerecord_to_h, 0); - rb_define_method(cWIN32OLE_RECORD, "typename", folerecord_typename, 0); - rb_define_method(cWIN32OLE_RECORD, "method_missing", folerecord_method_missing, -1); - rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_get", folerecord_ole_instance_variable_get, 1); - rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_set", folerecord_ole_instance_variable_set, 2); - rb_define_method(cWIN32OLE_RECORD, "inspect", folerecord_inspect, 0); -} diff --git a/ext/win32ole/win32ole_record.h b/ext/win32ole/win32ole_record.h deleted file mode 100644 index ab1df0ee7f..0000000000 --- a/ext/win32ole/win32ole_record.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef WIN32OLE_RECORD_H -#define WIN32OLE_RECORD_H 1 - -extern VALUE cWIN32OLE_RECORD; -void ole_rec2variant(VALUE rec, VARIANT *var); -void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec); -VALUE create_win32ole_record(IRecordInfo *pri, void *prec); -void Init_win32ole_record(void); - -#endif diff --git a/ext/win32ole/win32ole_type.c b/ext/win32ole/win32ole_type.c deleted file mode 100644 index 48dbc9dbde..0000000000 --- a/ext/win32ole/win32ole_type.c +++ /dev/null @@ -1,917 +0,0 @@ -#include "win32ole.h" - -struct oletypedata { - ITypeInfo *pTypeInfo; -}; - -static void oletype_free(void *ptr); -static size_t oletype_size(const void *ptr); -static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib); -static VALUE foletype_s_typelibs(VALUE self); -static VALUE foletype_s_progids(VALUE self); -static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name); -static VALUE foletype_s_allocate(VALUE klass); -static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass); -static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass); -static VALUE foletype_name(VALUE self); -static VALUE ole_ole_type(ITypeInfo *pTypeInfo); -static VALUE foletype_ole_type(VALUE self); -static VALUE ole_type_guid(ITypeInfo *pTypeInfo); -static VALUE foletype_guid(VALUE self); -static VALUE ole_type_progid(ITypeInfo *pTypeInfo); -static VALUE foletype_progid(VALUE self); -static VALUE ole_type_visible(ITypeInfo *pTypeInfo); -static VALUE foletype_visible(VALUE self); -static VALUE ole_type_major_version(ITypeInfo *pTypeInfo); -static VALUE foletype_major_version(VALUE self); -static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo); -static VALUE foletype_minor_version(VALUE self); -static VALUE ole_type_typekind(ITypeInfo *pTypeInfo); -static VALUE foletype_typekind(VALUE self); -static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo); -static VALUE foletype_helpstring(VALUE self); -static VALUE ole_type_src_type(ITypeInfo *pTypeInfo); -static VALUE foletype_src_type(VALUE self); -static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo); -static VALUE foletype_helpfile(VALUE self); -static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo); -static VALUE foletype_helpcontext(VALUE self); -static VALUE ole_variables(ITypeInfo *pTypeInfo); -static VALUE foletype_variables(VALUE self); -static VALUE foletype_methods(VALUE self); -static VALUE foletype_ole_typelib(VALUE self); -static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags); -static VALUE foletype_impl_ole_types(VALUE self); -static VALUE foletype_source_ole_types(VALUE self); -static VALUE foletype_default_event_sources(VALUE self); -static VALUE foletype_default_ole_types(VALUE self); -static VALUE foletype_inspect(VALUE self); - -static const rb_data_type_t oletype_datatype = { - "win32ole_type", - {NULL, oletype_free, oletype_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -/* - * Document-class: WIN32OLE_TYPE - * - * <code>WIN32OLE_TYPE</code> objects represent OLE type library information. - */ - -static void -oletype_free(void *ptr) -{ - struct oletypedata *poletype = ptr; - OLE_FREE(poletype->pTypeInfo); - free(poletype); -} - -static size_t -oletype_size(const void *ptr) -{ - return ptr ? sizeof(struct oletypedata) : 0; -} - -ITypeInfo *itypeinfo(VALUE self) -{ - struct oletypedata *ptype; - TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype); - return ptype->pTypeInfo; -} - -VALUE -ole_type_from_itypeinfo(ITypeInfo *pTypeInfo) -{ - ITypeLib *pTypeLib; - VALUE type = Qnil; - HRESULT hr; - unsigned int index; - BSTR bstr; - - hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index ); - if(FAILED(hr)) { - return Qnil; - } - hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index, - &bstr, NULL, NULL, NULL); - OLE_RELEASE(pTypeLib); - if (FAILED(hr)) { - return Qnil; - } - type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr)); - return type; -} - - -/* - * call-seq: - * WIN32OLE_TYPE.ole_classes(typelib) - * - * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library. - * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes instead. - */ -static VALUE -foletype_s_ole_classes(VALUE self, VALUE typelib) -{ - VALUE obj; - - /* - rb_warn("%s is obsolete; use %s instead.", - "WIN32OLE_TYPE.ole_classes", - "WIN32OLE_TYPELIB.new(typelib).ole_types"); - */ - obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib); - return rb_funcall(obj, rb_intern("ole_types"), 0); -} - -/* - * call-seq: - * WIN32OLE_TYPE.typelibs - * - * Returns array of type libraries. - * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead. - * - */ -static VALUE -foletype_s_typelibs(VALUE self) -{ - /* - rb_warn("%s is obsolete. use %s instead.", - "WIN32OLE_TYPE.typelibs", - "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}"); - */ - return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}"); -} - -/* - * call-seq: - * WIN32OLE_TYPE.progids - * - * Returns array of ProgID. - */ -static VALUE -foletype_s_progids(VALUE self) -{ - HKEY hclsids, hclsid; - DWORD i; - LONG err; - VALUE clsid; - VALUE v = rb_str_new2(""); - VALUE progids = rb_ary_new(); - - err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids); - if(err != ERROR_SUCCESS) { - return progids; - } - for(i = 0; ; i++) { - clsid = reg_enum_key(hclsids, i); - if (clsid == Qnil) - break; - err = reg_open_vkey(hclsids, clsid, &hclsid); - if (err != ERROR_SUCCESS) - continue; - if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil) - rb_ary_push(progids, v); - if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil) - rb_ary_push(progids, v); - RegCloseKey(hclsid); - } - RegCloseKey(hclsids); - return progids; -} - -static VALUE -oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name) -{ - struct oletypedata *ptype; - TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype); - rb_ivar_set(self, rb_intern("name"), name); - ptype->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - return self; -} - -static VALUE -foletype_s_allocate(VALUE klass) -{ - struct oletypedata *poletype; - VALUE obj; - ole_initialize(); - obj = TypedData_Make_Struct(klass,struct oletypedata, &oletype_datatype, poletype); - poletype->pTypeInfo = NULL; - return obj; -} - -VALUE -create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name) -{ - VALUE obj = foletype_s_allocate(cWIN32OLE_TYPE); - oletype_set_member(obj, pTypeInfo, name); - return obj; -} - -static VALUE -oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass) -{ - - long count; - int i; - HRESULT hr; - BSTR bstr; - VALUE typelib; - ITypeInfo *pTypeInfo; - - VALUE found = Qfalse; - - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count && found == Qfalse; i++) { - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); - if (FAILED(hr)) - continue; - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) - continue; - typelib = WC2VSTR(bstr); - if (rb_str_cmp(oleclass, typelib) == 0) { - oletype_set_member(self, pTypeInfo, typelib); - found = Qtrue; - } - OLE_RELEASE(pTypeInfo); - } - return found; -} - -/* - * call-seq: - * WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object - * - * Returns a new WIN32OLE_TYPE object. - * The first argument <i>typelib</i> specifies OLE type library name. - * The second argument specifies OLE class name. - * - * WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * # => WIN32OLE_TYPE object of Application class of Excel. - */ -static VALUE -foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass) -{ - VALUE file; - OLECHAR * pbuf; - ITypeLib *pTypeLib; - HRESULT hr; - - SafeStringValue(oleclass); - SafeStringValue(typelib); - file = typelib_file(typelib); - if (file == Qnil) { - file = typelib; - } - pbuf = ole_vstr2wc(file); - hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx"); - SysFreeString(pbuf); - if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) { - OLE_RELEASE(pTypeLib); - rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`", - StringValuePtr(oleclass), StringValuePtr(typelib)); - } - OLE_RELEASE(pTypeLib); - return self; -} - -/* - * call-seq: - * WIN32OLE_TYPE#name #=> OLE type name - * - * Returns OLE type name. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * puts tobj.name # => Application - */ -static VALUE -foletype_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_ole_type(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - VALUE type = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if(FAILED(hr)){ - return type; - } - switch(pTypeAttr->typekind) { - case TKIND_ENUM: - type = rb_str_new2("Enum"); - break; - case TKIND_RECORD: - type = rb_str_new2("Record"); - break; - case TKIND_MODULE: - type = rb_str_new2("Module"); - break; - case TKIND_INTERFACE: - type = rb_str_new2("Interface"); - break; - case TKIND_DISPATCH: - type = rb_str_new2("Dispatch"); - break; - case TKIND_COCLASS: - type = rb_str_new2("Class"); - break; - case TKIND_ALIAS: - type = rb_str_new2("Alias"); - break; - case TKIND_UNION: - type = rb_str_new2("Union"); - break; - case TKIND_MAX: - type = rb_str_new2("Max"); - break; - default: - type = Qnil; - break; - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return type; -} - -/* - * call-seq: - * WIN32OLE_TYPE#ole_type #=> OLE type string. - * - * returns type of OLE class. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * puts tobj.ole_type # => Class - */ -static VALUE -foletype_ole_type(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_ole_type(pTypeInfo); -} - -static VALUE -ole_type_guid(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - int len; - OLECHAR bstr[80]; - VALUE guid = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - return guid; - len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR)); - if (len > 3) { - guid = ole_wc2vstr(bstr, FALSE); - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return guid; -} - -/* - * call-seq: - * WIN32OLE_TYPE#guid #=> GUID - * - * Returns GUID. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * puts tobj.guid # => {00024500-0000-0000-C000-000000000046} - */ -static VALUE -foletype_guid(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_guid(pTypeInfo); -} - -static VALUE -ole_type_progid(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - OLECHAR *pbuf; - VALUE progid = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - return progid; - hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf); - if (SUCCEEDED(hr)) { - progid = ole_wc2vstr(pbuf, FALSE); - CoTaskMemFree(pbuf); - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return progid; -} - -/* - * call-seq: - * WIN32OLE_TYPE#progid #=> ProgID - * - * Returns ProgID if it exists. If not found, then returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * puts tobj.progid # => Excel.Application.9 - */ -static VALUE -foletype_progid(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_progid(pTypeInfo); -} - - -static VALUE -ole_type_visible(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - VALUE visible; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - return Qtrue; - if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) { - visible = Qfalse; - } else { - visible = Qtrue; - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return visible; -} - -/* - * call-seq: - * WIN32OLE_TYPE#visible? #=> true or false - * - * Returns true if the OLE class is public. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') - * puts tobj.visible # => true - */ -static VALUE -foletype_visible(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_visible(pTypeInfo); -} - -static VALUE -ole_type_major_version(ITypeInfo *pTypeInfo) -{ - VALUE ver; - TYPEATTR *pTypeAttr; - HRESULT hr; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); - ver = RB_INT2FIX(pTypeAttr->wMajorVerNum); - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return ver; -} - -/* - * call-seq: - * WIN32OLE_TYPE#major_version - * - * Returns major version. - * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') - * puts tobj.major_version # => 8 - */ -static VALUE -foletype_major_version(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_major_version(pTypeInfo); -} - -static VALUE -ole_type_minor_version(ITypeInfo *pTypeInfo) -{ - VALUE ver; - TYPEATTR *pTypeAttr; - HRESULT hr; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); - ver = RB_INT2FIX(pTypeAttr->wMinorVerNum); - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return ver; -} - -/* - * call-seq: - * WIN32OLE_TYPE#minor_version #=> OLE minor version - * - * Returns minor version. - * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') - * puts tobj.minor_version # => 2 - */ -static VALUE -foletype_minor_version(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_minor_version(pTypeInfo); -} - -static VALUE -ole_type_typekind(ITypeInfo *pTypeInfo) -{ - VALUE typekind; - TYPEATTR *pTypeAttr; - HRESULT hr; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); - typekind = RB_INT2FIX(pTypeAttr->typekind); - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return typekind; -} - -/* - * call-seq: - * WIN32OLE_TYPE#typekind #=> number of type. - * - * Returns number which represents type. - * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') - * puts tobj.typekind # => 4 - * - */ -static VALUE -foletype_typekind(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_typekind(pTypeInfo); -} - -static VALUE -ole_type_helpstring(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - BSTR bhelpstr; - hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL); - if(FAILED(hr)) { - return Qnil; - } - return WC2VSTR(bhelpstr); -} - -/* - * call-seq: - * WIN32OLE_TYPE#helpstring #=> help string. - * - * Returns help string. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser') - * puts tobj.helpstring # => Web Browser interface - */ -static VALUE -foletype_helpstring(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_helpstring(pTypeInfo); -} - -static VALUE -ole_type_src_type(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - VALUE alias = Qnil; - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) - return alias; - if(pTypeAttr->typekind != TKIND_ALIAS) { - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return alias; - } - alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil); - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return alias; -} - -/* - * call-seq: - * WIN32OLE_TYPE#src_type #=> OLE source class - * - * Returns source class when the OLE class is 'Alias'. - * tobj = WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType') - * puts tobj.src_type # => I4 - * - */ -static VALUE -foletype_src_type(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_src_type(pTypeInfo); -} - -static VALUE -ole_type_helpfile(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - BSTR bhelpfile; - hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile); - if(FAILED(hr)) { - return Qnil; - } - return WC2VSTR(bhelpfile); -} - -/* - * call-seq: - * WIN32OLE_TYPE#helpfile - * - * Returns helpfile path. If helpfile is not found, then returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') - * puts tobj.helpfile # => C:\...\VBAXL9.CHM - * - */ -static VALUE -foletype_helpfile(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_helpfile(pTypeInfo); -} - -static VALUE -ole_type_helpcontext(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - DWORD helpcontext; - hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, - &helpcontext, NULL); - if(FAILED(hr)) - return Qnil; - return RB_INT2FIX(helpcontext); -} - -/* - * call-seq: - * WIN32OLE_TYPE#helpcontext - * - * Returns helpcontext. If helpcontext is not found, then returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') - * puts tobj.helpfile # => 131185 - */ -static VALUE -foletype_helpcontext(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_helpcontext(pTypeInfo); -} - -static VALUE -ole_variables(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - TYPEATTR *pTypeAttr; - WORD i; - UINT len; - BSTR bstr; - VARDESC *pVarDesc; - VALUE var; - VALUE variables = rb_ary_new(); - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); - } - - for(i = 0; i < pTypeAttr->cVars; i++) { - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc); - if(FAILED(hr)) - continue; - len = 0; - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr, - 1, &len); - if(FAILED(hr) || len == 0 || !bstr) - continue; - - var = create_win32ole_variable(pTypeInfo, i, WC2VSTR(bstr)); - rb_ary_push(variables, var); - - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - pVarDesc = NULL; - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return variables; -} - -/* - * call-seq: - * WIN32OLE_TYPE#variables - * - * Returns array of WIN32OLE_VARIABLE objects which represent variables - * defined in OLE class. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * vars = tobj.variables - * vars.each do |v| - * puts "#{v.name} = #{v.value}" - * end - * - * The result of above sample script is follows: - * xlChart = -4109 - * xlDialogSheet = -4116 - * xlExcel4IntlMacroSheet = 4 - * xlExcel4MacroSheet = 3 - * xlWorksheet = -4167 - * - */ -static VALUE -foletype_variables(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_variables(pTypeInfo); -} - -/* - * call-seq: - * WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects. - * - * Returns array of WIN32OLE_METHOD objects which represent OLE method defined in - * OLE type library. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') - * methods = tobj.ole_methods.collect{|m| - * m.name - * } - * # => ['Activate', 'Copy', 'Delete',....] - */ -static VALUE -foletype_methods(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_methods_from_typeinfo(pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF); -} - -/* - * call-seq: - * WIN32OLE_TYPE#ole_typelib - * - * Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE - * object. If it is not found, then returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') - * puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library' - */ -static VALUE -foletype_ole_typelib(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_typelib_from_itypeinfo(pTypeInfo); -} - -static VALUE -ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags) -{ - HRESULT hr; - ITypeInfo *pRefTypeInfo; - HREFTYPE href; - WORD i; - VALUE type; - TYPEATTR *pTypeAttr; - int flags; - - VALUE types = rb_ary_new(); - hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); - if (FAILED(hr)) { - return types; - } - for (i = 0; i < pTypeAttr->cImplTypes; i++) { - hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags); - if (FAILED(hr)) - continue; - - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href); - if (FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo); - if (FAILED(hr)) - continue; - - if ((flags & implflags) == implflags) { - type = ole_type_from_itypeinfo(pRefTypeInfo); - if (type != Qnil) { - rb_ary_push(types, type); - } - } - - OLE_RELEASE(pRefTypeInfo); - } - OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); - return types; -} - -/* - * call-seq: - * WIN32OLE_TYPE#implemented_ole_types - * - * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE - * object. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') - * p tobj.implemented_ole_types # => [_Worksheet, DocEvents] - */ -static VALUE -foletype_impl_ole_types(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_impl_ole_types(pTypeInfo, 0); -} - -/* - * call-seq: - * WIN32OLE_TYPE#source_ole_types - * - * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE - * object and having IMPLTYPEFLAG_FSOURCE. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") - * p tobj.source_ole_types - * # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>] - */ -static VALUE -foletype_source_ole_types(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE); -} - -/* - * call-seq: - * WIN32OLE_TYPE#default_event_sources - * - * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE - * object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") - * p tobj.default_event_sources # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>] - */ -static VALUE -foletype_default_event_sources(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT); -} - -/* - * call-seq: - * WIN32OLE_TYPE#default_ole_types - * - * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE - * object and having IMPLTYPEFLAG_FDEFAULT. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") - * p tobj.default_ole_types - * # => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>] - */ -static VALUE -foletype_default_ole_types(VALUE self) -{ - ITypeInfo *pTypeInfo = itypeinfo(self); - return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FDEFAULT); -} - -/* - * call-seq: - * WIN32OLE_TYPE#inspect -> String - * - * Returns the type name with class name. - * - * ie = WIN32OLE.new('InternetExplorer.Application') - * ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2> - */ -static VALUE -foletype_inspect(VALUE self) -{ - return default_inspect(self, "WIN32OLE_TYPE"); -} - -VALUE cWIN32OLE_TYPE; - -void Init_win32ole_type(void) -{ - cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject); - rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1); - rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0); - rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0); - rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate); - rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2); - rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0); - rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0); - rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0); - rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0); - rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0); - rb_define_alias(cWIN32OLE_TYPE, "to_s", "name"); - rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0); - rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0); - rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0); - rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0); - rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0); - rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0); - rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0); - rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0); - rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0); - rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0); - rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0); - rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0); - rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0); - rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0); - rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0); -} diff --git a/ext/win32ole/win32ole_type.h b/ext/win32ole/win32ole_type.h deleted file mode 100644 index 87b551e502..0000000000 --- a/ext/win32ole/win32ole_type.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WIN32OLE_TYPE_H -#define WIN32OLE_TYPE_H 1 -extern VALUE cWIN32OLE_TYPE; -VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name); -ITypeInfo *itypeinfo(VALUE self); -VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo); -void Init_win32ole_type(void); -#endif diff --git a/ext/win32ole/win32ole_typelib.c b/ext/win32ole/win32ole_typelib.c deleted file mode 100644 index d89f181e07..0000000000 --- a/ext/win32ole/win32ole_typelib.c +++ /dev/null @@ -1,846 +0,0 @@ -#include "win32ole.h" - -struct oletypelibdata { - ITypeLib *pTypeLib; -}; - -static VALUE reg_get_typelib_file_path(HKEY hkey); -static VALUE oletypelib_path(VALUE guid, VALUE version); -static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib); -static VALUE foletypelib_s_typelibs(VALUE self); -static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib); -static void oletypelib_free(void *ptr); -static size_t oletypelib_size(const void *ptr); -static VALUE foletypelib_s_allocate(VALUE klass); -static VALUE oletypelib_search_registry(VALUE self, VALUE typelib); -static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr); -static VALUE oletypelib_search_registry2(VALUE self, VALUE args); -static VALUE foletypelib_initialize(VALUE self, VALUE args); -static VALUE foletypelib_guid(VALUE self); -static VALUE foletypelib_name(VALUE self); -static VALUE make_version_str(VALUE major, VALUE minor); -static VALUE foletypelib_version(VALUE self); -static VALUE foletypelib_major_version(VALUE self); -static VALUE foletypelib_minor_version(VALUE self); -static VALUE foletypelib_path(VALUE self); -static VALUE foletypelib_visible(VALUE self); -static VALUE foletypelib_library_name(VALUE self); -static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes); -static VALUE typelib_file_from_typelib(VALUE ole); -static VALUE typelib_file_from_clsid(VALUE ole); -static VALUE foletypelib_ole_types(VALUE self); -static VALUE foletypelib_inspect(VALUE self); - -static const rb_data_type_t oletypelib_datatype = { - "win32ole_typelib", - {NULL, oletypelib_free, oletypelib_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static VALUE -reg_get_typelib_file_path(HKEY hkey) -{ - VALUE path = Qnil; - path = reg_get_val2(hkey, "win64"); - if (path != Qnil) { - return path; - } - path = reg_get_val2(hkey, "win32"); - if (path != Qnil) { - return path; - } - path = reg_get_val2(hkey, "win16"); - return path; -} - -static VALUE -oletypelib_path(VALUE guid, VALUE version) -{ - int k; - LONG err; - HKEY hkey; - HKEY hlang; - VALUE lang; - VALUE path = Qnil; - - VALUE key = rb_str_new2("TypeLib\\"); - rb_str_concat(key, guid); - rb_str_cat2(key, "\\"); - rb_str_concat(key, version); - - err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey); - if (err != ERROR_SUCCESS) { - return Qnil; - } - for(k = 0; path == Qnil; k++) { - lang = reg_enum_key(hkey, k); - if (lang == Qnil) - break; - err = reg_open_vkey(hkey, lang, &hlang); - if (err == ERROR_SUCCESS) { - path = reg_get_typelib_file_path(hlang); - RegCloseKey(hlang); - } - } - RegCloseKey(hkey); - return path; -} - -static HRESULT -oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib) -{ - VALUE path; - OLECHAR *pBuf; - HRESULT hr; - path = oletypelib_path(guid, version); - if (path == Qnil) { - return E_UNEXPECTED; - } - pBuf = ole_vstr2wc(path); - hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib); - SysFreeString(pBuf); - return hr; -} - -ITypeLib * -itypelib(VALUE self) -{ - struct oletypelibdata *ptlib; - TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib); - return ptlib->pTypeLib; -} - -VALUE -ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo) -{ - HRESULT hr; - ITypeLib *pTypeLib; - unsigned int index; - VALUE retval = Qnil; - - hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index); - if(FAILED(hr)) { - return Qnil; - } - retval = create_win32ole_typelib(pTypeLib); - return retval; -} - -/* - * Document-class: WIN32OLE_TYPELIB - * - * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information. - */ - -/* - * call-seq: - * - * WIN32OLE_TYPELIB.typelibs - * - * Returns the array of WIN32OLE_TYPELIB object. - * - * tlibs = WIN32OLE_TYPELIB.typelibs - * - */ -static VALUE -foletypelib_s_typelibs(VALUE self) -{ - HKEY htypelib, hguid; - DWORD i, j; - LONG err; - VALUE guid; - VALUE version; - VALUE name = Qnil; - VALUE typelibs = rb_ary_new(); - VALUE typelib = Qnil; - HRESULT hr; - ITypeLib *pTypeLib; - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return typelibs; - } - for(i = 0; ; i++) { - guid = reg_enum_key(htypelib, i); - if (guid == Qnil) - break; - err = reg_open_vkey(htypelib, guid, &hguid); - if (err != ERROR_SUCCESS) - continue; - for(j = 0; ; j++) { - version = reg_enum_key(hguid, j); - if (version == Qnil) - break; - if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) { - hr = oletypelib_from_guid(guid, version, &pTypeLib); - if (SUCCEEDED(hr)) { - typelib = create_win32ole_typelib(pTypeLib); - rb_ary_push(typelibs, typelib); - } - } - } - RegCloseKey(hguid); - } - RegCloseKey(htypelib); - return typelibs; -} - -static VALUE -oletypelib_set_member(VALUE self, ITypeLib *pTypeLib) -{ - struct oletypelibdata *ptlib; - TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib); - ptlib->pTypeLib = pTypeLib; - return self; -} - -static void -oletypelib_free(void *ptr) -{ - struct oletypelibdata *poletypelib = ptr; - OLE_FREE(poletypelib->pTypeLib); - free(poletypelib); -} - -static size_t -oletypelib_size(const void *ptr) -{ - return ptr ? sizeof(struct oletypelibdata) : 0; -} - -static VALUE -foletypelib_s_allocate(VALUE klass) -{ - struct oletypelibdata *poletypelib; - VALUE obj; - ole_initialize(); - obj = TypedData_Make_Struct(klass, struct oletypelibdata, &oletypelib_datatype, poletypelib); - poletypelib->pTypeLib = NULL; - return obj; -} - -VALUE -create_win32ole_typelib(ITypeLib *pTypeLib) -{ - VALUE obj = foletypelib_s_allocate(cWIN32OLE_TYPELIB); - oletypelib_set_member(obj, pTypeLib); - return obj; -} - -static VALUE -oletypelib_search_registry(VALUE self, VALUE typelib) -{ - HKEY htypelib, hguid, hversion; - DWORD i, j; - LONG err; - VALUE found = Qfalse; - VALUE tlib; - VALUE guid; - VALUE ver; - HRESULT hr; - ITypeLib *pTypeLib; - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return Qfalse; - } - for(i = 0; !found; i++) { - guid = reg_enum_key(htypelib, i); - if (guid == Qnil) - break; - err = reg_open_vkey(htypelib, guid, &hguid); - if (err != ERROR_SUCCESS) - continue; - for(j = 0; found == Qfalse; j++) { - ver = reg_enum_key(hguid, j); - if (ver == Qnil) - break; - err = reg_open_vkey(hguid, ver, &hversion); - if (err != ERROR_SUCCESS) - continue; - tlib = reg_get_val(hversion, NULL); - if (tlib == Qnil) { - RegCloseKey(hversion); - continue; - } - if (rb_str_cmp(typelib, tlib) == 0) { - hr = oletypelib_from_guid(guid, ver, &pTypeLib); - if (SUCCEEDED(hr)) { - oletypelib_set_member(self, pTypeLib); - found = Qtrue; - } - } - RegCloseKey(hversion); - } - RegCloseKey(hguid); - } - RegCloseKey(htypelib); - return found; -} - -static void -oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr) -{ - HRESULT hr; - hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "failed to get library attribute(TLIBATTR) from ITypeLib"); - } -} - -static VALUE -oletypelib_search_registry2(VALUE self, VALUE args) -{ - HKEY htypelib, hguid, hversion; - double fver; - DWORD j; - LONG err; - VALUE found = Qfalse; - VALUE tlib; - VALUE ver; - VALUE version_str; - VALUE version = Qnil; - VALUE typelib = Qnil; - HRESULT hr; - ITypeLib *pTypeLib; - - VALUE guid = rb_ary_entry(args, 0); - version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2)); - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return Qfalse; - } - err = reg_open_vkey(htypelib, guid, &hguid); - if (err != ERROR_SUCCESS) { - RegCloseKey(htypelib); - return Qfalse; - } - if (version_str != Qnil) { - err = reg_open_vkey(hguid, version_str, &hversion); - if (err == ERROR_SUCCESS) { - tlib = reg_get_val(hversion, NULL); - if (tlib != Qnil) { - typelib = tlib; - version = version_str; - } - } - RegCloseKey(hversion); - } else { - fver = 0.0; - for(j = 0; ;j++) { - ver = reg_enum_key(hguid, j); - if (ver == Qnil) - break; - err = reg_open_vkey(hguid, ver, &hversion); - if (err != ERROR_SUCCESS) - continue; - tlib = reg_get_val(hversion, NULL); - if (tlib == Qnil) { - RegCloseKey(hversion); - continue; - } - if (fver < atof(StringValuePtr(ver))) { - fver = atof(StringValuePtr(ver)); - version = ver; - typelib = tlib; - } - RegCloseKey(hversion); - } - } - RegCloseKey(hguid); - RegCloseKey(htypelib); - if (typelib != Qnil) { - hr = oletypelib_from_guid(guid, version, &pTypeLib); - if (SUCCEEDED(hr)) { - found = Qtrue; - oletypelib_set_member(self, pTypeLib); - } - } - return found; -} - - -/* - * call-seq: - * WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object - * - * Returns a new WIN32OLE_TYPELIB object. - * - * The first argument <i>typelib</i> specifies OLE type library name or GUID or - * OLE library file. - * The second argument is major version or version of the type library. - * The third argument is minor version. - * The second argument and third argument are optional. - * If the first argument is type library name, then the second and third argument - * are ignored. - * - * tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}') - * tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3) - * tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3) - * tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL") - * puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library' - * puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library' - * puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library' - * puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library' - * puts tlib5.name # -> 'Microsoft Shell Controls And Automation' - * - */ -static VALUE -foletypelib_initialize(VALUE self, VALUE args) -{ - VALUE found = Qfalse; - VALUE typelib = Qnil; - int len = 0; - OLECHAR * pbuf; - ITypeLib *pTypeLib; - HRESULT hr = S_OK; - - len = RARRAY_LEN(args); - rb_check_arity(len, 1, 3); - - typelib = rb_ary_entry(args, 0); - - SafeStringValue(typelib); - - found = oletypelib_search_registry(self, typelib); - if (found == Qfalse) { - found = oletypelib_search_registry2(self, args); - } - if (found == Qfalse) { - pbuf = ole_vstr2wc(typelib); - hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); - SysFreeString(pbuf); - if (SUCCEEDED(hr)) { - found = Qtrue; - oletypelib_set_member(self, pTypeLib); - } - } - - if (found == Qfalse) { - rb_raise(eWIN32OLERuntimeError, "not found type library `%s`", - StringValuePtr(typelib)); - } - return self; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#guid -> The guid string. - * - * Returns guid string which specifies type library. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}' - */ -static VALUE -foletypelib_guid(VALUE self) -{ - ITypeLib *pTypeLib; - OLECHAR bstr[80]; - VALUE guid = Qnil; - int len; - TLIBATTR *pTLibAttr; - - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR)); - if (len > 3) { - guid = ole_wc2vstr(bstr, FALSE); - } - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - return guid; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#name -> The type library name - * - * Returns the type library name. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * name = tlib.name # -> 'Microsoft Excel 9.0 Object Library' - */ -static VALUE -foletypelib_name(VALUE self) -{ - ITypeLib *pTypeLib; - HRESULT hr; - BSTR bstr; - VALUE name; - pTypeLib = itypelib(self); - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1, - NULL, &bstr, NULL, NULL); - - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib"); - } - name = WC2VSTR(bstr); - return name; -} - -static VALUE -make_version_str(VALUE major, VALUE minor) -{ - VALUE version_str = Qnil; - VALUE minor_str = Qnil; - if (major == Qnil) { - return Qnil; - } - version_str = rb_String(major); - if (minor != Qnil) { - minor_str = rb_String(minor); - rb_str_cat2(version_str, "."); - rb_str_append(version_str, minor_str); - } - return version_str; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#version -> The type library version String object. - * - * Returns the type library version. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * puts tlib.version #-> "1.3" - */ -static VALUE -foletypelib_version(VALUE self) -{ - TLIBATTR *pTLibAttr; - ITypeLib *pTypeLib; - VALUE version; - - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - version = rb_sprintf("%d.%d", pTLibAttr->wMajorVerNum, pTLibAttr->wMinorVerNum); - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - return version; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#major_version -> The type library major version. - * - * Returns the type library major version. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * puts tlib.major_version # -> 1 - */ -static VALUE -foletypelib_major_version(VALUE self) -{ - TLIBATTR *pTLibAttr; - VALUE major; - ITypeLib *pTypeLib; - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - - major = RB_INT2NUM(pTLibAttr->wMajorVerNum); - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - return major; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#minor_version -> The type library minor version. - * - * Returns the type library minor version. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * puts tlib.minor_version # -> 3 - */ -static VALUE -foletypelib_minor_version(VALUE self) -{ - TLIBATTR *pTLibAttr; - VALUE minor; - ITypeLib *pTypeLib; - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - minor = RB_INT2NUM(pTLibAttr->wMinorVerNum); - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - return minor; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#path -> The type library file path. - * - * Returns the type library file path. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * puts tlib.path #-> 'C:\...\EXCEL9.OLB' - */ -static VALUE -foletypelib_path(VALUE self) -{ - TLIBATTR *pTLibAttr; - HRESULT hr = S_OK; - BSTR bstr; - LCID lcid = cWIN32OLE_lcid; - VALUE path; - ITypeLib *pTypeLib; - - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - hr = QueryPathOfRegTypeLib(&pTLibAttr->guid, - pTLibAttr->wMajorVerNum, - pTLibAttr->wMinorVerNum, - lcid, - &bstr); - if (FAILED(hr)) { - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib"); - } - - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - path = WC2VSTR(bstr); - return path; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#visible? - * - * Returns true if the type library information is not hidden. - * If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN, - * the method returns false, otherwise, returns true. - * If the method fails to access the TLIBATTR information, then - * WIN32OLERuntimeError is raised. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * tlib.visible? # => true - */ -static VALUE -foletypelib_visible(VALUE self) -{ - ITypeLib *pTypeLib = NULL; - VALUE visible = Qtrue; - TLIBATTR *pTLibAttr; - - pTypeLib = itypelib(self); - oletypelib_get_libattr(pTypeLib, &pTLibAttr); - - if ((pTLibAttr->wLibFlags == 0) || - (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) || - (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) { - visible = Qfalse; - } - pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); - return visible; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#library_name - * - * Returns library name. - * If the method fails to access library name, WIN32OLERuntimeError is raised. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * tlib.library_name # => Excel - */ -static VALUE -foletypelib_library_name(VALUE self) -{ - HRESULT hr; - ITypeLib *pTypeLib = NULL; - VALUE libname = Qnil; - BSTR bstr; - - pTypeLib = itypelib(self); - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name"); - } - libname = WC2VSTR(bstr); - return libname; -} - -static VALUE -ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes) -{ - long count; - int i; - HRESULT hr; - BSTR bstr; - ITypeInfo *pTypeInfo; - VALUE type; - - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count; i++) { - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) - continue; - - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); - if (FAILED(hr)) - continue; - - type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr)); - - rb_ary_push(classes, type); - OLE_RELEASE(pTypeInfo); - } - return classes; -} - -static VALUE -typelib_file_from_typelib(VALUE ole) -{ - HKEY htypelib, hclsid, hversion, hlang; - double fver; - DWORD i, j, k; - LONG err; - BOOL found = FALSE; - VALUE typelib; - VALUE file = Qnil; - VALUE clsid; - VALUE ver; - VALUE lang; - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return Qnil; - } - for(i = 0; !found; i++) { - clsid = reg_enum_key(htypelib, i); - if (clsid == Qnil) - break; - err = reg_open_vkey(htypelib, clsid, &hclsid); - if (err != ERROR_SUCCESS) - continue; - fver = 0; - for(j = 0; !found; j++) { - ver = reg_enum_key(hclsid, j); - if (ver == Qnil) - break; - err = reg_open_vkey(hclsid, ver, &hversion); - if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver))) - continue; - fver = atof(StringValuePtr(ver)); - typelib = reg_get_val(hversion, NULL); - if (typelib == Qnil) - continue; - if (rb_str_cmp(typelib, ole) == 0) { - for(k = 0; !found; k++) { - lang = reg_enum_key(hversion, k); - if (lang == Qnil) - break; - err = reg_open_vkey(hversion, lang, &hlang); - if (err == ERROR_SUCCESS) { - if ((file = reg_get_typelib_file_path(hlang)) != Qnil) - found = TRUE; - RegCloseKey(hlang); - } - } - } - RegCloseKey(hversion); - } - RegCloseKey(hclsid); - } - RegCloseKey(htypelib); - return file; -} - -static VALUE -typelib_file_from_clsid(VALUE ole) -{ - HKEY hroot, hclsid; - LONG err; - VALUE typelib; - char path[MAX_PATH + 1]; - - err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot); - if (err != ERROR_SUCCESS) { - return Qnil; - } - err = reg_open_key(hroot, StringValuePtr(ole), &hclsid); - if (err != ERROR_SUCCESS) { - RegCloseKey(hroot); - return Qnil; - } - typelib = reg_get_val2(hclsid, "InprocServer32"); - RegCloseKey(hroot); - RegCloseKey(hclsid); - if (typelib != Qnil) { - ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path)); - path[MAX_PATH] = '\0'; - typelib = rb_str_new2(path); - } - return typelib; -} - -VALUE -typelib_file(VALUE ole) -{ - VALUE file = typelib_file_from_clsid(ole); - if (file != Qnil) { - return file; - } - return typelib_file_from_typelib(ole); -} - - -/* - * call-seq: - * WIN32OLE_TYPELIB#ole_types -> The array of WIN32OLE_TYPE object included the type library. - * - * Returns the type library file path. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...] - */ -static VALUE -foletypelib_ole_types(VALUE self) -{ - ITypeLib *pTypeLib = NULL; - VALUE classes = rb_ary_new(); - pTypeLib = itypelib(self); - ole_types_from_typelib(pTypeLib, classes); - return classes; -} - -/* - * call-seq: - * WIN32OLE_TYPELIB#inspect -> String - * - * Returns the type library name with class name. - * - * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library') - * tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>" - */ -static VALUE -foletypelib_inspect(VALUE self) -{ - return default_inspect(self, "WIN32OLE_TYPELIB"); -} - -VALUE cWIN32OLE_TYPELIB; - -void -Init_win32ole_typelib(void) -{ - cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject); - rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0); - rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate); - rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2); - rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0); - rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0); - rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0); - rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0); - rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0); - rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0); - rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0); - rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types"); - rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0); - rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0); - rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name"); - rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0); -} diff --git a/ext/win32ole/win32ole_typelib.h b/ext/win32ole/win32ole_typelib.h deleted file mode 100644 index 2c2730bb58..0000000000 --- a/ext/win32ole/win32ole_typelib.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef WIN32OLE_TYPELIB_H -#define WIN32OLE_TYPELIB_H 1 - -extern VALUE cWIN32OLE_TYPELIB; - -void Init_win32ole_typelib(void); -ITypeLib * itypelib(VALUE self); -VALUE typelib_file(VALUE ole); -VALUE create_win32ole_typelib(ITypeLib *pTypeLib); -VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo); -#endif diff --git a/ext/win32ole/win32ole_variable.c b/ext/win32ole/win32ole_variable.c deleted file mode 100644 index 803083156c..0000000000 --- a/ext/win32ole/win32ole_variable.c +++ /dev/null @@ -1,382 +0,0 @@ -#include "win32ole.h" - -struct olevariabledata { - ITypeInfo *pTypeInfo; - UINT index; -}; - -static void olevariable_free(void *ptr); -static size_t olevariable_size(const void *ptr); -static VALUE folevariable_name(VALUE self); -static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_ole_type(VALUE self); -static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_ole_type_detail(VALUE self); -static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_value(VALUE self); -static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_visible(VALUE self); -static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_variable_kind(VALUE self); -static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_varkind(VALUE self); -static VALUE folevariable_inspect(VALUE self); - -static const rb_data_type_t olevariable_datatype = { - "win32ole_variable", - {NULL, olevariable_free, olevariable_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static void -olevariable_free(void *ptr) -{ - struct olevariabledata *polevar = ptr; - OLE_FREE(polevar->pTypeInfo); - free(polevar); -} - -static size_t -olevariable_size(const void *ptr) -{ - return ptr ? sizeof(struct olevariabledata) : 0; -} - -/* - * Document-class: WIN32OLE_VARIABLE - * - * <code>WIN32OLE_VARIABLE</code> objects represent OLE variable information. - */ - -VALUE -create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name) -{ - struct olevariabledata *pvar; - VALUE obj = TypedData_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata, - &olevariable_datatype, pvar); - pvar->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pvar->index = index; - rb_ivar_set(obj, rb_intern("name"), name); - return obj; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#name - * - * Returns the name of variable. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name}" - * end - * - * The result of above script is following: - * xlChart - * xlDialogSheet - * xlExcel4IntlMacroSheet - * xlExcel4MacroSheet - * xlWorksheet - * - */ -static VALUE -folevariable_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE type; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); - type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#ole_type - * - * Returns OLE type string. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.ole_type} #{variable.name}" - * end - * - * The result of above script is following: - * INT xlChart - * INT xlDialogSheet - * INT xlExcel4IntlMacroSheet - * INT xlExcel4MacroSheet - * INT xlWorksheet - * - */ -static VALUE -folevariable_ole_type(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_ole_type(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE type = rb_ary_new(); - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); - ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#ole_type_detail - * - * Returns detail information of type. The information is array of type. - * - * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS') - * variable = tobj.variables.find {|variable| variable.name == 'lFlags'} - * tdetail = variable.ole_type_detail - * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"] - * - */ -static VALUE -folevariable_ole_type_detail(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE val = Qnil; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return Qnil; - if(pVarDesc->varkind == VAR_CONST) - val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue)); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return val; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#value - * - * Returns value if value is exists. If the value does not exist, - * this method returns nil. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.value}" - * end - * - * The result of above script is following: - * xlChart = -4109 - * xlDialogSheet = -4116 - * xlExcel4IntlMacroSheet = 4 - * xlExcel4MacroSheet = 3 - * xlWorksheet = -4167 - * - */ -static VALUE -folevariable_value(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_value(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE visible = Qfalse; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return visible; - if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN | - VARFLAG_FRESTRICTED | - VARFLAG_FNONBROWSABLE))) { - visible = Qtrue; - } - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return visible; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#visible? - * - * Returns true if the variable is public. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.visible?}" - * end - * - * The result of above script is following: - * xlChart true - * xlDialogSheet true - * xlExcel4IntlMacroSheet true - * xlExcel4MacroSheet true - * xlWorksheet true - * - */ -static VALUE -folevariable_visible(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_visible(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE kind = rb_str_new2("UNKNOWN"); - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return kind; - switch(pVarDesc->varkind) { - case VAR_PERINSTANCE: - kind = rb_str_new2("PERINSTANCE"); - break; - case VAR_STATIC: - kind = rb_str_new2("STATIC"); - break; - case VAR_CONST: - kind = rb_str_new2("CONSTANT"); - break; - case VAR_DISPATCH: - kind = rb_str_new2("DISPATCH"); - break; - default: - break; - } - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return kind; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#variable_kind - * - * Returns variable kind string. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.variable_kind}" - * end - * - * The result of above script is following: - * xlChart CONSTANT - * xlDialogSheet CONSTANT - * xlExcel4IntlMacroSheet CONSTANT - * xlExcel4MacroSheet CONSTANT - * xlWorksheet CONSTANT - */ -static VALUE -folevariable_variable_kind(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_kind(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE kind = Qnil; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return kind; - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - kind = RB_INT2FIX(pVarDesc->varkind); - return kind; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#varkind - * - * Returns the number which represents variable kind. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.varkind}" - * end - * - * The result of above script is following: - * xlChart 2 - * xlDialogSheet 2 - * xlExcel4IntlMacroSheet 2 - * xlExcel4MacroSheet 2 - * xlWorksheet 2 - */ -static VALUE -folevariable_varkind(VALUE self) -{ - struct olevariabledata *pvar; - TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar); - return ole_variable_varkind(pvar->pTypeInfo, pvar->index); -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#inspect -> String - * - * Returns the OLE variable name and the value with class name. - * - */ -static VALUE -folevariable_inspect(VALUE self) -{ - VALUE v = rb_inspect(folevariable_value(self)); - VALUE n = folevariable_name(self); - VALUE detail = rb_sprintf("%"PRIsVALUE"=%"PRIsVALUE, n, v); - return make_inspect("WIN32OLE_VARIABLE", detail); -} - -VALUE cWIN32OLE_VARIABLE; - -void Init_win32ole_variable(void) -{ - cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject); - rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0); - rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0); - rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0); - rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0); - rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0); - rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0); - rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0); - rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0); - rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name"); -} diff --git a/ext/win32ole/win32ole_variable.h b/ext/win32ole/win32ole_variable.h deleted file mode 100644 index 209613fd44..0000000000 --- a/ext/win32ole/win32ole_variable.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WIN32OLE_VARIABLE_H -#define WIN32OLE_VARIABLE_H 1 - -extern VALUE cWIN32OLE_VARIABLE; -VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name); -void Init_win32ole_variable(void); - -#endif diff --git a/ext/win32ole/win32ole_variant.c b/ext/win32ole/win32ole_variant.c deleted file mode 100644 index 0953fc324c..0000000000 --- a/ext/win32ole/win32ole_variant.c +++ /dev/null @@ -1,735 +0,0 @@ -#include "win32ole.h" - -struct olevariantdata { - VARIANT realvar; - VARIANT var; -}; - -static void olevariant_free(void *ptr); -static size_t olevariant_size(const void *ptr); -static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar); -static void ole_val2variant_err(VALUE val, VARIANT *var); -static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt); -static VALUE folevariant_s_allocate(VALUE klass); -static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt); -static void check_type_val2variant(VALUE val); -static VALUE folevariant_initialize(VALUE self, VALUE args); -static LONG *ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa); -static void unlock_safe_array(SAFEARRAY *psa); -static SAFEARRAY *get_locked_safe_array(VALUE val); -static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self); -static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self); -static VALUE folevariant_value(VALUE self); -static VALUE folevariant_vartype(VALUE self); -static VALUE folevariant_set_value(VALUE self, VALUE val); - -static const rb_data_type_t olevariant_datatype = { - "win32ole_variant", - {NULL, olevariant_free, olevariant_size,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; - -static void -olevariant_free(void *ptr) -{ - struct olevariantdata *pvar = ptr; - VariantClear(&(pvar->realvar)); - VariantClear(&(pvar->var)); - free(pvar); -} - -static size_t -olevariant_size(const void *ptr) -{ - return ptr ? sizeof(struct olevariantdata) : 0; -} - -static void -ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar) -{ - HRESULT hr = S_OK; - - if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && RB_TYPE_P(val, T_STRING)) { - long len = RSTRING_LEN(val); - void *pdest = NULL; - SAFEARRAY *p = NULL; - SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len); - if (!psa) { - rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector"); - } - hr = SafeArrayAccessData(psa, &pdest); - if (SUCCEEDED(hr)) { - memcpy(pdest, RSTRING_PTR(val), len); - SafeArrayUnaccessData(psa); - V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF); - p = V_ARRAY(&(pvar->realvar)); - if (p != NULL) { - SafeArrayDestroy(p); - } - V_ARRAY(&(pvar->realvar)) = psa; - if (vt & VT_BYREF) { - V_VT(&(pvar->var)) = vt; - V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); - } else { - hr = VariantCopy(&(pvar->var), &(pvar->realvar)); - } - } else { - if (psa) - SafeArrayDestroy(psa); - } - } else if (vt & VT_ARRAY) { - if (val == Qnil) { - V_VT(&(pvar->var)) = vt; - if (vt & VT_BYREF) { - V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); - } - } else { - hr = ole_val_ary2variant_ary(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF)); - if (SUCCEEDED(hr)) { - if (vt & VT_BYREF) { - V_VT(&(pvar->var)) = vt; - V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); - } else { - hr = VariantCopy(&(pvar->var), &(pvar->realvar)); - } - } - } -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - } else if ( (vt & ~VT_BYREF) == VT_I8 || (vt & ~VT_BYREF) == VT_UI8) { - ole_val2variant_ex(val, &(pvar->realvar), (vt & ~VT_BYREF)); - ole_val2variant_ex(val, &(pvar->var), (vt & ~VT_BYREF)); - V_VT(&(pvar->var)) = vt; - if (vt & VT_BYREF) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } -#endif - } else if ( (vt & ~VT_BYREF) == VT_ERROR) { - ole_val2variant_err(val, &(pvar->realvar)); - if (vt & VT_BYREF) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } else { - hr = VariantCopy(&(pvar->var), &(pvar->realvar)); - } - } else { - if (val == Qnil) { - V_VT(&(pvar->var)) = vt; - if (vt == (VT_BYREF | VT_VARIANT)) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } else { - V_VT(&(pvar->realvar)) = vt & ~VT_BYREF; - if (vt & VT_BYREF) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } - } - } else { - ole_val2variant_ex(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF)); - if (vt == (VT_BYREF | VT_VARIANT)) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } else if (vt & VT_BYREF) { - if ( (vt & ~VT_BYREF) != V_VT(&(pvar->realvar))) { - hr = VariantChangeTypeEx(&(pvar->realvar), &(pvar->realvar), - cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF)); - } - if (SUCCEEDED(hr)) { - ole_set_byref(&(pvar->realvar), &(pvar->var), vt); - } - } else { - if (vt == V_VT(&(pvar->realvar))) { - hr = VariantCopy(&(pvar->var), &(pvar->realvar)); - } else { - hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar), - cWIN32OLE_lcid, 0, vt); - } - } - } - } - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to change type"); - } -} - -static void -ole_val2variant_err(VALUE val, VARIANT *var) -{ - VALUE v = val; - if (rb_obj_is_kind_of(v, cWIN32OLE_VARIANT)) { - v = folevariant_value(v); - } - if (!(FIXNUM_P(v) || RB_TYPE_P(v, T_BIGNUM) || v == Qnil)) { - rb_raise(eWIN32OLERuntimeError, "failed to convert VT_ERROR VARIANT:`%"PRIsVALUE"'", rb_inspect(v)); - } - V_VT(var) = VT_ERROR; - if (v != Qnil) { - V_ERROR(var) = RB_NUM2LONG(val); - } else { - V_ERROR(var) = 0; - } -} - -static void -ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt) -{ - V_VT(var) = vt; - if (vt == (VT_VARIANT|VT_BYREF)) { - V_VARIANTREF(var) = realvar; - } else { - if (V_VT(realvar) != (vt & ~VT_BYREF)) { - rb_raise(eWIN32OLERuntimeError, "variant type mismatch"); - } - switch(vt & ~VT_BYREF) { - case VT_I1: - V_I1REF(var) = &V_I1(realvar); - break; - case VT_UI1: - V_UI1REF(var) = &V_UI1(realvar); - break; - case VT_I2: - V_I2REF(var) = &V_I2(realvar); - break; - case VT_UI2: - V_UI2REF(var) = &V_UI2(realvar); - break; - case VT_I4: - V_I4REF(var) = &V_I4(realvar); - break; - case VT_UI4: - V_UI4REF(var) = &V_UI4(realvar); - break; - case VT_R4: - V_R4REF(var) = &V_R4(realvar); - break; - case VT_R8: - V_R8REF(var) = &V_R8(realvar); - break; - -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) -#ifdef V_I8REF - case VT_I8: - V_I8REF(var) = &V_I8(realvar); - break; -#endif -#ifdef V_UI8REF - case VT_UI8: - V_UI8REF(var) = &V_UI8(realvar); - break; -#endif -#endif - case VT_INT: - V_INTREF(var) = &V_INT(realvar); - break; - - case VT_UINT: - V_UINTREF(var) = &V_UINT(realvar); - break; - - case VT_CY: - V_CYREF(var) = &V_CY(realvar); - break; - case VT_DATE: - V_DATEREF(var) = &V_DATE(realvar); - break; - case VT_BSTR: - V_BSTRREF(var) = &V_BSTR(realvar); - break; - case VT_DISPATCH: - V_DISPATCHREF(var) = &V_DISPATCH(realvar); - break; - case VT_ERROR: - V_ERRORREF(var) = &V_ERROR(realvar); - break; - case VT_BOOL: - V_BOOLREF(var) = &V_BOOL(realvar); - break; - case VT_UNKNOWN: - V_UNKNOWNREF(var) = &V_UNKNOWN(realvar); - break; - case VT_ARRAY: - V_ARRAYREF(var) = &V_ARRAY(realvar); - break; - default: - rb_raise(eWIN32OLERuntimeError, "unknown type specified(setting BYREF):%d", vt); - break; - } - } -} - -static VALUE -folevariant_s_allocate(VALUE klass) -{ - struct olevariantdata *pvar; - VALUE obj; - ole_initialize(); - obj = TypedData_Make_Struct(klass, struct olevariantdata, &olevariant_datatype, pvar); - VariantInit(&(pvar->var)); - VariantInit(&(pvar->realvar)); - return obj; -} - -/* - * call-seq: - * WIN32OLE_VARIANT.array(ary, vt) - * - * Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY. - * The first argument should be Array object which specifies dimensions - * and each size of dimensions of OLE array. - * The second argument specifies variant type of the element of OLE array. - * - * The following create 2 dimensions OLE array. The first dimensions size - * is 3, and the second is 4. - * - * ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4) - * ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] - * - */ -static VALUE -folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt) -{ - VALUE obj = Qnil; - VARTYPE vt; - struct olevariantdata *pvar; - SAFEARRAYBOUND *psab = NULL; - SAFEARRAY *psa = NULL; - UINT dim = 0; - UINT i = 0; - - ole_initialize(); - - vt = RB_NUM2UINT(vvt); - vt = (vt | VT_ARRAY); - Check_Type(elems, T_ARRAY); - obj = folevariant_s_allocate(klass); - - TypedData_Get_Struct(obj, struct olevariantdata, &olevariant_datatype, pvar); - dim = RARRAY_LEN(elems); - - psab = ALLOC_N(SAFEARRAYBOUND, dim); - - if(!psab) { - rb_raise(rb_eRuntimeError, "memory allocation error"); - } - - for (i = 0; i < dim; i++) { - psab[i].cElements = RB_FIX2INT(rb_ary_entry(elems, i)); - psab[i].lLbound = 0; - } - - psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab); - if (psa == NULL) { - if (psab) free(psab); - rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)"); - } - - V_VT(&(pvar->var)) = vt; - if (vt & VT_BYREF) { - V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF); - V_ARRAY(&(pvar->realvar)) = psa; - V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); - } else { - V_ARRAY(&(pvar->var)) = psa; - } - if (psab) free(psab); - return obj; -} - -static void -check_type_val2variant(VALUE val) -{ - VALUE elem; - int len = 0; - int i = 0; - if(!rb_obj_is_kind_of(val, cWIN32OLE) && - !rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) && - !rb_obj_is_kind_of(val, rb_cTime)) { - switch (TYPE(val)) { - case T_ARRAY: - len = RARRAY_LEN(val); - for(i = 0; i < len; i++) { - elem = rb_ary_entry(val, i); - check_type_val2variant(elem); - } - break; - case T_STRING: - case T_FIXNUM: - case T_BIGNUM: - case T_FLOAT: - case T_TRUE: - case T_FALSE: - case T_NIL: - break; - default: - rb_raise(rb_eTypeError, "can not convert WIN32OLE_VARIANT from type %s", - rb_obj_classname(val)); - } - } -} - -/* - * Document-class: WIN32OLE_VARIANT - * - * <code>WIN32OLE_VARIANT</code> objects represents OLE variant. - * - * Win32OLE converts Ruby object into OLE variant automatically when - * invoking OLE methods. If OLE method requires the argument which is - * different from the variant by automatic conversion of Win32OLE, you - * can convert the specified variant type by using WIN32OLE_VARIANT class. - * - * param = WIN32OLE_VARIANT.new(10, WIN32OLE::VARIANT::VT_R4) - * oleobj.method(param) - * - * WIN32OLE_VARIANT does not support VT_RECORD variant. Use WIN32OLE_RECORD - * class instead of WIN32OLE_VARIANT if the VT_RECORD variant is needed. - */ - -/* - * call-seq: - * WIN32OLE_VARIANT.new(val, vartype) #=> WIN32OLE_VARIANT object. - * - * Returns Ruby object wrapping OLE variant. - * The first argument specifies Ruby object to convert OLE variant variable. - * The second argument specifies VARIANT type. - * In some situation, you need the WIN32OLE_VARIANT object to pass OLE method - * - * shell = WIN32OLE.new("Shell.Application") - * folder = shell.NameSpace("C:\\Windows") - * item = folder.ParseName("tmp.txt") - * # You can't use Ruby String object to call FolderItem.InvokeVerb. - * # Instead, you have to use WIN32OLE_VARIANT object to call the method. - * shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)") - * item.invokeVerb(shortcut) - * - */ -static VALUE -folevariant_initialize(VALUE self, VALUE args) -{ - int len = 0; - VARIANT var; - VALUE val; - VALUE vvt; - VARTYPE vt; - struct olevariantdata *pvar; - - len = RARRAY_LEN(args); - rb_check_arity(len, 1, 3); - VariantInit(&var); - val = rb_ary_entry(args, 0); - - check_type_val2variant(val); - - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - if (len == 1) { - ole_val2variant(val, &(pvar->var)); - } else { - vvt = rb_ary_entry(args, 1); - vt = RB_NUM2INT(vvt); - if ((vt & VT_TYPEMASK) == VT_RECORD) { - rb_raise(rb_eArgError, "not supported VT_RECORD WIN32OLE_VARIANT object"); - } - ole_val2olevariantdata(val, vt, pvar); - } - return self; -} - -static SAFEARRAY * -get_locked_safe_array(VALUE val) -{ - struct olevariantdata *pvar; - SAFEARRAY *psa = NULL; - HRESULT hr; - TypedData_Get_Struct(val, struct olevariantdata, &olevariant_datatype, pvar); - if (!(V_VT(&(pvar->var)) & VT_ARRAY)) { - rb_raise(rb_eTypeError, "variant type is not VT_ARRAY."); - } - psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var)); - if (psa == NULL) { - return psa; - } - hr = SafeArrayLock(psa); - if (FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock"); - } - return psa; -} - -static LONG * -ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa) -{ - long dim; - LONG *pid; - long i; - dim = SafeArrayGetDim(psa); - if (dim != ary_size) { - rb_raise(rb_eArgError, "unmatch number of indices"); - } - pid = ALLOC_N(LONG, dim); - if (pid == NULL) { - rb_raise(rb_eRuntimeError, "failed to allocate memory for indices"); - } - for (i = 0; i < dim; i++) { - pid[i] = RB_NUM2INT(ary[i]); - } - return pid; -} - -static void -unlock_safe_array(SAFEARRAY *psa) -{ - HRESULT hr; - hr = SafeArrayUnlock(psa); - if (FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayUnlock"); - } -} - -/* - * call-seq: - * WIN32OLE_VARIANT[i,j,...] #=> element of OLE array. - * - * Returns the element of WIN32OLE_VARIANT object(OLE array). - * This method is available only when the variant type of - * WIN32OLE_VARIANT object is VT_ARRAY. - * - * REMARK: - * The all indices should be 0 or natural number and - * lower than or equal to max indices. - * (This point is different with Ruby Array indices.) - * - * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]]) - * p obj[0,0] # => 1 - * p obj[1,0] # => 4 - * p obj[2,0] # => WIN32OLERuntimeError - * p obj[0, -1] # => WIN32OLERuntimeError - * - */ -static VALUE -folevariant_ary_aref(int argc, VALUE *argv, VALUE self) -{ - struct olevariantdata *pvar; - SAFEARRAY *psa; - VALUE val = Qnil; - VARIANT variant; - LONG *pid; - HRESULT hr; - - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - if (!V_ISARRAY(&(pvar->var))) { - rb_raise(eWIN32OLERuntimeError, - "`[]' is not available for this variant type object"); - } - psa = get_locked_safe_array(self); - if (psa == NULL) { - return val; - } - - pid = ary2safe_array_index(argc, argv, psa); - - VariantInit(&variant); - V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF; - hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant)); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex"); - } - val = ole_variant2val(&variant); - - unlock_safe_array(psa); - if (pid) free(pid); - return val; -} - -/* - * call-seq: - * WIN32OLE_VARIANT[i,j,...] = val #=> set the element of OLE array - * - * Set the element of WIN32OLE_VARIANT object(OLE array) to val. - * This method is available only when the variant type of - * WIN32OLE_VARIANT object is VT_ARRAY. - * - * REMARK: - * The all indices should be 0 or natural number and - * lower than or equal to max indices. - * (This point is different with Ruby Array indices.) - * - * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]]) - * obj[0,0] = 7 - * obj[1,0] = 8 - * p obj.value # => [[7,2,3], [8,5,6]] - * obj[2,0] = 9 # => WIN32OLERuntimeError - * obj[0, -1] = 9 # => WIN32OLERuntimeError - * - */ -static VALUE -folevariant_ary_aset(int argc, VALUE *argv, VALUE self) -{ - struct olevariantdata *pvar; - SAFEARRAY *psa; - VARIANT var; - VARTYPE vt; - LONG *pid; - HRESULT hr; - VOID *p = NULL; - - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - if (!V_ISARRAY(&(pvar->var))) { - rb_raise(eWIN32OLERuntimeError, - "`[]' is not available for this variant type object"); - } - psa = get_locked_safe_array(self); - if (psa == NULL) { - rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer"); - } - - pid = ary2safe_array_index(argc-1, argv, psa); - - VariantInit(&var); - vt = (V_VT(&(pvar->var)) & ~VT_ARRAY); - p = val2variant_ptr(argv[argc-1], &var, vt); - if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) || - (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) { - rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface"); - } - hr = SafeArrayPutElement(psa, pid, p); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement"); - } - - unlock_safe_array(psa); - if (pid) free(pid); - return argv[argc-1]; -} - -/* - * call-seq: - * WIN32OLE_VARIANT.value #=> Ruby object. - * - * Returns Ruby object value from OLE variant. - * obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR) - * obj.value # => "1" (not Integer object, but String object "1") - * - */ -static VALUE -folevariant_value(VALUE self) -{ - struct olevariantdata *pvar; - VALUE val = Qnil; - VARTYPE vt; - int dim; - SAFEARRAY *psa; - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - - val = ole_variant2val(&(pvar->var)); - vt = V_VT(&(pvar->var)); - - if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) { - if (vt & VT_BYREF) { - psa = *V_ARRAYREF(&(pvar->var)); - } else { - psa = V_ARRAY(&(pvar->var)); - } - if (!psa) { - return val; - } - dim = SafeArrayGetDim(psa); - if (dim == 1) { - val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*")); - } - } - return val; -} - -/* - * call-seq: - * WIN32OLE_VARIANT.vartype #=> OLE variant type. - * - * Returns OLE variant type. - * obj = WIN32OLE_VARIANT.new("string") - * obj.vartype # => WIN32OLE::VARIANT::VT_BSTR - * - */ -static VALUE -folevariant_vartype(VALUE self) -{ - struct olevariantdata *pvar; - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - return RB_INT2FIX(V_VT(&pvar->var)); -} - -/* - * call-seq: - * WIN32OLE_VARIANT.value = val #=> set WIN32OLE_VARIANT value to val. - * - * Sets variant value to val. If the val type does not match variant value - * type(vartype), then val is changed to match variant value type(vartype) - * before setting val. - * This method is not available when vartype is VT_ARRAY(except VT_UI1|VT_ARRAY). - * If the vartype is VT_UI1|VT_ARRAY, the val should be String object. - * - * obj = WIN32OLE_VARIANT.new(1) # obj.vartype is WIN32OLE::VARIANT::VT_I4 - * obj.value = 3.2 # 3.2 is changed to 3 when setting value. - * p obj.value # => 3 - */ -static VALUE -folevariant_set_value(VALUE self, VALUE val) -{ - struct olevariantdata *pvar; - VARTYPE vt; - TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); - vt = V_VT(&(pvar->var)); - if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || !RB_TYPE_P(val, T_STRING))) { - rb_raise(eWIN32OLERuntimeError, - "`value=' is not available for this variant type object"); - } - ole_val2olevariantdata(val, vt, pvar); - return Qnil; -} - -void -ole_variant2variant(VALUE val, VARIANT *var) -{ - struct olevariantdata *pvar; - TypedData_Get_Struct(val, struct olevariantdata, &olevariant_datatype, pvar); - VariantCopy(var, &(pvar->var)); -} - -VALUE cWIN32OLE_VARIANT; - -void -Init_win32ole_variant(void) -{ -#undef rb_intern - cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject); - rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate); - rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2); - rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2); - rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0); - rb_define_method(cWIN32OLE_VARIANT, "value=", folevariant_set_value, 1); - rb_define_method(cWIN32OLE_VARIANT, "vartype", folevariant_vartype, 0); - rb_define_method(cWIN32OLE_VARIANT, "[]", folevariant_ary_aref, -1); - rb_define_method(cWIN32OLE_VARIANT, "[]=", folevariant_ary_aset, -1); - - /* - * represents VT_EMPTY OLE object. - */ - rb_define_const(cWIN32OLE_VARIANT, "Empty", - rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_EMPTY))); - - /* - * represents VT_NULL OLE object. - */ - rb_define_const(cWIN32OLE_VARIANT, "Null", - rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_NULL))); - - /* - * represents Nothing of VB.NET or VB. - */ - rb_define_const(cWIN32OLE_VARIANT, "Nothing", - rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_DISPATCH))); - - /* - * represents VT_ERROR variant with DISP_E_PARAMNOTFOUND. - * This constants is used for not specified parameter. - * - * fso = WIN32OLE.new("Scripting.FileSystemObject") - * fso.openTextFile(filename, WIN32OLE_VARIANT::NoParam, false) - */ - rb_define_const(cWIN32OLE_VARIANT, "NoParam", - rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, INT2NUM(DISP_E_PARAMNOTFOUND), RB_INT2FIX(VT_ERROR))); -} diff --git a/ext/win32ole/win32ole_variant.h b/ext/win32ole/win32ole_variant.h deleted file mode 100644 index 4bd3b0aeea..0000000000 --- a/ext/win32ole/win32ole_variant.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef WIN32OLE_VARIANT_H -#define WIN32OLE_VARIANT_H 1 - -extern VALUE cWIN32OLE_VARIANT; -void ole_variant2variant(VALUE val, VARIANT *var); -void Init_win32ole_variant(void); - -#endif - diff --git a/ext/win32ole/win32ole_variant_m.c b/ext/win32ole/win32ole_variant_m.c deleted file mode 100644 index c285a00177..0000000000 --- a/ext/win32ole/win32ole_variant_m.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "win32ole.h" - -VALUE mWIN32OLE_VARIANT; - -void Init_win32ole_variant_m(void) -{ - /* - * Document-module: WIN32OLE::VARIANT - * - * The WIN32OLE::VARIANT module includes constants of VARIANT type constants. - * The constants is used when creating WIN32OLE_VARIANT object. - * - * obj = WIN32OLE_VARIANT.new("2e3", WIN32OLE::VARIANT::VT_R4) - * obj.value # => 2000.0 - * - */ - mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT"); - - /* - * represents VT_EMPTY type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", RB_INT2FIX(VT_EMPTY)); - - /* - * represents VT_NULL type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", RB_INT2FIX(VT_NULL)); - - /* - * represents VT_I2 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_I2", RB_INT2FIX(VT_I2)); - - /* - * represents VT_I4 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_I4", RB_INT2FIX(VT_I4)); - - /* - * represents VT_R4 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_R4", RB_INT2FIX(VT_R4)); - - /* - * represents VT_R8 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_R8", RB_INT2FIX(VT_R8)); - - /* - * represents VT_CY type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_CY", RB_INT2FIX(VT_CY)); - - /* - * represents VT_DATE type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", RB_INT2FIX(VT_DATE)); - - /* - * represents VT_BSTR type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", RB_INT2FIX(VT_BSTR)); - - /* - * represents VT_USERDEFINED type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", RB_INT2FIX(VT_USERDEFINED)); - - /* - * represents VT_PTR type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", RB_INT2FIX(VT_PTR)); - - /* - * represents VT_DISPATCH type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", RB_INT2FIX(VT_DISPATCH)); - - /* - * represents VT_ERROR type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", RB_INT2FIX(VT_ERROR)); - - /* - * represents VT_BOOL type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", RB_INT2FIX(VT_BOOL)); - - /* - * represents VT_VARIANT type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", RB_INT2FIX(VT_VARIANT)); - - /* - * represents VT_UNKNOWN type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", RB_INT2FIX(VT_UNKNOWN)); - - /* - * represents VT_I1 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_I1", RB_INT2FIX(VT_I1)); - - /* - * represents VT_UI1 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", RB_INT2FIX(VT_UI1)); - - /* - * represents VT_UI2 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", RB_INT2FIX(VT_UI2)); - - /* - * represents VT_UI4 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", RB_INT2FIX(VT_UI4)); - -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__) - /* - * represents VT_I8 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_I8", RB_INT2FIX(VT_I8)); - - /* - * represents VT_UI8 type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", RB_INT2FIX(VT_UI8)); -#endif - - /* - * represents VT_INT type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_INT", RB_INT2FIX(VT_INT)); - - /* - * represents VT_UINT type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", RB_INT2FIX(VT_UINT)); - - /* - * represents VT_ARRAY type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", RB_INT2FIX(VT_ARRAY)); - - /* - * represents VT_BYREF type constant. - */ - rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", RB_INT2FIX(VT_BYREF)); - -} diff --git a/ext/win32ole/win32ole_variant_m.h b/ext/win32ole/win32ole_variant_m.h deleted file mode 100644 index 6272a6578f..0000000000 --- a/ext/win32ole/win32ole_variant_m.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef WIN32OLE_VARIANT_M_H -#define WIN32OLE_VARIANT_M_H 1 - -extern VALUE mWIN32OLE_VARIANT; -void Init_win32ole_variant_m(void); - -#endif diff --git a/ext/zlib/depend b/ext/zlib/depend index d63d388c9e..22e9ca867a 100644 --- a/ext/zlib/depend +++ b/ext/zlib/depend @@ -7,7 +7,6 @@ zlib.o: $(hdrdir)/ruby/backward.h zlib.o: $(hdrdir)/ruby/backward/2/assume.h zlib.o: $(hdrdir)/ruby/backward/2/attributes.h zlib.o: $(hdrdir)/ruby/backward/2/bool.h -zlib.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h zlib.o: $(hdrdir)/ruby/backward/2/inttypes.h zlib.o: $(hdrdir)/ruby/backward/2/limits.h zlib.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -16,6 +15,7 @@ zlib.o: $(hdrdir)/ruby/backward/2/stdarg.h zlib.o: $(hdrdir)/ruby/defines.h zlib.o: $(hdrdir)/ruby/encoding.h zlib.o: $(hdrdir)/ruby/intern.h +zlib.o: $(hdrdir)/ruby/internal/abi.h zlib.o: $(hdrdir)/ruby/internal/anyargs.h zlib.o: $(hdrdir)/ruby/internal/arithmetic.h zlib.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -53,6 +53,7 @@ zlib.o: $(hdrdir)/ruby/internal/attr/noexcept.h zlib.o: $(hdrdir)/ruby/internal/attr/noinline.h zlib.o: $(hdrdir)/ruby/internal/attr/nonnull.h zlib.o: $(hdrdir)/ruby/internal/attr/noreturn.h +zlib.o: $(hdrdir)/ruby/internal/attr/packed_struct.h zlib.o: $(hdrdir)/ruby/internal/attr/pure.h zlib.o: $(hdrdir)/ruby/internal/attr/restrict.h zlib.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ zlib.o: $(hdrdir)/ruby/internal/intern/enumerator.h zlib.o: $(hdrdir)/ruby/internal/intern/error.h zlib.o: $(hdrdir)/ruby/internal/intern/eval.h zlib.o: $(hdrdir)/ruby/internal/intern/file.h -zlib.o: $(hdrdir)/ruby/internal/intern/gc.h zlib.o: $(hdrdir)/ruby/internal/intern/hash.h zlib.o: $(hdrdir)/ruby/internal/intern/io.h zlib.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ zlib.o: $(hdrdir)/ruby/internal/intern/re.h zlib.o: $(hdrdir)/ruby/internal/intern/ruby.h zlib.o: $(hdrdir)/ruby/internal/intern/select.h zlib.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +zlib.o: $(hdrdir)/ruby/internal/intern/set.h zlib.o: $(hdrdir)/ruby/internal/intern/signal.h zlib.o: $(hdrdir)/ruby/internal/intern/sprintf.h zlib.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ zlib.o: $(hdrdir)/ruby/internal/memory.h zlib.o: $(hdrdir)/ruby/internal/method.h zlib.o: $(hdrdir)/ruby/internal/module.h zlib.o: $(hdrdir)/ruby/internal/newobj.h -zlib.o: $(hdrdir)/ruby/internal/rgengc.h zlib.o: $(hdrdir)/ruby/internal/scan_args.h zlib.o: $(hdrdir)/ruby/internal/special_consts.h zlib.o: $(hdrdir)/ruby/internal/static_assert.h zlib.o: $(hdrdir)/ruby/internal/stdalign.h zlib.o: $(hdrdir)/ruby/internal/stdbool.h +zlib.o: $(hdrdir)/ruby/internal/stdckdint.h zlib.o: $(hdrdir)/ruby/internal/symbol.h zlib.o: $(hdrdir)/ruby/internal/value.h zlib.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb index d674544f22..2b2dbb1a5b 100644 --- a/ext/zlib/extconf.rb +++ b/ext/zlib/extconf.rb @@ -11,10 +11,9 @@ require 'rbconfig' dir_config 'zlib' libs = $libs -if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and - have_header('zlib.h') then - have_zlib = true -else +have_zlib = %w'z libz zlib1 zlib zdll zlibwapi'.any? {|z| have_library(z, 'deflateReset(NULL)', 'zlib.h')} + +unless have_zlib $libs = libs unless File.directory?(zsrc = "#{$srcdir}/zlib") dirs = Dir.open($srcdir) {|z| z.grep(/\Azlib-\d+[.\d]*\z/) {|x|"#{$srcdir}/#{x}"}} @@ -121,10 +120,18 @@ if have_zlib $defs << "-DHAVE_CRC32_COMBINE" $defs << "-DHAVE_ADLER32_COMBINE" $defs << "-DHAVE_TYPE_Z_CRC_T" + $defs << "-DHAVE_CRC32_Z" + $defs << "-DHAVE_ADLER32_Z" + $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS" else have_func('crc32_combine', 'zlib.h') have_func('adler32_combine', 'zlib.h') have_type('z_crc_t', 'zlib.h') + if (have_type('z_size_t', 'zlib.h') && + have_func('crc32_z', 'zlib.h') && + have_func('adler32_z', 'zlib.h')) + $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS" + end end create_makefile('zlib') {|conf| diff --git a/ext/zlib/extlibs b/ext/zlib/extlibs deleted file mode 100644 index a64b37ba5f..0000000000 --- a/ext/zlib/extlibs +++ /dev/null @@ -1,8 +0,0 @@ -ver = 1.2.11 -pkg = zlib-$(ver) - -https://zlib.net/$(pkg).tar.gz \ - md5:1c9f62f0778697a09d36121ead88e08e \ - sha512:73fd3fff4adeccd4894084c15ddac89890cd10ef105dd5e1835e1e9bbb6a49ff229713bd197d203edfa17c2727700fce65a2a235f07568212d820dca88b528ae \ - # - win32/$(pkg)-mswin.patch -p0 diff --git a/ext/zlib/win32/zlib-1.2.11-mswin.patch b/ext/zlib/win32/zlib-1.2.11-mswin.patch deleted file mode 100644 index 8810b4403c..0000000000 --- a/ext/zlib/win32/zlib-1.2.11-mswin.patch +++ /dev/null @@ -1,95 +0,0 @@ -diff -ru zlib-1.2.11/gzread.c zlib-1.2.11/gzread.c ---- zlib-1.2.11/gzread.c 2016-12-31 23:37:10.000000000 +0900 -+++ zlib-1.2.11/gzread.c 2020-11-23 19:35:00.550987184 +0900 -@@ -316,7 +316,7 @@ - /* set n to the maximum amount of len that fits in an unsigned int */ - n = -1; - if (n > len) -- n = len; -+ n = (unsigned)len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { -@@ -397,7 +397,7 @@ - } - - /* read len or fewer bytes to buf */ -- len = gz_read(state, buf, len); -+ len = (unsigned)gz_read(state, buf, len); - - /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) -@@ -469,7 +469,7 @@ - } - - /* nothing there -- try gz_read() */ -- ret = gz_read(state, buf, 1); -+ ret = (int)gz_read(state, buf, 1); - return ret < 1 ? -1 : buf[0]; - } - -diff -ru zlib-1.2.11/gzwrite.c zlib-1.2.11/gzwrite.c ---- zlib-1.2.11/gzwrite.c 2017-01-15 09:29:40.000000000 +0900 -+++ zlib-1.2.11/gzwrite.c 2020-11-23 19:35:41.530494030 +0900 -@@ -209,7 +209,7 @@ - state->in); - copy = state->size - have; - if (copy > len) -- copy = len; -+ copy = (unsigned)len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; -@@ -229,7 +229,7 @@ - do { - unsigned n = (unsigned)-1; - if (n > len) -- n = len; -+ n = (unsigned)len; - state->strm.avail_in = n; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) -@@ -368,7 +368,7 @@ - - /* write string */ - len = strlen(str); -- ret = gz_write(state, str, len); -+ ret = (int)gz_write(state, str, len); - return ret == 0 && len != 0 ? -1 : ret; - } - -diff -ru zlib-1.2.11/win32/Makefile.msc zlib-1.2.11/win32/Makefile.msc ---- zlib-1.2.11/win32/Makefile.msc 2017-01-15 09:07:08.000000000 +0900 -+++ zlib-1.2.11/win32/Makefile.msc 2020-11-23 22:37:19.746500208 +0900 -@@ -37,6 +37,22 @@ - gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj - OBJA = - -+!ifdef USE_ASM -+LOC = -DASMV -DASMINF -+!if "$(ARCH)" == "i386" -+OBJA = inffas32.obj match686.obj -+!else if "$(ARCH)" == "x64" -+AS = ml64 -+LOC = $(LOC) -I. -+OBJA = inffasx64.obj gvmat64.obj inffas8664.obj -+!endif -+!endif -+ -+!if "$(ARCH)" == "x64" -+ZBASE = 0x5A4C000000 -+!else -+ZBASE = 0x5A4C0000 -+!endif - - # targets - all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ -@@ -49,7 +65,7 @@ - - $(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res - $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \ -- -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res -+ -out:$@ -base:$(ZBASE) $(OBJS) $(OBJA) zlib1.res - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;2 - diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 9937f82740..7e319cae0d 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -25,7 +25,7 @@ # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0 #endif -#define RUBY_ZLIB_VERSION "2.1.1" +#define RUBY_ZLIB_VERSION "3.2.2" #ifndef RB_PASS_CALLED_KEYWORDS # define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass) @@ -44,6 +44,14 @@ #endif #endif +#if defined(HAVE_ZLIB_SIZE_T_FUNCS) +typedef uLong (*checksum_func)(uLong, const Bytef*, z_size_t); +# define crc32 crc32_z +# define adler32 adler32_z +#else +typedef uLong (*checksum_func)(uLong, const Bytef*, uInt); +#endif + #if SIZEOF_LONG > SIZEOF_INT static inline uInt max_uint(long n) @@ -65,7 +73,7 @@ static ID id_dictionaries, id_read, id_buffer; static NORETURN(void raise_zlib_error(int, const char*)); static VALUE rb_zlib_version(VALUE); -static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt)); +static VALUE do_checksum(int, VALUE*, checksum_func); static VALUE rb_zlib_adler32(int, VALUE*, VALUE); static VALUE rb_zlib_crc32(int, VALUE*, VALUE); static VALUE rb_zlib_crc_table(VALUE); @@ -82,7 +90,7 @@ static void zstream_expand_buffer_into(struct zstream*, unsigned long); static int zstream_expand_buffer_non_stream(struct zstream *z); static void zstream_append_buffer(struct zstream*, const Bytef*, long); static VALUE zstream_detach_buffer(struct zstream*); -static VALUE zstream_shift_buffer(struct zstream*, long); +static VALUE zstream_shift_buffer(struct zstream*, long, VALUE); static void zstream_buffer_ungets(struct zstream*, const Bytef*, unsigned long); static void zstream_buffer_ungetbyte(struct zstream*, int); static void zstream_append_input(struct zstream*, const Bytef*, long); @@ -162,8 +170,8 @@ static void gzfile_check_footer(struct gzfile*, VALUE outbuf); static void gzfile_write(struct gzfile*, Bytef*, long); static long gzfile_read_more(struct gzfile*, VALUE outbuf); static void gzfile_calc_crc(struct gzfile*, VALUE); -static VALUE gzfile_read(struct gzfile*, long); -static VALUE gzfile_read_all(struct gzfile*); +static VALUE gzfile_read(struct gzfile*, long, VALUE); +static VALUE gzfile_read_all(struct gzfile*, VALUE); static void gzfile_ungets(struct gzfile*, const Bytef*, long); static void gzfile_ungetbyte(struct gzfile*, int); static VALUE gzfile_writer_end_run(VALUE); @@ -288,6 +296,7 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE); * - Zlib::MemError * - Zlib::BufError * - Zlib::VersionError + * - Zlib::InProgressError * * (if you have GZIP_SUPPORT) * - Zlib::GzipReader @@ -304,7 +313,7 @@ void Init_zlib(void); /*--------- Exceptions --------*/ static VALUE cZError, cStreamEnd, cNeedDict; -static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError; +static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError, cInProgressError; static void raise_zlib_error(int err, const char *msg) @@ -373,26 +382,32 @@ rb_zlib_version(VALUE klass) return rb_str_new2(zlibVersion()); } -#if SIZEOF_LONG > SIZEOF_INT +#if SIZEOF_LONG * CHAR_BIT > 32 +# define mask32(x) ((x) & 0xffffffff) +#else +# define mask32(x) (x) +#endif + +#if SIZEOF_LONG > SIZEOF_INT && !defined(HAVE_ZLIB_SIZE_T_FUNCS) static uLong checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len) { if (len > UINT_MAX) { do { - sum = func(sum, ptr, UINT_MAX); + sum = func(mask32(sum), ptr, UINT_MAX); ptr += UINT_MAX; len -= UINT_MAX; } while (len >= UINT_MAX); } - if (len > 0) sum = func(sum, ptr, (uInt)len); + if (len > 0) sum = func(mask32(sum), ptr, (uInt)len); return sum; } #else -#define checksum_long(func, sum, ptr, len) (func)((sum), (ptr), (len)) +#define checksum_long(func, sum, ptr, len) (func)(mask32(sum), (ptr), (len)) #endif static VALUE -do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt)) +do_checksum(int argc, VALUE *argv, checksum_func func) { VALUE str, vsum; unsigned long sum; @@ -410,7 +425,7 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt)) } if (NIL_P(str)) { - sum = func(sum, Z_NULL, 0); + sum = func(mask32(sum), Z_NULL, 0); } else if (rb_obj_is_kind_of(str, rb_cIO)) { VALUE buf; @@ -460,7 +475,7 @@ rb_zlib_adler32(int argc, VALUE *argv, VALUE klass) * * call-seq: Zlib.adler32_combine(adler1, adler2, len2) * - * Combine two Adler-32 check values in to one. +alder1+ is the first Adler-32 + * Combine two Adler-32 check values in to one. +adler1+ is the first Adler-32 * value, +adler2+ is the second Adler-32 value. +len2+ is the length of the * string used to generate +adler2+. * @@ -557,14 +572,15 @@ struct zstream { } *func; }; -#define ZSTREAM_FLAG_READY 0x1 -#define ZSTREAM_FLAG_IN_STREAM 0x2 -#define ZSTREAM_FLAG_FINISHED 0x4 -#define ZSTREAM_FLAG_CLOSING 0x8 -#define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for +#define ZSTREAM_FLAG_READY (1 << 0) +#define ZSTREAM_FLAG_IN_STREAM (1 << 1) +#define ZSTREAM_FLAG_FINISHED (1 << 2) +#define ZSTREAM_FLAG_CLOSING (1 << 3) +#define ZSTREAM_FLAG_GZFILE (1 << 4) /* disallows yield from expand_buffer for gzip*/ -#define ZSTREAM_REUSE_BUFFER 0x20 -#define ZSTREAM_FLAG_UNUSED 0x40 +#define ZSTREAM_REUSE_BUFFER (1 << 5) +#define ZSTREAM_IN_PROGRESS (1 << 6) +#define ZSTREAM_FLAG_UNUSED (1 << 7) #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY) #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY) @@ -593,7 +609,9 @@ static const struct zstream_funcs inflate_funcs = { }; struct zstream_run_args { - struct zstream * z; + struct zstream *const z; + Bytef *src; + long len; int flush; /* stream flush value for inflate() or deflate() */ int interrupt; /* stop processing the stream and return to ruby */ int jump_state; /* for buffer expansion block break or exception */ @@ -656,9 +674,7 @@ zstream_expand_buffer(struct zstream *z) rb_obj_reveal(z->buf, rb_cString); } - rb_mutex_unlock(z->mutex); - rb_protect(rb_yield, z->buf, &state); - rb_mutex_lock(z->mutex); + rb_protect(rb_yield, z->buf, &state); if (ZSTREAM_REUSE_BUFFER_P(z)) { rb_str_modify(z->buf); @@ -702,15 +718,14 @@ zstream_expand_buffer_into(struct zstream *z, unsigned long size) } } -static void * -zstream_expand_buffer_protect(void *ptr) +static int +zstream_expand_buffer_protect(struct zstream *z) { - struct zstream *z = (struct zstream *)ptr; int state = 0; rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state); - return (void *)(VALUE)state; + return state; } static int @@ -802,19 +817,31 @@ zstream_detach_buffer(struct zstream *z) } static VALUE -zstream_shift_buffer(struct zstream *z, long len) +zstream_shift_buffer(struct zstream *z, long len, VALUE dst) { - VALUE dst; char *bufptr; long buflen = ZSTREAM_BUF_FILLED(z); if (buflen <= len) { - return zstream_detach_buffer(z); + if (NIL_P(dst) || (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) && + rb_block_given_p())) { + return zstream_detach_buffer(z); + } else { + bufptr = RSTRING_PTR(z->buf); + rb_str_resize(dst, buflen); + memcpy(RSTRING_PTR(dst), bufptr, buflen); + } + buflen = 0; + } else { + bufptr = RSTRING_PTR(z->buf); + if (NIL_P(dst)) { + dst = rb_str_new(bufptr, len); + } else { + rb_str_resize(dst, len); + memcpy(RSTRING_PTR(dst), bufptr, len); + } + buflen -= len; } - - bufptr = RSTRING_PTR(z->buf); - dst = rb_str_new(bufptr, len); - buflen -= len; memmove(bufptr, bufptr + len, buflen); rb_str_set_len(z->buf, buflen); z->stream.next_out = (Bytef*)RSTRING_END(z->buf); @@ -894,7 +921,6 @@ zstream_discard_input(struct zstream *z, long len) } rb_str_resize(z->input, newlen); if (newlen == 0) { - rb_gc_force_recycle(z->input); z->input = Qnil; } else { @@ -906,7 +932,7 @@ zstream_discard_input(struct zstream *z, long len) z->input = Qnil; } else { - z->input = rb_str_substr(z->input, len, + z->input = rb_str_subseq(z->input, len, RSTRING_LEN(z->input) - len); } } @@ -994,57 +1020,14 @@ zstream_ensure_end(VALUE v) } static void * -zstream_run_func(void *ptr) +zstream_run_once(void *_arguments) { - struct zstream_run_args *args = (struct zstream_run_args *)ptr; - int err, state, flush = args->flush; - struct zstream *z = args->z; - uInt n; - - err = Z_OK; - while (!args->interrupt) { - n = z->stream.avail_out; - err = z->func->run(&z->stream, flush); - rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out)); - - if (err == Z_STREAM_END) { - z->flags &= ~ZSTREAM_FLAG_IN_STREAM; - z->flags |= ZSTREAM_FLAG_FINISHED; - break; - } - - if (err != Z_OK && err != Z_BUF_ERROR) - break; - - if (z->stream.avail_out > 0) { - z->flags |= ZSTREAM_FLAG_IN_STREAM; - break; - } - - if (z->stream.avail_in == 0 && z->func == &inflate_funcs) { - /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */ - /* but deflate() could be called with avail_in == 0 (there's hidden buffer - in zstream->state) */ - z->flags |= ZSTREAM_FLAG_IN_STREAM; - break; - } + struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments; + struct zstream *z = arguments->z; - if (args->stream_output) { - state = (int)(VALUE)rb_thread_call_with_gvl(zstream_expand_buffer_protect, - (void *)z); - } - else { - state = zstream_expand_buffer_non_stream(z); - } + uintptr_t error = z->func->run(&z->stream, arguments->flush); - if (state) { - err = Z_OK; /* buffer expanded but stream processing was stopped */ - args->jump_state = state; - break; - } - } - - return (void *)(VALUE)err; + return (void*)error; } /* @@ -1059,18 +1042,108 @@ zstream_unblock_func(void *ptr) args->interrupt = 1; } -static void -zstream_run0(struct zstream *z, Bytef *src, long len, int flush) +#ifndef RB_NOGVL_OFFLOAD_SAFE +// Default to no-op if it's not defined: +#define RB_NOGVL_OFFLOAD_SAFE 0 +#endif + +static VALUE +zstream_run_once_begin(VALUE _arguments) { - struct zstream_run_args args; + struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments; + struct zstream *z = arguments->z; + + rb_str_locktmp(z->buf); + +#ifndef RB_NOGVL_UBF_ASYNC_SAFE + return (VALUE)rb_thread_call_without_gvl(zstream_run_once, (void *)arguments, zstream_unblock_func, (void *)arguments); +#else + return (VALUE)rb_nogvl(zstream_run_once, (void *)arguments, zstream_unblock_func, (void *)arguments, RB_NOGVL_UBF_ASYNC_SAFE | RB_NOGVL_OFFLOAD_SAFE); +#endif +} + +static VALUE +zstream_run_once_ensure(VALUE _arguments) +{ + struct zstream_run_args *arguments = (struct zstream_run_args *)_arguments; + struct zstream *z = arguments->z; + + rb_str_unlocktmp(z->buf); + + return Qnil; +} + +static int +zstream_run_func(struct zstream_run_args *args) +{ + struct zstream *z = args->z; + int state; + uInt n; + + int err = Z_OK; + while (!args->interrupt) { + n = z->stream.avail_out; + + err = (int)(VALUE)rb_ensure(zstream_run_once_begin, (VALUE)args, zstream_run_once_ensure, (VALUE)args); + + rb_str_set_len(z->buf, ZSTREAM_BUF_FILLED(z) + (n - z->stream.avail_out)); + + if (err == Z_STREAM_END) { + z->flags &= ~ZSTREAM_FLAG_IN_STREAM; + z->flags |= ZSTREAM_FLAG_FINISHED; + break; + } + + if (err != Z_OK && err != Z_BUF_ERROR) + break; + + if (z->stream.avail_out > 0) { + z->flags |= ZSTREAM_FLAG_IN_STREAM; + break; + } + + if (z->stream.avail_in == 0 && z->func == &inflate_funcs) { + /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */ + /* but deflate() could be called with avail_in == 0 (there's hidden buffer + in zstream->state) */ + z->flags |= ZSTREAM_FLAG_IN_STREAM; + break; + } + + if (args->stream_output) { + state = zstream_expand_buffer_protect(z); + } + else { + state = zstream_expand_buffer_non_stream(z); + } + + if (state) { + err = Z_OK; /* buffer expanded but stream processing was stopped */ + args->jump_state = state; + break; + } + } + + return err; +} + +static VALUE +zstream_run_try(VALUE value_arg) +{ + struct zstream_run_args *args = (struct zstream_run_args *)value_arg; + struct zstream *z = args->z; + Bytef *src = args->src; + long len = args->len; + int flush = args->flush; + int err; VALUE old_input = Qnil; - args.z = z; - args.flush = flush; - args.interrupt = 0; - args.jump_state = 0; - args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p(); + /* Cannot start zstream while it is in progress. */ + if (z->flags & ZSTREAM_IN_PROGRESS) { + rb_raise(cInProgressError, "zlib stream is in progress"); + } + z->flags |= ZSTREAM_IN_PROGRESS; if (NIL_P(z->input) && len == 0) { z->stream.next_in = (Bytef*)""; @@ -1092,18 +1165,11 @@ zstream_run0(struct zstream *z, Bytef *src, long len, int flush) } loop: -#ifndef RB_NOGVL_UBF_ASYNC_SAFE - err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args, - zstream_unblock_func, (void *)&args); -#else - err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)&args, - zstream_unblock_func, (void *)&args, - RB_NOGVL_UBF_ASYNC_SAFE); -#endif + err = zstream_run_func(args); /* retry if no exception is thrown */ - if (err == Z_OK && args.interrupt) { - args.interrupt = 0; + if (err == Z_OK && args->interrupt) { + args->interrupt = 0; goto loop; } @@ -1137,37 +1203,39 @@ loop: } if (!NIL_P(old_input)) { rb_str_resize(old_input, 0); - rb_gc_force_recycle(old_input); } - if (args.jump_state) - rb_jump_tag(args.jump_state); + return Qnil; } -struct zstream_run_synchronized_args { - struct zstream *z; - Bytef *src; - long len; - int flush; -}; - static VALUE -zstream_run_synchronized(VALUE value_arg) +zstream_run_ensure(VALUE value_arg) { - struct zstream_run_synchronized_args *run_args = (struct zstream_run_synchronized_args *)value_arg; - zstream_run0(run_args->z, run_args->src, run_args->len, run_args->flush); + struct zstream_run_args *args = (struct zstream_run_args *)value_arg; + struct zstream *z = args->z; + + /* Remove ZSTREAM_IN_PROGRESS flag to signal that this zstream is not in use. */ + z->flags &= ~ZSTREAM_IN_PROGRESS; + return Qnil; } static void zstream_run(struct zstream *z, Bytef *src, long len, int flush) { - struct zstream_run_synchronized_args run_args; - run_args.z = z; - run_args.src = src; - run_args.len = len; - run_args.flush = flush; - rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&run_args); + struct zstream_run_args args = { + .z = z, + .src = src, + .len = len, + .flush = flush, + .interrupt = 0, + .jump_state = 0, + .stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p(), + }; + + rb_ensure(zstream_run_try, (VALUE)&args, zstream_run_ensure, (VALUE)&args); + if (args.jump_state) + rb_jump_tag(args.jump_state); } static VALUE @@ -1388,6 +1456,7 @@ rb_zstream_finish(VALUE obj) * call-seq: * flush_next_in -> input * + * Flushes input buffer and returns all data in that buffer. */ static VALUE rb_zstream_flush_next_in(VALUE obj) @@ -1476,7 +1545,7 @@ rb_zstream_total_out(VALUE obj) } /* - * Guesses the type of the data which have been inputed into the stream. The + * Guesses the type of the data which have been inputted into the stream. The * returned value is either <tt>BINARY</tt>, <tt>ASCII</tt>, or * <tt>UNKNOWN</tt>. */ @@ -1733,6 +1802,22 @@ do_deflate(struct zstream *z, VALUE src, int flush) } } +struct rb_zlib_deflate_arguments { + struct zstream *z; + VALUE src; + int flush; +}; + +static VALUE +rb_deflate_deflate_body(VALUE args) +{ + struct rb_zlib_deflate_arguments *arguments = (struct rb_zlib_deflate_arguments *)args; + + do_deflate(arguments->z, arguments->src, arguments->flush); + + return zstream_detach_buffer(arguments->z); +} + /* * Document-method: Zlib::Deflate#deflate * @@ -1764,11 +1849,10 @@ rb_deflate_deflate(int argc, VALUE *argv, VALUE obj) { struct zstream *z = get_zstream(obj); VALUE src, flush; - rb_scan_args(argc, argv, "11", &src, &flush); - do_deflate(z, src, ARG_FLUSH(flush)); + struct rb_zlib_deflate_arguments arguments = {z, src, ARG_FLUSH(flush)}; - return zstream_detach_buffer(z); + return rb_mutex_synchronize(z->mutex, rb_deflate_deflate_body, (VALUE)&arguments); } /* @@ -2064,56 +2148,19 @@ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary) return obj; } -/* - * Document-method: Zlib::Inflate#inflate - * - * call-seq: - * inflate(deflate_string, buffer: nil) -> String - * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil - * - * Inputs +deflate_string+ into the inflate stream and returns the output from - * the stream. Calling this method, both the input and the output buffer of - * the stream are flushed. If string is +nil+, this method finishes the - * stream, just like Zlib::ZStream#finish. - * - * If a block is given consecutive inflated chunks from the +deflate_string+ - * are yielded to the block and +nil+ is returned. - * - * If a :buffer keyword argument is given and not nil: - * - * * The :buffer keyword should be a String, and will used as the output buffer. - * Using this option can reuse the memory required during inflation. - * * When not passing a block, the return value will be the same object as the - * :buffer keyword argument. - * * When passing a block, the yielded chunks will be the same value as the - * :buffer keyword argument. - * - * Raises a Zlib::NeedDict exception if a preset dictionary is needed to - * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then - * call this method again with an empty string to flush the stream: - * - * inflater = Zlib::Inflate.new - * - * begin - * out = inflater.inflate compressed - * rescue Zlib::NeedDict - * # ensure the dictionary matches the stream's required dictionary - * raise unless inflater.adler == Zlib.adler32(dictionary) - * - * inflater.set_dictionary dictionary - * inflater.inflate '' - * end - * - * # ... - * - * inflater.close - * - * See also Zlib::Inflate.new - */ +struct rb_zlib_inflate_arguments { + struct zstream *z; + int argc; + VALUE *argv; +}; + static VALUE -rb_inflate_inflate(int argc, VALUE* argv, VALUE obj) +rb_inflate_inflate_body(VALUE _arguments) { - struct zstream *z = get_zstream(obj); + struct rb_zlib_inflate_arguments *arguments = (struct rb_zlib_inflate_arguments*)_arguments; + struct zstream *z = arguments->z; + int argc = arguments->argc; + VALUE *argv = arguments->argv; VALUE dst, src, opts, buffer = Qnil; if (OPTHASH_GIVEN_P(opts)) { @@ -2169,6 +2216,60 @@ rb_inflate_inflate(int argc, VALUE* argv, VALUE obj) } /* + * Document-method: Zlib::Inflate#inflate + * + * call-seq: + * inflate(deflate_string, buffer: nil) -> String + * inflate(deflate_string, buffer: nil) { |chunk| ... } -> nil + * + * Inputs +deflate_string+ into the inflate stream and returns the output from + * the stream. Calling this method, both the input and the output buffer of + * the stream are flushed. If string is +nil+, this method finishes the + * stream, just like Zlib::ZStream#finish. + * + * If a block is given consecutive inflated chunks from the +deflate_string+ + * are yielded to the block and +nil+ is returned. + * + * If a :buffer keyword argument is given and not nil: + * + * * The :buffer keyword should be a String, and will used as the output buffer. + * Using this option can reuse the memory required during inflation. + * * When not passing a block, the return value will be the same object as the + * :buffer keyword argument. + * * When passing a block, the yielded chunks will be the same value as the + * :buffer keyword argument. + * + * Raises a Zlib::NeedDict exception if a preset dictionary is needed to + * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then + * call this method again with an empty string to flush the stream: + * + * inflater = Zlib::Inflate.new + * + * begin + * out = inflater.inflate compressed + * rescue Zlib::NeedDict + * # ensure the dictionary matches the stream's required dictionary + * raise unless inflater.adler == Zlib.adler32(dictionary) + * + * inflater.set_dictionary dictionary + * inflater.inflate '' + * end + * + * # ... + * + * inflater.close + * + * See also Zlib::Inflate.new + */ +static VALUE +rb_inflate_inflate(int argc, VALUE* argv, VALUE obj) +{ + struct zstream *z = get_zstream(obj); + struct rb_zlib_inflate_arguments arguments = {z, argc, argv}; + return rb_mutex_synchronize(z->mutex, rb_inflate_inflate_body, (VALUE)&arguments); +} + +/* * call-seq: << string * * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but @@ -2344,17 +2445,16 @@ struct gzfile { #define GZFILE_READ_SIZE 2048 +enum { read_raw_arg_len, read_raw_arg_buf, read_raw_arg__count}; struct read_raw_arg { VALUE io; - union { - const VALUE argv[2]; /* for rb_funcallv */ - struct { - VALUE len; - VALUE buf; - } in; - } as; + const VALUE argv[read_raw_arg__count]; /* for rb_funcallv */ }; +#define read_raw_arg_argc(ra) \ + ((int)read_raw_arg__count - NIL_P((ra)->argv[read_raw_arg__count - 1])) +#define read_raw_arg_init(io, len, buf) { io, { len, buf } } + static void gzfile_mark(void *p) { @@ -2480,9 +2580,9 @@ gzfile_read_raw_partial(VALUE arg) { struct read_raw_arg *ra = (struct read_raw_arg *)arg; VALUE str; - int argc = NIL_P(ra->as.argv[1]) ? 1 : 2; + int argc = read_raw_arg_argc(ra); - str = rb_funcallv(ra->io, id_readpartial, argc, ra->as.argv); + str = rb_funcallv(ra->io, id_readpartial, argc, ra->argv); Check_Type(str, T_STRING); return str; } @@ -2493,8 +2593,8 @@ gzfile_read_raw_rescue(VALUE arg, VALUE _) struct read_raw_arg *ra = (struct read_raw_arg *)arg; VALUE str = Qnil; if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) { - int argc = NIL_P(ra->as.argv[1]) ? 1 : 2; - str = rb_funcallv(ra->io, id_read, argc, ra->as.argv); + int argc = read_raw_arg_argc(ra); + str = rb_funcallv(ra->io, id_read, argc, ra->argv); if (!NIL_P(str)) { Check_Type(str, T_STRING); } @@ -2505,11 +2605,8 @@ gzfile_read_raw_rescue(VALUE arg, VALUE _) static VALUE gzfile_read_raw(struct gzfile *gz, VALUE outbuf) { - struct read_raw_arg ra; - - ra.io = gz->io; - ra.as.in.len = INT2FIX(GZFILE_READ_SIZE); - ra.as.in.buf = outbuf; + struct read_raw_arg ra = + read_raw_arg_init(gz->io, INT2FIX(GZFILE_READ_SIZE), outbuf); return rb_rescue2(gzfile_read_raw_partial, (VALUE)&ra, gzfile_read_raw_rescue, (VALUE)&ra, @@ -2841,18 +2938,18 @@ gzfile_newstr(struct gzfile *gz, VALUE str) } static long -gzfile_fill(struct gzfile *gz, long len) +gzfile_fill(struct gzfile *gz, long len, VALUE outbuf) { if (len < 0) rb_raise(rb_eArgError, "negative length %ld given", len); if (len == 0) return 0; while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) < len) { - gzfile_read_more(gz, Qnil); + gzfile_read_more(gz, outbuf); } if (GZFILE_IS_FINISHED(gz)) { if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) { - gzfile_check_footer(gz, Qnil); + gzfile_check_footer(gz, outbuf); } return -1; } @@ -2860,14 +2957,27 @@ gzfile_fill(struct gzfile *gz, long len) } static VALUE -gzfile_read(struct gzfile *gz, long len) +gzfile_read(struct gzfile *gz, long len, VALUE outbuf) { VALUE dst; - len = gzfile_fill(gz, len); - if (len == 0) return rb_str_new(0, 0); - if (len < 0) return Qnil; - dst = zstream_shift_buffer(&gz->z, len); + len = gzfile_fill(gz, len, outbuf); + + if (len < 0) { + if (!NIL_P(outbuf)) + rb_str_resize(outbuf, 0); + return Qnil; + } + if (len == 0) { + if (NIL_P(outbuf)) + return rb_str_new(0, 0); + else { + rb_str_resize(outbuf, 0); + return outbuf; + } + } + + dst = zstream_shift_buffer(&gz->z, len, outbuf); if (!NIL_P(dst)) gzfile_calc_crc(gz, dst); return dst; } @@ -2900,31 +3010,26 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf) rb_raise(rb_eEOFError, "end of file reached"); } - dst = zstream_shift_buffer(&gz->z, len); + dst = zstream_shift_buffer(&gz->z, len, outbuf); gzfile_calc_crc(gz, dst); - if (!NIL_P(outbuf)) { - rb_str_resize(outbuf, RSTRING_LEN(dst)); - memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst)); - rb_str_resize(dst, 0); - rb_gc_force_recycle(dst); - dst = outbuf; - } return dst; } static VALUE -gzfile_read_all(struct gzfile *gz) +gzfile_read_all(struct gzfile *gz, VALUE dst) { - VALUE dst; - while (!ZSTREAM_IS_FINISHED(&gz->z)) { - gzfile_read_more(gz, Qnil); + gzfile_read_more(gz, dst); } if (GZFILE_IS_FINISHED(gz)) { if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) { - gzfile_check_footer(gz, Qnil); + gzfile_check_footer(gz, dst); } + if (!NIL_P(dst)) { + rb_str_resize(dst, 0); + return dst; + } return rb_str_new(0, 0); } @@ -2962,7 +3067,7 @@ gzfile_getc(struct gzfile *gz) de = (unsigned char *)ds + GZFILE_CBUF_CAPA; (void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT); rb_econv_check_error(gz->ec); - dst = zstream_shift_buffer(&gz->z, sp - ss); + dst = zstream_shift_buffer(&gz->z, sp - ss, Qnil); gzfile_calc_crc(gz, dst); rb_str_resize(cbuf, dp - ds); return cbuf; @@ -2970,7 +3075,7 @@ gzfile_getc(struct gzfile *gz) else { buf = gz->z.buf; len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc); - dst = gzfile_read(gz, len); + dst = gzfile_read(gz, len, Qnil); if (NIL_P(dst)) return dst; return gzfile_newstr(gz, dst); } @@ -3469,6 +3574,9 @@ static VALUE rb_gzfile_eof_p(VALUE obj) { struct gzfile *gz = get_gzfile(obj); + while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) { + gzfile_read_more(gz, Qnil); + } return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse; } @@ -3875,7 +3983,7 @@ rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass) if (!buf) { buf = rb_str_new(0, 0); } - tmpbuf = gzfile_read_all(get_gzfile(obj)); + tmpbuf = gzfile_read_all(get_gzfile(obj), Qnil); rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf)); } @@ -3977,19 +4085,19 @@ static VALUE rb_gzreader_read(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); - VALUE vlen; + VALUE vlen, outbuf; long len; - rb_scan_args(argc, argv, "01", &vlen); + rb_scan_args(argc, argv, "02", &vlen, &outbuf); if (NIL_P(vlen)) { - return gzfile_read_all(gz); + return gzfile_read_all(gz, outbuf); } len = NUM2INT(vlen); if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } - return gzfile_read(gz, len); + return gzfile_read(gz, len, outbuf); } /* @@ -3998,7 +4106,7 @@ rb_gzreader_read(int argc, VALUE *argv, VALUE obj) * call-seq: * gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf * - * Reads at most <i>maxlen</i> bytes from the gziped stream but + * Reads at most <i>maxlen</i> bytes from the gzipped stream but * it blocks only if <em>gzipreader</em> has no data immediately available. * If the optional <i>outbuf</i> argument is present, * it must reference a String, which will receive the data. @@ -4062,7 +4170,7 @@ rb_gzreader_getbyte(VALUE obj) struct gzfile *gz = get_gzfile(obj); VALUE dst; - dst = gzfile_read(gz, 1); + dst = gzfile_read(gz, 1, Qnil); if (!NIL_P(dst)) { dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff); } @@ -4173,6 +4281,7 @@ gzreader_skip_linebreaks(struct gzfile *gz) while (n++, *(p++) == '\n') { if (n >= ZSTREAM_BUF_FILLED(&gz->z)) { str = zstream_detach_buffer(&gz->z); + ASSUME(!NIL_P(str)); gzfile_calc_crc(gz, str); while (ZSTREAM_BUF_FILLED(&gz->z) == 0) { if (GZFILE_IS_FINISHED(gz)) return; @@ -4183,7 +4292,7 @@ gzreader_skip_linebreaks(struct gzfile *gz) } } - str = zstream_shift_buffer(&gz->z, n - 1); + str = zstream_shift_buffer(&gz->z, n - 1, Qnil); gzfile_calc_crc(gz, str); } @@ -4204,7 +4313,7 @@ gzreader_charboundary(struct gzfile *gz, long n) if (l < n) { int n_bytes = rb_enc_precise_mbclen(p, e, gz->enc); if (MBCLEN_NEEDMORE_P(n_bytes)) { - if ((l = gzfile_fill(gz, n + MBCLEN_NEEDMORE_LEN(n_bytes))) > 0) { + if ((l = gzfile_fill(gz, n + MBCLEN_NEEDMORE_LEN(n_bytes), Qnil)) > 0) { return l; } } @@ -4256,10 +4365,10 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj) if (NIL_P(rs)) { if (limit < 0) { - dst = gzfile_read_all(gz); + dst = gzfile_read_all(gz, Qnil); if (RSTRING_LEN(dst) == 0) return Qnil; } - else if ((n = gzfile_fill(gz, limit)) <= 0) { + else if ((n = gzfile_fill(gz, limit, Qnil)) <= 0) { return Qnil; } else { @@ -4269,7 +4378,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj) else { n = limit; } - dst = zstream_shift_buffer(&gz->z, n); + dst = zstream_shift_buffer(&gz->z, n, Qnil); if (NIL_P(dst)) return dst; gzfile_calc_crc(gz, dst); dst = gzfile_newstr(gz, dst); @@ -4296,7 +4405,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj) while (ZSTREAM_BUF_FILLED(&gz->z) < rslen) { if (ZSTREAM_IS_FINISHED(&gz->z)) { if (ZSTREAM_BUF_FILLED(&gz->z) > 0) gz->lineno++; - return gzfile_read(gz, rslen); + return gzfile_read(gz, rslen, Qnil); } gzfile_read_more(gz, Qnil); } @@ -4333,7 +4442,7 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj) } gz->lineno++; - dst = gzfile_read(gz, n); + dst = gzfile_read(gz, n, Qnil); if (NIL_P(dst)) return dst; if (rspara) { gzreader_skip_linebreaks(gz); @@ -4581,6 +4690,7 @@ zlib_gunzip_run(VALUE arg) gzfile_read_header(gz, Qnil); dst = zstream_detach_buffer(&gz->z); + ASSUME(!NIL_P(dst)); gzfile_calc_crc(gz, dst); if (!ZSTREAM_IS_FINISHED(&gz->z)) { rb_raise(cGzError, "unexpected end of file"); @@ -4619,6 +4729,7 @@ Init_zlib(void) cMemError = rb_define_class_under(mZlib, "MemError", cZError); cBufError = rb_define_class_under(mZlib, "BufError", cZError); cVersionError = rb_define_class_under(mZlib, "VersionError", cZError); + cInProgressError = rb_define_class_under(mZlib, "InProgressError", cZError); rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0); rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1); @@ -4926,6 +5037,7 @@ Init_zlib(void) * - Zlib::MemError * - Zlib::BufError * - Zlib::VersionError + * - Zlib::InProgressError * */ @@ -5001,6 +5113,20 @@ Init_zlib(void) */ /* + * Document-class: Zlib::InProgressError + * + * Subclass of Zlib::Error. This error is raised when the zlib + * stream is currently in progress. + * + * For example: + * + * inflater = Zlib::Inflate.new + * inflater.inflate(compressed) do + * inflater.inflate(compressed) # Raises Zlib::InProgressError + * end + */ + +/* * Document-class: Zlib::GzipFile::Error * * Base class of errors that occur when processing GZIP files. diff --git a/ext/zlib/zlib.gemspec b/ext/zlib/zlib.gemspec index 4a5f8f2ee8..345dc5f225 100644 --- a/ext/zlib/zlib.gemspec +++ b/ext/zlib/zlib.gemspec @@ -22,10 +22,10 @@ Gem::Specification.new do |spec| spec.homepage = "https://github.com/ruby/zlib" spec.licenses = ["Ruby", "BSD-2-Clause"] - spec.files = ["LICENSE.txt", "README.md", "ext/zlib/extconf.rb", "ext/zlib/zlib.c", "zlib.gemspec"] + spec.files = ["COPYING", "BSDL", "README.md", "ext/zlib/extconf.rb", "ext/zlib/zlib.c", "zlib.gemspec"] spec.bindir = "exe" spec.executables = [] spec.require_paths = ["lib"] spec.extensions = "ext/zlib/extconf.rb" - spec.required_ruby_version = ">= 2.3.0" + spec.required_ruby_version = ">= 2.5.0" end |
