rpmdb/tagname.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmlib.h>
00008 #include "debug.h"
00009 
00010 /*@access headerTagTableEntry @*/
00011 /*@access headerTagIndices @*/
00012 
00019 static int tagCmpName(const void * avp, const void * bvp)
00020         /*@*/
00021 {
00022     headerTagTableEntry a = *(headerTagTableEntry *) avp;
00023     headerTagTableEntry b = *(headerTagTableEntry *) bvp;
00024     return strcmp(a->name, b->name);
00025 }
00026 
00033 static int tagCmpValue(const void * avp, const void * bvp)
00034         /*@*/
00035 {
00036     headerTagTableEntry a = *(headerTagTableEntry *) avp;
00037     headerTagTableEntry b = *(headerTagTableEntry *) bvp;
00038     int ret = (a->val - b->val);
00039     /* Make sure that sort is stable, longest name first. */
00040     if (ret == 0)
00041         ret = (strlen(b->name) - strlen(a->name));
00042     return ret;
00043 }
00044 
00052 static int tagLoadIndex(headerTagTableEntry ** ipp, int * np,
00053                 int (*cmp) (const void * avp, const void * bvp))
00054         /*@modifies *ipp, *np @*/
00055 {
00056     headerTagTableEntry tte, *ip;
00057     int n = 0;
00058 
00059     ip = xcalloc(rpmTagTableSize, sizeof(*ip));
00060     n = 0;
00061 /*@-dependenttrans@*/ /*@-observertrans@*/ /*@-castexpose@*/ /*@-mods@*/ /*@-modobserver@*/
00062     for (tte = (headerTagTableEntry)rpmTagTable; tte->name != NULL; tte++) {
00063         ip[n] = tte;
00064         n++;
00065     }
00066 assert(n == rpmTagTableSize);
00067 /*@=dependenttrans@*/ /*@=observertrans@*/ /*@=castexpose@*/ /*@=mods@*/ /*@=modobserver@*/
00068 
00069     if (n > 1)
00070         qsort(ip, n, sizeof(*ip), cmp);
00071     *ipp = ip;
00072     *np = n;
00073     return 0;
00074 }
00075 
00076 
00077 /* forward refs */
00078 static const char * _tagName(int tag)
00079         /*@*/;
00080 static int _tagType(int tag)
00081         /*@*/;
00082 static int _tagValue(const char * tagstr)
00083         /*@*/;
00084 
00085 /*@unchecked@*/
00086 static struct headerTagIndices_s _rpmTags = {
00087     tagLoadIndex,
00088     NULL, 0, tagCmpName, _tagValue,
00089     NULL, 0, tagCmpValue, _tagName, _tagType,
00090 };
00091 
00092 /*@-compmempass@*/
00093 /*@unchecked@*/
00094 headerTagIndices rpmTags = &_rpmTags;
00095 /*@=compmempass@*/
00096 
00097 static const char * _tagName(int tag)
00098 {
00099     static char nameBuf[128];   /* XXX yuk */
00100     const struct headerTagTableEntry_s *t;
00101     int comparison, i, l, u;
00102     int xx;
00103     char *s;
00104 
00105     if (_rpmTags.byValue == NULL)
00106         xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
00107 
00108     switch (tag) {
00109     case RPMDBI_PACKAGES:
00110         strcpy(nameBuf, "Packages");
00111         break;
00112     case RPMDBI_DEPENDS:
00113         strcpy(nameBuf, "Depends");
00114         break;
00115     case RPMDBI_ADDED:
00116         strcpy(nameBuf, "Added");
00117         break;
00118     case RPMDBI_REMOVED:
00119         strcpy(nameBuf, "Removed");
00120         break;
00121     case RPMDBI_AVAILABLE:
00122         strcpy(nameBuf, "Available");
00123         break;
00124     case RPMDBI_HDLIST:
00125         strcpy(nameBuf, "Hdlist");
00126         break;
00127     case RPMDBI_ARGLIST:
00128         strcpy(nameBuf, "Arglist");
00129         break;
00130     case RPMDBI_FTSWALK:
00131         strcpy(nameBuf, "Ftswalk");
00132         break;
00133 
00134     /* XXX make sure rpmdb indices are identically named. */
00135     case RPMTAG_CONFLICTS:
00136         strcpy(nameBuf, "Conflictname");
00137         break;
00138     case RPMTAG_HDRID:
00139         strcpy(nameBuf, "Sha1header");
00140         break;
00141 
00142     default:
00143         strcpy(nameBuf, "(unknown)");
00144         if (_rpmTags.byValue == NULL)
00145             break;
00146 /*@-boundswrite@*/
00147         l = 0;
00148         u = _rpmTags.byValueSize;
00149         while (l < u) {
00150             i = (l + u) / 2;
00151             t = _rpmTags.byValue[i];
00152         
00153             comparison = (tag - t->val);
00154 
00155             if (comparison < 0)
00156                 u = i;
00157             else if (comparison > 0)
00158                 l = i + 1;
00159             else {
00160                 nameBuf[0] = nameBuf[1] = '\0';
00161                 /* Make sure that the bsearch retrieve is stable. */
00162                 while (i > 0 && tag == _rpmTags.byValue[i-1]->val) {
00163                     i--;
00164                     t--;
00165                 }
00166                 t = _rpmTags.byValue[i];
00167                 if (t->name != NULL)
00168                     strcpy(nameBuf, t->name + (sizeof("RPMTAG_")-1));
00169                 for (s = nameBuf+1; *s != '\0'; s++)
00170                     *s = xtolower(*s);
00171                 /*@loopbreak@*/ break;
00172             }
00173         }
00174         break;
00175     }
00176 /*@-statictrans@*/
00177     return nameBuf;
00178 /*@=statictrans@*/
00179 }
00180 
00181 static int _tagType(int tag)
00182 {
00183     const struct headerTagTableEntry_s *t;
00184     int comparison, i, l, u;
00185     int xx;
00186 
00187     if (_rpmTags.byValue == NULL)
00188         xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
00189 
00190     switch (tag) {
00191     case RPMDBI_PACKAGES:
00192     case RPMDBI_DEPENDS:
00193     case RPMDBI_ADDED:
00194     case RPMDBI_REMOVED:
00195     case RPMDBI_AVAILABLE:
00196     case RPMDBI_HDLIST:
00197     case RPMDBI_ARGLIST:
00198     case RPMDBI_FTSWALK:
00199         break;
00200     default:
00201         if (_rpmTags.byValue == NULL)
00202             break;
00203 /*@-boundswrite@*/
00204         l = 0;
00205         u = _rpmTags.byValueSize;
00206         while (l < u) {
00207             i = (l + u) / 2;
00208             t = _rpmTags.byValue[i];
00209         
00210             comparison = (tag - t->val);
00211 
00212             if (comparison < 0)
00213                 u = i;
00214             else if (comparison > 0)
00215                 l = i + 1;
00216             else {
00217                 /* Make sure that the bsearch retrieve is stable. */
00218                 while (i > 0 && t->val == _rpmTags.byValue[i-1]->val) {
00219                     i--;
00220                     t--;
00221                 }
00222                 return t->type;
00223             }
00224         }
00225         break;
00226     }
00227     return RPM_NULL_TYPE;
00228 }
00229 
00230 static int _tagValue(const char * tagstr)
00231 {
00232     const struct headerTagTableEntry_s *t;
00233     int comparison, i, l, u;
00234     int xx;
00235 
00236     if (!xstrcasecmp(tagstr, "Packages"))
00237         return RPMDBI_PACKAGES;
00238     if (!xstrcasecmp(tagstr, "Depends"))
00239         return RPMDBI_DEPENDS;
00240     if (!xstrcasecmp(tagstr, "Added"))
00241         return RPMDBI_ADDED;
00242     if (!xstrcasecmp(tagstr, "Removed"))
00243         return RPMDBI_REMOVED;
00244     if (!xstrcasecmp(tagstr, "Available"))
00245         return RPMDBI_AVAILABLE;
00246     if (!xstrcasecmp(tagstr, "Hdlist"))
00247         return RPMDBI_HDLIST;
00248     if (!xstrcasecmp(tagstr, "Arglist"))
00249         return RPMDBI_ARGLIST;
00250     if (!xstrcasecmp(tagstr, "Ftswalk"))
00251         return RPMDBI_FTSWALK;
00252 
00253     if (_rpmTags.byName == NULL)
00254         xx = tagLoadIndex(&_rpmTags.byName, &_rpmTags.byNameSize, tagCmpName);
00255     if (_rpmTags.byName == NULL)
00256         return -1;
00257 
00258     l = 0;
00259     u = _rpmTags.byNameSize;
00260     while (l < u) {
00261         i = (l + u) / 2;
00262         t = _rpmTags.byName[i];
00263         
00264         comparison = xstrcasecmp(tagstr, t->name + (sizeof("RPMTAG_")-1));
00265 
00266         if (comparison < 0)
00267             u = i;
00268         else if (comparison > 0)
00269             l = i + 1;
00270         else
00271             return t->val;
00272     }
00273     return -1;
00274 }

Generated on Wed Oct 29 03:28:20 2008 for rpm by  doxygen 1.5.1