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 a_media_list = NULL;
00480 }
00481
00482 static void
00483 import_style (CRDocHandler * a_this, GList * a_media_list,
00484 GString * a_uri, GString * a_uri_default_ns)
00485 {
00486 enum CRStatus status = CR_OK;
00487 GString *uri = NULL;
00488 CRStatement *stmt = NULL,
00489 *stmt2 = NULL;
00490 ParsingContext *ctxt = NULL;
00491 ParsingContext **ctxtptr = NULL;
00492 GList *media_list = NULL,
00493 *cur = NULL;
00494
00495 g_return_if_fail (a_this);
00496 ctxtptr = &ctxt;
00497 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00498 g_return_if_fail (status == CR_OK && ctxt);
00499 g_return_if_fail (ctxt->stylesheet);
00500
00501 uri = g_string_new_len (a_uri->str, a_uri->len);
00502
00503 for (cur = a_media_list; cur; cur = cur->next) {
00504 if (cur->data) {
00505 GString *str1 = NULL,
00506 *str2 = NULL;
00507
00508 str1 = (GString *) cur->data;
00509 str2 = g_string_new_len (str1->str, str1->len);
00510
00511 media_list = g_list_append (media_list, str2);
00512 }
00513 }
00514
00515 stmt = cr_statement_new_at_import_rule
00516 (ctxt->stylesheet, uri, media_list, NULL);
00517 if (!stmt)
00518 goto error;
00519
00520 if (ctxt->cur_stmt) {
00521 stmt2 = cr_statement_append (ctxt->cur_stmt, stmt);
00522 if (!stmt2)
00523 goto error;
00524 ctxt->cur_stmt = stmt2;
00525 stmt2 = NULL;
00526 stmt = NULL;
00527 } else {
00528 stmt2 = cr_statement_append (ctxt->stylesheet->statements,
00529 stmt);
00530 if (!stmt2)
00531 goto error;
00532 ctxt->stylesheet->statements = stmt2;
00533 stmt2 = NULL;
00534 stmt = NULL;
00535 }
00536
00537 return;
00538
00539 error:
00540 if (uri) {
00541 g_string_free (uri, TRUE);
00542 }
00543
00544 if (stmt) {
00545 cr_statement_destroy (stmt);
00546 stmt = NULL;
00547 }
00548 a_uri_default_ns = NULL;
00549 }
00550
00551 static void
00552 start_selector (CRDocHandler * a_this, CRSelector * a_selector_list)
00553 {
00554 enum CRStatus status = CR_OK;
00555 ParsingContext *ctxt = NULL;
00556 ParsingContext **ctxtptr = NULL;
00557
00558 g_return_if_fail (a_this);
00559 ctxtptr = &ctxt;
00560 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00561 g_return_if_fail (status == CR_OK && ctxt);
00562 if (ctxt->cur_stmt) {
00563
00564 cr_statement_destroy (ctxt->cur_stmt);
00565 ctxt->cur_stmt = NULL;
00566 }
00567
00568 ctxt->cur_stmt = cr_statement_new_ruleset
00569 (ctxt->stylesheet, a_selector_list, NULL, NULL);
00570 }
00571
00572 static void
00573 end_selector (CRDocHandler * a_this, CRSelector * a_selector_list)
00574 {
00575 enum CRStatus status = CR_OK;
00576 ParsingContext *ctxt = NULL;
00577 ParsingContext **ctxtptr = NULL;
00578
00579 g_return_if_fail (a_this);
00580 ctxtptr = &ctxt;
00581 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00582 g_return_if_fail (status == CR_OK && ctxt);
00583 g_return_if_fail (ctxt->cur_stmt && ctxt->stylesheet);
00584
00585 if (ctxt->cur_stmt) {
00586 CRStatement *stmts = NULL;
00587
00588 if (ctxt->cur_media_stmt) {
00589 CRAtMediaRule *media_rule = NULL;
00590
00591 media_rule = ctxt->cur_media_stmt->kind.media_rule;
00592
00593 stmts = cr_statement_append
00594 (media_rule->rulesets, ctxt->cur_stmt);
00595
00596 if (!stmts) {
00597 cr_utils_trace_info
00598 ("Could not append a new statement");
00599 cr_statement_destroy (media_rule->rulesets);
00600 ctxt->cur_media_stmt->
00601 kind.media_rule->rulesets = NULL;
00602 return;
00603 }
00604 media_rule->rulesets = stmts;
00605 ctxt->cur_stmt = NULL;
00606 } else {
00607 stmts = cr_statement_append
00608 (ctxt->stylesheet->statements,
00609 ctxt->cur_stmt);
00610 if (!stmts) {
00611 cr_utils_trace_info
00612 ("Could not append a new statement");
00613 cr_statement_destroy (ctxt->cur_stmt);
00614 ctxt->cur_stmt = NULL;
00615 return;
00616 }
00617 ctxt->stylesheet->statements = stmts;
00618 ctxt->cur_stmt = NULL;
00619 }
00620
00621 }
00622 a_selector_list = NULL;
00623 }
00624
00625 static void
00626 property (CRDocHandler * a_this,
00627 GString * a_name, CRTerm * a_expression, gboolean a_important)
00628 {
00629 enum CRStatus status = CR_OK;
00630 ParsingContext *ctxt = NULL;
00631 ParsingContext **ctxtptr = NULL;
00632 CRDeclaration *decl = NULL,
00633 *decl2 = NULL;
00634 GString *str = NULL;
00635
00636 g_return_if_fail (a_this);
00637 ctxtptr = &ctxt;
00638 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00639 g_return_if_fail (status == CR_OK && ctxt);
00640
00641
00642
00643
00644
00645 g_return_if_fail
00646 (ctxt->cur_stmt
00647 &&
00648 (ctxt->cur_stmt->type == RULESET_STMT
00649 || ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT
00650 || ctxt->cur_stmt->type == AT_PAGE_RULE_STMT));
00651
00652 if (a_name) {
00653 str = g_string_new_len (a_name->str, a_name->len);
00654 g_return_if_fail (str);
00655 }
00656
00657
00658 decl = cr_declaration_new (ctxt->cur_stmt, str, a_expression);
00659 g_return_if_fail (decl);
00660 str = NULL;
00661 decl->important = a_important;
00662
00663
00664
00665
00666 switch (ctxt->cur_stmt->type) {
00667 case RULESET_STMT:
00668 decl2 = cr_declaration_append
00669 (ctxt->cur_stmt->kind.ruleset->decl_list, decl);
00670 if (!decl2) {
00671 cr_declaration_destroy (decl);
00672 cr_utils_trace_info
00673 ("Could not append decl to ruleset");
00674 goto error;
00675 }
00676 ctxt->cur_stmt->kind.ruleset->decl_list = decl2;
00677 decl = NULL;
00678 decl2 = NULL;
00679 break;
00680
00681 case AT_FONT_FACE_RULE_STMT:
00682 decl2 = cr_declaration_append
00683 (ctxt->cur_stmt->kind.font_face_rule->decl_list,
00684 decl);
00685 if (!decl2) {
00686 cr_declaration_destroy (decl);
00687 cr_utils_trace_info
00688 ("Could not append decl to ruleset");
00689 goto error;
00690 }
00691 ctxt->cur_stmt->kind.font_face_rule->decl_list = decl2;
00692 decl = NULL;
00693 decl2 = NULL;
00694 break;
00695 case AT_PAGE_RULE_STMT:
00696 decl2 = cr_declaration_append
00697 (ctxt->cur_stmt->kind.page_rule->decl_list, decl);
00698 if (!decl2) {
00699 cr_declaration_destroy (decl);
00700 cr_utils_trace_info
00701 ("Could not append decl to ruleset");
00702 goto error;
00703 }
00704 ctxt->cur_stmt->kind.page_rule->decl_list = decl2;
00705 decl = NULL;
00706 decl2 = NULL;
00707 break;
00708
00709 default:
00710 goto error;
00711 break;
00712 }
00713
00714 return;
00715
00716 error:
00717 if (str) {
00718 g_free (str);
00719 str = NULL;
00720 }
00721
00722 if (decl) {
00723 cr_declaration_destroy (decl);
00724 decl = NULL;
00725 }
00726 }
00727
00728 static void
00729 error (CRDocHandler * a_this)
00730 {
00731 enum CRStatus status = CR_OK;
00732 ParsingContext *ctxt = NULL;
00733 ParsingContext **ctxtptr = NULL;
00734
00735 g_return_if_fail (a_this);
00736 ctxtptr = &ctxt;
00737 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00738 g_return_if_fail (status == CR_OK && ctxt);
00739
00740 if (ctxt->cur_stmt) {
00741 cr_statement_destroy (ctxt->cur_stmt);
00742 ctxt->cur_stmt = NULL;
00743 }
00744 }
00745
00746 static void
00747 unrecoverable_error (CRDocHandler * a_this)
00748 {
00749 enum CRStatus status = CR_OK;
00750 ParsingContext *ctxt = NULL;
00751 ParsingContext **ctxtptr = NULL;
00752
00753 ctxtptr = &ctxt;
00754 status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr);
00755 g_return_if_fail (status == CR_OK);
00756
00757 if (ctxt) {
00758 if (ctxt->stylesheet) {
00759 status = cr_doc_handler_set_result
00760 (a_this, ctxt->stylesheet);
00761 g_return_if_fail (status == CR_OK);
00762 }
00763 g_free (ctxt);
00764 cr_doc_handler_set_ctxt (a_this, NULL);
00765 }
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 CROMParser *
00778 cr_om_parser_new (CRInput * a_input)
00779 {
00780 CROMParser *result = NULL;
00781 enum CRStatus status = CR_OK;
00782
00783 result = g_try_malloc (sizeof (CROMParser));
00784
00785 if (!result) {
00786 cr_utils_trace_info ("Out of memory");
00787 return NULL;
00788 }
00789
00790 memset (result, 0, sizeof (CROMParser));
00791 PRIVATE (result) = g_try_malloc (sizeof (CROMParserPriv));
00792
00793 if (!PRIVATE (result)) {
00794 cr_utils_trace_info ("Out of memory");
00795 goto error;
00796 }
00797
00798 memset (PRIVATE (result), 0, sizeof (CROMParserPriv));
00799
00800 PRIVATE (result)->parser = cr_parser_new_from_input (a_input);
00801
00802 if (!PRIVATE (result)->parser) {
00803 cr_utils_trace_info ("parsing instanciation failed");
00804 goto error;
00805 }
00806
00807 status = cr_om_parser_init_default_sac_handler (result);
00808
00809 if (status != CR_OK) {
00810 goto error;
00811 }
00812
00813 return result;
00814
00815 error:
00816
00817 if (result) {
00818 cr_om_parser_destroy (result);
00819 }
00820
00821 return NULL;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 enum CRStatus
00834 cr_om_parser_parse_buf (CROMParser * a_this,
00835 const guchar * a_buf,
00836 gulong a_len,
00837 enum CREncoding a_enc, CRStyleSheet ** a_result)
00838 {
00839
00840 enum CRStatus status = CR_OK;
00841
00842 g_return_val_if_fail (a_this && a_result, CR_BAD_PARAM_ERROR);
00843
00844 if (!PRIVATE (a_this)->parser) {
00845 PRIVATE (a_this)->parser = cr_parser_new (NULL);
00846 }
00847
00848 status = cr_parser_parse_buf (PRIVATE (a_this)->parser,
00849 a_buf, a_len, a_enc);
00850
00851 if (status == CR_OK) {
00852 CRStyleSheet *result = NULL;
00853 CRStyleSheet **resultptr = NULL;
00854 CRDocHandler *sac_handler = NULL;
00855
00856 cr_parser_get_sac_handler (PRIVATE (a_this)->parser,
00857 &sac_handler);
00858 g_return_val_if_fail (sac_handler, CR_ERROR);
00859 resultptr = &result;
00860 status = cr_doc_handler_get_result (sac_handler,
00861 (gpointer *) resultptr);
00862 g_return_val_if_fail (status == CR_OK, status);
00863
00864 if (result)
00865 *a_result = result;
00866 }
00867
00868 return status;
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 enum CRStatus
00880 cr_om_parser_simply_parse_buf (const guchar * a_buf,
00881 gulong a_len,
00882 enum CREncoding a_enc,
00883 CRStyleSheet ** a_result)
00884 {
00885 CROMParser *parser = NULL;
00886 enum CRStatus status = CR_OK;
00887
00888 parser = cr_om_parser_new (NULL);
00889 if (!parser) {
00890 cr_utils_trace_info ("Could not create om parser");
00891 cr_utils_trace_info ("System possibly out of memory");
00892 return CR_ERROR;
00893 }
00894
00895 status = cr_om_parser_parse_buf (parser, a_buf, a_len,
00896 a_enc, a_result);
00897
00898 if (parser) {
00899 cr_om_parser_destroy (parser);
00900 parser = NULL;
00901 }
00902
00903 return status;
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 enum CRStatus
00919 cr_om_parser_parse_file (CROMParser * a_this,
00920 const guchar * a_file_uri,
00921 enum CREncoding a_enc, CRStyleSheet ** a_result)
00922 {
00923 enum CRStatus status = CR_OK;
00924
00925 g_return_val_if_fail (a_this && a_file_uri && a_result,
00926 CR_BAD_PARAM_ERROR);
00927
00928 if (!PRIVATE (a_this)->parser) {
00929 PRIVATE (a_this)->parser = cr_parser_new_from_file
00930 (a_file_uri, a_enc);
00931 }
00932
00933 status = cr_parser_parse_file (PRIVATE (a_this)->parser,
00934 a_file_uri, a_enc);
00935
00936 if (status == CR_OK) {
00937 CRStyleSheet *result = NULL;
00938 CRStyleSheet **resultptr = NULL;
00939 CRDocHandler *sac_handler = NULL;
00940
00941 cr_parser_get_sac_handler (PRIVATE (a_this)->parser,
00942 &sac_handler);
00943 g_return_val_if_fail (sac_handler, CR_ERROR);
00944 resultptr = &result;
00945 status = cr_doc_handler_get_result
00946 (sac_handler, (gpointer *) resultptr);
00947 g_return_val_if_fail (status == CR_OK, status);
00948 if (result)
00949 *a_result = result;
00950 }
00951
00952 return status;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 enum CRStatus
00966 cr_om_parser_simply_parse_file (const guchar * a_file_path,
00967 enum CREncoding a_enc,
00968 CRStyleSheet ** a_result)
00969 {
00970 CROMParser *parser = NULL;
00971 enum CRStatus status = CR_OK;
00972
00973 parser = cr_om_parser_new (NULL);
00974 if (!parser) {
00975 cr_utils_trace_info ("Could not allocate om parser");
00976 cr_utils_trace_info ("System may be out of memory");
00977 return CR_ERROR;
00978 }
00979
00980 status = cr_om_parser_parse_file (parser, a_file_path,
00981 a_enc, a_result);
00982 if (parser) {
00983 cr_om_parser_destroy (parser);
00984 parser = NULL;
00985 }
00986
00987 return status;
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 enum CRStatus
01001 cr_om_parser_parse_paths_to_cascade (CROMParser * a_this,
01002 const guchar * a_author_path,
01003 const guchar * a_user_path,
01004 const guchar * a_ua_path,
01005 enum CREncoding a_encoding,
01006 CRCascade ** a_result)
01007 {
01008 enum CRStatus status = CR_OK;
01009
01010
01011 CRStyleSheet *sheets[3];
01012 guchar *paths[3];
01013 CRCascade *result = NULL;
01014 gint i = 0;
01015
01016 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
01017
01018 memset (sheets, 0, sizeof (CRStyleSheet) * 3);
01019 paths[0] = (guchar *) a_author_path;
01020 paths[1] = (guchar *) a_user_path;
01021 paths[2] = (guchar *) a_ua_path;
01022
01023 for (i = 0; i < 3; i++) {
01024 status = cr_om_parser_parse_file (a_this, paths[i],
01025 a_encoding, &sheets[i]);
01026 if (status != CR_OK) {
01027 if (sheets[i]) {
01028 cr_stylesheet_unref (sheets[i]);
01029 sheets[i] = NULL;
01030 }
01031 continue;
01032 }
01033 }
01034 result = cr_cascade_new (sheets[0], sheets[1], sheets[2]);
01035 if (!result) {
01036 for (i = 0; i < 3; i++) {
01037 cr_stylesheet_unref (sheets[i]);
01038 sheets[i] = 0;
01039 }
01040 return CR_ERROR;
01041 }
01042 *a_result = result;
01043 return CR_OK;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 enum CRStatus
01056 cr_om_parser_simply_parse_paths_to_cascade (const guchar * a_author_path,
01057 const guchar * a_user_path,
01058 const guchar * a_ua_path,
01059 enum CREncoding a_encoding,
01060 CRCascade ** a_result)
01061 {
01062 enum CRStatus status = CR_OK;
01063 CROMParser *parser = NULL;
01064
01065 parser = cr_om_parser_new (NULL);
01066 if (!parser) {
01067 cr_utils_trace_info ("could not allocated om parser");
01068 cr_utils_trace_info ("System may be out of memory");
01069 return CR_ERROR;
01070 }
01071 status = cr_om_parser_parse_paths_to_cascade (parser,
01072 a_author_path,
01073 a_user_path,
01074 a_ua_path,
01075 a_encoding, a_result);
01076 if (parser) {
01077 cr_om_parser_destroy (parser);
01078 parser = NULL;
01079 }
01080 return status;
01081 }
01082
01083
01084
01085
01086
01087 void
01088 cr_om_parser_destroy (CROMParser * a_this)
01089 {
01090 g_return_if_fail (a_this && PRIVATE (a_this));
01091
01092 if (PRIVATE (a_this)->parser) {
01093 cr_parser_destroy (PRIVATE (a_this)->parser);
01094 PRIVATE (a_this)->parser = NULL;
01095 }
01096
01097 if (PRIVATE (a_this)) {
01098 g_free (PRIVATE (a_this));
01099 PRIVATE (a_this) = NULL;
01100 }
01101
01102 if (a_this) {
01103 g_free (a_this);
01104 a_this = NULL;
01105 }
01106 }