port molfile plugin reader to platform namespace

This commit is contained in:
Axel Kohlmeyer
2021-10-04 22:40:40 -04:00
parent ee594a879b
commit 0bdc6d47e0
3 changed files with 37 additions and 239 deletions

View File

@ -26,8 +26,8 @@
#include "memory.h" #include "memory.h"
#include "update.h" #include "update.h"
#include <cstring>
#include <cmath> #include <cmath>
#include <cstring>
#include "molfile_interface.h" #include "molfile_interface.h"
@ -131,9 +131,9 @@ DumpMolfile::~DumpMolfile()
if (typenames) { if (typenames) {
for (int i = 1; i <= ntypes; i++) for (int i = 1; i <= ntypes; i++)
delete [] typenames[i]; delete[] typenames[i];
delete [] typenames; delete[] typenames;
typenames = nullptr; typenames = nullptr;
} }
} }
@ -152,8 +152,7 @@ void DumpMolfile::init_style()
typenames = new char*[ntypes+1]; typenames = new char*[ntypes+1];
for (int itype = 1; itype <= ntypes; itype++) { for (int itype = 1; itype <= ntypes; itype++) {
/* a 32-bit int can be maximally 10 digits plus sign */ /* a 32-bit int can be maximally 10 digits plus sign */
typenames[itype] = new char[12]; typenames[itype] = utils::strdup(std::to_string(itype));
sprintf(typenames[itype],"%d",itype);
} }
} }
@ -207,6 +206,7 @@ void DumpMolfile::write()
} }
} }
ntotal = 0; ntotal = 0;
reorderflag = 0;
// if file per timestep, open new file // if file per timestep, open new file
@ -430,9 +430,9 @@ int DumpMolfile::modify_param(int narg, char **arg)
if (typenames) { if (typenames) {
for (int i = 1; i <= ntypes; i++) for (int i = 1; i <= ntypes; i++)
delete [] typenames[i]; delete[] typenames[i];
delete [] typenames; delete[] typenames;
typenames = nullptr; typenames = nullptr;
} }

View File

