diff --git a/include/libxml/parser.h b/include/libxml/parser.h index cedbe19f..bc8f5f69 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -101,7 +101,11 @@ typedef void (* xmlParserInputDeallocate)(xmlChar *str); struct _xmlParserInput { /* Input buffer */ xmlParserInputBuffer *buf; - /* The file analyzed, if any */ + /** + * @deprecated Use #xmlCtxtGetInputPosition + * + * The filename or URI, if any + */ const char *filename; /* unused */ const char *directory XML_DEPRECATED_MEMBER; @@ -113,11 +117,23 @@ struct _xmlParserInput { const xmlChar *end; /* unused */ int length XML_DEPRECATED_MEMBER; - /* Current line */ + /** + * @deprecated Use #xmlCtxtGetInputPosition + * + * Current line + */ int line; - /* Current column */ + /** + * @deprecated Use #xmlCtxtGetInputPosition + * + * Current column + */ int col; - /* How many xmlChars already consumed */ + /** + * @deprecated Use #xmlCtxtGetInputPosition + * + * How many xmlChars already consumed + */ unsigned long consumed; /* function to deallocate the base */ xmlParserInputDeallocate free XML_DEPRECATED_MEMBER; @@ -1926,6 +1942,13 @@ XMLPUBFUN int const xmlChar **name, const xmlChar **systemId, const xmlChar **publicId); +XMLPUBFUN int + xmlCtxtGetInputPosition (xmlParserCtxt *ctxt, + int inputIndex, + const char **filname, + int *line, + int *col, + unsigned long *bytePos); XMLPUBFUN void xmlCtxtSetErrorHandler (xmlParserCtxt *ctxt, xmlStructuredErrorFunc handler, diff --git a/parserInternals.c b/parserInternals.c index 51abd033..d8591143 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -3318,6 +3318,63 @@ xmlCtxtGetDocTypeDecl(xmlParserCtxt *ctxt, return 0; } +/** + * Return input position. + * + * Should only be used by error handlers or SAX callbacks. + * + * Because of entities, there can be multiple inputs. Non-negative + * values of `inputIndex` (0, 1, 2, ...) select inputs starting + * from the outermost input. Negative values (-1, -2, ...) select + * inputs starting from the innermost input. + * + * @since 2.15.0 + * + * @param ctxt parser context + * @param inputIndex input index + * @param filename filename (output) + * @param line line number (output) + * @param col column number (output) + * @param bytePos byte position (output) + * @returns 0 on success, -1 if arguments are invalid + */ +int +xmlCtxtGetInputPosition(xmlParserCtxt *ctxt, int inputIndex, + const char **filename, int *line, int *col, + unsigned long *bytePos) { + xmlParserInput *input; + + if (ctxt == NULL) + return -1; + + if (inputIndex < 0) { + inputIndex += ctxt->inputNr; + if (inputIndex < 0) + return -1; + } + if (inputIndex >= ctxt->inputNr) + return -1; + + input = ctxt->inputTab[inputIndex]; + + if (filename != NULL) + *filename = input->filename; + if (line != NULL) + *line = input->line; + if (col != NULL) + *col = input->col; + + if (bytePos != NULL) { + unsigned long consumed; + + consumed = input->consumed; + xmlSaturatedAddSizeT(&consumed, input->end - input->base); + *bytePos = consumed; + } + + return 0; +} + /************************************************************************ * * * Handling of node information *