RPM Community Forums

Mailing List Message of <rpm-devel>

Re: disttag/distepoch in RPMTAG_NVRA [Fwd: [Cooker] Warning: remaining bugs in RPM ? (no distro tag)]

From: Per Øyvind Karlsen <pkarlsen@rpm5.org>
Date: Fri 21 Jan 2011 - 07:11:09 CET
Message-ID: <AANLkTinjjme-14HWvbeZe_NScXkqLvaRowV8z0rgj9oH@mail.gmail.com>
2011/1/20 Jeff Johnson <n3npq@mac.com>:
>
> On Jan 19, 2011, at 8:44 PM, Jeff Johnson wrote:
>
>>
>> On Jan 19, 2011, at 8:39 PM, Per Øyvind Karlsen wrote:
>>
>>>>
>>>>> ie. 'rpm -q foo' might return:
>>>>> foo-1-1-mdv2011.0.x86_64
>>>>> foo-bar-1-1mdv2011.0.x86_64
>>>>>
>>>>
>>>>
>>>> Yep. Can't tell what's what because the syntax isn't predictable.
>>> One workaround could be something like this:
>>> if(keyp[0] != '^') {
>>>    Header h;
>>>    while((h = rpmmiNext(mi)) {
>>>          he->tag = RPMTAG_NAME;
>>>          if(headerGet(h, he, 0))
>>>               if(strlen(keyp) < strlen(he->p.str))
>>>                      rpmmiPrune(mi,...);
>>> }
>>>
>>> This would remove the matches that has a name longer than the package
>>> queried for.
>>>
>>
>> strlen isn't a strong enough hint, there's equal length strings
>> that parse unambiguously too. Yoy're gonna need some restrictions
>
> s/un// (I said the opposite of what I meant to say).
>
>> on permitted characters in Disttag/Distepoch, just like Version/Release
>> cannot contain '-'.
Well, they already have,  you're thinking about in addition?
>
> And rpmmiPrune() isn't the right solution to a parsing problem either.
>
> A join might work, but there's no way that can be stabilizied on
> --query paths to meet luser expectations. It was hard enough
> figgering a means for pattern queries.
>
> I'd focus on getting a better *RE in place. You want as much of
> a prefix stem as possible so that DB_PARTIAL takes effect.
I hate regexp.. :p
>
> E.g., a *RE that starts like this: ^.*...
> will end up reading every key because there is no prefix stem,
> nor is there any way I could figger to make DB_PARTIAL relative to end-of-key.
>
> Reading every key for ~4K package NVRA is _STILL_ less computational
> effort than loading every header, as you example above does just
> to find the argument to pass to rpmmiPrune(), so stay focussed
> on a pattern that matsches strings can be handed to a parser.
Hmm, this one isn't much better either?
--- rpmdb/rpmdb.c       2011-01-09 07:25:35.583778635 +0100
+++ /home/peroyvind/RPM/rpm/BUILD/rpm-5.3.8/rpmdb/rpmdb.c
2011-01-21 06:58:28.104131003 +0100
@@ -1418,7 +1418,7 @@ static rpmRC dbiFindMatches(dbiIndex dbi
     /* Add ^...$ *RE anchors. Escape pattern characters. */
     {  rpmTag tag = dbi->dbi_rpmtag;
        rpmMireMode mode = RPMMIRE_PCRE;
-       static const char _post_NVRA[] =
"(-[^-]+-[^-]+\\.[^.]+|-[^-]+\\.[^.]+|\\.[^.]+|)$";
+       static const char _post_NVRA[] =
"(-[^-]+-[^-]+-[^-]+\\.[^.]+|-[^-]+-[^-]+\\.[^.]+|-[^-]+\\.[^.]+|\\.[^.]+|)$";
        const char * _pat;

        switch (tag) {
@@ -2442,6 +2442,44 @@ assert(keylen == sizeof(hdrNum));
        rpmRC rc;

        rc = dbiFindMatches(dbi, keyp, &set);
+       if(((const char*)keyp)[0] != '^' && tag == RPMTAG_NVRA && set
!= NULL && set->count > 0) {
+           int xx;
+           size_t i;
+           size_t len = strlen(keyp);
+           size_t size = 0;
+           dbiIndex pdbi;
+           DBC *pdbc;
+           DBT k = DBT_INIT;
+           DBT v = DBT_INIT;
+
+           pdbi = dbiOpen(db, RPMDBI_PACKAGES, 0);
+           xx = dbiCopen(pdbi, dbiTxnid(pdbi), &pdbc, 0);
+
+           for(i = 0; i < set->count; i++) {
+               Header h;
+               uint32_t offset = _hton_ui(set->recs[i].hdrNum);
+
+               k.data = &offset;
+               k.size = sizeof(offset);
+               xx = dbiGet(dbi, pdbc, &k, &v, DB_SET);
+               h = headerLoad(v.data);
+               he->tag = RPMTAG_NAME;
+               if(headerGet(h, he, 0)) {
+                   if(len >= strlen(he->p.str)) {
+                       set->recs[size].hdrNum = set->recs[i].hdrNum;
+                       set->recs[size].tagNum = set->recs[i].tagNum;
+                       size++;
+                   }
+                   _free(he->p.ptr);
+               }
+               h = headerFree(h);
+           }
+           if(set->count != size) {
+               set->count = size;
+               set->recs = realloc(set->recs, size * sizeof(*set->recs));
+           }
+           xx = dbiCclose(pdbi, pdbc, 0);
+       }

--
Regards,
Per Øyvind
Received on Fri Jan 21 07:11:32 2011
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.