EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

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

Subject: Re: Automatically generate iocsh registrar code?
From: Carl Lionberger <[email protected]>
To: Susanna Jacobson <[email protected]>
Cc: EPICS tech-talk <[email protected]>
Date: Fri, 08 Jun 2007 09:19:42 -0700
Here's a perl script

Carl

Susanna Jacobson wrote:

Does anyone have a script or program that will take a set of C function declarations and generate the C code to register those functions with the iocsh?

I have 18 functions to register, some with 4 or 5 arguments.

Susanna



--
Carl Lionberger 510 486 7503
Software Developer, Engineering Division
Lawrence Berkeley National Laboratory


#!/usr/bin/perl
#
# makeRegistrar 
#
# Takes [ansi vanilla] function prototypes and produces EPICS registrar 
# function.
#

# output is to be inserted into code containing functions to be registered.
# Note the registrar function and its export call both use the program name 
# "xxx", which you need to change by hand.  

#
# be sure to include "iocsh.h" and "epicsExport.h" in the file.
#

# Example prototypes from autoSaveRestore:
#  
#    Clip these and use as test input if desired.  Remove the ^#
#
#int set_savefile_name(char *filename, char *save_filename);
#int create_periodic_set(char *filename, int period, char *macrostring);
#int create_triggered_set(char *filename, char *trigger_channel,
#        char *macrostring);
#int create_monitor_set(char *filename, int period, char *macrostring);
#int create_manual_set(char *filename, char *macrostring);
#int fdbrestore(char *filename);
#void fdblist(int verbose);
#
#int set_requestfile_path(char *path, char *pathsub);
#int set_savefile_path(char *path, char *pathsub);
#int set_saveTask_priority(int priority);
#int remove_data_set(char *filename);
#int reload_periodic_set(char *filename, int period, char *macrostring);
#int reload_triggered_set(char *filename, char *trigger_channel,
#        char *macrostring);
#int reload_monitor_set(char * filename, int period, char *macrostring);
#int reload_manual_set(char * filename, char *macrostring);
#int fdbrestoreX(char *filename);
#


#
# input
#
$i = 0;
while (<>) {
#  chomp();
   @inlist[$i] = $_;
   $i++;
}

#
# combine broken lines
#
$i = 0;$untermed=0;
foreach (@inlist) {
   if (!/;$/) {
      chomp;
      @outlist[$i] = $_;
      $untermed = 1;
   }
   else {
      if ($untermed == 1) {
         $untermed = 0; 
         @outlist[$i] = join("",@outlist[$i],$_);   
      }  else {
         @outlist[$i] = $_;
      }
      $i++;
   }
}
#print @outlist;

#get args 

$i = 0;
foreach (@outlist) {
   ($junk, $arglist) = split("[(]",$_);
   ($arglist, $junk) = split("[)]",$arglist);
   @allargs[$i] = $arglist . "\n";
   $i++;
}

