use strict; use warnings; package Clownfish::Type::Arbitrary; use base qw( Clownfish::Type ); use Clownfish::Util qw( verify_args ); use Scalar::Util qw( blessed ); use Carp; our %new_PARAMS = ( parcel => undef, specifier => undef, ); sub new { my $either = shift; verify_args( \%new_PARAMS, @_ ) or confess $@; my $self = $either->SUPER::new(@_); # Validate specifier. confess("illegal specifier: '$self->{specifier}") unless $self->{specifier} =~ /^\w+$/; if ( $self->{specifier} =~ /^[A-Z]/ and $self->{parcel} ) { my $prefix = $self->{parcel}->get_prefix; # Add $prefix to what appear to be namespaced types. $self->{specifier} = $prefix . $self->{specifier} unless $self->{specifier} =~ /^$prefix/; } # Cache C representation. my $string = $self->const ? 'const ' : ''; $string .= $self->{specifier}; $self->set_c_string($string); return $self; } sub equals { my ( $self, $other ) = @_; return 0 unless blessed($other); return 0 unless $other->isa(__PACKAGE__); return 0 unless $self->{specifier} eq $other->{specifier}; return 1; } 1; __END__ __POD__ =head1 NAME Clownfish::Type::Arbitrary - An arbitrary type. =head1 DESCRIPTION The "arbitrary" type class is a hack that spares us from having to support C types with complex declaration syntaxes -- such as unions, structs, enums, or function pointers -- from within Clownfish itself. The only constraint is that the C must end in "_t". This allows us to create complex types in a C header file... typedef union { float f; int i; } floatint_t; ... pound-include the C header, then use the resulting typedef in a Clownfish header file and have it parse as an "arbitrary" type. floatint_t floatint; =head1 METHODS =head2 new my $type = Clownfish::Type->new( specifier => 'floatint_t', # required parcel => 'Crustacean', # default: undef ); =over =item * B - The name of the type, which must end in "_t". =item * B - A L or a parcel name. =back If C is supplied and C begins with a capital letter, the Parcel's prefix will be prepended to the specifier: foo_t -> foo_t # no prefix prepending Lobster_foo_t -> crust_Lobster_foo_t # prefix prepended =head1 COPYRIGHT AND LICENSE Copyright 2008-2011 Marvin Humphrey This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut