From 019f7389935b297963e908cb0416b919513282ec Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Wed, 4 Aug 2021 18:24:39 +0000
Subject: [PATCH] Update to use ZIPR_PLUGIN_PATH for Zipr

---
 SConscript         |   2 +-
 src/SConscript     |   3 +-
 src/plugin_man.cpp | 151 ++++++++++++++++++++++++++-------------------
 3 files changed, 89 insertions(+), 67 deletions(-)

diff --git a/SConscript b/SConscript
index 9558bf124..99af86f95 100644
--- a/SConscript
+++ b/SConscript
@@ -11,7 +11,7 @@ zipr=SConscript("src/SConscript")
 
 pedi = Command( target = "./zipr-testoutput",
                 source = zipr,
-                action = "echo zipr; cd "+os.environ['ZIPR_INSTALL']+" ; " +os.environ['PEDI_HOME']+"/pedi -m manifest.txt ; cd -" )
+                action = "echo zipr; cd "+os.environ['PEASOUP_HOME']+"/zipr_install ; " +os.environ['PEDI_HOME']+"/pedi -m manifest.txt ; cd -" )
 
 ret=[zipr]
 if Dir('.').abspath == Dir('#.').abspath:
diff --git a/src/SConscript b/src/SConscript
index 5a5c4c88b..dc07c45e5 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -9,7 +9,6 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
 myenv.Replace(ZIPR_HOME=os.environ['ZIPR_HOME'])
 myenv.Replace(IRDB_SDK=os.environ['IRDB_SDK'])
 myenv.Replace(ZIPR_SDK=os.environ['ZIPR_SDK'])
