00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <string.h>
00028 #include "cr-statement.h"
00029 #include "cr-parser.h"
00030
00031
00032
00033
00034
00035
00036 #define DECLARATION_INDENT_NB 2
00037
00038 static void
00039 cr_statement_clear (CRStatement *a_this) ;
00040
00041 static void
00042 cr_statement_dump_ruleset (CRStatement *a_this, FILE *a_fp, glong a_indent) ;
00043
00044 static void
00045 cr_statement_dump_charset (CRStatement *a_this, FILE *a_fp,
00046 gulong a_indent) ;
00047
00048 static void
00049 cr_statement_dump_page (CRStatement *a_this, FILE *a_fp, gulong a_indent) ;
00050
00051 static void
00052 cr_statement_dump_media_rule (CRStatement *a_this, FILE *a_fp,
00053 gulong a_indent) ;
00054
00055 static void
00056 cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp,
00057 gulong a_indent) ;
00058
00059 static void
00060 parse_font_face_start_font_face_cb (CRDocHandler *a_this)
00061 {
00062 CRStatement *stmt = NULL ;
00063 enum CRStatus status = CR_OK ;
00064
00065 stmt = cr_statement_new_at_font_face_rule (NULL,
00066 NULL) ;
00067 g_return_if_fail (stmt) ;
00068
00069 status = cr_doc_handler_set_ctxt (a_this, stmt) ;
00070 g_return_if_fail (status == CR_OK) ;
00071 }
00072
00073 static void
00074 parse_font_face_unrecoverable_error_cb (CRDocHandler *a_this)
00075 {
00076 CRStatement *stmt = NULL ;
00077 enum CRStatus status = CR_OK ;
00078
00079 g_return_if_fail (a_this) ;
00080
00081 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00082 if (status != CR_OK)
00083 {
00084 cr_utils_trace_info ("Couldn't get parsing context. "
00085 "This may lead to some memory leaks.") ;
00086 return ;
00087 }
00088 if (stmt)
00089 {
00090 cr_statement_destroy (stmt) ;
00091 cr_doc_handler_set_ctxt (a_this, NULL) ;
00092 return ;
00093 }
00094 }
00095
00096 static void
00097 parse_font_face_property_cb (CRDocHandler *a_this,
00098 GString *a_name,
00099 CRTerm *a_value)
00100 {
00101 enum CRStatus status = CR_OK ;
00102 GString *name = NULL ;
00103 CRDeclaration *decl = NULL ;
00104 CRStatement *stmt = NULL ;
00105
00106 g_return_if_fail (a_this && a_name) ;
00107
00108 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00109 g_return_if_fail (status == CR_OK && stmt) ;
00110 g_return_if_fail (stmt->type == AT_FONT_FACE_RULE_STMT) ;
00111
00112 name = g_string_new_len (a_name->str, a_name->len) ;
00113 g_return_if_fail (name) ;
00114 decl = cr_declaration_new (stmt, name, a_value) ;
00115 if (!decl)
00116 {
00117 cr_utils_trace_info ("cr_declaration_new () failed.") ;
00118 goto error ;
00119 }
00120 name = NULL ;
00121
00122 stmt->kind.font_face_rule->decl_list =
00123 cr_declaration_append (stmt->kind.font_face_rule->decl_list,
00124 decl) ;
00125 if (!stmt->kind.font_face_rule->decl_list)
00126 goto error ;
00127 decl = NULL ;
00128
00129 error:
00130 if (decl)
00131 {
00132 cr_declaration_unref (decl) ;
00133 decl = NULL ;
00134 }
00135 if (name)
00136 {
00137 g_string_free (name, TRUE) ;
00138 name = NULL ;
00139 }
00140 }
00141
00142 static void
00143 parse_font_face_end_font_face_cb (CRDocHandler *a_this)
00144
00145 {
00146 CRStatement *result = NULL ;
00147 enum CRStatus status = CR_OK ;
00148
00149 g_return_if_fail (a_this) ;
00150
00151 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&result) ;
00152 g_return_if_fail (status == CR_OK && result) ;
00153 g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT) ;
00154
00155 status = cr_doc_handler_set_result (a_this, result) ;
00156 g_return_if_fail (status == CR_OK) ;
00157 }
00158
00159 static void
00160 parse_page_start_page_cb (CRDocHandler *a_this,
00161 GString *a_name,
00162 GString *a_pseudo_page)
00163 {
00164 CRStatement *stmt = NULL ;
00165 enum CRStatus status = CR_OK ;
00166
00167 stmt = cr_statement_new_at_page_rule (NULL, NULL, a_name,
00168 a_pseudo_page) ;
00169 g_return_if_fail (stmt) ;
00170 status = cr_doc_handler_set_ctxt (a_this, stmt) ;
00171 g_return_if_fail (status == CR_OK) ;
00172 }
00173
00174 static void
00175 parse_page_unrecoverable_error_cb (CRDocHandler *a_this)
00176 {
00177 CRStatement *stmt = NULL ;
00178 enum CRStatus status = CR_OK ;
00179
00180 g_return_if_fail (a_this) ;
00181
00182 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00183 if (status != CR_OK)
00184 {
00185 cr_utils_trace_info ("Couldn't get parsing context. "
00186 "This may lead to some memory leaks.") ;
00187 return ;
00188 }
00189 if (stmt)
00190 {
00191 cr_statement_destroy (stmt) ;
00192 stmt = NULL ;
00193 cr_doc_handler_set_ctxt (a_this, NULL) ;
00194 }
00195 }
00196
00197 static void
00198 parse_page_property_cb (CRDocHandler *a_this,
00199 GString *a_name,
00200 CRTerm *a_expression)
00201 {
00202 GString *name = NULL ;
00203 CRStatement *stmt = NULL ;
00204 CRDeclaration *decl = NULL ;
00205 enum CRStatus status = CR_OK ;
00206
00207 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00208 g_return_if_fail (status == CR_OK && stmt->type == AT_PAGE_RULE_STMT) ;
00209
00210 name = g_string_new_len (a_name->str, a_name->len) ;
00211 g_return_if_fail (name) ;
00212
00213 decl = cr_declaration_new (stmt, name, a_expression) ;
00214 g_return_if_fail (decl) ;
00215
00216 stmt->kind.page_rule->decl_list =
00217 cr_declaration_append (stmt->kind.page_rule->decl_list,
00218 decl) ;
00219 g_return_if_fail (stmt->kind.page_rule->decl_list) ;
00220 }
00221
00222 static void
00223 parse_page_end_page_cb (CRDocHandler *a_this,
00224 GString *a_name,
00225 GString *a_pseudo_page)
00226 {
00227 enum CRStatus status = CR_OK ;
00228 CRStatement *stmt = NULL ;
00229
00230 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00231 g_return_if_fail (status == CR_OK && stmt);
00232 g_return_if_fail (stmt->type == AT_PAGE_RULE_STMT);
00233
00234 status = cr_doc_handler_set_result (a_this, stmt) ;
00235 g_return_if_fail (status == CR_OK) ;
00236 }
00237
00238 static void
00239 parse_at_media_start_media_cb (CRDocHandler *a_this,
00240 GList *a_media_list)
00241 {
00242 enum CRStatus status = CR_OK ;
00243 CRStatement *at_media = NULL ;
00244 GList *media_list = NULL ;
00245
00246 g_return_if_fail (a_this && a_this->priv) ;
00247
00248 if (a_media_list)
00249 {
00250
00251 media_list = cr_dup_glist_of_string (a_media_list) ;
00252 }
00253
00254 g_return_if_fail (media_list) ;
00255
00256
00257 at_media = cr_statement_new_at_media_rule (NULL, NULL,
00258 media_list) ;
00259
00260 status = cr_doc_handler_set_ctxt (a_this, at_media) ;
00261 g_return_if_fail (status == CR_OK) ;
00262 status = cr_doc_handler_set_result (a_this, at_media) ;
00263 g_return_if_fail (status == CR_OK) ;
00264 }
00265
00266 static void
00267 parse_at_media_unrecoverable_error_cb (CRDocHandler *a_this)
00268 {
00269 enum CRStatus status = CR_OK ;
00270 CRStatement * stmt = NULL ;
00271
00272 g_return_if_fail (a_this) ;
00273
00274 status = cr_doc_handler_get_result (a_this, (gpointer*)&stmt) ;
00275 if (status != CR_OK)
00276 {
00277 cr_utils_trace_info ("Couldn't get parsing context. "
00278 "This may lead to some memory leaks.") ;
00279 return ;
00280 }
00281 if (stmt)
00282 {
00283 cr_statement_destroy (stmt) ;
00284 stmt = NULL ;
00285 cr_doc_handler_set_ctxt (a_this, NULL) ;
00286 cr_doc_handler_set_result (a_this, NULL) ;
00287 }
00288 }
00289
00290 static void
00291 parse_at_media_start_selector_cb (CRDocHandler *a_this,
00292 CRSelector *a_sellist)
00293 {
00294 enum CRStatus status = CR_OK ;
00295 CRStatement *at_media = NULL, *ruleset = NULL ;
00296
00297 g_return_if_fail (a_this
00298 && a_this->priv
00299 && a_sellist) ;
00300
00301 status = cr_doc_handler_get_ctxt (a_this,
00302 (gpointer*)&at_media) ;
00303 g_return_if_fail (status == CR_OK && at_media) ;
00304 g_return_if_fail (at_media->type == AT_MEDIA_RULE_STMT) ;
00305 ruleset = cr_statement_new_ruleset (NULL, a_sellist,
00306 NULL, at_media) ;
00307 g_return_if_fail (ruleset) ;
00308 status = cr_doc_handler_set_ctxt (a_this, ruleset) ;
00309 g_return_if_fail (status == CR_OK) ;
00310 }
00311
00312 static void
00313 parse_at_media_property_cb (CRDocHandler *a_this,
00314 GString *a_name, CRTerm *a_value)
00315 {
00316 enum CRStatus status = CR_OK ;
00317
00318
00319
00320
00321 CRStatement *stmt = NULL;
00322 GString *name = NULL ;
00323
00324 g_return_if_fail (a_this && a_name) ;
00325
00326 name = g_string_new_len (a_name->str, a_name->len) ;
00327 g_return_if_fail (name) ;
00328
00329 status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ;
00330 g_return_if_fail (status == CR_OK && stmt) ;
00331 g_return_if_fail (stmt->type == RULESET_STMT) ;
00332
00333 status = cr_statement_ruleset_append_decl2
00334 (stmt, name, a_value) ;
00335 g_return_if_fail (status == CR_OK) ;
00336
00337
00338 }
00339
00340 static void
00341 parse_at_media_end_selector_cb (CRDocHandler *a_this,
00342 CRSelector *a_sellist)
00343 {
00344 enum CRStatus status = CR_OK ;
00345
00346
00347
00348
00349 CRStatement *stmt = NULL ;
00350
00351 g_return_if_fail (a_this && a_sellist) ;
00352
00353 status = cr_doc_handler_get_ctxt (a_this,
00354 (gpointer *)&stmt) ;
00355 g_return_if_fail (status == CR_OK && stmt
00356 && stmt->type == RULESET_STMT) ;
00357 g_return_if_fail (stmt->kind.ruleset->parent_media_rule) ;
00358
00359 status = cr_doc_handler_set_ctxt
00360 (a_this,
00361 stmt->kind.ruleset->parent_media_rule) ;
00362 g_return_if_fail (status == CR_OK) ;
00363 }
00364
00365 static void
00366 parse_at_media_end_media_cb (CRDocHandler *a_this,
00367 GList *a_media_list)
00368 {
00369 enum CRStatus status = CR_OK ;
00370 CRStatement *at_media = NULL ;
00371 g_return_if_fail (a_this && a_this->priv) ;
00372
00373 status = cr_doc_handler_get_ctxt (a_this,
00374 (gpointer*)&at_media) ;
00375 g_return_if_fail (status == CR_OK && at_media) ;
00376
00377 status = cr_doc_handler_set_result (a_this, at_media) ;
00378 }
00379
00380
00381 static void
00382 parse_ruleset_start_selector_cb (CRDocHandler *a_this,
00383 CRSelector *a_sellist)
00384 {
00385 CRStatement *ruleset = NULL ;
00386
00387 g_return_if_fail (a_this
00388 && a_this->priv
00389 && a_sellist) ;
00390
00391 ruleset = cr_statement_new_ruleset (NULL, a_sellist,
00392 NULL, NULL) ;
00393 g_return_if_fail (ruleset) ;
00394
00395 cr_doc_handler_set_result (a_this, ruleset) ;
00396 }
00397
00398 static void
00399 parse_ruleset_unrecoverable_error_cb (CRDocHandler *a_this)
00400 {
00401 CRStatement *stmt = NULL ;
00402 enum CRStatus status = CR_OK ;
00403
00404 status = cr_doc_handler_get_result (a_this, (gpointer*)&stmt) ;
00405 if (status != CR_OK)
00406 {
00407 cr_utils_trace_info ("Couldn't get parsing context. "
00408 "This may lead to some memory leaks.") ;
00409 return ;
00410 }
00411 if (stmt)
00412 {
00413 cr_statement_destroy (stmt) ;
00414 stmt = NULL ;
00415 cr_doc_handler_set_result (a_this, NULL) ;
00416 }
00417 }
00418
00419 static void
00420 parse_ruleset_property_cb (CRDocHandler *a_this,
00421 GString *a_name, CRTerm *a_value)
00422 {
00423 enum CRStatus status = CR_OK ;
00424 CRStatement *ruleset = NULL ;
00425 GString * stringue = NULL ;
00426
00427 g_return_if_fail (a_this && a_this->priv && a_name) ;
00428
00429 stringue = g_string_new (a_name->str) ;
00430 g_return_if_fail (stringue) ;
00431
00432 status = cr_doc_handler_get_result (a_this, (gpointer *)&ruleset) ;
00433 g_return_if_fail (status == CR_OK
00434 && ruleset && ruleset->type == RULESET_STMT) ;
00435
00436 status = cr_statement_ruleset_append_decl2
00437 (ruleset, stringue, a_value) ;
00438 g_return_if_fail (status == CR_OK) ;
00439 }
00440
00441 static void
00442 parse_ruleset_end_selector_cb (CRDocHandler *a_this,
00443 CRSelector *a_sellist)
00444 {
00445 CRStatement *result = NULL ;
00446 enum CRStatus status = CR_OK ;
00447
00448 g_return_if_fail (a_this && a_sellist) ;
00449
00450 status = cr_doc_handler_get_result (a_this, (gpointer *)&result) ;
00451
00452 g_return_if_fail (status == CR_OK
00453 && result
00454 && result->type == RULESET_STMT) ;
00455 }
00456
00457 static void
00458 cr_statement_clear (CRStatement *a_this)
00459 {
00460 g_return_if_fail (a_this) ;
00461
00462 switch (a_this->type)
00463 {
00464 case AT_RULE_STMT:
00465 break ;
00466 case RULESET_STMT:
00467 if (!a_this->kind.ruleset)
00468 return ;
00469 if (a_this->kind.ruleset->sel_list)
00470 {
00471 cr_selector_unref
00472 (a_this->kind.ruleset->sel_list) ;
00473 a_this->kind.ruleset->sel_list = NULL ;
00474 }
00475 if (a_this->kind.ruleset->decl_list)
00476 {
00477 cr_declaration_destroy
00478 (a_this->kind.ruleset->decl_list) ;
00479 a_this->kind.ruleset->decl_list = NULL ;
00480 }
00481 g_free (a_this->kind.ruleset) ;
00482 a_this->kind.ruleset = NULL ;
00483 break ;
00484
00485 case AT_IMPORT_RULE_STMT:
00486 if (!a_this->kind.import_rule)
00487 return ;
00488 if (a_this->kind.import_rule->url)
00489 {
00490 g_string_free
00491 (a_this->kind.import_rule->url,
00492 TRUE) ;
00493 a_this->kind.import_rule->url = NULL ;
00494 }
00495 g_free (a_this->kind.import_rule) ;
00496 a_this->kind.import_rule = NULL ;
00497 break ;
00498
00499 case AT_MEDIA_RULE_STMT:
00500 if (!a_this->kind.media_rule)
00501 return;
00502 if (a_this->kind.media_rule->rulesets)
00503 {
00504 cr_statement_destroy
00505 (a_this->kind.media_rule->rulesets) ;
00506 a_this->kind.media_rule->rulesets = NULL ;
00507 }
00508 if (a_this->kind.media_rule->media_list)
00509 {
00510 GList *cur = NULL ;
00511
00512 for (cur = a_this->kind.media_rule->media_list;
00513 cur ; cur = cur->next)
00514 {
00515 if (cur->data)
00516 {
00517 g_string_free ((GString*)cur->data,
00518 TRUE) ;
00519 cur->data = NULL ;
00520 }
00521
00522 }
00523 g_list_free
00524 (a_this->kind.media_rule->media_list) ;
00525 a_this->kind.media_rule->media_list = NULL ;
00526 }
00527 g_free (a_this->kind.media_rule) ;
00528 a_this->kind.media_rule = NULL ;
00529 break ;
00530
00531 case AT_PAGE_RULE_STMT:
00532 if (!a_this->kind.page_rule)
00533 return ;
00534
00535 if (a_this->kind.page_rule->decl_list)
00536 {
00537 cr_declaration_destroy
00538 (a_this->kind.page_rule->decl_list) ;
00539 a_this->kind.page_rule->decl_list = NULL ;
00540 }
00541 if (a_this->kind.page_rule->name)
00542 {
00543 g_string_free (a_this->kind.page_rule->name,
00544 TRUE) ;
00545 a_this->kind.page_rule->name = NULL ;
00546 }
00547 if (a_this->kind.page_rule->pseudo)
00548 {
00549 g_string_free (a_this->kind.page_rule->pseudo,
00550 TRUE) ;
00551 a_this->kind.page_rule->pseudo = NULL ;
00552 }
00553
00554 g_free (a_this->kind.page_rule) ;
00555 a_this->kind.page_rule = NULL ;
00556 break ;
00557
00558 case AT_CHARSET_RULE_STMT:
00559 if (!a_this->kind.charset_rule)
00560 return ;
00561
00562 if (a_this->kind.charset_rule->charset)
00563 {
00564 g_string_free
00565 (a_this->kind.charset_rule->charset,
00566 TRUE) ;
00567 a_this->kind.charset_rule->charset = NULL ;
00568 }
00569 g_free (a_this->kind.charset_rule) ;
00570 a_this->kind.charset_rule = NULL;
00571 break ;
00572
00573 case AT_FONT_FACE_RULE_STMT:
00574 if (!a_this->kind.font_face_rule)
00575 return ;
00576
00577 if (a_this->kind.font_face_rule->decl_list)
00578 {
00579 cr_declaration_unref
00580 (a_this->kind.font_face_rule->decl_list);
00581 a_this->kind.font_face_rule->decl_list = NULL ;
00582 }
00583 g_free (a_this->kind.font_face_rule) ;
00584 a_this->kind.font_face_rule = NULL ;
00585 break ;
00586
00587 default:
00588 break ;
00589 }
00590 }
00591
00592
00593
00594
00595
00596
00597
00598 static void
00599 cr_statement_dump_ruleset (CRStatement *a_this, FILE *a_fp, glong a_indent)
00600 {
00601 guchar *str = NULL, *tmp_str = NULL ;
00602
00603 g_return_if_fail (a_this && a_this->type == RULESET_STMT) ;
00604
00605 if (a_this->kind.ruleset->sel_list)
00606 {
00607 if (a_indent)
00608 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00609
00610 cr_selector_dump (a_this->kind.ruleset->sel_list, a_fp) ;
00611 }
00612
00613 if (a_this->kind.ruleset->decl_list)
00614 {
00615 fprintf (a_fp," {\n") ;
00616 cr_declaration_dump (a_this->kind.ruleset->decl_list,
00617 a_fp, a_indent + DECLARATION_INDENT_NB,
00618 TRUE) ;
00619 fprintf (a_fp,"\n") ;
00620 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00621 fprintf (a_fp,"}") ;
00622 }
00623
00624 if (str)
00625 {
00626 g_free (str) ;
00627 str = NULL ;
00628 }
00629 if (tmp_str)
00630 {
00631 g_free (tmp_str) ;
00632 tmp_str = NULL ;
00633 }
00634 }
00635
00636
00637
00638
00639
00640
00641
00642 static void
00643 cr_statement_dump_font_face_rule (CRStatement *a_this , FILE *a_fp,
00644 glong a_indent)
00645 {
00646 g_return_if_fail (a_this
00647 && a_this->type == AT_FONT_FACE_RULE_STMT) ;
00648
00649 if (a_this->kind.font_face_rule->decl_list)
00650 {
00651 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00652
00653 if (a_indent)
00654 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00655
00656 fprintf (a_fp,"@font-face {\n") ;
00657 cr_declaration_dump
00658 (a_this->kind.font_face_rule->decl_list,
00659 a_fp, a_indent + DECLARATION_INDENT_NB, TRUE) ;
00660 fprintf (a_fp,"\n}") ;
00661 }
00662 }
00663
00664
00665
00666
00667
00668
00669
00670 static void
00671 cr_statement_dump_charset (CRStatement *a_this, FILE *a_fp,
00672 gulong a_indent)
00673 {
00674 guchar *str = NULL ;
00675
00676 g_return_if_fail (a_this
00677 && a_this->type == AT_CHARSET_RULE_STMT) ;
00678
00679 if (a_this->kind.charset_rule
00680 && a_this->kind.charset_rule->charset)
00681 {
00682 str = g_strndup (a_this->kind.charset_rule->charset->str,
00683 a_this->kind.charset_rule->charset->len) ;
00684
00685 g_return_if_fail (str) ;
00686
00687 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00688 fprintf (a_fp,"@charset \"%s\" ;", str) ;
00689 if (str)
00690 {
00691 g_free (str) ;
00692 str = NULL;
00693 }
00694 }
00695 }
00696
00697
00698
00699
00700
00701
00702
00703 static void
00704 cr_statement_dump_page (CRStatement *a_this, FILE *a_fp, gulong a_indent)
00705 {
00706 guchar *str = NULL ;
00707
00708 g_return_if_fail (a_this
00709 && a_this->type == AT_PAGE_RULE_STMT
00710 && a_this->kind.page_rule) ;
00711
00712 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00713 fprintf (a_fp,"@page") ;
00714
00715 if (a_this->kind.page_rule->name)
00716 {
00717 str = g_strndup (a_this->kind.page_rule->name->str,
00718 a_this->kind.page_rule->name->len) ;
00719 g_return_if_fail (str) ;
00720 fprintf (a_fp," %s", str) ;
00721 if (str)
00722 {
00723 g_free (str) ;
00724 str = NULL ;
00725 }
00726 }
00727 else
00728 {
00729 fprintf (a_fp," ") ;
00730 }
00731
00732 if (a_this->kind.page_rule->pseudo)
00733 {
00734 str = g_strndup (a_this->kind.page_rule->pseudo->str,
00735 a_this->kind.page_rule->pseudo->len) ;
00736 g_return_if_fail (str) ;
00737 fprintf (a_fp,":%s", str) ;
00738 if (str)
00739 {
00740 g_free (str) ;
00741 str = NULL ;
00742 }
00743 }
00744
00745 if (a_this->kind.page_rule->decl_list)
00746 {
00747 fprintf (a_fp," {\n") ;
00748 cr_declaration_dump
00749 (a_this->kind.page_rule->decl_list,
00750 a_fp, a_indent + DECLARATION_INDENT_NB, TRUE) ;
00751 fprintf (a_fp,"\n}\n") ;
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 static void
00762 cr_statement_dump_media_rule (CRStatement *a_this, FILE *a_fp,
00763 gulong a_indent)
00764 {
00765 GList *cur = NULL ;
00766
00767 g_return_if_fail (a_this->type == AT_MEDIA_RULE_STMT) ;
00768
00769 if (a_this->kind.media_rule)
00770 {
00771 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00772 fprintf (a_fp,"@media") ;
00773 for (cur = a_this->kind.media_rule->media_list ; cur ;
00774 cur = cur->next)
00775 {
00776 if (cur->data)
00777 {
00778 guchar *str = g_strndup
00779 (((GString*)cur->data)->str,
00780 ((GString*)cur->data)->len) ;
00781 if (str)
00782 {
00783 if (cur->prev)
00784 {
00785 fprintf (a_fp,",") ;
00786 }
00787 fprintf (a_fp," %s", str) ;
00788 g_free (str) ; str = NULL ;
00789 }
00790 }
00791 }
00792 fprintf (a_fp," {\n") ;
00793 cr_statement_dump (a_this->kind.media_rule->rulesets,
00794 a_fp, a_indent + DECLARATION_INDENT_NB) ;
00795 fprintf (a_fp,"\n}") ;
00796 }
00797 }
00798
00799
00800
00801
00802
00803
00804 static void
00805 cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp,
00806 gulong a_indent)
00807 {
00808 g_return_if_fail (a_this
00809 && a_this->type == AT_IMPORT_RULE_STMT
00810 && a_this->kind.import_rule) ;
00811
00812 if (a_this->kind.import_rule->url)
00813 {
00814 guchar *str = NULL ;
00815
00816 str = g_strndup (a_this->kind.import_rule->url->str,
00817 a_this->kind.import_rule->url->len) ;
00818 cr_utils_dump_n_chars (' ', a_fp, a_indent) ;
00819
00820 if (str)
00821 {
00822 fprintf (a_fp,"@import url(\"%s\")", str) ;
00823 g_free (str) ;
00824 }
00825 else
00826 return ;
00827
00828 if (a_this->kind.import_rule->media_list)
00829 {
00830 GList *cur = NULL ;
00831
00832 for (cur = a_this->kind.import_rule->media_list ;
00833 cur; cur = cur->next)
00834 {
00835 if (cur->data)
00836 {
00837 GString *gstr = cur->data ;
00838
00839 if (cur->prev)
00840 {
00841 fprintf (a_fp,", ") ;
00842 }
00843
00844 str = g_strndup (gstr->str,
00845 gstr->len) ;
00846 if (str)
00847 {
00848 fprintf (a_fp,str) ;
00849 g_free (str) ;
00850 }
00851 }
00852 }
00853 fprintf (a_fp," ;") ;
00854 }
00855 }
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 gboolean
00872 cr_statement_does_buf_parses_against_core (const guchar *a_buf,
00873 enum CREncoding a_encoding)
00874 {
00875 CRParser *parser = NULL ;
00876 enum CRStatus status = CR_OK ;
00877 gboolean result = FALSE ;
00878
00879 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
00880 a_encoding, FALSE) ;
00881 g_return_val_if_fail (parser, FALSE) ;
00882
00883 status = cr_parser_set_use_core_grammar (parser, TRUE) ;
00884 if (status != CR_OK)
00885 {
00886 goto cleanup ;
00887 }
00888
00889 status = cr_parser_parse_statement_core (parser) ;
00890 if (status == CR_OK)
00891 {
00892 result = TRUE ;
00893 }
00894
00895 cleanup:
00896 if (parser)
00897 {
00898 cr_parser_destroy (parser) ;
00899 }
00900
00901 return result ;
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 CRStatement *
00914 cr_statement_parse_from_buf (const guchar *a_buf,
00915 enum CREncoding a_encoding)
00916 {
00917 CRStatement *result = NULL ;
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding) ;
00928 if (!result)
00929 {
00930 result = cr_statement_at_charset_rule_parse_from_buf
00931 (a_buf, a_encoding) ;
00932 }
00933 else
00934 {
00935 goto out ;
00936 }
00937
00938 if (!result)
00939 {
00940 result = cr_statement_at_media_rule_parse_from_buf
00941 (a_buf, a_encoding) ;
00942 }
00943 else
00944 {
00945 goto out ;
00946 }
00947
00948 if (!result)
00949 {
00950 result = cr_statement_at_charset_rule_parse_from_buf
00951 (a_buf, a_encoding) ;
00952 }
00953 else
00954 {
00955 goto out ;
00956 }
00957
00958 if (!result)
00959 {
00960 result = cr_statement_font_face_rule_parse_from_buf
00961 (a_buf, a_encoding) ;
00962
00963 }
00964 else
00965 {
00966 goto out ;
00967 }
00968
00969 if (!result)
00970 {
00971 result = cr_statement_at_page_rule_parse_from_buf
00972 (a_buf, a_encoding) ;
00973 }
00974 else
00975 {
00976 goto out ;
00977 }
00978
00979 if (!result)
00980 {
00981 result = cr_statement_at_import_rule_parse_from_buf
00982 (a_buf, a_encoding) ;
00983 }
00984 else
00985 {
00986 goto out ;
00987 }
00988
00989 out:
00990 return result ;
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 CRStatement *
01002 cr_statement_ruleset_parse_from_buf (const guchar * a_buf,
01003 enum CREncoding a_enc)
01004 {
01005 enum CRStatus status = CR_OK ;
01006 CRStatement *result = NULL;
01007 CRParser *parser = NULL ;
01008 CRDocHandler *sac_handler = NULL ;
01009
01010 g_return_val_if_fail (a_buf, NULL) ;
01011
01012 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01013 a_enc, FALSE) ;
01014
01015 g_return_val_if_fail (parser, NULL) ;
01016
01017 sac_handler = cr_doc_handler_new () ;
01018 g_return_val_if_fail (parser, NULL) ;
01019
01020 sac_handler->start_selector = parse_ruleset_start_selector_cb ;
01021 sac_handler->end_selector = parse_ruleset_end_selector_cb ;
01022 sac_handler->property = parse_ruleset_property_cb ;
01023 sac_handler->unrecoverable_error =
01024 parse_ruleset_unrecoverable_error_cb ;
01025
01026 cr_parser_set_sac_handler (parser, sac_handler) ;
01027 cr_parser_try_to_skip_spaces_and_comments (parser) ;
01028 status = cr_parser_parse_ruleset (parser) ;
01029 if (status != CR_OK)
01030 {
01031 goto cleanup ;
01032 }
01033
01034 status = cr_doc_handler_get_result (sac_handler,
01035 (gpointer*)&result) ;
01036 if (! ((status == CR_OK) && result) )
01037 {
01038 if (result)
01039 {
01040 cr_statement_destroy (result) ;
01041 result = NULL ;
01042 }
01043 }
01044
01045 cleanup:
01046 if (parser)
01047 {
01048 cr_parser_destroy (parser) ;
01049 parser = NULL ;
01050 }
01051 if (sac_handler)
01052 {
01053 cr_doc_handler_unref (sac_handler) ;
01054 sac_handler = NULL ;
01055 }
01056 return result ;
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 CRStatement*
01072 cr_statement_new_ruleset (CRStyleSheet * a_sheet,
01073 CRSelector *a_sel_list,
01074 CRDeclaration *a_decl_list,
01075 CRStatement *a_parent_media_rule)
01076 {
01077 CRStatement *result = NULL ;
01078
01079 g_return_val_if_fail (a_sel_list, NULL) ;
01080
01081 if (a_parent_media_rule)
01082 {
01083 g_return_val_if_fail
01084 (a_parent_media_rule->type == AT_MEDIA_RULE_STMT,
01085 NULL) ;
01086 g_return_val_if_fail (a_parent_media_rule->kind.media_rule,
01087 NULL) ;
01088 }
01089
01090 result = g_try_malloc (sizeof (CRStatement)) ;
01091
01092 if (!result)
01093 {
01094 cr_utils_trace_info ("Out of memory") ;
01095 return NULL ;
01096 }
01097
01098 memset (result, 0, sizeof (CRStatement)) ;
01099 result->type = RULESET_STMT ;
01100 result->kind.ruleset = g_try_malloc (sizeof (CRRuleSet)) ;
01101
01102 if (!result->kind.ruleset)
01103 {
01104 cr_utils_trace_info ("Out of memory") ;
01105 if (result) g_free (result) ;
01106 return NULL ;
01107 }
01108
01109 memset (result->kind.ruleset, 0, sizeof (CRRuleSet)) ;
01110 result->kind.ruleset->sel_list = a_sel_list;
01111 if (a_sel_list)
01112 cr_selector_ref (a_sel_list) ;
01113 result->kind.ruleset->decl_list = a_decl_list;
01114
01115 if (a_parent_media_rule)
01116 {
01117 result->kind.ruleset->parent_media_rule =
01118 a_parent_media_rule;
01119 a_parent_media_rule->kind.media_rule->rulesets =
01120 cr_statement_append
01121 (a_parent_media_rule->kind.media_rule->rulesets,
01122 result) ;
01123 }
01124
01125
01126 cr_statement_set_parent_sheet (result, a_sheet) ;
01127
01128 return result ;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 CRStatement *
01140 cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf,
01141 enum CREncoding a_enc)
01142 {
01143 CRParser *parser = NULL ;
01144 CRStatement *result = NULL ;
01145 CRDocHandler *sac_handler = NULL ;
01146 enum CRStatus status = CR_OK ;
01147
01148 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01149 a_enc, FALSE) ;
01150 if (!parser)
01151 {
01152 cr_utils_trace_info ("Instanciation of the parser failed") ;
01153 goto cleanup ;
01154 }
01155
01156 sac_handler = cr_doc_handler_new () ;
01157 if (!sac_handler)
01158 {
01159 cr_utils_trace_info ("Instanciation of the sac handler failed") ;
01160 goto cleanup ;
01161 }
01162
01163 sac_handler->start_media =
01164 parse_at_media_start_media_cb ;
01165 sac_handler->start_selector =
01166 parse_at_media_start_selector_cb ;
01167 sac_handler->property =
01168 parse_at_media_property_cb ;
01169 sac_handler->end_selector =
01170 parse_at_media_end_selector_cb ;
01171 sac_handler->end_media =
01172 parse_at_media_end_media_cb ;
01173 sac_handler->unrecoverable_error =
01174 parse_at_media_unrecoverable_error_cb ;
01175
01176 status = cr_parser_set_sac_handler (parser, sac_handler) ;
01177 if (status != CR_OK)
01178 goto cleanup ;
01179
01180 status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
01181 if (status != CR_OK)
01182 goto cleanup ;
01183
01184 status = cr_parser_parse_media (parser) ;
01185 if (status != CR_OK)
01186 goto cleanup ;
01187
01188 status = cr_doc_handler_get_result (sac_handler,
01189 (gpointer*)&result) ;
01190 if (status != CR_OK)
01191 goto cleanup ;
01192
01193
01194 cleanup:
01195
01196 if (parser)
01197 {
01198 cr_parser_destroy (parser) ;
01199 parser = NULL ;
01200 }
01201 if (sac_handler)
01202 {
01203 cr_doc_handler_unref (sac_handler) ;
01204 sac_handler = NULL ;
01205 }
01206
01207 return result ;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217 CRStatement *
01218 cr_statement_new_at_media_rule (CRStyleSheet *a_sheet,
01219 CRStatement *a_rulesets,
01220 GList *a_media)
01221 {
01222 CRStatement *result = NULL, *cur = NULL ;
01223
01224 if (a_rulesets)
01225 g_return_val_if_fail (a_rulesets->type == RULESET_STMT,
01226 NULL) ;
01227
01228 result = g_try_malloc (sizeof (CRStatement)) ;
01229
01230 if (!result)
01231 {
01232 cr_utils_trace_info ("Out of memory") ;
01233 return NULL ;
01234 }
01235
01236 memset (result, 0, sizeof (CRStatement)) ;
01237 result->type = AT_MEDIA_RULE_STMT ;
01238
01239 result->kind.media_rule = g_try_malloc (sizeof (CRAtMediaRule)) ;
01240 if (!result->kind.media_rule)
01241 {
01242 cr_utils_trace_info ("Out of memory") ;
01243 g_free (result) ;
01244 return NULL ;
01245 }
01246 memset (result->kind.media_rule, 0, sizeof (CRAtMediaRule)) ;
01247 result->kind.media_rule->rulesets = a_rulesets ;
01248 for (cur = a_rulesets ; cur ; cur = cur->next)
01249 {
01250 if (cur->type != RULESET_STMT || !cur->kind.ruleset)
01251 {
01252 cr_utils_trace_info ("Bad parameter a_rulesets. "
01253 "It should be a list of "
01254 "correct ruleset statement only !");
01255 goto error ;
01256 }
01257 cur->kind.ruleset->parent_media_rule = result ;
01258 }
01259
01260 result->kind.media_rule->media_list = a_media ;
01261 if (a_sheet)
01262 {
01263 cr_statement_set_parent_sheet (result, a_sheet) ;
01264 }
01265
01266 return result ;
01267
01268 error:
01269 return NULL ;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281 CRStatement*
01282 cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet,
01283 GString *a_url,
01284 GList *a_media_list,
01285 CRStyleSheet *a_imported_sheet)
01286 {
01287 CRStatement *result = NULL ;
01288
01289 result = g_try_malloc (sizeof (CRStatement)) ;
01290
01291 if (!result)
01292 {
01293 cr_utils_trace_info ("Out of memory") ;
01294 return NULL ;
01295 }
01296
01297 memset (result, 0, sizeof (CRStatement)) ;
01298 result->type = AT_IMPORT_RULE_STMT ;
01299
01300 result->kind.import_rule =
01301 g_try_malloc (sizeof (CRAtImportRule)) ;
01302
01303 if (!result->kind.import_rule)
01304 {
01305 cr_utils_trace_info ("Out of memory") ;
01306 g_free (result) ;
01307 return NULL ;
01308 }
01309
01310 memset (result->kind.import_rule, 0, sizeof (CRAtImportRule)) ;
01311 result->kind.import_rule->url = a_url;
01312 result->kind.import_rule->media_list = a_media_list ;
01313 result->kind.import_rule->sheet = a_imported_sheet;
01314 if (a_container_sheet)
01315 cr_statement_set_parent_sheet (result, a_container_sheet) ;
01316
01317 return result ;
01318 }
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 CRStatement *
01329 cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf,
01330 enum CREncoding a_encoding)
01331 {
01332 enum CRStatus status = CR_OK ;
01333 CRParser *parser = NULL ;
01334 CRStatement *result = NULL ;
01335 GList *media_list = NULL ;
01336 GString *import_string = NULL ;
01337
01338 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01339 a_encoding, FALSE) ;
01340 if (!parser)
01341 {
01342 cr_utils_trace_info ("Instanciation of parser failed.") ;
01343 goto cleanup ;
01344 }
01345
01346 status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
01347 if (status != CR_OK)
01348 goto cleanup ;
01349
01350 status = cr_parser_parse_import (parser, &media_list,
01351 &import_string) ;
01352 if (status != CR_OK || !import_string)
01353 goto cleanup ;
01354
01355 result = cr_statement_new_at_import_rule (NULL, import_string,
01356 media_list, NULL) ;
01357 if (result)
01358 {
01359 import_string = NULL ;
01360 media_list = NULL ;
01361 }
01362
01363 cleanup:
01364 if (parser)
01365 {
01366 cr_parser_destroy (parser) ;
01367 parser = NULL ;
01368 }
01369 if (media_list)
01370 {
01371 GList *cur = NULL ;
01372 for (cur = media_list; media_list;
01373 media_list = g_list_next (media_list))
01374 {
01375 if (media_list->data)
01376 {
01377 g_string_free (media_list->data, TRUE);
01378 media_list->data = NULL ;
01379 }
01380 }
01381 g_list_free (media_list) ;
01382 media_list = NULL;
01383 }
01384 if (import_string)
01385 {
01386 g_string_free (import_string, TRUE) ;
01387 import_string = NULL;
01388 }
01389
01390 return result ;
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 CRStatement *
01404 cr_statement_new_at_page_rule (CRStyleSheet *a_sheet,
01405 CRDeclaration *a_decl_list,
01406 GString *a_name,
01407 GString *a_pseudo)
01408 {
01409 CRStatement *result = NULL ;
01410
01411
01412 result = g_try_malloc (sizeof (CRStatement)) ;
01413
01414 if (!result)
01415 {
01416 cr_utils_trace_info ("Out of memory") ;
01417 return NULL ;
01418 }
01419
01420 memset (result, 0, sizeof (CRStatement)) ;
01421 result->type = AT_PAGE_RULE_STMT ;
01422
01423 result->kind.page_rule = g_try_malloc (sizeof (CRAtPageRule)) ;
01424
01425 if (!result->kind.page_rule)
01426 {
01427 cr_utils_trace_info ("Out of memory") ;
01428 g_free (result) ;
01429 return NULL ;
01430 }
01431
01432 memset (result->kind.page_rule, 0, sizeof (CRAtPageRule)) ;
01433 if (a_decl_list)
01434 {
01435 result->kind.page_rule->decl_list = a_decl_list;
01436 cr_declaration_ref (a_decl_list) ;
01437 }
01438 result->kind.page_rule->name = a_name ;
01439 result->kind.page_rule->name = a_pseudo ;
01440 if (a_sheet)
01441 cr_statement_set_parent_sheet (result, a_sheet) ;
01442
01443 return result ;
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 CRStatement *
01455 cr_statement_at_page_rule_parse_from_buf (const guchar *a_buf,
01456 enum CREncoding a_encoding)
01457 {
01458 enum CRStatus status = CR_OK ;
01459 CRParser *parser = NULL ;
01460 CRDocHandler *sac_handler = NULL ;
01461 CRStatement *result = NULL ;
01462
01463 g_return_val_if_fail (a_buf, NULL) ;
01464
01465 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01466 a_encoding, FALSE) ;
01467 if (!parser)
01468 {
01469 cr_utils_trace_info ("Instanciation of the parser failed.") ;
01470 goto cleanup ;
01471 }
01472
01473 sac_handler = cr_doc_handler_new () ;
01474 if (!sac_handler)
01475 {
01476 cr_utils_trace_info
01477 ("Instanciation of the sac handler failed.") ;
01478 goto cleanup ;
01479 }
01480
01481 sac_handler->start_page =
01482 parse_page_start_page_cb ;
01483 sac_handler->property =
01484 parse_page_property_cb ;
01485 sac_handler->end_page =
01486 parse_page_end_page_cb ;
01487 sac_handler->unrecoverable_error =
01488 parse_page_unrecoverable_error_cb ;
01489
01490 status = cr_parser_set_sac_handler (parser, sac_handler) ;
01491 if (status != CR_OK)
01492 goto cleanup ;
01493
01494
01495 cr_parser_try_to_skip_spaces_and_comments (parser) ;
01496 if (status != CR_OK)
01497 goto cleanup ;
01498 status = cr_parser_parse_page (parser) ;
01499 if (status != CR_OK)
01500 goto cleanup ;
01501
01502 status = cr_doc_handler_get_result (sac_handler,
01503 (gpointer*)&result) ;
01504
01505 cleanup:
01506
01507 if (parser)
01508 {
01509 cr_parser_destroy (parser) ;
01510 parser = NULL ;
01511 }
01512 if (sac_handler)
01513 {
01514 cr_doc_handler_unref (sac_handler) ;
01515 sac_handler = NULL ;
01516 }
01517 return result ;
01518
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530 CRStatement *
01531 cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet,
01532 GString *a_charset)
01533 {
01534 CRStatement * result = NULL ;
01535
01536 g_return_val_if_fail (a_charset, NULL) ;
01537
01538 result = g_try_malloc (sizeof (CRStatement)) ;
01539
01540 if (!result)
01541 {
01542 cr_utils_trace_info ("Out of memory") ;
01543 return NULL ;
01544 }
01545
01546 memset (result, 0, sizeof (CRStatement)) ;
01547 result->type = AT_CHARSET_RULE_STMT ;
01548
01549 result->kind.charset_rule = g_try_malloc
01550 (sizeof (CRAtCharsetRule)) ;
01551
01552 if (!result->kind.charset_rule)
01553 {
01554 cr_utils_trace_info ("Out of memory") ;
01555 g_free (result) ;
01556 return NULL ;
01557 }
01558 memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule)) ;
01559 result->kind.charset_rule->charset = a_charset ;
01560 cr_statement_set_parent_sheet (result, a_sheet) ;
01561
01562 return result ;
01563 }
01564
01565
01566
01567
01568
01569
01570
01571
01572 CRStatement *
01573 cr_statement_at_charset_rule_parse_from_buf (const guchar *a_buf,
01574 enum CREncoding a_encoding)
01575 {
01576 enum CRStatus status = CR_OK ;
01577 CRParser *parser = NULL ;
01578 CRStatement *result = NULL ;
01579 GString *charset = NULL ;
01580
01581 g_return_val_if_fail (a_buf, NULL) ;
01582
01583 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01584 a_encoding, FALSE) ;
01585 if (!parser)
01586 {
01587 cr_utils_trace_info ("Instanciation of the parser failed.") ;
01588 goto cleanup ;
01589 }
01590
01591
01592 cr_parser_try_to_skip_spaces_and_comments (parser) ;
01593 if (status != CR_OK)
01594 goto cleanup ;
01595 status = cr_parser_parse_charset (parser, &charset) ;
01596 if (status != CR_OK || !charset)
01597 goto cleanup ;
01598
01599 result = cr_statement_new_at_charset_rule (NULL, charset) ;
01600 if (result)
01601 charset = NULL ;
01602
01603 cleanup:
01604
01605 if (parser)
01606 {
01607 cr_parser_destroy (parser) ;
01608 parser = NULL ;
01609 }
01610 if (charset)
01611 {
01612 g_string_free (charset, TRUE) ;
01613 }
01614
01615 return result ;
01616 }
01617
01618
01619
01620
01621
01622
01623
01624 CRStatement *
01625 cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet,
01626 CRDeclaration *a_font_decls)
01627 {
01628 CRStatement *result = NULL ;
01629
01630 result = g_try_malloc (sizeof (CRStatement)) ;
01631
01632 if (!result)
01633 {
01634 cr_utils_trace_info ("Out of memory") ;
01635 return NULL ;
01636 }
01637 memset (result, 0, sizeof (CRStatement)) ;
01638 result->type = AT_FONT_FACE_RULE_STMT ;
01639
01640 result->kind.font_face_rule = g_try_malloc
01641 (sizeof (CRAtFontFaceRule)) ;
01642
01643 if (!result->kind.font_face_rule)
01644 {
01645 cr_utils_trace_info ("Out of memory") ;
01646 g_free (result) ;
01647 return NULL ;
01648 }
01649 memset (result->kind.font_face_rule, 0,
01650 sizeof (CRAtFontFaceRule));
01651
01652 result->kind.font_face_rule->decl_list = a_font_decls ;
01653 if (a_sheet)
01654 cr_statement_set_parent_sheet (result, a_sheet) ;
01655
01656 return result ;
01657 }
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667 CRStatement *
01668 cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf,
01669 enum CREncoding a_encoding)
01670 {
01671 CRStatement *result = NULL ;
01672 CRParser *parser = NULL ;
01673 CRDocHandler *sac_handler = NULL ;
01674 enum CRStatus status = CR_OK ;
01675
01676 parser = cr_parser_new_from_buf (a_buf, strlen (a_buf),
01677 a_encoding, FALSE) ;
01678 if (!parser)
01679 goto cleanup ;
01680
01681 sac_handler = cr_doc_handler_new () ;
01682 if (!sac_handler)
01683 goto cleanup ;
01684
01685
01686
01687
01688 sac_handler->start_font_face = parse_font_face_start_font_face_cb ;
01689 sac_handler->property = parse_font_face_property_cb ;
01690 sac_handler->end_font_face = parse_font_face_end_font_face_cb ;
01691 sac_handler->unrecoverable_error =
01692 parse_font_face_unrecoverable_error_cb ;
01693
01694 status = cr_parser_set_sac_handler (parser, sac_handler) ;
01695 if (status != CR_OK)
01696 goto cleanup ;
01697
01698
01699
01700
01701
01702 status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
01703 if (status != CR_OK)
01704 goto cleanup ;
01705
01706 status = cr_parser_parse_font_face (parser) ;
01707 if (status != CR_OK)
01708 goto cleanup ;
01709
01710 status = cr_doc_handler_get_result (sac_handler, (gpointer*)&result) ;
01711 if (status != CR_OK || !result)
01712 goto cleanup ;
01713
01714 cleanup:
01715 if (parser)
01716 {
01717 cr_parser_destroy (parser) ;
01718 parser = NULL ;
01719 }
01720 if (sac_handler)
01721 {
01722 cr_doc_handler_unref (sac_handler) ;
01723 sac_handler = NULL ;
01724 }
01725 return result ;
01726 }
01727
01728
01729
01730
01731
01732
01733
01734 enum CRStatus
01735 cr_statement_set_parent_sheet (CRStatement *a_this,
01736 CRStyleSheet *a_sheet)
01737 {
01738 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
01739 a_this->parent_sheet = a_sheet ;
01740 return CR_OK ;
01741 }
01742
01743
01744
01745
01746
01747
01748
01749 enum CRStatus
01750 cr_statement_get_parent_sheet (CRStatement *a_this,
01751 CRStyleSheet **a_sheet)
01752 {
01753 g_return_val_if_fail (a_this && a_sheet,
01754 CR_BAD_PARAM_ERROR) ;
01755 *a_sheet = a_this->parent_sheet ;
01756 return CR_OK ;
01757 }
01758
01759
01760
01761
01762
01763
01764
01765 CRStatement *
01766 cr_statement_append (CRStatement *a_this,
01767 CRStatement *a_new)
01768 {
01769 CRStatement * cur = NULL ;
01770
01771 g_return_val_if_fail (a_new, NULL) ;
01772
01773 if (!a_this)
01774 {
01775 return a_new ;
01776 }
01777
01778
01779 for (cur = a_this ; cur && cur->next ; cur = cur->next) ;
01780
01781 cur->next = a_new ;
01782 a_new->prev = cur ;
01783
01784 return a_this ;
01785 }
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 CRStatement*
01796 cr_statement_prepend (CRStatement *a_this,
01797 CRStatement *a_new)
01798 {
01799 CRStatement *cur = NULL ;
01800
01801 g_return_val_if_fail (a_new, NULL) ;
01802
01803 if (!a_this)
01804 return a_new ;
01805
01806 a_new->next = a_this ;
01807 a_this->prev = a_new ;
01808
01809
01810 for (cur = a_new ; cur && cur->prev ; cur = cur->prev) ;
01811
01812 return cur ;
01813 }
01814
01815
01816
01817
01818
01819
01820
01821
01822 CRStatement *
01823 cr_statement_unlink (CRStatement *a_stmt)
01824 {
01825 CRStatement *result = a_stmt ;
01826
01827 g_return_val_if_fail (result, NULL) ;
01828
01829
01830
01831
01832 if (a_stmt->next)
01833 {
01834 g_return_val_if_fail (a_stmt->next->prev == a_stmt,
01835 NULL) ;
01836 }
01837 if (a_stmt->prev)
01838 {
01839 g_return_val_if_fail (a_stmt->prev->next == a_stmt,
01840 NULL) ;
01841 }
01842
01843
01844
01845
01846 if (a_stmt->next)
01847 {
01848 a_stmt->next->prev = a_stmt->prev ;
01849 }
01850 if (a_stmt->prev)
01851 {
01852 a_stmt->prev->next = a_stmt->next ;
01853 }
01854
01855 if (a_stmt->parent_sheet
01856 && a_stmt->parent_sheet->statements == a_stmt)
01857 {
01858 a_stmt->parent_sheet->statements =
01859 a_stmt->parent_sheet->statements->next ;
01860 }
01861
01862 a_stmt->next = NULL ;
01863 a_stmt->prev = NULL ;
01864 a_stmt->parent_sheet = NULL ;
01865
01866 return result ;
01867 }
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 enum CRStatus
01880 cr_statement_ruleset_set_sel_list (CRStatement *a_this,
01881 CRSelector *a_sel_list)
01882 {
01883 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT,
01884 CR_BAD_PARAM_ERROR) ;
01885
01886 if (a_this->kind.ruleset->sel_list)
01887 cr_selector_unref (a_this->kind.ruleset->sel_list) ;
01888
01889 a_this->kind.ruleset->sel_list = a_sel_list ;
01890
01891 if (a_sel_list)
01892 cr_selector_ref (a_sel_list) ;
01893
01894 return CR_OK ;
01895 }
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906 enum CRStatus
01907 cr_statement_ruleset_get_declarations (CRStatement *a_this,
01908 CRDeclaration **a_decl_list)
01909 {
01910 g_return_val_if_fail (a_this
01911 && a_this->type == RULESET_STMT
01912 && a_this->kind.ruleset
01913 && a_decl_list,
01914 CR_BAD_PARAM_ERROR) ;
01915
01916 *a_decl_list = a_this->kind.ruleset->decl_list ;
01917
01918 return CR_OK ;
01919 }
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929 enum CRStatus
01930 cr_statement_ruleset_get_sel_list (CRStatement *a_this,
01931 CRSelector **a_list)
01932 {
01933 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
01934 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR) ;
01935
01936 *a_list = a_this->kind.ruleset->sel_list ;
01937
01938 return CR_OK ;
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949 enum CRStatus
01950 cr_statement_ruleset_set_decl_list (CRStatement *a_this,
01951 CRDeclaration *a_list)
01952 {
01953 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
01954 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR);
01955
01956 if (a_this->kind.ruleset->decl_list == a_list)
01957 return CR_OK ;
01958
01959 if (a_this->kind.ruleset->sel_list)
01960 {
01961 cr_declaration_destroy (a_this->kind.ruleset->decl_list) ;
01962 }
01963
01964 a_this->kind.ruleset->sel_list = NULL;
01965
01966 return CR_OK ;
01967 }
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978 enum CRStatus
01979 cr_statement_ruleset_append_decl2 (CRStatement *a_this,
01980 GString *a_prop, CRTerm *a_value)
01981 {
01982 CRDeclaration * new_decls = NULL ;
01983
01984 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
01985 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR) ;
01986
01987 new_decls = cr_declaration_append2
01988 (a_this->kind.ruleset->decl_list, a_prop, a_value) ;
01989 g_return_val_if_fail (new_decls, CR_ERROR) ;
01990 a_this->kind.ruleset->decl_list = new_decls ;
01991
01992 return CR_OK ;
01993 }
01994
01995
01996
01997
01998
01999
02000
02001
02002 enum CRStatus
02003 cr_statement_ruleset_append_decl (CRStatement *a_this,
02004 CRDeclaration *a_decl)
02005 {
02006 CRDeclaration * new_decls = NULL ;
02007
02008 g_return_val_if_fail (a_this && a_this->type == RULESET_STMT
02009 && a_this->kind.ruleset, CR_BAD_PARAM_ERROR) ;
02010
02011 new_decls = cr_declaration_append
02012 (a_this->kind.ruleset->decl_list, a_decl) ;
02013 g_return_val_if_fail (new_decls, CR_ERROR) ;
02014 a_this->kind.ruleset->decl_list = new_decls ;
02015
02016 return CR_OK ;
02017 }
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029 enum CRStatus
02030 cr_statement_at_import_rule_set_imported_sheet (CRStatement *a_this,
02031 CRStyleSheet *a_sheet)
02032 {
02033 g_return_val_if_fail (a_this
02034 && a_this->type == AT_IMPORT_RULE_STMT
02035 && a_this->kind.import_rule,
02036 CR_BAD_PARAM_ERROR) ;
02037
02038 a_this->kind.import_rule->sheet = a_sheet ;
02039
02040 return CR_OK ;
02041 }
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051 enum CRStatus
02052 cr_statement_at_import_rule_get_imported_sheet (CRStatement *a_this,
02053 CRStyleSheet **a_sheet)
02054 {
02055 g_return_val_if_fail (a_this
02056 && a_this->type == AT_IMPORT_RULE_STMT
02057 && a_this->kind.import_rule,
02058 CR_BAD_PARAM_ERROR) ;
02059 *a_sheet = a_this->kind.import_rule->sheet ;
02060 return CR_OK ;
02061
02062 }
02063
02064
02065
02066
02067
02068
02069
02070 enum CRStatus
02071 cr_statement_at_import_rule_set_url (CRStatement *a_this,
02072 GString *a_url)
02073 {
02074 g_return_val_if_fail (a_this
02075 && a_this->type == AT_IMPORT_RULE_STMT
02076 && a_this->kind.import_rule,
02077 CR_BAD_PARAM_ERROR) ;
02078
02079 if (a_this->kind.import_rule->url)
02080 {
02081 g_string_free (a_this->kind.import_rule->url, TRUE) ;
02082 }
02083
02084 a_this->kind.import_rule->url = a_url ;
02085
02086 return CR_OK ;
02087 }
02088
02089
02090
02091
02092
02093
02094
02095
02096 enum CRStatus
02097 cr_statement_at_import_rule_get_url (CRStatement *a_this,
02098 GString **a_url)
02099 {
02100 g_return_val_if_fail (a_this
02101 && a_this->type == AT_IMPORT_RULE_STMT
02102 && a_this->kind.import_rule,
02103 CR_BAD_PARAM_ERROR) ;
02104
02105 *a_url = a_this->kind.import_rule->url ;
02106
02107 return CR_OK ;
02108 }
02109
02110
02111
02112
02113
02114
02115
02116
02117 enum CRStatus
02118 cr_statement_at_page_rule_set_declarations (CRStatement *a_this,
02119 CRDeclaration *a_decl_list)
02120 {
02121 g_return_val_if_fail (a_this
02122 && a_this->type == AT_PAGE_RULE_STMT
02123 && a_this->kind.page_rule,
02124 CR_BAD_PARAM_ERROR) ;
02125
02126 if (a_this->kind.page_rule->decl_list)
02127 {
02128 cr_declaration_unref (a_this->kind.page_rule->decl_list);
02129 }
02130
02131 a_this->kind.page_rule->decl_list = a_decl_list ;
02132
02133 if (a_decl_list)
02134 {
02135 cr_declaration_ref (a_decl_list) ;
02136 }
02137
02138 return CR_OK ;
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149 enum CRStatus
02150 cr_statement_at_page_rule_get_declarations (CRStatement *a_this,
02151 CRDeclaration **a_decl_list)
02152 {
02153 g_return_val_if_fail (a_this
02154 && a_this->type == AT_PAGE_RULE_STMT
02155 && a_this->kind.page_rule,
02156 CR_BAD_PARAM_ERROR) ;
02157
02158 *a_decl_list = a_this->kind.page_rule->decl_list ;
02159
02160 return CR_OK ;
02161 }
02162
02163
02164
02165
02166
02167
02168
02169
02170 enum CRStatus
02171 cr_statement_at_charset_rule_set_charset (CRStatement *a_this,
02172 GString *a_charset)
02173 {
02174 g_return_val_if_fail (a_this
02175 && a_this->type == AT_CHARSET_RULE_STMT
02176 && a_this->kind.charset_rule,
02177 CR_BAD_PARAM_ERROR) ;
02178
02179 if (a_this->kind.charset_rule->charset)
02180 {
02181 g_string_free (a_this->kind.charset_rule->charset,
02182 TRUE) ;
02183 }
02184
02185 a_this->kind.charset_rule->charset = a_charset ;
02186 return CR_OK ;
02187 }
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197 enum CRStatus
02198 cr_statement_at_charset_rule_get_charset (CRStatement *a_this,
02199 GString **a_charset)
02200 {
02201 g_return_val_if_fail (a_this
02202 && a_this->type == AT_CHARSET_RULE_STMT
02203 && a_this->kind.charset_rule,
02204 CR_BAD_PARAM_ERROR) ;
02205
02206 *a_charset = a_this->kind.charset_rule->charset ;
02207
02208 return CR_OK ;
02209 }
02210
02211
02212
02213
02214
02215
02216
02217
02218 enum CRStatus
02219 cr_statement_at_font_face_rule_set_decls (CRStatement *a_this,
02220 CRDeclaration *a_decls)
02221 {
02222 g_return_val_if_fail (a_this
02223 && a_this->type == AT_FONT_FACE_RULE_STMT
02224 && a_this->kind.font_face_rule,
02225 CR_BAD_PARAM_ERROR) ;
02226
02227 if (a_this->kind.font_face_rule->decl_list)
02228 {
02229 cr_declaration_unref
02230 (a_this->kind.font_face_rule->decl_list) ;
02231 }
02232
02233 a_this->kind.font_face_rule->decl_list = a_decls;
02234 cr_declaration_ref (a_decls) ;
02235
02236 return CR_OK ;
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 enum CRStatus
02249 cr_statement_at_font_face_rule_get_decls (CRStatement *a_this,
02250 CRDeclaration **a_decls)
02251 {
02252 g_return_val_if_fail (a_this
02253 && a_this->type == AT_FONT_FACE_RULE_STMT
02254 && a_this->kind.font_face_rule,
02255 CR_BAD_PARAM_ERROR) ;
02256
02257 *a_decls = a_this->kind.font_face_rule->decl_list ;
02258
02259 return CR_OK ;
02260 }
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271 enum CRStatus
02272 cr_statement_at_font_face_rule_add_decl (CRStatement *a_this,
02273 GString *a_prop,
02274 CRTerm *a_value)
02275 {
02276 CRDeclaration *decls = NULL ;
02277
02278 g_return_val_if_fail (a_this
02279 && a_this->type == AT_FONT_FACE_RULE_STMT
02280 && a_this->kind.font_face_rule,
02281 CR_BAD_PARAM_ERROR) ;
02282
02283 decls = cr_declaration_append2
02284 (a_this->kind.font_face_rule->decl_list,
02285 a_prop, a_value) ;
02286
02287 g_return_val_if_fail (decls, CR_ERROR) ;
02288
02289 if (a_this->kind.font_face_rule->decl_list == NULL)
02290 cr_declaration_ref (decls) ;
02291
02292 a_this->kind.font_face_rule->decl_list = decls ;
02293
02294 return CR_OK ;
02295 }
02296
02297
02298
02299
02300
02301
02302
02303 void
02304 cr_statement_dump (CRStatement *a_this, FILE *a_fp, gulong a_indent)
02305 {
02306 g_return_if_fail (a_this) ;
02307
02308 if (a_this->prev)
02309 {
02310 fprintf (a_fp,"\n\n") ;
02311 }
02312
02313 switch (a_this->type)
02314 {
02315 case RULESET_STMT:
02316 cr_statement_dump_ruleset (a_this, a_fp, a_indent) ;
02317 break ;
02318
02319 case AT_FONT_FACE_RULE_STMT:
02320 cr_statement_dump_font_face_rule
02321 (a_this, a_fp, a_indent);
02322 break ;
02323
02324 case AT_CHARSET_RULE_STMT:
02325 cr_statement_dump_charset (a_this, a_fp, a_indent) ;
02326 break ;
02327
02328 case AT_PAGE_RULE_STMT:
02329 cr_statement_dump_page (a_this, a_fp, a_indent) ;
02330 break ;
02331
02332 case AT_MEDIA_RULE_STMT:
02333 cr_statement_dump_media_rule (a_this, a_fp, a_indent) ;
02334 break ;
02335
02336 case AT_IMPORT_RULE_STMT:
02337 cr_statement_dump_import_rule (a_this, a_fp, a_indent) ;
02338 break ;
02339
02340 default :
02341 fprintf (a_fp, "Statement unrecognized at %s:%d",
02342 __FILE__, __LINE__) ;
02343 break ;
02344 }
02345 }
02346
02347
02348
02349
02350 void
02351 cr_statement_destroy (CRStatement *a_this)
02352 {
02353 CRStatement *cur = NULL ;
02354
02355 g_return_if_fail (a_this) ;
02356
02357
02358 for (cur = a_this ; cur && cur->next; cur = cur->next)
02359 {
02360 cr_statement_clear (cur) ;
02361 }
02362
02363 if (cur)
02364 cr_statement_clear (cur) ;
02365
02366 if (cur->prev == NULL)
02367 {
02368 g_free (a_this);
02369 return ;
02370 }
02371
02372
02373 for (cur = cur->prev ; cur && cur->prev; cur = cur->prev)
02374 {
02375 if (cur->next)
02376 {
02377 g_free (cur->next) ;
02378 cur->next = NULL ;
02379 }
02380 }
02381
02382 if (!cur)
02383 return ;
02384
02385
02386 if (cur->next)
02387 {
02388 g_free (cur->next) ;
02389 cur->next = NULL ;
02390 }
02391
02392 g_free (cur) ;
02393 cur = NULL ;
02394 }