xref: /csrg-svn/usr.bin/indent/indent.c (revision 8800)
1*8800Smckusick static char sccsid[] = "@(#)indent.c	4.1	(Berkeley)	10/21/82";
2*8800Smckusick 
3*8800Smckusick /*
4*8800Smckusick 
5*8800Smckusick 			  Copyright (C) 1976
6*8800Smckusick 				by the
7*8800Smckusick 			  Board of Trustees
8*8800Smckusick 				of the
9*8800Smckusick 			University of Illinois
10*8800Smckusick 
11*8800Smckusick 			 All rights reserved
12*8800Smckusick 
13*8800Smckusick 
14*8800Smckusick NAME:
15*8800Smckusick 	indent main program
16*8800Smckusick 
17*8800Smckusick FUNCTION:
18*8800Smckusick 	This is the main program of the indent program.  Indent will take a C
19*8800Smckusick 	program source and reformat it into a semi-reasonable form.
20*8800Smckusick 
21*8800Smckusick ALGORITHM:
22*8800Smckusick 	The routine lexi scans tokens and passes them back one at a time to the
23*8800Smckusick 	main routine.  The subroutine parse takes care of much of the work of
24*8800Smckusick 	figuring indentation level.
25*8800Smckusick 
26*8800Smckusick 	1) Call lexi
27*8800Smckusick 	2) Enter a monster switch statement on the code returned by lexi.  If
28*8800Smckusick 	   the indentation level for the line yet to be printed should be
29*8800Smckusick 	   changed, set the variable ind_level.  If the indentation level for
30*8800Smckusick 	   the following line should be changed, set the variable i_l_follow.
31*8800Smckusick 
32*8800Smckusick PARAMETERS:
33*8800Smckusick 	None
34*8800Smckusick 
35*8800Smckusick RETURNS:
36*8800Smckusick 	Nothing
37*8800Smckusick 
38*8800Smckusick GLOBALS:
39*8800Smckusick 	be_save =
40*8800Smckusick 	break_comma
41*8800Smckusick 	bp_save =
42*8800Smckusick 	btype_2 =
43*8800Smckusick 	code_lines
44*8800Smckusick 	com_ind =
45*8800Smckusick 	com_lines
46*8800Smckusick 	dec_nest =
47*8800Smckusick 	decl_com_ind =
48*8800Smckusick 	decl_on_line =
49*8800Smckusick 	i_l_follow =
50*8800Smckusick 	in_decl =
51*8800Smckusick 	ind_level =
52*8800Smckusick 	ind_size =
53*8800Smckusick 	ind_stmt =
54*8800Smckusick 	last_u_d =
55*8800Smckusick 	leave_comma =
56*8800Smckusick 	line_no =
57*8800Smckusick 	ljust_decl =
58*8800Smckusick 	max_col =
59*8800Smckusick 	out_coms
60*8800Smckusick 	out_lines
61*8800Smckusick 	p_l_follow =
62*8800Smckusick 	paren_level =
63*8800Smckusick 	pcase =
64*8800Smckusick 	sc_end =
65*8800Smckusick 	unindent_displace =
66*8800Smckusick 	use_ff =
67*8800Smckusick 	verbose =
68*8800Smckusick 
69*8800Smckusick CALLS:
70*8800Smckusick 	atoi (lib)
71*8800Smckusick 	cmp
72*8800Smckusick 	creat (lib)
73*8800Smckusick 	dump_line
74*8800Smckusick 	eqin
75*8800Smckusick 	fill_buffer
76*8800Smckusick 	lexi
77*8800Smckusick 	open (lib)
78*8800Smckusick 	parse
79*8800Smckusick 	pr_comment
80*8800Smckusick 	printf (lib)
81*8800Smckusick 	seek (lib)
82*8800Smckusick 	time (lib)
83*8800Smckusick 
84*8800Smckusick CALLED BY:
85*8800Smckusick 	No one (main routine)
86*8800Smckusick 
87*8800Smckusick HISTORY:
88*8800Smckusick 	November 1976	D A Willcox of CAC	Initial coding
89*8800Smckusick 	12/9/76		D A Willcox of CAC	Fixed defaults for decl_com_ind
90*8800Smckusick 						to be 8 less than com_ind if
91*8800Smckusick 						left justifying declarations
92*8800Smckusick 	12/9/76		D A Willcox of CAC	Fixed processing of nested
93*8800Smckusick 						<c>?<s>:<s> constructs
94*8800Smckusick 	1/7/77		D A Willcox of CAC	Added check for overwrite of
95*8800Smckusick 						input file
96*8800Smckusick 						Added code to handle -br and -bl
97*8800Smckusick 						parameters
98*8800Smckusick */
99*8800Smckusick #include "indent_globs.h";
100*8800Smckusick #include "indent_codes.h";
101*8800Smckusick 
102*8800Smckusick /* #define dolog 1	/* if this define is removed, then the code to
103*8800Smckusick 			   produce a log file will be removed */
104*8800Smckusick 
105*8800Smckusick struct templ {		       /* this is a template for the list of
106*8800Smckusick 			          command line args */
107*8800Smckusick     char   *str;	       /* pointer to string which is a valid
108*8800Smckusick 			          command line arg */
109*8800Smckusick     int     code;	       /* code to be used in switch for processing
110*8800Smckusick 			          this arg */
111*8800Smckusick };
112*8800Smckusick 
113*8800Smckusick 
114*8800Smckusick struct templ    options[] =
115*8800Smckusick {			       /* warning - because of the way that this
116*8800Smckusick 			          table is scanned, if one entry is an
117*8800Smckusick 			          initial substring of another, then the
118*8800Smckusick 			          longer entry should occur first */
119*8800Smckusick     "-cd", 4,
120*8800Smckusick     "-c", 2,
121*8800Smckusick     "-l", 1,
122*8800Smckusick     "-i", 3,
123*8800Smckusick     "-v", 5,
124*8800Smckusick     "-nv", 6,
125*8800Smckusick     "-dj", 7,
126*8800Smckusick     "-d", 13,		       /* unindented comment placement */
127*8800Smckusick     "-ndj", 8,
128*8800Smckusick     "-bc", 10,		       /* break after command in decl */
129*8800Smckusick     "-nbc", 9,		       /* don't break after comma */
130*8800Smckusick     "-br", 14,		       /* put brace on right of stmt */
131*8800Smckusick     "-bl", 15,		       /* put brace on left by itself */
132*8800Smckusick     "-st", 16,		       /* use the standard input and output
133*8800Smckusick 				  files */
134*8800Smckusick     0, 0
135*8800Smckusick };
136*8800Smckusick 
137*8800Smckusick 
138*8800Smckusick char   *in_name = "Standard Input";
139*8800Smckusick 			       /* will always point to name of input file
140*8800Smckusick 			       */
141*8800Smckusick char   *out_name = "Standard Output";
142*8800Smckusick 			       /* will always point to name of output file
143*8800Smckusick 			          */
144*8800Smckusick char    bakfile[32] = "";
145*8800Smckusick 
146*8800Smckusick main (argc, argv)
147*8800Smckusick int     argc;
148*8800Smckusick char  **argv;
149*8800Smckusick {
150*8800Smckusick 
151*8800Smckusick     int     dec_ind;	       /* current indentation for declarations */
152*8800Smckusick     int     di_stack[20];      /* a stack of structure indentation levels
153*8800Smckusick 			       */
154*8800Smckusick     int     flushed_nl;	       /* used when buffering up comments to
155*8800Smckusick 			          remember that a newline was passed over
156*8800Smckusick 			       */
157*8800Smckusick     int     force_nl;	       /* when true, code must be broken */
158*8800Smckusick     int     hd_type;	       /* used to store type of stmt for if (...),
159*8800Smckusick 			          for (...), etc */
160*8800Smckusick     register int    i;	       /* local loop counter */
161*8800Smckusick     int     in_or_st;	       /* Will be true iff there has been a
162*8800Smckusick 			          declarator (e.g. int or char) and no
163*8800Smckusick 			          left paren since the last semicolon.
164*8800Smckusick 			          When true, a { is starting a structure
165*8800Smckusick 			          definition or an initialization list */
166*8800Smckusick     register int    j;	       /* local loop counter */
167*8800Smckusick     int     scase;	       /* set to true when we see a case, so we
168*8800Smckusick 			          will know what to do with the following
169*8800Smckusick 			          colon */
170*8800Smckusick     int     sp_sw;	       /* when true, we are in the expressin of
171*8800Smckusick 			          if(...), while(...), etc. */
172*8800Smckusick     int     squest;	       /* when this is positive, we have seen a ?
173*8800Smckusick 			          without the matching : in a <c>?<s>:<s>
174*8800Smckusick 			          construct */
175*8800Smckusick     register char  *t_ptr;     /* used for copying tokens */
176*8800Smckusick     int     type_code;	       /* the type of token, returned by lexi */
177*8800Smckusick     int     want_blank;	       /* set to true when the following token
178*8800Smckusick 			          should be prefixed by a blank. (Said
179*8800Smckusick 			          prefixing is ignored in some cases.) */
180*8800Smckusick 
181*8800Smckusick #ifdef dolog		       /* include declarations needed for log */
182*8800Smckusick     int     log_fid;	       /* fid of log file */
183*8800Smckusick 
184*8800Smckusick     struct logtmpl {	       /* structure of a log entry */
185*8800Smckusick 	int     tvec[2];       /* time of execution */
186*8800Smckusick 	char    inp;	       /* input fid */
187*8800Smckusick 	char    outp;	       /* output fid */
188*8800Smckusick 	int     nout;	       /* # output lines */
189*8800Smckusick 	int     ncom;	       /* # comments */
190*8800Smckusick 	int     wcom;	       /* # lines w/ comments */
191*8800Smckusick 	int     wcode;	       /* # lines w/code */
192*8800Smckusick 	char    mc;	       /* max line size */
193*8800Smckusick 	char    ci;	       /* comment indentation */
194*8800Smckusick 	char    inds;	       /* indent size */
195*8800Smckusick 	char    dci;	       /* decl comment indentation */
196*8800Smckusick 	char    verb;	       /* verbose */
197*8800Smckusick 	char    ljus;	       /* left just */
198*8800Smckusick 	char    lvcom;	       /* leave commas */
199*8800Smckusick 	char    unin;	       /* unindented comment indentation */
200*8800Smckusick 	char    uid;	       /* the user id */
201*8800Smckusick 	char    bropt;	       /* btype_2 */
202*8800Smckusick 	int     reserved[2];
203*8800Smckusick     };
204*8800Smckusick 
205*8800Smckusick     struct logtmpl  logent;
206*8800Smckusick #endif
207*8800Smckusick 
208*8800Smckusick /*-----------------------------------------------*\
209*8800Smckusick |    INITIALIZATION
210*8800Smckusick \*-----------------------------------------------*/
211*8800Smckusick 
212*8800Smckusick 
213*8800Smckusick     combuf[0] = codebuf[0] = labbuf[0] = ' ';
214*8800Smckusick  /* set up code, label, and comment buffers */
215*8800Smckusick     combuf[1] = codebuf[1] = labbuf[1] = '\0';
216*8800Smckusick     s_lab = e_lab = labbuf + 1;
217*8800Smckusick     s_code = e_code = codebuf + 1;
218*8800Smckusick     s_com = e_com = combuf + 1;
219*8800Smckusick 
220*8800Smckusick     buf_ptr = buf_end = in_buffer;
221*8800Smckusick     line_no = 1;
222*8800Smckusick     had_eof = in_decl = decl_on_line = break_comma = false;
223*8800Smckusick     sp_sw = force_nl = false;
224*8800Smckusick     in_or_st = false;
225*8800Smckusick     bl_line = true;
226*8800Smckusick     dec_ind = 0;
227*8800Smckusick     di_stack[dec_nest = 0] = 0;
228*8800Smckusick     want_blank = in_stmt = ind_stmt = false;
229*8800Smckusick 
230*8800Smckusick 
231*8800Smckusick     scase = pcase = false;
232*8800Smckusick     squest = 0;
233*8800Smckusick     sc_end = 0;
234*8800Smckusick     bp_save = 0;
235*8800Smckusick     be_save = 0;
236*8800Smckusick 
237*8800Smckusick     input = -1;
238*8800Smckusick     output = -1;
239*8800Smckusick     ljust_decl = d_ljust;
240*8800Smckusick 
241*8800Smckusick 
242*8800Smckusick 
243*8800Smckusick /*--------------------------------------------------*\
244*8800Smckusick |   COMMAND LINE SCAN
245*8800Smckusick \*--------------------------------------------------*/
246*8800Smckusick 
247*8800Smckusick     max_col = d_max_col;       /* set up some default values */
248*8800Smckusick     com_ind = d_com_ind;
249*8800Smckusick     ind_size = d_ind_size;
250*8800Smckusick     verbose = d_verbose;
251*8800Smckusick     decl_com_ind = 0;	       /* if this is not set to some positive
252*8800Smckusick 			          value by an arg, we will set this equal
253*8800Smckusick 			          to com_ind */
254*8800Smckusick     btype_2 = d_btype_2;
255*8800Smckusick     unindent_displace = d_unindent;
256*8800Smckusick     leave_comma = d_leave_comma;
257*8800Smckusick 
258*8800Smckusick     set_profile ();
259*8800Smckusick 
260*8800Smckusick     for (i = 1; i < argc; ++i) {
261*8800Smckusick     /* look thru args (if any) for changes to defaults */
262*8800Smckusick 	if (argv[i][0] != '-') {/* no flag on parameter */
263*8800Smckusick 	    if (input < 0) {   /* we must have the input file */
264*8800Smckusick 		in_name = argv[i];	/* remember name of input
265*8800Smckusick 					   file */
266*8800Smckusick 		input = open (in_name, 0);
267*8800Smckusick 		if (input < 0) {	/* check for open error */
268*8800Smckusick 		    printf ("Can't open %s\n", argv[i]);
269*8800Smckusick 		    exit ();
270*8800Smckusick 		}
271*8800Smckusick 		continue;
272*8800Smckusick 	    }
273*8800Smckusick 	    else
274*8800Smckusick 		if (output < 0) {	/* we have the output file */
275*8800Smckusick 		    out_name = argv[i];	/* remember name of output file */
276*8800Smckusick 		    if (cmp (in_name, out_name) == 0) {	 /* attempt to
277*8800Smckusick 					   overwright the file */
278*8800Smckusick 			printf ("Input and output files must be different\n");
279*8800Smckusick 			exit ();
280*8800Smckusick 		    }
281*8800Smckusick 		    output = creat (out_name, 0644);
282*8800Smckusick 		    if (output < 0) {   /* check for create error */
283*8800Smckusick 			printf ("Can't create %s\n", argv[i]);
284*8800Smckusick 			exit ();
285*8800Smckusick 		    }
286*8800Smckusick 		    continue;
287*8800Smckusick 		}
288*8800Smckusick 
289*8800Smckusick 	    printf ("Unknown parameter: %s\n", argv[i]);
290*8800Smckusick 	    exit ();
291*8800Smckusick 	}
292*8800Smckusick 	else
293*8800Smckusick 	    set_option (argv[i]);
294*8800Smckusick 
295*8800Smckusick     }			       /* end of for */
296*8800Smckusick 
297*8800Smckusick     if (input < 0) {
298*8800Smckusick 	printf ("Usage: indent file [ outfile ] [ options ]\n");
299*8800Smckusick 	exit ();
300*8800Smckusick     }
301*8800Smckusick     if (output < 0) {
302*8800Smckusick 	out_name = in_name;
303*8800Smckusick 	bakcopy ();
304*8800Smckusick     }
305*8800Smckusick 
306*8800Smckusick     if (com_ind <= 1)
307*8800Smckusick 	com_ind = 2;	       /* don't put normal comments before column
308*8800Smckusick 			          2 */
309*8800Smckusick 
310*8800Smckusick     if (decl_com_ind <= 0)     /* if not specified by user, set this */
311*8800Smckusick 	decl_com_ind = ljust_decl ? (com_ind <= 10 ? 2 : com_ind - 8) : com_ind;
312*8800Smckusick 
313*8800Smckusick     fill_buffer ();	       /* get first batch of stuff into input
314*8800Smckusick 			          buffer */
315*8800Smckusick 
316*8800Smckusick     parse (semicolon);
317*8800Smckusick /*-----------------------------------------------------
318*8800Smckusick |   START OF MAIN LOOP
319*8800Smckusick \*----------------------------------------------------*/
320*8800Smckusick 
321*8800Smckusick     while (1) {		       /* this is the main loop.  it will go until
322*8800Smckusick 			          we reach eof */
323*8800Smckusick 	type_code = lexi ();   /* lexi reads one token.  The actual
324*8800Smckusick 			          characters read are stored in "token".
325*8800Smckusick 			          lexi returns a code indicating the type
326*8800Smckusick 			          of token */
327*8800Smckusick 
328*8800Smckusick     /*
329*8800Smckusick      * The following code moves everything following an if (), while (),
330*8800Smckusick      * else, etc. up to the start of the following stmt to a buffer.  This
331*8800Smckusick      * allows proper handling of both kinds of brace placement.
332*8800Smckusick      */
333*8800Smckusick 
334*8800Smckusick 	flushed_nl = false;
335*8800Smckusick 	while (search_brace) { /* if we scanned an if(), while(), etc., we
336*8800Smckusick 			          might need to copy stuff into a buffer
337*8800Smckusick 	*//* we must loop, copying stuff into save_com, until we find the
338*8800Smckusick 	   start of the stmt which follows the if, or whatever */
339*8800Smckusick 	    switch (type_code) {
340*8800Smckusick 		case newline:
341*8800Smckusick 		    ++line_no;
342*8800Smckusick 		    flushed_nl = true;
343*8800Smckusick 		case form_feed:
344*8800Smckusick 		    break;     /* form feeds and newlines found here will
345*8800Smckusick 			          be ignored */
346*8800Smckusick 
347*8800Smckusick 		case lbrace:   /* this is a brace that starts the compound
348*8800Smckusick 			          stmt */
349*8800Smckusick 		    if (sc_end == 0) {
350*8800Smckusick 		    /* ignore buffering if a comment wasn't stored up */
351*8800Smckusick 			search_brace = false;
352*8800Smckusick 			goto check_type;
353*8800Smckusick 		    }
354*8800Smckusick 
355*8800Smckusick 		    if (btype_2) {
356*8800Smckusick 			save_com[0] = '{';
357*8800Smckusick 		    /* we either want to put the brace right after the if
358*8800Smckusick 		    */
359*8800Smckusick 			goto sw_buffer;
360*8800Smckusick 		    /* go to common code to get out of this loop */
361*8800Smckusick 		    }
362*8800Smckusick 
363*8800Smckusick 		default:       /* it is the start of a normal statment */
364*8800Smckusick 		    if (flushed_nl)
365*8800Smckusick 			       /* if we flushed a newline, make sure it is
366*8800Smckusick 			          put back */
367*8800Smckusick 			force_nl = true;
368*8800Smckusick 
369*8800Smckusick 		    if (sc_end == 0) {
370*8800Smckusick 		    /* ignore buffering if comment wasn't saved up */
371*8800Smckusick 			search_brace = false;
372*8800Smckusick 			goto check_type;
373*8800Smckusick 		    }
374*8800Smckusick 
375*8800Smckusick 		    if (force_nl) {
376*8800Smckusick 		    /* if we should insert a nl here, put it into the
377*8800Smckusick 		       buffer */
378*8800Smckusick 			force_nl = false;
379*8800Smckusick 			--line_no;
380*8800Smckusick 		    /* this will be re-increased when the nl is read from
381*8800Smckusick 		       the buffer */
382*8800Smckusick 			*sc_end++ = '\n';
383*8800Smckusick 			*sc_end++ = ' ';
384*8800Smckusick 			if (verbose && !flushed_nl)
385*8800Smckusick 			       /* print error msg if the line was not
386*8800Smckusick 			          already broken */
387*8800Smckusick 			    printf ("%d: Line broken\n", line_no);
388*8800Smckusick 			flushed_nl = false;
389*8800Smckusick 		    }
390*8800Smckusick 
391*8800Smckusick 		    for (t_ptr = token; *t_ptr; ++t_ptr)
392*8800Smckusick 			*sc_end++ = *t_ptr;
393*8800Smckusick 		/* copy token into temp buffer */
394*8800Smckusick 
395*8800Smckusick 	    sw_buffer:
396*8800Smckusick 		    search_brace = false;
397*8800Smckusick 		/* stop looking for start of stmt */
398*8800Smckusick 		    bp_save = buf_ptr;
399*8800Smckusick 		/* save current input buffer */
400*8800Smckusick 		    be_save = buf_end;
401*8800Smckusick 		    buf_ptr = save_com;
402*8800Smckusick 		/* fix so that subsequent calls to lexi will take tokens
403*8800Smckusick 		   out of save_com */
404*8800Smckusick 		    *sc_end++ = ' ';
405*8800Smckusick 		/* add trailing blank, just in case */
406*8800Smckusick 		    buf_end = sc_end;
407*8800Smckusick 		    sc_end = 0;
408*8800Smckusick 		    break;
409*8800Smckusick 
410*8800Smckusick 		case comment:  /* we have a comment, so we must copy it
411*8800Smckusick 			          into the buffer */
412*8800Smckusick 		    if (sc_end == 0) {
413*8800Smckusick 		    /* if this is the first comment, we must set up the
414*8800Smckusick 		       buffer */
415*8800Smckusick 			save_com[0] = save_com[1] = ' ';
416*8800Smckusick 			sc_end = &(save_com[2]);
417*8800Smckusick 		    }
418*8800Smckusick 		    else {
419*8800Smckusick 			*sc_end++ = '\n';
420*8800Smckusick 		    /* add newline between comments */
421*8800Smckusick 			*sc_end++ = ' ';
422*8800Smckusick 			--line_no;
423*8800Smckusick 		    }
424*8800Smckusick 
425*8800Smckusick 		    *sc_end++ = '/';
426*8800Smckusick 		/* copy in start of comment */
427*8800Smckusick 		    *sc_end++ = '*';
428*8800Smckusick 
429*8800Smckusick 		    for (;;) { /* loop until we get to the end of the
430*8800Smckusick 			          comment */
431*8800Smckusick 			*sc_end = *buf_ptr++;
432*8800Smckusick 			if (buf_ptr >= buf_end)
433*8800Smckusick 			    fill_buffer ();
434*8800Smckusick 
435*8800Smckusick 			if (*sc_end++ == '*' && *buf_ptr == '/')
436*8800Smckusick 			    break;
437*8800Smckusick 		    /* we are at end of comment */
438*8800Smckusick 
439*8800Smckusick 			if (sc_end >= &(save_com[sc_size])) {
440*8800Smckusick 			/* check for temp buffer overflow */
441*8800Smckusick 			    printf ("%d: Internal buffer overflow.\n",
442*8800Smckusick 				    line_no);
443*8800Smckusick 			    printf ("Move big comment from right after if,\
444*8800Smckusick  while, or whatever.\n");
445*8800Smckusick 			    exit ();
446*8800Smckusick 			}
447*8800Smckusick 		    }
448*8800Smckusick 
449*8800Smckusick 		    *sc_end++ = '/';
450*8800Smckusick 		/* add ending slash */
451*8800Smckusick 		    if (++buf_ptr >= buf_end)/* get past / in buffer */
452*8800Smckusick 			fill_buffer ();
453*8800Smckusick 		    break;
454*8800Smckusick 	    }		       /* end of switch */
455*8800Smckusick 
456*8800Smckusick 	    if (type_code != 0)/* we must make this check, just in case
457*8800Smckusick 			          there was an unexpected EOF */
458*8800Smckusick 		type_code = lexi ();
459*8800Smckusick 	/* read another token */
460*8800Smckusick 	}		       /* end of while (serach_brace) */
461*8800Smckusick check_type:
462*8800Smckusick 
463*8800Smckusick 	if (type_code == 0) {  /* we got eof */
464*8800Smckusick 	    if (s_lab != e_lab || s_code != e_code
465*8800Smckusick 		    || s_com != e_com)/* must dump end of line */
466*8800Smckusick 		dump_line ();
467*8800Smckusick 	    if (i_l_follow != 0)/* check for balanced braces */
468*8800Smckusick 		printf ("%d too few }'s\n", i_l_follow);
469*8800Smckusick 
470*8800Smckusick #ifdef dolog		       /* only include this stuff if we want to
471*8800Smckusick 			          keep a log */
472*8800Smckusick 	    log_fid = open ("/mnt/net/willcox/indent/indent_log", 1);
473*8800Smckusick 	/* open the log file */
474*8800Smckusick 	    if (log_fid >= 0) {
475*8800Smckusick 		seek (log_fid, 0, 2);
476*8800Smckusick 	    /* point to end of log */
477*8800Smckusick 		time (logent.tvec);
478*8800Smckusick 	    /* get current time */
479*8800Smckusick 		logent.inp = input;
480*8800Smckusick 	    /* set up the log entry */
481*8800Smckusick 		logent.outp = output;
482*8800Smckusick 		logent.nout = out_lines;
483*8800Smckusick 		logent.ncom = out_coms;
484*8800Smckusick 		logent.wcom = com_lines;
485*8800Smckusick 		logent.wcode = code_lines;
486*8800Smckusick 		logent.mc = max_col;
487*8800Smckusick 		logent.ci = com_ind;
488*8800Smckusick 		logent.inds = ind_size;
489*8800Smckusick 		logent.dci = decl_com_ind;
490*8800Smckusick 		logent.verb = verbose;
491*8800Smckusick 		logent.ljus = ljust_decl;
492*8800Smckusick 		logent.lvcom = leave_comma;
493*8800Smckusick 		logent.unin = unindent_displace;
494*8800Smckusick 		logent.uid = getuid ();
495*8800Smckusick 		logent.bropt = btype_2;
496*8800Smckusick 		write (log_fid, &logent, sizeof logent);
497*8800Smckusick 	    }
498*8800Smckusick #endif
499*8800Smckusick 	    if (verbose) {
500*8800Smckusick 		printf ("There were %d output lines and %d comments\n",
501*8800Smckusick 			out_lines, out_coms);
502*8800Smckusick 		printf ("(Lines with comments)/(Lines with code): %6.3f\n",
503*8800Smckusick 			(1.0 * com_lines) / code_lines);
504*8800Smckusick 	    }
505*8800Smckusick 
506*8800Smckusick 	    exit ();
507*8800Smckusick 	}
508*8800Smckusick 
509*8800Smckusick 	if (
510*8800Smckusick 		(type_code != comment) &&
511*8800Smckusick 		(type_code != newline) &&
512*8800Smckusick 		(type_code != preesc) &&
513*8800Smckusick 		(type_code != form_feed)) {
514*8800Smckusick 	    if (
515*8800Smckusick 		    force_nl
516*8800Smckusick 		    &&
517*8800Smckusick 		    (type_code != semicolon) &&
518*8800Smckusick 		    (
519*8800Smckusick 			type_code != lbrace
520*8800Smckusick 			||
521*8800Smckusick 			!btype_2
522*8800Smckusick 		    )) {       /* we should force a broken line here */
523*8800Smckusick 		if (verbose && !flushed_nl)
524*8800Smckusick 		    printf ("%d: Line broken\n", line_no);
525*8800Smckusick 		flushed_nl = false;
526*8800Smckusick 		dump_line ();
527*8800Smckusick 		want_blank = false;
528*8800Smckusick 	    /* don't insert blank at line start */
529*8800Smckusick 		force_nl = false;
530*8800Smckusick 	    }
531*8800Smckusick 
532*8800Smckusick 	    in_stmt = true;    /* turn on flag which causes an extra level
533*8800Smckusick 			          of indentation. this is turned off by a
534*8800Smckusick 			          ; or } */
535*8800Smckusick 	    if (s_com != e_com) {
536*8800Smckusick 	    /* the turkey has embedded a comment in a line. fix it */
537*8800Smckusick 		*e_code++ = ' ';
538*8800Smckusick 		for (t_ptr = s_com; *t_ptr; ++t_ptr)
539*8800Smckusick 		    *e_code++ = *t_ptr;
540*8800Smckusick 		*e_code++ = ' ';
541*8800Smckusick 		*e_code = '\0';/* null terminate code sect */
542*8800Smckusick 		want_blank = false;
543*8800Smckusick 		e_com = s_com;
544*8800Smckusick 	    }
545*8800Smckusick 	}
546*8800Smckusick 	else
547*8800Smckusick 	    if (type_code != comment)
548*8800Smckusick 			       /* preserve force_nl thru a comment */
549*8800Smckusick 		force_nl = false;
550*8800Smckusick     /* cancel forced newline after newline, form feed, etc */
551*8800Smckusick 
552*8800Smckusick 
553*8800Smckusick 
554*8800Smckusick     /*----------------------------------------------------*\
555*8800Smckusick     |   do switch on type of token scanned
556*8800Smckusick     \*----------------------------------------------------*/
557*8800Smckusick 	switch (type_code) {   /* now, decide what to do with the token */
558*8800Smckusick 
559*8800Smckusick 	    case form_feed:    /* found a form feed in line */
560*8800Smckusick 		use_ff = true; /* a form feed is treated much like a
561*8800Smckusick 			          newline */
562*8800Smckusick 		dump_line ();
563*8800Smckusick 		want_blank = false;
564*8800Smckusick 		break;
565*8800Smckusick 
566*8800Smckusick 	    case newline:
567*8800Smckusick 		dump_line ();
568*8800Smckusick 		++line_no;     /* keep track of input line number */
569*8800Smckusick 		want_blank = false;
570*8800Smckusick 		break;
571*8800Smckusick 
572*8800Smckusick 	    case lparen:       /* got a ( or [ */
573*8800Smckusick 		++p_l_follow;  /* count parens to make Healy happy */
574*8800Smckusick 		if (want_blank && *token != '[')
575*8800Smckusick 			       /* don't put space in front of square
576*8800Smckusick 			          bracket */
577*8800Smckusick 		    *e_code++ = ' ';
578*8800Smckusick 
579*8800Smckusick 		if (in_decl)
580*8800Smckusick 		    while ((e_code - s_code) < dec_ind)
581*8800Smckusick 			*e_code++ = ' ';
582*8800Smckusick 
583*8800Smckusick 		*e_code++ = token[0];
584*8800Smckusick 		want_blank = false;
585*8800Smckusick 		if (in_or_st && *token == '(') {
586*8800Smckusick 		/* this is a kluge to make sure that declarations will be
587*8800Smckusick 		   aaigned right if proc decl has an explicit type on it,
588*8800Smckusick 		   i.e. "int a(x) {..." */
589*8800Smckusick 		    parse (semicolon);
590*8800Smckusick 		/* I said this was a kluge... */
591*8800Smckusick 		    in_or_st = false;
592*8800Smckusick 		/* turn off flag for structure decl or initialization */
593*8800Smckusick 		}
594*8800Smckusick 
595*8800Smckusick 		break;
596*8800Smckusick 
597*8800Smckusick 	    case rparen:       /* got a ) or ] */
598*8800Smckusick 		if (--p_l_follow < 0) {
599*8800Smckusick 		    p_l_follow = 0;
600*8800Smckusick 		    printf ("%d: Extra %c\n", line_no, *token);
601*8800Smckusick 		}
602*8800Smckusick 
603*8800Smckusick 		if (e_code == s_code)/* if the paren starts the line */
604*8800Smckusick 		    paren_level = p_l_follow;
605*8800Smckusick 	    /*    then indent it */
606*8800Smckusick 
607*8800Smckusick 		*e_code++ = token[0];
608*8800Smckusick 		want_blank = true;
609*8800Smckusick 
610*8800Smckusick 		if (sp_sw && (p_l_follow == 0)) {
611*8800Smckusick 		/* check for end of if (...), or some such */
612*8800Smckusick 		    sp_sw = false;
613*8800Smckusick 		    force_nl = true;
614*8800Smckusick 		/* must force newline after if */
615*8800Smckusick 		    last_u_d = true;
616*8800Smckusick 		/* inform lexi that a following operator is unary */
617*8800Smckusick 		    in_stmt = false;
618*8800Smckusick 		/* don't use stmt continuation indentation */
619*8800Smckusick 
620*8800Smckusick 		    parse (hd_type);
621*8800Smckusick 		/* let parser worry about if, or whatever */
622*8800Smckusick 		}
623*8800Smckusick 
624*8800Smckusick 		search_brace = btype_2;
625*8800Smckusick 	    /* this should insure that constructs such as main(){... and
626*8800Smckusick 	       int[]{... have their braces put in the right place */
627*8800Smckusick 		break;
628*8800Smckusick 
629*8800Smckusick 	    case unary_op:     /* this could be any unary operation */
630*8800Smckusick 		if (want_blank)
631*8800Smckusick 		    *e_code++ = ' ';
632*8800Smckusick 
633*8800Smckusick 		if (in_decl) { /* if this is a unary op in a *//*
634*8800Smckusick 			          declaration, we should indent this token
635*8800Smckusick 			          */
636*8800Smckusick 		    for (i = 0; token[i]; ++i);
637*8800Smckusick 		/* find length of token */
638*8800Smckusick 		    while ((e_code - s_code) < (dec_ind - i))
639*8800Smckusick 			*e_code++ = ' ';
640*8800Smckusick 		/* pad it */
641*8800Smckusick 		}
642*8800Smckusick 
643*8800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
644*8800Smckusick 		    *e_code++ = *t_ptr;
645*8800Smckusick 	    /* move the token to buffer */
646*8800Smckusick 		want_blank = false;
647*8800Smckusick 		break;
648*8800Smckusick 
649*8800Smckusick 	    case binary_op:    /* any binary operation */
650*8800Smckusick 	do_binary:
651*8800Smckusick 		if (want_blank)
652*8800Smckusick 		    *e_code++ = ' ';
653*8800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
654*8800Smckusick 		    *e_code++ = *t_ptr;
655*8800Smckusick 	    /* move the operator */
656*8800Smckusick 		want_blank = true;
657*8800Smckusick 		break;
658*8800Smckusick 
659*8800Smckusick 	    case postop:       /* got a trailing ++ or -- */
660*8800Smckusick 		*e_code++ = token[0];
661*8800Smckusick 		*e_code++ = token[1];
662*8800Smckusick 		want_blank = true;
663*8800Smckusick 		break;
664*8800Smckusick 
665*8800Smckusick 	    case question:     /* got a ? */
666*8800Smckusick 		squest++;      /* this will be used when a later colon
667*8800Smckusick 			          appears so we can distinguish the
668*8800Smckusick 			          <c>?<n>:<n> construct */
669*8800Smckusick 		if (want_blank)
670*8800Smckusick 		    *e_code++ = ' ';
671*8800Smckusick 		*e_code++ = '?';
672*8800Smckusick 		want_blank = true;
673*8800Smckusick 		break;
674*8800Smckusick 
675*8800Smckusick 	    case casestmt:     /* got word 'case' or 'default' */
676*8800Smckusick 		scase = true;  /* so we can process the later colon
677*8800Smckusick 			          properly */
678*8800Smckusick 		if (want_blank)
679*8800Smckusick 		    *e_code++ = ' ';
680*8800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
681*8800Smckusick 		    *e_code++ = *t_ptr;
682*8800Smckusick 		want_blank = true;
683*8800Smckusick 		break;
684*8800Smckusick 
685*8800Smckusick 	    case colon:        /* got a ':' */
686*8800Smckusick 		if (squest > 0) {
687*8800Smckusick 		/* it is part of the <c>?<n>: <n> construct */
688*8800Smckusick 		    --squest;
689*8800Smckusick 		    if (want_blank)
690*8800Smckusick 			*e_code++ = ' ';
691*8800Smckusick 		    *e_code++ = ':';
692*8800Smckusick 		    want_blank = true;
693*8800Smckusick 		    break;
694*8800Smckusick 		}
695*8800Smckusick 
696*8800Smckusick 		in_stmt = false;
697*8800Smckusick 	    /* seeing a label does not imply we are in a stmt */
698*8800Smckusick 		for (t_ptr = s_code; *t_ptr; ++t_ptr)
699*8800Smckusick 		    *e_lab++ = *t_ptr;
700*8800Smckusick 	    /* turn everything so far into a label */
701*8800Smckusick 		e_code = s_code;
702*8800Smckusick 		*e_lab++ = ':';
703*8800Smckusick 		*e_lab++ = ' ';
704*8800Smckusick 		*e_lab = '\0';
705*8800Smckusick 
706*8800Smckusick 		force_nl = pcase = scase;
707*8800Smckusick 	    /* pcase will be used by dump_line to decide how to indent the
708*8800Smckusick 	       label. force_nl will force a case n: to be on a line by
709*8800Smckusick 	       itself */
710*8800Smckusick 		scase = false;
711*8800Smckusick 		want_blank = false;
712*8800Smckusick 		break;
713*8800Smckusick 
714*8800Smckusick 	    case semicolon:    /* got a ';' */
715*8800Smckusick 		in_or_st = false;
716*8800Smckusick 	    /* we are not in an initialization or structure declaration */
717*8800Smckusick 		scase = false; /* these will only need resetting in a
718*8800Smckusick 			          error */
719*8800Smckusick 		squest = 0;
720*8800Smckusick 
721*8800Smckusick 		if (in_decl && s_code == e_code)
722*8800Smckusick 			       /* align this in a declaration */
723*8800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
724*8800Smckusick 			*e_code++ = ' ';
725*8800Smckusick 
726*8800Smckusick 		in_decl = (dec_nest > 0);
727*8800Smckusick 	    /* if we were in a first level structure declaration, we
728*8800Smckusick 	       aren't any more */
729*8800Smckusick 
730*8800Smckusick 		if ((!sp_sw || hd_type != forstmt) && p_l_follow > 0) {
731*8800Smckusick 		/* This should be true iff there were unbalanced parens in
732*8800Smckusick 		   the stmt.  It is a bit complicated, because the
733*8800Smckusick 		   semicolon might be in a for stmt */
734*8800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
735*8800Smckusick 		    p_l_follow = 0;
736*8800Smckusick 		    if (sp_sw) {
737*8800Smckusick 		    /* this is a check for a if, while, etc. with
738*8800Smckusick 		       unbalanced parens */
739*8800Smckusick 			sp_sw = false;
740*8800Smckusick 			parse (hd_type);
741*8800Smckusick 		    /* don't lose the if, or whatever */
742*8800Smckusick 		    }
743*8800Smckusick 		}
744*8800Smckusick 
745*8800Smckusick 		*e_code++ = ';';
746*8800Smckusick 		want_blank = true;
747*8800Smckusick 		in_stmt = (p_l_follow > 0);
748*8800Smckusick 	    /* we are no longer in the middle of a stmt */
749*8800Smckusick 
750*8800Smckusick 		if (!sp_sw) {  /* if not if for (;;) */
751*8800Smckusick 		    parse (semicolon);
752*8800Smckusick 		/* let parser know about end of stmt */
753*8800Smckusick 		    force_nl = true;
754*8800Smckusick 		/* force newline after a end of stmt */
755*8800Smckusick 		}
756*8800Smckusick 
757*8800Smckusick 		break;
758*8800Smckusick 
759*8800Smckusick 	    case lbrace:       /* got a { */
760*8800Smckusick 		in_stmt = false;
761*8800Smckusick 	    /* don't indent the { */
762*8800Smckusick 		force_nl = true;
763*8800Smckusick 	    /* force other stuff on same line as { onto new line */
764*8800Smckusick 
765*8800Smckusick 		if (s_code != e_code && !btype_2) {
766*8800Smckusick 		/* bracket is not alone on line */
767*8800Smckusick 		    if (verbose)
768*8800Smckusick 			printf ("%d: Line broken\n", line_no);
769*8800Smckusick 		    dump_line ();
770*8800Smckusick 		    want_blank = false;
771*8800Smckusick 		}
772*8800Smckusick 
773*8800Smckusick 		if (p_l_follow > 0) {
774*8800Smckusick 		/* check for preceeding unbalanced parens */
775*8800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
776*8800Smckusick 		    p_l_follow = 0;
777*8800Smckusick 		    if (sp_sw) {
778*8800Smckusick 		    /* check for unclosed if, for, etc. */
779*8800Smckusick 			sp_sw = false;
780*8800Smckusick 			parse (hd_type);
781*8800Smckusick 			ind_level = i_l_follow;
782*8800Smckusick 		    }
783*8800Smckusick 		}
784*8800Smckusick 
785*8800Smckusick 		if (s_code == e_code)
786*8800Smckusick 		    ind_stmt = false;
787*8800Smckusick 	    /* don't put extra indentation on line with '{' */
788*8800Smckusick 		if (in_decl && in_or_st) {
789*8800Smckusick 		/* this is either a structure declaration or an init */
790*8800Smckusick 		    di_stack[dec_nest++] = dec_ind;
791*8800Smckusick 		    dec_ind = 0;
792*8800Smckusick 		}
793*8800Smckusick 		else
794*8800Smckusick 		    decl_on_line = false;
795*8800Smckusick 	    /* we can't be in the middle of a declaration, so don't do
796*8800Smckusick 	       special indentation of comments */
797*8800Smckusick 
798*8800Smckusick 		parse (lbrace);/* let parser know about this */
799*8800Smckusick 		if (want_blank)/* put a blank before { if { is not at
800*8800Smckusick 			          start of line */
801*8800Smckusick 		    *e_code++ = ' ';
802*8800Smckusick 		want_blank = false;
803*8800Smckusick 		*e_code++ = '{';
804*8800Smckusick 		break;
805*8800Smckusick 
806*8800Smckusick 	    case rbrace:       /* got a } */
807*8800Smckusick 		if (p_l_follow) {
808*8800Smckusick 		/* check for unclosed if, for, else. */
809*8800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
810*8800Smckusick 		    p_l_follow = 0;
811*8800Smckusick 		    sp_sw = false;
812*8800Smckusick 		}
813*8800Smckusick 
814*8800Smckusick 		if (s_code != e_code) {
815*8800Smckusick 		/* } must be first on line */
816*8800Smckusick 		    if (verbose)
817*8800Smckusick 			printf ("%d: Line broken\n", line_no);
818*8800Smckusick 		    dump_line ();
819*8800Smckusick 		}
820*8800Smckusick 
821*8800Smckusick 		*e_code++ = '}';
822*8800Smckusick 		want_blank = true;
823*8800Smckusick 		in_stmt = ind_stmt = false;
824*8800Smckusick 
825*8800Smckusick 		if (dec_nest > 0) {
826*8800Smckusick 		/* we are in multi-level structure declaration */
827*8800Smckusick 		    dec_ind = di_stack[--dec_nest];
828*8800Smckusick 		    in_decl = true;
829*8800Smckusick 		}
830*8800Smckusick 
831*8800Smckusick 		parse (rbrace);/*   let parser know about this */
832*8800Smckusick 		break;
833*8800Smckusick 
834*8800Smckusick 	    case swstmt:       /* got keyword "switch" */
835*8800Smckusick 		sp_sw = true;
836*8800Smckusick 		hd_type = swstmt;
837*8800Smckusick 	    /* keep this for when we have seen the expression */
838*8800Smckusick 		goto copy_id;  /* go move the token into buffer */
839*8800Smckusick 
840*8800Smckusick 	    case sp_paren:     /* token is if, while, for */
841*8800Smckusick 		sp_sw = true;  /* the interesting stuff is done after the
842*8800Smckusick 			          expression is scanned */
843*8800Smckusick 		hd_type = (*token == 'i' ? ifstmt :
844*8800Smckusick 			(*token == 'w' ? whilestmt : forstmt));
845*8800Smckusick 	    /* remember the type of header for later use by parser */
846*8800Smckusick 		goto copy_id;  /* copy the token into line */
847*8800Smckusick 
848*8800Smckusick 	    case sp_nparen:    /* got else, do */
849*8800Smckusick 		in_stmt = false;
850*8800Smckusick 		if (e_code != s_code) {
851*8800Smckusick 		/* make sure this starts a line */
852*8800Smckusick 		    if (verbose)
853*8800Smckusick 			printf ("%d: Line broken\n", line_no);
854*8800Smckusick 		    dump_line ();
855*8800Smckusick 		    want_blank = false;
856*8800Smckusick 		}
857*8800Smckusick 
858*8800Smckusick 		force_nl = true;
859*8800Smckusick 	    /* also, following stuff must go onto new line */
860*8800Smckusick 		parse (*token == 'e' ? elselit : dolit);
861*8800Smckusick 	    /* pass token on to parser */
862*8800Smckusick 		goto copy_id;  /* move the token into line */
863*8800Smckusick 
864*8800Smckusick 	    case decl: 	       /* we have a declaration type (int,
865*8800Smckusick 			          register, etc.) */
866*8800Smckusick 		parse (decl);  /* let parser worry about indentation */
867*8800Smckusick 		in_or_st = true;
868*8800Smckusick 	    /* this might be a structure or initialization declaration */
869*8800Smckusick 		in_decl = decl_on_line = true;
870*8800Smckusick 		for (i = 0; token[i++];);
871*8800Smckusick 	    /* get length of token */
872*8800Smckusick 
873*8800Smckusick 		if (i <= 3)
874*8800Smckusick 		    i = 4;
875*8800Smckusick 
876*8800Smckusick 		dec_ind = ((e_code - s_code + i) / ind_size + 1) * ind_size;
877*8800Smckusick 	    /* this will tell us how far to indent subsequent identifiers
878*8800Smckusick 	    */
879*8800Smckusick 		goto copy_id;
880*8800Smckusick 
881*8800Smckusick 	    case ident:        /* got an identifier or constant */
882*8800Smckusick 		if (in_decl) { /* if we are in a declaration, we must
883*8800Smckusick 			          indent identifier */
884*8800Smckusick 		    if (want_blank)
885*8800Smckusick 			*e_code++ = ' ';
886*8800Smckusick 		    want_blank = false;
887*8800Smckusick 
888*8800Smckusick 		    while ((e_code - s_code) < dec_ind)
889*8800Smckusick 			*e_code++ = ' ';
890*8800Smckusick 		}
891*8800Smckusick 		else
892*8800Smckusick 		    if (sp_sw && p_l_follow == 0) {
893*8800Smckusick 		    /* check for if expr w/o parens *//* this will make
894*8800Smckusick 		       JRM's obsurd "for ever" statements work */
895*8800Smckusick 			sp_sw = false;
896*8800Smckusick 			force_nl = true;
897*8800Smckusick 			last_u_d = true;
898*8800Smckusick 			in_stmt = false;
899*8800Smckusick 			parse (hd_type);
900*8800Smckusick 		    }
901*8800Smckusick 
902*8800Smckusick 	copy_id:
903*8800Smckusick 		if (want_blank)
904*8800Smckusick 		    *e_code++ = ' ';
905*8800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
906*8800Smckusick 		    *e_code++ = *t_ptr;
907*8800Smckusick 		want_blank = true;
908*8800Smckusick 		break;
909*8800Smckusick 
910*8800Smckusick 	    case period:       /* treat a period kind of like a binary
911*8800Smckusick 			          operation */
912*8800Smckusick 		*e_code++ = '.';
913*8800Smckusick 	    /* move the period into line */
914*8800Smckusick 		want_blank = false;
915*8800Smckusick 	    /* don't put a blank after a period */
916*8800Smckusick 		break;
917*8800Smckusick 
918*8800Smckusick 	    case comma:
919*8800Smckusick 		want_blank = (s_code != e_code);
920*8800Smckusick 	    /* only put blank after comma if comma does not start the line
921*8800Smckusick 	       */
922*8800Smckusick 		if (in_decl)   /* align these in a declaration */
923*8800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
924*8800Smckusick 			*e_code++ = ' ';
925*8800Smckusick 
926*8800Smckusick 		*e_code++ = ',';
927*8800Smckusick 
928*8800Smckusick 		if (break_comma && p_l_follow == 0 && !leave_comma)
929*8800Smckusick 		    force_nl = true;
930*8800Smckusick 
931*8800Smckusick 		break;
932*8800Smckusick 
933*8800Smckusick 	    case preesc:       /* got the character '#' */
934*8800Smckusick 		if (
935*8800Smckusick 			(s_com != e_com) ||
936*8800Smckusick 			(s_lab != e_lab) ||
937*8800Smckusick 			(s_code != e_code)) {
938*8800Smckusick 		/* true iff the '#' was not at start of the line */
939*8800Smckusick 		    printf ("%d: What is this # doing here?\n", line_no);
940*8800Smckusick 		    goto do_binary;
941*8800Smckusick 		/* treat it as a binary operator */
942*8800Smckusick 		}
943*8800Smckusick 
944*8800Smckusick 		*e_lab++ = '#';/* move whole line to 'label' buffer */
945*8800Smckusick 		while (*buf_ptr != '\n') {
946*8800Smckusick 		    *e_lab = *buf_ptr++;
947*8800Smckusick 		    if (buf_ptr >= buf_end)
948*8800Smckusick 			fill_buffer ();
949*8800Smckusick 
950*8800Smckusick 		    if (*e_lab++ == '/' && *buf_ptr == '*') {
951*8800Smckusick 		    /* check for comment on preprocessor line */
952*8800Smckusick 			e_lab - = 2;
953*8800Smckusick 		    /* skip back over slash */
954*8800Smckusick 			while (*e_lab == '\t' || *e_lab == ' ')
955*8800Smckusick 			    --e_lab;
956*8800Smckusick 		    /* strip off trailing blanks and tabs */
957*8800Smckusick 			*(++e_lab) = '\0';
958*8800Smckusick 		    /* null terminate the line */
959*8800Smckusick 			if (++buf_ptr >= buf_end)
960*8800Smckusick 			       /* space past start of comment */
961*8800Smckusick 			    fill_buffer ();
962*8800Smckusick 			col_1 = false;
963*8800Smckusick 		    /* don't let pr_comment think that this comment starts
964*8800Smckusick 		       in column 1 */
965*8800Smckusick 			decl_on_line = true;
966*8800Smckusick 		    /* treat this as a declaration for comment placement
967*8800Smckusick 		       purposes */
968*8800Smckusick 			goto proc_comment;
969*8800Smckusick 		    /* go process the comment */
970*8800Smckusick 		    }
971*8800Smckusick 		}
972*8800Smckusick 
973*8800Smckusick 		*e_lab = '\0'; /* null terminate line */
974*8800Smckusick 		pcase = false;
975*8800Smckusick 		break;	       /* subsequent processing of the newline
976*8800Smckusick 			          character will cause the line to be
977*8800Smckusick 			          printed */
978*8800Smckusick 
979*8800Smckusick 	    case comment:      /* we have gotten a /*  this is a biggie */
980*8800Smckusick 	proc_comment:
981*8800Smckusick 		pr_comment ();
982*8800Smckusick 		break;
983*8800Smckusick 	}		       /* end of big switch stmt */
984*8800Smckusick 
985*8800Smckusick 	*e_code = '\0';	       /* make sure code section is null
986*8800Smckusick 			          terminated */
987*8800Smckusick 
988*8800Smckusick     }			       /* end of main while (1) loop */
989*8800Smckusick };
990*8800Smckusick 
991*8800Smckusick /*
992*8800Smckusick  * copy input file to backup file
993*8800Smckusick  * if in_name is /blah/blah/blah/file, then backup file
994*8800Smckusick  * will be ".Bfile"
995*8800Smckusick  * then make the backup file the input and original
996*8800Smckusick  * input file the output
997*8800Smckusick  */
998*8800Smckusick bakcopy () {
999*8800Smckusick     int     n,
1000*8800Smckusick             bakchn;
1001*8800Smckusick     char    buff[512];
1002*8800Smckusick     register char  *p;
1003*8800Smckusick 
1004*8800Smckusick  /* construct file name .Bfile */
1005*8800Smckusick     for (p = in_name; *p; p++);/* skip to end of string */
1006*8800Smckusick     while (p > in_name && *p != '/')/* find last '/' */
1007*8800Smckusick 	p--;
1008*8800Smckusick     if (*p == '/')
1009*8800Smckusick 	p++;
1010*8800Smckusick     sprintf (bakfile, ".B%s", p);
1011*8800Smckusick 
1012*8800Smckusick  /* copy in_name to backup file */
1013*8800Smckusick     bakchn = creat (bakfile, 0600);
1014*8800Smckusick     if (bakchn < 0) {
1015*8800Smckusick 	printf ("can't create backup file \"%s\"\n", bakfile);
1016*8800Smckusick 	exit ();
1017*8800Smckusick     }
1018*8800Smckusick     while (n = read (input, buff, 512))
1019*8800Smckusick 	write (bakchn, buff, n);
1020*8800Smckusick     close (bakchn);
1021*8800Smckusick     close (input);
1022*8800Smckusick 
1023*8800Smckusick  /* re-open backup file as the input file */
1024*8800Smckusick     input = open (bakfile, 0);
1025*8800Smckusick     if (input < 0) {
1026*8800Smckusick 	printf ("can't re-open backup file\n");
1027*8800Smckusick 	exit ();
1028*8800Smckusick     }
1029*8800Smckusick 
1030*8800Smckusick  /* now the original input file will be the output */
1031*8800Smckusick     output = creat (in_name, 0644);
1032*8800Smckusick     if (output < 0) {
1033*8800Smckusick 	printf ("can't create %s\n", in_name);
1034*8800Smckusick 	unlink (bakfile);
1035*8800Smckusick 	exit ();
1036*8800Smckusick     }
1037*8800Smckusick }
1038*8800Smckusick 
1039*8800Smckusick 
1040*8800Smckusick set_option (arg)
1041*8800Smckusick char   *arg;
1042*8800Smckusick {
1043*8800Smckusick     register    j;
1044*8800Smckusick     for (j = 0; options[j].str != 0; ++j) {
1045*8800Smckusick 			       /* look thru list of possible options */
1046*8800Smckusick 	if (eqin (options[j].str, arg)) {
1047*8800Smckusick 	    set_var (j, arg);
1048*8800Smckusick 	    break;	       /* get out of for loop */
1049*8800Smckusick 	}
1050*8800Smckusick     }
1051*8800Smckusick 
1052*8800Smckusick     if (options[j].str == 0) { /* illegal arg given */
1053*8800Smckusick 	printf ("Unknown parameter: %s\n", arg);
1054*8800Smckusick 	exit ();
1055*8800Smckusick     }
1056*8800Smckusick }
1057*8800Smckusick 
1058*8800Smckusick 
1059*8800Smckusick set_var (j, arg)
1060*8800Smckusick char   *arg;
1061*8800Smckusick {
1062*8800Smckusick     switch (options[j].code) {
1063*8800Smckusick 	case 1: 	       /* have -lnnn */
1064*8800Smckusick 	    max_col = atoi (&arg[2]);
1065*8800Smckusick 	    break;
1066*8800Smckusick 	case 2: 	       /* have -cnnn */
1067*8800Smckusick 	    com_ind = atoi (&arg[2]);
1068*8800Smckusick 	    break;
1069*8800Smckusick 	case 3: 	       /* have -innn */
1070*8800Smckusick 	    ind_size = atoi (&arg[2]);
1071*8800Smckusick 	    break;
1072*8800Smckusick 	case 4: 	       /* have -cdnnn */
1073*8800Smckusick 	    decl_com_ind = atoi (&arg[3]);
1074*8800Smckusick 	    break;
1075*8800Smckusick 	case 5: 	       /* have -v */
1076*8800Smckusick 	    verbose = true;
1077*8800Smckusick 	    break;
1078*8800Smckusick 	case 6: 	       /* have -nv */
1079*8800Smckusick 	    verbose = false;
1080*8800Smckusick 	    break;
1081*8800Smckusick 	case 7: 	       /* have -dj */
1082*8800Smckusick 	    ljust_decl = true;
1083*8800Smckusick 	    break;
1084*8800Smckusick 	case 8: 	       /* have -ndj */
1085*8800Smckusick 	    ljust_decl = false;
1086*8800Smckusick 	    break;
1087*8800Smckusick 	case 9: 	       /* -nbc */
1088*8800Smckusick 	    leave_comma = true;
1089*8800Smckusick 	    break;
1090*8800Smckusick 	case 10: 	       /* -bc */
1091*8800Smckusick 	    leave_comma = false;
1092*8800Smckusick 	    break;
1093*8800Smckusick 	case 13: 	       /* -dnnn */
1094*8800Smckusick 	    unindent_displace = atoi (&arg[2]);
1095*8800Smckusick 	    break;
1096*8800Smckusick 	case 14: 	       /* -br */
1097*8800Smckusick 	    btype_2 = true;
1098*8800Smckusick 	    break;
1099*8800Smckusick 	case 15: 	       /* -bl */
1100*8800Smckusick 	    btype_2 = false;
1101*8800Smckusick 	    break;
1102*8800Smckusick 	case 16:
1103*8800Smckusick 	    if(input<0) input = 0;
1104*8800Smckusick 	    if(output<0) output = 1;
1105*8800Smckusick 	    break;
1106*8800Smckusick     }
1107*8800Smckusick }
1108*8800Smckusick 
1109*8800Smckusick 
1110*8800Smckusick /*
1111*8800Smckusick  * GETPRO - get profile file
1112*8800Smckusick  * profile file is max 127 characters
1113*8800Smckusick  */
1114*8800Smckusick getpro (name, buf)
1115*8800Smckusick char   *name,		       /* profile file name, as in '.indent.pro'
1116*8800Smckusick 			       */
1117*8800Smckusick        *buf;		       /* will receive contents of .pro file */
1118*8800Smckusick {
1119*8800Smckusick     register    chn,
1120*8800Smckusick                 n;
1121*8800Smckusick     char    file[32];
1122*8800Smckusick 
1123*8800Smckusick     file[0] = 0;
1124*8800Smckusick     strcat (file, getenv ("HOME"));
1125*8800Smckusick     strcat (file, "/");
1126*8800Smckusick     strcat (file, name);
1127*8800Smckusick     chn = open (file, 0);
1128*8800Smckusick     if (chn < 0)
1129*8800Smckusick 	return (-1);
1130*8800Smckusick     n = read (chn, buf, 127);
1131*8800Smckusick     if (n < 0)
1132*8800Smckusick 	return (-1);
1133*8800Smckusick     buf[n--] = 0;	       /* null terminate line */
1134*8800Smckusick     if (buf[n] == '\n')
1135*8800Smckusick 	buf[n] = 0;
1136*8800Smckusick     close (chn);
1137*8800Smckusick     return (0);
1138*8800Smckusick }
1139*8800Smckusick 
1140*8800Smckusick 
1141*8800Smckusick /*
1142*8800Smckusick  * strip off arguments in a string:
1143*8800Smckusick  * p is address of a character pointer
1144*8800Smckusick  * nextchr returns pointer to front of first arg
1145*8800Smckusick  * arg is null terminated.
1146*8800Smckusick  * p is reset to after arg for subsequent calls
1147*8800Smckusick  */
1148*8800Smckusick char   *nxtarg (p)
1149*8800Smckusick char  **p;
1150*8800Smckusick {
1151*8800Smckusick     register char  *f,
1152*8800Smckusick                    *b;
1153*8800Smckusick     f = b = *p;
1154*8800Smckusick     while (*f && (*f == ' ' || *f == '\t'))
1155*8800Smckusick 	f++;
1156*8800Smckusick     while (*b && (*b != ' ' && *b != '\t'))
1157*8800Smckusick 	b++;
1158*8800Smckusick     if (*b != 0)
1159*8800Smckusick 	*b++ = 0;
1160*8800Smckusick     *p = b;
1161*8800Smckusick     return (f);
1162*8800Smckusick }
1163*8800Smckusick 
1164*8800Smckusick 
1165*8800Smckusick set_profile () {
1166*8800Smckusick     char    line[128],
1167*8800Smckusick            *b;
1168*8800Smckusick     register char  *f;
1169*8800Smckusick     extern char *nxtarg ();
1170*8800Smckusick 
1171*8800Smckusick     if (getpro (".indent.pro", line) < 0)
1172*8800Smckusick 	return;
1173*8800Smckusick     b = line;
1174*8800Smckusick     if(verbose) printf ("profile: %s\n", b);
1175*8800Smckusick     while (*(f = nxtarg (&b)))
1176*8800Smckusick 	set_option (f);
1177*8800Smckusick }
1178