EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: calculating macros
From: Andrew Johnson <[email protected]>
To: Dirk Zimoch <[email protected]>
Cc: EPICS <[email protected]>
Date: Mon, 6 Jun 2016 12:32:23 -0500
Hi Dirk,

This looks like a great start and works for me as promised, but I do
think the 80/20 rule applies.

You might want to start a public branch for this development so we can
use Launchpad (or github) for feedback. You can use git for code
management if you don't have/like Bazaar, although the official repo's
are still all in Bazaar on Launchpad. I would see your feature as a
candidate for either the 3.15 or 3.16 branches, but not for 3.14.

I'm attaching a patch to the macLibTest.c program that makes a start on
our request that new functionality should come with test code. 15 of my
53 new tests currently fail due to the documented limitations inherent
in your current solution; it should be possible to fix these, but it
will require better integration into the existing macLib functionality.
I hope you will be willing to work on that.

I have not attempted to write tests for your formatting operators, I'm
not 100% convinced about your syntax for that feature yet but I haven't
really played with it much.

In addition to the two (somewhat out-dated) text files macLibNOTES and
macLibREADME in the source directory there is some user documentation on
the current macro syntax in the Application Developers Guide which would
also need updating, see
http://www.aps.anl.gov/epics/base/R3-15/4-docs/AppDevGuide/node7.html#SECTION00734000000000000000
 We can help with editing this when the code is closer to being merged.

Thanks,

- Andrew


On 05/31/2016 08:51 AM, Dirk Zimoch wrote:
> Hi folks
> 
> As proposed on the EPICS meeting in Lund, I have prepared a prototype
> implementation for calculating macros (based on R3.14.12.4).
> See attached file macCore.c.
> 
> Examples
> $(3+4)
> ${  1 + 2 * (3+4)  }
> ${%#04x 0x1b + 1}
> 
> It becomes interesting when the expression itself contains macros
> (typically as operands):
> 
> epicsEnvSet i, 5
> ${ $(i)+1 }
> 
> This can be used on the shell as well as in templates.
> 
> But be careful if the inner macro looks like an expression:
> epicsEnvSet x, 1+4
> ${2*${x}}
> This gives 6, not 10. Just as with C macros.
> ${2*(${x})}
> This gives 10.
> 
> BTW, this will not fool the calculation:
> epicsEnvSet 3+4, 9
> ${3+4}
> This results in 7, not 9, which is an incompatibility to the existing
> macLib. (I just hope nobody has built major parts of the control system
> upon macro names that look like integer expressions.)
> 
> The calculation is integer only and supports the operators +-*/% as well
> as parentheses (), comparison < and >, and the if-then-else operator ?:
> (with optional 'then' operand).
> 
> Unfortunately I could not support <= >= == and != because macLib already
> interprets = as the default value operator. Don't try. The expression
> will be truncated at the =.
> 
> But with integer expressions this does not hurt too much because a<=b is
> a<b+1 and a==b is a-b?0:1.
> 
> An expression can be prefixed with an integer printf format like %#04x
> to change the resulting string. (Allowed formats: diouxXc)
> 
> If the expression contains () you cannot use $() for the calculating
> macro or the inner () are not parsed correctly. Use ${}.
> 
> 
> Please try and give feedback.
> Dirk

-- 
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon
=== modified file 'src/libCom/test/macLibTest.c'
--- src/libCom/test/macLibTest.c	2010-10-05 19:27:37 +0000
+++ src/libCom/test/macLibTest.c	2016-06-06 16:43:35 +0000
@@ -49,6 +49,8 @@
     char output[54];
     long status;
 
+    testDiag("\n# Checking for buffer overflows\n#");
+
     macPutValue(h, "OVVAR","abcdefghijklmnopqrstuvwxyz");
 
     memset(output, '~', sizeof output);
@@ -68,7 +70,7 @@
 
 MAIN(macLibTest)
 {
-    testPlan(89);
+    testPlan(142);
 
     if (macCreateHandle(&h, NULL))
         testAbort("macCreateHandle() failed");
@@ -215,6 +217,81 @@
     check("${FOO,FOO=${FOO}}", "!$(FOO,recursive)");
     check("${FOO=GRIBBLE,FOO=${FOO}}", "!$(FOO,recursive)");
 
+    testDiag("\n# Checking arithmetic expressions\n#");
+    /* These pass */
+
+    check("${1}", " 1");
+    check("${+1}", " 1");
+    check("${ 1}", " 1");
+    check("${1 }", " 1");
+    check("${+ 1}", " 1");
+
+    check("${-0}", " 0");
+    check("${-1}", " -1");
+    check("${ -1}", " -1");
+    check("${-1 }", " -1");
+    check("${- 1}", " -1");
+
+    check("${+(1)}", " 1");
+    check("${-(1)}", " -1");
+
+    check("${1+2}", " 3");
+    check("${2-1}", " 1");
+    check("${1-2}", " -1");
+    check("${1--2}", " 3");
+
+    check("${2*3}", " 6");
+    check("${6/2}", " 3");
+    check("${5%3}", " 2");
+    check("${1<2}", " 1");
+    check("${1>2}", " 0");
+
+    check("${1+2*3}", " 7");
+    check("${2*3+1}", " 7");
+    check("${1+(2*3)}", " 7");
+    check("${(2*3)+1}", " 7");
+    check("${(1+2)*3}", " 9");
+    check("${3*(1+2)}", " 9");
+
+    check("${${1+2}*3}", " 9");
+    check("${3*${1+2}}", " 9");
+
+    check("${a=${1+2}}", " 3");
+    check("${a=${b},b=${1+2}}", " 3");
+    check("${a=${${b}},b=1+2}", " 3");
+    check("${a=${${b}*3},b=1+2}", " 7");
+    check("${a=${${b}*3},b=(1+2)}", " 9");
+
+    macPutValue(h, "one","1");
+    macPutValue(h, "two","2");
+
+    check("${${one}+${two}}", " 3");
+    check("${three=${${one}+${two}}}", " 3");
+    check("${sum,sum=${${one}+${two}}}", " 3");
+
+    testDiag("\n# Failing arithmetic expressions\n#");
+    /* These fail, but should be supported */
+
+    check("$(+(1))", " 1");
+    check("$(-(1))", " -1");
+    check("$(1+(2*3))", " 7");
+    check("$((1+2)*3)", " 9");
+
+    check("${1<=2}", " 1");
+    check("${1>=2}", " 0");
+    check("${1==2}", " 0");
+    check("${1==1}", " 1");
+    check("${1!=2}", " 1");
+    check("${1!=1}", " 0");
+
+    check("${a=1+2}", " 3");
+    check("${a=${b},b=1+2}", " 3");
+    check("${a=${b}*3,b=1+2}", " 7");
+    check("${a=${b}*3,b=(1+2)}", " 9");
+
+    check("${three=${one}+${two}}", " 3");
+    check("${sum,sum=${one}+${two}}", " 3");
+
     ovcheck();
 
     return testDone();


References:
calculating macros Dirk Zimoch

Navigate by Date:
Prev: Re: CSS vs. SSL Kasemir, Kay
Next: epicsEventSignal() question Michael Westfall
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: calculating macros Dirk Zimoch
Next: Control System Engineer (ESS, Sweden) David Brodrick
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 15 Jul 2016 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·