예제 #1
0
// Substitutes values, calculated by callback, on matching regex
func (c *Config) computeVar(beforeValue *string, regx *regexp.Regexp, headsz, tailsz int, withVar func(*string) string) (*string, error) {
	var i int
	computedVal := beforeValue
	for i = 0; i < _DEPTH_VALUES; i++ { // keep a sane depth

		vr := regx.FindStringSubmatchIndex(*computedVal)
		if len(vr) == 0 {
			break
		}

		varname := (*computedVal)[vr[headsz]:vr[headsz+1]]
		varVal := withVar(&varname)
		if varVal == "" {
			return &varVal, errors.New(fmt.Sprintf("Option not found: %s", varname))
		}

		// substitute by new value and take off leading '%(' and trailing ')s'
		//  %(foo)s => headsz=2, tailsz=2
		//  ${foo}  => headsz=2, tailsz=1
		newVal := (*computedVal)[0:vr[headsz]-headsz] + varVal + (*computedVal)[vr[headsz+1]+tailsz:]
		computedVal = &newVal
	}

	if i == _DEPTH_VALUES {
		retVal := ""
		return &retVal,
			fmt.Errorf("Possible cycle while unfolding variables: max depth of %d reached", _DEPTH_VALUES)
	}

	return computedVal, nil
}
예제 #2
0
파일: matcher.go 프로젝트: rsc/go-misc
// consume searches for r in the remaining text. If found, it consumes
// up to the end of the match, fills m.groups with the matched groups,
// and returns true.
func (m *matcher) consume(r *regexp.Regexp) bool {
	idx := r.FindStringSubmatchIndex(m.str[m.pos:])
	if idx == nil {
		m.groups = m.groups[:0]
		return false
	}
	if len(idx)/2 <= cap(m.groups) {
		m.groups = m.groups[:len(idx)/2]
	} else {
		m.groups = make([]string, len(idx)/2, len(idx))
	}
	for i := range m.groups {
		if idx[i*2] >= 0 {
			m.groups[i] = m.str[m.pos+idx[i*2] : m.pos+idx[i*2+1]]
		} else {
			m.groups[i] = ""
		}
	}
	m.matchPos = m.pos + idx[0]
	m.pos += idx[1]
	return true
}