Example #1
0
char*
CFCPerlPod_gen_subroutine_pod(CFCPerlPod *self, CFCFunction *func,
                              const char *alias, CFCClass *klass,
                              const char *code_sample,
                              const char *class_name, int is_constructor) {
    // Only allow "public" subs to be exposed as part of the public API.
    if (!CFCFunction_public(func)) {
        CFCUtil_die("%s#%s is not public", class_name, alias);
    }

    CFCParamList *param_list = CFCFunction_get_param_list(func);
    int num_vars = (int)CFCParamList_num_vars(param_list);
    char *pod = CFCUtil_sprintf("=head2 %s", alias);

    // 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) {
        CFCUtil_die("No DocuComment for '%s' in '%s'", alias, class_name);
    }

    // Build string summarizing arguments to use in header.
    if (num_vars > 2 || (is_constructor && num_vars > 1)) {
        pod = CFCUtil_cat(pod, "( I<[labeled params]> )\n\n", NULL);
    }
    else if (num_vars == 2) {
        // Kill self param.
        const char *name_list = CFCParamList_name_list(param_list);
        const char *after_comma = strchr(name_list, ',') + 1;
        while (isspace(*after_comma)) { after_comma++; }
        pod = CFCUtil_cat(pod, "(", after_comma, ")\n\n", NULL);
    }
    else {
        // num_args == 1, leave off 'self'.
        pod = CFCUtil_cat(pod, "()\n\n", NULL);
    }

    // Add code sample.
    if (code_sample && strlen(code_sample)) {
        pod = CFCUtil_cat(pod, code_sample, "\n", NULL);
    }

    // Incorporate "description" text from DocuComment.
    const char *long_doc = CFCDocuComment_get_description(docucomment);
    if (long_doc && strlen(long_doc)) {
        char *perlified = CFCPerlPod_md_to_pod(self, klass, long_doc);
        pod = CFCUtil_cat(pod, perlified, NULL);
        FREEMEM(perlified);
    }

    // Add params in a list.
    const char**param_names = CFCDocuComment_get_param_names(docucomment);
    const char**param_docs  = CFCDocuComment_get_param_docs(docucomment);
    if (param_names[0]) {
        pod = CFCUtil_cat(pod, "=over\n\n", NULL);
        for (size_t i = 0; param_names[i] != NULL; i++) {
            char *perlified = CFCPerlPod_md_to_pod(self, klass, param_docs[i]);
            pod = CFCUtil_cat(pod, "=item *\n\nB<", param_names[i], "> - ",
                              perlified, NULL);
            FREEMEM(perlified);
        }
        pod = CFCUtil_cat(pod, "=back\n\n", NULL);
    }

    // Add return value description, if any.
    const char *retval_doc = CFCDocuComment_get_retval(docucomment);
    if (retval_doc && strlen(retval_doc)) {
        char *perlified = CFCPerlPod_md_to_pod(self, klass, retval_doc);
        pod = CFCUtil_cat(pod, "Returns: ", perlified, NULL);
        FREEMEM(perlified);
    }

    return pod;
}
Example #2
0
static void
S_resolve(CFCUri *self, const char *parcel, const char *struct_sym,
          const char *callable) {

    // Try to find a CFCClass.
    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 (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 if (callable) {
        klass = doc_class;
    }

    if (klass) {
        if (!CFCClass_public(klass)) {
            CFCUtil_warn("Non-public class '%s' in Clownfish URI: %s",
                          CFCClass_get_struct_sym(klass), self->string);
        }

        self->type  = CFC_URI_CLASS;
        self->klass = klass;
        CFCBase_incref((CFCBase*)klass);

        if (callable) {
            if (islower(callable[0])) {
                CFCFunction *function = CFCClass_function(klass, callable);

                if (!function) {
                    CFCUtil_warn("Unknown function '%s' in Clownfish URI: %s",
                                 callable, self->string);
                }
                else if (!CFCFunction_public(function)) {
                    CFCUtil_warn("Non-public function '%s' in Clownfish URI:"
                                 " %s", callable, self->string);
                }

                self->type     = CFC_URI_FUNCTION;
                self->callable = CFCUtil_strdup(callable);
            }
            else {
                CFCMethod *method = CFCClass_method(klass, callable);

                if (!method) {
                    CFCUtil_warn("Unknown method '%s' in Clownfish URI: %s",
                                 callable, self->string);
                }
                else if (!CFCMethod_public(method)) {
                    CFCUtil_warn("Non-public method '%s' in Clownfish URI:"
                                 " %s", callable, self->string);
                }

                self->type     = CFC_URI_METHOD;
                self->callable = CFCUtil_strdup(callable);
            }
        }

        return;
    }

    // Try to find a CFCDocument.
    if (!parcel && struct_sym && !callable) {
        CFCDocument *doc = CFCDocument_fetch(struct_sym);

        if (doc) {
            self->type     = CFC_URI_DOCUMENT;
            self->document = doc;
            CFCBase_incref((CFCBase*)doc);
            return;
        }
    }

    S_set_error(self, "Couldn't resolve Clownfish URI");
}
Example #3
0
char*
CFCPerlPod_gen_subroutine_pod(CFCFunction *func,
                              const char *alias, CFCClass *klass,
                              const char *code_sample,
                              const char *class_name, int is_constructor) {
    // Only allow "public" subs to be exposed as part of the public API.
    if (!CFCFunction_public(func)) {
        CFCUtil_die("%s#%s is not public", class_name, alias);
    }

    char *pod = CFCUtil_sprintf("=head2 %s\n\n", alias);

    // Add code sample.
    if (!code_sample) {
        char *auto_sample
            = S_gen_code_sample(func, alias, klass, is_constructor);
        pod = CFCUtil_cat(pod, auto_sample, "\n", NULL);
        FREEMEM(auto_sample);
    }
    else {
        pod = CFCUtil_cat(pod, code_sample, "\n", NULL);
    }

    // Get documentation, which may be inherited.
    CFCDocuComment *docucomment = CFCFunction_get_docucomment(func);
    if (!docucomment) {
        const char *func_name = CFCFunction_get_name(func);
        CFCClass *parent = klass;
        while (NULL != (parent = CFCClass_get_parent(parent))) {
            CFCFunction *parent_func
                = (CFCFunction*)CFCClass_method(parent, func_name);
            if (!parent_func) { break; }
            docucomment = CFCFunction_get_docucomment(parent_func);
            if (docucomment) { break; }
        }
    }
    if (!docucomment) {
        return pod;
    }

    // Incorporate "description" text from DocuComment.
    const char *long_doc = CFCDocuComment_get_description(docucomment);
    if (long_doc && strlen(long_doc)) {
        char *perlified = CFCPerlPod_md_to_pod(long_doc, klass, 3);
        pod = CFCUtil_cat(pod, perlified, NULL);
        FREEMEM(perlified);
    }

    // Add params in a list.
    const char**param_names = CFCDocuComment_get_param_names(docucomment);
    const char**param_docs  = CFCDocuComment_get_param_docs(docucomment);
    if (param_names[0]) {
        pod = CFCUtil_cat(pod, "=over\n\n", NULL);
        for (size_t i = 0; param_names[i] != NULL; i++) {
            char *perlified = CFCPerlPod_md_to_pod(param_docs[i], klass, 3);
            pod = CFCUtil_cat(pod, "=item *\n\nB<", param_names[i], "> - ",
                              perlified, NULL);
            FREEMEM(perlified);
        }
        pod = CFCUtil_cat(pod, "=back\n\n", NULL);
    }

    // Add return value description, if any.
    const char *retval_doc = CFCDocuComment_get_retval(docucomment);
    if (retval_doc && strlen(retval_doc)) {
        char *perlified = CFCPerlPod_md_to_pod(retval_doc, klass, 3);
        pod = CFCUtil_cat(pod, "Returns: ", perlified, NULL);
        FREEMEM(perlified);
    }

    return pod;
}