Note that this patch is almost, but not quite, perfect.

The issue is how missing elements in the {E,V,R,D} tuple
should be represented. ATM either NULL or "" (with missing
Epoch: being mapped to "0" special cased) are all handled.

But I'd really like to commit to one, not all, of the above
representations of missing values.

This is the symptom message that you may see, from the
blue-printing of new <-> old EVR parsers:

[...@wellfleet wdj]$ rpm -q --whatneeds popt
==> "" 2 strcmp(,(null))
==> "" 2 strcmp(,(null))
OpenIPMI-2.0.14-5.fc10.i386
anaconda-11.4.1.58-1.i386
chkconfig-1.3.38-1.i386
chkfontpath-1.10.1-2.fc8.i386
control-center-2.25.1-5.fc11.i386

There's aanother place in python labelCompare() that
the issue will arise, trickier because the script kiddie's
will claim that something has broken because changed @rpm5.org, sigh.

73 de Jeff

On Jan 4, 2009, at 7:34 PM, Jeff Johnson wrote:

 RPM Package Manager, CVS Repository
 http://rpm5.org/cvs/
____________________________________________________________________________

 Server: rpm5.org                         Name:   Jeff Johnson
 Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
 Module: rpm                              Date:   05-Jan-2009 01:34:44
 Branch: HEAD                             Handle: 2009010500344300

 Modified files:
   rpm                     CHANGES
   rpm/rpmdb               hdrfmt.c librpmdb.vers rpmevr.c rpmevr.h

 Log:
   - EVRtuple: teach --whatneeds/--needswhat to use EVR_t opaquely.
   - EVRtuple: add rpmEVR{new,free} creator and destructors.

 Summary:
   Revision    Changes     Path
   1.2726      +2  -0      rpm/CHANGES
   1.127       +35 -57     rpm/rpmdb/hdrfmt.c
   1.54        +3  -0      rpm/rpmdb/librpmdb.vers
   1.27        +46 -0      rpm/rpmdb/rpmevr.c
   1.9         +29 -3      rpm/rpmdb/rpmevr.h
____________________________________________________________________________

 patch -p0 <<'@@ .'
 Index: rpm/CHANGES
= = = = = = ======================================================================
 $ cvs diff -u -r1.2725 -r1.2726 CHANGES
 --- rpm/CHANGES        3 Jan 2009 20:58:09 -0000       1.2725
 +++ rpm/CHANGES        5 Jan 2009 00:34:43 -0000       1.2726
 @@ -1,5 +1,7 @@

  5.2a2 -> 5.2a3:
+ - jbj: EVRtuple: teach --whatneeds/--needswhat to use EVR_t opaquely.
 +    - jbj: EVRtuple: add rpmEVR{new,free} creator and destructors.
      - jbj: EVRtuple: mark the old EVRD parser for destruction.
- jbj: EVRtuple: use the new EVRD pattern parser, reverse the assert check.
      - jbj: EVRtuple: precedence permutation for rpmdsCompare().
 @@ .
 patch -p0 <<'@@ .'
 Index: rpm/rpmdb/hdrfmt.c
= = = = = = ======================================================================
 $ cvs diff -u -r1.126 -r1.127 hdrfmt.c
 --- rpm/rpmdb/hdrfmt.c 1 Jan 2009 18:43:05 -0000       1.126
 +++ rpm/rpmdb/hdrfmt.c 5 Jan 2009 00:34:43 -0000       1.127
 @@ -2652,39 +2652,6 @@
      return rc;
  }

 -static int rpmEVRoverlap(EVR_t a, EVR_t b)
 -      /*...@modifies a, b @*/
 -{
 -    rpmsenseFlags aF = a->Flags;
 -    rpmsenseFlags bF = b->Flags;
 -    int sense;
 -    int result;
 -
 -    if (a->F[RPMEVR_E] == NULL)    a->F[RPMEVR_E] = "0";
 -    if (b->F[RPMEVR_E] == NULL)    b->F[RPMEVR_E] = "0";
 -    if (a->F[RPMEVR_V] == NULL)    a->F[RPMEVR_V] = "";
 -    if (b->F[RPMEVR_V] == NULL)    b->F[RPMEVR_V] = "";
 -    if (a->F[RPMEVR_R] == NULL)    a->F[RPMEVR_R] = "";
 -    if (b->F[RPMEVR_R] == NULL)    b->F[RPMEVR_R] = "";
 -    sense = rpmEVRcompare(a, b);
 -
 -    /* Detect overlap of {A,B} range. */
 -    if (aF == RPMSENSE_NOTEQUAL || bF == RPMSENSE_NOTEQUAL)
 -        result = (sense != 0);
- else if (sense < 0 && ((aF & RPMSENSE_GREATER) || (bF & RPMSENSE_LESS)))
 -        result = 1;
- else if (sense > 0 && ((aF & RPMSENSE_LESS) || (bF & RPMSENSE_GREATER)))
 -        result = 1;
 -    else if (sense == 0 &&
 -        (((aF & RPMSENSE_EQUAL) && (bF & RPMSENSE_EQUAL)) ||
 -         ((aF & RPMSENSE_LESS) && (bF & RPMSENSE_LESS)) ||
 -         ((aF & RPMSENSE_GREATER) && (bF & RPMSENSE_GREATER))))
 -        result = 1;
 -    else
 -        result = 0;
 -    return result;
 -}
 -
