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

Generated on Sat Mar 20 02:38:43 2004 for Libcroco by doxygen 1.3.5