#include #include #include #include #include #include "err_handling.h" #include "coc_logfile.h" #include "coc_util.h" #include "tecs_lsc.h" #include "str_util.h" #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_INFO, "%s#%s\n", pbuf, rbuf); return(0); } } } return(1); } #define nLIST 30 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[nLIST]; 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++; assert(nres<=nLIST); } 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++; assert(nres<=nLIST); /* pointer to parameters */ list[nres]=cmd_ptr; nres++; assert(nres<=nLIST); /* 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++; assert(nres<=nLIST); } 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==strncmp("?TMO", res, 4)) 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)) { if (0!=strcmp(result, qu)) { ERR_MSG("result does not match"); } else { ERR_MSG("result does not match command"); } } } } 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') { if (p==NULL) { /* last element: get rest of line */ sbuf.sep='\0'; } ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0)); } else { ERR_P(str_get_str(&sbuf, NULL)); } } } } return(res); OnError: return(NULL); }