static int InitValidator(LPXMLDTDVALIDATOR v) { struct ElementDecl *e, *ee; struct FSAState *s; LPXMLVECTOR *declAtts; void **d; ee = (struct ElementDecl *)_XMLVector_GetIterP(v->ElementDecls, e); for (; e!=ee; e++) { /* important: every 1. content particle contains a pointer to hastablebucket in its name, we MUST assign hashtable data here, we cannot alter the cpNames table when DTD parsing is in progress! */ d = (void**)XMLHTable_GetData(v->parser->prt->cpNames, (XMLHTABLEBUCKET*)e->cp->name); if (*d != EMPTYSTR) continue; /* duplicate declaration */ *d = e; switch (e->type) { case XMLCTYPE_ANY: case XMLCTYPE_EMPTY: break; case XMLCTYPE_MIXED: if (!e->cp->children) /* simple #PCDATA */ break; /* note that we can't easily simplify the (e) type content models (which is actually XMLCTYPE_CHOICE) - since we must allow (e)* or ((e))? etc. */ default: v->fsa = XMLVector_Create(&e->fsa, 4, sizeof(struct FSAState*)); if (!e->fsa) return 0; s = AddState(v); if (!s) return 0; SET_SMARK(s, SMARK_FINAL, 1); e->startState = CreateNFA(v, e->cp, s); if (!e->startState) return 0; #ifdef PRINT_FSA PrintFSA(e, "NFA"); if (!NFAtoDFA(v, e)) return 0; PrintFSA(e, "DFA"); #else if (!NFAtoDFA(v, e)) return 0; #endif } if (v->parser->prt->declAttTable) { declAtts = XMLHTable_Lookup(v->parser->prt->declAttTable, e->name); if (declAtts) { e->declAtts = *(declAtts+1); if (e->declAtts->length > 1) qsort((void*)e->declAtts->array, e->declAtts->length, sizeof(XMLATTDECL), attcmp); } } } v->ElementTable = v->parser->prt->cpNames; v->cpNodesPool = v->parser->prt->cpNodesPool; return 1; }
struct XMLReader_t *XMLReader_Create(struct XMLReader_t *r, int validating) { int i; if (!r) { r=malloc(sizeof(*r)); ASSERT_MEM_SETERR(r); r->dynamicalloc = 1; } memset(r, 0, sizeof *r); ASSERT_MEM_SETERR(XMLParser_Create(&r->parser)); XMLVector_Create(&r->atts, 0, sizeof(struct XMLReaderAttribute_t)); ASSERT_MEM_SETERR(r->atts); XMLVector_Create(&r->eventbuffer, 0, sizeof(union XMLReaderNode_t)); ASSERT_MEM_SETERR(r->eventbuffer); for (i=0; i<sizeof(r->buf)/sizeof(r->buf[0]); i++) { ASSERT_MEM_SETERR(XMLStringbuf_Init(&r->buf[i], 256, 256)); } _XMLParser_SetFlag(r->parser, XMLFLAG_USE_SIMPLEPULL, 1); if (validating) { ASSERT_MEM_SETERR(r->dtdv = XMLParser_CreateDTDValidator()); r->dtdv->UserData = r; r->parser->errorHandler = ErrorHandlerV; r->parser->startElementHandler = StartElementV; r->parser->endElementHandler = EndElementV; r->parser->charactersHandler = CharsV; r->parser->commentHandler = CommentV; r->parser->processingInstructionHandler = PiV; r->parser->endDocumentHandler = EndDocumentV; } else { r->parser->UserData = r; r->parser->errorHandler = ErrorHandlerN; r->parser->startElementHandler = StartElementN; r->parser->endElementHandler = EndElementN; r->parser->charactersHandler = CharsN; r->parser->commentHandler = CommentN; r->parser->processingInstructionHandler = PiN; } return r; }
static int AddNextCatalog(LPXMLRUNTIMEATT cat) { XMLCH **uri; ASSERT_MEM_ABORT(cat); /* shouldn't happen */ if (!nextCatalog) { XMLVector_Create(&nextCatalog, 0, sizeof(char*)); ASSERT_MEM_ABORT(nextCatalog); } uri = XMLVector_Append(nextCatalog, NULL); ASSERT_MEM_ABORT(uri); return GetUriAndBase(cat, uri); }
static struct FSATran *AddTran(struct FSAState *src, struct FSAState *dst, void *label) { struct FSATran *t; if (!src->trans) { XMLVector_Create(&src->trans, 4, sizeof(struct FSATran)); CHKMEM(src->trans); } t = XMLVector_Append(src->trans, NULL); CHKMEM(t); t->label = label; t->src = src; t->dst = dst; return t; }
LPXMLDTDVALIDATOR XMLAPI XMLParser_CreateDTDValidator(void) { LPXMLDTDVALIDATOR v = malloc(sizeof(XMLDTDVALIDATOR)); if (!v) return NULL; memset(v, 0, sizeof(XMLDTDVALIDATOR)); XMLVector_Create(&v->ElementDecls, 16, sizeof(struct ElementDecl)); if (!v->ElementDecls) goto ExitErr; XMLVector_Create(&v->ContextStack, 0, sizeof(struct vContext)); if (!v->ContextStack) goto ExitErr; v->StatePool = XMLPool_Create(sizeof(struct FSAState), 16); if (!v->StatePool) goto ExitErr; v->startElementHandlerFilter = DTDValidate_StartElement; v->endElementHandlerFilter = DTDValidate_EndElement; v->charactersHandlerFilter = DTDValidate_Characters; v->ignorableWhitespaceHandlerFilter = DTDValidate_IgnorableWhitespace; return v; ExitErr: if (v->ElementDecls) XMLVector_Free(v->ElementDecls); if (v->ContextStack) XMLVector_Free(v->ContextStack); if (v->StatePool) XMLPool_FreePool(v->StatePool); free(v); return NULL; }
int vfilter_Init(LPXMLDTDVALIDATOR dtd, char *uri) { if (dtd) { vuri = uri; if (!XMLVector_Create(&filteredAtts, 0, sizeof(XMLRUNTIMEATT))) { fputs("Out of memory!", stderr); return 0; } dtd->startElementHandlerFilter = StartElement; dtd->endElementHandlerFilter = EndElement; dtd->charactersHandlerFilter = Characters; dtd->ignorableWhitespaceHandlerFilter = IgnorableWS; } return 1; }
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 main(int argc, char* argv[]) { NSVALIDPARSER nsparser; LPXMLPARSER parser; LPXMLDTDVALIDATOR vp; FILE *f; int i; XMLCH *filename = NULL; if (argc < 2 || argc > 4) goto USAGE; nsparser.elemCount = 0; nsparser.wantedUri = ""; *nsparser.userDTD = '\0'; *nsparser.base = '\0'; for (i=1; i<argc; i++) { if (!strncmp(argv[i], "/DTD:", 5)) strcpy(nsparser.userDTD, argv[i]+5); else if (!strncmp(argv[i], "/URI:", 5)) nsparser.wantedUri = argv[i]+5; else { if (filename) goto USAGE; filename = argv[i]; } } if (!filename) goto USAGE; if (!XMLParser_Create(&parser)) { puts("Out of memory!"); return 1; } vp = XMLParser_CreateDTDValidator(); if (!vp) { puts("Out of memory!"); return 1; } if (!XMLVector_Create(&nsparser.filteredAtts, 0, sizeof(XMLRUNTIMEATT))) { puts("Out of memory!"); return 1; } vp->UserData = &nsparser; parser->errorHandler = ErrorHandler; parser->resolveEntityHandler = ResolveEntity; parser->externalEntityParsedHandler = FreeInputData; if (*nsparser.userDTD) { int filepos = GetBaseDir(nsparser.base, nsparser.userDTD); if (filepos) strcpy(nsparser.userDTD, nsparser.userDTD+filepos); XMLParser_SetExternalSubset(parser, NULL, nsparser.userDTD); } if (!*nsparser.base) GetBaseDir(nsparser.base, filename); if (*nsparser.wantedUri) { vp->startElementHandlerFilter = StartElement; vp->endElementHandlerFilter = EndElement; vp->charactersHandlerFilter = Characters; vp->ignorableWhitespaceHandlerFilter = IgnorableWS; } else /* simple validator w/o namespace filter: */ parser->startElementHandler = StartElementSimple; if (!(f = fopen(filename, "rb"))) { printf("Error opening file %s\n", filename); return 1; } if (XMLParser_ParseValidateDTD(vp, parser, cstream, f, 0)) { printf("Elements (total: %d) in namespace \"%s\" were valid\nin the" " document %s\n", nsparser.elemCount, ((*nsparser.wantedUri) ? nsparser.wantedUri : "not specified"), filename); } fclose(f); XMLVector_Free(nsparser.filteredAtts); XMLParser_FreeDTDValidator(vp); XMLParser_Free(parser); return 0; USAGE: puts("Usage: nsvalid document.xml /DTD:<optional> /URI:<optional>\n" "Example: nsvalid my.xml /DTD:/home/my.dtd /URI:http://my.org"); return 1; }
static int NFAtoDFA(LPXMLDTDVALIDATOR vp, struct ElementDecl *e) { struct FSAState **sw, **s, **se; struct FSATran *t, *te; LPXMLVECTOR o; int i; XMLVector_Create(&o, 0, sizeof(struct FSAState*)); if (!o) return 0; SET_SMARK(e->startState, SMARK_USEFUL, 1); se = (struct FSAState **)_XMLVector_GetIterP(e->fsa, s); for (;s!=se;s++) { if ((*s)->trans) { te = (struct FSATran *)_XMLVector_GetIterP((*s)->trans, t); for (; t!=te; t++) { if (t->label != epsilon) { SET_SMARK(t->dst, SMARK_USEFUL, 1); } } } } se = (struct FSAState **)_XMLVector_GetIterP(e->fsa, s); for (;s!=se;s++) { if ((*s)->mark & SMARK_USEFUL) { SET_SMARK((*s), SMARK_INUSE, 1); if ((*s)->trans) { for (i=0; i<(*s)->trans->length; i++) { t = XMLVector_Get((*s)->trans, i); if (t->label == epsilon) { if (!AddEpsilonClosure(*s, t->dst)) return 0; } } } UnMarkFSA(e->fsa, SMARK_INUSE); } } se = (struct FSAState **)_XMLVector_GetIterP(e->fsa, s); for (;s!=se;s++) { if ((*s)->mark & SMARK_USEFUL) { if ((*s)->trans) { for (i=0; i<(*s)->trans->length; i++) { t = XMLVector_Get((*s)->trans, i); if (t->label == epsilon) { if (!XMLVector_Remove((*s)->trans, i)) return 0; i--; } } } sw = XMLVector_Append(o, NULL); if (!sw) return 0; *sw = *s; } else if ((*s)->trans) { XMLVector_Free((*s)->trans); } } XMLVector_Free(e->fsa); e->fsa = o; return 1; }
int main(int argc, char* argv[]) { BOOKPARSER bparser; BOOK *b; LPXMLPARSER parser; LPXMLDTDVALIDATOR vp; int i, success; if (!XMLParser_Create(&parser)) { puts("Error creating parser!"); return 1; } vp = XMLParser_CreateDTDValidator(); if (!vp) { puts("Error creating DTDValidator in main()"); return 1; } if (!XMLVector_Create(&bparser.books, 6, sizeof(BOOK))) { puts("Error creating books vector in main()"); return 1; } /* init Stringbuf: blockSize 256, no pre-allocation: */ XMLStringbuf_Init(&bparser.textBuf, 256, 0); vp->UserData = &bparser; parser->errorHandler = ErrorHandler; parser->startElementHandler = StartElement; parser->endElementHandler = EndElement; parser->charactersHandler = Characters; success = XMLParser_ParseValidateDTD(vp, parser, cstream, stdin, 0); for (i=0; i<bparser.books->length; i++) { b = XMLVector_Get(bparser.books, i); if (success) printf("id: %d\n" "author: %s\n" "title: %s\n" "genre: %s\n" "price: %f\n" "publish_date: %s\n" "description: %s\n\n", b->id, b->author, b->title, b->genre, b->price, b->publish_date, b->description ); SAFE_FREE(b->author); SAFE_FREE(b->title); SAFE_FREE(b->genre); SAFE_FREE(b->publish_date); SAFE_FREE(b->description); } XMLParser_FreeDTDValidator(vp); XMLParser_Free(parser); XMLStringbuf_Free(&bparser.textBuf); XMLVector_Free(bparser.books); return 0; }