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 */
+