On Thu, 2010-08-19 at 21:03 -0700, Eric Norum wrote:
> Have a look at 'postfix()' and 'calcPerform()' in the appDevGuide.
>
Perfect! Here's a new version of the patch, bit less trivial, that uses
postfix() and calcPerform(). Now you can use any CALC-compatible
expression for the mask, provided that it doesn't contain whitespace,
commas, or parentheses.
I normally try not to commit code on Friday afternoons, but this patch
is pretty simple so I think I'm safe. ;)
- Angus
Slightly O/T: Having now encountered various pieces of parser code in
EPICS, it seems to me that many places in the framework would benefit
from using a tokenizer/parser framework. It seems like a few standard
syntaxes could be applied to most of the parsing done around the place.
Of course I know that's quite a big job. I wish I had time to volunteer
to try and implement it, but I thought I'd mention it as a talking point
anyway because it's been bothering me. :).
Index: asyn/devEpics/asynEpicsUtils.c
===================================================================
--- asyn/devEpics/asynEpicsUtils.c (revision 21)
+++ asyn/devEpics/asynEpicsUtils.c (working copy)
@@ -26,6 +26,7 @@
#include <shareLib.h>
#include "asynEpicsUtils.h"
#include <epicsExport.h>
+#include <postfix.h>
static asynStatus parseLink(asynUser *pasynUser, DBLINK *plink,
char **port, int *addr, char **userParam);
@@ -155,7 +156,42 @@
}
return(asynSuccess);
}
-
+
+
+// Scan a value for a bitmask, which can be any CALC-compatible value
+// that does not contain whitespace, commas or parentheses
+epicsUInt32 scanMaskValue(char *start, char **end)
+{
+ // find the end of this expression
+ *end = start;
+ while(!isspace(**end) && **end != 0 && **end != ')' && **end != ',') (*end)++;
+
+ // Make a temporary complete infix string from start to end
+ char endChar = **end;
+ **end = 0;
+
+ // Build the postfix expression
+ char pfix[INFIX_TO_POSTFIX_SIZE(strlen(start)+1)];
+ short error;
+ long res = postfix(start, pfix, &error);
+
+ **end = endChar; // fix the source string back up
+ if(res) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ double result;
+ res = calcPerform(NULL, &result, pfix);
+ if(res) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ errno=0;
+ return (epicsUInt32) result;
+}
+
static asynStatus parseLinkMask(asynUser *pasynUser, DBLINK *plink,
char **port, int *addr, epicsUInt32 *mask,char **userParam)
{
@@ -196,7 +232,7 @@
pnext = skipWhite(pnext,1);
if(*pnext==0 || *pnext==')') goto error;
errno = 0;
- *mask = strtoul(pnext,&endp,0);
+ *mask = scanMaskValue(pnext, &endp);
if(errno) goto error;
/*next is timeout*/
pnext = endp;
Index: documentation/asynDriver.html
===================================================================
--- documentation/asynDriver.html (revision 21)
+++ documentation/asynDriver.html (working copy)
@@ -3933,7 +3933,11 @@
interface asynUInt32Digital. The INP or OUT field must define asynMask. The mask
specified in the argument to asynMask is used in the calls to asynUInt32Digital
methods. In addition it is used to set the mask fields in bi and bo records and
- the mask and shft fields in mbbi, mbbo, mbbiDirect, and mbboDirect records.</p>
+ the mask and shft fields in mbbi, mbbo, mbbiDirect, and mbboDirect records. Mask
+ values can be specified as decimal or hexadecimal integers, or simple mathematical
+ expressions like 1<<9, 1+2, or ~0x3. Acceptable mask expressions are any that
+ would be accepted by the CALC record, provided they contain no whitespace, commas
+ or parentheses.)</p>
<ul>
<li>biRecord
<p>
@@ -3992,7 +3996,7 @@
Binary Output Example Record</p>
<pre>record(bo,"boUInt32Bit2") {
field(DTYP,"asynUInt32Digital")
- field(OUT,"@asynMask( $(port) , 0, 0x4 , 1.0) ")
+ field(OUT,"@asynMask( $(port) , 0, 1<<2 , 1.0) ")
field(ZNAM,"zero")
field(ONAM,"one")
}</pre>
- References:
- Small patch for asynMask bitmask values Angus Gratton
- Re: Small patch for asynMask bitmask values Eric Norum
- Re: Small patch for asynMask bitmask values Angus Gratton
- Re: Small patch for asynMask bitmask values Eric Norum
- Navigate by Date:
- Prev:
Re: Asyn and I/O intr scanning Hinko Kocevar
- Next:
msi again Benjamin Franksen
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
<2010>
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: Small patch for asynMask bitmask values Eric Norum
- Next:
msi again Benjamin Franksen
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
<2010>
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|