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 2011/02/11 20:41:24 UTC

[lucy-commits] svn commit: r1069929 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs lib/Clownfish/Type.pm src/CFCSymbol.c src/CFCSymbol.h src/CFCType.c src/CFCType.h

Author: marvin
Date: Fri Feb 11 19:41:23 2011
New Revision: 1069929

URL: http://svn.apache.org/viewvc?rev=1069929&view=rev
Log:
Port object-related routines in Clownfish::Type to C.

Modified:
    incubator/lucy/trunk/clownfish/lib/Clownfish.xs
    incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm
    incubator/lucy/trunk/clownfish/src/CFCSymbol.c
    incubator/lucy/trunk/clownfish/src/CFCSymbol.h
    incubator/lucy/trunk/clownfish/src/CFCType.c
    incubator/lucy/trunk/clownfish/src/CFCType.h

Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Fri Feb 11 19:41:23 2011
@@ -470,6 +470,24 @@ CODE:
 OUTPUT: RETVAL
 
 SV*
+_new_object(klass, flags, parcel_sv, specifier, indirection)
+    const char *klass;
+    int flags;
+    SV *parcel_sv;
+    const char *specifier;
+    int indirection;
+CODE:
+    CFCParcel *parcel = NULL;
+    if (SvOK(parcel_sv) && sv_derived_from(parcel_sv, "Clownfish::Parcel")) {
+        IV objint = SvIV((SV*)SvRV(parcel_sv));
+        parcel = INT2PTR(CFCParcel*, objint);
+    }   
+    CFCType *self = CFCType_new_object(flags, parcel, specifier, indirection);
+    RETVAL = newSV(0);
+	sv_setref_pv(RETVAL, klass, (void*)self);
+OUTPUT: RETVAL
+
+SV*
 _new_void(klass, is_const)
     const char *klass;
     int is_const;
@@ -531,6 +549,18 @@ CODE:
 OUTPUT: RETVAL
 
 unsigned
+INCREMENTED(...)
+CODE:
+    RETVAL = CFCTYPE_INCREMENTED;
+OUTPUT: RETVAL
+
+unsigned
+DECREMENTED(...)
+CODE:
+    RETVAL = CFCTYPE_DECREMENTED;
+OUTPUT: RETVAL
+
+unsigned
 VOID(...)
 CODE:
     RETVAL = CFCTYPE_VOID;
@@ -607,6 +637,8 @@ ALIAS:
     is_arbitrary    = 28
     is_composite    = 30
     get_width       = 32
+    incremented     = 34
+    decremented     = 36
 PPCODE:
 {
     START_SET_OR_GET_SWITCH
@@ -674,6 +706,12 @@ PPCODE:
         case 32:
             retval = newSVuv(CFCType_get_width(self));
             break;
+        case 34:
+            retval = newSVuv(CFCType_incremented(self));
+            break;
+        case 36:
+            retval = newSVuv(CFCType_decremented(self));
+            break;
     END_SET_OR_GET_SWITCH
 }
 

Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm Fri Feb 11 19:41:23 2011
@@ -24,8 +24,6 @@ use Scalar::Util qw( blessed );
 use Carp;
 
 # Inside-out member vars.
-our %incremented;
-our %decremented;
 our %array;
 our %child;
 
@@ -95,17 +93,6 @@ sub new_integer {
     return $package->_new_integer( $flags, $args{specifier} );
 }
 
-our %new_object_PARAMS = (
-    const       => undef,
-    specifier   => undef,
-    indirection => 1,
-    parcel      => undef,
-    incremented => 0,
-    decremented => 0,
-    nullable    => 0,
-);
-
-
 our %new_float_PARAMS = (
     const     => undef,
     specifier => undef,
@@ -120,52 +107,31 @@ sub new_float {
     return $package->_new_float( $flags, $args{specifier} );
 }
 
+our %new_object_PARAMS = (
+    const       => undef,
+    specifier   => undef,
+    indirection => 1,
+    parcel      => undef,
+    incremented => 0,
+    decremented => 0,
+    nullable    => 0,
+);
+
 sub new_object {
     my ( $either, %args ) = @_;
     verify_args( \%new_object_PARAMS, %args ) or confess $@;
-    my $incremented = delete $args{incremented} || 0;
-    my $decremented = delete $args{decremented} || 0;
-    my $nullable    = delete $args{nullable}    || 0;
+    my $flags = 0;
+    $flags |= INCREMENTED if $args{incremented};
+    $flags |= DECREMENTED if $args{decremented};
+    $flags |= NULLABLE    if $args{nullable};
+    $flags |= CONST       if $args{const};
     $args{indirection} = 1 unless defined $args{indirection};
-    my $indirection = $args{indirection};
-    $args{parcel} ||= Clownfish::Parcel->default_parcel;
+    my $parcel = Clownfish::Parcel->acquire( $args{parcel} );
+    my $package = ref($either) || $either;
     confess("Missing required param 'specifier'")
         unless defined $args{specifier};
-
-    # Derive boolean indicating whether this type is a string type.
-    my $is_string_type = $args{specifier} =~ /CharBuf/ ? 1 : 0;
-
-    my $self = $either->new(
-        %args,
-        object      => 1,
-        string_type => $is_string_type,
-    );
-    $incremented{$self} = $incremented;
-    $decremented{$self} = $decremented;
-    $self->set_nullable($nullable);
-    my $prefix    = $self->get_parcel->get_prefix;
-    my $specifier = $self->get_specifier;
-
-    # Validate params.
-    confess("Indirection must be 1") unless $indirection == 1;
-    confess("Can't be both incremented and decremented")
-        if ( $incremented && $decremented );
-    confess("Illegal specifier: '$specifier'")
-        unless $specifier
-            =~ /^(?:$prefix)?[A-Z][A-Za-z0-9]*[a-z]+[A-Za-z0-9]*(?!\w)/;
-
-    # Add $prefix if necessary.
-    if ( $specifier !~ /^$prefix/ ) {
-        $specifier = $prefix . $specifier;
-        $self->set_specifier($specifier);
-    }
-
-    # Cache C representation.
-    my $string = $self->const ? 'const ' : '';
-    $string .= "$specifier*";
-    $self->set_c_string($string);
-
-    return $self;
+    return $package->_new_object( $flags, $parcel, $args{specifier},
+        $args{indirection} );
 }
 
 our %new_composite_PARAMS = (
@@ -239,15 +205,11 @@ sub DESTROY {
     my $self = shift;
     delete $array{$self};
     delete $child{$self};
-    delete $incremented{$self};
-    delete $decremented{$self};
     $self->_destroy;
 }
 
 sub get_array     { $array{ +shift } }
 sub _get_child    { $child{ +shift } }
-sub incremented   { $incremented{ +shift } }
-sub decremented   { $decremented{ +shift } }
 
 sub similar {
     my ( $self, $other ) = @_;
@@ -265,8 +227,6 @@ sub equals {
         return 0 unless $other->_get_child;
         return 0 unless $child->equals( $other->_get_child );
     }
-    return 0 if ( $self->incremented xor $other->incremented );
-    return 0 if ( $self->decremented xor $other->decremented );
     return 0 if ( $self->get_array xor $other->get_array );
     return 0 if ( $self->get_array and $self->get_array ne $other->get_array );
     return $self->_equals($other);

Modified: incubator/lucy/trunk/clownfish/src/CFCSymbol.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCSymbol.c?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCSymbol.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCSymbol.c Fri Feb 11 19:41:23 2011
@@ -89,6 +89,14 @@ S_validate_class_name(const char *class_
     return true;
 }
 
+int
+CFCSymbol_validate_class_name_component(const char *name)
+{
+    if (!S_validate_class_name(name)) { return false; }
+    if (strchr(name, ':') != NULL) { return false; }
+    return true;
+}
+
 static int
 S_validate_class_cnick(const char *class_cnick)
 {
@@ -103,9 +111,7 @@ S_validate_class_cnick(const char *class
     }
 
     // Same as one component of a class name.
-    if (!S_validate_class_name(class_cnick)) { return false; }
-    if (strchr(class_cnick, ':') != NULL) { return false; }
-    return true;
+    return CFCSymbol_validate_class_name_component(class_cnick);
 }
 
 static int

Modified: incubator/lucy/trunk/clownfish/src/CFCSymbol.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCSymbol.h?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCSymbol.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCSymbol.h Fri Feb 11 19:41:23 2011
@@ -29,6 +29,13 @@ struct CFCSymbol {
 };
 #endif
 
+/** Return true if the supplied string is comprised solely of alphanumeric
+ * characters, begins with an uppercase letter, and contains at least one
+ * lower case letter.
+ */
+int
+CFCSymbol_validate_class_name_component(const char *name);
+
 CFCSymbol*
 CFCSymbol_new(struct CFCParcel *parcel, const char *exposure, const char *class_name, 
               const char *class_cnick, const char *micro_sym);

Modified: incubator/lucy/trunk/clownfish/src/CFCType.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCType.c?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCType.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCType.c Fri Feb 11 19:41:23 2011
@@ -153,6 +153,62 @@ CFCType_new_float(int flags, const char 
 }
 
 CFCType*
+CFCType_new_object(int flags, CFCParcel *parcel, const char *specifier, 
+                   int indirection)
+{
+    // Validate params.
+    if (indirection != 1) {
+        croak("Parameter 'indirection' can only be 1");
+    }
+    if (!specifier || !strlen(specifier)) {
+        croak("Missing required param 'specifier'");
+    }
+    if ((flags & CFCTYPE_INCREMENTED) && (flags & CFCTYPE_DECREMENTED)) {
+        croak("Can't be both incremented and decremented");
+    }
+    if (!parcel) {
+        croak("Missing required param 'parcel'");
+    }
+
+    // Add flags.
+    flags |= CFCTYPE_OBJECT;
+    if (strstr(specifier, "CharBuf")) {
+        // Determine whether this type is a string type.
+        flags |= CFCTYPE_STRING_TYPE;
+    }
+
+    const char *prefix = CFCParcel_get_prefix(parcel);
+    const size_t MAX_SPECIFIER_LEN = 256;
+    char full_specifier[MAX_SPECIFIER_LEN + 1];
+    char small_specifier[MAX_SPECIFIER_LEN + 1];
+    if (strlen(prefix) + strlen(specifier) > MAX_SPECIFIER_LEN) {
+        croak("Specifier and/or parcel prefix too long");
+    }
+    if (strstr(specifier, prefix) != specifier) {
+        sprintf(full_specifier, "%s%s", prefix, specifier);
+        strcpy(small_specifier, specifier);
+    }
+    else {
+        strcpy(full_specifier, specifier);
+        strcpy(small_specifier, specifier + strlen(prefix));
+    }
+    if (!CFCSymbol_validate_class_name_component(small_specifier)) {
+        croak("Invalid specifier: '%s'", specifier);
+    }
+    
+    // Cache C representation.
+    char c_string[MAX_SPECIFIER_LEN + 10];
+    if (flags & CFCTYPE_CONST) {
+        sprintf(c_string, "const %s*", full_specifier);
+    }
+    else {
+        sprintf(c_string, "%s*", full_specifier);
+    }
+
+    return CFCType_new(flags, parcel, full_specifier, 1, c_string);
+}
+
+CFCType*
 CFCType_new_void(int is_const)
 {
     int flags = CFCTYPE_VOID;
@@ -223,6 +279,8 @@ CFCType_equals(CFCType *self, CFCType *o
         || (CFCType_is_va_list(self)   ^ CFCType_is_va_list(other))
         || (CFCType_is_arbitrary(self) ^ CFCType_is_arbitrary(other))
         || (CFCType_is_composite(self) ^ CFCType_is_composite(other))
+        || (CFCType_incremented(self)  ^ CFCType_incremented(other))
+        || (CFCType_decremented(self)  ^ CFCType_decremented(other))
     ) { 
         return false; 
     }
@@ -299,6 +357,18 @@ CFCType_nullable(CFCType *self)
 }
 
 int
+CFCType_incremented(CFCType *self)
+{
+    return !!(self->flags & CFCTYPE_INCREMENTED);
+}
+
+int
+CFCType_decremented(CFCType *self)
+{
+    return !!(self->flags & CFCTYPE_DECREMENTED);
+}
+
+int
 CFCType_is_void(CFCType *self)
 {
     return !!(self->flags & CFCTYPE_VOID);

Modified: incubator/lucy/trunk/clownfish/src/CFCType.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCType.h?rev=1069929&r1=1069928&r2=1069929&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCType.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCType.h Fri Feb 11 19:41:23 2011
@@ -20,14 +20,16 @@ struct CFCParcel;
 #define CFCTYPE_CONST       0x00000001
 #define CFCTYPE_NULLABLE    0x00000002
 #define CFCTYPE_VOID        0x00000004
-#define CFCTYPE_OBJECT      0x00000008
-#define CFCTYPE_PRIMITIVE   0x00000010
-#define CFCTYPE_INTEGER     0x00000020
-#define CFCTYPE_FLOATING    0x00000040
-#define CFCTYPE_STRING_TYPE 0x00000080
-#define CFCTYPE_VA_LIST     0x00000100
-#define CFCTYPE_ARBITRARY   0x00000200
-#define CFCTYPE_COMPOSITE   0x00000400
+#define CFCTYPE_INCREMENTED 0x00000008
+#define CFCTYPE_DECREMENTED 0x00000010
+#define CFCTYPE_OBJECT      0x00000020
+#define CFCTYPE_PRIMITIVE   0x00000040
+#define CFCTYPE_INTEGER     0x00000080
+#define CFCTYPE_FLOATING    0x00000100
+#define CFCTYPE_STRING_TYPE 0x00000200
+#define CFCTYPE_VA_LIST     0x00000400
+#define CFCTYPE_ARBITRARY   0x00000800
+#define CFCTYPE_COMPOSITE   0x00001000
 
 CFCType*
 CFCType_new(int flags, struct CFCParcel *parcel, const char *specifier,
@@ -44,6 +46,10 @@ CFCType*
 CFCType_new_float(int flags, const char *specifier);
 
 CFCType*
+CFCType_new_object(int flags, struct CFCParcel *parcel, const char *specifier,
+                   int indirection);
+
+CFCType*
 CFCType_new_void(int is_const);
 
 CFCType*
@@ -86,6 +92,12 @@ int
 CFCType_nullable(CFCType *self);
 
 int
+CFCType_incremented(CFCType *self);
+
+int
+CFCType_decremented(CFCType *self);
+
+int
 CFCType_is_void(CFCType *self);
 
 int