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
11 #include <sys/ioctl.h>
12 #include <sys/termios.h>
22 #define WORD_ALLOC_QUANTA 1024
23 #define ALLOC_QUANTA 4096
25 int wordsize(Rune*, int);
32 int tabflag=0; /* -t flag turned off forever, except in acme */
36 int nalloc=ALLOC_QUANTA;
37 int nwalloc=WORD_ALLOC_QUANTA;
43 void getwidth(void), readbuf(int), error(char *);
44 void scanwords(void), columnate(void), morechars(void);
47 threadmain(int argc, char *argv[])
54 Binit(&bout, 1, OWRITE);
55 while(argc > 1 && argv[1][0] == '-'){
65 linewidth = atoi(&argv[0][1]);
74 cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));
75 word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));
76 if(word == 0 || cbuf == 0)
77 error("out of memory");
81 for(i = 1; i < argc; i++){
82 if((ifd = open(*++argv, OREAD)) == -1)
83 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 = wordsize(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 += wordsize(word[j], runestrlen(word[j]));
195 if(j+nlines < nwords){
214 wordsize(Rune *w, int nw)
219 return runestringnwidth(font, w, nw);
237 nalloc += ALLOC_QUANTA;
238 if((cbuf = realloc(cbuf, nalloc*sizeof(*cbuf))) == 0)
239 error("out of memory");
240 cbufp = cbuf+nchars-1;
244 * These routines discover the width of the display.
245 * It takes some work. If we do the easy calls to the
246 * draw library, the screen flashes due to repainting
250 windowrect(struct winsize *ws)
254 if((tty = open("/dev/tty", OWRITE)) < 0)
257 if(ioctl(tty, TIOCGWINSZ, ws) < 0){
271 char buf[500], *p, *f[10];
275 if((p = getenv("winid")) != nil){
276 fs = nsmount("acme", "");
279 snprint(buf, sizeof buf, "acme/%d/ctl", atoi(p));
280 if((fd = fsopenfd(fs, buf, OREAD)) < 0)
282 if((n=readn(fd, buf, sizeof buf-1)) <= 0)
285 if((nf=tokenize(buf, f, nelem(f))) < 7)
288 if(nf >= 8 && (tabwid = atoi(f[7])) == 0)
290 if((font = openfont(nil, f[6])) == nil)
292 mintab = stringwidth(font, "0");
295 linewidth = atoi(f[5]);
300 if((p = getenv("TERM")) != nil && strcmp(p, "9term") == 0)
301 if((p = getenv("font")) != nil)
302 font = openfont(nil, p);
304 if(windowrect(&ws) < 0)
306 if(ws.ws_xpixel == 0)
309 mintab = stringwidth(font, "0");
310 if((p = getenv("tabstop")) != nil)
311 tabwid = atoi(p)*mintab;
315 linewidth = ws.ws_xpixel;
317 linewidth = ws.ws_col;