small optimization for pool_addfileprovides
[platform/upstream/libsolv.git] / src / poolvendor.c
1 /*
2  * Copyright (c) 2007, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 /* we need FNM_CASEFOLD */
13 #ifndef _GNU_SOURCE
14 #define _GNU_SOURCE
15 #endif
16
17 #include <fnmatch.h>
18
19 #include "pool.h"
20 #include "poolid.h"
21 #include "poolvendor.h"
22 #include "util.h"
23
24 /*
25  *  const char *vendorsclasses[] = {
26  *    "!openSUSE Build Service*",
27  *    "SUSE*",
28  *    "openSUSE*",
29  *    "SGI*",
30  *    "Novell*",
31  *    "Silicon Graphics*",
32  *    "Jpackage Project*",
33  *    "ATI Technologies Inc.*",
34  *    "Nvidia*",
35  *    0,
36  *    0,
37  *  };
38  */
39
40 /* allows for 32 different vendor classes */
41
42 Id pool_vendor2mask(Pool *pool, Id vendor)
43 {
44   const char *vstr;
45   int i;
46   Id mask, m;
47   const char **v, *vs;
48
49   if (vendor == 0 || !pool->vendorclasses)
50     return 0;
51   for (i = 0; i < pool->vendormap.count; i += 2)
52     if (pool->vendormap.elements[i] == vendor)
53       return pool->vendormap.elements[i + 1];
54   vstr = pool_id2str(pool, vendor);
55   m = 1;
56   mask = 0;
57   for (v = pool->vendorclasses; ; v++)
58     {
59       vs = *v;
60       if (vs == 0)      /* end of block? */
61         {
62           v++;
63           if (*v == 0)
64             break;
65           if (m == (1 << 31))
66             break;      /* sorry, out of bits */
67           m <<= 1;      /* next vendor equivalence class */
68         }
69       if (fnmatch(*vs == '!' ? vs + 1 : vs, vstr, FNM_CASEFOLD) == 0)
70         {
71           if (*vs != '!')
72             mask |= m;
73           while (v[1])  /* forward to next block */
74             v++;
75         }
76     }
77   queue_push(&pool->vendormap, vendor);
78   queue_push(&pool->vendormap, mask);
79   return mask;
80 }
81
82 void
83 pool_setvendorclasses(Pool *pool, const char **vendorclasses)
84 {
85   int i;
86   const char **v;
87
88   if (pool->vendorclasses)
89     {
90       for (v = pool->vendorclasses; v[0] || v[1]; v++)
91         solv_free((void *)*v);
92       pool->vendorclasses = solv_free(pool->vendorclasses);
93     }
94   if (!vendorclasses || !vendorclasses[0])
95     return;
96   for (v = vendorclasses; v[0] || v[1]; v++)
97     ;
98   pool->vendorclasses = solv_calloc(v - vendorclasses + 2, sizeof(const char *));
99   for (v = vendorclasses, i = 0; v[0] || v[1]; v++, i++)
100     pool->vendorclasses[i] = *v ? solv_strdup(*v) : 0;
101   pool->vendorclasses[i++] = 0;
102   pool->vendorclasses[i] = 0;
103   queue_empty(&pool->vendormap);
104 }
105
106 void
107 pool_addvendorclass(Pool *pool, const char **vendorclass)
108 {
109   int i, j;
110
111   if (!vendorclass || !vendorclass[0])
112     return;
113   for (j = 1; vendorclass[j]; j++)
114     ;
115   i = 0;
116   if (pool->vendorclasses)
117     {
118       for (i = 0; pool->vendorclasses[i] || pool->vendorclasses[i + 1]; i++)
119         ;
120       if (i)
121         i++;
122     }
123   pool->vendorclasses = solv_realloc2(pool->vendorclasses, i + j + 2, sizeof(const char *));
124   for (j = 0; vendorclass[j]; j++)
125     pool->vendorclasses[i++] = solv_strdup(vendorclass[j]);
126   pool->vendorclasses[i++] = 0;
127   pool->vendorclasses[i] = 0;
128   queue_empty(&pool->vendormap);
129 }