ruby-oci8 2.2.6.1 → 2.2.7

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.
@@ -680,43 +680,53 @@ static VALUE oci8_named_collection_alloc(VALUE klass)
680
680
  return oci8_allocate_typeddata(klass, &oci8_named_collection_data_type);
681
681
  }
682
682
 
683
+ typedef struct {
684
+ oci8_bind_t bind;
685
+ VALUE *obj;
686
+ } bind_named_type_t;
687
+
683
688
  static void bind_named_type_mark(oci8_base_t *base)
684
689
  {
685
- oci8_bind_t *obind = (oci8_bind_t *)base;
686
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
690
+ bind_named_type_t *bnt = (bind_named_type_t *)base;
687
691
 
688
- if (oho != NULL) {
692
+ if (bnt->obj != NULL) {
689
693
  ub4 idx = 0;
690
694
 
691
695
  do {
692
- rb_gc_mark(oho[idx].obj);
693
- } while (++idx < obind->maxar_sz);
696
+ rb_gc_mark(bnt->obj[idx]);
697
+ } while (++idx < bnt->bind.maxar_sz);
694
698
  }
695
- rb_gc_mark(obind->tdo);
699
+ rb_gc_mark(bnt->bind.tdo);
696
700
  }
697
701
 
698
702
  static void bind_named_type_free(oci8_base_t *base)
699
703
  {
700
- oci8_bind_t *obind = (oci8_bind_t *)base;
701
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
704
+ bind_named_type_t *bnt = (bind_named_type_t *)base;
705
+ void **hp = (void **)bnt->bind.valuep;
702
706
 
703
- if (oho != NULL) {
707
+ if (hp != NULL) {
704
708
  ub4 idx = 0;
705
709
 
706
710
  do {
707
- if (oho[idx].hp != NULL) {
708
- OCIObjectFree(oci8_envhp, oci8_errhp, oho[idx].hp, OCI_DEFAULT);
709
- oho[idx].hp = NULL;
711
+ if (hp[idx] != NULL) {
712
+ OCIObjectFree(oci8_envhp, oci8_errhp, hp[idx], OCI_DEFAULT);
713
+ hp[idx] = NULL;
710
714
  }
711
- } while (++idx < obind->maxar_sz);
715
+ } while (++idx < bnt->bind.maxar_sz);
716
+ }
717
+ if (bnt->obj != NULL) {
718
+ xfree(bnt->obj);
719
+ bnt->obj = NULL;
712
720
  }
713
721
  oci8_bind_free(base);
714
722
  }
715
723
 
716
724
  static VALUE bind_named_type_get(oci8_bind_t *obind, void *data, void *null_struct)
717
725
  {
718
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
719
- return oho->obj;
726
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
727
+ ub4 idx = obind->curar_idx;
728
+
729
+ return bnt->obj[idx];
720
730
  }
721
731
 
722
732
  static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
@@ -726,10 +736,12 @@ static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_stru
726
736
 
727
737
  static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
728
738
  {
739
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
729
740
  VALUE tdo_obj = length;
730
741
 
731
742
  obind->value_sz = sizeof(void*);
732
- obind->alloc_sz = sizeof(oci8_hp_obj_t);
743
+ obind->alloc_sz = sizeof(void*);
744
+ bnt->obj = xcalloc(sizeof(VALUE), obind->maxar_sz ? obind->maxar_sz : 1);
733
745
 
734
746
  CHECK_TDO(tdo_obj);
735
747
  RB_OBJ_WRITE(obind->base.self, &obind->tdo, tdo_obj);
@@ -737,7 +749,8 @@ static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE
737
749
 
738
750
  static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
739
751
  {
740
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
752
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
753
+ void **hp = (void **)obind->valuep;
741
754
  oci8_base_t *tdo = DATA_PTR(obind->tdo);
742
755
  OCITypeCode tc = OCITypeTypeCode(oci8_envhp, oci8_errhp, tdo->hp.tdo);
743
756
  VALUE klass = Qnil;
@@ -755,14 +768,14 @@ static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
755
768
  }
756
769
  svcctx = oci8_get_svcctx(svc);
757
770
  do {
758
- oho[idx].obj = rb_class_new_instance(0, NULL, klass);
759
- RB_OBJ_WRITTEN(obind->base.self, Qundef, oho[idx].obj);
760
- obj = DATA_PTR(oho[idx].obj);
761
- RB_OBJ_WRITE(oho[idx].obj, &obj->tdo, obind->tdo);
762
- obj->instancep = (char**)&oho[idx].hp;
771
+ bnt->obj[idx] = rb_class_new_instance(0, NULL, klass);
772
+ RB_OBJ_WRITTEN(obind->base.self, Qundef, bnt->obj[idx]);
773
+ obj = DATA_PTR(bnt->obj[idx]);
774
+ RB_OBJ_WRITE(bnt->obj[idx], &obj->tdo, obind->tdo);
775
+ obj->instancep = (char**)&hp[idx];
763
776
  obj->null_structp = (char**)&obind->u.null_structs[idx];
764
777
  oci8_link_to_parent(&obj->base, &obind->base);
765
- RB_OBJ_WRITTEN(oho[idx].obj, Qundef, obind->base.self);
778
+ RB_OBJ_WRITTEN(bnt->obj[idx], Qundef, obind->base.self);
766
779
 
767
780
  chker2(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep),
768
781
  &svcctx->base);
@@ -804,7 +817,7 @@ static const oci8_bind_data_type_t bind_named_type_data_type = {
804
817
  #endif
805
818
  },
806
819
  bind_named_type_free,
807
- sizeof(oci8_bind_t)
820
+ sizeof(bind_named_type_t)
808
821
  },
809
822
  bind_named_type_get,
810
823
  bind_named_type_set,
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  * oci8.c - part of ruby-oci8
4
4
  *
5
- * Copyright (C) 2002-2015 Kubo Takehiro <kubo@jiubao.org>
5
+ * Copyright (C) 2002-2019 Kubo Takehiro <kubo@jiubao.org>
6
6
  *
7
7
  */
8
8
  #include "oci8.h"
@@ -734,14 +734,9 @@ static VALUE oci8_set_autocommit(VALUE self, VALUE val)
734
734
  /*
735
735
  * @overload long_read_len
736
736
  *
737
- * Gets the maximum length in bytes to fetch a LONG or LONG RAW
738
- * column. The default value is 65535.
739
- *
740
- * If the actual data length is longer than long_read_len,
741
- * the fetched valud is truncated and the value of {OCI8#last_error}
742
- * become {OCISuccessWithInfo} whose message is "ORA-01406: fetched column value was truncated".
743
- *
744
- * Note: long_read_len is also used for maximum length of XMLTYPE data type.
737
+ * @deprecated This has no effect since ruby-oci8 2.2.7.
738
+ * LONG, LONG RAW and XMLTYPE columns are fetched up to 4 gigabytes
739
+ * without this parameter.
745
740
  *
746
741
  * @return [Integer]
747
742
  * @see #long_read_len=
@@ -749,14 +744,16 @@ static VALUE oci8_set_autocommit(VALUE self, VALUE val)
749
744
  static VALUE oci8_long_read_len(VALUE self)
750
745
  {
751
746
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
747
+ rb_warning("OCI8.long_read_len has no effect since ruby-oci8 2.2.7");
752
748
  return svcctx->long_read_len;
753
749
  }
754
750
 
755
751
  /*
756
752
  * @overload long_read_len=(length)
757
753
  *
758
- * Sets the maximum length in bytes to fetch a LONG or LONG RAW
759
- * column.
754
+ * @deprecated This has no effect since ruby-oci8 2.2.7.
755
+ * LONG, LONG RAW and XMLTYPE columns are fetched up to 4 gigabytes
756
+ * without this parameter.
760
757
  *
761
758
  * @param [Integer] length
762
759
  * @see #long_read_len
@@ -766,6 +763,7 @@ static VALUE oci8_set_long_read_len(VALUE self, VALUE val)
766
763
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
767
764
  Check_Type(val, T_FIXNUM);
768
765
  RB_OBJ_WRITE(self, &svcctx->long_read_len, val);
766
+ rb_warning("OCI8.long_read_len= has no effect since ruby-oci8 2.2.7");
769
767
  return val;
770
768
  }
771
769
 
@@ -584,7 +584,7 @@ EOS
584
584
  if try_run("int main() { return 0; }")
585
585
  puts "ok"
586
586
  else
587
- puts "ng"
587
+ puts "failed"
588
588
  raise "C compiler doesn't work correctly."
589
589
  end
590
590
  end # check_cc
@@ -630,7 +630,7 @@ EOS
630
630
  STDOUT.flush
631
631
  rubyhdrdir = RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG['archdir']
632
632
  unless File.exist?(rubyhdrdir + '/ruby.h')
633
- puts "ng"
633
+ puts "failed"
634
634
  if RUBY_PLATFORM =~ /darwin/ and File.exist?("#{RbConfig::CONFIG['archdir']}/../universal-darwin8.0/ruby.h")
635
635
  raise <<EOS
636
636
  #{RbConfig::CONFIG['archdir']}/ruby.h doesn't exist.
@@ -15,7 +15,8 @@ static VALUE cOCIStmt;
15
15
  typedef struct {
16
16
  oci8_base_t base;
17
17
  VALUE svc;
18
- int use_stmt_release;
18
+ char use_stmt_release;
19
+ char end_of_fetch;
19
20
  } oci8_stmt_t;
20
21
 
21
22
  static void oci8_stmt_mark(oci8_base_t *base)
@@ -111,12 +112,24 @@ static VALUE oci8_define_by_pos(VALUE self, VALUE vposition, VALUE vbindobj)
111
112
  oci8_bind_t *obind = TO_BIND(vbindobj);
112
113
  const oci8_bind_data_type_t *data_type;
113
114
  sword status;
115
+ void *valuep;
116
+ void *indp;
117
+ ub4 mode;
114
118
 
115
119
  if (obind->base.hp.dfn != NULL) {
116
120
  oci8_base_free(&obind->base); /* TODO: OK? */
117
121
  }
