|
|
Experimental Physics and
| ||||||||||||||
|
|
I recently wrote this little perl script (attached) to automate the
writing of iocsh registration code using a trivial but (I think)
complete declarative specification "language" that is easy to compose on
the command line or in a Makefile. I am posting the code and an example
of what it does in the hope that it may turn out to be useful for others.
Here is the help output (slightly re-formatted for this email):
"""
> gen_iocsh_reg.pl -h
Usage: gen_iocsh_reg.pl [REG=<registrar>] <command>=[<args>] ...
where
<registrar> is the name of a C function to register the commands (if
not specified you'll have to call iocshRegister yourself for each
command)
<command> is the name of a command (in C as well as in the shell)
<args> is a comma separated list of argument descriptions <arg>
<arg> describes an argument to the underlying C command and is either
* a constant literal value (for instance 0 or "a string"), or
* an iocsh argument description of the form <name>:<type> (for
instance card_number:Int) where <type> is one of {Int, Double,
String}.
Only arguments of the <name>:<type> sort are exposed as arguments to the
command in the shell.
"""
Here is a real-world example use case,. This is from a Makefile in one
of our projects:
"""
iocshExtra.c:
$(PERL) $(BII_SCRIPTS_BIN)/gen_iocsh_reg.pl REG=registerIocshExtra\
asDump=0,0,verbosity:Int \
bootShow= bootChange= \
gevShow= gevDelete=name:String
gevUpdate=name:String,value:String > $@
"""
From this it generates the following boilerplate code:
"""
/*
* IOC shell command registration
*/
#include "epicsExport.h"
#include "iocsh.h"
static const iocshArg asDumpArg0 = { "verbosity", iocshArgInt };
static const iocshArg *const asDumpArgs[] = {
&asDumpArg0
};
static const iocshFuncDef asDumpDef = {"asDump", 1, asDumpArgs};
static void asDumpWrapper(const iocshArgBuf *args) {
asDump(0, 0, args[0].ival);
}
static const iocshArg *const bootChangeArgs[] = {};
static const iocshFuncDef bootChangeDef = {"bootChange", 0, bootChangeArgs};
static void bootChangeWrapper(const iocshArgBuf *args) {
bootChange();
}
static const iocshArg *const bootShowArgs[] = {};
static const iocshFuncDef bootShowDef = {"bootShow", 0, bootShowArgs};
static void bootShowWrapper(const iocshArgBuf *args) {
bootShow();
}
static const iocshArg gevDeleteArg0 = { "name", iocshArgString };
static const iocshArg *const gevDeleteArgs[] = {
&gevDeleteArg0
};
static const iocshFuncDef gevDeleteDef = {"gevDelete", 1, gevDeleteArgs};
static void gevDeleteWrapper(const iocshArgBuf *args) {
gevDelete(args[0].sval);
}
static const iocshArg *const gevShowArgs[] = {};
static const iocshFuncDef gevShowDef = {"gevShow", 0, gevShowArgs};
static void gevShowWrapper(const iocshArgBuf *args) {
gevShow();
}
static const iocshArg gevUpdateArg0 = { "name", iocshArgString };
static const iocshArg gevUpdateArg1 = { "value", iocshArgString };
static const iocshArg *const gevUpdateArgs[] = {
&gevUpdateArg0,
&gevUpdateArg1
};
static const iocshFuncDef gevUpdateDef = {"gevUpdate", 2, gevUpdateArgs};
static void gevUpdateWrapper(const iocshArgBuf *args) {
gevUpdate(args[0].sval, args[1].sval);
}
static void registerIocshExtra(void) {
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&asDumpDef, asDumpWrapper);
iocshRegister(&bootChangeDef, bootChangeWrapper);
iocshRegister(&bootShowDef, bootShowWrapper);
iocshRegister(&gevDeleteDef, gevDeleteWrapper);
iocshRegister(&gevShowDef, gevShowWrapper);
iocshRegister(&gevUpdateDef, gevUpdateWrapper);
}
}
epicsExportRegistrar(registerIocshExtra);
"""
Cheers
Ben
Attachment:
gen_iocsh_reg.pl Attachment:
signature.asc
| ||||||||||||||
| ANJ, 29 Apr 2019 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |