More flexible (and correct) version of CopySexprFile(),
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21738
(cherry picked from commit 666e7f5bc5)
This commit is contained in:
+12
-22
@@ -317,9 +317,8 @@ static void traverseSEXPR( SEXPR::SEXPR* aNode, const std::function<void( SEXPR:
|
||||
|
||||
|
||||
void CopySexprFile( const wxString& aSrcPath, const wxString& aDestPath,
|
||||
const std::map<std::string, wxString>& aPathTokenToExtensionMap,
|
||||
const wxString& aSrcProjectBasePath, const wxString& aSrcProjectName,
|
||||
const wxString& aNewProjectBasePath, const wxString& aNewProjectName, wxString& aErrors )
|
||||
std::function<bool( const std::string& token, wxString& value )> aCallback,
|
||||
wxString& aErrors )
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
@@ -333,27 +332,18 @@ void CopySexprFile( const wxString& aSrcPath, const wxString& aDestPath,
|
||||
{
|
||||
if( node->IsList() && node->GetNumberOfChildren() > 1 && node->GetChild( 0 )->IsSymbol() )
|
||||
{
|
||||
std::string token = node->GetChild( 0 )->GetSymbol();
|
||||
std::string token = node->GetChild( 0 )->GetSymbol();
|
||||
SEXPR::SEXPR_STRING* pathNode = dynamic_cast<SEXPR::SEXPR_STRING*>( node->GetChild( 1 ) );
|
||||
SEXPR::SEXPR_SYMBOL* symNode = dynamic_cast<SEXPR::SEXPR_SYMBOL*>( node->GetChild( 1 ) );
|
||||
wxString path;
|
||||
|
||||
if( aPathTokenToExtensionMap.contains( token ) )
|
||||
if( pathNode )
|
||||
path = pathNode->m_value;
|
||||
else if( symNode )
|
||||
path = symNode->m_value;
|
||||
|
||||
if( aCallback( token, path ) )
|
||||
{
|
||||
const wxString& extension = aPathTokenToExtensionMap.at( token );
|
||||
SEXPR::SEXPR_STRING* pathNode = dynamic_cast<SEXPR::SEXPR_STRING*>( node->GetChild( 1 ) );
|
||||
SEXPR::SEXPR_SYMBOL* symNode = dynamic_cast<SEXPR::SEXPR_SYMBOL*>( node->GetChild( 1 ) );
|
||||
wxString path;
|
||||
|
||||
if( pathNode )
|
||||
path = pathNode->m_value;
|
||||
else if( symNode )
|
||||
path = symNode->m_value;
|
||||
|
||||
if( path == aSrcProjectName + extension )
|
||||
path = aNewProjectName + extension;
|
||||
else if( path == aSrcProjectBasePath + "/" + aSrcProjectName + extension )
|
||||
path = aNewProjectBasePath + "/" + aNewProjectName + extension;
|
||||
else if( path.StartsWith( aSrcProjectBasePath ) )
|
||||
path.Replace( aSrcProjectBasePath, aNewProjectBasePath, false );
|
||||
|
||||
if( pathNode )
|
||||
pathNode->m_value = path;
|
||||
else if( symNode )
|
||||
|
||||
+38
-9
@@ -563,11 +563,18 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<std::string, wxString> aPathTokenToExtensionMap;
|
||||
aPathTokenToExtensionMap["project"] = wxEmptyString;
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
|
||||
[&]( const std::string& token, wxString& value ) -> bool
|
||||
{
|
||||
if( token == "project" && value == aProjectName )
|
||||
{
|
||||
value = aNewProjectName;
|
||||
return true;
|
||||
}
|
||||
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(), aPathTokenToExtensionMap,
|
||||
aProjectBasePath, aProjectName, aNewProjectBasePath, aNewProjectName, aErrors );
|
||||
return false;
|
||||
},
|
||||
aErrors );
|
||||
}
|
||||
else if( ext == FILEEXT::SchematicSymbolFileExtension )
|
||||
{
|
||||
@@ -591,12 +598,34 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
|
||||
if( destFile.GetName() == aProjectName )
|
||||
destFile.SetName( aNewProjectName );
|
||||
|
||||
std::map<std::string, wxString> aPathTokenToExtensionMap;
|
||||
aPathTokenToExtensionMap["source"] = wxS( ".sch" );
|
||||
aPathTokenToExtensionMap["source"] = wxS( ".kicad_sch" );
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
|
||||
[&]( const std::string& token, wxString& value ) -> bool
|
||||
{
|
||||
if( token == "source" )
|
||||
{
|
||||
for( const wxString& extension : { wxT( ".sch" ), wxT( ".kicad_sch" ) } )
|
||||
{
|
||||
if( value == aProjectName + extension )
|
||||
{
|
||||
value = aNewProjectName + extension;
|
||||
return true;
|
||||
}
|
||||
else if( value == aProjectBasePath + "/" + aProjectName + extension )
|
||||
{
|
||||
value = aNewProjectBasePath + "/" + aNewProjectName + extension;
|
||||
return true;
|
||||
}
|
||||
else if( value.StartsWith( aProjectBasePath ) )
|
||||
{
|
||||
value.Replace( aProjectBasePath, aNewProjectBasePath, false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(), aPathTokenToExtensionMap,
|
||||
aProjectBasePath, aProjectName, aNewProjectBasePath, aNewProjectName, aErrors );
|
||||
return false;
|
||||
},
|
||||
aErrors );
|
||||
}
|
||||
else if( destFile.GetName() == FILEEXT::SymbolLibraryTableFileName )
|
||||
{
|
||||
|
||||
+3
-6
@@ -61,15 +61,12 @@ KICOMMON_API void KiCopyFile( const wxString& aSrcPath, const wxString& aDestPat
|
||||
/**
|
||||
* @param aSrcPath is the full filename of the source.
|
||||
* @param[in] aDestPath is the full filename of the target.
|
||||
* @param[in] aPathTokenToExtensionMap a set of sexpr tokens which might be followed by a path to aSrcPath
|
||||
* which needs to be updated to aDestPath. The value of the map is the
|
||||
* extension any said path should have.
|
||||
* @param[in] aCallback a facility to allow modification of the values of particular tokens. Normally used
|
||||
* to update paths in the copied document.
|
||||
* @param[out] aErrors a wxString to *append* any errors to.
|
||||
*/
|
||||
KICOMMON_API void CopySexprFile( const wxString& aSrcPath, const wxString& aDestPath,
|
||||
const std::map<std::string, wxString>& aPathTokenToExtensionMap,
|
||||
const wxString& aSrcProjectBasePath, const wxString& aSrcProjectName,
|
||||
const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
|
||||
std::function<bool( const std::string& token, wxString& value )> aCallback,
|
||||
wxString& aErrors );
|
||||
|
||||
/**
|
||||
|
||||
+27
-6
@@ -520,13 +520,34 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr
|
||||
if( destFile.GetName() == aSrcProjectName )
|
||||
destFile.SetName( aNewProjectName );
|
||||
|
||||
std::map<std::string, wxString> aPathTokenToExtensionMap;
|
||||
aPathTokenToExtensionMap["sheetfile"] = wxS( ".sch" );
|
||||
aPathTokenToExtensionMap["sheetfile"] = wxS( ".kicad_sch" );
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
|
||||
[&]( const std::string& token, wxString& value )
|
||||
{
|
||||
if( token == "sheetfile" )
|
||||
{
|
||||
for( const wxString& extension : { wxT( ".sch" ), wxT( ".kicad_sch" ) } )
|
||||
{
|
||||
if( value == aSrcProjectName + extension )
|
||||
{
|
||||
value = aNewProjectName + extension;
|
||||
return true;
|
||||
}
|
||||
else if( value == aProjectBasePath + "/" + aSrcProjectName + extension )
|
||||
{
|
||||
value = aNewProjectBasePath + "/" + aNewProjectName + extension;
|
||||
return true;
|
||||
}
|
||||
else if( value.StartsWith( aProjectBasePath ) )
|
||||
{
|
||||
value.Replace( aProjectBasePath, aNewProjectBasePath, false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CopySexprFile( aSrcFilePath, destFile.GetFullPath(), aPathTokenToExtensionMap,
|
||||
aProjectBasePath, aSrcProjectName,
|
||||
aNewProjectBasePath, aNewProjectName, aErrors );
|
||||
return false;
|
||||
},
|
||||
aErrors );
|
||||
}
|
||||
else if( ext == FILEEXT::LegacyPcbFileExtension )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user