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