diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 31b868702c..4429bc6bee 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -247,6 +247,7 @@ set( COMMON_SRCS eda_dde.cpp eda_doc.cpp eda_pattern_match.cpp + env_paths.cpp exceptions.cpp executable_names.cpp filter_reader.cpp diff --git a/common/env_paths.cpp b/common/env_paths.cpp new file mode 100644 index 0000000000..11e959bf94 --- /dev/null +++ b/common/env_paths.cpp @@ -0,0 +1,112 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Wayne Stambaugh + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017 CERN + * @author Maciej Suminski + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include + +static bool normalizeAbsolutePaths( const wxFileName& aPathA, + const wxFileName& aPathB, + wxString* aResultPath ) +{ + wxCHECK_MSG( aPathA.IsAbsolute(), false, aPathA.GetPath() + " is not an absolute path." ); + wxCHECK_MSG( aPathB.IsAbsolute(), false, aPathB.GetPath() + " is not an absolute path." ); + + if( aPathA.GetPath() == aPathB.GetPath() ) + return true; + + if( ( aPathA.GetDirCount() > aPathB.GetDirCount() ) + || ( aPathA.HasVolume() && !aPathB.HasVolume() ) + || ( !aPathA.HasVolume() && aPathB.HasVolume() ) + || ( ( aPathA.HasVolume() && aPathB.HasVolume() ) + && ( aPathA.GetVolume() == aPathB.GetVolume() ) ) ) + return false; + + wxArrayString aDirs = aPathA.GetDirs(); + wxArrayString bDirs = aPathB.GetDirs(); + + size_t i = 0; + + while( i < aDirs.GetCount() ) + { + if( aDirs[i] != bDirs[i] ) + return false; + + i++; + } + + if( aResultPath ) + { + while( i < bDirs.GetCount() ) + { + *aResultPath += bDirs[i] + wxT( "/" ); + i++; + } + } + + return true; +} + + +wxString NormalizePath( const wxFileName& aFilePath, const ENV_VAR_MAP* aEnvVars, + const PROJECT* aProject ) +{ + wxFileName envPath; + wxString tmp, varName, normalizedFullPath; + + if( aEnvVars ) + { + for( auto& entry : *aEnvVars ) + { + // Don't bother normalizing paths that don't exist or the user cannot read. + if( !wxFileName::DirExists( entry.second.GetValue() ) + || !wxFileName::IsDirReadable( entry.second.GetValue() ) ) + continue; + + envPath.SetPath( entry.second.GetValue() ); + + if( normalizeAbsolutePaths( envPath, aFilePath, &tmp ) ) + { + varName = entry.first; + break; + } + } + } + + if( varName.IsEmpty() && aProject ) + { + envPath.SetPath( aProject->GetProjectPath() ); + + if( normalizeAbsolutePaths( envPath, aFilePath, &tmp ) ) + varName = PROJECT_VAR_NAME; + } + + if( !varName.IsEmpty() ) + { + normalizedFullPath = wxString::Format( "${%s}/", varName ); + + if( !tmp.IsEmpty() ) + normalizedFullPath += tmp; + + normalizedFullPath += aFilePath.GetFullName(); + } + + return normalizedFullPath; +} diff --git a/eeschema/dialogs/dialog_symbol_remap.cpp b/eeschema/dialogs/dialog_symbol_remap.cpp index b4ca635df8..40120627e0 100644 --- a/eeschema/dialogs/dialog_symbol_remap.cpp +++ b/eeschema/dialogs/dialog_symbol_remap.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -123,53 +124,13 @@ void DIALOG_SYMBOL_REMAP::createProjectSymbolLibTable( REPORTER& aReporter ) libNameInc++; } - wxString tmp; - wxString fullFileName; wxString pluginType = SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ); wxFileName fn = lib->GetFullFileName(); // Use environment variable substitution where possible. This is based solely // on the internal user environment variable list. Checking against all of the // system wide environment variables is probably not a good idea. - const ENV_VAR_MAP& envMap = Pgm().GetLocalEnvVariables(); - wxFileName envPath; - - for( auto& entry : envMap ) - { - // Don't bother normalizing paths that don't exist or the user cannot read. - if( !wxFileName::DirExists( entry.second.GetValue() ) - || !wxFileName::IsDirReadable( entry.second.GetValue() ) ) - continue; - - envPath.SetPath( entry.second.GetValue() ); - - if( normalizeAbsolutePaths( envPath, fn, &tmp ) ) - { - fullFileName = "${" + entry.first + "}/"; - - if( !tmp.IsEmpty() ) - fullFileName += tmp; - - fullFileName += fn.GetFullName(); - break; - } - } - - // Check the project path if no local environment variable paths where found. - if( fullFileName.IsEmpty() ) - { - envPath.SetPath( Prj().GetProjectPath() ); - - if( normalizeAbsolutePaths( envPath, fn, &tmp ) ) - { - fullFileName = wxString( "${" ) + PROJECT_VAR_NAME + wxString( "}/" ); - - if( !tmp.IsEmpty() ) - fullFileName += tmp; - - fullFileName += fn.GetFullName(); - } - } + wxString fullFileName = NormalizePath( fn, &Pgm().GetLocalEnvVariables(), &Prj() ); // Fall back to the absolute library path. if( fullFileName.IsEmpty() ) @@ -302,46 +263,3 @@ bool DIALOG_SYMBOL_REMAP::remapSymbolToLibTable( SCH_COMPONENT* aSymbol ) return false; } - - -bool DIALOG_SYMBOL_REMAP::normalizeAbsolutePaths( const wxFileName& aPathA, - const wxFileName& aPathB, - wxString* aResultPath ) -{ - wxCHECK_MSG( aPathA.IsAbsolute(), false, aPathA.GetPath() + " is not an absolute path." ); - wxCHECK_MSG( aPathB.IsAbsolute(), false, aPathB.GetPath() + " is not an absolute path." ); - - if( aPathA.GetPath() == aPathB.GetPath() ) - return true; - - if( ( aPathA.GetDirCount() > aPathB.GetDirCount() ) - || ( aPathA.HasVolume() && !aPathB.HasVolume() ) - || ( !aPathA.HasVolume() && aPathB.HasVolume() ) - || ( ( aPathA.HasVolume() && aPathB.HasVolume() ) - && ( aPathA.GetVolume() == aPathB.GetVolume() ) ) ) - return false; - - wxArrayString aDirs = aPathA.GetDirs(); - wxArrayString bDirs = aPathB.GetDirs(); - - size_t i = 0; - - while( i < aDirs.GetCount() ) - { - if( aDirs[i] != bDirs[i] ) - return false; - - i++; - } - - if( aResultPath ) - { - while( i < bDirs.GetCount() ) - { - *aResultPath += bDirs[i] + wxT( "/" ); - i++; - } - } - - return true; -} diff --git a/eeschema/dialogs/dialog_symbol_remap.h b/eeschema/dialogs/dialog_symbol_remap.h index cdb0a81719..7fe1bfe6a3 100644 --- a/eeschema/dialogs/dialog_symbol_remap.h +++ b/eeschema/dialogs/dialog_symbol_remap.h @@ -63,10 +63,6 @@ private: void remapSymbolsToLibTable( REPORTER& aReporter ); bool remapSymbolToLibTable( SCH_COMPONENT* aSymbol ); - - bool normalizeAbsolutePaths( const wxFileName& aPathA, - const wxFileName& aPathB, - wxString* aResultPath ); }; #endif // _DIALOG_SYMBOL_REMAP_H_ diff --git a/include/env_paths.h b/include/env_paths.h new file mode 100644 index 0000000000..f2eab67c09 --- /dev/null +++ b/include/env_paths.h @@ -0,0 +1,42 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Wayne Stambaugh + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017 CERN + * @author Maciej Suminski + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +///> Helper functions to substitute paths with environmental variables. + +#ifndef ENV_PATHS_H +#define ENV_PATHS_H + +#include + +/** + * Normalizes a file path to an environmental variable, if possible. + * + * @param aFilePath is the full file path (path and file name) to be normalized. + * @param aEnvVars is an optional map of environmental variables to try substition with. + * @param aProject is an optional project, to normalize the file path to the project path. + * @return Normalized full file path (path and file name) if succeeded or empty string if the + * path could not be normalized. + */ +wxString NormalizePath( const wxFileName& aFilePath, const ENV_VAR_MAP* aEnvVars, + const PROJECT* aProject ); + +#endif /* ENV_PATHS_H */