118
122
  data_type = (const oci8_bind_data_type_t *)obind->base.data_type;
119
- status = OCIDefineByPos(stmt->base.hp.stmt, &obind->base.hp.dfn, oci8_errhp, position, obind->valuep, obind->value_sz, data_type->dty, NIL_P(obind->tdo) ? obind->u.inds : NULL, NULL, 0, OCI_DEFAULT);
123
+ if (obind->value_sz != SB4MAXVAL) {
124
+ valuep = obind->valuep;
125
+ indp = NIL_P(obind->tdo) ? obind->u.inds : NULL;
126
+ mode = OCI_DEFAULT;
127
+ } else {
128
+ valuep = NULL;
129
+ indp = NULL;
130
+ mode = OCI_DYNAMIC_FETCH;
131
+ }
132
+ status = OCIDefineByPos(stmt->base.hp.stmt, &obind->base.hp.dfn, oci8_errhp, position, valuep, obind->value_sz, data_type->dty, indp, NULL, 0, mode);
120
133
  if (status != OCI_SUCCESS) {
121
134
  chker3(status, &stmt->base, stmt->base.hp.ptr);
122
135
  }
@@ -151,7 +164,9 @@ static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
151
164
  oci8_bind_t *obind;
152
165
  const oci8_bind_data_type_t *data_type;
153
166
  sword status;
167
+ void *valuep;
154
168
  void *indp;
169
+ ub4 mode;
155
170
 
156
171
  if (NIL_P(vplaceholder)) { /* 1 */
157
172
  placeholder_ptr = NULL;
@@ -185,11 +200,19 @@ static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
185
200
  }
186
201
  data_type = (const oci8_bind_data_type_t *)obind->base.data_type;
187
202
 
