# master pattern object. keeps track of global attributes
def __init__(self):
self.flags = 0
+ self.open = []
self.groups = 1
self.groupdict = {}
- def getgroup(self, name=None):
+ def opengroup(self, name=None):
gid = self.groups
self.groups = gid + 1
if name:
self.groupdict[name] = gid
+ self.open.append(gid)
return gid
+ def closegroup(self, gid):
+ self.open.remove(gid)
+ def checkgroup(self, gid):
+ return gid < self.groups and gid not in self.open
class SubPattern:
# a subpattern, in intermediate form
# got at least one decimal digit; this is a group reference
group = _group(escape, state.groups)
if group:
+ if not state.checkgroup(group):
+ raise error, "cannot refer to open group"
return GROUPREF, group
raise ValueError
if len(escape) == 2:
# anonymous group
group = None
else:
- group = state.getgroup(name)
+ group = state.opengroup(name)
p = _parse_sub(source, state)
if not source.match(")"):
raise error, "unbalanced parenthesis"
+ if group is not None:
+ state.closegroup(group)
subpattern.append((SUBPATTERN, (group, p)))
else:
while 1:
[(":", ""), (":", ":"), (":", "::")])
test(r"""sre.findall(r"(a)|(b)", "abc")""", [("a", ""), ("", "b")])
+# bug 117612
+test(r"""sre.findall(r"(a|(b))", "aba")""", [("a", ""),("b", "b"),("a", "")])
+
if verbose:
print "Running tests on sre.match"
*
* partial history:
* 1999-10-24 fl created (based on existing template matcher code)
- * 2000-03-06 fl first alpha, sort of (0.5)
- * 2000-06-30 fl added fast search optimization (0.9.3)
- * 2000-06-30 fl added assert (lookahead) primitives, etc (0.9.4)
- * 2000-07-02 fl added charset optimizations, etc (0.9.5)
+ * 2000-03-06 fl first alpha, sort of
+ * 2000-06-30 fl added fast search optimization
+ * 2000-06-30 fl added assert (lookahead) primitives, etc
+ * 2000-07-02 fl added charset optimizations, etc
* 2000-07-03 fl store code in pattern object, lookbehind, etc
* 2000-07-08 fl added regs attribute
- * 2000-07-21 fl reset lastindex in scanner methods (0.9.6)
- * 2000-08-01 fl fixes for 1.6b1 (0.9.8)
+ * 2000-07-21 fl reset lastindex in scanner methods
+ * 2000-08-01 fl fixes for 1.6b1
* 2000-08-03 fl added recursion limit
* 2000-08-07 fl use PyOS_CheckStack() if available
* 2000-08-08 fl changed findall to return empty strings instead of None
* 2000-09-20 fl added expand method
* 2000-09-21 fl don't use the buffer interface for unicode strings
* 2000-10-03 fl fixed assert_not primitive; support keyword arguments
+ * 2000-10-24 fl really fixed assert_not; reset groups in findall
*
* Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved.
*
#ifndef SRE_RECURSIVE
-char copyright[] = " SRE 0.9.8 Copyright (c) 1997-2000 by Secret Labs AB ";
+char copyright[] = " SRE 0.9.9 Copyright (c) 1997-2000 by Secret Labs AB ";
#include "Python.h"
/* <ASSERT_NOT> <skip> <back> <pattern> */
TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern, ptr, pattern[1]));
state->ptr = ptr - pattern[1];
- if (state->ptr < state->beginning)
- return 0;
- i = SRE_MATCH(state, pattern + 2, level + 1);
- if (i < 0)
- return i;
- if (i)
- return 0;
+ if (state->ptr >= state->beginning) {
+ i = SRE_MATCH(state, pattern + 2, level + 1);
+ if (i < 0)
+ return i;
+ if (i)
+ return 0;
+ }
pattern += pattern[0];
break;
n = PySequence_Length(code);
#endif
- self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, 100*n);
+ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
if (!self) {
Py_DECREF(code);
return NULL;
PyObject* item;
+ state_reset(&state);
+
state.ptr = state.start;
if (state.charsize == 1) {