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-utils.h"
00029 #include "cr-om-parser.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 struct _CROMParserPriv {
00039 CRParser *parser;
00040 };
00041
00042 #define PRIVATE(a_this) ((a_this)->priv)
00043
00044
00045
00046
00047
00048 struct _ParsingContext;
00049 typedef struct _ParsingContext ParsingContext;
00050
00051 static ParsingContext *new_parsing_context (void);
00052
00053 static void
00054 destroy_context (ParsingContext * a_ctxt);
00055
00056 static void
00057 unrecoverable_error (CRDocHandler * a_this);
00058
00059 static void
00060 error (CRDocHandler * a_this);
00061
00062 static void
00063 property (CRDocHandler * a_this,
00064 GString * a_name, CRTerm * a_expression, gboolean a_important);
00065
00066 static void
00067 end_selector (CRDocHandler * a_this, CRSelector * a_selector_list);
00068
00069 static void
00070 start_selector (CRDocHandler * a_this, CRSelector * a_selector_list);
00071
00072 static void
00073 start_font_face (CRDocHandler * a_this);
00074
00075 static void
00076 end_font_face (CRDocHandler * a_this);
00077
00078 static void
00079 end_document (CRDocHandler * a_this);
00080
00081 static void
00082 start_document (CRDocHandler * a_this);
00083
00084 static void
00085 charset (CRDocHandler * a_this, GString * a_charset);
00086
00087 static void
00088 start_page (CRDocHandler * a_this, GString * a_page,
00089 GString * a_pseudo_page);
00090
00091 static void
00092 end_page (CRDocHandler * a_this, GString * a_page, GString * a_pseudo_page);
00093
00094 static void
00095 start_media (CRDocHandler * a_this, GList * a_media_list);
00096
00097 static void
00098 end_media (CRDocHandler * a_this, GList * a_media_list);
00099
00100 static void
00101 import_style (CRDocHandler * a_this, GList * a_media_list,
00102 GString * a_uri, GString * a_uri_default_ns);
00103
00104 struct _ParsingContext {
00105 CRStyleSheet *stylesheet;
00106 CRStatement *cur_stmt;
00107 CRStatement *cur_media_stmt;
00108 };
00109
00110
00111
00112
00113
00114 static ParsingContext *
00115 new_parsing_context (void)
00116 {
00117 ParsingContext *result = NULL;
00118
00119 result = g_try_malloc (sizeof (ParsingContext));
00120 if (!result) {
00121 cr_utils_trace_info ("Out of Memory");
00122 return NULL;
00123 }
00124 memset (result, 0, sizeof (ParsingContext));
00125 return result;
00126 }
00127
00128 static void
00129 destroy_context (ParsingContext * a_ctxt)
00130 {
00131 g_return_if_fail (a_ctxt);
00132
00133 if (a_ctxt->stylesheet) {
00134 cr_stylesheet_destroy (a_ctxt->stylesheet);
00135 a_ctxt->stylesheet = NULL;
00136 }
00137 if (a_ctxt->cur_stmt) {
00138 cr_statement_destroy (a_ctxt->cur_stmt);
00139 a_ctxt->cur_stmt = NULL;
00140 }
00141 g_free (a_ctxt);
00142 }
00143
00144 static enum CRStatus
00145 cr_om_parser_init_default_sac_handler (CROMParser * a_this)
00146 {
00147 CRDocHandler *sac_handler = NULL;
00148 gboolean free_hdlr_if_error = FALSE;
00149 enum CRStatus status = CR_OK;
00150
00151 g_return_val_if_fail (a_this && PRIVATE (a_this)
00152 && PRIVATE (a_this)->parser,
00153 CR_BAD_PARAM_ERROR);
00154
00155 status = cr_parser_get_sac_handler (PRIVATE (a_this)->parser,
00156 &sac_handler);
00157 g_return_val_if_fail (status == CR_OK, status);
00158
00159 if (!sac_handler) {
00160 sac_handler = cr_doc_handler_new ();
00161 free_hdlr_if_error = TRUE;
00162 }
00163
00164
00165
00166
00167 sac_handler->start_document = start_document;
00168 sac_handler->end_document = end_document;
00169 sac_handler->start_selector = start_selector;
00170 sac_handler->end_selector = end_selector;
00171 sac_handler->property = property;
00172 sac_handler->start_font_face = start_font_face;
00173 sac_handler->end_font_face = end_font_face;
00174 sac_handler->error = error;
00175 sac_handler->unrecoverable_error = unrecoverable_error;
00176 sac_handler->charset = charset;
00177 sac_handler->start_page = start_page;
00178 sac_handler->end_page = end_page;
00179 sac_handler->start_media = start_media;
00180 sac_handler->end_media = end_media;
00181 sac_handler->import_style = import_style;
00182
00183 status = cr_parser_set_sac_handler (PRIVATE (a_this)->parser,
00184 sac_handler);
00185 if (status == CR_OK) {
00186 return CR_OK;
00187 }
00188
00189 if (sac_handler && free_hdlr_if_error == TRUE) {
00190 cr_doc_handler_destroy (sac_handler);
00191 sac_handler = NULL;
00192 }
00193
00194 return status;
00195
00196 }
00197
00198 static void
00199 start_document (CRDocHandler * a_this)
00200 {
00201 ParsingContext *ctxt = NULL;
00202 CRStyleSheet *stylesheet = NULL;
00203
00204 g_return_if_fail (a_this);
00205
00206 ctxt = new_parsing_context ();
00207 g_return_if_fail (ctxt);
00208
00209 stylesheet = cr_stylesheet_new (NULL);
00210 ctxt->stylesheet = stylesheet;
00211 cr_doc_handler_set_ctxt (a_this, ctxt);
00212 }
00213
00214 static void
00215 start_font_face (CRDocHandler * a_this)
00216 {
00217 enum CRStatus status = CR_OK;
00218 ParsingContext *ctxt = NULL;
00219 ParsingContext **ctxtptr = NULL;
00220
00221 g_return_if_fail (a_this);
00222
00223 g_return_if_fail (a_this);
00224 ctxtptr = &ctxt;
00225 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00226 g_return_if_fail (status == CR_OK && ctxt);
00227 g_return_if_fail (ctxt->cur_stmt == NULL);
00228
00229 ctxt->cur_stmt =
00230 cr_statement_new_at_font_face_rule (ctxt->stylesheet, NULL);
00231
00232 g_return_if_fail (ctxt->cur_stmt);
00233 }
00234
00235 static void
00236 end_font_face (CRDocHandler * a_this)
00237 {
00238 enum CRStatus status = CR_OK;
00239 ParsingContext *ctxt = NULL;
00240 ParsingContext **ctxtptr = NULL;
00241 CRStatement *stmts = NULL;
00242
00243 g_return_if_fail (a_this);
00244
00245 g_return_if_fail (a_this);
00246 ctxtptr = &ctxt;
00247 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00248 g_return_if_fail (status == CR_OK && ctxt);
00249 g_return_if_fail
00250 (ctxt->cur_stmt
00251 && ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT
00252 && ctxt->stylesheet);
00253
00254 stmts = cr_statement_append (ctxt->stylesheet->statements,
00255 ctxt->cur_stmt);
00256 if (!stmts)
00257 goto error;
00258
00259 ctxt->stylesheet->statements = stmts;
00260 stmts = NULL;
00261 ctxt->cur_stmt = NULL;
00262
00263 return;
00264
00265 error:
00266
00267 if (ctxt->cur_stmt) {
00268 cr_statement_destroy (ctxt->cur_stmt);
00269 ctxt->cur_stmt = NULL;
00270 }
00271
00272 if (!stmts) {
00273 cr_statement_destroy (stmts);
00274 stmts = NULL;
00275 }
00276 }
00277
00278 static void
00279 end_document (CRDocHandler * a_this)
00280 {
00281 enum CRStatus status = CR_OK;
00282 ParsingContext *ctxt = NULL;
00283 ParsingContext **ctxtptr = NULL;
00284
00285 g_return_if_fail (a_this);
00286 ctxtptr = &ctxt;
00287 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00288 g_return_if_fail (status == CR_OK && ctxt);
00289
00290 if (!ctxt->stylesheet || ctxt->cur_stmt)
00291 goto error;
00292
00293 status = cr_doc_handler_set_result (a_this, ctxt->stylesheet);
00294 g_return_if_fail (status == CR_OK);
00295
00296 ctxt->stylesheet = NULL;
00297 destroy_context (ctxt);
00298 cr_doc_handler_set_ctxt (a_this, NULL);
00299
00300 return;
00301
00302 error:
00303 if (ctxt) {
00304 destroy_context (ctxt);
00305 }
00306 }
00307
00308 static void
00309 charset (CRDocHandler * a_this, GString * a_charset)
00310 {
00311 enum CRStatus status = CR_OK;
00312 CRStatement *stmt = NULL,
00313 *stmt2 = NULL;
00314 GString *charset = NULL;
00315
00316 ParsingContext *ctxt = NULL;
00317 ParsingContext **ctxtptr = NULL;
00318
00319 g_return_if_fail (a_this);
00320 ctxtptr = &ctxt;
00321 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00322 g_return_if_fail (status == CR_OK && ctxt);
00323 g_return_if_fail (ctxt->stylesheet);
00324
00325 charset = g_string_new_len (a_charset->str, a_charset->len);
00326
00327 stmt = cr_statement_new_at_charset_rule (ctxt->stylesheet, charset);
00328 g_return_if_fail (stmt);
00329
00330 stmt2 = cr_statement_append (ctxt->stylesheet->statements, stmt);
00331 if (!stmt2) {
00332 if (stmt) {
00333 cr_statement_destroy (stmt);
00334 stmt = NULL;
00335 }
00336
00337 if (charset) {
00338 g_string_free (charset, TRUE);
00339 }
00340 return;
00341 }
00342
00343 ctxt->stylesheet->statements = stmt2;
00344 stmt2 = NULL;
00345 }
00346
00347 static void
00348 start_page (CRDocHandler * a_this, GString * a_page, GString * a_pseudo)
00349 {
00350 enum CRStatus status = CR_OK;
00351 ParsingContext *ctxt = NULL;
00352 ParsingContext **ctxtptr = NULL;
00353
00354 g_return_if_fail (a_this);
00355 ctxtptr = &ctxt;
00356 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00357 g_return_if_fail (status == CR_OK && ctxt);
00358 g_return_if_fail (ctxt->cur_stmt == NULL);
00359
00360 ctxt->cur_stmt = cr_statement_new_at_page_rule
00361 (ctxt->stylesheet, NULL, NULL, NULL);
00362
00363 if (a_page) {
00364 ctxt->cur_stmt->kind.page_rule->name =
00365 g_string_new_len (a_page->str, a_page->len);
00366
00367 if (!ctxt->cur_stmt->kind.page_rule->name) {
00368 goto error;
00369 }
00370 }
00371
00372 if (a_pseudo) {
00373 ctxt->cur_stmt->kind.page_rule->pseudo =
00374 g_string_new_len (a_pseudo->str, a_pseudo->len);
00375
00376 if (!ctxt->cur_stmt->kind.page_rule->pseudo) {
00377 goto error;
00378 }
00379 }
00380
00381 return;
00382
00383 error:
00384 if (ctxt->cur_stmt) {
00385 cr_statement_destroy (ctxt->cur_stmt);
00386 ctxt->cur_stmt = NULL;
00387 }
00388 }
00389
00390 static void
00391 end_page (CRDocHandler * a_this, GString * a_page, GString * a_pseudo_page)
00392 {
00393 enum CRStatus status = CR_OK;
00394 ParsingContext *ctxt = NULL;
00395 ParsingContext **ctxtptr = NULL;
00396 CRStatement *stmt = NULL;
00397
00398 g_return_if_fail (a_this);
00399 ctxtptr = &ctxt;
00400 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00401 g_return_if_fail (status == CR_OK && ctxt);
00402 g_return_if_fail (ctxt->cur_stmt
00403 && ctxt->cur_stmt->type == AT_PAGE_RULE_STMT
00404 && ctxt->stylesheet);
00405
00406 stmt = cr_statement_append (ctxt->stylesheet->statements,
00407 ctxt->cur_stmt);
00408
00409 if (stmt) {
00410 ctxt->stylesheet->statements = stmt;
00411 stmt = NULL;
00412 ctxt->cur_stmt = NULL;
00413 }
00414
00415 if (ctxt->cur_stmt) {
00416 cr_statement_destroy (ctxt->cur_stmt);
00417 ctxt->cur_stmt = NULL;
00418 }
00419 a_page = NULL;
00420 a_pseudo_page = NULL;
00421 }
00422
00423 static void
00424 start_media (CRDocHandler * a_this, GList * a_media_list)
00425 {
00426 enum CRStatus status = CR_OK;
00427 ParsingContext *ctxt = NULL;
00428 ParsingContext **ctxtptr = NULL;
00429 GList *media_list = NULL;
00430
00431 g_return_if_fail (a_this);
00432 ctxtptr = &ctxt;
00433 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00434 g_return_if_fail (status == CR_OK && ctxt);
00435
00436 g_return_if_fail (ctxt
00437 && ctxt->cur_stmt == NULL
00438 && ctxt->cur_media_stmt == NULL
00439 && ctxt->stylesheet);
00440
00441 if (a_media_list) {
00442
00443 media_list = cr_dup_glist_of_string (a_media_list);
00444 }
00445
00446 ctxt->cur_media_stmt =
00447 cr_statement_new_at_media_rule
00448 (ctxt->stylesheet, NULL, media_list);
00449
00450 }
00451
00452 static void
00453 end_media (CRDocHandler * a_this, GList * a_media_list)
00454 {
00455 enum CRStatus status = CR_OK;
00456 ParsingContext *ctxt = NULL;
00457 ParsingContext **ctxtptr = NULL;
00458 CRStatement *stmts = NULL;
00459
00460 g_return_if_fail (a_this);
00461 ctxtptr = &ctxt;
00462 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00463 g_return_if_fail (status == CR_OK && ctxt);
00464 g_return_if_fail (ctxt
00465 && ctxt->cur_media_stmt
00466 && ctxt->cur_media_stmt->type == AT_MEDIA_RULE_STMT
00467 && ctxt->stylesheet);
00468
00469 stmts = cr_statement_append (ctxt->stylesheet->statements,
00470 ctxt->cur_media_stmt);
00471 if (!stmts) {
00472 cr_statement_destroy (ctxt->cur_media_stmt);
00473 ctxt->cur_media_stmt = NULL;
00474 }
00475
00476 ctxt->stylesheet->statements = stmts;
00477 stmts = NULL;
00478
00479 ctxt->cur_stmt = NULL ;
00480 ctxt->cur_media_stmt = NULL ;
00481 a_media_list = NULL;
00482 }
00483
00484 static void
00485 import_style (CRDocHandler * a_this, GList * a_media_list,
00486 GString * a_uri, GString * a_uri_default_ns)
00487 {
00488 enum CRStatus status = CR_OK;
00489 GString *uri = NULL;
00490 CRStatement *stmt = NULL,
00491 *stmt2 = NULL;
00492 ParsingContext *ctxt = NULL;
00493 ParsingContext **ctxtptr = NULL;
00494 GList *media_list = NULL,
00495 *cur = NULL;
00496
00497 g_return_if_fail (a_this);
00498 ctxtptr = &ctxt;
00499 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00500 g_return_if_fail (status == CR_OK && ctxt);
00501 g_return_if_fail (ctxt->stylesheet);
00502
00503 uri = g_string_new_len (a_uri->str, a_uri->len);
00504
00505 for (cur = a_media_list; cur; cur = cur->next) {
00506 if (cur->data) {
00507 GString *str1 = NULL,
00508 *str2 = NULL;
00509
00510 str1 = (GString *) cur->data;
00511 str2 = g_string_new_len (str1->str, str1->len);
00512
00513 media_list = g_list_append (media_list, str2);
00514 }
00515 }
00516
00517 stmt = cr_statement_new_at_import_rule
00518 (ctxt->stylesheet, uri, media_list, NULL);
00519 if (!stmt)
00520 goto error;
00521
00522 if (ctxt->cur_stmt) {
00523 stmt2 = cr_statement_append (ctxt->cur_stmt, stmt);
00524 if (!stmt2)
00525 goto error;
00526 ctxt->cur_stmt = stmt2;
00527 stmt2 = NULL;
00528 stmt = NULL;
00529 } else {
00530 stmt2 = cr_statement_append (ctxt->stylesheet->statements,
00531 stmt);
00532 if (!stmt2)
00533 goto error;
00534 ctxt->stylesheet->statements = stmt2;
00535 stmt2 = NULL;
00536 stmt = NULL;
00537 }
00538
00539 return;
00540
00541 error:
00542 if (uri) {
00543 g_string_free (uri, TRUE);
00544 }
00545
00546 if (stmt) {
00547 cr_statement_destroy (stmt);
00548 stmt = NULL;
00549 }
00550 a_uri_default_ns = NULL;
00551 }
00552
00553 static void
00554 start_selector (CRDocHandler * a_this, CRSelector * a_selector_list)
00555 {
00556 enum CRStatus status = CR_OK;
00557 ParsingContext *ctxt = NULL;
00558 ParsingContext **ctxtptr = NULL;
00559
00560 g_return_if_fail (a_this);
00561 ctxtptr = &ctxt;
00562 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00563 g_return_if_fail (status == CR_OK && ctxt);
00564 if (ctxt->cur_stmt) {
00565
00566 cr_statement_destroy (ctxt->cur_stmt);
00567 ctxt->cur_stmt = NULL;
00568 }
00569
00570 ctxt->cur_stmt = cr_statement_new_ruleset
00571 (ctxt->stylesheet, a_selector_list, NULL, NULL);
00572 }
00573
00574 static void
00575 end_selector (CRDocHandler * a_this, CRSelector * a_selector_list)
00576 {
00577 enum CRStatus status = CR_OK;
00578 ParsingContext *ctxt = NULL;
00579 ParsingContext **ctxtptr = NULL;
00580
00581 g_return_if_fail (a_this);
00582 ctxtptr = &ctxt;
00583 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00584 g_return_if_fail (status == CR_OK && ctxt);
00585 g_return_if_fail (ctxt->cur_stmt && ctxt->stylesheet);
00586
00587 if (ctxt->cur_stmt) {
00588 CRStatement *stmts = NULL;
00589
00590 if (ctxt->cur_media_stmt) {
00591 CRAtMediaRule *media_rule = NULL;
00592
00593 media_rule = ctxt->cur_media_stmt->kind.media_rule;
00594
00595 stmts = cr_statement_append
00596 (media_rule->rulesets, ctxt->cur_stmt);
00597
00598 if (!stmts) {
00599 cr_utils_trace_info
00600 ("Could not append a new statement");
00601 cr_statement_destroy (media_rule->rulesets);
00602 ctxt->cur_media_stmt->
00603 kind.media_rule->rulesets = NULL;
00604 return;
00605 }
00606 media_rule->rulesets = stmts;
00607 ctxt->cur_stmt = NULL;
00608 } else {
00609 stmts = cr_statement_append
00610 (ctxt->stylesheet->statements,
00611 ctxt->cur_stmt);
00612 if (!stmts) {
00613 cr_utils_trace_info
00614 ("Could not append a new statement");
00615 cr_statement_destroy (ctxt->cur_stmt);
00616 ctxt->cur_stmt = NULL;
00617 return;
00618 }
00619 ctxt->stylesheet->statements = stmts;
00620 ctxt->cur_stmt = NULL;
00621 }
00622
00623 }
00624 a_selector_list = NULL;
00625 }
00626
00627 static void
00628 property (CRDocHandler * a_this,
00629 GString * a_name, CRTerm * a_expression, gboolean a_important)
00630 {
00631 enum CRStatus status = CR_OK;
00632 ParsingContext *ctxt = NULL;
00633 ParsingContext **ctxtptr = NULL;
00634 CRDeclaration *decl = NULL,
00635 *decl2 = NULL;
00636 GString *str = NULL;
00637
00638 g_return_if_fail (a_this);
00639 ctxtptr = &ctxt;
00640 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00641 g_return_if_fail (status == CR_OK && ctxt);
00642
00643
00644
00645
00646
00647 g_return_if_fail
00648 (ctxt->cur_stmt
00649 &&
00650 (ctxt->cur_stmt->type == RULESET_STMT
00651 || ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT
00652 || ctxt->cur_stmt->type == AT_PAGE_RULE_STMT));
00653
00654 if (a_name) {
00655 str = g_string_new_len (a_name->str, a_name->len);
00656 g_return_if_fail (str);
00657 }
00658
00659
00660 decl = cr_declaration_new (ctxt->cur_stmt, str, a_expression);
00661 g_return_if_fail (decl);
00662 str = NULL;
00663 decl->important = a_important;
00664
00665
00666
00667
00668 switch (ctxt->cur_stmt->type) {
00669 case RULESET_STMT:
00670 decl2 = cr_declaration_append
00671 (ctxt->cur_stmt->kind.ruleset->decl_list, decl);
00672 if (!decl2) {
00673 cr_declaration_destroy (decl);
00674 cr_utils_trace_info
00675 ("Could not append decl to ruleset");
00676 goto error;
00677 }
00678 ctxt->cur_stmt->kind.ruleset->decl_list = decl2;
00679 decl = NULL;
00680 decl2 = NULL;
00681 break;
00682
00683 case AT_FONT_FACE_RULE_STMT:
00684 decl2 = cr_declaration_append
00685 (ctxt->cur_stmt->kind.font_face_rule->decl_list,
00686 decl);
00687 if (!decl2) {
00688 cr_declaration_destroy (decl);
00689 cr_utils_trace_info
00690 ("Could not append decl to ruleset");
00691 goto error;
00692 }
00693 ctxt->cur_stmt->kind.font_face_rule->decl_list = decl2;
00694 decl = NULL;
00695 decl2 = NULL;
00696 break;
00697 case AT_PAGE_RULE_STMT:
00698 decl2 = cr_declaration_append
00699 (ctxt->cur_stmt->kind.page_rule->decl_list, decl);
00700 if (!decl2) {
00701 cr_declaration_destroy (decl);
00702 cr_utils_trace_info
00703 ("Could not append decl to ruleset");
00704 goto error;
00705 }
00706 ctxt->cur_stmt->kind.page_rule->decl_list = decl2;
00707 decl = NULL;
00708 decl2 = NULL;
00709 break;
00710
00711 default:
00712 goto error;
00713 break;
00714 }
00715
00716 return;
00717
00718 error:
00719 if (str) {
00720 g_free (str);
00721 str = NULL;
00722 }
00723
00724 if (decl) {
00725 cr_declaration_destroy (decl);
00726 decl = NULL;
00727 }
00728 }
00729
00730 static void
00731 error (CRDocHandler * a_this)
00732 {
00733 enum CRStatus status = CR_OK;
00734 ParsingContext *ctxt = NULL;
00735 ParsingContext **ctxtptr = NULL;
00736
00737 g_return_if_fail (a_this);
00738 ctxtptr = &ctxt;
00739 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00740 g_return_if_fail (status == CR_OK && ctxt);
00741
00742 if (ctxt->cur_stmt) {
00743 cr_statement_destroy (ctxt->cur_stmt);
00744 ctxt->cur_stmt = NULL;
00745 }
00746 }
00747
00748 static void
00749 unrecoverable_error (CRDocHandler * a_this)
00750 {
00751 enum CRStatus status = CR_OK;
00752 ParsingContext *ctxt = NULL;
00753 ParsingContext **ctxtptr = NULL;
00754
00755 ctxtptr = &ctxt;
00756 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00757 g_return_if_fail (status == CR_OK);
00758
00759 if (ctxt) {
00760 if (ctxt->stylesheet) {
00761 status = cr_doc_handler_set_result
00762 (a_this, ctxt->stylesheet);
00763 g_return_if_fail (status == CR_OK);
00764 }
00765 g_free (ctxt);
00766 cr_doc_handler_set_ctxt (a_this, NULL);
00767 }
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 CROMParser *
00780 cr_om_parser_new (CRInput * a_input)
00781 {
00782 CROMParser *result = NULL;
00783 enum CRStatus status = CR_OK;
00784
00785 result = g_try_malloc (sizeof (CROMParser));
00786
00787 if (!result) {
00788 cr_utils_trace_info ("Out of memory");
00789 return NULL;
00790 }
00791
00792 memset (result, 0, sizeof (CROMParser));
00793 PRIVATE (result) = g_try_malloc (sizeof (CROMParserPriv));
00794
00795 if (!PRIVATE (result)) {
00796 cr_utils_trace_info ("Out of memory");
00797 goto error;
00798 }
00799
00800 memset (PRIVATE (result), 0, sizeof (CROMParserPriv));
00801
00802 PRIVATE (result)->parser = cr_parser_new_from_input (a_input);
00803
00804 if (!PRIVATE (result)->parser) {
00805 cr_utils_trace_info ("parsing instanciation failed");
00806 goto error;
00807 }
00808
00809 status = cr_om_parser_init_default_sac_handler (result);
00810
00811 if (status != CR_OK) {
00812 goto error;
00813 }
00814
00815 return result;
00816
00817 error:
00818
00819 if (result) {
00820 cr_om_parser_destroy (result);
00821 }
00822
00823 return NULL;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 enum CRStatus
00836 cr_om_parser_parse_buf (CROMParser * a_this,
00837 const guchar * a_buf,
00838 gulong a_len,
00839 enum CREncoding a_enc, CRStyleSheet ** a_result)
00840 {
00841
00842 enum CRStatus status = CR_OK;
00843
00844 g_return_val_if_fail (a_this && a_result, CR_BAD_PARAM_ERROR);
00845
00846 if (!PRIVATE (a_this)->parser) {
00847 PRIVATE (a_this)->parser = cr_parser_new (NULL);
00848 }
00849
00850 status = cr_parser_parse_buf (PRIVATE (a_this)->parser,
00851 a_buf, a_len, a_enc);
00852
00853 if (status == CR_OK) {
00854 CRStyleSheet *result = NULL;
00855 CRStyleSheet **resultptr = NULL;
00856 CRDocHandler *sac_handler = NULL;
00857
00858 cr_parser_get_sac_handler (PRIVATE (a_this)->parser,
00859 &sac_handler);
00860 g_return_val_if_fail (sac_handler, CR_ERROR);
00861 resultptr = &result;
00862 status = cr_doc_handler_get_result (sac_handler,
00863 (gpointer *) resultptr);
00864 g_return_val_if_fail (status == CR_OK, status);
00865
00866 if (result)
00867 *a_result = result;
00868 }
00869
00870 return status;
00871 }
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 enum CRStatus
00882 cr_om_parser_simply_parse_buf (const guchar * a_buf,
00883 gulong a_len,
00884 enum CREncoding a_enc,
00885 CRStyleSheet ** a_result)
00886 {
00887 CROMParser *parser = NULL;
00888 enum CRStatus status = CR_OK;
00889
00890 parser = cr_om_parser_new (NULL);
00891 if (!parser) {
00892 cr_utils_trace_info ("Could not create om parser");
00893 cr_utils_trace_info ("System possibly out of memory");
00894 return CR_ERROR;
00895 }
00896
00897 status = cr_om_parser_parse_buf (parser, a_buf, a_len,
00898 a_enc, a_result);
00899
00900 if (parser) {
00901 cr_om_parser_destroy (parser);
00902 parser = NULL;
00903 }
00904
00905 return status;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 enum CRStatus
00921 cr_om_parser_parse_file (CROMParser * a_this,
00922 const guchar * a_file_uri,
00923 enum CREncoding a_enc, CRStyleSheet ** a_result)
00924 {
00925 enum CRStatus status = CR_OK;
00926
00927 g_return_val_if_fail (a_this && a_file_uri && a_result,
00928 CR_BAD_PARAM_ERROR);
00929
00930 if (!PRIVATE (a_this)->parser) {
00931 PRIVATE (a_this)->parser = cr_parser_new_from_file
00932 (a_file_uri, a_enc);
00933 }
00934
00935 status = cr_parser_parse_file (PRIVATE (a_this)->parser,
00936 a_file_uri, a_enc);
00937
00938 if (status == CR_OK) {
00939 CRStyleSheet *result = NULL;
00940 CRStyleSheet **resultptr = NULL;
00941 CRDocHandler *sac_handler = NULL;
00942
00943 cr_parser_get_sac_handler (PRIVATE (a_this)->parser,
00944 &sac_handler);
00945 g_return_val_if_fail (sac_handler, CR_ERROR);
00946 resultptr = &result;
00947 status = cr_doc_handler_get_result
00948 (sac_handler, (gpointer *) resultptr);
00949 g_return_val_if_fail (status == CR_OK, status);
00950 if (result)
00951 *a_result = result;
00952 }
00953
00954 return status;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 enum CRStatus
00968 cr_om_parser_simply_parse_file (const guchar * a_file_path,
00969 enum CREncoding a_enc,
00970 CRStyleSheet ** a_result)
00971 {
00972 CROMParser *parser = NULL;
00973 enum CRStatus status = CR_OK;
00974
00975 parser = cr_om_parser_new (NULL);
00976 if (!parser) {
00977 cr_utils_trace_info ("Could not allocate om parser");
00978 cr_utils_trace_info ("System may be out of memory");
00979 return CR_ERROR;
00980 }
00981
00982 status = cr_om_parser_parse_file (parser, a_file_path,
00983 a_enc, a_result);
00984 if (parser) {
00985 cr_om_parser_destroy (parser);
00986 parser = NULL;
00987 }
00988
00989 return status;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 enum CRStatus
01003 cr_om_parser_parse_paths_to_cascade (CROMParser * a_this,
01004 const guchar * a_author_path,
01005 const guchar * a_user_path,
01006 const guchar * a_ua_path,
01007 enum CREncoding a_encoding,
01008 CRCascade ** a_result)
01009 {
01010 enum CRStatus status = CR_OK;
01011
01012
01013 CRStyleSheet *sheets[3];
01014 guchar *paths[3];
01015 CRCascade *result = NULL;
01016 gint i = 0;
01017
01018 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
01019
01020 memset (sheets, 0, sizeof (CRStyleSheet) * 3);
01021 paths[0] = (guchar *) a_author_path;
01022 paths[1] = (guchar *) a_user_path;
01023 paths[2] = (guchar *) a_ua_path;
01024
01025 for (i = 0; i < 3; i++) {
01026 status = cr_om_parser_parse_file (a_this, paths[i],
01027 a_encoding, &sheets[i]);
01028 if (status != CR_OK) {
01029 if (sheets[i]) {
01030 cr_stylesheet_unref (sheets[i]);
01031 sheets[i] = NULL;
01032 }
01033 continue;
01034 }
01035 }
01036 result = cr_cascade_new (sheets[0], sheets[1], sheets[2]);
01037 if (!result) {
01038 for (i = 0; i < 3; i++) {
01039 cr_stylesheet_unref (sheets[i]);
01040 sheets[i] = 0;
01041 }
01042 return CR_ERROR;
01043 }
01044 *a_result = result;
01045 return CR_OK;
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 enum CRStatus
01058 cr_om_parser_simply_parse_paths_to_cascade (const guchar * a_author_path,
01059 const guchar * a_user_path,
01060 const guchar * a_ua_path,
01061 enum CREncoding a_encoding,
01062 CRCascade ** a_result)
01063 {
01064 enum CRStatus status = CR_OK;
01065 CROMParser *parser = NULL;
01066
01067 parser = cr_om_parser_new (NULL);
01068 if (!parser) {
01069 cr_utils_trace_info ("could not allocated om parser");
01070 cr_utils_trace_info ("System may be out of memory");
01071 return CR_ERROR;
01072 }
01073 status = cr_om_parser_parse_paths_to_cascade (parser,
01074 a_author_path,
01075 a_user_path,
01076 a_ua_path,
01077 a_encoding, a_result);
01078 if (parser) {
01079 cr_om_parser_destroy (parser);
01080 parser = NULL;
01081 }
01082 return status;
01083 }
01084
01085
01086
01087
01088
01089 void
01090 cr_om_parser_destroy (CROMParser * a_this)
01091 {
01092 g_return_if_fail (a_this && PRIVATE (a_this));
01093
01094 if (PRIVATE (a_this)->parser) {
01095 cr_parser_destroy (PRIVATE (a_this)->parser);
01096 PRIVATE (a_this)->parser = NULL;
01097 }
01098
01099 if (PRIVATE (a_this)) {
01100 g_free (PRIVATE (a_this));
01101 PRIVATE (a_this) = NULL;
01102 }
01103
01104 if (a_this) {
01105 g_free (a_this);
01106 a_this = NULL;
01107 }
01108 }