correct wrong option flag of BerkeleyDB.
[chise/perl.git] / Chise_utils / Chise_utils.pm
1 package Chise_utils;
2
3 require 5.008;
4 use strict;
5 use warnings;
6
7 require Exporter;
8
9 use utf8;
10 use BerkeleyDB;
11 use vars qw(%db %chardb
12             %reverse_db %reverse_chardb
13             %er_alias $er_prefix_re
14             $atr $idc
15             $omegadb_path
16         );
17
18 our @ISA = qw(Exporter);
19
20 # Items to export into callers namespace by default. Note: do not export
21 # names by default without a very good reason. Use EXPORT_OK instead.
22 # Do not simply export all your public functions/methods/constants.
23
24 # This allows declaration       use Chise_utils ':all';
25 # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
26 # will save memory.
27 our %EXPORT_TAGS = ( 'all' => [ qw(
28                                    %db %chardb
29                                    %reverse_db %reverse_chardb
30                                    $idc
31                                    %er_alias $er_prefix_re
32                                    $omegadb_path
33                                    &get_db
34                                    &get_reverse_db
35                                    &get_char_attribute
36                                    &get_chars_matching
37                                    &get_chars_containing
38                                    &get_chars_for
39                                    &de_er
40                                    &ids_argc
41 ) ] );
42
43 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
44
45 our @EXPORT = qw(
46 );
47 our $VERSION = '0.02';
48
49
50 # Preloaded methods go here.
51
52 $omegadb_path="/usr/local/lib/chise/omega";
53
54 my $DB_HOME="";
55 unless($DB_HOME){
56     if(-e '/usr/local/lib/chise/chise-db'){
57         $DB_HOME='/usr/local/lib/chise/chise-db';
58     }elsif(-e '/usr/lib/chise/chise-db'){
59         $DB_HOME='/usr/lib/chise/chise-db';
60     }elsif(-e '/usr/local/lib/chise/char-db'){
61         $DB_HOME='/usr/local/lib/chise/char-db';
62     }elsif(-e 'd:/work/chise/char-db'){
63         $DB_HOME='d:/work/chise/char-db';
64     }else{
65         print STDERR "No database found.\n";
66         print STDERR "Pleas set \$DB_HOME to Chise_utils.pm.\n";
67         exit 1;
68     }
69 }
70
71 $idc="\x{2ff0}-\x{2fff}";
72
73 %er_alias =
74     ('C1','=cns11643-1',
75      'C2','=cns11643-2',
76      'C3','=cns11643-3',
77      'C4','=cns11643-4',
78      'C5','=cns11643-5',
79      'C6','=cns11643-6',
80      'C7','=cns11643-7',
81      'CB','=cbeta',
82      'CDP','=big5-cdp',
83      'GT','=gt',
84      'GT-K','=gt-k',
85      'HZK1','=hanziku-1',
86      'HZK2','=hanziku-2',
87      'HZK3','=hanziku-3',
88      'HZK4','=hanziku-4',
89      'HZK5','=hanziku-5',
90      'HZK6','=hanziku-6',
91      'HZK7','=hanziku-7',
92      'HZK8','=hanziku-8',
93      'HZK9','=hanziku-9',
94      'HZK10','=hanziku-10',
95      'HZK11','=hanziku-11',
96      'HZK12','=hanziku-12',
97      'J78','=jisx0208-1978',
98      'J83','=jisx0208',
99      'J90','=jisx0208-1990',
100      'JSP','=jisx0212',
101      'JX1','=jisx0213-1',
102      'JX2','=jisx0213-2',
103      'K0','=ks-x1001',
104      'M','=daikanwa',
105      );
106
107 $er_prefix_re=join '|', keys %er_alias;
108
109 if(-d "$DB_HOME/character"){
110     for (glob "$DB_HOME/character/feature/*"){
111         next if(/\.txt$/);
112         $atr=$_;
113         $atr=~s!$DB_HOME/character/feature/!!;
114         $db{$atr}=$_;
115     }
116     for (glob "$DB_HOME/character/by_feature/*"){
117         next if(/\.txt$/);
118         $atr=$_;
119         $atr=~s!$DB_HOME/character/by_feature/!!;
120         $reverse_db{$atr}=$_;
121     }
122 }elsif(-d "$DB_HOME/system-char-id"){
123     for (glob "$DB_HOME/system-char-id/*"){
124         next if(/\.txt$/);
125         $atr=$_;
126         $atr=~s!$DB_HOME/system-char-id/!!;
127         $db{$atr}=$_;
128     }
129     for (glob "$DB_HOME/*"){
130         next if(/\.txt$/ or /system-char-id/);
131         $atr=$_;
132         $atr=~s!$DB_HOME/!!;
133         $reverse_db{$atr}=$_."/system-char-id";
134     }
135 }else{
136     print STDERR "No database found.\n";
137     print STDERR "Pleas set \$DB_HOME to Chise_utils.pm correctly.\n";
138     exit 1;
139 }
140
141 sub get_db{
142     my($atr)=@_;
143     return 1 if(defined(%{$chardb{$atr}}));
144     if(defined($db{$atr}) and -f $db{$atr}){
145         tie %{$chardb{$atr}}, "BerkeleyDB::Hash",
146         -Filename => $db{$atr},
147         -Flags => DB_RDONLY;
148     }else{
149         return undef;
150     }
151 }
152
153 sub get_reverse_db{
154     my($atr)=@_;
155     return 1 if(defined(%{$reverse_chardb{$atr}}));
156     if(defined($reverse_db{$atr}) and -f $reverse_db{$atr}){
157         tie %{$reverse_chardb{$atr}}, "BerkeleyDB::Hash",
158         -Filename => $reverse_db{$atr},
159         -Flags => DB_RDONLY;
160     }else{
161         return undef;
162     }
163 }
164
165
166 sub get_char_attribute{
167     my($char,$atr)=@_;
168     my($res);
169     &get_db($atr) or return "";
170     if($res=$chardb{$atr}->{"?$char"}){
171         utf8::decode($res);
172         return $res;
173     }else{
174         return "";
175     }
176 }
177
178 sub get_chars_containing{
179     my($atr,$value)=@_;
180     my($char,@res);
181     if(&get_db($atr)){
182         foreach $char (keys %{$chardb{$atr}}){
183             if($chardb{$atr}->{$char}=~/$value/){
184                 utf8::decode($char);
185                 $char=~s/^\?//;
186                 push @res,$char;
187             }
188         }
189     }
190     return @res;
191 }
192
193 sub get_chars_matching{
194     my($atr,$value)=@_;
195     my($char,@res);
196     if(defined($reverse_db{$atr})){
197         if(&get_reverse_db($atr)){
198             if($char=$reverse_chardb{$atr}->{$value}){
199                 utf8::decode($char);
200                 $char=~s/^\?//;
201                 push @res,$char;
202             }
203         }
204     }
205     else{
206 #   never fall back.
207 #    unless(@res){
208 #    # fall back if DB inconsistency exists.
209         if(&get_db($atr)){
210             foreach $char (keys %{$chardb{$atr}}){
211                 if($chardb{$atr}->{$char} eq $value){
212                     utf8::decode($char);
213                     $char=~s/^\?//;
214                     push @res,$char;
215                 }
216             }
217         }
218     }
219     return @res;
220 }
221
222 sub get_chars_for{
223     my($query)=@_;
224     my @q=split(",",$query);
225     my(%res,@res,$atr,$value);
226     my $i=0;
227     foreach $query (@q){
228         if($query=~/=~/){
229             ($atr,$value)=split("=~",$query,2);
230             $i++;
231             foreach (&get_chars_containing($atr,$value)){
232                 $res{$_}++;
233             }
234         }elsif($query=~/==/){
235             ($atr,$value)=split(/==/,$query,2);
236             $i++;
237             foreach (&get_chars_matching($atr,$value)){
238                 $res{$_}++;
239             }
240         }
241     }
242     return grep {defined($res{$_}) and $res{$_}==$i} (keys %res);
243 }
244
245 sub de_er{
246     my($er)=@_;
247     my($output_char,$atr,$value);
248     my($prefix,$suffix);
249     $er=~/^(amp|&)?(.+?)(;)?$/
250         and $prefix=$1,$er=$2,$suffix=$3;
251     $prefix or $prefix="",$suffix or $suffix="";
252     if($prefix eq 'amp'){$prefix="",$suffix="";}
253     if($er=~/^\d+$/){
254         $output_char=pack("U",$er);
255     }elsif($er=~/^U[\+\-]([a-fA-F\d]+)/){
256         $output_char=pack("U",hex($1));
257     }elsif($er=~/^(?:I\-)?($er_prefix_re)\-?([0-9a-fA-F]+)$/){
258         ($atr,$value)=($1,$2);
259         if($er_alias{$atr}=~/daikanwa|gt/){
260             $value+=0;
261         }else{
262             $value=hex($value);
263         }
264         ($output_char)=&get_chars_matching($er_alias{$atr},$value);
265     }
266     if($output_char){
267         return $output_char;
268     }else{
269         return $prefix.$er.$suffix;
270     }
271 }
272
273 sub ids_argc{
274     my($char)=@_;
275     my $char_id=unpack("U",$char);
276     if($char_id==0x2ff2 or $char_id==0x2ff3){
277         return 3;
278     }elsif($char_id>=0x2ff0 and $char_id<=0x2fff){
279         return 2;
280     }else{
281         return 0;
282     }
283 }
284
285 # Autoload methods go after =cut, and are processed by the autosplit program.
286
287 1;
288 __END__
289 # Below is stub documentation for your module. You better edit it!
290
291 =head1 NAME
292
293 Chise_utils - Perl extension for blah blah blah
294
295 =head1 SYNOPSIS
296
297   use Chise_utils;
298   blah blah blah
299
300 =head1 DESCRIPTION
301
302 Stub documentation for Chise_utils, created by h2xs. It looks like the
303 author of the extension was negligent enough to leave the stub
304 unedited.
305
306 Blah blah blah.
307
308 =head2 EXPORT
309
310 None by default.
311
312
313 =head1 AUTHOR
314
315 A. U. Thor, a.u.thor@a.galaxy.far.far.away
316
317 =head1 SEE ALSO
318
319 perl(1).
320
321 =cut