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; }
static void flush_text(void) { ok=rnv_text(¤t,&previous,text,n_txt,mixed)&&ok; text[n_txt=0]='\0'; }