fast_gettext 0.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|