File Coverage

blib/lib/ExtUtils/Constant.pm
Criterion Covered Total %
statement 107 138 77.5
branch 45 68 66.1
condition 7 23 30.4
subroutine 13 17 76.4
pod 6 9 66.6
total 178 255 69.8


line stmt bran cond sub pod time code
1             package ExtUtils::Constant;
2 1     1   126527 use vars qw (@ISA $VERSION @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         96  
3             $VERSION = '0.24_01';
4             $VERSION = eval $VERSION;
5              
6             =head1 NAME
7              
8             ExtUtils::Constant - generate XS code to import C header constants
9              
10             =head1 SYNOPSIS
11              
12             use ExtUtils::Constant qw (WriteConstants);
13             WriteConstants(
14             NAME => 'Foo',
15             NAMES => [qw(FOO BAR BAZ)],
16             );
17             # Generates wrapper code to make the values of the constants FOO BAR BAZ
18             # available to perl
19              
20             =head1 DESCRIPTION
21              
22             ExtUtils::Constant facilitates generating C and XS wrapper code to allow
23             perl modules to AUTOLOAD constants defined in C library header files.
24             It is principally used by the C utility, on which this code is based.
25             It doesn't contain the routines to scan header files to extract these
26             constants.
27              
28             Memory footprint and run-time performance is not as good as
29             specialized perfect hashes as with L or L.
30              
31             =head1 USAGE
32              
33             Generally one only needs to call the C function, and then
34              
35             #include "const-c.inc"
36              
37             in the C section of C
38              
39             INCLUDE: const-xs.inc
40              
41             in the XS section of C.
42              
43             For greater flexibility use C, C and
44             C, with which C is implemented.
45              
46             Currently this module understands the following types. h2xs may only know
47             a subset. The sizes of the numeric types are chosen by the C
48             script at compile time.
49              
50             =over 4
51              
52             =item IV
53              
54             signed integer, at least 32 bits.
55              
56             =item UV
57              
58             unsigned integer, the same size as I
59              
60             =item NV
61              
62             floating point type, probably C, possibly C
63              
64             =item PV
65              
66             NUL terminated string, length will be determined with C
67              
68             =item PVN
69              
70             A fixed length thing, given as a [pointer, length] pair. If you know the
71             length of a string at compile time you may use this instead of I
72              
73             =item SV
74              
75             A B SV.
76              
77             =item YES
78              
79             Truth. (C) The value is not needed (and ignored).
80              
81             =item NO
82              
83             Defined Falsehood. (C) The value is not needed (and ignored).
84              
85             =item UNDEF
86              
87             C. The value of the macro is not needed.
88              
89             =back
90              
91             =head1 FUNCTIONS
92              
93             =over 4
94              
95             =cut
96              
97             BEGIN {
98 1 50   1   6 if ($] >= 5.006) {
99 1 50   1   44 eval "use warnings; 1" or die $@;
  1         5  
  1         2  
  1         23  
100             }
101             }
102 1     1   6 use strict;
  1         1  
  1         19  
103 1     1   4 use Carp qw(croak cluck);
  1         2  
  1         47  
104              
105 1     1   5 use Exporter;
  1         2  
  1         28  
106 1     1   288 use ExtUtils::Constant::Utils qw(C_stringify);
  1         2  
  1         48  
107 1     1   247 use ExtUtils::Constant::XS qw(%XS_Constant %XS_TypeSet);
  1         4  
  1         1344  
