Autogenerate text for empty cfish URIs

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

Branch: refs/heads/markdown_v2
Commit: a1076cb4f8acaed91e03e71bcb231212afef19fc
Parents: fcbfaca
Author: Nick Wellnhofer <[email protected]>
Authored: Thu Dec 4 18:47:07 2014 +0100
Committer: Nick Wellnhofer <[email protected]>
Committed: Thu Dec 4 18:58:48 2014 +0100

----------------------------------------------------------------------
 compiler/src/CFCC.c       | 80 +++++++++++++++++++++++++++++++++++++
 compiler/src/CFCC.h       |  5 +++
 compiler/src/CFCCHtml.c   | 13 ++++++
 compiler/src/CFCCMan.c    | 60 ++++++++++++++++++----------
 compiler/src/CFCPerlPod.c | 91 ++++++++++++++++++++++++++++--------------
 5 files changed, 199 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a1076cb4/compiler/src/CFCC.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c
index cf9a4cf..adc6013 100644
--- a/compiler/src/CFCC.c
+++ b/compiler/src/CFCC.c
@@ -27,6 +27,7 @@
 #include "CFCClass.h"
 #include "CFCHierarchy.h"
 #include "CFCMethod.h"
+#include "CFCUri.h"
 #include "CFCUtil.h"
 
 struct CFCC {
@@ -236,4 +237,83 @@ CFCC_write_hostdefs(CFCC *self) {
     FREEMEM(content);
 }
 
+char*
+CFCC_link_text(CFCUri *uri_obj, CFCClass *klass) {
+    char *link_text = NULL;
+    int   type      = CFCUri_get_type(uri_obj);
+
+    switch (type) {
+        case CFC_URI_CLASS: {
+            if (strcmp(CFCUri_get_prefix(uri_obj),
+                       CFCClass_get_prefix(klass)) == 0
+            ) {
+                // Same parcel.
+                const char *struct_sym = CFCUri_get_struct_sym(uri_obj);
+                link_text = CFCUtil_strdup(struct_sym);
+            }
+            else {
+                // Other parcel.
+                const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+                CFCClass *uri_class
+                    = CFCClass_fetch_by_struct_sym(full_struct_sym);
+                if (!uri_class) {
+                    CFCUtil_warn("URI class not found: %s", full_struct_sym);
+                }
+                else {
+                    const char *class_name
+                        = CFCClass_get_class_name(uri_class);
+                    link_text = CFCUtil_strdup(class_name);
+                }
+            }
+
+            break;
+        }
+
+        case CFC_URI_FUNCTION:
+        case CFC_URI_METHOD: {
+#if 1
+            const char *func_sym = CFCUri_get_func_sym(uri_obj);
+            link_text = CFCUtil_sprintf("%s()", func_sym);
+#else
+            // Full function sym.
+            const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+            const char *func_sym        = CFCUri_get_func_sym(uri_obj);
+
+            if (strcmp(full_struct_sym,
+                       CFCClass_full_struct_sym(klass)) == 0
+            ) {
+                // Same class.
+                link_text = CFCUtil_sprintf("%s()", func_sym);
+            }
+            else {
+                CFCClass *uri_class
+                    = CFCClass_fetch_by_struct_sym(full_struct_sym);
+
+                if (!uri_class) {
+                    CFCUtil_warn("URI class not found: %s", full_struct_sym);
+                    link_text = CFCUtil_sprintf("%s()", func_sym);
+                }
+                else {
+                    const char *prefix   = CFCUri_get_prefix(uri_obj);
+                    const char *nickname = CFCClass_get_nickname(uri_class);
+
+                    if (strcmp(prefix, CFCClass_get_prefix(klass)) == 0) {
+                        // Same parcel.
+                        link_text = CFCUtil_sprintf("%s_%s()", nickname,
+                                                    func_sym);
+                    }
+                    else {
+                        // Other parcel.
+                        link_text = CFCUtil_sprintf("%s%s_%s()", prefix,
+                                                    nickname, func_sym);
+                    }
+                }
+            }
+#endif
+            break;
+        }
+    }
+
+    return link_text;
+}
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a1076cb4/compiler/src/CFCC.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCC.h b/compiler/src/CFCC.h
index c52ebae..093b043 100644
--- a/compiler/src/CFCC.h
+++ b/compiler/src/CFCC.h
@@ -24,7 +24,9 @@ extern "C" {
 #endif
 
 typedef struct CFCC CFCC;
+struct CFCClass;
 struct CFCHierarchy;
+struct CFCUri;
 
 /**
  * @param hierarchy A L<Clownfish::CFC::Model::Hierarchy>.
@@ -64,6 +66,9 @@ CFCC_write_html_docs(CFCC *self);
 void
 CFCC_write_man_pages(CFCC *self);
 
+char*
+CFCC_link_text(struct CFCUri *uri_obj, struct CFCClass *klass);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a1076cb4/compiler/src/CFCCHtml.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index 6c7ef6f..149968c 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -25,6 +25,7 @@
 #define CFC_NEED_BASE_STRUCT_DEF
 #include "CFCBase.h"
 #include "CFCCHtml.h"
+#include "CFCC.h"
 #include "CFCClass.h"
 #include "CFCDocuComment.h"
 #include "CFCFunction.h"
@@ -829,6 +830,18 @@ S_convert_uri(CFCClass *klass, cmark_node *link) {
 
     if (new_uri) {
         cmark_node_set_url(link, new_uri);
+
+        if (!cmark_node_first_child(link)) {
+            // Empty link text.
+            char *link_text = CFCC_link_text(uri_obj, klass);
+
+            if (link_text) {
+                cmark_node *text_node = cmark_node_new(CMARK_NODE_TEXT);
+                cmark_node_set_string_content(text_node, link_text);
+                cmark_node_append_child(link, text_node);
+                FREEMEM(link_text);
+            }
+        }
     }
     else {
         // Remove link.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a1076cb4/compiler/src/CFCCMan.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCMan.c b/compiler/src/CFCCMan.c
index e559d6b..632cb2e 100644
--- a/compiler/src/CFCCMan.c
+++ b/compiler/src/CFCCMan.c
@@ -20,6 +20,8 @@
 
 #include "charmony.h"
 #include "CFCCMan.h"
+#include "CFCBase.h"
+#include "CFCC.h"
 #include "CFCClass.h"
 #include "CFCDocuComment.h"
 #include "CFCFunction.h"
@@ -65,10 +67,10 @@ static char*
 S_man_create_inheritance(CFCClass *klass);
 
 static char*
-S_md_to_man(const char *md, int needs_indent);
+S_md_to_man(CFCClass *klass, const char *md, int needs_indent);
 
 static char*
-S_nodes_to_man(cmark_node *node, int needs_indent);
+S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent);
 
 static char*
 S_man_escape(const char *content);
@@ -131,7 +133,7 @@ S_man_create_name(CFCClass *klass) {
         raw_brief = CFCDocuComment_get_brief(docucom);
     }
     if (raw_brief && raw_brief[0] != '\0') {
-        char *brief = S_md_to_man(raw_brief, false);
+        char *brief = S_md_to_man(klass, raw_brief, false);
         result = CFCUtil_cat(result, " \\- ", brief, NULL);
         FREEMEM(brief);
     }
@@ -158,7 +160,7 @@ S_man_create_description(CFCClass *klass) {
     const char *raw_description = CFCDocuComment_get_long(docucom);
     if (!raw_description || raw_description[0] == '\0') { return result; }
 
-    char *description = S_md_to_man(raw_description, false);
+    char *description = S_md_to_man(klass, raw_description, false);
     result = CFCUtil_cat(result, ".SH DESCRIPTION\n", description, NULL);
     FREEMEM(description);
 
@@ -326,7 +328,7 @@ S_man_create_func(CFCClass *klass, CFCFunction *func, const 
char *short_sym,
     if (docucomment) {
         // Description
         const char *raw_desc = CFCDocuComment_get_description(docucomment);
-        char *desc = S_md_to_man(raw_desc, true);
+        char *desc = S_md_to_man(klass, raw_desc, true);
         result = CFCUtil_cat(result, ".IP\n", desc, NULL);
         FREEMEM(desc);
 
@@ -338,7 +340,7 @@ S_man_create_func(CFCClass *klass, CFCFunction *func, const 
char *short_sym,
         if (param_names[0]) {
             result = CFCUtil_cat(result, ".RS\n", NULL);
             for (size_t i = 0; param_names[i] != NULL; i++) {
-                char *doc = S_md_to_man(param_docs[i], true);
+                char *doc = S_md_to_man(klass, param_docs[i], true);
                 result = CFCUtil_cat(result, ".TP\n.I ", param_names[i],
                                      "\n", doc, NULL);
                 FREEMEM(doc);
@@ -349,7 +351,7 @@ S_man_create_func(CFCClass *klass, CFCFunction *func, const 
char *short_sym,
         // Return value
         const char *retval_doc = CFCDocuComment_get_retval(docucomment);
         if (retval_doc && strlen(retval_doc)) {
-            char *doc = S_md_to_man(retval_doc, true);
+            char *doc = S_md_to_man(klass, retval_doc, true);
             result = CFCUtil_cat(result, ".IP\n.B Returns:\n", doc, NULL);
             FREEMEM(doc);
         }
@@ -415,16 +417,16 @@ S_man_create_inheritance(CFCClass *klass) {
 }
 
 static char*
-S_md_to_man(const char *md, int needs_indent) {
+S_md_to_man(CFCClass *klass, const char *md, int needs_indent) {
     cmark_node *doc = cmark_parse_document(md, strlen(md));
-    char *result = S_nodes_to_man(doc, needs_indent);
+    char *result = S_nodes_to_man(klass, doc, needs_indent);
     cmark_node_free(doc);
 
     return result;
 }
 
 static char*
-S_nodes_to_man(cmark_node *node, int needs_indent) {
+S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) {
     char *result = CFCUtil_strdup("");
     int has_indent = needs_indent;
     int has_vspace = true;
@@ -435,7 +437,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
         switch (type) {
             case NODE_DOCUMENT: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, children_man, NULL);
                 FREEMEM(children_man);
                 break;
@@ -455,7 +458,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
                 }
 
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, children_man, "\n", NULL);
                 FREEMEM(children_man);
 
@@ -470,7 +474,7 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
                 }
 
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, true);
+                char *children_man = S_nodes_to_man(klass, child, true);
                 result = CFCUtil_cat(result, ".IP\n", children_man, NULL);
                 FREEMEM(children_man);
 
@@ -487,7 +491,7 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
 
             case NODE_LIST_ITEM: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, true);
+                char *children_man = S_nodes_to_man(klass, child, true);
                 result = CFCUtil_cat(result, ".IP \\(bu\n", children_man,
                                      NULL);
                 FREEMEM(children_man);
@@ -500,7 +504,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
                 }
 
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, children_man, NULL);
                 FREEMEM(children_man);
 
@@ -517,7 +522,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
 
             case NODE_HEADER: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, ".SS\n", children_man, "\n", 
NULL);
                 FREEMEM(children_man);
                 has_indent = false;
@@ -589,10 +595,22 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
 
             case NODE_LINK: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 const char *url = cmark_node_get_url(node);
                 if (CFCUri_is_clownfish_uri(url)) {
-                    result = CFCUtil_cat(result, children_man, NULL);
+                    if (children_man[0] != '\0') {
+                        result = CFCUtil_cat(result, children_man, NULL);
+                    }
+                    else {
+                        CFCUri *uri_obj = CFCUri_new(url, klass);
+                        char *link_text = CFCC_link_text(uri_obj, klass);
+                        if (link_text) {
+                            result = CFCUtil_cat(result, link_text, NULL);
+                            FREEMEM(link_text);
+                        }
+                        CFCBase_decref((CFCBase*)uri_obj);
+                    }
                 }
                 else {
                     result = CFCUtil_cat(result, "\n.UR ", url, "\n",
@@ -609,7 +627,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
 
             case NODE_STRONG: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, "\\fB", children_man, "\\f[]",
                                      NULL);
                 FREEMEM(children_man);
@@ -618,7 +637,8 @@ S_nodes_to_man(cmark_node *node, int needs_indent) {
 
             case NODE_EMPH: {
                 cmark_node *child = cmark_node_first_child(node);
-                char *children_man = S_nodes_to_man(child, needs_indent);
+                char *children_man = S_nodes_to_man(klass, child,
+                                                    needs_indent);
                 result = CFCUtil_cat(result, "\\fI", children_man, "\\f[]",
                                      NULL);
                 FREEMEM(children_man);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a1076cb4/compiler/src/CFCPerlPod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlPod.c b/compiler/src/CFCPerlPod.c
index e28fb55..4ba5f9d 100644
--- a/compiler/src/CFCPerlPod.c
+++ b/compiler/src/CFCPerlPod.c
@@ -560,57 +560,88 @@ S_convert_link(CFCClass *klass, cmark_node *link) {
         return retval;
     }
 
-    char   *new_uri = NULL;
-    CFCUri *uri_obj = CFCUri_new(uri, klass);
-    int     type    = CFCUri_get_type(uri_obj);
+    char   *new_uri  = NULL;
+    char   *new_text = NULL;
+    CFCUri *uri_obj  = CFCUri_new(uri, klass);
+    int     type     = CFCUri_get_type(uri_obj);
 
     switch (type) {
         case CFC_URI_NULL:
             // Change all instances of NULL to 'undef'
-            FREEMEM(text);
-            text = CFCUtil_strdup("undef");
+            new_text = CFCUtil_strdup("undef");
             break;
 
-        case CFC_URI_CLASS:
-        case CFC_URI_FUNCTION:
-        case CFC_URI_METHOD: {
-            // TODO: Class and method aliases
+        case CFC_URI_CLASS: {
+            const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+            CFCClass *uri_class
+                = CFCClass_fetch_by_struct_sym(full_struct_sym);
 
-            const char *struct_sym = CFCUri_full_struct_sym(uri_obj);
-            CFCClass *uri_class = CFCClass_fetch_by_struct_sym(struct_sym);
             if (!uri_class) {
-                CFCUtil_warn("No class found for URI: %s", uri);
-                break;
+                CFCUtil_warn("URI class not found: %s", full_struct_sym);
             }
-
-            if (uri_class != klass) {
+            else if (uri_class != klass) {
                 const char *class_name = CFCClass_get_class_name(uri_class);
                 new_uri = CFCUtil_strdup(class_name);
             }
 
-            if (type != CFC_URI_CLASS) {
-                // TODO: Link to relevant POD section. This isn't easy because
-                // the section headers for functions also contain a description
-                // of the parameters.
-
-                FREEMEM(text);
-                const char *func_sym = CFCUri_get_func_sym(uri_obj);
+            if (text[0] != '\0') {
+                // Keep text.
+                break;
+            }
 
-                if (strcmp(struct_sym, "cfish_Err") == 0
-                    && strcmp(func_sym, "error") == 0
-                ) {
-                    text = CFCUtil_strdup("Clownfish->error");
+            if (strcmp(CFCUri_get_prefix(uri_obj),
+                       CFCClass_get_prefix(klass)) == 0
+            ) {
+                // Same parcel.
+                const char *struct_sym = CFCUri_get_struct_sym(uri_obj);
+                new_text = CFCUtil_strdup(struct_sym);
+            }
+            else {
+                // Other parcel.
+                if (!uri_class) {
+                    new_text = CFCUtil_strdup(full_struct_sym);
                 }
                 else {
-                    text = CFCUtil_sprintf("%s()", func_sym);
-                    for (size_t i = 0; text[i] != '\0'; ++i) {
-                        text[i] = tolower(text[i]);
-                    }
+                    const char *class_name
+                        = CFCClass_get_class_name(uri_class);
+                    new_text = CFCUtil_strdup(class_name);
                 }
             }
 
             break;
         }
+
+        case CFC_URI_FUNCTION:
+        case CFC_URI_METHOD: {
+            const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+            CFCClass *uri_class
+                = CFCClass_fetch_by_struct_sym(full_struct_sym);
+
+            // TODO: Link to relevant POD section. This isn't easy because
+            // the section headers for functions also contain a description
+            // of the parameters.
+
+            if (!uri_class) {
+                CFCUtil_warn("URI class not found: %s", full_struct_sym);
+            }
+            else if (uri_class != klass) {
+                const char *class_name = CFCClass_get_class_name(uri_class);
+                new_uri = CFCUtil_strdup(class_name);
+            }
+
+            const char *func_sym  = CFCUri_get_func_sym(uri_obj);
+            new_text = CFCUtil_sprintf("%s()", func_sym);
+            for (size_t i = 0; new_text[i] != '\0'; ++i) {
+                new_text[i] = tolower(new_text[i]);
+            }
+
+            break;
+        }
+    }
+
+    if (new_text) {
+        FREEMEM(text);
+        text = new_text;
     }
 
     if (new_uri) {

Reply via email to