|
|
#include "unity/unity.h" |
|
|
#include <libxml/HTMLparser.h> |
|
|
#include <libxml/xmlmemory.h> |
|
|
|
|
|
#include <string.h> |
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
extern int test_htmlSkipBlankChars(xmlParserCtxtPtr ctxt); |
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
xmlInitParser(); |
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void create_ctxt_with_content(const char *content, |
|
|
int init_line, int init_col, |
|
|
xmlParserCtxtPtr *out_ctxt, |
|
|
xmlParserInputPtr *out_input, |
|
|
xmlChar **out_buf, |
|
|
int *out_len) { |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(out_ctxt, "out_ctxt must not be NULL"); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(out_input, "out_input must not be NULL"); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(out_buf, "out_buf must not be NULL"); |
|
|
|
|
|
int len = (content != NULL) ? (int)strlen(content) : 0; |
|
|
xmlChar *buf = (xmlChar *)xmlMalloc((size_t)len + 1); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(buf, "Failed to allocate buffer"); |
|
|
if (len > 0 && content != NULL) { |
|
|
memcpy(buf, content, (size_t)len); |
|
|
} |
|
|
buf[len] = 0; |
|
|
|
|
|
htmlParserCtxtPtr hctxt = htmlNewParserCtxt(); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(hctxt, "Failed to create parser context"); |
|
|
|
|
|
xmlParserInputPtr input = (xmlParserInputPtr)xmlMalloc(sizeof(*input)); |
|
|
TEST_ASSERT_NOT_NULL_MESSAGE(input, "Failed to allocate parser input"); |
|
|
memset(input, 0, sizeof(*input)); |
|
|
input->base = buf; |
|
|
input->cur = buf; |
|
|
input->end = buf + len; |
|
|
input->line = init_line; |
|
|
input->col = init_col; |
|
|
|
|
|
hctxt->input = input; |
|
|
|
|
|
*out_ctxt = (xmlParserCtxtPtr)hctxt; |
|
|
*out_input = input; |
|
|
*out_buf = buf; |
|
|
if (out_len) |
|
|
*out_len = len; |
|
|
} |
|
|
|
|
|
static void destroy_ctxt_with_content(xmlParserCtxtPtr ctxt, |
|
|
xmlParserInputPtr input, |
|
|
xmlChar *buf) { |
|
|
if (ctxt != NULL) { |
|
|
|
|
|
ctxt->input = NULL; |
|
|
htmlFreeParserCtxt((htmlParserCtxtPtr)ctxt); |
|
|
} |
|
|
if (input != NULL) |
|
|
xmlFree(input); |
|
|
if (buf != NULL) |
|
|
xmlFree(buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_only_spaces(void) { |
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
create_ctxt_with_content(" abc", 3, 5, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(4, ret); |
|
|
TEST_ASSERT_EQUAL_INT(3, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(9, input->col); |
|
|
TEST_ASSERT_EQUAL_CHAR('a', (char)*(input->cur)); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_newlines_and_spaces(void) { |
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
|
|
|
create_ctxt_with_content("\n \n\tX", 1, 1, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(4, ret); |
|
|
TEST_ASSERT_EQUAL_INT(3, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(2, input->col); |
|
|
TEST_ASSERT_EQUAL_CHAR('X', (char)*(input->cur)); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_stops_on_non_ws(void) { |
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
create_ctxt_with_content(" \t\rA B", 1, 1, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(3, ret); |
|
|
TEST_ASSERT_EQUAL_INT(1, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(4, input->col); |
|
|
TEST_ASSERT_EQUAL_CHAR('A', (char)*(input->cur)); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_zero_avail(void) { |
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
create_ctxt_with_content("", 10, 7, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, ret); |
|
|
TEST_ASSERT_EQUAL_INT(10, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(7, input->col); |
|
|
TEST_ASSERT_TRUE(input->cur == input->end); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_parser_stopped(void) { |
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
create_ctxt_with_content(" \n\tabc", 2, 3, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
|
|
|
ctxt->instate = XML_PARSER_EOF; |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, ret); |
|
|
TEST_ASSERT_EQUAL_INT(2, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(3, input->col); |
|
|
TEST_ASSERT_TRUE(input->cur == input->base); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlSkipBlankChars_large_whitespace(void) { |
|
|
char tmp[102 + 1]; |
|
|
memset(tmp, ' ', 100); |
|
|
tmp[100] = 'Z'; |
|
|
tmp[101] = '\0'; |
|
|
|
|
|
xmlParserCtxtPtr ctxt = NULL; |
|
|
xmlParserInputPtr input = NULL; |
|
|
xmlChar *buf = NULL; |
|
|
|
|
|
create_ctxt_with_content(tmp, 1, 1, &ctxt, &input, &buf, NULL); |
|
|
|
|
|
int ret = test_htmlSkipBlankChars(ctxt); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(100, ret); |
|
|
TEST_ASSERT_EQUAL_INT(1, input->line); |
|
|
TEST_ASSERT_EQUAL_INT(101, input->col); |
|
|
TEST_ASSERT_EQUAL_CHAR('Z', (char)*(input->cur)); |
|
|
|
|
|
destroy_ctxt_with_content(ctxt, input, buf); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_htmlSkipBlankChars_only_spaces); |
|
|
RUN_TEST(test_htmlSkipBlankChars_newlines_and_spaces); |
|
|
RUN_TEST(test_htmlSkipBlankChars_stops_on_non_ws); |
|
|
RUN_TEST(test_htmlSkipBlankChars_zero_avail); |
|
|
RUN_TEST(test_htmlSkipBlankChars_parser_stopped); |
|
|
RUN_TEST(test_htmlSkipBlankChars_large_whitespace); |
|
|
return UNITY_END(); |
|
|
} |