OSDN Git Service

FIRST REPOSITORY
[eos/hostdependOTHERS.git] / I386LINUX / util / I386LINUX / lib / ruby / 1.6 / jcode.rb
1 # jcode.rb - ruby code to handle japanese (EUC/SJIS) string
2
3 if $VERBOSE && $KCODE == "NONE"
4   STDERR.puts "Warning: $KCODE is NONE."
5 end
6
7 $vsave, $VERBOSE = $VERBOSE, false
8 class String
9   printf STDERR, "feel free for some warnings:\n" if $VERBOSE
10
11   def _regex_quote(str)
12     str.gsub(/[][.\\|*?+{}()]/){|s|
13       if s == "\\" then "\\\\" else "\\\\#{s}" end
14     }
15   end
16   private :_regex_quote
17
18   PATTERN_SJIS = '[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]'
19   PATTERN_EUC = '[\xa1-\xfe][\xa1-\xfe]'
20   PATTERN_UTF8 = '[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]'
21
22   RE_SJIS = Regexp.new(PATTERN_SJIS, 'n')
23   RE_EUC = Regexp.new(PATTERN_EUC, 'n')
24   RE_UTF8 = Regexp.new(PATTERN_UTF8, 'n')
25
26   SUCC = {}
27   SUCC['s'] = Hash.new(1)
28   for i in 0 .. 0x3f
29     SUCC['s'][i.chr] = 0x40 - i
30   end
31   SUCC['s']["\x7e"] = 0x80 - 0x7e
32   SUCC['s']["\xfd"] = 0x100 - 0xfd
33   SUCC['s']["\xfe"] = 0x100 - 0xfe
34   SUCC['s']["\xff"] = 0x100 - 0xff
35   SUCC['e'] = Hash.new(1)
36   for i in 0 .. 0xa0
37     SUCC['e'][i.chr] = 0xa1 - i
38   end
39   SUCC['e']["\xfe"] = 2
40   SUCC['u'] = Hash.new(1)
41   for i in 0 .. 0x7f
42     SUCC['u'][i.chr] = 0x80 - i
43   end
44   SUCC['u']["\xbf"] = 0x100 - 0xbf
45
46   def mbchar?
47     case $KCODE[0]
48     when ?s, ?S
49       self =~ RE_SJIS
50     when ?e, ?E
51       self =~ RE_EUC
52     when ?u, ?U
53       self =~ RE_UTF8
54     else
55       nil
56     end
57   end
58
59   def end_regexp
60     case $KCODE[0]
61     when ?s, ?S
62       /#{PATTERN_SJIS}$/o
63     when ?e, ?E
64       /#{PATTERN_EUC}$/o
65     when ?u, ?U
66       /#{PATTERN_UTF8}$/o
67     else
68       /.$/o
69     end
70   end
71
72   alias original_succ! succ!
73   private :original_succ!
74
75   alias original_succ succ
76   private :original_succ
77
78   def succ!
79     reg = end_regexp
80     if self =~ reg
81       succ_table = SUCC[$KCODE[0,1].downcase]
82       begin
83         self[-1] += succ_table[self[-1]]
84         self[-2] += 1 if self[-1] == 0
85       end while self !~ reg
86       self
87     else
88       original_succ!
89     end
90   end
91
92   def succ
93     (str = self.dup).succ! or str
94   end
95
96   private
97
98   def _expand_ch str
99     a = []
100     str.scan(/(.)-(.)|(.)/m) do |r|
101       if $3
102         a.push $3
103       elsif $1.length != $2.length
104         next
105       elsif $1.length == 1
106         $1[0].upto($2[0]) { |c| a.push c.chr }
107       else
108         $1.upto($2) { |c| a.push c }
109       end
110     end
111     a
112   end
113
114   def expand_ch_hash from, to
115     h = {}
116     afrom = _expand_ch(from)
117     ato = _expand_ch(to)
118     afrom.each_with_index do |x,i| h[x] = ato[i] || ato[-1] end
119     h
120   end
121
122   HashCache = {}
123   TrPatternCache = {}
124   DeletePatternCache = {}
125   SqueezePatternCache = {}
126
127   public
128
129   def tr!(from, to)
130     return self.delete!(from) if to.length == 0
131
132     pattern = TrPatternCache[from] ||= /[#{_regex_quote(from)}]/
133     if from[0] == ?^
134       last = /.$/.match(to)[0]
135       self.gsub!(pattern, last)
136     else
137       h = HashCache[from + "::" + to] ||= expand_ch_hash(from, to)
138       self.gsub!(pattern) do |c| h[c] end
139     end
140   end
141
142   def tr(from, to)
143     (str = self.dup).tr!(from, to) or str
144   end
145
146   def delete!(del)
147     self.gsub!(DeletePatternCache[del] ||= /[#{_regex_quote(del)}]+/, '')
148   end
149
150   def delete(del)
151     (str = self.dup).delete!(del) or str
152   end
153
154   def squeeze!(del=nil)
155     pattern =
156       if del
157         SqueezePatternCache[del] ||= /([#{_regex_quote(del)}])\1+/
158       else
159         /(.|\n)\1+/
160       end
161     self.gsub!(pattern, '\1')
162   end
163
164   def squeeze(del=nil)
165     (str = self.dup).squeeze!(del) or str
166   end
167
168   def tr_s!(from, to)
169     return self.delete!(from) if to.length == 0
170
171     pattern = SqueezePatternCache[from] ||= /([#{_regex_quote(from)}])\1+"/
172     if from[0] == ?^
173       last = /.$/.match(to)[0]
174       self.gsub!(pattern, last)
175     else
176       h = HashCache[from + "::" + to] ||= expand_ch_hash(from, to)
177       self.gsub!(pattern) do h[$1] end
178     end
179   end
180
181   def tr_s(from, to)
182     (str = self.dup).tr_s!(from,to) or str
183   end
184
185   def chop!
186     self.gsub!(/(?:.|\r?\n)\z/, '')
187   end
188
189   def chop
190     (str = self.dup).chop! or str
191   end
192
193   def jlength
194     self.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
195   end
196   alias jsize jlength
197
198   def jcount(str)
199     self.delete("^#{str}").jlength
200   end
201
202   def each_char
203     if block_given?
204       scan(/./m) do |x|
205         yield x
206       end
207     else
208       scan(/./m)
209     end
210   end
211
212 end
213 $VERBOSE = $vsave