
/*
 * mc.c
 *
 * Convert a file to multi column format.
 *
 * Usage:
 *	mc [-option value]... files.
 *
 * Options:
 *						Default
 *	-c	number of columns		   2
 *	-h	number of lines on the page	  60
 *	-w	width of the page		 132
 */

/*)BUILD	$(TKBOPTIONS) = {
			TASK	= ...MUL
		}
*/

#ifdef	DOCUMENTATION

title	mc	Multi-column Filter
index		Multi-column Filter

synopsis

	mc [-options] file__list

description

	Mc converts its input files to a multi-column format, writing all
	output to the standard output.  If no input files are specified,
	the standard input is read.
	.s
	The following options may be used to control mc:
	.lm +16
	.s.i-16;-c value (  2)	Number of columns to output.
	.s.i-16;-h value ( 60)	Height (lines per page).
	.s.i-16;-w value (132)	Width (columns per line).
	.lm -16

diagnostics

	.lm +8
	.s.i -8;Unreasonable -c (value) or -w (value).
	.s.i -8;Bad (option) specification.
	.s.i -8;(Filename): cannot open.
	.lm -8

author

	David Conroy

bugs

#endif

#include <stdio.h>

#define	WMAX	132
#define HMAX	60

int	wmax	= WMAX;
int	hmax	= HMAX;
int	ncol	= 2;

int	row;
int	col;
int	lmax;

char	line[128];
char	page[HMAX][WMAX];

main(argc, argv)
char *argv[];
{
	register char *p;
	register c, i;
	int nf;
	FILE *fp;

	nf = argc-1;
	for(i=1; i<argc; ++i) {
		p = argv[i];
		if(*p == '-') {
			argv[i] = 0;
			--nf;
			for(++p; c = *p++; )
				switch(c) {

				case 'c':
				case 'C':
					if(++i >= argc)
						usage();
					ncol = atoi(argv[i]);
					if(ncol == 0)
						bad(ncol, "column");
					argv[i] = 0;
					--nf;
					break;

				case 'h':
				case 'H':
					if(++i >= argc)
						usage();
					hmax = atoi(argv[i]);
					if(hmax > HMAX)
						bad(hmax, "height");
					argv[i] = 0;
					--nf;
					break;

				case 'w':
				case 'W':
					if(++i >= argc)
						usage();
					wmax = atoi(argv[i]);
					if(wmax > WMAX)
						bad(wmax, "width");
					argv[i] = 0;
					--nf;
					break;

				default:
					usage();
				}
		}
	}
	lmax = wmax/ncol - 1;
	if(lmax < 1)
		error("Unreasonable -c (%d) or -w (%d).\n", ncol, wmax);
	if(nf == 0)
		process(stdin);
	else
		for(i=1; i<argc; ++i)
			if(p = argv[i]) {
				if((fp=fopen(p, "r")) == NULL) {
					fprintf(stderr, "%s: cannot open.\n",
							p);
					continue;
				}
				process(fp);
				fclose(fp);
			}
}

process(fp)
FILE *fp;
{
	register char *p1, *p2;
	register c;

	row = 0;
	col = 0;
	blank();
	while(get(fp)) {
		if(++row >= hmax) {
			if(++col >= ncol) {
				output();
				col = 0;
				blank();
			}
			row = 0;
		}
		p1 = line;
		p2 = &page[row][(wmax*col)/ncol];
		while(c = *p1++)
			*p2++ = c;
	}
	output();
}

output()
{
	register char *p1, *p2;
	register i;

	if(row==0 && col==0)
		return;
	putchar('\f');
	for(i=0; i<hmax; ++i) {
		p1 = &page[i][0];
		p2 = p1 + wmax;
		while(p2>p1 && p2[-1]==' ')
			--p2;
		while(p1 < p2)
			putchar(*p1++);
		putchar('\n');
	}
}

blank()
{
	register char *p1, *p2;
	register i;

	for(i=0; i<hmax; ++i) {
		p1 = &page[i][0];
		p2 = p1 + wmax;
		while(p1 < p2)
			*p1++ = ' ';
	}
}

get(fp)
FILE *fp;
{
	register char *p;
	register c, h;

	p = line;
	h = 0;
	while((c=getc(fp))!=EOF && c!='\n') {
		if(c == '\b') {
			if(h) {
				--p;
				--h;
			}
		} else if(c == '\t') {
			do {
				*p++ = ' ';
			} while((++h&07) != 0);
		} else if(c>=' ' && c<='~') {
			*p++ = c;
			++h;
		}
	}
	*p = 0;
	line[lmax] = 0;
	return(c == '\n');
}

bad(n, s)
char *s;
{
	error("%d: bad %s specification.\n", n, s);
}

usage()
{
	error("Usage: mc [-c #] [-h #] [-w #] [file ...].\n\
	-c Number of columns          <2>\n\
	-h Height (lines per page)   <60>\n\
	-w Width (columns per line) <132>\n");
}
