Logo Search packages:      
Sourcecode: inkscape version File versions

enum CRStatus cr_parser_parse_ruleset ( CRParser a_this  ) 

Parses a "ruleset" as defined in the css2 spec at appendix D.1. ruleset ::= selector [ ',' S* selector ]* '{' S* declaration? [ ';' S* declaration? ]* '}' S*;

This methods calls the the SAC handler on the relevant SAC handler callbacks whenever it encounters some specific constructions. See the documentation of CRDocHandler (the SAC handler) to know when which SAC handler is called.

Parameters:
a_this the "this pointer" of the current instance of CRParser.
Returns:
CR_OK upon successfull completion, an error code otherwise.

Definition at line 3246 of file cr-parser.c.

References CHECK_PARSING_STATUS, CHECK_PARSING_STATUS_ERR, cr_parser_clear_errors(), cr_parser_parse_declaration(), cr_parser_parse_selector(), cr_parser_try_to_skip_spaces_and_comments(), cr_term_ref(), cr_term_unref(), cr_tknzr_peek_char(), PEEK_NEXT_CHAR, READ_NEXT_CHAR, and RECORD_INITIAL_POS.

Referenced by cr_parser_parse_media(), cr_parser_parse_stylesheet(), and cr_statement_ruleset_parse_from_buf().

{
        enum CRStatus status = CR_OK;
        CRInputPos init_pos;
        guint32 cur_char = 0,
                next_char = 0;
        CRString *property = NULL;
        CRTerm *expr = NULL;
        CRSimpleSel *simple_sels = NULL;
        CRSelector *selector = NULL;
        gboolean start_selector = FALSE,
                is_important = FALSE;

        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);

        RECORD_INITIAL_POS (a_this, &init_pos);

        status = cr_parser_parse_selector (a_this, &selector);
        CHECK_PARSING_STATUS (status, FALSE);

        READ_NEXT_CHAR (a_this, &cur_char);

        ENSURE_PARSING_COND_ERR
                (a_this, cur_char == '{',
                 (guchar *)"while parsing rulset: current char should be '{'",
                 CR_SYNTAX_ERROR);

        if (PRIVATE (a_this)->sac_handler
            && PRIVATE (a_this)->sac_handler->start_selector) {
                /*
                 *the selector is ref counted so that the parser's user
                 *can choose to keep it.
                 */
                if (selector) {
                        cr_selector_ref (selector);
                }

                PRIVATE (a_this)->sac_handler->start_selector
                        (PRIVATE (a_this)->sac_handler, selector);
                start_selector = TRUE;
        }

        cr_parser_try_to_skip_spaces_and_comments (a_this);

        PRIVATE (a_this)->state = TRY_PARSE_RULESET_STATE;

        status = cr_parser_parse_declaration (a_this, &property,
                                              &expr,
                                              &is_important);
        if (expr) {
                cr_term_ref (expr);
        }
        if (status == CR_OK
            && PRIVATE (a_this)->sac_handler
            && PRIVATE (a_this)->sac_handler->property) {
                PRIVATE (a_this)->sac_handler->property
                        (PRIVATE (a_this)->sac_handler, property, expr,
                         is_important);
        }        
        if (status == CR_OK) {
                /*
                 *free the allocated
                 *'property' and 'term' before parsing
                 *next declarations.
                 */
                if (property) {
                        cr_string_destroy (property);
                        property = NULL;
                }
                if (expr) {
                        cr_term_unref (expr);
                        expr = NULL;
                }
        } else {/*status != CR_OK*/                
                guint32 c = 0 ;
                /*
                 *test if we have reached '}', which
                 *would mean that we are parsing an empty ruleset (eg. x{ })
                 *In that case, goto end_of_ruleset.
                 */
                status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, &c) ;
                if (status == CR_OK && c == '}') {
                        status = CR_OK ;
                        goto end_of_ruleset ;
                }
        }
        CHECK_PARSING_STATUS_ERR
                (a_this, status, FALSE,
                 (guchar *)"while parsing ruleset: next construction should be a declaration",
                 CR_SYNTAX_ERROR);

        for (;;) {
                PEEK_NEXT_CHAR (a_this, &next_char);
                if (next_char != ';')
                        break;

                /*consume the ';' char */
                READ_NEXT_CHAR (a_this, &cur_char);

                cr_parser_try_to_skip_spaces_and_comments (a_this);

                status = cr_parser_parse_declaration (a_this, &property,
                                                      &expr, &is_important);

                if (expr) {
                        cr_term_ref (expr);
                }
                if (status == CR_OK
                    && PRIVATE (a_this)->sac_handler
                    && PRIVATE (a_this)->sac_handler->property) {
                        PRIVATE (a_this)->sac_handler->property
                                (PRIVATE (a_this)->sac_handler,
                                 property, expr, is_important);
                }
                if (property) {
                        cr_string_destroy (property);
                        property = NULL;
                }
                if (expr) {
                        cr_term_unref (expr);
                        expr = NULL;
                }
        }

 end_of_ruleset:
        cr_parser_try_to_skip_spaces_and_comments (a_this);
        READ_NEXT_CHAR (a_this, &cur_char);
        ENSURE_PARSING_COND_ERR
                (a_this, cur_char == '}',
                 (guchar *)"while parsing rulset: current char must be a '}'",
                 CR_SYNTAX_ERROR);

        if (PRIVATE (a_this)->sac_handler
            && PRIVATE (a_this)->sac_handler->end_selector) {
                PRIVATE (a_this)->sac_handler->end_selector
                        (PRIVATE (a_this)->sac_handler, selector);
                start_selector = FALSE;
        }

        if (expr) {
                cr_term_unref (expr);
                expr = NULL;
        }

        if (simple_sels) {
                cr_simple_sel_destroy (simple_sels);
                simple_sels = NULL;
        }

        if (selector) {
                cr_selector_unref (selector);
                selector = NULL;
        }

        cr_parser_clear_errors (a_this);
        PRIVATE (a_this)->state = RULESET_PARSED_STATE;

        return CR_OK;

 error:
        if (start_selector == TRUE
            && PRIVATE (a_this)->sac_handler
            && PRIVATE (a_this)->sac_handler->error) {
                PRIVATE (a_this)->sac_handler->error
                        (PRIVATE (a_this)->sac_handler);
        }
        if (expr) {
                cr_term_unref (expr);
                expr = NULL;
        }
        if (simple_sels) {
                cr_simple_sel_destroy (simple_sels);
                simple_sels = NULL;
        }
        if (property) {
                cr_string_destroy (property);
        }
        if (selector) {
                cr_selector_unref (selector);
                selector = NULL;
        }

        cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos);

        return status;
}


Generated by  Doxygen 1.6.0   Back to index