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

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