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_docpackage.h"
21 
comps_docpackage_create(COMPS_DocGroupPackage * package,COMPS_Object ** args)22 static void comps_docpackage_create(COMPS_DocGroupPackage* package, COMPS_Object **args) {
23     (void)args;
24     package->name = NULL;
25     package->requires = NULL;
26     package->basearchonly = NULL;
27     package->arches = NULL;
28     package->type = COMPS_PACKAGE_UNKNOWN;
29 }
COMPS_CREATE_u(docpackage,COMPS_DocGroupPackage)30 COMPS_CREATE_u(docpackage, COMPS_DocGroupPackage)
31 
32 static void comps_docpackage_copy(COMPS_DocGroupPackage *pkg_dst,
33                            COMPS_DocGroupPackage *pkg_src) {
34     pkg_dst->name = (COMPS_Str*)comps_object_copy((COMPS_Object*)pkg_src->name);
35     pkg_dst->requires = (COMPS_Str*)comps_object_copy(
36                                             (COMPS_Object*)pkg_src->requires);
37     pkg_dst->basearchonly = (COMPS_Num*)comps_object_copy(
38                                           (COMPS_Object*)pkg_src->basearchonly);
39     pkg_dst->arches = (COMPS_ObjList*)comps_object_copy(
40                                           (COMPS_Object*)pkg_src->arches);
41     pkg_dst->type = pkg_src->type;
42 }
COMPS_COPY_u(docpackage,COMPS_DocGroupPackage)43 COMPS_COPY_u(docpackage, COMPS_DocGroupPackage)    /*comps_utils.h macro*/
44 
45 static void comps_docpackage_destroy(COMPS_DocGroupPackage *pkg) {
46     comps_object_destroy((COMPS_Object*)pkg->name);
47     comps_object_destroy((COMPS_Object*)pkg->requires);
48     comps_object_destroy((COMPS_Object*)pkg->basearchonly);
49     comps_object_destroy((COMPS_Object*)pkg->arches);
50 }
COMPS_DESTROY_u(docpackage,COMPS_DocGroupPackage)51 COMPS_DESTROY_u(docpackage, COMPS_DocGroupPackage) /*comps_utils.h macro*/
52 
53 void comps_docpackage_set_name(COMPS_DocGroupPackage *pkg, char *name, char copy) {
54     (void)copy;
55     if (pkg->name)
56         comps_object_destroy((COMPS_Object*)pkg->name);
57     pkg->name = comps_str(name);
58 }
59 
comps_docpackage_get_name(COMPS_DocGroupPackage * pkg)60 COMPS_Object* comps_docpackage_get_name(COMPS_DocGroupPackage *pkg) {
61     return comps_object_incref((COMPS_Object*)pkg->name);
62 }
63 
comps_docpackage_set_requires(COMPS_DocGroupPackage * pkg,char * requires,char copy)64 void comps_docpackage_set_requires(COMPS_DocGroupPackage *pkg, char *requires, char copy) {
65     (void)copy;
66     if (pkg->requires)
67         comps_object_destroy((COMPS_Object*)pkg->requires);
68     pkg->requires = comps_str(requires);
69 }
70 
comps_docpackage_get_requires(COMPS_DocGroupPackage * pkg)71 COMPS_Object* comps_docpackage_get_requires(COMPS_DocGroupPackage *pkg) {
72     return comps_object_incref((COMPS_Object*)pkg->requires);
73 }
74 
comps_docpackage_set_basearchonly(COMPS_DocGroupPackage * pkg,int basearchonly,bool unset)75 void comps_docpackage_set_basearchonly(COMPS_DocGroupPackage *pkg,
76                                        int basearchonly, bool unset) {
77     (void)unset;
78     if (pkg->basearchonly) {
79         COMPS_OBJECT_DESTROY(pkg->basearchonly);
80     }
81     pkg->basearchonly = comps_num(basearchonly);
82 }
83 
comps_docpackage_get_basearchonly(COMPS_DocGroupPackage * pkg)84 COMPS_Object* comps_docpackage_get_basearchonly(COMPS_DocGroupPackage *pkg) {
85     return comps_object_incref((COMPS_Object*)pkg->basearchonly);
86 }
87 
comps_docpackage_set_type_i(COMPS_DocGroupPackage * pkg,int type,bool unset)88 void comps_docpackage_set_type_i(COMPS_DocGroupPackage *pkg, int type, bool unset) {
89     (void)unset;
90     pkg->type = type;
91 }
92 
comps_docpackage_set_type(COMPS_DocGroupPackage * pkg,COMPS_PackageType type,bool unset)93 void comps_docpackage_set_type(COMPS_DocGroupPackage *pkg,
94                                    COMPS_PackageType type, bool unset) {
95     (void)unset;
96     pkg->type = type;
97 }
98 
comps_docpackage_get_type(COMPS_DocGroupPackage * pkg)99 COMPS_Object* comps_docpackage_get_type(COMPS_DocGroupPackage *pkg) {
100     return (COMPS_Object*)comps_num(pkg->type);
101 }
102 
103 
comps_docpackage_cmp_u(COMPS_Object * pkg1,COMPS_Object * pkg2)104 signed char comps_docpackage_cmp_u(COMPS_Object *pkg1, COMPS_Object *pkg2) {
105     #define _pkg1 ((COMPS_DocGroupPackage*)pkg1)
106     #define _pkg2 ((COMPS_DocGroupPackage*)pkg2)
107 
108     if (!comps_object_cmp((COMPS_Object*)_pkg1->name,
109                           (COMPS_Object*)_pkg2->name)) return 0;
110     if (!comps_object_cmp((COMPS_Object*)_pkg1->requires,
111                           (COMPS_Object*)_pkg2->requires)) return 0;
112     if (_pkg1->type != _pkg2->type) return 0;
113 
114     return 1;
115 
116     #undef _pkg1
117     #undef _pkg2
118 }
119 
__comps_docpackage_idcmp(void * pkg1,void * pkg2)120 char __comps_docpackage_idcmp(void *pkg1, void *pkg2) {
121     return comps_object_cmp((COMPS_Object*)((COMPS_DocGroupPackage*)pkg1)->name,
122                            (COMPS_Object*)((COMPS_DocGroupPackage*)pkg2)->name);
123 }
124 
comps_docpackage_type_str(COMPS_PackageType type)125 const char* comps_docpackage_type_str(COMPS_PackageType type) {
126     switch(type){
127         case COMPS_PACKAGE_OPTIONAL:
128             return "optional";
129         case COMPS_PACKAGE_MANDATORY:
130             return "mandatory";
131         case COMPS_PACKAGE_CONDITIONAL:
132             return "conditional";
133         default:
134             return "default";
135     }
136 }
137 
comps_docpackage_cmp_set(void * pkg1,void * pkg2)138 inline char comps_docpackage_cmp_set(void *pkg1, void *pkg2) {
139     return COMPS_OBJECT_CMP(((COMPS_DocGroupPackage*)pkg1)->name,
140                             ((COMPS_DocGroupPackage*)pkg2)->name);
141 }
142 
comps_docpackage_xml(COMPS_DocGroupPackage * pkg,xmlTextWriterPtr writer,COMPS_Log * log,COMPS_XMLOptions * xml_options,COMPS_DefaultsOptions * def_options)143 signed char comps_docpackage_xml(COMPS_DocGroupPackage *pkg,
144                                  xmlTextWriterPtr writer,
145                                  COMPS_Log *log, COMPS_XMLOptions *xml_options,
146                                  COMPS_DefaultsOptions *def_options) {
147     char *str;
148     int ret;
149     bool bao_def = false;
150     (void)def_options;
151 
152     ret = xmlTextWriterStartElement(writer, BAD_CAST "packagereq");
153     COMPS_XMLRET_CHECK()
154     if (xml_options->arch_output) {
155         COMPS_Object *obj = (COMPS_Object*)pkg->arches;
156         ret = __comps_xml_arch(obj, writer);
157         COMPS_XMLRET_CHECK()
158     }
159     if (pkg->type == COMPS_PACKAGE_OPTIONAL)
160         str = "optional";
161     else if (pkg->type == COMPS_PACKAGE_MANDATORY)
162         str = "mandatory";
163     else if (pkg->type == COMPS_PACKAGE_CONDITIONAL)
164         str = "conditional";
165     else
166         str = "default";
167 
168     ret = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST str);
169 
170     if (pkg->requires) {
171         str = comps_object_tostr((COMPS_Object*)pkg->requires);
172         if (str && *str) {
173             ret = xmlTextWriterWriteAttribute(writer, (xmlChar*) "requires", BAD_CAST str);
174         }
175         free(str);
176     }
177     COMPS_XMLRET_CHECK()
178     if (xml_options->bao_explicit) {
179         if (pkg->basearchonly) {
180             ret = xmlTextWriterWriteAttribute(writer, (xmlChar*) "basearchonly",
181                                                 BAD_CAST "true");
182         } else {
183             ret = xmlTextWriterWriteAttribute(writer, (xmlChar*) "basearchonly",
184                                                 BAD_CAST "false");
185         }
186     } else {
187         if (pkg->basearchonly && pkg->basearchonly->val != bao_def) {
188             if (pkg->basearchonly) {
189                 ret = xmlTextWriterWriteAttribute(writer, (xmlChar*) "basearchonly",
190                                                     BAD_CAST "true");
191             } else {
192                 ret = xmlTextWriterWriteAttribute(writer, (xmlChar*) "basearchonly",
193                                                     BAD_CAST "false");
194             }
195         }
196     }
197     COMPS_XMLRET_CHECK()
198     str = comps_object_tostr((COMPS_Object*)pkg->name);
199     ret = xmlTextWriterWriteString(writer, (xmlChar*)str);
200     free(str);
201     COMPS_XMLRET_CHECK()
202     ret = xmlTextWriterEndElement(writer);
203     COMPS_XMLRET_CHECK()
204     return 0;
205 }
206 
comps_docpackage_str_u(COMPS_Object * docpackage)207 static char* comps_docpackage_str_u(COMPS_Object* docpackage) {
208     #define _package_ ((COMPS_DocGroupPackage*)docpackage)
209     const size_t len = strlen("<COMPS_DocGroupPackage name='' type='' "
210                               "requires='' basearchonly=''>");
211     char *name = comps_object_tostr((COMPS_Object*)_package_->name);
212     const char *type = comps_docpackage_type_str(_package_->type);
213     char *requires = comps_object_tostr((COMPS_Object*)_package_->requires);
214     char *basearchonly;
215     if ((_package_->basearchonly) && (_package_->basearchonly->val))
216         basearchonly = "True";
217     else
218         basearchonly = "False";
219     size_t total_len = len + strlen(name)
220                            + strlen(type)
221                            + strlen(requires) +
222                            + strlen(basearchonly) + 1;
223     char *ret = malloc(sizeof(char)*(total_len));
224 
225     snprintf(ret, total_len, "<COMPS_DocGroupPackage name='%s' type='%s'"
226                              " requires='%s' basearchonly='%s'>",
227                  name, type, requires, basearchonly);
228     free(name);
229     free(requires);
230     return ret;
231 }
232 
comps_docpackage_arches(COMPS_DocGroupPackage * pkg)233 COMPS_ObjList* comps_docpackage_arches(COMPS_DocGroupPackage *pkg) {
234     return (COMPS_ObjList*)comps_object_incref((COMPS_Object*)pkg->arches);
235 }
comps_docpackage_set_arches(COMPS_DocGroupPackage * pkg,COMPS_ObjList * arches)236 void comps_docpackage_set_arches(COMPS_DocGroupPackage *pkg,
237                                  COMPS_ObjList *arches) {
238     COMPS_OBJECT_DESTROY(pkg->arches);
239     pkg->arches = arches;
240 }
241 
242 COMPS_ValRuleGeneric* COMPS_DocGroupPackage_ValidateRules[] = {
243     (COMPS_ValRuleGeneric*)&(COMPS_ValRuleProp){COMPS_VAL_RULE_PROP,
244                          .verbose_msg = "Package name check: ",
245                          .get_f = (COMPS_VAL_GETF) &comps_docpackage_get_name,
246                          .check_f = &comps_empty_check},
247     NULL
248 };
249 
250 COMPS_ObjectInfo COMPS_DocGroupPackage_ObjInfo = {
251     .obj_size = sizeof(COMPS_DocGroupPackage),
252     .constructor = &comps_docpackage_create_u,
253     .destructor = &comps_docpackage_destroy_u,
254     .copy = &comps_docpackage_copy_u,
255     .obj_cmp = &comps_docpackage_cmp_u,
256     .to_str = &comps_docpackage_str_u
257 };
258