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
32 #include <config.h>
33 #include <stdio.h>
34 #include "cr-attr-sel.h"
35
36 /**
37 * CRAttrSel:
38 *
39 * #CRAdditionalSel abstracts an attribute selector.
40 * Attributes selectors are described in the css2 spec [5.8].
41 * There are more generally used in the css2 selectors described in
42 * css2 spec [5] .
43 */
44
45 /**
46 * cr_attr_sel_new:
47 * The constructor of #CRAttrSel.
48 * Returns the newly allocated instance
49 * of #CRAttrSel.
50 */
51 CRAttrSel *
cr_attr_sel_new(void)52 cr_attr_sel_new (void)
53 {
54 CRAttrSel *result = NULL;
55
56 result = g_malloc0 (sizeof (CRAttrSel));
57
58 return result;
59 }
60
61 /**
62 * cr_attr_sel_append_attr_sel:
63 * @a_this: the this pointer of the current instance of #CRAttrSel.
64 * @a_attr_sel: selector to append.
65 *
66 * Appends an attribute selector to the current list of
67 * attribute selectors represented by a_this.
68 * Returns CR_OK upon successfull completion, an error code otherwise.
69 */
70 enum CRStatus
cr_attr_sel_append_attr_sel(CRAttrSel * a_this,CRAttrSel * a_attr_sel)71 cr_attr_sel_append_attr_sel (CRAttrSel * a_this, CRAttrSel * a_attr_sel)
72 {
73 CRAttrSel *cur_sel = NULL;
74
75 g_return_val_if_fail (a_this && a_attr_sel,
76 CR_BAD_PARAM_ERROR);
77
78 for (cur_sel = a_this;
79 cur_sel->next;
80 cur_sel = cur_sel->next) ;
81
82 cur_sel->next = a_attr_sel;
83 a_attr_sel->prev = cur_sel;
84
85 return CR_OK;
86 }
87
88 /**
89 * cr_attr_sel_prepend_attr_sel:
90 *@a_this: the "this pointer" of the current instance *of #CRAttrSel.
91 *@a_attr_sel: the attribute selector to append.
92 *
93 *Prepends an attribute selector to the list of
94 *attributes selector represented by a_this.
95 *Returns CR_OK upon successfull completion, an error code otherwise.
96 */
97 enum CRStatus
cr_attr_sel_prepend_attr_sel(CRAttrSel * a_this,CRAttrSel * a_attr_sel)98 cr_attr_sel_prepend_attr_sel (CRAttrSel * a_this,
99 CRAttrSel * a_attr_sel)
100 {
101 g_return_val_if_fail (a_this && a_attr_sel,
102 CR_BAD_PARAM_ERROR);
103
104 a_attr_sel->next = a_this;
105 a_this->prev = a_attr_sel;
106
107 return CR_OK;
108 }
109
110 /**
111 * cr_attr_sel_to_string:
112 * @a_this: the current instance of #CRAttrSel.
113 *
114 * Serializes an attribute selector into a string
115 * Returns the serialized attribute selector.
116 */
117 guchar *
cr_attr_sel_to_string(CRAttrSel const * a_this)118 cr_attr_sel_to_string (CRAttrSel const * a_this)
119 {
120 CRAttrSel const *cur = NULL;
121 guchar *result = NULL;
122 GString *str_buf = NULL;
123
124 g_return_val_if_fail (a_this, NULL);
125
126 str_buf = g_string_new (NULL);
127
128 for (cur = a_this; cur; cur = cur->next) {
129 if (cur->prev) {
130 g_string_append_c (str_buf, ' ');
131 }
132
133 if (cur->name) {
134 guchar *name = NULL;
135
136 name = (guchar *) g_strndup (cur->name->stryng->str,
137 cur->name->stryng->len);
138 if (name) {
139 g_string_append (str_buf, (const gchar *) name);
140 g_free (name);
141 name = NULL;
142 }
143 }
144
145 if (cur->value) {
146 guchar *value = NULL;
147
148 value = (guchar *) g_strndup (cur->value->stryng->str,
149 cur->value->stryng->len);
150 if (value) {
151 switch (cur->match_way) {
152 case SET:
153 break;
154
155 case EQUALS:
156 g_string_append_c (str_buf, '=');
157 break;
158
159 case INCLUDES:
160 g_string_append (str_buf, "~=");
161 break;
162
163 case DASHMATCH:
164 g_string_append (str_buf, "|=");
165 break;
166
167 default:
168 break;
169 }
170
171 g_string_append_printf
172 (str_buf, "\"%s\"", value);
173
174 g_free (value);
175 value = NULL;
176 }
177 }
178 }
179
180 if (str_buf) {
181 result = (guchar *) str_buf->str;
182 g_string_free (str_buf, FALSE);
183 }
184
185 return result;
186 }
187
188 /**
189 * cr_attr_sel_dump:
190 * @a_this: the "this pointer" of the current instance of
191 * #CRAttrSel.
192 * @a_fp: the destination file.
193 *
194 * Dumps the current instance of #CRAttrSel to a file.
195 */
196 void
cr_attr_sel_dump(CRAttrSel const * a_this,FILE * a_fp)197 cr_attr_sel_dump (CRAttrSel const * a_this, FILE * a_fp)
198 {
199 guchar *tmp_str = NULL;
200
201 g_return_if_fail (a_this);
202
203 tmp_str = cr_attr_sel_to_string (a_this);
204
205 if (tmp_str) {
206 fprintf (a_fp, "%s", tmp_str);
207 g_free (tmp_str);
208 tmp_str = NULL;
209 }
210 }
211
212 /**
213 *cr_attr_sel_destroy:
214 *@a_this: the "this pointer" of the current
215 *instance of #CRAttrSel.
216 *
217 *Destroys the current instance of #CRAttrSel.
218 *Frees all the fields if they are non null.
219 */
220 void
cr_attr_sel_destroy(CRAttrSel * a_this)221 cr_attr_sel_destroy (CRAttrSel * a_this)
222 {
223 g_return_if_fail (a_this);
224
225 if (a_this->name) {
226 cr_string_destroy (a_this->name);
227 a_this->name = NULL;
228 }
229
230 if (a_this->value) {
231 cr_string_destroy (a_this->value);
232 a_this->value = NULL;
233 }
234
235 if (a_this->next) {
236 cr_attr_sel_destroy (a_this->next);
237 a_this->next = NULL;
238 }
239
240 if (a_this) {
241 g_free (a_this);
242 a_this = NULL;
243 }
244 }
245
246