4 * mc[-][-LINEWIDTH][-t][file...]
5 * - causes break on colon
6 * -LINEWIDTH sets width of line in which to columnate(default 80)
7 * -t suppresses expanding multiple blanks into tabs
17 #define WORD_ALLOC_QUANTA 1024
18 #define ALLOC_QUANTA 4096
23 int tabflag=0; /* -t flag turned off forever */
27 int nalloc=ALLOC_QUANTA;
28 int nwalloc=WORD_ALLOC_QUANTA;
36 void getwidth(void), readbuf(int), error(char *);
37 void scanwords(void), columnate(void), morechars(void);
38 int wordwidth(Rune*, int);
42 main(int argc, char *argv[])
49 Binit(&bout, 1, OWRITE);
50 while(argc > 1 && argv[1][0] == '-'){
60 linewidth = atoi(&argv[0][1]);
75 cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));
76 word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));
77 if(word == 0 || cbuf == 0)
78 error("out of memory");
82 for(i = 1; i < argc; i++){
83 if((ifd = open(*++argv, OREAD)) == -1)
84 fprint(2, "mc: can't open %s (%r)\n", *argv);
98 fprint(2, "mc: %s\n", s);
104 int lastwascolon = 0;
108 Binit(&bin, fd, OREAD);
110 if(nchars++ >= nalloc)
112 *cbufp++ = c = Bgetrune(&bin);
116 while(linesiz%TAB != 0) {
117 if(nchars++ >= nalloc)
123 if(colonflag && c == ':')
125 else if(lastwascolon){
127 --nchars; /* skip newline */
129 while(nchars > 0 && cbuf[--nchars] != '\n')
136 Bprint(&bout, "%S", cbuf+nchars);
154 for(p = q = cbuf, i = 0; i < nchars; i++){
156 if(nwords >= nwalloc){
157 nwalloc += WORD_ALLOC_QUANTA;
158 if((word = realloc(word, nwalloc*sizeof(*word)))==0)
159 error("out of memory");
163 w = wordwidth(q, p-q-1);
184 maxwidth = nexttab(maxwidth+mintab-1);
185 words_per_line = linewidth/maxwidth;
186 if(words_per_line <= 0)
188 nlines=(nwords+words_per_line-1)/words_per_line;
189 for(i = 0; i < nlines; i++){
191 for(j = i; j < nwords; j += nlines){
193 Bprint(&bout, "%S", word[j]);
194 col += wordwidth(word[j], runestrlen(word[j]));
195 if(j+nlines < nwords){
214 wordwidth(Rune *w, int nw)
217 return runestringnwidth(font, w, nw);
235 nalloc += ALLOC_QUANTA;
236 if((cbuf = realloc(cbuf, nalloc*sizeof(*cbuf))) == 0)
237 error("out of memory");
238 cbufp = cbuf+nchars-1;
242 * These routines discover the width of the display.
243 * It takes some work. If we do the easy calls to the
244 * draw library, the screen flashes due to repainting
251 terror(Display*, char*)
260 char buf[128], *f[10], *p;
262 if(access("/dev/acme", OREAD) >= 0){
263 if((fd = open("/dev/acme/ctl", OREAD)) < 0)
265 n = read(fd, buf, sizeof buf-1);
270 n = tokenize(buf, f, nelem(f));
273 if((font = openfont(nil, f[6])) == nil)
276 tabwidth = atoi(f[7]);
278 tabwidth = 4*stringwidth(font, "0");
279 mintab = stringwidth(font, "0");
280 linewidth = atoi(f[5]);
285 if((p = getenv("font")) == nil)
287 if((font = openfont(nil, p)) == nil)
289 if((fd = open("/dev/window", OREAD)) < 0){
293 n = read(fd, buf, 5*12);
309 linewidth = atoi(buf+3*12) - atoi(buf+1*12) - (4+1+12+4+4);
310 mintab = stringwidth(font, "0");
311 if((p = getenv("tabstop")) != nil)
312 tabwidth = atoi(p)*stringwidth(font, "0");
314 tabwidth = 4*stringwidth(font, "0");