File Coverage

blib/lib/Biblio/bp/lib/bp-p-dload.pl
Criterion Covered Total %
statement 80 126 63.4
branch 39 82 47.5
condition 5 9 55.5
subroutine 4 5 80.0
pod n/a
total 128 222 57.6


line stmt bran cond sub pod time code
1             #
2             # bibliography package for Perl
3             #
4             # The dynamic format and character set loading.
5             #
6             # Dana Jacobsen (dana@acm.org)
7             # 22 January 1995 (last modified 14 March 1996)
8              
9              
10             # load_format safely loads a format. It calls goterror if it can't find the
11             # format, and returns that result (undef). Be sure to check the result! It
12             # is not meant for users to call (although it doesn't hurt anything).
13             #
14             # It also loads a character set -- either the default for the format, or one
15             # asked for by name.
16             #
17             # It returns an array of two values:
18             # the format name, appropriate for use with the formats array
19             # the cset name, for use with the charsets array
20             #
21             # Thus, load_format will find, say "myRefer" and return "refer" if that is
22             # how the format is installed.
23             #
24             # XXXXX Should we install them as the name they gave us, or the format's name?
25             # XXXXX How about changing this so we can load formats like:
26             # '/usr/local/lib/formats/refer"
27             # XXXXX Added options as "format/opt1/opt2:cset"
28             # We don't support cset options, and won't until csets are 1st class.
29             #
30             sub load_format {
31 280     280   436 local($format) = @_;
32 280         409 local($fmt, $cset);
33 280         379 local(@opts);
34              
35 280 50       687 &panic("load_format called with no arguments") unless defined $format;
36            
37             # print "load_format $format\n";
38 280         611 ($fmt, $cset) = &parse_format($format);
39              
40 280         953 &debugs("fmt: $fmt, cset: ".&okprint($cset), 16384);
41              
42             # check the common case first
43 280 100 100     1907 if ( (defined $formats{$fmt, 'i_name'})
      66        
44             && (!defined $cset)
45             && ($fmt !~ /\//)
46             ) {
47 7         60 return ($formats{$fmt, 'i_name'}, $formats{$fmt, 'i_charset'});
48             }
49              
50 273         1005 while ($fmt =~ s/\/([^\/]+)$//) {
51 0         0 push(@opts, $1);
52             }
53 273         1012 &debugs("loading format $fmt...", 1024);
54 273         370 $glb_current_fmt = $fmt;
55             # XXXXX Should we set the error level to die before doing this?
56 273         488 $func = "require \"$glb_bpprefix$fmt.pl\";";
57 273         15827 eval $func;
58 273 50       967 if ($@) {
59 0 0       0 if ($@ =~ /^Can't locate $glb_bpprefix/) {
60 0         0 return &goterror("format $fmt is not supported.");
61             }
62 0 0       0 if ($@ =~ /^bp error /) {
63 0         0 print STDERR $@;
64 0         0 return &goterror("error in format $fmt", "module");
65             }
66 0         0 return &goterror("error in format $fmt: $@", "module");
67             }
68              
69 273 50       620 if (@opts) {
70 0         0 $func = $formats{$fmt, "options"};
71 0         0 local($opt, $ret);
72 0         0 foreach $opt (@opts) {
73 0         0 $ret = &$func($opt);
74 0 0       0 next if defined $ret;
75 0         0 &gotwarn("Unknown $fmt option: $opt");
76             }
77             }
78              
79             # We make sure our format name is the right one.
80             # XXXXX right now we don't do anything. We should get this from register.
81              
82             # use the format's default character set unless they asked for one.
83 273 100       578 $cset = $formats{$fmt, 'i_charset'} unless defined $cset;
84              
85             # XXXXX We will die right here if the charset isn't named correctly
86              
87 273         708 $cset = &load_charset($cset);
88              
89 273         1137 &debugs("loaded format $fmt, cset $cset", 1024);
90              
91 273         1639 ($fmt, $cset);
92             }
93              
94             #
95             # This loads a character set. It returns the correct name of the character
96             # set.
97             #
98             sub load_charset {
99 273     273   540 local($cset) = @_;
100              
101 273 50       649 &panic("load_charset called with no arguments") unless defined $cset;
102              
103 273         920 &debugs("cset: $cset", 8192);
104              
105 273 100       1273 return $cset if defined $charsets{$cset, 'i_name'};
106              
107             # XXXXX auto charset is unimplemented, so don't try to load it
108 10 100       36 return $cset if $cset eq "auto";
109              
110 8         30 &debugs("loading charset $cset...", 1024);
111 8         14 $glb_current_cset = $cset;
112 8         20 $func = "require \"${glb_bpprefix}cs-$cset.pl\";";
113 8         454 eval $func;
114 8 50       41 if ($@) {
115 0 0       0 if ($@ =~ /^Can't locate $glb_bpprefix/) {
116 0         0 return &goterror("character set $cset is not supported.");
117             }
118 0         0 return &goterror("error in character set $cset: $@", "module");
119             }
120             # XXXXX get real name from register
121 8         38 &debugs("loaded charset $cset", 1024);
122 8         20 $cset;
123             }
124              
125             #
126             # load_converter returns either the name of the converter or undef.
127             #
128             sub load_converter {
129 5     5   14 local($conv) = @_;
130              
131 5 50       25 &panic("load_converter called with no arguments") unless defined $conv;
132              
133 5         18 &debugs("conv: $conv", 8192);
134              
135 5 50       20 return $conv if defined $special_converters{$conv, 'i_name'};
136            
137 5         21 &debugs("loading converter $conv...", 1024);
138 5         17 $func = "require \"${glb_bpprefix}c-$conv.pl\";";
139 5         304 eval $func;
140 5 50       31 if ($@) {
141 5 50       76 if ($@ =~ /^Can't locate $glb_bpprefix/) {
142 5         24 &debugs("converter $conv not found", 1024);
143 5         17 return undef;
144             } else {
145 0         0 return &goterror("error in converter $glb_cvtname: $@", "module");
146             }
147             }
148 0         0 &debugs("loaded converter $conv", 1024);
149 0         0 $conv;
150             }
151              
152             ######
153              
154             sub find_bp_files {
155 0     0   0 local($rehash) = @_;
156              
157 0 0 0     0 if ( (defined $rehash) && ($rehash eq 'rehash') ) {
158 0         0 undef $glb_supported_files;
159             }
160              
161 0 0       0 if (!defined $glb_supported_files) {
162 0         0 local(*DIR);
163 0         0 local(@bpfiles);
164 0         0 local($path, $fmts, $csets);
165 0         0 local(%uniar);
166              
167 0         0 foreach $path (@INC) {
168 0         0 opendir(DIR, $path);
169 0         0 push(@bpfiles, grep(/^${glb_bpprefix}.*\.pl$/, readdir(DIR)) );
170 0         0 closedir(DIR);
171             }
172             # remove the header and trailer stuff
173 0         0 grep(s/^${glb_bpprefix}(.*)\.pl$/$1/, @bpfiles);
174              
175             # remove our packages
176 0         0 @bpfiles = grep(!/^p-\w+$/, @bpfiles);
177             # remove styles
178 0         0 @bpfiles = grep(!/^s-\w+$/, @bpfiles);
179              
180             # weed out duplicates (if packages are in multiple paths)
181 0         0 @bpfiles = grep($uniar{$_}++ == 0, @bpfiles);
182              
183             # now return formats and csets
184 0         0 $fmts = join(" ", sort grep(!/^cs-/, @bpfiles));
185 0         0 $csets = join(" ", sort grep(s/^cs-//, @bpfiles));
186              
187 0         0 $glb_supported_files = join("\000", $fmts, $csets);
188             }
189              
190 0         0 split("\000", $glb_supported_files);
191             }
192              
193             ######
194              
195             #
196             # The format registry subroutine.
197             #
198             # When a format starts up, it calls this routine, which registers all its
199             # exported procedures to bp. If any of the necessary functions are not
200             # given as arguments, they will default to the stdbib routines. If you
201             # know about a stdbib routine, it is suggested that you actually call this
202             # using the "foo is standard" method of registering foo, so people can see
203             # right off that you mean it, not that you just forgot. This also allows
204             # us to add functions (for example, maybe "readcanon" that reads right into
205             # canonical format) and then define a stdbib routine that would do the
206             # equivalent the long way around. Your module continues to work, because
207             # the registry will see that you didn't define one, and set up the mapping.
208              
209             # There are seven different formats for the function registry:
210             #
211             # "read is standard" registers read as the standard read routine.
212             # "read" registers read as your function of the same name.
213             # "read uses format" registers read as format's read.
214             # "read as myread" registers read as your function named "myread".
215             # "read as pkg'myread" registers read as the function "pkg'myread".
216             # "read is unsupported" registers read as an unsupported function.
217             # "read is unimplemented" registers read as an unimplemented function.
218             #
219             # Examples:
220             # "write is standard"
221             # Our format is going to use the standard write function, which prints
222             # the record with a single empty line after it.
223             # "read"
224             # Our format has it's own read function, declared with "sub read".
225             # "read uses refer"
226             # Our format will use whatever read function the refer format uses to
227             # do its reading. This will also take care of loading the refer format
228             # for you. Use this style when your format has a lot of similarities
229             # to one particular format. Don't use it otherwise, as it would waste
230             # time and memory loading a format that isn't needed.
231             # "read as lukea"
232             # Just in case you like naming your functions in Finnish, for example.
233             # "read as bp_refer'read"
234             # Not really recommended, but this lets you give the full name of the
235             # function you want called.
236             # "read is unsupported"
237             # This makes it explicit to anyone looking at your module code that
238             # you purposely do not support this function. It sets any call to
239             # this routine to code that returns an error message about the
240             # procedure not being supported.
241             # "read is unimplemented"
242             # This makes it explicit to anyone looking at your module code that
243             # you have not finished coding this function. Similarly to the
244             # unsupported option, this produces an error message about the procedure
245             # having not yet been implemented.
246             #
247             # For the unsupported and unimplemented calls, you may also wish to define
248             # your own call that does the same thing but gives more information.
249             #
250              
251             # On success, we return 1. If we couldn't parse your strings, or one of the
252             # functions given doesn't exist, we return undef. Your format should return
253             # undef if you are unable to register yourself.
254              
255             # XXXXX document suffix registration
256              
257             sub reg_format {
258 6     6   48 local($lname, $sname, $pname, $cname, @rest) = @_;
259              
260 6 50       28 &panic("reg_format called with no longname") unless defined $lname;
261 6 50       19 &panic("reg_format called with no shortname") unless defined $sname;
262 6 50       17 &panic("reg_format called with no package name") unless defined $pname;
263 6 50       15 &panic("reg_format called with no default charset") unless defined $cname;
264 6 50       33 &panic("Format $lname already registered") if defined $formats{$lname, 'i_name'};
265              
266 6         40 &debugs("registering format $lname:$cname ($sname) in $pname", 16384);
267              
268 6         27 $formats{$lname, 'i_name'} = $lname;
269 6         26 $formats{$lname, 'i_sname'} = $sname;
270 6         20 $formats{$lname, 'i_package'} = $pname;
271 6         17 $formats{$lname, 'i_charset'} = $cname;
272              
273             # Go through all of our functions, and assign to stdbib.
274              
275 6         18 foreach $f ( @glb_expfuncs ) {
276 60         182 $formats{$lname, $f} = "bib'${f}_stdbib";
277             }
278              
279             # next, walk through all the arguments they gave us
280              
281 6         21 local($f, $p, $as, $uses, $inst);
282 6         10 local(%seen); # check for duplicate definitions
283 6         15 foreach (@rest) {
284 66         81 $inst = undef;
285 66         223 s/\s+/ /g; # so the string can be spaced however one wants
286 66 100       471 if ( ($f) = /^suffix is (\w+)$/) {
    100          
    100          
    100          
    50          
    0          
    0          
    0          
287 6         21 $formats{$lname, 'i_suffix'} = $f;
288 6         17 next;
289             } elsif ( ($f) = /^(\w+) is standard$/) {
290 18         128 $inst = "bib'${f}_stdbib";
291             } elsif ( ($f, $p) = /^(\w+) is unimplemented$/) {
292 2         7 $inst = "bib'${f}_unimpl_stdbib";
293 2 50       13 if (!defined &$inst) {
294 0         0 $inst = "bib'generic_unimpl_stdbib";
295             }
296             } elsif ( ($f, $p) = /^(\w+) is unsupported$/) {
297 14         26 $inst = "bib'${f}_unsup_stdbib";
298 14 100       63 if (!defined &$inst) {
299 6         19 $inst = "bib'generic_unsup_stdbib";
300             }
301             } elsif ( ($f) = /^(\w+)$/) {
302 26         53 $inst = $pname . "'" . $f;
303             } elsif ( ($f, $uses) = /^(\w+) uses (\w+)$/) {
304 0 0       0 if (!defined $formats{$uses, $f}) {
305 0 0       0 return &goterror("Could not load format $uses") unless &load_format($uses);
306             }
307 0         0 $inst = $formats{$uses, $f};
308             } elsif ( ($f, $p, $as) = /^(\w+) as (\w+)'(\w+)$/) {
309 0         0 $inst = $p . "'" . $as;
310             } elsif ( ($f, $as) = /^(\w+) as (\w+)$/) {
311 0         0 $inst = $pname . "'" . $as;
312             } else {
313 0         0 return &goterror("Format register unable to parse '$_'", $glb_current_fmt);
314             }
315 60 50       192 return &goterror("Tried to register unknown function $f", $glb_current_fmt)
316             unless defined $formats{$lname, $f};
317 60 50       189 return &bib'goterror("$f function '$inst' does not exist", $glb_current_fmt)
318             unless defined &$inst;
319 60 50       136 return &bib'goterror("duplicate registration of function $f", $glb_current_fmt)
320             if defined $seen{$f};
321 60         113 $seen{$f} = 1;
322 60         132 $formats{$lname, $f} = $inst;
323             }
324 6         17 foreach $f ( @glb_expfuncs ) {
325 60         240 &debugs("$lname registered $f as $formats{$lname, $f}", 16);
326             #printf STDERR "%-12s registered to $lname as %s\n", $f, $formats{$lname, $f};
327 60 50       153 &gotwarn("Using default behavior for function $f", $glb_current_fmt)
328             unless defined $seen{$f};
329             }
330 6 50       26 $formats{$lname, 'i_suffix'} = $sname unless defined $formats{$lname, 'i_suffix'};
331              
332 6         36 1;
333             }
334              
335             # XXXXX We should have an "unreg_format" function to unregister a format.
336             # This could be used to remap formats through an option.
337              
338             1;