[net.sources] Source for format.c

dhb (04/21/83)

#include <stdio.h>

char	*format_sccsid	= "@(#) format.c: version 1.6";
char	*format_rayssd	= "@(#) format.c: Raytheon Submarine Signal Division";
char	*format_author	= "@(#) format.c: written by David H. Brierley";

/* In the following structure, type has the following meanings:
	1  = mm macros
	2  = ms macros
	3  = me macros
	4  = man macros
	10 = eqn
	11 = tbl
	20 = .so
	21 = .de
*/
struct	s_tbl	{
	char	macro[20];
	int	type;
};

/* the following strings are defined extermely large so that no matter	*/
/* how many arguments this program is given it will never blow up.	*/
char	buffer[4096];
char	macros[20]	= "";
char	nrflags[4096]	= "";
char	files[4096]	= "";
char	command[8192];
char	tmp_holdfile[100];
char	*index();

int	flags		= 0;
#define EQN	001
#define TBL	002
#define COL	004
#define VU	010

int	m_flags		= 0;
int	M_flags		= 0;
#define MM	002
#define MS	004
#define ME	010
#define MAN	020

int	fd_infile;
int	fd_stdin;
int	fd_holdfile;
int	check_flag	= 0;
int	src_flag	= 0;
int	file_count	= 0;
int	i,j,k,l,m,n;

/* The first macro entry in the following table MUST be in the	*/
/* position defined by FIRSTMAC.  The beginning entries are	*/
/* reserved for .so, the tbl macros, and the eqn macros.	*/
#define FIRSTMAC	6
struct	s_tbl	srch_table[]	=	{
	".EQ", 10,
	".EN", 10,
	".TS", 11,
	".TE", 11,
	".so", 20,
	".de", 21,
	".AF",	1,
	".AL",	1,
	".AS",	1,
	".BL",	1,
	".DF",	1,
	".DL",	1,
	".EC",	1,
	".EF",	1,
	".EH",	1,
	".FD",	1,
	".FG",	1,
	".H",	1,
	".HC",	1,
	".HM",	1,
	".HU",	1,
	".HX",	1,
	".HZ",	1,
	".LB",	1,
	".LC",	1,
	".LE",	1,
	".LI",	1,
	".ML",	1,
	".MT",	1,
	".NE",	1,
	".NS",	1,
	".OF",	1,
	".OH",	1,
	".P",	1,
	".PF",	1,
	".PH",	1,
	".PX",	1,
	".RL",	1,
	".SA",	1,
	".SK",	1,
	".SP",	1,
	".TB",	1,
	".TC",	1,
	".TX",	1,
	".VL",	1,
	".AB",	2,
	".AI",	2,
	".AT",	2,
	".B1",	2,
	".B2",	2,
	".BT",	2,
	".BX",	2,
	".CT",	2,
	".DA",	2,
	".EG",	2,
	".HO",	2,
	".IH",	2,
	".IM",	2,
	".KE",	2,
	".KF",	2,
	".KS",	2,
	".LG",	2,
	".MF",	2,
	".MH",	2,
	".MR",	2,
	".NH",	2,
	".NL",	2,
	".PT",	2,
	".PY",	2,
	".QE",	2,
	".QP",	2,
	".QS",	2,
	".RP",	2,
	".TR",	2,
	".UL",	2,
	".UX",	2,
	".WH",	2,
	".(c",	3,
	".(d",	3,
	".(f",	3,
	".(l",	3,
	".(q",	3,
	".(x",	3,
	".(z",	3,
	".)C",	3,
	".)d",	3,
	".)f",	3,
	".)l",	3,
	".)q",	3,
	".)x",	3,
	".)z",	3,
	".++",	3,
	".+c",	3,
	".1c",	3,
	".2c",	3,
	".ac",	3,
	".b",	3,
	".ba",	3,
	".bc",	3,
	".bi",	3,
	".bx",	3,
	".ef",	3,
	".eh",	3,
	".fo",	3,
	".hx",	3,
	".he",	3,
	".hl",	3,
	".i",	3,
	".ip",	3,
	".lp",	3,
	".lo",	3,
	".np",	3,
	".of",	3,
	".oh",	3,
	".pd",	3,
	".pp",	3,
	".r",	3,
	".re",	3,
	".sc",	3,
	".sh",	3,
	".sk",	3,
	".sz",	3,
	".th",	3,
	".tp",	3,
	".u",	3,
	".uh",	3,
	".xp",	3,
	".BI",	4,
	".BR",	4,
	".DT",	4,
	".HP",	4,
	".IB",	4,
	".IR",	4,
	".PD",	4,
	".RB",	4,
	".RI",	4,
	"END",	0
};

