Add sim_lib callback to resolve embeded libs
Also teach parser to look for include directives in libraries We get KiCad variable resolution in include pathnames for free. Fixes https://gitlab.com/kicad/code/kicad/issues/13083
This commit is contained in:
parent
cdcf875ec0
commit
10a3d57193
|
@ -90,8 +90,39 @@ SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath, REPORTER* aR
|
||||||
// May throw an exception.
|
// May throw an exception.
|
||||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||||
|
|
||||||
// May throw an exception.
|
std::function<std::string(const std::string&, const std::string&)> f2 =
|
||||||
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( path, aReporter );
|
[&]( const std::string& aLibPath, const std::string& aRelativeLib ) -> std::string
|
||||||
|
{
|
||||||
|
wxFileName testPath( aLibPath );
|
||||||
|
wxString fullPath( aLibPath );
|
||||||
|
|
||||||
|
if( !testPath.IsAbsolute() && !aRelativeLib.empty() )
|
||||||
|
{
|
||||||
|
wxString relLib( aRelativeLib );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
relLib = ResolveLibraryPath( relLib, m_project );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{}
|
||||||
|
|
||||||
|
wxFileName fn( relLib );
|
||||||
|
|
||||||
|
fullPath = testPath.GetAbsolutePath( fn.GetPath( true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fullPath = ResolveLibraryPath( fullPath, m_project );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{}
|
||||||
|
|
||||||
|
return fullPath.ToStdString();
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( path, aReporter, &f2 );
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
m_libraries[path] = std::move( library );
|
m_libraries[path] = std::move( library );
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
#include <sim/sim_library_spice.h>
|
#include <sim/sim_library_spice.h>
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( const wxString& aFilePath, REPORTER* aReporter )
|
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( const wxString &aFilePath, REPORTER *aReporter,
|
||||||
|
std::function<std::string( const std::string&, const std::string& )> *aResolver )
|
||||||
{
|
{
|
||||||
std::unique_ptr<SIM_LIBRARY> library;
|
std::unique_ptr<SIM_LIBRARY> library;
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( const wxString& aFilePath, REP
|
||||||
library = std::make_unique<SIM_LIBRARY_SPICE>();
|
library = std::make_unique<SIM_LIBRARY_SPICE>();
|
||||||
|
|
||||||
library->m_reporter = aReporter;
|
library->m_reporter = aReporter;
|
||||||
|
library->m_pathResolver = aResolver;
|
||||||
library->ReadFile( std::string( aFilePath.c_str() ) );
|
library->ReadFile( std::string( aFilePath.c_str() ) );
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,8 @@ public:
|
||||||
* @return The library loaded in a newly constructed object.
|
* @return The library loaded in a newly constructed object.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<SIM_LIBRARY> Create( const wxString& aFilePath,
|
static std::unique_ptr<SIM_LIBRARY> Create( const wxString& aFilePath,
|
||||||
REPORTER* aReporter = nullptr );
|
REPORTER* aReporter = nullptr,
|
||||||
|
std::function<std::string(const std::string&, const std::string&)>* aResolver = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read library from a source file. Must be in the format appropriate to the subclass, e.g.
|
* Read library from a source file. Must be in the format appropriate to the subclass, e.g.
|
||||||
|
@ -82,6 +83,8 @@ protected:
|
||||||
std::vector<std::string> m_modelNames;
|
std::vector<std::string> m_modelNames;
|
||||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||||
|
|
||||||
|
std::function<std::string( const std::string&, const std::string& )>* m_pathResolver;
|
||||||
|
|
||||||
std::string m_filePath;
|
std::string m_filePath;
|
||||||
|
|
||||||
REPORTER* m_reporter = nullptr;
|
REPORTER* m_reporter = nullptr;
|
||||||
|
|
|
@ -47,24 +47,25 @@ namespace SIM_LIBRARY_SPICE_PARSER
|
||||||
template <> struct librarySelector<modelUnit> : std::true_type {};
|
template <> struct librarySelector<modelUnit> : std::true_type {};
|
||||||
template <> struct librarySelector<modelName> : std::true_type {};
|
template <> struct librarySelector<modelName> : std::true_type {};
|
||||||
|
|
||||||
|
template <> struct librarySelector<dotInclude> : std::true_type {};
|
||||||
|
template <> struct librarySelector<dotIncludePathWithoutQuotes> : std::true_type {};
|
||||||
|
template <> struct librarySelector<dotIncludePathWithoutApostrophes> : std::true_type {};
|
||||||
|
template <> struct librarySelector<dotIncludePath> : std::true_type {};
|
||||||
|
|
||||||
// For debugging.
|
// For debugging.
|
||||||
template <> struct librarySelector<unknownLine> : std::true_type {};
|
template <> struct librarySelector<unknownLine> : std::true_type {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void SPICE_LIBRARY_PARSER::ReadFile( const std::string& aFilePath )
|
void SPICE_LIBRARY_PARSER::readElement( const std::string &aFilePath )
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
tao::pegtl::file_input in( aFilePath );
|
tao::pegtl::file_input in( aFilePath );
|
||||||
auto root = tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
|
std::unique_ptr<tao::pegtl::parse_tree::node> root =
|
||||||
|
tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
|
||||||
SIM_LIBRARY_SPICE_PARSER::librarySelector,
|
SIM_LIBRARY_SPICE_PARSER::librarySelector,
|
||||||
tao::pegtl::nothing,
|
tao::pegtl::nothing,
|
||||||
SIM_LIBRARY_SPICE_PARSER::control>( in );
|
SIM_LIBRARY_SPICE_PARSER::control>( in );
|
||||||
|
|
||||||
m_library.m_models.clear();
|
|
||||||
m_library.m_modelNames.clear();
|
|
||||||
|
|
||||||
for( const auto& node : root->children )
|
for( const auto& node : root->children )
|
||||||
{
|
{
|
||||||
if( node->is_type<SIM_LIBRARY_SPICE_PARSER::modelUnit>() )
|
if( node->is_type<SIM_LIBRARY_SPICE_PARSER::modelUnit>() )
|
||||||
|
@ -79,6 +80,15 @@ void SPICE_LIBRARY_PARSER::ReadFile( const std::string& aFilePath )
|
||||||
DisplayErrorMessage( nullptr, e.What() );
|
DisplayErrorMessage( nullptr, e.What() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::dotInclude>() )
|
||||||
|
{
|
||||||
|
std::string lib = node->children.at( 0 )->string();
|
||||||
|
|
||||||
|
if( m_library.m_pathResolver )
|
||||||
|
lib = ( *m_library.m_pathResolver )( lib, aFilePath );
|
||||||
|
|
||||||
|
readElement( lib );
|
||||||
|
}
|
||||||
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::unknownLine>() )
|
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::unknownLine>() )
|
||||||
{
|
{
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
|
@ -88,6 +98,17 @@ void SPICE_LIBRARY_PARSER::ReadFile( const std::string& aFilePath )
|
||||||
wxFAIL_MSG( "Unhandled parse tree node" );
|
wxFAIL_MSG( "Unhandled parse tree node" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SPICE_LIBRARY_PARSER::ReadFile( const std::string& aFilePath )
|
||||||
|
{
|
||||||
|
m_library.m_models.clear();
|
||||||
|
m_library.m_modelNames.clear();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
readElement( aFilePath );
|
||||||
}
|
}
|
||||||
catch( const std::filesystem::filesystem_error& e )
|
catch( const std::filesystem::filesystem_error& e )
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,11 +29,10 @@
|
||||||
|
|
||||||
class SIM_LIBRARY_SPICE;
|
class SIM_LIBRARY_SPICE;
|
||||||
|
|
||||||
|
|
||||||
class SPICE_LIBRARY_PARSER
|
class SPICE_LIBRARY_PARSER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SPICE_LIBRARY_PARSER( SIM_LIBRARY_SPICE& aLibrary ) :
|
SPICE_LIBRARY_PARSER( SIM_LIBRARY_SPICE &aLibrary ) :
|
||||||
m_library( aLibrary )
|
m_library( aLibrary )
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
@ -42,6 +41,9 @@ public:
|
||||||
|
|
||||||
virtual void ReadFile( const std::string& aFilePath );
|
virtual void ReadFile( const std::string& aFilePath );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void readElement( const std::string& aFilePath );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SIM_LIBRARY_SPICE& m_library;
|
SIM_LIBRARY_SPICE& m_library;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue