This reminds me. I added a boilerplate reduction helper
in the pvAccessCPP module. This has now appeared in several
epics 7.0 releases.
Usage looks like:
> #include <pv/iocshelper.h>
> void startPVAServer(const char *names) ...
> ...
> void someRegistar() {
> epics::iocshRegister<const char*, &startPVAServer>("startPVAServer", "provider names");
Ugly, still somewhat repetitive ('const char*' appears twice),
and currently only for functions with between 0 and 3 arguments
due to the limitations of c++98.
https://github.com/epics-base/pvAccessCPP/blob/master/src/ioc/pv/iocshelper.h
On 4/26/19 8:44 AM, Benjamin Franksen via Tech-talk wrote:
> 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:
signature.asc
Description: OpenPGP digital signature
- Replies:
- Re: gen_iocsh_reg.pl Johnson, Andrew N. via Tech-talk
- References:
- gen_iocsh_reg.pl Benjamin Franksen via Tech-talk
- Navigate by Date:
- Prev:
Re: Stopping IOC boot on failure to load database Ralph Lange via Tech-talk
- Next:
Re: Stopping IOC boot on failure to load database Johnson, Andrew N. via Tech-talk
- 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
2025
- Navigate by Thread:
- Prev:
Re: gen_iocsh_reg.pl Benjamin Franksen via Tech-talk
- Next:
Re: gen_iocsh_reg.pl Johnson, Andrew N. via Tech-talk
- 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
2025
|