SYN SYN
[p5sagit/p5-mst-13.2.git] / utils / h2xs.PL
CommitLineData
4633a7c4 1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
8a5546a1 5use Cwd;
4633a7c4 6
7# List explicitly here the variables you want Configure to
8# generate. Metaconfig only looks for shell variables, so you
9# have to mention them as if they were shell variables, not
10# %Config entries. Thus you write
11# $startperl
12# to ensure Configure will look for $Config{startperl}.
13
14# This forces PL files to create target in same directory as PL file.
15# This is so that make depend always knows where to find PL derivatives.
4b19af01 16my $origdir = cwd;
44a8e56a 17chdir dirname($0);
4b19af01 18my $file = basename($0, '.PL');
774d564b 19$file .= '.com' if $^O eq 'VMS';
4633a7c4 20
21open OUT,">$file" or die "Can't create $file: $!";
22
23print "Extracting $file (with variable substitutions)\n";
24
25# In this section, perl variables will be expanded during extraction.
26# You can use $Config{...} to use Configure variables.
27
28print OUT <<"!GROK!THIS!";
5f05dabc 29$Config{startperl}
30 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
31 if \$running_under_some_shell;
40000a8c 32!GROK!THIS!
33
4633a7c4 34# In the following, perl variables are not expanded during extraction.
35
36print OUT <<'!NO!SUBS!';
cf35f3c1 37
3edbfbe5 38=head1 NAME
39
40h2xs - convert .h C header files to Perl extensions
41
42=head1 SYNOPSIS
43
4b19af01 44B<h2xs> [B<-ACOPXacdfkmx>] [B<-F> addflags] [B<-M> fmask] [B<-n> module_name] [B<-o> tmask] [B<-p> prefix] [B<-s> subs] [B<-v> version] [headerfile ... [extra_libraries]]
f508c652 45
46B<h2xs> B<-h>
3edbfbe5 47
48=head1 DESCRIPTION
49
a887ff11 50I<h2xs> builds a Perl extension from C header files. The extension
51will include functions which can be used to retrieve the value of any
52#define statement which was in the C header files.
3edbfbe5 53
54The I<module_name> will be used for the name of the extension. If
a887ff11 55module_name is not supplied then the name of the first header file
56will be used, with the first character capitalized.
3edbfbe5 57
58If the extension might need extra libraries, they should be included
59here. The extension Makefile.PL will take care of checking whether
60the libraries actually exist and how they should be loaded.
61The extra libraries should be specified in the form -lm -lposix, etc,
62just as on the cc command line. By default, the Makefile.PL will
63search through the library path determined by Configure. That path
64can be augmented by including arguments of the form B<-L/another/library/path>
65in the extra-libraries argument.
66
67=head1 OPTIONS
68
69=over 5
70
f508c652 71=item B<-A>
3edbfbe5 72
f508c652 73Omit all autoload facilities. This is the same as B<-c> but also removes the
9ef261b5 74S<C<use AutoLoader>> statement from the .pm file.
3edbfbe5 75
c0f8b9cd 76=item B<-C>
77
78Omits creation of the F<Changes> file, and adds a HISTORY section to
79the POD template.
80
4b19af01 81=item B<-F> I<addflags>
b73edd97 82
83Additional flags to specify to C preprocessor when scanning header for
ddf6bed1 84function declarations. Should not be used without B<-x>.
85
86=item B<-M> I<regular expression>
87
88selects functions/macros to process.
b73edd97 89
2920c5d2 90=item B<-O>
91
92Allows a pre-existing extension directory to be overwritten.
93
f508c652 94=item B<-P>
3edbfbe5 95
f508c652 96Omit the autogenerated stub POD section.
3edbfbe5 97
b73edd97 98=item B<-X>
99
100Omit the XS portion. Used to generate templates for a module which is not
9ef261b5 101XS-based. C<-c> and C<-f> are implicitly enabled.
b73edd97 102
7c1d48a5 103=item B<-a>
104
105Generate an accessor method for each element of structs and unions. The
106generated methods are named after the element name; will return the current
107value of the element if called without additional arguments; and will set
ee8c7f54 108the element to the supplied value (and return the new value) if called with
109an additional argument. Embedded structures and unions are returned as a
110pointer rather than the complete structure, to facilitate chained calls.
111
112These methods all apply to the Ptr type for the structure; additionally
113two methods are constructed for the structure type itself, C<_to_ptr>
114which returns a Ptr type pointing to the same structure, and a C<new>
115method to construct and return a new structure, initialised to zeroes.
7c1d48a5 116
3edbfbe5 117=item B<-c>
118
119Omit C<constant()> from the .xs file and corresponding specialised
120C<AUTOLOAD> from the .pm file.
121
b73edd97 122=item B<-d>
123
124Turn on debugging messages.
125
f508c652 126=item B<-f>
3edbfbe5 127
f508c652 128Allows an extension to be created for a header even if that header is
ddf6bed1 129not found in standard include directories.
f508c652 130
131=item B<-h>
132
133Print the usage, help and version for this h2xs and exit.
134
ee8c7f54 135=item B<-k>
136
137For function arguments declared as C<const>, omit the const attribute in the
138generated XS code.
139
140=item B<-m>
141
142B<Experimental>: for each variable declared in the header file(s), declare
143a perl variable of the same name magically tied to the C variable.
144
f508c652 145=item B<-n> I<module_name>
146
147Specifies a name to be used for the extension, e.g., S<-n RPC::DCE>
148
ddf6bed1 149=item B<-o> I<regular expression>
150
151Use "opaque" data type for the C types matched by the regular
152expression, even if these types are C<typedef>-equivalent to types
153from typemaps. Should not be used without B<-x>.
154
155This may be useful since, say, types which are C<typedef>-equivalent
156to integers may represent OS-related handles, and one may want to work
157with these handles in OO-way, as in C<$handle-E<gt>do_something()>.
158Use C<-o .> if you want to handle all the C<typedef>ed types as opaque types.
159
160The type-to-match is whitewashed (except for commas, which have no
161whitespace before them, and multiple C<*> which have no whitespace
162between them).
163
ead2a595 164=item B<-p> I<prefix>
165
166Specify a prefix which should be removed from the Perl function names, e.g., S<-p sec_rgy_>
167This sets up the XS B<PREFIX> keyword and removes the prefix from functions that are
98a6f11e 168autoloaded via the C<constant()> mechanism.
ead2a595 169
170=item B<-s> I<sub1,sub2>
171
172Create a perl subroutine for the specified macros rather than autoload with the constant() subroutine.
173These macros are assumed to have a return type of B<char *>, e.g., S<-s sec_rgy_wildcard_name,sec_rgy_wildcard_sid>.
174
f508c652 175=item B<-v> I<version>
176
177Specify a version number for this extension. This version number is added
178to the templates. The default is 0.01.
3edbfbe5 179
760ac839 180=item B<-x>
181
182Automatically generate XSUBs basing on function declarations in the
183header file. The package C<C::Scan> should be installed. If this
184option is specified, the name of the header file may look like
185C<NAME1,NAME2>. In this case NAME1 is used instead of the specified string,
b73edd97 186but XSUBs are emitted only for the declarations included from file NAME2.
760ac839 187
5273d82d 188Note that some types of arguments/return-values for functions may
189result in XSUB-declarations/typemap-entries which need
190hand-editing. Such may be objects which cannot be converted from/to a
ddf6bed1 191pointer (like C<long long>), pointers to functions, or arrays. See
192also the section on L<LIMITATIONS of B<-x>>.
5273d82d 193
4b19af01 194=item B<-b> I<version>
195
196Generates a .pm file which is backwards compatible with the specified
197perl version.
198
199For versions < 5.6.0, the changes are.
200 - no use of 'our' (uses 'use vars' instead)
201 - no 'use warnings'
202
203Specifying a compatibility version higher than the version of perl you
204are using to run h2xs will have no effect.
205
3edbfbe5 206=back
207
208=head1 EXAMPLES
209
210
211 # Default behavior, extension is Rusers
212 h2xs rpcsvc/rusers
213
214 # Same, but extension is RUSERS
215 h2xs -n RUSERS rpcsvc/rusers
216
217 # Extension is rpcsvc::rusers. Still finds <rpcsvc/rusers.h>
218 h2xs rpcsvc::rusers
219
220 # Extension is ONC::RPC. Still finds <rpcsvc/rusers.h>
221 h2xs -n ONC::RPC rpcsvc/rusers
222
223 # Without constant() or AUTOLOAD
224 h2xs -c rpcsvc/rusers
225
226 # Creates templates for an extension named RPC
227 h2xs -cfn RPC
228
229 # Extension is ONC::RPC.
230 h2xs -cfn ONC::RPC
231
232 # Makefile.PL will look for library -lrpc in
233 # additional directory /opt/net/lib
234 h2xs rpcsvc/rusers -L/opt/net/lib -lrpc
235
ead2a595 236 # Extension is DCE::rgynbase
237 # prefix "sec_rgy_" is dropped from perl function names
238 h2xs -n DCE::rgynbase -p sec_rgy_ dce/rgynbase
239
240 # Extension is DCE::rgynbase
241 # prefix "sec_rgy_" is dropped from perl function names
242 # subroutines are created for sec_rgy_wildcard_name and sec_rgy_wildcard_sid
243 h2xs -n DCE::rgynbase -p sec_rgy_ \
244 -s sec_rgy_wildcard_name,sec_rgy_wildcard_sid dce/rgynbase
3edbfbe5 245
5273d82d 246 # Make XS without defines in perl.h, but with function declarations
760ac839 247 # visible from perl.h. Name of the extension is perl1.
248 # When scanning perl.h, define -DEXT=extern -DdEXT= -DINIT(x)=
249 # Extra backslashes below because the string is passed to shell.
5273d82d 250 # Note that a directory with perl header files would
251 # be added automatically to include path.
252 h2xs -xAn perl1 -F "-DEXT=extern -DdEXT= -DINIT\(x\)=" perl.h
760ac839 253
254 # Same with function declaration in proto.h as visible from perl.h.
5273d82d 255 h2xs -xAn perl2 perl.h,proto.h
760ac839 256
ddf6bed1 257 # Same but select only functions which match /^av_/
258 h2xs -M '^av_' -xAn perl2 perl.h,proto.h
259
260 # Same but treat SV* etc as "opaque" types
261 h2xs -o '^[S]V \*$' -M '^av_' -xAn perl2 perl.h,proto.h
262
22d4bb9c 263=head2 Extension based on F<.h> and F<.c> files
264
265Suppose that you have some C files implementing some functionality,
266and the corresponding header files. How to create an extension which
267makes this functionality accessable in Perl? The example below
268assumes that the header files are F<interface_simple.h> and
269I<interface_hairy.h>, and you want the perl module be named as
270C<Ext::Ension>. If you need some preprocessor directives and/or
271linking with external libraries, see the flags C<-F>, C<-L> and C<-l>
272in L<"OPTIONS">.
273
274=over
275
276=item Find the directory name
277
278Start with a dummy run of h2xs:
279
280 h2xs -Afn Ext::Ension
281
282The only purpose of this step is to create the needed directories, and
283let you know the names of these directories. From the output you can
284see that the directory for the extension is F<Ext/Ension>.
285
286=item Copy C files
287
288Copy your header files and C files to this directory F<Ext/Ension>.
289
290=item Create the extension
291
292Run h2xs, overwriting older autogenerated files:
293
294 h2xs -Oxan Ext::Ension interface_simple.h interface_hairy.h
295
296h2xs looks for header files I<after> changing to the extension
297directory, so it will find your header files OK.
298
299=item Archive and test
300
301As usual, run
302
303 cd Ext/Ension
304 perl Makefile.PL
305 make dist
306 make
307 make test
308
309=item Hints
310
311It is important to do C<make dist> as early as possible. This way you
312can easily merge(1) your changes to autogenerated files if you decide
313to edit your C<.h> files and rerun h2xs.
314
315Do not forget to edit the documentation in the generated F<.pm> file.
316
317Consider the autogenerated files as skeletons only, you may invent
318better interfaces than what h2xs could guess.
319
320Consider this section as a guideline only, some other options of h2xs
321may better suit your needs.
322
323=back
324
3edbfbe5 325=head1 ENVIRONMENT
326
327No environment variables are used.
328
329=head1 AUTHOR
330
331Larry Wall and others
332
333=head1 SEE ALSO
334
f508c652 335L<perl>, L<perlxstut>, L<ExtUtils::MakeMaker>, and L<AutoLoader>.
3edbfbe5 336
337=head1 DIAGNOSTICS
338
760ac839 339The usual warnings if it cannot read or write the files involved.
3edbfbe5 340
ddf6bed1 341=head1 LIMITATIONS of B<-x>
342
343F<h2xs> would not distinguish whether an argument to a C function
344which is of the form, say, C<int *>, is an input, output, or
345input/output parameter. In particular, argument declarations of the
346form
347
348 int
349 foo(n)
350 int *n
351
352should be better rewritten as
353
354 int
355 foo(n)
356 int &n
357
358if C<n> is an input parameter.
359
360Additionally, F<h2xs> has no facilities to intuit that a function
361
362 int
363 foo(addr,l)
364 char *addr
365 int l
366
367takes a pair of address and length of data at this address, so it is better
368to rewrite this function as
369
370 int
371 foo(sv)
7aff18a2 372 SV *addr
373 PREINIT:
374 STRLEN len;
375 char *s;
376 CODE:
377 s = SvPV(sv,len);
378 RETVAL = foo(s, len);
379 OUTPUT:
380 RETVAL
ddf6bed1 381
382or alternately
383
384 static int
385 my_foo(SV *sv)
386 {
387 STRLEN len;
388 char *s = SvPV(sv,len);
389
390 return foo(s, len);
391 }
392
393 MODULE = foo PACKAGE = foo PREFIX = my_
394
395 int
396 foo(sv)
397 SV *sv
398
399See L<perlxs> and L<perlxstut> for additional details.
400
3edbfbe5 401=cut
402
3cb4da91 403use strict;
404
405
ddf6bed1 406my( $H2XS_VERSION ) = ' $Revision: 1.20 $ ' =~ /\$Revision:\s+([^\s]+)/;
f508c652 407my $TEMPLATE_VERSION = '0.01';
ddf6bed1 408my @ARGS = @ARGV;
4b19af01 409my $compat_version = $];
a0d0e21e 410
411use Getopt::Std;
412
e1666bf5 413sub usage{
414 warn "@_\n" if @_;
4b19af01 415 die "h2xs [-ACOPXacdfhkmx] [-F addflags] [-M fmask] [-n module_name] [-o tmask] [-p prefix] [-s subs] [-v version] [headerfile [extra_libraries]]
f508c652 416version: $H2XS_VERSION
3edbfbe5 417 -A Omit all autoloading facilities (implies -c).
c0f8b9cd 418 -C Omit creating the Changes file, add HISTORY heading to stub POD.
b73edd97 419 -F Additional flags for C preprocessor (used with -x).
ddf6bed1 420 -M Mask to select C functions/macros (default is select all).
2920c5d2 421 -O Allow overwriting of a pre-existing extension directory.
f508c652 422 -P Omit the stub POD section.
9ef261b5 423 -X Omit the XS portion (implies both -c and -f).
7c1d48a5 424 -a Generate get/set accessors for struct and union members (used with -x).
b73edd97 425 -c Omit the constant() function and specialised AUTOLOAD from the XS file.
426 -d Turn on debugging messages.
427 -f Force creation of the extension even if the C header does not exist.
428 -h Display this help message
ee8c7f54 429 -k Omit 'const' attribute on function arguments (used with -x).
430 -m Generate tied variables for access to declared variables.
b73edd97 431 -n Specify a name to use for the extension (recommended).
ddf6bed1 432 -o Regular expression for \"opaque\" types.
b73edd97 433 -p Specify a prefix which should be removed from the Perl function names.
434 -s Create subroutines for specified macros.
f508c652 435 -v Specify a version number for this extension.
760ac839 436 -x Autogenerate XSUBs using C::Scan.
4b19af01 437 -b Specify a perl version to be backwards compatibile with
e1666bf5 438extra_libraries
439 are any libraries that might be needed for loading the
440 extension, e.g. -lm would try to link in the math library.
f508c652 441";
e1666bf5 442}
a0d0e21e 443
a0d0e21e 444
4b19af01 445getopts("ACF:M:OPXacdfhkmn:o:p:s:v:xb:") || usage;
ee8c7f54 446use vars qw($opt_A $opt_C $opt_F $opt_M $opt_O $opt_P $opt_X $opt_a $opt_c $opt_d
4b19af01 447 $opt_f $opt_h $opt_k $opt_m $opt_n $opt_o $opt_p $opt_s $opt_v $opt_x
448 $opt_b);
a0d0e21e 449
e1666bf5 450usage if $opt_h;
f508c652 451
4b19af01 452if( $opt_b ){
453 usage "You cannot use -b and -m at the same time.\n" if ($opt_b && $opt_m);
454 $opt_b =~ /^\d+\.\d+\.\d+/ ||
455 usage "You must provide the backwards compatibility version in X.Y.Z form. " .
456 "(i.e. 5.5.0)\n";
457 my ($maj,$min,$sub) = split(/\./,$opt_b,3);
458 $compat_version = sprintf("%d.%03d%02d",$maj,$min,$sub);
459}
460
f508c652 461if( $opt_v ){
462 $TEMPLATE_VERSION = $opt_v;
463}
9ef261b5 464
465# -A implies -c.
e1666bf5 466$opt_c = 1 if $opt_A;
9ef261b5 467
468# -X implies -c and -f
469$opt_c = $opt_f = 1 if $opt_X;
470
3cb4da91 471my %const_xsub = map { $_,1 } split(/,+/, $opt_s) if $opt_s;
472my $extralibs;
473my @path_h;
a0d0e21e 474
a887ff11 475while (my $arg = shift) {
476 if ($arg =~ /^-l/i) {
477 $extralibs = "$arg @ARGV";
478 last;
479 }
480 push(@path_h, $arg);
481}
e1666bf5 482
483usage "Must supply header file or module name\n"
a887ff11 484 unless (@path_h or $opt_n);
e1666bf5 485
ddf6bed1 486my $fmask;
3cb4da91 487my $tmask;
ddf6bed1 488
489$fmask = qr{$opt_M} if defined $opt_M;
490$tmask = qr{$opt_o} if defined $opt_o;
491my $tmask_all = $tmask && $opt_o eq '.';
492
493if ($opt_x) {
494 eval {require C::Scan; 1}
495 or die <<EOD;
496C::Scan required if you use -x option.
497To install C::Scan, execute
498 perl -MCPAN -e "install C::Scan"
499EOD
500 unless ($tmask_all) {
501 $C::Scan::VERSION >= 0.70
502 or die <<EOD;
503C::Scan v. 0.70 or later required unless you use -o . option.
504You have version $C::Scan::VERSION installed as $INC{'C/Scan.pm'}.
505To install C::Scan, execute
506 perl -MCPAN -e "install C::Scan"
507EOD
508 }
ee8c7f54 509 if (($opt_m || $opt_a) && $C::Scan::VERSION < 0.73) {
510 die <<EOD;
511C::Scan v. 0.73 or later required to use -m or -a options.
512You have version $C::Scan::VERSION installed as $INC{'C/Scan.pm'}.
513To install C::Scan, execute
514 perl -MCPAN -e "install C::Scan"
515EOD
516 }
7aff18a2 517}
518elsif ($opt_o or $opt_F) {
ddf6bed1 519 warn <<EOD;
520Options -o and -F do not make sense without -x.
521EOD
522}
523
3cb4da91 524my @path_h_ini = @path_h;
525my ($name, %fullpath, %prefix, %seen_define, %prefixless, %const_names);
a0d0e21e 526
a887ff11 527if( @path_h ){
ddf6bed1 528 use Config;
529 use File::Spec;
530 my @paths;
531 if ($^O eq 'VMS') { # Consider overrides of default location
3cb4da91 532 # XXXX This is not equivalent to what the older version did:
533 # it was looking at $hadsys header-file per header-file...
534 my($hadsys) = grep s!^sys/!!i , @path_h;
7aff18a2 535 @paths = qw( Sys$Library VAXC$Include );
ddf6bed1 536 push @paths, ($hadsys ? 'GNU_CC_Include[vms]' : 'GNU_CC_Include[000000]');
537 push @paths, qw( DECC$Library_Include DECC$System_Include );
7aff18a2 538 }
539 else {
ddf6bed1 540 @paths = (File::Spec->curdir(), $Config{usrinc},
541 (split ' ', $Config{locincpth}), '/usr/include');
542 }
a887ff11 543 foreach my $path_h (@path_h) {
544 $name ||= $path_h;
e1666bf5 545 if( $path_h =~ s#::#/#g && $opt_n ){
546 warn "Nesting of headerfile ignored with -n\n";
547 }
548 $path_h .= ".h" unless $path_h =~ /\.h$/;
3cb4da91 549 my $fullpath = $path_h;
760ac839 550 $path_h =~ s/,.*$// if $opt_x;
3cb4da91 551 $fullpath{$path_h} = $fullpath;
ddf6bed1 552
553 if (not -f $path_h) {
554 my $tmp_path_h = $path_h;
555 for my $dir (@paths) {
556 last if -f ($path_h = File::Spec->catfile($dir, $tmp_path_h));
557 }
ead2a595 558 }
5273d82d 559
560 if (!$opt_c) {
561 die "Can't find $path_h\n" if ( ! $opt_f && ! -f $path_h );
562 # Scan the header file (we should deal with nested header files)
563 # Record the names of simple #define constants into const_names
a887ff11 564 # Function prototypes are processed below.
5273d82d 565 open(CH, "<$path_h") || die "Can't open $path_h: $!\n";
ddf6bed1 566 defines:
5273d82d 567 while (<CH>) {
3cb4da91 568 if (/^[ \t]*#[ \t]*define\s+([\$\w]+)\b(?!\()\s*(?=[^" \t])(.*)/) {
ddf6bed1 569 my $def = $1;
570 my $rest = $2;
571 $rest =~ s!/\*.*?(\*/|\n)|//.*!!g; # Remove comments
572 $rest =~ s/^\s+//;
573 $rest =~ s/\s+$//;
574 # Cannot do: (-1) and ((LHANDLE)3) are OK:
575 #print("Skip non-wordy $def => $rest\n"),
576 # next defines if $rest =~ /[^\w\$]/;
577 if ($rest =~ /"/) {
578 print("Skip stringy $def => $rest\n") if $opt_d;
579 next defines;
580 }
581 print "Matched $_ ($def)\n" if $opt_d;
582 $seen_define{$def} = $rest;
583 $_ = $def;
e1666bf5 584 next if /^_.*_h_*$/i; # special case, but for what?
760ac839 585 if (defined $opt_p) {
5273d82d 586 if (!/^$opt_p(\d)/) {
587 ++$prefix{$_} if s/^$opt_p//;
588 }
589 else {
590 warn "can't remove $opt_p prefix from '$_'!\n";
591 }
ead2a595 592 }
ddf6bed1 593 $prefixless{$def} = $_;
594 if (!$fmask or /$fmask/) {
595 print "... Passes mask of -M.\n" if $opt_d and $fmask;
596 $const_names{$_}++;
597 }
5273d82d 598 }
599 }
600 close(CH);
e1666bf5 601 }
a887ff11 602 }
a0d0e21e 603}
604
e1666bf5 605
3cb4da91 606my $module = $opt_n || do {
a0d0e21e 607 $name =~ s/\.h$//;
608 if( $name !~ /::/ ){
609 $name =~ s#^.*/##;
610 $name = "\u$name";
611 }
612 $name;
613};
614
3cb4da91 615my ($ext, $nested, @modparts, $modfname, $modpname);
8e07c86e 616(chdir 'ext', $ext = 'ext/') if -d 'ext';
a0d0e21e 617
618if( $module =~ /::/ ){
619 $nested = 1;
620 @modparts = split(/::/,$module);
621 $modfname = $modparts[-1];
622 $modpname = join('/',@modparts);
623}
624else {
625 $nested = 0;
626 @modparts = ();
627 $modfname = $modpname = $module;
628}
629
630
2920c5d2 631if ($opt_O) {
632 warn "Overwriting existing $ext$modpname!!!\n" if -e $modpname;
7aff18a2 633}
634else {
2920c5d2 635 die "Won't overwrite existing $ext$modpname\n" if -e $modpname;
636}
c07a80fd 637if( $nested ){
3cb4da91 638 my $modpath = "";
c07a80fd 639 foreach (@modparts){
640 mkdir("$modpath$_", 0777);
641 $modpath .= "$_/";
642 }
643}
a0d0e21e 644mkdir($modpname, 0777);
8e07c86e 645chdir($modpname) || die "Can't chdir $ext$modpname: $!\n";
a0d0e21e 646
5273d82d 647my %types_seen;
648my %std_types;
f4d63e4e 649my $fdecls = [];
650my $fdecls_parsed = [];
ddf6bed1 651my $typedef_rex;
652my %typedefs_pre;
653my %known_fnames;
7c1d48a5 654my %structs;
5273d82d 655
3cb4da91 656my @fnames;
657my @fnames_no_prefix;
ee8c7f54 658my %vdecl_hash;
659my @vdecls;
5273d82d 660
2920c5d2 661if( ! $opt_X ){ # use XS, unless it was disabled
662 open(XS, ">$modfname.xs") || die "Can't create $ext$modpname/$modfname.xs: $!\n";
5273d82d 663 if ($opt_x) {
5273d82d 664 require Config; # Run-time directive
665 warn "Scanning typemaps...\n";
666 get_typemap();
3cb4da91 667 my @td;
668 my @good_td;
669 my $addflags = $opt_F || '';
670
f4d63e4e 671 foreach my $filename (@path_h) {
3cb4da91 672 my $c;
673 my $filter;
674
675 if ($fullpath{$filename} =~ /,/) {
f4d63e4e 676 $filename = $`;
677 $filter = $';
678 }
679 warn "Scanning $filename for functions...\n";
680 $c = new C::Scan 'filename' => $filename, 'filename_filter' => $filter,
7c1d48a5 681 'add_cppflags' => $addflags, 'c_styles' => [qw(C++ C9X)];
f4d63e4e 682 $c->set('includeDirs' => ["$Config::Config{archlib}/CORE"]);
ddf6bed1 683
f4d63e4e 684 push @$fdecls_parsed, @{ $c->get('parsed_fdecls') };
685 push(@$fdecls, @{$c->get('fdecls')});
3cb4da91 686
687 push @td, @{$c->get('typedefs_maybe')};
7c1d48a5 688 if ($opt_a) {
689 my $structs = $c->get('typedef_structs');
690 @structs{keys %$structs} = values %$structs;
691 }
3cb4da91 692
ee8c7f54 693 if ($opt_m) {
694 %vdecl_hash = %{ $c->get('vdecl_hash') };
695 @vdecls = sort keys %vdecl_hash;
696 for (local $_ = 0; $_ < @vdecls; ++$_) {
697 my $var = $vdecls[$_];
698 my($type, $post) = @{ $vdecl_hash{$var} };
699 if (defined $post) {
700 warn "Can't handle variable '$type $var $post', skipping.\n";
701 splice @vdecls, $_, 1;
702 redo;
703 }
704 $type = normalize_type($type);
705 $vdecl_hash{$var} = $type;
706 }
707 }
708
3cb4da91 709 unless ($tmask_all) {
710 warn "Scanning $filename for typedefs...\n";
711 my $td = $c->get('typedef_hash');
712 # eval {require 'dumpvar.pl'; ::dumpValue($td)} or warn $@ if $opt_d;
713 my @f_good_td = grep $td->{$_}[1] eq '', keys %$td;
714 push @good_td, @f_good_td;
715 @typedefs_pre{@f_good_td} = map $_->[0], @$td{@f_good_td};
716 }
717 }
718 { local $" = '|';
ee8c7f54 719 $typedef_rex = qr(\b(?<!struct )(?:@good_td)\b) if @good_td;
5273d82d 720 }
ddf6bed1 721 %known_fnames = map @$_[1,3], @$fdecls_parsed; # [1,3] is NAME, FULLTEXT
722 if ($fmask) {
723 my @good;
724 for my $i (0..$#$fdecls_parsed) {
725 next unless $fdecls_parsed->[$i][1] =~ /$fmask/; # [1] is NAME
726 push @good, $i;
727 print "... Function $fdecls_parsed->[$i][1] passes -M mask.\n"
728 if $opt_d;
729 }
730 $fdecls = [@$fdecls[@good]];
731 $fdecls_parsed = [@$fdecls_parsed[@good]];
732 }
3cb4da91 733 @fnames = sort map $_->[1], @$fdecls_parsed; # 1 is NAME
734 # Sort declarations:
735 {
736 my %h = map( ($_->[1], $_), @$fdecls_parsed);
737 $fdecls_parsed = [ @h{@fnames} ];
ddf6bed1 738 }
3cb4da91 739 @fnames_no_prefix = @fnames;
740 @fnames_no_prefix
741 = sort map { ++$prefix{$_} if s/^$opt_p(?!\d)//; $_ } @fnames_no_prefix;
ddf6bed1 742 # Remove macros which expand to typedefs
ddf6bed1 743 print "Typedefs are @td.\n" if $opt_d;
744 my %td = map {($_, $_)} @td;
745 # Add some other possible but meaningless values for macros
746 for my $k (qw(char double float int long short unsigned signed void)) {
747 $td{"$_$k"} = "$_$k" for ('', 'signed ', 'unsigned ');
748 }
749 # eval {require 'dumpvar.pl'; ::dumpValue( [\@td, \%td] ); 1} or warn $@;
750 my $n = 0;
751 my %bad_macs;
752 while (keys %td > $n) {
753 $n = keys %td;
754 my ($k, $v);
755 while (($k, $v) = each %seen_define) {
756 # print("found '$k'=>'$v'\n"),
757 $bad_macs{$k} = $td{$k} = $td{$v} if exists $td{$v};
758 }
759 }
760 # Now %bad_macs contains names of bad macros
761 for my $k (keys %bad_macs) {
762 delete $const_names{$prefixless{$k}};
763 print "Ignoring macro $k which expands to a typedef name '$bad_macs{$k}'\n" if $opt_d;
5273d82d 764 }
5273d82d 765 }
2920c5d2 766}
3cb4da91 767my @const_names = sort keys %const_names;
5273d82d 768
8e07c86e 769open(PM, ">$modfname.pm") || die "Can't create $ext$modpname/$modfname.pm: $!\n";
a0d0e21e 770
a0d0e21e 771$" = "\n\t";
8e07c86e 772warn "Writing $ext$modpname/$modfname.pm\n";
a0d0e21e 773
4b19af01 774if ( $compat_version < 5.006 ) {
a0d0e21e 775print PM <<"END";
776package $module;
777
4b19af01 778use $compat_version;
779use strict;
780END
781}
782else {
783print PM <<"END";
784package $module;
785
786use 5.006;
2920c5d2 787use strict;
ee8c7f54 788use warnings;
2920c5d2 789END
4b19af01 790}
2920c5d2 791
aba05478 792unless( $opt_X || $opt_c || $opt_A ){
2920c5d2 793 # we'll have an AUTOLOAD(), and it will have $AUTOLOAD and
794 # will want Carp.
795 print PM <<'END';
796use Carp;
2920c5d2 797END
798}
799
800print PM <<'END';
801
a0d0e21e 802require Exporter;
2920c5d2 803END
804
805print PM <<"END" if ! $opt_X; # use DynaLoader, unless XS was disabled
a0d0e21e 806require DynaLoader;
3edbfbe5 807END
808
e1666bf5 809
9ef261b5 810# Are we using AutoLoader or not?
811unless ($opt_A) { # no autoloader whatsoever.
812 unless ($opt_c) { # we're doing the AUTOLOAD
813 print PM "use AutoLoader;\n";
2920c5d2 814 }
9ef261b5 815 else {
816 print PM "use AutoLoader qw(AUTOLOAD);\n"
2920c5d2 817 }
3edbfbe5 818}
3edbfbe5 819
4b19af01 820if ( $compat_version < 5.006 ) {
821 if ( $opt_X || $opt_c || $opt_A ) {
822 print PM 'use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);';
823 } else {
824 print PM 'use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);';
825 }
826}
827
9ef261b5 828# Determine @ISA.
77ca0c92 829my $myISA = 'our @ISA = qw(Exporter'; # We seem to always want this.
9ef261b5 830$myISA .= ' DynaLoader' unless $opt_X; # no XS
831$myISA .= ');';
4b19af01 832$myISA =~ s/^our // if $compat_version < 5.006;
833
9ef261b5 834print PM "\n$myISA\n\n";
e1666bf5 835
ee8c7f54 836my @exported_names = (@const_names, @fnames_no_prefix, map '$'.$_, @vdecls);
3cb4da91 837
4b19af01 838my $tmp=<<"END";
e1666bf5 839# Items to export into callers namespace by default. Note: do not export
840# names by default without a very good reason. Use EXPORT_OK instead.
841# Do not simply export all your public functions/methods/constants.
ddf6bed1 842
843# This allows declaration use $module ':all';
844# If you do not need this, moving things directly into \@EXPORT or \@EXPORT_OK
845# will save memory.
51fac20b 846our %EXPORT_TAGS = ( 'all' => [ qw(
3cb4da91 847 @exported_names
ddf6bed1 848) ] );
849
51fac20b 850our \@EXPORT_OK = ( \@{ \$EXPORT_TAGS{'all'} } );
ddf6bed1 851
77ca0c92 852our \@EXPORT = qw(
e1666bf5 853 @const_names
a0d0e21e 854);
77ca0c92 855our \$VERSION = '$TEMPLATE_VERSION';
f508c652 856
e1666bf5 857END
858
4b19af01 859$tmp =~ s/^our //mg if $compat_version < 5.006;
860print PM $tmp;
861
ee8c7f54 862if (@vdecls) {
863 printf PM "our(@{[ join ', ', map '$'.$_, @vdecls ]});\n\n";
864}
865
4b19af01 866
867$tmp = ( $compat_version < 5.006 ? "" : "our \$AUTOLOAD;" );
2920c5d2 868print PM <<"END" unless $opt_c or $opt_X;
a0d0e21e 869sub AUTOLOAD {
3edbfbe5 870 # This AUTOLOAD is used to 'autoload' constants from the constant()
871 # XS function. If a constant is not found then control is passed
872 # to the AUTOLOAD in AutoLoader.
e1666bf5 873
2920c5d2 874 my \$constname;
4b19af01 875 $tmp
a0d0e21e 876 (\$constname = \$AUTOLOAD) =~ s/.*:://;
1d3434b8 877 croak "&$module::constant not defined" if \$constname eq 'constant';
2920c5d2 878 my \$val = constant(\$constname, \@_ ? \$_[0] : 0);
a0d0e21e 879 if (\$! != 0) {
265f5c4a 880 if (\$! =~ /Invalid/ || \$!{EINVAL}) {
a0d0e21e 881 \$AutoLoader::AUTOLOAD = \$AUTOLOAD;
882 goto &AutoLoader::AUTOLOAD;
883 }
884 else {
7aff18a2 885 croak "Your vendor has not defined $module macro \$constname";
a0d0e21e 886 }
887 }
7aff18a2 888 {
889 no strict 'refs';
890 # Fixed between 5.005_53 and 5.005_61
891 if (\$] >= 5.00561) {
892 *\$AUTOLOAD = sub () { \$val };
893 }
894 else {
895 *\$AUTOLOAD = sub { \$val };
896 }
ddf6bed1 897 }
a0d0e21e 898 goto &\$AUTOLOAD;
899}
900
a0d0e21e 901END
a0d0e21e 902
2920c5d2 903if( ! $opt_X ){ # print bootstrap, unless XS is disabled
904 print PM <<"END";
f508c652 905bootstrap $module \$VERSION;
2920c5d2 906END
907}
908
ee8c7f54 909# tying the variables can happen only after bootstrap
910if (@vdecls) {
911 printf PM <<END;
912{
913@{[ join "\n", map " _tievar_$_(\$$_);", @vdecls ]}
914}
915
916END
917}
918
3cb4da91 919my $after;
2920c5d2 920if( $opt_P ){ # if POD is disabled
921 $after = '__END__';
922}
923else {
924 $after = '=cut';
925}
926
927print PM <<"END";
a0d0e21e 928
e1666bf5 929# Preloaded methods go here.
9ef261b5 930END
931
932print PM <<"END" unless $opt_A;
a0d0e21e 933
2920c5d2 934# Autoload methods go after $after, and are processed by the autosplit program.
9ef261b5 935END
936
937print PM <<"END";
a0d0e21e 938
9391;
e1666bf5 940__END__
a0d0e21e 941END
a0d0e21e 942
3cb4da91 943my $author = "A. U. Thor";
944my $email = 'a.u.thor@a.galaxy.far.far.away';
f508c652 945
c0f8b9cd 946my $revhist = '';
947$revhist = <<EOT if $opt_C;
4b19af01 948#
949#=head1 HISTORY
950#
951#=over 8
952#
953#=item $TEMPLATE_VERSION
954#
955#Original version; created by h2xs $H2XS_VERSION with options
956#
957# @ARGS
958#
959#=back
960#
c0f8b9cd 961EOT
962
ddf6bed1 963my $exp_doc = <<EOD;
4b19af01 964#
965#=head2 EXPORT
966#
967#None by default.
968#
ddf6bed1 969EOD
22d4bb9c 970
5273d82d 971if (@const_names and not $opt_P) {
ddf6bed1 972 $exp_doc .= <<EOD;
4b19af01 973#=head2 Exportable constants
974#
975# @{[join "\n ", @const_names]}
976#
5273d82d 977EOD
978}
22d4bb9c 979
5273d82d 980if (defined $fdecls and @$fdecls and not $opt_P) {
ddf6bed1 981 $exp_doc .= <<EOD;
4b19af01 982#=head2 Exportable functions
983#
3cb4da91 984EOD
22d4bb9c 985
4b19af01 986# $exp_doc .= <<EOD if $opt_p;
987#When accessing these functions from Perl, prefix C<$opt_p> should be removed.
988#
22d4bb9c 989#EOD
3cb4da91 990 $exp_doc .= <<EOD;
4b19af01 991# @{[join "\n ", @known_fnames{@fnames}]}
992#
5273d82d 993EOD
994}
995
22d4bb9c 996my $meth_doc = '';
997
998if ($opt_x && $opt_a) {
999 my($name, $struct);
1000 $meth_doc .= accessor_docs($name, $struct)
1001 while ($name, $struct) = each %structs;
1002}
1003
3cb4da91 1004my $pod = <<"END" unless $opt_P;
7aff18a2 1005## Below is stub documentation for your module. You better edit it!
f508c652 1006#
1007#=head1 NAME
1008#
1009#$module - Perl extension for blah blah blah
1010#
1011#=head1 SYNOPSIS
1012#
1013# use $module;
1014# blah blah blah
1015#
1016#=head1 DESCRIPTION
1017#
7aff18a2 1018#Stub documentation for $module, created by h2xs. It looks like the
f508c652 1019#author of the extension was negligent enough to leave the stub
1020#unedited.
1021#
1022#Blah blah blah.
22d4bb9c 1023$exp_doc$meth_doc$revhist
f508c652 1024#=head1 AUTHOR
1025#
1026#$author, $email
1027#
1028#=head1 SEE ALSO
1029#
4b19af01 1030#L<perl>.
f508c652 1031#
1032#=cut
1033END
1034
1035$pod =~ s/^\#//gm unless $opt_P;
1036print PM $pod unless $opt_P;
1037
a0d0e21e 1038close PM;
1039
e1666bf5 1040
2920c5d2 1041if( ! $opt_X ){ # print XS, unless it is disabled
8e07c86e 1042warn "Writing $ext$modpname/$modfname.xs\n";
e1666bf5 1043
a0d0e21e 1044print XS <<"END";
1045#include "EXTERN.h"
1046#include "perl.h"
1047#include "XSUB.h"
1048
1049END
a887ff11 1050if( @path_h ){
3cb4da91 1051 foreach my $path_h (@path_h_ini) {
a0d0e21e 1052 my($h) = $path_h;
1053 $h =~ s#^/usr/include/##;
ead2a595 1054 if ($^O eq 'VMS') { $h =~ s#.*vms\]#sys/# or $h =~ s#.*[:>\]]##; }
a887ff11 1055 print XS qq{#include <$h>\n};
1056 }
1057 print XS "\n";
a0d0e21e 1058}
1059
ddf6bed1 1060my %pointer_typedefs;
1061my %struct_typedefs;
1062
1063sub td_is_pointer {
1064 my $type = shift;
1065 my $out = $pointer_typedefs{$type};
1066 return $out if defined $out;
1067 my $otype = $type;
1068 $out = ($type =~ /\*$/);
1069 # This converts only the guys which do not have trailing part in the typedef
1070 if (not $out
1071 and $typedef_rex and $type =~ s/($typedef_rex)/$typedefs_pre{$1}/go) {
1072 $type = normalize_type($type);
1073 print "Is-Pointer: Type mutation via typedefs: $otype ==> $type\n"
1074 if $opt_d;
1075 $out = td_is_pointer($type);
1076 }
1077 return ($pointer_typedefs{$otype} = $out);
1078}
1079
1080sub td_is_struct {
1081 my $type = shift;
1082 my $out = $struct_typedefs{$type};
1083 return $out if defined $out;
1084 my $otype = $type;
ee8c7f54 1085 $out = ($type =~ /^(struct|union)\b/) && !td_is_pointer($type);
ddf6bed1 1086 # This converts only the guys which do not have trailing part in the typedef
1087 if (not $out
1088 and $typedef_rex and $type =~ s/($typedef_rex)/$typedefs_pre{$1}/go) {
1089 $type = normalize_type($type);
1090 print "Is-Struct: Type mutation via typedefs: $otype ==> $type\n"
1091 if $opt_d;
1092 $out = td_is_struct($type);
1093 }
1094 return ($struct_typedefs{$otype} = $out);
1095}
1096
1097# Some macros will bomb if you try to return them from a double-returning func.
1098# Say, ((char *)0), or strlen (if somebody #define STRLEN strlen).
1099# Fortunately, we can detect both these cases...
1100sub protect_convert_to_double {
1101 my $in = shift;
1102 my $val;
1103 return '' unless defined ($val = $seen_define{$in});
1104 return '(IV)' if $known_fnames{$val};
1105 # OUT_t of ((OUT_t)-1):
1106 return '' unless $val =~ /^\s*(\(\s*)?\(\s*([^()]*?)\s*\)/;
1107 td_is_pointer($2) ? '(IV)' : '';
a0d0e21e 1108}
1109
ddf6bed1 1110# For each of the generated functions, length($pref) leading
1111# letters are already checked. Moreover, it is recommended that
1112# the generated functions uses switch on letter at offset at least
1113# $off + length($pref).
1114#
1115# The given list has length($pref) chars removed at front, it is
1116# guarantied that $off leading chars in the rest are the same for all
1117# elts of the list.
1118#
1119# Returns: how at which offset it was decided to make a switch, or -1 if none.
1120
1121sub write_const;
1122
1123sub write_const {
1124 my ($fh, $pref, $off, $list) = (shift,shift,shift,shift);
1125 my %leading;
1126 my $offarg = length $pref;
1127
1128 if (@$list == 0) { # Can happen on the initial iteration only
1129 print $fh <<"END";
a0d0e21e 1130static double
3cb4da91 1131constant(char *name, int len, int arg)
a0d0e21e 1132{
ddf6bed1 1133 errno = EINVAL;
1134 return 0;
1135}
a0d0e21e 1136END
a0d0e21e 1137 return -1;
ddf6bed1 1138 }
a0d0e21e 1139
ddf6bed1 1140 if (@$list == 1) { # Can happen on the initial iteration only
1141 my $protect = protect_convert_to_double("$pref$list->[0]");
e1666bf5 1142
ddf6bed1 1143 print $fh <<"END";
1144static double
3cb4da91 1145constant(char *name, int len, int arg)
ddf6bed1 1146{
daf40514 1147 errno = 0;
ddf6bed1 1148 if (strEQ(name + $offarg, "$list->[0]")) { /* $pref removed */
1149#ifdef $pref$list->[0]
1150 return $protect$pref$list->[0];
1151#else
1152 errno = ENOENT;
1153 return 0;
1154#endif
1155 }
1156 errno = EINVAL;
1157 return 0;
a0d0e21e 1158}
ddf6bed1 1159END
1160 return -1;
1161 }
a0d0e21e 1162
ddf6bed1 1163 for my $n (@$list) {
1164 my $c = substr $n, $off, 1;
1165 $leading{$c} = [] unless exists $leading{$c};
1166 push @{$leading{$c}}, substr $n, $off + 1;
1167 }
1168
1169 if (keys(%leading) == 1) {
1170 return 1 + write_const $fh, $pref, $off + 1, $list;
1171 }
1172
1173 my $leader = substr $list->[0], 0, $off;
3cb4da91 1174 foreach my $letter (keys %leading) {
ddf6bed1 1175 write_const $fh, "$pref$leader$letter", 0, $leading{$letter}
1176 if @{$leading{$letter}} > 1;
1177 }
a0d0e21e 1178
ddf6bed1 1179 my $npref = "_$pref";
1180 $npref = '' if $pref eq '';
a0d0e21e 1181
ddf6bed1 1182 print $fh <<"END";
a0d0e21e 1183static double
3cb4da91 1184constant$npref(char *name, int len, int arg)
a0d0e21e 1185{
daf40514 1186END
1187
1188 print $fh <<"END" if $npref eq '';
a0d0e21e 1189 errno = 0;
a0d0e21e 1190END
1191
3cb4da91 1192 print $fh <<"END" if $off;
1193 if ($offarg + $off >= len ) {
1194 errno = EINVAL;
1195 return 0;
1196 }
1197END
e1666bf5 1198
3cb4da91 1199 print $fh <<"END";
ddf6bed1 1200 switch (name[$offarg + $off]) {
1201END
a0d0e21e 1202
3cb4da91 1203 foreach my $letter (sort keys %leading) {
ddf6bed1 1204 my $let = $letter;
1205 $let = '\0' if $letter eq '';
a0d0e21e 1206
ddf6bed1 1207 print $fh <<EOP;
1208 case '$let':
1209EOP
1210 if (@{$leading{$letter}} > 1) {
1211 # It makes sense to call a function
1212 if ($off) {
1213 print $fh <<EOP;
1214 if (!strnEQ(name + $offarg,"$leader", $off))
1215 break;
1216EOP
1217 }
1218 print $fh <<EOP;
3cb4da91 1219 return constant_$pref$leader$letter(name, len, arg);
ddf6bed1 1220EOP
7aff18a2 1221 }
1222 else {
ddf6bed1 1223 # Do it ourselves
1224 my $protect
1225 = protect_convert_to_double("$pref$leader$letter$leading{$letter}[0]");
1226
1227 print $fh <<EOP;
1228 if (strEQ(name + $offarg, "$leader$letter$leading{$letter}[0]")) { /* $pref removed */
1229#ifdef $pref$leader$letter$leading{$letter}[0]
1230 return $protect$pref$leader$letter$leading{$letter}[0];
a0d0e21e 1231#else
1232 goto not_there;
1233#endif
ddf6bed1 1234 }
1235EOP
a0d0e21e 1236 }
ddf6bed1 1237 }
1238 print $fh <<"END";
a0d0e21e 1239 }
1240 errno = EINVAL;
1241 return 0;
1242
1243not_there:
1244 errno = ENOENT;
1245 return 0;
1246}
1247
e1666bf5 1248END
ddf6bed1 1249
e1666bf5 1250}
1251
ddf6bed1 1252if( ! $opt_c ) {
1253 print XS <<"END";
1254static int
1255not_here(char *s)
1256{
1257 croak("$module::%s not implemented on this architecture", s);
1258 return -1;
1259}
1260
1261END
1262
1263 write_const(\*XS, '', 0, \@const_names);
e1666bf5 1264}
1265
ee8c7f54 1266print_tievar_subs(\*XS, $_, $vdecl_hash{$_}) for @vdecls;
1267
3cb4da91 1268my $prefix;
ead2a595 1269$prefix = "PREFIX = $opt_p" if defined $opt_p;
3cb4da91 1270
e1666bf5 1271# Now switch from C to XS by issuing the first MODULE declaration:
1272print XS <<"END";
a0d0e21e 1273
ead2a595 1274MODULE = $module PACKAGE = $module $prefix
1275
1276END
1277
1278foreach (sort keys %const_xsub) {
1279 print XS <<"END";
1280char *
1281$_()
1282
1283 CODE:
1284#ifdef $_
7aff18a2 1285 RETVAL = $_;
ead2a595 1286#else
7aff18a2 1287 croak("Your vendor has not defined the $module macro $_");
ead2a595 1288#endif
1289
1290 OUTPUT:
7aff18a2 1291 RETVAL
a0d0e21e 1292
e1666bf5 1293END
ead2a595 1294}
e1666bf5 1295
1296# If a constant() function was written then output a corresponding
1297# XS declaration:
1298print XS <<"END" unless $opt_c;
1299
a0d0e21e 1300double
3cb4da91 1301constant(sv,arg)
7aff18a2 1302 PREINIT:
3cb4da91 1303 STRLEN len;
7aff18a2 1304 INPUT:
3cb4da91 1305 SV * sv
1306 char * s = SvPV(sv, len);
a0d0e21e 1307 int arg
7aff18a2 1308 CODE:
3cb4da91 1309 RETVAL = constant(s,len,arg);
7aff18a2 1310 OUTPUT:
3cb4da91 1311 RETVAL
a0d0e21e 1312
1313END
a0d0e21e 1314
5273d82d 1315my %seen_decl;
ddf6bed1 1316my %typemap;
5273d82d 1317
ead2a595 1318sub print_decl {
1319 my $fh = shift;
1320 my $decl = shift;
1321 my ($type, $name, $args) = @$decl;
5273d82d 1322 return if $seen_decl{$name}++; # Need to do the same for docs as well?
1323
ead2a595 1324 my @argnames = map {$_->[1]} @$args;
ddf6bed1 1325 my @argtypes = map { normalize_type( $_->[0], 1 ) } @$args;
ee8c7f54 1326 if ($opt_k) {
1327 s/^\s*const\b\s*// for @argtypes;
1328 }
5273d82d 1329 my @argarrays = map { $_->[4] || '' } @$args;
ead2a595 1330 my $numargs = @$args;
1331 if ($numargs and $argtypes[-1] eq '...') {
1332 $numargs--;
1333 $argnames[-1] = '...';
1334 }
1335 local $" = ', ';
ddf6bed1 1336 $type = normalize_type($type, 1);
1337
ead2a595 1338 print $fh <<"EOP";
1339
1340$type
1341$name(@argnames)
1342EOP
1343
3cb4da91 1344 for my $arg (0 .. $numargs - 1) {
ead2a595 1345 print $fh <<"EOP";
5273d82d 1346 $argtypes[$arg] $argnames[$arg]$argarrays[$arg]
ead2a595 1347EOP
1348 }
1349}
1350
ee8c7f54 1351sub print_tievar_subs {
1352 my($fh, $name, $type) = @_;
1353 print $fh <<END;
1354I32
1355_get_$name(IV index, SV *sv) {
1356 dSP;
1357 PUSHMARK(SP);
1358 XPUSHs(sv);
1359 PUTBACK;
1360 (void)call_pv("$module\::_get_$name", G_DISCARD);
1361 return (I32)0;
1362}
1363
1364I32
1365_set_$name(IV index, SV *sv) {
1366 dSP;
1367 PUSHMARK(SP);
1368 XPUSHs(sv);
1369 PUTBACK;
1370 (void)call_pv("$module\::_set_$name", G_DISCARD);
1371 return (I32)0;
1372}
1373
1374END
1375}
1376
1377sub print_tievar_xsubs {
1378 my($fh, $name, $type) = @_;
1379 print $fh <<END;
1380void
1381_tievar_$name(sv)
1382 SV* sv
1383 PREINIT:
1384 struct ufuncs uf;
1385 CODE:
1386 uf.uf_val = &_get_$name;
1387 uf.uf_set = &_set_$name;
1388 uf.uf_index = (IV)&_get_$name;
1389 sv_magic(sv, 0, 'U', (char*)&uf, sizeof(uf));
1390
1391void
1392_get_$name(THIS)
1393 $type THIS = NO_INIT
1394 CODE:
1395 THIS = $name;
1396 OUTPUT:
1397 SETMAGIC: DISABLE
1398 THIS
1399
1400void
1401_set_$name(THIS)
1402 $type THIS
1403 CODE:
1404 $name = THIS;
1405
1406END
1407}
1408
7c1d48a5 1409sub print_accessors {
1410 my($fh, $name, $struct) = @_;
1411 return unless defined $struct && $name !~ /\s|_ANON/;
1412 $name = normalize_type($name);
1413 my $ptrname = normalize_type("$name *");
ee8c7f54 1414 print $fh <<"EOF";
1415
1416MODULE = $module PACKAGE = ${name} $prefix
1417
1418$name *
1419_to_ptr(THIS)
1420 $name THIS = NO_INIT
1421 PROTOTYPE: \$
1422 CODE:
1423 if (sv_derived_from(ST(0), "$name")) {
1424 STRLEN len;
1425 char *s = SvPV((SV*)SvRV(ST(0)), len);
1426 if (len != sizeof(THIS))
1427 croak("Size \%d of packed data != expected \%d",
1428 len, sizeof(THIS));
1429 RETVAL = ($name *)s;
1430 }
1431 else
1432 croak("THIS is not of type $name");
1433 OUTPUT:
1434 RETVAL
1435
1436$name
1437new(CLASS)
1438 char *CLASS = NO_INIT
1439 PROTOTYPE: \$
1440 CODE:
1441 Zero((void*)&RETVAL, sizeof(RETVAL), char);
1442 OUTPUT:
1443 RETVAL
7c1d48a5 1444
1445MODULE = $module PACKAGE = ${name}Ptr $prefix
1446
1447EOF
1448 my @items = @$struct;
1449 while (@items) {
1450 my $item = shift @items;
1451 if ($item->[0] =~ /_ANON/) {
ee8c7f54 1452 if (defined $item->[2]) {
7c1d48a5 1453 push @items, map [
ee8c7f54 1454 @$_[0, 1], "$item->[2]_$_->[2]", "$item->[2].$_->[2]",
7c1d48a5 1455 ], @{ $structs{$item->[0]} };
1456 } else {
1457 push @items, @{ $structs{$item->[0]} };
1458 }
1459 } else {
1460 my $type = normalize_type($item->[0]);
ee8c7f54 1461 my $ttype = $structs{$type} ? normalize_type("$type *") : $type;
7c1d48a5 1462 print $fh <<"EOF";
ee8c7f54 1463$ttype
1464$item->[2](THIS, __value = NO_INIT)
7c1d48a5 1465 $ptrname THIS
1466 $type __value
1467 PROTOTYPE: \$;\$
1468 CODE:
7c1d48a5 1469 if (items > 1)
1470 THIS->$item->[-1] = __value;
ee8c7f54 1471 RETVAL = @{[
1472 $type eq $ttype ? "THIS->$item->[-1]" : "&(THIS->$item->[-1])"
1473 ]};
7c1d48a5 1474 OUTPUT:
1475 RETVAL
1476
1477EOF
1478 }
1479 }
1480}
1481
22d4bb9c 1482sub accessor_docs {
1483 my($name, $struct) = @_;
1484 return unless defined $struct && $name !~ /\s|_ANON/;
1485 $name = normalize_type($name);
1486 my $ptrname = $name . 'Ptr';
1487 my @items = @$struct;
1488 my @list;
1489 while (@items) {
1490 my $item = shift @items;
1491 if ($item->[0] =~ /_ANON/) {
1492 if (defined $item->[2]) {
1493 push @items, map [
1494 @$_[0, 1], "$item->[2]_$_->[2]", "$item->[2].$_->[2]",
1495 ], @{ $structs{$item->[0]} };
1496 } else {
1497 push @items, @{ $structs{$item->[0]} };
1498 }
1499 } else {
1500 push @list, $item->[2];
1501 }
1502 }
1503 my $methods = (join '(...)>, C<', @list) . '(...)';
1504
1505 my $pod = <<"EOF";
1506#
1507#=head2 Object and class methods for C<$name>/C<$ptrname>
1508#
1509#The principal Perl representation of a C object of type C<$name> is an
1510#object of class C<$ptrname> which is a reference to an integer
1511#representation of a C pointer. To create such an object, one may use
1512#a combination
1513#
1514# my \$buffer = $name->new();
1515# my \$obj = \$buffer->_to_ptr();
1516#
1517#This exersizes the following two methods, and an additional class
1518#C<$name>, the internal representation of which is a reference to a
1519#packed string with the C structure. Keep in mind that \$buffer should
1520#better survive longer than \$obj.
1521#
1522#=over
1523#
1524#=item C<\$object_of_type_$name-E<gt>_to_ptr()>
1525#
1526#Converts an object of type C<$name> to an object of type C<$ptrname>.
1527#
1528#=item C<$name-E<gt>new()>
1529#
1530#Creates an empty object of type C<$name>. The corresponding packed
1531#string is zeroed out.
1532#
1533#=item C<$methods>
1534#
1535#return the current value of the corresponding element if called
1536#without additional arguments. Set the element to the supplied value
1537#(and return the new value) if called with an additional argument.
1538#
1539#Applicable to objects of type C<$ptrname>.
1540#
1541#=back
1542#
1543EOF
1544 $pod =~ s/^\#//gm;
1545 return $pod;
1546}
1547
5273d82d 1548# Should be called before any actual call to normalize_type().
1549sub get_typemap {
1550 # We do not want to read ./typemap by obvios reasons.
1551 my @tm = qw(../../../typemap ../../typemap ../typemap);
1552 my $stdtypemap = "$Config::Config{privlib}/ExtUtils/typemap";
1553 unshift @tm, $stdtypemap;
1554 my $proto_re = "[" . quotemeta('\$%&*@;') . "]" ;
ddf6bed1 1555
1556 # Start with useful default values
1557 $typemap{float} = 'T_DOUBLE';
1558
3cb4da91 1559 foreach my $typemap (@tm) {
5273d82d 1560 next unless -e $typemap ;
1561 # skip directories, binary files etc.
1562 warn " Scanning $typemap\n";
1563 warn("Warning: ignoring non-text typemap file '$typemap'\n"), next
1564 unless -T $typemap ;
1565 open(TYPEMAP, $typemap)
1566 or warn ("Warning: could not open typemap file '$typemap': $!\n"), next;
1567 my $mode = 'Typemap';
1568 while (<TYPEMAP>) {
1569 next if /^\s*\#/;
1570 if (/^INPUT\s*$/) { $mode = 'Input'; next; }
1571 elsif (/^OUTPUT\s*$/) { $mode = 'Output'; next; }
1572 elsif (/^TYPEMAP\s*$/) { $mode = 'Typemap'; next; }
1573 elsif ($mode eq 'Typemap') {
1574 next if /^\s*($|\#)/ ;
3cb4da91 1575 my ($type, $image);
ddf6bed1 1576 if ( ($type, $image) =
5273d82d 1577 /^\s*(.*?\S)\s+(\S+)\s*($proto_re*)\s*$/o
1578 # This may reference undefined functions:
1579 and not ($image eq 'T_PACKED' and $typemap eq $stdtypemap)) {
ddf6bed1 1580 $typemap{normalize_type($type)} = $image;
5273d82d 1581 }
1582 }
1583 }
1584 close(TYPEMAP) or die "Cannot close $typemap: $!";
1585 }
1586 %std_types = %types_seen;
1587 %types_seen = ();
1588}
1589
ead2a595 1590
ddf6bed1 1591sub normalize_type { # Second arg: do not strip const's before \*
ead2a595 1592 my $type = shift;
3cb4da91 1593 my $do_keep_deep_const = shift;
1594 # If $do_keep_deep_const this is heuristical only
1595 my $keep_deep_const = ($do_keep_deep_const ? '\b(?![^(,)]*\*)' : '');
ddf6bed1 1596 my $ignore_mods
3cb4da91 1597 = "(?:\\b(?:(?:__const__|const)$keep_deep_const|static|inline|__inline__)\\b\\s*)*";
1598 if ($do_keep_deep_const) { # Keep different compiled /RExen/o separately!
1599 $type =~ s/$ignore_mods//go;
7aff18a2 1600 }
1601 else {
3cb4da91 1602 $type =~ s/$ignore_mods//go;
1603 }
ddf6bed1 1604 $type =~ s/([^\s\w])/ \1 /g;
ead2a595 1605 $type =~ s/\s+$//;
1606 $type =~ s/^\s+//;
ddf6bed1 1607 $type =~ s/\s+/ /g;
1608 $type =~ s/\* (?=\*)/*/g;
1609 $type =~ s/\. \. \./.../g;
1610 $type =~ s/ ,/,/g;
5273d82d 1611 $types_seen{$type}++
1612 unless $type eq '...' or $type eq 'void' or $std_types{$type};
ead2a595 1613 $type;
1614}
1615
ddf6bed1 1616my $need_opaque;
1617
1618sub assign_typemap_entry {
1619 my $type = shift;
1620 my $otype = $type;
1621 my $entry;
1622 if ($tmask and $type =~ /$tmask/) {
1623 print "Type $type matches -o mask\n" if $opt_d;
1624 $entry = (td_is_struct($type) ? "T_OPAQUE_STRUCT" : "T_PTROBJ");
1625 }
1626 elsif ($typedef_rex and $type =~ s/($typedef_rex)/$typedefs_pre{$1}/go) {
1627 $type = normalize_type $type;
1628 print "Type mutation via typedefs: $otype ==> $type\n" if $opt_d;
1629 $entry = assign_typemap_entry($type);
1630 }
1631 $entry ||= $typemap{$otype}
1632 || (td_is_struct($type) ? "T_OPAQUE_STRUCT" : "T_PTROBJ");
1633 $typemap{$otype} = $entry;
1634 $need_opaque = 1 if $entry eq "T_OPAQUE_STRUCT";
1635 return $entry;
1636}
1637
ee8c7f54 1638for (@vdecls) {
1639 print_tievar_xsubs(\*XS, $_, $vdecl_hash{$_});
1640}
1641
ead2a595 1642if ($opt_x) {
ee8c7f54 1643 for my $decl (@$fdecls_parsed) { print_decl(\*XS, $decl) }
1644 if ($opt_a) {
1645 while (my($name, $struct) = each %structs) {
1646 print_accessors(\*XS, $name, $struct);
7c1d48a5 1647 }
ee8c7f54 1648 }
ead2a595 1649}
1650
a0d0e21e 1651close XS;
5273d82d 1652
1653if (%types_seen) {
1654 my $type;
1655 warn "Writing $ext$modpname/typemap\n";
1656 open TM, ">typemap" or die "Cannot open typemap file for write: $!";
1657
3cb4da91 1658 for $type (sort keys %types_seen) {
ddf6bed1 1659 my $entry = assign_typemap_entry $type;
1660 print TM $type, "\t" x (5 - int((length $type)/8)), "\t$entry\n"
5273d82d 1661 }
1662
ddf6bed1 1663 print TM <<'EOP' if $need_opaque; # Older Perls do not have correct entry
1664#############################################################################
1665INPUT
1666T_OPAQUE_STRUCT
1667 if (sv_derived_from($arg, \"${ntype}\")) {
1668 STRLEN len;
1669 char *s = SvPV((SV*)SvRV($arg), len);
1670
1671 if (len != sizeof($var))
1672 croak(\"Size %d of packed data != expected %d\",
1673 len, sizeof($var));
1674 $var = *($type *)s;
1675 }
1676 else
1677 croak(\"$var is not of type ${ntype}\")
1678#############################################################################
1679OUTPUT
1680T_OPAQUE_STRUCT
1681 sv_setref_pvn($arg, \"${ntype}\", (char *)&$var, sizeof($var));
1682EOP
1683
5273d82d 1684 close TM or die "Cannot close typemap file for write: $!";
1685}
1686
2920c5d2 1687} # if( ! $opt_X )
e1666bf5 1688
8e07c86e 1689warn "Writing $ext$modpname/Makefile.PL\n";
1690open(PL, ">Makefile.PL") || die "Can't create $ext$modpname/Makefile.PL: $!\n";
a0d0e21e 1691
8bc03d0d 1692print PL <<END;
a0d0e21e 1693use ExtUtils::MakeMaker;
1694# See lib/ExtUtils/MakeMaker.pm for details of how to influence
42793c05 1695# the contents of the Makefile that is written.
8bc03d0d 1696WriteMakefile(
1697 'NAME' => '$module',
1698 'VERSION_FROM' => '$modfname.pm', # finds \$VERSION
1699 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
a0d0e21e 1700END
8bc03d0d 1701if (!$opt_X) { # print C stuff, unless XS is disabled
ddf6bed1 1702 $opt_F = '' unless defined $opt_F;
22d4bb9c 1703 my $I = (((glob '*.h') || (glob '*.hh')) ? '-I.' : '');
1704 my $Ihelp = ($I ? '-I. ' : '');
1705 my $Icomment = ($I ? '' : <<EOC);
1706 # Insert -I. if you add *.h files later:
1707EOC
1708
8bc03d0d 1709 print PL <<END;
1710 'LIBS' => ['$extralibs'], # e.g., '-lm'
1711 'DEFINE' => '$opt_F', # e.g., '-DHAVE_SOMETHING'
22d4bb9c 1712$Icomment 'INC' => '$I', # e.g., '$Ihelp-I/usr/include/other'
1713END
1714
1715 my $C = grep $_ ne "$modfname.c", (glob '*.c'), (glob '*.cc'), (glob '*.C');
1716 my $Cpre = ($C ? '' : '# ');
1717 my $Ccomment = ($C ? '' : <<EOC);
1718 # Un-comment this if you add C files to link with later:
1719EOC
1720
1721 print PL <<END;
1722$Ccomment $Cpre\'OBJECT' => '\$(O_FILES)', # link all the C files too
8bc03d0d 1723END
2920c5d2 1724}
a0d0e21e 1725print PL ");\n";
f508c652 1726close(PL) || die "Can't close $ext$modpname/Makefile.PL: $!\n";
1727
1728warn "Writing $ext$modpname/test.pl\n";
1729open(EX, ">test.pl") || die "Can't create $ext$modpname/test.pl: $!\n";
1730print EX <<'_END_';
1731# Before `make install' is performed this script should be runnable with
1732# `make test'. After `make install' it should work as `perl test.pl'
1733
1734######################### We start with some black magic to print on failure.
1735
1736# Change 1..1 below to 1..last_test_to_print .
1737# (It may become useful if the test is moved to ./t subdirectory.)
1738
5ae7f1db 1739BEGIN { $| = 1; print "1..1\n"; }
f508c652 1740END {print "not ok 1\n" unless $loaded;}
1741_END_
1742print EX <<_END_;
1743use $module;
1744_END_
1745print EX <<'_END_';
1746$loaded = 1;
1747print "ok 1\n";
1748
1749######################### End of black magic.
1750
1751# Insert your test code below (better if it prints "ok 13"
1752# (correspondingly "not ok 13") depending on the success of chunk 13
1753# of the test code):
e1666bf5 1754
f508c652 1755_END_
1756close(EX) || die "Can't close $ext$modpname/test.pl: $!\n";
a0d0e21e 1757
c0f8b9cd 1758unless ($opt_C) {
ddf6bed1 1759 warn "Writing $ext$modpname/Changes\n";
1760 $" = ' ';
1761 open(EX, ">Changes") || die "Can't create $ext$modpname/Changes: $!\n";
1762 @ARGS = map {/[\s\"\'\`\$*?^|&<>\[\]\{\}\(\)]/ ? "'$_'" : $_} @ARGS;
1763 print EX <<EOP;
1764Revision history for Perl extension $module.
1765
1766$TEMPLATE_VERSION @{[scalar localtime]}
1767\t- original version; created by h2xs $H2XS_VERSION with options
1768\t\t@ARGS
1769
1770EOP
1771 close(EX) || die "Can't close $ext$modpname/Changes: $!\n";
c0f8b9cd 1772}
c07a80fd 1773
1774warn "Writing $ext$modpname/MANIFEST\n";
5ae7f1db 1775open(MANI,'>MANIFEST') or die "Can't create MANIFEST: $!";
3cb4da91 1776my @files = <*>;
5ae7f1db 1777if (!@files) {
1778 eval {opendir(D,'.');};
1779 unless ($@) { @files = readdir(D); closedir(D); }
1780}
1781if (!@files) { @files = map {chomp && $_} `ls`; }
55497cff 1782if ($^O eq 'VMS') {
1783 foreach (@files) {
1784 # Clip trailing '.' for portability -- non-VMS OSs don't expect it
1785 s%\.$%%;
1786 # Fix up for case-sensitive file systems
1787 s/$modfname/$modfname/i && next;
1788 $_ = "\U$_" if $_ eq 'manifest' or $_ eq 'changes';
bbce6d69 1789 $_ = 'Makefile.PL' if $_ eq 'makefile.pl';
55497cff 1790 }
1791}
3e3baf6d 1792print MANI join("\n",@files), "\n";
5ae7f1db 1793close MANI;
40000a8c 1794!NO!SUBS!
4633a7c4 1795
1796close OUT or die "Can't close $file: $!";
1797chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1798exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
8a5546a1 1799chdir $origdir;