Code

Node tool: special case node duplication for endnodes - select new endnode
[inkscape.git] / src / libcroco / cr-attr-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  * See COPYRIGHTS file for copyrights information.
21  */
23 #include <stdio.h>
24 #include "cr-attr-sel.h"
26 /**
27  *@file
28  *The class that abstracts an attribute selector.
29  *Attributes selectors are described in the css2 spec [5.8].
30  *There are more generally used in the css2 selectors described in
31  *css2 spec [5] .
32  */
34 /**
35  *The constructor of #CRAttrSel.
36  *@return the newly allocated instance
37  *of #CRAttrSel.
38  */
39 CRAttrSel *
40 cr_attr_sel_new (void)
41 {
42         CRAttrSel *result = (CRAttrSel *)g_malloc0 (sizeof (CRAttrSel));
44         return result;
45 }
47 /**
48  *Appends an attribute selector to the current list of
49  *attribute selectors represented by a_this.
50  *
51  *@param a_this the this pointer of the current instance of
52  *#CRAttrSel.
53  *@param a_attr_sel selector to append.
54  *@return CR_OK upon successfull completion, an error code otherwise.
55  */
56 enum CRStatus
57 cr_attr_sel_append_attr_sel (CRAttrSel * a_this, CRAttrSel * a_attr_sel)
58 {
59         CRAttrSel *cur_sel = NULL;
61         g_return_val_if_fail (a_this && a_attr_sel, 
62                               CR_BAD_PARAM_ERROR);
64         for (cur_sel = a_this; 
65              cur_sel->next; 
66              cur_sel = cur_sel->next) ;
68         cur_sel->next = a_attr_sel;
69         a_attr_sel->prev = cur_sel;
71         return CR_OK;
72 }
74 /**
75  *Prepends an attribute selector to the list of
76  *attributes selector represented by a_this.
77  *
78  *@param a_this the "this pointer" of the current instance
79  *of #CRAttrSel.
80  *@param a_attr_sel the attribute selector to append.
81  *@return CR_OK upon successfull completion, an error code otherwise.
82  */
83 enum CRStatus
84 cr_attr_sel_prepend_attr_sel (CRAttrSel * a_this, 
85                               CRAttrSel * a_attr_sel)
86 {
87         g_return_val_if_fail (a_this && a_attr_sel, 
88                               CR_BAD_PARAM_ERROR);
90         a_attr_sel->next = a_this;
91         a_this->prev = a_attr_sel;
93         return CR_OK;
94 }
96 guchar *
97 cr_attr_sel_to_string (CRAttrSel * a_this)
98 {
99         CRAttrSel *cur = NULL;
100         guchar *result = NULL;
101         GString *str_buf = NULL;
103         g_return_val_if_fail (a_this, NULL);
105         str_buf = g_string_new (NULL);
107         for (cur = a_this; cur; cur = cur->next) {
108                 if (cur->prev) {
109                         g_string_append_c (str_buf, ' ');
110                 }
112                 if (cur->name) {
113                         gchar *name = g_strndup (cur->name->stryng->str, 
114                                           cur->name->stryng->len);
115                         if (name) {
116                                 g_string_append (str_buf, name);
117                                 g_free (name);
118                                 name = NULL;
119                         }
120                 }
122                 if (cur->value) {
123                         gchar *value = g_strndup (cur->value->stryng->str, 
124                                            cur->value->stryng->len);
125                         if (value) {
126                                 switch (cur->match_way) {
127                                 case SET:
128                                         break;
130                                 case EQUALS:
131                                         g_string_append_c (str_buf, '=');
132                                         break;
134                                 case INCLUDES:
135                                         g_string_append (str_buf, "~=");
136                                         break;
138                                 case DASHMATCH:
139                                         g_string_append (str_buf, "|=");
140                                         break;
142                                 default:
143                                         break;
144                                 }
146                                 g_string_append_printf
147                                         (str_buf, "\"%s\"", value);
149                                 g_free (value);
150                                 value = NULL;
151                         }
152                 }
153         }
155         if (str_buf) {
156                 result = (guchar *)str_buf->str;
157                 g_string_free (str_buf, FALSE);
158         }
160         return result;
163 /**
164  *Dumps the current instance of #CRAttrSel to a file.
165  *@param a_this the "this pointer" of the current instance of
166  *#CRAttrSel.
167  *@param a_fp the destination file.
168  */
169 void
170 cr_attr_sel_dump (CRAttrSel * a_this, FILE * a_fp)
172         guchar *tmp_str = NULL;
174         g_return_if_fail (a_this);
176         tmp_str = cr_attr_sel_to_string (a_this);
178         if (tmp_str) {
179                 fprintf (a_fp, "%s", tmp_str);
180                 g_free (tmp_str);
181                 tmp_str = NULL;
182         }
185 /**
186  *Destroys the current instance of #CRAttrSel.
187  *Frees all the fields if they are non null.
188  *@param a_this the "this pointer" of the current
189  *instance of #CRAttrSel.
190  */
191 void
192 cr_attr_sel_destroy (CRAttrSel * a_this)
194         g_return_if_fail (a_this);
196         if (a_this->name) {
197                 cr_string_destroy (a_this->name);
198                 a_this->name = NULL;
199         }
201         if (a_this->value) {
202                 cr_string_destroy (a_this->value);
203                 a_this->value = NULL;
204         }
206         if (a_this->next) {
207                 cr_attr_sel_destroy (a_this->next);
208                 a_this->next = NULL;
209         }
211         if (a_this) {
212                 g_free (a_this);
213                 a_this = NULL;
214         }