| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# |
|
2
|
|
|
|
|
|
|
# $Id$ |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# Unicode::Map 0.112 |
|
5
|
|
|
|
|
|
|
# |
|
6
|
|
|
|
|
|
|
# Documentation at end of file. |
|
7
|
|
|
|
|
|
|
# |
|
8
|
|
|
|
|
|
|
# Copyright (C) 1998, 1999, 2000 Martin Schwartz. All rights reserved. |
|
9
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or |
|
10
|
|
|
|
|
|
|
# modify it under the same terms as Perl itself. |
|
11
|
|
|
|
|
|
|
# |
|
12
|
|
|
|
|
|
|
# Contact: Martin Schwartz |
|
13
|
|
|
|
|
|
|
# |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
package Unicode::Map; |
|
16
|
3
|
|
|
3
|
|
2795
|
use strict; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
113
|
|
|
17
|
3
|
|
|
3
|
|
14
|
use vars qw($VERSION $WARNINGS @ISA $DEBUG); |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
235
|
|
|
18
|
3
|
|
|
3
|
|
14
|
use Carp; |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
20355
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
$VERSION='0.112'; # Michael Changes it to 0.112 |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
require DynaLoader; @ISA=qw(DynaLoader); |
|
23
|
|
|
|
|
|
|
bootstrap Unicode::Map $VERSION; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub NOISE () { 1 } |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub MAGIC () { 0xB827 } # magic word |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub M_END () { 0 } # end |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub M_INF () { 1 } # infinite subsequent entries (default) |
|
32
|
|
|
|
|
|
|
sub M_BYTE () { 2 } # 1..255 subsequent entries |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub M_VER () { 4 } # (Internal) file format revision. |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub M_AKV () { 6 } # key1, val1, key2, val2, ... (default) |
|
37
|
|
|
|
|
|
|
sub M_AKAV () { 7 } # key1, key2, ..., val1, val2, ... |
|
38
|
|
|
|
|
|
|
sub M_PKV () { 8 } # partial key value mappings |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub M_CKn () { 10 } # compress keys not |
|
41
|
|
|
|
|
|
|
sub M_CK () { 11 } # compress keys (default) |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub M_CVn () { 13 } # compress values not |
|
44
|
|
|
|
|
|
|
sub M_CV () { 14 } # compress values (default) |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
## |
|
47
|
|
|
|
|
|
|
## The next entries are for info, only. They are stored as unicode strings. |
|
48
|
|
|
|
|
|
|
## |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub I_NAME () { 20 } # Character Set Name |
|
51
|
|
|
|
|
|
|
sub I_ALIAS () { 21 } # Character Set alias name (several entries allowed) |
|
52
|
|
|
|
|
|
|
sub I_VER () { 22 } # Mapfile revision |
|
53
|
|
|
|
|
|
|
sub I_AUTH () { 23 } # Mapfile authRess |
|
54
|
|
|
|
|
|
|
sub I_INFO () { 24 } # Some userEss definable string |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub WARN_DEFAULT () { 0x0000 }; |
|
57
|
|
|
|
|
|
|
sub WARN_DEPRECATION () { 0x1000 }; |
|
58
|
|
|
|
|
|
|
sub WARN_COMPATIBILITY () { 0x2000 }; |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
## |
|
61
|
|
|
|
|
|
|
## --- Init --------------------------------------------------------------- |
|
62
|
|
|
|
|
|
|
## |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
my $MAP_Pathname = 'Unicode/Map'; |
|
65
|
|
|
|
|
|
|
my $MAP_Path = $INC{"Unicode/Map.pm"}; $MAP_Path=~s/\.pm//; |
|
66
|
|
|
|
|
|
|
die "Can't find base directory of Unicode::Map!" unless $MAP_Path; |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
my @order = ( |
|
69
|
|
|
|
|
|
|
{ 1=>"C", 2=>"n", 3=>"N", 4=>"N" }, # standard ("Network order") |
|
70
|
|
|
|
|
|
|
{ 1=>"C", 2=>"v", 3=>"V", 4=>"V" }, # reverse ("Vax order") |
|
71
|
|
|
|
|
|
|
); |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
my %registry = (); |
|
74
|
|
|
|
|
|
|
my %mappings = (); |
|
75
|
|
|
|
|
|
|
my $registry_loaded = 0; |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
$WARNINGS = WARN_DEFAULT; |
|
78
|
|
|
|
|
|
|
_init_registry(); |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
## |
|
81
|
|
|
|
|
|
|
## --- public conversion methods ------------------------------------------ |
|
82
|
|
|
|
|
|
|
## |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# For compatibility with Unicode::Map8 |
|
85
|
0
|
|
|
0
|
1
|
0
|
sub to8 { goto &from_unicode } |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub from_unicode { |
|
88
|
10
|
|
|
10
|
1
|
45
|
my $S = shift; |
|
89
|
10
|
100
|
|
|
|
25
|
if ( $#_==0 ) { |
|
90
|
9
|
|
|
|
|
16
|
$S -> _to ("TO_CUS", $S->_csid(), @_); |
|
91
|
|
|
|
|
|
|
} else { |
|
92
|
1
|
|
|
|
|
3
|
_deprecated ( ); |
|
93
|
1
|
|
|
|
|
3
|
_incompatible ( ); |
|
94
|
1
|
|
|
|
|
3
|
$S -> _to ("TO_CUS", @_); |
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub new { |
|
99
|
|
|
|
|
|
|
# |
|
100
|
|
|
|
|
|
|
# $ref||undef = Unicode::Map->new("ISO-8859-1") |
|
101
|
|
|
|
|
|
|
# |
|
102
|
|
|
|
|
|
|
# Note: usage like below is deprecated. It is not compatible with |
|
103
|
|
|
|
|
|
|
# Unicode::Map8. Support will vanish soon! martin [2000-Jun-19] |
|
104
|
|
|
|
|
|
|
# |
|
105
|
|
|
|
|
|
|
# I<$Map> = new Unicode::Map; |
|
106
|
|
|
|
|
|
|
# |
|
107
|
|
|
|
|
|
|
# I<$utf16> = I<$Map> -> to_unicode ("ISO-8859-1", "Hello world!"); |
|
108
|
|
|
|
|
|
|
# => $_16bit == "\0H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!" |
|
109
|
|
|
|
|
|
|
# |
|
110
|
|
|
|
|
|
|
# I<$locale> = I<$Map> -> from_unicode ("ISO-8859-7", I<$_16bit>); |
|
111
|
|
|
|
|
|
|
# => $_8bit == "Hello world!" |
|
112
|
9
|
|
|
9
|
1
|
1827
|
my ($proto, $parH) = @_; |
|
113
|
9
|
|
33
|
|
|
66
|
my $S = bless ({}, ref($proto) || $proto); |
|
114
|
9
|
|
|
|
|
30
|
$S -> _noise ( NOISE ); |
|
115
|
9
|
50
|
|
|
|
32
|
return unless $S -> _load_registry ( ); |
|
116
|
9
|
100
|
|
|
|
32
|
if (!$parH) { |
|
117
|
1
|
|
|
|
|
4
|
_deprecated ( ); |
|
118
|
|
|
|
|
|
|
} else { |
|
119
|
8
|
|
|
|
|
11
|
my $csid; |
|
120
|
8
|
100
|
|
|
|
22
|
if (!ref($parH)) { |
|
121
|
|
|
|
|
|
|
# Compatible to Unicode::Map8 |
|
122
|
7
|
|
|
|
|
11
|
$csid = $parH; |
|
123
|
|
|
|
|
|
|
} else { |
|
124
|
1
|
|
|
|
|
3
|
_deprecated ( ); |
|
125
|
1
|
|
|
|
|
3
|
_incompatible ( ); |
|
126
|
1
|
50
|
|
|
|
4
|
if ( $parH->{"STARTUP"} ) { |
|
127
|
0
|
|
|
|
|
0
|
$S -> Startup ( $parH->{"STARTUP"} ); |
|
128
|
|
|
|
|
|
|
} |
|
129
|
1
|
|
|
|
|
2
|
$csid = $parH -> { "ID" }; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
8
|
50
|
|
|
|
20
|
if ( $csid ) { |
|
132
|
8
|
50
|
|
|
|
23
|
return 0 unless $S -> _csid ( $S->_real_id($csid) ) |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
} |
|
135
|
9
|
|
|
|
|
27
|
$S; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
# Deprecated! |
|
139
|
|
|
|
|
|
|
sub noise { |
|
140
|
1
|
|
|
1
|
1
|
8
|
_deprecated ( ); |
|
141
|
1
|
|
|
|
|
3
|
_incompatible ( ); |
|
142
|
|
|
|
|
|
|
# Defines the verbosity of messages to user sent via I<$Startup>. Can be no |
|
143
|
|
|
|
|
|
|
# messages at all (n=0), some information (n=1) or some more information |
|
144
|
|
|
|
|
|
|
# (n=3). Default is n=1. |
|
145
|
|
|
|
|
|
|
# I<$Map> -> noise (I<$n>) |
|
146
|
1
|
|
|
|
|
2
|
_noise ( @_ ); |
|
147
|
|
|
|
|
|
|
} |
|
148
|
42
|
|
|
42
|
|
127
|
sub _noise { shift->_member("P_NOISE", @_) } |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# |
|
151
|
|
|
|
|
|
|
# Unicode::Map.xs -> reverse_unicode |
|
152
|
|
|
|
|
|
|
# |
|
153
|
|
|
|
|
|
|
# Usage is deprecated! Use Unicode::String::byteswap instead! |
|
154
|
|
|
|
|
|
|
# |
|
155
|
|
|
|
|
|
|
# I<$string> = I<$Map> -> reverse_unicode (I<$string>) |
|
156
|
|
|
|
|
|
|
# |
|
157
|
|
|
|
|
|
|
# One Unicode character, precise one utf16 character, consists of two |
|
158
|
|
|
|
|
|
|
# bytes. Therefore it is important, in which order these bytes are stored. |
|
159
|
|
|
|
|
|
|
# As far as I could figure out, Unicode characters are assumed to be in |
|
160
|
|
|
|
|
|
|
# "Network order" (0x1234 => 0x12, 0x34). Alas, many PC Windows documents |
|
161
|
|
|
|
|
|
|
# store Unicode characters internally in "Vax order" (0x1234 => 0x34, 0x12). |
|
162
|
|
|
|
|
|
|
# With this method you can convert "Vax mode" -> "Network mode" and vice versa. |
|
163
|
|
|
|
|
|
|
# |
|
164
|
|
|
|
|
|
|
# reverse_unicode changes the original variable if in a void context. If |
|
165
|
|
|
|
|
|
|
# in scalar or list context returns a new created string. |
|
166
|
|
|
|
|
|
|
# |
|
167
|
|
|
|
|
|
|
sub reverse_unicode { |
|
168
|
2
|
|
|
2
|
1
|
15
|
_deprecated ( "see: Unicode::String::byteswap" ); |
|
169
|
2
|
|
|
|
|
4
|
_incompatible ( ); |
|
170
|
2
|
|
|
|
|
8
|
&_reverse_unicode; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# For compatibility with Unicode::Map8 |
|
174
|
0
|
|
|
0
|
1
|
0
|
sub to16 { goto &to_unicode } |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub to_unicode { |
|
177
|
6
|
|
|
6
|
1
|
43
|
my $S = shift; |
|
178
|
6
|
100
|
|
|
|
18
|
if ( $#_==0 ) { |
|
179
|
5
|
|
|
|
|
15
|
$S -> _to ("TO_UNI", $S->_csid(), @_); |
|
180
|
|
|
|
|
|
|
} else { |
|
181
|
1
|
|
|
|
|
6
|
_deprecated ( ); |
|
182
|
1
|
|
|
|
|
3
|
_incompatible ( ); |
|
183
|
1
|
|
|
|
|
5
|
$S -> _to ("TO_UNI", @_); |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
## |
|
188
|
|
|
|
|
|
|
## --- public maintainance methods ---------------------------------------- |
|
189
|
|
|
|
|
|
|
## |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub alias { |
|
192
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
193
|
0
|
|
|
|
|
0
|
@{$registry{$_[1]} -> {"ALIAS"}}; |
|
|
0
|
|
|
|
|
0
|
|
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub dest { |
|
197
|
0
|
|
|
0
|
0
|
0
|
_deprecated ( "'dest' is now 'mapping'" ); |
|
198
|
0
|
|
|
|
|
0
|
goto &mapping; |
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub mapping { |
|
202
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
203
|
0
|
|
|
|
|
0
|
return shift -> _mapping ( shift() ); |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub id { |
|
207
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
208
|
0
|
|
|
|
|
0
|
shift->_real_id(shift()); |
|
209
|
|
|
|
|
|
|
} |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub ids { |
|
212
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
213
|
0
|
|
|
|
|
0
|
(sort {$a cmp $b} grep {!/^GENERIC$/i} keys %registry); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub info { |
|
217
|
0
|
|
|
0
|
0
|
0
|
_incompatible ( ); |
|
218
|
0
|
|
|
|
|
0
|
$registry{$_[1]} -> {"INFO"}; |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub read_text_mapping { |
|
222
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
223
|
0
|
|
|
|
|
0
|
my ($S, $csid, $textpath, $style) = @_; |
|
224
|
0
|
0
|
|
|
|
0
|
return 0 if !($csid = $S->id($csid)); |
|
225
|
0
|
0
|
|
|
|
0
|
$S->_msg("reading") if $S->_noise>0; |
|
226
|
0
|
|
|
|
|
0
|
$S->_read_text_mapping($csid, $textpath, $style); |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub src { |
|
230
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
231
|
0
|
|
|
|
|
0
|
$registry{$_[1]} -> {"SRC"}; |
|
232
|
|
|
|
|
|
|
} |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub srcURL { |
|
235
|
0
|
|
|
0
|
0
|
0
|
_incompatible ( ); |
|
236
|
0
|
|
|
|
|
0
|
$registry{$_[1]} -> {"SRCURL"}; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub style { |
|
240
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
241
|
0
|
|
|
|
|
0
|
$registry{$_[1]} -> {"STYLE"}; |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub write_binary_mapping { |
|
245
|
0
|
|
|
0
|
1
|
0
|
_incompatible ( ); |
|
246
|
0
|
|
|
|
|
0
|
my ($S, $csid, $binpath) = @_; |
|
247
|
0
|
0
|
|
|
|
0
|
return 0 unless ( $csid = $S->id($csid) ); |
|
248
|
0
|
0
|
|
|
|
0
|
$binpath = $S->_mapping($csid) if !$binpath; |
|
249
|
0
|
0
|
|
|
|
0
|
return 0 unless $binpath; |
|
250
|
0
|
0
|
|
|
|
0
|
$S->_msg("writing") if $S->_noise>0; |
|
251
|
0
|
|
|
|
|
0
|
$S->_write_IMap_to_binary($csid, $binpath); |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
## |
|
255
|
|
|
|
|
|
|
## --- Application program interface -------------------------------------- |
|
256
|
|
|
|
|
|
|
## |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub Startup { |
|
259
|
6
|
|
|
6
|
0
|
21
|
_deprecated ( "module Startup shouldn't be used any longer" ); |
|
260
|
6
|
|
|
|
|
16
|
shift->_member("STARTUP", @_); |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
## |
|
264
|
|
|
|
|
|
|
## --- private methods ---------------------------------------------------- |
|
265
|
|
|
|
|
|
|
## |
|
266
|
|
|
|
|
|
|
|
|
267
|
70
|
50
|
|
70
|
|
74
|
sub _member { my $S=shift; my $n=shift if @_; $S->{$n}=shift if @_; $S->{$n}} |
|
|
70
|
100
|
|
|
|
165
|
|
|
|
70
|
|
|
|
|
244
|
|
|
|
70
|
|
|
|
|
299
|
|
|
268
|
|
|
|
|
|
|
|
|
269
|
22
|
|
|
22
|
|
52
|
sub _csid { shift->_member("P_CSID", @_) } |
|
270
|
0
|
0
|
|
0
|
|
0
|
sub _error { my $S=shift; $S->Startup ? $S->Startup->error(@_) : 0 } |
|
|
0
|
|
|
|
|
0
|
|
|
271
|
6
|
50
|
|
6
|
|
10
|
sub _msg { my $S=shift; $S->Startup ? $S->Startup->msg(@_) : 0 } |
|
|
6
|
|
|
|
|
16
|
|
|
272
|
0
|
0
|
|
0
|
|
0
|
sub _msg_fin { my $S=shift; $S->Startup ? $S->Startup->msg_finish(@_) : 0 } |
|
|
0
|
|
|
|
|
0
|
|
|
273
|
0
|
|
|
0
|
|
0
|
sub _IMap { shift->_member("I", @_) } |
|
274
|
|
|
|
|
|
|
|
|
275
|
5
|
|
|
5
|
|
19
|
sub _mapping { $registry{$_[1]} -> {"MAP"} } |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub _dump { |
|
278
|
0
|
|
|
0
|
|
0
|
my $S = shift; |
|
279
|
0
|
|
|
|
|
0
|
print "Dumping Mapping $S:\n"; |
|
280
|
0
|
0
|
|
|
|
0
|
if ($S->Startup) { |
|
281
|
0
|
|
|
|
|
0
|
print " - Startup object: ".$S->Startup."\n"; |
|
282
|
|
|
|
|
|
|
} else { |
|
283
|
0
|
|
|
|
|
0
|
print " - no Startup object\n"; |
|
284
|
|
|
|
|
|
|
} |
|
285
|
0
|
0
|
|
|
|
0
|
if (%registry) { |
|
286
|
0
|
|
|
|
|
0
|
print " - Mapping: " . (keys %registry) . " entries defined.\n"; |
|
287
|
|
|
|
|
|
|
} else { |
|
288
|
0
|
|
|
|
|
0
|
print " - No mappings!\n"; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
0
|
0
|
|
|
|
0
|
if ($S->_IMap) { |
|
291
|
0
|
|
|
|
|
0
|
print " - IMap:\n"; |
|
292
|
0
|
|
|
|
|
0
|
my ($k,$v); while(($k,$v)=each %{$S->_IMap}) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
293
|
0
|
|
|
|
|
0
|
printf " %10s => %s\n", $k, $v; |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
} |
|
296
|
0
|
0
|
|
|
|
0
|
if (%mappings) { |
|
297
|
0
|
|
|
|
|
0
|
print " - Mappings:\n"; |
|
298
|
0
|
|
|
|
|
0
|
my ($k,$v); while(($k,$v)=each %mappings) { |
|
|
0
|
|
|
|
|
0
|
|
|
299
|
0
|
|
|
|
|
0
|
printf " %10s => %s\n", $k, $v; |
|
300
|
|
|
|
|
|
|
} |
|
301
|
|
|
|
|
|
|
} |
|
302
|
0
|
|
|
|
|
0
|
1} |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub _real_id { |
|
305
|
24
|
|
|
24
|
|
31
|
my ($S, $csid) = @_; |
|
306
|
24
|
50
|
|
|
|
108
|
if (!%registry) { |
|
307
|
0
|
|
|
|
|
0
|
return $S->_error("No mapping definitions!\n"); |
|
308
|
|
|
|
|
|
|
} |
|
309
|
24
|
50
|
|
|
|
122
|
return $csid if defined $registry{$csid}; |
|
310
|
0
|
|
|
|
|
0
|
my $id=""; |
|
311
|
0
|
|
|
|
|
0
|
my (@tmp, $k, $v); |
|
312
|
0
|
|
|
|
|
0
|
while (($k,$v) = each %registry) { |
|
313
|
0
|
0
|
0
|
|
|
0
|
next if !$k || !$v; |
|
314
|
0
|
0
|
|
|
|
0
|
if ($csid =~ /^$k$/i) { |
|
315
|
0
|
|
|
|
|
0
|
$id=$k; last; |
|
|
0
|
|
|
|
|
0
|
|
|
316
|
|
|
|
|
|
|
} else { |
|
317
|
0
|
|
|
|
|
0
|
for (@{$v->{"ALIAS"}}) { |
|
|
0
|
|
|
|
|
0
|
|
|
318
|
0
|
0
|
|
|
|
0
|
if (/^$csid$/i) { |
|
319
|
0
|
|
|
|
|
0
|
$id=$k; last; |
|
|
0
|
|
|
|
|
0
|
|
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
} |
|
324
|
0
|
|
|
|
|
0
|
while (($k, $v) = each %registry) {} |
|
325
|
0
|
0
|
|
|
|
0
|
return $S->_error("Character Set $csid not defined!") if !$id; |
|
326
|
0
|
|
|
|
|
0
|
$id; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
sub _to { |
|
330
|
|
|
|
|
|
|
# |
|
331
|
|
|
|
|
|
|
# 1||0 = $S -> _to ("TO_UNI"||"TO_CUS", $csid, $src||$srcR, $destR, $o, $l) |
|
332
|
|
|
|
|
|
|
# $text||"" = $S -> _to ("TO_UNI"||"TO_CUS", $csid, $src||$srcR, "", $o, $l) |
|
333
|
|
|
|
|
|
|
# |
|
334
|
16
|
|
|
16
|
|
29
|
my ($S, $to, $csid, $srcR, $destR, $o, $l) = @_; |
|
335
|
16
|
50
|
|
|
|
37
|
return 0 if !($csid = $S->_real_id($csid)); |
|
336
|
16
|
50
|
|
|
|
35
|
return 0 if !$S->_load_TMap($csid); |
|
337
|
|
|
|
|
|
|
|
|
338
|
16
|
|
|
|
|
30
|
my ($cs1, $n1, $cs2, $n2, $tmp) = (0, 0, 0, 0, ""); |
|
339
|
16
|
|
|
|
|
16
|
my (@M, @C); |
|
340
|
|
|
|
|
|
|
|
|
341
|
16
|
|
|
|
|
18
|
my $destbuf = ""; |
|
342
|
16
|
50
|
|
|
|
30
|
my $srcbuf = ref($srcR) ? $$srcR : $srcR; |
|
343
|
|
|
|
|
|
|
|
|
344
|
16
|
|
|
|
|
30
|
my $C = $mappings{$csid}->{$to}; |
|
345
|
|
|
|
|
|
|
|
|
346
|
16
|
50
|
|
|
|
35
|
if ($S->_noise>2) { |
|
347
|
0
|
0
|
|
|
|
0
|
$S->_msg("mapping ".(($to=~/^to_unicode$/i) ? "to Unicode" : "to $csid")); |
|
348
|
|
|
|
|
|
|
} |
|
349
|
16
|
|
|
|
|
18
|
my ($csa,$na,$csb,$nb); |
|
350
|
23
|
|
|
|
|
94
|
my @n = sort { |
|
351
|
|
|
|
|
|
|
# Sort the partial mappings according to their left side's total |
|
352
|
|
|
|
|
|
|
# length, descending order. |
|
353
|
16
|
|
|
|
|
72
|
($csa, $na) = split/,/,$a; |
|
354
|
23
|
|
|
|
|
44
|
($csb, $nb) = split/,/,$b; |
|
355
|
23
|
|
|
|
|
63
|
$csb*$nb <=> $csa*$na |
|
356
|
|
|
|
|
|
|
} keys %$C; |
|
357
|
16
|
100
|
|
|
|
34
|
if ($#n==0) { |
|
358
|
4
|
|
|
|
|
49
|
($cs1, $n1, $cs2, $n2) = split /,/,$n[0]; |
|
359
|
4
|
|
50
|
|
|
45
|
$destbuf = $S->_map_hash($srcbuf, |
|
|
|
|
50
|
|
|
|
|
|
360
|
|
|
|
|
|
|
$C->{$n[0]}, |
|
361
|
|
|
|
|
|
|
$n1*$cs1, |
|
362
|
|
|
|
|
|
|
$o||undef, $l||undef |
|
363
|
|
|
|
|
|
|
); |
|
364
|
|
|
|
|
|
|
} else { |
|
365
|
30
|
|
|
|
|
70
|
$destbuf = $S->_map_hashlist($srcbuf, |
|
366
|
|
|
|
|
|
|
[map $C->{$_}, @n], |
|
367
|
12
|
|
|
|
|
50
|
[map {($cs1,$n1)=split/,/; int($cs1*$n1)} @n], |
|
|
30
|
|
|
|
|
223
|
|
|
368
|
|
|
|
|
|
|
$o, $l |
|
369
|
|
|
|
|
|
|
); |
|
370
|
|
|
|
|
|
|
} |
|
371
|
16
|
50
|
|
|
|
44
|
if ($destR) { |
|
372
|
0
|
|
|
|
|
0
|
$$destR=$destbuf; 1; |
|
|
0
|
|
|
|
|
0
|
|
|
373
|
|
|
|
|
|
|
} else { |
|
374
|
16
|
|
|
|
|
76
|
$destbuf; |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
} |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
sub _init_registry { |
|
379
|
3
|
|
|
3
|
|
7
|
%registry = (); |
|
380
|
3
|
|
|
|
|
27
|
$registry_loaded = 0; |
|
381
|
3
|
|
|
|
|
11
|
_add_registry_entry("GENERIC", "GENERIC", "GENERIC"); |
|
382
|
3
|
|
|
|
|
6
|
1} |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
sub _unload_registry { |
|
385
|
0
|
|
|
0
|
|
0
|
_init_registry; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
## |
|
389
|
|
|
|
|
|
|
## --- Binary to TMap ----------------------------------------------------- |
|
390
|
|
|
|
|
|
|
## |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
# TMap structure: |
|
393
|
|
|
|
|
|
|
# |
|
394
|
|
|
|
|
|
|
# %T = ( |
|
395
|
|
|
|
|
|
|
# $CSID => { |
|
396
|
|
|
|
|
|
|
# TO_CUS => { |
|
397
|
|
|
|
|
|
|
# "$cs_a1,$n_a1,$cs_a2,$n_a2" => { |
|
398
|
|
|
|
|
|
|
# "str_a1_1" => "str_a2_1", ... , |
|
399
|
|
|
|
|
|
|
# "str_a1_n" => "str_a2_n", |
|
400
|
|
|
|
|
|
|
# }, ... , |
|
401
|
|
|
|
|
|
|
# "$cs_x1,$n_x1,$cs_x2,$n_x2" => { |
|
402
|
|
|
|
|
|
|
# "str_x1_1" => "str_x2_1", ... , |
|
403
|
|
|
|
|
|
|
# "str_x1_n" => "str_x2_n", |
|
404
|
|
|
|
|
|
|
# } |
|
405
|
|
|
|
|
|
|
# } |
|
406
|
|
|
|
|
|
|
# TO_UNI => { |
|
407
|
|
|
|
|
|
|
# "$cs_a2,$n_a2,$cs_a1,$n_a1" => { |
|
408
|
|
|
|
|
|
|
# "str_a2_1" => "str_a1_1", ... , |
|
409
|
|
|
|
|
|
|
# "str_a2_n" => "str_a1_n", |
|
410
|
|
|
|
|
|
|
# }, ... , |
|
411
|
|
|
|
|
|
|
# "$csx2,$nx2,$csx1,$nx1" => { |
|
412
|
|
|
|
|
|
|
# "str_x2_1" => "str_x1_1", ... , |
|
413
|
|
|
|
|
|
|
# "str_x2_n" => "str_x1_n", |
|
414
|
|
|
|
|
|
|
# } |
|
415
|
|
|
|
|
|
|
# } |
|
416
|
|
|
|
|
|
|
# } |
|
417
|
|
|
|
|
|
|
# ); |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub _load_TMap { |
|
420
|
16
|
|
|
16
|
|
21
|
my ($S, $csid) = @_; |
|
421
|
16
|
100
|
|
|
|
50
|
return 1 if $mappings{$csid}; |
|
422
|
5
|
50
|
|
|
|
15
|
return 0 if !$S->_read_binary_to_TMap($csid); |
|
423
|
5
|
|
|
|
|
28
|
1} |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
sub _read_binary_to_TMap { |
|
426
|
5
|
|
|
5
|
|
7
|
my ($S, $csid) = @_; |
|
427
|
5
|
|
|
|
|
13
|
my %U = (); |
|
428
|
5
|
|
|
|
|
7
|
my %C = (); |
|
429
|
5
|
|
|
|
|
7
|
my $buf = ""; |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# |
|
432
|
|
|
|
|
|
|
# read file |
|
433
|
|
|
|
|
|
|
# |
|
434
|
5
|
|
|
|
|
17
|
my $file = $S->_mapping($csid); |
|
435
|
5
|
50
|
|
|
|
265
|
return $S->_error ("Cannot find mapping file for id \"$csid\"!") |
|
436
|
|
|
|
|
|
|
unless -f $file |
|
437
|
|
|
|
|
|
|
; |
|
438
|
5
|
50
|
|
|
|
270
|
return $S->_error ("Cannot open binary mapping \"$file\"!") |
|
439
|
|
|
|
|
|
|
if !open(MAP1, $file) |
|
440
|
|
|
|
|
|
|
; |
|
441
|
5
|
|
|
|
|
19
|
binmode MAP1; |
|
442
|
5
|
|
|
|
|
404
|
my $size = read MAP1, $buf, -s $file; |
|
443
|
5
|
|
|
|
|
103
|
close MAP1; |
|
444
|
5
|
50
|
|
|
|
125
|
return $S->_error ("Error while reading mapping \"$file\"!") |
|
445
|
|
|
|
|
|
|
if ($size != -s $file) |
|
446
|
|
|
|
|
|
|
; |
|
447
|
|
|
|
|
|
|
|
|
448
|
5
|
100
|
|
|
|
13
|
if ($size>0x1000) { |
|
449
|
3
|
50
|
|
|
|
9
|
$S->_msg("loading mapfile \"$csid\"") if $S->_noise>0; |
|
450
|
|
|
|
|
|
|
} else { |
|
451
|
2
|
50
|
|
|
|
7
|
$S->_msg("loading mapfile \"$csid\"") if $S->_noise>2; |
|
452
|
|
|
|
|
|
|
} |
|
453
|
|
|
|
|
|
|
|
|
454
|
5
|
50
|
|
|
|
76877
|
return $S->_error ("Error in binary map file!\n") |
|
455
|
|
|
|
|
|
|
if !$S->_read_binary_mapping($buf, 0, \%U, \%C) |
|
456
|
|
|
|
|
|
|
; |
|
457
|
|
|
|
|
|
|
|
|
458
|
5
|
100
|
|
|
|
30
|
if ($size>0x1000) { |
|
459
|
3
|
50
|
|
|
|
26
|
$S->_msg("loaded") if $S->_noise>0; |
|
460
|
|
|
|
|
|
|
} else { |
|
461
|
2
|
50
|
|
|
|
14
|
$S->_msg("loaded") if $S->_noise>2; |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
|
|
464
|
5
|
|
|
|
|
37
|
$mappings{$csid} = { |
|
465
|
|
|
|
|
|
|
TO_CUS => \%C, |
|
466
|
|
|
|
|
|
|
TO_UNI => \%U |
|
467
|
|
|
|
|
|
|
}; |
|
468
|
|
|
|
|
|
|
# $S->_dump_TMap ($mappings{$csid}); |
|
469
|
5
|
|
|
|
|
33
|
1} |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
sub _dump_TMap { |
|
472
|
0
|
|
|
0
|
|
0
|
my ($S, $TMap) = @_; |
|
473
|
0
|
|
|
|
|
0
|
print "\nDumping TMap $TMap\n"; |
|
474
|
0
|
|
|
|
|
0
|
my ($pat1, $pat2, $up1, $up2); |
|
475
|
0
|
|
|
|
|
0
|
foreach (keys %$TMap) { |
|
476
|
0
|
|
|
|
|
0
|
my $subTMap = $TMap->{$_}; |
|
477
|
0
|
|
|
|
|
0
|
print "SubTMap $_:\n"; |
|
478
|
0
|
|
|
|
|
0
|
my @n = sort {(split/,/,$b)[0] <=> (split/,/,$a)[0]} keys %$subTMap; |
|
|
0
|
|
|
|
|
0
|
|
|
479
|
0
|
|
|
|
|
0
|
for (@n) { |
|
480
|
0
|
|
|
|
|
0
|
my ($cs1, $n1, $cs2, $n2) = split /,/; |
|
481
|
0
|
|
|
|
|
0
|
print " Submapping $cs1 bytes ($n1 times) => " |
|
482
|
|
|
|
|
|
|
."$cs2 bytes ($n2 times):\n" |
|
483
|
|
|
|
|
|
|
; |
|
484
|
0
|
|
|
|
|
0
|
my $s=""; |
|
485
|
0
|
|
|
|
|
0
|
$pat1 = ("%0".($cs1*2)."x ") x $n1; |
|
486
|
0
|
|
|
|
|
0
|
$pat2 = ("%0".($cs2*2)."x ") x $n2; |
|
487
|
0
|
|
|
|
|
0
|
$up1 = ($order[0]->{$cs1}).$n1; |
|
488
|
0
|
|
|
|
|
0
|
$up2 = ($order[0]->{$cs2}).$n2; |
|
489
|
0
|
|
|
|
|
0
|
my $subsubTMap = $subTMap->{$_}; |
|
490
|
0
|
|
|
|
|
0
|
for (sort keys %$subsubTMap) { |
|
491
|
0
|
|
|
|
|
0
|
printf " $pat1 => $pat2\n", |
|
492
|
|
|
|
|
|
|
unpack($up1, $_), |
|
493
|
|
|
|
|
|
|
unpack($up2, $subsubTMap->{$_}) |
|
494
|
|
|
|
|
|
|
; |
|
495
|
|
|
|
|
|
|
} |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
} |
|
498
|
0
|
|
|
|
|
0
|
print "Dumping done.\n\n"; |
|
499
|
|
|
|
|
|
|
} |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
## |
|
502
|
|
|
|
|
|
|
## --- Text (Unicode, Keld) to IMap --------------------------------------- |
|
503
|
|
|
|
|
|
|
## |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
sub _read_text_mapping { |
|
506
|
0
|
|
|
0
|
|
0
|
my ($S, $id, $path, $style) = @_; |
|
507
|
0
|
0
|
|
|
|
0
|
$S->_IMap({}) if !defined $S->_IMap; |
|
508
|
0
|
0
|
0
|
|
|
0
|
return $S->_error("Bad charset id") if (!$id || !$registry{$id}); |
|
509
|
0
|
0
|
0
|
|
|
0
|
if ($style =~ /^keld$/i) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
510
|
0
|
|
|
|
|
0
|
$S->_read_text_keld_to_IMap($id, $path); |
|
511
|
|
|
|
|
|
|
} elsif ($style =~ /^reverse$/i) { |
|
512
|
0
|
|
|
|
|
0
|
$S->_read_text_unicode_to_IMap($id, $path, 2, 1); |
|
513
|
|
|
|
|
|
|
} elsif (!$style || $style=~/^unicode$/i) { |
|
514
|
0
|
|
|
|
|
0
|
$S->_read_text_unicode_to_IMap($id, $path, 1, 2); |
|
515
|
|
|
|
|
|
|
} else { |
|
516
|
0
|
|
|
|
|
0
|
my ($vendor, $unicode) = ($style =~ /^\s*(\d+)\s+(\d+)/); |
|
517
|
0
|
0
|
0
|
|
|
0
|
if ($vendor && $unicode) { |
|
518
|
0
|
|
|
|
|
0
|
$S->_read_text_unicode_to_IMap($id, $path, $vendor, $unicode); |
|
519
|
|
|
|
|
|
|
} else { |
|
520
|
0
|
|
|
|
|
0
|
return $S->_error("Unknown style '$style'"); |
|
521
|
|
|
|
|
|
|
} |
|
522
|
|
|
|
|
|
|
} |
|
523
|
|
|
|
|
|
|
} |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
sub _read_text_keld_to_IMap { |
|
526
|
0
|
|
|
0
|
|
0
|
my ($S, $csid, $path) = @_; |
|
527
|
0
|
|
|
|
|
0
|
my %U = (); |
|
528
|
0
|
|
|
|
|
0
|
my ($k, $v); |
|
529
|
0
|
|
|
|
|
0
|
my $com = ""; my $esc = ""; |
|
|
0
|
|
|
|
|
0
|
|
|
530
|
0
|
0
|
|
|
|
0
|
return 0 unless my @file = $S -> readTextFile ( $path ); |
|
531
|
0
|
|
|
|
|
0
|
while ( @file ) { |
|
532
|
0
|
|
|
|
|
0
|
$_ = shift ( @file ); |
|
533
|
0
|
0
|
|
|
|
0
|
s/$com.*// if $com; |
|
534
|
0
|
0
|
|
|
|
0
|
s/^\s+//; s/\s+$//; next if !$_; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
535
|
0
|
0
|
|
|
|
0
|
last if /^CHARMAP/i; |
|
536
|
0
|
|
|
|
|
0
|
($k, $v) = split /\s+/,$_,2; |
|
537
|
0
|
0
|
|
|
|
0
|
if ($k =~ //i) { $com = $v; next } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
538
|
0
|
0
|
|
|
|
0
|
if ($k =~ //i) { $esc = $v; next } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
539
|
|
|
|
|
|
|
} |
|
540
|
0
|
|
|
|
|
0
|
my (@l, $f, $t); |
|
541
|
0
|
|
|
|
|
0
|
my $escx = $esc."x"; |
|
542
|
0
|
|
|
|
|
0
|
while ( @file ) { |
|
543
|
0
|
|
|
|
|
0
|
$_ = shift ( @file ); |
|
544
|
0
|
0
|
|
|
|
0
|
s/$com.*// if $com; |
|
545
|
0
|
0
|
|
|
|
0
|
next if ! /$escx([^\s]+)\s+]+)/; |
|
546
|
0
|
|
|
|
|
0
|
$U{length($1)*4}->{hex($1)} = hex($2); |
|
547
|
|
|
|
|
|
|
} |
|
548
|
|
|
|
|
|
|
# $S->_dump_IMap(\%U); |
|
549
|
0
|
|
|
|
|
0
|
$S->_IMap->{$csid} = \%U; |
|
550
|
0
|
|
|
|
|
0
|
1} |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
sub readTextFile { |
|
553
|
3
|
|
|
3
|
0
|
9
|
my ( $S, $filePath ) = @_; |
|
554
|
3
|
|
|
|
|
13
|
local $/; |
|
555
|
3
|
50
|
|
|
|
13
|
return $S->_error ( "No text file specified!" ) unless $filePath; |
|
556
|
3
|
50
|
|
|
|
166
|
return $S->_error ( "Can't find text file \"$filePath\"!" ) |
|
557
|
|
|
|
|
|
|
unless -f $filePath |
|
558
|
|
|
|
|
|
|
; |
|
559
|
3
|
50
|
|
|
|
158
|
return $S->_error ( "Cannot open text file \"$filePath\"!" ) |
|
560
|
|
|
|
|
|
|
unless open ( FILE, $filePath ) |
|
561
|
|
|
|
|
|
|
; |
|
562
|
3
|
|
|
|
|
8
|
undef $/; my $file = ; |
|
|
3
|
|
|
|
|
302
|
|
|
563
|
3
|
50
|
|
|
|
87
|
close FILE or warn ( "Oops: can't close file '$filePath'! ($!)" ); |
|
564
|
3
|
|
|
|
|
12904
|
return map "$_\n", split /\r\n|\r|\n/, $file; |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub _read_text_unicode_to_IMap { |
|
568
|
|
|
|
|
|
|
# |
|
569
|
|
|
|
|
|
|
# Converts map files like created by Unicode Inc. to IMap |
|
570
|
|
|
|
|
|
|
# |
|
571
|
3
|
|
|
3
|
|
36
|
no strict; |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
16872
|
|
|
572
|
0
|
|
|
0
|
|
0
|
my ($S, $csid, $file, $row_vendor, $row_unicode) = @_; |
|
573
|
0
|
|
|
|
|
0
|
my %U = (); |
|
574
|
|
|
|
|
|
|
|
|
575
|
0
|
0
|
|
|
|
0
|
return 0 unless my @file = $S -> readTextFile ( $file ); |
|
576
|
|
|
|
|
|
|
|
|
577
|
0
|
|
|
|
|
0
|
my (@l, $f, $t); |
|
578
|
0
|
|
|
|
|
0
|
my $hex = '(?:0x)?([^\s]+)\s+'; |
|
579
|
0
|
|
|
|
|
0
|
my $hexgap = '(?:0x)?[^\s]+\s+'; |
|
580
|
0
|
|
|
|
|
0
|
my ($min, $max) = ($row_vendor, $row_unicode); |
|
581
|
0
|
0
|
|
|
|
0
|
($min, $max) = ($row_unicode, $row_vendor) if $row_unicode<$row_vendor; |
|
582
|
0
|
|
|
|
|
0
|
my $gap1 = $hexgap x ($min - 1); |
|
583
|
0
|
|
|
|
|
0
|
my $gap2 = $hexgap x ($max - $min - 1); |
|
584
|
0
|
0
|
|
|
|
0
|
if ($row_vendor > $row_unicode) { |
|
585
|
0
|
|
|
|
|
0
|
$row_unicode=1; $row_vendor=2; |
|
|
0
|
|
|
|
|
0
|
|
|
586
|
|
|
|
|
|
|
} else { |
|
587
|
0
|
|
|
|
|
0
|
$row_unicode=2; $row_vendor=1; |
|
|
0
|
|
|
|
|
0
|
|
|
588
|
|
|
|
|
|
|
} |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
# Info fields in comments: (at this release still unused) |
|
591
|
0
|
|
|
|
|
0
|
my $Name = ""; |
|
592
|
0
|
|
|
|
|
0
|
my $Unicode_version = ""; |
|
593
|
0
|
|
|
|
|
0
|
my $Table_version = ""; |
|
594
|
0
|
|
|
|
|
0
|
my $Date = ""; |
|
595
|
0
|
|
|
|
|
0
|
my $Authresses = ""; |
|
596
|
|
|
|
|
|
|
|
|
597
|
0
|
|
|
|
|
0
|
my $comment_info = 1; my $comment_authress=0; |
|
|
0
|
|
|
|
|
0
|
|
|
598
|
0
|
|
|
|
|
0
|
while( @file ) { |
|
599
|
0
|
|
|
|
|
0
|
$_ = shift ( @file ); |
|
600
|
0
|
0
|
0
|
|
|
0
|
if ($comment_info && !/#/) { |
|
601
|
0
|
|
|
|
|
0
|
$comment_info = 0; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
0
|
0
|
|
|
|
0
|
if ($comment_info) { |
|
604
|
0
|
0
|
0
|
|
|
0
|
if ($comment_authress && (/^#\s*$/ || /^#[^:]:/)) { |
|
|
|
|
0
|
|
|
|
|
|
605
|
0
|
|
|
|
|
0
|
$comment_authress = 0; |
|
606
|
|
|
|
|
|
|
} |
|
607
|
0
|
0
|
|
|
|
0
|
if (/#\s*name\S*:\s*(.*$)/i) { |
|
608
|
0
|
|
|
|
|
0
|
$Name = $1; |
|
609
|
|
|
|
|
|
|
} |
|
610
|
0
|
0
|
|
|
|
0
|
if (/#\s*unicode\s*version\S*:\s*(.*$)/i) { |
|
611
|
0
|
|
|
|
|
0
|
$Unicode_version = $1; |
|
612
|
|
|
|
|
|
|
} |
|
613
|
0
|
0
|
|
|
|
0
|
if (/#\s*table\s*version\S*:\s*(.*$)/i) { |
|
614
|
0
|
|
|
|
|
0
|
$Table_version = $1; |
|
615
|
|
|
|
|
|
|
} |
|
616
|
0
|
0
|
|
|
|
0
|
if (/#\s*date\S*:\s*(.*$)/i) { |
|
617
|
0
|
|
|
|
|
0
|
$Date = $1; |
|
618
|
|
|
|
|
|
|
} |
|
619
|
0
|
0
|
|
|
|
0
|
if ($comment_authress) { |
|
|
|
0
|
|
|
|
|
|
|
620
|
0
|
0
|
|
|
|
0
|
$Authresses .= ", $1" if /^#\s*(.+$)/; |
|
621
|
|
|
|
|
|
|
} elsif (/#\s*Author\S*:\s*(.*$)/i) { |
|
622
|
0
|
|
|
|
|
0
|
$Authresses = $1; $comment_authress=1; |
|
|
0
|
|
|
|
|
0
|
|
|
623
|
|
|
|
|
|
|
} |
|
624
|
|
|
|
|
|
|
} |
|
625
|
0
|
|
|
|
|
0
|
s/#.*$//; |
|
626
|
0
|
0
|
|
|
|
0
|
next if !$_; |
|
627
|
0
|
0
|
|
|
|
0
|
next if ! /^$gap1$hex$gap2$hex/i; |
|
628
|
0
|
|
|
|
|
0
|
($f, $t) = ($$row_vendor, $$row_unicode); |
|
629
|
0
|
|
|
|
|
0
|
$f =~ s/0x//ig; |
|
630
|
0
|
|
|
|
|
0
|
$t =~ s/0x//ig; |
|
631
|
0
|
0
|
|
|
|
0
|
if ( index($f,"+")>=0 ) { |
|
632
|
|
|
|
|
|
|
# The left side contains one or more "+". Handling this way: |
|
633
|
|
|
|
|
|
|
# The key becomes an 8 bit string. |
|
634
|
0
|
|
|
|
|
0
|
$f =~ s/\s*\+\s*//g; |
|
635
|
0
|
|
|
|
|
0
|
my $fs = pack ( "H*", $f ); |
|
636
|
0
|
0
|
|
|
|
0
|
if (index($t, "+")<0) { |
|
637
|
0
|
|
|
|
|
0
|
my $list = "8,".length($fs); |
|
638
|
0
|
|
|
|
|
0
|
$U { $list } -> { $fs } = hex ( $t ); |
|
639
|
|
|
|
|
|
|
} else { |
|
640
|
0
|
|
|
|
|
0
|
@l = map hex($_), split /\+/, $t; |
|
641
|
0
|
|
|
|
|
0
|
my $list = "8,".length($fs).",".($#l+1); |
|
642
|
0
|
|
|
|
|
0
|
$U { $list } -> { $fs } = [@l]; |
|
643
|
|
|
|
|
|
|
} |
|
644
|
|
|
|
|
|
|
} else { |
|
645
|
0
|
0
|
|
|
|
0
|
if (index($t, "+")<0) { |
|
646
|
0
|
|
|
|
|
0
|
$U{length($f)*4}->{hex($f)} = hex($t); |
|
647
|
|
|
|
|
|
|
} else { |
|
648
|
0
|
|
|
|
|
0
|
@l = map hex($_), split /\+/, $t; |
|
649
|
0
|
|
|
|
|
0
|
$U{(length($f)*4).",1,".($#l+1)}->{hex($f)} = [@l]; |
|
650
|
|
|
|
|
|
|
} |
|
651
|
|
|
|
|
|
|
} |
|
652
|
|
|
|
|
|
|
} |
|
653
|
|
|
|
|
|
|
# $S->_dump_IMap(\%U); |
|
654
|
0
|
|
|
|
|
0
|
$S->_IMap->{$csid} = \%U; |
|
655
|
0
|
|
|
|
|
0
|
1} |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
sub _dump_IMap { |
|
658
|
|
|
|
|
|
|
# |
|
659
|
|
|
|
|
|
|
# Dump IMap |
|
660
|
|
|
|
|
|
|
# |
|
661
|
0
|
|
|
0
|
|
0
|
my ($S, $U) = @_; |
|
662
|
0
|
|
|
|
|
0
|
print "\nDumping IMap entry.\n"; |
|
663
|
0
|
|
|
|
|
0
|
my ($U1, @list); |
|
664
|
0
|
|
|
|
|
0
|
for (keys %{$U}) { |
|
|
0
|
|
|
|
|
0
|
|
|
665
|
0
|
|
|
|
|
0
|
my $size = $_ / 4; |
|
666
|
0
|
|
|
|
|
0
|
$U1 = $U->{$_}; |
|
667
|
0
|
|
|
|
|
0
|
for (sort {$a <=> $b} keys %{$U1}) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
668
|
0
|
|
|
|
|
0
|
printf ((" %0$size"."x => "), $_); |
|
669
|
0
|
0
|
|
|
|
0
|
if (ref($U1->{$_})) { |
|
670
|
0
|
|
|
|
|
0
|
@list = @{$U1->{$_}}; |
|
|
0
|
|
|
|
|
0
|
|
|
671
|
0
|
|
|
|
|
0
|
printf "(".("%04x " x ($#list+1)).")\n", @list; |
|
672
|
|
|
|
|
|
|
} else { |
|
673
|
0
|
|
|
|
|
0
|
printf "%04x\n", $U1->{$_}; |
|
674
|
|
|
|
|
|
|
} |
|
675
|
|
|
|
|
|
|
} |
|
676
|
|
|
|
|
|
|
} |
|
677
|
0
|
|
|
|
|
0
|
1} |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
## |
|
680
|
|
|
|
|
|
|
## --- IMap to binary ----------------------------------------------------- |
|
681
|
|
|
|
|
|
|
## |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
sub _write_IMap_to_binary { |
|
684
|
0
|
|
|
0
|
|
0
|
my ($S, $csid, $path) = @_; |
|
685
|
0
|
0
|
|
|
|
0
|
return $S->_error("Integer Map \"$csid\" not loaded!\n") |
|
686
|
|
|
|
|
|
|
if !(my $IMap = $S->_IMap->{$csid}) |
|
687
|
|
|
|
|
|
|
; |
|
688
|
0
|
0
|
|
|
|
0
|
return $S->_error("Cannot open output table \"$path\"!") |
|
689
|
|
|
|
|
|
|
if !open (MAP4, ">$path"); |
|
690
|
|
|
|
|
|
|
; |
|
691
|
0
|
|
|
|
|
0
|
binmode MAP4; |
|
692
|
0
|
|
|
|
|
0
|
my $str = ""; |
|
693
|
0
|
|
|
|
|
0
|
$str .= _map_binary_begin(); |
|
694
|
0
|
|
|
|
|
0
|
$str .= _map_binary_stream(I_NAME, $S->_to_unicode($csid)); |
|
695
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_BYTE); |
|
696
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_PKV); |
|
697
|
0
|
|
|
|
|
0
|
my ($from, $from_n, $to_n); |
|
698
|
0
|
|
|
|
|
0
|
for (keys %{$IMap}) { |
|
|
0
|
|
|
|
|
0
|
|
|
699
|
0
|
|
|
|
|
0
|
($from, $from_n, $to_n) = split /\s*,\s*/; |
|
700
|
0
|
|
0
|
|
|
0
|
my $subMapping = $S->_map_binary_submapping ( |
|
|
|
|
0
|
|
|
|
|
|
701
|
|
|
|
|
|
|
$IMap->{$_}, $from, $from_n||1, 16, $to_n||1 |
|
702
|
|
|
|
|
|
|
); |
|
703
|
0
|
0
|
|
|
|
0
|
return 0 unless $subMapping; |
|
704
|
0
|
|
|
|
|
0
|
$str .= $subMapping; |
|
705
|
|
|
|
|
|
|
} |
|
706
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_END); |
|
707
|
0
|
|
|
|
|
0
|
print MAP4 "$str"; |
|
708
|
0
|
|
|
|
|
0
|
close (MAP4); |
|
709
|
0
|
|
|
|
|
0
|
1} |
|
710
|
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
sub _to_unicode { |
|
712
|
0
|
|
|
0
|
|
0
|
my ($S, $txt) = @_; |
|
713
|
0
|
|
|
|
|
0
|
$S -> to_unicode ($ENV{LC_CTYPE}, \$txt); |
|
714
|
|
|
|
|
|
|
} |
|
715
|
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
sub _map_binary_begin { |
|
717
|
0
|
|
|
0
|
|
0
|
pack($order[0]->{2}, MAGIC); |
|
718
|
|
|
|
|
|
|
} |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
sub _map_binary_end { |
|
721
|
0
|
|
|
0
|
|
0
|
pack("C", M_END); |
|
722
|
|
|
|
|
|
|
} |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
sub _map_binary_submapping { |
|
725
|
0
|
|
|
0
|
|
0
|
my ($S, $mapH, $size1, $n1, $size2, $n2) = @_; |
|
726
|
0
|
0
|
0
|
|
|
0
|
return $S->_error ("No IMap specified!") if (!$mapH || !%$mapH); |
|
727
|
|
|
|
|
|
|
|
|
728
|
0
|
0
|
|
|
|
0
|
if ($n2*$size2>0xffff) { |
|
729
|
0
|
|
|
|
|
0
|
return $S->_error ("Bad n character mapping! Too many chars!"); |
|
730
|
|
|
|
|
|
|
} |
|
731
|
|
|
|
|
|
|
|
|
732
|
0
|
|
|
|
|
0
|
my $bs1S = $order[0]->{int(($size1+7)/8)}; |
|
733
|
0
|
|
|
|
|
0
|
my $bs2S = $order[0]->{int(($size2+7)/8)}.$n2; |
|
734
|
0
|
0
|
|
|
|
0
|
return $S->_error ("'From' characters have zero size!") if !$bs1S; |
|
735
|
|
|
|
|
|
|
|
|
736
|
0
|
|
|
|
|
0
|
my $str = ""; |
|
737
|
0
|
|
|
|
|
0
|
my $sig = pack ("C4", ($size1, $n1, $size2, $n2)); |
|
738
|
|
|
|
|
|
|
|
|
739
|
0
|
|
|
|
|
0
|
my @key; |
|
740
|
0
|
0
|
|
|
|
0
|
if ( $n1==1 ) { |
|
741
|
0
|
|
|
|
|
0
|
@key = sort {$a <=> $b} keys %$mapH; |
|
|
0
|
|
|
|
|
0
|
|
|
742
|
|
|
|
|
|
|
} else { |
|
743
|
0
|
|
|
|
|
0
|
@key = sort keys %$mapH; |
|
744
|
|
|
|
|
|
|
} |
|
745
|
0
|
|
|
|
|
0
|
my @val = map $mapH->{$_}, @key; |
|
746
|
0
|
|
|
|
|
0
|
my $max = $#key; |
|
747
|
|
|
|
|
|
|
|
|
748
|
0
|
0
|
|
|
|
0
|
if ($n1>1) { |
|
749
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_AKV); |
|
750
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_BYTE); |
|
751
|
0
|
|
|
|
|
0
|
$str .= $sig; |
|
752
|
0
|
|
|
|
|
0
|
my $n = 0; |
|
753
|
0
|
|
|
|
|
0
|
while ( @key ) { |
|
754
|
0
|
0
|
|
|
|
0
|
if ( $n==0 ) { |
|
755
|
0
|
|
|
|
|
0
|
$n = $#key + 1; |
|
756
|
0
|
0
|
|
|
|
0
|
if ( $n>255 ) { |
|
757
|
0
|
|
|
|
|
0
|
$n = 255; |
|
758
|
|
|
|
|
|
|
} |
|
759
|
0
|
|
|
|
|
0
|
$str .= pack ( "C", $n ); |
|
760
|
|
|
|
|
|
|
} |
|
761
|
0
|
|
|
|
|
0
|
$str .= shift ( @key ); |
|
762
|
0
|
|
|
|
|
0
|
my $val = shift ( @val ); |
|
763
|
0
|
0
|
|
|
|
0
|
if ( $n2==1 ) { |
|
764
|
0
|
|
|
|
|
0
|
$str .= pack ( $bs2S, $val ); |
|
765
|
|
|
|
|
|
|
} else { |
|
766
|
0
|
|
|
|
|
0
|
$str .= pack ( $bs2S, @$val ); |
|
767
|
|
|
|
|
|
|
} |
|
768
|
0
|
|
|
|
|
0
|
$n--; |
|
769
|
|
|
|
|
|
|
} |
|
770
|
|
|
|
|
|
|
} else { |
|
771
|
0
|
|
|
|
|
0
|
my ($kkey, $kbegin, $kend, $kn, $vkey, $vbegin, $vend, $vn); |
|
772
|
0
|
0
|
|
|
|
0
|
if ($n2==1) { |
|
773
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_PKV); |
|
774
|
0
|
|
|
|
|
0
|
$str .= $sig; |
|
775
|
0
|
|
|
|
|
0
|
$kkey = _list_to_intervals(\@key, 0, $#key); |
|
776
|
0
|
|
|
|
|
0
|
while (@$kkey) { |
|
777
|
0
|
|
|
|
|
0
|
$kbegin = shift(@$kkey); |
|
778
|
0
|
|
|
|
|
0
|
$kend = shift(@$kkey); |
|
779
|
|
|
|
|
|
|
#print "kbegin=$kbegin kend=$kend klen=".($kend-$kbegin+1)."\n"; |
|
780
|
0
|
|
|
|
|
0
|
$str .= pack("C", $kend-$kbegin+1); |
|
781
|
0
|
|
|
|
|
0
|
$str .= pack($bs1S, $key[$kbegin]); |
|
782
|
0
|
|
|
|
|
0
|
$vkey = _list_to_intervals(\@val, $kbegin, $kend); |
|
783
|
0
|
|
|
|
|
0
|
while (@$vkey) { |
|
784
|
0
|
|
|
|
|
0
|
$vbegin = shift (@$vkey); |
|
785
|
0
|
|
|
|
|
0
|
$vend = shift (@$vkey); |
|
786
|
0
|
|
|
|
|
0
|
$str .= pack("C", $vend-$vbegin+1); |
|
787
|
0
|
|
|
|
|
0
|
$str .= pack($bs2S, $val[$vbegin]); |
|
788
|
|
|
|
|
|
|
} |
|
789
|
|
|
|
|
|
|
} |
|
790
|
|
|
|
|
|
|
} else { |
|
791
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_CVn); |
|
792
|
0
|
|
|
|
|
0
|
$str .= $sig; |
|
793
|
0
|
|
|
|
|
0
|
$kkey = _list_to_intervals(\@key, 0, $#key); |
|
794
|
0
|
|
|
|
|
0
|
while (@$kkey) { |
|
795
|
0
|
|
|
|
|
0
|
$kbegin = shift(@$kkey); |
|
796
|
0
|
|
|
|
|
0
|
$kend = shift(@$kkey); |
|
797
|
0
|
|
|
|
|
0
|
$str .= pack("C", $kend-$kbegin+1); |
|
798
|
0
|
|
|
|
|
0
|
$str .= pack($bs1S, $key[$kbegin]); |
|
799
|
0
|
|
|
|
|
0
|
for ($kbegin..$kend) { |
|
800
|
0
|
|
|
|
|
0
|
$str .= pack($bs2S, @{$val[$_]}); |
|
|
0
|
|
|
|
|
0
|
|
|
801
|
|
|
|
|
|
|
} |
|
802
|
|
|
|
|
|
|
} |
|
803
|
|
|
|
|
|
|
} |
|
804
|
|
|
|
|
|
|
} |
|
805
|
0
|
|
|
|
|
0
|
$str .= _map_binary_mode(M_END); |
|
806
|
0
|
|
|
|
|
0
|
$str; |
|
807
|
|
|
|
|
|
|
} |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
sub _map_binary_mode { |
|
810
|
0
|
|
|
0
|
|
0
|
my ($mode) = @_; |
|
811
|
0
|
|
|
|
|
0
|
return "\0".pack("C", $mode)."\0"; |
|
812
|
|
|
|
|
|
|
} |
|
813
|
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
sub _map_binary_stream { |
|
815
|
0
|
|
|
0
|
|
0
|
my ($mode, $str) = @_; |
|
816
|
0
|
0
|
|
|
|
0
|
if (length($str) > 255) { |
|
817
|
0
|
|
|
|
|
0
|
$str = substr($str, 0, 255); |
|
818
|
|
|
|
|
|
|
} |
|
819
|
0
|
|
|
|
|
0
|
my $len = length($str); |
|
820
|
0
|
|
|
|
|
0
|
return "\0".pack("C2", $mode, $len).$str; |
|
821
|
|
|
|
|
|
|
} |
|
822
|
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
## |
|
824
|
|
|
|
|
|
|
## --- registry file ------------------------------------------------------- |
|
825
|
|
|
|
|
|
|
## |
|
826
|
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
# |
|
828
|
|
|
|
|
|
|
# Registry entries: |
|
829
|
|
|
|
|
|
|
# ALIAS => [a list of equivalent charset ids] |
|
830
|
|
|
|
|
|
|
# INFO => some occult information about this charset |
|
831
|
|
|
|
|
|
|
# MAP => the path to the binary mapfile of this charset |
|
832
|
|
|
|
|
|
|
# SRC => the path to the textual mapfile of this charset |
|
833
|
|
|
|
|
|
|
# SRCURL => an URL where to get the textual mapfile of this charset |
|
834
|
|
|
|
|
|
|
# STYLE => describes what type of textual mapfile this is |
|
835
|
|
|
|
|
|
|
# |
|
836
|
|
|
|
|
|
|
# Registry example: |
|
837
|
|
|
|
|
|
|
# registry = ( |
|
838
|
|
|
|
|
|
|
# "ISO-8859-3" => { |
|
839
|
|
|
|
|
|
|
# "ALIAS" => ["ISO-IR-109","ISO_8859-3:1988","LATIN3","L3"], |
|
840
|
|
|
|
|
|
|
# "INFO" => "", |
|
841
|
|
|
|
|
|
|
# "MAP" => "/usr/lib/perl5/.../Unicode/Map/ISO/8859-3.map", |
|
842
|
|
|
|
|
|
|
# "SRC" => "/usr/local/Unicode/ISO8859/8859-3.TXT", |
|
843
|
|
|
|
|
|
|
# "SRCURL" => "ftp://ftp.unicode.org/MAPPINGS/ISO8859/8859-3.TXT", |
|
844
|
|
|
|
|
|
|
# "STYLE" => "", |
|
845
|
|
|
|
|
|
|
# } |
|
846
|
|
|
|
|
|
|
# ) |
|
847
|
|
|
|
|
|
|
# |
|
848
|
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
sub _load_registry { |
|
850
|
|
|
|
|
|
|
# |
|
851
|
|
|
|
|
|
|
# The REGISTRY loaded once and reused later. Runtime modifications of |
|
852
|
|
|
|
|
|
|
# REGISTRY will remain unnoticed! |
|
853
|
|
|
|
|
|
|
# |
|
854
|
9
|
100
|
|
9
|
|
38
|
return 1 if $registry_loaded; |
|
855
|
3
|
|
|
|
|
8
|
my ($S) = @_; |
|
856
|
3
|
50
|
|
|
|
9
|
$S->_msg("loading unicode registry") if $S->_noise>2; |
|
857
|
3
|
|
|
|
|
15
|
my $path = $S -> _get_path ( "REGISTRY" ); |
|
858
|
3
|
50
|
|
|
|
19
|
return 0 unless my @file = $S -> readTextFile ( $path ); |
|
859
|
|
|
|
|
|
|
|
|
860
|
3
|
|
|
|
|
348
|
my %var = (); |
|
861
|
3
|
|
|
|
|
7
|
my ($k, $v); |
|
862
|
|
|
|
|
|
|
|
|
863
|
3
|
|
|
|
|
13
|
while ( @file ) { |
|
864
|
156
|
|
|
|
|
256
|
$_ = shift ( @file ); |
|
865
|
|
|
|
|
|
|
# Skip everything until DEFINE marker... |
|
866
|
156
|
100
|
|
|
|
336
|
s/#.*//; s/^\s+//; s/\s+$//; next if !$_; |
|
|
156
|
|
|
|
|
278
|
|
|
|
156
|
|
|
|
|
166
|
|
|
|
156
|
|
|
|
|
365
|
|
|
867
|
3
|
50
|
|
|
|
21
|
last if /^DEFINE:/i; |
|
868
|
|
|
|
|
|
|
} |
|
869
|
3
|
|
|
|
|
12
|
while ( @file ) { |
|
870
|
111
|
|
|
|
|
190
|
$_ = shift ( @file ); |
|
871
|
111
|
100
|
|
|
|
234
|
s/#.*//; s/^\s+//; s/\s+$//; next if !$_; |
|
|
111
|
|
|
|
|
230
|
|
|
|
111
|
|
|
|
|
243
|
|
|
|
111
|
|
|
|
|
288
|
|
|
872
|
21
|
100
|
|
|
|
52
|
last if /^DATA:/i; |
|
873
|
18
|
|
|
|
|
78
|
($k, $v) = split /\s*[= ]\s*/,$_,2; |
|
874
|
18
|
|
|
|
|
31
|
$k=~s/^\$//; $v=~s/^"(.*)"$/$1/; |
|
|
18
|
|
|
|
|
84
|
|
|
875
|
18
|
50
|
|
|
|
56
|
if ( defined $ENV{$k} ) { |
|
876
|
|
|
|
|
|
|
# User environment overrides file settings. |
|
877
|
0
|
|
|
|
|
0
|
$v = $ENV { $k }; |
|
878
|
|
|
|
|
|
|
} else { |
|
879
|
18
|
50
|
|
|
|
123
|
if ($v!~s/^'(.*)'$/$1/) { |
|
880
|
18
|
|
|
|
|
21
|
my @check; |
|
881
|
|
|
|
|
|
|
# parse environment |
|
882
|
18
|
|
|
|
|
28
|
@check=(); while ($v=~/\$(\w+|\$)/g) { push (@check, $1) } |
|
|
18
|
|
|
|
|
65
|
|
|
|
9
|
|
|
|
|
36
|
|
|
883
|
18
|
|
|
|
|
33
|
for (@check) { |
|
884
|
9
|
50
|
|
|
|
45
|
if ( defined $ENV{$_} ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
# User environment has ranges before registry and magics. |
|
886
|
0
|
|
|
|
|
0
|
$v =~ s/\$$_/$ENV{$_}/g |
|
887
|
|
|
|
|
|
|
} elsif ( $_ eq '$' ) { |
|
888
|
|
|
|
|
|
|
# Magic value $$ |
|
889
|
3
|
|
|
|
|
42
|
$v =~ s/\$\$/$MAP_Path/; |
|
890
|
|
|
|
|
|
|
} elsif ( defined $var{$_} ) { |
|
891
|
|
|
|
|
|
|
# Apply registry variables |
|
892
|
6
|
|
|
|
|
171
|
$v =~ s/\$$_/$var{$_}/g |
|
893
|
|
|
|
|
|
|
} else { |
|
894
|
|
|
|
|
|
|
# Error, undefined value! |
|
895
|
0
|
|
|
|
|
0
|
warn ("Error in file REGISTRY: Variable '$_' not defined!"); |
|
896
|
0
|
|
|
|
|
0
|
return 0; |
|
897
|
|
|
|
|
|
|
} |
|
898
|
|
|
|
|
|
|
} |
|
899
|
|
|
|
|
|
|
# parse home tilde |
|
900
|
18
|
100
|
66
|
|
|
567
|
if (($v eq '~') || ($v=~/^~\//)) { |
|
901
|
3
|
|
|
|
|
17
|
$v =~ s/^~/_getHomeDir()/e; |
|
|
3
|
|
|
|
|
15
|
|
|
902
|
|
|
|
|
|
|
} |
|
903
|
|
|
|
|
|
|
} |
|
904
|
|
|
|
|
|
|
} |
|
905
|
18
|
|
|
|
|
64
|
$var{$k} = $v; |
|
906
|
|
|
|
|
|
|
} |
|
907
|
3
|
|
|
|
|
8
|
my ($name, $map, $src, $srcURL, $style, @alias, $info); |
|
908
|
3
|
|
|
|
|
26
|
my %arg_s = ( |
|
909
|
|
|
|
|
|
|
"name"=>\$name, "map"=>\$map, "src"=>\$src, "srcurl"=>\$srcURL, |
|
910
|
|
|
|
|
|
|
"style"=>\$style, "info"=>\$info |
|
911
|
|
|
|
|
|
|
); |
|
912
|
3
|
|
|
|
|
13
|
my %arg_a = ("alias"=>\@alias); |
|
913
|
3
|
|
|
|
|
9
|
$name=""; $map=""; $src=""; $srcURL=""; $style=""; @alias=(); $info=""; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
4
|
|
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
8
|
|
|
914
|
3
|
|
|
|
|
13
|
while ( @file ) { |
|
915
|
2250
|
|
|
|
|
3204
|
$_ = shift ( @file ); |
|
916
|
2250
|
|
|
|
|
4060
|
s/#.*//; s/^\s+//; s/\s+$//; |
|
|
2250
|
|
|
|
|
13311
|
|
|
|
2250
|
|
|
|
|
5711
|
|
|
917
|
2250
|
100
|
|
|
|
4457
|
if (!$_) { |
|
918
|
699
|
100
|
|
|
|
1589
|
$S->_add_registry_entry ( |
|
919
|
|
|
|
|
|
|
$name, $src, $map, $srcURL, $style, \@alias, $info |
|
920
|
|
|
|
|
|
|
) if $name; |
|
921
|
699
|
|
|
|
|
973
|
$name=""; $map=""; $src=""; $srcURL=""; $style=""; @alias=(); |
|
|
699
|
|
|
|
|
2251
|
|
|
|
699
|
|
|
|
|
645
|
|
|
|
699
|
|
|
|
|
653
|
|
|
|
699
|
|
|
|
|
683
|
|
|
|
699
|
|
|
|
|
929
|
|
|
922
|
699
|
|
|
|
|
2025
|
$info=""; next; |
|
|
699
|
|
|
|
|
1515
|
|
|
923
|
|
|
|
|
|
|
} |
|
924
|
1551
|
|
|
|
|
10414
|
($k, $v) = split /\s*[: ]\s*/,$_,2; |
|
925
|
1551
|
|
|
|
|
4011
|
for (keys %var) { |
|
926
|
9306
|
|
|
|
|
78720
|
$v =~ s/\$$_/$var{$_}/g; |
|
927
|
|
|
|
|
|
|
} |
|
928
|
1551
|
|
|
|
|
3146
|
$k = lc($k); |
|
929
|
1551
|
100
|
|
|
|
3595
|
if ($arg_s{$k}) { |
|
|
|
50
|
|
|
|
|
|
|
930
|
1092
|
|
|
|
|
1053
|
${$arg_s{$k}} = $v; |
|
|
1092
|
|
|
|
|
3208
|
|
|
931
|
|
|
|
|
|
|
} elsif ($arg_a{$k}) { |
|
932
|
459
|
|
|
|
|
428
|
push (@{$arg_a{$k}}, $v); |
|
|
459
|
|
|
|
|
1484
|
|
|
933
|
|
|
|
|
|
|
} |
|
934
|
|
|
|
|
|
|
} |
|
935
|
3
|
50
|
|
|
|
17
|
$S->_msg_fin("done") if $S->_noise>2; |
|
936
|
3
|
|
|
|
|
8
|
$registry_loaded=1; |
|
937
|
3
|
|
|
|
|
37
|
1} |
|
938
|
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
sub _getHomeDir { |
|
940
|
3
|
50
|
33
|
3
|
|
34
|
$ENV{HOME} |
|
941
|
|
|
|
|
|
|
|| eval ( '(getpwuid($<))[7]' ) # for systems not supporting getpwuid |
|
942
|
|
|
|
|
|
|
|| "/"; |
|
943
|
|
|
|
|
|
|
} |
|
944
|
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
sub _add_registry_entry { |
|
946
|
273
|
|
|
273
|
|
581
|
my ($S, $name, $src, $map, $srcURL, $style, $aliasL, $info) = @_; |
|
947
|
273
|
100
|
100
|
|
|
4949
|
$registry{$name} = { |
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
948
|
|
|
|
|
|
|
"ALIAS" => $aliasL ? [@$aliasL] : [], |
|
949
|
|
|
|
|
|
|
"MAP" => $map || "", |
|
950
|
|
|
|
|
|
|
"INFO" => $info || "", |
|
951
|
|
|
|
|
|
|
"SRC" => $src || "", |
|
952
|
|
|
|
|
|
|
"SRCURL" => $srcURL || "", |
|
953
|
|
|
|
|
|
|
"STYLE" => $style || "", |
|
954
|
|
|
|
|
|
|
}; |
|
955
|
|
|
|
|
|
|
} |
|
956
|
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
sub _dump_registry { |
|
958
|
0
|
|
|
0
|
|
0
|
my ($k, $v); |
|
959
|
0
|
|
|
|
|
0
|
print "\nDumping registry definition:\n"; |
|
960
|
0
|
|
|
|
|
0
|
while (($k, $v) = each %registry) { |
|
961
|
0
|
|
|
|
|
0
|
print "Name: $k\n"; |
|
962
|
0
|
|
|
|
|
0
|
printf " src: %s\n", $v->{"SRC"}; |
|
963
|
0
|
|
|
|
|
0
|
printf " srcURL: %s\n", $v->{"SRC"}; |
|
964
|
0
|
|
|
|
|
0
|
printf " style: %s\n", $v->{"STYLE"}; |
|
965
|
0
|
|
|
|
|
0
|
printf " map: %s\n", $v->{"MAP"}; |
|
966
|
0
|
|
|
|
|
0
|
printf " info: %s\n", $v->{"INFO"}; |
|
967
|
0
|
|
|
|
|
0
|
print " alias: " . join (", ", @{$v->{"ALIAS"}}) . "\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
968
|
0
|
|
|
|
|
0
|
print "\n"; |
|
969
|
|
|
|
|
|
|
} |
|
970
|
0
|
|
|
|
|
0
|
print "done.\n"; |
|
971
|
|
|
|
|
|
|
} |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
## |
|
974
|
|
|
|
|
|
|
## --- misc --------------------------------------------------------------- |
|
975
|
|
|
|
|
|
|
## |
|
976
|
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
sub _get_path { |
|
978
|
3
|
|
|
3
|
|
9
|
my ($S, $path) = @_; |
|
979
|
3
|
50
|
|
|
|
11
|
return $S->_error("Cannot find mapfile base directory!") if !$MAP_Path; |
|
980
|
3
|
|
|
|
|
192
|
$path =~ s/^\/+//; |
|
981
|
3
|
|
|
|
|
14
|
return "$MAP_Path/$path"; |
|
982
|
|
|
|
|
|
|
} |
|
983
|
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
sub _list_to_intervals { |
|
985
|
0
|
|
|
0
|
|
0
|
my ($listR, $start, $end) = @_; |
|
986
|
0
|
|
|
|
|
0
|
my @split = (); |
|
987
|
0
|
|
|
|
|
0
|
my ($begin, $i, $partend); |
|
988
|
0
|
|
|
|
|
0
|
$i=$start; |
|
989
|
0
|
|
|
|
|
0
|
while ($i<=$end) { |
|
990
|
0
|
|
|
|
|
0
|
$begin = $i; |
|
991
|
0
|
|
|
|
|
0
|
$partend = $begin+254; |
|
992
|
0
|
|
0
|
|
|
0
|
while ( |
|
|
|
|
0
|
|
|
|
|
|
993
|
|
|
|
|
|
|
($i<$end) && |
|
994
|
|
|
|
|
|
|
($i<$partend) && |
|
995
|
|
|
|
|
|
|
($listR->[$i+1]==($listR->[$i]+1)) |
|
996
|
|
|
|
|
|
|
) { |
|
997
|
0
|
|
|
|
|
0
|
$i++ |
|
998
|
|
|
|
|
|
|
} |
|
999
|
0
|
|
|
|
|
0
|
push (@split, ($begin, $i)); |
|
1000
|
0
|
|
|
|
|
0
|
$i++; |
|
1001
|
|
|
|
|
|
|
} |
|
1002
|
0
|
|
|
|
|
0
|
\@split; |
|
1003
|
|
|
|
|
|
|
} |
|
1004
|
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
sub _deprecated { |
|
1006
|
13
|
|
|
13
|
|
21
|
my ( $msg ) = @_; |
|
1007
|
13
|
100
|
|
|
|
34
|
if ( $WARNINGS & WARN_DEPRECATION ) { |
|
1008
|
7
|
|
|
|
|
8
|
my $s = "Deprecated usage!"; |
|
1009
|
7
|
100
|
|
|
|
18
|
$s .= " ($msg)" if $msg; |
|
1010
|
7
|
|
|
|
|
991
|
carp ( $s ); |
|
1011
|
|
|
|
|
|
|
} |
|
1012
|
13
|
|
|
|
|
290
|
1} |
|
1013
|
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
sub _incompatible { |
|
1015
|
6
|
|
|
6
|
|
8
|
my ( $msg ) = @_; |
|
1016
|
6
|
50
|
|
|
|
16
|
if ( $WARNINGS & WARN_COMPATIBILITY ) { |
|
1017
|
0
|
|
|
|
|
0
|
my $s = "Incompatible usage!"; |
|
1018
|
0
|
0
|
|
|
|
0
|
$s .= " ($msg)" if $msg; |
|
1019
|
0
|
|
|
|
|
0
|
carp ( $s ); |
|
1020
|
|
|
|
|
|
|
} |
|
1021
|
6
|
|
|
|
|
9
|
1} |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
"Atomkraft? Nein, danke!" |
|
1024
|
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
__END__ |