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

cr-simple-sel.c

Go to the documentation of this file.
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
00002 
00003 /*
00004  * This file is part of The Croco Library
00005  *
00006  * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org>
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of version 2.1 of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00020  * USA
00021  */
00022 
00023 /*
00024  *$Id: cr-simple-sel.c,v 1.3 2003/05/24 10:42:42 dodji Exp $
00025  */
00026 
00027 #include <string.h>
00028 #include <glib.h>
00029 #include "cr-simple-sel.h"
00030 
00031 
00032 /**
00033  *The constructor of #CRSimpleSel.
00034  *
00035  *@return the new instance of #CRSimpleSel.
00036  */
00037 CRSimpleSel *
00038 cr_simple_sel_new (void)
00039 {
00040         CRSimpleSel *result = NULL ;
00041 
00042         result = g_try_malloc (sizeof (CRSimpleSel)) ;
00043         if (!result)
00044         {
00045                 cr_utils_trace_info ("Out of memory") ;
00046                 return NULL ;
00047         }
00048         memset (result, 0, sizeof (CRSimpleSel)) ;
00049 
00050         return result ;
00051 }
00052 
00053 /**
00054  *Appends a simpe selector to the current list of simple selector.
00055  *
00056  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00057  *@param a_sel the simple selector to append.
00058  *@return the new list upon successfull completion, an error code otherwise.
00059  */
00060 CRSimpleSel *
00061 cr_simple_sel_append_simple_sel (CRSimpleSel *a_this, CRSimpleSel *a_sel)
00062 {
00063         CRSimpleSel *cur = NULL ;
00064 
00065         g_return_val_if_fail (a_sel, NULL) ;
00066 
00067         if (a_this == NULL)
00068                 return a_sel ;
00069 
00070         for (cur = a_this ; cur->next ; cur = cur->next) ;
00071 
00072         cur->next = a_sel ;
00073         a_sel->prev = cur ;
00074 
00075         return a_this ;
00076 }
00077 
00078 /**
00079  *Prepends a simple selector to the current list of simple selectors.
00080  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00081  *@param a_sel the simple selector to prepend.
00082  *@return the new list upon successfull completion, an error code otherwise.
00083  */
00084 CRSimpleSel *
00085 cr_simple_sel_prepend_simple_sel (CRSimpleSel *a_this, CRSimpleSel *a_sel)
00086 {
00087         g_return_val_if_fail (a_sel, NULL) ;
00088 
00089         if (a_this == NULL)
00090                 return a_sel ;
00091 
00092         a_sel->next = a_this ;
00093         a_this->prev = a_sel ;
00094 
00095         return a_sel ;
00096 }
00097 
00098 guchar *
00099 cr_simple_sel_to_string (CRSimpleSel *a_this)
00100 {
00101         GString * str_buf = NULL ;
00102         guchar *result = NULL ;
00103 
00104         CRSimpleSel *cur = NULL ;
00105 
00106         g_return_val_if_fail (a_this,  NULL) ;
00107 
00108         str_buf = g_string_new (NULL) ;
00109         for (cur = a_this ; cur ; cur = cur->next)
00110         {
00111                 if (cur->name)
00112                 {
00113                         guchar * str = g_strndup (cur->name->str, 
00114                                                   cur->name->len) ;
00115                         if (str)
00116                         {
00117                                 switch (cur->combinator)
00118                                 {
00119                                 case COMB_WS:
00120                                         g_string_append_printf 
00121                                                 (str_buf, " ") ;
00122                                         break ;
00123 
00124                                 case COMB_PLUS:
00125                                         g_string_append_printf 
00126                                                 (str_buf, "+") ;
00127                                         break ;
00128 
00129                                 case COMB_GT:
00130                                         g_string_append_printf 
00131                                                 (str_buf, ">") ;
00132                                         break ;
00133 
00134                                 default:
00135                                         break ;
00136                                 }
00137                        
00138                                 g_string_append_printf (str_buf,"%s",str) ;
00139                                 g_free (str) ;
00140                                 str = NULL ;
00141                         }                        
00142                 }
00143 
00144                 if (cur->add_sel)
00145                 {
00146                         guchar *tmp_str = NULL ;
00147                         
00148                         tmp_str = cr_additional_sel_to_string 
00149                                 (cur->add_sel) ;
00150                         if (tmp_str)
00151                         {
00152                                 g_string_append_printf 
00153                                         (str_buf, "%s", tmp_str) ;
00154                                 g_free (tmp_str) ;
00155                                 tmp_str = NULL ;
00156                         }
00157                 }
00158         }
00159 
00160         if (str_buf)
00161         {
00162                 result = str_buf->str ;
00163                 g_string_free (str_buf, FALSE) ;
00164                 str_buf = NULL ;
00165         }
00166 
00167         return result ;
00168 }
00169 
00170 /**
00171  *Dumps the selector to a file.
00172  *TODO: add the support of unicode in the dump.
00173  *
00174  *@param a_this the current instance of #CRSimpleSel.
00175  *@param a_fp the destination file pointer.
00176  *@return CR_OK upon successfull completion, an error code
00177  *otherwise.
00178  */
00179 enum CRStatus
00180 cr_simple_sel_dump (CRSimpleSel *a_this, FILE *a_fp)
00181 {
00182         guchar *tmp_str = NULL ;
00183 
00184         g_return_val_if_fail (a_fp, CR_BAD_PARAM_ERROR) ;
00185 
00186         if (a_this)
00187         {
00188                 tmp_str = cr_simple_sel_to_string (a_this) ;
00189                 if (tmp_str)
00190                 {
00191                         fprintf (a_fp, "%s", tmp_str) ;
00192                         g_free (tmp_str) ;
00193                         tmp_str = NULL ;
00194                 }
00195         }
00196 
00197         return CR_OK ;
00198 }
00199 
00200 /**
00201  *Computes the selector (combinator separated list of simple selectors)
00202  *as defined in the css2 spec in chapter 6.4.3
00203  *@param a_this the current instance of #CRSimpleSel
00204  *@return CR_OK upon successfull completion, an error code otherwise.
00205  */
00206 enum CRStatus
00207 cr_simple_sel_compute_specificity (CRSimpleSel *a_this)
00208 {
00209         CRAdditionalSel *cur_add_sel = NULL ;
00210         CRSimpleSel *cur_sel = NULL ;
00211         gulong a=0, b=0, c=0;
00212 
00213         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00214 
00215         for (cur_sel = a_this ; cur_sel ; cur_sel = cur_sel->next)
00216         {
00217                 if (cur_sel->type_mask | TYPE_SELECTOR)
00218                 {
00219                         c++ ;/*hmmh, is this a new language ?*/
00220                 }
00221                 else if (!cur_sel->name || ! cur_sel->name->str)
00222                 {
00223                         if (cur_sel->add_sel->type == PSEUDO_CLASS_ADD_SELECTOR)
00224                         {
00225                                 /*
00226                                  *this is a pseudo element, and
00227                                  *the spec says, "ignore pseudo elements".
00228                                  */
00229                                 continue ;
00230                         }
00231                 }
00232 
00233                 for (cur_add_sel = cur_sel->add_sel ; 
00234                      cur_add_sel ;
00235                      cur_add_sel = cur_add_sel->next)
00236                 {
00237                         switch (cur_add_sel->type)
00238                         {
00239                         case ID_ADD_SELECTOR:
00240                                 a++ ;
00241                                 break ;
00242 
00243                         case NO_ADD_SELECTOR:
00244                                 continue ;
00245 
00246                         default:
00247                                 b++ ;
00248                                 break ;
00249                         }
00250                 }
00251         }
00252 
00253         /*we suppose a, b and c have 1 to 3 digits*/
00254         a_this->specificity = a * 1000000 + b * 1000 + c;
00255 
00256         return CR_OK ;
00257 }
00258 
00259 /**
00260  *The destructor of the current instance of
00261  *#CRSimpleSel.
00262  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00263  *
00264  */
00265 void
00266 cr_simple_sel_destroy (CRSimpleSel *a_this)
00267 {
00268         g_return_if_fail (a_this) ;
00269 
00270         if (a_this->name)
00271         {
00272                 g_string_free (a_this->name, TRUE) ;
00273                 a_this->name = NULL ;
00274         }
00275 
00276         if (a_this->add_sel)
00277         {
00278                 cr_additional_sel_destroy (a_this->add_sel) ;
00279                 a_this->add_sel = NULL ;
00280         }
00281 
00282         if (a_this->next)
00283         {
00284                 cr_simple_sel_destroy (a_this->next) ;
00285         }
00286 
00287         if (a_this)
00288         {
00289                 g_free (a_this) ;
00290         }
00291 }
00292 

Generated on Wed Oct 1 01:36:47 2003 for Libcroco by doxygen 1.3.3