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  <20122013  2014  2015  2016  2017  2018  2019  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019 
<== Date ==> <== Thread ==>

Subject: Two DBD utility functions
From: Dirk Zimoch <dirk.zimoch@psi.ch>
To: EPICS <tech-talk@aps.anl.gov>
Date: Wed, 06 Jun 2012 14:29:37 +0200
Hi all,

Some time ago, I have written two utility function to manipulate the EPICS dbd from the startup script. Some colleagues convinced me to share them with you.

These are updateMenuConvert and addScan <rate>. They allow to add entries to menuConvert and menuScan from the startup script (before iocInit of course). You do not have to modify the main dbd file manually any more.

Both functions should work with any version of base from 3.13 or 3.14.

* updateMenuConvert

This function adds all break tables that are loaded but not available in menuConvert to the end of menuConvert (in no particular order). Thus to add a new break table, simply load it with dbLoadDatabase and then call updateMenuConvert.

Example:
dbLoadDatabase breaktable1.dbd
dbLoadDatabase breaktable2.dbd
updateMenuConvert

* addScan

This function adds a new scan rate and inserts it at the right place into menuScan.

Example:
addScan 500
addScan 0.001
addScan .3

Add a new scan rate before you load a record that uses it. Adding an already existing rate is safe.

vxWorks users: The argument is actually a string and must be quoted on the vxWorks shell. The reason is the buggy vxWorks shell on powerPC that cannot handle floating point arguments.

Source code is attached. I have tested it on Linux and vxWorks but not yet on Windows. Please have a look and report bugs back to me.

Dirk



/* addScan.c
*
*  add a new scan rate to the ioc
*
*  $Author: zimoch $
*
*  $Source: /cvs/G/DRV/misc/addScan.c,v $
*
*/

#include <string.h>
#include <stdlib.h>
#include <dbScan.h>
#include <dbStaticLib.h>
#include <dbAccess.h>
#include <epicsVersion.h>
#ifdef BASE_VERSION
#define EPICS_3_13
extern DBBASE *pdbbase;
#else
#define EPICS_3_14
#include <iocsh.h>
#include <epicsExport.h>
#endif


int addScan (char* ratestr)
{
    dbMenu  *menuScan;
    int     l, i, j, nChoice;   
    char    **papChoiceName;      
    char    **papChoiceValue;
    double  rate, r;
    char    dummy;
    char    *name;
    
    if (interruptAccept)
    {
        fprintf(stderr, "addScan: Can add a scan period only before iocInit!\n");
        return -1;
    }
    if (!ratestr || sscanf (ratestr, "%lf%c", &rate, &dummy) != 1 || rate <= 0)
    {
        fprintf(stderr, "addScan: Argument '%s' must be a number > 0\n", ratestr);
        return -1;
    }    
    menuScan = dbFindMenu(pdbbase,"menuScan");
    nChoice = menuScan->nChoice;
    for (i=SCAN_1ST_PERIODIC; i < nChoice; i++)
    {
        r = strtod(menuScan->papChoiceValue[i], NULL);
        if (r == rate)
        {
            fprintf(stderr, "addScan: rate %s already available\n", menuScan->papChoiceValue[i]);
            return 0;
        }
        if (r < rate) break;
    }
    papChoiceName=dbCalloc(nChoice+1,sizeof(char*));
    papChoiceValue=dbCalloc(nChoice+1,sizeof(char*));
    for (j=0; j < i; j++)
    {
        papChoiceName[j] = menuScan->papChoiceName[j];
        papChoiceValue[j] = menuScan->papChoiceValue[j];
    }
    name = ratestr;
    while (name[0]=='0') name++;
    l = strlen(name);
    papChoiceValue[i] = dbCalloc(l+16,1);
    strcpy(papChoiceValue[i], name);
    strcpy(papChoiceValue[i]+l, " second");
    for (j=i; j < nChoice; j++)
    {
        papChoiceName[j+1] = menuScan->papChoiceName[j];
        papChoiceValue[j+1] = menuScan->papChoiceValue[j];
    }
    free(menuScan->papChoiceName);
    free(menuScan->papChoiceValue);
    menuScan->papChoiceName=papChoiceName;
    menuScan->papChoiceValue=papChoiceValue;
    menuScan->nChoice = nChoice+1;
    return 0;    
}

#ifdef EPICS_3_14
static const iocshArg addScanArg0 = { "rate", iocshArgString };
static const iocshArg * const addScanArgs[1] = { &addScanArg0 };
static const iocshFuncDef addScanDef = { "addScan", 1, addScanArgs };
static void addScanFunc (const iocshArgBuf *args)
{
    addScan(args[0].sval);
}
static void addScanRegister(void)
{
    static int firstTime = 1;
    if (firstTime) {
        iocshRegister (&addScanDef, addScanFunc);
        firstTime = 0;
    }
}
epicsExportRegistrar(addScanRegister);
#endif

registrar(addScanRegister)
/* updateMenuConvert.c
*
*  add all breakpoint tables found on this ioc
*  to the menu convert (used by LINR field)
*
*  $Author: zimoch $
*
*  $Source: /cvs/G/DRV/misc/updateMenuConvert.c,v $
*
*/

#include <string.h>
#include <ellLib.h>
#include <stdlib.h>
#include <dbScan.h>
#include <dbStaticLib.h>
#include <dbAccess.h>
#include <epicsVersion.h>
#ifdef BASE_VERSION
#define EPICS_3_13
extern DBBASE *pdbbase;
#else
#define EPICS_3_14
#include <iocsh.h>
#include <epicsExport.h>
#endif

typedef struct node {
    ELLNODE node;
    char    *name;
    char    *value;
} node;

int updateMenuConvert ()
{
    brkTable *pbrkTable;
    dbMenu   *menuConvert;
    ELLLIST  missing;              
    node     *pbtable;               
    int      l, i, found, nChoice;   
    char     **papChoiceName;      
    char     **papChoiceValue;     
    
    if (interruptAccept)
    {
        fprintf(stderr, "updateMenuConvert: Can update menuConvert only before iocInit!\n");
        return -1;
    }
    menuConvert = dbFindMenu(pdbbase,"menuConvert");
    ellInit(&missing);
    for(pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList);
        pbrkTable;
        pbrkTable = (brkTable *)ellNext(&pbrkTable->node))
    {
        found=0;
        for(i=0; i<menuConvert->nChoice; i++)
        {
            if (strcmp(menuConvert->papChoiceValue[i],pbrkTable->name)==0)
            {
                found=1;
                break;
            }
        }
        if (!found)
        {
            pbtable = dbCalloc(1,sizeof(struct node));
            l=strlen(pbrkTable->name);
            pbtable->name = dbCalloc(l+12,1);
            pbtable->value = dbCalloc(l+1,1);
            strcpy(pbtable->name, "menuConvert");
            strcpy(pbtable->name+11, pbrkTable->name);
            strcpy(pbtable->value, pbrkTable->name);
            ellAdd(&missing, &pbtable->node);
        }
    }
    if (ellCount(&missing))
    {
        nChoice = menuConvert->nChoice + ellCount(&missing);
        
        papChoiceName=dbCalloc(nChoice,sizeof(char*));
        papChoiceValue=dbCalloc(nChoice,sizeof(char*));
        for (i=0; i<menuConvert->nChoice; i++)
        {
            papChoiceName[i] = menuConvert->papChoiceName[i];
            papChoiceValue[i] = menuConvert->papChoiceValue[i];
        }
        for (; i<nChoice; i++)
        {
            pbtable = (node*)ellFirst(&missing);
            papChoiceName[i] = pbtable->name;
            papChoiceValue[i] = pbtable->value;
            ellDelete(&missing, &pbtable->node);
        }
        free(menuConvert->papChoiceName);
        free(menuConvert->papChoiceValue);
        menuConvert->papChoiceName=papChoiceName;
        menuConvert->papChoiceValue=papChoiceValue;
        menuConvert->nChoice = nChoice;
    }
    return 0;
}

#ifdef EPICS_3_14
static const iocshFuncDef updateMenuConvertDef = { "updateMenuConvert", 0, NULL };
static void updateMenuConvertFunc (const iocshArgBuf *args)
{
    updateMenuConvert();
}
static void updateMenuConvertRegister(void)
{
    static int firstTime = 1;
    if (firstTime) {
        iocshRegister (&updateMenuConvertDef, updateMenuConvertFunc);
        firstTime = 0;
    }
}
epicsExportRegistrar(updateMenuConvertRegister);
#endif

registrar(updateMenuConvertRegister)

Navigate by Date:
Prev: Re: [CSS] text edit + Go! button Kasemir, Kay
Next: Re: [CSS] text edit + Go! button Pavel Masloff
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019 
Navigate by Thread:
Prev: Re: [CSS] text edit + Go! button Pavel Masloff
Next: EPICS Compile error: cannot find -lrtemscpu on Windows using mingw Yoram Fisher
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·