#
# produce argument descriptors, arg lists, funcdefs, callfuncs
#

   $i = 0;
   $funcfound = 0;
   foreach (@allargs) {
      #
      # note that is block of code is repeated below, to catch last
      # member of list.  
      #
      if ($funcfound == 1) {
         $funcfound = 0;
         print "static const iocshArg * const ".$funcname."Args\[" . $j ."\] = {\n";
         for ($k = 0; $k < $j; $k++) {
            print "       &" . $funcname . "Arg" . $k;
            if (($k + 1) < $j) {
                print ",\n"; 
            } else { print "\};\n"}
         }
         print "static const iocshFuncDef " . $funcname . "FuncDef = {";
         print "\"". $funcname ."\"," . $j . "\," . $funcname."Args};\n";
         print "static void " . $funcname . "CallFunc\(const iocshArgBuf *args)\n";
         print "{\n";
         print "    " . $funcname . "\(";
         for ($k = 0; $k < $j; $k++) {
            print "args\[" . $k . "\]\.";
            if (@types[$k] eq "iocshArgInt") {
               print "ival"; }
            if (@types[$k] eq "iocshArgString") {
               print "sval"; }
            if (@types[$k] eq "iocshArgDouble") {
               print "dval"; }
            if (($k + 1) < $j) {
                print ","; 
            } else { print "\);\n"}
         }
         print "}\n";
      }
      ($type, $funcname) = split(/\s+/,@outlist[$i]);
      ($funcname, $junk) = split(/\(/,$funcname);
      $i++;
      @names = "";
      @types = "";
      $j = 0;
      @args = split;
      $typefound = 0;
      $charfound = 0;
      foreach (@args) {
         if ($charfound == 2) {
            $charfound = 0;
            @types[$j] = "iocshArgString";
            if (/,$/) { chop($_); }
            @names[$j] = $_;
            $funcfound = 1;
            print "static const iocshArg " . $funcname . "Arg" . $j . " = { ";
            print "\"". @names[$j] . "\",". @types[$j] . " };\n";
            $j++;
            next;
         }
         if ($charfound == 1 && /\*/ && length($_) == 1) { 
            $charfound = 2;
            next;
         }
         if ($charfound == 1 && /\*/ ) { 
            s/\*//;
            $charfound = 0;
            @types[$j] = "iocshArgString";
            if (/,$/) { chop($_); }
            @names[$j] = $_;
            $funcfound = 1;
            print "static const iocshArg " . $funcname . "Arg" . $j . " = { ";
            print "\"". @names[$j] . "\",". @types[$j] . " };\n";
            $j++;
            next;
         }
         if ($charfound == 1) {
            $charfound = 0;
            @types[$j] = "iocshArgInt";
            if (/,$/) { chop($_); }
            @names[$j] = $_;
            $funcfound = 1;
            print "static const iocshArg " . $funcname . "Arg" . $j . " = { ";
            print "\"". @names[$j] . "\",". @types[$j] . " };\n";
            $j++;
            next;
         }
         if (/char/) {
            $charfound = 1;
            next;
         }
         if (/unsigned/) {
            $unsfound = 1;
            next;
         }
         if ($intfound == 1) {
            $intfound = 0;
            @types[$j] = "iocshArgInt";
            if (/,$/) { chop($_); }
            @names[$j] = $_;
            $funcfound = 1;
            print "static const iocshArg " . $funcname . "Arg" . $j . " = { ";
            print "\"". @names[$j] . "\",". @types[$j] . " };\n";
            $j++;
            next;
         }
         if ($unsfound == 1 || /char|int|long|short/) {
            $unsfound = 0;
            $intfound = 1;
            next;
         }
         if ($doublefound ==1) {
            $doublefound = 0;
            @types[$j] = "iocshArgDouble";
            if (/,$/) { chop($_); }
            @names[$j] = $_;
            $funcfound = 1;
            print "static const iocshArg " . $funcname . "Arg" . $j . " = { ";
            print "\"". @names[$j] . "\",". @types[$j] . " };\n";
            $j++;
            next;
         }
         if (/double|float/) {
            $doublefound = 1;
            next;
         }
      }
   }
#
# this needs to be done one more time for the last function...
#

      if ($funcfound == 1) {
         $funcfound = 0;
         print "static const iocshArg * const ".$funcname."Args\[" . $j ."\] = {\n";
         for ($k = 0; $k < $j; $k++) {
            print "       &" . $funcname . "Arg" . $k;
            if (($k + 1) < $j) {
                print ",\n"; 
            } else { print "\};\n"}
         }
         print "static const iocshFuncDef " . $funcname . "FuncDef = {";
         print "\"". $funcname ."\"," . $j . "\," . $funcname."Args};\n";
         print "static void " . $funcname . "CallFunc\(const iocshArgBuf *args)\n";
         print "{\n";
         print "    " . $funcname . "\(";
         for ($k = 0; $k < $j; $k++) {
            print "args\[" . $k . "\]\.";
            if (@types[$k] eq "iocshArgInt") {
               print "ival"; }
            if (@types[$k] eq "iocshArgString") {
               print "sval"; }
            if (@types[$k] eq "iocshArgDouble") {
               print "dval"; }
            if (($k + 1) < $j) {
                print ","; 
            } else { print ");\n"}
         }
         print "}\n";
      }
#
#  end of last function work

#
# produce registrar function
#
print "\n";
print "void xxxRegister(void)\n";
print "{\n";


foreach (@outlist) {
      ($type, $funcname) = split(/\s+/,$_);
      ($funcname, $junk) = split(/\(/,$funcname);

   print "   iocshRegister(&" . $funcname . "FuncDef, " . $funcname . "CallFunc)\;\n";
}

print "}\n";

print "epicsExportRegistrar(xxxRegister)\;\n";


Replies:
Re: Automatically generate iocsh registrar code? Benjamin Franksen
References:
Automatically generate iocsh registrar code? Susanna Jacobson

Navigate by Date:
Prev: Re: the first installing jca2.1.2 problem Thomas Pelaia II
Next: EPICS channels via the Internet Doug Sheffer
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Automatically generate iocsh registrar code? Susanna Jacobson
Next: Re: Automatically generate iocsh registrar code? Benjamin Franksen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 10 Nov 2011 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·