static int wnlookupTag(Header h, rpmTag tagNVRA, ARGV_t *avp, ARGI_t *hitp,
                HE_t PNhe, /*...@null@*/ HE_t PEVRhe, /*...@null@*/ HE_t PFhe)
        /*...@globals rpmGlobalMacroContext, h_errno,
 @@ -2703,18 +2670,21 @@
      rpmTag tagN = RPMTAG_REQUIRENAME;
      rpmTag tagEVR = RPMTAG_REQUIREVERSION;
      rpmTag tagF = RPMTAG_REQUIREFLAGS;
 -    EVR_t Pevr = memset(alloca(sizeof(*Pevr)), 0, sizeof(*Pevr));
 -    EVR_t Revr = memset(alloca(sizeof(*Revr)), 0, sizeof(*Revr));
 +    rpmuint32_t PFlags;
 +    rpmuint32_t RFlags;
 +    EVR_t Pevr;
      Header oh;
      int rc = 0;
      int xx;

      if (tagNVRA == 0)
        tagNVRA = RPMTAG_NVRA;
 +
+ PFlags = (PFhe != NULL ? (PFhe->p.ui32p[PNhe->ix] & RPMSENSE_SENSEMASK) : 0);
 +    Pevr = rpmEVRnew(PFlags, 1);
 +
      if (PEVRhe != NULL)
        xx = rpmEVRparse(xstrdup(PEVRhe->p.argv[PNhe->ix]), Pevr);
 -    if (PFhe != NULL)
 -      Pevr->Flags = (PFhe->p.ui32p[PNhe->ix] & RPMSENSE_SENSEMASK);

      RNhe->tag = tagN;
      REVRhe->tag = tagEVR;
 @@ -2740,13 +2710,16 @@
                /*...@innercontinue@*/ continue;
            if (PEVRhe == NULL)
                goto bingo;
 -          Revr->Flags = RFhe->p.ui32p[RNhe->ix] & RPMSENSE_SENSEMASK;
 -          if (!(Pevr->Flags && Revr->Flags))
 -              goto bingo;
 -          xx = rpmEVRparse(REVRhe->p.argv[RNhe->ix], Revr);
 -          xx = rpmEVRoverlap(Pevr, Revr);
 -          Revr->str = _free(Revr->str);
 -          memset(Revr, 0, sizeof(*Revr));
 +          RFlags = RFhe->p.ui32p[RNhe->ix] & RPMSENSE_SENSEMASK;
 +          {   EVR_t Revr = rpmEVRnew(RFlags, 1);
 +              if (!(PFlags && RFlags))
 +                  xx = 1;
 +              else {
 +                  xx = rpmEVRparse(REVRhe->p.argv[RNhe->ix], Revr);
 +                  xx = rpmEVRoverlap(Pevr, Revr);
 +              }
 +              Revr = rpmEVRfree(Revr);
 +          }
            if (xx)
                goto bingo;
        }
 @@ -2771,7 +2744,7 @@
      }
      mi = rpmdbFreeIterator(mi);

 -    Pevr->str = _free(Pevr->str);
 +    Pevr = rpmEVRfree(Pevr);

      return rc;
  }
 @@ -2874,8 +2847,9 @@
        ? RPMTAG_BASENAMES : RPMTAG_PROVIDENAME;
      rpmTag tagEVR = RPMTAG_PROVIDEVERSION;
      rpmTag tagF = RPMTAG_PROVIDEFLAGS;
 -    EVR_t Revr = memset(alloca(sizeof(*Revr)), 0, sizeof(*Revr));
 -    EVR_t Pevr = memset(alloca(sizeof(*Pevr)), 0, sizeof(*Pevr));
 +    rpmuint32_t PFlags;
 +    rpmuint32_t RFlags;
 +    EVR_t Revr;
      Header oh;
      int rc = 0;
      int xx;
 @@ -2883,10 +2857,11 @@
      if (tagNVRA == 0)
        tagNVRA = RPMTAG_NVRA;

