9621 Make createtxg and guid properties public
[unleashed.git] / usr / src / cmd / msgfmt / check_header.c
blob82315db347c75ece83e996b508111bf6ffdb70f7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "sun_msgfmt.h"
31 static const char *mandatory_fields[] = {
32 "Project-Id-Version",
33 "PO-Revision-Date",
34 "Last-Translator",
35 "Language-Team",
36 "Content-Type",
37 "Content-Transfer-Encoding",
38 NULL
41 static const char *mandatory_fields_new[] = {
42 "POT-Creation-Date",
43 "Plural-Forms",
44 NULL
47 extern int verbose;
49 extern void invoke_gnu_msgfmt(void);
51 static size_t
52 get_one_line(char **bufhead, char **mbuf, size_t *fsize)
54 size_t len;
55 char *p = *mbuf;
56 char *q, *tmp;
58 if (*bufhead) {
59 free(*bufhead);
60 *bufhead = NULL;
63 if (*fsize == 0) {
64 /* eof */
65 return (0);
68 q = p;
69 while (((*fsize) != 0) && (*p++ != '\n')) {
70 (*fsize)--;
72 len = p - q;
73 if (len == 0) {
74 return (0);
76 tmp = (char *)Xmalloc(len + 1);
77 (void) memcpy(tmp, q, len);
78 tmp[len] = '\0';
79 *bufhead = tmp;
80 *mbuf = p;
81 return (len);
84 void
85 check_gnu(char *addr, size_t fsize)
87 int i;
88 char c, mc;
89 char *linebuf;
90 char *mbuf, *p, *buf;
91 unsigned int n;
92 size_t ln_size;
93 size_t bufsize, index;
94 size_t size = fsize;
95 int quotefound = 0;
96 const char *field;
98 buf = NULL;
99 linebuf = NULL;
100 mbuf = addr;
102 loop:
103 ln_size = get_one_line(&linebuf, &mbuf, &size);
104 if ((ln_size == (size_t)-1) ||
105 (ln_size == 0)) {
106 goto no_gnu;
108 p = linebuf;
110 while ((*p == '#') || (*p == '\n')) {
111 ln_size = get_one_line(&linebuf, &mbuf, &size);
112 if ((ln_size == (size_t)-1) ||
113 (ln_size == 0)) {
114 goto no_gnu;
116 p = linebuf;
119 if (strncmp(p, "domain", 6) == 0)
120 goto loop;
122 if (strncmp(p, "msgid", 5) != 0) {
123 /* error */
124 goto no_gnu;
127 p += 5;
128 if ((*p != ' ') && (*p != '\t') &&
129 (*p != '\n') && (*p != '\0')) {
130 /* no space after msgid */
131 goto no_gnu;
133 /* skip spaces */
134 while ((*p == ' ') || (*p == '\t'))
135 p++;
137 /* check if this entry is an empty string */
138 if ((*p != '\"') || (*(p + 1) != '\"')) {
139 /* this is not an empty string */
140 goto no_gnu;
142 p += 2;
143 while (*p && ((*p == ' ') || (*p == '\t'))) {
144 p++;
146 if ((*p != '\n') && (*p != '\0')) {
147 /* other characters than '\n' and '\0' found */
148 goto no_gnu;
151 for (; ; ) {
152 ln_size = get_one_line(&linebuf, &mbuf, &size);
153 if ((ln_size == (size_t)-1) ||
154 (ln_size == 0)) {
155 goto no_gnu;
157 p = linebuf;
158 /* skip leading spaces */
159 while ((*p == ' ') || (*p == '\t'))
160 p++;
162 if (*p != '\"') {
163 if (strncmp(p, "msgstr", 6) == 0) {
164 break;
166 /* not a valid entry */
167 goto no_gnu;
169 if (*(p + 1) != '\"') {
170 /* not an empty string */
171 goto no_gnu;
173 p += 2;
174 while ((*p == ' ') || (*p == '\t'))
175 p++;
177 if ((*p != '\n') && (*p != '\0')) {
178 /* other characters than '\n' and '\0' found */
179 goto no_gnu;
184 * msgid for the header entry found
185 * Now p points to "msgstr"
187 p += 6;
188 if ((*p != ' ') && (*p != '\t') &&
189 (*p != '\n') && (*p != '\0')) {
190 /* no space after msgid */
191 goto no_gnu;
194 /* skip spaces */
195 while ((*p == ' ') || (*p == '\t'))
196 p++;
198 if (*p != '\"') {
199 /* no quote */
200 goto no_gnu;
203 bufsize = ln_size + 1;
204 index = 0;
205 buf = (char *)Xmalloc(bufsize);
207 for (; ; ) {
208 if (*p != '\"') {
209 /* msgstr entry ends */
210 buf[index] = '\0';
211 break;
214 if (*p++ != '\"') {
215 /* no beginning quote */
216 goto no_gnu;
218 while (*p) {
219 switch (mc = *p++) {
220 case '\n':
221 if (!quotefound) {
222 /* error */
223 goto no_gnu;
225 break;
226 case '\"':
227 quotefound = 1;
228 break;
229 case '\\':
230 if (!*p)
231 break;
232 switch (c = *p++) {
233 case 'b':
234 buf[index++] = '\b';
235 break;
236 case 'f':
237 buf[index++] = '\f';
238 break;
239 case 'n':
240 buf[index++] = '\n';
241 break;
242 case 'r':
243 buf[index++] = '\r';
244 break;
245 case 't':
246 buf[index++] = '\t';
247 break;
248 case 'v':
249 buf[index++] = '\v';
250 break;
251 case 'a':
252 buf[index++] = '\a';
253 break;
254 case '\"':
255 case '\\':
256 case '\'':
257 case '?':
258 buf[index++] = c;
259 break;
260 default:
261 if (isdigit((unsigned char)c)) {
262 unsigned int x;
263 unsigned char *up =
264 (unsigned char *)p;
265 n = c - '0';
266 if (isdigit(*up)) {
267 x = *up++ - '0';
268 n = 8 * n + x;
269 if (isdigit(*up)) {
270 x = *up++ - '0';
271 n = 8 * n + x;
274 p = (char *)up;
275 buf[index++] = n;
277 break;
279 break;
280 default:
281 buf[index++] = mc;
282 break;
284 if (quotefound) {
285 while (*p && ((*p == ' ') || (*p == '\t'))) {
286 p++;
288 if ((*p != '\n') && (*p != '\0')) {
289 goto no_gnu;
291 quotefound = 0;
292 break;
295 ln_size = get_one_line(&linebuf, &mbuf, &size);
296 if ((ln_size == (size_t)-1) ||
297 (ln_size == 0)) {
298 goto no_gnu;
300 p = linebuf;
301 /* skip spaces */
302 while ((*p == ' ') || (*p == '\t'))
303 p++;
304 bufsize += ln_size;
305 buf = (char *)Xrealloc(buf, bufsize);
308 for (i = 0; (field = mandatory_fields[i]) != NULL; i++) {
309 if (strstr(buf, field) == NULL)
310 continue;
311 /* one of mandatory fields found */
312 free(linebuf);
313 free(buf);
314 (void) munmap(addr, fsize);
315 if (verbose)
316 diag(gettext(DIAG_GNU_FOUND));
317 invoke_gnu_msgfmt();
318 /* NOTREACHED */
320 for (i = 0; (field = mandatory_fields_new[i]) != NULL; i++) {
321 if (strstr(buf, field) == NULL)
322 continue;
323 /* one of mandatory fields found */
324 free(linebuf);
325 free(buf);
326 (void) munmap(addr, fsize);
327 if (verbose)
328 diag(gettext(DIAG_GNU_FOUND));
329 invoke_gnu_msgfmt();
330 /* NOTREACHED */
333 no_gnu:
334 free(linebuf);
335 if (buf)
336 free(buf);