PageRenderTime 26ms CodeModel.GetById 9ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/cssed-0.4.0/libcroco/parser/cr-prop-list.c

#
C | 360 lines | 209 code | 50 blank | 101 comment | 52 complexity | ed155a0de65443330520724843ea7df4 MD5 | raw file
  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 */
 21
 22#include <string.h>
 23#include "cr-prop-list.h"
 24
 25#define PRIVATE(a_obj) (a_obj)->priv
 26
 27struct _CRPropListPriv {
 28        CRString *prop;
 29        CRDeclaration *decl;
 30        CRPropList *next;
 31        CRPropList *prev;
 32};
 33
 34static CRPropList *cr_prop_list_allocate (void);
 35
 36/**
 37 *Default allocator of CRPropList
 38 *@return the newly allocated CRPropList or NULL
 39 *if an error arises.
 40 */
 41static CRPropList *
 42cr_prop_list_allocate (void)
 43{
 44        CRPropList *result = NULL;
 45
 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}
 61
 62/****************
 63 *public methods
 64 ***************/
 65
 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 */
 73CRPropList *
 74cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
 75{
 76        CRPropList *cur = NULL;
 77
 78        g_return_val_if_fail (a_to_append, NULL);
 79
 80        if (!a_this)
 81                return a_to_append;
 82
 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}
 92
 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 */
102CRPropList *
103cr_prop_list_append2 (CRPropList * a_this,
104                      CRString * a_prop, 
105		      CRDeclaration * a_decl)
106{
107        CRPropList *list = NULL,
108                *result = NULL;
109
110        g_return_val_if_fail (a_prop && a_decl, NULL);
111
112        list = cr_prop_list_allocate ();
113        g_return_val_if_fail (list && PRIVATE (list), NULL);
114
115        PRIVATE (list)->prop = a_prop;
116        PRIVATE (list)->decl = a_decl;
117
118        result = cr_prop_list_append (a_this, list);
119        return result;
120}
121
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 */
127CRPropList *
128cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
129{
130        CRPropList *cur = NULL;
131
132        g_return_val_if_fail (a_to_prepend, NULL);
133
134        if (!a_this)
135                return a_to_prepend;
136
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;
143}
144
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 */
150CRPropList *
151cr_prop_list_prepend2 (CRPropList * a_this,
152                       CRString * a_prop, CRDeclaration * a_decl)
153{
154        CRPropList *list = NULL,
155                *result = NULL;
156
157        g_return_val_if_fail (a_this && PRIVATE (a_this)
158                              && a_prop && a_decl, NULL);
159
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;
166}
167
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 */
173enum CRStatus
174cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop)
175{
176        g_return_val_if_fail (a_this && PRIVATE (a_this)
177                              && a_prop, CR_BAD_PARAM_ERROR);
178
179        PRIVATE (a_this)->prop = a_prop;
180        return CR_OK;
181}
182
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 */
191enum CRStatus
192cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop)
193{
194        g_return_val_if_fail (a_this && PRIVATE (a_this)
195                              && a_prop, CR_BAD_PARAM_ERROR);
196
197        *a_prop = PRIVATE (a_this)->prop;
198        return CR_OK;
199}
200
201enum CRStatus
202cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl)
203{
204        g_return_val_if_fail (a_this && PRIVATE (a_this)
205                              && a_decl, CR_BAD_PARAM_ERROR);
206
207        PRIVATE (a_this)->decl = a_decl;
208        return CR_OK;
209}
210
211enum CRStatus
212cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl)
213{
214        g_return_val_if_fail (a_this && PRIVATE (a_this)
215                              && a_decl, CR_BAD_PARAM_ERROR);
216
217        *a_decl = PRIVATE (a_this)->decl;
218        return CR_OK;
219}
220
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 */
231enum CRStatus
232cr_prop_list_lookup_prop (CRPropList * a_this,
233                          CRString * a_prop, CRPropList ** a_pair)
234{
235        CRPropList *cur = NULL;
236
237        g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
238
239        if (!a_this)
240                return CR_VALUE_NOT_FOUND_ERROR;
241
242        g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
243
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        }
254
255        if (cur) {
256                *a_pair = cur;
257                return CR_OK;
258        }
259
260        return CR_VALUE_NOT_FOUND_ERROR;
261}
262
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 */
271CRPropList *
272cr_prop_list_get_next (CRPropList * a_this)
273{
274        g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
275
276        return PRIVATE (a_this)->next;
277}
278
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 */
287CRPropList *
288cr_prop_list_get_prev (CRPropList * a_this)
289{
290        g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
291
292        return PRIVATE (a_this)->prev;
293}
294
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 */
301CRPropList *
302cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair)
303{
304        CRPropList *prev = NULL,
305                *next = NULL;
306
307        g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
308
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;
333}
334
335void
336cr_prop_list_destroy (CRPropList * a_this)
337{
338        CRPropList *tail = NULL,
339                *cur = NULL;
340
341        g_return_if_fail (a_this && PRIVATE (a_this));
342
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);
347
348        cur = tail;
349
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        }
360}