xref: /onnv-gate/usr/src/cmd/newform/newform.c (revision 364:f36290b8cb0b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*364Sceastha /*
23*364Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*364Sceastha  * Use is subject to license terms.
25*364Sceastha  */
26*364Sceastha 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
30*364Sceastha #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
32*364Sceastha /*
33*364Sceastha  *	FUNCTION PAGE INDEX
34*364Sceastha  * Function	Page		Description
35*364Sceastha  * append	16	Append chars to end of line.
36*364Sceastha  * begtrunc	16	Truncate characters from beginning of line.
37*364Sceastha  * center	5	Center text in the work area.
38*364Sceastha  * cnvtspec	7	Convert tab spec to tab positions.
39*364Sceastha  * endtrunc	16	Truncate chars from end of line.
40*364Sceastha  * inputtabs	17	Expand according to input tab specs.
41*364Sceastha  * main		3	MAIN
42*364Sceastha  * inputn	5	Read a command line option number.
43*364Sceastha  * options	4	Process command line options.
44*364Sceastha  * outputtabs	19	Contract according to output tab specs.
45*364Sceastha  * prepend	16	Prepend chars to line.
46*364Sceastha  * process	15	Process one line of input.
47*364Sceastha  * readline	14	Read one line from the file.
48*364Sceastha  * readspec	12	Read a tabspec from a file.
49*364Sceastha  * sstrip	18	Strip SCCS SID char from beginning of line.
50*364Sceastha  * sadd		18	Add SCCS SID chars to end of line.
51*364Sceastha  * type		14	Determine type of a character.
52*364Sceastha  */
530Sstevel@tonic-gate 
54*364Sceastha #include <stdlib.h>
55*364Sceastha #include <string.h>
56*364Sceastha #include <stdio.h>
570Sstevel@tonic-gate 
580Sstevel@tonic-gate #define	MAXOPTS	50
590Sstevel@tonic-gate #define	NCOLS	512
600Sstevel@tonic-gate #define	MAXLINE	512
610Sstevel@tonic-gate #define	NUMBER	'0'
620Sstevel@tonic-gate #define	LINELEN	80
630Sstevel@tonic-gate 
64*364Sceastha static int tabtbl[500] = {		/* Table containing tab stops	*/
65*364Sceastha 	1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 0,
66*364Sceastha 					/* Default tabs			*/
67*364Sceastha 	1, 10, 16, 36, 72, 0,		/* IBM 370 Assembler		*/
68*364Sceastha 	1, 10, 16, 40, 72, 0,		/* IBM 370 Assembler (alt.)	*/
69*364Sceastha 	1, 8, 12, 16, 20, 55, 0,	/* COBOL			*/
70*364Sceastha 	1, 6, 10, 14, 49, 0,		/* COBOL (crunched)		*/
71*364Sceastha 	1, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 67, 0,
72*364Sceastha 					/* COBOL (crunched, many cols.)	*/
73*364Sceastha 	1, 7, 11, 15, 19, 23, 0,	/* FORTRAN			*/
74*364Sceastha 	1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0,
75*364Sceastha 					/* PL/1				*/
76*364Sceastha 	1, 10, 55, 0,			/* SNOBOL			*/
77*364Sceastha 	1, 12, 20, 44, 0 },		/* UNIVAC Assembler		*/
780Sstevel@tonic-gate 
79*364Sceastha 	*nexttab = &tabtbl[87],		/* Pointer to next empty slot	*/
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	*spectbl[40] = {	/* Table of pointers into tabtbl	*/
820Sstevel@tonic-gate 	&tabtbl[0],		/* Default specification		*/
830Sstevel@tonic-gate 	&tabtbl[11],		/* -a  specification			*/
840Sstevel@tonic-gate 	&tabtbl[17],		/* -a2 specification			*/
850Sstevel@tonic-gate 	&tabtbl[23],		/* -c  specification			*/
860Sstevel@tonic-gate 	&tabtbl[30],		/* -c2 specification			*/
870Sstevel@tonic-gate 	&tabtbl[36],		/* -c3 specification			*/
880Sstevel@tonic-gate 	&tabtbl[54],		/* -f  specification			*/
890Sstevel@tonic-gate 	&tabtbl[61],		/* -p  specification			*/
900Sstevel@tonic-gate 	&tabtbl[78],		/* -s  specification			*/
910Sstevel@tonic-gate 	&tabtbl[82] },		/* -u  specification			*/
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	savek;		/* Stores char count stripped from front of line. */
94*364Sceastha static int nextspec = 10,	/* Index to next slot			*/
950Sstevel@tonic-gate 	sitabspec = -1,		/* Index to "standard input" spec.	*/
960Sstevel@tonic-gate 	effll	= 80,		/* Effective line length		*/
970Sstevel@tonic-gate 	optionf = 0,		/* 'f' option set			*/
980Sstevel@tonic-gate 	soption = 0,		/* 's' option used. */
990Sstevel@tonic-gate 	files	= 0,		/* Number of input files		*/
1000Sstevel@tonic-gate 	kludge	= 0,		/* Kludge to allow reread of 1st line	*/
101*364Sceastha 	okludge = 0,		/* Kludge to indicate reading "o" option */
1020Sstevel@tonic-gate 	lock	= 0;		/* Lock to prevent file indirection	*/
1030Sstevel@tonic-gate 
104*364Sceastha static char pachar = ' ',	/* Prepend/append character		*/
1050Sstevel@tonic-gate 	work[3*NCOLS+1],	/* Work area				*/
1060Sstevel@tonic-gate 	*pfirst,		/* Pointer to beginning of line 	*/
1070Sstevel@tonic-gate 	*plast,			/* Pointer to end of line		*/
1080Sstevel@tonic-gate 	*wfirst = &work[0],	/* Pointer to beginning of work area	*/
1090Sstevel@tonic-gate 	*wlast  = &work[3*NCOLS], /* Pointer to end of work area	*/
1100Sstevel@tonic-gate 	siline[NCOLS],		/* First standard input line		*/
1110Sstevel@tonic-gate 	savchr[8],		/* Holds char stripped from line start */
112*364Sceastha 	format[80] = "-8";	/* Array to hold format line		*/
1130Sstevel@tonic-gate 
114*364Sceastha static struct f {
1150Sstevel@tonic-gate 	char	option;
1160Sstevel@tonic-gate 	int	param;
1170Sstevel@tonic-gate 	}	optl[MAXOPTS],	/* List of command line options 	*/
1180Sstevel@tonic-gate 		*flp = optl;	/* Pointer to next open slot		*/
119*364Sceastha 
120*364Sceastha static void append(int);
121*364Sceastha static void begtrunc(int);
122*364Sceastha static void center(void);
123*364Sceastha static int cnvtspec(char *);
124*364Sceastha static void endtrunc(int);
125*364Sceastha static int inputn(char *);
126*364Sceastha static void inputtabs(int);
127*364Sceastha static void options(int, char **);
128*364Sceastha static void outputtabs(int);
129*364Sceastha static void prepend(int);
130*364Sceastha static void process(FILE *);
131*364Sceastha static char *readline(FILE *, char *);
132*364Sceastha static int readspec(char *);
133*364Sceastha static void sadd(void);
134*364Sceastha static void sstrip(void);
135*364Sceastha static char type(char);
136*364Sceastha 
137*364Sceastha int
main(int argc,char ** argv)138*364Sceastha main(int argc, char **argv)
1390Sstevel@tonic-gate {
1400Sstevel@tonic-gate 	char	*scan;		/* String scan pointer			*/
1410Sstevel@tonic-gate 	FILE	*fp;		/* Pointer to current file		*/
1420Sstevel@tonic-gate 
143*364Sceastha 	options(argc, argv);
144*364Sceastha 	if (optionf) {		/* Write tab spec format line. */
145*364Sceastha 		(void) fputs("<:t", stdout);
146*364Sceastha 		(void) fputs(format, stdout);
147*364Sceastha 		(void) fputs(" d:>\n", stdout);
148*364Sceastha 	}
1490Sstevel@tonic-gate 	if (files) {
1500Sstevel@tonic-gate 		while (--argc) {
1510Sstevel@tonic-gate 			scan = *++argv;
1520Sstevel@tonic-gate 			if (*scan != '-') {
153*364Sceastha 				if ((fp = fopen(scan, "r")) == NULL) {
154*364Sceastha 					(void) fprintf(stderr,
155*364Sceastha 					    "newform: can't open %s\n", scan);
1560Sstevel@tonic-gate 					exit(1);
157*364Sceastha 				}
1580Sstevel@tonic-gate 				process(fp);
159*364Sceastha 				(void) fclose(fp);
1600Sstevel@tonic-gate 			}
1610Sstevel@tonic-gate 		}
162*364Sceastha 	} else {
1630Sstevel@tonic-gate 		process(stdin);
164*364Sceastha 	}
165*364Sceastha 	return (0);
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 
169*364Sceastha static void
options(int argc,char ** argv)170*364Sceastha options(int argc, char **argv)		/* Process command line options	*/
1710Sstevel@tonic-gate {
1720Sstevel@tonic-gate 	int	n;		/* Temporary number holder		*/
173*364Sceastha 	char	*scan;		/* Pointer to individual option strings	*/
174*364Sceastha 	char	c;		/* Option character			*/
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate /*	changes to option parsing includes checks for exceeding	*/
1770Sstevel@tonic-gate /*	initial buffer sizes					*/
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	while (--argc > 0) {
1800Sstevel@tonic-gate 		scan = *++argv;
1810Sstevel@tonic-gate 		if (*scan++ == '-') {
1820Sstevel@tonic-gate 			switch (c = *scan++) {
1830Sstevel@tonic-gate 			case 'a':
1840Sstevel@tonic-gate 				flp->option = 'a';
1850Sstevel@tonic-gate 				flp->param = inputn(scan);
186*364Sceastha 				if (flp->param <= NCOLS)
1870Sstevel@tonic-gate 					flp++;
1880Sstevel@tonic-gate 				else {
189*364Sceastha 					(void) fprintf(stderr, "newform: "
190*364Sceastha 					    "prefix request larger than "
191*364Sceastha 					    "buffer, %d\n", NCOLS);
1920Sstevel@tonic-gate 					exit(1);
1930Sstevel@tonic-gate 				}
1940Sstevel@tonic-gate 				break;
1950Sstevel@tonic-gate 			case 'b':
1960Sstevel@tonic-gate 			case 'e':
1970Sstevel@tonic-gate 				flp->option = c;
1980Sstevel@tonic-gate 				flp->param = inputn(scan);
1990Sstevel@tonic-gate 				flp++;
2000Sstevel@tonic-gate 				break;
2010Sstevel@tonic-gate 			case 'p':
2020Sstevel@tonic-gate 				flp->option = 'p';
2030Sstevel@tonic-gate 				flp->param = inputn(scan);
204*364Sceastha 				if (flp->param <= NCOLS)
2050Sstevel@tonic-gate 					flp++;
2060Sstevel@tonic-gate 				else {
207*364Sceastha 					(void) fprintf(stderr, "newform: "
208*364Sceastha 					    "prefix request larger than "
209*364Sceastha 					    "buffer, %d\n", NCOLS);
2100Sstevel@tonic-gate 					exit(1);
2110Sstevel@tonic-gate 				}
2120Sstevel@tonic-gate 				break;
2130Sstevel@tonic-gate 			case 'c':
2140Sstevel@tonic-gate 				flp->option = 'c';
2150Sstevel@tonic-gate 				flp->param = *scan ? *scan : ' ';
2160Sstevel@tonic-gate 				flp++;
2170Sstevel@tonic-gate 				break;
2180Sstevel@tonic-gate 			case 'f':
2190Sstevel@tonic-gate 				flp->option = 'f';
2200Sstevel@tonic-gate 				optionf++;
2210Sstevel@tonic-gate 				flp++;
2220Sstevel@tonic-gate 				break;
2230Sstevel@tonic-gate 			case 'i':
2240Sstevel@tonic-gate 				flp->option = 'i';
2250Sstevel@tonic-gate 				flp->param = cnvtspec(scan);
2260Sstevel@tonic-gate 				flp++;
2270Sstevel@tonic-gate 				break;
2280Sstevel@tonic-gate 			case 'o':
229*364Sceastha 				if (*scan == '-' && *(scan+1) == '0' &&
230*364Sceastha 				    *(scan+2) == '\0')
231*364Sceastha 					break;
232*364Sceastha 			/* Above allows the -o-0 option to be ignored. */
2330Sstevel@tonic-gate 				flp->option = 'o';
234*364Sceastha 				(void) strcpy(format, scan);
2350Sstevel@tonic-gate 				okludge++;
2360Sstevel@tonic-gate 				flp->param = cnvtspec(scan);
2370Sstevel@tonic-gate 				okludge--;
238*364Sceastha 				if (flp->param == 0)
239*364Sceastha 					(void) strcpy(format, "-8");
2400Sstevel@tonic-gate 				flp++;
2410Sstevel@tonic-gate 				break;
2420Sstevel@tonic-gate 			case 'l':
2430Sstevel@tonic-gate 				flp->option = 'l';
2440Sstevel@tonic-gate 				flp->param = ((n = inputn(scan)) ? n : 72);
2450Sstevel@tonic-gate 				if (flp->param <= (3*NCOLS))
2460Sstevel@tonic-gate 					flp++;
2470Sstevel@tonic-gate 				else {
248*364Sceastha 					(void) fprintf(stderr, "newform: "
249*364Sceastha 					    "line length request larger "
250*364Sceastha 					    "than buffer, %d \n", (3*NCOLS));
2510Sstevel@tonic-gate 					exit(1);
2520Sstevel@tonic-gate 				}
2530Sstevel@tonic-gate 				break;
2540Sstevel@tonic-gate 			case 's':
2550Sstevel@tonic-gate 				flp->option = 's';
2560Sstevel@tonic-gate 				flp++;
2570Sstevel@tonic-gate 				soption++;
2580Sstevel@tonic-gate 				break;
2590Sstevel@tonic-gate 			default:
2600Sstevel@tonic-gate 				goto usageerr;
2610Sstevel@tonic-gate 				}
2620Sstevel@tonic-gate 			}
2630Sstevel@tonic-gate 		else
2640Sstevel@tonic-gate 			files++;
2650Sstevel@tonic-gate 		}
2660Sstevel@tonic-gate 	return;
2670Sstevel@tonic-gate usageerr:
268*364Sceastha 	(void) fprintf(stderr, "usage: newform  [-s] [-itabspec] [-otabspec] ");
269*364Sceastha 	(void) fprintf(stderr, "[-pn] [-en] [-an] [-f] [-cchar]\n\t\t");
270*364Sceastha 	(void) fprintf(stderr, "[-ln] [-bn] [file ...]\n");
2710Sstevel@tonic-gate 	exit(1);
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate /* _________________________________________________________________ */
2740Sstevel@tonic-gate 
275*364Sceastha static int
inputn(char * scan)276*364Sceastha inputn(char *scan)		/* Read a command option number		*/
277*364Sceastha 	/* Pointer to string of digits */
2780Sstevel@tonic-gate {
2790Sstevel@tonic-gate 	int	n;		/* Number				*/
2800Sstevel@tonic-gate 	char	c;		/* Character being scanned		*/
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	n = 0;
2830Sstevel@tonic-gate 	while ((c = *scan++) >= '0' && c <= '9')
2840Sstevel@tonic-gate 		n = n * 10 + c - '0';
285*364Sceastha 	return (n);
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate /* _________________________________________________________________ */
2880Sstevel@tonic-gate 
289*364Sceastha static void
center(void)290*364Sceastha center(void)			/* Center the text in the work area.	*/
2910Sstevel@tonic-gate {
292*364Sceastha 	char	*tfirst;	/* Pointer for moving buffer down	*/
293*364Sceastha 	char	*tlast;		/* Pointer for moving buffer up		*/
294*364Sceastha 	char	*tptr;		/* Temporary				*/
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	if (plast - pfirst > MAXLINE) {
297*364Sceastha 		(void) fprintf(stderr, "newform: internal line too long\n");
2980Sstevel@tonic-gate 		exit(1);
299*364Sceastha 	}
3000Sstevel@tonic-gate 	if (pfirst < &work[NCOLS]) {
3010Sstevel@tonic-gate 		tlast = plast + (&work[NCOLS] - pfirst);
3020Sstevel@tonic-gate 		tptr = tlast;
3030Sstevel@tonic-gate 		while (plast >= pfirst) *tlast-- = *plast--;
3040Sstevel@tonic-gate 		pfirst = ++tlast;
3050Sstevel@tonic-gate 		plast = tptr;
306*364Sceastha 	} else {
3070Sstevel@tonic-gate 		tfirst = &work[NCOLS];
3080Sstevel@tonic-gate 		tptr = tfirst;
3090Sstevel@tonic-gate 		while (pfirst <= plast) *tfirst++ = *pfirst++;
3100Sstevel@tonic-gate 		plast = --tfirst;
3110Sstevel@tonic-gate 		pfirst = tptr;
312*364Sceastha 	}
3130Sstevel@tonic-gate }
314*364Sceastha 
315*364Sceastha static int
cnvtspec(char * p)316*364Sceastha cnvtspec(char *p)	/* Convert tab specification to tab positions.	*/
317*364Sceastha 	/* Pointer to spec string. */
3180Sstevel@tonic-gate {
3190Sstevel@tonic-gate 	int	state,		/* DFA state				*/
3200Sstevel@tonic-gate 		spectype,	/* Specification type			*/
3210Sstevel@tonic-gate 		number[40],	/* Array of read-in numbers		*/
3220Sstevel@tonic-gate 		tp,		/* Pointer to last number		*/
3230Sstevel@tonic-gate 		ix;		/* Temporary				*/
324*364Sceastha 	int	tspec = 0;	/* Tab spec pointer			*/
3250Sstevel@tonic-gate 	char	c,		/* Temporary				*/
326*364Sceastha 		*filep;		/* Pointer to file name			*/
327*364Sceastha 	FILE	*fp;		/* File pointer				*/
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	state = 0;
3300Sstevel@tonic-gate 	while (state >= 0) {
3310Sstevel@tonic-gate 		c = *p++;
3320Sstevel@tonic-gate 		switch (state) {
3330Sstevel@tonic-gate 		case 0:
3340Sstevel@tonic-gate 			switch (type(c)) {
3350Sstevel@tonic-gate 			case '\0':
3360Sstevel@tonic-gate 				spectype = 0;
3370Sstevel@tonic-gate 				state = -1;
3380Sstevel@tonic-gate 				break;
3390Sstevel@tonic-gate 			case NUMBER:
3400Sstevel@tonic-gate 				state = 1;
3410Sstevel@tonic-gate 				tp = 0;
3420Sstevel@tonic-gate 				number[tp] = c - '0';
3430Sstevel@tonic-gate 				break;
3440Sstevel@tonic-gate 			case '-':
3450Sstevel@tonic-gate 				state = 3;
3460Sstevel@tonic-gate 				break;
3470Sstevel@tonic-gate 			default:
3480Sstevel@tonic-gate 				goto tabspecerr;
3490Sstevel@tonic-gate 				}
3500Sstevel@tonic-gate 			break;
3510Sstevel@tonic-gate 		case 1:
3520Sstevel@tonic-gate 			switch (type(c)) {
3530Sstevel@tonic-gate 			case '\0':
3540Sstevel@tonic-gate 				spectype = 11;
3550Sstevel@tonic-gate 				state = -1;
3560Sstevel@tonic-gate 				break;
3570Sstevel@tonic-gate 			case NUMBER:
3580Sstevel@tonic-gate 				state = 1;
3590Sstevel@tonic-gate 				number[tp] = number[tp] * 10 + c - '0';
3600Sstevel@tonic-gate 				break;
3610Sstevel@tonic-gate 			case ',':
3620Sstevel@tonic-gate 				state = 2;
3630Sstevel@tonic-gate 				break;
3640Sstevel@tonic-gate 			default:
3650Sstevel@tonic-gate 				goto tabspecerr;
3660Sstevel@tonic-gate 				}
3670Sstevel@tonic-gate 			break;
3680Sstevel@tonic-gate 		case 2:
3690Sstevel@tonic-gate 			if (type(c) == NUMBER) {
3700Sstevel@tonic-gate 				state = 1;
3710Sstevel@tonic-gate 				number[++tp] = c - '0';
3720Sstevel@tonic-gate 				}
3730Sstevel@tonic-gate 			else
3740Sstevel@tonic-gate 				goto tabspecerr;
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 			break;
3770Sstevel@tonic-gate 		case 3:
3780Sstevel@tonic-gate 			switch (type(c)) {
3790Sstevel@tonic-gate 			case '-':
3800Sstevel@tonic-gate 				state = 4;
3810Sstevel@tonic-gate 				break;
3820Sstevel@tonic-gate 			case 'a':
3830Sstevel@tonic-gate 				state = 5;
3840Sstevel@tonic-gate 				break;
3850Sstevel@tonic-gate 			case 'c':
3860Sstevel@tonic-gate 				state = 7;
3870Sstevel@tonic-gate 				break;
3880Sstevel@tonic-gate 			case 'f':
3890Sstevel@tonic-gate 				state = 10;
3900Sstevel@tonic-gate 				break;
3910Sstevel@tonic-gate 			case 'p':
3920Sstevel@tonic-gate 				state = 11;
3930Sstevel@tonic-gate 				break;
3940Sstevel@tonic-gate 			case 's':
3950Sstevel@tonic-gate 				state = 12;
3960Sstevel@tonic-gate 				break;
3970Sstevel@tonic-gate 			case 'u':
3980Sstevel@tonic-gate 				state = 13;
3990Sstevel@tonic-gate 				break;
4000Sstevel@tonic-gate 			case NUMBER:
4010Sstevel@tonic-gate 				state = 14;
4020Sstevel@tonic-gate 				number[0] = c - '0';
4030Sstevel@tonic-gate 				break;
4040Sstevel@tonic-gate 			default:
4050Sstevel@tonic-gate 				goto tabspecerr;
4060Sstevel@tonic-gate 				}
4070Sstevel@tonic-gate 			break;
4080Sstevel@tonic-gate 		case 4:
4090Sstevel@tonic-gate 			if (c == '\0') {
4100Sstevel@tonic-gate 				spectype = 12;
4110Sstevel@tonic-gate 				state = -1;
412*364Sceastha 			} else {
4130Sstevel@tonic-gate 				filep = --p;
4140Sstevel@tonic-gate 				spectype = 13;
4150Sstevel@tonic-gate 				state = -1;
416*364Sceastha 			}
4170Sstevel@tonic-gate 			break;
4180Sstevel@tonic-gate 		case 5:
4190Sstevel@tonic-gate 			if (c == '\0') {
4200Sstevel@tonic-gate 				spectype = 1;
4210Sstevel@tonic-gate 				state = -1;
422*364Sceastha 			} else if (c == '2')
4230Sstevel@tonic-gate 				state = 6;
4240Sstevel@tonic-gate 			else
4250Sstevel@tonic-gate 				goto tabspecerr;
4260Sstevel@tonic-gate 			break;
4270Sstevel@tonic-gate 		case 6:
4280Sstevel@tonic-gate 			if (c == '\0') {
4290Sstevel@tonic-gate 				spectype = 2;
4300Sstevel@tonic-gate 				state = -1;
4310Sstevel@tonic-gate 				}
4320Sstevel@tonic-gate 			else
4330Sstevel@tonic-gate 				goto tabspecerr;
4340Sstevel@tonic-gate 			break;
4350Sstevel@tonic-gate 		case 7:
4360Sstevel@tonic-gate 			switch (c) {
4370Sstevel@tonic-gate 			case '\0':
4380Sstevel@tonic-gate 				spectype = 3;
4390Sstevel@tonic-gate 				state = -1;
4400Sstevel@tonic-gate 				break;
4410Sstevel@tonic-gate 			case '2':
4420Sstevel@tonic-gate 				state = 8;
4430Sstevel@tonic-gate 				break;
4440Sstevel@tonic-gate 			case '3':
4450Sstevel@tonic-gate 				state = 9;
4460Sstevel@tonic-gate 				break;
4470Sstevel@tonic-gate 			default:
4480Sstevel@tonic-gate 				goto tabspecerr;
4490Sstevel@tonic-gate 				}
4500Sstevel@tonic-gate 			break;
4510Sstevel@tonic-gate 		case 8:
4520Sstevel@tonic-gate 			if (c == '\0') {
4530Sstevel@tonic-gate 				spectype = 4;
4540Sstevel@tonic-gate 				state = -1;
4550Sstevel@tonic-gate 				}
4560Sstevel@tonic-gate 			else
4570Sstevel@tonic-gate 				goto tabspecerr;
4580Sstevel@tonic-gate 			break;
4590Sstevel@tonic-gate 		case 9:
4600Sstevel@tonic-gate 			if (c == '\0') {
4610Sstevel@tonic-gate 				spectype = 5;
4620Sstevel@tonic-gate 				state = -1;
4630Sstevel@tonic-gate 				}
4640Sstevel@tonic-gate 			else
4650Sstevel@tonic-gate 				goto tabspecerr;
4660Sstevel@tonic-gate 			break;
4670Sstevel@tonic-gate 		case 10:
4680Sstevel@tonic-gate 			if (c == '\0') {
4690Sstevel@tonic-gate 				spectype = 6;
4700Sstevel@tonic-gate 				state = -1;
4710Sstevel@tonic-gate 				}
4720Sstevel@tonic-gate 			else
4730Sstevel@tonic-gate 				goto tabspecerr;
4740Sstevel@tonic-gate 			break;
4750Sstevel@tonic-gate 		case 11:
4760Sstevel@tonic-gate 			if (c == '\0') {
4770Sstevel@tonic-gate 				spectype = 7;
4780Sstevel@tonic-gate 				state = -1;
4790Sstevel@tonic-gate 				}
4800Sstevel@tonic-gate 			else
4810Sstevel@tonic-gate 				goto tabspecerr;
4820Sstevel@tonic-gate 			break;
4830Sstevel@tonic-gate 		case 12:
4840Sstevel@tonic-gate 			if (c == '\0') {
4850Sstevel@tonic-gate 				spectype = 8;
4860Sstevel@tonic-gate 				state = -1;
4870Sstevel@tonic-gate 				}
4880Sstevel@tonic-gate 			else
4890Sstevel@tonic-gate 				goto tabspecerr;
4900Sstevel@tonic-gate 			break;
4910Sstevel@tonic-gate 		case 13:
4920Sstevel@tonic-gate 			if (c == '\0') {
4930Sstevel@tonic-gate 				spectype = 9;
4940Sstevel@tonic-gate 				state = -1;
4950Sstevel@tonic-gate 				}
4960Sstevel@tonic-gate 			else
4970Sstevel@tonic-gate 				goto tabspecerr;
4980Sstevel@tonic-gate 			break;
4990Sstevel@tonic-gate 		case 14:
5000Sstevel@tonic-gate 			if (type(c) == NUMBER) {
5010Sstevel@tonic-gate 				state = 14;
5020Sstevel@tonic-gate 				number[0] = number[0] * 10 + c - '0';
503*364Sceastha 			} else if (c == '\0') {
5040Sstevel@tonic-gate 				spectype = 10;
5050Sstevel@tonic-gate 				state = -1;
506*364Sceastha 			} else
5070Sstevel@tonic-gate 				goto tabspecerr;
5080Sstevel@tonic-gate 			break;
5090Sstevel@tonic-gate 		}
510*364Sceastha 	}
511*364Sceastha 	if (spectype <= 9)
512*364Sceastha 		return (spectype);
5130Sstevel@tonic-gate 	if (spectype == 10) {
5140Sstevel@tonic-gate 		spectype = nextspec++;
5150Sstevel@tonic-gate 		spectbl[spectype] = nexttab;
5160Sstevel@tonic-gate 		*nexttab = 1;
517*364Sceastha 		if (number[0] == 0) number[0] = 1; /* Prevent infinite loop. */
5180Sstevel@tonic-gate 		while (*nexttab < LINELEN) {
5190Sstevel@tonic-gate 			*(nexttab + 1) = *nexttab;
5200Sstevel@tonic-gate 			*++nexttab += number[0];
5210Sstevel@tonic-gate 			}
5220Sstevel@tonic-gate 		*nexttab++ = '\0';
523*364Sceastha 		return (spectype);
524*364Sceastha 	}
5250Sstevel@tonic-gate 	if (spectype == 11) {
5260Sstevel@tonic-gate 		spectype = nextspec++;
5270Sstevel@tonic-gate 		spectbl[spectype] = nexttab;
5280Sstevel@tonic-gate 		*nexttab++ = 1;
5290Sstevel@tonic-gate 		for (ix = 0; ix <= tp; ix++) {
5300Sstevel@tonic-gate 			*nexttab++ = number[ix];
5310Sstevel@tonic-gate 			if ((number[ix] >= number[ix+1]) && (ix != tp))
5320Sstevel@tonic-gate 				goto tabspecerr;
5330Sstevel@tonic-gate 			}
5340Sstevel@tonic-gate 		*nexttab++ = '\0';
535*364Sceastha 		return (spectype);
536*364Sceastha 	}
5370Sstevel@tonic-gate 	if (lock == 1) {
538*364Sceastha 		(void) fprintf(stderr,
539*364Sceastha 		    "newform: tabspec indirection illegal\n");
5400Sstevel@tonic-gate 		exit(1);
541*364Sceastha 	}
5420Sstevel@tonic-gate 	lock = 1;
5430Sstevel@tonic-gate 	if (spectype == 12) {
5440Sstevel@tonic-gate 		if (sitabspec >= 0) {
5450Sstevel@tonic-gate 			tspec = sitabspec;
546*364Sceastha 		} else {
547*364Sceastha 			if (readline(stdin, siline) != NULL) {
5480Sstevel@tonic-gate 				kludge = 1;
5490Sstevel@tonic-gate 				tspec = readspec(siline);
5500Sstevel@tonic-gate 				sitabspec = tspec;
5510Sstevel@tonic-gate 			}
5520Sstevel@tonic-gate 		}
5530Sstevel@tonic-gate 	}
5540Sstevel@tonic-gate 	if (spectype == 13) {
555*364Sceastha 		if ((fp = fopen(filep, "r")) == NULL) {
556*364Sceastha 			(void) fprintf(stderr,
557*364Sceastha 			    "newform: can't open %s\n", filep);
5580Sstevel@tonic-gate 			exit(1);
559*364Sceastha 		}
560*364Sceastha 		(void) readline(fp, work);
561*364Sceastha 		(void) fclose(fp);
5620Sstevel@tonic-gate 		tspec = readspec(work);
563*364Sceastha 	}
5640Sstevel@tonic-gate 	lock = 0;
565*364Sceastha 	return (tspec);
5660Sstevel@tonic-gate tabspecerr:
567*364Sceastha 	(void) fprintf(stderr, "newform: tabspec in error\n");
568*364Sceastha 	(void) fprintf(stderr,
569*364Sceastha 	    "tabspec is \t-a\t-a2\t-c\t-c2\t-c3\t-f\t-p\t-s\n");
570*364Sceastha 	(void) fprintf(stderr,
571*364Sceastha 	    "\t\t-u\t--\t--file\t-number\tnumber,..,number\n");
5720Sstevel@tonic-gate 	exit(1);
573*364Sceastha 	/* NOTREACHED */
5740Sstevel@tonic-gate }
5750Sstevel@tonic-gate 
576*364Sceastha static int
readspec(char * p)577*364Sceastha readspec(char *p)		/* Read a tabspec from a file		*/
578*364Sceastha 	/* Pointer to buffer to process */
5790Sstevel@tonic-gate {
5800Sstevel@tonic-gate 	int	state,		/* Current state			*/
5810Sstevel@tonic-gate 		firsttime,	/* Flag to indicate spec found		*/
5820Sstevel@tonic-gate 		value;		/* Function value			*/
5830Sstevel@tonic-gate 	char	c,		/* Char being looked at			*/
5840Sstevel@tonic-gate 		*tabspecp,	/* Pointer to spec string		*/
5850Sstevel@tonic-gate 		*restore = " ",	/* Character to be restored		*/
5860Sstevel@tonic-gate 		repch;		/* Character to replace with		*/
5870Sstevel@tonic-gate 
5880Sstevel@tonic-gate 	state = 0;
5890Sstevel@tonic-gate 	firsttime = 1;
5900Sstevel@tonic-gate 	while (state >= 0) {
5910Sstevel@tonic-gate 		c = *p++;
5920Sstevel@tonic-gate 		switch (state) {
5930Sstevel@tonic-gate 		case 0:
5940Sstevel@tonic-gate 			state = (c == '<') ? 1 : 0;
5950Sstevel@tonic-gate 			break;
5960Sstevel@tonic-gate 		case 1:
5970Sstevel@tonic-gate 			state = (c == ':') ? 2 : 0;
5980Sstevel@tonic-gate 			break;
5990Sstevel@tonic-gate 		case 2:
6000Sstevel@tonic-gate 			state = (c == 't') ? 4
6010Sstevel@tonic-gate 				: ((c == ' ') || (c == '\t')) ? 2 : 3;
6020Sstevel@tonic-gate 			break;
6030Sstevel@tonic-gate 		case 3:
6040Sstevel@tonic-gate 			state = ((c == ' ') || (c == '\t')) ? 2 : 3;
6050Sstevel@tonic-gate 			break;
6060Sstevel@tonic-gate 		case 4:
6070Sstevel@tonic-gate 			if (firsttime) {
6080Sstevel@tonic-gate 				tabspecp = --p;
6090Sstevel@tonic-gate 				p++;
6100Sstevel@tonic-gate 				firsttime = 0;
6110Sstevel@tonic-gate 				}
6120Sstevel@tonic-gate 			if ((c == ' ') || (c == '\t') || (c == ':')) {
6130Sstevel@tonic-gate 				repch = *(restore = p - 1);
6140Sstevel@tonic-gate 				*restore = '\0';
6150Sstevel@tonic-gate 				}
6160Sstevel@tonic-gate 			state = (c == ':') ? 6
6170Sstevel@tonic-gate 				: ((c == ' ') || (c == '\t')) ? 5 : 4;
6180Sstevel@tonic-gate 			break;
6190Sstevel@tonic-gate 		case 5:
6200Sstevel@tonic-gate 			state = (c == ':') ? 6 : 5;
6210Sstevel@tonic-gate 			break;
6220Sstevel@tonic-gate 		case 6:
6230Sstevel@tonic-gate 			state = (c == '>') ? -2 : 5;
6240Sstevel@tonic-gate 			break;
6250Sstevel@tonic-gate 			}
6260Sstevel@tonic-gate 		if (c == '\n') state = -1;
6270Sstevel@tonic-gate 		}
628*364Sceastha 	if (okludge)
629*364Sceastha 		(void) strcpy(format, tabspecp);
6300Sstevel@tonic-gate 	value = (state == -1) ? 0 : cnvtspec(tabspecp);
6310Sstevel@tonic-gate 	*restore = repch;
632*364Sceastha 	return (value);
6330Sstevel@tonic-gate }
634*364Sceastha 
635*364Sceastha static char *
readline(FILE * fp,char * area)636*364Sceastha readline(FILE *fp, char *area)		/* Read one line from the file.	*/
637*364Sceastha 	/* fp - File to read from */
638*364Sceastha 	/* area - Array of characters to read into */
6390Sstevel@tonic-gate {
6400Sstevel@tonic-gate 	int	c;		/* Current character			*/
6410Sstevel@tonic-gate 	char	*xarea,		/* Temporary pointer to character array	*/
6420Sstevel@tonic-gate 		*temp;		/* Array pointer			*/
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate /* check for existence of stdin before attempting to read 		*/
6470Sstevel@tonic-gate /* kludge refers to reading from stdin to get tabspecs for option -i--	*/
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	xarea = area;
6500Sstevel@tonic-gate 	if (kludge && (fp == stdin)) {
6510Sstevel@tonic-gate 		if (fp != NULL) {
6520Sstevel@tonic-gate 			temp = siline;
653*364Sceastha 			while ((*area++ = *temp++) != '\n')
654*364Sceastha 				;
6550Sstevel@tonic-gate 			kludge = 0;
656*364Sceastha 			return (xarea);
657*364Sceastha 		} else
658*364Sceastha 			return (NULL);
659*364Sceastha 	} else {
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate /* check for exceeding size of buffer when reading valid input */
6620Sstevel@tonic-gate 
663*364Sceastha 		while (wlast - area) {
664*364Sceastha 			switch (c = getc(fp)) {
6650Sstevel@tonic-gate 			case EOF:
6660Sstevel@tonic-gate 				if (area == xarea)
667*364Sceastha 					return (NULL);
668*364Sceastha 				/* FALLTHROUGH */
669*364Sceastha 			case '\n':	/* EOF falls through to here */
6700Sstevel@tonic-gate 				*area = '\n';
671*364Sceastha 				return (xarea);
6720Sstevel@tonic-gate 			}
673*364Sceastha 			*area = c;
674*364Sceastha 			area++;
6750Sstevel@tonic-gate 		}
676*364Sceastha 		(void) printf("newform: input line larger than buffer area \n");
6770Sstevel@tonic-gate 		exit(1);
6780Sstevel@tonic-gate 	}
679*364Sceastha 	/* NOTREACHED */
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate /* _________________________________________________________________ */
6820Sstevel@tonic-gate 
683*364Sceastha static char
type(char c)684*364Sceastha type(char c)			/* Determine type of a character	*/
685*364Sceastha 	/* Character to check */
6860Sstevel@tonic-gate {
687*364Sceastha 	return ((c >= '0') && (c <= '9') ? NUMBER : c);
6880Sstevel@tonic-gate }
689*364Sceastha 
690*364Sceastha static void
process(FILE * fp)691*364Sceastha process(FILE *fp)		/* Process one line of input		*/
692*364Sceastha 	/* File pointer for current input */
6930Sstevel@tonic-gate {
6940Sstevel@tonic-gate 	struct	f	*lp;	/* Pointer to structs			*/
6950Sstevel@tonic-gate 	char	chrnow;		/* For int to char conversion. */
6960Sstevel@tonic-gate 
697*364Sceastha 	while (readline(fp, &work[NCOLS]) != NULL) {
6980Sstevel@tonic-gate 		effll = 80;
6990Sstevel@tonic-gate 		pachar = ' ';
7000Sstevel@tonic-gate 		pfirst = plast = &work[NCOLS];
7010Sstevel@tonic-gate 		while (*plast != '\n') plast++;
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate /*	changes to line parsing includes checks for exceeding	*/
7040Sstevel@tonic-gate /*	line size when modifying text				*/
7050Sstevel@tonic-gate 
706*364Sceastha 		for (lp = optl; lp < flp; lp++) {
7070Sstevel@tonic-gate 			switch (lp->option) {
7080Sstevel@tonic-gate 			case 'a':
7090Sstevel@tonic-gate 				append(lp->param);
7100Sstevel@tonic-gate 				break;
7110Sstevel@tonic-gate 			case 'b':
7120Sstevel@tonic-gate 				if (lp->param <= (plast - pfirst))
7130Sstevel@tonic-gate 					begtrunc(lp->param);
7140Sstevel@tonic-gate 				else
715*364Sceastha 					(void) fprintf(stderr,
716*364Sceastha 					    "newform: truncate "
717*364Sceastha 					    "request larger than line, %d \n",
718*364Sceastha 					    (plast - pfirst));
7190Sstevel@tonic-gate 				break;
7200Sstevel@tonic-gate 			case 'c':
7210Sstevel@tonic-gate 				chrnow = lp->param;
7220Sstevel@tonic-gate 				pachar = chrnow ? chrnow : ' ';
7230Sstevel@tonic-gate 				break;
7240Sstevel@tonic-gate 			case 'e':
7250Sstevel@tonic-gate 				if (lp->param <= (plast - pfirst))
7260Sstevel@tonic-gate 					endtrunc(lp->param);
7270Sstevel@tonic-gate 				else
728*364Sceastha 					(void) fprintf(stderr,
729*364Sceastha 					    "newform: truncate "
730*364Sceastha 					    "request larger than line, %d \n",
731*364Sceastha 					    (plast - pfirst));
7320Sstevel@tonic-gate 				break;
7330Sstevel@tonic-gate 			case 'f':
7340Sstevel@tonic-gate 				/* Ignored */
7350Sstevel@tonic-gate 				break;
7360Sstevel@tonic-gate 			case 'i':
7370Sstevel@tonic-gate 				inputtabs(lp->param);
7380Sstevel@tonic-gate 				break;
7390Sstevel@tonic-gate 			case 'l':	/* New eff line length */
7400Sstevel@tonic-gate 				effll = lp->param ? lp->param : 72;
7410Sstevel@tonic-gate 				break;
7420Sstevel@tonic-gate 			case 's':
7430Sstevel@tonic-gate 				sstrip();
7440Sstevel@tonic-gate 				break;
7450Sstevel@tonic-gate 			case 'o':
7460Sstevel@tonic-gate 				outputtabs(lp->param);
7470Sstevel@tonic-gate 				break;
7480Sstevel@tonic-gate 			case 'p':
7490Sstevel@tonic-gate 				prepend(lp->param);
7500Sstevel@tonic-gate 				break;
7510Sstevel@tonic-gate 			}
752*364Sceastha 		}
753*364Sceastha 		if (soption) sadd();
7540Sstevel@tonic-gate 		*++plast = '\0';
755*364Sceastha 		(void) fputs(pfirst, stdout);
756*364Sceastha 	}
7570Sstevel@tonic-gate }
758*364Sceastha 
759*364Sceastha static void
append(int n)760*364Sceastha append(int n)			/* Append characters to end of line.	*/
761*364Sceastha 	/* Number of characters to append. */
7620Sstevel@tonic-gate {
7630Sstevel@tonic-gate 	if (plast - pfirst < effll) {
7640Sstevel@tonic-gate 		n = n ? n : effll - (plast - pfirst);
7650Sstevel@tonic-gate 		if (plast + n > wlast) center();
7660Sstevel@tonic-gate 		while (n--) *plast++ = pachar;
7670Sstevel@tonic-gate 		*plast = '\n';
7680Sstevel@tonic-gate 		}
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate /* _________________________________________________________________ */
7710Sstevel@tonic-gate 
772*364Sceastha static void
prepend(int n)773*364Sceastha prepend(int n)			/* Prepend characters to line.		*/
774*364Sceastha 	/* Number of characters to prepend. */
7750Sstevel@tonic-gate {
7760Sstevel@tonic-gate 	if (plast - pfirst < effll) {
7770Sstevel@tonic-gate 		n = n ? n : effll - (plast - pfirst);
7780Sstevel@tonic-gate 		if (pfirst - n < wfirst) center();
7790Sstevel@tonic-gate 		while (n--) *--pfirst = pachar;
7800Sstevel@tonic-gate 		}
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate /* _________________________________________________________________ */
7830Sstevel@tonic-gate 
784*364Sceastha static void
begtrunc(int n)785*364Sceastha begtrunc(int n)		/* Truncate characters from beginning of line.	*/
786*364Sceastha 	/* Number of characters to truncate. */
7870Sstevel@tonic-gate {
7880Sstevel@tonic-gate 	if (plast - pfirst > effll) {
7890Sstevel@tonic-gate 		n = n ? n : plast - pfirst - effll;
7900Sstevel@tonic-gate 		pfirst += n;
7910Sstevel@tonic-gate 		if (pfirst >= plast)
7920Sstevel@tonic-gate 			*(pfirst = plast = &work[NCOLS]) = '\n';
7930Sstevel@tonic-gate 		}
7940Sstevel@tonic-gate }
7950Sstevel@tonic-gate /* _________________________________________________________________ */
7960Sstevel@tonic-gate 
797*364Sceastha static void
endtrunc(int n)798*364Sceastha endtrunc(int n)			/* Truncate characters from end of line. */
799*364Sceastha 	/* Number of characters to truncate. */
8000Sstevel@tonic-gate {
8010Sstevel@tonic-gate 	if (plast - pfirst > effll) {
8020Sstevel@tonic-gate 		n = n ? n : plast - pfirst - effll;
8030Sstevel@tonic-gate 		plast -= n;
8040Sstevel@tonic-gate 		if (pfirst >= plast)
8050Sstevel@tonic-gate 			*(pfirst = plast = &work[NCOLS]) = '\n';
8060Sstevel@tonic-gate 		else
8070Sstevel@tonic-gate 			*plast = '\n';
8080Sstevel@tonic-gate 		}
8090Sstevel@tonic-gate }
810*364Sceastha 
811*364Sceastha static void
inputtabs(int p)812*364Sceastha inputtabs(int p)	/* Expand according to input tab specifications. */
813*364Sceastha 	/* Pointer to tab specification. */
8140Sstevel@tonic-gate {
8150Sstevel@tonic-gate 	int	*tabs;		/* Pointer to tabs			*/
8160Sstevel@tonic-gate 	char	*tfirst,	/* Pointer to new buffer start		*/
8170Sstevel@tonic-gate 		*tlast;		/* Pointer to new buffer end		*/
818*364Sceastha 	char	c;		/* Character being scanned		*/
8190Sstevel@tonic-gate 	int	logcol;		/* Logical column			*/
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate 	tabs = spectbl[p];
8220Sstevel@tonic-gate 	tfirst = tlast = work;
8230Sstevel@tonic-gate 	logcol = 1;
8240Sstevel@tonic-gate 	center();
8250Sstevel@tonic-gate 	while (pfirst <= plast) {
8260Sstevel@tonic-gate 		if (logcol >= *tabs) tabs++;
8270Sstevel@tonic-gate 		switch (c = *pfirst++) {
8280Sstevel@tonic-gate 		case '\b':
8290Sstevel@tonic-gate 			if (logcol > 1) logcol--;
8300Sstevel@tonic-gate 			*tlast++ = c;
8310Sstevel@tonic-gate 			if (logcol < *tabs) tabs--;
8320Sstevel@tonic-gate 			break;
8330Sstevel@tonic-gate 		case '\t':
8340Sstevel@tonic-gate 			while (logcol < *tabs) {
8350Sstevel@tonic-gate 				*tlast++ = ' ';
8360Sstevel@tonic-gate 				logcol++;
8370Sstevel@tonic-gate 				}
8380Sstevel@tonic-gate 			tabs++;
8390Sstevel@tonic-gate 			break;
8400Sstevel@tonic-gate 		default:
8410Sstevel@tonic-gate 			*tlast++ = c;
8420Sstevel@tonic-gate 			logcol++;
8430Sstevel@tonic-gate 			break;
8440Sstevel@tonic-gate 			}
8450Sstevel@tonic-gate 		}
8460Sstevel@tonic-gate 	pfirst = tfirst;
8470Sstevel@tonic-gate 	plast = --tlast;
8480Sstevel@tonic-gate }
849*364Sceastha /*
850*364Sceastha  * Add SCCS SID (generated by a "get -m" command) to the end of each line.
851*364Sceastha  * Sequence is as follows for EACH line:
852*364Sceastha  *	Check for at least 1 tab.  Err if none.
853*364Sceastha  *	Strip off all char up to & including first tab.
854*364Sceastha  *	If more than 8 char were stripped, the 8 th is replaced by
855*364Sceastha  *		a '*' & the remainder are discarded.
856*364Sceastha  *	Unless user specified an "a", append blanks to fill
857*364Sceastha  *		out line to eff. line length (default= 72 char).
858*364Sceastha  *	Truncate lines > eff. line length (default=72).
859*364Sceastha  *	Add stripped char to end of line.
860*364Sceastha  */
861*364Sceastha static void
sstrip(void)862*364Sceastha sstrip(void)
8630Sstevel@tonic-gate {
864*364Sceastha 	int i, k;
865*364Sceastha 	char *c, *savec;
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 	k = -1;
8680Sstevel@tonic-gate 	c = pfirst;
869*364Sceastha 	while (*c != '\t' && *c != '\n') {
870*364Sceastha 		k++;
871*364Sceastha 		c++;
872*364Sceastha 	}
873*364Sceastha 	if (*c != '\t') {
874*364Sceastha 		(void) fprintf(stderr, "not -s format\r\n");
875*364Sceastha 		exit(1);
876*364Sceastha 	}
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	savec = c;
8790Sstevel@tonic-gate 	c = pfirst;
8800Sstevel@tonic-gate 	savek = (k > 7) ? 7 : k;
881*364Sceastha 	for (i = 0; i <= savek; i++) savchr[i] = *c++;	/* Tab not saved */
882*364Sceastha 	if (k > 7) savchr[7] = '*';
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	pfirst = ++savec;		/* Point pfirst to char after tab */
8850Sstevel@tonic-gate }
8860Sstevel@tonic-gate /* ================================================================= */
8870Sstevel@tonic-gate 
888*364Sceastha static void
sadd(void)889*364Sceastha sadd(void)
8900Sstevel@tonic-gate {
891*364Sceastha 	int i;
8920Sstevel@tonic-gate 
893*364Sceastha 	for (i = 0; i <= savek; i++) *plast++ = savchr[i];
8940Sstevel@tonic-gate 	*plast = '\n';
8950Sstevel@tonic-gate }
896*364Sceastha 
897*364Sceastha static void
outputtabs(int p)898*364Sceastha outputtabs(int p)	/* Contract according to output tab specifications. */
899*364Sceastha 	/* Pointer to tab specification. */
9000Sstevel@tonic-gate {
9010Sstevel@tonic-gate 	int	*tabs;		/* Pointer to tabs			*/
9020Sstevel@tonic-gate 	char	*tfirst,	/* Pointer to new buffer start		*/
9030Sstevel@tonic-gate 		*tlast,		/* Pointer to new buffer end		*/
9040Sstevel@tonic-gate 		*mark;		/* Marker pointer			*/
905*364Sceastha 	char c;			/* Character being scanned		*/
9060Sstevel@tonic-gate 	int	logcol;		/* Logical column			*/
9070Sstevel@tonic-gate 
9080Sstevel@tonic-gate 	tabs = spectbl[p];
9090Sstevel@tonic-gate 	tfirst = tlast = pfirst;
9100Sstevel@tonic-gate 	logcol = 1;
9110Sstevel@tonic-gate 	while (pfirst <= plast) {
9120Sstevel@tonic-gate 		if (logcol == *tabs) tabs++;
9130Sstevel@tonic-gate 		switch (c = *pfirst++) {
9140Sstevel@tonic-gate 		case '\b':
9150Sstevel@tonic-gate 			if (logcol > 1) logcol--;
9160Sstevel@tonic-gate 			*tlast++ = c;
9170Sstevel@tonic-gate 			if (logcol < *tabs) tabs--;
9180Sstevel@tonic-gate 			break;
9190Sstevel@tonic-gate 		case ' ':
9200Sstevel@tonic-gate 			mark = tlast;
9210Sstevel@tonic-gate 			do {
9220Sstevel@tonic-gate 				*tlast++ = ' ';
9230Sstevel@tonic-gate 				logcol++;
9240Sstevel@tonic-gate 				if (logcol == *tabs) {
9250Sstevel@tonic-gate 					*mark++ = '\t';
9260Sstevel@tonic-gate 					tlast = mark;
9270Sstevel@tonic-gate 					tabs++;
9280Sstevel@tonic-gate 					}
9290Sstevel@tonic-gate 				} while (*pfirst++ == ' ');
9300Sstevel@tonic-gate 			pfirst--;
9310Sstevel@tonic-gate 			break;
9320Sstevel@tonic-gate 		default:
9330Sstevel@tonic-gate 			logcol++;
9340Sstevel@tonic-gate 			*tlast++ = c;
9350Sstevel@tonic-gate 			break;
9360Sstevel@tonic-gate 			}
9370Sstevel@tonic-gate 		}
9380Sstevel@tonic-gate 	pfirst = tfirst;
9390Sstevel@tonic-gate 	plast = --tlast;
9400Sstevel@tonic-gate }
941