Ejemplo n.º 1
0
func (d *Dict) expandDirective(in *scanner.Scanner, out *bufio.Writer) error {
	var err error

	c := in.Next()
	switch c {
	case lDelim:
		switch in.Peek() {
		case lDelim:
			return copyNext(in, out)
		case condDelim:
			in.Next()
			err = d.expandCond(in, out)
		default:
			if err = d.expandVar(in, out); err == nil {
				err = match(in, rDelim)
			}
		}
	case rDelim:
		if err = writeString(out, "}"); err == nil {
			err = match(in, rDelim)
		}
	case scanner.EOF:
		err = parseErr(in, "Expected '%c' or '%c', got EOF", lDelim, rDelim)
	default:
		err = parseErr(in, "Expected '%c' or '%c', got '%c'", lDelim, rDelim, c)
	}

	return err
}
Ejemplo n.º 2
0
func copyUntilDelim(in *scanner.Scanner, out *bufio.Writer) error {
	var err error
	for err == nil && !isEOF(in) && in.Peek() != lDelim && in.Peek() != rDelim {
		err = copyNext(in, out)
	}
	return err
}
Ejemplo n.º 3
0
func parseVariable(sc *scanner.Scanner) (result []byte, err error) {
	delims := []byte{byte(sc.Next())}

	if ch := sc.Peek(); ch == '{' {
		delims = append(delims, byte(sc.Next()))
	}

	name, err := parseName(sc)

	if err == nil && len(delims) > 1 && '}' != byte(sc.Peek()) {
		err = errInvalidSyntax
	}

	if err != nil {
		name = append(delims, name...)
		if len(delims) > 1 {
			name = append(name, byte(sc.Next()))
		}

		return name, err
	}

	if len(delims) > 1 {
		sc.Next()
	}
	return name, err
}
Ejemplo n.º 4
0
// ProcessConfig replaces references of environment varialbes for the given data
// Support variable syntax: $varname, ${varname}
func ProcessConfig(data []byte, e *env.Env, escapeChar rune) ([]byte, error) {
	var result []byte
	var sc scanner.Scanner
	sc.Init(bytes.NewReader(data))

DONE:
	for {
		switch ch := sc.Peek(); ch {
		default:
			result = append(result, byte(sc.Next()))
		case scanner.EOF:
			break DONE
		case escapeChar:
			curr, next := sc.Next(), sc.Peek()
			if next != '$' {
				result = append(result, byte(curr))
			}

			if next != scanner.EOF {
				result = append(result, byte(sc.Next()))
			}

		case '$':
			name, err := parseVariable(&sc)

			if err != nil {
				pos := sc.Pos()
				return result, fmt.Errorf(`parseError:%d:%d: %v %q`, pos.Line, pos.Offset, err, name)
			}
			result = append(result, e.Get(string(name))...)
		}
	}
	return result, nil
}
Ejemplo n.º 5
0
func scanArray(s *scanner.Scanner, out chan Part, stop villa.Stop) (toStop bool) {
	if scanRune(s, out, stop, TP_ARRAY_START, '[') {
		return true
	}

	skipWhitespaces(s)
	if s.Peek() != ']' {
		for {
			if scanValue(s, out, stop) {
				return true
			}

			skipWhitespaces(s)
			if s.Peek() != ',' {
				break
			}

			if scanRune(s, out, stop, TP_COMMA, ',') {
				return true
			}

			skipWhitespaces(s)
		}
	}

	return scanRune(s, out, stop, TP_ARRAY_END, ']')
}
Ejemplo n.º 6
0
func split(expr string) (keys []string, err error) {

	var msgs []string
	var s scanner.Scanner
	s.Init(strings.NewReader(expr))
	s.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanStrings
	s.Error = func(s *scanner.Scanner, msg string) { msgs = append(msgs, fmt.Sprintf("%s %s", s.Pos(), msg)) }

	key := ""
	keys = []string{}
	for err == nil {
		t := s.Peek()
		// fmt.Printf(">>> %s: %s %s\n", s.Pos(), scanner.TokenString(t), s.TokenText())
		switch t {
		case '[':
			key, err = scanBracketedKey(&s)
		case '.':
			s.Scan()
			continue
		case scanner.EOF:
			goto end
		default:
			key, err = scanKey(&s)
		}
		if len(msgs) > 0 {
			err = errors.New(strings.Join(msgs, "\n"))
		}
		if err == nil {
			keys = append(keys, key)
		}
	}
end:
	return
}
Ejemplo n.º 7
0
Archivo: xml.go Proyecto: postfix/sgrep
func scanTo3(s *scanner.Scanner, target0, target1, target2 rune) bool {
	for {
		// match 0, 1
		if !scanTo2(s, target0, target1) {
			// EOF
			return false
		}
		switch s.Peek() {
		case scanner.EOF:
			s.Next()
			return false
		case target2:
			// matched 2, found
			s.Next()
			return true
		case target1:
			if target0 == target1 {
			loop:
				for {
					switch s.Next() {
					case scanner.EOF:
						return false
					case target2:
						return true
					case target0:
						// keep scanning
					default:
						// not found, go to out loop
						break loop
					}
				}
			}
		}
	}
}
Ejemplo n.º 8
0
func (w *wordsStruct) addString(str string) {
	var scan scanner.Scanner
	scan.Init(strings.NewReader(str))
	for scan.Peek() != scanner.EOF {
		w.addChar(scan.Next())
	}
}
Ejemplo n.º 9
0
// Parse the selector after ':'
func ParsePseudo(selector *CSSSelector, s scanner.Scanner) error {
	if selector.Pseudo != nil {
		return fmt.Errorf("Combined multiple pseudo classes")
	}
	var b bytes.Buffer
	for s.Peek() != scanner.EOF {
		if _, err := b.WriteRune(s.Next()); err != nil {
			return err
		}
	}
	cmd := b.String()
	var err error
	switch {
	case cmd == "empty":
		selector.Pseudo = func(n *html.Node) bool {
			return n.FirstChild == nil
		}
	case cmd == "first-child":
		selector.Pseudo = firstChildPseudo
	case cmd == "last-child":
		selector.Pseudo = lastChildPseudo
	case cmd == "only-child":
		selector.Pseudo = func(n *html.Node) bool {
			return firstChildPseudo(n) && lastChildPseudo(n)
		}
	case cmd == "first-of-type":
		selector.Pseudo = firstOfTypePseudo
	case cmd == "last-of-type":
		selector.Pseudo = lastOfTypePseudo
	case cmd == "only-of-type":
		selector.Pseudo = func(n *html.Node) bool {
			return firstOfTypePseudo(n) && lastOfTypePseudo(n)
		}
	case strings.HasPrefix(cmd, "contains("):
		selector.Pseudo, err = parseContainsPseudo(cmd[len("contains("):])
		if err != nil {
			return err
		}
	case strings.HasPrefix(cmd, "nth-child("),
		strings.HasPrefix(cmd, "nth-last-child("),
		strings.HasPrefix(cmd, "nth-last-of-type("),
		strings.HasPrefix(cmd, "nth-of-type("):
		if selector.Pseudo, err = parseNthPseudo(cmd); err != nil {
			return err
		}
	case strings.HasPrefix(cmd, "not("):
		if selector.Pseudo, err = parseNotPseudo(cmd[len("not("):]); err != nil {
			return err
		}
	case strings.HasPrefix(cmd, "parent-of("):
		if selector.Pseudo, err = parseParentOfPseudo(cmd[len("parent-of("):]); err != nil {
			return err
		}
	default:
		return fmt.Errorf("%s not a valid pseudo class", cmd)
	}
	return nil
}
Ejemplo n.º 10
0
func parseText(s *scanner.Scanner, depth int) ([]ast, error) {
	var slice []ast
	for {
		switch s.Scan() {
		case '+', '-', '/', '%', '*', '=', '<', '>', '!':
			slice = append(slice, parseIdent(s.TokenText()))
		case scanner.Ident:
			ident := s.TokenText()
			// Periods are allowed in package names.
			for s.Peek() == '.' {
				s.Next()
				ident += "."
				if s.Scan() != scanner.Ident {
					return nil, stitchError{pos: s.Pos(),
						err: fmt.Errorf("bad ident name: %s",
							ident)}
				}
				ident += s.TokenText()
			}
			slice = append(slice, parseIdent(ident))
		case scanner.Float:
			x, _ := strconv.ParseFloat(s.TokenText(), 64)
			slice = append(slice, astFloat(x))
		case scanner.Int:
			x, _ := strconv.Atoi(s.TokenText())
			slice = append(slice, astInt(x))
		case scanner.String:
			str := strings.Trim(s.TokenText(), "\"")
			slice = append(slice, astString(str))
		case '(':
			// We need to save our position before recursing because the
			// scanner will have moved on by the time the recursive call
			// returns.
			pos := s.Pos()
			sexp, err := parseText(s, depth+1)
			if err != nil {
				return nil, err
			}

			slice = append(slice, astSexp{sexp: sexp, pos: pos})

		case ')':
			if depth == 0 {
				return nil, stitchError{s.Pos(), errUnbalancedParens}
			}
			return slice, nil
		case scanner.EOF:
			if depth != 0 {
				return nil, stitchError{s.Pos(), errUnbalancedParens}
			}
			return slice, nil

		default:
			return nil, stitchError{s.Pos(), fmt.Errorf("bad element: %s",
				s.TokenText())}
		}
	}
}
Ejemplo n.º 11
0
Archivo: xml.go Proyecto: postfix/sgrep
func scanTo2(s *scanner.Scanner, target0, target1 rune) bool {
	for {
		switch s.Next() {
		case scanner.EOF:
			return false
		case target0:
			if s.Peek() == target1 {
				s.Next() // skip targe1
				return true
			}
		}
	}
}
Ejemplo n.º 12
0
// collect the next characters in s that are numbers
// assumes at least TokenText is a number
func Number(s *scanner.Scanner) string {
	var buffer bytes.Buffer

	for s.Scan() != scanner.EOF {
		buffer.WriteString(s.TokenText())

		if _, ok := strconv.Atoi(string(s.Peek())); ok != nil {
			return buffer.String()
		}
	}

	// reached the end of file, but that's ok potentially?
	return buffer.String()
}
Ejemplo n.º 13
0
func readVar(in *scanner.Scanner) (s string, err error) {
	var buf bytes.Buffer

	for isVarRune(in.Peek()) {
		buf.WriteRune(in.Next())
	}

	s = buf.String()
	if in.Peek() != rDelim {
		err = parseErr(in, "Unexpected character '%c'", in.Next())
	} else if len(s) == 0 {
		err = parseErr(in, "Empty variable")
	}
	return
}
Ejemplo n.º 14
0
func parseXML(sc *scanner.Scanner) (*Token, bool) {

	var entity = new(bytes.Buffer)
	token := new(Token)

	// Skip the '<'
	sc.Scan()

	switch sc.Peek() {
	case '/':
		token.Type = XMLEndToken
		sc.Next()
	case '!':
		log.Tracef("parseXML skipping comment")
		next := sc.Next()
		for next != '>' {
			next = sc.Next()
		}
		return nil, false
	default:
		token.Type = XMLStartToken
	}

	log.Tracef("parseXML creating %s element", token.Type)

	for {
		tok := sc.Scan()
		log.Tracef("parseXML found %s. Token is %v. Entity is: '%s'",
			sc.TokenText(),
			tok,
			entity.String())

		switch {
		case tok == '>':
			token.Text = entity.String()
			return token, true

		case unicode.IsSpace(tok):
			return nil, false

		default:
			log.Tracef("parseXML appending %s to string",
				sc.TokenText())
			entity.WriteString(sc.TokenText())

		}
	}
}
Ejemplo n.º 15
0
func scanKeyword(s *scanner.Scanner, out chan Part, stop villa.Stop) (toStop bool) {
	start := s.Pos()
	switch s.Peek() {
	case scanner.EOF:
		s.Next()
		return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
	case 't':
		return scanWord(s, out, stop, []rune("true"))
	case 'f':
		return scanWord(s, out, stop, []rune("false"))
	case 'n':
		return scanWord(s, out, stop, []rune("null"))
	}
	s.Next()
	return output(out, stop, TP_ERROR, start, s.Pos())
}
Ejemplo n.º 16
0
func parseName(sc *scanner.Scanner) (result []byte, err error) {
	if ch := sc.Peek(); scanner.EOF == ch {
		return result, errInvalidSyntax
	}

	for {
		if ch := sc.Peek(); unicode.IsLetter(ch) || unicode.IsDigit(ch) || '_' == ch {
			result = append(result, byte(sc.Next()))
		} else {
			if len(result) == 0 {
				err = errInvalidSyntax
			}
			return result, err
		}
	}
}
Ejemplo n.º 17
0
func scanValue(s *scanner.Scanner, out chan Part, stop villa.Stop) (toStop bool) {
	start := s.Pos()
	switch s.Peek() {
	case scanner.EOF:
		return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
	case '"':
		return scanString(s, out, stop)
	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return scanNumber(s, out, stop)
	case 't', 'f', 'n':
		return scanKeyword(s, out, stop)
	case '{':
		return scanObject(s, out, stop)
	case '[':
		return scanArray(s, out, stop)
	}
	return output(out, stop, TP_ERROR, start, s.Pos())
}
Ejemplo n.º 18
0
Archivo: gen.go Proyecto: streadway/zk
func fields(s *scanner.Scanner, tok rune) step {
	switch tok {
	case '.':
		return fields
	case '{':
		return fields
	case '}':
		return endStruct(s, tok)
	case ';':
		return fields
	case scanner.Ident:
		if s.Peek() == '.' {
			return fields
		}
		return emitField(s, tok)
	}
	return fail
}
Ejemplo n.º 19
0
func (d *Dict) expandCond(in *scanner.Scanner, writer *bufio.Writer) error {
	expand, err := d.evalBool(in)
	if err != nil {
		return err
	}

	var out *bufio.Writer
	expanded := false
	for err == nil && !isEOF(in) {
		if !expanded && expand {
			out = writer
			expanded = true
		}

		if err = copyUntilDelim(in, out); err != nil {
			break
		}

		if in.Peek() == lDelim {
			in.Next()

			switch in.Peek() {
			case lDelim:
				err = copyNext(in, out)
			case condDelim:
				in.Next()
				if in.Peek() == rDelim {
					in.Next()
					return nil
				} else {
					err = d.expandCond(in, out)
				}
			case condElsif:
				in.Next()
				out = nil
				if in.Peek() == rDelim {
					in.Next()
					expand = true
				} else {
					expand, err = d.evalBool(in)
				}
			default:
				err = d.expandVar(in, out)
				if out == nil || err == nil {
					err = match(in, rDelim)
				}
			}
		} else {
			err = d.expandDirective(in, out)
		}
	}

	return err
}
Ejemplo n.º 20
0
func get_map(data []byte) (map[string]string, error) {
	src := bytes.NewReader(data)
	var s scanner.Scanner
	var tok rune
	s.Init(src)
	var key, value string
	m := map[string]string{}
	for {
		if tok = s.Scan(); tok == scanner.Ident {
			key = s.TokenText()
			if tok = s.Scan(); tok == rune('=') {
				tok = s.Scan()
				if tok == scanner.String {
					v := []rune(s.TokenText())
					value = string(v[1 : len(v)-1])
				} else {
					if tok == scanner.Ident {
						value = s.TokenText()
						for {
							if tok = s.Peek(); tok == rune(',') || tok == scanner.EOF {
								break
							}
							tok = s.Scan()
							value += s.TokenText()
						}
					}
				}
				m[key] = value
				tok = s.Scan()
				if tok == scanner.EOF {
					break
				}
				if tok == rune(',') {
					continue
				}
			}
		}
		return nil, errors.New("Failed to parse SASL challenge string")
	}
	return m, nil
}
Ejemplo n.º 21
0
func ParseTags(s *scanner.Scanner, g *Game) error {
	//fmt.Println("starting tags parse")
	run := s.Peek()
	for run != scanner.EOF {
		switch run {
		case '[', ']', '\n', '\r':
			run = s.Next()
		case '1':
			return nil
		default:
			s.Scan()
			tag := s.TokenText()
			s.Scan()
			val := s.TokenText()
			//fmt.Println("tag:", tag, "; val:", val)
			g.Tags[tag] = strings.Trim(val, "\"")
		}
		run = s.Peek()
	}
	return nil
}
Ejemplo n.º 22
0
func scanString(s *scanner.Scanner, out chan Part, stop villa.Stop) (toStop bool) {
	start := s.Pos()
	// start quote
	if r := s.Next(); r == scanner.EOF {
		return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
	} else if r != '"' {
		return output(out, stop, TP_ERROR, start, s.Pos())
	}

	// body
	for s.Peek() != '"' {
		if r := s.Next(); r == scanner.EOF {
			return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
		} else if r == '\\' {
			switch s.Next() {
			case scanner.EOF:
				return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
			case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
				// just ok
			case 'u':
				for i := 0; i < 4; i++ {
					r := s.Next()
					if r == scanner.EOF {
						return output(out, stop, TP_EOF_UNEXPECTED, start, s.Pos())
					}

					if !isHexadecimal(r) {
						return output(out, stop, TP_ERROR, start, s.Pos())
					}
				}
			default:
				return output(out, stop, TP_ERROR, start, s.Pos())
			}
		}
	}
	// end quote
	s.Next()
	return output(out, stop, TP_STRING, start, s.Pos())
}
Ejemplo n.º 23
0
func scanObject(s *scanner.Scanner, out chan Part, stop villa.Stop) (toStop bool) {
	if scanRune(s, out, stop, TP_OBJECT_START, '{') {
		return true
	}

	skipWhitespaces(s)
	if s.Peek() != '}' {
		for {
			if scanString(s, out, stop) {
				return true
			}

			skipWhitespaces(s)
			if scanRune(s, out, stop, TP_COLON, ':') {
				return true
			}

			skipWhitespaces(s)
			if scanValue(s, out, stop) {
				return true
			}

			skipWhitespaces(s)
			if s.Peek() != ',' {
				break
			}

			if scanRune(s, out, stop, TP_COMMA, ',') {
				return true
			}

			skipWhitespaces(s)
		}
	}
	return scanRune(s, out, stop, TP_OBJECT_END, '}')
}
Ejemplo n.º 24
0
Archivo: xml.go Proyecto: postfix/sgrep
func skipWhiteSpace(s *scanner.Scanner) {
	for isWhiteSpace(s.Peek()) {
		s.Next()
	}
}
Ejemplo n.º 25
0
Archivo: xml.go Proyecto: postfix/sgrep
func scanBlock(s *scanner.Scanner) (blockType int, name string) {
	if s.Peek() != '<' {
		for s.Peek() != scanner.EOF && s.Peek() != '<' {
			s.Next()
		}
		return TP_FINAL, ""
	}
	// '<'
	s.Next()

	switch tp := s.Next(); tp {
	case '?':
		// PI
		// to find ?>
		scanTo2(s, '?', '>')
		return TP_FINAL, ""
	case '!':
		switch s.Next() {
		case scanner.EOF:
			// malformed
		case '[':
			// <![CDATA
			// find ]]>
			scanTo3(s, ']', ']', '>')
		case '-':
			// comments
			// find -->
			scanTo3(s, '-', '-', '>')
			return TP_COMMENT, ""
		default:
			// Attribute-List
			// find >
			scanTo1(s, '>')
		}
		return TP_FINAL, ""
	case '/':
		// end tag
		name := make([]rune, 0, 8)
		for {
			r := s.Next()
			if r == scanner.EOF || r == '>' {
				break
			}
			if isWhiteSpace(r) {
				scanTo1(s, '>')
				break
			}
			name = append(name, r)
		}
		if len(name) == 0 {
			// malformed
			return TP_FINAL, ""
		}
		return TP_END, string(name)
	case '>':
		// malformed
		return TP_FINAL, ""
	default:
		// start tag
		name := []rune{tp}
		for {
			r := s.Next()
			if r == scanner.EOF || r == '>' {
				break
			}

			if r == '/' {
				if s.Peek() == '>' {
					s.Next()
					return TP_FINAL, string(name)
				}
			}

			if isWhiteSpace(r) {
			loop:
				for {
					switch s.Next() {
					case scanner.EOF:
						return TP_FINAL, string(name)
					case '/':
						if s.Peek() == '>' {
							s.Next()
							return TP_FINAL, string(name)
						}
					case '>':
						break loop
					}
				}
				break
			}
			name = append(name, r)
		}
		return TP_START, string(name)
	}
}
Ejemplo n.º 26
0
func skipWhitespaces(s *scanner.Scanner) {
	for s.Peek() != scanner.EOF && isWhitespace(s.Peek()) {
		s.Next()
	}
}
Ejemplo n.º 27
0
func regexpMatch(pattern, path string) (bool, error) {
	regStr := "^"

	if _, err := filepath.Match(pattern, path); err != nil {
		return false, err
	}

	var scan scanner.Scanner
	scan.Init(strings.NewReader(pattern))

	sl := string(os.PathSeparator)
	escSL := sl
	if sl == `\` {
		escSL += `\`
	}

	for scan.Peek() != scanner.EOF {
		ch := scan.Next()

		if ch == '*' {
			if scan.Peek() == '*' {
				scan.Next()

				if scan.Peek() == scanner.EOF {
					regStr += ".*"
				} else {
					regStr += "((.*" + escSL + ")|([^" + escSL + "]*))"
				}

				if string(scan.Peek()) == sl {
					scan.Next()
				}
			} else {
				regStr += "[^" + escSL + "]*"
			}
		} else if ch == '?' {
			regStr += "[^" + escSL + "]"
		} else if strings.Index(".$", string(ch)) != -1 {
			regStr += `\` + string(ch)
		} else if ch == '\\' {
			if sl == `\` {
				regStr += escSL
				continue
			}
			if scan.Peek() != scanner.EOF {
				regStr += `\` + string(scan.Next())
			} else {
				regStr += `\`
			}
		} else {
			regStr += string(ch)
		}
	}

	regStr += "$"

	res, err := regexp.MatchString(regStr, path)

	if err != nil {
		err = filepath.ErrBadPattern
	}

	return res, err
}
Ejemplo n.º 28
0
func ParseMoves(s *scanner.Scanner, g *Game) error {
	//fmt.Println("starting moves parse")
	s.Mode = scanner.ScanIdents | scanner.ScanChars | scanner.ScanInts | scanner.ScanStrings
	run := s.Peek()
	board := NewBoard()
	var err error
	if len(g.Tags["FEN"]) > 0 {
		board, err = NewBoardFEN(g.Tags["FEN"])
		if err != nil {
			return err
		}
	}
	num := ""
	white := ""
	black := ""
	for run != scanner.EOF {
		switch run {
		case '(':
			for run != ')' && run != scanner.EOF {
				run = s.Next()
			}
		case '{':
			for run != '}' && run != scanner.EOF {
				run = s.Next()
			}
		case '#', '.', '+', '!', '?', '\n', '\r':
			run = s.Next()
			run = s.Peek()
		default:
			s.Scan()
			if s.TokenText() == "{" {
				run = '{'
				continue
			}
			if num == "" {
				num = s.TokenText()
				for s.Peek() == '-' {
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
				}
				for s.Peek() == '/' {
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
					s.Scan()
					num += s.TokenText()
				}
				if isEnd(num) {
					return nil
				}
			} else if white == "" {
				white = s.TokenText()
				for s.Peek() == '-' {
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
				}
				for s.Peek() == '/' {
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
				}
				if isEnd(white) {
					return nil
				}
				if s.Peek() == '=' {
					s.Scan()
					white += s.TokenText()
					s.Scan()
					white += s.TokenText()
				}
				move, err := board.MoveFromAlgebraic(white, White)
				if err != nil {
					fmt.Println(board)
					return err
				}
				g.Moves = append(g.Moves, move)
				board.MakeMove(move)
			} else if black == "" {
				black = s.TokenText()
				for s.Peek() == '-' {
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
				}
				for s.Peek() == '/' {
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
				}
				if isEnd(black) {
					return nil
				}
				if s.Peek() == '=' {
					s.Scan()
					black += s.TokenText()
					s.Scan()
					black += s.TokenText()
				}
				move, err := board.MoveFromAlgebraic(black, Black)
				if err != nil {
					fmt.Println(board)
					return err
				}
				g.Moves = append(g.Moves, move)
				board.MakeMove(move)
				num = ""
				white = ""
				black = ""
			}
			run = s.Peek()
		}
	}
	return nil
}
Ejemplo n.º 29
0
// regexpMatch tries to match the logic of filepath.Match but
// does so using regexp logic. We do this so that we can expand the
// wildcard set to include other things, like "**" to mean any number
// of directories.  This means that we should be backwards compatible
// with filepath.Match(). We'll end up supporting more stuff, due to
// the fact that we're using regexp, but that's ok - it does no harm.
func regexpMatch(pattern, path string) (bool, error) {
	regStr := "^"

	// Do some syntax checking on the pattern.
	// filepath's Match() has some really weird rules that are inconsistent
	// so instead of trying to dup their logic, just call Match() for its
	// error state and if there is an error in the pattern return it.
	// If this becomes an issue we can remove this since its really only
	// needed in the error (syntax) case - which isn't really critical.
	if _, err := filepath.Match(pattern, path); err != nil {
		return false, err
	}

	// Go through the pattern and convert it to a regexp.
	// We use a scanner so we can support utf-8 chars.
	var scan scanner.Scanner
	scan.Init(strings.NewReader(pattern))

	sl := string(os.PathSeparator)
	escSL := sl
	if sl == `\` {
		escSL += `\`
	}

	for scan.Peek() != scanner.EOF {
		ch := scan.Next()

		if ch == '*' {
			if scan.Peek() == '*' {
				// is some flavor of "**"
				scan.Next()

				if scan.Peek() == scanner.EOF {
					// is "**EOF" - to align with .gitignore just accept all
					regStr += ".*"
				} else {
					// is "**"
					regStr += "((.*" + escSL + ")|([^" + escSL + "]*))"
				}

				// Treat **/ as ** so eat the "/"
				if string(scan.Peek()) == sl {
					scan.Next()
				}
			} else {
				// is "*" so map it to anything but "/"
				regStr += "[^" + escSL + "]*"
			}
		} else if ch == '?' {
			// "?" is any char except "/"
			regStr += "[^" + escSL + "]"
		} else if strings.Index(".$", string(ch)) != -1 {
			// Escape some regexp special chars that have no meaning
			// in golang's filepath.Match
			regStr += `\` + string(ch)
		} else if ch == '\\' {
			// escape next char. Note that a trailing \ in the pattern
			// will be left alone (but need to escape it)
			if sl == `\` {
				// On windows map "\" to "\\", meaning an escaped backslash,
				// and then just continue because filepath.Match on
				// Windows doesn't allow escaping at all
				regStr += escSL
				continue
			}
			if scan.Peek() != scanner.EOF {
				regStr += `\` + string(scan.Next())
			} else {
				regStr += `\`
			}
		} else {
			regStr += string(ch)
		}
	}

	regStr += "$"

	res, err := regexp.MatchString(regStr, path)

	// Map regexp's error to filepath's so no one knows we're not using filepath
	if err != nil {
		err = filepath.ErrBadPattern
	}

	return res, err
}
Ejemplo n.º 30
0
func isEOF(in *scanner.Scanner) bool {
	return in.Peek() == scanner.EOF
}