main(argc,argv)
int	argc;
char	*argv[];
{

	if ( (strlen(argv[1]) == 2) && (strcmp(argv[1],"--") == 0) ) {
		check_flag = 1;
		argv++;
		argc--;
	}
	else	{
		sprintf(tmp_holdfile,"/tmp/FORMAT%d",getpid());
		if ((fd_holdfile = creat(tmp_holdfile,0666)) == -1) {
			fprintf(stderr,"Unable to create hold file\n");
			exit(1);
		}
	}

	while(argc > 1) {
		if (check_flag) {
			flags = 0;
			m_flags = 0;
			M_flags = 0;
		}
		if (argv[1][0] == '-' && strlen(argv[1]) > 1) {
			if (strlen(argv[1]) == 2) {
				switch(argv[1][1]) {
				case 'v':
					flags |= VU;
					break;
				case 'c':
					flags |= COL;
					break;
				default:
					if (!check_flag) {
						strcat(nrflags,argv[1]);
						strcat(nrflags," ");
					}
					break;
				}
			}
			else	{
				if (!check_flag) {
				strcat(nrflags,argv[1]);
				strcat(nrflags," ");
				}
			}
			argv++;
			argc--;
			continue;
		}
		find_pak(argv[1]);
		argv++;
		argc--;
	}
	if (check_flag) {
		exit(0);
	}

	dumpout(NULL);
	close(fd_holdfile);
	command[0] = '\0';
	if (flags & EQN) {
		strcat(command,"neqn ");
		strcat(command,tmp_holdfile);
		strcat(command," | ");
	}
	if (flags & TBL) {
		strcat(command,"tbl ");
		if ( !(flags & EQN) ) {
			strcat(command,tmp_holdfile);
		}
		strcat(command," | ");
	}
	strcat(command,"nroff ");
	strcat(command,macros);
	strcat(command," ");
	strcat(command,nrflags);
	if ( !(flags & (TBL | EQN)) ) {
		strcat(command,tmp_holdfile);
	}
	else	{
		strcat(command," -");
	}
	if (flags & COL) {
		strcat(command," | col");
	}
	if (flags & VU) {
		strcat(command," | vu");
	}

	system(command);
	unlink(tmp_holdfile);
}

search(filename)
char	*filename;
{
	struct	s_tbl	*table;
	char		*ptr, *ptr2;
	char		source[512];
	int		save_flag;
	int		save_mflg;

	if (strlen(buffer) < 2) {
		dumpout(buffer);
		return;
	}

	for (table = srch_table; table->type != 0; table++) {
		if (strlen(buffer) < strlen(table->macro)) continue;
		if (strncmp(table->macro,buffer,strlen(table->macro)) != 0)
			continue;
		if (strlen(table->macro) != strlen(buffer))
			if (buffer[strlen(table->macro)] != ' ') continue;
		switch(table->type) {

		case 1:
			dumpout(buffer);
			if (check_flag) double_check("-mm",filename);
			else strcpy(macros,"-mm");
			m_flags |= MM;
			if (!check_flag) srch_table[FIRSTMAC].type = 0;
			return;

		case 2:
			dumpout(buffer);
			if (check_flag) double_check("-ms",filename);
			else strcpy(macros,"-ms");
			m_flags |= MS;
			if (!check_flag) srch_table[FIRSTMAC].type = 0;
			return;

		case 3:
			dumpout(buffer);
			if (check_flag) double_check("-me",filename);
			else strcpy(macros,"-me");
			m_flags |= ME;
			if (!check_flag) srch_table[FIRSTMAC].type = 0;
			return;

		case 4:
			dumpout(buffer);
			if (check_flag) double_check("-man",filename);
			else strcpy(macros,"-man");
			m_flags |= MAN;
			if (!check_flag) srch_table[FIRSTMAC].type = 0;
			return;

		case 10:
			dumpout(buffer);
			flags |= EQN;
			return;

		case 11:
			dumpout(buffer);
			flags |= TBL;
			return;

		case 20:
			if ((ptr = index(buffer,' ')) == NULL) return;
			while(*ptr == ' ') ptr++;
			if ((ptr2 = index(ptr,' ')) != NULL) *ptr2 = '\0';
			strcpy(source,ptr);
			if (check_flag) {
				save_flag = flags;
				save_mflg = m_flags;
				src_flag++;
				flags = 0;
				m_flags = 0;
			}
			find_pak(source);
			if (check_flag) {
				M_flags |= m_flags;
				flags = save_flag;
				m_flags = save_mflg;
				src_flag--;
				if (src_flag == 0) m_flags |= M_flags;
			}
			return;

		case 21:
			dumpout(buffer);
			if ((ptr = index(buffer,' ')) == NULL) return;
			while(*ptr == ' ') ptr++;
			if ((ptr2 = index(ptr,' ')) != NULL) *ptr2 = '\0';
			for (table = srch_table; table->type!=0; table++) {
				if (strcmp(ptr,table->macro+1) == 0) {
					*(table->macro) = '+';
					return;
				}
			}
			return;

		default:
			break;
		}
	}
	dumpout(buffer);
}

/*----------------------------------------------------------------------*
 *									*
 * title: getline							*
 *									*
 * function:								*
 *	To read a line from a specified file descriptor.		*
 *									*
 * method of operation:							*
 *	The specified input is read until a carriage return is detected	*
 *	and passed back to the calling routine.				*
 *	If the file descriptor is not 0 (standard input), the		*
 *	file is read blocked, otherwise it is read unblocked.		*
 *									*
 *----------------------------------------------------------------------*/

