40#define CFGFILE_VERSION 1
43#define ERRFLG_ALIAS (1)
44#define ERRFLG_RELPATH (2)
45#define ERRFLG_ENVPATH (4)
47#define MASK_3D_RESOLVER "3D_RESOLVER"
62 if( aConfigDir.empty() )
69 if( !cfgdir.DirExists() )
90 if( !projdir.DirExists() )
101 al.
m_Alias = wxS(
"${KIPRJMOD}" );
126 std::ostringstream ostr;
127 ostr << __FILE__ <<
": " << __FUNCTION__ <<
": " << __LINE__ <<
"\n";
128 ostr <<
" * [INFO] changed project dir to ";
129 ostr <<
m_paths.front().m_Pathexp.ToUTF8();
167 lpath.
m_Alias = wxS(
"${KIPRJMOD}" );
172 wxUniChar psep = fndummy.GetPathSeparator();
173 std::list< wxString > epaths;
177 for(
const wxString& currPath : epaths )
179 wxString currPathVarFormat = currPath;
180 currPathVarFormat.Prepend( wxS(
"${" ) );
181 currPathVarFormat.Append( wxS(
"}" ) );
185 if( pathVal.empty() )
191 fndummy.Assign( pathVal,
"" );
206 lpath.
m_Alias = currPathVarFormat;
216 std::list< SEARCH_PATH >::const_iterator sPL =
m_paths.begin();
220 wxLogTrace(
MASK_3D_RESOLVER, wxS(
" + %s : '%s'\n" ), (*sPL).m_Alias.GetData(),
221 (*sPL).m_Pathexp.GetData() );
232 wxUniChar envMarker(
'$' );
234 while( !
m_paths.empty() && envMarker != *
m_paths.back().m_Alias.rbegin() )
248 if( aFileName.empty() )
249 return wxEmptyString;
255 wxString tname = aFileName;
263 wxFileName tmpFN( tname );
267 if( tmpFN.FileExists() )
270 tname = tmpFN.GetFullPath();
274 if( aFileName.StartsWith( wxS(
"${" ) ) || aFileName.StartsWith( wxS(
"$(" ) ) )
282 if( aFileName.StartsWith(
"${" ) || aFileName.StartsWith(
"$(" ) )
287 wxString errmsg =
"[3D File Resolver] No such path; ensure the environment var is defined";
288 errmsg.append(
"\n" );
289 errmsg.append( tname );
290 errmsg.append(
"\n" );
294 return wxEmptyString;
306 if( !
m_paths.begin()->m_Pathexp.empty() && !tname.StartsWith(
":" ) )
308 tmpFN.Assign(
m_paths.begin()->m_Pathexp,
"" );
309 wxString fullPath = tmpFN.GetPathWithSep() + tname;
313 if( wxFileName::FileExists( fullPath ) )
315 tmpFN.Assign( fullPath );
317 tname = tmpFN.GetFullPath();
324 if( !aWorkingPath.IsEmpty() && !tname.StartsWith(
":" ) )
326 wxString tmp = aWorkingPath;
327 tmp.Append( tmpFN.GetPathSeparator() );
331 if( tmpFN.MakeAbsolute() && tmpFN.FileExists() )
333 tname = tmpFN.GetFullPath();
339 if( !tname.StartsWith( wxS(
":" ) ) )
342 wxString fullPath( wxString::Format( wxS(
"${%s}" ),
344 fullPath.Append( fpath.GetPathSeparator() );
345 fullPath.Append( tname );
347 fpath.Assign( fullPath );
351 tname = fpath.GetFullPath();
368 wxString errmsg =
"[3D File Resolver] No such path";
369 errmsg.append( wxS(
"\n" ) );
370 errmsg.append( tname );
371 errmsg.append( wxS(
"\n" ) );
375 return wxEmptyString;
381 if(
path.m_Alias.StartsWith( wxS(
"${" ) ) ||
path.m_Alias.StartsWith( wxS(
"$(" ) ) )
384 if(
path.m_Alias == alias && !
path.m_Pathexp.empty() )
386 wxFileName fpath( wxFileName::DirName(
path.m_Pathexp ) );
387 wxString fullPath = fpath.GetPathWithSep() + relpath;
391 if( wxFileName::FileExists( fullPath ) )
395 wxFileName tmp( fullPath );
398 tname = tmp.GetFullPath();
408 wxString errmsg =
"[3D File Resolver] No such path; ensure the path alias is defined";
409 errmsg.append(
"\n" );
410 errmsg.append( tname.substr( 1 ) );
411 errmsg.append(
"\n" );
415 return wxEmptyString;
429 while( tpath.
m_Pathvar.EndsWith( wxT(
"\\" ) ) )
440 if( !
path.DirExists() )
442 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
447 || aPath.
m_Pathvar == wxS(
"${KISYS3DMOD}" ) || aPath.
m_Pathvar == wxS(
"$(KISYS3DMOD)" ) )
453 wxString msg =
_(
"The given path does not exist" );
454 msg.append( wxT(
"\n" ) );
466 while( tpath.
m_Pathexp.EndsWith( wxT(
"\\" ) ) )
474 std::list< SEARCH_PATH >::iterator sPL =
m_paths.begin();
475 std::list< SEARCH_PATH >::iterator ePL =
m_paths.end();
479 if( tpath.
m_Alias == sPL->m_Alias )
481 wxString msg =
_(
"Alias: " );
483 msg.append( wxT(
"\n" ) );
484 msg.append(
_(
"This path:" ) + wxS(
" " ) );
486 msg.append( wxT(
"\n" ) );
487 msg.append(
_(
"Existing path:" ) + wxS(
" " ) );
488 msg.append( sPL->m_Pathvar );
503 bool useParen =
false;
505 if( aPath.StartsWith( wxS(
"$(" ) ) )
507 else if( !aPath.StartsWith( wxS(
"${" ) ) )
513 pEnd = aPath.find( wxS(
")" ) );
515 pEnd = aPath.find( wxS(
"}" ) );
517 if( pEnd == wxString::npos )
520 wxString envar = aPath.substr( 0, pEnd + 1 );
529 if( sPL->m_Alias == envar )
532 if( !sPL->m_Alias.StartsWith( wxS(
"${" ) ) )
543 wxUniChar psep = tmpFN.GetPathSeparator();
546 if( !tmpFN.DirExists() )
563 wxString fname = aFullPathName;
570 std::list< SEARCH_PATH >::const_iterator sL =
m_paths.begin();
577 if( sL->m_Pathexp.empty() )
586 if( sL->m_Alias.StartsWith( wxS(
"${" ) ) || sL->m_Alias.StartsWith( wxS(
"$(" ) ) )
596 fpath.Assign( tpath, wxT(
"" ) );
600 fpath.Assign( sL->m_Pathexp, wxT(
"" ) );
603 wxString fps = fpath.GetPathWithSep();
606 idx = fname.find( fps );
610 fname = fname.substr( fps.size() );
614 fname.Replace( wxT(
"\\" ), wxT(
"/" ) );
617 if( sL->m_Alias.StartsWith( wxS(
"${" ) ) || sL->m_Alias.StartsWith( wxS(
"$(" ) ) )
621 tname.Append( wxS(
"/" ) );
622 tname.append( fname );
628 tname.append( sL->m_Alias );
629 tname.append( wxS(
"}/" ) );
630 tname.append( fname );
644 fname.Replace( wxT(
"\\" ), wxT(
"/" ) );
659 wxString& anAlias, wxString& aRelPath )
const
664 size_t searchStart = 0;
666 if( aFileName.StartsWith( wxT(
":" ) ) )
669 size_t tagpos = aFileName.find( wxT(
":" ), searchStart );
671 if( tagpos == wxString::npos || tagpos == searchStart )
674 if( tagpos + 1 >= aFileName.length() )
677 anAlias = aFileName.substr( searchStart, tagpos - searchStart );
678 aRelPath = aFileName.substr( tagpos + 1 );
693 if( aFileName.empty() )
696 wxString filename = aFileName;
698 size_t aliasStart = aFileName.StartsWith(
':' ) ? 1 : 0;
699 size_t aliasEnd = aFileName.find(
':', aliasStart );
703 filename.Replace( wxT(
"/" ), wxT(
"\\" ) );
706 if( aliasEnd != wxString::npos )
708 size_t pos1 = filename.find( wxT(
":\\" ) );
710 if( pos1 != wxString::npos && ( pos1 != aliasEnd || pos1 != 1 ) )
714 if( pos1 != wxString::npos )
715 aliasEnd = wxString::npos;
718 filename.Replace( wxT(
"\\" ), wxT(
"/" ) );
722 if( aliasEnd == aFileName.length() -1 )
725 if( aliasEnd != wxString::npos )
728 if( aliasEnd == aliasStart )
731 lpath = filename.substr( aliasStart, aliasEnd );
734 if( wxString::npos != lpath.find_first_of( wxT(
"{}[]()%~<>\"='`;:.,&?/\\|$" ) ) )
738 lpath = aFileName.substr( aliasEnd + 1 );
746 aliasEnd = wxString::npos;
748 if( aFileName.StartsWith( wxS(
"${" ) ) )
749 aliasEnd = aFileName.find(
'}' );
750 else if( aFileName.StartsWith( wxS(
"$(" ) ) )
751 aliasEnd = aFileName.find(
')' );
753 if( aliasEnd != wxString::npos )
754 lpath = aFileName.substr( aliasEnd + 1 );
762 wxString lpath_no_sep = lpath;
764 lpath_no_sep.Replace(
"/",
" " );
765 lpath_no_sep.Replace(
"\\",
" " );
768 if( lpath_no_sep.Length() > 1 && lpath_no_sep[1] ==
':' )
769 lpath_no_sep[1] =
' ';
772 if( wxString::npos != lpath_no_sep.find_first_of( wxFileName::GetForbiddenChars() ) )
786 bool hasKisys3D =
false;
797 if( mS->first == wxS(
"KICAD_PTEMPLATES" )
798 || mS->first.Matches( wxS(
"KICAD*_FOOTPRINT_DIR") ) )
804 if( wxString::npos != mS->second.GetValue().find( wxS(
"://" ) ) )
811 paths.push_back( mS->first );
813 if( mS->first.Matches( wxS(
"KICAD*_3DMODEL_DIR") ) )
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...
const std::list< SEARCH_PATH > * GetPaths() const
Return a pointer to the internal path list; the items in:load.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath)
Determines the full path of the given file name.
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
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().