port molfile plugin reader to platform namespace
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user