Libcroco
cr-statement.c
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 
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  * Author: Dodji Seketeli.
21  * See COPYRIGHTS files for copyrights information.
22  */
23 
24 #include <string.h>
25 #include "cr-statement.h"
26 #include "cr-parser.h"
27 
28 /**
29  *@file
30  *Definition of the #CRStatement class.
31  */
32 
33 #define DECLARATION_INDENT_NB 2
34 
35 static void cr_statement_clear (CRStatement * a_this);
36 
37 static void
38 parse_font_face_start_font_face_cb (CRDocHandler * a_this,
39  CRParsingLocation *a_location)
40 {
41  CRStatement *stmt = NULL;
42  enum CRStatus status = CR_OK;
43 
44  stmt = cr_statement_new_at_font_face_rule (NULL, NULL);
45  g_return_if_fail (stmt);
46 
47  status = cr_doc_handler_set_ctxt (a_this, stmt);
48  g_return_if_fail (status == CR_OK);
49 }
50 
51 static void
52 parse_font_face_unrecoverable_error_cb (CRDocHandler * a_this)
53 {
54  CRStatement *stmt = NULL;
55  CRStatement **stmtptr = NULL;
56  enum CRStatus status = CR_OK;
57 
58  g_return_if_fail (a_this);
59 
60  stmtptr = &stmt;
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.");
65  return;
66  }
67  if (stmt) {
68  cr_statement_destroy (stmt);
69  cr_doc_handler_set_ctxt (a_this, NULL);
70  return;
71  }
72 }
73 
74 static void
75 parse_font_face_property_cb (CRDocHandler * a_this,
76  CRString * a_name,
77  CRTerm * a_value, gboolean a_important)
78 {
79  enum CRStatus status = CR_OK;
80  CRString *name = NULL;
81  CRDeclaration *decl = NULL;
82  CRStatement *stmt = NULL;
83  CRStatement **stmtptr = NULL;
84 
85  g_return_if_fail (a_this && a_name);
86 
87  stmtptr = &stmt;
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);
91 
92  name = cr_string_dup (a_name) ;
93  g_return_if_fail (name);
94  decl = cr_declaration_new (stmt, name, a_value);
95  if (!decl) {
96  cr_utils_trace_info ("cr_declaration_new () failed.");
97  goto error;
98  }
99  name = NULL;
100 
101  stmt->kind.font_face_rule->decl_list =
103  decl);
104  if (!stmt->kind.font_face_rule->decl_list)
105  goto error;
106  decl = NULL;
107 
108  error:
109  if (decl) {
110  cr_declaration_unref (decl);
111  decl = NULL;
112  }
113  if (name) {
114  cr_string_destroy (name);
115  name = NULL;
116  }
117 }
118 
119 static void
120 parse_font_face_end_font_face_cb (CRDocHandler * a_this)
121 {
122  CRStatement *result = NULL;
123  CRStatement **resultptr = NULL;
124  enum CRStatus status = CR_OK;
125 
126  g_return_if_fail (a_this);
127 
128  resultptr = &result;
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);
132 
133  status = cr_doc_handler_set_result (a_this, result);
134  g_return_if_fail (status == CR_OK);
135 }
136 
137 static void
138 parse_page_start_page_cb (CRDocHandler * a_this,
139  CRString * a_name,
140  CRString * a_pseudo_page,
141  CRParsingLocation *a_location)
142 {
143  CRStatement *stmt = NULL;
144  enum CRStatus status = CR_OK;
145  CRString *page_name = NULL, *pseudo_name = NULL ;
146 
147  if (a_name)
148  page_name = cr_string_dup (a_name) ;
149  if (a_pseudo_page)
150  pseudo_name = cr_string_dup (a_pseudo_page) ;
151 
152  stmt = cr_statement_new_at_page_rule (NULL, NULL,
153  page_name,
154  pseudo_name);
155  page_name = NULL ;
156  pseudo_name = 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);
160 }
161 
162 static void
163 parse_page_unrecoverable_error_cb (CRDocHandler * a_this)
164 {
165  CRStatement *stmt = NULL;
166  CRStatement **stmtptr = NULL;
167  enum CRStatus status = CR_OK;
168 
169  g_return_if_fail (a_this);
170 
171  stmtptr = &stmt;
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.");
176  return;
177  }
178  if (stmt) {
179  cr_statement_destroy (stmt);
180  stmt = NULL;
181  cr_doc_handler_set_ctxt (a_this, NULL);
182  }
183 }
184 
185 static void
186 parse_page_property_cb (CRDocHandler * a_this,
187  CRString * a_name,
188  CRTerm * a_expression, gboolean a_important)
189 {
190  CRString *name = NULL;
191  CRStatement *stmt = NULL;
192  CRStatement **stmtptr = NULL;
193  CRDeclaration *decl = NULL;
194  enum CRStatus status = CR_OK;
195 
196  stmtptr = &stmt;
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);
199 
200  name = cr_string_dup (a_name);
201  g_return_if_fail (name);
202 
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 =
208  g_return_if_fail (stmt->kind.page_rule->decl_list);
209 }
210 
211 static void
212 parse_page_end_page_cb (CRDocHandler * a_this,
213  CRString * a_name,
214  CRString * a_pseudo_page)
215 {
216  enum CRStatus status = CR_OK;
217  CRStatement *stmt = NULL;
218  CRStatement **stmtptr = NULL;
219 
220  stmtptr = &stmt;
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);
224 
225  status = cr_doc_handler_set_result (a_this, stmt);
226  g_return_if_fail (status == CR_OK);
227 }
228 
229 static void
230 parse_at_media_start_media_cb (CRDocHandler * a_this,
231  GList * a_media_list,
232  CRParsingLocation *a_location)
233 {
234  enum CRStatus status = CR_OK;
235  CRStatement *at_media = NULL;
236  GList *media_list = NULL;
237 
238  g_return_if_fail (a_this && a_this->priv);
239 
240  if (a_media_list) {
241  /*duplicate media list */
242  media_list = cr_utils_dup_glist_of_cr_string
243  (a_media_list);
244  }
245 
246  g_return_if_fail (media_list);
247 
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);
250 
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);
255 }
256 
257 static void
258 parse_at_media_unrecoverable_error_cb (CRDocHandler * a_this)
259 {
260  enum CRStatus status = CR_OK;
261  CRStatement *stmt = NULL;
262  CRStatement **stmtptr = NULL;
263 
264  g_return_if_fail (a_this);
265 
266  stmtptr = &stmt;
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.");
271  return;
272  }
273  if (stmt) {
274  cr_statement_destroy (stmt);
275  stmt = NULL;
276  cr_doc_handler_set_ctxt (a_this, NULL);
277  cr_doc_handler_set_result (a_this, NULL);
278  }
279 }
280 
281 static void
282 parse_at_media_start_selector_cb (CRDocHandler * a_this,
283  CRSelector * a_sellist)
284 {
285  enum CRStatus status = CR_OK;
286  CRStatement *at_media = NULL;
287  CRStatement **at_media_ptr = NULL;
288  CRStatement *ruleset = NULL;
289 
290  g_return_if_fail (a_this && a_this->priv && a_sellist);
291 
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);
300 }
301 
302 static void
303 parse_at_media_property_cb (CRDocHandler * a_this,
304  CRString * a_name, CRTerm * a_value,
305  gboolean a_important)
306 {
307  enum CRStatus status = CR_OK;
308 
309  /*
310  *the current ruleset stmt, child of the
311  *current at-media being parsed.
312  */
313  CRStatement *stmt = NULL;
314  CRStatement **stmtptr = NULL;
315  CRDeclaration *decl = NULL;
316  CRString *name = NULL;
317 
318  g_return_if_fail (a_this && a_name);
319 
320  name = cr_string_dup (a_name) ;
321  g_return_if_fail (name);
322 
323  stmtptr = &stmt;
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);
328 
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);
334 }
335 
336 static void
337 parse_at_media_end_selector_cb (CRDocHandler * a_this,
338  CRSelector * a_sellist)
339 {
340  enum CRStatus status = CR_OK;
341 
342  /*
343  *the current ruleset stmt, child of the
344  *current at-media being parsed.
345  */
346  CRStatement *stmt = NULL;
347  CRStatement **stmtptr = NULL;
348 
349  g_return_if_fail (a_this && a_sellist);
350 
351  stmtptr = &stmt;
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);
356 
357  status = cr_doc_handler_set_ctxt
358  (a_this, stmt->kind.ruleset->parent_media_rule);
359  g_return_if_fail (status == CR_OK);
360 }
361 
362 static void
363 parse_at_media_end_media_cb (CRDocHandler * a_this,
364  GList * a_media_list)
365 {
366  enum CRStatus status = CR_OK;
367  CRStatement *at_media = NULL;
368  CRStatement **at_media_ptr = NULL;
369 
370  g_return_if_fail (a_this && a_this->priv);
371 
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);
377 }
378 
379 static void
380 parse_ruleset_start_selector_cb (CRDocHandler * a_this,
381  CRSelector * a_sellist)
382 {
383  CRStatement *ruleset = NULL;
384 
385  g_return_if_fail (a_this && a_this->priv && a_sellist);
386 
387  ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, NULL);
388  g_return_if_fail (ruleset);
389 
390  cr_doc_handler_set_result (a_this, ruleset);
391 }
392 
393 static void
394 parse_ruleset_unrecoverable_error_cb (CRDocHandler * a_this)
395 {
396  CRStatement *stmt = NULL;
397  CRStatement **stmtptr = NULL;
398  enum CRStatus status = CR_OK;
399 
400  stmtptr = &stmt;
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.");
405  return;
406  }
407  if (stmt) {
408  cr_statement_destroy (stmt);
409  stmt = NULL;
410  cr_doc_handler_set_result (a_this, NULL);
411  }
412 }
413 
414 static void
415 parse_ruleset_property_cb (CRDocHandler * a_this,
416  CRString * a_name,
417  CRTerm * a_value, gboolean a_important)
418 {
419  enum CRStatus status = CR_OK;
420  CRStatement *ruleset = NULL;
421  CRStatement **rulesetptr = NULL;
422  CRDeclaration *decl = NULL;
423  CRString *stringue = NULL;
424 
425  g_return_if_fail (a_this && a_this->priv && a_name);
426 
427  stringue = cr_string_dup (a_name);
428  g_return_if_fail (stringue);
429 
430  rulesetptr = &ruleset;
431  status = cr_doc_handler_get_result (a_this, (gpointer *) rulesetptr);
432  g_return_if_fail (status == CR_OK
433  && ruleset
434  && ruleset->type == RULESET_STMT);
435 
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);
441 }
442 
443 static void
444 parse_ruleset_end_selector_cb (CRDocHandler * a_this,
445  CRSelector * a_sellist)
446 {
447  CRStatement *result = NULL;
448  CRStatement **resultptr = NULL;
449  enum CRStatus status = CR_OK;
450 
451  g_return_if_fail (a_this && a_sellist);
452 
453  resultptr = &result;
454  status = cr_doc_handler_get_result (a_this, (gpointer *) resultptr);
455 
456  g_return_if_fail (status == CR_OK
457  && result
458  && result->type == RULESET_STMT);
459 }
460 
461 static void
462 cr_statement_clear (CRStatement * a_this)
463 {
464  g_return_if_fail (a_this);
465 
466  switch (a_this->type) {
467  case AT_RULE_STMT:
468  break;
469  case RULESET_STMT:
470  if (!a_this->kind.ruleset)
471  return;
472  if (a_this->kind.ruleset->sel_list) {
474  a_this->kind.ruleset->sel_list = NULL;
475  }
476  if (a_this->kind.ruleset->decl_list) {
478  (a_this->kind.ruleset->decl_list);
479  a_this->kind.ruleset->decl_list = NULL;
480  }
481  g_free (a_this->kind.ruleset);
482  a_this->kind.ruleset = NULL;
483  break;
484 
485  case AT_IMPORT_RULE_STMT:
486  if (!a_this->kind.import_rule)
487  return;
488  if (a_this->kind.import_rule->url) {
490  (a_this->kind.import_rule->url) ;
491  a_this->kind.import_rule->url = NULL;
492  }
493  g_free (a_this->kind.import_rule);
494  a_this->kind.import_rule = NULL;
495  break;
496 
497  case AT_MEDIA_RULE_STMT:
498  if (!a_this->kind.media_rule)
499  return;
500  if (a_this->kind.media_rule->rulesets) {
502  (a_this->kind.media_rule->rulesets);
503  a_this->kind.media_rule->rulesets = NULL;
504  }
505  if (a_this->kind.media_rule->media_list) {
506  GList *cur = NULL;
507 
508  for (cur = a_this->kind.media_rule->media_list;
509  cur; cur = cur->next) {
510  if (cur->data) {
511  cr_string_destroy ((CRString *) cur->data);
512  cur->data = NULL;
513  }
514 
515  }
516  g_list_free (a_this->kind.media_rule->media_list);
517  a_this->kind.media_rule->media_list = NULL;
518  }
519  g_free (a_this->kind.media_rule);
520  a_this->kind.media_rule = NULL;
521  break;
522 
523  case AT_PAGE_RULE_STMT:
524  if (!a_this->kind.page_rule)
525  return;
526 
527  if (a_this->kind.page_rule->decl_list) {
529  (a_this->kind.page_rule->decl_list);
530  a_this->kind.page_rule->decl_list = NULL;
531  }
532  if (a_this->kind.page_rule->name) {
534  (a_this->kind.page_rule->name);
535  a_this->kind.page_rule->name = NULL;
536  }
537  if (a_this->kind.page_rule->pseudo) {
539  (a_this->kind.page_rule->pseudo);
540  a_this->kind.page_rule->pseudo = NULL;
541  }
542  g_free (a_this->kind.page_rule);
543  a_this->kind.page_rule = NULL;
544  break;
545 
547  if (!a_this->kind.charset_rule)
548  return;
549 
550  if (a_this->kind.charset_rule->charset) {
552  (a_this->kind.charset_rule->charset);
553  a_this->kind.charset_rule->charset = NULL;
554  }
555  g_free (a_this->kind.charset_rule);
556  a_this->kind.charset_rule = NULL;
557  break;
558 
560  if (!a_this->kind.font_face_rule)
561  return;
562 
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;
567  }
568  g_free (a_this->kind.font_face_rule);
569  a_this->kind.font_face_rule = NULL;
570  break;
571 
572  default:
573  break;
574  }
575 }
576 
577 /**
578  * cr_statement_ruleset_to_string:
579  *
580  *@a_this: the current instance of #CRStatement
581  *@a_indent: the number of whitespace to use for indentation
582  *
583  *Serializes the ruleset statement into a string
584  *
585  *Returns the newly allocated serialised string. Must be freed
586  *by the caller, using g_free().
587  */
588 static gchar *
589 cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent)
590 {
591  GString *stringue = NULL;
592  gchar *tmp_str = NULL,
593  *result = NULL;
594 
595  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, NULL);
596 
597  stringue = g_string_new (NULL);
598 
599  if (a_this->kind.ruleset->sel_list) {
600  if (a_indent)
601  cr_utils_dump_n_chars2 (' ', stringue, a_indent);
602 
603  tmp_str =
604  (gchar *) cr_selector_to_string (a_this->kind.ruleset->
605  sel_list);
606  if (tmp_str) {
607  g_string_append (stringue, tmp_str);
608  g_free (tmp_str);
609  tmp_str = NULL;
610  }
611  }
612  g_string_append (stringue, " {\n");
613  if (a_this->kind.ruleset->decl_list) {
614  tmp_str = (gchar *) cr_declaration_list_to_string2
615  (a_this->kind.ruleset->decl_list,
616  a_indent + DECLARATION_INDENT_NB, TRUE);
617  if (tmp_str) {
618  g_string_append (stringue, tmp_str);
619  g_free (tmp_str);
620  tmp_str = NULL;
621  }
622  g_string_append (stringue, "\n");
623  cr_utils_dump_n_chars2 (' ', stringue, a_indent);
624  }
625  g_string_append (stringue, "}");
626  result = stringue->str;
627 
628  if (stringue) {
629  g_string_free (stringue, FALSE);
630  stringue = NULL;
631  }
632  if (tmp_str) {
633  g_free (tmp_str);
634  tmp_str = NULL;
635  }
636  return result;
637 }
638 
639 
640 /**
641  * cr_statement_font_face_rule_to_string:
642  *
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.
646  *
647  *Serializes a font face rule statement into a string.
648  *
649  *Returns the serialized string. Must be deallocated by the caller
650  *using g_free().
651  */
652 static gchar *
653 cr_statement_font_face_rule_to_string (CRStatement const * a_this,
654  glong a_indent)
655 {
656  gchar *result = NULL, *tmp_str = NULL ;
657  GString *stringue = NULL ;
658 
659  g_return_val_if_fail (a_this
660  && a_this->type == AT_FONT_FACE_RULE_STMT,
661  NULL);
662 
663  if (a_this->kind.font_face_rule->decl_list) {
664  stringue = g_string_new (NULL) ;
665  g_return_val_if_fail (stringue, NULL) ;
666  if (a_indent)
667  cr_utils_dump_n_chars2 (' ', stringue,
668  a_indent);
669  g_string_append (stringue, "@font-face {\n");
670  tmp_str = (gchar *) cr_declaration_list_to_string2
671  (a_this->kind.font_face_rule->decl_list,
672  a_indent + DECLARATION_INDENT_NB, TRUE) ;
673  if (tmp_str) {
674  g_string_append (stringue,
675  tmp_str) ;
676  g_free (tmp_str) ;
677  tmp_str = NULL ;
678  }
679  g_string_append (stringue, "\n}");
680  }
681  if (stringue) {
682  result = stringue->str ;
683  g_string_free (stringue, FALSE) ;
684  stringue = NULL ;
685  }
686  return result ;
687 }
688 
689 
690 /**
691  * cr_statement_charset_to_string:
692  *
693  *Serialises an \@charset statement into a string.
694  *@a_this: the statement to serialize.
695  *@a_indent: the number of indentation spaces
696  *
697  *Returns the serialized charset statement. Must be
698  *freed by the caller using g_free().
699  */
700 static gchar *
701 cr_statement_charset_to_string (CRStatement const *a_this,
702  gulong a_indent)
703 {
704  gchar *str = NULL ;
705  GString *stringue = NULL ;
706 
707  g_return_val_if_fail (a_this
708  && a_this->type == AT_CHARSET_RULE_STMT,
709  NULL) ;
710 
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);
723  if (str) {
724  g_free (str);
725  str = NULL;
726  }
727  }
728  if (stringue) {
729  str = stringue->str ;
730  g_string_free (stringue, FALSE) ;
731  }
732  return str ;
733 }
734 
735 
736 /**
737  * cr_statement_at_page_rule_to_string:
738  *
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.
742  *
743  *Returns the serialized string. Must be freed by the caller
744  */
745 static gchar *
746 cr_statement_at_page_rule_to_string (CRStatement const *a_this,
747  gulong a_indent)
748 {
749  GString *stringue = NULL;
750  gchar *result = NULL ;
751 
752  stringue = g_string_new (NULL) ;
753 
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
759  (stringue, " %s",
760  a_this->kind.page_rule->name->stryng->str) ;
761  } else {
762  g_string_append (stringue, " ");
763  }
764  if (a_this->kind.page_rule->pseudo
765  && a_this->kind.page_rule->pseudo->stryng) {
766  g_string_append_printf
767  (stringue, " :%s",
768  a_this->kind.page_rule->pseudo->stryng->str) ;
769  }
770  if (a_this->kind.page_rule->decl_list) {
771  gchar *str = NULL ;
772  g_string_append (stringue, " {\n");
773  str = (gchar *) cr_declaration_list_to_string2
774  (a_this->kind.page_rule->decl_list,
775  a_indent + DECLARATION_INDENT_NB, TRUE) ;
776  if (str) {
777  g_string_append (stringue, str) ;
778  g_free (str) ;
779  str = NULL ;
780  }
781  g_string_append (stringue, "\n}\n");
782  }
783  result = stringue->str ;
784  g_string_free (stringue, FALSE) ;
785  stringue = NULL ;
786  return result ;
787 }
788 
789 
790 /**
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().
796  */
797 static gchar *
798 cr_statement_media_rule_to_string (CRStatement const *a_this,
799  gulong a_indent)
800 {
801  gchar *str = NULL ;
802  GString *stringue = NULL ;
803  GList const *cur = NULL;
804 
805  g_return_val_if_fail (a_this->type == AT_MEDIA_RULE_STMT,
806  NULL);
807 
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");
812 
813  for (cur = a_this->kind.media_rule->media_list; cur;
814  cur = cur->next) {
815  if (cur->data) {
816  gchar *str2 = cr_string_dup2
817  ((CRString const *) cur->data);
818 
819  if (str2) {
820  if (cur->prev) {
821  g_string_append
822  (stringue,
823  ",");
824  }
825  g_string_append_printf
826  (stringue,
827  " %s", str2);
828  g_free (str2);
829  str2 = NULL;
830  }
831  }
832  }
833  g_string_append (stringue, " {\n");
835  (a_this->kind.media_rule->rulesets,
836  a_indent + DECLARATION_INDENT_NB) ;
837  if (str) {
838  g_string_append (stringue, str) ;
839  g_free (str) ;
840  str = NULL ;
841  }
842  g_string_append (stringue, "\n}");
843  }
844  if (stringue) {
845  str = stringue->str ;
846  g_string_free (stringue, FALSE) ;
847  }
848  return str ;
849 }
850 
851 
852 static gchar *
853 cr_statement_import_rule_to_string (CRStatement const *a_this,
854  gulong a_indent)
855 {
856  GString *stringue = NULL ;
857  gchar *str = NULL;
858 
859  g_return_val_if_fail (a_this
860  && a_this->type == AT_IMPORT_RULE_STMT
861  && a_this->kind.import_rule,
862  NULL) ;
863 
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);
871  if (str) {
872  g_string_append_printf (stringue,
873  "@import url(\"%s\")",
874  str);
875  g_free (str);
876  str = NULL ;
877  } else /*there is no url, so no import rule, get out! */
878  return NULL;
879 
880  if (a_this->kind.import_rule->media_list) {
881  GList const *cur = NULL;
882 
883  for (cur = a_this->kind.import_rule->media_list;
884  cur; cur = cur->next) {
885  if (cur->data) {
886  CRString const *crstr = cur->data;
887 
888  if (cur->prev) {
889  g_string_append
890  (stringue, ", ");
891  }
892  if (crstr
893  && crstr->stryng
894  && crstr->stryng->str) {
895  g_string_append_len
896  (stringue,
897  crstr->stryng->str,
898  crstr->stryng->len) ;
899  }
900  }
901  }
902  }
903  g_string_append (stringue, " ;");
904  }
905  if (stringue) {
906  str = stringue->str ;
907  g_string_free (stringue, FALSE) ;
908  stringue = NULL ;
909  }
910  return str ;
911 }
912 
913 
914 /*******************
915  *public functions
916  ******************/
917 
918 /**
919  * cr_statement_does_buf_parses_against_core:
920  *
921  *@a_buf: the buffer to parse.
922  *@a_encoding: the character encoding of a_buf.
923  *
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
926  *css spec) or not.
927  *
928  *Returns TRUE if the buffer parses against the core grammar, false otherwise.
929  */
930 gboolean
932  enum CREncoding a_encoding)
933 {
934  CRParser *parser = NULL;
935  enum CRStatus status = CR_OK;
936  gboolean result = FALSE;
937 
938  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
939  a_encoding, FALSE);
940  g_return_val_if_fail (parser, FALSE);
941 
942  status = cr_parser_set_use_core_grammar (parser, TRUE);
943  if (status != CR_OK) {
944  goto cleanup;
945  }
946 
947  status = cr_parser_parse_statement_core (parser);
948  if (status == CR_OK) {
949  result = TRUE;
950  }
951 
952  cleanup:
953  if (parser) {
954  cr_parser_destroy (parser);
955  }
956 
957  return result;
958 }
959 
960 /**
961  * cr_statement_parse_from_buf:
962  *
963  *@a_buf: the buffer to parse.
964  *@a_encoding: the character encoding of a_buf.
965  *
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.
969  *
970  *Returns the newly built instance of #CRStatement in case
971  *of successful parsing, NULL otherwise.
972  */
973 CRStatement *
974 cr_statement_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding)
975 {
976  CRStatement *result = NULL;
977 
978  /*
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.
984  */
985 
986  result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding);
987  if (!result) {
989  (a_buf, a_encoding);
990  } else {
991  goto out;
992  }
993 
994  if (!result) {
996  (a_buf, a_encoding);
997  } else {
998  goto out;
999  }
1000 
1001  if (!result) {
1003  (a_buf, a_encoding);
1004  } else {
1005  goto out;
1006  }
1007 
1008  if (!result) {
1010  (a_buf, a_encoding);
1011 
1012  } else {
1013  goto out;
1014  }
1015 
1016  if (!result) {
1018  (a_buf, a_encoding);
1019  } else {
1020  goto out;
1021  }
1022 
1023  if (!result) {
1025  (a_buf, a_encoding);
1026  } else {
1027  goto out;
1028  }
1029 
1030  out:
1031  return result;
1032 }
1033 
1034 /**
1035  * cr_statement_ruleset_parse_from_buf:
1036  *
1037  *@a_buf: the buffer to parse.
1038  *@a_enc: the character encoding of a_buf.
1039  *
1040  *Parses a buffer that contains a ruleset statement an instanciates
1041  *a #CRStatement of type RULESET_STMT.
1042  *
1043  *Returns the newly built instance of #CRStatement in case of successful parsing,
1044  *NULL otherwise.
1045  */
1046 CRStatement *
1048  enum CREncoding a_enc)
1049 {
1050  enum CRStatus status = CR_OK;
1051  CRStatement *result = NULL;
1052  CRStatement **resultptr = NULL;
1053  CRParser *parser = NULL;
1054  CRDocHandler *sac_handler = NULL;
1055 
1056  g_return_val_if_fail (a_buf, NULL);
1057 
1058  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1059  a_enc, FALSE);
1060 
1061  g_return_val_if_fail (parser, NULL);
1062 
1063  sac_handler = cr_doc_handler_new ();
1064  g_return_val_if_fail (parser, NULL);
1065 
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;
1071 
1072  cr_parser_set_sac_handler (parser, sac_handler);
1074  status = cr_parser_parse_ruleset (parser);
1075  if (status != CR_OK) {
1076  goto cleanup;
1077  }
1078 
1079  resultptr = &result;
1080  status = cr_doc_handler_get_result (sac_handler,
1081  (gpointer *) resultptr);
1082  if (!((status == CR_OK) && result)) {
1083  if (result) {
1084  cr_statement_destroy (result);
1085  result = NULL;
1086  }
1087  }
1088 
1089  cleanup:
1090  if (parser) {
1091  cr_parser_destroy (parser);
1092  parser = NULL;
1093  sac_handler = NULL ;
1094  }
1095  if (sac_handler) {
1096  cr_doc_handler_unref (sac_handler);
1097  sac_handler = NULL;
1098  }
1099  return result;
1100 }
1101 
1102 /**
1103  * cr_statement_new_ruleset:
1104  *
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.
1111  *
1112  *Creates a new instance of #CRStatement of type
1113  *#CRRulSet.
1114  *
1115  *Returns the new instance of #CRStatement or NULL if something
1116  *went wrong.
1117  */
1118 CRStatement *
1120  CRSelector * a_sel_list,
1121  CRDeclaration * a_decl_list,
1122  CRStatement * a_parent_media_rule)
1123 {
1124  CRStatement *result = NULL;
1125 
1126  g_return_val_if_fail (a_sel_list, NULL);
1127 
1128  if (a_parent_media_rule) {
1129  g_return_val_if_fail
1130  (a_parent_media_rule->type == AT_MEDIA_RULE_STMT,
1131  NULL);
1132  g_return_val_if_fail (a_parent_media_rule->kind.media_rule,
1133  NULL);
1134  }
1135 
1136  result = g_try_malloc (sizeof (CRStatement));
1137 
1138  if (!result) {
1139  cr_utils_trace_info ("Out of memory");
1140  return NULL;
1141  }
1142 
1143  memset (result, 0, sizeof (CRStatement));
1144  result->type = RULESET_STMT;
1145  result->kind.ruleset = g_try_malloc (sizeof (CRRuleSet));
1146 
1147  if (!result->kind.ruleset) {
1148  cr_utils_trace_info ("Out of memory");
1149  if (result)
1150  g_free (result);
1151  return NULL;
1152  }
1153 
1154  memset (result->kind.ruleset, 0, sizeof (CRRuleSet));
1155  result->kind.ruleset->sel_list = a_sel_list;
1156  if (a_sel_list)
1157  cr_selector_ref (a_sel_list);
1158  result->kind.ruleset->decl_list = a_decl_list;
1159 
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,
1165  result);
1166  }
1167 
1168  cr_statement_set_parent_sheet (result, a_sheet);
1169 
1170  return result;
1171 }
1172 
1173 /**
1174  * cr_statement_at_media_rule_parse_from_buf:
1175  *
1176  *@a_buf: the input to parse.
1177  *@a_enc: the encoding of the buffer.
1178  *
1179  *Parses a buffer that contains an "\@media" declaration
1180  *and builds an \@media css statement.
1181  *
1182  *Returns the \@media statement, or NULL if the buffer could not
1183  *be successfully parsed.
1184  */
1185 CRStatement *
1187  enum CREncoding a_enc)
1188 {
1189  CRParser *parser = NULL;
1190  CRStatement *result = NULL;
1191  CRStatement **resultptr = NULL;
1192  CRDocHandler *sac_handler = NULL;
1193  enum CRStatus status = CR_OK;
1194 
1195  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1196  a_enc, FALSE);
1197  if (!parser) {
1198  cr_utils_trace_info ("Instantiation of the parser failed");
1199  goto cleanup;
1200  }
1201 
1202  sac_handler = cr_doc_handler_new ();
1203  if (!sac_handler) {
1205  ("Instantiation of the sac handler failed");
1206  goto cleanup;
1207  }
1208 
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;
1216 
1217  status = cr_parser_set_sac_handler (parser, sac_handler);
1218  if (status != CR_OK)
1219  goto cleanup;
1220 
1222  if (status != CR_OK)
1223  goto cleanup;
1224 
1225  status = cr_parser_parse_media (parser);
1226  if (status != CR_OK)
1227  goto cleanup;
1228 
1229  resultptr = &result;
1230  status = cr_doc_handler_get_result (sac_handler,
1231  (gpointer *) resultptr);
1232  if (status != CR_OK)
1233  goto cleanup;
1234 
1235  cleanup:
1236 
1237  if (parser) {
1238  cr_parser_destroy (parser);
1239  parser = NULL;
1240  sac_handler = NULL ;
1241  }
1242  if (sac_handler) {
1243  cr_doc_handler_unref (sac_handler);
1244  sac_handler = NULL;
1245  }
1246 
1247  return result;
1248 }
1249 
1250 /**
1251  * cr_statement_new_at_media_rule:
1252  *
1253  *@a_ruleset: the ruleset statements contained
1254  *in the \@media rule.
1255  *@a_media: the media string list. A list of GString pointers.
1256  *
1257  *Instanciates an instance of #CRStatement of type
1258  *AT_MEDIA_RULE_STMT (\@media ruleset).
1259  *
1260  */
1261 CRStatement *
1263  CRStatement * a_rulesets, GList * a_media)
1264 {
1265  CRStatement *result = NULL,
1266  *cur = NULL;
1267 
1268  if (a_rulesets)
1269  g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL);
1270 
1271  result = g_try_malloc (sizeof (CRStatement));
1272 
1273  if (!result) {
1274  cr_utils_trace_info ("Out of memory");
1275  return NULL;
1276  }
1277 
1278  memset (result, 0, sizeof (CRStatement));
1279  result->type = AT_MEDIA_RULE_STMT;
1280 
1281  result->kind.media_rule = g_try_malloc (sizeof (CRAtMediaRule));
1282  if (!result->kind.media_rule) {
1283  cr_utils_trace_info ("Out of memory");
1284  g_free (result);
1285  return NULL;
1286  }
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 !");
1294  goto error;
1295  }
1296  cur->kind.ruleset->parent_media_rule = result;
1297  }
1298 
1299  result->kind.media_rule->media_list = a_media;
1300  if (a_sheet) {
1301  cr_statement_set_parent_sheet (result, a_sheet);
1302  }
1303 
1304  return result;
1305 
1306  error:
1307  return NULL;
1308 }
1309 
1310 /**
1311  * cr_statement_new_at_import_rule:
1312  *
1313  *@a_url: the url to connect to the get the file
1314  *to be imported.
1315  *@a_sheet: the imported parsed stylesheet.
1316  *
1317  *Creates a new instance of #CRStatment of type
1318  *#CRAtImportRule.
1319  *
1320  *Returns the newly built instance of #CRStatement.
1321  */
1322 CRStatement *
1324  CRString * a_url,
1325  GList * a_media_list,
1326  CRStyleSheet * a_imported_sheet)
1327 {
1328  CRStatement *result = NULL;
1329 
1330  result = g_try_malloc (sizeof (CRStatement));
1331 
1332  if (!result) {
1333  cr_utils_trace_info ("Out of memory");
1334  return NULL;
1335  }
1336 
1337  memset (result, 0, sizeof (CRStatement));
1338  result->type = AT_IMPORT_RULE_STMT;
1339 
1340  result->kind.import_rule = g_try_malloc (sizeof (CRAtImportRule));
1341 
1342  if (!result->kind.import_rule) {
1343  cr_utils_trace_info ("Out of memory");
1344  g_free (result);
1345  return NULL;
1346  }
1347 
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);
1354 
1355  return result;
1356 }
1357 
1358 /**
1359  * cr_statement_at_import_rule_parse_from_buf:
1360  *
1361  *@a_buf: the buffer to parse.
1362  *@a_encoding: the encoding of a_buf.
1363  *
1364  *Parses a buffer that contains an "\@import" rule and
1365  *instanciate a #CRStatement of type AT_IMPORT_RULE_STMT
1366  *
1367  *Returns the newly built instance of #CRStatement in case of
1368  *a successful parsing, NULL otherwise.
1369  */
1370 CRStatement *
1372  enum CREncoding a_encoding)
1373 {
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} ;
1380 
1381  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1382  a_encoding, FALSE);
1383  if (!parser) {
1384  cr_utils_trace_info ("Instantiation of parser failed.");
1385  goto cleanup;
1386  }
1387 
1389  if (status != CR_OK)
1390  goto cleanup;
1391 
1392  status = cr_parser_parse_import (parser,
1393  &media_list,
1394  &import_string,
1395  &location);
1396  if (status != CR_OK || !import_string)
1397  goto cleanup;
1398 
1399  result = cr_statement_new_at_import_rule (NULL, import_string,
1400  media_list, NULL);
1401  if (result) {
1403  &location) ;
1404  import_string = NULL;
1405  media_list = NULL;
1406  }
1407 
1408  cleanup:
1409  if (parser) {
1410  cr_parser_destroy (parser);
1411  parser = NULL;
1412  }
1413  if (media_list) {
1414  for (; media_list;
1415  media_list = g_list_next (media_list)) {
1416  if (media_list->data) {
1417  cr_string_destroy ((CRString*)media_list->data);
1418  media_list->data = NULL;
1419  }
1420  }
1421  g_list_free (media_list);
1422  media_list = NULL;
1423  }
1424  if (import_string) {
1425  cr_string_destroy (import_string);
1426  import_string = NULL;
1427  }
1428 
1429  return result;
1430 }
1431 
1432 /**
1433  * cr_statement_new_at_page_rule:
1434  *
1435  *@a_decl_list: a list of instances of #CRDeclarations
1436  *which is actually the list of declarations that applies to
1437  *this page rule.
1438  *@a_selector: the page rule selector.
1439  *
1440  *Creates a new instance of #CRStatement of type
1441  *#CRAtPageRule.
1442  *
1443  *Returns the newly built instance of #CRStatement or NULL
1444  *in case of error.
1445  */
1446 CRStatement *
1448  CRDeclaration * a_decl_list,
1449  CRString * a_name, CRString * a_pseudo)
1450 {
1451  CRStatement *result = NULL;
1452 
1453  result = g_try_malloc (sizeof (CRStatement));
1454 
1455  if (!result) {
1456  cr_utils_trace_info ("Out of memory");
1457  return NULL;
1458  }
1459 
1460  memset (result, 0, sizeof (CRStatement));
1461  result->type = AT_PAGE_RULE_STMT;
1462 
1463  result->kind.page_rule = g_try_malloc (sizeof (CRAtPageRule));
1464 
1465  if (!result->kind.page_rule) {
1466  cr_utils_trace_info ("Out of memory");
1467  g_free (result);
1468  return NULL;
1469  }
1470 
1471  memset (result->kind.page_rule, 0, sizeof (CRAtPageRule));
1472  if (a_decl_list) {
1473  result->kind.page_rule->decl_list = a_decl_list;
1474  cr_declaration_ref (a_decl_list);
1475  }
1476  result->kind.page_rule->name = a_name;
1477  result->kind.page_rule->pseudo = a_pseudo;
1478  if (a_sheet)
1479  cr_statement_set_parent_sheet (result, a_sheet);
1480 
1481  return result;
1482 }
1483 
1484 /**
1485  * cr_statement_at_page_rule_parse_from_buf:
1486  *
1487  *@a_buf: the character buffer to parse.
1488  *@a_encoding: the character encoding of a_buf.
1489  *
1490  *Parses a buffer that contains an "\@page" production and,
1491  *if the parsing succeeds, builds the page statement.
1492  *
1493  *Returns the newly built at page statement in case of successful parsing,
1494  *NULL otherwise.
1495  */
1496 CRStatement *
1498  enum CREncoding a_encoding)
1499 {
1500  enum CRStatus status = CR_OK;
1501  CRParser *parser = NULL;
1502  CRDocHandler *sac_handler = NULL;
1503  CRStatement *result = NULL;
1504  CRStatement **resultptr = NULL;
1505 
1506  g_return_val_if_fail (a_buf, NULL);
1507 
1508  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1509  a_encoding, FALSE);
1510  if (!parser) {
1511  cr_utils_trace_info ("Instantiation of the parser failed.");
1512  goto cleanup;
1513  }
1514 
1515  sac_handler = cr_doc_handler_new ();
1516  if (!sac_handler) {
1518  ("Instantiation of the sac handler failed.");
1519  goto cleanup;
1520  }
1521 
1522  sac_handler->start_page = parse_page_start_page_cb;
1523  sac_handler->property = parse_page_property_cb;
1524  sac_handler->end_page = parse_page_end_page_cb;
1525  sac_handler->unrecoverable_error = parse_page_unrecoverable_error_cb;
1526 
1527  status = cr_parser_set_sac_handler (parser, sac_handler);
1528  if (status != CR_OK)
1529  goto cleanup;
1530 
1531  /*Now, invoke the parser to parse the "@page production" */
1533  if (status != CR_OK)
1534  goto cleanup;
1535  status = cr_parser_parse_page (parser);
1536  if (status != CR_OK)
1537  goto cleanup;
1538 
1539  resultptr = &result;
1540  status = cr_doc_handler_get_result (sac_handler,
1541  (gpointer *) resultptr);
1542 
1543  cleanup:
1544 
1545  if (parser) {
1546  cr_parser_destroy (parser);
1547  parser = NULL;
1548  sac_handler = NULL ;
1549  }
1550  if (sac_handler) {
1551  cr_doc_handler_unref (sac_handler);
1552  sac_handler = NULL;
1553  }
1554  return result;
1555 }
1556 
1557 /**
1558  * cr_statement_new_at_charset_rule:
1559  *
1560  *@a_charset: the string representing the charset.
1561  *Note that the newly built instance of #CRStatement becomes
1562  *the owner of a_charset. The caller must not free a_charset !!!.
1563  *
1564  *Creates a new instance of #CRStatement of type
1565  *#CRAtCharsetRule.
1566  *
1567  *Returns the newly built instance of #CRStatement or NULL
1568  *if an error arises.
1569  */
1570 CRStatement *
1572  CRString * a_charset)
1573 {
1574  CRStatement *result = NULL;
1575 
1576  g_return_val_if_fail (a_charset, NULL);
1577 
1578  result = g_try_malloc (sizeof (CRStatement));
1579 
1580  if (!result) {
1581  cr_utils_trace_info ("Out of memory");
1582  return NULL;
1583  }
1584 
1585  memset (result, 0, sizeof (CRStatement));
1586  result->type = AT_CHARSET_RULE_STMT;
1587 
1588  result->kind.charset_rule = g_try_malloc (sizeof (CRAtCharsetRule));
1589 
1590  if (!result->kind.charset_rule) {
1591  cr_utils_trace_info ("Out of memory");
1592  g_free (result);
1593  return NULL;
1594  }
1595  memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule));
1596  result->kind.charset_rule->charset = a_charset;
1597  cr_statement_set_parent_sheet (result, a_sheet);
1598 
1599  return result;
1600 }
1601 
1602 /**
1603  * cr_statement_at_charset_rule_parse_from_buf:
1604  *
1605  *@a_buf: the buffer to parse.
1606  *@a_encoding: the character encoding of the buffer.
1607  *
1608  *Parses a buffer that contains an '\@charset' rule and
1609  *creates an instance of #CRStatement of type AT_CHARSET_RULE_STMT.
1610  *
1611  *Returns the newly built instance of #CRStatement.
1612  */
1613 CRStatement *
1615  enum CREncoding a_encoding)
1616 {
1617  enum CRStatus status = CR_OK;
1618  CRParser *parser = NULL;
1619  CRStatement *result = NULL;
1620  CRString *charset = NULL;
1621 
1622  g_return_val_if_fail (a_buf, NULL);
1623 
1624  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1625  a_encoding, FALSE);
1626  if (!parser) {
1627  cr_utils_trace_info ("Instantiation of the parser failed.");
1628  goto cleanup;
1629  }
1630 
1631  /*Now, invoke the parser to parse the "@charset production" */
1633  if (status != CR_OK)
1634  goto cleanup;
1635  status = cr_parser_parse_charset (parser, &charset, NULL);
1636  if (status != CR_OK || !charset)
1637  goto cleanup;
1638 
1639  result = cr_statement_new_at_charset_rule (NULL, charset);
1640  if (result)
1641  charset = NULL;
1642 
1643  cleanup:
1644 
1645  if (parser) {
1646  cr_parser_destroy (parser);
1647  parser = NULL;
1648  }
1649  if (charset) {
1650  cr_string_destroy (charset);
1651  }
1652 
1653  return result;
1654 }
1655 
1656 /**
1657  * cr_statement_new_at_font_face_rule:
1658  *
1659  *@a_font_decls: a list of instances of #CRDeclaration. Each declaration
1660  *is actually a font declaration.
1661  *
1662  *Creates an instance of #CRStatement of type #CRAtFontFaceRule.
1663  *
1664  *Returns the newly built instance of #CRStatement.
1665  */
1666 CRStatement *
1668  CRDeclaration * a_font_decls)
1669 {
1670  CRStatement *result = NULL;
1671 
1672  result = g_try_malloc (sizeof (CRStatement));
1673 
1674  if (!result) {
1675  cr_utils_trace_info ("Out of memory");
1676  return NULL;
1677  }
1678  memset (result, 0, sizeof (CRStatement));
1679  result->type = AT_FONT_FACE_RULE_STMT;
1680 
1681  result->kind.font_face_rule = g_try_malloc
1682  (sizeof (CRAtFontFaceRule));
1683 
1684  if (!result->kind.font_face_rule) {
1685  cr_utils_trace_info ("Out of memory");
1686  g_free (result);
1687  return NULL;
1688  }
1689  memset (result->kind.font_face_rule, 0, sizeof (CRAtFontFaceRule));
1690 
1691  result->kind.font_face_rule->decl_list = a_font_decls;
1692  if (a_sheet)
1693  cr_statement_set_parent_sheet (result, a_sheet);
1694 
1695  return result;
1696 }
1697 
1698 /**
1699  * cr_statement_font_face_rule_parse_from_buf:
1700  *
1701  *
1702  *@a_buf: the buffer to parse.
1703  *@a_encoding: the character encoding of a_buf.
1704  *
1705  *Parses a buffer that contains an "\@font-face" rule and builds
1706  *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it.
1707  *
1708  *Returns the newly built instance of #CRStatement in case of successufull
1709  *parsing, NULL otherwise.
1710  */
1711 CRStatement *
1713  enum CREncoding a_encoding)
1714 {
1715  CRStatement *result = NULL;
1716  CRStatement **resultptr = NULL;
1717  CRParser *parser = NULL;
1718  CRDocHandler *sac_handler = NULL;
1719  enum CRStatus status = CR_OK;
1720 
1721  parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf),
1722  a_encoding, FALSE);
1723  if (!parser)
1724  goto cleanup;
1725 
1726  sac_handler = cr_doc_handler_new ();
1727  if (!sac_handler)
1728  goto cleanup;
1729 
1730  /*
1731  *set sac callbacks here
1732  */
1733  sac_handler->start_font_face = parse_font_face_start_font_face_cb;
1734  sac_handler->property = parse_font_face_property_cb;
1735  sac_handler->end_font_face = parse_font_face_end_font_face_cb;
1736  sac_handler->unrecoverable_error =
1737  parse_font_face_unrecoverable_error_cb;
1738 
1739  status = cr_parser_set_sac_handler (parser, sac_handler);
1740  if (status != CR_OK)
1741  goto cleanup;
1742 
1743  /*
1744  *cleanup spaces of comment that may be there before the real
1745  *"@font-face" thing.
1746  */
1748  if (status != CR_OK)
1749  goto cleanup;
1750 
1751  status = cr_parser_parse_font_face (parser);
1752  if (status != CR_OK)
1753  goto cleanup;
1754 
1755  resultptr = &result;
1756  status = cr_doc_handler_get_result (sac_handler,
1757  (gpointer *) resultptr);
1758  if (status != CR_OK || !result)
1759  goto cleanup;
1760 
1761  cleanup:
1762  if (parser) {
1763  cr_parser_destroy (parser);
1764  parser = NULL;
1765  sac_handler = NULL ;
1766  }
1767  if (sac_handler) {
1768  cr_doc_handler_unref (sac_handler);
1769  sac_handler = NULL;
1770  }
1771  return result;
1772 }
1773 
1774 /**
1775  * cr_statement_set_parent_sheet:
1776  *
1777  *@a_this: the current instance of #CRStatement.
1778  *@a_sheet: the sheet that contains the current statement.
1779  *
1780  *Sets the container stylesheet.
1781  *
1782  *Returns CR_OK upon successful completion, an error code otherwise.
1783  */
1784 enum CRStatus
1786 {
1787  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1788  a_this->parent_sheet = a_sheet;
1789  return CR_OK;
1790 }
1791 
1792 /**
1793  * cr_statement_get_parent_sheet:
1794  *
1795  *@a_this: the current #CRStatement.
1796  *@a_sheet: out parameter. A pointer to the sheets that
1797  *
1798  *Gets the sheets that contains the current statement.
1799  *
1800  *Returns CR_OK upon successful completion, an error code otherwise.
1801  */
1802 enum CRStatus
1804 {
1805  g_return_val_if_fail (a_this && a_sheet, CR_BAD_PARAM_ERROR);
1806  *a_sheet = a_this->parent_sheet;
1807  return CR_OK;
1808 }
1809 
1810 /**
1811  * cr_statement_append:
1812  *
1813  *@a_this: the current instance of the statement list.
1814  *@a_new: a_new the new instance of #CRStatement to append.
1815  *
1816  *Appends a new statement to the statement list.
1817  *
1818  *Returns the new list statement list, or NULL in cas of failure.
1819  */
1820 CRStatement *
1822 {
1823  CRStatement *cur = NULL;
1824 
1825  g_return_val_if_fail (a_new, NULL);
1826 
1827  if (!a_this) {
1828  return a_new;
1829  }
1830 
1831  /*walk forward in the current list to find the tail list element */
1832  for (cur = a_this; cur && cur->next; cur = cur->next) ;
1833 
1834  cur->next = a_new;
1835  a_new->prev = cur;
1836 
1837  return a_this;
1838 }
1839 
1840 /**
1841  * cr_statement_prepend:
1842  *
1843  *@a_this: the current instance of #CRStatement.
1844  *@a_new: the new statement to prepend.
1845  *
1846  *Prepends the an instance of #CRStatement to
1847  *the current statement list.
1848  *
1849  *Returns the new list with the new statement prepended,
1850  *or NULL in case of an error.
1851  */
1852 CRStatement *
1854 {
1855  CRStatement *cur = NULL;
1856 
1857  g_return_val_if_fail (a_new, NULL);
1858 
1859  if (!a_this)
1860  return a_new;
1861 
1862  a_new->next = a_this;
1863  a_this->prev = a_new;
1864 
1865  /*walk backward in the prepended list to find the head list element */
1866  for (cur = a_new; cur && cur->prev; cur = cur->prev) ;
1867 
1868  return cur;
1869 }
1870 
1871 /**
1872  * cr_statement_unlink:
1873  *
1874  *@a_this: the current statements list.
1875  *@a_to_unlink: the statement to unlink from the list.
1876  *
1877  *Unlinks a statement from the statements list.
1878  *
1879  *Returns the new list where a_to_unlink has been unlinked
1880  *from, or NULL in case of error.
1881  */
1882 CRStatement *
1884 {
1885  CRStatement *result = a_stmt;
1886 
1887  g_return_val_if_fail (result, NULL);
1888 
1889  /**
1890  *Some sanity checks first
1891  */
1892  if (a_stmt->next) {
1893  g_return_val_if_fail (a_stmt->next->prev == a_stmt, NULL);
1894  }
1895  if (a_stmt->prev) {
1896  g_return_val_if_fail (a_stmt->prev->next == a_stmt, NULL);
1897  }
1898 
1899  /**
1900  *Now, the real unlinking job.
1901  */
1902  if (a_stmt->next) {
1903  a_stmt->next->prev = a_stmt->prev;
1904  }
1905  if (a_stmt->prev) {
1906  a_stmt->prev->next = a_stmt->next;
1907  }
1908 
1909  if (a_stmt->parent_sheet
1910  && a_stmt->parent_sheet->statements == a_stmt) {
1911  a_stmt->parent_sheet->statements =
1912  a_stmt->parent_sheet->statements->next;
1913  }
1914 
1915  a_stmt->next = NULL;
1916  a_stmt->prev = NULL;
1917  a_stmt->parent_sheet = NULL;
1918 
1919  return result;
1920 }
1921 
1922 /**
1923  * cr_statement_nr_rules:
1924  *
1925  *@a_this: the current instance of #CRStatement.
1926  *
1927  *Gets the number of rules in the statement list;
1928  *
1929  *Returns number of rules in the statement list.
1930  */
1931 gint
1933 {
1934  CRStatement const *cur = NULL;
1935  int nr = 0;
1936 
1937  g_return_val_if_fail (a_this, -1);
1938 
1939  for (cur = a_this; cur; cur = cur->next)
1940  nr++;
1941  return nr;
1942 }
1943 
1944 /**
1945  * cr_statement_get_from_list:
1946  *
1947  *@a_this: the current instance of #CRStatement.
1948  *@itemnr: the index into the statement list.
1949  *
1950  *Use an index to get a CRStatement from the statement list.
1951  *
1952  *Returns CRStatement at position itemnr, if itemnr > number of statements - 1,
1953  *it will return NULL.
1954  */
1955 CRStatement *
1957 {
1958  CRStatement *cur = NULL;
1959  int nr = 0;
1960 
1961  g_return_val_if_fail (a_this, NULL);
1962 
1963  for (cur = a_this; cur; cur = cur->next)
1964  if (nr++ == itemnr)
1965  return cur;
1966  return NULL;
1967 }
1968 
1969 /**
1970  * cr_statement_ruleset_set_sel_list:
1971  *
1972  *@a_this: the current ruleset statement.
1973  *@a_sel_list: the selector list to set. Note
1974  *that this function increments the ref count of a_sel_list.
1975  *The sel list will be destroyed at the destruction of the
1976  *current instance of #CRStatement.
1977  *
1978  *Sets a selector list to a ruleset statement.
1979  *
1980  *Returns CR_OK upon successful completion, an error code otherwise.
1981  */
1982 enum CRStatus
1984  CRSelector * a_sel_list)
1985 {
1986  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT,
1988 
1989  if (a_this->kind.ruleset->sel_list)
1991 
1992  a_this->kind.ruleset->sel_list = a_sel_list;
1993 
1994  if (a_sel_list)
1995  cr_selector_ref (a_sel_list);
1996 
1997  return CR_OK;
1998 }
1999 
2000 /**
2001  * cr_statement_ruleset_get_declarations:
2002  *
2003  *@a_this: the current instance of #CRStatement.
2004  *@a_decl_list: out parameter. A pointer to the the returned
2005  *list of declaration. Must not be NULL.
2006  *
2007  *Gets a pointer to the list of declaration contained
2008  *in the ruleset statement.
2009  *
2010  *Returns CR_OK upon successful completion, an error code if something
2011  *bad happened.
2012  */
2013 enum CRStatus
2015  CRDeclaration ** a_decl_list)
2016 {
2017  g_return_val_if_fail (a_this
2018  && a_this->type == RULESET_STMT
2019  && a_this->kind.ruleset
2020  && a_decl_list, CR_BAD_PARAM_ERROR);
2021 
2022  *a_decl_list = a_this->kind.ruleset->decl_list;
2023 
2024  return CR_OK;
2025 }
2026 
2027 /**
2028  * cr_statement_ruleset_get_sel_list:
2029  *
2030  *@a_this: the current ruleset statement.
2031  *@a_list: out parameter. The returned selector list,
2032  *if and only if the function returned CR_OK.
2033  *
2034  *Gets a pointer to the selector list contained in
2035  *the current ruleset statement.
2036  *
2037  *Returns CR_OK upon successful completion, an error code otherwise.
2038  */
2039 enum CRStatus
2041 {
2042  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2043  && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2044 
2045  *a_list = a_this->kind.ruleset->sel_list;
2046 
2047  return CR_OK;
2048 }
2049 
2050 /**
2051  * cr_statement_ruleset_set_decl_list:
2052  *
2053  *@a_this: the current ruleset statement.
2054  *@a_list: the declaration list to be added to the current
2055  *ruleset statement.
2056  *
2057  *Sets a declaration list to the current ruleset statement.
2058  *
2059  *Returns CR_OK upon successful completion, an error code otherwise.
2060  */
2061 enum CRStatus
2063  CRDeclaration * a_list)
2064 {
2065  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2066  && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2067 
2068  if (a_this->kind.ruleset->decl_list == a_list)
2069  return CR_OK;
2070 
2071  if (a_this->kind.ruleset->sel_list) {
2073  }
2074 
2075  a_this->kind.ruleset->sel_list = NULL;
2076 
2077  return CR_OK;
2078 }
2079 
2080 /**
2081  * cr_statement_ruleset_append_decl2:
2082  *
2083  *@a_this: the current statement.
2084  *@a_prop: the property of the declaration.
2085  *@a_value: the value of the declaration.
2086  *
2087  *Appends a declaration to the current ruleset statement.
2088  *
2089  *Returns CR_OK upon successful completion, an error code
2090  *otherwise.
2091  */
2092 enum CRStatus
2094  CRString * a_prop,
2095  CRTerm * a_value)
2096 {
2097  CRDeclaration *new_decls = NULL;
2098 
2099  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2100  && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2101 
2102  new_decls = cr_declaration_append2
2103  (a_this->kind.ruleset->decl_list,
2104  a_prop, a_value);
2105  g_return_val_if_fail (new_decls, CR_ERROR);
2106  a_this->kind.ruleset->decl_list = new_decls;
2107 
2108  return CR_OK;
2109 }
2110 
2111 /**
2112  * cr_statement_ruleset_append_decl:
2113  *
2114  *Appends a declaration to the current statement.
2115  *
2116  *@a_this: the current statement.
2117  *@a_declaration: the declaration to append.
2118  *
2119  *Returns CR_OK upon sucessful completion, an error code
2120  *otherwise.
2121  */
2122 enum CRStatus
2124  CRDeclaration * a_decl)
2125 {
2126  CRDeclaration *new_decls = NULL;
2127 
2128  g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
2129  && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
2130 
2131  new_decls = cr_declaration_append
2132  (a_this->kind.ruleset->decl_list, a_decl);
2133  g_return_val_if_fail (new_decls, CR_ERROR);
2134  a_this->kind.ruleset->decl_list = new_decls;
2135 
2136  return CR_OK;
2137 }
2138 
2139 /**
2140  * cr_statement_at_import_rule_set_imported_sheet:
2141  *
2142  *Sets a stylesheet to the current \@import rule.
2143  *@a_this: the current \@import rule.
2144  *@a_sheet: the stylesheet. The stylesheet is owned
2145  *by the current instance of #CRStatement, that is, the
2146  *stylesheet will be destroyed when the current instance
2147  *of #CRStatement is destroyed.
2148  *
2149  *Returns CR_OK upon successful completion, an error code otherwise.
2150  */
2151 enum CRStatus
2153  CRStyleSheet * a_sheet)
2154 {
2155  g_return_val_if_fail (a_this
2156  && a_this->type == AT_IMPORT_RULE_STMT
2157  && a_this->kind.import_rule,
2159 
2160  a_this->kind.import_rule->sheet = a_sheet;
2161 
2162  return CR_OK;
2163 }
2164 
2165 /**
2166  * cr_statement_at_import_rule_get_imported_sheet:
2167  *
2168  *@a_this: the current \@import rule statement.
2169  *@a_sheet: out parameter. The returned stylesheet if and
2170  *only if the function returns CR_OK.
2171  *
2172  *Gets the stylesheet contained by the \@import rule statement.
2173  *Returns CR_OK upon sucessful completion, an error code otherwise.
2174  */
2175 enum CRStatus
2177  CRStyleSheet ** a_sheet)
2178 {
2179  g_return_val_if_fail (a_this
2180  && a_this->type == AT_IMPORT_RULE_STMT
2181  && a_this->kind.import_rule,
2183  *a_sheet = a_this->kind.import_rule->sheet;
2184  return CR_OK;
2185 
2186 }
2187 
2188 /**
2189  * cr_statement_at_import_rule_set_url:
2190  *
2191  *@a_this: the current \@import rule statement.
2192  *@a_url: the url to set.
2193  *
2194  *Sets an url to the current \@import rule statement.
2195  *
2196  *Returns CR_OK upon successful completion, an error code otherwise.
2197  */
2198 enum CRStatus
2200  CRString * a_url)
2201 {
2202  g_return_val_if_fail (a_this
2203  && a_this->type == AT_IMPORT_RULE_STMT
2204  && a_this->kind.import_rule,
2206 
2207  if (a_this->kind.import_rule->url) {
2209  }
2210 
2211  a_this->kind.import_rule->url = a_url;
2212 
2213  return CR_OK;
2214 }
2215 
2216 /**
2217  * cr_statement_at_import_rule_get_url:
2218  *
2219  *@a_this: the current \@import rule statement.
2220  *@a_url: out parameter. The returned url if
2221  *and only if the function returned CR_OK.
2222  *
2223  *Gets the url of the \@import rule statement.
2224  *Returns CR_OK upon successful completion, an error code otherwise.
2225  */
2226 enum CRStatus
2228  CRString ** a_url)
2229 {
2230  g_return_val_if_fail (a_this
2231  && a_this->type == AT_IMPORT_RULE_STMT
2232  && a_this->kind.import_rule,
2234 
2235  *a_url = a_this->kind.import_rule->url;
2236 
2237  return CR_OK;
2238 }
2239 
2240 /**
2241  * cr_statement_at_media_nr_rules:
2242  *
2243  *@a_this: the current instance of #CRStatement.
2244  *
2245  *Returns the number of rules in the media rule;
2246  */
2247 int
2249 {
2250  g_return_val_if_fail (a_this
2251  && a_this->type == AT_MEDIA_RULE_STMT
2252  && a_this->kind.media_rule, CR_BAD_PARAM_ERROR);
2253 
2254  return cr_statement_nr_rules (a_this->kind.media_rule->rulesets);
2255 }
2256 
2257 /**
2258  * cr_statement_at_media_get_from_list:
2259  *
2260  *@a_this: the current instance of #CRStatement.
2261  *@itemnr: the index into the media rule list of rules.
2262  *
2263  *Use an index to get a CRStatement from the media rule list of rules.
2264  *
2265  *Returns CRStatement at position itemnr, if itemnr > number of rules - 1,
2266  *it will return NULL.
2267  */
2268 CRStatement *
2270 {
2271  g_return_val_if_fail (a_this
2272  && a_this->type == AT_MEDIA_RULE_STMT
2273  && a_this->kind.media_rule, NULL);
2274 
2276  itemnr);
2277 }
2278 
2279 /**
2280  * cr_statement_at_page_rule_set_declarations:
2281  *
2282  *@a_this: the current \@page rule statement.
2283  *@a_decl_list: the declaration list to add. Will be freed
2284  *by the current instance of #CRStatement when it is destroyed.
2285  *
2286  *Sets a declaration list to the current \@page rule statement.
2287  *
2288  *Returns CR_OK upon successful completion, an error code otherwise.
2289  */
2290 enum CRStatus
2292  CRDeclaration * a_decl_list)
2293 {
2294  g_return_val_if_fail (a_this
2295  && a_this->type == AT_PAGE_RULE_STMT
2296  && a_this->kind.page_rule, CR_BAD_PARAM_ERROR);
2297 
2298  if (a_this->kind.page_rule->decl_list) {
2300  }
2301 
2302  a_this->kind.page_rule->decl_list = a_decl_list;
2303 
2304  if (a_decl_list) {
2305  cr_declaration_ref (a_decl_list);
2306  }
2307 
2308  return CR_OK;
2309 }
2310 
2311 /**
2312  * cr_statement_at_page_rule_get_declarations:
2313  *
2314  *@a_this: the current \@page rule statement.
2315  *@a_decl_list: out parameter. The returned declaration list.
2316  *
2317  *Gets the declaration list associated to the current \@page rule
2318  *statement.
2319  *
2320  *Returns CR_OK upon successful completion, an error code otherwise.
2321  */
2322 enum CRStatus
2324  CRDeclaration ** a_decl_list)
2325 {
2326  g_return_val_if_fail (a_this
2327  && a_this->type == AT_PAGE_RULE_STMT
2328  && a_this->kind.page_rule, CR_BAD_PARAM_ERROR);
2329 
2330  *a_decl_list = a_this->kind.page_rule->decl_list;
2331 
2332  return CR_OK;
2333 }
2334 
2335 /**
2336  * cr_statement_at_charset_rule_set_charset:
2337  *
2338  *
2339  *@a_this: the current \@charset rule statement.
2340  *@a_charset: the charset to set.
2341  *
2342  *Sets the charset of the current \@charset rule statement.
2343  *
2344  *Returns CR_OK upon successful completion, an error code otherwise.
2345  */
2346 enum CRStatus
2348  CRString * a_charset)
2349 {
2350  g_return_val_if_fail (a_this
2351  && a_this->type == AT_CHARSET_RULE_STMT
2352  && a_this->kind.charset_rule,
2354 
2355  if (a_this->kind.charset_rule->charset) {
2357  }
2358  a_this->kind.charset_rule->charset = a_charset;
2359  return CR_OK;
2360 }
2361 
2362 /**
2363  * cr_statement_at_charset_rule_get_charset:
2364  *@a_this: the current \@charset rule statement.
2365  *@a_charset: out parameter. The returned charset string if
2366  *and only if the function returned CR_OK.
2367  *
2368  *Gets the charset string associated to the current
2369  *\@charset rule statement.
2370  *
2371  * Returns CR_OK upon successful completion, an error code otherwise.
2372  */
2373 enum CRStatus
2375  CRString ** a_charset)
2376 {
2377  g_return_val_if_fail (a_this
2378  && a_this->type == AT_CHARSET_RULE_STMT
2379  && a_this->kind.charset_rule,
2381 
2382  *a_charset = a_this->kind.charset_rule->charset;
2383 
2384  return CR_OK;
2385 }
2386 
2387 /**
2388  * cr_statement_at_font_face_rule_set_decls:
2389  *
2390  *@a_this: the current \@font-face rule statement.
2391  *@a_decls: the declarations list to set.
2392  *
2393  *Sets a declaration list to the current \@font-face rule statement.
2394  *
2395  *Returns CR_OK upon successful completion, an error code otherwise.
2396  */
2397 enum CRStatus
2399  CRDeclaration * a_decls)
2400 {
2401  g_return_val_if_fail (a_this
2402  && a_this->type == AT_FONT_FACE_RULE_STMT
2403  && a_this->kind.font_face_rule,
2405 
2406  if (a_this->kind.font_face_rule->decl_list) {
2408  }
2409 
2410  a_this->kind.font_face_rule->decl_list = a_decls;
2411  cr_declaration_ref (a_decls);
2412 
2413  return CR_OK;
2414 }
2415 
2416 /**
2417  * cr_statement_at_font_face_rule_get_decls:
2418  *
2419  *@a_this: the current \@font-face rule statement.
2420  *@a_decls: out parameter. The returned declaration list if
2421  *and only if this function returns CR_OK.
2422  *
2423  *Gets the declaration list associated to the current instance
2424  *of \@font-face rule statement.
2425  *
2426  *Returns CR_OK upon successful completion, an error code otherwise.
2427  */
2428 enum CRStatus
2430  CRDeclaration ** a_decls)
2431 {
2432  g_return_val_if_fail (a_this
2433  && a_this->type == AT_FONT_FACE_RULE_STMT
2434  && a_this->kind.font_face_rule,
2436 
2437  *a_decls = a_this->kind.font_face_rule->decl_list;
2438 
2439  return CR_OK;
2440 }
2441 
2442 /**
2443  * cr_statement_at_font_face_rule_add_decl:
2444  *
2445  *@a_this: the current \@font-face rule statement.
2446  *@a_prop: the property of the declaration.
2447  *@a_value: the value of the declaration.
2448  *
2449  *Adds a declaration to the current \@font-face rule
2450  *statement.
2451  *
2452  *Returns CR_OK upon successful completion, an error code otherwise.
2453  */
2454 enum CRStatus
2456  CRString * a_prop, CRTerm * a_value)
2457 {
2458  CRDeclaration *decls = NULL;
2459 
2460  g_return_val_if_fail (a_this
2461  && a_this->type == AT_FONT_FACE_RULE_STMT
2462  && a_this->kind.font_face_rule,
2464 
2465  decls = cr_declaration_append2
2466  (a_this->kind.font_face_rule->decl_list,
2467  a_prop, a_value);
2468 
2469  g_return_val_if_fail (decls, CR_ERROR);
2470 
2471  if (a_this->kind.font_face_rule->decl_list == NULL)
2472  cr_declaration_ref (decls);
2473 
2474  a_this->kind.font_face_rule->decl_list = decls;
2475 
2476  return CR_OK;
2477 }
2478 
2479 
2480 /**
2481  * cr_statement_to_string:
2482  *
2483  *@a_this: the current statement to serialize
2484  *@a_indent: the number of white space of indentation.
2485  *
2486  *Serializes a css statement into a string
2487  *
2488  *Returns the serialized statement. Must be freed by the caller
2489  *using g_free().
2490  */
2491 gchar *
2492 cr_statement_to_string (CRStatement const * a_this, gulong a_indent)
2493 {
2494  gchar *str = NULL ;
2495 
2496  if (!a_this)
2497  return NULL;
2498 
2499  switch (a_this->type) {
2500  case RULESET_STMT:
2501  str = cr_statement_ruleset_to_string
2502  (a_this, a_indent);
2503  break;
2504 
2506  str = cr_statement_font_face_rule_to_string
2507  (a_this, a_indent) ;
2508  break;
2509 
2510  case AT_CHARSET_RULE_STMT:
2511  str = cr_statement_charset_to_string
2512  (a_this, a_indent);
2513  break;
2514 
2515  case AT_PAGE_RULE_STMT:
2516  str = cr_statement_at_page_rule_to_string
2517  (a_this, a_indent);
2518  break;
2519 
2520  case AT_MEDIA_RULE_STMT:
2521  str = cr_statement_media_rule_to_string
2522  (a_this, a_indent);
2523  break;
2524 
2525  case AT_IMPORT_RULE_STMT:
2526  str = cr_statement_import_rule_to_string
2527  (a_this, a_indent);
2528  break;
2529 
2530  default:
2531  cr_utils_trace_info ("Statement unrecognized");
2532  break;
2533  }
2534  return str ;
2535 }
2536 
2537 gchar*
2538 cr_statement_list_to_string (CRStatement const *a_this, gulong a_indent)
2539 {
2540  CRStatement const *cur_stmt = NULL ;
2541  GString *stringue = NULL ;
2542  gchar *str = NULL ;
2543 
2544  g_return_val_if_fail (a_this, NULL) ;
2545 
2546  stringue = g_string_new (NULL) ;
2547  if (!stringue) {
2548  cr_utils_trace_info ("Out of memory") ;
2549  return NULL ;
2550  }
2551  for (cur_stmt = a_this ; cur_stmt;
2552  cur_stmt = cur_stmt->next) {
2553  str = cr_statement_to_string (cur_stmt, a_indent) ;
2554  if (str) {
2555  if (!cur_stmt->prev) {
2556  g_string_append (stringue, str) ;
2557  } else {
2558  g_string_append_printf
2559  (stringue, "\n%s", str) ;
2560  }
2561  g_free (str) ;
2562  str = NULL ;
2563  }
2564  }
2565  str = stringue->str ;
2566  g_string_free (stringue, FALSE) ;
2567  return str ;
2568 }
2569 
2570 /**
2571  * cr_statement_dump:
2572  *
2573  *@a_this: the current css2 statement.
2574  *@a_fp: the destination file pointer.
2575  *@a_indent: the number of white space indentation characters.
2576  *
2577  *Dumps the css2 statement to a file.
2578  */
2579 void
2580 cr_statement_dump (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2581 {
2582  gchar *str = NULL ;
2583 
2584  if (!a_this)
2585  return;
2586 
2587  str = cr_statement_to_string (a_this, a_indent) ;
2588  if (str) {
2589  fprintf (a_fp, "%s",str) ;
2590  g_free (str) ;
2591  str = NULL ;
2592  }
2593 }
2594 
2595 /**
2596  * cr_statement_dump_ruleset:
2597  *
2598  *@a_this: the current instance of #CRStatement.
2599  *@a_fp: the destination file pointer.
2600  *@a_indent: the number of indentation white spaces to add.
2601  *
2602  *Dumps a ruleset statement to a file.
2603  */
2604 void
2605 cr_statement_dump_ruleset (CRStatement const * a_this, FILE * a_fp, glong a_indent)
2606 {
2607  gchar *str = NULL;
2608 
2609  g_return_if_fail (a_fp && a_this);
2610  str = cr_statement_ruleset_to_string (a_this, a_indent);
2611  if (str) {
2612  fprintf (a_fp, "%s", str);
2613  g_free (str);
2614  str = NULL;
2615  }
2616 }
2617 
2618 /**
2619  * cr_statement_dump_font_face_rule:
2620  *
2621  *@a_this: the current instance of font face rule statement.
2622  *@a_fp: the destination file pointer.
2623  *@a_indent: the number of white space indentation.
2624  *
2625  *Dumps a font face rule statement to a file.
2626  */
2627 void
2628 cr_statement_dump_font_face_rule (CRStatement const * a_this, FILE * a_fp,
2629  glong a_indent)
2630 {
2631  gchar *str = NULL ;
2632  g_return_if_fail (a_this
2633  && a_this->type == AT_FONT_FACE_RULE_STMT);
2634 
2635  str = cr_statement_font_face_rule_to_string (a_this,
2636  a_indent) ;
2637  if (str) {
2638  fprintf (a_fp, "%s", str) ;
2639  g_free (str) ;
2640  str = NULL ;
2641  }
2642 }
2643 
2644 /**
2645  * cr_statement_dump_charset:
2646  *
2647  *@a_this: the current instance of the \@charset rule statement.
2648  *@a_fp: the destination file pointer.
2649  *@a_indent: the number of indentation white spaces.
2650  *
2651  *Dumps an \@charset rule statement to a file.
2652  */
2653 void
2654 cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2655 {
2656  gchar *str = NULL;
2657 
2658  g_return_if_fail (a_this && a_this->type == AT_CHARSET_RULE_STMT);
2659 
2660  str = cr_statement_charset_to_string (a_this,
2661  a_indent) ;
2662  if (str) {
2663  fprintf (a_fp, "%s", str) ;
2664  g_free (str) ;
2665  str = NULL ;
2666  }
2667 }
2668 
2669 
2670 /**
2671  * cr_statement_dump_page:
2672  *
2673  *@a_this: the statement to dump on stdout.
2674  *@a_fp: the destination file pointer.
2675  *@a_indent: the number of indentation white spaces.
2676  *
2677  *Dumps an \@page rule statement on stdout.
2678  */
2679 void
2680 cr_statement_dump_page (CRStatement const * a_this, FILE * a_fp, gulong a_indent)
2681 {
2682  gchar *str = NULL;
2683 
2684  g_return_if_fail (a_this
2685  && a_this->type == AT_PAGE_RULE_STMT
2686  && a_this->kind.page_rule);
2687 
2688  str = cr_statement_at_page_rule_to_string (a_this, a_indent) ;
2689  if (str) {
2690  fprintf (a_fp, "%s", str);
2691  g_free (str) ;
2692  str = NULL ;
2693  }
2694 }
2695 
2696 
2697 /**
2698  * cr_statement_dump_media_rule:
2699  *
2700  *@a_this: the statement to dump.
2701  *@a_fp: the destination file pointer
2702  *@a_indent: the number of white spaces indentation.
2703  *
2704  *Dumps an \@media rule statement to a file.
2705  */
2706 void
2708  FILE * a_fp,
2709  gulong a_indent)
2710 {
2711  gchar *str = NULL ;
2712  g_return_if_fail (a_this->type == AT_MEDIA_RULE_STMT);
2713 
2714  str = cr_statement_media_rule_to_string (a_this, a_indent) ;
2715  if (str) {
2716  fprintf (a_fp, "%s", str) ;
2717  g_free (str) ;
2718  str = NULL ;
2719  }
2720 }
2721 
2722 /**
2723  * cr_statement_dump_import_rule:
2724  *
2725  *@a_fp: the destination file pointer.
2726  *@a_indent: the number of white space indentations.
2727  *
2728  *Dumps an \@import rule statement to a file.
2729  */
2730 void
2731 cr_statement_dump_import_rule (CRStatement const * a_this, FILE * a_fp,
2732  gulong a_indent)
2733 {
2734  gchar *str = NULL ;
2735  g_return_if_fail (a_this
2736  && a_this->type == AT_IMPORT_RULE_STMT
2737  && a_fp
2738  && a_this->kind.import_rule);
2739 
2740  str = cr_statement_import_rule_to_string (a_this, a_indent) ;
2741  if (str) {
2742  fprintf (a_fp, "%s", str) ;
2743  g_free (str) ;
2744  str = NULL ;
2745  }
2746 }
2747 
2748 /**
2749  * cr_statement_destroy:
2750  *
2751  * @a_this: the current instance of #CRStatement.
2752  *
2753  *Destructor of #CRStatement.
2754  */
2755 void
2757 {
2758  CRStatement *cur = NULL;
2759 
2760  g_return_if_fail (a_this);
2761 
2762  /*go get the tail of the list */
2763  for (cur = a_this; cur && cur->next; cur = cur->next) {
2764  cr_statement_clear (cur);
2765  }
2766 
2767  if (cur)
2768  cr_statement_clear (cur);
2769 
2770  if (cur->prev == NULL) {
2771  g_free (a_this);
2772  return;
2773  }
2774 
2775  /*walk backward and free next element */
2776  for (cur = cur->prev; cur && cur->prev; cur = cur->prev) {
2777  if (cur->next) {
2778  g_free (cur->next);
2779  cur->next = NULL;
2780  }
2781  }
2782 
2783  if (!cur)
2784  return;
2785 
2786  /*free the one remaining list */
2787  if (cur->next) {
2788  g_free (cur->next);
2789  cur->next = NULL;
2790  }
2791 
2792  g_free (cur);
2793  cur = NULL;
2794 }
A css2 page rule.
Definition: cr-statement.h:165
CRSelector * sel_list
A list of instances of #CRSimpeSel.
Definition: cr-statement.h:66
CRStatement * cr_statement_at_media_rule_parse_from_buf(const guchar *a_buf, enum CREncoding a_enc)
cr_statement_at_media_rule_parse_from_buf:
The @page rule abstraction.
Definition: cr-statement.h:115
CRStatement * cr_statement_unlink(CRStatement *a_stmt)
cr_statement_unlink:
CRStatement * cr_statement_new_at_import_rule(CRStyleSheet *a_container_sheet, CRString *a_url, GList *a_media_list, CRStyleSheet *a_imported_sheet)
cr_statement_new_at_import_rule:
A css2 media rule.
Definition: cr-statement.h:162
CRStatement * parent_media_rule
The parent media rule, or NULL if no parent media rule exists.
Definition: cr-statement.h:75
CRDeclaration * decl_list
A list of instances of CRDeclaration.
Definition: cr-statement.h:69
CRAtMediaRule * media_rule
Definition: cr-statement.h:193
union _CRStatement::@1 kind
enum CRStatus cr_parser_parse_ruleset(CRParser *a_this)
cr_parser_parse_ruleset: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:3327
CRAtFontFaceRule * font_face_rule
Definition: cr-statement.h:196
The implementation of the SAC parser.
Definition: cr-parser.h:51
CRStatement * cr_statement_at_media_get_from_list(CRStatement *a_this, int itemnr)
cr_statement_at_media_get_from_list:
Declaration of the CRStatement class.
void cr_statement_dump_page(CRStatement const *a_this, FILE *a_fp, gulong a_indent)
cr_statement_dump_page:
enum CRStatus cr_doc_handler_set_ctxt(CRDocHandler *a_this, gpointer a_ctxt)
cr_doc_handler_set_ctxt: @a_this: the current instance of CRDocHandler @a_ctxt: a pointer to the pars...
#define DECLARATION_INDENT_NB
Definition: cr-statement.c:33
void cr_statement_destroy(CRStatement *a_this)
cr_statement_destroy:
CRStatement * statements
The css statements list.
Definition: cr-stylesheet.h:60
void cr_statement_dump_media_rule(CRStatement const *a_this, FILE *a_fp, gulong a_indent)
cr_statement_dump_media_rule:
CRStatement * cr_statement_prepend(CRStatement *a_this, CRStatement *a_new)
cr_statement_prepend:
void cr_declaration_destroy(CRDeclaration *a_this)
cr_declaration_destroy: @a_this: the current instance of CRDeclaration.
An abstraction of a css stylesheet as defined by the css2 spec in chapter 4.
Definition: cr-stylesheet.h:57
enum CRStatus cr_statement_ruleset_set_decl_list(CRStatement *a_this, CRDeclaration *a_list)
cr_statement_ruleset_set_decl_list:
CRStatement * cr_statement_get_from_list(CRStatement *a_this, int itemnr)
cr_statement_get_from_list:
enum CRStatus cr_statement_at_font_face_rule_set_decls(CRStatement *a_this, CRDeclaration *a_decls)
cr_statement_at_font_face_rule_set_decls:
CRAtPageRule * page_rule
Definition: cr-statement.h:194
enum CRStatus cr_parser_set_sac_handler(CRParser *a_this, CRDocHandler *a_handler)
cr_parser_set_sac_handler: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:2863
enum CRStatus cr_statement_set_parent_sheet(CRStatement *a_this, CRStyleSheet *a_sheet)
cr_statement_set_parent_sheet:
CRStatement * cr_statement_font_face_rule_parse_from_buf(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_font_face_rule_parse_from_buf:
void cr_string_destroy(CRString *a_this)
Definition: cr-string.c:159
CRStatement * cr_statement_parse_from_buf(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_parse_from_buf:
Definition: cr-statement.c:974
GList * media_list
Definition: cr-statement.h:108
A css2 font face rule.
Definition: cr-statement.h:171
enum CRStatus cr_statement_at_import_rule_set_imported_sheet(CRStatement *a_this, CRStyleSheet *a_sheet)
cr_statement_at_import_rule_set_imported_sheet:
CREncoding
Encoding values.
Definition: cr-utils.h:84
gboolean cr_selector_unref(CRSelector *a_this)
cr_selector_unref:
Definition: cr-selector.c:235
enum CRStatus cr_parser_try_to_skip_spaces_and_comments(CRParser *a_this)
cr_parser_try_to_skip_spaces_and_comments: @a_this: the current instance of CRParser.
Definition: cr-parser.c:621
CRDeclaration * decl_list
Definition: cr-statement.h:137
typedefG_BEGIN_DECLS struct _CRSelector CRSelector
Definition: cr-selector.h:40
enum CRStatus cr_doc_handler_get_ctxt(CRDocHandler const *a_this, gpointer *a_ctxt)
cr_doc_handler_get_ctxt: @a_this: the current instance of CRDocHandler.
enum CRStatus cr_doc_handler_set_result(CRDocHandler *a_this, gpointer a_result)
cr_doc_handler_set_result: @a_this: the current instance of CRDocHandler @a_result: the new result.
CRStatus
The status type returned by the methods of the croco library.
Definition: cr-utils.h:43
enum CRStatementType type
The type of the statement.
Definition: cr-statement.h:187
CRStatement * cr_statement_new_at_media_rule(CRStyleSheet *a_sheet, CRStatement *a_rulesets, GList *a_media)
cr_statement_new_at_media_rule:
typedefG_BEGIN_DECLS struct _CRDocHandler CRDocHandler
CRStatement * cr_statement_at_import_rule_parse_from_buf(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_at_import_rule_parse_from_buf:
CRDeclaration * cr_declaration_append(CRDeclaration *a_this, CRDeclaration *a_new)
cr_declaration_append: @a_this: the current declaration list.
gint cr_statement_nr_rules(CRStatement const *a_this)
cr_statement_nr_rules:
GList * cr_utils_dup_glist_of_cr_string(GList const *a_list_of_strings)
Duplicate a GList where the GList::data is a CRString.
Definition: cr-utils.c:1314
CRStatement * cr_statement_at_page_rule_parse_from_buf(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_at_page_rule_parse_from_buf:
void cr_statement_dump_ruleset(CRStatement const *a_this, FILE *a_fp, glong a_indent)
cr_statement_dump_ruleset:
Definition: cr-utils.h:44
CRAtCharsetRule * charset_rule
Definition: cr-statement.h:195
enum CRStatus cr_statement_at_font_face_rule_add_decl(CRStatement *a_this, CRString *a_prop, CRTerm *a_value)
cr_statement_at_font_face_rule_add_decl:
The abstraction of css statement as defined in the chapter 4 and appendix D.1 of the css2 spec.
Definition: cr-statement.h:182
enum CRStatus cr_parser_parse_page(CRParser *a_this)
cr_parser_parse_page: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:3874
gchar * cr_statement_list_to_string(CRStatement const *a_this, gulong a_indent)
enum CRStatus cr_doc_handler_get_result(CRDocHandler const *a_this, gpointer *a_result)
cr_doc_handler_get_result: @a_this: the current instance of CRDocHandler @a_result: out parameter.
guchar * cr_declaration_list_to_string2(CRDeclaration const *a_this, gulong a_indent, gboolean a_one_decl_per_line)
cr_declaration_list_to_string2: @a_this: the current instance of CRDeclaration.
CRString * pseudo
Definition: cr-statement.h:122
gboolean cr_declaration_unref(CRDeclaration *a_this)
cr_declaration_unref: @a_this: the current instance of CRDeclaration.
enum CRStatus cr_statement_at_charset_rule_get_charset(CRStatement const *a_this, CRString **a_charset)
cr_statement_at_charset_rule_get_charset: @a_this: the current @charset rule statement.
gboolean cr_statement_does_buf_parses_against_core(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_does_buf_parses_against_core:
Definition: cr-statement.c:931
gchar * cr_string_dup2(CRString const *a_this)
Definition: cr-string.c:110
CRString * cr_string_dup(CRString const *a_this)
Definition: cr-string.c:94
A css2 charset rule.
Definition: cr-statement.h:168
CRStatement * cr_statement_append(CRStatement *a_this, CRStatement *a_new)
cr_statement_append:
CRRuleSet * ruleset
Definition: cr-statement.h:191
enum CRStatus cr_parser_parse_charset(CRParser *a_this, CRString **a_value, CRParsingLocation *a_charset_sym_location)
cr_parser_parse_charset: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:4125
CRStatement * rulesets
Definition: cr-statement.h:109
CRStatement * cr_statement_at_charset_rule_parse_from_buf(const guchar *a_buf, enum CREncoding a_encoding)
cr_statement_at_charset_rule_parse_from_buf:
int cr_statement_at_media_nr_rules(CRStatement const *a_this)
cr_statement_at_media_nr_rules:
A generic css at-rule each unknown at-rule will be of this type.
Definition: cr-statement.h:153
gboolean cr_doc_handler_unref(CRDocHandler *a_this)
cr_doc_handler_unref: @a_this: the currrent instance of CRDocHandler.
CRParser * cr_parser_new_from_buf(guchar *a_buf, gulong a_len, enum CREncoding a_enc, gboolean a_free_buf)
cr_parser_new_from_buf: @a_buf: the buffer to parse.
Definition: cr-parser.c:2784
void cr_statement_dump_font_face_rule(CRStatement const *a_this, FILE *a_fp, glong a_indent)
cr_statement_dump_font_face_rule:
typedefG_BEGIN_DECLS struct _CRString CRString
Definition: cr-string.h:37
CRDeclaration * cr_declaration_append2(CRDeclaration *a_this, CRString *a_prop, CRTerm *a_value)
cr_declaration_append2: @a_this: the current declaration list.
enum CRStatus cr_parser_parse_statement_core(CRParser *a_this)
cr_parser_parse_statement_core: @a_this: the current instance of CRParser.
Definition: cr-parser.c:3263
void cr_statement_dump(CRStatement const *a_this, FILE *a_fp, gulong a_indent)
cr_statement_dump:
guchar * cr_selector_to_string(CRSelector const *a_this)
Definition: cr-selector.c:141
enum CRStatus cr_statement_at_charset_rule_set_charset(CRStatement *a_this, CRString *a_charset)
cr_statement_at_charset_rule_set_charset:
CRStatement * cr_statement_new_at_font_face_rule(CRStyleSheet *a_sheet, CRDeclaration *a_font_decls)
cr_statement_new_at_font_face_rule:
CRStyleSheet * sheet
the stylesheet fetched from the url, if any.
Definition: cr-statement.h:101
enum CRStatus cr_statement_ruleset_get_sel_list(CRStatement const *a_this, CRSelector **a_list)
cr_statement_ruleset_get_sel_list:
CRString * charset
Definition: cr-statement.h:129
enum CRStatus cr_statement_at_import_rule_get_imported_sheet(CRStatement *a_this, CRStyleSheet **a_sheet)
cr_statement_at_import_rule_get_imported_sheet:
enum CRStatus cr_statement_ruleset_get_declarations(CRStatement *a_this, CRDeclaration **a_decl_list)
cr_statement_ruleset_get_declarations:
The abstraction of a css ruleset.
Definition: cr-statement.h:63
CRDeclaration * cr_declaration_new(CRStatement *a_statement, CRString *a_property, CRTerm *a_value)
cr_declaration_new: @a_statement: the statement this declaration belongs to.
gchar * cr_statement_to_string(CRStatement const *a_this, gulong a_indent)
cr_statement_to_string:
enum CRStatus cr_statement_at_import_rule_get_url(CRStatement const *a_this, CRString **a_url)
cr_statement_at_import_rule_get_url:
An abstraction of a css2 term as defined in the CSS2 spec in appendix D.1: term ::= [ NUMBER S* | PER...
Definition: cr-term.h:82
enum CRStatus cr_statement_get_parent_sheet(CRStatement *a_this, CRStyleSheet **a_sheet)
cr_statement_get_parent_sheet:
void cr_selector_ref(CRSelector *a_this)
cr_selector_ref:
Definition: cr-selector.c:214
CRAtImportRule * import_rule
Definition: cr-statement.h:192
void cr_utils_dump_n_chars2(guchar a_char, GString *a_string, glong a_nb)
Definition: cr-utils.c:1270
enum CRStatus cr_parser_parse_font_face(CRParser *a_this)
cr_parser_parse_font_face: @a_this: the current instance of CRParser.
Definition: cr-parser.c:4216
CRParsingLocation location
Definition: cr-statement.h:215
CRString * url
the url of the import rule
Definition: cr-statement.h:92
enum CRStatus cr_parser_set_use_core_grammar(CRParser *a_this, gboolean a_use_core_grammar)
cr_parser_set_use_core_grammar: @a_this: the current instance of CRParser.
Definition: cr-parser.c:2937
void cr_statement_dump_charset(CRStatement const *a_this, FILE *a_fp, gulong a_indent)
cr_statement_dump_charset:
CRStyleSheet * parent_sheet
Definition: cr-statement.h:211
enum CRStatus cr_statement_at_page_rule_get_declarations(CRStatement *a_this, CRDeclaration **a_decl_list)
cr_statement_at_page_rule_get_declarations:
The declaration file of the CRParser class.
void cr_parser_destroy(CRParser *a_this)
cr_parser_destroy: @a_this: the current instance of CRParser to destroy.
Definition: cr-parser.c:4498
abstraction of an @media rule
Definition: cr-statement.h:106
gboolean important
void cr_statement_dump_import_rule(CRStatement const *a_this, FILE *a_fp, gulong a_indent)
cr_statement_dump_import_rule:
enum CRStatus cr_statement_ruleset_append_decl2(CRStatement *a_this, CRString *a_prop, CRTerm *a_value)
cr_statement_ruleset_append_decl2:
GList * media_list
Definition: cr-statement.h:94
CRStatement * next
Definition: cr-statement.h:212
CRStatement * cr_statement_new_at_charset_rule(CRStyleSheet *a_sheet, CRString *a_charset)
cr_statement_new_at_charset_rule:
enum CRStatus cr_statement_ruleset_append_decl(CRStatement *a_this, CRDeclaration *a_decl)
cr_statement_ruleset_append_decl:
CRStatement * cr_statement_new_ruleset(CRStyleSheet *a_sheet, CRSelector *a_sel_list, CRDeclaration *a_decl_list, CRStatement *a_parent_media_rule)
cr_statement_new_ruleset:
A css2 import rule.
Definition: cr-statement.h:159
enum CRStatus cr_parsing_location_copy(CRParsingLocation *a_to, CRParsingLocation const *a_from)
cr_parsing_location_copy: @a_to: the destination of the copy.
void cr_declaration_ref(CRDeclaration *a_this)
cr_declaration_ref: @a_this: the current instance of CRDeclaration.
enum CRStatus cr_parser_parse_media(CRParser *a_this)
cr_parser_parse_media: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:3704
enum CRStatus cr_parser_parse_import(CRParser *a_this, GList **a_media_list, CRString **a_import_string, CRParsingLocation *a_location)
cr_parser_parse_import: @a_this: the "this pointer" of the current instance of CRParser.
Definition: cr-parser.c:3543
enum CRStatus cr_statement_ruleset_set_sel_list(CRStatement *a_this, CRSelector *a_sel_list)
cr_statement_ruleset_set_sel_list:
enum CRStatus cr_statement_at_font_face_rule_get_decls(CRStatement *a_this, CRDeclaration **a_decls)
cr_statement_at_font_face_rule_get_decls:
CRString * name
page selector.
Definition: cr-statement.h:121
enum CRStatus cr_statement_at_page_rule_set_declarations(CRStatement *a_this, CRDeclaration *a_decl_list)
cr_statement_at_page_rule_set_declarations:
CRDeclaration * decl_list
a list of instances of CRDeclaration
Definition: cr-statement.h:118
CRStatement * cr_statement_ruleset_parse_from_buf(const guchar *a_buf, enum CREncoding a_enc)
cr_statement_ruleset_parse_from_buf:
CRStatement * prev
Definition: cr-statement.h:213
CRDocHandler * cr_doc_handler_new(void)
cr_doc_handler_new: Constructor of CRDocHandler.
#define cr_utils_trace_info(a_msg)
Traces an info message.
Definition: cr-utils.h:127
CRStatement * cr_statement_new_at_page_rule(CRStyleSheet *a_sheet, CRDeclaration *a_decl_list, CRString *a_name, CRString *a_pseudo)
cr_statement_new_at_page_rule:
enum CRStatus cr_statement_at_import_rule_set_url(CRStatement *a_this, CRString *a_url)
cr_statement_at_import_rule_set_url: