Write all variables to temp config file and have Kicad2Step use that.

Fixes https://gitlab.com/kicad/code/kicad/issues/7670
This commit is contained in:
Jeff Young 2021-06-14 16:53:54 +01:00
parent 44978f00e3
commit 2c1da70181
6 changed files with 34 additions and 263 deletions

View File

@ -234,7 +234,7 @@ bool FILENAME_RESOLVER::UpdatePathList( const std::vector< SEARCH_PATH >& aPathL
for( const SEARCH_PATH& path : aPathList )
addPath( path );
return writePathList();
return WritePathList( m_configDir, RESOLVER_CONFIG, false );
}
@ -594,15 +594,16 @@ bool FILENAME_RESOLVER::readPathList()
cfgFile.close();
if( vnum < CFGFILE_VERSION )
writePathList();
WritePathList( m_configDir, RESOLVER_CONFIG, false );
return( m_paths.size() != nitems );
}
bool FILENAME_RESOLVER::writePathList()
bool FILENAME_RESOLVER::WritePathList( const wxString& aDir, const wxString& aFilename,
bool aWriteFullList )
{
if( m_configDir.empty() )
if( aDir.empty() )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
@ -614,14 +615,19 @@ bool FILENAME_RESOLVER::writePathList()
return false;
}
std::list<SEARCH_PATH>::const_iterator sPL = m_paths.begin();
// skip all ${ENV_VAR} alias names
std::list< SEARCH_PATH >::const_iterator sPL = m_paths.begin();
if( !aWriteFullList )
{
while( sPL != m_paths.end()
&& ( sPL->m_Alias.StartsWith( "${" ) || sPL->m_Alias.StartsWith( "$(" ) ) )
{
++sPL;
}
}
while( sPL != m_paths.end() &&
( sPL->m_Alias.StartsWith( "${" ) || sPL->m_Alias.StartsWith( "$(" ) ) )
++sPL;
wxFileName cfgpath( m_configDir, RESOLVER_CONFIG );
wxFileName cfgpath( aDir, aFilename );
wxString cfgname = cfgpath.GetFullPath();
std::ofstream cfgFile;

View File

