Altium: handle '.var' concatenated special strings

The ST MB2046 reference board, for example, has all the
assembly-layer ref-des text in the format '.R42' even though
they're not concatenated.

Enable the existing but commented-out text.
This commit is contained in:
John Beard 2025-08-16 05:50:44 +08:00
parent 85dcdd5cb2
commit c5d5a718aa
2 changed files with 61 additions and 14 deletions

View File

@ -164,24 +164,71 @@ wxString AltiumPcbSpecialStringsToKiCadStrings( const wxString&
if( aString.IsEmpty() )
return aString;
// Convert a 'special string' to a KiCad variable, substituting any override.
const auto getVariable = [&]( const wxString& aSpecialString )
{
wxString str = aSpecialString;
str.UpperCase(); // matching is implemented using upper case strings
auto it = aOverrides.find( str );
if( it != aOverrides.end() )
str = it->second;
return wxString::Format( wxT( "${%s}" ), str );
};
// special case: string starts with dot -> whole string is special string
if( aString.at( 0 ) == '.' )
{
wxString specialString = aString.substr( 1 );
specialString.UpperCase(); // matching is implemented using upper case strings
auto overrideIt = aOverrides.find( specialString );
if( overrideIt != aOverrides.end() )
specialString = overrideIt->second;
return wxString::Format( wxT( "${%s}" ), specialString );
return getVariable( specialString );
}
// TODO: implement Concatenated special strings using apostrophe "'".
// Strings can also have one or more special strings using apostrophes to
// delineate them, e.g. "foo '.bar' '.baz' = '.qux' quux"
return aString;
// In the common case, the string is a simple string with no special strings,
// so bail out early.
if( !aString.Contains( "'." ) )
{
return aString;
}
wxString stringCopy = aString;
// Given a position of a dot, check if it is a special string variable
// and replace it with a variable name if defined.
const auto tryReplacement = [&]( wxString& aStr, unsigned aDotPos )
{
// Check that the dot has an apostrophe before it, if not, it's just a dot
if( aDotPos == 0 || aStr.at( aDotPos - 1 ) != '\'' )
return;
// Scan forward for the next apostrophe
size_t apostrophePos = aStr.find( '\'', aDotPos + 1 );
// Didn't find it
if( apostrophePos == wxString::npos )
return;
// Extract the special string
wxString specialString = aStr.substr( aDotPos + 1, apostrophePos - aDotPos - 1 );
wxString replacement = getVariable( specialString );
aStr.replace( aDotPos - 1, apostrophePos - aDotPos + 2, replacement );
};
// Work backwards through the string checking any dots
// (so we don't mess up the positions of the dots as we replace them)
for( size_t pos = stringCopy.size() - 1; pos > 0; --pos )
{
if( stringCopy[pos] == '.' )
{
tryReplacement( stringCopy, pos );
}
}
return stringCopy;
}

View File

@ -178,11 +178,11 @@ static const std::vector<SPECIAL_STRINGS_TO_KICAD> pcb_special_string_to_kicad_p
{ ".A", "${C}", { { "A", "C" } } },
{ ".A_B", "${A_B}", {} },
// Concatenated special strings
/*{ "'.A'", "${A}", {} },
{ "'.A'", "${A}", {} },
{ "'.A''.B'", "${A}${B}", {} },
{ "'.A''.B'", "${C}${B}", { { "A", "C" } } },
{ "'.A''.B'", "${C}${D}", { { "A", "C" }, { "B", "D" } } },
{ "A='.A', B='.B'", "A=${A}, B=${B}", {} },*/
{ "'.A''.B'", "${CC}${D}", { { "A", "CC" }, { "B", "D" } } },
{ "A='.A', B='.B'", "A=${A}, B=${B}", {} },
// Case-insensitive special strings
{ ".A", "${C}", { { "A", "C" } } },
{ ".a", "${C}", { { "A", "C" } } },