You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/08/31 15:34:04 UTC

[5/8] git commit: Add functions to create C API POD

Add functions to create C API POD


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

Branch: refs/heads/documentation
Commit: 1a19ac4de9824b7b8a81a3fdefd4a0556da31b3c
Parents: 19011e0
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 31 14:36:30 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 31 15:32:07 2014 +0200

----------------------------------------------------------------------
 compiler/include/CFC.h             |   1 +
 compiler/perl/lib/Clownfish/CFC.xs |  11 ++
 compiler/src/CFCPerlCPod.c         | 275 ++++++++++++++++++++++++++++++++
 compiler/src/CFCPerlCPod.h         |  36 +++++
 4 files changed, 323 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/1a19ac4d/compiler/include/CFC.h
----------------------------------------------------------------------
diff --git a/compiler/include/CFC.h b/compiler/include/CFC.h
index 9a13607..996e2d3 100644
--- a/compiler/include/CFC.h
+++ b/compiler/include/CFC.h
@@ -47,6 +47,7 @@
 #include "CFCPerlClass.h"
 #include "CFCPerlConstructor.h"
 #include "CFCPerlPod.h"
+#include "CFCPerlCPod.h"
 #include "CFCPerlTypeMap.h"
 
 #include "CFCRuby.h"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/1a19ac4d/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs
index a6ea249..38aa3fc 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -2487,6 +2487,17 @@ CODE:
 OUTPUT: RETVAL
 
 
+MODULE = Clownfish   PACKAGE = Clownfish::CFC::Binding::Perl::CPod
+
+SV*
+c_api_pod(unused, klass)
+    SV       *unused;
+    CFCClass *klass;
+CODE:
+    RETVAL = S_sv_eat_c_string(CFCPerlCPod_c_api_pod(klass));
+OUTPUT: RETVAL
+
+
 MODULE = Clownfish   PACKAGE = Clownfish::CFC::Binding::Perl::TypeMap
 
 SV*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/1a19ac4d/compiler/src/CFCPerlCPod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlCPod.c b/compiler/src/CFCPerlCPod.c
