Mercurial > illumos > onarm
annotate usr/src/cmd/genmsg/main.c @ 13:f60a82e85167 default tip
Revert NEC's changes to fix krb5 build
author | Andrew Stormont <andyjstormont@gmail.com> |
---|---|
date | Fri, 02 Mar 2012 22:25:26 +0000 |
parents | 1a15d5aaf794 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
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. | |
7 * | |
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. | |
12 * | |
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] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
21 /* | |
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
23 * Use is subject to license terms. | |
24 */ | |
25 | |
4
1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
Koji Uno <koji.uno@sun.com>
parents:
0
diff
changeset
|
26 #pragma ident "%Z%%M% %I% %E% SMI" |
0 | 27 |
28 #include <stdio.h> | |
29 #include <limits.h> | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 #include <libgen.h> | |
33 #include <libintl.h> | |
34 #include <locale.h> | |
35 #include <unistd.h> | |
36 #include <sys/param.h> | |
37 | |
38 #include "genmsg.h" | |
39 | |
40 #define MSG_SUFFIX ".msg" | |
41 #define NEW_SUFFIX ".new" | |
42 | |
43 #if !defined(TEXT_DOMAIN) | |
44 #define TEXT_DOMAIN "genmsg" | |
45 #endif | |
46 | |
47 /* | |
48 * External functions. | |
49 */ | |
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 */ | |
60 | |
61 /* Program name. */ | |
62 char *program; | |
63 | |
64 /* File pointer for auto-message-numbering. */ | |
65 FILE *newfp = NULL; | |
66 | |
67 /* Input source file. */ | |
68 char *srcfile; | |
69 | |
70 /* Tag for message comments. */ | |
71 char *mctag = NULL; | |
72 | |
73 /* Tag for set number comments. */ | |
74 char *sctag = NULL; | |
75 | |
76 /* Mode mask to define the genmsg tasks. */ | |
77 Mode active_mode = NoMode; | |
78 | |
79 /* | |
80 * This flag will be TRUE if a catgets() call is found | |
81 * in the input file. | |
82 */ | |
83 int is_cat_found = FALSE; | |
84 | |
85 /* Suppress an error message if this flag is TRUE. */ | |
86 int suppress_error = FALSE; | |
87 | |
88 /* Prefix and suffix of messages for testing. */ | |
89 char *premsg = NULL; | |
90 char *sufmsg = NULL; | |
91 | |
92 static void usage(void); | |
93 static void validate_options(void); | |
94 | |
95 int | |
96 main(int argc, char **argv) | |
97 { | |
98 int c; | |
99 char *msgfile = NULL; | |
100 char *projfile = NULL; | |
101 char *newprojfile = NULL; | |
102 char *cpppath = NULL; | |
103 int do_msgfile = FALSE; | |
104 int tmpfd = -1; | |
105 char *cmd, *tmp; | |
106 char tmpfile[32]; | |
107 size_t len; | |
108 | |
109 program = basename(argv[0]); | |
110 | |
111 (void) setlocale(LC_ALL, ""); | |
112 (void) textdomain(TEXT_DOMAIN); | |
113 | |
114 while ((c = getopt(argc, argv, "arndfg:o:l:p:c:s:m:M:txb")) != EOF) { | |
115 switch (c) { | |
116 case 'o': | |
117 SetActiveMode(MessageMode); | |
118 msgfile = optarg; | |
119 break; | |
120 case 'a': | |
121 SetActiveMode(AppendMode); | |
122 break; | |
123 case 'l': | |
124 projfile = optarg; | |
125 SetActiveMode(AutoNumMode); | |
126 break; | |
127 case 'r': | |
128 SetActiveMode(ReverseMode); | |
129 break; | |
130 case 'p': | |
131 cpppath = optarg; | |
132 SetActiveMode(PreProcessMode); | |
133 break; | |
134 case 'g': | |
135 newprojfile = optarg; | |
136 suppress_error = TRUE; | |
137 SetActiveMode(ProjectMode); | |
138 break; | |
139 case 'c': | |
140 mctag = optarg; | |
141 SetActiveMode(MsgCommentMode); | |
142 break; | |
143 case 's': | |
144 sctag = optarg; | |
145 SetActiveMode(SetCommentMode); | |
146 break; | |
147 case 'b': | |
148 SetActiveMode(BackCommentMode); | |
149 break; | |
150 case 'n': | |
151 SetActiveMode(LineInfoMode); | |
152 break; | |
153 case 'm': | |
154 premsg = optarg; | |
155 SetActiveMode(PrefixMode); | |
156 break; | |
157 case 'M': | |
158 sufmsg = optarg; | |
159 SetActiveMode(SuffixMode); | |
160 break; | |
161 case 't': | |
162 SetActiveMode(TripleMode); | |
163 break; | |
164 case 'd': | |
165 SetActiveMode(DoubleLineMode); | |
166 break; | |
167 case 'f': | |
168 SetActiveMode(OverwriteMode); | |
169 break; | |
170 case 'x': | |
171 suppress_error = TRUE; | |
172 SetActiveMode(NoErrorMode); | |
173 break; | |
174 default: | |
175 usage(); | |
176 break; | |
177 } | |
178 } | |
179 | |
180 if (optind >= argc) { | |
181 usage(); | |
182 } | |
183 | |
184 validate_options(); | |
185 | |
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")); | |
192 exit(EXIT_FAILURE); | |
193 } | |
194 (void) snprintf(newprojfile, len, "%s%s", | |
195 tmp, NEW_SUFFIX); | |
196 } else { | |
197 newprojfile = basename(projfile); | |
198 } | |
199 } | |
200 | |
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); | |
206 exit(EXIT_FAILURE); | |
207 } | |
208 | |
209 if (IsActiveMode(AppendMode) && msgfile != NULL) { | |
210 read_msgfile(msgfile); | |
211 } | |
212 | |
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")); | |
218 exit(EXIT_FAILURE); | |
219 } | |
220 (void) snprintf(msgfile, len, "%s%s", tmp, MSG_SUFFIX); | |
221 } | |
222 | |
223 while (optind < argc) { | |
224 is_cat_found = FALSE; | |
225 srcfile = argv[optind]; | |
226 | |
227 if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) { | |
228 init_linemsgid(); | |
229 } | |
230 | |
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")); | |
235 exit(EXIT_FAILURE); | |
236 } | |
237 (void) snprintf(cmd, len, "%s %s", cpppath, srcfile); | |
238 if ((yyin = popen(cmd, "r")) == NULL) { | |
239 prg_err( | |
240 gettext("fatal: cannot execute \"%s\""), | |
241 cpppath); | |
242 exit(EXIT_FAILURE); | |
243 } | |
244 free(cmd); | |
245 } else { | |
246 if ((yyin = fopen(srcfile, "r")) == NULL) { | |
247 prg_err( | |
248 gettext("cannot open \"%s\""), srcfile); | |
249 goto end; | |
250 } | |
251 } | |
252 | |
253 init_lex(); | |
254 (void) yyparse(); | |
255 | |
256 if (IsActiveMode(PreProcessMode)) { | |
257 if (pclose(yyin) != 0) { | |
258 prg_err(gettext("\"%s\" failed for \"%s\""), | |
259 cpppath, srcfile); | |
260 goto end; | |
261 } | |
262 } | |
263 | |
264 if (is_cat_found == FALSE) { | |
265 if (!IsActiveMode(PreProcessMode)) { | |
266 (void) fclose(yyin); | |
267 } | |
268 goto end; | |
269 } | |
270 | |
271 if (do_msgfile == FALSE) { | |
272 do_msgfile = TRUE; | |
273 } | |
274 | |
275 if (IsActiveMode(AutoNumMode) || IsActiveMode(ReverseMode)) { | |
276 char *newfile; | |
277 | |
278 tmp = basename(srcfile); | |
279 | |
280 if (IsActiveMode(OverwriteMode)) { | |
281 newfile = srcfile; | |
282 } else { | |
283 len = strlen(tmp) + sizeof (NEW_SUFFIX); | |
284 if ((newfile = malloc(len)) == NULL) { | |
285 prg_err( | |
286 gettext("fatal: out of memory")); | |
287 exit(EXIT_FAILURE); | |
288 } | |
289 (void) snprintf(newfile, len, "%s%s", | |
290 tmp, NEW_SUFFIX); | |
291 } | |
292 | |
293 if (is_writable(newfile) == FALSE) { | |
294 prg_err(gettext( | |
295 "cannot create \"%s\": permission denied"), newfile); | |
296 goto end; | |
297 } | |
298 | |
299 (void) strlcpy(tmpfile, "/tmp/gensmg.XXXXXX", | |
300 sizeof (tmpfile)); | |
301 | |
302 if ((tmpfd = mkstemp(tmpfile)) == -1) { | |
303 prg_err(gettext( | |
304 "cannot create \"%s\""), tmpfile); | |
305 if (!IsActiveMode(PreProcessMode)) { | |
306 (void) fclose(yyin); | |
307 } | |
308 goto end; | |
309 } | |
310 if ((newfp = fdopen(tmpfd, "w")) == NULL) { | |
311 prg_err(gettext( | |
312 "cannot create \"%s\""), tmpfile); | |
313 if (!IsActiveMode(PreProcessMode)) { | |
314 (void) fclose(yyin); | |
315 } | |
316 (void) close(tmpfd); | |
317 (void) unlink(tmpfile); | |
318 goto end; | |
319 } | |
320 | |
321 if (IsActiveMode(PreProcessMode)) { | |
322 if ((yyin = fopen(srcfile, "r")) == NULL) { | |
323 prg_err(gettext( | |
324 "cannot open \"%s\""), srcfile); | |
325 (void) fclose(newfp); | |
326 (void) unlink(tmpfile); | |
327 goto end; | |
328 } | |
329 } else { | |
330 rewind(yyin); | |
331 } | |
332 | |
333 SetActiveMode(ReplaceMode); | |
334 init_lex(); | |
335 (void) yyparse(); | |
336 ResetActiveMode(ReplaceMode); | |
337 | |
338 (void) fclose(newfp); | |
339 newfp = NULL; | |
340 | |
341 (void) fclose(yyin); | |
342 | |
343 (void) file_copy(tmpfile, newfile); | |
344 | |
345 (void) unlink(tmpfile); | |
346 | |
347 goto end; | |
348 } | |
349 | |
350 if (!IsActiveMode(PreProcessMode)) { | |
351 (void) fclose(yyin); | |
352 } | |
353 | |
354 end: | |
355 optind++; | |
356 } | |
357 | |
358 if (!do_msgfile) { /* no more business. */ | |
359 return (EXIT_SUCCESS); | |
360 } | |
361 | |
362 if (!IsActiveMode(ReverseMode) && !IsActiveMode(ProjectMode)) { | |
363 write_msgfile(msgfile); | |
364 } | |
365 | |
366 if (IsActiveMode(AutoNumMode) || IsActiveMode(ProjectMode)) { | |
367 write_projfile(IsActiveMode(OverwriteMode) ? | |
368 projfile : newprojfile); | |
369 } | |
370 return (EXIT_SUCCESS); | |
371 } | |
372 | |
373 static void | |
374 validate_options(void) | |
375 { | |
376 /* -r doesn't work with either -a or -l. */ | |
377 if (IsActiveMode(ReverseMode) && | |
378 (IsActiveMode(AutoNumMode) || IsActiveMode(AppendMode))) { | |
379 usage(); | |
380 } | |
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))) { | |
387 usage(); | |
388 } | |
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))) { | |
396 usage(); | |
397 } | |
398 } | |
399 | |
400 static void | |
401 usage(void) | |
402 { | |
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"), | |
408 program); | |
409 exit(EXIT_FAILURE); | |
410 } |