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