From c5b51df06e11a9dd1ec22b18debc3bbefa19b60e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= <sebastian.huetter@ovgu.de>
Date: Thu, 14 Jun 2018 14:17:37 +0200
Subject: [PATCH] Add support for inline format strings to immediate variable
 substitution

---
 doc/src/Section_commands.txt | 9 +++++++++
 src/input.cpp                | 9 ++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt
index 3dabdbeaa1..1835d0505f 100644
--- a/doc/src/Section_commands.txt
+++ b/doc/src/Section_commands.txt
@@ -129,6 +129,15 @@ region 1 block $((xlo+xhi)/2+sqrt(v_area)) 2 INF INF EDGE EDGE :pre
 
 so that you do not have to define (or discard) a temporary variable X.
 
+Additionally, the "immediate" expression may be followed by a colon,
+followed by a C-style format string, e.g. "%f" or "%.10g", which must be
+appropriate for formatting a double-precision floating-point value. The
+format string will be used to output the result of the variable evaluation,
+so you do not have to define a temporary "format-style variable"_variable.html.
+This may be used for formatting print output:
+
+print "Final energy per atom: $(pe/atoms:%10.3f) eV/atom" :pre
+
 Note that neither the curly-bracket or immediate form of variables can
 contain nested $ characters for other variables to substitute for.
 Thus you cannot do this:
diff --git a/src/input.cpp b/src/input.cpp
index b83a3683e4..f2afa34287 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -516,7 +516,14 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
         if (var[i] == '\0') error->one(FLERR,"Invalid immediate variable");
         var[i] = '\0';
         beyond = ptr + strlen(var) + 3;
-        sprintf(immediate,"%.20g",variable->compute_equal(var));
+        // check if an inline format specifier was given
+        char fmtstr[64] = "%.20g";
+        char *fmtflag;
+        if ((fmtflag=strrchr(var, ':')) && (fmtflag[1]=='%')) {
+          strncpy(fmtstr,&fmtflag[1],sizeof(fmtstr)-1);
+          *fmtflag='\0';
+        }
+        sprintf(immediate,fmtstr,variable->compute_equal(var));
         value = immediate;
 
         // single character variable name, e.g. $a
-- 
GitLab