xref: /csrg-svn/usr.bin/indent/indent.c (revision 24453)
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*24453Smckusick static char sccsid[] = "@(#)indent.c	5.2 (Berkeley) 08/28/85";
1521968Sdist #endif not lint
1621968Sdist 
17*24453Smckusick /*-
18*24453Smckusick 
19*24453Smckusick 	Copyright (C) 1976
20*24453Smckusick 		by the
21*24453Smckusick 	Board of Trustees
22*24453Smckusick 		of the
23*24453Smckusick 	University of Illinois
24*24453Smckusick 
25*24453Smckusick 	All rights reserved
26*24453Smckusick 
27*24453Smckusick 
288800Smckusick NAME:
29*24453Smckusick indent main program
30*24453Smckusick 
318800Smckusick FUNCTION:
32*24453Smckusick This is the main program of the indent program.  Indent will take a C
33*24453Smckusick program source and reformat it into a semi-reasonable form.
34*24453Smckusick 
358800Smckusick ALGORITHM:
36*24453Smckusick The routine lexi scans tokens and passes them back one at a time to the
37*24453Smckusick main routine.  The subroutine parse takes care of much of the work of
38*24453Smckusick figuring indentation level.
39*24453Smckusick 
40*24453Smckusick 1) Call lexi
41*24453Smckusick 2) Enter a monster switch statement on the code returned by lexi.  If
42*24453Smckusick the indentation level for the line yet to be printed should be
43*24453Smckusick changed, set the variable ps.ind_level.  If the indentation level for
44*24453Smckusick the following line should be changed, set the variable ps.i_l_follow.
458800Smckusick 
46*24453Smckusick */
478800Smckusick #include "indent_globs.h";
488800Smckusick #include "indent_codes.h";
498800Smckusick 
50*24453Smckusick char       *in_name = "Standard Input";	/* will always point to name of
51*24453Smckusick 					 * input file */
52*24453Smckusick char       *out_name = "Standard Output";	/* will always point to
53*24453Smckusick 						 * name of output file */
54*24453Smckusick char        bakfile[32] = "";
558800Smckusick 
56*24453Smckusick main(argc, argv)
57*24453Smckusick     int         argc;
58*24453Smckusick     char      **argv;
598800Smckusick {
608800Smckusick 
61*24453Smckusick     int         dec_ind;	/* current indentation for declarations */
62*24453Smckusick     int         di_stack[20];	/* a stack of structure indentation levels */
63*24453Smckusick     int         flushed_nl;	/* used when buffering up comments to
64*24453Smckusick 				 * remember that a newline was passed over */
65*24453Smckusick     int         force_nl;	/* when true, code must be broken */
66*24453Smckusick     int         hd_type;	/* used to store type of stmt for if
67*24453Smckusick 				 * (...), for (...), etc */
68*24453Smckusick     register int i;		/* local loop counter */
69*24453Smckusick     register int j;		/* local loop counter */
70*24453Smckusick     int         scase;		/* set to true when we see a case, so we
71*24453Smckusick 				 * will know what to do with the following
72*24453Smckusick 				 * colon */
73*24453Smckusick     int         sp_sw;		/* when true, we are in the expressin of
74*24453Smckusick 				 * if(...), while(...), etc. */
75*24453Smckusick     int         squest;		/* when this is positive, we have seen a ?
76*24453Smckusick 				 * without the matching : in a <c>?<s>:<s>
77*24453Smckusick 				 * construct */
78*24453Smckusick     register char *t_ptr;	/* used for copying tokens */
79*24453Smckusick     int         type_code;	/* the type of token, returned by lexi */
808800Smckusick 
81*24453Smckusick     int         last_else = 0;	/* true iff last keyword was an else */
828800Smckusick 
838800Smckusick 
84*24453Smckusick     /*-----------------------------------------------*\
85*24453Smckusick |		      INITIALIZATION		      |
868800Smckusick \*-----------------------------------------------*/
878800Smckusick 
888800Smckusick 
89*24453Smckusick     ps.p_stack[0] = stmt;	/* this is the parser's stack */
90*24453Smckusick     ps.last_nl = true;		/* this is true if the last thing scanned
91*24453Smckusick 				 * was a newline */
92*24453Smckusick     ps.last_token = semicolon;
93*24453Smckusick     combuf[0] = codebuf[0] = labbuf[0] = ' ';	/* set up code, label, and
94*24453Smckusick 						 * comment buffers */
958800Smckusick     combuf[1] = codebuf[1] = labbuf[1] = '\0';
96*24453Smckusick     ps.else_if = 1;		/* Default else-if special processing to
97*24453Smckusick 				 * on */
988800Smckusick     s_lab = e_lab = labbuf + 1;
998800Smckusick     s_code = e_code = codebuf + 1;
1008800Smckusick     s_com = e_com = combuf + 1;
1018800Smckusick 
1028800Smckusick     buf_ptr = buf_end = in_buffer;
1038800Smckusick     line_no = 1;
104*24453Smckusick     had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
1058800Smckusick     sp_sw = force_nl = false;
106*24453Smckusick     ps.in_or_st = false;
107*24453Smckusick     ps.bl_line = true;
1088800Smckusick     dec_ind = 0;
109*24453Smckusick     di_stack[ps.dec_nest = 0] = 0;
110*24453Smckusick     ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
1118800Smckusick 
1128800Smckusick 
113*24453Smckusick     scase = ps.pcase = false;
1148800Smckusick     squest = 0;
1158800Smckusick     sc_end = 0;
1168800Smckusick     bp_save = 0;
1178800Smckusick     be_save = 0;
1188800Smckusick 
119*24453Smckusick     output = 0;
1208800Smckusick 
1218800Smckusick 
1228800Smckusick 
123*24453Smckusick     /*--------------------------------------------------*\
1248800Smckusick |   COMMAND LINE SCAN
125*24453Smckusick \*--------------------------------------------------
126*24453Smckusick */
1278800Smckusick 
128*24453Smckusick     max_col = 78;		/* -l78 */
129*24453Smckusick     lineup_to_parens = 1;	/* -lp */
130*24453Smckusick     ps.ljust_decl = 0;		/* -ndj */
131*24453Smckusick     ps.com_ind = 33;		/* -c33 */
132*24453Smckusick     star_comment_cont = 1;	/* -sc */
133*24453Smckusick     ps.ind_size = 8;		/* -i8 */
134*24453Smckusick     verbose = 0;
135*24453Smckusick     ps.decl_indent = 16;	/* -di16 */
136*24453Smckusick     ps.indent_parameters = 1;	/* -ip */
137*24453Smckusick     ps.decl_com_ind = 0;	/* if this is not set to some positive
138*24453Smckusick 				 * value by an arg, we will set this equal
139*24453Smckusick 				 * to ps.com_ind */
140*24453Smckusick     btype_2 = 1;		/* -br */
141*24453Smckusick     cuddle_else = 1;		/* -ce */
142*24453Smckusick     ps.unindent_displace = 0;	/* -d0 */
143*24453Smckusick     ps.case_indent = 0;		/* -cli0 */
144*24453Smckusick     format_col1_comments = 1;	/* -fc1 */
145*24453Smckusick     procnames_start_line = 1;	/* -psl */
146*24453Smckusick     proc_calls_space = 0;	/* -npcs */
147*24453Smckusick     comment_delimiter_on_blankline = 1;	/* -cdb */
148*24453Smckusick     ps.leave_comma = 1;		/* -nbc */
1498800Smckusick 
150*24453Smckusick     for (i = 1; i < argc; ++i)
151*24453Smckusick 	if (strcmp(argv[i], "-npro") == 0)
152*24453Smckusick 	    break;
153*24453Smckusick     if (i >= argc)
154*24453Smckusick 	set_profile();
1558800Smckusick 
1568800Smckusick     for (i = 1; i < argc; ++i) {
157*24453Smckusick 
158*24453Smckusick 	/*
159*24453Smckusick 	 * look thru args (if any) for changes to defaults
160*24453Smckusick 	 */
1618800Smckusick 	if (argv[i][0] != '-') {/* no flag on parameter */
162*24453Smckusick 	    if (input == 0) {	/* we must have the input file */
163*24453Smckusick 		in_name = argv[i];	/* remember name of input file */
164*24453Smckusick 		input = fopen(in_name, "r");
165*24453Smckusick 		if (input == 0) {	/* check for open error */
166*24453Smckusick 		    printf("Can't open %s\n", argv[i]);
167*24453Smckusick 		    exit();
1688800Smckusick 		}
1698800Smckusick 		continue;
170*24453Smckusick 	    } else if (output == 0) {	/* we have the output file */
171*24453Smckusick 		out_name = argv[i];	/* remember name of output file */
172*24453Smckusick 		if (strcmp(in_name, out_name) == 0) {	/* attempt to overwrite
173*24453Smckusick 							 * the file */
174*24453Smckusick 		    printf("Input and output files must be different\n");
175*24453Smckusick 		    exit();
176*24453Smckusick 		}
177*24453Smckusick 		output = fopen(out_name, "w");
178*24453Smckusick 		if (output == 0) {	/* check for create error */
179*24453Smckusick 		    printf("Can't create %s\n", argv[i]);
180*24453Smckusick 		    exit();
181*24453Smckusick 		}
182*24453Smckusick 		continue;
1838800Smckusick 	    }
184*24453Smckusick 	    printf("Unknown parameter: %s\n", argv[i]);
185*24453Smckusick 	    exit();
186*24453Smckusick 	} else
187*24453Smckusick 	    set_option(argv[i]);
1888800Smckusick 
189*24453Smckusick     }				/* end of for */
190*24453Smckusick     if (input == 0) {
191*24453Smckusick 	printf("Usage: indent file [ outfile ] [ options ]\n");
192*24453Smckusick 	exit();
193*24453Smckusick     }
194*24453Smckusick     if (output == 0)
195*24453Smckusick 	if (troff)
196*24453Smckusick 	    output = stdout;
197*24453Smckusick 	else {
198*24453Smckusick 	    out_name = in_name;
199*24453Smckusick 	    bakcopy();
2008800Smckusick 	}
201*24453Smckusick     if (ps.com_ind <= 1)
202*24453Smckusick 	ps.com_ind = 2;		/* dont put normal comments before column
203*24453Smckusick 				 * 2 */
204*24453Smckusick     if (block_comment_max_col <= 0)
205*24453Smckusick 	block_comment_max_col = max_col;
206*24453Smckusick     if (ps.decl_com_ind <= 0)	/* if not specified by user, set this */
207*24453Smckusick 	ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
208*24453Smckusick     if (continuation_indent == 0)
209*24453Smckusick 	continuation_indent = ps.ind_size;
210*24453Smckusick     fill_buffer();		/* get first batch of stuff into input
211*24453Smckusick 				 * buffer */
2128800Smckusick 
213*24453Smckusick     parse(semicolon);
214*24453Smckusick     {
215*24453Smckusick 	register char *p = buf_ptr;
216*24453Smckusick 	register    col = 1;
2178800Smckusick 
218*24453Smckusick 	while (1) {
219*24453Smckusick 	    if (*p == ' ')
220*24453Smckusick 		col++;
221*24453Smckusick 	    else if (*p == '\t')
222*24453Smckusick 		col = ((col - 1) & ~7) + 9;
223*24453Smckusick 	    else
224*24453Smckusick 		break;
225*24453Smckusick 	    p++;
226*24453Smckusick 	};
227*24453Smckusick 	if (col > ps.ind_size)
228*24453Smckusick 	    ps.ind_level = ps.i_l_follow = col / ps.ind_size;
2298800Smckusick     }
230*24453Smckusick     if (troff) {
231*24453Smckusick 	register char *p = in_name,
232*24453Smckusick 	           *beg = in_name;
233*24453Smckusick 
234*24453Smckusick 	while (*p)
235*24453Smckusick 	    if (*p++ == '/')
236*24453Smckusick 		beg = p;
237*24453Smckusick 	fprintf(output, ".Fn \"%s\"\n", beg);
2388800Smckusick     }
2398800Smckusick 
240*24453Smckusick     /*
241*24453Smckusick      * START OF MAIN LOOP
242*24453Smckusick      */
2438800Smckusick 
244*24453Smckusick     while (1) {			/* this is the main loop.  it will go
245*24453Smckusick 				 * until we reach eof */
246*24453Smckusick 	int         is_procname;
2478800Smckusick 
248*24453Smckusick 	type_code = lexi();	/* lexi reads one token.  The actual
249*24453Smckusick 				 * characters read are stored in "token".
250*24453Smckusick 				 * lexi returns a code indicating the type
251*24453Smckusick 				 * of token */
252*24453Smckusick 	is_procname = ps.procname[0];
2538800Smckusick 
254*24453Smckusick 	/*
255*24453Smckusick 	 * The following code moves everything following an if (), while
256*24453Smckusick 	 * (), else, etc. up to the start of the following stmt to a
257*24453Smckusick 	 * buffer.  This allows proper handling of both kinds of brace
258*24453Smckusick 	 * placement.
259*24453Smckusick 	 */
2608800Smckusick 
2618800Smckusick 	flushed_nl = false;
262*24453Smckusick 	while (ps.search_brace) {	/* if we scanned an if(), while(),
263*24453Smckusick 					 * etc., we might need to copy
264*24453Smckusick 					 * stuff into a buffer we must
265*24453Smckusick 					 * loop, copying stuff into
266*24453Smckusick 					 * save_com, until we find the
267*24453Smckusick 					 * start of the stmt which follows
268*24453Smckusick 					 * the if, or whatever */
2698800Smckusick 	    switch (type_code) {
270*24453Smckusick 		case newline:
2718800Smckusick 		    ++line_no;
2728800Smckusick 		    flushed_nl = true;
273*24453Smckusick 		case form_feed:
274*24453Smckusick 		    break;	/* form feeds and newlines found here will
275*24453Smckusick 				 * be ignored */
2768800Smckusick 
277*24453Smckusick 		case lbrace:	/* this is a brace that starts the
278*24453Smckusick 				 * compound stmt */
279*24453Smckusick 		    if (sc_end == 0) {	/* ignore buffering if a comment
280*24453Smckusick 					 * wasnt stored up */
281*24453Smckusick 			ps.search_brace = false;
2828800Smckusick 			goto check_type;
2838800Smckusick 		    }
2848800Smckusick 		    if (btype_2) {
285*24453Smckusick 			save_com[0] = '{';	/* we either want to put
286*24453Smckusick 						 * the brace right after
287*24453Smckusick 						 * the if */
288*24453Smckusick 			goto sw_buffer;	/* go to common code to get out of
289*24453Smckusick 					 * this loop */
2908800Smckusick 		    }
291*24453Smckusick 		case comment:	/* we have a comment, so we must copy it
292*24453Smckusick 				 * into the buffer */
293*24453Smckusick 		    if (!flushed_nl) {
294*24453Smckusick 			if (sc_end == 0) {	/* if this is the first
295*24453Smckusick 						 * comment, we must set up
296*24453Smckusick 						 * the buffer */
297*24453Smckusick 			    save_com[0] = save_com[1] = ' ';
298*24453Smckusick 			    sc_end = &(save_com[2]);
299*24453Smckusick 			} else {
300*24453Smckusick 			    *sc_end++ = '\n';	/* add newline between
301*24453Smckusick 						 * comments */
302*24453Smckusick 			    *sc_end++ = ' ';
303*24453Smckusick 			    --line_no;
304*24453Smckusick 			}
305*24453Smckusick 			*sc_end++ = '/';	/* copy in start of
306*24453Smckusick 						 * comment */
307*24453Smckusick 			*sc_end++ = '*';
3088800Smckusick 
309*24453Smckusick 			for (;;) {	/* loop until we get to the end of
310*24453Smckusick 					 * the comment */
311*24453Smckusick 			    *sc_end = *buf_ptr++;
312*24453Smckusick 			    if (buf_ptr >= buf_end)
313*24453Smckusick 				fill_buffer();
314*24453Smckusick 
315*24453Smckusick 			    if (*sc_end++ == '*' && *buf_ptr == '/')
316*24453Smckusick 				break;	/* we are at end of comment */
317*24453Smckusick 
318*24453Smckusick 			    if (sc_end >= &(save_com[sc_size])) {	/* check for temp buffer
319*24453Smckusick 									 * overflow */
320*24453Smckusick 				diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
321*24453Smckusick 				fflush(output);
322*24453Smckusick 				exit();
323*24453Smckusick 			    }
324*24453Smckusick 			}
325*24453Smckusick 			*sc_end++ = '/';	/* add ending slash */
326*24453Smckusick 			if (++buf_ptr >= buf_end)	/* get past / in buffer */
327*24453Smckusick 			    fill_buffer();
328*24453Smckusick 			break;
329*24453Smckusick 		    }
330*24453Smckusick 		default:	/* it is the start of a normal statment */
331*24453Smckusick 		    if (flushed_nl)	/* if we flushed a newline, make
332*24453Smckusick 					 * sure it is put back */
3338800Smckusick 			force_nl = true;
334*24453Smckusick 		    if (type_code == sp_paren && *token == 'i'
335*24453Smckusick 			&& last_else && ps.else_if
336*24453Smckusick 			|| type_code == sp_nparen && *token == 'e'
337*24453Smckusick 			&& e_code != s_code && e_code[-1] == '}')
338*24453Smckusick 			force_nl = false;
3398800Smckusick 
340*24453Smckusick 		    if (sc_end == 0) {	/* ignore buffering if comment
341*24453Smckusick 					 * wasnt saved up */
342*24453Smckusick 			ps.search_brace = false;
3438800Smckusick 			goto check_type;
3448800Smckusick 		    }
345*24453Smckusick 		    if (force_nl) {	/* if we should insert a nl here,
346*24453Smckusick 					 * put it into the buffer */
3478800Smckusick 			force_nl = false;
348*24453Smckusick 			--line_no;	/* this will be re-increased when
349*24453Smckusick 					 * the nl is read from the buffer */
3508800Smckusick 			*sc_end++ = '\n';
3518800Smckusick 			*sc_end++ = ' ';
352*24453Smckusick 			if (verbose && !flushed_nl)	/* print error msg if
353*24453Smckusick 							 * the line was not
354*24453Smckusick 							 * already broken */
355*24453Smckusick 			    diag(0, "Line broken");
3568800Smckusick 			flushed_nl = false;
3578800Smckusick 		    }
3588800Smckusick 		    for (t_ptr = token; *t_ptr; ++t_ptr)
359*24453Smckusick 			*sc_end++ = *t_ptr;	/* copy token into temp
360*24453Smckusick 						 * buffer */
3618800Smckusick 
362*24453Smckusick 	    sw_buffer:
363*24453Smckusick 		    ps.search_brace = false;	/* stop looking for start
364*24453Smckusick 						 * of stmt */
365*24453Smckusick 		    bp_save = buf_ptr;	/* save current input buffer */
3668800Smckusick 		    be_save = buf_end;
367*24453Smckusick 		    buf_ptr = save_com;	/* fix so that subsequent calls to
368*24453Smckusick 					 * lexi will take tokens out of
369*24453Smckusick 					 * save_com */
370*24453Smckusick 		    *sc_end++ = ' ';	/* add trailing blank, just in
371*24453Smckusick 					 * case */
3728800Smckusick 		    buf_end = sc_end;
3738800Smckusick 		    sc_end = 0;
3748800Smckusick 		    break;
375*24453Smckusick 	    }			/* end of switch */
376*24453Smckusick 	    if (type_code != 0)	/* we must make this check, just in case
377*24453Smckusick 				 * there was an unexpected EOF */
378*24453Smckusick 		type_code = lexi();	/* read another token */
379*24453Smckusick 	    is_procname = ps.procname[0];
380*24453Smckusick 	}			/* end of while (serach_brace) */
381*24453Smckusick 	last_else = 0;
382*24453Smckusick check_type:
383*24453Smckusick 	if (type_code == 0) {	/* we got eof */
3848800Smckusick 	    if (s_lab != e_lab || s_code != e_code
385*24453Smckusick 		|| s_com != e_com)	/* must dump end of line */
386*24453Smckusick 		dump_line();
387*24453Smckusick 	    if (ps.tos > 1)	/* check for balanced braces */
388*24453Smckusick 		diag(1, "Stuff missing from end of file.");
3898800Smckusick 
3908800Smckusick 	    if (verbose) {
391*24453Smckusick 		printf("There were %d output lines and %d comments\n",
392*24453Smckusick 		       ps.out_lines, ps.out_coms);
393*24453Smckusick 		printf("(Lines with comments)/(Lines with code): %6.3f\n",
394*24453Smckusick 		       (1.0 * ps.com_lines) / code_lines);
3958800Smckusick 	    }
396*24453Smckusick 	    fflush(output);
397*24453Smckusick 	    exit();
3988800Smckusick 	}
3998800Smckusick 	if (
400*24453Smckusick 	    (type_code != comment) &&
401*24453Smckusick 	    (type_code != newline) &&
402*24453Smckusick 	    (type_code != preesc) &&
403*24453Smckusick 	    (type_code != form_feed)) {
4048800Smckusick 	    if (
405*24453Smckusick 		force_nl
406*24453Smckusick 		&&
407*24453Smckusick 		(type_code != semicolon) &&
408*24453Smckusick 		(
409*24453Smckusick 		 type_code != lbrace
410*24453Smckusick 		 ||
411*24453Smckusick 		 !btype_2
412*24453Smckusick 		 )) {		/* we should force a broken line here */
4138800Smckusick 		if (verbose && !flushed_nl)
414*24453Smckusick 		    diag(0, "Line broken");
4158800Smckusick 		flushed_nl = false;
416*24453Smckusick 		dump_line();
417*24453Smckusick 		ps.want_blank = false;	/* dont insert blank at line start */
4188800Smckusick 		force_nl = false;
4198800Smckusick 	    }
420*24453Smckusick 	    ps.in_stmt = true;	/* turn on flag which causes an extra
421*24453Smckusick 				 * level of indentation. this is turned
422*24453Smckusick 				 * off by a ; or '}' */
423*24453Smckusick 	    if (s_com != e_com) {	/* the turkey has embedded a
424*24453Smckusick 					 * comment in a line. fix it */
4258800Smckusick 		*e_code++ = ' ';
4268800Smckusick 		for (t_ptr = s_com; *t_ptr; ++t_ptr)
4278800Smckusick 		    *e_code++ = *t_ptr;
4288800Smckusick 		*e_code++ = ' ';
429*24453Smckusick 		*e_code = '\0';	/* null terminate code sect */
430*24453Smckusick 		ps.want_blank = false;
4318800Smckusick 		e_com = s_com;
4328800Smckusick 	    }
433*24453Smckusick 	} else if (type_code != comment)	/* preserve force_nl thru
434*24453Smckusick 						 * a comment */
435*24453Smckusick 	    force_nl = false;
4368800Smckusick 
437*24453Smckusick 	/*
438*24453Smckusick 	 * cancel forced newline after newline, form feed, etc
439*24453Smckusick 	 */
4408800Smckusick 
4418800Smckusick 
4428800Smckusick 
443*24453Smckusick 	/*----------------------------------------------------*\
444*24453Smckusick |   do switch on type of token scanned
445*24453Smckusick \*----------------------------------------------------*/
446*24453Smckusick 	switch (type_code) {	/* now, decide what to do with the token */
447*24453Smckusick 
448*24453Smckusick 	    case form_feed:	/* found a form feed in line */
449*24453Smckusick 		ps.use_ff = true;	/* a form feed is treated much
450*24453Smckusick 					 * like a newline */
451*24453Smckusick 		dump_line();
452*24453Smckusick 		ps.want_blank = false;
4538800Smckusick 		break;
4548800Smckusick 
455*24453Smckusick 	    case newline:
456*24453Smckusick 		if (ps.last_token != comma || ps.p_l_follow > 0
457*24453Smckusick 		    || !ps.leave_comma || !break_comma || s_com != e_com) {
458*24453Smckusick 		    dump_line();
459*24453Smckusick 		    ps.want_blank = false;
460*24453Smckusick 		}
461*24453Smckusick 		++line_no;	/* keep track of input line number */
4628800Smckusick 		break;
4638800Smckusick 
464*24453Smckusick 	    case lparen:	/* got a '(' or '[' */
465*24453Smckusick 		++ps.p_l_follow;/* count parens to make Healy happy */
466*24453Smckusick 		if (ps.want_blank && *token != '[' &&
467*24453Smckusick 		    (ps.last_token != ident || proc_calls_space
468*24453Smckusick 		     || (ps.its_a_keyword && !ps.sizeof_keyword)))
4698800Smckusick 		    *e_code++ = ' ';
470*24453Smckusick 		if (ps.in_decl && !ps.block_init)
471*24453Smckusick 		    if (troff && !ps.dumped_decl_indent) {
472*24453Smckusick 			ps.dumped_decl_indent = 1;
473*24453Smckusick 			sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
474*24453Smckusick 			e_code += strlen(e_code);
475*24453Smckusick 		    } else {
476*24453Smckusick 			while ((e_code - s_code) < dec_ind)
477*24453Smckusick 			    *e_code++ = ' ';
478*24453Smckusick 			*e_code++ = token[0];
479*24453Smckusick 		} else
480*24453Smckusick 		    *e_code++ = token[0];
481*24453Smckusick 		ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
482*24453Smckusick 		ps.want_blank = false;
483*24453Smckusick 		if (ps.in_or_st && *token == '(') {
4848800Smckusick 
485*24453Smckusick 		    /*
486*24453Smckusick 		     * this is a kluge to make sure that declarations will
487*24453Smckusick 		     * be aligned right if proc decl has an explicit type
488*24453Smckusick 		     * on it, i.e. "int a(x) {..."
489*24453Smckusick 		     */
490*24453Smckusick 		    parse(semicolon);	/* I said this was a kluge... */
491*24453Smckusick 		    ps.in_or_st = false;	/* turn off flag for
492*24453Smckusick 						 * structure decl or
493*24453Smckusick 						 * initialization */
4948800Smckusick 		}
495*24453Smckusick 		if (ps.sizeof_keyword) ps.sizeof_mask |= 1<<ps.p_l_follow;
4968800Smckusick 		break;
4978800Smckusick 
498*24453Smckusick 	    case rparen:	/* got a ')' or ']' */
499*24453Smckusick 		if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
500*24453Smckusick 		    ps.last_u_d = true;
501*24453Smckusick 		    ps.cast_mask &= (1 << ps.p_l_follow) - 1;
5028800Smckusick 		}
503*24453Smckusick 		ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
504*24453Smckusick 		if (--ps.p_l_follow < 0) {
505*24453Smckusick 		    ps.p_l_follow = 0;
506*24453Smckusick 		    diag(0, "Extra %c", *token);
507*24453Smckusick 		}
508*24453Smckusick 		if (e_code == s_code)	/* if the paren starts the line */
509*24453Smckusick 		    ps.paren_level = ps.p_l_follow;	/* then indent it */
5108800Smckusick 
5118800Smckusick 		*e_code++ = token[0];
512*24453Smckusick 		ps.want_blank = true;
5138800Smckusick 
514*24453Smckusick 		if (sp_sw && (ps.p_l_follow == 0)) {	/* check for end of if
515*24453Smckusick 							 * (...), or some such */
5168800Smckusick 		    sp_sw = false;
517*24453Smckusick 		    force_nl = true;	/* must force newline after if */
518*24453Smckusick 		    ps.last_u_d = true;	/* inform lexi that a following
519*24453Smckusick 					 * operator is unary */
520*24453Smckusick 		    ps.in_stmt = false;	/* dont use stmt continuation
521*24453Smckusick 					 * indentation */
5228800Smckusick 
523*24453Smckusick 		    parse(hd_type);	/* let parser worry about if, or
524*24453Smckusick 					 * whatever */
5258800Smckusick 		}
526*24453Smckusick 		ps.search_brace = btype_2;	/* this should insure that
527*24453Smckusick 						 * constructs such as
528*24453Smckusick 						 * main(){...} and
529*24453Smckusick 						 * int[]{...} have their
530*24453Smckusick 						 * braces put in the right
531*24453Smckusick 						 * place */
5328800Smckusick 		break;
5338800Smckusick 
534*24453Smckusick 	    case unary_op:	/* this could be any unary operation */
535*24453Smckusick 		if (ps.want_blank)
5368800Smckusick 		    *e_code++ = ' ';
5378800Smckusick 
538*24453Smckusick 		if (troff && !ps.dumped_decl_indent && ps.in_decl) {
539*24453Smckusick 		    sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
540*24453Smckusick 		    ps.dumped_decl_indent = 1;
541*24453Smckusick 		    e_code += strlen(e_code);
542*24453Smckusick 		} else {
543*24453Smckusick 		    char       *res = token;
544*24453Smckusick 
545*24453Smckusick 		    if (ps.in_decl && !ps.block_init) {	/* if this is a unary op
546*24453Smckusick 							 * in a declaration, we
547*24453Smckusick 							 * should indent this
548*24453Smckusick 							 * token */
549*24453Smckusick 			for (i = 0; token[i]; ++i);	/* find length of token */
550*24453Smckusick 			while ((e_code - s_code) < (dec_ind - i))
551*24453Smckusick 			    *e_code++ = ' ';	/* pad it */
552*24453Smckusick 		    }
553*24453Smckusick 		    if (troff && token[0] == '-' && token[1] == '>')
554*24453Smckusick 			res = "\\(->";
555*24453Smckusick 		    for (t_ptr = res; *t_ptr; ++t_ptr)
556*24453Smckusick 			*e_code++ = *t_ptr;
5578800Smckusick 		}
558*24453Smckusick 		ps.want_blank = false;
5598800Smckusick 		break;
5608800Smckusick 
561*24453Smckusick 	    case binary_op:	/* any binary operation */
562*24453Smckusick 	do_binary:
563*24453Smckusick 		if (ps.want_blank)
5648800Smckusick 		    *e_code++ = ' ';
565*24453Smckusick 		{
566*24453Smckusick 		    char       *res = token;
567*24453Smckusick 
568*24453Smckusick 		    if (troff)
569*24453Smckusick 			switch (token[0]) {
570*24453Smckusick 			    case '<':
571*24453Smckusick 				if (token[1] == '=')
572*24453Smckusick 				    res = "\\(<=";
573*24453Smckusick 				break;
574*24453Smckusick 			    case '>':
575*24453Smckusick 				if (token[1] == '=')
576*24453Smckusick 				    res = "\\(>=";
577*24453Smckusick 				break;
578*24453Smckusick 			    case '!':
579*24453Smckusick 				if (token[1] == '=')
580*24453Smckusick 				    res = "\\(!=";
581*24453Smckusick 				break;
582*24453Smckusick 			    case '|':
583*24453Smckusick 				if (token[1] == '|')
584*24453Smckusick 				    res = "\\(br\\(br";
585*24453Smckusick 				else if (token[1] == 0)
586*24453Smckusick 				    res = "\\(br";
587*24453Smckusick 				break;
588*24453Smckusick 			}
589*24453Smckusick 		    for (t_ptr = res; *t_ptr; ++t_ptr)
590*24453Smckusick 			*e_code++ = *t_ptr;	/* move the operator */
591*24453Smckusick 		}
592*24453Smckusick 		ps.want_blank = true;
5938800Smckusick 		break;
5948800Smckusick 
595*24453Smckusick 	    case postop:	/* got a trailing ++ or -- */
5968800Smckusick 		*e_code++ = token[0];
5978800Smckusick 		*e_code++ = token[1];
598*24453Smckusick 		ps.want_blank = true;
5998800Smckusick 		break;
6008800Smckusick 
601*24453Smckusick 	    case question:	/* got a ? */
602*24453Smckusick 		squest++;	/* this will be used when a later colon
603*24453Smckusick 				 * appears so we can distinguish the
604*24453Smckusick 				 * <c>?<n>:<n> construct */
605*24453Smckusick 		if (ps.want_blank)
6068800Smckusick 		    *e_code++ = ' ';
6078800Smckusick 		*e_code++ = '?';
608*24453Smckusick 		ps.want_blank = true;
6098800Smckusick 		break;
6108800Smckusick 
611*24453Smckusick 	    case casestmt:	/* got word 'case' or 'default' */
612*24453Smckusick 		scase = true;	/* so we can process the later colon
613*24453Smckusick 				 * properly */
614*24453Smckusick 		goto copy_id;
6158800Smckusick 
616*24453Smckusick 	    case colon:	/* got a ':' */
617*24453Smckusick 		if (squest > 0) {	/* it is part of the <c>?<n>: <n>
618*24453Smckusick 					 * construct */
6198800Smckusick 		    --squest;
620*24453Smckusick 		    if (ps.want_blank)
6218800Smckusick 			*e_code++ = ' ';
6228800Smckusick 		    *e_code++ = ':';
623*24453Smckusick 		    ps.want_blank = true;
6248800Smckusick 		    break;
6258800Smckusick 		}
626*24453Smckusick 		if (ps.in_decl) {
627*24453Smckusick 		    *e_code++ = ':';
628*24453Smckusick 		    ps.want_blank = false;
629*24453Smckusick 		    break;
630*24453Smckusick 		}
631*24453Smckusick 		ps.in_stmt = false;	/* seeing a label does not imply
632*24453Smckusick 					 * we are in a stmt */
6338800Smckusick 		for (t_ptr = s_code; *t_ptr; ++t_ptr)
634*24453Smckusick 		    *e_lab++ = *t_ptr;	/* turn everything so far into a
635*24453Smckusick 					 * label */
6368800Smckusick 		e_code = s_code;
6378800Smckusick 		*e_lab++ = ':';
6388800Smckusick 		*e_lab++ = ' ';
6398800Smckusick 		*e_lab = '\0';
6408800Smckusick 
641*24453Smckusick 		force_nl = ps.pcase = scase;	/* ps.pcase will be used
642*24453Smckusick 						 * by dump_line to decide
643*24453Smckusick 						 * how to indent the
644*24453Smckusick 						 * label. force_nl will
645*24453Smckusick 						 * force a case n: to be
646*24453Smckusick 						 * on a line by itself */
6478800Smckusick 		scase = false;
648*24453Smckusick 		ps.want_blank = false;
6498800Smckusick 		break;
6508800Smckusick 
651*24453Smckusick 	    case semicolon:	/* got a ';' */
652*24453Smckusick 		ps.in_or_st = false;	/* we are not in an initialization
653*24453Smckusick 					 * or structure declaration */
654*24453Smckusick 		scase = false;	/* these will only need resetting in a
655*24453Smckusick 				 * error */
6568800Smckusick 		squest = 0;
657*24453Smckusick 		if (ps.last_token == rparen)
658*24453Smckusick 		    ps.in_parameter_declaration = 0;
659*24453Smckusick 		ps.cast_mask = 0;
660*24453Smckusick 		ps.sizeof_mask = 0;
661*24453Smckusick 		ps.block_init = 0;
662*24453Smckusick 		ps.just_saw_decl--;
6638800Smckusick 
664*24453Smckusick 		if (ps.in_decl && s_code == e_code && !ps.block_init)
6658800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
6668800Smckusick 			*e_code++ = ' ';
6678800Smckusick 
668*24453Smckusick 		ps.in_decl = (ps.dec_nest > 0);	/* if we were in a first
669*24453Smckusick 						 * level structure
670*24453Smckusick 						 * declaration, we arent
671*24453Smckusick 						 * any more */
6728800Smckusick 
673*24453Smckusick 		if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
674*24453Smckusick 
675*24453Smckusick 		    /*
676*24453Smckusick 		     * This should be true iff there were unbalanced
677*24453Smckusick 		     * parens in the stmt.  It is a bit complicated,
678*24453Smckusick 		     * because the semicolon might be in a for stmt
679*24453Smckusick 		     */
680*24453Smckusick 		    diag(1, "Unbalanced parens");
681*24453Smckusick 		    ps.p_l_follow = 0;
682*24453Smckusick 		    if (sp_sw) {/* this is a check for a if, while, etc.
683*24453Smckusick 				 * with unbalanced parens */
6848800Smckusick 			sp_sw = false;
685*24453Smckusick 			parse(hd_type);	/* dont lose the if, or whatever */
6868800Smckusick 		    }
6878800Smckusick 		}
6888800Smckusick 		*e_code++ = ';';
689*24453Smckusick 		ps.want_blank = true;
690*24453Smckusick 		ps.in_stmt = (ps.p_l_follow > 0);	/* we are no longer in
691*24453Smckusick 							 * the middle of a stmt */
6928800Smckusick 
693*24453Smckusick 		if (!sp_sw) {	/* if not if for (;;) */
694*24453Smckusick 		    parse(semicolon);	/* let parser know about end of
695*24453Smckusick 					 * stmt */
696*24453Smckusick 		    force_nl = true;	/* force newline after a end of
697*24453Smckusick 					 * stmt */
6988800Smckusick 		}
6998800Smckusick 		break;
7008800Smckusick 
701*24453Smckusick 	    case lbrace:	/* got a '{' */
702*24453Smckusick 		ps.in_stmt = false;	/* dont indent the {} */
703*24453Smckusick 		if (!ps.block_init)
704*24453Smckusick 		    force_nl = true;	/* force other stuff on same line
705*24453Smckusick 					 * as '{' onto new line */
7068800Smckusick 
707*24453Smckusick 		if (s_code != e_code && !ps.block_init) {
708*24453Smckusick 		    if (!btype_2) {
709*24453Smckusick 			dump_line();
710*24453Smckusick 			ps.want_blank = false;
711*24453Smckusick 		    } else if (ps.in_parameter_declaration && !ps.in_or_st) {
712*24453Smckusick 			ps.i_l_follow = 0;
713*24453Smckusick 			dump_line();
714*24453Smckusick 			ps.want_blank = false;
715*24453Smckusick 		    }
7168800Smckusick 		}
717*24453Smckusick 		if (ps.in_parameter_declaration)
718*24453Smckusick 		    prefix_blankline_requested = 0;
7198800Smckusick 
720*24453Smckusick 		if (ps.p_l_follow > 0) {	/* check for preceeding
721*24453Smckusick 						 * unbalanced parens */
722*24453Smckusick 		    diag(1, "Unbalanced parens");
723*24453Smckusick 		    ps.p_l_follow = 0;
724*24453Smckusick 		    if (sp_sw) {/* check for unclosed if, for, etc. */
7258800Smckusick 			sp_sw = false;
726*24453Smckusick 			parse(hd_type);
727*24453Smckusick 			ps.ind_level = ps.i_l_follow;
7288800Smckusick 		    }
7298800Smckusick 		}
7308800Smckusick 		if (s_code == e_code)
731*24453Smckusick 		    ps.ind_stmt = false;	/* dont put extra
732*24453Smckusick 						 * indentation on line
733*24453Smckusick 						 * with '{' */
734*24453Smckusick 		if (ps.in_decl && ps.in_or_st) {	/* this is either a
735*24453Smckusick 							 * structure declaration
736*24453Smckusick 							 * or an init */
737*24453Smckusick 		    di_stack[ps.dec_nest++] = dec_ind;
7388800Smckusick 		    dec_ind = 0;
739*24453Smckusick 		} else {
740*24453Smckusick 		    ps.decl_on_line = false;	/* we cant be in the
741*24453Smckusick 						 * middle of a
742*24453Smckusick 						 * declaration, so dont do
743*24453Smckusick 						 * special indentation of
744*24453Smckusick 						 * comments */
745*24453Smckusick 		    ps.in_parameter_declaration = 0;
7468800Smckusick 		}
747*24453Smckusick 		parse(lbrace);	/* let parser know about this */
748*24453Smckusick 		if (ps.want_blank)	/* put a blank before '{' if '{'
749*24453Smckusick 					 * is not at start of line */
7508800Smckusick 		    *e_code++ = ' ';
751*24453Smckusick 		ps.want_blank = false;
7528800Smckusick 		*e_code++ = '{';
753*24453Smckusick 		ps.just_saw_decl = 0;
7548800Smckusick 		break;
7558800Smckusick 
756*24453Smckusick 	    case rbrace:	/* got a '}' */
757*24453Smckusick 		if (ps.p_l_follow) {	/* check for unclosed if, for,
758*24453Smckusick 					 * else. */
759*24453Smckusick 		    diag(1, "Unbalanced parens");
760*24453Smckusick 		    ps.p_l_follow = 0;
7618800Smckusick 		    sp_sw = false;
7628800Smckusick 		}
763*24453Smckusick 		ps.just_saw_decl = 0;
764*24453Smckusick 		if (s_code != e_code && !ps.block_init) {	/* '}' must be first on
765*24453Smckusick 								 * line */
7668800Smckusick 		    if (verbose)
767*24453Smckusick 			diag(0, "Line broken");
768*24453Smckusick 		    dump_line();
7698800Smckusick 		}
7708800Smckusick 		*e_code++ = '}';
771*24453Smckusick 		ps.want_blank = true;
772*24453Smckusick 		ps.in_stmt = ps.ind_stmt = false;
773*24453Smckusick 		if (ps.dec_nest > 0) {	/* we are in multi-level structure
774*24453Smckusick 					 * declaration */
775*24453Smckusick 		    dec_ind = di_stack[--ps.dec_nest];
776*24453Smckusick 		    if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
777*24453Smckusick 			ps.just_saw_decl = 2;
778*24453Smckusick 		    ps.in_decl = true;
7798800Smckusick 		}
780*24453Smckusick 		prefix_blankline_requested = 0;
781*24453Smckusick 		parse(rbrace);	/* let parser know about this */
782*24453Smckusick 		ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level;
783*24453Smckusick 		if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
784*24453Smckusick 		    postfix_blankline_requested = 1;
7858800Smckusick 		break;
7868800Smckusick 
787*24453Smckusick 	    case swstmt:	/* got keyword "switch" */
7888800Smckusick 		sp_sw = true;
789*24453Smckusick 		hd_type = swstmt;	/* keep this for when we have seen
790*24453Smckusick 					 * the expression */
791*24453Smckusick 		goto copy_id;	/* go move the token into buffer */
7928800Smckusick 
793*24453Smckusick 	    case sp_paren:	/* token is if, while, for */
794*24453Smckusick 		sp_sw = true;	/* the interesting stuff is done after the
795*24453Smckusick 				 * expression is scanned */
7968800Smckusick 		hd_type = (*token == 'i' ? ifstmt :
797*24453Smckusick 			   (*token == 'w' ? whilestmt : forstmt));
7988800Smckusick 
799*24453Smckusick 		/*
800*24453Smckusick 		 * remember the type of header for later use by parser
801*24453Smckusick 		 */
802*24453Smckusick 		goto copy_id;	/* copy the token into line */
803*24453Smckusick 
804*24453Smckusick 	    case sp_nparen:	/* got else, do */
805*24453Smckusick 		ps.in_stmt = false;
806*24453Smckusick 		if (*token == 'e') {
807*24453Smckusick 		    if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
808*24453Smckusick 			if (verbose)
809*24453Smckusick 			    diag(0, "Line broken");
810*24453Smckusick 			dump_line();	/* make sure this starts a line */
811*24453Smckusick 			ps.want_blank = false;
812*24453Smckusick 		    }
813*24453Smckusick 		    force_nl = true;	/* also, following stuff must go
814*24453Smckusick 					 * onto new line */
815*24453Smckusick 		    last_else = 1;
816*24453Smckusick 		    parse(elselit);
817*24453Smckusick 		} else {
818*24453Smckusick 		    if (e_code != s_code) {	/* make sure this starts a
819*24453Smckusick 						 * line */
820*24453Smckusick 			if (verbose)
821*24453Smckusick 			    diag(0, "Line broken");
822*24453Smckusick 			dump_line();
823*24453Smckusick 			ps.want_blank = false;
824*24453Smckusick 		    }
825*24453Smckusick 		    force_nl = true;	/* also, following stuff must go
826*24453Smckusick 					 * onto new line */
827*24453Smckusick 		    last_else = 0;
828*24453Smckusick 		    parse(dolit);
8298800Smckusick 		}
830*24453Smckusick 		goto copy_id;	/* move the token into line */
8318800Smckusick 
832*24453Smckusick 	    case decl:		/* we have a declaration type (int,
833*24453Smckusick 				 * register, etc.) */
834*24453Smckusick 		parse(decl);	/* let parser worry about indentation */
835*24453Smckusick 		if (ps.last_token == rparen && ps.tos <= 1)
836*24453Smckusick 		    ps.in_parameter_declaration = 1;
837*24453Smckusick 		if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
838*24453Smckusick 		    ps.ind_level = ps.i_l_follow = 1;
839*24453Smckusick 		    ps.ind_stmt = 0;
840*24453Smckusick 		}
841*24453Smckusick 		ps.in_or_st = true;	/* this might be a structure or
842*24453Smckusick 					 * initialization declaration */
843*24453Smckusick 		ps.in_decl = ps.decl_on_line = true;
844*24453Smckusick 		if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
845*24453Smckusick 		    ps.just_saw_decl = 2;
846*24453Smckusick 		prefix_blankline_requested = 0;
847*24453Smckusick 		for (i = 0; token[i++];);	/* get length of token */
8488800Smckusick 
849*24453Smckusick 		/*
850*24453Smckusick 		 * dec_ind = e_code - s_code + (ps.decl_indent>i ?
851*24453Smckusick 		 * ps.decl_indent : i);
852*24453Smckusick 		 */
853*24453Smckusick 		dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
8548800Smckusick 		goto copy_id;
8558800Smckusick 
856*24453Smckusick 	    case ident:	/* got an identifier or constant */
857*24453Smckusick 		if (ps.in_decl) {	/* if we are in a declaration, we
858*24453Smckusick 					 * must indent identifier */
859*24453Smckusick 		    if (ps.want_blank)
8608800Smckusick 			*e_code++ = ' ';
861*24453Smckusick 		    ps.want_blank = false;
862*24453Smckusick 		    if (is_procname == 0 || !procnames_start_line) {
863*24453Smckusick 			if (!ps.block_init)
864*24453Smckusick 			    if (troff && !ps.dumped_decl_indent) {
865*24453Smckusick 				sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7);
866*24453Smckusick 				ps.dumped_decl_indent = 1;
867*24453Smckusick 				e_code += strlen(e_code);
868*24453Smckusick 			    } else
869*24453Smckusick 				while ((e_code - s_code) < dec_ind)
870*24453Smckusick 				    *e_code++ = ' ';
871*24453Smckusick 		    } else {
872*24453Smckusick 			if (dec_ind && s_code != e_code)
873*24453Smckusick 			    dump_line();
874*24453Smckusick 			dec_ind = 0;
875*24453Smckusick 			ps.want_blank = false;
876*24453Smckusick 		    }
877*24453Smckusick 		} else if (sp_sw && ps.p_l_follow == 0) {
878*24453Smckusick 		    sp_sw = false;
879*24453Smckusick 		    force_nl = true;
880*24453Smckusick 		    ps.last_u_d = true;
881*24453Smckusick 		    ps.in_stmt = false;
882*24453Smckusick 		    parse(hd_type);
8838800Smckusick 		}
884*24453Smckusick 	copy_id:
885*24453Smckusick 		if (ps.want_blank)
8868800Smckusick 		    *e_code++ = ' ';
887*24453Smckusick 		if (troff && ps.its_a_keyword) {
888*24453Smckusick 		    *e_code++ = BACKSLASH;
889*24453Smckusick 		    *e_code++ = 'f';
890*24453Smckusick 		    *e_code++ = 'B';
891*24453Smckusick 		}
8928800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
8938800Smckusick 		    *e_code++ = *t_ptr;
894*24453Smckusick 		if (troff && ps.its_a_keyword) {
895*24453Smckusick 		    *e_code++ = BACKSLASH;
896*24453Smckusick 		    *e_code++ = 'f';
897*24453Smckusick 		    *e_code++ = 'R';
898*24453Smckusick 		}
899*24453Smckusick 		ps.want_blank = true;
9008800Smckusick 		break;
9018800Smckusick 
902*24453Smckusick 	    case period:	/* treat a period kind of like a binary
903*24453Smckusick 				 * operation */
904*24453Smckusick 		*e_code++ = '.';/* move the period into line */
905*24453Smckusick 		ps.want_blank = false;	/* dont put a blank after a period */
9068800Smckusick 		break;
9078800Smckusick 
908*24453Smckusick 	    case comma:
909*24453Smckusick 		ps.want_blank = (s_code != e_code);	/* only put blank after
910*24453Smckusick 							 * comma if comma does
911*24453Smckusick 							 * not start the line */
912*24453Smckusick 		if (ps.in_decl && is_procname == 0 && !ps.block_init)
9138800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
9148800Smckusick 			*e_code++ = ' ';
9158800Smckusick 
9168800Smckusick 		*e_code++ = ',';
917*24453Smckusick 		if (ps.p_l_follow == 0) {
918*24453Smckusick 		    ps.block_init = 0;
919*24453Smckusick 		    if (break_comma && !ps.leave_comma)
920*24453Smckusick 			force_nl = true;
921*24453Smckusick 		}
9228800Smckusick 		break;
9238800Smckusick 
924*24453Smckusick 	    case preesc:	/* got the character '#' */
925*24453Smckusick 		if ((s_com != e_com) ||
926*24453Smckusick 		    (s_lab != e_lab) ||
927*24453Smckusick 		    (s_code != e_code))
928*24453Smckusick 		    dump_line();
929*24453Smckusick 		*e_lab++ = '#';	/* move whole line to 'label' buffer */
930*24453Smckusick 		{
931*24453Smckusick 		    int         in_comment = 0;
932*24453Smckusick 		    char       *com_start = 0;
933*24453Smckusick 		    char        quote = 0;
934*24453Smckusick 		    char       *com_end = 0;
9358800Smckusick 
936*24453Smckusick 		    while (*buf_ptr != '\n' || in_comment) {
937*24453Smckusick 			*e_lab = *buf_ptr++;
938*24453Smckusick 			if (buf_ptr >= buf_end)
939*24453Smckusick 			    fill_buffer();
940*24453Smckusick 			switch (*e_lab++) {
941*24453Smckusick 			    case BACKSLASH:
942*24453Smckusick 				if (troff)
943*24453Smckusick 				    *e_lab++ = BACKSLASH;
944*24453Smckusick 				if (!in_comment) {
945*24453Smckusick 				    *e_lab++ = *buf_ptr++;
946*24453Smckusick 				    if (buf_ptr >= buf_end)
947*24453Smckusick 					fill_buffer();
948*24453Smckusick 				}
949*24453Smckusick 				break;
950*24453Smckusick 			    case '/':
951*24453Smckusick 				if (*buf_ptr == '*' && !in_comment && !quote) {
952*24453Smckusick 				    in_comment = 1;
953*24453Smckusick 				    *e_lab++ = *buf_ptr++;
954*24453Smckusick 				    com_start = e_lab - 2;
955*24453Smckusick 				}
956*24453Smckusick 				break;
957*24453Smckusick 			    case '"':
958*24453Smckusick 				if (quote == '"')
959*24453Smckusick 				    quote = 0;
960*24453Smckusick 				break;
961*24453Smckusick 			    case '\'':
962*24453Smckusick 				if (quote == '\'')
963*24453Smckusick 				    quote = 0;
964*24453Smckusick 				break;
965*24453Smckusick 			    case '*':
966*24453Smckusick 				if (*buf_ptr == '/' && in_comment) {
967*24453Smckusick 				    in_comment = 0;
968*24453Smckusick 				    *e_lab++ = *buf_ptr++;
969*24453Smckusick 				    com_end = e_lab;
970*24453Smckusick 				}
971*24453Smckusick 				break;
972*24453Smckusick 			}
9738800Smckusick 		    }
974*24453Smckusick 		    while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
975*24453Smckusick 			e_lab--;
976*24453Smckusick 		    if (e_lab == com_end && bp_save == 0) {	/* comment on
977*24453Smckusick 								 * preprocessor line */
978*24453Smckusick 			if (sc_end == 0)	/* if this is the first
979*24453Smckusick 						 * comment, we must set up
980*24453Smckusick 						 * the buffer */
981*24453Smckusick 			    sc_end = &(save_com[0]);
982*24453Smckusick 			else {
983*24453Smckusick 			    *sc_end++ = '\n';	/* add newline between
984*24453Smckusick 						 * comments */
985*24453Smckusick 			    *sc_end++ = ' ';
986*24453Smckusick 			    --line_no;
987*24453Smckusick 			}
988*24453Smckusick 			bcopy(com_start, sc_end, com_end - com_start);
989*24453Smckusick 			sc_end += com_end - com_start;
990*24453Smckusick 			e_lab = com_start;
991*24453Smckusick 			while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
992*24453Smckusick 			    e_lab--;
993*24453Smckusick 			bp_save = buf_ptr;	/* save current input
994*24453Smckusick 						 * buffer */
995*24453Smckusick 			be_save = buf_end;
996*24453Smckusick 			buf_ptr = save_com;	/* fix so that subsequent
997*24453Smckusick 						 * calls to lexi will take
998*24453Smckusick 						 * tokens out of save_com */
999*24453Smckusick 			*sc_end++ = ' ';	/* add trailing blank,
1000*24453Smckusick 						 * just in case */
1001*24453Smckusick 			buf_end = sc_end;
1002*24453Smckusick 			sc_end = 0;
1003*24453Smckusick 		    }
1004*24453Smckusick 		    *e_lab = '\0';	/* null terminate line */
1005*24453Smckusick 		    ps.pcase = false;
10068800Smckusick 		}
1007*24453Smckusick 		if (strncmp(s_lab, "#if", 3) == 0)
1008*24453Smckusick 		    if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
1009*24453Smckusick 			match_state[ifdef_level].tos = -1;
1010*24453Smckusick 			state_stack[ifdef_level++] = ps;
1011*24453Smckusick 		    } else
1012*24453Smckusick 			diag(1, "#if stack overflow");
1013*24453Smckusick 		else if (strncmp(s_lab, "#else", 5) == 0)
1014*24453Smckusick 		    if (ifdef_level <= 0)
1015*24453Smckusick 			diag(1, "Unmatched #else");
1016*24453Smckusick 		    else {
1017*24453Smckusick 			match_state[ifdef_level - 1] = ps;
1018*24453Smckusick 			ps = state_stack[ifdef_level - 1];
1019*24453Smckusick 		} else if (strncmp(s_lab, "#endif", 6) == 0)
1020*24453Smckusick 		    if (ifdef_level <= 0)
1021*24453Smckusick 			diag(1, "Unmatched #endif");
1022*24453Smckusick 		    else {
1023*24453Smckusick 			ifdef_level--;
1024*24453Smckusick #ifdef undef
10258800Smckusick 
1026*24453Smckusick 			/*
1027*24453Smckusick 			 * This match needs to be more intelligent before
1028*24453Smckusick 			 * the message is useful
1029*24453Smckusick 			 */
1030*24453Smckusick 			if (match_state[ifdef_level].tos >= 0
1031*24453Smckusick 			    && bcmp(&ps, &match_state[ifdef_level], sizeof ps))
1032*24453Smckusick 			    diag(0, "Syntactically inconsistant #ifdef alternatives.");
1033*24453Smckusick #endif
1034*24453Smckusick 		    }
1035*24453Smckusick 		break;		/* subsequent processing of the newline
1036*24453Smckusick 				 * character will cause the line to be
1037*24453Smckusick 				 * printed */
10388800Smckusick 
1039*24453Smckusick 	    case comment:	/* we have gotten a /*  this is a biggie */
1040*24453Smckusick 	proc_comment:
1041*24453Smckusick 		if (flushed_nl) {	/* we should force a broken line
1042*24453Smckusick 					 * here */
1043*24453Smckusick 		    flushed_nl = false;
1044*24453Smckusick 		    dump_line();
1045*24453Smckusick 		    ps.want_blank = false;	/* dont insert blank at
1046*24453Smckusick 						 * line start */
1047*24453Smckusick 		    force_nl = false;
1048*24453Smckusick 		}
1049*24453Smckusick 		pr_comment();
10508800Smckusick 		break;
1051*24453Smckusick 	}			/* end of big switch stmt */
1052*24453Smckusick 	*e_code = '\0';		/* make sure code section is null
1053*24453Smckusick 				 * terminated */
1054*24453Smckusick 	if (type_code != comment && type_code != newline && type_code != preesc)
1055*24453Smckusick 	    ps.last_token = type_code;
1056*24453Smckusick     }				/* end of main while (1) loop */
10578800Smckusick };
10588800Smckusick 
10598800Smckusick /*
1060*24453Smckusick  * copy input file to backup file if in_name is /blah/blah/blah/file, then
1061*24453Smckusick  * backup file will be ".Bfile" then make the backup file the input and
1062*24453Smckusick  * original input file the output
10638800Smckusick  */
1064*24453Smckusick bakcopy()
1065*24453Smckusick {
1066*24453Smckusick     int         n,
1067*24453Smckusick                 bakchn;
1068*24453Smckusick     char        buff[512];
1069*24453Smckusick     register char *p;
10708800Smckusick 
1071*24453Smckusick     /* construct file name .Bfile */
1072*24453Smckusick     for (p = in_name; *p; p++);	/* skip to end of string */
1073*24453Smckusick     while (p > in_name && *p != '/')	/* find last '/' */
10748800Smckusick 	p--;
10758800Smckusick     if (*p == '/')
10768800Smckusick 	p++;
1077*24453Smckusick     sprintf(bakfile, "%s.BAK", p);
10788800Smckusick 
1079*24453Smckusick     /* copy in_name to backup file */
1080*24453Smckusick     bakchn = creat(bakfile, 0600);
10818800Smckusick     if (bakchn < 0) {
1082*24453Smckusick 	printf("can't create backup file \"%s\"\n", bakfile);
1083*24453Smckusick 	exit();
10848800Smckusick     }
1085*24453Smckusick     while (n = read(fileno(input), buff, 512))
1086*24453Smckusick 	write(bakchn, buff, n);
1087*24453Smckusick     close(bakchn);
1088*24453Smckusick     fclose(input);
10898800Smckusick 
1090*24453Smckusick     /* re-open backup file as the input file */
1091*24453Smckusick     input = fopen(bakfile, "r");
10928800Smckusick     if (input < 0) {
1093*24453Smckusick 	printf("can't re-open backup file\n");
1094*24453Smckusick 	exit();
10958800Smckusick     }
1096*24453Smckusick     /* now the original input file will be the output */
1097*24453Smckusick     output = fopen(in_name, "w");
1098*24453Smckusick     if (output == 0) {
1099*24453Smckusick 	printf("can't create %s\n", in_name);
1100*24453Smckusick 	unlink(bakfile);
1101*24453Smckusick 	exit();
11028800Smckusick     }
11038800Smckusick }
11048800Smckusick 
11058800Smckusick 
1106*24453Smckusick char       *param_start;
1107*24453Smckusick 
1108*24453Smckusick eqin(s1, s2)
1109*24453Smckusick     register char *s1;
1110*24453Smckusick     register char *s2;
11118800Smckusick {
1112*24453Smckusick     while (*s1) {
1113*24453Smckusick 	if (*s1++ != *s2++)
1114*24453Smckusick 	    return (false);
11158800Smckusick     }
1116*24453Smckusick     param_start = s2;
1117*24453Smckusick     return (true);
11188800Smckusick }
11198800Smckusick 
11208800Smckusick 
1121*24453Smckusick set_option(arg)
1122*24453Smckusick     char       *arg;
11238800Smckusick {
1124*24453Smckusick     if (!eqin("-npro", arg))
1125*24453Smckusick 	if (eqin("-lc", arg))	/* comment line length */
1126*24453Smckusick 	    block_comment_max_col = atoi(param_start);
1127*24453Smckusick 	else if (eqin("-lp", arg))
1128*24453Smckusick 	    lineup_to_parens = 1;
1129*24453Smckusick 	else if (eqin("-nlp", arg))
1130*24453Smckusick 	    lineup_to_parens = 0;
1131*24453Smckusick 	else if (eqin("-l", arg))	/* line length */
1132*24453Smckusick 	    max_col = atoi(param_start);
1133*24453Smckusick 	else if (eqin("-psl", arg))	/* if true, the names of
1134*24453Smckusick 					 * procedures being defined get
1135*24453Smckusick 					 * placed in column 1 (ie. a
1136*24453Smckusick 					 * newline is placed between the
1137*24453Smckusick 					 * type of the procedure and its
1138*24453Smckusick 					 * name) */
1139*24453Smckusick 	    procnames_start_line = 1;
1140*24453Smckusick 	else if (eqin("-npsl", arg))
1141*24453Smckusick 	    procnames_start_line = 0;
1142*24453Smckusick 	else if (eqin("-fc1", arg))
1143*24453Smckusick 	    format_col1_comments = 1;
1144*24453Smckusick 	else if (eqin("-nfc1", arg))
1145*24453Smckusick 	    format_col1_comments = 0;
1146*24453Smckusick 	else if (eqin("-pcs", arg))	/* If true, procedure calls look
1147*24453Smckusick 					 * like: foo(bar) rather than foo
1148*24453Smckusick 					 * (bar) */
1149*24453Smckusick 	    proc_calls_space = 1;
1150*24453Smckusick 	else if (eqin("-npcs", arg))
1151*24453Smckusick 	    proc_calls_space = 0;
1152*24453Smckusick 	else if (eqin("-ip", arg))	/* indent parameters */
1153*24453Smckusick 	    ps.indent_parameters = 1;
1154*24453Smckusick 	else if (eqin("-nip", arg))	/* no indent parameters */
1155*24453Smckusick 	    ps.indent_parameters = 0;
1156*24453Smckusick 	else if (eqin("-cli", arg)) {	/* case label indent */
1157*24453Smckusick 	    extern float atof();
1158*24453Smckusick 
1159*24453Smckusick 	    ps.case_indent = atof(param_start);
1160*24453Smckusick 	}
1161*24453Smckusick 	else if (eqin("-ci",arg))
1162*24453Smckusick 	    continuation_indent = atoi(param_start);
1163*24453Smckusick 	else if (eqin("-cdb", arg))	/* comment delimiters should be on
1164*24453Smckusick 					 * lines by themselves */
1165*24453Smckusick 	    comment_delimiter_on_blankline = 1;
1166*24453Smckusick 	else if (eqin("-ncdb", arg))	/* comment delimiters shouldnt be
1167*24453Smckusick 					 * on lines by themselves */
1168*24453Smckusick 	    comment_delimiter_on_blankline = 0;
1169*24453Smckusick 	else if (eqin("-i", arg))	/* indent width */
1170*24453Smckusick 	    ps.ind_size = atoi(param_start);
1171*24453Smckusick 	else if (eqin("-cd", arg))	/* indent for comments on
1172*24453Smckusick 					 * declarations */
1173*24453Smckusick 	    ps.decl_com_ind = atoi(param_start);
1174*24453Smckusick 	else if (eqin("-ce", arg))	/* true iff 'else' should cuddle
1175*24453Smckusick 					 * up to '}' */
1176*24453Smckusick 	    cuddle_else = 1;
1177*24453Smckusick 	else if (eqin("-c", arg))	/* comment indent */
1178*24453Smckusick 	    ps.com_ind = atoi(param_start);
1179*24453Smckusick 	else if (eqin("-v", arg))	/* spew out rubbish */
11808800Smckusick 	    verbose = true;
1181*24453Smckusick 	else if (eqin("-nv", arg))	/* keep quiet */
11828800Smckusick 	    verbose = false;
1183*24453Smckusick 	else if (eqin("-dj", arg))
1184*24453Smckusick 	    ps.ljust_decl = true;
1185*24453Smckusick 	else if (eqin("-ndj", arg))
1186*24453Smckusick 	    ps.ljust_decl = false;
1187*24453Smckusick 	else if (eqin("-nbc", arg))	/* dont break after commas in
1188*24453Smckusick 					 * declarations */
1189*24453Smckusick 	    ps.leave_comma = true;
1190*24453Smckusick 	else if (eqin("-bc", arg))	/* break after commas in
1191*24453Smckusick 					 * declarations */
1192*24453Smckusick 	    ps.leave_comma = false;
1193*24453Smckusick 	else if (eqin("-di", arg))	/* indent from type to varname in
1194*24453Smckusick 					 * a declaration */
1195*24453Smckusick 	    ps.decl_indent = atoi(param_start);
1196*24453Smckusick 	else if (eqin("-d", arg))
1197*24453Smckusick 	    ps.unindent_displace = atoi(param_start);
1198*24453Smckusick 	else if (eqin("-br", arg))
11998800Smckusick 	    btype_2 = true;
1200*24453Smckusick 	else if (eqin("-bl", arg))
12018800Smckusick 	    btype_2 = false;
1202*24453Smckusick 	else if (eqin("-st", arg)) {	/* input and output on standard IO */
1203*24453Smckusick 	    if (input == 0)
1204*24453Smckusick 		input = stdin;
1205*24453Smckusick 	    if (output == 0)
1206*24453Smckusick 		output = stdout;
1207*24453Smckusick 	} else if (eqin("-ei", arg))	/* else-ifs should be stuck
1208*24453Smckusick 					 * together */
1209*24453Smckusick 	    ps.else_if = 1;
1210*24453Smckusick 	else if (eqin("-nei", arg))	/* else-ifs should be broken apart */
1211*24453Smckusick 	    ps.else_if = 0;
1212*24453Smckusick 	else if (eqin("-nce", arg))	/* else should always start a line */
1213*24453Smckusick 	    cuddle_else = 0;
1214*24453Smckusick 	else if (eqin("-sc", arg))	/* comment continuations should
1215*24453Smckusick 					 * start with a * */
1216*24453Smckusick 	    star_comment_cont = 1;
1217*24453Smckusick 	else if (eqin("-nsc", arg))
1218*24453Smckusick 	    star_comment_cont = 0;	/* comments shouldnt start with a
1219*24453Smckusick 					 * star */
1220*24453Smckusick 	else if (eqin("-bap", arg))	/* blanklines after procedures */
1221*24453Smckusick 	    blanklines_after_procs = 1;
1222*24453Smckusick 	else if (eqin("-nbap", arg))	/* blanklines after procedures */
1223*24453Smckusick 	    blanklines_after_procs = 0;
1224*24453Smckusick 	else if (eqin("-sob", arg))	/* swallow optional blanklines */
1225*24453Smckusick 	    swallow_optional_blanklines = 1;
1226*24453Smckusick 	else if (eqin("-nsob", arg))	/* swallow optional blanklines */
1227*24453Smckusick 	    swallow_optional_blanklines = 0;
1228*24453Smckusick 	else if (eqin("-bad", arg))	/* blanklines after declarations */
1229*24453Smckusick 	    blanklines_after_declarations = 1;
1230*24453Smckusick 	else if (eqin("-nbad", arg))	/* blanklines after declarations */
1231*24453Smckusick 	    blanklines_after_declarations = 0;
1232*24453Smckusick 	else if (eqin("-bbb", arg))	/* blanklines before blockcomments */
1233*24453Smckusick 	    blanklines_before_blockcomments = 1;
1234*24453Smckusick 	else if (eqin("-nbbb", arg))	/* blanklines before blockcomments */
1235*24453Smckusick 	    blanklines_before_blockcomments = 0;
1236*24453Smckusick 	else if (eqin("-troff", arg))
1237*24453Smckusick 	    troff = 1;
1238*24453Smckusick 	else if (arg[0] == '-' && arg[1] == 'T')	/* -Ttypename */
1239*24453Smckusick 	    addkey(arg + 2, 4);
1240*24453Smckusick 	else {			/* illegal arg given */
1241*24453Smckusick 	    printf("Unknown parameter: %s\n", arg);
1242*24453Smckusick 	    exit();
1243*24453Smckusick 	}
12448800Smckusick }
12458800Smckusick 
12468800Smckusick 
12478800Smckusick /*
1248*24453Smckusick  * GETPRO - get profile file profile file is max 127 characters
12498800Smckusick  */
1250*24453Smckusick getpro(name, buf, len)
1251*24453Smckusick     char       *name,		/* profile file name, as in '.indent.pro' */
1252*24453Smckusick                *buf;		/* will receive contents of .pro file */
12538800Smckusick {
12548800Smckusick     register    chn,
12558800Smckusick                 n;
1256*24453Smckusick     char        file[100];
12578800Smckusick 
12588800Smckusick     file[0] = 0;
1259*24453Smckusick     strcat(file, getenv("HOME"));
1260*24453Smckusick     strcat(file, "/");
1261*24453Smckusick     strcat(file, name);
1262*24453Smckusick     if ((chn = open(name, 0)) < 0)
1263*24453Smckusick 	chn = open(file, 0);
12648800Smckusick     if (chn < 0)
12658800Smckusick 	return (-1);
1266*24453Smckusick     n = read(chn, buf, len);
12678800Smckusick     if (n < 0)
12688800Smckusick 	return (-1);
1269*24453Smckusick     buf[n--] = 0;		/* null terminate line */
12708800Smckusick     if (buf[n] == '\n')
12718800Smckusick 	buf[n] = 0;
1272*24453Smckusick     close(chn);
12738800Smckusick     return (0);
12748800Smckusick }
12758800Smckusick 
12768800Smckusick 
12778800Smckusick /*
1278*24453Smckusick  * strip off arguments in a string: p is address of a character pointer
1279*24453Smckusick  * nextchr returns pointer to front of first arg arg is null terminated. p
1280*24453Smckusick  * is reset to after arg for subsequent calls
12818800Smckusick  */
1282*24453Smckusick char       *
1283*24453Smckusick nxtarg(p)
1284*24453Smckusick     char      **p;
12858800Smckusick {
1286*24453Smckusick     register char *f,
1287*24453Smckusick                *b;
1288*24453Smckusick 
1289*24453Smckusick     f = *p;
1290*24453Smckusick     while (*f && *f <= ' ')
12918800Smckusick 	f++;
1292*24453Smckusick     b = f;
1293*24453Smckusick     while (*b > ' ')
12948800Smckusick 	b++;
12958800Smckusick     if (*b != 0)
12968800Smckusick 	*b++ = 0;
12978800Smckusick     *p = b;
12988800Smckusick     return (f);
12998800Smckusick }
13008800Smckusick 
13018800Smckusick 
1302*24453Smckusick set_profile()
1303*24453Smckusick {
1304*24453Smckusick     char        line[1000],
1305*24453Smckusick                *b;
1306*24453Smckusick     register char *f;
1307*24453Smckusick     extern char *nxtarg();
13088800Smckusick 
1309*24453Smckusick     if (getpro(".indent.pro", line, sizeof line) < 0)
13108800Smckusick 	return;
13118800Smckusick     b = line;
1312*24453Smckusick     if (verbose)
1313*24453Smckusick 	printf("profile: %s\n", b);
1314*24453Smckusick     while (*(f = nxtarg(&b)))
1315*24453Smckusick 	set_option(f);
13168800Smckusick }
1317