On Tue, Oct 14, 2014 at 12:18 PM, singh.janmejay <[email protected]>
wrote:

> Yes, I'll make necessary changes and send the patch again.
>
> --
> Regards,
> Janmejay
>
> PS: Please blame the typos in this mail on my phone's uncivilized soft
> keyboard sporting it's not-so-smart-assist technology.
>  On Oct 14, 2014 12:02 PM, "Rainer Gerhards" <[email protected]>
> wrote:
>
>> 2014-10-14 8:30 GMT+02:00 singh.janmejay <[email protected]>:
>>
>> > > > - replace(operand, substring_to_be_replaced, its_replacement)
>> > > > - wrap(operand, string_to_wrap_around_it)
>> > > >
>> > >
>> > > - concat(operand_1, operand_2)
>> > > >
>> > >
>> > >
>> > > I think you overlooked the concatenation operation. you can simply do
>> > >
>> > > operand1 & operand2
>> > >
>> > > eg: "foo" & "bar" ==> "foobar"
>> > >
>> > > I think concat() is equivalent to this. Am I right?
>> > >
>> >
>> > It is the same. I didn't know it was available as an operator, my bad.
>> Will
>> > remove the concat implementation in the reworked patch.
>> >
>>
>> yeah the doc is pretty sparse.
>>
>> If I understand you correctly, I will wait for a new patch set before
>> merging the existing one. Right?
>>
>> Rainer
>> _______________________________________________
>> rsyslog mailing list
>> http://lists.adiscon.net/mailman/listinfo/rsyslog
>> http://www.rsyslog.com/professional-services/
>> What's up with rsyslog? Follow https://twitter.com/rgerhards
>> NOTE WELL: This is a PUBLIC mailing list, posts are ARCHIVED by a myriad
>> of sites beyond our control. PLEASE UNSUBSCRIBE and DO NOT POST if you
>> DON'T LIKE THAT.
>>
>

Hi,

Sorry for breaking the continuation here, I finally managed to get some
time to work on this today.

Patches are attached. Just for clarity, I am attaching all(actually 2)
relevant patches(even though one of them is not changed).

Changes made:
- removed the patch that implemented concat
- enhanced the wrap method to have 2 variants wrap(str, wrapper) and
wrap(str, wrapper, wrapper_escape)
- kept the replace (and wrap first cut) patch untouched.


-- 
Regards,
Janmejay
http://codehunk.wordpress.com
From ae3ccaf40de122714e2f42201efd788bbbb41bb4 Mon Sep 17 00:00:00 2001
From: Janmejay Singh <[email protected]>
Date: Thu, 9 Oct 2014 13:50:04 +0530
Subject: [PATCH 1/2] rainerscript functions 'replace(operand, str_to_replace,
 replacement)' and 'wrap(operand, wrapper_string)' to make some simple
 variable tranformations possible

---
 grammar/rainerscript.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
 grammar/rainerscript.h |   4 +-
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index ccfa0e2..488dd6c 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -1482,6 +1482,81 @@ doFunc_exec_template(struct cnffunc *__restrict__ const func,
 }
 
 
