int rnv_start_tag(int *curp,int *prevp,char *name,char **attrs) { int ok=1; ok=rnv_start_tag_open(curp,prevp,name)&&ok; while(*curp!=rn_notAllowed) { if(!(*attrs)) break; ok = rnv_attribute(curp,prevp,*attrs,*(attrs+1))&&ok; attrs+=2; } if(*curp!=rn_notAllowed) ok=rnv_start_tag_close(curp,prevp,name)&&ok; return ok; }
static int query(void) { int i,j,n,dn, kwd, patno,prevno, ok=0; char *name; n=0; for(;;) { if(n==n_q) { if(len_q-n_q<LEN_B) quebuf=(char*)m_stretch(quebuf,len_q=n_q+LEN_B,n_q,sizeof(char)); dn=read(0,quebuf+n_q,LEN_B); if(dn<0) longjmp(IOER,1); if(dn==0) {errno=EIO; longjmp(IOER,1);} n_q+=dn; } if(quebuf[n++]=='\0') break; } j=endtok(i=tok(0)); if((kwd=s_ntab(quebuf+i,j-i,kwdtab,NKWD))==QUIT) {resp(1,0,0); return 0;} switch(kwd) { case START: j=endtok((i=tok(j))); patno=0; while(i!=j) patno=patno*10+quebuf[i++]-'0'; if(patno>=n_st) goto PROTER; ok=1; patno=starts[patno]; break; case STO: case ATT: case STC: case TXT: case MIX: case ENT: j=endtok((i=tok(j))); if(i==j) goto PROTER; patno=0; do patno=patno*10+quebuf[i++]-'0'; while(i!=j); if(patno==0) goto PROTER; /* 0 is ERROR, not allowed */ switch(kwd) { case STO: case ATT: case STC: case ENT: j=endtok((i=tok(j))); if(i==j||(kwd==ATT&&quebuf[j]=='\0')) goto PROTER; name=quebuf+i; quebuf[j]='\0'; switch(kwd) { case STO: ok=rnv_start_tag_open(&patno,&prevno,name); break; case ATT: ok=rnv_attribute(&patno,&prevno,name,quebuf+j+1); break; case STC: ok=rnv_start_tag_close(&patno,&prevno,name); break; case ENT: ok=rnv_end_tag(&patno,&prevno,name); break; } break; case TXT: case MIX: if(quebuf[j]) ++j; i=j; while(quebuf[j]) ++j; ok=rnv_text(&patno,&prevno,quebuf+i,j-i,kwd==MIX); break; } break; case NKWD: PROTER: (*er_printf)("protocol error\n"); lasterr=0; patno=0; ok=0; break; default: assert(0); } resp(ok,patno,prevno); i=0; while(n!=n_q) quebuf[i++]=quebuf[n++]; n_q=i; return 1; }