diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | src/parser/cr-parser.c | 13 | ||||
-rw-r--r-- | src/parser/cr-statement.c | 222 | ||||
-rw-r--r-- | src/parser/cr-statement.h | 16 | ||||
-rw-r--r-- | tests/test4-main.c | 34 |
6 files changed, 286 insertions, 15 deletions
@@ -1,5 +1,14 @@ 2003-06-18 Dodji Seketeli <dodji@seketeli.org> + * src/parser/cr-statement.[ch]: + added cr_statement_font_face_rule_parse_from_buf () . + and a generic cr_statement_parse_from_buf () that knows + how to a parse virtually any css2 statement. This needs debugging + though. + + * src/parser/cr-parser.c: fixed some possible sigsev + that could occur when trying to access a null sac handler. + * tests/test4-main.c: updated the test routine to test cr_statement_at_charset_rule_parse_from_buf(). @@ -1,7 +1,12 @@ *coding:) -Provide support for font selection. (hard, started well underway.) +Code a cr_statement_at_import_rule_parse () function and +include it support in cr_statement_parse_from_buf (). + +Code a test case for cr_statement_parse_from_buf (). + +Provide support for font selection. (hard, started, is 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-parser.c b/src/parser/cr-parser.c index 402fcd0..58454c7 100644 --- a/src/parser/cr-parser.c +++ b/src/parser/cr-parser.c @@ -3048,7 +3048,8 @@ cr_parser_parse_stylesheet (CRParser *a_this) PRIVATE (a_this)->state = READY_STATE ; - if (PRIVATE (a_this)->sac_handler->start_document) + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_document) { PRIVATE (a_this)->sac_handler->start_document (PRIVATE (a_this)->sac_handler) ; @@ -3161,8 +3162,8 @@ cr_parser_parse_stylesheet (CRParser *a_this) if (status == CR_OK) { if (import_string - && PRIVATE - (a_this)->sac_handler-> + && PRIVATE (a_this)->sac_handler + && PRIVATE(a_this)->sac_handler-> import_style) { PRIVATE (a_this)->sac_handler-> @@ -4924,7 +4925,8 @@ cr_parser_parse_font_face (CRParser *a_this) *here, call the relevant SAC handler. */ - if (PRIVATE (a_this)->sac_handler->start_font_face) + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_font_face) { PRIVATE (a_this)->sac_handler->start_font_face (PRIVATE (a_this)->sac_handler) ; @@ -4948,7 +4950,8 @@ cr_parser_parse_font_face (CRParser *a_this) */ cr_term_ref (css_expression) ; - if (PRIVATE (a_this)->sac_handler->property) + if (PRIVATE (a_this)->sac_handler && + PRIVATE (a_this)->sac_handler->property) { PRIVATE (a_this)->sac_handler->property (PRIVATE (a_this)->sac_handler, diff --git a/src/parser/cr-statement.c b/src/parser/cr-statement.c index 11ee840..ce1ea56 100644 --- a/src/parser/cr-statement.c +++ b/src/parser/cr-statement.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ /* * This file is part of The Croco Library @@ -56,6 +56,82 @@ static void cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp, gulong a_indent) ; +static void +parse_font_face_start_font_face_cb (CRDocHandler *a_this) +{ + CRStatement *stmt = NULL ; + enum CRStatus status = CR_OK ; + + stmt = cr_statement_new_at_font_face_rule (NULL, + NULL) ; + g_return_if_fail (stmt) ; + + status = cr_doc_handler_set_ctxt (a_this, stmt) ; + g_return_if_fail (status == CR_OK) ; +} + +static void +parse_font_face_property_cb (CRDocHandler *a_this, + GString *a_name, + CRTerm *a_value) +{ + enum CRStatus status = CR_OK ; + GString *name = NULL ; + CRDeclaration *decl = NULL ; + CRStatement *stmt = NULL ; + + g_return_if_fail (a_this && a_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 == AT_FONT_FACE_RULE_STMT) ; + + name = g_string_new_len (a_name->str, a_name->len) ; + g_return_if_fail (name) ; + decl = cr_declaration_new (stmt, name, a_value) ; + if (!decl) + { + cr_utils_trace_info ("cr_declaration_new () failed.") ; + goto error ; + } + name = NULL ; + + stmt->kind.font_face_rule->decls_list = + cr_declaration_append (stmt->kind.font_face_rule->decls_list, + decl) ; + if (!stmt->kind.font_face_rule->decls_list) + goto error ; + decl = NULL ; + + error: + if (decl) + { + cr_declaration_unref (decl) ; + decl = NULL ; + } + if (name) + { + g_string_free (name, TRUE) ; + name = NULL ; + } +} + +static void +parse_font_face_end_font_face_cb (CRDocHandler *a_this) + +{ + CRStatement *result = NULL ; + enum CRStatus status = CR_OK ; + + g_return_if_fail (a_this) ; + + status = cr_doc_handler_get_ctxt (a_this, (gpointer*)&result) ; + g_return_if_fail (status == CR_OK && result) ; + g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT) ; + + status = cr_doc_handler_set_result (a_this, result) ; + g_return_if_fail (status == CR_OK) ; +} static void parse_page_start_page_cb (CRDocHandler *a_this, @@ -691,6 +767,78 @@ cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp, *public functions ******************/ +/** + *Parses a buffer that contains a css statement and returns + *an instance of #CRStatement in case of successfull parsing. + *TODO: at support of "@import" rules. + *@param a_buf the buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return the newly built instance of #CRStatement in case + *of successfull parsing, NULL otherwise. + */ +CRStatement * +cr_statement_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) +{ + CRStatement *result = NULL ; + + /* + *The strategy of this function is "brute force". + *It tries to parse all the types of #CRStatement it knows about. + *I could do this a smarter way but I don't have the time now. + *I think I will revisit this when time of performances and + *pull based incremental parsing comes. + */ + + result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding) ; + if (!result) + { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding) ; + if (result) + goto out ; + } + if (!result) + { + result = cr_statement_at_media_rule_parse_from_buf + (a_buf, a_encoding) ; + if (result) + goto out ; + } + if (!result) + { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding) ; + if (result) + goto out ; + } + if (!result) + { + result = cr_statement_font_face_rule_parse_from_buf + (a_buf, a_encoding) ; + if (result) + goto out ; + } + if (!result) + { + result = cr_statement_at_page_rule_parse_from_buf + (a_buf, a_encoding) ; + if (result) + goto out ; + } + + out: + return result ; +} + +/** + *Parses a buffer that contains a ruleset statement an instanciates + *a #CRStatement of type RULESET_STMT. + *@param a_buf the buffer to parse. + *@param a_enc the character encoding of a_buf. + *@param the newly built instance of #CRStatement in case of successfull parsing, + *NULL otherwise. + */ CRStatement * cr_statement_ruleset_parse_from_buf (const guchar * a_buf, enum CREncoding a_enc) @@ -1239,8 +1387,6 @@ cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, { CRStatement *result = NULL ; - g_return_val_if_fail (a_sheet, NULL) ; - result = g_try_malloc (sizeof (CRStatement)) ; if (!result) @@ -1264,8 +1410,76 @@ cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, sizeof (CRAtFontFaceRule)); result->kind.font_face_rule->decls_list = a_font_decls ; - cr_statement_set_parent_sheet (result, a_sheet) ; + if (a_sheet) + cr_statement_set_parent_sheet (result, a_sheet) ; + + return result ; +} + +/** + *Parses a buffer that contains an "@font-face" rule and builds + *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it. + *@param a_buf the buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return the newly built instance of #CRStatement in case of successufull + *parsing, NULL otherwise. + */ +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) +{ + CRStatement *result = NULL ; + CRParser *parser = NULL ; + CRDocHandler *sac_handler = NULL ; + enum CRStatus status = CR_OK ; + + parser = cr_parser_new_from_buf (a_buf, strlen (a_buf), + a_encoding, FALSE) ; + if (!parser) + goto cleanup ; + + sac_handler = cr_doc_handler_new () ; + if (!sac_handler) + goto cleanup ; + + /* + *set sac callbacks here + */ + sac_handler->start_font_face = parse_font_face_start_font_face_cb ; + sac_handler->property = parse_font_face_property_cb ; + sac_handler->end_font_face = parse_font_face_end_font_face_cb ; + status = cr_parser_set_sac_handler (parser, sac_handler) ; + if (status != CR_OK) + goto cleanup ; + + /* + *cleanup spaces of comment that may be there before the real + *"@font-face" thing. + */ + status = cr_parser_try_to_skip_spaces_and_comments (parser) ; + if (status != CR_OK) + goto cleanup ; + + status = cr_parser_parse_font_face (parser) ; + if (status != CR_OK) + goto cleanup ; + + status = cr_doc_handler_get_result (sac_handler, (gpointer*)&result) ; + if (status != CR_OK || !result) + 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 ; } diff --git a/src/parser/cr-statement.h b/src/parser/cr-statement.h index d1d7686..e293235 100644 --- a/src/parser/cr-statement.h +++ b/src/parser/cr-statement.h @@ -169,7 +169,7 @@ enum CRStatementType AT_CHARSET_RULE_STMT, /**A css2 font face rule*/ - AT_FONT_FACE_RULE_STMT + AT_FONT_FACE_RULE_STMT } ; @@ -232,6 +232,10 @@ struct _CRStatement } ; +CRStatement * +cr_statement_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; + CRStatement* cr_statement_new_ruleset (CRStyleSheet *a_sheet, CRSelector *a_sel_list, @@ -251,6 +255,9 @@ CRStatement * cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, CRStatement *a_ruleset, GList *a_media) ; +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_enc) ; CRStatement * cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, @@ -258,13 +265,14 @@ cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, CRStatement * cr_statement_at_charset_rule_parse_from_buf (const guchar *a_buf, enum CREncoding a_encoding); -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, CRDeclaration *a_font_decls) ; +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; CRStatement * cr_statement_new_at_page_rule (CRStyleSheet *a_sheet, diff --git a/tests/test4-main.c b/tests/test4-main.c index 1006c23..414455a 100644 --- a/tests/test4-main.c +++ b/tests/test4-main.c @@ -56,6 +56,13 @@ const guchar *gv_at_charset_buf = "@charset \"ISO-8859-1\" ; " ; +const guchar *gv_at_font_face_buf= +"@font-face {" +" font-family: \"Robson Celtic\";" +" src: url(\"http://site/fonts/rob-celt\")" +"}" +; + static void display_help (char *prg_name) ; @@ -232,6 +239,24 @@ test_cr_statement_at_charset_rule_parse (void) return CR_OK ; } + +static enum CRStatus +test_cr_statement_font_face_rule_parse_from_buf (void) +{ + CRStatement *stmt = NULL ; + + stmt = cr_statement_font_face_rule_parse_from_buf (gv_at_font_face_buf, + CR_UTF_8) ; + g_return_val_if_fail (stmt, CR_ERROR) ; + if (stmt) + { + cr_statement_destroy (stmt) ; + stmt = NULL ; + } + + return CR_OK ; +} + /** *The entry point of the testing routine. */ @@ -269,7 +294,14 @@ main (int argc, char ** argv) return 0 ; } - test_cr_statement_at_charset_rule_parse () ; + status = test_cr_statement_at_charset_rule_parse () ; + if (status != CR_OK) + { + g_print ("\nKO\n") ; + return 0 ; + } + + status = test_cr_statement_font_face_rule_parse_from_buf () ; if (status != CR_OK) { g_print ("\nKO\n") ; |