ruby-changes:6453
From: usa <ko1@a...>
Date: Wed, 9 Jul 2008 15:55:46 +0900 (JST)
Subject: [ruby-changes:6453] Ruby:r17968 (win32-unicode-test): pullup r17967.
usa 2008-07-09 15:51:15 +0900 (Wed, 09 Jul 2008) New Revision: 17968 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=17968 Log: pullup r17967. Modified files: branches/win32-unicode-test/ChangeLog branches/win32-unicode-test/compile.h branches/win32-unicode-test/dir.c branches/win32-unicode-test/ext/coverage/coverage.c branches/win32-unicode-test/ext/nkf/nkf-utf8/nkf.c branches/win32-unicode-test/ext/win32ole/win32ole.c branches/win32-unicode-test/include/ruby/ruby.h branches/win32-unicode-test/iseq.c branches/win32-unicode-test/lib/debug.rb branches/win32-unicode-test/lib/profile.rb branches/win32-unicode-test/lib/profiler.rb branches/win32-unicode-test/lib/rdoc/parsers/parse_c.rb branches/win32-unicode-test/parse.y branches/win32-unicode-test/string.c branches/win32-unicode-test/test/ruby/test_string.rb branches/win32-unicode-test/test/win32ole/test_win32ole_event.rb branches/win32-unicode-test/thread.c branches/win32-unicode-test/vm.c Index: win32-unicode-test/include/ruby/ruby.h =================================================================== --- win32-unicode-test/include/ruby/ruby.h (revision 17967) +++ win32-unicode-test/include/ruby/ruby.h (revision 17968) @@ -725,10 +725,9 @@ void rb_obj_infect(VALUE,VALUE); -typedef int ruby_glob_func(const char*,VALUE); -void rb_glob(const char*,void(*)(const char*,VALUE),VALUE); +typedef int ruby_glob_func(const char*,VALUE, void*); +void rb_glob(const char*,void(*)(const char*,VALUE,void*),VALUE); int ruby_glob(const char*,int,ruby_glob_func*,VALUE); -int ruby_brace_expand(const char*,int,ruby_glob_func*,VALUE); int ruby_brace_glob(const char*,int,ruby_glob_func*,VALUE); VALUE rb_define_class(const char*,VALUE); Index: win32-unicode-test/ChangeLog =================================================================== --- win32-unicode-test/ChangeLog (revision 17967) +++ win32-unicode-test/ChangeLog (revision 17968) @@ -1,3 +1,112 @@ +Wed Jul 9 11:13:39 2008 Nobuyoshi Nakada <nobu@r...> + + * lib/profiler.rb (Profiler__#print_profile): sort in the descending + order of cumulative time. + +Wed Jul 9 11:11:18 2008 Nobuyoshi Nakada <nobu@r...> + + * dir.c (struct glob_args, rb_glob_caller, rb_glob2, push_pattern), + (glob_brace): make consistent prototypes. + + * dir.c (push_glob): set enc in the caller of rb_glob_caller as well + as rb_glob2. + +Wed Jul 9 09:12:11 2008 NARUSE, Yui <naruse@r...> + + * ext/nkf/nkf-utf8/nkf.c (options): use input_endian. + +Wed Jul 9 01:38:37 2008 Nobuyoshi Nakada <nobu@r...> + + * string.c (rb_str_succ): alphabets or numerics mutually enclosing + non-alphanumeric characters can carry up. e.g., "1.999".succ should + be "2.000". + +Wed Jul 9 00:12:31 2008 Yusuke Endoh <mame@t...> + + * thread.c (rb_set_coverages, rb_reset_coverages): enable and disable + coverage measurement. + + * thread.c (rb_get_coverages): rename and move from vm.c. + + * vm.c (rb_vm_get_coverages): ditto. + + * iseq.c (prepare_iseq_build): ditto. + + * thread.c (clear_coverage): ditto. + + * parse.y (coverage): ditto. + + * ext/coverage/coverage.c: use above functions, add new method + Coverage.start and fix rdoc . + +Tue Jul 8 23:02:35 2008 Masaki Suketa <masaki.suketa@n...> + + * ext/win32ole/win32ole.c (find_default_source): bug fix when + OLE object does not have default source interface. + + * test/win32ole/test_win32ole_event.rb: ditto. + +Tue Jul 8 22:56:23 2008 Yusuke Endoh <mame@t...> + + * thread.c (rb_enable_coverages): hide coverage array by setting 0 to + klass during measurement. + + * parse.y (coverage, yycompile0): ditto. + + * iseq.c (prepare_iseq_build): use rb_hash_lookup instead of + rb_hash_aref. + + * thread.c (rb_coverage_result): restore klass of coverage array + and return it. + + * theaad.c (update_coverage): chcek whether its klass is 0. + +Tue Jul 8 22:28:25 2008 Koichi Sasada <ko1@a...> + + * lib/debug.rb, lib/profile.rb: fix to use RubyVM. + + * lib/rdoc/parsers/parse_c.rb: ditto. + +Tue Jul 8 21:45:22 2008 Yusuke Endoh <mame@t...> + + * vm.c (rb_vm_mark): mark the last element of special_exceptions. + +Tue Jul 8 19:55:40 2008 Masaki Suketa <masaki.suketa@n...> + + * ext/win32ole/win32ole.c (find_default_source): try to + find COCLASS when WIN32OLE object is not COCLASS. + + * test/win32ole/test_win32ole_event.rb: ditto + +Tue Jul 8 13:38:22 2008 Koichi Sasada <ko1@a...> + + * compile.h: fix to skip inserting a trace insn. + +Tue Jul 8 11:41:17 2008 NAKAMURA Usaku <usa@r...> + + * dir.c: shoudn't use ruby object in globbing, because glob service + routines are called before initializing ruby on some platforms (ex. + windows). + +Tue Jul 8 10:08:40 2008 NARUSE, Yui <naruse@r...> + + * dir.c (Next): use rb_enc_mbclen. [ruby-dev:35390] + +Tue Jul 8 07:59:40 2008 NARUSE, Yui <naruse@r...> + + * dir.c (Next): use rb_enc_precise_mbclen. + +Tue Jul 8 02:27:23 2008 NARUSE, Yui <naruse@r...> + + * dir.c: preserve encoding of strings in glob and fnmatch. + + * include/ruby/ruby.h: related changes. + +Tue Jul 8 00:22:58 2008 Nobuyoshi Nakada <nobu@r...> + + * string.c (rb_str_succ): limit carrying in an alphanumeric region if + exists. [ruby-dev:35094] + Tue Jul 8 01:04:55 2008 NAKAMURA Usaku <usa@r...> * ruby.c (proc_options, process_options): now opt->e_script is an array @@ -64,7 +173,7 @@ Sun Jul 6 10:12:21 2008 Kouhei Sutou <kou@c...> * lib/test/unit/collector/objectspace.rb - (Test::Unit::Collector::ObjectSpace::NAME): fix a typo. + (Test::Unit::Collector::ObjectSpace::NAME): fix a typo. Sun Jul 6 00:56:51 2008 Tanaka Akira <akr@f...> Index: win32-unicode-test/iseq.c =================================================================== --- win32-unicode-test/iseq.c (revision 17967) +++ win32-unicode-test/iseq.c (revision 17968) @@ -194,10 +194,10 @@ iseq->coverage = Qfalse; if (!GET_THREAD()->parse_in_eval) { - extern VALUE rb_vm_get_coverages(void); - VALUE coverages = rb_vm_get_coverages(); + extern VALUE rb_get_coverages(void); + VALUE coverages = rb_get_coverages(); if (RTEST(coverages)) { - iseq->coverage = rb_hash_aref(coverages, filename); + iseq->coverage = rb_hash_lookup(coverages, filename); if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse; } } Index: win32-unicode-test/string.c =================================================================== --- win32-unicode-test/string.c (revision 17967) +++ win32-unicode-test/string.c (revision 17968) @@ -2516,11 +2516,12 @@ { rb_encoding *enc; VALUE str; - char *sbeg, *s, *e; + char *sbeg, *s, *e, *last_alnum = 0; int c = -1; long l; char carry[ONIGENC_CODE_TO_MBC_MAXLEN] = "\1"; int carry_pos = 0, carry_len = 1; + enum neighbor_char neighbor = NEIGHBOR_FOUND; str = rb_str_new5(orig, RSTRING_PTR(orig), RSTRING_LEN(orig)); rb_enc_cr_str_copy_for_substr(str, orig); @@ -2532,13 +2533,24 @@ s = e = sbeg + RSTRING_LEN(str); while ((s = rb_enc_prev_char(sbeg, s, enc)) != 0) { - enum neighbor_char neighbor; + if (neighbor == NEIGHBOR_NOT_CHAR && last_alnum) { + if (ISALPHA(*last_alnum) ? ISDIGIT(*s) : + ISDIGIT(*last_alnum) ? ISALPHA(*s) : 0) { + s = last_alnum; + break; + } + } if ((l = rb_enc_precise_mbclen(s, e, enc)) <= 0) continue; neighbor = enc_succ_alnum_char(s, l, enc, carry); - if (neighbor == NEIGHBOR_NOT_CHAR) - continue; - if (neighbor == NEIGHBOR_FOUND) - return str; + switch (neighbor) { + case NEIGHBOR_NOT_CHAR: + continue; + case NEIGHBOR_FOUND: + return str; + case NEIGHBOR_WRAPPED: + last_alnum = s; + break; + } c = 1; carry_pos = s - sbeg; carry_len = l; Index: win32-unicode-test/lib/profiler.rb =================================================================== --- win32-unicode-test/lib/profiler.rb (revision 17967) +++ win32-unicode-test/lib/profiler.rb (revision 17968) @@ -34,7 +34,7 @@ total = Process.times[0] - @@start if total == 0 then total = 0.01 end data = @@map.values - data = data.sort_by{|x| x[2]} + data = data.sort_by{|x| -x[2]} sum = 0 f.printf " %% cumulative self self total\n" f.printf " time seconds seconds calls ms/call ms/call name\n" Index: win32-unicode-test/lib/rdoc/parsers/parse_c.rb =================================================================== --- win32-unicode-test/lib/rdoc/parsers/parse_c.rb (revision 17967) +++ win32-unicode-test/lib/rdoc/parsers/parse_c.rb (revision 17968) @@ -36,7 +36,7 @@ "rb_cTime" => "Time", "rb_cTrueClass" => "TrueClass", "rb_cStruct" => "Struct", - "rb_cVM" => "VM", + "rb_cRubyVM" => "RubyVM", "rb_eException" => "Exception", "rb_eStandardError" => "StandardError", "rb_eSystemExit" => "SystemExit", Index: win32-unicode-test/lib/profile.rb =================================================================== --- win32-unicode-test/lib/profile.rb (revision 17967) +++ win32-unicode-test/lib/profile.rb (revision 17968) @@ -1,6 +1,6 @@ require 'profiler' -VM::InstructionSequence.compile_option = { +RubyVM::InstructionSequence.compile_option = { :trace_instruction => true, :specialized_instruction => false } Index: win32-unicode-test/lib/debug.rb =================================================================== --- win32-unicode-test/lib/debug.rb (revision 17967) +++ win32-unicode-test/lib/debug.rb (revision 17968) @@ -904,7 +904,7 @@ set_trace_func proc { |event, file, line, id, binding, klass, *rest| DEBUGGER__.context.trace_func event, file, line, id, binding, klass } -VM::InstructionSequence.compile_option = { +RubyVM::InstructionSequence.compile_option = { trace_instruction: true } end Index: win32-unicode-test/compile.h =================================================================== --- win32-unicode-test/compile.h (revision 17967) +++ win32-unicode-test/compile.h (revision 17968) @@ -164,11 +164,14 @@ #define ADD_TRACE(seq, line, event) \ do { \ - if ((event) == RUBY_EVENT_LINE && iseq->coverage && RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \ + if ((event) == RUBY_EVENT_LINE && iseq->coverage && \ + RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \ RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \ ADD_INSN1(seq, line, trace, INT2FIX(RUBY_EVENT_COVERAGE)); \ } \ - ADD_INSN1(seq, line, trace, INT2FIX(event)); \ + if (iseq->compile_data->option->trace_instruction) { \ + ADD_INSN1(seq, line, trace, INT2FIX(event)); \ + } \ }while(0); /* add label */ Index: win32-unicode-test/thread.c =================================================================== --- win32-unicode-test/thread.c (revision 17967) +++ win32-unicode-test/thread.c (revision 17968) @@ -2117,8 +2117,8 @@ static void clear_coverage(void) { - extern VALUE rb_vm_get_coverages(void); - VALUE coverages = rb_vm_get_coverages(); + extern VALUE rb_get_coverages(void); + VALUE coverages = rb_get_coverages(); if (RTEST(coverages)) { st_foreach(RHASH_TBL(coverages), clear_coverage_i, 0); } @@ -3535,7 +3535,7 @@ update_coverage(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) { VALUE coverage = GET_THREAD()->cfp->iseq->coverage; - if (coverage) { + if (coverage && RBASIC(coverage)->klass == 0) { long line = rb_sourceline() - 1; long count; if (RARRAY_PTR(coverage)[line] == Qnil) { @@ -3548,16 +3548,22 @@ } } +VALUE +rb_get_coverages(void) +{ + return GET_VM()->coverages; +} + void -rb_enable_coverages(void) +rb_set_coverages(VALUE coverages) { - VALUE rb_mCoverage; + GET_VM()->coverages = coverages; + rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil); +} - if (!RTEST(GET_VM()->coverages)) { - extern VALUE rb_vm_get_coverages(void); - GET_VM()->coverages = rb_hash_new(); - rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil); - rb_mCoverage = rb_define_module("Coverage"); - rb_define_module_function(rb_mCoverage, "result", rb_vm_get_coverages, 0); - } +void +rb_reset_coverages(void) +{ + GET_VM()->coverages = Qfalse; + rb_remove_event_hook(update_coverage); } Index: win32-unicode-test/dir.c =================================================================== --- win32-unicode-test/dir.c (revision 17967) +++ win32-unicode-test/dir.c (revision 17968) @@ -80,97 +80,38 @@ #define FNM_NOMATCH 1 #define FNM_ERROR 2 -#define downcase(c) (nocase && ISUPPER(c) ? TOLOWER(c) : (c)) -#define compare(c1, c2) (((unsigned char)(c1)) - ((unsigned char)(c2))) +# define Next(p, e, enc) (p + rb_enc_mbclen(p, e, enc)) +# define Inc(p, e, enc) ((p) = Next(p, e, enc)) -/* caution: in case *p == '\0' - Next(p) == p + 1 in single byte environment - Next(p) == p in multi byte environment -*/ -#if defined(CharNext) -# define Next(p) CharNext(p) -#elif defined(DJGPP) -# define Next(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE)) -#elif defined(__EMX__) -# define Next(p) ((p) + emx_mblen(p)) -static inline int -emx_mblen(const char *p) -{ - int n = mblen(p, RUBY_MBCHAR_MAXSIZE); - return (n < 0) ? 1 : n; -} -#endif - -#ifndef Next /* single byte environment */ -# define Next(p) ((p) + 1) -# define Inc(p) (++(p)) -# define Compare(p1, p2) (compare(downcase(*(p1)), downcase(*(p2)))) -#else /* multi byte environment */ -# define Inc(p) ((p) = Next(p)) -# define Compare(p1, p2) (CompareImpl(p1, p2, nocase)) static int -CompareImpl(const char *p1, const char *p2, int nocase) +char_casecmp(const char *p1, const char *p2, rb_encoding *enc, const int nocase) { - const int len1 = Next(p1) - p1; - const int len2 = Next(p2) - p2; -#ifdef _WIN32 - char buf1[10], buf2[10]; /* large enough? */ -#endif + const char *p1end, *p2end; + int c1, c2; - if (len1 < 0 || len2 < 0) { - rb_fatal("CompareImpl: negative len"); - } + if (!*p1) return *p1; + if (!*p2) return -*p2; + p1end = p1 + strlen(p1); + p2end = p2 + strlen(p2); + c1 = rb_enc_codepoint(p1, p1end, enc); + c2 = rb_enc_codepoint(p2, p2end, enc); - if (len1 == 0) return len2; - if (len2 == 0) return -len1; - -#ifdef _WIN32 - if (nocase && rb_w32_iswinnt()) { - if (len1 > 1) { - if (len1 >= sizeof(buf1)) { - rb_fatal("CompareImpl: too large len"); - } - memcpy(buf1, p1, len1); - buf1[len1] = '\0'; - CharLower(buf1); - p1 = buf1; /* trick */ - } - if (len2 > 1) { - if (len2 >= sizeof(buf2)) { - rb_fatal("CompareImpl: too large len"); - } - memcpy(buf2, p2, len2); - buf2[len2] = '\0'; - CharLower(buf2); - p2 = buf2; /* trick */ - } + if (c1 == c2) return 0; + if (nocase) { + c1 = rb_enc_toupper(c1, enc); + c2 = rb_enc_toupper(c2, enc); } -#endif - if (len1 == 1) - if (len2 == 1) - return compare(downcase(*p1), downcase(*p2)); - else { - const int ret = compare(downcase(*p1), *p2); - return ret ? ret : -1; - } - else - if (len2 == 1) { - const int ret = compare(*p1, downcase(*p2)); - return ret ? ret : 1; - } - else { - const int ret = memcmp(p1, p2, len1 < len2 ? len1 : len2); - return ret ? ret : len1 - len2; - } + return c1 - c2; } -#endif /* environment */ static char * bracket( const char *p, /* pattern (next to '[') */ const char *s, /* string */ - int flags) + int flags, + rb_encoding *enc) { + const char *pend = p + strlen(p); const int nocase = flags & FNM_CASEFOLD; const int escape = !(flags & FNM_NOESCAPE); @@ -187,19 +128,19 @@ t1++; if (!*t1) return NULL; - p = Next(t1); + p = Next(t1, pend, enc); if (p[0] == '-' && p[1] != ']') { const char *t2 = p + 1; if (escape && *t2 == '\\') t2++; if (!*t2) return NULL; - p = Next(t2); - if (!ok && Compare(t1, s) <= 0 && Compare(s, t2) <= 0) + p = Next(t2, pend, enc); + if (!ok && char_casecmp(t1, s, enc, nocase) <= 0 && char_casecmp(s, t2, enc, nocase) <= 0) ok = 1; } else - if (!ok && Compare(t1, s) == 0) + if (!ok && char_casecmp(t1, s, enc, nocase) == 0) ok = 1; } @@ -219,7 +160,8 @@ fnmatch_helper( const char **pcur, /* pattern */ const char **scur, /* string */ - int flags) + int flags, + rb_encoding *enc) { const int period = !(flags & FNM_DOTMATCH); const int pathname = flags & FNM_PATHNAME; @@ -230,7 +172,9 @@ const char *stmp = 0; const char *p = *pcur; + const char *pend = p + strlen(p); const char *s = *scur; + const char *send = s + strlen(s); if (period && *s == '.' && *UNESCAPE(p) != '.') /* leading period */ RETURN(FNM_NOMATCH); @@ -253,16 +197,16 @@ if (ISEND(s)) RETURN(FNM_NOMATCH); p++; - Inc(s); + Inc(s, send, enc); continue; case '[': { const char *t; if (ISEND(s)) RETURN(FNM_NOMATCH); - if ((t = bracket(p + 1, s, flags)) != 0) { + if ((t = bracket(p + 1, s, flags, enc)) != 0) { p = t; - Inc(s); + Inc(s, send, enc); continue; } goto failed; @@ -275,16 +219,16 @@ RETURN(ISEND(p) ? 0 : FNM_NOMATCH); if (ISEND(p)) goto failed; - if (Compare(p, s) != 0) + if (char_casecmp(p, s, enc, nocase) != 0) goto failed; - Inc(p); - Inc(s); + Inc(p, pend, enc); + Inc(s, send, enc); continue; failed: /* try next '*' position */ if (ptmp && stmp) { p = ptmp; - Inc(stmp); /* !ISEND(*stmp) */ + Inc(stmp, send, enc); /* !ISEND(*stmp) */ s = stmp; continue; } @@ -294,10 +238,14 @@ static int fnmatch( - const char *p, /* pattern */ - const char *s, /* string */ + const char *pattern, + rb_encoding *enc, + const char *string, int flags) { + const char *p = pattern; + const char *s = string; + const char *send = s + strlen(string); const int period = !(flags & FNM_DOTMATCH); const int pathname = flags & FNM_PATHNAME; @@ -311,8 +259,8 @@ ptmp = p; stmp = s; } - if (fnmatch_helper(&p, &s, flags) == 0) { - while (*s && *s != '/') Inc(s); + if (fnmatch_helper(&p, &s, flags, enc) == 0) { + while (*s && *s != '/') Inc(s, send, enc); if (*p && *s) { p++; s++; @@ -323,7 +271,7 @@ } /* failed : try next recursion */ if (ptmp && stmp && !(period && *stmp == '.')) { - while (*stmp && *stmp != '/') Inc(stmp); + while (*stmp && *stmp != '/') Inc(stmp, send, enc); if (*stmp) { p = ptmp; stmp++; @@ -335,7 +283,7 @@ } } else - return fnmatch_helper(&p, &s, flags); + return fnmatch_helper(&p, &s, flags, enc); } VALUE rb_cDir; @@ -1030,12 +978,13 @@ /* Return nonzero if S has any special globbing chars in it. */ static int -has_magic(const char *s, int flags) +has_magic(const char *s, int flags, rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); const int nocase = flags & FNM_CASEFOLD; register const char *p = s; + register const char *pend = p + strlen(p); register char c; while ((c = *p++) != 0) { @@ -1055,7 +1004,7 @@ return 1; } - p = Next(p-1); + p = Next(p-1, pend, enc); } return 0; @@ -1063,11 +1012,12 @@ /* Find separator in globbing pattern. */ static char * -find_dirsep(const char *s, int flags) +find_dirsep(const char *s, int flags, rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); register const char *p = s; + register const char *pend = p + strlen(p); register char c; int open = 0; @@ -1091,7 +1041,7 @@ continue; } - p = Next(p-1); + p = Next(p-1, pend, enc); } return (char *)p-1; @@ -1099,8 +1049,9 @@ /* Remove escaping backslashes */ static void -remove_backslashes(char *p) +remove_backslashes(char *p, rb_encoding *enc) { + register const char *pend = p + strlen(p); char *t = p; char *s = p; @@ -1112,7 +1063,7 @@ s = ++p; if (!*p) break; } - Inc(p); + Inc(p, pend, enc); } while (*p++); @@ -1133,7 +1084,7 @@ static void glob_free_pattern(struct glob_pattern *list); static struct glob_pattern * -glob_make_pattern(const char *p, int flags) +glob_make_pattern(const char *p, int flags, rb_encoding *enc) { struct glob_pattern *list, *tmp, **tail = &list; int dirsep = 0; /* pattern is terminated with '/' */ @@ -1149,7 +1100,7 @@ dirsep = 1; } else { - const char *m = find_dirsep(p, flags); + const char *m = find_dirsep(p, flags, enc); char *buf = GLOB_ALLOC_N(char, m-p+1); if (!buf) { GLOB_FREE(tmp); @@ -1157,7 +1108,7 @@ } memcpy(buf, p, m-p); buf[m-p] = '\0'; - tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN; + tmp->type = has_magic(buf, flags, enc) ? MAGICAL : PLAIN; tmp->str = buf; if (*m) { dirsep = 1; @@ -1230,9 +1181,10 @@ #endif struct glob_args { - void (*func)(const char *, VALUE); + void (*func)(const char *, VALUE, void *); const char *path; VALUE value; + rb_encoding *enc; }; static VALUE @@ -1240,11 +1192,11 @@ { struct glob_args *args = (struct glob_args *)val; - (*args->func)(args->path, args->value); + (*args->func)(args->path, args->value, args->enc); return Qnil; } -#define glob_call_func(func, path, arg) (*func)(path, arg) +#define glob_call_func(func, path, arg, enc) (*func)(path, arg, enc) static int glob_helper( @@ -1256,7 +1208,8 @@ struct glob_pattern **end, int flags, ruby_glob_func *func, - VALUE arg) + VALUE arg, + rb_encoding *enc) { struct stat st; int status = 0; @@ -1310,13 +1263,13 @@ } } if (match_all && exist == YES) { - status = glob_call_func(func, path, arg); + status = glob_call_func(func, path, arg, enc); if (status) return status; } if (match_dir && isdir == YES) { char *tmp = join_path(path, dirsep, ""); if (!tmp) return -1; - status = glob_call_func(func, tmp, arg); + status = glob_call_func(func, tmp, arg, enc); GLOB_FREE(tmp); if (status) return status; } @@ -1338,7 +1291,7 @@ break; } if (recursive && strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0 - && fnmatch("*", dp->d_name, flags) == 0) { + && fnmatch("*", rb_usascii_encoding(), dp->d_name, flags) == 0) { #ifndef _WIN32 if (do_lstat(buf, &st, flags) == 0) new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO; @@ -1364,12 +1317,13 @@ p = p->next; /* 0 times recursion */ } if (p->type == PLAIN || p->type == MAGICAL) { - if (fnmatch(p->str, dp->d_name, flags) == 0) + if (fnmatch(p->str, enc, dp->d_name, flags) == 0) *new_end++ = p->next; } } - status = glob_helper(buf, 1, YES, new_isdir, new_beg, new_end, flags, func, arg); + status = glob_helper(buf, 1, YES, new_isdir, new_beg, new_end, + flags, func, arg, enc); GLOB_FREE(buf); GLOB_FREE(new_beg); if (status) break; @@ -1395,7 +1349,7 @@ break; } strcpy(name, (*cur)->str); - if (escape) remove_backslashes(name); + if (escape) remove_backslashes(name, enc); new_beg = new_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg); if (!new_beg) { @@ -1405,7 +1359,7 @@ } *new_end++ = (*cur)->next; for (cur2 = cur + 1; cur2 < copy_end; ++cur2) { - if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) { + if (*cur2 && fnmatch((*cur2)->str, enc, name, flags) == 0) { *new_end++ = (*cur2)->next; *cur2 = 0; } @@ -1418,7 +1372,8 @@ status = -1; break; } - status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg); + status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, + new_end, flags, func, arg, enc); GLOB_FREE(buf); GLOB_FREE(new_beg); if (status) break; @@ -1432,7 +1387,7 @@ } static int -ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg) +ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc) { struct glob_pattern *list; const char *root, *start; @@ -1454,12 +1409,12 @@ MEMCPY(buf, start, char, n); buf[n] = '\0'; - list = glob_make_pattern(root, flags); + list = glob_make_pattern(root, flags, enc); if (!list) { GLOB_FREE(buf); return -1; } - status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg); + status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg, enc); glob_free_pattern(list); GLOB_FREE(buf); @@ -1469,11 +1424,12 @@ int ruby_glob(const char *path, int flags, ruby_glob_func *func, VALUE arg) { - return ruby_glob0(path, flags & ~GLOB_VERBOSE, func, arg); + return ruby_glob0(path, flags & ~GLOB_VERBOSE, func, arg, + rb_ascii8bit_encoding()); } static int -rb_glob_caller(const char *path, VALUE a) +rb_glob_caller(const char *path, VALUE a, void *enc) { int status; struct glob_args *args = (struct glob_args *)a; @@ -1484,38 +1440,46 @@ } static int -rb_glob2(const char *path, int flags, void (*func)(const char *, VALUE), VALUE arg) +rb_glob2(const char *path, int flags, + void (*func)(const char *, VALUE, void *), VALUE arg, + rb_encoding* enc) { struct glob_args args; args.func = func; args.value = arg; + args.enc = enc; if (flags & FNM_SYSCASE) { rb_warning("Dir.glob() ignores File::FNM_CASEFOLD"); } - return ruby_glob0(path, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args); + return ruby_glob0(path, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args, + enc); } void -rb_glob(const char *path, void (*func)(const char *, VALUE), VALUE arg) +rb_glob(const char *path, void (*func)(const char *, VALUE, void *), VALUE arg) { - int status = rb_glob2(path, 0, func, arg); + int status = rb_glob2(path, 0, func, arg, rb_ascii8bit_encoding()); if (status) GLOB_JUMP_TAG(status); } static void -push_pattern(const char *path, VALUE ary) +push_pattern(const char *path, VALUE ary, void *enc) { - rb_ary_push(ary, rb_tainted_str_new2(path)); + VALUE vpath = rb_tainted_str_new2(path); + rb_enc_associate(vpath, enc); + rb_ary_push(ary, vpath); } -int -ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg) +static int +ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg, + rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); const char *p = str; + const char *pend = p + strlen(p); const char *s = p; const char *lbrace = 0, *rbrace = 0; int nest = 0, status = 0; @@ -1531,7 +1495,7 @@ if (*p == '\\' && escape) { if (!*++p) break; } - Inc(p); + Inc(p, pend, enc); } if (lbrace && rbrace) { @@ -1551,17 +1515,17 @@ if (*p == '\\' && escape) { if (++p == rbrace) break; } - Inc(p); + Inc(p, pend, enc); } memcpy(buf+shift, t, p-t); strcpy(buf+shift+(p-t), rbrace+1); - status = ruby_brace_expand(buf, flags, func, arg); + status = ruby_brace_expand(buf, flags, func, arg, enc); if (status) break; } GLOB_FREE(buf); } else if (!lbrace && !rbrace) { - status = (*func)(s, arg); + status = (*func)(s, arg, enc); } return status; @@ -1574,38 +1538,44 @@ }; static int -glob_brace(const char *path, VALUE val) +glob_brace(const char *path, VALUE val, void *enc) { struct brace_args *arg = (struct brace_args *)val; - return ruby_glob0(path, arg->flags, arg->func, arg->value); + return ruby_glob0(path, arg->flags, arg->func, arg->value, enc); } static int -ruby_brace_glob0(const char *str, int flags, ruby_glob_func *func, VALUE arg) +ruby_brace_glob0(const char *str, int flags, ruby_glob_func *func, VALUE arg, + rb_encoding* enc) { struct brace_args args; args.func = func; args.value = arg; args.flags = flags; - return ruby_brace_expand(str, flags, glob_brace, (VALUE)&args); + return ruby_brace_expand(str, flags, glob_brace, (VALUE)&args, enc); } int ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg) { - return ruby_brace_glob0(str, flags & ~GLOB_VERBOSE, func, arg); + return ruby_brace_glob0(str, flags & ~GLOB_VERBOSE, func, arg, + rb_ascii8bit_encoding()); } static int -push_glob(VALUE ary, const char *str, int flags) +push_glob(VALUE ary, VALUE str, int flags) { struct glob_args args; + rb_encoding *enc = rb_enc_get(str); args.func = push_pattern; args.value = ary; - return ruby_brace_glob0(str, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args); + args.enc = enc; + + return ruby_brace_glob0(RSTRING_PTR(str), flags | GLOB_VERBOSE, + rb_glob_caller, (VALUE)&args, enc); } static VALUE @@ -1618,11 +1588,13 @@ ary = rb_ary_new(); while (offset < RSTRING_LEN(str)) { - int status = push_glob(ary, RSTRING_PTR(str) + offset, flags); char *p, *pend; + int status; + p = RSTRING_PTR(str) + offset; + status = push_glob(ary, rb_enc_str_new(p, strlen(p), rb_enc_get(str)), + flags); if (status) GLOB_JUMP_TAG(status); if (offset >= RSTRING_LEN(str)) break; - p = RSTRING_PTR(str) + offset; p += strlen(p) + 1; pend = RSTRING_PTR(str) + RSTRING_LEN(str); while (p < pend && !*p) @@ -1643,7 +1615,7 @@ int status; VALUE str = argv[i]; StringValue(str); - status = push_glob(ary, RSTRING_PTR(str), flags); + status = push_glob(ary, str, flags); if (status) GLOB_JUMP_TAG(status); } @@ -1914,7 +1886,8 @@ StringValue(pattern); FilePathStringValue(path); - if (fnmatch(RSTRING_PTR(pattern), RSTRING_PTR(path), flags) == 0) + if (fnmatch(RSTRING_PTR(pattern), rb_enc_get(pattern), RSTRING_PTR(path), + flags) == 0) return Qtrue; return Qfalse; Index: win32-unicode-test/parse.y =================================================================== --- win32-unicode-test/parse.y (revision 17967) +++ win32-unicode-test/parse.y (revision 17968) @@ -4672,12 +4672,13 @@ static VALUE coverage(const char *f, int n) { - extern VALUE rb_vm_get_coverages(void); - VALUE coverages = rb_vm_get_coverages(); - if (RTEST(coverages)) { + extern VALUE rb_get_coverages(void); + VALUE coverages = rb_get_coverages(); + if (RTEST(coverages) && RBASIC(coverages)->klass == 0) { VALUE fname = rb_str_new2(f); VALUE lines = rb_ary_new2(n); int i; + RBASIC(lines)->klass = 0; for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil; RARRAY(lines)->len = n; rb_hash_aset(coverages, fname, lines); @@ -4718,9 +4719,6 @@ parser_prepare(parser); n = yyparse((void*)parser); - if (ruby_coverage) { - rb_ary_freeze(ruby_coverage); - } ruby_debug_lines = 0; ruby_coverage = 0; compile_for_eval = 0; Index: win32-unicode-test/ext/coverage/coverage.c =================================================================== --- win32-unicode-test/ext/coverage/coverage.c (revision 17967) +++ win32-unicode-test/ext/coverage/coverage.c (revision 17968) @@ -10,15 +10,67 @@ #include "ruby.h" -extern void rb_enable_coverages(void); +static VALUE rb_mCoverage; +extern VALUE rb_get_coverages(void); +extern void rb_set_coverages(VALUE); +extern void rb_reset_coverages(void); + +/* + * call-seq: + * Coverage.start => nil + * + * Enables coverage measurement. + */ +static VALUE +rb_coverage_start(VALUE klass) +{ + if (!RTEST(rb_get_coverages())) { + VALUE coverages = rb_hash_new(); + RBASIC(coverages)->klass = 0; + rb_set_coverages(coverages); + } +} + +static int +coverage_result_i(st_data_t key, st_data_t val, st_data_t dummy) +{ + VALUE coverage = (VALUE)val; + RBASIC(coverage)->klass = rb_cArray; + rb_ary_freeze(coverage); + return ST_CONTINUE; +} + +/* + * call-seq: + * Coverage.result => hash + * + * Returns a hash that contains filename as key and coverage array as value + * and disables coverage measurement. + */ +static VALUE +rb_coverage_result(VALUE klass) +{ + VALUE coverages = rb_get_coverages(); + if (!RTEST(coverages)) { + rb_raise(rb_eRuntimeError, "coverage measurement is not enabled"); + } + RBASIC(coverages)->klass = rb_cHash; + st_foreach(RHASH_TBL(coverages), coverage_result_i, 0); + rb_hash_freeze(coverages); + rb_reset_coverages(); + return coverages; +} + /* Coverage provides coverage measurement feature for Ruby. + * This feature is experimental, so these APIs may be changed in future. * * = Usage * * (1) require "coverage.so" - * (2) require or load Ruby source file - * (3) Coverage.result will return a hash that contains filename as key and + * (2) do Coverage.start + * (3) require or load Ruby source file + * (4) Coverage.result will return a hash that contains filename as key and * coverage array as value. * * = Example @@ -37,11 +89,14 @@ * [EOF] * * require "coverage.so" + * Coverage.start * require "foo.rb" - * p COVERAGE__ #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} + * p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} */ void Init_coverage(void) { - rb_enable_coverages(); + rb_mCoverage = rb_define_module("Coverage"); + rb_define_module_function(rb_mCoverage, "start", rb_coverage_start, 0); + rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, 0); } Index: win32-unicode-test/ext/win32ole/win32ole.c =================================================================== --- win32-unicode-test/ext/win32ole/win32ole.c (revision 17967) +++ win32-unicode-test/ext/win32ole/win32ole.c (revision 17968) @@ -118,7 +118,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "1.2.1" +#define WIN32OLE_VERSION "1.2.3" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -501,6 +501,8 @@ static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default); static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams); 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 void ole_event_free(struct oleeventdata *poleev); static VALUE fev_s_allocate(VALUE klass); @@ -7597,7 +7599,118 @@ 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; @@ -7606,10 +7719,9 @@ IDispatch *pDispatch; ITypeInfo *pTypeInfo; + ITypeInfo *pTypeInfo2 = NULL; TYPEATTR *pTypeAttr; - int i; - int iFlags; - HREFTYPE hRefType; + TYPEATTR *pTypeAttr2 = NULL; struct oledata *pole; @@ -7649,33 +7761,19 @@ OLE_RELEASE(pTypeInfo); return hr; } - /* Enumerate all implemented types of the COCLASS */ - for (i = 0; i < pTypeAttr->cImplTypes; i++) { - hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &iFlags); - if (FAILED(hr)) - continue; - /* - looking for the [default] [source] - we just hope that it is a dispinterface :-) - */ - if ((iFlags & IMPLTYPEFLAG_FDEFAULT) && - (iFlags & IMPLTYPEFLAG_FSOURCE)) { - - hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, - i, &hRefType); - if (FAILED(hr)) - continue; - hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, - hRefType, ppTypeInfo); - if (SUCCEEDED(hr)) - break; - } + *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)) @@ -7724,7 +7822,7 @@ char *pitf; HRESULT hr; IID iid; - ITypeInfo *pTypeInfo; + ITypeInfo *pTypeInfo = 0; IDispatch *pDispatch; IConnectionPointContainer *pContainer; IConnectionPoint *pConnectionPoint; Index: win32-unicode-test/ext/nkf/nkf-utf8/nkf.c =================================================================== --- win32-unicode-test/ext/nkf/nkf-utf8/nkf.c (revision 17967) +++ win32-unicode-test/ext/nkf/nkf-utf8/nkf.c (revision 17968) @@ -6086,8 +6086,8 @@ input_endian = ENDIAN_BIG; } enc_idx = enc_idx == UTF_16 - ? (output_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE) - : (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE); + ? (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; Index: win32-unicode-test/vm.c =================================================================== --- win32-unicode-test/vm.c (revision 17967) +++ win32-unicode-test/vm.c (revision 17968) @@ -1396,7 +1396,7 @@ RUBY_MARK_UNLESS_NULL(vm->loaded_features); RUBY_MARK_UNLESS_NULL(vm->top_self); RUBY_MARK_UNLESS_NULL(vm->coverages); - rb_gc_mark_locations(vm->special_exceptions, vm->special_exceptions + ruby_special_error_count - 1); + rb_gc_mark_locations(vm->special_exceptions, vm->special_exceptions + ruby_special_error_count); if (vm->loading_table) { rb_mark_tbl(vm->loading_table); @@ -1909,9 +1909,3 @@ { return ruby_vm_debug_ptr(GET_VM()); } - -VALUE -rb_vm_get_coverages(void) -{ - return GET_VM()->coverages; -} Index: win32-unicode-test/test/ruby/test_string.rb =================================================================== --- win32-unicode-test/test/ruby/test_string.rb (revision 17967) +++ win32-unicode-test/test/ruby/test_string.rb (revision 17968) @@ -1221,7 +1221,9 @@ assert_equal(S("124"), S("123").succ) assert_equal(S("1000"), S("999").succ) + assert_equal(S("2.000"), S("1.999").succ) + assert_equal(S("No.10"), S("No.9").succ) assert_equal(S("2000aaa"), S("1999zzz").succ) assert_equal(S("AAAAA000"), S("ZZZZ999").succ) assert_equal(S("*+"), S("**").succ) @@ -1269,6 +1271,10 @@ assert_equal(S("*+"), a.succ!) assert_equal(S("*+"), a) + a = S("No.9") + assert_equal(S("No.10"), a.succ!) + assert_equal(S("No.10"), a) + assert_equal("aaaaaaaaaaaa", "zzzzzzzzzzz".succ!) assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzzzzzzzzzzzzzzzzzzz".succ!) end Index: win32-unicode-test/test/win32ole/test_win32ole_event.rb =================================================================== --- win32-unicode-test/test/win32ole/test_win32ole_event.rb (revision 17967) +++ win32-unicode-test/test/win32ole/test_win32ole_event.rb (revision 17968) @@ -30,6 +30,20 @@ @event += event end + def test_s_new_without_itf + ev = WIN32OLE_EVENT.new(@ie) + ev.on_event {|*args| default_handler(*args)} + @ie.navigate("file:///#{@f}") + while @ie.busy + WIN32OLE_EVENT.new(@ie) + GC.start + WIN32OLE_EVENT.message_loop + sleep 0.1 + end + assert_match(/BeforeNavigate/, @event) + assert_match(/NavigateComplete/, @event) + end + def test_on_event ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents') ev.on_event {|*args| default_handler(*args)} @@ -111,6 +125,16 @@ } end + def test_non_exist_event + assert_raise(RuntimeError) { + ev = WIN32OLE_EVENT.new(@ie, 'XXXX') + } + dict = WIN32OLE.new('Scripting.Dictionary') + assert_raise(RuntimeError) { + ev = WIN32OLE_EVENT.new(dict) + } + end + def handler1 @event2 = "handler1" end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/