diff options
author | dodji <dodji@seketeli.org> | 2003-06-16 23:54:31 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@src.gnome.org> | 2003-06-16 23:54:31 +0000 |
commit | 5d526f8953f29f41d58de76f49314d72e3ccc919 (patch) | |
tree | e4b2c38f9b927c56306644ef773bb5d27c48de0b | |
parent | 359c7d2721532d0726e0882e178ab057bc046215 (diff) | |
download | libcroco-5d526f8953f29f41d58de76f49314d72e3ccc919.tar.gz |
coded a first version of cr_statement_at_media_rule_parse_from_buf(). This
2003-06-17 dodji <dodji@seketeli.org>
* src/parser/cr-statement.[hc]:
coded a first version of cr_statement_at_media_rule_parse_from_buf().
This took the writing of a couple a SAC callback. Pfffew, SAC is a rather
tedious api. cr_statement_at_media_rule_parse_from_buf() does not
work yet, I still have to debug it.
* src/parser/cr-parser.c: use the new cr_tknzr_peek_byte2 () function
in the cr_parser_parse_import() method. This is a cleaner, smaller and
faster than the older approach.
* src/parser/cr-om-parser.c: use the
cr_dup_glist_of_string () helper fonction in the
start media callback.
* src/parser/cr-utils.[ch]: fixed some 'const' omissions here also.
* src/parser/cr-enc-handler.[ch]:
fixed some "const" omissions.
2003-06-16 dodji <dodji@seketeli.org>
* src/parser/cr-parser.[ch]: cr_parser_parse_charset(),
cr_parser_parse_import(), cr_parser_parse_page (),
cr_parser_parse_font_face(), cr_parser_parse_media(),
* src/parser/cr-tknzr.[ch]:
added cr_tknzr_peek_byte2() function to export the functionalities
of cr_input_peek_byte2().
Dodji.
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | src/parser/cr-enc-handler.h | 12 | ||||
-rw-r--r-- | src/parser/cr-om-parser.c | 11 | ||||
-rw-r--r-- | src/parser/cr-parser.c | 2175 | ||||
-rw-r--r-- | src/parser/cr-parser.h | 16 | ||||
-rw-r--r-- | src/parser/cr-statement.c | 210 | ||||
-rw-r--r-- | src/parser/cr-statement.h | 10 | ||||
-rw-r--r-- | src/parser/cr-tknzr.c | 22 | ||||
-rw-r--r-- | src/parser/cr-tknzr.h | 4 | ||||
-rw-r--r-- | src/parser/cr-utils.c | 93 | ||||
-rw-r--r-- | src/parser/cr-utils.h | 54 |
12 files changed, 1483 insertions, 1159 deletions
@@ -1,3 +1,34 @@ +2003-06-17 dodji <dodji@seketeli.org> + + * src/parser/cr-statement.[hc]: + coded a first version of cr_statement_at_media_rule_parse_from_buf(). + This took the writing of a couple a SAC callback. Pfffew, SAC is a rather + tedious api. cr_statement_at_media_rule_parse_from_buf() does not + work yet, I still have to debug it. + + * src/parser/cr-parser.c: use the new cr_tknzr_peek_byte2 () function + in the cr_parser_parse_import() method. This is a cleaner, smaller and + faster than the older approach. + + * src/parser/cr-om-parser.c: use the + cr_dup_glist_of_string () helper fonction in the + start media callback. + + * src/parser/cr-utils.[ch]: fixed some 'const' omissions here also. + + * src/parser/cr-enc-handler.[ch]: + fixed some "const" omissions. + +2003-06-16 dodji <dodji@seketeli.org> + + * src/parser/cr-parser.[ch]: cr_parser_parse_charset(), + cr_parser_parse_import(), cr_parser_parse_page (), + cr_parser_parse_font_face(), cr_parser_parse_media(), + + * src/parser/cr-tknzr.[ch]: + added cr_tknzr_peek_byte2() function to export the functionalities + of cr_input_peek_byte2(). + 2003-06-15 dodji <dodji@seketeli.org> * tests/test4-main.c: updated this to test the new @@ -1,7 +1,9 @@ *coding:) -Provide support for font selection. (hard) +test/debug the new cr_statement_at_media_rule_parse_from_buf(). + +Provide support for font selection. (hard, started well underway.) First make sure to be able to gather all the font related property values. Then, figure out how to implement a font selector that uses pango. diff --git a/src/parser/cr-enc-handler.h b/src/parser/cr-enc-handler.h index d9bc42b..8155833 100644 --- a/src/parser/cr-enc-handler.h +++ b/src/parser/cr-enc-handler.h @@ -40,24 +40,24 @@ G_BEGIN_DECLS typedef struct _CREncHandler CREncHandler ; -typedef enum CRStatus (*CREncInputFunc) (guchar * a_in, +typedef enum CRStatus (*CREncInputFunc) (const guchar * a_in, gulong *a_in_len, guchar *a_out, gulong *a_out_len) ; -typedef enum CRStatus (*CREncOutputFunc) (guchar * a_in, +typedef enum CRStatus (*CREncOutputFunc) (const guchar * a_in, gulong *a_in_len, guchar *a_out, gulong *a_out_len) ; typedef enum CRStatus (*CREncInputStrLenAsUtf8Func) -(guchar *a_in_start, - guchar *a_in_end, +(const guchar *a_in_start, + const guchar *a_in_end, gulong *a_in_size); typedef enum CRStatus (*CREncUtf8StrLenAsOutputFunc) -(guchar *a_in_start, - guchar *a_in_end, +(const guchar *a_in_start, + const guchar *a_in_end, gulong *a_in_size) ; /** diff --git a/src/parser/cr-om-parser.c b/src/parser/cr-om-parser.c index c2c007a..0bceb4c 100644 --- a/src/parser/cr-om-parser.c +++ b/src/parser/cr-om-parser.c @@ -472,16 +472,7 @@ start_media (CRDocHandler *a_this, GList *a_media_list) GList *cur = NULL ; /*duplicate the media_list*/ - for (cur = a_media_list; cur ; cur = cur->next) - { - GString *str = NULL ; - - str = g_string_new_len (((GString*)cur->data)->str, - ((GString*)cur->data)->len) ; - if (str) - media_list = g_list_append (media_list, - str) ; - } + media_list = cr_dup_glist_of_string (a_media_list) ; } ctxt->cur_media_stmt = diff --git a/src/parser/cr-parser.c b/src/parser/cr-parser.c index e88906d..2686199 100644 --- a/src/parser/cr-parser.c +++ b/src/parser/cr-parser.c @@ -271,6 +271,8 @@ status = cr_tknzr_peek_byte (PRIVATE (a_this)->tknzr, \ a_byte_ptr) ; \ CHECK_PARSING_STATUS (status, TRUE) ; +#define BYTE(a_parser, a_offset, a_eof) \ +cr_tknzr_peek_byte2 (PRIVATE (a_this)->tknzr, a_offset, a_eof) /** *Reads a byte from the topmost parser input @@ -2701,938 +2703,6 @@ cr_parser_parse_simple_sels (CRParser *a_this, CRSimpleSel **a_sel) return status ; } -/** - *Parses a charset declaration as defined implictly by the css2 spec in - *appendix D.1: - *charset ::= CHARSET_SYM S* STRING S* ';' - * - *@param a_this the "this pointer" of the current instance of #CRParser. - *@param a_value out parameter. The actual parsed value of the charset - *declararation. - *@return CR_OK upon successfull completion, an error code otherwise. - */ -static enum CRStatus -cr_parser_parse_charset (CRParser *a_this, GString **a_value) -{ - enum CRStatus status = CR_OK ; - CRInputPos init_pos ; - CRToken *token = NULL ; - GString *charset_str = NULL ; - - g_return_val_if_fail (a_this && a_value - && (*a_value == NULL), - CR_BAD_PARAM_ERROR) ; - - RECORD_INITIAL_POS (a_this, &init_pos) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - - ENSURE_PARSING_COND (status == CR_OK - && token && token->type == CHARSET_SYM_TK) ; - - cr_token_destroy (token) ; - token = NULL ; - - PRIVATE (a_this)->state = TRY_PARSE_CHARSET_STATE ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token && token->type == STRING_TK) ; - charset_str = token->u.str ; - token->u.str = NULL ; - cr_token_destroy (token) ; - token = NULL ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - - ENSURE_PARSING_COND (status == CR_OK - && token && token->type == SEMICOLON_TK) ; - cr_token_destroy (token) ; - token = NULL ; - - if (charset_str) - { - *a_value = charset_str ; - } - - PRIVATE (a_this)->state = CHARSET_PARSED_STATE ; - return CR_OK ; - - error: - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - if (*a_value) - { - g_string_free (*a_value, TRUE) ; - *a_value = NULL ; - } - - cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, - &init_pos) ; - - return status ; -} - - -/** - *Parses an 'import' declaration as defined in the css2 spec - *in appendix D.1: - * - *import ::= - *@import [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S* - * - *@param a_this the "this pointer" of the current instance - *of #CRParser. - * - *@param a_medium_list out parameter. A linked list of - *GString (see the doc of glib-2). - *Each GString is a string that contains - *a 'medium' declaration part of the successfully - *parsed 'import' declaration. - * - *@param a_import_string out parameter. - *A string that contains the 'import - *string". The import string can be either an uri (if it starts with - *the substring "uri(") or a any other css2 string. Note that - * *a_import_string must be initially set to NULL or else, this function - *will return CR_BAD_PARAM_ERROR. - * - *@return CR_OK upon sucessfull completion, an error code otherwise. - */ -static enum CRStatus -cr_parser_parse_import (CRParser *a_this, GList ** a_media_list, - GString **a_import_string) -{ - enum CRStatus status = CR_OK ; - CRInputPos init_pos ; - guint32 cur_char = 0, next_char = 0 ; - guchar next_bytes[CHARS_TAB_SIZE] = {0} ; - GString *medium = NULL ; - - g_return_val_if_fail (a_this - && a_import_string - && (*a_import_string == NULL), - CR_BAD_PARAM_ERROR) ; - - RECORD_INITIAL_POS (a_this, &init_pos) ; - - PEEK_BYTE (a_this, 1, &next_bytes[0]) ; - PEEK_BYTE (a_this, 2, &next_bytes[1]) ; - PEEK_BYTE (a_this, 3, &next_bytes[2]) ; - PEEK_BYTE (a_this, 4, &next_bytes[3]) ; - PEEK_BYTE (a_this, 5, &next_bytes[4]) ; - PEEK_BYTE (a_this, 6, &next_bytes[5]) ; - PEEK_BYTE (a_this, 7, &next_bytes[6]) ; - - if (next_bytes[0] == '@' - && next_bytes[1] == 'i' - && next_bytes[2] == 'm' - && next_bytes[3] == 'p' - && next_bytes[4] == 'o' - && next_bytes[5] == 'r' - && next_bytes[6] == 't') - { - SKIP_CHARS (a_this, 7) ; - status = CR_OK ; - } - else - { - status = CR_PARSING_ERROR ; - goto error ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - PRIVATE (a_this)->state = TRY_PARSE_IMPORT_STATE ; - - PEEK_NEXT_CHAR (a_this, &next_char) ; - - if (next_char == '"' || next_char == '\'') - { - status = cr_parser_parse_string - (a_this, a_import_string) ; - - CHECK_PARSING_STATUS (status, FALSE) ; - } - else - { - status = cr_parser_parse_uri - (a_this, a_import_string) ; - - CHECK_PARSING_STATUS (status, FALSE) ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_parser_parse_ident (a_this, &medium) ; - - if (status == CR_OK && medium) - { - *a_media_list = g_list_append (*a_media_list, - medium) ; - medium = NULL ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - for (;status == CR_OK;) - { - PEEK_NEXT_CHAR (a_this, &next_char) ; - - if (next_char == ',') - { - READ_NEXT_CHAR (a_this, &cur_char) ; - } - else - { - break ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_parser_parse_ident (a_this, - &medium) ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - if ((status == CR_OK) && medium) - { - *a_media_list = g_list_append - (*a_media_list, medium) ; - - medium = NULL ; - } - - CHECK_PARSING_STATUS (status, FALSE) ; - - READ_NEXT_CHAR (a_this, &cur_char) ; - - ENSURE_PARSING_COND (cur_char == ';') ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - } - - cr_parser_clear_errors (a_this) ; - PRIVATE (a_this)->state = IMPORT_PARSED_STATE ; - - return CR_OK ; - - error: - - if (*a_media_list) - { - GList *cur = NULL ; - /* - *free each element of *a_media_list. - *Note that each element of *a_medium list *must* - *be a GString* or else, the code that is coming next - *will corrupt the memory and lead to hard to debug - *random crashes. - *This is where C++ and its compile time - *type checking mecanism (through STL containers) would - *have prevented us to go through this hassle. - */ - for (cur = *a_media_list; cur ; cur = cur->next) - { - if (cur->data) - { - g_string_free (cur->data, TRUE) ; - } - } - - g_list_free (*a_media_list) ; - *a_media_list = NULL ; - } - - if (*a_import_string) - { - g_string_free (*a_import_string, TRUE) ; - *a_import_string = NULL ; - } - - if (medium) - { - g_string_free (medium, TRUE) ; - medium = NULL ; - } - - cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; - - return status ; -} - -/** - *Parses a 'media' declaration as specified in the css2 spec at - *appendix D.1: - * - *media ::= @media S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S* - * - *@param a_this the "this pointer" of the current instance of #CRParser. - *@return CR_OK upon successfull completion, an error code otherwise. - */ -static enum CRStatus -cr_parser_parse_media (CRParser *a_this) -{ - enum CRStatus status = CR_OK ; - CRInputPos init_pos ; - CRToken * token = NULL ; - guint32 next_char = 0, cur_char = 0 ; - GString * medium = NULL ; - GList *media_list = NULL ; - - g_return_val_if_fail (a_this && PRIVATE (a_this), - CR_BAD_PARAM_ERROR) ; - - RECORD_INITIAL_POS (a_this, &init_pos) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == MEDIA_SYM_TK) ; - - cr_token_destroy (token) ; - token = NULL ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token && token->type == IDENT_TK) ; - - medium = token->u.str ; - token->u.str = NULL ; - cr_token_destroy (token) ; - token = NULL ; - - if (medium) - { - media_list = g_list_append (media_list, medium) ; - medium = NULL ; - } - - for (;status == CR_OK;) - { - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - PEEK_NEXT_CHAR (a_this, &next_char) ; - - if (next_char == ',') - { - READ_NEXT_CHAR (a_this, &cur_char) ; - } - else - { - break ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_parser_parse_ident (a_this, &medium) ; - - CHECK_PARSING_STATUS (status, FALSE) ; - - if (medium) - { - media_list = g_list_append (media_list, - medium) ; - medium = NULL ; - } - } - - READ_NEXT_CHAR (a_this, &cur_char) ; - - ENSURE_PARSING_COND (cur_char == '{') ; - - /* - *call the SAC handler api here. - */ - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->start_media) - { - PRIVATE (a_this)->sac_handler->start_media - (PRIVATE (a_this)->sac_handler, media_list) ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - PRIVATE (a_this)->state = TRY_PARSE_MEDIA_STATE ; - - for (;status == CR_OK;) - { - status = cr_parser_parse_ruleset (a_this) ; - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - } - - READ_NEXT_CHAR (a_this, &cur_char) ; - - ENSURE_PARSING_COND (cur_char == '}') ; - - /* - *call the right SAC handler api here. - */ - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->end_media) - { - PRIVATE (a_this)->sac_handler->end_media - (PRIVATE (a_this)->sac_handler, - media_list) ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - /* - *Then, free the data structures passed to - *the last call to the SAC handler. - */ - if (medium) - { - g_string_free (medium, TRUE) ; - medium = NULL ; - } - - if (media_list) - { - GList *cur = NULL ; - - for (cur = media_list ; cur ; cur = cur->next) - { - g_string_free (cur->data, TRUE) ; - } - - g_list_free (media_list) ; - media_list = NULL ; - } - - - cr_parser_clear_errors (a_this) ; - PRIVATE (a_this)->state = MEDIA_PARSED_STATE ; - - return CR_OK ; - - error: - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - if (medium) - { - g_string_free (medium, TRUE) ; - medium = NULL ; - } - - if (media_list) - { - GList *cur = NULL ; - - for (cur = media_list ; cur ; cur = cur->next) - { - g_string_free (cur->data, TRUE) ; - } - - g_list_free (media_list) ; - media_list = NULL ; - } - - cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); - - return status ; -} - - -/** - *Parses '@page' rule as specified in the css2 spec in appendix D.1: - *page ::= PAGE_SYM S* IDENT? pseudo_page? S* - *'{' S* declaration [ ';' S* declaration ]* '}' S* - * - *This function also calls the relevant SAC handlers whenever it - *encounters a construction that must - *be reported to the calling application. - *@param a_this the "this pointer" of the current instance of #CRParser. - *@return CR_OK upon successfull completion, an error code otherwise. - */ -static enum CRStatus -cr_parser_parse_page (CRParser *a_this) -{ - enum CRStatus status = CR_OK ; - CRInputPos init_pos ; - CRToken * token = NULL ; - CRTerm * css_expression = NULL ; - GString *page_selector = NULL, - *page_pseudo_class = NULL, - *property = NULL ; - - g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; - - RECORD_INITIAL_POS (a_this, &init_pos) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == PAGE_SYM_TK) ; - - cr_token_destroy (token) ; - token = NULL ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK && token) ; - - if (token->type == IDENT_TK) - { - page_selector = token->u.str ; - token->u.str = NULL ; - cr_token_destroy (token) ; - token = NULL ; - } - else - { - cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, - token) ; - token = NULL ; - } - - /* - *try to parse pseudo_page - */ - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token) ; - - if (token->type == DELIM_TK && token->u.unichar == ':') - { - cr_token_destroy (token) ; - token = NULL ; - status = cr_parser_parse_ident (a_this, &page_pseudo_class) ; - CHECK_PARSING_STATUS (status, FALSE) ; - } - else - { - cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token) ; - token = NULL ; - } - - /* - *parse_block - * - */ - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == CBO_TK) ; - - cr_token_destroy (token) ; token = NULL ; - - /* - *Call the appropriate SAC handler here. - */ - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->start_page) - { - PRIVATE (a_this)->sac_handler->start_page - (PRIVATE (a_this)->sac_handler, - page_selector, page_pseudo_class) ; - } - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - PRIVATE (a_this)->state = TRY_PARSE_PAGE_STATE ; - - status = cr_parser_parse_declaration (a_this, &property, - &css_expression) ; - - /* - *call the relevant SAC handler here... - */ - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->property) - { - cr_term_ref (css_expression) ; - PRIVATE (a_this)->sac_handler->property - (PRIVATE (a_this)->sac_handler, - property, - css_expression) ; - } - - /* - *... and free the data structure passed to that last - *SAC handler. - */ - - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_unref (css_expression) ; - css_expression = NULL ; - } - - for (;;) - { - /*parse the other ';' separated declarations*/ - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - status = cr_tknzr_get_next_token - (PRIVATE (a_this)->tknzr, &token) ; - - ENSURE_PARSING_COND (status == CR_OK && token) ; - - if (token->type != SEMICOLON_TK) break ; - - cr_token_destroy (token) ; - token = NULL ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_parser_parse_declaration (a_this, &property, - &css_expression) ; - CHECK_PARSING_STATUS (status, FALSE) ; - - /* - *call the relevant SAC handler here... - */ - - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->property) - { - cr_term_ref (css_expression) ; - PRIVATE (a_this)->sac_handler->property - (PRIVATE (a_this)->sac_handler, - property, - css_expression) ; - } - - /* - *... and free the data structure passed to that last - *SAC handler. - */ - - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_unref (css_expression) ; - css_expression = NULL ; - } - } - - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == CBC_TK) ; - - cr_token_destroy (token) ; token = NULL ; - - - /* - *call the relevant SAC handler here. - */ - if (PRIVATE (a_this)->sac_handler - && PRIVATE (a_this)->sac_handler->end_page) - { - PRIVATE (a_this)->sac_handler->end_page - (PRIVATE (a_this)->sac_handler, - page_selector, page_pseudo_class) ; - } - - if (page_selector) - { - g_string_free (page_selector, TRUE) ; - page_selector = NULL ; - } - - if (page_pseudo_class) - { - g_string_free (page_pseudo_class, TRUE) ; - page_pseudo_class = NULL ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - /*here goes the former implem of this function ...*/ - - cr_parser_clear_errors (a_this) ; - PRIVATE (a_this)->state = PAGE_PARSED_STATE ; - - return CR_OK ; - - error: - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - if (page_selector) - { - g_string_free (page_selector, TRUE) ; - page_selector = NULL ; - } - - if (page_pseudo_class) - { - g_string_free (page_pseudo_class, TRUE) ; - page_pseudo_class = NULL ; - } - - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_destroy (css_expression) ; - css_expression = NULL ; - } - - cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; - - return status ; -} - - -/** - *Parses the "@font-face" rule specified in the css1 spec in - *appendix D.1: - * - *font_face ::= FONT_FACE_SYM S* - *'{' S* declaration [ ';' S* declaration ]* '}' S* - * - *This function will call SAC handlers whenever it is necessary. - *@return CR_OK upon successfull completion, an error code otherwise. - */ -static enum CRStatus -cr_parser_parse_font_face (CRParser *a_this) -{ - enum CRStatus status = CR_ERROR ; - CRInputPos init_pos ; - GString *property = NULL ; - CRTerm * css_expression = NULL ; - CRToken *token = NULL ; - guint32 next_char = 0, cur_char = 0 ; - - g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; - - RECORD_INITIAL_POS (a_this, &init_pos) ; - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == FONT_FACE_SYM_TK) ; - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, - &token) ; - ENSURE_PARSING_COND (status == CR_OK - && token - && token->type == CBO_TK) ; - - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - /* - *here, call the relevant SAC handler. - */ - - if (PRIVATE (a_this)->sac_handler->start_font_face) - { - PRIVATE (a_this)->sac_handler->start_font_face - (PRIVATE (a_this)->sac_handler) ; - } - - PRIVATE (a_this)->state = TRY_PARSE_FONT_FACE_STATE ; - - /* - *and resume the parsing. - */ - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - - status = cr_parser_parse_declaration (a_this, &property, - &css_expression) ; - - if (status == CR_OK) - { - /* - *here, call the relevant SAC handler. - */ - cr_term_ref (css_expression) ; - - if (PRIVATE (a_this)->sac_handler->property) - { - PRIVATE (a_this)->sac_handler->property - (PRIVATE (a_this)->sac_handler, - property, css_expression) ; - } - ENSURE_PARSING_COND (css_expression && property) ; - } - - /*free the data structures allocated during last parsing.*/ - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_unref (css_expression) ; - css_expression = NULL ; - } - - for (;;) - { - PEEK_NEXT_CHAR (a_this, &next_char) ; - - if (next_char == ';') - { - READ_NEXT_CHAR (a_this, &cur_char) ; - } - else - { - break ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - status = cr_parser_parse_declaration (a_this, &property, - &css_expression) ; - - if (status != CR_OK) break ; - - /* - *here, call the relevant SAC handler. - */ - cr_term_ref (css_expression) ; - - if (PRIVATE (a_this)->sac_handler->property) - { - PRIVATE (a_this)->sac_handler->property - (PRIVATE (a_this)->sac_handler, - property, css_expression) ; - } - - /* - *Then, free the data structures allocated during - *last parsing. - */ - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_unref (css_expression) ; - css_expression = NULL ; - } - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - READ_NEXT_CHAR (a_this, &cur_char) ; - - ENSURE_PARSING_COND (cur_char == '}') ; - - /* - *here, call the relevant SAC handler. - */ - - if (PRIVATE (a_this)->sac_handler->end_font_face) - { - PRIVATE (a_this)->sac_handler->end_font_face - (PRIVATE (a_this)->sac_handler) ; - } - - cr_parser_try_to_skip_spaces_and_comments (a_this) ; - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - cr_parser_clear_errors (a_this) ; - - PRIVATE (a_this)->state = FONT_FACE_PARSED_STATE ; - - return CR_OK ; - - error: - - if (token) - { - cr_token_destroy (token) ; - token = NULL ; - } - - if (property) - { - g_string_free (property, TRUE) ; - property = NULL ; - } - - if (css_expression) - { - cr_term_destroy (css_expression) ; - css_expression = NULL ; - } - - cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; - - return status ; -} static enum CRStatus @@ -4515,6 +3585,240 @@ cr_parser_parse_stylesheet (CRParser *a_this) *Public CRParser Methods ****************************************/ + +/** + *Creates a new parser to parse data + *coming the input stream given in parameter. + *@param a_input the input stream of the parser. + *Note that the newly created parser will ref + *a_input and unref it when parsing reaches the + *end of the input stream. + *@return the newly created instance of #CRParser, + *or NULL if an error occured. + */ +CRParser * +cr_parser_new (CRTknzr *a_tknzr) +{ + CRParser * result = NULL ; + enum CRStatus status = CR_OK ; + + result = g_malloc0 (sizeof (CRParserInput)) ; + + PRIVATE (result) = g_malloc0 (sizeof (CRParserPriv)) ; + + if (a_tknzr) + { + status = cr_parser_set_tknzr (result, a_tknzr) ; + } + + g_return_val_if_fail (status == CR_OK, NULL) ; + + return result ; +} + + +/** + *Instanciates a new parser from a memory buffer. + *@param a_buf the buffer to parse. + *@param a_len the length of the data in the buffer. + *@param a_enc the encoding of the input buffer a_buf. + *@param a_free_buf if set to TRUE, a_buf will be freed + *during the destruction of the newly built instance + *of #CRParser. If set to FALSE, it is up to the caller to + *eventually free it. + *@return the newly built parser, or NULL if an error arises. + */ +CRParser * +cr_parser_new_from_buf (const guchar *a_buf, + gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) +{ + CRParser * result = NULL ; + CRInput *input = NULL ; + g_return_val_if_fail (a_buf && a_len, NULL) ; + + input = cr_input_new_from_buf (a_buf, a_len, a_enc, + a_free_buf) ; + g_return_val_if_fail (input, NULL) ; + + result = cr_parser_new_from_input (input) ; + if (!result) + { + cr_input_destroy (input) ; + input = NULL ; + return NULL ; + } + return result ; +} + +CRParser * +cr_parser_new_from_input (CRInput *a_input) +{ + CRParser *result = NULL ; + CRTknzr *tokenizer = NULL ; + + if (a_input) + { + tokenizer = cr_tknzr_new (a_input) ; + g_return_val_if_fail (tokenizer, NULL) ; + } + + result = cr_parser_new (tokenizer) ; + g_return_val_if_fail (result, NULL) ; + + return result ; +} + + +CRParser * +cr_parser_new_from_file (const guchar *a_file_uri, + enum CREncoding a_enc) +{ + CRParser *result = NULL ; + CRTknzr *tokenizer = NULL ; + + tokenizer = cr_tknzr_new_from_uri (a_file_uri, a_enc) ; + if (!tokenizer) + { + cr_utils_trace_info ("Could not open input file") ; + return NULL ; + } + + result = cr_parser_new (tokenizer) ; + g_return_val_if_fail (result, NULL) ; + return result ; +} + + +/** + *Sets a SAC document handler to the parser. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_handler the handler to set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_sac_handler (CRParser *a_this, CRDocHandler *a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + if (PRIVATE (a_this)->sac_handler) + { + cr_doc_handler_unref (PRIVATE (a_this)->sac_handler) ; + } + + PRIVATE (a_this)->sac_handler = a_handler ; + cr_doc_handler_ref (a_handler) ; + + return CR_OK ; +} + + +/** + *Gets the SAC document handler. + *@param a_this the "this pointer" of the current instance of + *#CRParser. + *@param a_handler out parameter. The returned handler. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_parser_get_sac_handler (CRParser *a_this, CRDocHandler **a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + *a_handler = PRIVATE (a_this)->sac_handler ; + + return CR_OK ; +} + + +/** + *Sets the SAC handler associated to the current instance + *of #CRParser to the default SAC handler. + *@param a_this a pointer to the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_default_sac_handler (CRParser *a_this) +{ + CRDocHandler *default_sac_handler = NULL ; + enum CRStatus status = CR_ERROR ; + + g_return_val_if_fail (a_this && PRIVATE (a_this), + CR_BAD_PARAM_ERROR) ; + + default_sac_handler = cr_doc_handler_new () ; + + cr_doc_handler_set_default_sac_handler (default_sac_handler) ; + + status = cr_parser_set_sac_handler (a_this, default_sac_handler) ; + + if (status != CR_OK) + { + cr_doc_handler_destroy (default_sac_handler) ; + default_sac_handler = NULL ; + } + + return status ; +} + + +enum CRStatus +cr_parser_set_use_core_grammar (CRParser *a_this, + gboolean a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), + CR_BAD_PARAM_ERROR) ; + + PRIVATE (a_this)->use_core_grammar = a_use_core_grammar ; + + return CR_OK ; +} + +enum CRStatus +cr_parser_get_use_core_grammar (CRParser *a_this, + gboolean *a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), + CR_BAD_PARAM_ERROR) ; + + *a_use_core_grammar = PRIVATE (a_this)->use_core_grammar ; + + return CR_OK ; +} + +/** + *Parses a the given in parameter. + *@param a_this a pointer to the current instance of #CRParser. + *@param a_file_uri the uri to the file to load. For the time being, + *only local files are supported. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_file (CRParser *a_this, + const guchar *a_file_uri, + enum CREncoding a_enc) +{ + enum CRStatus status = CR_ERROR ; + CRTknzr *tknzr = NULL ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_file_uri, + CR_BAD_PARAM_ERROR) ; + + tknzr = cr_tknzr_new_from_uri (a_file_uri, a_enc) ; + + g_return_val_if_fail (tknzr != NULL, CR_ERROR) ; + + status = cr_parser_set_tknzr (a_this, tknzr) ; + g_return_val_if_fail (status == CR_OK, CR_ERROR) ; + + status = cr_parser_parse (a_this) ; + + return status ; +} + /** *Parses a "declaration" as defined by the css2 spec in appendix D.1: *declaration ::= [property ':' S* expr prio?]? @@ -4820,207 +4124,944 @@ cr_parser_parse_ruleset (CRParser *a_this) return status ; } + /** - *Creates a new parser to parse data - *coming the input stream given in parameter. - *@param a_input the input stream of the parser. - *Note that the newly created parser will ref - *a_input and unref it when parsing reaches the - *end of the input stream. - *@return the newly created instance of #CRParser, - *or NULL if an error occured. + *Parses an 'import' declaration as defined in the css2 spec + *in appendix D.1: + * + *import ::= + *@import [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S* + * + *@param a_this the "this pointer" of the current instance + *of #CRParser. + * + *@param a_medium_list out parameter. A linked list of + *GString (see the doc of glib-2). + *Each GString is a string that contains + *a 'medium' declaration part of the successfully + *parsed 'import' declaration. + * + *@param a_import_string out parameter. + *A string that contains the 'import + *string". The import string can be either an uri (if it starts with + *the substring "uri(") or a any other css2 string. Note that + * *a_import_string must be initially set to NULL or else, this function + *will return CR_BAD_PARAM_ERROR. + * + *@return CR_OK upon sucessfull completion, an error code otherwise. */ -CRParser * -cr_parser_new (CRTknzr *a_tknzr) +enum CRStatus +cr_parser_parse_import (CRParser *a_this, GList ** a_media_list, + GString **a_import_string) { - CRParser * result = NULL ; enum CRStatus status = CR_OK ; + CRInputPos init_pos ; + guint32 cur_char = 0, next_char = 0 ; + GString *medium = NULL ; - result = g_malloc0 (sizeof (CRParserInput)) ; + g_return_val_if_fail (a_this + && a_import_string + && (*a_import_string == NULL), + CR_BAD_PARAM_ERROR) ; - PRIVATE (result) = g_malloc0 (sizeof (CRParserPriv)) ; + RECORD_INITIAL_POS (a_this, &init_pos) ; + + if (BYTE (a_this, 1, NULL) == '@' + && BYTE (a_this, 2, NULL) == 'i' + && BYTE (a_this, 3, NULL) == 'm' + && BYTE (a_this, 4, NULL) == 'p' + && BYTE (a_this, 5, NULL) == 'o' + && BYTE (a_this, 6, NULL) == 'r' + && BYTE (a_this, 7, NULL) == 't') + { + SKIP_CHARS (a_this, 7) ; + status = CR_OK ; + } + else + { + status = CR_PARSING_ERROR ; + goto error ; + } - if (a_tknzr) + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + PRIVATE (a_this)->state = TRY_PARSE_IMPORT_STATE ; + + PEEK_NEXT_CHAR (a_this, &next_char) ; + + if (next_char == '"' || next_char == '\'') + { + status = cr_parser_parse_string + (a_this, a_import_string) ; + + CHECK_PARSING_STATUS (status, FALSE) ; + } + else { - status = cr_parser_set_tknzr (result, a_tknzr) ; + status = cr_parser_parse_uri + (a_this, a_import_string) ; + + CHECK_PARSING_STATUS (status, FALSE) ; } - g_return_val_if_fail (status == CR_OK, NULL) ; + cr_parser_try_to_skip_spaces_and_comments (a_this) ; - return result ; + status = cr_parser_parse_ident (a_this, &medium) ; + + if (status == CR_OK && medium) + { + *a_media_list = g_list_append (*a_media_list, + medium) ; + medium = NULL ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + for (;status == CR_OK;) + { + if ( (status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char)) != CR_OK) + { + if (status == CR_END_OF_INPUT_ERROR) + { + status = CR_OK ; + goto okay ; + } + goto error ; + } + + + if (next_char == ',') + { + READ_NEXT_CHAR (a_this, &cur_char) ; + } + else + { + break ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_ident (a_this, + &medium) ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + if ((status == CR_OK) && medium) + { + *a_media_list = g_list_append + (*a_media_list, medium) ; + + medium = NULL ; + } + + CHECK_PARSING_STATUS (status, FALSE) ; + + READ_NEXT_CHAR (a_this, &cur_char) ; + + ENSURE_PARSING_COND (cur_char == ';') ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + } + + okay: + cr_parser_clear_errors (a_this) ; + PRIVATE (a_this)->state = IMPORT_PARSED_STATE ; + + return CR_OK ; + + error: + + if (*a_media_list) + { + GList *cur = NULL ; + /* + *free each element of *a_media_list. + *Note that each element of *a_medium list *must* + *be a GString* or else, the code that is coming next + *will corrupt the memory and lead to hard to debug + *random crashes. + *This is where C++ and its compile time + *type checking mecanism (through STL containers) would + *have prevented us to go through this hassle. + */ + for (cur = *a_media_list; cur ; cur = cur->next) + { + if (cur->data) + { + g_string_free (cur->data, TRUE) ; + } + } + + g_list_free (*a_media_list) ; + *a_media_list = NULL ; + } + + if (*a_import_string) + { + g_string_free (*a_import_string, TRUE) ; + *a_import_string = NULL ; + } + + if (medium) + { + g_string_free (medium, TRUE) ; + medium = NULL ; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; + + return status ; } /** - *Instanciates a new parser from a memory buffer. - *@param a_buf the buffer to parse. - *@param a_len the length of the data in the buffer. - *@param a_enc the encoding of the input buffer a_buf. - *@param a_free_buf if set to TRUE, a_buf will be freed - *during the destruction of the newly built instance - *of #CRParser. If set to FALSE, it is up to the caller to - *eventually free it. - *@return the newly built parser, or NULL if an error arises. + *Parses a 'media' declaration as specified in the css2 spec at + *appendix D.1: + * + *media ::= @media S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S* + * + *Note that this function calls the required sac handlers during the parsing + *to notify media productions. See #CRDocHandler to know the callback called + *during @media parsing. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. */ -CRParser * -cr_parser_new_from_buf (const guchar *a_buf, - gulong a_len, - enum CREncoding a_enc, - gboolean a_free_buf) +enum CRStatus +cr_parser_parse_media (CRParser *a_this) { - CRParser * result = NULL ; - CRInput *input = NULL ; - g_return_val_if_fail (a_buf && a_len, NULL) ; - - input = cr_input_new_from_buf (a_buf, a_len, a_enc, - a_free_buf) ; - g_return_val_if_fail (input, NULL) ; + enum CRStatus status = CR_OK ; + CRInputPos init_pos ; + CRToken * token = NULL ; + guint32 next_char = 0, cur_char = 0 ; + GString * medium = NULL ; + GList *media_list = NULL ; - result = cr_parser_new_from_input (input) ; - if (!result) + g_return_val_if_fail (a_this && PRIVATE (a_this), + CR_BAD_PARAM_ERROR) ; + + RECORD_INITIAL_POS (a_this, &init_pos) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == MEDIA_SYM_TK) ; + + cr_token_destroy (token) ; + token = NULL ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IDENT_TK) ; + + medium = token->u.str ; + token->u.str = NULL ; + cr_token_destroy (token) ; + token = NULL ; + + if (medium) { - cr_input_destroy (input) ; - input = NULL ; - return NULL ; + media_list = g_list_append (media_list, medium) ; + medium = NULL ; } - return result ; -} -CRParser * -cr_parser_new_from_input (CRInput *a_input) -{ - CRParser *result = NULL ; - CRTknzr *tokenizer = NULL ; + for (;status == CR_OK;) + { + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + PEEK_NEXT_CHAR (a_this, &next_char) ; - if (a_input) + if (next_char == ',') + { + READ_NEXT_CHAR (a_this, &cur_char) ; + } + else + { + break ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_ident (a_this, &medium) ; + + CHECK_PARSING_STATUS (status, FALSE) ; + + if (medium) + { + media_list = g_list_append (media_list, + medium) ; + medium = NULL ; + } + } + + READ_NEXT_CHAR (a_this, &cur_char) ; + + ENSURE_PARSING_COND (cur_char == '{') ; + + /* + *call the SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_media) { - tokenizer = cr_tknzr_new (a_input) ; - g_return_val_if_fail (tokenizer, NULL) ; + PRIVATE (a_this)->sac_handler->start_media + (PRIVATE (a_this)->sac_handler, media_list) ; } - result = cr_parser_new (tokenizer) ; - g_return_val_if_fail (result, NULL) ; + cr_parser_try_to_skip_spaces_and_comments (a_this) ; - return result ; -} + PRIVATE (a_this)->state = TRY_PARSE_MEDIA_STATE ; + for (;status == CR_OK;) + { + status = cr_parser_parse_ruleset (a_this) ; + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + } -CRParser * -cr_parser_new_from_file (const guchar *a_file_uri, - enum CREncoding a_enc) -{ - CRParser *result = NULL ; - CRTknzr *tokenizer = NULL ; + READ_NEXT_CHAR (a_this, &cur_char) ; - tokenizer = cr_tknzr_new_from_uri (a_file_uri, a_enc) ; - if (!tokenizer) + ENSURE_PARSING_COND (cur_char == '}') ; + + /* + *call the right SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_media) { - cr_utils_trace_info ("Could not open input file") ; - return NULL ; + PRIVATE (a_this)->sac_handler->end_media + (PRIVATE (a_this)->sac_handler, + media_list) ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + /* + *Then, free the data structures passed to + *the last call to the SAC handler. + */ + if (medium) + { + g_string_free (medium, TRUE) ; + medium = NULL ; + } + + if (media_list) + { + GList *cur = NULL ; + + for (cur = media_list ; cur ; cur = cur->next) + { + g_string_free (cur->data, TRUE) ; + } + + g_list_free (media_list) ; + media_list = NULL ; + } + + + cr_parser_clear_errors (a_this) ; + PRIVATE (a_this)->state = MEDIA_PARSED_STATE ; + + return CR_OK ; + + error: + + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + if (medium) + { + g_string_free (medium, TRUE) ; + medium = NULL ; + } + + if (media_list) + { + GList *cur = NULL ; + + for (cur = media_list ; cur ; cur = cur->next) + { + g_string_free (cur->data, TRUE) ; + } + + g_list_free (media_list) ; + media_list = NULL ; } - result = cr_parser_new (tokenizer) ; - g_return_val_if_fail (result, NULL) ; - return result ; + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status ; } - /** - *Sets a SAC document handler to the parser. + *Parses '@page' rule as specified in the css2 spec in appendix D.1: + *page ::= PAGE_SYM S* IDENT? pseudo_page? S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function also calls the relevant SAC handlers whenever it + *encounters a construction that must + *be reported to the calling application. *@param a_this the "this pointer" of the current instance of #CRParser. - *@param a_handler the handler to set. *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_parser_set_sac_handler (CRParser *a_this, CRDocHandler *a_handler) +cr_parser_parse_page (CRParser *a_this) { + enum CRStatus status = CR_OK ; + CRInputPos init_pos ; + CRToken * token = NULL ; + CRTerm * css_expression = NULL ; + GString *page_selector = NULL, + *page_pseudo_class = NULL, + *property = NULL ; + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; - if (PRIVATE (a_this)->sac_handler) + RECORD_INITIAL_POS (a_this, &init_pos) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == PAGE_SYM_TK) ; + + cr_token_destroy (token) ; + token = NULL ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK && token) ; + + if (token->type == IDENT_TK) { - cr_doc_handler_unref (PRIVATE (a_this)->sac_handler) ; + page_selector = token->u.str ; + token->u.str = NULL ; + cr_token_destroy (token) ; + token = NULL ; } + else + { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token) ; + token = NULL ; + } - PRIVATE (a_this)->sac_handler = a_handler ; - cr_doc_handler_ref (a_handler) ; + /* + *try to parse pseudo_page + */ + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token) ; + + if (token->type == DELIM_TK && token->u.unichar == ':') + { + cr_token_destroy (token) ; + token = NULL ; + status = cr_parser_parse_ident (a_this, &page_pseudo_class) ; + CHECK_PARSING_STATUS (status, FALSE) ; + } + else + { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token) ; + token = NULL ; + } + + /* + *parse_block + * + */ + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == CBO_TK) ; + + cr_token_destroy (token) ; token = NULL ; + + /* + *Call the appropriate SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_page) + { + PRIVATE (a_this)->sac_handler->start_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class) ; + } + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + PRIVATE (a_this)->state = TRY_PARSE_PAGE_STATE ; + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression) ; + + /* + *call the relevant SAC handler here... + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) + { + cr_term_ref (css_expression) ; + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, + css_expression) ; + } + + /* + *... and free the data structure passed to that last + *SAC handler. + */ + + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_unref (css_expression) ; + css_expression = NULL ; + } + + for (;;) + { + /*parse the other ';' separated declarations*/ + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token) ; + + ENSURE_PARSING_COND (status == CR_OK && token) ; + + if (token->type != SEMICOLON_TK) break ; + + cr_token_destroy (token) ; + token = NULL ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression) ; + CHECK_PARSING_STATUS (status, FALSE) ; + + /* + *call the relevant SAC handler here... + */ + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) + { + cr_term_ref (css_expression) ; + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, + css_expression) ; + } + + /* + *... and free the data structure passed to that last + *SAC handler. + */ + + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_unref (css_expression) ; + css_expression = NULL ; + } + } + + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == CBC_TK) ; + + cr_token_destroy (token) ; token = NULL ; + + + /* + *call the relevant SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_page) + { + PRIVATE (a_this)->sac_handler->end_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class) ; + } + + if (page_selector) + { + g_string_free (page_selector, TRUE) ; + page_selector = NULL ; + } + + if (page_pseudo_class) + { + g_string_free (page_pseudo_class, TRUE) ; + page_pseudo_class = NULL ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + /*here goes the former implem of this function ...*/ + + cr_parser_clear_errors (a_this) ; + PRIVATE (a_this)->state = PAGE_PARSED_STATE ; return CR_OK ; + + error: + + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + if (page_selector) + { + g_string_free (page_selector, TRUE) ; + page_selector = NULL ; + } + + if (page_pseudo_class) + { + g_string_free (page_pseudo_class, TRUE) ; + page_pseudo_class = NULL ; + } + + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_destroy (css_expression) ; + css_expression = NULL ; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; + + return status ; } /** - *Gets the SAC document handler. - *@param a_this the "this pointer" of the current instance of - *#CRParser. - *@param a_handler out parameter. The returned handler. - *@return CR_OK upon successfull completion, an error code - *otherwise. + *Parses a charset declaration as defined implictly by the css2 spec in + *appendix D.1: + *charset ::= CHARSET_SYM S* STRING S* ';' + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_value out parameter. The actual parsed value of the charset + *declararation. + *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_parser_get_sac_handler (CRParser *a_this, CRDocHandler **a_handler) +cr_parser_parse_charset (CRParser *a_this, GString **a_value) { - g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + enum CRStatus status = CR_OK ; + CRInputPos init_pos ; + CRToken *token = NULL ; + GString *charset_str = NULL ; - *a_handler = PRIVATE (a_this)->sac_handler ; + g_return_val_if_fail (a_this && a_value + && (*a_value == NULL), + CR_BAD_PARAM_ERROR) ; + + RECORD_INITIAL_POS (a_this, &init_pos) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == CHARSET_SYM_TK) ; + + cr_token_destroy (token) ; + token = NULL ; + + PRIVATE (a_this)->state = TRY_PARSE_CHARSET_STATE ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == STRING_TK) ; + charset_str = token->u.str ; + token->u.str = NULL ; + cr_token_destroy (token) ; + token = NULL ; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == SEMICOLON_TK) ; + cr_token_destroy (token) ; + token = NULL ; + + if (charset_str) + { + *a_value = charset_str ; + } + PRIVATE (a_this)->state = CHARSET_PARSED_STATE ; return CR_OK ; + + error: + + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + if (*a_value) + { + g_string_free (*a_value, TRUE) ; + *a_value = NULL ; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, + &init_pos) ; + + return status ; } + + /** - *Sets the SAC handler associated to the current instance - *of #CRParser to the default SAC handler. - *@param a_this a pointer to the current instance of #CRParser. + *Parses the "@font-face" rule specified in the css1 spec in + *appendix D.1: + * + *font_face ::= FONT_FACE_SYM S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function will call SAC handlers whenever it is necessary. *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_parser_set_default_sac_handler (CRParser *a_this) +cr_parser_parse_font_face (CRParser *a_this) { - CRDocHandler *default_sac_handler = NULL ; enum CRStatus status = CR_ERROR ; + CRInputPos init_pos ; + GString *property = NULL ; + CRTerm * css_expression = NULL ; + CRToken *token = NULL ; + guint32 next_char = 0, cur_char = 0 ; - g_return_val_if_fail (a_this && PRIVATE (a_this), - CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; - default_sac_handler = cr_doc_handler_new () ; + RECORD_INITIAL_POS (a_this, &init_pos) ; - cr_doc_handler_set_default_sac_handler (default_sac_handler) ; + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == FONT_FACE_SYM_TK) ; - status = cr_parser_set_sac_handler (a_this, default_sac_handler) ; + cr_parser_try_to_skip_spaces_and_comments (a_this) ; - if (status != CR_OK) + if (token) { - cr_doc_handler_destroy (default_sac_handler) ; - default_sac_handler = NULL ; + cr_token_destroy (token) ; + token = NULL ; } - return status ; -} + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == CBO_TK) ; -enum CRStatus -cr_parser_set_use_core_grammar (CRParser *a_this, - gboolean a_use_core_grammar) -{ - g_return_val_if_fail (a_this && PRIVATE (a_this), - CR_BAD_PARAM_ERROR) ; + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } - PRIVATE (a_this)->use_core_grammar = a_use_core_grammar ; + /* + *here, call the relevant SAC handler. + */ - return CR_OK ; -} + if (PRIVATE (a_this)->sac_handler->start_font_face) + { + PRIVATE (a_this)->sac_handler->start_font_face + (PRIVATE (a_this)->sac_handler) ; + } -enum CRStatus -cr_parser_get_use_core_grammar (CRParser *a_this, - gboolean *a_use_core_grammar) -{ - g_return_val_if_fail (a_this && PRIVATE (a_this), - CR_BAD_PARAM_ERROR) ; + PRIVATE (a_this)->state = TRY_PARSE_FONT_FACE_STATE ; - *a_use_core_grammar = PRIVATE (a_this)->use_core_grammar ; + /* + *and resume the parsing. + */ + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression) ; + + if (status == CR_OK) + { + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression) ; + + if (PRIVATE (a_this)->sac_handler->property) + { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression) ; + } + ENSURE_PARSING_COND (css_expression && property) ; + } + + /*free the data structures allocated during last parsing.*/ + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_unref (css_expression) ; + css_expression = NULL ; + } + + for (;;) + { + PEEK_NEXT_CHAR (a_this, &next_char) ; + + if (next_char == ';') + { + READ_NEXT_CHAR (a_this, &cur_char) ; + } + else + { + break ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression) ; + + if (status != CR_OK) break ; + + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression) ; + + if (PRIVATE (a_this)->sac_handler->property) + { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression) ; + } + + /* + *Then, free the data structures allocated during + *last parsing. + */ + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_unref (css_expression) ; + css_expression = NULL ; + } + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + READ_NEXT_CHAR (a_this, &cur_char) ; + + ENSURE_PARSING_COND (cur_char == '}') ; + + /* + *here, call the relevant SAC handler. + */ + + if (PRIVATE (a_this)->sac_handler->end_font_face) + { + PRIVATE (a_this)->sac_handler->end_font_face + (PRIVATE (a_this)->sac_handler) ; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + cr_parser_clear_errors (a_this) ; + + PRIVATE (a_this)->state = FONT_FACE_PARSED_STATE ; return CR_OK ; -} + error: + + if (token) + { + cr_token_destroy (token) ; + token = NULL ; + } + + if (property) + { + g_string_free (property, TRUE) ; + property = NULL ; + } + + if (css_expression) + { + cr_term_destroy (css_expression) ; + css_expression = NULL ; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos) ; + + return status ; +} /** *Parses the data that comes from the @@ -5097,38 +5138,6 @@ cr_parser_parse_buf (CRParser *a_this, const guchar *a_buf, /** - *Parses a the given in parameter. - *@param a_this a pointer to the current instance of #CRParser. - *@param a_file_uri the uri to the file to load. For the time being, - *only local files are supported. - *@return CR_OK upon successfull completion, an error code otherwise. - */ -enum CRStatus -cr_parser_parse_file (CRParser *a_this, - const guchar *a_file_uri, - enum CREncoding a_enc) -{ - enum CRStatus status = CR_ERROR ; - CRTknzr *tknzr = NULL ; - - g_return_val_if_fail (a_this && PRIVATE (a_this) - && a_file_uri, - CR_BAD_PARAM_ERROR) ; - - tknzr = cr_tknzr_new_from_uri (a_file_uri, a_enc) ; - - g_return_val_if_fail (tknzr != NULL, CR_ERROR) ; - - status = cr_parser_set_tknzr (a_this, tknzr) ; - g_return_val_if_fail (status == CR_OK, CR_ERROR) ; - - status = cr_parser_parse (a_this) ; - - return status ; -} - - -/** *Destroys the current instance *of #CRParser. *@param a_this the current instance of #CRParser to diff --git a/src/parser/cr-parser.h b/src/parser/cr-parser.h index 1455fa8..93d71fe 100644 --- a/src/parser/cr-parser.h +++ b/src/parser/cr-parser.h @@ -113,6 +113,22 @@ cr_parser_parse_declaration (CRParser *a_this, GString **a_property, enum CRStatus cr_parser_parse_ruleset (CRParser *a_this) ; +enum CRStatus +cr_parser_parse_import (CRParser *a_this, GList ** a_media_list, + GString **a_import_string) ; + +enum CRStatus +cr_parser_parse_media (CRParser *a_this) ; + +enum CRStatus +cr_parser_parse_page (CRParser *a_this) ; + +enum CRStatus +cr_parser_parse_charset (CRParser *a_this, GString **a_value) ; + +enum CRStatus +cr_parser_parse_font_face (CRParser *a_this) ; + void cr_parser_destroy (CRParser *a_this) ; diff --git a/src/parser/cr-statement.c b/src/parser/cr-statement.c index 8157b7c..efd87a2 100644 --- a/src/parser/cr-statement.c +++ b/src/parser/cr-statement.c @@ -57,6 +57,123 @@ cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp, gulong a_indent) ; static void +parse_at_media_start_media_cb (CRDocHandler *a_this, + GList *a_media_list) +{ + enum CRStatus status = CR_OK ; + CRStatement *at_media = NULL ; + GList *media_list = NULL ; + + g_return_if_fail (a_this && a_this->priv) ; + + if (a_media_list) + { + /*duplicate media list*/ + media_list = cr_dup_glist_of_string (a_media_list) ; + } + + g_return_if_fail (media_list) ; + + /*make sure cr_statement_new_at_media_rule works in this case.*/ + at_media = cr_statement_new_at_media_rule (NULL, NULL, + media_list) ; + + status = cr_doc_handler_set_ctxt (a_this, at_media) ; + g_return_if_fail (status == CR_OK) ; +} + +static void +parse_at_media_start_selector_cb (CRDocHandler *a_this, + CRSelector *a_sellist) +{ + enum CRStatus status = CR_OK ; + CRStatement *at_media = NULL, *ruleset = NULL ; + + g_return_if_fail (a_this + && a_this->priv + && a_sellist) ; + + status = cr_doc_handler_get_ctxt (a_this, + (gpointer*)&at_media) ; + g_return_if_fail (status == CR_OK && at_media) ; + g_return_if_fail (at_media->type == AT_MEDIA_RULE_STMT) ; + ruleset = cr_statement_new_ruleset (NULL, a_sellist, + NULL, at_media) ; + g_return_if_fail (ruleset) ; + status = cr_doc_handler_set_ctxt (a_this, ruleset) ; + g_return_if_fail (status == CR_OK) ; +} + +static void +parse_at_media_property_cb (CRDocHandler *a_this, + GString *a_name, CRTerm *a_value) +{ + enum CRStatus status = CR_OK ; + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL; + GString *name = NULL ; + + g_return_if_fail (a_this && a_name) ; + + name = g_string_new_len (a_name->str, a_name->len) ; + g_return_if_fail (name) ; + + status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&stmt) ; + g_return_if_fail (status == CR_OK && stmt) ; + g_return_if_fail (stmt->type == RULESET_STMT) ; + + status = cr_statement_ruleset_append_decl2 + (stmt, name, a_value) ; + g_return_if_fail (status == CR_OK) ; + + +} + +static void +parse_at_media_end_selector_cb (CRDocHandler *a_this, + CRSelector *a_sellist) +{ + enum CRStatus status = CR_OK ; + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL ; + + g_return_if_fail (a_this && a_sellist) ; + + status = cr_doc_handler_get_ctxt (a_this, + (gpointer *)stmt) ; + g_return_if_fail (status == CR_OK && stmt + && stmt->type == RULESET_STMT) ; + g_return_if_fail (stmt->kind.ruleset->parent_media_rule) ; + + status = cr_doc_handler_set_ctxt + (a_this, + stmt->kind.ruleset->parent_media_rule) ; + g_return_if_fail (status == CR_OK) ; +} + +static void +parse_at_media_end_media_cb (CRDocHandler *a_this, + GList *a_media_list) +{ + enum CRStatus status = CR_OK ; + CRStatement *at_media = NULL ; + g_return_if_fail (a_this && a_this->priv) ; + + status = cr_doc_handler_get_ctxt (a_this, + (gpointer*)&at_media) ; + g_return_if_fail (status == CR_OK && at_media) ; + + status = cr_doc_handler_set_result (a_this, at_media) ; +} + + +static void parse_ruleset_start_selector_cb (CRDocHandler *a_this, CRSelector *a_sellist) { @@ -66,8 +183,6 @@ parse_ruleset_start_selector_cb (CRDocHandler *a_this, && a_this->priv && a_sellist) ; - cr_selector_ref (a_sellist) ; - ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, NULL) ; g_return_if_fail (ruleset) ; @@ -92,13 +207,9 @@ parse_ruleset_property_cb (CRDocHandler *a_this, g_return_if_fail (status == CR_OK && ruleset && ruleset->type == RULESET_STMT) ; - if (a_value) - { - cr_term_ref (a_value) ; - } - - status = cr_statement_ruleset_append_decl2 (ruleset, stringue, a_value) ; - g_return_if_fail (status == CR_OK) ; + status = cr_statement_ruleset_append_decl2 + (ruleset, stringue, a_value) ; + g_return_if_fail (status == CR_OK) ; } static void @@ -576,10 +687,6 @@ cr_statement_ruleset_parse_from_buf (const guchar * a_buf, return result ; } -/********************** - *public functions - **********************/ - /** *Creates a new instance of #CRStatement of type *#CRRulSet. @@ -641,6 +748,83 @@ cr_statement_new_ruleset (CRStyleSheet * a_sheet, } /** + *Parses a buffer that contains an "@media" declaration + *and builds an @media css statement. + *@param a_buf the input to parse. + *@param a_enc the encoding of the buffer. + *@return the @media statement, or NULL if the buffer could not + *be successfully parsed. + */ +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_enc) +{ + CRParser *parser = NULL ; + CRStatement *result = NULL ; + CRDocHandler *sac_handler = NULL ; + enum CRStatus status = CR_OK ; + + parser = cr_parser_new_from_buf (a_buf, strlen (a_buf), + a_enc, FALSE) ; + if (!parser) + { + cr_utils_trace_info ("Instanciation of the parser failed") ; + goto cleanup ; + } + + sac_handler = cr_doc_handler_new () ; + if (!sac_handler) + { + cr_utils_trace_info ("Instanciation of the sac handler failed") ; + goto cleanup ; + } + + sac_handler->start_media = + parse_at_media_start_media_cb ; + sac_handler->start_selector = + parse_at_media_start_selector_cb ; + sac_handler->property = + parse_at_media_property_cb ; + sac_handler->end_selector = + parse_at_media_end_selector_cb ; + sac_handler->end_media = + parse_at_media_end_media_cb ; + + status = cr_parser_set_sac_handler (parser, sac_handler) ; + if (status != CR_OK) + goto cleanup ; + + status = cr_parser_try_to_skip_spaces_and_comments (parser) ; + if (status != CR_OK) + goto cleanup ; + + status = cr_parser_parse_media (parser) ; + if (status != CR_OK) + goto cleanup ; + + status = cr_doc_handler_get_result (sac_handler, + (gpointer*)&result) ; + if (status != CR_OK) + goto cleanup ; + + + cleanup: + + if (parser) + { + cr_parser_destroy (parser) ; + parser = NULL ; + } + if (sac_handler) + { + cr_doc_handler_unref (sac_handler) ; + sac_handler = NULL ; + } + + return result ; +} + +/** *Instanciates an instance of #CRStatement of type *AT_MEDIA_RULE_STMT (@media ruleset). *@param a_ruleset the ruleset statements contained diff --git a/src/parser/cr-statement.h b/src/parser/cr-statement.h index 06455e3..9db62f9 100644 --- a/src/parser/cr-statement.h +++ b/src/parser/cr-statement.h @@ -237,6 +237,9 @@ cr_statement_new_ruleset (CRStyleSheet *a_sheet, CRSelector *a_sel_list, CRDeclaration *a_decl_list, CRStatement *a_media_rule) ; +CRStatement * +cr_statement_ruleset_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) ; CRStatement* cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet, @@ -252,6 +255,9 @@ cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, CRStatement * cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, GString *a_charset) ; +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_enc) ; CRStatement * cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, @@ -282,9 +288,7 @@ CRStatement * cr_statement_unlink (CRStatement *a_this, CRStatement *a_to_unlink) ; -CRStatement * -cr_statement_ruleset_parse_from_buf (const guchar * a_buf, - enum CREncoding a_enc) ; + enum CRStatus cr_statement_ruleset_set_sel_list (CRStatement *a_this, CRSelector *a_sel_list) ; diff --git a/src/parser/cr-tknzr.c b/src/parser/cr-tknzr.c index be6c972..258b3bd 100644 --- a/src/parser/cr-tknzr.c +++ b/src/parser/cr-tknzr.c @@ -1938,6 +1938,28 @@ cr_tknzr_peek_byte (CRTknzr *a_this, gulong a_offset, guchar *a_byte) } /** + *Same as cr_tknzr_peek_byte() but this api returns the byte peeked. + *@param a_this the current instance of #CRTknzr. + *@param a_offset the offset of the peeked byte starting from the current + *byte in the parser input stream. + *@param a_eof out parameter. If not NULL, is set to TRUE if we reached end of + *file, FALE otherwise. If the caller sets it to NULL, this parameter + *is just ignored. + *@return the peeked byte. + */ +guchar +cr_tknzr_peek_byte2 (CRTknzr *a_this, gulong a_offset, + gboolean *a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + 0) ; + + return cr_input_peek_byte2 (PRIVATE (a_this)->input, + a_offset, a_eof) ; +} + +/** *Gets the number of bytes left in the topmost input stream *associated to this parser. *@param a_this the current instance of #CRTknzr diff --git a/src/parser/cr-tknzr.h b/src/parser/cr-tknzr.h index b3c26bb..6ba7d6b 100644 --- a/src/parser/cr-tknzr.h +++ b/src/parser/cr-tknzr.h @@ -78,6 +78,10 @@ enum CRStatus cr_tknzr_peek_byte (CRTknzr *a_this, gulong a_offset, guchar *a_byte) ; +guchar +cr_tknzr_peek_byte2 (CRTknzr *a_this, gulong a_offset, + gboolean *a_eof) ; + enum CRStatus cr_tknzr_set_cur_pos (CRTknzr *a_this, CRInputPos *a_pos) ; diff --git a/src/parser/cr-utils.c b/src/parser/cr-utils.c index 78bbe50..cbc4593 100644 --- a/src/parser/cr-utils.c +++ b/src/parser/cr-utils.c @@ -71,8 +71,8 @@ *otherwise. */ enum CRStatus -cr_utils_utf8_str_len_as_ucs4 (guchar *a_in_start, - guchar *a_in_end, +cr_utils_utf8_str_len_as_ucs4 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) { guchar *byte_ptr = NULL ; @@ -88,7 +88,7 @@ cr_utils_utf8_str_len_as_ucs4 (guchar *a_in_start, CR_BAD_PARAM_ERROR) ; *a_len = 0 ; - for (byte_ptr = a_in_start ; + for (byte_ptr = (guchar*)a_in_start ; byte_ptr <= a_in_end ; byte_ptr++) { @@ -211,7 +211,8 @@ cr_utils_utf8_str_len_as_ucs4 (guchar *a_in_start, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_ucs4_str_len_as_utf8 (guint32 *a_in_start, guint32 *a_in_end, +cr_utils_ucs4_str_len_as_utf8 (const guint32 *a_in_start, + const guint32 *a_in_end, gulong *a_len) { gint len = 0 ; @@ -220,7 +221,7 @@ cr_utils_ucs4_str_len_as_utf8 (guint32 *a_in_start, guint32 *a_in_end, g_return_val_if_fail (a_in_start && a_in_end && a_len, CR_BAD_PARAM_ERROR) ; - for (char_ptr = a_in_start ; + for (char_ptr = (guint32*)a_in_start ; char_ptr <= a_in_end ; char_ptr ++) { @@ -268,7 +269,8 @@ cr_utils_ucs4_str_len_as_utf8 (guint32 *a_in_start, guint32 *a_in_end, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_ucs1_str_len_as_utf8 (guchar *a_in_start, guchar *a_in_end, +cr_utils_ucs1_str_len_as_utf8 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) { gint len = 0 ; @@ -277,7 +279,7 @@ cr_utils_ucs1_str_len_as_utf8 (guchar *a_in_start, guchar *a_in_end, g_return_val_if_fail (a_in_start && a_in_end && a_len, CR_BAD_PARAM_ERROR) ; - for (char_ptr = a_in_start ; + for (char_ptr = (guchar *)a_in_start ; char_ptr <= a_in_end ; char_ptr ++) { @@ -313,8 +315,10 @@ cr_utils_ucs1_str_len_as_utf8 (guchar *a_in_start, guchar *a_in_end, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_utf8_to_ucs4 (guchar * a_in, gulong *a_in_len, - guint32 *a_out, gulong *a_out_len) +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong *a_in_len, + guint32 *a_out, + gulong *a_out_len) { gulong in_len = 0, out_len = 0, in_index = 0, out_index = 0 ; enum CRStatus status = CR_OK ; @@ -486,7 +490,8 @@ cr_utils_utf8_to_ucs4 (guchar * a_in, gulong *a_in_len, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_read_char_from_utf8_buf (guchar * a_in, gulong a_in_len, +cr_utils_read_char_from_utf8_buf (const guchar * a_in, + gulong a_in_len, guint32 *a_out, gulong *a_consumed) { gulong in_len = 0, in_index = 0, nb_bytes_2_decode = 0 ; @@ -643,8 +648,8 @@ cr_utils_read_char_from_utf8_buf (guchar * a_in, gulong a_in_len, * */ enum CRStatus -cr_utils_utf8_str_len_as_ucs1 (guchar *a_in_start, - guchar *a_in_end, +cr_utils_utf8_str_len_as_ucs1 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) { /* @@ -666,7 +671,7 @@ cr_utils_utf8_str_len_as_ucs1 (guchar *a_in_start, CR_BAD_PARAM_ERROR) ; *a_len = 0 ; - for (byte_ptr = a_in_start ; + for (byte_ptr = (guchar*)a_in_start ; byte_ptr <= a_in_end ; byte_ptr++) { @@ -804,7 +809,8 @@ cr_utils_utf8_str_len_as_ucs1 (guchar *a_in_start, * */ enum CRStatus -cr_utils_utf8_str_to_ucs4 (guchar * a_in, gulong *a_in_len, +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong *a_in_len, guint32 **a_out, gulong *a_out_len) { enum CRStatus status = CR_OK ; @@ -845,8 +851,10 @@ cr_utils_utf8_str_to_ucs4 (guchar * a_in, gulong *a_in_len, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_ucs4_to_utf8 (guint32 *a_in, gulong *a_in_len, - guchar *a_out, gulong *a_out_len) +cr_utils_ucs4_to_utf8 (const guint32 *a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) { gulong in_len = 0, in_index = 0, out_index = 0 ; enum CRStatus status = CR_OK ; @@ -954,7 +962,8 @@ cr_utils_ucs4_to_utf8 (guint32 *a_in, gulong *a_in_len, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_ucs4_str_to_utf8 (guint32 *a_in, gulong *a_in_len, +cr_utils_ucs4_str_to_utf8 (const guint32 *a_in, + gulong *a_in_len, guchar **a_out, gulong *a_out_len) { enum CRStatus status = CR_OK ; @@ -997,8 +1006,10 @@ cr_utils_ucs4_str_to_utf8 (guint32 *a_in, gulong *a_in_len, * */ enum CRStatus -cr_utils_ucs1_to_utf8 (guchar *a_in, gulong *a_in_len, - guchar *a_out, gulong *a_out_len) +cr_utils_ucs1_to_utf8 (const guchar *a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) { gulong out_index = 0, in_index = 0, in_len = 0, out_len = 0 ; enum CRStatus status = CR_OK ; @@ -1054,8 +1065,10 @@ cr_utils_ucs1_to_utf8 (guchar *a_in, gulong *a_in_len, * */ enum CRStatus -cr_utils_ucs1_str_to_utf8 (guchar *a_in, gulong *a_in_len, - guchar **a_out, gulong *a_out_len) +cr_utils_ucs1_str_to_utf8 (const guchar *a_in, + gulong *a_in_len, + guchar **a_out, + gulong *a_out_len) { gulong in_len = 0, out_len = 0 ; enum CRStatus status = CR_OK ; @@ -1113,8 +1126,10 @@ cr_utils_ucs1_str_to_utf8 (guchar *a_in, gulong *a_in_len, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_utils_utf8_to_ucs1 (guchar * a_in, gulong * a_in_len, - guchar *a_out, gulong *a_out_len) +cr_utils_utf8_to_ucs1 (const guchar * a_in, + gulong * a_in_len, + guchar *a_out, + gulong *a_out_len) { gulong in_index = 0, out_index = 0, in_len = 0, out_len = 0 ; enum CRStatus status = CR_OK ; @@ -1281,8 +1296,10 @@ cr_utils_utf8_to_ucs1 (guchar * a_in, gulong * a_in_len, *returns CR_OK. */ enum CRStatus -cr_utils_utf8_str_to_ucs1 (guchar * a_in, gulong * a_in_len, - guchar **a_out, gulong *a_out_len) +cr_utils_utf8_str_to_ucs1 (const guchar * a_in, + gulong * a_in_len, + guchar **a_out, + gulong *a_out_len) { enum CRStatus status = CR_OK ; @@ -1447,3 +1464,29 @@ cr_utils_n_to_0_dot_n (glong a_n) return result ; } + +/** + *Duplicates a list of GString instances. + *@return the duplicated list of GString instances or NULL if + *something bad happened. + *@param a_list_of_strings the list of strings to be duplicated. + */ +GList * +cr_dup_glist_of_string (GList *a_list_of_strings) +{ + GList *cur = NULL, *result = NULL ; + + g_return_val_if_fail (a_list_of_strings, NULL) ; + + for (cur = a_list_of_strings ; cur ; cur = cur->next) + { + GString *str = NULL ; + + str = g_string_new_len (((GString *)cur->data)->str, + ((GString *)cur->data)->len) ; + if (str) + result = g_list_append (result, str) ; + } + + return result ; +} diff --git a/src/parser/cr-utils.h b/src/parser/cr-utils.h index d43dffc..91ca333 100644 --- a/src/parser/cr-utils.h +++ b/src/parser/cr-utils.h @@ -139,55 +139,65 @@ cr_utils_trace (G_LOG_LEVEL_DEBUG, a_msg) ; ****************************/ enum CRStatus -cr_utils_read_char_from_utf8_buf (guchar * a_in, gulong a_in_len, +cr_utils_read_char_from_utf8_buf (const guchar * a_in, gulong a_in_len, guint32 *a_out, gulong *a_consumed) ; enum CRStatus -cr_utils_ucs1_to_utf8 (guchar *a_in, gulong *a_in_len, +cr_utils_ucs1_to_utf8 (const guchar *a_in, gulong *a_in_len, guchar *a_out, gulong *a_out_len) ; enum CRStatus -cr_utils_utf8_to_ucs1 (guchar * a_in, gulong * a_in_len, +cr_utils_utf8_to_ucs1 (const guchar * a_in, gulong * a_in_len, guchar *a_out, gulong *a_out_len) ; enum CRStatus -cr_utils_ucs4_to_utf8 (guint32 *a_in, gulong *a_in_len, +cr_utils_ucs4_to_utf8 (const guint32 *a_in, gulong *a_in_len, guchar *a_out, gulong *a_out_len) ; enum CRStatus -cr_utils_utf8_str_len_as_ucs4 (guchar *a_in_start, - guchar *a_in_end, +cr_utils_utf8_str_len_as_ucs4 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) ; enum CRStatus -cr_utils_ucs1_str_len_as_utf8 (guchar *a_in_start, guchar *a_in_end, +cr_utils_ucs1_str_len_as_utf8 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) ; enum CRStatus -cr_utils_utf8_str_len_as_ucs1 (guchar *a_in_start, - guchar *a_in_end, +cr_utils_utf8_str_len_as_ucs1 (const guchar *a_in_start, + const guchar *a_in_end, gulong *a_len) ; enum CRStatus -cr_utils_ucs4_str_len_as_utf8 (guint32 *a_in_start, guint32 *a_in_end, +cr_utils_ucs4_str_len_as_utf8 (const guint32 *a_in_start, + const guint32 *a_in_end, gulong *a_len) ; enum CRStatus -cr_utils_ucs1_str_to_utf8 (guchar *a_in_start, gulong *a_in_len, - guchar **a_out, gulong *a_len) ; +cr_utils_ucs1_str_to_utf8 (const guchar *a_in_start, + gulong *a_in_len, + guchar **a_out, + gulong *a_len) ; enum CRStatus -cr_utils_utf8_str_to_ucs1 (guchar * a_in_start, gulong * a_in_len, - guchar **a_out, gulong *a_out_len) ; +cr_utils_utf8_str_to_ucs1 (const guchar * a_in_start, + gulong * a_in_len, + guchar **a_out, + gulong *a_out_len) ; enum CRStatus -cr_utils_utf8_to_ucs4 (guchar * a_in, gulong * a_in_len, +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong * a_in_len, guint32 *a_out, gulong *a_out_len) ; enum CRStatus -cr_utils_ucs4_str_to_utf8 (guint32 *a_in, gulong *a_in_len, +cr_utils_ucs4_str_to_utf8 (const guint32 *a_in, + gulong *a_in_len, guchar **a_out, gulong *a_out_len) ; enum CRStatus -cr_utils_utf8_str_to_ucs4 (guchar * a_in, gulong *a_in_len, - guint32 **a_out, gulong *a_out_len) ; +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong *a_in_len, + guint32 **a_out, + gulong *a_out_len) ; /***************************************** @@ -206,6 +216,11 @@ cr_utils_is_nonascii (guint32 a_char) ; gboolean cr_utils_is_hexa_char (guint32 a_char) ; + +/********************************** + *Miscellaneous utility functions + ***********************************/ + void cr_utils_dump_n_chars (guchar a_char, FILE *a_fp, @@ -218,6 +233,9 @@ cr_utils_dump_n_chars2 (guchar a_char, gdouble cr_utils_n_to_0_dot_n (glong a_n) ; +GList * +cr_dup_glist_of_string (GList *a_list) ; + G_END_DECLS #endif /*__CR_DEFS_H__*/ |