xref: /titanic_44/usr/src/cmd/genmsg/main.c (revision 6e54a631bc06b2a4f5919eb8d582d52780e17983)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*6e54a631Smuffin  * Common Development and Distribution License (the "License").
6*6e54a631Smuffin  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*6e54a631Smuffin  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*6e54a631Smuffin  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <limits.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <libgen.h>
337c478bd9Sstevel@tonic-gate #include <libintl.h>
347c478bd9Sstevel@tonic-gate #include <locale.h>
357c478bd9Sstevel@tonic-gate #include <unistd.h>
367c478bd9Sstevel@tonic-gate #include <sys/param.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include "genmsg.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #define	MSG_SUFFIX	".msg"
417c478bd9Sstevel@tonic-gate #define	NEW_SUFFIX	".new"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
447c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"genmsg"
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * External functions.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate extern void write_msgfile(char *);	/* from util.c */
517c478bd9Sstevel@tonic-gate extern int read_projfile(char *);	/* from util.c */
527c478bd9Sstevel@tonic-gate extern void write_projfile(char *);	/* from util.c */
537c478bd9Sstevel@tonic-gate extern void read_msgfile(char *);	/* from util.c */
547c478bd9Sstevel@tonic-gate extern int is_writable(char *);		/* from util.c */
557c478bd9Sstevel@tonic-gate extern int file_copy(char *, char *);	/* from util.c */
567c478bd9Sstevel@tonic-gate extern void init_lex(void);		/* from genmsg.l */
577c478bd9Sstevel@tonic-gate extern void init_linemsgid(void);	/* from genmsg.l */
58*6e54a631Smuffin extern FILE *yyin;			/* from lex */
59*6e54a631Smuffin extern int yyparse(void);		/* from genmsg.l */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate /* Program name. */
627c478bd9Sstevel@tonic-gate char *program;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate /* File pointer for auto-message-numbering. */
657c478bd9Sstevel@tonic-gate FILE *newfp = NULL;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /* Input source file. */
687c478bd9Sstevel@tonic-gate char *srcfile;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /* Tag for message comments. */
717c478bd9Sstevel@tonic-gate char *mctag = NULL;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /* Tag for set number comments. */
747c478bd9Sstevel@tonic-gate char *sctag = NULL;
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate /* Mode mask to define the genmsg tasks. */
777c478bd9Sstevel@tonic-gate Mode active_mode = NoMode;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * This flag will be TRUE if a catgets() call is found
817c478bd9Sstevel@tonic-gate  * in the input file.
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate int is_cat_found = FALSE;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /* Suppress an error message if this flag is TRUE. */
867c478bd9Sstevel@tonic-gate int suppress_error = FALSE;
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /* Prefix and suffix of messages for testing. */
897c478bd9Sstevel@tonic-gate char *premsg = NULL;
907c478bd9Sstevel@tonic-gate char *sufmsg = NULL;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate static void usage(void);
937c478bd9Sstevel@tonic-gate static void validate_options(void);
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)967c478bd9Sstevel@tonic-gate main(int argc, char **argv)
977c478bd9Sstevel@tonic-gate {
987c478bd9Sstevel@tonic-gate 	int c;
997c478bd9Sstevel@tonic-gate 	char *msgfile = NULL;
1007c478bd9Sstevel@tonic-gate 	char *projfile = NULL;
1017c478bd9Sstevel@tonic-gate 	char *newprojfile = NULL;
1027c478bd9Sstevel@tonic-gate 	char *cpppath = NULL;
1037c478bd9Sstevel@tonic-gate 	int do_msgfile = FALSE;
1047c478bd9Sstevel@tonic-gate 	int tmpfd = -1;
105*6e54a631Smuffin 	char	*cmd, *tmp;
106*6e54a631Smuffin 	char	tmpfile[32];
107*6e54a631Smuffin 	size_t	len;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	program = basename(argv[0]);
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1127c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1137c478bd9Sstevel@tonic-gate 
114*6e54a631Smuffin 	while ((c = getopt(argc, argv, "arndfg:o:l:p:c:s:m:M:txb")) != EOF) {
1157c478bd9Sstevel@tonic-gate 		switch (c) {
1167c478bd9Sstevel@tonic-gate 		case 'o':
1177c478bd9Sstevel@tonic-gate 			SetActiveMode(MessageMode);
1187c478bd9Sstevel@tonic-gate 			msgfile = optarg;
1197c478bd9Sstevel@tonic-gate 			break;
1207c478bd9Sstevel@tonic-gate 		case 'a':
1217c478bd9Sstevel@tonic-gate 			SetActiveMode(AppendMode);
1227c478bd9Sstevel@tonic-gate 			break;
1237c478bd9Sstevel@tonic-gate 		case 'l':
1247c478bd9Sstevel@tonic-gate 			projfile = optarg;
1257c478bd9Sstevel@tonic-gate 			SetActiveMode(AutoNumMode);
1267c478bd9Sstevel@tonic-gate 			break;
1277c478bd9Sstevel@tonic-gate 		case 'r':
1287c478bd9Sstevel@tonic-gate 			SetActiveMode(ReverseMode);
1297c478bd9Sstevel@tonic-gate 			break;
1307c478bd9Sstevel@tonic-gate 		case 'p':
1317c478bd9Sstevel@tonic-gate 			cpppath = optarg;
1327c478bd9Sstevel@tonic-gate 			SetActiveMode(PreProcessMode);
1337c478bd9Sstevel@tonic-gate 			break;
1347c478bd9Sstevel@tonic-gate 		case 'g':
1357c478bd9Sstevel@tonic-gate 			newprojfile = optarg;
1367c478bd9Sstevel@tonic-gate 			suppress_error = TRUE;
1377c478bd9Sstevel@tonic-gate 			SetActiveMode(ProjectMode);
1387c478bd9Sstevel@tonic-gate 			break;
1397c478bd9Sstevel@tonic-gate 		case 'c':
1407c478bd9Sstevel@tonic-gate 			mctag = optarg;
1417c478bd9Sstevel@tonic-gate 			SetActiveMode(MsgCommentMode);
1427c478bd9Sstevel@tonic-gate 			break;
1437c478bd9Sstevel@tonic-gate 		case 's':
1447c478bd9Sstevel@tonic-gate 			sctag = optarg;
1457c478bd9Sstevel@tonic-gate 			SetActiveMode(SetCommentMode);
1467c478bd9Sstevel@tonic-gate 			break;
1477c478bd9Sstevel@tonic-gate 		case 'b':
1487c478bd9Sstevel@tonic-gate 			SetActiveMode(BackCommentMode);
1497c478bd9Sstevel@tonic-gate 			break;
1507c478bd9Sstevel@tonic-gate 		case 'n':
1517c478bd9Sstevel@tonic-gate 			SetActiveMode(LineInfoMode);
1527c478bd9Sstevel@tonic-gate 			break;
1537c478bd9Sstevel@tonic-gate 		case 'm':
1547c478bd9Sstevel@tonic-gate 			premsg = optarg;
1557c478bd9Sstevel@tonic-gate 			SetActiveMode(PrefixMode);
1567c478bd9Sstevel@tonic-gate 			break;
1577c478bd9Sstevel@tonic-gate 		case 'M':
1587c478bd9Sstevel@tonic-gate 			sufmsg = optarg;
1597c478bd9Sstevel@tonic-gate 			SetActiveMode(SuffixMode);
1607c478bd9Sstevel@tonic-gate 			break;
1617c478bd9Sstevel@tonic-gate 		case 't':
1627c478bd9Sstevel@tonic-gate 			SetActiveMode(TripleMode);
1637c478bd9Sstevel@tonic-gate 			break;
1647c478bd9Sstevel@tonic-gate 		case 'd':
1657c478bd9Sstevel@tonic-gate 			SetActiveMode(DoubleLineMode);
1667c478bd9Sstevel@tonic-gate 			break;
1677c478bd9Sstevel@tonic-gate 		case 'f':
1687c478bd9Sstevel@tonic-gate 			SetActiveMode(OverwriteMode);
1697c478bd9Sstevel@tonic-gate 			break;
1707c478bd9Sstevel@tonic-gate 		case 'x':
1717c478bd9Sstevel@tonic-gate 			suppress_error = TRUE;
1727c478bd9Sstevel@tonic-gate 			SetActiveMode(NoErrorMode);
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 		default:
1757c478bd9Sstevel@tonic-gate 			usage();
1767c478bd9Sstevel@tonic-gate 			break;
1777c478bd9Sstevel@tonic-gate 		}
1787c478bd9Sstevel@tonic-gate 	}
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	if (optind >= argc) {
1817c478bd9Sstevel@tonic-gate 		usage();
1827c478bd9Sstevel@tonic-gate 	}
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	validate_options();
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	if (IsActiveMode(AutoNumMode)) {
1877c478bd9Sstevel@tonic-gate 		if (read_projfile(projfile)) {
1887c478bd9Sstevel@tonic-gate 			tmp = basename(projfile);
189*6e54a631Smuffin 			len = strlen(tmp) + sizeof (NEW_SUFFIX);
190*6e54a631Smuffin 			if ((newprojfile = malloc(len)) == NULL) {
1917c478bd9Sstevel@tonic-gate 				prg_err(gettext("fatal: out of memory"));
1927c478bd9Sstevel@tonic-gate 				exit(EXIT_FAILURE);
1937c478bd9Sstevel@tonic-gate 			}
194*6e54a631Smuffin 			(void) snprintf(newprojfile, len, "%s%s",
195*6e54a631Smuffin 			    tmp, NEW_SUFFIX);
1967c478bd9Sstevel@tonic-gate 		} else {
1977c478bd9Sstevel@tonic-gate 			newprojfile = basename(projfile);
1987c478bd9Sstevel@tonic-gate 		}
1997c478bd9Sstevel@tonic-gate 	}
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	if ((IsActiveMode(AutoNumMode) || IsActiveMode(ProjectMode)) &&
2027c478bd9Sstevel@tonic-gate 	    (is_writable(IsActiveMode(OverwriteMode) ?
2037c478bd9Sstevel@tonic-gate 	    projfile : newprojfile) == FALSE)) {
2047c478bd9Sstevel@tonic-gate 		prg_err(gettext("cannot write \"%s\": permission denied"),
2057c478bd9Sstevel@tonic-gate 		    IsActiveMode(OverwriteMode) ? projfile : newprojfile);
2067c478bd9Sstevel@tonic-gate 		exit(EXIT_FAILURE);
2077c478bd9Sstevel@tonic-gate 	}
2087c478bd9Sstevel@tonic-gate 
209*6e54a631Smuffin 	if (IsActiveMode(AppendMode) && msgfile != NULL) {
2107c478bd9Sstevel@tonic-gate 		read_msgfile(msgfile);
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 
213*6e54a631Smuffin 	if (msgfile == NULL) {
214*6e54a631Smuffin 		tmp = basename(argv[optind]);
215*6e54a631Smuffin 		len = strlen(tmp) + sizeof (MSG_SUFFIX);
216*6e54a631Smuffin 		if ((msgfile = malloc(len)) == NULL) {
2177c478bd9Sstevel@tonic-gate 			prg_err(gettext("fatal: out of memory"));
2187c478bd9Sstevel@tonic-gate 			exit(EXIT_FAILURE);
2197c478bd9Sstevel@tonic-gate 		}
220*6e54a631Smuffin 		(void) snprintf(msgfile, len, "%s%s", tmp, MSG_SUFFIX);
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	while (optind < argc) {
2247c478bd9Sstevel@tonic-gate 		is_cat_found = FALSE;
2257c478bd9Sstevel@tonic-gate 		srcfile = argv[optind];
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 		if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) {
2287c478bd9Sstevel@tonic-gate 			init_linemsgid();
2297c478bd9Sstevel@tonic-gate 		}
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 		if (IsActiveMode(PreProcessMode)) {
232*6e54a631Smuffin 			len = strlen(cpppath) + 1 + strlen(srcfile) + 1;
233*6e54a631Smuffin 			if ((cmd = malloc(len)) == NULL) {
234*6e54a631Smuffin 				prg_err(gettext("fatal: out of memory"));
235*6e54a631Smuffin 				exit(EXIT_FAILURE);
236*6e54a631Smuffin 			}
237*6e54a631Smuffin 			(void) snprintf(cmd, len, "%s %s", cpppath, srcfile);
238*6e54a631Smuffin 			if ((yyin = popen(cmd, "r")) == NULL) {
2397c478bd9Sstevel@tonic-gate 				prg_err(
2407c478bd9Sstevel@tonic-gate 				    gettext("fatal: cannot execute \"%s\""),
2417c478bd9Sstevel@tonic-gate 				    cpppath);
2427c478bd9Sstevel@tonic-gate 				exit(EXIT_FAILURE);
2437c478bd9Sstevel@tonic-gate 			}
244*6e54a631Smuffin 			free(cmd);
2457c478bd9Sstevel@tonic-gate 		} else {
2467c478bd9Sstevel@tonic-gate 			if ((yyin = fopen(srcfile, "r")) == NULL) {
247*6e54a631Smuffin 				prg_err(
2487c478bd9Sstevel@tonic-gate 				    gettext("cannot open \"%s\""), srcfile);
2497c478bd9Sstevel@tonic-gate 				goto end;
2507c478bd9Sstevel@tonic-gate 			}
2517c478bd9Sstevel@tonic-gate 		}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 		init_lex();
254*6e54a631Smuffin 		(void) yyparse();
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 		if (IsActiveMode(PreProcessMode)) {
2577c478bd9Sstevel@tonic-gate 			if (pclose(yyin) != 0) {
2587c478bd9Sstevel@tonic-gate 				prg_err(gettext("\"%s\" failed for \"%s\""),
2597c478bd9Sstevel@tonic-gate 				    cpppath, srcfile);
2607c478bd9Sstevel@tonic-gate 				goto end;
2617c478bd9Sstevel@tonic-gate 			}
2627c478bd9Sstevel@tonic-gate 		}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 		if (is_cat_found == FALSE) {
2657c478bd9Sstevel@tonic-gate 			if (!IsActiveMode(PreProcessMode)) {
2667c478bd9Sstevel@tonic-gate 				(void) fclose(yyin);
2677c478bd9Sstevel@tonic-gate 			}
2687c478bd9Sstevel@tonic-gate 			goto end;
2697c478bd9Sstevel@tonic-gate 		}
2707c478bd9Sstevel@tonic-gate 
271*6e54a631Smuffin 		if (do_msgfile == FALSE) {
2727c478bd9Sstevel@tonic-gate 			do_msgfile = TRUE;
2737c478bd9Sstevel@tonic-gate 		}
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 		if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) {
276*6e54a631Smuffin 			char	*newfile;
277*6e54a631Smuffin 
278*6e54a631Smuffin 			tmp = basename(srcfile);
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 			if (IsActiveMode(OverwriteMode)) {
281*6e54a631Smuffin 				newfile = srcfile;
2827c478bd9Sstevel@tonic-gate 			} else {
283*6e54a631Smuffin 				len = strlen(tmp) + sizeof (NEW_SUFFIX);
284*6e54a631Smuffin 				if ((newfile = malloc(len)) == NULL) {
285*6e54a631Smuffin 					prg_err(
286*6e54a631Smuffin 					    gettext("fatal: out of memory"));
287*6e54a631Smuffin 					exit(EXIT_FAILURE);
288*6e54a631Smuffin 				}
289*6e54a631Smuffin 				(void) snprintf(newfile, len, "%s%s",
2907c478bd9Sstevel@tonic-gate 				    tmp, NEW_SUFFIX);
2917c478bd9Sstevel@tonic-gate 			}
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 			if (is_writable(newfile) == FALSE) {
294*6e54a631Smuffin 				prg_err(gettext(
295*6e54a631Smuffin 			"cannot create \"%s\": permission denied"), newfile);
2967c478bd9Sstevel@tonic-gate 				goto end;
2977c478bd9Sstevel@tonic-gate 			}
2987c478bd9Sstevel@tonic-gate 
299*6e54a631Smuffin 			(void) strlcpy(tmpfile, "/tmp/gensmg.XXXXXX",
300*6e54a631Smuffin 			    sizeof (tmpfile));
301*6e54a631Smuffin 
3027c478bd9Sstevel@tonic-gate 			if ((tmpfd = mkstemp(tmpfile)) == -1) {
303*6e54a631Smuffin 				prg_err(gettext(
304*6e54a631Smuffin 			"cannot create \"%s\""), tmpfile);
3057c478bd9Sstevel@tonic-gate 				if (!IsActiveMode(PreProcessMode)) {
3067c478bd9Sstevel@tonic-gate 					(void) fclose(yyin);
3077c478bd9Sstevel@tonic-gate 				}
3087c478bd9Sstevel@tonic-gate 				goto end;
3097c478bd9Sstevel@tonic-gate 			}
310*6e54a631Smuffin 			if ((newfp = fdopen(tmpfd, "w")) == NULL) {
311*6e54a631Smuffin 				prg_err(gettext(
312*6e54a631Smuffin 			"cannot create \"%s\""), tmpfile);
3137c478bd9Sstevel@tonic-gate 				if (!IsActiveMode(PreProcessMode)) {
3147c478bd9Sstevel@tonic-gate 					(void) fclose(yyin);
3157c478bd9Sstevel@tonic-gate 				}
316*6e54a631Smuffin 				(void) close(tmpfd);
3177c478bd9Sstevel@tonic-gate 				(void) unlink(tmpfile);
3187c478bd9Sstevel@tonic-gate 				goto end;
3197c478bd9Sstevel@tonic-gate 			}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 			if (IsActiveMode(PreProcessMode)) {
3227c478bd9Sstevel@tonic-gate 				if ((yyin = fopen(srcfile, "r")) == NULL) {
323*6e54a631Smuffin 					prg_err(gettext(
324*6e54a631Smuffin 			"cannot open \"%s\""), srcfile);
325*6e54a631Smuffin 					(void) fclose(newfp);
3267c478bd9Sstevel@tonic-gate 					(void) unlink(tmpfile);
3277c478bd9Sstevel@tonic-gate 					goto end;
3287c478bd9Sstevel@tonic-gate 				}
3297c478bd9Sstevel@tonic-gate 			} else {
3307c478bd9Sstevel@tonic-gate 				rewind(yyin);
3317c478bd9Sstevel@tonic-gate 			}
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 			SetActiveMode(ReplaceMode);
3347c478bd9Sstevel@tonic-gate 			init_lex();
335*6e54a631Smuffin 			(void) yyparse();
3367c478bd9Sstevel@tonic-gate 			ResetActiveMode(ReplaceMode);
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 			(void) fclose(newfp);
3397c478bd9Sstevel@tonic-gate 			newfp = NULL;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 			(void) fclose(yyin);
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 			(void) file_copy(tmpfile, newfile);
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 			(void) unlink(tmpfile);
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 			goto end;
3487c478bd9Sstevel@tonic-gate 		}
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 		if (!IsActiveMode(PreProcessMode)) {
3517c478bd9Sstevel@tonic-gate 			(void) fclose(yyin);
3527c478bd9Sstevel@tonic-gate 		}
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate end:
3557c478bd9Sstevel@tonic-gate 		optind++;
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	if (!do_msgfile) { /* no more business. */
3597c478bd9Sstevel@tonic-gate 		return (EXIT_SUCCESS);
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	if (!IsActiveMode(ReverseMode) && !IsActiveMode(ProjectMode)) {
3637c478bd9Sstevel@tonic-gate 		write_msgfile(msgfile);
3647c478bd9Sstevel@tonic-gate 	}
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 	if (IsActiveMode(AutoNumMode) || IsActiveMode(ProjectMode)) {
3677c478bd9Sstevel@tonic-gate 		write_projfile(IsActiveMode(OverwriteMode) ?
3687c478bd9Sstevel@tonic-gate 		    projfile : newprojfile);
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 	return (EXIT_SUCCESS);
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate static void
validate_options(void)3747c478bd9Sstevel@tonic-gate validate_options(void)
3757c478bd9Sstevel@tonic-gate {
3767c478bd9Sstevel@tonic-gate 	/* -r doesn't work with either -a or -l. */
3777c478bd9Sstevel@tonic-gate 	if (IsActiveMode(ReverseMode) &&
3787c478bd9Sstevel@tonic-gate 	    (IsActiveMode(AutoNumMode) || IsActiveMode(AppendMode))) {
3797c478bd9Sstevel@tonic-gate 		usage();
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 	/* -b should be accompanied with -c, -s, -d, and -n. */
3827c478bd9Sstevel@tonic-gate 	if (IsActiveMode(BackCommentMode) &&
3837c478bd9Sstevel@tonic-gate 	    (!IsActiveMode(MsgCommentMode) &&
3847c478bd9Sstevel@tonic-gate 	    !IsActiveMode(SetCommentMode) &&
3857c478bd9Sstevel@tonic-gate 	    !IsActiveMode(DoubleLineMode) &&
3867c478bd9Sstevel@tonic-gate 	    !IsActiveMode(LineInfoMode))) {
3877c478bd9Sstevel@tonic-gate 		usage();
3887c478bd9Sstevel@tonic-gate 	}
3897c478bd9Sstevel@tonic-gate 	if (IsActiveMode(ProjectMode) &&
3907c478bd9Sstevel@tonic-gate 	    (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode) ||
3917c478bd9Sstevel@tonic-gate 	    IsActiveMode(AppendMode) || IsActiveMode(MsgCommentMode) ||
3927c478bd9Sstevel@tonic-gate 	    IsActiveMode(LineInfoMode) || IsActiveMode(OverwriteMode) ||
3937c478bd9Sstevel@tonic-gate 	    IsActiveMode(PrefixMode) || IsActiveMode(SuffixMode) ||
3947c478bd9Sstevel@tonic-gate 	    IsActiveMode(TripleMode) || IsActiveMode(DoubleLineMode) ||
3957c478bd9Sstevel@tonic-gate 	    IsActiveMode(MessageMode) || IsActiveMode(NoErrorMode))) {
3967c478bd9Sstevel@tonic-gate 		usage();
3977c478bd9Sstevel@tonic-gate 	}
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate static void
usage(void)4017c478bd9Sstevel@tonic-gate usage(void)
4027c478bd9Sstevel@tonic-gate {
403*6e54a631Smuffin 	(void) fprintf(stderr, gettext(
404*6e54a631Smuffin 	    "Usage: %s [-o message-file] [-a] [-d] [-p preprocessor]\n"
4057c478bd9Sstevel@tonic-gate 	    "          [-s set-tag] [-c message-tag] [-b] [-n]\n"
4067c478bd9Sstevel@tonic-gate 	    "          [-l project-file] [-r] [-f] [-g project-file]\n"
4077c478bd9Sstevel@tonic-gate 	    "          [-m prefix] [-M suffix] [-t] [-x] files ...\n"),
4087c478bd9Sstevel@tonic-gate 	    program);
4097c478bd9Sstevel@tonic-gate 	exit(EXIT_FAILURE);
4107c478bd9Sstevel@tonic-gate }
411