EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024  2025  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024  2025 
<== Date ==> <== Thread ==>

Subject: Re: [Merge] ~dirk.zimoch/epics-base:FilterForInfoFields into epics-base:7.0
From: Dirk Zimoch via Core-talk <core-talk at aps.anl.gov>
To: mp+399414 at code.launchpad.net
Date: Fri, 12 Mar 2021 08:35:22 -0000
Simon, please comment on the compiler flags.

Diff comments:

> diff --git a/modules/database/src/std/filters/filters.dbd.pod b/modules/database/src/std/filters/filters.dbd.pod
> index 27e356f..0a1757e 100644
> --- a/modules/database/src/std/filters/filters.dbd.pod
> +++ b/modules/database/src/std/filters/filters.dbd.pod
> @@ -6,15 +6,17 @@ The following filters are available in this release:
>  
>  =over
>  
> -=item * L<TimeStamp|/"TimeStamp Filter ts">
> +=item * L<TimeStamp|/TimeStamp Filter "ts">

Ok. I noticed that they were broken at the moment but if that was because of a bug in pod2Html.pl, I will revert this change.
What you are fixing pod2Html.pl: It prints a very cryptic error message when the filedoes not end with a =cut block.

>  
> -=item * L<Deadband|/"Deadband Filter dbnd">
> +=item * L<Deadband|/Deadband Filter "dbnd">
>  
> -=item * L<Array|/"Array Filter arr">
> +=item * L<Array|/Array Filter "arr">
>  
> -=item * L<Synchronize|/"Synchronize Filter sync">
> +=item * L<Synchronize|/Synchronize Filter "sync">
>  
> -=item * L<Decimation|/"Decimation Filter dec">
> +=item * L<Decimation|/Decimation Filter "dec">
> +
> +=item * L<Info Field|/Info Field Filter "info">
>  
>  =back
>  
> @@ -285,3 +287,43 @@ once every minute:
>   ...
>  
>  =cut
> +
> +registrar(infoInitialize)
> +
> +=head3 Info Field Filter C<"info">
> +
> +This filter gives access to the info fields of a record.
> +
> +=head4 Parameters
> +
> +=over
> +
> +=item Name C<"name"> or C<"n">
> +
> +The name of the info field.
> +Currently, there is an implementation limit of 50 chars
> +for the name length.
> +
> +=item Long String Flag C<"longstr"> or C<"l">
> +
> +If this optional flag is C<"yes">, C<"on">, or C<1>, the info field is returned
> +as an array of C<CHAR>.
> +If it is C<"no">, C<"off">, or C<0>, the info field is returned as a C<STRING>,
> +truncated to 40 characters if necessary.
> +The default is C<"auto">, which will use C<STRING> for sufficiently short values
> +and array of C<CHAR> for long values.
> +
> +=back
> +
> +=head4 Example
> +
> +Assuming the record C<test:channel> has:
> +
> + info(infofieldname, "value of the info field")
> +
> +To read the value of the info field:
> +
> + $ caget 'test:channel.{"info":{"name":"infofieldname"}}
> + $ caget -S 'test:channel.{"info":{"name":"infofieldname","l":"yes"}} 

I have notices that it works without quotes. I left them in the documentation to match the other examples.
I need to check what the chfPlugin allows. Maybe I can extend it.

> + 
> +=cut
> diff --git a/modules/database/src/std/filters/info.c b/modules/database/src/std/filters/info.c
> new file mode 100644
> index 0000000..5d5fb52
> --- /dev/null
> +++ b/modules/database/src/std/filters/info.c
> @@ -0,0 +1,166 @@
> +/*************************************************************************\
> +* Copyright (c) 2021 Paul Scherrer Institute
> +* SPDX-License-Identifier: EPICS
> +* EPICS BASE is distributed subject to a Software License Agreement found
> +* in file LICENSE that is included with this distribution.
> +\*************************************************************************/
> +
> +/*
> + *  Author: Dirk Zimoch <dirk.zimoch at psi.ch>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include "chfPlugin.h"
> +#include "dbStaticLib.h"
> +#include "dbAccessDefs.h"
> +#include "dbExtractArray.h"
> +#include "db_field_log.h"
> +#include "dbLock.h"
> +#include "epicsExit.h"
> +#include "freeList.h"
> +#include "epicsExport.h"
> +
> +typedef struct myStruct {
> +    char name[52];  /* arbitrary size, we better had dynamic strings */

Maybe I will extend chfPlugin to support arbitrary long strings (with char* struture field). But that's a different project.

