1 /* libcomps - C alternative to yum.comps library
2 * Copyright (C) 2013 Jindrich Luza
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 * USA
18 */
19
20 #include "comps_set.h"
21 #include <stdlib.h>
22 #include <string.h>
23
comps_set_index_cmp(void * item1,void * item2)24 char comps_set_index_cmp(void *item1, void *item2) {
25 return *(unsigned int*)item1 == *(unsigned int*)item2;
26 }
comps_set_index_clone(void * item)27 void* comps_set_index_clone(void *item) {
28 void * ret;
29 if ((ret = malloc(sizeof(unsigned int))) == NULL)
30 return NULL;
31 memcpy(ret, item, sizeof(unsigned int));
32 return ret;
33 }
34
comps_set_create()35 COMPS_Set * comps_set_create()
36 {
37 COMPS_Set *ret;
38 if ((ret = malloc(sizeof(COMPS_Set))) == NULL) {
39 return NULL;
40 }
41 ret->data = comps_hslist_create();
42 if (ret->data == NULL) {
43 free(ret);
44 return NULL;
45 }
46 return ret;
47 }
48
comps_set_destroy(COMPS_Set ** set)49 void comps_set_destroy(COMPS_Set **set) {
50 comps_hslist_destroy(&(*set)->data);
51 free(*set);
52 *set = NULL;
53 }
54
comps_set_destroy_v(void * set)55 inline void comps_set_destroy_v(void *set) {
56 comps_hslist_destroy(&((COMPS_Set*)set)->data);
57 free((COMPS_Set*)set);
58 }
59
comps_set_init(COMPS_Set * set,void * (* data_constructor)(void *),void * (* data_cloner)(void *),void (* data_destructor)(void *),char (* eqf)(void *,void *))60 void comps_set_init(COMPS_Set * set, void* (*data_constructor)(void*),
61 void* (*data_cloner)(void*),
62 void (*data_destructor)(void*),
63 char (*eqf)(void*, void*)) {
64 if (set == NULL)
65 return;
66 set->data_constructor = data_constructor;
67 set->data_destructor = data_destructor;
68 set->data_cloner = data_cloner;
69 set->eqf = eqf;
70 comps_hslist_init(set->data, data_constructor, data_cloner, data_destructor);
71 }
72
comps_set_in(COMPS_Set * set,void * item)73 char comps_set_in(COMPS_Set * set, void * item) {
74 COMPS_HSListItem * it;
75 for (it = set->data->first; it != NULL; it = it->next) {
76 if (set->eqf(it->data, item))
77 return 1;
78 }
79 return 0;
80 }
81
comps_set_at(COMPS_Set * set,void * item)82 int comps_set_at(COMPS_Set * set, void * item) {
83 COMPS_HSListItem * it;
84 int x;
85 for (x=0, it = set->data->first; it != NULL; it = it->next, x++) {
86 if (set->eqf(it->data, item)) {
87 return x;
88 }
89 }
90 return -1;
91 }
92
comps_set_data_at(COMPS_Set * set,void * item)93 void* comps_set_data_at(COMPS_Set * set, void * item) {
94 COMPS_HSListItem * it;
95 for (it = set->data->first; it != NULL; it = it->next) {
96 if (set->eqf(it->data, item)) {
97 return it->data;
98 }
99 }
100 return NULL;
101 }
102
comps_set_add(COMPS_Set * set,void * item)103 char comps_set_add(COMPS_Set * set, void *item) {
104 COMPS_HSListItem * it;
105
106 for (it = set->data->first; it != NULL; it = it->next) {
107 if (set->eqf(it->data, item)) {
108 return 0;
109 }
110 }
111 comps_hslist_append(set->data, item, 1);
112 return 1;
113 }
114
comps_set_remove(COMPS_Set * set,void * item)115 void* comps_set_remove(COMPS_Set *set, void *item) {
116 void * ret;
117 COMPS_HSListItem * it;
118 for (it = set->data->first; it != NULL; it = it->next) {
119 if (set->eqf(it->data, item)) {
120 comps_hslist_remove(set->data, it);
121 ret = it->data;
122 free(it);
123 return ret;
124 }
125 }
126 return NULL;
127 }
128
comps_set_is_empty(COMPS_Set * set)129 inline char comps_set_is_empty(COMPS_Set *set) {
130 if (set->data->first == NULL) {
131 return 1;
132 } else return 0;
133 }
134
comps_set_cmp(COMPS_Set * set1,COMPS_Set * set2)135 char comps_set_cmp(COMPS_Set *set1, COMPS_Set *set2) {
136 unsigned int x, index;
137 COMPS_Set *not_processed1, *not_processed2;
138 COMPS_HSListItem *it;
139 void *item;//, *tmpdata;
140 char ret;
141 int at;
142
143 not_processed1 = comps_set_create();
144 not_processed2 = comps_set_create();
145 comps_set_init(not_processed1, &comps_set_index_clone,
146 &comps_set_index_clone,
147 &free, &comps_set_index_cmp);
148 comps_set_init(not_processed2, &comps_set_index_clone,
149 &comps_set_index_clone,
150 &free, &comps_set_index_cmp);
151 for (x = 0, it = set1->data->first; it!= NULL; it = it->next, x++) {
152 comps_hslist_append(not_processed1->data, &x, 1);
153 }
154 for (x = 0, it = set2->data->first; it!= NULL; it = it->next, x++) {
155 comps_hslist_append(not_processed2->data, &x, 1);
156 }
157 it = set1->data->first;
158
159 index = 0;
160 ret = 0;
161 while (!comps_set_is_empty(not_processed1) &&
162 !comps_set_is_empty(not_processed2)) {
163 if ((at = comps_set_at(set2, it->data)) != -1) {
164 item = comps_set_remove(not_processed1, (void*)&index);
165 free(item);
166 item = comps_set_remove(not_processed2 , (void*)&at);
167 free(item);
168 //tmpdata = comps_hslist_data_at(set2->data, at);
169 } else {
170 ret = 2;
171 break;
172 }
173 it = it->next;
174 index++;
175 if (it == NULL) break;
176 }
177 if (ret == 0) {
178 if (comps_set_is_empty(not_processed1)) {
179 /*if (comps_set_is_empty(not_processed2))
180 ret = 0;*/
181 if (!comps_set_is_empty(not_processed2))
182 ret = -1;
183 } else {
184 if (comps_set_is_empty(not_processed2))
185 ret = 1;
186 else ret = 2;
187 }
188 }
189 comps_set_destroy(¬_processed1);
190 comps_set_destroy(¬_processed2);
191 return ret;
192 }
193
comps_set_clear(COMPS_Set * set)194 inline void comps_set_clear(COMPS_Set *set) {
195 comps_hslist_clear(set->data);
196 }
197
198