summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--obj-types.h59
-rw-r--r--rsyslog.h1
-rw-r--r--vmop.c37
-rw-r--r--vmop.h24
-rw-r--r--vmprg.c20
5 files changed, 123 insertions, 18 deletions
diff --git a/obj-types.h b/obj-types.h
index 6fce1f8f..d823af47 100644
--- a/obj-types.h
+++ b/obj-types.h
@@ -237,6 +237,7 @@ finalize_it: \
* rgerhards, 2008-02-20
*/
#define PROTOTYPEObjDebugPrint(obj) rsRetVal obj##DebugPrint(obj##_t *pThis)
+#define INTERFACEObjDebugPrint(obj) rsRetVal (*DebugPrint)(obj##_t *pThis)
#define BEGINobjDebugPrint(obj) \
rsRetVal obj##DebugPrint(obj##_t *pThis) \
{ \
@@ -250,6 +251,64 @@ finalize_it: \
RETiRet; \
}
+/* ------------------------------ object loader system ------------------------------ *
+ * The following code is the early beginning of a dynamic object loader system. The
+ * root idea is that all objects will become dynamically loadable libraries over time,
+ * which is necessary to get a clean plug-in interface where every plugin can access
+ * rsyslog's rich object model via simple and quite portable methods.
+ *
+ * To do so, each object defines one or more interfaces. They are essentially structures
+ * with function (method) pointers. Anyone interested in calling an object must first
+ * obtain the interface and can then call through it.
+ *
+ * The interface data type must always be called <obj>_if_t, as this is expected
+ * by the macros. Having consitent naming is also easier for the programmer. By default,
+ * macros create a static variable named like the object in each calling objects
+ * static data block.
+ *
+ * To facilitate moving to this system, I begin to implement some hooks, which
+ * allows to use interfaces today (when the rest of the infrastructure is not yet
+ * there). This is in the hope that it will ease migration to the full-fledged system
+ * once we are ready to work on that.
+ * rgerhards, 2008-02-21
+ */
+
+/* this defines the QueryInterface print entry point. Over time, it should be
+ * present in all objects.
+ */
+#define PROTOTYPEObjQueryInterface(obj) rsRetVal obj##QueryInterface(obj##_if_t *pThis)
+#define BEGINobjQueryInterface(obj) \
+ rsRetVal obj##QueryInterface(obj##_if_t *pIf) \
+ { \
+ DEFiRet; \
+
+#define CODESTARTobjQueryInterface(obj) \
+ ASSERT(pIf != NULL);
+
+#define ENDobjQueryInterface(obj) \
+ RETiRet; \
+ }
+/* the base data type for interfaces
+ * This MUST be in sync with the ifBEGIN macro
+ */
+typedef struct interface_s {
+ int ifVersion; /* must be set to version requested */
+ objID_t oID; /* our object ID (later dynamically assigned) */
+} interface_t;
+
+/* defines data that must always be present at the very begin of the interface structure */
+#define ifBEGIN \
+ int ifVersion; /* must be set to version requested */ \
+ objID_t oID; /* our object ID (later dynamically assigned) */
+
+
+/* use the following define some place in your static data (suggested right at
+ * the beginning
+ */
+#define DEFobjCurrIf(obj) \
+ obj##_if_t obj = { .ifVersion = obj##CURR_IF_VERSION };
+
+/* ------------------------------ end object loader system ------------------------------ */
#endif /* #ifndef OBJ_TYPES_H_INCLUDED */
diff --git a/rsyslog.h b/rsyslog.h
index 655cf5d9..8b8ada8d 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -127,6 +127,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_SYNTAX_ERROR = -2051, /**< syntax error, eg. during parsing */
RS_RET_INVALID_OCTAL_DIGIT = -2052, /**< invalid octal digit during parsing */
RS_RET_INVALID_HEX_DIGIT = -2053, /**< invalid hex digit during parsing */
+ RS_RET_INTERFACE_NOT_SUPPORTED = -2054, /**< interface not supported */
RS_RET_OK_DELETE_LISTENTRY = 1, /**< operation successful, but callee requested the deletion of an entry (special state) */
RS_RET_TERMINATE_NOW = 2, /**< operation successful, function is requested to terminate (mostly used with threads) */
RS_RET_NO_RUN = 3, /**< operation successful, but function does not like to be executed */
diff --git a/vmop.c b/vmop.c
index c8fff752..978db899 100644
--- a/vmop.c
+++ b/vmop.c
@@ -35,6 +35,9 @@
DEFobjStaticHelpers
+/* forward definitions */
+static rsRetVal vmopOpcode2Str(vmop_t *pThis, uchar **ppName);
+
/* Standard-Constructor
*/
BEGINobjConstruct(vmop) /* be sure to specify the object type also in END macro! */
@@ -73,7 +76,7 @@ ENDobjDebugPrint(vmop)
/* set operand (variant case)
* rgerhards, 2008-02-20
*/
-rsRetVal
+static rsRetVal
vmopSetVar(vmop_t *pThis, var_t *pVar)
{
DEFiRet;
@@ -87,7 +90,7 @@ vmopSetVar(vmop_t *pThis, var_t *pVar)
/* set operation
* rgerhards, 2008-02-20
*/
-rsRetVal
+static rsRetVal
vmopSetOpcode(vmop_t *pThis, opcode_t opcode)
{
DEFiRet;
@@ -99,7 +102,7 @@ vmopSetOpcode(vmop_t *pThis, opcode_t opcode)
/* a way to turn an opcode into a readable string
*/
-rsRetVal
+static rsRetVal
vmopOpcode2Str(vmop_t *pThis, uchar **ppName)
{
DEFiRet;
@@ -175,6 +178,34 @@ vmopOpcode2Str(vmop_t *pThis, uchar **ppName)
}
+/* queryInterface function
+ * rgerhards, 2008-02-21
+ */
+BEGINobjQueryInterface(vmop)
+CODESTARTobjQueryInterface(vmop)
+ if(pIf->ifVersion != vmopCURR_IF_VERSION) { /* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->oID = OBJvmop;
+
+ pIf->Construct = vmopConstruct;
+ pIf->ConstructFinalize = vmopConstructFinalize;
+ pIf->Destruct = vmopDestruct;
+ pIf->DebugPrint = vmopDebugPrint;
+ pIf->SetOpcode = vmopSetOpcode;
+ pIf->SetVar = vmopSetVar;
+ pIf->Opcode2Str = vmopOpcode2Str;
+finalize_it:
+ENDobjQueryInterface(vmop)
+
+
+
/* Initialize the vmop class. Must be called as the very first method
* before anything else is called inside this class.
* rgerhards, 2008-02-19
diff --git a/vmop.h b/vmop.h
index 6c74054a..30e64888 100644
--- a/vmop.h
+++ b/vmop.h
@@ -66,14 +66,22 @@ typedef struct vmop_s {
} vmop_t;
-/* prototypes */
-rsRetVal vmopConstruct(vmop_t **ppThis);
-rsRetVal vmopConstructFinalize(vmop_t __attribute__((unused)) *pThis);
-rsRetVal vmopDestruct(vmop_t **ppThis);
-rsRetVal vmopSetOpcode(vmop_t *pThis, opcode_t opcode);
-rsRetVal vmopSetVar(vmop_t *pThis, var_t *pVar);
-rsRetVal vmopOpcode2Str(vmop_t *pThis, uchar **ppName);
+/* interfaces */
+typedef struct vmop_if_s {
+ ifBEGIN; /* This MUST always be the first interface member */
+ INTERFACEObjDebugPrint(vmop);
+ rsRetVal (*Construct)(vmop_t **ppThis);
+ rsRetVal (*ConstructFinalize)(vmop_t __attribute__((unused)) *pThis);
+ rsRetVal (*Destruct)(vmop_t **ppThis);
+ rsRetVal (*SetOpcode)(vmop_t *pThis, opcode_t opcode);
+ rsRetVal (*SetVar)(vmop_t *pThis, var_t *pVar);
+ rsRetVal (*Opcode2Str)(vmop_t *pThis, uchar **ppName);
+} vmop_if_t;
+
+#define vmopCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* the remaining prototypes */
PROTOTYPEObjClassInit(vmop);
-PROTOTYPEObjDebugPrint(vmop);
+PROTOTYPEObjQueryInterface(vmop);
#endif /* #ifndef INCLUDED_VMOP_H */
diff --git a/vmprg.c b/vmprg.c
index 2d522426..4856ebb2 100644
--- a/vmprg.c
+++ b/vmprg.c
@@ -32,6 +32,7 @@
/* static data */
DEFobjStaticHelpers
+DEFobjCurrIf(vmop)
/* Standard-Constructor
@@ -60,7 +61,7 @@ CODESTARTobjDestruct(vmprg)
for(pOp = pThis->vmopRoot ; pOp != NULL ; ) {
pTmp = pOp;
pOp = pOp->pNext;
- vmopDestruct(&pTmp);
+ vmop.Destruct(&pTmp);
}
ENDobjDestruct(vmprg)
@@ -71,7 +72,7 @@ BEGINobjDebugPrint(vmprg) /* be sure to specify the object type also in END and
CODESTARTobjDebugPrint(vmprg)
dbgoprint((obj_t*) pThis, "program contents:\n");
for(pOp = pThis->vmopRoot ; pOp != NULL ; pOp = pOp->pNext) {
- vmopDebugPrint(pOp);
+ vmop.DebugPrint(pOp);
}
ENDobjDebugPrint(vmprg)
@@ -90,12 +91,12 @@ vmprgAddVarOperation(vmprg_t *pThis, opcode_t opcode, var_t *pVar)
ISOBJ_TYPE_assert(pThis, vmprg);
/* construct and fill vmop */
- CHKiRet(vmopConstruct(&pOp));
- CHKiRet(vmopConstructFinalize(pOp));
- CHKiRet(vmopConstructFinalize(pOp));
- CHKiRet(vmopSetOpcode(pOp, opcode));
+ CHKiRet(vmop.Construct(&pOp));
+ CHKiRet(vmop.ConstructFinalize(pOp));
+ CHKiRet(vmop.ConstructFinalize(pOp));
+ CHKiRet(vmop.SetOpcode(pOp, opcode));
if(pVar != NULL)
- CHKiRet(vmopSetVar(pOp, pVar));
+ CHKiRet(vmop.SetVar(pOp, pVar));
/* and add it to the program */
CHKiRet(vmprgAddOperation(pThis, pOp));
@@ -134,6 +135,11 @@ vmprgAddOperation(vmprg_t *pThis, vmop_t *pOp)
* rgerhards, 2008-02-19
*/
BEGINObjClassInit(vmprg, 1) /* class, version */
+ /* request objects we use */
+ //objUse(vmop);
+ CHKiRet(vmopQueryInterface(&vmop));
+
+ /* set our own handlers */
OBJSetMethodHandler(objMethod_DEBUGPRINT, vmprgDebugPrint);
OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, vmprgConstructFinalize);
ENDObjClassInit(vmprg)