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.
29 #include "cr-parser.h"
33 *Definition of the #CRTem class.
37 cr_term_clear (CRTerm * a_this)
39 g_return_if_fail (a_this);
41 switch (a_this->type) {
43 if (a_this->content.num) {
44 cr_num_destroy (a_this->content.num);
45 a_this->content.num = NULL;
50 if (a_this->ext_content.func_param) {
51 cr_term_destroy (a_this->ext_content.func_param);
52 a_this->ext_content.func_param = NULL;
58 if (a_this->content.str) {
59 cr_string_destroy (a_this->content.str);
60 a_this->content.str = NULL;
65 if (a_this->content.rgb) {
66 cr_rgb_destroy (a_this->content.rgb);
67 a_this->content.rgb = NULL;
71 case TERM_UNICODERANGE:
77 a_this->type = TERM_NO_TYPE;
81 *Instanciate a #CRTerm.
82 *@return the newly build instance
88 CRTerm *result = NULL;
90 result = g_try_malloc (sizeof (CRTerm));
92 cr_utils_trace_info ("Out of memory");
95 memset (result, 0, sizeof (CRTerm));
100 *Parses an expresion as defined by the css2 spec
101 *and builds the expression as a list of terms.
102 *@param a_buf the buffer to parse.
103 *@return a pointer to the first term of the expression or
104 *NULL if parsing failed.
107 cr_term_parse_expression_from_buf (const guchar * a_buf,
108 enum CREncoding a_encoding)
110 CRParser *parser = NULL;
111 CRTerm *result = NULL;
112 enum CRStatus status = CR_OK;
114 g_return_val_if_fail (a_buf, NULL);
116 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
118 g_return_val_if_fail (parser, NULL);
120 status = cr_parser_try_to_skip_spaces_and_comments (parser);
121 if (status != CR_OK) {
124 status = cr_parser_parse_expr (parser, &result);
125 if (status != CR_OK) {
127 cr_term_destroy (result);
134 cr_parser_destroy (parser);
142 cr_term_set_number (CRTerm * a_this, CRNum * a_num)
144 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
146 cr_term_clear (a_this);
148 a_this->type = TERM_NUMBER;
149 a_this->content.num = a_num;
154 cr_term_set_function (CRTerm * a_this, CRString * a_func_name,
155 CRTerm * a_func_param)
157 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
159 cr_term_clear (a_this);
161 a_this->type = TERM_FUNCTION;
162 a_this->content.str = a_func_name;
163 a_this->ext_content.func_param = a_func_param;
168 cr_term_set_string (CRTerm * a_this, CRString * a_str)
170 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
172 cr_term_clear (a_this);
174 a_this->type = TERM_STRING;
175 a_this->content.str = a_str;
180 cr_term_set_ident (CRTerm * a_this, CRString * a_str)
182 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
184 cr_term_clear (a_this);
186 a_this->type = TERM_IDENT;
187 a_this->content.str = a_str;
192 cr_term_set_uri (CRTerm * a_this, CRString * a_str)
194 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
196 cr_term_clear (a_this);
198 a_this->type = TERM_URI;
199 a_this->content.str = a_str;
204 cr_term_set_rgb (CRTerm * a_this, CRRgb * a_rgb)
206 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
208 cr_term_clear (a_this);
210 a_this->type = TERM_RGB;
211 a_this->content.rgb = a_rgb;
216 cr_term_set_hash (CRTerm * a_this, CRString * a_str)
218 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
220 cr_term_clear (a_this);
222 a_this->type = TERM_HASH;
223 a_this->content.str = a_str;
228 *Appends a new term to the current list of #CRTerm.
230 *@param a_this the "this pointer" of the current instance
232 *@param a_new_term the term to append.
233 *@return the list of terms with the a_new_term appended to it.
236 cr_term_append_term (CRTerm * a_this, CRTerm * a_new_term)
240 g_return_val_if_fail (a_new_term, NULL);
245 for (cur = a_this; cur->next; cur = cur->next) ;
247 cur->next = a_new_term;
248 a_new_term->prev = cur;
254 *Prepends a term to the list of terms represented by a_this.
256 *@param a_this the "this pointer" of the current instance of
258 *@param a_new_term the term to prepend.
259 *@return the head of the new list.
262 cr_term_prepend_term (CRTerm * a_this, CRTerm * a_new_term)
264 g_return_val_if_fail (a_this && a_new_term, NULL);
266 a_new_term->next = a_this;
267 a_this->prev = a_new_term;
273 *Serializes the expression represented by
274 *the chained instances of #CRterm.
275 *@param a_this the current instance of #CRTerm
276 *@return the zero terminated string containing the serialized
277 *form of #CRTerm. MUST BE FREED BY THE CALLER using g_free().
280 cr_term_to_string (CRTerm * a_this)
282 GString *str_buf = NULL;
284 guchar *result = NULL,
287 g_return_val_if_fail (a_this, NULL);
289 str_buf = g_string_new (NULL);
290 g_return_val_if_fail (str_buf, NULL);
292 for (cur = a_this; cur; cur = cur->next) {
293 if ((cur->content.str == NULL)
294 && (cur->content.num == NULL)
295 && (cur->content.str == NULL)
296 && (cur->content.rgb == NULL))
299 switch (cur->the_operator) {
301 g_string_append (str_buf, " / ");
305 g_string_append (str_buf, ", ");
310 g_string_append (str_buf, " ");
318 switch (cur->unary_op) {
320 g_string_append (str_buf, "+");
324 g_string_append (str_buf, "-");
333 if (cur->content.num) {
334 content = cr_num_to_string (cur->content.num);
338 g_string_append (str_buf, content);
346 if (cur->content.str) {
348 (cur->content.str->stryng->str,
349 cur->content.str->stryng->len);
353 g_string_append_printf (str_buf, "%s(",
356 if (cur->ext_content.func_param) {
357 guchar *tmp_str = NULL;
359 tmp_str = cr_term_to_string
361 ext_content.func_param);
364 g_string_append (str_buf,
373 g_string_append (str_buf, ")");
379 if (cur->content.str) {
381 (cur->content.str->stryng->str,
382 cur->content.str->stryng->len);
386 g_string_append_printf (str_buf,
394 if (cur->content.str) {
396 (cur->content.str->stryng->str,
397 cur->content.str->stryng->len);
401 g_string_append (str_buf, content);
408 if (cur->content.str) {
410 (cur->content.str->stryng->str,
411 cur->content.str->stryng->len);
415 g_string_append_printf
416 (str_buf, "url(%s)", content);
423 if (cur->content.rgb) {
424 guchar *tmp_str = NULL;
426 g_string_append (str_buf, "rgb(");
427 tmp_str = cr_rgb_to_string (cur->content.rgb);
430 g_string_append (str_buf, tmp_str);
434 g_string_append (str_buf, ")");
439 case TERM_UNICODERANGE:
442 "?found unicoderange: dump not supported yet?");
446 if (cur->content.str) {
448 (cur->content.str->stryng->str,
449 cur->content.str->stryng->len);
453 g_string_append_printf (str_buf,
461 g_string_append (str_buf,
462 "Unrecognized Term type");
468 result = str_buf->str;
469 g_string_free (str_buf, FALSE);
477 cr_term_one_to_string (CRTerm * a_this)
479 GString *str_buf = NULL;
480 guchar *result = NULL,
483 g_return_val_if_fail (a_this, NULL);
485 str_buf = g_string_new (NULL);
486 g_return_val_if_fail (str_buf, NULL);
488 if ((a_this->content.str == NULL)
489 && (a_this->content.num == NULL)
490 && (a_this->content.str == NULL)
491 && (a_this->content.rgb == NULL))
494 switch (a_this->the_operator) {
496 g_string_append_printf (str_buf, " / ");
500 g_string_append_printf (str_buf, ", ");
505 g_string_append_printf (str_buf, " ");
513 switch (a_this->unary_op) {
515 g_string_append_printf (str_buf, "+");
519 g_string_append_printf (str_buf, "-");
526 switch (a_this->type) {
528 if (a_this->content.num) {
529 content = cr_num_to_string (a_this->content.num);
533 g_string_append (str_buf, content);
541 if (a_this->content.str) {
543 (a_this->content.str->stryng->str,
544 a_this->content.str->stryng->len);
548 g_string_append_printf (str_buf, "%s(",
551 if (a_this->ext_content.func_param) {
552 guchar *tmp_str = NULL;
554 tmp_str = cr_term_to_string
556 ext_content.func_param);
559 g_string_append_printf
566 g_string_append_printf (str_buf, ")");
575 if (a_this->content.str) {
577 (a_this->content.str->stryng->str,
578 a_this->content.str->stryng->len);
582 g_string_append_printf (str_buf,
590 if (a_this->content.str) {
592 (a_this->content.str->stryng->str,
593 a_this->content.str->stryng->len);
597 g_string_append (str_buf, content);
604 if (a_this->content.str) {
606 (a_this->content.str->stryng->str,
607 a_this->content.str->stryng->len);
611 g_string_append_printf
612 (str_buf, "url(%s)", content);
619 if (a_this->content.rgb) {
620 guchar *tmp_str = NULL;
622 g_string_append_printf (str_buf, "rgb(");
623 tmp_str = cr_rgb_to_string (a_this->content.rgb);
626 g_string_append (str_buf, tmp_str);
630 g_string_append_printf (str_buf, ")");
635 case TERM_UNICODERANGE:
636 g_string_append_printf
638 "?found unicoderange: dump not supported yet?");
642 if (a_this->content.str) {
644 (a_this->content.str->stryng->str,
645 a_this->content.str->stryng->len);
649 g_string_append_printf (str_buf,
657 g_string_append_printf (str_buf,
659 "Unrecognized Term type");
664 result = str_buf->str;
665 g_string_free (str_buf, FALSE);
673 *Dumps the expression (a list of terms connected by operators)
675 *TODO: finish the dump. The dump of some type of terms have not yet been
677 *@param a_this the current instance of #CRTerm.
678 *@param a_fp the destination file pointer.
681 cr_term_dump (CRTerm * a_this, FILE * a_fp)
683 guchar *content = NULL;
685 g_return_if_fail (a_this);
687 content = cr_term_to_string (a_this);
690 fprintf (a_fp, "%s", content);
696 *Return the number of terms in the expression.
697 *@param a_this the current instance of #CRTerm.
698 *@return number of terms in the expression.
701 cr_term_nr_values (CRTerm *a_this)
706 g_return_val_if_fail (a_this, -1) ;
708 for (cur = a_this ; cur ; cur = cur->next)
714 *Use an index to get a CRTerm from the expression.
715 *@param a_this the current instance of #CRTerm.
716 *@param itemnr the index into the expression.
717 *@return CRTerm at position itemnr, if itemnr > number of terms - 1,
718 *it will return NULL.
721 cr_term_get_from_list (CRTerm *a_this, int itemnr)
726 g_return_val_if_fail (a_this, NULL) ;
728 for (cur = a_this ; cur ; cur = cur->next)
735 *Increments the reference counter of the current instance
737 *@param a_this the current instance of #CRTerm.
740 cr_term_ref (CRTerm * a_this)
742 g_return_if_fail (a_this);
748 *Decrements the ref count of the current instance of
749 *#CRTerm. If the ref count reaches zero, the instance is
751 *@param a_this the current instance of #CRTerm.
752 *@return TRUE if the current instance has been destroyed, FALSE otherwise.
755 cr_term_unref (CRTerm * a_this)
757 g_return_val_if_fail (a_this, FALSE);
759 if (a_this->ref_count) {
763 if (a_this->ref_count == 0) {
764 cr_term_destroy (a_this);
772 *The destructor of the the #CRTerm class.
773 *@param a_this the "this pointer" of the current instance
777 cr_term_destroy (CRTerm * a_this)
779 g_return_if_fail (a_this);
781 cr_term_clear (a_this);
784 cr_term_destroy (a_this->next);