-
Notifications
You must be signed in to change notification settings - Fork 149
/
Copy pathparenthesesutils.go
148 lines (132 loc) · 4.05 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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(slice []Parentheses) ParenthesesSlice {
return ParenthesesSlice{Parentheses: slice}
}
func CreateParenthesesSlice(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 IsPlaceholdersUsed(pattern, target string) bool {
removedParenthesesTarget := RemovePlaceholderParentheses(pattern, target)
return removedParenthesesTarget != target
}
func RemovePlaceholderParentheses(pattern, target string) string {
parentheses := CreateParenthesesSlice(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 += string(c)
}
}
return temp
}
// addEscapingParentheses escapes parentheses with no corresponding placeholder.
func addEscapingParentheses(pattern, target string) string {
return AddEscapingParentheses(pattern, target, "")
}
// AddEscapingParentheses escapes parentheses with no corresponding placeholder.
// pattern - the pattern in which the parentheses are escaped.
// target - target parameter containing placeholders.
// targetPathInArchive - The target archive path containing placeholders (relevant only for upload commands).
func AddEscapingParentheses(pattern, target, targetPathInArchive string) string {
parentheses := CreateParenthesesSlice(pattern, target)
archiveParentheses := CreateParenthesesSlice(pattern, targetPathInArchive)
var temp string
for i, c := range pattern {
if (c == '(' || c == ')') && !parentheses.IsPresent(i) && !archiveParentheses.IsPresent(i) {
temp = temp + "\\" + string(c)
} else {
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 {
parentheses := getAllParentheses(pattern)
// Filter out parentheses without placeholders
var result []Parentheses
for _, placeHolderValueIndex := range getPlaceHoldersValues(target) {
if len(parentheses) > placeHolderValueIndex-1 {
result = append(result, parentheses[placeHolderValueIndex-1])
}
}
return result
}
// Find the list of Parentheses in the pattern.
func getAllParentheses(pattern string) []Parentheses {
// Save each parentheses index
var parentheses []Parentheses
for i, char := range pattern {
if char == '(' {
parentheses = append(parentheses, Parentheses{i, 0})
}
if char == ')' {
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])
}
}
return temp
}
// 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]
}