summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-02-22 12:36:14 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-02-22 12:36:14 +0000
commit44ac484dd18867163735c54d052e57d52142edaa (patch)
treed006fbda03e52b2cdb8e81b0cb7385bcc7ad7a00
parentc0d0e0643dabbbb8a7fce0a52af5a35831403aee (diff)
downloadrsyslog-44ac484dd18867163735c54d052e57d52142edaa.tar.gz
rsyslog-44ac484dd18867163735c54d052e57d52142edaa.tar.xz
rsyslog-44ac484dd18867163735c54d052e57d52142edaa.zip
worked a bit on type conversion (specified the interface)
-rw-r--r--rsyslog.h1
-rw-r--r--var.c83
-rw-r--r--var.h1
3 files changed, 85 insertions, 0 deletions
diff --git a/rsyslog.h b/rsyslog.h
index c8b2fcfa..1d0bb3ce 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -131,6 +131,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_OUT_OF_STACKSPACE = -2055, /**< a stack data structure is exhausted and can not be grown */
RS_RET_STACK_EMPTY = -2056, /**< a pop was requested on a stack, but the stack was already empty */
RS_RET_INVALID_VMOP = -2057, /**< invalid virtual machine instruction */
+ RS_RET_INVALID_VAR = -2057, /**< a var_t or its content is unsuitable, eg. VARTYPE_NONE */
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/var.c b/var.c
index 9947f159..0c6c6e8b 100644
--- a/var.c
+++ b/var.c
@@ -145,6 +145,88 @@ finalize_it:
}
+/* This function is used to prepare two var_t objects for a common operation,
+ * e.g before they are added, multiplied or compared. The function looks at
+ * the data types of both operands and finds the best data type suitable for
+ * the operation (in respect to current types). Then, it converts those
+ * operands that need conversion. Please note that the passed-in var objects
+ * *are* modified and returned as new type. So do call this function only if
+ * you actually need the conversion.
+ *
+ * This is how the common data type is selected. Note that op1 and op2 are
+ * just the two operands, their order is irrelevant (this would just take up
+ * more table space - so string/number is the same thing as number/string).
+ *
+ * Common Types:
+ * op1 op2 operation data type
+ * string string string
+ * string number number if op1 can be converted to number, string else
+ * date string date if op1 can be converted to date, string else
+ * number number number
+ * date number string (maybe we can do better?)
+ * date date date
+ * none n/a error
+ *
+ * If a boolean value is required, we need to have a number inside the
+ * operand. If it is not, conversion rules to number apply. Once we
+ * have a number, things get easy: 0 is false, anything else is true.
+ * Please note that due to this conversion rules, "0" becomes false
+ * while "-4712" becomes true. Using a date as boolen is not a good
+ * idea. Depending on the ultimate conversion rules, it may always
+ * become true or false. As such, using dates as booleans is
+ * prohibited and the result defined to be undefined.
+ *
+ * rgerhards, 2008-02-22
+ */
+static rsRetVal
+ConvForOperation(var_t *pThis, var_t *pOther)
+{
+ DEFiRet;
+ varType_t commonType;
+
+ if(pThis->varType == VARTYPE_NONE || pOther->varType == VARTYPE_NONE)
+ ABORT_FINALIZE(RS_RET_INVALID_VAR);
+
+ switch(pThis->varType) {
+ case VARTYPE_NONE:
+ ABORT_FINALIZE(RS_RET_INVALID_VAR);
+ break;
+ // TODO: remove VARTYPE_PSZ?
+ // TODO: check need for SHORT/INT/LONG...
+ case VARTYPE_PSZ:
+ case VARTYPE_CSTR:
+ switch(pThis->varType) {
+ case VARTYPE_NONE:
+ ABORT_FINALIZE(RS_RET_INVALID_VAR);
+ break;
+ case VARTYPE_PSZ:
+ case VARTYPE_CSTR:
+ break;
+ case VARTYPE_SHORT:
+ case VARTYPE_INT:
+ case VARTYPE_LONG:
+ case VARTYPE_INT64:
+ break;
+ case VARTYPE_SYSLOGTIME:
+ ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED);
+ break;
+ }
+ break;
+ case VARTYPE_SHORT:
+ case VARTYPE_INT:
+ case VARTYPE_LONG:
+ case VARTYPE_INT64:
+ break;
+ case VARTYPE_SYSLOGTIME:
+ ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED);
+ break;
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
/* queryInterface function
* rgerhards, 2008-02-21
*/
@@ -167,6 +249,7 @@ CODESTARTobjQueryInterface(var)
pIf->DebugPrint = varDebugPrint;
pIf->SetInt64 = varSetInt64;
pIf->SetString = varSetString;
+ pIf->ConvForOperation = ConvForOperation;
finalize_it:
ENDobjQueryInterface(var)
diff --git a/var.h b/var.h
index 24efca7b..0dbc9c64 100644
--- a/var.h
+++ b/var.h
@@ -61,6 +61,7 @@ BEGINinterface(var) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Destruct)(var_t **ppThis);
rsRetVal (*SetInt64)(var_t *pThis, int64 iVal);
rsRetVal (*SetString)(var_t *pThis, cstr_t *pCStr);
+ rsRetVal (*ConvForOperation)(var_t *pThis, var_t *pOther);
ENDinterface(var)
#define varCURR_IF_VERSION 1 /* increment whenever you change the interface above! */