Code

Unify stat type for older glib.
[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 = (CRSelector *)g_try_malloc (sizeof (CRSelector));
38         if (!result) {
39                 cr_utils_trace_info ("Out of memory");
40                 return NULL;
41         }
42         memset (result, 0, sizeof (CRSelector));
43         result->simple_sel = a_simple_sel;
44         return result;
45 }
47 CRSelector *
48 cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc)
49 {
50         CRParser *parser = NULL;
52         g_return_val_if_fail (a_char_buf, NULL);
54         parser = cr_parser_new_from_buf ((guchar*)a_char_buf,
55                                                  strlen ((char *)a_char_buf),
56                                          a_enc, FALSE);
57         g_return_val_if_fail (parser, NULL);
59         return NULL;
60 }
62 /**
63  *Appends a new instance of #CRSelector to the current selector list.
64  *@param a_this the current instance of #CRSelector.
65  *@param a_new the instance of #CRSelector to be appended.
66  *@return the new list.
67  */
68 CRSelector *
69 cr_selector_append (CRSelector * a_this, CRSelector * a_new)
70 {
71         CRSelector *cur = NULL;
73         if (!a_this) {
74                 return a_new;
75         }
77         /*walk forward the list headed by a_this to get the list tail */
78         for (cur = a_this; cur && cur->next; cur = cur->next) ;
80         cur->next = a_new;
81         a_new->prev = cur;
83         return a_this;
84 }
86 /**
87  *Prepends an element to the #CRSelector list.
88  *@param a_this the current instance of #CRSelector list.
89  *@param a_new the instance of #CRSelector.
90  *@return the new list.
91  */
92 CRSelector *
93 cr_selector_prepend (CRSelector * a_this, CRSelector * a_new)
94 {
95         CRSelector *cur = NULL;
97         a_new->next = a_this;
98         a_this->prev = a_new;
100         for (cur = a_new; cur && cur->prev; cur = cur->prev) ;
102         return cur;
105 /**
106  *append a simple selector to the current #CRSelector list.
107  *@param a_this the current instance of #CRSelector.
108  *@param a_simple_sel the simple selector to append.
109  *@return the new list or NULL in case of failure.
110  */
111 CRSelector *
112 cr_selector_append_simple_sel (CRSelector * a_this,
113                                CRSimpleSel * a_simple_sel)
115         CRSelector *selector = NULL;
117         selector = cr_selector_new (a_simple_sel);
118         g_return_val_if_fail (selector, NULL);
120         return cr_selector_append (a_this, selector);
123 guchar *
124 cr_selector_to_string (CRSelector * a_this)
126         guchar *result = NULL;
128         GString *str_buf = (GString *)g_string_new (NULL);
129         g_return_val_if_fail (str_buf, NULL);
131         if (a_this) {
132                 CRSelector *cur = NULL;
134                 for (cur = a_this; cur; cur = cur->next) {
135                         if (cur->simple_sel) {
136                                 guchar *tmp_str = NULL;
138                                 tmp_str = cr_simple_sel_to_string
139                                         (cur->simple_sel);
141                                 if (tmp_str) {
142                                         if (cur->prev)
143                                                 g_string_append (str_buf, 
144                                                                  ", ");
146                                         g_string_append (str_buf, (gchar *)tmp_str);
148                                         g_free (tmp_str);
149                                         tmp_str = NULL;
150                                 }
151                         }
152                 }
153         }
155         if (str_buf) {
156                 result = (guchar *)str_buf->str;
157                 g_string_free (str_buf, FALSE);
158                 str_buf = NULL;
159         }
161         return result;
164 /**
165  *Serializes the current instance of #CRSelector to a file.
166  *@param a_this the current instance of #CRSelector.
167  *@param a_fp the destination file.
168  */
169 void
170 cr_selector_dump (CRSelector * a_this, FILE * a_fp)
172         guchar *tmp_buf = NULL;
174         if (a_this) {
175                 tmp_buf = cr_selector_to_string (a_this);
176                 if (tmp_buf) {
177                         fprintf (a_fp, "%s", tmp_buf);
178                         g_free (tmp_buf);
179                         tmp_buf = NULL;
180                 }
181         }
184 /**
185  *Increments the ref count of the current instance
186  *of #CRSelector.
187  *@param a_this the current instance of #CRSelector.
188  */
189 void
190 cr_selector_ref (CRSelector * a_this)
192         g_return_if_fail (a_this);
194         a_this->ref_count++;
197 /**
198  *Decrements the ref count of the current instance of
199  *#CRSelector.
200  *If the ref count reaches zero, the current instance of
201  *#CRSelector is destroyed.
202  *@param a_this the current instance of #CRSelector.
203  *@return TRUE if this function destroyed the current instance
204  *of #CRSelector, FALSE otherwise.
205  */
206 gboolean
207 cr_selector_unref (CRSelector * a_this)
209         g_return_val_if_fail (a_this, FALSE);
211         if (a_this->ref_count) {
212                 a_this->ref_count--;
213         }
215         if (a_this->ref_count == 0) {
216                 cr_selector_destroy (a_this);
217                 return TRUE;
218         }
220         return FALSE;
223 /**
224  *Destroys the selector list.
225  *@param a_this the current instance of #CRSelector.
226  */
227 void
228 cr_selector_destroy (CRSelector * a_this)
230         CRSelector *cur = NULL;
232         g_return_if_fail (a_this);
234         /*
235          *go and get the list tail. In the same time, free
236          *all the simple selectors contained in the list.
237          */
238         for (cur = a_this; cur && cur->next; cur = cur->next) {
239                 if (cur->simple_sel) {
240                         cr_simple_sel_destroy (cur->simple_sel);
241                         cur->simple_sel = NULL;
242                 }
243         }
245         if (cur) {
246                 if (cur->simple_sel) {
247                         cr_simple_sel_destroy (cur->simple_sel);
248                         cur->simple_sel = NULL;
249                 }
250         }
252         /*in case the list has only one element */
253         if (cur && !cur->prev) {
254                 g_free (cur);
255                 return;
256         }
258         /*walk backward the list and free each "next element" */
259         for (cur = cur->prev; cur && cur->prev; cur = cur->prev) {
260                 if (cur->next) {
261                         g_free (cur->next);
262                         cur->next = NULL;
263                 }
264         }
266         if (!cur)
267                 return;
269         if (cur->next) {
270                 g_free (cur->next);
271                 cur->next = NULL;
272         }
274         g_free (cur);