forked from jfrog/jfrog-client-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parenthesesutils.go
129 lines (116 loc) · 3.14 KB
/
parenthesesutils.go
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package utils
import (
"regexp"
"sort"
"strconv"
)
var placeholderRegExp = regexp.MustCompile(`{([^}]*)}`)
// This struct represents the parentheses used for defining Placeholders (Placeholders is a feature supported by File Specs).
type Parentheses struct {
OpenIndex int
CloseIndex int
}
type ParenthesesSlice struct {
Parentheses []Parentheses
}
func NewParenthesesSlice(pattern, target string) ParenthesesSlice {
return ParenthesesSlice{findParentheses(pattern, target)}
}
func (p *ParenthesesSlice) IsPresent(index int) bool {
for _, v := range p.Parentheses {
if v.OpenIndex == index || v.CloseIndex == index {
return true
}
}
return false
}
// Return true if at least one of the {i} in 'target' has corresponding parentheses in 'pattern'.
func PlaceholdersUserd(pattern, target string) bool {
removedParenthesesTarget := RemovePlaceholderParentheses(pattern, target)
return removedParenthesesTarget != target
}
func RemovePlaceholderParentheses(pattern, target string) string {
parentheses := NewParenthesesSlice(pattern, target)
// Remove parentheses which have a corresponding placeholder.
var temp string
for i, c := range pattern {
if (c == '(' || c == ')') && parentheses.IsPresent(i) {
continue
} else {
temp = temp + string(c)
}
}
return temp
}
// Escaping Parentheses with no corresponding placeholder.
func addEscapingParentheses(pattern, target string) string {
parentheses := NewParenthesesSlice(pattern, target)
var temp string
for i, c := range pattern {
if (c == '(' || c == ')') && !parentheses.IsPresent(i) {
temp = temp + "\\" + string(c)
} else {
temp = temp + string(c)
}
}
return temp
}
func getPlaceHoldersValues(target string) []int {
var placeholderFound []int
matches := placeholderRegExp.FindAllStringSubmatch(target, -1)
for _, v := range matches {
if number, err := strconv.Atoi(v[1]); err == nil {
placeholderFound = append(placeholderFound, number)
}
}
if placeholderFound != nil {
sortNoDuplicates(&placeholderFound)
}
return placeholderFound
}
// Find the list of Parentheses in the pattern, which correspond to placeholders defined in the target.
func findParentheses(pattern, target string) []Parentheses {
// Save each parentheses index
var parentheses []Parentheses
for i, v := range pattern {
if v == '(' {
parentheses = append(parentheses, Parentheses{i, 0})
}
if v == ')' {
for j := len(parentheses) - 1; j >= 0; j-- {
if parentheses[j].CloseIndex == 0 {
parentheses[j].CloseIndex = i
break
}
}
}
}
// Remove open parentheses without closing parenthesis
var temp []Parentheses
for i := 0; i < len(parentheses); i++ {
if parentheses[i].CloseIndex != 0 {
temp = append(temp, parentheses[i])
}
}
// Filter parentheses without placeholders
var result []Parentheses
for _, v := range getPlaceHoldersValues(target) {
if len(temp) > v-1 {
result = append(result, temp[v-1])
}
}
return result
}
// Sort array and remove duplicates.
func sortNoDuplicates(arg *[]int) {
sort.Ints(*arg)
j := 0
for i := 1; i < len(*arg); i++ {
if (*arg)[j] == (*arg)[i] {
continue
}
j++
(*arg)[j] = (*arg)[i]
}
*arg = (*arg)[:j+1]
}