diff options
author | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
---|---|---|
committer | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
commit | 89b7b67a13ebb7965cc7f13ad0595e2194a2d34c (patch) | |
tree | 25efd77a90ae87236e6730d8ea3846bbe0fd126f /src/columnt.c |
add sqmail-4.2.29asqmail-4.2
Diffstat (limited to 'src/columnt.c')
-rw-r--r-- | src/columnt.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/columnt.c b/src/columnt.c new file mode 100644 index 0000000..9e4cf0e --- /dev/null +++ b/src/columnt.c @@ -0,0 +1,104 @@ +#include <unistd.h> +#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); +} |