Libcroco
cr-additional-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 
00025 #include "cr-additional-sel.h"
00026 #include "string.h"
00027 
00028 /**
00029  * CRAdditionalSel:
00030  *
00031  * #CRAdditionalSel abstracts an additionnal selector.
00032  * An additional selector is the selector part
00033  * that comes after the combination of type selectors.
00034  * It can be either "a class selector (the .class part),
00035  * a pseudo class selector, an attribute selector 
00036  * or an id selector.
00037  */
00038 
00039 /**
00040  * cr_additional_sel_new:
00041  *
00042  * Default constructor of #CRAdditionalSel.
00043  * Returns the newly build instance of #CRAdditionalSel.
00044  */
00045 CRAdditionalSel *
00046 cr_additional_sel_new (void)
00047 {
00048         CRAdditionalSel *result = NULL;
00049 
00050         result = g_try_malloc (sizeof (CRAdditionalSel));
00051 
00052         if (result == NULL) {
00053                 cr_utils_trace_debug ("Out of memory");
00054                 return NULL;
00055         }
00056 
00057         memset (result, 0, sizeof (CRAdditionalSel));
00058 
00059         return result;
00060 }
00061 
00062 /**
00063  * cr_additional_sel_new_with_type:
00064  * @a_sel_type: the type of the newly built instance 
00065  * of #CRAdditionalSel.
00066  *
00067  * Constructor of #CRAdditionalSel.
00068  * Returns the newly built instance of #CRAdditionalSel.
00069  */
00070 CRAdditionalSel *
00071 cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type)
00072 {
00073         CRAdditionalSel *result = NULL;
00074 
00075         result = cr_additional_sel_new ();
00076 
00077         g_return_val_if_fail (result, NULL);
00078 
00079         result->type = a_sel_type;
00080 
00081         return result;
00082 }
00083 
00084 /**
00085  * cr_additional_sel_set_class_name:
00086  * @a_this: the "this pointer" of the current instance
00087  * of #CRAdditionalSel .
00088  * @a_class_name: the new class name to set.
00089  *
00090  * Sets a new class name to a
00091  * CLASS additional selector.
00092  */
00093 void
00094 cr_additional_sel_set_class_name (CRAdditionalSel * a_this,
00095                                   CRString * a_class_name)
00096 {
00097         g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR);
00098 
00099         if (a_this->content.class_name) {
00100                 cr_string_destroy (a_this->content.class_name);
00101         }
00102 
00103         a_this->content.class_name = a_class_name;
00104 }
00105 
00106 /**
00107  * cr_additional_sel_set_id_name:
00108  * @a_this: the "this pointer" of the current instance
00109  * of #CRAdditionalSel .
00110  * @a_id: the new id to set.
00111  *
00112  * Sets a new id name to an
00113  * ID additional selector.
00114  */
00115 void
00116 cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id)
00117 {
00118         g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR);
00119 
00120         if (a_this->content.id_name) {
00121                 cr_string_destroy (a_this->content.id_name);
00122         }
00123 
00124         a_this->content.id_name = a_id;
00125 }
00126 
00127 /**
00128  * cr_additional_sel_set_pseudo:
00129  * @a_this: the "this pointer" of the current instance
00130  * of #CRAdditionalSel .
00131  * @a_pseudo: the new pseudo to set.
00132  *
00133  * Sets a new pseudo to a
00134  * PSEUDO additional selector.
00135  */
00136 void
00137 cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo)
00138 {
00139         g_return_if_fail (a_this
00140                           && a_this->type == PSEUDO_CLASS_ADD_SELECTOR);
00141 
00142         if (a_this->content.pseudo) {
00143                 cr_pseudo_destroy (a_this->content.pseudo);
00144         }
00145 
00146         a_this->content.pseudo = a_pseudo;
00147 }
00148 
00149 /**
00150  * cr_additional_sel_set_attr_sel:
00151  * @a_this: the "this pointer" of the current instance
00152  * of #CRAdditionalSel .
00153  * @a_sel: the new instance of #CRAttrSel to set.
00154  *
00155  * Sets a new instance of #CRAttrSel to 
00156  * a ATTRIBUTE additional selector.
00157  */
00158 void
00159 cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel)
00160 {
00161         g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR);
00162 
00163         if (a_this->content.attr_sel) {
00164                 cr_attr_sel_destroy (a_this->content.attr_sel);
00165         }
00166 
00167         a_this->content.attr_sel = a_sel;
00168 }
00169 
00170 /**
00171  * cr_additional_sel_append:
00172  * @a_this: the "this pointer" of the current instance
00173  * of #CRAdditionalSel .
00174  * @a_sel: the new instance to #CRAdditional to append.
00175  *
00176  * Appends a new instance of #CRAdditional to the
00177  * current list of #CRAdditional.
00178  *
00179  * Returns the new list of CRAdditionalSel or NULL if an error arises.
00180  */
00181 CRAdditionalSel *
00182 cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
00183 {
00184         CRAdditionalSel *cur_sel = NULL;
00185 
00186         g_return_val_if_fail (a_sel, NULL);
00187 
00188         if (a_this == NULL) {
00189                 return a_sel;
00190         }
00191 
00192         if (a_sel == NULL)
00193                 return NULL;
00194 
00195         for (cur_sel = a_this;
00196              cur_sel && cur_sel->next; cur_sel = cur_sel->next) ;
00197 
00198         g_return_val_if_fail (cur_sel != NULL, NULL);
00199 
00200         cur_sel->next = a_sel;
00201         a_sel->prev = cur_sel;
00202 
00203         return a_this;
00204 }
00205 
00206 /**
00207  * cr_additional_sel_prepend:
00208  * @a_this: the "this pointer" of the current instance
00209  * of #CRAdditionalSel .
00210  * @a_sel: the new instance to #CRAdditional to preappend.
00211  *
00212  * Preppends a new instance of #CRAdditional to the
00213  * current list of #CRAdditional.
00214  *
00215  * Returns the new list of CRAdditionalSel or NULL if an error arises.
00216  */
00217 CRAdditionalSel *
00218 cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
00219 {
00220         g_return_val_if_fail (a_sel, NULL);
00221 
00222         if (a_this == NULL) {
00223                 return a_sel;
00224         }
00225 
00226         a_sel->next = a_this;
00227         a_this->prev = a_sel;
00228 
00229         return a_sel;
00230 }
00231 
00232 guchar *
00233 cr_additional_sel_to_string (CRAdditionalSel const * a_this)
00234 {
00235         guchar *result = NULL;
00236         GString *str_buf = NULL;
00237         CRAdditionalSel const *cur = NULL;
00238 
00239         g_return_val_if_fail (a_this, NULL);
00240 
00241         str_buf = g_string_new (NULL);
00242 
00243         for (cur = a_this; cur; cur = cur->next) {
00244                 switch (cur->type) {
00245                 case CLASS_ADD_SELECTOR:
00246                         {
00247                                 guchar *name = NULL;
00248 
00249                                 if (cur->content.class_name) {
00250                                         name = g_strndup
00251                                                 (cur->content.class_name->stryng->str,
00252                                                  cur->content.class_name->stryng->len);
00253 
00254                                         if (name) {
00255                                                 g_string_append_printf
00256                                                         (str_buf, ".%s",
00257                                                          name);
00258                                                 g_free (name);
00259                                                 name = NULL;
00260                                         }
00261                                 }
00262                         }
00263                         break;
00264 
00265                 case ID_ADD_SELECTOR:
00266                         {
00267                                 guchar *name = NULL;
00268 
00269                                 if (cur->content.class_name) {
00270                                         name = g_strndup
00271                                                 (cur->content.id_name->stryng->str,
00272                                                  cur->content.id_name->stryng->len);
00273 
00274                                         if (name) {
00275                                                 g_string_append_printf
00276                                                         (str_buf, "#%s",
00277                                                          name);
00278                                                 g_free (name);
00279                                                 name = NULL;
00280                                         }
00281                                 }
00282                         }
00283 
00284                         break;
00285 
00286                 case PSEUDO_CLASS_ADD_SELECTOR:
00287                         {
00288                                 if (cur->content.pseudo) {
00289                                         guchar *tmp_str = NULL;
00290 
00291                                         tmp_str = cr_pseudo_to_string
00292                                                 (cur->content.pseudo);
00293                                         if (tmp_str) {
00294                                                 g_string_append_printf
00295                                                         (str_buf, ":%s",
00296                                                          tmp_str);
00297                                                 g_free (tmp_str);
00298                                                 tmp_str = NULL;
00299                                         }
00300                                 }
00301                         }
00302                         break;
00303 
00304                 case ATTRIBUTE_ADD_SELECTOR:
00305                         if (cur->content.attr_sel) {
00306                                 guchar *tmp_str = NULL;
00307 
00308                                 g_string_append_c (str_buf, '[');
00309                                 tmp_str = cr_attr_sel_to_string
00310                                         (cur->content.attr_sel);
00311                                 if (tmp_str) {
00312                                         g_string_append_printf
00313                                                 (str_buf, "%s]", tmp_str);
00314                                         g_free (tmp_str);
00315                                         tmp_str = NULL;
00316                                 }
00317                         }
00318                         break;
00319 
00320                 default:
00321                         break;
00322                 }
00323         }
00324 
00325         if (str_buf) {
00326                 result = str_buf->str;
00327                 g_string_free (str_buf, FALSE);
00328                 str_buf = NULL;
00329         }
00330 
00331         return result;
00332 }
00333 
00334 guchar * 
00335 cr_additional_sel_one_to_string (CRAdditionalSel const *a_this)
00336 {
00337         guchar *result = NULL;
00338         GString *str_buf = NULL;
00339 
00340         g_return_val_if_fail (a_this, NULL) ;
00341 
00342         str_buf = g_string_new (NULL) ;
00343 
00344         switch (a_this->type) {
00345         case CLASS_ADD_SELECTOR:
00346         {
00347                 guchar *name = NULL;
00348 
00349                 if (a_this->content.class_name) {
00350                         name = g_strndup
00351                                 (a_this->content.class_name->stryng->str,
00352                                  a_this->content.class_name->stryng->len);
00353 
00354                         if (name) {
00355                                 g_string_append_printf
00356                                         (str_buf, ".%s",
00357                                          name);
00358                                 g_free (name);
00359                                 name = NULL;
00360                         }
00361                 }
00362         }
00363         break;
00364 
00365         case ID_ADD_SELECTOR:
00366         {
00367                 guchar *name = NULL;
00368 
00369                 if (a_this->content.class_name) {
00370                         name = g_strndup
00371                                 (a_this->content.id_name->stryng->str,
00372                                  a_this->content.id_name->stryng->len);
00373 
00374                         if (name) {
00375                                 g_string_append_printf
00376                                         (str_buf, "#%s",
00377                                          name);
00378                                 g_free (name);
00379                                 name = NULL;
00380                         }
00381                 }
00382         }
00383 
00384         break;
00385 
00386         case PSEUDO_CLASS_ADD_SELECTOR:
00387         {
00388                 if (a_this->content.pseudo) {
00389                         guchar *tmp_str = NULL;
00390 
00391                         tmp_str = cr_pseudo_to_string
00392                                 (a_this->content.pseudo);
00393                         if (tmp_str) {
00394                                 g_string_append_printf
00395                                         (str_buf, ":%s",
00396                                          tmp_str);
00397                                 g_free (tmp_str);
00398                                 tmp_str = NULL;
00399                         }
00400                 }
00401         }
00402         break;
00403 
00404         case ATTRIBUTE_ADD_SELECTOR:
00405                 if (a_this->content.attr_sel) {
00406                         guchar *tmp_str = NULL;
00407 
00408                         g_string_append_printf (str_buf, "[");
00409                         tmp_str = cr_attr_sel_to_string
00410                                 (a_this->content.attr_sel);
00411                         if (tmp_str) {
00412                                 g_string_append_printf
00413                                         (str_buf, "%s]", tmp_str);
00414                                 g_free (tmp_str);
00415                                 tmp_str = NULL;
00416                         }
00417                 }
00418                 break;
00419 
00420         default:
00421                 break;
00422         }
00423 
00424         if (str_buf) {
00425                 result = str_buf->str;
00426                 g_string_free (str_buf, FALSE);
00427                 str_buf = NULL;
00428         }
00429 
00430         return result;
00431 }
00432 
00433 /**
00434  * cr_additional_sel_dump:
00435  * @a_this: the "this pointer" of the current instance of
00436  * #CRAdditionalSel.
00437  * @a_fp: the destination file.
00438  *
00439  * Dumps the current instance of #CRAdditionalSel to a file
00440  */
00441 void
00442 cr_additional_sel_dump (CRAdditionalSel const * a_this, FILE * a_fp)
00443 {
00444         guchar *tmp_str = NULL;
00445 
00446         g_return_if_fail (a_fp);
00447 
00448         if (a_this) {
00449                 tmp_str = cr_additional_sel_to_string (a_this);
00450                 if (tmp_str) {
00451                         fprintf (a_fp, "%s", tmp_str);
00452                         g_free (tmp_str);
00453                         tmp_str = NULL;
00454                 }
00455         }
00456 }
00457 
00458 /**
00459  * cr_additional_sel_destroy:
00460  * @a_this: the "this pointer" of the current instance
00461  * of #CRAdditionalSel .
00462  *
00463  * Destroys an instance of #CRAdditional.
00464  */
00465 void
00466 cr_additional_sel_destroy (CRAdditionalSel * a_this)
00467 {
00468         g_return_if_fail (a_this);
00469 
00470         switch (a_this->type) {
00471         case CLASS_ADD_SELECTOR:
00472                 cr_string_destroy (a_this->content.class_name);
00473                 a_this->content.class_name = NULL;
00474                 break;
00475 
00476         case PSEUDO_CLASS_ADD_SELECTOR:
00477                 cr_pseudo_destroy (a_this->content.pseudo);
00478                 a_this->content.pseudo = NULL;
00479                 break;
00480 
00481         case ID_ADD_SELECTOR:
00482                 cr_string_destroy (a_this->content.id_name);
00483                 a_this->content.id_name = NULL;
00484                 break;
00485 
00486         case ATTRIBUTE_ADD_SELECTOR:
00487                 cr_attr_sel_destroy (a_this->content.attr_sel);
00488                 a_this->content.attr_sel = NULL;
00489                 break;
00490 
00491         default:
00492                 break;
00493         }
00494 
00495         if (a_this->next) {
00496                 cr_additional_sel_destroy (a_this->next);
00497         }
00498 
00499         g_free (a_this);
00500 }