/* only compile this if LIBEXPAT is defined. */ #ifdef LIBEXPAT /* File that provides the entry point for an event driven XML parser that performs callbacks to the different user-level functions in the closure passed to it. * See Copyright for the license status of this software. */ #include "EventParse.h" #include "Utils.h" /* For the findFunction and invokeFunction. */ #include "RSCommon.h" #include "ExpatParse.h" void RS_XML(initParser)(XML_Parser parser, RS_XMLParserData *parserData) { XML_SetUserData(parser, parserData); XML_SetElementHandler(parser, RS_XML(startElement), RS_XML(endElement)); XML_SetCommentHandler(parser, RS_XML(commentHandler)); XML_SetExternalEntityRefHandler(parser, RS_XML(externalEntityHandler)); XML_SetUnparsedEntityDeclHandler(parser, RS_XML(entityDeclarationHandler)); XML_SetCharacterDataHandler(parser, RS_XML(textHandler)); XML_SetProcessingInstructionHandler(parser, RS_XML(processingInstructionHandler)); XML_SetCdataSectionHandler(parser, RS_XML(startCdataSectionHandler), RS_XML(endCdataSectionHandler)); XML_SetBase(parser, parserData->fileName); XML_SetNotStandaloneHandler(parser, RS_XML(notStandAloneHandler)); } int RS_XML(parse)(FILE *file, USER_OBJECT_ handlers) { RS_XMLParserData *parserData; parserData = RS_XML(createParserData)(handlers); return(RS_XML(parseWithParserData)(file, parserData)); } int RS_XML(parseWithParserData)(FILE *file, RS_XMLParserData *parserData) { char buf[BUFSIZ]; int done; XML_Parser parser = XML_ParserCreate(NULL); RS_XML(initParser)(parser, parserData); do { size_t len = fread(buf, 1, sizeof(buf), file); done = len < sizeof(buf); if (!XML_Parse(parser, buf, len, done)) { Rf_warning("%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); return 1; } } while (!done); XML_ParserFree(parser); return 0; } int RS_XML(parseBufferWithParserData)(char *buf, RS_XMLParserData *parserData) { int status; XML_Parser parser = XML_ParserCreate(NULL); RS_XML(initParser)(parser, parserData); status = XML_Parse(parser, buf, strlen(buf), 1); if(status == 0) { const char *msg = XML_ErrorString(XML_GetErrorCode(parser)); Rf_error("XML Parser Error: %s", msg); } return(status); } int RS_XML(externalEntityHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId) { RS_XMLParserData *parserData = (RS_XMLParserData*)XML_GetUserData(parser); USER_OBJECT_ opArgs; int i, num; const XML_Char *xml_args[4]; num = sizeof(xml_args)/sizeof(xml_args[0]); xml_args[0] = context; xml_args[1] = base;xml_args[2] = systemId; xml_args[3] = publicId; opArgs = NEW_LIST(num); for(i =0;i < num; i++) { RECURSIVE_DATA(opArgs)[i] = NEW_CHARACTER(1); CHARACTER_DATA(RECURSIVE_DATA(opArgs)[i])[0] = ENC_COPY_TO_USER_STRING(xml_args[i] ? xml_args[i] : ""); } RS_XML(callUserFunction)("externalEntity", NULL, parserData, opArgs); return(1); /* ok to go on */ } #else /* Something to avoid an empty file.*/ void XML_Expat_unused_dummy(void) { } #endif /* only if LIBEXPAT is defined */