Patch #1014930.  Expose current parse location to XMLParser.
diff --git a/Doc/lib/libpyexpat.tex b/Doc/lib/libpyexpat.tex
index 5b1c737..dd218c6 100644
--- a/Doc/lib/libpyexpat.tex
+++ b/Doc/lib/libpyexpat.tex
@@ -257,6 +257,26 @@
 Line number at which an error occurred.
 \end{memberdesc}
 
+The following attributes contain values relating to the current parse
+location in an \class{xmlparser} object.  During a callback reporting
+a parse event they indicate the location of the first of the sequence
+of characters that generated the event.  When called outside of a
+callback, the position indicated will be just past the last parse
+event (regardless of whether there was an associated callback).
+\versionadded{2.4}
+
+\begin{memberdesc}[xmlparser]{CurrentByteIndex} 
+Current byte index in the parser input.
+\end{memberdesc} 
+
+\begin{memberdesc}[xmlparser]{CurrentColumnNumber} 
+Current column number in the parser input.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{CurrentLineNumber}
+Current line number in the parser input.
+\end{memberdesc}
+
 Here is the list of handlers that can be set.  To set a handler on an
 \class{xmlparser} object \var{o}, use
 \code{\var{o}.\var{handlername} = \var{func}}.  \var{handlername} must
diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py
index 44f9ee8..a9a5e8f 100644
--- a/Lib/test/test_pyexpat.py
+++ b/Lib/test/test_pyexpat.py
@@ -326,3 +326,42 @@
         print "Expected RuntimeError for element 'a'; found %r" % e.args[0]
 else:
     print "Expected RuntimeError for 'a'"
+
+# Test Current* members:
+class PositionTest:
+
+    def __init__(self, expected_list, parser):
+        self.parser = parser
+        self.parser.StartElementHandler = self.StartElementHandler
+        self.parser.EndElementHandler = self.EndElementHandler
+        self.expected_list = expected_list
+        self.upto = 0
+
+    def StartElementHandler(self, name, attrs):
+        self.check_pos('s')
+
+    def EndElementHandler(self, name):
+        self.check_pos('e')
+
+    def check_pos(self, event):
+        pos = (event,
+               self.parser.CurrentByteIndex,
+               self.parser.CurrentLineNumber,
+               self.parser.CurrentColumnNumber)
+        require(self.upto < len(self.expected_list),
+                'too many parser events')
+        expected = self.expected_list[self.upto]
+        require(pos == expected,
+                'expected position %s, got %s' % (expected, pos))
+        self.upto += 1
+
+
+parser = expat.ParserCreate()
+handler = PositionTest([('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
+                        ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)],
+                       parser)
+parser.Parse('''<a>
+ <b>
+  <c/>
+ </b>
+</a>''', 1)
diff --git a/Misc/NEWS b/Misc/NEWS
index cb49e0b..fd5ba68 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -54,6 +54,9 @@
 
 - Added socket.socketpair().
 
+- Added CurrentByteIndex, CurrentColumnNumber, CurrentLineNumber
+  members to xml.parsers.expat.XMLParser object.
+
 Library
 -------
 
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 3bee0ac..d5929b6 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1455,6 +1455,17 @@
             return PyInt_FromLong((long)
                                   XML_GetErrorByteIndex(self->itself));
     }
+    if (name[0] == 'C') {
+        if (strcmp(name, "CurrentLineNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentLineNumber(self->itself));
+        if (strcmp(name, "CurrentColumnNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentColumnNumber(self->itself));
+        if (strcmp(name, "CurrentByteIndex") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetCurrentByteIndex(self->itself));
+    }
     if (name[0] == 'b') {
         if (strcmp(name, "buffer_size") == 0)
             return PyInt_FromLong((long) self->buffer_size);
@@ -1503,6 +1514,9 @@
         APPEND(rc, "ErrorLineNumber");
         APPEND(rc, "ErrorColumnNumber");
         APPEND(rc, "ErrorByteIndex");
+        APPEND(rc, "CurrentLineNumber");
+        APPEND(rc, "CurrentColumnNumber");
+        APPEND(rc, "CurrentByteIndex");
         APPEND(rc, "buffer_size");
         APPEND(rc, "buffer_text");
         APPEND(rc, "buffer_used");