+static inline es_str_t*
+doFuncReplace(struct var *__restrict__ const operandVal, struct var *__restrict__ const findVal, struct var *__restrict__ const replaceWithVal) {
+    int freeOperand, freeFind, freeReplacement;
+    es_str_t *str = var2String(operandVal, &freeOperand);
+    es_str_t *findStr = var2String(findVal, &freeFind);
+    es_str_t *replaceWithStr = var2String(replaceWithVal, &freeReplacement);
+    uchar *find = es_getBufAddr(findStr);
+    uchar *replaceWith = es_getBufAddr(replaceWithStr);
+    uint lfind = es_strlen(findStr);
+    uint lReplaceWith = es_strlen(replaceWithStr);
+    uint size = 0;
+    uchar* src = es_getBufAddr(str);
+    uint i, j;
+    for(i = j = 0; i < es_strlen(str); i++, size++) {
+        if (j == lfind) {
+            size = size - lfind + lReplaceWith;
+            j = 0;
+        } else if (src[i] == find[j]) {
+            j++;
+        } else if (j > 0) {
+            j = 0;
+        }
+    }
+    es_str_t *res = es_newStr(size);
+    unsigned char* dest = es_getBufAddr(res);
+    uint k, s;
+    for(i = j = k = s = 0; i < es_strlen(str); i++, s++) {
+        if (j == lfind) {
+            for (k = 0; k < lReplaceWith; k++) {
+                dest[s - j + k] = replaceWith[k];
+            }
+            s = s - j + lReplaceWith;
+            j = 0;
+            dest[s] = src[i];
+        } else {
+            if (src[i] == find[j]) {
+                j++;
+            } else if (j > 0) {
+                j = 0;
+                for (k = 0; k < j; k++) {
+                    dest[s - j + k]  = find[k];
+                }
+            }
+            dest[s] = src[i];
+        }
+    }
+    res->lenStr = size;
+    if(freeOperand) es_deleteStr(str);
+    if(freeFind) es_deleteStr(findStr);
+    if(freeReplacement) es_deleteStr(replaceWithStr);
+    return res;
+}
+
+static inline es_str_t*
+doFuncWrap(struct var *__restrict__ const sourceVal, struct var *__restrict__ const wrapperVal) {
+    int freeSource, freeWrapper;
+    es_str_t *sourceStr = var2String(sourceVal, &freeSource);
+    es_str_t *wrapperStr = var2String(wrapperVal, &freeWrapper);
+    uchar *src = es_getBufAddr(sourceStr);
+    uchar *wrapper = es_getBufAddr(wrapperStr);
+    uint lWrapper = es_strlen(wrapperStr);
+    uint lSrc = es_strlen(sourceStr);
+    uint totalLen = lSrc + 2 * lWrapper;
+    es_str_t *res = es_newStr(totalLen);
+    uchar* resBuf = es_getBufAddr(res);
+    memcpy(resBuf, wrapper, lWrapper);
+    memcpy(resBuf + lWrapper, src, lSrc);
+    memcpy(resBuf + lSrc + lWrapper, wrapper, lWrapper);
+    res->lenStr = totalLen;
+    if (freeSource) es_deleteStr(sourceStr);
+    if (freeWrapper) es_deleteStr(wrapperStr);
+    return res;
+}
+
+
 /* Perform a function call. This has been moved out of cnfExprEval in order
  * to keep the code small and easier to maintain.
  */
@@ -1519,6 +1594,24 @@ doFuncCall(struct cnffunc *__restrict__ const func, struct var *__restrict__ con
 		}
 		ret->datatype = 'N';
 		break;
