summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordodji <dodji@seketeli.org>2003-06-16 23:54:31 +0000
committerDodji Seketeli <dodji@src.gnome.org>2003-06-16 23:54:31 +0000
commit5d526f8953f29f41d58de76f49314d72e3ccc919 (patch)
treee4b2c38f9b927c56306644ef773bb5d27c48de0b
parent359c7d2721532d0726e0882e178ab057bc046215 (diff)
downloadlibcroco-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--ChangeLog31
-rw-r--r--TODO4
-rw-r--r--src/parser/cr-enc-handler.h12
-rw-r--r--src/parser/cr-om-parser.c11
-rw-r--r--src/parser/cr-parser.c2175
-rw-r--r--src/parser/cr-parser.h16
-rw-r--r--src/parser/cr-statement.c210
-rw-r--r--src/parser/cr-statement.h10
-rw-r--r--src/parser/cr-tknzr.c22
-rw-r--r--src/parser/cr-tknzr.h4
-rw-r--r--src/parser/cr-utils.c93
-rw-r--r--src/parser/cr-utils.h54
12 files changed, 1483 insertions, 1159 deletions
diff --git a/ChangeLog b/ChangeLog
index c42fc50..6072ae2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/TODO b/TODO
index ad13a25..b98b5f0 100644
--- a/TODO
+++ b/TODO
@@ -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__*/