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.6 2004/03/07 13:22:47 dodji Exp $
00025  */
00026 
00027 #include <string.h>
00028 #include <glib.h>
00029 #include "cr-simple-sel.h"
00030 
00031 /**
00032  *The constructor of #CRSimpleSel.
00033  *
00034  *@return the new instance of #CRSimpleSel.
00035  */
00036 CRSimpleSel *
00037 cr_simple_sel_new (void)
00038 {
00039         CRSimpleSel *result = NULL;
00040 
00041         result = g_try_malloc (sizeof (CRSimpleSel));
00042         if (!result) {
00043                 cr_utils_trace_info ("Out of memory");
00044                 return NULL;
00045         }
00046         memset (result, 0, sizeof (CRSimpleSel));
00047 
00048         return result;
00049 }
00050 
00051 /**
00052  *Appends a simpe selector to the current list of simple selector.
00053  *
00054  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00055  *@param a_sel the simple selector to append.
00056  *@return the new list upon successfull completion, an error code otherwise.
00057  */
00058 CRSimpleSel *
00059 cr_simple_sel_append_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel)
00060 {
00061         CRSimpleSel *cur = NULL;
00062 
00063         g_return_val_if_fail (a_sel, NULL);
00064 
00065         if (a_this == NULL)
00066                 return a_sel;
00067 
00068         for (cur = a_this; cur->next; cur = cur->next) ;
00069 
00070         cur->next = a_sel;
00071         a_sel->prev = cur;
00072 
00073         return a_this;
00074 }
00075 
00076 /**
00077  *Prepends a simple selector to the current list of simple selectors.
00078  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00079  *@param a_sel the simple selector to prepend.
00080  *@return the new list upon successfull completion, an error code otherwise.
00081  */
00082 CRSimpleSel *
00083 cr_simple_sel_prepend_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel)
00084 {
00085         g_return_val_if_fail (a_sel, NULL);
00086 
00087         if (a_this == NULL)
00088                 return a_sel;
00089 
00090         a_sel->next = a_this;
00091         a_this->prev = a_sel;
00092 
00093         return a_sel;
00094 }
00095 
00096 guchar *
00097 cr_simple_sel_to_string (CRSimpleSel * a_this)
00098 {
00099         GString *str_buf = NULL;
00100         guchar *result = NULL;
00101 
00102         CRSimpleSel *cur = NULL;
00103 
00104         g_return_val_if_fail (a_this, NULL);
00105 
00106         str_buf = g_string_new (NULL);
00107         for (cur = a_this; cur; cur = cur->next) {
00108                 if (cur->name) {
00109                         guchar *str = g_strndup (cur->name->str,
00110                                                  cur->name->len);
00111 
00112                         if (str) {
00113                                 switch (cur->combinator) {
00114                                 case COMB_WS:
00115                                         g_string_append_printf (str_buf, " ");
00116                                         break;
00117 
00118                                 case COMB_PLUS:
00119                                         g_string_append_printf (str_buf, "+");
00120                                         break;
00121 
00122                                 case COMB_GT:
00123                                         g_string_append_printf (str_buf, ">");
00124                                         break;
00125 
00126                                 default:
00127                                         break;
00128                                 }
00129 
00130                                 g_string_append_printf (str_buf, "%s", str);
00131                                 g_free (str);
00132                                 str = NULL;
00133                         }
00134                 }
00135 
00136                 if (cur->add_sel) {
00137                         guchar *tmp_str = NULL;
00138 
00139                         tmp_str = cr_additional_sel_to_string (cur->add_sel);
00140                         if (tmp_str) {
00141                                 g_string_append_printf
00142                                         (str_buf, "%s", tmp_str);
00143                                 g_free (tmp_str);
00144                                 tmp_str = NULL;
00145                         }
00146                 }
00147         }
00148 
00149         if (str_buf) {
00150                 result = str_buf->str;
00151                 g_string_free (str_buf, FALSE);
00152                 str_buf = NULL;
00153         }
00154 
00155         return result;
00156 }
00157 
00158 /**
00159  *Dumps the selector to a file.
00160  *TODO: add the support of unicode in the dump.
00161  *
00162  *@param a_this the current instance of #CRSimpleSel.
00163  *@param a_fp the destination file pointer.
00164  *@return CR_OK upon successfull completion, an error code
00165  *otherwise.
00166  */
00167 enum CRStatus
00168 cr_simple_sel_dump (CRSimpleSel * a_this, FILE * a_fp)
00169 {
00170         guchar *tmp_str = NULL;
00171 
00172         g_return_val_if_fail (a_fp, CR_BAD_PARAM_ERROR);
00173 
00174         if (a_this) {
00175                 tmp_str = cr_simple_sel_to_string (a_this);
00176                 if (tmp_str) {
00177                         fprintf (a_fp, "%s", tmp_str);
00178                         g_free (tmp_str);
00179                         tmp_str = NULL;
00180                 }
00181         }
00182 
00183         return CR_OK;
00184 }
00185 
00186 /**
00187  *Computes the selector (combinator separated list of simple selectors)
00188  *as defined in the css2 spec in chapter 6.4.3
00189  *@param a_this the current instance of #CRSimpleSel
00190  *@return CR_OK upon successfull completion, an error code otherwise.
00191  */
00192 enum CRStatus
00193 cr_simple_sel_compute_specificity (CRSimpleSel * a_this)
00194 {
00195         CRAdditionalSel *cur_add_sel = NULL;
00196         CRSimpleSel *cur_sel = NULL;
00197         gulong a = 0,
00198                 b = 0,
00199                 c = 0;
00200 
00201         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00202 
00203         for (cur_sel = a_this; cur_sel; cur_sel = cur_sel->next) {
00204                 if (cur_sel->type_mask | TYPE_SELECTOR) {
00205                         c++;    /*hmmh, is this a new language ? */
00206                 } else if (!cur_sel->name || !cur_sel->name->str) {
00207                         if (cur_sel->add_sel->type ==
00208                             PSEUDO_CLASS_ADD_SELECTOR) {
00209                                 /*
00210                                  *this is a pseudo element, and
00211                                  *the spec says, "ignore pseudo elements".
00212                                  */
00213                                 continue;
00214                         }
00215                 }
00216 
00217                 for (cur_add_sel = cur_sel->add_sel;
00218                      cur_add_sel; cur_add_sel = cur_add_sel->next) {
00219                         switch (cur_add_sel->type) {
00220                         case ID_ADD_SELECTOR:
00221                                 a++;
00222                                 break;
00223 
00224                         case NO_ADD_SELECTOR:
00225                                 continue;
00226 
00227                         default:
00228                                 b++;
00229                                 break;
00230                         }
00231                 }
00232         }
00233 
00234         /*we suppose a, b and c have 1 to 3 digits */
00235         a_this->specificity = a * 1000000 + b * 1000 + c;
00236 
00237         return CR_OK;
00238 }
00239 
00240 /**
00241  *The destructor of the current instance of
00242  *#CRSimpleSel.
00243  *@param a_this the this pointer of the current instance of #CRSimpleSel.
00244  *
00245  */
00246 void
00247 cr_simple_sel_destroy (CRSimpleSel * a_this)
00248 {
00249         g_return_if_fail (a_this);
00250 
00251         if (a_this->name) {
00252                 g_string_free (a_this->name, TRUE);
00253                 a_this->name = NULL;
00254         }
00255 
00256         if (a_this->add_sel) {
00257                 cr_additional_sel_destroy (a_this->add_sel);
00258                 a_this->add_sel = NULL;
00259         }
00260 
00261         if (a_this->next) {
00262                 cr_simple_sel_destroy (a_this->next);
00263         }
00264 
00265         if (a_this) {
00266                 g_free (a_this);
00267         }
00268 }

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