1
/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
4
* This file is part of The Croco Library
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.
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.
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
20
* Author: Dodji Seketeli
21
* See COPYRIGHTS file for copyright information.
28
#include "cr-parser.h"
32
*Definition of the #CRTem class.
36
cr_term_clear (CRTerm * a_this)
38
g_return_if_fail (a_this);
40
switch (a_this->type) {
42
if (a_this->content.num) {
43
cr_num_destroy (a_this->content.num);
44
a_this->content.num = NULL;
49
if (a_this->ext_content.func_param) {
50
cr_term_destroy (a_this->ext_content.func_param);
51
a_this->ext_content.func_param = NULL;
57
if (a_this->content.str) {
58
cr_string_destroy (a_this->content.str);
59
a_this->content.str = NULL;
64
if (a_this->content.rgb) {
65
cr_rgb_destroy (a_this->content.rgb);
66
a_this->content.rgb = NULL;
70
case TERM_UNICODERANGE:
76
a_this->type = TERM_NO_TYPE;
80
*Instanciate a #CRTerm.
81
*@return the newly build instance
87
CRTerm *result = (CRTerm *)g_try_malloc (sizeof (CRTerm));
89
cr_utils_trace_info ("Out of memory");
92
memset (result, 0, sizeof (CRTerm));
97
*Parses an expresion as defined by the css2 spec
98
*and builds the expression as a list of terms.
99
*@param a_buf the buffer to parse.
100
*@return a pointer to the first term of the expression or
101
*NULL if parsing failed.
104
cr_term_parse_expression_from_buf (const guchar * a_buf,
105
enum CREncoding a_encoding)
107
CRTerm *result = NULL;
108
enum CRStatus status = CR_OK;
110
g_return_val_if_fail (a_buf, NULL);
112
CRParser *parser = cr_parser_new_from_buf (
114
strlen ((char *)a_buf),
116
g_return_val_if_fail (parser, NULL);
118
status = cr_parser_try_to_skip_spaces_and_comments (parser);
119
if (status != CR_OK) {
122
status = cr_parser_parse_expr (parser, &result);
123
if (status != CR_OK) {
125
cr_term_destroy (result);
132
cr_parser_destroy (parser);
140
cr_term_set_number (CRTerm * a_this, CRNum * a_num)
142
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
144
cr_term_clear (a_this);
146
a_this->type = TERM_NUMBER;
147
a_this->content.num = a_num;
152
cr_term_set_function (CRTerm * a_this, CRString * a_func_name,
153
CRTerm * a_func_param)
155
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
157
cr_term_clear (a_this);
159
a_this->type = TERM_FUNCTION;
160
a_this->content.str = a_func_name;
161
a_this->ext_content.func_param = a_func_param;
166
cr_term_set_string (CRTerm * a_this, CRString * a_str)
168
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
170
cr_term_clear (a_this);
172
a_this->type = TERM_STRING;
173
a_this->content.str = a_str;
178
cr_term_set_ident (CRTerm * a_this, CRString * a_str)
180
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
182
cr_term_clear (a_this);
184
a_this->type = TERM_IDENT;
185
a_this->content.str = a_str;
190
cr_term_set_uri (CRTerm * a_this, CRString * a_str)
192
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
194
cr_term_clear (a_this);
196
a_this->type = TERM_URI;
197
a_this->content.str = a_str;
202
cr_term_set_rgb (CRTerm * a_this, CRRgb * a_rgb)
204
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
206
cr_term_clear (a_this);
208
a_this->type = TERM_RGB;
209
a_this->content.rgb = a_rgb;
214
cr_term_set_hash (CRTerm * a_this, CRString * a_str)
216
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
218
cr_term_clear (a_this);
220
a_this->type = TERM_HASH;
221
a_this->content.str = a_str;
226
*Appends a new term to the current list of #CRTerm.
228
*@param a_this the "this pointer" of the current instance
230
*@param a_new_term the term to append.
231
*@return the list of terms with the a_new_term appended to it.
234
cr_term_append_term (CRTerm * a_this, CRTerm * a_new_term)
238
g_return_val_if_fail (a_new_term, NULL);
243
for (cur = a_this; cur->next; cur = cur->next) ;
245
cur->next = a_new_term;
246
a_new_term->prev = cur;
252
*Prepends a term to the list of terms represented by a_this.
254
*@param a_this the "this pointer" of the current instance of
256
*@param a_new_term the term to prepend.
257
*@return the head of the new list.
260
cr_term_prepend_term (CRTerm * a_this, CRTerm * a_new_term)
262
g_return_val_if_fail (a_this && a_new_term, NULL);
264
a_new_term->next = a_this;
265
a_this->prev = a_new_term;
271
*Serializes the expression represented by
272
*the chained instances of #CRterm.
273
*@param a_this the current instance of #CRTerm
274
*@return the zero terminated string containing the serialized
275
*form of #CRTerm. MUST BE FREED BY THE CALLER using g_free().
278
cr_term_to_string (CRTerm * a_this)
280
GString *str_buf = NULL;
282
guchar *result = NULL;
283
gchar *content = NULL;
285
g_return_val_if_fail (a_this, NULL);
287
str_buf = g_string_new (NULL);
288
g_return_val_if_fail (str_buf, NULL);
290
for (cur = a_this; cur; cur = cur->next) {
291
if ((cur->content.str == NULL)
292
&& (cur->content.num == NULL)
293
&& (cur->content.str == NULL)
294
&& (cur->content.rgb == NULL))
297
switch (cur->the_operator) {
299
g_string_append (str_buf, " / ");
303
g_string_append (str_buf, ", ");
308
g_string_append (str_buf, " ");
316
switch (cur->unary_op) {
318
g_string_append (str_buf, "+");
322
g_string_append (str_buf, "-");
331
if (cur->content.num) {
332
content = (gchar *)cr_num_to_string (cur->content.num);
336
g_string_append (str_buf, content);
344
if (cur->content.str) {
346
(cur->content.str->stryng->str,
347
cur->content.str->stryng->len);
351
g_string_append_printf (str_buf, "%s(",
354
if (cur->ext_content.func_param) {
355
guchar *tmp_str = NULL;
357
tmp_str = cr_term_to_string
359
ext_content.func_param);
362
g_string_append (str_buf,
371
g_string_append (str_buf, ")");
377
if (cur->content.str) {
379
(cur->content.str->stryng->str,
380
cur->content.str->stryng->len);
384
g_string_append_printf (str_buf,
392
if (cur->content.str) {
394
(cur->content.str->stryng->str,
395
cur->content.str->stryng->len);
399
g_string_append (str_buf, content);
406
if (cur->content.str) {
408
(cur->content.str->stryng->str,
409
cur->content.str->stryng->len);
413
g_string_append_printf
414
(str_buf, "url(%s)", content);
421
if (cur->content.rgb) {
422
guchar *tmp_str = NULL;
424
g_string_append (str_buf, "rgb(");
425
tmp_str = cr_rgb_to_string (cur->content.rgb);
428
g_string_append (str_buf, (gchar *)tmp_str);
432
g_string_append (str_buf, ")");
437
case TERM_UNICODERANGE:
440
"?found unicoderange: dump not supported yet?");
444
if (cur->content.str) {
446
(cur->content.str->stryng->str,
447
cur->content.str->stryng->len);
451
g_string_append_printf (str_buf,
459
g_string_append (str_buf,
460
"Unrecognized Term type");
466
result = (guchar *)str_buf->str;
467
g_string_free (str_buf, FALSE);
475
cr_term_one_to_string (CRTerm * a_this)
477
GString *str_buf = NULL;
478
guchar *result = NULL;
479
gchar *content = NULL;
481
g_return_val_if_fail (a_this, NULL);
483
str_buf = g_string_new (NULL);
484
g_return_val_if_fail (str_buf, NULL);
486
if ((a_this->content.str == NULL)
487
&& (a_this->content.num == NULL)
488
&& (a_this->content.str == NULL)
489
&& (a_this->content.rgb == NULL))
492
switch (a_this->the_operator) {
494
g_string_append_printf (str_buf, " / ");
498
g_string_append_printf (str_buf, ", ");
503
g_string_append_printf (str_buf, " ");
511
switch (a_this->unary_op) {
513
g_string_append_printf (str_buf, "+");
517
g_string_append_printf (str_buf, "-");
524
switch (a_this->type) {
526
if (a_this->content.num) {
527
content = (gchar *)cr_num_to_string (a_this->content.num);
531
g_string_append (str_buf, content);
539
if (a_this->content.str) {
541
(a_this->content.str->stryng->str,
542
a_this->content.str->stryng->len);
546
g_string_append_printf (str_buf, "%s(",
549
if (a_this->ext_content.func_param) {
550
guchar *tmp_str = NULL;
552
tmp_str = cr_term_to_string
554
ext_content.func_param);
557
g_string_append_printf
564
g_string_append_printf (str_buf, ")");
573
if (a_this->content.str) {
575
(a_this->content.str->stryng->str,
576
a_this->content.str->stryng->len);
580
g_string_append_printf (str_buf,
588
if (a_this->content.str) {
590
(a_this->content.str->stryng->str,
591
a_this->content.str->stryng->len);
595
g_string_append (str_buf, content);
602
if (a_this->content.str) {
604
(a_this->content.str->stryng->str,
605
a_this->content.str->stryng->len);
609
g_string_append_printf
610
(str_buf, "url(%s)", content);
617
if (a_this->content.rgb) {
619
g_string_append_printf (str_buf, "rgb(");
620
gchar *tmp_str = (gchar *)cr_rgb_to_string (a_this->content.rgb);
623
g_string_append (str_buf, tmp_str);
627
g_string_append_printf (str_buf, ")");
632
case TERM_UNICODERANGE:
633
g_string_append_printf
635
"?found unicoderange: dump not supported yet?");
639
if (a_this->content.str) {
641
(a_this->content.str->stryng->str,
642
a_this->content.str->stryng->len);
646
g_string_append_printf (str_buf,
654
g_string_append_printf (str_buf,
656
"Unrecognized Term type");
661
result = (guchar *)str_buf->str;
662
g_string_free (str_buf, FALSE);
670
*Dumps the expression (a list of terms connected by operators)
672
*TODO: finish the dump. The dump of some type of terms have not yet been
674
*@param a_this the current instance of #CRTerm.
675
*@param a_fp the destination file pointer.
678
cr_term_dump (CRTerm * a_this, FILE * a_fp)
680
guchar *content = NULL;
682
g_return_if_fail (a_this);
684
content = cr_term_to_string (a_this);
687
fprintf (a_fp, "%s", content);
693
*Return the number of terms in the expression.
694
*@param a_this the current instance of #CRTerm.
695
*@return number of terms in the expression.
698
cr_term_nr_values (CRTerm *a_this)
703
g_return_val_if_fail (a_this, -1) ;
705
for (cur = a_this ; cur ; cur = cur->next)
711
*Use an index to get a CRTerm from the expression.
712
*@param a_this the current instance of #CRTerm.
713
*@param itemnr the index into the expression.
714
*@return CRTerm at position itemnr, if itemnr > number of terms - 1,
715
*it will return NULL.
718
cr_term_get_from_list (CRTerm *a_this, int itemnr)
723
g_return_val_if_fail (a_this, NULL) ;
725
for (cur = a_this ; cur ; cur = cur->next)
732
*Increments the reference counter of the current instance
734
*@param a_this the current instance of #CRTerm.
737
cr_term_ref (CRTerm * a_this)
739
g_return_if_fail (a_this);
745
*Decrements the ref count of the current instance of
746
*#CRTerm. If the ref count reaches zero, the instance is
748
*@param a_this the current instance of #CRTerm.
749
*@return TRUE if the current instance has been destroyed, FALSE otherwise.
752
cr_term_unref (CRTerm * a_this)
754
g_return_val_if_fail (a_this, FALSE);
756
if (a_this->ref_count) {
760
if (a_this->ref_count == 0) {
761
cr_term_destroy (a_this);
769
*The destructor of the the #CRTerm class.
770
*@param a_this the "this pointer" of the current instance
774
cr_term_destroy (CRTerm * a_this)
776
g_return_if_fail (a_this);
778
cr_term_clear (a_this);
781
cr_term_destroy (a_this->next);