#include #include #include #include #include "errhdl.h" #include "logfile.h" #include "coc.h" #include "lsc.h" #include "util.h" #define MC LSC_MAX_CMDS #define MAX_PAR 16 #define MAX_ARG 9 int LscEqPar(char *par, char *res) { char *p, *r, pbuf[SER_BUF_LEN], rbuf[SER_BUF_LEN]; int i,n,i1,i2; float f1, f2; p=par; r=res; while (p!=NULL) { if (r==NULL) { return(0); } p=str_split(pbuf, p, ','); str_trim(pbuf, pbuf, sizeof(pbuf)); r=str_split(rbuf, r, ','); str_trim(rbuf, rbuf, sizeof(rbuf)); if (pbuf[0]!='\0' && 0!=strcasecmp(pbuf, rbuf)) { i1=sscanf(pbuf, "%f", &f1); i2=sscanf(rbuf, "%f", &f2); if (i1!=1 || i2!=1 || abs(f1-f2)>1e-4+abs(f1)*5e-6) { logfileOut(LOG_WARN, "%s#%s\n", pbuf, rbuf); return(0); } } } return(1); } char *LscCmd(SerChannel *ser, const char *cmds) { va_list ap; char *blank, *colon, *qu, *res; const char *p, *this, *next, *cmd_ptr, *retreq; const char *list[MC*3]; char seg[SER_BUF_LEN], buf[SER_BUF_LEN], result[SER_BUF_LEN], par[SER_BUF_LEN]; char cmd[SER_BUF_LEN]; char varname[32]; Str_Buf sbuf; int nres, i, j, response; nres=0; response=0; str_link_buf(&sbuf, buf, sizeof(buf), STR_NOSEPARATOR); this=cmds; while (this!=NULL) { next=str_split(cmd, this, ';'); retreq=strchr(cmd, '>'); if (retreq!=NULL) { /* save pointer to return request */ i=retreq-cmd; cmd[i]='\0'; /* cut return request */ list[nres]=this+i; nres++; } cmd_ptr=sbuf.buf+sbuf.wrpos; /* pointer to command in buffer */ p=str_split(seg, cmd, '['); ERR_I(str_put_str(&sbuf, seg)); while (p!=NULL) { /* substitute variables */ p=str_split(varname, p, ']'); if (p==NULL) ERR_MSG("missing '\'"); ERR_I(CocPutVar(serverVarList, &sbuf, varname, 0)); p=str_split(seg, p, '['); ERR_I(str_put_str(&sbuf, seg)); } ERR_I(str_copy(cmd, cmd_ptr)); colon=strchr(cmd_ptr, ':'); if (colon!=NULL) { /* command with query */ blank=strchr(cmd_ptr, ' '); if (blank==NULL || blank>colon) { *colon=' '; blank=colon; } else { *colon=','; } list[nres]=colon+1; nres++; /* pointer to parameters */ list[nres]=cmd_ptr; nres++; /* pointer to command */ ERR_I(str_put_str(&sbuf, ";")); cmd[blank-cmd_ptr]='?'; /* build query */ if (colon==blank) colon++; cmd[colon-cmd_ptr]='\0'; ERR_I(str_put_str(&sbuf, cmd)); /* put query */ ERR_I(str_put_str(&sbuf, ";")); response=1; } else { qu=strchr(cmd, '?'); ERR_I(str_put_str(&sbuf, ";")); if (qu!=NULL) { /* command is a query */ response=1; if (retreq==NULL) ERR_MSG("missing return format"); list[nres]=NULL; nres++; } else { if (retreq!=NULL) ERR_MSG("no return request allowed after command without query "); } } this=next; } if (!response) { ERR_I(str_put_str(&sbuf, "busy?")); } else { buf[sbuf.wrpos-1]='\0'; /* strip off trailing ";" */ } ERR_P(res=SerCmd(ser, buf)); if (0==strcmp("?TMO", res)) ERR_MSG("timeout"); /* list[0..nres-1] contains a now: for a command with return request: - a pointer to a the request then, for a command with query: - a pointer to the parameters and - a pointer to the command this is repeated for every command */ /* check results */ this=res; for (i=0; i') { i++; } else { retreq=NULL; } } if (list[i]!=NULL) { qu=str_split(par, list[i], ';'); /* get parameters */ i++; if (!LscEqPar(par, result)) { /* try again with single command */ qu=strchr(qu, ';'); assert(list[i]!=NULL); str_copy(cmd, list[i]); if (qu!=NULL) cmd[qu-list[i]]='\0'; ERR_P(qu=SerCmd(ser, cmd)); if (!LscEqPar(par, qu)) ERR_MSG("result does not match"); } } if (retreq!=NULL) { /* query */ str_link_buf(&sbuf, result, 0, ','); str_split(par, retreq+1, ';'); p=par; while (p!=NULL) { p=str_split(varname, p, ','); if (varname[0]!='\0') { ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0)); } else { ERR_P(str_get_str(&sbuf, NULL)); } } i++; } } return(res); OnError: return(NULL); } int LscCmdChk(SerChannel *ser, char *cmds) { char *b, *o, *cn, *c, *d, *r, *res; char *clist[MC], *plist[MC], *rlist[MC], *olist[MC]; char obuf[SER_BUF_LEN], r1[SER_BUF_LEN]; int i,n,m,j,cnt,l; if (NULL!=strchr(cmds, '?')) ERR_COD(EINVAL); cn=cmds; o=&obuf[0]; m=MC; do { n=m; cn=str_splitx(cn, ';', clist, &n); for (i=0; id) { *d=' '; b=d; } else { *d=','; } plist[i]=d+1; l=strlen(c); if ((o-&obuf[0])+l+(d-c)+2>SER_BUF_LEN) ERR_COD(ENOBUFS); olist[i]=o; strcpy(o, c); o+=l; *o=';'; o++; strncpy(o, c, d-c); o[b-c]='?'; o+=d-c; if (b==d) o++; *o=';'; o++; }; o--; *o='\0'; cnt=0; do { cnt++; if (cnt>3) ERR_MSG("can not set parameter"); ERR_P(res=SerCmd(ser, obuf)); if (cnt>0) { if (0==strcmp(r1, res)) break; /* got two times the same result */ } strcpy(r1, res); j=n; r=str_splitx(res, ';', rlist, &n); if (r==NULL || n!=j) continue; for (i=0; i