rpm  4.5
tagname.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmlib.h>
8 #include "debug.h"
9 
10 /*@access headerTagTableEntry @*/
11 /*@access headerTagIndices @*/
12 
19 static int tagCmpName(const void * avp, const void * bvp)
20  /*@*/
21 {
24  return strcmp(a->name, b->name);
25 }
26 
33 static int tagCmpValue(const void * avp, const void * bvp)
34  /*@*/
35 {
38  int ret = (a->val - b->val);
39  /* Make sure that sort is stable, longest name first. */
40  if (ret == 0)
41  ret = (strlen(b->name) - strlen(a->name));
42  return ret;
43 }
44 
52 static int tagLoadIndex(headerTagTableEntry ** ipp, int * np,
53  int (*cmp) (const void * avp, const void * bvp))
54  /*@modifies *ipp, *np @*/
55 {
56  headerTagTableEntry tte, *ip;
57  int n = 0;
58 
59  ip = xcalloc(rpmTagTableSize, sizeof(*ip));
60  n = 0;
61 /*@-dependenttrans@*/ /*@-observertrans@*/ /*@-castexpose@*/ /*@-mods@*/ /*@-modobserver@*/
62  for (tte = (headerTagTableEntry)rpmTagTable; tte->name != NULL; tte++) {
63  ip[n] = tte;
64  n++;
65  }
66 assert(n == rpmTagTableSize);
67 /*@=dependenttrans@*/ /*@=observertrans@*/ /*@=castexpose@*/ /*@=mods@*/ /*@=modobserver@*/
68 
69  if (n > 1)
70  qsort(ip, n, sizeof(*ip), cmp);
71  *ipp = ip;
72  *np = n;
73  return 0;
74 }
75 
76 
77 /* forward refs */
78 static const char * _tagName(int tag)
79  /*@*/;
80 static int _tagType(int tag)
81  /*@*/;
82 static int _tagValue(const char * tagstr)
83  /*@*/;
84 
85 /*@unchecked@*/
86 static struct headerTagIndices_s _rpmTags = {
88  NULL, 0, tagCmpName, _tagValue,
89  NULL, 0, tagCmpValue, _tagName, _tagType,
90 };
91 
92 /*@-compmempass@*/
93 /*@unchecked@*/
95 /*@=compmempass@*/
96 
97 static const char * _tagName(int tag)
98 {
99  static char nameBuf[128]; /* XXX yuk */
100  const struct headerTagTableEntry_s *t;
101  int comparison, i, l, u;
102  int xx;
103  char *s;
104 
105  if (_rpmTags.byValue == NULL)
106  xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
107 
108  switch (tag) {
109  case RPMDBI_PACKAGES:
110  strcpy(nameBuf, "Packages");
111  break;
112  case RPMDBI_DEPENDS:
113  strcpy(nameBuf, "Depends");
114  break;
115  case RPMDBI_ADDED:
116  strcpy(nameBuf, "Added");
117  break;
118  case RPMDBI_REMOVED:
119  strcpy(nameBuf, "Removed");
120  break;
121  case RPMDBI_AVAILABLE:
122  strcpy(nameBuf, "Available");
123  break;
124  case RPMDBI_HDLIST:
125  strcpy(nameBuf, "Hdlist");
126  break;
127  case RPMDBI_ARGLIST:
128  strcpy(nameBuf, "Arglist");
129  break;
130  case RPMDBI_FTSWALK:
131  strcpy(nameBuf, "Ftswalk");
132  break;
133 
134  /* XXX make sure rpmdb indices are identically named. */
135  case RPMTAG_CONFLICTS:
136  strcpy(nameBuf, "Conflictname");
137  break;
138  case RPMTAG_HDRID:
139  strcpy(nameBuf, "Sha1header");
140  break;
141 
142  default:
143  strcpy(nameBuf, "(unknown)");
144  if (_rpmTags.byValue == NULL)
145  break;
146 /*@-boundswrite@*/
147  l = 0;
148  u = _rpmTags.byValueSize;
149  while (l < u) {
150  i = (l + u) / 2;
151  t = _rpmTags.byValue[i];
152 
153  comparison = (tag - t->val);
154 
155  if (comparison < 0)
156  u = i;
157  else if (comparison > 0)
158  l = i + 1;
159  else {
160  nameBuf[0] = nameBuf[1] = '\0';
161  /* Make sure that the bsearch retrieve is stable. */
162  while (i > 0 && tag == _rpmTags.byValue[i-1]->val) {
163  i--;
164  t--;
165  }
166  t = _rpmTags.byValue[i];
167  if (t->name != NULL)
168  strcpy(nameBuf, t->name + (sizeof("RPMTAG_")-1));
169  for (s = nameBuf+1; *s != '\0'; s++)
170  *s = xtolower(*s);
171  /*@loopbreak@*/ break;
172  }
173  }
174  break;
175  }
176 /*@-statictrans@*/
177  return nameBuf;
178 /*@=statictrans@*/
179 }
180 
181 static int _tagType(int tag)
182 {
183  const struct headerTagTableEntry_s *t;
184  int comparison, i, l, u;
185  int xx;
186 
187  if (_rpmTags.byValue == NULL)
188  xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
189 
190  switch (tag) {
191  case RPMDBI_PACKAGES:
192  case RPMDBI_DEPENDS:
193  case RPMDBI_ADDED:
194  case RPMDBI_REMOVED:
195  case RPMDBI_AVAILABLE:
196  case RPMDBI_HDLIST:
197  case RPMDBI_ARGLIST:
198  case RPMDBI_FTSWALK:
199  break;
200  default:
201  if (_rpmTags.byValue == NULL)
202  break;
203 /*@-boundswrite@*/
204  l = 0;
205  u = _rpmTags.byValueSize;
206  while (l < u) {
207  i = (l + u) / 2;
208  t = _rpmTags.byValue[i];
209 
210  comparison = (tag - t->val);
211 
212  if (comparison < 0)
213  u = i;
214  else if (comparison > 0)
215  l = i + 1;
216  else {
217  /* Make sure that the bsearch retrieve is stable. */
218  while (i > 0 && t->val == _rpmTags.byValue[i-1]->val) {
219  i--;
220  t--;
221  }
222  return t->type;
223  }
224  }
225  break;
226  }
227  return RPM_NULL_TYPE;
228 }
229 
230 static int _tagValue(const char * tagstr)
231 {
232  const struct headerTagTableEntry_s *t;
233  int comparison, i, l, u;
234  int xx;
235 
236  if (!xstrcasecmp(tagstr, "Packages"))
237  return RPMDBI_PACKAGES;
238  if (!xstrcasecmp(tagstr, "Depends"))
239  return RPMDBI_DEPENDS;
240  if (!xstrcasecmp(tagstr, "Added"))
241  return RPMDBI_ADDED;
242  if (!xstrcasecmp(tagstr, "Removed"))
243  return RPMDBI_REMOVED;
244  if (!xstrcasecmp(tagstr, "Available"))
245  return RPMDBI_AVAILABLE;
246  if (!xstrcasecmp(tagstr, "Hdlist"))
247  return RPMDBI_HDLIST;
248  if (!xstrcasecmp(tagstr, "Arglist"))
249  return RPMDBI_ARGLIST;
250  if (!xstrcasecmp(tagstr, "Ftswalk"))
251  return RPMDBI_FTSWALK;
252 
253  if (_rpmTags.byName == NULL)
254  xx = tagLoadIndex(&_rpmTags.byName, &_rpmTags.byNameSize, tagCmpName);
255  if (_rpmTags.byName == NULL)
256  return -1;
257 
258  l = 0;
259  u = _rpmTags.byNameSize;
260  while (l < u) {
261  i = (l + u) / 2;
262  t = _rpmTags.byName[i];
263 
264  comparison = xstrcasecmp(tagstr, t->name + (sizeof("RPMTAG_")-1));
265 
266  if (comparison < 0)
267  u = i;
268  else if (comparison > 0)
269  l = i + 1;
270  else
271  return t->val;
272  }
273  return -1;
274 }