main() { int c,p,nb,last; p = 0; nb = 0; while((c=getchar()) != EOF) { if(c == ' ') { last = c; ++nb; ++p; } else if (c != ' ' && c != '\n') { if(last == ' ') { tabstop(p,nb); nb = 0; } putchar(c); ++p; last = c; } else { putchar(c); p = 0; nb = 0; } } }
/*** Returns the characer-index corresponding to the screen column ***/ ULONG find_nbc(LINE *ln, ULONG nbrc) { register LONG rc, nbc; register UBYTE *str; for(str=ln->stream, rc=0, nbc=ln->size; nbc && rc<nbrc; str++, nbc--) rc += (*str=='\t' ? tabstop(rc) : 1); return ln->size-nbc; }
/*** Convert num chars to real column number: ***/ ULONG x2pos(LINE *ln, ULONG nb) { register ULONG nbrc=0; register UBYTE *str; for(str=ln->stream; nb; nb--, str++) nbrc += (*str=='\t' ? tabstop(nbrc) : 1); return nbrc; }
/*** Adjust column to an existing one: ***/ ULONG adjust_rc(LINE *ln, ULONG rc, ULONG *c, UBYTE atleast) { register ULONG nbrc, nbc; register UBYTE *str; for(str=ln->stream, nbrc=nbc=0; nbc<ln->size; str++, nbc++) { register ULONG tmp = (*str=='\t' ? tabstop(nbrc) : 1); /* If atleast is TRUE be sure that cursor will be at least at column rc: */ if(atleast) if(nbrc<rc) nbrc+=tmp; else break; else if(nbrc+tmp<=rc) nbrc+=tmp; else break; } *c=nbc; return nbrc; }
/*** Mark: block selection ***/ BYTE move_column_selection(Project p, LONG xn, LONG yn) { static WORD left, nbcol; static LONG left_pos; extern BYTE clear; LONG yline; /* Nb. of line marked */ LINE *ln; /* Running pointer */ BYTE ret; /* Autoscroll ? */ WORD y; /* VPos of item sel */ BYTE rdw = 0; /** Vertical autoscroll ? **/ ret = (yn<p->top_line ? 2 : (yn>=(LONG)(p->top_line+gui.nbline) ? 1 : 0)); if(p->nbrc<p->ccp.startsel && gui.topcurs <= p->ycurs && p->ycurs <= gui.botcurs) p->ccp.select=0,inv_curs(p,0),p->ccp.select=COLUMN_TYPE; clear=FALSE; /** Reduce refreshed area **/ left_pos=p->left_pos; left=gui.left; nbcol=gui.nbcol; gui.left += XSIZE * ( ( p->left_pos = MIN(MIN(p->ccp.xp,p->ccp.xc), xn)) - left_pos); yline = MAX(MAX(p->ccp.xp,p->ccp.xc), xn); gui.nbcol = yline - p->left_pos + tabstop(yline); if(p->left_pos+gui.nbcol > left_pos+nbcol) gui.nbcol = left_pos+nbcol-p->left_pos; if(yn<0) yn=0; if(yn>=p->max_lines) yn=p->max_lines-1,ret=0; yline=p->ccp.yc; ln=p->ccp.cline; /* top_line may changed */ y=(yline-p->top_line)*YSIZE+gui.topcurs; /** Update start & end selection pos **/ if( xn < p->ccp.xp ) p->ccp.endsel = p->ccp.xp, p->ccp.startsel = xn; else p->ccp.startsel = p->ccp.xp, p->ccp.endsel = xn; /** Same fight as before: afterward or backward scan **/ if( yn >= yline ) { /* Search is afterward */ for(; yline<yn; y+=YSIZE, yline++, ln=ln->next) { if(yline < p->ccp.yp) ln->flags=0; else ln->flags=FIRSTSEL | LASTSEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP,gui.left,y),write_text(p,ln); } /* If user has changed vertical position of selection an ** ** update of part of selected buffer will be required: */ if(xn != p->ccp.xc) { if(p->ccp.yp < p->ccp.yc) rdw=6; else if(p->ccp.yp > yn) rdw=1; } } else { /* Scan is backward */ for(; yline>yn; y-=YSIZE, yline--, ln=ln->prev) { if(yline > p->ccp.yp) ln->flags=0; else ln->flags=FIRSTSEL | LASTSEL; if(gui.topcurs <= y && y <= gui.botcurs) Move(RP,gui.left,y),write_text(p,ln); } /* If user has changed vertical position of selection an ** ** update of part of selected buffer will be required: */ if(xn != p->ccp.xc) { if(p->ccp.yp > p->ccp.yc) rdw=5; else if(p->ccp.yp < yn) rdw=2; } } /** Current point now become the previous **/ ln->flags = FIRSTSEL | LASTSEL; /* Last line can overlap edit area */ if(gui.topcurs<=y && y<=gui.botcurs) Move(RP,gui.left,y),write_text(p,ln); /** Update unmodified lines **/ if(rdw) { register LINE *ptr; register WORD yc; /* Limits number of lines to redraw */ if(rdw&4) ptr=p->ccp.cline, yline=p->ccp.yc, yc=(yline-p->top_line)*YSIZE+gui.topcurs; else ptr=ln, yc=y; /* Reduces number of columns to redraw */ if(p->ccp.xc < xn) p->left_pos=p->ccp.xc, gui.nbcol=xn-p->ccp.xc+1+tabstop(xn); else p->left_pos=xn, gui.nbcol=p->ccp.xc-xn+1+tabstop(p->ccp.xc); gui.left = left + XSIZE*(p->left_pos-left_pos); /* Be sure lines won't erase right border of window */ if(p->left_pos+gui.nbcol > left_pos+nbcol) gui.nbcol = left_pos+nbcol-p->left_pos; if(rdw&1) { for(; yc<=gui.botcurs && yline<=p->ccp.yp; yline++, yc+=YSIZE, ptr=ptr->next) if(yc>=gui.topcurs) Move(RP,gui.left,yc),write_text(p,ptr); } else { for(; yc>=gui.topcurs && yline>=p->ccp.yp; yline--, yc-=YSIZE, ptr=ptr->prev) if(yc<=gui.botcurs) Move(RP,gui.left,yc),write_text(p,ptr); } } p->left_pos=left_pos; gui.left=left; gui.nbcol=nbcol; p->ccp.xc=xn; p->ccp.cline=ln; p->ccp.yc=yn; clear=TRUE; return ret; }