Commit 27a6371f authored by Axel Kohlmeyer's avatar Axel Kohlmeyer
Browse files

implement a `python source` command as suggested in issue #454

parent a069d216
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ python func keyword args ... :pre

func = name of Python function :ulb,l
one or more keyword/args pairs must be appended :l
keyword = {invoke} or {input} or {return} or {format} or {length} or {file} or {here} or {exists}
keyword = {invoke} or {input} or {return} or {format} or {length} or {file} or {here} or {exists} or {source}
  {invoke} arg = none = invoke the previously defined Python function
  {input} args = N i1 i2 ... iN
    N = # of inputs to function
@@ -36,7 +36,12 @@ keyword = {invoke} or {input} or {return} or {format} or {length} or {file} or {
  {here} arg = inline
    inline = one or more lines of Python code which defines func
             must be a single argument, typically enclosed between triple quotes
  {exists} arg = none = Python code has been loaded by previous python command :pre
  {exists} arg = none = Python code has been loaded by previous python command
  {source} arg = {filename} or {inline}
    filename = file of Python code which will be executed immediately
    inline = one or more lines of Python code which will be executed immediately
             must be a single argument, typically enclosed between triple quotes
:pre
:ule

[Examples:]
@@ -67,7 +72,8 @@ def loop(lmpptr,N,cut0):

[Description:]

Define a Python function or execute a previously defined function.
Define a Python function or execute a previously defined function or
execute some arbitrary python code.
Arguments, including LAMMPS variables, can be passed to the function
from the LAMMPS input script and a value returned by the Python
function to a LAMMPS variable.  The Python code for the function can
@@ -102,7 +108,8 @@ command.

The {func} setting specifies the name of the Python function.  The
code for the function is defined using the {file} or {here} keywords
as explained below.
as explained below. In case of the {source} keyword, the name of
the function is ignored.

If the {invoke} keyword is used, no other keywords can be used, and a
previous python command must have defined the Python function
@@ -111,6 +118,13 @@ previously defined arguments and return value processed as explained
below.  You can invoke the function as many times as you wish in your
input script.

If the {source} keyword is used, no other keywords can be used.
The argument can be a filename or a string with python commands,
either on a single line enclosed in quotes, or as multiple lines
enclosed in triple quotes. These python commands will be passed
to the python interpreter and executed immediately without registering
a python function for future execution.

The {input} keyword defines how many arguments {N} the Python function
expects.  If it takes no arguments, then the {input} keyword should
not be used.  Each argument can be specified directly as a value,
+26 −0
Original line number Diff line number Diff line
@@ -119,6 +119,32 @@ void PythonImpl::command(int narg, char **arg)
    return;
  }

  // if source is only keyword, execute the python code

  if (narg == 3 && strcmp(arg[1],"source") == 0) {

    PyGILState_STATE gstate = PyGILState_Ensure();

    // if argument string is file, open it
    // otherwise process string as python code

    int err = 0;
    FILE *fp = fopen(arg[2],"r");

    if (fp == NULL)
      err = PyRun_SimpleString(arg[2]);
    else
      err = PyRun_SimpleFile(fp,arg[2]);

    if (err) {
      PyGILState_Release(gstate);
      error->all(FLERR,"Could not process Python source command");
    }
    if (fp) fclose(fp);
    PyGILState_Release(gstate);
    return;
  }

  // parse optional args, invoke is not allowed in this mode

  ninput = noutput = 0;