diff --git a/src/uri.c b/src/uri.c index 4a2c61a421d56021ef45b969a518a0e5e06fff9e..926dbd429317e83eea1a988eef58a5c91620b482 100644 --- a/src/uri.c +++ b/src/uri.c @@ -9,21 +9,18 @@ #include <errno.h> #include <limits.h> -bool -lkt_uri_from(struct lkt_uri *ret, char *const str) +static inline char * +__prefix(char *str, struct lkt_uri *ret) { - char *val, *endptr; + char *val; size_t len; - long id; - - if (ret == NULL || str == NULL) - return false; - len = strlen(str); + if (!str || !ret) + return NULL; - // The minimal uri is id://1 which is a 6 characters long - if (len <= 5 * sizeof(char)) - return false; + /* 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; @@ -47,35 +44,70 @@ lkt_uri_from(struct lkt_uri *ret, char *const str) ret->type = uri_query; val = str + 5; } else - return false; + return NULL; - // No place for the '://' separator + /* No place for the '://' separator */ if (len - (val - str) < 3) - return false; + return NULL; val += 3; + ret->value = val; + return val; +} - if (ret->type == uri_id) { - id = strtol(val, &endptr, 10); +bool +lkt_uri_from(struct lkt_uri *ret, char *const str) +{ + if (NULL == __prefix(str, ret)) + return false; - if ((errno == ERANGE && (id == LONG_MAX || id == LONG_MIN)) - || (errno != 0 && id == 0) || endptr == str) + if (ret->type == uri_id) { + errno = 0; + ret->id = strtol(ret->value, NULL, 10); /* Override */ + if (errno != 0) return false; + } - ret->value = calloc(1, sizeof(int)); + ret->_allocated = false; + return true; +} - if (ret->value == NULL) - return false; +bool +lkt_uri_from_list(struct lkt_uri *ret, char **list) +{ + int i; + if (!list || !list[0]) + return false; - *(int *) ret->value = id; - ret->_allocated = true; - } + 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; + } - else { - ret->_allocated = false; - ret->value = val; + buffer = new; + strcat(buffer, " "); + strcat(buffer, list[i]); } + ret->value = buffer; + ret->_allocated = true; return true; } @@ -110,8 +142,8 @@ __lkt_to_str(struct lkt_uri *uri, char *ret, size_t len) safe_snprintf(ret, len, "search=%s", (char *) uri->value); break; default: - LOG_ERROR("URI", "type %d may not be supported by kurisu, " - "generate an error", uri->type); + LOG_WARN("URI", "type %d may not be supported by kurisu, " + "generate an error", uri->type); return 1; }