From: Gurusamy Sarathy Date: Wed, 22 Mar 2000 14:28:56 +0000 (+0000) Subject: backout change#5708; fixups for behavior of recently added -a switch; X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=32fb2b7854b4f571a20a8804fd6ec64101553f6d;p=p5sagit%2Fp5-mst-13.2.git backout change#5708; fixups for behavior of recently added -a switch; support -k and -m switches in h2xs (from Hugo van der Sanden) p4raw-link: @5708 on //depot/perl: ea5e7566745834b0ad6566d9ab0445e5381c11f5 p4raw-id: //depot/perl@5873 --- diff --git a/lib/ExtUtils/xsubpp b/lib/ExtUtils/xsubpp index 4abdee9..5a71e89 100755 --- a/lib/ExtUtils/xsubpp +++ b/lib/ExtUtils/xsubpp @@ -1562,7 +1562,6 @@ sub generate_init { unless defined($type_kind{$type}); ($ntype = $type) =~ s/\s*\*/Ptr/g; - $ntype =~ s/^\s*const\b\s*//; ($subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//; $tk = $type_kind{$type}; $tk =~ s/OBJ$/REF/ if $func_name =~ /DESTROY$/; diff --git a/utils/h2xs.PL b/utils/h2xs.PL index 033ad02..ca0e7cb 100644 --- a/utils/h2xs.PL +++ b/utils/h2xs.PL @@ -105,8 +105,14 @@ XS-based. C<-c> and C<-f> are implicitly enabled. Generate an accessor method for each element of structs and unions. The generated methods are named after the element name; will return the current value of the element if called without additional arguments; and will set -the element to the supplied value (and return the old value) if called with -an additional argument. +the element to the supplied value (and return the new value) if called with +an additional argument. Embedded structures and unions are returned as a +pointer rather than the complete structure, to facilitate chained calls. + +These methods all apply to the Ptr type for the structure; additionally +two methods are constructed for the structure type itself, C<_to_ptr> +which returns a Ptr type pointing to the same structure, and a C +method to construct and return a new structure, initialised to zeroes. =item B<-c> @@ -126,6 +132,16 @@ not found in standard include directories. Print the usage, help and version for this h2xs and exit. +=item B<-k> + +For function arguments declared as C, omit the const attribute in the +generated XS code. + +=item B<-m> + +B: for each variable declared in the header file(s), declare +a perl variable of the same name magically tied to the C variable. + =item B<-n> I Specifies a name to be used for the extension, e.g., S<-n RPC::DCE> @@ -335,6 +351,8 @@ version: $H2XS_VERSION -d Turn on debugging messages. -f Force creation of the extension even if the C header does not exist. -h Display this help message + -k Omit 'const' attribute on function arguments (used with -x). + -m Generate tied variables for access to declared variables. -n Specify a name to use for the extension (recommended). -o Regular expression for \"opaque\" types. -p Specify a prefix which should be removed from the Perl function names. @@ -348,9 +366,9 @@ extra_libraries } -getopts("ACF:M:OPXacdfhn:o:p:s:v:x") || usage; -use vars qw($opt_A $opt_C $opt_F $opt_M $opt_O $opt_P $opt_X $opt_a $opt_c - $opt_d $opt_f $opt_h $opt_n $opt_o $opt_p $opt_s $opt_v $opt_x); +getopts("ACF:M:OPXacdfhkmn:o:p:s:v:x") || usage; +use vars qw($opt_A $opt_C $opt_F $opt_M $opt_O $opt_P $opt_X $opt_a $opt_c $opt_d + $opt_f $opt_h $opt_k $opt_m $opt_n $opt_o $opt_p $opt_s $opt_v $opt_x); usage if $opt_h; @@ -402,6 +420,14 @@ To install C::Scan, execute perl -MCPAN -e "install C::Scan" EOD } + if (($opt_m || $opt_a) && $C::Scan::VERSION < 0.73) { + die <$modfname.xs") || die "Can't create $ext$modpname/$modfname.xs: $!\n"; @@ -576,6 +604,22 @@ if( ! $opt_X ){ # use XS, unless it was disabled @structs{keys %$structs} = values %$structs; } + if ($opt_m) { + %vdecl_hash = %{ $c->get('vdecl_hash') }; + @vdecls = sort keys %vdecl_hash; + for (local $_ = 0; $_ < @vdecls; ++$_) { + my $var = $vdecls[$_]; + my($type, $post) = @{ $vdecl_hash{$var} }; + if (defined $post) { + warn "Can't handle variable '$type $var $post', skipping.\n"; + splice @vdecls, $_, 1; + redo; + } + $type = normalize_type($type); + $vdecl_hash{$var} = $type; + } + } + unless ($tmask_all) { warn "Scanning $filename for typedefs...\n"; my $td = $c->get('typedef_hash'); @@ -683,7 +727,7 @@ $myISA .= ' DynaLoader' unless $opt_X; # no XS $myISA .= ');'; print PM "\n$myISA\n\n"; -my @exported_names = (@const_names, @fnames_no_prefix); +my @exported_names = (@const_names, @fnames_no_prefix, map '$'.$_, @vdecls); print PM<<"END"; # Items to export into callers namespace by default. Note: do not export @@ -706,6 +750,10 @@ our \$VERSION = '$TEMPLATE_VERSION'; END +if (@vdecls) { + printf PM "our(@{[ join ', ', map '$'.$_, @vdecls ]});\n\n"; +} + print PM <<"END" unless $opt_c or $opt_X; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() @@ -747,6 +795,16 @@ bootstrap $module \$VERSION; END } +# tying the variables can happen only after bootstrap +if (@vdecls) { + printf PM <[1]} @$args; my @argtypes = map { normalize_type( $_->[0], 1 ) } @$args; + if ($opt_k) { + s/^\s*const\b\s*// for @argtypes; + } my @argarrays = map { $_->[4] || '' } @$args; my $numargs = @$args; if ($numargs and $argtypes[-1] eq '...') { @@ -1163,12 +1226,99 @@ EOP } } +sub print_tievar_subs { + my($fh, $name, $type) = @_; + print $fh <[0] =~ /_ANON/) { - if (defined $item->[1]) { + if (defined $item->[2]) { push @items, map [ - $_->[0], "$item->[1]_$_->[1]", "$item->[1].$_->[1]" + @$_[0, 1], "$item->[2]_$_->[2]", "$item->[2].$_->[2]", ], @{ $structs{$item->[0]} }; } else { push @items, @{ $structs{$item->[0]} }; } } else { my $type = normalize_type($item->[0]); + my $ttype = $structs{$type} ? normalize_type("$type *") : $type; print $fh <<"EOF"; -$type -$item->[1](THIS, __value = NO_INIT) +$ttype +$item->[2](THIS, __value = NO_INIT) $ptrname THIS $type __value PROTOTYPE: \$;\$ CODE: - RETVAL = THIS->$item->[-1]; if (items > 1) THIS->$item->[-1] = __value; + RETVAL = @{[ + $type eq $ttype ? "THIS->$item->[-1]" : "&(THIS->$item->[-1])" + ]}; OUTPUT: RETVAL @@ -1294,13 +1447,17 @@ sub assign_typemap_entry { return $entry; } +for (@vdecls) { + print_tievar_xsubs(\*XS, $_, $vdecl_hash{$_}); +} + if ($opt_x) { - for my $decl (@$fdecls_parsed) { print_decl(\*XS, $decl) } - if ($opt_a) { - while (my($name, $struct) = each %structs) { - print_accessors(\*XS, $name, $struct); - } + for my $decl (@$fdecls_parsed) { print_decl(\*XS, $decl) } + if ($opt_a) { + while (my($name, $struct) = each %structs) { + print_accessors(\*XS, $name, $struct); } + } } close XS;