/*
 * Copyright (c) 2003-2011
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 */

/*
 * Simple table transposition utility.
 * Usage: tabtr [-c #]
 * Input is stdin
 */

#ifndef lint
static const char copyright[] =
"Copyright (c) 2003-2011\n\
Distributed Systems Software.  All rights reserved.";
static const char revid[] =
  "$Id: tabtr.c 2530 2011-09-23 22:32:19Z brachman $";
#endif

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/*
 * Input is read one item per line
 * Example: for ncols=3, nitems=11
 *
 * 1 (+0) 5 (+4) 9 (+8)      ROW0
 * 2 (+1) 6 (+5) A (+9)      ROW1
 * 3 (+2) 7 (+6) B (+10)     ROW2
 * 4 (+3) 8 (+7)             ROW3
 */

static int
load(FILE *fp, char ***vecp)
{
    int n, nalloc;
    char buf[10240], *p, **vec;

    vec = NULL;
	n = nalloc = 0;
	while (fgets(buf, sizeof(buf), fp) != NULL) {
		if ((p = strchr(buf, (int) '\n')) == NULL)
			return(-1);
		*p = '\0';
		if (n == nalloc) {
			if (vec == NULL) {
				nalloc = 1024;
				vec = (char **) malloc(sizeof(char *) * (nalloc + 1));
			}
			else {
				nalloc *= 2;
				vec = (char **) realloc(vec, sizeof(char *) * (nalloc + 1));
			}
		}
		vec[n++] = strdup(buf);
	}
	if (!feof(fp))
		return(-1);

	*vecp = vec;

	return(n);
}

int
main(int argc, char **argv)
{
  int c, i, ncols, nitems, nrows, r, x;
  char *endptr, *str, **vec;

  ncols = 1;

  for (i = 1; i < argc; i++) {
	if (strcmp(argv[i], "-c") == 0) {
	  if (++i == argc) {
		fprintf(stderr, "Missing argument\n");
		exit(1);
	  }

      errno = 0;
      ncols = (int) strtol(argv[i], &endptr, 10);
	  if (argv[i][0] == '\0' || errno != 0 || *endptr != '\0') {
		fprintf(stderr, "Bad argument\n");
		exit(1);
	  }
	}
	else {
	  fprintf(stderr, "Invalid argument\n");
	  exit(1);
	}
  }

  if ((nitems = load(stdin, &vec)) == -1) {
	fprintf(stderr, "Input error\n");
	exit(1);
  }

  nrows = nitems / ncols;
  if (nitems % ncols)
	nrows++;

  for (r = 0; r < nrows; r++) {
	for (c = 0; c < ncols; c++) {
	  x = r + nrows * c;
	  if (x >= nitems)
		continue;
	  str = vec[x];
	  printf("%s\n", str);
	}
  }

  exit(0);
}
