|
|
1.1 root 1: #define JERQ
2: /*
3: * mc - columnate
4: *
5: * mc[-][-LINEWIDTH][-t][file...]
6: * - causes break on colon
7: * -LINEWIDTH sets width of line in which to columnate(default 80)
8: * -t suppresses expanding multiple blanks into tabs
9: *
10: */
11: #include <stdio.h>
12: #ifdef JERQ
13: #include <sgtty.h>
14: #include "/usr/jerq/include/jioctl.h"
15: #endif
16: #define WIDTH 80
17: #define NWALLOC 1024
18: #define NALLOC 4096
19: int linewidth=WIDTH;
20: int colonflag=0;
21: int tabflag=1;
22: char *cbuf, *cbufp;
23: char **word;
24: FILE *file;
25: char *malloc();
26: char *realloc();
27: int maxwidth=0;
28: int nalloc=NALLOC;
29: int nwalloc=NWALLOC;
30: int nchars=0;
31: int nwords=0;
32:
33: main(argc, argv)
34: char *argv[];
35: {
36: FILE *fopen();
37: register i;
38: char buf[BUFSIZ];
39: #ifdef JERQ
40: struct winsize wbuf;
41:
42: if(ioctl(1, JWINSIZE, &wbuf)==0){
43: linewidth=wbuf.bytesx;
44: if(linewidth<0)
45: linewidth=WIDTH;
46: }
47: #endif
48: while(argc>1 && argv[1][0]=='-'){
49: --argc; argv++;
50: switch(argv[0][1]){
51: case '\0':
52: colonflag=1;
53: break;
54: case 't':
55: tabflag=0;
56: break;
57: default:
58: linewidth=atoi(&argv[0][1]);
59: if(linewidth<=1)
60: linewidth=WIDTH;
61: break;
62: }
63: }
64: setbuf(stdout, buf);
65: cbuf=cbufp=malloc(NALLOC);
66: word=(char **)malloc(NWALLOC *(sizeof *word));
67: if(word==0 || cbuf==0)
68: error("out of memory");
69: if(argc==1){
70: file=stdin;
71: readbuf();
72: }else{
73: for(i=1; i<argc; i++){
74: file=freopen(*++argv, "r", stdin);
75: if(file==NULL)
76: fprintf(stderr, "mc: can't open %s\n", *argv);
77: else
78: readbuf();
79: }
80: }
81: columnate();
82: exit(0);
83: }
84: error(s)
85: char *s;
86: {
87: fprintf(stderr, "mc: %s\n", s);
88: exit(1);
89: }
90: readbuf()
91: {
92: register c, lastwascolon=0;
93: int linesiz = 0;
94: do{
95: if(nchars++>=nalloc)
96: morechars();
97: *cbufp++=c=getc(file);
98: linesiz++;
99: if(c=='\t') {
100: cbufp[-1] = ' ';
101: while(linesiz%8 != 0) {
102: if(nchars++>=nalloc)
103: morechars();
104: *cbufp++ = ' ';
105: linesiz++;
106: }
107: }
108: if(colonflag && c==':')
109: lastwascolon++;
110: else if(lastwascolon){
111: if(c=='\n'){
112: register n=1;
113: --nchars; /* skip newline */
114: while(nchars>0 && cbuf[--nchars]!='\n')
115: n++;
116: if(cbuf[nchars]=='\n')
117: nchars++;
118: columnate();
119: if (nchars)
120: putchar('\n');
121: fwrite(cbuf+nchars, 1, n, stdout);
122: nchars=0;
123: cbufp=cbuf;
124: }
125: lastwascolon=0;
126: }
127: if(c=='\n')
128: linesiz = 0;
129: }while(c!=EOF);
130: }
131: scanwords(){
132: register char *p, *q;
133: register i;
134: nwords=0;
135: maxwidth=0;
136: for(p=q=cbuf, i=0; i<nchars; i++){
137: if(*p++=='\n'){
138: if(nwords>=nwalloc){
139: if((word=(char **)realloc((char *)word, (nwalloc+=NWALLOC)*sizeof(*word)))==0)
140: error("out of memory");
141: }
142: word[nwords++]=q;
143: p[-1]=0;
144: if(p-q>maxwidth)
145: maxwidth=p-q;
146: q=p;
147: }
148: }
149: }
150: int words_per_line;
151: int nlines;
152: int col;
153: int tabcol;
154: int endcol;
155: int maxcol;
156: columnate(){
157: register char *p;
158: register i, j;
159: scanwords();
160: if(nwords==0)
161: return;
162: words_per_line=linewidth/maxwidth;
163: if(words_per_line<=0)
164: words_per_line=1;
165: nlines=(nwords+words_per_line-1)/words_per_line;
166: for(i=0; i<nlines; i++){
167: col=0;
168: endcol=0;
169: for(j=0; i+j<nwords; ){
170: endcol+=maxwidth;
171: p=word[i+j];
172: while(*p){
173: putchar(*p++);
174: col++;
175: }
176: if(i+(j+=nlines)<nwords){
177: tabcol=(col|07)+1;
178: if(tabflag)
179: while(tabcol<=endcol){
180: putchar('\t');
181: col=tabcol;
182: tabcol+=8;
183: }
184: while(col<endcol){
185: putchar(' ');
186: col++;
187: }
188: }
189: }
190: putchar('\n');
191: }
192: }
193:
194: morechars()
195: {
196: if((cbuf=realloc(cbuf, nalloc+=NALLOC))==0)
197: error("out of memory");
198: cbufp=cbuf+nchars-1;
199: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.