rpm
4.5
|
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 }