aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--URPM.xs402
-rw-r--r--URPM/Build.pm1
-rw-r--r--URPM/Resolve.pm54
-rw-r--r--perl-URPM.spec10
4 files changed, 319 insertions, 148 deletions
diff --git a/URPM.xs b/URPM.xs
index f928db6..0ad6fec 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -416,61 +416,199 @@ print_list_entry(char *buff, int sz, char *name, int_32 flags, char *evr) {
}
static int
-return_list_str(char *s, Header header, int_32 tag_name, int_32 tag_flags, int_32 tag_version, char *buf, int buflen) {
- int count = 0;
+ranges_overlap(int_32 aflags, char *sa, int_32 bflags, char *sb, int b_nopromote) {
+ if (!aflags || !bflags)
+ return 1; /* really faster to test it there instead of later */
+ else {
+ int sense = 0;
+ char *eosa = strchr(sa, ']');
+ char *eosb = strchr(sb, ']');
+ char *ea, *va, *ra, *eb, *vb, *rb;
+
+ if (eosa) *eosa = 0;
+ if (eosb) *eosb = 0;
+ /* parse sa as an [epoch:]version[-release] */
+ for (ea = sa; *sa >= '0' && *sa <= '9'; ++sa);
+ if (*sa == ':') {
+ *sa++ = 0; /* ea could be an empty string (should be interpreted as 0) */
+ va = sa;
+ } else {
+ va = ea; /* no epoch */
+ ea = NULL;
+ }
+ if ((ra = strrchr(sa, '-'))) *ra++ = 0;
+ /* parse sb as an [epoch:]version[-release] */
+ for (eb = sb; *sb >= '0' && *sb <= '9'; ++sb);
+ if (*sb == ':') {
+ *sb++ = 0; /* ea could be an empty string (should be interpreted as 0) */
+ vb = sb;
+ } else {
+ vb = eb; /* no epoch */
+ eb = NULL;
+ }
+ if ((rb = strrchr(sb, '-'))) *rb++ = 0;
+ /* now compare epoch */
+ if (ea && eb)
+ sense = rpmvercmp(*ea ? ea : "0", *eb ? eb : "0");
+#ifdef RPM_42
+ else if (ea && *ea && atol(ea) > 0)
+ sense = b_nopromote ? 1 : 0;
+#endif
+ else if (eb && *eb && atol(eb) > 0)
+ sense = -1;
+ /* now compare version and release if epoch has not been enough */
+ if (sense == 0) {
+ sense = rpmvercmp(va, vb);
+ if (sense == 0 && ra && *ra && rb && *rb)
+ sense = rpmvercmp(ra, rb);
+ }
+ /* restore all character that have been modified inline */
+ if (rb) rb[-1] = '-';
+ if (ra) ra[-1] = '-';
+ if (eb) vb[-1] = ':';
+ if (ea) va[-1] = ':';
+ if (eosb) *eosb = ']';
+ if (eosa) *eosa = ']';
+ /* finish the overlap computation */
+ if (sense < 0 && ((aflags & RPMSENSE_GREATER) || (bflags & RPMSENSE_LESS)))
+ return 1;
+ else if (sense > 0 && ((aflags & RPMSENSE_LESS) || (bflags & RPMSENSE_GREATER)))
+ return 1;
+ else if (sense == 0 && (((aflags & RPMSENSE_EQUAL) && (bflags & RPMSENSE_EQUAL)) ||
+ ((aflags & RPMSENSE_LESS) && (bflags & RPMSENSE_LESS)) ||
+ ((aflags & RPMSENSE_GREATER) && (bflags & RPMSENSE_GREATER))))
+ return 1;
+ else
+ return 0;
+ }
+}
+
+typedef int (*callback_list_str)(char *s, int slen, char *name, int_32 flags, char *evr, void *param);
+
+static int
+callback_list_str_xpush(char *s, int slen, char *name, int_32 flags, char *evr, void *param) {
dSP;
+ if (s) {
+ XPUSHs(sv_2mortal(newSVpv(s, slen)));
+ } else {
+ char buff[4096];
+ int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr);
+ if (len > 0)
+ XPUSHs(sv_2mortal(newSVpv(buff, len)));
+ }
+ PUTBACK;
+ /* returning zero indicate to continue processing */
+ return 0;
+}
+
+struct cb_overlap_s {
+ char *name;
+ int_32 flags;
+ char *evr;
+ int direction; /* indicate to compare the above at left or right to the iteration element */
+ int b_nopromote;
+};
+
+static int
+callback_list_str_overlap(char *s, int slen, char *name, int_32 flags, char *evr, void *param) {
+ struct cb_overlap_s *os = (struct cb_overlap_s *)param;
+ int result = 0;
+ char *eos = NULL;
+ char *eon = NULL;
+ char eosc;
+ char eonc;
+
+ /* we need to extract name, flags and evr from a full sense information, store result in local copy */
+ if (s) {
+ if (slen) { eos = s + slen; eosc = *eos; *eos = 0; }
+ name = s;
+ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s;
+ if (*s) {
+ eon = s;
+ while (*s) {
+ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']');
+ else if (*s == '<') flags |= RPMSENSE_LESS;
+ else if (*s == '>') flags |= RPMSENSE_GREATER;
+ else if (*s == '=') flags |= RPMSENSE_EQUAL;
+ else break;
+ ++s;
+ }
+ evr = s;
+ } else
+ evr = "";
+ }
+
+ /* mark end of name */
+ if (eon) { eonc = *eon; *eon = 0; }
+ /* name should be equal, else it will not overlap */
+ if (!strcmp(name, os->name)) {
+ /* perform overlap according to direction needed, negative for left */
+ if (os->direction < 0)
+ result = ranges_overlap(os->flags, os->evr, flags, evr, os->b_nopromote);
+ else
+ result = ranges_overlap(flags, evr, os->flags, os->evr, os->b_nopromote);
+ }
+
+ /* fprintf(stderr, "cb_list_str_overlap result=%d, os->direction=%d, os->name=%s, os->evr=%s, name=%s, evr=%s\n",
+ result, os->direction, os->name, os->evr, name, evr); */
+
+ /* restore s if needed */
+ if (eon) *eon = eonc;
+ if (eos) *eos = eosc;
+
+ return result;
+}
+
+static int
+return_list_str(char *s, Header header, int_32 tag_name, int_32 tag_flags, int_32 tag_version, callback_list_str f, void *param) {
+ int count = 0;
if (s != NULL) {
char *ps = strchr(s, '@');
if (tag_flags && tag_version) {
while(ps != NULL) {
- if (buf != NULL) {
- buflen -= ps-s+1; if (buflen > 0) { memcpy(buf, s, ps-s); buf += ps-s; *buf++ = 0; ++count; }
- } else XPUSHs(sv_2mortal(newSVpv(s, ps-s)));
+ ++count;
+ if (f(s, ps-s, NULL, 0, NULL, param)) return -count;
s = ps + 1; ps = strchr(s, '@');
}
- if (buf != NULL) strcpy(buf, s);
- else XPUSHs(sv_2mortal(newSVpv(s, 0)));
+ ++count;
+ if (f(s, 0, NULL, 0, NULL, param)) return -count;
} else {
char *eos;
while(ps != NULL) {
*ps = 0; eos = strchr(s, '['); if (!eos) eos = strchr(s, ' ');
- if (buf != NULL) {
- int l = eos ? eos-s : ps-s; buflen -= l; if (buflen > 0) { memcpy(buf, s, l); buf += l; *buf++ = 0; ++count; }
- } else XPUSHs(sv_2mortal(newSVpv(s, eos ? eos-s : ps-s)));
+ ++count;
+ if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { *ps = '@'; return -count; }
*ps = '@'; /* restore in memory modified char */
s = ps + 1; ps = strchr(s, '@');
}
eos = strchr(s, '['); if (!eos) eos = strchr(s, ' ');
- if (buf != NULL) {
- int l = eos ? eos-s : strlen(s); buflen -= l; if (buflen > 0) { memcpy(buf, s, l); buf += l; *buf++ = 0; ++count; }
- } else XPUSHs(sv_2mortal(newSVpv(s, eos ? eos-s : 0)));
+ ++count;
+ if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) return -count;
}
} else if (header) {
- char buff[4096];
- int_32 type, count;
+ int_32 type, c;
char **list = NULL;
int_32 *flags = NULL;
char **list_evr = NULL;
int i;
- headerGetEntry(header, tag_name, &type, (void **) &list, &count);
+ headerGetEntry(header, tag_name, &type, (void **) &list, &c);
if (list) {
- if (tag_flags) headerGetEntry(header, tag_flags, &type, (void **) &flags, &count);
- if (tag_version) headerGetEntry(header, tag_version, &type, (void **) &list_evr, &count);
- for(i = 0; i < count; i++) {
- int len = print_list_entry(buff, sizeof(buff)-1, list[i], flags ? flags[i] : 0, list_evr ? list_evr[i] : NULL);
- if (len < 0) continue;
- if (buf != NULL) {
- buflen -= len; if (buflen > 0) { memcpy(buf, buff, len); buf += len; *buf++ = 0; ++count; }
- } else XPUSHs(sv_2mortal(newSVpv(buff, len)));
+ if (tag_flags) headerGetEntry(header, tag_flags, &type, (void **) &flags, &c);
+ if (tag_version) headerGetEntry(header, tag_version, &type, (void **) &list_evr, &c);
+ for(i = 0; i < c; i++) {
+ ++count;
+ if (f(NULL, 0, list[i], flags ? flags[i] : 0, list_evr ? list_evr[i] : NULL, param)) {
+ free(list);
+ free(list_evr);
+ return -count;
+ }
}
-
free(list);
free(list_evr);
}
}
- if (buf == NULL) PUTBACK;
return count;
}
@@ -1716,7 +1854,8 @@ Pkg_requires(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, NULL, 0);
+ return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION,
+ callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1724,7 +1863,7 @@ Pkg_requires_nosense(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, 0, 0, NULL, 0);
+ return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1732,7 +1871,8 @@ Pkg_obsoletes(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, NULL, 0);
+ return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION,
+ callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1740,15 +1880,55 @@ Pkg_obsoletes_nosense(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, 0, 0, NULL, 0);
+ return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
+int
+Pkg_obsoletes_overlap(pkg, s, b_nopromote=0, direction=-1)
+ URPM::Package pkg
+ char *s
+ int b_nopromote
+ int direction
+ PREINIT:
+ struct cb_overlap_s os;
+ char *eon = NULL;
+ char eonc;
+ CODE:
+ os.name = s;
+ os.flags = 0;
+ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s;
+ if (*s) {
+ eon = s;
+ while (*s) {
+ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']');
+ else if (*s == '<') os.flags |= RPMSENSE_LESS;
+ else if (*s == '>') os.flags |= RPMSENSE_GREATER;
+ else if (*s == '=') os.flags |= RPMSENSE_EQUAL;
+ else break;
+ ++s;
+ }
+ os.evr = s;
+ } else
+ os.evr = "";
+ os.direction = direction;
+ os.b_nopromote = b_nopromote;
+ /* mark end of name */
+ if (eon) { eonc = *eon; *eon = 0; }
+ /* return_list_str returns a negative value is the callback has returned non-zero */
+ RETVAL = return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION,
+ callback_list_str_overlap, &os) < 0;
+ /* restore end of name */
+ if (eon) *eon = eonc;
+ OUTPUT:
+ RETVAL
+
void
Pkg_conflicts(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION, NULL, 0);
+ return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION,
+ callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1756,7 +1936,7 @@ Pkg_conflicts_nosense(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, 0, 0, NULL, 0);
+ return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1764,7 +1944,8 @@ Pkg_provides(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, NULL, 0);
+ return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION,
+ callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1772,15 +1953,54 @@ Pkg_provides_nosense(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, 0, 0, NULL, 0);
+ return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
+int
+Pkg_provides_overlap(pkg, s, b_nopromote=0, direction=1)
+ URPM::Package pkg
+ char *s
+ int b_nopromote
+ int direction
+ PREINIT:
+ struct cb_overlap_s os;
+ char *eon = NULL;
+ char eonc;
+ CODE:
+ os.name = s;
+ os.flags = 0;
+ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s;
+ if (*s) {
+ eon = s;
+ while (*s) {
+ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']');
+ else if (*s == '<') os.flags |= RPMSENSE_LESS;
+ else if (*s == '>') os.flags |= RPMSENSE_GREATER;
+ else if (*s == '=') os.flags |= RPMSENSE_EQUAL;
+ else break;
+ ++s;
+ }
+ os.evr = s;
+ } else
+ os.evr = "";
+ os.direction = direction;
+ os.b_nopromote = b_nopromote;
+ /* mark end of name */
+ if (eon) { eonc = *eon; *eon = 0; }
+ /* return_list_str returns a negative value is the callback has returned non-zero */
+ RETVAL = return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION,
+ callback_list_str_overlap, &os) < 0;
+ /* restore end of name */
+ if (eon) *eon = eonc;
+ OUTPUT:
+ RETVAL
+
void
Pkg_buildarchs(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_BUILDARCHS, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_BUILDARCHS, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1788,7 +2008,7 @@ Pkg_excludearchs(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_EXCLUDEARCH, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_EXCLUDEARCH, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1796,7 +2016,7 @@ Pkg_exclusivearchs(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_EXCLUSIVEARCH, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_EXCLUSIVEARCH, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1812,7 +2032,7 @@ Pkg_files_md5sum(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_FILEMD5S, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_FILEMD5S, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1820,7 +2040,7 @@ Pkg_files_owner(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_FILEUSERNAME, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_FILEUSERNAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1828,7 +2048,7 @@ Pkg_files_group(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_FILEGROUPNAME, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_FILEGROUPNAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1900,7 +2120,7 @@ Pkg_changelog_name(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_CHANGELOGNAME, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_CHANGELOGNAME, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1908,7 +2128,7 @@ Pkg_changelog_text(pkg)
URPM::Package pkg
PPCODE:
PUTBACK;
- return_list_str(NULL, pkg->h, RPMTAG_CHANGELOGTEXT, 0, 0, NULL, 0);
+ return_list_str(NULL, pkg->h, RPMTAG_CHANGELOGTEXT, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -2802,69 +3022,7 @@ Urpm_ranges_overlap(a, b, b_nopromote=0)
else break;
++sb;
}
- if (!aflags || !bflags)
- RETVAL = 1; /* really faster to test it there instead of later */
- else {
- int sense = 0;
- char *eosa = strchr(sa, ']');
- char *eosb = strchr(sb, ']');
- char *ea, *va, *ra, *eb, *vb, *rb;
-
- if (eosa) *eosa = 0;
- if (eosb) *eosb = 0;
- /* parse sa as an [epoch:]version[-release] */
- for (ea = sa; *sa >= '0' && *sa <= '9'; ++sa);
- if (*sa == ':') {
- *sa++ = 0; /* ea could be an empty string (should be interpreted as 0) */
- va = sa;
- } else {
- va = ea; /* no epoch */
- ea = NULL;
- }
- if ((ra = strrchr(sa, '-'))) *ra++ = 0;
- /* parse sb as an [epoch:]version[-release] */
- for (eb = sb; *sb >= '0' && *sb <= '9'; ++sb);
- if (*sb == ':') {
- *sb++ = 0; /* ea could be an empty string (should be interpreted as 0) */
- vb = sb;
- } else {
- vb = eb; /* no epoch */
- eb = NULL;
- }
- if ((rb = strrchr(sb, '-'))) *rb++ = 0;
- /* now compare epoch */
- if (ea && eb)
- sense = rpmvercmp(*ea ? ea : "0", *eb ? eb : "0");
-#ifdef RPM_42
- else if (ea && *ea && atol(ea) > 0)
- sense = b_nopromote ? 1 : 0;
-#endif
- else if (eb && *eb && atol(eb) > 0)
- sense = -1;
- /* now compare version and release if epoch has not been enough */
- if (sense == 0) {
- sense = rpmvercmp(va, vb);
- if (sense == 0 && ra && *ra && rb && *rb)
- sense = rpmvercmp(ra, rb);
- }
- /* restore all character that have been modified inline */
- if (rb) rb[-1] = '-';
- if (ra) ra[-1] = '-';
- if (eb) vb[-1] = ':';
- if (ea) va[-1] = '-';
- if (eosb) *eosb = ']';
- if (eosa) *eosa = ']';
- /* finish the overlap computation */
- RETVAL = 0;
- if (sense < 0 && ((aflags & RPMSENSE_GREATER) || (bflags & RPMSENSE_LESS)))
- RETVAL = 1;
- else if (sense > 0 && ((aflags & RPMSENSE_LESS) || (bflags & RPMSENSE_GREATER)))
- RETVAL = 1;
- else if (sense == 0 && (((aflags & RPMSENSE_EQUAL) && (bflags & RPMSENSE_EQUAL)) ||
- ((aflags & RPMSENSE_LESS) && (bflags & RPMSENSE_LESS)) ||
- ((aflags & RPMSENSE_GREATER) && (bflags & RPMSENSE_GREATER))))
- RETVAL = 1;
- }
+ RETVAL = ranges_overlap(aflags, sa, bflags, sb, b_nopromote);
}
OUTPUT:
RETVAL
@@ -2878,10 +3036,34 @@ Urpm_unsatisfied_requires2(urpm, db, state, pkg, ...)
PREINIT:
char *option_name = NULL;
int option_nopromoteepoch = 0;
+ HV *cached_installed = NULL;
+ HV *rejected = NULL;
+ HV *selected = NULL;
PPCODE:
+ if (SvROK(state) && SvTYPE(SvRV(state)) == SVt_PVHV) {
+ SV **fcached_installed = hv_fetch((HV*)SvRV(state), "cached_installed", 16, 1);
+ SV **frejected = hv_fetch((HV*)SvRV(state), "rejected", 8, 0);
+ SV **fselected = hv_fetch((HV*)SvRV(state), "selected", 8, 0);
+
+ if (fcached_installed) {
+ if (!SvROK(*fcached_installed) || SvTYPE(SvRV(*fcached_installed)) != SVt_PVHV) {
+ SvREFCNT_dec(*fcached_installed);
+ *fcached_installed = newRV_noinc((SV*)newHV());
+ }
+ if (SvROK(*fcached_installed) && SvTYPE(SvRV(*fcached_installed)) == SVt_PVHV)
+ cached_installed = (HV*)SvRV(*fcached_installed);
+ }
+ if (frejected && SvROK(*frejected) && SvTYPE(SvRV(*frejected)) == SVt_PVHV)
+ rejected = (HV*)SvRV(*frejected);
+ if (fselected && SvROK(*fselected) && SvTYPE(SvRV(*fselected)) == SVt_PVHV)
+ selected = (HV*)SvRV(*fselected);
+ } else croak("state should be a reference to HASH");
if (SvROK(urpm) && SvTYPE(SvRV(urpm)) == SVt_PVHV) {
SV **fprovides = hv_fetch((HV*)SvRV(urpm), "provides", 8, 0);
HV *provides = fprovides && SvROK(*fprovides) && SvTYPE(SvRV(*fprovides)) == SVt_PVHV ? (HV*)SvRV(*fprovides) : NULL;
+ SV **fdepslist = hv_fetch((HV*)SvRV(urpm), "depslist", 8, 0);
+ AV *depslist = fdepslist && SvROK(*fdepslist) && SvTYPE(SvRV(*fdepslist)) == SVt_PVAV ? (AV*)SvRV(*fdepslist) : NULL;
+ SV **f;
/* get options */
if (items > 4) {
@@ -2902,7 +3084,7 @@ Urpm_unsatisfied_requires2(urpm, db, state, pkg, ...)
/* we have to iterate over requires of pkg */
char b[65536];
char *p = b;
- int n = return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, b, sizeof(b));
+ int n = return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, NULL, NULL);
while (n--) {
char *n = p, *s, *eos;
@@ -2914,10 +3096,14 @@ Urpm_unsatisfied_requires2(urpm, db, state, pkg, ...)
/* if option name is given, it should match the name found in requires on go to next requires */
if (option_name != NULL && strcmp(n, option_name)) { p = eos + 1; continue; }
-
+ /* check for installed packages in the cache */
+ if ((f = hv_fetch(cached_installed, n, strlen(n), 0))) {
+ /* f is a reference to an hash containing the name of packages as keys */
+
+ }
}
}
- } else croak("first argument should be a reference to HASH");
+ } else croak("urpm should be a reference to HASH");
void
Urpm_parse_synthesis(urpm, filename, ...)
diff --git a/URPM/Build.pm b/URPM/Build.pm
index 8dcb893..d0daaa7 100644
--- a/URPM/Build.pm
+++ b/URPM/Build.pm
@@ -244,6 +244,7 @@ sub compute_deps {
#- set new id.
$pkg->set_id($remap_ids{$_});
+ print STDERR "setting id of ".$pkg->name.":$remap_ids{$_}\n";
my ($id, $base, %requires_id, %not_founds);
foreach (split ' ', $urpm->{requires}[$_]) {
diff --git a/URPM/Resolve.pm b/URPM/Resolve.pm
index 9987dc5..3eba9f9 100644
--- a/URPM/Resolve.pm
+++ b/URPM/Resolve.pm
@@ -22,13 +22,8 @@ sub find_candidate_packages {
$pkg->is_arch_compat or next;
$options{avoided} && exists $options{avoided}{$pkg->fullname} and next;
#- check if at least one provide of the package overlap the property.
- my $satisfied = !$urpm->{provides}{$name}{$_};
- unless ($satisfied) {
- foreach ($pkg->provides) {
- ranges_overlap($_, $property, $options{nopromoteepoch}) and ++$satisfied, last;
- }
- }
- $satisfied and push @{$packages{$pkg->name}}, $pkg;
+ !$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property, $options{nopromoteepoch}) and
+ push @{$packages{$pkg->name}}, $pkg;
}
}
}
@@ -59,13 +54,7 @@ sub find_chosen_packages {
$pkg->flag_skip || exists $state->{rejected}{$pkg->fullname} and next;
$pkg->is_arch_compat or next;
#- check if at least one provide of the package overlap the property (if sense are needed).
- my $satisfied = !$urpm->{provides}{$name}{$_};
- unless ($satisfied) {
- foreach ($pkg->provides) {
- ranges_overlap($_, $property) and ++$satisfied, last;
- }
- }
- if ($satisfied) {
+ if (!$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property)) {
#- determine if this packages is better than a possibly previously chosen package.
$pkg->flag_selected || exists $state->{selected}{$pkg->id} and return $pkg;
if (my $p = $packages{$pkg->name}) {
@@ -161,20 +150,11 @@ sub unsatisfied_requires {
foreach (keys %{$urpm->{provides}{$n} || {}}) {
my $p = $urpm->{depslist}[$_];
exists $state->{selected}{$_} or next;
- if ($urpm->{provides}{$n}{$_}) {
- #- sense information are used, this means we have to examine carrefully the provides.
- foreach ($p->provides) {
- ranges_overlap($_, $dep, $options{nopromoteepoch}) and next REQUIRES;
- }
- } else {
- next REQUIRES;
- }
+ !$urpm->{provides}{$n}{$_} || $p->provides_overlap($dep, $options{nopromoteepoch}) and next REQUIRES;
}
#- check if the package itself provides what is necessary.
- foreach ($pkg->provides) {
- ranges_overlap($_, $dep) and next REQUIRES;
- }
+ $pkg->provides_overlap($dep) and next REQUIRES;
#- check on installed system a package which is not obsoleted is satisfying the require.
my $satisfied = 0;
@@ -611,14 +591,14 @@ sub resolve_requested {
} elsif (my ($property, $name) = /^(([^\s\[]*).*)/) {
$db->traverse_tag('whatprovides', [ $name ], sub {
my ($p) = @_;
- if (grep { ranges_overlap($_, $property) } $p->provides) {
+ if ($p->provides_overlap($property)) {
#- the existing package will conflicts with selection, check if a newer
#- version will be ok, else ask to remove the old.
my $need_deps = $p->name . " > " . ($p->epoch ? $p->epoch.":" : "") .
$p->version . "-" . $p->release;
my $packages = $urpm->find_candidate_packages($need_deps, avoided => $state->{rejected});
my $best = join '|', map { $_->id }
- grep { ! grep { ranges_overlap($_, $property) } $_->provides }
+ grep { ! $_->provides_overlap($property) }
@{$packages->{$p->name}};
if (length $best) {
@@ -638,7 +618,7 @@ sub resolve_requested {
$db->traverse_tag('whatconflicts', [ $pkg->name ], sub {
my ($p) = @_;
foreach my $property ($p->conflicts) {
- if (grep { ranges_overlap($_, $property) } $pkg->provides) {
+ if ($pkg->provides_overlap($property)) {
#- all these packages should be removed.
$urpm->resolve_rejected($db, $state, $p,
removed => 1, unsatisfied => \@properties,
@@ -824,9 +804,7 @@ sub compute_flags {
my $satisfied = exists($sense->{''}) || !$urpm->{provides}{$name}{$_};
unless ($satisfied) {
foreach my $s (keys %$sense) {
- foreach ($pkg->provides) {
- ranges_overlap($_, $name.$s) and ++$satisfied, last;
- }
+ $pkg->provides_overlap($name.$s) and ++$satisfied, last;
}
}
if ($satisfied) {
@@ -945,17 +923,15 @@ sub request_packages_to_upgrade {
foreach my $property ($p->provides) {
#- only real provides should be taken into account, this means internal obsoletes
#- should be avoided.
- unless (grep { ranges_overlap($property, $_) } $p->obsoletes) {
+ unless ($p->obsoletes_overlap($property)) {
if (my ($n) = $property =~ /^([^\s\[]*)/) {
foreach my $pkg (@{$obsoletes{$n} || []}) {
next if $pkg->name eq $p->name || $p->name ne $n || !$names{$pkg->name};
- foreach ($pkg->obsoletes) {
- if (ranges_overlap($property, $_)) {
- #- the package being examined can be obsoleted.
- #- do not set installed and provides flags.
- push @obsoleters, $pkg;
- return;
- }
+ if ($pkg->obsoletes_overlap($property)) {
+ #- the package being examined can be obsoleted.
+ #- do not set installed and provides flags.
+ push @obsoleters, $pkg;
+ return;
}
}
}
diff --git a/perl-URPM.spec b/perl-URPM.spec
index 6323492..d887743 100644
--- a/perl-URPM.spec
+++ b/perl-URPM.spec
@@ -1,7 +1,7 @@
%define name perl-URPM
%define real_name URPM
%define version 0.91
-%define release 12mdk
+%define release 13mdk
%{expand:%%define rpm_version %(rpm -q --queryformat '%{VERSION}-%{RELEASE}' rpm)}
@@ -51,6 +51,14 @@ rm -rf $RPM_BUILD_ROOT
%changelog
+* Thu Jul 24 2003 François Pons <fpons@mandrakesoft.com> 0.91-13mdk
+- modified internal handling of string list to allow complex
+ combined method in pure C in order to increase speed.
+- added provides_overlap and obsoletes_overlap in XS to implement
+ a scalar grep of ranges_overlap on provides or obsoletes.
+- fixed a small typo in constant character in ranges_overlap which
+ may have caused some strange result.
+
* Wed Jul 16 2003 François Pons <fpons@mandrakesoft.com> 0.91-12mdk
- fixed typo in regex handling in URPM::compute_flags.
- fixed cache contents not taken into account.