* [gentoo-commits] proj/portage-utils:master commit in: /, tests/atom_explode/, libq/
@ 2020-01-01 12:51 Fabian Groffen
0 siblings, 0 replies; only message in thread
From: Fabian Groffen @ 2020-01-01 12:51 UTC (permalink / raw
To: gentoo-commits
commit: c6537da04a6695656d655bf4e48813fb041ec010
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 1 12:50:18 2020 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Wed Jan 1 12:50:18 2020 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=c6537da0
libq/atom: stick to PMS for PVR
rework allocations somewhat, and make sure PVR does NOT include -r0, in
addition add PF to the structure, so this one can be grabbed more easily
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
TODO.md | 9 +--
libq/atom.c | 149 ++++++++++++++++++++++++++--------------------
libq/atom.h | 1 +
tests/atom_explode/test.c | 22 +++++--
4 files changed, 107 insertions(+), 74 deletions(-)
diff --git a/TODO.md b/TODO.md
index dffaa91..cd4f2b2 100644
--- a/TODO.md
+++ b/TODO.md
@@ -22,13 +22,8 @@
- replace all strtok by strtok\_r, because the latter is already used,
so we can
-# Atoms
-
-- only 32bit values are supported for revision (-r#)
-- only 64bit values are supported in any individual version component
- foo-(1234)\_alpha(56789)
-- these limits should not be an issue for all practical purposes
-- make PVR match PMS https://dev.gentoo.org/~ulm/pms/head/pms.html#x1-10800011
+- parse package.accept\_keywords such that we can provide the latest
+ "available" version like Portage
# qmerge
diff --git a/libq/atom.c b/libq/atom.c
index 05b138c..6f70847 100644
--- a/libq/atom.c
+++ b/libq/atom.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2019 Gentoo Foundation
+ * Copyright 2005-2020 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2008 Ned Ludd - <solar@gentoo.org>
@@ -39,6 +39,9 @@ const char * const atom_op_str[] = {
const char * const booga[] = {"!!!", "!=", "==", ">", "<"};
+/* split string into individual components, known as an atom
+ * 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)
{
@@ -48,18 +51,33 @@ atom_explode(const char *atom)
size_t slen;
size_t idx;
size_t sidx;
-
- /* we allocate mem for atom struct and two strings (strlen(atom)).
- * the first string is for CAT/PN/PV while the second is for PVR.
- * PVR needs 3 extra bytes for possible implicit '-r0'. */
- slen = strlen(atom);
- len = sizeof(*ret) + (slen + 1) * sizeof(*atom) * 3 + 3;
+ char *lastpv = NULL;
+ char *pv;
+
+ /* PMS 11.1 recap:
+ * CAT The package’s category app-editors
+ * PF Package name, version, and revision (if any) vim-7.0.174-r1
+ * PVR Package version and revision (if any) 7.0.174-r1
+ * P Package name and version, without the revision part vim-7.0.174
+ * PV Package version, with no revision 7.0.174
+ * PN Package name vim
+ * PR Package revision, or r0 if none exists r1
+ *
+ * Thus, CAT/PF is the full allocation of the input string, for the
+ * rest (P, PN, PV, PR, PVR) we need copies. We represent PR as an
+ * integer, which leaves the set to PN, P and PV.
+ * PVR is an offset inside PF, likewise, PV is an offset inside P.
+ * 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);
memset(ret, '\0', sizeof(*ret));
- ptr = (char *)ret;
- ret->P = ptr + sizeof(*ret);
- ret->PVR = ret->P + slen + 1;
- ret->CATEGORY = ret->PVR + slen + 1 + 3;
+
+ /* 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 */
/* check for blocker operators */
ret->blocker = ATOM_BL_NONE;
@@ -95,13 +113,15 @@ atom_explode(const char *atom)
ret->pfx_op += ATOM_OP_EQUAL;
atom++;
}
+
+ /* fill in full block */
strcpy(ret->CATEGORY, atom);
/* eat file name crap when given an (autocompleted) path */
if ((ptr = strstr(ret->CATEGORY, ".ebuild")) != NULL)
*ptr = '\0';
- /* chip off the trailing [::REPO] as needed */
+ /* chip off the trailing ::REPO as needed */
if ((ptr = strstr(ret->CATEGORY, "::")) != NULL) {
ret->REPO = ptr + 2;
*ptr = '\0';
@@ -172,7 +192,7 @@ atom_explode(const char *atom)
*ptr++ = '\0';
}
- /* chip off the trailing [:SLOT] as needed */
+ /* chip off the trailing :SLOT as needed */
if ((ptr = strrchr(ret->CATEGORY, ':')) != NULL) {
*ptr++ = '\0';
ret->SLOT = ptr;
@@ -205,14 +225,14 @@ atom_explode(const char *atom)
*ptr = '\0';
}
- /* break up the CATEGORY and PVR */
+ /* break up the CATEGORY, PF and PVR */
if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL) {
- ret->PN = ptr + 1;
- *ptr = '\0';
+ *ptr++ = '\0';
+ ret->PF = ptr;
/* set PN to NULL if there's nothing */
- if (ret->PN[0] == '\0')
- ret->PN = NULL;
+ if (ret->PF[0] == '\0')
+ ret->PF = NULL;
/* eat extra crap in case it exists, this is a feature to allow
* /path/to/pkg.ebuild, doesn't work with prefix operators
@@ -220,75 +240,81 @@ atom_explode(const char *atom)
if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL)
ret->CATEGORY = ptr + 1;
} else {
- ret->PN = ret->CATEGORY;
+ ret->PF = ret->CATEGORY;
ret->CATEGORY = NULL;
}
- if (ret->PN == NULL) {
+ if (ret->PF == NULL) {
/* atom has no name, this is it */
ret->P = NULL;
+ ret->PN = NULL;
ret->PVR = NULL;
+
return ret;
}
- /* CATEGORY should be all set here, PN contains everything up to
+ /* CATEGORY should be all set here, PF contains everything up to
* SLOT, REPO or '*'
- * PN must not end in a hyphen followed by anything matching version
- * syntax, version syntax starts with a number, so "-[0-9]" is a
- * separator from PN to PV* -- except it doesn't when the thing
- * doesn't validate as version :( */
-
- ptr = ret->PN;
- {
- char *lastpv = NULL;
- char *pv;
-
- while ((ptr = strchr(ptr, '-')) != NULL) {
- ptr++;
- if (!isdigit(*ptr))
- continue;
+ * PMS 3.1.2 says PN must not end in a hyphen followed by
+ * anything matching version syntax. PMS 3.2 version syntax
+ * starts with a number, so "-[0-9]" is a separator from PN to
+ * PV* -- except it doesn't when the thing doesn't validate as
+ * version :( */
+
+ ptr = ret->PF;
+ while ((ptr = strchr(ptr, '-')) != NULL) {
+ ptr++;
+ if (!isdigit(*ptr))
+ continue;
- /* so we should have something like "-2" here, see if this
- * checks out as valid version string */
- pv = ptr;
- while (*++ptr != '\0') {
- if (*ptr != '.' && !isdigit(*ptr))
- break;
- }
- /* allow for 1 optional suffix letter */
- if (*ptr >= 'a' && *ptr <= 'z')
- ret->letter = *ptr++;
- if (*ptr == '_' || *ptr == '-' || *ptr == '\0') {
- lastpv = pv;
- continue; /* valid, keep searching */
- }
- ret->letter = '\0';
+ /* so we should have something like "-2" here, see if this
+ * checks out as valid version string */
+ pv = ptr;
+ while (*++ptr != '\0') {
+ if (*ptr != '.' && !isdigit(*ptr))
+ break;
+ }
+ /* allow for 1 optional suffix letter */
+ if (*ptr >= 'a' && *ptr <= 'z')
+ ret->letter = *ptr++;
+ if (*ptr == '_' || *ptr == '-' || *ptr == '\0') {
+ lastpv = pv;
+ continue; /* valid, keep searching */
}
- ptr = lastpv;
+ ret->letter = '\0';
}
+ ptr = lastpv;
if (ptr == NULL) {
/* atom has no version, this is it */
- strcpy(ret->P, ret->PN);
- ret->PVR = NULL;
+ ret->P = ret->PN = ret->PF;
+ ret->PV = ret->PVR = NULL;
+
return ret;
}
- ret->PV = ptr;
+
+ ret->PVR = ptr;
+ snprintf(ret->PN, slen, "%.*s", (int)(ret->PVR - 1 - ret->PF), ret->PF);
/* find -r# */
- ptr = ret->PV + strlen(ret->PV) - 1;
- while (*ptr && ptr > ret->PV) {
- if (!isdigit(*ptr)) {
+ pv = NULL;
+ ptr = ret->PVR + strlen(ret->PVR) - 1;
+ while (*ptr && ptr > ret->PVR) {
+ if (!isdigit((int)*ptr)) {
if (ptr[0] == 'r' && ptr[-1] == '-') {
ret->PR_int = atoi(ptr + 1);
- ptr[-1] = '\0';
+ pv = &ptr[-1];
}
break;
}
ptr--;
}
- strcpy(ret->P, ret->PN);
- ret->PV[-1] = '\0';
+ if (pv != NULL) {
+ snprintf(ret->P, slen, "%.*s", (int)(pv - ret->PF), ret->PF);
+ } else {
+ ret->P = ret->PF;
+ }
+ ret->PV = ret->P + (ret->PVR - ret->PF);
/* break out all the suffixes */
sidx = 0;
@@ -325,9 +351,6 @@ atom_explode(const char *atom)
ret->suffixes[idx] = t;
}
- /* size is malloced above with the required space in mind */
- sprintf(ret->PVR, "%s-r%i", ret->PV, ret->PR_int);
-
return ret;
}
diff --git a/libq/atom.h b/libq/atom.h
index a5175b0..1548dd9 100644
--- a/libq/atom.h
+++ b/libq/atom.h
@@ -74,6 +74,7 @@ typedef struct {
char *CATEGORY;
char *PN;
char *PV;
+ char *PF;
unsigned int PR_int;
char letter;
atom_suffix *suffixes;
diff --git a/tests/atom_explode/test.c b/tests/atom_explode/test.c
index 21a5f1d..b794d3b 100644
--- a/tests/atom_explode/test.c
+++ b/tests/atom_explode/test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2019 Gentoo Foundation
+ * Copyright 2005-2020 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2008 Ned Ludd - <solar@gentoo.org>
@@ -19,9 +19,23 @@ FILE *warnout;
static inline void boom(depend_atom *a, char *s)
{
- printf("%s -> %s / [%s] %s - %s [%s] [r%i]\n",
- s, (a->CATEGORY?:"null"), a->P, a->PN,
- a->PVR, a->PV, a->PR_int);
+ /* python code:
+ * CATEGORY = cpv[0]
+ * PN = cpv[1]
+ * PV = cpv[2]
+ * PR_int = cpv[3]
+ * P = PN + "-" + PV
+ * PVR = PV + "-" + cpv[3]
+ * print(a+" -> "+CATEGORY+" / ["+P+"] "+PN+" - "+PVR+" ["+PV+"] ["+PR_int+"]")
+ * this most notably doesn't test PVR in compliance with PMS */
+ printf("%s -> %s / [%s] %s - %s%s [%s] [r%i]\n",
+ s,
+ (a->CATEGORY ? a->CATEGORY : "null"),
+ a->P,
+ a->PN,
+ a->PVR, (a->PVR != NULL && a->PR_int == 0) ? "-r0" : "",
+ a->PV,
+ a->PR_int);
}
int main(int argc, char *argv[])
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-01-01 12:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-01 12:51 [gentoo-commits] proj/portage-utils:master commit in: /, tests/atom_explode/, libq/ Fabian Groffen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox