Merge pull request #16539 from gemu2015/scripter_update

nested loops etc
This commit is contained in:
Jason2866 2022-09-16 13:13:08 +02:00 committed by GitHub
commit 5eb43d21b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -80,7 +80,7 @@ uint32_t EncodeLightId(uint8_t relay_id);
uint32_t DecodeLightId(uint32_t hue_id); uint32_t DecodeLightId(uint32_t hue_id);
char *web_send_line(char mc, char *lp); char *web_send_line(char mc, char *lp);
int32_t web_send_file(char mc, char *file); int32_t web_send_file(char mc, char *file);
char *Get_esc_char(char *cp, char *esc_chr);
#define SPECIAL_EEPMODE_SIZE 6200 #define SPECIAL_EEPMODE_SIZE 6200
#ifndef STASK_STACK #ifndef STASK_STACK
@ -438,6 +438,7 @@ struct SCRIPT_MEM {
void *script_mem; void *script_mem;
uint16_t script_mem_size; uint16_t script_mem_size;
uint8_t script_dprec; uint8_t script_dprec;
char script_sepc;
uint8_t script_lzero; uint8_t script_lzero;
uint8_t var_not_found; uint8_t var_not_found;
uint8_t glob_error; uint8_t glob_error;
@ -499,7 +500,7 @@ void flt2char(float num, char *nbuff) {
dtostrfd(num, glob_script_mem.script_dprec, nbuff); dtostrfd(num, glob_script_mem.script_dprec, nbuff);
} }
// convert float to char with leading zeros // convert float to char with leading zeros
void f2char(float num, uint32_t dprec, uint32_t lzeros, char *nbuff) { void f2char(float num, uint32_t dprec, uint32_t lzeros, char *nbuff, char dsep) {
dtostrfd(num, dprec, nbuff); dtostrfd(num, dprec, nbuff);
if (lzeros > 1) { if (lzeros > 1) {
// check leading zeros // check leading zeros
@ -522,6 +523,13 @@ void f2char(float num, uint32_t dprec, uint32_t lzeros, char *nbuff) {
strcpy(nbuff,cpbuf); strcpy(nbuff,cpbuf);
} }
} }
if (dsep != '.') {
for (uint16_t cnt = 0; cnt < strlen(nbuff); cnt++) {
if (nbuff[cnt] == '.') {
nbuff[cnt] = dsep;
}
}
}
} }
@ -791,7 +799,10 @@ char *script;
*snp_p ++= strings_p; *snp_p ++= strings_p;
while (*op != '\"') { while (*op != '\"') {
if (*op == SCRIPT_EOL) break; if (*op == SCRIPT_EOL) break;
*strings_p++ = *op++; char iob;
op = Get_esc_char(op, &iob);
//*strings_p++ = *op++;
*strings_p++ = iob;
} }
*strings_p++ = 0; *strings_p++ = 0;
vtypes[vars].bits.is_string = 1; vtypes[vars].bits.is_string = 1;
@ -970,6 +981,7 @@ char *script;
glob_script_mem.numvars = vars; glob_script_mem.numvars = vars;
glob_script_mem.script_dprec = SCRIPT_FLOAT_PRECISION; glob_script_mem.script_dprec = SCRIPT_FLOAT_PRECISION;
glob_script_mem.script_lzero = 0; glob_script_mem.script_lzero = 0;
glob_script_mem.script_sepc = '.';
glob_script_mem.script_loglevel = LOG_LEVEL_INFO; glob_script_mem.script_loglevel = LOG_LEVEL_INFO;
@ -980,7 +992,7 @@ char *script;
} else { } else {
char string[32]; char string[32];
f2char(glob_script_mem.fvars[dvtp[count].index], glob_script_mem.script_dprec, glob_script_mem.script_lzero, string); f2char(glob_script_mem.fvars[dvtp[count].index], glob_script_mem.script_dprec, glob_script_mem.script_lzero, string, '.');
toLog(string); toLog(string);
} }
} }
@ -1997,6 +2009,33 @@ char *isargs(char *lp, uint32_t isind) {
return lp; return lp;
} }
char *Get_esc_char(char *cp, char *esc_chr) {
char iob = *cp;
if (iob == '\\') {
cp++;
if (*cp == 't') {
iob = '\t';
} else if (*cp == 'n') {
iob = '\n';
} else if (*cp == 'r') {
iob = '\r';
} else if (*cp == '0' && *(cp + 1) == 'x') {
cp += 2;
iob = strtol(cp, 0, 16);
cp++;
} else if (*cp == '\\') {
iob = '\\';
}
else {
cp--;
}
}
*esc_chr = iob;
cp++;
return cp;
}
char *isget(char *lp, char *sp, uint32_t isind, struct GVARS *gv) { char *isget(char *lp, char *sp, uint32_t isind, struct GVARS *gv) {
float fvar; float fvar;
lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0); lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
@ -2061,29 +2100,9 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
lp++; lp++;
while (*lp != '"') { while (*lp != '"') {
if (*lp == 0 || *lp == SCRIPT_EOL) break; if (*lp == 0 || *lp == SCRIPT_EOL) break;
uint8_t iob = *lp; char iob;
if (iob == '\\') { lp = Get_esc_char(lp, &iob);
lp++;
if (*lp == 't') {
iob = '\t';
} else if (*lp == 'n') {
iob = '\n';
} else if (*lp == 'r') {
iob = '\r';
} else if (*lp == '0' && *(lp+1) == 'x') {
lp += 2;
iob = strtol(lp, 0, 16);
lp++;
} else if (*lp == '\\') {
iob = '\\';
} else {
lp--;
}
if (sp) *sp++ = iob; if (sp) *sp++ = iob;
} else {
if (sp) *sp++ = iob;
}
lp++;
} }
if (sp) *sp = 0; if (sp) *sp = 0;
*vtype = STR_RES; *vtype = STR_RES;
@ -2569,6 +2588,10 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv);
while (*lp==' ') lp++; while (*lp==' ') lp++;
glob_script_mem.script_lzero = fvar; glob_script_mem.script_lzero = fvar;
if (*lp == ',' || *lp == '.') {
glob_script_mem.script_sepc = *lp;
lp++;
}
lp = GetNumericArgument(lp , OPER_EQU, &fvar, gv); lp = GetNumericArgument(lp , OPER_EQU, &fvar, gv);
while (*lp==' ') lp++; while (*lp==' ') lp++;
glob_script_mem.script_dprec = fvar; glob_script_mem.script_dprec = fvar;
@ -3979,7 +4002,13 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
char token[2]; char token[2];
if (*lp == '\'') {
lp++;
lp = Get_esc_char(lp, token);
lp++;
} else {
token[0] = *lp++; token[0] = *lp++;
}
token[1] = 0; token[1] = 0;
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
@ -4033,8 +4062,10 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
lp += 2; lp += 2;
uint8_t dprec = glob_script_mem.script_dprec; uint8_t dprec = glob_script_mem.script_dprec;
uint8_t lzero = glob_script_mem.script_lzero; uint8_t lzero = glob_script_mem.script_lzero;
char dsep = glob_script_mem.script_sepc;
if (isdigit(*lp)) { if (isdigit(*lp)) {
if (*(lp + 1) == '.') { if (*(lp + 1) == '.' || *(lp + 1) == ',') {
dsep = *(lp + 1);
lzero = *lp & 0xf; lzero = *lp & 0xf;
lp += 2; lp += 2;
dprec = *lp & 0xf; dprec = *lp & 0xf;
@ -4046,7 +4077,7 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
} }
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
char str[SCRIPT_MAXSSIZE]; char str[SCRIPT_MAXSSIZE];
f2char(fvar, dprec, lzero, str); f2char(fvar, dprec, lzero, str, dsep);
if (sp) strlcpy(sp, str, glob_script_mem.max_ssize); if (sp) strlcpy(sp, str, glob_script_mem.max_ssize);
lp++; lp++;
len = 0; len = 0;
@ -4853,6 +4884,16 @@ extern char *SML_GetSVal(uint32_t index);
goto nfuncexit; goto nfuncexit;
} }
#endif #endif
if (!strncmp(lp, "tc(", 3)) {
lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv);
lp++;
if (sp) {
sp[0] = fvar;
sp[1] = 0;
}
len = 0;
goto strexit;
}
break; break;
case 'u': case 'u':
if (!strncmp(vname, "uptime", 6)) { if (!strncmp(vname, "uptime", 6)) {
@ -5446,6 +5487,7 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst
uint16_t count; uint16_t count;
uint8_t vtype; uint8_t vtype;
uint8_t dprec = glob_script_mem.script_dprec; uint8_t dprec = glob_script_mem.script_dprec;
char dsep = glob_script_mem.script_sepc;
uint8_t lzero = glob_script_mem.script_lzero; uint8_t lzero = glob_script_mem.script_lzero;
float fvar; float fvar;
cp = srcbuf; cp = srcbuf;
@ -5460,7 +5502,8 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst
dstbuf[count] = *cp++; dstbuf[count] = *cp++;
} else { } else {
if (isdigit(*cp)) { if (isdigit(*cp)) {
if (*(cp+1) == '.') { if (*(cp + 1) == '.' || *(cp + 1) == ',') {
dsep = *(cp + 1);
lzero = *cp & 0xf; lzero = *cp & 0xf;
cp+=2; cp+=2;
} }
@ -5469,6 +5512,7 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst
} else { } else {
dprec = glob_script_mem.script_dprec; dprec = glob_script_mem.script_dprec;
lzero = glob_script_mem.script_lzero; lzero = glob_script_mem.script_lzero;
dsep = glob_script_mem.script_sepc;
} }
if (*cp=='(') { if (*cp=='(') {
// math expression // math expression
@ -5480,7 +5524,7 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst
glob_script_mem.glob_error = 0; glob_script_mem.glob_error = 0;
cp = GetStringArgument(slp, OPER_EQU, string, 0); cp = GetStringArgument(slp, OPER_EQU, string, 0);
} else { } else {
f2char(fvar, dprec, lzero, string); f2char(fvar, dprec, lzero, string, dsep);
} }
uint8_t slen = strlen(string); uint8_t slen = strlen(string);
if (count + slen < dstsize - 1) { if (count + slen < dstsize - 1) {
@ -5494,7 +5538,7 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst
// found variable as result // found variable as result
if (vtype==NUM_RES || (vtype&STYPE)==0) { if (vtype==NUM_RES || (vtype&STYPE)==0) {
// numeric result // numeric result
f2char(fvar, dprec, lzero, string); f2char(fvar, dprec, lzero, string, dsep);
} else { } else {
// string result // string result
} }
@ -5871,9 +5915,15 @@ int16_t retval;
return retval; return retval;
} }
#define SCRIPT_LOOP_NEST 3
int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
uint8_t vtype = 0, sindex, xflg, floop = 0, globvindex, fromscriptcmd = 0; uint8_t vtype = 0, sindex, xflg, globvindex, fromscriptcmd = 0;
char *lp_next; // 22 bytes per nested loop
uint8_t floop[SCRIPT_LOOP_NEST] = {0, 0, 0};
int8_t loopdepth = -1;
char *lp_next[SCRIPT_LOOP_NEST];
char *cv_ptr[SCRIPT_LOOP_NEST];
float *cv_count[SCRIPT_LOOP_NEST], cv_max[SCRIPT_LOOP_NEST], cv_inc[SCRIPT_LOOP_NEST];
int16_t globaindex, saindex; int16_t globaindex, saindex;
struct T_INDEX ind; struct T_INDEX ind;
uint8_t operand, lastop, numeric = 1, if_state[IF_NEST], if_exe[IF_NEST], if_result[IF_NEST], and_or, ifstck = 0; uint8_t operand, lastop, numeric = 1, if_state[IF_NEST], if_exe[IF_NEST], if_result[IF_NEST], and_or, ifstck = 0;
@ -5881,8 +5931,8 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
if_result[ifstck] = 0; if_result[ifstck] = 0;
if_exe[ifstck] = 1; if_exe[ifstck] = 1;
char cmpstr[SCRIPT_MAXSSIZE]; char cmpstr[SCRIPT_MAXSSIZE];
float *dfvar, *cv_count, cv_max, cv_inc; float *dfvar;
char *cv_ptr;
float fvar = 0, fvar1, sysvar, swvar; float fvar = 0, fvar1, sysvar, swvar;
uint8_t section = 0, sysv_type = 0, swflg = 0; uint8_t section = 0, sysv_type = 0, swflg = 0;
@ -5903,10 +5953,11 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
while (1) { while (1) {
// check line // check line
// skip leading spaces // skip leading spaces and tabs
startline: startline:
SCRIPT_SKIP_SPACES while (*lp == '\t' || *lp == ' ') {
while (*lp == '\t') {lp++;} lp++;
}
// skip empty line // skip empty line
SCRIPT_SKIP_EOL SCRIPT_SKIP_EOL
// skip comment // skip comment
@ -6008,28 +6059,29 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
// simple implementation, zero loop count not supported // simple implementation, zero loop count not supported
lp += 3; lp += 3;
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
lp_next = 0; loopdepth++;
if (loopdepth >= SCRIPT_LOOP_NEST) {
loopdepth = SCRIPT_LOOP_NEST - 1;
}
lp_next[loopdepth] = 0;
lp = isvar(lp, &vtype, &ind, 0, 0, gv); lp = isvar(lp, &vtype, &ind, 0, 0, gv);
if ((vtype != VAR_NV) && (vtype & STYPE) == 0) { if ((vtype != VAR_NV) && (vtype & STYPE) == 0) {
// numeric var // numeric var
uint8_t index = glob_script_mem.type[ind.index].index; uint8_t index = glob_script_mem.type[ind.index].index;
cv_count = &glob_script_mem.fvars[index]; cv_count[loopdepth] = &glob_script_mem.fvars[index];
SCRIPT_SKIP_SPACES lp = GetNumericArgument(lp, OPER_EQU, cv_count[loopdepth], 0);
lp = GetNumericArgument(lp, OPER_EQU, cv_count, 0); lp = GetNumericArgument(lp, OPER_EQU, &cv_max[loopdepth], 0);
SCRIPT_SKIP_SPACES lp = GetNumericArgument(lp, OPER_EQU, &cv_inc[loopdepth], 0);
lp = GetNumericArgument(lp, OPER_EQU, &cv_max, 0);
SCRIPT_SKIP_SPACES
lp = GetNumericArgument(lp, OPER_EQU, &cv_inc, 0);
//SCRIPT_SKIP_EOL //SCRIPT_SKIP_EOL
cv_ptr = lp; cv_ptr[loopdepth] = lp;
if (*cv_count<=cv_max && cv_inc>0) { if (*cv_count[loopdepth] <= cv_max[loopdepth] && cv_inc[loopdepth] > 0) {
// inc loop // inc loop
floop = 1; floop[loopdepth] = 1;
} else { } else {
// dec loop // dec loop
floop = 2; floop[loopdepth] = 2;
if (cv_inc>0) { if (cv_inc[loopdepth] > 0) {
floop = 1; floop[loopdepth] = 1;
} }
} }
} else { } else {
@ -6037,23 +6089,40 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
toLogEOL("for error", lp); toLogEOL("for error", lp);
} }
} else if (!strncmp(lp, "next", 4)) { } else if (!strncmp(lp, "next", 4)) {
lp_next = lp; getnext:
if (floop>0) { if (loopdepth >= 0) {
lp_next[loopdepth] = lp;
if (floop[loopdepth] > 0) {
// for next loop // for next loop
*cv_count += cv_inc; *cv_count[loopdepth] += cv_inc[loopdepth];
if (floop==1) { if (floop[loopdepth] == 1) {
if (*cv_count<=cv_max) { if (*cv_count[loopdepth] <= cv_max[loopdepth]) {
lp = cv_ptr; lp = cv_ptr[loopdepth];
} else { } else {
lp += 4; lp += 4;
floop = 0; floop[loopdepth] = 0;
loopdepth--;
if (loopdepth < -1) {
loopdepth = -1;
}
} }
} else { } else {
if (*cv_count>=cv_max) { if (*cv_count[loopdepth] >= cv_max[loopdepth]) {
lp = cv_ptr; lp = cv_ptr[loopdepth];
} else { } else {
lp += 4; lp += 4;
floop = 0; floop[loopdepth] = 0;
loopdepth--;
if (loopdepth < -1) {
loopdepth = -1;
}
}
}
} else {
lp += 4;
loopdepth--;
if (loopdepth < -1) {
loopdepth = -1;
} }
} }
} }
@ -6137,21 +6206,26 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
goto next_line; goto next_line;
} else if (!strncmp(lp, "break", 5)) { } else if (!strncmp(lp, "break", 5)) {
lp += 5; lp += 5;
if (floop) { if (loopdepth >= 0) {
if (floop[loopdepth] ) {
// should break loop // should break loop
if (lp_next) { if (lp_next[loopdepth]) {
lp = lp_next; lp = lp_next[loopdepth];
}
floop[loopdepth] = 0;
goto getnext;
} }
floop = 0;
} else { } else {
section = 99; section = 99;
// leave immediately // leave immediately
}
goto next_line; goto next_line;
}
} else if (!strncmp(lp, "dp", 2) && isdigit(*(lp + 2))) { } else if (!strncmp(lp, "dp", 2) && isdigit(*(lp + 2))) {
lp += 2; lp += 2;
// number precision // number precision
if (*(lp + 1)== '.') { if (*(lp + 1) == '.' || *(lp + 1) == ',' ) {
glob_script_mem.script_sepc = *(lp + 1);
glob_script_mem.script_lzero = atoi(lp); glob_script_mem.script_lzero = atoi(lp);
lp += 2; lp += 2;
} }
@ -9943,7 +10017,7 @@ exgc:
} else { } else {
fval = fp[cnt]; fval = fp[cnt];
} }
f2char(fval, glob_script_mem.script_dprec, glob_script_mem.script_lzero, acbuff); f2char(fval, glob_script_mem.script_dprec, glob_script_mem.script_lzero, acbuff, '.');
WSContentSend_P("%s", acbuff); WSContentSend_P("%s", acbuff);
if (ind < anum - 1) { WSContentSend_P(","); } if (ind < anum - 1) { WSContentSend_P(","); }
} }