+ RFlags = (RFhe != NULL ? (RFhe->p.ui32p[RNhe->ix] & RPMSENSE_SENSEMASK) : 0);
 +    Revr = rpmEVRnew(RFlags, 1);
 +
      if (REVRhe != NULL)
        xx = rpmEVRparse(REVRhe->p.argv[RNhe->ix], Revr);
 -    if (RFhe != NULL)
 -      Revr->Flags = (RFhe->p.ui32p[RNhe->ix] & RPMSENSE_SENSEMASK);

      PNhe->tag = tagN;
      PEVRhe->tag = tagEVR;
 @@ -2912,13 +2887,16 @@
                /*...@innercontinue@*/ continue;
            if (REVRhe == NULL)
                goto bingo;
 -          Pevr->Flags = PFhe->p.ui32p[PNhe->ix] & RPMSENSE_SENSEMASK;
 -          if (!(Revr->Flags && Pevr->Flags))
 -              goto bingo;
 -          xx = rpmEVRparse(PEVRhe->p.argv[PNhe->ix], Pevr);
 -          xx = rpmEVRoverlap(Revr, Pevr);
 -          Pevr->str = _free(Pevr->str);
 -          memset(Pevr, 0, sizeof(*Pevr));
 +          PFlags = PFhe->p.ui32p[PNhe->ix] & RPMSENSE_SENSEMASK;
 +          {   EVR_t Pevr = rpmEVRnew(PFlags, 1);
 +              if (!(PFlags && RFlags))
 +                  xx = 1;
 +              else {
 +                  xx = rpmEVRparse(PEVRhe->p.argv[PNhe->ix], Pevr);
 +                  xx = rpmEVRoverlap(Revr, Pevr);
 +              }
 +              Pevr = rpmEVRfree(Pevr);
 +          }
            if (xx)
                goto bingo;
        }
 @@ -2943,7 +2921,7 @@
      }
      mi = rpmdbFreeIterator(mi);

 -    Revr->str = _free(Revr->str);
 +    Revr = rpmEVRfree(Revr);

      return rc;
  }
 @@ .
 patch -p0 <<'@@ .'
 Index: rpm/rpmdb/librpmdb.vers
= = = = = = ======================================================================
 $ cvs diff -u -r1.53 -r1.54 librpmdb.vers
 --- rpm/rpmdb/librpmdb.vers    23 Sep 2008 21:40:51 -0000      1.53
 +++ rpm/rpmdb/librpmdb.vers    5 Jan 2009 00:34:43 -0000       1.54
 @@ -123,6 +123,9 @@
      rpmEVRcmp;
      rpmEVRcompare;
      rpmEVRflags;
 +    rpmEVRfree;
 +    rpmEVRnew;
 +    rpmEVRoverlap;
      rpmEVRparse;
      _rpmns_debug;
      _rpmns_N_at_A;
 @@ .
 patch -p0 <<'@@ .'
 Index: rpm/rpmdb/rpmevr.c
