/* wrap.c - fold long lines into multiple lines for eg thin lineprinters */

/* ufilter5.c - prototype filter program - line (actually record) oriented */
/*
 * Modular, fast, record filter skeleton.
 * Forces FD.CR on output file.
 * Gets file names from argv[1],[2]. Too hard to use stdin,stdout.
 * The record has NOTHING (like free '\n's) added to it.
 * Howlong = the record size in bytes.
 * Designed for R.VAR files.
 * Seperate input & output buffers
 */

#include <stdio.h>
#include <algol68.h>
#include <cx.h>
#include <nboff.h>
#include <fdoff.h>
char *	inbufp;		/* where the input buffer is			*/
int	bufmax;		/* maximum record size, needed for recinp()	*/
#define OUTMAX (bufmax)	/* maximum output record size			*/
FILE	*inf;		/* input file					*/
FILE	*ouf;		/* output file					*/
FDB *	fdbp;		/* obsolete kludge				*/
int	howlong;	/* char length of this record			*/
char *	otbufp;		/* where the output buffer is			*/

helpless(winge)
char *	winge;
BEGIN
fprintf(stderr,"\7%s\n",winge);
fprintf(stderr,"\n\nusage: WRAP in-file-name out-file-name width");
fprintf(stderr," {overflow-prefix} {ordinary-prefix}\n");
fprintf(stderr," Width is maximum width of an output file line.\n");
fprintf(stderr," Input lines longer than 'width' are broken after every\n");
fprintf(stderr," 'width' characters, by taking a new line (record actually)\n");
fprintf(stderr," and prepending 'overflow-prefix' (optional string) to each overflowed\n");
fprintf(stderr," line. For purposes of breaking lines, prefix strings DO NOT\n");
fprintf(stderr," get counted in line lengths.\n");
fprintf(stderr," 'Prefix' may use standard(?) C escapes: \\42 is a \", \t a tab.\n");
fprintf(stderr," 'Ordinary-prefix' is a string to prepend to non-overflowed lines.\n");
	exit();
END

int	width;		/* desired max output width (excluding prefix)	*/
char	ovprefix[100];	/* string to prefix overflow lines		*/
char	prefix[100];	/* string to prefix non-overflow lines		*/
#define OUTMAX (bufmax+300)	/* incase clown wants VERY big prefix	*/
int	remain;		/* chars remaining in input record		*/
char *	p;		/*						*/
char *	q;		/*						*/
int	thislen;	/* length of this segment of input record	*/
int	prelen;		/* length (excluding EOS) of prefix[] string	*/
int	ovprelen;	/* prelen, but for ovprefix[]			*/

main(argc,argv)
char **argv;
BEGIN
char *	recinp();	/* the record-getter: 0 means end-of-file	*/

	IF	(argc<4)
	THEN	helpless("I expect at least 3 arguments: in-file out-file width");
	FI
	IF	((inf=fopen(argv[1],"urn"))==NULL)
	THEN	error("can't find %s\7",argv[1]);
	FI
	fdbp = inf -> io_fdb;
	IF	(!(inbufp=malloc(bufmax=fdbp->f_fatt.f_rsiz)))
	THEN	error("max record size=%d.\7",bufmax);
	FI

	IF	(!(otbufp=malloc(OUTMAX)))
	THEN	error("MAX rec siz=%d.\7",OUTMAX);
	FI
	IF	((ouf=fopen(argv[2],"uwn"))==NULL)
	THEN	error("can't make %s\7",argv[2]);
	FI
	fdbp = ouf -> io_fdb;
	fdbp -> f_fatt . f_ratt |= fd_cr;	/* force fd.cr		*/

	sscanf(argv[3],"%d",&width);
	IF	(width<=0)
	THEN	fprintf(stderr,"\7width assumed to be 1, not %d.!\n",width);
		width = 1;
	FI

	p = ovprefix;
	IF	(argc>4)
	THEN	FOR	(q=argv[4]; *q; q++)
		DO	*p++ = esc(&q);
		OD
	FI
	*p = EOS;

	p = prefix;
	IF	(argc>5)
	THEN	FOR	(q=argv[5]; *q; q++)
		DO	*p++ = esc(&q);
		OD
	FI
	*p = EOS;

	prelen   = strlen(  prefix);
	ovprelen = strlen(ovprefix);

	WHILE	(recinp(inbufp,bufmax,inf,&howlong))
	DO	copy(otbufp,prefix,prelen);
		p = otbufp+prelen;
		q = inbufp;
		FOR	(remain=howlong; remain; remain-=thislen)
		DO	thislen = min(remain,width);
			copy(p,q,thislen);
			p+=thislen;
			q+=thislen;
			recout(otbufp,p-otbufp,ouf);
			copy(otbufp,ovprefix,ovprelen);
			p = otbufp+ovprelen;
		OD
	OD

	IF	(fclose(ouf))
	THEN	error("Can't close\7");
	FI
END

char * recinp (where,moby,sewer,lenp)	/* 0==end-file, else buf adr	*/
char *	where;				/* buffer			*/
int	moby;				/* buffer size			*/
FILE *	sewer;				/* input file			*/
int *	lenp;				/* return actual record size	*/
BEGIN
	*lenp = fget(where,moby,sewer);
	IF	(ferror(sewer))
	THEN	error("read failure $$ferr=%oo\7\n",$$ferr);
	FI
	return	(feof(sewer)?NULL:where);
END

recout(where,len,sewer)
char *	where;		/* buffer					*/
int	len;		/* record size					*/
FILE *	sewer;		/* output file					*/
BEGIN
	fput(where,len,sewer);
	IF	(ferror(sewer))
	THEN	error("write failed $$ferr=%oo len=%d.\7\n",$$ferr,len);
	FI
END
/* end: ufilter4.c */
