static enum CRStatus test_cr_declaration_parse_list (void) { GString *str = NULL; guchar *tmp_str = NULL; CRDeclaration *decl = NULL, *cur_decl = NULL; decl = cr_declaration_parse_list_from_buf (gv_decl_list_buf, CR_UTF_8); if (!decl) return CR_ERROR; str = g_string_new (NULL); for (cur_decl = decl; cur_decl; cur_decl = cur_decl->next) { tmp_str = cr_declaration_to_string (cur_decl, 2); if (tmp_str) { g_string_append_printf (str, "%s;", tmp_str); g_free (tmp_str); tmp_str = NULL; } } if (decl) { cr_declaration_destroy (decl); } if (str) { g_string_free (str, TRUE); str = NULL; } return CR_OK; }
/** * cr_declaration_unref: *@param a_this the current instance of #CRDeclaration. *@return TRUE if the current instance of #CRDeclaration has been destroyed *(ref count reached zero), FALSE otherwise. * *Decrements the ref count of the current instance of #CRDeclaration. *If the ref count reaches zero, the current instance of #CRDeclaration *if destroyed. *Returns TRUE if the object got destroyed, FALSE otherwise. */ gboolean cr_declaration_unref (CRDeclaration * a_this) { g_return_val_if_fail (a_this, FALSE); if (a_this->ref_count) { a_this->ref_count--; } if (a_this->ref_count == 0) { cr_declaration_destroy (a_this); return TRUE; } return FALSE; }
static enum CRStatus test_cr_declaration_parse (void) { guchar *tmp_str = NULL; CRDeclaration *decl = NULL; decl = cr_declaration_parse_from_buf (NULL, gv_decl_buf, CR_UTF_8); if (!decl) return CR_ERROR; tmp_str = cr_declaration_to_string (decl, 2); if (decl) { cr_declaration_destroy (decl); } if (tmp_str) { g_free (tmp_str); tmp_str = NULL; } return CR_OK; }
/** * cr_declaration_parse_list_from_buf: *@a_str: the input buffer that contains the list of declaration to *parse. *@a_enc: the encoding of a_str * *Parses a ';' separated list of properties declaration. *Returns the parsed list of declaration, NULL if parsing failed. */ CRDeclaration * cr_declaration_parse_list_from_buf (const guchar * a_str, enum CREncoding a_enc) { enum CRStatus status = CR_OK; CRTerm *value = NULL; CRString *property = NULL; CRDeclaration *result = NULL, *cur_decl = NULL; CRParser *parser = NULL; CRTknzr *tokenizer = NULL; gboolean important = FALSE; g_return_val_if_fail (a_str, NULL); parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), a_enc, FALSE); g_return_val_if_fail (parser, NULL); status = cr_parser_get_tknzr (parser, &tokenizer); if (status != CR_OK || !tokenizer) { if (status == CR_OK) status = CR_ERROR; goto cleanup; } status = cr_parser_try_to_skip_spaces_and_comments (parser); if (status != CR_OK) goto cleanup; status = cr_parser_parse_declaration (parser, &property, &value, &important); if (status != CR_OK || !property) { if (status != CR_OK) status = CR_ERROR; goto cleanup; } result = cr_declaration_new (NULL, property, value); if (result) { property = NULL; value = NULL; result->important = important; } /*now, go parse the other declarations */ for (;;) { guint32 c = 0; cr_parser_try_to_skip_spaces_and_comments (parser); status = cr_tknzr_peek_char (tokenizer, &c); if (status != CR_OK) { if (status == CR_END_OF_INPUT_ERROR) status = CR_OK; goto cleanup; } if (c == ';') { status = cr_tknzr_read_char (tokenizer, &c); } else { break; } important = FALSE; cr_parser_try_to_skip_spaces_and_comments (parser); status = cr_parser_parse_declaration (parser, &property, &value, &important); if (status != CR_OK || !property) { if (status == CR_END_OF_INPUT_ERROR) { status = CR_OK; } break; } cur_decl = cr_declaration_new (NULL, property, value); if (cur_decl) { cur_decl->important = important; result = cr_declaration_append (result, cur_decl); property = NULL; value = NULL; cur_decl = NULL; } else { break; } } cleanup: if (parser) { cr_parser_destroy (parser); parser = NULL; } if (property) { cr_string_destroy (property); property = NULL; } if (value) { cr_term_destroy (value); value = NULL; } if (status != CR_OK && result) { cr_declaration_destroy (result); result = NULL; } return result; }
static void property (CRDocHandler * a_this, CRString * a_name, CRTerm * a_expression, gboolean a_important) { enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; CRDeclaration *decl = NULL, *decl2 = NULL; CRString *str = NULL; g_return_if_fail (a_this); ctxtptr = &ctxt; status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); g_return_if_fail (status == CR_OK && ctxt); /* *make sure a current ruleset statement has been allocated *already. */ g_return_if_fail (ctxt->cur_stmt && (ctxt->cur_stmt->type == RULESET_STMT || ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT || ctxt->cur_stmt->type == AT_PAGE_RULE_STMT)); if (a_name) { str = cr_string_dup (a_name); g_return_if_fail (str); } /*instanciates a new declaration */ decl = cr_declaration_new (ctxt->cur_stmt, str, a_expression); g_return_if_fail (decl); str = NULL; decl->important = a_important; /* *add the new declaration to the current statement *being build. */ switch (ctxt->cur_stmt->type) { case RULESET_STMT: decl2 = cr_declaration_append (ctxt->cur_stmt->kind.ruleset->decl_list, decl); if (!decl2) { cr_declaration_destroy (decl); cr_utils_trace_info ("Could not append decl to ruleset"); goto error; } ctxt->cur_stmt->kind.ruleset->decl_list = decl2; decl = NULL; decl2 = NULL; break; case AT_FONT_FACE_RULE_STMT: decl2 = cr_declaration_append (ctxt->cur_stmt->kind.font_face_rule->decl_list, decl); if (!decl2) { cr_declaration_destroy (decl); cr_utils_trace_info ("Could not append decl to ruleset"); goto error; } ctxt->cur_stmt->kind.font_face_rule->decl_list = decl2; decl = NULL; decl2 = NULL; break; case AT_PAGE_RULE_STMT: decl2 = cr_declaration_append (ctxt->cur_stmt->kind.page_rule->decl_list, decl); if (!decl2) { cr_declaration_destroy (decl); cr_utils_trace_info ("Could not append decl to ruleset"); goto error; } ctxt->cur_stmt->kind.page_rule->decl_list = decl2; decl = NULL; decl2 = NULL; break; default: goto error; break; } return; error: if (str) { g_free (str); str = NULL; } if (decl) { cr_declaration_destroy (decl); decl = NULL; } }
/** *Parses a ';' separated list of properties declaration. *@param a_str the input buffer that contains the list of declaration to *parse. *@param a_enc the encoding of a_str *@return the parsed list of declaration, NULL if parsing failed. */ CRDeclaration * cr_declaration_parse_list_from_buf (const guchar * a_str, enum CREncoding a_enc) { enum CRStatus status = CR_OK; CRTerm *value = NULL; CRString *property = NULL; CRDeclaration *result = NULL, *cur_decl = NULL; CRTknzr *tokenizer = NULL; gboolean important = FALSE; g_return_val_if_fail (a_str, NULL); CRParser *parser = (CRParser *)cr_parser_new_from_buf ((guchar*)a_str, strlen ((char *)a_str), a_enc, FALSE); g_return_val_if_fail (parser, NULL); status = cr_parser_get_tknzr (parser, &tokenizer); if (status != CR_OK || !tokenizer) { if (status == CR_OK) status = CR_ERROR; goto cleanup; } status = cr_parser_try_to_skip_spaces_and_comments (parser); if (status != CR_OK) goto cleanup; status = cr_parser_parse_declaration (parser, &property, &value, &important); if (status != CR_OK || !property) { if (status != CR_OK) status = CR_ERROR; goto cleanup; } result = cr_declaration_new (NULL, property, value); if (result) { property = NULL; value = NULL; result->important = important; } /*now, go parse the other declarations */ for (;;) { guint32 c = 0; cr_parser_try_to_skip_spaces_and_comments (parser); status = cr_tknzr_peek_char (tokenizer, &c); if (status != CR_OK) { if (status == CR_END_OF_INPUT_ERROR) status = CR_OK; goto cleanup; } if (c == ';') { status = cr_tknzr_read_char (tokenizer, &c); } else { cr_tknzr_read_char (tokenizer, &c); continue; // try to keep reading until we reach the end or a ; } important = FALSE; cr_parser_try_to_skip_spaces_and_comments (parser); status = cr_parser_parse_declaration (parser, &property, &value, &important); if (status != CR_OK || !property) { if (status == CR_END_OF_INPUT_ERROR) { status = CR_OK; // simply the end of input, do not delete what we got so far, just finish break; } else { continue; // even if one declaration is broken, it's no reason to discard others (see http://www.w3.org/TR/CSS21/syndata.html#declaration) } } cur_decl = cr_declaration_new (NULL, property, value); if (cur_decl) { cur_decl->important = important; result = cr_declaration_append (result, cur_decl); property = NULL; value = NULL; cur_decl = NULL; } else { break; } } cleanup: if (parser) { cr_parser_destroy (parser); parser = NULL; } if (property) { cr_string_destroy (property); property = NULL; } if (value) { cr_term_destroy (value); value = NULL; } if (status != CR_OK && result) { cr_declaration_destroy (result); result = NULL; } return result; }