188
- indp = NIL_P(obind->tdo) ? obind->u.inds : NULL;
203
+ if (obind->value_sz != SB4MAXVAL) {
204
+ valuep = obind->valuep;
205
+ indp = NIL_P(obind->tdo) ? obind->u.inds : NULL;
206
+ mode = OCI_DEFAULT;
207
+ } else {
208
+ valuep = NULL;
209
+ indp = NULL;
210
+ mode = OCI_DATA_AT_EXEC;
211
+ }
189
212
  if (placeholder_ptr == (char*)-1) {
190
- status = OCIBindByPos(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, position, obind->valuep, obind->value_sz, data_type->dty, indp, NULL, 0, 0, 0, OCI_DEFAULT);
213
+ status = OCIBindByPos(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, position, valuep, obind->value_sz, data_type->dty, indp, NULL, 0, 0, 0, mode);
191
214
  } else {
192
- status = OCIBindByName(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, TO_ORATEXT(placeholder_ptr), placeholder_len, obind->valuep, obind->value_sz, data_type->dty, indp, NULL, 0, 0, 0, OCI_DEFAULT);
215
+ status = OCIBindByName(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, TO_ORATEXT(placeholder_ptr), placeholder_len, valuep, obind->value_sz, data_type->dty, indp, NULL, 0, 0, 0, mode);
193
216
  }
194
217
  if (status != OCI_SUCCESS) {
195
218
  chker3(status, &stmt->base, stmt->base.hp.stmt);
@@ -238,6 +261,7 @@ static VALUE oci8_stmt_execute(VALUE self, VALUE iteration_count)
238
261
  oci8_stmt_t *stmt = TO_STMT(self);
239
262
  oci8_svcctx_t *svcctx = oci8_get_svcctx(stmt->svc);
240
263
 
264
+ stmt->end_of_fetch = 0;
241
265
  chker3(oci8_call_stmt_execute(svcctx, stmt, NUM2UINT(iteration_count),
242
266
  svcctx->is_autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT),
243
267
  &stmt->base, stmt->base.hp.stmt);
@@ -245,7 +269,7 @@ static VALUE oci8_stmt_execute(VALUE self, VALUE iteration_count)
245
269
  }
246
270
 
247
271
  /*
248
- * @overload __fetch(connection)
272
+ * @overload __fetch(connection, max_rows)
249
273
  *
250
274
  * Fetches one row and set the result to <code>@define_handles</code>.
251
275
  * This is called by private methods of OCI8::Cursor.
@@ -255,13 +279,18 @@ static VALUE oci8_stmt_execute(VALUE self, VALUE iteration_count)
255
279
  *
256
280
  * @private
257
281
  */
258
- static VALUE oci8_stmt_fetch(VALUE self, VALUE svc)
282
+ static VALUE oci8_stmt_fetch(VALUE self, VALUE svc, VALUE max_rows)
259
283
  {
260
284
  oci8_stmt_t *stmt = TO_STMT(self);
261
285
  oci8_svcctx_t *svcctx = oci8_get_svcctx(svc);
262
286
  sword rv;
263
287
  oci8_bind_t *obind;
264
288
  const oci8_bind_data_type_t *data_type;
289
+ ub4 nrows = NUM2UINT(max_rows);
290
+
291
+ if (stmt->end_of_fetch) {
292
+ return Qnil;
293
+ }
265
294
 
266
295
  if (stmt->base.children != NULL) {
267
296
  obind = (oci8_bind_t *)stmt->base.children;
@@ -271,16 +300,22 @@ static VALUE oci8_stmt_fetch(VALUE self, VALUE svc)
271
300
  if (data_type->pre_fetch_hook != NULL) {
272
301
  data_type->pre_fetch_hook(obind, stmt->svc);
273
302
  }
303
+ if (nrows > 1 && nrows != obind->maxar_sz) {
304
+ rb_raise(rb_eRuntimeError, "fetch size (%u) != define-handle size %u", nrows, obind->maxar_sz);
305
+ }
274
306
  }
275
307
  obind = (oci8_bind_t *)obind->base.next;
276
308
  } while (obind != (oci8_bind_t*)stmt->base.children);
277
309
  }
