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>
13 #ifdef HAS_SYS_TERMIOS
14 #include <sys/termios.h>
25 #define WORD_ALLOC_QUANTA 1024
26 #define ALLOC_QUANTA 4096
28 int wordsize(Rune*, int);
35 int tabflag=0; /* -t flag turned off forever, except in acme */
39 int nalloc=ALLOC_QUANTA;
40 int nwalloc=WORD_ALLOC_QUANTA;
46 void getwidth(void), readbuf(int), error(char *);
47 void scanwords(void), columnate(void), morechars(void);
50 threadmain(int argc, char *argv[])
57 Binit(&bout, 1, OWRITE);
58 while(argc > 1 && argv[1][0] == '-'){
68 linewidth = atoi(&argv[0][1]);
77 cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));
78 word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));
79 if(word == 0 || cbuf == 0)
80 error("out of memory");
84 for(i = 1; i < argc; i++){
85 if((ifd = open(*++argv, OREAD)) == -1)
86 fprint(2, "mc: can't open %s (%r)\n", *argv);
101 fprint(2, "mc: %s\n", s);
107 int lastwascolon = 0;
111 Binit(&bin, fd, OREAD);
113 if(nchars++ >= nalloc)
115 *cbufp++ = c = Bgetrune(&bin);
119 while(linesiz%TAB != 0) {
120 if(nchars++ >= nalloc)
126 if(colonflag && c == ':')
128 else if(lastwascolon){
130 --nchars; /* skip newline */
132 while(nchars > 0 && cbuf[--nchars] != '\n')
139 Bprint(&bout, "%S", cbuf+nchars);
157 for(p = q = cbuf, i = 0; i < nchars; i++){
159 if(nwords >= nwalloc){
160 nwalloc += WORD_ALLOC_QUANTA;
161 if((word = realloc(word, nwalloc*sizeof(*word)))==0)
162 error("out of memory");
166 w = wordsize(q, p-q-1);
187 maxwidth = nexttab(maxwidth+mintab-1);
188 words_per_line = linewidth/maxwidth;
189 if(words_per_line <= 0)
191 nlines=(nwords+words_per_line-1)/words_per_line;
192 for(i = 0; i < nlines; i++){
194 for(j = i; j < nwords; j += nlines){
196 Bprint(&bout, "%S", word[j]);
197 col += wordsize(word[j], runestrlen(word[j]));
198 if(j+nlines < nwords){
217 wordsize(Rune *w, int nw)
222 return runestringnwidth(font, w, nw);
240 nalloc += ALLOC_QUANTA;
241 if((cbuf = realloc(cbuf, nalloc*sizeof(*cbuf))) == 0)
242 error("out of memory");
243 cbufp = cbuf+nchars-1;
247 * These routines discover the width of the display.
248 * It takes some work. If we do the easy calls to the
249 * draw library, the screen flashes due to repainting
253 windowrect(struct winsize *ws)
257 if((tty = open("/dev/tty", OWRITE)) < 0)
260 if(ioctl(tty, TIOCGWINSZ, ws) < 0){
274 char buf[500], *p, *q, *f[10], *fname;
275 int fd, n, nf, scale;
279 if((p = getenv("winid")) != nil){
280 fs = nsmount("acme", "");
283 snprint(buf, sizeof buf, "acme/%d/ctl", atoi(p));
284 if((fd = fsopenfd(fs, buf, OREAD)) < 0)
286 if((n=readn(fd, buf, sizeof buf-1)) <= 0)
289 if((nf=tokenize(buf, f, nelem(f))) < 7)
291 // hidpi font in stringwidth(3) will call scalesubfont,
292 // which aborts in bytesperline, due to unknow depth,
293 // without initdraw. We scale by ourselves.
294 scale = parsefontscale(f[6], &fname);
296 if(nf >= 8 && (tabwid = atoi(f[7])/scale) == 0)
298 if((font = openfont(nil, fname)) == nil)
300 mintab = stringwidth(font, "0");
303 linewidth = atoi(f[5]) / scale;
308 if((p = getenv("termprog")) != nil && strcmp(p, "9term") == 0)
309 if((p = getenv("font")) != nil)
310 font = openfont(nil, p);
312 if(windowrect(&ws) < 0)
314 if(ws.ws_xpixel == 0)
317 // 9term leaves "is this a hidpi display" in the low bit of the ypixel height.
320 // loadhifpi creates a font that crashes in stringwidth,
321 // for reasons i don't understand.
327 f1 = openfont(nil, q+1);
333 mintab = stringwidth(font, "0");
334 if((p = getenv("tabstop")) != nil)
335 tabwid = atoi(p)*mintab;
339 linewidth = ws.ws_xpixel;
341 linewidth = ws.ws_col;