static void cutfields(Cut_t* cut, Sfio_t* fdin, Sfio_t* fdout) { register unsigned char *sp = cut->space; register unsigned char *cp; register unsigned char *wp; register int c, nfields; register const int *lp = cut->list; register unsigned char *copy; register int nodelim, empty, inword=0; register unsigned char *ep; unsigned char *bp, *first; int lastchar; wchar_t w; Sfio_t *fdtmp = 0; long offset = 0; unsigned char mb[8]; /* process each buffer */ while ((bp = (unsigned char*)sfreserve(fdin, SF_UNBOUND, -1)) && (c = sfvalue(fdin)) > 0) { cp = bp; ep = cp + --c; if((lastchar = cp[c]) != cut->eob) *ep = cut->eob; /* process each line in the buffer */ while (cp <= ep) { first = cp; if (!inword) { nodelim = empty = 1; copy = cp; if (nfields = *(lp = cut->list)) copy = 0; else nfields = *++lp; } else if (copy) copy = cp; inword = 0; do { /* skip over non-delimiter characters */ if (cut->mb) for (;;) { switch (c = sp[*(unsigned char*)cp++]) { case 0: continue; case SP_WIDE: wp = --cp; while ((c = mb2wc(w, cp, ep - cp)) <= 0) { /* mb char possibly spanning buffer boundary -- fun stuff */ if ((ep - cp) < mbmax()) { int i; int j; int k; if (lastchar != cut->eob) { *ep = lastchar; if ((c = mb2wc(w, cp, ep - cp)) > 0) break; } if (copy) { empty = 0; if ((c = cp - copy) > 0 && sfwrite(fdout, (char*)copy, c) < 0) goto failed; } for (i = 0; i <= (ep - cp); i++) mb[i] = cp[i]; if (!(bp = (unsigned char*)sfreserve(fdin, SF_UNBOUND, -1)) || (c = sfvalue(fdin)) <= 0) goto failed; cp = bp; ep = cp + --c; if ((lastchar = cp[c]) != cut->eob) *ep = cut->eob; j = i; k = 0; while (j < mbmax()) mb[j++] = cp[k++]; if ((c = mb2wc(w, (char*)mb, j)) <= 0) { c = i; w = 0; } first = bp = cp += c - i; if (copy) { copy = bp; if (w == cut->ldelim.chr) lastchar = cut->ldelim.chr; else if (w != cut->wdelim.chr) { empty = 0; if (sfwrite(fdout, (char*)mb, c) < 0) goto failed; } } c = 0; } else { w = *cp; c = 1; } break; } cp += c; c = w; if (c == cut->wdelim.chr) { c = SP_WORD; break; } if (c == cut->ldelim.chr) { c = SP_LINE; break; } continue; default: wp = cp - 1; break; } break; } else { while (!(c = sp[*cp++])); wp = cp - 1; } /* check for end-of-line */ if (c == SP_LINE) { if (cp <= ep) break; if (lastchar == cut->ldelim.chr) break; /* restore cut->last character */ if (lastchar != cut->eob) *ep = lastchar; inword++; if (!sp[lastchar]) break; } nodelim = 0; if (--nfields > 0) continue; nfields = *++lp; if (copy) { empty = 0; if ((c = wp - copy) > 0 && sfwrite(fdout, (char*)copy, c) < 0) goto failed; copy = 0; } else /* set to delimiter unless the first field */ copy = empty ? cp : wp; } while (!inword); if (!inword) { if (!copy) { if (nodelim) { if (!cut->sflag) { if (offset) { sfseek(fdtmp,(Sfoff_t)0,SEEK_SET); sfmove(fdtmp,fdout,offset,-1); } copy = first; } } else sfputc(fdout,'\n'); } if (offset) sfseek(fdtmp,offset=0,SEEK_SET); } if (copy && (c=cp-copy)>0 && (!nodelim || !cut->sflag) && sfwrite(fdout,(char*)copy,c)< 0) goto failed; } /* see whether to save in tmp file */ if(inword && nodelim && !cut->sflag && (c=cp-first)>0) { /* copy line to tmpfile in case no fields */ if(!fdtmp) fdtmp = sftmp(BLOCK); sfwrite(fdtmp,(char*)first,c); offset +=c; } } failed: if(fdtmp) sfclose(fdtmp); }
/* * put <string> of length <nbyte> onto lookahead stack * if <type> is non-zero, the negation of the character is put * onto the stack so that it can be checked for KEYTRAP * putstack() returns 1 except when in the middle of a multi-byte char */ static int putstack(Edit_t *ep,char string[], register int nbyte, int type) { register int c; #if SHOPT_MULTIBYTE char *endp, *p=string; int size, offset = ep->e_lookahead + nbyte; *(endp = &p[nbyte]) = 0; endp = &p[nbyte]; do { c = (int)((*p) & STRIP); if(c< 0x80 && c!='<') { if (type) c = -c; # ifndef CBREAK if(c == '\0') { /*** user break key ***/ ep->e_lookahead = 0; # if KSHELL sh_fault(SIGINT); siglongjmp(ep->e_env, UINTR); # endif /* KSHELL */ } # endif /* CBREAK */ } else { again: if((c=mbchar(p)) >=0) { p--; /* incremented below */ if(type) c = -c; } #ifdef EILSEQ else if(errno == EILSEQ) errno = 0; #endif else if((endp-p) < mbmax()) { if ((c=ed_read(ep,ep->e_fd,endp, 1,0)) == 1) { *++endp = 0; goto again; } return(c); } else { ed_ringbell(); c = -(int)((*p) & STRIP); offset += mbmax()-1; } } ep->e_lbuf[--offset] = c; p++; } while (p < endp); /* shift lookahead buffer if necessary */ if(offset -= ep->e_lookahead) { for(size=offset;size < nbyte;size++) ep->e_lbuf[ep->e_lookahead+size-offset] = ep->e_lbuf[ep->e_lookahead+size]; } ep->e_lookahead += nbyte-offset; #else while (nbyte > 0) { c = string[--nbyte] & STRIP; ep->e_lbuf[ep->e_lookahead++] = (type?-c:c); # ifndef CBREAK if( c == '\0' ) { /*** user break key ***/ ep->e_lookahead = 0; # if KSHELL sh_fault(SIGINT); siglongjmp(ep->e_env, UINTR); # endif /* KSHELL */ } # endif /* CBREAK */ } #endif /* SHOPT_MULTIBYTE */ return(1); }