]> git.ipfire.org Git - pakfire.git/commitdiff
util: Add new dependency parsing function
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 29 Apr 2021 21:14:22 +0000 (21:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 29 Apr 2021 21:15:59 +0000 (21:15 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/util.h
src/libpakfire/util.c

index c92b33b1df61813287b181b067f30dd4d32084c6..e8e32fdd7e3e6a5a7a47f2d32c590f401c287700 100644 (file)
 
 #include <archive.h>
 
+#include <solv/pooltypes.h>
+
 #include <pakfire/types.h>
 
+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)
 
index a6eb41ec08f4f67cfb7263631e903b99c26a7615..0032cdd5fd7a9a6bac7ea9e9783bd46ddab44c8a 100644 (file)
 #include <archive.h>
 #include <archive_entry.h>
 #include <json.h>
+#include <solv/pool.h>
 #include <uuid/uuid.h>
 
 #include <pakfire/constants.h>
 #include <pakfire/logging.h>
 #include <pakfire/types.h>
+#include <pakfire/util.h>
 
 #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));
 }