| 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__ |