37 wxString outputFormat;
38 wxString outputNumber;
39 int ii =
name.Len() - 1;
42 while( ii >= 0 && !wxIsdigit(
name.GetChar( ii ) ) )
44 suffix =
name.GetChar( ii ) + suffix;
48 while( ii >= 0 && wxIsdigit(
name.GetChar( ii ) ) )
50 digits =
name.GetChar( ii ) + digits;
55 if( digits.IsEmpty() )
60 if( digits.ToLong( &number ) )
67 name.Remove( ii + 1 );
70 outputFormat.Printf( wxS(
"%%0%dld" ), dCount );
73 outputNumber.Printf( outputFormat, number );
74 name << outputNumber << suffix;
84 size_t aRightIndex )
const
91 std::string remaining = aStr.utf8_string();
92 std::vector<std::pair<std::string, STRING_PART_TYPE>> parts;
97 while( goodParts <= aRightIndex && !remaining.empty() )
99 static const std::regex integerRegex( R
"(\d+$)" );
102 static const std::regex sameCaseAlphabetRegex( R
"(([a-z]+|[A-Z]+)$)" );
105 static const std::regex skipRegex( R
"([^a-zA-Z0-9]+$)" );
109 if( std::regex_search( remaining, match, integerRegex ) )
114 else if( std::regex_search( remaining, match, sameCaseAlphabetRegex ) )
119 else if( std::regex_search( remaining, match, skipRegex ) )
129 remaining.erase( remaining.size() - match.str().size() );
133 if( goodParts <= aRightIndex )
137 wxString part = wxString::FromUTF8( parts.back().first );
142 parts.back().first = part.utf8_string();
145 std::string
result = remaining;
147 for(
auto it = parts.rbegin(); it != parts.rend(); ++it )
152 return wxString::FromUTF8(
result );
158 static const wxString iosqxz =
"IOSQXZ";
160 for(
const wxUniChar& c : aStr )
162 if( iosqxz.Contains( c ) )
177 bool zeroPadded = aPart.StartsWith(
'0' );
178 size_t oldLen = aPart.Len();
180 if( aPart.ToLong( &number ) )
184 if( aDelta > 0 && number > std::numeric_limits<long>::max() - aDelta )
194 aPart.Printf(
"%ld", number );
198 if( zeroPadded && aPart.Len() < oldLen )
199 aPart.Prepend( wxString(
'0', oldLen - aPart.Len() ) );
209 wxString upper = aPart.Upper();
210 bool wasUpper = aPart == upper;
212 static const wxString alphabetFull =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
213 static const wxString alphaNoIOSQXZ =
"ABCDEFGHJKLMNPRTUVWY";
215 const wxString& alpha =
229 const long long nextIndex =
static_cast<long long>(
index ) + aDelta;
231 if( nextIndex < 0 || nextIndex > std::numeric_limits<int>::max() )
237 newStr = newStr.Lower();
253 const int radix = aAlphabet.Length();
255 for(
size_t i = 0; i < aStr.Len(); i++ )
257 int alphaIndex = aAlphabet.Find( aStr[i] );
259 if( alphaIndex == wxNOT_FOUND )
262 if( i != aStr.Len() - 1 )
265 index += alphaIndex * pow( radix, aStr.Len() - 1 - i );
273 bool aZeroBasedNonUnitCols )
276 bool firstRound =
true;
277 const int radix = aAlphabet.Length();
281 int modN = aN % radix;
283 if( aZeroBasedNonUnitCols && !firstRound )
286 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.