commit:     e3c6591032d6a4589ae98d6abb0f59d3325bc11e
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 17 20:00:28 2021 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Wed Feb 17 20:00:28 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=e3c65910

libq/atom: adapt atom_explode to take an optional category

Sometimes we don't have the category available in the to be parsed
string, but in a separate string.  Make it relatively cheap to use this
category, compared to having to allocate and format a string to make
atom_explode pick it up.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 libq/atom.c | 21 ++++++++++++++-------
 libq/atom.h |  5 +++--
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/libq/atom.c b/libq/atom.c
index acf28be..f4c7c1e 100644
--- a/libq/atom.c
+++ b/libq/atom.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2020 Gentoo Foundation
+ * Copyright 2005-2021 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2008 Ned Ludd        - <[email protected]>
@@ -43,7 +43,7 @@ const char * const booga[] = {"!!!", "!=", "==", ">", "<"};
  * for a definition of which variable contains what, see:
  * https://dev.gentoo.org/~ulm/pms/head/pms.html#x1-10800011 */
 depend_atom *
-atom_explode(const char *atom)
+atom_explode_cat(const char *atom, const char *cat)
 {
        depend_atom *ret;
        char *ptr;
@@ -70,14 +70,14 @@ atom_explode(const char *atom)
         * We allocate memory for atom struct, one string for CAT/PF + PVR,
         * another to cover PN and a final one for P + PV. */
        slen = strlen(atom) + 1;
-       len = sizeof(*ret) + (slen * 3);
-       ret = xmalloc(len);
+       len = cat != NULL ? strlen(cat) + 1 : 0;
+       ret = xmalloc(sizeof(*ret) + (slen * 3) + len);
        memset(ret, '\0', sizeof(*ret));
 
        /* assign pointers to the three storage containers */
-       ret->CATEGORY = (char *)ret + sizeof(*ret);     /* CAT PF PVR */
-       ret->P        = ret->CATEGORY + slen;           /* P   PV     */
-       ret->PN       = ret->P + slen;                  /* PN         */
+       ret->CATEGORY = (char *)ret + sizeof(*ret) + len;     /* CAT PF PVR */
+       ret->P        = ret->CATEGORY + slen;                 /* P   PV     */
+       ret->PN       = ret->P + slen;                        /* PN         */
 
        /* check for blocker operators */
        ret->blocker = ATOM_BL_NONE;
@@ -245,6 +245,13 @@ atom_explode(const char *atom)
                ret->CATEGORY = NULL;
        }
 
+       /* inject separate CATEGORY when given, this will override any found
+        * CATEGORY, which is what it could be used for too */
+       if (cat != NULL) {
+               ret->CATEGORY = (char *)ret + sizeof(*ret);
+               memcpy(ret->CATEGORY, cat, len);
+       }
+
        if (ret->PF == NULL) {
                /* atom has no name, this is it */
                ret->P = NULL;

diff --git a/libq/atom.h b/libq/atom.h
index aff4548..ead9154 100644
--- a/libq/atom.h
+++ b/libq/atom.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2019 Gentoo Foundation
+ * Copyright 2005-2021 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2008 Ned Ludd        - <[email protected]>
@@ -96,7 +96,8 @@ typedef enum {
        OLDER
 } atom_equality;
 
-depend_atom *atom_explode(const char *atom);
+depend_atom *atom_explode_cat(const char *atom, const char *cat);
+#define atom_explode(A) atom_explode_cat(A, NULL)
 depend_atom *atom_clone(depend_atom *atom);
 void atom_implode(depend_atom *atom);
 atom_equality atom_compare(const depend_atom *a1, const depend_atom *a2);

Reply via email to