move throwing Python variable errors to PythonImpl class and change API accordingly.
This commit is contained in:
@ -451,16 +451,23 @@ int PythonImpl::find(const char *name)
|
||||
ensure a string is returned only if retrieve() is the caller
|
||||
--------------------------------------------------------------------- */
|
||||
|
||||
int PythonImpl::function_match(const char *name, const char *varname, int numeric)
|
||||
int PythonImpl::function_match(const char *name, const char *varname, int numeric, Error *error)
|
||||
{
|
||||
// NOTE to Richard - any reason not to put error messages here instead of in Variable class ?
|
||||
// error messages appear 3x in Variable
|
||||
|
||||
int ifunc = find(name);
|
||||
if (ifunc < 0) return -1;
|
||||
if (pfuncs[ifunc].noutput == 0) return -2;
|
||||
if (strcmp(pfuncs[ifunc].ovarname, varname) != 0) return -3;
|
||||
if (numeric && pfuncs[ifunc].otype == STRING) return -4;
|
||||
|
||||
if (ifunc < 0)
|
||||
error->all(FLERR, Error::NOLASTLINE, "Python function {} specified by variable {} not found",
|
||||
name, varname);
|
||||
if (pfuncs[ifunc].noutput == 0)
|
||||
error->all(FLERR, Error::NOLASTLINE,
|
||||
"Python function {} for variable {} does not return a value", name, varname);
|
||||
if (strcmp(pfuncs[ifunc].ovarname, varname) != 0)
|
||||
error->all(FLERR, Error::NOLASTLINE,
|
||||
"Python function {} and variable {} do not not link to each other", name, varname);
|
||||
if (numeric && pfuncs[ifunc].otype == STRING)
|
||||
error->all(FLERR, Error::NOLASTLINE, "Python function {} for variable {} returns a string",
|
||||
name, varname);
|
||||
|
||||
return ifunc;
|
||||
}
|
||||
|
||||
@ -477,18 +484,18 @@ int PythonImpl::function_match(const char *name, const char *varname, int numeri
|
||||
other classes avoid this issue by setting variable indices in their init() method
|
||||
--------------------------------------------------------------------- */
|
||||
|
||||
int PythonImpl::wrapper_match(const char *name, const char *varname, int narg, int *argvars)
|
||||
int PythonImpl::wrapper_match(const char *name, const char *varname, int narg, int *argvars,
|
||||
Error *error)
|
||||
{
|
||||
// NOTE to Richard - any reason not to put 2 extra error messages here instead of in Variable class ?
|
||||
// only this class knows the name of the missing internal var, so can generate better error message
|
||||
|
||||
int ifunc = function_match(name, varname, 1);
|
||||
int ifunc = function_match(name, varname, 1, error);
|
||||
if (ifunc < 0) return ifunc;
|
||||
|
||||
int internal_count = 0;
|
||||
for (int i = 0; i < pfuncs[ifunc].ninput; i++)
|
||||
if (pfuncs[ifunc].ivarflag[i] == INTERNALVAR) internal_count++;
|
||||
if (internal_count != narg) return -5;
|
||||
if (internal_count != narg)
|
||||
error->all(FLERR, Error::NOLASTLINE,
|
||||
"Python function {} does not use {} internal variable args", name, narg);
|
||||
|
||||
// set argvars of internal-style variables for use by Variable class
|
||||
// in Python wrapper functions
|
||||
@ -496,13 +503,15 @@ int PythonImpl::wrapper_match(const char *name, const char *varname, int narg, i
|
||||
// so that invoke_function() is as fast as possible for args which are internal-style vars
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < pfuncs[ifunc].ninput; i++)
|
||||
for (int i = 0; i < pfuncs[ifunc].ninput; i++) {
|
||||
if (pfuncs[ifunc].ivarflag[i] == INTERNALVAR) {
|
||||
int ivar = input->variable->find(pfuncs[ifunc].svalue[i]);
|
||||
if (ivar < 0) return -6;
|
||||
error->all(FLERR, Error::NOLASTLINE, "Python function {} cannot find internal variable {}",
|
||||
name, pfuncs[ifunc].svalue[i]);
|
||||
pfuncs[ifunc].internal_var[i] = ivar;
|
||||
argvars[j++] = ivar;
|
||||
}
|
||||
}
|
||||
|
||||
return ifunc;
|
||||
}
|
||||
|
||||
@ -27,8 +27,8 @@ class PythonImpl : protected Pointers, public PythonInterface {
|
||||
void command(int, char **) override;
|
||||
void invoke_function(int, char *, double *) override;
|
||||
int find(const char *) override;
|
||||
int function_match(const char *, const char *, int) override;
|
||||
int wrapper_match(const char *, const char *, int, int *) override;
|
||||
int function_match(const char *, const char *, int, Error *) override;
|
||||
int wrapper_match(const char *, const char *, int, int *, Error *) override;
|
||||
char *long_string(int) override;
|
||||
int execute_string(char *) override;
|
||||
int execute_file(char *) override;
|
||||
|
||||
@ -14,9 +14,8 @@
|
||||
#include "lmppython.h"
|
||||
#if defined(LMP_PYTHON)
|
||||
#include "python_impl.h"
|
||||
#else
|
||||
#include "error.h"
|
||||
#endif
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
@ -43,7 +42,7 @@ void Python::init()
|
||||
#if defined(LMP_PYTHON)
|
||||
if (!impl) impl = new PythonImpl(lmp);
|
||||
#else
|
||||
error->all(FLERR, "Python support missing! Compile with PYTHON package installed!");
|
||||
error->all(FLERR, Error::NOLASTLINE, "Python support missing! Compile with PYTHON package installed!");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -83,19 +82,19 @@ int Python::find(const char *name)
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::function_match(const char *name, const char *varname, int numeric)
|
||||
int Python::function_match(const char *name, const char *varname, int numeric, Error *errptr)
|
||||
{
|
||||
init();
|
||||
return impl->function_match(name, varname, numeric);
|
||||
return impl->function_match(name, varname, numeric, errptr);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int Python::wrapper_match(const char *name, const char *varname,
|
||||
int narg, int *argvars)
|
||||
int Python::wrapper_match(const char *name, const char *varname, int narg, int *argvars,
|
||||
Error *errptr)
|
||||
{
|
||||
init();
|
||||
return impl->wrapper_match(name, varname, narg, argvars);
|
||||
return impl->wrapper_match(name, varname, narg, argvars, errptr);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@ -24,8 +24,8 @@ class PythonInterface {
|
||||
virtual void command(int, char **) = 0;
|
||||
virtual void invoke_function(int, char *, double *) = 0;
|
||||
virtual int find(const char *) = 0;
|
||||
virtual int function_match(const char *, const char *, int) = 0;
|
||||
virtual int wrapper_match(const char *, const char *, int, int *) = 0;
|
||||
virtual int function_match(const char *, const char *, int, Error *) = 0;
|
||||
virtual int wrapper_match(const char *, const char *, int, int *, Error *) = 0;
|
||||
virtual char *long_string(int ifunc) = 0;
|
||||
virtual int execute_string(char *) = 0;
|
||||
virtual int execute_file(char *) = 0;
|
||||
@ -40,8 +40,8 @@ class Python : protected Pointers {
|
||||
void command(int, char **);
|
||||
void invoke_function(int, char *, double *);
|
||||
int find(const char *);
|
||||
int function_match(const char *, const char *, int);
|
||||
int wrapper_match(const char *, const char *, int, int *);
|
||||
int function_match(const char *, const char *, int, Error *);
|
||||
int wrapper_match(const char *, const char *, int, int *, Error *);
|
||||
char *long_string(int ifunc);
|
||||
int execute_string(char *);
|
||||
int execute_file(char *);
|
||||
|
||||
@ -959,31 +959,10 @@ void Variable::python_command(int narg, char **arg)
|
||||
|
||||
int Variable::equalstyle(int ivar)
|
||||
{
|
||||
if (style[ivar] == EQUAL || style[ivar] == TIMER ||
|
||||
style[ivar] == INTERNAL) return 1;
|
||||
if (style[ivar] == PYTHON) {
|
||||
pyindex[ivar] = python->function_match(data[ivar][0],names[ivar],1);
|
||||
if (pyindex[ivar] < 0) {
|
||||
int ierror = pyindex[ivar];
|
||||
if (ierror == -1) {
|
||||
error->all(FLERR, "Python function {} specified by variable {} not found",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -2) {
|
||||
error->all(FLERR, "Python function {} for variable {} does not return a value",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -3) {
|
||||
error->all(FLERR, "Python function {} and variable {} do not not link to each other",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -4) {
|
||||
error->all(FLERR, "Python function {} for variable {} returns a string",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else {
|
||||
error->all(FLERR, "Unknown error linking Python function {} to variable {}",
|
||||
data[ivar][0],names[ivar]);
|
||||
}
|
||||
return 0;
|
||||
} else return 1;
|
||||
}
|
||||
if (style[ivar] == EQUAL || style[ivar] == TIMER || style[ivar] == INTERNAL) return 1;
|
||||
if ((style[ivar] == PYTHON) && (python->function_match(data[ivar][0], names[ivar], 1, error) >= 0))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1103,22 +1082,7 @@ char *Variable::retrieve(const char *name)
|
||||
str = data[ivar][1] = utils::strdup(result);
|
||||
|
||||
} else if (style[ivar] == PYTHON) {
|
||||
int ifunc = python->function_match(data[ivar][0],name,0);
|
||||
if (ifunc < 0) {
|
||||
if (ifunc == -1) {
|
||||
error->all(FLERR, "Python function {} specified by variable {} not found",
|
||||
data[ivar][0], name);
|
||||
} else if (ifunc == -2) {
|
||||
error->all(FLERR, "Python function {} for variable {} does not return a value",
|
||||
data[ivar][0], name);
|
||||
} else if (ifunc == -3) {
|
||||
error->all(FLERR, "Python function {} and variable {} do not not link to each other",
|
||||
data[ivar][0], name);
|
||||
} else {
|
||||
error->all(FLERR, "Unknown error linking Python function {} to variable {}",
|
||||
data[ivar][0],name);
|
||||
}
|
||||
}
|
||||
int ifunc = python->function_match(data[ivar][0],name,0,error);
|
||||
python->invoke_function(ifunc,data[ivar][1],nullptr);
|
||||
str = data[ivar][1];
|
||||
|
||||
@ -4208,32 +4172,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, Tree **tree
|
||||
// jvars = returned indices of narg internal variables used by Python function
|
||||
|
||||
int *jvars = new int[narg];
|
||||
pyindex[pyvar] = python->wrapper_match(data[pyvar][0],names[pyvar],narg,jvars);
|
||||
if (pyindex[pyvar] < 0) {
|
||||
int ierror = pyindex[pyvar];
|
||||
if (ierror == -1) {
|
||||
error->all(FLERR, "Python function {} specified by variable {} not found",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -2) {
|
||||
error->all(FLERR, "Python function {} for variable {} does not return a value",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -3) {
|
||||
error->all(FLERR, "Python function {} and variable {} do not not link to each other",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -4) {
|
||||
error->all(FLERR, "Python function {} for variable {} returns a string",
|
||||
data[ivar][0], names[ivar]);
|
||||
} else if (ierror == -5) {
|
||||
error->all(FLERR, "Python function {} does not use {} internal variable args",
|
||||
data[ivar][0], narg);
|
||||
} else if (ierror == -6) {
|
||||
error->all(FLERR,"Python function {} cannot find an internal variable",
|
||||
data[ivar][0]);
|
||||
} else {
|
||||
error->all(FLERR, "Unknown error linking Python function {} to variable {}",
|
||||
data[ivar][0],names[ivar]);
|
||||
}
|
||||
}
|
||||
pyindex[pyvar] = python->wrapper_match(data[pyvar][0],names[pyvar],narg,jvars,error);
|
||||
|
||||
// if tree: store python variable and arg info in tree for later eval
|
||||
// else: one-time eval of python-coded function now via python variable
|
||||
|
||||
Reference in New Issue
Block a user