int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { XMLCONFPARSER *xcp = (XMLCONFPARSER*)UserData; LPXMLRUNTIMEATT att; int *pstate = STACK_PEEK(xcp->stateStack); xcp->state = (pstate) ? *pstate : NONE; if (xcp->inMixedContent || xcp->state == TEST) { /* + other tags that allow mixed content tested here */ /* if we're in mixed content, we don't bother to use stack, just incrementing (and decrementing in EndElement) the counter: */ xcp->inMixedContent++; /* could call mixed content legal tag check routine here e.g. if (!isvalidmixedcontent(state, qName)) return sin(); */ fprintf(PFOUT, "<%s>", qName); return 0; } if (xcp->state == NONE && !strcmp(qName, "TESTSUITE")) { if (att = XMLParser_GetNamedItem(xcp->parser, "PROFILE")) fprintf(PFOUT, "<h1><b>%s</b></h1><br><h3>Parsifal XML Parser %s</h3>", att->value, XMLParser_GetVersionString()); xcp->state = TESTSUITE; } else if (xcp->state == TESTSUITE && !strcmp(qName, "TESTCASES")) { if (att = XMLParser_GetNamedItem(xcp->parser, "PROFILE")) { /* new testcase, spit out the profile header: */ fprintf(PFOUT, "<br><br><h2>Testcase profile: <b>%s</b></h2><br>", att->value); fputs("<table cellspacing='0'>", PFOUT); /* open table for results */ } xcp->state = TESTCASES; } else if (xcp->state == TESTCASES) { if (!strcmp(qName, "TEST")) { if (att = XMLParser_GetNamedItem(xcp->parser, "URI")) { /* new test, run it: */ if (!RunTest(xcp, att->value)) fprintf(PFERR, "Fatal Error running test: %s\n", att->value); } xcp->state = TEST; } else if (!strcmp(qName, "TESTCASES")) { /* for some reason there's TESTCASES inside TESTCASES in ibm tests, so it must ust be handled here: */ xcp->state = TESTCASES; } } else { fprintf(PFERR, "Unexpected tag: %s\n", qName); return XML_ABORT; } STACK_PUSH(xcp->stateStack, &xcp->state); return 0; }
static int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { if (!strcmp(qName, "public")) return AddUri(&publicIDS, XMLParser_GetNamedItem(parser, "publicId")); else if (!strcmp(qName, "system")) return AddUri(&systemIDS, XMLParser_GetNamedItem(parser, "systemId")); else if (!strcmp(qName, "nextCatalog")) return AddNextCatalog(XMLParser_GetNamedItem(parser, "catalog")); return 0; }
int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData; if (!strcmp(qName, "book")) { int ret; LPXMLRUNTIMEATT a; /* append and initialize new book: */ BOOKP->curBook = XMLVector_Append(BOOKP->books, NULL); ASSERT_MEM_ABORT(BOOKP->curBook); memset(BOOKP->curBook, 0, sizeof(struct tagBOOK)); BOOKP->fld = -1; /* get book id: */ a = XMLParser_GetNamedItem(v->parser, "id"); /* a == NULL doesn't happen 'cos id is #REQUIRED */ ret = sscanf(a->value, "bk%d", &BOOKP->curBook->id); ASSERT_SCANF_ABORT(ret, 1, a->qname); } else if (!strcmp(qName, "author")) BOOKP->fld = offsetof(BOOK, author); else if (!strcmp(qName, "title")) BOOKP->fld = offsetof(BOOK, title); else if (!strcmp(qName, "genre")) BOOKP->fld = offsetof(BOOK, genre); else if (!strcmp(qName, "price")) BOOKP->fld = offsetof(BOOK, price); else if (!strcmp(qName, "publish_date")) BOOKP->fld = offsetof(BOOK, publish_date); else if (!strcmp(qName, "description")) BOOKP->fld = offsetof(BOOK, description); return XML_OK; }
static int AddUri(LPXMLVECTOR *v, LPXMLRUNTIMEATT idAtt) { struct IDs *id; LPXMLRUNTIMEATT a; ASSERT_MEM_ABORT(idAtt); /* shouldn't happen */ if (!*v) { XMLVector_Create(v, 0, sizeof(struct IDs)); ASSERT_MEM_ABORT(*v); } id = XMLVector_Append(*v, NULL); ASSERT_MEM_ABORT(id); id->uri = NULL; id->id = strdup(idAtt->value); ASSERT_MEM_ABORT(id->id); a = XMLParser_GetNamedItem(parser, "uri"); ASSERT_MEM_ABORT(a); return GetUriAndBase(a, &id->uri); }
int RunTest(XMLCONFPARSER *xcp, char *uri) { LPXMLRUNTIMEATT att, tatt; XMLCH testuri[MAX_PATH]; XMLCH xmlbase[MAX_PATH]; XMLCH id[256]; XMLCH *s; FILE *f; RUNPARSERDATA rdata; int result, expect; LPXMLPARSER parser = xcp->runParser; int type; if ((s = XMLParser_GetPrefixMapping(xcp->parser, "xml:base"))) strcpy(xmlbase, s); /* we save current xmlbase (although it shouldn't get modified 'cos main parser isn't running during RunTest()) */ else { /* rmt-e2e-18: External entity containing start of entity declaration is base URI for system identifier, so: */ XMLCH *sysID = XMLParser_GetSystemID(xcp->parser); if (!sysID) xmlbase[0] = '\0'; else GetBaseDir(sysID, xmlbase); } strcpy(testuri, xmlbase); strcat(testuri, uri); puts(testuri); /* resolve basedir for external entities, DTD and for canonxml */ GetBaseDir(testuri, rdata.testbasedir); tatt = XMLParser_GetNamedItem(xcp->parser, "TYPE"); if (tatt) { /* "Nonvalidating parsers must also accept "invalid" testcases, but validating ones must reject them." */ if (!strcmp(tatt->value, "valid")) type = TYPE_VALID; else if (!strcmp(tatt->value, "invalid")) type = TYPE_INVALID; else type = TYPE_OTHER; /* error, not-wf */ } if ((f = fopen(testuri, "rb"))) { #ifdef TEST_VALIDATING xcp->v->UserData = &rdata; xcp->v->UserFlag = type; xcp->v->startElementHandlerFilter = StartElementDetermineValidation; result = XMLParser_ParseValidateDTD(xcp->v, parser, cstream, f, 0); #else parser->UserData = &rdata; result = XMLParser_Parse(parser, cstream, f, 0); #endif fclose(f); } else { fprintf(PFERR, "Error opening file %s\n", testuri); return 0; } xcp->testCount++; /* 1 row columns: ID, TYPE, PASS/FAIL, ERRORSTRING 2 row columns: ENTITIES + OUTPUT in one col, 3 empty cols 3 row: test description, 3 empty cols */ att = XMLParser_GetNamedItem(xcp->parser, "ID"); strcpy(id, (att) ? att->value : "unknown"); fputs((xcp->testCount % 2) ? "<tr bgcolor='#EEEEEE'>" : "<tr>", xcp->pfout); fprintf(xcp->pfout, "<td><a href='%s'>%s</a></td>", testuri, id); if (tatt) { if (type == TYPE_VALID) expect = 1; else if (type == TYPE_INVALID) #ifdef TEST_VALIDATING expect = 0; #else expect = 1; #endif else expect = 0; fprintf(xcp->pfout, "<td>%s</td>", tatt->value); if (result == expect) xcp->testSuccess++; }
static int ValidateAtts(LPXMLDTDVALIDATOR v, struct ElementDecl *e, LPXMLVECTOR atts) { LPXMLATTDECL da, da2; LPXMLRUNTIMEATT a, ae; int numAtts; if (e->declAtts) { da2 = (LPXMLATTDECL)_XMLVector_GetIterP(e->declAtts, da); for (;da!=da2;da++) { if (da->defaultDecl != XMLATTDECL_DEF_REQUIRED) break; a = XMLParser_GetNamedItem(v->parser, da->name); if (!a) { Er_(v, NULL, ERR_XMLDTDV_REQUIRED_ATT_MISSING, da->name, e->name); MAYRET(0); continue; } if (da->type > XMLATTDECL_TYPE_NMTOKENS && !ValidateAttsEnum(da->pExt, a->value)) { Er_(v, da->pExt, ERR_XMLDTDV_ILLEGAL_ATT_VALUE, a->qname, e->name); MAYRET(0); } else if (da->type != XMLATTDECL_TYPE_CDATA && !ValidateAttsTok(v, da->type, e->name, a->qname, a->value)) { if (!v->ErrorCode) { Er_(v, NULL, ERR_XMLDTDV_MEMORY_ALLOC); return 0; } MAYRET(0); } a->value = EMPTYSTR; /* hack for marking this attribute processed */ } numAtts = da2-da; /* maybe 0 (only #REQUIRED atts declared) */ } else numAtts = 0; /* no declared atts */ ae = (LPXMLRUNTIMEATT)_XMLVector_GetIterP(atts, a); for (;a!=ae;a++) { if (_XMLParser_AttIsDefaulted(a)) break; /* defaulted atts are always at the end so don't test further */ else if (a->value == EMPTYSTR) /* already processed */ a->value = a->valBuf.str; else { da2 = (numAtts) ? bsearch(a->qname, da, numAtts, sizeof(XMLATTDECL), sattcmp) : NULL; if (!da2) { Er_(v, NULL, ERR_XMLDTDV_UNDECLARED_ATT, a->qname, e->name); MAYRET(0); } else if (da2->defaultDecl == XMLATTDECL_DEF_FIXED && strcmp(a->value, da2->value)) { Er_(v, NULL, ERR_XMLDTDV_ILLEGAL_ATT_VALUE, a->qname, e->name); MAYRET(0); } else if (da2->type > XMLATTDECL_TYPE_NMTOKENS && !ValidateAttsEnum(da2->pExt, a->value)) { Er_(v, da2->pExt, ERR_XMLDTDV_ILLEGAL_ATT_VALUE, a->qname, e->name); MAYRET(0); } else if (da2->type != XMLATTDECL_TYPE_CDATA && !ValidateAttsTok(v, da2->type, e->name, a->qname, a->value)) { if (!v->ErrorCode) { Er_(v, NULL, ERR_XMLDTDV_MEMORY_ALLOC); return 0; } MAYRET(0); } } } return 1; }