2011/1/20 Jeff Johnson <n3...@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 ______________________________________________________________________ RPM Package Manager http://rpm5.org Developer Communication List rpm-devel@rpm5.org