diff options
Diffstat (limited to 'libgo/go/regexp/exec.go')
-rw-r--r-- | libgo/go/regexp/exec.go | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/libgo/go/regexp/exec.go b/libgo/go/regexp/exec.go index 518272092a..977619cb28 100644 --- a/libgo/go/regexp/exec.go +++ b/libgo/go/regexp/exec.go @@ -19,7 +19,7 @@ type queue struct { // A entry is an entry on a queue. // It holds both the instruction pc and the actual thread. // Some queue entries are just place holders so that the machine -// knows it has considered that pc. Such entries have t == nil. +// knows it has considered that pc. Such entries have t == nil. type entry struct { pc uint32 t *thread @@ -107,14 +107,6 @@ func (m *machine) alloc(i *syntax.Inst) *thread { return t } -// free returns t to the free pool. -func (m *machine) free(t *thread) { - m.inputBytes.str = nil - m.inputString.str = "" - m.inputReader.r = nil - m.pool = append(m.pool, t) -} - // match runs the machine over the input starting at pos. // It reports whether a match was found. // If so, m.matchcap holds the submatch information. @@ -192,7 +184,6 @@ func (m *machine) match(i input, pos int) bool { func (m *machine) clear(q *queue) { for _, d := range q.dense { if d.t != nil { - // m.free(d.t) m.pool = append(m.pool, d.t) } } @@ -213,7 +204,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy continue } if longest && m.matched && len(t.cap) > 0 && m.matchcap[0] < t.cap[0] { - // m.free(t) m.pool = append(m.pool, t) continue } @@ -232,7 +222,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy // First-match mode: cut off all lower-priority threads. for _, d := range runq.dense[j+1:] { if d.t != nil { - // m.free(d.t) m.pool = append(m.pool, d.t) } } @@ -253,7 +242,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy t = m.add(nextq, i.Out, nextPos, t.cap, nextCond, t) } if t != nil { - // m.free(t) m.pool = append(m.pool, t) } } @@ -417,14 +405,16 @@ func (m *machine) onepass(i input, pos int) bool { return m.matched } -// empty is a non-nil 0-element slice, -// so doExecute can avoid an allocation -// when 0 captures are requested from a successful match. -var empty = make([]int, 0) +// doMatch reports whether either r, b or s match the regexp. +func (re *Regexp) doMatch(r io.RuneReader, b []byte, s string) bool { + return re.doExecute(r, b, s, 0, 0, nil) != nil +} -// doExecute finds the leftmost match in the input and returns -// the position of its subexpressions. -func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap int) []int { +// doExecute finds the leftmost match in the input, appends the position +// of its subexpressions to dstCap and returns dstCap. +// +// nil is returned if no matches are found and non-nil if matches are found. +func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap int, dstCap []int) []int { m := re.get() var i input var size int @@ -457,12 +447,15 @@ func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap i return nil } } - if ncap == 0 { - re.put(m) - return empty // empty but not nil + dstCap = append(dstCap, m.matchcap...) + if dstCap == nil { + // Keep the promise of returning non-nil value on match. + dstCap = arrayNoInts[:0] } - cap := make([]int, len(m.matchcap)) - copy(cap, m.matchcap) re.put(m) - return cap + return dstCap } + +// arrayNoInts is returned by doExecute match if nil dstCap is passed +// to it with ncap=0. +var arrayNoInts [0]int |