Code

Prevent localized doubles from being written into filter matrices
[inkscape.git] / src / libcroco / cr-additional-sel.c
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3 /*
4  * This file is part of The Croco Library
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2.1 of the GNU Lesser General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  *
20  * Author: Dodji Seketeli
21  * See COPYRIGHTS file for copyright information.
22  *
23  */
25 #include "cr-additional-sel.h"
26 #include "string.h"
28 /**
29  *Default constructor of #CRAdditionalSel.
30  *@return the newly build instance of #CRAdditionalSel.
31  */
32 CRAdditionalSel *
33 cr_additional_sel_new (void)
34 {
35         CRAdditionalSel *result = NULL;
37         result = (CRAdditionalSel *)g_try_malloc (sizeof (CRAdditionalSel));
39         if (result == NULL) {
40                 cr_utils_trace_debug ("Out of memory");
41                 return NULL;
42         }
44         memset (result, 0, sizeof (CRAdditionalSel));
46         return result;
47 }
49 /**
50  *Constructor of #CRAdditionalSel.
51  *@param a_sel_type the type of the newly built instance 
52  *of #CRAdditionalSel.
53  *@return the newly built instance of #CRAdditionalSel.
54  */
55 CRAdditionalSel *
56 cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type)
57 {
58         CRAdditionalSel *result = NULL;
60         result = cr_additional_sel_new ();
62         g_return_val_if_fail (result, NULL);
64         result->type = a_sel_type;
66         return result;
67 }
69 /**
70  *Sets a new class name to a
71  *CLASS additional selector.
72  *@param a_this the "this pointer" of the current instance
73  *of #CRAdditionalSel .
74  *@param a_class_name the new class name to set.
75  *
76  */
77 void
78 cr_additional_sel_set_class_name (CRAdditionalSel * a_this,
79                                   CRString * a_class_name)
80 {
81         g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR);
83         if (a_this->content.class_name) {
84                 cr_string_destroy (a_this->content.class_name);
85         }
87         a_this->content.class_name = a_class_name;
88 }
90 /**
91  *Sets a new id name to an
92  *ID additional selector.
93  *@param a_this the "this pointer" of the current instance
94  *of #CRAdditionalSel .
95  *@param a_id the new id to set.
96  */
97 void
98 cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id)
99 {
100         g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR);
102         if (a_this->content.id_name) {
103                 cr_string_destroy (a_this->content.id_name);
104         }
106         a_this->content.id_name = a_id;
109 /**
110  *Sets a new pseudo to a
111  *PSEUDO additional selector.
112  *@param a_this the "this pointer" of the current instance
113  *of #CRAdditionalSel .
114  *@param a_pseudo the new pseudo to set.
115  */
116 void
117 cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo)
119         g_return_if_fail (a_this
120                           && a_this->type == PSEUDO_CLASS_ADD_SELECTOR);
122         if (a_this->content.pseudo) {
123                 cr_pseudo_destroy (a_this->content.pseudo);
124         }
126         a_this->content.pseudo = a_pseudo;
129 /**
130  *Sets a new instance of #CRAttrSel to 
131  *a ATTRIBUTE additional selector.
132  *@param a_this the "this pointer" of the current instance
133  *of #CRAdditionalSel .
134  *@param a_sel the new instance of #CRAttrSel to set.
135  */
136 void
137 cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel)
139         g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR);
141         if (a_this->content.attr_sel) {
142                 cr_attr_sel_destroy (a_this->content.attr_sel);
143         }
145         a_this->content.attr_sel = a_sel;
148 /**
149  *Appends a new instance of #CRAdditional to the
150  *current list of #CRAdditional.
151  *@param a_this the "this pointer" of the current instance
152  *of #CRAdditionalSel .
153  *@param a_sel the new instance to #CRAdditional to append.
154  *@return the new list of CRAdditionalSel or NULL if an error arises.
155  */
156 CRAdditionalSel *
157 cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
159         CRAdditionalSel *cur_sel = NULL;
161         g_return_val_if_fail (a_sel, NULL);
163         if (a_this == NULL) {
164                 return a_sel;
165         }
167         if (a_sel == NULL)
168                 return NULL;
170         for (cur_sel = a_this;
171              cur_sel && cur_sel->next; cur_sel = cur_sel->next) ;
173         g_return_val_if_fail (cur_sel != NULL, NULL);
175         cur_sel->next = a_sel;
176         a_sel->prev = cur_sel;
178         return a_this;
181 /**
182  *Preppends a new instance of #CRAdditional to the
183  *current list of #CRAdditional.
184  *@param a_this the "this pointer" of the current instance
185  *of #CRAdditionalSel .
186  *@param a_sel the new instance to #CRAdditional to preappend.
187  *@return the new list of CRAdditionalSel or NULL if an error arises.
188  */
189 CRAdditionalSel *
190 cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel)
192         g_return_val_if_fail (a_sel, NULL);
194         if (a_this == NULL) {
195                 return a_sel;
196         }
198         a_sel->next = a_this;
199         a_this->prev = a_sel;
201         return a_sel;
204 guchar *
205 cr_additional_sel_to_string (CRAdditionalSel * a_this)
207         guchar *result = NULL;
208         GString *str_buf = NULL;
209         CRAdditionalSel *cur = NULL;
211         g_return_val_if_fail (a_this, NULL);
213         str_buf = g_string_new (NULL);
215         for (cur = a_this; cur; cur = cur->next) {
216                 switch (cur->type) {
217                 case CLASS_ADD_SELECTOR:
218                         {
219                                 guchar *name = NULL;
221                                 if (cur->content.class_name) {
222                                         name = (guchar *)g_strndup
223                                                 (cur->content.class_name->stryng->str,
224                                                  cur->content.class_name->stryng->len);
226                                         if (name) {
227                                                 g_string_append_printf
228                                                         (str_buf, ".%s",
229                                                          name);
230                                                 g_free (name);
231                                                 name = NULL;
232                                         }
233                                 }
234                         }
235                         break;
237                 case ID_ADD_SELECTOR:
238                         {
239                                 guchar *name = NULL;
241                                 if (cur->content.class_name) {
242                                         name = (guchar *)g_strndup
243                                                 (cur->content.id_name->stryng->str,
244                                                  cur->content.id_name->stryng->len);
246                                         if (name) {
247                                                 g_string_append_printf
248                                                         (str_buf, "#%s",
249                                                          name);
250                                                 g_free (name);
251                                                 name = NULL;
252                                         }
253                                 }
254                         }
256                         break;
258                 case PSEUDO_CLASS_ADD_SELECTOR:
259                         {
260                                 if (cur->content.pseudo) {
261                                         guchar *tmp_str = NULL;
263                                         tmp_str = cr_pseudo_to_string
264                                                 (cur->content.pseudo);
265                                         if (tmp_str) {
266                                                 g_string_append_printf
267                                                         (str_buf, ":%s",
268                                                          tmp_str);
269                                                 g_free (tmp_str);
270                                                 tmp_str = NULL;
271                                         }
272                                 }
273                         }
274                         break;
276                 case ATTRIBUTE_ADD_SELECTOR:
277                         if (cur->content.attr_sel) {
278                                 guchar *tmp_str = NULL;
280                                 g_string_append_c (str_buf, '[');
281                                 tmp_str = cr_attr_sel_to_string
282                                         (cur->content.attr_sel);
283                                 if (tmp_str) {
284                                         g_string_append_printf
285                                                 (str_buf, "%s]", tmp_str);
286                                         g_free (tmp_str);
287                                         tmp_str = NULL;
288                                 }
289                         }
290                         break;
292                 default:
293                         break;
294                 }
295         }
297         if (str_buf) {
298                 result = (guchar *)str_buf->str;
299                 g_string_free (str_buf, FALSE);
300                 str_buf = NULL;
301         }
303         return result;
306 guchar * 
307 cr_additional_sel_one_to_string (CRAdditionalSel *a_this)
309         guchar *result = NULL;
310         GString *str_buf = NULL;
312         g_return_val_if_fail (a_this, NULL) ;
314         str_buf = g_string_new (NULL) ;
316         switch (a_this->type) {
317         case CLASS_ADD_SELECTOR:
318         {
319                 guchar *name = NULL;
321                 if (a_this->content.class_name) {
322                         name = (guchar *)g_strndup
323                                 (a_this->content.class_name->stryng->str,
324                                  a_this->content.class_name->stryng->len);
326                         if (name) {
327                                 g_string_append_printf
328                                         (str_buf, ".%s",
329                                          name);
330                                 g_free (name);
331                                 name = NULL;
332                         }
333                 }
334         }
335         break;
337         case ID_ADD_SELECTOR:
338         {
339                 guchar *name = NULL;
341                 if (a_this->content.class_name) {
342                         name = (guchar *)g_strndup
343                                 (a_this->content.id_name->stryng->str,
344                                  a_this->content.id_name->stryng->len);
346                         if (name) {
347                                 g_string_append_printf
348                                         (str_buf, "#%s",
349                                          name);
350                                 g_free (name);
351                                 name = NULL;
352                         }
353                 }
354         }
356         break;
358         case PSEUDO_CLASS_ADD_SELECTOR:
359         {
360                 if (a_this->content.pseudo) {
361                         guchar *tmp_str = NULL;
363                         tmp_str = cr_pseudo_to_string
364                                 (a_this->content.pseudo);
365                         if (tmp_str) {
366                                 g_string_append_printf
367                                         (str_buf, ":%s",
368                                          tmp_str);
369                                 g_free (tmp_str);
370                                 tmp_str = NULL;
371                         }
372                 }
373         }
374         break;
376         case ATTRIBUTE_ADD_SELECTOR:
377                 if (a_this->content.attr_sel) {
378                         guchar *tmp_str = NULL;
380                         g_string_append_printf (str_buf, "[");
381                         tmp_str = cr_attr_sel_to_string
382                                 (a_this->content.attr_sel);
383                         if (tmp_str) {
384                                 g_string_append_printf
385                                         (str_buf, "%s]", tmp_str);
386                                 g_free (tmp_str);
387                                 tmp_str = NULL;
388                         }
389                 }
390                 break;
392         default:
393                 break;
394         }
396         if (str_buf) {
397                 result = (guchar *)str_buf->str;
398                 g_string_free (str_buf, FALSE);
399                 str_buf = NULL;
400         }
402         return result;
405 /**
406  *Dumps the current instance of #CRAdditionalSel to a file
407  *@param a_this the "this pointer" of the current instance of
408  *#CRAdditionalSel.
409  *@param a_fp the destination file.
410  */
411 void
412 cr_additional_sel_dump (CRAdditionalSel * a_this, FILE * a_fp)
414         guchar *tmp_str = NULL;
416         g_return_if_fail (a_fp);
418         if (a_this) {
419                 tmp_str = cr_additional_sel_to_string (a_this);
420                 if (tmp_str) {
421                         fprintf (a_fp, "%s", tmp_str);
422                         g_free (tmp_str);
423                         tmp_str = NULL;
424                 }
425         }
428 /**
429  *Destroys an instance of #CRAdditional.
430  *@param a_this the "this pointer" of the current instance
431  *of #CRAdditionalSel .
432  */
433 void
434 cr_additional_sel_destroy (CRAdditionalSel * a_this)
436         g_return_if_fail (a_this);
438         switch (a_this->type) {
439         case CLASS_ADD_SELECTOR:
440                 cr_string_destroy (a_this->content.class_name);
441                 a_this->content.class_name = NULL;
442                 break;
444         case PSEUDO_CLASS_ADD_SELECTOR:
445                 cr_pseudo_destroy (a_this->content.pseudo);
446                 a_this->content.pseudo = NULL;
447                 break;
449         case ID_ADD_SELECTOR:
450                 cr_string_destroy (a_this->content.id_name);
451                 a_this->content.id_name = NULL;
452                 break;
454         case ATTRIBUTE_ADD_SELECTOR:
455                 cr_attr_sel_destroy (a_this->content.attr_sel);
456                 a_this->content.attr_sel = NULL;
457                 break;
459         default:
460                 break;
461         }
463         if (a_this->next) {
464                 cr_additional_sel_destroy (a_this->next);
465         }
467         g_free (a_this);