Blame


1 25b866dd 2003-12-04 devnull /*
2 25b866dd 2003-12-04 devnull * mc - columnate
3 25b866dd 2003-12-04 devnull *
4 25b866dd 2003-12-04 devnull * mc[-][-LINEWIDTH][-t][file...]
5 25b866dd 2003-12-04 devnull * - causes break on colon
6 25b866dd 2003-12-04 devnull * -LINEWIDTH sets width of line in which to columnate(default 80)
7 25b866dd 2003-12-04 devnull * -t suppresses expanding multiple blanks into tabs
8 25b866dd 2003-12-04 devnull *
9 25b866dd 2003-12-04 devnull */
10 25b866dd 2003-12-04 devnull #include <u.h>
11 6b2d0fd9 2004-03-26 devnull #include <sys/ioctl.h>
12 6b2d0fd9 2004-03-26 devnull #include <sys/termios.h>
13 25b866dd 2003-12-04 devnull #include <libc.h>
14 25b866dd 2003-12-04 devnull #include <draw.h>
15 25b866dd 2003-12-04 devnull #include <bio.h>
16 25b866dd 2003-12-04 devnull
17 25b866dd 2003-12-04 devnull #define WIDTH 80
18 25b866dd 2003-12-04 devnull #define TAB 4
19 25b866dd 2003-12-04 devnull #define WORD_ALLOC_QUANTA 1024
20 25b866dd 2003-12-04 devnull #define ALLOC_QUANTA 4096
21 25b866dd 2003-12-04 devnull
22 25b866dd 2003-12-04 devnull int linewidth=WIDTH;
23 25b866dd 2003-12-04 devnull int colonflag=0;
24 25b866dd 2003-12-04 devnull int tabflag=0; /* -t flag turned off forever */
25 25b866dd 2003-12-04 devnull Rune *cbuf, *cbufp;
26 25b866dd 2003-12-04 devnull Rune **word;
27 25b866dd 2003-12-04 devnull int maxwidth=0;
28 25b866dd 2003-12-04 devnull int nalloc=ALLOC_QUANTA;
29 25b866dd 2003-12-04 devnull int nwalloc=WORD_ALLOC_QUANTA;
30 25b866dd 2003-12-04 devnull int nchars=0;
31 25b866dd 2003-12-04 devnull int nwords=0;
32 25b866dd 2003-12-04 devnull Biobuf bin;
33 25b866dd 2003-12-04 devnull Biobuf bout;
34 25b866dd 2003-12-04 devnull
35 25b866dd 2003-12-04 devnull void getwidth(void), readbuf(int), error(char *);
36 25b866dd 2003-12-04 devnull void scanwords(void), columnate(void), morechars(void);
37 25b866dd 2003-12-04 devnull
38 25b866dd 2003-12-04 devnull void
39 25b866dd 2003-12-04 devnull main(int argc, char *argv[])
40 25b866dd 2003-12-04 devnull {
41 25b866dd 2003-12-04 devnull int i;
42 25b866dd 2003-12-04 devnull int lineset;
43 25b866dd 2003-12-04 devnull int ifd;
44 25b866dd 2003-12-04 devnull
45 25b866dd 2003-12-04 devnull lineset = 0;
46 25b866dd 2003-12-04 devnull Binit(&bout, 1, OWRITE);
47 25b866dd 2003-12-04 devnull while(argc > 1 && argv[1][0] == '-'){
48 25b866dd 2003-12-04 devnull --argc; argv++;
49 25b866dd 2003-12-04 devnull switch(argv[0][1]){
50 25b866dd 2003-12-04 devnull case '\0':
51 25b866dd 2003-12-04 devnull colonflag = 1;
52 25b866dd 2003-12-04 devnull break;
53 25b866dd 2003-12-04 devnull case 't':
54 25b866dd 2003-12-04 devnull tabflag = 0;
55 25b866dd 2003-12-04 devnull break;
56 25b866dd 2003-12-04 devnull default:
57 25b866dd 2003-12-04 devnull linewidth = atoi(&argv[0][1]);
58 25b866dd 2003-12-04 devnull if(linewidth <= 1)
59 25b866dd 2003-12-04 devnull linewidth = WIDTH;
60 25b866dd 2003-12-04 devnull lineset = 1;
61 25b866dd 2003-12-04 devnull break;
62 25b866dd 2003-12-04 devnull }
63 25b866dd 2003-12-04 devnull }
64 25b866dd 2003-12-04 devnull if(lineset == 0)
65 25b866dd 2003-12-04 devnull getwidth();
66 25b866dd 2003-12-04 devnull cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));
67 25b866dd 2003-12-04 devnull word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));
68 25b866dd 2003-12-04 devnull if(word == 0 || cbuf == 0)
69 25b866dd 2003-12-04 devnull error("out of memory");
70 25b866dd 2003-12-04 devnull if(argc == 1)
71 25b866dd 2003-12-04 devnull readbuf(0);
72 25b866dd 2003-12-04 devnull else{
73 25b866dd 2003-12-04 devnull for(i = 1; i < argc; i++){
74 25b866dd 2003-12-04 devnull if((ifd = open(*++argv, OREAD)) == -1)
75 25b866dd 2003-12-04 devnull fprint(2, "mc: can't open %s (%r)\n", *argv);
76 25b866dd 2003-12-04 devnull else{
77 25b866dd 2003-12-04 devnull readbuf(ifd);
78 25b866dd 2003-12-04 devnull Bflush(&bin);
79 25b866dd 2003-12-04 devnull close(ifd);
80 25b866dd 2003-12-04 devnull }
81 25b866dd 2003-12-04 devnull }
82 25b866dd 2003-12-04 devnull }
83 25b866dd 2003-12-04 devnull columnate();
84 25b866dd 2003-12-04 devnull exits(0);
85 25b866dd 2003-12-04 devnull }
86 25b866dd 2003-12-04 devnull void
87 25b866dd 2003-12-04 devnull error(char *s)
88 25b866dd 2003-12-04 devnull {
89 25b866dd 2003-12-04 devnull fprint(2, "mc: %s\n", s);
90 25b866dd 2003-12-04 devnull exits(s);
91 25b866dd 2003-12-04 devnull }
92 25b866dd 2003-12-04 devnull void
93 25b866dd 2003-12-04 devnull readbuf(int fd)
94 25b866dd 2003-12-04 devnull {
95 25b866dd 2003-12-04 devnull int lastwascolon = 0;
96 25b866dd 2003-12-04 devnull long c;
97 25b866dd 2003-12-04 devnull int linesiz = 0;
98 25b866dd 2003-12-04 devnull
99 25b866dd 2003-12-04 devnull Binit(&bin, fd, OREAD);
100 25b866dd 2003-12-04 devnull do{
101 25b866dd 2003-12-04 devnull if(nchars++ >= nalloc)
102 25b866dd 2003-12-04 devnull morechars();
103 25b866dd 2003-12-04 devnull *cbufp++ = c = Bgetrune(&bin);
104 25b866dd 2003-12-04 devnull linesiz++;
105 25b866dd 2003-12-04 devnull if(c == '\t') {
106 25b866dd 2003-12-04 devnull cbufp[-1] = L' ';
107 25b866dd 2003-12-04 devnull while(linesiz%TAB != 0) {
108 25b866dd 2003-12-04 devnull if(nchars++ >= nalloc)
109 25b866dd 2003-12-04 devnull morechars();
110 25b866dd 2003-12-04 devnull *cbufp++ = L' ';
111 25b866dd 2003-12-04 devnull linesiz++;
112 25b866dd 2003-12-04 devnull }
113 25b866dd 2003-12-04 devnull }
114 25b866dd 2003-12-04 devnull if(colonflag && c == ':')
115 25b866dd 2003-12-04 devnull lastwascolon++;
116 25b866dd 2003-12-04 devnull else if(lastwascolon){
117 25b866dd 2003-12-04 devnull if(c == '\n'){
118 25b866dd 2003-12-04 devnull --nchars; /* skip newline */
119 25b866dd 2003-12-04 devnull *cbufp = L'\0';
120 25b866dd 2003-12-04 devnull while(nchars > 0 && cbuf[--nchars] != '\n')
121 25b866dd 2003-12-04 devnull ;
122 25b866dd 2003-12-04 devnull if(nchars)
123 25b866dd 2003-12-04 devnull nchars++;
124 25b866dd 2003-12-04 devnull columnate();
125 25b866dd 2003-12-04 devnull if (nchars)
126 25b866dd 2003-12-04 devnull Bputc(&bout, '\n');
127 25b866dd 2003-12-04 devnull Bprint(&bout, "%S", cbuf+nchars);
128 25b866dd 2003-12-04 devnull nchars = 0;
129 25b866dd 2003-12-04 devnull cbufp = cbuf;
130 25b866dd 2003-12-04 devnull }
131 25b866dd 2003-12-04 devnull lastwascolon = 0;
132 25b866dd 2003-12-04 devnull }
133 25b866dd 2003-12-04 devnull if(c == '\n')
134 25b866dd 2003-12-04 devnull linesiz = 0;
135 25b866dd 2003-12-04 devnull }while(c >= 0);
136 25b866dd 2003-12-04 devnull }
137 25b866dd 2003-12-04 devnull void
138 25b866dd 2003-12-04 devnull scanwords(void)
139 25b866dd 2003-12-04 devnull {
140 25b866dd 2003-12-04 devnull Rune *p, *q;
141 25b866dd 2003-12-04 devnull int i;
142 25b866dd 2003-12-04 devnull
143 25b866dd 2003-12-04 devnull nwords=0;
144 25b866dd 2003-12-04 devnull maxwidth=0;
145 25b866dd 2003-12-04 devnull for(p = q = cbuf, i = 0; i < nchars; i++){
146 25b866dd 2003-12-04 devnull if(*p++ == L'\n'){
147 25b866dd 2003-12-04 devnull if(nwords >= nwalloc){
148 25b866dd 2003-12-04 devnull nwalloc += WORD_ALLOC_QUANTA;
149 25b866dd 2003-12-04 devnull if((word = realloc(word, nwalloc*sizeof(*word)))==0)
150 25b866dd 2003-12-04 devnull error("out of memory");
151 25b866dd 2003-12-04 devnull }
152 25b866dd 2003-12-04 devnull word[nwords++] = q;
153 25b866dd 2003-12-04 devnull p[-1] = L'\0';
154 25b866dd 2003-12-04 devnull if(p-q > maxwidth)
155 25b866dd 2003-12-04 devnull maxwidth = p-q;
156 25b866dd 2003-12-04 devnull q = p;
157 25b866dd 2003-12-04 devnull }
158 25b866dd 2003-12-04 devnull }
159 25b866dd 2003-12-04 devnull }
160 25b866dd 2003-12-04 devnull
161 25b866dd 2003-12-04 devnull void
162 25b866dd 2003-12-04 devnull columnate(void)
163 25b866dd 2003-12-04 devnull {
164 25b866dd 2003-12-04 devnull int i, j;
165 25b866dd 2003-12-04 devnull int words_per_line;
166 25b866dd 2003-12-04 devnull int nlines;
167 25b866dd 2003-12-04 devnull int col;
168 25b866dd 2003-12-04 devnull int endcol;
169 25b866dd 2003-12-04 devnull
170 25b866dd 2003-12-04 devnull
171 25b866dd 2003-12-04 devnull scanwords();
172 25b866dd 2003-12-04 devnull if(nwords==0)
173 25b866dd 2003-12-04 devnull return;
174 25b866dd 2003-12-04 devnull words_per_line = linewidth/maxwidth;
175 25b866dd 2003-12-04 devnull if(words_per_line <= 0)
176 25b866dd 2003-12-04 devnull words_per_line = 1;
177 25b866dd 2003-12-04 devnull nlines=(nwords+words_per_line-1)/words_per_line;
178 25b866dd 2003-12-04 devnull for(i = 0; i < nlines; i++){
179 25b866dd 2003-12-04 devnull col = endcol = 0;
180 25b866dd 2003-12-04 devnull for(j = i; j < nwords; j += nlines){
181 25b866dd 2003-12-04 devnull endcol += maxwidth;
182 25b866dd 2003-12-04 devnull Bprint(&bout, "%S", word[j]);
183 25b866dd 2003-12-04 devnull col += word[j+1]-word[j]-1;
184 25b866dd 2003-12-04 devnull if(j+nlines < nwords){
185 25b866dd 2003-12-04 devnull if(tabflag) {
186 25b866dd 2003-12-04 devnull int tabcol = (col|(TAB-1))+1;
187 25b866dd 2003-12-04 devnull while(tabcol <= endcol){
188 25b866dd 2003-12-04 devnull Bputc(&bout, '\t');
189 25b866dd 2003-12-04 devnull col = tabcol;
190 25b866dd 2003-12-04 devnull tabcol += TAB;
191 25b866dd 2003-12-04 devnull }
192 25b866dd 2003-12-04 devnull }
193 25b866dd 2003-12-04 devnull while(col < endcol){
194 25b866dd 2003-12-04 devnull Bputc(&bout, ' ');
195 25b866dd 2003-12-04 devnull col++;
196 25b866dd 2003-12-04 devnull }
197 25b866dd 2003-12-04 devnull }
198 25b866dd 2003-12-04 devnull }
199 25b866dd 2003-12-04 devnull Bputc(&bout, '\n');
200 25b866dd 2003-12-04 devnull }
201 25b866dd 2003-12-04 devnull }
202 25b866dd 2003-12-04 devnull
203 25b866dd 2003-12-04 devnull void
204 25b866dd 2003-12-04 devnull morechars(void)
205 25b866dd 2003-12-04 devnull {
206 25b866dd 2003-12-04 devnull nalloc += ALLOC_QUANTA;
207 25b866dd 2003-12-04 devnull if((cbuf = realloc(cbuf, nalloc*sizeof(*cbuf))) == 0)
208 25b866dd 2003-12-04 devnull error("out of memory");
209 25b866dd 2003-12-04 devnull cbufp = cbuf+nchars-1;
210 25b866dd 2003-12-04 devnull }
211 25b866dd 2003-12-04 devnull
212 25b866dd 2003-12-04 devnull /*
213 25b866dd 2003-12-04 devnull * These routines discover the width of the display.
214 25b866dd 2003-12-04 devnull * It takes some work. If we do the easy calls to the
215 25b866dd 2003-12-04 devnull * draw library, the screen flashes due to repainting
216 25b866dd 2003-12-04 devnull * when mc exits.
217 25b866dd 2003-12-04 devnull */
218 25b866dd 2003-12-04 devnull
219 25b866dd 2003-12-04 devnull int
220 25b866dd 2003-12-04 devnull windowrect(struct winsize *ws)
221 25b866dd 2003-12-04 devnull {
222 25b866dd 2003-12-04 devnull int tty;
223 25b866dd 2003-12-04 devnull
224 25b866dd 2003-12-04 devnull if((tty = open("/dev/tty", OWRITE)) < 0)
225 25b866dd 2003-12-04 devnull tty = 1;
226 25b866dd 2003-12-04 devnull
227 25b866dd 2003-12-04 devnull if(ioctl(tty, TIOCGWINSZ, ws) < 0){
228 25b866dd 2003-12-04 devnull if(tty != 1)
229 25b866dd 2003-12-04 devnull close(tty);
230 25b866dd 2003-12-04 devnull return -1;
231 25b866dd 2003-12-04 devnull }
232 25b866dd 2003-12-04 devnull if(tty != 1)
233 25b866dd 2003-12-04 devnull close(tty);
234 25b866dd 2003-12-04 devnull return 0;
235 25b866dd 2003-12-04 devnull }
236 25b866dd 2003-12-04 devnull
237 25b866dd 2003-12-04 devnull void
238 25b866dd 2003-12-04 devnull getwidth(void)
239 25b866dd 2003-12-04 devnull {
240 25b866dd 2003-12-04 devnull struct winsize ws;
241 25b866dd 2003-12-04 devnull
242 25b866dd 2003-12-04 devnull if(windowrect(&ws) < 0)
243 25b866dd 2003-12-04 devnull return;
244 25b866dd 2003-12-04 devnull linewidth = ws.ws_col;
245 25b866dd 2003-12-04 devnull }