Beispiel #1
0
// gofmtFlags looks for a comment of the form
//
//	//gofmt flags
//
// within the first maxLines lines of the given file,
// and returns the flags string, if any. Otherwise it
// returns the empty string.
func gofmtFlags(filename string, maxLines int) string {
	f, err := os.Open(filename)
	if err != nil {
		return "" // ignore errors - they will be found later
	}
	defer f.Close()

	// initialize scanner
	var s scanner.Scanner
	s.Init(f)
	s.Error = func(*scanner.Scanner, string) {}       // ignore errors
	s.Mode = scanner.GoTokens &^ scanner.SkipComments // want comments

	// look for //gofmt comment
	for s.Line <= maxLines {
		switch s.Scan() {
		case scanner.Comment:
			const prefix = "//gofmt "
			if t := s.TokenText(); strings.HasPrefix(t, prefix) {
				return strings.TrimSpace(t[len(prefix):])
			}
		case scanner.EOF:
			return ""
		}

	}

	return ""
}
Beispiel #2
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
}
Beispiel #3
0
func cmdFind(root *CmdNode, path string, level int) (*CmdNode, error) {

	var s scanner.Scanner
	s.Error = func(s *scanner.Scanner, msg string) {
		log.Printf("command scan error: %s [%s]", msg, path)
	}
	s.Init(strings.NewReader(path))

	parent := root
	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		//log.Printf("cmdFind: token: [%s]", s.TokenText())
		label := s.TokenText()
		children := matchChildren(parent.Children, label)
		size := len(children)
		if size < 1 {
			return nil, fmt.Errorf("cmdFind: not found: [%s] under [%s]", label, parent.Path)
		}
		if size > 1 {
			return nil, fmt.Errorf("cmdFind: ambiguous: [%s] under [%s]", label, parent.Path)
		}
		parent = children[0]
	}

	//log.Printf("cmdFind: found [%s] as [%s]", path, parent.Path)

	return parent, nil
}
Beispiel #4
0
func NewDecoder(r io.Reader) *Decoder {
	var scan scanner.Scanner
	scan.Init(r)
	dec := Decoder{scan: scan}
	scan.Error = dec.setError
	return &dec
}
Beispiel #5
0
func NewScanner(src []byte) *scanner.Scanner {
	var s scanner.Scanner
	s.Init(bytes.NewReader(src))
	s.Error = func(_ *scanner.Scanner, _ string) {}
	s.Whitespace = 0
	s.Mode = s.Mode ^ scanner.SkipComments
	return &s
}
Beispiel #6
0
// NewScannerReader takes a reader src and creates a Scanner.
func NewScannerReader(src io.Reader) *scanner.Scanner {
	var s scanner.Scanner
	s.Init(src)
	s.Error = func(_ *scanner.Scanner, _ string) {}
	s.Whitespace = 0
	s.Mode = s.Mode ^ scanner.SkipComments
	return &s
}
Beispiel #7
0
func main() {
	s := new(scanner.Scanner)
	s.Init(os.Stdin)
	s.Error = err

	parse := start
	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		parse = parse(s, tok)
	}
}
Beispiel #8
0
func StringToMap(value string) (map[string]string, error) {
	var tokenizer scanner.Scanner
	tokenizer.Init(strings.NewReader(value))
	tokenizer.Error = func(*scanner.Scanner, string) {}

	result := make(map[string]string)
	next := func() string {
		tokenizer.Scan()
		return tokenizer.TokenText()
	}

	var lvalue, rvalue, expression string
	for {
		lvalue = next()
		if lvalue == "" {
			return result, errors.New(fmt.Sprintf("Expected key at pos '%d' but found none; "+
				"map values should be 'key=value' separated by commas", tokenizer.Pos().Offset))
		}
		if lvalue == "{" {
			// Assume this is JSON format and attempt to un-marshal
			return JSONToMap(value)
		}

		expression = next()
		if expression != "=" {
			return result, errors.New(fmt.Sprintf("Expected '=' after '%s' but found '%s'; "+
				"map values should be 'key=value' separated by commas", lvalue, expression))
		}
		rvalue = next()
		if rvalue == "" {
			return result, errors.New(fmt.Sprintf("Expected value after '%s' but found none; "+
				"map values should be 'key=value' separated by commas", expression))
		}
		// TODO: Handle quoted strings and escaped double quotes
		result[lvalue] = rvalue

		// Are there anymore tokens?
		delimiter := next()
		if delimiter == "" {
			break
		}

		// Should be a comma next
		if delimiter != "," {
			return result, errors.New(fmt.Sprintf("Expected ',' after '%s' but found '%s'; "+
				"map values should be 'key=value' separated by commas", rvalue, delimiter))
		}
	}

	return result, nil
}
Beispiel #9
0
func parse(s scanner.Scanner) ([]ast, error) {
	scanErrors := []string{}
	s.Error = func(s *scanner.Scanner, msg string) {
		scanErrors = append(scanErrors, msg)
	}

	pt, err := parseText(&s, 0)
	if s.ErrorCount != 0 {
		return nil, errors.New(strings.Join(scanErrors, "\n"))
	} else if err != nil {
		return nil, err
	}

	return astRoot(pt), nil
}
Beispiel #10
0
// Text satifies the Extractor interface
//
//ReplaceGo is a specialized routine for correcting Golang source
// files.  Currently only checks comments, not identifiers for
// spelling.
//
// Other items:
//   - check strings, but need to ignore
//      * import "statements" blocks
//      * import ( "blocks" )
//   - skip first comment (line 0) if build comment
//
func (p *GolangText) Text(raw []byte) []byte {
	out := bytes.Buffer{}
	s := scanner.Scanner{}
	s.Init(bytes.NewReader(raw))
	s.Error = (func(s *scanner.Scanner, msg string) {})
	s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments
	for {
		switch s.Scan() {
		case scanner.Comment:
			out.WriteString(s.TokenText())
			out.WriteByte('\n')
		case scanner.EOF:
			return out.Bytes()
		}
	}
}
Beispiel #11
0
// parseCommand reads command name and arguments from the given input.
func parseCommand(data string) (string, ParamList) {
	var scan scanner.Scanner
	var list []string

	scan.Init(bytes.NewBufferString(strings.TrimSpace(data)))
	scan.Error = func(s *scanner.Scanner, msg string) {}

	tok := scan.Scan()
	for tok != scanner.EOF {
		list = append(list, unquote(scan.TokenText()))
		tok = scan.Scan()
	}

	if len(list) == 0 || scan.ErrorCount > 0 {
		return "", nil
	}

	return strings.ToLower(list[0]), ParamList(list[1:])
}
Beispiel #12
0
func funcFromFormula(form string) (string, error) {
	f, _, err := extractFormula(form)
	if err != nil {
		return "", err
	}
	var s scanner.Scanner
	s.Init(strings.NewReader(f))
	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("error parsing plural formula %s: %s", s.Pos(), msg)
	}
	s.Mode = scanner.ScanIdents | scanner.ScanInts
	s.Whitespace = 0
	tok := s.Scan()
	var code []string
	var buf bytes.Buffer
	for tok != scanner.EOF && err == nil {
		switch tok {
		case scanner.Ident, scanner.Int:
			buf.WriteString(s.TokenText())
		case '?':
			code = append(code, fmt.Sprintf("if %s {\n", buf.String()))
			buf.Reset()
		case ':':
			code = append(code, fmt.Sprintf("return %s\n}\n", buf.String()))
			buf.Reset()
		default:
			buf.WriteRune(tok)
		}
		tok = s.Scan()
	}
	if err != nil {
		return "", err
	}
	if len(code) == 0 && buf.Len() > 0 && buf.String() != "0" {
		code = append(code, fmt.Sprintf("if %s {\nreturn 1\n}\nreturn 0\n", buf.String()))
		buf.Reset()
	}
	if buf.Len() > 0 {
		code = append(code, fmt.Sprintf("\nreturn %s\n", buf.String()))
	}
	return strings.Join(code, ""), nil
}
Beispiel #13
0
func (cl *contLiner) countDepth() int {
	reader := bytes.NewBufferString(cl.buffer)
	sc := new(scanner.Scanner)
	sc.Init(reader)
	sc.Error = func(_ *scanner.Scanner, msg string) {
		debugf("scanner: %s", msg)
	}

	depth := 0
	for {
		switch sc.Scan() {
		case '{':
			depth++
		case '}':
			depth--
		case scanner.EOF:
			return depth
		}
	}
}
Beispiel #14
0
func TokenizeQuery(q string) ([]token, error) {

	tokens := make([]token, 0, 10)

	s := scanner.Scanner{}
	s.Init(strings.NewReader(q))

	var err error

	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("%s", msg)
	}

	for tok := s.Scan(); tok != scanner.EOF && err == nil; tok = s.Scan() {
		if strings.ContainsRune("():,", tok) {
			tokens = append(tokens, token{int(tok), ""})
		} else if s.TokenText() == "SELECT" {
			tokens = append(tokens, token{SELECT, ""})
		} else if s.TokenText() == "WHERE" {
			tokens = append(tokens, token{WHERE, ""})
		} else if s.TokenText() == "AND" {
			tokens = append(tokens, token{AND, ""})
		} else if s.TokenText() == "HOSTS" {
			tokens = append(tokens, token{HOSTS, ""})
		} else {
			text := s.TokenText()
			if strings.HasPrefix(text, "\"") && strings.HasSuffix(text, "\"") {
				text = text[1 : len(text)-1]
			}
			tokens = append(tokens, token{GENERIC_IDENTIFIER, text})
		}
	}

	return tokens, err

}
Beispiel #15
0
func parsePo(r io.Reader, filename string) (*Po, error) {
	comment := false
	s := new(scanner.Scanner)
	var err error
	s.Init(r)
	s.Filename = filename
	s.Error = func(s *scanner.Scanner, msg string) {
		if !comment {
			err = fmt.Errorf("error parsing %s: %s", s.Pos(), msg)
		}
	}
	s.Mode = scanner.ScanIdents | scanner.ScanStrings | scanner.ScanInts
	tok := s.Scan()
	po := &Po{Attrs: make(map[string]string)}
	var trans *Translation
	for tok != scanner.EOF && err == nil {
		if tok == '#' {
			// Skip until EOL
			comment = true
			s.Whitespace = whitespace
			for tok != '\n' && tok != scanner.EOF {
				tok = s.Scan()
			}
			s.Whitespace = scanner.GoWhitespace
			comment = false
			tok = s.Scan()
			continue
		}
		if tok != scanner.Ident {
			err = unexpected(s, tok)
			break
		}
		text := s.TokenText()
		switch text {
		case "msgctxt":
			if trans != nil {
				if len(trans.Translations) == 0 {
					err = unexpected(s, tok)
					break
				}
				po.addTranslation(trans)
			}
			trans = &Translation{Context: readString(s, &tok, &err)}
		case "msgid":
			if trans != nil {
				if len(trans.Translations) > 0 || trans.Singular != "" {
					po.addTranslation(trans)
				} else if trans.Context != "" {
					trans.Singular = readString(s, &tok, &err)
					break
				}
			}
			trans = &Translation{Singular: readString(s, &tok, &err)}
		case "msgid_plural":
			if trans == nil || trans.Plural != "" {
				err = unexpected(s, tok)
				break
			}
			trans.Plural = readString(s, &tok, &err)
		case "msgstr":
			str := readString(s, &tok, &err)
			if tok == '[' {
				tok = s.Scan()
				if tok != scanner.Int {
					err = unexpected(s, tok)
					break
				}
				ii, _ := strconv.Atoi(s.TokenText())
				if ii != len(trans.Translations) {
					err = unexpected(s, tok)
					break
				}
				if tok = s.Scan(); tok != ']' {
					err = unexpected(s, tok)
					break
				}
				str = readString(s, &tok, &err)
			}
			trans.Translations = append(trans.Translations, str)
		default:
			err = unexpected(s, tok)
		}
	}
	if trans != nil {
		po.addTranslation(trans)
	}
	if err != nil {
		return nil, err
	}
	for _, v := range po.Messages {
		if v.Context == "" && v.Singular == "" {
			if len(v.Translations) > 0 {
				meta := v.Translations[0]
				for _, line := range strings.Split(meta, "\n") {
					colon := strings.Index(line, ":")
					if colon > 0 {
						key := strings.TrimSpace(line[:colon])
						value := strings.TrimSpace(line[colon+1:])
						po.Attrs[key] = value
					}
				}
			}
			break
		}
	}
	return po, nil
}
Beispiel #16
0
func fail(s *scanner.Scanner, tok rune) step {
	s.Error(s, fmt.Sprintf("unhandled: %s %s", scanner.TokenString(tok), s.TokenText()))
	return fail
}