From: Michael Tremer Date: Thu, 29 Apr 2021 21:14:22 +0000 (+0000) Subject: util: Add new dependency parsing function X-Git-Tag: 0.9.28~1285^2~188 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bddb328380b5db7d3becb3dc14fda324695792a;p=pakfire.git util: Add new dependency parsing function This function can handle namespaces and has a better approach than the brute-force one that we used before that tries to find operators like =, >=, etc. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/util.h b/src/libpakfire/include/pakfire/util.h index c92b33b1d..e8e32fdd7 100644 --- a/src/libpakfire/include/pakfire/util.h +++ b/src/libpakfire/include/pakfire/util.h @@ -28,8 +28,12 @@ #include +#include + #include +Id pakfire_parse_dep(Pakfire pakfire, const char* s); + #define pakfire_string_format(s, fmt, ...) snprintf(s, sizeof(s) - 1, fmt, __VA_ARGS__) #define pakfire_string_set(s, value) pakfire_string_format(s, "%s", value) diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index a6eb41ec0..0032cdd5f 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -36,14 +36,98 @@ #include #include #include +#include #include #include #include #include +#include #define NSEC_PER_SEC 1000000000 +static Id pakfire_parse_namespace(Pool* pool, const char* s) { + const char* p = strchr(s, '('); + if (!p) + return 0; + + // Store the namespace ID + Id namespace = pool_strn2id(pool, s, p - s, 1); + + // Find the end of the string + s = strrchr(p, ')'); + if (!s) + return 0; + + Id id = pool_strn2id(pool, p + 1, s - p - 1, 1); + + // Bring it all together + return pool_rel2id(pool, namespace, id, REL_NAMESPACE, 1); +} + +Id pakfire_parse_dep(Pakfire pakfire, const char* s) { + Id id; + + if (!s) { + errno = EINVAL; + return 0; + } + + Pool* pool = pakfire_get_solv_pool(pakfire); + + // Consume any leading space + if (isspace(*s)) + s++; + + const char* p = s; + + // Find the first part (before =, >= or <=) + while (*p && !isspace(*p) && *p != '<' && *p != '=' && *p != '>') + p++; + + // The length of the first part + size_t l = p - s; + + // Add name to pool + if (pakfire_string_startswith(s, "pakfire(")) + id = pakfire_parse_namespace(pool, s); + else + id = pool_strn2id(pool, s, l, 1); + + // Consume any more space + if (isspace(*p)) + p++; + + if (*p == '<' || *p == '=' || *p == '>') { + int flags = 0; + + while (1) { + if (*p == '<') + flags |= REL_LT; + else if (*p == '=') + flags |= REL_EQ; + else if (*p == '>') + flags |= REL_GT; + else + break; + + p++; + } + + // Consume any more space + if (isspace(*p)) + p++; + + // Add EVR to pool + Id evr = pool_str2id(pool, p, 1); + + // Combine everything + id = pool_rel2id(pool, id, evr, flags, 1); + } + + return id; +} + int pakfire_string_startswith(const char* s, const char* prefix) { return !strncmp(s, prefix, strlen(prefix)); }