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.