@ -17,6 +17,11 @@
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "molfile_interface.h" #include "molfile_interface.h"
#include "platform.h"
#include "tokenizer.h"
#include "utils.h"
#include "molfile_plugin.h" #include "molfile_plugin.h"
#include <cstdio> #include <cstdio>
@ -25,13 +30,6 @@
#include <cctype> #include <cctype>
#include <strings.h> // for strcasecmp() #include <strings.h> // for strcasecmp()
#if defined(_WIN32)
#include <windows.h>
#else
#include <dirent.h>
#include <dlfcn.h>
#endif
#if vmdplugin_ABIVERSION < 16 #if vmdplugin_ABIVERSION < 16
#error "unsupported VMD molfile plugin ABI version" #error "unsupported VMD molfile plugin ABI version"
#endif #endif
@ -199,172 +197,17 @@ extern "C" {
return 0; return 0;
} }
// directory traversal helper functions
#if defined(_WIN32)
// Win32 directory traversal handle
typedef struct {
HANDLE h;
WIN32_FIND_DATA fd;
char *name;
char *searchname;
int dlen;
} dirhandle_t;
// open a directory handle
static dirhandle_t *my_opendir(const char *dirname)
{
dirhandle_t *d;
int len;
if (dirname == nullptr)
return nullptr;
d = new dirhandle_t;
len = 2 + strlen(dirname);
d->name = new char[len];
strcpy(d->name, dirname);
strcat(d->name, "\\");
d->dlen = len;
len += 1;
d->searchname = new char[len];
strcpy(d->searchname, dirname);
strcat(d->searchname, "\\*");
d->h = FindFirstFile(d->searchname, &(d->fd));
if (d->h == ((HANDLE)(-1))) {
delete[] d->searchname;
delete[] d->name;
delete d;
return nullptr;
}
return d;
}
// get next file name from directory handle
static char *my_readdir(dirhandle_t *d)
{
if (FindNextFile(d->h, &(d->fd))) {
return d->fd.cFileName;
}
return nullptr;
}
// close directory handle
static void my_closedir(dirhandle_t *d)
{
if (d->h != nullptr) {
FindClose(d->h);
}
delete[] d->searchname;
delete[] d->name;
delete d;
}
// open a shared object file
static void *my_dlopen(const char *fname) {
return (void *)LoadLibrary(fname);
}
// resolve a symbol in shared object
static void *my_dlsym(void *h, const char *sym) {
return (void *)GetProcAddress((HINSTANCE)h, sym);
}
// close a shared object
static int my_dlclose(void *h) {
/* FreeLibrary returns nonzero on success */
return !FreeLibrary((HINSTANCE)h);
}
#else
// Unix directory traversal handle
typedef struct {
DIR *d;
char *name;
int dlen;
} dirhandle_t;
// open a directory handle
static dirhandle_t *my_opendir(const char *dirname)
{
dirhandle_t *d;
int len;
if (dirname == nullptr) return nullptr;
d = new dirhandle_t;
len = 2 + strlen(dirname);
d->name = new char[len];
strcpy(d->name,dirname);
strcat(d->name,"/");
d->dlen = len;
d->d = opendir(d->name);
if (d->d == nullptr) {
delete[] d->name;
delete d;
return nullptr;
}
return d;
}
// get next file name from directory handle
static char *my_readdir(dirhandle_t *d)
{
struct dirent *p;
if ((p = readdir(d->d)) != nullptr) {
return p->d_name;
}
return nullptr;
}
// close directory handle
static void my_closedir(dirhandle_t *d)
{
if (d->d != nullptr) {
closedir(d->d);
}
delete[] d->name;
delete d;
return;
}
// open a shared object file
static void *my_dlopen(const char *fname) {
return dlopen(fname, RTLD_NOW);
}
// resolve a symbol in shared object
static void *my_dlsym(void *h, const char *sym) {
return dlsym(h, sym);
}
// close a shared object
static int my_dlclose(void *h) {
return dlclose(h);
}
#endif
} // end of extern "C" region } // end of extern "C" region
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
// constructor. // constructor.
MolfileInterface::MolfileInterface(const char *type, const int mode) MolfileInterface::MolfileInterface(const char *type, const int mode)
: _plugin(0), _dso(0), _ptr(0), _info(0), _natoms(0), : _plugin(nullptr), _dso(nullptr), _ptr(nullptr), _info(nullptr), _natoms(0),
_mode(mode), _caps(M_NONE) _mode(mode), _caps(M_NONE), _props(0)
{ {
_name = new char[5]; _name = utils::strdup("none");
strcpy(_name,"none"); _type = utils::strdup(type);
_type = new char[1+strlen(type)];
strcpy(_type,type);
} }
// destructor. // destructor.
@ -384,62 +227,21 @@ MolfileInterface::~MolfileInterface()
// register the best matching plugin in a given directory // register the best matching plugin in a given directory
int MolfileInterface::find_plugin(const char *pluginpath) int MolfileInterface::find_plugin(const char *pluginpath)
{ {
dirhandle_t *dir;
char *filename, *ext, *next, *path, *plugindir;
int retval = E_NONE; int retval = E_NONE;
#if defined(_WIN32)
#define MY_PATHSEP ';'
#else
#define MY_PATHSEP ':'
#endif
if (pluginpath == nullptr) return E_DIR; if (pluginpath == nullptr) return E_DIR;
plugindir = path = strdup(pluginpath);
while (plugindir) { // search for suitable file names in provided path and try to inspect them
// check if this a single directory or path. // only look at .so files, since this is what VMD uses on all platforms
next = strchr(plugindir,MY_PATHSEP);
if (next) { for (const auto &dir : Tokenizer(pluginpath,":").as_vector()) {
*next = '\0'; for (const auto &filename : platform::list_directory(dir)) {
++next; if (utils::strmatch(filename,"\\.so$")) {
int rv = load_plugin(platform::path_join(dir,filename).c_str());
if (rv > retval) retval = rv;
}
} }
dir = my_opendir(plugindir);
if (!dir)
retval = (retval > E_DIR) ? retval : E_DIR;
// search for suitable file names and try to inspect them
while (dir) {
char *fullname;
int len;
filename = my_readdir(dir);
if (filename == nullptr) break;
// only look at .so files
ext = strrchr(filename, '.');
if (ext == nullptr) continue;
if (strcasecmp(ext,".so") != 0) continue;
// construct full pathname of potential DSO
len = dir->dlen;
len += strlen(filename);
fullname = new char[len];
strcpy(fullname,dir->name);
strcat(fullname,filename);
// try to register plugin at file name.
int rv = load_plugin(fullname);
if (rv > retval) retval = rv;
delete[] fullname;
}
if (dir)
my_closedir(dir);
plugindir = next;
} }
free(path);
return retval; return retval;
} }
@ -450,22 +252,22 @@ int MolfileInterface::load_plugin(const char *filename)
int len, retval = E_NONE; int len, retval = E_NONE;
// access shared object // access shared object
dso = my_dlopen(filename); dso = platform::dlopen(filename);
if (dso == nullptr) if (dso == nullptr)
return E_FILE; return E_FILE;
// check for required plugin symbols // check for required plugin symbols
void *ifunc = my_dlsym(dso,"vmdplugin_init"); void *ifunc = platform::dlsym(dso,"vmdplugin_init");
void *rfunc = my_dlsym(dso,"vmdplugin_register"); void *rfunc = platform::dlsym(dso,"vmdplugin_register");
void *ffunc = my_dlsym(dso,"vmdplugin_fini"); void *ffunc = platform::dlsym(dso,"vmdplugin_fini");
if (ifunc == nullptr || rfunc == nullptr || ffunc == nullptr) { if (ifunc == nullptr || rfunc == nullptr || ffunc == nullptr) {
my_dlclose(dso); platform::dlclose(dso);
return E_SYMBOL; return E_SYMBOL;
} }
// initialize plugin. skip plugin if it fails. // initialize plugin. skip plugin if it fails.
if (((initfunc)(ifunc))()) { if (((initfunc)(ifunc))()) {
my_dlclose(dso); platform::dlclose(dso);
return E_SYMBOL; return E_SYMBOL;
} }
@ -528,12 +330,8 @@ int MolfileInterface::load_plugin(const char *filename)
forget_plugin(); forget_plugin();
delete[] _name; delete[] _name;
len = 16; _name = utils::strdup(fmt::format("{} v{}.{} by {}", plugin->prettyname,
len += strlen(plugin->prettyname); plugin->majorv, plugin->minorv, plugin->author));
len += strlen(plugin->author);
_name = new char[len];
sprintf(_name,"%s v%d.%d by %s",plugin->prettyname,
plugin->majorv, plugin->minorv, plugin->author);
// determine plugin capabilities // determine plugin capabilities
_caps = M_NONE; _caps = M_NONE;
@ -569,7 +367,7 @@ int MolfileInterface::load_plugin(const char *filename)
} }
// better luck next time. clean up and return. // better luck next time. clean up and return.
my_dlclose(dso); platform::dlclose(dso);
return retval; return retval;
} }
@ -583,10 +381,10 @@ void MolfileInterface::forget_plugin()
_plugin = nullptr; _plugin = nullptr;
if (_dso) { if (_dso) {
void *ffunc = my_dlsym(_dso,"vmdplugin_fini"); void *ffunc = platform::dlsym(_dso,"vmdplugin_fini");
if (ffunc) if (ffunc)
((finifunc)ffunc)(); ((finifunc)ffunc)();
my_dlclose(_dso); platform::dlclose(_dso);
} }
_dso = nullptr; _dso = nullptr;

View File

@ -527,7 +527,7 @@ void *platform::dlsym(void *handle, const std::string &symbol)
// open a shared object file // open a shared object file
void *platform::dlopen(const std::string &fname) void *platform::dlopen(const std::string &fname)
{ {
return ::dlopen(fname.c_str(), RTLD_NOW); return ::dlopen(fname.c_str(), RTLD_NOW | RTLD_GLOBAL);
} }
// close a shared object // close a shared object