Skip to content

Commit 5939c09

Browse files
committed
Matching tag stack should be dynamically sized
Fixes yet another regression: #10
1 parent e0194fd commit 5939c09

1 file changed

Lines changed: 30 additions & 30 deletions

File tree

src/TagFinder.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ enum SearchDirection { dirBackward = -1, dirNone, dirForward, dirUnknown };
1818

1919
struct TagPair {
2020
std::string name;
21-
SciTextRange *tag;
21+
std::shared_ptr<SciTextRange> tag;
2222
};
2323

24-
SciTextRange *extractTagName(std::string &tagName, bool &isOpenTag, bool &isEndTag, Sci_Position tagPos = -1);
24+
std::shared_ptr<SciTextRange> extractTagName(
25+
std::string &tagName, bool &isOpenTag, bool &isEndTag, Sci_Position tagPos = -1);
2526
void selectTags(SciTextRange *startTag, SciTextRange *endTag = nullptr);
2627

2728
/* https://html.spec.whatwg.org/multipage/syntax.html#void-elements */
@@ -56,28 +57,29 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
5657
SearchDirection searchDirection = dirUnknown;
5758
SciActiveDocument doc = plugin.editor().activeDocument();
5859
SciTextRange match{ doc };
59-
SciTextRange *currentTag = nullptr;
60-
TagPair matchingTags[2]{ { "", currentTag } };
60+
std::shared_ptr<SciTextRange> currentTag = nullptr;
61+
std::vector<TagPair> matchingTags;
6162
// --------------------------------------------------------------------------------------
6263
auto classifyTag = [&matchingTags, &currentTag, &match, &tagName, &searchDirection, &dispose](
6364
SearchDirection processDirection, char prefix) {
6465
tagName = prefix + tagName;
6566

66-
if (!matchingTags->tag) {
67-
*matchingTags = TagPair{ tagName, currentTag };
67+
if (matchingTags.empty()) {
68+
matchingTags.push_back(TagPair{ tagName, currentTag });
6869
dispose = false;
6970
searchDirection = processDirection;
70-
} else if (sameText(tagName.substr(1), matchingTags->name.substr(1))) {
71-
if (searchDirection != processDirection && !matchingTags[1].tag) {
72-
match = *currentTag;
73-
matchingTags[1] = TagPair{ tagName, currentTag };
74-
dispose = false;
75-
} else if (matchingTags[1].tag) {
76-
delete matchingTags[1].tag;
77-
matchingTags[1].tag = nullptr;
78-
} else if (searchDirection == processDirection) {
79-
matchingTags[1] = TagPair{ tagName, currentTag };
71+
} else if (sameText(tagName.substr(1), matchingTags.front().name.substr(1))) {
72+
if (searchDirection == processDirection) {
73+
matchingTags.push_back(TagPair{ tagName, currentTag });
8074
dispose = false;
75+
} else {
76+
if (matchingTags.size() > 1) {
77+
matchingTags.pop_back();
78+
} else {
79+
match = *currentTag;
80+
matchingTags.push_back(TagPair{ tagName, currentTag });
81+
dispose = false;
82+
}
8183
}
8284
}
8385
};
@@ -113,9 +115,9 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
113115

114116
if (isStartTag && isEndTag) {
115117
tagName = '*' + tagName;
116-
if (!matchingTags->tag) {
118+
if (matchingTags.empty()) {
117119
match = *currentTag;
118-
*matchingTags = TagPair{ tagName, currentTag };
120+
matchingTags.push_back(TagPair{ tagName, currentTag });
119121
dispose = false;
120122
searchDirection = dirNone;
121123
}
@@ -169,14 +171,13 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
169171
}
170172

171173
if (dispose) {
172-
delete currentTag;
173174
currentTag = nullptr;
174175
}
175176
} while (nextTag && !match);
176177

177178
if (match) {
178-
if (matchingTags[1].tag) {
179-
currentTag = matchingTags->tag;
179+
if (matchingTags.size() == 2) {
180+
currentTag = matchingTags.front().tag;
180181

181182
// Matching tag may be hidden by a fold
182183
doc.sendMessage(SCI_FOLDLINE, doc.sendMessage(SCI_LINEFROMPOSITION, match.startPos()),
@@ -212,7 +213,7 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
212213
}
213214
selRange.select();
214215
} else if (wantSelection) {
215-
selectTags(currentTag, &match);
216+
selectTags(currentTag.get(), &match);
216217
} else {
217218
match.select();
218219
}
@@ -222,8 +223,8 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
222223
else
223224
match.select();
224225
}
225-
} else if (matchingTags->tag) { // A tag with no match
226-
currentTag = matchingTags->tag;
226+
} else if (!matchingTags.empty()) { // A tag with no match
227+
currentTag = matchingTags.front().tag;
227228

228229
if (wantSelection)
229230
currentTag->select();
@@ -232,18 +233,17 @@ void TagFinder::findMatchingTag(SelectionOptions options) {
232233
::MessageBeep(MB_ICONWARNING);
233234
}
234235

235-
if (matchingTags->tag)
236-
delete matchingTags->tag;
237-
if (matchingTags[1].tag)
238-
delete matchingTags[1].tag;
236+
while (!matchingTags.empty())
237+
matchingTags.pop_back();
239238

240239
} catch (...) {
241240
}
242241
}
243242

244243
/////////////////////////////////////////////////////////////////////////////////////////
245244
namespace {
246-
SciTextRange *extractTagName(std::string &tagName, bool &isOpenTag, bool &isEndTag, Sci_Position tagPos) {
245+
std::shared_ptr<SciTextRange> extractTagName(
246+
std::string &tagName, bool &isOpenTag, bool &isEndTag, Sci_Position tagPos) {
247247
SciActiveDocument doc = plugin.editor().activeDocument();
248248
bool closureFound = false;
249249
isOpenTag = true;
@@ -256,7 +256,7 @@ SciTextRange *extractTagName(std::string &tagName, bool &isOpenTag, bool &isEndT
256256
: doc.currentPosition();
257257
}
258258

259-
SciTextRange *result = new SciTextRange(doc);
259+
std::shared_ptr<SciTextRange> result = std::make_shared<SciTextRange>(doc);
260260
doc.find(L"<", *result, 0, tagPos, 0);
261261
if (result->length() == 0) {
262262
doc.find(L"<", *result, 0, tagPos);

0 commit comments

Comments
 (0)