source: gs2-extensions/parallel-building/trunk/src/perllib/gsprintf.pm@ 24626

Last change on this file since 24626 was 24626, checked in by jmt12, 13 years ago

An (almost) complete copy of the perllib directory from a (circa SEP2011) head checkout from Greenstone 2 trunk - in order to try and make merging in this extension a little easier later on (as there have been some major changes to buildcol.pl commited in the main trunk but not in the x64 branch)

File size: 9.4 KB
Line 
1###########################################################################
2#
3# gsprintf.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25use strict;
26no strict 'refs';
27
28package gsprintf;
29require Exporter;
30@gsprintf::ISA=qw(Exporter);
31
32use unicode;
33use util;
34
35use Cwd;
36
37@gsprintf::EXPORT_OK = qw(gsprintf); # functions we can export into namespace
38
39
40# Language-specific resource bundle
41my %specialresourcebundle = ();
42our $specialoutputencoding; # our, so that it can be changed outside.
43
44# Default resource bundle
45my %defaultresourcebundle;
46my $defaultoutputencoding;
47
48# English resource bundle
49my %englishresourcebundle;
50my $englishoutputencoding;
51
52# Ignore the OutputEncoding strings in the resource bundles and output all text in UTF-8
53my $outputstringsinUTF8 = 0;
54
55
56sub gsprintf
57{
58 my ($handle, $text_string, @text_arguments) = @_;
59
60 # Return unless the required arguments were supplied
61 return unless (defined($handle) && defined($text_string));
62
63 # Look up all the strings in the dictionary
64 $text_string =~ s/(\{[^\}]+\})/&lookup_string($1)/eg;
65
66 # Resolve the string arguments using sprintf, then write out to the handle
67 print $handle sprintf($text_string, @text_arguments);
68}
69
70
71sub lookup_string
72{
73 my ($stringkey) = @_;
74 return "" unless defined $stringkey;
75 # Try the language-specific resource bundle first
76 my $utf8string = $specialresourcebundle{$stringkey};
77 my $outputencoding = $specialoutputencoding;
78
79 # Try the default resource bundle next
80 if (!defined($utf8string)) {
81 # Load the default resource bundle if it is not already loaded
82 &load_default_resource_bundle() if (!%defaultresourcebundle);
83
84 $utf8string = $defaultresourcebundle{$stringkey};
85 $outputencoding = $defaultoutputencoding;
86 }
87
88 # Try the English resource bundle last
89 if (!defined($utf8string)) {
90 # Load the English resource bundle if it is not already loaded
91 &load_english_resource_bundle() if (!%englishresourcebundle);
92
93 $utf8string = $englishresourcebundle{$stringkey};
94 $outputencoding = $englishoutputencoding;
95 }
96
97 # No matching string was found, so just return the key
98 if (!defined($utf8string)) {
99 return $stringkey;
100 }
101
102 # Return the string matching the key
103 return $utf8string if (!defined($outputencoding) || $outputstringsinUTF8
104 || $outputencoding eq "utf8");
105
106 # If an 8-bit output encoding has been defined, encode the string appropriately
107 my $encoded=unicode::unicode2singlebyte(&unicode::utf82unicode($utf8string), $outputencoding);
108
109 # If we successfully encoded it, return it
110 if ($encoded) { return $encoded }
111
112 # Otherwise, we can't convert to the requested encoding. return the utf8?
113 $specialoutputencoding='utf8';
114 return $utf8string;
115}
116
117
118sub load_language_specific_resource_bundle
119{
120 my $language = shift(@_);
121
122 # Read the specified resource bundle
123 my $resourcebundlename = "strings_" . $language . ".properties";
124
125 %specialresourcebundle
126 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
127 return if (!%specialresourcebundle);
128
129 # Read the output encoding to use from the resource bundle
130 if ($ENV{'GSDLOS'} =~ /windows/) {
131 $specialoutputencoding = $specialresourcebundle{"{OutputEncoding.windows}"};
132 }
133 else {
134 # see if there is an encoding set in the appropriate locale env var
135
136 foreach my $envvar ('LC_ALL', 'LANG') {
137 if (!exists $ENV{$envvar}) { next }
138 my $locale=$ENV{$envvar};
139 if ($locale !~ /^\w+\.(.+)$/) { next }
140 my $enc=lc($1);
141 $enc =~ s/-/_/g;
142 if ($enc eq 'utf_8') { $enc='utf8' } # normalise to this name
143 $specialoutputencoding = $enc;
144 return;
145 }
146 $specialoutputencoding = $specialresourcebundle{"{OutputEncoding.unix}"};
147 }
148}
149
150
151sub load_default_resource_bundle
152{
153 # Read the default resource bundle
154 my $resourcebundlename = "strings.properties";
155
156 %defaultresourcebundle = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
157
158 if (!%defaultresourcebundle) {
159 # $! will still have the error value for the last failed syscall
160 print STDERR "$! $resourcebundlename\n";
161 # set something so we don't bother trying to load it again
162 $defaultresourcebundle{0}=undef;
163 return;
164 }
165
166 # Read the output encoding to use from the resource bundle
167 if ($ENV{'GSDLOS'} =~ /windows/) {
168 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.windows}"};
169 }
170 else {
171 $defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.unix}"};
172 }
173}
174
175
176sub load_english_resource_bundle
177{
178 # Ensure the English resource bundle hasn't already been loaded
179 if (%specialresourcebundle && $specialresourcebundle{"{Language.code}"} eq "en") {
180 %englishresourcebundle = %specialresourcebundle;
181 $englishoutputencoding = $specialoutputencoding;
182 }
183
184 if ($defaultresourcebundle{"{Language.code}"} &&
185 $defaultresourcebundle{"{Language.code}"} eq "en") {
186 %englishresourcebundle = %defaultresourcebundle;
187 $englishoutputencoding = $defaultoutputencoding;
188 }
189
190 # Read the English resource bundle
191 my $resourcebundlename = "strings_en.properties";
192
193 %englishresourcebundle
194 = &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
195 return if (!%englishresourcebundle);
196
197 # Read the output encoding to use from the resource bundle
198 if ($ENV{'GSDLOS'} =~ /windows/) {
199 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.windows}"};
200 }
201 else {
202 $englishoutputencoding = $englishresourcebundle{"{OutputEncoding.unix}"};
203 }
204}
205
206
207sub read_resource_bundle_and_extensions
208{
209 my ($bundle_base,$primary_dir,$resourcename) = @_;
210
211 my $primary_resourcebundlefile
212 = &util::filename_cat($bundle_base,$primary_dir,$resourcename);
213
214 my $resourcebundle = read_resource_bundle($primary_resourcebundlefile);
215 return if (!defined $resourcebundle);
216
217 if (defined $ENV{'GSDLEXTS'}) {
218 my @extensions = split(/:/,$ENV{'GSDLEXTS'});
219 foreach my $e (@extensions) {
220 my $ext_base
221 = &util::filename_cat($bundle_base,"ext",$e);
222
223 my $ext_resourcebundlefile
224 = &util::filename_cat($ext_base,$primary_dir,$resourcename);
225
226 # can ignore return value (will be same reference to $resourcebundle)
227 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
228 }
229 }
230 if (defined $ENV{'GSDL3EXTS'}) {
231 my @extensions = split(/:/,$ENV{'GSDL3EXTS'});
232 foreach my $e (@extensions) {
233 my $ext_base
234 = &util::filename_cat($ENV{'GSDL3SRCHOME'},"ext",$e);
235
236 my $ext_resourcebundlefile
237 = &util::filename_cat($ext_base,$primary_dir,$resourcename);
238
239 # can ignore return value (will be same reference to $resourcebundle)
240 read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
241 }
242 }
243
244 return %$resourcebundle;
245}
246
247
248sub read_resource_bundle
249{
250 my ($resourcebundlefilepath,$resourcebundle) = @_;
251
252 if (!open(RESOURCE_BUNDLE, "<$resourcebundlefilepath")) {
253 # When called for the first time (primary resource), $resourcebundle
254 # is not defined (=undef). If the file does not exist, then we return
255 # this 'undef' to signal it was not found
256 # For an extension resource bundle, if it does not exist this
257 # is not so serious (in fact quite likely) => return what we
258 # have built up so far
259
260 return $resourcebundle;
261 }
262
263 if (!defined $resourcebundle) {
264 # resource files exists, so exect some content to be stored
265 $resourcebundle = {};
266 }
267
268 # Load this resource bundle
269 my @resourcebundlelines = <RESOURCE_BUNDLE>;
270 close(RESOURCE_BUNDLE);
271
272 # Parse the resource bundle
273
274 foreach my $line (@resourcebundlelines) {
275 # Remove any trailing whitespace
276 $line =~ s/(\s*)$//;
277
278 # Ignore comments and empty lines
279 if ($line !~ /^\#/ && $line ne "") {
280 # Parse key (everything up to the first colon)
281 if ($line =~ m/^([^:]+):(.+)$/) {
282 my $linekey = "{" . $1 . "}";
283 my $linetext = $2;
284 $linetext =~ s/(\s*)\#\s+Updated\s+(\d?\d-\D\D\D-\d\d\d\d).*$//i;
285
286 # Map key to text
287 $resourcebundle->{$linekey} = $linetext;
288 }
289 }
290 }
291
292 return $resourcebundle;
293}
294
295
296sub output_strings_in_UTF8
297{
298 $outputstringsinUTF8 = 1;
299}
300
301
302sub debug_unicode_string
303{
304 join("",
305 map { $_ > 255 ? # if wide character...
306 sprintf("\\x{%04X}", $_) : # \x{...}
307 chr($_)
308 } unpack("U*", $_[0])); # unpack Unicode characters
309}
310
311
3121;
Note: See TracBrowser for help on using the repository browser.