new file mode 100644
index 0000000..b58fa2f
--- /dev/null
+++ b/compiler/src/CFCPerlCPod.c
@@ -0,0 +1,275 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "CFCPerlCPod.h"
+
+#include "CFCClass.h"
+#include "CFCDocuComment.h"
+#include "CFCFunction.h"
+#include "CFCMethod.h"
+#include "CFCParamList.h"
+#include "CFCType.h"
+#include "CFCUtil.h"
+#include "CFCVariable.h"
+
+static char*
+S_name_pod(CFCClass *klass);
+
+static char*
+S_description_pod(CFCClass *klass);
+
+static char*
+S_functions_pod(CFCClass *klass);
+
+static char*
+S_methods_pod(CFCClass *klass);
+
+static char*
+S_function_pod(CFCClass *klass, CFCFunction *func, const char *short_sym,
+                 const char *full_sym);
+
+static char*
+S_param_list_pod(CFCFunction *func);
+
+char*
+CFCPerlCPod_c_api_pod(CFCClass *klass) {
+    const char *full_struct_sym = CFCClass_full_struct_sym(klass);
+    char       *name_pod        = S_name_pod(klass);
+    char       *description_pod = S_description_pod(klass);
+    char       *functions_pod   = S_functions_pod(klass);
+    char       *methods_pod     = S_methods_pod(klass);
+
+    const char pattern[] =
+        "%s"
+        "%s"
+        "%s"
+        "%s";
+    char *result
+        = CFCUtil_sprintf(pattern, name_pod, description_pod, functions_pod,
+                          methods_pod);
+
+    FREEMEM(methods_pod);
+    return result;
+}
+
+static char*
+S_name_pod(CFCClass *klass) {
+    char *result = CFCUtil_sprintf("=head1 NAME\n\n%s",
+                                   CFCClass_get_class_name(klass));
+
+    CFCDocuComment *docucom = CFCClass_get_docucomment(klass);
+    if (docucom) {
+        const char *brief = CFCDocuComment_get_brief(docucom);
+        if (brief && brief[0] != '\0') {
+            result = CFCUtil_cat(result, " - ", brief, NULL);
+        }
+    }
+
+    result = CFCUtil_cat(result, "\n\n", NULL);
+
+    return result;
+}
+
+static char*
+S_description_pod(CFCClass *klass) {
+    char *result  = CFCUtil_strdup("");
+
+    CFCDocuComment *docucom = CFCClass_get_docucomment(klass);
+    if (!docucom) { return result; }
+
+    const char *description = CFCDocuComment_get_long(docucom);
+    if (description && description[0] != '\0') {
+        result = CFCUtil_cat(result, "=head1 DESCRIPTION\n\n", description,
+                             "\n\n", NULL);
+    }
+
+    return result;
+}
+
+static char*
+S_functions_pod(CFCClass *klass) {
+    CFCFunction **functions = CFCClass_functions(klass);
+    char         *result    = CFCUtil_strdup("");
+
+    for (int func_num = 0; functions[func_num] != NULL; func_num++) {
+        CFCFunction *func = functions[func_num];
+
+        if (result[0] == '\0') {
+            result = CFCUtil_cat(result, "=head1 FUNCTIONS\n\n", NULL);
+        }
+
+        const char *micro_sym     = CFCFunction_micro_sym(func);
+        const char *full_func_sym = CFCFunction_full_func_sym(func);
+
+        char *function_pod = S_function_pod(klass, func, micro_sym,
+                                              full_func_sym);
+        result = CFCUtil_cat(result, function_pod, NULL);
+        FREEMEM(function_pod);
+    }
+
+    return result;
+}
+
+static char*
+S_methods_pod(CFCClass *klass) {
+    CFCMethod **fresh_methods = CFCClass_fresh_methods(klass);
+    char       *abstract_pod  = CFCUtil_strdup("");
+    char       *novel_pod     = CFCUtil_strdup("");
+
+    for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
+        CFCMethod *method = fresh_methods[meth_num];
+        if (!CFCMethod_novel(method)) {
+            continue;
+        }
+
+        const char *macro_sym = CFCMethod_get_macro_sym(method);
+        char *full_method_sym = CFCMethod_full_method_sym(method, NULL);
+        char *method_pod = S_function_pod(klass, (CFCFunction*)method,
+                                            macro_sym, full_method_sym);
+
+        if (CFCMethod_abstract(method)) {
+            if (abstract_pod[0] == '\0') {
+                abstract_pod
+                    = CFCUtil_cat(abstract_pod, "=head1 ABSTRACT METHODS\n\n",
+                                  NULL);
+            }
+            abstract_pod = CFCUtil_cat(abstract_pod, method_pod, NULL);
+        }
+        else {
+            if (novel_pod[0] == '\0') {
+                novel_pod
+                    = CFCUtil_cat(novel_pod, "=head1 NOVEL METHODS\n\n", NULL);
+            }
+            novel_pod = CFCUtil_cat(novel_pod, method_pod, NULL);
+        }
+
+        FREEMEM(method_pod);
+        FREEMEM(full_method_sym);
+    }
+
+    char *result = CFCUtil_sprintf("%s%s", abstract_pod, novel_pod);
+
+    FREEMEM(abstract_pod);
+    FREEMEM(novel_pod);
+    FREEMEM(fresh_methods);
+    return result;
+}
+
+static char*
+S_function_pod(CFCClass *klass, CFCFunction *func, const char *short_sym,
+                 const char *full_sym) {
+    CFCType    *return_type   = CFCFunction_get_return_type(func);
+    const char *return_type_c = CFCType_to_c(return_type);
+    const char *incremented   = "";
+
+    if (CFCType_incremented(return_type)) {
+        incremented = " // incremented";
+    }
+
+    char *param_list = S_param_list_pod(func);
+
+    const char *pattern =
+        "=head2 %s\n"
+        "\n"
+        "    %s%s\n"
+        "    %s%s;\n\n";
+    char *result = CFCUtil_sprintf(pattern, short_sym, return_type_c,
+                                   incremented, full_sym, param_list);
+
+    FREEMEM(param_list);
+
+    // Get documentation, which may be inherited.
+    CFCDocuComment *docucomment = CFCFunction_get_docucomment(func);
+    if (!docucomment) {
+        const char *micro_sym = CFCFunction_micro_sym(func);
+        CFCClass *parent = klass;
+        while (NULL != (parent = CFCClass_get_parent(parent))) {
+            CFCFunction *parent_func
+                = (CFCFunction*)CFCClass_method(parent, micro_sym);
+            if (!parent_func) { break; }
+            docucomment = CFCFunction_get_docucomment(parent_func);
+            if (docucomment) { break; }
+        }
+    }
+
+    if (docucomment) {
+        // Description
+        const char *desc = CFCDocuComment_get_description(docucomment);
+        if (desc && desc[0] != '\0') {
+            result = CFCUtil_cat(result, desc, "\n\n", NULL);
+        }
+
+        // Params
+        const char **param_names
+            = CFCDocuComment_get_param_names(docucomment);
+        const char **param_docs
+            = CFCDocuComment_get_param_docs(docucomment);
+        if (param_names[0]) {
+            result = CFCUtil_cat(result, "=over\n\n", NULL);
+            for (size_t i = 0; param_names[i] != NULL; i++) {
+                result = CFCUtil_cat(result, "=item *\n\nB<", param_names[i],
+                                     "> - ", param_docs[i], "\n\n", NULL);
+            }
+            result = CFCUtil_cat(result, "=back\n\n", NULL);
+        }
+
+        // Return value
+        const char *retval_doc = CFCDocuComment_get_retval(docucomment);
+        if (retval_doc && strlen(retval_doc)) {
+            result = CFCUtil_cat(result, "Returns: ", retval_doc, "\n\n",
+                                 NULL);
+        }
+    }
+
+    return result;
+}
+
+static char*
+S_param_list_pod(CFCFunction *func) {
+    CFCParamList  *param_list = CFCFunction_get_param_list(func);
+    CFCVariable  **variables  = CFCParamList_get_variables(param_list);
+
+    if (!variables[0]) {
+        return CFCUtil_strdup("(void);\n");
+    }
+
+    char *result = CFCUtil_strdup("(");
+
+    for (int i = 0; variables[i]; ++i) {
+        CFCVariable *variable = variables[i];
+        CFCType     *type     = CFCVariable_get_type(variable);
+        const char  *type_c   = CFCType_to_c(type);
+        const char  *name     = CFCVariable_micro_sym(variable);
+
+        result = CFCUtil_cat(result, "\n        ", type_c, " ", name,
+                             NULL);
+
+        if (variables[i+1]) {
+            result = CFCUtil_cat(result, ",", NULL);
+        }
+        if (CFCType_decremented(type)) {
+            result = CFCUtil_cat(result, " // decremented", NULL);
+        }
+    }
+
+    result = CFCUtil_cat(result, "\n    )", NULL);
+
+    return result;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/1a19ac4d/compiler/src/CFCPerlCPod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlCPod.h b/compiler/src/CFCPerlCPod.h
new file mode 100644
index 0000000..b687167
--- /dev/null
+++ b/compiler/src/CFCPerlCPod.h
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef H_CFCPERLCPOD
+#define H_CFCPERLCPOD
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct CFCClass;
+
+/** Create POD for the C API of a class.
+ */
+char*
+CFCPerlCPod_c_api_pod(struct CFCClass *klass);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_CFCPERL */
+