#define BUFFSIZE 4096
#define BUFCOUNT 30

getline(fd,line)
int	fd;
register char	*line;
{

	static	char	*buffer[BUFCOUNT];
	static	int	buf_pos[BUFCOUNT];
	static	int	buf_size[BUFCOUNT];
	static	int	buf_max[BUFCOUNT];
	static	int	init_flag = 1;
	register int	i;
	register char	*Buffer;
	register int	Bufpos;
	register int	*Bufsize;

	if (init_flag){
		for (i=0; i<BUFCOUNT; i++){
			buffer[i] = NULL;
			buf_pos[i] = BUFFSIZE;
			buf_size[i] = BUFFSIZE;
		}
		init_flag = 0;
	}

	if (fd >= BUFCOUNT){
		printf("getline: file descriptor greater than max, fd=%d\n",fd);
		exit(1);
	}

	if (buffer[fd] == NULL){
		if (fd == 0) buf_max[fd] = 1;
		else buf_max[fd] = BUFFSIZE;
		if ((buffer[fd] = (char *)malloc(buf_max[fd])) == NULL){
			printf("getline: unable to allocate buffer space, ");
			printf("fd = %d\n",fd);
			perror("getline");
			exit(1);
		}
	}


	i = 0;
	Bufpos = buf_pos[fd];
	Bufsize = &buf_size[fd];
	if (Bufpos < *Bufsize)
		Buffer = &buffer[fd][Bufpos];

	while ( 1 ){
		if (Bufpos >= *Bufsize){
			*Bufsize = read(fd,buffer[fd],buf_max[fd]);
			Bufpos = 0;
			Buffer = buffer[fd];
			if (*Bufsize == 0) break;
		}

		if (*Buffer == '\n') break;
		*line = *Buffer++;
		Bufpos++;
		line++;
		i++;

	}

	*line = '\0';
	if ((i == 0) && (*Bufsize == 0) && (Bufpos == 0)) i = -1;
	buf_pos[fd] = ++Bufpos;

	return(i);

}

print_info(filename)
char	*filename;
{
	int	i;

	if (src_flag) printf("Sourced file ");
	else printf("File ");

	printf("%s requires ",
		(filename[0] == '-') ? "STANDARD INPUT" : filename);

	if (flags & TBL) {
		printf("tbl, ");
	}

	if (flags & EQN) {
		printf("eqn, ");
	}

	i = 0;
	if (m_flags & MM) {
		strcpy(macros,"-mm");
		i++;
	}
	if (m_flags & MS) {
		strcpy(macros,"-ms");
		i++;
	}
	if (m_flags & ME) {
		strcpy(macros,"-me");
		i++;
	}
	if (m_flags & MAN) {
		strcpy(macros,"-man");
		i++;
	}

	if (i == 0) {
		printf("unknown (or no) macro package\n");
	}
	else	{
		printf("%s macro package\n",macros);
	}

	if (i > 1) {
		printf("ERROR: file \"%s\" uses multiple macro packages:",
			(filename[0] == '-') ? "STANDARD INPUT" : filename);
		if (m_flags & MM) printf(" -mm");
		if (m_flags & MS) printf(" -ms");
		if (m_flags & ME) printf(" -me");
		if (m_flags & MAN) printf(" -man");
		printf("\n");
	}

	fflush(stdout);

}

double_check(package,filename)
char	*package;
char	*filename;
{

	if (macros[0] == '\0') return;

	if (strlen(package) == strlen(macros)
	    && strcmp(package,macros) == 0)
		return;

	printf("ERROR: file \"%s\" conflicts with previous files\n",
		(filename[0] == '-') ? "STANDARD INPUT" : filename);
	printf("previous files used the %s macro package and\n",macros);
	printf("file \"%s\" uses the %s macro package\n",
		(filename[0] == '-') ? "STANDARD INPUT" : filename,package);

}

find_pak(filename)
char	*filename;
{
	int	fd_infile;

	if (filename[0] == '-'){
		fd_infile = 0;
	}
	else	{
		if ((fd_infile = open(filename,0)) == -1) {
			printf("Unable to open file %s\n",filename);
			perror("format");
			return;
		}
	}
	while(getline(fd_infile,buffer) != -1) {
		if (buffer[0] != '.') {
			dumpout(buffer);
			continue;
		}
		search(filename);
	}
	close(fd_infile);
	if (check_flag) print_info(filename);
}

dumpout(buffer)
char	*buffer;
{

	static	char	dumpbuff[8192];
	static	int	buffpos = 0;
	register int	n;
	register int	size	= buffpos;

	if (check_flag) return;

	if (buffer == NULL) {
		write(fd_holdfile,dumpbuff,buffpos);
		buffpos = 0;
		return;
	}
	n = strlen(buffer);
	strcpy(dumpbuff+size,buffer);
	dumpbuff[size + (n++)] = '\n';
	dumpbuff[size + n] = '\0';

	if ((size += n) > 4096) {
		write(fd_holdfile,dumpbuff,4096);
		strcpy(dumpbuff,dumpbuff+4096);
		size -= 4096;
	}
	buffpos = size;

}