static void cr_term_clear (CRTerm * a_this) { g_return_if_fail (a_this); switch (a_this->type) { case TERM_NUMBER: if (a_this->content.num) { cr_num_destroy (a_this->content.num); a_this->content.num = NULL; } break; case TERM_FUNCTION: if (a_this->ext_content.func_param) { cr_term_destroy (a_this->ext_content.func_param); a_this->ext_content.func_param = NULL; } case TERM_STRING: case TERM_IDENT: case TERM_URI: case TERM_HASH: if (a_this->content.str) { cr_string_destroy (a_this->content.str); a_this->content.str = NULL; } break; case TERM_RGB: if (a_this->content.rgb) { cr_rgb_destroy (a_this->content.rgb); a_this->content.rgb = NULL; } break; case TERM_UNICODERANGE: case TERM_NO_TYPE: default: break; } a_this->type = TERM_NO_TYPE; }
/** * cr_rgb_parse_from_buf: *@a_str: a string that contains a color description *@a_enc: the encoding of a_str * *Parses a text buffer that contains a rgb color * *Returns the parsed color, or NULL in case of error */ CRRgb * cr_rgb_parse_from_buf (const guchar *a_str, enum CREncoding a_enc) { enum CRStatus status = CR_OK ; CRTerm *value = NULL ; CRParser * parser = NULL; CRRgb *result = NULL; 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_try_to_skip_spaces_and_comments (parser) ; if (status != CR_OK) goto cleanup; status = cr_parser_parse_term (parser, &value); if (status != CR_OK) goto cleanup; result = cr_rgb_new (); if (!result) goto cleanup; status = cr_rgb_set_from_term (result, value); cleanup: if (parser) { cr_parser_destroy (parser); parser = NULL; } if (value) { cr_term_destroy(value); value = NULL; } return result ; }
static enum CRStatus test_cr_term_parse_expression_from_buf (void) { guchar *tmp_str = NULL; CRTerm *term = NULL; term = cr_term_parse_expression_from_buf (gv_term_buf, CR_UTF_8); if (!term) return CR_ERROR; tmp_str = cr_term_to_string (term); if (term) { cr_term_destroy (term); term = NULL; } 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; }
/** *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; }