summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-02-22 18:13:01 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-02-22 18:13:01 +0000
commit79ca6100e64b3fff6f52444f121ee1f7642a7b04 (patch)
treef45da675d90c84b8b863cd0bc00f5ee839a560ad
parent75e9a2dc69bad2fe10cc60d801019731069005cf (diff)
downloadrsyslog-79ca6100e64b3fff6f52444f121ee1f7642a7b04.tar.gz
rsyslog-79ca6100e64b3fff6f52444f121ee1f7642a7b04.tar.xz
rsyslog-79ca6100e64b3fff6f52444f121ee1f7642a7b04.zip
worked a bit on var_t data type conversion
-rwxr-xr-xstringbuf.c31
-rwxr-xr-xstringbuf.h1
-rw-r--r--var.c63
3 files changed, 78 insertions, 17 deletions
diff --git a/stringbuf.c b/stringbuf.c
index a54fe1bd..d1e69abf 100755
--- a/stringbuf.c
+++ b/stringbuf.c
@@ -718,6 +718,37 @@ int rsCStrOffsetSzStrCmp(cstr_t *pCS1, size_t iOffset, uchar *psz, size_t iLenSz
}
+/* check if the string can be converted to a number. Returns 1 if that's possible
+ * and 0 otherwise.
+ */
+int rsCStrCanConvertToNumber(cstr_t *pStr)
+{
+ int i;
+ int ret = 1;
+
+ if(pStr->iStrLen == 0) {
+ /* can be converted to 0! (by convention) */
+ goto finalize_it;
+ }
+
+ /* we have a string, so let's check its syntax */
+ if(pStr->pBuf[0] == '+' || pStr->pBuf[0] == '-') {
+ i = 1; /* skip that char */
+ } else {
+ i = 0; /* start from the beginning */
+ }
+
+ while(i < pStr->iStrLen && isdigit(pStr->pBuf[i]))
+ ++i;
+
+ if(i < pStr->iStrLen) /* non-digits before end of string? */
+ ret = 0; /* than we can not convert */
+
+finalize_it:
+ return ret;
+}
+
+
/* compare a rsCStr object with a classical sz string.
* Just like rsCStrCStrCmp, just for a different data type.
* There must not only the sz string but also its length be
diff --git a/stringbuf.h b/stringbuf.h
index 1c4ff04b..02720c2a 100755
--- a/stringbuf.h
+++ b/stringbuf.h
@@ -138,6 +138,7 @@ int rsCStrLocateInSzStr(cstr_t *pThis, uchar *sz);
int rsCStrStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz);
int rsCStrSzStrStartsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz);
int rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz);
+int rsCStrCanConvertToNumber(cstr_t *pStr);
/* now come inline-like functions */
#ifdef NDEBUG
diff --git a/var.c b/var.c
index d383a1a8..1f4ed1cb 100644
--- a/var.c
+++ b/var.c
@@ -142,6 +142,29 @@ finalize_it:
}
+/* check if the provided object can be converted to a number. Uses
+ * non-standard calling conventions because it makes an awful lot of sense.
+ * Returns 1 if conversion is possibe and 0 if not. If 1 is returned, a
+ * conversion request on the unchanged object is guaranteed to succeed.
+ * rgerhards, 2008-02-22
+ */
+int canConvToNumber(var_t *pThis)
+{
+ int ret = 0;
+
+ BEGINfunc
+
+ if(pThis->varType == VARTYPE_NUMBER) {
+ ret = 1;
+ } else if(pThis->varType == VARTYPE_STR) {
+ ret = rsCStrCanConvertToNumber(pThis->val.pStr); // TODO: implement the same method in str_t object, then call that */
+ }
+
+ ENDfunc
+ return ret;
+}
+
+
/* 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
@@ -184,42 +207,48 @@ ConvForOperation(var_t *pThis, var_t *pOther)
if(pThis->varType == VARTYPE_NONE || pOther->varType == VARTYPE_NONE)
ABORT_FINALIZE(RS_RET_INVALID_VAR);
-#if 0
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_STR:
+ switch(pOther->varType) {
case VARTYPE_NONE:
ABORT_FINALIZE(RS_RET_INVALID_VAR);
break;
- case VARTYPE_PSZ:
- case VARTYPE_CSTR:
+ case VARTYPE_STR:
+ commonType = VARTYPE_STR;
break;
- case VARTYPE_SHORT:
- case VARTYPE_INT:
- case VARTYPE_LONG:
- case VARTYPE_INT64:
+ case VARTYPE_NUMBER:
+ /* check if we can convert pThis to a number, if so use number format. */
+ commonType = canConvToNumber(pThis) ? VARTYPE_NUMBER : VARTYPE_STR;
break;
case VARTYPE_SYSLOGTIME:
ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED);
break;
}
break;
- case VARTYPE_SHORT:
- case VARTYPE_INT:
- case VARTYPE_LONG:
- case VARTYPE_INT64:
+ case VARTYPE_NUMBER:
+ switch(pOther->varType) {
+ case VARTYPE_NONE:
+ ABORT_FINALIZE(RS_RET_INVALID_VAR);
+ break;
+ case VARTYPE_STR:
+ /* check if we can convert pOther to a number, if so use number format. */
+ commonType = canConvToNumber(pOther) ? VARTYPE_NUMBER : VARTYPE_STR;
+ break;
+ case VARTYPE_NUMBER:
+ commonType = VARTYPE_NUMBER;
+ break;
+ case VARTYPE_SYSLOGTIME:
+ ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED);
+ break;
+ }
break;
case VARTYPE_SYSLOGTIME:
ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED);
break;
}
-#endif
finalize_it:
RETiRet;