Convert Clownfish/Go string types in glue.

Convert Clownfish Strings to Go strings and vice versa when crossing the
Go/C border.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9da72036
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9da72036
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9da72036

Branch: refs/heads/master
Commit: 9da720363a68aad40b62bafcd4e8b843c3384a21
Parents: ba550db
Author: Marvin Humphrey <mar...@rectangular.com>
Authored: Fri May 22 18:47:02 2015 -0700
Committer: Marvin Humphrey <mar...@rectangular.com>
Committed: Thu May 28 11:04:19 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGoFunc.c    | 16 ++++++++++++++++
 compiler/src/CFCGoMethod.c  | 18 ++++++++++++++++--
 compiler/src/CFCGoTypeMap.c |  5 ++++-
 3 files changed, 36 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9da72036/compiler/src/CFCGoFunc.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoFunc.c b/compiler/src/CFCGoFunc.c
index 79c129a..3138605 100644
--- a/compiler/src/CFCGoFunc.c
+++ b/compiler/src/CFCGoFunc.c
@@ -118,6 +118,22 @@ CFCGoFunc_return_statement(CFCParcel *parcel, CFCType 
*return_type,
         if (CFCType_is_primitive(return_type)) {
             statement = CFCUtil_sprintf("\treturn %s(retvalCF)\n", 
ret_type_str);
         }
+        else if (CFCType_is_string_type(return_type)) {
+            const char *clownfish_dot = CFCParcel_is_cfish(parcel)
+                                        ? "" : "clownfish.";
+            if (CFCType_incremented(return_type)) {
+                char pattern[] =
+                    "\tdefer C.cfish_dec_refcount(unsafe.Pointer(retvalCF))\n"
+                    "\treturn %sCFStringToGo(unsafe.Pointer(retvalCF))\n"
+                    ;
+                statement = CFCUtil_sprintf(pattern, clownfish_dot);
+            }
+            else {
+                char pattern[] =
+                    "\treturn %sCFStringToGo(unsafe.Pointer(retvalCF))\n";
+                statement = CFCUtil_sprintf(pattern, clownfish_dot);
+            }
+        }
         else if (CFCType_is_object(return_type)) {
             char *go_type_name = CFCGoTypeMap_go_type_name(return_type, 
parcel);
             char *struct_name  = go_type_name;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9da72036/compiler/src/CFCGoMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoMethod.c b/compiler/src/CFCGoMethod.c
index 9626e59..b095347 100644
--- a/compiler/src/CFCGoMethod.c
+++ b/compiler/src/CFCGoMethod.c
@@ -136,7 +136,8 @@ CFCGoMethod_get_sig(CFCGoMethod *self, CFCClass *invoker) {
 #define GO_NAME_BUF_SIZE 128
 
 static char*
-S_prep_cfargs(CFCClass *invoker, CFCParamList *param_list) {
+S_prep_cfargs(CFCParcel *parcel, CFCClass *invoker,
+              CFCParamList *param_list) {
     CFCVariable **vars = CFCParamList_get_variables(param_list);
     char go_name[GO_NAME_BUF_SIZE];
     char *cfargs = CFCUtil_strdup("");
@@ -158,6 +159,19 @@ S_prep_cfargs(CFCClass *invoker, CFCParamList *param_list) 
{
             cfargs = CFCUtil_cat(cfargs, "C.", CFCType_get_specifier(type),
                                  "(", go_name, ")", NULL);
         }
+        else if (CFCType_is_string_type(type)
+                 && i != 0) { // Don't convert a clownfish.String invocant.
+            const char *format;
+            if (CFCParcel_is_cfish(parcel)) {
+                format = 
"%s((*C.cfish_String)(unsafe.Pointer(NewString(%s).TOPTR())))";
+            }
+            else {
+                format = 
"%s((*C.cfish_String)(unsafe.Pointer(clownfish.NewString(%s).TOPTR())))";
+            }
+            char *temp = CFCUtil_sprintf(format, cfargs, go_name);
+            FREEMEM(cfargs);
+            cfargs = temp;
+        }
         else if (CFCType_is_object(type)) {
 
             char *obj_pattern;
@@ -197,7 +211,7 @@ CFCGoMethod_func_def(CFCGoMethod *self, CFCClass *invoker) {
         cfunc = CFCMethod_full_method_sym(novel_method, invoker);
     }
 
-    char *cfargs = S_prep_cfargs(invoker, param_list);
+    char *cfargs = S_prep_cfargs(parcel, invoker, param_list);
 
     char *maybe_retval;
     char *maybe_return;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9da72036/compiler/src/CFCGoTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.c b/compiler/src/CFCGoTypeMap.c
index 6dd7700..d61ca47 100644
--- a/compiler/src/CFCGoTypeMap.c
+++ b/compiler/src/CFCGoTypeMap.c
@@ -126,7 +126,10 @@ static int num_go_keywords = sizeof(go_keywords) / 
sizeof(go_keywords[0]);
 
 char*
 CFCGoTypeMap_go_type_name(CFCType *type, CFCParcel *current_parcel) {
-    if (CFCType_is_object(type)) {
+    if (CFCType_is_string_type(type)) {
+        return CFCUtil_strdup("string");
+    }
+    else if (CFCType_is_object(type)) {
         // Divide the specifier into prefix and struct name.
         const char *specifier  = CFCType_get_specifier(type);
         size_t      prefix_len = 0;

Reply via email to