refactor var desctruction in script engine

This provides better extensibility when new data types are added. Thanks
to Pavel Levshin for suggesting this.
This commit is contained in:
Rainer Gerhards 2013-10-25 15:46:37 +02:00
parent bf95d5f034
commit a3d2ad0add

View File

@ -1142,6 +1142,23 @@ var2CString(struct var *r, int *bMustFree)
return cstr; return cstr;
} }
/* frees struct var members, but not the struct itself. This is because
* it usually is allocated on the stack. Callers why dynamically allocate
* struct var need to free the struct themselfes!
*/
static void
varFreeMembers(struct var *r)
{
/* Note: we do NOT need to free JSON objects, as we use
* json_object_object_get() to obtain the values, which does not
* increment the reference count. So json_object_put() [free] is
* neither required nor permitted (would free the original object!).
* So for the time being the string data type is the only one that
* we currently need to free.
*/
if(r->datatype == 'S') es_deleteStr(r->d.estr);
}
static rsRetVal static rsRetVal
doExtractFieldByChar(uchar *str, uchar delim, int matchnbr, uchar **resstr) doExtractFieldByChar(uchar *str, uchar delim, int matchnbr, uchar **resstr)
{ {
@ -1309,9 +1326,9 @@ doFunc_re_extract(struct cnffunc *func, struct var *ret, void* usrptr)
finalize_it: finalize_it:
if(bMustFree) free(str); if(bMustFree) free(str);
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
if(r[2].datatype == 'S') es_deleteStr(r[2].d.estr); varFreeMembers(&r[2]);
if(r[3].datatype == 'S') es_deleteStr(r[3].d.estr); varFreeMembers(&r[3]);
if(bHadNoMatch) { if(bHadNoMatch) {
cnfexprEval(func->expr[4], &r[4], usrptr); cnfexprEval(func->expr[4], &r[4], usrptr);
@ -1379,7 +1396,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
} }
ret->datatype = 'S'; ret->datatype = 'S';
if(bMustFree) es_deleteStr(estr); if(bMustFree) es_deleteStr(estr);
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
free(str); free(str);
break; break;
case CNFFUNC_TOLOWER: case CNFFUNC_TOLOWER:
@ -1390,7 +1407,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
es_tolower(estr); es_tolower(estr);
ret->datatype = 'S'; ret->datatype = 'S';
ret->d.estr = estr; ret->d.estr = estr;
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
break; break;
case CNFFUNC_CSTR: case CNFFUNC_CSTR:
cnfexprEval(func->expr[0], &r[0], usrptr); cnfexprEval(func->expr[0], &r[0], usrptr);
@ -1399,7 +1416,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
estr = es_strdup(estr); estr = es_strdup(estr);
ret->datatype = 'S'; ret->datatype = 'S';
ret->d.estr = estr; ret->d.estr = estr;
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
break; break;
case CNFFUNC_CNUM: case CNFFUNC_CNUM:
if(func->expr[0]->nodetype == 'N') { if(func->expr[0]->nodetype == 'N') {
@ -1410,7 +1427,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
} else { } else {
cnfexprEval(func->expr[0], &r[0], usrptr); cnfexprEval(func->expr[0], &r[0], usrptr);
ret->d.n = var2Number(&r[0], NULL); ret->d.n = var2Number(&r[0], NULL);
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
} }
ret->datatype = 'N'; ret->datatype = 'N';
break; break;
@ -1428,7 +1445,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
} }
ret->datatype = 'N'; ret->datatype = 'N';
if(bMustFree) free(str); if(bMustFree) free(str);
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
break; break;
case CNFFUNC_RE_EXTRACT: case CNFFUNC_RE_EXTRACT:
doFunc_re_extract(func, ret, usrptr); doFunc_re_extract(func, ret, usrptr);
@ -1461,9 +1478,9 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
} }
ret->datatype = 'S'; ret->datatype = 'S';
if(bMustFree) free(str); if(bMustFree) free(str);
if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr); varFreeMembers(&r[0]);
if(r[1].datatype == 'S') es_deleteStr(r[1].d.estr); varFreeMembers(&r[1]);
if(r[2].datatype == 'S') es_deleteStr(r[2].d.estr); varFreeMembers(&r[2]);
break; break;
case CNFFUNC_PRIFILT: case CNFFUNC_PRIFILT:
pPrifilt = (struct funcData_prifilt*) func->funcdata; pPrifilt = (struct funcData_prifilt*) func->funcdata;
@ -1549,8 +1566,8 @@ evalStrArrayCmp(es_str_t *estr_l, struct cnfarray* ar, int cmpop)
} }
#define FREE_BOTH_RET \ #define FREE_BOTH_RET \
if(r.datatype == 'S') es_deleteStr(r.d.estr); \ varFreeMembers(&r); \
if(l.datatype == 'S') es_deleteStr(l.d.estr) varFreeMembers(&l)
#define COMP_NUM_BINOP(x) \ #define COMP_NUM_BINOP(x) \
cnfexprEval(expr->l, &l, usrptr); \ cnfexprEval(expr->l, &l, usrptr); \
@ -1577,9 +1594,9 @@ evalStrArrayCmp(es_str_t *estr_l, struct cnfarray* ar, int cmpop)
#define FREE_TWO_STRINGS \ #define FREE_TWO_STRINGS \
if(bMustFree) es_deleteStr(estr_r); \ if(bMustFree) es_deleteStr(estr_r); \
if(expr->r->nodetype != 'S' && expr->r->nodetype != 'A' && r.datatype == 'S') es_deleteStr(r.d.estr); \ if(expr->r->nodetype != 'S' && expr->r->nodetype != 'A') varFreeMembers(&r); \
if(bMustFree2) es_deleteStr(estr_l); \ if(bMustFree2) es_deleteStr(estr_l); \
if(l.datatype == 'S') es_deleteStr(l.d.estr) varFreeMembers(&l)
/* evaluate an expression. /* evaluate an expression.
* Note that we try to avoid malloc whenever possible (because of * Note that we try to avoid malloc whenever possible (because of
@ -1630,7 +1647,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
if(bMustFree) es_deleteStr(estr_r); if(bMustFree) es_deleteStr(estr_r);
} }
} }
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
} }
} else if(l.datatype == 'J') { } else if(l.datatype == 'J') {
estr_l = var2String(&l, &bMustFree); estr_l = var2String(&l, &bMustFree);
@ -1652,7 +1669,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
if(bMustFree) es_deleteStr(estr_r); if(bMustFree) es_deleteStr(estr_r);
} }
} }
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
} }
if(bMustFree) es_deleteStr(estr_l); if(bMustFree) es_deleteStr(estr_l);
} else { } else {
@ -1669,9 +1686,9 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
} else { } else {
ret->d.n = (l.d.n == r.d.n); /*CMP*/ ret->d.n = (l.d.n == r.d.n); /*CMP*/
} }
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
} }
if(l.datatype == 'S') es_deleteStr(l.d.estr); varFreeMembers(&l);
break; break;
case CMP_NE: case CMP_NE:
cnfexprEval(expr->l, &l, usrptr); cnfexprEval(expr->l, &l, usrptr);
@ -1899,9 +1916,9 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
ret->d.n = 1ll; ret->d.n = 1ll;
else else
ret->d.n = 0ll; ret->d.n = 0ll;
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
} }
if(l.datatype == 'S') es_deleteStr(l.d.estr); varFreeMembers(&l);
break; break;
case AND: case AND:
cnfexprEval(expr->l, &l, usrptr); cnfexprEval(expr->l, &l, usrptr);
@ -1912,17 +1929,17 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
ret->d.n = 1ll; ret->d.n = 1ll;
else else
ret->d.n = 0ll; ret->d.n = 0ll;
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
} else { } else {
ret->d.n = 0ll; ret->d.n = 0ll;
} }
if(l.datatype == 'S') es_deleteStr(l.d.estr); varFreeMembers(&l);
break; break;
case NOT: case NOT:
cnfexprEval(expr->r, &r, usrptr); cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N'; ret->datatype = 'N';
ret->d.n = !var2Number(&r, &convok_r); ret->d.n = !var2Number(&r, &convok_r);
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
break; break;
case 'N': case 'N':
ret->datatype = 'N'; ret->datatype = 'N';
@ -1973,7 +1990,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
cnfexprEval(expr->r, &r, usrptr); cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N'; ret->datatype = 'N';
ret->d.n = -var2Number(&r, &convok_r); ret->d.n = -var2Number(&r, &convok_r);
if(r.datatype == 'S') es_deleteStr(r.d.estr); varFreeMembers(&r);
break; break;
case 'F': case 'F':
doFuncCall((struct cnffunc*) expr, ret, usrptr); doFuncCall((struct cnffunc*) expr, ret, usrptr);