File: cached_parser.go

package info (click to toggle)
golang-github-editorconfig-editorconfig-core-go 2.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 220 kB
  • sloc: makefile: 32
file content (89 lines) | stat: -rw-r--r-- 2,087 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package editorconfig

import (
	"errors"
	"fmt"
	"os"
	"regexp"

	"gopkg.in/ini.v1"
)

// CachedParser implements the Parser interface but caches the definition and
// the regular expressions.
type CachedParser struct {
	editorconfigs map[string]*Editorconfig
	regexps       map[string]*regexp.Regexp
}

// NewCachedParser initializes the CachedParser.
func NewCachedParser() *CachedParser {
	return &CachedParser{
		editorconfigs: make(map[string]*Editorconfig),
		regexps:       make(map[string]*regexp.Regexp),
	}
}

// ParseIni parses the given filename to a Definition and caches the result.
func (parser *CachedParser) ParseIni(filename string) (*Editorconfig, error) {
	ec, warning, err := parser.ParseIniGraceful(filename)
	if err != nil {
		return nil, err
	}

	return ec, warning
}

// ParseIniGraceful parses the given filename to a Definition and caches the result.
func (parser *CachedParser) ParseIniGraceful(filename string) (*Editorconfig, error, error) {
	var warning error

	ec, ok := parser.editorconfigs[filename]
	if !ok {
		fp, err := os.Open(filename)
		if err != nil {
			return nil, nil, fmt.Errorf("error opening %q: %w", filename, err)
		}

		defer fp.Close()

		iniFile, err := ini.Load(fp)
		if err != nil {
			return nil, nil, fmt.Errorf("error loading ini file %q: %w", filename, err)
		}

		var warn error

		ec, warn, err = newEditorconfig(iniFile)
		if err != nil {
			return nil, nil, fmt.Errorf("error creating config: %w", err)
		}

		if warn != nil {
			warning = errors.Join(warning, warn)
		}

		parser.editorconfigs[filename] = ec
	}

	return ec, warning, nil
}

// FnmatchCase calls the module's FnmatchCase and caches the parsed selector.
func (parser *CachedParser) FnmatchCase(selector string, filename string) (bool, error) {
	r, ok := parser.regexps[selector]
	if !ok {
		p := translate(selector)

		var err error

		r, err = regexp.Compile(fmt.Sprintf("^%s$", p))
		if err != nil {
			return false, fmt.Errorf("error compiling selector %q: %w", selector, err)
		}

		parser.regexps[selector] = r
	}

	return r.MatchString(filename), nil
}