From 5e15eb69491f4983ea1c20e51334c82e2f93a7cc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 20 Sep 2024 00:17:06 -0400 Subject: [PATCH] add lammps_expand() method and make available in python --- python/lammps/core.py | 25 ++++++++++++++++++++++++ src/library.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ src/library.h | 2 ++ 3 files changed, 72 insertions(+) diff --git a/python/lammps/core.py b/python/lammps/core.py index 249b4719e0..508148594e 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -178,6 +178,9 @@ class lammps(object): self.lib.lammps_error.argtypes = [c_void_p, c_int, c_char_p] + self.lib.lammps_expand.argtypes = [c_void_p, c_char_p] + self.lib.lammps_expand.restype = c_char_p + self.lib.lammps_file.argtypes = [c_void_p, c_char_p] self.lib.lammps_file.restype = None @@ -613,6 +616,28 @@ class lammps(object): # ------------------------------------------------------------------------- + def expand(self,line): + """Expand a single LAMMPS string like an input line + + This is a wrapper around the :cpp:func:`lammps_expand` + function of the C-library interface. + + :param cmd: a single lammps line + :type cmd: string + :return: expanded string + :rtype: string + """ + if line: newline = line.encode() + else: return None + + with ExceptionCheck(self): + strptr = self.lib.lammps_expand(self.lmp, newline) + rval = strptr.decode() + return rval + + return None + # ------------------------------------------------------------------------- + def file(self, path): """Read LAMMPS commands from a file. diff --git a/src/library.cpp b/src/library.cpp index 29cec30488..75d6fecc18 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -501,6 +501,51 @@ void lammps_error(void *handle, int error_type, const char *error_text) } } +/* ---------------------------------------------------------------------- */ + +/** expand a single LAMMPS input line from a string. + * +\verbatim embed:rst + +This function tells LAMMPS to expand the string in *cmd* like it would process +an input line fed to :cpp:func:`lammps_command` **without** executing it. +The entire string is considered as command and need not have a +(final) newline character. Newline characters in the body of the +string, however, will be treated as part of the command and will **not** +start a second command. + +The function returns the expanded string in a new string buffer that +must be freed with :cpp:func:`lammps_free` after use to avoid a memory leak. + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param cmd string with a single LAMMPS input line + * \return string with expanded line */ + +char *lammps_expand(void *handle, const char *line) +{ + auto lmp = (LAMMPS *) handle; + char *copy, *work; + int n, maxcopy, maxwork; + + if (!line) return nullptr; + + BEGIN_CAPTURE + { + n = strlen(line) + 1; + copy = (char *) malloc(n * sizeof(char)); + work = (char *) malloc(n * sizeof(char)); + maxwork = maxcopy = n; + memcpy(copy, line, maxcopy); + lmp->input->substitute(copy, work, maxcopy, maxwork, 0); + free(work); + } + END_CAPTURE + + return copy; +} + // ---------------------------------------------------------------------- // Library functions to process commands // ---------------------------------------------------------------------- diff --git a/src/library.h b/src/library.h index dbfd32a542..36e67470ae 100644 --- a/src/library.h +++ b/src/library.h @@ -133,6 +133,8 @@ void lammps_python_finalize(); void lammps_error(void *handle, int error_type, const char *error_text); +char *lammps_expand(void *handle, const char *line); + /* ---------------------------------------------------------------------- * Library functions to process commands * ---------------------------------------------------------------------- */