[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