Esempio n. 1
0
static char*
S_camel_to_lower(const char *camel) {
    if (camel[0] == '\0') { return CFCUtil_strdup(""); }

    size_t alloc = 1;
    for (size_t i = 1; camel[i]; i++) {
        if (CFCUtil_isupper(camel[i]) && CFCUtil_islower(camel[i+1])) {
            alloc += 1;
        }
        alloc += 1;
    }
    char *lower = (char*)MALLOCATE(alloc + 1);

    lower[0] = CFCUtil_tolower(camel[0]);
    size_t j = 1;
    for (size_t i = 1; camel[i]; i++) {
        // Only insert underscore if next char is lowercase.
        if (CFCUtil_isupper(camel[i]) && CFCUtil_islower(camel[i+1])) {
            lower[j++] = '_';
        }
        lower[j++] = CFCUtil_tolower(camel[i]);
    }
    lower[j] = '\0';

    return lower;
}
Esempio n. 2
0
static char*
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, doc_class, header_level);
    char       *retval;

    if (!CFCUri_is_clownfish_uri(uri)) {
        retval = S_pod_link(text, uri);
        FREEMEM(text);
        return retval;
    }

    char       *new_uri  = NULL;
    char       *new_text = NULL;
    CFCUri     *uri_obj  = CFCUri_new(uri, doc_class);
    CFCUriType  type     = CFCUri_get_type(uri_obj);

    switch (type) {
        case CFC_URI_ERROR: {
            const char *error = CFCUri_get_error(uri_obj);
            new_text = CFCUtil_sprintf("[%s]", error);
            break;
        }

        case CFC_URI_NULL:
            // Change all instances of NULL to 'undef'
            new_text = CFCUtil_strdup("undef");
            break;

        case CFC_URI_CLASS: {
            CFCClass *klass = CFCUri_get_class(uri_obj);

            if (klass != doc_class) {
                const char *class_name = CFCClass_get_name(klass);
                new_uri = 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;
        }

        case CFC_URI_FUNCTION:
        case CFC_URI_METHOD: {
            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(CFCClass_full_struct_sym(klass), "cfish_Err") == 0
                && strcmp(name, "get_error") == 0
            ) {
                new_text = CFCUtil_strdup("Clownfish->error");
                break;
            }

            char *perl_name = CFCUtil_strdup(name);
            for (size_t i = 0; perl_name[i] != '\0'; ++i) {
                perl_name[i] = CFCUtil_tolower(perl_name[i]);
            }

            // The Perl POD only contains sections for novel methods. Link
            // to the class where the method is declared first.
            if (type == CFC_URI_METHOD) {
                CFCClass *parent = CFCClass_get_parent(klass);
                while (parent && CFCClass_method(parent, name)) {
                    klass = parent;
                    parent = CFCClass_get_parent(klass);
                }
            }

            if (klass == doc_class) {
                new_uri = CFCUtil_sprintf("/%s", perl_name);
            }
            else {
                const char *class_name = CFCClass_get_name(klass);
                new_uri = CFCUtil_sprintf("%s/%s", class_name, perl_name);
            }

            if (text[0] == '\0') {
                new_text = CFCUtil_sprintf("%s()", perl_name);
            }

            FREEMEM(perl_name);
            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;
        }
    }

    if (new_text) {
        FREEMEM(text);
        text = new_text;
    }

    if (new_uri) {
        retval = S_pod_link(text, new_uri);
        FREEMEM(new_uri);
        FREEMEM(text);
    }
    else {
        retval = text;
    }

    CFCBase_decref((CFCBase*)uri_obj);

    return retval;
}
Esempio n. 3
0
CFCParcel*
CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
               CFCVersion *version, CFCVersion *major_version,
               CFCFileSpec *file_spec) {
    // Validate name.
    if (!name || !S_validate_name_or_nickname(name)) {
        CFCUtil_die("Invalid name: '%s'", name ? name : "[NULL]");
    }
    self->name = CFCUtil_strdup(name);

    // Validate or derive nickname.
    if (nickname) {
        if (!S_validate_name_or_nickname(nickname)) {
            CFCUtil_die("Invalid nickname: '%s'", nickname);
        }
        self->nickname = CFCUtil_strdup(nickname);
    }
    else {
        // Default nickname to name.
        self->nickname = CFCUtil_strdup(name);
    }

    // Default to version v0.
    if (version) {
        self->version = (CFCVersion*)CFCBase_incref((CFCBase*)version);
    }
    else {
        self->version = CFCVersion_new("v0");
    }
    if (major_version) {
        self->major_version
            = (CFCVersion*)CFCBase_incref((CFCBase*)major_version);
    }
    else {
        self->major_version = CFCVersion_new("v0");
    }

    // Set file_spec.
    self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec);

    // Derive prefix, Prefix, PREFIX.
    size_t nickname_len  = strlen(self->nickname);
    size_t prefix_len = nickname_len ? nickname_len + 1 : 0;
    size_t amount     = prefix_len + 1;
    self->prefix = (char*)MALLOCATE(amount);
    self->Prefix = (char*)MALLOCATE(amount);
    self->PREFIX = (char*)MALLOCATE(amount);
    memcpy(self->Prefix, self->nickname, nickname_len);
    if (nickname_len) {
        self->Prefix[nickname_len]  = '_';
        self->Prefix[nickname_len + 1]  = '\0';
    }
    else {
        self->Prefix[nickname_len] = '\0';
    }
    for (size_t i = 0; i < amount; i++) {
        self->prefix[i] = CFCUtil_tolower(self->Prefix[i]);
        self->PREFIX[i] = CFCUtil_toupper(self->Prefix[i]);
    }
    self->prefix[prefix_len] = '\0';
    self->Prefix[prefix_len] = '\0';
    self->PREFIX[prefix_len] = '\0';

    // Derive privacy symbol.
    size_t privacy_sym_len = nickname_len + 4;
    self->privacy_sym = (char*)MALLOCATE(privacy_sym_len + 1);
    memcpy(self->privacy_sym, "CFP_", 4);
    for (size_t i = 0; i < nickname_len; i++) {
        self->privacy_sym[i+4] = CFCUtil_toupper(self->nickname[i]);
    }
    self->privacy_sym[privacy_sym_len] = '\0';

    // Initialize flags.
    self->is_installed = false;

    // Initialize arrays.
    self->classes = (CFCClass**)CALLOCATE(1, sizeof(CFCClass*));
    self->num_classes = 0;
    self->prereqs = (CFCPrereq**)CALLOCATE(1, sizeof(CFCPrereq*));
    self->num_prereqs = 0;

    return self;
}