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_OBJECT_H
21 #define COMPS_OBJECT_H
22 
23 #include "comps_mm.h"
24 
25 /** \file comps_obj.h
26  * \brief COMPS_Object header file
27  *
28  */
29 
30 /** \def COMPS_OBJECT_CREATE(obj_type, args)
31  * \brief macro for create object by choosen type without explicit needs
32  * of typecast. Macro returns concrete type of object not
33  * COMPS_Object type. If you want use this macro, you have to declare
34  * COMPS_ObjectInfo object exactly as <YourObject>_ObjInfo
35  * @see COMPS_Object_TAIL
36  */
37 
38 /** \def COMPS_OBJECT_CMP(obj1, obj2)
39  * \brief macro for compare two COMPS_Object derivates without typecasting to
40  *  COMPS_Object pointer
41  */
42 
43 /** \def COMPS_OBJECT_DESTROY(obj1)
44  * \brief macro for call comps_object_destroy without typecasting to
45  *  COMPS_Object pointer
46  */
47 
48 /** \def COMPS_OBJECT_COPY(obj)
49  * \brief macro for call comps_object_copy without typecasting to
50  *  COMPS_Object pointer
51  */
52 
53 /** \def COMPS_Object_TAIL(obj)
54  * \brief insert "extern COMPS_ObjectInfo <obj>_ObjInfo" statement. Use this
55  * macro in combination with COMPS_OBJECT_CREATE
56  * @see COMPS_OBJECT_CREATE
57  */
58 
59 #define COMPS_OBJECT_CREATE(objtype, args)\
60     (objtype*)comps_object_create(&objtype##_ObjInfo, args)
61 
62 
63 #define COMPS_OBJECT_CMP(obj1,obj2)\
64     comps_object_cmp((COMPS_Object*)obj1, (COMPS_Object*)obj2)
65 
66 #define COMPS_OBJECT_DESTROY(obj1)\
67     comps_object_destroy((COMPS_Object*)obj1)
68 
69 #define COMPS_OBJECT_COPY(obj)\
70     comps_object_copy(((COMPS_Object*)obj))
71 
72 #define COMPS_OBJECT_INCREF(obj)\
73     comps_object_incref(((COMPS_Object*)obj))
74 
75 #define COMPS_OBJECT_REPLACE(oldobj, TYPE, new_obj)\
76     COMPS_OBJECT_DESTROY(oldobj);\
77     oldobj = (TYPE*)COMPS_OBJECT_INCREF(new_obj);
78 
79 
80 #define COMPS_CAST_CONSTR void (*)(COMPS_Object*, COMPS_Object**)
81 #define COMPS_CAST_DESTR void (*)(COMPS_Object*)
82 
83 /** ensure that COMPS_Object derivate has need struct members for properly
84  * behaviour
85  */
86 #define COMPS_Object_HEAD COMPS_RefC *refc;\
87                          COMPS_ObjectInfo *obj_info
88 
89 #define COMPS_Object_TAIL(obj) extern COMPS_ObjectInfo obj##_ObjInfo
90 
91 typedef struct COMPS_Object COMPS_Object;
92 typedef struct COMPS_ObjectInfo COMPS_ObjectInfo;
93 typedef struct COMPS_Packed COMPS_Packed;
94 typedef struct COMPS_Num COMPS_Num;
95 typedef struct COMPS_Str COMPS_Str;
96 
97 
98 /** Structure holding all importating callback functions supporting
99  * COMPS_Object derivate proper behavior. All callbacks except constructor
100  * and destructor are optional @see comps_object_create
101  */
102 struct COMPS_ObjectInfo {
103     size_t obj_size; /**< size of derivate object which is sizeof(obj) */
104     void (*constructor)(COMPS_Object*, COMPS_Object **);
105     /**< pointer to derivate object constructor @see comps_object_create*/
106     void (*destructor)(COMPS_Object*);
107     /**< pointer to derivate objects destructor @see comps_object_destroy*/
108     void (*copy)(COMPS_Object*, COMPS_Object*);
109     /**< pointer to derivate object copy function @see comps_object_copy*/
110     COMPS_Object* (*deep_copy)(COMPS_Object*, COMPS_Object*);
111     /**< currently unused*/
112     signed char (*obj_cmp)(COMPS_Object*, COMPS_Object*);
113     /**< pointer to comparator function*/
114     char* (*to_str)(COMPS_Object*);
115     /**< pointer to string representation convert function */
116 };
117 
118 /** COMPS Object structure
119  * COMPS_Object is basic structure from which are derived concrete COMPS
120  * structure. Using COMPS Object as bootstrap of concrete object ensure
121  * eventuality of creating and destroying with reference counting, copying,
122  * comparing with other object, string representation
123 */
124 struct COMPS_Object {
125     COMPS_RefC *refc; /**< reference counter pointer for COMPS_Object*/
126     COMPS_ObjectInfo *obj_info; /**< pointer to COMPS_ObjectInfo struct*/
127 };
128 
129 /** COMPS Object derivate representing number
130  *
131  * COMPS_Num represents integer (signer or unsigned) number as COMPS Object
132 */
133 struct COMPS_Num {
134     COMPS_Object_HEAD; /** \n */
135     int val; /**< value of represented number*/
136 };
137 COMPS_Object_TAIL(COMPS_Num);
138 
139 /** COMPS Object derivate representing string
140  *
141  * COMPS_Str represents string as COMPS Object
142 */
143 struct COMPS_Str {
144     COMPS_Object_HEAD; /** \n */
145     char *val; /**< holds reprezented string, freed at destruction time*/
146 };
147 COMPS_Object_TAIL(COMPS_Str);
148 
149 
150 /** Create COMPS_Object derivate and pass \a args arguments to its constructor
151  * @param obj_info pointer to COMPS_ObjectInfo structure
152  * @param args array of arguments passed to derivate constructor. Array doesn't
153  * have to end with NULL sentinel.
154  * Processing args attribute passed to contructor
155  * is completely in programmer's care
156  * @return COMPS_Object derivate typecasted as general COMPS_Object
157  */
158 COMPS_Object* comps_object_create(COMPS_ObjectInfo *obj_info, COMPS_Object **args);
159 
160 /** Destroy passed COMPS_Object derivate if its reference counter is zero
161  * if not, only decrement reference counter
162  */
163 void comps_object_destroy(COMPS_Object *comps_obj);
164 void comps_object_destroy_v(void *comps_obj);
165 /** Return whole new copy of COMPS_Object derivate.
166  *
167  * Function create new allocation of derivate and call obj_copy callback with
168  * old instance and new instance of derivate. Copying inner structure members
169  * are in programmers care
170  * @param comps_obj derivate object want to be copied
171  * @return new copy of derivate object
172  * @see COMPS_ObjectInfo
173  */
174 COMPS_Object* comps_object_copy(COMPS_Object *comps_obj);
175 
176 /** Compare two COMPS_Object derivates and return non-zero value if equals
177  *
178  * \warning Function doen't check equality of derivate types (COMPS_ObjectInfo)!!
179  *
180  * @param obj1 first derivate
181  * @param obj2 second derivate
182  * @return non-zero value if equals, zero otherwise
183 */
184 signed char comps_object_cmp(COMPS_Object *obj1, COMPS_Object *obj2);
185 char comps_object_cmp_v(void *obj1, void *obj2);
186 
187 /** Return string representation of COMPS_Object derivate
188  *
189  * \warning
190  * Returned string is new allocation which needs to be freed manualy
191  *
192  * @param obj1 COMPS_Object derivate
193  * @return new alllocation of string representation of concrete object
194  */
195 char* comps_object_tostr(COMPS_Object *obj1);
196 
197 /** Increment COMPS_Object derivate reference counter
198  */
199 COMPS_Object* comps_object_incref(COMPS_Object *obj);
200 
201 /** Directly construct COMPS_Num derivate from passed argument
202  * @param n value of COMPS_Num
203  */
204 COMPS_Num* comps_num(int n);
205 
206 /** Directly construct COMPS_Str derivate from passed argument
207  *
208  * passed argument is copied as new allocation
209  * @param s string value of derivate
210  */
211 COMPS_Str* comps_str(const char *s);
212 
213 /** Directly construct COMPS_Str derivate from passed argument
214  *
215  * \warning
216  * passed argument is not copied. COMPS_Str derivate use same memory place as
217  * \a s argument and during destruction of derivate this memory place is freed
218  * @param s string value of derivate
219  */
220 COMPS_Str* comps_str_x(char *s);
221 
222 /** Set memory copy of passed argument as COMPS_Str value
223  *
224  * @param str COMPS_Str object
225  * @param s desired new COMPS_Str object value
226  */
227 void comps_str_set(COMPS_Str *str, char *s);
228 
229 //extern COMPS_ObjectInfo COMPS_Num_ObjInfo;
230 //extern COMPS_ObjectInfo COMPS_Str_ObjInfo;
231 
232 /** Return non-zero if str match the pattern by fnmatch
233  *
234  * @param str source string. COMPS_Str object
235  * @param pattern match pattern
236  */
237 signed char comps_str_fnmatch(COMPS_Str *str, char *pattern, int flags);
238 
239 /** Return non-zero if str match the pattern by fnmatch
240  *
241  * @param str source string. COMPS_Str object
242  * @param pattern COMPS_Str match pattern
243  */
244 signed char comps_str_fnmatch_o(COMPS_Str *str, COMPS_Str *pattern, int flags);
245 
246 #endif
247