Skip to content

Commit

Permalink
0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
junegunn committed Apr 20, 2011
1 parent c9d2b2c commit 3250d04
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
@@ -0,0 +1,7 @@
=== 0.1.1 / 2011/04/20
* Fixed bugs in handling multibyte characters
* 1.8.7 backward compatiblitiy

=== 0.1.0 / 2011/04/12
* Initial release

28 changes: 20 additions & 8 deletions ext/tre/tre.c
@@ -1,4 +1,5 @@
#include "ruby.h"
#include "ruby/version.h"
#include "tre/tre.h"

VALUE mTRE;
Expand Down Expand Up @@ -81,6 +82,14 @@ tre_compile_regex(regex_t* preg, VALUE pattern, VALUE ignore_case, VALUE multi_l
}
}

#if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
#define CHAR_LENGTH(string) RSTRING_LEN(string)
#define BYTE_TO_CHAR(string, bo) bo
#else
#define CHAR_LENGTH(string) NUM2LONG( rb_str_length(string) )
#define BYTE_TO_CHAR(string, bo) rb_str_sublen(string, bo)
#endif

static VALUE
tre_traverse(VALUE pattern, VALUE string, long char_offset, VALUE params,
VALUE ignore_case, VALUE multi_line, int num_captures, VALUE repeat) {
Expand All @@ -107,31 +116,34 @@ tre_traverse(VALUE pattern, VALUE string, long char_offset, VALUE params,

while (1) {
// Get substring to start with
long len = RSTRING_LEN(string) - char_offset;
if (char_offset >= len) break;
string = rb_str_substr(string, char_offset, len);
long char_len = CHAR_LENGTH(string) - char_offset;
if (char_len <= 0) break;
string = rb_str_substr(string, char_offset, char_len);

int result = tre_reganexec(&preg, StringValuePtr(string), len, &match, aparams, 0);
int result = tre_reganexec(&preg, StringValuePtr(string),
RSTRING_LEN(string), &match, aparams, 0);

if (result == REG_NOMATCH) break;

// Fill in array with ranges
VALUE subarr;
if (match.nmatch == 1)
subarr = arr; // Fake
subarr = arr; // Faking.. kind of.
else {
subarr = rb_ary_new();
// rb_global_variable(&subarr);
}

unsigned int i;
for (i = 0; i < match.nmatch; ++i)
// No match
if (match.pmatch[i].rm_so == -1)
rb_ary_push(subarr, Qnil);
// Match => Range
else {
VALUE range = rb_range_new(
LONG2NUM( char_offset_acc + rb_str_sublen(string, match.pmatch[i].rm_so) ),
LONG2NUM( char_offset_acc + rb_str_sublen(string, match.pmatch[i].rm_eo) ),
LONG2NUM( char_offset_acc + BYTE_TO_CHAR(string, match.pmatch[i].rm_so) ),
LONG2NUM( char_offset_acc + BYTE_TO_CHAR(string, match.pmatch[i].rm_eo) ),
1);
// rb_global_variable(&range);

Expand All @@ -143,7 +155,7 @@ tre_traverse(VALUE pattern, VALUE string, long char_offset, VALUE params,
if (repeat == Qfalse)
break;
else {
char_offset = rb_str_sublen(string, match.pmatch[0].rm_eo);
char_offset = BYTE_TO_CHAR(string, match.pmatch[0].rm_eo);
if (char_offset == 0) char_offset = 1; // Weird case
char_offset_acc += char_offset;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/tre-ruby.rb
Expand Up @@ -160,7 +160,8 @@ def parse_pattern pattern
opts &= ~Regexp::MULTILINE
ret[:ignore_case] = (opts & Regexp::IGNORECASE) > 0
opts &= ~Regexp::IGNORECASE
opts &= ~Regexp::FIXEDENCODING # FIXME
opts &= ~Regexp::FIXEDENCODING if
Regexp.constants.map { |c| c.to_s }.include? "FIXEDENCODING"
raise ArgumentError.new("Unsupported Regexp flag provided") if opts > 0

# Pessimistic estimation of the number of captures
Expand Down
48 changes: 47 additions & 1 deletion test/test_tre-ruby.rb
Expand Up @@ -76,7 +76,7 @@ def test_aindex_regex
assert_equal nil, TWISTER.aindex(/toult/i, 0, params)

# Frozen: cannot modify
assert_raise(RuntimeError) { params.max_err = 2 }
assert_raise(RUBY_VERSION =~ /^1.8/ ? TypeError : RuntimeError) { params.max_err = 2 }

# Warm AParams
params = TRE::AParams.new
Expand Down Expand Up @@ -176,6 +176,52 @@ def test_agsub!
assert_not_equal copy, TWISTER
end

def test_multibyte
$KCODE = 'u' if RUBY_VERSION =~ /^1.8/
lyric = "
사랑을 한다는 말은 못했어
어쨌거나 지금은 너무 늦어버렸어
그때 나는 무얼 하고 있었나
그 미소는 너무 아름다웠어
난 정말 그대 그대만을 좋아헀어
나에게 이런 슬픔 안겨 주는 그대여
제발 이별만은 말 하지 말아요
나에겐 오직 그대만이 전부였잖아
오 그대여 가지 마세요
나를 정말 떠나 가나요
오 그대여 가지 마세요
나는 지금 울잖아요
난 알아요
이 밤이 흐르면 YO!
그대 떠나는 모습 뒤로 하고
마지막 키스에 슬픈 마음
정말 떠나는가
사랑을 하고 싶어 너의 모든 향기
내 몸 속에 젖어 있는 너의 많은 숨결
그 미소 그 눈물 그 알 수 없는 마음 그대 마음
그리고 또 마음 그대 마음
그 어렵다는 편지는 쓰지 않아도 돼
너의 진실한 모습을 바라보고 있어요
아직도 마음속엔 내가 있나요
나는 그대의 영원한
난 정말 그대 그대만을 좋아했어
나에게 이런 슬픔 안겨주는 그대여
오 그대여 가지 마세요
나를 정말 떠나 가나요
오 그대여 가지 마세요
나는 지금 울잖아요
오 그대여 가지 마세요
나를 정말 떠나 가나요
오 그대여 가지 마세요
나는 지금 울잖아요"
srch = "오 그대여 가지 마세요"
assert_equal 6,
lyric.extend(TRE).ascan_r(/#{srch}/i, TRE.fuzziness(0)).length
assert_equal 6,
lyric.extend(TRE).ascan(/#{srch}/i, TRE.fuzziness(0)).length
assert lyric.extend(TRE).ascan(/#{srch}/i, TRE.fuzziness(0)).all? { |e| e == srch }
end

TWISTER = TREString.new <<-EOF
She sells sea shells by the sea shore.
The shells she sells are surely seashells.
Expand Down

0 comments on commit 3250d04

Please sign in to comment.