static void PrintFSA(struct ElementDecl *e, XMLCH *type) { int i, j; struct FSAState *s, **ss; struct FSATran *t; #ifdef PRINT_FSA_ELEMENT /* outputs automaton only for this element*/ if (strcmp(e->name, PRINT_FSA_ELEMENT)) return; #endif printf("%s for element \"%s\":\n", type, e->name); for (i=0; i<e->fsa->length; i++) { ss = XMLVector_Get(e->fsa, i); s = *ss; if(s == e->startState || s->mark & SMARK_FINAL) { if (s==e->startState) printf("%p [Start]\n", s); if (s->mark & SMARK_FINAL) printf("%p [End]\n", s); } else printf("%p\n", s); if (s->trans) { for (j=0; j<s->trans->length; j++) { t = XMLVector_Get(s->trans, j); if (t->label == epsilon) printf(" [epsilon] -> %p\n", t->dst); else printf(" %s -> %p\n", ((XMLCP*)t->label)->name, t->dst); } } } }
int StartElement(struct XMLReader_t *r, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { union XMLReaderNode_t *rn = XMLVector_Append(r->eventbuffer, NULL); ASSERT_MEM_ABORT(rn); rn->type = XMLREADERTYPE_STARTELEMENT; ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)uri, rn->startelement.ibuf[0])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)localName, rn->startelement.ibuf[1])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)qName, rn->startelement.ibuf[2])); if (r->atts->length) ASSERT_MEM_ABORT(_XMLVector_RemoveAll(r->atts)); if (atts->length) { struct XMLReaderAttribute_t *a; int i; for (i=0; i<atts->length; i++) { LPXMLRUNTIMEATT aa = XMLVector_Get(atts, i); ASSERT_MEM_ABORT(a = XMLVector_Append(r->atts, NULL)); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->uri, a->ibuf[0])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->localName, a->ibuf[1])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->qname, a->ibuf[2])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->value, a->ibuf[3])); } } return XML_OK; }
int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData; if (!strcmp(uri, NSVALIDP->wantedUri)) { LPXMLVECTOR attsF; if (v->UserFlag) v->UserFlag = 0; NSVALIDP->elemCount++; if (!atts->length) attsF = atts; else { int i; LPXMLRUNTIMEATT a; if (NSVALIDP->filteredAtts->length) _XMLVector_RemoveAll(NSVALIDP->filteredAtts); for (i=0; i<atts->length; i++) { a = XMLVector_Get(atts, i); if (!*a->uri || !strcmp(a->uri, NSVALIDP->wantedUri)) a = XMLVector_Append(NSVALIDP->filteredAtts, a); ASSERT_MEM_ABORT(a); } attsF = NSVALIDP->filteredAtts; } return DTDValidate_StartElement(v, uri, localName, localName, attsF); } v->UserFlag++; return XML_OK; }
static int AddEpsilonClosure(struct FSAState *base, struct FSAState *state) { int i; struct FSATran *t1, *t2, *te2; if (state->mark & SMARK_INUSE) return 1; SET_SMARK(state, SMARK_INUSE, 1); if (state->mark & SMARK_FINAL) { SET_SMARK(base, SMARK_FINAL, 1); } if (!state->trans) return 1; for (i=0; i<state->trans->length; i++) { t1 = XMLVector_Get(state->trans, i); if (t1->label == epsilon) { if (!AddEpsilonClosure(base, t1->dst)) return 0; } else { te2 = (struct FSATran *)_XMLVector_GetIterP(base->trans, t2); for (; t2!=te2; t2++) { if(t2->label == t1->label && t2->dst == t1->dst) break; } if(t2 == te2) { if (!AddTran(base, t1->dst, t1->label)) return 0; } } } return 1; }
static void CleanupIds(LPXMLVECTOR v) { int i; for (i=0; i<v->length; i++) { struct IDs *id = XMLVector_Get(v, i); if (id->id) free(id->id); if (id->uri) free(id->uri); } XMLVector_Free(v); }
static void Er_Hint(LPXMLDTDVALIDATOR p, void *errCtx, int n) { int i=0, j; XMLCH *s; LPXMLVECTOR v = (p->ErrorCode==ERR_XMLDTDV_ILLEGAL_ATT_VALUE) ? errCtx : ((struct FSAState*)errCtx)->trans; if (v==NULL || !v->length) return; do { if (p->ErrorCode==ERR_XMLDTDV_ILLEGAL_ATT_VALUE) { XMLATTENUM *av = XMLVector_Get(v, i); s = av->name; } else { struct FSATran *t = XMLVector_Get(v, i); s = ((XMLCP*)t->label)->name; } j = strlen(s); if (++i==1) { if (n+j+7 > 127) return; memcpy(p->ErrorString+n, ". Try: ", 7); n+=7; } else { if (n+j+2 > 127) break; p->ErrorString[n++] = ','; p->ErrorString[n++] = ' '; } memcpy(p->ErrorString+n, s, j); n+=j; } while (i<4 && i<v->length); if (i!=v->length && !(n+3 > 127)) { p->ErrorString[n++] = '.'; p->ErrorString[n++] = '.'; p->ErrorString[n++] = '.'; } p->ErrorString[n]='\0'; }
union XMLReaderNode_t *XMLReader_Read(struct XMLReader_t *r) { do { if (r->eventbuffer->length) { if (r->eventbufferpos == r->eventbuffer->length) { /* for (i=0; i<sizeof(r->buf)/sizeof(r->buf[0]); i++) */ if (r->buf[0].len) XMLStringbuf_SetLength(&r->buf[0], 0); if (r->buf[1].len) XMLStringbuf_SetLength(&r->buf[1], 0); if (r->buf[2].len) XMLStringbuf_SetLength(&r->buf[2], 0); _XMLVector_RemoveAll(r->eventbuffer); r->eventbufferpos = 0; } else { union XMLReaderNode_t *rn = XMLVector_Get(r->eventbuffer, r->eventbufferpos); if (r->buf[0].len) { ASSERT_MEM_SETERR(XMLStringbuf_ToString(&r->buf[0])); if (rn->type == XMLREADERTYPE_CHARS) { rn->chars.text = r->buf[0].str; rn->chars.length = r->buf[0].len; } else if (rn->type == XMLREADERTYPE_COMMENT) { rn->comment.text = r->buf[0].str; rn->comment.length = r->buf[0].len; } r->buf[0].len = 0; } else { switch(rn->type) { case XMLREADERTYPE_STARTELEMENT: rn->startelement.uri = IBUF_GET(&r->buf[1], rn->startelement.ibuf[0]); rn->startelement.localname = IBUF_GET(&r->buf[1], rn->startelement.ibuf[1]); rn->startelement.qname = IBUF_GET(&r->buf[1], rn->startelement.ibuf[2]); rn->startelement.atts = r->atts; break; case XMLREADERTYPE_ENDELEMENT: rn->endelement.uri = IBUF_GET(&r->buf[1], rn->endelement.ibuf[0]); rn->endelement.localname = IBUF_GET(&r->buf[1], rn->endelement.ibuf[1]); rn->endelement.qname = IBUF_GET(&r->buf[1], rn->endelement.ibuf[2]); break; } } r->eventbufferpos++; return rn; } } } while (XMLParser_HasMoreEvents(r->parser)); return NULL; }
void Catalogs_Cleanup(void) { if (publicIDS) CleanupIds(publicIDS); if (systemIDS) CleanupIds(systemIDS); if (nextCatalog) { int i; char **uri; for (i=0; i<nextCatalog->length; i++) { uri = XMLVector_Get(nextCatalog, i); if (*uri) free(*uri); } XMLVector_Free(nextCatalog); } }
int main(int argc, char* argv[]) { struct XMLReader_t r; if (!XMLReader_Create(&r, 0)) { puts("Error creating parser"); return EXIT_FAILURE; } if (XMLReader_Parse(&r, cstream, stdin, 0)) { union XMLReaderNode_t *rn; int i; while((rn = XMLReader_Read(&r))) { if (rn->type == XMLREADERTYPE_STARTELEMENT) { if (!strcmp((const char*)rn->startelement.qname, "toni.uusitalo")) { printf("Don't be silly, illegal naming policy of xml element,\n" "Your parsing will be terminated immediately!\n"); XMLReader_AbortParse(&r); break; /* note: DON'T call Read after AbortParse */ } printf("STARTELEMENT -- uri: %s localName: %s qName: %s\n" " attributes count: %d\n", rn->startelement.uri, rn->startelement.localname, rn->startelement.qname, rn->startelement.atts->length); for(i=0; i<rn->startelement.atts->length; i++) { struct XMLReaderAttribute_t *a = XMLVector_Get(rn->startelement.atts, i); printf(" name: %s value: %s\n", XMLReader_GetAttributeQName(&r, a), XMLReader_GetAttributeValue(&r, a)); } } else if (rn->type == XMLREADERTYPE_ENDELEMENT) { printf("ENDELEMENT -- uri: %s localName: %s qName: %s\n", rn->endelement.uri, rn->endelement.localname, rn->endelement.qname); } else if (rn->type == XMLREADERTYPE_CHARS) { printf("CHARS -- text: %s length: %d\n", rn->chars.text, rn->chars.length); } else if (rn->type == XMLREADERTYPE_COMMENT) { printf("COMMENT -- text: %s length: %d\n", rn->comment.text, rn->comment.length); } else if (rn->type == XMLREADERTYPE_PI) { printf("PROCESSINGINSTRUCTION -- target: %s data: %s\n", rn->pi.target, rn->pi.data); } } /* while read != NULL */ } /* parse ok */ if (r.errorcode) { if (r.errorcode == ERR_XMLP_VALIDATION) fprintf(stderr, "\nValidation Error: %s\nAt line %d, col %d, code %d\n", r.dtdv->ErrorString, r.dtdv->ErrorLine, r.dtdv->ErrorColumn, r.dtdv->ErrorCode); else fprintf(stderr, "\nParsing Error: %s\nAt line %d, col %d, code %d\n", r.parser->ErrorString, r.parser->ErrorLine, r.parser->ErrorColumn, r.errorcode); } XMLReader_Free(&r); return 0; }
static int ValidateAttsEnum(LPXMLVECTOR e, XMLCH *val) { if (e->length == 1) return (!strcmp(((XMLATTENUM*)XMLVector_Get(e, 0))->name, val)); return (bsearch(val, e->array, e->length, sizeof(XMLATTENUM), ecmp)!=NULL); }
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 Catalogs_Init(void) { LPXMLDTDVALIDATOR dtd; FILE *f; int ret=1, i=0; char t[FILENAME_MAX]; char *env = getenv("XML_CATALOG_FILES"); if (!env) doc = "/etc/xml/catalog"; if (!XMLParser_Create(&parser)) { fputs("Out of memory\n", stderr); return 0; } if (!(dtd = XMLParser_CreateDTDValidator())) { XMLParser_Free(parser); fputs("Out of memory\n", stderr); return 0; } XMLParser_SetExternalSubset(parser, NULL, "catalog_flat.dtd"); parser->startElementHandler = StartElement; parser->errorHandler = ErrorHandler; parser->resolveEntityHandler = ResolveEntity; parser->externalEntityParsedHandler = FreeInputData; while (ret) { if (env) doc = mstrtok(&env, t, sizeof(t)/sizeof(t[0]), ';'); if (!doc) { if (env && *env) { ret = 0; fprintf(stderr, "Erroneous token in XML_CATALOG FILES: %s\n", env); } break; } while (doc) { if (!(f = mfopen(doc, "rb"))) { fprintf(stderr, "Error opening file %s\n", doc); ret = 0; break; } ret = XMLParser_ParseValidateDTD(dtd, parser, filestream, f, 0); fclose(f); if (!ret || !nextCatalog || i == nextCatalog->length) doc = NULL; else { char **uri = XMLVector_Get(nextCatalog, i++); doc = *uri; } } } if (ret) { if (publicIDS && publicIDS->length > 1) qsort(publicIDS->array, publicIDS->length, sizeof(struct IDs), (int(*)(const void*, const void*))idsort); if (systemIDS && systemIDS->length > 1) qsort(systemIDS->array, publicIDS->length, sizeof(struct IDs), (int(*)(const void*, const void*))idsort); } XMLParser_FreeDTDValidator(dtd); XMLParser_Free(parser); return ret; }
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; }