42#define CFGFILE_VERSION 1
45#define ERRFLG_ALIAS (1)
46#define ERRFLG_RELPATH (2)
47#define ERRFLG_ENVPATH (4)
49#define MASK_3D_RESOLVER "3D_RESOLVER"
64 if( aConfigDir.empty() )
71 if( !cfgdir.DirExists() )
92 if( !projdir.DirExists() )
103 al.
m_Alias = wxS(
"${KIPRJMOD}" );
128 std::ostringstream ostr;
129 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
130 ostr <<
" * [INFO] changed project dir to ";
131 ostr <<
m_paths.front().m_Pathexp.ToUTF8();
169 lpath.
m_Alias = wxS(
"${KIPRJMOD}" );
174 wxUniChar psep = fndummy.GetPathSeparator();
175 std::list< wxString > epaths;
179 for(
const wxString& currPath : epaths )
181 wxString currPathVarFormat = currPath;
182 currPathVarFormat.Prepend( wxS(
"${" ) );
183 currPathVarFormat.Append( wxS(
"}" ) );
187 if( pathVal.empty() )
193 fndummy.Assign( pathVal,
"" );
208 lpath.
m_Alias = currPathVarFormat;
218 std::list< SEARCH_PATH >::const_iterator sPL =
m_paths.begin();
222 wxLogTrace(
MASK_3D_RESOLVER, wxS(
" + %s : '%s'\n" ), (*sPL).m_Alias.GetData(),
223 (*sPL).m_Pathexp.GetData() );
234 wxUniChar envMarker(
'$' );
236 while( !
m_paths.empty() && envMarker != *
m_paths.back().m_Alias.rbegin() )
251 if( aFileName.empty() )
252 return wxEmptyString;
258 wxString tname = aFileName;
271 wxLogTrace( wxT(
"KICAD_EMBED" ),
272 wxT(
"No EMBEDDED_FILES object provided for kicad_embed URI" ) );
273 return wxEmptyString;
276 wxString
path = tname.Mid( 14 );
279 if( !temp_file.IsOk() )
281 wxLogTrace( wxT(
"KICAD_EMBED" ),
282 wxT(
"Failed to get temp file '%s' for kicad_embed URI" ),
path );
283 return wxEmptyString;
286 wxLogTrace( wxT(
"KICAD_EMBED" ), wxT(
"Opening embedded file '%s' as '%s'" ),
287 tname, temp_file.GetFullPath() );
289 return temp_file.GetFullPath();
292 wxFileName tmpFN( tname );
296 if( tmpFN.FileExists() )
299 tname = tmpFN.GetFullPath();
303 if( aFileName.StartsWith( wxS(
"${" ) ) || aFileName.StartsWith( wxS(
"$(" ) ) )
311 if( aFileName.StartsWith(
"${" ) || aFileName.StartsWith(
"$(" ) )
316 wxString errmsg =
"[3D File Resolver] No such path; ensure the environment var is defined";
317 errmsg.append(
"\n" );
318 errmsg.append( tname );
319 errmsg.append(
"\n" );
323 return wxEmptyString;
335 if( !
m_paths.begin()->m_Pathexp.empty() && !tname.StartsWith(
":" ) )
337 tmpFN.Assign(
m_paths.begin()->m_Pathexp,
"" );
338 wxString fullPath = tmpFN.GetPathWithSep() + tname;
342 if( wxFileName::FileExists( fullPath ) )
344 tmpFN.Assign( fullPath );
346 tname = tmpFN.GetFullPath();
353 if( !aWorkingPath.IsEmpty() && !tname.StartsWith(
":" ) )
355 wxString tmp = aWorkingPath;
356 tmp.Append( tmpFN.GetPathSeparator() );
360 if( tmpFN.MakeAbsolute() && tmpFN.FileExists() )
362 tname = tmpFN.GetFullPath();
368 if( !tname.StartsWith( wxS(
":" ) ) )
371 wxString fullPath( wxString::Format( wxS(
"${%s}" ),
373 fullPath.Append( fpath.GetPathSeparator() );
374 fullPath.Append( tname );
376 fpath.Assign( fullPath );
380 tname = fpath.GetFullPath();
397 wxString errmsg =
"[3D File Resolver] No such path";
398 errmsg.append( wxS(
"\n" ) );
399 errmsg.append( tname );
400 errmsg.append( wxS(
"\n" ) );
404 return wxEmptyString;
410 if(
path.m_Alias.StartsWith( wxS(
"${" ) ) ||
path.m_Alias.StartsWith( wxS(
"$(" ) ) )
413 if(
path.m_Alias == alias && !
path.m_Pathexp.empty() )
415 wxFileName fpath( wxFileName::DirName(
path.m_Pathexp ) );
416 wxString fullPath = fpath.GetPathWithSep() + relpath;
420 if( wxFileName::FileExists( fullPath ) )
424 wxFileName tmp( fullPath );
427 tname = tmp.GetFullPath();
437 wxString errmsg =
"[3D File Resolver] No such path; ensure the path alias is defined";
438 errmsg.append(
"\n" );
439 errmsg.append( tname.substr( 1 ) );
440 errmsg.append(
"\n" );
444 return wxEmptyString;
458 while( tpath.
m_Pathvar.EndsWith( wxT(
"\\" ) ) )
469 if( !
path.DirExists() )
471 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
476 || aPath.
m_Pathvar == wxS(
"${KISYS3DMOD}" ) || aPath.
m_Pathvar == wxS(
"$(KISYS3DMOD)" ) )
482 wxString msg =
_(
"The given path does not exist" );
483 msg.append( wxT(
"\n" ) );
495 while( tpath.
m_Pathexp.EndsWith( wxT(
"\\" ) ) )
503 std::list< SEARCH_PATH >::iterator sPL =
m_paths.begin();
504 std::list< SEARCH_PATH >::iterator ePL =
m_paths.end();
508 if( tpath.
m_Alias == sPL->m_Alias )
510 wxString msg =
_(
"Alias: " );
512 msg.append( wxT(
"\n" ) );
513 msg.append(
_(
"This path:" ) + wxS(
" " ) );
515 msg.append( wxT(
"\n" ) );
516 msg.append(
_(
"Existing path:" ) + wxS(
" " ) );
517 msg.append( sPL->m_Pathvar );
532 bool useParen =
false;
534 if( aPath.StartsWith( wxS(
"$(" ) ) )
536 else if( !aPath.StartsWith( wxS(
"${" ) ) )
542 pEnd = aPath.find( wxS(
")" ) );
544 pEnd = aPath.find( wxS(
"}" ) );
546 if( pEnd == wxString::npos )
549 wxString envar = aPath.substr( 0, pEnd + 1 );
558 if( sPL->m_Alias == envar )
561 if( !sPL->m_Alias.StartsWith( wxS(
"${" ) ) )
572 wxUniChar psep = tmpFN.GetPathSeparator();
575 if( !tmpFN.DirExists() )
592 wxString fname = aFullPathName;
599 std::list< SEARCH_PATH >::const_iterator sL =
m_paths.begin();
606 if( sL->m_Pathexp.empty() )
615 if( sL->m_Alias.StartsWith( wxS(
"${" ) ) || sL->m_Alias.StartsWith( wxS(
"$(" ) ) )
625 fpath.Assign( tpath, wxT(
"" ) );
629 fpath.Assign( sL->m_Pathexp, wxT(
"" ) );
632 wxString fps = fpath.GetPathWithSep();
635 idx = fname.find( fps );
639 fname = fname.substr( fps.size() );
643 fname.Replace( wxT(
"\\" ), wxT(
"/" ) );
646 if( sL->m_Alias.StartsWith( wxS(
"${" ) ) || sL->m_Alias.StartsWith( wxS(
"$(" ) ) )
650 tname.Append( wxS(
"/" ) );
651 tname.append( fname );
657 tname.append( sL->m_Alias );
658 tname.append( wxS(
"}/" ) );
659 tname.append( fname );
673 fname.Replace( wxT(
"\\" ), wxT(
"/" ) );
688 wxString& anAlias, wxString& aRelPath )
const
693 size_t searchStart = 0;
695 if( aFileName.StartsWith( wxT(
":" ) ) )
698 size_t tagpos = aFileName.find( wxT(
":" ), searchStart );
700 if( tagpos == wxString::npos || tagpos == searchStart )
703 if( tagpos + 1 >= aFileName.length() )
706 anAlias = aFileName.substr( searchStart, tagpos - searchStart );
707 aRelPath = aFileName.substr( tagpos + 1 );
724 if( aFileName.empty() )
727 if( aFileName.StartsWith( wxT(
"file://" ) )
730 size_t prefixLength = aFileName.StartsWith( wxT(
"file://" ) ) ? 7 : 14;
731 if( aFileName.length() > prefixLength && aFileName[prefixLength] !=
'/' )
737 wxString filename = aFileName;
739 size_t aliasStart = aFileName.StartsWith(
':' ) ? 1 : 0;
740 size_t aliasEnd = aFileName.find(
':', aliasStart );
744 filename.Replace( wxT(
"/" ), wxT(
"\\" ) );
747 if( aliasEnd != wxString::npos )
749 size_t pos1 = filename.find( wxT(
":\\" ) );
751 if( pos1 != wxString::npos && ( pos1 != aliasEnd || pos1 != 1 ) )
755 if( pos1 != wxString::npos )
756 aliasEnd = wxString::npos;
759 filename.Replace( wxT(
"\\" ), wxT(
"/" ) );
763 if( aliasEnd == aFileName.length() -1 )
766 if( aliasEnd != wxString::npos )
769 if( aliasEnd == aliasStart )
772 lpath = filename.substr( aliasStart, aliasEnd );
775 if( wxString::npos != lpath.find_first_of( wxT(
"{}[]()%~<>\"='`;:.,&?/\\|$" ) ) )
779 lpath = aFileName.substr( aliasEnd + 1 );
787 aliasEnd = wxString::npos;
789 if( aFileName.StartsWith( wxS(
"${" ) ) )
790 aliasEnd = aFileName.find(
'}' );
791 else if( aFileName.StartsWith( wxS(
"$(" ) ) )
792 aliasEnd = aFileName.find(
')' );
794 if( aliasEnd != wxString::npos )
795 lpath = aFileName.substr( aliasEnd + 1 );
803 wxString lpath_no_sep = lpath;
805 lpath_no_sep.Replace(
"/",
" " );
806 lpath_no_sep.Replace(
"\\",
" " );
809 if( lpath_no_sep.Length() > 1 && lpath_no_sep[1] ==
':' )
810 lpath_no_sep[1] =
' ';
813 if( wxString::npos != lpath_no_sep.find_first_of( wxFileName::GetForbiddenChars() ) )
827 bool hasKisys3D =
false;
838 if( mS->first == wxS(
"KICAD_PTEMPLATES" )
839 || mS->first.Matches( wxS(
"KICAD*_FOOTPRINT_DIR") ) )
845 if( wxString::npos != mS->second.GetValue().find( wxS(
"://" ) ) )
852 paths.push_back( mS->first );
854 if( mS->first.Matches( wxS(
"KICAD*_3DMODEL_DIR") ) )
wxFileName GetTemporaryFileName(const wxString &aName) const
bool ValidateFileName(const wxString &aFileName, bool &hasAlias) const
Returns true if the given path is a valid aliased relative path.
bool createPathList(void)
Build the path list using available information such as KICAD7_3DMODEL_DIR and the 3d_path_list confi...
bool addPath(const SEARCH_PATH &aPath)
Check that a path is valid and adds it to the search list.
wxString GetProjectDir() const
bool GetKicadPaths(std::list< wxString > &paths) const
Return a list of path environment variables local to KiCad.
bool Set3DConfigDir(const wxString &aConfigDir)
Set the user's configuration directory for 3D models.
void checkEnvVarPath(const wxString &aPath)
Check the ${ENV_VAR} component of a path and adds it to the resolver's path list if it is not yet in ...
std::list< SEARCH_PATH > m_paths
bool SetProject(PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
bool SplitAlias(const wxString &aFileName, wxString &anAlias, wxString &aRelPath) const
Return true if the given name contains an alias and populates the string anAlias with the alias and a...
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, const EMBEDDED_FILES *aFiles)
Determines the full path of the given file name.
const std::list< SEARCH_PATH > * GetPaths() const
Return a pointer to the internal path list; the items in:load.
bool UpdatePathList(const std::vector< SEARCH_PATH > &aPathList)
Clear the current path list and substitutes the given path list and update the path configuration fil...
wxString ShortenPath(const wxString &aFullPathName)
Produce a relative path based on the existing search directories or returns the same path if the path...
Container for data for KiCad programs.
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Container for project specific data.
virtual const wxString GetProjectPath() const
Return the full path of the project.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
Functions related to environment variables, including help functions.
static std::mutex mutex_resolver
static const std::string KiCadUriPrefix
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
std::map< wxString, ENV_VAR_ITEM >::const_iterator ENV_VAR_MAP_CITER
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Constructs a versioned environment variable based on this KiCad major version.
wxLogTrace helper definitions.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().