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 files for copyrights information.
25 #include "cr-statement.h"
26 #include "cr-parser.h"
30 *Definition of the #CRStatement class.
33 #define DECLARATION_INDENT_NB 2
35 static void cr_statement_clear (CRStatement * a_this);
38 parse_font_face_start_font_face_cb (CRDocHandler * a_this,
39 CRParsingLocation *a_location)
41 CRStatement *stmt = NULL;
42 enum CRStatus status = CR_OK;
44 stmt = cr_statement_new_at_font_face_rule (NULL, NULL);
45 g_return_if_fail (stmt);
47 status = cr_doc_handler_set_ctxt (a_this, stmt);
48 g_return_if_fail (status == CR_OK);
52 parse_font_face_unrecoverable_error_cb (CRDocHandler * a_this)
54 CRStatement *stmt = NULL;
55 CRStatement **stmtptr = NULL;
56 enum CRStatus status = CR_OK;
58 g_return_if_fail (a_this);
61 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
62 if (status != CR_OK) {
63 cr_utils_trace_info ("Couldn't get parsing context. "
64 "This may lead to some memory leaks.");
68 cr_statement_destroy (stmt);
69 cr_doc_handler_set_ctxt (a_this, NULL);
75 parse_font_face_property_cb (CRDocHandler * a_this,
77 CRTerm * a_value, gboolean a_important)
79 enum CRStatus status = CR_OK;
80 CRString *name = NULL;
81 CRDeclaration *decl = NULL;
82 CRStatement *stmt = NULL;
83 CRStatement **stmtptr = NULL;
85 g_return_if_fail (a_this && a_name);
88 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
89 g_return_if_fail (status == CR_OK && stmt);
90 g_return_if_fail (stmt->type == AT_FONT_FACE_RULE_STMT);
92 name = cr_string_dup (a_name) ;
93 g_return_if_fail (name);
94 decl = cr_declaration_new (stmt, name, a_value);
96 cr_utils_trace_info ("cr_declaration_new () failed.");
101 stmt->kind.font_face_rule->decl_list =
102 cr_declaration_append (stmt->kind.font_face_rule->decl_list,
104 if (!stmt->kind.font_face_rule->decl_list)
110 cr_declaration_unref (decl);
114 cr_string_destroy (name);
120 parse_font_face_end_font_face_cb (CRDocHandler * a_this)
122 CRStatement *result = NULL;
123 CRStatement **resultptr = NULL;
124 enum CRStatus status = CR_OK;
126 g_return_if_fail (a_this);
129 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) resultptr);
130 g_return_if_fail (status == CR_OK && result);
131 g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT);
133 status = cr_doc_handler_set_result (a_this, result);
134 g_return_if_fail (status == CR_OK);
138 parse_page_start_page_cb (CRDocHandler * a_this,
140 CRString * a_pseudo_page,
141 CRParsingLocation *a_location)
143 CRStatement *stmt = NULL;
144 enum CRStatus status = CR_OK;
145 CRString *page_name = NULL, *pseudo_name = NULL ;
148 page_name = cr_string_dup (a_name) ;
150 pseudo_name = cr_string_dup (a_pseudo_page) ;
152 stmt = cr_statement_new_at_page_rule (NULL, NULL,
157 g_return_if_fail (stmt);
158 status = cr_doc_handler_set_ctxt (a_this, stmt);
159 g_return_if_fail (status == CR_OK);
163 parse_page_unrecoverable_error_cb (CRDocHandler * a_this)
165 CRStatement *stmt = NULL;
166 CRStatement **stmtptr = NULL;
167 enum CRStatus status = CR_OK;
169 g_return_if_fail (a_this);
172 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
173 if (status != CR_OK) {
174 cr_utils_trace_info ("Couldn't get parsing context. "
175 "This may lead to some memory leaks.");
179 cr_statement_destroy (stmt);
181 cr_doc_handler_set_ctxt (a_this, NULL);
186 parse_page_property_cb (CRDocHandler * a_this,
188 CRTerm * a_expression, gboolean a_important)
190 CRString *name = NULL;
191 CRStatement *stmt = NULL;
192 CRStatement **stmtptr = NULL;
193 CRDeclaration *decl = NULL;
194 enum CRStatus status = CR_OK;
197 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
198 g_return_if_fail (status == CR_OK && stmt->type == AT_PAGE_RULE_STMT);
200 name = cr_string_dup (a_name);
201 g_return_if_fail (name);
203 decl = cr_declaration_new (stmt, name, a_expression);
204 g_return_if_fail (decl);
205 decl->important = a_important;
206 stmt->kind.page_rule->decl_list =
207 cr_declaration_append (stmt->kind.page_rule->decl_list, decl);
208 g_return_if_fail (stmt->kind.page_rule->decl_list);
212 parse_page_end_page_cb (CRDocHandler * a_this,
214 CRString * a_pseudo_page)
216 enum CRStatus status = CR_OK;
217 CRStatement *stmt = NULL;
218 CRStatement **stmtptr = NULL;
221 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
222 g_return_if_fail (status == CR_OK && stmt);
223 g_return_if_fail (stmt->type == AT_PAGE_RULE_STMT);
225 status = cr_doc_handler_set_result (a_this, stmt);
226 g_return_if_fail (status == CR_OK);
230 parse_at_media_start_media_cb (CRDocHandler * a_this,
231 GList * a_media_list,
232 CRParsingLocation *a_location)
234 enum CRStatus status = CR_OK;
235 CRStatement *at_media = NULL;
236 GList *media_list = NULL;
238 g_return_if_fail (a_this && a_this->priv);
241 /*duplicate media list */
242 media_list = cr_utils_dup_glist_of_cr_string
246 g_return_if_fail (media_list);
248 /*make sure cr_statement_new_at_media_rule works in this case. */
249 at_media = cr_statement_new_at_media_rule (NULL, NULL, media_list);
251 status = cr_doc_handler_set_ctxt (a_this, at_media);
252 g_return_if_fail (status == CR_OK);
253 status = cr_doc_handler_set_result (a_this, at_media);
254 g_return_if_fail (status == CR_OK);
258 parse_at_media_unrecoverable_error_cb (CRDocHandler * a_this)
260 enum CRStatus status = CR_OK;
261 CRStatement *stmt = NULL;
262 CRStatement **stmtptr = NULL;
264 g_return_if_fail (a_this);
267 status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr);
268 if (status != CR_OK) {
269 cr_utils_trace_info ("Couldn't get parsing context. "
270 "This may lead to some memory leaks.");
274 cr_statement_destroy (stmt);
276 cr_doc_handler_set_ctxt (a_this, NULL);
277 cr_doc_handler_set_result (a_this, NULL);
282 parse_at_media_start_selector_cb (CRDocHandler * a_this,
283 CRSelector * a_sellist)
285 enum CRStatus status = CR_OK;
286 CRStatement *at_media = NULL;
287 CRStatement **at_media_ptr = NULL;
288 CRStatement *ruleset = NULL;
290 g_return_if_fail (a_this && a_this->priv && a_sellist);
292 at_media_ptr = &at_media;
293 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) at_media_ptr);
294 g_return_if_fail (status == CR_OK && at_media);
295 g_return_if_fail (at_media->type == AT_MEDIA_RULE_STMT);
296 ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, at_media);
297 g_return_if_fail (ruleset);
298 status = cr_doc_handler_set_ctxt (a_this, ruleset);
299 g_return_if_fail (status == CR_OK);
303 parse_at_media_property_cb (CRDocHandler * a_this,
304 CRString * a_name, CRTerm * a_value,
305 gboolean a_important)
307 enum CRStatus status = CR_OK;
310 *the current ruleset stmt, child of the
311 *current at-media being parsed.
313 CRStatement *stmt = NULL;
314 CRStatement **stmtptr = NULL;
315 CRDeclaration *decl = NULL;
316 CRString *name = NULL;
318 g_return_if_fail (a_this && a_name);
320 name = cr_string_dup (a_name) ;
321 g_return_if_fail (name);
324 status = cr_doc_handler_get_ctxt (a_this,
325 (gpointer *) stmtptr);
326 g_return_if_fail (status == CR_OK && stmt);
327 g_return_if_fail (stmt->type == RULESET_STMT);
329 decl = cr_declaration_new (stmt, name, a_value);
330 g_return_if_fail (decl);
331 decl->important = a_important;
332 status = cr_statement_ruleset_append_decl (stmt, decl);
333 g_return_if_fail (status == CR_OK);
337 parse_at_media_end_selector_cb (CRDocHandler * a_this,
338 CRSelector * a_sellist)
340 enum CRStatus status = CR_OK;
343 *the current ruleset stmt, child of the
344 *current at-media being parsed.
346 CRStatement *stmt = NULL;
347 CRStatement **stmtptr = NULL;
349 g_return_if_fail (a_this && a_sellist);
352 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr);
353 g_return_if_fail (status == CR_OK && stmt
354 && stmt->type == RULESET_STMT);
355 g_return_if_fail (stmt->kind.ruleset->parent_media_rule);
357 status = cr_doc_handler_set_ctxt
358 (a_this, stmt->kind.ruleset->parent_media_rule);
359 g_return_if_fail (status == CR_OK);
363 parse_at_media_end_media_cb (CRDocHandler * a_this,
364 GList * a_media_list)
366 enum CRStatus status = CR_OK;
367 CRStatement *at_media = NULL;
368 CRStatement **at_media_ptr = NULL;
370 g_return_if_fail (a_this && a_this->priv);
372 at_media_ptr = &at_media;
373 status = cr_doc_handler_get_ctxt (a_this,
374 (gpointer *) at_media_ptr);
375 g_return_if_fail (status == CR_OK && at_media);
376 status = cr_doc_handler_set_result (a_this, at_media);
380 parse_ruleset_start_selector_cb (CRDocHandler * a_this,
381 CRSelector * a_sellist)
383 CRStatement *ruleset = NULL;
385 g_return_if_fail (a_this && a_this->priv && a_sellist);
387 ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, NULL);
388 g_return_if_fail (ruleset);
390 cr_doc_handler_set_result (a_this, ruleset);
394 parse_ruleset_unrecoverable_error_cb (CRDocHandler * a_this)
396 CRStatement *stmt = NULL;
397 CRStatement **stmtptr = NULL;
398 enum CRStatus status = CR_OK;
401 status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr);
402 if (status != CR_OK) {
403 cr_utils_trace_info ("Couldn't get parsing context. "
404 "This may lead to some memory leaks.");
408 cr_statement_destroy (stmt);
410 cr_doc_handler_set_result (a_this, NULL);
415 parse_ruleset_property_cb (CRDocHandler * a_this,
417 CRTerm * a_value, gboolean a_important)
419 enum CRStatus status = CR_OK;
420 CRStatement *ruleset = NULL;
421 CRStatement **rulesetptr = NULL;
422 CRDeclaration *decl = NULL;
423 CRString *stringue = NULL;
425 g_return_if_fail (a_this && a_this->priv && a_name);
427 stringue = cr_string_dup (a_name);
428 g_return_if_fail (stringue);
430 rulesetptr = &ruleset;
431 status = cr_doc_handler_get_result (a_this, (gpointer *) rulesetptr);
432 g_return_if_fail (status == CR_OK
434 && ruleset->type == RULESET_STMT);
436 decl = cr_declaration_new (ruleset, stringue, a_value);
437 g_return_if_fail (decl);
438 decl->important = a_important;
439 status = cr_statement_ruleset_append_decl (ruleset, decl);
440 g_return_if_fail (status == CR_OK);
444 parse_ruleset_end_selector_cb (CRDocHandler * a_this,
445 CRSelector * a_sellist)
447 CRStatement *result = NULL;
448 CRStatement **resultptr = NULL;
449 enum CRStatus status = CR_OK;
451 g_return_if_fail (a_this && a_sellist);
454 status = cr_doc_handler_get_result (a_this, (gpointer *) resultptr);
456 g_return_if_fail (status == CR_OK
458 && result->type == RULESET_STMT);
462 cr_statement_clear (CRStatement * a_this)
464 g_return_if_fail (a_this);
466 switch (a_this->type) {
470 if (!a_this->kind.ruleset)
472 if (a_this->kind.ruleset->sel_list) {
473 cr_selector_unref (a_this->kind.ruleset->sel_list);
474 a_this->kind.ruleset->sel_list = NULL;
476 if (a_this->kind.ruleset->decl_list) {
477 cr_declaration_destroy
478 (a_this->kind.ruleset->decl_list);
479 a_this->kind.ruleset->decl_list = NULL;
481 g_free (a_this->kind.ruleset);
482 a_this->kind.ruleset = NULL;
485 case AT_IMPORT_RULE_STMT:
486 if (!a_this->kind.import_rule)
488 if (a_this->kind.import_rule->url) {
490 (a_this->kind.import_rule->url) ;
491 a_this->kind.import_rule->url = NULL;
493 g_free (a_this->kind.import_rule);
494 a_this->kind.import_rule = NULL;
497 case AT_MEDIA_RULE_STMT:
498 if (!a_this->kind.media_rule)
500 if (a_this->kind.media_rule->rulesets) {
502 (a_this->kind.media_rule->rulesets);
503 a_this->kind.media_rule->rulesets = NULL;
505 if (a_this->kind.media_rule->media_list) {
508 for (cur = a_this->kind.media_rule->media_list;
509 cur; cur = cur->next) {
511 cr_string_destroy ((CRString *) cur->data);
516 g_list_free (a_this->kind.media_rule->media_list);
517 a_this->kind.media_rule->media_list = NULL;
519 g_free (a_this->kind.media_rule);
520 a_this->kind.media_rule = NULL;
523 case AT_PAGE_RULE_STMT:
524 if (!a_this->kind.page_rule)
527 if (a_this->kind.page_rule->decl_list) {
528 cr_declaration_destroy
529 (a_this->kind.page_rule->decl_list);
530 a_this->kind.page_rule->decl_list = NULL;
532 if (a_this->kind.page_rule->name) {
534 (a_this->kind.page_rule->name);
535 a_this->kind.page_rule->name = NULL;
537 if (a_this->kind.page_rule->pseudo) {
539 (a_this->kind.page_rule->pseudo);
540 a_this->kind.page_rule->pseudo = NULL;
542 g_free (a_this->kind.page_rule);
543 a_this->kind.page_rule = NULL;
546 case AT_CHARSET_RULE_STMT:
547 if (!a_this->kind.charset_rule)
550 if (a_this->kind.charset_rule->charset) {
552 (a_this->kind.charset_rule->charset);
553 a_this->kind.charset_rule->charset = NULL;
555 g_free (a_this->kind.charset_rule);
556 a_this->kind.charset_rule = NULL;
559 case AT_FONT_FACE_RULE_STMT:
560 if (!a_this->kind.font_face_rule)
563 if (a_this->kind.font_face_rule->decl_list) {
565 (a_this->kind.font_face_rule->decl_list);
566 a_this->kind.font_face_rule->decl_list = NULL;
568 g_free (a_this->kind.font_face_rule);
569 a_this->kind.font_face_rule = NULL;
578 * cr_statement_ruleset_to_string:
580 *@a_this: the current instance of #CRStatement
581 *@a_indent: the number of whitespace to use for indentation
583 *Serializes the ruleset statement into a string
585 *Returns the newly allocated serialised string. Must be freed
586 *by the caller, using g_free().
589 cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent)
591 GString *stringue = NULL;
592 gchar *tmp_str = NULL,
595 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, NULL);
597 stringue = g_string_new (NULL);
599 if (a_this->kind.ruleset->sel_list) {
601 cr_utils_dump_n_chars2 (' ', stringue, a_indent);
604 cr_selector_to_string (a_this->kind.ruleset->
607 g_string_append (stringue, tmp_str);
612 g_string_append (stringue, " {\n");
613 if (a_this->kind.ruleset->decl_list) {
614 tmp_str = cr_declaration_list_to_string2
615 (a_this->kind.ruleset->decl_list,
616 a_indent + DECLARATION_INDENT_NB, TRUE);
618 g_string_append (stringue, tmp_str);
622 g_string_append (stringue, "\n");
623 cr_utils_dump_n_chars2 (' ', stringue, a_indent);
625 g_string_append (stringue, "}");
626 result = stringue->str;
629 g_string_free (stringue, FALSE);
641 * cr_statement_font_face_rule_to_string:
643 *@a_this: the current instance of #CRStatement to consider
644 *It must be a font face rule statement.
645 *@a_indent: the number of white spaces of indentation.
647 *Serializes a font face rule statement into a string.
649 *Returns the serialized string. Must be deallocated by the caller
653 cr_statement_font_face_rule_to_string (CRStatement const * a_this,
656 gchar *result = NULL, *tmp_str = NULL ;
657 GString *stringue = NULL ;
659 g_return_val_if_fail (a_this
660 && a_this->type == AT_FONT_FACE_RULE_STMT,
663 if (a_this->kind.font_face_rule->decl_list) {
664 stringue = g_string_new (NULL) ;
665 g_return_val_if_fail (stringue, NULL) ;
667 cr_utils_dump_n_chars2 (' ', stringue,
669 g_string_append (stringue, "@font-face {\n");
670 tmp_str = cr_declaration_list_to_string2
671 (a_this->kind.font_face_rule->decl_list,
672 a_indent + DECLARATION_INDENT_NB, TRUE) ;
674 g_string_append (stringue,
679 g_string_append (stringue, "\n}");
682 result = stringue->str ;
683 g_string_free (stringue, FALSE) ;
691 * cr_statement_charset_to_string:
693 *Serialises an \@charset statement into a string.
694 *@a_this: the statement to serialize.
695 *@a_indent: the number of indentation spaces
697 *Returns the serialized charset statement. Must be
698 *freed by the caller using g_free().
701 cr_statement_charset_to_string (CRStatement const *a_this,
705 GString *stringue = NULL ;
707 g_return_val_if_fail (a_this
708 && a_this->type == AT_CHARSET_RULE_STMT,
711 if (a_this->kind.charset_rule
712 && a_this->kind.charset_rule->charset
713 && a_this->kind.charset_rule->charset->stryng
714 && a_this->kind.charset_rule->charset->stryng->str) {
715 str = g_strndup (a_this->kind.charset_rule->charset->stryng->str,
716 a_this->kind.charset_rule->charset->stryng->len);
717 g_return_val_if_fail (str, NULL);
718 stringue = g_string_new (NULL) ;
719 g_return_val_if_fail (stringue, NULL) ;
720 cr_utils_dump_n_chars2 (' ', stringue, a_indent);
721 g_string_append_printf (stringue,
722 "@charset \"%s\" ;", str);
729 str = stringue->str ;
730 g_string_free (stringue, FALSE) ;
737 * cr_statement_at_page_rule_to_string:
739 *Serialises the at page rule statement into a string
740 *@a_this: the current instance of #CRStatement. Must
741 *be an "\@page" rule statement.
743 *Returns the serialized string. Must be freed by the caller
746 cr_statement_at_page_rule_to_string (CRStatement const *a_this,
749 GString *stringue = NULL;
750 gchar *result = NULL ;
752 stringue = g_string_new (NULL) ;
754 cr_utils_dump_n_chars2 (' ', stringue, a_indent) ;
755 g_string_append (stringue, "@page");
756 if (a_this->kind.page_rule->name
757 && a_this->kind.page_rule->name->stryng) {
758 g_string_append_printf
760 a_this->kind.page_rule->name->stryng->str) ;
762 g_string_append (stringue, " ");
764 if (a_this->kind.page_rule->pseudo
765 && a_this->kind.page_rule->pseudo->stryng) {
766 g_string_append_printf
768 a_this->kind.page_rule->pseudo->stryng->str) ;
770 if (a_this->kind.page_rule->decl_list) {
772 g_string_append (stringue, " {\n");
773 str = cr_declaration_list_to_string2
774 (a_this->kind.page_rule->decl_list,
775 a_indent + DECLARATION_INDENT_NB, TRUE) ;
777 g_string_append (stringue, str) ;
781 g_string_append (stringue, "\n}\n");
783 result = stringue->str ;
784 g_string_free (stringue, FALSE) ;
791 *Serializes an \@media statement.
792 *@param a_this the current instance of #CRStatement
793 *@param a_indent the number of spaces of indentation.
794 *@return the serialized \@media statement. Must be freed
795 *by the caller using g_free().
798 cr_statement_media_rule_to_string (CRStatement const *a_this,
802 GString *stringue = NULL ;
803 GList const *cur = NULL;
805 g_return_val_if_fail (a_this->type == AT_MEDIA_RULE_STMT,
808 if (a_this->kind.media_rule) {
809 stringue = g_string_new (NULL) ;
810 cr_utils_dump_n_chars2 (' ', stringue, a_indent);
811 g_string_append (stringue, "@media");
813 for (cur = a_this->kind.media_rule->media_list; cur;
816 guchar *str = cr_string_dup2
817 ((CRString const *) cur->data);
825 g_string_append_printf
833 g_string_append (stringue, " {\n");
834 str = cr_statement_list_to_string
835 (a_this->kind.media_rule->rulesets,
836 a_indent + DECLARATION_INDENT_NB) ;
838 g_string_append (stringue, str) ;
842 g_string_append (stringue, "\n}");
845 str = stringue->str ;
846 g_string_free (stringue, FALSE) ;
853 cr_statement_import_rule_to_string (CRStatement const *a_this,
856 GString *stringue = NULL ;
859 g_return_val_if_fail (a_this
860 && a_this->type == AT_IMPORT_RULE_STMT
861 && a_this->kind.import_rule,
864 if (a_this->kind.import_rule->url
865 && a_this->kind.import_rule->url->stryng) {
866 stringue = g_string_new (NULL) ;
867 g_return_val_if_fail (stringue, NULL) ;
868 str = g_strndup (a_this->kind.import_rule->url->stryng->str,
869 a_this->kind.import_rule->url->stryng->len);
870 cr_utils_dump_n_chars2 (' ', stringue, a_indent);
872 g_string_append_printf (stringue,
873 "@import url(\"%s\")",
877 } else /*there is no url, so no import rule, get out! */
880 if (a_this->kind.import_rule->media_list) {
881 GList const *cur = NULL;
883 for (cur = a_this->kind.import_rule->media_list;
884 cur; cur = cur->next) {
886 CRString const *crstr = cur->data;
894 && crstr->stryng->str) {
898 crstr->stryng->len) ;
903 g_string_append (stringue, " ;");
906 str = stringue->str ;
907 g_string_free (stringue, FALSE) ;
919 * cr_statement_does_buf_parses_against_core:
921 *@a_buf: the buffer to parse.
922 *@a_encoding: the character encoding of a_buf.
924 *Tries to parse a buffer and says whether if the content of the buffer
925 *is a css statement as defined by the "Core CSS Grammar" (chapter 4 of the
928 *Returns TRUE if the buffer parses against the core grammar, false otherwise.
931 cr_statement_does_buf_parses_against_core (const guchar * a_buf,
932 enum CREncoding a_encoding)
934 CRParser *parser = NULL;
935 enum CRStatus status = CR_OK;
936 gboolean result = FALSE;
938 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
940 g_return_val_if_fail (parser, FALSE);
942 status = cr_parser_set_use_core_grammar (parser, TRUE);
943 if (status != CR_OK) {
947 status = cr_parser_parse_statement_core (parser);
948 if (status == CR_OK) {
954 cr_parser_destroy (parser);
961 * cr_statement_parse_from_buf:
963 *@a_buf: the buffer to parse.
964 *@a_encoding: the character encoding of a_buf.
966 *Parses a buffer that contains a css statement and returns
967 *an instance of #CRStatement in case of successful parsing.
968 *TODO: at support of "\@import" rules.
970 *Returns the newly built instance of #CRStatement in case
971 *of successful parsing, NULL otherwise.
974 cr_statement_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding)
976 CRStatement *result = NULL;
979 *The strategy of this function is "brute force".
980 *It tries to parse all the types of CRStatement it knows about.
981 *I could do this a smarter way but I don't have the time now.
982 *I think I will revisit this when time of performances and
983 *pull based incremental parsing comes.
986 result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding);
988 result = cr_statement_at_charset_rule_parse_from_buf
995 result = cr_statement_at_media_rule_parse_from_buf
1002 result = cr_statement_at_charset_rule_parse_from_buf
1003 (a_buf, a_encoding);
1009 result = cr_statement_font_face_rule_parse_from_buf
1010 (a_buf, a_encoding);
1017 result = cr_statement_at_page_rule_parse_from_buf
1018 (a_buf, a_encoding);
1024 result = cr_statement_at_import_rule_parse_from_buf
1025 (a_buf, a_encoding);
1035 * cr_statement_ruleset_parse_from_buf:
1037 *@a_buf: the buffer to parse.
1038 *@a_enc: the character encoding of a_buf.
1040 *Parses a buffer that contains a ruleset statement an instanciates
1041 *a #CRStatement of type RULESET_STMT.
1043 *Returns the newly built instance of #CRStatement in case of successful parsing,
1047 cr_statement_ruleset_parse_from_buf (const guchar * a_buf,
1048 enum CREncoding a_enc)
1050 enum CRStatus status = CR_OK;
1051 CRStatement *result = NULL;
1052 CRStatement **resultptr = NULL;
1053 CRParser *parser = NULL;
1054 CRDocHandler *sac_handler = NULL;
1056 g_return_val_if_fail (a_buf, NULL);
1058 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1061 g_return_val_if_fail (parser, NULL);
1063 sac_handler = cr_doc_handler_new ();
1064 g_return_val_if_fail (parser, NULL);
1066 sac_handler->start_selector = parse_ruleset_start_selector_cb;
1067 sac_handler->end_selector = parse_ruleset_end_selector_cb;
1068 sac_handler->property = parse_ruleset_property_cb;
1069 sac_handler->unrecoverable_error =
1070 parse_ruleset_unrecoverable_error_cb;
1072 cr_parser_set_sac_handler (parser, sac_handler);
1073 cr_parser_try_to_skip_spaces_and_comments (parser);
1074 status = cr_parser_parse_ruleset (parser);
1075 if (status != CR_OK) {
1079 resultptr = &result;
1080 status = cr_doc_handler_get_result (sac_handler,
1081 (gpointer *) resultptr);
1082 if (!((status == CR_OK) && result)) {
1084 cr_statement_destroy (result);
1091 cr_parser_destroy (parser);
1093 sac_handler = NULL ;
1096 cr_doc_handler_unref (sac_handler);
1103 * cr_statement_new_ruleset:
1105 *@a_sel_list: the list of #CRSimpleSel (selectors)
1106 *the rule applies to.
1107 *@a_decl_list: the list of instances of #CRDeclaration
1108 *that composes the ruleset.
1109 *@a_media_types: a list of instances of GString that
1110 *describe the media list this ruleset applies to.
1112 *Creates a new instance of #CRStatement of type
1115 *Returns the new instance of #CRStatement or NULL if something
1119 cr_statement_new_ruleset (CRStyleSheet * a_sheet,
1120 CRSelector * a_sel_list,
1121 CRDeclaration * a_decl_list,
1122 CRStatement * a_parent_media_rule)
1124 CRStatement *result = NULL;
1126 g_return_val_if_fail (a_sel_list, NULL);
1128 if (a_parent_media_rule) {
1129 g_return_val_if_fail
1130 (a_parent_media_rule->type == AT_MEDIA_RULE_STMT,
1132 g_return_val_if_fail (a_parent_media_rule->kind.media_rule,
1136 result = g_try_malloc (sizeof (CRStatement));
1139 cr_utils_trace_info ("Out of memory");
1143 memset (result, 0, sizeof (CRStatement));
1144 result->type = RULESET_STMT;
1145 result->kind.ruleset = g_try_malloc (sizeof (CRRuleSet));
1147 if (!result->kind.ruleset) {
1148 cr_utils_trace_info ("Out of memory");
1154 memset (result->kind.ruleset, 0, sizeof (CRRuleSet));
1155 result->kind.ruleset->sel_list = a_sel_list;
1157 cr_selector_ref (a_sel_list);
1158 result->kind.ruleset->decl_list = a_decl_list;
1160 if (a_parent_media_rule) {
1161 result->kind.ruleset->parent_media_rule = a_parent_media_rule;
1162 a_parent_media_rule->kind.media_rule->rulesets =
1164 (a_parent_media_rule->kind.media_rule->rulesets,
1168 cr_statement_set_parent_sheet (result, a_sheet);
1174 * cr_statement_at_media_rule_parse_from_buf:
1176 *@a_buf: the input to parse.
1177 *@a_enc: the encoding of the buffer.
1179 *Parses a buffer that contains an "\@media" declaration
1180 *and builds an \@media css statement.
1182 *Returns the \@media statement, or NULL if the buffer could not
1183 *be successfully parsed.
1186 cr_statement_at_media_rule_parse_from_buf (const guchar * a_buf,
1187 enum CREncoding a_enc)
1189 CRParser *parser = NULL;
1190 CRStatement *result = NULL;
1191 CRStatement **resultptr = NULL;
1192 CRDocHandler *sac_handler = NULL;
1193 enum CRStatus status = CR_OK;
1195 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1198 cr_utils_trace_info ("Instanciation of the parser failed");
1202 sac_handler = cr_doc_handler_new ();
1205 ("Instanciation of the sac handler failed");
1209 sac_handler->start_media = parse_at_media_start_media_cb;
1210 sac_handler->start_selector = parse_at_media_start_selector_cb;
1211 sac_handler->property = parse_at_media_property_cb;
1212 sac_handler->end_selector = parse_at_media_end_selector_cb;
1213 sac_handler->end_media = parse_at_media_end_media_cb;
1214 sac_handler->unrecoverable_error =
1215 parse_at_media_unrecoverable_error_cb;
1217 status = cr_parser_set_sac_handler (parser, sac_handler);
1218 if (status != CR_OK)
1221 status = cr_parser_try_to_skip_spaces_and_comments (parser);
1222 if (status != CR_OK)
1225 status = cr_parser_parse_media (parser);
1226 if (status != CR_OK)
1229 resultptr = &result;
1230 status = cr_doc_handler_get_result (sac_handler,
1231 (gpointer *) resultptr);
1232 if (status != CR_OK)
1238 cr_parser_destroy (parser);
1240 sac_handler = NULL ;
1243 cr_doc_handler_unref (sac_handler);
1251 * cr_statement_new_at_media_rule:
1253 *@a_ruleset: the ruleset statements contained
1254 *in the \@media rule.
1255 *@a_media: the media string list. A list of GString pointers.
1257 *Instanciates an instance of #CRStatement of type
1258 *AT_MEDIA_RULE_STMT (\@media ruleset).
1262 cr_statement_new_at_media_rule (CRStyleSheet * a_sheet,
1263 CRStatement * a_rulesets, GList * a_media)
1265 CRStatement *result = NULL,
1269 g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL);
1271 result = g_try_malloc (sizeof (CRStatement));
1274 cr_utils_trace_info ("Out of memory");
1278 memset (result, 0, sizeof (CRStatement));
1279 result->type = AT_MEDIA_RULE_STMT;
1281 result->kind.media_rule = g_try_malloc (sizeof (CRAtMediaRule));
1282 if (!result->kind.media_rule) {
1283 cr_utils_trace_info ("Out of memory");
1287 memset (result->kind.media_rule, 0, sizeof (CRAtMediaRule));
1288 result->kind.media_rule->rulesets = a_rulesets;
1289 for (cur = a_rulesets; cur; cur = cur->next) {
1290 if (cur->type != RULESET_STMT || !cur->kind.ruleset) {
1291 cr_utils_trace_info ("Bad parameter a_rulesets. "
1292 "It should be a list of "
1293 "correct ruleset statement only !");
1296 cur->kind.ruleset->parent_media_rule = result;
1299 result->kind.media_rule->media_list = a_media;
1301 cr_statement_set_parent_sheet (result, a_sheet);
1311 * cr_statement_new_at_import_rule:
1313 *@a_url: the url to connect to the get the file
1315 *@a_sheet: the imported parsed stylesheet.
1317 *Creates a new instance of #CRStatment of type
1320 *Returns the newly built instance of #CRStatement.
1323 cr_statement_new_at_import_rule (CRStyleSheet * a_container_sheet,
1325 GList * a_media_list,
1326 CRStyleSheet * a_imported_sheet)
1328 CRStatement *result = NULL;
1330 result = g_try_malloc (sizeof (CRStatement));
1333 cr_utils_trace_info ("Out of memory");
1337 memset (result, 0, sizeof (CRStatement));
1338 result->type = AT_IMPORT_RULE_STMT;
1340 result->kind.import_rule = g_try_malloc (sizeof (CRAtImportRule));
1342 if (!result->kind.import_rule) {
1343 cr_utils_trace_info ("Out of memory");
1348 memset (result->kind.import_rule, 0, sizeof (CRAtImportRule));
1349 result->kind.import_rule->url = a_url;
1350 result->kind.import_rule->media_list = a_media_list;
1351 result->kind.import_rule->sheet = a_imported_sheet;
1352 if (a_container_sheet)
1353 cr_statement_set_parent_sheet (result, a_container_sheet);
1359 * cr_statement_at_import_rule_parse_from_buf:
1361 *@a_buf: the buffer to parse.
1362 *@a_encoding: the encoding of a_buf.
1364 *Parses a buffer that contains an "\@import" rule and
1365 *instanciate a #CRStatement of type AT_IMPORT_RULE_STMT
1367 *Returns the newly built instance of #CRStatement in case of
1368 *a successful parsing, NULL otherwise.
1371 cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf,
1372 enum CREncoding a_encoding)
1374 enum CRStatus status = CR_OK;
1375 CRParser *parser = NULL;
1376 CRStatement *result = NULL;
1377 GList *media_list = NULL;
1378 CRString *import_string = NULL;
1379 CRParsingLocation location = {0} ;
1381 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1384 cr_utils_trace_info ("Instanciation of parser failed.");
1388 status = cr_parser_try_to_skip_spaces_and_comments (parser);
1389 if (status != CR_OK)
1392 status = cr_parser_parse_import (parser,
1396 if (status != CR_OK || !import_string)
1399 result = cr_statement_new_at_import_rule (NULL, import_string,
1402 cr_parsing_location_copy (&result->location,
1404 import_string = NULL;
1410 cr_parser_destroy (parser);
1416 for (cur = media_list; media_list;
1417 media_list = g_list_next (media_list)) {
1418 if (media_list->data) {
1419 cr_string_destroy ((CRString*)media_list->data);
1420 media_list->data = NULL;
1423 g_list_free (media_list);
1426 if (import_string) {
1427 cr_string_destroy (import_string);
1428 import_string = NULL;
1435 * cr_statement_new_at_page_rule:
1437 *@a_decl_list: a list of instances of #CRDeclarations
1438 *which is actually the list of declarations that applies to
1440 *@a_selector: the page rule selector.
1442 *Creates a new instance of #CRStatement of type
1445 *Returns the newly built instance of #CRStatement or NULL
1449 cr_statement_new_at_page_rule (CRStyleSheet * a_sheet,
1450 CRDeclaration * a_decl_list,
1451 CRString * a_name, CRString * a_pseudo)
1453 CRStatement *result = NULL;
1455 result = g_try_malloc (sizeof (CRStatement));
1458 cr_utils_trace_info ("Out of memory");
1462 memset (result, 0, sizeof (CRStatement));
1463 result->type = AT_PAGE_RULE_STMT;
1465 result->kind.page_rule = g_try_malloc (sizeof (CRAtPageRule));
1467 if (!result->kind.page_rule) {
1468 cr_utils_trace_info ("Out of memory");
1473 memset (result->kind.page_rule, 0, sizeof (CRAtPageRule));
1475 result->kind.page_rule->decl_list = a_decl_list;
1476 cr_declaration_ref (a_decl_list);
1478 result->kind.page_rule->name = a_name;
1479 result->kind.page_rule->pseudo = a_pseudo;
1481 cr_statement_set_parent_sheet (result, a_sheet);
1487 * cr_statement_at_page_rule_parse_from_buf:
1489 *@a_buf: the character buffer to parse.
1490 *@a_encoding: the character encoding of a_buf.
1492 *Parses a buffer that contains an "\@page" production and,
1493 *if the parsing succeeds, builds the page statement.
1495 *Returns the newly built at page statement in case of successful parsing,
1499 cr_statement_at_page_rule_parse_from_buf (const guchar * a_buf,
1500 enum CREncoding a_encoding)
1502 enum CRStatus status = CR_OK;
1503 CRParser *parser = NULL;
1504 CRDocHandler *sac_handler = NULL;
1505 CRStatement *result = NULL;
1506 CRStatement **resultptr = NULL;
1508 g_return_val_if_fail (a_buf, NULL);
1510 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1513 cr_utils_trace_info ("Instanciation of the parser failed.");
1517 sac_handler = cr_doc_handler_new ();
1520 ("Instanciation of the sac handler failed.");
1524 sac_handler->start_page = parse_page_start_page_cb;
1525 sac_handler->property = parse_page_property_cb;
1526 sac_handler->end_page = parse_page_end_page_cb;
1527 sac_handler->unrecoverable_error = parse_page_unrecoverable_error_cb;
1529 status = cr_parser_set_sac_handler (parser, sac_handler);
1530 if (status != CR_OK)
1533 /*Now, invoke the parser to parse the "@page production" */
1534 cr_parser_try_to_skip_spaces_and_comments (parser);
1535 if (status != CR_OK)
1537 status = cr_parser_parse_page (parser);
1538 if (status != CR_OK)
1541 resultptr = &result;
1542 status = cr_doc_handler_get_result (sac_handler,
1543 (gpointer *) resultptr);
1548 cr_parser_destroy (parser);
1550 sac_handler = NULL ;
1553 cr_doc_handler_unref (sac_handler);
1560 * cr_statement_new_at_charset_rule:
1562 *@a_charset: the string representing the charset.
1563 *Note that the newly built instance of #CRStatement becomes
1564 *the owner of a_charset. The caller must not free a_charset !!!.
1566 *Creates a new instance of #CRStatement of type
1569 *Returns the newly built instance of #CRStatement or NULL
1570 *if an error arises.
1573 cr_statement_new_at_charset_rule (CRStyleSheet * a_sheet,
1574 CRString * a_charset)
1576 CRStatement *result = NULL;
1578 g_return_val_if_fail (a_charset, NULL);
1580 result = g_try_malloc (sizeof (CRStatement));
1583 cr_utils_trace_info ("Out of memory");
1587 memset (result, 0, sizeof (CRStatement));
1588 result->type = AT_CHARSET_RULE_STMT;
1590 result->kind.charset_rule = g_try_malloc (sizeof (CRAtCharsetRule));
1592 if (!result->kind.charset_rule) {
1593 cr_utils_trace_info ("Out of memory");
1597 memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule));
1598 result->kind.charset_rule->charset = a_charset;
1599 cr_statement_set_parent_sheet (result, a_sheet);
1605 * cr_statement_at_charset_rule_parse_from_buf:
1607 *@a_buf: the buffer to parse.
1608 *@a_encoding: the character encoding of the buffer.
1610 *Parses a buffer that contains an '\@charset' rule and
1611 *creates an instance of #CRStatement of type AT_CHARSET_RULE_STMT.
1613 *Returns the newly built instance of #CRStatement.
1616 cr_statement_at_charset_rule_parse_from_buf (const guchar * a_buf,
1617 enum CREncoding a_encoding)
1619 enum CRStatus status = CR_OK;
1620 CRParser *parser = NULL;
1621 CRStatement *result = NULL;
1622 CRString *charset = NULL;
1624 g_return_val_if_fail (a_buf, NULL);
1626 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1629 cr_utils_trace_info ("Instanciation of the parser failed.");
1633 /*Now, invoke the parser to parse the "@charset production" */
1634 cr_parser_try_to_skip_spaces_and_comments (parser);
1635 if (status != CR_OK)
1637 status = cr_parser_parse_charset (parser, &charset, NULL);
1638 if (status != CR_OK || !charset)
1641 result = cr_statement_new_at_charset_rule (NULL, charset);
1648 cr_parser_destroy (parser);
1652 cr_string_destroy (charset);
1659 * cr_statement_new_at_font_face_rule:
1661 *@a_font_decls: a list of instances of #CRDeclaration. Each declaration
1662 *is actually a font declaration.
1664 *Creates an instance of #CRStatement of type #CRAtFontFaceRule.
1666 *Returns the newly built instance of #CRStatement.
1669 cr_statement_new_at_font_face_rule (CRStyleSheet * a_sheet,
1670 CRDeclaration * a_font_decls)
1672 CRStatement *result = NULL;
1674 result = g_try_malloc (sizeof (CRStatement));
1677 cr_utils_trace_info ("Out of memory");
1680 memset (result, 0, sizeof (CRStatement));
1681 result->type = AT_FONT_FACE_RULE_STMT;
1683 result->kind.font_face_rule = g_try_malloc
1684 (sizeof (CRAtFontFaceRule));
1686 if (!result->kind.font_face_rule) {
1687 cr_utils_trace_info ("Out of memory");
1691 memset (result->kind.font_face_rule, 0, sizeof (CRAtFontFaceRule));
1693 result->kind.font_face_rule->decl_list = a_font_decls;
1695 cr_statement_set_parent_sheet (result, a_sheet);
1701 * cr_statement_font_face_rule_parse_from_buf:
1704 *@a_buf: the buffer to parse.
1705 *@a_encoding: the character encoding of a_buf.
1707 *Parses a buffer that contains an "\@font-face" rule and builds
1708 *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it.
1710 *Returns the newly built instance of #CRStatement in case of successufull
1711 *parsing, NULL otherwise.
1714 cr_statement_font_face_rule_parse_from_buf (const guchar * a_buf,
1715 enum CREncoding a_encoding)
1717 CRStatement *result = NULL;
1718 CRStatement **resultptr = NULL;
1719 CRParser *parser = NULL;
1720 CRDocHandler *sac_handler = NULL;
1721 enum CRStatus status = CR_OK;
1723 parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf),
1728 sac_handler = cr_doc_handler_new ();
1733 *set sac callbacks here
1735 sac_handler->start_font_face = parse_font_face_start_font_face_cb;
1736 sac_handler->property = parse_font_face_property_cb;
1737 sac_handler->end_font_face = parse_font_face_end_font_face_cb;
1738 sac_handler->unrecoverable_error =
1739 parse_font_face_unrecoverable_error_cb;
1741 status = cr_parser_set_sac_handler (parser, sac_handler);
1742 if (status != CR_OK)
1746 *cleanup spaces of comment that may be there before the real
1747 *"@font-face" thing.
1749 status = cr_parser_try_to_skip_spaces_and_comments (parser);
1750 if (status != CR_OK)
1753 status = cr_parser_parse_font_face (parser);
1754 if (status != CR_OK)
1757 resultptr = &result;
1758 status = cr_doc_handler_get_result (sac_handler,
1759 (gpointer *) resultptr);
1760 if (status != CR_OK || !result)
1765 cr_parser_destroy (parser);
1767 sac_handler = NULL ;
1770 cr_doc_handler_unref (sac_handler);
1777 * cr_statement_set_parent_sheet:
1779 *@a_this: the current instance of #CRStatement.
1780 *@a_sheet: the sheet that contains the current statement.
1782 *Sets the container stylesheet.
1784 *Returns CR_OK upon successful completion, an error code otherwise.
1787 cr_statement_set_parent_sheet (CRStatement * a_this, CRStyleSheet * a_sheet)
1789 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1790 a_this->parent_sheet = a_sheet;
1795 * cr_statement_get_parent_sheet:
1797 *@a_this: the current #CRStatement.
1798 *@a_sheet: out parameter. A pointer to the sheets that
1800 *Gets the sheets that contains the current statement.
1802 *Returns CR_OK upon successful completion, an error code otherwise.
1805 cr_statement_get_parent_sheet (CRStatement * a_this, CRStyleSheet ** a_sheet)
1807 g_return_val_if_fail (a_this && a_sheet, CR_BAD_PARAM_ERROR);
1808 *a_sheet = a_this->parent_sheet;
1813 * cr_statement_append:
1815 *@a_this: the current instance of the statement list.
1816 *@a_new: a_new the new instance of #CRStatement to append.
1818 *Appends a new statement to the statement list.
1820 *Returns the new list statement list, or NULL in cas of failure.
1823 cr_statement_append (CRStatement * a_this, CRStatement * a_new)
1825 CRStatement *cur = NULL;
1827 g_return_val_if_fail (a_new, NULL);
1833 /*walk forward in the current list to find the tail list element */
1834 for (cur = a_this; cur && cur->next; cur = cur->next) ;
1843 * cr_statement_prepend:
1845 *@a_this: the current instance of #CRStatement.
1846 *@a_new: the new statement to prepend.
1848 *Prepends the an instance of #CRStatement to
1849 *the current statement list.
1851 *Returns the new list with the new statement prepended,
1852 *or NULL in case of an error.
1855 cr_statement_prepend (CRStatement * a_this, CRStatement * a_new)
1857 CRStatement *cur = NULL;
1859 g_return_val_if_fail (a_new, NULL);
1864 a_new->next = a_this;
1865 a_this->prev = a_new;
1867 /*walk backward in the prepended list to find the head list element */
1868 for (cur = a_new; cur && cur->prev; cur = cur->prev) ;
1874 * cr_statement_unlink:
1876 *@a_this: the current statements list.
1877 *@a_to_unlink: the statement to unlink from the list.
1879 *Unlinks a statement from the statements list.
1881 *Returns the new list where a_to_unlink has been unlinked
1882 *from, or NULL in case of error.
1885 cr_statement_unlink (CRStatement * a_stmt)
1887 CRStatement *result = a_stmt;
1889 g_return_val_if_fail (result, NULL);
1892 *Some sanity checks first
1895 g_return_val_if_fail (a_stmt->next->prev == a_stmt, NULL);
1898 g_return_val_if_fail (a_stmt->prev->next == a_stmt, NULL);
1902 *Now, the real unlinking job.
1905 a_stmt->next->prev = a_stmt->prev;
1908 a_stmt->prev->next = a_stmt->next;
1911 if (a_stmt->parent_sheet
1912 && a_stmt->parent_sheet->statements == a_stmt) {
1913 a_stmt->parent_sheet->statements =
1914 a_stmt->parent_sheet->statements->next;
1917 a_stmt->next = NULL;
1918 a_stmt->prev = NULL;
1919 a_stmt->parent_sheet = NULL;
1925 * cr_statement_nr_rules:
1927 *@a_this: the current instance of #CRStatement.
1929 *Gets the number of rules in the statement list;
1931 *Returns number of rules in the statement list.
1934 cr_statement_nr_rules (CRStatement const * a_this)
1936 CRStatement const *cur = NULL;
1939 g_return_val_if_fail (a_this, -1);
1941 for (cur = a_this; cur; cur = cur->next)
1947 * cr_statement_get_from_list:
1949 *@a_this: the current instance of #CRStatement.
1950 *@itemnr: the index into the statement list.
1952 *Use an index to get a CRStatement from the statement list.
1954 *Returns CRStatement at position itemnr, if itemnr > number of statements - 1,
1955 *it will return NULL.
1958 cr_statement_get_from_list (CRStatement * a_this, int itemnr)
1960 CRStatement *cur = NULL;
1963 g_return_val_if_fail (a_this, NULL);
1965 for (cur = a_this; cur; cur = cur->next)
1972 * cr_statement_ruleset_set_sel_list:
1974 *@a_this: the current ruleset statement.
1975 *@a_sel_list: the selector list to set. Note
1976 *that this function increments the ref count of a_sel_list.
1977 *The sel list will be destroyed at the destruction of the
1978 *current instance of #CRStatement.
1980 *Sets a selector list to a ruleset statement.
1982 *Returns CR_OK upon successful completion, an error code otherwise.
1985 cr_statement_ruleset_set_sel_list (CRStatement * a_this,
1986 CRSelector * a_sel_list)
1988 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT,
1989 CR_BAD_PARAM_ERROR);
1991 if (a_this->kind.ruleset->sel_list)
1992 cr_selector_unref (a_this->kind.ruleset->sel_list);
1994 a_this->kind.ruleset->sel_list = a_sel_list;
1997 cr_selector_ref (a_sel_list);
2003 * cr_statement_ruleset_get_declarations:
2005 *@a_this: the current instance of #CRStatement.
2006 *@a_decl_list: out parameter. A pointer to the the returned
2007 *list of declaration. Must not be NULL.
2009 *Gets a pointer to the list of declaration contained
2010 *in the ruleset statement.
2012 *Returns CR_OK upon successful completion, an error code if something
2016 cr_statement_ruleset_get_declarations (CRStatement * a_this,
2017 CRDeclaration ** a_decl_list)
2019 g_return_val_if_fail (a_this
2020 && a_this->type == RULESET_STMT
2021 && a_this->kind.ruleset
2022 && a_decl_list, CR_BAD_PARAM_ERROR);
2024 *a_decl_list = a_this->kind.ruleset->decl_list;
2030 * cr_statement_ruleset_get_sel_list:
2032 *@a_this: the current ruleset statement.
2033 *@a_list: out parameter. The returned selector list,
2034 *if and only if the function returned CR_OK.
2036 *Gets a pointer to the selector list contained in
2037 *the current ruleset statement.
2039 *Returns CR_OK upon successful completion, an error code otherwise.
2042 cr_statement_ruleset_get_sel_list (CRStatement const * a_this, CRSelector ** a_list)
2044 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2045 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2047 *a_list = a_this->kind.ruleset->sel_list;
2053 * cr_statement_ruleset_set_decl_list:
2055 *@a_this: the current ruleset statement.
2056 *@a_list: the declaration list to be added to the current
2059 *Sets a declaration list to the current ruleset statement.
2061 *Returns CR_OK upon successful completion, an error code otherwise.
2064 cr_statement_ruleset_set_decl_list (CRStatement * a_this,
2065 CRDeclaration * a_list)
2067 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2068 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2070 if (a_this->kind.ruleset->decl_list == a_list)
2073 if (a_this->kind.ruleset->sel_list) {
2074 cr_declaration_destroy (a_this->kind.ruleset->decl_list);
2077 a_this->kind.ruleset->sel_list = NULL;
2083 * cr_statement_ruleset_append_decl2:
2085 *@a_this: the current statement.
2086 *@a_prop: the property of the declaration.
2087 *@a_value: the value of the declaration.
2089 *Appends a declaration to the current ruleset statement.
2091 *Returns CR_OK upon successful completion, an error code
2095 cr_statement_ruleset_append_decl2 (CRStatement * a_this,
2099 CRDeclaration *new_decls = NULL;
2101 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2102 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2104 new_decls = cr_declaration_append2
2105 (a_this->kind.ruleset->decl_list,
2107 g_return_val_if_fail (new_decls, CR_ERROR);
2108 a_this->kind.ruleset->decl_list = new_decls;
2114 * cr_statement_ruleset_append_decl:
2116 *Appends a declaration to the current statement.
2118 *@a_this: the current statement.
2119 *@a_declaration: the declaration to append.
2121 *Returns CR_OK upon sucessful completion, an error code
2125 cr_statement_ruleset_append_decl (CRStatement * a_this,
2126 CRDeclaration * a_decl)
2128 CRDeclaration *new_decls = NULL;
2130 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2131 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2133 new_decls = cr_declaration_append
2134 (a_this->kind.ruleset->decl_list, a_decl);
2135 g_return_val_if_fail (new_decls, CR_ERROR);
2136 a_this->kind.ruleset->decl_list = new_decls;
2142 * cr_statement_at_import_rule_set_imported_sheet:
2144 *Sets a stylesheet to the current \@import rule.
2145 *@a_this: the current \@import rule.
2146 *@a_sheet: the stylesheet. The stylesheet is owned
2147 *by the current instance of #CRStatement, that is, the
2148 *stylesheet will be destroyed when the current instance
2149 *of #CRStatement is destroyed.
2151 *Returns CR_OK upon successful completion, an error code otherwise.
2154 cr_statement_at_import_rule_set_imported_sheet (CRStatement * a_this,
2155 CRStyleSheet * a_sheet)
2157 g_return_val_if_fail (a_this
2158 && a_this->type == AT_IMPORT_RULE_STMT
2159 && a_this->kind.import_rule,
2160 CR_BAD_PARAM_ERROR);
2162 a_this->kind.import_rule->sheet = a_sheet;
2168 * cr_statement_at_import_rule_get_imported_sheet:
2170 *@a_this: the current \@import rule statement.
2171 *@a_sheet: out parameter. The returned stylesheet if and
2172 *only if the function returns CR_OK.
2174 *Gets the stylesheet contained by the \@import rule statement.
2175 *Returns CR_OK upon sucessful completion, an error code otherwise.
2178 cr_statement_at_import_rule_get_imported_sheet (CRStatement * a_this,
2179 CRStyleSheet ** a_sheet)
2181 g_return_val_if_fail (a_this
2182 && a_this->type == AT_IMPORT_RULE_STMT
2183 && a_this->kind.import_rule,
2184 CR_BAD_PARAM_ERROR);
2185 *a_sheet = a_this->kind.import_rule->sheet;
2191 * cr_statement_at_import_rule_set_url:
2193 *@a_this: the current \@import rule statement.
2194 *@a_url: the url to set.
2196 *Sets an url to the current \@import rule statement.
2198 *Returns CR_OK upon successful completion, an error code otherwise.
2201 cr_statement_at_import_rule_set_url (CRStatement * a_this,
2204 g_return_val_if_fail (a_this
2205 && a_this->type == AT_IMPORT_RULE_STMT
2206 && a_this->kind.import_rule,
2207 CR_BAD_PARAM_ERROR);
2209 if (a_this->kind.import_rule->url) {
2210 cr_string_destroy (a_this->kind.import_rule->url);
2213 a_this->kind.import_rule->url = a_url;
2219 * cr_statement_at_import_rule_get_url:
2221 *@a_this: the current \@import rule statement.
2222 *@a_url: out parameter. The returned url if
2223 *and only if the function returned CR_OK.
2225 *Gets the url of the \@import rule statement.
2226 *Returns CR_OK upon successful completion, an error code otherwise.
2229 cr_statement_at_import_rule_get_url (CRStatement const * a_this,
2232 g_return_val_if_fail (a_this
2233 && a_this->type == AT_IMPORT_RULE_STMT
2234 && a_this->kind.import_rule,
2235 CR_BAD_PARAM_ERROR);
2237 *a_url = a_this->kind.import_rule->url;
2243 * cr_statement_at_media_nr_rules:
2245 *@a_this: the current instance of #CRStatement.
2247 *Returns the number of rules in the media rule;
2250 cr_statement_at_media_nr_rules (CRStatement const * a_this)
2252 g_return_val_if_fail (a_this
2253 && a_this->type == AT_MEDIA_RULE_STMT
2254 && a_this->kind.media_rule, CR_BAD_PARAM_ERROR);
2256 return cr_statement_nr_rules (a_this->kind.media_rule->rulesets);
2260 * cr_statement_at_media_get_from_list:
2262 *@a_this: the current instance of #CRStatement.
2263 *@itemnr: the index into the media rule list of rules.
2265 *Use an index to get a CRStatement from the media rule list of rules.
2267 *Returns CRStatement at position itemnr, if itemnr > number of rules - 1,
2268 *it will return NULL.
2271 cr_statement_at_media_get_from_list (CRStatement * a_this, int itemnr)
2273 g_return_val_if_fail (a_this
2274 && a_this->type == AT_MEDIA_RULE_STMT
2275 && a_this->kind.media_rule, NULL);
2277 return cr_statement_get_from_list (a_this->kind.media_rule->rulesets,
2282 * cr_statement_at_page_rule_set_declarations:
2284 *@a_this: the current \@page rule statement.
2285 *@a_decl_list: the declaration list to add. Will be freed
2286 *by the current instance of #CRStatement when it is destroyed.
2288 *Sets a declaration list to the current \@page rule statement.
2290 *Returns CR_OK upon successful completion, an error code otherwise.
2293 cr_statement_at_page_rule_set_declarations (CRStatement * a_this,
2294 CRDeclaration * a_decl_list)
2296 g_return_val_if_fail (a_this
2297 && a_this->type == AT_PAGE_RULE_STMT
2298 && a_this->kind.page_rule, CR_BAD_PARAM_ERROR);
2300 if (a_this->kind.page_rule->decl_list) {
2301 cr_declaration_unref (a_this->kind.page_rule->decl_list);
2304 a_this->kind.page_rule->decl_list = a_decl_list;
2307 cr_declaration_ref (a_decl_list);
2314 * cr_statement_at_page_rule_get_declarations:
2316 *@a_this: the current \@page rule statement.
2317 *@a_decl_list: out parameter. The returned declaration list.
2319 *Gets the declaration list associated to the current \@page rule
2322 *Returns CR_OK upon successful completion, an error code otherwise.
2325 cr_statement_at_page_rule_get_declarations (CRStatement * a_this,
2326 CRDeclaration ** a_decl_list)
2328 g_return_val_if_fail (a_this
2329 && a_this->type == AT_PAGE_RULE_STMT
2330 && a_this->kind.page_rule, CR_BAD_PARAM_ERROR);
2332 *a_decl_list = a_this->kind.page_rule->decl_list;
2338 * cr_statement_at_charset_rule_set_charset:
2341 *@a_this: the current \@charset rule statement.
2342 *@a_charset: the charset to set.
2344 *Sets the charset of the current \@charset rule statement.
2346 *Returns CR_OK upon successful completion, an error code otherwise.
2349 cr_statement_at_charset_rule_set_charset (CRStatement * a_this,
2350 CRString * a_charset)
2352 g_return_val_if_fail (a_this
2353 && a_this->type == AT_CHARSET_RULE_STMT
2354 && a_this->kind.charset_rule,
2355 CR_BAD_PARAM_ERROR);
2357 if (a_this->kind.charset_rule->charset) {
2358 cr_string_destroy (a_this->kind.charset_rule->charset);
2360 a_this->kind.charset_rule->charset = a_charset;
2365 * cr_statement_at_charset_rule_get_charset:
2366 *@a_this: the current \@charset rule statement.
2367 *@a_charset: out parameter. The returned charset string if
2368 *and only if the function returned CR_OK.
2370 *Gets the charset string associated to the current
2371 *\@charset rule statement.
2373 * Returns CR_OK upon successful completion, an error code otherwise.
2376 cr_statement_at_charset_rule_get_charset (CRStatement const * a_this,
2377 CRString ** a_charset)
2379 g_return_val_if_fail (a_this
2380 && a_this->type == AT_CHARSET_RULE_STMT
2381 && a_this->kind.charset_rule,
2382 CR_BAD_PARAM_ERROR);
2384 *a_charset = a_this->kind.charset_rule->charset;
2390 * cr_statement_at_font_face_rule_set_decls:
2392 *@a_this: the current \@font-face rule statement.
2393 *@a_decls: the declarations list to set.
2395 *Sets a declaration list to the current \@font-face rule statement.
2397 *Returns CR_OK upon successful completion, an error code otherwise.
2400 cr_statement_at_font_face_rule_set_decls (CRStatement * a_this,
2401 CRDeclaration * a_decls)
2403 g_return_val_if_fail (a_this
2404 && a_this->type == AT_FONT_FACE_RULE_STMT
2405 && a_this->kind.font_face_rule,
2406 CR_BAD_PARAM_ERROR);
2408 if (a_this->kind.font_face_rule->decl_list) {
2409 cr_declaration_unref (a_this->kind.font_face_rule->decl_list);
2412 a_this->kind.font_face_rule->decl_list = a_decls;
2413 cr_declaration_ref (a_decls);
2419 * cr_statement_at_font_face_rule_get_decls:
2421 *@a_this: the current \@font-face rule statement.
2422 *@a_decls: out parameter. The returned declaration list if
2423 *and only if this function returns CR_OK.
2425 *Gets the declaration list associated to the current instance
2426 *of \@font-face rule statement.
2428 *Returns CR_OK upon successful completion, an error code otherwise.
2431 cr_statement_at_font_face_rule_get_decls (CRStatement * a_this,
2432 CRDeclaration ** a_decls)
2434 g_return_val_if_fail (a_this
2435 && a_this->type == AT_FONT_FACE_RULE_STMT
2436 && a_this->kind.font_face_rule,
2437 CR_BAD_PARAM_ERROR);
2439 *a_decls = a_this->kind.font_face_rule->decl_list;
2445 * cr_statement_at_font_face_rule_add_decl:
2447 *@a_this: the current \@font-face rule statement.
2448 *@a_prop: the property of the declaration.
2449 *@a_value: the value of the declaration.
2451 *Adds a declaration to the current \@font-face rule
2454 *Returns CR_OK upon successful completion, an error code otherwise.
2457 cr_statement_at_font_face_rule_add_decl (CRStatement * a_this,
2458 CRString * a_prop, CRTerm * a_value)
2460 CRDeclaration *decls = NULL;
2462 g_return_val_if_fail (a_this
2463 && a_this->type == AT_FONT_FACE_RULE_STMT
2464 && a_this->kind.font_face_rule,
2465 CR_BAD_PARAM_ERROR);
2467 decls = cr_declaration_append2
2468 (a_this->kind.font_face_rule->decl_list,
2471 g_return_val_if_fail (decls, CR_ERROR);
2473 if (a_this->kind.font_face_rule->decl_list == NULL)
2474 cr_declaration_ref (decls);
2476 a_this->kind.font_face_rule->decl_list = decls;
2483 * cr_statement_to_string:
2485 *@a_this: the current statement to serialize
2486 *@a_indent: the number of white space of indentation.
2488 *Serializes a css statement into a string
2490 *Returns the serialized statement. Must be freed by the caller
2494 cr_statement_to_string (CRStatement const * a_this, gulong a_indent)
2501 switch (a_this->type) {
2503 str = cr_statement_ruleset_to_string
2507 case AT_FONT_FACE_RULE_STMT:
2508 str = cr_statement_font_face_rule_to_string
2509 (a_this, a_indent) ;
2512 case AT_CHARSET_RULE_STMT:
2513 str = cr_statement_charset_to_string
2517 case AT_PAGE_RULE_STMT:
2518 str = cr_statement_at_page_rule_to_string
2522 case AT_MEDIA_RULE_STMT:
2523 str = cr_statement_media_rule_to_string
2527 case AT_IMPORT_RULE_STMT:
2528 str = cr_statement_import_rule_to_string
2533 cr_utils_trace_info ("Statement unrecognized");
2540 cr_statement_list_to_string (CRStatement const *a_this, gulong a_indent)
2542 CRStatement const *cur_stmt = NULL ;
2543 GString *stringue = NULL ;
2546 g_return_val_if_fail (a_this, NULL) ;
2548 stringue = g_string_new (NULL) ;
2550 cr_utils_trace_info ("Out of memory") ;
2553 for (cur_stmt = a_this ; cur_stmt;
2554 cur_stmt = cur_stmt->next) {
2555 str = cr_statement_to_string (cur_stmt, a_indent) ;
2557 if (!cur_stmt->prev) {
2558 g_string_append (stringue, str) ;
2560 g_string_append_printf
2561 (stringue, "\n%s", str) ;
2567 str = stringue->str ;
2568 g_string_free (stringue, FALSE) ;
2573 * cr_statement_dump:
2575 *@a_this: the current css2 statement.
2576 *@a_fp: the destination file pointer.
2577 *@a_indent: the number of white space indentation characters.
2579 *Dumps the css2 statement to a file.
2582 cr_statement_dump (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2589 str = cr_statement_to_string (a_this, a_indent) ;
2591 fprintf (a_fp, "%s",str) ;
2598 * cr_statement_dump_ruleset:
2600 *@a_this: the current instance of #CRStatement.
2601 *@a_fp: the destination file pointer.
2602 *@a_indent: the number of indentation white spaces to add.
2604 *Dumps a ruleset statement to a file.
2607 cr_statement_dump_ruleset (CRStatement const * a_this, FILE * a_fp, glong a_indent)
2611 g_return_if_fail (a_fp && a_this);
2612 str = cr_statement_ruleset_to_string (a_this, a_indent);
2614 fprintf (a_fp, str);
2621 * cr_statement_dump_font_face_rule:
2623 *@a_this: the current instance of font face rule statement.
2624 *@a_fp: the destination file pointer.
2625 *@a_indent: the number of white space indentation.
2627 *Dumps a font face rule statement to a file.
2630 cr_statement_dump_font_face_rule (CRStatement const * a_this, FILE * a_fp,
2634 g_return_if_fail (a_this
2635 && a_this->type == AT_FONT_FACE_RULE_STMT);
2637 str = cr_statement_font_face_rule_to_string (a_this,
2640 fprintf (a_fp, "%s", str) ;
2647 * cr_statement_dump_charset:
2649 *@a_this: the current instance of the \@charset rule statement.
2650 *@a_fp: the destination file pointer.
2651 *@a_indent: the number of indentation white spaces.
2653 *Dumps an \@charset rule statement to a file.
2656 cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2660 g_return_if_fail (a_this && a_this->type == AT_CHARSET_RULE_STMT);
2662 str = cr_statement_charset_to_string (a_this,
2665 fprintf (a_fp, str) ;
2673 * cr_statement_dump_page:
2675 *@a_this: the statement to dump on stdout.
2676 *@a_fp: the destination file pointer.
2677 *@a_indent: the number of indentation white spaces.
2679 *Dumps an \@page rule statement on stdout.
2682 cr_statement_dump_page (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2686 g_return_if_fail (a_this
2687 && a_this->type == AT_PAGE_RULE_STMT
2688 && a_this->kind.page_rule);
2690 str = cr_statement_at_page_rule_to_string (a_this, a_indent) ;
2692 fprintf (a_fp, str);
2700 * cr_statement_dump_media_rule:
2702 *@a_this: the statement to dump.
2703 *@a_fp: the destination file pointer
2704 *@a_indent: the number of white spaces indentation.
2706 *Dumps an \@media rule statement to a file.
2709 cr_statement_dump_media_rule (CRStatement const * a_this,
2714 g_return_if_fail (a_this->type == AT_MEDIA_RULE_STMT);
2716 str = cr_statement_media_rule_to_string (a_this, a_indent) ;
2718 fprintf (a_fp, str) ;
2725 * cr_statement_dump_import_rule:
2727 *@a_fp: the destination file pointer.
2728 *@a_indent: the number of white space indentations.
2730 *Dumps an \@import rule statement to a file.
2733 cr_statement_dump_import_rule (CRStatement const * a_this, FILE * a_fp,
2737 g_return_if_fail (a_this
2738 && a_this->type == AT_IMPORT_RULE_STMT
2740 && a_this->kind.import_rule);
2742 str = cr_statement_import_rule_to_string (a_this, a_indent) ;
2744 fprintf (a_fp, str) ;
2751 * cr_statement_destroy:
2753 * @a_this: the current instance of #CRStatement.
2755 *Destructor of #CRStatement.
2758 cr_statement_destroy (CRStatement * a_this)
2760 CRStatement *cur = NULL;
2762 g_return_if_fail (a_this);
2764 /*go get the tail of the list */
2765 for (cur = a_this; cur && cur->next; cur = cur->next) {
2766 cr_statement_clear (cur);
2770 cr_statement_clear (cur);
2772 if (cur->prev == NULL) {
2777 /*walk backward and free next element */
2778 for (cur = cur->prev; cur && cur->prev; cur = cur->prev) {
2788 /*free the one remaining list */