(root)/
gettext-0.22.4/
libtextstyle/
lib/
libcroco/
cr-additional-sel.c
       1  /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
       2  
       3  /* libcroco - Library for parsing and applying CSS
       4   * Copyright (C) 2006-2019 Free Software Foundation, Inc.
       5   *
       6   * This file is not part of the GNU gettext program, but is used with
       7   * GNU gettext.
       8   *
       9   * The original copyright notice is as follows:
      10   */
      11  
      12  /*
      13   * This file is part of The Croco Library
      14   *
      15   * Copyright (C) 2003-2004 Dodji Seketeli.  All Rights Reserved.
      16   *
      17   * This program is free software; you can redistribute it and/or
      18   * modify it under the terms of version 2.1 of the GNU Lesser General Public
      19   * License as published by the Free Software Foundation.
      20   *
      21   * This program is distributed in the hope that it will be useful,
      22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24   * GNU General Public License for more details.
      25   *
      26   * You should have received a copy of the GNU Lesser General Public License
      27   * along with this program; if not, write to the Free Software
      28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      29   * USA
      30   *
      31   * Author: Dodji Seketeli
      32   *
      33   */
      34  
      35  #include <config.h>
      36  #include "cr-additional-sel.h"
      37  #include "string.h"
      38  
      39  /**
      40   * CRAdditionalSel:
      41   *
      42   * #CRAdditionalSel abstracts an additionnal selector.
      43   * An additional selector is the selector part
      44   * that comes after the combination of type selectors.
      45   * It can be either "a class selector (the .class part),
      46   * a pseudo class selector, an attribute selector 
      47   * or an id selector.
      48   */
      49  
      50  /**
      51   * cr_additional_sel_new:
      52   *
      53   * Default constructor of #CRAdditionalSel.
      54   * Returns the newly build instance of #CRAdditionalSel.
      55   */
      56  CRAdditionalSel *
      57  cr_additional_sel_new (void)
      58  {
      59          CRAdditionalSel *result = NULL;
      60  
      61          result = g_try_malloc (sizeof (CRAdditionalSel));
      62  
      63          if (result == NULL) {
      64                  cr_utils_trace_debug ("Out of memory");
      65                  return NULL;
      66          }
      67  
      68          memset (result, 0, sizeof (CRAdditionalSel));
      69  
      70          return result;
      71  }
      72  
      73  /**
      74   * cr_additional_sel_new_with_type:
      75   * @a_sel_type: the type of the newly built instance 
      76   * of #CRAdditionalSel.
      77   *
      78   * Constructor of #CRAdditionalSel.
      79   * Returns the newly built instance of #CRAdditionalSel.
      80   */
      81  CRAdditionalSel *
      82  cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type)
      83  {
      84          CRAdditionalSel *result = NULL;
      85  
      86          result = cr_additional_sel_new ();
      87  
      88          g_return_val_if_fail (result, NULL);
      89  
      90          result->type = a_sel_type;
      91  
      92          return result;
      93  }
      94  
      95  /**
      96   * cr_additional_sel_set_class_name:
      97   * @a_this: the "this pointer" of the current instance
      98   * of #CRAdditionalSel .
      99   * @a_class_name: the new class name to set.
     100   *
     101   * Sets a new class name to a
     102   * CLASS additional selector.
     103   */
     104  void
     105  cr_additional_sel_set_class_name (CRAdditionalSel * a_this,
     106                                    CRString * a_class_name)
     107  {
     108          g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR);
     109  
     110          if (a_this->content.class_name) {
     111                  cr_string_destroy (a_this->content.class_name);
     112          }
     113  
     114          a_this->content.class_name = a_class_name;
     115  }
     116  
     117  /**
     118   * cr_additional_sel_set_id_name:
     119   * @a_this: the "this pointer" of the current instance
     120   * of #CRAdditionalSel .
     121   * @a_id: the new id to set.
     122   *
     123   * Sets a new id name to an
     124   * ID additional selector.
     125   */
     126  void
     127  cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id)
     128  {
     129          g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR);
     130  
     131          if (a_this->content.id_name) {
     132                  cr_string_destroy (a_this->content.id_name);
     133          }
     134  
     135          a_this->content.id_name = a_id;
     136  }
     137  
     138  /**
     139   * cr_additional_sel_set_pseudo:
     140   * @a_this: the "this pointer" of the current instance
     141   * of #CRAdditionalSel .
     142   * @a_pseudo: the new pseudo to set.
     143   *
     144   * Sets a new pseudo to a
     145   * PSEUDO additional selector.
     146   */
     147  void
     148  cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo)
     149  {
     150          g_return_if_fail (a_this
     151                            && a_this->type == PSEUDO_CLASS_ADD_SELECTOR);
     152  
     153          if (a_this->content.pseudo) {
     154                  cr_pseudo_destroy (a_this->content.pseudo);
     155          }
     156  
     157          a_this->content.pseudo = a_pseudo;
     158  }
     159  
     160  /**
     161   * cr_additional_sel_set_attr_sel:
     162   * @a_this: the "this pointer" of the current instance
     163   * of #CRAdditionalSel .
     164   * @a_sel: the new instance of #CRAttrSel to set.
     165   *
     166   * Sets a new instance of #CRAttrSel to 
     167   * a ATTRIBUTE additional selector.
     168   */
     169  void
     170  cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel)
     171  {
     172          g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR);
     173  
     174          if (a_this->content.attr_sel) {
     175                  cr_attr_sel_destroy (a_this->content.attr_sel);
     176          }
     177  
     178          a_this->content.attr_sel = a_sel;
     179  }
     180  
     181  /**
     182   * cr_additional_sel_append:
     183   * @a_this: the "this pointer" of the current instance
     184   * of #CRAdditionalSel .
     185   * @a_sel: the new instance to #CRAdditional to append.
     186   *
     187   * Appends a new instance of #CRAdditional to the
     188   * current list of #CRAdditional.
     189   *
     190   * Returns the new list of CRAdditionalSel or NULL if an error arises.
     191   */
     192  CRAdditionalSel *
     193  cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
     194  {
     195          CRAdditionalSel *cur_sel = NULL;
     196  
     197          g_return_val_if_fail (a_sel, NULL);
     198  
     199          if (a_this == NULL) {
     200                  return a_sel;
     201          }
     202  
     203          if (a_sel == NULL)
     204                  return NULL;
     205  
     206          for (cur_sel = a_this;
     207               cur_sel && cur_sel->next; cur_sel = cur_sel->next) ;
     208  
     209          g_return_val_if_fail (cur_sel != NULL, NULL);
     210  
     211          cur_sel->next = a_sel;
     212          a_sel->prev = cur_sel;
     213  
     214          return a_this;
     215  }
     216  
     217  /**
     218   * cr_additional_sel_prepend:
     219   * @a_this: the "this pointer" of the current instance
     220   * of #CRAdditionalSel .
     221   * @a_sel: the new instance to #CRAdditional to preappend.
     222   *
     223   * Preppends a new instance of #CRAdditional to the
     224   * current list of #CRAdditional.
     225   *
     226   * Returns the new list of CRAdditionalSel or NULL if an error arises.
     227   */
     228  CRAdditionalSel *
     229  cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
     230  {
     231          g_return_val_if_fail (a_sel, NULL);
     232  
     233          if (a_this == NULL) {
     234                  return a_sel;
     235          }
     236  
     237          a_sel->next = a_this;
     238          a_this->prev = a_sel;
     239  
     240          return a_sel;
     241  }
     242  
     243  guchar *
     244  cr_additional_sel_to_string (CRAdditionalSel const * a_this)
     245  {
     246          guchar *result = NULL;
     247          GString *str_buf = NULL;
     248          CRAdditionalSel const *cur = NULL;
     249  
     250          g_return_val_if_fail (a_this, NULL);
     251  
     252          str_buf = g_string_new (NULL);
     253  
     254          for (cur = a_this; cur; cur = cur->next) {
     255                  switch (cur->type) {
     256                  case CLASS_ADD_SELECTOR:
     257                          {
     258                                  guchar *name = NULL;
     259  
     260                                  if (cur->content.class_name) {
     261                                          name = (guchar *) g_strndup
     262                                                  (cur->content.class_name->stryng->str,
     263                                                   cur->content.class_name->stryng->len);
     264  
     265                                          if (name) {
     266                                                  g_string_append_printf
     267                                                          (str_buf, ".%s",
     268                                                           name);
     269                                                  g_free (name);
     270                                                  name = NULL;
     271                                          }
     272                                  }
     273                          }
     274                          break;
     275  
     276                  case ID_ADD_SELECTOR:
     277                          {
     278                                  guchar *name = NULL;
     279  
     280                                  if (cur->content.id_name) {
     281                                          name = (guchar *) g_strndup
     282                                                  (cur->content.id_name->stryng->str,
     283                                                   cur->content.id_name->stryng->len);
     284  
     285                                          if (name) {
     286                                                  g_string_append_printf
     287                                                          (str_buf, "#%s",
     288                                                           name);
     289                                                  g_free (name);
     290                                                  name = NULL;
     291                                          }
     292                                  }
     293                          }
     294  
     295                          break;
     296  
     297                  case PSEUDO_CLASS_ADD_SELECTOR:
     298                          {
     299                                  if (cur->content.pseudo) {
     300                                          guchar *tmp_str = NULL;
     301  
     302                                          tmp_str = cr_pseudo_to_string
     303                                                  (cur->content.pseudo);
     304                                          if (tmp_str) {
     305                                                  g_string_append_printf
     306                                                          (str_buf, ":%s",
     307                                                           tmp_str);
     308                                                  g_free (tmp_str);
     309                                                  tmp_str = NULL;
     310                                          }
     311                                  }
     312                          }
     313                          break;
     314  
     315                  case ATTRIBUTE_ADD_SELECTOR:
     316                          if (cur->content.attr_sel) {
     317                                  guchar *tmp_str = NULL;
     318  
     319                                  g_string_append_c (str_buf, '[');
     320                                  tmp_str = cr_attr_sel_to_string
     321                                          (cur->content.attr_sel);
     322                                  if (tmp_str) {
     323                                          g_string_append_printf
     324                                                  (str_buf, "%s]", tmp_str);
     325                                          g_free (tmp_str);
     326                                          tmp_str = NULL;
     327                                  }
     328                          }
     329                          break;
     330  
     331                  default:
     332                          break;
     333                  }
     334          }
     335  
     336          if (str_buf) {
     337                  result = (guchar *) str_buf->str;
     338                  g_string_free (str_buf, FALSE);
     339                  str_buf = NULL;
     340          }
     341  
     342          return result;
     343  }
     344  
     345  guchar * 
     346  cr_additional_sel_one_to_string (CRAdditionalSel const *a_this)
     347  {
     348          guchar *result = NULL;
     349          GString *str_buf = NULL;
     350  
     351          g_return_val_if_fail (a_this, NULL) ;
     352  
     353          str_buf = g_string_new (NULL) ;
     354  
     355          switch (a_this->type) {
     356          case CLASS_ADD_SELECTOR:
     357          {
     358                  guchar *name = NULL;
     359  
     360                  if (a_this->content.class_name) {
     361                          name = (guchar *) g_strndup
     362                                  (a_this->content.class_name->stryng->str,
     363                                   a_this->content.class_name->stryng->len);
     364  
     365                          if (name) {
     366                                  g_string_append_printf
     367                                          (str_buf, ".%s",
     368                                           name);
     369                                  g_free (name);
     370                                  name = NULL;
     371                          }
     372                  }
     373          }
     374          break;
     375  
     376          case ID_ADD_SELECTOR:
     377          {
     378                  guchar *name = NULL;
     379  
     380                  if (a_this->content.id_name) {
     381                          name = (guchar *) g_strndup
     382                                  (a_this->content.id_name->stryng->str,
     383                                   a_this->content.id_name->stryng->len);
     384  
     385                          if (name) {
     386                                  g_string_append_printf
     387                                          (str_buf, "#%s",
     388                                           name);
     389                                  g_free (name);
     390                                  name = NULL;
     391                          }
     392                  }
     393          }
     394  
     395          break;
     396  
     397          case PSEUDO_CLASS_ADD_SELECTOR:
     398          {
     399                  if (a_this->content.pseudo) {
     400                          guchar *tmp_str = NULL;
     401  
     402                          tmp_str = cr_pseudo_to_string
     403                                  (a_this->content.pseudo);
     404                          if (tmp_str) {
     405                                  g_string_append_printf
     406                                          (str_buf, ":%s",
     407                                           tmp_str);
     408                                  g_free (tmp_str);
     409                                  tmp_str = NULL;
     410                          }
     411                  }
     412          }
     413          break;
     414  
     415          case ATTRIBUTE_ADD_SELECTOR:
     416                  if (a_this->content.attr_sel) {
     417                          guchar *tmp_str = NULL;
     418  
     419                          g_string_append_printf (str_buf, "[");
     420                          tmp_str = cr_attr_sel_to_string
     421                                  (a_this->content.attr_sel);
     422                          if (tmp_str) {
     423                                  g_string_append_printf
     424                                          (str_buf, "%s]", tmp_str);
     425                                  g_free (tmp_str);
     426                                  tmp_str = NULL;
     427                          }
     428                  }
     429                  break;
     430  
     431          default:
     432                  break;
     433          }
     434  
     435          if (str_buf) {
     436                  result = (guchar *) str_buf->str;
     437                  g_string_free (str_buf, FALSE);
     438                  str_buf = NULL;
     439          }
     440  
     441          return result;
     442  }
     443  
     444  /**
     445   * cr_additional_sel_dump:
     446   * @a_this: the "this pointer" of the current instance of
     447   * #CRAdditionalSel.
     448   * @a_fp: the destination file.
     449   *
     450   * Dumps the current instance of #CRAdditionalSel to a file
     451   */
     452  void
     453  cr_additional_sel_dump (CRAdditionalSel const * a_this, FILE * a_fp)
     454  {
     455          guchar *tmp_str = NULL;
     456  
     457          g_return_if_fail (a_fp);
     458  
     459          if (a_this) {
     460                  tmp_str = cr_additional_sel_to_string (a_this);
     461                  if (tmp_str) {
     462                          fprintf (a_fp, "%s", tmp_str);
     463                          g_free (tmp_str);
     464                          tmp_str = NULL;
     465                  }
     466          }
     467  }
     468  
     469  /**
     470   * cr_additional_sel_destroy:
     471   * @a_this: the "this pointer" of the current instance
     472   * of #CRAdditionalSel .
     473   *
     474   * Destroys an instance of #CRAdditional.
     475   */
     476  void
     477  cr_additional_sel_destroy (CRAdditionalSel * a_this)
     478  {
     479          g_return_if_fail (a_this);
     480  
     481          switch (a_this->type) {
     482          case CLASS_ADD_SELECTOR:
     483                  cr_string_destroy (a_this->content.class_name);
     484                  a_this->content.class_name = NULL;
     485                  break;
     486  
     487          case PSEUDO_CLASS_ADD_SELECTOR:
     488                  cr_pseudo_destroy (a_this->content.pseudo);
     489                  a_this->content.pseudo = NULL;
     490                  break;
     491  
     492          case ID_ADD_SELECTOR:
     493                  cr_string_destroy (a_this->content.id_name);
     494                  a_this->content.id_name = NULL;
     495                  break;
     496  
     497          case ATTRIBUTE_ADD_SELECTOR:
     498                  cr_attr_sel_destroy (a_this->content.attr_sel);
     499                  a_this->content.attr_sel = NULL;
     500                  break;
     501  
     502          default:
     503                  break;
     504          }
     505  
     506          if (a_this->next) {
     507                  cr_additional_sel_destroy (a_this->next);
     508          }
     509  
     510          g_free (a_this);
     511  }