if (!pd->swtab[pd->state])
return; // Current element should not have any sub elements
- /* TODO TEST THIS */
if (!pd->pkg && pd->state != STATE_FILELISTS && pd->state != STATE_START)
return; // Do not parse current package tag and its content
break;
case STATE_PACKAGE: {
- /* TODO: Parse all attrs in single loop instead of use cr_find_attr */
const char *pkgId = cr_find_attr("pkgid", attr);
const char *name = cr_find_attr("name", attr);
const char *arch = cr_find_attr("arch", attr);
+
if (!pkgId) {
+ // Package without a pkgid attr is error
pd->ret = CRE_BADXMLFILELISTS;
- g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_BADXMLFILELISTS,
+ g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_BADXMLFILELISTS,
"Package pkgid attributte is missing!");
break;
}
+ // Get package object to store current package or NULL if
+ // current XML package element shoud be skipped/ignored.
if (pd->newpkgcb(&pd->pkg,
pkgId,
name,
{
pd->ret = CRE_CBINTERRUPTED;
if (tmp_err)
- g_propagate_prefixed_error(pd->err,
+ g_propagate_prefixed_error(&pd->err,
tmp_err,
"Parsing interrupted:");
else
- g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED,
+ g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED,
"Parsing interrupted");
}
- /* TODO: Insert name and pkg id to the package */
+ if (pd->pkg) {
+ if (!pd->pkg->pkgId)
+ pd->pkg->pkgId = g_string_chunk_insert(pd->pkg->chunk, pkgId);
+ if (!pd->pkg->name && name)
+ pd->pkg->name = g_string_chunk_insert(pd->pkg->chunk, name);
+ if (!pd->pkg->arch && arch)
+ pd->pkg->arch = g_string_chunk_insert(pd->pkg->chunk, arch);
+ }
break;
}
case STATE_VERSION:
- /* TODO: Parse version */
+ if (!pd->pkg)
+ break;
+
+ // Version string insert only if them don't already exists
+
+ if (!pd->pkg->epoch)
+ pd->pkg->epoch = cr_safe_string_chunk_insert(pd->pkg->chunk,
+ cr_find_attr("epoch", attr));
+ if (!pd->pkg->version)
+ pd->pkg->version = cr_safe_string_chunk_insert(pd->pkg->chunk,
+ cr_find_attr("ver", attr));
+ if (!pd->pkg->release)
+ pd->pkg->release = cr_safe_string_chunk_insert(pd->pkg->chunk,
+ cr_find_attr("rel", attr));
break;
case STATE_FILE: {
if (!pd->pkg)
return;
- if (pd->pkgcb(pd->pkg, pd->pkgcb_data, &tmp_err)) {
+ if (pd->pkgcb && pd->pkgcb(pd->pkg, pd->pkgcb_data, &tmp_err)) {
pd->ret = CRE_CBINTERRUPTED;
if (tmp_err)
- g_propagate_prefixed_error(pd->err,
+ g_propagate_prefixed_error(&pd->err,
tmp_err,
"Parsing interrupted:");
else
- g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED,
+ g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED,
"Parsing interrupted");
+ } else {
+ // If callback return CRE_OK but it simultaneously set
+ // the tmp_err then it's a programming error.
+ assert(tmp_err == NULL);
}
+
pd->pkg = NULL;
break;
void *newpkgcb_data,
cr_XmlParserPkgCb pkgcb,
void *pkgcb_data,
+ char **messages,
GError **err)
{
int ret = CRE_OK;
CR_FILE *f;
cr_ParserData *pd;
XML_Parser parser;
+ char *msgs;
assert(path);
- assert(pkgcb);
+ assert(newpkgcb || pkgcb);
+ assert(!messages || *messages == NULL);
assert(!err || *err == NULL);
if (!newpkgcb)
XML_SetElementHandler(parser, cr_start_handler, cr_end_handler);
XML_SetCharacterDataHandler(parser, cr_char_handler);
- pd = cr_xml_parser_data();
+ pd = cr_xml_parser_data(NUMSTATES);
pd->parser = &parser;
pd->state = STATE_START;
pd->newpkgcb_data = newpkgcb_data;
pd->newpkgcb = newpkgcb;
pd->pkgcb_data = pkgcb_data;
pd->pkgcb = pkgcb;
- pd->swtab = g_malloc0(sizeof(cr_StatesSwitch *) * NUMSTATES);
- pd->sbtab = g_malloc(sizeof(cr_FilState) * NUMSTATES);
for (cr_StatesSwitch *sw = stateswitches; sw->from != NUMSTATES; sw++) {
if (!pd->swtab[sw->from])
pd->swtab[sw->from] = sw;
break;
}
- if (len == 0)
- break;
-
if (pd->ret != CRE_OK) {
ret = pd->ret;
break;
}
+
+ if (len == 0)
+ break;
}
- cr_xml_parser_data_free(pd);
+ if (pd->err)
+ g_propagate_error(err, pd->err);
+
+ msgs = cr_xml_parser_data_free(pd);
XML_ParserFree(parser);
+ cr_close(f);
+
+ if (messages)
+ *messages = msgs;
+ else
+ g_free(msgs);
return ret;
}
#include "createrepo/misc.h"
#include "createrepo/xml_parser.h"
+// Callbacks
+
static int
pkgcb(cr_Package *pkg, void *cbdata, GError **err)
{
+ g_assert(pkg);
g_assert(!err || *err == NULL);
if (cbdata) *((int *)cbdata) += 1;
+ cr_package_free(pkg);
return CRE_OK;
}
-static void test_cr_xml_parse_filelists_00(void)
+static int
+pkgcb_interrupt(cr_Package *pkg, void *cbdata, GError **err)
+{
+ g_assert(pkg);
+ g_assert(!err || *err == NULL);
+ if (cbdata) *((int *)cbdata) += 1;
+ cr_package_free(pkg);
+ return 1;
+}
+
+static int
+newpkgcb_skip_fake_bash(cr_Package **pkg,
+ const char *pkgId,
+ const char *name,
+ const char *arch,
+ void *cbdata,
+ GError **err)
+{
+ CR_UNUSED(pkgId);
+ CR_UNUSED(arch);
+ CR_UNUSED(cbdata);
+
+ g_assert(pkg != NULL);
+ g_assert(*pkg == NULL);
+ g_assert(pkgId != NULL);
+ g_assert(!err || *err == NULL);
+
+ if (!g_strcmp0(name, "fake_bash"))
+ return CRE_OK;
+
+ *pkg = cr_package_new();
+ return CRE_OK;
+}
+
+static int
+newpkgcb_interrupt(cr_Package **pkg,
+ const char *pkgId,
+ const char *name,
+ const char *arch,
+ void *cbdata,
+ GError **err)
+{
+ CR_UNUSED(pkgId);
+ CR_UNUSED(arch);
+ CR_UNUSED(cbdata);
+
+ g_assert(pkg != NULL);
+ g_assert(*pkg == NULL);
+ g_assert(pkgId != NULL);
+ g_assert(!err || *err == NULL);
+
+ return 1;
+}
+
+// Tests
+
+static void
+test_cr_xml_parse_filelists_00(void)
+{
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_REPO_00_FILELISTS, NULL, NULL,
+ pkgcb, NULL, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+}
+
+static void
+test_cr_xml_parse_filelists_01(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_REPO_01_FILELISTS, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 1);
+}
+
+static void
+test_cr_xml_parse_filelists_02(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 2);
+}
+
+static void
+test_cr_xml_parse_filelists_unknown_element_00(void)
{
- int ret;
+ int parsed = 0;
GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_00, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 2);
+}
- ret = cr_xml_parse_filelists(TEST_REPO_00_FILELISTS,
- NULL,
- NULL,
- pkgcb,
- NULL,
- &tmp_err);
+static void
+test_cr_xml_parse_filelists_unknown_element_01(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_01, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 1);
+}
+static void
+test_cr_xml_parse_filelists_unknown_element_02(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_02, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
g_assert(tmp_err == NULL);
g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 2);
}
-static void test_cr_xml_parse_filelists_01(void)
+static void
+test_cr_xml_parse_filelists_no_pkgid(void)
{
- int ret;
int parsed = 0;
GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_NO_PKGID_FIL, NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err != NULL);
+ g_error_free(tmp_err);
+ g_assert_cmpint(ret, ==, CRE_BADXMLFILELISTS);
+}
- ret = cr_xml_parse_filelists(TEST_REPO_01_FILELISTS,
- NULL,
- NULL,
- pkgcb,
- &parsed,
- &tmp_err);
+static void
+test_cr_xml_parse_filelists_skip_fake_bash_00(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_00,
+ newpkgcb_skip_fake_bash, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 1);
+}
+static void
+test_cr_xml_parse_filelists_skip_fake_bash_01(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_01,
+ newpkgcb_skip_fake_bash, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
g_assert(tmp_err == NULL);
g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 0);
+}
+
+static void
+test_cr_xml_parse_filelists_pkgcb_interrupt(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, NULL, NULL,
+ pkgcb_interrupt, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err != NULL);
+ g_error_free(tmp_err);
+ g_assert_cmpint(ret, ==, CRE_CBINTERRUPTED);
g_assert_cmpint(parsed, ==, 1);
}
-static void test_cr_xml_parse_filelists_02(void)
+static void
+test_cr_xml_parse_filelists_newpkgcb_interrupt(void)
{
- int ret;
int parsed = 0;
GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS,
+ newpkgcb_interrupt, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err != NULL);
+ g_error_free(tmp_err);
+ g_assert_cmpint(ret, ==, CRE_CBINTERRUPTED);
+ g_assert_cmpint(parsed, ==, 0);
+}
- ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS,
- NULL,
- NULL,
- pkgcb,
- &parsed,
- &tmp_err);
+static void
+test_cr_xml_parse_filelists_bad_file_type_00(void)
+{
+ int parsed = 0;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_BAD_TYPE_FIL,
+ NULL, NULL,
+ pkgcb, &parsed, NULL, &tmp_err);
+ g_assert(tmp_err == NULL);
+ g_assert_cmpint(ret, ==, CRE_OK);
+ g_assert_cmpint(parsed, ==, 2);
+}
+static void
+test_cr_xml_parse_filelists_bad_file_type_01(void)
+{
+ int parsed = 0;
+ char *msgs = NULL;
+ GError *tmp_err = NULL;
+ int ret = cr_xml_parse_filelists(TEST_MRF_BAD_TYPE_FIL,
+ NULL, NULL,
+ pkgcb, &parsed, &msgs, &tmp_err);
+ g_assert(msgs != NULL);
+ g_assert_cmpstr(msgs, ==, "Unknown file type \"foo\";");
+ g_free(msgs);
g_assert(tmp_err == NULL);
g_assert_cmpint(ret, ==, CRE_OK);
g_assert_cmpint(parsed, ==, 2);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
test_cr_xml_parse_filelists_01);
g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_02",
test_cr_xml_parse_filelists_02);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_00",
+ test_cr_xml_parse_filelists_unknown_element_00);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_01",
+ test_cr_xml_parse_filelists_unknown_element_01);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_02",
+ test_cr_xml_parse_filelists_unknown_element_02);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_no_pgkid",
+ test_cr_xml_parse_filelists_no_pkgid);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_skip_fake_bash_00",
+ test_cr_xml_parse_filelists_skip_fake_bash_00);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_skip_fake_bash_01",
+ test_cr_xml_parse_filelists_skip_fake_bash_01);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_pkgcb_interrupt",
+ test_cr_xml_parse_filelists_pkgcb_interrupt);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_newpkgcb_interrupt",
+ test_cr_xml_parse_filelists_newpkgcb_interrupt);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_bad_file_type_00",
+ test_cr_xml_parse_filelists_bad_file_type_00);
+ g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_bad_file_type_01",
+ test_cr_xml_parse_filelists_bad_file_type_01);
+
return g_test_run();
}