fast_gettext 0.4.16
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +6 -0
- data/README.markdown +181 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/benchmark/base.rb +42 -0
- data/benchmark/baseline.rb +5 -0
- data/benchmark/fast_gettext.rb +18 -0
- data/benchmark/i18n_simple.rb +7 -0
- data/benchmark/ideal.rb +22 -0
- data/benchmark/locale/de.yml +127 -0
- data/benchmark/locale/de/LC_MESSAGES/large.mo +0 -0
- data/benchmark/misc/threadsave.rb +21 -0
- data/benchmark/namespace/fast_gettext.rb +15 -0
- data/benchmark/namespace/original.rb +14 -0
- data/benchmark/original.rb +15 -0
- data/examples/db/migration.rb +22 -0
- data/examples/missing_translation_logger.rb +13 -0
- data/fast_gettext.gemspec +114 -0
- data/lib/fast_gettext.rb +30 -0
- data/lib/fast_gettext/mo_file.rb +67 -0
- data/lib/fast_gettext/po_file.rb +14 -0
- data/lib/fast_gettext/storage.rb +188 -0
- data/lib/fast_gettext/translation.rb +53 -0
- data/lib/fast_gettext/translation_repository.rb +15 -0
- data/lib/fast_gettext/translation_repository/base.rb +49 -0
- data/lib/fast_gettext/translation_repository/chain.rb +43 -0
- data/lib/fast_gettext/translation_repository/db.rb +57 -0
- data/lib/fast_gettext/translation_repository/db_models/translation_key.rb +26 -0
- data/lib/fast_gettext/translation_repository/db_models/translation_text.rb +9 -0
- data/lib/fast_gettext/translation_repository/logger.rb +27 -0
- data/lib/fast_gettext/translation_repository/mo.rb +35 -0
- data/lib/fast_gettext/translation_repository/po.rb +18 -0
- data/spec/aa_unconfigued_spec.rb +21 -0
- data/spec/fast_gettext/mo_file_spec.rb +36 -0
- data/spec/fast_gettext/storage_spec.rb +309 -0
- data/spec/fast_gettext/translation_repository/base_spec.rb +21 -0
- data/spec/fast_gettext/translation_repository/chain_spec.rb +82 -0
- data/spec/fast_gettext/translation_repository/db_spec.rb +71 -0
- data/spec/fast_gettext/translation_repository/logger_spec.rb +41 -0
- data/spec/fast_gettext/translation_repository/mo_spec.rb +31 -0
- data/spec/fast_gettext/translation_repository/po_spec.rb +31 -0
- data/spec/fast_gettext/translation_spec.rb +152 -0
- data/spec/fast_gettext_spec.rb +44 -0
- data/spec/locale/de/LC_MESSAGES/test.mo +0 -0
- data/spec/locale/de/test.po +61 -0
- data/spec/locale/en/LC_MESSAGES/plural_test.mo +0 -0
- data/spec/locale/en/LC_MESSAGES/test.mo +0 -0
- data/spec/locale/en/plural_test.po +20 -0
- data/spec/locale/en/test.po +59 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/vendor/fake_load_path/iconv.rb +2 -0
- data/spec/vendor/iconv_spec.rb +27 -0
- data/spec/vendor/string_spec.rb +67 -0
- data/vendor/README.rdoc +236 -0
- data/vendor/empty.mo +0 -0
- data/vendor/iconv.rb +107 -0
- data/vendor/mofile.rb +296 -0
- data/vendor/poparser.rb +331 -0
- data/vendor/string.rb +58 -0
- metadata +130 -0
data/vendor/empty.mo
ADDED
Binary file
|
data/vendor/iconv.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
=begin
|
2
|
+
iconv.rb - Pseudo Iconv class. Supports Iconv.iconv, Iconv.conv.
|
3
|
+
|
4
|
+
For Matz Ruby:
|
5
|
+
If you don't have iconv but glib2, this library uses glib2 iconv functions.
|
6
|
+
|
7
|
+
For JRuby:
|
8
|
+
Use Java String class to convert strings.
|
9
|
+
|
10
|
+
Copyright (C) 2004-2007 Masao Mutoh
|
11
|
+
|
12
|
+
You may redistribute it and/or modify it under the same
|
13
|
+
license terms as Ruby.
|
14
|
+
|
15
|
+
$Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $
|
16
|
+
=end
|
17
|
+
|
18
|
+
#Modifications
|
19
|
+
#wrapped inside FastGettext namespace to reduce conflic
|
20
|
+
|
21
|
+
begin
|
22
|
+
require 'iconv'
|
23
|
+
rescue LoadError
|
24
|
+
# Provides Iconv.iconv which normally is provided through Ruby/GLib(1) functions.
|
25
|
+
# This library is required for 'gettext'.
|
26
|
+
# If you require 'gettext/iconv', it tries to call Ruby/GLib function
|
27
|
+
# when it doesn't find original Iconv class(iconv.so) it adds a pseudo class.
|
28
|
+
#
|
29
|
+
# One-click Ruby Installer for Win32 hadn’t had iconv and there hadn’t been a way to install iconv.so itself for Win32.
|
30
|
+
# And JRuby hadn’t had Iconv.
|
31
|
+
# I’ve not checked them currently, but if they’ve supported iconv now, we don’t need this anymore...
|
32
|
+
#
|
33
|
+
# (1) Ruby/GLib is a module which is provided from Ruby-GNOME2 Project.
|
34
|
+
# You can get binaries for Win32(One-Click Ruby Installer).
|
35
|
+
# <URL: http://ruby-gnome2.sourceforge.jp/>
|
36
|
+
module FastGettext
|
37
|
+
class Iconv2
|
38
|
+
module Failure; end
|
39
|
+
class InvalidEncoding < ArgumentError; include Failure; end
|
40
|
+
class IllegalSequence < ArgumentError; include Failure; end
|
41
|
+
class InvalidCharacter < ArgumentError; include Failure; end
|
42
|
+
|
43
|
+
if RUBY_PLATFORM =~ /java/
|
44
|
+
def self.conv(to, from, str)
|
45
|
+
raise InvalidCharacter, "the 3rd argument is nil" unless str
|
46
|
+
begin
|
47
|
+
str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
|
48
|
+
str.getBytes(to).to_ary.pack("C*")
|
49
|
+
rescue java.io.UnsupportedEncodingException
|
50
|
+
raise InvalidEncoding
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
begin
|
55
|
+
require 'glib2'
|
56
|
+
|
57
|
+
def self.check_glib_version?(major, minor, micro) # :nodoc:
|
58
|
+
(GLib::BINDING_VERSION[0] > major ||
|
59
|
+
(GLib::BINDING_VERSION[0] == major &&
|
60
|
+
GLib::BINDING_VERSION[1] > minor) ||
|
61
|
+
(GLib::BINDING_VERSION[0] == major &&
|
62
|
+
GLib::BINDING_VERSION[1] == minor &&
|
63
|
+
GLib::BINDING_VERSION[2] >= micro))
|
64
|
+
end
|
65
|
+
|
66
|
+
if check_glib_version?(0, 11, 0)
|
67
|
+
# This is a function equivalent of Iconv.iconv.
|
68
|
+
# * to: encoding name for destination
|
69
|
+
# * from: encoding name for source
|
70
|
+
# * str: strings to be converted
|
71
|
+
# * Returns: Returns an Array of converted strings.
|
72
|
+
def self.conv(to, from, str)
|
73
|
+
begin
|
74
|
+
GLib.convert(str, to, from)
|
75
|
+
rescue GLib::ConvertError => e
|
76
|
+
case e.code
|
77
|
+
when GLib::ConvertError::NO_CONVERSION
|
78
|
+
raise InvalidEncoding.new(str)
|
79
|
+
when GLib::ConvertError::ILLEGAL_SEQUENCE
|
80
|
+
raise IllegalSequence.new(str)
|
81
|
+
else
|
82
|
+
raise InvalidCharacter.new(str)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
def self.conv(to, from, str) # :nodoc:
|
88
|
+
begin
|
89
|
+
GLib.convert(str, to, from)
|
90
|
+
rescue
|
91
|
+
raise IllegalSequence.new(str)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
rescue LoadError
|
96
|
+
def self.conv(to, from, str) # :nodoc:
|
97
|
+
warn "Iconv was not found." if $DEBUG
|
98
|
+
str
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
def self.iconv(to, from, str)
|
103
|
+
conv(to, from, str).split(//)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/vendor/mofile.rb
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
=begin
|
2
|
+
mofile.rb - A simple class for operating GNU MO file.
|
3
|
+
|
4
|
+
Copyright (C) 2003-2008 Masao Mutoh
|
5
|
+
Copyright (C) 2002 Masahiro Sakai, Masao Mutoh
|
6
|
+
Copyright (C) 2001 Masahiro Sakai
|
7
|
+
|
8
|
+
Masahiro Sakai <s01397ms at sfc.keio.ac.jp>
|
9
|
+
Masao Mutoh <mutoh at highway.ne.jp>
|
10
|
+
|
11
|
+
You can redistribute this file and/or modify it under the same term
|
12
|
+
of Ruby. License of Ruby is included with Ruby distribution in
|
13
|
+
the file "README".
|
14
|
+
|
15
|
+
$Id: mo.rb,v 1.10 2008/06/17 16:40:52 mutoh Exp $
|
16
|
+
=end
|
17
|
+
|
18
|
+
require 'iconv'
|
19
|
+
require 'stringio'
|
20
|
+
|
21
|
+
#Modifications:
|
22
|
+
# use Iconv or FastGettext::Icvon
|
23
|
+
|
24
|
+
module FastGettext
|
25
|
+
module GetText
|
26
|
+
class MOFile < Hash
|
27
|
+
class InvalidFormat < RuntimeError; end;
|
28
|
+
|
29
|
+
attr_reader :filename
|
30
|
+
|
31
|
+
Header = Struct.new(:magic,
|
32
|
+
:revision,
|
33
|
+
:nstrings,
|
34
|
+
:orig_table_offset,
|
35
|
+
:translated_table_offset,
|
36
|
+
:hash_table_size,
|
37
|
+
:hash_table_offset)
|
38
|
+
|
39
|
+
# The following are only used in .mo files
|
40
|
+
# with minor revision >= 1.
|
41
|
+
class HeaderRev1 < Header
|
42
|
+
attr_accessor :n_sysdep_segments,
|
43
|
+
:sysdep_segments_offset,
|
44
|
+
:n_sysdep_strings,
|
45
|
+
:orig_sysdep_tab_offset,
|
46
|
+
:trans_sysdep_tab_offset
|
47
|
+
end
|
48
|
+
|
49
|
+
MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
|
50
|
+
MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
|
51
|
+
|
52
|
+
def self.open(arg = nil, output_charset = nil)
|
53
|
+
result = self.new(output_charset)
|
54
|
+
result.load(arg)
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(output_charset = nil)
|
58
|
+
@filename = nil
|
59
|
+
@last_modified = nil
|
60
|
+
@little_endian = true
|
61
|
+
@output_charset = output_charset
|
62
|
+
super()
|
63
|
+
end
|
64
|
+
|
65
|
+
def update!
|
66
|
+
if FileTest.exist?(@filename)
|
67
|
+
st = File.stat(@filename)
|
68
|
+
load(@filename) unless (@last_modified == [st.ctime, st.mtime])
|
69
|
+
else
|
70
|
+
warn "#{@filename} was lost." if $DEBUG
|
71
|
+
clear
|
72
|
+
end
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
def load(arg)
|
77
|
+
if arg.kind_of? String
|
78
|
+
begin
|
79
|
+
st = File.stat(arg)
|
80
|
+
@last_modified = [st.ctime, st.mtime]
|
81
|
+
rescue Exception
|
82
|
+
end
|
83
|
+
load_from_file(arg)
|
84
|
+
else
|
85
|
+
load_from_stream(arg)
|
86
|
+
end
|
87
|
+
@filename = arg
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def load_from_stream(io)
|
92
|
+
magic = io.read(4)
|
93
|
+
case magic
|
94
|
+
when MAGIC_BIG_ENDIAN
|
95
|
+
@little_endian = false
|
96
|
+
when MAGIC_LITTLE_ENDIAN
|
97
|
+
@little_endian = true
|
98
|
+
else
|
99
|
+
raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
|
100
|
+
end
|
101
|
+
|
102
|
+
endian_type6 = @little_endian ? 'V6' : 'N6'
|
103
|
+
endian_type_astr = @little_endian ? 'V*' : 'N*'
|
104
|
+
|
105
|
+
header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
|
106
|
+
|
107
|
+
if header.revision == 1
|
108
|
+
# FIXME: It doesn't support sysdep correctly.
|
109
|
+
header.n_sysdep_segments = io.read(4).unpack(endian_type6)
|
110
|
+
header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
|
111
|
+
header.n_sysdep_strings = io.read(4).unpack(endian_type6)
|
112
|
+
header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
|
113
|
+
header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
|
114
|
+
elsif header.revision > 1
|
115
|
+
raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
|
116
|
+
end
|
117
|
+
io.pos = header.orig_table_offset
|
118
|
+
orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
|
119
|
+
|
120
|
+
io.pos = header.translated_table_offset
|
121
|
+
trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
|
122
|
+
|
123
|
+
original_strings = Array.new(header.nstrings)
|
124
|
+
for i in 0...header.nstrings
|
125
|
+
io.pos = orig_table_data[i * 2 + 1]
|
126
|
+
original_strings[i] = io.read(orig_table_data[i * 2 + 0])
|
127
|
+
end
|
128
|
+
|
129
|
+
clear
|
130
|
+
for i in 0...header.nstrings
|
131
|
+
io.pos = trans_table_data[i * 2 + 1]
|
132
|
+
str = io.read(trans_table_data[i * 2 + 0])
|
133
|
+
|
134
|
+
if (! original_strings[i]) || original_strings[i] == ""
|
135
|
+
if str
|
136
|
+
@charset = nil
|
137
|
+
@nplurals = nil
|
138
|
+
@plural = nil
|
139
|
+
str.each_line{|line|
|
140
|
+
if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
|
141
|
+
@charset = $1
|
142
|
+
elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
|
143
|
+
@nplurals = $1
|
144
|
+
@plural = $2
|
145
|
+
end
|
146
|
+
break if @charset and @nplurals
|
147
|
+
}
|
148
|
+
@nplurals = "1" unless @nplurals
|
149
|
+
@plural = "0" unless @plural
|
150
|
+
end
|
151
|
+
else
|
152
|
+
if @output_charset
|
153
|
+
begin
|
154
|
+
iconv = Iconv || FastGettext::Iconv
|
155
|
+
str = iconv.conv(@output_charset, @charset, str) if @charset
|
156
|
+
rescue iconv::Failure
|
157
|
+
if $DEBUG
|
158
|
+
warn "@charset = ", @charset
|
159
|
+
warn"@output_charset = ", @output_charset
|
160
|
+
warn "msgid = ", original_strings[i]
|
161
|
+
warn "msgstr = ", str
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
self[original_strings[i]] = str.freeze
|
167
|
+
end
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
# Is this number a prime number ?
|
172
|
+
# http://apidock.com/ruby/Prime
|
173
|
+
def prime?(number)
|
174
|
+
('1' * number) !~ /^1?$|^(11+?)\1+$/
|
175
|
+
end
|
176
|
+
|
177
|
+
def next_prime(seed)
|
178
|
+
require 'mathn'
|
179
|
+
prime = Prime.new
|
180
|
+
while current = prime.succ
|
181
|
+
return current if current > seed
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# From gettext-0.12.1/gettext-runtime/intl/hash-string.h
|
186
|
+
# Defines the so called `hashpjw' function by P.J. Weinberger
|
187
|
+
# [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
|
188
|
+
# 1986, 1987 Bell Telephone Laboratories, Inc.]
|
189
|
+
HASHWORDBITS = 32
|
190
|
+
def hash_string(str)
|
191
|
+
hval = 0
|
192
|
+
i = 0
|
193
|
+
str.each_byte do |b|
|
194
|
+
break if b == '\0'
|
195
|
+
hval <<= 4
|
196
|
+
hval += b.to_i
|
197
|
+
g = hval & (0xf << (HASHWORDBITS - 4))
|
198
|
+
if (g != 0)
|
199
|
+
hval ^= g >> (HASHWORDBITS - 8)
|
200
|
+
hval ^= g
|
201
|
+
end
|
202
|
+
end
|
203
|
+
hval
|
204
|
+
end
|
205
|
+
|
206
|
+
def save_to_stream(io)
|
207
|
+
#Save data as little endian format.
|
208
|
+
header_size = 4 * 7
|
209
|
+
table_size = 4 * 2 * size
|
210
|
+
|
211
|
+
hash_table_size = next_prime((size * 4) / 3)
|
212
|
+
hash_table_size = 3 if hash_table_size <= 2
|
213
|
+
header = Header.new(
|
214
|
+
MAGIC_LITTLE_ENDIAN, # magic
|
215
|
+
0, # revision
|
216
|
+
size, # nstrings
|
217
|
+
header_size, # orig_table_offset
|
218
|
+
header_size + table_size, # translated_table_offset
|
219
|
+
hash_table_size, # hash_table_size
|
220
|
+
header_size + table_size * 2 # hash_table_offset
|
221
|
+
)
|
222
|
+
io.write(header.to_a.pack('a4V*'))
|
223
|
+
|
224
|
+
ary = to_a
|
225
|
+
ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
|
226
|
+
|
227
|
+
pos = header.hash_table_size * 4 + header.hash_table_offset
|
228
|
+
|
229
|
+
orig_table_data = Array.new()
|
230
|
+
ary.each{|item, _|
|
231
|
+
orig_table_data.push(item.size)
|
232
|
+
orig_table_data.push(pos)
|
233
|
+
pos += item.size + 1 # +1 is <NUL>
|
234
|
+
}
|
235
|
+
io.write(orig_table_data.pack('V*'))
|
236
|
+
|
237
|
+
trans_table_data = Array.new()
|
238
|
+
ary.each{|_, item|
|
239
|
+
trans_table_data.push(item.size)
|
240
|
+
trans_table_data.push(pos)
|
241
|
+
pos += item.size + 1 # +1 is <NUL>
|
242
|
+
}
|
243
|
+
io.write(trans_table_data.pack('V*'))
|
244
|
+
|
245
|
+
hash_tab = Array.new(hash_table_size)
|
246
|
+
j = 0
|
247
|
+
ary[0...size].each {|key, _|
|
248
|
+
hash_val = hash_string(key)
|
249
|
+
idx = hash_val % hash_table_size
|
250
|
+
if hash_tab[idx] != nil
|
251
|
+
incr = 1 + (hash_val % (hash_table_size - 2))
|
252
|
+
begin
|
253
|
+
if (idx >= hash_table_size - incr)
|
254
|
+
idx -= hash_table_size - incr
|
255
|
+
else
|
256
|
+
idx += incr
|
257
|
+
end
|
258
|
+
end until (hash_tab[idx] == nil)
|
259
|
+
end
|
260
|
+
hash_tab[idx] = j + 1
|
261
|
+
j += 1
|
262
|
+
}
|
263
|
+
hash_tab.collect!{|i| i ? i : 0}
|
264
|
+
|
265
|
+
io.write(hash_tab.pack('V*'))
|
266
|
+
|
267
|
+
ary.each{|item, _| io.write(item); io.write("\0") }
|
268
|
+
ary.each{|_, item| io.write(item); io.write("\0") }
|
269
|
+
|
270
|
+
self
|
271
|
+
end
|
272
|
+
|
273
|
+
def load_from_file(filename)
|
274
|
+
@filename = filename
|
275
|
+
begin
|
276
|
+
File.open(filename, 'rb'){|f| load_from_stream(f)}
|
277
|
+
rescue => e
|
278
|
+
e.set_backtrace("File: #{@filename}")
|
279
|
+
raise e
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def save_to_file(filename)
|
284
|
+
File.open(filename, 'wb'){|f| save_to_stream(f)}
|
285
|
+
end
|
286
|
+
|
287
|
+
def set_comment(msgid_or_sym, comment)
|
288
|
+
#Do nothing
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
attr_accessor :little_endian, :path, :last_modified
|
293
|
+
attr_reader :charset, :nplurals, :plural
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
data/vendor/poparser.rb
ADDED
@@ -0,0 +1,331 @@
|
|
1
|
+
=begin
|
2
|
+
poparser.rb - Generate a .mo
|
3
|
+
|
4
|
+
Copyright (C) 2003-2009 Masao Mutoh <mutoh at highway.ne.jp>
|
5
|
+
|
6
|
+
You may redistribute it and/or modify it under the same
|
7
|
+
license terms as Ruby.
|
8
|
+
=end
|
9
|
+
|
10
|
+
#MODIFIED
|
11
|
+
# removed include GetText etc
|
12
|
+
# added stub translation method _(x)
|
13
|
+
require 'racc/parser'
|
14
|
+
|
15
|
+
module FastGettext
|
16
|
+
module GetText
|
17
|
+
|
18
|
+
class PoParser < Racc::Parser
|
19
|
+
|
20
|
+
def _(x)
|
21
|
+
x
|
22
|
+
end
|
23
|
+
|
24
|
+
module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108
|
25
|
+
def unescape(orig)
|
26
|
+
ret = orig.gsub(/\\n/, "\n")
|
27
|
+
ret.gsub!(/\\t/, "\t")
|
28
|
+
ret.gsub!(/\\r/, "\r")
|
29
|
+
ret.gsub!(/\\"/, "\"")
|
30
|
+
ret
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse(str, data, ignore_fuzzy = true)
|
34
|
+
@comments = []
|
35
|
+
@data = data
|
36
|
+
@fuzzy = false
|
37
|
+
@msgctxt = ""
|
38
|
+
$ignore_fuzzy = ignore_fuzzy
|
39
|
+
|
40
|
+
str.strip!
|
41
|
+
@q = []
|
42
|
+
until str.empty? do
|
43
|
+
case str
|
44
|
+
when /\A\s+/
|
45
|
+
str = $'
|
46
|
+
when /\Amsgctxt/
|
47
|
+
@q.push [:MSGCTXT, $&]
|
48
|
+
str = $'
|
49
|
+
when /\Amsgid_plural/
|
50
|
+
@q.push [:MSGID_PLURAL, $&]
|
51
|
+
str = $'
|
52
|
+
when /\Amsgid/
|
53
|
+
@q.push [:MSGID, $&]
|
54
|
+
str = $'
|
55
|
+
when /\Amsgstr/
|
56
|
+
@q.push [:MSGSTR, $&]
|
57
|
+
str = $'
|
58
|
+
when /\A\[(\d+)\]/
|
59
|
+
@q.push [:PLURAL_NUM, $1]
|
60
|
+
str = $'
|
61
|
+
when /\A\#~(.*)/
|
62
|
+
$stderr.print _("Warning: obsolete msgid exists.\n")
|
63
|
+
$stderr.print " #{$&}\n"
|
64
|
+
@q.push [:COMMENT, $&]
|
65
|
+
str = $'
|
66
|
+
when /\A\#(.*)/
|
67
|
+
@q.push [:COMMENT, $&]
|
68
|
+
str = $'
|
69
|
+
when /\A\"(.*)\"/
|
70
|
+
@q.push [:STRING, $1]
|
71
|
+
str = $'
|
72
|
+
else
|
73
|
+
#c = str[0,1]
|
74
|
+
#@q.push [:STRING, c]
|
75
|
+
str = str[1..-1]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@q.push [false, '$end']
|
79
|
+
if $DEBUG
|
80
|
+
@q.each do |a,b|
|
81
|
+
puts "[#{a}, #{b}]"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@yydebug = true if $DEBUG
|
85
|
+
do_parse
|
86
|
+
|
87
|
+
if @comments.size > 0
|
88
|
+
@data.set_comment(:last, @comments.join("\n"))
|
89
|
+
end
|
90
|
+
@data
|
91
|
+
end
|
92
|
+
|
93
|
+
def next_token
|
94
|
+
@q.shift
|
95
|
+
end
|
96
|
+
|
97
|
+
def on_message(msgid, msgstr)
|
98
|
+
if msgstr.size > 0
|
99
|
+
@data[msgid] = msgstr
|
100
|
+
@data.set_comment(msgid, @comments.join("\n"))
|
101
|
+
end
|
102
|
+
@comments.clear
|
103
|
+
@msgctxt = ""
|
104
|
+
end
|
105
|
+
|
106
|
+
def on_comment(comment)
|
107
|
+
@fuzzy = true if (/fuzzy/ =~ comment)
|
108
|
+
@comments << comment
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
..end src/poparser.ry modeval..id7a99570e05
|
113
|
+
|
114
|
+
##### racc 1.4.5 generates ###
|
115
|
+
|
116
|
+
racc_reduce_table = [
|
117
|
+
0, 0, :racc_error,
|
118
|
+
0, 10, :_reduce_none,
|
119
|
+
2, 10, :_reduce_none,
|
120
|
+
2, 10, :_reduce_none,
|
121
|
+
2, 10, :_reduce_none,
|
122
|
+
2, 12, :_reduce_5,
|
123
|
+
1, 13, :_reduce_none,
|
124
|
+
1, 13, :_reduce_none,
|
125
|
+
4, 15, :_reduce_8,
|
126
|
+
5, 16, :_reduce_9,
|
127
|
+
2, 17, :_reduce_10,
|
128
|
+
1, 17, :_reduce_none,
|
129
|
+
3, 18, :_reduce_12,
|
130
|
+
1, 11, :_reduce_13,
|
131
|
+
2, 14, :_reduce_14,
|
132
|
+
1, 14, :_reduce_15 ]
|
133
|
+
|
134
|
+
racc_reduce_n = 16
|
135
|
+
|
136
|
+
racc_shift_n = 26
|
137
|
+
|
138
|
+
racc_action_table = [
|
139
|
+
3, 13, 5, 7, 9, 15, 16, 17, 20, 17,
|
140
|
+
13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ]
|
141
|
+
|
142
|
+
racc_action_check = [
|
143
|
+
1, 16, 1, 1, 1, 12, 12, 12, 18, 18,
|
144
|
+
7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ]
|
145
|
+
|
146
|
+
racc_action_pointer = [
|
147
|
+
nil, 0, nil, 14, nil, nil, nil, 3, nil, 6,
|
148
|
+
nil, nil, 0, nil, 4, 5, -6, nil, 2, 8,
|
149
|
+
8, 11, nil, 11, nil, 12 ]
|
150
|
+
|
151
|
+
racc_action_default = [
|
152
|
+
-1, -16, -2, -16, -3, -13, -4, -16, -6, -16,
|
153
|
+
-7, 26, -16, -15, -5, -16, -16, -14, -16, -8,
|
154
|
+
-16, -9, -11, -16, -10, -12 ]
|
155
|
+
|
156
|
+
racc_goto_table = [
|
157
|
+
12, 22, 14, 4, 24, 6, 2, 8, 18, 19,
|
158
|
+
10, 21, 1, nil, nil, nil, 25 ]
|
159
|
+
|
160
|
+
racc_goto_check = [
|
161
|
+
5, 9, 5, 3, 9, 4, 2, 6, 5, 5,
|
162
|
+
7, 8, 1, nil, nil, nil, 5 ]
|
163
|
+
|
164
|
+
racc_goto_pointer = [
|
165
|
+
nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ]
|
166
|
+
|
167
|
+
racc_goto_default = [
|
168
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ]
|
169
|
+
|
170
|
+
racc_token_table = {
|
171
|
+
false => 0,
|
172
|
+
Object.new => 1,
|
173
|
+
:COMMENT => 2,
|
174
|
+
:MSGID => 3,
|
175
|
+
:MSGCTXT => 4,
|
176
|
+
:MSGID_PLURAL => 5,
|
177
|
+
:MSGSTR => 6,
|
178
|
+
:STRING => 7,
|
179
|
+
:PLURAL_NUM => 8 }
|
180
|
+
|
181
|
+
racc_use_result_var = true
|
182
|
+
|
183
|
+
racc_nt_base = 9
|
184
|
+
|
185
|
+
Racc_arg = [
|
186
|
+
racc_action_table,
|
187
|
+
racc_action_check,
|
188
|
+
racc_action_default,
|
189
|
+
racc_action_pointer,
|
190
|
+
racc_goto_table,
|
191
|
+
racc_goto_check,
|
192
|
+
racc_goto_default,
|
193
|
+
racc_goto_pointer,
|
194
|
+
racc_nt_base,
|
195
|
+
racc_reduce_table,
|
196
|
+
racc_token_table,
|
197
|
+
racc_shift_n,
|
198
|
+
racc_reduce_n,
|
199
|
+
racc_use_result_var ]
|
200
|
+
|
201
|
+
Racc_token_to_s_table = [
|
202
|
+
'$end',
|
203
|
+
'error',
|
204
|
+
'COMMENT',
|
205
|
+
'MSGID',
|
206
|
+
'MSGCTXT',
|
207
|
+
'MSGID_PLURAL',
|
208
|
+
'MSGSTR',
|
209
|
+
'STRING',
|
210
|
+
'PLURAL_NUM',
|
211
|
+
'$start',
|
212
|
+
'msgfmt',
|
213
|
+
'comment',
|
214
|
+
'msgctxt',
|
215
|
+
'message',
|
216
|
+
'string_list',
|
217
|
+
'single_message',
|
218
|
+
'plural_message',
|
219
|
+
'msgstr_plural',
|
220
|
+
'msgstr_plural_line']
|
221
|
+
|
222
|
+
Racc_debug_parser = true
|
223
|
+
|
224
|
+
##### racc system variables end #####
|
225
|
+
|
226
|
+
# reduce 0 omitted
|
227
|
+
|
228
|
+
# reduce 1 omitted
|
229
|
+
|
230
|
+
# reduce 2 omitted
|
231
|
+
|
232
|
+
# reduce 3 omitted
|
233
|
+
|
234
|
+
# reduce 4 omitted
|
235
|
+
|
236
|
+
module_eval <<'.,.,', 'src/poparser.ry', 25
|
237
|
+
def _reduce_5( val, _values, result )
|
238
|
+
@msgctxt = unescape(val[1]) + "\004"
|
239
|
+
result
|
240
|
+
end
|
241
|
+
.,.,
|
242
|
+
|
243
|
+
# reduce 6 omitted
|
244
|
+
|
245
|
+
# reduce 7 omitted
|
246
|
+
|
247
|
+
module_eval <<'.,.,', 'src/poparser.ry', 48
|
248
|
+
def _reduce_8( val, _values, result )
|
249
|
+
if @fuzzy and $ignore_fuzzy
|
250
|
+
if val[1] != ""
|
251
|
+
$stderr.print _("Warning: fuzzy message was ignored.\n")
|
252
|
+
$stderr.print " msgid '#{val[1]}'\n"
|
253
|
+
else
|
254
|
+
on_message('', unescape(val[3]))
|
255
|
+
end
|
256
|
+
@fuzzy = false
|
257
|
+
else
|
258
|
+
on_message(@msgctxt + unescape(val[1]), unescape(val[3]))
|
259
|
+
end
|
260
|
+
result = ""
|
261
|
+
result
|
262
|
+
end
|
263
|
+
.,.,
|
264
|
+
|
265
|
+
module_eval <<'.,.,', 'src/poparser.ry', 65
|
266
|
+
def _reduce_9( val, _values, result )
|
267
|
+
if @fuzzy and $ignore_fuzzy
|
268
|
+
if val[1] != ""
|
269
|
+
$stderr.print _("Warning: fuzzy message was ignored.\n")
|
270
|
+
$stderr.print "msgid = '#{val[1]}\n"
|
271
|
+
else
|
272
|
+
on_message('', unescape(val[3]))
|
273
|
+
end
|
274
|
+
@fuzzy = false
|
275
|
+
else
|
276
|
+
on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4]))
|
277
|
+
end
|
278
|
+
result = ""
|
279
|
+
result
|
280
|
+
end
|
281
|
+
.,.,
|
282
|
+
|
283
|
+
module_eval <<'.,.,', 'src/poparser.ry', 76
|
284
|
+
def _reduce_10( val, _values, result )
|
285
|
+
if val[0].size > 0
|
286
|
+
result = val[0] + "\000" + val[1]
|
287
|
+
else
|
288
|
+
result = ""
|
289
|
+
end
|
290
|
+
result
|
291
|
+
end
|
292
|
+
.,.,
|
293
|
+
|
294
|
+
# reduce 11 omitted
|
295
|
+
|
296
|
+
module_eval <<'.,.,', 'src/poparser.ry', 84
|
297
|
+
def _reduce_12( val, _values, result )
|
298
|
+
result = val[2]
|
299
|
+
result
|
300
|
+
end
|
301
|
+
.,.,
|
302
|
+
|
303
|
+
module_eval <<'.,.,', 'src/poparser.ry', 91
|
304
|
+
def _reduce_13( val, _values, result )
|
305
|
+
on_comment(val[0])
|
306
|
+
result
|
307
|
+
end
|
308
|
+
.,.,
|
309
|
+
|
310
|
+
module_eval <<'.,.,', 'src/poparser.ry', 99
|
311
|
+
def _reduce_14( val, _values, result )
|
312
|
+
result = val.delete_if{|item| item == ""}.join
|
313
|
+
result
|
314
|
+
end
|
315
|
+
.,.,
|
316
|
+
|
317
|
+
module_eval <<'.,.,', 'src/poparser.ry', 103
|
318
|
+
def _reduce_15( val, _values, result )
|
319
|
+
result = val[0]
|
320
|
+
result
|
321
|
+
end
|
322
|
+
.,.,
|
323
|
+
|
324
|
+
def _reduce_none( val, _values, result )
|
325
|
+
result
|
326
|
+
end
|
327
|
+
|
328
|
+
end # class PoParser
|
329
|
+
|
330
|
+
end # module GetText
|
331
|
+
end
|