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_UTILS_H
21 #define COMPS_UTILS_H
22 
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdbool.h>
26 
27 #include "comps_obj.h"
28 #include "comps_objlist.h"
29 #include "comps_set.h"
30 
31 #include <libxml/encoding.h>
32 #include <libxml/xmlwriter.h>
33 #include <libxml/tree.h>
34 
35 
36 #define CONCAT(A,B) CONCAT2(A, B)
37 #define CONCAT2(A, B) A ## B
38 
39 #define COMPS_PROP_CMP(OBJNAME, PROPNAME, GETTER)\
40 char CONCAT(CONCAT(CONCAT(CONCAT(__comps_, OBJNAME),_),PROPNAME),cmp) (void *obj1,\
41                                                                        void *obj2){\
42     COMPS_Prop *prop1, *prop2;\
43     prop1 = GETTER(obj1, #PROPNAME);\
44     prop2 = GETTER(obj2, #PROPNAME);\
45     if (prop1 == NULL && prop2 == NULL) return 1;\
46     if (prop1 == NULL || prop2 == NULL) return 0;\
47     if (prop1->prop_type != COMPS_PROP_STR ||\
48         prop2->prop_type != COMPS_PROP_STR) return 0;\
49     return __comps_strcmp(prop1->prop.str, prop2->prop.str);\
50 }
51 
52 #define COMPS_STRPROP_SETTER(OBJNAME, OBJTYPE, PROPNAME)\
53 inline void CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _set_), PROPNAME)(OBJTYPE *OBJNAME,\
54                                                                         char *PROPNAME,\
55                                                                         char copy) {\
56     (void)copy;\
57     if (PROPNAME) {\
58         COMPS_Object *str;\
59         str = (COMPS_Object*)comps_str(PROPNAME);\
60         comps_objdict_set_x(OBJNAME->properties, #PROPNAME, str);\
61     }\
62 }
63 
64 #define HEAD_COMPS_STRPROP_SETTER(OBJNAME, OBJTYPE, PROPNAME)\
65 void CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _set_), PROPNAME)(OBJTYPE *OBJNAME,\
66                                                                  char *PROPNAME,\
67                                                                  char copy);
68 
69 #define COMPS_NUMPROP_SETTER(OBJNAME, OBJTYPE, PROPNAME)\
70 inline void CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _set_), PROPNAME)(OBJTYPE *OBJNAME,\
71                                                                         int PROPNAME,\
72                                                                         bool unset){\
73         if (unset) {\
74             comps_objdict_set_x(OBJNAME->properties, #PROPNAME, NULL);\
75             return;\
76         } \
77         COMPS_Object *num;\
78         num = (COMPS_Object*)comps_num(PROPNAME);\
79         comps_objdict_set_x(OBJNAME->properties, #PROPNAME, num);\
80 }
81 #define HEAD_COMPS_NUMPROP_SETTER(OBJNAME, OBJTYPE, PROPNAME)\
82 void CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _set_), PROPNAME)(OBJTYPE *OBJNAME,\
83                                                                  int PROPNAME,\
84                                                                  bool unset);
85 
86 
87 #define COMPS_PROP_GETTER(OBJNAME, OBJTYPE, PROPNAME)\
88 inline COMPS_Object* CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _get_), PROPNAME)\
89                                                          (OBJTYPE *OBJNAME){\
90     return comps_objdict_get(OBJNAME->properties, #PROPNAME);\
91 }
92 #define HEAD_COMPS_PROP_GETTER(OBJNAME, OBJTYPE, PROPNAME)\
93 COMPS_Object* CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _get_), PROPNAME)\
94                                                             (OBJTYPE *OBJNAME);
95 #define COMPS_PROP_GETTER_OBJ(OBJNAME, OBJTYPE, PROPNAME)\
96 inline COMPS_Object* CONCAT(CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME),\
97                                            _get_), PROPNAME), _obj)\
98                                                       (COMPS_Object *OBJNAME){\
99     return CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME), _get_), PROPNAME)\
100                                                         ((OBJTYPE*)OBJNAME);\
101 }
102 #define HEAD_COMPS_PROP_GETTER_OBJ(OBJNAME, PROPNAME)\
103 COMPS_Object* CONCAT(CONCAT(CONCAT(CONCAT(comps_doc, OBJNAME),\
104                                    _get_), PROPNAME), _obj)\
105                                                         (COMPS_Object *OBJNAME);
106 
107 
108 #define COMPS_CREATE_u(NAME, TYPE) void CONCAT(CONCAT(comps_, NAME), _create_u)\
109                                                         (COMPS_Object *uobj,\
110                                                          COMPS_Object **args) {\
111     CONCAT(CONCAT(comps_, NAME),_create)((TYPE*)uobj, args);\
112 }
113 #define HEAD_COMPS_CREATE_u(NAME, TYPE) void CONCAT(CONCAT(comps_, NAME), _create_u)\
114                                                         (COMPS_Object *uobj,\
115                                                          COMPS_Object **args);
116 
117 #define COMPS_COPY_u(NAME, TYPE) void CONCAT(CONCAT(comps_,NAME),_copy_u)\
118                                                             (COMPS_Object* obj_dst,\
119                                                              COMPS_Object* obj_src){\
120     CONCAT(CONCAT(comps_, NAME),_copy) ((TYPE*)obj_dst, (TYPE*)obj_src);\
121 }
122 #define HEAD_COMPS_COPY_u(NAME, TYPE) void CONCAT(CONCAT(comps_,NAME),_copy_u)\
123                                                         (COMPS_Object* obj_dst,\
124                                                          COMPS_Object* obj_src);
125 
126 #define COMPS_DESTROY_u(NAME, TYPE)\
127 static void CONCAT(CONCAT(comps_, NAME), _destroy_u)(COMPS_Object* obj){\
128     CONCAT(CONCAT(comps_, NAME),_destroy) ((TYPE*)obj);\
129 }
130 #define HEAD_COMPS_DESTROY_u(NAME, TYPE)\
131 static void CONCAT(CONCAT(comps_, NAME), _destroy_u)(COMPS_Object* obj);
132 
133 #define COMPS_CMP_u(NAME, TYPE) signed char CONCAT(CONCAT(comps_,NAME),_cmp_u)\
134                                                             (COMPS_Object* obj_dst,\
135                                                              COMPS_Object* obj_src){\
136     return CONCAT(CONCAT(comps_, NAME),_cmp) ((TYPE*)obj_dst, (TYPE*)obj_src);\
137 }
138 #define HEAD_COMPS_CMP_u(NAME, TYPE) void CONCAT(CONCAT(comps_,NAME),_cmp_u)\
139 
140 
141 #define COMPS_DOCOBJ_GETOBJLIST(OBJ, OBJTYPE, MEMBER, OBJS)\
142 COMPS_ObjList* CONCAT(CONCAT(CONCAT(comps_, OBJ), _), OBJS) (OBJTYPE *obj){\
143     return obj->MEMBER;\
144 }
145 #define HEAD_COMPS_DOCOBJ_GETOBJLIST(OBJ, OBJTYPE, MEMBER, OBJS)\
146 COMPS_ObjList* CONCAT(CONCAT(CONCAT(comps_, OBJ), _), OBJS) (OBJTYPE *obj);
147 
148 #define COMPS_DOCOBJ_SETOBJLIST(OBJ, OBJTYPE, MEMBER, OBJS)\
149 void CONCAT(CONCAT(CONCAT(comps_, OBJ), _set_), OBJS) (OBJTYPE *obj,\
150                                                    COMPS_ObjList *list){\
151     COMPS_OBJECT_DESTROY(obj->MEMBER);\
152     obj->MEMBER = (COMPS_ObjList*)comps_object_incref((COMPS_Object*)list);\
153 }
154 #define HEAD_COMPS_DOCOBJ_SETOBJLIST(OBJ, OBJTYPE, MEMBER, OBJS)\
155 void CONCAT(CONCAT(CONCAT(comps_, OBJ), _set_), OBJS) (OBJTYPE *obj,\
156                                                    COMPS_ObjList *list);
157 
158 #define COMPS_DOCOBJ_GETARCHES(OBJ, OBJTYPE)\
159 COMPS_ObjList* CONCAT(CONCAT(comps_, OBJ), _arches) (OBJTYPE *obj){\
160     return (COMPS_ObjList*)comps_objdict_get(obj->properties, "arches");\
161 }
162 #define HEAD_COMPS_DOCOBJ_GETARCHES(OBJ, OBJTYPE)\
163 COMPS_ObjList* CONCAT(CONCAT(comps_, OBJ), _arches)(OBJTYPE *obj);
164 
165 #define COMPS_DOCOBJ_SETARCHES(OBJ, OBJTYPE)\
166 void CONCAT(CONCAT(comps_, OBJ), _set_arches)(OBJTYPE *obj,\
167                                               COMPS_ObjList *list){\
168     comps_objdict_set_x(obj->properties, "arches", (COMPS_Object*)list);\
169 }
170 #define HEAD_COMPS_DOCOBJ_SETARCHES(OBJ, OBJTYPE)\
171 void CONCAT(CONCAT(comps_, OBJ), _set_arches)(OBJTYPE *obj,\
172                                               COMPS_ObjList *list);
173 
174 
175 #define COMPS_XMLRET_CHECK(free_code) if (ret == -1) {\
176     free_code;\
177     comps_log_error(log, COMPS_ERR_XMLGEN, 0);\
178     return -1;\
179 }
180 
181 char __comps_strcmp(void *s1, void *s2);
182 char* __comps_strcpy(char *str);
183 char* __comps_strcat(char *str1, char *str2);
184 void* __comps_str_clone(void *str);
185 int __comps_xml_prop(char *key, char *val, xmlTextWriterPtr writer);
186 char* __comps_num2boolstr(COMPS_Object* obj);
187 unsigned int digits_count(unsigned int x);
188 bool __comps_objlist_intersected(COMPS_ObjList *list1, COMPS_ObjList *list2);
189 char* __comps_xml_arch_str(COMPS_Object *arches);
190 int __comps_xml_arch(COMPS_Object *archlist, xmlTextWriterPtr writer);
191 
192 int __comps_check_xml_get(int retcode, COMPS_Object * log);
193 #endif
194