Code

* src/dialogs/layers-panel.cpp: Compile fix from Mathieu Dimanche.
[inkscape.git] / src / libcroco / cr-prop-list.c
1 /*
2  * This file is part of The Croco Library
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2.1 of the GNU Lesser General Public
6  * License as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16  * USA
17  *
18  * Author: Dodji Seketeli
19  * See COPYRIGHTS file for copyrights information.
20  */
22 #include <string.h>
23 #include "cr-prop-list.h"
25 #define PRIVATE(a_obj) (a_obj)->priv
27 struct _CRPropListPriv {
28         CRString *prop;
29         CRDeclaration *decl;
30         CRPropList *next;
31         CRPropList *prev;
32 };
34 static CRPropList *cr_prop_list_allocate (void);
36 /**
37  *Default allocator of CRPropList
38  *@return the newly allocated CRPropList or NULL
39  *if an error arises.
40  */
41 static CRPropList *
42 cr_prop_list_allocate (void)
43 {
44         CRPropList *result = NULL;
46         result = g_try_malloc (sizeof (CRPropList));
47         if (!result) {
48                 cr_utils_trace_info ("could not allocate CRPropList");
49                 return NULL;
50         }
51         memset (result, 0, sizeof (CRPropList));
52         PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv));
53         if (!result) {
54                 cr_utils_trace_info ("could not allocate CRPropListPriv");
55                 g_free (result);
56                 return NULL;
57         }
58         memset (PRIVATE (result), 0, sizeof (CRPropListPriv));
59         return result;
60 }
62 /****************
63  *public methods
64  ***************/
66 /**
67  *Appends a property list to the current one.
68  *@param a_this the current instance of #CRPropList
69  *@param a_to_append the property list to append
70  *@return the resulting prop list, or NULL if an error
71  *occured
72  */
73 CRPropList *
74 cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
75 {
76         CRPropList *cur = NULL;
78         g_return_val_if_fail (a_to_append, NULL);
80         if (!a_this)
81                 return a_to_append;
83         /*go fetch the last element of the list */
84         for (cur = a_this;
85              cur && PRIVATE (cur) && PRIVATE (cur)->next;
86              cur = PRIVATE (cur)->next) ;
87         g_return_val_if_fail (cur, NULL);
88         PRIVATE (cur)->next = a_to_append;
89         PRIVATE (a_to_append)->prev = cur;
90         return a_this;
91 }
93 /**
94  *Appends a pair of prop/declaration to
95  *the current prop list.
96  *@param a_this the current instance of #CRPropList
97  *@param a_prop the property to consider
98  *@param a_decl the declaration to consider
99  *@return the resulting property list, or NULL in case
100  *of an error.
101  */
102 CRPropList *
103 cr_prop_list_append2 (CRPropList * a_this,
104                       CRString * a_prop, 
105                       CRDeclaration * a_decl)
107         CRPropList *list = NULL,
108                 *result = NULL;
110         g_return_val_if_fail (a_prop && a_decl, NULL);
112         list = cr_prop_list_allocate ();
113         g_return_val_if_fail (list && PRIVATE (list), NULL);
115         PRIVATE (list)->prop = a_prop;
116         PRIVATE (list)->decl = a_decl;
118         result = cr_prop_list_append (a_this, list);
119         return result;
122 /**
123  *Prepends a list to the current list
124  *@param a_this the current instance of #CRPropList
125  *@param the new list to prepend.
126  */
127 CRPropList *
128 cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
130         CRPropList *cur = NULL;
132         g_return_val_if_fail (a_to_prepend, NULL);
134         if (!a_this)
135                 return a_to_prepend;
137         for (cur = a_to_prepend; cur && PRIVATE (cur)->next;
138              cur = PRIVATE (cur)->next) ;
139         g_return_val_if_fail (cur, NULL);
140         PRIVATE (cur)->next = a_this;
141         PRIVATE (a_this)->prev = cur;
142         return a_to_prepend;
145 /**
146  *Prepends a list to the current list
147  *@param a_this the current instance of #CRPropList
148  *@param the new list to prepend.
149  */
150 CRPropList *
151 cr_prop_list_prepend2 (CRPropList * a_this,
152                        CRString * a_prop, CRDeclaration * a_decl)
154         CRPropList *list = NULL,
155                 *result = NULL;
157         g_return_val_if_fail (a_this && PRIVATE (a_this)
158                               && a_prop && a_decl, NULL);
160         list = cr_prop_list_allocate ();
161         g_return_val_if_fail (list, NULL);
162         PRIVATE (list)->prop = a_prop;
163         PRIVATE (list)->decl = a_decl;
164         result = cr_prop_list_prepend (a_this, list);
165         return result;
168 /**
169  *Sets the property of a CRPropList
170  *@param a_this the current instance of #CRPropList
171  *@param a_prop the property to set
172  */
173 enum CRStatus
174 cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop)
176         g_return_val_if_fail (a_this && PRIVATE (a_this)
177                               && a_prop, CR_BAD_PARAM_ERROR);
179         PRIVATE (a_this)->prop = a_prop;
180         return CR_OK;
183 /**
184  *Getter of the property associated to the current instance
185  *of #CRPropList
186  *@param a_this the current instance of #CRPropList
187  *@param a_prop out parameter. The returned property
188  *@return CR_OK upon successful completion, an error code
189  *otherwise.
190  */
191 enum CRStatus
192 cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop)
194         g_return_val_if_fail (a_this && PRIVATE (a_this)
195                               && a_prop, CR_BAD_PARAM_ERROR);
197         *a_prop = PRIVATE (a_this)->prop;
198         return CR_OK;
201 enum CRStatus
202 cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl)
204         g_return_val_if_fail (a_this && PRIVATE (a_this)
205                               && a_decl, CR_BAD_PARAM_ERROR);
207         PRIVATE (a_this)->decl = a_decl;
208         return CR_OK;
211 enum CRStatus
212 cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl)
214         g_return_val_if_fail (a_this && PRIVATE (a_this)
215                               && a_decl, CR_BAD_PARAM_ERROR);
217         *a_decl = PRIVATE (a_this)->decl;
218         return CR_OK;
221 /**
222  *Lookup a given property/declaration pair
223  *@param a_this the current instance of #CRPropList
224  *@param a_prop the property to lookup
225  *@param a_prop_list out parameter. The property/declaration
226  *pair found (if and only if the function returned code if CR_OK)
227  *@return CR_OK if a prop/decl pair has been found,
228  *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something
229  *bad happens.
230  */
231 enum CRStatus
232 cr_prop_list_lookup_prop (CRPropList * a_this,
233                           CRString * a_prop, CRPropList ** a_pair)
235         CRPropList *cur = NULL;
237         g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
239         if (!a_this)
240                 return CR_VALUE_NOT_FOUND_ERROR;
242         g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
244         for (cur = a_this; cur; cur = PRIVATE (cur)->next) {
245                 if (PRIVATE (cur)->prop
246                     && PRIVATE (cur)->prop->stryng
247                     && PRIVATE (cur)->prop->stryng->str
248                     && a_prop->stryng
249                     && a_prop->stryng->str
250                     && !strcmp (PRIVATE (cur)->prop->stryng->str, 
251                                 a_prop->stryng->str))
252                         break;
253         }
255         if (cur) {
256                 *a_pair = cur;
257                 return CR_OK;
258         }
260         return CR_VALUE_NOT_FOUND_ERROR;
263 /**
264  *Gets the next prop/decl pair in the list
265  *@param a_this the current instance of CRPropList
266  *@param the next prop/decl pair, or NULL if we
267  *reached the end of the list.
268  *@return the next prop/declaration pair of the list, 
269  *or NULL if we reached end of list (or if an error occurs)
270  */
271 CRPropList *
272 cr_prop_list_get_next (CRPropList * a_this)
274         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
276         return PRIVATE (a_this)->next;
279 /**
280  *Gets the previous prop/decl pair in the list
281  *@param a_this the current instance of CRPropList
282  *@param the previous prop/decl pair, or NULL if we
283  *reached the end of the list.
284  *@return the previous prop/declaration pair of the list, 
285  *or NULL if we reached end of list (or if an error occurs)
286  */
287 CRPropList *
288 cr_prop_list_get_prev (CRPropList * a_this)
290         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
292         return PRIVATE (a_this)->prev;
295 /**
296  *Unlinks a prop/decl pair from the list
297  *@param a_this the current list of prop/decl pairs
298  *@param a_pair the prop/decl pair to unlink.
299  *@return the new list or NULL in case of an error.
300  */
301 CRPropList *
302 cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair)
304         CRPropList *prev = NULL,
305                 *next = NULL;
307         g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
309         /*some sanity checks */
310         if (PRIVATE (a_pair)->next) {
311                 next = PRIVATE (a_pair)->next;
312                 g_return_val_if_fail (PRIVATE (next), NULL);
313                 g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL);
314         }
315         if (PRIVATE (a_pair)->prev) {
316                 prev = PRIVATE (a_pair)->prev;
317                 g_return_val_if_fail (PRIVATE (prev), NULL);
318                 g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL);
319         }
320         if (prev) {
321                 PRIVATE (prev)->next = next;
322         }
323         if (next) {
324                 PRIVATE (next)->prev = prev;
325         }
326         PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL;
327         if (a_this == a_pair) {
328                 if (next)
329                         return next;
330                 return NULL;
331         }
332         return a_this;
335 void
336 cr_prop_list_destroy (CRPropList * a_this)
338         CRPropList *tail = NULL,
339                 *cur = NULL;
341         g_return_if_fail (a_this && PRIVATE (a_this));
343         for (tail = a_this;
344              tail && PRIVATE (tail) && PRIVATE (tail)->next;
345              tail = cr_prop_list_get_next (tail)) ;
346         g_return_if_fail (tail);
348         cur = tail;
350         while (cur) {
351                 tail = PRIVATE (cur)->prev;
352                 if (tail && PRIVATE (tail))
353                         PRIVATE (tail)->next = NULL;
354                 PRIVATE (cur)->prev = NULL;
355                 g_free (PRIVATE (cur));
356                 PRIVATE (cur) = NULL;
357                 g_free (cur);
358                 cur = tail;
359         }