Solve codemodel libraries loading problem in ngspice
Fixes: lp:1630675 * https://bugs.launchpad.net/kicad/+bug/1630675
This commit is contained in:
parent
d1e4399a29
commit
af3d5befa7
|
@ -26,7 +26,9 @@
|
|||
#include "ngspice.h"
|
||||
#include "spice_reporter.h"
|
||||
|
||||
#include <common.h>
|
||||
#include <common.h> // LOCALE_IO
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/dir.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -273,13 +275,111 @@ void NGSPICE::init()
|
|||
LOCALE_IO c_locale; // ngspice works correctly only with C locale
|
||||
ngSpice_Init( &cbSendChar, &cbSendStat, &cbControlledExit, NULL, NULL, &cbBGThreadRunning, this );
|
||||
|
||||
// Workaround to avoid hang ups on certain errors
|
||||
// Load a custom spinit file, to fix the problem with loading .cm files
|
||||
// Switch to the executable directory, so the relative paths are correct
|
||||
const wxStandardPaths& paths = wxStandardPaths::Get();
|
||||
wxString cwd( wxGetCwd() );
|
||||
wxFileName exeDir( paths.GetExecutablePath() );
|
||||
wxSetWorkingDirectory( exeDir.GetPath() );
|
||||
|
||||
// Find *.cm files
|
||||
string cmPath = findCmPath();
|
||||
|
||||
// __CMPATH is used in custom spinit file to point to the codemodels directory
|
||||
if( !cmPath.empty() )
|
||||
Command( "set __CMPATH=\"" + cmPath + "\"" );
|
||||
|
||||
// Possible relative locations for spinit file
|
||||
const vector<string> spiceinitPaths =
|
||||
{
|
||||
".",
|
||||
"../share/kicad",
|
||||
"../share",
|
||||
"../../share/kicad",
|
||||
"../../share"
|
||||
};
|
||||
|
||||
bool foundSpiceinit = false;
|
||||
|
||||
for( const auto& path : spiceinitPaths )
|
||||
{
|
||||
if( loadSpinit( path + "/spiceinit" ) )
|
||||
{
|
||||
foundSpiceinit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Last chance to load codemodel files, we have not found
|
||||
// spiceinit file, but we know the path to *.cm files
|
||||
if( !foundSpiceinit && !cmPath.empty() )
|
||||
loadCodemodels( cmPath );
|
||||
|
||||
// Restore the working directory
|
||||
wxSetWorkingDirectory( cwd );
|
||||
|
||||
// Workarounds to avoid hang ups on certain errors,
|
||||
// they have to be called, no matter what is in the spinit file
|
||||
Command( "unset interactive" );
|
||||
Command( "set noaskquit" );
|
||||
Command( "set nomoremode" );
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool NGSPICE::loadSpinit( const string& aFileName )
|
||||
{
|
||||
if( !wxFileName::FileExists( aFileName ) )
|
||||
return false;
|
||||
|
||||
wxTextFile file;
|
||||
|
||||
if( !file.Open( aFileName ) )
|
||||
return false;
|
||||
|
||||
for( auto cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
|
||||
Command( cmd.ToStdString() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string NGSPICE::findCmPath() const
|
||||
{
|
||||
const vector<string> cmPaths =
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
"/Applications/ngspice/lib/ngspice",
|
||||
#endif /* __APPLE__ */
|
||||
"../lib/ngspice",
|
||||
"../../lib/ngspice"
|
||||
"lib/ngspice",
|
||||
"ngspice"
|
||||
};
|
||||
|
||||
for( const auto& path : cmPaths )
|
||||
{
|
||||
if( wxFileName::DirExists( path ) )
|
||||
return path;
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
bool NGSPICE::loadCodemodels( const string& aPath )
|
||||
{
|
||||
wxArrayString cmFiles;
|
||||
size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
|
||||
|
||||
for( const auto& cm : cmFiles )
|
||||
Command( "codemodel " + cm.ToStdString() );
|
||||
|
||||
return count != 0;
|
||||
}
|
||||
|
||||
|
||||
int NGSPICE::cbSendChar( char* what, int id, void* user )
|
||||
{
|
||||
NGSPICE* sim = reinterpret_cast<NGSPICE*>( user );
|
||||
|
|
|
@ -76,6 +76,16 @@ public:
|
|||
private:
|
||||
void init();
|
||||
|
||||
///> Executes commands from a file
|
||||
bool loadSpinit( const std::string& aFileName );
|
||||
|
||||
///> Checks a few different locations for codemodel files and returns one
|
||||
///> if it exists
|
||||
std::string findCmPath() const;
|
||||
|
||||
///> Loads codemodel files from a directory
|
||||
bool loadCodemodels( const std::string& aPath );
|
||||
|
||||
// Callback functions
|
||||
static int cbSendChar( char* what, int id, void* user );
|
||||
static int cbSendStat( char* what, int id, void* user );
|
||||
|
|
Loading…
Reference in New Issue