]> git.ipfire.org Git - pakfire.git/blobdiff - src/libpakfire/util.c
Move dependency functions into an own file
[pakfire.git] / src / libpakfire / util.c
index e051d3abc61cffb9ed53f4f5beb78f2751e7b27b..0ff1107bdc7e877c763e14c78d1084536993e9a0 100644 (file)
@@ -18,7 +18,6 @@
 #                                                                             #
 #############################################################################*/
 
-#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <ftw.h>
@@ -37,7 +36,6 @@
 #include <archive.h>
 #include <archive_entry.h>
 #include <json.h>
-#include <solv/pool.h>
 #include <uuid/uuid.h>
 
 #include <pakfire/constants.h>
 #define BUFFER_SIZE 64 * 1024
 #define NSEC_PER_SEC 1000000000
 
-static const struct pakfire_rich_operation {
-       const char* keyword;
-       const int flags;
-} pakfire_rich_operations[] = {
-       { "and ",     REL_AND },
-       { "or ",      REL_OR },
-       { "if ",      REL_COND },
-       { "unless ",  REL_UNLESS },
-       { "else ",    REL_ELSE },
-       { "with ",    REL_WITH },
-       { "without ", REL_WITHOUT },
-       { NULL, 0 },
-};
-
-const char* pakfire_dep2str(struct pakfire* pakfire, Id id) {
-       Pool* pool = pakfire_get_solv_pool(pakfire);
-       if (!pool)
-               return NULL;
-
-       return pool_dep2str(pool, id);
-}
-
-/*
-       Reads the string until the next space is found.
-
-       This function considers opening and closing brackets.
-*/
-static size_t skip(const char** s, const char** n) {
-       const char* p = *s;
-
-       // Store p in n
-       *n = p;
-
-       int brackets = 0;
-
-       while (*p) {
-               switch (*p) {
-                       // End on space or comma
-                       case ' ':
-                       case ',':
-                               goto END;
-
-                       // Increment counter on opening bracket
-                       case '(':
-                               brackets++;
-                               break;
-
-                       // End on the last closing bracket
-                       case ')':
-                               if (brackets-- <= 0)
-                                       goto END;
-                               break;
-               }
-
-               // Move to next character
-               p++;
-       }
-
-END:
-       *s = p;
-
-       // Return the length of the skipped string
-       return p - *n;
-}
-
-/*
-       This function parses any namespaced dependencies
-*/
-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);
-}
-
-/*
-       This function parses a simple dependency like "foo = 1.2.3"
-*/
-static Id pakfire_parse_dep(struct pakfire* pakfire, const char** s) {
-       Id id = ID_NULL;
-
-       if (!s) {
-               errno = EINVAL;
-               return 0;
-       }
-
-       const char* p = *s;
-       const char* n = NULL;
-
-       // Ignore empty strings
-       if (!p)
-               return ID_NULL;
-
-       Pool* pool = pakfire_get_solv_pool(pakfire);
-
-       // Consume any leading space
-       if (isspace(*p))
-               p++;
-
-       // Find the first part
-       size_t l = skip(&p, &n);
-
-       // Add name to pool
-       if (pakfire_string_startswith(n, "pakfire("))
-               id = pakfire_parse_namespace(pool, n);
-       else
-               id = pool_strn2id(pool, n, 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++;
-
-               // Find the length of EVR
-               l = skip(&p, &n);
-
-               // Strip zero epoch
-               if (pakfire_string_startswith(n, "0:"))
-                       n += 2;
-
-               // Add EVR to pool
-               Id evr = pool_strn2id(pool, n, l, 1);
-
-               // Combine everything
-               id = pool_rel2id(pool, id, evr, flags, 1);
-       }
-
-       *s = p;
-
-       return id;
-}
-
-/*
-       This function parses any rich dependencies
-*/
-static Id pakfire_parse_rich_dep(struct pakfire* pakfire, const char** dep, int flags) {
-       const char* p = *dep;
-       Id id;
-
-       // Do not try parsing empty strings
-       if (!*p)
-               return ID_NULL;
-
-       // Must be starting with an opening bracket
-       if (!flags && *p++ != '(')
-               return ID_NULL;
-
-       switch (*p) {
-               // A new rich dependency
-               case '(':
-                       id = pakfire_parse_rich_dep(pakfire, &p, 0);
-                       if (!id)
-                               return id;
-                       break;
-
-               // End
-               case ')':
-                       return ID_NULL;
-
-               // Parse a regular dependency
-               default:
-                       id = pakfire_parse_dep(pakfire, &p);
-                       if (!id)
-                               return id;
-                       break;
-       }
-
-       // Consume any space
-       if (isspace(*p))
-               p++;
-
-       // If we have successfully parsed something, we would expect a closing bracket
-       if (*p == ')') {
-               *dep = p + 1;
-               return id;
-       }
-
-       // Search for a keyword
-       for (const struct pakfire_rich_operation* op = pakfire_rich_operations; op->keyword; op++) {
-               if (pakfire_string_startswith(p, op->keyword)) {
-                       // Skip the keyword
-                       p += strlen(op->keyword);
-
-                       // Store the flags
-                       flags = op->flags;
-                       break;
-               }
-       }
-
-       // If there was no keyword, we are done
-       if (!flags)
-               return ID_NULL;
-
-       // Parse the next bit
-       Id evr = pakfire_parse_rich_dep(pakfire, &p, flags);
-
-       // Abort if there was a problem
-       if (!evr)
-               return ID_NULL;
-
-       // Store until where we have parsed the string
-       *dep = p;
-
-       Pool* pool = pakfire_get_solv_pool(pakfire);
-
-       // Combine everything
-       return pool_rel2id(pool, id, evr, flags, 1);
-}
-
-Id pakfire_str2dep(struct pakfire* pakfire, const char* s) {
-       Id id = ID_NULL;
-
-       // Invalid input
-       if (!s) {
-               errno = EINVAL;
-               return id;
-       }
-
-       // Ignore empty strings
-       if (!*s)
-               return id;
-
-       // Consume any leading space
-       if (isspace(*s))
-               s++;
-
-       // Ignore any comments
-       if (*s == '#')
-               return id;
-
-       // Parse any rich dependencies
-       if (*s == '(')
-               id = pakfire_parse_rich_dep(pakfire, &s, 0);
-       else
-               id = pakfire_parse_dep(pakfire, &s);
-
-       // Return nothing if we could not parse the entire string
-       if (id && *s)
-               id = ID_NULL;
-
-       return id;
-}
-
-int pakfire_str2deps(struct pakfire* pakfire, struct pakfire_package* pkg,
-               void (callback)(struct pakfire_package* pkg, const char* dep), const char* deps) {
-       char* p = NULL;
-
-       // Check for valid inputs
-       if (!callback || !deps) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       // Copy deps into a working buffer
-       char* buffer = strdup(deps);
-       if (!buffer)
-               return 1;
-
-       char* dep = strtok_r(buffer, "\n", &p);
-
-       // Walk through the buffer line by line
-       while (dep) {
-               DEBUG(pakfire, "Found dep '%s'\n", dep);
-
-               // Add the dependency
-               callback(pkg, dep);
-
-               // Move on to next token
-               dep = strtok_r(NULL, "\n", &p);
-       }
-
-       free(buffer);
-       return 0;
-}
-
 int pakfire_string_startswith(const char* s, const char* prefix) {
        // Validate input
        if (!s || !prefix) {