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 #ifndef COMPS_DOC_H
21 #define COMPS_DOC_H
22 
23 #include "comps_obj.h"
24 #include "comps_objdict.h"
25 #include "comps_objlist.h"
26 #include "comps_log.h"
27 #include "comps_types.h"
28 #include "comps_docgroup.h"
29 #include "comps_doccategory.h"
30 #include "comps_docenv.h"
31 #include "comps_validate.h"
32 #include "comps_default.h"
33 
34 /** \file comps_doc.h
35  * \brief COMPS_Doc header file
36  *
37  * COMPS_Doc object support union operation. Read more about
38  * @link doc_unioning Libcomps objects unioning
39  * @endlink
40  * @see COMPS_Doc_getters @see COMPS_Doc_setters @see COMPS_Doc_adders
41  */
42 
43 /** @cond NOTMET */
44 #define COMPS_DOC_GETOBJLIST(OBJS) COMPS_ObjList* CONCAT(comps_doc_, OBJS)\
45                                                            (COMPS_Doc *doc){\
46     COMPS_ObjList *ret;\
47     ret = (COMPS_ObjList*)comps_objdict_get(doc->objects, #OBJS);\
48     if (!ret) {\
49         ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);\
50         comps_objdict_set_x(doc->objects, #OBJS, (COMPS_Object*)ret);\
51         ret = (COMPS_ObjList*)comps_object_incref((COMPS_Object*)ret);\
52     }\
53     return ret;\
54 }
55 /** <@hideinititalizer */
56 
57 #define HEAD_COMPS_DOC_GETOBJLIST(OBJS) COMPS_ObjList* CONCAT(comps_doc_, OBJS)\
58                                                            (COMPS_Doc *doc);
59 /** <@hideinititalizer */
60 
61 #define COMPS_DOC_SETOBJLIST(OBJS) void CONCAT(comps_doc_set_, OBJS)\
62                                                        (COMPS_Doc *doc,\
63                                                         COMPS_ObjList *list){\
64     comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)list);\
65 }
66 /** <@hideinititalizer */
67 #define HEAD_COMPS_DOC_SETOBJLIST(OBJS) void CONCAT(comps_doc_set_, OBJS)\
68                                                    (COMPS_Doc *doc,\
69                                                     COMPS_ObjList *list);
70 /** <@hideinititalizer */
71 
72 #define COMPS_DOC_GETOBJDICT(OBJNAME) COMPS_ObjDict* CONCAT(comps_doc_, OBJNAME)\
73                                                            (COMPS_Doc *doc){\
74     COMPS_ObjDict *ret;\
75     ret = (COMPS_ObjDict*)comps_objdict_get(doc->objects, #OBJNAME);\
76     if (!ret) {\
77         ret = COMPS_OBJECT_CREATE(COMPS_ObjDict, NULL);\
78         comps_objdict_set_x(doc->objects, #OBJNAME, (COMPS_Object*)ret);\
79         ret = (COMPS_ObjDict*)comps_object_incref((COMPS_Object*)ret);\
80     }\
81     return ret;\
82 }
83 /** <@hideinititalizer */
84 #define HEAD_COMPS_DOC_GETOBJDICT(OBJNAME) COMPS_ObjDict* CONCAT(comps_doc_, OBJNAME)\
85                                                            (COMPS_Doc *doc);
86 /** <@hideinititalizer */
87 
88 #define COMPS_DOC_GETOBJMDICT(OBJNAME) COMPS_ObjMDict* CONCAT(comps_doc_, OBJNAME)\
89                                                            (COMPS_Doc *doc){\
90     COMPS_ObjMDict *ret;\
91     ret = (COMPS_ObjMDict*)comps_objdict_get(doc->objects, #OBJNAME);\
92     if (!ret) {\
93         ret = COMPS_OBJECT_CREATE(COMPS_ObjMDict, NULL);\
94         comps_objdict_set_x(doc->objects, #OBJNAME, (COMPS_Object*)ret);\
95         ret = (COMPS_ObjMDict*)comps_object_incref((COMPS_Object*)ret);\
96     }\
97     return ret;\
98 }
99 /** <@hideinititalizer */
100 #define HEAD_COMPS_DOC_GETOBJMDICT(OBJNAME) COMPS_ObjMDict* CONCAT(comps_doc_, OBJNAME)\
101                                                            (COMPS_Doc *doc);
102 /** <@hideinititalizer */
103 
104 #define COMPS_DOC_SETOBJDICT(OBJS) void CONCAT(comps_doc_set_, OBJS)\
105                                                        (COMPS_Doc *doc,\
106                                                         COMPS_ObjDict *dict){\
107     comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)dict);\
108 }
109 /** <@hideinititalizer */
110 #define HEAD_COMPS_DOC_SETOBJDICT(OBJS) void CONCAT(comps_doc_set_, OBJS)\
111                                                    (COMPS_Doc *doc,\
112                                                     COMPS_ObjDict *dict);
113 /** <@hideinititalizer */
114 
115 #define COMPS_DOC_SETOBJMDICT(OBJS) void CONCAT(comps_doc_set_, OBJS)\
116                                                        (COMPS_Doc *doc,\
117                                                         COMPS_ObjMDict *dict){\
118     comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)dict);\
119 }
120 /** <@hideinititalizer */
121 #define HEAD_COMPS_DOC_SETOBJMDICT(OBJS) void CONCAT(comps_doc_set_, OBJS)\
122                                                    (COMPS_Doc *doc,\
123                                                     COMPS_ObjMDict *dict);
124 /** <@hideinititalizer */
125 
126 
127 #define COMPS_DOC_ADDOBJLIST(OBJS, OBJNAME, OBJTYPE) void CONCAT(comps_doc_add_,\
128                                                            OBJNAME)\
129                                                            (COMPS_Doc *doc,\
130                                                             OBJTYPE *obj){\
131     COMPS_ObjList *ret;\
132     ret = (COMPS_ObjList*)comps_objdict_get(doc->objects, #OBJS);\
133     if (!ret) {\
134         ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);\
135         comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)ret);\
136     } else {\
137     }\
138     comps_objlist_append_x(ret, (COMPS_Object*)obj);\
139     COMPS_OBJECT_DESTROY(ret);\
140 }
141 /** <@hideinititalizer */
142 #define HEAD_COMPS_DOC_ADDOBJLIST(OBJNAME, OBJTYPE) void CONCAT(comps_doc_add_,\
143                                                            OBJNAME)\
144                                                            (COMPS_Doc *doc,\
145                                                             OBJTYPE *obj);
146 /** <@hideinititalizer */
147 
148 #define COMPS_DOC_ADDOBJDICT(OBJS, OBJNAME) void CONCAT(comps_doc_add_,\
149                                                            OBJNAME)\
150                                                            (COMPS_Doc *doc,\
151                                                             char *key,\
152                                                             COMPS_Str *obj){\
153     COMPS_ObjDict *ret;\
154     ret = (COMPS_ObjDict*)comps_objdict_get(doc->objects, #OBJS);\
155     if (!ret) {\
156         ret = COMPS_OBJECT_CREATE(COMPS_ObjDict, NULL);\
157         comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)ret);\
158     }\
159     comps_objdict_set_x(ret, key, (COMPS_Object*)obj);\
160     COMPS_OBJECT_DESTROY(ret);\
161 }
162 /** <@hideinititalizer */
163 #define HEAD_COMPS_DOC_ADDOBJDICT(OBJNAME) void CONCAT(comps_doc_add_,\
164                                                            OBJNAME)\
165                                                            (COMPS_Doc *doc,\
166                                                             char *key,\
167                                                             COMPS_Str *obj);
168 /** <@hideinititalizer */
169 
170 
171 #define COMPS_DOC_ADDOBJMDICT(OBJS, OBJNAME) void CONCAT(comps_doc_add_,\
172                                                            OBJNAME)\
173                                                            (COMPS_Doc *doc,\
174                                                             char *key,\
175                                                             COMPS_Str *obj){\
176     COMPS_ObjMDict *ret;\
177     ret = (COMPS_ObjMDict*)comps_objdict_get(doc->objects, #OBJS);\
178     if (!ret) {\
179         ret = COMPS_OBJECT_CREATE(COMPS_ObjMDict, NULL);\
180         comps_objdict_set(doc->objects, #OBJS, (COMPS_Object*)ret);\
181     }\
182     comps_objmdict_set_x(ret, key, (COMPS_Object*)obj);\
183     COMPS_OBJECT_DESTROY(ret);\
184 }
185 /** <@hideinititalizer */
186 #define HEAD_COMPS_DOC_ADDOBJMDICT(OBJNAME) void CONCAT(comps_doc_add_,\
187                                                            OBJNAME)\
188                                                            (COMPS_Doc *doc,\
189                                                             char *key,\
190                                                             COMPS_Str *obj);
191 /** <@hideinititalizer */
192 
193 #define COMPS_DOC_GETPROP(OBJ,TYPE) CONCAT(TYPE,CONCAT(* ,CONCAT(comps_doc_, OBJ)))\
194                                                            (COMPS_Doc *doc){\
195     TYPE *ret;\
196     ret = (COMPS_Str*)comps_objdict_get(doc->objects, #OBJ);\
197     if (!ret) {\
198         ret = COMPS_OBJECT_CREATE(TYPE, NULL);\
199         comps_objdict_set_x(doc->objects, #OBJ, (COMPS_Object*)ret);\
200         ret = (TYPE*)comps_object_incref((COMPS_Object*)ret);\
201     }\
202     return ret;\
203 }
204 /** <@hideinititalizer */
205 
206 #define HEAD_COMPS_DOC_GETPROP(OBJ, TYPE) CONCAT(TYPE,CONCAT(*,CONCAT(comps_doc_, OBJS)))\
207                                                            (COMPS_Doc *doc);
208 /** <@hideinititalizer */
209 
210 
211 #define COMPS_DOC_SETPROP(OBJ, TYPE) void CONCAT(comps_doc_set_, OBJ)\
212                                                        (COMPS_Doc *doc,\
213                                                         TYPE *value){\
214     comps_objdict_set(doc->objects, #OBJ, (COMPS_Object*)value);\
215 }
216 
217 /** <@hideinititalizer */
218 
219 
220 #define HEAD_COMPS_DOC_SETPROP(OBJ, TYPE) void CONCAT(comps_doc_set_, OBJ)\
221                                                    (COMPS_Doc *doc,\
222                                                     TYPE *value);
223 
224 /** <@hideinititalizer */
225 /** @endcond*/
226 
227 /** COMPS_Object derivate containing whole comps.xml document.
228  */
229 typedef struct {
230     COMPS_Object_HEAD;
231     COMPS_ObjDict *objects; /**< dictionary of comps subobjects */
232     COMPS_Log *log;
233     /**< COMPS_Log object to store log messages evoked
234      * by parsing and xml generating */
235     COMPS_Str *encoding;   /**< comps.xml document encoding */
236     COMPS_Str *doctype_name;
237     COMPS_Str *doctype_sysid;
238     COMPS_Str *doctype_pubid;
239     COMPS_Str *lang;
240     } COMPS_Doc;
241 COMPS_Object_TAIL(COMPS_Doc);
242 
243 //HEAD_COMPS_CREATE_u(doc, COMPS_Doc)  /*comps_utils.h macro*/
244 //HEAD_COMPS_COPY_u(doc, COMPS_Doc)  /*comps_utils.h macro*/
245 //HEAD_COMPS_DESTROY_u(doc, COMPS_Doc)  /*comps_utils.h macro*/
246 
247 /** constructor callback for COMPS_Doc object. COMPS_Doc is COMPS_Object
248  * derivate. Use comps_object_create() or COMPS_OBJECT_CREATE for construction
249  * instead
250  *
251  * @param doc allocated COMPS_Doc object
252  * @param args array of constructor arguments. COMPS_Doc constructor accepts
253  * encoding argument as COMPS_Str object only so array need not end with
254  * sentinel item*/
255 void comps_doc_create(COMPS_Doc* doc, COMPS_Object **args);
256 
257 /** copy callback for COMPS_Doc object*/
258 void comps_doc_copy(COMPS_Doc *doc_dst, COMPS_Doc *doc_src);
259 
260 /** destructor callback for COMPS_Doc object. COMPS_Doc is COMPS_Object
261  * derivate. Use comps_object_create() for construction instead*/
262 void comps_doc_destroy(COMPS_Doc *doc);
263 
264 /** comparator callback for COMPS_Doc object */
265 signed char comps_doc_cmp_u(COMPS_Object *obj1, COMPS_Object *obj2);
266 
267 /** \defgroup COMPS_Doc_getters COMPS_Doc getters
268  * @{
269  */
270 
271 /** comps group list getter
272  * @param doc COMPS_Doc instance
273  * @return COMPS_ObjList object of COMPS_DocGroup*/
274 HEAD_COMPS_DOC_GETOBJLIST(groups) /*comps_doc.h macro*/
275 
276 /** comps category list getter
277  * @param doc COMPS_Doc instance
278  * @return COMPS_ObjList object of COMPS_DocCategory*/
279 HEAD_COMPS_DOC_GETOBJLIST(categories) /*comps_doc.h macro*/
280 
281 /** comps environment list getter
282  * @param doc COMPS_Doc instance
283  * @return COMPS_ObjList object of COMPS_DocEnv*/
284 HEAD_COMPS_DOC_GETOBJLIST(environments) /*comps_doc.h macro*/
285 
286 /** comps langpack dictionary getter
287  * @param doc COMPS_Doc instance
288  * @return COMPS_ObjDict object of COMPS_Str*/
289 HEAD_COMPS_DOC_GETOBJDICT(langpacks) /*comps_doc.h macro*/
290 
291 /** comps blacklist dictionary getter
292  * @param doc COMPS_Doc instance
293  * @return COMPS_ObjMDict object of COMPS_Str*/
294 HEAD_COMPS_DOC_GETOBJMDICT(blacklist) /*comps_doc.h macro*/
295 
296 /** comps whiteout dictionary getter
297  * @param doc COMPS_Doc instance
298  * @return COMPS_ObjMDict object of COMPS_Str*/
299 HEAD_COMPS_DOC_GETOBJMDICT(whiteout) /*comps_doc.h macro*/
300 
301 /**@}*/
302 
303 /** \defgroup COMPS_Doc_setters COMPS_Doc setters
304  * @{
305  */
306 
307 /** comps group list setter
308  * @param doc COMPS_Doc instance
309  * @param list COMPS_ObjList of COMPS_DocGroup items
310  * \warning make sure of correct items type. Setter doesn't provide any
311  * additional control routines
312  */
313 HEAD_COMPS_DOC_SETOBJLIST(groups) /*comps_doc.h macro*/
314 
315 /** comps category list setter
316  * @param doc COMPS_Doc instance
317  * @param list COMPS_ObjList of COMPS_DocCategory items
318  * \warning make sure of correct items type. Setter doesn't provide any
319  * additional control routines
320  */
321 HEAD_COMPS_DOC_SETOBJLIST(categories) /*comps_doc.h macro*/
322 
323 /** comps environments list setter
324  * @param doc COMPS_Doc instance
325  * @param list COMPS_ObjList of COMPS_DocEnv items
326  * \warning make sure of correct items type. Setter doesn't provide any
327  * additional control routines
328  */
329 HEAD_COMPS_DOC_SETOBJLIST(environments) /*comps_doc.h macro*/
330 
331 /** comps lankpack dict setter
332  * @param doc COMPS_Doc instance
333  * @param dict COMPS_ObjDict of COMPS_Str items
334  * \warning make sure of correct items type. Setter doesn't provide any
335  * additional control routines
336  */
337 HEAD_COMPS_DOC_SETOBJDICT(langpacks) /*comps_doc.h macro*/
338 
339 /** comps blacklist multi-dict setter
340  * @param doc COMPS_Doc instance
341  * @param dict COMPS_ObjMDict of COMPS_Str items
342  * \warning make sure of correct items type. Setter doesn't provide any
343  * additional control routines
344  */
345 HEAD_COMPS_DOC_SETOBJMDICT(blacklist) /*comps_doc.h macro*/
346 
347 /** comps whiteout multi-dict setter
348  * @param doc COMPS_Doc instance
349  * @param dict COMPS_ObjMDict of COMPS_Str items
350  * \warning make sure of correct items type. Setter doesn't provide any
351  * additional control routines
352  */
353 HEAD_COMPS_DOC_SETOBJMDICT(whiteout) /*comps_doc.h macro*/
354 
355 /**@}*/
356 
357 /** \defgroup COMPS_Doc_adders COMPS_Doc adders
358  * @{
359  */
360 
361 /** COMPS_DocGroup adder to group list in COMPS_Doc
362  * @param doc COMPS_Doc instance
363  * @param obj COMPS_DocGroup object
364  * append COMPS_DocGroup object to group list in COMPS_Doc structure
365  * \warning function doesn't increment COMPS_DocGroup object reference count.
366  */
367 HEAD_COMPS_DOC_ADDOBJLIST(group, COMPS_DocGroup) /*comps_doc.h macro*/
368 
369 /** COMPS_DocCategory adder to category list in COMPS_Doc
370  * @param doc COMPS_Doc instance
371  * @param obj COMPS_DocCategory object
372  * append COMPS_DocCategory object to category list in COMPS_Doc structure
373  * \warning function doesn't increment COMPS_DocCategory object reference count.
374  */
375 HEAD_COMPS_DOC_ADDOBJLIST(category, COMPS_DocCategory) /*comps_doc.h macro*/
376 
377 /** COMPS_DocEnv adder to environment list in COMPS_Doc
378  * @param doc COMPS_Doc instance
379  * @param obj COMPS_DocEnv object
380  * append COMPS_DocEnv object to environment list in COMPS_Doc structure
381  * \warning function doesn't increment COMPS_DocEnv object reference count.
382  */
383 HEAD_COMPS_DOC_ADDOBJLIST(environment, COMPS_DocEnv) /*comps_doc.h macro*/
384 
385 /** Langpack adder to langpack dict in COMPS_Doc
386  * @param doc COMPS_Doc instance
387  * @param key COMPS_Str dictionary key of langpack
388  * @param obj COMPS_Str langpack
389  * add langpack string to langpack dict in COMPS_Doc structure. If There's
390  * allready langpack string with same key, will be overwritten.
391  * \warning function doesn't increment obj param reference count.
392  */
393 HEAD_COMPS_DOC_ADDOBJDICT(langpack) /*comps_doc.h macro*/
394 
395 /** Blacklist adder to blacklist multi-dict in COMPS_Doc
396  * @param doc COMPS_Doc instance
397  * @param key COMPS_Str dictionary key of blacklist
398  * @param obj COMPS_Str blacklist item
399  * append blacklist item object to blacklist in COMPS_Doc structure. Items
400  * with same key are grouped in COMPS_ObjList object.
401  * \warning function doesn't increment obj param reference count.
402  */
403 HEAD_COMPS_DOC_ADDOBJMDICT(blacklist) /*comps_doc.h macro*/
404 
405 /** whiteout adder to whitetout multi-dict in COMPS_Doc
406  * @param doc COMPS_Doc instance
407  * @param key COMPS_Str dictionary key of whiteout
408  * @param obj COMPS_Str whiteout item
409  * append whiteout item object to blacklist in COMPS_Doc structure. Items
410  * with same key are grouped in COMPS_ObjList object.
411  * \warning function doesn't increment obj param reference count.
412  */
413 HEAD_COMPS_DOC_ADDOBJMDICT(whiteout) /*comps_doc.h macro*/
414 
415 
416 
417 /** whiteout adder to whitetout multi-dict in COMPS_Doc
418  * @param doc COMPS_Doc instance
419  * @param obj COMPS_Str language value
420  * Set language to comps object and all subobjects
421  */
422 
423 HEAD_COMPS_DOC_SETPROP(lang, COMPS_Str) /*comps_doc.h macro*/
424 
425 /**@}*/
426 
427 /** \defgroup COMPS_Doc_filters COMPS_Doc filters
428  * @{
429  */
430 
431 COMPS_ObjList* comps_doc_get_groups(COMPS_Doc *doc, char *id, char *name,
432                                     char *desc, char *lang, int flags);
433 COMPS_ObjList* comps_doc_get_categories(COMPS_Doc *doc, char *id, char *name,
434                                         char *desc, char *lang, int flags);
435 COMPS_ObjList* comps_doc_get_envs(COMPS_Doc *doc, char *id, char *name,
436                                   char *desc, char *lang, int flags);
437 
438 /**@}*/
439 
440 //char* comps_doc_xml_str(COMPS_Doc* doc, char *enc, COMPS_Log *log);
441 
442 
443 //static signed char comps_doc_xml(COMPS_Doc *doc, xmlTextWriterPtr writer);
444 
445 /** Write XML representation to file
446  * @param doc COMPS_Doc object
447  * @param filename filename where to write
448  * @param stdoutredirect in non-zero all warning and error messages will
449  * be redirected to stdout, otherwise will be stored in doc->log only
450  * @return 0 if there wasn't any errors, 1 if there was non-fatal errors
451  * -1 if fatal error emerge during xml generation
452  */
453 signed char comps2xml_f(COMPS_Doc * doc, char *filename, char stdoutredirect,
454                         COMPS_XMLOptions *xml_options,
455                         COMPS_DefaultsOptions *def_options);
456 
457 /** Generate XML string representating COMPS_Doc structure
458  * @param doc COMPS_Doc object
459  * @return XML string
460  */
461 char* comps2xml_str(COMPS_Doc *doc, COMPS_XMLOptions *options,
462                     COMPS_DefaultsOptions *def_options);
463 
464 /** Union two COMPS_Doc structures
465  * COMPS_Doc structures are unioned as unioning it's subparts
466  * (group, categories, environments). Object with same 'id' attribute
467  * are regarded as equal and unioned by with each other
468  *
469  * @param c1 COMPS_Doc object
470  * @param c2 COMPS_Doc object
471  */
472 COMPS_Doc* comps_doc_union(COMPS_Doc *c1, COMPS_Doc *c2);
473 COMPS_Doc* comps_doc_intersect(COMPS_Doc *c1, COMPS_Doc *c2);
474 
475 COMPS_Doc* comps_doc_arch_filter(COMPS_Doc *source, COMPS_ObjList *arches);
476 
477 COMPS_Str* comps_doc_doctype_name_get(COMPS_Doc* doc);
478 COMPS_Str* comps_doc_doctype_pubid_get(COMPS_Doc* doc);
479 COMPS_Str* comps_doc_doctype_sysid_get(COMPS_Doc* doc);
480 void comps_doc_doctype_name_set(COMPS_Doc* doc, COMPS_Str *val);
481 void comps_doc_doctype_sysid_set(COMPS_Doc* doc, COMPS_Str *val);
482 void comps_doc_doctype_pubid_set(COMPS_Doc* doc, COMPS_Str *val);
483 
484 //extern COMPS_ObjectInfo COMPS_Doc_ObjInfo;
485 extern COMPS_ValRuleGeneric* COMPS_Doc_ValidateRules[];
486 
487 #endif //COMPS_DOC_H
488 
489