-myenv.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL'])
 
 
 files=  '''
@@ -85,7 +84,7 @@ myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpat
 myenv.Append(CXXFLAGS=" -Wno-deprecated -fmax-errors=2")
 ziprexe=myenv.Program("zipr.exe", Split(files))
 
-install=myenv.Install("$ZIPR_INSTALL/bin/", ziprexe)
+install=myenv.Install("$PEASOUP_HOME/zipr_install/bin/", ziprexe)
 Default(install)
 ret=install+ziprexe
 Return('ret')
diff --git a/src/plugin_man.cpp b/src/plugin_man.cpp
index 85c815141..1320a6510 100644
--- a/src/plugin_man.cpp
+++ b/src/plugin_man.cpp
@@ -39,7 +39,6 @@
 #include <iostream>
 
 
-
 using namespace std;
 using namespace Zipr_SDK;
 using namespace IRDB_SDK;
@@ -60,6 +59,36 @@ for(DLFunctionHandleSet_t::iterator it=m_handleList.begin(); it!=m_handleList.en
 	var=zpi->func(var); \
 } 
 
+#define ALLOF(a) begin(a),end(a)
+
+
+
+/*
+ * Convert a bash PATH-like string into a vector of strings.
+ * by default, delimintor is :
+ * Returns the vector of strings
+ */
+const vector<string>& splitVar(const string& toSplit , const char delimiter = ':')
+{
+    static vector<string> result;
+    if( !result.empty() )
+        return result;
+    if( toSplit.empty() )
+        throw runtime_error( "toSplit should not be empty" );
+
+    auto previous = size_t(0);
+    auto index = toSplit.find( delimiter );
+    while( index != string::npos )
+    {
+        result.push_back( toSplit.substr(previous, index-previous));
+        previous=index+1;
+        index = toSplit.find( delimiter, previous );
+    }
+    result.push_back( toSplit.substr(previous) );
+
+    return result;
+}
+
 /*
  * sort_plugins_by_name()
  *
@@ -165,10 +194,8 @@ bool ZiprPluginManager_t::DoesPluginRetargetCallback(const RangeAddress_t &callb
 
 bool ZiprPluginManager_t::DoesPluginRetargetPin(const RangeAddress_t &patch_addr, const Zipr_SDK::Dollop_t *target_dollop, RangeAddress_t &target_address, DLFunctionHandle_t &patcher) 
 {
-	DLFunctionHandleSet_t::iterator it=m_handleList.begin();
-	for(m_handleList.begin();it!=m_handleList.end();++it)
+	for(const auto& zpi : m_handleList)
 	{
-		ZiprPluginInterface_t* zpi=(ZiprPluginInterface_t*)*it;
 		if (Must == zpi->retargetPin(patch_addr, target_dollop, target_address))
 		{
 			patcher = zpi;
@@ -184,76 +211,72 @@ void ZiprPluginManager_t::open_plugins
 				Zipr_SDK::ZiprOptionsManager_t *p_opts
                         )
 {
-	char* zinst=getenv("ZIPR_INSTALL");
-
-	if(!zinst)
+	const auto ziprPluginDirs=splitVar(getenv("ZIPR_PLUGIN_PATH"));
+	for(const auto dir : ziprPluginDirs) 
 	{
-		cerr<<"Cannot fid $ZIPR_INSTALL environment variable.  Please set properly."<<endl;
-	}
 
-	string dir=string(zinst)+"/plugins/";
-
-    	DIR *dp;
-    	struct dirent *dirp;
-    	if((dp  = opendir(dir.c_str())) == nullptr) 
-	{
-        	cout << "Error(" << errno << ") opening plugins directory: " << dir << endl;
-		exit(1);
-    	}
-
-    	while ((dirp = readdir(dp)) != nullptr) 
-	{
-		auto basename = string(dirp->d_name);
-		auto name=dir+basename;
-		auto zpi=string(".zpi");
-		auto extension=name.substr(name.size() - zpi.length());
-
-		// Automatically skip cwd and pwd entries.
-		if(basename == "." || basename == "..")
-			continue;
-
-		if (extension!=zpi)
+		const auto dp = opendir(dir.c_str());
+		if(dp == nullptr) 
 		{
-			cout<<"File ("<<name<<") does not have proper extension, skipping."<<endl;
-			continue; // try next file
-		}
-		if (m_verbose)
-			cout<<"Attempting load of file ("<<name<<")."<<endl;
-
-		auto handle=dlopen(name.c_str(), RTLD_LAZY|RTLD_GLOBAL);
-		if(!handle)
-		{
-			cerr<<"Failed to open file ("<<name<<"), error code: "<<dlerror()<<endl;
+			cout << "Error(" << errno << ") opening plugins directory: " << dir << endl;
 			exit(1);
 		}
-		dlerror();
 
-		auto sym=dlsym(handle,"GetPluginInterface");
-		if(!sym)
+		auto dirp = (dirent*) nullptr;
+		while ((dirp = readdir(dp)) != nullptr) 
 		{
-			cerr<<"Failed to find GetPluginInterface from file ("<<name<<"), error code: "<<dlerror()<<endl;
-			exit(1);
-		}
-
-		auto my_GetPluginInterface= (GetPluginInterface_t)sym;
-		auto interface            = (*my_GetPluginInterface)(zipr_obj);
+			const auto basename = string(dirp->d_name);
+			const auto name=dir+'/'+basename;
+			const auto zpi=string(".zpi");
+			const auto extension=name.substr(name.size() - zpi.length());
+
+			// Automatically skip cwd and pwd entries.
+			if(basename == "." || basename == "..")
+				continue;
+
+			if (extension!=zpi)
+			{
+				cout<<"File ("<<name<<") does not have proper extension, skipping."<<endl;
+				continue; // try next file
+			}
+			if (m_verbose)
+				cout<<"Attempting load of file ("<<name<<")."<<endl;
+
+			const auto handle=dlopen(name.c_str(), RTLD_LAZY|RTLD_GLOBAL);
+			if(!handle)
+			{
+				cerr<<"Failed to open file ("<<name<<"), error code: "<<dlerror()<<endl;
+				exit(1);
+			}
+			dlerror();
+
+			const auto sym=dlsym(handle,"GetPluginInterface");
+			if(!sym)
+			{
+				cerr<<"Failed to find GetPluginInterface from file ("<<name<<"), error code: "<<dlerror()<<endl;
+				exit(1);
+			}
+
+			const auto my_GetPluginInterface= (GetPluginInterface_t)sym;
+			const auto interface            = (*my_GetPluginInterface)(zipr_obj);
+
+			if(!interface)
+			{
+				cerr<<"Failed to get interface from file ("<<name<<")"<<endl;
+				exit(1);
+			}
+
+			// constructors now register options
+			// auto global_ns            = p_opts->getNamespace("global");
+			// p_opts->addNamespace(interface->registerOptions(global_ns));
+
+			m_handleList.push_back(interface);
 
-		if(!interface)
-		{
-			cerr<<"Failed to get interface from file ("<<name<<")"<<endl;
-			exit(1);
 		}
+		closedir(dp);
 
-		// constructors now register options
-		// auto global_ns            = p_opts->getNamespace("global");
-		// p_opts->addNamespace(interface->registerOptions(global_ns));
-
-		m_handleList.push_back(interface);
-		
-    	}
-    	closedir(dp);
-
-			std::sort(m_handleList.begin(), m_handleList.end(), sort_plugins_by_name);
+	}
+	std::sort(ALLOF(m_handleList), sort_plugins_by_name);
 
     	return;
 }
-- 
GitLab