cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.3.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/parser/read.go

140lines · modecode

1package parser
2
3import (
4 "bufio"
5 "errors"
6 "io"
7 "strings"
8)
9
10type skipMode int
11
12const (
13 skipNone skipMode = iota
14 skipNextLine
15 skipBegin
16 skipEnd
17 skipCurrentLine
18 skipFile
19)
20
21func removeRedundantSpaces(line string) string {
22 return strings.Join(strings.Fields(line), " ")
23}
24
25func emptyLine(line string) (emptied string) {
26 preComment := strings.TrimSuffix(line, "\n")
27 var comment string
28 if commentStart := strings.IndexRune(line, '#'); commentStart >= 0 {
29 comment = preComment[commentStart:]
30 preComment = preComment[:commentStart]
31 }
32
33 emptied = strings.Repeat(" ", len(preComment)) + comment
34
35 if strings.HasSuffix(line, "\n") {
36 emptied += "\n"
37 }
38
39 return
40}
41
42func hasComment(line, comment string) bool {
43 if !strings.Contains(line, "#") {
44 return false
45 }
46
47 elems := strings.Split(strings.TrimSuffix(line, "\n"), "#")
48 lastComment := elems[len(elems)-1]
49 parts := strings.SplitN(removeRedundantSpaces(lastComment), " ", 2)
50 if len(parts) < 2 {
51 return false
52 }
53
54 return parts[0] == "pint" && parts[1] == comment
55}
56
57func parseSkipComment(line string) (skipMode, bool) {
58 if hasComment(line, "ignore/file") {
59 return skipFile, true
60 } else if hasComment(line, "ignore/line") {
61 return skipCurrentLine, true
62 } else if hasComment(line, "ignore/next-line") {
63 return skipNextLine, true
64 } else if hasComment(line, "ignore/begin") {
65 return skipBegin, true
66 } else if hasComment(line, "ignore/end") {
67 return skipEnd, true
68 }
69 return skipNone, false
70}
71
72func ReadContent(r io.Reader) (out []byte, err error) {
73 reader := bufio.NewReader(r)
74 var line string
75 var found bool
76 var skip skipMode
77
78 var skipNext bool
79 var autoReset bool
80 var skipAll bool
81 var inBegin bool
82 for {
83 line, err = reader.ReadString('\n')
84 if err != nil && !errors.Is(err, io.EOF) {
85 break
86 }
87
88 if skipAll {
89 out = append(out, []byte(emptyLine(line))...)
90 } else {
91 skip, found = parseSkipComment(line)
92 if found {
93 switch skip {
94 case skipFile:
95 out = append(out, []byte(emptyLine(line))...)
96 skipNext = true
97 autoReset = false
98 skipAll = true
99 case skipCurrentLine:
100 out = append(out, []byte(emptyLine(line))...)
101 if !inBegin {
102 skipNext = false
103 autoReset = true
104 }
105 case skipNextLine:
106 out = append(out, []byte(line)...)
107 skipNext = true
108 autoReset = true
109 case skipBegin:
110 out = append(out, []byte(line)...)
111 skipNext = true
112 autoReset = false
113 inBegin = true
114 case skipEnd:
115 out = append(out, []byte(line)...)
116 skipNext = false
117 autoReset = true
118 inBegin = false
119 }
120 } else if skipNext {
121 out = append(out, []byte(emptyLine(line))...)
122 if autoReset {
123 skipNext = false
124 }
125 } else {
126 out = append(out, []byte(line)...)
127 }
128 }
129
130 if err != nil {
131 break
132 }
133 }
134
135 if !errors.Is(err, io.EOF) {
136 return nil, err
137 }
138
139 return out, nil
140}
141