aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPer Øyvind Karlsen <peroyvind@mandriva.org>2009-08-06 04:04:26 +0000
committerPer Øyvind Karlsen <peroyvind@mandriva.org>2009-08-06 04:04:26 +0000
commit96006bae106a9e4d6466c335916d1ea0ae69754f (patch)
tree8ab18382ce7fb794e6d7a2606192f6b1656f4f58
parent0eef8b901ac136b9cb681f6219f29bd8c197453a (diff)
downloadperl-URPM-96006bae106a9e4d6466c335916d1ea0ae69754f.tar
perl-URPM-96006bae106a9e4d6466c335916d1ea0ae69754f.tar.gz
perl-URPM-96006bae106a9e4d6466c335916d1ea0ae69754f.tar.bz2
perl-URPM-96006bae106a9e4d6466c335916d1ea0ae69754f.tar.xz
perl-URPM-96006bae106a9e4d6466c335916d1ea0ae69754f.zip
implement a local version of rpm5.org's EVR_t, rpmEVR* & friends for rpm.org
-rw-r--r--Makefile.PL2
-rw-r--r--URPM.xs121
2 files changed, 117 insertions, 6 deletions
diff --git a/Makefile.PL b/Makefile.PL
index a35ba66..eb008bb 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -54,7 +54,7 @@ my $ldflags = `pkg-config --libs rpm`;
if ($hversion ge hexversion("4.4.90") && $hversion lt hexversion("4.7")) {
# rpm.org version
push @rpmflags, "-DRPM_ORG";
- $ldflags .= ' -lrpmbuild';
+ $ldflags .= ' -lrpmbuild -lpcreposix';
}
my $ccflags = join(' ', '-Wall -Wextra -fno-strict-aliasing', @rpmflags);
diff --git a/URPM.xs b/URPM.xs
index 72325f0..baf7664 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -29,11 +29,127 @@
#undef Fstat
#ifdef RPM_ORG
+#include <pcreposix.h>
+#include <rpm/rpmlib.h>
+#include <rpm/rpmds.h>
+
static inline void *_free(const void * p) {
if (p != NULL) free((void *)p);
return NULL;
}
typedef struct rpmSpec_s * Spec;
+
+typedef struct EVR_s {
+ const char * str; /*!< EVR storage */
+ unsigned long Elong; /*!< E converted to integer. */
+ rpmsenseFlags Flags; /*!< EVR comparison flags. */
+ const char * F[5]; /*!< Parsed fields (\1=E, \2=V, \3=R, \4=D). */
+#define RPMEVR_E 1
+#define RPMEVR_V 2
+#define RPMEVR_R 3
+#define RPMEVR_D 4
+} * EVR_t;
+
+static EVR_t rpmEVRnew(uint32_t Flags, int initialize) {
+ EVR_t evr = calloc(1, sizeof(*evr));
+ evr->Flags = Flags;
+ if (initialize) {
+ evr->F[RPMEVR_E] = "0";
+ evr->F[RPMEVR_V] = "";
+ evr->F[RPMEVR_R] = "";
+ evr->F[RPMEVR_D] = "";
+ }
+ return evr;
+}
+
+static EVR_t rpmEVRfree(EVR_t evr) {
+ if (evr != NULL) {
+ evr->str = _free(evr->str);
+ memset(evr, 0, sizeof(*evr));
+ evr = _free(evr);
+ }
+ return NULL;
+}
+
+static struct regexp_s {
+ int initialized;
+ regex_t regexp;
+} re = { .initialized = 0 };
+
+static const char evr_tuple_match[] = "^(?:([^:-]+):)?([^:-]+)(?:-([^:-]+))?(?::([^:-]+))?$";
+
+static int rpmEVRparse(const char * evrstr, EVR_t evr) {
+ int noffsets = 6 * 3;
+ int offsets[6 * 3];
+ size_t nb;
+ int xx;
+ int i;
+
+ if(re.initialized == 0)
+ xx = pcreposix_regcomp(&(re.regexp), evr_tuple_match, REG_EXTENDED | REG_NEWLINE),
+ re.initialized = 1;
+
+ memset(evr, 0, sizeof(*evr));
+ evr->str = strdup(evrstr);
+ nb = strlen(evr->str);
+
+ memset(offsets, -1, sizeof(offsets));
+
+ xx = pcreposix_regexec(&(re.regexp), evr->str,
+ noffsets/3, (regmatch_t *)offsets, 0);
+
+ for (i = 0; i < noffsets; i += 2) {
+ int ix;
+
+ if (offsets[i] < 0)
+ continue;
+
+ switch (i/2) {
+ default:
+ case 0: continue; break;
+ case 1: ix = RPMEVR_E; break;
+ case 2: ix = RPMEVR_V; break;
+ case 3: ix = RPMEVR_R; break;
+ case 4: ix = RPMEVR_D; break;
+ }
+
+assert(offsets[i ] >= 0 && offsets[i ] <= (int)nb);
+assert(offsets[i+1] >= 0 && offsets[i+1] <= (int)nb);
+ { char * te = (char *) evr->str;
+ evr->F[ix] = te + offsets[i];
+ te += offsets[i+1];
+ *te = '\0';
+ }
+
+ }
+
+ if (evr->F[RPMEVR_E] == NULL) evr->F[RPMEVR_E] = "0";
+
+ evr->Elong = strtoul(evr->F[RPMEVR_E], NULL, 10);
+
+ return 0;
+}
+
+static int rpmEVRcompare(const EVR_t a, const EVR_t b) {
+ const char * s;
+ int rc = 0;
+
+ for (s = "EVRD"; *s != '\0'; s++) {
+ int ix;
+ switch ((int)*s) {
+ default: continue; break;
+ case 'E': ix = RPMEVR_E; break;
+ case 'V': ix = RPMEVR_V; break;
+ case 'R': ix = RPMEVR_R; break;
+ case 'D': ix = RPMEVR_D; break;
+ }
+ rc = rpmvercmp(a->F[ix] ? a->F[ix] : "", b->F[ix] ? b->F[ix] : "");
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
#else
#include <rpm/rpm46compat.h>
#endif
@@ -296,10 +412,6 @@ get_nvra(Header h) {
static int
do_rpmEVRcmp(const char *a, const char *b) {
int compare;
-#ifdef RPM_ORG
- /* TODO: implement EVR_t & friends locally? */
- compare = rpmvercmp(a, b);
-#else
EVR_t lEVR,
rEVR;
lEVR = rpmEVRnew(RPMSENSE_EQUAL, 0),
@@ -309,7 +421,6 @@ do_rpmEVRcmp(const char *a, const char *b) {
compare = rpmEVRcompare(lEVR, rEVR);
lEVR = rpmEVRfree(lEVR),
rEVR = rpmEVRfree(rEVR);
-#endif
return compare;
}