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/20 03:44:08 UTC
[lucy-commits] svn commit: r1072480 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs
lib/Clownfish/File.pm lib/Clownfish/Parser.pm src/CFCFile.c src/CFCFile.h
Author: marvin
Date: Sun Feb 20 02:44:07 2011
New Revision: 1072480
URL: http://svn.apache.org/viewvc?rev=1072480&view=rev
Log:
Port the rest of Clownfish::File to C.
Modified:
incubator/lucy/trunk/clownfish/lib/Clownfish.xs
incubator/lucy/trunk/clownfish/lib/Clownfish/File.pm
incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm
incubator/lucy/trunk/clownfish/src/CFCFile.c
incubator/lucy/trunk/clownfish/src/CFCFile.h
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1072480&r1=1072479&r2=1072480&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Sun Feb 20 02:44:07 2011
@@ -210,6 +210,13 @@ PPCODE:
CFCFile_destroy(self);
void
+add_block(self, block)
+ CFCFile *self;
+ CFCBase *block;
+PPCODE:
+ CFCFile_add_block(self, block);
+
+void
_set_or_get(self, ...)
CFCFile *self;
ALIAS:
@@ -219,6 +226,8 @@ ALIAS:
guard_name = 6
guard_start = 8
guard_close = 10
+ blocks = 12
+ classes = 14
PPCODE:
{
START_SET_OR_GET_SWITCH
@@ -248,9 +257,66 @@ PPCODE:
retval = newSVpv(value, strlen(value));
}
break;
+ case 12: {
+ AV *av = newAV();
+ CFCBase **blocks = CFCFile_blocks(self);
+ size_t i;
+ for (i = 0; blocks[i] != NULL; i++) {
+ SV *ref = newRV((SV*)CFCBase_get_perl_obj(blocks[i]));
+ av_store(av, i, ref);
+ }
+ retval = newRV((SV*)av);
+ SvREFCNT_dec(av);
+ break;
+ }
+ case 14: {
+ AV *av = newAV();
+ CFCClass **classes = CFCFile_classes(self);
+ size_t i;
+ for (i = 0; classes[i] != NULL; i++) {
+ SV *ref = newRV((SV*)CFCBase_get_perl_obj(
+ (CFCBase*)classes[i]));
+ av_store(av, i, ref);
+ }
+ retval = newRV((SV*)av);
+ SvREFCNT_dec(av);
+ break;
+ }
END_SET_OR_GET_SWITCH
}
+SV*
+_gen_path(self, base_dir = NULL)
+ CFCFile *self;
+ const char *base_dir;
+ALIAS:
+ c_path = 1
+ h_path = 2
+ cfh_path = 3
+CODE:
+{
+ size_t buf_size = CFCFile_path_buf_size(self, base_dir);
+ RETVAL = newSV(buf_size);
+ SvPOK_on(RETVAL);
+ char *buf = SvPVX(RETVAL);
+ switch(ix) {
+ case 1:
+ CFCFile_c_path(self, buf, buf_size, base_dir);
+ break;
+ case 2:
+ CFCFile_h_path(self, buf, buf_size, base_dir);
+ break;
+ case 3:
+ CFCFile_cfh_path(self, buf, buf_size, base_dir);
+ break;
+ default:
+ croak("unexpected ix value: %d", ix);
+ }
+ SvCUR_set(RETVAL, strlen(buf));
+}
+OUTPUT: RETVAL
+
+
MODULE = Clownfish PACKAGE = Clownfish::Function
SV*
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/File.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/File.pm?rev=1072480&r1=1072479&r2=1072480&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/File.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/File.pm Sun Feb 20 02:44:07 2011
@@ -17,68 +17,16 @@ use strict;
use warnings;
package Clownfish::File;
-use Clownfish::Util qw( verify_args a_isa_b );
-use Clownfish::Parcel;
-use Scalar::Util qw( blessed );
-use File::Spec::Functions qw( catfile );
+use Clownfish::Util qw( verify_args );
use Carp;
-# Inside out member vars.
-our %blocks;
-
-our %new_PARAMS = (
- source_class => undef,
-);
+our %new_PARAMS = ( source_class => undef, );
sub new {
my ( $either, %args ) = @_;
verify_args( \%new_PARAMS, %args ) or confess $@;
my $package = ref($either) || $either;
- my $self = $either->_new($args{source_class});
- $blocks{$self} = [];
- return $self;
-}
-
-sub DESTROY {
- my $self = shift;
- delete $blocks{$self};
- $self->_destroy;
-}
-
-our %block_types = (
- 'Clownfish::Parcel' => 1,
- 'Clownfish::Class' => 1,
- 'Clownfish::CBlock' => 1,
-);
-
-sub add_block {
- my ( $self, $block ) = @_;
- my $block_class = ref($block);
- confess("Invalid block type: $block_class")
- unless $block_types{$block_class};
- push @{ $blocks{$self} }, $block;
-}
-
-sub blocks { $blocks{ +shift } }
-
-sub classes {
- my $self = shift;
- my @classes
- = grep { ref $_ and $_->isa('Clownfish::Class') } @{ $self->blocks };
- return \@classes;
-}
-
-sub c_path { return $_[0]->_some_path( $_[1], '.c' ) }
-sub h_path { return $_[0]->_some_path( $_[1], '.h' ) }
-sub cfh_path { return $_[0]->_some_path( $_[1], '.cfh' ) }
-
-sub _some_path {
- my ( $self, $base_dir, $ext ) = @_;
- my @components = split( '::', $self->get_source_class );
- unshift @components, $base_dir
- if defined $base_dir;
- $components[-1] .= $ext;
- return catfile(@components);
+ return $either->_new( $args{source_class} );
}
1;
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm?rev=1072480&r1=1072479&r2=1072480&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm Sun Feb 20 02:44:07 2011
@@ -508,7 +508,7 @@ sub new_file {
my ( undef, $item, $arg ) = @_;
my $file = Clownfish::File->new( source_class => $arg->{source_class}, );
for my $block ( @{ $item->{'major_block(s)'} } ) {
- $file->add_block( $block, ref($block) );
+ $file->add_block($block);
}
return $file;
}
Modified: incubator/lucy/trunk/clownfish/src/CFCFile.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCFile.c?rev=1072480&r1=1072479&r2=1072480&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCFile.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCFile.c Sun Feb 20 02:44:07 2011
@@ -24,18 +24,30 @@
#define false 0
#endif
+#ifdef _WIN32
+#define PATH_SEP "\\"
+#define PATH_SEP_CHAR '\\'
+#else
+#define PATH_SEP "/"
+#define PATH_SEP_CHAR '/'
+#endif
+
#define CFC_NEED_BASE_STRUCT_DEF
#include "CFCBase.h"
#include "CFCFile.h"
#include "CFCUtil.h"
+#include "CFCClass.h"
struct CFCFile {
CFCBase base;
+ CFCBase **blocks;
+ CFCClass **classes;
int modified;
char *source_class;
char *guard_name;
char *guard_start;
char *guard_close;
+ char *path_part;
};
CFCFile*
@@ -53,6 +65,9 @@ CFCFile_init(CFCFile *self, const char *
CFCUTIL_NULL_CHECK(source_class);
self->modified = false;
self->source_class = CFCUtil_strdup(source_class);
+ self->blocks = (CFCBase**)calloc(1, sizeof(CFCBase*));
+ self->classes = (CFCClass**)calloc(1, sizeof(CFCBase*));
+ if (!self->blocks || !self->classes) { croak("malloc failed"); }
// Derive include guard name, plus C code for opening and closing the
// guard.
@@ -72,7 +87,7 @@ CFCFile_init(CFCFile *self, const char *
i++;
}
else {
- self->guard_name[j] = toupper(source_class[i]);
+ self->guard_name[j] = toupper(c);
}
}
self->guard_name[j] = '\0';
@@ -83,20 +98,157 @@ CFCFile_init(CFCFile *self, const char *
self->guard_name);
if (check < 0) { croak("sprintf failed"); }
+ // Cache partial path derived from source_class.
+ self->path_part = malloc(len + 1);
+ if (!self->path_part) { croak("malloc failed"); }
+ for (i = 0, j = 0; i < len; i++, j++) {
+ char c = source_class[i];
+ if (c == ':') {
+ self->path_part[j] = PATH_SEP_CHAR;
+ i++;
+ }
+ else {
+ self->path_part[j] = c;
+ }
+ }
+ self->path_part[j] = '\0';
+
return self;
}
void
CFCFile_destroy(CFCFile *self)
{
+ size_t i;
+ /*
+ for (i = 0; self->blocks[i] != NULL; i++) {
+ CFCBase_decref(self->blocks[i]);
+ }
+ free(self->blocks);
+ for (i = 0; self->classes[i] != NULL; i++) {
+ CFCBase_decref((CFCBase*)self->classes[i]);
+ }
+ */
+ free(self->classes);
free(self->guard_name);
free(self->guard_start);
free(self->guard_close);
free(self->source_class);
+ free(self->path_part);
CFCBase_destroy((CFCBase*)self);
}
void
+CFCFile_add_block(CFCFile *self, CFCBase *block)
+{
+ CFCUTIL_NULL_CHECK(block);
+ const char *cfc_class = CFCBase_get_cfc_class(block);
+
+ // Add to classes array if the block is a CFCClass.
+ if (strcmp(cfc_class, "Clownfish::Class") == 0) {
+ size_t num_class_blocks = 0;
+ while (self->classes[num_class_blocks] != NULL) {
+ num_class_blocks++;
+ }
+ num_class_blocks++;
+ size_t size = (num_class_blocks + 1) * sizeof(CFCClass*);
+ self->classes = (CFCClass**)realloc(self->classes, size);
+ if (!self->classes) { croak("realloc failed"); }
+ self->classes[num_class_blocks - 1]
+ = (CFCClass*)CFCBase_incref(block);
+ self->classes[num_class_blocks] = NULL;
+ }
+
+ // Add to blocks array.
+ if ( strcmp(cfc_class, "Clownfish::Class") == 0
+ || strcmp(cfc_class, "Clownfish::Parcel") == 0
+ || strcmp(cfc_class, "Clownfish::CBlock") == 0
+ ) {
+ size_t num_blocks = 0;
+ while (self->blocks[num_blocks] != NULL) {
+ num_blocks++;
+ }
+ num_blocks++;
+ size_t size = (num_blocks + 1) * sizeof(CFCBase*);
+ self->blocks = (CFCBase**)realloc(self->blocks, size);
+ if (!self->blocks) { croak("realloc failed"); }
+ self->blocks[num_blocks - 1] = CFCBase_incref(block);
+ self->blocks[num_blocks] = NULL;
+ }
+ else {
+ croak("Wrong kind of object: '%s'", cfc_class);
+ }
+}
+
+static void
+S_some_path(CFCFile *self, char *buf, size_t buf_size, const char *base_dir,
+ const char *ext)
+{
+ size_t needed = CFCFile_path_buf_size(self, base_dir);
+ if (strlen(ext) > 4) {
+ croak("ext cannot be more than 4 characters.");
+ }
+ if (needed > buf_size) {
+ croak("Need buf_size of %lu, but got %lu", needed, buf_size);
+ }
+ if (base_dir) {
+ int check = sprintf(buf, "%s" PATH_SEP "%s%s", base_dir,
+ self->path_part, ext);
+ if (check < 0) { croak("sprintf failed"); }
+ }
+ else {
+ int check = sprintf(buf, "%s%s", self->path_part, ext);
+ if (check < 0) { croak("sprintf failed"); }
+ }
+}
+
+size_t
+CFCFile_path_buf_size(CFCFile *self, const char *base_dir)
+{
+ size_t size = strlen(self->path_part);
+ size += 4; // Max extension length.
+ size += 1; // NULL-termination.
+ if (base_dir) {
+ size += strlen(base_dir);
+ size += strlen(PATH_SEP);
+ }
+ return size;
+}
+
+void
+CFCFile_c_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir)
+{
+ S_some_path(self, buf, buf_size, base_dir, ".c");
+}
+
+void
+CFCFile_h_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir)
+{
+ S_some_path(self, buf, buf_size, base_dir, ".h");
+}
+
+void
+CFCFile_cfh_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir)
+{
+ S_some_path(self, buf, buf_size, base_dir, ".cfh");
+}
+
+CFCBase**
+CFCFile_blocks(CFCFile *self)
+{
+ return self->blocks;
+}
+
+CFCClass**
+CFCFile_classes(CFCFile *self)
+{
+ return self->classes;
+}
+
+void
CFCFile_set_modified(CFCFile *self, int modified)
{
self->modified = !!modified;
Modified: incubator/lucy/trunk/clownfish/src/CFCFile.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCFile.h?rev=1072480&r1=1072479&r2=1072480&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCFile.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCFile.h Sun Feb 20 02:44:07 2011
@@ -18,6 +18,8 @@
#define H_CFCFILE
typedef struct CFCFile CFCFile;
+struct CFCBase;
+struct CFCClass;
CFCFile*
CFCFile_new(const char *source_class);
@@ -29,6 +31,33 @@ void
CFCFile_destroy(CFCFile *self);
void
+CFCFile_add_block(CFCFile *self, CFCBase *block);
+
+/** Calculate the size of the buffer needed for a call to c_path(), h_path(),
+ * or cfh_path().
+ */
+size_t
+CFCFile_path_buf_size(CFCFile *self, const char *base_dir);
+
+void
+CFCFile_c_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir);
+
+void
+CFCFile_h_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir);
+
+void
+CFCFile_cfh_path(CFCFile *self, char *buf, size_t buf_size,
+ const char *base_dir);
+
+struct CFCBase**
+CFCFile_blocks(CFCFile *self);
+
+struct CFCClass**
+CFCFile_classes(CFCFile *self);
+
+void
CFCFile_set_modified(CFCFile *self, int modified);
int