+    case CNFFUNC_REPLACE:
+        cnfexprEval(func->expr[0], &r[0], usrptr);
+        cnfexprEval(func->expr[1], &r[1], usrptr);
+        cnfexprEval(func->expr[2], &r[2], usrptr);
+        ret->d.estr = doFuncReplace(&r[0], &r[1], &r[2]);
+        ret->datatype = 'S';
+        varFreeMembers(&r[0]);
+        varFreeMembers(&r[1]);
+        varFreeMembers(&r[2]);
+        break;
+    case CNFFUNC_WRAP:
+        cnfexprEval(func->expr[0], &r[0], usrptr);
+        cnfexprEval(func->expr[1], &r[1], usrptr);
+        ret->d.estr = doFuncWrap(&r[0], &r[1]);
+        ret->datatype = 'S';
+        varFreeMembers(&r[0]);
+        varFreeMembers(&r[1]);
+        break;
 	case CNFFUNC_GETENV:
 		/* note: the optimizer shall have replaced calls to getenv()
 		 * with a constant argument to a single string (once obtained via
@@ -3550,6 +3643,20 @@ funcName2ID(es_str_t *fname, unsigned short nParams)
 			return CNFFUNC_INVALID;
 		}
 		return CNFFUNC_LOOKUP;
+	} else if(!es_strbufcmp(fname, (unsigned char*)"replace", sizeof("replace") - 1)) {
+		if(nParams != 3) {
+			parser_errmsg("number of parameters for wrap() must be three (operand_string, fragment_to_find, fragment_to_replace_in_its_place) "
+                          "but is %d.", nParams);
+			return CNFFUNC_INVALID;
+		}
+		return CNFFUNC_REPLACE;
+	} else if(!es_strbufcmp(fname, (unsigned char*)"wrap", sizeof("wrap") - 1)) {
+		if(nParams != 2) {
+			parser_errmsg("number of parameters for wrap() must be two (operand_string, string_to_wrap_it_in) "
+                          "but is %d.", nParams);
+			return CNFFUNC_INVALID;
+		}
+		return CNFFUNC_WRAP;
 	} else {
 		return CNFFUNC_INVALID;
 	}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 8742c75..514e83a 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -258,7 +258,9 @@ enum cnffuncid {
 	CNFFUNC_FIELD,
 	CNFFUNC_PRIFILT,
 	CNFFUNC_LOOKUP,
-	CNFFUNC_EXEC_TEMPLATE
+	CNFFUNC_EXEC_TEMPLATE,
+	CNFFUNC_REPLACE,
+	CNFFUNC_WRAP
 };
 
 struct cnffunc {
-- 
2.0.4

From 4d53c89868580e9643e9eecabdd0d95d919ee198 Mon Sep 17 00:00:00 2001
From: Janmejay Singh <[email protected]>
Date: Fri, 17 Oct 2014 15:49:29 +0530
Subject: [PATCH 2/2] wrap now has 2 variants: 1. wrap(string, wrapper) 2.
 wrap(string, wrapper, escaper)

1st wraps the string with the given string, for instance: wrap("foo", "#") -> "#foo#"
2nd wraps the string, but also escapes any wrapper-fragments found in the string with escaper, for instance: wrap("foo#bar", "#", "\#") => "#foo\#bar#"
---
 grammar/rainerscript.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 488dd6c..e02df91 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -1536,9 +1536,15 @@ doFuncReplace(struct var *__restrict__ const operandVal, struct var *__restrict_
 }
 
 static inline es_str_t*
-doFuncWrap(struct var *__restrict__ const sourceVal, struct var *__restrict__ const wrapperVal) {
+doFuncWrap(struct var *__restrict__ const sourceVal, struct var *__restrict__ const wrapperVal, struct var *__restrict__ const escaperVal) {
     int freeSource, freeWrapper;
-    es_str_t *sourceStr = var2String(sourceVal, &freeSource);
+    es_str_t *sourceStr;
+    if (escaperVal) {
+        sourceStr = doFuncReplace(sourceVal, wrapperVal, escaperVal);
+        freeSource = 1;
+    } else {
+        sourceStr = var2String(sourceVal, &freeSource);
+    }
     es_str_t *wrapperStr = var2String(wrapperVal, &freeWrapper);
     uchar *src = es_getBufAddr(sourceStr);
     uchar *wrapper = es_getBufAddr(wrapperStr);
@@ -1607,10 +1613,12 @@ doFuncCall(struct cnffunc *__restrict__ const func, struct var *__restrict__ con
     case CNFFUNC_WRAP:
         cnfexprEval(func->expr[0], &r[0], usrptr);
         cnfexprEval(func->expr[1], &r[1], usrptr);
-        ret->d.estr = doFuncWrap(&r[0], &r[1]);
+        if (func->nParams == 3) cnfexprEval(func->expr[2], &r[2], usrptr);
+        ret->d.estr = doFuncWrap(&r[0], &r[1], func->nParams > 2 ? &r[2] : NULL);
         ret->datatype = 'S';
         varFreeMembers(&r[0]);
         varFreeMembers(&r[1]);
+        if (func->nParams > 3) varFreeMembers(&r[2]);
         break;
 	case CNFFUNC_GETENV:
 		/* note: the optimizer shall have replaced calls to getenv()
@@ -3645,14 +3653,17 @@ funcName2ID(es_str_t *fname, unsigned short nParams)
 		return CNFFUNC_LOOKUP;
 	} else if(!es_strbufcmp(fname, (unsigned char*)"replace", sizeof("replace") - 1)) {
 		if(nParams != 3) {
-			parser_errmsg("number of parameters for wrap() must be three (operand_string, fragment_to_find, fragment_to_replace_in_its_place) "
+			parser_errmsg("number of parameters for replace() must be three "
+                          "(operand_string, fragment_to_find, fragment_to_replace_in_its_place) "
                           "but is %d.", nParams);
 			return CNFFUNC_INVALID;
 		}
 		return CNFFUNC_REPLACE;
 	} else if(!es_strbufcmp(fname, (unsigned char*)"wrap", sizeof("wrap") - 1)) {
-		if(nParams != 2) {
-			parser_errmsg("number of parameters for wrap() must be two (operand_string, string_to_wrap_it_in) "
+		if(nParams < 2 || nParams > 3) {
+			parser_errmsg("number of parameters for wrap() must either be "
+                          "two (operand_string, wrapper) or"
+                          "three (operand_string, wrapper, wrapper_escape_str)"
                           "but is %d.", nParams);
 			return CNFFUNC_INVALID;
 		}
-- 
2.0.4

_______________________________________________
rsyslog mailing list
http://lists.adiscon.net/mailman/listinfo/rsyslog
http://www.rsyslog.com/professional-services/
What's up with rsyslog? Follow https://twitter.com/rgerhards
NOTE WELL: This is a PUBLIC mailing list, posts are ARCHIVED by a myriad of 
sites beyond our control. PLEASE UNSUBSCRIBE and DO NOT POST if you DON'T LIKE 
THAT.

Reply via email to