xref: /onnv-gate/usr/src/cmd/genmsg/main.c (revision 4933:4406e11cad66)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*4933Smuffin  * Common Development and Distribution License (the "License").
6*4933Smuffin  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*4933Smuffin  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*4933Smuffin  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <limits.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <libgen.h>
330Sstevel@tonic-gate #include <libintl.h>
340Sstevel@tonic-gate #include <locale.h>
350Sstevel@tonic-gate #include <unistd.h>
360Sstevel@tonic-gate #include <sys/param.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include "genmsg.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #define	MSG_SUFFIX	".msg"
410Sstevel@tonic-gate #define	NEW_SUFFIX	".new"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
440Sstevel@tonic-gate #define	TEXT_DOMAIN	"genmsg"
450Sstevel@tonic-gate #endif
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * External functions.
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate extern void write_msgfile(char *);	/* from util.c */
510Sstevel@tonic-gate extern int read_projfile(char *);	/* from util.c */
520Sstevel@tonic-gate extern void write_projfile(char *);	/* from util.c */
530Sstevel@tonic-gate extern void read_msgfile(char *);	/* from util.c */
540Sstevel@tonic-gate extern int is_writable(char *);		/* from util.c */
550Sstevel@tonic-gate extern int file_copy(char *, char *);	/* from util.c */
560Sstevel@tonic-gate extern void init_lex(void);		/* from genmsg.l */
570Sstevel@tonic-gate extern void init_linemsgid(void);	/* from genmsg.l */
58*4933Smuffin extern FILE *yyin;			/* from lex */
59*4933Smuffin extern int yyparse(void);		/* from genmsg.l */
600Sstevel@tonic-gate 
610Sstevel@tonic-gate /* Program name. */
620Sstevel@tonic-gate char *program;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate /* File pointer for auto-message-numbering. */
650Sstevel@tonic-gate FILE *newfp = NULL;
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /* Input source file. */
680Sstevel@tonic-gate char *srcfile;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /* Tag for message comments. */
710Sstevel@tonic-gate char *mctag = NULL;
720Sstevel@tonic-gate 
730Sstevel@tonic-gate /* Tag for set number comments. */
740Sstevel@tonic-gate char *sctag = NULL;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate /* Mode mask to define the genmsg tasks. */
770Sstevel@tonic-gate Mode active_mode = NoMode;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate  * This flag will be TRUE if a catgets() call is found
810Sstevel@tonic-gate  * in the input file.
820Sstevel@tonic-gate  */
830Sstevel@tonic-gate int is_cat_found = FALSE;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate /* Suppress an error message if this flag is TRUE. */
860Sstevel@tonic-gate int suppress_error = FALSE;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate /* Prefix and suffix of messages for testing. */
890Sstevel@tonic-gate char *premsg = NULL;
900Sstevel@tonic-gate char *sufmsg = NULL;
910Sstevel@tonic-gate 
920Sstevel@tonic-gate static void usage(void);
930Sstevel@tonic-gate static void validate_options(void);
940Sstevel@tonic-gate 
950Sstevel@tonic-gate int
main(int argc,char ** argv)960Sstevel@tonic-gate main(int argc, char **argv)
970Sstevel@tonic-gate {
980Sstevel@tonic-gate 	int c;
990Sstevel@tonic-gate 	char *msgfile = NULL;
1000Sstevel@tonic-gate 	char *projfile = NULL;
1010Sstevel@tonic-gate 	char *newprojfile = NULL;
1020Sstevel@tonic-gate 	char *cpppath = NULL;
1030Sstevel@tonic-gate 	int do_msgfile = FALSE;
1040Sstevel@tonic-gate 	int tmpfd = -1;
105*4933Smuffin 	char	*cmd, *tmp;
106*4933Smuffin 	char	tmpfile[32];
107*4933Smuffin 	size_t	len;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	program = basename(argv[0]);
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1120Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1130Sstevel@tonic-gate 
114*4933Smuffin 	while ((c = getopt(argc, argv, "arndfg:o:l:p:c:s:m:M:txb")) != EOF) {
1150Sstevel@tonic-gate 		switch (c) {
1160Sstevel@tonic-gate 		case 'o':
1170Sstevel@tonic-gate 			SetActiveMode(MessageMode);
1180Sstevel@tonic-gate 			msgfile = optarg;
1190Sstevel@tonic-gate 			break;
1200Sstevel@tonic-gate 		case 'a':
1210Sstevel@tonic-gate 			SetActiveMode(AppendMode);
1220Sstevel@tonic-gate 			break;
1230Sstevel@tonic-gate 		case 'l':
1240Sstevel@tonic-gate 			projfile = optarg;
1250Sstevel@tonic-gate 			SetActiveMode(AutoNumMode);
1260Sstevel@tonic-gate 			break;
1270Sstevel@tonic-gate 		case 'r':
1280Sstevel@tonic-gate 			SetActiveMode(ReverseMode);
1290Sstevel@tonic-gate 			break;
1300Sstevel@tonic-gate 		case 'p':
1310Sstevel@tonic-gate 			cpppath = optarg;
1320Sstevel@tonic-gate 			SetActiveMode(PreProcessMode);
1330Sstevel@tonic-gate 			break;
1340Sstevel@tonic-gate 		case 'g':
1350Sstevel@tonic-gate 			newprojfile = optarg;
1360Sstevel@tonic-gate 			suppress_error = TRUE;
1370Sstevel@tonic-gate 			SetActiveMode(ProjectMode);
1380Sstevel@tonic-gate 			break;
1390Sstevel@tonic-gate 		case 'c':
1400Sstevel@tonic-gate 			mctag = optarg;
1410Sstevel@tonic-gate 			SetActiveMode(MsgCommentMode);
1420Sstevel@tonic-gate 			break;
1430Sstevel@tonic-gate 		case 's':
1440Sstevel@tonic-gate 			sctag = optarg;
1450Sstevel@tonic-gate 			SetActiveMode(SetCommentMode);
1460Sstevel@tonic-gate 			break;
1470Sstevel@tonic-gate 		case 'b':
1480Sstevel@tonic-gate 			SetActiveMode(BackCommentMode);
1490Sstevel@tonic-gate 			break;
1500Sstevel@tonic-gate 		case 'n':
1510Sstevel@tonic-gate 			SetActiveMode(LineInfoMode);
1520Sstevel@tonic-gate 			break;
1530Sstevel@tonic-gate 		case 'm':
1540Sstevel@tonic-gate 			premsg = optarg;
1550Sstevel@tonic-gate 			SetActiveMode(PrefixMode);
1560Sstevel@tonic-gate 			break;
1570Sstevel@tonic-gate 		case 'M':
1580Sstevel@tonic-gate 			sufmsg = optarg;
1590Sstevel@tonic-gate 			SetActiveMode(SuffixMode);
1600Sstevel@tonic-gate 			break;
1610Sstevel@tonic-gate 		case 't':
1620Sstevel@tonic-gate 			SetActiveMode(TripleMode);
1630Sstevel@tonic-gate 			break;
1640Sstevel@tonic-gate 		case 'd':
1650Sstevel@tonic-gate 			SetActiveMode(DoubleLineMode);
1660Sstevel@tonic-gate 			break;
1670Sstevel@tonic-gate 		case 'f':
1680Sstevel@tonic-gate 			SetActiveMode(OverwriteMode);
1690Sstevel@tonic-gate 			break;
1700Sstevel@tonic-gate 		case 'x':
1710Sstevel@tonic-gate 			suppress_error = TRUE;
1720Sstevel@tonic-gate 			SetActiveMode(NoErrorMode);
1730Sstevel@tonic-gate 			break;
1740Sstevel@tonic-gate 		default:
1750Sstevel@tonic-gate 			usage();
1760Sstevel@tonic-gate 			break;
1770Sstevel@tonic-gate 		}
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	if (optind >= argc) {
1810Sstevel@tonic-gate 		usage();
1820Sstevel@tonic-gate 	}
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	validate_options();
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	if (IsActiveMode(AutoNumMode)) {
1870Sstevel@tonic-gate 		if (read_projfile(projfile)) {
1880Sstevel@tonic-gate 			tmp = basename(projfile);
189*4933Smuffin 			len = strlen(tmp) + sizeof (NEW_SUFFIX);
190*4933Smuffin 			if ((newprojfile = malloc(len)) == NULL) {
1910Sstevel@tonic-gate 				prg_err(gettext("fatal: out of memory"));
1920Sstevel@tonic-gate 				exit(EXIT_FAILURE);
1930Sstevel@tonic-gate 			}
194*4933Smuffin 			(void) snprintf(newprojfile, len, "%s%s",
195*4933Smuffin 			    tmp, NEW_SUFFIX);
1960Sstevel@tonic-gate 		} else {
1970Sstevel@tonic-gate 			newprojfile = basename(projfile);
1980Sstevel@tonic-gate 		}
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	if ((IsActiveMode(AutoNumMode) || IsActiveMode(ProjectMode)) &&
202*4933Smuffin 	    (is_writable(IsActiveMode(OverwriteMode) ?
203*4933Smuffin 	    projfile : newprojfile) == FALSE)) {
2040Sstevel@tonic-gate 		prg_err(gettext("cannot write \"%s\": permission denied"),
205*4933Smuffin 		    IsActiveMode(OverwriteMode) ? projfile : newprojfile);
2060Sstevel@tonic-gate 		exit(EXIT_FAILURE);
2070Sstevel@tonic-gate 	}
2080Sstevel@tonic-gate 
209*4933Smuffin 	if (IsActiveMode(AppendMode) && msgfile != NULL) {
2100Sstevel@tonic-gate 		read_msgfile(msgfile);
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 
213*4933Smuffin 	if (msgfile == NULL) {
214*4933Smuffin 		tmp = basename(argv[optind]);
215*4933Smuffin 		len = strlen(tmp) + sizeof (MSG_SUFFIX);
216*4933Smuffin 		if ((msgfile = malloc(len)) == NULL) {
2170Sstevel@tonic-gate 			prg_err(gettext("fatal: out of memory"));
2180Sstevel@tonic-gate 			exit(EXIT_FAILURE);
2190Sstevel@tonic-gate 		}
220*4933Smuffin 		(void) snprintf(msgfile, len, "%s%s", tmp, MSG_SUFFIX);
2210Sstevel@tonic-gate 	}
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	while (optind < argc) {
2240Sstevel@tonic-gate 		is_cat_found = FALSE;
2250Sstevel@tonic-gate 		srcfile = argv[optind];
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 		if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) {
2280Sstevel@tonic-gate 			init_linemsgid();
2290Sstevel@tonic-gate 		}
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 		if (IsActiveMode(PreProcessMode)) {
232*4933Smuffin 			len = strlen(cpppath) + 1 + strlen(srcfile) + 1;
233*4933Smuffin 			if ((cmd = malloc(len)) == NULL) {
234*4933Smuffin 				prg_err(gettext("fatal: out of memory"));
2350Sstevel@tonic-gate 				exit(EXIT_FAILURE);
2360Sstevel@tonic-gate 			}
237*4933Smuffin 			(void) snprintf(cmd, len, "%s %s", cpppath, srcfile);
238*4933Smuffin 			if ((yyin = popen(cmd, "r")) == NULL) {
239*4933Smuffin 				prg_err(
240*4933Smuffin 				    gettext("fatal: cannot execute \"%s\""),
241*4933Smuffin 				    cpppath);
242*4933Smuffin 				exit(EXIT_FAILURE);
243*4933Smuffin 			}
244*4933Smuffin 			free(cmd);
2450Sstevel@tonic-gate 		} else {
2460Sstevel@tonic-gate 			if ((yyin = fopen(srcfile, "r")) == NULL) {
247*4933Smuffin 				prg_err(
248*4933Smuffin 				    gettext("cannot open \"%s\""), srcfile);
2490Sstevel@tonic-gate 				goto end;
2500Sstevel@tonic-gate 			}
2510Sstevel@tonic-gate 		}
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 		init_lex();
254*4933Smuffin 		(void) yyparse();
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 		if (IsActiveMode(PreProcessMode)) {
2570Sstevel@tonic-gate 			if (pclose(yyin) != 0) {
2580Sstevel@tonic-gate 				prg_err(gettext("\"%s\" failed for \"%s\""),
259*4933Smuffin 				    cpppath, srcfile);
2600Sstevel@tonic-gate 				goto end;
2610Sstevel@tonic-gate 			}
2620Sstevel@tonic-gate 		}
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 		if (is_cat_found == FALSE) {
2650Sstevel@tonic-gate 			if (!IsActiveMode(PreProcessMode)) {
2660Sstevel@tonic-gate 				(void) fclose(yyin);
2670Sstevel@tonic-gate 			}
2680Sstevel@tonic-gate 			goto end;
2690Sstevel@tonic-gate 		}
2700Sstevel@tonic-gate 
271*4933Smuffin 		if (do_msgfile == FALSE) {
2720Sstevel@tonic-gate 			do_msgfile = TRUE;
2730Sstevel@tonic-gate 		}
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 		if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) {
276*4933Smuffin 			char	*newfile;
277*4933Smuffin 
278*4933Smuffin 			tmp = basename(srcfile);
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 			if (IsActiveMode(OverwriteMode)) {
281*4933Smuffin 				newfile = srcfile;
2820Sstevel@tonic-gate 			} else {
283*4933Smuffin 				len = strlen(tmp) + sizeof (NEW_SUFFIX);
284*4933Smuffin 				if ((newfile = malloc(len)) == NULL) {
285*4933Smuffin 					prg_err(
286*4933Smuffin 					    gettext("fatal: out of memory"));
287*4933Smuffin 					exit(EXIT_FAILURE);
288*4933Smuffin 				}
289*4933Smuffin 				(void) snprintf(newfile, len, "%s%s",
290*4933Smuffin 				    tmp, NEW_SUFFIX);
2910Sstevel@tonic-gate 			}
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 			if (is_writable(newfile) == FALSE) {
294*4933Smuffin 				prg_err(gettext(
295*4933Smuffin 			"cannot create \"%s\": permission denied"), newfile);
2960Sstevel@tonic-gate 				goto end;
2970Sstevel@tonic-gate 			}
2980Sstevel@tonic-gate 
299*4933Smuffin 			(void) strlcpy(tmpfile, "/tmp/gensmg.XXXXXX",
300*4933Smuffin 			    sizeof (tmpfile));
301*4933Smuffin 
3020Sstevel@tonic-gate 			if ((tmpfd = mkstemp(tmpfile)) == -1) {
303*4933Smuffin 				prg_err(gettext(
304*4933Smuffin 			"cannot create \"%s\""), tmpfile);
3050Sstevel@tonic-gate 				if (!IsActiveMode(PreProcessMode)) {
3060Sstevel@tonic-gate 					(void) fclose(yyin);
3070Sstevel@tonic-gate 				}
308*4933Smuffin 				goto end;
3090Sstevel@tonic-gate 			}
310*4933Smuffin 			if ((newfp = fdopen(tmpfd, "w")) == NULL) {
311*4933Smuffin 				prg_err(gettext(
312*4933Smuffin 			"cannot create \"%s\""), tmpfile);
3130Sstevel@tonic-gate 				if (!IsActiveMode(PreProcessMode)) {
3140Sstevel@tonic-gate 					(void) fclose(yyin);
3150Sstevel@tonic-gate 				}
316*4933Smuffin 				(void) close(tmpfd);
3170Sstevel@tonic-gate 				(void) unlink(tmpfile);
3180Sstevel@tonic-gate 				goto end;
3190Sstevel@tonic-gate 			}
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate 			if (IsActiveMode(PreProcessMode)) {
3220Sstevel@tonic-gate 				if ((yyin = fopen(srcfile, "r")) == NULL) {
323*4933Smuffin 					prg_err(gettext(
324*4933Smuffin 			"cannot open \"%s\""), srcfile);
325*4933Smuffin 					(void) fclose(newfp);
3260Sstevel@tonic-gate 					(void) unlink(tmpfile);
3270Sstevel@tonic-gate 					goto end;
3280Sstevel@tonic-gate 				}
3290Sstevel@tonic-gate 			} else {
3300Sstevel@tonic-gate 				rewind(yyin);
3310Sstevel@tonic-gate 			}
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate 			SetActiveMode(ReplaceMode);
3340Sstevel@tonic-gate 			init_lex();
335*4933Smuffin 			(void) yyparse();
3360Sstevel@tonic-gate 			ResetActiveMode(ReplaceMode);
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate 			(void) fclose(newfp);
3390Sstevel@tonic-gate 			newfp = NULL;
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 			(void) fclose(yyin);
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 			(void) file_copy(tmpfile, newfile);
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 			(void) unlink(tmpfile);
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 			goto end;
3480Sstevel@tonic-gate 		}
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 		if (!IsActiveMode(PreProcessMode)) {
3510Sstevel@tonic-gate 			(void) fclose(yyin);
3520Sstevel@tonic-gate 		}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate end:
3550Sstevel@tonic-gate 		optind++;
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	if (!do_msgfile) { /* no more business. */
3590Sstevel@tonic-gate 		return (EXIT_SUCCESS);
3600Sstevel@tonic-gate 	}
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	if (!IsActiveMode(ReverseMode) && !IsActiveMode(ProjectMode)) {
3630Sstevel@tonic-gate 		write_msgfile(msgfile);
3640Sstevel@tonic-gate 	}
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	if (IsActiveMode(AutoNumMode) || IsActiveMode(ProjectMode)) {
3670Sstevel@tonic-gate 		write_projfile(IsActiveMode(OverwriteMode) ?
368*4933Smuffin 		    projfile : newprojfile);
3690Sstevel@tonic-gate 	}
3700Sstevel@tonic-gate 	return (EXIT_SUCCESS);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate static void
validate_options(void)3740Sstevel@tonic-gate validate_options(void)
3750Sstevel@tonic-gate {
3760Sstevel@tonic-gate 	/* -r doesn't work with either -a or -l. */
3770Sstevel@tonic-gate 	if (IsActiveMode(ReverseMode) &&
378*4933Smuffin 	    (IsActiveMode(AutoNumMode) || IsActiveMode(AppendMode))) {
3790Sstevel@tonic-gate 		usage();
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate 	/* -b should be accompanied with -c, -s, -d, and -n. */
3820Sstevel@tonic-gate 	if (IsActiveMode(BackCommentMode) &&
383*4933Smuffin 	    (!IsActiveMode(MsgCommentMode) &&
384*4933Smuffin 	    !IsActiveMode(SetCommentMode) &&
385*4933Smuffin 	    !IsActiveMode(DoubleLineMode) &&
386*4933Smuffin 	    !IsActiveMode(LineInfoMode))) {
3870Sstevel@tonic-gate 		usage();
3880Sstevel@tonic-gate 	}
3890Sstevel@tonic-gate 	if (IsActiveMode(ProjectMode) &&
390*4933Smuffin 	    (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode) ||
391*4933Smuffin 	    IsActiveMode(AppendMode) || IsActiveMode(MsgCommentMode) ||
392*4933Smuffin 	    IsActiveMode(LineInfoMode) || IsActiveMode(OverwriteMode) ||
393*4933Smuffin 	    IsActiveMode(PrefixMode) || IsActiveMode(SuffixMode) ||
394*4933Smuffin 	    IsActiveMode(TripleMode) || IsActiveMode(DoubleLineMode) ||
395*4933Smuffin 	    IsActiveMode(MessageMode) || IsActiveMode(NoErrorMode))) {
3960Sstevel@tonic-gate 		usage();
3970Sstevel@tonic-gate 	}
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate static void
usage(void)4010Sstevel@tonic-gate usage(void)
4020Sstevel@tonic-gate {
403*4933Smuffin 	(void) fprintf(stderr, gettext(
404*4933Smuffin 	    "Usage: %s [-o message-file] [-a] [-d] [-p preprocessor]\n"
405*4933Smuffin 	    "          [-s set-tag] [-c message-tag] [-b] [-n]\n"
406*4933Smuffin 	    "          [-l project-file] [-r] [-f] [-g project-file]\n"
407*4933Smuffin 	    "          [-m prefix] [-M suffix] [-t] [-x] files ...\n"),
408*4933Smuffin 	    program);
4090Sstevel@tonic-gate 	exit(EXIT_FAILURE);
4100Sstevel@tonic-gate }
411