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
<2021>
2022
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
<2021>
2022
2023
2024
2025
|