Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

cr-prop-list.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of The Croco Library
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of version 2.1 of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program; if not, write to the Free Software
00015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00016  * USA
00017  *
00018  * Author: Dodji Seketeli
00019  * See COPYRIGHTS file for copyrights information.
00020  */
00021 
00022 #include <string.h>
00023 #include "cr-prop-list.h"
00024 
00025 #define PRIVATE(a_obj) (a_obj)->priv
00026 
00027 struct _CRPropListPriv {
00028         CRString *prop;
00029         CRDeclaration *decl;
00030         CRPropList *next;
00031         CRPropList *prev;
00032 };
00033 
00034 static CRPropList *cr_prop_list_allocate (void);
00035 
00036 /**
00037  *Default allocator of CRPropList
00038  *@return the newly allocated CRPropList or NULL
00039  *if an error arises.
00040  */
00041 static CRPropList *
00042 cr_prop_list_allocate (void)
00043 {
00044         CRPropList *result = NULL;
00045 
00046         result = g_try_malloc (sizeof (CRPropList));
00047         if (!result) {
00048                 cr_utils_trace_info ("could not allocate CRPropList");
00049                 return NULL;
00050         }
00051         memset (result, 0, sizeof (CRPropList));
00052         PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv));
00053         if (!result) {
00054                 cr_utils_trace_info ("could not allocate CRPropListPriv");
00055                 g_free (result);
00056                 return NULL;
00057         }
00058         memset (PRIVATE (result), 0, sizeof (CRPropListPriv));
00059         return result;
00060 }
00061 
00062 /****************
00063  *public methods
00064  ***************/
00065 
00066 /**
00067  *Appends a property list to the current one.
00068  *@param a_this the current instance of #CRPropList
00069  *@param a_to_append the property list to append
00070  *@return the resulting prop list, or NULL if an error
00071  *occured
00072  */
00073 CRPropList *
00074 cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append)
00075 {
00076         CRPropList *cur = NULL;
00077 
00078         g_return_val_if_fail (a_to_append, NULL);
00079 
00080         if (!a_this)
00081                 return a_to_append;
00082 
00083         /*go fetch the last element of the list */
00084         for (cur = a_this;
00085              cur && PRIVATE (cur) && PRIVATE (cur)->next;
00086              cur = PRIVATE (cur)->next) ;
00087         g_return_val_if_fail (cur, NULL);
00088         PRIVATE (cur)->next = a_to_append;
00089         PRIVATE (a_to_append)->prev = cur;
00090         return a_this;
00091 }
00092 
00093 /**
00094  *Appends a pair of prop/declaration to
00095  *the current prop list.
00096  *@param a_this the current instance of #CRPropList
00097  *@param a_prop the property to consider
00098  *@param a_decl the declaration to consider
00099  *@return the resulting property list, or NULL in case
00100  *of an error.
00101  */
00102 CRPropList *
00103 cr_prop_list_append2 (CRPropList * a_this,
00104                       CRString * a_prop, 
00105                       CRDeclaration * a_decl)
00106 {
00107         CRPropList *list = NULL,
00108                 *result = NULL;
00109 
00110         g_return_val_if_fail (a_prop && a_decl, NULL);
00111 
00112         list = cr_prop_list_allocate ();
00113         g_return_val_if_fail (list && PRIVATE (list), NULL);
00114 
00115         PRIVATE (list)->prop = a_prop;
00116         PRIVATE (list)->decl = a_decl;
00117 
00118         result = cr_prop_list_append (a_this, list);
00119         return result;
00120 }
00121 
00122 /**
00123  *Prepends a list to the current list
00124  *@param a_this the current instance of #CRPropList
00125  *@param the new list to prepend.
00126  */
00127 CRPropList *
00128 cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend)
00129 {
00130         CRPropList *cur = NULL;
00131 
00132         g_return_val_if_fail (a_to_prepend, NULL);
00133 
00134         if (!a_this)
00135                 return a_to_prepend;
00136 
00137         for (cur = a_to_prepend; cur && PRIVATE (cur)->next;
00138              cur = PRIVATE (cur)->next) ;
00139         g_return_val_if_fail (cur, NULL);
00140         PRIVATE (cur)->next = a_this;
00141         PRIVATE (a_this)->prev = cur;
00142         return a_to_prepend;
00143 }
00144 
00145 /**
00146  *Prepends a list to the current list
00147  *@param a_this the current instance of #CRPropList
00148  *@param the new list to prepend.
00149  */
00150 CRPropList *
00151 cr_prop_list_prepend2 (CRPropList * a_this,
00152                        CRString * a_prop, CRDeclaration * a_decl)
00153 {
00154         CRPropList *list = NULL,
00155                 *result = NULL;
00156 
00157         g_return_val_if_fail (a_this && PRIVATE (a_this)
00158                               && a_prop && a_decl, NULL);
00159 
00160         list = cr_prop_list_allocate ();
00161         g_return_val_if_fail (list, NULL);
00162         PRIVATE (list)->prop = a_prop;
00163         PRIVATE (list)->decl = a_decl;
00164         result = cr_prop_list_prepend (a_this, list);
00165         return result;
00166 }
00167 
00168 /**
00169  *Sets the property of a CRPropList
00170  *@param a_this the current instance of #CRPropList
00171  *@param a_prop the property to set
00172  */
00173 enum CRStatus
00174 cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop)
00175 {
00176         g_return_val_if_fail (a_this && PRIVATE (a_this)
00177                               && a_prop, CR_BAD_PARAM_ERROR);
00178 
00179         PRIVATE (a_this)->prop = a_prop;
00180         return CR_OK;
00181 }
00182 
00183 /**
00184  *Getter of the property associated to the current instance
00185  *of #CRPropList
00186  *@param a_this the current instance of #CRPropList
00187  *@param a_prop out parameter. The returned property
00188  *@return CR_OK upon successful completion, an error code
00189  *otherwise.
00190  */
00191 enum CRStatus
00192 cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop)
00193 {
00194         g_return_val_if_fail (a_this && PRIVATE (a_this)
00195                               && a_prop, CR_BAD_PARAM_ERROR);
00196 
00197         *a_prop = PRIVATE (a_this)->prop;
00198         return CR_OK;
00199 }
00200 
00201 enum CRStatus
00202 cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl)
00203 {
00204         g_return_val_if_fail (a_this && PRIVATE (a_this)
00205                               && a_decl, CR_BAD_PARAM_ERROR);
00206 
00207         PRIVATE (a_this)->decl = a_decl;
00208         return CR_OK;
00209 }
00210 
00211 enum CRStatus
00212 cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl)
00213 {
00214         g_return_val_if_fail (a_this && PRIVATE (a_this)
00215                               && a_decl, CR_BAD_PARAM_ERROR);
00216 
00217         *a_decl = PRIVATE (a_this)->decl;
00218         return CR_OK;
00219 }
00220 
00221 /**
00222  *Lookup a given property/declaration pair
00223  *@param a_this the current instance of #CRPropList
00224  *@param a_prop the property to lookup
00225  *@param a_prop_list out parameter. The property/declaration
00226  *pair found (if and only if the function returned code if CR_OK)
00227  *@return CR_OK if a prop/decl pair has been found,
00228  *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something
00229  *bad happens.
00230  */
00231 enum CRStatus
00232 cr_prop_list_lookup_prop (CRPropList * a_this,
00233                           CRString * a_prop, CRPropList ** a_pair)
00234 {
00235         CRPropList *cur = NULL;
00236 
00237         g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR);
00238 
00239         if (!a_this)
00240                 return CR_VALUE_NOT_FOUND_ERROR;
00241 
00242         g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR);
00243 
00244         for (cur = a_this; cur; cur = PRIVATE (cur)->next) {
00245                 if (PRIVATE (cur)->prop
00246                     && PRIVATE (cur)->prop->stryng
00247                     && PRIVATE (cur)->prop->stryng->str
00248                     && a_prop->stryng
00249                     && a_prop->stryng->str
00250                     && !strcmp (PRIVATE (cur)->prop->stryng->str, 
00251                                 a_prop->stryng->str))
00252                         break;
00253         }
00254 
00255         if (cur) {
00256                 *a_pair = cur;
00257                 return CR_OK;
00258         }
00259 
00260         return CR_VALUE_NOT_FOUND_ERROR;
00261 }
00262 
00263 /**
00264  *Gets the next prop/decl pair in the list
00265  *@param a_this the current instance of CRPropList
00266  *@param the next prop/decl pair, or NULL if we
00267  *reached the end of the list.
00268  *@return the next prop/declaration pair of the list, 
00269  *or NULL if we reached end of list (or if an error occurs)
00270  */
00271 CRPropList *
00272 cr_prop_list_get_next (CRPropList * a_this)
00273 {
00274         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
00275 
00276         return PRIVATE (a_this)->next;
00277 }
00278 
00279 /**
00280  *Gets the previous prop/decl pair in the list
00281  *@param a_this the current instance of CRPropList
00282  *@param the previous prop/decl pair, or NULL if we
00283  *reached the end of the list.
00284  *@return the previous prop/declaration pair of the list, 
00285  *or NULL if we reached end of list (or if an error occurs)
00286  */
00287 CRPropList *
00288 cr_prop_list_get_prev (CRPropList * a_this)
00289 {
00290         g_return_val_if_fail (a_this && PRIVATE (a_this), NULL);
00291 
00292         return PRIVATE (a_this)->prev;
00293 }
00294 
00295 /**
00296  *Unlinks a prop/decl pair from the list
00297  *@param a_this the current list of prop/decl pairs
00298  *@param a_pair the prop/decl pair to unlink.
00299  *@return the new list or NULL in case of an error.
00300  */
00301 CRPropList *
00302 cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair)
00303 {
00304         CRPropList *prev = NULL,
00305                 *next = NULL;
00306 
00307         g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL);
00308 
00309         /*some sanity checks */
00310         if (PRIVATE (a_pair)->next) {
00311                 next = PRIVATE (a_pair)->next;
00312                 g_return_val_if_fail (PRIVATE (next), NULL);
00313                 g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL);
00314         }
00315         if (PRIVATE (a_pair)->prev) {
00316                 prev = PRIVATE (a_pair)->prev;
00317                 g_return_val_if_fail (PRIVATE (prev), NULL);
00318                 g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL);
00319         }
00320         if (prev) {
00321                 PRIVATE (prev)->next = next;
00322         }
00323         if (next) {
00324                 PRIVATE (next)->prev = prev;
00325         }
00326         PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL;
00327         if (a_this == a_pair) {
00328                 if (next)
00329                         return next;
00330                 return NULL;
00331         }
00332         return a_this;
00333 }
00334 
00335 void
00336 cr_prop_list_destroy (CRPropList * a_this)
00337 {
00338         CRPropList *tail = NULL,
00339                 *cur = NULL;
00340 
00341         g_return_if_fail (a_this && PRIVATE (a_this));
00342 
00343         for (tail = a_this;
00344              tail && PRIVATE (tail) && PRIVATE (tail)->next;
00345              tail = cr_prop_list_get_next (tail)) ;
00346         g_return_if_fail (tail);
00347 
00348         cur = tail;
00349 
00350         while (cur) {
00351                 tail = PRIVATE (cur)->prev;
00352                 if (tail && PRIVATE (tail))
00353                         PRIVATE (tail)->next = NULL;
00354                 PRIVATE (cur)->prev = NULL;
00355                 g_free (PRIVATE (cur));
00356                 PRIVATE (cur) = NULL;
00357                 g_free (cur);
00358                 cur = tail;
00359         }
00360 }

Generated on Fri Oct 29 08:29:12 2004 for Libcroco by  doxygen 1.3.9.1