278
- rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
310
+ rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, nrows, OCI_FETCH_NEXT, OCI_DEFAULT);
279
311
  if (rv == OCI_NO_DATA) {
280
- return Qfalse;
312
+ stmt->end_of_fetch = 1;
313
+ } else {
314
+ chker3(rv, &svcctx->base, stmt->base.hp.stmt);
281
315
  }
282
- chker3(rv, &svcctx->base, stmt->base.hp.stmt);
283
- return Qtrue;
316
+ chker2(OCIAttrGet(stmt->base.hp.stmt, OCI_HTYPE_STMT, &nrows, 0, OCI_ATTR_ROWS_FETCHED, oci8_errhp),
317
+ &svcctx->base);
318
+ return nrows ? UINT2NUM(nrows) : Qnil;
284
319
  }
285
320
 
286
321
  /*
@@ -405,7 +440,7 @@ void Init_oci8_stmt(VALUE cOCI8)
405
440
  rb_define_private_method(cOCIStmt, "__define", oci8_define_by_pos, 2);
406
441
  rb_define_private_method(cOCIStmt, "__bind", oci8_bind, 2);
407
442
  rb_define_private_method(cOCIStmt, "__execute", oci8_stmt_execute, 1);
408
- rb_define_private_method(cOCIStmt, "__fetch", oci8_stmt_fetch, 1);
443
+ rb_define_private_method(cOCIStmt, "__fetch", oci8_stmt_fetch, 2);
409
444
  rb_define_private_method(cOCIStmt, "__paramGet", oci8_stmt_get_param, 1);
410
445
  rb_define_method(cOCIStmt, "rowid", oci8_stmt_get_rowid, 0);
411
446
 
@@ -95,7 +95,7 @@ begin
95
95
 
96
96
  ruby_arch = [nil].pack('P').size == 8 ? :x64 : :x86
97
97
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
98
- if dll_arch.call(File.join(path, 'OCI.DLL')) == ruby_arch
98
+ if !path.empty? && dll_arch.call(File.join(path, 'OCI.DLL')) == ruby_arch
99
99
  dll_dir = RubyInstaller::Runtime.add_dll_directory(path)
100
100
  break
101
101
  end
@@ -172,20 +172,6 @@ class OCI8
172
172
  end
173
173
  end
174
174
 
175
- class Long < OCI8::BindType::String
176
- def self.create(con, val, param, max_array_size)
177
- param = {:length => con.long_read_len, :char_semantics => true}
178
- super(con, val, param, max_array_size)
179
- end
180
- end
181
-
182
- class LongRaw < OCI8::BindType::RAW
183
- def self.create(con, val, param, max_array_size)
184
- param = {:length => con.long_read_len, :char_semantics => false}
185
- self.new(con, val, param, max_array_size)
186
- end
187
- end
188
-
189
175
  class CLOB
190
176
  def self.create(con, val, param, max_array_size)
191
177
  if param.is_a? OCI8::Metadata::Base and param.charset_form == :nchar
@@ -6,14 +6,24 @@ class OCI8
6
6
  case RUBY_PLATFORM
7
7
  when /mswin32|cygwin|mingw32|bccwin32/
8
8
 
9
- require 'Win32API'
9
+ require 'fiddle/import'
10
+ require 'fiddle/types'
11
+
12
+ extend Fiddle::Importer
13
+ dlload 'kernel32.dll'
14
+ include Fiddle::BasicTypes
15
+ include Fiddle::Win32Types
16
+
17
+ typealias "HANDLE", "void*"
18
+ typealias "HMODULE", "void*"
19
+ extern "DWORD GetModuleFileNameA(HMODULE, LPSTR, DWORD)"
20
+ extern "UINT GetSystemDirectoryA(LPCSTR, UINT)"
21
+ extern "UINT GetWindowsDirectoryA(LPCSTR, UINT)"
22
+ extern "HMODULE LoadLibraryExA(LPCSTR, HANDLE, DWORD)"
23
+ extern "BOOL FreeLibrary(HMODULE)"
24
+
10
25
  MAX_PATH = 260
11
- GetModuleFileNameA = Win32API.new('kernel32.dll', 'GetModuleFileNameA', 'PPL', 'L')
12
- GetSystemDirectoryA = Win32API.new('kernel32.dll', 'GetSystemDirectoryA', 'PL', 'L')
13
- GetWindowsDirectoryA = Win32API.new('kernel32.dll', 'GetWindowsDirectoryA', 'PL', 'L')
14
- LoadLibraryExA = Win32API.new('kernel32.dll', 'LoadLibraryExA', 'PPL', 'P')
15
- FreeLibrary = Win32API.new('kernel32.dll', 'FreeLibrary', 'P', 'L')
16
- LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020
26
+ DONT_RESOLVE_DLL_REFERENCES = 0x00000001
17
27
 
18
28
  def self.check_os_specific_load_error(exc)
19
29
  case exc.message
@@ -23,25 +33,50 @@ class OCI8
23
33
  check_win32_pe_arch(File.join(path, '\OCI.DLL'), "Oracle client")
24
34
  end
25
35
  when /^OCI.DLL: 126\(/, /^126: / # "OCI.DLL: 126(The specified module could not be found.)" in English
26
- handle = LoadLibraryExA.call('OCI.DLL', nil, LOAD_LIBRARY_AS_IMAGE_RESOURCE)
27
- unless handle.null?
28
- FreeLibrary.call(handle)
29
- raise LoadError, <<EOS
30
- OCI.DLL is in the PATH but its dependent modules are not found.
36
+ oci_dll_files = dll_load_path_list.inject([]) do |files, path|
37
+ file = File.join(path, '\OCI.DLL')
38
+ files << file if File.exist?(file)
39
+ files
40
+ end
41
+ if oci_dll_files.empty?
42
+ raise LoadError, "Cannot find OCI.DLL in PATH."
43
+ end
44
+ if oci_dll_files.none? {|file| open(file, 'rb') {true} rescue false}
45
+ raise LoadError, "OCI.DLL in PATH isn't readable."
46
+ end
47
+ first_error = nil
48
+ oci_dll_files.each do |file|
49
+ begin
50
+ check_win32_pe_arch(file, "Oracle client")
51
+ valid_arch = true
52
+ rescue LoadError
53
+ first_error ||= $!
54
+ valid_arch = false
55
+ end
56
+ if valid_arch
57
+ handle = LoadLibraryExA(file, nil, DONT_RESOLVE_DLL_REFERENCES)
58
+ unless handle.null?
59
+ FreeLibrary(handle)
60
+ raise LoadError, <<EOS
61
+ Cannot find DLLs depended by #{file}.
31
62
  See http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-instant-client.md#Windows
32
63
  EOS
64
+ end
65
+ break
66
+ end
33
67
  end
68
+ raise first_error if first_error
34
69
  end
35
70
  end # self.check_os_specific_load_error
36
71
 
37
72
  def self.dll_load_path_list
38
73
  buf = "\0" * MAX_PATH
39
74
  paths = []
40
- paths << buf[0, GetModuleFileNameA.call(nil, buf, MAX_PATH)].force_encoding("locale").gsub(/\\[^\\]*$/, '')
41
- paths << buf[0, GetSystemDirectoryA.call(buf, MAX_PATH)].force_encoding("locale")
42
- paths << buf[0, GetWindowsDirectoryA.call(buf, MAX_PATH)].force_encoding("locale")
75
+ paths << buf[0, GetModuleFileNameA(nil, buf, MAX_PATH)].force_encoding("locale").gsub(/\\[^\\]*$/, '')
76
+ paths << buf[0, GetSystemDirectoryA(buf, MAX_PATH)].force_encoding("locale")
77
+ paths << buf[0, GetWindowsDirectoryA(buf, MAX_PATH)].force_encoding("locale")
43
78
  paths << "."
44
- paths + ENV['PATH'].split(';')
79
+ paths + (ENV['PATH'].split(';').reject {|path| path.empty?})
45
80
  end # self.dll_load_path_list
46
81
 
47
82
  def self.check_win32_pe_arch(filename, package)