You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2009/08/18 01:53:25 UTC

svn commit: r805227 - in /lucene/lucy/trunk/boilerplater: lib/Boilerplater/Parser.pm lib/Boilerplater/Type/Arbitrary.pm t/107-arbitrary_type.t

Author: marvin
Date: Mon Aug 17 23:53:25 2009
New Revision: 805227

URL: http://svn.apache.org/viewvc?rev=805227&view=rev
Log:
Commit LUCY-16, adding Boilerplater::Type::Arbitrary.

Added:
    lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm   (with props)
    lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t   (with props)
Modified:
    lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm

Modified: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm?rev=805227&r1=805226&r2=805227&view=diff
==============================================================================
--- lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm (original)
+++ lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm Mon Aug 17 23:53:25 2009
@@ -10,8 +10,9 @@
 use Boilerplater::Type::Integer;
 use Boilerplater::Type::Float;
 use Boilerplater::Type::Void;
-use Boilerplater::Type::Object;
 use Boilerplater::Type::VAList;
+use Boilerplater::Type::Arbitrary;
+use Boilerplater::Type::Object;
 use Carp;
 
 our $grammar = <<'END_GRAMMAR';
@@ -62,6 +63,10 @@
     va_list_type_specifier
     { Boilerplater::Type::VAList->new }
 
+arbitrary_type:
+    arbitrary_type_specifier
+    { Boilerplater::Parser->new_arbitrary_type(\%item); }
+
 object_type:
     type_qualifier(s?) object_type_specifier '*'
     { Boilerplater::Parser->new_object_type(\%item); }
@@ -92,6 +97,9 @@
 va_list_type_specifier:
     /va_list(?!\w)/
 
+arbitrary_type_specifier:
+    /\w+_t(?!\w)/
+
 object_type_specifier:
     /[A-Z]+[A-Z0-9]*[a-z]+[A-Za-z0-9]*(?!\w)/
 
@@ -125,6 +133,14 @@
     return Boilerplater::Type::Void->new(%args);
 }
 
+sub new_arbitrary_type {
+    my ( undef, $item ) = @_;
+    return Boilerplater::Type::Arbitrary->new(
+        specifier => $item->{arbitrary_type_specifier},
+        parcel    => $parcel,
+    );
+}
+
 sub new_object_type {
     my ( undef, $item ) = @_;
     my %args = (

Added: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm?rev=805227&view=auto
==============================================================================
--- lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm (added)
+++ lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm Mon Aug 17 23:53:25 2009
@@ -0,0 +1,114 @@
+use strict;
+use warnings;
+
+package Boilerplater::Type::Arbitrary;
+use base qw( Boilerplater::Type );
+use Boilerplater::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
+
+Boilerplater::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 Boilerplater itself.
+
+The only constraint is that the C<specifier> 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 .bp file
+and have it parse as an "arbitrary" type.
+
+    floatint_t floatint;
+
+=head1 METHODS
+
+=head2 new
+
+    my $type = Boilerplater::Type->new(
+        specifier => 'floatint_t',    # required
+        parcel    => 'Boil',          # default: undef
+    );
+
+=over
+
+=item * B<specifier> - The name of the type, which must end in "_t".
+
+=item * B<parcel> - A L<Boilerplater::Parcel> or a parcel name.
+
+=back
+
+If C<parcel> is supplied and C<specifier> begins with a capital letter, the
+Parcel's prefix will be prepended to the specifier:
+
+    "foo_t"     -> "foo_t"           # no prefix prepending
+    "Obj_foo_t" -> "boil_Obj_foo_t"  # prefix prepended
+
+=head1 COPYRIGHT AND LICENSE
+
+    /**
+     * Copyright 2009 The Apache Software Foundation
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+     * implied.  See the License for the specific language governing
+     * permissions and limitations under the License.
+     */
+
+=cut

Propchange: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Arbitrary.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t?rev=805227&view=auto
==============================================================================
--- lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t (added)
+++ lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t Mon Aug 17 23:53:25 2009
@@ -0,0 +1,45 @@
+use strict;
+use warnings;
+
+use Test::More tests => 12;
+use Boilerplater::Type::Arbitrary;
+use Boilerplater::Parser;
+
+my $foo_type = Boilerplater::Type::Arbitrary->new(
+    parcel    => 'Boil',
+    specifier => "foo_t",
+);
+is( $foo_type->get_specifier, "foo_t", "get_specifier" );
+is( $foo_type->to_c,          "foo_t", "to_c" );
+
+my $compare_t_type = Boilerplater::Type::Arbitrary->new(
+    parcel    => 'Boil',
+    specifier => "Sort_compare_t",
+);
+is( $compare_t_type->get_specifier,
+    "boil_Sort_compare_t", "Prepend prefix to specifier" );
+is( $compare_t_type->to_c, "boil_Sort_compare_t", "to_c" );
+
+my $evil_twin = Boilerplater::Type::Arbitrary->new(
+    parcel    => 'Boil',
+    specifier => "foo_t",
+);
+ok( $foo_type->equals($evil_twin), "equals" );
+ok( !$foo_type->equals($compare_t_type),
+    "equals spoiled by different specifier"
+);
+
+my $parser = Boilerplater::Parser->new;
+
+for my $specifier (qw( foo_t Sort_compare_t )) {
+    is( $parser->arbitrary_type_specifier($specifier),
+        $specifier, 'arbitrary_type_specifier' );
+    isa_ok(
+        $parser->arbitrary_type($specifier),
+        "Boilerplater::Type::Arbitrary"
+    );
+    ok( !$parser->arbitrary_type_specifier( $specifier . "_y_p_e" ),
+        "arbitrary_type_specifier guards against partial word matches"
+    );
+}
+

Propchange: lucene/lucy/trunk/boilerplater/t/107-arbitrary_type.t
------------------------------------------------------------------------------
    svn:eol-style = native