> +    DBENTRY dbentry;
> +    int longstr;
> +} myStruct;
> +
> +static void *myStructFreeList;
> +
> +static const
> +chfPluginEnumType longstrEnum[] = {{"no",0}, {"off",0}, {"yes",1}, {"on",1}, {"auto",2}, {NULL, 0}};
> +
> +static const chfPluginArgDef opts[] = {
> +    chfString (myStruct, name,    "name",    1, 0),
> +    chfString (myStruct, name,    "n",       1, 0),
> +    chfEnum   (myStruct, longstr, "longstr", 0, 1, longstrEnum),
> +    chfEnum   (myStruct, longstr, "l",       0, 1, longstrEnum),
> +    chfPluginArgEnd
> +};
> +
> +static void * allocPvt(void)
> +{
> +    myStruct *my = (myStruct*) freeListCalloc(myStructFreeList);
> +    if (!my) return NULL;
> +    my->longstr = 2;
> +    return (void *) my;
> +}
> +
> +static void freePvt(void *pvt)
> +{
> +    freeListFree(myStructFreeList, pvt);
> +}
> +
> +static int parse_ok(void *pvt)
> +{
> +    myStruct *my = (myStruct*) pvt;
> +    if (my->name[0] == 0) /* empty name */
> +        return -1;
> +    if (my->name[sizeof(my->name)-2] != 0) /* name buffer overrun */
> +        return -1;
> +    return 0;
> +}
> +
> +static void dbfl_free(struct db_field_log *pfl)
> +{
> +    /* dummy needed for dbGet() to work correctly */
> +}
> +
> +static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl)
> +{
> +    myStruct *my = (myStruct*) pvt;
> +
> +    if (pfl->type == dbfl_type_ref && pfl->u.r.dtor)
> +        pfl->u.r.dtor(pfl);
> +    pfl->type = dbfl_type_ref;
> +    pfl->u.r.dtor = dbfl_free;
> +    pfl->u.r.field = (void*)dbGetInfoString(&my->dbentry);
> +
> +    if (my->longstr) {
> +        pfl->field_size = 1;
> +        pfl->field_type = DBF_CHAR;
> +        pfl->no_elements = strlen((char*)pfl->u.r.field)+1;
> +    } else {
> +        pfl->field_size = MAX_STRING_SIZE;
> +        pfl->field_type = DBF_STRING;
> +        pfl->no_elements = 1;
> +    }
> +    return pfl;
> +}
> +
> +static long channel_open(dbChannel *chan, void *pvt)
> +{
> +    myStruct *my = (myStruct*) pvt;
> +    DBENTRY* pdbe = &my->dbentry;
> +    int status;
> +
> +    dbInitEntryFromAddr(&chan->addr, pdbe);
> +    for (status = dbFirstInfo(pdbe); !status; status = dbNextInfo(pdbe))
> +        if (strcmp(dbGetInfoName(pdbe), my->name) == 0)
> +            return 0;
> +    return -1;
> +}
> +
> +static void channelRegisterPre(dbChannel *chan, void *pvt,
> +    chPostEventFunc **cb_out, void **arg_out, db_field_log *pfl)
> +{
> +    myStruct *my = (myStruct*) pvt;
> +    size_t len = strlen(dbGetInfoString(&my->dbentry)) + 1;
> +    if (my->longstr == 2) {
> +        my->longstr = len > MAX_STRING_SIZE;
> +    }
> +    if (my->longstr) {
> +        pfl->field_size = 1;
> +        pfl->field_type = DBF_CHAR;
> +        pfl->no_elements = len;
> +    } else {
> +        pfl->field_size = MAX_STRING_SIZE;
> +        pfl->field_type = DBF_STRING;
> +        pfl->no_elements = 1;
> +    }
> +    *cb_out = filter;
> +    *arg_out = pvt;
> +}
> +
> +static void channel_report(dbChannel *chan, void *pvt, int level,
> +    const unsigned short indent)
> +{
> +    myStruct *my = (myStruct*) pvt;
> +    printf("%*sInfo: name=%s\n", indent, "",
> +           my->name);
> +}
> +
> +static chfPluginIf pif = {
> +    allocPvt,
> +    freePvt,
> +
> +    NULL, /* parse_error, */
> +    parse_ok,
> +
> +    channel_open,
> +    channelRegisterPre,
> +    NULL, /* channelRegisterPost, */
> +    channel_report,
> +    NULL /* channel_close */
> +};
> +
> +static void infoShutdown(void* ignore)
> +{
> +    if(myStructFreeList)
> +        freeListCleanup(myStructFreeList);
> +    myStructFreeList = NULL;
> +}
> +
> +static void infoInitialize(void)
> +{
> +    if (!myStructFreeList)
> +        freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64);
> +
> +    chfPluginRegister("info", &pif, opts);
> +    epicsAtExit(infoShutdown, NULL);
> +}
> +
> +epicsExportRegistrar(infoInitialize);


-- 
https://code.launchpad.net/~dirk.zimoch/epics-base/+git/epics-base/+merge/399414
Your team EPICS Core Developers is subscribed to branch epics-base:7.0.

References:
[Merge] ~dirk.zimoch/epics-base:FilterForInfoFields into epics-base:7.0 Dirk Zimoch via Core-talk

Navigate by Date:
Prev: Base 7.0.5 / pvDatabaseCPP 4.5.3 / pvDataCPP 8.0.4 (8.1.0?) Ralph Lange via Core-talk
Next: Re: Base 7.0.5 / pvDatabaseCPP 4.5.3 / pvDataCPP 8.0.4 (8.1.0?) Ralph Lange via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024  2025 
Navigate by Thread:
Prev: Re: [Merge] ~dirk.zimoch/epics-base:FilterForInfoFields into epics-base:7.0 Ben Franksen via Core-talk
Next: Re: [Merge] ~dirk.zimoch/epics-base:FilterForInfoFields into epics-base:7.0 Dirk Zimoch via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024  2025 
ANJ, 12 Mar 2021 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions ·
· Download · Search · IRMIS · Talk · Documents · Links · Licensing ·