@ -87,7 +87,13 @@ public:
* Clear the current path list and substitutes the given path list and update the path
* configuration file on success.
*/
bool UpdatePathList( const std::vector< SEARCH_PATH >& aPathList );
bool UpdatePathList( const std::vector<SEARCH_PATH>& aPathList );
/**
* Write the current path list to a config file.
* @param aWriteFullList indicates whether env vars should also be written out or not
*/
bool WritePathList( const wxString& aDir, const wxString& aFilename, bool aWriteFullList );
/**
* Determines the full path of the given file name.
@ -114,7 +120,7 @@ public:
*
* @return pointer to the internal path list.
*/
const std::list< SEARCH_PATH >* GetPaths() const;
const std::list<SEARCH_PATH>* GetPaths() const;
/**
* Return true if the given name contains an alias and populates the string \a anAlias
@ -162,14 +168,6 @@ private:
*/
bool readPathList( void );
/**
* Write the current path list to a configuration file.
*
* @return true if the path list was not empty and was successfully written to the
* configuration file.
*/
bool writePathList( void );
/**
* Check the ${ENV_VAR} component of a path and adds it to the resolver's path list if
* it is not yet in the list.

View File

@ -39,7 +39,7 @@
#include <project/project_file.h> // LAST_PATH_TYPE
#include <reporter.h>
#include <widgets/text_ctrl_eval.h>
#include <filename_resolver.h>
class DIALOG_EXPORT_STEP: public DIALOG_EXPORT_STEP_BASE
{
@ -326,6 +326,10 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
return;
}
FILENAME_RESOLVER* fnResolver = m_parent->Prj().Get3DFilenameResolver();
fnResolver->WritePathList( wxStandardPaths::Get().GetTempDir(), "ExportPaths.cfg", true );
DIALOG_EXPORT_STEP::STEP_ORG_OPT orgOpt = GetOriginOption();
double xOrg = 0.0;
double yOrg = 0.0;

View File

@ -35,13 +35,14 @@
#include <wx/thread.h>
#include <wx/utils.h>
#include <wx/msgdlg.h>
#include <wx/stdpaths.h>
#include "kicadpcb.h"
#include "3d_resolver.h"
// configuration file version
#define CFGFILE_VERSION 1
#define S3D_RESOLVER_CONFIG "3Dresolver.cfg"
#define S3D_RESOLVER_CONFIG "ExportPaths.cfg"
// flag bits used to track different one-off messages to users
#define ERRFLG_ALIAS (1)
@ -62,57 +63,6 @@ S3D_RESOLVER::S3D_RESOLVER()
bool S3D_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
{
if( aConfigDir.empty() )
return false;
wxFileName cfgdir( aConfigDir, "" );
cfgdir.Normalize();
if( false == cfgdir.DirExists() )
return false;
wxFileName kcom( cfgdir.GetPath(), "" );
kcom.RemoveLastDir();
kcom.SetFullName( "kicad_common" );
wxUniChar psep = wxFileName::GetPathSeparator();
if( kcom.FileExists() )
{
wxConfigBase* cfg = new wxFileConfig( "", "", kcom.GetFullPath() );
wxString subgroup( "EnvironmentVariables" );
wxString entry;
wxString val;
long idx = 0;
if( cfg->HasGroup( subgroup ) )
{
cfg->SetPath( subgroup );
while( cfg->GetNextEntry( entry, idx ) )
{
val = cfg->Read( entry, "" );
if( val.Last() == psep )
val = val.substr( 0, val.length() -1 );
// only add the EnvVar if it is not currently defined by the shell
wxString subst = "${";
subst.append( entry );
subst.append( "}" );
wxString exvar = wxExpandEnvVars( subst );
if( exvar == subst )
m_EnvVars.insert(std::pair< wxString, wxString >(entry, val));
entry.clear();
val.clear();
}
}
delete cfg;
}
m_ConfigDir = cfgdir.GetPath();
createPathList();
return true;
@ -309,22 +259,6 @@ bool S3D_RESOLVER::createPathList( void )
}
bool S3D_RESOLVER::UpdatePathList( std::vector< SEARCH_PATH >& aPathList )
{
wxUniChar envMarker( '$' );
while( !m_Paths.empty() && envMarker != *m_Paths.back().m_Alias.rbegin() )
m_Paths.pop_back();
size_t nI = aPathList.size();
for( size_t i = 0; i < nI; ++i )
addPath( aPathList[i] );
return writePathList();
}
wxString S3D_RESOLVER::ResolvePath( const wxString& aFileName )
{
std::lock_guard<std::mutex> lock( mutex3D_resolver );
@ -596,17 +530,7 @@ bool S3D_RESOLVER::addPath( const SEARCH_PATH& aPath )
bool S3D_RESOLVER::readPathList( void )
{
if( m_ConfigDir.empty() )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = "3D configuration directory is unknown";
ostr << " * " << errmsg.ToUTF8();
wxLogTrace( MASK_3D_RESOLVER, "%s\n", ostr.str().c_str() );
return false;
}
wxFileName cfgpath( m_ConfigDir, S3D_RESOLVER_CONFIG );
wxFileName cfgpath( wxStandardPaths::Get().GetTempDir(), S3D_RESOLVER_CONFIG );
cfgpath.Normalize();
wxString cfgname = cfgpath.GetFullPath();
@ -690,9 +614,6 @@ bool S3D_RESOLVER::readPathList( void )
cfgFile.close();
if( vnum < CFGFILE_VERSION )
writePathList();
if( m_Paths.size() != nitems )
return true;
@ -700,101 +621,6 @@ bool S3D_RESOLVER::readPathList( void )
}
bool S3D_RESOLVER::writePathList( void )
{
if( m_ConfigDir.empty() )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = _( "3D configuration directory is unknown" );
ostr << " * " << errmsg.ToUTF8();
wxLogTrace( MASK_3D_RESOLVER, "%s\n", ostr.str().c_str() );
wxMessageBox( errmsg, _( "Write 3D search path list" ) );
return false;
}
// skip all ${ENV_VAR} alias names
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
while( sPL != ePL && ( sPL->m_Alias.StartsWith( "${" )
|| sPL->m_Alias.StartsWith( "$(" ) ) )
++sPL;
wxFileName cfgpath( m_ConfigDir, S3D_RESOLVER_CONFIG );
wxString cfgname = cfgpath.GetFullPath();
std::ofstream cfgFile;
if( sPL == ePL )
{
wxMessageDialog md( NULL,
_( "3D search path list is empty;\ncontinue to write empty file?" ),
_( "Write 3D search path list" ), wxYES_NO );
if( md.ShowModal() == wxID_YES )
{
cfgFile.open( cfgname.ToUTF8(), std::ios_base::trunc );
if( !cfgFile.is_open() )
{
wxMessageBox( _( "Could not open configuration file" ),
_( "Write 3D search path list" ) );
return false;
}
cfgFile << "#V" << CFGFILE_VERSION << "\n";
cfgFile.close();
return true;
}
return false;
}
cfgFile.open( cfgname.ToUTF8(), std::ios_base::trunc );
if( !cfgFile.is_open() )
{
std::ostringstream ostr;
ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
wxString errmsg = _( "Could not open configuration file" );
ostr << " * " << errmsg.ToUTF8() << " '" << cfgname.ToUTF8() << "'";
wxLogTrace( MASK_3D_RESOLVER, "%s\n", ostr.str().c_str() );
wxMessageBox( errmsg, _( "Write 3D search path list" ) );
return false;
}
cfgFile << "#V" << CFGFILE_VERSION << "\n";
std::string tstr;
while( sPL != ePL )
{
tstr = sPL->m_Alias.ToUTF8();
cfgFile << "\"" << tstr.size() << ":" << tstr << "\",";
tstr = sPL->m_Pathvar.ToUTF8();
cfgFile << "\"" << tstr.size() << ":" << tstr << "\",";
tstr = sPL->m_Description.ToUTF8();
cfgFile << "\"" << tstr.size() << ":" << tstr << "\"\n";
++sPL;
}
bool bad = cfgFile.bad();
cfgFile.close();
if( bad )
{
wxMessageBox( _( "Problems writing configuration file" ),
_( "Write 3D search path list" ) );
return false;
}
return true;
}
void S3D_RESOLVER::checkEnvVarPath( const wxString& aPath )
{
bool useParen = false;

View File

@ -140,15 +140,6 @@ private:
*/
bool readPathList( void );
/**
* Function writePathList
* writes the current path list to a configuration file
*
* @return true if the path list was not empty and was
* successfully written to the configuration file
*/
bool writePathList( void );
/**
* Function checkEnvVarPath
* checks the ${ENV_VAR} component of a path and adds
@ -184,13 +175,6 @@ public:
bool SetProjectDir( const wxString& aProjDir, bool* flgChanged = NULL );
wxString GetProjectDir( void );
/**
* Function UpdatePathList
* clears the current path list and substitutes the given path
* list, updating the path configuration file on success.
*/
bool UpdatePathList( std::vector< SEARCH_PATH >& aPathList );
/**
* Function ResolvePath
* determines the full path of the given file name. In the future

View File

@ -34,64 +34,17 @@
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <wx/textctrl.h>
#include <wx/utils.h>
#include <wx/wxcrtvararg.h>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <wx/wxcrtvararg.h>
/*
* GetKicadConfigPath() is taken from KiCad's common.cpp source:
* Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers
*/
static wxString GetKicadConfigPath()
{
wxFileName cfgpath;
// From the wxWidgets wxStandardPaths::GetUserConfigDir() help:
// Unix: ~ (the home directory)
// Windows: "C:\Documents and Settings\username\Application Data"
// Mac: ~/Library/Preferences
cfgpath.AssignDir( wxStandardPaths::Get().GetUserConfigDir() );
#if !defined( __WINDOWS__ ) && !defined( __WXMAC__ )
wxString envstr;
if( !wxGetEnv( "XDG_CONFIG_HOME", &envstr ) || envstr.IsEmpty() )
{
// XDG_CONFIG_HOME is not set, so use the fallback
cfgpath.AppendDir( ".config" );
}
else
{
// Override the assignment above with XDG_CONFIG_HOME
cfgpath.AssignDir( envstr );
}
#endif
cfgpath.AppendDir( "kicad" );
if( !cfgpath.DirExists() )
{
cfgpath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
}
return cfgpath.GetPath();
}
KICADPCB::KICADPCB()
{
wxFileName cfgdir( GetKicadConfigPath(), "" );
cfgdir.AppendDir( "3d" );
m_resolver.Set3DConfigDir( cfgdir.GetPath() );
m_resolver.Set3DConfigDir( "" );
m_thickness = 1.6;
m_pcb_model = nullptr;
m_minDistance = MIN_DISTANCE;