4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/param.h>
40 #define MSG_SUFFIX ".msg"
41 #define NEW_SUFFIX ".new"
43 #if !defined(TEXT_DOMAIN)
44 #define TEXT_DOMAIN "genmsg"
50 extern void write_msgfile(char *); /* from util.c */
51 extern int read_projfile(char *); /* from util.c */
52 extern void write_projfile(char *); /* from util.c */
53 extern void read_msgfile(char *); /* from util.c */
54 extern int is_writable(char *); /* from util.c */
55 extern int file_copy(char *, char *); /* from util.c */
56 extern void init_lex(void); /* from genmsg.l */
57 extern void init_linemsgid(void); /* from genmsg.l */
58 extern FILE *yyin
; /* from lex */
59 extern int yyparse(void); /* from genmsg.l */
64 /* File pointer for auto-message-numbering. */
67 /* Input source file. */
70 /* Tag for message comments. */
73 /* Tag for set number comments. */
76 /* Mode mask to define the genmsg tasks. */
77 Mode active_mode
= NoMode
;
80 * This flag will be TRUE if a catgets() call is found
83 int is_cat_found
= FALSE
;
85 /* Suppress an error message if this flag is TRUE. */
86 int suppress_error
= FALSE
;
88 /* Prefix and suffix of messages for testing. */
92 static void usage(void);
93 static void validate_options(void);
96 main(int argc
, char **argv
)
100 char *projfile
= NULL
;
101 char *newprojfile
= NULL
;
102 char *cpppath
= NULL
;
103 int do_msgfile
= FALSE
;
109 program
= basename(argv
[0]);
111 (void) setlocale(LC_ALL
, "");
112 (void) textdomain(TEXT_DOMAIN
);
114 while ((c
= getopt(argc
, argv
, "arndfg:o:l:p:c:s:m:M:txb")) != EOF
) {
117 SetActiveMode(MessageMode
);
121 SetActiveMode(AppendMode
);
125 SetActiveMode(AutoNumMode
);
128 SetActiveMode(ReverseMode
);
132 SetActiveMode(PreProcessMode
);
135 newprojfile
= optarg
;
136 suppress_error
= TRUE
;
137 SetActiveMode(ProjectMode
);
141 SetActiveMode(MsgCommentMode
);
145 SetActiveMode(SetCommentMode
);
148 SetActiveMode(BackCommentMode
);
151 SetActiveMode(LineInfoMode
);
155 SetActiveMode(PrefixMode
);
159 SetActiveMode(SuffixMode
);
162 SetActiveMode(TripleMode
);
165 SetActiveMode(DoubleLineMode
);
168 SetActiveMode(OverwriteMode
);
171 suppress_error
= TRUE
;
172 SetActiveMode(NoErrorMode
);
180 if (optind
>= argc
) {
186 if (IsActiveMode(AutoNumMode
)) {
187 if (read_projfile(projfile
)) {
188 tmp
= basename(projfile
);
189 len
= strlen(tmp
) + sizeof (NEW_SUFFIX
);
190 if ((newprojfile
= malloc(len
)) == NULL
) {
191 prg_err(gettext("fatal: out of memory"));
194 (void) snprintf(newprojfile
, len
, "%s%s",
197 newprojfile
= basename(projfile
);
201 if ((IsActiveMode(AutoNumMode
) || IsActiveMode(ProjectMode
)) &&
202 (is_writable(IsActiveMode(OverwriteMode
) ?
203 projfile
: newprojfile
) == FALSE
)) {
204 prg_err(gettext("cannot write \"%s\": permission denied"),
205 IsActiveMode(OverwriteMode
) ? projfile
: newprojfile
);
209 if (IsActiveMode(AppendMode
) && msgfile
!= NULL
) {
210 read_msgfile(msgfile
);
213 if (msgfile
== NULL
) {
214 tmp
= basename(argv
[optind
]);
215 len
= strlen(tmp
) + sizeof (MSG_SUFFIX
);
216 if ((msgfile
= malloc(len
)) == NULL
) {
217 prg_err(gettext("fatal: out of memory"));
220 (void) snprintf(msgfile
, len
, "%s%s", tmp
, MSG_SUFFIX
);
223 while (optind
< argc
) {
224 is_cat_found
= FALSE
;
225 srcfile
= argv
[optind
];
227 if (IsActiveMode(AutoNumMode
) || IsActiveMode(ReverseMode
)) {
231 if (IsActiveMode(PreProcessMode
)) {
232 len
= strlen(cpppath
) + 1 + strlen(srcfile
) + 1;
233 if ((cmd
= malloc(len
)) == NULL
) {
234 prg_err(gettext("fatal: out of memory"));
237 (void) snprintf(cmd
, len
, "%s %s", cpppath
, srcfile
);
238 if ((yyin
= popen(cmd
, "r")) == NULL
) {
240 gettext("fatal: cannot execute \"%s\""),
246 if ((yyin
= fopen(srcfile
, "r")) == NULL
) {
248 gettext("cannot open \"%s\""), srcfile
);
256 if (IsActiveMode(PreProcessMode
)) {
257 if (pclose(yyin
) != 0) {
258 prg_err(gettext("\"%s\" failed for \"%s\""),
264 if (is_cat_found
== FALSE
) {
265 if (!IsActiveMode(PreProcessMode
)) {
271 if (do_msgfile
== FALSE
) {
275 if (IsActiveMode(AutoNumMode
) || IsActiveMode(ReverseMode
)) {
278 tmp
= basename(srcfile
);
280 if (IsActiveMode(OverwriteMode
)) {
283 len
= strlen(tmp
) + sizeof (NEW_SUFFIX
);
284 if ((newfile
= malloc(len
)) == NULL
) {
286 gettext("fatal: out of memory"));
289 (void) snprintf(newfile
, len
, "%s%s",
293 if (is_writable(newfile
) == FALSE
) {
295 "cannot create \"%s\": permission denied"), newfile
);
299 (void) strlcpy(tmpfile
, "/tmp/gensmg.XXXXXX",
302 if ((tmpfd
= mkstemp(tmpfile
)) == -1) {
304 "cannot create \"%s\""), tmpfile
);
305 if (!IsActiveMode(PreProcessMode
)) {
310 if ((newfp
= fdopen(tmpfd
, "w")) == NULL
) {
312 "cannot create \"%s\""), tmpfile
);
313 if (!IsActiveMode(PreProcessMode
)) {
317 (void) unlink(tmpfile
);
321 if (IsActiveMode(PreProcessMode
)) {
322 if ((yyin
= fopen(srcfile
, "r")) == NULL
) {
324 "cannot open \"%s\""), srcfile
);
325 (void) fclose(newfp
);
326 (void) unlink(tmpfile
);
333 SetActiveMode(ReplaceMode
);
336 ResetActiveMode(ReplaceMode
);
338 (void) fclose(newfp
);
343 (void) file_copy(tmpfile
, newfile
);
345 (void) unlink(tmpfile
);
350 if (!IsActiveMode(PreProcessMode
)) {
358 if (!do_msgfile
) { /* no more business. */
359 return (EXIT_SUCCESS
);
362 if (!IsActiveMode(ReverseMode
) && !IsActiveMode(ProjectMode
)) {
363 write_msgfile(msgfile
);
366 if (IsActiveMode(AutoNumMode
) || IsActiveMode(ProjectMode
)) {
367 write_projfile(IsActiveMode(OverwriteMode
) ?
368 projfile
: newprojfile
);
370 return (EXIT_SUCCESS
);
374 validate_options(void)
376 /* -r doesn't work with either -a or -l. */
377 if (IsActiveMode(ReverseMode
) &&
378 (IsActiveMode(AutoNumMode
) || IsActiveMode(AppendMode
))) {
381 /* -b should be accompanied with -c, -s, -d, and -n. */
382 if (IsActiveMode(BackCommentMode
) &&
383 (!IsActiveMode(MsgCommentMode
) &&
384 !IsActiveMode(SetCommentMode
) &&
385 !IsActiveMode(DoubleLineMode
) &&
386 !IsActiveMode(LineInfoMode
))) {
389 if (IsActiveMode(ProjectMode
) &&
390 (IsActiveMode(AutoNumMode
) || IsActiveMode(ReverseMode
) ||
391 IsActiveMode(AppendMode
) || IsActiveMode(MsgCommentMode
) ||
392 IsActiveMode(LineInfoMode
) || IsActiveMode(OverwriteMode
) ||
393 IsActiveMode(PrefixMode
) || IsActiveMode(SuffixMode
) ||
394 IsActiveMode(TripleMode
) || IsActiveMode(DoubleLineMode
) ||
395 IsActiveMode(MessageMode
) || IsActiveMode(NoErrorMode
))) {
403 (void) fprintf(stderr
, gettext(
404 "Usage: %s [-o message-file] [-a] [-d] [-p preprocessor]\n"
405 " [-s set-tag] [-c message-tag] [-b] [-n]\n"
406 " [-l project-file] [-r] [-f] [-g project-file]\n"
407 " [-m prefix] [-M suffix] [-t] [-x] files ...\n"),