From: nobu.nakada@... Date: 2002-02-01T02:14:07+09:00 Subject: [ruby-dev:15828] Re: [PATCH] improve on \G なかだです。 At Wed, 30 Jan 2002 14:48:34 +0900, K.Kosako wrote: > + case MBCTYPE_SJIS: > + while (i + (w = mbclen(string[i])) < pos) { > + i += w; > + } > + return i; > + どうもSJISのときに行ったり来たりするのが気になるので、こうして みました。要するに、その前が1バイト目でなければ、2バイト目でな いはずということです。 while (i > 0 && istrail(string[i]) && isfirst(string[i-1])) { --i; } 1バイト目の範囲は2バイト目の範囲に含まれることを利用して変形し てますが。 # なんかテーブル追加した意味がない。 Index: regex.c =================================================================== RCS file: /cvs/ruby/src/ruby/regex.c,v retrieving revision 1.60 diff -u -2 -p -r1.60 regex.c --- regex.c 2002/01/30 07:00:58 1.60 +++ regex.c 2002/01/31 17:04:44 @@ -479,5 +479,13 @@ re_set_syntax(syntax) ((current_mbctype != MBCTYPE_UTF8) ? ((c<0x100) ? (c) : (((c)>>8)&0xff)) : utf8_firstbyte(c)) -int mbc_startpos _((const char *start, int pos)); +static int asc_startpos _((const char *string, int pos)); +static int euc_startpos _((const char *string, int pos)); +static int sjis_startpos _((const char *string, int pos)); +static int utf8_startpos _((const char *string, int pos)); +int (*const mbc_startpos_func[4]) _((const char *string, int pos)) = { + asc_startpos, euc_startpos, sjis_startpos, utf8_startpos +}; + +#define mbc_startpos(start, pos) (*mbc_startpos_func[current_mbctype])((start), (pos)) static unsigned int @@ -4562,32 +4570,79 @@ re_mbcinit(mbctype) } -int -mbc_startpos(string, pos) +#define mbc_isfirst(t, c) (t)[(unsigned char)(c)] +#define mbc_istrail(t, c) (t)[(unsigned char)(c)+256] +#define mbc_len(t, c) ((t)[(unsigned char)(c)]+1) + +static int +asc_startpos(string, pos) const char *string; int pos; { + return pos; +} + +#define euc_islead(c) ((unsigned char)((c) - 0xa1) > 0xfe - 0xa1) +#define euc_mbclen(c) mbc_len(mbctab_euc, (c)) + +static int +euc_startpos(string, pos) + const char *string; + int pos; +{ int i = pos, w; - while (i > 0 && re_mbctab[(unsigned char)string[i]+256]) { + while (i > 0 && !euc_islead(string[i])) { --i; + } + if (i == pos || i + (w = euc_mbclen(string[i])) > pos) { + return i; } - if (i == pos || i + (w = mbclen(string[i])) > pos) return i; i += w; + return i + ((pos - i) & ~1); +} - switch (current_mbctype) { - case MBCTYPE_EUC: - return i + ((pos - i) & ~1); +#define sjis_isfirst(c) mbc_isfirst(mbctab_sjis, (c)) +#define sjis_istrail(c) mbc_istrail(mbctab_sjis, (c)) +#define sjis_mbclen(c) mbc_len(mbctab_sjis, (c)) - case MBCTYPE_SJIS: - while (i + (w = mbclen(string[i])) < pos) { - i += w; - } +static int +sjis_startpos(string, pos) + const char *string; + int pos; +{ + int i = pos, w; + + if (i > 0 && sjis_istrail(string[i])) { + do { + if (!sjis_isfirst(string[--i])) { + ++i; + break; + } + } while (i > 0); + } + if (i == pos || i + (w = sjis_mbclen(string[i])) > pos) { return i; + } + i += w; + return i + ((pos - i) & ~1); +} - case MBCTYPE_UTF8: +#define utf8_islead(c) ((unsigned char)((c) & 0xc0) != 0x80) +#define utf8_mbclen(c) mbc_len(mbctab_utf8, (c)) + +static int +utf8_startpos(string, pos) + const char *string; + int pos; +{ + int i = pos, w; + + while (i > 0 && !utf8_islead(string[i])) { + --i; + } + if (i == pos || i + (w = utf8_mbclen(string[i])) > pos) { return i; - default: - return pos; } + return i + w; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