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 2015/08/06 18:19:54 UTC
[17/20] lucy-clownfish git commit: Create HTML docs for standalone
documentation
Create HTML docs for standalone documentation
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d11a489f
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d11a489f
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d11a489f
Branch: refs/heads/master
Commit: d11a489f30e3f09bb1e85715353b53baaf39a67d
Parents: ea9281e
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Jul 26 00:58:47 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Thu Aug 6 18:19:19 2015 +0200
----------------------------------------------------------------------
compiler/src/CFCC.c | 41 ++--
compiler/src/CFCCHtml.c | 390 ++++++++++++++++++++++++---------
compiler/src/CFCCHtml.h | 9 +-
compiler/src/CFCTestDocuComment.c | 29 ++-
4 files changed, 334 insertions(+), 135 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d11a489f/compiler/src/CFCC.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c
index ad7f882..aa1e267 100644
--- a/compiler/src/CFCC.c
+++ b/compiler/src/CFCC.c
@@ -25,6 +25,7 @@
#include "CFCCHtml.h"
#include "CFCCMan.h"
#include "CFCClass.h"
+#include "CFCDocument.h"
#include "CFCHierarchy.h"
#include "CFCMethod.h"
#include "CFCUri.h"
@@ -177,27 +178,39 @@ CFCC_link_text(CFCUri *uri_obj, CFCClass *klass) {
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);
+ const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+ CFCClass *uri_class = full_struct_sym
+ ? CFCClass_fetch_by_struct_sym(full_struct_sym)
+ : NULL;
+
+ if (uri_class) {
+ if (klass
+ && strcmp(CFCClass_get_prefix(uri_class),
+ 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 *class_name = CFCClass_get_name(uri_class);
link_text = CFCUtil_strdup(class_name);
}
+
+ break;
+ }
+
+ const char *struct_sym = CFCUri_get_struct_sym(uri_obj);
+ CFCDocument *doc = CFCDocument_fetch(struct_sym);
+
+ if (doc) {
+ const char *name = CFCDocument_get_name(doc);
+ link_text = CFCUtil_strdup(name);
+ break;
}
+ CFCUtil_warn("Can't resolve Clownfish URI '%s'", struct_sym);
break;
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d11a489f/compiler/src/CFCCHtml.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index 02cc34e..3c953fe 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -28,6 +28,7 @@
#include "CFCC.h"
#include "CFCClass.h"
#include "CFCDocuComment.h"
+#include "CFCDocument.h"
#include "CFCFunction.h"
#include "CFCHierarchy.h"
#include "CFCMethod.h"
@@ -52,6 +53,7 @@ struct CFCCHtml {
char *doc_path;
char *header;
char *footer;
+ char *index_filename;
};
static const CFCMeta CFCCHTML_META = {
@@ -113,11 +115,17 @@ static const char footer_template[] =
"</html>\n"
"{autogen_footer}";
+char*
+S_create_index_doc(CFCCHtml *self, CFCClass **classes, CFCDocument **docs);
+
+char*
+S_create_standalone_doc(CFCCHtml *self, CFCDocument *doc);
+
static int
S_compare_class_name(const void *va, const void *vb);
-static char*
-S_index_filename(CFCParcel *parcel);
+static int
+S_compare_doc_path(const void *va, const void *vb);
static char*
S_html_create_name(CFCClass *klass);
@@ -148,25 +156,29 @@ static char*
S_html_create_inheritance(CFCClass *klass);
static char*
-S_md_to_html(CFCClass *klass, const char *md);
+S_md_to_html(const char *md, CFCClass *klass, int dir_level);
static void
-S_convert_uris(CFCClass *klass, cmark_node *node);
+S_convert_uris(cmark_node *node, CFCClass *klass, int dir_level);
static void
-S_convert_uri(CFCClass *klass, cmark_node *link);
+S_convert_uri(cmark_node *link, CFCClass *klass, int dir_level);
static char*
S_type_to_html(CFCClass *klass, CFCType *type);
static char*
-S_struct_sym_to_url(const char *struct_sym, CFCClass *base);
+S_cfc_uri_to_url(CFCUri *uri_obj, const char *uri_string, CFCClass *base,
+ int dir_level);
static char*
-S_class_to_url(CFCClass *klass, CFCClass *base);
+S_struct_sym_to_url(const char *struct_sym, CFCClass *base, int dir_level);
static char*
-S_relative_url(const char *url, CFCClass *base);
+S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level);
+
+static char*
+S_relative_url(const char *url, CFCClass *base, int dir_level);
CFCCHtml*
CFCCHtml_new(CFCHierarchy *hierarchy, const char *header, const char *footer) {
@@ -206,29 +218,36 @@ CFCCHtml_destroy(CFCCHtml *self) {
FREEMEM(self->doc_path);
FREEMEM(self->header);
FREEMEM(self->footer);
+ FREEMEM(self->index_filename);
CFCBase_destroy((CFCBase*)self);
}
void
CFCCHtml_write_html_docs(CFCCHtml *self) {
- CFCHierarchy *hierarchy = self->hierarchy;
- CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
- CFCParcel **parcels = CFCParcel_all_parcels();
- const char *doc_path = self->doc_path;
-
- size_t num_parcels = 0;
- for (size_t i = 0; parcels[i] != NULL; i++) {
- ++num_parcels;
- }
+ CFCHierarchy *hierarchy = self->hierarchy;
+ CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
+ CFCDocument **doc_registry = CFCDocument_get_registry();
+ const char *doc_path = self->doc_path;
size_t num_classes = 0;
for (size_t i = 0; ordered[i] != NULL; i++) {
++num_classes;
}
+ size_t num_md_docs = 0;
+ for (size_t i = 0; doc_registry[i] != NULL; i++) {
+ ++num_md_docs;
+ }
+
+ // Clone doc registry.
+ size_t bytes = (num_md_docs + 1) * sizeof(CFCDocument*);
+ CFCDocument **md_docs = (CFCDocument**)MALLOCATE(bytes);
+ memcpy(md_docs, doc_registry, bytes);
+
qsort(ordered, num_classes, sizeof(*ordered), S_compare_class_name);
+ qsort(md_docs, num_md_docs, sizeof(*md_docs), S_compare_doc_path);
- size_t max_docs = num_classes + num_parcels;
+ size_t max_docs = 1 + num_classes + num_md_docs;
char **filenames = (char**)CALLOCATE(max_docs, sizeof(char*));
char **html_docs = (char**)CALLOCATE(max_docs, sizeof(char*));
size_t num_docs = 0;
@@ -237,16 +256,11 @@ CFCCHtml_write_html_docs(CFCCHtml *self) {
// while generating the pages, we leak memory but don't clutter up the file
// system.
- for (size_t i = 0; parcels[i] != NULL; ++i) {
- CFCParcel *parcel = parcels[i];
- if (CFCParcel_included(parcel)) { continue; }
-
- char *html = CFCCHtml_create_index_doc(self, parcel, ordered);
- if (html != NULL) {
- filenames[num_docs] = S_index_filename(parcel);
- html_docs[num_docs] = html;
- ++num_docs;
- }
+ char *index_doc = S_create_index_doc(self, ordered, md_docs);
+ if (index_doc != NULL) {
+ filenames[num_docs] = CFCUtil_strdup(self->index_filename);
+ html_docs[num_docs] = index_doc;
+ num_docs++;
}
for (size_t i = 0; ordered[i] != NULL; i++) {
@@ -264,11 +278,23 @@ CFCCHtml_write_html_docs(CFCCHtml *self) {
FREEMEM(path);
}
+ for (size_t i = 0; md_docs[i] != NULL; i++) {
+ CFCDocument *md_doc = md_docs[i];
+ const char *path = CFCDocument_get_path_part(md_doc);
+ filenames[num_docs] = CFCUtil_sprintf("%s.html", path);
+ html_docs[num_docs] = S_create_standalone_doc(self, md_doc);
+ ++num_docs;
+ }
+
+ // Write out docs.
+
for (size_t i = 0; i < num_docs; ++i) {
char *filename = filenames[i];
char *path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s", doc_path,
filename);
+ // Make path.
+
char *dir = CFCUtil_strdup(path);
for (size_t j = strlen(dir); j--;) {
if (dir[j] == CHY_DIR_SEP_CHAR) {
@@ -299,51 +325,165 @@ CFCCHtml_write_html_docs(CFCCHtml *self) {
}
char*
-CFCCHtml_create_index_doc(CFCCHtml *self, CFCParcel *parcel,
- CFCClass **classes) {
- const char *prefix = CFCParcel_get_prefix(parcel);
- const char *parcel_name = CFCParcel_get_name(parcel);
- char *class_list = CFCUtil_strdup("");
-
- for (size_t i = 0; classes[i] != NULL; i++) {
- CFCClass *klass = classes[i];
- if (strcmp(CFCClass_get_prefix(klass), prefix) != 0
- || !CFCClass_public(klass)
- ) {
- continue;
- }
+S_create_index_doc(CFCCHtml *self, CFCClass **classes, CFCDocument **docs) {
+ CFCParcel **parcels = CFCParcel_all_parcels();
- const char *class_name = CFCClass_get_name(klass);
- char *url = S_class_to_url(klass, NULL);
- class_list
- = CFCUtil_cat(class_list, "<li><a href=\"", url, "\">",
- class_name, "</a></li>\n", NULL);
+ // Compile standalone document list.
+
+ char *doc_list = CFCUtil_strdup("");
+
+ for (size_t i = 0; docs[i] != NULL; i++) {
+ CFCDocument *doc = docs[i];
+
+ const char *path_part = CFCDocument_get_path_part(doc);
+ char *url = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "/");
+ char *name = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "::");
+ doc_list
+ = CFCUtil_cat(doc_list, "<li><a href=\"", url, ".html\">",
+ name, "</a></li>\n", NULL);
+ FREEMEM(name);
FREEMEM(url);
}
- if (class_list[0] == '\0') {
+ if (doc_list[0] != '\0') {
+ const char *pattern =
+ "<h2>Documentation</h2>\n"
+ "<ul>\n"
+ "%s"
+ "</ul>\n";
+ char *contents = doc_list;
+ doc_list = CFCUtil_sprintf(pattern, contents);
+ FREEMEM(contents);
+ }
+
+ // Compile class lists per parcel.
+
+ char *class_lists = CFCUtil_strdup("");
+ char *parcel_names = CFCUtil_strdup("");
+ char *filename = CFCUtil_strdup("");
+
+ for (size_t i = 0; parcels[i]; i++) {
+ CFCParcel *parcel = parcels[i];
+ if (CFCParcel_included(parcel)) { continue; }
+
+ const char *prefix = CFCParcel_get_prefix(parcel);
+ const char *parcel_name = CFCParcel_get_name(parcel);
+
+ char *class_list = CFCUtil_strdup("");
+
+ for (size_t i = 0; classes[i] != NULL; i++) {
+ CFCClass *klass = classes[i];
+ if (strcmp(CFCClass_get_prefix(klass), prefix) != 0
+ || !CFCClass_public(klass)
+ ) {
+ continue;
+ }
+
+ const char *class_name = CFCClass_get_name(klass);
+ char *url = S_class_to_url(klass, NULL, 0);
+ class_list
+ = CFCUtil_cat(class_list, "<li><a href=\"", url, "\">",
+ class_name, "</a></li>\n", NULL);
+ FREEMEM(url);
+ }
+
+ if (class_list[0] != '\0') {
+ const char *pattern =
+ "<h2>Classes in parcel %s</h2>\n"
+ "<ul>\n"
+ "%s"
+ "</ul>\n";
+ char *html = CFCUtil_sprintf(pattern, parcel_name, class_list);
+ class_lists = CFCUtil_cat(class_lists, html, NULL);
+ FREEMEM(html);
+
+ const char *parcel_name = CFCParcel_get_name(parcel);
+ const char *sep = parcel_names[0] == '\0' ? "" : ", ";
+ parcel_names = CFCUtil_cat(parcel_names, sep, parcel_name, NULL);
+
+ const char *parcel_prefix = CFCParcel_get_prefix(parcel);
+ filename = CFCUtil_cat(filename, parcel_prefix, NULL);
+ }
+
FREEMEM(class_list);
- return NULL;
}
- char *title
- = CFCUtil_sprintf("%s " UTF8_NDASH " C API Index", parcel_name);
+ // Create doc.
+
+ char *title = CFCUtil_sprintf("%s " UTF8_NDASH " C API Index",
+ parcel_names);
char *header = CFCUtil_global_replace(self->header, "{title}", title);
const char pattern[] =
"%s"
"<h1>%s</h1>\n"
- "<ul>\n"
"%s"
- "</ul>\n"
+ "%s"
"%s";
- char *html_doc
- = CFCUtil_sprintf(pattern, header, title, class_list, self->footer);
+ char *doc
+ = CFCUtil_sprintf(pattern, header, title, doc_list, class_lists,
+ self->footer);
+
+ // Create filename
+
+ if (filename[0] == '\0') {
+ for (size_t i = 0; parcels[i]; i++) {
+ CFCParcel *parcel = parcels[i];
+ if (CFCParcel_included(parcel)) { continue; }
+ const char *prefix = CFCParcel_get_prefix(parcel);
+ filename = CFCUtil_cat(filename, prefix, NULL);
+ }
+ }
+
+ char *retval = NULL;
+
+ if (filename[0] != '\0') {
+ // Removing trailing underscore.
+ size_t filename_len = strlen(filename);
+ filename[filename_len-1] = '\0';
+
+ // Add .html extension.
+ char *base = filename;
+ filename = CFCUtil_sprintf("%s.html", base);
+ FREEMEM(base);
+
+ retval = doc;
+ doc = NULL;
+
+ FREEMEM(self->index_filename);
+ self->index_filename = filename;
+ filename = NULL;
+ }
+ FREEMEM(doc);
FREEMEM(header);
FREEMEM(title);
- FREEMEM(class_list);
+ FREEMEM(filename);
+ FREEMEM(parcel_names);
+ FREEMEM(class_lists);
+ FREEMEM(doc_list);
+
+ return retval;
+}
+
+char*
+S_create_standalone_doc(CFCCHtml *self, CFCDocument *doc) {
+ const char *path = CFCDocument_get_path_part(doc);
+ char *title = CFCUtil_global_replace(path, CHY_DIR_SEP, "::");
+ char *header = CFCUtil_global_replace(self->header, "{title}", title);
+ const char *md = CFCDocument_get_contents(doc);
+ int dir_level = 0;
+ for (size_t i = 0; path[i]; i++) {
+ if (path[i] == CHY_DIR_SEP_CHAR) { ++dir_level; }
+ }
+ char *body = S_md_to_html(md, NULL, dir_level);
+
+ char *html_doc = CFCUtil_sprintf("%s%s%s", header, body, self->footer);
+
+ FREEMEM(body);
+ FREEMEM(header);
+ FREEMEM(title);
return html_doc;
}
@@ -353,7 +493,7 @@ CFCCHtml_create_html_doc(CFCCHtml *self, CFCClass *klass) {
char *title
= CFCUtil_sprintf("%s " UTF8_NDASH " C API Documentation", class_name);
char *header = CFCUtil_global_replace(self->header, "{title}", title);
- char *body = CFCCHtml_create_html_body(klass);
+ char *body = CFCCHtml_create_html_body(self, klass);
char *html_doc = CFCUtil_sprintf("%s%s%s", header, body, self->footer);
@@ -364,7 +504,20 @@ CFCCHtml_create_html_doc(CFCCHtml *self, CFCClass *klass) {
}
char*
-CFCCHtml_create_html_body(CFCClass *klass) {
+CFCCHtml_create_html_body(CFCCHtml *self, CFCClass *klass) {
+ if (self->index_filename == NULL) {
+ // Create index filename by creating index doc.
+ CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
+ CFCDocument **docs = CFCDocument_get_registry();
+ char *index_doc = S_create_index_doc(self, ordered, docs);
+ FREEMEM(index_doc);
+ FREEMEM(ordered);
+
+ if (self->index_filename == NULL) {
+ CFCUtil_die("Empty hierarchy");
+ }
+ }
+
CFCParcel *parcel = CFCClass_get_parcel(klass);
const char *parcel_name = CFCParcel_get_name(parcel);
const char *prefix = CFCClass_get_prefix(klass);
@@ -393,8 +546,7 @@ CFCCHtml_create_html_body(CFCClass *klass) {
// Build an INHERITANCE section describing class ancestry.
char *inheritance = S_html_create_inheritance(klass);
- char *index_filename = S_index_filename(parcel);
- char *index_url = S_relative_url(index_filename, klass);
+ char *index_url = S_relative_url(self->index_filename, klass, 0);
// Put it all together.
const char pattern[] =
@@ -435,7 +587,6 @@ CFCCHtml_create_html_body(CFCClass *klass) {
inheritance);
FREEMEM(index_url);
- FREEMEM(index_filename);
FREEMEM(name);
FREEMEM(synopsis);
FREEMEM(description);
@@ -454,15 +605,12 @@ S_compare_class_name(const void *va, const void *vb) {
return strcmp(a, b);
}
-static char*
-S_index_filename(CFCParcel *parcel) {
- char *nickname = CFCUtil_strdup(CFCParcel_get_nickname(parcel));
- for (size_t i = 0; nickname[i]; ++i) {
- nickname[i] = tolower(nickname[i]);
- }
- char *filename = CFCUtil_sprintf("%s.html", nickname);
- FREEMEM(nickname);
- return filename;
+static int
+S_compare_doc_path(const void *va, const void *vb) {
+ const char *a = CFCDocument_get_path_part(*(CFCDocument**)va);
+ const char *b = CFCDocument_get_path_part(*(CFCDocument**)vb);
+
+ return strcmp(a, b);
}
static char*
@@ -478,7 +626,7 @@ S_html_create_name(CFCClass *klass) {
}
}
- char *html = S_md_to_html(klass, md);
+ char *html = S_md_to_html(md, klass, 0);
const char *format =
"<h2>Name</h2>\n"
@@ -504,7 +652,7 @@ S_html_create_description(CFCClass *klass) {
if (docucom) {
const char *raw_desc = CFCDocuComment_get_long(docucom);
if (raw_desc && raw_desc[0] != '\0') {
- desc = S_md_to_html(klass, raw_desc);
+ desc = S_md_to_html(raw_desc, klass, 0);
}
}
@@ -675,7 +823,7 @@ S_html_create_func(CFCClass *klass, CFCFunction *func, const char *prefix,
if (docucomment) {
// Description
const char *raw_desc = CFCDocuComment_get_description(docucomment);
- char *desc = S_md_to_html(klass, raw_desc);
+ char *desc = S_md_to_html(raw_desc, klass, 0);
result = CFCUtil_cat(result, desc, NULL);
FREEMEM(desc);
@@ -687,7 +835,7 @@ S_html_create_func(CFCClass *klass, CFCFunction *func, const char *prefix,
if (param_names[0]) {
result = CFCUtil_cat(result, "<dl>\n", NULL);
for (size_t i = 0; param_names[i] != NULL; i++) {
- char *doc = S_md_to_html(klass, param_docs[i]);
+ char *doc = S_md_to_html(param_docs[i], klass, 0);
result = CFCUtil_cat(result, "<dt>", param_names[i],
"</dt>\n<dd>", doc, "</dd>\n",
NULL);
@@ -700,7 +848,7 @@ S_html_create_func(CFCClass *klass, CFCFunction *func, const char *prefix,
const char *retval_doc = CFCDocuComment_get_retval(docucomment);
if (retval_doc && strlen(retval_doc)) {
char *md = CFCUtil_sprintf("**Returns:** %s", retval_doc);
- char *html = S_md_to_html(klass, md);
+ char *html = S_md_to_html(md, klass, 0);
result = CFCUtil_cat(result, html, NULL);
FREEMEM(html);
FREEMEM(md);
@@ -774,7 +922,7 @@ S_html_create_inheritance(CFCClass *klass) {
NULL);
while (ancestor) {
const char *ancestor_name = CFCClass_get_name(ancestor);
- char *ancestor_url = S_class_to_url(ancestor, klass);
+ char *ancestor_url = S_class_to_url(ancestor, klass, 0);
result = CFCUtil_cat(result, " is a <a href=\"", ancestor_url, "\">",
ancestor_name, "</a>", NULL);
FREEMEM(ancestor_url);
@@ -786,12 +934,12 @@ S_html_create_inheritance(CFCClass *klass) {
}
static char*
-S_md_to_html(CFCClass *klass, const char *md) {
+S_md_to_html(const char *md, CFCClass *klass, int dir_level) {
int options = CMARK_OPT_SMART
| CMARK_OPT_VALIDATE_UTF8
| CMARK_OPT_SAFE;
cmark_node *doc = cmark_parse_document(md, strlen(md), options);
- S_convert_uris(klass, doc);
+ S_convert_uris(doc, klass, dir_level);
char *html = cmark_render_html(doc, CMARK_OPT_DEFAULT);
cmark_node_free(doc);
@@ -799,7 +947,7 @@ S_md_to_html(CFCClass *klass, const char *md) {
}
static void
-S_convert_uris(CFCClass *klass, cmark_node *node) {
+S_convert_uris(cmark_node *node, CFCClass *klass, int dir_level) {
cmark_iter *iter = cmark_iter_new(node);
cmark_event_type ev_type;
@@ -809,7 +957,7 @@ S_convert_uris(CFCClass *klass, cmark_node *node) {
if (ev_type == CMARK_EVENT_EXIT
&& cmark_node_get_type(cur) == NODE_LINK
) {
- S_convert_uri(klass, cur);
+ S_convert_uri(cur, klass, dir_level);
}
}
@@ -817,28 +965,27 @@ S_convert_uris(CFCClass *klass, cmark_node *node) {
}
static void
-S_convert_uri(CFCClass *klass, cmark_node *link) {
- const char *uri = cmark_node_get_url(link);
- if (!uri || !CFCUri_is_clownfish_uri(uri)) {
+S_convert_uri(cmark_node *link, CFCClass *klass, int dir_level) {
+ const char *uri_string = cmark_node_get_url(link);
+ if (!uri_string || !CFCUri_is_clownfish_uri(uri_string)) {
return;
}
char *new_uri = NULL;
- CFCUri *uri_obj = CFCUri_new(uri, klass);
+ CFCUri *uri_obj = CFCUri_new(uri_string, klass);
int type = CFCUri_get_type(uri_obj);
switch (type) {
case CFC_URI_CLASS: {
- const char *struct_sym = CFCUri_full_struct_sym(uri_obj);
- new_uri = S_struct_sym_to_url(struct_sym, klass);
+ new_uri = S_cfc_uri_to_url(uri_obj, uri_string, klass, dir_level);
break;
}
case CFC_URI_FUNCTION:
case CFC_URI_METHOD: {
- const char *struct_sym = CFCUri_full_struct_sym(uri_obj);
- const char *func_sym = CFCUri_get_func_sym(uri_obj);
- char *url = S_struct_sym_to_url(struct_sym, klass);
+ const char *func_sym = CFCUri_get_func_sym(uri_obj);
+ char *url = S_cfc_uri_to_url(uri_obj, uri_string, klass,
+ dir_level);
new_uri = CFCUtil_sprintf("%s#func_%s", url, func_sym);
FREEMEM(url);
break;
@@ -895,7 +1042,7 @@ S_type_to_html(CFCClass *klass, CFCType *type) {
prefix, type_c + offset);
}
else {
- char *url = S_struct_sym_to_url(specifier, klass);
+ char *url = S_struct_sym_to_url(specifier, klass, 0);
const char *pattern =
"<span class=\"prefix\">%s</span>"
"<a href=\"%s\">%s</a>";
@@ -912,25 +1059,57 @@ S_type_to_html(CFCClass *klass, CFCType *type) {
return CFCUtil_strdup(type_c);
}
+// Return a relative URL for a CFCUri object.
+static char*
+S_cfc_uri_to_url(CFCUri *uri_obj, const char *uri_string, CFCClass *base,
+ int dir_level) {
+ const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj);
+ CFCClass *klass = full_struct_sym
+ ? CFCClass_fetch_by_struct_sym(full_struct_sym)
+ : NULL;
+
+ if (klass) {
+ return S_struct_sym_to_url(full_struct_sym, base, dir_level);
+ }
+
+ const char *struct_sym = CFCUri_get_struct_sym(uri_obj);
+ CFCDocument *doc = CFCDocument_fetch(struct_sym);
+
+ if (doc) {
+ const char *path_part = CFCDocument_get_path_part(doc);
+ char *slashy = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "/");
+ char *url = CFCUtil_sprintf("%s.html", slashy);
+ char *rel_url = S_relative_url(url, base, dir_level);
+
+ FREEMEM(url);
+ FREEMEM(slashy);
+ return rel_url;
+ }
+
+ CFCUtil_warn("No class or document found for URI '%s'",
+ uri_string);
+ return CFCUtil_strdup("not_found.html");
+}
+
// Return a relative URL to the class with full struct sym `struct_sym`.
static char*
-S_struct_sym_to_url(const char *struct_sym, CFCClass *base) {
+S_struct_sym_to_url(const char *struct_sym, CFCClass *base, int dir_level) {
if (!struct_sym) { return CFCUtil_strdup("not_found.html"); }
CFCClass *klass = CFCClass_fetch_by_struct_sym(struct_sym);
- return S_class_to_url(klass, base);
+ return S_class_to_url(klass, base, dir_level);
}
// Return a relative URL to a class.
static char*
-S_class_to_url(CFCClass *klass, CFCClass *base) {
+S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level) {
if (!klass) { return CFCUtil_strdup("not_found.html"); }
const char *class_name = CFCClass_get_name(klass);
char *path = CFCUtil_global_replace(class_name, "::", CHY_DIR_SEP);
char *url = CFCUtil_sprintf("%s.html", path);
- char *rel_url = S_relative_url(url, base);
+ char *rel_url = S_relative_url(url, base, dir_level);
FREEMEM(url);
FREEMEM(path);
@@ -938,19 +1117,24 @@ S_class_to_url(CFCClass *klass, CFCClass *base) {
}
static char*
-S_relative_url(const char *url, CFCClass *base) {
- if (base == NULL) { return CFCUtil_strdup(url); }
+S_relative_url(const char *url, CFCClass *base, int dir_level) {
+ if (base) {
+ const char *base_name = CFCClass_get_name(base);
+ for (size_t i = 0; base_name[i]; i++) {
+ if (base_name[i] == ':' && base_name[i+1] == ':') {
+ dir_level++;
+ i++;
+ }
+ }
+ }
// Create path back to root
- char *prefix = CFCUtil_strdup("");
- const char *base_name = CFCClass_get_name(base);
-
- for (size_t i = 0; base_name[i]; i++) {
- if (base_name[i] == ':' && base_name[i+1] == ':') {
- prefix = CFCUtil_cat(prefix, "../", NULL);
- i++;
- }
+ size_t bytes = dir_level * 3;
+ char *prefix = (char*)MALLOCATE(bytes + 1);
+ for (size_t i = 0; i < bytes; i += 3) {
+ memcpy(prefix + i, "../", 3);
}
+ prefix[bytes] = '\0';
char *rel_url = CFCUtil_sprintf("%s%s", prefix, url);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d11a489f/compiler/src/CFCCHtml.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.h b/compiler/src/CFCCHtml.h
index 41f46fc..3e095d5 100644
--- a/compiler/src/CFCCHtml.h
+++ b/compiler/src/CFCCHtml.h
@@ -51,20 +51,13 @@ CFCCHtml_destroy(CFCCHtml *self);
void
CFCCHtml_write_html_docs(CFCCHtml *self);
-/** Return the index document of the HTML documentation for `parcel`
- * or NULL if there aren't any public classes in the parcel.
- */
-char*
-CFCCHtml_create_index_doc(CFCCHtml *self, struct CFCParcel *parcel,
- struct CFCClass **classes);
-
/** Return the HTML documentation for the class.
*/
char*
CFCCHtml_create_html_doc(CFCCHtml *self, struct CFCClass *klass);
char*
-CFCCHtml_create_html_body(struct CFCClass *klass);
+CFCCHtml_create_html_body(CFCCHtml *self, struct CFCClass *klass);
#ifdef __cplusplus
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d11a489f/compiler/src/CFCTestDocuComment.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestDocuComment.c b/compiler/src/CFCTestDocuComment.c
index 99bcc95..2baf6c9 100644
--- a/compiler/src/CFCTestDocuComment.c
+++ b/compiler/src/CFCTestDocuComment.c
@@ -20,6 +20,7 @@
#include "CFCCHtml.h"
#include "CFCCMan.h"
#include "CFCClass.h"
+#include "CFCHierarchy.h"
#include "CFCParcel.h"
#include "CFCParser.h"
#include "CFCPerlClass.h"
@@ -118,7 +119,10 @@ S_test_parser(CFCTest *test) {
static void
S_test_generator(CFCTest *test) {
+ CFCHierarchy *hierarchy = CFCHierarchy_new("autogen");
CFCParcel *parcel = CFCParcel_new("Neato", NULL, NULL, NULL);
+ CFCParcel_register(parcel);
+
CFCDocuComment *docu = CFCDocuComment_parse(
"/** Test documentation generator.\n"
" * \n"
@@ -182,29 +186,30 @@ S_test_generator(CFCTest *test) {
"Paragraph after list\n";
STR_EQ(test, man_page, expected_man, "create man page");
- char *html = CFCCHtml_create_html_body(klass);
+ CFCCHtml *chtml = CFCCHtml_new(hierarchy, "", "");
+ char *html = CFCCHtml_create_html_body(chtml, klass);
const char *expected_html =
"<h1>Neato::Object</h1>\n"
"<table>\n"
"<tr>\n"
"<td class=\"label\">parcel</td>\n"
- "<td><a href=\"neato.html\">Neato</a></td>\n"
+ "<td><a href=\"../neato.html\">Neato</a></td>\n"
"</tr>\n"
"<tr>\n"
- "<td class=\"label\">class name</td>\n"
- "<td>Neato::Object</td>\n"
+ "<td class=\"label\">class variable</td>\n"
+ "<td><code><span class=\"prefix\">NEATO_</span>OBJECT</code></td>\n"
"</tr>\n"
"<tr>\n"
- "<td class=\"label\">class nickname</td>\n"
- "<td>Object</td>\n"
+ "<td class=\"label\">struct symbol</td>\n"
+ "<td><code><span class=\"prefix\">neato_</span>Object</code></td>\n"
"</tr>\n"
"<tr>\n"
- "<td class=\"label\">class variable</td>\n"
- "<td><code>NEATO_OBJECT</code></td>\n"
+ "<td class=\"label\">class nickname</td>\n"
+ "<td><code><span class=\"prefix\">neato_</span>Object</code></td>\n"
"</tr>\n"
"<tr>\n"
- "<td class=\"label\">struct symbol</td>\n"
- "<td><code>neato_Object</code></td>\n"
+ "<td class=\"label\">header file</td>\n"
+ "<td><code>class.h</code></td>\n"
"</tr>\n"
"</table>\n"
"<h2>Name</h2>\n"
@@ -286,10 +291,14 @@ S_test_generator(CFCTest *test) {
CFCBase_decref((CFCBase*)perl_pod);
CFCBase_decref((CFCBase*)perl_class);
FREEMEM(html);
+ CFCBase_decref((CFCBase*)chtml);
FREEMEM(man_page);
CFCBase_decref((CFCBase*)klass);
CFCBase_decref((CFCBase*)docu);
CFCBase_decref((CFCBase*)parcel);
+ CFCBase_decref((CFCBase*)hierarchy);
+
+ CFCParcel_reap_singletons();
}
static void