Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

cr-om-parser.c

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

Generated on Wed Oct 1 01:36:46 2003 for Libcroco by doxygen 1.3.3