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

Generated on Wed Mar 15 18:23:54 2006 for Libcroco by  doxygen 1.4.6