From 33f061484d7456f0eb34f9ebab7a82e25ac26448 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 20 Feb 2008 13:54:11 +0000 Subject: created var class out of property_t --- ChangeLog | 1 + Makefile.am | 2 ++ debug.c | 2 +- expr.c | 31 ++++++++++------------- msg.c | 2 +- obj-types.h | 28 +++------------------ obj.c | 56 +++++++++++++++++++---------------------- obj.h | 9 ++++--- queue.c | 2 +- stream.c | 2 +- syslogd.c | 1 + var.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ var.h | 58 ++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 197 insertions(+), 81 deletions(-) create mode 100644 var.c create mode 100644 var.h diff --git a/ChangeLog b/ChangeLog index 1badc202..b5e2c14c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Version 3.12.0 (rgerhards), 2008-02-?? - bugfix: debug.html was missing from release tarball - thanks to Michael Biebl for bringing this to my attention - some internal cleanup on the stringbuf object calling interface +- general code cleanup and further modularization --------------------------------------------------------------------------- Version 3.11.3 (rgerhards), 2008-02-18 - fixed a bug in imklog which lead to duplicate message content in diff --git a/Makefile.am b/Makefile.am index a0e61210..d5dd3ba8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,8 @@ rsyslogd_SOURCES = \ threads.h \ stream.c \ stream.h \ + var.c \ + var.h \ wtp.c \ wtp.h \ wti.c \ diff --git a/debug.c b/debug.c index 00b7916b..2614225b 100644 --- a/debug.c +++ b/debug.c @@ -57,7 +57,7 @@ static dbgThrdInfo_t *dbgGetThrdInfo(void); /* static data (some time to be replaced) */ int Debug; /* debug flag - read-only after startup */ int debugging_on = 0; /* read-only, except on sig USR1 */ -static int bLogFuncFlow = 1; /* shall the function entry and exit be logged to the debug log? */ +static int bLogFuncFlow = 0; /* shall the function entry and exit be logged to the debug log? */ static int bLogAllocFree = 0; /* shall calls to (m/c)alloc and free be logged to the debug log? */ static int bPrintFuncDBOnExit = 0; /* shall the function entry and exit be logged to the debug log? */ static int bPrintMutexAction = 0; /* shall mutex calls be printed to the debug log? */ diff --git a/expr.c b/expr.c index bb72cb89..cdf123e2 100644 --- a/expr.c +++ b/expr.c @@ -53,22 +53,6 @@ DEFobjStaticHelpers /* forward definiton - thanks to recursive ABNF, we can not avoid at least one ;) */ static rsRetVal expr(expr_t *pThis, ctok_t *ctok); -#if 0 -static rsRetVal -template(expr_t *pThis, ctok_t *ctok) -{ - DEFiRet; - - ISOBJ_TYPE_assert(pThis, expr); - ISOBJ_TYPE_assert(ctok, ctok); - - -finalize_it: - RETiRet; -} -#endif - - static rsRetVal terminal(expr_t *pThis, ctok_t *ctok) @@ -84,18 +68,24 @@ terminal(expr_t *pThis, ctok_t *ctok) switch(pToken->tok) { case ctok_SIMPSTR: dbgoprint((obj_t*) pThis, "simpstr\n"); + // push val break; case ctok_NUMBER: dbgoprint((obj_t*) pThis, "number\n"); + // push val break; case ctok_FUNCTION: dbgoprint((obj_t*) pThis, "function\n"); + // vm: call - well, need to implement that first + ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED); break; case ctok_MSGVAR: dbgoprint((obj_t*) pThis, "MSGVAR\n"); + // push val break; case ctok_SYSVAR: dbgoprint((obj_t*) pThis, "SYSVAR\n"); + // push val break; case ctok_LPAREN: dbgoprint((obj_t*) pThis, "expr\n"); @@ -129,7 +119,6 @@ factor(expr_t *pThis, ctok_t *ctok) CHKiRet(ctokGetToken(ctok, &pToken)); if(pToken->tok == ctok_NOT) { - /* TODO: fill structure */ dbgprintf("not\n"); CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */ CHKiRet(ctokGetToken(ctok, &pToken)); /* get next one */ @@ -138,6 +127,7 @@ factor(expr_t *pThis, ctok_t *ctok) CHKiRet(ctokUngetToken(ctok, pToken)); } CHKiRet(terminal(pThis, ctok)); + // vm: not finalize_it: RETiRet; @@ -153,6 +143,7 @@ term(expr_t *pThis, ctok_t *ctok) ISOBJ_TYPE_assert(ctok, ctok); CHKiRet(factor(pThis, ctok)); + // vm: +/- finalize_it: RETiRet; @@ -169,7 +160,7 @@ val(expr_t *pThis, ctok_t *ctok) CHKiRet(ctokGetToken(ctok, &pToken)); if(pToken->tok == ctok_PLUS || pToken->tok == ctok_MINUS) { - /* TODO: fill structure */ + /* TODO: this must be a loop! */ dbgprintf("plus/minus\n"); CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */ CHKiRet(ctokGetToken(ctok, &pToken)); /* get next one */ @@ -179,6 +170,7 @@ val(expr_t *pThis, ctok_t *ctok) } CHKiRet(term(pThis, ctok)); + // vm: +/- finalize_it: RETiRet; @@ -203,6 +195,7 @@ e_cmp(expr_t *pThis, ctok_t *ctok) /* fill structure */ CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */ CHKiRet(val(pThis, ctok)); + // vm: cmpop } else { /* we could not process the token, so push it back */ CHKiRet(ctokUngetToken(ctok, pToken)); @@ -232,6 +225,7 @@ e_and(expr_t *pThis, ctok_t *ctok) /* fill structure */ CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */ CHKiRet(e_cmp(pThis, ctok)); + // VM: and CHKiRet(ctokGetToken(ctok, &pToken)); } @@ -263,6 +257,7 @@ expr(expr_t *pThis, ctok_t *ctok) dbgoprint((obj_t*) pThis, "found OR\n"); CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */ CHKiRet(e_and(pThis, ctok)); + // VM: or CHKiRet(ctokGetToken(ctok, &pToken)); } diff --git a/msg.c b/msg.c index 72cb6a3b..b23d2724 100644 --- a/msg.c +++ b/msg.c @@ -2082,7 +2082,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, * rgerhards, 2008-01-07 */ #define isProp(name) !rsCStrSzStrCmp(pProp->pcsName, (uchar*) name, sizeof(name) - 1) -rsRetVal MsgSetProperty(msg_t *pThis, property_t *pProp) +rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp) { DEFiRet; diff --git a/obj-types.h b/obj-types.h index d3722070..831dd897 100644 --- a/obj-types.h +++ b/obj-types.h @@ -31,29 +31,6 @@ #include "stringbuf.h" #include "syslogd-types.h" -/* property types */ -typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */ - PROPTYPE_PSZ = 1, - PROPTYPE_SHORT = 2, - PROPTYPE_INT = 3, - PROPTYPE_LONG = 4, - PROPTYPE_CSTR = 5, - PROPTYPE_SYSLOGTIME = 6 -} propertyType_t; - -typedef struct { - rsCStrObj *pcsName; - propertyType_t propType; - union { - short vShort; - int vInt; - long vLong; - rsCStrObj *vpCStr; /* used for both rsCStr and psz */ - syslogTime_t vSyslogTime; - - } val; -} property_t; - /* object Types/IDs */ typedef enum { /* IDs of known object "types/classes" */ OBJNull = 0, /* no valid object (we do not start at zero so we can detect calloc()) */ @@ -64,9 +41,10 @@ typedef enum { /* IDs of known object "types/classes" */ OBJqueue = 5, OBJctok = 6, OBJctok_token = 7, - OBJexpr = 8 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */ + OBJvar = 8, + OBJexpr = 9 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */ } objID_t; -#define OBJ_NUM_IDS 9 +#define OBJ_NUM_IDS 10 typedef enum { /* IDs of base methods supported by all objects - used for jump table, so * they must start at zero and be incremented. -- rgerahrds, 2008-01-04 diff --git a/obj.c b/obj.c index 32818672..6edddbac 100644 --- a/obj.c +++ b/obj.c @@ -180,7 +180,6 @@ rsRetVal objBeginSerialize(strm_t *pStrm, obj_t *pObj) { DEFiRet; -dbgprintf("objBeginSerialize obj type: %x\n", objGetObjID(pStrm)); ISOBJ_TYPE_assert(pStrm, strm); ISOBJ_assert(pObj); @@ -218,14 +217,14 @@ finalize_it: /* append a property */ -rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propertyType_t propType, void *pUsr) +rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, varType_t propType, void *pUsr) { DEFiRet; uchar *pszBuf = NULL; size_t lenBuf = 0; uchar szBuf[64]; - assert(pStrm != NULL); + ISOBJ_TYPE_assert(pStrm, strm); assert(pszPropName != NULL); /*dbgprintf("objSerializeProp: strm %p, propName '%s', type %d, pUsr %p\n", pStrm, pszPropName, propType, pUsr);*/ @@ -240,30 +239,30 @@ rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propertyType_t prop /* TODO: use the stream functions for data conversion here - should be quicker */ switch(propType) { - case PROPTYPE_PSZ: + case VARTYPE_PSZ: pszBuf = (uchar*) pUsr; lenBuf = strlen((char*) pszBuf); break; - case PROPTYPE_SHORT: + case VARTYPE_SHORT: CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), (long) *((short*) pUsr))); pszBuf = szBuf; lenBuf = strlen((char*) szBuf); break; - case PROPTYPE_INT: + case VARTYPE_INT: CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), (long) *((int*) pUsr))); pszBuf = szBuf; lenBuf = strlen((char*) szBuf); break; - case PROPTYPE_LONG: + case VARTYPE_LONG: CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), *((long*) pUsr))); pszBuf = szBuf; lenBuf = strlen((char*) szBuf); break; - case PROPTYPE_CSTR: + case VARTYPE_CSTR: pszBuf = rsCStrGetSzStrNoNULL((rsCStrObj *) pUsr); lenBuf = rsCStrLen((rsCStrObj*) pUsr); break; - case PROPTYPE_SYSLOGTIME: + case VARTYPE_SYSLOGTIME: lenBuf = snprintf((char*) szBuf, sizeof(szBuf), "%d:%d:%d:%d:%d:%d:%d:%d:%d:%c:%d:%d", ((syslogTime_t*)pUsr)->timeType, ((syslogTime_t*)pUsr)->year, @@ -466,7 +465,7 @@ finalize_it: /* Deserialize a single property. Pointer must be positioned at begin of line. Whole line * up until the \n is read. */ -static rsRetVal objDeserializeProperty(property_t *pProp, strm_t *pStrm) +static rsRetVal objDeserializeProperty(var_t *pProp, strm_t *pStrm) { DEFiRet; long i; @@ -495,32 +494,31 @@ static rsRetVal objDeserializeProperty(property_t *pProp, strm_t *pStrm) /* property type */ CHKiRet(objDeserializeLong(&i, pStrm)); - pProp->propType = i; + pProp->varType = i; /* size (needed for strings) */ CHKiRet(objDeserializeLong(&iLen, pStrm)); /* we now need to deserialize the value */ -//dbgprintf("deserialized property name '%s', type %d, size %ld, c: %c\n", rsCStrGetSzStrNoNULL(pProp->pcsName), pProp->propType, iLen, c); - switch(pProp->propType) { - case PROPTYPE_PSZ: + switch(pProp->varType) { + case VARTYPE_PSZ: CHKiRet(objDeserializeStr(&pProp->val.vpCStr, iLen, pStrm)); break; - case PROPTYPE_SHORT: + case VARTYPE_SHORT: CHKiRet(objDeserializeLong(&i, pStrm)); pProp->val.vShort = i; break; - case PROPTYPE_INT: + case VARTYPE_INT: CHKiRet(objDeserializeLong(&i, pStrm)); pProp->val.vInt = i; break; - case PROPTYPE_LONG: + case VARTYPE_LONG: CHKiRet(objDeserializeLong(&pProp->val.vLong, pStrm)); break; - case PROPTYPE_CSTR: + case VARTYPE_CSTR: CHKiRet(objDeserializeStr(&pProp->val.vpCStr, iLen, pStrm)); break; - case PROPTYPE_SYSLOGTIME: + case VARTYPE_SYSLOGTIME: CHKiRet(objDeserializeSyslogTime(&pProp->val.vSyslogTime, pStrm)); break; } @@ -604,19 +602,21 @@ finalize_it: static rsRetVal objDeserializeProperties(obj_t *pObj, objID_t oID, strm_t *pStrm) { DEFiRet; - property_t propBuf; + var_t *pVar; ISOBJ_assert(pObj); ISOBJ_TYPE_assert(pStrm, strm); - assert(oID > 0 && oID < OBJ_NUM_IDS); + ASSERT(oID > 0 && oID < OBJ_NUM_IDS); + + CHKiRet(varConstruct(&pVar)); + CHKiRet(varConstructFinalize(pVar)); - iRet = objDeserializeProperty(&propBuf, pStrm); + iRet = objDeserializeProperty(pVar, pStrm); while(iRet == RS_RET_OK) { - CHKiRet(arrObjInfo[oID]->objMethods[objMethod_SETPROPERTY](pObj, &propBuf)); - iRet = objDeserializeProperty(&propBuf, pStrm); + CHKiRet(arrObjInfo[oID]->objMethods[objMethod_SETPROPERTY](pObj, pVar)); + iRet = objDeserializeProperty(pVar, pStrm); } - rsCStrDestruct(propBuf.pcsName); /* todo: a destructor would be nice here... -- rger, 2008-01-07 */ - // TODO: do we have a mem leak for the other CStr in this struct? + varDestruct(&pVar); if(iRet != RS_RET_NO_PROPLINE) FINALIZE; @@ -699,11 +699,8 @@ rsRetVal objDeserializeObjAsPropBag(obj_t *pObj, strm_t *pStrm) objID_t oID = 0; /* this assignment is just to supress a compiler warning - this saddens me */ int oVers = 0; /* after all, it is totally useless but takes up some execution time... */ -dbgprintf("objDese...AsPropBag 0\n"); ISOBJ_assert(pObj); -dbgprintf("objDese...AsPropBag 0a\n"); ISOBJ_TYPE_assert(pStrm, strm); -dbgprintf("objDese...AsPropBag 1\n"); /* we de-serialize the header. if all goes well, we are happy. However, if * we experience a problem, we try to recover. We do this by skipping to @@ -720,7 +717,6 @@ dbgprintf("objDese...AsPropBag 1\n"); } } while(iRetLocal != RS_RET_OK); -dbgprintf("objDese...AsPropBag 2\n"); if(oID != objGetObjID(pObj)) ABORT_FINALIZE(RS_RET_INVALID_OID); diff --git a/obj.h b/obj.h index 0a89b74a..229bcd7b 100644 --- a/obj.h +++ b/obj.h @@ -45,6 +45,7 @@ #define OBJ_H_INCLUDED #include "obj-types.h" +#include "var.h" #include "stream.h" /* macros */ @@ -60,11 +61,11 @@ } #define objSerializeSCALAR_VAR(strm, propName, propType, var) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &var)); + CHKiRet(objSerializeProp(strm, (uchar*) #propName, VARTYPE_##propType, (void*) &var)); #define objSerializeSCALAR(strm, propName, propType) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &pThis->propName)); + CHKiRet(objSerializeProp(strm, (uchar*) #propName, VARTYPE_##propType, (void*) &pThis->propName)); #define objSerializePTR(strm, propName, propType) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) pThis->propName)); + CHKiRet(objSerializeProp(strm, (uchar*) #propName, VARTYPE_##propType, (void*) pThis->propName)); #define DEFobjStaticHelpers static objInfo_t *pObjInfoOBJ = NULL; #define objGetClassName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName) #define objGetObjID(pThis) (((obj_t*) (pThis))->pObjInfo->objID) @@ -91,7 +92,7 @@ rsRetVal objDestructObjSelf(obj_t *pThis); rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)); rsRetVal objBeginSerializePropBag(strm_t *pStrm, obj_t *pObj); rsRetVal objBeginSerialize(strm_t *pStrm, obj_t *pObj); -rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propertyType_t propType, void *pUsr); +rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, varType_t propType, void *pUsr); rsRetVal objEndSerialize(strm_t *pStrm); rsRetVal objRegisterObj(objID_t oID, objInfo_t *pInfo); rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr); diff --git a/queue.c b/queue.c index 7f43f244..2c43e773 100644 --- a/queue.c +++ b/queue.c @@ -2058,7 +2058,7 @@ DEFpropSetMeth(queue, sizeOnDiskMax, int64); * rgerhards, 2008-01-11 */ #define isProp(name) !rsCStrSzStrCmp(pProp->pcsName, (uchar*) name, sizeof(name) - 1) -static rsRetVal queueSetProperty(queue_t *pThis, property_t *pProp) +static rsRetVal queueSetProperty(queue_t *pThis, var_t *pProp) { DEFiRet; diff --git a/stream.c b/stream.c index 5adc0b7e..24d42d17 100644 --- a/stream.c +++ b/stream.c @@ -803,7 +803,7 @@ finalize_it: * rgerhards, 2008-01-11 */ #define isProp(name) !rsCStrSzStrCmp(pProp->pcsName, (uchar*) name, sizeof(name) - 1) -rsRetVal strmSetProperty(strm_t *pThis, property_t *pProp) +rsRetVal strmSetProperty(strm_t *pThis, var_t *pProp) { DEFiRet; diff --git a/syslogd.c b/syslogd.c index 40581d54..3550de7e 100644 --- a/syslogd.c +++ b/syslogd.c @@ -3418,6 +3418,7 @@ static rsRetVal InitGlobalClasses(void) CHKiRet(wtiClassInit()); CHKiRet(wtpClassInit()); CHKiRet(queueClassInit()); + CHKiRet(varClassInit()); CHKiRet(ctok_tokenClassInit()); CHKiRet(ctokClassInit()); CHKiRet(exprClassInit()); diff --git a/var.c b/var.c new file mode 100644 index 00000000..8c43ddbb --- /dev/null +++ b/var.c @@ -0,0 +1,84 @@ +/* var.c - a typeless variable class + * + * This class is used to represent variable values, which may have any type. + * Among others, it will be used inside rsyslog's expression system, but + * also internally at any place where a typeless variable is needed. + * + * Module begun 2008-02-20 by Rainer Gerhards, with some code taken + * from the obj.c/.h files. + * + * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ + +#include "config.h" +#include +#include + +#include "rsyslog.h" +#include "obj.h" +#include "var.h" + +/* static data */ +DEFobjStaticHelpers + + +/* Standard-Constructor + */ +BEGINobjConstruct(var) /* be sure to specify the object type also in END macro! */ +ENDobjConstruct(var) + + +/* ConstructionFinalizer + * rgerhards, 2008-01-09 + */ +rsRetVal varConstructFinalize(var_t *pThis) +{ + DEFiRet; + + ISOBJ_TYPE_assert(pThis, var); + + RETiRet; +} + + +/* destructor for the var object */ +BEGINobjDestruct(var) /* be sure to specify the object type also in END and CODESTART macros! */ +CODESTARTobjDestruct(var) + if(pThis->pcsName != NULL) + d_free(pThis->pcsName); + if(pThis->varType == VARTYPE_CSTR) { + if(pThis->val.vpCStr != NULL) + d_free(pThis->val.vpCStr); + } + +ENDobjDestruct(var) + + + +/* Initialize the var class. Must be called as the very first method + * before anything else is called inside this class. + * rgerhards, 2008-02-19 + */ +BEGINObjClassInit(var, 1) /* class, version */ + OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, varConstructFinalize); +ENDObjClassInit(var) + +/* vi:set ai: + */ diff --git a/var.h b/var.h new file mode 100644 index 00000000..9f3e7d82 --- /dev/null +++ b/var.h @@ -0,0 +1,58 @@ +/* The var object. + * + * Copyright 2008 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#ifndef INCLUDED_VAR_H +#define INCLUDED_VAR_H + + +/* data types */ +typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */ + VARTYPE_PSZ = 1, + VARTYPE_SHORT = 2, + VARTYPE_INT = 3, + VARTYPE_LONG = 4, + VARTYPE_CSTR = 5, + VARTYPE_SYSLOGTIME = 6 +} varType_t; + +/* the var object */ +typedef struct var_s { + BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */ + rsCStrObj *pcsName; + varType_t varType; + union { + short vShort; + int vInt; + long vLong; + rsCStrObj *vpCStr; /* used for both rsCStr and psz */ + syslogTime_t vSyslogTime; + + } val; +} var_t; + + +/* prototypes */ +rsRetVal varConstruct(var_t **ppThis); +rsRetVal varConstructFinalize(var_t __attribute__((unused)) *pThis); +rsRetVal varDestruct(var_t **ppThis); +PROTOTYPEObjClassInit(var); + +#endif /* #ifndef INCLUDED_VAR_H */ -- cgit