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/06/25 03:01:48 UTC
[lucy-commits] svn commit: r1139475 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs
lib/Clownfish/Binding/Core/Class.pm src/CFCBindClass.c src/CFCBindClass.h
Author: marvin
Date: Sat Jun 25 01:01:48 2011
New Revision: 1139475
URL: http://svn.apache.org/viewvc?rev=1139475&view=rev
Log:
Refactor many chunks of the C header file generation by
Clownfish::Binding::Core::Class into helper routines, ported to C.
Modified:
incubator/lucy/trunk/clownfish/lib/Clownfish.xs
incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm
incubator/lucy/trunk/clownfish/src/CFCBindClass.c
incubator/lucy/trunk/clownfish/src/CFCBindClass.h
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Sat Jun 25 01:01:48 2011
@@ -1783,6 +1783,14 @@ _set_or_get(self, ...)
CFCBindClass *self;
ALIAS:
_short_names_macro = 6
+ _callback_declarations = 8
+ _method_typedefs = 10
+ _parent_include = 12
+ _sub_declarations = 14
+ _inert_var_declarations = 16
+ _method_defs = 18
+ _vt_singleton_def = 20
+ _short_names = 22
PPCODE:
{
START_SET_OR_GET_SWITCH
@@ -1791,6 +1799,46 @@ PPCODE:
retval = newSVpv(value, strlen(value));
}
break;
+ case 8: {
+ char *value = CFCBindClass_callback_declarations(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 10: {
+ char *value = CFCBindClass_method_typedefs(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 12: {
+ char *value = CFCBindClass_parent_include(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 14: {
+ char *value = CFCBindClass_sub_declarations(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 16: {
+ char *value = CFCBindClass_inert_var_declarations(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 18: {
+ char *value = CFCBindClass_method_defs(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 20: {
+ char *value = CFCBindClass_vt_singleton_def(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
+ case 22: {
+ char *value = CFCBindClass_short_names(self);
+ retval = S_sv_eat_c_string(value);
+ }
+ break;
END_SET_OR_GET_SWITCH
}
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Class.pm Sat Jun 25 01:01:48 2011
@@ -38,95 +38,32 @@ sub to_c_header {
my $methods = $client->methods;
my $novel_methods = $client->novel_methods;
my $inert_vars = $client->inert_vars;
- my $vtable_var = $client->full_vtable_var;
- my $short_vt_var = $client->short_vtable_var;
- my $short_struct = $client->get_struct_sym;
- my $full_struct = $client->full_struct_sym;
- my $c_file_sym = "C_" . uc($full_struct);
+ my $c_file_sym = "C_" . uc($client->full_struct_sym);
my $struct_def = _struct_definition($self);
# If class inherits from something, include the parent class's header.
- my $parent_include = "";
- if ( my $parent = $client->get_parent ) {
- $parent_include = $parent->include_h;
- $parent_include = qq|#include "$parent_include"|;
- }
+ my $parent_include = _parent_include($self);
# Add a C function definition for each method and each function.
- my $sub_declarations = "";
- for my $sub ( @$functions, @$novel_methods ) {
- $sub_declarations
- .= Clownfish::Binding::Core::Function->func_declaration($sub)
- . "\n\n";
- }
+ my $sub_declarations = _sub_declarations($self);
# Declare class (a.k.a. "inert") variables.
- my $inert_var_defs = "";
- for my $inert_var (@$inert_vars) {
- $inert_var_defs .= "extern " . $inert_var->global_c . ";\n";
- }
+ my $inert_var_defs = _inert_var_declarations($self);
# Declare typedefs for novel methods, to ease casting.
- my $method_typedefs = '';
- for my $method (@$novel_methods) {
- $method_typedefs
- .= Clownfish::Binding::Core::Method->typedef_dec($method) . "\n";
- }
+ my $method_typedefs = _method_typedefs($self);
# Define method invocation syntax.
- my $method_defs = '';
- for my $method (@$methods) {
- $method_defs .= Clownfish::Binding::Core::Method->method_def(
- method => $method,
- class => $self->_get_client,
- ) . "\n";
- }
+ my $method_defs = _method_defs($self);
# Declare the virtual table singleton object.
- my $vt_type = $self->_get_client->full_vtable_type;
- my $vt = "extern struct $vt_type ${vtable_var}_vt;";
- my $vtable_object
- = "#define $vtable_var ((cfish_VTable*)&${vtable_var}_vt)";
- my $num_methods = scalar @$methods;
+ my $vt_singleton_def = _vt_singleton_def($self);
# Declare cfish_Callback objects.
- my $callback_declarations = "";
- for my $method (@$novel_methods) {
- next unless $method->public || $method->abstract;
- $callback_declarations
- .= Clownfish::Binding::Core::Method->callback_dec($method);
- }
+ my $callback_declarations = _callback_declarations($self);
# Define short names.
- my $short_names = '';
- my $short_names_macro = _short_names_macro($self);
- for my $function (@$functions) {
- my $short_func_sym = $function->short_sym;
- my $full_func_sym = $function->full_sym;
- $short_names .= " #define $short_func_sym $full_func_sym\n";
- }
- for my $inert_var (@$inert_vars) {
- my $short_sym = $inert_var->short_sym;
- my $full_sym = $inert_var->full_sym;
- $short_names .= " #define $short_sym $full_sym\n";
- }
- if ( !$client->inert ) {
- for my $method (@$novel_methods) {
- if ( !$method->isa("Clownfish::Method::Overridden") ) {
- my $short_typedef = $method->short_typedef;
- my $full_typedef = $method->full_typedef;
- $short_names .= " #define $short_typedef $full_typedef\n";
- }
- my $short_func_sym = $method->short_func_sym;
- my $full_func_sym = $method->full_func_sym;
- $short_names .= " #define $short_func_sym $full_func_sym\n";
- }
- for my $method (@$methods) {
- my $short_method_sym = $method->short_method_sym($cnick);
- my $full_method_sym = $method->full_method_sym($cnick);
- $short_names .= " #define $short_method_sym $full_method_sym\n";
- }
- }
+ my $short_names = _short_names($self);
# Make the spacing in the file a little more elegant.
s/\s+$// for ( $method_typedefs, $method_defs, $short_names );
@@ -142,9 +79,7 @@ $inert_var_defs
$sub_declarations
-#ifdef $short_names_macro
$short_names
-#endif /* $short_names_macro */
END_INERT
}
@@ -169,26 +104,8 @@ $method_typedefs
$method_defs
-typedef struct $vt_type {
- cfish_VTable *vtable;
- cfish_ref_t ref;
- cfish_VTable *parent;
- cfish_CharBuf *name;
- uint32_t flags;
- void *x;
- size_t obj_alloc_size;
- size_t vt_alloc_size;
- void *callbacks;
- cfish_method_t methods[$num_methods];
-} $vt_type;
-$vt
-$vtable_object
-
-#ifdef $short_names_macro
- #define $short_struct $full_struct
- #define $short_vt_var $vtable_var
+$vt_singleton_def
$short_names
-#endif /* $short_names_macro */
END_STUFF
}
Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.c?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.c Sat Jun 25 01:01:48 2011
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
#include "CFCBindClass.h"
+#include "CFCBindFunction.h"
#include "CFCBindMethod.h"
#include "CFCBase.h"
#include "CFCClass.h"
@@ -336,3 +337,217 @@ CFCBindClass_short_names_macro(CFCBindCl
return self->short_names_macro;
}
+// Declare cfish_Callback objects.
+char*
+CFCBindClass_callback_declarations(CFCBindClass *self) {
+ CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+ char *declarations = CFCUtil_strdup("");
+ for (int i = 0; novel_methods[i] != NULL; i++) {
+ CFCMethod *method = novel_methods[i];
+ if (CFCMethod_public(method) || CFCMethod_abstract(method)) {
+ char *callback = CFCBindMeth_callback_dec(method);
+ declarations = CFCUtil_cat_strings(declarations, callback, NULL);
+ FREEMEM(callback);
+ }
+ }
+ FREEMEM(novel_methods);
+ return declarations;
+}
+
+// Declare typedefs for novel methods, to ease casting.
+char*
+CFCBindClass_method_typedefs(CFCBindClass *self) {
+ CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+ char *typedefs = CFCUtil_strdup("");
+ for (int i = 0; novel_methods[i] != NULL; i++) {
+ CFCMethod *method = novel_methods[i];
+ char *typedef_str = CFCBindMeth_typdef_dec(method);
+ typedefs = CFCUtil_cat_strings(typedefs, typedef_str, "\n", NULL);
+ FREEMEM(typedef_str);
+ }
+ FREEMEM(novel_methods);
+ return typedefs;
+}
+
+// If class inherits from something, include the parent class's header.
+char*
+CFCBindClass_parent_include(CFCBindClass *self) {
+ char *parent_include = CFCUtil_strdup("");
+ CFCClass *parent = CFCClass_get_parent(self->client);
+ if (parent) {
+ parent_include
+ = CFCUtil_cat_strings(parent_include, "#include \"",
+ CFCClass_include_h(parent), "\"", NULL);
+ }
+ return parent_include;
+}
+
+// Add a C function definition for each method and each function.
+char*
+CFCBindClass_sub_declarations(CFCBindClass *self) {
+ CFCFunction **functions = CFCClass_functions(self->client);
+ CFCMethod** novel_methods = CFCClass_novel_methods(self->client);
+ char *declarations = CFCUtil_strdup("");
+ for (int i = 0; functions[i] != NULL; i++) {
+ CFCFunction *func = functions[i];
+ char *dec = CFCBindFunc_func_declaration(func);
+ declarations = CFCUtil_cat_strings(declarations, dec, "\n\n", NULL);
+ FREEMEM(dec);
+ }
+ for (int i = 0; novel_methods[i] != NULL; i++) {
+ CFCMethod *method = novel_methods[i];
+ char *dec = CFCBindFunc_func_declaration((CFCFunction*)method);
+ declarations = CFCUtil_cat_strings(declarations, dec, "\n\n", NULL);
+ FREEMEM(dec);
+ }
+ FREEMEM(novel_methods);
+ return declarations;
+}
+
+// Declare class (a.k.a. "inert") variables.
+char*
+CFCBindClass_inert_var_declarations(CFCBindClass *self) {
+ CFCVariable **inert_vars = CFCClass_inert_vars(self->client);
+ char *declarations = CFCUtil_strdup("");
+ for (int i = 0; inert_vars[i] != NULL; i++) {
+ const char *global_c = CFCVariable_global_c(inert_vars[i]);
+ declarations = CFCUtil_cat_strings(declarations, "extern ", global_c,
+ ";\n", NULL);
+ }
+ return declarations;
+}
+
+// Define method invocation inline functions.
+char*
+CFCBindClass_method_defs(CFCBindClass *self) {
+ CFCMethod **methods = CFCClass_methods(self->client);
+ char *method_defs = CFCUtil_strdup("");
+ for (int i = 0; methods[i] != NULL; i++) {
+ CFCMethod *method = methods[i];
+ char *def = CFCBindMeth_method_def(method, self->client);
+ method_defs = CFCUtil_cat_strings(method_defs, def, "\n", NULL);
+ FREEMEM(def);
+ }
+ return method_defs;
+}
+
+
+// Define the virtual table singleton object.
+char*
+CFCBindClass_vt_singleton_def(CFCBindClass *self) {
+ CFCClass *client = self->client;
+ const char *vt_type = CFCClass_full_vtable_type(client);
+ const char *vt_var = CFCClass_full_vtable_var(client);
+ const char *vt_hidden = CFCClass_full_vtable_hidden(client);
+ size_t num_methods = CFCClass_num_methods(client);
+
+ const char pattern[] =
+ "typedef struct %s {\n"
+ " cfish_VTable *vtable;\n"
+ " cfish_ref_t ref;\n"
+ " cfish_VTable *parent;\n"
+ " cfish_CharBuf *name;\n"
+ " uint32_t flags;\n"
+ " void *x;\n"
+ " size_t obj_alloc_size;\n"
+ " size_t vt_alloc_size;\n"
+ " void *callbacks;\n"
+ " cfish_method_t methods[%lu];\n"
+ "} %s;\n"
+ "extern struct %s %s;\n"
+ "#define %s ((cfish_VTable*)&%s)\n";
+
+ size_t size = sizeof(pattern)
+ + strlen(vt_type)
+ + 40 // num_methods
+ + strlen(vt_type)
+ + strlen(vt_type)
+ + strlen(vt_hidden)
+ + strlen(vt_var)
+ + strlen(vt_hidden)
+ + 30;
+ char *def = (char*)MALLOCATE(size);
+ sprintf(def, pattern, vt_type, (unsigned long)num_methods, vt_type,
+ vt_type, vt_hidden, vt_var, vt_hidden);
+
+ return def;
+}
+
+// Define short names for all of the symbols associated with this class.
+char*
+CFCBindClass_short_names(CFCBindClass *self) {
+ CFCClass *client = self->client;
+ char *short_names = CFCUtil_strdup("");
+ short_names = CFCUtil_cat_strings(short_names, "#ifdef ",
+ self->short_names_macro, "\n", NULL);
+
+ if (!CFCClass_inert(client)) {
+ const char *short_struct = CFCClass_get_struct_sym(client);
+ const char *full_struct = CFCClass_full_struct_sym(client);
+ const char *short_vt_var = CFCClass_short_vtable_var(client);
+ const char *full_vt_var = CFCClass_full_vtable_var(client);
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ",
+ short_struct, " ", full_struct, "\n",
+ " #define ", short_vt_var, " ",
+ full_vt_var, "\n", NULL);
+ }
+
+ CFCFunction **functions = CFCClass_functions(client);
+ for (int i = 0; functions[i] != NULL; i++) {
+ CFCFunction *func = functions[i];
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ",
+ CFCFunction_short_func_sym(func), " ",
+ CFCFunction_full_func_sym(func), "\n",
+ NULL);
+ }
+
+ CFCVariable **inert_vars = CFCClass_inert_vars(client);
+ for (int i = 0; inert_vars[i] != NULL; i++) {
+ CFCVariable *var = inert_vars[i];
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ",
+ CFCVariable_short_sym(var), " ",
+ CFCVariable_full_sym(var), "\n", NULL);
+ }
+
+ if (!CFCClass_inert(client)) {
+ CFCMethod **novel_methods = CFCClass_novel_methods(client);
+ for (int i = 0; novel_methods[i] != NULL; i++) {
+ CFCMethod *meth = novel_methods[i];
+ const char *short_typedef = CFCMethod_short_typedef(meth);
+ const char *full_typedef = CFCMethod_full_typedef(meth);
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ",
+ short_typedef, " ", full_typedef, "\n",
+ NULL);
+ const char *short_func = CFCMethod_short_implementing_func_sym(meth);
+ const char *full_func = CFCMethod_implementing_func_sym(meth);
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ", short_func,
+ " ", full_func, "\n", NULL);
+ }
+ FREEMEM(novel_methods);
+
+ CFCMethod **methods = CFCClass_methods(client);
+ const char *cnick = CFCClass_get_cnick(client);
+ for (int i = 0; methods[i] != NULL; i++) {
+ CFCMethod *meth = methods[i];
+ size_t size = CFCMethod_short_method_sym(meth, cnick, NULL, 0);
+ char *short_sym = (char*)MALLOCATE(size);
+ CFCMethod_short_method_sym(meth, cnick, short_sym, size);
+ size = CFCMethod_full_method_sym(meth, cnick, NULL, 0);
+ char *full_sym = (char*)MALLOCATE(size);
+ CFCMethod_full_method_sym(meth, cnick, full_sym, size);
+ short_names
+ = CFCUtil_cat_strings(short_names, " #define ", short_sym,
+ " ", full_sym, "\n", NULL);
+ }
+ }
+ short_names = CFCUtil_cat_strings(short_names, "#endif /* ",
+ self->short_names_macro, " */\n", NULL);
+
+ return short_names;
+}
+
Modified: incubator/lucy/trunk/clownfish/src/CFCBindClass.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindClass.h?rev=1139475&r1=1139474&r2=1139475&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindClass.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindClass.h Sat Jun 25 01:01:48 2011
@@ -46,6 +46,30 @@ CFCBindClass_get_client(struct CFCBindCl
const char*
CFCBindClass_short_names_macro(CFCBindClass *self);
+char*
+CFCBindClass_callback_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_method_typedefs(CFCBindClass *self);
+
+char*
+CFCBindClass_parent_include(CFCBindClass *self);
+
+char*
+CFCBindClass_sub_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_inert_var_declarations(CFCBindClass *self);
+
+char*
+CFCBindClass_method_defs(CFCBindClass *self);
+
+char*
+CFCBindClass_vt_singleton_def(CFCBindClass *self);
+
+char*
+CFCBindClass_short_names(CFCBindClass *self);
+
#ifdef __cplusplus
}
#endif