gint64 lr_xml_parser_strtoll(LrParserData *pd, const char *nptr, unsigned int base) { gint64 val; char *endptr = NULL; assert(pd); assert(base <= 36 && base != 1); if (!nptr) return 0; val = g_ascii_strtoll(nptr, &endptr, base); if ((val == G_MAXINT64 || val == G_MININT64) && errno == ERANGE) lr_xml_parser_warning(pd, LR_XML_WARNING_BADATTRVAL, "Correct integer value \"%s\" caused overflow", nptr); else if (val == 0 && *endptr != '\0') lr_xml_parser_warning(pd, LR_XML_WARNING_BADATTRVAL, "Conversion of \"%s\" to integer failed", nptr); return val; }
static void XMLCALL lr_end_handler(void *pdata, G_GNUC_UNUSED const char *element) { LrParserData *pd = pdata; unsigned int state = pd->state; if (pd->err) return; // There was an error -> do nothing if (pd->depth != pd->statedepth) { // Back from the unknown state pd->depth--; return; } pd->depth--; pd->statedepth--; pd->state = pd->sbtab[pd->state]; pd->docontent = 0; switch (state) { case STATE_START: case STATE_REPOMD: break; case STATE_REVISION: assert(pd->repomd); assert(!pd->repomdrecord); if (pd->lcontent == 0) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGVAL, "Missing value of a revision element"); break; } lr_yum_repomd_set_revision(pd->repomd, pd->content); break; case STATE_REPOID: assert(pd->repomd); assert(!pd->repomdrecord); pd->repomd->repoid = g_string_chunk_insert(pd->repomd->chunk, pd->content); break; case STATE_TAGS: break; case STATE_REPO: assert(pd->repomd); assert(!pd->repomdrecord); lr_yum_repomd_add_repo_tag(pd->repomd, pd->content); break; case STATE_CONTENT: assert(pd->repomd); assert(!pd->repomdrecord); lr_yum_repomd_add_content_tag(pd->repomd, pd->content); break; case STATE_DISTRO: assert(pd->repomd); assert(!pd->repomdrecord); lr_yum_repomd_add_distro_tag(pd->repomd, pd->cpeid, pd->content); if (pd->cpeid) { g_free(pd->cpeid); pd->cpeid = NULL; } break; case STATE_DATA: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord = NULL; break; case STATE_LOCATION: break; case STATE_CHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->checksum = lr_string_chunk_insert( pd->repomdrecord->chunk, pd->content); break; case STATE_OPENCHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->checksum_open = lr_string_chunk_insert( pd->repomdrecord->chunk, pd->content); break; case STATE_TIMESTAMP: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->timestamp = lr_xml_parser_strtoll(pd, pd->content, 0); break; case STATE_SIZE: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->size = lr_xml_parser_strtoll(pd, pd->content, 0); break; case STATE_OPENSIZE: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->size_open = lr_xml_parser_strtoll(pd, pd->content, 0); break; case STATE_DBVERSION: assert(pd->repomd); assert(pd->repomdrecord); pd->repomdrecord->db_version = (int) lr_xml_parser_strtoll(pd, pd->content, 0); break; default: break; } }
static void XMLCALL lr_start_handler(void *pdata, const char *element, const char **attr) { LrParserData *pd = pdata; LrStatesSwitch *sw; if (pd->err) return; // There was an error -> do nothing if (pd->depth != pd->statedepth) { // We are inside of unknown element pd->depth++; return; } pd->depth++; if (!pd->swtab[pd->state]) { // Current element should not have any sub elements return; } // Find current state by its name for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) if (!strcmp(element, sw->ename)) break; if (sw->from != pd->state) { // No state for current element (unknown element) lr_xml_parser_warning(pd, LR_XML_WARNING_UNKNOWNTAG, "Unknown element \"%s\"", element); return; } // Update parser data pd->state = sw->to; pd->docontent = sw->docontent; pd->statedepth = pd->depth; pd->lcontent = 0; pd->content[0] = '\0'; const char *val; switch(pd->state) { case STATE_START: break; case STATE_REPOMD: pd->repomdfound = TRUE; break; case STATE_REVISION: case STATE_TAGS: case STATE_REPO: case STATE_CONTENT: break; case STATE_REPOID: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("type", attr); if (val) pd->repomd->repoid_type = g_string_chunk_insert(pd->repomd->chunk, val); break; case STATE_DISTRO: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("cpeid", attr); if (val) pd->cpeid = g_strdup(val); break; case STATE_DATA: assert(pd->repomd); assert(!pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of a data element"); val = "unknown"; } pd->repomdrecord = lr_yum_repomdrecord_init(val); lr_yum_repomd_set_record(pd->repomd, pd->repomdrecord); break; case STATE_LOCATION: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("href", attr); if (val) pd->repomdrecord->location_href = g_string_chunk_insert( pd->repomdrecord->chunk, val); else lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"href\" of a location element"); val = lr_find_attr("xml:base", attr); if (val) pd->repomdrecord->location_base = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_CHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of a checksum element"); break; } pd->repomdrecord->checksum_type = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_OPENCHECKSUM: assert(pd->repomd); assert(pd->repomdrecord); val = lr_find_attr("type", attr); if (!val) { lr_xml_parser_warning(pd, LR_XML_WARNING_MISSINGATTR, "Missing attribute \"type\" of an open checksum element"); break; } pd->repomdrecord->checksum_open_type = g_string_chunk_insert( pd->repomdrecord->chunk, val); break; case STATE_TIMESTAMP: case STATE_SIZE: case STATE_OPENSIZE: case STATE_DBVERSION: default: break; } }