1 #include "stralloc.h"
2 #include "alloc.h"
3 #include "slurpclose.h"
4 #include "strerr.h"
5 #include "substdio.h"
6 #include "readwrite.h"
7 #include "exit.h"
8 
9 #define FATAL "columnt: fatal: "
10 
11 char outbuf[4096];
12 substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof outbuf);
13 
nomem()14 void nomem() { strerr_die2x(111,FATAL,"out of memory"); }
die_read()15 void die_read() { strerr_die2sys(111,FATAL,"unable to read input: "); }
die_write()16 void die_write() { strerr_die2sys(111,FATAL,"unable to write output: "); }
17 
18 stralloc file = {0};
19 int *width;
20 int maxfield = 0;
21 
nothing()22 void nothing()
23 {
24   ;
25 }
26 
printline()27 void printline()
28 {
29   if (substdio_put(&ssout,"\n",1) == -1) die_write();
30 }
31 
maxfield_check(fieldnum,buf,len)32 void maxfield_check(fieldnum,buf,len) int fieldnum; char *buf; int len;
33 {
34   if (fieldnum > maxfield) maxfield = fieldnum;
35 }
36 
width_check(fieldnum,buf,len)37 void width_check(fieldnum,buf,len) int fieldnum; char *buf; int len;
38 {
39   if (len > width[fieldnum]) width[fieldnum] = len;
40 }
41 
width_init()42 void width_init()
43 {
44   int i;
45 
46   width = (int *) alloc((maxfield + 1) * sizeof(int));
47   if (!width) nomem();
48   for (i = 0;i <= maxfield;++i) width[i] = 0;
49 }
50 
printfield(fieldnum,buf,len)51 void printfield(fieldnum,buf,len) int fieldnum; char *buf; int len;
52 {
53   int i;
54 
55   if (fieldnum < maxfield)
56     for (i = len;i < width[fieldnum];++i)
57       if (substdio_put(&ssout," ",1) == -1) die_write();
58 
59   if (substdio_put(&ssout,buf,len) == -1) die_write();
60 
61   if (fieldnum < maxfield)
62     if (substdio_put(&ssout,"  ",2) == -1) die_write();
63 }
64 
65 void split(dofield,doline)
66 void (*dofield)();
67 void (*doline)();
68 {
69   int i;
70   int j;
71   int fieldpos;
72   int fieldnum;
73 
74   for (j = i = 0;j < file.len;++j)
75     if (file.s[j] == '\n') {
76       fieldnum = 0;
77       for (;;) {
78         while ((file.s[i] == ' ') || (file.s[i] == '\t')) ++i;
79         if (i == j) break;
80         fieldpos = i;
81         while ((file.s[i] != ' ') && (file.s[i] != '\t') && (file.s[i] != '\n')) ++i;
82         dofield(fieldnum++,file.s + fieldpos,i - fieldpos);
83       }
84       doline();
85       i = j + 1;
86     }
87 }
88 
main()89 void main()
90 {
91   if (slurpclose(0,&file,4096) == -1) die_read();
92   if (!file.len) _exit(0);
93   if (file.s[file.len - 1] != '\n')
94     if (!stralloc_append(&file,"\n")) nomem();
95 
96   split(maxfield_check,nothing);
97   width_init();
98   split(width_check,nothing);
99   split(printfield,printline);
100 
101   if (substdio_flush(&ssout) == -1) die_write();
102   _exit(0);
103 }
104