#define JERQ /* * mc - columnate * * mc[-][-LINEWIDTH][-t][file...] * -suppresses break on colon * -LINEWIDTH sets width of line in which to columnate(default 80) * -t suppresses expanding multiple blanks into tabs * */ #include <stdio.h> #ifdef JERQ #include <sgtty.h> #include "/usr/jerq/include/jioctl.h" #endif #define WIDTH 80 #define NWALLOC 1024 #define NALLOC 4096 int linewidth=WIDTH; int colonflag=1; int tabflag=1; char *cbuf, *cbufp; char **word; FILE *file; char *malloc(); char *realloc(); int maxwidth=0; int nalloc=NALLOC; int nwalloc=NWALLOC; int nchars=0; int nwords=0; main(argc, argv) char *argv[]; { FILE *fopen(); register i; char buf[BUFSIZ]; #ifdef JERQ struct winsize wbuf; if(ioctl(1, JWINSIZE, &wbuf)==0){ linewidth=wbuf.bytesx; if(linewidth<0) linewidth=WIDTH; } #endif if(argc>1){ while(*argv[1]=='-'){ --argc; argv++; switch(argv[0][1]){ case '\0': colonflag=0; break; case 't': tabflag=0; break; default: linewidth=atoi(&argv[0][1]); if(linewidth<=1) linewidth=WIDTH; break; } } } setbuf(stdout, buf); cbuf=cbufp=malloc(NALLOC); word=(char **)malloc(NWALLOC *(sizeof *word)); if(word==0 || cbuf==0) error("out of memory"); if(argc==1){ file=stdin; readbuf(); }else{ colonflag=0; for(i=1; i<argc; i++){ file=freopen(*++argv, "r", stdin); if(file==NULL) fprintf(stderr, "mc: can't open %s\n", *argv); else readbuf(); } } columnate(); exit(0); } error(s) char *s; { fprintf(stderr, "mc: %s\n", s); exit(1); } readbuf() { register c, lastwascolon=0; do{ if(nchars++>=nalloc){ if((cbuf=realloc(cbuf, nalloc+=NALLOC))==0) error("out of memory"); cbufp=cbuf+nchars-1; } *cbufp++=c=getc(file); if(colonflag && c==':') lastwascolon++; else if(lastwascolon){ if(c=='\n'){ register n=1; --nchars; /* skip newline */ while(nchars>0 && cbuf[--nchars]!='\n') n++; if(cbuf[nchars]=='\n') nchars++; columnate(); fwrite(cbuf+nchars, 1, n, stdout); nchars=0; cbufp=cbuf; } lastwascolon=0; } }while(c!=EOF); } scanwords(){ register char *p, *q; register i; nwords=0; maxwidth=0; for(p=q=cbuf, i=0; i<nchars; i++){ if(*p++=='\n'){ if(nwords>=nwalloc){ if((word=(char **)realloc((char *)word, (nwalloc+=NWALLOC)*sizeof(*word)))==0) error("out of memory"); } word[nwords++]=q; p[-1]=0; if(p-q>maxwidth) maxwidth=p-q; q=p; } } } int words_per_line; int nlines; int col; int tabcol; int endcol; int maxcol; columnate(){ register char *p; register i, j; scanwords(); if(nwords==0) return; words_per_line=linewidth/maxwidth; if(words_per_line<=0) words_per_line=1; nlines=(nwords+words_per_line-1)/words_per_line; for(i=0; i<nlines; i++){ col=0; endcol=0; for(j=0; i+j<nwords; ){ endcol+=maxwidth; p=word[i+j]; while(*p){ putchar(*p++); col++; } if(i+(j+=nlines)<nwords){ tabcol=(col|07)+1; if(tabflag) while(tabcol<=endcol){ putchar('\t'); col=tabcol; tabcol+=8; } while(col<endcol){ putchar(' '); col++; } } } putchar('\n'); } }