mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-30 22:26:35 +00:00
Merge pull request #6180 from gemu2015/scripter-update
scripter expression brackets
This commit is contained in:
commit
266856eb28
@ -172,7 +172,9 @@ then
|
|||||||
|
|
||||||
remarks:
|
remarks:
|
||||||
the last closing bracket must be on a single line
|
the last closing bracket must be on a single line
|
||||||
the condition may not be enclosed in brackets
|
the condition may be enclosed in brackets
|
||||||
|
and on the same line conditions may be bracketed e.g. if ((a==b) and ((c==d) or (c==e)) and (s!="x"))
|
||||||
|
|
||||||
|
|
||||||
>**break** exits a section or terminates a for next loop
|
>**break** exits a section or terminates a for next loop
|
||||||
**dpx** sets decimal precision to x (0-9)
|
**dpx** sets decimal precision to x (0-9)
|
||||||
|
@ -1935,7 +1935,111 @@ void toSLog(const char *str) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Evaluate_expression(char *lp,uint8_t and_or, uint8_t *result,JsonObject *jo) {
|
||||||
|
float fvar,*dfvar,fvar1;
|
||||||
|
uint8_t numeric;
|
||||||
|
struct T_INDEX ind;
|
||||||
|
uint8_t vtype=0,lastop;
|
||||||
|
uint8_t res=0;
|
||||||
|
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
|
||||||
|
if (*lp=='(') {
|
||||||
|
lp++;
|
||||||
|
lp=Evaluate_expression(lp,and_or,result,jo);
|
||||||
|
lp++;
|
||||||
|
// check for next and or
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
if (!strncmp(lp,"or",2)) {
|
||||||
|
lp+=2;
|
||||||
|
and_or=1;
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
lp=Evaluate_expression(lp,and_or,result,jo);
|
||||||
|
} else if (!strncmp(lp,"and",3)) {
|
||||||
|
lp+=3;
|
||||||
|
and_or=2;
|
||||||
|
SCRIPT_SKIP_SPACES
|
||||||
|
lp=Evaluate_expression(lp,and_or,result,jo);
|
||||||
|
}
|
||||||
|
return lp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare
|
||||||
|
dfvar=&fvar;
|
||||||
|
glob_script_mem.glob_error=0;
|
||||||
|
char *slp=lp;
|
||||||
|
numeric=1;
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,dfvar,0);
|
||||||
|
if (glob_script_mem.glob_error==1) {
|
||||||
|
// was string, not number
|
||||||
|
char cmpstr[SCRIPT_MAXSSIZE];
|
||||||
|
lp=slp;
|
||||||
|
numeric=0;
|
||||||
|
// get the string
|
||||||
|
lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
|
||||||
|
lp=getop(lp,&lastop);
|
||||||
|
// compare string
|
||||||
|
char str[SCRIPT_MAXSSIZE];
|
||||||
|
lp=GetStringResult(lp,OPER_EQU,str,jo);
|
||||||
|
if (lastop==OPER_EQUEQU || lastop==OPER_NOTEQU) {
|
||||||
|
uint8_t res=0;
|
||||||
|
res=strcmp(cmpstr,str);
|
||||||
|
if (lastop==OPER_EQUEQU) res=!res;
|
||||||
|
if (!and_or) {
|
||||||
|
*result=res;
|
||||||
|
} else if (and_or==1) {
|
||||||
|
*result|=res;
|
||||||
|
} else {
|
||||||
|
*result&=res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// numeric
|
||||||
|
// evaluate operand
|
||||||
|
lp=getop(lp,&lastop);
|
||||||
|
|
||||||
|
lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo);
|
||||||
|
switch (lastop) {
|
||||||
|
case OPER_EQUEQU:
|
||||||
|
res=(*dfvar==fvar1);
|
||||||
|
break;
|
||||||
|
case OPER_NOTEQU:
|
||||||
|
res=(*dfvar!=fvar1);
|
||||||
|
break;
|
||||||
|
case OPER_LOW:
|
||||||
|
res=(*dfvar<fvar1);
|
||||||
|
break;
|
||||||
|
case OPER_LOWEQU:
|
||||||
|
res=(*dfvar<=fvar1);
|
||||||
|
break;
|
||||||
|
case OPER_GRT:
|
||||||
|
res=(*dfvar>fvar1);
|
||||||
|
break;
|
||||||
|
case OPER_GRTEQU:
|
||||||
|
res=(*dfvar>=fvar1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// error
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!and_or) {
|
||||||
|
*result=res;
|
||||||
|
} else if (and_or==1) {
|
||||||
|
*result|=res;
|
||||||
|
} else {
|
||||||
|
*result&=res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
#if SCRIPT_DEBUG>0
|
||||||
|
char tbuff[128];
|
||||||
|
sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d line: ",(int32_t)*dfvar,(int32_t)fvar1,*result);
|
||||||
|
toLogEOL(tbuff,lp);
|
||||||
|
#endif
|
||||||
|
return lp;
|
||||||
|
}
|
||||||
|
|
||||||
//#define IFTHEN_DEBUG
|
//#define IFTHEN_DEBUG
|
||||||
|
|
||||||
@ -2305,19 +2409,15 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||||||
|
|
||||||
// check for variable result
|
// check for variable result
|
||||||
if (if_state[ifstck]==1) {
|
if (if_state[ifstck]==1) {
|
||||||
// compare
|
// evaluate exxpression
|
||||||
dfvar=&fvar;
|
lp=Evaluate_expression(lp,and_or,&if_result[ifstck],jo);
|
||||||
glob_script_mem.glob_error=0;
|
SCRIPT_SKIP_SPACES
|
||||||
char *slp=lp;
|
if (*lp=='{' && if_state[ifstck]==1) {
|
||||||
numeric=1;
|
lp+=1; // then
|
||||||
lp=GetNumericResult(lp,OPER_EQU,dfvar,0);
|
if_state[ifstck]=2;
|
||||||
if (glob_script_mem.glob_error==1) {
|
if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
|
||||||
// was string, not number
|
|
||||||
lp=slp;
|
|
||||||
numeric=0;
|
|
||||||
// get the string
|
|
||||||
lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
|
|
||||||
}
|
}
|
||||||
|
goto next_line;
|
||||||
} else {
|
} else {
|
||||||
lp=isvar(lp,&vtype,&ind,&sysvar,0,0);
|
lp=isvar(lp,&vtype,&ind,&sysvar,0,0);
|
||||||
if (vtype!=VAR_NV) {
|
if (vtype!=VAR_NV) {
|
||||||
@ -2335,180 +2435,110 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||||||
sysv_type=0;
|
sysv_type=0;
|
||||||
}
|
}
|
||||||
numeric=1;
|
numeric=1;
|
||||||
} else {
|
lp=getop(lp,&lastop);
|
||||||
// string result
|
char *slp=lp;
|
||||||
numeric=0;
|
glob_script_mem.glob_error=0;
|
||||||
sindex=index;
|
lp=GetNumericResult(lp,OPER_EQU,&fvar,jo);
|
||||||
}
|
if (glob_script_mem.glob_error==1) {
|
||||||
}
|
// mismatch was string, not number
|
||||||
}
|
// get the string and convert to number
|
||||||
// evaluate operand
|
lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
|
||||||
lp=getop(lp,&lastop);
|
fvar=CharToFloat(cmpstr);
|
||||||
if (if_state[ifstck]==1) {
|
}
|
||||||
if (numeric) {
|
switch (lastop) {
|
||||||
uint8_t res=0;
|
case OPER_EQU:
|
||||||
lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo);
|
if (glob_script_mem.var_not_found) {
|
||||||
switch (lastop) {
|
if (!js) toLog("var not found\n");
|
||||||
case OPER_EQUEQU:
|
goto next_line;
|
||||||
res=(*dfvar==fvar1);
|
}
|
||||||
break;
|
*dfvar=fvar;
|
||||||
case OPER_NOTEQU:
|
break;
|
||||||
res=(*dfvar!=fvar1);
|
case OPER_PLSEQU:
|
||||||
break;
|
*dfvar+=fvar;
|
||||||
case OPER_LOW:
|
break;
|
||||||
res=(*dfvar<fvar1);
|
case OPER_MINEQU:
|
||||||
break;
|
*dfvar-=fvar;
|
||||||
case OPER_LOWEQU:
|
break;
|
||||||
res=(*dfvar<=fvar1);
|
case OPER_MULEQU:
|
||||||
break;
|
*dfvar*=fvar;
|
||||||
case OPER_GRT:
|
break;
|
||||||
res=(*dfvar>fvar1);
|
case OPER_DIVEQU:
|
||||||
break;
|
*dfvar/=fvar;
|
||||||
case OPER_GRTEQU:
|
break;
|
||||||
res=(*dfvar>=fvar1);
|
case OPER_PERCEQU:
|
||||||
break;
|
*dfvar=fmodf(*dfvar,fvar);
|
||||||
default:
|
break;
|
||||||
// error
|
case OPER_ANDEQU:
|
||||||
break;
|
*dfvar=(uint32_t)*dfvar&(uint32_t)fvar;
|
||||||
}
|
break;
|
||||||
|
case OPER_OREQU:
|
||||||
if (!and_or) {
|
*dfvar=(uint32_t)*dfvar|(uint32_t)fvar;
|
||||||
if_result[ifstck]=res;
|
break;
|
||||||
} else if (and_or==1) {
|
case OPER_XOREQU:
|
||||||
if_result[ifstck]|=res;
|
*dfvar=(uint32_t)*dfvar^(uint32_t)fvar;
|
||||||
} else {
|
break;
|
||||||
if_result[ifstck]&=res;
|
default:
|
||||||
}
|
// error
|
||||||
#if SCRIPT_DEBUG>0
|
break;
|
||||||
char tbuff[128];
|
}
|
||||||
sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d line: ",(int32_t)*dfvar,(int32_t)fvar1,if_result[ifstck]);
|
// var was changed
|
||||||
toLogEOL(tbuff,lp);
|
glob_script_mem.type[globvindex].bits.changed=1;
|
||||||
#endif
|
if (glob_script_mem.type[globvindex].bits.is_filter) {
|
||||||
|
if (globaindex>=0) {
|
||||||
} else {
|
Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
|
||||||
// compare string
|
} else {
|
||||||
char str[SCRIPT_MAXSSIZE];
|
Set_MFilter(glob_script_mem.type[globvindex].index,*dfvar);
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
|
||||||
if (lastop==OPER_EQUEQU || lastop==OPER_NOTEQU) {
|
|
||||||
uint8_t res=0;
|
|
||||||
res=strcmp(cmpstr,str);
|
|
||||||
if (lastop==OPER_EQUEQU) res=!res;
|
|
||||||
if (!and_or) {
|
|
||||||
if_result[ifstck]=res;
|
|
||||||
} else if (and_or==1) {
|
|
||||||
if_result[ifstck]|=res;
|
|
||||||
} else {
|
|
||||||
if_result[ifstck]&=res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SCRIPT_SKIP_SPACES
|
|
||||||
if (*lp=='{' && if_state[ifstck]==1) {
|
|
||||||
lp+=1; // then
|
|
||||||
if_state[ifstck]=2;
|
|
||||||
if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
|
|
||||||
}
|
|
||||||
goto next_line;
|
|
||||||
} else {
|
|
||||||
if (numeric) {
|
|
||||||
char *slp=lp;
|
|
||||||
glob_script_mem.glob_error=0;
|
|
||||||
lp=GetNumericResult(lp,OPER_EQU,&fvar,jo);
|
|
||||||
if (glob_script_mem.glob_error==1) {
|
|
||||||
// mismatch was string, not number
|
|
||||||
// get the string and convert to number
|
|
||||||
lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
|
|
||||||
fvar=CharToFloat(cmpstr);
|
|
||||||
}
|
|
||||||
switch (lastop) {
|
|
||||||
case OPER_EQU:
|
|
||||||
if (glob_script_mem.var_not_found) {
|
|
||||||
if (!js) toLog("var not found\n");
|
|
||||||
goto next_line;
|
|
||||||
}
|
}
|
||||||
*dfvar=fvar;
|
}
|
||||||
break;
|
|
||||||
case OPER_PLSEQU:
|
if (sysv_type) {
|
||||||
*dfvar+=fvar;
|
switch (sysv_type) {
|
||||||
break;
|
case SCRIPT_LOGLEVEL:
|
||||||
case OPER_MINEQU:
|
glob_script_mem.script_loglevel=*dfvar;
|
||||||
*dfvar-=fvar;
|
break;
|
||||||
break;
|
case SCRIPT_TELEPERIOD:
|
||||||
case OPER_MULEQU:
|
if (*dfvar<10) *dfvar=10;
|
||||||
*dfvar*=fvar;
|
if (*dfvar>300) *dfvar=300;
|
||||||
break;
|
Settings.tele_period=*dfvar;
|
||||||
case OPER_DIVEQU:
|
break;
|
||||||
*dfvar/=fvar;
|
}
|
||||||
break;
|
sysv_type=0;
|
||||||
case OPER_PERCEQU:
|
}
|
||||||
*dfvar=fmodf(*dfvar,fvar);
|
|
||||||
break;
|
|
||||||
case OPER_ANDEQU:
|
|
||||||
*dfvar=(uint32_t)*dfvar&(uint32_t)fvar;
|
|
||||||
break;
|
|
||||||
case OPER_OREQU:
|
|
||||||
*dfvar=(uint32_t)*dfvar|(uint32_t)fvar;
|
|
||||||
break;
|
|
||||||
case OPER_XOREQU:
|
|
||||||
*dfvar=(uint32_t)*dfvar^(uint32_t)fvar;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// error
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// var was changed
|
|
||||||
glob_script_mem.type[globvindex].bits.changed=1;
|
|
||||||
if (glob_script_mem.type[globvindex].bits.is_filter) {
|
|
||||||
if (globaindex>=0) {
|
|
||||||
Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
|
|
||||||
} else {
|
} else {
|
||||||
Set_MFilter(glob_script_mem.type[globvindex].index,*dfvar);
|
// string result
|
||||||
}
|
numeric=0;
|
||||||
}
|
sindex=index;
|
||||||
|
// string result
|
||||||
|
char str[SCRIPT_MAXSSIZE];
|
||||||
|
char *slp=lp;
|
||||||
|
lp=getop(lp,&lastop);
|
||||||
|
lp=GetStringResult(lp,OPER_EQU,str,jo);
|
||||||
|
if (!js && glob_script_mem.var_not_found) {
|
||||||
|
// mismatch
|
||||||
|
lp=GetNumericResult(slp,OPER_EQU,&fvar,0);
|
||||||
|
dtostrfd(fvar,6,str);
|
||||||
|
glob_script_mem.var_not_found=0;
|
||||||
|
}
|
||||||
|
|
||||||
if (sysv_type) {
|
if (!glob_script_mem.var_not_found) {
|
||||||
switch (sysv_type) {
|
// var was changed
|
||||||
case SCRIPT_LOGLEVEL:
|
glob_script_mem.type[globvindex].bits.changed=1;
|
||||||
glob_script_mem.script_loglevel=*dfvar;
|
if (lastop==OPER_EQU) {
|
||||||
break;
|
strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
|
||||||
case SCRIPT_TELEPERIOD:
|
} else if (lastop==OPER_PLSEQU) {
|
||||||
if (*dfvar<10) *dfvar=10;
|
strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
|
||||||
if (*dfvar>300) *dfvar=300;
|
}
|
||||||
Settings.tele_period=*dfvar;
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
sysv_type=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
}
|
||||||
// string result
|
SCRIPT_SKIP_SPACES
|
||||||
char str[SCRIPT_MAXSSIZE];
|
if (*lp=='{' && if_state[ifstck]==3) {
|
||||||
char *slp=lp;
|
lp+=1; // else
|
||||||
lp=GetStringResult(lp,OPER_EQU,str,jo);
|
//if_state[ifstck]=3;
|
||||||
if (!js && glob_script_mem.var_not_found) {
|
}
|
||||||
// mismatch
|
goto next_line;
|
||||||
lp=GetNumericResult(slp,OPER_EQU,&fvar,0);
|
}
|
||||||
dtostrfd(fvar,6,str);
|
|
||||||
glob_script_mem.var_not_found=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glob_script_mem.var_not_found) {
|
|
||||||
// var was changed
|
|
||||||
glob_script_mem.type[globvindex].bits.changed=1;
|
|
||||||
if (lastop==OPER_EQU) {
|
|
||||||
strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
|
|
||||||
} else if (lastop==OPER_PLSEQU) {
|
|
||||||
strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SCRIPT_SKIP_SPACES
|
|
||||||
if (*lp=='{' && if_state[ifstck]==3) {
|
|
||||||
lp+=1; // else
|
|
||||||
//if_state[ifstck]=3;
|
|
||||||
}
|
|
||||||
goto next_line;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// decode line
|
// decode line
|
||||||
if (*lp=='>' && tlen==1) {
|
if (*lp=='>' && tlen==1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user