= = = = = = ======================================================================
 $ cvs diff -u -r1.26 -r1.27 rpmevr.c
 --- rpm/rpmdb/rpmevr.c 3 Jan 2009 20:58:10 -0000       1.26
 +++ rpm/rpmdb/rpmevr.c 5 Jan 2009 00:34:43 -0000       1.27
 @@ -21,6 +21,28 @@
  #define MAX(x, y) ( ((x)>(y))?(x):(y) )
  #endif

 +EVR_t rpmEVRnew(rpmuint32_t Flags, int initialize)
 +{
 +    EVR_t evr = xcalloc(1, sizeof(*evr));
 +    evr->Flags = Flags;
 +    if (initialize) {
 +      evr->F[RPMEVR_E] = "0";
 +      evr->F[RPMEVR_V] = "";
 +      evr->F[RPMEVR_R] = "";
 +    }
 +    return evr;
 +}
 +
 +EVR_t rpmEVRfree(EVR_t evr)
 +{
 +    if (evr != NULL) {
 +      evr->str = _free(evr->str);
 +      memset(evr, 0, sizeof(*evr));
 +      evr = _free(evr);
 +    }
 +    return NULL;
 +}
 +
  /* XXX Force digits to beat alphas. See bugzilla #50977. */
  /*...@unchecked@*/
  #if defined(RPM_VENDOR_MANDRIVA) /* old-comparision-behaviour */
 @@ -313,6 +335,30 @@
      return rc;
  }

 +int rpmEVRoverlap(EVR_t a, EVR_t b)
 +{
 +    rpmsenseFlags aF = a->Flags;
 +    rpmsenseFlags bF = b->Flags;
 +    int sense = rpmEVRcompare(a, b);
 +    int result;
 +
 +    /* Detect overlap of {A,B} range. */
 +    if (aF == RPMSENSE_NOTEQUAL || bF == RPMSENSE_NOTEQUAL)
 +        result = (sense != 0);
+ else if (sense < 0 && ((aF & RPMSENSE_GREATER) || (bF & RPMSENSE_LESS)))
 +        result = 1;
+ else if (sense > 0 && ((aF & RPMSENSE_LESS) || (bF & RPMSENSE_GREATER)))
 +        result = 1;
 +    else if (sense == 0 &&
 +        (((aF & RPMSENSE_EQUAL) && (bF & RPMSENSE_EQUAL)) ||
 +         ((aF & RPMSENSE_LESS) && (bF & RPMSENSE_LESS)) ||
 +         ((aF & RPMSENSE_GREATER) && (bF & RPMSENSE_GREATER))))
 +        result = 1;
 +    else
 +        result = 0;
 +    return result;
 +}
 +
  /*...@-redecl@*/
  int (*rpmvercmp) (const char *a, const char *b) = rpmEVRcmp;
  /*...@=redecl@*/
 @@ .
 patch -p0 <<'@@ .'
 Index: rpm/rpmdb/rpmevr.h
= = = = = = ======================================================================
 $ cvs diff -u -r1.8 -r1.9 rpmevr.h
 --- rpm/rpmdb/rpmevr.h 3 Jan 2009 15:49:38 -0000       1.8
 +++ rpm/rpmdb/rpmevr.h 5 Jan 2009 00:34:43 -0000       1.9
 @@ -82,10 +82,9 @@
  struct EVR_s {
      const char * str;         /*!< EVR storage */
  #ifndef       DYING
 -    unsigned long Elong;
 +    unsigned long Elong;      /*!< E converted to integer. */
  #endif
      evrFlags Flags;           /*!< EVR comparison flags. */
 -    size_t nF;                        /*!< No. of parsed fields. */
const char * F[5]; /*!< Parsed fields (\1=E, \2=V, \3=R, \4=D). */
  #define       RPMEVR_E        1
  #define       RPMEVR_V        2
 @@ -124,6 +123,24 @@
  #endif        /* _RPMEVR_INTERNAL */

  /** \ingroup rpmds
 + * Create a new EVR container.
 + * @param flags               EVR inequality flags
 + * @param initialize  Should empty defaults be initialized?
 + * @return            initialized EVR container
 + */
 +EVR_t rpmEVRnew(rpmuint32_t flags, int initialize)
 +        /*...@*/;
 +
 +/** \ingroup rpmtd
 + * Destroy an EVR container.
 + * @param             EVR container
 + * @return            NULL always
 + */
 +/*...@null@*/
 +EVR_t rpmEVRfree(/*...@only@*/ EVR_t evr)
 +        /*...@modifies evr @*/;
 +
 +/** \ingroup rpmds
   * Segmented string compare.
   * @param a           1st string
   * @param b           2nd string
 @@ -142,7 +159,7 @@
        /*...@modifies evrstr, evr @*/;

  /** \ingroup rpmds
 - * Compare EVR containers.
 + * Compare EVR containers for equality.
   * @param a           1st EVR container
   * @param b           2nd EVR container
   * @return            +1 if a is "newer", 0 if equal, -1 if b is "newer"
 @@ -151,6 +168,15 @@
        /*...@*/;

  /** \ingroup rpmds
 + * Compare EVR containers for overlap.
 + * @param a           1st EVR container
 + * @param b           2nd EVR container
 + * @return            1 if EVR inequalities overlap, 0 otherwise
 + */
 +int rpmEVRoverlap(EVR_t a, EVR_t b)
 +      /*...@*/;
 +
 +/** \ingroup rpmds
   * Segmented string compare vector.
   * @param a           1st string
   * @param b           2nd string
 @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-...@rpm5.org

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to