@@ -9283,63 +9283,71 @@ int MultiReplace::getFontHeight(HWND hwnd, HFONT hFont) {
9283
9283
std::vector<int > MultiReplace::parseNumberRanges (const std::wstring& input, const std::wstring& errorMessage)
9284
9284
{
9285
9285
std::vector<int > result;
9286
- if (input.empty ()) return result; // Return empty vector if input is empty
9286
+ if (input.empty ()) return result; // nothing to parse
9287
+
9288
+ // use a hash set to filter out duplicates, but preserve insertion order in 'result'
9289
+ std::unordered_set<int > seen;
9287
9290
9288
- std::set<int > uniqueNumbers;
9289
9291
std::wistringstream stream (input);
9290
9292
std::wstring token;
9291
9293
9292
- // Lambda function to process each token (either a single number or a range "1-5")
9294
+ // helper to add a number only once, in the order encountered
9295
+ auto pushUnique = [&](int n) {
9296
+ if (seen.insert (n).second ) // if n was not already present
9297
+ result.push_back (n);
9298
+ };
9299
+
9300
+ // process each comma-separated token, either a single number or a range "start-end"
9293
9301
auto processToken = [&](const std::wstring& token) -> bool
9294
9302
{
9295
- if (token.empty ()) return true ; // Ignore empty tokens
9303
+ if (token.empty ()) return true ; // skip empty entries
9296
9304
9297
- try
9298
- {
9305
+ try {
9299
9306
size_t dashPos = token.find (L' -' );
9300
- if (dashPos != std::wstring::npos)
9301
- {
9302
- // Extract range start and end
9307
+ if (dashPos != std::wstring::npos) {
9308
+ // RANGE: parse start and end values
9303
9309
int startRange = std::stoi (token.substr (0 , dashPos));
9304
9310
int endRange = std::stoi (token.substr (dashPos + 1 ));
9305
-
9306
- // Validate range
9307
- if (startRange < 1 || endRange < startRange)
9311
+ if (startRange < 1 || endRange < 1 )
9308
9312
return false ;
9309
9313
9310
- // Insert numbers in the range
9311
- for (int i = startRange; i <= endRange; ++i)
9312
- uniqueNumbers.insert (i);
9314
+ // push each number in the range, preserving order
9315
+ if (endRange >= startRange) {
9316
+ // ascending range
9317
+ for (int i = startRange; i <= endRange; ++i)
9318
+ pushUnique (i);
9319
+ }
9320
+ else {
9321
+ // descending range
9322
+ for (int i = startRange; i >= endRange; --i)
9323
+ pushUnique (i);
9324
+ }
9313
9325
}
9314
- else
9315
- {
9316
- // Single number
9326
+ else {
9327
+ // SINGLE NUMBER
9317
9328
int number = std::stoi (token);
9318
9329
if (number < 1 )
9319
- return false ; // Invalid input
9330
+ return false ; // invalid value
9320
9331
9321
- uniqueNumbers.insert (number);
9332
+ // add the single number
9333
+ pushUnique (number);
9322
9334
}
9323
9335
}
9324
- catch (const std::exception&)
9325
- {
9326
- return false ; // Invalid input format
9336
+ catch (const std::exception&) {
9337
+ return false ; // parsing failure
9327
9338
}
9328
-
9329
9339
return true ;
9330
9340
};
9331
9341
9332
- // Split input by comma and process each token
9333
- while (std::getline (stream, token, L' ,' ))
9334
- {
9335
- if (!processToken (token))
9336
- {
9342
+ // split the input string on commas and feed each token to our processor
9343
+ while (std::getline (stream, token, L' ,' )) {
9344
+ if (!processToken (token)) {
9337
9345
showStatusMessage (errorMessage, MessageStatus::Error);
9338
- return {}; // Invalid input -> return empty vector
9346
+ return {}; // abort on invalid syntax
9339
9347
}
9340
9348
}
9341
9349
9342
- result. assign (uniqueNumbers. begin (), uniqueNumbers. end ());
9350
+ // ' result' contains the right values in the correct order
9343
9351
return result;
9344
9352
}
9345
9353
0 commit comments