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) {
