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