108              
109             @ISA = 'Exporter';
110              
111             %EXPORT_TAGS = ( 'all' => [ qw(
112             XS_constant constant_types return_clause memEQ_clause C_stringify
113             C_constant autoload WriteConstants WriteMakefileSnippet
114             ) ] );
115              
116             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
117              
118             =item constant_types
119              
120             A function returning a single scalar with C<#define> definitions for the
121             constants used internally between the generated C and XS functions.
122              
123             =cut
124              
125             sub constant_types {
126 6     6 1 100 ExtUtils::Constant::XS->header();
127             }
128              
129             sub memEQ_clause {
130 0     0 0 0 cluck "ExtUtils::Constant::memEQ_clause is deprecated";
131 0         0 ExtUtils::Constant::XS->memEQ_clause({name=>$_[0], checked_at=>$_[1],
132             indent=>$_[2]});
133             }
134              
135             sub return_clause ($$) {
136 0     0 0 0 cluck "ExtUtils::Constant::return_clause is deprecated";
137 0         0 my $indent = shift;
138 0         0 ExtUtils::Constant::XS->return_clause({indent=>$indent}, @_);
139             }
140              
141             sub switch_clause {
142 0     0 0 0 cluck "ExtUtils::Constant::switch_clause is deprecated";
143 0         0 my $indent = shift;
144 0         0 my $comment = shift;
145 0         0 ExtUtils::Constant::XS->switch_clause({indent=>$indent, comment=>$comment},
146             @_);
147             }
148              
149             =item C_constant
150              
151             A function to generate the C code in F to implement the
152             perl subroutine I::constant.
153              
154             The C<$what> paramater should be given either as a comma separated
155             list of types that the C subroutine C will generate or as a
156             reference to a hash. It should be the same list of types as
157             C was given. Otherwise C and C
158             may have different ideas about the number of parameters passed to the
159             C function C.
160              
161             =cut
162              
163             sub C_constant {
164 1     1 1 1879459 my ($package, $subname, $default_type, $what, $indent, $breakout, @items)
165             = @_;
166 1         29 ExtUtils::Constant::XS->C_constant({package => $package, subname => $subname,
167             default_type => $default_type,
168             types => $what, indent => $indent,
169             breakout => $breakout}, @items);
170             }
171              
172             =item XS_constant PACKAGE, TYPES, XS_SUBNAME, C_SUBNAME
173              
174             A function to generate the XS code to implement the perl subroutine
175             I::constant used by I::AUTOLOAD to load constants.
176             This XS code is a wrapper around a C subroutine usually generated by
177             C, and usually named C.
178              
179             I should be given either as a comma separated list of types that the
180             C subroutine C will generate or as a reference to a hash. It should
181             be the same list of types as C was given.
182             Otherwise C and C may have different ideas about
183             the number of parameters passed to the C function C.
184              
185             You can call the perl visible subroutine something other than C if
186             you give the parameter I. The C subroutine it calls defaults to
187             the name of the perl visible subroutine, unless you give the parameter
188             I.
189              
190             =cut
191              
192             sub XS_constant {
193 6     6 1 16 my $package = shift;
194 6         10 my $what = shift;
195 6         11 my $XS_subname = shift;
196 6         11 my $C_subname = shift;
197 6   50     16 $XS_subname ||= 'constant';
198 6   33     17 $C_subname ||= $XS_subname;
199              
200 6 50       16 if (!ref $what) {
201             # Convert line of the form IV,UV,NV to hash
202 0         0 $what = {map {$_ => 1} split /,\s*/, ($what)};
  0         0  
203             }
204 6         21 my $params = ExtUtils::Constant::XS->params ($what);
205 6         11 my $type;
206              
207 6         20 my $xs = <<"EOT";
208             void
209             $XS_subname(sv)
210             PREINIT:
211             #ifdef dXSTARG
212             dXSTARG; /* Faster if we have it. */
213             #else
214             dTARGET;
215             #endif
216             STRLEN len;
217             int type;
218             EOT
219              
220 6 100       16 if ($params->{IV}) {
221 5         13 $xs .= " IV iv = 0; /* avoid uninit var warning */\n";
222             } else {
223 1         4 $xs .= " /* IV\t\tiv;\tUncomment this if you need to return IVs */\n";
224             }
225 6 100       23 if ($params->{NV}) {
226 1         2 $xs .= " NV nv = 0.0; /* avoid uninit var warning */\n";
227             } else {
228 5         11 $xs .= " /* NV\t\tnv;\tUncomment this if you need to return NVs */\n";
229             }
230 6 100       14 if ($params->{PV}) {
231 2         4 $xs .= " const char *pv = NULL; /* avoid uninit var warning */\n";
232             } else {
233 4         12 $xs .=
234             " /* const char\t*pv;\tUncomment this if you need to return PVs */\n";
235             }
236              
237 6         13 $xs .= << 'EOT';
238             INPUT:
239             SV * sv;
240             const char * s = SvPV(sv, len);
241             EOT
242 6 100       17 if ($params->{''}) {
243 2         3 $xs .= << 'EOT';
244             INPUT:
245             int utf8 = SvUTF8(sv);
246             EOT
247             }
248 6         13 $xs .= << 'EOT';
249             PPCODE:
250             EOT
251              
252 6 100 75     37 if ($params->{IV} xor $params->{NV}) {
253 4         15 $xs .= << "EOT";
254             /* Change this to $C_subname(aTHX_ s, len, &iv, &nv);
255             if you need to return both NVs and IVs */
256             EOT
257             }
258 6         14 $xs .= " type = $C_subname(aTHX_ s, len";
259 6 100       27 $xs .= ', utf8' if $params->{''};
260 6 100       16 $xs .= ', &iv' if $params->{IV};
261 6 100       15 $xs .= ', &nv' if $params->{NV};
262 6 100       14 $xs .= ', &pv' if $params->{PV};
263 6 100       16 $xs .= ', &sv' if $params->{SV};
264 6         10 $xs .= ");\n";
265              
266             # If anyone is insane enough to suggest a package name containing %
267 6         11 my $package_sprintf_safe = $package;
268 6         18 $package_sprintf_safe =~ s/%/%%/g;
269             # People were actually more insane than thought
270 6 50       20 $package_sprintf_safe =~ s/\x{0}/\\0/g if $] > 5.015006;
271              
272 6         20 $xs .= << "EOT";
273             /* Return 1 or 2 items. First is error message, or undef if no error.
274             Second, if present, is found value */
275             switch (type) {
276             case PERL_constant_NOTFOUND:
277             sv =
278             sv_2mortal(newSVpvf("%s is not a valid $package_sprintf_safe macro", s));
279             PUSHs(sv);
280             break;
281             case PERL_constant_NOTDEF:
282             sv = sv_2mortal(newSVpvf(
283             "Your vendor has not defined $package_sprintf_safe macro %s, used",
284             s));
285             PUSHs(sv);
286             break;
287             EOT
288              
289 6         44 foreach $type (sort keys %XS_Constant) {
290             # '' marks utf8 flag needed.
291 60 100       165 next if $type eq '';
292             $xs .= "\t/* Uncomment this if you need to return ${type}s\n"
293 54 100       121 unless $what->{$type};
294 54         89 $xs .= " case PERL_constant_IS$type:\n";
295 54 100       102 if (length $XS_Constant{$type}) {
296 48         96 $xs .= << "EOT";
297             EXTEND(SP, 1);
298             PUSHs(&PL_sv_undef);
299             $XS_Constant{$type};
300             EOT
301             } else {
302             # Do nothing. return (), which will be correctly interpreted as
303             # (undef, undef)
304             }
305 54         82 $xs .= " break;\n";
306 54 100       101 unless ($what->{$type}) {
307 40         66 chop $xs; # Yes, another need for chop not chomp.
308 40         66 $xs .= " */\n";
309             }
310             }
311 6         21 $xs .= << "EOT";
312             default:
313             sv = sv_2mortal(newSVpvf(
314             "Unexpected return type %d while processing $package_sprintf_safe macro %s, used",
315             type, s));
316             PUSHs(sv);
317             }
318             EOT
319              
320 6         50 return $xs;
321             }
322              
323              
324             =item autoload PACKAGE, VERSION, AUTOLOADER
325              
326             A function to generate the AUTOLOAD subroutine for the module I
327             I is the perl version the code should be backwards compatible with.
328             It defaults to the version of perl running the subroutine. If I
329             is true, the AUTOLOAD subroutine falls back on AutoLoader::AUTOLOAD for all
330             names that the constant() routine doesn't recognise.
331              
332             This is needed unless you use C {autoload=>1}>, but which generates
333             code unusable earlier than 5.8.
334              
335             =cut
336              
337             # ' # Grr. syntax highlighters that don't grok pod.
338              
339             sub autoload {
340 11     11 1 5260 my ($module, $compat_version, $autoloader) = @_;
341 11   33     43 $compat_version ||= $];
342 11 50       39 croak "Can't maintain compatibility back as far as version $compat_version"
343             if $compat_version < 5;
344 11         27 my $func = "sub AUTOLOAD {\n"
345             . " # This AUTOLOAD is used to 'autoload' constants from the constant()\n"
346             . " # XS function.";
347 11 50       42 $func .= " If a constant is not found then control is passed\n"
348             . " # to the AUTOLOAD in AutoLoader." if $autoloader;
349              
350              
351 11         27 $func .= "\n\n"
352             . " my \$constname;\n";
353 11 50       40 $func .=
354             " our \$AUTOLOAD;\n" if ($compat_version >= 5.006);
355              
356 11         37 $func .= <<"EOT";
357             (\$constname = \$AUTOLOAD) =~ s/.*:://;
358             croak "&${module}::constant not defined" if \$constname eq 'constant';
359             my (\$error, \$val) = constant(\$constname);
360             EOT
361              
362 11 50       37 if ($autoloader) {
363 0         0 $func .= <<'EOT';
364             if ($error) {
365             if ($error =~ /is not a valid/) {
366             $AutoLoader::AUTOLOAD = $AUTOLOAD;
367             goto &AutoLoader::AUTOLOAD;
368             } else {
369             croak $error;
370             }
371             }
372             EOT
373             } else {
374 11         31 $func .=
375             " if (\$error) { croak \$error; }\n";
376             }
377              
378 11         25 $func .= <<'END';
379             {
380             no strict 'refs';
381             # Fixed between 5.005_53 and 5.005_61
382             #XXX if ($] >= 5.00561) {
383             #XXX *$AUTOLOAD = sub () { $val };
384             #XXX }
385             #XXX else {
386             *$AUTOLOAD = sub { $val };
387             #XXX }
388             }
389             goto &$AUTOLOAD;
390             }
391              
392             END
393              
394 11         39 return $func;
395             }
396              
397              
398             =item WriteMakefileSnippet
399              
400             WriteMakefileSnippet ATTRIBUTE =E VALUE [, ...]
401              
402             A function to generate perl code for Makefile.PL that will regenerate
403             the constant subroutines. Parameters are named as passed to C,
404             with the addition of C to specify the number of leading spaces
405             (default 2).
406              
407             Currently only C, C, C, C, C and
408             C are recognised.
409              
410             =cut
411              
412             sub WriteMakefileSnippet {
413 0     0 1 0 my %args = @_;
414 0   0     0 my $indent = $args{INDENT} || 2;
415              
416 0         0 my $result = <<"EOT";
417             ExtUtils::Constant::WriteConstants
418             (
419             NAME => '$args{NAME}',
420             NAMES => \\\@names,
421             DEFAULT_TYPE => '$args{DEFAULT_TYPE}',
422             EOT
423 0         0 foreach (qw (C_FILE XS_FILE)) {
424 0 0       0 next unless exists $args{$_};
425             $result .= sprintf " %-12s => '%s',\n",
426 0         0 $_, $args{$_};
427             }
428 0         0 $result .= <<'EOT';
429             );
430             EOT
431              
432 0         0 $result =~ s/^/' 'x$indent/gem;
  0         0  
433             return ExtUtils::Constant::XS->dump_names
434             ({default_type=>$args{DEFAULT_TYPE},
435             indent=>$indent,},
436 0         0 @{$args{NAMES}})
  0         0  
437             . $result;
438             }
439              
440             =item WriteConstants ATTRIBUTE =E VALUE [, ...]
441              
442             Writes a file of C code and a file of XS code which you should C<#include>
443             and C in the C and XS sections respectively of your module's XS
444             code. You probably want to do this in your C, so that you can
445             easily edit the list of constants without touching the rest of your module.
446             The attributes supported are
447              
448             =over 4
449              
450             =item C
451              
452             Name of the module. This must be specified
453              
454             =item C
455              
456             The default type for the constants. If not specified C is assumed.
457              
458             =item C
459              
460             The names of the constants are grouped by length. Generate child subroutines
461             for each group with this number or more names in.
462              
463             =item C
464              
465             An array of constants' names, either scalars containing names, or hashrefs
466             as detailed in L<"C_constant">.
467              
468             =item C
469              
470             If true, uses proxy subs. See L.
471             PROXYSUBS create CONSTSUB's for each defined constant upfront, while
472             without PROXYSUBS every constant is looked up at run-time. Thus it
473             trades memory footprint for faster run-time performance.
474              
475             Options: autoload, push, croak_on_error or croak_on_read with most of
476             the options being exclusive, and croak_on_read usable since 5.24.
477              
478             =item C
479              
480             A filehandle to write the C code to. If not given, then I is opened
481             for writing.
482              
483             =item C
484              
485             The name of the file to write containing the C code. The default is
486             C. The C<-> in the name ensures that the file can't be
487             mistaken for anything related to a legitimate perl package name, and
488             not naming the file C<.c> avoids having to override Makefile.PL's
489             C<.xs> to C<.c> rules.
490              
491             =item C
492              
493             A filehandle to write the XS code to. If not given, then I is opened
494             for writing.
495              
496             =item C
497              
498             The name of the file to write containing the XS code. The default is
499             C.
500              
501             =item C
502              
503             The perl visible name of the XS subroutine generated which will return the
504             constants. The default is C.
505              
506             =item C
507              
508             The name of the C subroutine generated which will return the constants.
509             The default is I. Child subroutines have C<_> and the name
510             length appended, so constants with 10 character names would be in
511             C with the default I.
512              
513             =back
514              
515             =cut
516              
517             sub WriteConstants {
518 13     13 1 22292664 my %ARGS =
519             ( # defaults
520             C_FILE => 'const-c.inc',
521             XS_FILE => 'const-xs.inc',
522             XS_SUBNAME => 'constant',
523             DEFAULT_TYPE => 'IV',
524             @_);
525              
526 13   33     142 $ARGS{C_SUBNAME} ||= $ARGS{XS_SUBNAME}; # No-one sane will have C_SUBNAME eq '0'
527              
528 13 50       66 croak "Module name not specified" unless length $ARGS{NAME};
529              
530             # Do this before creating (empty) files, in case it fails:
531 13 100       817 require ExtUtils::Constant::ProxySubs if $ARGS{PROXYSUBS};
532              
533 13         34 my $c_fh = $ARGS{C_FH};
534 13 50       43 if (!$c_fh) {
535 0 0       0 if ($] <= 5.008) {
536             # We need these little games, rather than doing things
537             # unconditionally, because we're used in core Makefile.PLs before
538             # IO is available (needed by filehandle), but also we want to work on
539             # older perls where undefined scalars do not automatically turn into
540             # anonymous file handles.
541 0         0 require FileHandle;
542 0         0 $c_fh = FileHandle->new();
543             }
544 0 0       0 open $c_fh, ">", $ARGS{C_FILE} or die "Can't open $ARGS{C_FILE}: $!";
545             }
546              
547 13         32 my $xs_fh = $ARGS{XS_FH};
548 13 50       35 if (!$xs_fh) {
549 0 0       0 if ($] <= 5.008) {
550 0         0 require FileHandle;
551 0         0 $xs_fh = FileHandle->new();
552             }
553 0 0       0 open $xs_fh, ">", $ARGS{XS_FILE} or die "Can't open $ARGS{XS_FILE}: $!";
554             }
555              
556             # As this subroutine is intended to make code that isn't edited, there's no
557             # need for the user to specify any types that aren't found in the list of
558             # names.
559            
560 13 100       56 if ($ARGS{PROXYSUBS}) {
561 7         21 $ARGS{C_FH} = $c_fh;
562 7         23 $ARGS{XS_FH} = $xs_fh;
563 7         116 ExtUtils::Constant::ProxySubs->WriteConstants(%ARGS);
564             } else {
565 6         20 my $types = {};
566              
567 6         39 print $c_fh constant_types(); # macro defs
568 6         77 print $c_fh "\n";
569              
570             # indent is still undef. Until anyone implements indent style rules with
571             # it.
572 6         102 foreach (ExtUtils::Constant::XS->C_constant
573             ({package => $ARGS{NAME},
574             subname => $ARGS{C_SUBNAME},
575             default_type =>
576             $ARGS{DEFAULT_TYPE},
577             types => $types,
578             breakout =>
579             $ARGS{BREAKOUT_AT}},
580 6         64 @{$ARGS{NAMES}}))
581             {
582 16         130 print $c_fh $_, "\n"; # C constant subs
583             }
584             print $xs_fh XS_constant ($ARGS{NAME}, $types, $ARGS{XS_SUBNAME},
585 6         93 $ARGS{C_SUBNAME});
586             }
587              
588 13 50 0     320 close $c_fh or warn "Error closing $ARGS{C_FILE}: $!" unless $ARGS{C_FH};
589 13 50 0     78 close $xs_fh or warn "Error closing $ARGS{XS_FILE}: $!" unless $ARGS{XS_FH};
590             }
591              
592             1;
593             __END__