#include #include "alloc.h" #include "logmsg.h" #include "buffer.h" #include "stralloc.h" #include "exit.h" #include "readclose.h" #define WHO "columnt" #define BSIZE 4096 char outbuf[BSIZE]; buffer bo = BUFFER_INIT(write,1,outbuf,sizeof(outbuf)); void nomem() { logmsg(WHO,111,FATAL,"out of memory"); } void die_read() { logmsg(WHO,110,ERROR,"unable to read input: "); } void die_write() { logmsg(WHO,110,ERROR,"unable to write output: "); } stralloc file = {0}; int *width; int maxfield = 0; void nothing() { ; } void printline() { if (buffer_put(&bo,"\n",1) == -1) die_write(); } void maxfield_check(int fieldnum,char *buf,int len) { if (fieldnum > maxfield) maxfield = fieldnum; } void width_check(int fieldnum,char *buf,int len) { if (len > width[fieldnum]) width[fieldnum] = len; } void width_init() { int i; width = (int *) alloc((maxfield + 1) * sizeof(int)); if (!width) nomem(); for (i = 0; i <= maxfield; ++i) width[i] = 0; } void printfield(int fieldnum,char *buf,int len) { int i; if (fieldnum < maxfield) for (i = len; i < width[fieldnum]; ++i) if (buffer_put(&bo," ",1) == -1) die_write(); if (buffer_put(&bo,buf,len) == -1) die_write(); if (fieldnum < maxfield) if (buffer_put(&bo," ",2) == -1) die_write(); } void split(void (*dofield)(), void (*doline)()) { int i; int j; int fieldpos; int fieldnum; for (j = i = 0; j < file.len; ++j) if (file.s[j] == '\n') { fieldnum = 0; for (;;) { while ((file.s[i] == ' ') || (file.s[i] == '\t')) ++i; if (i == j) break; fieldpos = i; while ((file.s[i] != ' ') && (file.s[i] != '\t') && (file.s[i] != '\n')) ++i; dofield(fieldnum++,file.s + fieldpos,i - fieldpos); } doline(); i = j + 1; } } int main() { if (readclose_append(0,&file,BSIZE) == -1) die_read(); if (!file.len) _exit(0); if (file.s[file.len - 1] != '\n') if (!stralloc_append(&file,"\n")) nomem(); split(maxfield_check,nothing); width_init(); split(width_check,nothing); split(printfield,printline); if (buffer_flush(&bo) == -1) die_write(); _exit(0); }