[Pkg-electronics-commits] [gnucap] 27/43: plugpath-bug: handle '/' in plugin name, add help text, list loaded plugins when no arg
felix salfelder
felix-guest at moszumanska.debian.org
Wed Oct 4 03:21:45 UTC 2017
This is an automated email from the git hooks/post-receive script.
felix-guest pushed a commit to branch master
in repository gnucap.
commit f3059b5f0debd409a912cbb5debe3f5f2228a8ff
Author: al davis <ad211 at freeelectron.net>
Date: Sat May 13 17:29:01 2017 -0400
plugpath-bug: handle '/' in plugin name, add help text, list loaded plugins when no arg
'/' in plugin name can be either start at current dir, or search path
to allow explicit subdirs in plugin path,
because same name (ex: jfet.so) can exist in several packages (ex: spice3f5 and ngspice)
---
include/patchlev.h | 2 +-
lib/c_attach.cc | 143 +++++++++++++++++++++++++++++-------------
tests/==out/c_attach.1.gc.out | 16 +++++
tests/c_attach.1.gc | 6 ++
4 files changed, 121 insertions(+), 46 deletions(-)
diff --git a/include/patchlev.h b/include/patchlev.h
index c395aac..7ff64a9 100644
--- a/include/patchlev.h
+++ b/include/patchlev.h
@@ -1 +1 @@
-#define PATCHLEVEL "plugpath-bug 2017.05.11"
+#define PATCHLEVEL "plugpath-bug 2017.05.13"
diff --git a/lib/c_attach.cc b/lib/c_attach.cc
index bb0d31f..d1e5c0b 100644
--- a/lib/c_attach.cc
+++ b/lib/c_attach.cc
@@ -1,4 +1,4 @@
-/*$Id: c_attach.cc,v 26.137 2010/04/10 02:37:33 al Exp $ -*- C++ -*-
+/*$Id: c_attach.cc $ -*- C++ -*-
* Copyright (C) 2007 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -20,7 +20,7 @@
* 02110-1301, USA.
*------------------------------------------------------------------
*/
-//testing=script 2017.03.12
+//testing=script 2017.05.13
#include "e_cardlist.h"
#include "c_comand.h"
#include "globals.h"
@@ -34,6 +34,18 @@ std::string plug_path()
return OS::getenv("GNUCAP_PLUGPATH");
}
/*--------------------------------------------------------------------------*/
+void list()
+{
+ for (std::map<std::string, void*>::iterator
+ ii = attach_list.begin(); ii != attach_list.end(); ++ii) {
+ if (ii->second) {
+ IO::mstdout << ii->first << '\n';
+ }else{untested();
+ error(bTRACE, ii->first + " (unloaded)\n");
+ }
+ }
+}
+/*--------------------------------------------------------------------------*/
class CMD_ATTACH : public CMD {
public:
void do_it(CS& cmd, CARD_LIST*)
@@ -60,41 +72,66 @@ public:
std::string short_file_name;
cmd >> short_file_name;
- void* handle = attach_list[short_file_name];
- if (handle) {itested();
- if (CARD_LIST::card_list.is_empty()) {itested();
- cmd.warn(bDANGER, here, "\"" + short_file_name + "\": already loaded, replacing");
- dlclose(handle);
- attach_list[short_file_name] = NULL;
- }else{itested();
- cmd.reset(here);
- throw Exception_CS("already loaded, cannot replace when there is a circuit", cmd);
- }
+ if (short_file_name == "") {
+ // nothing, list what we have
+ list();
}else{
- }
-
- if (short_file_name.find('/') == std::string::npos) {
- // no '/' in name, search for it
- std::string path = plug_path();
- std::string full_file_name = findfile(short_file_name, path, R_OK);
- if (full_file_name != "") {
- // found it in path
- handle = dlopen(full_file_name.c_str(), check | dl_scope);
+ // a name to look for
+ // check if already loaded
+ void* handle = attach_list[short_file_name];
+ if (handle) {itested();
+ if (CARD_LIST::card_list.is_empty()) {itested();
+ cmd.warn(bDANGER, here, "\"" + short_file_name + "\": already loaded, replacing");
+ dlclose(handle);
+ handle = NULL;
+ attach_list[short_file_name] = NULL;
+ }else{untested();itested();
+ cmd.reset(here);
+ throw Exception_CS("already loaded, cannot replace when there is a circuit", cmd);
+ }
+ }else{
+ }
+
+ // '/' in name, try local search
+ if (short_file_name.find('/') != std::string::npos) {itested();
+ handle = dlopen(short_file_name.c_str(), check | dl_scope);
+ }else{
+ assert(!handle);
+ }
+
+ if (!handle) {
+ // didn't find locally, try plug_path(), even if '/' in name
+ std::string path = plug_path();
+ std::string full_file_name = findfile(short_file_name, path, R_OK);
+ if (full_file_name != "") {
+ // found it in path
+ handle = dlopen(full_file_name.c_str(), check | dl_scope);
+ }else{itested();
+ cmd.reset(here);
+ throw Exception_CS("plugin not found in " + path, cmd);
+ }
}else{itested();
+ // already got it ('/' in name)
+ }
+
+ if (handle) {
+ attach_list[short_file_name] = handle;
+ }else{untested();itested();
cmd.reset(here);
- throw Exception_CS("plugin not found in " + path, cmd);
+ throw Exception_CS(dlerror(), cmd);
}
- }else{itested();
- // has '/' in name, don't search, we have full name
- handle = dlopen(short_file_name.c_str(), check | dl_scope);
}
+ }
- if (handle) {
- attach_list[short_file_name] = handle;
- }else{itested();
- cmd.reset(here);
- throw Exception_CS(dlerror(), cmd);
- }
+ std::string help_text()const
+ {
+ return
+ "load command\n"
+ "Loads plugins\n"
+ "Syntax: load plugin\n"
+ "Plugin search path is: " + plug_path() + " \n"
+ "Path is set by GNUCAP_PLUGPATH environment variable\n"
+ "With no arg, it lists plugins already loaded\n\n";
}
} p1;
DISPATCHER<CMD>::INSTALL d1(&command_dispatcher, "attach|load", &p1);
@@ -102,24 +139,40 @@ DISPATCHER<CMD>::INSTALL d1(&command_dispatcher, "attach|load", &p1);
class CMD_DETACH : public CMD {
public:
void do_it(CS& cmd, CARD_LIST*)
- {untested();
- if (CARD_LIST::card_list.is_empty()) {untested();
- unsigned here = cmd.cursor();
- std::string file_name;
- cmd >> file_name;
-
- void* handle = attach_list[file_name];
- if (handle) {untested();
- dlclose(handle);
- attach_list[file_name] = NULL;
+ {
+ unsigned here = cmd.cursor(); //BUG// due to the way dlopen and dlclose work
+ std::string file_name; // it doesn't really work.
+ cmd >> file_name; // the dispatcher's active instance blocks unload
+
+ if (file_name == "") {
+ // nothing, list what we have
+ list();
+ }else{untested();
+ if (CARD_LIST::card_list.is_empty()) {untested();
+ void* handle = attach_list[file_name];
+ if (handle) {untested();
+ dlclose(handle);
+ attach_list[file_name] = NULL;
+ }else{untested();
+ cmd.reset(here);
+ throw Exception_CS("plugin not attached", cmd);
+ }
}else{untested();
- cmd.reset(here);
- throw Exception_CS("plugin not attached", cmd);
+ throw Exception_CS("detach prohibited when there is a circuit", cmd);
}
- }else{untested();
- throw Exception_CS("detach prohibited when there is a circuit", cmd);
}
}
+
+ std::string help_text()const
+ {
+ return
+ "unload command\n"
+ "Unloads plugins\n"
+ "Syntax: unload plugin\n"
+ "The name must match the name you loaded it with.\n"
+ "Prohibited when there is a circuit\n"
+ "With no arg, it lists plugins already loaded\n\n";
+ }
} p2;
DISPATCHER<CMD>::INSTALL d2(&command_dispatcher, "detach|unload", &p2);
/*--------------------------------------------------------------------------*/
diff --git a/tests/==out/c_attach.1.gc.out b/tests/==out/c_attach.1.gc.out
new file mode 100644
index 0000000..2614f3f
--- /dev/null
+++ b/tests/==out/c_attach.1.gc.out
@@ -0,0 +1,16 @@
+load command
+Loads plugins
+Syntax: load plugin
+Plugin search path is: /usr/local/lib/gnucap
+Path is set by GNUCAP_PLUGPATH environment variable
+With no arg, it lists plugins already loaded
+
+gnucap-default-plugins.so
+unload command
+Unloads plugins
+Syntax: unload plugin
+The name must match the name you loaded it with.
+Prohibited when there is a circuit
+With no arg, it lists plugins already loaded
+
+gnucap-default-plugins.so
diff --git a/tests/c_attach.1.gc b/tests/c_attach.1.gc
new file mode 100644
index 0000000..2df7253
--- /dev/null
+++ b/tests/c_attach.1.gc
@@ -0,0 +1,6 @@
+
+help load
+load
+help unload
+unload
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/gnucap.git
More information about the Pkg-electronics-commits
mailing list