ruby-oci8 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -61,6 +61,14 @@ static void oci8_handle_mark(oci8_base_t *base)
61
61
 
62
62
  static void oci8_handle_cleanup(oci8_base_t *base)
63
63
  {
64
+ if (oci8_in_finalizer) {
65
+ /* Do nothing when the program exits.
66
+ * The first two words of memory addressed by VALUE datatype is
67
+ * changed in finalizer. If a ruby function which access it such
68
+ * as rb_obj_is_kind_of is called, it may cause SEGV.
69
+ */
70
+ return;
71
+ }
64
72
  oci8_base_free(base);
65
73
  xfree(base);
66
74
  }
@@ -74,7 +82,7 @@ static VALUE oci8_s_allocate(VALUE klass)
74
82
 
75
83
  superklass = klass;
76
84
  while (!RTEST(rb_ivar_defined(superklass, oci8_id_oci8_class))) {
77
- superklass = RCLASS_SUPER(superklass);
85
+ superklass = rb_class_superclass(superklass);
78
86
  if (superklass == rb_cObject)
79
87
  rb_raise(rb_eRuntimeError, "private method `new' called for %s:Class", rb_class2name(klass));
80
88
  }
@@ -10,7 +10,7 @@
10
10
  #include <errno.h>
11
11
  #include "oranumber_util.h"
12
12
 
13
- #ifndef RUBY_VM
13
+ #ifndef RB_NUM_COERCE_FUNCS_NEED_OPID
14
14
  /* ruby 1.8 */
15
15
  #define rb_num_coerce_cmp(x, y, id) rb_num_coerce_cmp((x), (y))
16
16
  #define rb_num_coerce_bin(x, y, id) rb_num_coerce_bin((x), (y))
@@ -39,6 +39,9 @@ static OCINumber const_mPI2; /* -PI/2 */
39
39
 
40
40
  #define _NUMBER(val) ((OCINumber *)DATA_PTR(val)) /* dangerous macro */
41
41
 
42
+ #ifndef T_MASK
43
+ #define T_MASK 0x100 /* TODO: rboci8_type() should be changed to be more portable. */
44
+ #endif
42
45
  #define RBOCI8_T_ORANUMBER (T_MASK + 1)
43
46
  #define RBOCI8_T_BIGDECIMAL (T_MASK + 2)
44
47
  #ifdef T_RATIONAL
@@ -721,13 +724,13 @@ static VALUE onum_add(VALUE lhs, VALUE rhs)
721
724
  oci_lc(OCINumberAdd(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
722
725
  return oci8_make_ocinumber(&r, errhp);
723
726
  case T_FLOAT:
724
- return rb_funcall(onum_to_f(lhs), '+', 1, rhs);
727
+ return rb_funcall(onum_to_f(lhs), oci8_id_add_op, 1, rhs);
725
728
  case RBOCI8_T_RATIONAL:
726
- return rb_funcall(onum_to_r(lhs), '+', 1, rhs);
729
+ return rb_funcall(onum_to_r(lhs), oci8_id_add_op, 1, rhs);
727
730
  case RBOCI8_T_BIGDECIMAL:
728
- return rb_funcall(onum_to_d(lhs), '+', 1, rhs);
731
+ return rb_funcall(onum_to_d(lhs), oci8_id_add_op, 1, rhs);
729
732
  }
730
- return rb_num_coerce_bin(lhs, rhs, '+');
733
+ return rb_num_coerce_bin(lhs, rhs, oci8_id_add_op);
731
734
  }
732
735
 
733
736
  /*
@@ -755,13 +758,13 @@ static VALUE onum_sub(VALUE lhs, VALUE rhs)
755
758
  oci_lc(OCINumberSub(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
756
759
  return oci8_make_ocinumber(&r, errhp);
757
760
  case T_FLOAT:
758
- return rb_funcall(onum_to_f(lhs), '-', 1, rhs);
761
+ return rb_funcall(onum_to_f(lhs), oci8_id_sub_op, 1, rhs);
759
762
  case RBOCI8_T_RATIONAL:
760
- return rb_funcall(onum_to_r(lhs), '-', 1, rhs);
763
+ return rb_funcall(onum_to_r(lhs), oci8_id_sub_op, 1, rhs);
761
764
  case RBOCI8_T_BIGDECIMAL:
762
- return rb_funcall(onum_to_d(lhs), '-', 1, rhs);
765
+ return rb_funcall(onum_to_d(lhs), oci8_id_sub_op, 1, rhs);
763
766
  }
764
- return rb_num_coerce_bin(lhs, rhs, '-');
767
+ return rb_num_coerce_bin(lhs, rhs, oci8_id_sub_op);
765
768
  }
766
769
 
767
770
  /*
@@ -788,13 +791,13 @@ static VALUE onum_mul(VALUE lhs, VALUE rhs)
788
791
  oci_lc(OCINumberMul(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
789
792
  return oci8_make_ocinumber(&r, errhp);
790
793
  case T_FLOAT:
791
- return rb_funcall(onum_to_f(lhs), '*', 1, rhs);
794
+ return rb_funcall(onum_to_f(lhs), oci8_id_mul_op, 1, rhs);
792
795
  case RBOCI8_T_RATIONAL:
793
- return rb_funcall(onum_to_r(lhs), '*', 1, rhs);
796
+ return rb_funcall(onum_to_r(lhs), oci8_id_mul_op, 1, rhs);
794
797
  case RBOCI8_T_BIGDECIMAL:
795
- return rb_funcall(onum_to_d(lhs), '*', 1, rhs);
798
+ return rb_funcall(onum_to_d(lhs), oci8_id_mul_op, 1, rhs);
796
799
  }
797
- return rb_num_coerce_bin(lhs, rhs, '*');
800
+ return rb_num_coerce_bin(lhs, rhs, oci8_id_mul_op);
798
801
  }
799
802
 
800
803
  /*
@@ -830,13 +833,13 @@ static VALUE onum_div(VALUE lhs, VALUE rhs)
830
833
  oci_lc(OCINumberDiv(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
831
834
  return oci8_make_ocinumber(&r, errhp);
832
835
  case T_FLOAT:
833
- return rb_funcall(onum_to_f(lhs), '/', 1, rhs);
836
+ return rb_funcall(onum_to_f(lhs), oci8_id_div_op, 1, rhs);
834
837
  case RBOCI8_T_RATIONAL:
835
- return rb_funcall(onum_to_r(lhs), '/', 1, rhs);
838
+ return rb_funcall(onum_to_r(lhs), oci8_id_div_op, 1, rhs);
836
839
  case RBOCI8_T_BIGDECIMAL:
837
- return rb_funcall(onum_to_d(lhs), '/', 1, rhs);
840
+ return rb_funcall(onum_to_d(lhs), oci8_id_div_op, 1, rhs);
838
841
  }
839
- return rb_num_coerce_bin(lhs, rhs, '/');
842
+ return rb_num_coerce_bin(lhs, rhs, oci8_id_div_op);
840
843
  }
841
844
 
842
845
  /*
@@ -1171,7 +1174,7 @@ static VALUE onum_to_d_real(OCINumber *num, OCIError *errhp)
1171
1174
  {
1172
1175
  char buf[64];
1173
1176
  ub4 buf_size = sizeof(buf);
1174
- const const char *fmt = "FM9.99999999999999999999999999999999999999EEEE";
1177
+ const char *fmt = "FM9.99999999999999999999999999999999999999EEEE";
1175
1178
 
1176
1179
  if (!cBigDecimal) {
1177
1180
  rb_require("bigdecimal");
@@ -1182,6 +1185,24 @@ static VALUE onum_to_d_real(OCINumber *num, OCIError *errhp)
1182
1185
  return rb_funcall(rb_cObject, id_BigDecimal, 1, rb_usascii_str_new(buf, buf_size));
1183
1186
  }
1184
1187
 
1188
+ /*
1189
+ * call-seq:
1190
+ * onum.has_decimal_part? -> true or false
1191
+ *
1192
+ * Returns +true+ if <i>self</i> has a decimal part.
1193
+ *
1194
+ * OraNumber(10).has_decimal_part? # => false
1195
+ * OraNumber(10.1).has_decimal_part? # => true
1196
+ */
1197
+ static VALUE onum_has_decimal_part_p(VALUE self)
1198
+ {
1199
+ OCIError *errhp = oci8_errhp;
1200
+ boolean result;
1201
+
1202
+ oci_lc(OCINumberIsInt(errhp, _NUMBER(self), &result));
1203
+ return result ? Qfalse : Qtrue;
1204
+ }
1205
+
1185
1206
  /*
1186
1207
  * call-seq:
1187
1208
  * onum.to_onum -> oranumber
@@ -1504,6 +1525,7 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
1504
1525
  rb_define_method(cOCINumber, "to_f", onum_to_f, 0);
1505
1526
  rb_define_method(cOCINumber, "to_r", onum_to_r, 0);
1506
1527
  rb_define_method(cOCINumber, "to_d", onum_to_d, 0);
1528
+ rb_define_method(cOCINumber, "has_decimal_part?", onum_has_decimal_part_p, 0);
1507
1529
  rb_define_method_nodoc(cOCINumber, "to_onum", onum_to_onum, 0);
1508
1530
 
1509
1531
  rb_define_method(cOCINumber, "zero?", onum_zero_p, 0);
@@ -378,6 +378,18 @@ EOS
378
378
 
379
379
  private
380
380
 
381
+ def self.make_proc_to_check_cpu(expect)
382
+ Proc.new do |file|
383
+ so = MiniSOReader.new(file)
384
+ if so.cpu == expect
385
+ true
386
+ else
387
+ puts " skip: #{file} is for #{so.cpu} cpu."
388
+ false
389
+ end
390
+ end
391
+ end
392
+
381
393
  def self.check_ic_dir
382
394
  puts "checking for load library path... "
383
395
  STDOUT.flush
@@ -390,6 +402,16 @@ EOS
390
402
  so_ext = 'so'
391
403
  nls_data_ext = nil
392
404
  check_proc = nil
405
+ size_of_pointer = begin
406
+ # the size of a pointer.
407
+ [nil].pack('P').size
408
+ rescue ArgumentError
409
+ # Rubinius 1.2.3 doesn't support Array#pack('P').
410
+ # Use Fixnum#size, which returns the size of long.
411
+ 1.size
412
+ end
413
+ is_32bit = size_of_pointer == 4
414
+ is_big_endian = "\x01\x02".unpack('s')[0] == 0x0102
393
415
  case RUBY_PLATFORM
394
416
  when /mswin32|cygwin|mingw32|bccwin32/
395
417
  oci_basename = 'oci'
@@ -398,40 +420,29 @@ EOS
398
420
  @@ld_envs = %w[PATH]
399
421
  so_ext = 'dll'
400
422
  when /i.86-linux/
401
- check_proc = Proc.new do |file|
402
- so = MiniSOReader.new(file)
403
- if so.cpu == :i386
404
- true
405
- else
406
- puts " skip: #{file} is for #{so.cpu} cpu."
407
- false
408
- end
409
- end
423
+ check_proc = make_proc_to_check_cpu(:i386)
410
424
  when /ia64-linux/
411
- check_proc = Proc.new do |file|
412
- so = MiniSOReader.new(file)
413
- if so.cpu == :ia64
414
- true
415
- else
416
- puts " skip: #{file} is for #{so.cpu} cpu."
417
- false
418
- end
419
- end
425
+ check_proc = make_proc_to_check_cpu(:ia64)
420
426
  when /x86_64-linux/
421
- check_proc = Proc.new do |file|
422
- so = MiniSOReader.new(file)
423
- if so.cpu == :x86_64
424
- true
427
+ # RUBY_PLATFORM depends on the compilation environment.
428
+ # Even though it is x86_64-linux, the compiled ruby may
429
+ # be a 32-bit executable.
430
+ check_proc = make_proc_to_check_cpu(is_32bit ? :i386 : :x86_64)
431
+ when /solaris/
432
+ if is_32bit
433
+ @@ld_envs = %w[LD_LIBRARY_PATH_32 LD_LIBRARY_PATH]
434
+ if is_big_endian
435
+ check_proc = make_proc_to_check_cpu(:sparc)
425
436
  else
426
- puts " skip: #{file} is for #{so.cpu} cpu."
427
- false
437
+ check_proc = make_proc_to_check_cpu(:i386)
428
438
  end
429
- end
430
- when /solaris/
431
- if [0].pack('l!').length == 8
432
- @@ld_envs = %w[LD_LIBRARY_PATH_64 LD_LIBRARY_PATH]
433
439
  else
434
- @@ld_envs = %w[LD_LIBRARY_PATH_32 LD_LIBRARY_PATH]
440
+ @@ld_envs = %w[LD_LIBRARY_PATH_64 LD_LIBRARY_PATH]
441
+ if is_big_endian
442
+ check_proc = make_proc_to_check_cpu(:sparcv9)
443
+ else
444
+ check_proc = make_proc_to_check_cpu(:x86_64)
445
+ end
435
446
  end
436
447
  when /aix/
437
448
  oci_glob_postfix = ''
@@ -439,29 +450,27 @@ EOS
439
450
  so_ext = 'a'
440
451
  nls_data_ext = 'so'
441
452
  when /hppa.*-hpux/
442
- if [0].pack('l!').length == 4
453
+ if is_32bit
443
454
  @@ld_envs = %w[SHLIB_PATH]
444
455
  end
445
456
  so_ext = 'sl'
446
457
  when /darwin/
447
458
  @@ld_envs = %w[DYLD_LIBRARY_PATH]
448
459
  so_ext = 'dylib'
449
- check_proc = Proc.new do |file|
450
- is_32bit = [0].pack('l!').size == 4
451
- is_big_endian = "\x01\x02".unpack('s')[0] == 0x0102
452
- if is_32bit
453
- if is_big_endian
454
- this_cpu = :ppc # 32-bit big-endian
455
- else
456
- this_cpu = :i386 # 32-bit little-endian
457
- end
460
+ if is_32bit
461
+ if is_big_endian
462
+ this_cpu = :ppc # 32-bit big-endian
458
463
  else
459
- if is_big_endian
460
- this_cpu = :ppc64 # 64-bit big-endian
461
- else
462
- this_cpu = :x86_64 # 64-bit little-endian
463
- end
464
+ this_cpu = :i386 # 32-bit little-endian
464
465
  end
466
+ else
467
+ if is_big_endian
468
+ this_cpu = :ppc64 # 64-bit big-endian
469
+ else
470
+ this_cpu = :x86_64 # 64-bit little-endian
471
+ end
472
+ end
473
+ check_proc = Proc.new do |file|
465
474
  so = MiniSOReader.new(file)
466
475
  if so.file_format == :universal
467
476
  if so.cpu.include? this_cpu
@@ -495,40 +504,43 @@ EOS
495
504
  next
496
505
  end
497
506
  puts " #{env}... "
498
- ENV[env].split(File::PATH_SEPARATOR).each do |path|
499
- next if path.nil? or path == ''
500
- print " checking #{path}... "
501
- path.gsub!(/\\/, '/') if /mswin32|cygwin|mingw32|bccwin32/ =~ RUBY_PLATFORM
502
- files = Dir.glob(File.join(path, glob_name))
503
- if files.empty?
504
- puts "no"
505
- next
506
- end
507
- STDOUT.flush
508
- next if (check_proc && !check_proc.call(files[0]))
509
- file = files[0]
510
- ld_path = path
511
- puts "yes"
512
- break
513
- end
514
- break
507
+ ld_path, file = check_lib_in_path(ENV[env], glob_name, check_proc)
508
+ break if ld_path
515
509
  end
516
510
 
517
- if ld_path.nil? and RUBY_PLATFORM =~ /linux/
518
- open("|/sbin/ldconfig -p") do |f|
519
- print " checking ld.so.conf... "
520
- STDOUT.flush
521
- while line = f.gets
522
- if line =~ /libclntsh\.so\..* => (\/.*)\/libclntsh\.so\.(.*)/
523
- file = "#$1/libclntsh.so.#$2"
524
- path = $1
525
- next if (check_proc && !check_proc.call(file))
526
- ld_path = path
527
- puts "yes"
528
- break
511
+ if ld_path.nil?
512
+ case RUBY_PLATFORM
513
+ when /linux/
514
+ open("|/sbin/ldconfig -p") do |f|
515
+ print " checking ld.so.conf... "
516
+ STDOUT.flush
517
+ while line = f.gets
518
+ if line =~ /libclntsh\.so\..* => (\/.*)\/libclntsh\.so\.(.*)/
519
+ file = "#$1/libclntsh.so.#$2"
520
+ path = $1
521
+ next if (check_proc && !check_proc.call(file))
522
+ ld_path = path
523
+ puts "yes"
524
+ break
525
+ end
526
+ end
527
+ puts "no"
528
+ end
529
+ when /solaris/
530
+ if is_32bit
531
+ crle_cmd = 'crle'
532
+ else
533
+ crle_cmd = 'crle -64'
534
+ end
535
+ open('|env LANG=C /usr/bin/' + crle_cmd) do |f|
536
+ while line = f.gets
537
+ if line =~ /Default Library Path[^:]*:\s*(\S*)/
538
+ puts " checking output of `#{crle_cmd}'... "
539
+ ld_path, file = check_lib_in_path($1, glob_name, check_proc)
540
+ break
541
+ end
529
542
  end
530
543
  end
531
- puts "no"
532
544
  end
533
545
  end
534
546
 
@@ -545,6 +557,23 @@ EOS
545
557
  nil
546
558
  end
547
559
 
560
+ def self.check_lib_in_path(paths, glob_name, check_proc)
561
+ paths.split(File::PATH_SEPARATOR).each do |path|
562
+ next if path.nil? or path == ''
563
+ print " checking #{path}... "
564
+ path.gsub!(/\\/, '/') if /mswin32|cygwin|mingw32|bccwin32/ =~ RUBY_PLATFORM
565
+ files = Dir.glob(File.join(path, glob_name))
566
+ if files.empty?
567
+ puts "no"
568
+ next
569
+ end
570
+ STDOUT.flush
571
+ next if (check_proc && !check_proc.call(files[0]))
572
+ puts "yes"
573
+ return path, files[0]
574
+ end
575
+ end
576
+
548
577
  def init
549
578
  check_cc()
550
579
  @cc_is_gcc = check_cc_is_gcc()
@@ -1109,20 +1138,8 @@ EOS
1109
1138
  end
1110
1139
 
1111
1140
  if RUBY_PLATFORM =~ /darwin/
1112
- is_intelmac = ([1].pack('s') == "\001\000")
1113
- arch_ppc_error = false
1114
- arch_i386_error = false
1115
1141
  open('mkmf.log', 'r') do |f|
1116
1142
  while line = f.gets
1117
- # universal-darwin8.0 (Mac OS X 10.4?)
1118
- if line.include? 'cputype (18, architecture ppc) does not match cputype (7)'
1119
- # try to link an i386 library but the instant client is ppc.
1120
- arch_i386_error = true
1121
- end
1122
- if line.include? 'cputype (7, architecture i386) does not match cputype (18)'
1123
- # try to link a ppc library but the instant client is i386.
1124
- arch_ppc_error = true
1125
- end
1126
1143
  if line.include? '/libclntsh.dylib load command 8 unknown cmd field'
1127
1144
  raise <<EOS
1128
1145
  Intel mac instant client is for Mac OS X 10.5.
@@ -1135,54 +1152,37 @@ You have three workarounds.
1135
1152
  EOS
1136
1153
  # '
1137
1154
  end
1138
- # universal-darwin9.0 (Mac OS X 10.5?)
1139
- if line.include? 'Undefined symbols for architecture i386:'
1140
- # try to link an i386 library but the instant client is ppc.
1141
- arch_i386_error = true
1142
- end
1143
- if line.include? 'Undefined symbols for architecture ppc:'
1144
- # try to link a ppc library but the instant client is i386.
1145
- arch_ppc_error = true
1155
+
1156
+ case line
1157
+ when /cputype \(\d+, architecture \w+\) does not match cputype \(\d+\) for specified -arch flag: (\w+)/
1158
+ missing_arch = $1
1159
+ when /Undefined symbols for architecture (\w+)/
1160
+ missing_arch = $1
1161
+ when /missing required architecture (\w+) in file/
1162
+ missing_arch = $1
1146
1163
  end
1147
1164
 
1148
- if arch_i386_error
1149
- if is_intelmac
1150
- # intel mac and '-arch i386' error
1151
- raise <<EOS
1152
- Could not compile with Oracle instant client.
1153
- Use intel mac instant client.
1154
- EOS
1165
+ if missing_arch
1166
+ if [nil].pack('p').size == 8
1167
+ my_arch = 'x86_64'
1168
+ elsif "\x01\x02".unpack('s')[0] == 0x0201
1169
+ my_arch = 'i386'
1155
1170
  else
1156
- # ppc mac and '-arch i386' error
1157
- raise <<EOS
1158
- Could not compile with Oracle instant client.
1159
- You may need to set a environment variable:
1160
- RC_ARCHS=ppc
1161
- export RC_ARCHS
1162
- If it does not fix the problem, delete all '-arch i386'
1163
- in '#{Config::CONFIG['archdir']}/rbconfig.rb'.
1164
- EOS
1171
+ my_arch = 'ppc'
1165
1172
  end
1166
- end
1167
-
1168
- if arch_ppc_error
1169
- if is_intelmac
1170
- # intel mac and '-arch ppc' error
1171
- raise <<EOS
1173
+ raise <<EOS
1172
1174
  Could not compile with Oracle instant client.
1173
- You may need to set a environment variable:
1174
- RC_ARCHS=i386
1175
+ You may need to set the environment variable RC_ARCHS or ARCHFLAGS as follows:
1176
+
1177
+ RC_ARCHS=#{my_arch}
1178
+ export RC_ARCHS
1179
+ or
1180
+ ARCHFLAGS='-arch #{my_arch}'
1175
1181
  export RC_ARCHS
1176
- If it does not fix the problem, delete all '-arch ppc'
1182
+
1183
+ If it does not fix the problem, delete all '-arch #{missing_arch}'
1177
1184
  in '#{Config::CONFIG['archdir']}/rbconfig.rb'.
1178
1185
  EOS
1179
- else
1180
- # ppc mac and '-arch ppc' error
1181
- raise <<EOS
1182
- Could not compile with Oracle instant client.
1183
- Use ppc instant client.
1184
- EOS
1185
- end
1186
1186
  end
1187
1187
  end
1188
1188
  end