use std::{
borrow::Cow,
ffi::c_void,
io::{Stderr, Stdout, Write, stderr},
ptr::{NonNull, null_mut},
sync::atomic::{AtomicBool, Ordering},
};
use crate::{
globals::{GLOBAL_STATE, GenericError, GenericErrorContext, StructuredError},
parser::XML_SAX2_MAGIC,
parser::{XmlParserCtxtPtr, XmlParserInput},
tree::{XmlElementType, XmlGenericNodePtr, XmlNodePtr},
};
macro_rules! impl_xml_parser_errors {
( $( $variant:ident $( = $default:literal )? ),* ) => {
#[doc(alias = "xmlParserError")]
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum XmlParserErrors {
$(
$variant $( = $default )?
),*
}
impl TryFrom<i32> for XmlParserErrors {
type Error = anyhow::Error;
fn try_from(value: i32) -> Result<Self, Self::Error> {
$(
if value == Self:: $variant as i32 {
return Ok(Self:: $variant);
}
)*
Err(anyhow::anyhow!("Invalid convert from value '{value}' to {}", std::any::type_name::<Self>()))
}
}
impl Default for XmlParserErrors {
fn default() -> Self {
Self::XmlErrOK
}
}
};
}
impl_xml_parser_errors!(
XmlErrOK = 0,
XmlErrInternalError,
XmlErrNoMemory,
XmlErrDocumentStart,
XmlErrDocumentEmpty,
XmlErrDocumentEnd,
XmlErrInvalidHexCharRef,
XmlErrInvalidDecCharRef,
XmlErrInvalidCharRef,
XmlErrInvalidChar,
XmlErrCharRefAtEOF,
XmlErrCharRefInProlog,
XmlErrCharRefInEpilog,
XmlErrCharRefInDTD,
XmlErrEntityRefAtEOF,
XmlErrEntityRefInProlog,
XmlErrEntityRefInEpilog,
XmlErrEntityRefInDTD,
XmlErrPERefAtEOF,
XmlErrPERefInProlog,
XmlErrPERefInEpilog,
XmlErrPERefInIntSubset,
XmlErrEntityRefNoName,
XmlErrEntityRefSemicolMissing,
XmlErrPERefNoName,
XmlErrPERefSemicolMissing,
XmlErrUndeclaredEntity,
XmlWarUndeclaredEntity,
XmlErrUnparsedEntity,
XmlErrEntityIsExternal,
XmlErrEntityIsParameter,
XmlErrUnknownEncoding,
XmlErrUnsupportedEncoding,
XmlErrStringNotStarted,
XmlErrStringNotClosed,
XmlErrNsDeclError,
XmlErrEntityNotStarted,
XmlErrEntityNotFinished,
XmlErrLtInAttribute,
XmlErrAttributeNotStarted,
XmlErrAttributeNotFinished,
XmlErrAttributeWithoutValue,
XmlErrAttributeRedefined,
XmlErrLiteralNotStarted,
XmlErrLiteralNotFinished,
XmlErrCommentNotFinished,
XmlErrPINotStarted,
XmlErrPINotFinished,
XmlErrNotationNotStarted,
XmlErrNotationNotFinished,
XmlErrAttlistNotStarted,
XmlErrAttlistNotFinished,
XmlErrMixedNotStarted,
XmlErrMixedNotFinished,
XmlErrElemcontentNotStarted,
XmlErrElemcontentNotFinished,
XmlErrXMLDeclNotStarted,
XmlErrXMLDeclNotFinished,
XmlErrCondsecNotStarted,
XmlErrCondsecNotFinished,
XmlErrExtSubsetNotFinished,
XmlErrDoctypeNotFinished,
XmlErrMisplacedCDATAEnd,
XmlErrCDATANotFinished,
XmlErrReservedXmlName,
XmlErrSpaceRequired,
XmlErrSeparatorRequired,
XmlErrNmtokenRequired,
XmlErrNameRequired,
XmlErrPCDATARequired,
XmlErrURIRequired,
XmlErrPubidRequired,
XmlErrLtRequired,
XmlErrGtRequired,
XmlErrLtSlashRequired,
XmlErrEqualRequired,
XmlErrTagNameMismatch,
XmlErrTagNotFinished,
XmlErrStandaloneValue,
XmlErrEncodingName,
XmlErrHyphenInComment,
XmlErrInvalidEncoding,
XmlErrExtEntityStandalone,
XmlErrCondsecInvalid,
XmlErrValueRequired,
XmlErrNotWellBalanced,
XmlErrExtraContent,
XmlErrEntityCharError,
XmlErrEntityPEInternal,
XmlErrEntityLoop,
XmlErrEntityBoundary,
XmlErrInvalidURI,
XmlErrURIFragment,
XmlWarCatalogPI,
XmlErrNoDTD,
XmlErrCondsecInvalidKeyword,
XmlErrVersionMissing,
XmlWarUnknownVersion,
XmlWarLangValue,
XmlWarNsURI,
XmlWarNsURIRelative,
XmlErrMissingEncoding,
XmlWarSpaceValue,
XmlErrNotStandalone,
XmlErrEntityProcessing,
XmlErrNotationProcessing,
XmlWarNsColumn,
XmlWarEntityRedefined,
XmlErrUnknownVersion,
XmlErrVersionMismatch,
XmlErrNameTooLong,
XmlErrUserStop,
XmlErrCommentAbruptlyEnded,
XmlNsErrXmlNamespace = 200,
XmlNsErrUndefinedNamespace,
XmlNsErrQname,
XmlNsErrAttributeRedefined,
XmlNsErrEmpty,
XmlNsErrColon,
XmlDTDAttributeDefault = 500,
XmlDTDAttributeRedefined,
XmlDTDAttributeValue,
XmlDTDContentError,
XmlDTDContentModel,
XmlDTDContentNotDeterminist,
XmlDTDDifferentPrefix,
XmlDTDElemDefaultNamespace,
XmlDTDElemNamespace,
XmlDTDElemRedefined,
XmlDTDEmptyNotation,
XmlDTDEntityType,
XmlDTDIDFixed,
XmlDTDIDRedefined,
XmlDTDIDSubset,
XmlDTDInvalidChild,
XmlDTDInvalidDefault,
XmlDTDLoadError,
XmlDTDMissingAttribute,
XmlDTDMixedCorrupt,
XmlDTDMultipleID,
XmlDTDNoDoc,
XmlDTDNoDTD,
XmlDTDNoElemName,
XmlDTDNoPrefix,
XmlDTDNoRoot,
XmlDTDNotationRedefined,
XmlDTDNotationValue,
XmlDTDNotEmpty,
XmlDTDNotPCDATA,
XmlDTDNotStandalone,
XmlDTDRootName,
XmlDTDStandaloneWhiteSpace,
XmlDTDUnknownAttribute,
XmlDTDUnknownElem,
XmlDTDUnknownEntity,
XmlDTDUnknownID,
XmlDTDUnknownNotation,
XmlDTDStandaloneDefaulted,
XmlDTDXmlidValue,
XmlDTDXmlidType,
XmlDTDDupToken,
XmlHTMLStrucureError = 800,
XmlHTMLUnknownTag,
XmlHTMLIncorrectlyOpenedComment,
XmlRngpAnynameAttrAncestor = 1000,
XmlRngpAttrConflict,
XmlRngpAttributeChildren,
XmlRngpAttributeContent,
XmlRngpAttributeEmpty,
XmlRngpAttributeNoop,
XmlRngpChoiceContent,
XmlRngpChoiceEmpty,
XmlRngpCreateFailure,
XmlRngpDataContent,
XmlRngpDefChoiceAndInterleave,
XmlRngpDefineCreateFailed,
XmlRngpDefineEmpty,
XmlRngpDefineMissing,
XmlRngpDefineNameMissing,
XmlRngpElemContentEmpty,
XmlRngpElemContentError,
XmlRngpElementEmpty,
XmlRngpElementContent,
XmlRngpElementName,
XmlRngpElementNoContent,
XmlRngpElemTextConflict,
XmlRngpEmpty,
XmlRngpEmptyConstruct,
XmlRngpEmptyContent,
XmlRngpEmptyNotEmpty,
XmlRngpErrorTypeLib,
XmlRngpExceptEmpty,
XmlRngpExceptMissing,
XmlRngpExceptMultiple,
XmlRngpExceptNoContent,
XmlRngpExternalRefEmtpy,
XmlRngpExternalRefFailure,
XmlRngpExternalRefRecurse,
XmlRngpForbiddenAttribute,
XmlRngpForeignElement,
XmlRngpGrammarContent,
XmlRngpGrammarEmpty,
XmlRngpGrammarMissing,
XmlRngpGrammarNoStart,
XmlRngpGroupAttrConflict,
XmlRngpHrefError,
XmlRngpIncludeEmpty,
XmlRngpIncludeFailure,
XmlRngpIncludeRecurse,
XmlRngpInterleaveAdd,
XmlRngpInterleaveCreateFailed,
XmlRngpInterleaveEmpty,
XmlRngpInterleaveNoContent,
XmlRngpInvalidDefineName,
XmlRngpInvalidURI,
XmlRngpInvalidValue,
XmlRngpMissingHref,
XmlRngpNameMissing,
XmlRngpNeedCombine,
XmlRngpNotAllowedNotEmpty,
XmlRngpNsNameAttrAncestor,
XmlRngpNsNameNoNs,
XmlRngpParamForbidden,
XmlRngpParamNameMissing,
XmlRngpParentRefCreateFailed,
XmlRngpParentRefNameInvalid,
XmlRngpParentRefNoName,
XmlRngpParentRefNoParent,
XmlRngpParentRefNotEmpty,
XmlRngpParseError,
XmlRngpPatAnynameExceptAnyname,
XmlRngpPatAttrAttr,
XmlRngpPatAttrElem,
XmlRngpPatDataExceptAttr,
XmlRngpPatDataExceptElem,
XmlRngpPatDataExceptEmpty,
XmlRngpPatDataExceptGroup,
XmlRngpPatDataExceptInterleave,
XmlRngpPatDataExceptList,
XmlRngpPatDataExceptOnemore,
XmlRngpPatDataExceptRef,
XmlRngpPatDataExceptText,
XmlRngpPatListAttr,
XmlRngpPatListElem,
XmlRngpPatListInterleave,
XmlRngpPatListList,
XmlRngpPatListRef,
XmlRngpPatListText,
XmlRngpPatNsNameExceptAnyName,
XmlRngpPatNsNameExceptNsName,
XmlRngpPatOnemoreGroupAttr,
XmlRngpPatOnemoreInterleaveAttr,
XmlRngpPatStartAttr,
XmlRngpPatStartData,
XmlRngpPatStartEmpty,
XmlRngpPatStartGroup,
XmlRngpPatStartInterleave,
XmlRngpPatStartList,
XmlRngpPatStartOnemore,
XmlRngpPatStartText,
XmlRngpPatStartValue,
XmlRngpPrefixUndefined,
XmlRngpRefCreateFailed,
XmlRngpRefCycle,
XmlRngpRefNameInvalid,
XmlRngpRefNoDef,
XmlRngpRefNoName,
XmlRngpRefNotEmpty,
XmlRngpStartChoiceAndInterleave,
XmlRngpStartContent,
XmlRngpStartEmpty,
XmlRngpStartMissing,
XmlRngpTextExpected,
XmlRngpTextHasChild,
XmlRngpTypeMissing,
XmlRngpTypeNotFound,
XmlRngpTypeValue,
XmlRngpUnknownAttribute,
XmlRngpUnknownCombine,
XmlRngpUnknownConstruct,
XmlRngpUnknownTypeLib,
XmlRngpURIFragment,
XmlRngpURINotAbsolute,
XmlRngpValueEmpty,
XmlRngpValueNoContent,
XmlRngpXmlNsName,
XmlRngpXmlNs,
XmlXPathExpressionOk = 1200,
XmlXPathNumberError,
XmlXPathUnfinishedLiteralError,
XmlXPathStartLiteralError,
XmlXPathVariableRefError,
XmlXPathUndefVariableError,
XmlXPathInvalidPredicateError,
XmlXPathExprError,
XmlXPathUnclosedError,
XmlXPathUnknownFuncError,
XmlXPathInvalidOperand,
XmlXPathInvalidType,
XmlXPathInvalidArity,
XmlXPathInvalidCtxtSize,
XmlXPathInvalidCtxtPosition,
XmlXPathMemoryError,
XmlXPtrSyntaxError,
XmlXPtrResourceError,
XmlXPtrSubResourceError,
XmlXPathUndefPrefixError,
XmlXPathEncodingError,
XmlXPathInvalidCharError,
XmlXPathInvalidCtxt,
XmlXPathStackError,
XmlXPathForbidVariableError,
XmlXPathOpLimitExceeded,
XmlXPathRecursionLimitExceeded,
XmlXPathUnknownError, XmlTreeInvalidHex = 1300,
XmlTreeInvalidDec,
XmlTreeUnterminatedEntity,
XmlTreeNotUTF8,
XmlSaveNotUTF8 = 1400,
XmlSaveCharInvalid,
XmlSaveNoDoctype,
XmlSaveUnknownEncoding,
XmlRegexpCompileError = 1450,
XmlIOUnknown = 1500,
XmlIOEACCES,
XmlIOEAGAIN,
XmlIOEBADF,
XmlIOEBADMSG,
XmlIOEBUSY,
XmlIOECANCELED,
XmlIOECHILD,
XmlIOEDEADLK,
XmlIOEDOM,
XmlIOEEXIST,
XmlIOEFAULT,
XmlIOEFBIG,
XmlIOEINPROGRESS,
XmlIOEINTR,
XmlIOEINVAL,
XmlIOEIO,
XmlIOEISDIR,
XmlIOEMFILE,
XmlIOEMLINK,
XmlIOEMSGSIZE,
XmlIOENAMETOOLONG,
XmlIOENFILE,
XmlIOENODEV,
XmlIOENOENT,
XmlIOENOEXEC,
XmlIOENOLCK,
XmlIOENOMEM,
XmlIOENOSPC,
XmlIOENOSYS,
XmlIOENOTDIR,
XmlIOENOTEMPTY,
XmlIOENOTSUP,
XmlIOENOTTY,
XmlIOENXIO,
XmlIOEPERM,
XmlIOEPIPE,
XmlIOERANGE,
XmlIOEROFS,
XmlIOESPIPE,
XmlIOESRCH,
XmlIOETIMEOUT,
XmlIOEXDEV,
XmlIONetworkAttempt,
XmlIOEncoder,
XmlIOFlush,
XmlIOWrite,
XmlIONoInput,
XmlIOBufferFull,
XmlIOLoadError,
XmlIOENOTSOCK,
XmlIOEISCONN,
XmlIOECONNREFUSED,
XmlIOENETUNREACH,
XmlIOEADDRINUSE,
XmlIOEALREADY,
XmlIOEAFNOSUPPORT,
XmlXIncludeRecursion = 1600,
XmlXIncludeParseValue,
XmlXIncludeEntityDefMismatch,
XmlXIncludeNoHref,
XmlXIncludeNoFallback,
XmlXIncludeHrefURI,
XmlXIncludeTextFragment,
XmlXIncludeTextDocument,
XmlXIncludeInvalidChar,
XmlXIncludeBuildFailed,
XmlXIncludeUnknownEncoding,
XmlXIncludeMultipleRoot,
XmlXIncludeXPtrFailed,
XmlXIncludeXPtrResult,
XmlXIncludeIncludeInInclude,
XmlXIncludeFallbacksInInclude,
XmlXIncludeFallbackNotInInclude,
XmlXIncludeDeprecatedNs,
XmlXIncludeFragmentID,
XmlCatalogMissingAttr = 1650,
XmlCatalogEntryBroken,
XmlCatalogPreferValue,
XmlCatalogNotCatalog,
XmlCatalogRecursion,
XmlSchemapPrefixUndefined = 1700,
XmlSchemapAttrFormDefaultValue,
XmlSchemapAttrGrpNonameNoRef,
XmlSchemapAttrNonameNoRef,
XmlSchemapComplextypeNonameNoRef,
XmlSchemapElemFormDefaultValue,
XmlSchemapElemNonameNoRef,
XmlSchemapExtensionNoBase,
XmlSchemapFacetNoValue,
XmlSchemapFailedBuildImport,
XmlSchemapGroupNonameNoRef,
XmlSchemapImportNamespaceNotURI,
XmlSchemapImportRedefineNsname,
XmlSchemapImportSchemaNotURI,
XmlSchemapInvalidBoolean,
XmlSchemapInvalidEnum,
XmlSchemapInvalidFacet,
XmlSchemapInvalidFacetValue,
XmlSchemapInvalidMaxoccurs,
XmlSchemapInvalidMinoccurs,
XmlSchemapInvalidRefAndSubtype,
XmlSchemapInvalidWhiteSpace,
XmlSchemapNoattrNoRef,
XmlSchemapNotationNoName,
XmlSchemapNotypeNoRef,
XmlSchemapRefAndSubtype,
XmlSchemapRestrictionNonameNoRef,
XmlSchemapSimpletypeNoname,
XmlSchemapTypeAndSubtype,
XmlSchemapUnknownAllChild,
XmlSchemapUnknownAnyattributeChild,
XmlSchemapUnknownAttrChild,
XmlSchemapUnknownAttrGrpChild,
XmlSchemapUnknownAttributeGroup,
XmlSchemapUnknownBaseType,
XmlSchemapUnknownChoiceChild,
XmlSchemapUnknownComplexcontentChild,
XmlSchemapUnknownComplextypeChild,
XmlSchemapUnknownElemChild,
XmlSchemapUnknownExtensionChild,
XmlSchemapUnknownFacetChild,
XmlSchemapUnknownFacetType,
XmlSchemapUnknownGroupChild,
XmlSchemapUnknownImportChild,
XmlSchemapUnknownListChild,
XmlSchemapUnknownNotationChild,
XmlSchemapUnknownProcesscontentChild,
XmlSchemapUnknownRef,
XmlSchemapUnknownRestrictionChild,
XmlSchemapUnknownSchemasChild,
XmlSchemapUnknownSequenceChild,
XmlSchemapUnknownSimplecontentChild,
XmlSchemapUnknownSimpletypeChild,
XmlSchemapUnknownType,
XmlSchemapUnknownUnionChild,
XmlSchemapElemDefaultFixed,
XmlSchemapRegexpInvalid,
XmlSchemapFailedLoad,
XmlSchemapNothingToParse,
XmlSchemapNoroot,
XmlSchemapRedefinedGroup,
XmlSchemapRedefinedType,
XmlSchemapRedefinedElement,
XmlSchemapRedefinedAttrgroup,
XmlSchemapRedefinedAttr,
XmlSchemapRedefinedNotation,
XmlSchemapFailedParse,
XmlSchemapUnknownPrefix,
XmlSchemapDefAndPrefix,
XmlSchemapUnknownIncludeChild,
XmlSchemapIncludeSchemaNotURI,
XmlSchemapIncludeSchemaNoURI,
XmlSchemapNotSchema,
XmlSchemapUnknownMemberType,
XmlSchemapInvalidAttrUse,
XmlSchemapRecursive,
XmlSchemapSupernumerousListItemType,
XmlSchemapInvalidAttrCombination,
XmlSchemapInvalidAttrInlineCombination,
XmlSchemapMissingSimpletypeChild,
XmlSchemapInvalidAttrName,
XmlSchemapRefAndContent,
XmlSchemapCtPropsCorrect1,
XmlSchemapCtPropsCorrect2,
XmlSchemapCtPropsCorrect3,
XmlSchemapCtPropsCorrect4,
XmlSchemapCtPropsCorrect5,
XmlSchemapDerivationOkRestriction1,
XmlSchemapDerivationOkRestriction2_1_1,
XmlSchemapDerivationOkRestriction2_1_2,
XmlSchemapDerivationOkRestriction2_2,
XmlSchemapDerivationOkRestriction3,
XmlSchemapWildcardInvalidNsMember,
XmlSchemapIntersectionNotExpressible,
XmlSchemapUnionNotExpressible,
XmlSchemapSrcImport3_1,
XmlSchemapSrcImport3_2,
XmlSchemapDerivationOkRestriction4_1,
XmlSchemapDerivationOkRestriction4_2,
XmlSchemapDerivationOkRestriction4_3,
XmlSchemapCosCtExtends1_3,
XmlSchemavNoRoot = 1801,
XmlSchemavUndeclaredElem,
XmlSchemavNotToplevel,
XmlSchemavMissing,
XmlSchemavWrongElem,
XmlSchemavNoType,
XmlSchemavNoRollback,
XmlSchemavIsAbstract,
XmlSchemavNotEmpty,
XmlSchemavElemCont,
XmlSchemavHaveDefault,
XmlSchemavNotNillable,
XmlSchemavExtraContent,
XmlSchemavInvalidAttr,
XmlSchemavInvalidElem,
XmlSchemavNotDeterminist,
XmlSchemavConstruct,
XmlSchemavInternal,
XmlSchemavNotSimple,
XmlSchemavAttrUnknown,
XmlSchemavAttrInvalid,
XmlSchemavValue,
XmlSchemavFacet,
XmlSchemavCvcDatatypeValid1_2_1,
XmlSchemavCvcDatatypeValid1_2_2,
XmlSchemavCvcDatatypeValid1_2_3,
XmlSchemavCvcType3_1_1,
XmlSchemavCvcType3_1_2,
XmlSchemavCvcFacetValid,
XmlSchemavCvcLengthValid,
XmlSchemavCvcMinLengthValid,
XmlSchemavCvcMaxLengthValid,
XmlSchemavCvcMinInclusiveValid,
XmlSchemavCvcMaxInclusiveValid,
XmlSchemavCvcMinExclusiveValid,
XmlSchemavCvcMaxExclusiveValid,
XmlSchemavCvcTotalDigitsValid,
XmlSchemavCvcFractionDigitsValid,
XmlSchemavCvcPatternValid,
XmlSchemavCvcEnumerationValid,
XmlSchemavCvcComplexType2_1,
XmlSchemavCvcComplexType2_2,
XmlSchemavCvcComplexType2_3,
XmlSchemavCvcComplexType2_4,
XmlSchemavCvcElt1,
XmlSchemavCvcElt2,
XmlSchemavCvcElt3_1,
XmlSchemavCvcElt3_2_1,
XmlSchemavCvcElt3_2_2,
XmlSchemavCvcElt4_1,
XmlSchemavCvcElt4_2,
XmlSchemavCvcElt4_3,
XmlSchemavCvcElt5_1_1,
XmlSchemavCvcElt5_1_2,
XmlSchemavCvcElt5_2_1,
XmlSchemavCvcElt5_2_2_1,
XmlSchemavCvcElt5_2_2_2_1,
XmlSchemavCvcElt5_2_2_2_2,
XmlSchemavCvcElt6,
XmlSchemavCvcElt7,
XmlSchemavCvcAttribute1,
XmlSchemavCvcAttribute2,
XmlSchemavCvcAttribute3,
XmlSchemavCvcAttribute4,
XmlSchemavCvcComplexType3_1,
XmlSchemavCvcComplexType3_2_1,
XmlSchemavCvcComplexType3_2_2,
XmlSchemavCvcComplexType4,
XmlSchemavCvcComplexType5_1,
XmlSchemavCvcComplexType5_2,
XmlSchemavElementContent,
XmlSchemavDocumentElementMissing,
XmlSchemavCvcComplexType1,
XmlSchemavCvcAu,
XmlSchemavCvcType1,
XmlSchemavCvcType2,
XmlSchemavCvcIdc,
XmlSchemavCvcWildcard,
XmlSchemavMisc,
XmlXPtrUnknownScheme = 1900,
XmlXPtrChildseqStart,
XmlXPtrEvalFailed,
XmlXPtrExtraObjects,
XmlC14NCreateCtxt = 1950,
XmlC14NRequiresUtf8,
XmlC14NCreateStack,
XmlC14NInvalidNode,
XmlC14NUnknowNode,
XmlC14NRelativeNamespace,
XmlFTPPasvAnswer = 2000,
XmlFTPEpsvAnswer,
XmlFTPAccnt,
XmlFTPUrlSyntax,
XmlHTTPUrlSyntax = 2020,
XmlHTTPUseIp,
XmlHTTPUnknownHost,
XmlSchemapSrcSimpleType1 = 3000,
XmlSchemapSrcSimpleType2,
XmlSchemapSrcSimpleType3,
XmlSchemapSrcSimpleType4,
XmlSchemapSrcResolve,
XmlSchemapSrcRestrictionBaseOrSimpletype,
XmlSchemapSrcListItemtypeOrSimpletype,
XmlSchemapSrcUnionMembertypesOrSimpletypes,
XmlSchemapStPropsCorrect1,
XmlSchemapStPropsCorrect2,
XmlSchemapStPropsCorrect3,
XmlSchemapCosStRestricts1_1,
XmlSchemapCosStRestricts1_2,
XmlSchemapCosStRestricts1_3_1,
XmlSchemapCosStRestricts1_3_2,
XmlSchemapCosStRestricts2_1,
XmlSchemapCosStRestricts2_3_1_1,
XmlSchemapCosStRestricts2_3_1_2,
XmlSchemapCosStRestricts2_3_2_1,
XmlSchemapCosStRestricts2_3_2_2,
XmlSchemapCosStRestricts2_3_2_3,
XmlSchemapCosStRestricts2_3_2_4,
XmlSchemapCosStRestricts2_3_2_5,
XmlSchemapCosStRestricts3_1,
XmlSchemapCosStRestricts3_3_1,
XmlSchemapCosStRestricts3_3_1_2,
XmlSchemapCosStRestricts3_3_2_2,
XmlSchemapCosStRestricts3_3_2_1,
XmlSchemapCosStRestricts3_3_2_3,
XmlSchemapCosStRestricts3_3_2_4,
XmlSchemapCosStRestricts3_3_2_5,
XmlSchemapCosStDerivedOk2_1,
XmlSchemapCosStDerivedOk2_2,
XmlSchemapS4sElemNotAllowed,
XmlSchemapS4sElemMissing,
XmlSchemapS4sAttrNotAllowed,
XmlSchemapS4sAttrMissing,
XmlSchemapS4sAttrInvalidValue,
XmlSchemapSrcElement1,
XmlSchemapSrcElement2_1,
XmlSchemapSrcElement2_2,
XmlSchemapSrcElement3,
XmlSchemapPPropsCorrect1,
XmlSchemapPPropsCorrect2_1,
XmlSchemapPPropsCorrect2_2,
XmlSchemapEPropsCorrect2,
XmlSchemapEPropsCorrect3,
XmlSchemapEPropsCorrect4,
XmlSchemapEPropsCorrect5,
XmlSchemapEPropsCorrect6,
XmlSchemapSrcInclude,
XmlSchemapSrcAttribute1,
XmlSchemapSrcAttribute2,
XmlSchemapSrcAttribute3_1,
XmlSchemapSrcAttribute3_2,
XmlSchemapSrcAttribute4,
XmlSchemapNoXmlns,
XmlSchemapNoXsi,
XmlSchemapCosValidDefault1,
XmlSchemapCosValidDefault2_1,
XmlSchemapCosValidDefault2_2_1,
XmlSchemapCosValidDefault2_2_2,
XmlSchemapCvcSimpleType,
XmlSchemapCosCtExtends1_1,
XmlSchemapSrcImport1_1,
XmlSchemapSrcImport1_2,
XmlSchemapSrcImport2,
XmlSchemapSrcImport2_1,
XmlSchemapSrcImport2_2,
XmlSchemapInternal,
XmlSchemapNotDeterministic,
XmlSchemapSrcAttributeGroup1,
XmlSchemapSrcAttributeGroup2,
XmlSchemapSrcAttributeGroup3,
XmlSchemapMgPropsCorrect1,
XmlSchemapMgPropsCorrect2,
XmlSchemapSrcCt1,
XmlSchemapDerivationOkRestriction2_1_3,
XmlSchemapAuPropsCorrect2,
XmlSchemapAPropsCorrect2,
XmlSchemapCPropsCorrect,
XmlSchemapSrcRedefine,
XmlSchemapSrcImport,
XmlSchemapWarnSkipSchema,
XmlSchemapWarnUnlocatedSchema,
XmlSchemapWarnAttrRedeclProh,
XmlSchemapWarnAttrPointlessProh,
XmlSchemapAgPropsCorrect,
XmlSchemapCosCtExtends1_2,
XmlSchemapAuPropsCorrect,
XmlSchemapAPropsCorrect3,
XmlSchemapCosAllLimited,
XmlSchematronvAssert = 4000,
XmlSchematronvReport,
XmlModuleOpen = 4900,
XmlModuleClose,
XmlCheckFoundElement = 5000,
XmlCheckFoundAttribute,
XmlCheckFoundText,
XmlCheckFoundCDATA,
XmlCheckFoundEntityRef,
XmlCheckFoundEntity,
XmlCheckFoundPI,
XmlCheckFoundComment,
XmlCheckFoundDoctype,
XmlCheckFoundFragment,
XmlCheckFoundNotation,
XmlCheckUnknownNode,
XmlCheckEntityType,
XmlCheckNoParent,
XmlCheckNoDoc,
XmlCheckNoName,
XmlCheckNoElem,
XmlCheckWrongDoc,
XmlCheckNoPrev,
XmlCheckWrongPrev,
XmlCheckNoNext,
XmlCheckWrongNext,
XmlCheckNotDTD,
XmlCheckNotAttr,
XmlCheckNotAttrDecl,
XmlCheckNotElemDecl,
XmlCheckNotEntityDecl,
XmlCheckNotNsDecl,
XmlCheckNoHref,
XmlCheckWrongParent,
XmlCheckNsScope,
XmlCheckNsAncestor,
XmlCheckNotUTF8,
XmlCheckNoDict,
XmlCheckNotNCName,
XmlCheckOutsideDict,
XmlCheckWrongName,
XmlCheckNameNotNull,
XmlI18NNoName = 6000,
XmlI18NNoHandler,
XmlI18NExcessHandler,
XmlI18NConvFailed,
XmlI18NNoOutput,
XmlBufOverflow = 7000
);
impl XmlParserErrors {
pub fn is_ok(&self) -> bool {
*self == Self::XmlErrOK
}
pub fn is_err(&self) -> bool {
!self.is_ok()
}
}
pub const XML_MAX_ERRORS: usize = 100;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum XmlErrorLevel {
#[default]
XmlErrNone = 0,
XmlErrWarning = 1,
XmlErrError = 2,
XmlErrFatal = 3,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum XmlErrorDomain {
#[default]
XmlFromNone = 0,
XmlFromParser,
XmlFromTree,
XmlFromNamespace,
XmlFromDTD,
XmlFromHTML,
XmlFromMemory,
XmlFromOutput,
XmlFromIO,
XmlFromFTP,
XmlFromHTTP,
XmlFromXInclude,
XmlFromXPath,
XmlFromXPointer,
XmlFromRegexp,
XmlFromDatatype,
XmlFromSchemasp,
XmlFromSchemasv,
XmlFromRelaxngp,
XmlFromRelaxngv,
XmlFromCatalog,
XmlFromC14N,
XmlFromXSLT,
XmlFromValid,
XmlFromCheck,
XmlFromWriter,
XmlFromModule,
XmlFromI18N,
XmlFromSchematronv,
XmlFromBuffer,
XmlFromURI,
}
#[derive(Clone, Default)]
pub struct XmlError {
pub(crate) domain: XmlErrorDomain,
pub(crate) code: XmlParserErrors,
pub(crate) message: Option<Cow<'static, str>>,
pub(crate) level: XmlErrorLevel,
pub(crate) file: Option<Cow<'static, str>>, pub(crate) line: usize,
pub(crate) str1: Option<Cow<'static, str>>,
pub(crate) str2: Option<Cow<'static, str>>,
pub(crate) str3: Option<Cow<'static, str>>,
pub(crate) int1: i32,
pub(crate) int2: i32,
pub(crate) ctxt: Option<NonNull<c_void>>,
pub(crate) node: Option<XmlGenericNodePtr>,
}
impl XmlError {
pub fn reset(&mut self) {
if !self.code.is_ok() {
*self = Self::default();
}
}
pub fn is_ok(&self) -> bool {
self.code.is_ok()
}
pub fn is_err(&self) -> bool {
!self.is_ok()
}
pub fn code(&self) -> XmlParserErrors {
self.code
}
pub fn message(&self) -> Option<&str> {
self.message.as_ref().map(|s| s.as_ref())
}
pub fn file(&self) -> Option<&str> {
self.file.as_ref().map(|s| s.as_ref())
}
pub fn line(&self) -> usize {
self.line
}
pub fn domain(&self) -> XmlErrorDomain {
self.domain
}
pub fn level(&self) -> XmlErrorLevel {
self.level
}
pub fn node(&self) -> Option<XmlGenericNodePtr> {
self.node
}
pub fn context(&self) -> Option<NonNull<c_void>> {
self.ctxt
}
pub fn str1(&self) -> Option<&str> {
self.str1.as_ref().map(|s| s.as_ref())
}
pub fn int1(&self) -> i32 {
self.int1
}
}
pub fn generic_error_default(_context: Option<GenericErrorContext>, msg: &str) {
let out = GLOBAL_STATE.with_borrow_mut(|state| {
state
.generic_error_context
.get_or_insert_with(|| GenericErrorContext::new(stderr()))
.clone()
});
let mut lock = out.context.lock().unwrap();
if lock.downcast_mut::<Stdout>().is_some() {
print!("{msg}");
} else if lock.downcast_mut::<Stderr>().is_some() {
eprint!("{msg}");
} else {
let context = lock
.downcast_mut::<Box<dyn Write>>()
.expect("GenericErrorContext is not writable.");
write!(context, "{msg}").ok();
}
}
#[macro_export]
macro_rules! generic_error {
( $fmt:literal, $( $args:expr ),* ) => {{
let msg = format!($fmt, $( $args ),*);
let func = $crate::globals::GLOBAL_STATE.with_borrow_mut(|state| state.generic_error);
func(None, msg.as_str());
}};
( $fmt:literal ) => {{
$crate::generic_error!($fmt, );
}}
}
#[doc(hidden)]
pub fn parser_print_file_context_internal(
input: Option<&XmlParserInput>,
channel: GenericError,
data: Option<GenericErrorContext>,
) {
const SIZE: usize = 80;
let Some(input) = input else {
return;
};
let mut cur = input.cur;
while 0 < cur
&& cur < input.base_contents().len()
&& matches!(input.base_contents()[cur], b'\n' | b'\r')
{
cur -= 1;
}
let mut n = 0;
if cur == input.base_contents().len() {
cur -= 1;
n += 1;
}
while n < SIZE && cur > 0 && !matches!(input.base_contents()[cur], b'\n' | b'\r') {
cur -= 1;
n += 1;
}
let mut cur = &input.base_contents()[cur..];
if n > 0 && matches!(cur.first(), Some(&(b'\n' | b'\r'))) {
cur = &cur[1..];
} else {
while cur.len() > input.base_contents().len() - input.cur && cur[0] & 0xC0 == 0x80 {
cur = &cur[1..];
}
}
let col = input.cur - (input.base_contents().len() - cur.len());
let mut content = String::with_capacity(SIZE);
let mut n = 0;
let chunk = {
let mut i = 0;
while i < SIZE.min(cur.len()) && cur[i] != b'\n' && cur[i] != b'\r' {
i += 1;
}
&cur[..i]
};
if let Some(chunk) = chunk.utf8_chunks().next() {
for c in chunk
.valid()
.chars()
.take_while(|&c| c != '\n' && c != '\r')
{
n += c.len_utf8();
if n > SIZE {
break;
}
content.push(c);
}
}
channel(data.clone(), format!("{content}\n").as_str());
let mut ptr = content
.bytes()
.take(col)
.map(|c| if c == b'\t' { '\t' } else { ' ' })
.collect::<String>();
if ptr.len() == SIZE {
ptr.pop();
}
ptr.push_str("^\n");
channel(data.clone(), ptr.as_str());
}
pub fn parser_print_file_context(input: Option<&XmlParserInput>) {
let (channel, data) = GLOBAL_STATE
.with_borrow(|state| (state.generic_error, state.generic_error_context.clone()));
parser_print_file_context_internal(input, channel, data);
}
pub fn parser_print_file_info(input: Option<&XmlParserInput>) {
if let Some(input) = input {
if input.filename.is_some() {
generic_error!("{}:{}: ", input.filename.as_deref().unwrap(), input.line);
} else {
generic_error!("Entity: line {}: ", input.line);
}
}
}
pub unsafe fn report_error(
err: &XmlError,
ctxt: XmlParserCtxtPtr,
msg: Option<&str>,
channel: Option<GenericError>,
data: Option<GenericErrorContext>,
) {
unsafe {
let channel = GLOBAL_STATE.with_borrow_mut(|state| {
if let Some(channel) = channel {
channel
} else {
state.generic_error
}
});
let file = err.file.as_ref();
let line = err.line;
let code = err.code;
let domain = err.domain;
let level = err.level;
let node = err.node;
if code.is_ok() {
return;
}
let name = node
.filter(|node| node.element_type() == XmlElementType::XmlElementNode)
.map(|node| XmlNodePtr::try_from(node).unwrap())
.map(|node| node.name.clone());
let mut input = None;
let mut cur = None;
if !ctxt.is_null() {
input = (*ctxt).input();
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
cur = input;
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() - 2]);
}
}
if let Some(input) = input {
if input.filename.is_some() {
channel(
data.clone(),
format!("{}:{}: ", input.filename.as_deref().unwrap(), input.line).as_str(),
);
} else if line != 0 && domain == XmlErrorDomain::XmlFromParser {
channel(
data.clone(),
format!("Entity: line {}: ", input.line).as_str(),
);
}
}
} else if let Some(file) = file {
channel(data.clone(), format!("{file}:{line}: ").as_str());
} else if line != 0
&& (domain == XmlErrorDomain::XmlFromParser
|| domain == XmlErrorDomain::XmlFromSchemasv
|| domain == XmlErrorDomain::XmlFromSchemasp
|| domain == XmlErrorDomain::XmlFromDTD
|| domain == XmlErrorDomain::XmlFromRelaxngp
|| domain == XmlErrorDomain::XmlFromRelaxngv)
{
channel(data.clone(), format!("Entity: line {line}: ").as_str());
}
if let Some(name) = name {
channel(data.clone(), format!("element {}: ", name).as_str());
}
match domain {
XmlErrorDomain::XmlFromParser => channel(data.clone(), "parser "),
XmlErrorDomain::XmlFromNamespace => channel(data.clone(), "namespace "),
XmlErrorDomain::XmlFromDTD | XmlErrorDomain::XmlFromValid => {
channel(data.clone(), "validity ")
}
XmlErrorDomain::XmlFromHTML => channel(data.clone(), "HTML parser "),
XmlErrorDomain::XmlFromMemory => channel(data.clone(), "memory "),
XmlErrorDomain::XmlFromOutput => channel(data.clone(), "output "),
XmlErrorDomain::XmlFromIO => channel(data.clone(), "I/O "),
XmlErrorDomain::XmlFromXInclude => channel(data.clone(), "XInclude "),
XmlErrorDomain::XmlFromXPath => channel(data.clone(), "XPath "),
XmlErrorDomain::XmlFromXPointer => channel(data.clone(), "parser "),
XmlErrorDomain::XmlFromRegexp => channel(data.clone(), "regexp "),
XmlErrorDomain::XmlFromModule => channel(data.clone(), "module "),
XmlErrorDomain::XmlFromSchemasv => channel(data.clone(), "Schemas validity "),
XmlErrorDomain::XmlFromSchemasp => channel(data.clone(), "Schemas parser "),
XmlErrorDomain::XmlFromRelaxngp => channel(data.clone(), "Relax-NG parser "),
XmlErrorDomain::XmlFromRelaxngv => channel(data.clone(), "Relax-NG validity "),
XmlErrorDomain::XmlFromCatalog => channel(data.clone(), "Catalog "),
XmlErrorDomain::XmlFromC14N => channel(data.clone(), "C14N "),
XmlErrorDomain::XmlFromXSLT => channel(data.clone(), "XSLT "),
XmlErrorDomain::XmlFromI18N => channel(data.clone(), "encoding "),
XmlErrorDomain::XmlFromSchematronv => channel(data.clone(), "schematron "),
XmlErrorDomain::XmlFromBuffer => channel(data.clone(), "internal buffer "),
XmlErrorDomain::XmlFromURI => channel(data.clone(), "URI "),
_ => {}
};
match level {
XmlErrorLevel::XmlErrNone => channel(data.clone(), ": "),
XmlErrorLevel::XmlErrWarning => channel(data.clone(), "warning : "),
XmlErrorLevel::XmlErrError => channel(data.clone(), "error : "),
XmlErrorLevel::XmlErrFatal => channel(data.clone(), "error : "),
};
if let Some(msg) = msg {
if !msg.is_empty() && !msg.ends_with('\n') {
channel(data.clone(), format!("{msg}\n").as_str());
} else {
channel(data.clone(), msg);
}
} else {
channel(data.clone(), "out of memory error\n");
}
if !ctxt.is_null() {
parser_print_file_context_internal(input, channel, data.clone());
if let Some(cur) = cur {
if cur.filename.is_some() {
channel(
data.clone(),
format!("{}:{}: \n", cur.filename.as_deref().unwrap(), cur.line).as_str(),
)
} else if line != 0 && domain == XmlErrorDomain::XmlFromParser {
channel(
data.clone(),
format!("Entity: line {}: \n", cur.line).as_str(),
);
}
parser_print_file_context_internal(Some(cur), channel, data.clone());
}
}
if let Some(str1) = err.str1.as_ref() {
if domain == XmlErrorDomain::XmlFromXPath
&& err.int1 < 100
&& err.int1 < str1.len() as i32
{
channel(data.clone(), format!("{str1}\n").as_str());
let mut buf = " ".repeat(err.int1 as usize);
buf.push_str("^\n");
channel(data.clone(), buf.as_str());
}
}
}
}
pub(crate) fn parser_error(ctx: Option<GenericErrorContext>, msg: &str) {
if let Some(ctxt) = ctx {
unsafe {
let lock = ctxt.context.lock().unwrap();
let ctxt = **lock
.downcast_ref::<Box<XmlParserCtxtPtr>>()
.expect("ctxt is not XmlParserCtxtPtr");
let mut input = (*ctxt).input();
let mut cur = None;
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
cur = input;
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() - 2]);
}
}
parser_print_file_info(input);
generic_error!("error: {msg}");
parser_print_file_context(input);
if let Some(cur) = cur {
parser_print_file_info(Some(cur));
generic_error!("\n");
parser_print_file_context(Some(cur));
}
}
} else {
generic_error!("error: {msg}");
}
}
pub(crate) fn parser_warning(ctx: Option<GenericErrorContext>, msg: &str) {
if let Some(ctx) = ctx {
let lock = ctx.context.lock().unwrap();
let ctxt = **lock
.downcast_ref::<Box<XmlParserCtxtPtr>>()
.expect("ctxt is not XmlParserCtxtPtr");
unsafe {
let mut input = (*ctxt).input();
let mut cur = None;
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
cur = input;
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() - 2]);
}
}
parser_print_file_info(input);
generic_error!("warning: {msg}");
parser_print_file_context(input);
if let Some(cur) = cur {
parser_print_file_info(Some(cur));
generic_error!("\n");
parser_print_file_context(Some(cur));
}
}
} else {
generic_error!("warning: {msg}");
}
}
pub(crate) fn parser_validity_error(ctx: Option<GenericErrorContext>, msg: &str) {
let len = msg.len();
static HAD_INFO: AtomicBool = AtomicBool::new(false);
unsafe {
if let Some(ctx) = ctx {
let lock = ctx.context.lock().unwrap();
let ctxt = **lock
.downcast_ref::<Box<XmlParserCtxtPtr>>()
.expect("ctxt is not XmlParserCtxtPtr");
let mut input = None;
if len > 1 && msg.as_bytes()[len - 2] != b':' {
input = (*ctxt).input();
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() - 2]);
}
}
if !HAD_INFO.load(Ordering::Acquire) {
parser_print_file_info(input);
}
generic_error!("validity error: ");
HAD_INFO.store(false, Ordering::Release)
} else {
HAD_INFO.store(true, Ordering::Release);
}
generic_error!("{msg}");
parser_print_file_context(input);
} else {
if len > 1 && msg.as_bytes()[len - 2] != b':' {
generic_error!("validity error: ");
HAD_INFO.store(false, Ordering::Release)
} else {
HAD_INFO.store(true, Ordering::Release);
}
generic_error!("{msg}");
}
}
}
pub(crate) fn parser_validity_warning(ctx: Option<GenericErrorContext>, msg: &str) {
let len = msg.len();
if let Some(ctx) = ctx {
let lock = ctx.context.lock().unwrap();
let ctxt = **lock
.downcast_ref::<Box<XmlParserCtxtPtr>>()
.expect("ctxt is not XmlParserCtxtPtr");
let mut input = None;
unsafe {
if len != 0 && msg.as_bytes()[len - 1] != b':' {
input = (*ctxt).input();
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() - 2]);
}
}
parser_print_file_info(input);
}
}
generic_error!("validity warning: {msg}");
parser_print_file_context(input);
} else {
generic_error!("validity warning: {msg}");
}
}
#[doc(alias = "__xmlRaiseError")]
macro_rules! __xml_raise_error {
($schannel:expr, $channel:expr, $data:expr, $ctx:expr, $nod:expr, $domain:expr, $code:expr, $level:expr, $file:expr, $line:expr, $str1:expr, $str2:expr, $str3:expr, $int1:expr, $col:expr, $msg:literal, $( $args:expr ),*) => {
$crate::error::xml_raise_error(
$schannel,
$channel,
$data,
$ctx,
$nod,
$domain,
$code,
$level,
$file,
$line,
$str1,
$str2,
$str3,
$int1,
$col,
Some(format!($msg, $( $args ),*).as_str()),
);
};
($schannel:expr, $channel:expr, $data:expr, $ctx:expr, $nod:expr, $domain:expr, $code:expr, $level:expr, $file:expr, $line:expr, $str1:expr, $str2:expr, $str3:expr, $int1:expr, $col:expr, $msg:expr,) => {{
$crate::error::xml_raise_error(
$schannel,
$channel,
$data,
$ctx,
$nod,
$domain,
$code,
$level,
$file,
$line,
$str1,
$str2,
$str3,
$int1,
$col,
$msg
);
}};
}
pub(crate) use __xml_raise_error;
#[allow(clippy::too_many_arguments)]
pub(crate) fn xml_raise_error(
mut schannel: Option<StructuredError>,
mut channel: Option<GenericError>,
mut data: Option<GenericErrorContext>,
ctx: *mut c_void,
nod: Option<XmlGenericNodePtr>,
domain: XmlErrorDomain,
code: XmlParserErrors,
level: XmlErrorLevel,
mut file: Option<Cow<'static, str>>,
mut line: i32,
str1: Option<Cow<'static, str>>,
str2: Option<Cow<'static, str>>,
str3: Option<Cow<'static, str>>,
int1: i32,
mut col: i32,
msg: Option<&str>,
) {
let msg = msg.unwrap_or("No error message provided");
let mut ctxt: XmlParserCtxtPtr = null_mut();
let Some((channel, error, s, data)) = GLOBAL_STATE.with_borrow_mut(|state| {
let mut node = nod;
let mut to = &mut state.last_error;
let mut baseptr = None;
if code == XmlParserErrors::XmlErrOK {
return None;
}
if state.get_warnings_default_value == 0 && matches!(level, XmlErrorLevel::XmlErrWarning) {
return None;
}
if domain == XmlErrorDomain::XmlFromParser
|| domain == XmlErrorDomain::XmlFromHTML
|| domain == XmlErrorDomain::XmlFromDTD
|| domain == XmlErrorDomain::XmlFromNamespace
|| domain == XmlErrorDomain::XmlFromIO
|| domain == XmlErrorDomain::XmlFromValid
{
ctxt = ctx as XmlParserCtxtPtr;
if !ctxt.is_null() {
unsafe {
if matches!(level, XmlErrorLevel::XmlErrWarning) {
if (*ctxt).nb_warnings >= XML_MAX_ERRORS as u16 {
return None;
}
(*ctxt).nb_warnings += 1;
} else {
if (*ctxt).nb_errors >= XML_MAX_ERRORS as u16 {
return None;
}
(*ctxt).nb_errors += 1;
}
if schannel.is_none() {
if let Some(serror) = (*ctxt)
.sax
.as_deref_mut()
.filter(|sax| sax.initialized == XML_SAX2_MAGIC as u32)
.and_then(|sax| sax.serror)
{
schannel = Some(serror);
data = (*ctxt).user_data.clone();
}
}
}
}
}
if schannel.is_none() {
schannel = state.structured_error;
if schannel.is_some() {
data = state.structured_error_context.clone();
}
}
if !ctxt.is_null() {
unsafe {
if file.is_none() {
let mut input = (*ctxt).input();
if let Some(now) = input {
if now.filename.is_none() && (*ctxt).input_tab.len() > 1 {
input = Some(&(*ctxt).input_tab[(*ctxt).input_tab.len() as usize - 2]);
}
}
if let Some(input) = input {
file = input.filename.as_deref().map(|f| f.to_owned().into());
line = input.line;
col = input.col;
}
}
to = &mut (*ctxt).last_error;
}
} else if let Some(now) = node.filter(|_| file.is_none()) {
if now.document().is_some_and(|doc| doc.url.is_some()) {
baseptr = Some(now);
}
for _ in 0..10 {
let Some(now) =
node.filter(|node| node.element_type() != XmlElementType::XmlElementNode)
else {
break;
};
node = now.parent();
}
if baseptr.is_none()
&& node.is_some_and(|node| node.document().is_some_and(|doc| doc.url.is_some()))
{
baseptr = node;
}
if let Some(node) = node
.filter(|node| matches!(node.element_type(), XmlElementType::XmlElementNode))
.map(|node| XmlNodePtr::try_from(node).unwrap())
{
line = node.line as _;
}
if line == 0 || line == 65535 {
line = node.map_or(-1, |node| node.get_line_no() as i32);
}
}
to.reset();
to.domain = domain;
to.code = code;
to.message = Some(msg.to_owned().into());
to.level = level;
if let Some(file) = file {
to.file = Some(file);
} else if let Some(baseptr) = baseptr {
#[cfg(feature = "xinclude")]
{
let mut prev = Some(baseptr);
let mut href = None;
let mut inclcount = 0;
while let Some(cur_node) = prev {
if let Some(p) = cur_node.prev() {
prev = Some(p);
if matches!(p.element_type(), XmlElementType::XmlXIncludeStart) {
if inclcount > 0 {
inclcount -= 1;
} else {
href = p.get_prop("href");
if href.is_some() {
break;
}
}
} else if matches!(p.element_type(), XmlElementType::XmlXIncludeEnd) {
inclcount += 1;
}
} else {
prev = cur_node.parent();
}
}
if href.is_some() {
to.file = href.map(|h| h.into());
} else {
to.file = baseptr
.document()
.as_deref()
.and_then(|doc| doc.url.as_deref().map(|u| Cow::Owned(u.to_owned())));
}
}
#[cfg(not(feature = "xinclude"))]
{
if let Some(doc) = baseptr.document() {
to.file = doc.url.as_deref().map(|u| Cow::Owned(u.to_owned()));
}
}
if to.file.is_none() {
if let Some(node) = node {
if let Some(doc) = node.document() {
to.file = doc.url.as_deref().map(|u| Cow::Owned(u.to_owned()));
}
}
}
}
to.line = line as usize;
to.str1 = str1;
to.str2 = str2;
to.str3 = str3;
to.int1 = int1;
to.int2 = col;
to.node = node;
to.ctxt = NonNull::new(ctx);
let error = to.clone();
state.last_error = to.clone();
if let Some(schannel) = schannel {
schannel(data, &state.last_error);
return None;
}
unsafe {
if !ctxt.is_null()
&& channel.is_none()
&& state.structured_error.is_none()
&& (*ctxt).sax.is_some()
{
let sax = (*ctxt).sax.as_deref_mut().unwrap();
if matches!(level, XmlErrorLevel::XmlErrWarning) {
channel = sax.warning as _;
} else {
channel = sax.error as _;
}
channel.map(|c| {
(
c,
error,
Cow::<'static, str>::Owned(msg.to_owned()),
(*ctxt).user_data.clone(),
)
})
} else if channel.is_none() {
channel = Some(state.generic_error);
if !ctxt.is_null() {
let context = GenericErrorContext::new(Box::new(ctxt));
channel.map(|c| {
(
c,
error,
Cow::<'static, str>::Owned(msg.to_owned()),
Some(context),
)
})
} else {
channel.map(|c| {
(
c,
error,
Cow::<'static, str>::Owned(msg.to_owned()),
state.generic_error_context.clone(),
)
})
}
} else {
channel.map(|c| (c, error, Cow::<'static, str>::Owned(msg.to_owned()), None))
}
}
}) else {
return;
};
unsafe {
if channel as usize == parser_error as usize
|| channel as usize == parser_warning as usize
|| channel as usize == parser_validity_error as usize
|| channel as usize == parser_validity_warning as usize
{
report_error(&error, ctxt, Some(s.as_ref()), None, None);
} else if channel as usize == generic_error_default as usize {
report_error(&error, ctxt, Some(s.as_ref()), Some(channel), data);
} else {
channel(data, s.as_ref());
}
}
}
#[doc(alias = "__xmlSimpleError")]
#[doc(hidden)]
pub(crate) fn __xml_simple_oom_error(
domain: XmlErrorDomain,
node: Option<XmlGenericNodePtr>,
msg: Option<&str>,
) {
if let Some(msg) = msg {
__xml_raise_error!(
None,
None,
None,
null_mut(),
node,
domain,
XmlParserErrors::XmlErrNoMemory,
XmlErrorLevel::XmlErrFatal,
None,
0,
Some(msg.to_owned().into()),
None,
None,
0,
0,
Some(format!("Memory allocation failed : {msg}\n").as_str()),
);
} else {
__xml_raise_error!(
None,
None,
None,
null_mut(),
node,
domain,
XmlParserErrors::XmlErrNoMemory,
XmlErrorLevel::XmlErrFatal,
None,
0,
None,
None,
None,
0,
0,
"Memory allocation failed\n",
);
}
}
#[doc(alias = "__xmlSimpleError")]
macro_rules! __xml_simple_error {
(
$domain:expr,
$code:expr,
$node:expr,
None,
$extra:expr
) => {
assert_ne!(
$code,
XmlParserErrors::XmlErrNoMemory,
"Use __xml_simple_oom_error"
);
$crate::error::__xml_raise_error!(
None,
None,
None,
std::ptr::null_mut(),
$node as _,
$domain,
$code,
$crate::error::XmlErrorLevel::XmlErrError,
None,
0,
Some($extra.to_owned().into()),
None,
None,
0,
0,
None,
);
};
(
$domain:expr,
$code:expr,
$node:expr,
$msg:expr
) => {
assert_ne!(
$code,
XmlParserErrors::XmlErrNoMemory,
"Use __xml_simple_oom_error"
);
$crate::error::__xml_raise_error!(
None,
None,
None,
std::ptr::null_mut(),
$node as _,
$domain,
$code,
$crate::error::XmlErrorLevel::XmlErrError,
None,
0,
None,
None,
None,
0,
0,
Some($msg),
);
};
(
$domain:expr,
$code:expr,
$node:expr,
$msg:literal,
$extra:expr
) => {
assert_ne!(
$code,
XmlParserErrors::XmlErrNoMemory,
"Use __xml_simple_oom_error"
);
$crate::__xml_raise_error!(
None,
None,
None,
null_mut(),
$node as _,
$domain,
$code,
XmlErrorLevel::XmlErrError,
None,
0,
Some($extra.to_owned().into()),
None,
None,
0,
0,
Some(format!($msg, $extra).as_str()),
);
};
}
pub(crate) use __xml_simple_error;