mirror of https://github.com/KLayout/klayout.git
Fixed #21 (Autorun(-early) doesn't seem to run when lym files are inside a package)
This commit is contained in:
parent
54a373572f
commit
1bb662b9ed
|
|
@ -773,7 +773,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
|
|||
}
|
||||
|
||||
// Actually load the macros and/or establish the search path
|
||||
mc->finish (! m_no_macros);
|
||||
mc->finish ();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static lay::MacroController::MacroCategory drc_cat ()
|
|||
}
|
||||
|
||||
void
|
||||
MacroController::finish (bool load)
|
||||
MacroController::finish ()
|
||||
{
|
||||
// Scan built-in macros
|
||||
// These macros are always taken, even if there are no macros requested (they are required to
|
||||
|
|
@ -96,10 +96,14 @@ MacroController::finish (bool load)
|
|||
m_macro_categories.push_back (python_cat ());
|
||||
m_macro_categories.push_back (drc_cat ());
|
||||
|
||||
// scans the macros from techs and packages (this will allow autorun-early on them)
|
||||
// and updates m_external_paths
|
||||
sync_macro_sources ();
|
||||
|
||||
// Scan for macros and set interpreter path
|
||||
for (std::vector <InternalPathDescriptor>::const_iterator p = m_internal_paths.begin (); p != m_internal_paths.end (); ++p) {
|
||||
|
||||
if (load) {
|
||||
if (! m_no_implicit_macros) {
|
||||
|
||||
for (size_t c = 0; c < m_macro_categories.size (); ++c) {
|
||||
|
||||
|
|
@ -137,6 +141,19 @@ MacroController::finish (bool load)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Scan for macros in packages and techs
|
||||
|
||||
if (! m_no_implicit_macros) {
|
||||
for (std::vector <ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the interpreter path to packages too
|
||||
|
||||
sync_package_paths ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -377,10 +394,106 @@ void
|
|||
MacroController::sync_implicit_macros (bool ask_before_autorun)
|
||||
{
|
||||
if (m_no_implicit_macros) {
|
||||
sync_package_paths ();
|
||||
return;
|
||||
}
|
||||
|
||||
sync_macro_sources ();
|
||||
sync_package_paths ();
|
||||
|
||||
} else {
|
||||
|
||||
// determine the paths currently in use
|
||||
std::map<std::string, const ExternalPathDescriptor *> prev_folders_by_path;
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
|
||||
}
|
||||
|
||||
// gets the external paths (tech, packages) into m_external_paths
|
||||
sync_macro_sources ();
|
||||
|
||||
// delete macro collections which are no longer required or update description
|
||||
|
||||
std::vector<lym::MacroCollection *> folders_to_delete;
|
||||
|
||||
// determine the paths that will be in use
|
||||
std::map<std::string, const ExternalPathDescriptor *> new_folders_by_path;
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
|
||||
}
|
||||
|
||||
lym::MacroCollection *root = &lym::MacroCollection::root ();
|
||||
|
||||
for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) {
|
||||
if (m->second->virtual_mode () == lym::MacroCollection::TechFolder ||
|
||||
m->second->virtual_mode () == lym::MacroCollection::SaltFolder) {
|
||||
std::map<std::string, const ExternalPathDescriptor *>::const_iterator u = new_folders_by_path.find (m->second->path ());
|
||||
if (u == new_folders_by_path.end ()) {
|
||||
// no longer used
|
||||
folders_to_delete.push_back (m->second);
|
||||
} else {
|
||||
m->second->set_description (u->second->description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<lym::MacroCollection *>::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) {
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use";
|
||||
}
|
||||
root->erase (*m);
|
||||
}
|
||||
|
||||
// sync the search paths with the packages
|
||||
sync_package_paths ();
|
||||
|
||||
// add new folders
|
||||
std::vector<lym::MacroCollection *> new_folders;
|
||||
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
|
||||
if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'";
|
||||
}
|
||||
|
||||
// Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in
|
||||
// a non-tech context.
|
||||
// In that case, the add_folder method will return 0.
|
||||
|
||||
// TODO: is it wise to make this writeable?
|
||||
lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
|
||||
if (mc) {
|
||||
mc->set_virtual_mode (p->type);
|
||||
new_folders.push_back (mc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
// This prevents the message dialog below to issue deferred methods
|
||||
tl::NoDeferredMethods silent;
|
||||
|
||||
bool has_autorun = false;
|
||||
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) {
|
||||
has_autorun = (*m)->has_autorun ();
|
||||
}
|
||||
|
||||
if (has_autorun) {
|
||||
if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) {
|
||||
(*m)->autorun ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroController::sync_macro_sources ()
|
||||
{
|
||||
std::vector<ExternalPathDescriptor> external_paths;
|
||||
|
||||
// Add additional places where the technologies define some macros
|
||||
|
|
@ -480,96 +593,8 @@ MacroController::sync_implicit_macros (bool ask_before_autorun)
|
|||
|
||||
}
|
||||
|
||||
// delete macro collections which are no longer required or update description
|
||||
|
||||
std::vector<lym::MacroCollection *> folders_to_delete;
|
||||
|
||||
// determine the paths that will be in use
|
||||
std::map<std::string, const ExternalPathDescriptor *> new_folders_by_path;
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = external_paths.begin (); p != external_paths.end (); ++p) {
|
||||
new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
|
||||
}
|
||||
|
||||
// determine the paths currently in use
|
||||
std::map<std::string, const ExternalPathDescriptor *> prev_folders_by_path;
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
|
||||
}
|
||||
|
||||
lym::MacroCollection *root = &lym::MacroCollection::root ();
|
||||
|
||||
for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) {
|
||||
if (m->second->virtual_mode () == lym::MacroCollection::TechFolder ||
|
||||
m->second->virtual_mode () == lym::MacroCollection::SaltFolder) {
|
||||
std::map<std::string, const ExternalPathDescriptor *>::const_iterator u = new_folders_by_path.find (m->second->path ());
|
||||
if (u == new_folders_by_path.end ()) {
|
||||
// no longer used
|
||||
folders_to_delete.push_back (m->second);
|
||||
} else {
|
||||
m->second->set_description (u->second->description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<lym::MacroCollection *>::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) {
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use";
|
||||
}
|
||||
root->erase (*m);
|
||||
}
|
||||
|
||||
// sync the search paths with the packages
|
||||
sync_package_paths ();
|
||||
|
||||
// store new paths
|
||||
m_external_paths = external_paths;
|
||||
|
||||
// add new folders
|
||||
|
||||
std::vector<lym::MacroCollection *> new_folders;
|
||||
|
||||
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
|
||||
|
||||
if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'";
|
||||
}
|
||||
|
||||
// Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in
|
||||
// a non-tech context.
|
||||
// In that case, the add_folder method will return 0.
|
||||
|
||||
// TODO: is it wise to make this writeable?
|
||||
lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
|
||||
if (mc) {
|
||||
mc->set_virtual_mode (p->type);
|
||||
new_folders.push_back (mc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
// This prevents the message dialog below to issue deferred methods
|
||||
tl::NoDeferredMethods silent;
|
||||
|
||||
bool has_autorun = false;
|
||||
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) {
|
||||
has_autorun = (*m)->has_autorun ();
|
||||
}
|
||||
|
||||
if (has_autorun) {
|
||||
if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) {
|
||||
(*m)->autorun ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -144,10 +144,8 @@ public:
|
|||
/**
|
||||
* @brief Loads the macros from the predefined paths and establishes the search paths
|
||||
* This method will also establish the macro categories.
|
||||
* If "load" is false, only the search path will be set. The macros themselves are not
|
||||
* loaded into memory.
|
||||
*/
|
||||
void finish (bool load);
|
||||
void finish ();
|
||||
|
||||
/**
|
||||
* @brief Adds a temporary macro
|
||||
|
|
@ -256,6 +254,7 @@ private:
|
|||
void sync_file_watcher ();
|
||||
void sync_files ();
|
||||
void sync_package_paths ();
|
||||
void sync_macro_sources ();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1789,6 +1789,11 @@ bool MacroCollection::has_autorun () const
|
|||
return has_autorun_for (*this, false);
|
||||
}
|
||||
|
||||
bool MacroCollection::has_autorun_early () const
|
||||
{
|
||||
return has_autorun_for (*this, true);
|
||||
}
|
||||
|
||||
static void autorun_for (lym::MacroCollection &collection, bool early)
|
||||
{
|
||||
for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) {
|
||||
|
|
|
|||
|
|
@ -989,6 +989,11 @@ public:
|
|||
*/
|
||||
void autorun ();
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the collection has an early autorun macro
|
||||
*/
|
||||
bool has_autorun_early () const;
|
||||
|
||||
/**
|
||||
* @brief Runs all macros marked with early auto-run
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue