|
|
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: if(argc>1){
49: while(argv[1] && *argv[1]=='-'){
50: --argc; argv++;
51: switch(argv[0][1]){
52: case '\0':
53: colonflag=1;
54: break;
55: case 't':
56: tabflag=0;
57: break;
58: default:
59: linewidth=atoi(&argv[0][1]);
60: if(linewidth<=1)
61: linewidth=WIDTH;
62: break;
63: }
64: }
65: }
66: setbuf(stdout, buf);
67: cbuf=cbufp=malloc(NALLOC);
68: word=(char **)malloc(NWALLOC *(sizeof *word));
69: if(word==0 || cbuf==0)
70: error("out of memory");
71: if(argc==1){
72: file=stdin;
73: readbuf();
74: }else{
75: for(i=1; i<argc; i++){
76: file=freopen(*++argv, "r", stdin);
77: if(file==NULL)
78: fprintf(stderr, "mc: can't open %s\n", *argv);
79: else
80: readbuf();
81: }
82: }
83: columnate();
84: exit(0);
85: }
86: error(s)
87: char *s;
88: {
89: fprintf(stderr, "mc: %s\n", s);
90: exit(1);
91: }
92: readbuf()
93: {
94: register c, lastwascolon=0;
95: do{
96: if(nchars++>=nalloc){
97: if((cbuf=realloc(cbuf, nalloc+=NALLOC))==0)
98: error("out of memory");
99: cbufp=cbuf+nchars-1;
100: }
101: *cbufp++=c=getc(file);
102: if(colonflag && c==':')
103: lastwascolon++;
104: else if(lastwascolon){
105: if(c=='\n'){
106: register n=1;
107: --nchars; /* skip newline */
108: while(nchars>0 && cbuf[--nchars]!='\n')
109: n++;
110: if(cbuf[nchars]=='\n')
111: nchars++;
112: columnate();
113: if (nchars)
114: putchar('\n');
115: fwrite(cbuf+nchars, 1, n, stdout);
116: nchars=0;
117: cbufp=cbuf;
118: }
119: lastwascolon=0;
120: }
121: }while(c!=EOF);
122: }
123: scanwords(){
124: register char *p, *q;
125: register i;
126: nwords=0;
127: maxwidth=0;
128: for(p=q=cbuf, i=0; i<nchars; i++){
129: if(*p++=='\n'){
130: if(nwords>=nwalloc){
131: if((word=(char **)realloc((char *)word, (nwalloc+=NWALLOC)*sizeof(*word)))==0)
132: error("out of memory");
133: }
134: word[nwords++]=q;
135: p[-1]=0;
136: if(p-q>maxwidth)
137: maxwidth=p-q;
138: q=p;
139: }
140: }
141: }
142: int words_per_line;
143: int nlines;
144: int col;
145: int tabcol;
146: int endcol;
147: int maxcol;
148: columnate(){
149: register char *p;
150: register i, j;
151: scanwords();
152: if(nwords==0)
153: return;
154: words_per_line=linewidth/maxwidth;
155: if(words_per_line<=0)
156: words_per_line=1;
157: nlines=(nwords+words_per_line-1)/words_per_line;
158: for(i=0; i<nlines; i++){
159: col=0;
160: endcol=0;
161: for(j=0; i+j<nwords; ){
162: endcol+=maxwidth;
163: p=word[i+j];
164: while(*p){
165: putchar(*p++);
166: col++;
167: }
168: if(i+(j+=nlines)<nwords){
169: tabcol=(col|07)+1;
170: if(tabflag)
171: while(tabcol<=endcol){
172: putchar('\t');
173: col=tabcol;
174: tabcol+=8;
175: }
176: while(col<endcol){
177: putchar(' ');
178: col++;
179: }
180: }
181: }
182: putchar('\n');
183: }
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.