36 wxString outputFormat;
37 wxString outputNumber;
38 int ii =
name.Len() - 1;
41 while( ii >= 0 && !wxIsdigit(
name.GetChar( ii ) ) )
43 suffix =
name.GetChar( ii ) + suffix;
47 while( ii >= 0 && wxIsdigit(
name.GetChar( ii ) ) )
49 digits =
name.GetChar( ii ) + digits;
54 if( digits.IsEmpty() )
59 if( digits.ToLong( &number ) )
66 name.Remove( ii + 1 );
69 outputFormat.Printf( wxS(
"%%0%dld" ), dCount );
72 outputNumber.Printf( outputFormat, number );
73 name << outputNumber << suffix;
83 size_t aRightIndex )
const
88 wxString remaining = aStr;
89 std::vector<std::pair<wxString, STRING_PART_TYPE>> parts;
93 while( goodParts < ( aRightIndex + 1 ) && !remaining.IsEmpty() )
95 static const std::regex integerRegex( R
"(\d+$)" );
98 static const std::regex sameCaseAlphabetRegex( R
"(([a-z]+|[A-Z]+)$)" );
101 static const std::regex skipRegex( R
"([^a-zA-Z0-9]+$)" );
103 std::string remainingStr = remaining.ToStdString();
106 if( std::regex_search( remainingStr, match, integerRegex ) )
109 remaining = remaining.Left( remaining.Len() - match.str().size() );
112 else if( std::regex_search( remainingStr, match, sameCaseAlphabetRegex ) )
115 remaining = remaining.Left( remaining.Len() - match.str().size() );
118 else if( std::regex_search( remainingStr, match, skipRegex ) )
121 remaining = remaining.Left( remaining.Len() - match.str().size() );
131 if( goodParts < aRightIndex + 1 )
135 bool didIncrement =
incrementPart( parts.back().first, parts.back().second, aDelta );
141 wxString
result = remaining;
143 for(
auto it = parts.rbegin(); it != parts.rend(); ++it )
154 static const wxString iosqxz =
"IOSQXZ";
156 for(
const wxUniChar& c : aStr )
158 if( iosqxz.Contains( c ) )
173 bool zeroPadded = aPart.StartsWith(
'0' );
174 size_t oldLen = aPart.Len();
176 if( aPart.ToLong( &number ) )
185 aPart.Printf(
"%ld", number );
190 aPart = wxString(
"0", oldLen - aPart.Len() ) + aPart;
201 wxString upper = aPart.Upper();
202 bool wasUpper = aPart == upper;
204 static const wxString alphabetFull =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
205 static const wxString alphaNoIOSQXZ =
"ABCDEFGHJKLMNPRTUVWY";
207 const wxString& alpha =
228 newStr = newStr.Lower();
244 const int radix = aAlphabet.Length();
246 for(
size_t i = 0; i < aStr.Len(); i++ )
248 int alphaIndex = aAlphabet.Find( aStr[i] );
250 if( alphaIndex == wxNOT_FOUND )
253 if( i != aStr.Len() - 1 )
256 index += alphaIndex * pow( radix, aStr.Len() - 1 - i );
264 bool aZeroBasedNonUnitCols )
267 bool firstRound =
true;
268 const int radix = aAlphabet.Length();
272 int modN = aN % radix;
274 if( aZeroBasedNonUnitCols && !firstRound )
277 itemNum.insert( 0, 1, aAlphabet[modN] );
bool incrementPart(wxString &aPart, STRING_PART_TYPE aType, int aDelta) const
std::optional< wxString > Increment(const wxString &aStr, int aDelta, size_t aRightIndex) const
Increment the n-th part from the right of the given string.
KICOMMON_API int IndexFromAlphabetic(const wxString &aStr, const wxString &aAlphabet)
Attempt to convert a string to an integer, assuming it is an alphabetic string like "A",...
wxString KICOMMON_API AlphabeticFromIndex(size_t aN, const wxString &aAlphabet, bool aZeroBasedNonUnitCols)
Get an alphabetic string like A, B, ... Z, AA, AB, ... ZZ, AAA, ...
static bool containsIOSQXZ(const wxString &aStr)
KICOMMON_API bool IncrementString(wxString &name, int aIncrement)
Generic string incrementer.
KICOMMON_API wxString AlphabeticFromIndex(size_t aN, const wxString &aAlphabet, bool aZeroBasedNonUnitCols)
Get an alphabetic string like A, B, ... Z, AA, AB, ... ZZ, AAA, ...
KICOMMON_API int IndexFromAlphabetic(const wxString &aStr, const wxString &aAlphabet)
Attempt to convert a string to an integer, assuming it is an alphabetic string like "A",...
wxString result
Test unit parsing edge cases and error handling.