Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • a8e93126148a825be4ef03ae8371d10f095ac4a1
  • main par défaut protégée
2 résultats

tag.lua

Blame
  • uri.c 3,85 Kio
    #define _POSIX_C_SOURCE 200809L
    
    #include <common/common.h>
    #include <lektor/uri.h>
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
    #include <stdio.h>
    #include <errno.h>
    #include <limits.h>
    
    static inline char *
    __prefix(char *str, struct lkt_uri *ret)
    {
        char *val;
        size_t len;
    
        if (!str || !ret)
            return NULL;
    
        /* The minimal uri is id://1 which is a 6 characters long */
        if ((len = strlen(str)) <= 5)
            return NULL;
    
        if (STR_NMATCH(str, "id", 2)) {
            ret->type = uri_id;
            val = str + 2;
        } else if (STR_NMATCH(str, "playlist", 8)) {
            ret->type = uri_playlist;
            val = str + 3;
        } else if (STR_NMATCH(str, "type", 4)) {
            ret->type = uri_type;
            val = str + 4;
        } else if (STR_NMATCH(str, "author", 6)) {
            ret->type = uri_author;
            val = str + 6;
        } else if (STR_NMATCH(str, "category", 8)) {
            ret->type = uri_category;
            val = str + 8;
        } else if (STR_NMATCH(str, "lang", 4)) {
            ret->type = uri_language;
            val = str + 4;
        } else if (STR_NMATCH(str, "query", 5)) {
            ret->type = uri_query;
            val = str + 5;
        } else
            return NULL;
    
        /* No place for the '://' separator */
        if (len - (val - str) < 3)
            return NULL;
    
        val += 3;
        ret->value = val;
        return val;
    }
    
    bool
    lkt_uri_from(struct lkt_uri *ret, char *const str)
    {
        if (NULL == __prefix(str, ret))
            return false;
    
        if (ret->type == uri_id) {
            errno = 0;
            ret->id = strtol(ret->value, NULL, 10);  /* Override */
            if (errno != 0)
                return false;
        }
    
        ret->_allocated = false;
        return true;
    }
    
    bool
    lkt_uri_from_list(struct lkt_uri *ret, char **list)
    {
        int i;
        if (!list || !list[0])
            return false;
    
        if (!list[1])
            return lkt_uri_from(ret, list[0]);
    
        if (NULL == __prefix(list[0], ret))
            return false;
    
        /* Nothing after the separator */
        if ('\0' == * (char *) ret->value)
            return false;
    
        char *buffer = (char *) malloc(sizeof(char) * (strlen(ret->value) + 1));
        if (NULL == buffer)
            return false;
        strcpy(buffer, ret->value);
    
        for (i = 1; list[i]; ++i) {
            char *new = realloc(buffer, strlen(buffer) + 1 + strlen(list[i]) + 1);
            if (NULL == new) {
                free(buffer);
                return false;
            }
    
            buffer = new;
            strcat(buffer, " ");
            strcat(buffer, list[i]);
        }
    
        ret->value = buffer;
        ret->_allocated = true;
        return true;
    }
    
    void
    lkt_uri_free(struct lkt_uri *ret)
    {
        if (NULL == ret)
            return;
    
        if (ret->_allocated)
            free(ret->value);
    }
    
    /* Support a subrange of URIs. */
    static inline int
    __lkt_to_str(struct lkt_uri *uri, char *ret, size_t len)
    {
        switch (uri->type) {
        case uri_id:
            safe_snprintf(ret, len, "id=%s", (char *) uri->value);
            break;
        case uri_type:
            safe_snprintf(ret, len, "type=%s", (char *) uri->value);
            break;
        case uri_author:
            safe_snprintf(ret, len, "author=%s", (char *) uri->value);
            break;
        case uri_category:
            safe_snprintf(ret, len, "cat=%s", (char *) uri->value);
            break;
        case uri_query:
            safe_snprintf(ret, len, "search=%s", (char *) uri->value);
            break;
        default:
            LOG_WARN("URI", "type %d may not be supported by kurisu, "
                     "generate an error", uri->type);
            return 1;
        }
    
        ret[len - 1] = '\0';
        return 0;
    }
    
    int
    lkt_uri_to_url(struct lkt_uri *uri, const char *base_url, char *ret, size_t len)
    {
        RETURN_UNLESS(uri && base_url && ret && len > 0, "Invalid argument", 1);
    
        /* Craft URL */
        memset(ret, 0, len);
        memcpy(ret, base_url, sizeof(char) * strlen(base_url));
        strncat(ret, "?", len - 1);
    
        /* The query */
        size_t init_len = strlen(ret);
        return __lkt_to_str(uri, ret + init_len, len - init_len);
    }