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