git ls-files modules/database/src/ioc|egrep '\.[hc]p*$' | xargs sed -i \ -e 's|epicsShareFunc|DBCORE_API|g' \ -e 's|epicsShareClass|DBCORE_API|g' \ -e 's|epicsShareExtern|DBCORE_API extern|g' \ -e 's|epicsShareDef\s*||g' \ -e 's|shareLib\.h|dbCoreAPI.h|g' \ -e 's|epicsShareAPI|epicsStdCall|g' \ -e '/#define\s*epicsExportSharedSymbols/d'
320 lines
11 KiB
C
320 lines
11 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2010 Brookhaven National Laboratory.
|
|
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
|
|
* für Materialien und Energie GmbH.
|
|
* Copyright (c) 2014 ITER Organization.
|
|
* 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: Ralph Lange <Ralph.Lange@gmx.de>
|
|
*/
|
|
|
|
/* Based on the linkoptions utility by Michael Davidsaver (BNL) */
|
|
|
|
#ifndef CHFPLUGIN_H
|
|
#define CHFPLUGIN_H
|
|
|
|
#include <dbCoreAPI.h>
|
|
#include <dbDefs.h>
|
|
#include <epicsTypes.h>
|
|
#include <dbChannel.h>
|
|
|
|
struct db_field_log;
|
|
|
|
/** @file chfPlugin.h
|
|
* @brief Channel filter simplified plugins.
|
|
*
|
|
* Utility layer to allow an easier (reduced) interface for
|
|
* channel filter plugins.
|
|
*
|
|
* Parsing the configuration arguments of a channel filter plugin
|
|
* is done according to an argument description table provided by the plugin.
|
|
* The parser stores the results directly into a user supplied structure
|
|
* after appropriate type conversion.
|
|
*
|
|
* To specify the arguments, a chfPluginArgDef table must be defined
|
|
* for the user structure. This table has to be specified when the plugin registers.
|
|
*
|
|
* The plugin is responsible to register an init function using
|
|
* epicsExportRegistrar() and the accompanying registrar() directive in the dbd,
|
|
* and call chfPluginRegister() from within the init function.
|
|
*
|
|
* For example:
|
|
*
|
|
* typedef struct myStruct {
|
|
* ... other stuff
|
|
* char mode;
|
|
* epicsInt32 ival;
|
|
* double dval;
|
|
* epicsInt32 ival2;
|
|
* int enumval;
|
|
* char strval[20];
|
|
* char boolval;
|
|
* } myStruct;
|
|
*
|
|
* static const
|
|
* chfPluginEnumType colorEnum[] = { {"Red",1}, {"Green",2}, {"Blue",3}, {NULL,0} };
|
|
*
|
|
* static const
|
|
* chfPluginDef myStructDef[] = {
|
|
* chfTagInt32(myStruct, ival, "Integer" , ival2, 3, 0, 0),
|
|
* chfInt32 (myStruct, ival2, "Second" , 1, 0),
|
|
* chfDouble (myStruct, dval, "Double" , 1, 0),
|
|
* chfString (myStruct, strval , "String" , 1, 0),
|
|
* chfEnum (myStruct, enumval, "Color" , 1, 0, colorEnum),
|
|
* chfBoolean (myStruct, boolval, "Bool" , 1, 0),
|
|
* chfPluginEnd
|
|
* };
|
|
*
|
|
* Note: The 4th argument specifies the parameter to be required (1) or optional (0),
|
|
* the 5th whether converting to the required type is allowed (1), or
|
|
* type mismatches are an error (0).
|
|
* Note: The "Tag" version has two additional arguments. the 4th arg specifies the tag
|
|
* field (integer type) inside the structure to be set, the 5th arg specifies the
|
|
* value to set the tag field to. Arguments 6 and 7 specify "required" and
|
|
* "conversion" as described above.
|
|
*
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** @brief Channel filter simplified plugin interface.
|
|
*
|
|
* The routines in this structure must be implemented by each filter plugin.
|
|
*/
|
|
typedef struct chfPluginIf {
|
|
|
|
/* Memory management */
|
|
/** @brief Allocate private resources.
|
|
*
|
|
* <em>Called before parsing starts.</em>
|
|
* The plugin should allocate its per-instance structures,
|
|
* returning a pointer to them or NULL requesting an abort of the operation.
|
|
*
|
|
* allocPvt may be set to NULL, if no resource allocation is needed.
|
|
*
|
|
* @return Pointer to private structure, NULL if operation is to be aborted.
|
|
*/
|
|
void * (* allocPvt) (void);
|
|
|
|
/** @brief Free private resources.
|
|
*
|
|
* <em>Called as part of abort or shutdown.</em>
|
|
* The plugin should release any resources allocated for this filter;
|
|
* no further calls through this interface will be made.
|
|
*
|
|
* freePvt may be set to NULL, if no resources need to be released.
|
|
*
|
|
* @param pvt Pointer to private structure.
|
|
*/
|
|
void (* freePvt) (void *pvt);
|
|
|
|
/* Parameter parsing results */
|
|
/** @brief A parsing error occurred.
|
|
*
|
|
* <em>Called after parsing failed with an error.</em>
|
|
*
|
|
* @param pvt Pointer to private structure.
|
|
*/
|
|
void (* parse_error) (void *pvt);
|
|
|
|
/** @brief Configuration has been parsed successfully.
|
|
*
|
|
* <em>Called after parsing has finished ok.</em>
|
|
* The plugin may check the validity of the parsed data,
|
|
* returning -1 to request an abort of the operation.
|
|
*
|
|
* @param pvt Pointer to private structure.
|
|
* @return 0 for success, -1 if operation is to be aborted.
|
|
*/
|
|
int (* parse_ok) (void *pvt);
|
|
|
|
/* Channel operations */
|
|
/** @brief Open channel.
|
|
*
|
|
* <em>Called as part of the channel connection setup.</em>
|
|
*
|
|
* @param chan dbChannel for which the connection is being made.
|
|
* @param pvt Pointer to private structure.
|
|
* @return 0 for success, -1 if operation is to be aborted.
|
|
*/
|
|
long (* channel_open) (dbChannel *chan, void *pvt);
|
|
|
|
/** @brief Register callbacks for pre-event-queue operation.
|
|
*
|
|
* <em>Called as part of the channel connection setup.</em>
|
|
*
|
|
* This function is called to establish the stack of plugins that an event
|
|
* is passed through between the database and the event queue.
|
|
*
|
|
* The plugin must set pe_out to point to its own post-event callback in order
|
|
* to be called when a data update is sent from the database towards the
|
|
* event queue.
|
|
*
|
|
* The plugin may find out the type of data it will receive by looking at 'probe'.
|
|
* If the plugin will change the data type and/or size, it must update 'probe'
|
|
* accordingly.
|
|
*
|
|
* @param chan dbChannel for which the connection is being made.
|
|
* @param pvt Pointer to private structure.
|
|
* @param cb_out Pointer to this plugin's post-event callback (NULL to bypass
|
|
* this plugin).
|
|
* @param arg_out Argument that must be supplied when calling
|
|
* this plugin's post-event callback.
|
|
*/
|
|
void (* channelRegisterPre) (dbChannel *chan, void *pvt,
|
|
chPostEventFunc **cb_out, void **arg_out,
|
|
db_field_log *probe);
|
|
|
|
/** @brief Register callbacks for post-event-queue operation.
|
|
*
|
|
* <em>Called as part of the channel connection setup.</em>
|
|
*
|
|
* This function is called to establish the stack of plugins that an event
|
|
* is passed through between the event queue and the final user (CA server or
|
|
* database access).
|
|
*
|
|
* The plugin must set pe_out to point to its own post-event callback in order
|
|
* to be called when a data update is sent from the event queue towards the
|
|
* final user.
|
|
*
|
|
* The plugin may find out the type of data it will receive by looking at 'probe'.
|
|
* If the plugin will change the data type and/or size, it must update 'probe'
|
|
* accordingly.
|
|
*
|
|
* @param chan dbChannel for which the connection is being made.
|
|
* @param pvt Pointer to private structure.
|
|
* @param cb_out Pointer to this plugin's post-event callback (NULL to bypass
|
|
* this plugin).
|
|
* @param arg_out Argument that must be supplied when calling
|
|
* this plugin's post-event callback.
|
|
*/
|
|
void (* channelRegisterPost) (dbChannel *chan, void *pvt,
|
|
chPostEventFunc **cb_out, void **arg_out,
|
|
db_field_log *probe);
|
|
|
|
/** @brief Channel report request.
|
|
*
|
|
* <em>Called as part of show... routines.</em>
|
|
*
|
|
* @param chan dbChannel for which the report is requested.
|
|
* @param pvt Pointer to private structure.
|
|
* @param level Interest level.
|
|
* @param indent Number of spaces to print before each output line.
|
|
*/
|
|
void (* channel_report) (dbChannel *chan, void *pvt, int level, const unsigned short indent);
|
|
|
|
/** @brief Channel close request.
|
|
*
|
|
* <em>Called as part of connection shutdown.</em>
|
|
* @param chan dbChannel for which the connection is being shut down.
|
|
* @param pvt Pointer to private structure.
|
|
*/
|
|
void (* channel_close) (dbChannel *chan, void *pvt);
|
|
|
|
} chfPluginIf;
|
|
|
|
typedef enum chfPluginArg {
|
|
chfPluginArgInvalid=0,
|
|
chfPluginArgBoolean,
|
|
chfPluginArgInt32,
|
|
chfPluginArgDouble,
|
|
chfPluginArgString,
|
|
chfPluginArgEnum
|
|
} chfPluginArg;
|
|
|
|
typedef struct chfPluginEnumType {
|
|
const char *name;
|
|
const int value;
|
|
} chfPluginEnumType;
|
|
|
|
typedef struct chfPluginArgDef {
|
|
const char * name;
|
|
chfPluginArg optType;
|
|
unsigned int required:1;
|
|
unsigned int convert:1;
|
|
unsigned int tagged:1;
|
|
epicsUInt32 tagOffset;
|
|
epicsUInt32 choice;
|
|
epicsUInt32 dataOffset;
|
|
epicsUInt32 size;
|
|
const chfPluginEnumType *enums;
|
|
} chfPluginArgDef;
|
|
|
|
/* Simple arguments */
|
|
|
|
#define chfInt32(Struct, Member, Name, Req, Conv) \
|
|
{Name, chfPluginArgInt32, Req, Conv, 0, 0, 0, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfBoolean(Struct, Member, Name, Req, Conv) \
|
|
{Name, chfPluginArgBoolean, Req, Conv, 0, 0, 0, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfDouble(Struct, Member, Name, Req, Conv) \
|
|
{Name, chfPluginArgDouble, Req, Conv, 0, 0, 0, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfString(Struct, Member, Name, Req, Conv) \
|
|
{Name, chfPluginArgString, Req, Conv, 0, 0, 0, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfEnum(Struct, Member, Name, Req, Conv, Enums) \
|
|
{Name, chfPluginArgEnum, Req, Conv, 0, 0, 0, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums}
|
|
|
|
/* Tagged arguments */
|
|
|
|
#define chfTagInt32(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
|
{Name, chfPluginArgInt32, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfTagBoolean(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
|
{Name, chfPluginArgBoolean, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfTagDouble(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
|
{Name, chfPluginArgDouble, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfTagString(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
|
{Name, chfPluginArgString, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
|
|
|
#define chfTagEnum(Struct, Member, Name, Tag, Choice, Req, Conv, Enums) \
|
|
{Name, chfPluginArgEnum, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
|
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums}
|
|
|
|
#define chfPluginArgEnd {0}
|
|
|
|
/* Extra output when parsing and converting */
|
|
#define CHFPLUGINDEBUG 1
|
|
|
|
/** @brief Return the string associated with Enum index 'i'.
|
|
*
|
|
* @param Enums A null-terminated array of string/integer pairs.
|
|
* @param i An Enum index.
|
|
* @param def String to be returned when 'i' isn't a valid Enum index.
|
|
* @return The string associated with 'i'.
|
|
*/
|
|
DBCORE_API const char* chfPluginEnumString(const chfPluginEnumType *Enums, int i, const char* def);
|
|
|
|
/** @brief Register a plugin.
|
|
*
|
|
* @param key The plugin name key that clients will use.
|
|
* @param pif Pointer to the plugin's interface.
|
|
* @param opts Pointer to the configuration argument description table.
|
|
*/
|
|
DBCORE_API int chfPluginRegister(const char* key, const chfPluginIf *pif, const chfPluginArgDef* opts);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // CHFPLUGIN_H
|