xref: /csrg-svn/usr.bin/indent/indent.c (revision 30984)
121968Sdist /*
221968Sdist  * Copyright (c) 1980 Regents of the University of California.
321968Sdist  * All rights reserved.  The Berkeley software License Agreement
421968Sdist  * specifies the terms and conditions for redistribution.
521968Sdist  */
68800Smckusick 
721968Sdist #ifndef lint
821968Sdist char copyright[] =
921968Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1021968Sdist  All rights reserved.\n";
1121968Sdist #endif not lint
1221968Sdist 
1321968Sdist #ifndef lint
14*30984Sbostic static char sccsid[] = "@(#)indent.c	5.5 (Berkeley) 04/29/87";
1521968Sdist #endif not lint
1621968Sdist 
1724453Smckusick /*-
1824453Smckusick 
1924453Smckusick 	Copyright (C) 1976
2024453Smckusick 		by the
2124453Smckusick 	Board of Trustees
2224453Smckusick 		of the
2324453Smckusick 	University of Illinois
2424453Smckusick 
2524453Smckusick 	All rights reserved
2624453Smckusick 
2724453Smckusick 
288800Smckusick NAME:
2924453Smckusick indent main program
3024453Smckusick 
318800Smckusick FUNCTION:
3224453Smckusick This is the main program of the indent program.  Indent will take a C
3324453Smckusick program source and reformat it into a semi-reasonable form.
3424453Smckusick 
358800Smckusick ALGORITHM:
3624453Smckusick The routine lexi scans tokens and passes them back one at a time to the
3724453Smckusick main routine.  The subroutine parse takes care of much of the work of
3824453Smckusick figuring indentation level.
3924453Smckusick 
4024453Smckusick 1) Call lexi
4124453Smckusick 2) Enter a monster switch statement on the code returned by lexi.  If
4224453Smckusick the indentation level for the line yet to be printed should be
4324453Smckusick changed, set the variable ps.ind_level.  If the indentation level for
4424453Smckusick the following line should be changed, set the variable ps.i_l_follow.
458800Smckusick 
4624453Smckusick */
478800Smckusick #include "indent_globs.h";
488800Smckusick #include "indent_codes.h";
498800Smckusick 
5024453Smckusick char       *in_name = "Standard Input";	/* will always point to name of
5124453Smckusick 					 * input file */
5224453Smckusick char       *out_name = "Standard Output";	/* will always point to
5324453Smckusick 						 * name of output file */
5424453Smckusick char        bakfile[32] = "";
558800Smckusick 
5624453Smckusick main(argc, argv)
5724453Smckusick     int         argc;
5824453Smckusick     char      **argv;
598800Smckusick {
60*30984Sbostic     extern int	found_err;	/* if any error occurred */
618800Smckusick 
6224453Smckusick     int         dec_ind;	/* current indentation for declarations */
6324453Smckusick     int         di_stack[20];	/* a stack of structure indentation levels */
6424453Smckusick     int         flushed_nl;	/* used when buffering up comments to
6524453Smckusick 				 * remember that a newline was passed over */
6624453Smckusick     int         force_nl;	/* when true, code must be broken */
6724453Smckusick     int         hd_type;	/* used to store type of stmt for if
6824453Smckusick 				 * (...), for (...), etc */
6924453Smckusick     register int i;		/* local loop counter */
7024453Smckusick     register int j;		/* local loop counter */
7124453Smckusick     int         scase;		/* set to true when we see a case, so we
7224453Smckusick 				 * will know what to do with the following
7324453Smckusick 				 * colon */
7424453Smckusick     int         sp_sw;		/* when true, we are in the expressin of
7524453Smckusick 				 * if(...), while(...), etc. */
7624453Smckusick     int         squest;		/* when this is positive, we have seen a ?
7724453Smckusick 				 * without the matching : in a <c>?<s>:<s>
7824453Smckusick 				 * construct */
7924453Smckusick     register char *t_ptr;	/* used for copying tokens */
8024453Smckusick     int         type_code;	/* the type of token, returned by lexi */
818800Smckusick 
8224453Smckusick     int         last_else = 0;	/* true iff last keyword was an else */
838800Smckusick 
848800Smckusick 
8524453Smckusick     /*-----------------------------------------------*\
8624648Smckusick     |		      INITIALIZATION		      |
8724648Smckusick     \*-----------------------------------------------*/
888800Smckusick 
898800Smckusick 
9024453Smckusick     ps.p_stack[0] = stmt;	/* this is the parser's stack */
9124453Smckusick     ps.last_nl = true;		/* this is true if the last thing scanned
9224453Smckusick 				 * was a newline */
9324453Smckusick     ps.last_token = semicolon;
9424453Smckusick     combuf[0] = codebuf[0] = labbuf[0] = ' ';	/* set up code, label, and
9524453Smckusick 						 * comment buffers */
968800Smckusick     combuf[1] = codebuf[1] = labbuf[1] = '\0';
978800Smckusick     s_lab = e_lab = labbuf + 1;
988800Smckusick     s_code = e_code = codebuf + 1;
998800Smckusick     s_com = e_com = combuf + 1;
1008800Smckusick 
1018800Smckusick     buf_ptr = buf_end = in_buffer;
1028800Smckusick     line_no = 1;
10324453Smckusick     had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
1048800Smckusick     sp_sw = force_nl = false;
10524453Smckusick     ps.in_or_st = false;
10624453Smckusick     ps.bl_line = true;
1078800Smckusick     dec_ind = 0;
10824453Smckusick     di_stack[ps.dec_nest = 0] = 0;
10924453Smckusick     ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
1108800Smckusick 
1118800Smckusick 
11224453Smckusick     scase = ps.pcase = false;
1138800Smckusick     squest = 0;
1148800Smckusick     sc_end = 0;
1158800Smckusick     bp_save = 0;
1168800Smckusick     be_save = 0;
1178800Smckusick 
11824453Smckusick     output = 0;
1198800Smckusick 
1208800Smckusick 
1218800Smckusick 
12224453Smckusick     /*--------------------------------------------------*\
12324648Smckusick     |   COMMAND LINE SCAN
12424648Smckusick     \*--------------------------------------------------*/
1258800Smckusick 
12624648Smckusick     set_defaults();
1278800Smckusick 
12824648Smckusick     /*
12924648Smckusick      * Unfortunately, we must look for -npro here because the profiles
13024648Smckusick      * are read before the command line arguments.
13124648Smckusick      */
13224453Smckusick     for (i = 1; i < argc; ++i)
13324453Smckusick 	if (strcmp(argv[i], "-npro") == 0)
13424453Smckusick 	    break;
13524453Smckusick     if (i >= argc)
13624453Smckusick 	set_profile();
1378800Smckusick 
13824648Smckusick     input = 0;			/* cancel -st if it was in the profiles, */
13924648Smckusick     output = 0;			/* as it doesn't make any sense there. */
14024648Smckusick 
1418800Smckusick     for (i = 1; i < argc; ++i) {
14224453Smckusick 
14324453Smckusick 	/*
14424453Smckusick 	 * look thru args (if any) for changes to defaults
14524453Smckusick 	 */
1468800Smckusick 	if (argv[i][0] != '-') {/* no flag on parameter */
14724453Smckusick 	    if (input == 0) {	/* we must have the input file */
14824453Smckusick 		in_name = argv[i];	/* remember name of input file */
14924453Smckusick 		input = fopen(in_name, "r");
15024453Smckusick 		if (input == 0) {	/* check for open error */
15124648Smckusick 		    fprintf(stderr, "indent: can't open %s\n", argv[i]);
15224648Smckusick 		    exit(1);
1538800Smckusick 		}
1548800Smckusick 		continue;
15524453Smckusick 	    } else if (output == 0) {	/* we have the output file */
15624453Smckusick 		out_name = argv[i];	/* remember name of output file */
15724453Smckusick 		if (strcmp(in_name, out_name) == 0) {	/* attempt to overwrite
15824453Smckusick 							 * the file */
15924648Smckusick 		    fprintf(stderr, "indent: input and output files must be different\n");
16024648Smckusick 		    exit(1);
16124453Smckusick 		}
16224453Smckusick 		output = fopen(out_name, "w");
16324453Smckusick 		if (output == 0) {	/* check for create error */
16424648Smckusick 		    fprintf(stderr, "indent: can't create %s\n", argv[i]);
16524648Smckusick 		    exit(1);
16624453Smckusick 		}
16724453Smckusick 		continue;
1688800Smckusick 	    }
16924648Smckusick 	    fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]);
17024648Smckusick 	    exit(1);
17124453Smckusick 	} else
17224453Smckusick 	    set_option(argv[i]);
1738800Smckusick 
17424453Smckusick     }				/* end of for */
17524453Smckusick     if (input == 0) {
17624453Smckusick 	printf("Usage: indent file [ outfile ] [ options ]\n");
17724648Smckusick 	exit(1);
17824453Smckusick     }
17924453Smckusick     if (output == 0)
18024453Smckusick 	if (troff)
18124453Smckusick 	    output = stdout;
18224453Smckusick 	else {
18324453Smckusick 	    out_name = in_name;
18424453Smckusick 	    bakcopy();
1858800Smckusick 	}
18624648Smckusick 
18724648Smckusick     /*
18824648Smckusick      * Adjust parameters that are out of range, or set defaults if
18924648Smckusick      * no values were specified.
19024648Smckusick      */
19124453Smckusick     if (ps.com_ind <= 1)
19224453Smckusick 	ps.com_ind = 2;		/* dont put normal comments before column
19324453Smckusick 				 * 2 */
19424453Smckusick     if (block_comment_max_col <= 0)
19524453Smckusick 	block_comment_max_col = max_col;
19624453Smckusick     if (ps.decl_com_ind <= 0)	/* if not specified by user, set this */
19724648Smckusick 	ps.decl_com_ind = ps.ljust_decl ? ps.com_ind - 8 : ps.com_ind;
19824648Smckusick     if (ps.decl_com_ind <= 1)
19924648Smckusick 	ps.decl_com_ind = 2;
20024453Smckusick     if (continuation_indent == 0)
20124453Smckusick 	continuation_indent = ps.ind_size;
20224453Smckusick     fill_buffer();		/* get first batch of stuff into input
20324453Smckusick 				 * buffer */
2048800Smckusick 
20524453Smckusick     parse(semicolon);
20624453Smckusick     {
20724453Smckusick 	register char *p = buf_ptr;
20824453Smckusick 	register    col = 1;
2098800Smckusick 
21024453Smckusick 	while (1) {
21124453Smckusick 	    if (*p == ' ')
21224453Smckusick 		col++;
21324453Smckusick 	    else if (*p == '\t')
21424453Smckusick 		col = ((col - 1) & ~7) + 9;
21524453Smckusick 	    else
21624453Smckusick 		break;
21724453Smckusick 	    p++;
21824453Smckusick 	};
21924453Smckusick 	if (col > ps.ind_size)
22024453Smckusick 	    ps.ind_level = ps.i_l_follow = col / ps.ind_size;
2218800Smckusick     }
22224453Smckusick     if (troff) {
22324453Smckusick 	register char *p = in_name,
22424453Smckusick 	           *beg = in_name;
22524453Smckusick 
22624453Smckusick 	while (*p)
22724453Smckusick 	    if (*p++ == '/')
22824453Smckusick 		beg = p;
22924453Smckusick 	fprintf(output, ".Fn \"%s\"\n", beg);
2308800Smckusick     }
2318800Smckusick 
23224453Smckusick     /*
23324453Smckusick      * START OF MAIN LOOP
23424453Smckusick      */
2358800Smckusick 
23624453Smckusick     while (1) {			/* this is the main loop.  it will go
23724453Smckusick 				 * until we reach eof */
23824453Smckusick 	int         is_procname;
2398800Smckusick 
24024453Smckusick 	type_code = lexi();	/* lexi reads one token.  The actual
24124453Smckusick 				 * characters read are stored in "token".
24224453Smckusick 				 * lexi returns a code indicating the type
24324453Smckusick 				 * of token */
24424453Smckusick 	is_procname = ps.procname[0];
2458800Smckusick 
24624453Smckusick 	/*
24724453Smckusick 	 * The following code moves everything following an if (), while
24824453Smckusick 	 * (), else, etc. up to the start of the following stmt to a
24924453Smckusick 	 * buffer.  This allows proper handling of both kinds of brace
25024453Smckusick 	 * placement.
25124453Smckusick 	 */
2528800Smckusick 
2538800Smckusick 	flushed_nl = false;
25424453Smckusick 	while (ps.search_brace) {	/* if we scanned an if(), while(),
25524453Smckusick 					 * etc., we might need to copy
25624453Smckusick 					 * stuff into a buffer we must
25724453Smckusick 					 * loop, copying stuff into
25824453Smckusick 					 * save_com, until we find the
25924453Smckusick 					 * start of the stmt which follows
26024453Smckusick 					 * the if, or whatever */
2618800Smckusick 	    switch (type_code) {
26224453Smckusick 		case newline:
2638800Smckusick 		    ++line_no;
2648800Smckusick 		    flushed_nl = true;
26524453Smckusick 		case form_feed:
26624453Smckusick 		    break;	/* form feeds and newlines found here will
26724453Smckusick 				 * be ignored */
2688800Smckusick 
26924453Smckusick 		case lbrace:	/* this is a brace that starts the
27024453Smckusick 				 * compound stmt */
27124453Smckusick 		    if (sc_end == 0) {	/* ignore buffering if a comment
27224453Smckusick 					 * wasnt stored up */
27324453Smckusick 			ps.search_brace = false;
2748800Smckusick 			goto check_type;
2758800Smckusick 		    }
2768800Smckusick 		    if (btype_2) {
27724453Smckusick 			save_com[0] = '{';	/* we either want to put
27824453Smckusick 						 * the brace right after
27924453Smckusick 						 * the if */
28024453Smckusick 			goto sw_buffer;	/* go to common code to get out of
28124453Smckusick 					 * this loop */
2828800Smckusick 		    }
28324453Smckusick 		case comment:	/* we have a comment, so we must copy it
28424453Smckusick 				 * into the buffer */
28524453Smckusick 		    if (!flushed_nl) {
28624453Smckusick 			if (sc_end == 0) {	/* if this is the first
28724453Smckusick 						 * comment, we must set up
28824453Smckusick 						 * the buffer */
28924453Smckusick 			    save_com[0] = save_com[1] = ' ';
29024453Smckusick 			    sc_end = &(save_com[2]);
29124453Smckusick 			} else {
29224453Smckusick 			    *sc_end++ = '\n';	/* add newline between
29324453Smckusick 						 * comments */
29424453Smckusick 			    *sc_end++ = ' ';
29524453Smckusick 			    --line_no;
29624453Smckusick 			}
29724453Smckusick 			*sc_end++ = '/';	/* copy in start of
29824453Smckusick 						 * comment */
29924453Smckusick 			*sc_end++ = '*';
3008800Smckusick 
30124453Smckusick 			for (;;) {	/* loop until we get to the end of
30224453Smckusick 					 * the comment */
30324453Smckusick 			    *sc_end = *buf_ptr++;
30424453Smckusick 			    if (buf_ptr >= buf_end)
30524453Smckusick 				fill_buffer();
30624453Smckusick 
30724453Smckusick 			    if (*sc_end++ == '*' && *buf_ptr == '/')
30824453Smckusick 				break;	/* we are at end of comment */
30924453Smckusick 
31024453Smckusick 			    if (sc_end >= &(save_com[sc_size])) {	/* check for temp buffer
31124453Smckusick 									 * overflow */
31224453Smckusick 				diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
31324453Smckusick 				fflush(output);
31424648Smckusick 				exit(1);
31524453Smckusick 			    }
31624453Smckusick 			}
31724453Smckusick 			*sc_end++ = '/';	/* add ending slash */
31824453Smckusick 			if (++buf_ptr >= buf_end)	/* get past / in buffer */
31924453Smckusick 			    fill_buffer();
32024453Smckusick 			break;
32124453Smckusick 		    }
32224453Smckusick 		default:	/* it is the start of a normal statment */
32324453Smckusick 		    if (flushed_nl)	/* if we flushed a newline, make
32424453Smckusick 					 * sure it is put back */
3258800Smckusick 			force_nl = true;
32624453Smckusick 		    if (type_code == sp_paren && *token == 'i'
32724453Smckusick 			&& last_else && ps.else_if
32824453Smckusick 			|| type_code == sp_nparen && *token == 'e'
32924453Smckusick 			&& e_code != s_code && e_code[-1] == '}')
33024453Smckusick 			force_nl = false;
3318800Smckusick 
33224453Smckusick 		    if (sc_end == 0) {	/* ignore buffering if comment
33324453Smckusick 					 * wasnt saved up */
33424453Smckusick 			ps.search_brace = false;
3358800Smckusick 			goto check_type;
3368800Smckusick 		    }
33724453Smckusick 		    if (force_nl) {	/* if we should insert a nl here,
33824453Smckusick 					 * put it into the buffer */
3398800Smckusick 			force_nl = false;
34024453Smckusick 			--line_no;	/* this will be re-increased when
34124453Smckusick 					 * the nl is read from the buffer */
3428800Smckusick 			*sc_end++ = '\n';
3438800Smckusick 			*sc_end++ = ' ';
34424453Smckusick 			if (verbose && !flushed_nl)	/* print error msg if
34524453Smckusick 							 * the line was not
34624453Smckusick 							 * already broken */
34724453Smckusick 			    diag(0, "Line broken");
3488800Smckusick 			flushed_nl = false;
3498800Smckusick 		    }
3508800Smckusick 		    for (t_ptr = token; *t_ptr; ++t_ptr)
35124453Smckusick 			*sc_end++ = *t_ptr;	/* copy token into temp
35224453Smckusick 						 * buffer */
3538800Smckusick 
35424453Smckusick 	    sw_buffer:
35524453Smckusick 		    ps.search_brace = false;	/* stop looking for start
35624453Smckusick 						 * of stmt */
35724453Smckusick 		    bp_save = buf_ptr;	/* save current input buffer */
3588800Smckusick 		    be_save = buf_end;
35924453Smckusick 		    buf_ptr = save_com;	/* fix so that subsequent calls to
36024453Smckusick 					 * lexi will take tokens out of
36124453Smckusick 					 * save_com */
36224453Smckusick 		    *sc_end++ = ' ';	/* add trailing blank, just in
36324453Smckusick 					 * case */
3648800Smckusick 		    buf_end = sc_end;
3658800Smckusick 		    sc_end = 0;
3668800Smckusick 		    break;
36724453Smckusick 	    }			/* end of switch */
36824453Smckusick 	    if (type_code != 0)	/* we must make this check, just in case
36924453Smckusick 				 * there was an unexpected EOF */
37024453Smckusick 		type_code = lexi();	/* read another token */
37124453Smckusick 	    is_procname = ps.procname[0];
37224453Smckusick 	}			/* end of while (serach_brace) */
37324453Smckusick 	last_else = 0;
37424453Smckusick check_type:
37524453Smckusick 	if (type_code == 0) {	/* we got eof */
3768800Smckusick 	    if (s_lab != e_lab || s_code != e_code
37724453Smckusick 		|| s_com != e_com)	/* must dump end of line */
37824453Smckusick 		dump_line();
37924453Smckusick 	    if (ps.tos > 1)	/* check for balanced braces */
38024453Smckusick 		diag(1, "Stuff missing from end of file.");
3818800Smckusick 
3828800Smckusick 	    if (verbose) {
38324453Smckusick 		printf("There were %d output lines and %d comments\n",
38424453Smckusick 		       ps.out_lines, ps.out_coms);
38524453Smckusick 		printf("(Lines with comments)/(Lines with code): %6.3f\n",
38624453Smckusick 		       (1.0 * ps.com_lines) / code_lines);
3878800Smckusick 	    }
38824453Smckusick 	    fflush(output);
389*30984Sbostic 	    exit(ps.tos > 1 || found_err);
3908800Smckusick 	}
3918800Smckusick 	if (
39224453Smckusick 	    (type_code != comment) &&
39324453Smckusick 	    (type_code != newline) &&
39424453Smckusick 	    (type_code != preesc) &&
39524453Smckusick 	    (type_code != form_feed)) {
3968800Smckusick 	    if (
39724453Smckusick 		force_nl
39824453Smckusick 		&&
39924453Smckusick 		(type_code != semicolon) &&
40024453Smckusick 		(
40124453Smckusick 		 type_code != lbrace
40224453Smckusick 		 ||
40324453Smckusick 		 !btype_2
40424453Smckusick 		 )) {		/* we should force a broken line here */
4058800Smckusick 		if (verbose && !flushed_nl)
40624453Smckusick 		    diag(0, "Line broken");
4078800Smckusick 		flushed_nl = false;
40824453Smckusick 		dump_line();
40924453Smckusick 		ps.want_blank = false;	/* dont insert blank at line start */
4108800Smckusick 		force_nl = false;
4118800Smckusick 	    }
41224453Smckusick 	    ps.in_stmt = true;	/* turn on flag which causes an extra
41324453Smckusick 				 * level of indentation. this is turned
41424453Smckusick 				 * off by a ; or '}' */
41524453Smckusick 	    if (s_com != e_com) {	/* the turkey has embedded a
41624453Smckusick 					 * comment in a line. fix it */
4178800Smckusick 		*e_code++ = ' ';
4188800Smckusick 		for (t_ptr = s_com; *t_ptr; ++t_ptr)
4198800Smckusick 		    *e_code++ = *t_ptr;
4208800Smckusick 		*e_code++ = ' ';
42124453Smckusick 		*e_code = '\0';	/* null terminate code sect */
42224453Smckusick 		ps.want_blank = false;
4238800Smckusick 		e_com = s_com;
4248800Smckusick 	    }
42524453Smckusick 	} else if (type_code != comment)	/* preserve force_nl thru
42624453Smckusick 						 * a comment */
42724453Smckusick 	    force_nl = false;
4288800Smckusick 
42924453Smckusick 	/*
43024453Smckusick 	 * cancel forced newline after newline, form feed, etc
43124453Smckusick 	 */
4328800Smckusick 
4338800Smckusick 
4348800Smckusick 
43524453Smckusick 	/*----------------------------------------------------*\
43624648Smckusick 	|   do switch on type of token scanned
43724648Smckusick 	\*----------------------------------------------------*/
43824453Smckusick 	switch (type_code) {	/* now, decide what to do with the token */
43924453Smckusick 
44024453Smckusick 	    case form_feed:	/* found a form feed in line */
44124453Smckusick 		ps.use_ff = true;	/* a form feed is treated much
44224453Smckusick 					 * like a newline */
44324453Smckusick 		dump_line();
44424453Smckusick 		ps.want_blank = false;
4458800Smckusick 		break;
4468800Smckusick 
44724453Smckusick 	    case newline:
44824453Smckusick 		if (ps.last_token != comma || ps.p_l_follow > 0
44924453Smckusick 		    || !ps.leave_comma || !break_comma || s_com != e_com) {
45024453Smckusick 		    dump_line();
45124453Smckusick 		    ps.want_blank = false;
45224453Smckusick 		}
45324453Smckusick 		++line_no;	/* keep track of input line number */
4548800Smckusick 		break;
4558800Smckusick 
45624453Smckusick 	    case lparen:	/* got a '(' or '[' */
45724453Smckusick 		++ps.p_l_follow;/* count parens to make Healy happy */
45824453Smckusick 		if (ps.want_blank && *token != '[' &&
45924453Smckusick 		    (ps.last_token != ident || proc_calls_space
46024453Smckusick 		     || (ps.its_a_keyword && !ps.sizeof_keyword)))
4618800Smckusick 		    *e_code++ = ' ';
46224453Smckusick 		if (ps.in_decl && !ps.block_init)
46324453Smckusick 		    if (troff && !ps.dumped_decl_indent) {
46424453Smckusick 			ps.dumped_decl_indent = 1;
46524453Smckusick 			sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
46624453Smckusick 			e_code += strlen(e_code);
46724453Smckusick 		    } else {
46824453Smckusick 			while ((e_code - s_code) < dec_ind)
46924453Smckusick 			    *e_code++ = ' ';
47024453Smckusick 			*e_code++ = token[0];
47124453Smckusick 		} else
47224453Smckusick 		    *e_code++ = token[0];
47324453Smckusick 		ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
47424453Smckusick 		ps.want_blank = false;
47524453Smckusick 		if (ps.in_or_st && *token == '(') {
4768800Smckusick 
47724453Smckusick 		    /*
47824453Smckusick 		     * this is a kluge to make sure that declarations will
47924453Smckusick 		     * be aligned right if proc decl has an explicit type
48024453Smckusick 		     * on it, i.e. "int a(x) {..."
48124453Smckusick 		     */
48224453Smckusick 		    parse(semicolon);	/* I said this was a kluge... */
48324453Smckusick 		    ps.in_or_st = false;	/* turn off flag for
48424453Smckusick 						 * structure decl or
48524453Smckusick 						 * initialization */
4868800Smckusick 		}
48724453Smckusick 		if (ps.sizeof_keyword) ps.sizeof_mask |= 1<<ps.p_l_follow;
4888800Smckusick 		break;
4898800Smckusick 
49024453Smckusick 	    case rparen:	/* got a ')' or ']' */
49124453Smckusick 		if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
49224453Smckusick 		    ps.last_u_d = true;
49324453Smckusick 		    ps.cast_mask &= (1 << ps.p_l_follow) - 1;
4948800Smckusick 		}
49524453Smckusick 		ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
49624453Smckusick 		if (--ps.p_l_follow < 0) {
49724453Smckusick 		    ps.p_l_follow = 0;
49824453Smckusick 		    diag(0, "Extra %c", *token);
49924453Smckusick 		}
50024453Smckusick 		if (e_code == s_code)	/* if the paren starts the line */
50124453Smckusick 		    ps.paren_level = ps.p_l_follow;	/* then indent it */
5028800Smckusick 
5038800Smckusick 		*e_code++ = token[0];
50424453Smckusick 		ps.want_blank = true;
5058800Smckusick 
50624453Smckusick 		if (sp_sw && (ps.p_l_follow == 0)) {	/* check for end of if
50724453Smckusick 							 * (...), or some such */
5088800Smckusick 		    sp_sw = false;
50924453Smckusick 		    force_nl = true;	/* must force newline after if */
51024453Smckusick 		    ps.last_u_d = true;	/* inform lexi that a following
51124453Smckusick 					 * operator is unary */
51224453Smckusick 		    ps.in_stmt = false;	/* dont use stmt continuation
51324453Smckusick 					 * indentation */
5148800Smckusick 
51524453Smckusick 		    parse(hd_type);	/* let parser worry about if, or
51624453Smckusick 					 * whatever */
5178800Smckusick 		}
51824453Smckusick 		ps.search_brace = btype_2;	/* this should insure that
51924453Smckusick 						 * constructs such as
52024453Smckusick 						 * main(){...} and
52124453Smckusick 						 * int[]{...} have their
52224453Smckusick 						 * braces put in the right
52324453Smckusick 						 * place */
5248800Smckusick 		break;
5258800Smckusick 
52624453Smckusick 	    case unary_op:	/* this could be any unary operation */
52724453Smckusick 		if (ps.want_blank)
5288800Smckusick 		    *e_code++ = ' ';
5298800Smckusick 
53024453Smckusick 		if (troff && !ps.dumped_decl_indent && ps.in_decl) {
53124453Smckusick 		    sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
53224453Smckusick 		    ps.dumped_decl_indent = 1;
53324453Smckusick 		    e_code += strlen(e_code);
53424453Smckusick 		} else {
53524453Smckusick 		    char       *res = token;
53624453Smckusick 
53724453Smckusick 		    if (ps.in_decl && !ps.block_init) {	/* if this is a unary op
53824453Smckusick 							 * in a declaration, we
53924453Smckusick 							 * should indent this
54024453Smckusick 							 * token */
54124453Smckusick 			for (i = 0; token[i]; ++i);	/* find length of token */
54224453Smckusick 			while ((e_code - s_code) < (dec_ind - i))
54324453Smckusick 			    *e_code++ = ' ';	/* pad it */
54424453Smckusick 		    }
54524453Smckusick 		    if (troff && token[0] == '-' && token[1] == '>')
54624453Smckusick 			res = "\\(->";
54724453Smckusick 		    for (t_ptr = res; *t_ptr; ++t_ptr)
54824453Smckusick 			*e_code++ = *t_ptr;
5498800Smckusick 		}
55024453Smckusick 		ps.want_blank = false;
5518800Smckusick 		break;
5528800Smckusick 
55324453Smckusick 	    case binary_op:	/* any binary operation */
55424453Smckusick 	do_binary:
55524453Smckusick 		if (ps.want_blank)
5568800Smckusick 		    *e_code++ = ' ';
55724453Smckusick 		{
55824453Smckusick 		    char       *res = token;
55924453Smckusick 
56024453Smckusick 		    if (troff)
56124453Smckusick 			switch (token[0]) {
56224453Smckusick 			    case '<':
56324453Smckusick 				if (token[1] == '=')
56424453Smckusick 				    res = "\\(<=";
56524453Smckusick 				break;
56624453Smckusick 			    case '>':
56724453Smckusick 				if (token[1] == '=')
56824453Smckusick 				    res = "\\(>=";
56924453Smckusick 				break;
57024453Smckusick 			    case '!':
57124453Smckusick 				if (token[1] == '=')
57224453Smckusick 				    res = "\\(!=";
57324453Smckusick 				break;
57424453Smckusick 			    case '|':
57524453Smckusick 				if (token[1] == '|')
57624453Smckusick 				    res = "\\(br\\(br";
57724453Smckusick 				else if (token[1] == 0)
57824453Smckusick 				    res = "\\(br";
57924453Smckusick 				break;
58024676Smckusick 			    case '-':
58124676Smckusick 				if (token[1] == '>')
58224676Smckusick 				    res = "\\(->";
58324453Smckusick 			}
58424453Smckusick 		    for (t_ptr = res; *t_ptr; ++t_ptr)
58524453Smckusick 			*e_code++ = *t_ptr;	/* move the operator */
58624453Smckusick 		}
58724453Smckusick 		ps.want_blank = true;
5888800Smckusick 		break;
5898800Smckusick 
59024453Smckusick 	    case postop:	/* got a trailing ++ or -- */
5918800Smckusick 		*e_code++ = token[0];
5928800Smckusick 		*e_code++ = token[1];
59324453Smckusick 		ps.want_blank = true;
5948800Smckusick 		break;
5958800Smckusick 
59624453Smckusick 	    case question:	/* got a ? */
59724453Smckusick 		squest++;	/* this will be used when a later colon
59824453Smckusick 				 * appears so we can distinguish the
59924453Smckusick 				 * <c>?<n>:<n> construct */
60024453Smckusick 		if (ps.want_blank)
6018800Smckusick 		    *e_code++ = ' ';
6028800Smckusick 		*e_code++ = '?';
60324453Smckusick 		ps.want_blank = true;
6048800Smckusick 		break;
6058800Smckusick 
60624453Smckusick 	    case casestmt:	/* got word 'case' or 'default' */
60724453Smckusick 		scase = true;	/* so we can process the later colon
60824453Smckusick 				 * properly */
60924453Smckusick 		goto copy_id;
6108800Smckusick 
61124453Smckusick 	    case colon:	/* got a ':' */
61224453Smckusick 		if (squest > 0) {	/* it is part of the <c>?<n>: <n>
61324453Smckusick 					 * construct */
6148800Smckusick 		    --squest;
61524453Smckusick 		    if (ps.want_blank)
6168800Smckusick 			*e_code++ = ' ';
6178800Smckusick 		    *e_code++ = ':';
61824453Smckusick 		    ps.want_blank = true;
6198800Smckusick 		    break;
6208800Smckusick 		}
62124453Smckusick 		if (ps.in_decl) {
62224453Smckusick 		    *e_code++ = ':';
62324453Smckusick 		    ps.want_blank = false;
62424453Smckusick 		    break;
62524453Smckusick 		}
62624453Smckusick 		ps.in_stmt = false;	/* seeing a label does not imply
62724453Smckusick 					 * we are in a stmt */
6288800Smckusick 		for (t_ptr = s_code; *t_ptr; ++t_ptr)
62924453Smckusick 		    *e_lab++ = *t_ptr;	/* turn everything so far into a
63024453Smckusick 					 * label */
6318800Smckusick 		e_code = s_code;
6328800Smckusick 		*e_lab++ = ':';
6338800Smckusick 		*e_lab++ = ' ';
6348800Smckusick 		*e_lab = '\0';
6358800Smckusick 
63624453Smckusick 		force_nl = ps.pcase = scase;	/* ps.pcase will be used
63724453Smckusick 						 * by dump_line to decide
63824453Smckusick 						 * how to indent the
63924453Smckusick 						 * label. force_nl will
64024453Smckusick 						 * force a case n: to be
64124453Smckusick 						 * on a line by itself */
6428800Smckusick 		scase = false;
64324453Smckusick 		ps.want_blank = false;
6448800Smckusick 		break;
6458800Smckusick 
64624453Smckusick 	    case semicolon:	/* got a ';' */
64724453Smckusick 		ps.in_or_st = false;	/* we are not in an initialization
64824453Smckusick 					 * or structure declaration */
64924453Smckusick 		scase = false;	/* these will only need resetting in a
65024453Smckusick 				 * error */
6518800Smckusick 		squest = 0;
65224453Smckusick 		if (ps.last_token == rparen)
65324453Smckusick 		    ps.in_parameter_declaration = 0;
65424453Smckusick 		ps.cast_mask = 0;
65524453Smckusick 		ps.sizeof_mask = 0;
65624453Smckusick 		ps.block_init = 0;
65724453Smckusick 		ps.just_saw_decl--;
6588800Smckusick 
65924453Smckusick 		if (ps.in_decl && s_code == e_code && !ps.block_init)
6608800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
6618800Smckusick 			*e_code++ = ' ';
6628800Smckusick 
66324453Smckusick 		ps.in_decl = (ps.dec_nest > 0);	/* if we were in a first
66424453Smckusick 						 * level structure
66524453Smckusick 						 * declaration, we arent
66624453Smckusick 						 * any more */
6678800Smckusick 
66824453Smckusick 		if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
66924453Smckusick 
67024453Smckusick 		    /*
67124453Smckusick 		     * This should be true iff there were unbalanced
67224453Smckusick 		     * parens in the stmt.  It is a bit complicated,
67324453Smckusick 		     * because the semicolon might be in a for stmt
67424453Smckusick 		     */
67524453Smckusick 		    diag(1, "Unbalanced parens");
67624453Smckusick 		    ps.p_l_follow = 0;
67724453Smckusick 		    if (sp_sw) {/* this is a check for a if, while, etc.
67824453Smckusick 				 * with unbalanced parens */
6798800Smckusick 			sp_sw = false;
68024453Smckusick 			parse(hd_type);	/* dont lose the if, or whatever */
6818800Smckusick 		    }
6828800Smckusick 		}
6838800Smckusick 		*e_code++ = ';';
68424453Smckusick 		ps.want_blank = true;
68524453Smckusick 		ps.in_stmt = (ps.p_l_follow > 0);	/* we are no longer in
68624453Smckusick 							 * the middle of a stmt */
6878800Smckusick 
68824453Smckusick 		if (!sp_sw) {	/* if not if for (;;) */
68924453Smckusick 		    parse(semicolon);	/* let parser know about end of
69024453Smckusick 					 * stmt */
69124453Smckusick 		    force_nl = true;	/* force newline after a end of
69224453Smckusick 					 * stmt */
6938800Smckusick 		}
6948800Smckusick 		break;
6958800Smckusick 
69624453Smckusick 	    case lbrace:	/* got a '{' */
69724453Smckusick 		ps.in_stmt = false;	/* dont indent the {} */
69824453Smckusick 		if (!ps.block_init)
69924453Smckusick 		    force_nl = true;	/* force other stuff on same line
70024453Smckusick 					 * as '{' onto new line */
7018800Smckusick 
70224453Smckusick 		if (s_code != e_code && !ps.block_init) {
70324453Smckusick 		    if (!btype_2) {
70424453Smckusick 			dump_line();
70524453Smckusick 			ps.want_blank = false;
70624453Smckusick 		    } else if (ps.in_parameter_declaration && !ps.in_or_st) {
70724453Smckusick 			ps.i_l_follow = 0;
70824453Smckusick 			dump_line();
70924453Smckusick 			ps.want_blank = false;
71024453Smckusick 		    }
7118800Smckusick 		}
71224453Smckusick 		if (ps.in_parameter_declaration)
71324453Smckusick 		    prefix_blankline_requested = 0;
7148800Smckusick 
71524648Smckusick 		if (ps.p_l_follow > 0) {	/* check for preceding
71624453Smckusick 						 * unbalanced parens */
71724453Smckusick 		    diag(1, "Unbalanced parens");
71824453Smckusick 		    ps.p_l_follow = 0;
71924453Smckusick 		    if (sp_sw) {/* check for unclosed if, for, etc. */
7208800Smckusick 			sp_sw = false;
72124453Smckusick 			parse(hd_type);
72224453Smckusick 			ps.ind_level = ps.i_l_follow;
7238800Smckusick 		    }
7248800Smckusick 		}
7258800Smckusick 		if (s_code == e_code)
72624453Smckusick 		    ps.ind_stmt = false;	/* dont put extra
72724453Smckusick 						 * indentation on line
72824453Smckusick 						 * with '{' */
72924453Smckusick 		if (ps.in_decl && ps.in_or_st) {	/* this is either a
73024453Smckusick 							 * structure declaration
73124453Smckusick 							 * or an init */
73224453Smckusick 		    di_stack[ps.dec_nest++] = dec_ind;
7338800Smckusick 		    dec_ind = 0;
73424453Smckusick 		} else {
73524453Smckusick 		    ps.decl_on_line = false;	/* we cant be in the
73624453Smckusick 						 * middle of a
73724453Smckusick 						 * declaration, so dont do
73824453Smckusick 						 * special indentation of
73924453Smckusick 						 * comments */
74024453Smckusick 		    ps.in_parameter_declaration = 0;
7418800Smckusick 		}
74224453Smckusick 		parse(lbrace);	/* let parser know about this */
74324453Smckusick 		if (ps.want_blank)	/* put a blank before '{' if '{'
74424453Smckusick 					 * is not at start of line */
7458800Smckusick 		    *e_code++ = ' ';
74624453Smckusick 		ps.want_blank = false;
7478800Smckusick 		*e_code++ = '{';
74824453Smckusick 		ps.just_saw_decl = 0;
7498800Smckusick 		break;
7508800Smckusick 
75124453Smckusick 	    case rbrace:	/* got a '}' */
75224453Smckusick 		if (ps.p_l_follow) {	/* check for unclosed if, for,
75324453Smckusick 					 * else. */
75424453Smckusick 		    diag(1, "Unbalanced parens");
75524453Smckusick 		    ps.p_l_follow = 0;
7568800Smckusick 		    sp_sw = false;
7578800Smckusick 		}
75824453Smckusick 		ps.just_saw_decl = 0;
75924453Smckusick 		if (s_code != e_code && !ps.block_init) {	/* '}' must be first on
76024453Smckusick 								 * line */
7618800Smckusick 		    if (verbose)
76224453Smckusick 			diag(0, "Line broken");
76324453Smckusick 		    dump_line();
7648800Smckusick 		}
7658800Smckusick 		*e_code++ = '}';
76624453Smckusick 		ps.want_blank = true;
76724453Smckusick 		ps.in_stmt = ps.ind_stmt = false;
76824453Smckusick 		if (ps.dec_nest > 0) {	/* we are in multi-level structure
76924453Smckusick 					 * declaration */
77024453Smckusick 		    dec_ind = di_stack[--ps.dec_nest];
77124453Smckusick 		    if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
77224453Smckusick 			ps.just_saw_decl = 2;
77324453Smckusick 		    ps.in_decl = true;
7748800Smckusick 		}
77524453Smckusick 		prefix_blankline_requested = 0;
77624453Smckusick 		parse(rbrace);	/* let parser know about this */
77724453Smckusick 		ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level;
77824453Smckusick 		if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
77924453Smckusick 		    postfix_blankline_requested = 1;
7808800Smckusick 		break;
7818800Smckusick 
78224453Smckusick 	    case swstmt:	/* got keyword "switch" */
7838800Smckusick 		sp_sw = true;
78424453Smckusick 		hd_type = swstmt;	/* keep this for when we have seen
78524453Smckusick 					 * the expression */
78624453Smckusick 		goto copy_id;	/* go move the token into buffer */
7878800Smckusick 
78824453Smckusick 	    case sp_paren:	/* token is if, while, for */
78924453Smckusick 		sp_sw = true;	/* the interesting stuff is done after the
79024453Smckusick 				 * expression is scanned */
7918800Smckusick 		hd_type = (*token == 'i' ? ifstmt :
79224453Smckusick 			   (*token == 'w' ? whilestmt : forstmt));
7938800Smckusick 
79424453Smckusick 		/*
79524453Smckusick 		 * remember the type of header for later use by parser
79624453Smckusick 		 */
79724453Smckusick 		goto copy_id;	/* copy the token into line */
79824453Smckusick 
79924453Smckusick 	    case sp_nparen:	/* got else, do */
80024453Smckusick 		ps.in_stmt = false;
80124453Smckusick 		if (*token == 'e') {
80224453Smckusick 		    if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
80324453Smckusick 			if (verbose)
80424453Smckusick 			    diag(0, "Line broken");
80524453Smckusick 			dump_line();	/* make sure this starts a line */
80624453Smckusick 			ps.want_blank = false;
80724453Smckusick 		    }
80824453Smckusick 		    force_nl = true;	/* also, following stuff must go
80924453Smckusick 					 * onto new line */
81024453Smckusick 		    last_else = 1;
81124453Smckusick 		    parse(elselit);
81224453Smckusick 		} else {
81324453Smckusick 		    if (e_code != s_code) {	/* make sure this starts a
81424453Smckusick 						 * line */
81524453Smckusick 			if (verbose)
81624453Smckusick 			    diag(0, "Line broken");
81724453Smckusick 			dump_line();
81824453Smckusick 			ps.want_blank = false;
81924453Smckusick 		    }
82024453Smckusick 		    force_nl = true;	/* also, following stuff must go
82124453Smckusick 					 * onto new line */
82224453Smckusick 		    last_else = 0;
82324453Smckusick 		    parse(dolit);
8248800Smckusick 		}
82524453Smckusick 		goto copy_id;	/* move the token into line */
8268800Smckusick 
82724453Smckusick 	    case decl:		/* we have a declaration type (int,
82824453Smckusick 				 * register, etc.) */
82924453Smckusick 		parse(decl);	/* let parser worry about indentation */
83024453Smckusick 		if (ps.last_token == rparen && ps.tos <= 1)
83124453Smckusick 		    ps.in_parameter_declaration = 1;
83224453Smckusick 		if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
83324453Smckusick 		    ps.ind_level = ps.i_l_follow = 1;
83424453Smckusick 		    ps.ind_stmt = 0;
83524453Smckusick 		}
83624453Smckusick 		ps.in_or_st = true;	/* this might be a structure or
83724453Smckusick 					 * initialization declaration */
83824453Smckusick 		ps.in_decl = ps.decl_on_line = true;
83924453Smckusick 		if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
84024453Smckusick 		    ps.just_saw_decl = 2;
84124453Smckusick 		prefix_blankline_requested = 0;
84224453Smckusick 		for (i = 0; token[i++];);	/* get length of token */
8438800Smckusick 
84424453Smckusick 		/*
84524453Smckusick 		 * dec_ind = e_code - s_code + (ps.decl_indent>i ?
84624453Smckusick 		 * ps.decl_indent : i);
84724453Smckusick 		 */
84824453Smckusick 		dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
8498800Smckusick 		goto copy_id;
8508800Smckusick 
85124453Smckusick 	    case ident:	/* got an identifier or constant */
85224453Smckusick 		if (ps.in_decl) {	/* if we are in a declaration, we
85324453Smckusick 					 * must indent identifier */
85424453Smckusick 		    if (ps.want_blank)
8558800Smckusick 			*e_code++ = ' ';
85624453Smckusick 		    ps.want_blank = false;
85724453Smckusick 		    if (is_procname == 0 || !procnames_start_line) {
85824453Smckusick 			if (!ps.block_init)
85924453Smckusick 			    if (troff && !ps.dumped_decl_indent) {
86024453Smckusick 				sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7);
86124453Smckusick 				ps.dumped_decl_indent = 1;
86224453Smckusick 				e_code += strlen(e_code);
86324453Smckusick 			    } else
86424453Smckusick 				while ((e_code - s_code) < dec_ind)
86524453Smckusick 				    *e_code++ = ' ';
86624453Smckusick 		    } else {
86724453Smckusick 			if (dec_ind && s_code != e_code)
86824453Smckusick 			    dump_line();
86924453Smckusick 			dec_ind = 0;
87024453Smckusick 			ps.want_blank = false;
87124453Smckusick 		    }
87224453Smckusick 		} else if (sp_sw && ps.p_l_follow == 0) {
87324453Smckusick 		    sp_sw = false;
87424453Smckusick 		    force_nl = true;
87524453Smckusick 		    ps.last_u_d = true;
87624453Smckusick 		    ps.in_stmt = false;
87724453Smckusick 		    parse(hd_type);
8788800Smckusick 		}
87924453Smckusick 	copy_id:
88024453Smckusick 		if (ps.want_blank)
8818800Smckusick 		    *e_code++ = ' ';
88224453Smckusick 		if (troff && ps.its_a_keyword) {
88324453Smckusick 		    *e_code++ = BACKSLASH;
88424453Smckusick 		    *e_code++ = 'f';
88524453Smckusick 		    *e_code++ = 'B';
88624453Smckusick 		}
8878800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
8888800Smckusick 		    *e_code++ = *t_ptr;
88924453Smckusick 		if (troff && ps.its_a_keyword) {
89024453Smckusick 		    *e_code++ = BACKSLASH;
89124453Smckusick 		    *e_code++ = 'f';
89224453Smckusick 		    *e_code++ = 'R';
89324453Smckusick 		}
89424453Smckusick 		ps.want_blank = true;
8958800Smckusick 		break;
8968800Smckusick 
89724453Smckusick 	    case period:	/* treat a period kind of like a binary
89824453Smckusick 				 * operation */
89924453Smckusick 		*e_code++ = '.';/* move the period into line */
90024453Smckusick 		ps.want_blank = false;	/* dont put a blank after a period */
9018800Smckusick 		break;
9028800Smckusick 
90324453Smckusick 	    case comma:
90424453Smckusick 		ps.want_blank = (s_code != e_code);	/* only put blank after
90524453Smckusick 							 * comma if comma does
90624453Smckusick 							 * not start the line */
90724453Smckusick 		if (ps.in_decl && is_procname == 0 && !ps.block_init)
9088800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
9098800Smckusick 			*e_code++ = ' ';
9108800Smckusick 
9118800Smckusick 		*e_code++ = ',';
91224453Smckusick 		if (ps.p_l_follow == 0) {
91324453Smckusick 		    ps.block_init = 0;
91424453Smckusick 		    if (break_comma && !ps.leave_comma)
91524453Smckusick 			force_nl = true;
91624453Smckusick 		}
9178800Smckusick 		break;
9188800Smckusick 
91924453Smckusick 	    case preesc:	/* got the character '#' */
92024453Smckusick 		if ((s_com != e_com) ||
92124453Smckusick 		    (s_lab != e_lab) ||
92224453Smckusick 		    (s_code != e_code))
92324453Smckusick 		    dump_line();
92424453Smckusick 		*e_lab++ = '#';	/* move whole line to 'label' buffer */
92524453Smckusick 		{
92624453Smckusick 		    int         in_comment = 0;
92724453Smckusick 		    char       *com_start = 0;
92824453Smckusick 		    char        quote = 0;
92924453Smckusick 		    char       *com_end = 0;
9308800Smckusick 
93124453Smckusick 		    while (*buf_ptr != '\n' || in_comment) {
93224453Smckusick 			*e_lab = *buf_ptr++;
93324453Smckusick 			if (buf_ptr >= buf_end)
93424453Smckusick 			    fill_buffer();
93524453Smckusick 			switch (*e_lab++) {
93624453Smckusick 			    case BACKSLASH:
93724453Smckusick 				if (troff)
93824453Smckusick 				    *e_lab++ = BACKSLASH;
93924453Smckusick 				if (!in_comment) {
94024453Smckusick 				    *e_lab++ = *buf_ptr++;
94124453Smckusick 				    if (buf_ptr >= buf_end)
94224453Smckusick 					fill_buffer();
94324453Smckusick 				}
94424453Smckusick 				break;
94524453Smckusick 			    case '/':
94624453Smckusick 				if (*buf_ptr == '*' && !in_comment && !quote) {
94724453Smckusick 				    in_comment = 1;
94824453Smckusick 				    *e_lab++ = *buf_ptr++;
94924453Smckusick 				    com_start = e_lab - 2;
95024453Smckusick 				}
95124453Smckusick 				break;
95224453Smckusick 			    case '"':
95324453Smckusick 				if (quote == '"')
95424453Smckusick 				    quote = 0;
95524453Smckusick 				break;
95624453Smckusick 			    case '\'':
95724453Smckusick 				if (quote == '\'')
95824453Smckusick 				    quote = 0;
95924453Smckusick 				break;
96024453Smckusick 			    case '*':
96124453Smckusick 				if (*buf_ptr == '/' && in_comment) {
96224453Smckusick 				    in_comment = 0;
96324453Smckusick 				    *e_lab++ = *buf_ptr++;
96424453Smckusick 				    com_end = e_lab;
96524453Smckusick 				}
96624453Smckusick 				break;
96724453Smckusick 			}
9688800Smckusick 		    }
96924453Smckusick 		    while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
97024453Smckusick 			e_lab--;
97124453Smckusick 		    if (e_lab == com_end && bp_save == 0) {	/* comment on
97224453Smckusick 								 * preprocessor line */
97324453Smckusick 			if (sc_end == 0)	/* if this is the first
97424453Smckusick 						 * comment, we must set up
97524453Smckusick 						 * the buffer */
97624453Smckusick 			    sc_end = &(save_com[0]);
97724453Smckusick 			else {
97824453Smckusick 			    *sc_end++ = '\n';	/* add newline between
97924453Smckusick 						 * comments */
98024453Smckusick 			    *sc_end++ = ' ';
98124453Smckusick 			    --line_no;
98224453Smckusick 			}
98324453Smckusick 			bcopy(com_start, sc_end, com_end - com_start);
98424453Smckusick 			sc_end += com_end - com_start;
98524453Smckusick 			e_lab = com_start;
98624453Smckusick 			while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
98724453Smckusick 			    e_lab--;
98824453Smckusick 			bp_save = buf_ptr;	/* save current input
98924453Smckusick 						 * buffer */
99024453Smckusick 			be_save = buf_end;
99124453Smckusick 			buf_ptr = save_com;	/* fix so that subsequent
99224453Smckusick 						 * calls to lexi will take
99324453Smckusick 						 * tokens out of save_com */
99424453Smckusick 			*sc_end++ = ' ';	/* add trailing blank,
99524453Smckusick 						 * just in case */
99624453Smckusick 			buf_end = sc_end;
99724453Smckusick 			sc_end = 0;
99824453Smckusick 		    }
99924453Smckusick 		    *e_lab = '\0';	/* null terminate line */
100024453Smckusick 		    ps.pcase = false;
10018800Smckusick 		}
100224453Smckusick 		if (strncmp(s_lab, "#if", 3) == 0)
100324453Smckusick 		    if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
100424453Smckusick 			match_state[ifdef_level].tos = -1;
100524453Smckusick 			state_stack[ifdef_level++] = ps;
100624453Smckusick 		    } else
100724453Smckusick 			diag(1, "#if stack overflow");
100824453Smckusick 		else if (strncmp(s_lab, "#else", 5) == 0)
100924453Smckusick 		    if (ifdef_level <= 0)
101024453Smckusick 			diag(1, "Unmatched #else");
101124453Smckusick 		    else {
101224453Smckusick 			match_state[ifdef_level - 1] = ps;
101324453Smckusick 			ps = state_stack[ifdef_level - 1];
101424453Smckusick 		} else if (strncmp(s_lab, "#endif", 6) == 0)
101524453Smckusick 		    if (ifdef_level <= 0)
101624453Smckusick 			diag(1, "Unmatched #endif");
101724453Smckusick 		    else {
101824453Smckusick 			ifdef_level--;
101924453Smckusick #ifdef undef
10208800Smckusick 
102124453Smckusick 			/*
102224453Smckusick 			 * This match needs to be more intelligent before
102324453Smckusick 			 * the message is useful
102424453Smckusick 			 */
102524453Smckusick 			if (match_state[ifdef_level].tos >= 0
102624453Smckusick 			    && bcmp(&ps, &match_state[ifdef_level], sizeof ps))
102724453Smckusick 			    diag(0, "Syntactically inconsistant #ifdef alternatives.");
102824453Smckusick #endif
102924453Smckusick 		    }
103024453Smckusick 		break;		/* subsequent processing of the newline
103124453Smckusick 				 * character will cause the line to be
103224453Smckusick 				 * printed */
10338800Smckusick 
103424453Smckusick 	    case comment:	/* we have gotten a /*  this is a biggie */
103524453Smckusick 	proc_comment:
103624453Smckusick 		if (flushed_nl) {	/* we should force a broken line
103724453Smckusick 					 * here */
103824453Smckusick 		    flushed_nl = false;
103924453Smckusick 		    dump_line();
104024453Smckusick 		    ps.want_blank = false;	/* dont insert blank at
104124453Smckusick 						 * line start */
104224453Smckusick 		    force_nl = false;
104324453Smckusick 		}
104424453Smckusick 		pr_comment();
10458800Smckusick 		break;
104624453Smckusick 	}			/* end of big switch stmt */
104724453Smckusick 	*e_code = '\0';		/* make sure code section is null
104824453Smckusick 				 * terminated */
104924453Smckusick 	if (type_code != comment && type_code != newline && type_code != preesc)
105024453Smckusick 	    ps.last_token = type_code;
105124453Smckusick     }				/* end of main while (1) loop */
10528800Smckusick };
10538800Smckusick 
10548800Smckusick /*
105524648Smckusick  * copy input file to backup file.  If in_name is /blah/blah/blah/file, then
105624648Smckusick  * backup file will be "file.BAK".  Then make the backup file the input and
105724648Smckusick  * original input file the output.
10588800Smckusick  */
105924453Smckusick bakcopy()
106024453Smckusick {
106124453Smckusick     int         n,
106224453Smckusick                 bakchn;
106324648Smckusick     char        buff[BUFSIZ];
106424453Smckusick     register char *p;
106524648Smckusick     char *rindex();
10668800Smckusick 
106724648Smckusick     if ((p = rindex(in_name, '/')) != NULL)
10688800Smckusick 	p++;
106924648Smckusick     else
107024648Smckusick 	p = in_name;
107124453Smckusick     sprintf(bakfile, "%s.BAK", p);
10728800Smckusick 
107324453Smckusick     /* copy in_name to backup file */
107424453Smckusick     bakchn = creat(bakfile, 0600);
10758800Smckusick     if (bakchn < 0) {
107624648Smckusick 	fprintf(stderr, "indent: can't create backup file \"%s\"\n", bakfile);
107724648Smckusick 	exit(1);
10788800Smckusick     }
107924648Smckusick     while ((n = read(fileno(input), buff, sizeof buff)) > 0)
108024648Smckusick 	if (write(bakchn, buff, n) != n) {
108124648Smckusick 	    fprintf(stderr, "indent: error writing backup file \"%s\"\n",
108224648Smckusick 		bakfile);
108324648Smckusick 	    exit(1);
108424648Smckusick 	}
108524648Smckusick     if (n < 0) {
108624648Smckusick 	fprintf(stderr, "indent: error reading input file \"%s\"\n", in_name);
108724648Smckusick 	exit(1);
108824648Smckusick     }
108924453Smckusick     close(bakchn);
109024453Smckusick     fclose(input);
10918800Smckusick 
109224453Smckusick     /* re-open backup file as the input file */
109324453Smckusick     input = fopen(bakfile, "r");
109424648Smckusick     if (input == NULL) {
109524648Smckusick 	fprintf(stderr, "indent: can't re-open backup file\n");
109624648Smckusick 	exit(1);
10978800Smckusick     }
109824453Smckusick     /* now the original input file will be the output */
109924453Smckusick     output = fopen(in_name, "w");
110024648Smckusick     if (output == NULL) {
110124648Smckusick 	fprintf(stderr, "indent: can't create %s\n", in_name);
110224453Smckusick 	unlink(bakfile);
110324648Smckusick 	exit(1);
11048800Smckusick     }
11058800Smckusick }
1106