Line data Source code
1 : /**
2 : * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
3 : *
4 : * @brief Add a type to the internalnotification plugin.
5 : *
6 : * Additional required steps:
7 : * - Export the register function using INTERNALNOTIFICATION_EXPORT_FUNCTION in elektraInternalnotificationGet()
8 : * - Update testmod_internalnotification.c: Generate additional test cases using the create_type_tests supermacro
9 : * - Update kdbnotification.h: add a ELEKTRA_NOTIFICATION_TYPE_DECLARATION
10 : * - Update libs/notification/notification.c: add a ELEKTRA_NOTIFICATION_TYPE_DEFINITION
11 : *
12 : * This supermacro creates the following functions:
13 : * - void elektraInternalnotificationConvertTYPE_NAME (Key * key, void * context)
14 : * - int elektraInternalnotificationRegisterTYPE_NAME (Plugin * handle, Key * key, TYPE * variable)
15 : *
16 : * @param TYPE valid C type (e.g. int or kdb_short_t)
17 : * @param TYPE_NAME name suffix for the functions (e.g. Int or UnsignedLong)
18 : * @param VALUE_TYPE optional, defaults to TYPE. Ideally a larger type assigned to variable `value` for
19 : * checking the range before the variable is updated
20 : * @param TO_VALUE expression for converting `string` (variable containing the key value) to VALUE_TYPE
21 : * @param CHECK_CONVERSION optional, defaults to true. A boolean expression. Allows to check the range after
22 : * conversion. Use INTERNALNOTIFICATION_CHECK_CONVERSION to check if a conversion using
23 : * strto*()-functions was successful and INTERNALNOTIFICATION_CHECK_CONVERSION_RANGE (RANGE)
24 : * to check additionally for a specified range.
25 : */
26 : #ifndef TYPE
27 : #error "You have to #define TYPE, TYPE_NAME and TO_VALUE before including the addType supermacro"
28 : #endif
29 : #ifndef VALUE_TYPE
30 : // use type as default if not set
31 : #define VALUE_TYPE TYPE
32 : #endif
33 : #ifndef TYPE_NAME
34 : #error "You have to #define TYPE, TYPE_NAME and TO_VALUE before including the addType supermacro"
35 : #endif
36 : #ifndef TO_VALUE
37 : #error "You have to #define TYPE, TYPE_NAME and TO_VALUE before including the addType supermacro"
38 : #endif
39 : #ifndef CHECK_CONVERSION
40 : #define CHECK_CONVERSION 1
41 : #endif
42 :
43 : #define INTERNALNOTIFICATION_CONVERSION_FUNCTION_NAME(TYPE_NAME) ELEKTRA_CONCAT (elektraInternalnotificationConvert, TYPE_NAME)
44 : #define INTERNALNOTIFICATION_CONVERSION_CALLBACK_NAME(TYPE_NAME) ELEKTRA_CONCAT (elektraInternalnotificationConvertCallback, TYPE_NAME)
45 :
46 : #define INTERNALNOTIFICATION_REGISTER_SIGNATURE(TYPE, TYPE_NAME) \
47 : int INTERNALNOTIFICATION_REGISTER_NAME (TYPE_NAME) (Plugin * handle, Key * key, TYPE * variable)
48 :
49 : #define INTERNALNOTIFICATION_CONVERSION_CALLBACK_SIGNATURE(TYPE_NAME) \
50 : void INTERNALNOTIFICATION_CONVERSION_CALLBACK_NAME (TYPE_NAME) (Key * key, void * context)
51 :
52 : #define DISABLE_UNDEF_PARAMETERS
53 : #define NAME_MACRO INTERNALNOTIFICATION_CONVERSION_FUNCTION_NAME
54 : #include <macros/type_create_to_value.h>
55 :
56 92 : INTERNALNOTIFICATION_CONVERSION_CALLBACK_SIGNATURE (TYPE_NAME)
57 : {
58 92 : _ElektraInternalnotificationConversionContext * ctx = (_ElektraInternalnotificationConversionContext *) context;
59 92 : TYPE * variable = (TYPE *) ctx->variable;
60 92 : if (!INTERNALNOTIFICATION_CONVERSION_FUNCTION_NAME (TYPE_NAME) (key, variable))
61 : {
62 42 : if (ctx->errorCallback)
63 : {
64 2 : ctx->errorCallback (key, ctx->errorCallbackContext);
65 : }
66 : }
67 92 : }
68 :
69 92 : INTERNALNOTIFICATION_REGISTER_SIGNATURE (TYPE, TYPE_NAME)
70 : {
71 92 : PluginState * pluginState = elektraPluginGetData (handle);
72 92 : ELEKTRA_ASSERT (pluginState != NULL, "plugin state was not initialized properly");
73 :
74 92 : _ElektraInternalnotificationConversionContext * context = elektraMalloc (sizeof *context);
75 92 : if (context == NULL)
76 : {
77 : return 0;
78 : }
79 92 : context->errorCallback = pluginState->conversionErrorCallback;
80 92 : context->errorCallbackContext = pluginState->conversionErrorCallbackContext;
81 92 : context->variable = variable;
82 :
83 92 : KeyRegistration * registeredKey = elektraInternalnotificationAddNewRegistration (
84 : pluginState, key, INTERNALNOTIFICATION_CONVERSION_CALLBACK_NAME (TYPE_NAME), context, 1);
85 92 : if (registeredKey == NULL)
86 : {
87 : return 0;
88 : }
89 92 : return 1;
90 : }
91 :
92 : #undef INTERNALNOTIFICATION_CONVERSION_CALLBACK_NAME
93 : #undef INTERNALNOTIFICATION_CONVERSION_FUNCTION_NAME_SIGNATURE
94 : #undef INTERNALNOTIFICATION_CONVERSION_CALLBACK_SIGNATURE
95 : #undef INTERNALNOTIFICATION_REGISTER_SIGNATURE
96 : #undef NAME_MACRO
97 :
98 : #undef TYPE
99 : #undef VALUE_TYPE
100 : #undef TYPE_NAME
101 : #undef TO_VALUE
102 : #undef CHECK_CONVERSION
103 : #undef PRE_CHECK_BLOCK
104 : #undef PRE_CHECK_CONVERSION
|