Simplify URI handling
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/37504e4c Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/37504e4c Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/37504e4c Branch: refs/heads/master Commit: 37504e4cb19bc94fc801ef511a621d475022a813 Parents: 7973bf5 Author: Nick Wellnhofer <[email protected]> Authored: Sun Jul 26 18:29:53 2015 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Thu Aug 6 18:19:19 2015 +0200 ---------------------------------------------------------------------- compiler/src/CFCC.c | 90 +++----------- compiler/src/CFCC.h | 2 +- compiler/src/CFCCHtml.c | 98 +++++++-------- compiler/src/CFCCMan.c | 2 +- compiler/src/CFCPerlPod.c | 98 ++++++--------- compiler/src/CFCUri.c | 276 +++++++++++++++++++++++------------------ compiler/src/CFCUri.h | 21 ++-- 7 files changed, 274 insertions(+), 313 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCC.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c index aa1e267..6fba122 100644 --- a/compiler/src/CFCC.c +++ b/compiler/src/CFCC.c @@ -172,89 +172,35 @@ CFCC_write_hostdefs(CFCC *self) { } char* -CFCC_link_text(CFCUri *uri_obj, CFCClass *klass) { +CFCC_link_text(CFCUri *uri_obj) { char *link_text = NULL; int type = CFCUri_get_type(uri_obj); switch (type) { - case CFC_URI_CLASS: { - 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; - } + case CFC_URI_NULL: + link_text = CFCUtil_strdup("NULL"); + break; - CFCUtil_warn("Can't resolve Clownfish URI '%s'", struct_sym); + case CFC_URI_CLASS: { + CFCClass *klass = CFCUri_get_class(uri_obj); + const char *src = CFCClass_included(klass) + ? CFCClass_get_name(klass) + : CFCClass_get_struct_sym(klass); + link_text = CFCUtil_strdup(src); 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); + const char *name = CFCUri_get_callable_name(uri_obj); + link_text = CFCUtil_sprintf("%s()", name); + break; + } - 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 + case CFC_URI_DOCUMENT: { + CFCDocument *doc = CFCUri_get_document(uri_obj); + const char *name = CFCDocument_get_name(doc); + link_text = CFCUtil_strdup(name); break; } } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCC.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCC.h b/compiler/src/CFCC.h index b8c6c73..8b98461 100644 --- a/compiler/src/CFCC.h +++ b/compiler/src/CFCC.h @@ -62,7 +62,7 @@ void CFCC_write_man_pages(CFCC *self); char* -CFCC_link_text(struct CFCUri *uri_obj, struct CFCClass *klass); +CFCC_link_text(struct CFCUri *uri_obj); #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCCHtml.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c index aa240b0..52740f5 100644 --- a/compiler/src/CFCCHtml.c +++ b/compiler/src/CFCCHtml.c @@ -171,8 +171,7 @@ static char* S_type_to_html(CFCClass *klass, CFCType *type); static char* -S_cfc_uri_to_url(CFCUri *uri_obj, const char *uri_string, CFCClass *base, - int dir_level); +S_cfc_uri_to_url(CFCUri *uri_obj, CFCClass *base, int dir_level); static char* S_struct_sym_to_url(const char *struct_sym, CFCClass *base, int dir_level); @@ -181,6 +180,9 @@ static char* S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level); static char* +S_document_to_url(CFCDocument *doc, CFCClass *base, int dir_level); + +static char* S_relative_url(const char *url, CFCClass *base, int dir_level); CFCCHtml* @@ -1007,39 +1009,21 @@ S_transform_code_block(cmark_node *code_block, int found_matching_code_block) { } static void -S_transform_link(cmark_node *link, CFCClass *klass, int dir_level) { +S_transform_link(cmark_node *link, CFCClass *doc_class, 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_string, klass); - int type = CFCUri_get_type(uri_obj); - - switch (type) { - case CFC_URI_CLASS: { - 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 *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; - } - } + CFCUri *uri_obj = CFCUri_new(uri_string, doc_class); + char *url = S_cfc_uri_to_url(uri_obj, doc_class, dir_level); - if (new_uri) { - cmark_node_set_url(link, new_uri); + if (url) { + cmark_node_set_url(link, url); if (!cmark_node_first_child(link)) { // Empty link text. - char *link_text = CFCC_link_text(uri_obj, klass); + char *link_text = CFCC_link_text(uri_obj); if (link_text) { cmark_node *text_node = cmark_node_new(CMARK_NODE_TEXT); @@ -1061,7 +1045,7 @@ S_transform_link(cmark_node *link, CFCClass *klass, int dir_level) { } CFCBase_decref((CFCBase*)uri_obj); - FREEMEM(new_uri); + FREEMEM(url); } static char* @@ -1103,34 +1087,35 @@ S_type_to_html(CFCClass *klass, CFCType *type) { // 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); - } +S_cfc_uri_to_url(CFCUri *uri_obj, CFCClass *doc_class, int dir_level) { + char *url = NULL; + int type = CFCUri_get_type(uri_obj); - const char *struct_sym = CFCUri_get_struct_sym(uri_obj); - CFCDocument *doc = CFCDocument_fetch(struct_sym); + switch (type) { + case CFC_URI_CLASS: { + CFCClass *klass = CFCUri_get_class(uri_obj); + url = S_class_to_url(klass, doc_class, dir_level); + break; + } - 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); + case CFC_URI_FUNCTION: + case CFC_URI_METHOD: { + CFCClass *klass = CFCUri_get_class(uri_obj); + const char *name = CFCUri_get_callable_name(uri_obj); + char *class_url = S_class_to_url(klass, doc_class, dir_level); + url = CFCUtil_sprintf("%s#func_%s", class_url, name); + FREEMEM(class_url); + break; + } - FREEMEM(url); - FREEMEM(slashy); - return rel_url; + case CFC_URI_DOCUMENT: { + CFCDocument *doc = CFCUri_get_document(uri_obj); + url = S_document_to_url(doc, doc_class, dir_level); + break; + } } - CFCUtil_warn("No class or document found for URI '%s'", - uri_string); - return CFCUtil_strdup("not_found.html"); + return url; } // Return a relative URL to the class with full struct sym `struct_sym`. @@ -1158,6 +1143,19 @@ S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level) { return rel_url; } +// Return a relative URL to a document. +static char* +S_document_to_url(CFCDocument *doc, CFCClass *base, int dir_level) { + 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; +} + static char* S_relative_url(const char *url, CFCClass *base, int dir_level) { if (base) { http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCCMan.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCCMan.c b/compiler/src/CFCCMan.c index 6089ca3..d6ba04d 100644 --- a/compiler/src/CFCCMan.c +++ b/compiler/src/CFCCMan.c @@ -597,7 +597,7 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { ) { // Empty link text. CFCUri *uri_obj = CFCUri_new(url, klass); - char *link_text = CFCC_link_text(uri_obj, klass); + char *link_text = CFCC_link_text(uri_obj); if (link_text) { result = CFCUtil_cat(result, link_text, NULL); FREEMEM(link_text); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCPerlPod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlPod.c b/compiler/src/CFCPerlPod.c index fa221e4..ffa0f04 100644 --- a/compiler/src/CFCPerlPod.c +++ b/compiler/src/CFCPerlPod.c @@ -558,10 +558,10 @@ S_pod_escape(const char *content) { } static char* -S_convert_link(cmark_node *link, CFCClass *klass, int header_level) { +S_convert_link(cmark_node *link, CFCClass *doc_class, int header_level) { cmark_node *child = cmark_node_first_child(link); const char *uri = cmark_node_get_url(link); - char *text = S_nodes_to_pod(child, klass, header_level); + char *text = S_nodes_to_pod(child, doc_class, header_level); char *retval; if (!CFCUri_is_clownfish_uri(uri)) { @@ -572,7 +572,7 @@ S_convert_link(cmark_node *link, CFCClass *klass, int header_level) { char *new_uri = NULL; char *new_text = NULL; - CFCUri *uri_obj = CFCUri_new(uri, klass); + CFCUri *uri_obj = CFCUri_new(uri, doc_class); int type = CFCUri_get_type(uri_obj); switch (type) { @@ -582,52 +582,18 @@ S_convert_link(cmark_node *link, CFCClass *klass, int header_level) { break; case CFC_URI_CLASS: { - 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 (uri_class != klass) { - const char *class_name = CFCClass_get_name(uri_class); - new_uri = CFCUtil_strdup(class_name); - } - } - else { - const char *doc_name = CFCUri_get_struct_sym(uri_obj); - CFCDocument *doc = CFCDocument_fetch(doc_name); + CFCClass *klass = CFCUri_get_class(uri_obj); - if (!doc) { - CFCUtil_warn("No class or document found for URI '%s'", - uri); - } - else { - const char *path_part = CFCDocument_get_path_part(doc); - new_uri = CFCUtil_global_replace(path_part, CHY_DIR_SEP, - "::"); - } - } - - if (text[0] != '\0') { - // Keep text. - break; + if (klass != doc_class) { + const char *class_name = CFCClass_get_name(klass); + new_uri = CFCUtil_strdup(class_name); } - if (!uri_class - || !klass - || 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. - const char *class_name - = CFCClass_get_name(uri_class); - new_text = CFCUtil_strdup(class_name); + if (text[0] == '\0') { + const char *src = CFCClass_included(klass) + ? CFCClass_get_name(klass) + : CFCClass_get_struct_sym(klass); + new_text = CFCUtil_strdup(src); } break; @@ -635,35 +601,45 @@ S_convert_link(cmark_node *link, CFCClass *klass, int header_level) { case CFC_URI_FUNCTION: case CFC_URI_METHOD: { - const char *full_struct_sym = CFCUri_full_struct_sym(uri_obj); - const char *func_sym = CFCUri_get_func_sym(uri_obj); + CFCClass *klass = CFCUri_get_class(uri_obj); + const char *name = CFCUri_get_callable_name(uri_obj); // Convert "Err_get_error" to "Clownfish->error". - if (strcmp(full_struct_sym, "cfish_Err") == 0 - && strcmp(func_sym, "get_error") == 0 + if (strcmp(CFCClass_full_struct_sym(klass), "cfish_Err") == 0 + && strcmp(name, "get_error") == 0 ) { new_text = CFCUtil_strdup("Clownfish->error"); break; } - 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_name(uri_class); + if (klass != doc_class) { + const char *class_name = CFCClass_get_name(klass); new_uri = CFCUtil_strdup(class_name); } - new_text = CFCUtil_sprintf("%s()", func_sym); - for (size_t i = 0; new_text[i] != '\0'; ++i) { - new_text[i] = tolower(new_text[i]); + if (text[0] == '\0') { + new_text = CFCUtil_sprintf("%s()", name); + for (size_t i = 0; new_text[i] != '\0'; ++i) { + new_text[i] = tolower(new_text[i]); + } + } + + break; + } + + case CFC_URI_DOCUMENT: { + CFCDocument *doc = CFCUri_get_document(uri_obj); + + const char *path_part = CFCDocument_get_path_part(doc); + new_uri = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "::"); + + if (text[0] == '\0') { + const char *name = CFCDocument_get_name(doc); + new_text = CFCUtil_strdup(name); } break; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCUri.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCUri.c b/compiler/src/CFCUri.c index 4799d6a..fc6e8e8 100644 --- a/compiler/src/CFCUri.c +++ b/compiler/src/CFCUri.c @@ -22,15 +22,17 @@ #include "CFCBase.h" #include "CFCUri.h" #include "CFCClass.h" +#include "CFCDocument.h" #include "CFCUtil.h" struct CFCUri { - CFCBase base; - int type; - char *prefix; - char *struct_sym; - char *full_struct_sym; - char *func_sym; + CFCBase base; + char *string; + CFCClass *doc_class; + int type; + CFCClass *klass; + CFCDocument *document; + char *callable; }; static const CFCMeta CFCURI_META = { @@ -40,10 +42,14 @@ static const CFCMeta CFCURI_META = { }; static void -S_parse_uri(CFCUri *self, const char *str, CFCClass *klass); +S_parse(CFCUri *self); -static char** -S_split(const char *str, char c, size_t *num_parts_ptr); +static void +S_resolve(CFCUri *self, const char *prefix, const char *struct_sym, + const char *callable); + +static char* +S_next_component(char **iter); int CFCUri_is_clownfish_uri(const char *uri) { @@ -51,176 +57,210 @@ CFCUri_is_clownfish_uri(const char *uri) { } CFCUri* -CFCUri_new(const char *uri, CFCClass *klass) { +CFCUri_new(const char *uri, CFCClass *doc_class) { CFCUri *self = (CFCUri*)CFCBase_allocate(&CFCURI_META); - return CFCUri_init(self, uri, klass); + return CFCUri_init(self, uri, doc_class); } CFCUri* -CFCUri_init(CFCUri *self, const char *uri, CFCClass *klass) { +CFCUri_init(CFCUri *self, const char *uri, CFCClass *doc_class) { CFCUTIL_NULL_CHECK(uri); if (strncmp(uri, "cfish:", 6) != 0) { CFCUtil_die("Invalid clownfish URI: %s", uri); } - if (strcmp(uri + 6, "@null") == 0) { - self->type = CFC_URI_NULL; - } - else { - S_parse_uri(self, uri, klass); - } - - if (self->prefix && self->struct_sym) { - self->full_struct_sym - = CFCUtil_sprintf("%s%s", self->prefix, self->struct_sym); - - if (getenv("CFC_CHECK_LINKS")) { - CFCClass *klass - = CFCClass_fetch_by_struct_sym(self->full_struct_sym); - - if (!klass) { - CFCUtil_warn("No class found for URI: %s", uri); - } - else if (self->type == CFC_URI_FUNCTION) { - if (!CFCClass_function(klass, self->func_sym)) { - const char *class_name = CFCClass_get_name(klass); - CFCUtil_warn("No function found for URI %s in %s", uri, - class_name); - } - } - else if (self->type == CFC_URI_METHOD) { - if (!CFCClass_method(klass, self->func_sym)) { - const char *class_name = CFCClass_get_name(klass); - CFCUtil_warn("No method found for URI %s in %s", uri, - class_name); - } - } - } - } + self->string = CFCUtil_strdup(uri); + self->doc_class = (CFCClass*)CFCBase_incref((CFCBase*)doc_class); return self; } void CFCUri_destroy(CFCUri *self) { - FREEMEM(self->prefix); - FREEMEM(self->struct_sym); - FREEMEM(self->full_struct_sym); - FREEMEM(self->func_sym); + FREEMEM(self->string); + FREEMEM(self->callable); + CFCBase_decref((CFCBase*)self->doc_class); + CFCBase_decref((CFCBase*)self->klass); + CFCBase_decref((CFCBase*)self->document); CFCBase_destroy((CFCBase*)self); } static void -S_parse_uri(CFCUri *self, const char *uri, CFCClass *klass) { - size_t num_components = 0; - char **components = S_split(uri + 6, '.', &num_components); - size_t i = 0; +S_parse(CFCUri *self) { + const char *uri_part = self->string + sizeof("cfish:") - 1; - self->type = CFC_URI_PARCEL; + if (strcmp(uri_part, "@null") == 0) { + self->type = CFC_URI_NULL; + return; + } - if (islower(components[i][0])) { + const char *parcel = NULL; + const char *struct_sym = NULL; + const char *callable = NULL; + + char *buf = CFCUtil_strdup(uri_part); + char *iter = buf; + const char *component = S_next_component(&iter); + + if (islower(component[0])) { // Parcel - self->prefix = CFCUtil_sprintf("%s_", components[i]); - ++i; - } - else if (klass) { - self->prefix = CFCUtil_strdup(CFCClass_get_prefix(klass)); + parcel = component; + component = S_next_component(&iter); } - if (i < num_components) { - self->type = CFC_URI_CLASS; - - if (isupper(components[i][0])) { + if (component) { + if (isupper(component[0])) { // Class - self->struct_sym = components[i]; - components[i] = NULL; + struct_sym = component; } - else if (i == 0 && components[i][0] == '\0') { - if (!klass) { - CFCUtil_die("Class needed to complete URI: %s", uri); - } - self->struct_sym = CFCUtil_strdup(CFCClass_get_struct_sym(klass)); + else if (component == buf && component[0] == '\0' && iter) { + // "cfish:.Method" style URL. + ; } else { - CFCUtil_die("Invalid clownfish URI: %s", uri); + CFCUtil_die("Invalid component in Clownfish URI: %s", + self->string); } - ++i; + component = S_next_component(&iter); + } + + if (component) { + callable = component; + component = S_next_component(&iter); + } + + if (component) { + CFCUtil_die("Trailing components in Clownfish URI: %s", self->string); } - if (i < num_components) { - if (isupper(components[i][0])) { - self->type = CFC_URI_METHOD; + S_resolve(self, parcel, struct_sym, callable); + + FREEMEM(buf); +} + +static void +S_resolve(CFCUri *self, const char *parcel, const char *struct_sym, + const char *callable) { + + // Try to find a CFCClass. + if (struct_sym || callable) { + CFCClass *doc_class = self->doc_class; + CFCClass *klass = NULL; + + if (parcel) { + char *full_struct_sym = CFCUtil_sprintf("%s_%s", parcel, struct_sym); + klass = CFCClass_fetch_by_struct_sym(full_struct_sym); + FREEMEM(full_struct_sym); } - else if (islower(components[i][0])) { - self->type = CFC_URI_FUNCTION; + else if (struct_sym && doc_class) { + const char *prefix = CFCClass_get_prefix(doc_class); + char *full_struct_sym = CFCUtil_sprintf("%s%s", prefix, struct_sym); + klass = CFCClass_fetch_by_struct_sym(full_struct_sym); + FREEMEM(full_struct_sym); } else { - CFCUtil_die("Invalid clownfish URI: %s", uri); + klass = doc_class; } - self->func_sym = components[i]; - components[i] = NULL; - ++i; - } + if (klass) { + self->type = CFC_URI_CLASS; + self->klass = klass; + CFCBase_incref((CFCBase*)klass); - if (i != num_components) { - CFCUtil_die("Invalid clownfish URI: %s", uri); + if (callable) { + if (islower(callable[0])) { + if (!CFCClass_function(klass, callable)) { + CFCUtil_warn("Unknown function '%s' in Clownfish URI: %s", + callable, self->string); + } + + self->type = CFC_URI_FUNCTION; + self->callable = CFCUtil_strdup(callable); + } + else { + if (!CFCClass_method(klass, callable)) { + CFCUtil_warn("Unknown method '%s' in Clownfish URI: %s", + callable, self->string); + } + + self->type = CFC_URI_METHOD; + self->callable = CFCUtil_strdup(callable); + } + } + } } - CFCUtil_free_string_array(components); -} + // Try to find a CFCDocument. + if (self->type == 0 && !parcel && struct_sym && !callable) { + CFCDocument *doc = CFCDocument_fetch(struct_sym); -static char** -S_split(const char *str, char c, size_t *num_parts_ptr) { - const char *ptr; - int num_parts = 1; + if (doc) { + self->type = CFC_URI_DOCUMENT; + self->document = doc; + CFCBase_incref((CFCBase*)doc); + } + } - for (ptr = str; *ptr != '\0'; ++ptr) { - if (*ptr == c) { ++num_parts; } + if (self->type == 0) { + CFCUtil_die("Couldn't resolve Clownfish URI: %s", self->string); } +} - char **parts = (char**)MALLOCATE((num_parts + 1) * sizeof(char*)); - const char *start = str; - size_t i = 0; +static char* +S_next_component(char **iter) { + char *component = *iter; - for (ptr = str; *ptr != '\0'; ++ptr) { - if (*ptr == c) { - parts[i++] = CFCUtil_strndup(start, ptr - start); - start = ptr + 1; + if (!component) { return NULL; } + + for (char *ptr = component; *ptr != '\0'; ptr++) { + if (*ptr == '.') { + *ptr = '\0'; + *iter = ptr + 1; + return component; } } - parts[i++] = CFCUtil_strndup(start, ptr - start); - parts[i] = NULL; - *num_parts_ptr = num_parts; + *iter = NULL; + return component; +} - return parts; +const char* +CFCUri_get_string(CFCUri *self) { + return self->string; } int CFCUri_get_type(CFCUri *self) { + if (self->type == 0) { S_parse(self); } return self->type; } -const char* -CFCUri_get_prefix(CFCUri *self) { - return self->prefix; -} - -const char* -CFCUri_get_struct_sym(CFCUri *self) { - return self->struct_sym; +CFCClass* +CFCUri_get_class(CFCUri *self) { + if (self->type == 0) { S_parse(self); } + if (self->klass == NULL) { + CFCUtil_die("Not a class URI"); + } + return self->klass; } -const char* -CFCUri_full_struct_sym(CFCUri *self) { - return self->full_struct_sym; +CFCDocument* +CFCUri_get_document(CFCUri *self) { + if (self->type == 0) { S_parse(self); } + if (self->document == NULL) { + CFCUtil_die("Not a document URI"); + } + return self->document; } const char* -CFCUri_get_func_sym(CFCUri *self) { - return self->func_sym; +CFCUri_get_callable_name(CFCUri *self) { + if (self->type == 0) { S_parse(self); } + if (self->callable == NULL) { + CFCUtil_die("Not a callable URI"); + } + return self->callable; } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37504e4c/compiler/src/CFCUri.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCUri.h b/compiler/src/CFCUri.h index 004fc3c..9e22d4e 100644 --- a/compiler/src/CFCUri.h +++ b/compiler/src/CFCUri.h @@ -21,14 +21,15 @@ extern "C" { #endif -#define CFC_URI_PARCEL 1 +#define CFC_URI_NULL 1 #define CFC_URI_CLASS 2 #define CFC_URI_FUNCTION 3 #define CFC_URI_METHOD 4 -#define CFC_URI_NULL 5 +#define CFC_URI_DOCUMENT 5 typedef struct CFCUri CFCUri; struct CFCClass; +struct CFCDocument; int CFCUri_is_clownfish_uri(const char *uri); @@ -42,20 +43,20 @@ CFCUri_init(CFCUri *self, const char *uri, struct CFCClass *klass); void CFCUri_destroy(CFCUri *self); +const char* +CFCUri_get_string(CFCUri *self); + int CFCUri_get_type(CFCUri *self); -const char* -CFCUri_get_prefix(CFCUri *self); - -const char* -CFCUri_get_struct_sym(CFCUri *self); +struct CFCClass* +CFCUri_get_class(CFCUri *self); -const char* -CFCUri_full_struct_sym(CFCUri *self); +struct CFCDocument* +CFCUri_get_document(CFCUri *self); const char* -CFCUri_get_func_sym(CFCUri *self); +CFCUri_get_callable_name(CFCUri *self); #ifdef __cplusplus }
