📄 expat.xs
字号:
Safefree(model); PUSHMARK(sp); EXTEND(sp, 3); PUSHs(cbv->self_sv); PUSHs(sv_2mortal(newUTF8SVpv((char *)name, 0))); PUSHs(sv_2mortal(cmod)); PUTBACK; perl_call_sv(cbv->eledcl_sv, G_DISCARD); FREETMPS; LEAVE;} /* End elementDecl */static voidattributeDecl(void *data, const char * elname, const char * attname, const char * att_type, const char * dflt, int reqorfix) { dSP; CallbackVector *cbv = (CallbackVector*) data; SV * dfltsv; if (dflt) { dfltsv = newUTF8SVpv("'", 1); sv_catpv(dfltsv, (char *) dflt); sv_catpv(dfltsv, "'"); } else { dfltsv = newUTF8SVpv(reqorfix ? "#REQUIRED" : "#IMPLIED", 0); } ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 5); PUSHs(cbv->self_sv); PUSHs(sv_2mortal(newUTF8SVpv((char *)elname, 0))); PUSHs(sv_2mortal(newUTF8SVpv((char *)attname, 0))); PUSHs(sv_2mortal(newUTF8SVpv((char *)att_type, 0))); PUSHs(sv_2mortal(dfltsv)); if (dflt && reqorfix) XPUSHs(&PL_sv_yes); PUTBACK; perl_call_sv(cbv->attdcl_sv, G_DISCARD); FREETMPS; LEAVE;} /* End attributeDecl */static voidentityDecl(void *data, const char *name, int isparam, const char *value, int vlen, const char *base, const char *sysid, const char *pubid, const char *notation) { dSP; CallbackVector *cbv = (CallbackVector*) data; ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 6); PUSHs(cbv->self_sv); PUSHs(sv_2mortal(newUTF8SVpv((char*)name, 0))); PUSHs(value ? sv_2mortal(newUTF8SVpvn((char*)value, vlen)) : &PL_sv_undef); PUSHs(sysid ? sv_2mortal(newUTF8SVpv((char *)sysid, 0)) : &PL_sv_undef); PUSHs(pubid ? sv_2mortal(newUTF8SVpv((char *)pubid, 0)) : &PL_sv_undef); PUSHs(notation ? sv_2mortal(newUTF8SVpv((char *)notation, 0)) : &PL_sv_undef); if (isparam) XPUSHs(&PL_sv_yes); PUTBACK; perl_call_sv(cbv->entdcl_sv, G_DISCARD); FREETMPS; LEAVE;} /* End entityDecl */static voiddoctypeStart(void *userData, const char* name, const char* sysid, const char* pubid, int hasinternal) { dSP; CallbackVector *cbv = (CallbackVector*) userData; ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 5); PUSHs(cbv->self_sv); PUSHs(sv_2mortal(newUTF8SVpv((char*)name, 0))); PUSHs(sysid ? sv_2mortal(newUTF8SVpv((char*)sysid, 0)) : &PL_sv_undef); PUSHs(pubid ? sv_2mortal(newUTF8SVpv((char*)pubid, 0)) : &PL_sv_undef); PUSHs(hasinternal ? &PL_sv_yes : &PL_sv_no); PUTBACK; perl_call_sv(cbv->doctyp_sv, G_DISCARD); FREETMPS; LEAVE;} /* End doctypeStart */static voiddoctypeEnd(void *userData) { dSP; CallbackVector *cbv = (CallbackVector*) userData; ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 1); PUSHs(cbv->self_sv); PUTBACK; perl_call_sv(cbv->doctypfin_sv, G_DISCARD); FREETMPS; LEAVE;} /* End doctypeEnd */static voidxmlDecl(void *userData, const char *version, const char *encoding, int standalone) { dSP; CallbackVector *cbv = (CallbackVector*) userData; ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 4); PUSHs(cbv->self_sv); PUSHs(version ? sv_2mortal(newUTF8SVpv((char *)version, 0)) : &PL_sv_undef); PUSHs(encoding ? sv_2mortal(newUTF8SVpv((char *)encoding, 0)) : &PL_sv_undef); PUSHs(standalone == -1 ? &PL_sv_undef : (standalone ? &PL_sv_yes : &PL_sv_no)); PUTBACK; perl_call_sv(cbv->xmldec_sv, G_DISCARD); FREETMPS; LEAVE;} /* End xmlDecl */static voidunparsedEntityDecl(void *userData, const char* entity, const char* base, const char* sysid, const char* pubid, const char* notation){ dSP; CallbackVector* cbv = (CallbackVector*) userData; ENTER; SAVETMPS; PUSHMARK(sp); EXTEND(sp, 6); PUSHs(cbv->self_sv); PUSHs(sv_2mortal(newUTF8SVpv((char*) entity, 0))); PUSHs(base ? sv_2mortal(newUTF8SVpv((char*) base, 0)) : &PL_sv_undef); PUSHs(sv_2mortal(newUTF8SVpv((char*) sysid, 0))); PUSHs(pubid ? sv_2mortal(newUTF8SVpv((char*) pubid, 0)) : &PL_sv_undef); PUSHs(sv_2mortal(newUTF8SVpv((char*) notation, 0))); PUTBACK; perl_call_sv(cbv->unprsd_sv, G_DISCARD); FREETMPS; LEAVE;} /* End unparsedEntityDecl */static voidnotationDecl(void *userData, const char *name, const char *base, const char *sysid, const char *pubid){ dSP; CallbackVector* cbv = (CallbackVector*) userData; PUSHMARK(sp); XPUSHs(cbv->self_sv); XPUSHs(sv_2mortal(newUTF8SVpv((char*) name, 0))); if (base) { XPUSHs(sv_2mortal(newUTF8SVpv((char *) base, 0))); } else if (sysid || pubid) { XPUSHs(&PL_sv_undef); } if (sysid) { XPUSHs(sv_2mortal(newUTF8SVpv((char *) sysid, 0))); } else if (pubid) { XPUSHs(&PL_sv_undef); } if (pubid) XPUSHs(sv_2mortal(newUTF8SVpv((char *) pubid, 0))); PUTBACK; perl_call_sv(cbv->notation_sv, G_DISCARD);} /* End notationDecl */static intexternalEntityRef(XML_Parser parser, const char* open, const char* base, const char* sysid, const char* pubid){ dSP;#if defined(USE_THREADS) && PATCHLEVEL==6 dTHX;#endif int count; int ret = 0; int parse_done = 0; CallbackVector* cbv = (CallbackVector*) XML_GetUserData(parser); if (! cbv->extent_sv) return 0; ENTER ; SAVETMPS ; PUSHMARK(sp); EXTEND(sp, pubid ? 4 : 3); PUSHs(cbv->self_sv); PUSHs(base ? sv_2mortal(newUTF8SVpv((char*) base, 0)) : &PL_sv_undef); PUSHs(sv_2mortal(newSVpv((char*) sysid, 0))); if (pubid) PUSHs(sv_2mortal(newUTF8SVpv((char*) pubid, 0))); PUTBACK ; count = perl_call_sv(cbv->extent_sv, G_SCALAR); SPAGAIN ; if (count >= 1) { SV * result = POPs; int type; if (result && (type = SvTYPE(result)) > 0) { SV **pval = hv_fetch((HV*) SvRV(cbv->self_sv), "Parser", 6, 0); if (! pval || ! SvIOK(*pval)) append_error(parser, "Can't find parser entry in XML::Parser object"); else { XML_Parser entpar; char *errmsg = (char *) 0; entpar = XML_ExternalEntityParserCreate(parser, open, 0); XML_SetBase(entpar, XML_GetBase(parser)); sv_setiv(*pval, (IV) entpar); cbv->p = entpar; PUSHMARK(sp); EXTEND(sp, 2); PUSHs(*pval); PUSHs(result); PUTBACK; count = perl_call_pv("XML::Parser::Expat::Do_External_Parse", G_SCALAR | G_EVAL); SPAGAIN; if (SvTRUE(ERRSV)) { char *hold; STRLEN len; POPs; hold = SvPV(ERRSV, len); New(326, errmsg, len + 1, char); if (len) Copy(hold, errmsg, len, char); goto Extparse_Cleanup; } if (count > 0) ret = POPi; parse_done = 1; Extparse_Cleanup: cbv->p = parser; sv_setiv(*pval, (IV) parser); XML_ParserFree(entpar); if (cbv->extfin_sv) { PUSHMARK(sp); PUSHs(cbv->self_sv); PUTBACK; perl_call_sv(cbv->extfin_sv, G_DISCARD); SPAGAIN; } if (SvTRUE(ERRSV)) append_error(parser, SvPV(ERRSV, PL_na)); } } } if (! ret && ! parse_done) append_error(parser, "Handler couldn't resolve external entity"); PUTBACK ; FREETMPS ; LEAVE ; return ret;} /* End externalEntityRef *//*================================================================** This is the function that expat calls to convert multi-byte sequences** for external encodings. Each byte in the sequence is used to index** into the current map to either set the next map or, in the case of** the final byte, to get the corresponding Unicode scalar, which is** returned.*/static intconvert_to_unicode(void *data, const char *seq) { Encinfo *enc = (Encinfo *) data; PrefixMap *curpfx; int count; int index = 0; for (count = 0; count < 4; count++) { unsigned char byte = (unsigned char) seq[count]; unsigned char bndx; unsigned char bmsk; int offset; curpfx = &enc->prefixes[index]; offset = ((int) byte) - curpfx->min; if (offset < 0) break; if (offset >= curpfx->len && curpfx->len != 0) break; bndx = byte >> 3; bmsk = 1 << (byte & 0x7); if (curpfx->ispfx[bndx] & bmsk) { index = enc->bytemap[curpfx->bmap_start + offset]; } else if (curpfx->ischar[bndx] & bmsk) { return enc->bytemap[curpfx->bmap_start + offset]; } else break; } return -1;} /* End convert_to_unicode */static intunknownEncoding(void *unused, const char *name, XML_Encoding *info){ SV ** encinfptr; Encinfo *enc; int namelen; int i; char buff[42]; namelen = strlen(name); if (namelen > 40) return 0; /* Make uppercase */ for (i = 0; i < namelen; i++) { char c = name[i]; if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; buff[i] = c; } if (! EncodingTable) { EncodingTable = perl_get_hv("XML::Parser::Expat::Encoding_Table", FALSE); if (! EncodingTable) croak("Can't find XML::Parser::Expat::Encoding_Table"); } encinfptr = hv_fetch(EncodingTable, buff, namelen, 0); if (! encinfptr || ! SvOK(*encinfptr)) { /* Not found, so try to autoload */ dSP; int count; ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSVpvn(buff,namelen))); PUTBACK; perl_call_pv("XML::Parser::Expat::load_encoding", G_DISCARD); encinfptr = hv_fetch(EncodingTable, buff, namelen, 0); FREETMPS; LEAVE; if (! encinfptr || ! SvOK(*encinfptr)) return 0; } if (! sv_derived_from(*encinfptr, "XML::Parser::Encinfo")) croak("Entry in XML::Parser::Expat::Encoding_Table not an Encinfo object"); enc = (Encinfo *) SvIV((SV*)SvRV(*encinfptr)); Copy(enc->firstmap, info->map, 256, int); info->release = NULL; if (enc->prefixes_size) { info->data = (void *) enc; info->convert = convert_to_unicode; } else { info->data = NULL; info->convert = NULL; } return 1;} /* End unknownEncoding */static voidrecString(void *userData, const char *string, int len){ CallbackVector *cbv = (CallbackVector*) userData; if (cbv->recstring) { sv_catpvn(cbv->recstring, (char *) string, len); } else { cbv->recstring = newUTF8SVpvn((char *) string, len); }} /* End recString */static voidsuspend_callbacks(CallbackVector *cbv) { if (SvTRUE(cbv->char_sv)) { XML_SetCharacterDataHandler(cbv->p, (XML_CharacterDataHandler) 0); } if (SvTRUE(cbv->proc_sv)) { XML_SetProcessingInstructionHandler(cbv->p, (XML_ProcessingInstructionHandler) 0); } if (SvTRUE(cbv->cmnt_sv)) { XML_SetCommentHandler(cbv->p, (XML_CommentHandler) 0); } if (SvTRUE(cbv->startcd_sv) || SvTRUE(cbv->endcd_sv)) { XML_SetCdataSectionHandler(cbv->p, (XML_StartCdataSectionHandler) 0, (XML_EndCdataSectionHandler) 0); } if (SvTRUE(cbv->unprsd_sv)) { XML_SetUnparsedEntityDeclHandler(cbv->p, (XML_UnparsedEntityDeclHandler) 0); } if (SvTRUE(cbv->notation_sv)) { XML_SetNotationDeclHandler(cbv->p, (XML_NotationDeclHandler) 0); } if (SvTRUE(cbv->extent_sv)) { XML_SetExternalEntityRefHandler(cbv->p, (XML_ExternalEntityRefHandler) 0); }} /* End suspend_callbacks */static voidresume_callbacks(CallbackVector *cbv) { if (SvTRUE(cbv->char_sv)) { XML_SetCharacterDataHandler(cbv->p, characterData); } if (SvTRUE(cbv->proc_sv)) { XML_SetProcessingInstructionHandler(cbv->p, processingInstruction); } if (SvTRUE(cbv->cmnt_sv)) { XML_SetCommentHandler(cbv->p, commenthandle); } if (SvTRUE(cbv->startcd_sv) || SvTRUE(cbv->endcd_sv)) { XML_SetCdataSectionHandler(cbv->p, startCdata, endCdata); } if (SvTRUE(cbv->unprsd_sv)) { XML_SetUnparsedEntityDeclHandler(cbv->p, unparsedEntityDecl); } if (SvTRUE(cbv->notation_sv)) { XML_SetNotationDeclHandler(cbv->p, notationDecl); } if (SvTRUE(cbv->extent_sv)) { XML_SetExternalEntityRefHandler(cbv->p, externalEntityRef); }} /* End resume_callbacks */MODULE = XML::Parser::Expat PACKAGE = XML::Parser::Expat PREFIX = XML_XML_ParserXML_ParserCreate(self_sv, enc_sv, namespaces) SV * self_sv SV * enc_sv int namespaces CODE: { CallbackVector *cbv; enum XML_ParamEntityParsing pep = XML_PARAM_ENTITY_PARSING_NEVER; char *enc = (char *) (SvTRUE(enc_sv) ? SvPV(enc_sv,PL_na) : 0); SV ** spp; Newz(320, cbv, 1, CallbackVector); cbv->self_sv = SvREFCNT_inc(self_sv); Newz(325, cbv->st_serial_stack, 1024, unsigned int); spp = hv_fetch((HV*)SvRV(cbv->self_sv), "NoExpand", 8, 0); if (spp && SvTRUE(*spp)) cbv->no_expand = 1; spp = hv_fetch((HV*)SvRV(cbv->self_sv), "Context", 7, 0); if (! spp || ! *spp || !SvROK(*spp)) croak("XML::Parser instance missing Context"); cbv->context = (AV*) SvRV(*spp); cbv->ns = (unsigned) namespaces; if (namespaces) { spp = hv_fetch((HV*)SvRV(cbv->self_sv), "New_Prefixes", 12, 0); if (! spp || ! *spp || !SvROK(*spp)) croak("XML::Parser instance missing New_Prefixes"); cbv->new_prefix_list = (AV *) SvRV(*spp); spp = hv_fetch((HV*)SvRV(cbv->self_sv), "Namespace_Table", 15, FALSE); if (! spp || ! *spp || !SvROK(*spp)) croak("XML::Parser instance missing Namespace_Table"); cbv->nstab = (HV *) SvRV(*spp); spp = hv_fetch((HV*)SvRV(cbv->self_sv), "Namespace_List", 14, FALSE); if (! spp || ! *spp || !SvROK(*spp)) croak("XML::Parser instance missing Namespace_List"); cbv->nslst = (AV *) SvRV(*spp); RETVAL = XML_ParserCreate_MM(enc, &ms, nsdelim); XML_SetNamespaceDeclHandler(RETVAL,nsStart, nsEnd); } else { RETVAL = XML_ParserCreate_MM(enc, &ms, NULL); } cbv->p = RETVAL; XML_SetUserData(RETVAL, (void *) cbv); XML_SetElementHandler(RETVAL, startElement, endElement); XML_SetUnknownEncodingHandler(RETVAL, unknownEncoding, 0); spp = hv_fetch((HV*)SvRV(cbv->self_sv), "ParseParamEnt", 13, FALSE); if (spp && SvTRUE(*spp)) { pep = XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE; cbv->parseparam = 1; } XML_SetParamEntityParsing(RETVAL, pep); } OUTPUT: RETVALvoidXML_ParserRelease(parser) XML_Parser parser CODE: { CallbackVector * cbv = (CallbackVector *) XML_GetUserData(parser); SvREFCNT_dec(cbv->self_sv); }voidXML_ParserFree(parser) XML_Parser parser CODE: { CallbackVector * cbv = (CallbackVector *) XML_GetUserData(parser); Safefree(cbv->st_serial_stack); /* Clean up any SVs that we have */ /* (Note that self_sv must already be taken care of or we couldn't be here */ if (cbv->recstring) SvREFCNT_dec(cbv->recstring); if (cbv->start_sv) SvREFCNT_dec(cbv->start_sv); if (cbv->end_sv) SvREFCNT_dec(cbv->end_sv); if (cbv->char_sv) SvREFCNT_dec(cbv->char_sv); if (cbv->proc_sv) SvREFCNT_dec(cbv->proc_sv); if (cbv->cmnt_sv) SvREFCNT_dec(cbv->cmnt_sv); if (cbv->dflt_sv) SvREFCNT_dec(cbv->dflt_sv); if (cbv->entdcl_sv) SvREFCNT_dec(cbv->entdcl_sv); if (cbv->eledcl_sv) SvREFCNT_dec(cbv->eledcl_sv); if (cbv->attdcl_sv) SvREFCNT_dec(cbv->attdcl_sv); if (cbv->doctyp_sv) SvREFCNT_dec(cbv->doctyp_sv); if (cbv->doctypfin_sv) SvREFCNT_dec(cbv->doctypfin_sv); if (cbv->xmldec_sv) SvREFCNT_dec(cbv->xmldec_sv); if (cbv->unprsd_sv) SvREFCNT_dec(cbv->unprsd_sv); if (cbv->notation_sv) SvREFCNT_dec(cbv->notation_sv); if (cbv->extent_sv) SvREFCNT_dec(cbv->extent_sv); if (cbv->extfin_sv) SvREFCNT_dec(cbv->extfin_sv); if (cbv->startcd_sv) SvREFCNT_dec(cbv->startcd_sv); if (cbv->endcd_sv) SvREFCNT_dec(cbv->endcd_sv); /* ================ */ Safefree(cbv); XML_ParserFree(parser); }intXML_ParseString(parser, sv) XML_Parser parser SV * sv CODE: { CallbackVector * cbv; STRLEN len; char *s = SvPV(sv, len); cbv = (CallbackVector *) XML_GetUserData(parser); RETVAL = XML_Parse(parser, s, len, 1); SPAGAIN; /* XML_Parse might have changed stack pointer */ if (! RETVAL) append_error(parser, NULL); } OUTPUT: RETVALintXML_ParseStream(parser, ioref, delim) XML_Parser parser SV * ioref SV * delim CODE: { SV **delimsv; CallbackVector * cbv; cbv = (CallbackVector *) XML_GetUserData(parser); if (SvOK(delim)) { cbv->delim = SvPV(delim, cbv->delimlen); } else { cbv->delim = (char *) 0; } RETVAL = parse_stream(parser, ioref); SPAGAIN; /* parse_stream might have changed stack pointer */ } OUTPUT: RETVAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -