Code

* src/dialogs/layers-panel.cpp: Compile fix from Mathieu Dimanche.
[inkscape.git] / src / libcroco / cr-selector.c
1 /* -*- Mode: C; indent-tabs-mode: ni; 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 copyright information.
21  */
23 #include <string.h>
24 #include "cr-selector.h"
25 #include "cr-parser.h"
27 /**
28  *Creates a new instance of #CRSelector.
29  *@param a_simple_sel the initial simple selector list
30  *of the current instance of #CRSelector.
31  *@return the newly built instance of #CRSelector, or
32  *NULL in case of failure.
33  */
34 CRSelector *
35 cr_selector_new (CRSimpleSel * a_simple_sel)
36 {
37         CRSelector *result = NULL;
39         result = g_try_malloc (sizeof (CRSelector));
40         if (!result) {
41                 cr_utils_trace_info ("Out of memory");
42                 return NULL;
43         }
44         memset (result, 0, sizeof (CRSelector));
45         result->simple_sel = a_simple_sel;
46         return result;
47 }
49 CRSelector *
50 cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc)
51 {
52         CRParser *parser = NULL;
54         g_return_val_if_fail (a_char_buf, NULL);
56         parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen (a_char_buf),
57                                          a_enc, FALSE);
58         g_return_val_if_fail (parser, NULL);
60         return NULL;
61 }
63 /**
64  *Appends a new instance of #CRSelector to the current selector list.
65  *@param a_this the current instance of #CRSelector.
66  *@param a_new the instance of #CRSelector to be appended.
67  *@return the new list.
68  */
69 CRSelector *
70 cr_selector_append (CRSelector * a_this, CRSelector * a_new)
71 {
72         CRSelector *cur = NULL;
74         if (!a_this) {
75                 return a_new;
76         }
78         /*walk forward the list headed by a_this to get the list tail */
79         for (cur = a_this; cur && cur->next; cur = cur->next) ;
81         cur->next = a_new;
82         a_new->prev = cur;
84         return a_this;
85 }
87 /**
88  *Prepends an element to the #CRSelector list.
89  *@param a_this the current instance of #CRSelector list.
90  *@param a_new the instance of #CRSelector.
91  *@return the new list.
92  */
93 CRSelector *
94 cr_selector_prepend (CRSelector * a_this, CRSelector * a_new)
95 {
96         CRSelector *cur = NULL;
98         a_new->next = a_this;
99         a_this->prev = a_new;
101         for (cur = a_new; cur && cur->prev; cur = cur->prev) ;
103         return cur;
106 /**
107  *append a simple selector to the current #CRSelector list.
108  *@param a_this the current instance of #CRSelector.
109  *@param a_simple_sel the simple selector to append.
110  *@return the new list or NULL in case of failure.
111  */
112 CRSelector *
113 cr_selector_append_simple_sel (CRSelector * a_this,
114                                CRSimpleSel * a_simple_sel)
116         CRSelector *selector = NULL;
118         selector = cr_selector_new (a_simple_sel);
119         g_return_val_if_fail (selector, NULL);
121         return cr_selector_append (a_this, selector);
124 guchar *
125 cr_selector_to_string (CRSelector * a_this)
127         guchar *result = NULL;
128         GString *str_buf = NULL;
130         str_buf = g_string_new (NULL);
131         g_return_val_if_fail (str_buf, NULL);
133         if (a_this) {
134                 CRSelector *cur = NULL;
136                 for (cur = a_this; cur; cur = cur->next) {
137                         if (cur->simple_sel) {
138                                 guchar *tmp_str = NULL;
140                                 tmp_str = cr_simple_sel_to_string
141                                         (cur->simple_sel);
143                                 if (tmp_str) {
144                                         if (cur->prev)
145                                                 g_string_append (str_buf, 
146                                                                  ", ");
148                                         g_string_append (str_buf, tmp_str);
150                                         g_free (tmp_str);
151                                         tmp_str = NULL;
152                                 }
153                         }
154                 }
155         }
157         if (str_buf) {
158                 result = str_buf->str;
159                 g_string_free (str_buf, FALSE);
160                 str_buf = NULL;
161         }
163         return result;
166 /**
167  *Serializes the current instance of #CRSelector to a file.
168  *@param a_this the current instance of #CRSelector.
169  *@param a_fp the destination file.
170  */
171 void
172 cr_selector_dump (CRSelector * a_this, FILE * a_fp)
174         guchar *tmp_buf = NULL;
176         if (a_this) {
177                 tmp_buf = cr_selector_to_string (a_this);
178                 if (tmp_buf) {
179                         fprintf (a_fp, "%s", tmp_buf);
180                         g_free (tmp_buf);
181                         tmp_buf = NULL;
182                 }
183         }
186 /**
187  *Increments the ref count of the current instance
188  *of #CRSelector.
189  *@param a_this the current instance of #CRSelector.
190  */
191 void
192 cr_selector_ref (CRSelector * a_this)
194         g_return_if_fail (a_this);
196         a_this->ref_count++;
199 /**
200  *Decrements the ref count of the current instance of
201  *#CRSelector.
202  *If the ref count reaches zero, the current instance of
203  *#CRSelector is destroyed.
204  *@param a_this the current instance of #CRSelector.
205  *@return TRUE if this function destroyed the current instance
206  *of #CRSelector, FALSE otherwise.
207  */
208 gboolean
209 cr_selector_unref (CRSelector * a_this)
211         g_return_val_if_fail (a_this, FALSE);
213         if (a_this->ref_count) {
214                 a_this->ref_count--;
215         }
217         if (a_this->ref_count == 0) {
218                 cr_selector_destroy (a_this);
219                 return TRUE;
220         }
222         return FALSE;
225 /**
226  *Destroys the selector list.
227  *@param a_this the current instance of #CRSelector.
228  */
229 void
230 cr_selector_destroy (CRSelector * a_this)
232         CRSelector *cur = NULL;
234         g_return_if_fail (a_this);
236         /*
237          *go and get the list tail. In the same time, free
238          *all the simple selectors contained in the list.
239          */
240         for (cur = a_this; cur && cur->next; cur = cur->next) {
241                 if (cur->simple_sel) {
242                         cr_simple_sel_destroy (cur->simple_sel);
243                         cur->simple_sel = NULL;
244                 }
245         }
247         if (cur) {
248                 if (cur->simple_sel) {
249                         cr_simple_sel_destroy (cur->simple_sel);
250                         cur->simple_sel = NULL;
251                 }
252         }
254         /*in case the list has only one element */
255         if (cur && !cur->prev) {
256                 g_free (cur);
257                 return;
258         }
260         /*walk backward the list and free each "next element" */
261         for (cur = cur->prev; cur && cur->prev; cur = cur->prev) {
262                 if (cur->next) {
263                         g_free (cur->next);
264                         cur->next = NULL;
265                 }
266         }
268         if (!cur)
269                 return;
271         if (cur->next) {
272                 g_free (cur->next);
273                 cur->next = NULL;
274         }
276         g_free (cur);