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