Home | History | Annotate | Line # | Download | only in indent
indent.c revision 1.17
      1  1.17     lukem /*	$NetBSD: indent.c,v 1.17 2008/07/21 14:19:23 lukem Exp $	*/
      2   1.4       tls 
      3   1.1       cgd /*
      4   1.5       mrg  * Copyright (c) 1980, 1993
      5   1.5       mrg  *	The Regents of the University of California.  All rights reserved.
      6  1.15       agc  *
      7  1.15       agc  * Redistribution and use in source and binary forms, with or without
      8  1.15       agc  * modification, are permitted provided that the following conditions
      9  1.15       agc  * are met:
     10  1.15       agc  * 1. Redistributions of source code must retain the above copyright
     11  1.15       agc  *    notice, this list of conditions and the following disclaimer.
     12  1.15       agc  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.15       agc  *    notice, this list of conditions and the following disclaimer in the
     14  1.15       agc  *    documentation and/or other materials provided with the distribution.
     15  1.15       agc  * 3. Neither the name of the University nor the names of its contributors
     16  1.15       agc  *    may be used to endorse or promote products derived from this software
     17  1.15       agc  *    without specific prior written permission.
     18  1.15       agc  *
     19  1.15       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  1.15       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  1.15       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  1.15       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  1.15       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  1.15       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  1.15       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  1.15       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  1.15       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  1.15       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  1.15       agc  * SUCH DAMAGE.
     30  1.15       agc  */
     31  1.15       agc 
     32  1.15       agc /*
     33   1.5       mrg  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
     34   1.1       cgd  * Copyright (c) 1985 Sun Microsystems, Inc.
     35   1.1       cgd  * All rights reserved.
     36   1.1       cgd  *
     37   1.1       cgd  * Redistribution and use in source and binary forms, with or without
     38   1.1       cgd  * modification, are permitted provided that the following conditions
     39   1.1       cgd  * are met:
     40   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     41   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     42   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     43   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     44   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     45   1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     46   1.1       cgd  *    must display the following acknowledgement:
     47   1.1       cgd  *	This product includes software developed by the University of
     48   1.1       cgd  *	California, Berkeley and its contributors.
     49   1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     50   1.1       cgd  *    may be used to endorse or promote products derived from this software
     51   1.1       cgd  *    without specific prior written permission.
     52   1.1       cgd  *
     53   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     54   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     55   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     56   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     57   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     58   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     59   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63   1.1       cgd  * SUCH DAMAGE.
     64   1.1       cgd  */
     65   1.1       cgd 
     66   1.6     lukem #include <sys/cdefs.h>
     67   1.1       cgd #ifndef lint
     68  1.17     lukem __COPYRIGHT("@(#) Copyright (c) 1985 Sun Microsystems, Inc.\
     69  1.17     lukem   Copyright (c) 1976 Board of Trustees of the University of Illinois.\
     70  1.17     lukem   Copyright (c) 1980, 1993\
     71  1.17     lukem  The Regents of the University of California.  All rights reserved.");
     72   1.6     lukem #endif				/* not lint */
     73   1.1       cgd 
     74   1.1       cgd #ifndef lint
     75   1.5       mrg #if 0
     76   1.5       mrg static char sccsid[] = "@(#)indent.c	5.17 (Berkeley) 6/7/93";
     77   1.5       mrg #else
     78  1.17     lukem __RCSID("$NetBSD: indent.c,v 1.17 2008/07/21 14:19:23 lukem Exp $");
     79   1.5       mrg #endif
     80   1.6     lukem #endif				/* not lint */
     81   1.1       cgd 
     82   1.1       cgd #include <sys/param.h>
     83   1.6     lukem #include <ctype.h>
     84   1.6     lukem #include <err.h>
     85   1.6     lukem #include <errno.h>
     86   1.1       cgd #include <fcntl.h>
     87   1.1       cgd #include <stdio.h>
     88   1.1       cgd #include <stdlib.h>
     89   1.1       cgd #include <string.h>
     90   1.6     lukem #include <unistd.h>
     91  1.14  christos #include <locale.h>
     92   1.9  wsanchez #define EXTERN
     93   1.1       cgd #include "indent_globs.h"
     94   1.9  wsanchez #undef  EXTERN
     95   1.1       cgd #include "indent_codes.h"
     96   1.1       cgd 
     97   1.6     lukem char   *in_name = "Standard Input";	/* will always point to name of input
     98   1.6     lukem 					 * file */
     99   1.6     lukem char   *out_name = "Standard Output";	/* will always point to name of output
    100   1.1       cgd 					 * file */
    101   1.6     lukem char    bakfile[MAXPATHLEN] = "";
    102   1.1       cgd 
    103  1.13       wiz int main(int, char **);
    104   1.6     lukem 
    105   1.6     lukem int
    106  1.13       wiz main(int argc, char **argv)
    107   1.1       cgd {
    108   1.1       cgd 
    109   1.6     lukem 	extern int found_err;	/* flag set in diag() on error */
    110   1.6     lukem 	int     dec_ind;	/* current indentation for declarations */
    111   1.6     lukem 	int     di_stack[20];	/* a stack of structure indentation levels */
    112   1.6     lukem 	int     flushed_nl;	/* used when buffering up comments to remember
    113   1.1       cgd 				 * that a newline was passed over */
    114   1.6     lukem 	int     force_nl;	/* when true, code must be broken */
    115   1.6     lukem 	int     hd_type;	/* used to store type of stmt for if (...),
    116   1.1       cgd 				 * for (...), etc */
    117   1.6     lukem 	int     i;		/* local loop counter */
    118   1.6     lukem 	int     scase;		/* set to true when we see a case, so we will
    119   1.1       cgd 				 * know what to do with the following colon */
    120   1.6     lukem 	int     sp_sw;		/* when true, we are in the expressin of
    121   1.1       cgd 				 * if(...), while(...), etc. */
    122   1.6     lukem 	int     squest;		/* when this is positive, we have seen a ?
    123   1.1       cgd 				 * without the matching : in a <c>?<s>:<s>
    124   1.1       cgd 				 * construct */
    125   1.6     lukem 	char   *t_ptr;		/* used for copying tokens */
    126   1.6     lukem 	int     type_code;	/* the type of token, returned by lexi */
    127   1.1       cgd 
    128   1.6     lukem 	int     last_else = 0;	/* true iff last keyword was an else */
    129   1.1       cgd 
    130   1.1       cgd 
    131   1.6     lukem 	/*-----------------------------------------------*\
    132   1.6     lukem         |		      INITIALIZATION		      |
    133   1.6     lukem         \*-----------------------------------------------*/
    134   1.1       cgd 
    135  1.14  christos 	if (!setlocale(LC_ALL, ""))
    136  1.14  christos 		fprintf(stderr, "indent: can't set locale.\n");
    137   1.1       cgd 
    138   1.6     lukem 	hd_type = 0;
    139   1.6     lukem 	ps.p_stack[0] = stmt;	/* this is the parser's stack */
    140   1.6     lukem 	ps.last_nl = true;	/* this is true if the last thing scanned was
    141   1.1       cgd 				 * a newline */
    142   1.6     lukem 	ps.last_token = semicolon;
    143   1.6     lukem 	combuf = (char *) malloc(bufsize);
    144   1.6     lukem 	labbuf = (char *) malloc(bufsize);
    145   1.6     lukem 	codebuf = (char *) malloc(bufsize);
    146   1.6     lukem 	tokenbuf = (char *) malloc(bufsize);
    147   1.6     lukem 	l_com = combuf + bufsize - 5;
    148   1.6     lukem 	l_lab = labbuf + bufsize - 5;
    149   1.6     lukem 	l_code = codebuf + bufsize - 5;
    150   1.6     lukem 	l_token = tokenbuf + bufsize - 5;
    151   1.6     lukem 	combuf[0] = codebuf[0] = labbuf[0] = ' ';	/* set up code, label,
    152   1.6     lukem 							 * and comment buffers */
    153   1.6     lukem 	combuf[1] = codebuf[1] = labbuf[1] = '\0';
    154   1.6     lukem 	ps.else_if = 1;		/* Default else-if special processing to on */
    155   1.6     lukem 	s_lab = e_lab = labbuf + 1;
    156   1.6     lukem 	s_code = e_code = codebuf + 1;
    157   1.6     lukem 	s_com = e_com = combuf + 1;
    158   1.6     lukem 	s_token = e_token = tokenbuf + 1;
    159   1.6     lukem 
    160   1.6     lukem 	in_buffer = (char *) malloc(10);
    161   1.6     lukem 	in_buffer_limit = in_buffer + 8;
    162   1.6     lukem 	buf_ptr = buf_end = in_buffer;
    163   1.6     lukem 	line_no = 1;
    164   1.6     lukem 	had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
    165   1.6     lukem 	sp_sw = force_nl = false;
    166   1.6     lukem 	ps.in_or_st = false;
    167   1.6     lukem 	ps.bl_line = true;
    168   1.6     lukem 	dec_ind = 0;
    169   1.6     lukem 	di_stack[ps.dec_nest = 0] = 0;
    170   1.6     lukem 	ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
    171   1.6     lukem 
    172   1.6     lukem 
    173   1.6     lukem 	scase = ps.pcase = false;
    174   1.6     lukem 	squest = 0;
    175   1.6     lukem 	sc_end = 0;
    176   1.6     lukem 	bp_save = 0;
    177   1.6     lukem 	be_save = 0;
    178   1.6     lukem 
    179   1.6     lukem 	output = 0;
    180   1.1       cgd 
    181   1.1       cgd 
    182   1.1       cgd 
    183   1.6     lukem 	/*--------------------------------------------------*\
    184   1.6     lukem         |   		COMMAND LINE SCAN		 |
    185   1.6     lukem         \*--------------------------------------------------*/
    186   1.1       cgd 
    187   1.1       cgd #ifdef undef
    188   1.6     lukem 	max_col = 78;		/* -l78 */
    189   1.6     lukem 	lineup_to_parens = 1;	/* -lp */
    190   1.6     lukem 	ps.ljust_decl = 0;	/* -ndj */
    191   1.6     lukem 	ps.com_ind = 33;	/* -c33 */
    192   1.6     lukem 	star_comment_cont = 1;	/* -sc */
    193   1.6     lukem 	ps.ind_size = 8;	/* -i8 */
    194   1.6     lukem 	verbose = 0;
    195   1.6     lukem 	ps.decl_indent = 16;	/* -di16 */
    196   1.6     lukem 	ps.indent_parameters = 1;	/* -ip */
    197   1.6     lukem 	ps.decl_com_ind = 0;	/* if this is not set to some positive value
    198   1.1       cgd 				 * by an arg, we will set this equal to
    199   1.1       cgd 				 * ps.com_ind */
    200   1.6     lukem 	btype_2 = 1;		/* -br */
    201   1.6     lukem 	cuddle_else = 1;	/* -ce */
    202   1.6     lukem 	ps.unindent_displace = 0;	/* -d0 */
    203   1.6     lukem 	ps.case_indent = 0;	/* -cli0 */
    204   1.6     lukem 	format_col1_comments = 1;	/* -fc1 */
    205   1.6     lukem 	procnames_start_line = 1;	/* -psl */
    206   1.6     lukem 	proc_calls_space = 0;	/* -npcs */
    207   1.6     lukem 	comment_delimiter_on_blankline = 1;	/* -cdb */
    208   1.6     lukem 	ps.leave_comma = 1;	/* -nbc */
    209   1.1       cgd #endif
    210   1.1       cgd 
    211   1.6     lukem 	for (i = 1; i < argc; ++i)
    212   1.6     lukem 		if (strcmp(argv[i], "-npro") == 0)
    213   1.6     lukem 			break;
    214   1.6     lukem 	set_defaults();
    215   1.6     lukem 	if (i >= argc)
    216   1.6     lukem 		set_profile();
    217   1.1       cgd 
    218   1.6     lukem 	for (i = 1; i < argc; ++i) {
    219   1.1       cgd 
    220   1.6     lukem 		/*
    221   1.6     lukem 		 * look thru args (if any) for changes to defaults
    222   1.6     lukem 		 */
    223   1.6     lukem 		if (argv[i][0] != '-') {	/* no flag on parameter */
    224   1.6     lukem 			if (input == 0) {	/* we must have the input file */
    225   1.6     lukem 				in_name = argv[i];	/* remember name of
    226   1.6     lukem 							 * input file */
    227   1.6     lukem 				input = fopen(in_name, "r");
    228   1.6     lukem 				if (input == 0)	/* check for open error */
    229   1.6     lukem 					err(1, "%s", in_name);
    230   1.6     lukem 				continue;
    231   1.6     lukem 			} else
    232   1.6     lukem 				if (output == 0) {	/* we have the output
    233   1.6     lukem 							 * file */
    234   1.6     lukem 					out_name = argv[i];	/* remember name of
    235   1.6     lukem 								 * output file */
    236   1.6     lukem 					if (strcmp(in_name, out_name) == 0) {	/* attempt to overwrite
    237   1.6     lukem 										 * the file */
    238   1.6     lukem 						fprintf(stderr, "indent: input and output files must be different\n");
    239   1.6     lukem 						exit(1);
    240   1.6     lukem 					}
    241   1.6     lukem 					output = fopen(out_name, "w");
    242   1.6     lukem 					if (output == 0)	/* check for create
    243   1.6     lukem 								 * error */
    244   1.6     lukem 						err(1, "%s", out_name);
    245   1.6     lukem 					continue;
    246   1.6     lukem 				}
    247   1.6     lukem 			fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]);
    248   1.6     lukem 			exit(1);
    249   1.6     lukem 		} else
    250   1.6     lukem 			set_option(argv[i]);
    251   1.6     lukem 	}			/* end of for */
    252   1.6     lukem 	if (input == 0) {
    253   1.8    mellon 		input = stdin;
    254   1.6     lukem 	}
    255   1.7      ross 	if (output == 0) {
    256   1.8    mellon 		if (troff || input == stdin)
    257   1.6     lukem 			output = stdout;
    258   1.6     lukem 		else {
    259   1.6     lukem 			out_name = in_name;
    260   1.6     lukem 			bakcopy();
    261   1.1       cgd 		}
    262   1.7      ross 	}
    263   1.6     lukem 	if (ps.com_ind <= 1)
    264   1.6     lukem 		ps.com_ind = 2;	/* dont put normal comments before column 2 */
    265   1.6     lukem 	if (troff) {
    266   1.6     lukem 		if (bodyf.font[0] == 0)
    267   1.6     lukem 			parsefont(&bodyf, "R");
    268   1.6     lukem 		if (scomf.font[0] == 0)
    269   1.6     lukem 			parsefont(&scomf, "I");
    270   1.6     lukem 		if (blkcomf.font[0] == 0)
    271   1.6     lukem 			blkcomf = scomf, blkcomf.size += 2;
    272   1.6     lukem 		if (boxcomf.font[0] == 0)
    273   1.6     lukem 			boxcomf = blkcomf;
    274   1.6     lukem 		if (stringf.font[0] == 0)
    275   1.6     lukem 			parsefont(&stringf, "L");
    276   1.6     lukem 		if (keywordf.font[0] == 0)
    277   1.6     lukem 			parsefont(&keywordf, "B");
    278   1.6     lukem 		writefdef(&bodyf, 'B');
    279   1.6     lukem 		writefdef(&scomf, 'C');
    280   1.6     lukem 		writefdef(&blkcomf, 'L');
    281   1.6     lukem 		writefdef(&boxcomf, 'X');
    282   1.6     lukem 		writefdef(&stringf, 'S');
    283   1.6     lukem 		writefdef(&keywordf, 'K');
    284   1.1       cgd 	}
    285   1.6     lukem 	if (block_comment_max_col <= 0)
    286   1.6     lukem 		block_comment_max_col = max_col;
    287   1.6     lukem 	if (ps.decl_com_ind <= 0)	/* if not specified by user, set this */
    288   1.6     lukem 		ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
    289   1.6     lukem 	if (continuation_indent == 0)
    290   1.6     lukem 		continuation_indent = ps.ind_size;
    291   1.6     lukem 	fill_buffer();		/* get first batch of stuff into input buffer */
    292   1.6     lukem 
    293   1.6     lukem 	parse(semicolon);
    294   1.6     lukem 	{
    295   1.6     lukem 		char   *p = buf_ptr;
    296   1.6     lukem 		int     col = 1;
    297   1.6     lukem 
    298   1.6     lukem 		while (1) {
    299   1.6     lukem 			if (*p == ' ')
    300   1.6     lukem 				col++;
    301   1.6     lukem 			else
    302   1.6     lukem 				if (*p == '\t')
    303   1.6     lukem 					col = ((col - 1) & ~7) + 9;
    304   1.6     lukem 				else
    305   1.6     lukem 					break;
    306   1.6     lukem 			p++;
    307   1.6     lukem 		}
    308   1.6     lukem 		if (col > ps.ind_size)
    309   1.6     lukem 			ps.ind_level = ps.i_l_follow = col / ps.ind_size;
    310   1.1       cgd 	}
    311   1.6     lukem 	if (troff) {
    312   1.6     lukem 		char   *p = in_name, *beg = in_name;
    313   1.6     lukem 
    314   1.6     lukem 		while (*p)
    315   1.6     lukem 			if (*p++ == '/')
    316   1.6     lukem 				beg = p;
    317   1.6     lukem 		fprintf(output, ".Fn \"%s\"\n", beg);
    318   1.1       cgd 	}
    319   1.6     lukem 	/*
    320   1.6     lukem          * START OF MAIN LOOP
    321   1.6     lukem          */
    322   1.1       cgd 
    323   1.6     lukem 	while (1) {		/* this is the main loop.  it will go until we
    324   1.1       cgd 				 * reach eof */
    325   1.6     lukem 		int     is_procname;
    326   1.1       cgd 
    327   1.6     lukem 		type_code = lexi();	/* lexi reads one token.  The actual
    328   1.6     lukem 					 * characters read are stored in
    329   1.6     lukem 					 * "token". lexi returns a code
    330   1.6     lukem 					 * indicating the type of token */
    331   1.6     lukem 		is_procname = ps.procname[0];
    332   1.1       cgd 
    333   1.6     lukem 		/*
    334   1.6     lukem 		 * The following code moves everything following an if (), while (),
    335   1.6     lukem 		 * else, etc. up to the start of the following stmt to a buffer. This
    336   1.6     lukem 		 * allows proper handling of both kinds of brace placement.
    337   1.6     lukem 		 */
    338   1.6     lukem 
    339   1.6     lukem 		flushed_nl = false;
    340   1.6     lukem 		while (ps.search_brace) {	/* if we scanned an if(),
    341   1.6     lukem 						 * while(), etc., we might
    342   1.6     lukem 						 * need to copy stuff into a
    343   1.6     lukem 						 * buffer we must loop,
    344   1.6     lukem 						 * copying stuff into
    345   1.6     lukem 						 * save_com, until we find the
    346   1.6     lukem 						 * start of the stmt which
    347   1.6     lukem 						 * follows the if, or whatever */
    348   1.6     lukem 			switch (type_code) {
    349   1.6     lukem 			case newline:
    350   1.6     lukem 				++line_no;
    351   1.6     lukem 				flushed_nl = true;
    352   1.6     lukem 			case form_feed:
    353   1.6     lukem 				break;	/* form feeds and newlines found here
    354   1.6     lukem 					 * will be ignored */
    355   1.6     lukem 
    356   1.6     lukem 			case lbrace:	/* this is a brace that starts the
    357   1.6     lukem 					 * compound stmt */
    358   1.6     lukem 				if (sc_end == 0) {	/* ignore buffering if a
    359   1.6     lukem 							 * comment wasnt stored
    360   1.6     lukem 							 * up */
    361   1.6     lukem 					ps.search_brace = false;
    362   1.6     lukem 					goto check_type;
    363   1.6     lukem 				}
    364   1.6     lukem 				if (btype_2) {
    365   1.6     lukem 					save_com[0] = '{';	/* we either want to put
    366   1.6     lukem 								 * the brace right after
    367   1.6     lukem 								 * the if */
    368   1.6     lukem 					goto sw_buffer;	/* go to common code to
    369   1.6     lukem 							 * get out of this loop */
    370   1.6     lukem 				}
    371   1.6     lukem 			case comment:	/* we have a comment, so we must copy
    372   1.6     lukem 					 * it into the buffer */
    373   1.6     lukem 				if (!flushed_nl || sc_end != 0) {
    374   1.6     lukem 					if (sc_end == 0) {	/* if this is the first
    375   1.6     lukem 								 * comment, we must set
    376   1.6     lukem 								 * up the buffer */
    377   1.6     lukem 						save_com[0] = save_com[1] = ' ';
    378   1.6     lukem 						sc_end = &(save_com[2]);
    379   1.6     lukem 					} else {
    380   1.6     lukem 						*sc_end++ = '\n';	/* add newline between
    381   1.6     lukem 									 * comments */
    382   1.6     lukem 						*sc_end++ = ' ';
    383   1.6     lukem 						--line_no;
    384   1.6     lukem 					}
    385   1.6     lukem 					*sc_end++ = '/';	/* copy in start of
    386   1.6     lukem 								 * comment */
    387   1.6     lukem 					*sc_end++ = '*';
    388   1.6     lukem 
    389   1.6     lukem 					for (;;) {	/* loop until we get to
    390   1.6     lukem 							 * the end of the
    391   1.6     lukem 							 * comment */
    392   1.6     lukem 						*sc_end = *buf_ptr++;
    393   1.6     lukem 						if (buf_ptr >= buf_end)
    394   1.6     lukem 							fill_buffer();
    395   1.6     lukem 
    396   1.6     lukem 						if (*sc_end++ == '*' && *buf_ptr == '/')
    397   1.6     lukem 							break;	/* we are at end of
    398   1.6     lukem 								 * comment */
    399   1.6     lukem 
    400   1.6     lukem 						if (sc_end >= &(save_com[sc_size])) {	/* check for temp buffer
    401   1.6     lukem 											 * overflow */
    402   1.6     lukem 							diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
    403   1.6     lukem 							fflush(output);
    404   1.6     lukem 							exit(1);
    405   1.6     lukem 						}
    406   1.6     lukem 					}
    407   1.6     lukem 					*sc_end++ = '/';	/* add ending slash */
    408   1.6     lukem 					if (++buf_ptr >= buf_end)	/* get past / in buffer */
    409   1.6     lukem 						fill_buffer();
    410   1.6     lukem 					break;
    411   1.6     lukem 				}
    412   1.6     lukem 			default:	/* it is the start of a normal
    413   1.6     lukem 					 * statment */
    414   1.6     lukem 				if (flushed_nl)	/* if we flushed a newline,
    415   1.6     lukem 						 * make sure it is put back */
    416   1.6     lukem 					force_nl = true;
    417   1.6     lukem 				if ((type_code == sp_paren && *token == 'i'
    418   1.6     lukem 					&& last_else && ps.else_if) ||
    419   1.6     lukem 				    (type_code == sp_nparen && *token == 'e'
    420   1.6     lukem 					&& e_code != s_code && e_code[-1] == '}'))
    421   1.6     lukem 					force_nl = false;
    422   1.6     lukem 
    423   1.6     lukem 				if (sc_end == 0) {	/* ignore buffering if
    424   1.6     lukem 							 * comment wasnt saved
    425   1.6     lukem 							 * up */
    426   1.6     lukem 					ps.search_brace = false;
    427   1.6     lukem 					goto check_type;
    428   1.6     lukem 				}
    429   1.6     lukem 				if (force_nl) {	/* if we should insert a nl
    430   1.6     lukem 						 * here, put it into the
    431   1.6     lukem 						 * buffer */
    432   1.6     lukem 					force_nl = false;
    433   1.6     lukem 					--line_no;	/* this will be
    434   1.6     lukem 							 * re-increased when the
    435   1.6     lukem 							 * nl is read from the
    436   1.6     lukem 							 * buffer */
    437   1.6     lukem 					*sc_end++ = '\n';
    438   1.6     lukem 					*sc_end++ = ' ';
    439   1.6     lukem 					if (verbose && !flushed_nl)	/* print error msg if
    440   1.6     lukem 									 * the line was not
    441   1.6     lukem 									 * already broken */
    442   1.6     lukem 						diag(0, "Line broken");
    443   1.6     lukem 					flushed_nl = false;
    444   1.6     lukem 				}
    445   1.6     lukem 				for (t_ptr = token; *t_ptr; ++t_ptr)
    446   1.6     lukem 					*sc_end++ = *t_ptr;	/* copy token into temp
    447   1.6     lukem 								 * buffer */
    448   1.6     lukem 				ps.procname[0] = 0;
    449   1.6     lukem 
    450   1.6     lukem 		sw_buffer:
    451   1.6     lukem 				ps.search_brace = false;	/* stop looking for
    452   1.6     lukem 								 * start of stmt */
    453   1.6     lukem 				bp_save = buf_ptr;	/* save current input
    454   1.6     lukem 							 * buffer */
    455   1.6     lukem 				be_save = buf_end;
    456   1.6     lukem 				buf_ptr = save_com;	/* fix so that
    457   1.6     lukem 							 * subsequent calls to
    458   1.6     lukem 							 * lexi will take tokens
    459   1.6     lukem 							 * out of save_com */
    460   1.6     lukem 				*sc_end++ = ' ';	/* add trailing blank,
    461   1.6     lukem 							 * just in case */
    462   1.6     lukem 				buf_end = sc_end;
    463   1.6     lukem 				sc_end = 0;
    464   1.6     lukem 				break;
    465   1.6     lukem 			}	/* end of switch */
    466   1.6     lukem 			if (type_code != 0)	/* we must make this check,
    467   1.6     lukem 						 * just in case there was an
    468   1.6     lukem 						 * unexpected EOF */
    469   1.6     lukem 				type_code = lexi();	/* read another token */
    470   1.6     lukem 			/* if (ps.search_brace) ps.procname[0] = 0; */
    471   1.6     lukem 			if ((is_procname = ps.procname[0]) && flushed_nl
    472   1.6     lukem 			    && !procnames_start_line && ps.in_decl
    473   1.6     lukem 			    && type_code == ident)
    474   1.6     lukem 				flushed_nl = 0;
    475   1.6     lukem 		}		/* end of while (search_brace) */
    476   1.6     lukem 		last_else = 0;
    477   1.1       cgd check_type:
    478   1.6     lukem 		if (type_code == 0) {	/* we got eof */
    479   1.6     lukem 			if (s_lab != e_lab || s_code != e_code
    480   1.6     lukem 			    || s_com != e_com)	/* must dump end of line */
    481   1.6     lukem 				dump_line();
    482   1.6     lukem 			if (ps.tos > 1)	/* check for balanced braces */
    483   1.6     lukem 				diag(1, "Stuff missing from end of file.");
    484   1.6     lukem 
    485   1.6     lukem 			if (verbose) {
    486   1.6     lukem 				printf("There were %d output lines and %d comments\n",
    487   1.6     lukem 				    ps.out_lines, ps.out_coms);
    488   1.6     lukem 				printf("(Lines with comments)/(Lines with code): %6.3f\n",
    489   1.6     lukem 				    (1.0 * ps.com_lines) / code_lines);
    490   1.6     lukem 			}
    491   1.6     lukem 			fflush(output);
    492   1.6     lukem 			exit(found_err);
    493   1.1       cgd 		}
    494   1.6     lukem 		if (
    495   1.6     lukem 		    (type_code != comment) &&
    496   1.6     lukem 		    (type_code != newline) &&
    497   1.6     lukem 		    (type_code != preesc) &&
    498   1.6     lukem 		    (type_code != form_feed)) {
    499   1.6     lukem 			if (force_nl &&
    500   1.6     lukem 			    (type_code != semicolon) &&
    501   1.6     lukem 			    (type_code != lbrace || !btype_2)) {
    502   1.6     lukem 				/* we should force a broken line here */
    503   1.6     lukem 				if (verbose && !flushed_nl)
    504   1.6     lukem 					diag(0, "Line broken");
    505   1.6     lukem 				flushed_nl = false;
    506   1.6     lukem 				dump_line();
    507   1.6     lukem 				ps.want_blank = false;	/* dont insert blank at
    508   1.6     lukem 							 * line start */
    509   1.6     lukem 				force_nl = false;
    510   1.6     lukem 			}
    511   1.6     lukem 			ps.in_stmt = true;	/* turn on flag which causes
    512   1.6     lukem 						 * an extra level of
    513   1.6     lukem 						 * indentation. this is turned
    514   1.6     lukem 						 * off by a ; or '}' */
    515   1.6     lukem 			if (s_com != e_com) {	/* the turkey has embedded a
    516   1.6     lukem 						 * comment in a line. fix it */
    517   1.6     lukem 				*e_code++ = ' ';
    518   1.6     lukem 				for (t_ptr = s_com; *t_ptr; ++t_ptr) {
    519   1.6     lukem 					CHECK_SIZE_CODE;
    520   1.6     lukem 					*e_code++ = *t_ptr;
    521   1.6     lukem 				}
    522   1.6     lukem 				*e_code++ = ' ';
    523   1.6     lukem 				*e_code = '\0';	/* null terminate code sect */
    524   1.6     lukem 				ps.want_blank = false;
    525   1.6     lukem 				e_com = s_com;
    526   1.6     lukem 			}
    527   1.6     lukem 		} else
    528   1.6     lukem 			if (type_code != comment)	/* preserve force_nl
    529   1.6     lukem 							 * thru a comment */
    530   1.6     lukem 				force_nl = false;	/* cancel forced newline
    531   1.6     lukem 							 * after newline, form
    532   1.6     lukem 							 * feed, etc */
    533   1.1       cgd 
    534   1.1       cgd 
    535   1.1       cgd 
    536   1.6     lukem 		/*-----------------------------------------------------*\
    537   1.6     lukem 		|	   do switch on type of token scanned		|
    538   1.6     lukem 		\*-----------------------------------------------------*/
    539   1.6     lukem 		CHECK_SIZE_CODE;
    540   1.6     lukem 		switch (type_code) {	/* now, decide what to do with the
    541   1.6     lukem 					 * token */
    542   1.6     lukem 
    543   1.6     lukem 		case form_feed:/* found a form feed in line */
    544   1.6     lukem 			ps.use_ff = true;	/* a form feed is treated much
    545   1.6     lukem 						 * like a newline */
    546   1.6     lukem 			dump_line();
    547   1.6     lukem 			ps.want_blank = false;
    548   1.6     lukem 			break;
    549   1.6     lukem 
    550   1.6     lukem 		case newline:
    551   1.6     lukem 			if (ps.last_token != comma || ps.p_l_follow > 0
    552   1.6     lukem 			    || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
    553   1.6     lukem 				dump_line();
    554   1.6     lukem 				ps.want_blank = false;
    555   1.6     lukem 			}
    556   1.6     lukem 			++line_no;	/* keep track of input line number */
    557   1.6     lukem 			break;
    558   1.1       cgd 
    559   1.6     lukem 		case lparen:	/* got a '(' or '[' */
    560   1.6     lukem 			++ps.p_l_follow;	/* count parens to make Healy
    561   1.6     lukem 						 * happy */
    562   1.6     lukem 			if (ps.want_blank && *token != '[' &&
    563   1.6     lukem 			    (ps.last_token != ident || proc_calls_space
    564   1.6     lukem 				|| (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon))))
    565   1.6     lukem 				*e_code++ = ' ';
    566  1.10  christos 			if (ps.in_decl && !ps.block_init) {
    567   1.6     lukem 				if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) {
    568   1.6     lukem 					ps.dumped_decl_indent = 1;
    569   1.6     lukem 					sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
    570   1.6     lukem 					e_code += strlen(e_code);
    571   1.6     lukem 				} else {
    572   1.6     lukem 					while ((e_code - s_code) < dec_ind) {
    573   1.6     lukem 						CHECK_SIZE_CODE;
    574   1.6     lukem 						*e_code++ = ' ';
    575   1.6     lukem 					}
    576   1.6     lukem 					*e_code++ = token[0];
    577   1.6     lukem 				}
    578  1.10  christos 			} else
    579   1.6     lukem 				*e_code++ = token[0];
    580   1.6     lukem 			ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
    581   1.6     lukem 			if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent
    582   1.6     lukem 			    && ps.paren_indents[0] < 2 * ps.ind_size)
    583   1.6     lukem 				ps.paren_indents[0] = 2 * ps.ind_size;
    584   1.6     lukem 			ps.want_blank = false;
    585   1.6     lukem 			if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
    586   1.6     lukem 				/*
    587   1.6     lukem 				 * this is a kluge to make sure that declarations will be
    588   1.6     lukem 				 * aligned right if proc decl has an explicit type on it, i.e.
    589   1.6     lukem 				 * "int a(x) {..."
    590   1.6     lukem 				 */
    591   1.6     lukem 				parse(semicolon);	/* I said this was a
    592   1.6     lukem 							 * kluge... */
    593   1.6     lukem 				ps.in_or_st = false;	/* turn off flag for
    594   1.6     lukem 							 * structure decl or
    595   1.6     lukem 							 * initialization */
    596   1.6     lukem 			}
    597   1.6     lukem 			if (ps.sizeof_keyword)
    598   1.6     lukem 				ps.sizeof_mask |= 1 << ps.p_l_follow;
    599   1.1       cgd 			break;
    600   1.6     lukem 
    601   1.6     lukem 		case rparen:	/* got a ')' or ']' */
    602   1.6     lukem 			rparen_count--;
    603   1.6     lukem 			if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
    604   1.6     lukem 				ps.last_u_d = true;
    605   1.6     lukem 				ps.cast_mask &= (1 << ps.p_l_follow) - 1;
    606   1.6     lukem 			}
    607   1.6     lukem 			ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
    608   1.6     lukem 			if (--ps.p_l_follow < 0) {
    609   1.6     lukem 				ps.p_l_follow = 0;
    610   1.6     lukem 				diag(0, "Extra %c", *token);
    611   1.6     lukem 			}
    612   1.6     lukem 			if (e_code == s_code)	/* if the paren starts the
    613   1.6     lukem 						 * line */
    614   1.6     lukem 				ps.paren_level = ps.p_l_follow;	/* then indent it */
    615   1.6     lukem 
    616   1.6     lukem 			*e_code++ = token[0];
    617   1.6     lukem 			ps.want_blank = true;
    618   1.6     lukem 
    619   1.6     lukem 			if (sp_sw && (ps.p_l_follow == 0)) {	/* check for end of if
    620   1.6     lukem 								 * (...), or some such */
    621   1.6     lukem 				sp_sw = false;
    622   1.6     lukem 				force_nl = true;	/* must force newline
    623   1.6     lukem 							 * after if */
    624   1.6     lukem 				ps.last_u_d = true;	/* inform lexi that a
    625   1.6     lukem 							 * following operator is
    626   1.6     lukem 							 * unary */
    627   1.6     lukem 				ps.in_stmt = false;	/* dont use stmt
    628   1.6     lukem 							 * continuation
    629   1.6     lukem 							 * indentation */
    630   1.6     lukem 
    631   1.6     lukem 				parse(hd_type);	/* let parser worry about if,
    632   1.6     lukem 						 * or whatever */
    633   1.6     lukem 			}
    634   1.6     lukem 			ps.search_brace = btype_2;	/* this should insure
    635   1.6     lukem 							 * that constructs such
    636   1.6     lukem 							 * as main(){...} and
    637   1.6     lukem 							 * int[]{...} have their
    638   1.6     lukem 							 * braces put in the
    639   1.6     lukem 							 * right place */
    640   1.1       cgd 			break;
    641   1.6     lukem 
    642   1.6     lukem 		case unary_op:	/* this could be any unary operation */
    643   1.6     lukem 			if (ps.want_blank)
    644   1.6     lukem 				*e_code++ = ' ';
    645   1.6     lukem 
    646   1.6     lukem 			if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) {
    647   1.6     lukem 				sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
    648   1.6     lukem 				ps.dumped_decl_indent = 1;
    649   1.6     lukem 				e_code += strlen(e_code);
    650   1.6     lukem 			} else {
    651   1.6     lukem 				char   *res = token;
    652   1.6     lukem 
    653   1.6     lukem 				if (ps.in_decl && !ps.block_init) {	/* if this is a unary op
    654   1.6     lukem 									 * in a declaration, we
    655   1.6     lukem 									 * should indent this
    656   1.6     lukem 									 * token */
    657   1.6     lukem 					for (i = 0; token[i]; ++i);	/* find length of token */
    658   1.6     lukem 					while ((e_code - s_code) < (dec_ind - i)) {
    659   1.6     lukem 						CHECK_SIZE_CODE;
    660   1.6     lukem 						*e_code++ = ' ';	/* pad it */
    661   1.6     lukem 					}
    662   1.6     lukem 				}
    663   1.6     lukem 				if (troff && token[0] == '-' && token[1] == '>')
    664   1.6     lukem 					res = "\\(->";
    665   1.6     lukem 				for (t_ptr = res; *t_ptr; ++t_ptr) {
    666   1.6     lukem 					CHECK_SIZE_CODE;
    667   1.6     lukem 					*e_code++ = *t_ptr;
    668   1.6     lukem 				}
    669   1.6     lukem 			}
    670   1.6     lukem 			ps.want_blank = false;
    671   1.1       cgd 			break;
    672   1.6     lukem 
    673   1.6     lukem 		case binary_op:/* any binary operation */
    674   1.6     lukem 			if (ps.want_blank)
    675   1.6     lukem 				*e_code++ = ' ';
    676   1.6     lukem 			{
    677   1.6     lukem 				char   *res = token;
    678   1.6     lukem 
    679   1.6     lukem 				if (troff)
    680   1.6     lukem 					switch (token[0]) {
    681   1.6     lukem 					case '<':
    682   1.6     lukem 						if (token[1] == '=')
    683   1.6     lukem 							res = "\\(<=";
    684   1.6     lukem 						break;
    685   1.6     lukem 					case '>':
    686   1.6     lukem 						if (token[1] == '=')
    687   1.6     lukem 							res = "\\(>=";
    688   1.6     lukem 						break;
    689   1.6     lukem 					case '!':
    690   1.6     lukem 						if (token[1] == '=')
    691   1.6     lukem 							res = "\\(!=";
    692   1.6     lukem 						break;
    693   1.6     lukem 					case '|':
    694   1.6     lukem 						if (token[1] == '|')
    695   1.6     lukem 							res = "\\(br\\(br";
    696   1.6     lukem 						else
    697   1.6     lukem 							if (token[1] == 0)
    698   1.6     lukem 								res = "\\(br";
    699   1.6     lukem 						break;
    700   1.6     lukem 					}
    701   1.6     lukem 				for (t_ptr = res; *t_ptr; ++t_ptr) {
    702   1.6     lukem 					CHECK_SIZE_CODE;
    703   1.6     lukem 					*e_code++ = *t_ptr;	/* move the operator */
    704   1.6     lukem 				}
    705   1.6     lukem 			}
    706   1.6     lukem 			ps.want_blank = true;
    707   1.1       cgd 			break;
    708   1.1       cgd 
    709   1.6     lukem 		case postop:	/* got a trailing ++ or -- */
    710   1.6     lukem 			*e_code++ = token[0];
    711   1.6     lukem 			*e_code++ = token[1];
    712   1.6     lukem 			ps.want_blank = true;
    713   1.6     lukem 			break;
    714   1.1       cgd 
    715   1.6     lukem 		case question:	/* got a ? */
    716   1.6     lukem 			squest++;	/* this will be used when a later
    717   1.6     lukem 					 * colon appears so we can distinguish
    718   1.6     lukem 					 * the <c>?<n>:<n> construct */
    719   1.6     lukem 			if (ps.want_blank)
    720   1.6     lukem 				*e_code++ = ' ';
    721   1.6     lukem 			*e_code++ = '?';
    722   1.6     lukem 			ps.want_blank = true;
    723   1.6     lukem 			break;
    724   1.1       cgd 
    725   1.6     lukem 		case casestmt:	/* got word 'case' or 'default' */
    726   1.6     lukem 			scase = true;	/* so we can process the later colon
    727   1.6     lukem 					 * properly */
    728   1.6     lukem 			goto copy_id;
    729   1.6     lukem 
    730   1.6     lukem 		case colon:	/* got a ':' */
    731   1.6     lukem 			if (squest > 0) {	/* it is part of the <c>?<n>:
    732   1.6     lukem 						 * <n> construct */
    733   1.6     lukem 				--squest;
    734   1.6     lukem 				if (ps.want_blank)
    735   1.6     lukem 					*e_code++ = ' ';
    736   1.6     lukem 				*e_code++ = ':';
    737   1.6     lukem 				ps.want_blank = true;
    738   1.6     lukem 				break;
    739   1.6     lukem 			}
    740  1.11    kleink 			if (ps.in_or_st) {
    741   1.6     lukem 				*e_code++ = ':';
    742   1.6     lukem 				ps.want_blank = false;
    743   1.6     lukem 				break;
    744   1.6     lukem 			}
    745   1.6     lukem 			ps.in_stmt = false;	/* seeing a label does not
    746   1.6     lukem 						 * imply we are in a stmt */
    747   1.6     lukem 			for (t_ptr = s_code; *t_ptr; ++t_ptr)
    748   1.6     lukem 				*e_lab++ = *t_ptr;	/* turn everything so
    749   1.6     lukem 							 * far into a label */
    750   1.6     lukem 			e_code = s_code;
    751   1.6     lukem 			*e_lab++ = ':';
    752   1.6     lukem 			*e_lab++ = ' ';
    753   1.6     lukem 			*e_lab = '\0';
    754   1.6     lukem 
    755   1.6     lukem 			force_nl = ps.pcase = scase;	/* ps.pcase will be used
    756   1.6     lukem 							 * by dump_line to
    757   1.6     lukem 							 * decide how to indent
    758   1.6     lukem 							 * the label. force_nl
    759   1.6     lukem 							 * will force a case n:
    760   1.6     lukem 							 * to be on a line by
    761   1.6     lukem 							 * itself */
    762   1.6     lukem 			scase = false;
    763   1.6     lukem 			ps.want_blank = false;
    764   1.6     lukem 			break;
    765   1.1       cgd 
    766   1.6     lukem 		case semicolon:/* got a ';' */
    767   1.6     lukem 			ps.in_or_st = false;	/* we are not in an
    768   1.6     lukem 						 * initialization or structure
    769   1.6     lukem 						 * declaration */
    770   1.6     lukem 			scase = false;	/* these will only need resetting in a
    771   1.6     lukem 					 * error */
    772   1.6     lukem 			squest = 0;
    773   1.6     lukem 			if (ps.last_token == rparen && rparen_count == 0)
    774   1.6     lukem 				ps.in_parameter_declaration = 0;
    775   1.6     lukem 			ps.cast_mask = 0;
    776   1.6     lukem 			ps.sizeof_mask = 0;
    777   1.6     lukem 			ps.block_init = 0;
    778   1.6     lukem 			ps.block_init_level = 0;
    779   1.6     lukem 			ps.just_saw_decl--;
    780   1.6     lukem 
    781   1.6     lukem 			if (ps.in_decl && s_code == e_code && !ps.block_init)
    782   1.6     lukem 				while ((e_code - s_code) < (dec_ind - 1)) {
    783   1.6     lukem 					CHECK_SIZE_CODE;
    784   1.6     lukem 					*e_code++ = ' ';
    785   1.6     lukem 				}
    786   1.6     lukem 
    787   1.6     lukem 			ps.in_decl = (ps.dec_nest > 0);	/* if we were in a first
    788   1.6     lukem 							 * level structure
    789   1.6     lukem 							 * declaration, we arent
    790   1.6     lukem 							 * any more */
    791   1.6     lukem 
    792   1.6     lukem 			if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
    793   1.6     lukem 
    794   1.6     lukem 				/*
    795   1.6     lukem 				 * This should be true iff there were unbalanced parens in the
    796   1.6     lukem 				 * stmt.  It is a bit complicated, because the semicolon might
    797   1.6     lukem 				 * be in a for stmt
    798   1.6     lukem 				 */
    799   1.6     lukem 				diag(1, "Unbalanced parens");
    800   1.6     lukem 				ps.p_l_follow = 0;
    801   1.6     lukem 				if (sp_sw) {	/* this is a check for a if,
    802   1.6     lukem 						 * while, etc. with unbalanced
    803   1.6     lukem 						 * parens */
    804   1.6     lukem 					sp_sw = false;
    805   1.6     lukem 					parse(hd_type);	/* dont lose the if, or
    806   1.6     lukem 							 * whatever */
    807   1.6     lukem 				}
    808   1.6     lukem 			}
    809   1.6     lukem 			*e_code++ = ';';
    810   1.6     lukem 			ps.want_blank = true;
    811   1.6     lukem 			ps.in_stmt = (ps.p_l_follow > 0);	/* we are no longer in
    812   1.6     lukem 								 * the middle of a stmt */
    813   1.6     lukem 
    814   1.6     lukem 			if (!sp_sw) {	/* if not if for (;;) */
    815   1.6     lukem 				parse(semicolon);	/* let parser know about
    816   1.6     lukem 							 * end of stmt */
    817   1.6     lukem 				force_nl = true;	/* force newline after a
    818   1.6     lukem 							 * end of stmt */
    819   1.1       cgd 			}
    820   1.6     lukem 			break;
    821   1.6     lukem 
    822   1.6     lukem 		case lbrace:	/* got a '{' */
    823   1.6     lukem 			ps.in_stmt = false;	/* dont indent the {} */
    824   1.6     lukem 			if (!ps.block_init)
    825   1.6     lukem 				force_nl = true;	/* force other stuff on
    826   1.6     lukem 							 * same line as '{' onto
    827   1.6     lukem 							 * new line */
    828   1.1       cgd 			else
    829   1.6     lukem 				if (ps.block_init_level <= 0)
    830   1.6     lukem 					ps.block_init_level = 1;
    831   1.6     lukem 				else
    832   1.6     lukem 					ps.block_init_level++;
    833   1.6     lukem 
    834   1.6     lukem 			if (s_code != e_code && !ps.block_init) {
    835   1.6     lukem 				if (!btype_2) {
    836   1.6     lukem 					dump_line();
    837   1.6     lukem 					ps.want_blank = false;
    838   1.6     lukem 				} else
    839   1.6     lukem 					if (ps.in_parameter_declaration && !ps.in_or_st) {
    840   1.6     lukem 						ps.i_l_follow = 0;
    841   1.6     lukem 						dump_line();
    842   1.6     lukem 						ps.want_blank = false;
    843   1.6     lukem 					}
    844   1.6     lukem 			}
    845   1.6     lukem 			if (ps.in_parameter_declaration)
    846   1.6     lukem 				prefix_blankline_requested = 0;
    847   1.6     lukem 
    848  1.12       wiz 			if (ps.p_l_follow > 0) {	/* check for preceding
    849   1.6     lukem 							 * unbalanced parens */
    850   1.6     lukem 				diag(1, "Unbalanced parens");
    851   1.6     lukem 				ps.p_l_follow = 0;
    852   1.6     lukem 				if (sp_sw) {	/* check for unclosed if, for,
    853   1.6     lukem 						 * etc. */
    854   1.6     lukem 					sp_sw = false;
    855   1.6     lukem 					parse(hd_type);
    856   1.6     lukem 					ps.ind_level = ps.i_l_follow;
    857   1.6     lukem 				}
    858   1.6     lukem 			}
    859   1.6     lukem 			if (s_code == e_code)
    860   1.6     lukem 				ps.ind_stmt = false;	/* dont put extra
    861   1.6     lukem 							 * indentation on line
    862   1.6     lukem 							 * with '{' */
    863   1.6     lukem 			if (ps.in_decl && ps.in_or_st) {	/* this is either a
    864   1.6     lukem 								 * structure declaration
    865   1.6     lukem 								 * or an init */
    866   1.6     lukem 				di_stack[ps.dec_nest++] = dec_ind;
    867   1.6     lukem 				/* ?		dec_ind = 0; */
    868   1.6     lukem 			} else {
    869   1.6     lukem 				ps.decl_on_line = false;	/* we cant be in the
    870   1.6     lukem 								 * middle of a
    871   1.6     lukem 								 * declaration, so dont
    872   1.6     lukem 								 * do special
    873   1.6     lukem 								 * indentation of
    874   1.6     lukem 								 * comments */
    875   1.6     lukem 				if (blanklines_after_declarations_at_proctop
    876   1.6     lukem 				    && ps.in_parameter_declaration)
    877   1.6     lukem 					postfix_blankline_requested = 1;
    878   1.6     lukem 				ps.in_parameter_declaration = 0;
    879   1.6     lukem 			}
    880   1.6     lukem 			dec_ind = 0;
    881   1.6     lukem 			parse(lbrace);	/* let parser know about this */
    882   1.6     lukem 			if (ps.want_blank)	/* put a blank before '{' if
    883   1.6     lukem 						 * '{' is not at start of line */
    884   1.1       cgd 				*e_code++ = ' ';
    885   1.6     lukem 			ps.want_blank = false;
    886   1.6     lukem 			*e_code++ = '{';
    887   1.6     lukem 			ps.just_saw_decl = 0;
    888   1.6     lukem 			break;
    889   1.6     lukem 
    890   1.6     lukem 		case rbrace:	/* got a '}' */
    891   1.6     lukem 			if (ps.p_stack[ps.tos] == decl && !ps.block_init)	/* semicolons can be
    892   1.6     lukem 										 * omitted in
    893   1.6     lukem 										 * declarations */
    894   1.6     lukem 				parse(semicolon);
    895   1.6     lukem 			if (ps.p_l_follow) {	/* check for unclosed if, for,
    896   1.6     lukem 						 * else. */
    897   1.6     lukem 				diag(1, "Unbalanced parens");
    898   1.6     lukem 				ps.p_l_follow = 0;
    899   1.6     lukem 				sp_sw = false;
    900   1.6     lukem 			}
    901   1.6     lukem 			ps.just_saw_decl = 0;
    902   1.6     lukem 			ps.block_init_level--;
    903   1.6     lukem 			if (s_code != e_code && !ps.block_init) {	/* '}' must be first on
    904   1.6     lukem 									 * line */
    905   1.6     lukem 				if (verbose)
    906   1.6     lukem 					diag(0, "Line broken");
    907   1.6     lukem 				dump_line();
    908   1.6     lukem 			}
    909   1.6     lukem 			*e_code++ = '}';
    910   1.6     lukem 			ps.want_blank = true;
    911   1.6     lukem 			ps.in_stmt = ps.ind_stmt = false;
    912   1.6     lukem 			if (ps.dec_nest > 0) {	/* we are in multi-level
    913   1.6     lukem 						 * structure declaration */
    914   1.6     lukem 				dec_ind = di_stack[--ps.dec_nest];
    915   1.6     lukem 				if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
    916   1.6     lukem 					ps.just_saw_decl = 2;
    917   1.6     lukem 				ps.in_decl = true;
    918   1.6     lukem 			}
    919   1.6     lukem 			prefix_blankline_requested = 0;
    920   1.6     lukem 			parse(rbrace);	/* let parser know about this */
    921   1.6     lukem 			ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead
    922   1.6     lukem 			    && ps.il[ps.tos] >= ps.ind_level;
    923   1.6     lukem 			if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
    924   1.6     lukem 				postfix_blankline_requested = 1;
    925   1.6     lukem 			break;
    926   1.1       cgd 
    927   1.6     lukem 		case swstmt:	/* got keyword "switch" */
    928   1.6     lukem 			sp_sw = true;
    929   1.6     lukem 			hd_type = swstmt;	/* keep this for when we have
    930   1.6     lukem 						 * seen the expression */
    931   1.6     lukem 			goto copy_id;	/* go move the token into buffer */
    932   1.6     lukem 
    933   1.6     lukem 		case sp_paren:	/* token is if, while, for */
    934   1.6     lukem 			sp_sw = true;	/* the interesting stuff is done after
    935   1.6     lukem 					 * the expression is scanned */
    936   1.6     lukem 			hd_type = (*token == 'i' ? ifstmt :
    937   1.6     lukem 			    (*token == 'w' ? whilestmt : forstmt));
    938   1.6     lukem 
    939   1.6     lukem 			/*
    940   1.6     lukem 		         * remember the type of header for later use by parser
    941   1.6     lukem 		         */
    942   1.6     lukem 			goto copy_id;	/* copy the token into line */
    943   1.6     lukem 
    944   1.6     lukem 		case sp_nparen:/* got else, do */
    945   1.6     lukem 			ps.in_stmt = false;
    946   1.6     lukem 			if (*token == 'e') {
    947   1.6     lukem 				if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
    948   1.6     lukem 					if (verbose)
    949   1.6     lukem 						diag(0, "Line broken");
    950   1.6     lukem 					dump_line();	/* make sure this starts
    951   1.6     lukem 							 * a line */
    952   1.6     lukem 					ps.want_blank = false;
    953   1.6     lukem 				}
    954   1.6     lukem 				force_nl = true;	/* also, following stuff
    955   1.6     lukem 							 * must go onto new line */
    956   1.6     lukem 				last_else = 1;
    957   1.6     lukem 				parse(elselit);
    958   1.6     lukem 			} else {
    959   1.6     lukem 				if (e_code != s_code) {	/* make sure this starts
    960   1.6     lukem 							 * a line */
    961   1.6     lukem 					if (verbose)
    962   1.6     lukem 						diag(0, "Line broken");
    963   1.6     lukem 					dump_line();
    964   1.6     lukem 					ps.want_blank = false;
    965   1.6     lukem 				}
    966   1.6     lukem 				force_nl = true;	/* also, following stuff
    967   1.6     lukem 							 * must go onto new line */
    968   1.6     lukem 				last_else = 0;
    969   1.6     lukem 				parse(dolit);
    970   1.6     lukem 			}
    971   1.6     lukem 			goto copy_id;	/* move the token into line */
    972   1.1       cgd 
    973   1.6     lukem 		case decl:	/* we have a declaration type (int, register,
    974   1.6     lukem 				 * etc.) */
    975   1.6     lukem 			parse(decl);	/* let parser worry about indentation */
    976   1.6     lukem 			if (ps.last_token == rparen && ps.tos <= 1) {
    977   1.6     lukem 				ps.in_parameter_declaration = 1;
    978   1.6     lukem 				if (s_code != e_code) {
    979   1.6     lukem 					dump_line();
    980   1.6     lukem 					ps.want_blank = 0;
    981   1.6     lukem 				}
    982   1.1       cgd 			}
    983   1.6     lukem 			if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
    984   1.6     lukem 				ps.ind_level = ps.i_l_follow = 1;
    985   1.6     lukem 				ps.ind_stmt = 0;
    986   1.1       cgd 			}
    987   1.6     lukem 			ps.in_or_st = true;	/* this might be a structure
    988   1.6     lukem 						 * or initialization
    989   1.6     lukem 						 * declaration */
    990   1.6     lukem 			ps.in_decl = ps.decl_on_line = true;
    991   1.6     lukem 			if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
    992   1.6     lukem 				ps.just_saw_decl = 2;
    993   1.6     lukem 			prefix_blankline_requested = 0;
    994   1.6     lukem 			for (i = 0; token[i++];);	/* get length of token */
    995   1.6     lukem 
    996   1.6     lukem 			/*
    997   1.6     lukem 		         * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent
    998   1.6     lukem 		         * : i);
    999   1.6     lukem 		         */
   1000   1.6     lukem 			dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
   1001   1.6     lukem 			goto copy_id;
   1002   1.6     lukem 
   1003   1.6     lukem 		case ident:	/* got an identifier or constant */
   1004   1.6     lukem 			if (ps.in_decl) {	/* if we are in a declaration,
   1005   1.6     lukem 						 * we must indent identifier */
   1006   1.6     lukem 				if (ps.want_blank)
   1007   1.6     lukem 					*e_code++ = ' ';
   1008   1.6     lukem 				ps.want_blank = false;
   1009   1.6     lukem 				if (is_procname == 0 || !procnames_start_line) {
   1010   1.7      ross 					if (!ps.block_init) {
   1011   1.6     lukem 						if (troff && !ps.dumped_decl_indent) {
   1012   1.6     lukem 							sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7);
   1013   1.6     lukem 							ps.dumped_decl_indent = 1;
   1014   1.6     lukem 							e_code += strlen(e_code);
   1015   1.6     lukem 						} else
   1016   1.6     lukem 							while ((e_code - s_code) < dec_ind) {
   1017   1.6     lukem 								CHECK_SIZE_CODE;
   1018   1.6     lukem 								*e_code++ = ' ';
   1019   1.6     lukem 							}
   1020   1.7      ross 					}
   1021   1.6     lukem 				} else {
   1022   1.6     lukem 					if (dec_ind && s_code != e_code)
   1023   1.6     lukem 						dump_line();
   1024   1.6     lukem 					dec_ind = 0;
   1025   1.6     lukem 					ps.want_blank = false;
   1026   1.6     lukem 				}
   1027   1.6     lukem 			} else
   1028   1.6     lukem 				if (sp_sw && ps.p_l_follow == 0) {
   1029   1.6     lukem 					sp_sw = false;
   1030   1.6     lukem 					force_nl = true;
   1031   1.6     lukem 					ps.last_u_d = true;
   1032   1.6     lukem 					ps.in_stmt = false;
   1033   1.6     lukem 					parse(hd_type);
   1034   1.6     lukem 				}
   1035   1.6     lukem 	copy_id:
   1036   1.6     lukem 			if (ps.want_blank)
   1037   1.6     lukem 				*e_code++ = ' ';
   1038   1.6     lukem 			if (troff && ps.its_a_keyword) {
   1039   1.6     lukem 				e_code = chfont(&bodyf, &keywordf, e_code);
   1040   1.6     lukem 				for (t_ptr = token; *t_ptr; ++t_ptr) {
   1041   1.6     lukem 					CHECK_SIZE_CODE;
   1042  1.16       dsl 					*e_code++ = keywordf.allcaps
   1043  1.16       dsl 					    ? toupper((unsigned char)*t_ptr)
   1044  1.16       dsl 					    : *t_ptr;
   1045   1.6     lukem 				}
   1046   1.6     lukem 				e_code = chfont(&keywordf, &bodyf, e_code);
   1047   1.6     lukem 			} else
   1048   1.6     lukem 				for (t_ptr = token; *t_ptr; ++t_ptr) {
   1049   1.6     lukem 					CHECK_SIZE_CODE;
   1050   1.6     lukem 					*e_code++ = *t_ptr;
   1051   1.6     lukem 				}
   1052   1.6     lukem 			ps.want_blank = true;
   1053   1.1       cgd 			break;
   1054   1.6     lukem 
   1055   1.6     lukem 		case period:	/* treat a period kind of like a binary
   1056   1.6     lukem 				 * operation */
   1057   1.6     lukem 			*e_code++ = '.';	/* move the period into line */
   1058   1.6     lukem 			ps.want_blank = false;	/* dont put a blank after a
   1059   1.6     lukem 						 * period */
   1060   1.1       cgd 			break;
   1061   1.6     lukem 
   1062   1.6     lukem 		case comma:
   1063   1.6     lukem 			ps.want_blank = (s_code != e_code);	/* only put blank after
   1064   1.6     lukem 								 * comma if comma does
   1065   1.6     lukem 								 * not start the line */
   1066   1.6     lukem 			if (ps.in_decl && is_procname == 0 && !ps.block_init)
   1067   1.6     lukem 				while ((e_code - s_code) < (dec_ind - 1)) {
   1068   1.6     lukem 					CHECK_SIZE_CODE;
   1069   1.6     lukem 					*e_code++ = ' ';
   1070   1.6     lukem 				}
   1071   1.6     lukem 
   1072   1.6     lukem 			*e_code++ = ',';
   1073   1.6     lukem 			if (ps.p_l_follow == 0) {
   1074   1.6     lukem 				if (ps.block_init_level <= 0)
   1075   1.6     lukem 					ps.block_init = 0;
   1076   1.6     lukem 				if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8))
   1077   1.6     lukem 					force_nl = true;
   1078   1.6     lukem 			}
   1079   1.1       cgd 			break;
   1080   1.6     lukem 
   1081   1.6     lukem 		case preesc:	/* got the character '#' */
   1082   1.6     lukem 			if ((s_com != e_com) ||
   1083   1.6     lukem 			    (s_lab != e_lab) ||
   1084   1.6     lukem 			    (s_code != e_code))
   1085   1.6     lukem 				dump_line();
   1086   1.6     lukem 			*e_lab++ = '#';	/* move whole line to 'label' buffer */
   1087   1.6     lukem 			{
   1088   1.6     lukem 				int     in_comment = 0;
   1089   1.6     lukem 				int     com_start = 0;
   1090   1.6     lukem 				char    quote = 0;
   1091   1.6     lukem 				int     com_end = 0;
   1092   1.6     lukem 
   1093   1.6     lukem 				while (*buf_ptr == ' ' || *buf_ptr == '\t') {
   1094   1.6     lukem 					buf_ptr++;
   1095   1.6     lukem 					if (buf_ptr >= buf_end)
   1096   1.6     lukem 						fill_buffer();
   1097   1.6     lukem 				}
   1098   1.6     lukem 				while (*buf_ptr != '\n' || in_comment) {
   1099   1.6     lukem 					CHECK_SIZE_LAB;
   1100   1.6     lukem 					*e_lab = *buf_ptr++;
   1101   1.6     lukem 					if (buf_ptr >= buf_end)
   1102   1.6     lukem 						fill_buffer();
   1103   1.6     lukem 					switch (*e_lab++) {
   1104   1.6     lukem 					case BACKSLASH:
   1105   1.6     lukem 						if (troff)
   1106   1.6     lukem 							*e_lab++ = BACKSLASH;
   1107   1.6     lukem 						if (!in_comment) {
   1108   1.6     lukem 							*e_lab++ = *buf_ptr++;
   1109   1.6     lukem 							if (buf_ptr >= buf_end)
   1110   1.6     lukem 								fill_buffer();
   1111   1.6     lukem 						}
   1112   1.6     lukem 						break;
   1113   1.6     lukem 					case '/':
   1114   1.6     lukem 						if (*buf_ptr == '*' && !in_comment && !quote) {
   1115   1.6     lukem 							in_comment = 1;
   1116   1.6     lukem 							*e_lab++ = *buf_ptr++;
   1117   1.6     lukem 							com_start = e_lab - s_lab - 2;
   1118   1.6     lukem 						}
   1119   1.6     lukem 						break;
   1120   1.6     lukem 					case '"':
   1121   1.6     lukem 						if (quote == '"')
   1122   1.6     lukem 							quote = 0;
   1123   1.6     lukem 						break;
   1124   1.6     lukem 					case '\'':
   1125   1.6     lukem 						if (quote == '\'')
   1126   1.6     lukem 							quote = 0;
   1127   1.6     lukem 						break;
   1128   1.6     lukem 					case '*':
   1129   1.6     lukem 						if (*buf_ptr == '/' && in_comment) {
   1130   1.6     lukem 							in_comment = 0;
   1131   1.6     lukem 							*e_lab++ = *buf_ptr++;
   1132   1.6     lukem 							com_end = e_lab - s_lab;
   1133   1.6     lukem 						}
   1134   1.6     lukem 						break;
   1135   1.6     lukem 					}
   1136   1.6     lukem 				}
   1137   1.6     lukem 
   1138   1.6     lukem 				while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
   1139   1.6     lukem 					e_lab--;
   1140   1.6     lukem 				if (e_lab - s_lab == com_end && bp_save == 0) {	/* comment on
   1141   1.6     lukem 										 * preprocessor line */
   1142   1.6     lukem 					if (sc_end == 0)	/* if this is the first
   1143   1.6     lukem 								 * comment, we must set
   1144   1.6     lukem 								 * up the buffer */
   1145   1.6     lukem 						sc_end = &(save_com[0]);
   1146   1.6     lukem 					else {
   1147   1.6     lukem 						*sc_end++ = '\n';	/* add newline between
   1148   1.6     lukem 									 * comments */
   1149   1.6     lukem 						*sc_end++ = ' ';
   1150   1.6     lukem 						--line_no;
   1151   1.6     lukem 					}
   1152   1.6     lukem 					memmove(sc_end, s_lab + com_start, com_end - com_start);
   1153   1.6     lukem 					sc_end += com_end - com_start;
   1154   1.6     lukem 					if (sc_end >= &save_com[sc_size])
   1155   1.6     lukem 						abort();
   1156   1.6     lukem 					e_lab = s_lab + com_start;
   1157   1.6     lukem 					while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
   1158   1.6     lukem 						e_lab--;
   1159   1.6     lukem 					bp_save = buf_ptr;	/* save current input
   1160   1.6     lukem 								 * buffer */
   1161   1.6     lukem 					be_save = buf_end;
   1162   1.6     lukem 					buf_ptr = save_com;	/* fix so that
   1163   1.6     lukem 								 * subsequent calls to
   1164   1.6     lukem 								 * lexi will take tokens
   1165   1.6     lukem 								 * out of save_com */
   1166   1.6     lukem 					*sc_end++ = ' ';	/* add trailing blank,
   1167   1.6     lukem 								 * just in case */
   1168   1.6     lukem 					buf_end = sc_end;
   1169   1.6     lukem 					sc_end = 0;
   1170   1.6     lukem 				}
   1171   1.6     lukem 				*e_lab = '\0';	/* null terminate line */
   1172   1.6     lukem 				ps.pcase = false;
   1173   1.1       cgd 			}
   1174   1.1       cgd 
   1175   1.6     lukem 			if (strncmp(s_lab, "#if", 3) == 0) {
   1176   1.6     lukem 				if (blanklines_around_conditional_compilation) {
   1177   1.6     lukem 					int     c;
   1178   1.6     lukem 					prefix_blankline_requested++;
   1179   1.6     lukem 					while ((c = getc(input)) == '\n');
   1180   1.6     lukem 					ungetc(c, input);
   1181   1.6     lukem 				}
   1182   1.6     lukem 				if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
   1183   1.6     lukem 					match_state[ifdef_level].tos = -1;
   1184   1.6     lukem 					state_stack[ifdef_level++] = ps;
   1185   1.6     lukem 				} else
   1186   1.6     lukem 					diag(1, "#if stack overflow");
   1187   1.6     lukem 			} else
   1188  1.10  christos 				if (strncmp(s_lab, "#else", 5) == 0) {
   1189   1.6     lukem 					if (ifdef_level <= 0)
   1190   1.6     lukem 						diag(1, "Unmatched #else");
   1191   1.6     lukem 					else {
   1192   1.6     lukem 						match_state[ifdef_level - 1] = ps;
   1193   1.6     lukem 						ps = state_stack[ifdef_level - 1];
   1194   1.6     lukem 					}
   1195  1.10  christos 				} else
   1196   1.6     lukem 					if (strncmp(s_lab, "#endif", 6) == 0) {
   1197   1.6     lukem 						if (ifdef_level <= 0)
   1198   1.6     lukem 							diag(1, "Unmatched #endif");
   1199   1.6     lukem 						else {
   1200   1.6     lukem 							ifdef_level--;
   1201   1.1       cgd 
   1202   1.1       cgd #ifdef undef
   1203   1.6     lukem 							/*
   1204   1.6     lukem 						         * This match needs to be more intelligent before the
   1205   1.6     lukem 						         * message is useful
   1206   1.6     lukem 						         */
   1207   1.6     lukem 							if (match_state[ifdef_level].tos >= 0
   1208   1.6     lukem 							    && memcmp(&ps, &match_state[ifdef_level], sizeof ps))
   1209   1.6     lukem 								diag(0, "Syntactically inconsistant #ifdef alternatives.");
   1210   1.1       cgd #endif
   1211   1.6     lukem 						}
   1212   1.6     lukem 						if (blanklines_around_conditional_compilation) {
   1213   1.6     lukem 							postfix_blankline_requested++;
   1214   1.6     lukem 							n_real_blanklines = 0;
   1215   1.6     lukem 						}
   1216   1.6     lukem 					}
   1217   1.6     lukem 			break;	/* subsequent processing of the newline
   1218   1.1       cgd 				 * character will cause the line to be printed */
   1219   1.1       cgd 
   1220   1.6     lukem 		case comment:	/* we have gotten a start comment */
   1221   1.6     lukem 			/* this is a biggie */
   1222   1.6     lukem 			if (flushed_nl) {	/* we should force a broken
   1223   1.6     lukem 						 * line here */
   1224   1.6     lukem 				flushed_nl = false;
   1225   1.6     lukem 				dump_line();
   1226   1.6     lukem 				ps.want_blank = false;	/* dont insert blank at
   1227   1.6     lukem 							 * line start */
   1228   1.6     lukem 				force_nl = false;
   1229   1.6     lukem 			}
   1230   1.6     lukem 			pr_comment();
   1231   1.6     lukem 			break;
   1232   1.6     lukem 		}		/* end of big switch stmt */
   1233   1.6     lukem 
   1234   1.6     lukem 		*e_code = '\0';	/* make sure code section is null terminated */
   1235   1.6     lukem 		if (type_code != comment && type_code != newline && type_code != preesc)
   1236   1.6     lukem 			ps.last_token = type_code;
   1237   1.6     lukem 	}			/* end of main while (1) loop */
   1238   1.1       cgd }
   1239   1.1       cgd /*
   1240   1.1       cgd  * copy input file to backup file if in_name is /blah/blah/blah/file, then
   1241   1.1       cgd  * backup file will be ".Bfile" then make the backup file the input and
   1242   1.1       cgd  * original input file the output
   1243   1.1       cgd  */
   1244   1.6     lukem void
   1245  1.13       wiz bakcopy(void)
   1246   1.1       cgd {
   1247   1.6     lukem 	int     n, bakchn;
   1248   1.6     lukem 	char    buff[8 * 1024];
   1249   1.6     lukem 	char   *p;
   1250   1.6     lukem 
   1251   1.6     lukem 	/* construct file name .Bfile */
   1252   1.6     lukem 	for (p = in_name; *p; p++);	/* skip to end of string */
   1253   1.6     lukem 	while (p > in_name && *p != '/')	/* find last '/' */
   1254   1.6     lukem 		p--;
   1255   1.6     lukem 	if (*p == '/')
   1256   1.6     lukem 		p++;
   1257   1.6     lukem 	sprintf(bakfile, "%s.BAK", p);
   1258   1.6     lukem 
   1259   1.6     lukem 	/* copy in_name to backup file */
   1260   1.6     lukem 	bakchn = creat(bakfile, 0600);
   1261   1.6     lukem 	if (bakchn < 0)
   1262   1.6     lukem 		err(1, "%s", bakfile);
   1263   1.6     lukem 	while ((n = read(fileno(input), buff, sizeof buff)) > 0)
   1264   1.6     lukem 		if (write(bakchn, buff, n) != n)
   1265   1.6     lukem 			err(1, "%s", bakfile);
   1266   1.6     lukem 	if (n < 0)
   1267   1.6     lukem 		err(1, "%s", in_name);
   1268   1.6     lukem 	close(bakchn);
   1269   1.6     lukem 	fclose(input);
   1270   1.6     lukem 
   1271   1.6     lukem 	/* re-open backup file as the input file */
   1272   1.6     lukem 	input = fopen(bakfile, "r");
   1273   1.6     lukem 	if (input == 0)
   1274   1.6     lukem 		err(1, "%s", bakfile);
   1275   1.6     lukem 	/* now the original input file will be the output */
   1276   1.6     lukem 	output = fopen(in_name, "w");
   1277   1.6     lukem 	if (output == 0) {
   1278   1.6     lukem 		unlink(bakfile);
   1279   1.6     lukem 		err(1, "%s", in_name);
   1280   1.6     lukem 	}
   1281   1.1       cgd }
   1282