ruby-oci8 2.2.6.1 → 2.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)