xref: /csrg-svn/usr.bin/indent/indent.c (revision 21968)
1*21968Sdist /*
2*21968Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21968Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21968Sdist  * specifies the terms and conditions for redistribution.
5*21968Sdist  */
68800Smckusick 
7*21968Sdist #ifndef lint
8*21968Sdist char copyright[] =
9*21968Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*21968Sdist  All rights reserved.\n";
11*21968Sdist #endif not lint
12*21968Sdist 
13*21968Sdist #ifndef lint
14*21968Sdist static char sccsid[] = "@(#)indent.c	5.1 (Berkeley) 06/04/85";
15*21968Sdist #endif not lint
16*21968Sdist 
178800Smckusick /*
188800Smckusick 
198800Smckusick 			  Copyright (C) 1976
208800Smckusick 				by the
218800Smckusick 			  Board of Trustees
228800Smckusick 				of the
238800Smckusick 			University of Illinois
248800Smckusick 
258800Smckusick 			 All rights reserved
268800Smckusick 
278800Smckusick 
288800Smckusick NAME:
298800Smckusick 	indent main program
308800Smckusick 
318800Smckusick FUNCTION:
328800Smckusick 	This is the main program of the indent program.  Indent will take a C
338800Smckusick 	program source and reformat it into a semi-reasonable form.
348800Smckusick 
358800Smckusick ALGORITHM:
368800Smckusick 	The routine lexi scans tokens and passes them back one at a time to the
378800Smckusick 	main routine.  The subroutine parse takes care of much of the work of
388800Smckusick 	figuring indentation level.
398800Smckusick 
408800Smckusick 	1) Call lexi
418800Smckusick 	2) Enter a monster switch statement on the code returned by lexi.  If
428800Smckusick 	   the indentation level for the line yet to be printed should be
438800Smckusick 	   changed, set the variable ind_level.  If the indentation level for
448800Smckusick 	   the following line should be changed, set the variable i_l_follow.
458800Smckusick 
468800Smckusick PARAMETERS:
478800Smckusick 	None
488800Smckusick 
498800Smckusick RETURNS:
508800Smckusick 	Nothing
518800Smckusick 
528800Smckusick GLOBALS:
538800Smckusick 	be_save =
548800Smckusick 	break_comma
558800Smckusick 	bp_save =
568800Smckusick 	btype_2 =
578800Smckusick 	code_lines
588800Smckusick 	com_ind =
598800Smckusick 	com_lines
608800Smckusick 	dec_nest =
618800Smckusick 	decl_com_ind =
628800Smckusick 	decl_on_line =
638800Smckusick 	i_l_follow =
648800Smckusick 	in_decl =
658800Smckusick 	ind_level =
668800Smckusick 	ind_size =
678800Smckusick 	ind_stmt =
688800Smckusick 	last_u_d =
698800Smckusick 	leave_comma =
708800Smckusick 	line_no =
718800Smckusick 	ljust_decl =
728800Smckusick 	max_col =
738800Smckusick 	out_coms
748800Smckusick 	out_lines
758800Smckusick 	p_l_follow =
768800Smckusick 	paren_level =
778800Smckusick 	pcase =
788800Smckusick 	sc_end =
798800Smckusick 	unindent_displace =
808800Smckusick 	use_ff =
818800Smckusick 	verbose =
828800Smckusick 
838800Smckusick CALLS:
848800Smckusick 	atoi (lib)
858800Smckusick 	cmp
868800Smckusick 	creat (lib)
878800Smckusick 	dump_line
888800Smckusick 	eqin
898800Smckusick 	fill_buffer
908800Smckusick 	lexi
918800Smckusick 	open (lib)
928800Smckusick 	parse
938800Smckusick 	pr_comment
948800Smckusick 	printf (lib)
958800Smckusick 	seek (lib)
968800Smckusick 	time (lib)
978800Smckusick 
988800Smckusick CALLED BY:
998800Smckusick 	No one (main routine)
1008800Smckusick 
1018800Smckusick HISTORY:
1028800Smckusick 	November 1976	D A Willcox of CAC	Initial coding
1038800Smckusick 	12/9/76		D A Willcox of CAC	Fixed defaults for decl_com_ind
1048800Smckusick 						to be 8 less than com_ind if
1058800Smckusick 						left justifying declarations
1068800Smckusick 	12/9/76		D A Willcox of CAC	Fixed processing of nested
1078800Smckusick 						<c>?<s>:<s> constructs
1088800Smckusick 	1/7/77		D A Willcox of CAC	Added check for overwrite of
1098800Smckusick 						input file
1108800Smckusick 						Added code to handle -br and -bl
1118800Smckusick 						parameters
1128800Smckusick */
1138800Smckusick #include "indent_globs.h";
1148800Smckusick #include "indent_codes.h";
1158800Smckusick 
1168800Smckusick /* #define dolog 1	/* if this define is removed, then the code to
1178800Smckusick 			   produce a log file will be removed */
1188800Smckusick 
1198800Smckusick struct templ {		       /* this is a template for the list of
1208800Smckusick 			          command line args */
1218800Smckusick     char   *str;	       /* pointer to string which is a valid
1228800Smckusick 			          command line arg */
1238800Smckusick     int     code;	       /* code to be used in switch for processing
1248800Smckusick 			          this arg */
1258800Smckusick };
1268800Smckusick 
1278800Smckusick 
1288800Smckusick struct templ    options[] =
1298800Smckusick {			       /* warning - because of the way that this
1308800Smckusick 			          table is scanned, if one entry is an
1318800Smckusick 			          initial substring of another, then the
1328800Smckusick 			          longer entry should occur first */
1338800Smckusick     "-cd", 4,
1348800Smckusick     "-c", 2,
1358800Smckusick     "-l", 1,
1368800Smckusick     "-i", 3,
1378800Smckusick     "-v", 5,
1388800Smckusick     "-nv", 6,
1398800Smckusick     "-dj", 7,
1408800Smckusick     "-d", 13,		       /* unindented comment placement */
1418800Smckusick     "-ndj", 8,
1428800Smckusick     "-bc", 10,		       /* break after command in decl */
1438800Smckusick     "-nbc", 9,		       /* don't break after comma */
1448800Smckusick     "-br", 14,		       /* put brace on right of stmt */
1458800Smckusick     "-bl", 15,		       /* put brace on left by itself */
1468800Smckusick     "-st", 16,		       /* use the standard input and output
1478800Smckusick 				  files */
1488800Smckusick     0, 0
1498800Smckusick };
1508800Smckusick 
1518800Smckusick 
1528800Smckusick char   *in_name = "Standard Input";
1538800Smckusick 			       /* will always point to name of input file
1548800Smckusick 			       */
1558800Smckusick char   *out_name = "Standard Output";
1568800Smckusick 			       /* will always point to name of output file
1578800Smckusick 			          */
1588800Smckusick char    bakfile[32] = "";
1598800Smckusick 
1608800Smckusick main (argc, argv)
1618800Smckusick int     argc;
1628800Smckusick char  **argv;
1638800Smckusick {
1648800Smckusick 
1658800Smckusick     int     dec_ind;	       /* current indentation for declarations */
1668800Smckusick     int     di_stack[20];      /* a stack of structure indentation levels
1678800Smckusick 			       */
1688800Smckusick     int     flushed_nl;	       /* used when buffering up comments to
1698800Smckusick 			          remember that a newline was passed over
1708800Smckusick 			       */
1718800Smckusick     int     force_nl;	       /* when true, code must be broken */
1728800Smckusick     int     hd_type;	       /* used to store type of stmt for if (...),
1738800Smckusick 			          for (...), etc */
1748800Smckusick     register int    i;	       /* local loop counter */
1758800Smckusick     int     in_or_st;	       /* Will be true iff there has been a
1768800Smckusick 			          declarator (e.g. int or char) and no
1778800Smckusick 			          left paren since the last semicolon.
1788800Smckusick 			          When true, a { is starting a structure
1798800Smckusick 			          definition or an initialization list */
1808800Smckusick     register int    j;	       /* local loop counter */
1818800Smckusick     int     scase;	       /* set to true when we see a case, so we
1828800Smckusick 			          will know what to do with the following
1838800Smckusick 			          colon */
1848800Smckusick     int     sp_sw;	       /* when true, we are in the expressin of
1858800Smckusick 			          if(...), while(...), etc. */
1868800Smckusick     int     squest;	       /* when this is positive, we have seen a ?
1878800Smckusick 			          without the matching : in a <c>?<s>:<s>
1888800Smckusick 			          construct */
1898800Smckusick     register char  *t_ptr;     /* used for copying tokens */
1908800Smckusick     int     type_code;	       /* the type of token, returned by lexi */
1918800Smckusick     int     want_blank;	       /* set to true when the following token
1928800Smckusick 			          should be prefixed by a blank. (Said
1938800Smckusick 			          prefixing is ignored in some cases.) */
1948800Smckusick 
1958800Smckusick #ifdef dolog		       /* include declarations needed for log */
1968800Smckusick     int     log_fid;	       /* fid of log file */
1978800Smckusick 
1988800Smckusick     struct logtmpl {	       /* structure of a log entry */
1998800Smckusick 	int     tvec[2];       /* time of execution */
2008800Smckusick 	char    inp;	       /* input fid */
2018800Smckusick 	char    outp;	       /* output fid */
2028800Smckusick 	int     nout;	       /* # output lines */
2038800Smckusick 	int     ncom;	       /* # comments */
2048800Smckusick 	int     wcom;	       /* # lines w/ comments */
2058800Smckusick 	int     wcode;	       /* # lines w/code */
2068800Smckusick 	char    mc;	       /* max line size */
2078800Smckusick 	char    ci;	       /* comment indentation */
2088800Smckusick 	char    inds;	       /* indent size */
2098800Smckusick 	char    dci;	       /* decl comment indentation */
2108800Smckusick 	char    verb;	       /* verbose */
2118800Smckusick 	char    ljus;	       /* left just */
2128800Smckusick 	char    lvcom;	       /* leave commas */
2138800Smckusick 	char    unin;	       /* unindented comment indentation */
2148800Smckusick 	char    uid;	       /* the user id */
2158800Smckusick 	char    bropt;	       /* btype_2 */
2168800Smckusick 	int     reserved[2];
2178800Smckusick     };
2188800Smckusick 
2198800Smckusick     struct logtmpl  logent;
2208800Smckusick #endif
2218800Smckusick 
2228800Smckusick /*-----------------------------------------------*\
2238800Smckusick |    INITIALIZATION
2248800Smckusick \*-----------------------------------------------*/
2258800Smckusick 
2268800Smckusick 
2278800Smckusick     combuf[0] = codebuf[0] = labbuf[0] = ' ';
2288800Smckusick  /* set up code, label, and comment buffers */
2298800Smckusick     combuf[1] = codebuf[1] = labbuf[1] = '\0';
2308800Smckusick     s_lab = e_lab = labbuf + 1;
2318800Smckusick     s_code = e_code = codebuf + 1;
2328800Smckusick     s_com = e_com = combuf + 1;
2338800Smckusick 
2348800Smckusick     buf_ptr = buf_end = in_buffer;
2358800Smckusick     line_no = 1;
2368800Smckusick     had_eof = in_decl = decl_on_line = break_comma = false;
2378800Smckusick     sp_sw = force_nl = false;
2388800Smckusick     in_or_st = false;
2398800Smckusick     bl_line = true;
2408800Smckusick     dec_ind = 0;
2418800Smckusick     di_stack[dec_nest = 0] = 0;
2428800Smckusick     want_blank = in_stmt = ind_stmt = false;
2438800Smckusick 
2448800Smckusick 
2458800Smckusick     scase = pcase = false;
2468800Smckusick     squest = 0;
2478800Smckusick     sc_end = 0;
2488800Smckusick     bp_save = 0;
2498800Smckusick     be_save = 0;
2508800Smckusick 
2518800Smckusick     input = -1;
2528800Smckusick     output = -1;
2538800Smckusick     ljust_decl = d_ljust;
2548800Smckusick 
2558800Smckusick 
2568800Smckusick 
2578800Smckusick /*--------------------------------------------------*\
2588800Smckusick |   COMMAND LINE SCAN
2598800Smckusick \*--------------------------------------------------*/
2608800Smckusick 
2618800Smckusick     max_col = d_max_col;       /* set up some default values */
2628800Smckusick     com_ind = d_com_ind;
2638800Smckusick     ind_size = d_ind_size;
2648800Smckusick     verbose = d_verbose;
2658800Smckusick     decl_com_ind = 0;	       /* if this is not set to some positive
2668800Smckusick 			          value by an arg, we will set this equal
2678800Smckusick 			          to com_ind */
2688800Smckusick     btype_2 = d_btype_2;
2698800Smckusick     unindent_displace = d_unindent;
2708800Smckusick     leave_comma = d_leave_comma;
2718800Smckusick 
2728800Smckusick     set_profile ();
2738800Smckusick 
2748800Smckusick     for (i = 1; i < argc; ++i) {
2758800Smckusick     /* look thru args (if any) for changes to defaults */
2768800Smckusick 	if (argv[i][0] != '-') {/* no flag on parameter */
2778800Smckusick 	    if (input < 0) {   /* we must have the input file */
2788800Smckusick 		in_name = argv[i];	/* remember name of input
2798800Smckusick 					   file */
2808800Smckusick 		input = open (in_name, 0);
2818800Smckusick 		if (input < 0) {	/* check for open error */
2828800Smckusick 		    printf ("Can't open %s\n", argv[i]);
2838800Smckusick 		    exit ();
2848800Smckusick 		}
2858800Smckusick 		continue;
2868800Smckusick 	    }
2878800Smckusick 	    else
2888800Smckusick 		if (output < 0) {	/* we have the output file */
2898800Smckusick 		    out_name = argv[i];	/* remember name of output file */
2908800Smckusick 		    if (cmp (in_name, out_name) == 0) {	 /* attempt to
2918800Smckusick 					   overwright the file */
2928800Smckusick 			printf ("Input and output files must be different\n");
2938800Smckusick 			exit ();
2948800Smckusick 		    }
2958800Smckusick 		    output = creat (out_name, 0644);
2968800Smckusick 		    if (output < 0) {   /* check for create error */
2978800Smckusick 			printf ("Can't create %s\n", argv[i]);
2988800Smckusick 			exit ();
2998800Smckusick 		    }
3008800Smckusick 		    continue;
3018800Smckusick 		}
3028800Smckusick 
3038800Smckusick 	    printf ("Unknown parameter: %s\n", argv[i]);
3048800Smckusick 	    exit ();
3058800Smckusick 	}
3068800Smckusick 	else
3078800Smckusick 	    set_option (argv[i]);
3088800Smckusick 
3098800Smckusick     }			       /* end of for */
3108800Smckusick 
3118800Smckusick     if (input < 0) {
3128800Smckusick 	printf ("Usage: indent file [ outfile ] [ options ]\n");
3138800Smckusick 	exit ();
3148800Smckusick     }
3158800Smckusick     if (output < 0) {
3168800Smckusick 	out_name = in_name;
3178800Smckusick 	bakcopy ();
3188800Smckusick     }
3198800Smckusick 
3208800Smckusick     if (com_ind <= 1)
3218800Smckusick 	com_ind = 2;	       /* don't put normal comments before column
3228800Smckusick 			          2 */
3238800Smckusick 
3248800Smckusick     if (decl_com_ind <= 0)     /* if not specified by user, set this */
3258800Smckusick 	decl_com_ind = ljust_decl ? (com_ind <= 10 ? 2 : com_ind - 8) : com_ind;
3268800Smckusick 
3278800Smckusick     fill_buffer ();	       /* get first batch of stuff into input
3288800Smckusick 			          buffer */
3298800Smckusick 
3308800Smckusick     parse (semicolon);
3318800Smckusick /*-----------------------------------------------------
3328800Smckusick |   START OF MAIN LOOP
3338800Smckusick \*----------------------------------------------------*/
3348800Smckusick 
3358800Smckusick     while (1) {		       /* this is the main loop.  it will go until
3368800Smckusick 			          we reach eof */
3378800Smckusick 	type_code = lexi ();   /* lexi reads one token.  The actual
3388800Smckusick 			          characters read are stored in "token".
3398800Smckusick 			          lexi returns a code indicating the type
3408800Smckusick 			          of token */
3418800Smckusick 
3428800Smckusick     /*
3438800Smckusick      * The following code moves everything following an if (), while (),
3448800Smckusick      * else, etc. up to the start of the following stmt to a buffer.  This
3458800Smckusick      * allows proper handling of both kinds of brace placement.
3468800Smckusick      */
3478800Smckusick 
3488800Smckusick 	flushed_nl = false;
3498800Smckusick 	while (search_brace) { /* if we scanned an if(), while(), etc., we
3508800Smckusick 			          might need to copy stuff into a buffer
3518800Smckusick 	*//* we must loop, copying stuff into save_com, until we find the
3528800Smckusick 	   start of the stmt which follows the if, or whatever */
3538800Smckusick 	    switch (type_code) {
3548800Smckusick 		case newline:
3558800Smckusick 		    ++line_no;
3568800Smckusick 		    flushed_nl = true;
3578800Smckusick 		case form_feed:
3588800Smckusick 		    break;     /* form feeds and newlines found here will
3598800Smckusick 			          be ignored */
3608800Smckusick 
3618800Smckusick 		case lbrace:   /* this is a brace that starts the compound
3628800Smckusick 			          stmt */
3638800Smckusick 		    if (sc_end == 0) {
3648800Smckusick 		    /* ignore buffering if a comment wasn't stored up */
3658800Smckusick 			search_brace = false;
3668800Smckusick 			goto check_type;
3678800Smckusick 		    }
3688800Smckusick 
3698800Smckusick 		    if (btype_2) {
3708800Smckusick 			save_com[0] = '{';
3718800Smckusick 		    /* we either want to put the brace right after the if
3728800Smckusick 		    */
3738800Smckusick 			goto sw_buffer;
3748800Smckusick 		    /* go to common code to get out of this loop */
3758800Smckusick 		    }
3768800Smckusick 
3778800Smckusick 		default:       /* it is the start of a normal statment */
3788800Smckusick 		    if (flushed_nl)
3798800Smckusick 			       /* if we flushed a newline, make sure it is
3808800Smckusick 			          put back */
3818800Smckusick 			force_nl = true;
3828800Smckusick 
3838800Smckusick 		    if (sc_end == 0) {
3848800Smckusick 		    /* ignore buffering if comment wasn't saved up */
3858800Smckusick 			search_brace = false;
3868800Smckusick 			goto check_type;
3878800Smckusick 		    }
3888800Smckusick 
3898800Smckusick 		    if (force_nl) {
3908800Smckusick 		    /* if we should insert a nl here, put it into the
3918800Smckusick 		       buffer */
3928800Smckusick 			force_nl = false;
3938800Smckusick 			--line_no;
3948800Smckusick 		    /* this will be re-increased when the nl is read from
3958800Smckusick 		       the buffer */
3968800Smckusick 			*sc_end++ = '\n';
3978800Smckusick 			*sc_end++ = ' ';
3988800Smckusick 			if (verbose && !flushed_nl)
3998800Smckusick 			       /* print error msg if the line was not
4008800Smckusick 			          already broken */
4018800Smckusick 			    printf ("%d: Line broken\n", line_no);
4028800Smckusick 			flushed_nl = false;
4038800Smckusick 		    }
4048800Smckusick 
4058800Smckusick 		    for (t_ptr = token; *t_ptr; ++t_ptr)
4068800Smckusick 			*sc_end++ = *t_ptr;
4078800Smckusick 		/* copy token into temp buffer */
4088800Smckusick 
4098800Smckusick 	    sw_buffer:
4108800Smckusick 		    search_brace = false;
4118800Smckusick 		/* stop looking for start of stmt */
4128800Smckusick 		    bp_save = buf_ptr;
4138800Smckusick 		/* save current input buffer */
4148800Smckusick 		    be_save = buf_end;
4158800Smckusick 		    buf_ptr = save_com;
4168800Smckusick 		/* fix so that subsequent calls to lexi will take tokens
4178800Smckusick 		   out of save_com */
4188800Smckusick 		    *sc_end++ = ' ';
4198800Smckusick 		/* add trailing blank, just in case */
4208800Smckusick 		    buf_end = sc_end;
4218800Smckusick 		    sc_end = 0;
4228800Smckusick 		    break;
4238800Smckusick 
4248800Smckusick 		case comment:  /* we have a comment, so we must copy it
4258800Smckusick 			          into the buffer */
4268800Smckusick 		    if (sc_end == 0) {
4278800Smckusick 		    /* if this is the first comment, we must set up the
4288800Smckusick 		       buffer */
4298800Smckusick 			save_com[0] = save_com[1] = ' ';
4308800Smckusick 			sc_end = &(save_com[2]);
4318800Smckusick 		    }
4328800Smckusick 		    else {
4338800Smckusick 			*sc_end++ = '\n';
4348800Smckusick 		    /* add newline between comments */
4358800Smckusick 			*sc_end++ = ' ';
4368800Smckusick 			--line_no;
4378800Smckusick 		    }
4388800Smckusick 
4398800Smckusick 		    *sc_end++ = '/';
4408800Smckusick 		/* copy in start of comment */
4418800Smckusick 		    *sc_end++ = '*';
4428800Smckusick 
4438800Smckusick 		    for (;;) { /* loop until we get to the end of the
4448800Smckusick 			          comment */
4458800Smckusick 			*sc_end = *buf_ptr++;
4468800Smckusick 			if (buf_ptr >= buf_end)
4478800Smckusick 			    fill_buffer ();
4488800Smckusick 
4498800Smckusick 			if (*sc_end++ == '*' && *buf_ptr == '/')
4508800Smckusick 			    break;
4518800Smckusick 		    /* we are at end of comment */
4528800Smckusick 
4538800Smckusick 			if (sc_end >= &(save_com[sc_size])) {
4548800Smckusick 			/* check for temp buffer overflow */
4558800Smckusick 			    printf ("%d: Internal buffer overflow.\n",
4568800Smckusick 				    line_no);
4578800Smckusick 			    printf ("Move big comment from right after if,\
4588800Smckusick  while, or whatever.\n");
4598800Smckusick 			    exit ();
4608800Smckusick 			}
4618800Smckusick 		    }
4628800Smckusick 
4638800Smckusick 		    *sc_end++ = '/';
4648800Smckusick 		/* add ending slash */
4658800Smckusick 		    if (++buf_ptr >= buf_end)/* get past / in buffer */
4668800Smckusick 			fill_buffer ();
4678800Smckusick 		    break;
4688800Smckusick 	    }		       /* end of switch */
4698800Smckusick 
4708800Smckusick 	    if (type_code != 0)/* we must make this check, just in case
4718800Smckusick 			          there was an unexpected EOF */
4728800Smckusick 		type_code = lexi ();
4738800Smckusick 	/* read another token */
4748800Smckusick 	}		       /* end of while (serach_brace) */
4758800Smckusick check_type:
4768800Smckusick 
4778800Smckusick 	if (type_code == 0) {  /* we got eof */
4788800Smckusick 	    if (s_lab != e_lab || s_code != e_code
4798800Smckusick 		    || s_com != e_com)/* must dump end of line */
4808800Smckusick 		dump_line ();
4818800Smckusick 	    if (i_l_follow != 0)/* check for balanced braces */
4828800Smckusick 		printf ("%d too few }'s\n", i_l_follow);
4838800Smckusick 
4848800Smckusick #ifdef dolog		       /* only include this stuff if we want to
4858800Smckusick 			          keep a log */
4868800Smckusick 	    log_fid = open ("/mnt/net/willcox/indent/indent_log", 1);
4878800Smckusick 	/* open the log file */
4888800Smckusick 	    if (log_fid >= 0) {
4898800Smckusick 		seek (log_fid, 0, 2);
4908800Smckusick 	    /* point to end of log */
4918800Smckusick 		time (logent.tvec);
4928800Smckusick 	    /* get current time */
4938800Smckusick 		logent.inp = input;
4948800Smckusick 	    /* set up the log entry */
4958800Smckusick 		logent.outp = output;
4968800Smckusick 		logent.nout = out_lines;
4978800Smckusick 		logent.ncom = out_coms;
4988800Smckusick 		logent.wcom = com_lines;
4998800Smckusick 		logent.wcode = code_lines;
5008800Smckusick 		logent.mc = max_col;
5018800Smckusick 		logent.ci = com_ind;
5028800Smckusick 		logent.inds = ind_size;
5038800Smckusick 		logent.dci = decl_com_ind;
5048800Smckusick 		logent.verb = verbose;
5058800Smckusick 		logent.ljus = ljust_decl;
5068800Smckusick 		logent.lvcom = leave_comma;
5078800Smckusick 		logent.unin = unindent_displace;
5088800Smckusick 		logent.uid = getuid ();
5098800Smckusick 		logent.bropt = btype_2;
5108800Smckusick 		write (log_fid, &logent, sizeof logent);
5118800Smckusick 	    }
5128800Smckusick #endif
5138800Smckusick 	    if (verbose) {
5148800Smckusick 		printf ("There were %d output lines and %d comments\n",
5158800Smckusick 			out_lines, out_coms);
5168800Smckusick 		printf ("(Lines with comments)/(Lines with code): %6.3f\n",
5178800Smckusick 			(1.0 * com_lines) / code_lines);
5188800Smckusick 	    }
5198800Smckusick 
5208800Smckusick 	    exit ();
5218800Smckusick 	}
5228800Smckusick 
5238800Smckusick 	if (
5248800Smckusick 		(type_code != comment) &&
5258800Smckusick 		(type_code != newline) &&
5268800Smckusick 		(type_code != preesc) &&
5278800Smckusick 		(type_code != form_feed)) {
5288800Smckusick 	    if (
5298800Smckusick 		    force_nl
5308800Smckusick 		    &&
5318800Smckusick 		    (type_code != semicolon) &&
5328800Smckusick 		    (
5338800Smckusick 			type_code != lbrace
5348800Smckusick 			||
5358800Smckusick 			!btype_2
5368800Smckusick 		    )) {       /* we should force a broken line here */
5378800Smckusick 		if (verbose && !flushed_nl)
5388800Smckusick 		    printf ("%d: Line broken\n", line_no);
5398800Smckusick 		flushed_nl = false;
5408800Smckusick 		dump_line ();
5418800Smckusick 		want_blank = false;
5428800Smckusick 	    /* don't insert blank at line start */
5438800Smckusick 		force_nl = false;
5448800Smckusick 	    }
5458800Smckusick 
5468800Smckusick 	    in_stmt = true;    /* turn on flag which causes an extra level
5478800Smckusick 			          of indentation. this is turned off by a
5488800Smckusick 			          ; or } */
5498800Smckusick 	    if (s_com != e_com) {
5508800Smckusick 	    /* the turkey has embedded a comment in a line. fix it */
5518800Smckusick 		*e_code++ = ' ';
5528800Smckusick 		for (t_ptr = s_com; *t_ptr; ++t_ptr)
5538800Smckusick 		    *e_code++ = *t_ptr;
5548800Smckusick 		*e_code++ = ' ';
5558800Smckusick 		*e_code = '\0';/* null terminate code sect */
5568800Smckusick 		want_blank = false;
5578800Smckusick 		e_com = s_com;
5588800Smckusick 	    }
5598800Smckusick 	}
5608800Smckusick 	else
5618800Smckusick 	    if (type_code != comment)
5628800Smckusick 			       /* preserve force_nl thru a comment */
5638800Smckusick 		force_nl = false;
5648800Smckusick     /* cancel forced newline after newline, form feed, etc */
5658800Smckusick 
5668800Smckusick 
5678800Smckusick 
5688800Smckusick     /*----------------------------------------------------*\
5698800Smckusick     |   do switch on type of token scanned
5708800Smckusick     \*----------------------------------------------------*/
5718800Smckusick 	switch (type_code) {   /* now, decide what to do with the token */
5728800Smckusick 
5738800Smckusick 	    case form_feed:    /* found a form feed in line */
5748800Smckusick 		use_ff = true; /* a form feed is treated much like a
5758800Smckusick 			          newline */
5768800Smckusick 		dump_line ();
5778800Smckusick 		want_blank = false;
5788800Smckusick 		break;
5798800Smckusick 
5808800Smckusick 	    case newline:
5818800Smckusick 		dump_line ();
5828800Smckusick 		++line_no;     /* keep track of input line number */
5838800Smckusick 		want_blank = false;
5848800Smckusick 		break;
5858800Smckusick 
5868800Smckusick 	    case lparen:       /* got a ( or [ */
5878800Smckusick 		++p_l_follow;  /* count parens to make Healy happy */
5888800Smckusick 		if (want_blank && *token != '[')
5898800Smckusick 			       /* don't put space in front of square
5908800Smckusick 			          bracket */
5918800Smckusick 		    *e_code++ = ' ';
5928800Smckusick 
5938800Smckusick 		if (in_decl)
5948800Smckusick 		    while ((e_code - s_code) < dec_ind)
5958800Smckusick 			*e_code++ = ' ';
5968800Smckusick 
5978800Smckusick 		*e_code++ = token[0];
5988800Smckusick 		want_blank = false;
5998800Smckusick 		if (in_or_st && *token == '(') {
6008800Smckusick 		/* this is a kluge to make sure that declarations will be
6018800Smckusick 		   aaigned right if proc decl has an explicit type on it,
6028800Smckusick 		   i.e. "int a(x) {..." */
6038800Smckusick 		    parse (semicolon);
6048800Smckusick 		/* I said this was a kluge... */
6058800Smckusick 		    in_or_st = false;
6068800Smckusick 		/* turn off flag for structure decl or initialization */
6078800Smckusick 		}
6088800Smckusick 
6098800Smckusick 		break;
6108800Smckusick 
6118800Smckusick 	    case rparen:       /* got a ) or ] */
6128800Smckusick 		if (--p_l_follow < 0) {
6138800Smckusick 		    p_l_follow = 0;
6148800Smckusick 		    printf ("%d: Extra %c\n", line_no, *token);
6158800Smckusick 		}
6168800Smckusick 
6178800Smckusick 		if (e_code == s_code)/* if the paren starts the line */
6188800Smckusick 		    paren_level = p_l_follow;
6198800Smckusick 	    /*    then indent it */
6208800Smckusick 
6218800Smckusick 		*e_code++ = token[0];
6228800Smckusick 		want_blank = true;
6238800Smckusick 
6248800Smckusick 		if (sp_sw && (p_l_follow == 0)) {
6258800Smckusick 		/* check for end of if (...), or some such */
6268800Smckusick 		    sp_sw = false;
6278800Smckusick 		    force_nl = true;
6288800Smckusick 		/* must force newline after if */
6298800Smckusick 		    last_u_d = true;
6308800Smckusick 		/* inform lexi that a following operator is unary */
6318800Smckusick 		    in_stmt = false;
6328800Smckusick 		/* don't use stmt continuation indentation */
6338800Smckusick 
6348800Smckusick 		    parse (hd_type);
6358800Smckusick 		/* let parser worry about if, or whatever */
6368800Smckusick 		}
6378800Smckusick 
6388800Smckusick 		search_brace = btype_2;
6398800Smckusick 	    /* this should insure that constructs such as main(){... and
6408800Smckusick 	       int[]{... have their braces put in the right place */
6418800Smckusick 		break;
6428800Smckusick 
6438800Smckusick 	    case unary_op:     /* this could be any unary operation */
6448800Smckusick 		if (want_blank)
6458800Smckusick 		    *e_code++ = ' ';
6468800Smckusick 
6478800Smckusick 		if (in_decl) { /* if this is a unary op in a *//*
6488800Smckusick 			          declaration, we should indent this token
6498800Smckusick 			          */
6508800Smckusick 		    for (i = 0; token[i]; ++i);
6518800Smckusick 		/* find length of token */
6528800Smckusick 		    while ((e_code - s_code) < (dec_ind - i))
6538800Smckusick 			*e_code++ = ' ';
6548800Smckusick 		/* pad it */
6558800Smckusick 		}
6568800Smckusick 
6578800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
6588800Smckusick 		    *e_code++ = *t_ptr;
6598800Smckusick 	    /* move the token to buffer */
6608800Smckusick 		want_blank = false;
6618800Smckusick 		break;
6628800Smckusick 
6638800Smckusick 	    case binary_op:    /* any binary operation */
6648800Smckusick 	do_binary:
6658800Smckusick 		if (want_blank)
6668800Smckusick 		    *e_code++ = ' ';
6678800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
6688800Smckusick 		    *e_code++ = *t_ptr;
6698800Smckusick 	    /* move the operator */
6708800Smckusick 		want_blank = true;
6718800Smckusick 		break;
6728800Smckusick 
6738800Smckusick 	    case postop:       /* got a trailing ++ or -- */
6748800Smckusick 		*e_code++ = token[0];
6758800Smckusick 		*e_code++ = token[1];
6768800Smckusick 		want_blank = true;
6778800Smckusick 		break;
6788800Smckusick 
6798800Smckusick 	    case question:     /* got a ? */
6808800Smckusick 		squest++;      /* this will be used when a later colon
6818800Smckusick 			          appears so we can distinguish the
6828800Smckusick 			          <c>?<n>:<n> construct */
6838800Smckusick 		if (want_blank)
6848800Smckusick 		    *e_code++ = ' ';
6858800Smckusick 		*e_code++ = '?';
6868800Smckusick 		want_blank = true;
6878800Smckusick 		break;
6888800Smckusick 
6898800Smckusick 	    case casestmt:     /* got word 'case' or 'default' */
6908800Smckusick 		scase = true;  /* so we can process the later colon
6918800Smckusick 			          properly */
6928800Smckusick 		if (want_blank)
6938800Smckusick 		    *e_code++ = ' ';
6948800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
6958800Smckusick 		    *e_code++ = *t_ptr;
6968800Smckusick 		want_blank = true;
6978800Smckusick 		break;
6988800Smckusick 
6998800Smckusick 	    case colon:        /* got a ':' */
7008800Smckusick 		if (squest > 0) {
7018800Smckusick 		/* it is part of the <c>?<n>: <n> construct */
7028800Smckusick 		    --squest;
7038800Smckusick 		    if (want_blank)
7048800Smckusick 			*e_code++ = ' ';
7058800Smckusick 		    *e_code++ = ':';
7068800Smckusick 		    want_blank = true;
7078800Smckusick 		    break;
7088800Smckusick 		}
7098800Smckusick 
7108800Smckusick 		in_stmt = false;
7118800Smckusick 	    /* seeing a label does not imply we are in a stmt */
7128800Smckusick 		for (t_ptr = s_code; *t_ptr; ++t_ptr)
7138800Smckusick 		    *e_lab++ = *t_ptr;
7148800Smckusick 	    /* turn everything so far into a label */
7158800Smckusick 		e_code = s_code;
7168800Smckusick 		*e_lab++ = ':';
7178800Smckusick 		*e_lab++ = ' ';
7188800Smckusick 		*e_lab = '\0';
7198800Smckusick 
7208800Smckusick 		force_nl = pcase = scase;
7218800Smckusick 	    /* pcase will be used by dump_line to decide how to indent the
7228800Smckusick 	       label. force_nl will force a case n: to be on a line by
7238800Smckusick 	       itself */
7248800Smckusick 		scase = false;
7258800Smckusick 		want_blank = false;
7268800Smckusick 		break;
7278800Smckusick 
7288800Smckusick 	    case semicolon:    /* got a ';' */
7298800Smckusick 		in_or_st = false;
7308800Smckusick 	    /* we are not in an initialization or structure declaration */
7318800Smckusick 		scase = false; /* these will only need resetting in a
7328800Smckusick 			          error */
7338800Smckusick 		squest = 0;
7348800Smckusick 
7358800Smckusick 		if (in_decl && s_code == e_code)
7368800Smckusick 			       /* align this in a declaration */
7378800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
7388800Smckusick 			*e_code++ = ' ';
7398800Smckusick 
7408800Smckusick 		in_decl = (dec_nest > 0);
7418800Smckusick 	    /* if we were in a first level structure declaration, we
7428800Smckusick 	       aren't any more */
7438800Smckusick 
7448800Smckusick 		if ((!sp_sw || hd_type != forstmt) && p_l_follow > 0) {
7458800Smckusick 		/* This should be true iff there were unbalanced parens in
7468800Smckusick 		   the stmt.  It is a bit complicated, because the
7478800Smckusick 		   semicolon might be in a for stmt */
7488800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
7498800Smckusick 		    p_l_follow = 0;
7508800Smckusick 		    if (sp_sw) {
7518800Smckusick 		    /* this is a check for a if, while, etc. with
7528800Smckusick 		       unbalanced parens */
7538800Smckusick 			sp_sw = false;
7548800Smckusick 			parse (hd_type);
7558800Smckusick 		    /* don't lose the if, or whatever */
7568800Smckusick 		    }
7578800Smckusick 		}
7588800Smckusick 
7598800Smckusick 		*e_code++ = ';';
7608800Smckusick 		want_blank = true;
7618800Smckusick 		in_stmt = (p_l_follow > 0);
7628800Smckusick 	    /* we are no longer in the middle of a stmt */
7638800Smckusick 
7648800Smckusick 		if (!sp_sw) {  /* if not if for (;;) */
7658800Smckusick 		    parse (semicolon);
7668800Smckusick 		/* let parser know about end of stmt */
7678800Smckusick 		    force_nl = true;
7688800Smckusick 		/* force newline after a end of stmt */
7698800Smckusick 		}
7708800Smckusick 
7718800Smckusick 		break;
7728800Smckusick 
7738800Smckusick 	    case lbrace:       /* got a { */
7748800Smckusick 		in_stmt = false;
7758800Smckusick 	    /* don't indent the { */
7768800Smckusick 		force_nl = true;
7778800Smckusick 	    /* force other stuff on same line as { onto new line */
7788800Smckusick 
7798800Smckusick 		if (s_code != e_code && !btype_2) {
7808800Smckusick 		/* bracket is not alone on line */
7818800Smckusick 		    if (verbose)
7828800Smckusick 			printf ("%d: Line broken\n", line_no);
7838800Smckusick 		    dump_line ();
7848800Smckusick 		    want_blank = false;
7858800Smckusick 		}
7868800Smckusick 
7878800Smckusick 		if (p_l_follow > 0) {
7888800Smckusick 		/* check for preceeding unbalanced parens */
7898800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
7908800Smckusick 		    p_l_follow = 0;
7918800Smckusick 		    if (sp_sw) {
7928800Smckusick 		    /* check for unclosed if, for, etc. */
7938800Smckusick 			sp_sw = false;
7948800Smckusick 			parse (hd_type);
7958800Smckusick 			ind_level = i_l_follow;
7968800Smckusick 		    }
7978800Smckusick 		}
7988800Smckusick 
7998800Smckusick 		if (s_code == e_code)
8008800Smckusick 		    ind_stmt = false;
8018800Smckusick 	    /* don't put extra indentation on line with '{' */
8028800Smckusick 		if (in_decl && in_or_st) {
8038800Smckusick 		/* this is either a structure declaration or an init */
8048800Smckusick 		    di_stack[dec_nest++] = dec_ind;
8058800Smckusick 		    dec_ind = 0;
8068800Smckusick 		}
8078800Smckusick 		else
8088800Smckusick 		    decl_on_line = false;
8098800Smckusick 	    /* we can't be in the middle of a declaration, so don't do
8108800Smckusick 	       special indentation of comments */
8118800Smckusick 
8128800Smckusick 		parse (lbrace);/* let parser know about this */
8138800Smckusick 		if (want_blank)/* put a blank before { if { is not at
8148800Smckusick 			          start of line */
8158800Smckusick 		    *e_code++ = ' ';
8168800Smckusick 		want_blank = false;
8178800Smckusick 		*e_code++ = '{';
8188800Smckusick 		break;
8198800Smckusick 
8208800Smckusick 	    case rbrace:       /* got a } */
8218800Smckusick 		if (p_l_follow) {
8228800Smckusick 		/* check for unclosed if, for, else. */
8238800Smckusick 		    printf ("%d: Unbalanced parens\n", line_no);
8248800Smckusick 		    p_l_follow = 0;
8258800Smckusick 		    sp_sw = false;
8268800Smckusick 		}
8278800Smckusick 
8288800Smckusick 		if (s_code != e_code) {
8298800Smckusick 		/* } must be first on line */
8308800Smckusick 		    if (verbose)
8318800Smckusick 			printf ("%d: Line broken\n", line_no);
8328800Smckusick 		    dump_line ();
8338800Smckusick 		}
8348800Smckusick 
8358800Smckusick 		*e_code++ = '}';
8368800Smckusick 		want_blank = true;
8378800Smckusick 		in_stmt = ind_stmt = false;
8388800Smckusick 
8398800Smckusick 		if (dec_nest > 0) {
8408800Smckusick 		/* we are in multi-level structure declaration */
8418800Smckusick 		    dec_ind = di_stack[--dec_nest];
8428800Smckusick 		    in_decl = true;
8438800Smckusick 		}
8448800Smckusick 
8458800Smckusick 		parse (rbrace);/*   let parser know about this */
8468800Smckusick 		break;
8478800Smckusick 
8488800Smckusick 	    case swstmt:       /* got keyword "switch" */
8498800Smckusick 		sp_sw = true;
8508800Smckusick 		hd_type = swstmt;
8518800Smckusick 	    /* keep this for when we have seen the expression */
8528800Smckusick 		goto copy_id;  /* go move the token into buffer */
8538800Smckusick 
8548800Smckusick 	    case sp_paren:     /* token is if, while, for */
8558800Smckusick 		sp_sw = true;  /* the interesting stuff is done after the
8568800Smckusick 			          expression is scanned */
8578800Smckusick 		hd_type = (*token == 'i' ? ifstmt :
8588800Smckusick 			(*token == 'w' ? whilestmt : forstmt));
8598800Smckusick 	    /* remember the type of header for later use by parser */
8608800Smckusick 		goto copy_id;  /* copy the token into line */
8618800Smckusick 
8628800Smckusick 	    case sp_nparen:    /* got else, do */
8638800Smckusick 		in_stmt = false;
8648800Smckusick 		if (e_code != s_code) {
8658800Smckusick 		/* make sure this starts a line */
8668800Smckusick 		    if (verbose)
8678800Smckusick 			printf ("%d: Line broken\n", line_no);
8688800Smckusick 		    dump_line ();
8698800Smckusick 		    want_blank = false;
8708800Smckusick 		}
8718800Smckusick 
8728800Smckusick 		force_nl = true;
8738800Smckusick 	    /* also, following stuff must go onto new line */
8748800Smckusick 		parse (*token == 'e' ? elselit : dolit);
8758800Smckusick 	    /* pass token on to parser */
8768800Smckusick 		goto copy_id;  /* move the token into line */
8778800Smckusick 
8788800Smckusick 	    case decl: 	       /* we have a declaration type (int,
8798800Smckusick 			          register, etc.) */
8808800Smckusick 		parse (decl);  /* let parser worry about indentation */
8818800Smckusick 		in_or_st = true;
8828800Smckusick 	    /* this might be a structure or initialization declaration */
8838800Smckusick 		in_decl = decl_on_line = true;
8848800Smckusick 		for (i = 0; token[i++];);
8858800Smckusick 	    /* get length of token */
8868800Smckusick 
8878800Smckusick 		if (i <= 3)
8888800Smckusick 		    i = 4;
8898800Smckusick 
8908800Smckusick 		dec_ind = ((e_code - s_code + i) / ind_size + 1) * ind_size;
8918800Smckusick 	    /* this will tell us how far to indent subsequent identifiers
8928800Smckusick 	    */
8938800Smckusick 		goto copy_id;
8948800Smckusick 
8958800Smckusick 	    case ident:        /* got an identifier or constant */
8968800Smckusick 		if (in_decl) { /* if we are in a declaration, we must
8978800Smckusick 			          indent identifier */
8988800Smckusick 		    if (want_blank)
8998800Smckusick 			*e_code++ = ' ';
9008800Smckusick 		    want_blank = false;
9018800Smckusick 
9028800Smckusick 		    while ((e_code - s_code) < dec_ind)
9038800Smckusick 			*e_code++ = ' ';
9048800Smckusick 		}
9058800Smckusick 		else
9068800Smckusick 		    if (sp_sw && p_l_follow == 0) {
9078800Smckusick 		    /* check for if expr w/o parens *//* this will make
9088800Smckusick 		       JRM's obsurd "for ever" statements work */
9098800Smckusick 			sp_sw = false;
9108800Smckusick 			force_nl = true;
9118800Smckusick 			last_u_d = true;
9128800Smckusick 			in_stmt = false;
9138800Smckusick 			parse (hd_type);
9148800Smckusick 		    }
9158800Smckusick 
9168800Smckusick 	copy_id:
9178800Smckusick 		if (want_blank)
9188800Smckusick 		    *e_code++ = ' ';
9198800Smckusick 		for (t_ptr = token; *t_ptr; ++t_ptr)
9208800Smckusick 		    *e_code++ = *t_ptr;
9218800Smckusick 		want_blank = true;
9228800Smckusick 		break;
9238800Smckusick 
9248800Smckusick 	    case period:       /* treat a period kind of like a binary
9258800Smckusick 			          operation */
9268800Smckusick 		*e_code++ = '.';
9278800Smckusick 	    /* move the period into line */
9288800Smckusick 		want_blank = false;
9298800Smckusick 	    /* don't put a blank after a period */
9308800Smckusick 		break;
9318800Smckusick 
9328800Smckusick 	    case comma:
9338800Smckusick 		want_blank = (s_code != e_code);
9348800Smckusick 	    /* only put blank after comma if comma does not start the line
9358800Smckusick 	       */
9368800Smckusick 		if (in_decl)   /* align these in a declaration */
9378800Smckusick 		    while ((e_code - s_code) < (dec_ind - 1))
9388800Smckusick 			*e_code++ = ' ';
9398800Smckusick 
9408800Smckusick 		*e_code++ = ',';
9418800Smckusick 
9428800Smckusick 		if (break_comma && p_l_follow == 0 && !leave_comma)
9438800Smckusick 		    force_nl = true;
9448800Smckusick 
9458800Smckusick 		break;
9468800Smckusick 
9478800Smckusick 	    case preesc:       /* got the character '#' */
9488800Smckusick 		if (
9498800Smckusick 			(s_com != e_com) ||
9508800Smckusick 			(s_lab != e_lab) ||
9518800Smckusick 			(s_code != e_code)) {
9528800Smckusick 		/* true iff the '#' was not at start of the line */
9538800Smckusick 		    printf ("%d: What is this # doing here?\n", line_no);
9548800Smckusick 		    goto do_binary;
9558800Smckusick 		/* treat it as a binary operator */
9568800Smckusick 		}
9578800Smckusick 
9588800Smckusick 		*e_lab++ = '#';/* move whole line to 'label' buffer */
9598800Smckusick 		while (*buf_ptr != '\n') {
9608800Smckusick 		    *e_lab = *buf_ptr++;
9618800Smckusick 		    if (buf_ptr >= buf_end)
9628800Smckusick 			fill_buffer ();
9638800Smckusick 
9648800Smckusick 		    if (*e_lab++ == '/' && *buf_ptr == '*') {
9658800Smckusick 		    /* check for comment on preprocessor line */
9668800Smckusick 			e_lab - = 2;
9678800Smckusick 		    /* skip back over slash */
9688800Smckusick 			while (*e_lab == '\t' || *e_lab == ' ')
9698800Smckusick 			    --e_lab;
9708800Smckusick 		    /* strip off trailing blanks and tabs */
9718800Smckusick 			*(++e_lab) = '\0';
9728800Smckusick 		    /* null terminate the line */
9738800Smckusick 			if (++buf_ptr >= buf_end)
9748800Smckusick 			       /* space past start of comment */
9758800Smckusick 			    fill_buffer ();
9768800Smckusick 			col_1 = false;
9778800Smckusick 		    /* don't let pr_comment think that this comment starts
9788800Smckusick 		       in column 1 */
9798800Smckusick 			decl_on_line = true;
9808800Smckusick 		    /* treat this as a declaration for comment placement
9818800Smckusick 		       purposes */
9828800Smckusick 			goto proc_comment;
9838800Smckusick 		    /* go process the comment */
9848800Smckusick 		    }
9858800Smckusick 		}
9868800Smckusick 
9878800Smckusick 		*e_lab = '\0'; /* null terminate line */
9888800Smckusick 		pcase = false;
9898800Smckusick 		break;	       /* subsequent processing of the newline
9908800Smckusick 			          character will cause the line to be
9918800Smckusick 			          printed */
9928800Smckusick 
9938800Smckusick 	    case comment:      /* we have gotten a /*  this is a biggie */
9948800Smckusick 	proc_comment:
9958800Smckusick 		pr_comment ();
9968800Smckusick 		break;
9978800Smckusick 	}		       /* end of big switch stmt */
9988800Smckusick 
9998800Smckusick 	*e_code = '\0';	       /* make sure code section is null
10008800Smckusick 			          terminated */
10018800Smckusick 
10028800Smckusick     }			       /* end of main while (1) loop */
10038800Smckusick };
10048800Smckusick 
10058800Smckusick /*
10068800Smckusick  * copy input file to backup file
10078800Smckusick  * if in_name is /blah/blah/blah/file, then backup file
10088800Smckusick  * will be ".Bfile"
10098800Smckusick  * then make the backup file the input and original
10108800Smckusick  * input file the output
10118800Smckusick  */
10128800Smckusick bakcopy () {
10138800Smckusick     int     n,
10148800Smckusick             bakchn;
10158800Smckusick     char    buff[512];
10168800Smckusick     register char  *p;
10178800Smckusick 
10188800Smckusick  /* construct file name .Bfile */
10198800Smckusick     for (p = in_name; *p; p++);/* skip to end of string */
10208800Smckusick     while (p > in_name && *p != '/')/* find last '/' */
10218800Smckusick 	p--;
10228800Smckusick     if (*p == '/')
10238800Smckusick 	p++;
10248800Smckusick     sprintf (bakfile, ".B%s", p);
10258800Smckusick 
10268800Smckusick  /* copy in_name to backup file */
10278800Smckusick     bakchn = creat (bakfile, 0600);
10288800Smckusick     if (bakchn < 0) {
10298800Smckusick 	printf ("can't create backup file \"%s\"\n", bakfile);
10308800Smckusick 	exit ();
10318800Smckusick     }
10328800Smckusick     while (n = read (input, buff, 512))
10338800Smckusick 	write (bakchn, buff, n);
10348800Smckusick     close (bakchn);
10358800Smckusick     close (input);
10368800Smckusick 
10378800Smckusick  /* re-open backup file as the input file */
10388800Smckusick     input = open (bakfile, 0);
10398800Smckusick     if (input < 0) {
10408800Smckusick 	printf ("can't re-open backup file\n");
10418800Smckusick 	exit ();
10428800Smckusick     }
10438800Smckusick 
10448800Smckusick  /* now the original input file will be the output */
10458800Smckusick     output = creat (in_name, 0644);
10468800Smckusick     if (output < 0) {
10478800Smckusick 	printf ("can't create %s\n", in_name);
10488800Smckusick 	unlink (bakfile);
10498800Smckusick 	exit ();
10508800Smckusick     }
10518800Smckusick }
10528800Smckusick 
10538800Smckusick 
10548800Smckusick set_option (arg)
10558800Smckusick char   *arg;
10568800Smckusick {
10578800Smckusick     register    j;
10588800Smckusick     for (j = 0; options[j].str != 0; ++j) {
10598800Smckusick 			       /* look thru list of possible options */
10608800Smckusick 	if (eqin (options[j].str, arg)) {
10618800Smckusick 	    set_var (j, arg);
10628800Smckusick 	    break;	       /* get out of for loop */
10638800Smckusick 	}
10648800Smckusick     }
10658800Smckusick 
10668800Smckusick     if (options[j].str == 0) { /* illegal arg given */
10678800Smckusick 	printf ("Unknown parameter: %s\n", arg);
10688800Smckusick 	exit ();
10698800Smckusick     }
10708800Smckusick }
10718800Smckusick 
10728800Smckusick 
10738800Smckusick set_var (j, arg)
10748800Smckusick char   *arg;
10758800Smckusick {
10768800Smckusick     switch (options[j].code) {
10778800Smckusick 	case 1: 	       /* have -lnnn */
10788800Smckusick 	    max_col = atoi (&arg[2]);
10798800Smckusick 	    break;
10808800Smckusick 	case 2: 	       /* have -cnnn */
10818800Smckusick 	    com_ind = atoi (&arg[2]);
10828800Smckusick 	    break;
10838800Smckusick 	case 3: 	       /* have -innn */
10848800Smckusick 	    ind_size = atoi (&arg[2]);
10858800Smckusick 	    break;
10868800Smckusick 	case 4: 	       /* have -cdnnn */
10878800Smckusick 	    decl_com_ind = atoi (&arg[3]);
10888800Smckusick 	    break;
10898800Smckusick 	case 5: 	       /* have -v */
10908800Smckusick 	    verbose = true;
10918800Smckusick 	    break;
10928800Smckusick 	case 6: 	       /* have -nv */
10938800Smckusick 	    verbose = false;
10948800Smckusick 	    break;
10958800Smckusick 	case 7: 	       /* have -dj */
10968800Smckusick 	    ljust_decl = true;
10978800Smckusick 	    break;
10988800Smckusick 	case 8: 	       /* have -ndj */
10998800Smckusick 	    ljust_decl = false;
11008800Smckusick 	    break;
11018800Smckusick 	case 9: 	       /* -nbc */
11028800Smckusick 	    leave_comma = true;
11038800Smckusick 	    break;
11048800Smckusick 	case 10: 	       /* -bc */
11058800Smckusick 	    leave_comma = false;
11068800Smckusick 	    break;
11078800Smckusick 	case 13: 	       /* -dnnn */
11088800Smckusick 	    unindent_displace = atoi (&arg[2]);
11098800Smckusick 	    break;
11108800Smckusick 	case 14: 	       /* -br */
11118800Smckusick 	    btype_2 = true;
11128800Smckusick 	    break;
11138800Smckusick 	case 15: 	       /* -bl */
11148800Smckusick 	    btype_2 = false;
11158800Smckusick 	    break;
11168800Smckusick 	case 16:
11178800Smckusick 	    if(input<0) input = 0;
11188800Smckusick 	    if(output<0) output = 1;
11198800Smckusick 	    break;
11208800Smckusick     }
11218800Smckusick }
11228800Smckusick 
11238800Smckusick 
11248800Smckusick /*
11258800Smckusick  * GETPRO - get profile file
11268800Smckusick  * profile file is max 127 characters
11278800Smckusick  */
11288800Smckusick getpro (name, buf)
11298800Smckusick char   *name,		       /* profile file name, as in '.indent.pro'
11308800Smckusick 			       */
11318800Smckusick        *buf;		       /* will receive contents of .pro file */
11328800Smckusick {
11338800Smckusick     register    chn,
11348800Smckusick                 n;
11358800Smckusick     char    file[32];
11368800Smckusick 
11378800Smckusick     file[0] = 0;
11388800Smckusick     strcat (file, getenv ("HOME"));
11398800Smckusick     strcat (file, "/");
11408800Smckusick     strcat (file, name);
11418800Smckusick     chn = open (file, 0);
11428800Smckusick     if (chn < 0)
11438800Smckusick 	return (-1);
11448800Smckusick     n = read (chn, buf, 127);
11458800Smckusick     if (n < 0)
11468800Smckusick 	return (-1);
11478800Smckusick     buf[n--] = 0;	       /* null terminate line */
11488800Smckusick     if (buf[n] == '\n')
11498800Smckusick 	buf[n] = 0;
11508800Smckusick     close (chn);
11518800Smckusick     return (0);
11528800Smckusick }
11538800Smckusick 
11548800Smckusick 
11558800Smckusick /*
11568800Smckusick  * strip off arguments in a string:
11578800Smckusick  * p is address of a character pointer
11588800Smckusick  * nextchr returns pointer to front of first arg
11598800Smckusick  * arg is null terminated.
11608800Smckusick  * p is reset to after arg for subsequent calls
11618800Smckusick  */
11628800Smckusick char   *nxtarg (p)
11638800Smckusick char  **p;
11648800Smckusick {
11658800Smckusick     register char  *f,
11668800Smckusick                    *b;
11678800Smckusick     f = b = *p;
11688800Smckusick     while (*f && (*f == ' ' || *f == '\t'))
11698800Smckusick 	f++;
11708800Smckusick     while (*b && (*b != ' ' && *b != '\t'))
11718800Smckusick 	b++;
11728800Smckusick     if (*b != 0)
11738800Smckusick 	*b++ = 0;
11748800Smckusick     *p = b;
11758800Smckusick     return (f);
11768800Smckusick }
11778800Smckusick 
11788800Smckusick 
11798800Smckusick set_profile () {
11808800Smckusick     char    line[128],
11818800Smckusick            *b;
11828800Smckusick     register char  *f;
11838800Smckusick     extern char *nxtarg ();
11848800Smckusick 
11858800Smckusick     if (getpro (".indent.pro", line) < 0)
11868800Smckusick 	return;
11878800Smckusick     b = line;
11888800Smckusick     if(verbose) printf ("profile: %s\n", b);
11898800Smckusick     while (*(f = nxtarg (&b)))
11908800Smckusick 	set_option (f);
11918800Smckusick }
1192